Initial import of OpenJdk files.

Create new libcore/ojluni directory with src/main/java and
src/main/native subdirectiories.

Build ojluni into core-oj jar.

Use openjdk classes from java.awt.font package.

Copy all files from jdk/src/share/classes and jdk/src/solaris/classes
directories in openjdk into libcore/ojluni/src/main/java.

Copy following native files from openjdk to
libcore/ojluni/src/main/native:
jdk/src/solaris/native/java/io/canonicalize_md.c
build/linux-amd64/include/classfile_constants.h
jdk/src/share/native/java/net/DatagramPacket.c
jdk/src/solaris/native/sun/net/spi/DefaultProxySelector.c
jdk/src/share/native/java/lang/Double.c
jdk/src/share/native/java/lang/fdlibm/include/fdlibm.h
jdk/src/solaris/native/sun/nio/ch/FileChannelImpl.c
jdk/src/solaris/native/java/io/FileDescriptor_md.c
jdk/src/solaris/native/sun/nio/ch/FileDispatcherImpl.c
jdk/src/share/native/java/io/FileInputStream.c
jdk/src/solaris/native/sun/nio/ch/FileKey.c
jdk/src/solaris/native/java/io/FileOutputStream_md.c
jdk/src/solaris/native/java/io/FileSystem_md.c
jdk/src/share/native/java/lang/Float.c
jdk/src/share/native/java/net/Inet4Address.c
jdk/src/solaris/native/java/net/Inet4AddressImpl.c
jdk/src/share/native/java/net/Inet6Address.c
jdk/src/solaris/native/java/net/Inet6AddressImpl.c
jdk/src/share/native/java/net/InetAddress.c
jdk/src/solaris/native/java/net/InetAddressImplFactory.c
jdk/src/share/native/java/io/io_util.c
jdk/src/solaris/native/sun/nio/ch/IOUtil.c
jdk/src/share/native/java/io/io_util.h
jdk/src/solaris/native/java/io/io_util_md.c
jdk/src/solaris/native/java/io/io_util_md.h
build/linux-amd64/tmp/java/java.nio/nio/CClassHeaders/java_io_FileDescriptor.h
build/linux-amd64/tmp/java/java.lang/java/CClassHeaders/java_io_FileInputStream.h
build/linux-amd64/tmp/java/java.lang/java/CClassHeaders/java_io_FileOutputStream.h
build/linux-amd64/tmp/java/java.lang/java/CClassHeaders/java_io_FileSystem.h
build/linux-amd64/tmp/java/java.lang/java/CClassHeaders/java_io_ObjectStreamClass.h
build/linux-amd64/tmp/java/java.lang/java/CClassHeaders/java_io_UnixFileSystem.h
build/linux-amd64/tmp/java/java.lang/java/CClassHeaders/java_lang_Double.h
build/linux-amd64/tmp/java/java.lang/java/CClassHeaders/java_lang_Float.h
build/linux-amd64/tmp/java/java.lang/java/CClassHeaders/java_lang_Integer.h
build/linux-amd64/tmp/java/java.lang/java/CClassHeaders/java_lang_Long.h
build/linux-amd64/tmp/java/java.lang/java/CClassHeaders/java_lang_Runtime.h
build/linux-amd64/tmp/java/java.lang/java/CClassHeaders/java_lang_Shutdown.h
build/linux-amd64/tmp/java/java.lang/java/CClassHeaders/java_lang_StrictMath.h
build/linux-amd64/tmp/java/java.lang/java/CClassHeaders/java_lang_String.h
build/linux-amd64/tmp/java/java.lang/java/CClassHeaders/java_lang_System.h
build/linux-amd64/tmp/java/java.lang/java/CClassHeaders/java_lang_Thread.h
build/linux-amd64/tmp/java/java.lang/java/CClassHeaders/java_lang_Throwable.h
build/linux-amd64/tmp/sun/java.net/net/CClassHeaders/java_net_DatagramPacket.h
build/linux-amd64/tmp/sun/java.net/net/CClassHeaders/java_net_Inet4Address.h
build/linux-amd64/tmp/sun/java.net/net/CClassHeaders/java_net_Inet4AddressImpl.h
build/linux-amd64/tmp/sun/java.net/net/CClassHeaders/java_net_Inet6Address.h
build/linux-amd64/tmp/sun/java.net/net/CClassHeaders/java_net_Inet6AddressImpl.h
build/linux-amd64/tmp/sun/java.net/net/CClassHeaders/java_net_InetAddress.h
build/linux-amd64/tmp/sun/java.net/net/CClassHeaders/java_net_InetAddressImplFactory.h
build/linux-amd64/tmp/sun/java.net/net/CClassHeaders/java_net_NetworkInterface.h
build/linux-amd64/tmp/sun/java.net/net/CClassHeaders/java_net_PlainDatagramSocketImpl.h
build/linux-amd64/tmp/sun/java.net/net/CClassHeaders/java_net_PlainSocketImpl.h
build/linux-amd64/tmp/sun/java.net/net/CClassHeaders/java_net_SocketInputStream.h
build/linux-amd64/tmp/sun/java.net/net/CClassHeaders/java_net_SocketOptions.h
build/linux-amd64/tmp/sun/java.net/net/CClassHeaders/java_net_SocketOutputStream.h
jdk/src/share/native/java/lang/java_props.h
jdk/src/solaris/native/java/lang/java_props_md.c
jdk/src/share/native/java/util/zip/Adler32.c as java_util_zip_Adler32.c
jdk/src/share/native/java/util/zip/CRC32.c as java_util_zip_CRC32.c
build/linux-amd64/tmp/sun/java.util.zip/zip/CClassHeaders/java_util_zip_CRC32.h
jdk/src/share/native/java/util/zip/Deflater.c as java_util_zip_Deflater.c
build/linux-amd64/tmp/sun/java.util.zip/zip/CClassHeaders/java_util_zip_Deflater.h
jdk/src/share/native/java/util/zip/Inflater.c as java_util_zip_Inflater.c
build/linux-amd64/tmp/sun/java.util.zip/zip/CClassHeaders/java_util_zip_Inflater.h
jdk/src/share/native/java/util/zip/ZipFile.c as java_util_zip_ZipFile.c
build/linux-amd64/tmp/sun/java.util.zip/zip/CClassHeaders/java_util_zip_ZipFile.h
jdk/src/share/native/java/lang/fdlibm/include/jfdlibm.h
jdk/src/share/native/common/jlong.h
jdk/src/solaris/native/common/jlong_md.h
jdk/src/share/native/common/jni_util.c
jdk/src/share/native/common/jni_util.h
jdk/src/solaris/native/common/jni_util_md.c
jdk/src/share/javavm/export/jvm.h
jdk/src/solaris/javavm/export/jvm_md.h
jdk/src/solaris/native/java/net/linux_close.c
jdk/src/share/native/sun/misc/NativeSignalHandler.c
jdk/src/solaris/native/sun/nio/ch/NativeThread.c
jdk/src/share/native/java/net/net_util.c
jdk/src/share/native/java/net/net_util.h
jdk/src/solaris/native/java/net/net_util_md.c
jdk/src/solaris/native/java/net/net_util_md.h
jdk/src/solaris/native/java/net/NetworkInterface.c
jdk/src/share/native/sun/nio/ch/nio.h
jdk/src/solaris/native/sun/nio/ch/nio_util.h
jdk/src/share/native/java/io/ObjectStreamClass.c
jdk/src/solaris/native/java/net/PlainDatagramSocketImpl.c
jdk/src/solaris/native/java/net/PlainSocketImpl.c
jdk/src/solaris/native/java/lang/ProcessEnvironment_md.c
jdk/src/share/native/java/lang/Runtime.c
jdk/src/share/native/java/lang/Shutdown.c
jdk/src/share/native/sun/misc/Signal.c
jdk/src/solaris/native/java/net/SocketInputStream.c
jdk/src/solaris/native/java/net/SocketOutputStream.c
jdk/src/share/native/java/lang/StrictMath.c
jdk/src/share/native/java/lang/String.c
build/linux-amd64/tmp/java/java.lang/java/CClassHeaders/sun_misc_NativeSignalHandler.h
build/linux-amd64/tmp/java/java.lang/java/CClassHeaders/sun_misc_Signal.h
build/linux-amd64/tmp/sun/java.net/net/CClassHeaders/sun_net_spi_DefaultProxySelector.h
build/linux-amd64/tmp/java/java.nio/nio/CClassHeaders/sun_nio_ch_FileChannelImpl.h
build/linux-amd64/tmp/java/java.nio/nio/CClassHeaders/sun_nio_ch_FileDispatcherImpl.h
build/linux-amd64/tmp/java/java.nio/nio/CClassHeaders/sun_nio_ch_FileKey.h
build/linux-amd64/tmp/java/java.nio/nio/CClassHeaders/sun_nio_ch_IOStatus.h
build/linux-amd64/tmp/java/java.nio/nio/CClassHeaders/sun_nio_ch_IOUtil.h
build/linux-amd64/tmp/java/java.nio/nio/CClassHeaders/sun_nio_ch_NativeThread.h
jdk/src/share/native/java/lang/System.c
jdk/src/share/native/java/lang/Thread.c
jdk/src/share/native/java/lang/Throwable.c
jdk/src/solaris/native/java/io/UnixFileSystem_md.c
jdk/src/solaris/native/java/lang/UNIXProcess_md.c
jdk/src/share/native/java/util/zip/zip_util.c
jdk/src/share/native/java/util/zip/zip_util.h

Change-Id: Ib237df4e1b7b5b4d9f12e74d189e6ec9eed3c31d
diff --git a/ojluni/src/main/native/DatagramPacket.c b/ojluni/src/main/native/DatagramPacket.c
new file mode 100755
index 0000000..01ac9fb
--- /dev/null
+++ b/ojluni/src/main/native/DatagramPacket.c
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 1997, 2002, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include "java_net_DatagramPacket.h"
+#include "net_util.h"
+
+/************************************************************************
+ * DatagramPacket
+ */
+
+jfieldID dp_addressID;
+jfieldID dp_portID;
+jfieldID dp_bufID;
+jfieldID dp_offsetID;
+jfieldID dp_lengthID;
+jfieldID dp_bufLengthID;
+
+/*
+ * Class:     java_net_DatagramPacket
+ * Method:    init
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL
+Java_java_net_DatagramPacket_init (JNIEnv *env, jclass cls) {
+    dp_addressID = (*env)->GetFieldID(env, cls, "address",
+                                      "Ljava/net/InetAddress;");
+    CHECK_NULL(dp_addressID);
+    dp_portID = (*env)->GetFieldID(env, cls, "port", "I");
+    CHECK_NULL(dp_portID);
+    dp_bufID = (*env)->GetFieldID(env, cls, "buf", "[B");
+    CHECK_NULL(dp_bufID);
+    dp_offsetID = (*env)->GetFieldID(env, cls, "offset", "I");
+    CHECK_NULL(dp_offsetID);
+    dp_lengthID = (*env)->GetFieldID(env, cls, "length", "I");
+    CHECK_NULL(dp_lengthID);
+    dp_bufLengthID = (*env)->GetFieldID(env, cls, "bufLength", "I");
+    CHECK_NULL(dp_bufLengthID);
+}
diff --git a/ojluni/src/main/native/DefaultProxySelector.c b/ojluni/src/main/native/DefaultProxySelector.c
new file mode 100755
index 0000000..6883902
--- /dev/null
+++ b/ojluni/src/main/native/DefaultProxySelector.c
@@ -0,0 +1,335 @@
+/*
+ * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include "jni.h"
+#include "jni_util.h"
+#include "jvm.h"
+#include "jvm_md.h"
+#include "jlong.h"
+#include "sun_net_spi_DefaultProxySelector.h"
+#include <dlfcn.h>
+#include <stdio.h>
+#if defined(__linux__) || defined(_ALLBSD_SOURCE)
+#include <string.h>
+#else
+#include <strings.h>
+#endif
+
+/**
+ * These functions are used by the sun.net.spi.DefaultProxySelector class
+ * to access some platform specific settings.
+ * This is the Solaris/Linux Gnome 2.x code using the GConf-2 library.
+ * Everything is loaded dynamically so no hard link with any library exists.
+ * The GConf-2 settings used are:
+ * - /system/http_proxy/use_http_proxy          boolean
+ * - /system/http_proxy/use_authentcation       boolean
+ * - /system/http_proxy/use_same_proxy          boolean
+ * - /system/http_proxy/host                    string
+ * - /system/http_proxy/authentication_user     string
+ * - /system/http_proxy/authentication_password string
+ * - /system/http_proxy/port                    int
+ * - /system/proxy/socks_host                   string
+ * - /system/proxy/mode                         string
+ * - /system/proxy/ftp_host                     string
+ * - /system/proxy/secure_host                  string
+ * - /system/proxy/socks_port                   int
+ * - /system/proxy/ftp_port                     int
+ * - /system/proxy/secure_port                  int
+ * - /system/proxy/no_proxy_for                 list
+ * - /system/proxy/gopher_host                  string
+ * - /system/proxy/gopher_port                  int
+ */
+typedef void* gconf_client_get_default_func();
+typedef char* gconf_client_get_string_func(void *, char *, void**);
+typedef int   gconf_client_get_int_func(void*, char *, void**);
+typedef int   gconf_client_get_bool_func(void*, char *, void**);
+typedef int   gconf_init_func(int, char**, void**);
+typedef void  g_type_init_func ();
+gconf_client_get_default_func* my_get_default_func = NULL;
+gconf_client_get_string_func* my_get_string_func = NULL;
+gconf_client_get_int_func* my_get_int_func = NULL;
+gconf_client_get_bool_func* my_get_bool_func = NULL;
+gconf_init_func* my_gconf_init_func = NULL;
+g_type_init_func* my_g_type_init_func = NULL;
+
+static jclass proxy_class;
+static jclass isaddr_class;
+static jclass ptype_class;
+static jmethodID isaddr_createUnresolvedID;
+static jmethodID proxy_ctrID;
+static jfieldID pr_no_proxyID;
+static jfieldID ptype_httpID;
+static jfieldID ptype_socksID;
+
+static int gconf_ver = 0;
+static void* gconf_client = NULL;
+
+#define CHECK_NULL(X) { if ((X) == NULL) fprintf (stderr,"JNI errror at line %d\n", __LINE__); }
+
+/*
+ * Class:     sun_net_spi_DefaultProxySelector
+ * Method:    init
+ * Signature: ()Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_sun_net_spi_DefaultProxySelector_init(JNIEnv *env, jclass clazz) {
+  jclass cls = NULL;
+  CHECK_NULL(cls = (*env)->FindClass(env,"java/net/Proxy"));
+  proxy_class = (*env)->NewGlobalRef(env, cls);
+  CHECK_NULL(cls = (*env)->FindClass(env,"java/net/Proxy$Type"));
+  ptype_class = (*env)->NewGlobalRef(env, cls);
+  CHECK_NULL(cls = (*env)->FindClass(env, "java/net/InetSocketAddress"));
+  isaddr_class = (*env)->NewGlobalRef(env, cls);
+  proxy_ctrID = (*env)->GetMethodID(env, proxy_class, "<init>", "(Ljava/net/Proxy$Type;Ljava/net/SocketAddress;)V");
+  pr_no_proxyID = (*env)->GetStaticFieldID(env, proxy_class, "NO_PROXY", "Ljava/net/Proxy;");
+  ptype_httpID = (*env)->GetStaticFieldID(env, ptype_class, "HTTP", "Ljava/net/Proxy$Type;");
+  ptype_socksID = (*env)->GetStaticFieldID(env, ptype_class, "SOCKS", "Ljava/net/Proxy$Type;");
+  isaddr_createUnresolvedID = (*env)->GetStaticMethodID(env, isaddr_class, "createUnresolved", "(Ljava/lang/String;I)Ljava/net/InetSocketAddress;");
+
+  /**
+   * Let's try to load le GConf-2 library
+   */
+  if (dlopen(JNI_LIB_NAME("gconf-2"), RTLD_GLOBAL | RTLD_LAZY) != NULL ||
+      dlopen(VERSIONED_JNI_LIB_NAME("gconf-2", "4"),
+             RTLD_GLOBAL | RTLD_LAZY) != NULL) {
+    gconf_ver = 2;
+  }
+  if (gconf_ver > 0) {
+    /*
+     * Now let's get pointer to the functions we need.
+     */
+    my_g_type_init_func = (g_type_init_func*) dlsym(RTLD_DEFAULT, "g_type_init");
+    my_get_default_func = (gconf_client_get_default_func*) dlsym(RTLD_DEFAULT, "gconf_client_get_default");
+    if (my_g_type_init_func != NULL && my_get_default_func != NULL) {
+      /**
+       * Try to connect to GConf.
+       */
+      (*my_g_type_init_func)();
+      gconf_client = (*my_get_default_func)();
+      if (gconf_client != NULL) {
+        my_get_string_func = (gconf_client_get_string_func*) dlsym(RTLD_DEFAULT, "gconf_client_get_string");
+        my_get_int_func = (gconf_client_get_int_func*) dlsym(RTLD_DEFAULT, "gconf_client_get_int");
+        my_get_bool_func = (gconf_client_get_bool_func*) dlsym(RTLD_DEFAULT, "gconf_client_get_bool");
+        if (my_get_int_func != NULL && my_get_string_func != NULL &&
+            my_get_bool_func != NULL) {
+          /**
+           * We did get all we need. Let's enable the System Proxy Settings.
+           */
+          return JNI_TRUE;
+        }
+      }
+    }
+  }
+  return JNI_FALSE;
+}
+
+
+/*
+ * Class:     sun_net_spi_DefaultProxySelector
+ * Method:    getSystemProxy
+ * Signature: ([Ljava/lang/String;Ljava/lang/String;)Ljava/net/Proxy;
+ */
+JNIEXPORT jobject JNICALL
+Java_sun_net_spi_DefaultProxySelector_getSystemProxy(JNIEnv *env,
+                                                     jobject this,
+                                                     jstring proto,
+                                                     jstring host)
+{
+  char *phost = NULL;
+  char *mode = NULL;
+  int pport = 0;
+  int use_proxy = 0;
+  int use_same_proxy = 0;
+  const char* urlhost;
+  jobject isa = NULL;
+  jobject proxy = NULL;
+  jobject type_proxy = NULL;
+  jobject no_proxy = NULL;
+  const char *cproto;
+  jboolean isCopy;
+
+  if (gconf_ver > 0) {
+    if (gconf_client == NULL) {
+      (*my_g_type_init_func)();
+      gconf_client = (*my_get_default_func)();
+    }
+    if (gconf_client != NULL) {
+      cproto = (*env)->GetStringUTFChars(env, proto, &isCopy);
+      if (cproto != NULL) {
+        /**
+         * We will have to check protocol by protocol as they do use different
+         * entries.
+         */
+
+        use_same_proxy = (*my_get_bool_func)(gconf_client, "/system/http_proxy/use_same_proxy", NULL);
+        if (use_same_proxy) {
+          use_proxy = (*my_get_bool_func)(gconf_client, "/system/http_proxy/use_http_proxy", NULL);
+          if (use_proxy) {
+            phost = (*my_get_string_func)(gconf_client, "/system/http_proxy/host", NULL);
+            pport = (*my_get_int_func)(gconf_client, "/system/http_proxy/port", NULL);
+          }
+        }
+
+        /**
+         * HTTP:
+         * /system/http_proxy/use_http_proxy (boolean)
+         * /system/http_proxy/host (string)
+         * /system/http_proxy/port (integer)
+         */
+        if (strcasecmp(cproto, "http") == 0) {
+          use_proxy = (*my_get_bool_func)(gconf_client, "/system/http_proxy/use_http_proxy", NULL);
+          if (use_proxy) {
+            if (!use_same_proxy) {
+              phost = (*my_get_string_func)(gconf_client, "/system/http_proxy/host", NULL);
+              pport = (*my_get_int_func)(gconf_client, "/system/http_proxy/port", NULL);
+            }
+            CHECK_NULL(type_proxy = (*env)->GetStaticObjectField(env, ptype_class, ptype_httpID));
+          }
+        }
+
+        /**
+         * HTTPS:
+         * /system/proxy/mode (string) [ "manual" means use proxy settings ]
+         * /system/proxy/secure_host (string)
+         * /system/proxy/secure_port (integer)
+         */
+        if (strcasecmp(cproto, "https") == 0) {
+          mode =  (*my_get_string_func)(gconf_client, "/system/proxy/mode", NULL);
+          if (mode != NULL && (strcasecmp(mode,"manual") == 0)) {
+            if (!use_same_proxy) {
+              phost = (*my_get_string_func)(gconf_client, "/system/proxy/secure_host", NULL);
+              pport = (*my_get_int_func)(gconf_client, "/system/proxy/secure_port", NULL);
+            }
+            use_proxy = (phost != NULL);
+            if (use_proxy)
+              type_proxy = (*env)->GetStaticObjectField(env, ptype_class, ptype_httpID);
+          }
+        }
+
+        /**
+         * FTP:
+         * /system/proxy/mode (string) [ "manual" means use proxy settings ]
+         * /system/proxy/ftp_host (string)
+         * /system/proxy/ftp_port (integer)
+         */
+        if (strcasecmp(cproto, "ftp") == 0) {
+          mode =  (*my_get_string_func)(gconf_client, "/system/proxy/mode", NULL);
+          if (mode != NULL && (strcasecmp(mode,"manual") == 0)) {
+            if (!use_same_proxy) {
+              phost = (*my_get_string_func)(gconf_client, "/system/proxy/ftp_host", NULL);
+              pport = (*my_get_int_func)(gconf_client, "/system/proxy/ftp_port", NULL);
+            }
+            use_proxy = (phost != NULL);
+            if (use_proxy)
+              type_proxy = (*env)->GetStaticObjectField(env, ptype_class, ptype_httpID);
+          }
+        }
+
+        /**
+         * GOPHER:
+         * /system/proxy/mode (string) [ "manual" means use proxy settings ]
+         * /system/proxy/gopher_host (string)
+         * /system/proxy/gopher_port (integer)
+         */
+        if (strcasecmp(cproto, "gopher") == 0) {
+          mode =  (*my_get_string_func)(gconf_client, "/system/proxy/mode", NULL);
+          if (mode != NULL && (strcasecmp(mode,"manual") == 0)) {
+            if (!use_same_proxy) {
+              phost = (*my_get_string_func)(gconf_client, "/system/proxy/gopher_host", NULL);
+              pport = (*my_get_int_func)(gconf_client, "/system/proxy/gopher_port", NULL);
+            }
+            use_proxy = (phost != NULL);
+            if (use_proxy)
+              type_proxy = (*env)->GetStaticObjectField(env, ptype_class, ptype_httpID);
+          }
+        }
+
+        /**
+         * SOCKS:
+         * /system/proxy/mode (string) [ "manual" means use proxy settings ]
+         * /system/proxy/socks_host (string)
+         * /system/proxy/socks_port (integer)
+         */
+        if (strcasecmp(cproto, "socks") == 0) {
+          mode =  (*my_get_string_func)(gconf_client, "/system/proxy/mode", NULL);
+          if (mode != NULL && (strcasecmp(mode,"manual") == 0)) {
+            if (!use_same_proxy) {
+              phost = (*my_get_string_func)(gconf_client, "/system/proxy/socks_host", NULL);
+              pport = (*my_get_int_func)(gconf_client, "/system/proxy/socks_port", NULL);
+            }
+            use_proxy = (phost != NULL);
+            if (use_proxy)
+              type_proxy = (*env)->GetStaticObjectField(env, ptype_class, ptype_socksID);
+          }
+        }
+
+        if (isCopy == JNI_TRUE)
+          (*env)->ReleaseStringUTFChars(env, proto, cproto);
+
+        if (use_proxy && (phost != NULL)) {
+          jstring jhost;
+          char *noproxyfor;
+          char *s;
+
+          /**
+           * check for the exclude list (aka "No Proxy For" list).
+           * It's a list of comma separated suffixes (e.g. domain name).
+           */
+          noproxyfor = (*my_get_string_func)(gconf_client, "/system/proxy/no_proxy_for", NULL);
+          if (noproxyfor != NULL) {
+            char *tmpbuf[512];
+
+            s = strtok_r(noproxyfor, ", ", tmpbuf);
+            urlhost = (*env)->GetStringUTFChars(env, host, &isCopy);
+            if (urlhost != NULL) {
+              while (s != NULL && strlen(s) <= strlen(urlhost)) {
+                if (strcasecmp(urlhost+(strlen(urlhost) - strlen(s)), s) == 0) {
+                  /**
+                   * the URL host name matches with one of the sufixes,
+                   * therefore we have to use a direct connection.
+                   */
+                  use_proxy = 0;
+                  break;
+                }
+                s = strtok_r(NULL, ", ", tmpbuf);
+              }
+              if (isCopy == JNI_TRUE)
+                (*env)->ReleaseStringUTFChars(env, host, urlhost);
+            }
+          }
+          if (use_proxy) {
+            jhost = (*env)->NewStringUTF(env, phost);
+            isa = (*env)->CallStaticObjectMethod(env, isaddr_class, isaddr_createUnresolvedID, jhost, pport);
+            proxy = (*env)->NewObject(env, proxy_class, proxy_ctrID, type_proxy, isa);
+            return proxy;
+          }
+        }
+      }
+    }
+  }
+
+  CHECK_NULL(no_proxy = (*env)->GetStaticObjectField(env, proxy_class, pr_no_proxyID));
+  return no_proxy;
+}
diff --git a/ojluni/src/main/native/Double.c b/ojluni/src/main/native/Double.c
new file mode 100755
index 0000000..7715788
--- /dev/null
+++ b/ojluni/src/main/native/Double.c
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 1997, 2005, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include "jni.h"
+#include "jni_util.h"
+#include "jlong.h"
+#include "jvm.h"
+
+#include "java_lang_Double.h"
+
+/*
+ * Find the double float corresponding to a given bit pattern
+ */
+JNIEXPORT jdouble JNICALL
+Java_java_lang_Double_longBitsToDouble(JNIEnv *env, jclass unused, jlong v)
+{
+    union {
+        jlong l;
+        double d;
+    } u;
+    jlong_to_jdouble_bits(&v);
+    u.l = v;
+    return (jdouble)u.d;
+}
+
+/*
+ * Find the bit pattern corresponding to a given double float, NOT collapsing NaNs
+ */
+JNIEXPORT jlong JNICALL
+Java_java_lang_Double_doubleToRawLongBits(JNIEnv *env, jclass unused, jdouble v)
+{
+    union {
+        jlong l;
+        double d;
+    } u;
+    jdouble_to_jlong_bits(&v);
+    u.d = (double)v;
+    return u.l;
+}
diff --git a/ojluni/src/main/native/FileChannelImpl.c b/ojluni/src/main/native/FileChannelImpl.c
new file mode 100755
index 0000000..8e5c0fd
--- /dev/null
+++ b/ojluni/src/main/native/FileChannelImpl.c
@@ -0,0 +1,234 @@
+/*
+ * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include "jni.h"
+#include "jni_util.h"
+#include "jvm.h"
+#include "jvm_md.h"
+#include "jlong.h"
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include "sun_nio_ch_FileChannelImpl.h"
+#include "java_lang_Integer.h"
+#include "nio.h"
+#include "nio_util.h"
+#include <dlfcn.h>
+
+#if defined(__linux__) || defined(__solaris__)
+#include <sys/sendfile.h>
+#elif defined(_ALLBSD_SOURCE)
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/uio.h>
+
+#define lseek64 lseek
+#define mmap64 mmap
+#endif
+
+static jfieldID chan_fd;        /* jobject 'fd' in sun.io.FileChannelImpl */
+
+JNIEXPORT jlong JNICALL
+Java_sun_nio_ch_FileChannelImpl_initIDs(JNIEnv *env, jclass clazz)
+{
+    jlong pageSize = sysconf(_SC_PAGESIZE);
+    chan_fd = (*env)->GetFieldID(env, clazz, "fd", "Ljava/io/FileDescriptor;");
+    return pageSize;
+}
+
+static jlong
+handle(JNIEnv *env, jlong rv, char *msg)
+{
+    if (rv >= 0)
+        return rv;
+    if (errno == EINTR)
+        return IOS_INTERRUPTED;
+    JNU_ThrowIOExceptionWithLastError(env, msg);
+    return IOS_THROWN;
+}
+
+
+JNIEXPORT jlong JNICALL
+Java_sun_nio_ch_FileChannelImpl_map0(JNIEnv *env, jobject this,
+                                     jint prot, jlong off, jlong len)
+{
+    void *mapAddress = 0;
+    jobject fdo = (*env)->GetObjectField(env, this, chan_fd);
+    jint fd = fdval(env, fdo);
+    int protections = 0;
+    int flags = 0;
+
+    if (prot == sun_nio_ch_FileChannelImpl_MAP_RO) {
+        protections = PROT_READ;
+        flags = MAP_SHARED;
+    } else if (prot == sun_nio_ch_FileChannelImpl_MAP_RW) {
+        protections = PROT_WRITE | PROT_READ;
+        flags = MAP_SHARED;
+    } else if (prot == sun_nio_ch_FileChannelImpl_MAP_PV) {
+        protections =  PROT_WRITE | PROT_READ;
+        flags = MAP_PRIVATE;
+    }
+
+    mapAddress = mmap64(
+        0,                    /* Let OS decide location */
+        len,                  /* Number of bytes to map */
+        protections,          /* File permissions */
+        flags,                /* Changes are shared */
+        fd,                   /* File descriptor of mapped file */
+        off);                 /* Offset into file */
+
+    if (mapAddress == MAP_FAILED) {
+        if (errno == ENOMEM) {
+            JNU_ThrowOutOfMemoryError(env, "Map failed");
+            return IOS_THROWN;
+        }
+        return handle(env, -1, "Map failed");
+    }
+
+    return ((jlong) (unsigned long) mapAddress);
+}
+
+
+JNIEXPORT jint JNICALL
+Java_sun_nio_ch_FileChannelImpl_unmap0(JNIEnv *env, jobject this,
+                                       jlong address, jlong len)
+{
+    void *a = (void *)jlong_to_ptr(address);
+    return handle(env,
+                  munmap(a, (size_t)len),
+                  "Unmap failed");
+}
+
+
+JNIEXPORT jlong JNICALL
+Java_sun_nio_ch_FileChannelImpl_position0(JNIEnv *env, jobject this,
+                                          jobject fdo, jlong offset)
+{
+    jint fd = fdval(env, fdo);
+    jlong result = 0;
+
+    if (offset < 0) {
+        result = lseek64(fd, 0, SEEK_CUR);
+    } else {
+        result = lseek64(fd, offset, SEEK_SET);
+    }
+    return handle(env, result, "Position failed");
+}
+
+
+JNIEXPORT void JNICALL
+Java_sun_nio_ch_FileChannelImpl_close0(JNIEnv *env, jobject this, jobject fdo)
+{
+    jint fd = fdval(env, fdo);
+    if (fd != -1) {
+        jlong result = close(fd);
+        if (result < 0) {
+            JNU_ThrowIOExceptionWithLastError(env, "Close failed");
+        }
+    }
+}
+
+JNIEXPORT jlong JNICALL
+Java_sun_nio_ch_FileChannelImpl_transferTo0(JNIEnv *env, jobject this,
+                                            jint srcFD,
+                                            jlong position, jlong count,
+                                            jint dstFD)
+{
+#if defined(__linux__)
+    off64_t offset = (off64_t)position;
+    jlong n = sendfile64(dstFD, srcFD, &offset, (size_t)count);
+    if (n < 0) {
+        if (errno == EAGAIN)
+            return IOS_UNAVAILABLE;
+        if ((errno == EINVAL) && ((ssize_t)count >= 0))
+            return IOS_UNSUPPORTED_CASE;
+        if (errno == EINTR) {
+            return IOS_INTERRUPTED;
+        }
+        JNU_ThrowIOExceptionWithLastError(env, "Transfer failed");
+        return IOS_THROWN;
+    }
+    return n;
+#elif defined (__solaris__)
+    sendfilevec64_t sfv;
+    size_t numBytes = 0;
+    jlong result;
+
+    sfv.sfv_fd = srcFD;
+    sfv.sfv_flag = 0;
+    sfv.sfv_off = (off64_t)position;
+    sfv.sfv_len = count;
+
+    result = sendfilev64(dstFD, &sfv, 1, &numBytes);
+
+    /* Solaris sendfilev() will return -1 even if some bytes have been
+     * transferred, so we check numBytes first.
+     */
+    if (numBytes > 0)
+        return numBytes;
+    if (result < 0) {
+        if (errno == EAGAIN)
+            return IOS_UNAVAILABLE;
+        if (errno == EOPNOTSUPP)
+            return IOS_UNSUPPORTED_CASE;
+        if ((errno == EINVAL) && ((ssize_t)count >= 0))
+            return IOS_UNSUPPORTED_CASE;
+        if (errno == EINTR)
+            return IOS_INTERRUPTED;
+        JNU_ThrowIOExceptionWithLastError(env, "Transfer failed");
+        return IOS_THROWN;
+    }
+    return result;
+#elif defined(__APPLE__)
+    off_t numBytes;
+    int result;
+
+    numBytes = count;
+
+#ifdef __APPLE__
+    result = sendfile(srcFD, dstFD, position, &numBytes, NULL, 0);
+#endif
+
+    if (numBytes > 0)
+        return numBytes;
+
+    if (result == -1) {
+        if (errno == EAGAIN)
+            return IOS_UNAVAILABLE;
+        if (errno == EOPNOTSUPP || errno == ENOTSOCK || errno == ENOTCONN)
+            return IOS_UNSUPPORTED_CASE;
+        if ((errno == EINVAL) && ((ssize_t)count >= 0))
+            return IOS_UNSUPPORTED_CASE;
+        if (errno == EINTR)
+            return IOS_INTERRUPTED;
+        JNU_ThrowIOExceptionWithLastError(env, "Transfer failed");
+        return IOS_THROWN;
+    }
+
+    return result;
+#else
+    return IOS_UNSUPPORTED_CASE;
+#endif
+}
diff --git a/ojluni/src/main/native/FileDescriptor_md.c b/ojluni/src/main/native/FileDescriptor_md.c
new file mode 100755
index 0000000..c279ca9
--- /dev/null
+++ b/ojluni/src/main/native/FileDescriptor_md.c
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 1997, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include "jni.h"
+#include "jni_util.h"
+#include "jvm.h"
+
+#include "java_io_FileDescriptor.h"
+
+/*******************************************************************/
+/*  BEGIN JNI ********* BEGIN JNI *********** BEGIN JNI ************/
+/*******************************************************************/
+
+/* field id for jint 'fd' in java.io.FileDescriptor */
+jfieldID IO_fd_fdID;
+
+/**************************************************************
+ * static methods to store field ID's in initializers
+ */
+
+JNIEXPORT void JNICALL
+Java_java_io_FileDescriptor_initIDs(JNIEnv *env, jclass fdClass) {
+    IO_fd_fdID = (*env)->GetFieldID(env, fdClass, "fd", "I");
+}
+
+/**************************************************************
+ * File Descriptor
+ */
+
+JNIEXPORT void JNICALL
+Java_java_io_FileDescriptor_sync(JNIEnv *env, jobject this) {
+    int fd = (*env)->GetIntField(env, this, IO_fd_fdID);
+    if (JVM_Sync(fd) == -1) {
+        JNU_ThrowByName(env, "java/io/SyncFailedException", "sync failed");
+    }
+}
diff --git a/ojluni/src/main/native/FileDispatcherImpl.c b/ojluni/src/main/native/FileDispatcherImpl.c
new file mode 100755
index 0000000..4d987b9
--- /dev/null
+++ b/ojluni/src/main/native/FileDispatcherImpl.c
@@ -0,0 +1,265 @@
+/*
+ * Copyright (c) 2000, 2009, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include "jni.h"
+#include "jni_util.h"
+#include "jvm.h"
+#include "jlong.h"
+#include "sun_nio_ch_FileDispatcherImpl.h"
+#include "java_lang_Long.h"
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <fcntl.h>
+#include <sys/uio.h>
+#include <unistd.h>
+#include "nio.h"
+#include "nio_util.h"
+
+#ifdef _ALLBSD_SOURCE
+#define stat64 stat
+#define flock64 flock
+#define off64_t off_t
+#define F_SETLKW64 F_SETLKW
+#define F_SETLK64 F_SETLK
+
+#define pread64 pread
+#define pwrite64 pwrite
+#define ftruncate64 ftruncate
+#define fstat64 fstat
+
+#define fdatasync fsync
+#endif
+
+static int preCloseFD = -1;     /* File descriptor to which we dup other fd's
+                                   before closing them for real */
+
+
+JNIEXPORT void JNICALL
+Java_sun_nio_ch_FileDispatcherImpl_init(JNIEnv *env, jclass cl)
+{
+    int sp[2];
+    if (socketpair(PF_UNIX, SOCK_STREAM, 0, sp) < 0) {
+        JNU_ThrowIOExceptionWithLastError(env, "socketpair failed");
+        return;
+    }
+    preCloseFD = sp[0];
+    close(sp[1]);
+}
+
+JNIEXPORT jint JNICALL
+Java_sun_nio_ch_FileDispatcherImpl_read0(JNIEnv *env, jclass clazz,
+                             jobject fdo, jlong address, jint len)
+{
+    jint fd = fdval(env, fdo);
+    void *buf = (void *)jlong_to_ptr(address);
+
+    return convertReturnVal(env, read(fd, buf, len), JNI_TRUE);
+}
+
+JNIEXPORT jint JNICALL
+Java_sun_nio_ch_FileDispatcherImpl_pread0(JNIEnv *env, jclass clazz, jobject fdo,
+                            jlong address, jint len, jlong offset)
+{
+    jint fd = fdval(env, fdo);
+    void *buf = (void *)jlong_to_ptr(address);
+
+    return convertReturnVal(env, pread64(fd, buf, len, offset), JNI_TRUE);
+}
+
+JNIEXPORT jlong JNICALL
+Java_sun_nio_ch_FileDispatcherImpl_readv0(JNIEnv *env, jclass clazz,
+                              jobject fdo, jlong address, jint len)
+{
+    jint fd = fdval(env, fdo);
+    struct iovec *iov = (struct iovec *)jlong_to_ptr(address);
+    return convertLongReturnVal(env, readv(fd, iov, len), JNI_TRUE);
+}
+
+JNIEXPORT jint JNICALL
+Java_sun_nio_ch_FileDispatcherImpl_write0(JNIEnv *env, jclass clazz,
+                              jobject fdo, jlong address, jint len)
+{
+    jint fd = fdval(env, fdo);
+    void *buf = (void *)jlong_to_ptr(address);
+
+    return convertReturnVal(env, write(fd, buf, len), JNI_FALSE);
+}
+
+JNIEXPORT jint JNICALL
+Java_sun_nio_ch_FileDispatcherImpl_pwrite0(JNIEnv *env, jclass clazz, jobject fdo,
+                            jlong address, jint len, jlong offset)
+{
+    jint fd = fdval(env, fdo);
+    void *buf = (void *)jlong_to_ptr(address);
+
+    return convertReturnVal(env, pwrite64(fd, buf, len, offset), JNI_FALSE);
+}
+
+JNIEXPORT jlong JNICALL
+Java_sun_nio_ch_FileDispatcherImpl_writev0(JNIEnv *env, jclass clazz,
+                                       jobject fdo, jlong address, jint len)
+{
+    jint fd = fdval(env, fdo);
+    struct iovec *iov = (struct iovec *)jlong_to_ptr(address);
+    return convertLongReturnVal(env, writev(fd, iov, len), JNI_FALSE);
+}
+
+static jlong
+handle(JNIEnv *env, jlong rv, char *msg)
+{
+    if (rv >= 0)
+        return rv;
+    if (errno == EINTR)
+        return IOS_INTERRUPTED;
+    JNU_ThrowIOExceptionWithLastError(env, msg);
+    return IOS_THROWN;
+}
+
+JNIEXPORT jint JNICALL
+Java_sun_nio_ch_FileDispatcherImpl_force0(JNIEnv *env, jobject this,
+                                          jobject fdo, jboolean md)
+{
+    jint fd = fdval(env, fdo);
+    int result = 0;
+
+    if (md == JNI_FALSE) {
+        result = fdatasync(fd);
+    } else {
+        result = fsync(fd);
+    }
+    return handle(env, result, "Force failed");
+}
+
+JNIEXPORT jint JNICALL
+Java_sun_nio_ch_FileDispatcherImpl_truncate0(JNIEnv *env, jobject this,
+                                             jobject fdo, jlong size)
+{
+    return handle(env,
+                  ftruncate64(fdval(env, fdo), size),
+                  "Truncation failed");
+}
+
+JNIEXPORT jlong JNICALL
+Java_sun_nio_ch_FileDispatcherImpl_size0(JNIEnv *env, jobject this, jobject fdo)
+{
+    struct stat64 fbuf;
+
+    if (fstat64(fdval(env, fdo), &fbuf) < 0)
+        return handle(env, -1, "Size failed");
+    return fbuf.st_size;
+}
+
+JNIEXPORT jint JNICALL
+Java_sun_nio_ch_FileDispatcherImpl_lock0(JNIEnv *env, jobject this, jobject fdo,
+                                      jboolean block, jlong pos, jlong size,
+                                      jboolean shared)
+{
+    jint fd = fdval(env, fdo);
+    jint lockResult = 0;
+    int cmd = 0;
+    struct flock64 fl;
+
+    fl.l_whence = SEEK_SET;
+    if (size == (jlong)java_lang_Long_MAX_VALUE) {
+        fl.l_len = (off64_t)0;
+    } else {
+        fl.l_len = (off64_t)size;
+    }
+    fl.l_start = (off64_t)pos;
+    if (shared == JNI_TRUE) {
+        fl.l_type = F_RDLCK;
+    } else {
+        fl.l_type = F_WRLCK;
+    }
+    if (block == JNI_TRUE) {
+        cmd = F_SETLKW64;
+    } else {
+        cmd = F_SETLK64;
+    }
+    lockResult = fcntl(fd, cmd, &fl);
+    if (lockResult < 0) {
+        if ((cmd == F_SETLK64) && (errno == EAGAIN || errno == EACCES))
+            return sun_nio_ch_FileDispatcherImpl_NO_LOCK;
+        if (errno == EINTR)
+            return sun_nio_ch_FileDispatcherImpl_INTERRUPTED;
+        JNU_ThrowIOExceptionWithLastError(env, "Lock failed");
+    }
+    return 0;
+}
+
+JNIEXPORT void JNICALL
+Java_sun_nio_ch_FileDispatcherImpl_release0(JNIEnv *env, jobject this,
+                                         jobject fdo, jlong pos, jlong size)
+{
+    jint fd = fdval(env, fdo);
+    jint lockResult = 0;
+    struct flock64 fl;
+    int cmd = F_SETLK64;
+
+    fl.l_whence = SEEK_SET;
+    if (size == (jlong)java_lang_Long_MAX_VALUE) {
+        fl.l_len = (off64_t)0;
+    } else {
+        fl.l_len = (off64_t)size;
+    }
+    fl.l_start = (off64_t)pos;
+    fl.l_type = F_UNLCK;
+    lockResult = fcntl(fd, cmd, &fl);
+    if (lockResult < 0) {
+        JNU_ThrowIOExceptionWithLastError(env, "Release failed");
+    }
+}
+
+
+static void closeFileDescriptor(JNIEnv *env, int fd) {
+    if (fd != -1) {
+        int result = close(fd);
+        if (result < 0)
+            JNU_ThrowIOExceptionWithLastError(env, "Close failed");
+    }
+}
+
+JNIEXPORT void JNICALL
+Java_sun_nio_ch_FileDispatcherImpl_close0(JNIEnv *env, jclass clazz, jobject fdo)
+{
+    jint fd = fdval(env, fdo);
+    closeFileDescriptor(env, fd);
+}
+
+JNIEXPORT void JNICALL
+Java_sun_nio_ch_FileDispatcherImpl_preClose0(JNIEnv *env, jclass clazz, jobject fdo)
+{
+    jint fd = fdval(env, fdo);
+    if (preCloseFD >= 0) {
+        if (dup2(preCloseFD, fd) < 0)
+            JNU_ThrowIOExceptionWithLastError(env, "dup2 failed");
+    }
+}
+
+JNIEXPORT void JNICALL
+Java_sun_nio_ch_FileDispatcherImpl_closeIntFD(JNIEnv *env, jclass clazz, jint fd)
+{
+    closeFileDescriptor(env, fd);
+}
diff --git a/ojluni/src/main/native/FileInputStream.c b/ojluni/src/main/native/FileInputStream.c
new file mode 100755
index 0000000..81fdd32
--- /dev/null
+++ b/ojluni/src/main/native/FileInputStream.c
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 1997, 2007, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include "jni.h"
+#include "jni_util.h"
+#include "jlong.h"
+#include "io_util.h"
+
+#include "jvm.h"
+
+#include "java_io_FileInputStream.h"
+
+#include <fcntl.h>
+#include <limits.h>
+
+#include "io_util_md.h"
+
+/*******************************************************************/
+/*  BEGIN JNI ********* BEGIN JNI *********** BEGIN JNI ************/
+/*******************************************************************/
+
+jfieldID fis_fd; /* id for jobject 'fd' in java.io.FileInputStream */
+
+/**************************************************************
+ * static methods to store field ID's in initializers
+ */
+
+JNIEXPORT void JNICALL
+Java_java_io_FileInputStream_initIDs(JNIEnv *env, jclass fdClass) {
+    fis_fd = (*env)->GetFieldID(env, fdClass, "fd", "Ljava/io/FileDescriptor;");
+}
+
+/**************************************************************
+ * Input stream
+ */
+
+JNIEXPORT void JNICALL
+Java_java_io_FileInputStream_open(JNIEnv *env, jobject this, jstring path) {
+    fileOpen(env, this, path, fis_fd, O_RDONLY);
+}
+
+JNIEXPORT jint JNICALL
+Java_java_io_FileInputStream_read0(JNIEnv *env, jobject this) {
+    return readSingle(env, this, fis_fd);
+}
+
+JNIEXPORT jint JNICALL
+Java_java_io_FileInputStream_readBytes(JNIEnv *env, jobject this,
+        jbyteArray bytes, jint off, jint len) {
+    return readBytes(env, this, bytes, off, len, fis_fd);
+}
+
+JNIEXPORT jlong JNICALL
+Java_java_io_FileInputStream_skip(JNIEnv *env, jobject this, jlong toSkip) {
+    jlong cur = jlong_zero;
+    jlong end = jlong_zero;
+    FD fd = GET_FD(this, fis_fd);
+    if (fd == -1) {
+        JNU_ThrowIOException (env, "Stream Closed");
+        return 0;
+    }
+    if ((cur = IO_Lseek(fd, (jlong)0, (jint)SEEK_CUR)) == -1) {
+        JNU_ThrowIOExceptionWithLastError(env, "Seek error");
+    } else if ((end = IO_Lseek(fd, toSkip, (jint)SEEK_CUR)) == -1) {
+        JNU_ThrowIOExceptionWithLastError(env, "Seek error");
+    }
+    return (end - cur);
+}
+
+JNIEXPORT jint JNICALL
+Java_java_io_FileInputStream_available(JNIEnv *env, jobject this) {
+    jlong ret;
+    FD fd = GET_FD(this, fis_fd);
+    if (fd == -1) {
+        JNU_ThrowIOException (env, "Stream Closed");
+        return 0;
+    }
+    if (IO_Available(fd, &ret)) {
+        if (ret > INT_MAX) {
+            ret = (jlong) INT_MAX;
+        }
+        return jlong_to_jint(ret);
+    }
+    JNU_ThrowIOExceptionWithLastError(env, NULL);
+    return 0;
+}
diff --git a/ojluni/src/main/native/FileKey.c b/ojluni/src/main/native/FileKey.c
new file mode 100755
index 0000000..85719b2
--- /dev/null
+++ b/ojluni/src/main/native/FileKey.c
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2005, 2008, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include "jni.h"
+#include "jni_util.h"
+#include "jvm.h"
+#include "nio.h"
+#include "nio_util.h"
+#include "sun_nio_ch_FileKey.h"
+
+#ifdef _ALLBSD_SOURCE
+#define stat64 stat
+
+#define fstat64 fstat
+#endif
+
+static jfieldID key_st_dev;    /* id for FileKey.st_dev */
+static jfieldID key_st_ino;    /* id for FileKey.st_ino */
+
+
+JNIEXPORT void JNICALL
+Java_sun_nio_ch_FileKey_initIDs(JNIEnv *env, jclass clazz)
+{
+    key_st_dev = (*env)->GetFieldID(env, clazz, "st_dev", "J");
+    key_st_ino = (*env)->GetFieldID(env, clazz, "st_ino", "J");
+}
+
+
+JNIEXPORT void JNICALL
+Java_sun_nio_ch_FileKey_init(JNIEnv *env, jobject this, jobject fdo)
+{
+    struct stat64 fbuf;
+    int res;
+
+    RESTARTABLE(fstat64(fdval(env, fdo), &fbuf), res);
+    if (res < 0) {
+        JNU_ThrowIOExceptionWithLastError(env, "fstat64 failed");
+    } else {
+        (*env)->SetLongField(env, this, key_st_dev, (jlong)fbuf.st_dev);
+        (*env)->SetLongField(env, this, key_st_ino, (jlong)fbuf.st_ino);
+    }
+}
diff --git a/ojluni/src/main/native/FileOutputStream_md.c b/ojluni/src/main/native/FileOutputStream_md.c
new file mode 100755
index 0000000..efd5864
--- /dev/null
+++ b/ojluni/src/main/native/FileOutputStream_md.c
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include "jni.h"
+#include "jni_util.h"
+#include "jvm.h"
+
+#include "io_util.h"
+#include "io_util_md.h"
+#include "java_io_FileOutputStream.h"
+
+#include <fcntl.h>
+
+/*******************************************************************/
+/*  BEGIN JNI ********* BEGIN JNI *********** BEGIN JNI ************/
+/*******************************************************************/
+
+jfieldID fos_fd; /* id for jobject 'fd' in java.io.FileOutputStream */
+
+/**************************************************************
+ * static methods to store field ID's in initializers
+ */
+
+JNIEXPORT void JNICALL
+Java_java_io_FileOutputStream_initIDs(JNIEnv *env, jclass fdClass) {
+    fos_fd = (*env)->GetFieldID(env, fdClass, "fd", "Ljava/io/FileDescriptor;");
+}
+
+/**************************************************************
+ * Output stream
+ */
+
+JNIEXPORT void JNICALL
+Java_java_io_FileOutputStream_open(JNIEnv *env, jobject this,
+                                   jstring path, jboolean append) {
+    fileOpen(env, this, path, fos_fd,
+             O_WRONLY | O_CREAT | (append ? O_APPEND : O_TRUNC));
+}
+
+JNIEXPORT void JNICALL
+Java_java_io_FileOutputStream_write(JNIEnv *env, jobject this, jint byte, jboolean append) {
+    writeSingle(env, this, byte, append, fos_fd);
+}
+
+JNIEXPORT void JNICALL
+Java_java_io_FileOutputStream_writeBytes(JNIEnv *env,
+    jobject this, jbyteArray bytes, jint off, jint len, jboolean append) {
+    writeBytes(env, this, bytes, off, len, append, fos_fd);
+}
+
+JNIEXPORT void JNICALL
+Java_java_io_FileOutputStream_close0(JNIEnv *env, jobject this) {
+    fileClose(env, this, fos_fd);
+}
diff --git a/ojluni/src/main/native/FileSystem_md.c b/ojluni/src/main/native/FileSystem_md.c
new file mode 100755
index 0000000..af4aaba
--- /dev/null
+++ b/ojluni/src/main/native/FileSystem_md.c
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 1998, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include "jni.h"
+#include "jni_util.h"
+#include "java_io_FileSystem.h"
+
+
+JNIEXPORT jobject JNICALL
+Java_java_io_FileSystem_getFileSystem(JNIEnv *env, jclass ignored)
+{
+    return JNU_NewObjectByName(env, "java/io/UnixFileSystem", "()V");
+}
diff --git a/ojluni/src/main/native/Float.c b/ojluni/src/main/native/Float.c
new file mode 100755
index 0000000..d63c08f
--- /dev/null
+++ b/ojluni/src/main/native/Float.c
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 1997, 2005, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include "jni.h"
+#include "jvm.h"
+
+#include "java_lang_Float.h"
+
+/*
+ * Find the float corresponding to a given bit pattern
+ */
+JNIEXPORT jfloat JNICALL
+Java_java_lang_Float_intBitsToFloat(JNIEnv *env, jclass unused, jint v)
+{
+    union {
+        int i;
+        float f;
+    } u;
+    u.i = (long)v;
+    return (jfloat)u.f;
+}
+
+/*
+ * Find the bit pattern corresponding to a given float, NOT collapsing NaNs
+ */
+JNIEXPORT jint JNICALL
+Java_java_lang_Float_floatToRawIntBits(JNIEnv *env, jclass unused, jfloat v)
+{
+    union {
+        int i;
+        float f;
+    } u;
+    u.f = (float)v;
+    return (jint)u.i;
+}
diff --git a/ojluni/src/main/native/IOUtil.c b/ojluni/src/main/native/IOUtil.c
new file mode 100755
index 0000000..faa7e36
--- /dev/null
+++ b/ojluni/src/main/native/IOUtil.c
@@ -0,0 +1,203 @@
+/*
+ * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include <sys/types.h>
+#include <string.h>
+#include <sys/resource.h>
+
+#include "jni.h"
+#include "jni_util.h"
+#include "jvm.h"
+#include "jlong.h"
+#include "sun_nio_ch_IOUtil.h"
+#include "java_lang_Integer.h"
+#include "nio.h"
+#include "nio_util.h"
+
+static jfieldID fd_fdID;        /* for jint 'fd' in java.io.FileDescriptor */
+
+
+JNIEXPORT void JNICALL
+Java_sun_nio_ch_IOUtil_initIDs(JNIEnv *env, jclass clazz)
+{
+    clazz = (*env)->FindClass(env, "java/io/FileDescriptor");
+    fd_fdID = (*env)->GetFieldID(env, clazz, "fd", "I");
+}
+
+JNIEXPORT jboolean JNICALL
+Java_sun_nio_ch_IOUtil_randomBytes(JNIEnv *env, jclass clazz,
+                                  jbyteArray randArray)
+{
+    JNU_ThrowByName(env, "java/lang/UnsupportedOperationException", NULL);
+    return JNI_FALSE;
+}
+
+JNIEXPORT jint JNICALL
+Java_sun_nio_ch_IOUtil_fdVal(JNIEnv *env, jclass clazz, jobject fdo)
+{
+    return (*env)->GetIntField(env, fdo, fd_fdID);
+}
+
+JNIEXPORT void JNICALL
+Java_sun_nio_ch_IOUtil_setfdVal(JNIEnv *env, jclass clazz, jobject fdo, jint val)
+{
+    (*env)->SetIntField(env, fdo, fd_fdID, val);
+}
+
+static int
+configureBlocking(int fd, jboolean blocking)
+{
+    int flags = fcntl(fd, F_GETFL);
+    int newflags = blocking ? (flags & ~O_NONBLOCK) : (flags | O_NONBLOCK);
+
+    return (flags == newflags) ? 0 : fcntl(fd, F_SETFL, newflags);
+}
+
+JNIEXPORT void JNICALL
+Java_sun_nio_ch_IOUtil_configureBlocking(JNIEnv *env, jclass clazz,
+                                         jobject fdo, jboolean blocking)
+{
+    if (configureBlocking(fdval(env, fdo), blocking) < 0)
+        JNU_ThrowIOExceptionWithLastError(env, "Configure blocking failed");
+}
+
+JNIEXPORT jlong JNICALL
+Java_sun_nio_ch_IOUtil_makePipe(JNIEnv *env, jobject this, jboolean blocking)
+{
+    int fd[2];
+
+    if (pipe(fd) < 0) {
+        JNU_ThrowIOExceptionWithLastError(env, "Pipe failed");
+        return 0;
+    }
+    if (blocking == JNI_FALSE) {
+        if ((configureBlocking(fd[0], JNI_FALSE) < 0)
+            || (configureBlocking(fd[1], JNI_FALSE) < 0)) {
+            JNU_ThrowIOExceptionWithLastError(env, "Configure blocking failed");
+            close(fd[0]);
+            close(fd[1]);
+            return 0;
+        }
+    }
+    return ((jlong) fd[0] << 32) | (jlong) fd[1];
+}
+
+JNIEXPORT jboolean JNICALL
+Java_sun_nio_ch_IOUtil_drain(JNIEnv *env, jclass cl, jint fd)
+{
+    char buf[128];
+    int tn = 0;
+
+    for (;;) {
+        int n = read(fd, buf, sizeof(buf));
+        tn += n;
+        if ((n < 0) && (errno != EAGAIN))
+            JNU_ThrowIOExceptionWithLastError(env, "Drain");
+        if (n == (int)sizeof(buf))
+            continue;
+        return (tn > 0) ? JNI_TRUE : JNI_FALSE;
+    }
+}
+
+JNIEXPORT jint JNICALL
+Java_sun_nio_ch_IOUtil_fdLimit(JNIEnv *env, jclass this)
+{
+    struct rlimit rlp;
+    if (getrlimit(RLIMIT_NOFILE, &rlp) < 0) {
+        JNU_ThrowIOExceptionWithLastError(env, "getrlimit failed");
+        return -1;
+    }
+    if (rlp.rlim_max < 0 || rlp.rlim_max > java_lang_Integer_MAX_VALUE) {
+        return java_lang_Integer_MAX_VALUE;
+    } else {
+        return (jint)rlp.rlim_max;
+    }
+}
+
+/* Declared in nio_util.h for use elsewhere in NIO */
+
+jint
+convertReturnVal(JNIEnv *env, jint n, jboolean reading)
+{
+    if (n > 0) /* Number of bytes written */
+        return n;
+    else if (n == 0) {
+        if (reading) {
+            return IOS_EOF; /* EOF is -1 in javaland */
+        } else {
+            return 0;
+        }
+    }
+    else if (errno == EAGAIN)
+        return IOS_UNAVAILABLE;
+    else if (errno == EINTR)
+        return IOS_INTERRUPTED;
+    else {
+        const char *msg = reading ? "Read failed" : "Write failed";
+        JNU_ThrowIOExceptionWithLastError(env, msg);
+        return IOS_THROWN;
+    }
+}
+
+JNIEXPORT jint JNICALL
+Java_sun_nio_ch_IOUtil_iovMax(JNIEnv *env, jclass this)
+{
+    jlong iov_max = sysconf(_SC_IOV_MAX);
+    if (iov_max == -1)
+        iov_max = 16;
+    return (jint)iov_max;
+}
+
+
+/* Declared in nio_util.h for use elsewhere in NIO */
+
+jlong
+convertLongReturnVal(JNIEnv *env, jlong n, jboolean reading)
+{
+    if (n > 0) /* Number of bytes written */
+        return n;
+    else if (n == 0) {
+        if (reading) {
+            return IOS_EOF; /* EOF is -1 in javaland */
+        } else {
+            return 0;
+        }
+    }
+    else if (errno == EAGAIN)
+        return IOS_UNAVAILABLE;
+    else if (errno == EINTR)
+        return IOS_INTERRUPTED;
+    else {
+        const char *msg = reading ? "Read failed" : "Write failed";
+        JNU_ThrowIOExceptionWithLastError(env, msg);
+        return IOS_THROWN;
+    }
+}
+
+jint
+fdval(JNIEnv *env, jobject fdo)
+{
+    return (*env)->GetIntField(env, fdo, fd_fdID);
+}
diff --git a/ojluni/src/main/native/Inet4Address.c b/ojluni/src/main/native/Inet4Address.c
new file mode 100755
index 0000000..2030471
--- /dev/null
+++ b/ojluni/src/main/native/Inet4Address.c
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2000, 2002, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include <string.h>
+
+#include "java_net_Inet4Address.h"
+#include "net_util.h"
+
+/************************************************************************
+ * Inet4Address
+ */
+jclass ia4_class;
+jmethodID ia4_ctrID;
+
+/*
+ * Class:     java_net_Inet4Address
+ * Method:    init
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL
+Java_java_net_Inet4Address_init(JNIEnv *env, jclass cls) {
+    jclass c = (*env)->FindClass(env, "java/net/Inet4Address");
+    CHECK_NULL(c);
+    ia4_class = (*env)->NewGlobalRef(env, c);
+    CHECK_NULL(ia4_class);
+    ia4_ctrID = (*env)->GetMethodID(env, ia4_class, "<init>", "()V");
+    CHECK_NULL(ia4_ctrID);
+}
diff --git a/ojluni/src/main/native/Inet4AddressImpl.c b/ojluni/src/main/native/Inet4AddressImpl.c
new file mode 100755
index 0000000..1aa2de0
--- /dev/null
+++ b/ojluni/src/main/native/Inet4AddressImpl.c
@@ -0,0 +1,858 @@
+/*
+ * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include <errno.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in_systm.h>
+#include <netinet/in.h>
+#include <netinet/ip.h>
+#include <netinet/ip_icmp.h>
+#include <netdb.h>
+#include <string.h>
+#include <stdlib.h>
+#include <ctype.h>
+
+#ifdef _ALLBSD_SOURCE
+#include <unistd.h>
+#include <sys/param.h>
+#endif
+
+#include "jvm.h"
+#include "jni_util.h"
+#include "net_util.h"
+
+#include "java_net_Inet4AddressImpl.h"
+
+#if defined(__GLIBC__) || (defined(__FreeBSD__) && (__FreeBSD_version >= 601104))
+#define HAS_GLIBC_GETHOSTBY_R   1
+#endif
+
+#if defined(_ALLBSD_SOURCE) && !defined(HAS_GLIBC_GETHOSTBY_R)
+/* Use getaddrinfo(3), which is thread safe */
+/************************************************************************
+ * Inet4AddressImpl
+ */
+
+/*
+ * Class:     java_net_Inet4AddressImpl
+ * Method:    getLocalHostName
+ * Signature: ()Ljava/lang/String;
+ */
+JNIEXPORT jstring JNICALL
+Java_java_net_Jnet4AddressImpl_getLocalHostName(JNIEnv *env, jobject this) {
+    char hostname[NI_MAXHOST+1];
+
+    hostname[0] = '\0';
+    if (JVM_GetHostName(hostname, NI_MAXHOST)) {
+        /* Something went wrong, maybe networking is not setup? */
+        strcpy(hostname, "localhost");
+    } else {
+         struct addrinfo  hints, *res;
+         int error;
+
+         memset(&hints, 0, sizeof(hints));
+         hints.ai_flags = AI_CANONNAME;
+         hints.ai_family = AF_UNSPEC;
+
+         error = getaddrinfo(hostname, NULL, &hints, &res);
+
+         if (error == 0) {
+             /* host is known to name service */
+             error = getnameinfo(res->ai_addr,
+                                 res->ai_addrlen,
+                                 hostname,
+                                 NI_MAXHOST,
+                                 NULL,
+                                 0,
+                                 NI_NAMEREQD);
+
+             /* if getnameinfo fails hostname is still the value
+                from gethostname */
+
+             freeaddrinfo(res);
+        }
+    }
+    return (*env)->NewStringUTF(env, hostname);
+}
+
+static jclass ni_iacls;
+static jclass ni_ia4cls;
+static jmethodID ni_ia4ctrID;
+static int initialized = 0;
+
+/*
+ * Find an internet address for a given hostname.  Note that this
+ * code only works for addresses of type INET. The translation
+ * of %d.%d.%d.%d to an address (int) occurs in java now, so the
+ * String "host" shouldn't *ever* be a %d.%d.%d.%d string
+ *
+ * Class:     java_net_Inet4AddressImpl
+ * Method:    lookupAllHostAddr
+ * Signature: (Ljava/lang/String;)[[B
+ */
+
+JNIEXPORT jobjectArray JNICALL
+Java_java_net_Jnet4AddressImpl_lookupAllHostAddr(JNIEnv *env, jobject this,
+                                                jstring host) {
+    const char *hostname;
+    jobject name;
+    jobjectArray ret = 0;
+    int retLen = 0;
+
+    int error=0;
+    struct addrinfo hints, *res, *resNew = NULL;
+
+    if (!initialized) {
+      ni_iacls = (*env)->FindClass(env, "java/net/InetAddress");
+      ni_iacls = (*env)->NewGlobalRef(env, ni_iacls);
+      ni_ia4cls = (*env)->FindClass(env, "java/net/Inet4Address");
+      ni_ia4cls = (*env)->NewGlobalRef(env, ni_ia4cls);
+      ni_ia4ctrID = (*env)->GetMethodID(env, ni_ia4cls, "<init>", "()V");
+      initialized = 1;
+    }
+
+    if (IS_NULL(host)) {
+        JNU_ThrowNullPointerException(env, "host is null");
+        return 0;
+    }
+    hostname = JNU_GetStringPlatformChars(env, host, JNI_FALSE);
+    CHECK_NULL_RETURN(hostname, NULL);
+
+    memset(&hints, 0, sizeof(hints));
+    hints.ai_flags = AI_CANONNAME;
+    hints.ai_family = AF_INET;
+
+    /*
+     * Workaround for Solaris bug 4160367 - if a hostname contains a
+     * white space then 0.0.0.0 is returned
+     */
+    if (isspace((unsigned char)hostname[0])) {
+        JNU_ThrowByName(env, JNU_JAVANETPKG "UnknownHostException",
+                        (char *)hostname);
+        JNU_ReleaseStringPlatformChars(env, host, hostname);
+        return NULL;
+    }
+
+    error = getaddrinfo(hostname, NULL, &hints, &res);
+
+    if (error) {
+        /* report error */
+        JNU_ThrowByName(env, JNU_JAVANETPKG "UnknownHostException",
+                        (char *)hostname);
+        JNU_ReleaseStringPlatformChars(env, host, hostname);
+        return NULL;
+    } else {
+        int i = 0;
+        struct addrinfo *itr, *last = NULL, *iterator = res;
+        while (iterator != NULL) {
+            int skip = 0;
+            itr = resNew;
+
+            while (itr != NULL) {
+                struct sockaddr_in *addr1, *addr2;
+
+                addr1 = (struct sockaddr_in *)iterator->ai_addr;
+                addr2 = (struct sockaddr_in *)itr->ai_addr;
+                if (addr1->sin_addr.s_addr ==
+                    addr2->sin_addr.s_addr) {
+                    skip = 1;
+                    break;
+                }
+
+                itr = itr->ai_next;
+            }
+
+            if (!skip) {
+                struct addrinfo *next
+                    = (struct addrinfo*) malloc(sizeof(struct addrinfo));
+                if (!next) {
+                    JNU_ThrowOutOfMemoryError(env, "Native heap allocation failed");
+                    ret = NULL;
+                    goto cleanupAndReturn;
+                }
+                memcpy(next, iterator, sizeof(struct addrinfo));
+                next->ai_next = NULL;
+                if (resNew == NULL) {
+                    resNew = next;
+                } else {
+                    last->ai_next = next;
+                }
+                last = next;
+                i++;
+            }
+            iterator = iterator->ai_next;
+        }
+
+        retLen = i;
+        iterator = resNew;
+        i = 0;
+
+        name = (*env)->NewStringUTF(env, hostname);
+        if (IS_NULL(name)) {
+          goto cleanupAndReturn;
+        }
+
+        ret = (*env)->NewObjectArray(env, retLen, ni_iacls, NULL);
+        if (IS_NULL(ret)) {
+            /* we may have memory to free at the end of this */
+            goto cleanupAndReturn;
+        }
+
+        while (iterator != NULL) {
+            /* We need 4 bytes to store ipv4 address; */
+            int len = 4;
+
+            jobject iaObj = (*env)->NewObject(env, ni_ia4cls, ni_ia4ctrID);
+            if (IS_NULL(iaObj)) {
+                /* we may have memory to free at the end of this */
+                ret = NULL;
+                goto cleanupAndReturn;
+            }
+            setInetAddress_addr(env, iaObj, ntohl(((struct sockaddr_in*)(iterator->ai_addr))->sin_addr.s_addr));
+            setInetAddress_hostName(env, iaObj, name);
+            (*env)->SetObjectArrayElement(env, ret, retLen - i -1, iaObj);
+            i++;
+            iterator = iterator->ai_next;
+        }
+    }
+
+cleanupAndReturn:
+    {
+        struct addrinfo *iterator, *tmp;
+        iterator = resNew;
+        while (iterator != NULL) {
+            tmp = iterator;
+            iterator = iterator->ai_next;
+            free(tmp);
+        }
+        JNU_ReleaseStringPlatformChars(env, host, hostname);
+    }
+
+    freeaddrinfo(res);
+
+    return ret;
+
+}
+
+/*
+ * Class:     java_net_Inet4AddressImpl
+ * Method:    getHostByAddr
+ * Signature: (I)Ljava/lang/String;
+ */
+JNIEXPORT jstring JNICALL
+Java_java_net_Jnet4AddressImpl_getHostByAddr(JNIEnv *env, jobject this,
+                                            jbyteArray addrArray) {
+    jstring ret = NULL;
+
+    char host[NI_MAXHOST+1];
+    jfieldID fid;
+    int error = 0;
+    jint family;
+    struct sockaddr *him ;
+    int len = 0;
+    jbyte caddr[4];
+    jint addr;
+
+    struct sockaddr_in him4;
+    struct sockaddr *sa;
+
+    /*
+         * For IPv4 addresses construct a sockaddr_in structure.
+         */
+    (*env)->GetByteArrayRegion(env, addrArray, 0, 4, caddr);
+    addr = ((caddr[0]<<24) & 0xff000000);
+    addr |= ((caddr[1] <<16) & 0xff0000);
+    addr |= ((caddr[2] <<8) & 0xff00);
+    addr |= (caddr[3] & 0xff);
+    memset((char *) &him4, 0, sizeof(him4));
+    him4.sin_addr.s_addr = (uint32_t) htonl(addr);
+    him4.sin_family = AF_INET;
+    sa = (struct sockaddr *) &him4;
+    len = sizeof(him4);
+
+    error = getnameinfo(sa, len, host, NI_MAXHOST, NULL, 0,
+                               NI_NAMEREQD);
+
+    if (!error) {
+        ret = (*env)->NewStringUTF(env, host);
+    }
+
+    if (ret == NULL) {
+        JNU_ThrowByName(env, JNU_JAVANETPKG "UnknownHostException", NULL);
+    }
+
+    return ret;
+
+}
+
+#else /* defined(_ALLBSD_SOURCE) && !defined(HAS_GLIBC_GETHOSTBY_R) */
+
+/* the initial size of our hostent buffers */
+#define HENT_BUF_SIZE 1024
+#define BIG_HENT_BUF_SIZE 10240  /* a jumbo-sized one */
+
+/************************************************************************
+ * Inet4AddressImpl
+ */
+
+/*
+ * Class:     java_net_Inet4AddressImpl
+ * Method:    getLocalHostName
+ * Signature: ()Ljava/lang/String;
+ */
+JNIEXPORT jstring JNICALL
+Java_java_net_Jnet4AddressImpl_getLocalHostName(JNIEnv *env, jobject this) {
+    char hostname[MAXHOSTNAMELEN+1];
+
+    hostname[0] = '\0';
+    if (JVM_GetHostName(hostname, sizeof(hostname))) {
+        /* Something went wrong, maybe networking is not setup? */
+        strcpy(hostname, "localhost");
+    } else {
+#ifdef __linux__
+        /* On Linux gethostname() says "host.domain.sun.com".  On
+         * Solaris gethostname() says "host", so extra work is needed.
+         */
+#else
+        /* Solaris doesn't want to give us a fully qualified domain name.
+         * We do a reverse lookup to try and get one.  This works
+         * if DNS occurs before NIS in /etc/resolv.conf, but fails
+         * if NIS comes first (it still gets only a partial name).
+         * We use thread-safe system calls.
+         */
+#endif /* __linux__ */
+        struct hostent res, res2, *hp;
+        // these buffers must be pointer-aligned so they are declared
+        // with pointer type
+        char *buf[HENT_BUF_SIZE/(sizeof (char *))];
+        char *buf2[HENT_BUF_SIZE/(sizeof (char *))];
+        int h_error=0;
+
+        // ensure null-terminated
+        hostname[MAXHOSTNAMELEN] = '\0';
+
+#ifdef HAS_GLIBC_GETHOSTBY_R
+        gethostbyname_r(hostname, &res, (char*)buf, sizeof(buf), &hp, &h_error);
+#else
+        hp = gethostbyname_r(hostname, &res, (char*)buf, sizeof(buf), &h_error);
+#endif
+        if (hp) {
+#ifdef HAS_GLIBC_GETHOSTBY_R
+            gethostbyaddr_r(hp->h_addr, hp->h_length, AF_INET,
+                            &res2, (char*)buf2, sizeof(buf2), &hp, &h_error);
+#else
+            hp = gethostbyaddr_r(hp->h_addr, hp->h_length, AF_INET,
+                                 &res2, (char*)buf2, sizeof(buf2), &h_error);
+#endif
+            if (hp) {
+                /*
+                 * If gethostbyaddr_r() found a fully qualified host name,
+                 * returns that name. Otherwise, returns the hostname
+                 * found by gethostname().
+                 */
+                char *p = hp->h_name;
+                if ((strlen(hp->h_name) > strlen(hostname))
+                    && (strncmp(hostname, hp->h_name, strlen(hostname)) == 0)
+                    && (*(p + strlen(hostname)) == '.'))
+                    strcpy(hostname, hp->h_name);
+            }
+        }
+    }
+    return (*env)->NewStringUTF(env, hostname);
+}
+
+static jclass ni_iacls;
+static jclass ni_ia4cls;
+static jmethodID ni_ia4ctrID;
+static int initialized = 0;
+
+/*
+ * Find an internet address for a given hostname.  Note that this
+ * code only works for addresses of type INET. The translation
+ * of %d.%d.%d.%d to an address (int) occurs in java now, so the
+ * String "host" shouldn't *ever* be a %d.%d.%d.%d string
+ *
+ * Class:     java_net_Inet4AddressImpl
+ * Method:    lookupAllHostAddr
+ * Signature: (Ljava/lang/String;)[[B
+ */
+
+JNIEXPORT jobjectArray JNICALL
+Java_java_net_Jnet4AddressImpl_lookupAllHostAddr(JNIEnv *env, jobject this,
+                                                jstring host) {
+    const char *hostname;
+    jobjectArray ret = 0;
+    struct hostent res, *hp = 0;
+    // this buffer must be pointer-aligned so is declared
+    // with pointer type
+    char *buf[HENT_BUF_SIZE/(sizeof (char *))];
+
+    /* temporary buffer, on the off chance we need to expand */
+    char *tmp = NULL;
+    int h_error=0;
+
+    if (!initialized) {
+      ni_iacls = (*env)->FindClass(env, "java/net/InetAddress");
+      ni_iacls = (*env)->NewGlobalRef(env, ni_iacls);
+      ni_ia4cls = (*env)->FindClass(env, "java/net/Inet4Address");
+      ni_ia4cls = (*env)->NewGlobalRef(env, ni_ia4cls);
+      ni_ia4ctrID = (*env)->GetMethodID(env, ni_ia4cls, "<init>", "()V");
+      initialized = 1;
+    }
+
+    if (IS_NULL(host)) {
+        JNU_ThrowNullPointerException(env, "host is null");
+        return 0;
+    }
+    hostname = JNU_GetStringPlatformChars(env, host, JNI_FALSE);
+    CHECK_NULL_RETURN(hostname, NULL);
+
+#ifdef __solaris__
+    /*
+     * Workaround for Solaris bug 4160367 - if a hostname contains a
+     * white space then 0.0.0.0 is returned
+     */
+    if (isspace((unsigned char)hostname[0])) {
+        JNU_ThrowByName(env, JNU_JAVANETPKG "UnknownHostException",
+                        (char *)hostname);
+        JNU_ReleaseStringPlatformChars(env, host, hostname);
+        return NULL;
+    }
+#endif
+
+    /* Try once, with our static buffer. */
+#ifdef HAS_GLIBC_GETHOSTBY_R
+    gethostbyname_r(hostname, &res, (char*)buf, sizeof(buf), &hp, &h_error);
+#else
+    hp = gethostbyname_r(hostname, &res, (char*)buf, sizeof(buf), &h_error);
+#endif
+
+    /* With the re-entrant system calls, it's possible that the buffer
+     * we pass to it is not large enough to hold an exceptionally
+     * large DNS entry.  This is signaled by errno->ERANGE.  We try once
+     * more, with a very big size.
+     */
+    if (hp == NULL && errno == ERANGE) {
+        if ((tmp = (char*)malloc(BIG_HENT_BUF_SIZE))) {
+#ifdef HAS_GLIBC_GETHOSTBY_R
+            gethostbyname_r(hostname, &res, tmp, BIG_HENT_BUF_SIZE,
+                            &hp, &h_error);
+#else
+            hp = gethostbyname_r(hostname, &res, tmp, BIG_HENT_BUF_SIZE,
+                                 &h_error);
+#endif
+        }
+    }
+    if (hp != NULL) {
+        struct in_addr **addrp = (struct in_addr **) hp->h_addr_list;
+        int i = 0;
+
+        while (*addrp != (struct in_addr *) 0) {
+            i++;
+            addrp++;
+        }
+
+        ret = (*env)->NewObjectArray(env, i, ni_iacls, NULL);
+        if (IS_NULL(ret)) {
+            /* we may have memory to free at the end of this */
+            goto cleanupAndReturn;
+        }
+        addrp = (struct in_addr **) hp->h_addr_list;
+        i = 0;
+        while (*addrp) {
+          jobject iaObj = (*env)->NewObject(env, ni_ia4cls, ni_ia4ctrID);
+          if (IS_NULL(iaObj)) {
+            ret = NULL;
+            goto cleanupAndReturn;
+          }
+          setInetAddress_addr(env, iaObj, ntohl((*addrp)->s_addr));
+          setInetAddress_hostName(env, iaObj, host);
+          (*env)->SetObjectArrayElement(env, ret, i, iaObj);
+          addrp++;
+          i++;
+        }
+    } else {
+        JNU_ThrowByName(env, JNU_JAVANETPKG "UnknownHostException",
+                        (char *)hostname);
+        ret = NULL;
+    }
+
+cleanupAndReturn:
+    JNU_ReleaseStringPlatformChars(env, host, hostname);
+    if (tmp != NULL) {
+        free(tmp);
+    }
+    return ret;
+}
+
+/*
+ * Class:     java_net_Inet4AddressImpl
+ * Method:    getHostByAddr
+ * Signature: (I)Ljava/lang/String;
+ */
+JNIEXPORT jstring JNICALL
+Java_java_net_Jnet4AddressImpl_getHostByAddr(JNIEnv *env, jobject this,
+                                            jbyteArray addrArray) {
+    jstring ret = NULL;
+    jint addr;
+    struct hostent hent, *hp = 0;
+    // this buffer must be pointer-aligned so is declared
+    // with pointer type
+    char *buf[HENT_BUF_SIZE/(sizeof (char *))];
+    int h_error = 0;
+    char *tmp = NULL;
+
+    /*
+     * We are careful here to use the reentrant version of
+     * gethostbyname because at the Java level this routine is not
+     * protected by any synchronization.
+     *
+     * Still keeping the reentrant platform dependent calls temporarily
+     * We should probably conform to one interface later.
+     *
+     */
+    jbyte caddr[4];
+    (*env)->GetByteArrayRegion(env, addrArray, 0, 4, caddr);
+    addr = ((caddr[0]<<24) & 0xff000000);
+    addr |= ((caddr[1] <<16) & 0xff0000);
+    addr |= ((caddr[2] <<8) & 0xff00);
+    addr |= (caddr[3] & 0xff);
+    addr = htonl(addr);
+#ifdef HAS_GLIBC_GETHOSTBY_R
+    gethostbyaddr_r((char *)&addr, sizeof(addr), AF_INET, &hent,
+                    (char*)buf, sizeof(buf), &hp, &h_error);
+#else
+    hp = gethostbyaddr_r((char *)&addr, sizeof(addr), AF_INET, &hent,
+                         (char*)buf, sizeof(buf), &h_error);
+#endif
+    /* With the re-entrant system calls, it's possible that the buffer
+     * we pass to it is not large enough to hold an exceptionally
+     * large DNS entry.  This is signaled by errno->ERANGE.  We try once
+     * more, with a very big size.
+     */
+    if (hp == NULL && errno == ERANGE) {
+        if ((tmp = (char*)malloc(BIG_HENT_BUF_SIZE))) {
+#ifdef HAS_GLIBC_GETHOSTBY_R
+            gethostbyaddr_r((char *)&addr, sizeof(addr), AF_INET,
+                            &hent, tmp, BIG_HENT_BUF_SIZE, &hp, &h_error);
+#else
+            hp = gethostbyaddr_r((char *)&addr, sizeof(addr), AF_INET,
+                                 &hent, tmp, BIG_HENT_BUF_SIZE, &h_error);
+#endif
+        } else {
+            JNU_ThrowOutOfMemoryError(env, "getHostByAddr");
+        }
+    }
+    if (hp == NULL) {
+        JNU_ThrowByName(env, JNU_JAVANETPKG "UnknownHostException", NULL);
+    } else {
+        ret = (*env)->NewStringUTF(env, hp->h_name);
+    }
+    if (tmp) {
+        free(tmp);
+    }
+    return ret;
+}
+
+#endif /* _ALLBSD_SOURCE */
+
+#define SET_NONBLOCKING(fd) {           \
+        int flags = fcntl(fd, F_GETFL); \
+        flags |= O_NONBLOCK;            \
+        fcntl(fd, F_SETFL, flags);      \
+}
+
+/**
+ * ping implementation.
+ * Send a ICMP_ECHO_REQUEST packet every second until either the timeout
+ * expires or a answer is received.
+ * Returns true is an ECHO_REPLY is received, otherwise, false.
+ */
+static jboolean
+ping4(JNIEnv *env, jint fd, struct sockaddr_in* him, jint timeout,
+      struct sockaddr_in* netif, jint ttl) {
+    jint size;
+    jint n, hlen1, icmplen;
+    socklen_t len;
+    char sendbuf[1500];
+    char recvbuf[1500];
+    struct icmp *icmp;
+    struct ip *ip;
+    struct sockaddr_in sa_recv;
+    jchar pid;
+    jint tmout2, seq = 1;
+    struct timeval tv;
+    size_t plen;
+
+    /* icmp_id is a 16 bit data type, therefore down cast the pid */
+    pid = (jchar)getpid();
+    size = 60*1024;
+    setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &size, sizeof(size));
+    /*
+     * sets the ttl (max number of hops)
+     */
+    if (ttl > 0) {
+      setsockopt(fd, IPPROTO_IP, IP_TTL, &ttl, sizeof(ttl));
+    }
+    /*
+     * a specific interface was specified, so let's bind the socket
+     * to that interface to ensure the requests are sent only through it.
+     */
+    if (netif != NULL) {
+      if (bind(fd, (struct sockaddr*)netif, sizeof(struct sockaddr_in)) < 0) {
+        NET_ThrowNew(env, errno, "Can't bind socket");
+        close(fd);
+        return JNI_FALSE;
+      }
+    }
+    /*
+     * Make the socket non blocking so we can use select
+     */
+    SET_NONBLOCKING(fd);
+    do {
+      /*
+       * create the ICMP request
+       */
+      icmp = (struct icmp *) sendbuf;
+      icmp->icmp_type = ICMP_ECHO;
+      icmp->icmp_code = 0;
+      icmp->icmp_id = htons(pid);
+      icmp->icmp_seq = htons(seq);
+      seq++;
+      gettimeofday(&tv, NULL);
+      memcpy(icmp->icmp_data, &tv, sizeof(tv));
+      plen = ICMP_ADVLENMIN + sizeof(tv);
+      icmp->icmp_cksum = 0;
+      icmp->icmp_cksum = in_cksum((u_short *)icmp, plen);
+      /*
+       * send it
+       */
+      n = sendto(fd, sendbuf, plen, 0, (struct sockaddr *)him,
+                 sizeof(struct sockaddr));
+      if (n < 0 && errno != EINPROGRESS ) {
+#ifdef __linux__
+        if (errno != EINVAL && errno != EHOSTUNREACH)
+          /*
+           * On some Linuxes, when bound to the loopback interface, sendto
+           * will fail and errno will be set to EINVAL or EHOSTUNREACH.
+           * When that happens, don't throw an exception, just return false.
+           */
+#endif /*__linux__ */
+          NET_ThrowNew(env, errno, "Can't send ICMP packet");
+        close(fd);
+        return JNI_FALSE;
+      }
+
+      tmout2 = timeout > 1000 ? 1000 : timeout;
+      do {
+        tmout2 = NET_Wait(env, fd, NET_WAIT_READ, tmout2);
+        if (tmout2 >= 0) {
+          len = sizeof(sa_recv);
+          n = recvfrom(fd, recvbuf, sizeof(recvbuf), 0, (struct sockaddr *)&sa_recv, &len);
+          ip = (struct ip*) recvbuf;
+          hlen1 = (ip->ip_hl) << 2;
+          icmp = (struct icmp *) (recvbuf + hlen1);
+          icmplen = n - hlen1;
+          /*
+           * We did receive something, but is it what we were expecting?
+           * I.E.: A ICMP_ECHOREPLY packet with the proper PID.
+           */
+          if (icmplen >= 8 && icmp->icmp_type == ICMP_ECHOREPLY
+               && (ntohs(icmp->icmp_id) == pid)) {
+            if ((him->sin_addr.s_addr == sa_recv.sin_addr.s_addr)) {
+              close(fd);
+              return JNI_TRUE;
+            }
+
+            if (him->sin_addr.s_addr == 0) {
+              close(fd);
+              return JNI_TRUE;
+            }
+         }
+
+        }
+      } while (tmout2 > 0);
+      timeout -= 1000;
+    } while (timeout >0);
+    close(fd);
+    return JNI_FALSE;
+}
+
+/*
+ * Class:     java_net_Inet4AddressImpl
+ * Method:    isReachable0
+ * Signature: ([bI[bI)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_java_net_Jnet4AddressImpl_isReachable0(JNIEnv *env, jobject this,
+                                           jbyteArray addrArray,
+                                           jint timeout,
+                                           jbyteArray ifArray,
+                                           jint ttl) {
+    jint addr;
+    jbyte caddr[4];
+    jint fd;
+    struct sockaddr_in him;
+    struct sockaddr_in* netif = NULL;
+    struct sockaddr_in inf;
+    int len = 0;
+    int connect_rv = -1;
+    int sz;
+
+    memset((char *) caddr, 0, sizeof(caddr));
+    memset((char *) &him, 0, sizeof(him));
+    memset((char *) &inf, 0, sizeof(inf));
+    sz = (*env)->GetArrayLength(env, addrArray);
+    if (sz != 4) {
+      return JNI_FALSE;
+    }
+    (*env)->GetByteArrayRegion(env, addrArray, 0, 4, caddr);
+    addr = ((caddr[0]<<24) & 0xff000000);
+    addr |= ((caddr[1] <<16) & 0xff0000);
+    addr |= ((caddr[2] <<8) & 0xff00);
+    addr |= (caddr[3] & 0xff);
+    addr = htonl(addr);
+    him.sin_addr.s_addr = addr;
+    him.sin_family = AF_INET;
+    len = sizeof(him);
+    /*
+     * If a network interface was specified, let's create the address
+     * for it.
+     */
+    if (!(IS_NULL(ifArray))) {
+      memset((char *) caddr, 0, sizeof(caddr));
+      (*env)->GetByteArrayRegion(env, ifArray, 0, 4, caddr);
+      addr = ((caddr[0]<<24) & 0xff000000);
+      addr |= ((caddr[1] <<16) & 0xff0000);
+      addr |= ((caddr[2] <<8) & 0xff00);
+      addr |= (caddr[3] & 0xff);
+      addr = htonl(addr);
+      inf.sin_addr.s_addr = addr;
+      inf.sin_family = AF_INET;
+      inf.sin_port = 0;
+      netif = &inf;
+    }
+
+    /*
+     * Let's try to create a RAW socket to send ICMP packets
+     * This usually requires "root" privileges, so it's likely to fail.
+     */
+    fd = JVM_Socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
+    if (fd != -1) {
+      /*
+       * It didn't fail, so we can use ICMP_ECHO requests.
+       */
+      return ping4(env, fd, &him, timeout, netif, ttl);
+    }
+
+    /*
+     * Can't create a raw socket, so let's try a TCP socket
+     */
+    fd = JVM_Socket(AF_INET, SOCK_STREAM, 0);
+    if (fd == JVM_IO_ERR) {
+        /* note: if you run out of fds, you may not be able to load
+         * the exception class, and get a NoClassDefFoundError
+         * instead.
+         */
+        NET_ThrowNew(env, errno, "Can't create socket");
+        return JNI_FALSE;
+    }
+    if (ttl > 0) {
+      setsockopt(fd, IPPROTO_IP, IP_TTL, &ttl, sizeof(ttl));
+    }
+
+    /*
+     * A network interface was specified, so let's bind to it.
+     */
+    if (netif != NULL) {
+      if (bind(fd, (struct sockaddr*)netif, sizeof(struct sockaddr_in)) < 0) {
+        NET_ThrowNew(env, errno, "Can't bind socket");
+        close(fd);
+        return JNI_FALSE;
+      }
+    }
+
+    /*
+     * Make the socket non blocking so we can use select/poll.
+     */
+    SET_NONBLOCKING(fd);
+
+    /* no need to use NET_Connect as non-blocking */
+    him.sin_port = htons(7);    /* Echo */
+    connect_rv = JVM_Connect(fd, (struct sockaddr *)&him, len);
+
+    /**
+     * connection established or refused immediately, either way it means
+     * we were able to reach the host!
+     */
+    if (connect_rv == 0 || errno == ECONNREFUSED) {
+        close(fd);
+        return JNI_TRUE;
+    } else {
+        int optlen;
+
+        switch (errno) {
+        case ENETUNREACH: /* Network Unreachable */
+        case EAFNOSUPPORT: /* Address Family not supported */
+        case EADDRNOTAVAIL: /* address is not available on  the  remote machine */
+#ifdef __linux__
+        case EINVAL:
+        case EHOSTUNREACH:
+          /*
+           * On some Linuxes, when bound to the loopback interface, connect
+           * will fail and errno will be set to EINVAL or EHOSTUNREACH.
+           * When that happens, don't throw an exception, just return false.
+           */
+#endif /* __linux__ */
+          close(fd);
+          return JNI_FALSE;
+        }
+
+        if (errno != EINPROGRESS) {
+          NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "ConnectException",
+                                       "connect failed");
+          close(fd);
+          return JNI_FALSE;
+        }
+
+        timeout = NET_Wait(env, fd, NET_WAIT_CONNECT, timeout);
+        if (timeout >= 0) {
+          /* has connection been established? */
+          optlen = sizeof(connect_rv);
+          if (JVM_GetSockOpt(fd, SOL_SOCKET, SO_ERROR, (void*)&connect_rv,
+                             &optlen) <0) {
+            connect_rv = errno;
+          }
+          if (connect_rv == 0 || connect_rv == ECONNREFUSED) {
+            close(fd);
+            return JNI_TRUE;
+          }
+        }
+        close(fd);
+        return JNI_FALSE;
+    }
+}
diff --git a/ojluni/src/main/native/Inet6Address.c b/ojluni/src/main/native/Inet6Address.c
new file mode 100755
index 0000000..7b04c67
--- /dev/null
+++ b/ojluni/src/main/native/Inet6Address.c
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2000, 2003, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include <string.h>
+
+#include "java_net_Inet6Address.h"
+#include "net_util.h"
+
+/************************************************************************
+ * Inet6Address
+ */
+
+jclass ia6_class;
+jfieldID ia6_ipaddressID;
+jfieldID ia6_scopeidID;
+jfieldID ia6_cachedscopeidID;
+jfieldID ia6_scopeidsetID;
+jfieldID ia6_scopeifnameID;
+jfieldID ia6_scopeifnamesetID;
+jmethodID ia6_ctrID;
+
+/*
+ * Class:     java_net_Inet6Address
+ * Method:    init
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL
+Java_java_net_Inet6Address_init(JNIEnv *env, jclass cls) {
+    jclass c = (*env)->FindClass(env, "java/net/Inet6Address");
+    CHECK_NULL(c);
+    ia6_class = (*env)->NewGlobalRef(env, c);
+    CHECK_NULL(ia6_class);
+    ia6_ipaddressID = (*env)->GetFieldID(env, ia6_class, "ipaddress", "[B");
+    CHECK_NULL(ia6_ipaddressID);
+    ia6_scopeidID = (*env)->GetFieldID(env, ia6_class, "scope_id", "I");
+    CHECK_NULL(ia6_scopeidID);
+    ia6_cachedscopeidID = (*env)->GetFieldID(env, ia6_class, "cached_scope_id", "I");
+    CHECK_NULL(ia6_cachedscopeidID);
+    ia6_scopeidsetID = (*env)->GetFieldID(env, ia6_class, "scope_id_set", "Z");
+    CHECK_NULL(ia6_scopeidID);
+    ia6_scopeifnameID = (*env)->GetFieldID(env, ia6_class, "scope_ifname", "Ljava/net/NetworkInterface;");
+    CHECK_NULL(ia6_scopeifnameID);
+    ia6_scopeifnamesetID = (*env)->GetFieldID(env, ia6_class, "scope_ifname_set", "Z");
+    CHECK_NULL(ia6_scopeifnamesetID);
+    ia6_ctrID = (*env)->GetMethodID(env, ia6_class, "<init>", "()V");
+    CHECK_NULL(ia6_ctrID);
+}
diff --git a/ojluni/src/main/native/Inet6AddressImpl.c b/ojluni/src/main/native/Inet6AddressImpl.c
new file mode 100755
index 0000000..4038504
--- /dev/null
+++ b/ojluni/src/main/native/Inet6AddressImpl.c
@@ -0,0 +1,719 @@
+/*
+ * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include <errno.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <string.h>
+#include <strings.h>
+#include <stdlib.h>
+#include <ctype.h>
+#ifdef _ALLBSD_SOURCE
+#include <unistd.h> /* gethostname */
+#endif
+
+#include "jvm.h"
+#include "jni_util.h"
+#include "net_util.h"
+#ifndef IPV6_DEFS_H
+#include <netinet/icmp6.h>
+#endif
+
+#include "java_net_Inet4AddressImpl.h"
+#include "java_net_Inet6AddressImpl.h"
+
+/* the initial size of our hostent buffers */
+#ifndef NI_MAXHOST
+#define NI_MAXHOST 1025
+#endif
+
+
+/************************************************************************
+ * Inet6AddressImpl
+ */
+
+/*
+ * Class:     java_net_Inet6AddressImpl
+ * Method:    getLocalHostName
+ * Signature: ()Ljava/lang/String;
+ */
+JNIEXPORT jstring JNICALL
+Java_java_net_Inet6AddressImpl_getLocalHostName(JNIEnv *env, jobject this) {
+    char hostname[NI_MAXHOST+1];
+
+    hostname[0] = '\0';
+    if (JVM_GetHostName(hostname, sizeof(hostname))) {
+        /* Something went wrong, maybe networking is not setup? */
+        strcpy(hostname, "localhost");
+    } else {
+        // ensure null-terminated
+        hostname[NI_MAXHOST] = '\0';
+#if defined(__linux__) || defined(_ALLBSD_SOURCE)
+        /* On Linux/FreeBSD gethostname() says "host.domain.sun.com".  On
+         * Solaris gethostname() says "host", so extra work is needed.
+         */
+#else
+        /* Solaris doesn't want to give us a fully qualified domain name.
+         * We do a reverse lookup to try and get one.  This works
+         * if DNS occurs before NIS in /etc/resolv.conf, but fails
+         * if NIS comes first (it still gets only a partial name).
+         * We use thread-safe system calls.
+         */
+#ifdef AF_INET6
+        if (NET_addrtransAvailable()) {
+            struct addrinfo  hints, *res;
+            int error;
+
+            bzero(&hints, sizeof(hints));
+            hints.ai_flags = AI_CANONNAME;
+            hints.ai_family = AF_UNSPEC;
+
+            error = (*getaddrinfo_ptr)(hostname, NULL, &hints, &res);
+
+            if (error == 0) {
+                /* host is known to name service */
+                error = (*getnameinfo_ptr)(res->ai_addr,
+                                           res->ai_addrlen,
+                                           hostname,
+                                           NI_MAXHOST,
+                                           NULL,
+                                           0,
+                                           NI_NAMEREQD);
+
+                /* if getnameinfo fails hostname is still the value
+                   from gethostname */
+
+                (*freeaddrinfo_ptr)(res);
+            }
+        }
+#endif /* AF_INET6 */
+#endif /* __linux__ || _ALLBSD_SOURCE */
+    }
+    return (*env)->NewStringUTF(env, hostname);
+}
+
+static jclass ni_iacls;
+static jclass ni_ia4cls;
+static jclass ni_ia6cls;
+static jmethodID ni_ia4ctrID;
+static jmethodID ni_ia6ctrID;
+static jfieldID ni_ia6ipaddressID;
+static int initialized = 0;
+
+/*
+ * Find an internet address for a given hostname.  Note that this
+ * code only works for addresses of type INET. The translation
+ * of %d.%d.%d.%d to an address (int) occurs in java now, so the
+ * String "host" shouldn't *ever* be a %d.%d.%d.%d string
+ *
+ * Class:     java_net_Inet6AddressImpl
+ * Method:    lookupAllHostAddr
+ * Signature: (Ljava/lang/String;)[[B
+ */
+
+JNIEXPORT jobjectArray JNICALL
+Java_java_net_Inet6AddressImpl_lookupAllHostAddr(JNIEnv *env, jobject this,
+                                                jstring host) {
+    const char *hostname;
+    jobjectArray ret = 0;
+    int retLen = 0;
+    jboolean preferIPv6Address;
+
+    int error=0;
+#ifdef AF_INET6
+    struct addrinfo hints, *res, *resNew = NULL;
+#endif /* AF_INET6 */
+
+    if (!initialized) {
+      ni_iacls = (*env)->FindClass(env, "java/net/InetAddress");
+      ni_iacls = (*env)->NewGlobalRef(env, ni_iacls);
+      ni_ia4cls = (*env)->FindClass(env, "java/net/Inet4Address");
+      ni_ia4cls = (*env)->NewGlobalRef(env, ni_ia4cls);
+      ni_ia6cls = (*env)->FindClass(env, "java/net/Inet6Address");
+      ni_ia6cls = (*env)->NewGlobalRef(env, ni_ia6cls);
+      ni_ia4ctrID = (*env)->GetMethodID(env, ni_ia4cls, "<init>", "()V");
+      ni_ia6ctrID = (*env)->GetMethodID(env, ni_ia6cls, "<init>", "()V");
+      ni_ia6ipaddressID = (*env)->GetFieldID(env, ni_ia6cls, "ipaddress", "[B");
+      initialized = 1;
+    }
+
+    if (IS_NULL(host)) {
+        JNU_ThrowNullPointerException(env, "host is null");
+        return 0;
+    }
+    hostname = JNU_GetStringPlatformChars(env, host, JNI_FALSE);
+    CHECK_NULL_RETURN(hostname, NULL);
+
+#ifdef AF_INET6
+    if (NET_addrtransAvailable()) {
+        static jfieldID ia_preferIPv6AddressID;
+        if (ia_preferIPv6AddressID == NULL) {
+            jclass c = (*env)->FindClass(env,"java/net/InetAddress");
+            if (c)  {
+                ia_preferIPv6AddressID =
+                    (*env)->GetStaticFieldID(env, c, "preferIPv6Address", "Z");
+            }
+            if (ia_preferIPv6AddressID == NULL) {
+                JNU_ReleaseStringPlatformChars(env, host, hostname);
+                return NULL;
+            }
+        }
+        /* get the address preference */
+        preferIPv6Address
+            = (*env)->GetStaticBooleanField(env, ia_class, ia_preferIPv6AddressID);
+
+        /* Try once, with our static buffer. */
+        bzero(&hints, sizeof(hints));
+        hints.ai_flags = AI_CANONNAME;
+        hints.ai_family = AF_UNSPEC;
+
+#ifdef __solaris__
+        /*
+         * Workaround for Solaris bug 4160367 - if a hostname contains a
+         * white space then 0.0.0.0 is returned
+         */
+        if (isspace((unsigned char)hostname[0])) {
+            JNU_ThrowByName(env, JNU_JAVANETPKG "UnknownHostException",
+                            hostname);
+            JNU_ReleaseStringPlatformChars(env, host, hostname);
+            return NULL;
+        }
+#endif
+
+        error = (*getaddrinfo_ptr)(hostname, NULL, &hints, &res);
+
+        if (error) {
+            /* report error */
+            ThrowUnknownHostExceptionWithGaiError(env, hostname, error);
+            JNU_ReleaseStringPlatformChars(env, host, hostname);
+            return NULL;
+        } else {
+            int i = 0;
+            int inetCount = 0, inet6Count = 0, inetIndex, inet6Index;
+            struct addrinfo *itr, *last = NULL, *iterator = res;
+            while (iterator != NULL) {
+                int skip = 0;
+                itr = resNew;
+                while (itr != NULL) {
+                    if (iterator->ai_family == itr->ai_family &&
+                        iterator->ai_addrlen == itr->ai_addrlen) {
+                        if (itr->ai_family == AF_INET) { /* AF_INET */
+                            struct sockaddr_in *addr1, *addr2;
+                            addr1 = (struct sockaddr_in *)iterator->ai_addr;
+                            addr2 = (struct sockaddr_in *)itr->ai_addr;
+                            if (addr1->sin_addr.s_addr ==
+                                addr2->sin_addr.s_addr) {
+                                skip = 1;
+                                break;
+                            }
+                        } else {
+                            int t;
+                            struct sockaddr_in6 *addr1, *addr2;
+                            addr1 = (struct sockaddr_in6 *)iterator->ai_addr;
+                            addr2 = (struct sockaddr_in6 *)itr->ai_addr;
+
+                            for (t = 0; t < 16; t++) {
+                                if (addr1->sin6_addr.s6_addr[t] !=
+                                    addr2->sin6_addr.s6_addr[t]) {
+                                    break;
+                                }
+                            }
+                            if (t < 16) {
+                                itr = itr->ai_next;
+                                continue;
+                            } else {
+                                skip = 1;
+                                break;
+                            }
+                        }
+                    } else if (iterator->ai_family != AF_INET &&
+                               iterator->ai_family != AF_INET6) {
+                        /* we can't handle other family types */
+                        skip = 1;
+                        break;
+                    }
+                    itr = itr->ai_next;
+                }
+
+                if (!skip) {
+                    struct addrinfo *next
+                        = (struct addrinfo*) malloc(sizeof(struct addrinfo));
+                    if (!next) {
+                        JNU_ThrowOutOfMemoryError(env, "Native heap allocation failed");
+                        ret = NULL;
+                        goto cleanupAndReturn;
+                    }
+                    memcpy(next, iterator, sizeof(struct addrinfo));
+                    next->ai_next = NULL;
+                    if (resNew == NULL) {
+                        resNew = next;
+                    } else {
+                        last->ai_next = next;
+                    }
+                    last = next;
+                    i++;
+                    if (iterator->ai_family == AF_INET) {
+                        inetCount ++;
+                    } else if (iterator->ai_family == AF_INET6) {
+                        inet6Count ++;
+                    }
+                }
+                iterator = iterator->ai_next;
+            }
+            retLen = i;
+            iterator = resNew;
+
+            ret = (*env)->NewObjectArray(env, retLen, ni_iacls, NULL);
+
+            if (IS_NULL(ret)) {
+                /* we may have memory to free at the end of this */
+                goto cleanupAndReturn;
+            }
+
+            if (preferIPv6Address) {
+                /* AF_INET addresses will be offset by inet6Count */
+                inetIndex = inet6Count;
+                inet6Index = 0;
+            } else {
+                /* AF_INET6 addresses will be offset by inetCount */
+                inetIndex = 0;
+                inet6Index = inetCount;
+            }
+
+            while (iterator != NULL) {
+              if (iterator->ai_family == AF_INET) {
+                jobject iaObj = (*env)->NewObject(env, ni_ia4cls, ni_ia4ctrID);
+                if (IS_NULL(iaObj)) {
+                  ret = NULL;
+                  goto cleanupAndReturn;
+                }
+                setInetAddress_addr(env, iaObj, ntohl(((struct sockaddr_in*)iterator->ai_addr)->sin_addr.s_addr));
+                setInetAddress_hostName(env, iaObj, host);
+                (*env)->SetObjectArrayElement(env, ret, inetIndex, iaObj);
+                inetIndex++;
+              } else if (iterator->ai_family == AF_INET6) {
+                jint scope = 0;
+                jbyteArray ipaddress;
+
+                jobject iaObj = (*env)->NewObject(env, ni_ia6cls, ni_ia6ctrID);
+                if (IS_NULL(iaObj)) {
+                  ret = NULL;
+                  goto cleanupAndReturn;
+                }
+                ipaddress = (*env)->NewByteArray(env, 16);
+                if (IS_NULL(ipaddress)) {
+                  ret = NULL;
+                  goto cleanupAndReturn;
+                }
+                (*env)->SetByteArrayRegion(env, ipaddress, 0, 16,
+                                           (jbyte *)&(((struct sockaddr_in6*)iterator->ai_addr)->sin6_addr));
+#ifdef __linux__
+                if (!kernelIsV22()) {
+                  scope = ((struct sockaddr_in6*)iterator->ai_addr)->sin6_scope_id;
+                }
+#else
+                scope = ((struct sockaddr_in6*)iterator->ai_addr)->sin6_scope_id;
+#endif
+                if (scope != 0) { /* zero is default value, no need to set */
+                  (*env)->SetIntField(env, iaObj, ia6_scopeidID, scope);
+                  (*env)->SetBooleanField(env, iaObj, ia6_scopeidsetID, JNI_TRUE);
+                }
+                (*env)->SetObjectField(env, iaObj, ni_ia6ipaddressID, ipaddress);
+                setInetAddress_hostName(env, iaObj, host);
+                (*env)->SetObjectArrayElement(env, ret, inet6Index, iaObj);
+                inet6Index++;
+              }
+              iterator = iterator->ai_next;
+            }
+        }
+    }
+
+cleanupAndReturn:
+    {
+        struct addrinfo *iterator, *tmp;
+        iterator = resNew;
+        while (iterator != NULL) {
+            tmp = iterator;
+            iterator = iterator->ai_next;
+            free(tmp);
+        }
+        JNU_ReleaseStringPlatformChars(env, host, hostname);
+    }
+
+    if (NET_addrtransAvailable())
+        (*freeaddrinfo_ptr)(res);
+#endif /* AF_INET6 */
+
+    return ret;
+}
+
+/*
+ * Class:     java_net_Inet6AddressImpl
+ * Method:    getHostByAddr
+ * Signature: (I)Ljava/lang/String;
+ */
+JNIEXPORT jstring JNICALL
+Java_java_net_Inet6AddressImpl_getHostByAddr(JNIEnv *env, jobject this,
+                                            jbyteArray addrArray) {
+
+    jstring ret = NULL;
+
+#ifdef AF_INET6
+    char host[NI_MAXHOST+1];
+    int error = 0;
+    int len = 0;
+    jbyte caddr[16];
+
+    if (NET_addrtransAvailable()) {
+        struct sockaddr_in him4;
+        struct sockaddr_in6 him6;
+        struct sockaddr *sa;
+
+        /*
+         * For IPv4 addresses construct a sockaddr_in structure.
+         */
+        if ((*env)->GetArrayLength(env, addrArray) == 4) {
+            jint addr;
+            (*env)->GetByteArrayRegion(env, addrArray, 0, 4, caddr);
+            addr = ((caddr[0]<<24) & 0xff000000);
+            addr |= ((caddr[1] <<16) & 0xff0000);
+            addr |= ((caddr[2] <<8) & 0xff00);
+            addr |= (caddr[3] & 0xff);
+            memset((void *) &him4, 0, sizeof(him4));
+            him4.sin_addr.s_addr = (uint32_t) htonl(addr);
+            him4.sin_family = AF_INET;
+            sa = (struct sockaddr *) &him4;
+            len = sizeof(him4);
+        } else {
+            /*
+             * For IPv6 address construct a sockaddr_in6 structure.
+             */
+            (*env)->GetByteArrayRegion(env, addrArray, 0, 16, caddr);
+            memset((void *) &him6, 0, sizeof(him6));
+            memcpy((void *)&(him6.sin6_addr), caddr, sizeof(struct in6_addr) );
+            him6.sin6_family = AF_INET6;
+            sa = (struct sockaddr *) &him6 ;
+            len = sizeof(him6) ;
+        }
+
+        error = (*getnameinfo_ptr)(sa, len, host, NI_MAXHOST, NULL, 0,
+                                   NI_NAMEREQD);
+
+        if (!error) {
+            ret = (*env)->NewStringUTF(env, host);
+        }
+    }
+#endif /* AF_INET6 */
+
+    if (ret == NULL) {
+        JNU_ThrowByName(env, JNU_JAVANETPKG "UnknownHostException", NULL);
+    }
+
+    return ret;
+}
+
+#define SET_NONBLOCKING(fd) {           \
+        int flags = fcntl(fd, F_GETFL); \
+        flags |= O_NONBLOCK;            \
+        fcntl(fd, F_SETFL, flags);      \
+}
+
+#ifdef AF_INET6
+static jboolean
+ping6(JNIEnv *env, jint fd, struct sockaddr_in6* him, jint timeout,
+      struct sockaddr_in6* netif, jint ttl) {
+    jint size;
+    jint n;
+    socklen_t len;
+    char sendbuf[1500];
+    unsigned char recvbuf[1500];
+    struct icmp6_hdr *icmp6;
+    struct sockaddr_in6 sa_recv;
+    jbyte *caddr, *recv_caddr;
+    jchar pid;
+    jint tmout2, seq = 1;
+    struct timeval tv;
+    size_t plen;
+
+#ifdef __linux__
+    {
+    int csum_offset;
+    /**
+     * For some strange reason, the linux kernel won't calculate the
+     * checksum of ICMPv6 packets unless you set this socket option
+     */
+    csum_offset = 2;
+    setsockopt(fd, SOL_RAW, IPV6_CHECKSUM, &csum_offset, sizeof(int));
+    }
+#endif
+
+    caddr = (jbyte *)&(him->sin6_addr);
+
+    /* icmp_id is a 16 bit data type, therefore down cast the pid */
+    pid = (jchar)getpid();
+    size = 60*1024;
+    setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &size, sizeof(size));
+    if (ttl > 0) {
+      setsockopt(fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &ttl, sizeof(ttl));
+    }
+    if (netif != NULL) {
+      if (bind(fd, (struct sockaddr*)netif, sizeof(struct sockaddr_in6)) <0) {
+        NET_ThrowNew(env, errno, "Can't bind socket");
+        close(fd);
+        return JNI_FALSE;
+      }
+    }
+    SET_NONBLOCKING(fd);
+
+    do {
+      icmp6 = (struct icmp6_hdr *) sendbuf;
+      icmp6->icmp6_type = ICMP6_ECHO_REQUEST;
+      icmp6->icmp6_code = 0;
+      /* let's tag the ECHO packet with our pid so we can identify it */
+      icmp6->icmp6_id = htons(pid);
+      icmp6->icmp6_seq = htons(seq);
+      seq++;
+      icmp6->icmp6_cksum = 0;
+      gettimeofday(&tv, NULL);
+      memcpy(sendbuf + sizeof(struct icmp6_hdr), &tv, sizeof(tv));
+      plen = sizeof(struct icmp6_hdr) + sizeof(tv);
+      n = sendto(fd, sendbuf, plen, 0, (struct sockaddr*) him, sizeof(struct sockaddr_in6));
+      if (n < 0 && errno != EINPROGRESS) {
+#ifdef __linux__
+        if (errno != EINVAL && errno != EHOSTUNREACH)
+          /*
+           * On some Linuxes, when bound to the loopback interface, sendto
+           * will fail and errno will be set to EINVAL or EHOSTUNREACH.
+           * When that happens, don't throw an exception, just return false.
+           */
+#endif /*__linux__ */
+        NET_ThrowNew(env, errno, "Can't send ICMP packet");
+        close(fd);
+        return JNI_FALSE;
+      }
+
+      tmout2 = timeout > 1000 ? 1000 : timeout;
+      do {
+        tmout2 = NET_Wait(env, fd, NET_WAIT_READ, tmout2);
+
+        if (tmout2 >= 0) {
+          len = sizeof(sa_recv);
+          n = recvfrom(fd, recvbuf, sizeof(recvbuf), 0, (struct sockaddr*) &sa_recv, &len);
+          icmp6 = (struct icmp6_hdr *) (recvbuf);
+          recv_caddr = (jbyte *)&(sa_recv.sin6_addr);
+          /*
+           * We did receive something, but is it what we were expecting?
+           * I.E.: An ICMP6_ECHO_REPLY packet with the proper PID and
+           *       from the host that we are trying to determine is reachable.
+           */
+          if (n >= 8 && icmp6->icmp6_type == ICMP6_ECHO_REPLY &&
+              (ntohs(icmp6->icmp6_id) == pid)) {
+            if (NET_IsEqual(caddr, recv_caddr)) {
+              close(fd);
+              return JNI_TRUE;
+            }
+            if (NET_IsZeroAddr(caddr)) {
+              close(fd);
+              return JNI_TRUE;
+            }
+          }
+        }
+      } while (tmout2 > 0);
+      timeout -= 1000;
+    } while (timeout > 0);
+    close(fd);
+    return JNI_FALSE;
+}
+#endif /* AF_INET6 */
+
+/*
+ * Class:     java_net_Inet6AddressImpl
+ * Method:    isReachable0
+ * Signature: ([bII[bI)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_java_net_Inet6AddressImpl_isReachable0(JNIEnv *env, jobject this,
+                                           jbyteArray addrArray,
+                                           jint scope,
+                                           jint timeout,
+                                           jbyteArray ifArray,
+                                           jint ttl, jint if_scope) {
+#ifdef AF_INET6
+    jbyte caddr[16];
+    jint fd, sz;
+    struct sockaddr_in6 him6;
+    struct sockaddr_in6 inf6;
+    struct sockaddr_in6* netif = NULL;
+    int len = 0;
+    int connect_rv = -1;
+
+    /*
+     * If IPv6 is not enable, then we can't reach an IPv6 address, can we?
+     */
+    if (!ipv6_available()) {
+      return JNI_FALSE;
+    }
+    /*
+     * If it's an IPv4 address, ICMP won't work with IPv4 mapped address,
+     * therefore, let's delegate to the Inet4Address method.
+     */
+    sz = (*env)->GetArrayLength(env, addrArray);
+    if (sz == 4) {
+      return Java_java_net_Inet4AddressImpl_isReachable0(env, this,
+                                                         addrArray,
+                                                         timeout,
+                                                         ifArray, ttl);
+    }
+
+    memset((void *) caddr, 0, 16);
+    memset((void *) &him6, 0, sizeof(him6));
+    (*env)->GetByteArrayRegion(env, addrArray, 0, 16, caddr);
+    memcpy((void *)&(him6.sin6_addr), caddr, sizeof(struct in6_addr) );
+    him6.sin6_family = AF_INET6;
+#ifdef __linux__
+    if (scope > 0)
+      him6.sin6_scope_id = scope;
+    else
+      him6.sin6_scope_id = getDefaultIPv6Interface( &(him6.sin6_addr));
+    len = sizeof(struct sockaddr_in6);
+#else
+    if (scope > 0)
+      him6.sin6_scope_id = scope;
+    len = sizeof(struct sockaddr_in6);
+#endif
+    /*
+     * If a network interface was specified, let's create the address
+     * for it.
+     */
+    if (!(IS_NULL(ifArray))) {
+      memset((void *) caddr, 0, 16);
+      memset((void *) &inf6, 0, sizeof(inf6));
+      (*env)->GetByteArrayRegion(env, ifArray, 0, 16, caddr);
+      memcpy((void *)&(inf6.sin6_addr), caddr, sizeof(struct in6_addr) );
+      inf6.sin6_family = AF_INET6;
+      inf6.sin6_scope_id = if_scope;
+      netif = &inf6;
+    }
+    /*
+     * If we can create a RAW socket, then when can use the ICMP ECHO_REQUEST
+     * otherwise we'll try a tcp socket to the Echo port (7).
+     * Note that this is empiric, and not connecting could mean it's blocked
+     * or the echo servioe has been disabled.
+     */
+
+    fd = JVM_Socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6);
+
+    if (fd != -1) { /* Good to go, let's do a ping */
+        return ping6(env, fd, &him6, timeout, netif, ttl);
+    }
+
+    /* No good, let's fall back on TCP */
+    fd = JVM_Socket(AF_INET6, SOCK_STREAM, 0);
+    if (fd == JVM_IO_ERR) {
+        /* note: if you run out of fds, you may not be able to load
+         * the exception class, and get a NoClassDefFoundError
+         * instead.
+         */
+        NET_ThrowNew(env, errno, "Can't create socket");
+        return JNI_FALSE;
+    }
+    if (ttl > 0) {
+      setsockopt(fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &ttl, sizeof(ttl));
+    }
+
+    /*
+     * A network interface was specified, so let's bind to it.
+     */
+    if (netif != NULL) {
+      if (bind(fd, (struct sockaddr*)netif, sizeof(struct sockaddr_in6)) <0) {
+        NET_ThrowNew(env, errno, "Can't bind socket");
+        close(fd);
+        return JNI_FALSE;
+      }
+    }
+    SET_NONBLOCKING(fd);
+
+    /* no need to use NET_Connect as non-blocking */
+    him6.sin6_port = htons((short) 7); /* Echo port */
+    connect_rv = JVM_Connect(fd, (struct sockaddr *)&him6, len);
+
+    /**
+     * connection established or refused immediately, either way it means
+     * we were able to reach the host!
+     */
+    if (connect_rv == 0 || errno == ECONNREFUSED) {
+        close(fd);
+        return JNI_TRUE;
+    } else {
+        int optlen;
+
+        switch (errno) {
+        case ENETUNREACH: /* Network Unreachable */
+        case EAFNOSUPPORT: /* Address Family not supported */
+        case EADDRNOTAVAIL: /* address is not available on  the  remote machine */
+#ifdef __linux__
+        case EINVAL:
+        case EHOSTUNREACH:
+          /*
+           * On some Linuxes, when bound to the loopback interface, connect
+           * will fail and errno will be set to EINVAL or EHOSTUNREACH.
+           * When that happens, don't throw an exception, just return false.
+           */
+#endif /* __linux__ */
+          close(fd);
+          return JNI_FALSE;
+        }
+
+        if (errno != EINPROGRESS) {
+            NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "ConnectException",
+                                         "connect failed");
+            close(fd);
+            return JNI_FALSE;
+        }
+
+        timeout = NET_Wait(env, fd, NET_WAIT_CONNECT, timeout);
+
+        if (timeout >= 0) {
+          /* has connection been established */
+          optlen = sizeof(connect_rv);
+          if (JVM_GetSockOpt(fd, SOL_SOCKET, SO_ERROR, (void*)&connect_rv,
+                             &optlen) <0) {
+            connect_rv = errno;
+          }
+          if (connect_rv == 0 || ECONNREFUSED) {
+            close(fd);
+            return JNI_TRUE;
+          }
+        }
+        close(fd);
+        return JNI_FALSE;
+    }
+#else /* AF_INET6 */
+    return JNI_FALSE;
+#endif /* AF_INET6 */
+}
diff --git a/ojluni/src/main/native/InetAddress.c b/ojluni/src/main/native/InetAddress.c
new file mode 100755
index 0000000..3111573
--- /dev/null
+++ b/ojluni/src/main/native/InetAddress.c
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 1997, 2002, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include <string.h>
+
+#include "java_net_InetAddress.h"
+#include "net_util.h"
+
+/************************************************************************
+ * InetAddress
+ */
+
+jclass ia_class;
+jclass iac_class;
+jfieldID ia_holderID;
+jfieldID iac_addressID;
+jfieldID iac_familyID;
+jfieldID iac_hostNameID;
+jfieldID ia_preferIPv6AddressID;
+
+/*
+ * Class:     java_net_InetAddress
+ * Method:    init
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL
+Java_java_net_InetAddress_init(JNIEnv *env, jclass cls) {
+    jclass c = (*env)->FindClass(env,"java/net/InetAddress");
+    CHECK_NULL(c);
+    ia_class = (*env)->NewGlobalRef(env, c);
+    CHECK_NULL(ia_class);
+    c = (*env)->FindClass(env,"java/net/InetAddress$InetAddressHolder");
+    CHECK_NULL(c);
+    iac_class = (*env)->NewGlobalRef(env, c);
+    ia_holderID = (*env)->GetFieldID(env, ia_class, "holder", "Ljava/net/InetAddress$InetAddressHolder;");
+    CHECK_NULL(ia_holderID);
+    ia_preferIPv6AddressID = (*env)->GetStaticFieldID(env, ia_class, "preferIPv6Address", "Z");
+    CHECK_NULL(ia_preferIPv6AddressID);
+
+    iac_addressID = (*env)->GetFieldID(env, iac_class, "address", "I");
+    CHECK_NULL(iac_addressID);
+    iac_familyID = (*env)->GetFieldID(env, iac_class, "family", "I");
+    CHECK_NULL(iac_familyID);
+    iac_hostNameID = (*env)->GetFieldID(env, iac_class, "hostName", "Ljava/lang/String;");
+    CHECK_NULL(iac_hostNameID);
+}
diff --git a/ojluni/src/main/native/InetAddressImplFactory.c b/ojluni/src/main/native/InetAddressImplFactory.c
new file mode 100755
index 0000000..feae950
--- /dev/null
+++ b/ojluni/src/main/native/InetAddressImplFactory.c
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 1997, 2001, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include "java_net_InetAddressImplFactory.h"
+
+#include "net_util.h"
+
+/************************************************************************
+ * InetAddressImplFactory
+ */
+
+/*
+ * Class:     java_net_InetAddressImplFactory
+ * Method:    isIPv6Supported
+ * Signature: ()I
+ */
+JNIEXPORT jboolean JNICALL
+Java_java_net_InetAddressImplFactory_isIPv6Supported(JNIEnv *env, jclass cls)
+{
+#ifdef AF_INET6
+    if (ipv6_available()) {
+        return JNI_TRUE;
+    } else
+#endif /* AF_INET6 */
+        {
+            return JNI_FALSE;
+        }
+}
diff --git a/ojluni/src/main/native/NativeSignalHandler.c b/ojluni/src/main/native/NativeSignalHandler.c
new file mode 100755
index 0000000..23c7589
--- /dev/null
+++ b/ojluni/src/main/native/NativeSignalHandler.c
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 1998, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include <signal.h>
+#include <stdlib.h>
+
+#include <jni.h>
+#include <jlong.h>
+#include "sun_misc_NativeSignalHandler.h"
+
+typedef void (*sig_handler_t)(jint, void *, void *);
+
+JNIEXPORT void JNICALL
+Java_sun_misc_NativeSignalHandler_handle0(JNIEnv *env, jclass cls, jint sig, jlong f)
+{
+    /* We've lost the siginfo and context */
+    (*(sig_handler_t)jlong_to_ptr(f))(sig, NULL, NULL);
+}
diff --git a/ojluni/src/main/native/NativeThread.c b/ojluni/src/main/native/NativeThread.c
new file mode 100755
index 0000000..79a91a0
--- /dev/null
+++ b/ojluni/src/main/native/NativeThread.c
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2002, 2006, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include <sys/types.h>
+#include <string.h>
+#include "jni.h"
+#include "jni_util.h"
+#include "jvm.h"
+#include "jlong.h"
+#include "sun_nio_ch_NativeThread.h"
+#include "nio_util.h"
+
+
+#ifdef __linux__
+#include <pthread.h>
+#include <sys/signal.h>
+
+/* Also defined in src/solaris/native/java/net/linux_close.c */
+#define INTERRUPT_SIGNAL (__SIGRTMAX - 2)
+
+static void
+nullHandler(int sig)
+{
+}
+
+#endif
+
+
+JNIEXPORT void JNICALL
+Java_sun_nio_ch_NativeThread_init(JNIEnv *env, jclass cl)
+{
+#ifdef __linux__
+
+    /* Install the null handler for INTERRUPT_SIGNAL.  This might overwrite the
+     * handler previously installed by java/net/linux_close.c, but that's okay
+     * since neither handler actually does anything.  We install our own
+     * handler here simply out of paranoia; ultimately the two mechanisms
+     * should somehow be unified, perhaps within the VM.
+     */
+
+    sigset_t ss;
+    struct sigaction sa, osa;
+    sa.sa_handler = nullHandler;
+    sa.sa_flags = 0;
+    sigemptyset(&sa.sa_mask);
+    if (sigaction(INTERRUPT_SIGNAL, &sa, &osa) < 0)
+        JNU_ThrowIOExceptionWithLastError(env, "sigaction");
+
+#endif
+}
+
+JNIEXPORT jlong JNICALL
+Java_sun_nio_ch_NativeThread_current(JNIEnv *env, jclass cl)
+{
+#ifdef __linux__
+    return (long)pthread_self();
+#else
+    return -1;
+#endif
+}
+
+JNIEXPORT void JNICALL
+Java_sun_nio_ch_NativeThread_signal(JNIEnv *env, jclass cl, jlong thread)
+{
+#ifdef __linux__
+    if (pthread_kill((pthread_t)thread, INTERRUPT_SIGNAL))
+        JNU_ThrowIOExceptionWithLastError(env, "Thread signal failed");
+#endif
+}
diff --git a/ojluni/src/main/native/NetworkInterface.c b/ojluni/src/main/native/NetworkInterface.c
new file mode 100755
index 0000000..6a31a61
--- /dev/null
+++ b/ojluni/src/main/native/NetworkInterface.c
@@ -0,0 +1,2000 @@
+/*
+ * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+#include <errno.h>
+#include <strings.h>
+#if defined(_ALLBSD_SOURCE) && defined(__OpenBSD__)
+#include <sys/types.h>
+#endif
+#include <netinet/in.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <arpa/inet.h>
+#include <net/if.h>
+#include <net/if_arp.h>
+
+#ifdef __solaris__
+#include <sys/dlpi.h>
+#include <fcntl.h>
+#include <stropts.h>
+#include <sys/sockio.h>
+#endif
+
+#ifdef __linux__
+#include <sys/ioctl.h>
+#include <bits/ioctls.h>
+#include <sys/utsname.h>
+#include <stdio.h>
+#endif
+
+#ifdef __linux__
+#define _PATH_PROCNET_IFINET6           "/proc/net/if_inet6"
+#endif
+
+#if defined(_ALLBSD_SOURCE)
+#include <sys/param.h>
+#include <sys/ioctl.h>
+#include <sys/sockio.h>
+#if defined(__APPLE__)
+#include <net/ethernet.h>
+#include <net/if_var.h>
+#include <net/if_dl.h>
+#include <netinet/in_var.h>
+#include <ifaddrs.h>
+#endif
+#endif
+
+#include "jvm.h"
+#include "jni_util.h"
+#include "net_util.h"
+
+typedef struct _netaddr  {
+    struct sockaddr *addr;
+    struct sockaddr *brdcast;
+    short mask;
+    int family; /* to make searches simple */
+    struct _netaddr *next;
+} netaddr;
+
+typedef struct _netif {
+    char *name;
+    int index;
+    char virtual;
+    netaddr *addr;
+    struct _netif *childs;
+    struct _netif *next;
+} netif;
+
+/************************************************************************
+ * NetworkInterface
+ */
+
+#include "java_net_NetworkInterface.h"
+
+/************************************************************************
+ * NetworkInterface
+ */
+jclass ni_class;
+jfieldID ni_nameID;
+jfieldID ni_indexID;
+jfieldID ni_descID;
+jfieldID ni_addrsID;
+jfieldID ni_bindsID;
+jfieldID ni_virutalID;
+jfieldID ni_childsID;
+jfieldID ni_parentID;
+jfieldID ni_defaultIndexID;
+jmethodID ni_ctrID;
+
+static jclass ni_iacls;
+static jclass ni_ia4cls;
+static jclass ni_ia6cls;
+static jclass ni_ibcls;
+static jmethodID ni_ia4ctrID;
+static jmethodID ni_ia6ctrID;
+static jmethodID ni_ibctrID;
+static jfieldID ni_ia6ipaddressID;
+static jfieldID ni_ibaddressID;
+static jfieldID ni_ib4broadcastID;
+static jfieldID ni_ib4maskID;
+
+/** Private methods declarations **/
+static jobject createNetworkInterface(JNIEnv *env, netif *ifs);
+static int     getFlags0(JNIEnv *env, jstring  ifname);
+
+static netif  *enumInterfaces(JNIEnv *env);
+static netif  *enumIPv4Interfaces(JNIEnv *env, int sock, netif *ifs);
+
+#ifdef AF_INET6
+static netif  *enumIPv6Interfaces(JNIEnv *env, int sock, netif *ifs);
+#endif
+
+static netif  *addif(JNIEnv *env, int sock, const char * if_name, netif *ifs, struct sockaddr* ifr_addrP, int family, short prefix);
+static void    freeif(netif *ifs);
+
+static int     openSocket(JNIEnv *env, int proto);
+static int     openSocketWithFallback(JNIEnv *env, const char *ifname);
+
+
+static struct  sockaddr *getBroadcast(JNIEnv *env, int sock, const char *name, struct sockaddr *brdcast_store);
+static short   getSubnet(JNIEnv *env, int sock, const char *ifname);
+static int     getIndex(int sock, const char *ifname);
+
+static int     getFlags(int sock, const char *ifname, int *flags);
+static int     getMacAddress(JNIEnv *env, int sock,  const char* ifname, const struct in_addr* addr, unsigned char *buf);
+static int     getMTU(JNIEnv *env, int sock, const char *ifname);
+
+
+
+#ifdef __solaris__
+static netif *enumIPvXInterfaces(JNIEnv *env, int sock, netif *ifs, int family);
+static int    getMacFromDevice(JNIEnv *env, const char* ifname, unsigned char* retbuf);
+
+#ifndef SIOCGLIFHWADDR
+#define SIOCGLIFHWADDR  _IOWR('i', 192, struct lifreq)
+#endif
+
+#endif
+
+/******************* Java entry points *****************************/
+
+/*
+ * Class:     java_net_NetworkInterface
+ * Method:    init
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL
+Java_java_net_NetworkInterface_init(JNIEnv *env, jclass cls) {
+    ni_class = (*env)->FindClass(env,"java/net/NetworkInterface");
+    ni_class = (*env)->NewGlobalRef(env, ni_class);
+    ni_nameID = (*env)->GetFieldID(env, ni_class,"name", "Ljava/lang/String;");
+    ni_indexID = (*env)->GetFieldID(env, ni_class, "index", "I");
+    ni_addrsID = (*env)->GetFieldID(env, ni_class, "addrs", "[Ljava/net/InetAddress;");
+    ni_bindsID = (*env)->GetFieldID(env, ni_class, "bindings", "[Ljava/net/InterfaceAddress;");
+    ni_descID = (*env)->GetFieldID(env, ni_class, "displayName", "Ljava/lang/String;");
+    ni_virutalID = (*env)->GetFieldID(env, ni_class, "virtual", "Z");
+    ni_childsID = (*env)->GetFieldID(env, ni_class, "childs", "[Ljava/net/NetworkInterface;");
+    ni_parentID = (*env)->GetFieldID(env, ni_class, "parent", "Ljava/net/NetworkInterface;");
+    ni_ctrID = (*env)->GetMethodID(env, ni_class, "<init>", "()V");
+
+    ni_iacls = (*env)->FindClass(env, "java/net/InetAddress");
+    ni_iacls = (*env)->NewGlobalRef(env, ni_iacls);
+    ni_ia4cls = (*env)->FindClass(env, "java/net/Inet4Address");
+    ni_ia4cls = (*env)->NewGlobalRef(env, ni_ia4cls);
+    ni_ia6cls = (*env)->FindClass(env, "java/net/Inet6Address");
+    ni_ia6cls = (*env)->NewGlobalRef(env, ni_ia6cls);
+    ni_ibcls = (*env)->FindClass(env, "java/net/InterfaceAddress");
+    ni_ibcls = (*env)->NewGlobalRef(env, ni_ibcls);
+    ni_ia4ctrID = (*env)->GetMethodID(env, ni_ia4cls, "<init>", "()V");
+    ni_ia6ctrID = (*env)->GetMethodID(env, ni_ia6cls, "<init>", "()V");
+    ni_ibctrID = (*env)->GetMethodID(env, ni_ibcls, "<init>", "()V");
+    ni_ia6ipaddressID = (*env)->GetFieldID(env, ni_ia6cls, "ipaddress", "[B");
+    ni_ibaddressID = (*env)->GetFieldID(env, ni_ibcls, "address", "Ljava/net/InetAddress;");
+    ni_ib4broadcastID = (*env)->GetFieldID(env, ni_ibcls, "broadcast", "Ljava/net/Inet4Address;");
+    ni_ib4maskID = (*env)->GetFieldID(env, ni_ibcls, "maskLength", "S");
+    ni_defaultIndexID = (*env)->GetStaticFieldID(env, ni_class, "defaultIndex", "I");
+}
+
+
+/*
+ * Class:     java_net_NetworkInterface
+ * Method:    getByName0
+ * Signature: (Ljava/lang/String;)Ljava/net/NetworkInterface;
+ */
+JNIEXPORT jobject JNICALL Java_java_net_NetworkInterface_getByName0
+    (JNIEnv *env, jclass cls, jstring name) {
+
+    netif *ifs, *curr;
+    jboolean isCopy;
+    const char* name_utf;
+    jobject obj = NULL;
+
+    ifs = enumInterfaces(env);
+    if (ifs == NULL) {
+        return NULL;
+    }
+
+    name_utf = (*env)->GetStringUTFChars(env, name, &isCopy);
+
+    /*
+     * Search the list of interface based on name
+     */
+    curr = ifs;
+    while (curr != NULL) {
+        if (strcmp(name_utf, curr->name) == 0) {
+            break;
+        }
+        curr = curr->next;
+    }
+
+    /* if found create a NetworkInterface */
+    if (curr != NULL) {;
+        obj = createNetworkInterface(env, curr);
+    }
+
+    /* release the UTF string and interface list */
+    (*env)->ReleaseStringUTFChars(env, name, name_utf);
+    freeif(ifs);
+
+    return obj;
+}
+
+
+/*
+ * Class:     java_net_NetworkInterface
+ * Method:    getByIndex0
+ * Signature: (Ljava/lang/String;)Ljava/net/NetworkInterface;
+ */
+JNIEXPORT jobject JNICALL Java_java_net_NetworkInterface_getByIndex0
+    (JNIEnv *env, jclass cls, jint index) {
+
+    netif *ifs, *curr;
+    jobject obj = NULL;
+
+    if (index <= 0) {
+        return NULL;
+    }
+
+    ifs = enumInterfaces(env);
+    if (ifs == NULL) {
+        return NULL;
+    }
+
+    /*
+     * Search the list of interface based on index
+     */
+    curr = ifs;
+    while (curr != NULL) {
+        if (index == curr->index) {
+            break;
+        }
+        curr = curr->next;
+    }
+
+    /* if found create a NetworkInterface */
+    if (curr != NULL) {;
+        obj = createNetworkInterface(env, curr);
+    }
+
+    freeif(ifs);
+    return obj;
+}
+
+/*
+ * Class:     java_net_NetworkInterface
+ * Method:    getByInetAddress0
+ * Signature: (Ljava/net/InetAddress;)Ljava/net/NetworkInterface;
+ */
+JNIEXPORT jobject JNICALL Java_java_net_NetworkInterface_getByInetAddress0
+    (JNIEnv *env, jclass cls, jobject iaObj) {
+
+    netif *ifs, *curr;
+
+#ifdef AF_INET6
+    int family = (getInetAddress_family(env, iaObj) == IPv4) ? AF_INET : AF_INET6;
+#else
+    int family =  AF_INET;
+#endif
+
+    jobject obj = NULL;
+    jboolean match = JNI_FALSE;
+
+    ifs = enumInterfaces(env);
+    if (ifs == NULL) {
+        return NULL;
+    }
+
+    curr = ifs;
+    while (curr != NULL) {
+        netaddr *addrP = curr->addr;
+
+        /*
+         * Iterate through each address on the interface
+         */
+        while (addrP != NULL) {
+
+            if (family == addrP->family) {
+                if (family == AF_INET) {
+                    int address1 = htonl(((struct sockaddr_in*)addrP->addr)->sin_addr.s_addr);
+                    int address2 = getInetAddress_addr(env, iaObj);
+
+                    if (address1 == address2) {
+                        match = JNI_TRUE;
+                        break;
+                    }
+                }
+
+#ifdef AF_INET6
+                if (family == AF_INET6) {
+                    jbyte *bytes = (jbyte *)&(((struct sockaddr_in6*)addrP->addr)->sin6_addr);
+                    jbyteArray ipaddress = (*env)->GetObjectField(env, iaObj, ni_ia6ipaddressID);
+                    jbyte caddr[16];
+                    int i;
+
+                    (*env)->GetByteArrayRegion(env, ipaddress, 0, 16, caddr);
+                    i = 0;
+                    while (i < 16) {
+                        if (caddr[i] != bytes[i]) {
+                            break;
+                        }
+                        i++;
+                    }
+                    if (i >= 16) {
+                        match = JNI_TRUE;
+                        break;
+                    }
+                }
+#endif
+
+            }
+
+            if (match) {
+                break;
+            }
+            addrP = addrP->next;
+        }
+
+        if (match) {
+            break;
+        }
+        curr = curr->next;
+    }
+
+    /* if found create a NetworkInterface */
+    if (match) {;
+        obj = createNetworkInterface(env, curr);
+    }
+
+    freeif(ifs);
+    return obj;
+}
+
+
+/*
+ * Class:     java_net_NetworkInterface
+ * Method:    getAll
+ * Signature: ()[Ljava/net/NetworkInterface;
+ */
+JNIEXPORT jobjectArray JNICALL Java_java_net_NetworkInterface_getAll
+    (JNIEnv *env, jclass cls) {
+
+    netif *ifs, *curr;
+    jobjectArray netIFArr;
+    jint arr_index, ifCount;
+
+    ifs = enumInterfaces(env);
+    if (ifs == NULL) {
+        return NULL;
+    }
+
+    /* count the interface */
+    ifCount = 0;
+    curr = ifs;
+    while (curr != NULL) {
+        ifCount++;
+        curr = curr->next;
+    }
+
+    /* allocate a NetworkInterface array */
+    netIFArr = (*env)->NewObjectArray(env, ifCount, cls, NULL);
+    if (netIFArr == NULL) {
+        freeif(ifs);
+        return NULL;
+    }
+
+    /*
+     * Iterate through the interfaces, create a NetworkInterface instance
+     * for each array element and populate the object.
+     */
+    curr = ifs;
+    arr_index = 0;
+    while (curr != NULL) {
+        jobject netifObj;
+
+        netifObj = createNetworkInterface(env, curr);
+        if (netifObj == NULL) {
+            freeif(ifs);
+            return NULL;
+        }
+
+        /* put the NetworkInterface into the array */
+        (*env)->SetObjectArrayElement(env, netIFArr, arr_index++, netifObj);
+
+        curr = curr->next;
+    }
+
+    freeif(ifs);
+    return netIFArr;
+}
+
+
+/*
+ * Class:     java_net_NetworkInterface
+ * Method:    isUp0
+ * Signature: (Ljava/lang/String;I)Z
+ */
+JNIEXPORT jboolean JNICALL Java_java_net_NetworkInterface_isUp0(JNIEnv *env, jclass cls, jstring name, jint index) {
+    int ret = getFlags0(env, name);
+    return ((ret & IFF_UP) && (ret & IFF_RUNNING)) ? JNI_TRUE :  JNI_FALSE;
+}
+
+/*
+ * Class:     java_net_NetworkInterface
+ * Method:    isP2P0
+ * Signature: (Ljava/lang/String;I)Z
+ */
+JNIEXPORT jboolean JNICALL Java_java_net_NetworkInterface_isP2P0(JNIEnv *env, jclass cls, jstring name, jint index) {
+    int ret = getFlags0(env, name);
+    return (ret & IFF_POINTOPOINT) ? JNI_TRUE :  JNI_FALSE;
+}
+
+/*
+ * Class:     java_net_NetworkInterface
+ * Method:    isLoopback0
+ * Signature: (Ljava/lang/String;I)Z
+ */
+JNIEXPORT jboolean JNICALL Java_java_net_NetworkInterface_isLoopback0(JNIEnv *env, jclass cls, jstring name, jint index) {
+    int ret = getFlags0(env, name);
+    return (ret & IFF_LOOPBACK) ? JNI_TRUE :  JNI_FALSE;
+}
+
+/*
+ * Class:     java_net_NetworkInterface
+ * Method:    supportsMulticast0
+ * Signature: (Ljava/lang/String;I)Z
+ */
+JNIEXPORT jboolean JNICALL Java_java_net_NetworkInterface_supportsMulticast0(JNIEnv *env, jclass cls, jstring name, jint index) {
+    int ret = getFlags0(env, name);
+    return (ret & IFF_MULTICAST) ? JNI_TRUE :  JNI_FALSE;
+}
+
+/*
+ * Class:     java_net_NetworkInterface
+ * Method:    getMacAddr0
+ * Signature: ([bLjava/lang/String;I)[b
+ */
+JNIEXPORT jbyteArray JNICALL Java_java_net_NetworkInterface_getMacAddr0(JNIEnv *env, jclass class, jbyteArray addrArray, jstring name, jint index) {
+    jint addr;
+    jbyte caddr[4];
+    struct in_addr iaddr;
+    jbyteArray ret = NULL;
+    unsigned char mac[16];
+    int len;
+    int sock;
+    jboolean isCopy;
+    const char* name_utf;
+
+    name_utf = (*env)->GetStringUTFChars(env, name, &isCopy);
+
+    if ((sock =openSocketWithFallback(env, name_utf)) < 0) {
+       (*env)->ReleaseStringUTFChars(env, name, name_utf);
+       return JNI_FALSE;
+    }
+
+
+    if (!IS_NULL(addrArray)) {
+       (*env)->GetByteArrayRegion(env, addrArray, 0, 4, caddr);
+       addr = ((caddr[0]<<24) & 0xff000000);
+       addr |= ((caddr[1] <<16) & 0xff0000);
+       addr |= ((caddr[2] <<8) & 0xff00);
+       addr |= (caddr[3] & 0xff);
+       iaddr.s_addr = htonl(addr);
+       len = getMacAddress(env, sock, name_utf, &iaddr, mac);
+    } else {
+       len = getMacAddress(env, sock, name_utf,NULL, mac);
+    }
+    if (len > 0) {
+       ret = (*env)->NewByteArray(env, len);
+       if (IS_NULL(ret)) {
+          /* we may have memory to free at the end of this */
+          goto fexit;
+       }
+       (*env)->SetByteArrayRegion(env, ret, 0, len, (jbyte *) (mac));
+    }
+ fexit:
+   /* release the UTF string and interface list */
+   (*env)->ReleaseStringUTFChars(env, name, name_utf);
+
+   close(sock);
+   return ret;
+}
+
+/*
+ * Class:       java_net_NetworkInterface
+ * Method:      getMTU0
+ * Signature:   ([bLjava/lang/String;I)I
+ */
+
+JNIEXPORT jint JNICALL Java_java_net_NetworkInterface_getMTU0(JNIEnv *env, jclass class, jstring name, jint index) {
+    jboolean isCopy;
+    int ret = -1;
+    int sock;
+    const char* name_utf;
+
+    name_utf = (*env)->GetStringUTFChars(env, name, &isCopy);
+
+    if ((sock =openSocketWithFallback(env, name_utf)) < 0) {
+       (*env)->ReleaseStringUTFChars(env, name, name_utf);
+       return JNI_FALSE;
+    }
+
+    ret = getMTU(env, sock, name_utf);
+
+    (*env)->ReleaseStringUTFChars(env, name, name_utf);
+
+    close(sock);
+    return ret;
+}
+
+/*** Private methods definitions ****/
+
+static int getFlags0(JNIEnv *env, jstring name) {
+    jboolean isCopy;
+    int ret, sock;
+    const char* name_utf;
+    int flags = 0;
+
+    name_utf = (*env)->GetStringUTFChars(env, name, &isCopy);
+
+    if ((sock = openSocketWithFallback(env, name_utf)) < 0) {
+        (*env)->ReleaseStringUTFChars(env, name, name_utf);
+         return -1;
+    }
+
+    name_utf = (*env)->GetStringUTFChars(env, name, &isCopy);
+
+    ret = getFlags(sock, name_utf, &flags);
+
+    close(sock);
+    (*env)->ReleaseStringUTFChars(env, name, name_utf);
+
+    if (ret < 0) {
+        NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "IOCTL  SIOCGLIFFLAGS failed");
+        return -1;
+    }
+
+    return flags;
+}
+
+
+
+
+/*
+ * Create a NetworkInterface object, populate the name and index, and
+ * populate the InetAddress array based on the IP addresses for this
+ * interface.
+ */
+jobject createNetworkInterface(JNIEnv *env, netif *ifs) {
+    jobject netifObj;
+    jobject name;
+    jobjectArray addrArr;
+    jobjectArray bindArr;
+    jobjectArray childArr;
+    netaddr *addrs;
+    jint addr_index, addr_count, bind_index;
+    jint child_count, child_index;
+    netaddr *addrP;
+    netif *childP;
+    jobject tmp;
+
+    /*
+     * Create a NetworkInterface object and populate it
+     */
+    netifObj = (*env)->NewObject(env, ni_class, ni_ctrID);
+    name = (*env)->NewStringUTF(env, ifs->name);
+    if (netifObj == NULL || name == NULL) {
+        return NULL;
+    }
+    (*env)->SetObjectField(env, netifObj, ni_nameID, name);
+    (*env)->SetObjectField(env, netifObj, ni_descID, name);
+    (*env)->SetIntField(env, netifObj, ni_indexID, ifs->index);
+    (*env)->SetBooleanField(env, netifObj, ni_virutalID, ifs->virtual ? JNI_TRUE : JNI_FALSE);
+
+    /*
+     * Count the number of address on this interface
+     */
+    addr_count = 0;
+    addrP = ifs->addr;
+    while (addrP != NULL) {
+        addr_count++;
+        addrP = addrP->next;
+    }
+
+    /*
+     * Create the array of InetAddresses
+     */
+    addrArr = (*env)->NewObjectArray(env, addr_count,  ni_iacls, NULL);
+    if (addrArr == NULL) {
+        return NULL;
+    }
+
+    bindArr = (*env)->NewObjectArray(env, addr_count, ni_ibcls, NULL);
+    if (bindArr == NULL) {
+       return NULL;
+    }
+    addrP = ifs->addr;
+    addr_index = 0;
+    bind_index = 0;
+    while (addrP != NULL) {
+        jobject iaObj = NULL;
+        jobject ibObj = NULL;
+
+        if (addrP->family == AF_INET) {
+            iaObj = (*env)->NewObject(env, ni_ia4cls, ni_ia4ctrID);
+            if (iaObj) {
+                 setInetAddress_addr(env, iaObj, htonl(((struct sockaddr_in*)addrP->addr)->sin_addr.s_addr));
+            }
+            ibObj = (*env)->NewObject(env, ni_ibcls, ni_ibctrID);
+            if (ibObj) {
+                 (*env)->SetObjectField(env, ibObj, ni_ibaddressID, iaObj);
+                 if (addrP->brdcast) {
+                    jobject ia2Obj = NULL;
+                    ia2Obj = (*env)->NewObject(env, ni_ia4cls, ni_ia4ctrID);
+                    if (ia2Obj) {
+                       setInetAddress_addr(env, ia2Obj, htonl(((struct sockaddr_in*)addrP->brdcast)->sin_addr.s_addr));
+                       (*env)->SetObjectField(env, ibObj, ni_ib4broadcastID, ia2Obj);
+                       (*env)->SetShortField(env, ibObj, ni_ib4maskID, addrP->mask);
+                    }
+                 }
+                 (*env)->SetObjectArrayElement(env, bindArr, bind_index++, ibObj);
+            }
+        }
+
+#ifdef AF_INET6
+        if (addrP->family == AF_INET6) {
+            int scope=0;
+            iaObj = (*env)->NewObject(env, ni_ia6cls, ni_ia6ctrID);
+            if (iaObj) {
+                jbyteArray ipaddress = (*env)->NewByteArray(env, 16);
+                if (ipaddress == NULL) {
+                    return NULL;
+                }
+                (*env)->SetByteArrayRegion(env, ipaddress, 0, 16,
+                                                                        (jbyte *)&(((struct sockaddr_in6*)addrP->addr)->sin6_addr));
+
+                scope = ((struct sockaddr_in6*)addrP->addr)->sin6_scope_id;
+
+                if (scope != 0) { /* zero is default value, no need to set */
+                    (*env)->SetIntField(env, iaObj, ia6_scopeidID, scope);
+                    (*env)->SetBooleanField(env, iaObj, ia6_scopeidsetID, JNI_TRUE);
+                    (*env)->SetObjectField(env, iaObj, ia6_scopeifnameID, netifObj);
+                }
+                (*env)->SetObjectField(env, iaObj, ni_ia6ipaddressID, ipaddress);
+            }
+            ibObj = (*env)->NewObject(env, ni_ibcls, ni_ibctrID);
+            if (ibObj) {
+                (*env)->SetObjectField(env, ibObj, ni_ibaddressID, iaObj);
+                (*env)->SetShortField(env, ibObj, ni_ib4maskID, addrP->mask);
+                (*env)->SetObjectArrayElement(env, bindArr, bind_index++, ibObj);
+            }
+        }
+#endif
+
+        if (iaObj == NULL) {
+            return NULL;
+        }
+
+        (*env)->SetObjectArrayElement(env, addrArr, addr_index++, iaObj);
+        addrP = addrP->next;
+    }
+
+    /*
+     * See if there is any virtual interface attached to this one.
+     */
+    child_count = 0;
+    childP = ifs->childs;
+    while (childP) {
+        child_count++;
+        childP = childP->next;
+    }
+
+    childArr = (*env)->NewObjectArray(env, child_count, ni_class, NULL);
+    if (childArr == NULL) {
+        return NULL;
+    }
+
+    /*
+     * Create the NetworkInterface instances for the sub-interfaces as
+     * well.
+     */
+    child_index = 0;
+    childP = ifs->childs;
+    while(childP) {
+      tmp = createNetworkInterface(env, childP);
+      if (tmp == NULL) {
+         return NULL;
+      }
+      (*env)->SetObjectField(env, tmp, ni_parentID, netifObj);
+      (*env)->SetObjectArrayElement(env, childArr, child_index++, tmp);
+      childP = childP->next;
+    }
+    (*env)->SetObjectField(env, netifObj, ni_addrsID, addrArr);
+    (*env)->SetObjectField(env, netifObj, ni_bindsID, bindArr);
+    (*env)->SetObjectField(env, netifObj, ni_childsID, childArr);
+
+    /* return the NetworkInterface */
+    return netifObj;
+}
+
+/*
+ * Enumerates all interfaces
+ */
+static netif *enumInterfaces(JNIEnv *env) {
+    netif *ifs;
+    int sock;
+
+    /*
+     * Enumerate IPv4 addresses
+     */
+
+    sock = openSocket(env, AF_INET);
+    if (sock < 0 && (*env)->ExceptionOccurred(env)) {
+        return NULL;
+    }
+
+    ifs = enumIPv4Interfaces(env, sock, NULL);
+    close(sock);
+
+    if (ifs == NULL && (*env)->ExceptionOccurred(env)) {
+        return NULL;
+    }
+
+    /* return partial list if exception occure in the middle of process ???*/
+
+    /*
+     * If IPv6 is available then enumerate IPv6 addresses.
+     */
+#ifdef AF_INET6
+
+        /* User can disable ipv6 expicitly by -Djava.net.preferIPv4Stack=true,
+         * so we have to call ipv6_available()
+         */
+        if (ipv6_available()) {
+
+           sock =  openSocket(env, AF_INET6);
+           if (sock < 0 && (*env)->ExceptionOccurred(env)) {
+               freeif(ifs);
+               return NULL;
+           }
+
+           ifs = enumIPv6Interfaces(env, sock, ifs);
+           close(sock);
+
+           if ((*env)->ExceptionOccurred(env)) {
+              freeif(ifs);
+              return NULL;
+           }
+
+       }
+#endif
+
+    return ifs;
+}
+
+#define CHECKED_MALLOC3(_pointer,_type,_size) \
+       do{ \
+        _pointer = (_type)malloc( _size ); \
+        if (_pointer == NULL) { \
+            JNU_ThrowOutOfMemoryError(env, "Native heap allocation failed"); \
+            return ifs; /* return untouched list */ \
+        } \
+       } while(0)
+
+
+/*
+ * Free an interface list (including any attached addresses)
+ */
+void freeif(netif *ifs) {
+    netif *currif = ifs;
+    netif *child = NULL;
+
+    while (currif != NULL) {
+        netaddr *addrP = currif->addr;
+        while (addrP != NULL) {
+            netaddr *next = addrP->next;
+            free(addrP);
+            addrP = next;
+         }
+
+            /*
+            * Don't forget to free the sub-interfaces.
+            */
+          if (currif->childs != NULL) {
+                freeif(currif->childs);
+          }
+
+          ifs = currif->next;
+          free(currif);
+          currif = ifs;
+    }
+}
+
+netif *addif(JNIEnv *env, int sock, const char * if_name,
+             netif *ifs, struct sockaddr* ifr_addrP, int family,
+             short prefix)
+{
+    netif *currif = ifs, *parent;
+    netaddr *addrP;
+
+#ifdef LIFNAMSIZ
+    int ifnam_size = LIFNAMSIZ;
+    char name[LIFNAMSIZ], vname[LIFNAMSIZ];
+#else
+    int ifnam_size = IFNAMSIZ;
+    char name[IFNAMSIZ], vname[IFNAMSIZ];
+#endif
+
+    char  *name_colonP;
+    int mask;
+    int isVirtual = 0;
+    int addr_size;
+    int flags = 0;
+
+    /*
+     * If the interface name is a logical interface then we
+     * remove the unit number so that we have the physical
+     * interface (eg: hme0:1 -> hme0). NetworkInterface
+     * currently doesn't have any concept of physical vs.
+     * logical interfaces.
+     */
+    strncpy(name, if_name, ifnam_size);
+    name[ifnam_size - 1] = '\0';
+    *vname = 0;
+
+    /*
+     * Create and populate the netaddr node. If allocation fails
+     * return an un-updated list.
+     */
+    /*Allocate for addr and brdcast at once*/
+
+#ifdef AF_INET6
+    addr_size = (family == AF_INET) ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6);
+#else
+    addr_size = sizeof(struct sockaddr_in);
+#endif
+
+    CHECKED_MALLOC3(addrP, netaddr *, sizeof(netaddr)+2*addr_size);
+    addrP->addr = (struct sockaddr *)( (char *) addrP+sizeof(netaddr) );
+    memcpy(addrP->addr, ifr_addrP, addr_size);
+
+    addrP->family = family;
+    addrP->brdcast = NULL;
+    addrP->mask = prefix;
+    addrP->next = 0;
+    if (family == AF_INET) {
+      /*
+       * Deal with brodcast addr & subnet mask
+       */
+       struct sockaddr * brdcast_to = (struct sockaddr *) ((char *) addrP + sizeof(netaddr) + addr_size);
+       addrP->brdcast = getBroadcast(env, sock, name,  brdcast_to );
+
+       if (addrP->brdcast && (mask = getSubnet(env, sock, name)) != -1) {
+           addrP->mask = mask;
+       }
+     }
+
+    /**
+     * Deal with virtual interface with colon notaion e.g. eth0:1
+     */
+    name_colonP = strchr(name, ':');
+    if (name_colonP != NULL) {
+      /**
+       * This is a virtual interface. If we are able to access the parent
+       * we need to create a new entry if it doesn't exist yet *and* update
+       * the 'parent' interface with the new records.
+       */
+        *name_colonP = 0;
+        if (getFlags(sock, name, &flags) < 0 || flags < 0) {
+            // failed to access parent interface do not create parent.
+            // We are a virtual interface with no parent.
+            isVirtual = 1;
+            *name_colonP = ':';
+        }
+        else{
+           // Got access to parent, so create it if necessary.
+           // Save original name to vname and truncate name by ':'
+            memcpy(vname, name, sizeof(vname) );
+            vname[name_colonP - name] = ':';
+        }
+    }
+
+    /*
+     * Check if this is a "new" interface. Use the interface
+     * name for matching because index isn't supported on
+     * Solaris 2.6 & 7.
+     */
+    while (currif != NULL) {
+        if (strcmp(name, currif->name) == 0) {
+            break;
+        }
+        currif = currif->next;
+    }
+
+    /*
+     * If "new" then create an netif structure and
+     * insert it onto the list.
+     */
+    if (currif == NULL) {
+         CHECKED_MALLOC3(currif, netif *, sizeof(netif) + ifnam_size);
+         currif->name = (char *) currif+sizeof(netif);
+         strncpy(currif->name, name, ifnam_size);
+         currif->name[ifnam_size - 1] = '\0';
+         currif->index = getIndex(sock, name);
+         currif->addr = NULL;
+         currif->childs = NULL;
+         currif->virtual = isVirtual;
+         currif->next = ifs;
+         ifs = currif;
+    }
+
+    /*
+     * Finally insert the address on the interface
+     */
+    addrP->next = currif->addr;
+    currif->addr = addrP;
+
+    parent = currif;
+
+    /**
+     * Let's deal with the virtual interface now.
+     */
+    if (vname[0]) {
+        netaddr *tmpaddr;
+
+        currif = parent->childs;
+
+        while (currif != NULL) {
+            if (strcmp(vname, currif->name) == 0) {
+                break;
+            }
+            currif = currif->next;
+        }
+
+        if (currif == NULL) {
+            CHECKED_MALLOC3(currif, netif *, sizeof(netif) + ifnam_size);
+            currif->name = (char *) currif + sizeof(netif);
+            strncpy(currif->name, vname, ifnam_size);
+            currif->name[ifnam_size - 1] = '\0';
+            currif->index = getIndex(sock, vname);
+            currif->addr = NULL;
+           /* Need to duplicate the addr entry? */
+            currif->virtual = 1;
+            currif->childs = NULL;
+            currif->next = parent->childs;
+            parent->childs = currif;
+        }
+
+        CHECKED_MALLOC3(tmpaddr, netaddr *, sizeof(netaddr)+2*addr_size);
+        memcpy(tmpaddr, addrP, sizeof(netaddr));
+        if (addrP->addr != NULL) {
+            tmpaddr->addr = (struct sockaddr *) ( (char*)tmpaddr + sizeof(netaddr) ) ;
+            memcpy(tmpaddr->addr, addrP->addr, addr_size);
+        }
+
+        if (addrP->brdcast != NULL) {
+            tmpaddr->brdcast = (struct sockaddr *) ((char *) tmpaddr + sizeof(netaddr)+addr_size);
+            memcpy(tmpaddr->brdcast, addrP->brdcast, addr_size);
+        }
+
+        tmpaddr->next = currif->addr;
+        currif->addr = tmpaddr;
+    }
+
+    return ifs;
+}
+
+/* Open socket for further ioct calls
+ * proto is AF_INET/AF_INET6
+ */
+static int  openSocket(JNIEnv *env, int proto){
+    int sock;
+
+    if ((sock = JVM_Socket(proto, SOCK_DGRAM, 0)) < 0) {
+        /*
+         * If EPROTONOSUPPORT is returned it means we don't have
+         * support  for this proto so don't throw an exception.
+         */
+        if (errno != EPROTONOSUPPORT) {
+            NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException", "Socket creation failed");
+        }
+        return -1;
+    }
+
+    return sock;
+}
+
+
+/** Linux **/
+#ifdef __linux__
+/* Open socket for further ioct calls, try v4 socket first and
+ * if it falls return v6 socket
+ */
+
+#ifdef AF_INET6
+static int openSocketWithFallback(JNIEnv *env, const char *ifname){
+    int sock;
+    struct ifreq if2;
+
+     if ((sock = JVM_Socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
+         if (errno == EPROTONOSUPPORT){
+              if ( (sock = JVM_Socket(AF_INET6, SOCK_DGRAM, 0)) < 0 ){
+                 NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException", "IPV6 Socket creation failed");
+                 return -1;
+              }
+         }
+         else{ // errno is not NOSUPPORT
+             NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException", "IPV4 Socket creation failed");
+             return -1;
+         }
+   }
+
+     /* Linux starting from 2.6.? kernel allows ioctl call with either IPv4 or IPv6 socket regardless of type
+        of address of an interface */
+
+       return sock;
+}
+
+#else
+static int openSocketWithFallback(JNIEnv *env, const char *ifname){
+    return openSocket(env,AF_INET);
+}
+#endif
+
+static netif *enumIPv4Interfaces(JNIEnv *env, int sock, netif *ifs) {
+    struct ifconf ifc;
+    struct ifreq *ifreqP;
+    char *buf;
+    int numifs;
+    unsigned i;
+
+
+    /* need to do a dummy SIOCGIFCONF to determine the buffer size.
+     * SIOCGIFCOUNT doesn't work
+     */
+    ifc.ifc_buf = NULL;
+    if (ioctl(sock, SIOCGIFCONF, (char *)&ifc) < 0) {
+        NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException", "ioctl SIOCGIFCONF failed");
+        return ifs;
+    }
+
+    CHECKED_MALLOC3(buf,char *, ifc.ifc_len);
+
+    ifc.ifc_buf = buf;
+    if (ioctl(sock, SIOCGIFCONF, (char *)&ifc) < 0) {
+        NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException", "ioctl SIOCGIFCONF failed");
+        (void) free(buf);
+        return ifs;
+    }
+
+    /*
+     * Iterate through each interface
+     */
+    ifreqP = ifc.ifc_req;
+    for (i=0; i<ifc.ifc_len/sizeof (struct ifreq); i++, ifreqP++) {
+        /*
+         * Add to the list
+         */
+        ifs = addif(env, sock, ifreqP->ifr_name, ifs, (struct sockaddr *) & (ifreqP->ifr_addr), AF_INET, 0);
+
+        /*
+         * If an exception occurred then free the list
+         */
+        if ((*env)->ExceptionOccurred(env)) {
+            free(buf);
+            freeif(ifs);
+            return NULL;
+        }
+    }
+
+    /*
+     * Free socket and buffer
+     */
+    free(buf);
+    return ifs;
+}
+
+
+/*
+ * Enumerates and returns all IPv6 interfaces on Linux
+ */
+
+#ifdef AF_INET6
+static netif *enumIPv6Interfaces(JNIEnv *env, int sock, netif *ifs) {
+    FILE *f;
+    char addr6[40], devname[21];
+    char addr6p[8][5];
+    int plen, scope, dad_status, if_idx;
+    uint8_t ipv6addr[16];
+
+    if ((f = fopen(_PATH_PROCNET_IFINET6, "r")) != NULL) {
+        while (fscanf(f, "%4s%4s%4s%4s%4s%4s%4s%4s %08x %02x %02x %02x %20s\n",
+                         addr6p[0], addr6p[1], addr6p[2], addr6p[3], addr6p[4], addr6p[5], addr6p[6], addr6p[7],
+                         &if_idx, &plen, &scope, &dad_status, devname) != EOF) {
+
+            struct netif *ifs_ptr = NULL;
+            struct netif *last_ptr = NULL;
+            struct sockaddr_in6 addr;
+
+            sprintf(addr6, "%s:%s:%s:%s:%s:%s:%s:%s",
+                           addr6p[0], addr6p[1], addr6p[2], addr6p[3], addr6p[4], addr6p[5], addr6p[6], addr6p[7]);
+            inet_pton(AF_INET6, addr6, ipv6addr);
+
+            memset(&addr, 0, sizeof(struct sockaddr_in6));
+            memcpy((void*)addr.sin6_addr.s6_addr, (const void*)ipv6addr, 16);
+
+            addr.sin6_scope_id = if_idx;
+
+            ifs = addif(env, sock, devname, ifs, (struct sockaddr *)&addr, AF_INET6, plen);
+
+
+            /*
+             * If an exception occurred then return the list as is.
+             */
+            if ((*env)->ExceptionOccurred(env)) {
+                fclose(f);
+                return ifs;
+            }
+       }
+       fclose(f);
+    }
+    return ifs;
+}
+#endif
+
+
+static int getIndex(int sock, const char *name){
+     /*
+      * Try to get the interface index
+      * (Not supported on Solaris 2.6 or 7)
+      */
+    struct ifreq if2;
+    strcpy(if2.ifr_name, name);
+
+    if (ioctl(sock, SIOCGIFINDEX, (char *)&if2) < 0) {
+        return -1;
+    }
+
+    return if2.ifr_ifindex;
+}
+
+/**
+ * Returns the IPv4 broadcast address of a named interface, if it exists.
+ * Returns 0 if it doesn't have one.
+ */
+static struct sockaddr *getBroadcast(JNIEnv *env, int sock, const char *ifname, struct sockaddr *brdcast_store) {
+  struct sockaddr *ret = NULL;
+  struct ifreq if2;
+
+  memset((char *) &if2, 0, sizeof(if2));
+  strcpy(if2.ifr_name, ifname);
+
+  /* Let's make sure the interface does have a broadcast address */
+  if (ioctl(sock, SIOCGIFFLAGS, (char *)&if2)  < 0) {
+      NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "IOCTL  SIOCGIFFLAGS failed");
+      return ret;
+  }
+
+  if (if2.ifr_flags & IFF_BROADCAST) {
+      /* It does, let's retrieve it*/
+      if (ioctl(sock, SIOCGIFBRDADDR, (char *)&if2) < 0) {
+          NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "IOCTL SIOCGIFBRDADDR failed");
+          return ret;
+      }
+
+      ret = brdcast_store;
+      memcpy(ret, &if2.ifr_broadaddr, sizeof(struct sockaddr));
+  }
+
+  return ret;
+}
+
+/**
+ * Returns the IPv4 subnet prefix length (aka subnet mask) for the named
+ * interface, if it has one, otherwise return -1.
+ */
+static short getSubnet(JNIEnv *env, int sock, const char *ifname) {
+    unsigned int mask;
+    short ret;
+    struct ifreq if2;
+
+    memset((char *) &if2, 0, sizeof(if2));
+    strcpy(if2.ifr_name, ifname);
+
+    if (ioctl(sock, SIOCGIFNETMASK, (char *)&if2) < 0) {
+        NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "IOCTL SIOCGIFNETMASK failed");
+        return -1;
+    }
+
+    mask = ntohl(((struct sockaddr_in*)&(if2.ifr_addr))->sin_addr.s_addr);
+    ret = 0;
+    while (mask) {
+       mask <<= 1;
+       ret++;
+    }
+
+    return ret;
+}
+
+/**
+ * Get the Hardware address (usually MAC address) for the named interface.
+ * return puts the data in buf, and returns the length, in byte, of the
+ * MAC address. Returns -1 if there is no hardware address on that interface.
+ */
+static int getMacAddress(JNIEnv *env, int sock, const char* ifname, const struct in_addr* addr, unsigned char *buf) {
+    static struct ifreq ifr;
+    int i;
+
+    strcpy(ifr.ifr_name, ifname);
+    if (ioctl(sock, SIOCGIFHWADDR, &ifr) < 0) {
+        NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "IOCTL SIOCGIFHWADDR failed");
+        return -1;
+    }
+
+    memcpy(buf, &ifr.ifr_hwaddr.sa_data, IFHWADDRLEN);
+
+   /*
+    * All bytes to 0 means no hardware address.
+    */
+
+    for (i = 0; i < IFHWADDRLEN; i++) {
+        if (buf[i] != 0)
+            return IFHWADDRLEN;
+    }
+
+    return -1;
+}
+
+static int getMTU(JNIEnv *env, int sock,  const char *ifname) {
+    struct ifreq if2;
+
+    memset((char *) &if2, 0, sizeof(if2));
+    strcpy(if2.ifr_name, ifname);
+
+    if (ioctl(sock, SIOCGIFMTU, (char *)&if2) < 0) {
+        NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "IOCTL SIOCGIFMTU failed");
+        return -1;
+    }
+
+    return  if2.ifr_mtu;
+}
+
+static int getFlags(int sock, const char *ifname, int *flags) {
+  struct ifreq if2;
+
+  memset((char *) &if2, 0, sizeof(if2));
+  strcpy(if2.ifr_name, ifname);
+
+  if (ioctl(sock, SIOCGIFFLAGS, (char *)&if2) < 0){
+      return -1;
+  }
+
+  if (sizeof(if2.ifr_flags) == sizeof(short)) {
+      *flags = (if2.ifr_flags & 0xffff);
+  } else {
+      *flags = if2.ifr_flags;
+  }
+  return 0;
+}
+
+#endif
+
+/** Solaris **/
+#ifdef __solaris__
+/* Open socket for further ioct calls, try v4 socket first and
+ * if it falls return v6 socket
+ */
+
+#ifdef AF_INET6
+static int openSocketWithFallback(JNIEnv *env, const char *ifname){
+    int sock, alreadyV6 = 0;
+    struct lifreq if2;
+
+     if ((sock = JVM_Socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
+         if (errno == EPROTONOSUPPORT){
+              if ( (sock = JVM_Socket(AF_INET6, SOCK_DGRAM, 0)) < 0 ){
+                 NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException", "IPV6 Socket creation failed");
+                 return -1;
+              }
+
+              alreadyV6=1;
+         }
+         else{ // errno is not NOSUPPORT
+             NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException", "IPV4 Socket creation failed");
+             return -1;
+         }
+   }
+
+     /**
+      * Solaris requires that we have IPv6 socket to query an
+      * interface without IPv4 address - check it here
+      * POSIX 1 require the kernell to return ENOTTY if the call is
+      * unappropriate for device e.g. NETMASK for device having IPv6
+      * only address but not all devices follows the standart so
+      * fallback on any error.  It's not an ecology friendly but more
+      * reliable.
+      */
+
+    if (! alreadyV6 ){
+        memset((char *) &if2, 0, sizeof(if2));
+        strcpy(if2.lifr_name, ifname);
+        if (ioctl(sock, SIOCGLIFNETMASK, (char *)&if2) < 0) {
+                close(sock);
+                if ( (sock = JVM_Socket(AF_INET6, SOCK_DGRAM, 0)) < 0 ){
+                      NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException", "IPV6 Socket creation failed");
+                      return -1;
+                }
+        }
+    }
+
+    return sock;
+}
+
+#else
+static int openSocketWithFallback(JNIEnv *env, const char *ifname){
+    return openSocket(env,AF_INET);
+}
+#endif
+
+/*
+ * Enumerates and returns all IPv4 interfaces
+ * (linux verison)
+ */
+
+static netif *enumIPv4Interfaces(JNIEnv *env, int sock, netif *ifs) {
+     return enumIPvXInterfaces(env,sock, ifs, AF_INET);
+}
+
+#ifdef AF_INET6
+static netif *enumIPv6Interfaces(JNIEnv *env, int sock, netif *ifs) {
+    return enumIPvXInterfaces(env,sock, ifs, AF_INET6);
+}
+#endif
+
+/*
+   Enumerates and returns all interfaces on Solaris
+   use the same code for IPv4 and IPv6
+ */
+static netif *enumIPvXInterfaces(JNIEnv *env, int sock, netif *ifs, int family) {
+    struct lifconf ifc;
+    struct lifreq *ifr;
+    int n;
+    char *buf;
+    struct lifnum numifs;
+    unsigned bufsize;
+
+    /*
+     * Get the interface count
+     */
+    numifs.lifn_family = family;
+    numifs.lifn_flags = 0;
+    if (ioctl(sock, SIOCGLIFNUM, (char *)&numifs) < 0) {
+        NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException", "ioctl SIOCGLIFNUM failed");
+        return ifs;
+    }
+
+    /*
+     *  Enumerate the interface configurations
+     */
+    bufsize = numifs.lifn_count * sizeof (struct lifreq);
+    CHECKED_MALLOC3(buf, char *, bufsize);
+
+    ifc.lifc_family = family;
+    ifc.lifc_flags = 0;
+    ifc.lifc_len = bufsize;
+    ifc.lifc_buf = buf;
+    if (ioctl(sock, SIOCGLIFCONF, (char *)&ifc) < 0) {
+        NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException", "ioctl SIOCGLIFCONF failed");
+        free(buf);
+        return ifs;
+    }
+
+    /*
+     * Iterate through each interface
+     */
+    ifr = ifc.lifc_req;
+    for (n=0; n<numifs.lifn_count; n++, ifr++) {
+        int index = -1;
+        struct lifreq if2;
+
+        /*
+        * Ignore either IPv4 or IPv6 addresses
+        */
+        if (ifr->lifr_addr.ss_family != family) {
+            continue;
+        }
+
+#ifdef AF_INET6
+        if (ifr->lifr_addr.ss_family == AF_INET6) {
+            struct sockaddr_in6 *s6= (struct sockaddr_in6 *)&(ifr->lifr_addr);
+            s6->sin6_scope_id = getIndex(sock, ifr->lifr_name);
+        }
+#endif
+
+        /* add to the list */
+        ifs = addif(env, sock,ifr->lifr_name, ifs, (struct sockaddr *)&(ifr->lifr_addr),family, (short) ifr->lifr_addrlen);
+
+        /*
+        * If an exception occurred we return immediately
+        */
+        if ((*env)->ExceptionOccurred(env)) {
+            free(buf);
+            return ifs;
+        }
+
+   }
+
+    free(buf);
+    return ifs;
+}
+
+static int getIndex(int sock, const char *name){
+   /*
+    * Try to get the interface index
+    * (Not supported on Solaris 2.6 or 7)
+    */
+    struct lifreq if2;
+    strcpy(if2.lifr_name, name);
+
+    if (ioctl(sock, SIOCGLIFINDEX, (char *)&if2) < 0) {
+        return -1;
+    }
+
+    return if2.lifr_index;
+}
+
+/**
+ * Returns the IPv4 broadcast address of a named interface, if it exists.
+ * Returns 0 if it doesn't have one.
+ */
+static struct sockaddr *getBroadcast(JNIEnv *env, int sock, const char *ifname, struct sockaddr *brdcast_store) {
+    struct sockaddr *ret = NULL;
+    struct lifreq if2;
+
+    memset((char *) &if2, 0, sizeof(if2));
+    strcpy(if2.lifr_name, ifname);
+
+    /* Let's make sure the interface does have a broadcast address */
+    if (ioctl(sock, SIOCGLIFFLAGS, (char *)&if2)  < 0) {
+        NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "IOCTL  SIOCGLIFFLAGS failed");
+        return ret;
+    }
+
+    if (if2.lifr_flags & IFF_BROADCAST) {
+        /* It does, let's retrieve it*/
+        if (ioctl(sock, SIOCGLIFBRDADDR, (char *)&if2) < 0) {
+            NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "IOCTL SIOCGLIFBRDADDR failed");
+            return ret;
+        }
+
+        ret = brdcast_store;
+        memcpy(ret, &if2.lifr_broadaddr, sizeof(struct sockaddr));
+    }
+
+    return ret;
+}
+
+/**
+ * Returns the IPv4 subnet prefix length (aka subnet mask) for the named
+ * interface, if it has one, otherwise return -1.
+ */
+static short getSubnet(JNIEnv *env, int sock, const char *ifname) {
+    unsigned int mask;
+    short ret;
+    struct lifreq if2;
+
+    memset((char *) &if2, 0, sizeof(if2));
+    strcpy(if2.lifr_name, ifname);
+
+    if (ioctl(sock, SIOCGLIFNETMASK, (char *)&if2) < 0) {
+        NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "IOCTL SIOCGLIFNETMASK failed");
+        return -1;
+    }
+
+    mask = ntohl(((struct sockaddr_in*)&(if2.lifr_addr))->sin_addr.s_addr);
+    ret = 0;
+
+    while (mask) {
+       mask <<= 1;
+       ret++;
+    }
+
+    return ret;
+}
+
+
+
+#define DEV_PREFIX  "/dev/"
+
+/**
+ * Solaris specific DLPI code to get hardware address from a device.
+ * Unfortunately, at least up to Solaris X, you have to have special
+ * privileges (i.e. be root).
+ */
+static int getMacFromDevice(JNIEnv *env, const char* ifname, unsigned char* retbuf) {
+    char style1dev[MAXPATHLEN];
+    int fd;
+    dl_phys_addr_req_t dlpareq;
+    dl_phys_addr_ack_t *dlpaack;
+    struct strbuf msg;
+    char buf[128];
+    int flags = 0;
+
+   /**
+    * Device is in /dev
+    * e.g.: /dev/bge0
+    */
+    strcpy(style1dev, DEV_PREFIX);
+    strcat(style1dev, ifname);
+    if ((fd = open(style1dev, O_RDWR)) < 0) {
+        /*
+         * Can't open it. We probably are missing the privilege.
+         * We'll have to try something else
+         */
+         return 0;
+    }
+
+    dlpareq.dl_primitive = DL_PHYS_ADDR_REQ;
+    dlpareq.dl_addr_type = DL_CURR_PHYS_ADDR;
+
+    msg.buf = (char *)&dlpareq;
+    msg.len = DL_PHYS_ADDR_REQ_SIZE;
+
+    if (putmsg(fd, &msg, NULL, 0) < 0) {
+        NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "putmsg failed");
+        return -1;
+    }
+
+    dlpaack = (dl_phys_addr_ack_t *)buf;
+
+    msg.buf = (char *)buf;
+    msg.len = 0;
+    msg.maxlen = sizeof (buf);
+    if (getmsg(fd, &msg, NULL, &flags) < 0) {
+        NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "getmsg failed");
+        return -1;
+    }
+
+    if (msg.len < DL_PHYS_ADDR_ACK_SIZE || dlpaack->dl_primitive != DL_PHYS_ADDR_ACK) {
+        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Couldn't obtain phys addr\n");
+        return -1;
+    }
+
+    memcpy(retbuf, &buf[dlpaack->dl_addr_offset], dlpaack->dl_addr_length);
+    return dlpaack->dl_addr_length;
+}
+
+/**
+ * Get the Hardware address (usually MAC address) for the named interface.
+ * return puts the data in buf, and returns the length, in byte, of the
+ * MAC address. Returns -1 if there is no hardware address on that interface.
+ */
+static int getMacAddress(JNIEnv *env, int sock, const char *ifname,  const struct in_addr* addr, unsigned char *buf) {
+    struct arpreq arpreq;
+    struct sockaddr_in* sin;
+    struct sockaddr_in ipAddr;
+    int len, i;
+    struct lifreq lif;
+
+    /* First, try the new (S11) SIOCGLIFHWADDR ioctl(). If that fails
+     * try the old way.
+     */
+    memset(&lif, 0, sizeof(lif));
+    strlcpy(lif.lifr_name, ifname, sizeof(lif.lifr_name));
+
+    if (ioctl(sock, SIOCGLIFHWADDR, &lif) != -1) {
+        struct sockaddr_dl *sp;
+        sp = (struct sockaddr_dl *)&lif.lifr_addr;
+        memcpy(buf, &sp->sdl_data[0], sp->sdl_alen);
+        return sp->sdl_alen;
+    }
+
+   /**
+    * On Solaris we have to use DLPI, but it will only work if we have
+    * privileged access (i.e. root). If that fails, we try a lookup
+    * in the ARP table, which requires an IPv4 address.
+    */
+    if ((len = getMacFromDevice(env, ifname, buf))  == 0) {
+        /*DLPI failed - trying to do arp lookup*/
+
+        if (addr == NULL) {
+            /**
+             * No IPv4 address for that interface, so can't do an ARP lookup.
+             */
+             return -1;
+         }
+
+         len = 6; //???
+
+         sin = (struct sockaddr_in *) &arpreq.arp_pa;
+         memset((char *) &arpreq, 0, sizeof(struct arpreq));
+         ipAddr.sin_port = 0;
+         ipAddr.sin_family = AF_INET;
+         memcpy(&ipAddr.sin_addr, addr, sizeof(struct in_addr));
+         memcpy(&arpreq.arp_pa, &ipAddr, sizeof(struct sockaddr_in));
+         arpreq.arp_flags= ATF_PUBL;
+
+         if (ioctl(sock, SIOCGARP, &arpreq) < 0) {
+             return -1;
+         }
+
+         memcpy(buf, &arpreq.arp_ha.sa_data[0], len );
+    }
+
+    /*
+     * All bytes to 0 means no hardware address.
+     */
+
+    for (i = 0; i < len; i++) {
+      if (buf[i] != 0)
+         return len;
+    }
+
+    return -1;
+}
+
+static int getMTU(JNIEnv *env, int sock,  const char *ifname) {
+    struct lifreq if2;
+
+    memset((char *) &if2, 0, sizeof(if2));
+    strcpy(if2.lifr_name, ifname);
+
+    if (ioctl(sock, SIOCGLIFMTU, (char *)&if2) < 0) {
+        NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "IOCTL SIOCGLIFMTU failed");
+        return -1;
+    }
+
+    return  if2.lifr_mtu;
+}
+
+
+static int getFlags(int sock, const char *ifname, int *flags) {
+     struct   lifreq lifr;
+     memset((caddr_t)&lifr, 0, sizeof(lifr));
+     strcpy((caddr_t)&(lifr.lifr_name), ifname);
+
+     if (ioctl(sock, SIOCGLIFFLAGS, (char *)&lifr) < 0) {
+         return -1;
+     }
+
+     *flags = lifr.lifr_flags;
+     return 0;
+}
+
+
+#endif
+
+
+/** BSD **/
+#ifdef _ALLBSD_SOURCE
+/* Open socket for further ioct calls, try v4 socket first and
+ * if it falls return v6 socket
+ */
+
+#ifdef AF_INET6
+static int openSocketWithFallback(JNIEnv *env, const char *ifname){
+    int sock;
+    struct ifreq if2;
+
+     if ((sock = JVM_Socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
+         if (errno == EPROTONOSUPPORT){
+              if ( (sock = JVM_Socket(AF_INET6, SOCK_DGRAM, 0)) < 0 ){
+                 NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException", "IPV6 Socket creation failed");
+                 return -1;
+              }
+         }
+         else{ // errno is not NOSUPPORT
+             NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException", "IPV4 Socket creation failed");
+             return -1;
+         }
+   }
+
+   return sock;
+}
+
+#else
+static int openSocketWithFallback(JNIEnv *env, const char *ifname){
+    return openSocket(env,AF_INET);
+}
+#endif
+
+/*
+ * Enumerates and returns all IPv4 interfaces
+ */
+static netif *enumIPv4Interfaces(JNIEnv *env, int sock, netif *ifs) {
+    struct ifaddrs *ifa, *origifa;
+
+    if (getifaddrs(&origifa) != 0) {
+        NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException",
+                         "getifaddrs() function failed");
+        return ifs;
+    }
+
+    for (ifa = origifa; ifa != NULL; ifa = ifa->ifa_next) {
+
+        /*
+         * Skip non-AF_INET entries.
+         */
+        if (ifa->ifa_addr == NULL || ifa->ifa_addr->sa_family != AF_INET)
+            continue;
+
+        /*
+         * Add to the list.
+         */
+        ifs = addif(env, sock, ifa->ifa_name, ifs, ifa->ifa_addr, AF_INET, 0);
+
+        /*
+         * If an exception occurred then free the list.
+         */
+        if ((*env)->ExceptionOccurred(env)) {
+            freeifaddrs(origifa);
+            freeif(ifs);
+            return NULL;
+        }
+    }
+
+    /*
+     * Free socket and buffer
+     */
+    freeifaddrs(origifa);
+    return ifs;
+}
+
+
+/*
+ * Enumerates and returns all IPv6 interfaces on Linux
+ */
+
+#ifdef AF_INET6
+/*
+ * Determines the prefix on BSD for IPv6 interfaces.
+ */
+static
+int prefix(void *val, int size) {
+    u_char *name = (u_char *)val;
+    int byte, bit, plen = 0;
+
+    for (byte = 0; byte < size; byte++, plen += 8)
+        if (name[byte] != 0xff)
+            break;
+    if (byte == size)
+        return (plen);
+    for (bit = 7; bit != 0; bit--, plen++)
+        if (!(name[byte] & (1 << bit)))
+            break;
+    for (; bit != 0; bit--)
+        if (name[byte] & (1 << bit))
+            return (0);
+    byte++;
+    for (; byte < size; byte++)
+        if (name[byte])
+            return (0);
+    return (plen);
+}
+
+/*
+ * Enumerates and returns all IPv6 interfaces on BSD
+ */
+static netif *enumIPv6Interfaces(JNIEnv *env, int sock, netif *ifs) {
+    struct ifaddrs *ifa, *origifa;
+    struct sockaddr_in6 *sin6;
+    struct in6_ifreq ifr6;
+
+    if (getifaddrs(&origifa) != 0) {
+        NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException",
+                         "getifaddrs() function failed");
+        return ifs;
+    }
+
+    for (ifa = origifa; ifa != NULL; ifa = ifa->ifa_next) {
+
+        /*
+         * Skip non-AF_INET6 entries.
+         */
+        if (ifa->ifa_addr == NULL || ifa->ifa_addr->sa_family != AF_INET6)
+            continue;
+
+        memset(&ifr6, 0, sizeof(ifr6));
+        strlcpy(ifr6.ifr_name, ifa->ifa_name, sizeof(ifr6.ifr_name));
+        memcpy(&ifr6.ifr_addr, ifa->ifa_addr, MIN(sizeof(ifr6.ifr_addr), ifa->ifa_addr->sa_len));
+
+        if (ioctl(sock, SIOCGIFNETMASK_IN6, (caddr_t)&ifr6) < 0) {
+            NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException",
+                             "ioctl SIOCGIFNETMASK_IN6 failed");
+            freeifaddrs(origifa);
+            freeif(ifs);
+            return NULL;
+        }
+
+        /* Add to the list.  */
+        sin6 = (struct sockaddr_in6 *)&ifr6.ifr_addr;
+        ifs = addif(env, sock, ifa->ifa_name, ifs, ifa->ifa_addr, AF_INET6,
+                    prefix(&sin6->sin6_addr, sizeof(struct in6_addr)));
+
+        /* If an exception occurred then free the list.  */
+        if ((*env)->ExceptionOccurred(env)) {
+            freeifaddrs(origifa);
+            freeif(ifs);
+            return NULL;
+        }
+    }
+
+    /*
+     * Free socket and ifaddrs buffer
+     */
+    freeifaddrs(origifa);
+    return ifs;
+}
+#endif
+
+static int getIndex(int sock, const char *name){
+#ifdef __FreeBSD__
+     /*
+      * Try to get the interface index
+      * (Not supported on Solaris 2.6 or 7)
+      */
+    struct ifreq if2;
+    strcpy(if2.ifr_name, name);
+
+    if (ioctl(sock, SIOCGIFINDEX, (char *)&if2) < 0) {
+        return -1;
+    }
+
+    return if2.ifr_index;
+#else
+    /*
+     * Try to get the interface index using BSD specific if_nametoindex
+     */
+    int index = if_nametoindex(name);
+    return (index == 0) ? -1 : index;
+#endif
+}
+
+/**
+ * Returns the IPv4 broadcast address of a named interface, if it exists.
+ * Returns 0 if it doesn't have one.
+ */
+static struct sockaddr *getBroadcast(JNIEnv *env, int sock, const char *ifname, struct sockaddr *brdcast_store) {
+  struct sockaddr *ret = NULL;
+  struct ifreq if2;
+
+  memset((char *) &if2, 0, sizeof(if2));
+  strcpy(if2.ifr_name, ifname);
+
+  /* Let's make sure the interface does have a broadcast address */
+  if (ioctl(sock, SIOCGIFFLAGS, (char *)&if2) < 0) {
+      NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "IOCTL SIOCGIFFLAGS failed");
+      return ret;
+  }
+
+  if (if2.ifr_flags & IFF_BROADCAST) {
+      /* It does, let's retrieve it*/
+      if (ioctl(sock, SIOCGIFBRDADDR, (char *)&if2) < 0) {
+          NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "IOCTL SIOCGIFBRDADDR failed");
+          return ret;
+      }
+
+      ret = brdcast_store;
+      memcpy(ret, &if2.ifr_broadaddr, sizeof(struct sockaddr));
+  }
+
+  return ret;
+}
+
+/**
+ * Returns the IPv4 subnet prefix length (aka subnet mask) for the named
+ * interface, if it has one, otherwise return -1.
+ */
+static short getSubnet(JNIEnv *env, int sock, const char *ifname) {
+    unsigned int mask;
+    short ret;
+    struct ifreq if2;
+
+    memset((char *) &if2, 0, sizeof(if2));
+    strcpy(if2.ifr_name, ifname);
+
+    if (ioctl(sock, SIOCGIFNETMASK, (char *)&if2) < 0) {
+        NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "IOCTL SIOCGIFNETMASK failed");
+        return -1;
+    }
+
+    mask = ntohl(((struct sockaddr_in*)&(if2.ifr_addr))->sin_addr.s_addr);
+    ret = 0;
+    while (mask) {
+       mask <<= 1;
+       ret++;
+    }
+
+    return ret;
+}
+
+/**
+ * Get the Hardware address (usually MAC address) for the named interface.
+ * return puts the data in buf, and returns the length, in byte, of the
+ * MAC address. Returns -1 if there is no hardware address on that interface.
+ */
+static int getMacAddress(JNIEnv *env, int sock, const char* ifname, const struct in_addr* addr, unsigned char *buf) {
+    struct ifaddrs *ifa0, *ifa;
+    struct sockaddr *saddr;
+    int i;
+
+    /* Grab the interface list */
+    if (!getifaddrs(&ifa0)) {
+        /* Cycle through the interfaces */
+        for (i = 0, ifa = ifa0; ifa != NULL; ifa = ifa->ifa_next, i++) {
+            saddr = ifa->ifa_addr;
+            /* Link layer contains the MAC address */
+            if (saddr->sa_family == AF_LINK && !strcmp(ifname, ifa->ifa_name)) {
+                struct sockaddr_dl *sadl = (struct sockaddr_dl *) saddr;
+                /* Check the address is the correct length */
+                if (sadl->sdl_alen == ETHER_ADDR_LEN) {
+                    memcpy(buf, (sadl->sdl_data + sadl->sdl_nlen), ETHER_ADDR_LEN);
+                    freeifaddrs(ifa0);
+                    return ETHER_ADDR_LEN;
+                }
+            }
+        }
+        freeifaddrs(ifa0);
+    }
+
+    return -1;
+}
+
+static int getMTU(JNIEnv *env, int sock,  const char *ifname) {
+    struct ifreq if2;
+
+    memset((char *) &if2, 0, sizeof(if2));
+    strcpy(if2.ifr_name, ifname);
+
+    if (ioctl(sock, SIOCGIFMTU, (char *)&if2) < 0) {
+        NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "IOCTL SIOCGIFMTU failed");
+        return -1;
+    }
+
+    return  if2.ifr_mtu;
+}
+
+static int getFlags(int sock, const char *ifname, int *flags) {
+  struct ifreq if2;
+  int ret = -1;
+
+  memset((char *) &if2, 0, sizeof(if2));
+  strcpy(if2.ifr_name, ifname);
+
+  if (ioctl(sock, SIOCGIFFLAGS, (char *)&if2) < 0){
+      return -1;
+  }
+
+  if (sizeof(if2.ifr_flags) == sizeof(short)) {
+    *flags = (if2.ifr_flags & 0xffff);
+  } else {
+    *flags = if2.ifr_flags;
+  }
+  return 0;
+}
+
+#endif
diff --git a/ojluni/src/main/native/ObjectStreamClass.c b/ojluni/src/main/native/ObjectStreamClass.c
new file mode 100755
index 0000000..f9e6c57
--- /dev/null
+++ b/ojluni/src/main/native/ObjectStreamClass.c
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2001, 2003, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include "jni.h"
+#include "jvm.h"
+
+#include "java_io_ObjectStreamClass.h"
+
+static jclass noSuchMethodErrCl;
+
+/*
+ * Class:     java_io_ObjectStreamClass
+ * Method:    initNative
+ * Signature: ()V
+ *
+ * Native code initialization hook.
+ */
+JNIEXPORT void JNICALL
+Java_java_io_ObjectStreamClass_initNative(JNIEnv *env, jclass this)
+{
+    jclass cl = (*env)->FindClass(env, "java/lang/NoSuchMethodError");
+    if (cl == NULL) {           /* exception thrown */
+        return;
+    }
+    noSuchMethodErrCl = (*env)->NewGlobalRef(env, cl);
+}
+
+/*
+ * Class:     java_io_ObjectStreamClass
+ * Method:    hasStaticInitializer
+ * Signature: (Ljava/lang/Class;)Z
+ *
+ * Returns true if the given class defines a <clinit>()V method; returns false
+ * otherwise.
+ */
+JNIEXPORT jboolean JNICALL
+Java_java_io_ObjectStreamClass_hasStaticInitializer(JNIEnv *env, jclass this,
+                                                    jclass clazz)
+{
+    jclass superCl = NULL;
+    jmethodID superClinitId = NULL;
+    jmethodID clinitId =
+        (*env)->GetStaticMethodID(env, clazz, "<clinit>", "()V");
+    if (clinitId == NULL) {     /* error thrown */
+        jthrowable th = (*env)->ExceptionOccurred(env);
+        (*env)->ExceptionClear(env);    /* normal return */
+        if (!(*env)->IsInstanceOf(env, th, noSuchMethodErrCl)) {
+            (*env)->Throw(env, th);
+        }
+        return JNI_FALSE;
+    }
+
+    /*
+     * Check superclass for static initializer as well--if the same method ID
+     * is returned, then the static initializer is from a superclass.
+     * Empirically, this step appears to be unnecessary in 1.4; however, the
+     * JNI spec makes no guarantee that GetStaticMethodID will not return the
+     * ID for a superclass initializer.
+     */
+
+    if ((superCl = (*env)->GetSuperclass(env, clazz)) == NULL) {
+        return JNI_TRUE;
+    }
+    superClinitId =
+        (*env)->GetStaticMethodID(env, superCl, "<clinit>", "()V");
+    if (superClinitId == NULL) {        /* error thrown */
+        jthrowable th = (*env)->ExceptionOccurred(env);
+        (*env)->ExceptionClear(env);    /* normal return */
+        if (!(*env)->IsInstanceOf(env, th, noSuchMethodErrCl)) {
+            (*env)->Throw(env, th);
+        }
+        return JNI_TRUE;
+    }
+
+    return (clinitId != superClinitId);
+}
diff --git a/ojluni/src/main/native/PlainDatagramSocketImpl.c b/ojluni/src/main/native/PlainDatagramSocketImpl.c
new file mode 100755
index 0000000..64f0b7b
--- /dev/null
+++ b/ojluni/src/main/native/PlainDatagramSocketImpl.c
@@ -0,0 +1,2465 @@
+/*
+ * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include <errno.h>
+#include <netinet/in.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#ifdef __solaris__
+#include <fcntl.h>
+#endif
+#ifdef __linux__
+#include <unistd.h>
+#include <sys/sysctl.h>
+#include <sys/utsname.h>
+#include <netinet/ip.h>
+
+#define IPV6_MULTICAST_IF 17
+#ifndef SO_BSDCOMPAT
+#define SO_BSDCOMPAT  14
+#endif
+#endif
+
+#ifndef IPTOS_TOS_MASK
+#define IPTOS_TOS_MASK 0x1e
+#endif
+#ifndef IPTOS_PREC_MASK
+#define IPTOS_PREC_MASK 0xe0
+#endif
+
+#include "jvm.h"
+#include "jni_util.h"
+#include "net_util.h"
+
+#include "java_net_SocketOptions.h"
+#include "java_net_PlainDatagramSocketImpl.h"
+#include "java_net_NetworkInterface.h"
+/************************************************************************
+ * PlainDatagramSocketImpl
+ */
+
+static jfieldID IO_fd_fdID;
+
+static jfieldID pdsi_fdID;
+static jfieldID pdsi_timeoutID;
+static jfieldID pdsi_trafficClassID;
+static jfieldID pdsi_localPortID;
+static jfieldID pdsi_connected;
+static jfieldID pdsi_connectedAddress;
+static jfieldID pdsi_connectedPort;
+
+#ifdef __linux__
+static jboolean isOldKernel;
+#endif
+
+#if defined(__linux__) && defined(AF_INET6)
+static jfieldID pdsi_multicastInterfaceID;
+static jfieldID pdsi_loopbackID;
+static jfieldID pdsi_ttlID;
+#endif
+
+extern void setDefaultScopeID(JNIEnv *env, struct sockaddr *him);
+extern int getDefaultScopeID(JNIEnv *env);
+
+/*
+ * Returns a java.lang.Integer based on 'i'
+ */
+static jobject createInteger(JNIEnv *env, int i) {
+    static jclass i_class;
+    static jmethodID i_ctrID;
+
+    if (i_class == NULL) {
+        jclass c = (*env)->FindClass(env, "java/lang/Integer");
+        CHECK_NULL_RETURN(c, NULL);
+        i_ctrID = (*env)->GetMethodID(env, c, "<init>", "(I)V");
+        CHECK_NULL_RETURN(i_ctrID, NULL);
+        i_class = (*env)->NewGlobalRef(env, c);
+        CHECK_NULL_RETURN(i_class, NULL);
+    }
+
+    return ( (*env)->NewObject(env, i_class, i_ctrID, i) );
+}
+
+/*
+ * Returns a java.lang.Boolean based on 'b'
+ */
+static jobject createBoolean(JNIEnv *env, int b) {
+    static jclass b_class;
+    static jmethodID b_ctrID;
+
+    if (b_class == NULL) {
+        jclass c = (*env)->FindClass(env, "java/lang/Boolean");
+        CHECK_NULL_RETURN(c, NULL);
+        b_ctrID = (*env)->GetMethodID(env, c, "<init>", "(Z)V");
+        CHECK_NULL_RETURN(b_ctrID, NULL);
+        b_class = (*env)->NewGlobalRef(env, c);
+        CHECK_NULL_RETURN(b_class, NULL);
+    }
+
+    return( (*env)->NewObject(env, b_class, b_ctrID, (jboolean)(b!=0)) );
+}
+
+
+/*
+ * Returns the fd for a PlainDatagramSocketImpl or -1
+ * if closed.
+ */
+static int getFD(JNIEnv *env, jobject this) {
+    jobject fdObj = (*env)->GetObjectField(env, this, pdsi_fdID);
+    if (fdObj == NULL) {
+        return -1;
+    }
+    return (*env)->GetIntField(env, fdObj, IO_fd_fdID);
+}
+
+
+/*
+ * Class:     java_net_PlainDatagramSocketImpl
+ * Method:    init
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL
+Java_java_net_PlainDatagramSocketImpl_init(JNIEnv *env, jclass cls) {
+
+#ifdef __linux__
+    struct utsname sysinfo;
+#endif
+    pdsi_fdID = (*env)->GetFieldID(env, cls, "fd",
+                                   "Ljava/io/FileDescriptor;");
+    CHECK_NULL(pdsi_fdID);
+    pdsi_timeoutID = (*env)->GetFieldID(env, cls, "timeout", "I");
+    CHECK_NULL(pdsi_timeoutID);
+    pdsi_trafficClassID = (*env)->GetFieldID(env, cls, "trafficClass", "I");
+    CHECK_NULL(pdsi_trafficClassID);
+    pdsi_localPortID = (*env)->GetFieldID(env, cls, "localPort", "I");
+    CHECK_NULL(pdsi_localPortID);
+    pdsi_connected = (*env)->GetFieldID(env, cls, "connected", "Z");
+    CHECK_NULL(pdsi_connected);
+    pdsi_connectedAddress = (*env)->GetFieldID(env, cls, "connectedAddress",
+                                               "Ljava/net/InetAddress;");
+    CHECK_NULL(pdsi_connectedAddress);
+    pdsi_connectedPort = (*env)->GetFieldID(env, cls, "connectedPort", "I");
+    CHECK_NULL(pdsi_connectedPort);
+
+    IO_fd_fdID = NET_GetFileDescriptorID(env);
+    CHECK_NULL(IO_fd_fdID);
+
+    Java_java_net_InetAddress_init(env, 0);
+    Java_java_net_Inet4Address_init(env, 0);
+    Java_java_net_Inet6Address_init(env, 0);
+    Java_java_net_NetworkInterface_init(env, 0);
+
+#ifdef __linux__
+    /*
+     * We need to determine if this is a 2.2 kernel.
+     */
+    if (uname(&sysinfo) == 0) {
+        sysinfo.release[3] = '\0';
+        isOldKernel = (strcmp(sysinfo.release, "2.2") == 0);
+    } else {
+        /*
+         * uname failed - move to plan B and examine /proc/version
+         * If this fails assume that /proc has changed and that
+         * this must be new /proc format and hence new kernel.
+         */
+        FILE *fP;
+        isOldKernel = JNI_FALSE;
+        if ((fP = fopen("/proc/version", "r")) != NULL) {
+            char ver[25];
+            if (fgets(ver, sizeof(ver), fP) != NULL) {
+                isOldKernel = (strstr(ver, "2.2.") != NULL);
+            }
+            fclose(fP);
+        }
+    }
+
+#ifdef AF_INET6
+    pdsi_multicastInterfaceID = (*env)->GetFieldID(env, cls, "multicastInterface", "I");
+    CHECK_NULL(pdsi_multicastInterfaceID);
+    pdsi_loopbackID = (*env)->GetFieldID(env, cls, "loopbackMode", "Z");
+    CHECK_NULL(pdsi_loopbackID);
+    pdsi_ttlID = (*env)->GetFieldID(env, cls, "ttl", "I");
+    CHECK_NULL(pdsi_ttlID);
+#endif
+
+#endif
+
+}
+
+/*
+ * Class:     java_net_PlainDatagramSocketImpl
+ * Method:    bind
+ * Signature: (ILjava/net/InetAddress;)V
+ */
+JNIEXPORT void JNICALL
+Java_java_net_PlainDatagramSocketImpl_bind0(JNIEnv *env, jobject this,
+                                           jint localport, jobject iaObj) {
+    /* fdObj is the FileDescriptor field on this */
+    jobject fdObj = (*env)->GetObjectField(env, this, pdsi_fdID);
+    /* fd is an int field on fdObj */
+    int fd;
+    int len = 0;
+    SOCKADDR him;
+
+    if (IS_NULL(fdObj)) {
+        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
+                        "Socket closed");
+        return;
+    } else {
+        fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
+    }
+
+    if (IS_NULL(iaObj)) {
+        JNU_ThrowNullPointerException(env, "iaObj is null.");
+        return;
+    }
+
+    /* bind */
+    if (NET_InetAddressToSockaddr(env, iaObj, localport, (struct sockaddr *)&him, &len, JNI_TRUE) != 0) {
+      return;
+    }
+    setDefaultScopeID(env, (struct sockaddr *)&him);
+
+    if (NET_Bind(fd, (struct sockaddr *)&him, len) < 0)  {
+        if (errno == EADDRINUSE || errno == EADDRNOTAVAIL ||
+            errno == EPERM || errno == EACCES) {
+            NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "BindException",
+                            "Bind failed");
+        } else {
+            NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
+                            "Bind failed");
+        }
+        return;
+    }
+
+    /* intialize the local port */
+    if (localport == 0) {
+        /* Now that we're a connected socket, let's extract the port number
+         * that the system chose for us and store it in the Socket object.
+         */
+        if (JVM_GetSockName(fd, (struct sockaddr *)&him, &len) == -1) {
+            NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
+                            "Error getting socket name");
+            return;
+        }
+
+        localport = NET_GetPortFromSockaddr((struct sockaddr *)&him);
+
+        (*env)->SetIntField(env, this, pdsi_localPortID, localport);
+    } else {
+        (*env)->SetIntField(env, this, pdsi_localPortID, localport);
+    }
+}
+
+/*
+ * Class:     java_net_PlainDatagramSocketImpl
+ * Method:    connect0
+ * Signature: (Ljava/net/InetAddress;I)V
+ */
+JNIEXPORT void JNICALL
+Java_java_net_PlainDatagramSocketImpl_connect0(JNIEnv *env, jobject this,
+                                               jobject address, jint port) {
+    /* The object's field */
+    jobject fdObj = (*env)->GetObjectField(env, this, pdsi_fdID);
+    /* The fdObj'fd */
+    jint fd;
+    /* The packetAddress address, family and port */
+    SOCKADDR rmtaddr;
+    int len = 0;
+
+    if (IS_NULL(fdObj)) {
+        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
+                        "Socket closed");
+        return;
+    }
+    fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
+
+    if (IS_NULL(address)) {
+        JNU_ThrowNullPointerException(env, "address");
+        return;
+    }
+
+    if (NET_InetAddressToSockaddr(env, address, port, (struct sockaddr *)&rmtaddr, &len, JNI_TRUE) != 0) {
+      return;
+    }
+
+#ifdef __linux__
+    if (isOldKernel) {
+        int t = 0;
+        setsockopt(fd, SOL_SOCKET, SO_BSDCOMPAT, (char*) &t, sizeof(int));
+    } else
+#endif
+    setDefaultScopeID(env, (struct sockaddr *)&rmtaddr);
+    {
+        if (JVM_Connect(fd, (struct sockaddr *)&rmtaddr, len) == -1) {
+            NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "ConnectException",
+                            "Connect failed");
+            return;
+        }
+    }
+}
+
+/*
+ * Class:     java_net_PlainDatagramSocketImpl
+ * Method:    disconnect0
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL
+Java_java_net_PlainDatagramSocketImpl_disconnect0(JNIEnv *env, jobject this, jint family) {
+    /* The object's field */
+    jobject fdObj = (*env)->GetObjectField(env, this, pdsi_fdID);
+    /* The fdObj'fd */
+    jint fd;
+
+#if defined(__linux__) || defined(_ALLBSD_SOURCE)
+    SOCKADDR addr;
+    int len;
+#endif
+
+    if (IS_NULL(fdObj)) {
+        return;
+    }
+    fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
+
+#if defined(__linux__) || defined(_ALLBSD_SOURCE)
+#ifdef __linux__
+    if (isOldKernel) {
+        int t = 1;
+        setsockopt(fd, SOL_SOCKET, SO_BSDCOMPAT, (char*) &t, sizeof(int));
+    } else {
+#endif /* __linux__ */
+        memset(&addr, 0, sizeof(addr));
+#ifdef AF_INET6
+        if (ipv6_available()) {
+            struct sockaddr_in6 *him6 = (struct sockaddr_in6 *)&addr;
+            him6->sin6_family = AF_UNSPEC;
+            len = sizeof(struct sockaddr_in6);
+        } else
+#endif
+        {
+            struct sockaddr_in *him4 = (struct sockaddr_in*)&addr;
+            him4->sin_family = AF_UNSPEC;
+            len = sizeof(struct sockaddr_in);
+        }
+        JVM_Connect(fd, (struct sockaddr *)&addr, len);
+
+#ifdef __linux__
+        // After disconnecting a UDP socket, Linux kernel will set
+        // local port to zero if the port number comes from implicit
+        // bind. Successive send/recv on the same socket will fail.
+        // So bind again with former port number here.
+        int localPort = 0;
+        if (JVM_GetSockName(fd, (struct sockaddr *)&addr, &len) == -1) {
+            return;
+        }
+        localPort = NET_GetPortFromSockaddr((struct sockaddr *)&addr);
+        if (localPort == 0) {
+            localPort = (*env)->GetIntField(env, this, pdsi_localPortID);
+#ifdef AF_INET6
+            if (((struct sockaddr*)&addr)->sa_family == AF_INET6) {
+                ((struct sockaddr_in6*)&addr)->sin6_port = htons(localPort);
+            } else
+#endif /* AF_INET6 */
+            {
+                ((struct sockaddr_in*)&addr)->sin_port = htons(localPort);
+            }
+            NET_Bind(fd, (struct sockaddr *)&addr, len);
+        }
+    }
+#endif
+#else
+    JVM_Connect(fd, 0, 0);
+#endif
+}
+
+/*
+ * Class:     java_net_PlainDatagramSocketImpl
+ * Method:    send
+ * Signature: (Ljava/net/DatagramPacket;)V
+ */
+JNIEXPORT void JNICALL
+Java_java_net_PlainDatagramSocketImpl_send(JNIEnv *env, jobject this,
+                                           jobject packet) {
+
+    char BUF[MAX_BUFFER_LEN];
+    char *fullPacket = NULL;
+    int ret, mallocedPacket = JNI_FALSE;
+    /* The object's field */
+    jobject fdObj = (*env)->GetObjectField(env, this, pdsi_fdID);
+    jint trafficClass = (*env)->GetIntField(env, this, pdsi_trafficClassID);
+
+    jbyteArray packetBuffer;
+    jobject packetAddress;
+    jint packetBufferOffset, packetBufferLen, packetPort;
+    jboolean connected;
+
+    /* The fdObj'fd */
+    jint fd;
+
+    SOCKADDR rmtaddr, *rmtaddrP=&rmtaddr;
+    int len;
+
+    if (IS_NULL(fdObj)) {
+        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
+                        "Socket closed");
+        return;
+    }
+    fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
+
+    if (IS_NULL(packet)) {
+        JNU_ThrowNullPointerException(env, "packet");
+        return;
+    }
+
+    connected = (*env)->GetBooleanField(env, this, pdsi_connected);
+
+    packetBuffer = (*env)->GetObjectField(env, packet, dp_bufID);
+    packetAddress = (*env)->GetObjectField(env, packet, dp_addressID);
+    if (IS_NULL(packetBuffer) || IS_NULL(packetAddress)) {
+        JNU_ThrowNullPointerException(env, "null buffer || null address");
+        return;
+    }
+
+    packetBufferOffset = (*env)->GetIntField(env, packet, dp_offsetID);
+    packetBufferLen = (*env)->GetIntField(env, packet, dp_lengthID);
+
+#ifdef __linux__
+    if (connected && !isOldKernel) {
+#else
+    if (connected) {
+#endif
+        /* arg to NET_Sendto () null in this case */
+        len = 0;
+        rmtaddrP = 0;
+    } else {
+        packetPort = (*env)->GetIntField(env, packet, dp_portID);
+        if (NET_InetAddressToSockaddr(env, packetAddress, packetPort, (struct sockaddr *)&rmtaddr, &len, JNI_TRUE) != 0) {
+          return;
+        }
+    }
+    setDefaultScopeID(env, (struct sockaddr *)&rmtaddr);
+
+    if (packetBufferLen > MAX_BUFFER_LEN) {
+        /* When JNI-ifying the JDK's IO routines, we turned
+         * read's and write's of byte arrays of size greater
+         * than 2048 bytes into several operations of size 2048.
+         * This saves a malloc()/memcpy()/free() for big
+         * buffers.  This is OK for file IO and TCP, but that
+         * strategy violates the semantics of a datagram protocol.
+         * (one big send) != (several smaller sends).  So here
+         * we *must* alloc the buffer.  Note it needn't be bigger
+         * than 65,536 (0xFFFF) the max size of an IP packet.
+         * Anything bigger should be truncated anyway.
+         *
+         * We may want to use a smarter allocation scheme at some
+         * point.
+         */
+        if (packetBufferLen > MAX_PACKET_LEN) {
+            packetBufferLen = MAX_PACKET_LEN;
+        }
+        fullPacket = (char *)malloc(packetBufferLen);
+
+        if (!fullPacket) {
+            JNU_ThrowOutOfMemoryError(env, "Send buffer native heap allocation failed");
+            return;
+        } else {
+            mallocedPacket = JNI_TRUE;
+        }
+    } else {
+        fullPacket = &(BUF[0]);
+    }
+
+    (*env)->GetByteArrayRegion(env, packetBuffer, packetBufferOffset, packetBufferLen,
+                               (jbyte *)fullPacket);
+#ifdef AF_INET6
+    if (trafficClass != 0 && ipv6_available()) {
+        NET_SetTrafficClass((struct sockaddr *)&rmtaddr, trafficClass);
+    }
+#endif /* AF_INET6 */
+
+
+    /*
+     * Send the datagram.
+     *
+     * If we are connected it's possible that sendto will return
+     * ECONNREFUSED indicating that an ICMP port unreachable has
+     * received.
+     */
+    ret = NET_SendTo(fd, fullPacket, packetBufferLen, 0,
+                     (struct sockaddr *)rmtaddrP, len);
+
+    if (ret < 0) {
+        switch (ret) {
+            case JVM_IO_ERR :
+                if (errno == ECONNREFUSED) {
+                    JNU_ThrowByName(env, JNU_JAVANETPKG "PortUnreachableException",
+                            "ICMP Port Unreachable");
+                } else {
+                    NET_ThrowByNameWithLastError(env, "java/io/IOException", "sendto failed");
+                }
+                break;
+
+            case JVM_IO_INTR:
+                JNU_ThrowByName(env, "java/io/InterruptedIOException",
+                                "operation interrupted");
+                break;
+        }
+    }
+
+    if (mallocedPacket) {
+        free(fullPacket);
+    }
+    return;
+}
+
+/*
+ * Class:     java_net_PlainDatagramSocketImpl
+ * Method:    peek
+ * Signature: (Ljava/net/InetAddress;)I
+ */
+JNIEXPORT jint JNICALL
+Java_java_net_PlainDatagramSocketImpl_peek(JNIEnv *env, jobject this,
+                                           jobject addressObj) {
+
+    jobject fdObj = (*env)->GetObjectField(env, this, pdsi_fdID);
+    jint timeout = (*env)->GetIntField(env, this, pdsi_timeoutID);
+    jint fd;
+    ssize_t n;
+    SOCKADDR remote_addr;
+    int len;
+    char buf[1];
+    jint family;
+    jobject iaObj;
+    int port;
+    if (IS_NULL(fdObj)) {
+        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Socket closed");
+        return -1;
+    } else {
+        fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
+    }
+    if (IS_NULL(addressObj)) {
+        JNU_ThrowNullPointerException(env, "Null address in peek()");
+    }
+    if (timeout) {
+        int ret = NET_Timeout(fd, timeout);
+        if (ret == 0) {
+            JNU_ThrowByName(env, JNU_JAVANETPKG "SocketTimeoutException",
+                            "Peek timed out");
+            return ret;
+        } else if (ret == JVM_IO_ERR) {
+            if (errno == EBADF) {
+                 JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Socket closed");
+            } else {
+                 NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "Peek failed");
+            }
+            return ret;
+        } else if (ret == JVM_IO_INTR) {
+            JNU_ThrowByName(env, JNU_JAVAIOPKG "InterruptedIOException",
+                            "operation interrupted");
+            return ret; /* WARNING: SHOULD WE REALLY RETURN -2??? */
+        }
+    }
+
+    len = SOCKADDR_LEN;
+    n = NET_RecvFrom(fd, buf, 1, MSG_PEEK,
+                     (struct sockaddr *)&remote_addr, &len);
+
+    if (n == JVM_IO_ERR) {
+
+#ifdef __solaris__
+        if (errno == ECONNREFUSED) {
+            int orig_errno = errno;
+            (void) recv(fd, buf, 1, 0);
+            errno = orig_errno;
+        }
+#endif
+        if (errno == ECONNREFUSED) {
+            JNU_ThrowByName(env, JNU_JAVANETPKG "PortUnreachableException",
+                            "ICMP Port Unreachable");
+        } else {
+            if (errno == EBADF) {
+                 JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Socket closed");
+            } else {
+                 NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "Peek failed");
+            }
+        }
+        return 0;
+    } else if (n == JVM_IO_INTR) {
+        JNU_ThrowByName(env, "java/io/InterruptedIOException", 0);
+        return 0;
+    }
+
+    iaObj = NET_SockaddrToInetAddress(env, (struct sockaddr *)&remote_addr, &port);
+#ifdef AF_INET6
+    family = getInetAddress_family(env, iaObj) == IPv4? AF_INET : AF_INET6;
+#else
+    family = AF_INET;
+#endif
+    if (family == AF_INET) { /* this api can't handle IPV6 addresses */
+        int address = getInetAddress_addr(env, iaObj);
+        setInetAddress_addr(env, addressObj, address);
+    }
+    return port;
+}
+
+JNIEXPORT jint JNICALL
+Java_java_net_PlainDatagramSocketImpl_peekData(JNIEnv *env, jobject this,
+                                           jobject packet) {
+
+    char BUF[MAX_BUFFER_LEN];
+    char *fullPacket = NULL;
+    int mallocedPacket = JNI_FALSE;
+    jobject fdObj = (*env)->GetObjectField(env, this, pdsi_fdID);
+    jint timeout = (*env)->GetIntField(env, this, pdsi_timeoutID);
+
+    jbyteArray packetBuffer;
+    jint packetBufferOffset, packetBufferLen;
+
+    int fd;
+
+    int n;
+    SOCKADDR remote_addr;
+    int len;
+    int port;
+
+    if (IS_NULL(fdObj)) {
+        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
+                        "Socket closed");
+        return -1;
+    }
+
+    fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
+
+    if (IS_NULL(packet)) {
+        JNU_ThrowNullPointerException(env, "packet");
+        return -1;
+    }
+
+    packetBuffer = (*env)->GetObjectField(env, packet, dp_bufID);
+    if (IS_NULL(packetBuffer)) {
+        JNU_ThrowNullPointerException(env, "packet buffer");
+        return -1;
+    }
+    packetBufferOffset = (*env)->GetIntField(env, packet, dp_offsetID);
+    packetBufferLen = (*env)->GetIntField(env, packet, dp_bufLengthID);
+    if (timeout) {
+        int ret = NET_Timeout(fd, timeout);
+        if (ret == 0) {
+            JNU_ThrowByName(env, JNU_JAVANETPKG "SocketTimeoutException",
+                            "Receive timed out");
+            return -1;
+        } else if (ret == JVM_IO_ERR) {
+#ifdef __linux__
+            if (errno == EBADF) {
+                JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Socket closed");
+            } else {
+                NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "Receive failed");
+            }
+#else
+            JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Socket closed");
+#endif
+            return -1;
+        } else if (ret == JVM_IO_INTR) {
+            JNU_ThrowByName(env, JNU_JAVAIOPKG "InterruptedIOException",
+                            "operation interrupted");
+            return -1;
+        }
+    }
+
+    if (packetBufferLen > MAX_BUFFER_LEN) {
+
+        /* When JNI-ifying the JDK's IO routines, we turned
+         * read's and write's of byte arrays of size greater
+         * than 2048 bytes into several operations of size 2048.
+         * This saves a malloc()/memcpy()/free() for big
+         * buffers.  This is OK for file IO and TCP, but that
+         * strategy violates the semantics of a datagram protocol.
+         * (one big send) != (several smaller sends).  So here
+         * we *must* alloc the buffer.  Note it needn't be bigger
+         * than 65,536 (0xFFFF) the max size of an IP packet.
+         * anything bigger is truncated anyway.
+         *
+         * We may want to use a smarter allocation scheme at some
+         * point.
+         */
+        if (packetBufferLen > MAX_PACKET_LEN) {
+            packetBufferLen = MAX_PACKET_LEN;
+        }
+        fullPacket = (char *)malloc(packetBufferLen);
+
+        if (!fullPacket) {
+            JNU_ThrowOutOfMemoryError(env, "Peek buffer native heap allocation failed");
+            return -1;
+        } else {
+            mallocedPacket = JNI_TRUE;
+        }
+    } else {
+        fullPacket = &(BUF[0]);
+    }
+
+    len = SOCKADDR_LEN;
+    n = NET_RecvFrom(fd, fullPacket, packetBufferLen, MSG_PEEK,
+                     (struct sockaddr *)&remote_addr, &len);
+    /* truncate the data if the packet's length is too small */
+    if (n > packetBufferLen) {
+        n = packetBufferLen;
+    }
+    if (n == JVM_IO_ERR) {
+
+#ifdef __solaris__
+        if (errno == ECONNREFUSED) {
+            int orig_errno = errno;
+            (void) recv(fd, fullPacket, 1, 0);
+            errno = orig_errno;
+        }
+#endif
+        (*env)->SetIntField(env, packet, dp_offsetID, 0);
+        (*env)->SetIntField(env, packet, dp_lengthID, 0);
+        if (errno == ECONNREFUSED) {
+            JNU_ThrowByName(env, JNU_JAVANETPKG "PortUnreachableException",
+                            "ICMP Port Unreachable");
+        } else {
+            if (errno == EBADF) {
+                 JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Socket closed");
+            } else {
+                 NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "Receive failed");
+            }
+        }
+    } else if (n == JVM_IO_INTR) {
+        (*env)->SetIntField(env, packet, dp_offsetID, 0);
+        (*env)->SetIntField(env, packet, dp_lengthID, 0);
+        JNU_ThrowByName(env, JNU_JAVAIOPKG "InterruptedIOException",
+                        "operation interrupted");
+    } else {
+        /*
+         * success - fill in received address...
+         *
+         * REMIND: Fill in an int on the packet, and create inetadd
+         * object in Java, as a performance improvement. Also
+         * construct the inetadd object lazily.
+         */
+
+        jobject packetAddress;
+
+        /*
+         * Check if there is an InetAddress already associated with this
+         * packet. If so we check if it is the same source address. We
+         * can't update any existing InetAddress because it is immutable
+         */
+        packetAddress = (*env)->GetObjectField(env, packet, dp_addressID);
+        if (packetAddress != NULL) {
+            if (!NET_SockaddrEqualsInetAddress(env, (struct sockaddr *)&remote_addr, packetAddress)) {
+                /* force a new InetAddress to be created */
+                packetAddress = NULL;
+            }
+        }
+        if (packetAddress == NULL) {
+            packetAddress = NET_SockaddrToInetAddress(env, (struct sockaddr *)&remote_addr, &port);
+            /* stuff the new Inetaddress in the packet */
+            (*env)->SetObjectField(env, packet, dp_addressID, packetAddress);
+        } else {
+            /* only get the new port number */
+            port = NET_GetPortFromSockaddr((struct sockaddr *)&remote_addr);
+        }
+        /* and fill in the data, remote address/port and such */
+        (*env)->SetByteArrayRegion(env, packetBuffer, packetBufferOffset, n,
+                                   (jbyte *)fullPacket);
+        (*env)->SetIntField(env, packet, dp_portID, port);
+        (*env)->SetIntField(env, packet, dp_lengthID, n);
+    }
+
+    if (mallocedPacket) {
+        free(fullPacket);
+    }
+    return port;
+}
+
+/*
+ * Class:     java_net_PlainDatagramSocketImpl
+ * Method:    receive
+ * Signature: (Ljava/net/DatagramPacket;)V
+ */
+JNIEXPORT void JNICALL
+Java_java_net_PlainDatagramSocketImpl_receive0(JNIEnv *env, jobject this,
+                                              jobject packet) {
+
+    char BUF[MAX_BUFFER_LEN];
+    char *fullPacket = NULL;
+    int mallocedPacket = JNI_FALSE;
+    jobject fdObj = (*env)->GetObjectField(env, this, pdsi_fdID);
+    jint timeout = (*env)->GetIntField(env, this, pdsi_timeoutID);
+
+    jbyteArray packetBuffer;
+    jint packetBufferOffset, packetBufferLen;
+
+    int fd;
+
+    int n;
+    SOCKADDR remote_addr;
+    int len;
+    jboolean retry;
+#ifdef __linux__
+    jboolean connected = JNI_FALSE;
+    jobject connectedAddress = NULL;
+    jint connectedPort = 0;
+    jlong prevTime = 0;
+#endif
+
+    if (IS_NULL(fdObj)) {
+        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
+                        "Socket closed");
+        return;
+    }
+
+    fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
+
+    if (IS_NULL(packet)) {
+        JNU_ThrowNullPointerException(env, "packet");
+        return;
+    }
+
+    packetBuffer = (*env)->GetObjectField(env, packet, dp_bufID);
+    if (IS_NULL(packetBuffer)) {
+        JNU_ThrowNullPointerException(env, "packet buffer");
+        return;
+    }
+    packetBufferOffset = (*env)->GetIntField(env, packet, dp_offsetID);
+    packetBufferLen = (*env)->GetIntField(env, packet, dp_bufLengthID);
+
+    if (packetBufferLen > MAX_BUFFER_LEN) {
+
+        /* When JNI-ifying the JDK's IO routines, we turned
+         * read's and write's of byte arrays of size greater
+         * than 2048 bytes into several operations of size 2048.
+         * This saves a malloc()/memcpy()/free() for big
+         * buffers.  This is OK for file IO and TCP, but that
+         * strategy violates the semantics of a datagram protocol.
+         * (one big send) != (several smaller sends).  So here
+         * we *must* alloc the buffer.  Note it needn't be bigger
+         * than 65,536 (0xFFFF) the max size of an IP packet.
+         * anything bigger is truncated anyway.
+         *
+         * We may want to use a smarter allocation scheme at some
+         * point.
+         */
+        if (packetBufferLen > MAX_PACKET_LEN) {
+            packetBufferLen = MAX_PACKET_LEN;
+        }
+        fullPacket = (char *)malloc(packetBufferLen);
+
+        if (!fullPacket) {
+            JNU_ThrowOutOfMemoryError(env, "Receive buffer native heap allocation failed");
+            return;
+        } else {
+            mallocedPacket = JNI_TRUE;
+        }
+    } else {
+        fullPacket = &(BUF[0]);
+    }
+
+#ifdef __linux__
+    /*
+     * On Linux with the 2.2 kernel we simulate connected datagrams by
+     * discarding packets
+     */
+    if (isOldKernel) {
+        connected = (*env)->GetBooleanField(env, this, pdsi_connected);
+        if (connected) {
+            connectedAddress = (*env)->GetObjectField(env, this, pdsi_connectedAddress);
+            connectedPort = (*env)->GetIntField(env, this, pdsi_connectedPort);
+
+            if (timeout) {
+                prevTime = JVM_CurrentTimeMillis(env, 0);
+            }
+        }
+    }
+#endif
+
+    do {
+        retry = JNI_FALSE;
+
+        if (timeout) {
+            int ret = NET_Timeout(fd, timeout);
+            if (ret <= 0) {
+                if (ret == 0) {
+                    JNU_ThrowByName(env, JNU_JAVANETPKG "SocketTimeoutException",
+                                    "Receive timed out");
+                } else if (ret == JVM_IO_ERR) {
+#ifdef __linux__
+                    if (errno == EBADF) {
+                         JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Socket closed");
+                     } else {
+                         NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "Receive failed");
+                     }
+#else
+                     JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Socket closed");
+#endif
+                } else if (ret == JVM_IO_INTR) {
+                    JNU_ThrowByName(env, JNU_JAVAIOPKG "InterruptedIOException",
+                                    "operation interrupted");
+                }
+
+                if (mallocedPacket) {
+                    free(fullPacket);
+                }
+
+                return;
+            }
+        }
+
+        /*
+         * Security Note: For Linux 2.2 with connected datagrams ensure that
+         * you receive into the stack/heap allocated buffer - do not attempt
+         * to receive directly into DatagramPacket's byte array.
+         * (ie: if the virtual machine support pinning don't use
+         * GetByteArrayElements or a JNI critical section and receive
+         * directly into the byte array)
+         */
+        len = SOCKADDR_LEN;
+        n = NET_RecvFrom(fd, fullPacket, packetBufferLen, 0,
+                         (struct sockaddr *)&remote_addr, &len);
+        /* truncate the data if the packet's length is too small */
+        if (n > packetBufferLen) {
+            n = packetBufferLen;
+        }
+        if (n == JVM_IO_ERR) {
+            (*env)->SetIntField(env, packet, dp_offsetID, 0);
+            (*env)->SetIntField(env, packet, dp_lengthID, 0);
+            if (errno == ECONNREFUSED) {
+                JNU_ThrowByName(env, JNU_JAVANETPKG "PortUnreachableException",
+                                "ICMP Port Unreachable");
+            } else {
+                if (errno == EBADF) {
+                     JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Socket closed");
+                 } else {
+                     NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "Receive failed");
+                 }
+            }
+        } else if (n == JVM_IO_INTR) {
+            (*env)->SetIntField(env, packet, dp_offsetID, 0);
+            (*env)->SetIntField(env, packet, dp_lengthID, 0);
+            JNU_ThrowByName(env, JNU_JAVAIOPKG "InterruptedIOException",
+                            "operation interrupted");
+        } else {
+            int port;
+            jobject packetAddress;
+
+            /*
+             * If we are connected then we know that the datagram that we have
+             * received is from the address that we are connected too. However
+             * on Linux with 2.2 kernel we have to simulate this behaviour by
+             * discarding any datagrams that aren't from the connected address.
+             */
+#ifdef __linux__
+            if (isOldKernel && connected) {
+
+                if (NET_GetPortFromSockaddr((struct sockaddr *)&remote_addr) != connectedPort ||
+                    !NET_SockaddrEqualsInetAddress(env, (struct sockaddr *)&remote_addr, connectedAddress)) {
+
+                    /*
+                     * Discard the datagram as it's not from the connected
+                     * address
+                     */
+                    retry = JNI_TRUE;
+
+                    /*
+                     * Adjust timeout if necessary to ensure that we adhere to
+                     * timeout semantics.
+                     */
+                    if (timeout) {
+                        jlong newTime = JVM_CurrentTimeMillis(env, 0);
+                        timeout -= (newTime - prevTime);
+                        if (timeout <= 0) {
+                            JNU_ThrowByName(env, JNU_JAVANETPKG "SocketTimeoutException",
+                                    "Receive timed out");
+                            if (mallocedPacket) {
+                                free(fullPacket);
+                            }
+                            return;
+                        }
+                        prevTime = newTime;
+                    }
+
+                    continue;
+                }
+            }
+#endif
+
+            /*
+             * success - fill in received address...
+             *
+             * REMIND: Fill in an int on the packet, and create inetadd
+             * object in Java, as a performance improvement. Also
+             * construct the inetadd object lazily.
+             */
+
+            /*
+             * Check if there is an InetAddress already associated with this
+             * packet. If so we check if it is the same source address. We
+             * can't update any existing InetAddress because it is immutable
+             */
+            packetAddress = (*env)->GetObjectField(env, packet, dp_addressID);
+            if (packetAddress != NULL) {
+                if (!NET_SockaddrEqualsInetAddress(env, (struct sockaddr *)&remote_addr, packetAddress)) {
+                    /* force a new InetAddress to be created */
+                    packetAddress = NULL;
+                }
+            }
+            if (packetAddress == NULL) {
+                packetAddress = NET_SockaddrToInetAddress(env, (struct sockaddr *)&remote_addr, &port);
+                /* stuff the new Inetaddress in the packet */
+                (*env)->SetObjectField(env, packet, dp_addressID, packetAddress);
+            } else {
+                /* only get the new port number */
+                port = NET_GetPortFromSockaddr((struct sockaddr *)&remote_addr);
+            }
+            /* and fill in the data, remote address/port and such */
+            (*env)->SetByteArrayRegion(env, packetBuffer, packetBufferOffset, n,
+                                       (jbyte *)fullPacket);
+            (*env)->SetIntField(env, packet, dp_portID, port);
+            (*env)->SetIntField(env, packet, dp_lengthID, n);
+        }
+
+    } while (retry);
+
+    if (mallocedPacket) {
+        free(fullPacket);
+    }
+}
+
+/*
+ * Class:     java_net_PlainDatagramSocketImpl
+ * Method:    datagramSocketCreate
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL
+Java_java_net_PlainDatagramSocketImpl_datagramSocketCreate(JNIEnv *env,
+                                                           jobject this) {
+    jobject fdObj = (*env)->GetObjectField(env, this, pdsi_fdID);
+    int arg, fd, t = 1;
+#ifdef AF_INET6
+    int domain = ipv6_available() ? AF_INET6 : AF_INET;
+#else
+    int domain = AF_INET;
+#endif
+
+    if (IS_NULL(fdObj)) {
+        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
+                        "Socket closed");
+        return;
+    }
+
+    if ((fd = JVM_Socket(domain, SOCK_DGRAM, 0)) == JVM_IO_ERR) {
+        NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
+                       "Error creating socket");
+        return;
+    }
+
+#ifdef AF_INET6
+    /* Disable IPV6_V6ONLY to ensure dual-socket support */
+    if (domain == AF_INET6) {
+        arg = 0;
+        if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&arg,
+                       sizeof(int)) < 0) {
+            NET_ThrowNew(env, errno, "cannot set IPPROTO_IPV6");
+            close(fd);
+            return;
+        }
+    }
+#endif /* AF_INET6 */
+
+#ifdef __APPLE__
+    arg = 65507;
+    if (JVM_SetSockOpt(fd, SOL_SOCKET, SO_SNDBUF,
+                       (char *)&arg, sizeof(arg)) < 0) {
+        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
+                        strerror(errno));
+        return;
+    }
+    if (JVM_SetSockOpt(fd, SOL_SOCKET, SO_RCVBUF,
+                       (char *)&arg, sizeof(arg)) < 0) {
+        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
+                        strerror(errno));
+        return;
+    }
+#endif /* __APPLE__ */
+
+     setsockopt(fd, SOL_SOCKET, SO_BROADCAST, (char*) &t, sizeof(int));
+
+#ifdef __linux__
+    if (isOldKernel) {
+        setsockopt(fd, SOL_SOCKET, SO_BSDCOMPAT, (char*) &t, sizeof(int));
+    }
+
+#ifdef AF_INET6
+    /*
+     * On Linux for IPv6 sockets we must set the hop limit
+     * to 1 to be compatible with default ttl of 1 for IPv4 sockets.
+     */
+    if (domain == AF_INET6) {
+        int ttl = 1;
+        setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, (char *)&ttl,
+                   sizeof(ttl));
+
+        if (isOldKernel) {
+            (*env)->SetIntField(env, this, pdsi_ttlID, ttl);
+        }
+    }
+#endif
+
+#endif /* __linux__ */
+
+    (*env)->SetIntField(env, fdObj, IO_fd_fdID, fd);
+}
+
+/*
+ * Class:     java_net_PlainDatagramSocketImpl
+ * Method:    datagramSocketClose
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL
+Java_java_net_PlainDatagramSocketImpl_datagramSocketClose(JNIEnv *env,
+                                                          jobject this) {
+    /*
+     * REMIND: PUT A LOCK AROUND THIS CODE
+     */
+    jobject fdObj = (*env)->GetObjectField(env, this, pdsi_fdID);
+    int fd;
+
+    if (IS_NULL(fdObj)) {
+        return;
+    }
+    fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
+    if (fd == -1) {
+        return;
+    }
+    (*env)->SetIntField(env, fdObj, IO_fd_fdID, -1);
+    NET_SocketClose(fd);
+}
+
+
+/*
+ * Set outgoing multicast interface designated by a NetworkInterface.
+ * Throw exception if failed.
+ */
+static void mcast_set_if_by_if_v4(JNIEnv *env, jobject this, int fd, jobject value) {
+    static jfieldID ni_addrsID;
+    struct in_addr in;
+    jobjectArray addrArray;
+    jsize len;
+    jobject addr;
+    int i;
+
+    if (ni_addrsID == NULL ) {
+        jclass c = (*env)->FindClass(env, "java/net/NetworkInterface");
+        CHECK_NULL(c);
+        ni_addrsID = (*env)->GetFieldID(env, c, "addrs",
+                                        "[Ljava/net/InetAddress;");
+        CHECK_NULL(ni_addrsID);
+    }
+
+    addrArray = (*env)->GetObjectField(env, value, ni_addrsID);
+    len = (*env)->GetArrayLength(env, addrArray);
+
+    /*
+     * Check that there is at least one address bound to this
+     * interface.
+     */
+    if (len < 1) {
+        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
+            "bad argument for IP_MULTICAST_IF2: No IP addresses bound to interface");
+        return;
+    }
+
+    /*
+     * We need an ipv4 address here
+     */
+    for (i = 0; i < len; i++) {
+        addr = (*env)->GetObjectArrayElement(env, addrArray, i);
+        if (getInetAddress_family(env, addr) == IPv4) {
+            in.s_addr = htonl(getInetAddress_addr(env, addr));
+            break;
+        }
+    }
+
+    if (JVM_SetSockOpt(fd, IPPROTO_IP, IP_MULTICAST_IF,
+                       (const char*)&in, sizeof(in)) < 0) {
+        NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
+                       "Error setting socket option");
+    }
+}
+
+/*
+ * Set outgoing multicast interface designated by a NetworkInterface.
+ * Throw exception if failed.
+ */
+#ifdef AF_INET6
+static void mcast_set_if_by_if_v6(JNIEnv *env, jobject this, int fd, jobject value) {
+    static jfieldID ni_indexID;
+    int index;
+
+    if (ni_indexID == NULL) {
+        jclass c = (*env)->FindClass(env, "java/net/NetworkInterface");
+        CHECK_NULL(c);
+        ni_indexID = (*env)->GetFieldID(env, c, "index", "I");
+        CHECK_NULL(ni_indexID);
+    }
+    index = (*env)->GetIntField(env, value, ni_indexID);
+
+    if (JVM_SetSockOpt(fd, IPPROTO_IPV6, IPV6_MULTICAST_IF,
+                       (const char*)&index, sizeof(index)) < 0) {
+        if (errno == EINVAL && index > 0) {
+            JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
+                "IPV6_MULTICAST_IF failed (interface has IPv4 "
+                "address only?)");
+        } else {
+            NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
+                           "Error setting socket option");
+        }
+        return;
+    }
+
+#ifdef __linux__
+    /*
+     * Linux 2.2 kernel doesn't support IPV6_MULTICAST_IF socket
+     * option so record index for later retrival.
+     */
+    if (isOldKernel) {
+        (*env)->SetIntField(env, this, pdsi_multicastInterfaceID,
+                            (jint)index);
+    }
+#endif
+}
+#endif /* AF_INET6 */
+
+/*
+ * Set outgoing multicast interface designated by an InetAddress.
+ * Throw exception if failed.
+ */
+static void mcast_set_if_by_addr_v4(JNIEnv *env, jobject this, int fd, jobject value) {
+    struct in_addr in;
+
+    in.s_addr = htonl( getInetAddress_addr(env, value) );
+
+    if (JVM_SetSockOpt(fd, IPPROTO_IP, IP_MULTICAST_IF,
+                       (const char*)&in, sizeof(in)) < 0) {
+        NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
+                         "Error setting socket option");
+    }
+}
+
+/*
+ * Set outgoing multicast interface designated by an InetAddress.
+ * Throw exception if failed.
+ */
+#ifdef AF_INET6
+static void mcast_set_if_by_addr_v6(JNIEnv *env, jobject this, int fd, jobject value) {
+    static jclass ni_class;
+    if (ni_class == NULL) {
+        jclass c = (*env)->FindClass(env, "java/net/NetworkInterface");
+        CHECK_NULL(c);
+        ni_class = (*env)->NewGlobalRef(env, c);
+        CHECK_NULL(ni_class);
+    }
+
+    value = Java_java_net_NetworkInterface_getByInetAddress0(env, ni_class, value);
+    if (value == NULL) {
+        if (!(*env)->ExceptionOccurred(env)) {
+            JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
+                 "bad argument for IP_MULTICAST_IF"
+                 ": address not bound to any interface");
+        }
+        return;
+    }
+
+    mcast_set_if_by_if_v6(env, this, fd, value);
+}
+#endif
+
+/*
+ * Sets the multicast interface.
+ *
+ * SocketOptions.IP_MULTICAST_IF :-
+ *      value is a InetAddress
+ *      IPv4:   set outgoing multicast interface using
+ *              IPPROTO_IP/IP_MULTICAST_IF
+ *      IPv6:   Get the index of the interface to which the
+ *              InetAddress is bound
+ *              Set outgoing multicast interface using
+ *              IPPROTO_IPV6/IPV6_MULTICAST_IF
+ *              On Linux 2.2 record interface index as can't
+ *              query the multicast interface.
+ *
+ * SockOptions.IF_MULTICAST_IF2 :-
+ *      value is a NetworkInterface
+ *      IPv4:   Obtain IP address bound to network interface
+ *              (NetworkInterface.addres[0])
+ *              set outgoing multicast interface using
+ *              IPPROTO_IP/IP_MULTICAST_IF
+ *      IPv6:   Obtain NetworkInterface.index
+ *              Set outgoing multicast interface using
+ *              IPPROTO_IPV6/IPV6_MULTICAST_IF
+ *              On Linux 2.2 record interface index as can't
+ *              query the multicast interface.
+ *
+ */
+static void setMulticastInterface(JNIEnv *env, jobject this, int fd,
+                                  jint opt, jobject value)
+{
+    if (opt == java_net_SocketOptions_IP_MULTICAST_IF) {
+        /*
+         * value is an InetAddress.
+         */
+#ifdef AF_INET6
+#ifdef __linux__
+        mcast_set_if_by_addr_v4(env, this, fd, value);
+        if (ipv6_available()) {
+            mcast_set_if_by_addr_v6(env, this, fd, value);
+        }
+#else  /* __linux__ not defined */
+        if (ipv6_available()) {
+            mcast_set_if_by_addr_v6(env, this, fd, value);
+        } else {
+            mcast_set_if_by_addr_v4(env, this, fd, value);
+        }
+#endif  /* __linux__ */
+#else
+        mcast_set_if_by_addr_v4(env, this, fd, value);
+#endif  /* AF_INET6 */
+    }
+
+    if (opt == java_net_SocketOptions_IP_MULTICAST_IF2) {
+        /*
+         * value is a NetworkInterface.
+         */
+#ifdef AF_INET6
+#ifdef __linux__
+        mcast_set_if_by_if_v4(env, this, fd, value);
+        if (ipv6_available()) {
+            mcast_set_if_by_if_v6(env, this, fd, value);
+        }
+#else  /* __linux__ not defined */
+        if (ipv6_available()) {
+            mcast_set_if_by_if_v6(env, this, fd, value);
+        } else {
+            mcast_set_if_by_if_v4(env, this, fd, value);
+        }
+#endif  /* __linux__ */
+#else
+        mcast_set_if_by_if_v4(env, this, fd, value);
+#endif  /* AF_INET6 */
+    }
+}
+
+/*
+ * Enable/disable local loopback of multicast datagrams.
+ */
+static void mcast_set_loop_v4(JNIEnv *env, jobject this, int fd, jobject value) {
+    jclass cls;
+    jfieldID fid;
+    jboolean on;
+    char loopback;
+
+    cls = (*env)->FindClass(env, "java/lang/Boolean");
+    CHECK_NULL(cls);
+    fid =  (*env)->GetFieldID(env, cls, "value", "Z");
+    CHECK_NULL(fid);
+
+    on = (*env)->GetBooleanField(env, value, fid);
+    loopback = (!on ? 1 : 0);
+
+    if (NET_SetSockOpt(fd, IPPROTO_IP, IP_MULTICAST_LOOP, (const void *)&loopback, sizeof(char)) < 0) {
+        NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "Error setting socket option");
+        return;
+    }
+}
+
+/*
+ * Enable/disable local loopback of multicast datagrams.
+ */
+#ifdef AF_INET6
+static void mcast_set_loop_v6(JNIEnv *env, jobject this, int fd, jobject value) {
+    jclass cls;
+    jfieldID fid;
+    jboolean on;
+    int loopback;
+
+    cls = (*env)->FindClass(env, "java/lang/Boolean");
+    CHECK_NULL(cls);
+    fid =  (*env)->GetFieldID(env, cls, "value", "Z");
+    CHECK_NULL(fid);
+
+    on = (*env)->GetBooleanField(env, value, fid);
+    loopback = (!on ? 1 : 0);
+
+    if (NET_SetSockOpt(fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, (const void *)&loopback, sizeof(int)) < 0) {
+        NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "Error setting socket option");
+        return;
+    }
+
+#ifdef __linux__
+    /*
+     * Can't query IPV6_MULTICAST_LOOP on Linux 2.2 kernel so
+     * store it in impl so that we can simulate getsockopt.
+     */
+    if (isOldKernel) {
+        (*env)->SetBooleanField(env, this, pdsi_loopbackID, on);
+    }
+#endif
+}
+#endif  /* AF_INET6 */
+
+/*
+ * Sets the multicast loopback mode.
+ */
+static void setMulticastLoopbackMode(JNIEnv *env, jobject this, int fd,
+                                  jint opt, jobject value) {
+#ifdef AF_INET6
+#ifdef __linux__
+    mcast_set_loop_v4(env, this, fd, value);
+    if (ipv6_available()) {
+        mcast_set_loop_v6(env, this, fd, value);
+    }
+#else  /* __linux__ not defined */
+    if (ipv6_available()) {
+        mcast_set_loop_v6(env, this, fd, value);
+    } else {
+        mcast_set_loop_v4(env, this, fd, value);
+    }
+#endif  /* __linux__ */
+#else
+    mcast_set_loop_v4(env, this, fd, value);
+#endif  /* AF_INET6 */
+}
+
+/*
+ * Class:     java_net_PlainDatagramSocketImpl
+ * Method:    socketSetOption
+ * Signature: (ILjava/lang/Object;)V
+ */
+JNIEXPORT void JNICALL
+Java_java_net_PlainDatagramSocketImpl_socketSetOption(JNIEnv *env,
+                                                      jobject this,
+                                                      jint opt,
+                                                      jobject value) {
+    int fd;
+    int level, optname, optlen;
+    union {
+        int i;
+        char c;
+    } optval;
+
+    /*
+     * Check that socket hasn't been closed
+     */
+    fd = getFD(env, this);
+    if (fd < 0) {
+        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
+                        "Socket closed");
+        return;
+    }
+
+    /*
+     * Check argument has been provided
+     */
+    if (IS_NULL(value)) {
+        JNU_ThrowNullPointerException(env, "value argument");
+        return;
+    }
+
+    /*
+     * Setting the multicast interface handled seperately
+     */
+    if (opt == java_net_SocketOptions_IP_MULTICAST_IF ||
+        opt == java_net_SocketOptions_IP_MULTICAST_IF2) {
+
+        setMulticastInterface(env, this, fd, opt, value);
+        return;
+    }
+
+    /*
+     * Setting the multicast loopback mode handled separately
+     */
+    if (opt == java_net_SocketOptions_IP_MULTICAST_LOOP) {
+        setMulticastLoopbackMode(env, this, fd, opt, value);
+        return;
+    }
+
+    /*
+     * Map the Java level socket option to the platform specific
+     * level and option name.
+     */
+    if (NET_MapSocketOption(opt, &level, &optname)) {
+        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Invalid option");
+        return;
+    }
+
+    switch (opt) {
+        case java_net_SocketOptions_SO_SNDBUF :
+        case java_net_SocketOptions_SO_RCVBUF :
+        case java_net_SocketOptions_IP_TOS :
+            {
+                jclass cls;
+                jfieldID fid;
+
+                cls = (*env)->FindClass(env, "java/lang/Integer");
+                CHECK_NULL(cls);
+                fid =  (*env)->GetFieldID(env, cls, "value", "I");
+                CHECK_NULL(fid);
+
+                optval.i = (*env)->GetIntField(env, value, fid);
+                optlen = sizeof(optval.i);
+                break;
+            }
+
+        case java_net_SocketOptions_SO_REUSEADDR:
+        case java_net_SocketOptions_SO_BROADCAST:
+            {
+                jclass cls;
+                jfieldID fid;
+                jboolean on;
+
+                cls = (*env)->FindClass(env, "java/lang/Boolean");
+                CHECK_NULL(cls);
+                fid =  (*env)->GetFieldID(env, cls, "value", "Z");
+                CHECK_NULL(fid);
+
+                on = (*env)->GetBooleanField(env, value, fid);
+
+                /* SO_REUSEADDR or SO_BROADCAST */
+                optval.i = (on ? 1 : 0);
+                optlen = sizeof(optval.i);
+
+                break;
+            }
+
+        default :
+            JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
+                "Socket option not supported by PlainDatagramSocketImp");
+            break;
+
+    }
+
+    if (NET_SetSockOpt(fd, level, optname, (const void *)&optval, optlen) < 0) {
+        NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "Error setting socket option");
+        return;
+    }
+}
+
+
+/*
+ * Return the multicast interface:
+ *
+ * SocketOptions.IP_MULTICAST_IF
+ *      IPv4:   Query IPPROTO_IP/IP_MULTICAST_IF
+ *              Create InetAddress
+ *              IP_MULTICAST_IF returns struct ip_mreqn on 2.2
+ *              kernel but struct in_addr on 2.4 kernel
+ *      IPv6:   Query IPPROTO_IPV6 / IPV6_MULTICAST_IF or
+ *              obtain from impl is Linux 2.2 kernel
+ *              If index == 0 return InetAddress representing
+ *              anyLocalAddress.
+ *              If index > 0 query NetworkInterface by index
+ *              and returns addrs[0]
+ *
+ * SocketOptions.IP_MULTICAST_IF2
+ *      IPv4:   Query IPPROTO_IP/IP_MULTICAST_IF
+ *              Query NetworkInterface by IP address and
+ *              return the NetworkInterface that the address
+ *              is bound too.
+ *      IPv6:   Query IPPROTO_IPV6 / IPV6_MULTICAST_IF
+ *              (except Linux .2 kernel)
+ *              Query NetworkInterface by index and
+ *              return NetworkInterface.
+ */
+jobject getMulticastInterface(JNIEnv *env, jobject this, int fd, jint opt) {
+    jboolean isIPV4 = JNI_TRUE;
+
+#ifdef AF_INET6
+    if (ipv6_available()) {
+        isIPV4 = JNI_FALSE;
+    }
+#endif
+
+    /*
+     * IPv4 implementation
+     */
+    if (isIPV4) {
+        static jclass inet4_class;
+        static jmethodID inet4_ctrID;
+
+        static jclass ni_class;
+        static jmethodID ni_ctrID;
+        static jfieldID ni_indexID;
+        static jfieldID ni_addrsID;
+
+        jobjectArray addrArray;
+        jobject addr;
+        jobject ni;
+
+        struct in_addr in;
+        struct in_addr *inP = &in;
+        int len = sizeof(struct in_addr);
+
+#ifdef __linux__
+        struct ip_mreqn mreqn;
+        if (isOldKernel) {
+            inP = (struct in_addr *)&mreqn;
+            len = sizeof(struct ip_mreqn);
+        }
+#endif
+
+        if (JVM_GetSockOpt(fd, IPPROTO_IP, IP_MULTICAST_IF,
+                           (char *)inP, &len) < 0) {
+            NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
+                             "Error getting socket option");
+            return NULL;
+        }
+
+        /*
+         * Construct and populate an Inet4Address
+         */
+        if (inet4_class == NULL) {
+            jclass c = (*env)->FindClass(env, "java/net/Inet4Address");
+            CHECK_NULL_RETURN(c, NULL);
+            inet4_ctrID = (*env)->GetMethodID(env, c, "<init>", "()V");
+            CHECK_NULL_RETURN(inet4_ctrID, NULL);
+            inet4_class = (*env)->NewGlobalRef(env, c);
+            CHECK_NULL_RETURN(inet4_class, NULL);
+        }
+        addr = (*env)->NewObject(env, inet4_class, inet4_ctrID, 0);
+        CHECK_NULL_RETURN(addr, NULL);
+
+#ifdef __linux__
+        setInetAddress_addr(env, addr, (isOldKernel ?
+                ntohl(mreqn.imr_address.s_addr) : ntohl(in.s_addr)));
+#else
+        setInetAddress_addr(env, addr, ntohl(in.s_addr));
+#endif
+
+        /*
+         * For IP_MULTICAST_IF return InetAddress
+         */
+        if (opt == java_net_SocketOptions_IP_MULTICAST_IF) {
+            return addr;
+        }
+
+        /*
+         * For IP_MULTICAST_IF2 we get the NetworkInterface for
+         * this address and return it
+         */
+        if (ni_class == NULL) {
+            jclass c = (*env)->FindClass(env, "java/net/NetworkInterface");
+            CHECK_NULL_RETURN(c, NULL);
+            ni_ctrID = (*env)->GetMethodID(env, c, "<init>", "()V");
+            CHECK_NULL_RETURN(ni_ctrID, NULL);
+            ni_indexID = (*env)->GetFieldID(env, c, "index", "I");
+            CHECK_NULL_RETURN(ni_indexID, NULL);
+            ni_addrsID = (*env)->GetFieldID(env, c, "addrs",
+                                            "[Ljava/net/InetAddress;");
+            CHECK_NULL_RETURN(ni_addrsID, NULL);
+            ni_class = (*env)->NewGlobalRef(env, c);
+            CHECK_NULL_RETURN(ni_class, NULL);
+        }
+        ni = Java_java_net_NetworkInterface_getByInetAddress0(env, ni_class, addr);
+        if (ni) {
+            return ni;
+        }
+
+        /*
+         * The address doesn't appear to be bound at any known
+         * NetworkInterface. Therefore we construct a NetworkInterface
+         * with this address.
+         */
+        ni = (*env)->NewObject(env, ni_class, ni_ctrID, 0);
+        CHECK_NULL_RETURN(ni, NULL);
+
+        (*env)->SetIntField(env, ni, ni_indexID, -1);
+        addrArray = (*env)->NewObjectArray(env, 1, inet4_class, NULL);
+        CHECK_NULL_RETURN(addrArray, NULL);
+        (*env)->SetObjectArrayElement(env, addrArray, 0, addr);
+        (*env)->SetObjectField(env, ni, ni_addrsID, addrArray);
+        return ni;
+    }
+
+
+#ifdef AF_INET6
+    /*
+     * IPv6 implementation
+     */
+    if ((opt == java_net_SocketOptions_IP_MULTICAST_IF) ||
+        (opt == java_net_SocketOptions_IP_MULTICAST_IF2)) {
+
+        static jclass ni_class;
+        static jmethodID ni_ctrID;
+        static jfieldID ni_indexID;
+        static jfieldID ni_addrsID;
+        static jclass ia_class;
+        static jmethodID ia_anyLocalAddressID;
+
+        int index;
+        int len = sizeof(index);
+
+        jobjectArray addrArray;
+        jobject addr;
+        jobject ni;
+
+#ifdef __linux__
+        /*
+         * Linux 2.2 kernel doesn't support IPV6_MULTICAST_IF socke option
+         * so use cached index.
+         */
+        if (isOldKernel) {
+            index = (*env)->GetIntField(env, this, pdsi_multicastInterfaceID);
+        } else
+#endif
+        {
+            if (JVM_GetSockOpt(fd, IPPROTO_IPV6, IPV6_MULTICAST_IF,
+                               (char*)&index, &len) < 0) {
+                NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
+                               "Error getting socket option");
+                return NULL;
+            }
+        }
+
+        if (ni_class == NULL) {
+            jclass c = (*env)->FindClass(env, "java/net/NetworkInterface");
+            CHECK_NULL_RETURN(c, NULL);
+            ni_ctrID = (*env)->GetMethodID(env, c, "<init>", "()V");
+            CHECK_NULL_RETURN(ni_ctrID, NULL);
+            ni_indexID = (*env)->GetFieldID(env, c, "index", "I");
+            CHECK_NULL_RETURN(ni_indexID, NULL);
+            ni_addrsID = (*env)->GetFieldID(env, c, "addrs",
+                                            "[Ljava/net/InetAddress;");
+            CHECK_NULL_RETURN(ni_addrsID, NULL);
+
+            ia_class = (*env)->FindClass(env, "java/net/InetAddress");
+            CHECK_NULL_RETURN(ia_class, NULL);
+            ia_class = (*env)->NewGlobalRef(env, ia_class);
+            CHECK_NULL_RETURN(ia_class, NULL);
+            ia_anyLocalAddressID = (*env)->GetStaticMethodID(env,
+                                                             ia_class,
+                                                             "anyLocalAddress",
+                                                             "()Ljava/net/InetAddress;");
+            CHECK_NULL_RETURN(ia_anyLocalAddressID, NULL);
+            ni_class = (*env)->NewGlobalRef(env, c);
+            CHECK_NULL_RETURN(ni_class, NULL);
+        }
+
+        /*
+         * If multicast to a specific interface then return the
+         * interface (for IF2) or the any address on that interface
+         * (for IF).
+         */
+        if (index > 0) {
+            ni = Java_java_net_NetworkInterface_getByIndex0(env, ni_class,
+                                                                   index);
+            if (ni == NULL) {
+                char errmsg[255];
+                sprintf(errmsg,
+                        "IPV6_MULTICAST_IF returned index to unrecognized interface: %d",
+                        index);
+                JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", errmsg);
+                return NULL;
+            }
+
+            /*
+             * For IP_MULTICAST_IF2 return the NetworkInterface
+             */
+            if (opt == java_net_SocketOptions_IP_MULTICAST_IF2) {
+                return ni;
+            }
+
+            /*
+             * For IP_MULTICAST_IF return addrs[0]
+             */
+            addrArray = (*env)->GetObjectField(env, ni, ni_addrsID);
+            if ((*env)->GetArrayLength(env, addrArray) < 1) {
+                JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
+                    "IPV6_MULTICAST_IF returned interface without IP bindings");
+                return NULL;
+            }
+
+            addr = (*env)->GetObjectArrayElement(env, addrArray, 0);
+            return addr;
+        }
+
+        /*
+         * Multicast to any address - return anyLocalAddress
+         * or a NetworkInterface with addrs[0] set to anyLocalAddress
+         */
+
+        addr = (*env)->CallStaticObjectMethod(env, ia_class, ia_anyLocalAddressID,
+                                              NULL);
+        if (opt == java_net_SocketOptions_IP_MULTICAST_IF) {
+            return addr;
+        }
+
+        ni = (*env)->NewObject(env, ni_class, ni_ctrID, 0);
+        CHECK_NULL_RETURN(ni, NULL);
+        (*env)->SetIntField(env, ni, ni_indexID, -1);
+        addrArray = (*env)->NewObjectArray(env, 1, ia_class, NULL);
+        CHECK_NULL_RETURN(addrArray, NULL);
+        (*env)->SetObjectArrayElement(env, addrArray, 0, addr);
+        (*env)->SetObjectField(env, ni, ni_addrsID, addrArray);
+        return ni;
+    }
+#endif
+    return NULL;
+}
+
+
+
+/*
+ * Returns relevant info as a jint.
+ *
+ * Class:     java_net_PlainDatagramSocketImpl
+ * Method:    socketGetOption
+ * Signature: (I)Ljava/lang/Object;
+ */
+JNIEXPORT jobject JNICALL
+Java_java_net_PlainDatagramSocketImpl_socketGetOption(JNIEnv *env, jobject this,
+                                                      jint opt) {
+    int fd;
+    int level, optname, optlen;
+    union {
+        int i;
+        char c;
+    } optval;
+
+    fd = getFD(env, this);
+    if (fd < 0) {
+        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
+                        "socket closed");
+        return NULL;
+    }
+
+    /*
+     * Handle IP_MULTICAST_IF seperately
+     */
+    if (opt == java_net_SocketOptions_IP_MULTICAST_IF ||
+        opt == java_net_SocketOptions_IP_MULTICAST_IF2) {
+        return getMulticastInterface(env, this, fd, opt);
+
+    }
+
+    /*
+     * SO_BINDADDR implemented using getsockname
+     */
+    if (opt == java_net_SocketOptions_SO_BINDADDR) {
+        /* find out local IP address */
+        SOCKADDR him;
+        socklen_t len = 0;
+        int port;
+        jobject iaObj;
+
+        len = SOCKADDR_LEN;
+
+        if (getsockname(fd, (struct sockaddr *)&him, &len) == -1) {
+            NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
+                           "Error getting socket name");
+            return NULL;
+        }
+        iaObj = NET_SockaddrToInetAddress(env, (struct sockaddr *)&him, &port);
+
+        return iaObj;
+    }
+
+    /*
+     * Map the Java level socket option to the platform specific
+     * level and option name.
+     */
+    if (NET_MapSocketOption(opt, &level, &optname)) {
+        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Invalid option");
+        return NULL;
+    }
+
+    /*
+     * IP_MULTICAST_LOOP socket option isn't available on Linux 2.2
+     * kernel with IPv6 so return value stored in impl.
+     */
+#if defined(AF_INET6) && defined(__linux__)
+    if (isOldKernel && opt == java_net_SocketOptions_IP_MULTICAST_LOOP &&
+        level == IPPROTO_IPV6) {
+        int mode = (int)(*env)->GetBooleanField(env, this, pdsi_loopbackID);
+        return createBoolean(env, mode);
+    }
+#endif
+
+    if (opt == java_net_SocketOptions_IP_MULTICAST_LOOP &&
+        level == IPPROTO_IP) {
+        optlen = sizeof(optval.c);
+    } else {
+        optlen = sizeof(optval.i);
+    }
+
+    if (NET_GetSockOpt(fd, level, optname, (void *)&optval, &optlen) < 0) {
+        NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
+                         "Error getting socket option");
+        return NULL;
+    }
+
+    switch (opt) {
+        case java_net_SocketOptions_IP_MULTICAST_LOOP:
+            /* getLoopbackMode() returns true if IP_MULTICAST_LOOP disabled */
+            if (level == IPPROTO_IP) {
+                return createBoolean(env, (int)!optval.c);
+            } else {
+                return createBoolean(env, !optval.i);
+            }
+
+        case java_net_SocketOptions_SO_BROADCAST:
+        case java_net_SocketOptions_SO_REUSEADDR:
+            return createBoolean(env, optval.i);
+
+        case java_net_SocketOptions_SO_SNDBUF:
+        case java_net_SocketOptions_SO_RCVBUF:
+        case java_net_SocketOptions_IP_TOS:
+            return createInteger(env, optval.i);
+
+    }
+
+    /* should never rearch here */
+    return NULL;
+}
+
+/*
+ * Multicast-related calls
+ */
+
+JNIEXPORT void JNICALL
+Java_java_net_PlainDatagramSocketImpl_setTTL(JNIEnv *env, jobject this,
+                                             jbyte ttl) {
+    jint ittl = ttl;
+    if (ittl < 0) {
+        ittl += 0x100;
+    }
+    Java_java_net_PlainDatagramSocketImpl_setTimeToLive(env, this, ittl);
+}
+
+/*
+ * Set TTL for a socket. Throw exception if failed.
+ */
+static void setTTL(JNIEnv *env, int fd, jint ttl) {
+    char ittl = (char)ttl;
+    if (JVM_SetSockOpt(fd, IPPROTO_IP, IP_MULTICAST_TTL, (char*)&ittl,
+                       sizeof(ittl)) < 0) {
+        NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
+                       "Error setting socket option");
+    }
+}
+
+/*
+ * Set hops limit for a socket. Throw exception if failed.
+ */
+#ifdef AF_INET6
+static void setHopLimit(JNIEnv *env, int fd, jint ttl) {
+    int ittl = (int)ttl;
+    if (JVM_SetSockOpt(fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS,
+                       (char*)&ittl, sizeof(ittl)) < 0) {
+        NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
+                       "Error setting socket option");
+    }
+}
+#endif
+
+/*
+ * Class:     java_net_PlainDatagramSocketImpl
+ * Method:    setTTL
+ * Signature: (B)V
+ */
+JNIEXPORT void JNICALL
+Java_java_net_PlainDatagramSocketImpl_setTimeToLive(JNIEnv *env, jobject this,
+                                                    jint ttl) {
+
+    jobject fdObj = (*env)->GetObjectField(env, this, pdsi_fdID);
+    int fd;
+    /* it is important to cast this to a char, otherwise setsockopt gets confused */
+
+    if (IS_NULL(fdObj)) {
+        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
+                        "Socket closed");
+        return;
+    } else {
+        fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
+    }
+    /* setsockopt to be correct ttl */
+#ifdef AF_INET6
+#ifdef __linux__
+    setTTL(env, fd, ttl);
+    if (ipv6_available()) {
+        setHopLimit(env, fd, ttl);
+        if (isOldKernel) {
+            (*env)->SetIntField(env, this, pdsi_ttlID, ttl);
+        }
+    }
+#else  /*  __linux__ not defined */
+    if (ipv6_available()) {
+        setHopLimit(env, fd, ttl);
+    } else {
+        setTTL(env, fd, ttl);
+    }
+#endif  /* __linux__ */
+#else
+    setTTL(env, fd, ttl);
+#endif  /* AF_INET6 */
+}
+
+/*
+ * Class:     java_net_PlainDatagramSocketImpl
+ * Method:    getTTL
+ * Signature: ()B
+ */
+JNIEXPORT jbyte JNICALL
+Java_java_net_PlainDatagramSocketImpl_getTTL(JNIEnv *env, jobject this) {
+    return (jbyte)Java_java_net_PlainDatagramSocketImpl_getTimeToLive(env, this);
+}
+
+
+/*
+ * Class:     java_net_PlainDatagramSocketImpl
+ * Method:    getTTL
+ * Signature: ()B
+ */
+JNIEXPORT jint JNICALL
+Java_java_net_PlainDatagramSocketImpl_getTimeToLive(JNIEnv *env, jobject this) {
+
+    jobject fdObj = (*env)->GetObjectField(env, this, pdsi_fdID);
+    jint fd = -1;
+
+    if (IS_NULL(fdObj)) {
+        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
+                        "Socket closed");
+        return -1;
+    } else {
+        fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
+    }
+    /* getsockopt of ttl */
+#ifdef AF_INET6
+    if (ipv6_available()) {
+        int ttl = 0;
+        int len = sizeof(ttl);
+
+#ifdef __linux__
+        /*
+         * Linux 2.2 kernel doesn't support IPV6_MULTICAST_HOPS socket option
+         */
+        if (isOldKernel) {
+            return (*env)->GetIntField(env, this, pdsi_ttlID);
+        }
+#endif
+
+        if (JVM_GetSockOpt(fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS,
+                               (char*)&ttl, &len) < 0) {
+                NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
+                               "Error getting socket option");
+                return -1;
+            }
+        return (jint)ttl;
+    } else
+#endif /* AF_INET6 */
+        {
+            u_char ttl = 0;
+            int len = sizeof(ttl);
+            if (JVM_GetSockOpt(fd, IPPROTO_IP, IP_MULTICAST_TTL,
+                               (char*)&ttl, &len) < 0) {
+                NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
+                               "Error getting socket option");
+                return -1;
+            }
+            return (jint)ttl;
+        }
+}
+
+
+/*
+ * mcast_join_leave: Join or leave a multicast group.
+ *
+ * For IPv4 sockets use IP_ADD_MEMBERSHIP/IP_DROP_MEMBERSHIP socket option
+ * to join/leave multicast group.
+ *
+ * For IPv6 sockets use IPV6_ADD_MEMBERSHIP/IPV6_DROP_MEMBERSHIP socket option
+ * to join/leave multicast group. If multicast group is an IPv4 address then
+ * an IPv4-mapped address is used.
+ *
+ * On Linux with IPv6 if we wish to join/leave an IPv4 multicast group then
+ * we must use the IPv4 socket options. This is because the IPv6 socket options
+ * don't support IPv4-mapped addresses. This is true as per 2.2.19 and 2.4.7
+ * kernel releases. In the future it's possible that IP_ADD_MEMBERSHIP
+ * will be updated to return ENOPROTOOPT if uses with an IPv6 socket (Solaris
+ * already does this). Thus to cater for this we first try with the IPv4
+ * socket options and if they fail we use the IPv6 socket options. This
+ * seems a reasonable failsafe solution.
+ */
+static void mcast_join_leave(JNIEnv *env, jobject this,
+                             jobject iaObj, jobject niObj,
+                             jboolean join) {
+
+    jobject fdObj = (*env)->GetObjectField(env, this, pdsi_fdID);
+    jint fd;
+    jint ipv6_join_leave;
+
+    if (IS_NULL(fdObj)) {
+        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
+                        "Socket closed");
+        return;
+    } else {
+        fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
+    }
+    if (IS_NULL(iaObj)) {
+        JNU_ThrowNullPointerException(env, "iaObj");
+        return;
+    }
+
+    /*
+     * Determine if this is an IPv4 or IPv6 join/leave.
+     */
+#ifdef AF_INET6
+    ipv6_join_leave = ipv6_available();
+
+#ifdef __linux__
+    if (getInetAddress_family(env, iaObj) == IPv4) {
+        ipv6_join_leave = JNI_FALSE;
+    }
+#endif
+
+#else
+    /*
+     * IPv6 not compiled in
+     */
+    ipv6_join_leave = JNI_FALSE;
+#endif
+
+    /*
+     * For IPv4 join use IP_ADD_MEMBERSHIP/IP_DROP_MEMBERSHIP socket option
+     *
+     * On Linux if IPv4 or IPv6 use IP_ADD_MEMBERSHIP/IP_DROP_MEMBERSHIP
+     */
+    if (!ipv6_join_leave) {
+#ifdef __linux__
+        struct ip_mreqn mname;
+#else
+        struct ip_mreq mname;
+#endif
+        int mname_len;
+
+        /*
+         * joinGroup(InetAddress, NetworkInterface) implementation :-
+         *
+         * Linux/IPv6:  use ip_mreqn structure populated with multicast
+         *              address and interface index.
+         *
+         * IPv4:        use ip_mreq structure populated with multicast
+         *              address and first address obtained from
+         *              NetworkInterface
+         */
+        if (niObj != NULL) {
+#if defined(__linux__) && defined(AF_INET6)
+            if (ipv6_available()) {
+                static jfieldID ni_indexID;
+
+                if (ni_indexID == NULL) {
+                    jclass c = (*env)->FindClass(env, "java/net/NetworkInterface");
+                    CHECK_NULL(c);
+                    ni_indexID = (*env)->GetFieldID(env, c, "index", "I");
+                    CHECK_NULL(ni_indexID);
+                }
+
+                mname.imr_multiaddr.s_addr = htonl(getInetAddress_addr(env, iaObj));
+                mname.imr_address.s_addr = 0;
+                mname.imr_ifindex =  (*env)->GetIntField(env, niObj, ni_indexID);
+                mname_len = sizeof(struct ip_mreqn);
+            } else
+#endif
+            {
+                jobjectArray addrArray = (*env)->GetObjectField(env, niObj, ni_addrsID);
+                jobject addr;
+
+                if ((*env)->GetArrayLength(env, addrArray) < 1) {
+                    JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
+                        "bad argument for IP_ADD_MEMBERSHIP: "
+                        "No IP addresses bound to interface");
+                    return;
+                }
+                addr = (*env)->GetObjectArrayElement(env, addrArray, 0);
+
+                mname.imr_multiaddr.s_addr = htonl(getInetAddress_addr(env, iaObj));
+#ifdef __linux__
+                mname.imr_address.s_addr = htonl(getInetAddress_addr(env, addr));
+#else
+                mname.imr_interface.s_addr = htonl(getInetAddress_addr(env, addr));
+#endif
+                mname_len = sizeof(struct ip_mreq);
+            }
+        }
+
+
+        /*
+         * joinGroup(InetAddress) implementation :-
+         *
+         * Linux/IPv6:  use ip_mreqn structure populated with multicast
+         *              address and interface index. index obtained
+         *              from cached value or IPV6_MULTICAST_IF.
+         *
+         * IPv4:        use ip_mreq structure populated with multicast
+         *              address and local address obtained from
+         *              IP_MULTICAST_IF. On Linux IP_MULTICAST_IF
+         *              returns different structure depending on
+         *              kernel.
+         */
+
+        if (niObj == NULL) {
+
+#if defined(__linux__) && defined(AF_INET6)
+            if (ipv6_available()) {
+
+                int index;
+                int len = sizeof(index);
+
+                if (isOldKernel) {
+                    index = (*env)->GetIntField(env, this, pdsi_multicastInterfaceID);
+                } else {
+                    if (JVM_GetSockOpt(fd, IPPROTO_IPV6, IPV6_MULTICAST_IF,
+                                       (char*)&index, &len) < 0) {
+                        NET_ThrowCurrent(env, "getsockopt IPV6_MULTICAST_IF failed");
+                        return;
+                    }
+                }
+
+                mname.imr_multiaddr.s_addr = htonl(getInetAddress_addr(env, iaObj));
+                mname.imr_address.s_addr = 0 ;
+                mname.imr_ifindex = index;
+                mname_len = sizeof(struct ip_mreqn);
+            } else
+#endif
+            {
+                struct in_addr in;
+                struct in_addr *inP = &in;
+                socklen_t len = sizeof(struct in_addr);
+
+#ifdef __linux__
+                struct ip_mreqn mreqn;
+                if (isOldKernel) {
+                    inP = (struct in_addr *)&mreqn;
+                    len = sizeof(struct ip_mreqn);
+                }
+#endif
+                if (getsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF, (char *)inP, &len) < 0) {
+                    NET_ThrowCurrent(env, "getsockopt IP_MULTICAST_IF failed");
+                    return;
+                }
+
+#ifdef __linux__
+                mname.imr_address.s_addr =
+                    (isOldKernel ? mreqn.imr_address.s_addr : in.s_addr);
+
+#else
+                mname.imr_interface.s_addr = in.s_addr;
+#endif
+                mname.imr_multiaddr.s_addr = htonl(getInetAddress_addr(env, iaObj));
+                mname_len = sizeof(struct ip_mreq);
+            }
+        }
+
+
+        /*
+         * Join the multicast group.
+         */
+        if (JVM_SetSockOpt(fd, IPPROTO_IP, (join ? IP_ADD_MEMBERSHIP:IP_DROP_MEMBERSHIP),
+                           (char *) &mname, mname_len) < 0) {
+
+            /*
+             * If IP_ADD_MEMBERSHIP returns ENOPROTOOPT on Linux and we've got
+             * IPv6 enabled then it's possible that the kernel has been fixed
+             * so we switch to IPV6_ADD_MEMBERSHIP socket option.
+             * As of 2.4.7 kernel IPV6_ADD_MEMERSHIP can't handle IPv4-mapped
+             * addresses so we have to use IP_ADD_MEMERSHIP for IPv4 multicast
+             * groups. However if the socket is an IPv6 socket then then setsockopt
+             * should reurn ENOPROTOOPT. We assume this will be fixed in Linux
+             * at some stage.
+             */
+#if defined(__linux__) && defined(AF_INET6)
+            if (errno == ENOPROTOOPT) {
+                if (ipv6_available()) {
+                    ipv6_join_leave = JNI_TRUE;
+                    errno = 0;
+                } else  {
+                    errno = ENOPROTOOPT;    /* errno can be changed by ipv6_available */
+                }
+            }
+#endif
+            if (errno) {
+                if (join) {
+                    NET_ThrowCurrent(env, "setsockopt IP_ADD_MEMBERSHIP failed");
+                } else {
+                    if (errno == ENOENT)
+                        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
+                            "Not a member of the multicast group");
+                    else
+                        NET_ThrowCurrent(env, "setsockopt IP_DROP_MEMBERSHIP failed");
+                }
+            }
+        }
+
+        /*
+         * If we haven't switched to IPv6 socket option then we're done.
+         */
+        if (!ipv6_join_leave) {
+            return;
+        }
+    }
+
+
+    /*
+     * IPv6 join. If it's an IPv4 multicast group then we use an IPv4-mapped
+     * address.
+     */
+#ifdef AF_INET6
+    {
+        struct ipv6_mreq mname6;
+        jbyteArray ipaddress;
+        jbyte caddr[16];
+        jint family;
+        jint address;
+        family = getInetAddress_family(env, iaObj) == IPv4? AF_INET : AF_INET6;
+        if (family == AF_INET) { /* will convert to IPv4-mapped address */
+            memset((char *) caddr, 0, 16);
+            address = getInetAddress_addr(env, iaObj);
+
+            caddr[10] = 0xff;
+            caddr[11] = 0xff;
+
+            caddr[12] = ((address >> 24) & 0xff);
+            caddr[13] = ((address >> 16) & 0xff);
+            caddr[14] = ((address >> 8) & 0xff);
+            caddr[15] = (address & 0xff);
+        } else {
+            ipaddress = (*env)->GetObjectField(env, iaObj, ia6_ipaddressID);
+            (*env)->GetByteArrayRegion(env, ipaddress, 0, 16, caddr);
+        }
+
+        memcpy((void *)&(mname6.ipv6mr_multiaddr), caddr, sizeof(struct in6_addr));
+        if (IS_NULL(niObj)) {
+            int index;
+            int len = sizeof(index);
+
+#ifdef __linux__
+            /*
+             * 2.2 kernel doens't support IPV6_MULTICAST_IF socket option
+             */
+            if (isOldKernel) {
+                index = (*env)->GetIntField(env, this, pdsi_multicastInterfaceID);
+            } else
+#endif
+            {
+                if (JVM_GetSockOpt(fd, IPPROTO_IPV6, IPV6_MULTICAST_IF,
+                                 (char*)&index, &len) < 0) {
+                    NET_ThrowCurrent(env, "getsockopt IPV6_MULTICAST_IF failed");
+                    return;
+                }
+            }
+
+#ifdef __linux__
+            /*
+             * On 2.4.8+ if we join a group with the interface set to 0
+             * then the kernel records the interface it decides. This causes
+             * subsequent leave groups to fail as there is no match. Thus we
+             * pick the interface if there is a matching route.
+             */
+            if (index == 0 && !isOldKernel) {
+                int rt_index = getDefaultIPv6Interface(&(mname6.ipv6mr_multiaddr));
+                if (rt_index > 0) {
+                    index = rt_index;
+                }
+            }
+#endif
+#ifdef MACOSX
+            if (family == AF_INET6 && index == 0) {
+                index = getDefaultScopeID(env);
+            }
+#endif
+            mname6.ipv6mr_interface = index;
+        } else {
+            jint idx = (*env)->GetIntField(env, niObj, ni_indexID);
+            mname6.ipv6mr_interface = idx;
+        }
+
+#if defined(_ALLBSD_SOURCE)
+#define ADD_MEMBERSHIP          IPV6_JOIN_GROUP
+#define DRP_MEMBERSHIP          IPV6_LEAVE_GROUP
+#define S_ADD_MEMBERSHIP        "IPV6_JOIN_GROUP"
+#define S_DRP_MEMBERSHIP        "IPV6_LEAVE_GROUP"
+#else
+#define ADD_MEMBERSHIP          IPV6_ADD_MEMBERSHIP
+#define DRP_MEMBERSHIP          IPV6_DROP_MEMBERSHIP
+#define S_ADD_MEMBERSHIP        "IPV6_ADD_MEMBERSHIP"
+#define S_DRP_MEMBERSHIP        "IPV6_DROP_MEMBERSHIP"
+#endif
+
+        /* Join the multicast group */
+        if (JVM_SetSockOpt(fd, IPPROTO_IPV6, (join ? ADD_MEMBERSHIP : DRP_MEMBERSHIP),
+                           (char *) &mname6, sizeof (mname6)) < 0) {
+
+            if (join) {
+                NET_ThrowCurrent(env, "setsockopt " S_ADD_MEMBERSHIP " failed");
+            } else {
+                if (errno == ENOENT) {
+                   JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
+                        "Not a member of the multicast group");
+                } else {
+                    NET_ThrowCurrent(env, "setsockopt " S_DRP_MEMBERSHIP " failed");
+                }
+            }
+        }
+    }
+#endif
+}
+
+/*
+ * Class:     java_net_PlainDatagramSocketImpl
+ * Method:    join
+ * Signature: (Ljava/net/InetAddress;)V
+ */
+JNIEXPORT void JNICALL
+Java_java_net_PlainDatagramSocketImpl_join(JNIEnv *env, jobject this,
+                                           jobject iaObj, jobject niObj)
+{
+    mcast_join_leave(env, this, iaObj, niObj, JNI_TRUE);
+}
+
+/*
+ * Class:     java_net_PlainDatagramSocketImpl
+ * Method:    leave
+ * Signature: (Ljava/net/InetAddress;)V
+ */
+JNIEXPORT void JNICALL
+Java_java_net_PlainDatagramSocketImpl_leave(JNIEnv *env, jobject this,
+                                            jobject iaObj, jobject niObj)
+{
+    mcast_join_leave(env, this, iaObj, niObj, JNI_FALSE);
+}
diff --git a/ojluni/src/main/native/PlainSocketImpl.c b/ojluni/src/main/native/PlainSocketImpl.c
new file mode 100755
index 0000000..82616f2
--- /dev/null
+++ b/ojluni/src/main/native/PlainSocketImpl.c
@@ -0,0 +1,1110 @@
+/*
+ * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include <errno.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#if defined(__linux__) && !defined(USE_SELECT)
+#include <sys/poll.h>
+#endif
+#include <netinet/tcp.h>        /* Defines TCP_NODELAY, needed for 2.6 */
+#include <netinet/in.h>
+#ifdef __linux__
+#include <netinet/ip.h>
+#endif
+#include <netdb.h>
+#include <stdlib.h>
+
+#ifdef __solaris__
+#include <fcntl.h>
+#endif
+#ifdef __linux__
+#include <unistd.h>
+#include <sys/sysctl.h>
+#endif
+
+#include "jvm.h"
+#include "jni_util.h"
+#include "net_util.h"
+
+#include "java_net_SocketOptions.h"
+#include "java_net_PlainSocketImpl.h"
+
+/************************************************************************
+ * PlainSocketImpl
+ */
+
+static jfieldID IO_fd_fdID;
+
+jfieldID psi_fdID;
+jfieldID psi_addressID;
+jfieldID psi_ipaddressID;
+jfieldID psi_portID;
+jfieldID psi_localportID;
+jfieldID psi_timeoutID;
+jfieldID psi_trafficClassID;
+jfieldID psi_serverSocketID;
+jfieldID psi_fdLockID;
+jfieldID psi_closePendingID;
+
+extern void setDefaultScopeID(JNIEnv *env, struct sockaddr *him);
+
+/*
+ * file descriptor used for dup2
+ */
+static int marker_fd = -1;
+
+
+#define SET_NONBLOCKING(fd) {           \
+        int flags = fcntl(fd, F_GETFL); \
+        flags |= O_NONBLOCK;            \
+        fcntl(fd, F_SETFL, flags);      \
+}
+
+#define SET_BLOCKING(fd) {              \
+        int flags = fcntl(fd, F_GETFL); \
+        flags &= ~O_NONBLOCK;           \
+        fcntl(fd, F_SETFL, flags);      \
+}
+
+/*
+ * Create the marker file descriptor by establishing a loopback connection
+ * which we shutdown but do not close the fd. The result is an fd that
+ * can be used for read/write.
+ */
+static int getMarkerFD()
+{
+    int sv[2];
+
+#ifdef AF_UNIX
+    if (socketpair(AF_UNIX, SOCK_STREAM, 0, sv) == -1) {
+        return -1;
+    }
+#else
+    return -1;
+#endif
+
+    /*
+     * Finally shutdown sv[0] (any reads to this fd will get
+     * EOF; any writes will get an error).
+     */
+    JVM_SocketShutdown(sv[0], 2);
+    JVM_SocketClose(sv[1]);
+
+    return sv[0];
+}
+
+/*
+ * Return the file descriptor given a PlainSocketImpl
+ */
+static int getFD(JNIEnv *env, jobject this) {
+    jobject fdObj = (*env)->GetObjectField(env, this, psi_fdID);
+    CHECK_NULL_RETURN(fdObj, -1);
+    return (*env)->GetIntField(env, fdObj, IO_fd_fdID);
+}
+
+/*
+ * The initroto function is called whenever PlainSocketImpl is
+ * loaded, to cache fieldIds for efficiency. This is called everytime
+ * the Java class is loaded.
+ *
+ * Class:     java_net_PlainSocketImpl
+ * Method:    initProto
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL
+Java_java_net_PlainSocketImpl_initProto(JNIEnv *env, jclass cls) {
+    psi_fdID = (*env)->GetFieldID(env, cls , "fd",
+                                  "Ljava/io/FileDescriptor;");
+    CHECK_NULL(psi_fdID);
+    psi_addressID = (*env)->GetFieldID(env, cls, "address",
+                                          "Ljava/net/InetAddress;");
+    CHECK_NULL(psi_addressID);
+    psi_portID = (*env)->GetFieldID(env, cls, "port", "I");
+    CHECK_NULL(psi_portID);
+    psi_localportID = (*env)->GetFieldID(env, cls, "localport", "I");
+    CHECK_NULL(psi_localportID);
+    psi_timeoutID = (*env)->GetFieldID(env, cls, "timeout", "I");
+    CHECK_NULL(psi_timeoutID);
+    psi_trafficClassID = (*env)->GetFieldID(env, cls, "trafficClass", "I");
+    CHECK_NULL(psi_trafficClassID);
+    psi_serverSocketID = (*env)->GetFieldID(env, cls, "serverSocket",
+                        "Ljava/net/ServerSocket;");
+    CHECK_NULL(psi_serverSocketID);
+    psi_fdLockID = (*env)->GetFieldID(env, cls, "fdLock",
+                                      "Ljava/lang/Object;");
+    CHECK_NULL(psi_fdLockID);
+    psi_closePendingID = (*env)->GetFieldID(env, cls, "closePending", "Z");
+    CHECK_NULL(psi_closePendingID);
+    IO_fd_fdID = NET_GetFileDescriptorID(env);
+    CHECK_NULL(IO_fd_fdID);
+
+    /* Create the marker fd used for dup2 */
+    marker_fd = getMarkerFD();
+}
+
+/* a global reference to the java.net.SocketException class. In
+ * socketCreate, we ensure that this is initialized. This is to
+ * prevent the problem where socketCreate runs out of file
+ * descriptors, and is then unable to load the exception class.
+ */
+static jclass socketExceptionCls;
+
+/*
+ * Class:     java_net_PlainSocketImpl
+ * Method:    socketCreate
+ * Signature: (Z)V */
+JNIEXPORT void JNICALL
+Java_java_net_PlainSocketImpl_socketCreate(JNIEnv *env, jobject this,
+                                           jboolean stream) {
+    jobject fdObj, ssObj;
+    int fd;
+    int type = (stream ? SOCK_STREAM : SOCK_DGRAM);
+#ifdef AF_INET6
+    int domain = ipv6_available() ? AF_INET6 : AF_INET;
+#else
+    int domain = AF_INET;
+#endif
+
+    if (socketExceptionCls == NULL) {
+        jclass c = (*env)->FindClass(env, "java/net/SocketException");
+        CHECK_NULL(c);
+        socketExceptionCls = (jclass)(*env)->NewGlobalRef(env, c);
+        CHECK_NULL(socketExceptionCls);
+    }
+    fdObj = (*env)->GetObjectField(env, this, psi_fdID);
+
+    if (fdObj == NULL) {
+        (*env)->ThrowNew(env, socketExceptionCls, "null fd object");
+        return;
+    }
+
+    if ((fd = JVM_Socket(domain, type, 0)) == JVM_IO_ERR) {
+        /* note: if you run out of fds, you may not be able to load
+         * the exception class, and get a NoClassDefFoundError
+         * instead.
+         */
+        NET_ThrowNew(env, errno, "can't create socket");
+        return;
+    }
+
+#ifdef AF_INET6
+    /* Disable IPV6_V6ONLY to ensure dual-socket support */
+    if (domain == AF_INET6) {
+        int arg = 0;
+        if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&arg,
+                       sizeof(int)) < 0) {
+            NET_ThrowNew(env, errno, "cannot set IPPROTO_IPV6");
+            close(fd);
+            return;
+        }
+    }
+#endif /* AF_INET6 */
+
+    /*
+     * If this is a server socket then enable SO_REUSEADDR
+     * automatically and set to non blocking.
+     */
+    ssObj = (*env)->GetObjectField(env, this, psi_serverSocketID);
+    if (ssObj != NULL) {
+        int arg = 1;
+        SET_NONBLOCKING(fd);
+        if (JVM_SetSockOpt(fd, SOL_SOCKET, SO_REUSEADDR, (char*)&arg,
+                           sizeof(arg)) < 0) {
+            NET_ThrowNew(env, errno, "cannot set SO_REUSEADDR");
+            close(fd);
+            return;
+        }
+    }
+
+    (*env)->SetIntField(env, fdObj, IO_fd_fdID, fd);
+}
+
+/*
+ * inetAddress is the address object passed to the socket connect
+ * call.
+ *
+ * Class:     java_net_PlainSocketImpl
+ * Method:    socketConnect
+ * Signature: (Ljava/net/InetAddress;I)V
+ */
+JNIEXPORT void JNICALL
+Java_java_net_PlainSocketImpl_socketConnect(JNIEnv *env, jobject this,
+                                            jobject iaObj, jint port,
+                                            jint timeout)
+{
+    jint localport = (*env)->GetIntField(env, this, psi_localportID);
+    int len = 0;
+
+    /* fdObj is the FileDescriptor field on this */
+    jobject fdObj = (*env)->GetObjectField(env, this, psi_fdID);
+
+    jclass clazz = (*env)->GetObjectClass(env, this);
+
+    jobject fdLock;
+
+    jint trafficClass = (*env)->GetIntField(env, this, psi_trafficClassID);
+
+    /* fd is an int field on iaObj */
+    jint fd;
+
+    SOCKADDR him;
+    /* The result of the connection */
+    int connect_rv = -1;
+
+    if (IS_NULL(fdObj)) {
+        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Socket closed");
+        return;
+    } else {
+        fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
+    }
+    if (IS_NULL(iaObj)) {
+        JNU_ThrowNullPointerException(env, "inet address argument null.");
+        return;
+    }
+
+    /* connect */
+    if (NET_InetAddressToSockaddr(env, iaObj, port, (struct sockaddr *)&him, &len, JNI_TRUE) != 0) {
+      return;
+    }
+    setDefaultScopeID(env, (struct sockaddr *)&him);
+
+#ifdef AF_INET6
+    if (trafficClass != 0 && ipv6_available()) {
+        NET_SetTrafficClass((struct sockaddr *)&him, trafficClass);
+    }
+#endif /* AF_INET6 */
+    if (timeout <= 0) {
+        connect_rv = NET_Connect(fd, (struct sockaddr *)&him, len);
+#ifdef __solaris__
+        if (connect_rv == JVM_IO_ERR && errno == EINPROGRESS ) {
+
+            /* This can happen if a blocking connect is interrupted by a signal.
+             * See 6343810.
+             */
+            while (1) {
+#ifndef USE_SELECT
+                {
+                    struct pollfd pfd;
+                    pfd.fd = fd;
+                    pfd.events = POLLOUT;
+
+                    connect_rv = NET_Poll(&pfd, 1, -1);
+                }
+#else
+                {
+                    fd_set wr, ex;
+
+                    FD_ZERO(&wr);
+                    FD_SET(fd, &wr);
+                    FD_ZERO(&ex);
+                    FD_SET(fd, &ex);
+
+                    connect_rv = NET_Select(fd+1, 0, &wr, &ex, 0);
+                }
+#endif
+
+                if (connect_rv == JVM_IO_ERR) {
+                    if (errno == EINTR) {
+                        continue;
+                    } else {
+                        break;
+                    }
+                }
+                if (connect_rv > 0) {
+                    int optlen;
+                    /* has connection been established */
+                    optlen = sizeof(connect_rv);
+                    if (JVM_GetSockOpt(fd, SOL_SOCKET, SO_ERROR,
+                                        (void*)&connect_rv, &optlen) <0) {
+                        connect_rv = errno;
+                    }
+
+                    if (connect_rv != 0) {
+                        /* restore errno */
+                        errno = connect_rv;
+                        connect_rv = JVM_IO_ERR;
+                    }
+                    break;
+                }
+            }
+        }
+#endif
+    } else {
+        /*
+         * A timeout was specified. We put the socket into non-blocking
+         * mode, connect, and then wait for the connection to be
+         * established, fail, or timeout.
+         */
+        SET_NONBLOCKING(fd);
+
+        /* no need to use NET_Connect as non-blocking */
+        connect_rv = connect(fd, (struct sockaddr *)&him, len);
+
+        /* connection not established immediately */
+        if (connect_rv != 0) {
+            int optlen;
+            jlong prevTime = JVM_CurrentTimeMillis(env, 0);
+
+            if (errno != EINPROGRESS) {
+                NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "ConnectException",
+                             "connect failed");
+                SET_BLOCKING(fd);
+                return;
+            }
+
+            /*
+             * Wait for the connection to be established or a
+             * timeout occurs. poll/select needs to handle EINTR in
+             * case lwp sig handler redirects any process signals to
+             * this thread.
+             */
+            while (1) {
+                jlong newTime;
+#ifndef USE_SELECT
+                {
+                    struct pollfd pfd;
+                    pfd.fd = fd;
+                    pfd.events = POLLOUT;
+
+                    errno = 0;
+                    connect_rv = NET_Poll(&pfd, 1, timeout);
+                }
+#else
+                {
+                    fd_set wr, ex;
+                    struct timeval t;
+
+                    t.tv_sec = timeout / 1000;
+                    t.tv_usec = (timeout % 1000) * 1000;
+
+                    FD_ZERO(&wr);
+                    FD_SET(fd, &wr);
+                    FD_ZERO(&ex);
+                    FD_SET(fd, &ex);
+
+                    errno = 0;
+                    connect_rv = NET_Select(fd+1, 0, &wr, &ex, &t);
+                }
+#endif
+
+                if (connect_rv >= 0) {
+                    break;
+                }
+                if (errno != EINTR) {
+                    break;
+                }
+
+                /*
+                 * The poll was interrupted so adjust timeout and
+                 * restart
+                 */
+                newTime = JVM_CurrentTimeMillis(env, 0);
+                timeout -= (newTime - prevTime);
+                if (timeout <= 0) {
+                    connect_rv = 0;
+                    break;
+                }
+                prevTime = newTime;
+
+            } /* while */
+
+            if (connect_rv == 0) {
+                JNU_ThrowByName(env, JNU_JAVANETPKG "SocketTimeoutException",
+                            "connect timed out");
+
+                /*
+                 * Timeout out but connection may still be established.
+                 * At the high level it should be closed immediately but
+                 * just in case we make the socket blocking again and
+                 * shutdown input & output.
+                 */
+                SET_BLOCKING(fd);
+                JVM_SocketShutdown(fd, 2);
+                return;
+            }
+
+            /* has connection been established */
+            optlen = sizeof(connect_rv);
+            if (JVM_GetSockOpt(fd, SOL_SOCKET, SO_ERROR, (void*)&connect_rv,
+                               &optlen) <0) {
+                connect_rv = errno;
+            }
+        }
+
+        /* make socket blocking again */
+        SET_BLOCKING(fd);
+
+        /* restore errno */
+        if (connect_rv != 0) {
+            errno = connect_rv;
+            connect_rv = JVM_IO_ERR;
+        }
+    }
+
+    /* report the appropriate exception */
+    if (connect_rv < 0) {
+
+#ifdef __linux__
+        /*
+         * Linux/GNU distribution setup /etc/hosts so that
+         * InetAddress.getLocalHost gets back the loopback address
+         * rather than the host address. Thus a socket can be
+         * bound to the loopback address and the connect will
+         * fail with EADDRNOTAVAIL. In addition the Linux kernel
+         * returns the wrong error in this case - it returns EINVAL
+         * instead of EADDRNOTAVAIL. We handle this here so that
+         * a more descriptive exception text is used.
+         */
+        if (connect_rv == JVM_IO_ERR && errno == EINVAL) {
+            JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
+                "Invalid argument or cannot assign requested address");
+            return;
+        }
+#endif
+        if (connect_rv == JVM_IO_INTR) {
+            JNU_ThrowByName(env, JNU_JAVAIOPKG "InterruptedIOException",
+                            "operation interrupted");
+#if defined(EPROTO)
+        } else if (errno == EPROTO) {
+            NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "ProtocolException",
+                           "Protocol error");
+#endif
+        } else if (errno == ECONNREFUSED) {
+            NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "ConnectException",
+                           "Connection refused");
+        } else if (errno == ETIMEDOUT) {
+            NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "ConnectException",
+                           "Connection timed out");
+        } else if (errno == EHOSTUNREACH) {
+            NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "NoRouteToHostException",
+                           "Host unreachable");
+        } else if (errno == EADDRNOTAVAIL) {
+            NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "NoRouteToHostException",
+                             "Address not available");
+        } else if ((errno == EISCONN) || (errno == EBADF)) {
+            JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
+                            "Socket closed");
+        } else {
+            NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "connect failed");
+        }
+        return;
+    }
+
+    (*env)->SetIntField(env, fdObj, IO_fd_fdID, fd);
+
+    /* set the remote peer address and port */
+    (*env)->SetObjectField(env, this, psi_addressID, iaObj);
+    (*env)->SetIntField(env, this, psi_portID, port);
+
+    /*
+     * we need to initialize the local port field if bind was called
+     * previously to the connect (by the client) then localport field
+     * will already be initialized
+     */
+    if (localport == 0) {
+        /* Now that we're a connected socket, let's extract the port number
+         * that the system chose for us and store it in the Socket object.
+         */
+        len = SOCKADDR_LEN;
+        if (JVM_GetSockName(fd, (struct sockaddr *)&him, &len) == -1) {
+            NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
+                           "Error getting socket name");
+        } else {
+            localport = NET_GetPortFromSockaddr((struct sockaddr *)&him);
+            (*env)->SetIntField(env, this, psi_localportID, localport);
+        }
+    }
+}
+
+/*
+ * Class:     java_net_PlainSocketImpl
+ * Method:    socketBind
+ * Signature: (Ljava/net/InetAddress;I)V
+ */
+JNIEXPORT void JNICALL
+Java_java_net_PlainSocketImpl_socketBind(JNIEnv *env, jobject this,
+                                         jobject iaObj, jint localport) {
+
+    /* fdObj is the FileDescriptor field on this */
+    jobject fdObj = (*env)->GetObjectField(env, this, psi_fdID);
+    /* fd is an int field on fdObj */
+    int fd;
+    int len;
+    SOCKADDR him;
+
+    if (IS_NULL(fdObj)) {
+        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
+                        "Socket closed");
+        return;
+    } else {
+        fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
+    }
+    if (IS_NULL(iaObj)) {
+        JNU_ThrowNullPointerException(env, "iaObj is null.");
+        return;
+    }
+
+    /* bind */
+    if (NET_InetAddressToSockaddr(env, iaObj, localport, (struct sockaddr *)&him, &len, JNI_TRUE) != 0) {
+      return;
+    }
+    setDefaultScopeID(env, (struct sockaddr *)&him);
+
+    if (NET_Bind(fd, (struct sockaddr *)&him, len) < 0) {
+        if (errno == EADDRINUSE || errno == EADDRNOTAVAIL ||
+            errno == EPERM || errno == EACCES) {
+            NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "BindException",
+                           "Bind failed");
+        } else {
+            NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
+                           "Bind failed");
+        }
+        return;
+    }
+
+    /* set the address */
+    (*env)->SetObjectField(env, this, psi_addressID, iaObj);
+
+    /* intialize the local port */
+    if (localport == 0) {
+        /* Now that we're a connected socket, let's extract the port number
+         * that the system chose for us and store it in the Socket object.
+         */
+        if (JVM_GetSockName(fd, (struct sockaddr *)&him, &len) == -1) {
+            NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
+                           "Error getting socket name");
+            return;
+        }
+        localport = NET_GetPortFromSockaddr((struct sockaddr *)&him);
+        (*env)->SetIntField(env, this, psi_localportID, localport);
+    } else {
+        (*env)->SetIntField(env, this, psi_localportID, localport);
+    }
+}
+
+/*
+ * Class:     java_net_PlainSocketImpl
+ * Method:    socketListen
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_java_net_PlainSocketImpl_socketListen (JNIEnv *env, jobject this,
+                                            jint count)
+{
+    /* this FileDescriptor fd field */
+    jobject fdObj = (*env)->GetObjectField(env, this, psi_fdID);
+    /* fdObj's int fd field */
+    int fd;
+
+    if (IS_NULL(fdObj)) {
+        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
+                        "Socket closed");
+        return;
+    } else {
+        fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
+    }
+
+    /*
+     * Workaround for bugid 4101691 in Solaris 2.6. See 4106600.
+     * If listen backlog is Integer.MAX_VALUE then subtract 1.
+     */
+    if (count == 0x7fffffff)
+        count -= 1;
+
+    if (JVM_Listen(fd, count) == JVM_IO_ERR) {
+        NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
+                       "Listen failed");
+    }
+}
+
+/*
+ * Class:     java_net_PlainSocketImpl
+ * Method:    socketAccept
+ * Signature: (Ljava/net/SocketImpl;)V
+ */
+JNIEXPORT void JNICALL
+Java_java_net_PlainSocketImpl_socketAccept(JNIEnv *env, jobject this,
+                                           jobject socket)
+{
+    /* fields on this */
+    int port;
+    jint timeout = (*env)->GetIntField(env, this, psi_timeoutID);
+    jlong prevTime = 0;
+    jobject fdObj = (*env)->GetObjectField(env, this, psi_fdID);
+
+    /* the FileDescriptor field on socket */
+    jobject socketFdObj;
+    /* the InetAddress field on socket */
+    jobject socketAddressObj;
+
+    /* the ServerSocket fd int field on fdObj */
+    jint fd;
+
+    /* accepted fd */
+    jint newfd;
+
+    SOCKADDR him;
+    int len;
+
+    len = SOCKADDR_LEN;
+
+    if (IS_NULL(fdObj)) {
+        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
+                        "Socket closed");
+        return;
+    } else {
+        fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
+    }
+    if (IS_NULL(socket)) {
+        JNU_ThrowNullPointerException(env, "socket is null");
+        return;
+    }
+
+    /*
+     * accept connection but ignore ECONNABORTED indicating that
+     * connection was eagerly accepted by the OS but was reset
+     * before accept() was called.
+     *
+     * If accept timeout in place and timeout is adjusted with
+     * each ECONNABORTED or EWOULDBLOCK to ensure that semantics
+     * of timeout are preserved.
+     */
+    for (;;) {
+        int ret;
+
+        /* first usage pick up current time */
+        if (prevTime == 0 && timeout > 0) {
+            prevTime = JVM_CurrentTimeMillis(env, 0);
+        }
+
+        /* passing a timeout of 0 to poll will return immediately,
+           but in the case of ServerSocket 0 means infinite. */
+        if (timeout <= 0) {
+            ret = NET_Timeout(fd, -1);
+        } else {
+            ret = NET_Timeout(fd, timeout);
+        }
+
+        if (ret == 0) {
+            JNU_ThrowByName(env, JNU_JAVANETPKG "SocketTimeoutException",
+                            "Accept timed out");
+            return;
+        } else if (ret == JVM_IO_ERR) {
+            if (errno == EBADF) {
+               JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Socket closed");
+            } else {
+               NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "Accept failed");
+            }
+            return;
+        } else if (ret == JVM_IO_INTR) {
+            JNU_ThrowByName(env, JNU_JAVAIOPKG "InterruptedIOException",
+                            "operation interrupted");
+            return;
+        }
+
+        newfd = NET_Accept(fd, (struct sockaddr *)&him, (jint*)&len);
+
+        /* connection accepted */
+        if (newfd >= 0) {
+            SET_BLOCKING(newfd);
+            break;
+        }
+
+        /* non (ECONNABORTED or EWOULDBLOCK) error */
+        if (!(errno == ECONNABORTED || errno == EWOULDBLOCK)) {
+            break;
+        }
+
+        /* ECONNABORTED or EWOULDBLOCK error so adjust timeout if there is one. */
+        if (timeout) {
+            jlong currTime = JVM_CurrentTimeMillis(env, 0);
+            timeout -= (currTime - prevTime);
+
+            if (timeout <= 0) {
+                JNU_ThrowByName(env, JNU_JAVANETPKG "SocketTimeoutException",
+                                "Accept timed out");
+                return;
+            }
+            prevTime = currTime;
+        }
+    }
+
+    if (newfd < 0) {
+        if (newfd == -2) {
+            JNU_ThrowByName(env, JNU_JAVAIOPKG "InterruptedIOException",
+                            "operation interrupted");
+        } else {
+            if (errno == EINVAL) {
+                errno = EBADF;
+            }
+            if (errno == EBADF) {
+                JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Socket closed");
+            } else {
+                NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "Accept failed");
+            }
+        }
+        return;
+    }
+
+    /*
+     * fill up the remote peer port and address in the new socket structure.
+     */
+    socketAddressObj = NET_SockaddrToInetAddress(env, (struct sockaddr *)&him, &port);
+    if (socketAddressObj == NULL) {
+        /* should be pending exception */
+        close(newfd);
+        return;
+    }
+
+    /*
+     * Populate SocketImpl.fd.fd
+     */
+    socketFdObj = (*env)->GetObjectField(env, socket, psi_fdID);
+    (*env)->SetIntField(env, socketFdObj, IO_fd_fdID, newfd);
+
+    (*env)->SetObjectField(env, socket, psi_addressID, socketAddressObj);
+    (*env)->SetIntField(env, socket, psi_portID, port);
+    /* also fill up the local port information */
+     port = (*env)->GetIntField(env, this, psi_localportID);
+    (*env)->SetIntField(env, socket, psi_localportID, port);
+}
+
+
+/*
+ * Class:     java_net_PlainSocketImpl
+ * Method:    socketAvailable
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL
+Java_java_net_PlainSocketImpl_socketAvailable(JNIEnv *env, jobject this) {
+
+    jint ret = -1;
+    jobject fdObj = (*env)->GetObjectField(env, this, psi_fdID);
+    jint fd;
+
+    if (IS_NULL(fdObj)) {
+        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
+                        "Socket closed");
+        return -1;
+    } else {
+        fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
+    }
+    /* JVM_SocketAvailable returns 0 for failure, 1 for success */
+    if (!JVM_SocketAvailable(fd, &ret)){
+        if (errno == ECONNRESET) {
+            JNU_ThrowByName(env, "sun/net/ConnectionResetException", "");
+        } else {
+            NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
+                                         "ioctl FIONREAD failed");
+        }
+    }
+    return ret;
+}
+
+/*
+ * Class:     java_net_PlainSocketImpl
+ * Method:    socketClose0
+ * Signature: (Z)V
+ */
+JNIEXPORT void JNICALL
+Java_java_net_PlainSocketImpl_socketClose0(JNIEnv *env, jobject this,
+                                          jboolean useDeferredClose) {
+
+    jobject fdObj = (*env)->GetObjectField(env, this, psi_fdID);
+    jint fd;
+
+    if (IS_NULL(fdObj)) {
+        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
+                        "socket already closed");
+        return;
+    } else {
+        fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
+    }
+    if (fd != -1) {
+        if (useDeferredClose && marker_fd >= 0) {
+            NET_Dup2(marker_fd, fd);
+        } else {
+            (*env)->SetIntField(env, fdObj, IO_fd_fdID, -1);
+            NET_SocketClose(fd);
+        }
+    }
+}
+
+/*
+ * Class:     java_net_PlainSocketImpl
+ * Method:    socketShutdown
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_java_net_PlainSocketImpl_socketShutdown(JNIEnv *env, jobject this,
+                                             jint howto)
+{
+
+    jobject fdObj = (*env)->GetObjectField(env, this, psi_fdID);
+    jint fd;
+
+    /*
+     * WARNING: THIS NEEDS LOCKING. ALSO: SHOULD WE CHECK for fd being
+     * -1 already?
+     */
+    if (IS_NULL(fdObj)) {
+        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
+                        "socket already closed");
+        return;
+    } else {
+        fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
+    }
+    JVM_SocketShutdown(fd, howto);
+}
+
+
+/*
+ * Class:     java_net_PlainSocketImpl
+ * Method:    socketSetOption
+ * Signature: (IZLjava/lang/Object;)V
+ */
+JNIEXPORT void JNICALL
+Java_java_net_PlainSocketImpl_socketSetOption(JNIEnv *env, jobject this,
+                                              jint cmd, jboolean on,
+                                              jobject value) {
+    int fd;
+    int level, optname, optlen;
+    union {
+        int i;
+        struct linger ling;
+    } optval;
+
+    /*
+     * Check that socket hasn't been closed
+     */
+    fd = getFD(env, this);
+    if (fd < 0) {
+        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
+                        "Socket closed");
+        return;
+    }
+
+    /*
+     * SO_TIMEOUT is a no-op on Solaris/Linux
+     */
+    if (cmd == java_net_SocketOptions_SO_TIMEOUT) {
+        return;
+    }
+
+    /*
+     * Map the Java level socket option to the platform specific
+     * level and option name.
+     */
+    if (NET_MapSocketOption(cmd, &level, &optname)) {
+        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Invalid option");
+        return;
+    }
+
+    switch (cmd) {
+        case java_net_SocketOptions_SO_SNDBUF :
+        case java_net_SocketOptions_SO_RCVBUF :
+        case java_net_SocketOptions_SO_LINGER :
+        case java_net_SocketOptions_IP_TOS :
+            {
+                jclass cls;
+                jfieldID fid;
+
+                cls = (*env)->FindClass(env, "java/lang/Integer");
+                CHECK_NULL(cls);
+                fid = (*env)->GetFieldID(env, cls, "value", "I");
+                CHECK_NULL(fid);
+
+                if (cmd == java_net_SocketOptions_SO_LINGER) {
+                    if (on) {
+                        optval.ling.l_onoff = 1;
+                        optval.ling.l_linger = (*env)->GetIntField(env, value, fid);
+                    } else {
+                        optval.ling.l_onoff = 0;
+                        optval.ling.l_linger = 0;
+                    }
+                    optlen = sizeof(optval.ling);
+                } else {
+                    optval.i = (*env)->GetIntField(env, value, fid);
+                    optlen = sizeof(optval.i);
+                }
+
+                break;
+            }
+
+        /* Boolean -> int */
+        default :
+            optval.i = (on ? 1 : 0);
+            optlen = sizeof(optval.i);
+
+    }
+
+    if (NET_SetSockOpt(fd, level, optname, (const void *)&optval, optlen) < 0) {
+#ifdef __solaris__
+        if (errno == EINVAL) {
+            // On Solaris setsockopt will set errno to EINVAL if the socket
+            // is closed. The default error message is then confusing
+            char fullMsg[128];
+            jio_snprintf(fullMsg, sizeof(fullMsg), "Invalid option or socket reset by remote peer");
+            JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", fullMsg);
+            return;
+        }
+#endif /* __solaris__ */
+        NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
+                                      "Error setting socket option");
+    }
+}
+
+/*
+ * Class:     java_net_PlainSocketImpl
+ * Method:    socketGetOption
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL
+Java_java_net_PlainSocketImpl_socketGetOption(JNIEnv *env, jobject this,
+                                              jint cmd, jobject iaContainerObj) {
+
+    int fd;
+    int level, optname, optlen;
+    union {
+        int i;
+        struct linger ling;
+    } optval;
+
+    /*
+     * Check that socket hasn't been closed
+     */
+    fd = getFD(env, this);
+    if (fd < 0) {
+        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
+                        "Socket closed");
+        return -1;
+    }
+
+    /*
+     * SO_BINDADDR isn't a socket option
+     */
+    if (cmd == java_net_SocketOptions_SO_BINDADDR) {
+        SOCKADDR him;
+        socklen_t len = 0;
+        int port;
+        jobject iaObj;
+        jclass iaCntrClass;
+        jfieldID iaFieldID;
+
+        len = SOCKADDR_LEN;
+
+        if (getsockname(fd, (struct sockaddr *)&him, &len) < 0) {
+            NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
+                             "Error getting socket name");
+            return -1;
+        }
+        iaObj = NET_SockaddrToInetAddress(env, (struct sockaddr *)&him, &port);
+        CHECK_NULL_RETURN(iaObj, -1);
+
+        iaCntrClass = (*env)->GetObjectClass(env, iaContainerObj);
+        iaFieldID = (*env)->GetFieldID(env, iaCntrClass, "addr", "Ljava/net/InetAddress;");
+        CHECK_NULL_RETURN(iaFieldID, -1);
+        (*env)->SetObjectField(env, iaContainerObj, iaFieldID, iaObj);
+        return 0; /* notice change from before */
+    }
+
+    /*
+     * Map the Java level socket option to the platform specific
+     * level and option name.
+     */
+    if (NET_MapSocketOption(cmd, &level, &optname)) {
+        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Invalid option");
+        return -1;
+    }
+
+    /*
+     * Args are int except for SO_LINGER
+     */
+    if (cmd == java_net_SocketOptions_SO_LINGER) {
+        optlen = sizeof(optval.ling);
+    } else {
+        optlen = sizeof(optval.i);
+    }
+
+    if (NET_GetSockOpt(fd, level, optname, (void *)&optval, &optlen) < 0) {
+        NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
+                                      "Error getting socket option");
+        return -1;
+    }
+
+    switch (cmd) {
+        case java_net_SocketOptions_SO_LINGER:
+            return (optval.ling.l_onoff ? optval.ling.l_linger: -1);
+
+        case java_net_SocketOptions_SO_SNDBUF:
+        case java_net_SocketOptions_SO_RCVBUF:
+        case java_net_SocketOptions_IP_TOS:
+            return optval.i;
+
+        default :
+            return (optval.i == 0) ? -1 : 1;
+    }
+}
+
+
+/*
+ * Class:     java_net_PlainSocketImpl
+ * Method:    socketSendUrgentData
+ * Signature: (B)V
+ */
+JNIEXPORT void JNICALL
+Java_java_net_PlainSocketImpl_socketSendUrgentData(JNIEnv *env, jobject this,
+                                             jint data) {
+    /* The fd field */
+    jobject fdObj = (*env)->GetObjectField(env, this, psi_fdID);
+    int n, fd;
+    unsigned char d = data & 0xFF;
+
+    if (IS_NULL(fdObj)) {
+        JNU_ThrowByName(env, "java/net/SocketException", "Socket closed");
+        return;
+    } else {
+        fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
+        /* Bug 4086704 - If the Socket associated with this file descriptor
+         * was closed (sysCloseFD), the the file descriptor is set to -1.
+         */
+        if (fd == -1) {
+            JNU_ThrowByName(env, "java/net/SocketException", "Socket closed");
+            return;
+        }
+
+    }
+    n = JVM_Send(fd, (char *)&d, 1, MSG_OOB);
+    if (n == JVM_IO_ERR) {
+        NET_ThrowByNameWithLastError(env, "java/io/IOException", "Write failed");
+        return;
+    }
+    if (n == JVM_IO_INTR) {
+        JNU_ThrowByName(env, "java/io/InterruptedIOException", 0);
+        return;
+    }
+}
diff --git a/ojluni/src/main/native/ProcessEnvironment_md.c b/ojluni/src/main/native/ProcessEnvironment_md.c
new file mode 100755
index 0000000..b946663
--- /dev/null
+++ b/ojluni/src/main/native/ProcessEnvironment_md.c
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include "jni.h"
+#include "jni_util.h"
+
+#ifdef __APPLE__
+#include <crt_externs.h>
+#define environ (*_NSGetEnviron())
+#endif
+
+JNIEXPORT jobjectArray JNICALL
+Java_java_lang_ProcessEnvironment_environ(JNIEnv *env, jclass ign)
+{
+    /* This is one of the rare times it's more portable to declare an
+     * external symbol explicitly, rather than via a system header.
+     * The declaration is standardized as part of UNIX98, but there is
+     * no standard (not even de-facto) header file where the
+     * declaration is to be found.  See:
+     * http://www.opengroup.org/onlinepubs/007908799/xbd/envvar.html */
+#ifndef __APPLE__
+    extern char ** environ; /* environ[i] looks like: VAR=VALUE\0 */
+#endif
+
+    jsize count = 0;
+    jsize i, j;
+    jobjectArray result;
+    jclass byteArrCls = (*env)->FindClass(env, "[B");
+
+    for (i = 0; environ[i]; i++) {
+        /* Ignore corrupted environment variables */
+        if (strchr(environ[i], '=') != NULL)
+            count++;
+    }
+
+    result = (*env)->NewObjectArray(env, 2*count, byteArrCls, 0);
+    if (result == NULL) return NULL;
+
+    for (i = 0, j = 0; environ[i]; i++) {
+        const char * varEnd = strchr(environ[i], '=');
+        /* Ignore corrupted environment variables */
+        if (varEnd != NULL) {
+            jbyteArray var, val;
+            const char * valBeg = varEnd + 1;
+            jsize varLength = varEnd - environ[i];
+            jsize valLength = strlen(valBeg);
+            var = (*env)->NewByteArray(env, varLength);
+            if (var == NULL) return NULL;
+            val = (*env)->NewByteArray(env, valLength);
+            if (val == NULL) return NULL;
+            (*env)->SetByteArrayRegion(env, var, 0, varLength,
+                                       (jbyte*) environ[i]);
+            (*env)->SetByteArrayRegion(env, val, 0, valLength,
+                                       (jbyte*) valBeg);
+            (*env)->SetObjectArrayElement(env, result, 2*j  , var);
+            (*env)->SetObjectArrayElement(env, result, 2*j+1, val);
+            (*env)->DeleteLocalRef(env, var);
+            (*env)->DeleteLocalRef(env, val);
+            j++;
+        }
+    }
+
+    return result;
+}
diff --git a/ojluni/src/main/native/Runtime.c b/ojluni/src/main/native/Runtime.c
new file mode 100755
index 0000000..dece223
--- /dev/null
+++ b/ojluni/src/main/native/Runtime.c
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 1994, 2000, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ *      Link foreign methods.  This first half of this file contains the
+ *      machine independent dynamic linking routines.
+ *      See "BUILD_PLATFORM"/java/lang/linker_md.c to see
+ *      the implementation of this shared dynamic linking
+ *      interface.
+ *
+ *      NOTE - source in this file is POSIX.1 compliant, host
+ *             specific code lives in the platform specific
+ *             code tree.
+ */
+
+#include "jni.h"
+#include "jni_util.h"
+#include "jvm.h"
+
+#include "java_lang_Runtime.h"
+
+JNIEXPORT jlong JNICALL
+Java_java_lang_Runtime_freeMemory(JNIEnv *env, jobject this)
+{
+    return JVM_FreeMemory();
+}
+
+JNIEXPORT jlong JNICALL
+Java_java_lang_Runtime_totalMemory(JNIEnv *env, jobject this)
+{
+    return JVM_TotalMemory();
+}
+
+JNIEXPORT jlong JNICALL
+Java_java_lang_Runtime_maxMemory(JNIEnv *env, jobject this)
+{
+    return JVM_MaxMemory();
+}
+
+JNIEXPORT void JNICALL
+Java_java_lang_Runtime_gc(JNIEnv *env, jobject this)
+{
+    JVM_GC();
+}
+
+JNIEXPORT void JNICALL
+Java_java_lang_Runtime_traceInstructions(JNIEnv *env, jobject this, jboolean on)
+{
+    JVM_TraceInstructions(on);
+}
+
+JNIEXPORT void JNICALL
+Java_java_lang_Runtime_traceMethodCalls(JNIEnv *env, jobject this, jboolean on)
+{
+    JVM_TraceMethodCalls(on);
+}
+
+JNIEXPORT void JNICALL
+Java_java_lang_Runtime_runFinalization0(JNIEnv *env, jobject this)
+{
+    jclass cl;
+    jmethodID mid;
+
+    if ((cl = (*env)->FindClass(env, "java/lang/ref/Finalizer"))
+        && (mid = (*env)->GetStaticMethodID(env, cl,
+                                            "runFinalization", "()V"))) {
+        (*env)->CallStaticVoidMethod(env, cl, mid);
+    }
+}
+
+JNIEXPORT jint JNICALL
+Java_java_lang_Runtime_availableProcessors(JNIEnv *env, jobject this)
+{
+    return JVM_ActiveProcessorCount();
+}
diff --git a/ojluni/src/main/native/Shutdown.c b/ojluni/src/main/native/Shutdown.c
new file mode 100755
index 0000000..f131a24
--- /dev/null
+++ b/ojluni/src/main/native/Shutdown.c
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 1999, 2003, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include "jni.h"
+#include "jni_util.h"
+#include "jvm.h"
+
+#include "java_lang_Shutdown.h"
+
+
+JNIEXPORT void JNICALL
+Java_java_lang_Shutdown_halt0(JNIEnv *env, jclass ignored, jint code)
+{
+    JVM_Halt(code);
+}
+
+
+JNIEXPORT void JNICALL
+Java_java_lang_Shutdown_runAllFinalizers(JNIEnv *env, jclass ignored)
+{
+    jclass cl;
+    jmethodID mid;
+
+    if ((cl = (*env)->FindClass(env, "java/lang/ref/Finalizer"))
+        && (mid = (*env)->GetStaticMethodID(env, cl,
+                                            "runAllFinalizers", "()V"))) {
+        (*env)->CallStaticVoidMethod(env, cl, mid);
+    }
+}
diff --git a/ojluni/src/main/native/Signal.c b/ojluni/src/main/native/Signal.c
new file mode 100755
index 0000000..da1bc19
--- /dev/null
+++ b/ojluni/src/main/native/Signal.c
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 1998, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include <signal.h>
+#include <stdlib.h>
+
+#include <jni.h>
+#include <jvm.h>
+#include <jni_util.h>
+#include <jlong.h>
+#include "sun_misc_Signal.h"
+
+JNIEXPORT jint JNICALL
+Java_sun_misc_Signal_findSignal(JNIEnv *env, jclass cls, jstring name)
+{
+    jint res;
+    const char *cname = (*env)->GetStringUTFChars(env, name, 0);
+    if (cname == NULL) {
+        /* out of memory thrown */
+        return 0;
+    }
+    res = JVM_FindSignal(cname);
+    (*env)->ReleaseStringUTFChars(env, name, cname);
+    return res;
+}
+
+JNIEXPORT jlong JNICALL
+Java_sun_misc_Signal_handle0(JNIEnv *env, jclass cls, jint sig, jlong handler)
+{
+    return ptr_to_jlong(JVM_RegisterSignal(sig, jlong_to_ptr(handler)));
+}
+
+JNIEXPORT void JNICALL
+Java_sun_misc_Signal_raise0(JNIEnv *env, jclass cls, jint sig)
+{
+    JVM_RaiseSignal(sig);
+}
diff --git a/ojluni/src/main/native/SocketInputStream.c b/ojluni/src/main/native/SocketInputStream.c
new file mode 100755
index 0000000..1e115ce
--- /dev/null
+++ b/ojluni/src/main/native/SocketInputStream.c
@@ -0,0 +1,161 @@
+/*
+ * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include "jvm.h"
+#include "jni_util.h"
+#include "net_util.h"
+
+#include "java_net_SocketInputStream.h"
+
+
+/************************************************************************
+ * SocketInputStream
+ */
+
+static jfieldID IO_fd_fdID;
+
+/*
+ * Class:     java_net_SocketInputStream
+ * Method:    init
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL
+Java_java_net_SocketInputStream_init(JNIEnv *env, jclass cls) {
+    IO_fd_fdID = NET_GetFileDescriptorID(env);
+}
+
+/*
+ * Class:     java_net_SocketInputStream
+ * Method:    socketRead0
+ * Signature: (Ljava/io/FileDescriptor;[BIII)I
+ */
+JNIEXPORT jint JNICALL
+Java_java_net_SocketInputStream_socketRead0(JNIEnv *env, jobject this,
+                                            jobject fdObj, jbyteArray data,
+                                            jint off, jint len, jint timeout)
+{
+    char BUF[MAX_BUFFER_LEN];
+    char *bufP;
+    jint fd, nread;
+
+    if (IS_NULL(fdObj)) {
+        /* should't this be a NullPointerException? -br */
+        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
+                        "Socket closed");
+        return -1;
+    } else {
+        fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
+        /* Bug 4086704 - If the Socket associated with this file descriptor
+         * was closed (sysCloseFD), the the file descriptor is set to -1.
+         */
+        if (fd == -1) {
+            JNU_ThrowByName(env, "java/net/SocketException", "Socket closed");
+            return -1;
+        }
+    }
+
+    /*
+     * If the read is greater than our stack allocated buffer then
+     * we allocate from the heap (up to a limit)
+     */
+    if (len > MAX_BUFFER_LEN) {
+        if (len > MAX_HEAP_BUFFER_LEN) {
+            len = MAX_HEAP_BUFFER_LEN;
+        }
+        bufP = (char *)malloc((size_t)len);
+        if (bufP == NULL) {
+            bufP = BUF;
+            len = MAX_BUFFER_LEN;
+        }
+    } else {
+        bufP = BUF;
+    }
+
+    if (timeout) {
+        nread = NET_Timeout(fd, timeout);
+        if (nread <= 0) {
+            if (nread == 0) {
+                JNU_ThrowByName(env, JNU_JAVANETPKG "SocketTimeoutException",
+                            "Read timed out");
+            } else if (nread == JVM_IO_ERR) {
+                if (errno == EBADF) {
+                     JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Socket closed");
+                 } else {
+                     NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
+                                                  "select/poll failed");
+                 }
+            } else if (nread == JVM_IO_INTR) {
+                JNU_ThrowByName(env, JNU_JAVAIOPKG "InterruptedIOException",
+                            "Operation interrupted");
+            }
+            if (bufP != BUF) {
+                free(bufP);
+            }
+            return -1;
+        }
+    }
+
+    nread = NET_Read(fd, bufP, len);
+
+    if (nread <= 0) {
+        if (nread < 0) {
+
+            switch (errno) {
+                case ECONNRESET:
+                case EPIPE:
+                    JNU_ThrowByName(env, "sun/net/ConnectionResetException",
+                        "Connection reset");
+                    break;
+
+                case EBADF:
+                    JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
+                        "Socket closed");
+                    break;
+
+                case EINTR:
+                     JNU_ThrowByName(env, JNU_JAVAIOPKG "InterruptedIOException",
+                           "Operation interrupted");
+                     break;
+
+                default:
+                    NET_ThrowByNameWithLastError(env,
+                        JNU_JAVANETPKG "SocketException", "Read failed");
+            }
+        }
+    } else {
+        (*env)->SetByteArrayRegion(env, data, off, nread, (jbyte *)bufP);
+    }
+
+    if (bufP != BUF) {
+        free(bufP);
+    }
+    return nread;
+}
diff --git a/ojluni/src/main/native/SocketOutputStream.c b/ojluni/src/main/native/SocketOutputStream.c
new file mode 100755
index 0000000..d6e01ff
--- /dev/null
+++ b/ojluni/src/main/native/SocketOutputStream.c
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include "jni_util.h"
+#include "jvm.h"
+#include "net_util.h"
+
+#include "java_net_SocketOutputStream.h"
+
+#define min(a, b)       ((a) < (b) ? (a) : (b))
+
+/*
+ * SocketOutputStream
+ */
+
+static jfieldID IO_fd_fdID;
+
+/*
+ * Class:     java_net_SocketOutputStream
+ * Method:    init
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL
+Java_java_net_SocketOutputStream_init(JNIEnv *env, jclass cls) {
+    IO_fd_fdID = NET_GetFileDescriptorID(env);
+}
+
+/*
+ * Class:     java_net_SocketOutputStream
+ * Method:    socketWrite0
+ * Signature: (Ljava/io/FileDescriptor;[BII)V
+ */
+JNIEXPORT void JNICALL
+Java_java_net_SocketOutputStream_socketWrite0(JNIEnv *env, jobject this,
+                                              jobject fdObj,
+                                              jbyteArray data,
+                                              jint off, jint len) {
+    char *bufP;
+    char BUF[MAX_BUFFER_LEN];
+    int buflen;
+    int fd;
+
+    if (IS_NULL(fdObj)) {
+        JNU_ThrowByName(env, "java/net/SocketException", "Socket closed");
+        return;
+    } else {
+        fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
+        /* Bug 4086704 - If the Socket associated with this file descriptor
+         * was closed (sysCloseFD), the the file descriptor is set to -1.
+         */
+        if (fd == -1) {
+            JNU_ThrowByName(env, "java/net/SocketException", "Socket closed");
+            return;
+        }
+
+    }
+
+    if (len <= MAX_BUFFER_LEN) {
+        bufP = BUF;
+        buflen = MAX_BUFFER_LEN;
+    } else {
+        buflen = min(MAX_HEAP_BUFFER_LEN, len);
+        bufP = (char *)malloc((size_t)buflen);
+
+        /* if heap exhausted resort to stack buffer */
+        if (bufP == NULL) {
+            bufP = BUF;
+            buflen = MAX_BUFFER_LEN;
+        }
+    }
+
+    while(len > 0) {
+        int loff = 0;
+        int chunkLen = min(buflen, len);
+        int llen = chunkLen;
+        (*env)->GetByteArrayRegion(env, data, off, chunkLen, (jbyte *)bufP);
+
+        while(llen > 0) {
+            int n = NET_Send(fd, bufP + loff, llen, 0);
+            if (n > 0) {
+                llen -= n;
+                loff += n;
+                continue;
+            }
+            if (n == JVM_IO_INTR) {
+                JNU_ThrowByName(env, "java/io/InterruptedIOException", 0);
+            } else {
+                if (errno == ECONNRESET) {
+                    JNU_ThrowByName(env, "sun/net/ConnectionResetException",
+                        "Connection reset");
+                } else {
+                    NET_ThrowByNameWithLastError(env, "java/net/SocketException",
+                        "Write failed");
+                }
+            }
+            if (bufP != BUF) {
+                free(bufP);
+            }
+            return;
+        }
+        len -= chunkLen;
+        off += chunkLen;
+    }
+
+    if (bufP != BUF) {
+        free(bufP);
+    }
+}
diff --git a/ojluni/src/main/native/StrictMath.c b/ojluni/src/main/native/StrictMath.c
new file mode 100755
index 0000000..d7c2007
--- /dev/null
+++ b/ojluni/src/main/native/StrictMath.c
@@ -0,0 +1,153 @@
+/*
+ * Copyright (c) 1994, 2003, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include "jni.h"
+#include "fdlibm.h"
+
+#include "java_lang_StrictMath.h"
+
+JNIEXPORT jdouble JNICALL
+Java_java_lang_StrictMath_cos(JNIEnv *env, jclass unused, jdouble d)
+{
+    return (jdouble) jcos((double)d);
+}
+
+JNIEXPORT jdouble JNICALL
+Java_java_lang_StrictMath_sin(JNIEnv *env, jclass unused, jdouble d)
+{
+    return (jdouble) jsin((double)d);
+}
+
+JNIEXPORT jdouble JNICALL
+Java_java_lang_StrictMath_tan(JNIEnv *env, jclass unused, jdouble d)
+{
+    return (jdouble) jtan((double)d);
+}
+
+JNIEXPORT jdouble JNICALL
+Java_java_lang_StrictMath_asin(JNIEnv *env, jclass unused, jdouble d)
+{
+    return (jdouble) jasin((double)d);
+}
+
+JNIEXPORT jdouble JNICALL
+Java_java_lang_StrictMath_acos(JNIEnv *env, jclass unused, jdouble d)
+{
+    return (jdouble) jacos((double)d);
+}
+
+JNIEXPORT jdouble JNICALL
+Java_java_lang_StrictMath_atan(JNIEnv *env, jclass unused, jdouble d)
+{
+    return (jdouble) jatan((double)d);
+}
+
+JNIEXPORT jdouble JNICALL
+Java_java_lang_StrictMath_exp(JNIEnv *env, jclass unused, jdouble d)
+{
+    return (jdouble) jexp((double)d);
+}
+
+JNIEXPORT jdouble JNICALL
+Java_java_lang_StrictMath_log(JNIEnv *env, jclass unused, jdouble d)
+{
+    return (jdouble) jlog((double)d);
+}
+
+JNIEXPORT jdouble JNICALL
+Java_java_lang_StrictMath_log10(JNIEnv *env, jclass unused, jdouble d)
+{
+    return (jdouble) jlog10((double)d);
+}
+
+JNIEXPORT jdouble JNICALL
+Java_java_lang_StrictMath_sqrt(JNIEnv *env, jclass unused, jdouble d)
+{
+    return (jdouble) jsqrt((double)d);
+}
+
+JNIEXPORT jdouble JNICALL
+Java_java_lang_StrictMath_cbrt(JNIEnv *env, jclass unused, jdouble d)
+{
+    return (jdouble) jcbrt((double)d);
+}
+
+JNIEXPORT jdouble JNICALL
+Java_java_lang_StrictMath_atan2(JNIEnv *env, jclass unused, jdouble d1, jdouble d2)
+{
+    return (jdouble) jatan2((double)d1, (double)d2);
+}
+
+JNIEXPORT jdouble JNICALL
+Java_java_lang_StrictMath_pow(JNIEnv *env, jclass unused, jdouble d1, jdouble d2)
+{
+    return (jdouble) jpow((double)d1, (double)d2);
+}
+
+JNIEXPORT jdouble JNICALL
+Java_java_lang_StrictMath_IEEEremainder(JNIEnv *env, jclass unused,
+                                  jdouble dividend,
+                                  jdouble divisor)
+{
+    return (jdouble) jremainder(dividend, divisor);
+}
+
+JNIEXPORT jdouble JNICALL
+Java_java_lang_StrictMath_cosh(JNIEnv *env, jclass unused, jdouble d)
+{
+    return (jdouble) jcosh((double)d);
+}
+
+JNIEXPORT jdouble JNICALL
+Java_java_lang_StrictMath_sinh(JNIEnv *env, jclass unused, jdouble d)
+{
+    return (jdouble) jsinh((double)d);
+}
+
+JNIEXPORT jdouble JNICALL
+Java_java_lang_StrictMath_tanh(JNIEnv *env, jclass unused, jdouble d)
+{
+    return (jdouble) jtanh((double)d);
+}
+
+JNIEXPORT jdouble JNICALL
+Java_java_lang_StrictMath_hypot(JNIEnv *env, jclass unused, jdouble x, jdouble y)
+{
+    return (jdouble) jhypot((double)x, (double)y);
+}
+
+
+
+JNIEXPORT jdouble JNICALL
+Java_java_lang_StrictMath_log1p(JNIEnv *env, jclass unused, jdouble d)
+{
+    return (jdouble) jlog1p((double)d);
+}
+
+JNIEXPORT jdouble JNICALL
+Java_java_lang_StrictMath_expm1(JNIEnv *env, jclass unused, jdouble d)
+{
+    return (jdouble) jexpm1((double)d);
+}
diff --git a/ojluni/src/main/native/String.c b/ojluni/src/main/native/String.c
new file mode 100755
index 0000000..7c8170e
--- /dev/null
+++ b/ojluni/src/main/native/String.c
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 1997, 1998, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include "jvm.h"
+#include "java_lang_String.h"
+
+JNIEXPORT jobject JNICALL
+Java_java_lang_String_intern(JNIEnv *env, jobject this)
+{
+    return JVM_InternString(env, this);
+}
diff --git a/ojluni/src/main/native/System.c b/ojluni/src/main/native/System.c
new file mode 100755
index 0000000..4051bff
--- /dev/null
+++ b/ojluni/src/main/native/System.c
@@ -0,0 +1,473 @@
+/*
+ * Copyright (c) 1994, 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include <string.h>
+
+#include "jni.h"
+#include "jni_util.h"
+#include "jvm.h"
+#include "java_props.h"
+
+#include "java_lang_System.h"
+
+#define OBJ "Ljava/lang/Object;"
+
+/* Only register the performance-critical methods */
+static JNINativeMethod methods[] = {
+    {"currentTimeMillis", "()J",              (void *)&JVM_CurrentTimeMillis},
+    {"nanoTime",          "()J",              (void *)&JVM_NanoTime},
+    {"arraycopy",     "(" OBJ "I" OBJ "II)V", (void *)&JVM_ArrayCopy},
+};
+
+#undef OBJ
+
+JNIEXPORT void JNICALL
+Java_java_lang_System_registerNatives(JNIEnv *env, jclass cls)
+{
+    (*env)->RegisterNatives(env, cls,
+                            methods, sizeof(methods)/sizeof(methods[0]));
+}
+
+JNIEXPORT jint JNICALL
+Java_java_lang_System_identityHashCode(JNIEnv *env, jobject this, jobject x)
+{
+    return JVM_IHashCode(env, x);
+}
+
+#define PUTPROP(props, key, val) \
+    if (1) { \
+        jstring jkey = (*env)->NewStringUTF(env, key); \
+        jstring jval = (*env)->NewStringUTF(env, val); \
+        jobject r = (*env)->CallObjectMethod(env, props, putID, jkey, jval); \
+        if ((*env)->ExceptionOccurred(env)) return NULL; \
+        (*env)->DeleteLocalRef(env, jkey); \
+        (*env)->DeleteLocalRef(env, jval); \
+        (*env)->DeleteLocalRef(env, r); \
+    } else ((void) 0)
+
+/*  "key" is a char type string with only ASCII character in it.
+    "val" is a nchar (typedefed in java_props.h) type string  */
+
+#define PUTPROP_ForPlatformNString(props, key, val) \
+    if (1) { \
+        jstring jkey = (*env)->NewStringUTF(env, key);  \
+        jstring jval = GetStringPlatform(env, val); \
+        jobject r = (*env)->CallObjectMethod(env, props, putID, jkey, jval); \
+        if ((*env)->ExceptionOccurred(env)) return NULL; \
+        (*env)->DeleteLocalRef(env, jkey); \
+        (*env)->DeleteLocalRef(env, jval); \
+        (*env)->DeleteLocalRef(env, r); \
+    } else ((void) 0)
+#define REMOVEPROP(props, key) \
+    if (1) { \
+        jstring jkey = JNU_NewStringPlatform(env, key); \
+        jobject r = (*env)->CallObjectMethod(env, props, removeID, jkey); \
+        if ((*env)->ExceptionOccurred(env)) return NULL; \
+        (*env)->DeleteLocalRef(env, jkey); \
+        (*env)->DeleteLocalRef(env, r); \
+    } else ((void) 0)
+#define GETPROP(props, key, jret) \
+    if (1) { \
+        jstring jkey = JNU_NewStringPlatform(env, key); \
+        jret = (*env)->CallObjectMethod(env, props, getPropID, jkey); \
+        if ((*env)->ExceptionOccurred(env)) return NULL; \
+        (*env)->DeleteLocalRef(env, jkey); \
+    } else ((void) 0)
+
+#ifndef VENDOR /* Third party may overwrite this. */
+#define VENDOR "Oracle Corporation"
+#define VENDOR_URL "http://java.oracle.com/"
+#define VENDOR_URL_BUG "http://bugreport.sun.com/bugreport/"
+#endif
+
+#define JAVA_MAX_SUPPORTED_VERSION 51
+#define JAVA_MAX_SUPPORTED_MINOR_VERSION 0
+
+#ifdef JAVA_SPECIFICATION_VENDOR /* Third party may NOT overwrite this. */
+  #error "ERROR: No override of JAVA_SPECIFICATION_VENDOR is allowed"
+#else
+  #define JAVA_SPECIFICATION_VENDOR "Oracle Corporation"
+#endif
+
+static int fmtdefault; // boolean value
+jobject fillI18nProps(JNIEnv *env, jobject props, char *baseKey,
+                      char *platformDispVal, char *platformFmtVal,
+                      jmethodID putID, jmethodID getPropID) {
+    jstring jVMBaseVal = NULL;
+
+    GETPROP(props, baseKey, jVMBaseVal);
+    if (jVMBaseVal) {
+        // user specified the base property.  there's nothing to do here.
+        (*env)->DeleteLocalRef(env, jVMBaseVal);
+    } else {
+        char buf[64];
+        jstring jVMVal = NULL;
+        const char *baseVal = "";
+
+        /* user.xxx base property */
+        if (fmtdefault) {
+            if (platformFmtVal) {
+                PUTPROP(props, baseKey, platformFmtVal);
+                baseVal = platformFmtVal;
+            }
+        } else {
+            if (platformDispVal) {
+                PUTPROP(props, baseKey, platformDispVal);
+                baseVal = platformDispVal;
+            }
+        }
+
+        /* user.xxx.display property */
+        jio_snprintf(buf, sizeof(buf), "%s.display", baseKey);
+        GETPROP(props, buf, jVMVal);
+        if (jVMVal == NULL) {
+            if (platformDispVal && (strcmp(baseVal, platformDispVal) != 0)) {
+                PUTPROP(props, buf, platformDispVal);
+            }
+        } else {
+            (*env)->DeleteLocalRef(env, jVMVal);
+        }
+
+        /* user.xxx.format property */
+        jio_snprintf(buf, sizeof(buf), "%s.format", baseKey);
+        GETPROP(props, buf, jVMVal);
+        if (jVMVal == NULL) {
+            if (platformFmtVal && (strcmp(baseVal, platformFmtVal) != 0)) {
+                PUTPROP(props, buf, platformFmtVal);
+            }
+        } else {
+            (*env)->DeleteLocalRef(env, jVMVal);
+        }
+    }
+
+    return NULL;
+}
+
+JNIEXPORT jobject JNICALL
+Java_java_lang_System_initProperties(JNIEnv *env, jclass cla, jobject props)
+{
+    char buf[128];
+    java_props_t *sprops = GetJavaProperties(env);
+    jmethodID putID = (*env)->GetMethodID(env,
+                                          (*env)->GetObjectClass(env, props),
+                                          "put",
+            "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
+    jmethodID removeID = (*env)->GetMethodID(env,
+                                          (*env)->GetObjectClass(env, props),
+                                          "remove",
+            "(Ljava/lang/Object;)Ljava/lang/Object;");
+    jmethodID getPropID = (*env)->GetMethodID(env,
+                                          (*env)->GetObjectClass(env, props),
+                                          "getProperty",
+            "(Ljava/lang/String;)Ljava/lang/String;");
+    jobject ret = NULL;
+    jstring jVMVal = NULL;
+
+    if (sprops == NULL || putID == NULL ) return NULL;
+
+    PUTPROP(props, "java.specification.version",
+            JDK_MAJOR_VERSION "." JDK_MINOR_VERSION);
+    PUTPROP(props, "java.specification.name",
+            "Java Platform API Specification");
+    PUTPROP(props, "java.specification.vendor",
+            JAVA_SPECIFICATION_VENDOR);
+
+    PUTPROP(props, "java.version", RELEASE);
+    PUTPROP(props, "java.vendor", VENDOR);
+    PUTPROP(props, "java.vendor.url", VENDOR_URL);
+    PUTPROP(props, "java.vendor.url.bug", VENDOR_URL_BUG);
+
+    jio_snprintf(buf, sizeof(buf), "%d.%d", JAVA_MAX_SUPPORTED_VERSION,
+                                            JAVA_MAX_SUPPORTED_MINOR_VERSION);
+    PUTPROP(props, "java.class.version", buf);
+
+    if (sprops->awt_toolkit) {
+        PUTPROP(props, "awt.toolkit", sprops->awt_toolkit);
+    }
+
+    /* os properties */
+    PUTPROP(props, "os.name", sprops->os_name);
+    PUTPROP(props, "os.version", sprops->os_version);
+    PUTPROP(props, "os.arch", sprops->os_arch);
+
+    /* file system properties */
+    PUTPROP(props, "file.separator", sprops->file_separator);
+    PUTPROP(props, "path.separator", sprops->path_separator);
+    PUTPROP(props, "line.separator", sprops->line_separator);
+
+    /*
+     *  user.language
+     *  user.script, user.country, user.variant (if user's environment specifies them)
+     *  file.encoding
+     *  file.encoding.pkg
+     */
+    PUTPROP(props, "user.language", sprops->language);
+    if (sprops->script) {
+        PUTPROP(props, "user.script", sprops->script);
+    }
+    if (sprops->country) {
+        PUTPROP(props, "user.country", sprops->country);
+    }
+    if (sprops->variant) {
+        PUTPROP(props, "user.variant", sprops->variant);
+    }
+    PUTPROP(props, "file.encoding", sprops->encoding);
+    PUTPROP(props, "sun.jnu.encoding", sprops->sun_jnu_encoding);
+    PUTPROP(props, "file.encoding.pkg", "sun.io");
+    /* unicode_encoding specifies the default endianness */
+    PUTPROP(props, "sun.io.unicode.encoding", sprops->unicode_encoding);
+    PUTPROP(props, "sun.cpu.isalist",
+            (sprops->cpu_isalist ? sprops->cpu_isalist : ""));
+    PUTPROP(props, "sun.cpu.endian",  sprops->cpu_endian);
+
+
+#ifdef MACOSX
+    /* Proxy setting properties */
+    if (sprops->httpProxyEnabled) {
+        PUTPROP(props, "http.proxyHost", sprops->httpHost);
+        PUTPROP(props, "http.proxyPort", sprops->httpPort);
+    }
+
+    if (sprops->httpsProxyEnabled) {
+        PUTPROP(props, "https.proxyHost", sprops->httpsHost);
+        PUTPROP(props, "https.proxyPort", sprops->httpsPort);
+    }
+
+    if (sprops->ftpProxyEnabled) {
+        PUTPROP(props, "ftp.proxyHost", sprops->ftpHost);
+        PUTPROP(props, "ftp.proxyPort", sprops->ftpPort);
+    }
+
+    if (sprops->socksProxyEnabled) {
+        PUTPROP(props, "socksProxyHost", sprops->socksHost);
+        PUTPROP(props, "socksProxyPort", sprops->socksPort);
+    }
+
+    if (sprops->gopherProxyEnabled) {
+        // The gopher client is different in that it expects an 'is this set?' flag that the others don't.
+        PUTPROP(props, "gopherProxySet", "true");
+        PUTPROP(props, "gopherProxyHost", sprops->gopherHost);
+        PUTPROP(props, "gopherProxyPort", sprops->gopherPort);
+    } else {
+        PUTPROP(props, "gopherProxySet", "false");
+    }
+
+    // Mac OS X only has a single proxy exception list which applies
+    // to all protocols
+    if (sprops->exceptionList) {
+        PUTPROP(props, "http.nonProxyHosts", sprops->exceptionList);
+        // HTTPS: implementation in jsse.jar uses http.nonProxyHosts
+        PUTPROP(props, "ftp.nonProxyHosts", sprops->exceptionList);
+        PUTPROP(props, "socksNonProxyHosts", sprops->exceptionList);
+    }
+#endif
+
+    /* !!! DO NOT call PUTPROP_ForPlatformNString before this line !!!
+     * !!! I18n properties have not been set up yet !!!
+     */
+
+    /* Printing properties */
+    /* Note: java.awt.printerjob is an implementation private property which
+     * just happens to have a java.* name because it is referenced in
+     * a java.awt class. It is the mechanism by which the implementation
+     * finds the appropriate class in the JRE for the platform.
+     * It is explicitly not designed to be overridden by clients as
+     * a way of replacing the implementation class, and in any case
+     * the mechanism by which the class is loaded is constrained to only
+     * find and load classes that are part of the JRE.
+     * This property may be removed if that mechanism is redesigned
+     */
+    PUTPROP(props, "java.awt.printerjob", sprops->printerJob);
+
+    /* data model */
+    if (sizeof(sprops) == 4) {
+        sprops->data_model = "32";
+    } else if (sizeof(sprops) == 8) {
+        sprops->data_model = "64";
+    } else {
+        sprops->data_model = "unknown";
+    }
+    PUTPROP(props, "sun.arch.data.model",  \
+                    sprops->data_model);
+
+    /* patch level */
+    PUTPROP(props, "sun.os.patch.level",  \
+                    sprops->patch_level);
+
+    /* Java2D properties */
+    /* Note: java.awt.graphicsenv is an implementation private property which
+     * just happens to have a java.* name because it is referenced in
+     * a java.awt class. It is the mechanism by which the implementation
+     * finds the appropriate class in the JRE for the platform.
+     * It is explicitly not designed to be overridden by clients as
+     * a way of replacing the implementation class, and in any case
+     * the mechanism by which the class is loaded is constrained to only
+     * find and load classes that are part of the JRE.
+     * This property may be removed if that mechanism is redesigned
+     */
+    PUTPROP(props, "java.awt.graphicsenv", sprops->graphics_env);
+    if (sprops->font_dir != NULL) {
+        PUTPROP_ForPlatformNString(props,
+                                   "sun.java2d.fontpath", sprops->font_dir);
+    }
+
+    PUTPROP_ForPlatformNString(props, "java.io.tmpdir", sprops->tmp_dir);
+
+    PUTPROP_ForPlatformNString(props, "user.name", sprops->user_name);
+    PUTPROP_ForPlatformNString(props, "user.home", sprops->user_home);
+
+    PUTPROP(props, "user.timezone", sprops->timezone);
+
+    PUTPROP_ForPlatformNString(props, "user.dir", sprops->user_dir);
+
+    /* This is a sun. property as it is currently only set for Gnome and
+     * Windows desktops.
+     */
+    if (sprops->desktop != NULL) {
+        PUTPROP(props, "sun.desktop", sprops->desktop);
+    }
+
+    /*
+     * unset "user.language", "user.script", "user.country", and "user.variant"
+     * in order to tell whether the command line option "-DXXXX=YYYY" is
+     * specified or not.  They will be reset in fillI18nProps() below.
+     */
+    REMOVEPROP(props, "user.language");
+    REMOVEPROP(props, "user.script");
+    REMOVEPROP(props, "user.country");
+    REMOVEPROP(props, "user.variant");
+    REMOVEPROP(props, "file.encoding");
+
+    ret = JVM_InitProperties(env, props);
+
+    /* Check the compatibility flag */
+    GETPROP(props, "sun.locale.formatasdefault", jVMVal);
+    if (jVMVal) {
+        const char * val = (*env)->GetStringUTFChars(env, jVMVal, 0);
+        fmtdefault = !strcmp(val, "true");
+        (*env)->ReleaseStringUTFChars(env, jVMVal, val);
+        (*env)->DeleteLocalRef(env, jVMVal);
+    }
+
+    /* reconstruct i18n related properties */
+    fillI18nProps(env, props, "user.language", sprops->display_language,
+        sprops->format_language, putID, getPropID);
+    fillI18nProps(env, props, "user.script",
+        sprops->display_script, sprops->format_script, putID, getPropID);
+    fillI18nProps(env, props, "user.country",
+        sprops->display_country, sprops->format_country, putID, getPropID);
+    fillI18nProps(env, props, "user.variant",
+        sprops->display_variant, sprops->format_variant, putID, getPropID);
+    GETPROP(props, "file.encoding", jVMVal);
+    if (jVMVal == NULL) {
+#ifdef MACOSX
+        /*
+         * Since sun_jnu_encoding is now hard-coded to UTF-8 on Mac, we don't
+         * want to use it to overwrite file.encoding
+         */
+        PUTPROP(props, "file.encoding", sprops->encoding);
+#else
+        if (fmtdefault) {
+            PUTPROP(props, "file.encoding", sprops->encoding);
+        } else {
+            PUTPROP(props, "file.encoding", sprops->sun_jnu_encoding);
+        }
+#endif
+    } else {
+        (*env)->DeleteLocalRef(env, jVMVal);
+    }
+
+    return ret;
+}
+
+/*
+ * The following three functions implement setter methods for
+ * java.lang.System.{in, out, err}. They are natively implemented
+ * because they violate the semantics of the language (i.e. set final
+ * variable).
+ */
+JNIEXPORT void JNICALL
+Java_java_lang_System_setIn0(JNIEnv *env, jclass cla, jobject stream)
+{
+    jfieldID fid =
+        (*env)->GetStaticFieldID(env,cla,"in","Ljava/io/InputStream;");
+    if (fid == 0)
+        return;
+    (*env)->SetStaticObjectField(env,cla,fid,stream);
+}
+
+JNIEXPORT void JNICALL
+Java_java_lang_System_setOut0(JNIEnv *env, jclass cla, jobject stream)
+{
+    jfieldID fid =
+        (*env)->GetStaticFieldID(env,cla,"out","Ljava/io/PrintStream;");
+    if (fid == 0)
+        return;
+    (*env)->SetStaticObjectField(env,cla,fid,stream);
+}
+
+JNIEXPORT void JNICALL
+Java_java_lang_System_setErr0(JNIEnv *env, jclass cla, jobject stream)
+{
+    jfieldID fid =
+        (*env)->GetStaticFieldID(env,cla,"err","Ljava/io/PrintStream;");
+    if (fid == 0)
+        return;
+    (*env)->SetStaticObjectField(env,cla,fid,stream);
+}
+
+static void cpchars(jchar *dst, char *src, int n)
+{
+    int i;
+    for (i = 0; i < n; i++) {
+        dst[i] = src[i];
+    }
+}
+
+JNIEXPORT jstring JNICALL
+Java_java_lang_System_mapLibraryName(JNIEnv *env, jclass ign, jstring libname)
+{
+    int len;
+    int prefix_len = (int) strlen(JNI_LIB_PREFIX);
+    int suffix_len = (int) strlen(JNI_LIB_SUFFIX);
+
+    jchar chars[256];
+    if (libname == NULL) {
+        JNU_ThrowNullPointerException(env, 0);
+        return NULL;
+    }
+    len = (*env)->GetStringLength(env, libname);
+    if (len > 240) {
+        JNU_ThrowIllegalArgumentException(env, "name too long");
+        return NULL;
+    }
+    cpchars(chars, JNI_LIB_PREFIX, prefix_len);
+    (*env)->GetStringRegion(env, libname, 0, len, chars + prefix_len);
+    len += prefix_len;
+    cpchars(chars + len, JNI_LIB_SUFFIX, suffix_len);
+    len += suffix_len;
+
+    return (*env)->NewString(env, chars, len);
+}
diff --git a/ojluni/src/main/native/Thread.c b/ojluni/src/main/native/Thread.c
new file mode 100755
index 0000000..cfbc7fd
--- /dev/null
+++ b/ojluni/src/main/native/Thread.c
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 1994, 2003, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*-
+ *      Stuff for dealing with threads.
+ *      originally in threadruntime.c, Sun Sep 22 12:09:39 1991
+ */
+
+#include "jni.h"
+#include "jvm.h"
+
+#include "java_lang_Thread.h"
+
+#define THD "Ljava/lang/Thread;"
+#define OBJ "Ljava/lang/Object;"
+#define STE "Ljava/lang/StackTraceElement;"
+#define STR "Ljava/lang/String;"
+
+#define ARRAY_LENGTH(a) (sizeof(a)/sizeof(a[0]))
+
+static JNINativeMethod methods[] = {
+    {"start0",           "()V",        (void *)&JVM_StartThread},
+    {"stop0",            "(" OBJ ")V", (void *)&JVM_StopThread},
+    {"isAlive",          "()Z",        (void *)&JVM_IsThreadAlive},
+    {"suspend0",         "()V",        (void *)&JVM_SuspendThread},
+    {"resume0",          "()V",        (void *)&JVM_ResumeThread},
+    {"setPriority0",     "(I)V",       (void *)&JVM_SetThreadPriority},
+    {"yield",            "()V",        (void *)&JVM_Yield},
+    {"sleep",            "(J)V",       (void *)&JVM_Sleep},
+    {"currentThread",    "()" THD,     (void *)&JVM_CurrentThread},
+    {"countStackFrames", "()I",        (void *)&JVM_CountStackFrames},
+    {"interrupt0",       "()V",        (void *)&JVM_Interrupt},
+    {"isInterrupted",    "(Z)Z",       (void *)&JVM_IsInterrupted},
+    {"holdsLock",        "(" OBJ ")Z", (void *)&JVM_HoldsLock},
+    {"getThreads",        "()[" THD,   (void *)&JVM_GetAllThreads},
+    {"dumpThreads",      "([" THD ")[[" STE, (void *)&JVM_DumpThreads},
+    {"setNativeName",    "(" STR ")V", (void *)&JVM_SetNativeThreadName},
+};
+
+#undef THD
+#undef OBJ
+#undef STE
+#undef STR
+
+JNIEXPORT void JNICALL
+Java_java_lang_Thread_registerNatives(JNIEnv *env, jclass cls)
+{
+    (*env)->RegisterNatives(env, cls, methods, ARRAY_LENGTH(methods));
+}
diff --git a/ojluni/src/main/native/Throwable.c b/ojluni/src/main/native/Throwable.c
new file mode 100755
index 0000000..aaf3c26
--- /dev/null
+++ b/ojluni/src/main/native/Throwable.c
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 1994, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ *      Implementation of class Throwable
+ *
+ *      former classruntime.c, Wed Jun 26 18:43:20 1991
+ */
+
+#include <stdio.h>
+#include <signal.h>
+
+#include "jni.h"
+#include "jvm.h"
+
+#include "java_lang_Throwable.h"
+
+/*
+ * Fill in the current stack trace in this exception.  This is
+ * usually called automatically when the exception is created but it
+ * may also be called explicitly by the user.  This routine returns
+ * `this' so you can write 'throw e.fillInStackTrace();'
+ */
+JNIEXPORT jobject JNICALL
+Java_java_lang_Throwable_fillInStackTrace(JNIEnv *env, jobject throwable, int dummy)
+{
+    JVM_FillInStackTrace(env, throwable);
+    return throwable;
+}
+
+JNIEXPORT jint JNICALL
+Java_java_lang_Throwable_getStackTraceDepth(JNIEnv *env, jobject throwable)
+{
+    return JVM_GetStackTraceDepth(env, throwable);
+}
+
+JNIEXPORT jobject JNICALL
+Java_java_lang_Throwable_getStackTraceElement(JNIEnv *env,
+                                              jobject throwable, jint index)
+{
+    return JVM_GetStackTraceElement(env, throwable, index);
+}
diff --git a/ojluni/src/main/native/UNIXProcess_md.c b/ojluni/src/main/native/UNIXProcess_md.c
new file mode 100755
index 0000000..6904a44
--- /dev/null
+++ b/ojluni/src/main/native/UNIXProcess_md.c
@@ -0,0 +1,965 @@
+/*
+ * Copyright (c) 1995, 2008, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#undef  _LARGEFILE64_SOURCE
+#define _LARGEFILE64_SOURCE 1
+
+#include "jni.h"
+#include "jvm.h"
+#include "jvm_md.h"
+#include "jni_util.h"
+#include "io_util.h"
+
+/*
+ * Platform-specific support for java.lang.Process
+ */
+#include <assert.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <ctype.h>
+#ifdef _ALLBSD_SOURCE
+#include <sys/wait.h>
+#else
+#include <wait.h>
+#endif
+#include <signal.h>
+#include <string.h>
+#include <errno.h>
+#include <dirent.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <limits.h>
+
+#ifdef __APPLE__
+#include <crt_externs.h>
+#define environ (*_NSGetEnviron())
+#endif
+
+/*
+ * There are 3 possible strategies we might use to "fork":
+ *
+ * - fork(2).  Very portable and reliable but subject to
+ *   failure due to overcommit (see the documentation on
+ *   /proc/sys/vm/overcommit_memory in Linux proc(5)).
+ *   This is the ancient problem of spurious failure whenever a large
+ *   process starts a small subprocess.
+ *
+ * - vfork().  Using this is scary because all relevant man pages
+ *   contain dire warnings, e.g. Linux vfork(2).  But at least it's
+ *   documented in the glibc docs and is standardized by XPG4.
+ *   http://www.opengroup.org/onlinepubs/000095399/functions/vfork.html
+ *   On Linux, one might think that vfork() would be implemented using
+ *   the clone system call with flag CLONE_VFORK, but in fact vfork is
+ *   a separate system call (which is a good sign, suggesting that
+ *   vfork will continue to be supported at least on Linux).
+ *   Another good sign is that glibc implements posix_spawn using
+ *   vfork whenever possible.  Note that we cannot use posix_spawn
+ *   ourselves because there's no reliable way to close all inherited
+ *   file descriptors.
+ *
+ * - clone() with flags CLONE_VM but not CLONE_THREAD.  clone() is
+ *   Linux-specific, but this ought to work - at least the glibc
+ *   sources contain code to handle different combinations of CLONE_VM
+ *   and CLONE_THREAD.  However, when this was implemented, it
+ *   appeared to fail on 32-bit i386 (but not 64-bit x86_64) Linux with
+ *   the simple program
+ *     Runtime.getRuntime().exec("/bin/true").waitFor();
+ *   with:
+ *     #  Internal Error (os_linux_x86.cpp:683), pid=19940, tid=2934639536
+ *     #  Error: pthread_getattr_np failed with errno = 3 (ESRCH)
+ *   We believe this is a glibc bug, reported here:
+ *     http://sources.redhat.com/bugzilla/show_bug.cgi?id=10311
+ *   but the glibc maintainers closed it as WONTFIX.
+ *
+ * Based on the above analysis, we are currently using vfork() on
+ * Linux and fork() on other Unix systems, but the code to use clone()
+ * remains.
+ */
+
+#define START_CHILD_USE_CLONE 0  /* clone() currently disabled; see above. */
+
+#ifndef START_CHILD_USE_CLONE
+  #ifdef __linux__
+    #define START_CHILD_USE_CLONE 1
+  #else
+    #define START_CHILD_USE_CLONE 0
+  #endif
+#endif
+
+/* By default, use vfork() on Linux. */
+#ifndef START_CHILD_USE_VFORK
+  #ifdef __linux__
+    #define START_CHILD_USE_VFORK 1
+  #else
+    #define START_CHILD_USE_VFORK 0
+  #endif
+#endif
+
+#if START_CHILD_USE_CLONE
+#include <sched.h>
+#define START_CHILD_SYSTEM_CALL "clone"
+#elif START_CHILD_USE_VFORK
+#define START_CHILD_SYSTEM_CALL "vfork"
+#else
+#define START_CHILD_SYSTEM_CALL "fork"
+#endif
+
+#ifndef STDIN_FILENO
+#define STDIN_FILENO 0
+#endif
+
+#ifndef STDOUT_FILENO
+#define STDOUT_FILENO 1
+#endif
+
+#ifndef STDERR_FILENO
+#define STDERR_FILENO 2
+#endif
+
+#ifndef SA_NOCLDSTOP
+#define SA_NOCLDSTOP 0
+#endif
+
+#ifndef SA_RESTART
+#define SA_RESTART 0
+#endif
+
+#define FAIL_FILENO (STDERR_FILENO + 1)
+
+/* TODO: Refactor. */
+#define RESTARTABLE(_cmd, _result) do { \
+  do { \
+    _result = _cmd; \
+  } while((_result == -1) && (errno == EINTR)); \
+} while(0)
+
+/* This is one of the rare times it's more portable to declare an
+ * external symbol explicitly, rather than via a system header.
+ * The declaration is standardized as part of UNIX98, but there is
+ * no standard (not even de-facto) header file where the
+ * declaration is to be found.  See:
+ * http://www.opengroup.org/onlinepubs/009695399/functions/environ.html
+ * http://www.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_02.html
+ *
+ * "All identifiers in this volume of IEEE Std 1003.1-2001, except
+ * environ, are defined in at least one of the headers" (!)
+ */
+extern char **environ;
+
+
+static void
+setSIGCHLDHandler(JNIEnv *env)
+{
+    /* There is a subtle difference between having the signal handler
+     * for SIGCHLD be SIG_DFL and SIG_IGN.  We cannot obtain process
+     * termination information for child processes if the signal
+     * handler is SIG_IGN.  It must be SIG_DFL.
+     *
+     * We used to set the SIGCHLD handler only on Linux, but it's
+     * safest to set it unconditionally.
+     *
+     * Consider what happens if java's parent process sets the SIGCHLD
+     * handler to SIG_IGN.  Normally signal handlers are inherited by
+     * children, but SIGCHLD is a controversial case.  Solaris appears
+     * to always reset it to SIG_DFL, but this behavior may be
+     * non-standard-compliant, and we shouldn't rely on it.
+     *
+     * References:
+     * http://www.opengroup.org/onlinepubs/7908799/xsh/exec.html
+     * http://www.pasc.org/interps/unofficial/db/p1003.1/pasc-1003.1-132.html
+     */
+    struct sigaction sa;
+    sa.sa_handler = SIG_DFL;
+    sigemptyset(&sa.sa_mask);
+    sa.sa_flags = SA_NOCLDSTOP | SA_RESTART;
+    if (sigaction(SIGCHLD, &sa, NULL) < 0)
+        JNU_ThrowInternalError(env, "Can't set SIGCHLD handler");
+}
+
+static void*
+xmalloc(JNIEnv *env, size_t size)
+{
+    void *p = malloc(size);
+    if (p == NULL)
+        JNU_ThrowOutOfMemoryError(env, NULL);
+    return p;
+}
+
+#define NEW(type, n) ((type *) xmalloc(env, (n) * sizeof(type)))
+
+/**
+ * If PATH is not defined, the OS provides some default value.
+ * Unfortunately, there's no portable way to get this value.
+ * Fortunately, it's only needed if the child has PATH while we do not.
+ */
+static const char*
+defaultPath(void)
+{
+#ifdef __solaris__
+    /* These really are the Solaris defaults! */
+    return (geteuid() == 0 || getuid() == 0) ?
+        "/usr/xpg4/bin:/usr/ccs/bin:/usr/bin:/opt/SUNWspro/bin:/usr/sbin" :
+        "/usr/xpg4/bin:/usr/ccs/bin:/usr/bin:/opt/SUNWspro/bin:";
+#else
+    return ":/bin:/usr/bin";    /* glibc */
+#endif
+}
+
+static const char*
+effectivePath(void)
+{
+    const char *s = getenv("PATH");
+    return (s != NULL) ? s : defaultPath();
+}
+
+static int
+countOccurrences(const char *s, char c)
+{
+    int count;
+    for (count = 0; *s != '\0'; s++)
+        count += (*s == c);
+    return count;
+}
+
+static const char * const *
+splitPath(JNIEnv *env, const char *path)
+{
+    const char *p, *q;
+    char **pathv;
+    int i;
+    int count = countOccurrences(path, ':') + 1;
+
+    pathv = NEW(char*, count+1);
+    pathv[count] = NULL;
+    for (p = path, i = 0; i < count; i++, p = q + 1) {
+        for (q = p; (*q != ':') && (*q != '\0'); q++)
+            ;
+        if (q == p)             /* empty PATH component => "." */
+            pathv[i] = "./";
+        else {
+            int addSlash = ((*(q - 1)) != '/');
+            pathv[i] = NEW(char, q - p + addSlash + 1);
+            memcpy(pathv[i], p, q - p);
+            if (addSlash)
+                pathv[i][q - p] = '/';
+            pathv[i][q - p + addSlash] = '\0';
+        }
+    }
+    return (const char * const *) pathv;
+}
+
+/**
+ * Cached value of JVM's effective PATH.
+ * (We don't support putenv("PATH=...") in native code)
+ */
+static const char *parentPath;
+
+/**
+ * Split, canonicalized version of parentPath
+ */
+static const char * const *parentPathv;
+
+static jfieldID field_exitcode;
+
+JNIEXPORT void JNICALL
+Java_java_lang_UNIXProcess_initIDs(JNIEnv *env, jclass clazz)
+{
+    field_exitcode = (*env)->GetFieldID(env, clazz, "exitcode", "I");
+
+    parentPath  = effectivePath();
+    parentPathv = splitPath(env, parentPath);
+
+    setSIGCHLDHandler(env);
+}
+
+
+#ifndef WIFEXITED
+#define WIFEXITED(status) (((status)&0xFF) == 0)
+#endif
+
+#ifndef WEXITSTATUS
+#define WEXITSTATUS(status) (((status)>>8)&0xFF)
+#endif
+
+#ifndef WIFSIGNALED
+#define WIFSIGNALED(status) (((status)&0xFF) > 0 && ((status)&0xFF00) == 0)
+#endif
+
+#ifndef WTERMSIG
+#define WTERMSIG(status) ((status)&0x7F)
+#endif
+
+/* Block until a child process exits and return its exit code.
+   Note, can only be called once for any given pid. */
+JNIEXPORT jint JNICALL
+Java_java_lang_UNIXProcess_waitForProcessExit(JNIEnv* env,
+                                              jobject junk,
+                                              jint pid)
+{
+    /* We used to use waitid() on Solaris, waitpid() on Linux, but
+     * waitpid() is more standard, so use it on all POSIX platforms. */
+    int status;
+    /* Wait for the child process to exit.  This returns immediately if
+       the child has already exited. */
+    while (waitpid(pid, &status, 0) < 0) {
+        switch (errno) {
+        case ECHILD: return 0;
+        case EINTR: break;
+        default: return -1;
+        }
+    }
+
+    if (WIFEXITED(status)) {
+        /*
+         * The child exited normally; get its exit code.
+         */
+        return WEXITSTATUS(status);
+    } else if (WIFSIGNALED(status)) {
+        /* The child exited because of a signal.
+         * The best value to return is 0x80 + signal number,
+         * because that is what all Unix shells do, and because
+         * it allows callers to distinguish between process exit and
+         * process death by signal.
+         * Unfortunately, the historical behavior on Solaris is to return
+         * the signal number, and we preserve this for compatibility. */
+#ifdef __solaris__
+        return WTERMSIG(status);
+#else
+        return 0x80 + WTERMSIG(status);
+#endif
+    } else {
+        /*
+         * Unknown exit code; pass it through.
+         */
+        return status;
+    }
+}
+
+static ssize_t
+restartableWrite(int fd, const void *buf, size_t count)
+{
+    ssize_t result;
+    RESTARTABLE(write(fd, buf, count), result);
+    return result;
+}
+
+static int
+restartableDup2(int fd_from, int fd_to)
+{
+    int err;
+    RESTARTABLE(dup2(fd_from, fd_to), err);
+    return err;
+}
+
+static int
+restartableClose(int fd)
+{
+    int err;
+    RESTARTABLE(close(fd), err);
+    return err;
+}
+
+static int
+closeSafely(int fd)
+{
+    return (fd == -1) ? 0 : restartableClose(fd);
+}
+
+static int
+isAsciiDigit(char c)
+{
+  return c >= '0' && c <= '9';
+}
+
+#ifdef _ALLBSD_SOURCE
+#define FD_DIR "/dev/fd"
+#define dirent64 dirent
+#define readdir64 readdir
+#else
+#define FD_DIR "/proc/self/fd"
+#endif
+
+static int
+closeDescriptors(void)
+{
+    DIR *dp;
+    struct dirent64 *dirp;
+    int from_fd = FAIL_FILENO + 1;
+
+    /* We're trying to close all file descriptors, but opendir() might
+     * itself be implemented using a file descriptor, and we certainly
+     * don't want to close that while it's in use.  We assume that if
+     * opendir() is implemented using a file descriptor, then it uses
+     * the lowest numbered file descriptor, just like open().  So we
+     * close a couple explicitly.  */
+
+    restartableClose(from_fd);          /* for possible use by opendir() */
+    restartableClose(from_fd + 1);      /* another one for good luck */
+
+    if ((dp = opendir(FD_DIR)) == NULL)
+        return 0;
+
+    /* We use readdir64 instead of readdir to work around Solaris bug
+     * 6395699: /proc/self/fd fails to report file descriptors >= 1024 on Solaris 9
+     */
+    while ((dirp = readdir64(dp)) != NULL) {
+        int fd;
+        if (isAsciiDigit(dirp->d_name[0]) &&
+            (fd = strtol(dirp->d_name, NULL, 10)) >= from_fd + 2)
+            restartableClose(fd);
+    }
+
+    closedir(dp);
+
+    return 1;
+}
+
+static int
+moveDescriptor(int fd_from, int fd_to)
+{
+    if (fd_from != fd_to) {
+        if ((restartableDup2(fd_from, fd_to) == -1) ||
+            (restartableClose(fd_from) == -1))
+            return -1;
+    }
+    return 0;
+}
+
+static const char *
+getBytes(JNIEnv *env, jbyteArray arr)
+{
+    return arr == NULL ? NULL :
+        (const char*) (*env)->GetByteArrayElements(env, arr, NULL);
+}
+
+static void
+releaseBytes(JNIEnv *env, jbyteArray arr, const char* parr)
+{
+    if (parr != NULL)
+        (*env)->ReleaseByteArrayElements(env, arr, (jbyte*) parr, JNI_ABORT);
+}
+
+static void
+initVectorFromBlock(const char**vector, const char* block, int count)
+{
+    int i;
+    const char *p;
+    for (i = 0, p = block; i < count; i++) {
+        /* Invariant: p always points to the start of a C string. */
+        vector[i] = p;
+        while (*(p++));
+    }
+    vector[count] = NULL;
+}
+
+static void
+throwIOException(JNIEnv *env, int errnum, const char *defaultDetail)
+{
+    static const char * const format = "error=%d, %s";
+    const char *detail = defaultDetail;
+    char *errmsg;
+    jstring s;
+
+    if (errnum != 0) {
+        const char *s = strerror(errnum);
+        if (strcmp(s, "Unknown error") != 0)
+            detail = s;
+    }
+    /* ASCII Decimal representation uses 2.4 times as many bits as binary. */
+    errmsg = NEW(char, strlen(format) + strlen(detail) + 3 * sizeof(errnum));
+    sprintf(errmsg, format, errnum, detail);
+    s = JNU_NewStringPlatform(env, errmsg);
+    if (s != NULL) {
+        jobject x = JNU_NewObjectByName(env, "java/io/IOException",
+                                        "(Ljava/lang/String;)V", s);
+        if (x != NULL)
+            (*env)->Throw(env, x);
+    }
+    free(errmsg);
+}
+
+#ifdef DEBUG_PROCESS
+/* Debugging process code is difficult; where to write debug output? */
+static void
+debugPrint(char *format, ...)
+{
+    FILE *tty = fopen("/dev/tty", "w");
+    va_list ap;
+    va_start(ap, format);
+    vfprintf(tty, format, ap);
+    va_end(ap);
+    fclose(tty);
+}
+#endif /* DEBUG_PROCESS */
+
+/**
+ * Exec FILE as a traditional Bourne shell script (i.e. one without #!).
+ * If we could do it over again, we would probably not support such an ancient
+ * misfeature, but compatibility wins over sanity.  The original support for
+ * this was imported accidentally from execvp().
+ */
+static void
+execve_as_traditional_shell_script(const char *file,
+                                   const char *argv[],
+                                   const char *const envp[])
+{
+    /* Use the extra word of space provided for us in argv by caller. */
+    const char *argv0 = argv[0];
+    const char *const *end = argv;
+    while (*end != NULL)
+        ++end;
+    memmove(argv+2, argv+1, (end-argv) * sizeof (*end));
+    argv[0] = "/bin/sh";
+    argv[1] = file;
+    execve(argv[0], (char **) argv, (char **) envp);
+    /* Can't even exec /bin/sh?  Big trouble, but let's soldier on... */
+    memmove(argv+1, argv+2, (end-argv) * sizeof (*end));
+    argv[0] = argv0;
+}
+
+/**
+ * Like execve(2), except that in case of ENOEXEC, FILE is assumed to
+ * be a shell script and the system default shell is invoked to run it.
+ */
+static void
+execve_with_shell_fallback(const char *file,
+                           const char *argv[],
+                           const char *const envp[])
+{
+#if START_CHILD_USE_CLONE || START_CHILD_USE_VFORK
+    /* shared address space; be very careful. */
+    execve(file, (char **) argv, (char **) envp);
+    if (errno == ENOEXEC)
+        execve_as_traditional_shell_script(file, argv, envp);
+#else
+    /* unshared address space; we can mutate environ. */
+    environ = (char **) envp;
+    execvp(file, (char **) argv);
+#endif
+}
+
+/**
+ * 'execvpe' should have been included in the Unix standards,
+ * and is a GNU extension in glibc 2.10.
+ *
+ * JDK_execvpe is identical to execvp, except that the child environment is
+ * specified via the 3rd argument instead of being inherited from environ.
+ */
+static void
+JDK_execvpe(const char *file,
+            const char *argv[],
+            const char *const envp[])
+{
+    if (envp == NULL || (char **) envp == environ) {
+        execvp(file, (char **) argv);
+        return;
+    }
+
+    if (*file == '\0') {
+        errno = ENOENT;
+        return;
+    }
+
+    if (strchr(file, '/') != NULL) {
+        execve_with_shell_fallback(file, argv, envp);
+    } else {
+        /* We must search PATH (parent's, not child's) */
+        char expanded_file[PATH_MAX];
+        int filelen = strlen(file);
+        int sticky_errno = 0;
+        const char * const * dirs;
+        for (dirs = parentPathv; *dirs; dirs++) {
+            const char * dir = *dirs;
+            int dirlen = strlen(dir);
+            if (filelen + dirlen + 1 >= PATH_MAX) {
+                errno = ENAMETOOLONG;
+                continue;
+            }
+            memcpy(expanded_file, dir, dirlen);
+            memcpy(expanded_file + dirlen, file, filelen);
+            expanded_file[dirlen + filelen] = '\0';
+            execve_with_shell_fallback(expanded_file, argv, envp);
+            /* There are 3 responses to various classes of errno:
+             * return immediately, continue (especially for ENOENT),
+             * or continue with "sticky" errno.
+             *
+             * From exec(3):
+             *
+             * If permission is denied for a file (the attempted
+             * execve returned EACCES), these functions will continue
+             * searching the rest of the search path.  If no other
+             * file is found, however, they will return with the
+             * global variable errno set to EACCES.
+             */
+            switch (errno) {
+            case EACCES:
+                sticky_errno = errno;
+                /* FALLTHRU */
+            case ENOENT:
+            case ENOTDIR:
+#ifdef ELOOP
+            case ELOOP:
+#endif
+#ifdef ESTALE
+            case ESTALE:
+#endif
+#ifdef ENODEV
+            case ENODEV:
+#endif
+#ifdef ETIMEDOUT
+            case ETIMEDOUT:
+#endif
+                break; /* Try other directories in PATH */
+            default:
+                return;
+            }
+        }
+        if (sticky_errno != 0)
+            errno = sticky_errno;
+    }
+}
+
+/*
+ * Reads nbyte bytes from file descriptor fd into buf,
+ * The read operation is retried in case of EINTR or partial reads.
+ *
+ * Returns number of bytes read (normally nbyte, but may be less in
+ * case of EOF).  In case of read errors, returns -1 and sets errno.
+ */
+static ssize_t
+readFully(int fd, void *buf, size_t nbyte)
+{
+    ssize_t remaining = nbyte;
+    for (;;) {
+        ssize_t n = read(fd, buf, remaining);
+        if (n == 0) {
+            return nbyte - remaining;
+        } else if (n > 0) {
+            remaining -= n;
+            if (remaining <= 0)
+                return nbyte;
+            /* We were interrupted in the middle of reading the bytes.
+             * Unlikely, but possible. */
+            buf = (void *) (((char *)buf) + n);
+        } else if (errno == EINTR) {
+            /* Strange signals like SIGJVM1 are possible at any time.
+             * See http://www.dreamsongs.com/WorseIsBetter.html */
+        } else {
+            return -1;
+        }
+    }
+}
+
+typedef struct _ChildStuff
+{
+    int in[2];
+    int out[2];
+    int err[2];
+    int fail[2];
+    int fds[3];
+    const char **argv;
+    const char **envv;
+    const char *pdir;
+    jboolean redirectErrorStream;
+#if START_CHILD_USE_CLONE
+    void *clone_stack;
+#endif
+} ChildStuff;
+
+static void
+copyPipe(int from[2], int to[2])
+{
+    to[0] = from[0];
+    to[1] = from[1];
+}
+
+/**
+ * Child process after a successful fork() or clone().
+ * This function must not return, and must be prepared for either all
+ * of its address space to be shared with its parent, or to be a copy.
+ * It must not modify global variables such as "environ".
+ */
+static int
+childProcess(void *arg)
+{
+    const ChildStuff* p = (const ChildStuff*) arg;
+
+    /* Close the parent sides of the pipes.
+       Closing pipe fds here is redundant, since closeDescriptors()
+       would do it anyways, but a little paranoia is a good thing. */
+    if ((closeSafely(p->in[1])   == -1) ||
+        (closeSafely(p->out[0])  == -1) ||
+        (closeSafely(p->err[0])  == -1) ||
+        (closeSafely(p->fail[0]) == -1))
+        goto WhyCantJohnnyExec;
+
+    /* Give the child sides of the pipes the right fileno's. */
+    /* Note: it is possible for in[0] == 0 */
+    if ((moveDescriptor(p->in[0] != -1 ?  p->in[0] : p->fds[0],
+                        STDIN_FILENO) == -1) ||
+        (moveDescriptor(p->out[1]!= -1 ? p->out[1] : p->fds[1],
+                        STDOUT_FILENO) == -1))
+        goto WhyCantJohnnyExec;
+
+    if (p->redirectErrorStream) {
+        if ((closeSafely(p->err[1]) == -1) ||
+            (restartableDup2(STDOUT_FILENO, STDERR_FILENO) == -1))
+            goto WhyCantJohnnyExec;
+    } else {
+        if (moveDescriptor(p->err[1] != -1 ? p->err[1] : p->fds[2],
+                           STDERR_FILENO) == -1)
+            goto WhyCantJohnnyExec;
+    }
+
+    if (moveDescriptor(p->fail[1], FAIL_FILENO) == -1)
+        goto WhyCantJohnnyExec;
+
+    /* close everything */
+    if (closeDescriptors() == 0) { /* failed,  close the old way */
+        int max_fd = (int)sysconf(_SC_OPEN_MAX);
+        int fd;
+        for (fd = FAIL_FILENO + 1; fd < max_fd; fd++)
+            if (restartableClose(fd) == -1 && errno != EBADF)
+                goto WhyCantJohnnyExec;
+    }
+
+    /* change to the new working directory */
+    if (p->pdir != NULL && chdir(p->pdir) < 0)
+        goto WhyCantJohnnyExec;
+
+    if (fcntl(FAIL_FILENO, F_SETFD, FD_CLOEXEC) == -1)
+        goto WhyCantJohnnyExec;
+
+    JDK_execvpe(p->argv[0], p->argv, p->envv);
+
+ WhyCantJohnnyExec:
+    /* We used to go to an awful lot of trouble to predict whether the
+     * child would fail, but there is no reliable way to predict the
+     * success of an operation without *trying* it, and there's no way
+     * to try a chdir or exec in the parent.  Instead, all we need is a
+     * way to communicate any failure back to the parent.  Easy; we just
+     * send the errno back to the parent over a pipe in case of failure.
+     * The tricky thing is, how do we communicate the *success* of exec?
+     * We use FD_CLOEXEC together with the fact that a read() on a pipe
+     * yields EOF when the write ends (we have two of them!) are closed.
+     */
+    {
+        int errnum = errno;
+        restartableWrite(FAIL_FILENO, &errnum, sizeof(errnum));
+    }
+    restartableClose(FAIL_FILENO);
+    _exit(-1);
+    return 0;  /* Suppress warning "no return value from function" */
+}
+
+/**
+ * Start a child process running function childProcess.
+ * This function only returns in the parent.
+ * We are unusually paranoid; use of clone/vfork is
+ * especially likely to tickle gcc/glibc bugs.
+ */
+#ifdef __attribute_noinline__  /* See: sys/cdefs.h */
+__attribute_noinline__
+#endif
+static pid_t
+startChild(ChildStuff *c) {
+#if START_CHILD_USE_CLONE
+#define START_CHILD_CLONE_STACK_SIZE (64 * 1024)
+    /*
+     * See clone(2).
+     * Instead of worrying about which direction the stack grows, just
+     * allocate twice as much and start the stack in the middle.
+     */
+    if ((c->clone_stack = malloc(2 * START_CHILD_CLONE_STACK_SIZE)) == NULL)
+        /* errno will be set to ENOMEM */
+        return -1;
+    return clone(childProcess,
+                 c->clone_stack + START_CHILD_CLONE_STACK_SIZE,
+                 CLONE_VFORK | CLONE_VM | SIGCHLD, c);
+#else
+  #if START_CHILD_USE_VFORK
+    /*
+     * We separate the call to vfork into a separate function to make
+     * very sure to keep stack of child from corrupting stack of parent,
+     * as suggested by the scary gcc warning:
+     *  warning: variable 'foo' might be clobbered by 'longjmp' or 'vfork'
+     */
+    volatile pid_t resultPid = vfork();
+  #else
+    /*
+     * From Solaris fork(2): In Solaris 10, a call to fork() is
+     * identical to a call to fork1(); only the calling thread is
+     * replicated in the child process. This is the POSIX-specified
+     * behavior for fork().
+     */
+    pid_t resultPid = fork();
+  #endif
+    if (resultPid == 0)
+        childProcess(c);
+    assert(resultPid != 0);  /* childProcess never returns */
+    return resultPid;
+#endif /* ! START_CHILD_USE_CLONE */
+}
+
+JNIEXPORT jint JNICALL
+Java_java_lang_UNIXProcess_forkAndExec(JNIEnv *env,
+                                       jobject process,
+                                       jbyteArray prog,
+                                       jbyteArray argBlock, jint argc,
+                                       jbyteArray envBlock, jint envc,
+                                       jbyteArray dir,
+                                       jintArray std_fds,
+                                       jboolean redirectErrorStream)
+{
+    int errnum;
+    int resultPid = -1;
+    int in[2], out[2], err[2], fail[2];
+    jint *fds = NULL;
+    const char *pprog = NULL;
+    const char *pargBlock = NULL;
+    const char *penvBlock = NULL;
+    ChildStuff *c;
+
+    in[0] = in[1] = out[0] = out[1] = err[0] = err[1] = fail[0] = fail[1] = -1;
+
+    if ((c = NEW(ChildStuff, 1)) == NULL) return -1;
+    c->argv = NULL;
+    c->envv = NULL;
+    c->pdir = NULL;
+#if START_CHILD_USE_CLONE
+    c->clone_stack = NULL;
+#endif
+
+    /* Convert prog + argBlock into a char ** argv.
+     * Add one word room for expansion of argv for use by
+     * execve_as_traditional_shell_script.
+     */
+    assert(prog != NULL && argBlock != NULL);
+    if ((pprog     = getBytes(env, prog))       == NULL) goto Catch;
+    if ((pargBlock = getBytes(env, argBlock))   == NULL) goto Catch;
+    if ((c->argv = NEW(const char *, argc + 3)) == NULL) goto Catch;
+    c->argv[0] = pprog;
+    initVectorFromBlock(c->argv+1, pargBlock, argc);
+
+    if (envBlock != NULL) {
+        /* Convert envBlock into a char ** envv */
+        if ((penvBlock = getBytes(env, envBlock))   == NULL) goto Catch;
+        if ((c->envv = NEW(const char *, envc + 1)) == NULL) goto Catch;
+        initVectorFromBlock(c->envv, penvBlock, envc);
+    }
+
+    if (dir != NULL) {
+        if ((c->pdir = getBytes(env, dir)) == NULL) goto Catch;
+    }
+
+    assert(std_fds != NULL);
+    fds = (*env)->GetIntArrayElements(env, std_fds, NULL);
+    if (fds == NULL) goto Catch;
+
+    if ((fds[0] == -1 && pipe(in)  < 0) ||
+        (fds[1] == -1 && pipe(out) < 0) ||
+        (fds[2] == -1 && pipe(err) < 0) ||
+        (pipe(fail) < 0)) {
+        throwIOException(env, errno, "Bad file descriptor");
+        goto Catch;
+    }
+    c->fds[0] = fds[0];
+    c->fds[1] = fds[1];
+    c->fds[2] = fds[2];
+
+    copyPipe(in,   c->in);
+    copyPipe(out,  c->out);
+    copyPipe(err,  c->err);
+    copyPipe(fail, c->fail);
+
+    c->redirectErrorStream = redirectErrorStream;
+
+    resultPid = startChild(c);
+    assert(resultPid != 0);
+
+    if (resultPid < 0) {
+        throwIOException(env, errno, START_CHILD_SYSTEM_CALL " failed");
+        goto Catch;
+    }
+
+    restartableClose(fail[1]); fail[1] = -1; /* See: WhyCantJohnnyExec */
+
+    switch (readFully(fail[0], &errnum, sizeof(errnum))) {
+    case 0: break; /* Exec succeeded */
+    case sizeof(errnum):
+        waitpid(resultPid, NULL, 0);
+        throwIOException(env, errnum, "Exec failed");
+        goto Catch;
+    default:
+        throwIOException(env, errno, "Read failed");
+        goto Catch;
+    }
+
+    fds[0] = (in [1] != -1) ? in [1] : -1;
+    fds[1] = (out[0] != -1) ? out[0] : -1;
+    fds[2] = (err[0] != -1) ? err[0] : -1;
+
+ Finally:
+#if START_CHILD_USE_CLONE
+    free(c->clone_stack);
+#endif
+
+    /* Always clean up the child's side of the pipes */
+    closeSafely(in [0]);
+    closeSafely(out[1]);
+    closeSafely(err[1]);
+
+    /* Always clean up fail descriptors */
+    closeSafely(fail[0]);
+    closeSafely(fail[1]);
+
+    releaseBytes(env, prog,     pprog);
+    releaseBytes(env, argBlock, pargBlock);
+    releaseBytes(env, envBlock, penvBlock);
+    releaseBytes(env, dir,      c->pdir);
+
+    free(c->argv);
+    free(c->envv);
+    free(c);
+
+    if (fds != NULL)
+        (*env)->ReleaseIntArrayElements(env, std_fds, fds, 0);
+
+    return resultPid;
+
+ Catch:
+    /* Clean up the parent's side of the pipes in case of failure only */
+    closeSafely(in [1]);
+    closeSafely(out[0]);
+    closeSafely(err[0]);
+    goto Finally;
+}
+
+JNIEXPORT void JNICALL
+Java_java_lang_UNIXProcess_destroyProcess(JNIEnv *env, jobject junk, jint pid)
+{
+    kill(pid, SIGTERM);
+}
diff --git a/ojluni/src/main/native/UnixFileSystem_md.c b/ojluni/src/main/native/UnixFileSystem_md.c
new file mode 100755
index 0000000..4309ffb
--- /dev/null
+++ b/ojluni/src/main/native/UnixFileSystem_md.c
@@ -0,0 +1,455 @@
+/*
+ * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include <assert.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/stat.h>
+#include <sys/statvfs.h>
+#include <string.h>
+#include <stdlib.h>
+#include <dlfcn.h>
+#include <limits.h>
+
+#include "jni.h"
+#include "jni_util.h"
+#include "jlong.h"
+#include "jvm.h"
+#include "io_util.h"
+#include "io_util_md.h"
+#include "java_io_FileSystem.h"
+#include "java_io_UnixFileSystem.h"
+
+#if defined(_ALLBSD_SOURCE)
+#define dirent64 dirent
+#define readdir64_r readdir_r
+#define stat64 stat
+#define statvfs64 statvfs
+#endif
+
+/* -- Field IDs -- */
+
+static struct {
+    jfieldID path;
+} ids;
+
+
+JNIEXPORT void JNICALL
+Java_java_io_UnixFileSystem_initIDs(JNIEnv *env, jclass cls)
+{
+    jclass fileClass = (*env)->FindClass(env, "java/io/File");
+    if (!fileClass) return;
+    ids.path = (*env)->GetFieldID(env, fileClass,
+                                  "path", "Ljava/lang/String;");
+}
+
+/* -- Path operations -- */
+
+extern int canonicalize(char *path, const char *out, int len);
+
+JNIEXPORT jstring JNICALL
+Java_java_io_UnixFileSystem_canonicalize0(JNIEnv *env, jobject this,
+                                          jstring pathname)
+{
+    jstring rv = NULL;
+
+    WITH_PLATFORM_STRING(env, pathname, path) {
+        char canonicalPath[JVM_MAXPATHLEN];
+        if (canonicalize(JVM_NativePath((char *)path),
+                         canonicalPath, JVM_MAXPATHLEN) < 0) {
+            JNU_ThrowIOExceptionWithLastError(env, "Bad pathname");
+        } else {
+#ifdef MACOSX
+            rv = newStringPlatform(env, canonicalPath);
+#else
+            rv = JNU_NewStringPlatform(env, canonicalPath);
+#endif
+        }
+    } END_PLATFORM_STRING(env, path);
+    return rv;
+}
+
+
+/* -- Attribute accessors -- */
+
+
+static jboolean
+statMode(const char *path, int *mode)
+{
+    struct stat64 sb;
+    if (stat64(path, &sb) == 0) {
+        *mode = sb.st_mode;
+        return JNI_TRUE;
+    }
+    return JNI_FALSE;
+}
+
+
+JNIEXPORT jint JNICALL
+Java_java_io_UnixFileSystem_getBooleanAttributes0(JNIEnv *env, jobject this,
+                                                  jobject file)
+{
+    jint rv = 0;
+
+    WITH_FIELD_PLATFORM_STRING(env, file, ids.path, path) {
+        int mode;
+        if (statMode(path, &mode)) {
+            int fmt = mode & S_IFMT;
+            rv = (jint) (java_io_FileSystem_BA_EXISTS
+                  | ((fmt == S_IFREG) ? java_io_FileSystem_BA_REGULAR : 0)
+                  | ((fmt == S_IFDIR) ? java_io_FileSystem_BA_DIRECTORY : 0));
+        }
+    } END_PLATFORM_STRING(env, path);
+    return rv;
+}
+
+JNIEXPORT jboolean JNICALL
+Java_java_io_UnixFileSystem_checkAccess(JNIEnv *env, jobject this,
+                                        jobject file, jint a)
+{
+    jboolean rv = JNI_FALSE;
+    int mode = 0;
+    switch (a) {
+    case java_io_FileSystem_ACCESS_READ:
+        mode = R_OK;
+        break;
+    case java_io_FileSystem_ACCESS_WRITE:
+        mode = W_OK;
+        break;
+    case java_io_FileSystem_ACCESS_EXECUTE:
+        mode = X_OK;
+        break;
+    default: assert(0);
+    }
+    WITH_FIELD_PLATFORM_STRING(env, file, ids.path, path) {
+        if (access(path, mode) == 0) {
+            rv = JNI_TRUE;
+        }
+    } END_PLATFORM_STRING(env, path);
+    return rv;
+}
+
+
+JNIEXPORT jboolean JNICALL
+Java_java_io_UnixFileSystem_setPermission(JNIEnv *env, jobject this,
+                                          jobject file,
+                                          jint access,
+                                          jboolean enable,
+                                          jboolean owneronly)
+{
+    jboolean rv = JNI_FALSE;
+
+    WITH_FIELD_PLATFORM_STRING(env, file, ids.path, path) {
+        int amode = 0;
+        int mode;
+        switch (access) {
+        case java_io_FileSystem_ACCESS_READ:
+            if (owneronly)
+                amode = S_IRUSR;
+            else
+                amode = S_IRUSR | S_IRGRP | S_IROTH;
+            break;
+        case java_io_FileSystem_ACCESS_WRITE:
+            if (owneronly)
+                amode = S_IWUSR;
+            else
+                amode = S_IWUSR | S_IWGRP | S_IWOTH;
+            break;
+        case java_io_FileSystem_ACCESS_EXECUTE:
+            if (owneronly)
+                amode = S_IXUSR;
+            else
+                amode = S_IXUSR | S_IXGRP | S_IXOTH;
+            break;
+        default:
+            assert(0);
+        }
+        if (statMode(path, &mode)) {
+            if (enable)
+                mode |= amode;
+            else
+                mode &= ~amode;
+            if (chmod(path, mode) >= 0) {
+                rv = JNI_TRUE;
+            }
+        }
+    } END_PLATFORM_STRING(env, path);
+    return rv;
+}
+
+JNIEXPORT jlong JNICALL
+Java_java_io_UnixFileSystem_getLastModifiedTime(JNIEnv *env, jobject this,
+                                                jobject file)
+{
+    jlong rv = 0;
+
+    WITH_FIELD_PLATFORM_STRING(env, file, ids.path, path) {
+        struct stat64 sb;
+        if (stat64(path, &sb) == 0) {
+            rv = 1000 * (jlong)sb.st_mtime;
+        }
+    } END_PLATFORM_STRING(env, path);
+    return rv;
+}
+
+
+JNIEXPORT jlong JNICALL
+Java_java_io_UnixFileSystem_getLength(JNIEnv *env, jobject this,
+                                      jobject file)
+{
+    jlong rv = 0;
+
+    WITH_FIELD_PLATFORM_STRING(env, file, ids.path, path) {
+        struct stat64 sb;
+        if (stat64(path, &sb) == 0) {
+            rv = sb.st_size;
+        }
+    } END_PLATFORM_STRING(env, path);
+    return rv;
+}
+
+
+/* -- File operations -- */
+
+
+JNIEXPORT jboolean JNICALL
+Java_java_io_UnixFileSystem_createFileExclusively(JNIEnv *env, jclass cls,
+                                                  jstring pathname)
+{
+    jboolean rv = JNI_FALSE;
+
+    WITH_PLATFORM_STRING(env, pathname, path) {
+        int fd;
+        if (!strcmp (path, "/")) {
+            fd = JVM_EEXIST;    /* The root directory always exists */
+        } else {
+            fd = JVM_Open(path, JVM_O_RDWR | JVM_O_CREAT | JVM_O_EXCL, 0666);
+        }
+        if (fd < 0) {
+            if (fd != JVM_EEXIST) {
+                JNU_ThrowIOExceptionWithLastError(env, path);
+            }
+        } else {
+            JVM_Close(fd);
+            rv = JNI_TRUE;
+        }
+    } END_PLATFORM_STRING(env, path);
+    return rv;
+}
+
+
+JNIEXPORT jboolean JNICALL
+Java_java_io_UnixFileSystem_delete0(JNIEnv *env, jobject this,
+                                    jobject file)
+{
+    jboolean rv = JNI_FALSE;
+
+    WITH_FIELD_PLATFORM_STRING(env, file, ids.path, path) {
+        if (remove(path) == 0) {
+            rv = JNI_TRUE;
+        }
+    } END_PLATFORM_STRING(env, path);
+    return rv;
+}
+
+
+JNIEXPORT jobjectArray JNICALL
+Java_java_io_UnixFileSystem_list(JNIEnv *env, jobject this,
+                                 jobject file)
+{
+    DIR *dir = NULL;
+    struct dirent64 *ptr;
+    struct dirent64 *result;
+    int len, maxlen;
+    jobjectArray rv, old;
+
+    WITH_FIELD_PLATFORM_STRING(env, file, ids.path, path) {
+        dir = opendir(path);
+    } END_PLATFORM_STRING(env, path);
+    if (dir == NULL) return NULL;
+
+    ptr = malloc(sizeof(struct dirent64) + (PATH_MAX + 1));
+    if (ptr == NULL) {
+        JNU_ThrowOutOfMemoryError(env, "heap allocation failed");
+        closedir(dir);
+        return NULL;
+    }
+
+    /* Allocate an initial String array */
+    len = 0;
+    maxlen = 16;
+    rv = (*env)->NewObjectArray(env, maxlen, JNU_ClassString(env), NULL);
+    if (rv == NULL) goto error;
+
+    /* Scan the directory */
+    while ((readdir64_r(dir, ptr, &result) == 0)  && (result != NULL)) {
+        jstring name;
+        if (!strcmp(ptr->d_name, ".") || !strcmp(ptr->d_name, ".."))
+            continue;
+        if (len == maxlen) {
+            old = rv;
+            rv = (*env)->NewObjectArray(env, maxlen <<= 1,
+                                        JNU_ClassString(env), NULL);
+            if (rv == NULL) goto error;
+            if (JNU_CopyObjectArray(env, rv, old, len) < 0) goto error;
+            (*env)->DeleteLocalRef(env, old);
+        }
+#ifdef MACOSX
+        name = newStringPlatform(env, ptr->d_name);
+#else
+        name = JNU_NewStringPlatform(env, ptr->d_name);
+#endif
+        if (name == NULL) goto error;
+        (*env)->SetObjectArrayElement(env, rv, len++, name);
+        (*env)->DeleteLocalRef(env, name);
+    }
+    closedir(dir);
+    free(ptr);
+
+    /* Copy the final results into an appropriately-sized array */
+    old = rv;
+    rv = (*env)->NewObjectArray(env, len, JNU_ClassString(env), NULL);
+    if (rv == NULL) {
+        return NULL;
+    }
+    if (JNU_CopyObjectArray(env, rv, old, len) < 0) {
+        return NULL;
+    }
+    return rv;
+
+ error:
+    closedir(dir);
+    free(ptr);
+    return NULL;
+}
+
+
+JNIEXPORT jboolean JNICALL
+Java_java_io_UnixFileSystem_createDirectory(JNIEnv *env, jobject this,
+                                            jobject file)
+{
+    jboolean rv = JNI_FALSE;
+
+    WITH_FIELD_PLATFORM_STRING(env, file, ids.path, path) {
+        if (mkdir(path, 0777) == 0) {
+            rv = JNI_TRUE;
+        }
+    } END_PLATFORM_STRING(env, path);
+    return rv;
+}
+
+
+JNIEXPORT jboolean JNICALL
+Java_java_io_UnixFileSystem_rename0(JNIEnv *env, jobject this,
+                                    jobject from, jobject to)
+{
+    jboolean rv = JNI_FALSE;
+
+    WITH_FIELD_PLATFORM_STRING(env, from, ids.path, fromPath) {
+        WITH_FIELD_PLATFORM_STRING(env, to, ids.path, toPath) {
+            if (rename(fromPath, toPath) == 0) {
+                rv = JNI_TRUE;
+            }
+        } END_PLATFORM_STRING(env, toPath);
+    } END_PLATFORM_STRING(env, fromPath);
+    return rv;
+}
+
+JNIEXPORT jboolean JNICALL
+Java_java_io_UnixFileSystem_setLastModifiedTime(JNIEnv *env, jobject this,
+                                                jobject file, jlong time)
+{
+    jboolean rv = JNI_FALSE;
+
+    WITH_FIELD_PLATFORM_STRING(env, file, ids.path, path) {
+        struct stat64 sb;
+
+        if (stat64(path, &sb) == 0) {
+            struct timeval tv[2];
+
+            /* Preserve access time */
+            tv[0].tv_sec = sb.st_atime;
+            tv[0].tv_usec = 0;
+
+            /* Change last-modified time */
+            tv[1].tv_sec = time / 1000;
+            tv[1].tv_usec = (time % 1000) * 1000;
+
+            if (utimes(path, tv) == 0)
+                rv = JNI_TRUE;
+        }
+    } END_PLATFORM_STRING(env, path);
+
+    return rv;
+}
+
+
+JNIEXPORT jboolean JNICALL
+Java_java_io_UnixFileSystem_setReadOnly(JNIEnv *env, jobject this,
+                                        jobject file)
+{
+    jboolean rv = JNI_FALSE;
+
+    WITH_FIELD_PLATFORM_STRING(env, file, ids.path, path) {
+        int mode;
+        if (statMode(path, &mode)) {
+            if (chmod(path, mode & ~(S_IWUSR | S_IWGRP | S_IWOTH)) >= 0) {
+                rv = JNI_TRUE;
+            }
+        }
+    } END_PLATFORM_STRING(env, path);
+    return rv;
+}
+
+JNIEXPORT jlong JNICALL
+Java_java_io_UnixFileSystem_getSpace(JNIEnv *env, jobject this,
+                                     jobject file, jint t)
+{
+    jlong rv = 0L;
+
+    WITH_FIELD_PLATFORM_STRING(env, file, ids.path, path) {
+        struct statvfs64 fsstat;
+        memset(&fsstat, 0, sizeof(fsstat));
+        if (statvfs64(path, &fsstat) == 0) {
+            switch(t) {
+            case java_io_FileSystem_SPACE_TOTAL:
+                rv = jlong_mul(long_to_jlong(fsstat.f_frsize),
+                               long_to_jlong(fsstat.f_blocks));
+                break;
+            case java_io_FileSystem_SPACE_FREE:
+                rv = jlong_mul(long_to_jlong(fsstat.f_frsize),
+                               long_to_jlong(fsstat.f_bfree));
+                break;
+            case java_io_FileSystem_SPACE_USABLE:
+                rv = jlong_mul(long_to_jlong(fsstat.f_frsize),
+                               long_to_jlong(fsstat.f_bavail));
+                break;
+            default:
+                assert(0);
+            }
+        }
+    } END_PLATFORM_STRING(env, path);
+    return rv;
+}
diff --git a/ojluni/src/main/native/canonicalize_md.c b/ojluni/src/main/native/canonicalize_md.c
new file mode 100755
index 0000000..b78cc2d
--- /dev/null
+++ b/ojluni/src/main/native/canonicalize_md.c
@@ -0,0 +1,272 @@
+/*
+ * Copyright (c) 1994, 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * Pathname canonicalization for Unix file systems
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <limits.h>
+#if !defined(_ALLBSD_SOURCE)
+#include <alloca.h>
+#endif
+
+
+/* Note: The comments in this file use the terminology
+         defined in the java.io.File class */
+
+
+/* Check the given name sequence to see if it can be further collapsed.
+   Return zero if not, otherwise return the number of names in the sequence. */
+
+static int
+collapsible(char *names)
+{
+    char *p = names;
+    int dots = 0, n = 0;
+
+    while (*p) {
+        if ((p[0] == '.') && ((p[1] == '\0')
+                              || (p[1] == '/')
+                              || ((p[1] == '.') && ((p[2] == '\0')
+                                                    || (p[2] == '/'))))) {
+            dots = 1;
+        }
+        n++;
+        while (*p) {
+            if (*p == '/') {
+                p++;
+                break;
+            }
+            p++;
+        }
+    }
+    return (dots ? n : 0);
+}
+
+
+/* Split the names in the given name sequence,
+   replacing slashes with nulls and filling in the given index array */
+
+static void
+splitNames(char *names, char **ix)
+{
+    char *p = names;
+    int i = 0;
+
+    while (*p) {
+        ix[i++] = p++;
+        while (*p) {
+            if (*p == '/') {
+                *p++ = '\0';
+                break;
+            }
+            p++;
+        }
+    }
+}
+
+
+/* Join the names in the given name sequence, ignoring names whose index
+   entries have been cleared and replacing nulls with slashes as needed */
+
+static void
+joinNames(char *names, int nc, char **ix)
+{
+    int i;
+    char *p;
+
+    for (i = 0, p = names; i < nc; i++) {
+        if (!ix[i]) continue;
+        if (i > 0) {
+            p[-1] = '/';
+        }
+        if (p == ix[i]) {
+            p += strlen(p) + 1;
+        } else {
+            char *q = ix[i];
+            while ((*p++ = *q++));
+        }
+    }
+    *p = '\0';
+}
+
+
+/* Collapse "." and ".." names in the given path wherever possible.
+   A "." name may always be eliminated; a ".." name may be eliminated if it
+   follows a name that is neither "." nor "..".  This is a syntactic operation
+   that performs no filesystem queries, so it should only be used to cleanup
+   after invoking the realpath() procedure. */
+
+static void
+collapse(char *path)
+{
+    char *names = (path[0] == '/') ? path + 1 : path; /* Preserve first '/' */
+    int nc;
+    char **ix;
+    int i, j;
+    char *p, *q;
+
+    nc = collapsible(names);
+    if (nc < 2) return;         /* Nothing to do */
+    ix = (char **)alloca(nc * sizeof(char *));
+    splitNames(names, ix);
+
+    for (i = 0; i < nc; i++) {
+        int dots = 0;
+
+        /* Find next occurrence of "." or ".." */
+        do {
+            char *p = ix[i];
+            if (p[0] == '.') {
+                if (p[1] == '\0') {
+                    dots = 1;
+                    break;
+                }
+                if ((p[1] == '.') && (p[2] == '\0')) {
+                    dots = 2;
+                    break;
+                }
+            }
+            i++;
+        } while (i < nc);
+        if (i >= nc) break;
+
+        /* At this point i is the index of either a "." or a "..", so take the
+           appropriate action and then continue the outer loop */
+        if (dots == 1) {
+            /* Remove this instance of "." */
+            ix[i] = 0;
+        }
+        else {
+            /* If there is a preceding name, remove both that name and this
+               instance of ".."; otherwise, leave the ".." as is */
+            for (j = i - 1; j >= 0; j--) {
+                if (ix[j]) break;
+            }
+            if (j < 0) continue;
+            ix[j] = 0;
+            ix[i] = 0;
+        }
+        /* i will be incremented at the top of the loop */
+    }
+
+    joinNames(names, nc, ix);
+}
+
+
+/* Convert a pathname to canonical form.  The input path is assumed to contain
+   no duplicate slashes.  On Solaris we can use realpath() to do most of the
+   work, though once that's done we still must collapse any remaining "." and
+   ".." names by hand. */
+
+int
+canonicalize(char *original, char *resolved, int len)
+{
+    if (len < PATH_MAX) {
+        errno = EINVAL;
+        return -1;
+    }
+
+    if (strlen(original) > PATH_MAX) {
+        errno = ENAMETOOLONG;
+        return -1;
+    }
+
+    /* First try realpath() on the entire path */
+    if (realpath(original, resolved)) {
+        /* That worked, so return it */
+        collapse(resolved);
+        return 0;
+    }
+    else {
+        /* Something's bogus in the original path, so remove names from the end
+           until either some subpath works or we run out of names */
+        char *p, *end, *r = NULL;
+        char path[PATH_MAX + 1];
+
+        strncpy(path, original, sizeof(path));
+        if (path[PATH_MAX] != '\0') {
+            errno = ENAMETOOLONG;
+            return -1;
+        }
+        end = path + strlen(path);
+
+        for (p = end; p > path;) {
+
+            /* Skip last element */
+            while ((--p > path) && (*p != '/'));
+            if (p == path) break;
+
+            /* Try realpath() on this subpath */
+            *p = '\0';
+            r = realpath(path, resolved);
+            *p = (p == end) ? '\0' : '/';
+
+            if (r != NULL) {
+                /* The subpath has a canonical path */
+                break;
+            }
+            else if (errno == ENOENT || errno == ENOTDIR || errno == EACCES) {
+                /* If the lookup of a particular subpath fails because the file
+                   does not exist, because it is of the wrong type, or because
+                   access is denied, then remove its last name and try again.
+                   Other I/O problems cause an error return. */
+                continue;
+            }
+            else {
+                return -1;
+            }
+        }
+
+        if (r != NULL) {
+            /* Append unresolved subpath to resolved subpath */
+            int rn = strlen(r);
+            if (rn + (int)strlen(p) >= len) {
+                /* Buffer overflow */
+                errno = ENAMETOOLONG;
+                return -1;
+            }
+            if ((rn > 0) && (r[rn - 1] == '/') && (*p == '/')) {
+                /* Avoid duplicate slashes */
+                p++;
+            }
+            strcpy(r + rn, p);
+            collapse(r);
+            return 0;
+        }
+        else {
+            /* Nothing resolved, so just return the original path */
+            strcpy(resolved, path);
+            collapse(resolved);
+            return 0;
+        }
+    }
+
+}
diff --git a/ojluni/src/main/native/classfile_constants.h b/ojluni/src/main/native/classfile_constants.h
new file mode 100755
index 0000000..861576e
--- /dev/null
+++ b/ojluni/src/main/native/classfile_constants.h
@@ -0,0 +1,560 @@
+/*
+ * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#ifndef CLASSFILE_CONSTANTS_H
+#define CLASSFILE_CONSTANTS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Classfile version number for this information */
+#define JVM_CLASSFILE_MAJOR_VERSION 51
+#define JVM_CLASSFILE_MINOR_VERSION 0
+
+/* Flags */
+
+enum {
+    JVM_ACC_PUBLIC        = 0x0001,
+    JVM_ACC_PRIVATE       = 0x0002,
+    JVM_ACC_PROTECTED     = 0x0004,
+    JVM_ACC_STATIC        = 0x0008,
+    JVM_ACC_FINAL         = 0x0010,
+    JVM_ACC_SYNCHRONIZED  = 0x0020,
+    JVM_ACC_SUPER         = 0x0020,
+    JVM_ACC_VOLATILE      = 0x0040,
+    JVM_ACC_BRIDGE        = 0x0040,
+    JVM_ACC_TRANSIENT     = 0x0080,
+    JVM_ACC_VARARGS       = 0x0080,
+    JVM_ACC_NATIVE        = 0x0100,
+    JVM_ACC_INTERFACE     = 0x0200,
+    JVM_ACC_ABSTRACT      = 0x0400,
+    JVM_ACC_STRICT        = 0x0800,
+    JVM_ACC_SYNTHETIC     = 0x1000,
+    JVM_ACC_ANNOTATION    = 0x2000,
+    JVM_ACC_ENUM          = 0x4000
+};
+
+/* Used in newarray instruction. */
+
+enum {
+    JVM_T_BOOLEAN = 4,
+    JVM_T_CHAR    = 5,
+    JVM_T_FLOAT   = 6,
+    JVM_T_DOUBLE  = 7,
+    JVM_T_BYTE    = 8,
+    JVM_T_SHORT   = 9,
+    JVM_T_INT     = 10,
+    JVM_T_LONG    = 11
+};
+
+/* Constant Pool Entries */
+
+enum {
+    JVM_CONSTANT_Utf8                   = 1,
+    JVM_CONSTANT_Unicode                = 2, /* unused */
+    JVM_CONSTANT_Integer                = 3,
+    JVM_CONSTANT_Float                  = 4,
+    JVM_CONSTANT_Long                   = 5,
+    JVM_CONSTANT_Double                 = 6,
+    JVM_CONSTANT_Class                  = 7,
+    JVM_CONSTANT_String                 = 8,
+    JVM_CONSTANT_Fieldref               = 9,
+    JVM_CONSTANT_Methodref              = 10,
+    JVM_CONSTANT_InterfaceMethodref     = 11,
+    JVM_CONSTANT_NameAndType            = 12,
+    JVM_CONSTANT_MethodHandle           = 15,  // JSR 292
+    JVM_CONSTANT_MethodType             = 16,   // JSR 292
+    JVM_CONSTANT_InvokeDynamic          = 18
+};
+
+/* JVM_CONSTANT_MethodHandle subtypes */
+enum {
+    JVM_REF_getField                = 1,
+    JVM_REF_getStatic               = 2,
+    JVM_REF_putField                = 3,
+    JVM_REF_putStatic               = 4,
+    JVM_REF_invokeVirtual           = 5,
+    JVM_REF_invokeStatic            = 6,
+    JVM_REF_invokeSpecial           = 7,
+    JVM_REF_newInvokeSpecial        = 8,
+    JVM_REF_invokeInterface         = 9
+};
+
+/* StackMapTable type item numbers */
+
+enum {
+    JVM_ITEM_Top                = 0,
+    JVM_ITEM_Integer            = 1,
+    JVM_ITEM_Float              = 2,
+    JVM_ITEM_Double             = 3,
+    JVM_ITEM_Long               = 4,
+    JVM_ITEM_Null               = 5,
+    JVM_ITEM_UninitializedThis  = 6,
+    JVM_ITEM_Object             = 7,
+    JVM_ITEM_Uninitialized      = 8
+};
+
+/* Type signatures */
+
+enum {
+    JVM_SIGNATURE_ARRAY         = '[',
+    JVM_SIGNATURE_BYTE          = 'B',
+    JVM_SIGNATURE_CHAR          = 'C',
+    JVM_SIGNATURE_CLASS         = 'L',
+    JVM_SIGNATURE_ENDCLASS      = ';',
+    JVM_SIGNATURE_ENUM          = 'E',
+    JVM_SIGNATURE_FLOAT         = 'F',
+    JVM_SIGNATURE_DOUBLE        = 'D',
+    JVM_SIGNATURE_FUNC          = '(',
+    JVM_SIGNATURE_ENDFUNC       = ')',
+    JVM_SIGNATURE_INT           = 'I',
+    JVM_SIGNATURE_LONG          = 'J',
+    JVM_SIGNATURE_SHORT         = 'S',
+    JVM_SIGNATURE_VOID          = 'V',
+    JVM_SIGNATURE_BOOLEAN       = 'Z'
+};
+
+/* Opcodes */
+
+enum {
+    JVM_OPC_nop                 = 0,
+    JVM_OPC_aconst_null         = 1,
+    JVM_OPC_iconst_m1           = 2,
+    JVM_OPC_iconst_0            = 3,
+    JVM_OPC_iconst_1            = 4,
+    JVM_OPC_iconst_2            = 5,
+    JVM_OPC_iconst_3            = 6,
+    JVM_OPC_iconst_4            = 7,
+    JVM_OPC_iconst_5            = 8,
+    JVM_OPC_lconst_0            = 9,
+    JVM_OPC_lconst_1            = 10,
+    JVM_OPC_fconst_0            = 11,
+    JVM_OPC_fconst_1            = 12,
+    JVM_OPC_fconst_2            = 13,
+    JVM_OPC_dconst_0            = 14,
+    JVM_OPC_dconst_1            = 15,
+    JVM_OPC_bipush              = 16,
+    JVM_OPC_sipush              = 17,
+    JVM_OPC_ldc                 = 18,
+    JVM_OPC_ldc_w               = 19,
+    JVM_OPC_ldc2_w              = 20,
+    JVM_OPC_iload               = 21,
+    JVM_OPC_lload               = 22,
+    JVM_OPC_fload               = 23,
+    JVM_OPC_dload               = 24,
+    JVM_OPC_aload               = 25,
+    JVM_OPC_iload_0             = 26,
+    JVM_OPC_iload_1             = 27,
+    JVM_OPC_iload_2             = 28,
+    JVM_OPC_iload_3             = 29,
+    JVM_OPC_lload_0             = 30,
+    JVM_OPC_lload_1             = 31,
+    JVM_OPC_lload_2             = 32,
+    JVM_OPC_lload_3             = 33,
+    JVM_OPC_fload_0             = 34,
+    JVM_OPC_fload_1             = 35,
+    JVM_OPC_fload_2             = 36,
+    JVM_OPC_fload_3             = 37,
+    JVM_OPC_dload_0             = 38,
+    JVM_OPC_dload_1             = 39,
+    JVM_OPC_dload_2             = 40,
+    JVM_OPC_dload_3             = 41,
+    JVM_OPC_aload_0             = 42,
+    JVM_OPC_aload_1             = 43,
+    JVM_OPC_aload_2             = 44,
+    JVM_OPC_aload_3             = 45,
+    JVM_OPC_iaload              = 46,
+    JVM_OPC_laload              = 47,
+    JVM_OPC_faload              = 48,
+    JVM_OPC_daload              = 49,
+    JVM_OPC_aaload              = 50,
+    JVM_OPC_baload              = 51,
+    JVM_OPC_caload              = 52,
+    JVM_OPC_saload              = 53,
+    JVM_OPC_istore              = 54,
+    JVM_OPC_lstore              = 55,
+    JVM_OPC_fstore              = 56,
+    JVM_OPC_dstore              = 57,
+    JVM_OPC_astore              = 58,
+    JVM_OPC_istore_0            = 59,
+    JVM_OPC_istore_1            = 60,
+    JVM_OPC_istore_2            = 61,
+    JVM_OPC_istore_3            = 62,
+    JVM_OPC_lstore_0            = 63,
+    JVM_OPC_lstore_1            = 64,
+    JVM_OPC_lstore_2            = 65,
+    JVM_OPC_lstore_3            = 66,
+    JVM_OPC_fstore_0            = 67,
+    JVM_OPC_fstore_1            = 68,
+    JVM_OPC_fstore_2            = 69,
+    JVM_OPC_fstore_3            = 70,
+    JVM_OPC_dstore_0            = 71,
+    JVM_OPC_dstore_1            = 72,
+    JVM_OPC_dstore_2            = 73,
+    JVM_OPC_dstore_3            = 74,
+    JVM_OPC_astore_0            = 75,
+    JVM_OPC_astore_1            = 76,
+    JVM_OPC_astore_2            = 77,
+    JVM_OPC_astore_3            = 78,
+    JVM_OPC_iastore             = 79,
+    JVM_OPC_lastore             = 80,
+    JVM_OPC_fastore             = 81,
+    JVM_OPC_dastore             = 82,
+    JVM_OPC_aastore             = 83,
+    JVM_OPC_bastore             = 84,
+    JVM_OPC_castore             = 85,
+    JVM_OPC_sastore             = 86,
+    JVM_OPC_pop                 = 87,
+    JVM_OPC_pop2                = 88,
+    JVM_OPC_dup                 = 89,
+    JVM_OPC_dup_x1              = 90,
+    JVM_OPC_dup_x2              = 91,
+    JVM_OPC_dup2                = 92,
+    JVM_OPC_dup2_x1             = 93,
+    JVM_OPC_dup2_x2             = 94,
+    JVM_OPC_swap                = 95,
+    JVM_OPC_iadd                = 96,
+    JVM_OPC_ladd                = 97,
+    JVM_OPC_fadd                = 98,
+    JVM_OPC_dadd                = 99,
+    JVM_OPC_isub                = 100,
+    JVM_OPC_lsub                = 101,
+    JVM_OPC_fsub                = 102,
+    JVM_OPC_dsub                = 103,
+    JVM_OPC_imul                = 104,
+    JVM_OPC_lmul                = 105,
+    JVM_OPC_fmul                = 106,
+    JVM_OPC_dmul                = 107,
+    JVM_OPC_idiv                = 108,
+    JVM_OPC_ldiv                = 109,
+    JVM_OPC_fdiv                = 110,
+    JVM_OPC_ddiv                = 111,
+    JVM_OPC_irem                = 112,
+    JVM_OPC_lrem                = 113,
+    JVM_OPC_frem                = 114,
+    JVM_OPC_drem                = 115,
+    JVM_OPC_ineg                = 116,
+    JVM_OPC_lneg                = 117,
+    JVM_OPC_fneg                = 118,
+    JVM_OPC_dneg                = 119,
+    JVM_OPC_ishl                = 120,
+    JVM_OPC_lshl                = 121,
+    JVM_OPC_ishr                = 122,
+    JVM_OPC_lshr                = 123,
+    JVM_OPC_iushr               = 124,
+    JVM_OPC_lushr               = 125,
+    JVM_OPC_iand                = 126,
+    JVM_OPC_land                = 127,
+    JVM_OPC_ior                 = 128,
+    JVM_OPC_lor                 = 129,
+    JVM_OPC_ixor                = 130,
+    JVM_OPC_lxor                = 131,
+    JVM_OPC_iinc                = 132,
+    JVM_OPC_i2l                 = 133,
+    JVM_OPC_i2f                 = 134,
+    JVM_OPC_i2d                 = 135,
+    JVM_OPC_l2i                 = 136,
+    JVM_OPC_l2f                 = 137,
+    JVM_OPC_l2d                 = 138,
+    JVM_OPC_f2i                 = 139,
+    JVM_OPC_f2l                 = 140,
+    JVM_OPC_f2d                 = 141,
+    JVM_OPC_d2i                 = 142,
+    JVM_OPC_d2l                 = 143,
+    JVM_OPC_d2f                 = 144,
+    JVM_OPC_i2b                 = 145,
+    JVM_OPC_i2c                 = 146,
+    JVM_OPC_i2s                 = 147,
+    JVM_OPC_lcmp                = 148,
+    JVM_OPC_fcmpl               = 149,
+    JVM_OPC_fcmpg               = 150,
+    JVM_OPC_dcmpl               = 151,
+    JVM_OPC_dcmpg               = 152,
+    JVM_OPC_ifeq                = 153,
+    JVM_OPC_ifne                = 154,
+    JVM_OPC_iflt                = 155,
+    JVM_OPC_ifge                = 156,
+    JVM_OPC_ifgt                = 157,
+    JVM_OPC_ifle                = 158,
+    JVM_OPC_if_icmpeq           = 159,
+    JVM_OPC_if_icmpne           = 160,
+    JVM_OPC_if_icmplt           = 161,
+    JVM_OPC_if_icmpge           = 162,
+    JVM_OPC_if_icmpgt           = 163,
+    JVM_OPC_if_icmple           = 164,
+    JVM_OPC_if_acmpeq           = 165,
+    JVM_OPC_if_acmpne           = 166,
+    JVM_OPC_goto                = 167,
+    JVM_OPC_jsr                 = 168,
+    JVM_OPC_ret                 = 169,
+    JVM_OPC_tableswitch         = 170,
+    JVM_OPC_lookupswitch        = 171,
+    JVM_OPC_ireturn             = 172,
+    JVM_OPC_lreturn             = 173,
+    JVM_OPC_freturn             = 174,
+    JVM_OPC_dreturn             = 175,
+    JVM_OPC_areturn             = 176,
+    JVM_OPC_return              = 177,
+    JVM_OPC_getstatic           = 178,
+    JVM_OPC_putstatic           = 179,
+    JVM_OPC_getfield            = 180,
+    JVM_OPC_putfield            = 181,
+    JVM_OPC_invokevirtual       = 182,
+    JVM_OPC_invokespecial       = 183,
+    JVM_OPC_invokestatic        = 184,
+    JVM_OPC_invokeinterface     = 185,
+    JVM_OPC_invokedynamic       = 186,
+    JVM_OPC_new                 = 187,
+    JVM_OPC_newarray            = 188,
+    JVM_OPC_anewarray           = 189,
+    JVM_OPC_arraylength         = 190,
+    JVM_OPC_athrow              = 191,
+    JVM_OPC_checkcast           = 192,
+    JVM_OPC_instanceof          = 193,
+    JVM_OPC_monitorenter        = 194,
+    JVM_OPC_monitorexit         = 195,
+    JVM_OPC_wide                = 196,
+    JVM_OPC_multianewarray      = 197,
+    JVM_OPC_ifnull              = 198,
+    JVM_OPC_ifnonnull           = 199,
+    JVM_OPC_goto_w              = 200,
+    JVM_OPC_jsr_w               = 201,
+    JVM_OPC_MAX                 = 201
+};
+
+/* Opcode length initializer, use with something like:
+ *   unsigned char opcode_length[JVM_OPC_MAX+1] = JVM_OPCODE_LENGTH_INITIALIZER;
+ */
+#define JVM_OPCODE_LENGTH_INITIALIZER { \
+   1,   /* nop */                       \
+   1,   /* aconst_null */               \
+   1,   /* iconst_m1 */                 \
+   1,   /* iconst_0 */                  \
+   1,   /* iconst_1 */                  \
+   1,   /* iconst_2 */                  \
+   1,   /* iconst_3 */                  \
+   1,   /* iconst_4 */                  \
+   1,   /* iconst_5 */                  \
+   1,   /* lconst_0 */                  \
+   1,   /* lconst_1 */                  \
+   1,   /* fconst_0 */                  \
+   1,   /* fconst_1 */                  \
+   1,   /* fconst_2 */                  \
+   1,   /* dconst_0 */                  \
+   1,   /* dconst_1 */                  \
+   2,   /* bipush */                    \
+   3,   /* sipush */                    \
+   2,   /* ldc */                       \
+   3,   /* ldc_w */                     \
+   3,   /* ldc2_w */                    \
+   2,   /* iload */                     \
+   2,   /* lload */                     \
+   2,   /* fload */                     \
+   2,   /* dload */                     \
+   2,   /* aload */                     \
+   1,   /* iload_0 */                   \
+   1,   /* iload_1 */                   \
+   1,   /* iload_2 */                   \
+   1,   /* iload_3 */                   \
+   1,   /* lload_0 */                   \
+   1,   /* lload_1 */                   \
+   1,   /* lload_2 */                   \
+   1,   /* lload_3 */                   \
+   1,   /* fload_0 */                   \
+   1,   /* fload_1 */                   \
+   1,   /* fload_2 */                   \
+   1,   /* fload_3 */                   \
+   1,   /* dload_0 */                   \
+   1,   /* dload_1 */                   \
+   1,   /* dload_2 */                   \
+   1,   /* dload_3 */                   \
+   1,   /* aload_0 */                   \
+   1,   /* aload_1 */                   \
+   1,   /* aload_2 */                   \
+   1,   /* aload_3 */                   \
+   1,   /* iaload */                    \
+   1,   /* laload */                    \
+   1,   /* faload */                    \
+   1,   /* daload */                    \
+   1,   /* aaload */                    \
+   1,   /* baload */                    \
+   1,   /* caload */                    \
+   1,   /* saload */                    \
+   2,   /* istore */                    \
+   2,   /* lstore */                    \
+   2,   /* fstore */                    \
+   2,   /* dstore */                    \
+   2,   /* astore */                    \
+   1,   /* istore_0 */                  \
+   1,   /* istore_1 */                  \
+   1,   /* istore_2 */                  \
+   1,   /* istore_3 */                  \
+   1,   /* lstore_0 */                  \
+   1,   /* lstore_1 */                  \
+   1,   /* lstore_2 */                  \
+   1,   /* lstore_3 */                  \
+   1,   /* fstore_0 */                  \
+   1,   /* fstore_1 */                  \
+   1,   /* fstore_2 */                  \
+   1,   /* fstore_3 */                  \
+   1,   /* dstore_0 */                  \
+   1,   /* dstore_1 */                  \
+   1,   /* dstore_2 */                  \
+   1,   /* dstore_3 */                  \
+   1,   /* astore_0 */                  \
+   1,   /* astore_1 */                  \
+   1,   /* astore_2 */                  \
+   1,   /* astore_3 */                  \
+   1,   /* iastore */                   \
+   1,   /* lastore */                   \
+   1,   /* fastore */                   \
+   1,   /* dastore */                   \
+   1,   /* aastore */                   \
+   1,   /* bastore */                   \
+   1,   /* castore */                   \
+   1,   /* sastore */                   \
+   1,   /* pop */                       \
+   1,   /* pop2 */                      \
+   1,   /* dup */                       \
+   1,   /* dup_x1 */                    \
+   1,   /* dup_x2 */                    \
+   1,   /* dup2 */                      \
+   1,   /* dup2_x1 */                   \
+   1,   /* dup2_x2 */                   \
+   1,   /* swap */                      \
+   1,   /* iadd */                      \
+   1,   /* ladd */                      \
+   1,   /* fadd */                      \
+   1,   /* dadd */                      \
+   1,   /* isub */                      \
+   1,   /* lsub */                      \
+   1,   /* fsub */                      \
+   1,   /* dsub */                      \
+   1,   /* imul */                      \
+   1,   /* lmul */                      \
+   1,   /* fmul */                      \
+   1,   /* dmul */                      \
+   1,   /* idiv */                      \
+   1,   /* ldiv */                      \
+   1,   /* fdiv */                      \
+   1,   /* ddiv */                      \
+   1,   /* irem */                      \
+   1,   /* lrem */                      \
+   1,   /* frem */                      \
+   1,   /* drem */                      \
+   1,   /* ineg */                      \
+   1,   /* lneg */                      \
+   1,   /* fneg */                      \
+   1,   /* dneg */                      \
+   1,   /* ishl */                      \
+   1,   /* lshl */                      \
+   1,   /* ishr */                      \
+   1,   /* lshr */                      \
+   1,   /* iushr */                     \
+   1,   /* lushr */                     \
+   1,   /* iand */                      \
+   1,   /* land */                      \
+   1,   /* ior */                       \
+   1,   /* lor */                       \
+   1,   /* ixor */                      \
+   1,   /* lxor */                      \
+   3,   /* iinc */                      \
+   1,   /* i2l */                       \
+   1,   /* i2f */                       \
+   1,   /* i2d */                       \
+   1,   /* l2i */                       \
+   1,   /* l2f */                       \
+   1,   /* l2d */                       \
+   1,   /* f2i */                       \
+   1,   /* f2l */                       \
+   1,   /* f2d */                       \
+   1,   /* d2i */                       \
+   1,   /* d2l */                       \
+   1,   /* d2f */                       \
+   1,   /* i2b */                       \
+   1,   /* i2c */                       \
+   1,   /* i2s */                       \
+   1,   /* lcmp */                      \
+   1,   /* fcmpl */                     \
+   1,   /* fcmpg */                     \
+   1,   /* dcmpl */                     \
+   1,   /* dcmpg */                     \
+   3,   /* ifeq */                      \
+   3,   /* ifne */                      \
+   3,   /* iflt */                      \
+   3,   /* ifge */                      \
+   3,   /* ifgt */                      \
+   3,   /* ifle */                      \
+   3,   /* if_icmpeq */                 \
+   3,   /* if_icmpne */                 \
+   3,   /* if_icmplt */                 \
+   3,   /* if_icmpge */                 \
+   3,   /* if_icmpgt */                 \
+   3,   /* if_icmple */                 \
+   3,   /* if_acmpeq */                 \
+   3,   /* if_acmpne */                 \
+   3,   /* goto */                      \
+   3,   /* jsr */                       \
+   2,   /* ret */                       \
+   99,  /* tableswitch */               \
+   99,  /* lookupswitch */              \
+   1,   /* ireturn */                   \
+   1,   /* lreturn */                   \
+   1,   /* freturn */                   \
+   1,   /* dreturn */                   \
+   1,   /* areturn */                   \
+   1,   /* return */                    \
+   3,   /* getstatic */                 \
+   3,   /* putstatic */                 \
+   3,   /* getfield */                  \
+   3,   /* putfield */                  \
+   3,   /* invokevirtual */             \
+   3,   /* invokespecial */             \
+   3,   /* invokestatic */              \
+   5,   /* invokeinterface */           \
+   5,   /* invokedynamic */             \
+   3,   /* new */                       \
+   2,   /* newarray */                  \
+   3,   /* anewarray */                 \
+   1,   /* arraylength */               \
+   1,   /* athrow */                    \
+   3,   /* checkcast */                 \
+   3,   /* instanceof */                \
+   1,   /* monitorenter */              \
+   1,   /* monitorexit */               \
+   0,   /* wide */                      \
+   4,   /* multianewarray */            \
+   3,   /* ifnull */                    \
+   3,   /* ifnonnull */                 \
+   5,   /* goto_w */                    \
+   5    /* jsr_w */                     \
+}
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif /* __cplusplus */
+
+#endif /* CLASSFILE_CONSTANTS */
diff --git a/ojluni/src/main/native/fdlibm.h b/ojluni/src/main/native/fdlibm.h
new file mode 100755
index 0000000..c24c781
--- /dev/null
+++ b/ojluni/src/main/native/fdlibm.h
@@ -0,0 +1,239 @@
+
+/*
+ * Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#ifdef _ALLBSD_SOURCE
+#include <machine/endian.h>
+#elif __linux__
+#define __USE_BSD 1
+#include <endian.h>
+#endif
+#include "jfdlibm.h"
+
+#ifdef __NEWVALID       /* special setup for Sun test regime */
+#if defined(i386) || defined(i486) || \
+    defined(intel) || defined(x86) || defined(arm) || \
+    defined(i86pc) || defined(_M_IA64) || defined(ia64)
+#define _LITTLE_ENDIAN
+#endif
+#endif
+
+#ifdef _LITTLE_ENDIAN
+#define __HI(x) *(1+(int*)&x)
+#define __LO(x) *(int*)&x
+#define __HIp(x) *(1+(int*)x)
+#define __LOp(x) *(int*)x
+#else
+#define __HI(x) *(int*)&x
+#define __LO(x) *(1+(int*)&x)
+#define __HIp(x) *(int*)x
+#define __LOp(x) *(1+(int*)x)
+#endif
+
+#ifndef __P
+#ifdef __STDC__
+#define __P(p)  p
+#else
+#define __P(p)  ()
+#endif
+#endif
+
+/*
+ * ANSI/POSIX
+ */
+
+extern int signgam;
+
+#define MAXFLOAT        ((float)3.40282346638528860e+38)
+
+enum fdversion {fdlibm_ieee = -1, fdlibm_svid, fdlibm_xopen, fdlibm_posix};
+
+#define _LIB_VERSION_TYPE enum fdversion
+#define _LIB_VERSION _fdlib_version
+
+/* if global variable _LIB_VERSION is not desirable, one may
+ * change the following to be a constant by:
+ *      #define _LIB_VERSION_TYPE const enum version
+ * In that case, after one initializes the value _LIB_VERSION (see
+ * s_lib_version.c) during compile time, it cannot be modified
+ * in the middle of a program
+ */
+extern  _LIB_VERSION_TYPE  _LIB_VERSION;
+
+#define _IEEE_  fdlibm_ieee
+#define _SVID_  fdlibm_svid
+#define _XOPEN_ fdlibm_xopen
+#define _POSIX_ fdlibm_posix
+
+struct exception {
+        int type;
+        char *name;
+        double arg1;
+        double arg2;
+        double retval;
+};
+
+#define HUGE            MAXFLOAT
+
+/*
+ * set X_TLOSS = pi*2**52, which is possibly defined in <values.h>
+ * (one may replace the following line by "#include <values.h>")
+ */
+
+#define X_TLOSS         1.41484755040568800000e+16
+
+#define DOMAIN          1
+#define SING            2
+#define OVERFLOW        3
+#define UNDERFLOW       4
+#define TLOSS           5
+#define PLOSS           6
+
+/*
+ * ANSI/POSIX
+ */
+extern double acos __P((double));
+extern double asin __P((double));
+extern double atan __P((double));
+extern double atan2 __P((double, double));
+extern double cos __P((double));
+extern double sin __P((double));
+extern double tan __P((double));
+
+extern double cosh __P((double));
+extern double sinh __P((double));
+extern double tanh __P((double));
+
+extern double exp __P((double));
+extern double frexp __P((double, int *));
+extern double ldexp __P((double, int));
+extern double log __P((double));
+extern double log10 __P((double));
+extern double modf __P((double, double *));
+
+extern double pow __P((double, double));
+extern double sqrt __P((double));
+
+extern double ceil __P((double));
+extern double fabs __P((double));
+extern double floor __P((double));
+extern double fmod __P((double, double));
+
+extern double erf __P((double));
+extern double erfc __P((double));
+extern double gamma __P((double));
+extern double hypot __P((double, double));
+extern int isnan __P((double));
+extern int finite __P((double));
+extern double j0 __P((double));
+extern double j1 __P((double));
+extern double jn __P((int, double));
+extern double lgamma __P((double));
+extern double y0 __P((double));
+extern double y1 __P((double));
+extern double yn __P((int, double));
+
+extern double acosh __P((double));
+extern double asinh __P((double));
+extern double atanh __P((double));
+extern double cbrt __P((double));
+extern double logb __P((double));
+extern double nextafter __P((double, double));
+extern double remainder __P((double, double));
+#ifdef _SCALB_INT
+extern double scalb __P((double, int));
+#else
+extern double scalb __P((double, double));
+#endif
+
+extern int matherr __P((struct exception *));
+
+/*
+ * IEEE Test Vector
+ */
+extern double significand __P((double));
+
+/*
+ * Functions callable from C, intended to support IEEE arithmetic.
+ */
+extern double copysign __P((double, double));
+extern int ilogb __P((double));
+extern double rint __P((double));
+extern double scalbn __P((double, int));
+
+/*
+ * BSD math library entry points
+ */
+extern double expm1 __P((double));
+extern double log1p __P((double));
+
+/*
+ * Reentrant version of gamma & lgamma; passes signgam back by reference
+ * as the second argument; user must allocate space for signgam.
+ */
+#ifdef _REENTRANT
+extern double gamma_r __P((double, int *));
+extern double lgamma_r __P((double, int *));
+#endif  /* _REENTRANT */
+
+/* ieee style elementary functions */
+extern double __ieee754_sqrt __P((double));
+extern double __ieee754_acos __P((double));
+extern double __ieee754_acosh __P((double));
+extern double __ieee754_log __P((double));
+extern double __ieee754_atanh __P((double));
+extern double __ieee754_asin __P((double));
+extern double __ieee754_atan2 __P((double,double));
+extern double __ieee754_exp __P((double));
+extern double __ieee754_cosh __P((double));
+extern double __ieee754_fmod __P((double,double));
+extern double __ieee754_pow __P((double,double));
+extern double __ieee754_lgamma_r __P((double,int *));
+extern double __ieee754_gamma_r __P((double,int *));
+extern double __ieee754_lgamma __P((double));
+extern double __ieee754_gamma __P((double));
+extern double __ieee754_log10 __P((double));
+extern double __ieee754_sinh __P((double));
+extern double __ieee754_hypot __P((double,double));
+extern double __ieee754_j0 __P((double));
+extern double __ieee754_j1 __P((double));
+extern double __ieee754_y0 __P((double));
+extern double __ieee754_y1 __P((double));
+extern double __ieee754_jn __P((int,double));
+extern double __ieee754_yn __P((int,double));
+extern double __ieee754_remainder __P((double,double));
+extern int    __ieee754_rem_pio2 __P((double,double*));
+#ifdef _SCALB_INT
+extern double __ieee754_scalb __P((double,int));
+#else
+extern double __ieee754_scalb __P((double,double));
+#endif
+
+/* fdlibm kernel function */
+extern double __kernel_standard __P((double,double,int));
+extern double __kernel_sin __P((double,double,int));
+extern double __kernel_cos __P((double,double));
+extern double __kernel_tan __P((double,double,int));
+extern int    __kernel_rem_pio2 __P((double*,double*,int,int,int,const int*));
diff --git a/ojluni/src/main/native/io_util.c b/ojluni/src/main/native/io_util.c
new file mode 100755
index 0000000..e17652a
--- /dev/null
+++ b/ojluni/src/main/native/io_util.c
@@ -0,0 +1,232 @@
+/*
+ * Copyright (c) 1994, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <stddef.h>
+
+#include "jni.h"
+#include "jni_util.h"
+#include "jvm.h"
+#include "io_util.h"
+#include "io_util_md.h"
+
+/* IO helper functions */
+
+jint
+readSingle(JNIEnv *env, jobject this, jfieldID fid) {
+    jint nread;
+    char ret;
+    FD fd = GET_FD(this, fid);
+    if (fd == -1) {
+        JNU_ThrowIOException(env, "Stream Closed");
+        return -1;
+    }
+    nread = (jint)IO_Read(fd, &ret, 1);
+    if (nread == 0) { /* EOF */
+        return -1;
+    } else if (nread == JVM_IO_ERR) { /* error */
+        JNU_ThrowIOExceptionWithLastError(env, "Read error");
+    } else if (nread == JVM_IO_INTR) {
+        JNU_ThrowByName(env, "java/io/InterruptedIOException", NULL);
+    }
+    return ret & 0xFF;
+}
+
+/* The maximum size of a stack-allocated buffer.
+ */
+#define BUF_SIZE 8192
+
+/*
+ * Returns true if the array slice defined by the given offset and length
+ * is out of bounds.
+ */
+static int
+outOfBounds(JNIEnv *env, jint off, jint len, jbyteArray array) {
+    return ((off < 0) ||
+            (len < 0) ||
+            // We are very careful to avoid signed integer overflow,
+            // the result of which is undefined in C.
+            ((*env)->GetArrayLength(env, array) - off < len));
+}
+
+jint
+readBytes(JNIEnv *env, jobject this, jbyteArray bytes,
+          jint off, jint len, jfieldID fid)
+{
+    jint nread;
+    char stackBuf[BUF_SIZE];
+    char *buf = NULL;
+    FD fd;
+
+    if (IS_NULL(bytes)) {
+        JNU_ThrowNullPointerException(env, NULL);
+        return -1;
+    }
+
+    if (outOfBounds(env, off, len, bytes)) {
+        JNU_ThrowByName(env, "java/lang/IndexOutOfBoundsException", NULL);
+        return -1;
+    }
+
+    if (len == 0) {
+        return 0;
+    } else if (len > BUF_SIZE) {
+        buf = malloc(len);
+        if (buf == NULL) {
+            JNU_ThrowOutOfMemoryError(env, NULL);
+            return 0;
+        }
+    } else {
+        buf = stackBuf;
+    }
+
+    fd = GET_FD(this, fid);
+    if (fd == -1) {
+        JNU_ThrowIOException(env, "Stream Closed");
+        nread = -1;
+    } else {
+        nread = (jint)IO_Read(fd, buf, len);
+        if (nread > 0) {
+            (*env)->SetByteArrayRegion(env, bytes, off, nread, (jbyte *)buf);
+        } else if (nread == JVM_IO_ERR) {
+            JNU_ThrowIOExceptionWithLastError(env, "Read error");
+        } else if (nread == JVM_IO_INTR) {
+            JNU_ThrowByName(env, "java/io/InterruptedIOException", NULL);
+        } else { /* EOF */
+            nread = -1;
+        }
+    }
+
+    if (buf != stackBuf) {
+        free(buf);
+    }
+    return nread;
+}
+
+void
+writeSingle(JNIEnv *env, jobject this, jint byte, jboolean append, jfieldID fid) {
+    // Discard the 24 high-order bits of byte. See OutputStream#write(int)
+    char c = (char) byte;
+    jint n;
+    FD fd = GET_FD(this, fid);
+    if (fd == -1) {
+        JNU_ThrowIOException(env, "Stream Closed");
+        return;
+    }
+    if (append == JNI_TRUE) {
+        n = (jint)IO_Append(fd, &c, 1);
+    } else {
+        n = (jint)IO_Write(fd, &c, 1);
+    }
+    if (n == JVM_IO_ERR) {
+        JNU_ThrowIOExceptionWithLastError(env, "Write error");
+    } else if (n == JVM_IO_INTR) {
+        JNU_ThrowByName(env, "java/io/InterruptedIOException", NULL);
+    }
+}
+
+void
+writeBytes(JNIEnv *env, jobject this, jbyteArray bytes,
+           jint off, jint len, jboolean append, jfieldID fid)
+{
+    jint n;
+    char stackBuf[BUF_SIZE];
+    char *buf = NULL;
+    FD fd;
+
+    if (IS_NULL(bytes)) {
+        JNU_ThrowNullPointerException(env, NULL);
+        return;
+    }
+
+    if (outOfBounds(env, off, len, bytes)) {
+        JNU_ThrowByName(env, "java/lang/IndexOutOfBoundsException", NULL);
+        return;
+    }
+
+    if (len == 0) {
+        return;
+    } else if (len > BUF_SIZE) {
+        buf = malloc(len);
+        if (buf == NULL) {
+            JNU_ThrowOutOfMemoryError(env, NULL);
+            return;
+        }
+    } else {
+        buf = stackBuf;
+    }
+
+    (*env)->GetByteArrayRegion(env, bytes, off, len, (jbyte *)buf);
+
+    if (!(*env)->ExceptionOccurred(env)) {
+        off = 0;
+        while (len > 0) {
+            fd = GET_FD(this, fid);
+            if (fd == -1) {
+                JNU_ThrowIOException(env, "Stream Closed");
+                break;
+            }
+            if (append == JNI_TRUE) {
+                n = (jint)IO_Append(fd, buf+off, len);
+            } else {
+                n = (jint)IO_Write(fd, buf+off, len);
+            }
+            if (n == JVM_IO_ERR) {
+                JNU_ThrowIOExceptionWithLastError(env, "Write error");
+                break;
+            } else if (n == JVM_IO_INTR) {
+                JNU_ThrowByName(env, "java/io/InterruptedIOException", NULL);
+                break;
+            }
+            off += n;
+            len -= n;
+        }
+    }
+    if (buf != stackBuf) {
+        free(buf);
+    }
+}
+
+void
+throwFileNotFoundException(JNIEnv *env, jstring path)
+{
+    char buf[256];
+    jint n;
+    jobject x;
+    jstring why = NULL;
+
+    n = JVM_GetLastErrorString(buf, sizeof(buf));
+    if (n > 0) {
+        why = JNU_NewStringPlatform(env, buf);
+    }
+    x = JNU_NewObjectByName(env,
+                            "java/io/FileNotFoundException",
+                            "(Ljava/lang/String;Ljava/lang/String;)V",
+                            path, why);
+    if (x != NULL) {
+        (*env)->Throw(env, x);
+    }
+}
diff --git a/ojluni/src/main/native/io_util.h b/ojluni/src/main/native/io_util.h
new file mode 100755
index 0000000..31088a9
--- /dev/null
+++ b/ojluni/src/main/native/io_util.h
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include "jni.h"
+#include "jni_util.h"
+
+extern jfieldID IO_fd_fdID;
+extern jfieldID IO_handle_fdID;
+
+#ifdef _ALLBSD_SOURCE
+#include <fcntl.h>
+#ifndef O_SYNC
+#define O_SYNC  O_FSYNC
+#endif
+#ifndef O_DSYNC
+#define O_DSYNC O_FSYNC
+#endif
+#elif !defined(O_DSYNC) || !defined(O_SYNC)
+#define O_SYNC  (0x0800)
+#define O_DSYNC (0x2000)
+#endif
+
+/*
+ * IO helper functions
+ */
+
+jint readSingle(JNIEnv *env, jobject this, jfieldID fid);
+jint readBytes(JNIEnv *env, jobject this, jbyteArray bytes, jint off,
+               jint len, jfieldID fid);
+void writeSingle(JNIEnv *env, jobject this, jint byte, jboolean append, jfieldID fid);
+void writeBytes(JNIEnv *env, jobject this, jbyteArray bytes, jint off,
+                jint len, jboolean append, jfieldID fid);
+void fileOpen(JNIEnv *env, jobject this, jstring path, jfieldID fid, int flags);
+void throwFileNotFoundException(JNIEnv *env, jstring path);
+
+
+/*
+ * Macros for managing platform strings.  The typical usage pattern is:
+ *
+ *     WITH_PLATFORM_STRING(env, string, var) {
+ *         doSomethingWith(var);
+ *     } END_PLATFORM_STRING(env, var);
+ *
+ *  where  env      is the prevailing JNIEnv,
+ *         string   is a JNI reference to a java.lang.String object, and
+ *         var      is the char * variable that will point to the string,
+ *                  after being converted into the platform encoding.
+ *
+ * The related macro WITH_FIELD_PLATFORM_STRING first extracts the string from
+ * a given field of a given object:
+ *
+ *     WITH_FIELD_PLATFORM_STRING(env, object, id, var) {
+ *         doSomethingWith(var);
+ *     } END_PLATFORM_STRING(env, var);
+ *
+ *  where  env      is the prevailing JNIEnv,
+ *         object   is a jobject,
+ *         id       is the field ID of the String field to be extracted, and
+ *         var      is the char * variable that will point to the string.
+ *
+ * Uses of these macros may be nested as long as each WITH_.._STRING macro
+ * declares a unique variable.
+ */
+
+#define WITH_PLATFORM_STRING(env, strexp, var)                                \
+    if (1) {                                                                  \
+        const char *var;                                                      \
+        jstring _##var##str = (strexp);                                       \
+        if (_##var##str == NULL) {                                            \
+            JNU_ThrowNullPointerException((env), NULL);                       \
+            goto _##var##end;                                                 \
+        }                                                                     \
+        var = JNU_GetStringPlatformChars((env), _##var##str, NULL);           \
+        if (var == NULL) goto _##var##end;
+
+#define WITH_FIELD_PLATFORM_STRING(env, object, id, var)                      \
+    WITH_PLATFORM_STRING(env,                                                 \
+                         ((object == NULL)                                    \
+                          ? NULL                                              \
+                          : (*(env))->GetObjectField((env), (object), (id))), \
+                         var)
+
+#define END_PLATFORM_STRING(env, var)                                         \
+        JNU_ReleaseStringPlatformChars(env, _##var##str, var);                \
+    _##var##end: ;                                                            \
+    } else ((void)NULL)
+
+
+/* Macros for transforming Java Strings into native Unicode strings.
+ * Works analogously to WITH_PLATFORM_STRING.
+ */
+
+#define WITH_UNICODE_STRING(env, strexp, var)                                 \
+    if (1) {                                                                  \
+        const jchar *var;                                                     \
+        jstring _##var##str = (strexp);                                       \
+        if (_##var##str == NULL) {                                            \
+            JNU_ThrowNullPointerException((env), NULL);                       \
+            goto _##var##end;                                                 \
+        }                                                                     \
+        var = (*(env))->GetStringChars((env), _##var##str, NULL);             \
+        if (var == NULL) goto _##var##end;
+
+#define END_UNICODE_STRING(env, var)                                          \
+        (*(env))->ReleaseStringChars(env, _##var##str, var);                  \
+    _##var##end: ;                                                            \
+    } else ((void)NULL)
diff --git a/ojluni/src/main/native/io_util_md.c b/ojluni/src/main/native/io_util_md.c
new file mode 100755
index 0000000..646e130
--- /dev/null
+++ b/ojluni/src/main/native/io_util_md.c
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include "jni.h"
+#include "jni_util.h"
+#include "jvm.h"
+#include "io_util.h"
+#include "io_util_md.h"
+#include <string.h>
+
+#ifdef MACOSX
+
+#include <CoreFoundation/CoreFoundation.h>
+
+__private_extern__
+jstring newStringPlatform(JNIEnv *env, const char* str)
+{
+    jstring rv = NULL;
+    CFMutableStringRef csref = CFStringCreateMutable(NULL, 0);
+    if (csref == NULL) {
+        JNU_ThrowOutOfMemoryError(env, "native heap");
+    } else {
+        CFStringAppendCString(csref, str, kCFStringEncodingUTF8);
+        CFStringNormalize(csref, kCFStringNormalizationFormC);
+        int clen = CFStringGetLength(csref);
+        int ulen = (clen + 1) * 2;        // utf16 + zero padding
+        char* chars = malloc(ulen);
+        if (chars == NULL) {
+            CFRelease(csref);
+            JNU_ThrowOutOfMemoryError(env, "native heap");
+        } else {
+            if (CFStringGetCString(csref, chars, ulen, kCFStringEncodingUTF16)) {
+                rv = (*env)->NewString(env, (jchar*)chars, clen);
+            }
+            free(chars);
+            CFRelease(csref);
+        }
+    }
+    return rv;
+}
+#endif
+
+void
+fileOpen(JNIEnv *env, jobject this, jstring path, jfieldID fid, int flags)
+{
+    WITH_PLATFORM_STRING(env, path, ps) {
+        FD fd;
+
+#if defined(__linux__) || defined(_ALLBSD_SOURCE)
+        /* Remove trailing slashes, since the kernel won't */
+        char *p = (char *)ps + strlen(ps) - 1;
+        while ((p > ps) && (*p == '/'))
+            *p-- = '\0';
+#endif
+        fd = JVM_Open(ps, flags, 0666);
+        if (fd >= 0) {
+            SET_FD(this, fd, fid);
+        } else {
+            throwFileNotFoundException(env, path);
+        }
+    } END_PLATFORM_STRING(env, ps);
+}
+
+
+void
+fileClose(JNIEnv *env, jobject this, jfieldID fid)
+{
+    FD fd = GET_FD(this, fid);
+    if (fd == -1) {
+        return;
+    }
+
+    /* Set the fd to -1 before closing it so that the timing window
+     * of other threads using the wrong fd (closed but recycled fd,
+     * that gets re-opened with some other filename) is reduced.
+     * Practically the chance of its occurance is low, however, we are
+     * taking extra precaution over here.
+     */
+    SET_FD(this, -1, fid);
+
+    /*
+     * Don't close file descriptors 0, 1, or 2. If we close these stream
+     * then a subsequent file open or socket will use them. Instead we
+     * just redirect these file descriptors to /dev/null.
+     */
+    if (fd >= STDIN_FILENO && fd <= STDERR_FILENO) {
+        int devnull = open("/dev/null", O_WRONLY);
+        if (devnull < 0) {
+            SET_FD(this, fd, fid); // restore fd
+            JNU_ThrowIOExceptionWithLastError(env, "open /dev/null failed");
+        } else {
+            dup2(devnull, fd);
+            close(devnull);
+        }
+    } else if (JVM_Close(fd) == -1) {
+        JNU_ThrowIOExceptionWithLastError(env, "close failed");
+    }
+}
diff --git a/ojluni/src/main/native/io_util_md.h b/ojluni/src/main/native/io_util_md.h
new file mode 100755
index 0000000..fbf8172
--- /dev/null
+++ b/ojluni/src/main/native/io_util_md.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include "jni.h"
+#include "jni_util.h"
+
+/*
+ * Macros to use the right data type for file descriptors
+ */
+#define FD jint
+
+/*
+ * Macros to set/get fd from the java.io.FileDescriptor.  These
+ * macros rely on having an appropriately defined 'this' object
+ * within the scope in which they're used.
+ * If GetObjectField returns null, SET_FD will stop and GET_FD
+ * will simply return -1 to avoid crashing VM.
+ */
+
+#define SET_FD(this, fd, fid) \
+    if ((*env)->GetObjectField(env, (this), (fid)) != NULL) \
+        (*env)->SetIntField(env, (*env)->GetObjectField(env, (this), (fid)),IO_fd_fdID, (fd))
+
+#define GET_FD(this, fid) \
+    (*env)->GetObjectField(env, (this), (fid)) == NULL ? \
+        -1 : (*env)->GetIntField(env, (*env)->GetObjectField(env, (this), (fid)), IO_fd_fdID)
+
+/*
+ * Macros to set/get fd when inside java.io.FileDescriptor
+ */
+#define THIS_FD(obj) (*env)->GetIntField(env, obj, IO_fd_fdID)
+
+/*
+ * Route the routines through VM
+ */
+#define IO_Append JVM_Write
+#define IO_Write JVM_Write
+#define IO_Sync JVM_Sync
+#define IO_Read JVM_Read
+#define IO_Lseek JVM_Lseek
+#define IO_Available JVM_Available
+#define IO_SetLength JVM_SetLength
+
+/*
+ * On Solaris, the handle field is unused
+ */
+#define SET_HANDLE(fd) return (jlong)-1
+
+/*
+ * IO helper function(s)
+ */
+void fileClose(JNIEnv *env, jobject this, jfieldID fid);
+
+#ifdef MACOSX
+jstring newStringPlatform(JNIEnv *env, const char* str);
+#endif
diff --git a/ojluni/src/main/native/java_io_FileDescriptor.h b/ojluni/src/main/native/java_io_FileDescriptor.h
new file mode 100755
index 0000000..1a776e3
--- /dev/null
+++ b/ojluni/src/main/native/java_io_FileDescriptor.h
@@ -0,0 +1,29 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class java_io_FileDescriptor */
+
+#ifndef _Included_java_io_FileDescriptor
+#define _Included_java_io_FileDescriptor
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class:     java_io_FileDescriptor
+ * Method:    sync
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_java_io_FileDescriptor_sync
+  (JNIEnv *, jobject);
+
+/*
+ * Class:     java_io_FileDescriptor
+ * Method:    initIDs
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_java_io_FileDescriptor_initIDs
+  (JNIEnv *, jclass);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/ojluni/src/main/native/java_io_FileInputStream.h b/ojluni/src/main/native/java_io_FileInputStream.h
new file mode 100755
index 0000000..4dae98a
--- /dev/null
+++ b/ojluni/src/main/native/java_io_FileInputStream.h
@@ -0,0 +1,71 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class java_io_FileInputStream */
+
+#ifndef _Included_java_io_FileInputStream
+#define _Included_java_io_FileInputStream
+#ifdef __cplusplus
+extern "C" {
+#endif
+#undef java_io_FileInputStream_MAX_SKIP_BUFFER_SIZE
+#define java_io_FileInputStream_MAX_SKIP_BUFFER_SIZE 2048L
+/*
+ * Class:     java_io_FileInputStream
+ * Method:    open
+ * Signature: (Ljava/lang/String;)V
+ */
+JNIEXPORT void JNICALL Java_java_io_FileInputStream_open
+  (JNIEnv *, jobject, jstring);
+
+/*
+ * Class:     java_io_FileInputStream
+ * Method:    read0
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL Java_java_io_FileInputStream_read0
+  (JNIEnv *, jobject);
+
+/*
+ * Class:     java_io_FileInputStream
+ * Method:    readBytes
+ * Signature: ([BII)I
+ */
+JNIEXPORT jint JNICALL Java_java_io_FileInputStream_readBytes
+  (JNIEnv *, jobject, jbyteArray, jint, jint);
+
+/*
+ * Class:     java_io_FileInputStream
+ * Method:    skip
+ * Signature: (J)J
+ */
+JNIEXPORT jlong JNICALL Java_java_io_FileInputStream_skip
+  (JNIEnv *, jobject, jlong);
+
+/*
+ * Class:     java_io_FileInputStream
+ * Method:    available
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL Java_java_io_FileInputStream_available
+  (JNIEnv *, jobject);
+
+/*
+ * Class:     java_io_FileInputStream
+ * Method:    initIDs
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_java_io_FileInputStream_initIDs
+  (JNIEnv *, jclass);
+
+/*
+ * Class:     java_io_FileInputStream
+ * Method:    close0
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_java_io_FileInputStream_close0
+  (JNIEnv *, jobject);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/ojluni/src/main/native/java_io_FileOutputStream.h b/ojluni/src/main/native/java_io_FileOutputStream.h
new file mode 100755
index 0000000..9741a28
--- /dev/null
+++ b/ojluni/src/main/native/java_io_FileOutputStream.h
@@ -0,0 +1,53 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class java_io_FileOutputStream */
+
+#ifndef _Included_java_io_FileOutputStream
+#define _Included_java_io_FileOutputStream
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class:     java_io_FileOutputStream
+ * Method:    open
+ * Signature: (Ljava/lang/String;Z)V
+ */
+JNIEXPORT void JNICALL Java_java_io_FileOutputStream_open
+  (JNIEnv *, jobject, jstring, jboolean);
+
+/*
+ * Class:     java_io_FileOutputStream
+ * Method:    write
+ * Signature: (IZ)V
+ */
+JNIEXPORT void JNICALL Java_java_io_FileOutputStream_write
+  (JNIEnv *, jobject, jint, jboolean);
+
+/*
+ * Class:     java_io_FileOutputStream
+ * Method:    writeBytes
+ * Signature: ([BIIZ)V
+ */
+JNIEXPORT void JNICALL Java_java_io_FileOutputStream_writeBytes
+  (JNIEnv *, jobject, jbyteArray, jint, jint, jboolean);
+
+/*
+ * Class:     java_io_FileOutputStream
+ * Method:    close0
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_java_io_FileOutputStream_close0
+  (JNIEnv *, jobject);
+
+/*
+ * Class:     java_io_FileOutputStream
+ * Method:    initIDs
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_java_io_FileOutputStream_initIDs
+  (JNIEnv *, jclass);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/ojluni/src/main/native/java_io_FileSystem.h b/ojluni/src/main/native/java_io_FileSystem.h
new file mode 100755
index 0000000..0a2105d
--- /dev/null
+++ b/ojluni/src/main/native/java_io_FileSystem.h
@@ -0,0 +1,41 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class java_io_FileSystem */
+
+#ifndef _Included_java_io_FileSystem
+#define _Included_java_io_FileSystem
+#ifdef __cplusplus
+extern "C" {
+#endif
+#undef java_io_FileSystem_BA_EXISTS
+#define java_io_FileSystem_BA_EXISTS 1L
+#undef java_io_FileSystem_BA_REGULAR
+#define java_io_FileSystem_BA_REGULAR 2L
+#undef java_io_FileSystem_BA_DIRECTORY
+#define java_io_FileSystem_BA_DIRECTORY 4L
+#undef java_io_FileSystem_BA_HIDDEN
+#define java_io_FileSystem_BA_HIDDEN 8L
+#undef java_io_FileSystem_ACCESS_READ
+#define java_io_FileSystem_ACCESS_READ 4L
+#undef java_io_FileSystem_ACCESS_WRITE
+#define java_io_FileSystem_ACCESS_WRITE 2L
+#undef java_io_FileSystem_ACCESS_EXECUTE
+#define java_io_FileSystem_ACCESS_EXECUTE 1L
+#undef java_io_FileSystem_SPACE_TOTAL
+#define java_io_FileSystem_SPACE_TOTAL 0L
+#undef java_io_FileSystem_SPACE_FREE
+#define java_io_FileSystem_SPACE_FREE 1L
+#undef java_io_FileSystem_SPACE_USABLE
+#define java_io_FileSystem_SPACE_USABLE 2L
+/*
+ * Class:     java_io_FileSystem
+ * Method:    getFileSystem
+ * Signature: ()Ljava/io/FileSystem;
+ */
+JNIEXPORT jobject JNICALL Java_java_io_FileSystem_getFileSystem
+  (JNIEnv *, jclass);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/ojluni/src/main/native/java_io_ObjectStreamClass.h b/ojluni/src/main/native/java_io_ObjectStreamClass.h
new file mode 100755
index 0000000..4e757c3
--- /dev/null
+++ b/ojluni/src/main/native/java_io_ObjectStreamClass.h
@@ -0,0 +1,31 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class java_io_ObjectStreamClass */
+
+#ifndef _Included_java_io_ObjectStreamClass
+#define _Included_java_io_ObjectStreamClass
+#ifdef __cplusplus
+extern "C" {
+#endif
+#undef java_io_ObjectStreamClass_serialVersionUID
+#define java_io_ObjectStreamClass_serialVersionUID -6120832682080437368LL
+/*
+ * Class:     java_io_ObjectStreamClass
+ * Method:    initNative
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_java_io_ObjectStreamClass_initNative
+  (JNIEnv *, jclass);
+
+/*
+ * Class:     java_io_ObjectStreamClass
+ * Method:    hasStaticInitializer
+ * Signature: (Ljava/lang/Class;)Z
+ */
+JNIEXPORT jboolean JNICALL Java_java_io_ObjectStreamClass_hasStaticInitializer
+  (JNIEnv *, jclass, jclass);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/ojluni/src/main/native/java_io_UnixFileSystem.h b/ojluni/src/main/native/java_io_UnixFileSystem.h
new file mode 100755
index 0000000..249fa79
--- /dev/null
+++ b/ojluni/src/main/native/java_io_UnixFileSystem.h
@@ -0,0 +1,153 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class java_io_UnixFileSystem */
+
+#ifndef _Included_java_io_UnixFileSystem
+#define _Included_java_io_UnixFileSystem
+#ifdef __cplusplus
+extern "C" {
+#endif
+#undef java_io_UnixFileSystem_BA_EXISTS
+#define java_io_UnixFileSystem_BA_EXISTS 1L
+#undef java_io_UnixFileSystem_BA_REGULAR
+#define java_io_UnixFileSystem_BA_REGULAR 2L
+#undef java_io_UnixFileSystem_BA_DIRECTORY
+#define java_io_UnixFileSystem_BA_DIRECTORY 4L
+#undef java_io_UnixFileSystem_BA_HIDDEN
+#define java_io_UnixFileSystem_BA_HIDDEN 8L
+#undef java_io_UnixFileSystem_ACCESS_READ
+#define java_io_UnixFileSystem_ACCESS_READ 4L
+#undef java_io_UnixFileSystem_ACCESS_WRITE
+#define java_io_UnixFileSystem_ACCESS_WRITE 2L
+#undef java_io_UnixFileSystem_ACCESS_EXECUTE
+#define java_io_UnixFileSystem_ACCESS_EXECUTE 1L
+#undef java_io_UnixFileSystem_SPACE_TOTAL
+#define java_io_UnixFileSystem_SPACE_TOTAL 0L
+#undef java_io_UnixFileSystem_SPACE_FREE
+#define java_io_UnixFileSystem_SPACE_FREE 1L
+#undef java_io_UnixFileSystem_SPACE_USABLE
+#define java_io_UnixFileSystem_SPACE_USABLE 2L
+/*
+ * Class:     java_io_UnixFileSystem
+ * Method:    canonicalize0
+ * Signature: (Ljava/lang/String;)Ljava/lang/String;
+ */
+JNIEXPORT jstring JNICALL Java_java_io_UnixFileSystem_canonicalize0
+  (JNIEnv *, jobject, jstring);
+
+/*
+ * Class:     java_io_UnixFileSystem
+ * Method:    getBooleanAttributes0
+ * Signature: (Ljava/io/File;)I
+ */
+JNIEXPORT jint JNICALL Java_java_io_UnixFileSystem_getBooleanAttributes0
+  (JNIEnv *, jobject, jobject);
+
+/*
+ * Class:     java_io_UnixFileSystem
+ * Method:    checkAccess
+ * Signature: (Ljava/io/File;I)Z
+ */
+JNIEXPORT jboolean JNICALL Java_java_io_UnixFileSystem_checkAccess
+  (JNIEnv *, jobject, jobject, jint);
+
+/*
+ * Class:     java_io_UnixFileSystem
+ * Method:    getLastModifiedTime
+ * Signature: (Ljava/io/File;)J
+ */
+JNIEXPORT jlong JNICALL Java_java_io_UnixFileSystem_getLastModifiedTime
+  (JNIEnv *, jobject, jobject);
+
+/*
+ * Class:     java_io_UnixFileSystem
+ * Method:    getLength
+ * Signature: (Ljava/io/File;)J
+ */
+JNIEXPORT jlong JNICALL Java_java_io_UnixFileSystem_getLength
+  (JNIEnv *, jobject, jobject);
+
+/*
+ * Class:     java_io_UnixFileSystem
+ * Method:    setPermission
+ * Signature: (Ljava/io/File;IZZ)Z
+ */
+JNIEXPORT jboolean JNICALL Java_java_io_UnixFileSystem_setPermission
+  (JNIEnv *, jobject, jobject, jint, jboolean, jboolean);
+
+/*
+ * Class:     java_io_UnixFileSystem
+ * Method:    createFileExclusively
+ * Signature: (Ljava/lang/String;)Z
+ */
+JNIEXPORT jboolean JNICALL Java_java_io_UnixFileSystem_createFileExclusively
+  (JNIEnv *, jobject, jstring);
+
+/*
+ * Class:     java_io_UnixFileSystem
+ * Method:    delete0
+ * Signature: (Ljava/io/File;)Z
+ */
+JNIEXPORT jboolean JNICALL Java_java_io_UnixFileSystem_delete0
+  (JNIEnv *, jobject, jobject);
+
+/*
+ * Class:     java_io_UnixFileSystem
+ * Method:    list
+ * Signature: (Ljava/io/File;)[Ljava/lang/String;
+ */
+JNIEXPORT jobjectArray JNICALL Java_java_io_UnixFileSystem_list
+  (JNIEnv *, jobject, jobject);
+
+/*
+ * Class:     java_io_UnixFileSystem
+ * Method:    createDirectory
+ * Signature: (Ljava/io/File;)Z
+ */
+JNIEXPORT jboolean JNICALL Java_java_io_UnixFileSystem_createDirectory
+  (JNIEnv *, jobject, jobject);
+
+/*
+ * Class:     java_io_UnixFileSystem
+ * Method:    rename0
+ * Signature: (Ljava/io/File;Ljava/io/File;)Z
+ */
+JNIEXPORT jboolean JNICALL Java_java_io_UnixFileSystem_rename0
+  (JNIEnv *, jobject, jobject, jobject);
+
+/*
+ * Class:     java_io_UnixFileSystem
+ * Method:    setLastModifiedTime
+ * Signature: (Ljava/io/File;J)Z
+ */
+JNIEXPORT jboolean JNICALL Java_java_io_UnixFileSystem_setLastModifiedTime
+  (JNIEnv *, jobject, jobject, jlong);
+
+/*
+ * Class:     java_io_UnixFileSystem
+ * Method:    setReadOnly
+ * Signature: (Ljava/io/File;)Z
+ */
+JNIEXPORT jboolean JNICALL Java_java_io_UnixFileSystem_setReadOnly
+  (JNIEnv *, jobject, jobject);
+
+/*
+ * Class:     java_io_UnixFileSystem
+ * Method:    getSpace
+ * Signature: (Ljava/io/File;I)J
+ */
+JNIEXPORT jlong JNICALL Java_java_io_UnixFileSystem_getSpace
+  (JNIEnv *, jobject, jobject, jint);
+
+/*
+ * Class:     java_io_UnixFileSystem
+ * Method:    initIDs
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_java_io_UnixFileSystem_initIDs
+  (JNIEnv *, jclass);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/ojluni/src/main/native/java_lang_Double.h b/ojluni/src/main/native/java_lang_Double.h
new file mode 100755
index 0000000..37ae67f
--- /dev/null
+++ b/ojluni/src/main/native/java_lang_Double.h
@@ -0,0 +1,51 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class java_lang_Double */
+
+#ifndef _Included_java_lang_Double
+#define _Included_java_lang_Double
+#ifdef __cplusplus
+extern "C" {
+#endif
+#undef java_lang_Double_serialVersionUID
+#define java_lang_Double_serialVersionUID -8742448824652078965LL
+#undef java_lang_Double_POSITIVE_INFINITY
+#define java_lang_Double_POSITIVE_INFINITY InfD
+#undef java_lang_Double_NEGATIVE_INFINITY
+#define java_lang_Double_NEGATIVE_INFINITY -InfD
+#undef java_lang_Double_NaN
+#define java_lang_Double_NaN NaN
+#undef java_lang_Double_MAX_VALUE
+#define java_lang_Double_MAX_VALUE 1.7976931348623157E308
+#undef java_lang_Double_MIN_NORMAL
+#define java_lang_Double_MIN_NORMAL 2.2250738585072014E-308
+#undef java_lang_Double_MIN_VALUE
+#define java_lang_Double_MIN_VALUE 4.9E-324
+#undef java_lang_Double_MAX_EXPONENT
+#define java_lang_Double_MAX_EXPONENT 1023L
+#undef java_lang_Double_MIN_EXPONENT
+#define java_lang_Double_MIN_EXPONENT -1022L
+#undef java_lang_Double_SIZE
+#define java_lang_Double_SIZE 64L
+#undef java_lang_Double_serialVersionUID
+#define java_lang_Double_serialVersionUID -9172774392245257468LL
+/*
+ * Class:     java_lang_Double
+ * Method:    doubleToRawLongBits
+ * Signature: (D)J
+ */
+JNIEXPORT jlong JNICALL Java_java_lang_Double_doubleToRawLongBits
+  (JNIEnv *, jclass, jdouble);
+
+/*
+ * Class:     java_lang_Double
+ * Method:    longBitsToDouble
+ * Signature: (J)D
+ */
+JNIEXPORT jdouble JNICALL Java_java_lang_Double_longBitsToDouble
+  (JNIEnv *, jclass, jlong);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/ojluni/src/main/native/java_lang_Float.h b/ojluni/src/main/native/java_lang_Float.h
new file mode 100755
index 0000000..5e77a7d
--- /dev/null
+++ b/ojluni/src/main/native/java_lang_Float.h
@@ -0,0 +1,51 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class java_lang_Float */
+
+#ifndef _Included_java_lang_Float
+#define _Included_java_lang_Float
+#ifdef __cplusplus
+extern "C" {
+#endif
+#undef java_lang_Float_serialVersionUID
+#define java_lang_Float_serialVersionUID -8742448824652078965LL
+#undef java_lang_Float_POSITIVE_INFINITY
+#define java_lang_Float_POSITIVE_INFINITY Inff
+#undef java_lang_Float_NEGATIVE_INFINITY
+#define java_lang_Float_NEGATIVE_INFINITY -Inff
+#undef java_lang_Float_NaN
+#define java_lang_Float_NaN NaNf
+#undef java_lang_Float_MAX_VALUE
+#define java_lang_Float_MAX_VALUE 3.4028235E38f
+#undef java_lang_Float_MIN_NORMAL
+#define java_lang_Float_MIN_NORMAL 1.17549435E-38f
+#undef java_lang_Float_MIN_VALUE
+#define java_lang_Float_MIN_VALUE 1.4E-45f
+#undef java_lang_Float_MAX_EXPONENT
+#define java_lang_Float_MAX_EXPONENT 127L
+#undef java_lang_Float_MIN_EXPONENT
+#define java_lang_Float_MIN_EXPONENT -126L
+#undef java_lang_Float_SIZE
+#define java_lang_Float_SIZE 32L
+#undef java_lang_Float_serialVersionUID
+#define java_lang_Float_serialVersionUID -2671257302660747028LL
+/*
+ * Class:     java_lang_Float
+ * Method:    floatToRawIntBits
+ * Signature: (F)I
+ */
+JNIEXPORT jint JNICALL Java_java_lang_Float_floatToRawIntBits
+  (JNIEnv *, jclass, jfloat);
+
+/*
+ * Class:     java_lang_Float
+ * Method:    intBitsToFloat
+ * Signature: (I)F
+ */
+JNIEXPORT jfloat JNICALL Java_java_lang_Float_intBitsToFloat
+  (JNIEnv *, jclass, jint);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/ojluni/src/main/native/java_lang_Integer.h b/ojluni/src/main/native/java_lang_Integer.h
new file mode 100755
index 0000000..94c8788
--- /dev/null
+++ b/ojluni/src/main/native/java_lang_Integer.h
@@ -0,0 +1,23 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class java_lang_Integer */
+
+#ifndef _Included_java_lang_Integer
+#define _Included_java_lang_Integer
+#ifdef __cplusplus
+extern "C" {
+#endif
+#undef java_lang_Integer_serialVersionUID
+#define java_lang_Integer_serialVersionUID -8742448824652078965LL
+#undef java_lang_Integer_MIN_VALUE
+#define java_lang_Integer_MIN_VALUE -2147483648L
+#undef java_lang_Integer_MAX_VALUE
+#define java_lang_Integer_MAX_VALUE 2147483647L
+#undef java_lang_Integer_SIZE
+#define java_lang_Integer_SIZE 32L
+#undef java_lang_Integer_serialVersionUID
+#define java_lang_Integer_serialVersionUID 1360826667806852920LL
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/ojluni/src/main/native/java_lang_Long.h b/ojluni/src/main/native/java_lang_Long.h
new file mode 100755
index 0000000..a0953b3
--- /dev/null
+++ b/ojluni/src/main/native/java_lang_Long.h
@@ -0,0 +1,23 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class java_lang_Long */
+
+#ifndef _Included_java_lang_Long
+#define _Included_java_lang_Long
+#ifdef __cplusplus
+extern "C" {
+#endif
+#undef java_lang_Long_serialVersionUID
+#define java_lang_Long_serialVersionUID -8742448824652078965LL
+#undef java_lang_Long_MIN_VALUE
+#define java_lang_Long_MIN_VALUE -9223372036854775808LL
+#undef java_lang_Long_MAX_VALUE
+#define java_lang_Long_MAX_VALUE 9223372036854775807LL
+#undef java_lang_Long_SIZE
+#define java_lang_Long_SIZE 64L
+#undef java_lang_Long_serialVersionUID
+#define java_lang_Long_serialVersionUID 4290774380558885855LL
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/ojluni/src/main/native/java_lang_Runtime.h b/ojluni/src/main/native/java_lang_Runtime.h
new file mode 100755
index 0000000..2ba3dac
--- /dev/null
+++ b/ojluni/src/main/native/java_lang_Runtime.h
@@ -0,0 +1,77 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class java_lang_Runtime */
+
+#ifndef _Included_java_lang_Runtime
+#define _Included_java_lang_Runtime
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class:     java_lang_Runtime
+ * Method:    availableProcessors
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL Java_java_lang_Runtime_availableProcessors
+  (JNIEnv *, jobject);
+
+/*
+ * Class:     java_lang_Runtime
+ * Method:    freeMemory
+ * Signature: ()J
+ */
+JNIEXPORT jlong JNICALL Java_java_lang_Runtime_freeMemory
+  (JNIEnv *, jobject);
+
+/*
+ * Class:     java_lang_Runtime
+ * Method:    totalMemory
+ * Signature: ()J
+ */
+JNIEXPORT jlong JNICALL Java_java_lang_Runtime_totalMemory
+  (JNIEnv *, jobject);
+
+/*
+ * Class:     java_lang_Runtime
+ * Method:    maxMemory
+ * Signature: ()J
+ */
+JNIEXPORT jlong JNICALL Java_java_lang_Runtime_maxMemory
+  (JNIEnv *, jobject);
+
+/*
+ * Class:     java_lang_Runtime
+ * Method:    gc
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_java_lang_Runtime_gc
+  (JNIEnv *, jobject);
+
+/*
+ * Class:     java_lang_Runtime
+ * Method:    runFinalization0
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_java_lang_Runtime_runFinalization0
+  (JNIEnv *, jclass);
+
+/*
+ * Class:     java_lang_Runtime
+ * Method:    traceInstructions
+ * Signature: (Z)V
+ */
+JNIEXPORT void JNICALL Java_java_lang_Runtime_traceInstructions
+  (JNIEnv *, jobject, jboolean);
+
+/*
+ * Class:     java_lang_Runtime
+ * Method:    traceMethodCalls
+ * Signature: (Z)V
+ */
+JNIEXPORT void JNICALL Java_java_lang_Runtime_traceMethodCalls
+  (JNIEnv *, jobject, jboolean);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/ojluni/src/main/native/java_lang_Shutdown.h b/ojluni/src/main/native/java_lang_Shutdown.h
new file mode 100755
index 0000000..33a3592
--- /dev/null
+++ b/ojluni/src/main/native/java_lang_Shutdown.h
@@ -0,0 +1,37 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class java_lang_Shutdown */
+
+#ifndef _Included_java_lang_Shutdown
+#define _Included_java_lang_Shutdown
+#ifdef __cplusplus
+extern "C" {
+#endif
+#undef java_lang_Shutdown_RUNNING
+#define java_lang_Shutdown_RUNNING 0L
+#undef java_lang_Shutdown_HOOKS
+#define java_lang_Shutdown_HOOKS 1L
+#undef java_lang_Shutdown_FINALIZERS
+#define java_lang_Shutdown_FINALIZERS 2L
+#undef java_lang_Shutdown_MAX_SYSTEM_HOOKS
+#define java_lang_Shutdown_MAX_SYSTEM_HOOKS 10L
+/*
+ * Class:     java_lang_Shutdown
+ * Method:    halt0
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL Java_java_lang_Shutdown_halt0
+  (JNIEnv *, jclass, jint);
+
+/*
+ * Class:     java_lang_Shutdown
+ * Method:    runAllFinalizers
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_java_lang_Shutdown_runAllFinalizers
+  (JNIEnv *, jclass);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/ojluni/src/main/native/java_lang_StrictMath.h b/ojluni/src/main/native/java_lang_StrictMath.h
new file mode 100755
index 0000000..0756f83
--- /dev/null
+++ b/ojluni/src/main/native/java_lang_StrictMath.h
@@ -0,0 +1,177 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class java_lang_StrictMath */
+
+#ifndef _Included_java_lang_StrictMath
+#define _Included_java_lang_StrictMath
+#ifdef __cplusplus
+extern "C" {
+#endif
+#undef java_lang_StrictMath_E
+#define java_lang_StrictMath_E 2.718281828459045
+#undef java_lang_StrictMath_PI
+#define java_lang_StrictMath_PI 3.141592653589793
+/*
+ * Class:     java_lang_StrictMath
+ * Method:    sin
+ * Signature: (D)D
+ */
+JNIEXPORT jdouble JNICALL Java_java_lang_StrictMath_sin
+  (JNIEnv *, jclass, jdouble);
+
+/*
+ * Class:     java_lang_StrictMath
+ * Method:    cos
+ * Signature: (D)D
+ */
+JNIEXPORT jdouble JNICALL Java_java_lang_StrictMath_cos
+  (JNIEnv *, jclass, jdouble);
+
+/*
+ * Class:     java_lang_StrictMath
+ * Method:    tan
+ * Signature: (D)D
+ */
+JNIEXPORT jdouble JNICALL Java_java_lang_StrictMath_tan
+  (JNIEnv *, jclass, jdouble);
+
+/*
+ * Class:     java_lang_StrictMath
+ * Method:    asin
+ * Signature: (D)D
+ */
+JNIEXPORT jdouble JNICALL Java_java_lang_StrictMath_asin
+  (JNIEnv *, jclass, jdouble);
+
+/*
+ * Class:     java_lang_StrictMath
+ * Method:    acos
+ * Signature: (D)D
+ */
+JNIEXPORT jdouble JNICALL Java_java_lang_StrictMath_acos
+  (JNIEnv *, jclass, jdouble);
+
+/*
+ * Class:     java_lang_StrictMath
+ * Method:    atan
+ * Signature: (D)D
+ */
+JNIEXPORT jdouble JNICALL Java_java_lang_StrictMath_atan
+  (JNIEnv *, jclass, jdouble);
+
+/*
+ * Class:     java_lang_StrictMath
+ * Method:    exp
+ * Signature: (D)D
+ */
+JNIEXPORT jdouble JNICALL Java_java_lang_StrictMath_exp
+  (JNIEnv *, jclass, jdouble);
+
+/*
+ * Class:     java_lang_StrictMath
+ * Method:    log
+ * Signature: (D)D
+ */
+JNIEXPORT jdouble JNICALL Java_java_lang_StrictMath_log
+  (JNIEnv *, jclass, jdouble);
+
+/*
+ * Class:     java_lang_StrictMath
+ * Method:    log10
+ * Signature: (D)D
+ */
+JNIEXPORT jdouble JNICALL Java_java_lang_StrictMath_log10
+  (JNIEnv *, jclass, jdouble);
+
+/*
+ * Class:     java_lang_StrictMath
+ * Method:    sqrt
+ * Signature: (D)D
+ */
+JNIEXPORT jdouble JNICALL Java_java_lang_StrictMath_sqrt
+  (JNIEnv *, jclass, jdouble);
+
+/*
+ * Class:     java_lang_StrictMath
+ * Method:    cbrt
+ * Signature: (D)D
+ */
+JNIEXPORT jdouble JNICALL Java_java_lang_StrictMath_cbrt
+  (JNIEnv *, jclass, jdouble);
+
+/*
+ * Class:     java_lang_StrictMath
+ * Method:    IEEEremainder
+ * Signature: (DD)D
+ */
+JNIEXPORT jdouble JNICALL Java_java_lang_StrictMath_IEEEremainder
+  (JNIEnv *, jclass, jdouble, jdouble);
+
+/*
+ * Class:     java_lang_StrictMath
+ * Method:    atan2
+ * Signature: (DD)D
+ */
+JNIEXPORT jdouble JNICALL Java_java_lang_StrictMath_atan2
+  (JNIEnv *, jclass, jdouble, jdouble);
+
+/*
+ * Class:     java_lang_StrictMath
+ * Method:    pow
+ * Signature: (DD)D
+ */
+JNIEXPORT jdouble JNICALL Java_java_lang_StrictMath_pow
+  (JNIEnv *, jclass, jdouble, jdouble);
+
+/*
+ * Class:     java_lang_StrictMath
+ * Method:    sinh
+ * Signature: (D)D
+ */
+JNIEXPORT jdouble JNICALL Java_java_lang_StrictMath_sinh
+  (JNIEnv *, jclass, jdouble);
+
+/*
+ * Class:     java_lang_StrictMath
+ * Method:    cosh
+ * Signature: (D)D
+ */
+JNIEXPORT jdouble JNICALL Java_java_lang_StrictMath_cosh
+  (JNIEnv *, jclass, jdouble);
+
+/*
+ * Class:     java_lang_StrictMath
+ * Method:    tanh
+ * Signature: (D)D
+ */
+JNIEXPORT jdouble JNICALL Java_java_lang_StrictMath_tanh
+  (JNIEnv *, jclass, jdouble);
+
+/*
+ * Class:     java_lang_StrictMath
+ * Method:    hypot
+ * Signature: (DD)D
+ */
+JNIEXPORT jdouble JNICALL Java_java_lang_StrictMath_hypot
+  (JNIEnv *, jclass, jdouble, jdouble);
+
+/*
+ * Class:     java_lang_StrictMath
+ * Method:    expm1
+ * Signature: (D)D
+ */
+JNIEXPORT jdouble JNICALL Java_java_lang_StrictMath_expm1
+  (JNIEnv *, jclass, jdouble);
+
+/*
+ * Class:     java_lang_StrictMath
+ * Method:    log1p
+ * Signature: (D)D
+ */
+JNIEXPORT jdouble JNICALL Java_java_lang_StrictMath_log1p
+  (JNIEnv *, jclass, jdouble);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/ojluni/src/main/native/java_lang_String.h b/ojluni/src/main/native/java_lang_String.h
new file mode 100755
index 0000000..d398a14
--- /dev/null
+++ b/ojluni/src/main/native/java_lang_String.h
@@ -0,0 +1,23 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class java_lang_String */
+
+#ifndef _Included_java_lang_String
+#define _Included_java_lang_String
+#ifdef __cplusplus
+extern "C" {
+#endif
+#undef java_lang_String_serialVersionUID
+#define java_lang_String_serialVersionUID -6849794470754667710LL
+/*
+ * Class:     java_lang_String
+ * Method:    intern
+ * Signature: ()Ljava/lang/String;
+ */
+JNIEXPORT jstring JNICALL Java_java_lang_String_intern
+  (JNIEnv *, jobject);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/ojluni/src/main/native/java_lang_System.h b/ojluni/src/main/native/java_lang_System.h
new file mode 100755
index 0000000..9e2e7c3
--- /dev/null
+++ b/ojluni/src/main/native/java_lang_System.h
@@ -0,0 +1,93 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class java_lang_System */
+
+#ifndef _Included_java_lang_System
+#define _Included_java_lang_System
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class:     java_lang_System
+ * Method:    registerNatives
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_java_lang_System_registerNatives
+  (JNIEnv *, jclass);
+
+/*
+ * Class:     java_lang_System
+ * Method:    setIn0
+ * Signature: (Ljava/io/InputStream;)V
+ */
+JNIEXPORT void JNICALL Java_java_lang_System_setIn0
+  (JNIEnv *, jclass, jobject);
+
+/*
+ * Class:     java_lang_System
+ * Method:    setOut0
+ * Signature: (Ljava/io/PrintStream;)V
+ */
+JNIEXPORT void JNICALL Java_java_lang_System_setOut0
+  (JNIEnv *, jclass, jobject);
+
+/*
+ * Class:     java_lang_System
+ * Method:    setErr0
+ * Signature: (Ljava/io/PrintStream;)V
+ */
+JNIEXPORT void JNICALL Java_java_lang_System_setErr0
+  (JNIEnv *, jclass, jobject);
+
+/*
+ * Class:     java_lang_System
+ * Method:    currentTimeMillis
+ * Signature: ()J
+ */
+JNIEXPORT jlong JNICALL Java_java_lang_System_currentTimeMillis
+  (JNIEnv *, jclass);
+
+/*
+ * Class:     java_lang_System
+ * Method:    nanoTime
+ * Signature: ()J
+ */
+JNIEXPORT jlong JNICALL Java_java_lang_System_nanoTime
+  (JNIEnv *, jclass);
+
+/*
+ * Class:     java_lang_System
+ * Method:    arraycopy
+ * Signature: (Ljava/lang/Object;ILjava/lang/Object;II)V
+ */
+JNIEXPORT void JNICALL Java_java_lang_System_arraycopy
+  (JNIEnv *, jclass, jobject, jint, jobject, jint, jint);
+
+/*
+ * Class:     java_lang_System
+ * Method:    identityHashCode
+ * Signature: (Ljava/lang/Object;)I
+ */
+JNIEXPORT jint JNICALL Java_java_lang_System_identityHashCode
+  (JNIEnv *, jclass, jobject);
+
+/*
+ * Class:     java_lang_System
+ * Method:    initProperties
+ * Signature: (Ljava/util/Properties;)Ljava/util/Properties;
+ */
+JNIEXPORT jobject JNICALL Java_java_lang_System_initProperties
+  (JNIEnv *, jclass, jobject);
+
+/*
+ * Class:     java_lang_System
+ * Method:    mapLibraryName
+ * Signature: (Ljava/lang/String;)Ljava/lang/String;
+ */
+JNIEXPORT jstring JNICALL Java_java_lang_System_mapLibraryName
+  (JNIEnv *, jclass, jstring);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/ojluni/src/main/native/java_lang_Thread.h b/ojluni/src/main/native/java_lang_Thread.h
new file mode 100755
index 0000000..e2778f6
--- /dev/null
+++ b/ojluni/src/main/native/java_lang_Thread.h
@@ -0,0 +1,155 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class java_lang_Thread */
+
+#ifndef _Included_java_lang_Thread
+#define _Included_java_lang_Thread
+#ifdef __cplusplus
+extern "C" {
+#endif
+#undef java_lang_Thread_MIN_PRIORITY
+#define java_lang_Thread_MIN_PRIORITY 1L
+#undef java_lang_Thread_NORM_PRIORITY
+#define java_lang_Thread_NORM_PRIORITY 5L
+#undef java_lang_Thread_MAX_PRIORITY
+#define java_lang_Thread_MAX_PRIORITY 10L
+/*
+ * Class:     java_lang_Thread
+ * Method:    registerNatives
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_java_lang_Thread_registerNatives
+  (JNIEnv *, jclass);
+
+/*
+ * Class:     java_lang_Thread
+ * Method:    currentThread
+ * Signature: ()Ljava/lang/Thread;
+ */
+JNIEXPORT jobject JNICALL Java_java_lang_Thread_currentThread
+  (JNIEnv *, jclass);
+
+/*
+ * Class:     java_lang_Thread
+ * Method:    yield
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_java_lang_Thread_yield
+  (JNIEnv *, jclass);
+
+/*
+ * Class:     java_lang_Thread
+ * Method:    sleep
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_java_lang_Thread_sleep
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     java_lang_Thread
+ * Method:    start0
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_java_lang_Thread_start0
+  (JNIEnv *, jobject);
+
+/*
+ * Class:     java_lang_Thread
+ * Method:    isInterrupted
+ * Signature: (Z)Z
+ */
+JNIEXPORT jboolean JNICALL Java_java_lang_Thread_isInterrupted
+  (JNIEnv *, jobject, jboolean);
+
+/*
+ * Class:     java_lang_Thread
+ * Method:    isAlive
+ * Signature: ()Z
+ */
+JNIEXPORT jboolean JNICALL Java_java_lang_Thread_isAlive
+  (JNIEnv *, jobject);
+
+/*
+ * Class:     java_lang_Thread
+ * Method:    countStackFrames
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL Java_java_lang_Thread_countStackFrames
+  (JNIEnv *, jobject);
+
+/*
+ * Class:     java_lang_Thread
+ * Method:    holdsLock
+ * Signature: (Ljava/lang/Object;)Z
+ */
+JNIEXPORT jboolean JNICALL Java_java_lang_Thread_holdsLock
+  (JNIEnv *, jclass, jobject);
+
+/*
+ * Class:     java_lang_Thread
+ * Method:    dumpThreads
+ * Signature: ([Ljava/lang/Thread;)[[Ljava/lang/StackTraceElement;
+ */
+JNIEXPORT jobjectArray JNICALL Java_java_lang_Thread_dumpThreads
+  (JNIEnv *, jclass, jobjectArray);
+
+/*
+ * Class:     java_lang_Thread
+ * Method:    getThreads
+ * Signature: ()[Ljava/lang/Thread;
+ */
+JNIEXPORT jobjectArray JNICALL Java_java_lang_Thread_getThreads
+  (JNIEnv *, jclass);
+
+/*
+ * Class:     java_lang_Thread
+ * Method:    setPriority0
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL Java_java_lang_Thread_setPriority0
+  (JNIEnv *, jobject, jint);
+
+/*
+ * Class:     java_lang_Thread
+ * Method:    stop0
+ * Signature: (Ljava/lang/Object;)V
+ */
+JNIEXPORT void JNICALL Java_java_lang_Thread_stop0
+  (JNIEnv *, jobject, jobject);
+
+/*
+ * Class:     java_lang_Thread
+ * Method:    suspend0
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_java_lang_Thread_suspend0
+  (JNIEnv *, jobject);
+
+/*
+ * Class:     java_lang_Thread
+ * Method:    resume0
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_java_lang_Thread_resume0
+  (JNIEnv *, jobject);
+
+/*
+ * Class:     java_lang_Thread
+ * Method:    interrupt0
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_java_lang_Thread_interrupt0
+  (JNIEnv *, jobject);
+
+/*
+ * Class:     java_lang_Thread
+ * Method:    setNativeName
+ * Signature: (Ljava/lang/String;)V
+ */
+JNIEXPORT void JNICALL Java_java_lang_Thread_setNativeName
+  (JNIEnv *, jobject, jstring);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/ojluni/src/main/native/java_lang_Throwable.h b/ojluni/src/main/native/java_lang_Throwable.h
new file mode 100755
index 0000000..fd93e9f
--- /dev/null
+++ b/ojluni/src/main/native/java_lang_Throwable.h
@@ -0,0 +1,39 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class java_lang_Throwable */
+
+#ifndef _Included_java_lang_Throwable
+#define _Included_java_lang_Throwable
+#ifdef __cplusplus
+extern "C" {
+#endif
+#undef java_lang_Throwable_serialVersionUID
+#define java_lang_Throwable_serialVersionUID -3042686055658047285LL
+/*
+ * Class:     java_lang_Throwable
+ * Method:    fillInStackTrace
+ * Signature: (I)Ljava/lang/Throwable;
+ */
+JNIEXPORT jthrowable JNICALL Java_java_lang_Throwable_fillInStackTrace
+  (JNIEnv *, jobject, jint);
+
+/*
+ * Class:     java_lang_Throwable
+ * Method:    getStackTraceDepth
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL Java_java_lang_Throwable_getStackTraceDepth
+  (JNIEnv *, jobject);
+
+/*
+ * Class:     java_lang_Throwable
+ * Method:    getStackTraceElement
+ * Signature: (I)Ljava/lang/StackTraceElement;
+ */
+JNIEXPORT jobject JNICALL Java_java_lang_Throwable_getStackTraceElement
+  (JNIEnv *, jobject, jint);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/ojluni/src/main/native/java_net_DatagramPacket.h b/ojluni/src/main/native/java_net_DatagramPacket.h
new file mode 100755
index 0000000..456b353
--- /dev/null
+++ b/ojluni/src/main/native/java_net_DatagramPacket.h
@@ -0,0 +1,21 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class java_net_DatagramPacket */
+
+#ifndef _Included_java_net_DatagramPacket
+#define _Included_java_net_DatagramPacket
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class:     java_net_DatagramPacket
+ * Method:    init
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_java_net_DatagramPacket_init
+  (JNIEnv *, jclass);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/ojluni/src/main/native/java_net_Inet4Address.h b/ojluni/src/main/native/java_net_Inet4Address.h
new file mode 100755
index 0000000..9a618a5
--- /dev/null
+++ b/ojluni/src/main/native/java_net_Inet4Address.h
@@ -0,0 +1,35 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class java_net_Inet4Address */
+
+#ifndef _Included_java_net_Inet4Address
+#define _Included_java_net_Inet4Address
+#ifdef __cplusplus
+extern "C" {
+#endif
+#undef java_net_Inet4Address_IPv4
+#define java_net_Inet4Address_IPv4 1L
+#undef java_net_Inet4Address_IPv6
+#define java_net_Inet4Address_IPv6 2L
+#undef java_net_Inet4Address_serialVersionUID
+#define java_net_Inet4Address_serialVersionUID 3286316764910316507LL
+#undef java_net_Inet4Address_maxCacheTime
+#define java_net_Inet4Address_maxCacheTime 5000LL
+#undef java_net_Inet4Address_INADDRSZ
+#define java_net_Inet4Address_INADDRSZ 4L
+#undef java_net_Inet4Address_serialVersionUID
+#define java_net_Inet4Address_serialVersionUID 3286316764910316507LL
+#undef java_net_Inet4Address_loopback
+#define java_net_Inet4Address_loopback 2130706433L
+/*
+ * Class:     java_net_Inet4Address
+ * Method:    init
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_java_net_Inet4Address_init
+  (JNIEnv *, jclass);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/ojluni/src/main/native/java_net_Inet4AddressImpl.h b/ojluni/src/main/native/java_net_Inet4AddressImpl.h
new file mode 100755
index 0000000..fbf88af
--- /dev/null
+++ b/ojluni/src/main/native/java_net_Inet4AddressImpl.h
@@ -0,0 +1,45 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class java_net_Inet4AddressImpl */
+
+#ifndef _Included_java_net_Inet4AddressImpl
+#define _Included_java_net_Inet4AddressImpl
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class:     java_net_Inet4AddressImpl
+ * Method:    getLocalHostName
+ * Signature: ()Ljava/lang/String;
+ */
+JNIEXPORT jstring JNICALL Java_java_net_Inet4AddressImpl_getLocalHostName
+  (JNIEnv *, jobject);
+
+/*
+ * Class:     java_net_Inet4AddressImpl
+ * Method:    lookupAllHostAddr
+ * Signature: (Ljava/lang/String;)[Ljava/net/InetAddress;
+ */
+JNIEXPORT jobjectArray JNICALL Java_java_net_Inet4AddressImpl_lookupAllHostAddr
+  (JNIEnv *, jobject, jstring);
+
+/*
+ * Class:     java_net_Inet4AddressImpl
+ * Method:    getHostByAddr
+ * Signature: ([B)Ljava/lang/String;
+ */
+JNIEXPORT jstring JNICALL Java_java_net_Inet4AddressImpl_getHostByAddr
+  (JNIEnv *, jobject, jbyteArray);
+
+/*
+ * Class:     java_net_Inet4AddressImpl
+ * Method:    isReachable0
+ * Signature: ([BI[BI)Z
+ */
+JNIEXPORT jboolean JNICALL Java_java_net_Inet4AddressImpl_isReachable0
+  (JNIEnv *, jobject, jbyteArray, jint, jbyteArray, jint);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/ojluni/src/main/native/java_net_Inet6Address.h b/ojluni/src/main/native/java_net_Inet6Address.h
new file mode 100755
index 0000000..3936063
--- /dev/null
+++ b/ojluni/src/main/native/java_net_Inet6Address.h
@@ -0,0 +1,35 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class java_net_Inet6Address */
+
+#ifndef _Included_java_net_Inet6Address
+#define _Included_java_net_Inet6Address
+#ifdef __cplusplus
+extern "C" {
+#endif
+#undef java_net_Inet6Address_IPv4
+#define java_net_Inet6Address_IPv4 1L
+#undef java_net_Inet6Address_IPv6
+#define java_net_Inet6Address_IPv6 2L
+#undef java_net_Inet6Address_serialVersionUID
+#define java_net_Inet6Address_serialVersionUID 3286316764910316507LL
+#undef java_net_Inet6Address_maxCacheTime
+#define java_net_Inet6Address_maxCacheTime 5000LL
+#undef java_net_Inet6Address_INADDRSZ
+#define java_net_Inet6Address_INADDRSZ 16L
+#undef java_net_Inet6Address_serialVersionUID
+#define java_net_Inet6Address_serialVersionUID 6880410070516793377LL
+#undef java_net_Inet6Address_INT16SZ
+#define java_net_Inet6Address_INT16SZ 2L
+/*
+ * Class:     java_net_Inet6Address
+ * Method:    init
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_java_net_Inet6Address_init
+  (JNIEnv *, jclass);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/ojluni/src/main/native/java_net_Inet6AddressImpl.h b/ojluni/src/main/native/java_net_Inet6AddressImpl.h
new file mode 100755
index 0000000..ab5f1d0
--- /dev/null
+++ b/ojluni/src/main/native/java_net_Inet6AddressImpl.h
@@ -0,0 +1,45 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class java_net_Inet6AddressImpl */
+
+#ifndef _Included_java_net_Inet6AddressImpl
+#define _Included_java_net_Inet6AddressImpl
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class:     java_net_Inet6AddressImpl
+ * Method:    getLocalHostName
+ * Signature: ()Ljava/lang/String;
+ */
+JNIEXPORT jstring JNICALL Java_java_net_Inet6AddressImpl_getLocalHostName
+  (JNIEnv *, jobject);
+
+/*
+ * Class:     java_net_Inet6AddressImpl
+ * Method:    lookupAllHostAddr
+ * Signature: (Ljava/lang/String;)[Ljava/net/InetAddress;
+ */
+JNIEXPORT jobjectArray JNICALL Java_java_net_Inet6AddressImpl_lookupAllHostAddr
+  (JNIEnv *, jobject, jstring);
+
+/*
+ * Class:     java_net_Inet6AddressImpl
+ * Method:    getHostByAddr
+ * Signature: ([B)Ljava/lang/String;
+ */
+JNIEXPORT jstring JNICALL Java_java_net_Inet6AddressImpl_getHostByAddr
+  (JNIEnv *, jobject, jbyteArray);
+
+/*
+ * Class:     java_net_Inet6AddressImpl
+ * Method:    isReachable0
+ * Signature: ([BII[BII)Z
+ */
+JNIEXPORT jboolean JNICALL Java_java_net_Inet6AddressImpl_isReachable0
+  (JNIEnv *, jobject, jbyteArray, jint, jint, jbyteArray, jint, jint);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/ojluni/src/main/native/java_net_InetAddress.h b/ojluni/src/main/native/java_net_InetAddress.h
new file mode 100755
index 0000000..8125ff1
--- /dev/null
+++ b/ojluni/src/main/native/java_net_InetAddress.h
@@ -0,0 +1,29 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class java_net_InetAddress */
+
+#ifndef _Included_java_net_InetAddress
+#define _Included_java_net_InetAddress
+#ifdef __cplusplus
+extern "C" {
+#endif
+#undef java_net_InetAddress_IPv4
+#define java_net_InetAddress_IPv4 1L
+#undef java_net_InetAddress_IPv6
+#define java_net_InetAddress_IPv6 2L
+#undef java_net_InetAddress_serialVersionUID
+#define java_net_InetAddress_serialVersionUID 3286316764910316507LL
+#undef java_net_InetAddress_maxCacheTime
+#define java_net_InetAddress_maxCacheTime 5000LL
+/*
+ * Class:     java_net_InetAddress
+ * Method:    init
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_java_net_InetAddress_init
+  (JNIEnv *, jclass);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/ojluni/src/main/native/java_net_InetAddressImplFactory.h b/ojluni/src/main/native/java_net_InetAddressImplFactory.h
new file mode 100755
index 0000000..4c96086
--- /dev/null
+++ b/ojluni/src/main/native/java_net_InetAddressImplFactory.h
@@ -0,0 +1,21 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class java_net_InetAddressImplFactory */
+
+#ifndef _Included_java_net_InetAddressImplFactory
+#define _Included_java_net_InetAddressImplFactory
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class:     java_net_InetAddressImplFactory
+ * Method:    isIPv6Supported
+ * Signature: ()Z
+ */
+JNIEXPORT jboolean JNICALL Java_java_net_InetAddressImplFactory_isIPv6Supported
+  (JNIEnv *, jclass);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/ojluni/src/main/native/java_net_NetworkInterface.h b/ojluni/src/main/native/java_net_NetworkInterface.h
new file mode 100755
index 0000000..2a9c0b7
--- /dev/null
+++ b/ojluni/src/main/native/java_net_NetworkInterface.h
@@ -0,0 +1,101 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class java_net_NetworkInterface */
+
+#ifndef _Included_java_net_NetworkInterface
+#define _Included_java_net_NetworkInterface
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class:     java_net_NetworkInterface
+ * Method:    getAll
+ * Signature: ()[Ljava/net/NetworkInterface;
+ */
+JNIEXPORT jobjectArray JNICALL Java_java_net_NetworkInterface_getAll
+  (JNIEnv *, jclass);
+
+/*
+ * Class:     java_net_NetworkInterface
+ * Method:    getByName0
+ * Signature: (Ljava/lang/String;)Ljava/net/NetworkInterface;
+ */
+JNIEXPORT jobject JNICALL Java_java_net_NetworkInterface_getByName0
+  (JNIEnv *, jclass, jstring);
+
+/*
+ * Class:     java_net_NetworkInterface
+ * Method:    getByIndex0
+ * Signature: (I)Ljava/net/NetworkInterface;
+ */
+JNIEXPORT jobject JNICALL Java_java_net_NetworkInterface_getByIndex0
+  (JNIEnv *, jclass, jint);
+
+/*
+ * Class:     java_net_NetworkInterface
+ * Method:    getByInetAddress0
+ * Signature: (Ljava/net/InetAddress;)Ljava/net/NetworkInterface;
+ */
+JNIEXPORT jobject JNICALL Java_java_net_NetworkInterface_getByInetAddress0
+  (JNIEnv *, jclass, jobject);
+
+/*
+ * Class:     java_net_NetworkInterface
+ * Method:    isUp0
+ * Signature: (Ljava/lang/String;I)Z
+ */
+JNIEXPORT jboolean JNICALL Java_java_net_NetworkInterface_isUp0
+  (JNIEnv *, jclass, jstring, jint);
+
+/*
+ * Class:     java_net_NetworkInterface
+ * Method:    isLoopback0
+ * Signature: (Ljava/lang/String;I)Z
+ */
+JNIEXPORT jboolean JNICALL Java_java_net_NetworkInterface_isLoopback0
+  (JNIEnv *, jclass, jstring, jint);
+
+/*
+ * Class:     java_net_NetworkInterface
+ * Method:    supportsMulticast0
+ * Signature: (Ljava/lang/String;I)Z
+ */
+JNIEXPORT jboolean JNICALL Java_java_net_NetworkInterface_supportsMulticast0
+  (JNIEnv *, jclass, jstring, jint);
+
+/*
+ * Class:     java_net_NetworkInterface
+ * Method:    isP2P0
+ * Signature: (Ljava/lang/String;I)Z
+ */
+JNIEXPORT jboolean JNICALL Java_java_net_NetworkInterface_isP2P0
+  (JNIEnv *, jclass, jstring, jint);
+
+/*
+ * Class:     java_net_NetworkInterface
+ * Method:    getMacAddr0
+ * Signature: ([BLjava/lang/String;I)[B
+ */
+JNIEXPORT jbyteArray JNICALL Java_java_net_NetworkInterface_getMacAddr0
+  (JNIEnv *, jclass, jbyteArray, jstring, jint);
+
+/*
+ * Class:     java_net_NetworkInterface
+ * Method:    getMTU0
+ * Signature: (Ljava/lang/String;I)I
+ */
+JNIEXPORT jint JNICALL Java_java_net_NetworkInterface_getMTU0
+  (JNIEnv *, jclass, jstring, jint);
+
+/*
+ * Class:     java_net_NetworkInterface
+ * Method:    init
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_java_net_NetworkInterface_init
+  (JNIEnv *, jclass);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/ojluni/src/main/native/java_net_PlainDatagramSocketImpl.h b/ojluni/src/main/native/java_net_PlainDatagramSocketImpl.h
new file mode 100755
index 0000000..50719c4
--- /dev/null
+++ b/ojluni/src/main/native/java_net_PlainDatagramSocketImpl.h
@@ -0,0 +1,157 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class java_net_PlainDatagramSocketImpl */
+
+#ifndef _Included_java_net_PlainDatagramSocketImpl
+#define _Included_java_net_PlainDatagramSocketImpl
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class:     java_net_PlainDatagramSocketImpl
+ * Method:    bind0
+ * Signature: (ILjava/net/InetAddress;)V
+ */
+JNIEXPORT void JNICALL Java_java_net_PlainDatagramSocketImpl_bind0
+  (JNIEnv *, jobject, jint, jobject);
+
+/*
+ * Class:     java_net_PlainDatagramSocketImpl
+ * Method:    send
+ * Signature: (Ljava/net/DatagramPacket;)V
+ */
+JNIEXPORT void JNICALL Java_java_net_PlainDatagramSocketImpl_send
+  (JNIEnv *, jobject, jobject);
+
+/*
+ * Class:     java_net_PlainDatagramSocketImpl
+ * Method:    peek
+ * Signature: (Ljava/net/InetAddress;)I
+ */
+JNIEXPORT jint JNICALL Java_java_net_PlainDatagramSocketImpl_peek
+  (JNIEnv *, jobject, jobject);
+
+/*
+ * Class:     java_net_PlainDatagramSocketImpl
+ * Method:    peekData
+ * Signature: (Ljava/net/DatagramPacket;)I
+ */
+JNIEXPORT jint JNICALL Java_java_net_PlainDatagramSocketImpl_peekData
+  (JNIEnv *, jobject, jobject);
+
+/*
+ * Class:     java_net_PlainDatagramSocketImpl
+ * Method:    receive0
+ * Signature: (Ljava/net/DatagramPacket;)V
+ */
+JNIEXPORT void JNICALL Java_java_net_PlainDatagramSocketImpl_receive0
+  (JNIEnv *, jobject, jobject);
+
+/*
+ * Class:     java_net_PlainDatagramSocketImpl
+ * Method:    setTimeToLive
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL Java_java_net_PlainDatagramSocketImpl_setTimeToLive
+  (JNIEnv *, jobject, jint);
+
+/*
+ * Class:     java_net_PlainDatagramSocketImpl
+ * Method:    getTimeToLive
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL Java_java_net_PlainDatagramSocketImpl_getTimeToLive
+  (JNIEnv *, jobject);
+
+/*
+ * Class:     java_net_PlainDatagramSocketImpl
+ * Method:    setTTL
+ * Signature: (B)V
+ */
+JNIEXPORT void JNICALL Java_java_net_PlainDatagramSocketImpl_setTTL
+  (JNIEnv *, jobject, jbyte);
+
+/*
+ * Class:     java_net_PlainDatagramSocketImpl
+ * Method:    getTTL
+ * Signature: ()B
+ */
+JNIEXPORT jbyte JNICALL Java_java_net_PlainDatagramSocketImpl_getTTL
+  (JNIEnv *, jobject);
+
+/*
+ * Class:     java_net_PlainDatagramSocketImpl
+ * Method:    join
+ * Signature: (Ljava/net/InetAddress;Ljava/net/NetworkInterface;)V
+ */
+JNIEXPORT void JNICALL Java_java_net_PlainDatagramSocketImpl_join
+  (JNIEnv *, jobject, jobject, jobject);
+
+/*
+ * Class:     java_net_PlainDatagramSocketImpl
+ * Method:    leave
+ * Signature: (Ljava/net/InetAddress;Ljava/net/NetworkInterface;)V
+ */
+JNIEXPORT void JNICALL Java_java_net_PlainDatagramSocketImpl_leave
+  (JNIEnv *, jobject, jobject, jobject);
+
+/*
+ * Class:     java_net_PlainDatagramSocketImpl
+ * Method:    datagramSocketCreate
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_java_net_PlainDatagramSocketImpl_datagramSocketCreate
+  (JNIEnv *, jobject);
+
+/*
+ * Class:     java_net_PlainDatagramSocketImpl
+ * Method:    datagramSocketClose
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_java_net_PlainDatagramSocketImpl_datagramSocketClose
+  (JNIEnv *, jobject);
+
+/*
+ * Class:     java_net_PlainDatagramSocketImpl
+ * Method:    socketSetOption
+ * Signature: (ILjava/lang/Object;)V
+ */
+JNIEXPORT void JNICALL Java_java_net_PlainDatagramSocketImpl_socketSetOption
+  (JNIEnv *, jobject, jint, jobject);
+
+/*
+ * Class:     java_net_PlainDatagramSocketImpl
+ * Method:    socketGetOption
+ * Signature: (I)Ljava/lang/Object;
+ */
+JNIEXPORT jobject JNICALL Java_java_net_PlainDatagramSocketImpl_socketGetOption
+  (JNIEnv *, jobject, jint);
+
+/*
+ * Class:     java_net_PlainDatagramSocketImpl
+ * Method:    connect0
+ * Signature: (Ljava/net/InetAddress;I)V
+ */
+JNIEXPORT void JNICALL Java_java_net_PlainDatagramSocketImpl_connect0
+  (JNIEnv *, jobject, jobject, jint);
+
+/*
+ * Class:     java_net_PlainDatagramSocketImpl
+ * Method:    disconnect0
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL Java_java_net_PlainDatagramSocketImpl_disconnect0
+  (JNIEnv *, jobject, jint);
+
+/*
+ * Class:     java_net_PlainDatagramSocketImpl
+ * Method:    init
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_java_net_PlainDatagramSocketImpl_init
+  (JNIEnv *, jclass);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/ojluni/src/main/native/java_net_PlainSocketImpl.h b/ojluni/src/main/native/java_net_PlainSocketImpl.h
new file mode 100755
index 0000000..9afa226
--- /dev/null
+++ b/ojluni/src/main/native/java_net_PlainSocketImpl.h
@@ -0,0 +1,113 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class java_net_PlainSocketImpl */
+
+#ifndef _Included_java_net_PlainSocketImpl
+#define _Included_java_net_PlainSocketImpl
+#ifdef __cplusplus
+extern "C" {
+#endif
+#undef java_net_PlainSocketImpl_SHUT_RD
+#define java_net_PlainSocketImpl_SHUT_RD 0L
+#undef java_net_PlainSocketImpl_SHUT_WR
+#define java_net_PlainSocketImpl_SHUT_WR 1L
+/*
+ * Class:     java_net_PlainSocketImpl
+ * Method:    socketCreate
+ * Signature: (Z)V
+ */
+JNIEXPORT void JNICALL Java_java_net_PlainSocketImpl_socketCreate
+  (JNIEnv *, jobject, jboolean);
+
+/*
+ * Class:     java_net_PlainSocketImpl
+ * Method:    socketConnect
+ * Signature: (Ljava/net/InetAddress;II)V
+ */
+JNIEXPORT void JNICALL Java_java_net_PlainSocketImpl_socketConnect
+  (JNIEnv *, jobject, jobject, jint, jint);
+
+/*
+ * Class:     java_net_PlainSocketImpl
+ * Method:    socketBind
+ * Signature: (Ljava/net/InetAddress;I)V
+ */
+JNIEXPORT void JNICALL Java_java_net_PlainSocketImpl_socketBind
+  (JNIEnv *, jobject, jobject, jint);
+
+/*
+ * Class:     java_net_PlainSocketImpl
+ * Method:    socketListen
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL Java_java_net_PlainSocketImpl_socketListen
+  (JNIEnv *, jobject, jint);
+
+/*
+ * Class:     java_net_PlainSocketImpl
+ * Method:    socketAccept
+ * Signature: (Ljava/net/SocketImpl;)V
+ */
+JNIEXPORT void JNICALL Java_java_net_PlainSocketImpl_socketAccept
+  (JNIEnv *, jobject, jobject);
+
+/*
+ * Class:     java_net_PlainSocketImpl
+ * Method:    socketAvailable
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL Java_java_net_PlainSocketImpl_socketAvailable
+  (JNIEnv *, jobject);
+
+/*
+ * Class:     java_net_PlainSocketImpl
+ * Method:    socketClose0
+ * Signature: (Z)V
+ */
+JNIEXPORT void JNICALL Java_java_net_PlainSocketImpl_socketClose0
+  (JNIEnv *, jobject, jboolean);
+
+/*
+ * Class:     java_net_PlainSocketImpl
+ * Method:    socketShutdown
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL Java_java_net_PlainSocketImpl_socketShutdown
+  (JNIEnv *, jobject, jint);
+
+/*
+ * Class:     java_net_PlainSocketImpl
+ * Method:    initProto
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_java_net_PlainSocketImpl_initProto
+  (JNIEnv *, jclass);
+
+/*
+ * Class:     java_net_PlainSocketImpl
+ * Method:    socketSetOption
+ * Signature: (IZLjava/lang/Object;)V
+ */
+JNIEXPORT void JNICALL Java_java_net_PlainSocketImpl_socketSetOption
+  (JNIEnv *, jobject, jint, jboolean, jobject);
+
+/*
+ * Class:     java_net_PlainSocketImpl
+ * Method:    socketGetOption
+ * Signature: (ILjava/lang/Object;)I
+ */
+JNIEXPORT jint JNICALL Java_java_net_PlainSocketImpl_socketGetOption
+  (JNIEnv *, jobject, jint, jobject);
+
+/*
+ * Class:     java_net_PlainSocketImpl
+ * Method:    socketSendUrgentData
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL Java_java_net_PlainSocketImpl_socketSendUrgentData
+  (JNIEnv *, jobject, jint);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/ojluni/src/main/native/java_net_SocketInputStream.h b/ojluni/src/main/native/java_net_SocketInputStream.h
new file mode 100755
index 0000000..47ce360
--- /dev/null
+++ b/ojluni/src/main/native/java_net_SocketInputStream.h
@@ -0,0 +1,31 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class java_net_SocketInputStream */
+
+#ifndef _Included_java_net_SocketInputStream
+#define _Included_java_net_SocketInputStream
+#ifdef __cplusplus
+extern "C" {
+#endif
+#undef java_net_SocketInputStream_MAX_SKIP_BUFFER_SIZE
+#define java_net_SocketInputStream_MAX_SKIP_BUFFER_SIZE 2048L
+/*
+ * Class:     java_net_SocketInputStream
+ * Method:    socketRead0
+ * Signature: (Ljava/io/FileDescriptor;[BIII)I
+ */
+JNIEXPORT jint JNICALL Java_java_net_SocketInputStream_socketRead0
+  (JNIEnv *, jobject, jobject, jbyteArray, jint, jint, jint);
+
+/*
+ * Class:     java_net_SocketInputStream
+ * Method:    init
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_java_net_SocketInputStream_init
+  (JNIEnv *, jclass);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/ojluni/src/main/native/java_net_SocketOptions.h b/ojluni/src/main/native/java_net_SocketOptions.h
new file mode 100755
index 0000000..f744fc3
--- /dev/null
+++ b/ojluni/src/main/native/java_net_SocketOptions.h
@@ -0,0 +1,41 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class java_net_SocketOptions */
+
+#ifndef _Included_java_net_SocketOptions
+#define _Included_java_net_SocketOptions
+#ifdef __cplusplus
+extern "C" {
+#endif
+#undef java_net_SocketOptions_TCP_NODELAY
+#define java_net_SocketOptions_TCP_NODELAY 1L
+#undef java_net_SocketOptions_SO_BINDADDR
+#define java_net_SocketOptions_SO_BINDADDR 15L
+#undef java_net_SocketOptions_SO_REUSEADDR
+#define java_net_SocketOptions_SO_REUSEADDR 4L
+#undef java_net_SocketOptions_SO_BROADCAST
+#define java_net_SocketOptions_SO_BROADCAST 32L
+#undef java_net_SocketOptions_IP_MULTICAST_IF
+#define java_net_SocketOptions_IP_MULTICAST_IF 16L
+#undef java_net_SocketOptions_IP_MULTICAST_IF2
+#define java_net_SocketOptions_IP_MULTICAST_IF2 31L
+#undef java_net_SocketOptions_IP_MULTICAST_LOOP
+#define java_net_SocketOptions_IP_MULTICAST_LOOP 18L
+#undef java_net_SocketOptions_IP_TOS
+#define java_net_SocketOptions_IP_TOS 3L
+#undef java_net_SocketOptions_SO_LINGER
+#define java_net_SocketOptions_SO_LINGER 128L
+#undef java_net_SocketOptions_SO_TIMEOUT
+#define java_net_SocketOptions_SO_TIMEOUT 4102L
+#undef java_net_SocketOptions_SO_SNDBUF
+#define java_net_SocketOptions_SO_SNDBUF 4097L
+#undef java_net_SocketOptions_SO_RCVBUF
+#define java_net_SocketOptions_SO_RCVBUF 4098L
+#undef java_net_SocketOptions_SO_KEEPALIVE
+#define java_net_SocketOptions_SO_KEEPALIVE 8L
+#undef java_net_SocketOptions_SO_OOBINLINE
+#define java_net_SocketOptions_SO_OOBINLINE 4099L
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/ojluni/src/main/native/java_net_SocketOutputStream.h b/ojluni/src/main/native/java_net_SocketOutputStream.h
new file mode 100755
index 0000000..2fa8d94
--- /dev/null
+++ b/ojluni/src/main/native/java_net_SocketOutputStream.h
@@ -0,0 +1,29 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class java_net_SocketOutputStream */
+
+#ifndef _Included_java_net_SocketOutputStream
+#define _Included_java_net_SocketOutputStream
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class:     java_net_SocketOutputStream
+ * Method:    socketWrite0
+ * Signature: (Ljava/io/FileDescriptor;[BII)V
+ */
+JNIEXPORT void JNICALL Java_java_net_SocketOutputStream_socketWrite0
+  (JNIEnv *, jobject, jobject, jbyteArray, jint, jint);
+
+/*
+ * Class:     java_net_SocketOutputStream
+ * Method:    init
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_java_net_SocketOutputStream_init
+  (JNIEnv *, jclass);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/ojluni/src/main/native/java_props.h b/ojluni/src/main/native/java_props.h
new file mode 100755
index 0000000..de1947168
--- /dev/null
+++ b/ojluni/src/main/native/java_props.h
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#ifndef _JAVA_PROPS_H
+#define _JAVA_PROPS_H
+
+#include <jni_util.h>
+
+/* The preferred native type for storing text on the current OS */
+#ifdef WIN32
+#include <tchar.h>
+typedef WCHAR nchar;
+#else
+typedef char nchar;
+#endif
+
+typedef struct {
+    char *os_name;
+    char *os_version;
+    char *os_arch;
+
+    nchar *tmp_dir;
+    nchar *font_dir;
+    nchar *user_dir;
+
+    char *file_separator;
+    char *path_separator;
+    char *line_separator;
+
+    nchar *user_name;
+    nchar *user_home;
+
+    char *language;
+    char *format_language;
+    char *display_language;
+    char *script;
+    char *format_script;
+    char *display_script;
+    char *country;
+    char *format_country;
+    char *display_country;
+    char *variant;
+    char *format_variant;
+    char *display_variant;
+    char *encoding;
+    char *sun_jnu_encoding;
+    char *timezone;
+
+    char *printerJob;
+    char *graphics_env;
+    char *awt_toolkit;
+
+    char *unicode_encoding;     /* The default endianness of unicode
+                                    i.e. UnicodeBig or UnicodeLittle   */
+
+    const char *cpu_isalist;    /* list of supported instruction sets */
+
+    char *cpu_endian;           /* endianness of platform */
+
+    char *data_model;           /* 32 or 64 bit data model */
+
+    char *patch_level;          /* patches/service packs installed */
+
+    char *desktop;              /* Desktop name. */
+
+#ifdef MACOSX
+    // These are for proxy-related information.
+    // Note that if these platform-specific extensions get out of hand we should make a new
+    // structure for them and #include it here.
+    int httpProxyEnabled;
+    char *httpHost;
+    char *httpPort;
+
+    int httpsProxyEnabled;
+    char *httpsHost;
+    char *httpsPort;
+
+    int ftpProxyEnabled;
+    char *ftpHost;
+    char *ftpPort;
+
+    int socksProxyEnabled;
+    char *socksHost;
+    char *socksPort;
+
+    int gopherProxyEnabled;
+    char *gopherHost;
+    char *gopherPort;
+
+    char *exceptionList;
+#endif
+
+} java_props_t;
+
+java_props_t *GetJavaProperties(JNIEnv *env);
+jstring GetStringPlatform(JNIEnv *env, nchar* str);
+
+#endif /* _JAVA_PROPS_H */
diff --git a/ojluni/src/main/native/java_props_md.c b/ojluni/src/main/native/java_props_md.c
new file mode 100755
index 0000000..3a2d6e0
--- /dev/null
+++ b/ojluni/src/main/native/java_props_md.c
@@ -0,0 +1,582 @@
+/*
+ * Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#if defined(__linux__) || defined(_ALLBSD_SOURCE)
+#include <stdio.h>
+#include <ctype.h>
+#endif
+#include <pwd.h>
+#include <locale.h>
+#ifndef ARCHPROPNAME
+#error "The macro ARCHPROPNAME has not been defined"
+#endif
+#include <sys/utsname.h>        /* For os_name and os_version */
+#include <langinfo.h>           /* For nl_langinfo */
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <sys/param.h>
+#include <time.h>
+#include <errno.h>
+
+#ifdef MACOSX
+#include "java_props_macosx.h"
+#endif
+
+#if defined(_ALLBSD_SOURCE)
+#if !defined(P_tmpdir)
+#include <paths.h>
+#define P_tmpdir _PATH_VARTMP
+#endif
+#endif
+
+#include "locale_str.h"
+#include "java_props.h"
+
+#if !defined(_ALLBSD_SOURCE)
+#ifdef __linux__
+  #ifndef CODESET
+  #define CODESET _NL_CTYPE_CODESET_NAME
+  #endif
+#else
+#ifdef ALT_CODESET_KEY
+#define CODESET ALT_CODESET_KEY
+#endif
+#endif
+#endif /* !_ALLBSD_SOURCE */
+
+#ifdef JAVASE_EMBEDDED
+#include <dlfcn.h>
+#include <sys/stat.h>
+#endif
+
+/* Take an array of string pairs (map of key->value) and a string (key).
+ * Examine each pair in the map to see if the first string (key) matches the
+ * string.  If so, store the second string of the pair (value) in the value and
+ * return 1.  Otherwise do nothing and return 0.  The end of the map is
+ * indicated by an empty string at the start of a pair (key of "").
+ */
+static int
+mapLookup(char* map[], const char* key, char** value) {
+    int i;
+    for (i = 0; strcmp(map[i], ""); i += 2){
+        if (!strcmp(key, map[i])){
+            *value = map[i + 1];
+            return 1;
+        }
+    }
+    return 0;
+}
+
+/* This function sets an environment variable using envstring.
+ * The format of envstring is "name=value".
+ * If the name has already existed, it will append value to the name.
+ */
+static void
+setPathEnvironment(char *envstring)
+{
+    char name[20], *value, *current;
+
+    value = strchr(envstring, '='); /* locate name and value separator */
+
+    if (! value)
+        return; /* not a valid environment setting */
+
+    /* copy first part as environment name */
+    strncpy(name, envstring, value - envstring);
+    name[value-envstring] = '\0';
+
+    value++; /* set value point to value of the envstring */
+
+    current = getenv(name);
+    if (current) {
+        if (! strstr(current, value)) {
+            /* value is not found in current environment, append it */
+            char *temp = malloc(strlen(envstring) + strlen(current) + 2);
+        strcpy(temp, name);
+        strcat(temp, "=");
+        strcat(temp, current);
+        strcat(temp, ":");
+        strcat(temp, value);
+        putenv(temp);
+        }
+        /* else the value has already been set, do nothing */
+    }
+    else {
+        /* environment variable is not found */
+        putenv(envstring);
+    }
+}
+
+#ifndef P_tmpdir
+#define P_tmpdir "/var/tmp"
+#endif
+
+static int ParseLocale(int cat, char ** std_language, char ** std_script,
+                       char ** std_country, char ** std_variant, char ** std_encoding) {
+    char temp[64];
+    char *language = NULL, *country = NULL, *variant = NULL,
+         *encoding = NULL;
+    char *p, encoding_variant[64];
+    char *lc;
+
+    /* Query the locale set for the category */
+
+#ifdef MACOSX
+    lc = setupMacOSXLocale(cat); // malloc'd memory, need to free
+#else
+    lc = setlocale(cat, NULL);
+#endif
+
+#ifndef __linux__
+    if (lc == NULL) {
+        return 0;
+    }
+
+    if (cat == LC_CTYPE) {
+        /*
+         * Workaround for Solaris bug 4201684: Xlib doesn't like @euro
+         * locales. Since we don't depend on the libc @euro behavior,
+         * we just remove the qualifier.
+         * On Linux, the bug doesn't occur; on the other hand, @euro
+         * is needed there because it's a shortcut that also determines
+         * the encoding - without it, we wouldn't get ISO-8859-15.
+         * Therefore, this code section is Solaris-specific.
+         */
+        lc = strdup(lc);    /* keep a copy, setlocale trashes original. */
+        strcpy(temp, lc);
+        p = strstr(temp, "@euro");
+        if (p != NULL) {
+            *p = '\0';
+            setlocale(LC_ALL, temp);
+        }
+    }
+#else
+    if (lc == NULL || !strcmp(lc, "C") || !strcmp(lc, "POSIX")) {
+        lc = "en_US";
+    }
+#endif
+
+    /*
+     * locale string format in Solaris is
+     * <language name>_<country name>.<encoding name>@<variant name>
+     * <country name>, <encoding name>, and <variant name> are optional.
+     */
+
+    strcpy(temp, lc);
+#ifdef MACOSX
+    free(lc); // malloced memory
+#endif
+    /* Parse the language, country, encoding, and variant from the
+     * locale.  Any of the elements may be missing, but they must occur
+     * in the order language_country.encoding@variant, and must be
+     * preceded by their delimiter (except for language).
+     *
+     * If the locale name (without .encoding@variant, if any) matches
+     * any of the names in the locale_aliases list, map it to the
+     * corresponding full locale name.  Most of the entries in the
+     * locale_aliases list are locales that include a language name but
+     * no country name, and this facility is used to map each language
+     * to a default country if that's possible.  It's also used to map
+     * the Solaris locale aliases to their proper Java locale IDs.
+     */
+    if ((p = strchr(temp, '.')) != NULL) {
+        strcpy(encoding_variant, p); /* Copy the leading '.' */
+        *p = '\0';
+    } else if ((p = strchr(temp, '@')) != NULL) {
+        strcpy(encoding_variant, p); /* Copy the leading '@' */
+        *p = '\0';
+    } else {
+        *encoding_variant = '\0';
+    }
+
+    if (mapLookup(locale_aliases, temp, &p)) {
+        strcpy(temp, p);
+        // check the "encoding_variant" again, if any.
+        if ((p = strchr(temp, '.')) != NULL) {
+            strcpy(encoding_variant, p); /* Copy the leading '.' */
+            *p = '\0';
+        } else if ((p = strchr(temp, '@')) != NULL) {
+            strcpy(encoding_variant, p); /* Copy the leading '@' */
+            *p = '\0';
+        }
+    }
+
+    language = temp;
+    if ((country = strchr(temp, '_')) != NULL) {
+        *country++ = '\0';
+    }
+
+    p = encoding_variant;
+    if ((encoding = strchr(p, '.')) != NULL) {
+        p[encoding++ - p] = '\0';
+        p = encoding;
+    }
+    if ((variant = strchr(p, '@')) != NULL) {
+        p[variant++ - p] = '\0';
+    }
+
+    /* Normalize the language name */
+    if (std_language != NULL) {
+        *std_language = "en";
+        if (language != NULL && mapLookup(language_names, language, std_language) == 0) {
+            *std_language = malloc(strlen(language)+1);
+            strcpy(*std_language, language);
+        }
+    }
+
+    /* Normalize the country name */
+    if (std_country != NULL && country != NULL) {
+        if (mapLookup(country_names, country, std_country) == 0) {
+            *std_country = malloc(strlen(country)+1);
+            strcpy(*std_country, country);
+        }
+    }
+
+    /* Normalize the script and variant name.  Note that we only use
+     * variants listed in the mapping array; others are ignored.
+     */
+    if (variant != NULL) {
+        if (std_script != NULL) {
+            mapLookup(script_names, variant, std_script);
+        }
+
+        if (std_variant != NULL) {
+            mapLookup(variant_names, variant, std_variant);
+        }
+    }
+
+    /* Normalize the encoding name.  Note that we IGNORE the string
+     * 'encoding' extracted from the locale name above.  Instead, we use the
+     * more reliable method of calling nl_langinfo(CODESET).  This function
+     * returns an empty string if no encoding is set for the given locale
+     * (e.g., the C or POSIX locales); we use the default ISO 8859-1
+     * converter for such locales.
+     */
+    if (std_encoding != NULL) {
+        /* OK, not so reliable - nl_langinfo() gives wrong answers on
+         * Euro locales, in particular. */
+        if (strcmp(p, "ISO8859-15") == 0)
+            p = "ISO8859-15";
+        else
+            p = nl_langinfo(CODESET);
+
+        /* Convert the bare "646" used on Solaris to a proper IANA name */
+        if (strcmp(p, "646") == 0)
+            p = "ISO646-US";
+
+        /* return same result nl_langinfo would return for en_UK,
+         * in order to use optimizations. */
+        *std_encoding = (*p != '\0') ? p : "ISO8859-1";
+
+#ifdef __linux__
+        /*
+         * Remap the encoding string to a different value for japanese
+         * locales on linux so that customized converters are used instead
+         * of the default converter for "EUC-JP". The customized converters
+         * omit support for the JIS0212 encoding which is not supported by
+         * the variant of "EUC-JP" encoding used on linux
+         */
+        if (strcmp(p, "EUC-JP") == 0) {
+            *std_encoding = "EUC-JP-LINUX";
+        }
+#else
+        if (strcmp(p,"eucJP") == 0) {
+            /* For Solaris use customized vendor defined character
+             * customized EUC-JP converter
+             */
+            *std_encoding = "eucJP-open";
+        } else if (strcmp(p, "Big5") == 0 || strcmp(p, "BIG5") == 0) {
+            /*
+             * Remap the encoding string to Big5_Solaris which augments
+             * the default converter for Solaris Big5 locales to include
+             * seven additional ideographic characters beyond those included
+             * in the Java "Big5" converter.
+             */
+            *std_encoding = "Big5_Solaris";
+        } else if (strcmp(p, "Big5-HKSCS") == 0) {
+            /*
+             * Solaris uses HKSCS2001
+             */
+            *std_encoding = "Big5-HKSCS-2001";
+        }
+#endif
+    }
+
+    return 1;
+}
+
+#ifdef JAVASE_EMBEDDED
+/* Determine the default embedded toolkit based on whether lib/xawt/
+ * exists in the JRE. This can still be overridden by -Dawt.toolkit=XXX
+ */
+static char* getEmbeddedToolkit() {
+    Dl_info dlinfo;
+    char buf[MAXPATHLEN];
+    int32_t len;
+    char *p;
+    struct stat statbuf;
+
+    /* Get address of this library and the directory containing it. */
+    dladdr((void *)getEmbeddedToolkit, &dlinfo);
+    realpath((char *)dlinfo.dli_fname, buf);
+    len = strlen(buf);
+    p = strrchr(buf, '/');
+    /* Default AWT Toolkit on Linux and Solaris is XAWT. */
+    strncpy(p, "/xawt/", MAXPATHLEN-len-1);
+    /* Check if it exists */
+    if (stat(buf, &statbuf) == -1 && errno == ENOENT) {
+        /* No - this is a reduced-headless-jre so use special HToolkit */
+        return "sun.awt.HToolkit";
+    }
+    else {
+        /* Yes - this is a headful JRE so fallback to SE defaults */
+        return NULL;
+    }
+}
+#endif
+
+/* This function gets called very early, before VM_CALLS are setup.
+ * Do not use any of the VM_CALLS entries!!!
+ */
+java_props_t *
+GetJavaProperties(JNIEnv *env)
+{
+    static java_props_t sprops;
+    char *v; /* tmp var */
+
+    if (sprops.user_dir) {
+        return &sprops;
+    }
+
+    /* tmp dir */
+    sprops.tmp_dir = P_tmpdir;
+#ifdef MACOSX
+    /* darwin has a per-user temp dir */
+    static char tmp_path[PATH_MAX];
+    int pathSize = confstr(_CS_DARWIN_USER_TEMP_DIR, tmp_path, PATH_MAX);
+    if (pathSize > 0 && pathSize <= PATH_MAX) {
+        sprops.tmp_dir = tmp_path;
+    }
+#endif /* MACOSX */
+
+    /* Printing properties */
+#ifdef MACOSX
+    sprops.printerJob = "sun.lwawt.macosx.CPrinterJob";
+#else
+    sprops.printerJob = "sun.print.PSPrinterJob";
+#endif
+
+    /* patches/service packs installed */
+    sprops.patch_level = "unknown";
+
+    /* Java 2D properties */
+#ifdef MACOSX
+    PreferredToolkit prefToolkit = getPreferredToolkit();
+    switch (prefToolkit) {
+        case CToolkit:
+        case HToolkit:
+            sprops.graphics_env = "sun.awt.CGraphicsEnvironment";
+            break;
+        case XToolkit:
+#endif
+    sprops.graphics_env = "sun.awt.X11GraphicsEnvironment";
+#ifdef MACOSX
+            break;
+    }
+#endif
+    /* AWT properties */
+#ifdef JAVASE_EMBEDDED
+    sprops.awt_toolkit = getEmbeddedToolkit();
+    if (sprops.awt_toolkit == NULL) // default as below
+#endif
+#ifdef MACOSX
+        switch (prefToolkit) {
+            case CToolkit:
+                sprops.awt_toolkit = "sun.lwawt.macosx.LWCToolkit";
+                break;
+            case XToolkit:
+#endif
+    sprops.awt_toolkit = "sun.awt.X11.XToolkit";
+#ifdef MACOSX
+                break;
+            default:
+                sprops.awt_toolkit = "sun.awt.HToolkit";
+                break;
+        }
+#endif
+
+    /* This is used only for debugging of font problems. */
+    v = getenv("JAVA2D_FONTPATH");
+    sprops.font_dir = v ? v : NULL;
+
+#ifdef SI_ISALIST
+    /* supported instruction sets */
+    {
+        char list[258];
+        sysinfo(SI_ISALIST, list, sizeof(list));
+        sprops.cpu_isalist = strdup(list);
+    }
+#else
+    sprops.cpu_isalist = NULL;
+#endif
+
+    /* endianness of platform */
+    {
+        unsigned int endianTest = 0xff000000;
+        if (((char*)(&endianTest))[0] != 0)
+            sprops.cpu_endian = "big";
+        else
+            sprops.cpu_endian = "little";
+    }
+
+    /* os properties */
+    {
+#ifdef MACOSX
+        setOSNameAndVersion(&sprops);
+#else
+        struct utsname name;
+        uname(&name);
+        sprops.os_name = strdup(name.sysname);
+        sprops.os_version = strdup(name.release);
+#endif
+
+        sprops.os_arch = ARCHPROPNAME;
+
+        if (getenv("GNOME_DESKTOP_SESSION_ID") != NULL) {
+            sprops.desktop = "gnome";
+        }
+        else {
+            sprops.desktop = NULL;
+        }
+    }
+
+    /* Determine the language, country, variant, and encoding from the host,
+     * and store these in the user.language, user.country, user.variant and
+     * file.encoding system properties. */
+    setlocale(LC_ALL, "");
+    if (ParseLocale(LC_CTYPE,
+                    &(sprops.format_language),
+                    &(sprops.format_script),
+                    &(sprops.format_country),
+                    &(sprops.format_variant),
+                    &(sprops.encoding))) {
+        ParseLocale(LC_MESSAGES,
+                    &(sprops.language),
+                    &(sprops.script),
+                    &(sprops.country),
+                    &(sprops.variant),
+                    NULL);
+    } else {
+        sprops.language = "en";
+        sprops.encoding = "ISO8859-1";
+    }
+    sprops.display_language = sprops.language;
+    sprops.display_script = sprops.script;
+    sprops.display_country = sprops.country;
+    sprops.display_variant = sprops.variant;
+
+#ifdef MACOSX
+    sprops.sun_jnu_encoding = "UTF-8";
+#else
+    sprops.sun_jnu_encoding = sprops.encoding;
+#endif
+
+#ifdef _ALLBSD_SOURCE
+#if BYTE_ORDER == _LITTLE_ENDIAN
+     sprops.unicode_encoding = "UnicodeLittle";
+ #else
+     sprops.unicode_encoding = "UnicodeBig";
+ #endif
+#else /* !_ALLBSD_SOURCE */
+#ifdef __linux__
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+    sprops.unicode_encoding = "UnicodeLittle";
+#else
+    sprops.unicode_encoding = "UnicodeBig";
+#endif
+#else
+    sprops.unicode_encoding = "UnicodeBig";
+#endif
+#endif /* _ALLBSD_SOURCE */
+
+    /* user properties */
+    {
+        struct passwd *pwent = getpwuid(getuid());
+        sprops.user_name = pwent ? strdup(pwent->pw_name) : "?";
+        sprops.user_home = pwent ? strdup(pwent->pw_dir) : "?";
+    }
+
+    /* User TIMEZONE */
+    {
+        /*
+         * We defer setting up timezone until it's actually necessary.
+         * Refer to TimeZone.getDefault(). However, the system
+         * property is necessary to be able to be set by the command
+         * line interface -D. Here temporarily set a null string to
+         * timezone.
+         */
+        tzset();        /* for compatibility */
+        sprops.timezone = "";
+    }
+
+    /* Current directory */
+    {
+        char buf[MAXPATHLEN];
+        errno = 0;
+        if (getcwd(buf, sizeof(buf))  == NULL)
+            JNU_ThrowByName(env, "java/lang/Error",
+             "Properties init: Could not determine current working directory.");
+        else
+            sprops.user_dir = strdup(buf);
+    }
+
+    sprops.file_separator = "/";
+    sprops.path_separator = ":";
+    sprops.line_separator = "\n";
+
+#if !defined(_ALLBSD_SOURCE)
+    /* Append CDE message and resource search path to NLSPATH and
+     * XFILESEARCHPATH, in order to pick localized message for
+     * FileSelectionDialog window (Bug 4173641).
+     */
+    setPathEnvironment("NLSPATH=/usr/dt/lib/nls/msg/%L/%N.cat");
+    setPathEnvironment("XFILESEARCHPATH=/usr/dt/app-defaults/%L/Dt");
+#endif
+
+
+#ifdef MACOSX
+    setProxyProperties(&sprops);
+#endif
+
+    return &sprops;
+}
+
+jstring
+GetStringPlatform(JNIEnv *env, nchar* cstr)
+{
+    return JNU_NewStringPlatform(env, cstr);
+}
diff --git a/ojluni/src/main/native/java_util_zip_Adler32.c b/ojluni/src/main/native/java_util_zip_Adler32.c
new file mode 100755
index 0000000..87f265d
--- /dev/null
+++ b/ojluni/src/main/native/java_util_zip_Adler32.c
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 1997, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * Native method support for java.util.zip.Adler32
+ */
+
+#include "jni.h"
+#include "jni_util.h"
+#include <zlib.h>
+
+#include "java_util_zip_Adler32.h"
+
+JNIEXPORT jint JNICALL
+Java_java_util_zip_Adler32_update(JNIEnv *env, jclass cls, jint adler, jint b)
+{
+    Bytef buf[1];
+
+    buf[0] = (Bytef)b;
+    return adler32(adler, buf, 1);
+}
+
+JNIEXPORT jint JNICALL
+Java_java_util_zip_Adler32_updateBytes(JNIEnv *env, jclass cls, jint adler,
+                                       jarray b, jint off, jint len)
+{
+    Bytef *buf = (*env)->GetPrimitiveArrayCritical(env, b, 0);
+    if (buf) {
+        adler = adler32(adler, buf + off, len);
+        (*env)->ReleasePrimitiveArrayCritical(env, b, buf, 0);
+    }
+    return adler;
+}
+
+JNIEXPORT jint JNICALL
+Java_java_util_zip_Adler32_updateByteBuffer(JNIEnv *env, jclass cls, jint adler,
+                                            jlong address, jint off, jint len)
+{
+    Bytef *buf = (Bytef *)jlong_to_ptr(address);
+    if (buf) {
+        adler = adler32(adler, buf + off, len);
+    }
+    return adler;
+}
diff --git a/ojluni/src/main/native/java_util_zip_CRC32.c b/ojluni/src/main/native/java_util_zip_CRC32.c
new file mode 100755
index 0000000..689b34b
--- /dev/null
+++ b/ojluni/src/main/native/java_util_zip_CRC32.c
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 1997, 1999, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * Native method support for java.util.zip.CRC32
+ */
+
+#include "jni.h"
+#include "jni_util.h"
+#include <zlib.h>
+
+#include "java_util_zip_CRC32.h"
+
+JNIEXPORT jint JNICALL
+Java_java_util_zip_CRC32_update(JNIEnv *env, jclass cls, jint crc, jint b)
+{
+    Bytef buf[1];
+
+    buf[0] = (Bytef)b;
+    return crc32(crc, buf, 1);
+}
+
+JNIEXPORT jint JNICALL
+Java_java_util_zip_CRC32_updateBytes(JNIEnv *env, jclass cls, jint crc,
+                                     jarray b, jint off, jint len)
+{
+    Bytef *buf = (*env)->GetPrimitiveArrayCritical(env, b, 0);
+    if (buf) {
+        crc = crc32(crc, buf + off, len);
+        (*env)->ReleasePrimitiveArrayCritical(env, b, buf, 0);
+    }
+    return crc;
+}
+
+JNIEXPORT jint ZIP_CRC32(jint crc, const jbyte *buf, jint len)
+{
+    return crc32(crc, (Bytef*)buf, len);
+}
diff --git a/ojluni/src/main/native/java_util_zip_CRC32.h b/ojluni/src/main/native/java_util_zip_CRC32.h
new file mode 100755
index 0000000..73ea19f
--- /dev/null
+++ b/ojluni/src/main/native/java_util_zip_CRC32.h
@@ -0,0 +1,29 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class java_util_zip_CRC32 */
+
+#ifndef _Included_java_util_zip_CRC32
+#define _Included_java_util_zip_CRC32
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class:     java_util_zip_CRC32
+ * Method:    update
+ * Signature: (II)I
+ */
+JNIEXPORT jint JNICALL Java_java_util_zip_CRC32_update
+  (JNIEnv *, jclass, jint, jint);
+
+/*
+ * Class:     java_util_zip_CRC32
+ * Method:    updateBytes
+ * Signature: (I[BII)I
+ */
+JNIEXPORT jint JNICALL Java_java_util_zip_CRC32_updateBytes
+  (JNIEnv *, jclass, jint, jbyteArray, jint, jint);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/ojluni/src/main/native/java_util_zip_Deflater.c b/ojluni/src/main/native/java_util_zip_Deflater.c
new file mode 100755
index 0000000..dbf5ea4
--- /dev/null
+++ b/ojluni/src/main/native/java_util_zip_Deflater.c
@@ -0,0 +1,234 @@
+/*
+ * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * Native method support for java.util.zip.Deflater
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "jlong.h"
+#include "jni.h"
+#include "jni_util.h"
+#include <zlib.h>
+
+#include "java_util_zip_Deflater.h"
+
+#define DEF_MEM_LEVEL 8
+
+static jfieldID levelID;
+static jfieldID strategyID;
+static jfieldID setParamsID;
+static jfieldID finishID;
+static jfieldID finishedID;
+static jfieldID bufID, offID, lenID;
+
+JNIEXPORT void JNICALL
+Java_java_util_zip_Deflater_initIDs(JNIEnv *env, jclass cls)
+{
+    levelID = (*env)->GetFieldID(env, cls, "level", "I");
+    strategyID = (*env)->GetFieldID(env, cls, "strategy", "I");
+    setParamsID = (*env)->GetFieldID(env, cls, "setParams", "Z");
+    finishID = (*env)->GetFieldID(env, cls, "finish", "Z");
+    finishedID = (*env)->GetFieldID(env, cls, "finished", "Z");
+    bufID = (*env)->GetFieldID(env, cls, "buf", "[B");
+    offID = (*env)->GetFieldID(env, cls, "off", "I");
+    lenID = (*env)->GetFieldID(env, cls, "len", "I");
+}
+
+JNIEXPORT jlong JNICALL
+Java_java_util_zip_Deflater_init(JNIEnv *env, jclass cls, jint level,
+                                 jint strategy, jboolean nowrap)
+{
+    z_stream *strm = calloc(1, sizeof(z_stream));
+
+    if (strm == 0) {
+        JNU_ThrowOutOfMemoryError(env, 0);
+        return jlong_zero;
+    } else {
+        char *msg;
+        switch (deflateInit2(strm, level, Z_DEFLATED,
+                             nowrap ? -MAX_WBITS : MAX_WBITS,
+                             DEF_MEM_LEVEL, strategy)) {
+          case Z_OK:
+            return ptr_to_jlong(strm);
+          case Z_MEM_ERROR:
+            free(strm);
+            JNU_ThrowOutOfMemoryError(env, 0);
+            return jlong_zero;
+          case Z_STREAM_ERROR:
+            free(strm);
+            JNU_ThrowIllegalArgumentException(env, 0);
+            return jlong_zero;
+          default:
+            msg = strm->msg;
+            free(strm);
+            JNU_ThrowInternalError(env, msg);
+            return jlong_zero;
+        }
+    }
+}
+
+JNIEXPORT void JNICALL
+Java_java_util_zip_Deflater_setDictionary(JNIEnv *env, jclass cls, jlong addr,
+                                          jarray b, jint off, jint len)
+{
+    Bytef *buf = (*env)->GetPrimitiveArrayCritical(env, b, 0);
+    int res;
+    if (buf == 0) {/* out of memory */
+        return;
+    }
+    res = deflateSetDictionary((z_stream *)jlong_to_ptr(addr), buf + off, len);
+    (*env)->ReleasePrimitiveArrayCritical(env, b, buf, 0);
+    switch (res) {
+    case Z_OK:
+        break;
+    case Z_STREAM_ERROR:
+        JNU_ThrowIllegalArgumentException(env, 0);
+        break;
+    default:
+        JNU_ThrowInternalError(env, ((z_stream *)jlong_to_ptr(addr))->msg);
+        break;
+    }
+}
+
+JNIEXPORT jint JNICALL
+Java_java_util_zip_Deflater_deflateBytes(JNIEnv *env, jobject this, jlong addr,
+                                         jarray b, jint off, jint len, jint flush)
+{
+    z_stream *strm = jlong_to_ptr(addr);
+
+    jarray this_buf = (*env)->GetObjectField(env, this, bufID);
+    jint this_off = (*env)->GetIntField(env, this, offID);
+    jint this_len = (*env)->GetIntField(env, this, lenID);
+    jbyte *in_buf;
+    jbyte *out_buf;
+    int res;
+    if ((*env)->GetBooleanField(env, this, setParamsID)) {
+        int level = (*env)->GetIntField(env, this, levelID);
+        int strategy = (*env)->GetIntField(env, this, strategyID);
+        in_buf = (*env)->GetPrimitiveArrayCritical(env, this_buf, 0);
+        if (in_buf == NULL) {
+            // Throw OOME only when length is not zero
+            if (this_len != 0)
+                JNU_ThrowOutOfMemoryError(env, 0);
+            return 0;
+        }
+        out_buf = (*env)->GetPrimitiveArrayCritical(env, b, 0);
+        if (out_buf == NULL) {
+            (*env)->ReleasePrimitiveArrayCritical(env, this_buf, in_buf, 0);
+            if (len != 0)
+                JNU_ThrowOutOfMemoryError(env, 0);
+            return 0;
+        }
+
+        strm->next_in = (Bytef *) (in_buf + this_off);
+        strm->next_out = (Bytef *) (out_buf + off);
+        strm->avail_in = this_len;
+        strm->avail_out = len;
+        res = deflateParams(strm, level, strategy);
+        (*env)->ReleasePrimitiveArrayCritical(env, b, out_buf, 0);
+        (*env)->ReleasePrimitiveArrayCritical(env, this_buf, in_buf, 0);
+
+        switch (res) {
+        case Z_OK:
+            (*env)->SetBooleanField(env, this, setParamsID, JNI_FALSE);
+            this_off += this_len - strm->avail_in;
+            (*env)->SetIntField(env, this, offID, this_off);
+            (*env)->SetIntField(env, this, lenID, strm->avail_in);
+            return len - strm->avail_out;
+        case Z_BUF_ERROR:
+            (*env)->SetBooleanField(env, this, setParamsID, JNI_FALSE);
+            return 0;
+        default:
+            JNU_ThrowInternalError(env, strm->msg);
+            return 0;
+        }
+    } else {
+        jboolean finish = (*env)->GetBooleanField(env, this, finishID);
+        in_buf = (*env)->GetPrimitiveArrayCritical(env, this_buf, 0);
+        if (in_buf == NULL) {
+            if (this_len != 0)
+                JNU_ThrowOutOfMemoryError(env, 0);
+            return 0;
+        }
+        out_buf = (*env)->GetPrimitiveArrayCritical(env, b, 0);
+        if (out_buf == NULL) {
+            (*env)->ReleasePrimitiveArrayCritical(env, this_buf, in_buf, 0);
+            if (len != 0)
+                JNU_ThrowOutOfMemoryError(env, 0);
+
+            return 0;
+        }
+
+        strm->next_in = (Bytef *) (in_buf + this_off);
+        strm->next_out = (Bytef *) (out_buf + off);
+        strm->avail_in = this_len;
+        strm->avail_out = len;
+        res = deflate(strm, finish ? Z_FINISH : flush);
+        (*env)->ReleasePrimitiveArrayCritical(env, b, out_buf, 0);
+        (*env)->ReleasePrimitiveArrayCritical(env, this_buf, in_buf, 0);
+
+        switch (res) {
+        case Z_STREAM_END:
+            (*env)->SetBooleanField(env, this, finishedID, JNI_TRUE);
+            /* fall through */
+        case Z_OK:
+            this_off += this_len - strm->avail_in;
+            (*env)->SetIntField(env, this, offID, this_off);
+            (*env)->SetIntField(env, this, lenID, strm->avail_in);
+            return len - strm->avail_out;
+        case Z_BUF_ERROR:
+            return 0;
+            default:
+            JNU_ThrowInternalError(env, strm->msg);
+            return 0;
+        }
+    }
+}
+
+JNIEXPORT jint JNICALL
+Java_java_util_zip_Deflater_getAdler(JNIEnv *env, jclass cls, jlong addr)
+{
+    return ((z_stream *)jlong_to_ptr(addr))->adler;
+}
+
+JNIEXPORT void JNICALL
+Java_java_util_zip_Deflater_reset(JNIEnv *env, jclass cls, jlong addr)
+{
+    if (deflateReset((z_stream *)jlong_to_ptr(addr)) != Z_OK) {
+        JNU_ThrowInternalError(env, 0);
+    }
+}
+
+JNIEXPORT void JNICALL
+Java_java_util_zip_Deflater_end(JNIEnv *env, jclass cls, jlong addr)
+{
+    if (deflateEnd((z_stream *)jlong_to_ptr(addr)) == Z_STREAM_ERROR) {
+        JNU_ThrowInternalError(env, 0);
+    } else {
+        free((z_stream *)jlong_to_ptr(addr));
+    }
+}
diff --git a/ojluni/src/main/native/java_util_zip_Deflater.h b/ojluni/src/main/native/java_util_zip_Deflater.h
new file mode 100755
index 0000000..a07f810
--- /dev/null
+++ b/ojluni/src/main/native/java_util_zip_Deflater.h
@@ -0,0 +1,91 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class java_util_zip_Deflater */
+
+#ifndef _Included_java_util_zip_Deflater
+#define _Included_java_util_zip_Deflater
+#ifdef __cplusplus
+extern "C" {
+#endif
+#undef java_util_zip_Deflater_DEFLATED
+#define java_util_zip_Deflater_DEFLATED 8L
+#undef java_util_zip_Deflater_NO_COMPRESSION
+#define java_util_zip_Deflater_NO_COMPRESSION 0L
+#undef java_util_zip_Deflater_BEST_SPEED
+#define java_util_zip_Deflater_BEST_SPEED 1L
+#undef java_util_zip_Deflater_BEST_COMPRESSION
+#define java_util_zip_Deflater_BEST_COMPRESSION 9L
+#undef java_util_zip_Deflater_DEFAULT_COMPRESSION
+#define java_util_zip_Deflater_DEFAULT_COMPRESSION -1L
+#undef java_util_zip_Deflater_FILTERED
+#define java_util_zip_Deflater_FILTERED 1L
+#undef java_util_zip_Deflater_HUFFMAN_ONLY
+#define java_util_zip_Deflater_HUFFMAN_ONLY 2L
+#undef java_util_zip_Deflater_DEFAULT_STRATEGY
+#define java_util_zip_Deflater_DEFAULT_STRATEGY 0L
+#undef java_util_zip_Deflater_NO_FLUSH
+#define java_util_zip_Deflater_NO_FLUSH 0L
+#undef java_util_zip_Deflater_SYNC_FLUSH
+#define java_util_zip_Deflater_SYNC_FLUSH 2L
+#undef java_util_zip_Deflater_FULL_FLUSH
+#define java_util_zip_Deflater_FULL_FLUSH 3L
+/*
+ * Class:     java_util_zip_Deflater
+ * Method:    initIDs
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_java_util_zip_Deflater_initIDs
+  (JNIEnv *, jclass);
+
+/*
+ * Class:     java_util_zip_Deflater
+ * Method:    init
+ * Signature: (IIZ)J
+ */
+JNIEXPORT jlong JNICALL Java_java_util_zip_Deflater_init
+  (JNIEnv *, jclass, jint, jint, jboolean);
+
+/*
+ * Class:     java_util_zip_Deflater
+ * Method:    setDictionary
+ * Signature: (J[BII)V
+ */
+JNIEXPORT void JNICALL Java_java_util_zip_Deflater_setDictionary
+  (JNIEnv *, jclass, jlong, jbyteArray, jint, jint);
+
+/*
+ * Class:     java_util_zip_Deflater
+ * Method:    deflateBytes
+ * Signature: (J[BIII)I
+ */
+JNIEXPORT jint JNICALL Java_java_util_zip_Deflater_deflateBytes
+  (JNIEnv *, jobject, jlong, jbyteArray, jint, jint, jint);
+
+/*
+ * Class:     java_util_zip_Deflater
+ * Method:    getAdler
+ * Signature: (J)I
+ */
+JNIEXPORT jint JNICALL Java_java_util_zip_Deflater_getAdler
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     java_util_zip_Deflater
+ * Method:    reset
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_java_util_zip_Deflater_reset
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     java_util_zip_Deflater
+ * Method:    end
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_java_util_zip_Deflater_end
+  (JNIEnv *, jclass, jlong);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/ojluni/src/main/native/java_util_zip_Inflater.c b/ojluni/src/main/native/java_util_zip_Inflater.c
new file mode 100755
index 0000000..062a892
--- /dev/null
+++ b/ojluni/src/main/native/java_util_zip_Inflater.c
@@ -0,0 +1,193 @@
+/*
+ * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * Native method support for java.util.zip.Inflater
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include "jlong.h"
+#include "jni.h"
+#include "jvm.h"
+#include "jni_util.h"
+#include <zlib.h>
+#include "java_util_zip_Inflater.h"
+
+#define ThrowDataFormatException(env, msg) \
+        JNU_ThrowByName(env, "java/util/zip/DataFormatException", msg)
+
+static jfieldID needDictID;
+static jfieldID finishedID;
+static jfieldID bufID, offID, lenID;
+
+JNIEXPORT void JNICALL
+Java_java_util_zip_Inflater_initIDs(JNIEnv *env, jclass cls)
+{
+    needDictID = (*env)->GetFieldID(env, cls, "needDict", "Z");
+    finishedID = (*env)->GetFieldID(env, cls, "finished", "Z");
+    bufID = (*env)->GetFieldID(env, cls, "buf", "[B");
+    offID = (*env)->GetFieldID(env, cls, "off", "I");
+    lenID = (*env)->GetFieldID(env, cls, "len", "I");
+}
+
+JNIEXPORT jlong JNICALL
+Java_java_util_zip_Inflater_init(JNIEnv *env, jclass cls, jboolean nowrap)
+{
+    z_stream *strm = calloc(1, sizeof(z_stream));
+
+    if (strm == 0) {
+        JNU_ThrowOutOfMemoryError(env, 0);
+        return jlong_zero;
+    } else {
+        char *msg;
+        switch (inflateInit2(strm, nowrap ? -MAX_WBITS : MAX_WBITS)) {
+          case Z_OK:
+            return ptr_to_jlong(strm);
+          case Z_MEM_ERROR:
+            free(strm);
+            JNU_ThrowOutOfMemoryError(env, 0);
+            return jlong_zero;
+          default:
+            msg = strm->msg;
+            free(strm);
+            JNU_ThrowInternalError(env, msg);
+            return jlong_zero;
+        }
+    }
+}
+
+JNIEXPORT void JNICALL
+Java_java_util_zip_Inflater_setDictionary(JNIEnv *env, jclass cls, jlong addr,
+                                          jarray b, jint off, jint len)
+{
+    Bytef *buf = (*env)->GetPrimitiveArrayCritical(env, b, 0);
+    int res;
+    if (buf == 0) /* out of memory */
+        return;
+    res = inflateSetDictionary(jlong_to_ptr(addr), buf + off, len);
+    (*env)->ReleasePrimitiveArrayCritical(env, b, buf, 0);
+    switch (res) {
+    case Z_OK:
+        break;
+    case Z_STREAM_ERROR:
+    case Z_DATA_ERROR:
+        JNU_ThrowIllegalArgumentException(env, ((z_stream *)jlong_to_ptr(addr))->msg);
+        break;
+    default:
+        JNU_ThrowInternalError(env, ((z_stream *)jlong_to_ptr(addr))->msg);
+        break;
+    }
+}
+
+JNIEXPORT jint JNICALL
+Java_java_util_zip_Inflater_inflateBytes(JNIEnv *env, jobject this, jlong addr,
+                                         jarray b, jint off, jint len)
+{
+    z_stream *strm = jlong_to_ptr(addr);
+    jarray this_buf = (jarray)(*env)->GetObjectField(env, this, bufID);
+    jint this_off = (*env)->GetIntField(env, this, offID);
+    jint this_len = (*env)->GetIntField(env, this, lenID);
+
+    jbyte *in_buf;
+    jbyte *out_buf;
+    int ret;
+
+    in_buf  = (*env)->GetPrimitiveArrayCritical(env, this_buf, 0);
+    if (in_buf == NULL) {
+        if (this_len != 0)
+            JNU_ThrowOutOfMemoryError(env, 0);
+        return 0;
+    }
+    out_buf = (*env)->GetPrimitiveArrayCritical(env, b, 0);
+    if (out_buf == NULL) {
+        (*env)->ReleasePrimitiveArrayCritical(env, this_buf, in_buf, 0);
+        if (len != 0)
+            JNU_ThrowOutOfMemoryError(env, 0);
+        return 0;
+    }
+    strm->next_in  = (Bytef *) (in_buf + this_off);
+    strm->next_out = (Bytef *) (out_buf + off);
+    strm->avail_in  = this_len;
+    strm->avail_out = len;
+    ret = inflate(strm, Z_PARTIAL_FLUSH);
+    (*env)->ReleasePrimitiveArrayCritical(env, b, out_buf, 0);
+    (*env)->ReleasePrimitiveArrayCritical(env, this_buf, in_buf, 0);
+
+    switch (ret) {
+    case Z_STREAM_END:
+        (*env)->SetBooleanField(env, this, finishedID, JNI_TRUE);
+        /* fall through */
+    case Z_OK:
+        this_off += this_len - strm->avail_in;
+        (*env)->SetIntField(env, this, offID, this_off);
+        (*env)->SetIntField(env, this, lenID, strm->avail_in);
+        return len - strm->avail_out;
+    case Z_NEED_DICT:
+        (*env)->SetBooleanField(env, this, needDictID, JNI_TRUE);
+        /* Might have consumed some input here! */
+        this_off += this_len - strm->avail_in;
+        (*env)->SetIntField(env, this, offID, this_off);
+        (*env)->SetIntField(env, this, lenID, strm->avail_in);
+        return 0;
+    case Z_BUF_ERROR:
+        return 0;
+    case Z_DATA_ERROR:
+        ThrowDataFormatException(env, strm->msg);
+        return 0;
+    case Z_MEM_ERROR:
+        JNU_ThrowOutOfMemoryError(env, 0);
+        return 0;
+    default:
+        JNU_ThrowInternalError(env, strm->msg);
+        return 0;
+    }
+}
+
+JNIEXPORT jint JNICALL
+Java_java_util_zip_Inflater_getAdler(JNIEnv *env, jclass cls, jlong addr)
+{
+    return ((z_stream *)jlong_to_ptr(addr))->adler;
+}
+
+JNIEXPORT void JNICALL
+Java_java_util_zip_Inflater_reset(JNIEnv *env, jclass cls, jlong addr)
+{
+    if (inflateReset(jlong_to_ptr(addr)) != Z_OK) {
+        JNU_ThrowInternalError(env, 0);
+    }
+}
+
+JNIEXPORT void JNICALL
+Java_java_util_zip_Inflater_end(JNIEnv *env, jclass cls, jlong addr)
+{
+    if (inflateEnd(jlong_to_ptr(addr)) == Z_STREAM_ERROR) {
+        JNU_ThrowInternalError(env, 0);
+    } else {
+        free(jlong_to_ptr(addr));
+    }
+}
diff --git a/ojluni/src/main/native/java_util_zip_Inflater.h b/ojluni/src/main/native/java_util_zip_Inflater.h
new file mode 100755
index 0000000..0fcec49
--- /dev/null
+++ b/ojluni/src/main/native/java_util_zip_Inflater.h
@@ -0,0 +1,69 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class java_util_zip_Inflater */
+
+#ifndef _Included_java_util_zip_Inflater
+#define _Included_java_util_zip_Inflater
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class:     java_util_zip_Inflater
+ * Method:    initIDs
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_java_util_zip_Inflater_initIDs
+  (JNIEnv *, jclass);
+
+/*
+ * Class:     java_util_zip_Inflater
+ * Method:    init
+ * Signature: (Z)J
+ */
+JNIEXPORT jlong JNICALL Java_java_util_zip_Inflater_init
+  (JNIEnv *, jclass, jboolean);
+
+/*
+ * Class:     java_util_zip_Inflater
+ * Method:    setDictionary
+ * Signature: (J[BII)V
+ */
+JNIEXPORT void JNICALL Java_java_util_zip_Inflater_setDictionary
+  (JNIEnv *, jclass, jlong, jbyteArray, jint, jint);
+
+/*
+ * Class:     java_util_zip_Inflater
+ * Method:    inflateBytes
+ * Signature: (J[BII)I
+ */
+JNIEXPORT jint JNICALL Java_java_util_zip_Inflater_inflateBytes
+  (JNIEnv *, jobject, jlong, jbyteArray, jint, jint);
+
+/*
+ * Class:     java_util_zip_Inflater
+ * Method:    getAdler
+ * Signature: (J)I
+ */
+JNIEXPORT jint JNICALL Java_java_util_zip_Inflater_getAdler
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     java_util_zip_Inflater
+ * Method:    reset
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_java_util_zip_Inflater_reset
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     java_util_zip_Inflater
+ * Method:    end
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_java_util_zip_Inflater_end
+  (JNIEnv *, jclass, jlong);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/ojluni/src/main/native/java_util_zip_ZipFile.c b/ojluni/src/main/native/java_util_zip_ZipFile.c
new file mode 100755
index 0000000..30fbfdd
--- /dev/null
+++ b/ojluni/src/main/native/java_util_zip_ZipFile.c
@@ -0,0 +1,395 @@
+/*
+ * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * Native method support for java.util.zip.ZipFile
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <ctype.h>
+#include <assert.h>
+#include "jlong.h"
+#include "jvm.h"
+#include "jni.h"
+#include "jni_util.h"
+#include "zip_util.h"
+#ifdef WIN32
+#include "io_util_md.h"
+#else
+#include "io_util.h"
+#endif
+
+#include "java_util_zip_ZipFile.h"
+#include "java_util_jar_JarFile.h"
+
+#define DEFLATED 8
+#define STORED 0
+
+static jfieldID jzfileID;
+
+static int OPEN_READ = java_util_zip_ZipFile_OPEN_READ;
+static int OPEN_DELETE = java_util_zip_ZipFile_OPEN_DELETE;
+
+JNIEXPORT void JNICALL
+Java_java_util_zip_ZipFile_initIDs(JNIEnv *env, jclass cls)
+{
+    jzfileID = (*env)->GetFieldID(env, cls, "jzfile", "J");
+    assert(jzfileID != 0);
+}
+
+static void
+ThrowZipException(JNIEnv *env, const char *msg)
+{
+    jstring s = NULL;
+    jobject x;
+
+    if (msg != NULL) {
+        s = JNU_NewStringPlatform(env, msg);
+    }
+    x = JNU_NewObjectByName(env,
+                            "java/util/zip/ZipException",
+                            "(Ljava/lang/String;)V", s);
+    if (x != NULL) {
+        (*env)->Throw(env, x);
+    }
+}
+
+JNIEXPORT jlong JNICALL
+Java_java_util_zip_ZipFile_open(JNIEnv *env, jclass cls, jstring name,
+                                        jint mode, jlong lastModified,
+                                        jboolean usemmap)
+{
+    const char *path = JNU_GetStringPlatformChars(env, name, 0);
+    char *msg = 0;
+    jlong result = 0;
+    int flag = 0;
+    jzfile *zip = 0;
+
+    if (mode & OPEN_READ) flag |= O_RDONLY;
+    if (mode & OPEN_DELETE) flag |= JVM_O_DELETE;
+
+    if (path != 0) {
+        zip = ZIP_Get_From_Cache(path, &msg, lastModified);
+        if (zip == 0 && msg == 0) {
+            ZFILE zfd = 0;
+#ifdef WIN32
+            zfd = winFileHandleOpen(env, name, flag);
+            if (zfd == -1) {
+                /* Exception already pending. */
+                goto finally;
+            }
+#else
+            zfd = JVM_Open(path, flag, 0);
+            if (zfd < 0) {
+                throwFileNotFoundException(env, name);
+                goto finally;
+            }
+#endif
+            zip = ZIP_Put_In_Cache0(path, zfd, &msg, lastModified, usemmap);
+        }
+
+        if (zip != 0) {
+            result = ptr_to_jlong(zip);
+        } else if (msg != 0) {
+            ThrowZipException(env, msg);
+            free(msg);
+        } else if (errno == ENOMEM) {
+            JNU_ThrowOutOfMemoryError(env, 0);
+        } else {
+            ThrowZipException(env, "error in opening zip file");
+        }
+finally:
+        JNU_ReleaseStringPlatformChars(env, name, path);
+    }
+    return result;
+}
+
+JNIEXPORT jint JNICALL
+Java_java_util_zip_ZipFile_getTotal(JNIEnv *env, jclass cls, jlong zfile)
+{
+    jzfile *zip = jlong_to_ptr(zfile);
+
+    return zip->total;
+}
+
+JNIEXPORT jboolean JNICALL
+Java_java_util_zip_ZipFile_startsWithLOC(JNIEnv *env, jclass cls, jlong zfile)
+{
+    jzfile *zip = jlong_to_ptr(zfile);
+
+    return zip->locsig;
+}
+
+JNIEXPORT void JNICALL
+Java_java_util_zip_ZipFile_close(JNIEnv *env, jclass cls, jlong zfile)
+{
+    ZIP_Close(jlong_to_ptr(zfile));
+}
+
+JNIEXPORT jlong JNICALL
+Java_java_util_zip_ZipFile_getEntry(JNIEnv *env, jclass cls, jlong zfile,
+                                    jbyteArray name, jboolean addSlash)
+{
+#define MAXNAME 1024
+    jzfile *zip = jlong_to_ptr(zfile);
+    jsize ulen = (*env)->GetArrayLength(env, name);
+    char buf[MAXNAME+2], *path;
+    jzentry *ze;
+
+    if (ulen > MAXNAME) {
+        path = malloc(ulen + 2);
+        if (path == 0) {
+            JNU_ThrowOutOfMemoryError(env, 0);
+            return 0;
+        }
+    } else {
+        path = buf;
+    }
+    (*env)->GetByteArrayRegion(env, name, 0, ulen, (jbyte *)path);
+    path[ulen] = '\0';
+    if (addSlash == JNI_FALSE) {
+        ze = ZIP_GetEntry(zip, path, 0);
+    } else {
+        ze = ZIP_GetEntry(zip, path, (jint)ulen);
+    }
+    if (path != buf) {
+        free(path);
+    }
+    return ptr_to_jlong(ze);
+}
+
+JNIEXPORT void JNICALL
+Java_java_util_zip_ZipFile_freeEntry(JNIEnv *env, jclass cls, jlong zfile,
+                                    jlong zentry)
+{
+    jzfile *zip = jlong_to_ptr(zfile);
+    jzentry *ze = jlong_to_ptr(zentry);
+    ZIP_FreeEntry(zip, ze);
+}
+
+JNIEXPORT jlong JNICALL
+Java_java_util_zip_ZipFile_getNextEntry(JNIEnv *env, jclass cls, jlong zfile,
+                                        jint n)
+{
+    jzentry *ze = ZIP_GetNextEntry(jlong_to_ptr(zfile), n);
+    return ptr_to_jlong(ze);
+}
+
+JNIEXPORT jint JNICALL
+Java_java_util_zip_ZipFile_getEntryMethod(JNIEnv *env, jclass cls, jlong zentry)
+{
+    jzentry *ze = jlong_to_ptr(zentry);
+    return ze->csize != 0 ? DEFLATED : STORED;
+}
+
+JNIEXPORT jint JNICALL
+Java_java_util_zip_ZipFile_getEntryFlag(JNIEnv *env, jclass cls, jlong zentry)
+{
+    jzentry *ze = jlong_to_ptr(zentry);
+    return ze->flag;
+}
+
+JNIEXPORT jlong JNICALL
+Java_java_util_zip_ZipFile_getEntryCSize(JNIEnv *env, jclass cls, jlong zentry)
+{
+    jzentry *ze = jlong_to_ptr(zentry);
+    return ze->csize != 0 ? ze->csize : ze->size;
+}
+
+JNIEXPORT jlong JNICALL
+Java_java_util_zip_ZipFile_getEntrySize(JNIEnv *env, jclass cls, jlong zentry)
+{
+    jzentry *ze = jlong_to_ptr(zentry);
+    return ze->size;
+}
+
+JNIEXPORT jlong JNICALL
+Java_java_util_zip_ZipFile_getEntryTime(JNIEnv *env, jclass cls, jlong zentry)
+{
+    jzentry *ze = jlong_to_ptr(zentry);
+    return (jlong)ze->time & 0xffffffffUL;
+}
+
+JNIEXPORT jlong JNICALL
+Java_java_util_zip_ZipFile_getEntryCrc(JNIEnv *env, jclass cls, jlong zentry)
+{
+    jzentry *ze = jlong_to_ptr(zentry);
+    return (jlong)ze->crc & 0xffffffffUL;
+}
+
+JNIEXPORT jbyteArray JNICALL
+Java_java_util_zip_ZipFile_getCommentBytes(JNIEnv *env,
+                                           jclass cls,
+                                           jlong zfile)
+{
+    jzfile *zip = jlong_to_ptr(zfile);
+    jbyteArray jba = NULL;
+
+    if (zip->comment != NULL) {
+        if ((jba = (*env)->NewByteArray(env, zip->clen)) == NULL)
+            return NULL;
+        (*env)->SetByteArrayRegion(env, jba, 0, zip->clen, (jbyte*)zip->comment);
+    }
+    return jba;
+}
+
+JNIEXPORT jbyteArray JNICALL
+Java_java_util_zip_ZipFile_getEntryBytes(JNIEnv *env,
+                                         jclass cls,
+                                         jlong zentry, jint type)
+{
+    jzentry *ze = jlong_to_ptr(zentry);
+    int len = 0;
+    jbyteArray jba = NULL;
+    switch (type) {
+    case java_util_zip_ZipFile_JZENTRY_NAME:
+        if (ze->name != 0) {
+            len = (int)strlen(ze->name);
+            if (len == 0 || (jba = (*env)->NewByteArray(env, len)) == NULL)
+                break;
+            (*env)->SetByteArrayRegion(env, jba, 0, len, (jbyte *)ze->name);
+        }
+        break;
+    case java_util_zip_ZipFile_JZENTRY_EXTRA:
+        if (ze->extra != 0) {
+            unsigned char *bp = (unsigned char *)&ze->extra[0];
+            len = (bp[0] | (bp[1] << 8));
+            if (len <= 0 || (jba = (*env)->NewByteArray(env, len)) == NULL)
+                break;
+            (*env)->SetByteArrayRegion(env, jba, 0, len, &ze->extra[2]);
+        }
+        break;
+    case java_util_zip_ZipFile_JZENTRY_COMMENT:
+        if (ze->comment != 0) {
+            len = (int)strlen(ze->comment);
+            if (len == 0 || (jba = (*env)->NewByteArray(env, len)) == NULL)
+                break;
+            (*env)->SetByteArrayRegion(env, jba, 0, len, (jbyte*)ze->comment);
+        }
+        break;
+    }
+    return jba;
+}
+
+JNIEXPORT jint JNICALL
+Java_java_util_zip_ZipFile_read(JNIEnv *env, jclass cls, jlong zfile,
+                                jlong zentry, jlong pos, jbyteArray bytes,
+                                jint off, jint len)
+{
+    jzfile *zip = jlong_to_ptr(zfile);
+    char *msg;
+
+#define BUFSIZE 8192
+    /* copy via tmp stack buffer: */
+    jbyte buf[BUFSIZE];
+
+    if (len > BUFSIZE) {
+        len = BUFSIZE;
+    }
+
+    ZIP_Lock(zip);
+    len = ZIP_Read(zip, jlong_to_ptr(zentry), pos, buf, len);
+    msg = zip->msg;
+    ZIP_Unlock(zip);
+    if (len != -1) {
+        (*env)->SetByteArrayRegion(env, bytes, off, len, buf);
+    }
+
+    if (len == -1) {
+        if (msg != 0) {
+            ThrowZipException(env, msg);
+        } else {
+            char errmsg[128];
+            sprintf(errmsg, "errno: %d, error: %s\n",
+                    errno, "Error reading ZIP file");
+            JNU_ThrowIOExceptionWithLastError(env, errmsg);
+        }
+    }
+
+    return len;
+}
+
+/*
+ * Returns an array of strings representing the names of all entries
+ * that begin with "META-INF/" (case ignored). This native method is
+ * used in JarFile as an optimization when looking up manifest and
+ * signature file entries. Returns null if no entries were found.
+ */
+JNIEXPORT jobjectArray JNICALL
+Java_java_util_jar_JarFile_getMetaInfEntryNames(JNIEnv *env, jobject obj)
+{
+    jlong zfile = (*env)->GetLongField(env, obj, jzfileID);
+    jzfile *zip;
+    int i, count;
+    jobjectArray result = 0;
+
+    if (zfile == 0) {
+        JNU_ThrowByName(env,
+                        "java/lang/IllegalStateException", "zip file closed");
+        return NULL;
+    }
+    zip = jlong_to_ptr(zfile);
+
+    /* count the number of valid ZIP metanames */
+    count = 0;
+    if (zip->metanames != 0) {
+        for (i = 0; i < zip->metacount; i++) {
+            if (zip->metanames[i] != 0) {
+                count++;
+            }
+        }
+    }
+
+    /* If some names were found then build array of java strings */
+    if (count > 0) {
+        jclass cls = (*env)->FindClass(env, "java/lang/String");
+        result = (*env)->NewObjectArray(env, count, cls, 0);
+        if (result != 0) {
+            for (i = 0; i < count; i++) {
+                jstring str = (*env)->NewStringUTF(env, zip->metanames[i]);
+                if (str == 0) {
+                    break;
+                }
+                (*env)->SetObjectArrayElement(env, result, i, str);
+                (*env)->DeleteLocalRef(env, str);
+            }
+        }
+    }
+    return result;
+}
+
+JNIEXPORT jstring JNICALL
+Java_java_util_zip_ZipFile_getZipMessage(JNIEnv *env, jclass cls, jlong zfile)
+{
+    jzfile *zip = jlong_to_ptr(zfile);
+    char *msg = zip->msg;
+    if (msg == NULL) {
+        return NULL;
+    }
+    return JNU_NewStringPlatform(env, msg);
+}
diff --git a/ojluni/src/main/native/java_util_zip_ZipFile.h b/ojluni/src/main/native/java_util_zip_ZipFile.h
new file mode 100755
index 0000000..d58b4f0
--- /dev/null
+++ b/ojluni/src/main/native/java_util_zip_ZipFile.h
@@ -0,0 +1,171 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class java_util_zip_ZipFile */
+
+#ifndef _Included_java_util_zip_ZipFile
+#define _Included_java_util_zip_ZipFile
+#ifdef __cplusplus
+extern "C" {
+#endif
+#undef java_util_zip_ZipFile_STORED
+#define java_util_zip_ZipFile_STORED 0L
+#undef java_util_zip_ZipFile_DEFLATED
+#define java_util_zip_ZipFile_DEFLATED 8L
+#undef java_util_zip_ZipFile_OPEN_READ
+#define java_util_zip_ZipFile_OPEN_READ 1L
+#undef java_util_zip_ZipFile_OPEN_DELETE
+#define java_util_zip_ZipFile_OPEN_DELETE 4L
+#undef java_util_zip_ZipFile_JZENTRY_NAME
+#define java_util_zip_ZipFile_JZENTRY_NAME 0L
+#undef java_util_zip_ZipFile_JZENTRY_EXTRA
+#define java_util_zip_ZipFile_JZENTRY_EXTRA 1L
+#undef java_util_zip_ZipFile_JZENTRY_COMMENT
+#define java_util_zip_ZipFile_JZENTRY_COMMENT 2L
+/*
+ * Class:     java_util_zip_ZipFile
+ * Method:    initIDs
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_java_util_zip_ZipFile_initIDs
+  (JNIEnv *, jclass);
+
+/*
+ * Class:     java_util_zip_ZipFile
+ * Method:    getEntry
+ * Signature: (J[BZ)J
+ */
+JNIEXPORT jlong JNICALL Java_java_util_zip_ZipFile_getEntry
+  (JNIEnv *, jclass, jlong, jbyteArray, jboolean);
+
+/*
+ * Class:     java_util_zip_ZipFile
+ * Method:    freeEntry
+ * Signature: (JJ)V
+ */
+JNIEXPORT void JNICALL Java_java_util_zip_ZipFile_freeEntry
+  (JNIEnv *, jclass, jlong, jlong);
+
+/*
+ * Class:     java_util_zip_ZipFile
+ * Method:    getNextEntry
+ * Signature: (JI)J
+ */
+JNIEXPORT jlong JNICALL Java_java_util_zip_ZipFile_getNextEntry
+  (JNIEnv *, jclass, jlong, jint);
+
+/*
+ * Class:     java_util_zip_ZipFile
+ * Method:    close
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_java_util_zip_ZipFile_close
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     java_util_zip_ZipFile
+ * Method:    open
+ * Signature: (Ljava/lang/String;IJZ)J
+ */
+JNIEXPORT jlong JNICALL Java_java_util_zip_ZipFile_open
+  (JNIEnv *, jclass, jstring, jint, jlong, jboolean);
+
+/*
+ * Class:     java_util_zip_ZipFile
+ * Method:    getTotal
+ * Signature: (J)I
+ */
+JNIEXPORT jint JNICALL Java_java_util_zip_ZipFile_getTotal
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     java_util_zip_ZipFile
+ * Method:    startsWithLOC
+ * Signature: (J)Z
+ */
+JNIEXPORT jboolean JNICALL Java_java_util_zip_ZipFile_startsWithLOC
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     java_util_zip_ZipFile
+ * Method:    read
+ * Signature: (JJJ[BII)I
+ */
+JNIEXPORT jint JNICALL Java_java_util_zip_ZipFile_read
+  (JNIEnv *, jclass, jlong, jlong, jlong, jbyteArray, jint, jint);
+
+/*
+ * Class:     java_util_zip_ZipFile
+ * Method:    getEntryTime
+ * Signature: (J)J
+ */
+JNIEXPORT jlong JNICALL Java_java_util_zip_ZipFile_getEntryTime
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     java_util_zip_ZipFile
+ * Method:    getEntryCrc
+ * Signature: (J)J
+ */
+JNIEXPORT jlong JNICALL Java_java_util_zip_ZipFile_getEntryCrc
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     java_util_zip_ZipFile
+ * Method:    getEntryCSize
+ * Signature: (J)J
+ */
+JNIEXPORT jlong JNICALL Java_java_util_zip_ZipFile_getEntryCSize
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     java_util_zip_ZipFile
+ * Method:    getEntrySize
+ * Signature: (J)J
+ */
+JNIEXPORT jlong JNICALL Java_java_util_zip_ZipFile_getEntrySize
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     java_util_zip_ZipFile
+ * Method:    getEntryMethod
+ * Signature: (J)I
+ */
+JNIEXPORT jint JNICALL Java_java_util_zip_ZipFile_getEntryMethod
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     java_util_zip_ZipFile
+ * Method:    getEntryFlag
+ * Signature: (J)I
+ */
+JNIEXPORT jint JNICALL Java_java_util_zip_ZipFile_getEntryFlag
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     java_util_zip_ZipFile
+ * Method:    getCommentBytes
+ * Signature: (J)[B
+ */
+JNIEXPORT jbyteArray JNICALL Java_java_util_zip_ZipFile_getCommentBytes
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     java_util_zip_ZipFile
+ * Method:    getEntryBytes
+ * Signature: (JI)[B
+ */
+JNIEXPORT jbyteArray JNICALL Java_java_util_zip_ZipFile_getEntryBytes
+  (JNIEnv *, jclass, jlong, jint);
+
+/*
+ * Class:     java_util_zip_ZipFile
+ * Method:    getZipMessage
+ * Signature: (J)Ljava/lang/String;
+ */
+JNIEXPORT jstring JNICALL Java_java_util_zip_ZipFile_getZipMessage
+  (JNIEnv *, jclass, jlong);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/ojluni/src/main/native/jfdlibm.h b/ojluni/src/main/native/jfdlibm.h
new file mode 100755
index 0000000..4525f4b
--- /dev/null
+++ b/ojluni/src/main/native/jfdlibm.h
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 1998, 2003, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#ifndef _JFDLIBM_H
+#define _JFDLIBM_H
+
+#define _IEEE_LIBM
+
+/*
+ * In order to resolve the conflict between fdlibm and compilers
+ * (such as keywords and built-in functions), the following
+ * function names have to be re-mapped.
+ */
+
+#define huge    HUGE_NUMBER
+#define acos    jacos
+#define asin    jasin
+#define atan    jatan
+#define atan2   jatan2
+#define cos     jcos
+#define exp     jexp
+#define log     jlog
+#define log10   jlog10
+#define pow     jpow
+#define sin     jsin
+#define sqrt    jsqrt
+#define cbrt    jcbrt
+#define tan     jtan
+#define floor   jfloor
+#define ceil    jceil
+#define cosh    jcosh
+#define fmod    jmod
+#define log10   jlog10
+#define sinh    jsinh
+#define fabs    jfabs
+#define tanh    jtanh
+#define remainder jremainder
+#define hypot   jhypot
+#define log1p   jlog1p
+#define expm1   jexpm1
+
+#if defined(__linux__) || defined(_ALLBSD_SOURCE)
+#define __ieee754_sqrt          __j__ieee754_sqrt
+#define __ieee754_acos          __j__ieee754_acos
+#define __ieee754_acosh         __j__ieee754_acosh
+#define __ieee754_log           __j__ieee754_log
+#define __ieee754_atanh         __j__ieee754_atanh
+#define __ieee754_asin          __j__ieee754_asin
+#define __ieee754_atan2         __j__ieee754_atan2
+#define __ieee754_exp           __j__ieee754_exp
+#define __ieee754_cosh          __j__ieee754_cosh
+#define __ieee754_fmod          __j__ieee754_fmod
+#define __ieee754_pow           __j__ieee754_pow
+#define __ieee754_lgamma_r      __j__ieee754_lgamma_r
+#define __ieee754_gamma_r       __j__ieee754_gamma_r
+#define __ieee754_lgamma        __j__ieee754_lgamma
+#define __ieee754_gamma         __j__ieee754_gamma
+#define __ieee754_log10         __j__ieee754_log10
+#define __ieee754_sinh          __j__ieee754_sinh
+#define __ieee754_hypot         __j__ieee754_hypot
+#define __ieee754_j0            __j__ieee754_j0
+#define __ieee754_j1            __j__ieee754_j1
+#define __ieee754_y0            __j__ieee754_y0
+#define __ieee754_y1            __j__ieee754_y1
+#define __ieee754_jn            __j__ieee754_jn
+#define __ieee754_yn            __j__ieee754_yn
+#define __ieee754_remainder     __j__ieee754_remainder
+#define __ieee754_rem_pio2      __j__ieee754_rem_pio2
+#define __ieee754_scalb         __j__ieee754_scalb
+#define __kernel_standard       __j__kernel_standard
+#define __kernel_sin            __j__kernel_sin
+#define __kernel_cos            __j__kernel_cos
+#define __kernel_tan            __j__kernel_tan
+#define __kernel_rem_pio2       __j__kernel_rem_pio2
+#define __ieee754_log1p         __j__ieee754_log1p
+#define __ieee754_expm1         __j__ieee754_expm1
+#endif
+#endif/*_JFDLIBM_H*/
diff --git a/ojluni/src/main/native/jlong.h b/ojluni/src/main/native/jlong.h
new file mode 100755
index 0000000..40fd9f1
--- /dev/null
+++ b/ojluni/src/main/native/jlong.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 1997, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#ifndef _JLONG_H_
+#define _JLONG_H_
+
+#include "jlong_md.h"
+
+#endif
diff --git a/ojluni/src/main/native/jlong_md.h b/ojluni/src/main/native/jlong_md.h
new file mode 100755
index 0000000..97b08e6
--- /dev/null
+++ b/ojluni/src/main/native/jlong_md.h
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#ifndef _SOLARIS_JLONG_MD_H_
+#define _SOLARIS_JLONG_MD_H_
+
+/* Make sure ptrdiff_t is defined */
+#include <stddef.h>
+#include <stdint.h>  /* For uintptr_t */
+
+#define jlong_high(a)   ((jint)((a)>>32))
+#define jlong_low(a)    ((jint)(a))
+#define jlong_add(a, b) ((a) + (b))
+#define jlong_and(a, b) ((a) & (b))
+#define jlong_div(a, b) ((a) / (b))
+#define jlong_mul(a, b) ((a) * (b))
+#define jlong_neg(a)    (-(a))
+#define jlong_not(a)    (~(a))
+#define jlong_or(a, b)  ((a) | (b))
+#define jlong_shl(a, n) ((a) << (n))
+#define jlong_shr(a, n) ((a) >> (n))
+#define jlong_sub(a, b) ((a) - (b))
+#define jlong_xor(a, b) ((a) ^ (b))
+#define jlong_rem(a,b)  ((a) % (b))
+
+/* comparison operators */
+#define jlong_ltz(ll)   ((ll)<0)
+#define jlong_gez(ll)   ((ll)>=0)
+#define jlong_gtz(ll)   ((ll)>0)
+#define jlong_eqz(a)    ((a) == 0)
+#define jlong_eq(a, b)  ((a) == (b))
+#define jlong_ne(a,b)   ((a) != (b))
+#define jlong_ge(a,b)   ((a) >= (b))
+#define jlong_le(a,b)   ((a) <= (b))
+#define jlong_lt(a,b)   ((a) < (b))
+#define jlong_gt(a,b)   ((a) > (b))
+
+#define jlong_zero      ((jlong) 0)
+#define jlong_one       ((jlong) 1)
+#define jlong_minus_one ((jlong) -1)
+
+/* For static variables initialized to zero */
+#define jlong_zero_init  ((jlong) 0L)
+
+#ifdef _LP64
+#define jlong_to_ptr(a) ((void*)(a))
+#define ptr_to_jlong(a) ((jlong)(a))
+#else
+#define jlong_to_ptr(a) ((void*)(int)(a))
+#define ptr_to_jlong(a) ((jlong)(int)(a))
+#endif
+
+#define jint_to_jlong(a)        ((jlong)(a))
+#define jlong_to_jint(a)        ((jint)(a))
+
+/* Useful on machines where jlong and jdouble have different endianness. */
+#define jlong_to_jdouble_bits(a)
+#define jdouble_to_jlong_bits(a)
+
+#define jlong_to_int(a)     ((int)(a))
+#define int_to_jlong(a)     ((jlong)(a))
+#define jlong_to_uint(a)    ((unsigned int)(a))
+#define uint_to_jlong(a)    ((jlong)(a))
+#define jlong_to_ptrdiff(a) ((ptrdiff_t)(a))
+#define ptrdiff_to_jlong(a) ((jlong)(a))
+#define jlong_to_size(a)    ((size_t)(a))
+#define size_to_jlong(a)    ((jlong)(a))
+#define long_to_jlong(a)    ((jlong)(a))
+
+#endif /* !_SOLARIS_JLONG_MD_H_ */
diff --git a/ojluni/src/main/native/jni_util.c b/ojluni/src/main/native/jni_util.c
new file mode 100755
index 0000000..3ef707f
--- /dev/null
+++ b/ojluni/src/main/native/jni_util.c
@@ -0,0 +1,1322 @@
+/*
+ * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "jvm.h"
+#include "jni.h"
+#include "jni_util.h"
+
+/* Due to a bug in the win32 C runtime library strings
+ * such as "z:" need to be appended with a "." so we
+ * must allocate at least 4 bytes to allow room for
+ * this expansion. See 4235353 for details.
+ */
+#define MALLOC_MIN4(len) ((char *)malloc((len) + 1 < 4 ? 4 : (len) + 1))
+
+/**
+ * Throw a Java exception by name. Similar to SignalError.
+ */
+JNIEXPORT void JNICALL
+JNU_ThrowByName(JNIEnv *env, const char *name, const char *msg)
+{
+    jclass cls = (*env)->FindClass(env, name);
+
+    if (cls != 0) /* Otherwise an exception has already been thrown */
+        (*env)->ThrowNew(env, cls, msg);
+}
+
+/* JNU_Throw common exceptions */
+
+JNIEXPORT void JNICALL
+JNU_ThrowNullPointerException(JNIEnv *env, const char *msg)
+{
+    JNU_ThrowByName(env, "java/lang/NullPointerException", msg);
+}
+
+JNIEXPORT void JNICALL
+JNU_ThrowArrayIndexOutOfBoundsException(JNIEnv *env, const char *msg)
+{
+    JNU_ThrowByName(env, "java/lang/ArrayIndexOutOfBoundsException", msg);
+}
+
+JNIEXPORT void JNICALL
+JNU_ThrowOutOfMemoryError(JNIEnv *env, const char *msg)
+{
+    JNU_ThrowByName(env, "java/lang/OutOfMemoryError", msg);
+}
+
+JNIEXPORT void JNICALL
+JNU_ThrowIllegalArgumentException(JNIEnv *env, const char *msg)
+{
+    JNU_ThrowByName(env, "java/lang/IllegalArgumentException", msg);
+}
+
+JNIEXPORT void JNICALL
+JNU_ThrowIllegalAccessError(JNIEnv *env, const char *msg)
+{
+    JNU_ThrowByName(env, "java/lang/IllegalAccessError", msg);
+}
+
+JNIEXPORT void JNICALL
+JNU_ThrowIllegalAccessException(JNIEnv *env, const char *msg)
+{
+    JNU_ThrowByName(env, "java/lang/IllegalAccessException", msg);
+}
+
+JNIEXPORT void JNICALL
+JNU_ThrowInternalError(JNIEnv *env, const char *msg)
+{
+    JNU_ThrowByName(env, "java/lang/InternalError", msg);
+}
+
+JNIEXPORT void JNICALL
+JNU_ThrowNoSuchFieldException(JNIEnv *env, const char *msg)
+{
+    JNU_ThrowByName(env, "java/lang/NoSuchFieldException", msg);
+}
+
+JNIEXPORT void JNICALL
+JNU_ThrowNoSuchMethodException(JNIEnv *env, const char *msg)
+{
+    JNU_ThrowByName(env, "java/lang/NoSuchMethodException", msg);
+}
+
+JNIEXPORT void JNICALL
+JNU_ThrowClassNotFoundException(JNIEnv *env, const char *msg)
+{
+    JNU_ThrowByName(env, "java/lang/ClassNotFoundException", msg);
+}
+
+JNIEXPORT void JNICALL
+JNU_ThrowNumberFormatException(JNIEnv *env, const char *msg)
+{
+    JNU_ThrowByName(env, "java/lang/NumberFormatException", msg);
+}
+
+JNIEXPORT void JNICALL
+JNU_ThrowIOException(JNIEnv *env, const char *msg)
+{
+    JNU_ThrowByName(env, "java/io/IOException", msg);
+}
+
+JNIEXPORT void JNICALL
+JNU_ThrowNoSuchFieldError(JNIEnv *env, const char *msg)
+{
+    JNU_ThrowByName(env, "java/lang/NoSuchFieldError", msg);
+}
+
+JNIEXPORT void JNICALL
+JNU_ThrowNoSuchMethodError(JNIEnv *env, const char *msg)
+{
+    JNU_ThrowByName(env, "java/lang/NoSuchMethodError", msg);
+}
+
+JNIEXPORT void JNICALL
+JNU_ThrowStringIndexOutOfBoundsException(JNIEnv *env, const char *msg)
+{
+    JNU_ThrowByName(env, "java/lang/StringIndexOutOfBoundsException", msg);
+}
+
+JNIEXPORT void JNICALL
+JNU_ThrowInstantiationException(JNIEnv *env, const char *msg)
+{
+    JNU_ThrowByName(env, "java/lang/InstantiationException", msg);
+}
+
+
+/* Throw an exception by name, using the string returned by
+ * JVM_LastErrorString for the detail string.  If the last-error
+ * string is NULL, use the given default detail string.
+ */
+JNIEXPORT void JNICALL
+JNU_ThrowByNameWithLastError(JNIEnv *env, const char *name,
+                             const char *defaultDetail)
+{
+    char buf[256];
+    int n = JVM_GetLastErrorString(buf, sizeof(buf));
+
+    if (n > 0) {
+        jstring s = JNU_NewStringPlatform(env, buf);
+        if (s != NULL) {
+            jobject x = JNU_NewObjectByName(env, name,
+                                            "(Ljava/lang/String;)V", s);
+            if (x != NULL) {
+                (*env)->Throw(env, x);
+            }
+        }
+    }
+    if (!(*env)->ExceptionOccurred(env)) {
+        JNU_ThrowByName(env, name, defaultDetail);
+    }
+}
+
+/* Throw an IOException, using the last-error string for the detail
+ * string.  If the last-error string is NULL, use the given default
+ * detail string.
+ */
+JNIEXPORT void JNICALL
+JNU_ThrowIOExceptionWithLastError(JNIEnv *env, const char *defaultDetail)
+{
+    JNU_ThrowByNameWithLastError(env, "java/io/IOException", defaultDetail);
+}
+
+
+JNIEXPORT jvalue JNICALL
+JNU_CallStaticMethodByName(JNIEnv *env,
+                           jboolean *hasException,
+                           const char *class_name,
+                           const char *name,
+                           const char *signature,
+                           ...)
+{
+    jclass clazz;
+    jmethodID mid;
+    va_list args;
+    jvalue result;
+    const char *p = signature;
+
+    /* find out the return type */
+    while (*p && *p != ')')
+        p++;
+    p++;
+
+    result.i = 0;
+
+    if ((*env)->EnsureLocalCapacity(env, 3) < 0)
+        goto done2;
+
+    clazz = (*env)->FindClass(env, class_name);
+    if (clazz == 0)
+        goto done2;
+    mid = (*env)->GetStaticMethodID(env, clazz, name, signature);
+    if (mid == 0)
+        goto done1;
+    va_start(args, signature);
+    switch (*p) {
+    case 'V':
+        (*env)->CallStaticVoidMethodV(env, clazz, mid, args);
+        break;
+    case '[':
+    case 'L':
+        result.l = (*env)->CallStaticObjectMethodV(env, clazz, mid, args);
+        break;
+    case 'Z':
+        result.z = (*env)->CallStaticBooleanMethodV(env, clazz, mid, args);
+        break;
+    case 'B':
+        result.b = (*env)->CallStaticByteMethodV(env, clazz, mid, args);
+        break;
+    case 'C':
+        result.c = (*env)->CallStaticCharMethodV(env, clazz, mid, args);
+        break;
+    case 'S':
+        result.s = (*env)->CallStaticShortMethodV(env, clazz, mid, args);
+        break;
+    case 'I':
+        result.i = (*env)->CallStaticIntMethodV(env, clazz, mid, args);
+        break;
+    case 'J':
+        result.j = (*env)->CallStaticLongMethodV(env, clazz, mid, args);
+        break;
+    case 'F':
+        result.f = (*env)->CallStaticFloatMethodV(env, clazz, mid, args);
+        break;
+    case 'D':
+        result.d = (*env)->CallStaticDoubleMethodV(env, clazz, mid, args);
+        break;
+    default:
+        (*env)->FatalError(env, "JNU_CallStaticMethodByName: illegal signature");
+    }
+    va_end(args);
+
+ done1:
+    (*env)->DeleteLocalRef(env, clazz);
+ done2:
+    if (hasException) {
+        *hasException = (*env)->ExceptionCheck(env);
+    }
+    return result;
+}
+
+JNIEXPORT jvalue JNICALL
+JNU_CallMethodByName(JNIEnv *env,
+                     jboolean *hasException,
+                     jobject obj,
+                     const char *name,
+                     const char *signature,
+                     ...)
+{
+    jvalue result;
+    va_list args;
+
+    va_start(args, signature);
+    result = JNU_CallMethodByNameV(env, hasException, obj, name, signature,
+                                   args);
+    va_end(args);
+
+    return result;
+}
+
+
+JNIEXPORT jvalue JNICALL
+JNU_CallMethodByNameV(JNIEnv *env,
+                      jboolean *hasException,
+                      jobject obj,
+                      const char *name,
+                      const char *signature,
+                      va_list args)
+{
+    jclass clazz;
+    jmethodID mid;
+    jvalue result;
+    const char *p = signature;
+
+    /* find out the return type */
+    while (*p && *p != ')')
+        p++;
+    p++;
+
+    result.i = 0;
+
+    if ((*env)->EnsureLocalCapacity(env, 3) < 0)
+        goto done2;
+
+    clazz = (*env)->GetObjectClass(env, obj);
+    mid = (*env)->GetMethodID(env, clazz, name, signature);
+    if (mid == 0)
+        goto done1;
+
+    switch (*p) {
+    case 'V':
+        (*env)->CallVoidMethodV(env, obj, mid, args);
+        break;
+    case '[':
+    case 'L':
+        result.l = (*env)->CallObjectMethodV(env, obj, mid, args);
+        break;
+    case 'Z':
+        result.z = (*env)->CallBooleanMethodV(env, obj, mid, args);
+        break;
+    case 'B':
+        result.b = (*env)->CallByteMethodV(env, obj, mid, args);
+        break;
+    case 'C':
+        result.c = (*env)->CallCharMethodV(env, obj, mid, args);
+        break;
+    case 'S':
+        result.s = (*env)->CallShortMethodV(env, obj, mid, args);
+        break;
+    case 'I':
+        result.i = (*env)->CallIntMethodV(env, obj, mid, args);
+        break;
+    case 'J':
+        result.j = (*env)->CallLongMethodV(env, obj, mid, args);
+        break;
+    case 'F':
+        result.f = (*env)->CallFloatMethodV(env, obj, mid, args);
+        break;
+    case 'D':
+        result.d = (*env)->CallDoubleMethodV(env, obj, mid, args);
+        break;
+    default:
+        (*env)->FatalError(env, "JNU_CallMethodByNameV: illegal signature");
+    }
+ done1:
+    (*env)->DeleteLocalRef(env, clazz);
+ done2:
+    if (hasException) {
+        *hasException = (*env)->ExceptionCheck(env);
+    }
+    return result;
+}
+
+JNIEXPORT jobject JNICALL
+JNU_NewObjectByName(JNIEnv *env, const char *class_name,
+                    const char *constructor_sig, ...)
+{
+    jobject obj = NULL;
+
+    jclass cls = 0;
+    jmethodID cls_initMID;
+    va_list args;
+
+    if ((*env)->EnsureLocalCapacity(env, 2) < 0)
+        goto done;
+
+    cls = (*env)->FindClass(env, class_name);
+    if (cls == 0) {
+        goto done;
+    }
+    cls_initMID  = (*env)->GetMethodID(env, cls,
+                                       "<init>", constructor_sig);
+    if (cls_initMID == NULL) {
+        goto done;
+    }
+    va_start(args, constructor_sig);
+    obj = (*env)->NewObjectV(env, cls, cls_initMID, args);
+    va_end(args);
+
+ done:
+    (*env)->DeleteLocalRef(env, cls);
+    return obj;
+}
+
+/* Optimized for char set ISO_8559_1 */
+static jstring
+newString8859_1(JNIEnv *env, const char *str)
+{
+    int len = (int)strlen(str);
+    jchar buf[512];
+    jchar *str1;
+    jstring result;
+    int i;
+
+    if (len > 512) {
+        str1 = (jchar *)malloc(len * sizeof(jchar));
+        if (str1 == 0) {
+            JNU_ThrowOutOfMemoryError(env, 0);
+            return 0;
+        }
+    } else
+        str1 = buf;
+
+    for (i=0;i<len;i++)
+        str1[i] = (unsigned char)str[i];
+    result = (*env)->NewString(env, str1, len);
+    if (str1 != buf)
+        free(str1);
+    return result;
+}
+
+static const char*
+getString8859_1Chars(JNIEnv *env, jstring jstr)
+{
+    int i;
+    char *result;
+    jint len = (*env)->GetStringLength(env, jstr);
+    const jchar *str = (*env)->GetStringCritical(env, jstr, 0);
+    if (str == 0) {
+        return 0;
+    }
+
+    result = MALLOC_MIN4(len);
+    if (result == 0) {
+        (*env)->ReleaseStringCritical(env, jstr, str);
+        JNU_ThrowOutOfMemoryError(env, 0);
+        return 0;
+    }
+
+    for (i=0; i<len; i++) {
+        jchar unicode = str[i];
+        if (unicode <= 0x00ff)
+            result[i] = (char)unicode;
+        else
+            result[i] = '?';
+    }
+
+    result[len] = 0;
+    (*env)->ReleaseStringCritical(env, jstr, str);
+    return result;
+}
+
+
+/* Optimized for char set ISO646-US (us-ascii) */
+static jstring
+newString646_US(JNIEnv *env, const char *str)
+{
+    int len = strlen(str);
+    jchar buf[512];
+    jchar *str1;
+    jstring result;
+    int i;
+
+    if (len > 512) {
+        str1 = (jchar *)malloc(len * sizeof(jchar));
+        if (str1 == 0) {
+            JNU_ThrowOutOfMemoryError(env, 0);
+            return 0;
+        }
+    } else
+        str1 = buf;
+
+    for (i=0; i<len; i++) {
+        unsigned char c = (unsigned char)str[i];
+        if (c <= 0x7f)
+            str1[i] = c;
+        else
+            str1[i] = '?';
+    }
+
+    result = (*env)->NewString(env, str1, len);
+    if (str1 != buf)
+        free(str1);
+    return result;
+}
+
+static const char*
+getString646_USChars(JNIEnv *env, jstring jstr)
+{
+    int i;
+    char *result;
+    jint len = (*env)->GetStringLength(env, jstr);
+    const jchar *str = (*env)->GetStringCritical(env, jstr, 0);
+    if (str == 0) {
+        return 0;
+    }
+
+    result = MALLOC_MIN4(len);
+    if (result == 0) {
+        (*env)->ReleaseStringCritical(env, jstr, str);
+        JNU_ThrowOutOfMemoryError(env, 0);
+        return 0;
+    }
+
+    for (i=0; i<len; i++) {
+        jchar unicode = str[i];
+        if (unicode <= 0x007f )
+            result[i] = (char)unicode;
+        else
+            result[i] = '?';
+    }
+
+    result[len] = 0;
+    (*env)->ReleaseStringCritical(env, jstr, str);
+    return result;
+}
+
+/* enumeration of c1 row from Cp1252 */
+static int cp1252c1chars[32] = {
+    0x20AC,0xFFFD,0x201A,0x0192,0x201E,0x2026,0x2020,0x2021,
+    0x02C6,0x2030,0x0160,0x2039,0x0152,0xFFFD,0x017D,0xFFFD,
+    0xFFFD,0x2018,0x2019,0x201C,0x201D,0x2022,0x2013,0x2014,
+    0x02Dc,0x2122,0x0161,0x203A,0x0153,0xFFFD,0x017E,0x0178
+};
+
+/* Optimized for char set Cp1252 */
+static jstring
+newStringCp1252(JNIEnv *env, const char *str)
+{
+    int len = (int) strlen(str);
+    jchar buf[512];
+    jchar *str1;
+    jstring result;
+    int i;
+    if (len > 512) {
+        str1 = (jchar *)malloc(len * sizeof(jchar));
+        if (str1 == 0) {
+            JNU_ThrowOutOfMemoryError(env, 0);
+            return 0;
+        }
+    } else
+        str1 = buf;
+
+    for (i=0; i<len; i++) {
+        unsigned char c = (unsigned char)str[i];
+        if ((c >= 0x80) && (c <= 0x9f))
+            str1[i] = cp1252c1chars[c-128];
+        else
+            str1[i] = c;
+    }
+
+    result = (*env)->NewString(env, str1, len);
+    if (str1 != buf)
+        free(str1);
+    return result;
+}
+
+static const char*
+getStringCp1252Chars(JNIEnv *env, jstring jstr)
+{
+    int i;
+    char *result;
+    jint len = (*env)->GetStringLength(env, jstr);
+    const jchar *str = (*env)->GetStringCritical(env, jstr, 0);
+    if (str == 0) {
+        return 0;
+    }
+
+    result = MALLOC_MIN4(len);
+    if (result == 0) {
+        (*env)->ReleaseStringCritical(env, jstr, str);
+        JNU_ThrowOutOfMemoryError(env, 0);
+        return 0;
+    }
+
+    for (i=0; i<len; i++) {
+        jchar c = str[i];
+        if (c < 256)
+            result[i] = (char)c;
+        else switch(c) {
+            case 0x20AC: result[i] = (char)0x80; break;
+            case 0x201A: result[i] = (char)0x82; break;
+            case 0x0192: result[i] = (char)0x83; break;
+            case 0x201E: result[i] = (char)0x84; break;
+            case 0x2026: result[i] = (char)0x85; break;
+            case 0x2020: result[i] = (char)0x86; break;
+            case 0x2021: result[i] = (char)0x87; break;
+            case 0x02C6: result[i] = (char)0x88; break;
+            case 0x2030: result[i] = (char)0x89; break;
+            case 0x0160: result[i] = (char)0x8A; break;
+            case 0x2039: result[i] = (char)0x8B; break;
+            case 0x0152: result[i] = (char)0x8C; break;
+            case 0x017D: result[i] = (char)0x8E; break;
+            case 0x2018: result[i] = (char)0x91; break;
+            case 0x2019: result[i] = (char)0x92; break;
+            case 0x201C: result[i] = (char)0x93; break;
+            case 0x201D: result[i] = (char)0x94; break;
+            case 0x2022: result[i] = (char)0x95; break;
+            case 0x2013: result[i] = (char)0x96; break;
+            case 0x2014: result[i] = (char)0x97; break;
+            case 0x02DC: result[i] = (char)0x98; break;
+            case 0x2122: result[i] = (char)0x99; break;
+            case 0x0161: result[i] = (char)0x9A; break;
+            case 0x203A: result[i] = (char)0x9B; break;
+            case 0x0153: result[i] = (char)0x9C; break;
+            case 0x017E: result[i] = (char)0x9E; break;
+            case 0x0178: result[i] = (char)0x9F; break;
+            default:     result[i] = '?';  break;
+        }
+    }
+
+    result[len] = 0;
+    (*env)->ReleaseStringCritical(env, jstr, str);
+    return result;
+}
+
+static int fastEncoding = NO_ENCODING_YET;
+static jstring jnuEncoding = NULL;
+
+/* Cached method IDs */
+static jmethodID String_init_ID;        /* String(byte[], enc) */
+static jmethodID String_getBytes_ID;    /* String.getBytes(enc) */
+
+int getFastEncoding() {
+    return fastEncoding;
+}
+
+/* Initialize the fast encoding.  If the "sun.jnu.encoding" property
+ * has not yet been set, we leave fastEncoding == NO_ENCODING_YET.
+ */
+void
+initializeEncoding(JNIEnv *env)
+{
+    jstring propname = 0;
+    jstring enc = 0;
+
+    if ((*env)->EnsureLocalCapacity(env, 3) < 0)
+        return;
+
+    propname = (*env)->NewStringUTF(env, "sun.jnu.encoding");
+    if (propname) {
+        jboolean exc;
+        enc = JNU_CallStaticMethodByName
+                       (env,
+                        &exc,
+                        "java/lang/System",
+                        "getProperty",
+                        "(Ljava/lang/String;)Ljava/lang/String;",
+                        propname).l;
+        if (!exc) {
+            if (enc) {
+                const char* encname = (*env)->GetStringUTFChars(env, enc, 0);
+                if (encname) {
+           /*
+            * On Solaris with nl_langinfo() called in GetJavaProperties():
+            *
+            *   locale undefined -> NULL -> hardcoded default
+            *   "C" locale       -> "" -> hardcoded default     (on 2.6)
+            *   "C" locale       -> "ISO646-US"                 (on Sol 7/8)
+            *   "en_US" locale -> "ISO8859-1"
+            *   "en_GB" locale -> "ISO8859-1"                   (on Sol 7/8)
+            *   "en_UK" locale -> "ISO8859-1"                   (on 2.6)
+            */
+                    if ((strcmp(encname, "8859_1") == 0) ||
+                        (strcmp(encname, "ISO8859-1") == 0) ||
+                        (strcmp(encname, "ISO8859_1") == 0))
+                        fastEncoding = FAST_8859_1;
+                    else if (strcmp(encname, "ISO646-US") == 0)
+                        fastEncoding = FAST_646_US;
+                    else if (strcmp(encname, "Cp1252") == 0 ||
+                             /* This is a temporary fix until we move */
+                             /* to wide character versions of all Windows */
+                             /* calls. */
+                             strcmp(encname, "utf-16le") == 0)
+                        fastEncoding = FAST_CP1252;
+                    else {
+                        fastEncoding = NO_FAST_ENCODING;
+                        jnuEncoding = (jstring)(*env)->NewGlobalRef(env, enc);
+                    }
+                    (*env)->ReleaseStringUTFChars(env, enc, encname);
+                }
+            }
+        } else {
+            (*env)->ExceptionClear(env);
+        }
+    } else {
+        (*env)->ExceptionClear(env);
+    }
+    (*env)->DeleteLocalRef(env, propname);
+    (*env)->DeleteLocalRef(env, enc);
+
+    /* Initialize method-id cache */
+    String_getBytes_ID = (*env)->GetMethodID(env, JNU_ClassString(env),
+                                             "getBytes", "(Ljava/lang/String;)[B");
+    String_init_ID = (*env)->GetMethodID(env, JNU_ClassString(env),
+                                         "<init>", "([BLjava/lang/String;)V");
+}
+
+static jboolean isJNUEncodingSupported = JNI_FALSE;
+static jboolean jnuEncodingSupported(JNIEnv *env) {
+    jboolean exe;
+    if (isJNUEncodingSupported == JNI_TRUE) {
+        return JNI_TRUE;
+    }
+    isJNUEncodingSupported = (jboolean) JNU_CallStaticMethodByName (
+                                    env, &exe,
+                                    "java/nio/charset/Charset",
+                                    "isSupported",
+                                    "(Ljava/lang/String;)Z",
+                                    jnuEncoding).z;
+    return isJNUEncodingSupported;
+}
+
+
+JNIEXPORT jstring
+NewStringPlatform(JNIEnv *env, const char *str)
+{
+    return JNU_NewStringPlatform(env, str);
+}
+
+JNIEXPORT jstring JNICALL
+JNU_NewStringPlatform(JNIEnv *env, const char *str)
+{
+    jstring result;
+    result = nativeNewStringPlatform(env, str);
+    if (result == NULL) {
+        jbyteArray hab = 0;
+        int len;
+
+        if (fastEncoding == NO_ENCODING_YET)
+            initializeEncoding(env);
+
+        if ((fastEncoding == FAST_8859_1) || (fastEncoding == NO_ENCODING_YET))
+            return newString8859_1(env, str);
+        if (fastEncoding == FAST_646_US)
+            return newString646_US(env, str);
+        if (fastEncoding == FAST_CP1252)
+            return newStringCp1252(env, str);
+
+        if ((*env)->EnsureLocalCapacity(env, 2) < 0)
+            return NULL;
+
+        len = (int)strlen(str);
+        hab = (*env)->NewByteArray(env, len);
+        if (hab != 0) {
+            (*env)->SetByteArrayRegion(env, hab, 0, len, (jbyte *)str);
+            if (jnuEncodingSupported(env)) {
+                result = (*env)->NewObject(env, JNU_ClassString(env),
+                                           String_init_ID, hab, jnuEncoding);
+            } else {
+                /*If the encoding specified in sun.jnu.encoding is not endorsed
+                  by "Charset.isSupported" we have to fall back to use String(byte[])
+                  explicitly here without specifying the encoding name, in which the
+                  StringCoding class will pickup the iso-8859-1 as the fallback
+                  converter for us.
+                 */
+                jmethodID mid = (*env)->GetMethodID(env, JNU_ClassString(env),
+                                                    "<init>", "([B)V");
+                result = (*env)->NewObject(env, JNU_ClassString(env), mid, hab);
+            }
+            (*env)->DeleteLocalRef(env, hab);
+            return result;
+        }
+    }
+    return NULL;
+}
+
+JNIEXPORT const char *
+GetStringPlatformChars(JNIEnv *env, jstring jstr, jboolean *isCopy)
+{
+    return JNU_GetStringPlatformChars(env, jstr, isCopy);
+}
+
+JNIEXPORT const char * JNICALL
+JNU_GetStringPlatformChars(JNIEnv *env, jstring jstr, jboolean *isCopy)
+{
+    char *result = nativeGetStringPlatformChars(env, jstr, isCopy);
+    if (result == NULL) {
+
+        jbyteArray hab = 0;
+
+        if (isCopy)
+            *isCopy = JNI_TRUE;
+
+        if (fastEncoding == NO_ENCODING_YET)
+            initializeEncoding(env);
+
+        if ((fastEncoding == FAST_8859_1) || (fastEncoding == NO_ENCODING_YET))
+            return getString8859_1Chars(env, jstr);
+        if (fastEncoding == FAST_646_US)
+            return getString646_USChars(env, jstr);
+        if (fastEncoding == FAST_CP1252)
+            return getStringCp1252Chars(env, jstr);
+
+        if ((*env)->EnsureLocalCapacity(env, 2) < 0)
+            return 0;
+
+        if (jnuEncodingSupported(env)) {
+            hab = (*env)->CallObjectMethod(env, jstr, String_getBytes_ID, jnuEncoding);
+        } else {
+            jmethodID mid = (*env)->GetMethodID(env, JNU_ClassString(env),
+                                                "getBytes", "()[B");
+            hab = (*env)->CallObjectMethod(env, jstr, mid);
+        }
+
+        if (!(*env)->ExceptionCheck(env)) {
+            jint len = (*env)->GetArrayLength(env, hab);
+            result = MALLOC_MIN4(len);
+            if (result == 0) {
+                JNU_ThrowOutOfMemoryError(env, 0);
+                (*env)->DeleteLocalRef(env, hab);
+                return 0;
+            }
+            (*env)->GetByteArrayRegion(env, hab, 0, len, (jbyte *)result);
+            result[len] = 0; /* NULL-terminate */
+        }
+
+        (*env)->DeleteLocalRef(env, hab);
+    }
+    return result;
+}
+
+JNIEXPORT void JNICALL
+JNU_ReleaseStringPlatformChars(JNIEnv *env, jstring jstr, const char *str)
+{
+    free((void *)str);
+}
+
+/*
+ * Export the platform dependent path canonicalization so that
+ * VM can find it when loading system classes.
+ *
+ */
+extern int canonicalize(char *path, const char *out, int len);
+
+JNIEXPORT int
+Canonicalize(JNIEnv *env, char *orig, char *out, int len)
+{
+    /* canonicalize an already natived path */
+    return canonicalize(orig, out, len);
+}
+
+JNIEXPORT jclass JNICALL
+JNU_ClassString(JNIEnv *env)
+{
+    static jclass cls = 0;
+    if (cls == 0) {
+        jclass c;
+        if ((*env)->EnsureLocalCapacity(env, 1) < 0)
+            return 0;
+        c = (*env)->FindClass(env, "java/lang/String");
+        cls = (*env)->NewGlobalRef(env, c);
+        (*env)->DeleteLocalRef(env, c);
+    }
+    return cls;
+}
+
+JNIEXPORT jclass JNICALL
+JNU_ClassClass(JNIEnv *env)
+{
+    static jclass cls = 0;
+    if (cls == 0) {
+        jclass c;
+        if ((*env)->EnsureLocalCapacity(env, 1) < 0)
+            return 0;
+        c = (*env)->FindClass(env, "java/lang/Class");
+        cls = (*env)->NewGlobalRef(env, c);
+        (*env)->DeleteLocalRef(env, c);
+    }
+    return cls;
+}
+
+JNIEXPORT jclass JNICALL
+JNU_ClassObject(JNIEnv *env)
+{
+    static jclass cls = 0;
+    if (cls == 0) {
+        jclass c;
+        if ((*env)->EnsureLocalCapacity(env, 1) < 0)
+            return 0;
+        c = (*env)->FindClass(env, "java/lang/Object");
+        cls = (*env)->NewGlobalRef(env, c);
+        (*env)->DeleteLocalRef(env, c);
+    }
+    return cls;
+}
+
+JNIEXPORT jclass JNICALL
+JNU_ClassThrowable(JNIEnv *env)
+{
+    static jclass cls = 0;
+    if (cls == 0) {
+        jclass c;
+        if ((*env)->EnsureLocalCapacity(env, 1) < 0)
+            return 0;
+        c = (*env)->FindClass(env, "java/lang/Throwable");
+        cls = (*env)->NewGlobalRef(env, c);
+        (*env)->DeleteLocalRef(env, c);
+    }
+    return cls;
+}
+
+JNIEXPORT jint JNICALL
+JNU_CopyObjectArray(JNIEnv *env, jobjectArray dst, jobjectArray src,
+                         jint count)
+{
+    int i;
+    if ((*env)->EnsureLocalCapacity(env, 1) < 0)
+        return -1;
+    for (i=0; i<count; i++) {
+        jstring p = (*env)->GetObjectArrayElement(env, src, i);
+        (*env)->SetObjectArrayElement(env, dst, i, p);
+        (*env)->DeleteLocalRef(env, p);
+    }
+    return 0;
+}
+
+JNIEXPORT void * JNICALL
+JNU_GetEnv(JavaVM *vm, jint version)
+{
+    void *env;
+    (*vm)->GetEnv(vm, &env, version);
+    return env;
+}
+
+JNIEXPORT jint JNICALL
+JNU_IsInstanceOfByName(JNIEnv *env, jobject object, char* classname)
+{
+    jclass cls;
+    if ((*env)->EnsureLocalCapacity(env, 1) < 0)
+        return JNI_ERR;
+    cls = (*env)->FindClass(env, classname);
+    if (cls != NULL) {
+        jint result = (*env)->IsInstanceOf(env, object, cls);
+        (*env)->DeleteLocalRef(env, cls);
+        return result;
+    }
+    return JNI_ERR;
+}
+
+JNIEXPORT jboolean JNICALL
+JNU_Equals(JNIEnv *env, jobject object1, jobject object2)
+{
+    static jmethodID mid = NULL;
+    if (mid == NULL) {
+        mid = (*env)->GetMethodID(env, JNU_ClassObject(env), "equals",
+                                  "(Ljava/lang/Object;)Z");
+    }
+    return (*env)->CallBooleanMethod(env, object1, mid, object2);
+}
+
+
+/************************************************************************
+ * Thread calls
+ */
+
+static jmethodID Object_waitMID;
+static jmethodID Object_notifyMID;
+static jmethodID Object_notifyAllMID;
+
+JNIEXPORT void JNICALL
+JNU_MonitorWait(JNIEnv *env, jobject object, jlong timeout)
+{
+    if (object == NULL) {
+        JNU_ThrowNullPointerException(env, "JNU_MonitorWait argument");
+        return;
+    }
+    if (Object_waitMID == NULL) {
+        jclass cls = JNU_ClassObject(env);
+        if (cls == NULL) {
+            return;
+        }
+        Object_waitMID = (*env)->GetMethodID(env, cls, "wait", "(J)V");
+        if (Object_waitMID == NULL) {
+            return;
+        }
+    }
+    (*env)->CallVoidMethod(env, object, Object_waitMID, timeout);
+}
+
+JNIEXPORT void JNICALL
+JNU_Notify(JNIEnv *env, jobject object)
+{
+    if (object == NULL) {
+        JNU_ThrowNullPointerException(env, "JNU_Notify argument");
+        return;
+    }
+    if (Object_notifyMID == NULL) {
+        jclass cls = JNU_ClassObject(env);
+        if (cls == NULL) {
+            return;
+        }
+        Object_notifyMID = (*env)->GetMethodID(env, cls, "notify", "()V");
+        if (Object_notifyMID == NULL) {
+            return;
+        }
+    }
+    (*env)->CallVoidMethod(env, object, Object_notifyMID);
+}
+
+JNIEXPORT void JNICALL
+JNU_NotifyAll(JNIEnv *env, jobject object)
+{
+    if (object == NULL) {
+        JNU_ThrowNullPointerException(env, "JNU_NotifyAll argument");
+        return;
+    }
+    if (Object_notifyAllMID == NULL) {
+        jclass cls = JNU_ClassObject(env);
+        if (cls == NULL) {
+            return;
+        }
+        Object_notifyAllMID = (*env)->GetMethodID(env, cls,"notifyAll", "()V");
+        if (Object_notifyAllMID == NULL) {
+            return;
+        }
+    }
+    (*env)->CallVoidMethod(env, object, Object_notifyAllMID);
+}
+
+
+/************************************************************************
+ * Debugging utilities
+ */
+
+JNIEXPORT void JNICALL
+JNU_PrintString(JNIEnv *env, char *hdr, jstring string)
+{
+    if (string == NULL) {
+        fprintf(stderr, "%s: is NULL\n", hdr);
+    } else {
+        const char *stringPtr = JNU_GetStringPlatformChars(env, string, 0);
+        if (stringPtr == 0)
+            return;
+        fprintf(stderr, "%s: %s\n", hdr, stringPtr);
+        JNU_ReleaseStringPlatformChars(env, string, stringPtr);
+    }
+}
+
+JNIEXPORT void JNICALL
+JNU_PrintClass(JNIEnv *env, char* hdr, jobject object)
+{
+    if (object == NULL) {
+        fprintf(stderr, "%s: object is NULL\n", hdr);
+        return;
+    } else {
+        jclass cls = (*env)->GetObjectClass(env, object);
+        jstring clsName = JNU_ToString(env, cls);
+        JNU_PrintString(env, hdr, clsName);
+        (*env)->DeleteLocalRef(env, cls);
+        (*env)->DeleteLocalRef(env, clsName);
+    }
+}
+
+JNIEXPORT jstring JNICALL
+JNU_ToString(JNIEnv *env, jobject object)
+{
+    if (object == NULL) {
+        return (*env)->NewStringUTF(env, "NULL");
+    } else {
+        return (jstring)JNU_CallMethodByName(env,
+                                             NULL,
+                                             object,
+                                             "toString",
+                                             "()Ljava/lang/String;").l;
+    }
+}
+
+JNIEXPORT jvalue JNICALL
+JNU_GetFieldByName(JNIEnv *env,
+                   jboolean *hasException,
+                   jobject obj,
+                   const char *name,
+                   const char *signature)
+{
+    jclass cls;
+    jfieldID fid;
+    jvalue result;
+
+    result.i = 0;
+
+    if ((*env)->EnsureLocalCapacity(env, 3) < 0)
+        goto done2;
+
+    cls = (*env)->GetObjectClass(env, obj);
+    fid = (*env)->GetFieldID(env, cls, name, signature);
+    if (fid == 0)
+        goto done1;
+
+    switch (*signature) {
+    case '[':
+    case 'L':
+        result.l = (*env)->GetObjectField(env, obj, fid);
+        break;
+    case 'Z':
+        result.z = (*env)->GetBooleanField(env, obj, fid);
+        break;
+    case 'B':
+        result.b = (*env)->GetByteField(env, obj, fid);
+        break;
+    case 'C':
+        result.c = (*env)->GetCharField(env, obj, fid);
+        break;
+    case 'S':
+        result.s = (*env)->GetShortField(env, obj, fid);
+        break;
+    case 'I':
+        result.i = (*env)->GetIntField(env, obj, fid);
+        break;
+    case 'J':
+        result.j = (*env)->GetLongField(env, obj, fid);
+        break;
+    case 'F':
+        result.f = (*env)->GetFloatField(env, obj, fid);
+        break;
+    case 'D':
+        result.d = (*env)->GetDoubleField(env, obj, fid);
+        break;
+
+    default:
+        (*env)->FatalError(env, "JNU_GetFieldByName: illegal signature");
+    }
+
+ done1:
+    (*env)->DeleteLocalRef(env, cls);
+ done2:
+    if (hasException) {
+        *hasException = (*env)->ExceptionCheck(env);
+    }
+    return result;
+}
+
+JNIEXPORT void JNICALL
+JNU_SetFieldByName(JNIEnv *env,
+                   jboolean *hasException,
+                   jobject obj,
+                   const char *name,
+                   const char *signature,
+                   ...)
+{
+    jclass cls;
+    jfieldID fid;
+    va_list args;
+
+    if ((*env)->EnsureLocalCapacity(env, 3) < 0)
+        goto done2;
+
+    cls = (*env)->GetObjectClass(env, obj);
+    fid = (*env)->GetFieldID(env, cls, name, signature);
+    if (fid == 0)
+        goto done1;
+
+    va_start(args, signature);
+    switch (*signature) {
+    case '[':
+    case 'L':
+        (*env)->SetObjectField(env, obj, fid, va_arg(args, jobject));
+        break;
+    case 'Z':
+        (*env)->SetBooleanField(env, obj, fid, (jboolean)va_arg(args, int));
+        break;
+    case 'B':
+        (*env)->SetByteField(env, obj, fid, (jbyte)va_arg(args, int));
+        break;
+    case 'C':
+        (*env)->SetCharField(env, obj, fid, (jchar)va_arg(args, int));
+        break;
+    case 'S':
+        (*env)->SetShortField(env, obj, fid, (jshort)va_arg(args, int));
+        break;
+    case 'I':
+        (*env)->SetIntField(env, obj, fid, va_arg(args, jint));
+        break;
+    case 'J':
+        (*env)->SetLongField(env, obj, fid, va_arg(args, jlong));
+        break;
+    case 'F':
+        (*env)->SetFloatField(env, obj, fid, (jfloat)va_arg(args, jdouble));
+        break;
+    case 'D':
+        (*env)->SetDoubleField(env, obj, fid, va_arg(args, jdouble));
+        break;
+
+    default:
+        (*env)->FatalError(env, "JNU_SetFieldByName: illegal signature");
+    }
+    va_end(args);
+
+ done1:
+    (*env)->DeleteLocalRef(env, cls);
+ done2:
+    if (hasException) {
+        *hasException = (*env)->ExceptionCheck(env);
+    }
+}
+
+JNIEXPORT jvalue JNICALL
+JNU_GetStaticFieldByName(JNIEnv *env,
+                         jboolean *hasException,
+                         const char *classname,
+                         const char *name,
+                         const char *signature)
+{
+    jclass cls;
+    jfieldID fid;
+    jvalue result;
+
+    result.i = 0;
+
+    if ((*env)->EnsureLocalCapacity(env, 3) < 0)
+        goto done2;
+
+    cls = (*env)->FindClass(env, classname);
+    if (cls == 0)
+        goto done2;
+
+    fid = (*env)->GetStaticFieldID(env, cls, name, signature);
+    if (fid == 0)
+        goto done1;
+
+    switch (*signature) {
+    case '[':
+    case 'L':
+        result.l = (*env)->GetStaticObjectField(env, cls, fid);
+        break;
+    case 'Z':
+        result.z = (*env)->GetStaticBooleanField(env, cls, fid);
+        break;
+    case 'B':
+        result.b = (*env)->GetStaticByteField(env, cls, fid);
+        break;
+    case 'C':
+        result.c = (*env)->GetStaticCharField(env, cls, fid);
+        break;
+    case 'S':
+        result.s = (*env)->GetStaticShortField(env, cls, fid);
+        break;
+    case 'I':
+        result.i = (*env)->GetStaticIntField(env, cls, fid);
+        break;
+    case 'J':
+        result.j = (*env)->GetStaticLongField(env, cls, fid);
+        break;
+    case 'F':
+        result.f = (*env)->GetStaticFloatField(env, cls, fid);
+        break;
+    case 'D':
+        result.d = (*env)->GetStaticDoubleField(env, cls, fid);
+        break;
+
+    default:
+        (*env)->FatalError(env, "JNU_GetStaticFieldByName: illegal signature");
+    }
+
+ done1:
+    (*env)->DeleteLocalRef(env, cls);
+ done2:
+    if (hasException) {
+        *hasException = (*env)->ExceptionCheck(env);
+    }
+    return result;
+}
+
+JNIEXPORT void JNICALL
+JNU_SetStaticFieldByName(JNIEnv *env,
+                         jboolean *hasException,
+                         const char *classname,
+                         const char *name,
+                         const char *signature,
+                         ...)
+{
+    jclass cls;
+    jfieldID fid;
+    va_list args;
+
+    if ((*env)->EnsureLocalCapacity(env, 3) < 0)
+        goto done2;
+
+    cls = (*env)->FindClass(env, classname);
+    if (cls == 0)
+        goto done2;
+
+    fid = (*env)->GetStaticFieldID(env, cls, name, signature);
+    if (fid == 0)
+        goto done1;
+
+    va_start(args, signature);
+    switch (*signature) {
+    case '[':
+    case 'L':
+        (*env)->SetStaticObjectField(env, cls, fid, va_arg(args, jobject));
+        break;
+    case 'Z':
+        (*env)->SetStaticBooleanField(env, cls, fid, (jboolean)va_arg(args, int));
+        break;
+    case 'B':
+        (*env)->SetStaticByteField(env, cls, fid, (jbyte)va_arg(args, int));
+        break;
+    case 'C':
+        (*env)->SetStaticCharField(env, cls, fid, (jchar)va_arg(args, int));
+        break;
+    case 'S':
+        (*env)->SetStaticShortField(env, cls, fid, (jshort)va_arg(args, int));
+        break;
+    case 'I':
+        (*env)->SetStaticIntField(env, cls, fid, va_arg(args, jint));
+        break;
+    case 'J':
+        (*env)->SetStaticLongField(env, cls, fid, va_arg(args, jlong));
+        break;
+    case 'F':
+        (*env)->SetStaticFloatField(env, cls, fid, (jfloat)va_arg(args, jdouble));
+        break;
+    case 'D':
+        (*env)->SetStaticDoubleField(env, cls, fid, va_arg(args, jdouble));
+        break;
+
+    default:
+        (*env)->FatalError(env, "JNU_SetStaticFieldByName: illegal signature");
+    }
+    va_end(args);
+
+ done1:
+    (*env)->DeleteLocalRef(env, cls);
+ done2:
+    if (hasException) {
+        *hasException = (*env)->ExceptionCheck(env);
+    }
+}
diff --git a/ojluni/src/main/native/jni_util.h b/ojluni/src/main/native/jni_util.h
new file mode 100755
index 0000000..55dd0fa
--- /dev/null
+++ b/ojluni/src/main/native/jni_util.h
@@ -0,0 +1,347 @@
+/*
+ * Copyright (c) 1997, 2004, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#ifndef JNI_UTIL_H
+#define JNI_UTIL_H
+
+#include "jni.h"
+#include "jlong.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * This file contains utility functions that can be implemented in pure JNI.
+ *
+ * Caution: Callers of functions declared in this file should be
+ * particularly aware of the fact that these functions are convenience
+ * functions, and as such are often compound operations, each one of
+ * which may throw an exception. Therefore, the functions this file
+ * will often return silently if an exception has occured, and callers
+ * must check for exception themselves.
+ */
+
+/* Throw a Java exception by name. Similar to SignalError. */
+JNIEXPORT void JNICALL
+JNU_ThrowByName(JNIEnv *env, const char *name, const char *msg);
+
+/* Throw common exceptions */
+JNIEXPORT void JNICALL
+JNU_ThrowNullPointerException(JNIEnv *env, const char *msg);
+
+JNIEXPORT void JNICALL
+JNU_ThrowArrayIndexOutOfBoundsException(JNIEnv *env, const char *msg);
+
+JNIEXPORT void JNICALL
+JNU_ThrowOutOfMemoryError(JNIEnv *env, const char *msg);
+
+JNIEXPORT void JNICALL
+JNU_ThrowIllegalArgumentException(JNIEnv *env, const char *msg);
+
+JNIEXPORT void JNICALL
+JNU_ThrowIllegalAccessError(JNIEnv *env, const char *msg);
+
+JNIEXPORT void JNICALL
+JNU_ThrowIllegalAccessException(JNIEnv *env, const char *msg);
+
+JNIEXPORT void JNICALL
+JNU_ThrowInternalError(JNIEnv *env, const char *msg);
+
+JNIEXPORT void JNICALL
+JNU_ThrowIOException(JNIEnv *env, const char *msg);
+
+JNIEXPORT void JNICALL
+JNU_ThrowNoSuchFieldException(JNIEnv *env, const char *msg);
+
+JNIEXPORT void JNICALL
+JNU_ThrowNoSuchMethodException(JNIEnv *env, const char *msg);
+
+JNIEXPORT void JNICALL
+JNU_ThrowClassNotFoundException(JNIEnv *env, const char *msg);
+
+JNIEXPORT void JNICALL
+JNU_ThrowNumberFormatException(JNIEnv *env, const char *msg);
+
+JNIEXPORT void JNICALL
+JNU_ThrowNoSuchFieldError(JNIEnv *env, const char *msg);
+
+JNIEXPORT void JNICALL
+JNU_ThrowNoSuchMethodError(JNIEnv *env, const char *msg);
+
+JNIEXPORT void JNICALL
+JNU_ThrowStringIndexOutOfBoundsException(JNIEnv *env, const char *msg);
+
+JNIEXPORT void JNICALL
+JNU_ThrowInstantiationException(JNIEnv *env, const char *msg);
+
+/* Throw an exception by name, using the string returned by
+ * JVM_LastErrorString for the detail string.  If the last-error
+ * string is NULL, use the given default detail string.
+ */
+JNIEXPORT void JNICALL
+JNU_ThrowByNameWithLastError(JNIEnv *env, const char *name,
+                             const char *defaultMessage);
+
+/* Throw an IOException, using the last-error string for the detail
+ * string.  If the last-error string is NULL, use the given default
+ * detail string.
+ */
+JNIEXPORT void JNICALL
+JNU_ThrowIOExceptionWithLastError(JNIEnv *env, const char *defaultDetail);
+
+/* Convert between Java strings and i18n C strings */
+JNIEXPORT jstring
+NewStringPlatform(JNIEnv *env, const char *str);
+
+JNIEXPORT const char *
+GetStringPlatformChars(JNIEnv *env, jstring jstr, jboolean *isCopy);
+
+JNIEXPORT jstring JNICALL
+JNU_NewStringPlatform(JNIEnv *env, const char *str);
+
+JNIEXPORT const char * JNICALL
+JNU_GetStringPlatformChars(JNIEnv *env, jstring jstr, jboolean *isCopy);
+
+JNIEXPORT void JNICALL
+JNU_ReleaseStringPlatformChars(JNIEnv *env, jstring jstr, const char *str);
+
+/* Class constants */
+JNIEXPORT jclass JNICALL
+JNU_ClassString(JNIEnv *env);
+
+JNIEXPORT jclass JNICALL
+JNU_ClassClass(JNIEnv *env);
+
+JNIEXPORT jclass JNICALL
+JNU_ClassObject(JNIEnv *env);
+
+JNIEXPORT jclass JNICALL
+JNU_ClassThrowable(JNIEnv *env);
+
+/* Copy count number of arguments from src to dst. Array bounds
+ * and ArrayStoreException are checked.
+ */
+JNIEXPORT jint JNICALL
+JNU_CopyObjectArray(JNIEnv *env, jobjectArray dst, jobjectArray src,
+                    jint count);
+
+/* Invoke a object-returning static method, based on class name,
+ * method name, and signature string.
+ *
+ * The caller should check for exceptions by setting hasException
+ * argument. If the caller is not interested in whether an exception
+ * has occurred, pass in NULL.
+ */
+JNIEXPORT jvalue JNICALL
+JNU_CallStaticMethodByName(JNIEnv *env,
+                           jboolean *hasException,
+                           const char *class_name,
+                           const char *name,
+                           const char *signature,
+                           ...);
+
+/* Invoke an instance method by name.
+ */
+JNIEXPORT jvalue JNICALL
+JNU_CallMethodByName(JNIEnv *env,
+                     jboolean *hasException,
+                     jobject obj,
+                     const char *name,
+                     const char *signature,
+                     ...);
+
+JNIEXPORT jvalue JNICALL
+JNU_CallMethodByNameV(JNIEnv *env,
+                      jboolean *hasException,
+                      jobject obj,
+                      const char *name,
+                      const char *signature,
+                      va_list args);
+
+/* Construct a new object of class, specifying the class by name,
+ * and specififying which constructor to run and what arguments to
+ * pass to it.
+ *
+ * The method will return an initialized instance if successful.
+ * It will return NULL if an error has occured (for example if
+ * it ran out of memory) and the appropriate Java exception will
+ * have been thrown.
+ */
+JNIEXPORT jobject JNICALL
+JNU_NewObjectByName(JNIEnv *env, const char *class_name,
+                    const char *constructor_sig, ...);
+
+/* returns:
+ * 0: object is not an instance of the class named by classname.
+ * 1: object is an instance of the class named by classname.
+ * -1: the class named by classname cannot be found. An exception
+ * has been thrown.
+ */
+JNIEXPORT jint JNICALL
+JNU_IsInstanceOfByName(JNIEnv *env, jobject object, char *classname);
+
+
+/* Get or set class and instance fields.
+ * Note that set functions take a variable number of arguments,
+ * but only one argument of the appropriate type can be passed.
+ * For example, to set an integer field i to 100:
+ *
+ * JNU_SetFieldByName(env, &exc, obj, "i", "I", 100);
+ *
+ * To set a float field f to 12.3:
+ *
+ * JNU_SetFieldByName(env, &exc, obj, "f", "F", 12.3);
+ *
+ * The caller should check for exceptions by setting hasException
+ * argument. If the caller is not interested in whether an exception
+ * has occurred, pass in NULL.
+ */
+JNIEXPORT jvalue JNICALL
+JNU_GetFieldByName(JNIEnv *env,
+                   jboolean *hasException,
+                   jobject obj,
+                   const char *name,
+                   const char *sig);
+JNIEXPORT void JNICALL
+JNU_SetFieldByName(JNIEnv *env,
+                   jboolean *hasException,
+                   jobject obj,
+                   const char *name,
+                   const char *sig,
+                   ...);
+
+JNIEXPORT jvalue JNICALL
+JNU_GetStaticFieldByName(JNIEnv *env,
+                         jboolean *hasException,
+                         const char *classname,
+                         const char *name,
+                         const char *sig);
+JNIEXPORT void JNICALL
+JNU_SetStaticFieldByName(JNIEnv *env,
+                         jboolean *hasException,
+                         const char *classname,
+                         const char *name,
+                         const char *sig,
+                         ...);
+
+
+/*
+ * Calls the .equals method.
+ */
+JNIEXPORT jboolean JNICALL
+JNU_Equals(JNIEnv *env, jobject object1, jobject object2);
+
+
+/************************************************************************
+ * Thread calls
+ *
+ * Convenience thread-related calls on the java.lang.Object class.
+ */
+
+JNIEXPORT void JNICALL
+JNU_MonitorWait(JNIEnv *env, jobject object, jlong timeout);
+
+JNIEXPORT void JNICALL
+JNU_Notify(JNIEnv *env, jobject object);
+
+JNIEXPORT void JNICALL
+JNU_NotifyAll(JNIEnv *env, jobject object);
+
+
+/************************************************************************
+ * Miscellaneous utilities used by the class libraries
+ */
+
+#define IS_NULL(obj) ((obj) == NULL)
+#define JNU_IsNull(env,obj) ((obj) == NULL)
+
+
+/************************************************************************
+ * Debugging utilities
+ */
+
+JNIEXPORT void JNICALL
+JNU_PrintString(JNIEnv *env, char *hdr, jstring string);
+
+JNIEXPORT void JNICALL
+JNU_PrintClass(JNIEnv *env, char *hdr, jobject object);
+
+JNIEXPORT jstring JNICALL
+JNU_ToString(JNIEnv *env, jobject object);
+
+/*
+ * Package shorthand for use by native libraries
+ */
+#define JNU_JAVAPKG         "java/lang/"
+#define JNU_JAVAIOPKG       "java/io/"
+#define JNU_JAVANETPKG      "java/net/"
+
+/*
+ * Check if the current thread is attached to the VM, and returns
+ * the JNIEnv of the specified version if the thread is attached.
+ *
+ * If the current thread is not attached, this function returns 0.
+ *
+ * If the current thread is attached, this function returns the
+ * JNI environment, or returns (void *)JNI_ERR if the specified
+ * version is not supported.
+ */
+JNIEXPORT void * JNICALL
+JNU_GetEnv(JavaVM *vm, jint version);
+
+/*
+ * Warning free access to pointers stored in Java long fields.
+ */
+#define JNU_GetLongFieldAsPtr(env,obj,id) \
+    (jlong_to_ptr((*(env))->GetLongField((env),(obj),(id))))
+#define JNU_SetLongFieldFromPtr(env,obj,id,val) \
+    (*(env))->SetLongField((env),(obj),(id),ptr_to_jlong(val))
+
+/*
+ * Internal use only.
+ */
+enum {
+    NO_ENCODING_YET = 0,        /* "sun.jnu.encoding" not yet set */
+    NO_FAST_ENCODING,           /* Platform encoding is not fast */
+    FAST_8859_1,                /* ISO-8859-1 */
+    FAST_CP1252,                /* MS-DOS Cp1252 */
+    FAST_646_US                 /* US-ASCII : ISO646-US */
+};
+
+jstring nativeNewStringPlatform(JNIEnv *env, const char *str);
+
+char* nativeGetStringPlatformChars(JNIEnv *env, jstring jstr, jboolean *isCopy);
+
+int getFastEncoding();
+
+void initializeEncoding();
+
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif /* __cplusplus */
+
+#endif /* JNI_UTIL_H */
diff --git a/ojluni/src/main/native/jni_util_md.c b/ojluni/src/main/native/jni_util_md.c
new file mode 100755
index 0000000..dc9fb99
--- /dev/null
+++ b/ojluni/src/main/native/jni_util_md.c
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include "jni.h"
+#include "jni_util.h"
+
+jstring nativeNewStringPlatform(JNIEnv *env, const char *str) {
+    return NULL;
+}
+
+char* nativeGetStringPlatformChars(JNIEnv *env, jstring jstr, jboolean *isCopy) {
+    return NULL;
+}
diff --git a/ojluni/src/main/native/jvm.h b/ojluni/src/main/native/jvm.h
new file mode 100755
index 0000000..f298cca
--- /dev/null
+++ b/ojluni/src/main/native/jvm.h
@@ -0,0 +1,1486 @@
+/*
+ * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#ifndef _JAVASOFT_JVM_H_
+#define _JAVASOFT_JVM_H_
+
+#include <sys/stat.h>
+
+#include "jni.h"
+#include "jvm_md.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * This file contains additional functions exported from the VM.
+ * These functions are complementary to the standard JNI support.
+ * There are three parts to this file:
+ *
+ * First, this file contains the VM-related functions needed by native
+ * libraries in the standard Java API. For example, the java.lang.Object
+ * class needs VM-level functions that wait for and notify monitors.
+ *
+ * Second, this file contains the functions and constant definitions
+ * needed by the byte code verifier and class file format checker.
+ * These functions allow the verifier and format checker to be written
+ * in a VM-independent way.
+ *
+ * Third, this file contains various I/O and nerwork operations needed
+ * by the standard Java I/O and network APIs.
+ */
+
+/*
+ * Bump the version number when either of the following happens:
+ *
+ * 1. There is a change in JVM_* functions.
+ *
+ * 2. There is a change in the contract between VM and Java classes.
+ *    For example, if the VM relies on a new private field in Thread
+ *    class.
+ */
+
+#define JVM_INTERFACE_VERSION 4
+
+JNIEXPORT jint JNICALL
+JVM_GetInterfaceVersion(void);
+
+/*************************************************************************
+ PART 1: Functions for Native Libraries
+ ************************************************************************/
+/*
+ * java.lang.Object
+ */
+JNIEXPORT jint JNICALL
+JVM_IHashCode(JNIEnv *env, jobject obj);
+
+JNIEXPORT void JNICALL
+JVM_MonitorWait(JNIEnv *env, jobject obj, jlong ms);
+
+JNIEXPORT void JNICALL
+JVM_MonitorNotify(JNIEnv *env, jobject obj);
+
+JNIEXPORT void JNICALL
+JVM_MonitorNotifyAll(JNIEnv *env, jobject obj);
+
+JNIEXPORT jobject JNICALL
+JVM_Clone(JNIEnv *env, jobject obj);
+
+/*
+ * java.lang.String
+ */
+JNIEXPORT jstring JNICALL
+JVM_InternString(JNIEnv *env, jstring str);
+
+/*
+ * java.lang.System
+ */
+JNIEXPORT jlong JNICALL
+JVM_CurrentTimeMillis(JNIEnv *env, jclass ignored);
+
+JNIEXPORT jlong JNICALL
+JVM_NanoTime(JNIEnv *env, jclass ignored);
+
+JNIEXPORT void JNICALL
+JVM_ArrayCopy(JNIEnv *env, jclass ignored, jobject src, jint src_pos,
+              jobject dst, jint dst_pos, jint length);
+
+JNIEXPORT jobject JNICALL
+JVM_InitProperties(JNIEnv *env, jobject p);
+
+/*
+ * java.io.File
+ */
+JNIEXPORT void JNICALL
+JVM_OnExit(void (*func)(void));
+
+/*
+ * java.lang.Runtime
+ */
+JNIEXPORT void JNICALL
+JVM_Exit(jint code);
+
+JNIEXPORT void JNICALL
+JVM_Halt(jint code);
+
+JNIEXPORT void JNICALL
+JVM_GC(void);
+
+/* Returns the number of real-time milliseconds that have elapsed since the
+ * least-recently-inspected heap object was last inspected by the garbage
+ * collector.
+ *
+ * For simple stop-the-world collectors this value is just the time
+ * since the most recent collection.  For generational collectors it is the
+ * time since the oldest generation was most recently collected.  Other
+ * collectors are free to return a pessimistic estimate of the elapsed time, or
+ * simply the time since the last full collection was performed.
+ *
+ * Note that in the presence of reference objects, a given object that is no
+ * longer strongly reachable may have to be inspected multiple times before it
+ * can be reclaimed.
+ */
+JNIEXPORT jlong JNICALL
+JVM_MaxObjectInspectionAge(void);
+
+JNIEXPORT void JNICALL
+JVM_TraceInstructions(jboolean on);
+
+JNIEXPORT void JNICALL
+JVM_TraceMethodCalls(jboolean on);
+
+JNIEXPORT jlong JNICALL
+JVM_TotalMemory(void);
+
+JNIEXPORT jlong JNICALL
+JVM_FreeMemory(void);
+
+JNIEXPORT jlong JNICALL
+JVM_MaxMemory(void);
+
+JNIEXPORT jint JNICALL
+JVM_ActiveProcessorCount(void);
+
+JNIEXPORT void * JNICALL
+JVM_LoadLibrary(const char *name);
+
+JNIEXPORT void JNICALL
+JVM_UnloadLibrary(void * handle);
+
+JNIEXPORT void * JNICALL
+JVM_FindLibraryEntry(void *handle, const char *name);
+
+JNIEXPORT jboolean JNICALL
+JVM_IsSupportedJNIVersion(jint version);
+
+/*
+ * java.lang.Float and java.lang.Double
+ */
+JNIEXPORT jboolean JNICALL
+JVM_IsNaN(jdouble d);
+
+/*
+ * java.lang.Throwable
+ */
+JNIEXPORT void JNICALL
+JVM_FillInStackTrace(JNIEnv *env, jobject throwable);
+
+JNIEXPORT void JNICALL
+JVM_PrintStackTrace(JNIEnv *env, jobject throwable, jobject printable);
+
+JNIEXPORT jint JNICALL
+JVM_GetStackTraceDepth(JNIEnv *env, jobject throwable);
+
+JNIEXPORT jobject JNICALL
+JVM_GetStackTraceElement(JNIEnv *env, jobject throwable, jint index);
+
+/*
+ * java.lang.Compiler
+ */
+JNIEXPORT void JNICALL
+JVM_InitializeCompiler (JNIEnv *env, jclass compCls);
+
+JNIEXPORT jboolean JNICALL
+JVM_IsSilentCompiler(JNIEnv *env, jclass compCls);
+
+JNIEXPORT jboolean JNICALL
+JVM_CompileClass(JNIEnv *env, jclass compCls, jclass cls);
+
+JNIEXPORT jboolean JNICALL
+JVM_CompileClasses(JNIEnv *env, jclass cls, jstring jname);
+
+JNIEXPORT jobject JNICALL
+JVM_CompilerCommand(JNIEnv *env, jclass compCls, jobject arg);
+
+JNIEXPORT void JNICALL
+JVM_EnableCompiler(JNIEnv *env, jclass compCls);
+
+JNIEXPORT void JNICALL
+JVM_DisableCompiler(JNIEnv *env, jclass compCls);
+
+/*
+ * java.lang.Thread
+ */
+JNIEXPORT void JNICALL
+JVM_StartThread(JNIEnv *env, jobject thread);
+
+JNIEXPORT void JNICALL
+JVM_StopThread(JNIEnv *env, jobject thread, jobject exception);
+
+JNIEXPORT jboolean JNICALL
+JVM_IsThreadAlive(JNIEnv *env, jobject thread);
+
+JNIEXPORT void JNICALL
+JVM_SuspendThread(JNIEnv *env, jobject thread);
+
+JNIEXPORT void JNICALL
+JVM_ResumeThread(JNIEnv *env, jobject thread);
+
+JNIEXPORT void JNICALL
+JVM_SetThreadPriority(JNIEnv *env, jobject thread, jint prio);
+
+JNIEXPORT void JNICALL
+JVM_Yield(JNIEnv *env, jclass threadClass);
+
+JNIEXPORT void JNICALL
+JVM_Sleep(JNIEnv *env, jclass threadClass, jlong millis);
+
+JNIEXPORT jobject JNICALL
+JVM_CurrentThread(JNIEnv *env, jclass threadClass);
+
+JNIEXPORT jint JNICALL
+JVM_CountStackFrames(JNIEnv *env, jobject thread);
+
+JNIEXPORT void JNICALL
+JVM_Interrupt(JNIEnv *env, jobject thread);
+
+JNIEXPORT jboolean JNICALL
+JVM_IsInterrupted(JNIEnv *env, jobject thread, jboolean clearInterrupted);
+
+JNIEXPORT jboolean JNICALL
+JVM_HoldsLock(JNIEnv *env, jclass threadClass, jobject obj);
+
+JNIEXPORT void JNICALL
+JVM_DumpAllStacks(JNIEnv *env, jclass unused);
+
+JNIEXPORT jobjectArray JNICALL
+JVM_GetAllThreads(JNIEnv *env, jclass dummy);
+
+JNIEXPORT void JNICALL
+JVM_SetNativeThreadName(JNIEnv *env, jobject jthread, jstring name);
+
+/* getStackTrace() and getAllStackTraces() method */
+JNIEXPORT jobjectArray JNICALL
+JVM_DumpThreads(JNIEnv *env, jclass threadClass, jobjectArray threads);
+
+/*
+ * java.lang.SecurityManager
+ */
+JNIEXPORT jclass JNICALL
+JVM_CurrentLoadedClass(JNIEnv *env);
+
+JNIEXPORT jobject JNICALL
+JVM_CurrentClassLoader(JNIEnv *env);
+
+JNIEXPORT jobjectArray JNICALL
+JVM_GetClassContext(JNIEnv *env);
+
+JNIEXPORT jint JNICALL
+JVM_ClassDepth(JNIEnv *env, jstring name);
+
+JNIEXPORT jint JNICALL
+JVM_ClassLoaderDepth(JNIEnv *env);
+
+/*
+ * java.lang.Package
+ */
+JNIEXPORT jstring JNICALL
+JVM_GetSystemPackage(JNIEnv *env, jstring name);
+
+JNIEXPORT jobjectArray JNICALL
+JVM_GetSystemPackages(JNIEnv *env);
+
+/*
+ * java.io.ObjectInputStream
+ */
+JNIEXPORT jobject JNICALL
+JVM_AllocateNewObject(JNIEnv *env, jobject obj, jclass currClass,
+                      jclass initClass);
+
+JNIEXPORT jobject JNICALL
+JVM_AllocateNewArray(JNIEnv *env, jobject obj, jclass currClass,
+                     jint length);
+
+JNIEXPORT jobject JNICALL
+JVM_LatestUserDefinedLoader(JNIEnv *env);
+
+/*
+ * This function has been deprecated and should not be considered
+ * part of the specified JVM interface.
+ */
+JNIEXPORT jclass JNICALL
+JVM_LoadClass0(JNIEnv *env, jobject obj, jclass currClass,
+               jstring currClassName);
+
+/*
+ * java.lang.reflect.Array
+ */
+JNIEXPORT jint JNICALL
+JVM_GetArrayLength(JNIEnv *env, jobject arr);
+
+JNIEXPORT jobject JNICALL
+JVM_GetArrayElement(JNIEnv *env, jobject arr, jint index);
+
+JNIEXPORT jvalue JNICALL
+JVM_GetPrimitiveArrayElement(JNIEnv *env, jobject arr, jint index, jint wCode);
+
+JNIEXPORT void JNICALL
+JVM_SetArrayElement(JNIEnv *env, jobject arr, jint index, jobject val);
+
+JNIEXPORT void JNICALL
+JVM_SetPrimitiveArrayElement(JNIEnv *env, jobject arr, jint index, jvalue v,
+                             unsigned char vCode);
+
+JNIEXPORT jobject JNICALL
+JVM_NewArray(JNIEnv *env, jclass eltClass, jint length);
+
+JNIEXPORT jobject JNICALL
+JVM_NewMultiArray(JNIEnv *env, jclass eltClass, jintArray dim);
+
+/*
+ * java.lang.Class and java.lang.ClassLoader
+ */
+/*
+ * Returns the class in which the code invoking the native method
+ * belongs.
+ *
+ * Note that in JDK 1.1, native methods did not create a frame.
+ * In 1.2, they do. Therefore native methods like Class.forName
+ * can no longer look at the current frame for the caller class.
+ */
+JNIEXPORT jclass JNICALL
+JVM_GetCallerClass(JNIEnv *env, int n);
+
+/*
+ * Find primitive classes
+ * utf: class name
+ */
+JNIEXPORT jclass JNICALL
+JVM_FindPrimitiveClass(JNIEnv *env, const char *utf);
+
+/*
+ * Link the class
+ */
+JNIEXPORT void JNICALL
+JVM_ResolveClass(JNIEnv *env, jclass cls);
+
+/*
+ * Find a class from a boot class loader. Returns NULL if class not found.
+ */
+JNIEXPORT jclass JNICALL
+JVM_FindClassFromBootLoader(JNIEnv *env, const char *name);
+
+/*
+ * Find a class from a given class loader. Throw ClassNotFoundException
+ * or NoClassDefFoundError depending on the value of the last
+ * argument.
+ */
+JNIEXPORT jclass JNICALL
+JVM_FindClassFromClassLoader(JNIEnv *env, const char *name, jboolean init,
+                             jobject loader, jboolean throwError);
+
+/*
+ * Find a class from a given class.
+ */
+JNIEXPORT jclass JNICALL
+JVM_FindClassFromClass(JNIEnv *env, const char *name, jboolean init,
+                             jclass from);
+
+/* Find a loaded class cached by the VM */
+JNIEXPORT jclass JNICALL
+JVM_FindLoadedClass(JNIEnv *env, jobject loader, jstring name);
+
+/* Define a class */
+JNIEXPORT jclass JNICALL
+JVM_DefineClass(JNIEnv *env, const char *name, jobject loader, const jbyte *buf,
+                jsize len, jobject pd);
+
+/* Define a class with a source (added in JDK1.5) */
+JNIEXPORT jclass JNICALL
+JVM_DefineClassWithSource(JNIEnv *env, const char *name, jobject loader,
+                          const jbyte *buf, jsize len, jobject pd,
+                          const char *source);
+
+/*
+ * Reflection support functions
+ */
+
+JNIEXPORT jstring JNICALL
+JVM_GetClassName(JNIEnv *env, jclass cls);
+
+JNIEXPORT jobjectArray JNICALL
+JVM_GetClassInterfaces(JNIEnv *env, jclass cls);
+
+JNIEXPORT jobject JNICALL
+JVM_GetClassLoader(JNIEnv *env, jclass cls);
+
+JNIEXPORT jboolean JNICALL
+JVM_IsInterface(JNIEnv *env, jclass cls);
+
+JNIEXPORT jobjectArray JNICALL
+JVM_GetClassSigners(JNIEnv *env, jclass cls);
+
+JNIEXPORT void JNICALL
+JVM_SetClassSigners(JNIEnv *env, jclass cls, jobjectArray signers);
+
+JNIEXPORT jobject JNICALL
+JVM_GetProtectionDomain(JNIEnv *env, jclass cls);
+
+JNIEXPORT void JNICALL
+JVM_SetProtectionDomain(JNIEnv *env, jclass cls, jobject protection_domain);
+
+JNIEXPORT jboolean JNICALL
+JVM_IsArrayClass(JNIEnv *env, jclass cls);
+
+JNIEXPORT jboolean JNICALL
+JVM_IsPrimitiveClass(JNIEnv *env, jclass cls);
+
+JNIEXPORT jclass JNICALL
+JVM_GetComponentType(JNIEnv *env, jclass cls);
+
+JNIEXPORT jint JNICALL
+JVM_GetClassModifiers(JNIEnv *env, jclass cls);
+
+JNIEXPORT jobjectArray JNICALL
+JVM_GetDeclaredClasses(JNIEnv *env, jclass ofClass);
+
+JNIEXPORT jclass JNICALL
+JVM_GetDeclaringClass(JNIEnv *env, jclass ofClass);
+
+/* Generics support (JDK 1.5) */
+JNIEXPORT jstring JNICALL
+JVM_GetClassSignature(JNIEnv *env, jclass cls);
+
+/* Annotations support (JDK 1.5) */
+JNIEXPORT jbyteArray JNICALL
+JVM_GetClassAnnotations(JNIEnv *env, jclass cls);
+
+/*
+ * New (JDK 1.4) reflection implementation
+ */
+
+JNIEXPORT jobjectArray JNICALL
+JVM_GetClassDeclaredMethods(JNIEnv *env, jclass ofClass, jboolean publicOnly);
+
+JNIEXPORT jobjectArray JNICALL
+JVM_GetClassDeclaredFields(JNIEnv *env, jclass ofClass, jboolean publicOnly);
+
+JNIEXPORT jobjectArray JNICALL
+JVM_GetClassDeclaredConstructors(JNIEnv *env, jclass ofClass, jboolean publicOnly);
+
+/* Differs from JVM_GetClassModifiers in treatment of inner classes.
+   This returns the access flags for the class as specified in the
+   class file rather than searching the InnerClasses attribute (if
+   present) to find the source-level access flags. Only the values of
+   the low 13 bits (i.e., a mask of 0x1FFF) are guaranteed to be
+   valid. */
+JNIEXPORT jint JNICALL
+JVM_GetClassAccessFlags(JNIEnv *env, jclass cls);
+
+/* The following two reflection routines are still needed due to startup time issues */
+/*
+ * java.lang.reflect.Method
+ */
+JNIEXPORT jobject JNICALL
+JVM_InvokeMethod(JNIEnv *env, jobject method, jobject obj, jobjectArray args0);
+
+/*
+ * java.lang.reflect.Constructor
+ */
+JNIEXPORT jobject JNICALL
+JVM_NewInstanceFromConstructor(JNIEnv *env, jobject c, jobjectArray args0);
+
+/*
+ * Constant pool access; currently used to implement reflective access to annotations (JDK 1.5)
+ */
+
+JNIEXPORT jobject JNICALL
+JVM_GetClassConstantPool(JNIEnv *env, jclass cls);
+
+JNIEXPORT jint JNICALL JVM_ConstantPoolGetSize
+(JNIEnv *env, jobject unused, jobject jcpool);
+
+JNIEXPORT jclass JNICALL JVM_ConstantPoolGetClassAt
+(JNIEnv *env, jobject unused, jobject jcpool, jint index);
+
+JNIEXPORT jclass JNICALL JVM_ConstantPoolGetClassAtIfLoaded
+(JNIEnv *env, jobject unused, jobject jcpool, jint index);
+
+JNIEXPORT jobject JNICALL JVM_ConstantPoolGetMethodAt
+(JNIEnv *env, jobject unused, jobject jcpool, jint index);
+
+JNIEXPORT jobject JNICALL JVM_ConstantPoolGetMethodAtIfLoaded
+(JNIEnv *env, jobject unused, jobject jcpool, jint index);
+
+JNIEXPORT jobject JNICALL JVM_ConstantPoolGetFieldAt
+(JNIEnv *env, jobject unused, jobject jcpool, jint index);
+
+JNIEXPORT jobject JNICALL JVM_ConstantPoolGetFieldAtIfLoaded
+(JNIEnv *env, jobject unused, jobject jcpool, jint index);
+
+JNIEXPORT jobjectArray JNICALL JVM_ConstantPoolGetMemberRefInfoAt
+(JNIEnv *env, jobject unused, jobject jcpool, jint index);
+
+JNIEXPORT jint JNICALL JVM_ConstantPoolGetIntAt
+(JNIEnv *env, jobject unused, jobject jcpool, jint index);
+
+JNIEXPORT jlong JNICALL JVM_ConstantPoolGetLongAt
+(JNIEnv *env, jobject unused, jobject jcpool, jint index);
+
+JNIEXPORT jfloat JNICALL JVM_ConstantPoolGetFloatAt
+(JNIEnv *env, jobject unused, jobject jcpool, jint index);
+
+JNIEXPORT jdouble JNICALL JVM_ConstantPoolGetDoubleAt
+(JNIEnv *env, jobject unused, jobject jcpool, jint index);
+
+JNIEXPORT jstring JNICALL JVM_ConstantPoolGetStringAt
+(JNIEnv *env, jobject unused, jobject jcpool, jint index);
+
+JNIEXPORT jstring JNICALL JVM_ConstantPoolGetUTF8At
+(JNIEnv *env, jobject unused, jobject jcpool, jint index);
+
+/*
+ * java.security.*
+ */
+
+JNIEXPORT jobject JNICALL
+JVM_DoPrivileged(JNIEnv *env, jclass cls,
+                 jobject action, jobject context, jboolean wrapException);
+
+JNIEXPORT jobject JNICALL
+JVM_GetInheritedAccessControlContext(JNIEnv *env, jclass cls);
+
+JNIEXPORT jobject JNICALL
+JVM_GetStackAccessControlContext(JNIEnv *env, jclass cls);
+
+/*
+ * Signal support, used to implement the shutdown sequence.  Every VM must
+ * support JVM_SIGINT and JVM_SIGTERM, raising the former for user interrupts
+ * (^C) and the latter for external termination (kill, system shutdown, etc.).
+ * Other platform-dependent signal values may also be supported.
+ */
+
+JNIEXPORT void * JNICALL
+JVM_RegisterSignal(jint sig, void *handler);
+
+JNIEXPORT jboolean JNICALL
+JVM_RaiseSignal(jint sig);
+
+JNIEXPORT jint JNICALL
+JVM_FindSignal(const char *name);
+
+/*
+ * Retrieve the assertion directives for the specified class.
+ */
+JNIEXPORT jboolean JNICALL
+JVM_DesiredAssertionStatus(JNIEnv *env, jclass unused, jclass cls);
+
+/*
+ * Retrieve the assertion directives from the VM.
+ */
+JNIEXPORT jobject JNICALL
+JVM_AssertionStatusDirectives(JNIEnv *env, jclass unused);
+
+/*
+ * java.util.concurrent.AtomicLong
+ */
+JNIEXPORT jboolean JNICALL
+JVM_SupportsCX8(void);
+
+/*
+ * com.sun.dtrace.jsdt support
+ */
+
+#define JVM_TRACING_DTRACE_VERSION 1
+
+/*
+ * Structure to pass one probe description to JVM
+ */
+typedef struct {
+    jmethodID method;
+    jstring   function;
+    jstring   name;
+    void*            reserved[4];     // for future use
+} JVM_DTraceProbe;
+
+/**
+ * Encapsulates the stability ratings for a DTrace provider field
+ */
+typedef struct {
+    jint nameStability;
+    jint dataStability;
+    jint dependencyClass;
+} JVM_DTraceInterfaceAttributes;
+
+/*
+ * Structure to pass one provider description to JVM
+ */
+typedef struct {
+    jstring                       name;
+    JVM_DTraceProbe*              probes;
+    jint                          probe_count;
+    JVM_DTraceInterfaceAttributes providerAttributes;
+    JVM_DTraceInterfaceAttributes moduleAttributes;
+    JVM_DTraceInterfaceAttributes functionAttributes;
+    JVM_DTraceInterfaceAttributes nameAttributes;
+    JVM_DTraceInterfaceAttributes argsAttributes;
+    void*                         reserved[4]; // for future use
+} JVM_DTraceProvider;
+
+/*
+ * Get the version number the JVM was built with
+ */
+JNIEXPORT jint JNICALL
+JVM_DTraceGetVersion(JNIEnv* env);
+
+/*
+ * Register new probe with given signature, return global handle
+ *
+ * The version passed in is the version that the library code was
+ * built with.
+ */
+JNIEXPORT jlong JNICALL
+JVM_DTraceActivate(JNIEnv* env, jint version, jstring module_name,
+  jint providers_count, JVM_DTraceProvider* providers);
+
+/*
+ * Check JSDT probe
+ */
+JNIEXPORT jboolean JNICALL
+JVM_DTraceIsProbeEnabled(JNIEnv* env, jmethodID method);
+
+/*
+ * Destroy custom DOF
+ */
+JNIEXPORT void JNICALL
+JVM_DTraceDispose(JNIEnv* env, jlong activation_handle);
+
+/*
+ * Check to see if DTrace is supported by OS
+ */
+JNIEXPORT jboolean JNICALL
+JVM_DTraceIsSupported(JNIEnv* env);
+
+/*************************************************************************
+ PART 2: Support for the Verifier and Class File Format Checker
+ ************************************************************************/
+/*
+ * Return the class name in UTF format. The result is valid
+ * until JVM_ReleaseUTf is called.
+ *
+ * The caller must treat the string as a constant and not modify it
+ * in any way.
+ */
+JNIEXPORT const char * JNICALL
+JVM_GetClassNameUTF(JNIEnv *env, jclass cb);
+
+/*
+ * Returns the constant pool types in the buffer provided by "types."
+ */
+JNIEXPORT void JNICALL
+JVM_GetClassCPTypes(JNIEnv *env, jclass cb, unsigned char *types);
+
+/*
+ * Returns the number of Constant Pool entries.
+ */
+JNIEXPORT jint JNICALL
+JVM_GetClassCPEntriesCount(JNIEnv *env, jclass cb);
+
+/*
+ * Returns the number of *declared* fields or methods.
+ */
+JNIEXPORT jint JNICALL
+JVM_GetClassFieldsCount(JNIEnv *env, jclass cb);
+
+JNIEXPORT jint JNICALL
+JVM_GetClassMethodsCount(JNIEnv *env, jclass cb);
+
+/*
+ * Returns the CP indexes of exceptions raised by a given method.
+ * Places the result in the given buffer.
+ *
+ * The method is identified by method_index.
+ */
+JNIEXPORT void JNICALL
+JVM_GetMethodIxExceptionIndexes(JNIEnv *env, jclass cb, jint method_index,
+                                unsigned short *exceptions);
+/*
+ * Returns the number of exceptions raised by a given method.
+ * The method is identified by method_index.
+ */
+JNIEXPORT jint JNICALL
+JVM_GetMethodIxExceptionsCount(JNIEnv *env, jclass cb, jint method_index);
+
+/*
+ * Returns the byte code sequence of a given method.
+ * Places the result in the given buffer.
+ *
+ * The method is identified by method_index.
+ */
+JNIEXPORT void JNICALL
+JVM_GetMethodIxByteCode(JNIEnv *env, jclass cb, jint method_index,
+                        unsigned char *code);
+
+/*
+ * Returns the length of the byte code sequence of a given method.
+ * The method is identified by method_index.
+ */
+JNIEXPORT jint JNICALL
+JVM_GetMethodIxByteCodeLength(JNIEnv *env, jclass cb, jint method_index);
+
+/*
+ * A structure used to a capture exception table entry in a Java method.
+ */
+typedef struct {
+    jint start_pc;
+    jint end_pc;
+    jint handler_pc;
+    jint catchType;
+} JVM_ExceptionTableEntryType;
+
+/*
+ * Returns the exception table entry at entry_index of a given method.
+ * Places the result in the given buffer.
+ *
+ * The method is identified by method_index.
+ */
+JNIEXPORT void JNICALL
+JVM_GetMethodIxExceptionTableEntry(JNIEnv *env, jclass cb, jint method_index,
+                                   jint entry_index,
+                                   JVM_ExceptionTableEntryType *entry);
+
+/*
+ * Returns the length of the exception table of a given method.
+ * The method is identified by method_index.
+ */
+JNIEXPORT jint JNICALL
+JVM_GetMethodIxExceptionTableLength(JNIEnv *env, jclass cb, int index);
+
+/*
+ * Returns the modifiers of a given field.
+ * The field is identified by field_index.
+ */
+JNIEXPORT jint JNICALL
+JVM_GetFieldIxModifiers(JNIEnv *env, jclass cb, int index);
+
+/*
+ * Returns the modifiers of a given method.
+ * The method is identified by method_index.
+ */
+JNIEXPORT jint JNICALL
+JVM_GetMethodIxModifiers(JNIEnv *env, jclass cb, int index);
+
+/*
+ * Returns the number of local variables of a given method.
+ * The method is identified by method_index.
+ */
+JNIEXPORT jint JNICALL
+JVM_GetMethodIxLocalsCount(JNIEnv *env, jclass cb, int index);
+
+/*
+ * Returns the number of arguments (including this pointer) of a given method.
+ * The method is identified by method_index.
+ */
+JNIEXPORT jint JNICALL
+JVM_GetMethodIxArgsSize(JNIEnv *env, jclass cb, int index);
+
+/*
+ * Returns the maximum amount of stack (in words) used by a given method.
+ * The method is identified by method_index.
+ */
+JNIEXPORT jint JNICALL
+JVM_GetMethodIxMaxStack(JNIEnv *env, jclass cb, int index);
+
+/*
+ * Is a given method a constructor.
+ * The method is identified by method_index.
+ */
+JNIEXPORT jboolean JNICALL
+JVM_IsConstructorIx(JNIEnv *env, jclass cb, int index);
+
+/*
+ * Returns the name of a given method in UTF format.
+ * The result remains valid until JVM_ReleaseUTF is called.
+ *
+ * The caller must treat the string as a constant and not modify it
+ * in any way.
+ */
+JNIEXPORT const char * JNICALL
+JVM_GetMethodIxNameUTF(JNIEnv *env, jclass cb, jint index);
+
+/*
+ * Returns the signature of a given method in UTF format.
+ * The result remains valid until JVM_ReleaseUTF is called.
+ *
+ * The caller must treat the string as a constant and not modify it
+ * in any way.
+ */
+JNIEXPORT const char * JNICALL
+JVM_GetMethodIxSignatureUTF(JNIEnv *env, jclass cb, jint index);
+
+/*
+ * Returns the name of the field refered to at a given constant pool
+ * index.
+ *
+ * The result is in UTF format and remains valid until JVM_ReleaseUTF
+ * is called.
+ *
+ * The caller must treat the string as a constant and not modify it
+ * in any way.
+ */
+JNIEXPORT const char * JNICALL
+JVM_GetCPFieldNameUTF(JNIEnv *env, jclass cb, jint index);
+
+/*
+ * Returns the name of the method refered to at a given constant pool
+ * index.
+ *
+ * The result is in UTF format and remains valid until JVM_ReleaseUTF
+ * is called.
+ *
+ * The caller must treat the string as a constant and not modify it
+ * in any way.
+ */
+JNIEXPORT const char * JNICALL
+JVM_GetCPMethodNameUTF(JNIEnv *env, jclass cb, jint index);
+
+/*
+ * Returns the signature of the method refered to at a given constant pool
+ * index.
+ *
+ * The result is in UTF format and remains valid until JVM_ReleaseUTF
+ * is called.
+ *
+ * The caller must treat the string as a constant and not modify it
+ * in any way.
+ */
+JNIEXPORT const char * JNICALL
+JVM_GetCPMethodSignatureUTF(JNIEnv *env, jclass cb, jint index);
+
+/*
+ * Returns the signature of the field refered to at a given constant pool
+ * index.
+ *
+ * The result is in UTF format and remains valid until JVM_ReleaseUTF
+ * is called.
+ *
+ * The caller must treat the string as a constant and not modify it
+ * in any way.
+ */
+JNIEXPORT const char * JNICALL
+JVM_GetCPFieldSignatureUTF(JNIEnv *env, jclass cb, jint index);
+
+/*
+ * Returns the class name refered to at a given constant pool index.
+ *
+ * The result is in UTF format and remains valid until JVM_ReleaseUTF
+ * is called.
+ *
+ * The caller must treat the string as a constant and not modify it
+ * in any way.
+ */
+JNIEXPORT const char * JNICALL
+JVM_GetCPClassNameUTF(JNIEnv *env, jclass cb, jint index);
+
+/*
+ * Returns the class name refered to at a given constant pool index.
+ *
+ * The constant pool entry must refer to a CONSTANT_Fieldref.
+ *
+ * The result is in UTF format and remains valid until JVM_ReleaseUTF
+ * is called.
+ *
+ * The caller must treat the string as a constant and not modify it
+ * in any way.
+ */
+JNIEXPORT const char * JNICALL
+JVM_GetCPFieldClassNameUTF(JNIEnv *env, jclass cb, jint index);
+
+/*
+ * Returns the class name refered to at a given constant pool index.
+ *
+ * The constant pool entry must refer to CONSTANT_Methodref or
+ * CONSTANT_InterfaceMethodref.
+ *
+ * The result is in UTF format and remains valid until JVM_ReleaseUTF
+ * is called.
+ *
+ * The caller must treat the string as a constant and not modify it
+ * in any way.
+ */
+JNIEXPORT const char * JNICALL
+JVM_GetCPMethodClassNameUTF(JNIEnv *env, jclass cb, jint index);
+
+/*
+ * Returns the modifiers of a field in calledClass. The field is
+ * referred to in class cb at constant pool entry index.
+ *
+ * The caller must treat the string as a constant and not modify it
+ * in any way.
+ *
+ * Returns -1 if the field does not exist in calledClass.
+ */
+JNIEXPORT jint JNICALL
+JVM_GetCPFieldModifiers(JNIEnv *env, jclass cb, int index, jclass calledClass);
+
+/*
+ * Returns the modifiers of a method in calledClass. The method is
+ * referred to in class cb at constant pool entry index.
+ *
+ * Returns -1 if the method does not exist in calledClass.
+ */
+JNIEXPORT jint JNICALL
+JVM_GetCPMethodModifiers(JNIEnv *env, jclass cb, int index, jclass calledClass);
+
+/*
+ * Releases the UTF string obtained from the VM.
+ */
+JNIEXPORT void JNICALL
+JVM_ReleaseUTF(const char *utf);
+
+/*
+ * Compare if two classes are in the same package.
+ */
+JNIEXPORT jboolean JNICALL
+JVM_IsSameClassPackage(JNIEnv *env, jclass class1, jclass class2);
+
+/* Get classfile constants */
+#include "classfile_constants.h"
+
+/*
+ * A function defined by the byte-code verifier and called by the VM.
+ * This is not a function implemented in the VM.
+ *
+ * Returns JNI_FALSE if verification fails. A detailed error message
+ * will be places in msg_buf, whose length is specified by buf_len.
+ */
+typedef jboolean (*verifier_fn_t)(JNIEnv *env,
+                                  jclass cb,
+                                  char * msg_buf,
+                                  jint buf_len);
+
+
+/*
+ * Support for a VM-independent class format checker.
+ */
+typedef struct {
+    unsigned long code;    /* byte code */
+    unsigned long excs;    /* exceptions */
+    unsigned long etab;    /* catch table */
+    unsigned long lnum;    /* line number */
+    unsigned long lvar;    /* local vars */
+} method_size_info;
+
+typedef struct {
+    unsigned int constants;    /* constant pool */
+    unsigned int fields;
+    unsigned int methods;
+    unsigned int interfaces;
+    unsigned int fields2;      /* number of static 2-word fields */
+    unsigned int innerclasses; /* # of records in InnerClasses attr */
+
+    method_size_info clinit;   /* memory used in clinit */
+    method_size_info main;     /* used everywhere else */
+} class_size_info;
+
+/*
+ * Functions defined in libjava.so to perform string conversions.
+ *
+ */
+
+typedef jstring (*to_java_string_fn_t)(JNIEnv *env, char *str);
+
+typedef char *(*to_c_string_fn_t)(JNIEnv *env, jstring s, jboolean *b);
+
+/* This is the function defined in libjava.so that performs class
+ * format checks. This functions fills in size information about
+ * the class file and returns:
+ *
+ *   0: good
+ *  -1: out of memory
+ *  -2: bad format
+ *  -3: unsupported version
+ *  -4: bad class name
+ */
+
+typedef jint (*check_format_fn_t)(char *class_name,
+                                  unsigned char *data,
+                                  unsigned int data_size,
+                                  class_size_info *class_size,
+                                  char *message_buffer,
+                                  jint buffer_length,
+                                  jboolean measure_only,
+                                  jboolean check_relaxed);
+
+#define JVM_RECOGNIZED_CLASS_MODIFIERS (JVM_ACC_PUBLIC | \
+                                        JVM_ACC_FINAL | \
+                                        JVM_ACC_SUPER | \
+                                        JVM_ACC_INTERFACE | \
+                                        JVM_ACC_ABSTRACT | \
+                                        JVM_ACC_ANNOTATION | \
+                                        JVM_ACC_ENUM | \
+                                        JVM_ACC_SYNTHETIC)
+
+#define JVM_RECOGNIZED_FIELD_MODIFIERS (JVM_ACC_PUBLIC | \
+                                        JVM_ACC_PRIVATE | \
+                                        JVM_ACC_PROTECTED | \
+                                        JVM_ACC_STATIC | \
+                                        JVM_ACC_FINAL | \
+                                        JVM_ACC_VOLATILE | \
+                                        JVM_ACC_TRANSIENT | \
+                                        JVM_ACC_ENUM | \
+                                        JVM_ACC_SYNTHETIC)
+
+#define JVM_RECOGNIZED_METHOD_MODIFIERS (JVM_ACC_PUBLIC | \
+                                         JVM_ACC_PRIVATE | \
+                                         JVM_ACC_PROTECTED | \
+                                         JVM_ACC_STATIC | \
+                                         JVM_ACC_FINAL | \
+                                         JVM_ACC_SYNCHRONIZED | \
+                                         JVM_ACC_BRIDGE | \
+                                         JVM_ACC_VARARGS | \
+                                         JVM_ACC_NATIVE | \
+                                         JVM_ACC_ABSTRACT | \
+                                         JVM_ACC_STRICT | \
+                                         JVM_ACC_SYNTHETIC)
+
+/*
+ * This is the function defined in libjava.so to perform path
+ * canonicalization. VM call this function before opening jar files
+ * to load system classes.
+ *
+ */
+
+typedef int (*canonicalize_fn_t)(JNIEnv *env, char *orig, char *out, int len);
+
+/*************************************************************************
+ PART 3: I/O and Network Support
+ ************************************************************************/
+
+/* Note that the JVM IO functions are expected to return JVM_IO_ERR
+ * when there is any kind of error. The caller can then use the
+ * platform specific support (e.g., errno) to get the detailed
+ * error info.  The JVM_GetLastErrorString procedure may also be used
+ * to obtain a descriptive error string.
+ */
+#define JVM_IO_ERR  (-1)
+
+/* For interruptible IO. Returning JVM_IO_INTR indicates that an IO
+ * operation has been disrupted by Thread.interrupt. There are a
+ * number of technical difficulties related to interruptible IO that
+ * need to be solved. For example, most existing programs do not handle
+ * InterruptedIOExceptions specially, they simply treat those as any
+ * IOExceptions, which typically indicate fatal errors.
+ *
+ * There are also two modes of operation for interruptible IO. In the
+ * resumption mode, an interrupted IO operation is guaranteed not to
+ * have any side-effects, and can be restarted. In the termination mode,
+ * an interrupted IO operation corrupts the underlying IO stream, so
+ * that the only reasonable operation on an interrupted stream is to
+ * close that stream. The resumption mode seems to be impossible to
+ * implement on Win32 and Solaris. Implementing the termination mode is
+ * easier, but it's not clear that's the right semantics.
+ *
+ * Interruptible IO is not supported on Win32.It can be enabled/disabled
+ * using a compile-time flag on Solaris. Third-party JVM ports do not
+ * need to implement interruptible IO.
+ */
+#define JVM_IO_INTR (-2)
+
+/* Write a string into the given buffer, in the platform's local encoding,
+ * that describes the most recent system-level error to occur in this thread.
+ * Return the length of the string or zero if no error occurred.
+ */
+JNIEXPORT jint JNICALL
+JVM_GetLastErrorString(char *buf, int len);
+
+/*
+ * Convert a pathname into native format.  This function does syntactic
+ * cleanup, such as removing redundant separator characters.  It modifies
+ * the given pathname string in place.
+ */
+JNIEXPORT char * JNICALL
+JVM_NativePath(char *);
+
+/*
+ * JVM I/O error codes
+ */
+#define JVM_EEXIST       -100
+
+/*
+ * Open a file descriptor. This function returns a negative error code
+ * on error, and a non-negative integer that is the file descriptor on
+ * success.
+ */
+JNIEXPORT jint JNICALL
+JVM_Open(const char *fname, jint flags, jint mode);
+
+/*
+ * Close a file descriptor. This function returns -1 on error, and 0
+ * on success.
+ *
+ * fd        the file descriptor to close.
+ */
+JNIEXPORT jint JNICALL
+JVM_Close(jint fd);
+
+/*
+ * Read data from a file decriptor into a char array.
+ *
+ * fd        the file descriptor to read from.
+ * buf       the buffer where to put the read data.
+ * nbytes    the number of bytes to read.
+ *
+ * This function returns -1 on error, and 0 on success.
+ */
+JNIEXPORT jint JNICALL
+JVM_Read(jint fd, char *buf, jint nbytes);
+
+/*
+ * Write data from a char array to a file decriptor.
+ *
+ * fd        the file descriptor to read from.
+ * buf       the buffer from which to fetch the data.
+ * nbytes    the number of bytes to write.
+ *
+ * This function returns -1 on error, and 0 on success.
+ */
+JNIEXPORT jint JNICALL
+JVM_Write(jint fd, char *buf, jint nbytes);
+
+/*
+ * Returns the number of bytes available for reading from a given file
+ * descriptor
+ */
+JNIEXPORT jint JNICALL
+JVM_Available(jint fd, jlong *pbytes);
+
+/*
+ * Move the file descriptor pointer from whence by offset.
+ *
+ * fd        the file descriptor to move.
+ * offset    the number of bytes to move it by.
+ * whence    the start from where to move it.
+ *
+ * This function returns the resulting pointer location.
+ */
+JNIEXPORT jlong JNICALL
+JVM_Lseek(jint fd, jlong offset, jint whence);
+
+/*
+ * Set the length of the file associated with the given descriptor to the given
+ * length.  If the new length is longer than the current length then the file
+ * is extended; the contents of the extended portion are not defined.  The
+ * value of the file pointer is undefined after this procedure returns.
+ */
+JNIEXPORT jint JNICALL
+JVM_SetLength(jint fd, jlong length);
+
+/*
+ * Synchronize the file descriptor's in memory state with that of the
+ * physical device.  Return of -1 is an error, 0 is OK.
+ */
+JNIEXPORT jint JNICALL
+JVM_Sync(jint fd);
+
+/*
+ * Networking library support
+ */
+
+JNIEXPORT jint JNICALL
+JVM_InitializeSocketLibrary(void);
+
+struct sockaddr;
+
+JNIEXPORT jint JNICALL
+JVM_Socket(jint domain, jint type, jint protocol);
+
+JNIEXPORT jint JNICALL
+JVM_SocketClose(jint fd);
+
+JNIEXPORT jint JNICALL
+JVM_SocketShutdown(jint fd, jint howto);
+
+JNIEXPORT jint JNICALL
+JVM_Recv(jint fd, char *buf, jint nBytes, jint flags);
+
+JNIEXPORT jint JNICALL
+JVM_Send(jint fd, char *buf, jint nBytes, jint flags);
+
+JNIEXPORT jint JNICALL
+JVM_Timeout(int fd, long timeout);
+
+JNIEXPORT jint JNICALL
+JVM_Listen(jint fd, jint count);
+
+JNIEXPORT jint JNICALL
+JVM_Connect(jint fd, struct sockaddr *him, jint len);
+
+JNIEXPORT jint JNICALL
+JVM_Bind(jint fd, struct sockaddr *him, jint len);
+
+JNIEXPORT jint JNICALL
+JVM_Accept(jint fd, struct sockaddr *him, jint *len);
+
+JNIEXPORT jint JNICALL
+JVM_RecvFrom(jint fd, char *buf, int nBytes,
+                  int flags, struct sockaddr *from, int *fromlen);
+
+JNIEXPORT jint JNICALL
+JVM_SendTo(jint fd, char *buf, int len,
+                int flags, struct sockaddr *to, int tolen);
+
+JNIEXPORT jint JNICALL
+JVM_SocketAvailable(jint fd, jint *result);
+
+
+JNIEXPORT jint JNICALL
+JVM_GetSockName(jint fd, struct sockaddr *him, int *len);
+
+JNIEXPORT jint JNICALL
+JVM_GetSockOpt(jint fd, int level, int optname, char *optval, int *optlen);
+
+JNIEXPORT jint JNICALL
+JVM_SetSockOpt(jint fd, int level, int optname, const char *optval, int optlen);
+
+JNIEXPORT int JNICALL
+JVM_GetHostName(char* name, int namelen);
+
+/*
+ * The standard printing functions supported by the Java VM. (Should they
+ * be renamed to JVM_* in the future?
+ */
+
+/*
+ * BE CAREFUL! The following functions do not implement the
+ * full feature set of standard C printf formats.
+ */
+int
+jio_vsnprintf(char *str, size_t count, const char *fmt, va_list args);
+
+int
+jio_snprintf(char *str, size_t count, const char *fmt, ...);
+
+int
+jio_fprintf(FILE *, const char *fmt, ...);
+
+int
+jio_vfprintf(FILE *, const char *fmt, va_list args);
+
+
+JNIEXPORT void * JNICALL
+JVM_RawMonitorCreate(void);
+
+JNIEXPORT void JNICALL
+JVM_RawMonitorDestroy(void *mon);
+
+JNIEXPORT jint JNICALL
+JVM_RawMonitorEnter(void *mon);
+
+JNIEXPORT void JNICALL
+JVM_RawMonitorExit(void *mon);
+
+/*
+ * java.lang.management support
+ */
+JNIEXPORT void* JNICALL
+JVM_GetManagement(jint version);
+
+/*
+ * com.sun.tools.attach.VirtualMachine support
+ *
+ * Initialize the agent properties with the properties maintained in the VM.
+ */
+JNIEXPORT jobject JNICALL
+JVM_InitAgentProperties(JNIEnv *env, jobject agent_props);
+
+/* Generics reflection support.
+ *
+ * Returns information about the given class's EnclosingMethod
+ * attribute, if present, or null if the class had no enclosing
+ * method.
+ *
+ * If non-null, the returned array contains three elements. Element 0
+ * is the java.lang.Class of which the enclosing method is a member,
+ * and elements 1 and 2 are the java.lang.Strings for the enclosing
+ * method's name and descriptor, respectively.
+ */
+JNIEXPORT jobjectArray JNICALL
+JVM_GetEnclosingMethodInfo(JNIEnv* env, jclass ofClass);
+
+/*
+ * Java thread state support
+ */
+enum {
+    JAVA_THREAD_STATE_NEW           = 0,
+    JAVA_THREAD_STATE_RUNNABLE      = 1,
+    JAVA_THREAD_STATE_BLOCKED       = 2,
+    JAVA_THREAD_STATE_WAITING       = 3,
+    JAVA_THREAD_STATE_TIMED_WAITING = 4,
+    JAVA_THREAD_STATE_TERMINATED    = 5,
+    JAVA_THREAD_STATE_COUNT         = 6
+};
+
+/*
+ * Returns an array of the threadStatus values representing the
+ * given Java thread state.  Returns NULL if the VM version is
+ * incompatible with the JDK or doesn't support the given
+ * Java thread state.
+ */
+JNIEXPORT jintArray JNICALL
+JVM_GetThreadStateValues(JNIEnv* env, jint javaThreadState);
+
+/*
+ * Returns an array of the substate names representing the
+ * given Java thread state.  Returns NULL if the VM version is
+ * incompatible with the JDK or the VM doesn't support
+ * the given Java thread state.
+ * values must be the jintArray returned from JVM_GetThreadStateValues
+ * and javaThreadState.
+ */
+JNIEXPORT jobjectArray JNICALL
+JVM_GetThreadStateNames(JNIEnv* env, jint javaThreadState, jintArray values);
+
+/* =========================================================================
+ * The following defines a private JVM interface that the JDK can query
+ * for the JVM version and capabilities.  sun.misc.Version defines
+ * the methods for getting the VM version and its capabilities.
+ *
+ * When a new bit is added, the following should be updated to provide
+ * access to the new capability:
+ *    HS:   JVM_GetVersionInfo and Abstract_VM_Version class
+ *    SDK:  Version class
+ *
+ * Similary, a private JDK interface JDK_GetVersionInfo0 is defined for
+ * JVM to query for the JDK version and capabilities.
+ *
+ * When a new bit is added, the following should be updated to provide
+ * access to the new capability:
+ *    HS:   JDK_Version class
+ *    SDK:  JDK_GetVersionInfo0
+ *
+ * ==========================================================================
+ */
+typedef struct {
+    /* Naming convention of RE build version string: n.n.n[_uu[c]][-<identifier>]-bxx */
+    unsigned int jvm_version;   /* Consists of major, minor, micro (n.n.n) */
+                                /* and build number (xx) */
+    unsigned int update_version : 8;         /* Update release version (uu) */
+    unsigned int special_update_version : 8; /* Special update release version (c)*/
+    unsigned int reserved1 : 16;
+    unsigned int reserved2;
+
+    /* The following bits represents JVM supports that JDK has dependency on.
+     * JDK can use these bits to determine which JVM version
+     * and support it has to maintain runtime compatibility.
+     *
+     * When a new bit is added in a minor or update release, make sure
+     * the new bit is also added in the main/baseline.
+     */
+    unsigned int is_attach_supported : 1;
+    unsigned int is_kernel_jvm : 1;
+    unsigned int : 30;
+    unsigned int : 32;
+    unsigned int : 32;
+} jvm_version_info;
+
+#define JVM_VERSION_MAJOR(version) ((version & 0xFF000000) >> 24)
+#define JVM_VERSION_MINOR(version) ((version & 0x00FF0000) >> 16)
+#define JVM_VERSION_MICRO(version) ((version & 0x0000FF00) >> 8)
+
+/* Build number is available only for RE builds.
+ * It will be zero for internal builds.
+ */
+#define JVM_VERSION_BUILD(version) ((version & 0x000000FF))
+
+JNIEXPORT void JNICALL
+JVM_GetVersionInfo(JNIEnv* env, jvm_version_info* info, size_t info_size);
+
+typedef struct {
+    // Naming convention of RE build version string: n.n.n[_uu[c]][-<identifier>]-bxx
+    unsigned int jdk_version;   /* Consists of major, minor, micro (n.n.n) */
+                                /* and build number (xx) */
+    unsigned int update_version : 8;         /* Update release version (uu) */
+    unsigned int special_update_version : 8; /* Special update release version (c)*/
+    unsigned int reserved1 : 16;
+    unsigned int reserved2;
+
+    /* The following bits represents new JDK supports that VM has dependency on.
+     * VM implementation can use these bits to determine which JDK version
+     * and support it has to maintain runtime compatibility.
+     *
+     * When a new bit is added in a minor or update release, make sure
+     * the new bit is also added in the main/baseline.
+     */
+    unsigned int thread_park_blocker : 1;
+    unsigned int post_vm_init_hook_enabled : 1;
+    unsigned int : 30;
+    unsigned int : 32;
+    unsigned int : 32;
+} jdk_version_info;
+
+#define JDK_VERSION_MAJOR(version) ((version & 0xFF000000) >> 24)
+#define JDK_VERSION_MINOR(version) ((version & 0x00FF0000) >> 16)
+#define JDK_VERSION_MICRO(version) ((version & 0x0000FF00) >> 8)
+
+/* Build number is available only for RE build (i.e. JDK_BUILD_NUMBER is set to bNN)
+ * It will be zero for internal builds.
+ */
+#define JDK_VERSION_BUILD(version) ((version & 0x000000FF))
+
+/*
+ * This is the function JDK_GetVersionInfo0 defined in libjava.so
+ * that is dynamically looked up by JVM.
+ */
+typedef void (*jdk_version_info_fn_t)(jdk_version_info* info, size_t info_size);
+
+/*
+ * This structure is used by the launcher to get the default thread
+ * stack size from the VM using JNI_GetDefaultJavaVMInitArgs() with a
+ * version of 1.1.  As it is not supported otherwise, it has been removed
+ * from jni.h
+ */
+typedef struct JDK1_1InitArgs {
+    jint version;
+
+    char **properties;
+    jint checkSource;
+    jint nativeStackSize;
+    jint javaStackSize;
+    jint minHeapSize;
+    jint maxHeapSize;
+    jint verifyMode;
+    char *classpath;
+
+    jint (JNICALL *vfprintf)(FILE *fp, const char *format, va_list args);
+    void (JNICALL *exit)(jint code);
+    void (JNICALL *abort)(void);
+
+    jint enableClassGC;
+    jint enableVerboseGC;
+    jint disableAsyncGC;
+    jint verbose;
+    jboolean debugging;
+    jint debugPort;
+} JDK1_1InitArgs;
+
+
+#ifdef __cplusplus
+} /* extern "C" */
+
+#endif /* __cplusplus */
+
+#endif /* !_JAVASOFT_JVM_H_ */
diff --git a/ojluni/src/main/native/jvm_md.h b/ojluni/src/main/native/jvm_md.h
new file mode 100755
index 0000000..390e89c
--- /dev/null
+++ b/ojluni/src/main/native/jvm_md.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#ifndef _JAVASOFT_JVM_MD_H_
+#define _JAVASOFT_JVM_MD_H_
+
+/*
+ * This file is currently collecting system-specific dregs for the
+ * JNI conversion, which should be sorted out later.
+ */
+
+#include <dirent.h>             /* For DIR */
+#include <sys/param.h>          /* For MAXPATHLEN */
+#include <unistd.h>             /* For F_OK, R_OK, W_OK */
+#include <stddef.h>             /* For ptrdiff_t */
+#include <stdint.h>             /* For uintptr_t */
+
+#define JNI_ONLOAD_SYMBOLS   {"JNI_OnLoad"}
+#define JNI_ONUNLOAD_SYMBOLS {"JNI_OnUnload"}
+
+#define JNI_LIB_PREFIX "lib"
+#ifdef __APPLE__
+#define JNI_LIB_SUFFIX ".dylib"
+#define VERSIONED_JNI_LIB_NAME(NAME, VERSION) JNI_LIB_PREFIX NAME "." VERSION JNI_LIB_SUFFIX
+#else
+#define JNI_LIB_SUFFIX ".so"
+#define VERSIONED_JNI_LIB_NAME(NAME, VERSION) JNI_LIB_PREFIX NAME JNI_LIB_SUFFIX "." VERSION
+#endif
+#define JNI_LIB_NAME(NAME) JNI_LIB_PREFIX NAME JNI_LIB_SUFFIX
+
+#define JVM_MAXPATHLEN MAXPATHLEN
+
+#define JVM_R_OK    R_OK
+#define JVM_W_OK    W_OK
+#define JVM_X_OK    X_OK
+#define JVM_F_OK    F_OK
+
+/*
+ * File I/O
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/signal.h>
+
+/* O Flags */
+
+#define JVM_O_RDONLY     O_RDONLY
+#define JVM_O_WRONLY     O_WRONLY
+#define JVM_O_RDWR       O_RDWR
+#define JVM_O_O_APPEND   O_APPEND
+#define JVM_O_EXCL       O_EXCL
+#define JVM_O_CREAT      O_CREAT
+#define JVM_O_DELETE     0x10000
+
+/* Signals */
+
+#define JVM_SIGINT     SIGINT
+#define JVM_SIGTERM    SIGTERM
+
+
+#endif /* !_JAVASOFT_JVM_MD_H_ */
diff --git a/ojluni/src/main/native/linux_close.c b/ojluni/src/main/native/linux_close.c
new file mode 100755
index 0000000..5665e85
--- /dev/null
+++ b/ojluni/src/main/native/linux_close.c
@@ -0,0 +1,385 @@
+/*
+ * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <pthread.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <sys/uio.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include <sys/poll.h>
+
+/*
+ * Stack allocated by thread when doing blocking operation
+ */
+typedef struct threadEntry {
+    pthread_t thr;                      /* this thread */
+    struct threadEntry *next;           /* next thread */
+    int intr;                           /* interrupted */
+} threadEntry_t;
+
+/*
+ * Heap allocated during initialized - one entry per fd
+ */
+typedef struct {
+    pthread_mutex_t lock;               /* fd lock */
+    threadEntry_t *threads;             /* threads blocked on fd */
+} fdEntry_t;
+
+/*
+ * Signal to unblock thread
+ */
+static int sigWakeup = (__SIGRTMAX - 2);
+
+/*
+ * The fd table and the number of file descriptors
+ */
+static fdEntry_t *fdTable;
+static int fdCount;
+
+/*
+ * Null signal handler
+ */
+static void sig_wakeup(int sig) {
+}
+
+/*
+ * Initialization routine (executed when library is loaded)
+ * Allocate fd tables and sets up signal handler.
+ */
+static void __attribute((constructor)) init() {
+    struct rlimit nbr_files;
+    sigset_t sigset;
+    struct sigaction sa;
+
+    /*
+     * Allocate table based on the maximum number of
+     * file descriptors.
+     */
+    getrlimit(RLIMIT_NOFILE, &nbr_files);
+    fdCount = nbr_files.rlim_max;
+    fdTable = (fdEntry_t *)calloc(fdCount, sizeof(fdEntry_t));
+    if (fdTable == NULL) {
+        fprintf(stderr, "library initialization failed - "
+                "unable to allocate file descriptor table - out of memory");
+        abort();
+    }
+
+    /*
+     * Setup the signal handler
+     */
+    sa.sa_handler = sig_wakeup;
+    sa.sa_flags   = 0;
+    sigemptyset(&sa.sa_mask);
+    sigaction(sigWakeup, &sa, NULL);
+
+    sigemptyset(&sigset);
+    sigaddset(&sigset, sigWakeup);
+    sigprocmask(SIG_UNBLOCK, &sigset, NULL);
+}
+
+/*
+ * Return the fd table for this fd or NULL is fd out
+ * of range.
+ */
+static inline fdEntry_t *getFdEntry(int fd)
+{
+    if (fd < 0 || fd >= fdCount) {
+        return NULL;
+    }
+    return &fdTable[fd];
+}
+
+/*
+ * Start a blocking operation :-
+ *    Insert thread onto thread list for the fd.
+ */
+static inline void startOp(fdEntry_t *fdEntry, threadEntry_t *self)
+{
+    self->thr = pthread_self();
+    self->intr = 0;
+
+    pthread_mutex_lock(&(fdEntry->lock));
+    {
+        self->next = fdEntry->threads;
+        fdEntry->threads = self;
+    }
+    pthread_mutex_unlock(&(fdEntry->lock));
+}
+
+/*
+ * End a blocking operation :-
+ *     Remove thread from thread list for the fd
+ *     If fd has been interrupted then set errno to EBADF
+ */
+static inline void endOp
+    (fdEntry_t *fdEntry, threadEntry_t *self)
+{
+    int orig_errno = errno;
+    pthread_mutex_lock(&(fdEntry->lock));
+    {
+        threadEntry_t *curr, *prev=NULL;
+        curr = fdEntry->threads;
+        while (curr != NULL) {
+            if (curr == self) {
+                if (curr->intr) {
+                    orig_errno = EBADF;
+                }
+                if (prev == NULL) {
+                    fdEntry->threads = curr->next;
+                } else {
+                    prev->next = curr->next;
+                }
+                break;
+            }
+            prev = curr;
+            curr = curr->next;
+        }
+    }
+    pthread_mutex_unlock(&(fdEntry->lock));
+    errno = orig_errno;
+}
+
+/*
+ * Close or dup2 a file descriptor ensuring that all threads blocked on
+ * the file descriptor are notified via a wakeup signal.
+ *
+ *      fd1 < 0    => close(fd2)
+ *      fd1 >= 0   => dup2(fd1, fd2)
+ *
+ * Returns -1 with errno set if operation fails.
+ */
+static int closefd(int fd1, int fd2) {
+    int rv, orig_errno;
+    fdEntry_t *fdEntry = getFdEntry(fd2);
+    if (fdEntry == NULL) {
+        errno = EBADF;
+        return -1;
+    }
+
+    /*
+     * Lock the fd to hold-off additional I/O on this fd.
+     */
+    pthread_mutex_lock(&(fdEntry->lock));
+
+    {
+        /*
+         * Send a wakeup signal to all threads blocked on this
+         * file descriptor.
+         */
+        threadEntry_t *curr = fdEntry->threads;
+        while (curr != NULL) {
+            curr->intr = 1;
+            pthread_kill( curr->thr, sigWakeup );
+            curr = curr->next;
+        }
+
+        /*
+         * And close/dup the file descriptor
+         * (restart if interrupted by signal)
+         */
+        do {
+            if (fd1 < 0) {
+                rv = close(fd2);
+            } else {
+                rv = dup2(fd1, fd2);
+            }
+        } while (rv == -1 && errno == EINTR);
+
+    }
+
+    /*
+     * Unlock without destroying errno
+     */
+    orig_errno = errno;
+    pthread_mutex_unlock(&(fdEntry->lock));
+    errno = orig_errno;
+
+    return rv;
+}
+
+/*
+ * Wrapper for dup2 - same semantics as dup2 system call except
+ * that any threads blocked in an I/O system call on fd2 will be
+ * preempted and return -1/EBADF;
+ */
+int NET_Dup2(int fd, int fd2) {
+    if (fd < 0) {
+        errno = EBADF;
+        return -1;
+    }
+    return closefd(fd, fd2);
+}
+
+/*
+ * Wrapper for close - same semantics as close system call
+ * except that any threads blocked in an I/O on fd will be
+ * preempted and the I/O system call will return -1/EBADF.
+ */
+int NET_SocketClose(int fd) {
+    return closefd(-1, fd);
+}
+
+/************** Basic I/O operations here ***************/
+
+/*
+ * Macro to perform a blocking IO operation. Restarts
+ * automatically if interrupted by signal (other than
+ * our wakeup signal)
+ */
+#define BLOCKING_IO_RETURN_INT(FD, FUNC) {      \
+    int ret;                                    \
+    threadEntry_t self;                         \
+    fdEntry_t *fdEntry = getFdEntry(FD);        \
+    if (fdEntry == NULL) {                      \
+        errno = EBADF;                          \
+        return -1;                              \
+    }                                           \
+    do {                                        \
+        startOp(fdEntry, &self);                \
+        ret = FUNC;                             \
+        endOp(fdEntry, &self);                  \
+    } while (ret == -1 && errno == EINTR);      \
+    return ret;                                 \
+}
+
+int NET_Read(int s, void* buf, size_t len) {
+    BLOCKING_IO_RETURN_INT( s, recv(s, buf, len, 0) );
+}
+
+int NET_ReadV(int s, const struct iovec * vector, int count) {
+    BLOCKING_IO_RETURN_INT( s, readv(s, vector, count) );
+}
+
+int NET_RecvFrom(int s, void *buf, int len, unsigned int flags,
+       struct sockaddr *from, int *fromlen) {
+    socklen_t socklen = *fromlen;
+    BLOCKING_IO_RETURN_INT( s, recvfrom(s, buf, len, flags, from, &socklen) );
+    *fromlen = socklen;
+}
+
+int NET_Send(int s, void *msg, int len, unsigned int flags) {
+    BLOCKING_IO_RETURN_INT( s, send(s, msg, len, flags) );
+}
+
+int NET_WriteV(int s, const struct iovec * vector, int count) {
+    BLOCKING_IO_RETURN_INT( s, writev(s, vector, count) );
+}
+
+int NET_SendTo(int s, const void *msg, int len,  unsigned  int
+       flags, const struct sockaddr *to, int tolen) {
+    BLOCKING_IO_RETURN_INT( s, sendto(s, msg, len, flags, to, tolen) );
+}
+
+int NET_Accept(int s, struct sockaddr *addr, int *addrlen) {
+    socklen_t socklen = *addrlen;
+    BLOCKING_IO_RETURN_INT( s, accept(s, addr, &socklen) );
+    *addrlen = socklen;
+}
+
+int NET_Connect(int s, struct sockaddr *addr, int addrlen) {
+    BLOCKING_IO_RETURN_INT( s, connect(s, addr, addrlen) );
+}
+
+#ifndef USE_SELECT
+int NET_Poll(struct pollfd *ufds, unsigned int nfds, int timeout) {
+    BLOCKING_IO_RETURN_INT( ufds[0].fd, poll(ufds, nfds, timeout) );
+}
+#else
+int NET_Select(int s, fd_set *readfds, fd_set *writefds,
+               fd_set *exceptfds, struct timeval *timeout) {
+    BLOCKING_IO_RETURN_INT( s-1,
+                            select(s, readfds, writefds, exceptfds, timeout) );
+}
+#endif
+
+/*
+ * Wrapper for poll(s, timeout).
+ * Auto restarts with adjusted timeout if interrupted by
+ * signal other than our wakeup signal.
+ */
+int NET_Timeout(int s, long timeout) {
+    long prevtime = 0, newtime;
+    struct timeval t;
+    fdEntry_t *fdEntry = getFdEntry(s);
+
+    /*
+     * Check that fd hasn't been closed.
+     */
+    if (fdEntry == NULL) {
+        errno = EBADF;
+        return -1;
+    }
+
+    /*
+     * Pick up current time as may need to adjust timeout
+     */
+    if (timeout > 0) {
+        gettimeofday(&t, NULL);
+        prevtime = t.tv_sec * 1000  +  t.tv_usec / 1000;
+    }
+
+    for(;;) {
+        struct pollfd pfd;
+        int rv;
+        threadEntry_t self;
+
+        /*
+         * Poll the fd. If interrupted by our wakeup signal
+         * errno will be set to EBADF.
+         */
+        pfd.fd = s;
+        pfd.events = POLLIN | POLLERR;
+
+        startOp(fdEntry, &self);
+        rv = poll(&pfd, 1, timeout);
+        endOp(fdEntry, &self);
+
+        /*
+         * If interrupted then adjust timeout. If timeout
+         * has expired return 0 (indicating timeout expired).
+         */
+        if (rv < 0 && errno == EINTR) {
+            if (timeout > 0) {
+                gettimeofday(&t, NULL);
+                newtime = t.tv_sec * 1000  +  t.tv_usec / 1000;
+                timeout -= newtime - prevtime;
+                if (timeout <= 0) {
+                    return 0;
+                }
+                prevtime = newtime;
+            }
+        } else {
+            return rv;
+        }
+
+    }
+}
diff --git a/ojluni/src/main/native/net_util.c b/ojluni/src/main/native/net_util.c
new file mode 100755
index 0000000..2f99a34
--- /dev/null
+++ b/ojluni/src/main/native/net_util.c
@@ -0,0 +1,298 @@
+/*
+ * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include "jni.h"
+#include "jvm.h"
+#include "jni_util.h"
+#include "net_util.h"
+
+int IPv6_supported() ;
+
+static int IPv6_available;
+
+JNIEXPORT jint JNICALL ipv6_available()
+{
+    return IPv6_available ;
+}
+
+JNIEXPORT jint JNICALL
+JNI_OnLoad(JavaVM *vm, void *reserved)
+{
+    JNIEnv *env;
+    jclass iCls;
+    jmethodID mid;
+    jstring s;
+    jint preferIPv4Stack;
+
+    if ((*vm)->GetEnv(vm, (void **)&env, JNI_VERSION_1_2) == JNI_OK) {
+        if (JVM_InitializeSocketLibrary() < 0) {
+            JNU_ThrowByName(env, "java/lang/UnsatisfiedLinkError",
+                            "failed to initialize net library.");
+            return JNI_VERSION_1_2;
+        }
+    }
+    iCls = (*env)->FindClass(env, "java/lang/Boolean");
+    CHECK_NULL_RETURN(iCls, JNI_VERSION_1_2);
+    mid = (*env)->GetStaticMethodID(env, iCls, "getBoolean", "(Ljava/lang/String;)Z");
+    CHECK_NULL_RETURN(mid, JNI_VERSION_1_2);
+    s = (*env)->NewStringUTF(env, "java.net.preferIPv4Stack");
+    CHECK_NULL_RETURN(s, JNI_VERSION_1_2);
+    preferIPv4Stack = (*env)->CallStaticBooleanMethod(env, iCls, mid, s);
+
+    /*
+       Since we have initialized and loaded the Socket library we will
+       check now to whether we have IPv6 on this platform and if the
+       supporting socket APIs are available
+    */
+    IPv6_available = IPv6_supported() & (!preferIPv4Stack);
+    initLocalAddrTable ();
+    parseExclusiveBindProperty(env);
+
+    return JNI_VERSION_1_2;
+}
+
+static int initialized = 0;
+
+static void initInetAddrs(JNIEnv *env) {
+    if (!initialized) {
+        Java_java_net_InetAddress_init(env, 0);
+        Java_java_net_Inet4Address_init(env, 0);
+        Java_java_net_Inet6Address_init(env, 0);
+        initialized = 1;
+    }
+}
+
+/* The address, and family fields used to be in InetAddress
+ * but are now in an implementation object. So, there is an extra
+ * level of indirection to access them now.
+ */
+
+extern jclass iac_class;
+extern jfieldID ia_holderID;
+extern jfieldID iac_addressID;
+extern jfieldID iac_familyID;
+
+void setInetAddress_addr(JNIEnv *env, jobject iaObj, int address) {
+    jobject holder;
+    initInetAddrs(env);
+    holder = (*env)->GetObjectField(env, iaObj, ia_holderID);
+    (*env)->SetIntField(env, holder, iac_addressID, address);
+}
+
+void setInetAddress_family(JNIEnv *env, jobject iaObj, int family) {
+    jobject holder;
+    initInetAddrs(env);
+    holder = (*env)->GetObjectField(env, iaObj, ia_holderID);
+    (*env)->SetIntField(env, holder, iac_familyID, family);
+}
+
+void setInetAddress_hostName(JNIEnv *env, jobject iaObj, jobject host) {
+    jobject holder;
+    initInetAddrs(env);
+    holder = (*env)->GetObjectField(env, iaObj, ia_holderID);
+    (*env)->SetObjectField(env, holder, iac_hostNameID, host);
+}
+
+int getInetAddress_addr(JNIEnv *env, jobject iaObj) {
+    jobject holder;
+    initInetAddrs(env);
+    holder = (*env)->GetObjectField(env, iaObj, ia_holderID);
+    return (*env)->GetIntField(env, holder, iac_addressID);
+}
+
+int getInetAddress_family(JNIEnv *env, jobject iaObj) {
+    jobject holder;
+
+    initInetAddrs(env);
+    holder = (*env)->GetObjectField(env, iaObj, ia_holderID);
+    return (*env)->GetIntField(env, holder, iac_familyID);
+}
+
+jobject getInetAddress_hostName(JNIEnv *env, jobject iaObj) {
+    jobject holder;
+    initInetAddrs(env);
+    holder = (*env)->GetObjectField(env, iaObj, ia_holderID);
+    return (*env)->GetObjectField(env, holder, iac_hostNameID);
+}
+
+JNIEXPORT jobject JNICALL
+NET_SockaddrToInetAddress(JNIEnv *env, struct sockaddr *him, int *port) {
+    jobject iaObj;
+    initInetAddrs(env);
+#ifdef AF_INET6
+    if (him->sa_family == AF_INET6) {
+        jbyteArray ipaddress;
+#ifdef WIN32
+        struct SOCKADDR_IN6 *him6 = (struct SOCKADDR_IN6 *)him;
+#else
+        struct sockaddr_in6 *him6 = (struct sockaddr_in6 *)him;
+#endif
+        jbyte *caddr = (jbyte *)&(him6->sin6_addr);
+        if (NET_IsIPv4Mapped(caddr)) {
+            int address;
+            static jclass inet4Cls = 0;
+            if (inet4Cls == 0) {
+                jclass c = (*env)->FindClass(env, "java/net/Inet4Address");
+                CHECK_NULL_RETURN(c, NULL);
+                inet4Cls = (*env)->NewGlobalRef(env, c);
+                CHECK_NULL_RETURN(inet4Cls, NULL);
+                (*env)->DeleteLocalRef(env, c);
+            }
+            iaObj = (*env)->NewObject(env, inet4Cls, ia4_ctrID);
+            CHECK_NULL_RETURN(iaObj, NULL);
+            address = NET_IPv4MappedToIPv4(caddr);
+            setInetAddress_addr(env, iaObj, address);
+            setInetAddress_family(env, iaObj, IPv4);
+        } else {
+            static jclass inet6Cls = 0;
+            jint scope;
+            if (inet6Cls == 0) {
+                jclass c = (*env)->FindClass(env, "java/net/Inet6Address");
+                CHECK_NULL_RETURN(c, NULL);
+                inet6Cls = (*env)->NewGlobalRef(env, c);
+                CHECK_NULL_RETURN(inet6Cls, NULL);
+                (*env)->DeleteLocalRef(env, c);
+            }
+            iaObj = (*env)->NewObject(env, inet6Cls, ia6_ctrID);
+            CHECK_NULL_RETURN(iaObj, NULL);
+            ipaddress = (*env)->NewByteArray(env, 16);
+            CHECK_NULL_RETURN(ipaddress, NULL);
+            (*env)->SetByteArrayRegion(env, ipaddress, 0, 16,
+                                       (jbyte *)&(him6->sin6_addr));
+
+            (*env)->SetObjectField(env, iaObj, ia6_ipaddressID, ipaddress);
+
+            setInetAddress_family(env, iaObj, IPv6);
+            scope = getScopeID(him);
+            (*env)->SetIntField(env, iaObj, ia6_scopeidID, scope);
+            if (scope > 0)
+                (*env)->SetBooleanField(env, iaObj, ia6_scopeidsetID, JNI_TRUE);
+        }
+        *port = ntohs(him6->sin6_port);
+    } else
+#endif /* AF_INET6 */
+        {
+            struct sockaddr_in *him4 = (struct sockaddr_in *)him;
+            static jclass inet4Cls = 0;
+
+            if (inet4Cls == 0) {
+                jclass c = (*env)->FindClass(env, "java/net/Inet4Address");
+                CHECK_NULL_RETURN(c, NULL);
+                inet4Cls = (*env)->NewGlobalRef(env, c);
+                CHECK_NULL_RETURN(inet4Cls, NULL);
+                (*env)->DeleteLocalRef(env, c);
+            }
+            iaObj = (*env)->NewObject(env, inet4Cls, ia4_ctrID);
+            CHECK_NULL_RETURN(iaObj, NULL);
+            setInetAddress_family(env, iaObj, IPv4);
+            setInetAddress_addr(env, iaObj, ntohl(him4->sin_addr.s_addr));
+            *port = ntohs(him4->sin_port);
+        }
+    return iaObj;
+}
+
+JNIEXPORT jint JNICALL
+NET_SockaddrEqualsInetAddress(JNIEnv *env, struct sockaddr *him, jobject iaObj)
+{
+    jint family = AF_INET;
+
+#ifdef AF_INET6
+    family = getInetAddress_family(env, iaObj) == IPv4? AF_INET : AF_INET6;
+    if (him->sa_family == AF_INET6) {
+#ifdef WIN32
+        struct SOCKADDR_IN6 *him6 = (struct SOCKADDR_IN6 *)him;
+#else
+        struct sockaddr_in6 *him6 = (struct sockaddr_in6 *)him;
+#endif
+        jbyte *caddrNew = (jbyte *)&(him6->sin6_addr);
+        if (NET_IsIPv4Mapped(caddrNew)) {
+            int addrNew;
+            int addrCur;
+            if (family == AF_INET6) {
+                return JNI_FALSE;
+            }
+            addrNew = NET_IPv4MappedToIPv4(caddrNew);
+            addrCur = getInetAddress_addr(env, iaObj);
+            if (addrNew == addrCur) {
+                return JNI_TRUE;
+            } else {
+                return JNI_FALSE;
+            }
+        } else {
+            jbyteArray ipaddress;
+            jbyte caddrCur[16];
+            int scope;
+
+            if (family == AF_INET) {
+                return JNI_FALSE;
+            }
+            ipaddress = (*env)->GetObjectField(env, iaObj, ia6_ipaddressID);
+            scope = (*env)->GetIntField(env, iaObj, ia6_scopeidID);
+            (*env)->GetByteArrayRegion(env, ipaddress, 0, 16, caddrCur);
+            if (NET_IsEqual(caddrNew, caddrCur) && cmpScopeID(scope, him)) {
+                return JNI_TRUE;
+            } else {
+                return JNI_FALSE;
+            }
+        }
+    } else
+#endif /* AF_INET6 */
+        {
+            struct sockaddr_in *him4 = (struct sockaddr_in *)him;
+            int addrNew, addrCur;
+            if (family != AF_INET) {
+                return JNI_FALSE;
+            }
+            addrNew = ntohl(him4->sin_addr.s_addr);
+            addrCur = getInetAddress_addr(env, iaObj);
+            if (addrNew == addrCur) {
+                return JNI_TRUE;
+            } else {
+                return JNI_FALSE;
+            }
+        }
+}
+
+unsigned short
+in_cksum(unsigned short *addr, int len) {
+    int nleft = len;
+    int sum = 0;
+    unsigned short *w = addr;
+    unsigned short answer = 0;
+    while(nleft > 1) {
+        sum += *w++;
+        nleft -= 2;
+    }
+
+    if (nleft == 1) {
+        *(unsigned char *) (&answer) = *(unsigned char *)w;
+        sum += answer;
+    }
+
+    sum = (sum >> 16) + (sum & 0xffff);
+    sum += (sum >> 16);
+    answer = ~sum;
+    return (answer);
+}
diff --git a/ojluni/src/main/native/net_util.h b/ojluni/src/main/native/net_util.h
new file mode 100755
index 0000000..604c83d
--- /dev/null
+++ b/ojluni/src/main/native/net_util.h
@@ -0,0 +1,180 @@
+/*
+ * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#ifndef NET_UTILS_H
+#define NET_UTILS_H
+
+#include "jvm.h"
+#include "jni_util.h"
+#include "net_util_md.h"
+
+/************************************************************************
+ * Macros and misc constants
+ */
+
+#define MAX_PACKET_LEN 65536
+
+#define IPv4 1
+#define IPv6 2
+
+#define NET_ERROR(env, ex, msg) \
+{ if (!(*env)->ExceptionOccurred(env)) JNU_ThrowByName(env, ex, msg) }
+
+#define CHECK_NULL(x) if ((x) == NULL) return;
+#define CHECK_NULL_RETURN(x, y) if ((x) == NULL) return y;
+
+/************************************************************************
+ * Cached field IDs
+ *
+ * The naming convention for field IDs is
+ *      <class abbrv>_<fieldName>ID
+ * i.e. psi_timeoutID is PlainSocketImpl's timeout field's ID.
+ */
+extern jclass ia_class;
+extern jfieldID iac_addressID;
+extern jfieldID iac_familyID;
+extern jfieldID iac_hostNameID;
+extern jfieldID ia_preferIPv6AddressID;
+
+extern void setInetAddress_addr(JNIEnv *env, jobject iaObj, int address);
+extern void setInetAddress_family(JNIEnv *env, jobject iaObj, int family);
+extern void setInetAddress_hostName(JNIEnv *env, jobject iaObj, jobject h);
+extern int getInetAddress_addr(JNIEnv *env, jobject iaObj);
+extern int getInetAddress_family(JNIEnv *env, jobject iaObj);
+extern jobject getInetAddress_hostName(JNIEnv *env, jobject iaObj);
+
+extern jclass ia4_class;
+extern jmethodID ia4_ctrID;
+
+/* NetworkInterface fields */
+extern jclass ni_class;
+extern jfieldID ni_nameID;
+extern jfieldID ni_indexID;
+extern jfieldID ni_addrsID;
+extern jfieldID ni_descID;
+extern jmethodID ni_ctrID;
+
+/* PlainSocketImpl fields */
+extern jfieldID psi_timeoutID;
+extern jfieldID psi_fdID;
+extern jfieldID psi_addressID;
+extern jfieldID psi_portID;
+extern jfieldID psi_localportID;
+
+/* DatagramPacket fields */
+extern jfieldID dp_addressID;
+extern jfieldID dp_portID;
+extern jfieldID dp_bufID;
+extern jfieldID dp_offsetID;
+extern jfieldID dp_lengthID;
+extern jfieldID dp_bufLengthID;
+
+/* Inet6Address fields */
+extern jclass ia6_class;
+extern jfieldID ia6_ipaddressID;
+extern jfieldID ia6_scopeidID;
+extern jfieldID ia6_cachedscopeidID;
+extern jfieldID ia6_scopeidsetID;
+extern jfieldID ia6_scopeifnameID;
+extern jfieldID ia6_scopeifnamesetID;
+extern jmethodID ia6_ctrID;
+
+/************************************************************************
+ *  Utilities
+ */
+JNIEXPORT void JNICALL Java_java_net_InetAddress_init(JNIEnv *env, jclass cls);
+JNIEXPORT void JNICALL Java_java_net_Inet4Address_init(JNIEnv *env, jclass cls);
+JNIEXPORT void JNICALL Java_java_net_Inet6Address_init(JNIEnv *env, jclass cls);
+JNIEXPORT void JNICALL Java_java_net_NetworkInterface_init(JNIEnv *env, jclass cls);
+
+JNIEXPORT void JNICALL NET_ThrowNew(JNIEnv *env, int errorNum, char *msg);
+int NET_GetError();
+
+void NET_ThrowCurrent(JNIEnv *env, char *msg);
+
+jfieldID NET_GetFileDescriptorID(JNIEnv *env);
+
+JNIEXPORT jint JNICALL ipv6_available();
+
+void
+NET_AllocSockaddr(struct sockaddr **him, int *len);
+
+JNIEXPORT int JNICALL
+NET_InetAddressToSockaddr(JNIEnv *env, jobject iaObj, int port, struct sockaddr *him, int *len, jboolean v4MappedAddress);
+
+JNIEXPORT jobject JNICALL
+NET_SockaddrToInetAddress(JNIEnv *env, struct sockaddr *him, int *port);
+
+void initLocalAddrTable ();
+void parseExclusiveBindProperty(JNIEnv *env);
+
+void
+NET_SetTrafficClass(struct sockaddr *him, int trafficClass);
+
+JNIEXPORT jint JNICALL
+NET_GetPortFromSockaddr(struct sockaddr *him);
+
+JNIEXPORT jint JNICALL
+NET_SockaddrEqualsInetAddress(JNIEnv *env,struct sockaddr *him, jobject iaObj);
+
+int
+NET_IsIPv4Mapped(jbyte* caddr);
+
+int
+NET_IPv4MappedToIPv4(jbyte* caddr);
+
+int
+NET_IsEqual(jbyte* caddr1, jbyte* caddr2);
+
+int
+NET_IsZeroAddr(jbyte* caddr);
+
+/* Socket operations
+ *
+ * These work just like the JVM_* procedures, except that they may do some
+ * platform-specific pre/post processing of the arguments and/or results.
+ */
+
+JNIEXPORT int JNICALL
+NET_GetSockOpt(int fd, int level, int opt, void *result, int *len);
+
+JNIEXPORT int JNICALL
+NET_SetSockOpt(int fd, int level, int opt, const void *arg, int len);
+
+JNIEXPORT int JNICALL
+NET_Bind(int fd, struct sockaddr *him, int len);
+
+JNIEXPORT int JNICALL
+NET_MapSocketOption(jint cmd, int *level, int *optname);
+
+JNIEXPORT int JNICALL
+NET_MapSocketOptionV6(jint cmd, int *level, int *optname);
+
+int getScopeID (struct sockaddr *);
+
+int cmpScopeID (unsigned int, struct sockaddr *);
+
+unsigned short in_cksum(unsigned short *addr, int len);
+#endif /* NET_UTILS_H */
diff --git a/ojluni/src/main/native/net_util_md.c b/ojluni/src/main/native/net_util_md.c
new file mode 100755
index 0000000..84b3156
--- /dev/null
+++ b/ojluni/src/main/native/net_util_md.c
@@ -0,0 +1,1697 @@
+/*
+ * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include <errno.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/tcp.h>        /* Defines TCP_NODELAY, needed for 2.6 */
+#include <netinet/in.h>
+#include <net/if.h>
+#include <netdb.h>
+#include <stdlib.h>
+#include <dlfcn.h>
+
+#ifndef _ALLBSD_SOURCE
+#include <values.h>
+#else
+#include <limits.h>
+#include <sys/param.h>
+#include <sys/sysctl.h>
+#ifndef MAXINT
+#define MAXINT INT_MAX
+#endif
+#endif
+
+#ifdef __solaris__
+#include <sys/sockio.h>
+#include <stropts.h>
+#include <inet/nd.h>
+#endif
+
+#ifdef __linux__
+#include <arpa/inet.h>
+#include <net/route.h>
+#include <sys/utsname.h>
+
+#ifndef IPV6_FLOWINFO_SEND
+#define IPV6_FLOWINFO_SEND      33
+#endif
+
+#endif
+
+#include "jni_util.h"
+#include "jvm.h"
+#include "net_util.h"
+
+#include "java_net_SocketOptions.h"
+
+/* needed from libsocket on Solaris 8 */
+
+getaddrinfo_f getaddrinfo_ptr = NULL;
+freeaddrinfo_f freeaddrinfo_ptr = NULL;
+gai_strerror_f gai_strerror_ptr = NULL;
+getnameinfo_f getnameinfo_ptr = NULL;
+
+/*
+ * EXCLBIND socket options only on Solaris
+ */
+#if defined(__solaris__) && !defined(TCP_EXCLBIND)
+#define TCP_EXCLBIND            0x21
+#endif
+#if defined(__solaris__) && !defined(UDP_EXCLBIND)
+#define UDP_EXCLBIND            0x0101
+#endif
+
+void setDefaultScopeID(JNIEnv *env, struct sockaddr *him)
+{
+#ifdef MACOSX
+    static jclass ni_class = NULL;
+    static jfieldID ni_defaultIndexID;
+    if (ni_class == NULL) {
+        jclass c = (*env)->FindClass(env, "java/net/NetworkInterface");
+        CHECK_NULL(c);
+        c = (*env)->NewGlobalRef(env, c);
+        CHECK_NULL(c);
+        ni_defaultIndexID = (*env)->GetStaticFieldID(
+            env, c, "defaultIndex", "I");
+        ni_class = c;
+    }
+    int defaultIndex;
+    struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)him;
+    if (sin6->sin6_family == AF_INET6 && (sin6->sin6_scope_id == 0)) {
+        defaultIndex = (*env)->GetStaticIntField(env, ni_class,
+                                                 ni_defaultIndexID);
+        sin6->sin6_scope_id = defaultIndex;
+    }
+#endif
+}
+
+int getDefaultScopeID(JNIEnv *env) {
+    static jclass ni_class = NULL;
+    static jfieldID ni_defaultIndexID;
+    if (ni_class == NULL) {
+        jclass c = (*env)->FindClass(env, "java/net/NetworkInterface");
+        CHECK_NULL(c);
+        c = (*env)->NewGlobalRef(env, c);
+        CHECK_NULL(c);
+        ni_defaultIndexID = (*env)->GetStaticFieldID(
+            env, c, "defaultIndex", "I");
+        ni_class = c;
+    }
+    int defaultIndex = 0;
+    defaultIndex = (*env)->GetStaticIntField(env, ni_class,
+                                                 ni_defaultIndexID);
+    return defaultIndex;
+}
+
+#ifdef __solaris__
+static int init_tcp_max_buf, init_udp_max_buf;
+static int tcp_max_buf;
+static int udp_max_buf;
+static int useExclBind = 0;
+
+/*
+ * Get the specified parameter from the specified driver. The value
+ * of the parameter is assumed to be an 'int'. If the parameter
+ * cannot be obtained return -1
+ */
+static int
+getParam(char *driver, char *param)
+{
+    struct strioctl stri;
+    char buf [64];
+    int s;
+    int value;
+
+    s = open (driver, O_RDWR);
+    if (s < 0) {
+        return -1;
+    }
+    strncpy (buf, param, sizeof(buf));
+    stri.ic_cmd = ND_GET;
+    stri.ic_timout = 0;
+    stri.ic_dp = buf;
+    stri.ic_len = sizeof(buf);
+    if (ioctl (s, I_STR, &stri) < 0) {
+        value = -1;
+    } else {
+        value = atoi(buf);
+    }
+    close (s);
+    return value;
+}
+
+/*
+ * Iterative way to find the max value that SO_SNDBUF or SO_RCVBUF
+ * for Solaris versions that do not support the ioctl() in getParam().
+ * Ugly, but only called once (for each sotype).
+ *
+ * As an optimisation, we make a guess using the default values for Solaris
+ * assuming they haven't been modified with ndd.
+ */
+
+#define MAX_TCP_GUESS 1024 * 1024
+#define MAX_UDP_GUESS 2 * 1024 * 1024
+
+#define FAIL_IF_NOT_ENOBUFS if (errno != ENOBUFS) return -1
+
+static int findMaxBuf(int fd, int opt, int sotype) {
+    int a = 0;
+    int b = MAXINT;
+    int initial_guess;
+    int limit = -1;
+
+    if (sotype == SOCK_DGRAM) {
+        initial_guess = MAX_UDP_GUESS;
+    } else {
+        initial_guess = MAX_TCP_GUESS;
+    }
+
+    if (setsockopt(fd, SOL_SOCKET, opt, &initial_guess, sizeof(int)) == 0) {
+        initial_guess++;
+        if (setsockopt(fd, SOL_SOCKET, opt, &initial_guess,sizeof(int)) < 0) {
+            FAIL_IF_NOT_ENOBUFS;
+            return initial_guess - 1;
+        }
+        a = initial_guess;
+    } else {
+        FAIL_IF_NOT_ENOBUFS;
+        b = initial_guess - 1;
+    }
+    do {
+        int mid = a + (b-a)/2;
+        if (setsockopt(fd, SOL_SOCKET, opt, &mid, sizeof(int)) == 0) {
+            limit = mid;
+            a = mid + 1;
+        } else {
+            FAIL_IF_NOT_ENOBUFS;
+            b = mid - 1;
+        }
+    } while (b >= a);
+
+    return limit;
+}
+#endif
+
+#ifdef __linux__
+static int kernelV22 = 0;
+static int vinit = 0;
+
+int kernelIsV22 () {
+    if (!vinit) {
+        struct utsname sysinfo;
+        if (uname(&sysinfo) == 0) {
+            sysinfo.release[3] = '\0';
+            if (strcmp(sysinfo.release, "2.2") == 0) {
+                kernelV22 = JNI_TRUE;
+            }
+        }
+        vinit = 1;
+    }
+    return kernelV22;
+}
+
+static int kernelV24 = 0;
+static int vinit24 = 0;
+
+int kernelIsV24 () {
+    if (!vinit24) {
+        struct utsname sysinfo;
+        if (uname(&sysinfo) == 0) {
+            sysinfo.release[3] = '\0';
+            if (strcmp(sysinfo.release, "2.4") == 0) {
+                kernelV24 = JNI_TRUE;
+            }
+        }
+        vinit24 = 1;
+    }
+    return kernelV24;
+}
+
+int getScopeID (struct sockaddr *him) {
+    struct sockaddr_in6 *hext = (struct sockaddr_in6 *)him;
+    if (kernelIsV22()) {
+        return 0;
+    }
+    return hext->sin6_scope_id;
+}
+
+int cmpScopeID (unsigned int scope, struct sockaddr *him) {
+    struct sockaddr_in6 *hext = (struct sockaddr_in6 *)him;
+    if (kernelIsV22()) {
+        return 1;       /* scope is ignored for comparison in 2.2 kernel */
+    }
+    return hext->sin6_scope_id == scope;
+}
+
+#else
+
+int getScopeID (struct sockaddr *him) {
+    struct sockaddr_in6 *him6 = (struct sockaddr_in6 *)him;
+    return him6->sin6_scope_id;
+}
+
+int cmpScopeID (unsigned int scope, struct sockaddr *him) {
+    struct sockaddr_in6 *him6 = (struct sockaddr_in6 *)him;
+    return him6->sin6_scope_id == scope;
+}
+
+#endif
+
+
+void
+NET_ThrowByNameWithLastError(JNIEnv *env, const char *name,
+                   const char *defaultDetail) {
+    char errmsg[255];
+    sprintf(errmsg, "errno: %d, error: %s\n", errno, defaultDetail);
+    JNU_ThrowByNameWithLastError(env, name, errmsg);
+}
+
+void
+NET_ThrowCurrent(JNIEnv *env, char *msg) {
+    NET_ThrowNew(env, errno, msg);
+}
+
+void
+NET_ThrowNew(JNIEnv *env, int errorNumber, char *msg) {
+    char fullMsg[512];
+    if (!msg) {
+        msg = "no further information";
+    }
+    switch(errorNumber) {
+    case EBADF:
+        jio_snprintf(fullMsg, sizeof(fullMsg), "socket closed: %s", msg);
+        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", fullMsg);
+        break;
+    case EINTR:
+        JNU_ThrowByName(env, JNU_JAVAIOPKG "InterruptedIOException", msg);
+        break;
+    default:
+        errno = errorNumber;
+        JNU_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", msg);
+        break;
+    }
+}
+
+
+jfieldID
+NET_GetFileDescriptorID(JNIEnv *env)
+{
+    jclass cls = (*env)->FindClass(env, "java/io/FileDescriptor");
+    CHECK_NULL_RETURN(cls, NULL);
+    return (*env)->GetFieldID(env, cls, "fd", "I");
+}
+
+#if defined(DONT_ENABLE_IPV6)
+jint  IPv6_supported()
+{
+    return JNI_FALSE;
+}
+
+#else /* !DONT_ENABLE_IPV6 */
+
+jint  IPv6_supported()
+{
+#ifndef AF_INET6
+    return JNI_FALSE;
+#endif
+
+#ifdef AF_INET6
+    int fd;
+    void *ipv6_fn;
+    SOCKADDR sa;
+    socklen_t sa_len = sizeof(sa);
+
+    fd = JVM_Socket(AF_INET6, SOCK_STREAM, 0) ;
+    if (fd < 0) {
+        /*
+         *  TODO: We really cant tell since it may be an unrelated error
+         *  for now we will assume that AF_INET6 is not available
+         */
+        return JNI_FALSE;
+    }
+
+    /*
+     * If fd 0 is a socket it means we've been launched from inetd or
+     * xinetd. If it's a socket then check the family - if it's an
+     * IPv4 socket then we need to disable IPv6.
+     */
+    if (getsockname(0, (struct sockaddr *)&sa, &sa_len) == 0) {
+        struct sockaddr *saP = (struct sockaddr *)&sa;
+        if (saP->sa_family != AF_INET6) {
+            return JNI_FALSE;
+        }
+    }
+
+    /**
+     * Linux - check if any interface has an IPv6 address.
+     * Don't need to parse the line - we just need an indication.
+     */
+#ifdef __linux__
+    {
+        FILE *fP = fopen("/proc/net/if_inet6", "r");
+        char buf[255];
+        char *bufP;
+
+        if (fP == NULL) {
+            close(fd);
+            return JNI_FALSE;
+        }
+        bufP = fgets(buf, sizeof(buf), fP);
+        fclose(fP);
+        if (bufP == NULL) {
+            close(fd);
+            return JNI_FALSE;
+        }
+    }
+#endif
+
+    /**
+     * On Solaris 8 it's possible to create INET6 sockets even
+     * though IPv6 is not enabled on all interfaces. Thus we
+     * query the number of IPv6 addresses to verify that IPv6
+     * has been configured on at least one interface.
+     *
+     * On Linux it doesn't matter - if IPv6 is built-in the
+     * kernel then IPv6 addresses will be bound automatically
+     * to all interfaces.
+     */
+#ifdef __solaris__
+
+#ifdef SIOCGLIFNUM
+    {
+        struct lifnum numifs;
+
+        numifs.lifn_family = AF_INET6;
+        numifs.lifn_flags = 0;
+        if (ioctl(fd, SIOCGLIFNUM, (char *)&numifs) < 0) {
+            /**
+             * SIOCGLIFNUM failed - assume IPv6 not configured
+             */
+            close(fd);
+            return JNI_FALSE;
+        }
+        /**
+         * If no IPv6 addresses then return false. If count > 0
+         * it's possible that all IPv6 addresses are "down" but
+         * that's okay as they may be brought "up" while the
+         * VM is running.
+         */
+        if (numifs.lifn_count == 0) {
+            close(fd);
+            return JNI_FALSE;
+        }
+    }
+#else
+    /* SIOCGLIFNUM not defined in build environment ??? */
+    close(fd);
+    return JNI_FALSE;
+#endif
+
+#endif /* __solaris */
+
+    /*
+     *  OK we may have the stack available in the kernel,
+     *  we should also check if the APIs are available.
+     */
+    ipv6_fn = JVM_FindLibraryEntry(RTLD_DEFAULT, "inet_pton");
+    if (ipv6_fn == NULL ) {
+        close(fd);
+        return JNI_FALSE;
+    }
+
+    /*
+     * We've got the library, let's get the pointers to some
+     * IPV6 specific functions. We have to do that because, at least
+     * on Solaris we may build on a system without IPV6 networking
+     * libraries, therefore we can't have a hard link to these
+     * functions.
+     */
+    getaddrinfo_ptr = (getaddrinfo_f)
+        JVM_FindLibraryEntry(RTLD_DEFAULT, "getaddrinfo");
+
+    freeaddrinfo_ptr = (freeaddrinfo_f)
+        JVM_FindLibraryEntry(RTLD_DEFAULT, "freeaddrinfo");
+
+    gai_strerror_ptr = (gai_strerror_f)
+        JVM_FindLibraryEntry(RTLD_DEFAULT, "gai_strerror");
+
+    getnameinfo_ptr = (getnameinfo_f)
+        JVM_FindLibraryEntry(RTLD_DEFAULT, "getnameinfo");
+
+    if (freeaddrinfo_ptr == NULL || getnameinfo_ptr == NULL) {
+        /* We need all 3 of them */
+        getaddrinfo_ptr = NULL;
+    }
+
+    close(fd);
+    return JNI_TRUE;
+#endif /* AF_INET6 */
+}
+#endif /* DONT_ENABLE_IPV6 */
+
+void ThrowUnknownHostExceptionWithGaiError(JNIEnv *env,
+                                           const char* hostname,
+                                           int gai_error)
+{
+    int size;
+    char *buf;
+    const char *format = "%s: %s";
+    const char *error_string =
+        (gai_strerror_ptr == NULL) ? NULL : (*gai_strerror_ptr)(gai_error);
+    if (error_string == NULL)
+        error_string = "unknown error";
+
+    size = strlen(format) + strlen(hostname) + strlen(error_string) + 2;
+    buf = (char *) malloc(size);
+    if (buf) {
+        jstring s;
+        sprintf(buf, format, hostname, error_string);
+        s = JNU_NewStringPlatform(env, buf);
+        if (s != NULL) {
+            jobject x = JNU_NewObjectByName(env,
+                                            "java/net/UnknownHostException",
+                                            "(Ljava/lang/String;)V", s);
+            if (x != NULL)
+                (*env)->Throw(env, x);
+        }
+        free(buf);
+    }
+}
+
+void
+NET_AllocSockaddr(struct sockaddr **him, int *len) {
+#ifdef AF_INET6
+    if (ipv6_available()) {
+        struct sockaddr_in6 *him6 = (struct sockaddr_in6*)malloc(sizeof(struct sockaddr_in6));
+        *him = (struct sockaddr*)him6;
+        *len = sizeof(struct sockaddr_in6);
+    } else
+#endif /* AF_INET6 */
+        {
+            struct sockaddr_in *him4 = (struct sockaddr_in*)malloc(sizeof(struct sockaddr_in));
+            *him = (struct sockaddr*)him4;
+            *len = sizeof(struct sockaddr_in);
+        }
+}
+
+#if defined(__linux__) && defined(AF_INET6)
+
+
+/* following code creates a list of addresses from the kernel
+ * routing table that are routed via the loopback address.
+ * We check all destination addresses against this table
+ * and override the scope_id field to use the relevant value for "lo"
+ * in order to work-around the Linux bug that prevents packets destined
+ * for certain local addresses from being sent via a physical interface.
+ */
+
+struct loopback_route {
+    struct in6_addr addr; /* destination address */
+    int plen; /* prefix length */
+};
+
+static struct loopback_route *loRoutes = 0;
+static int nRoutes = 0; /* number of routes */
+static int loRoutes_size = 16; /* initial size */
+static int lo_scope_id = 0;
+
+static void initLoopbackRoutes();
+
+void printAddr (struct in6_addr *addr) {
+    int i;
+    for (i=0; i<16; i++) {
+        printf ("%02x", addr->s6_addr[i]);
+    }
+    printf ("\n");
+}
+
+static jboolean needsLoopbackRoute (struct in6_addr* dest_addr) {
+    int byte_count;
+    int extra_bits, i;
+    struct loopback_route *ptr;
+
+    if (loRoutes == 0) {
+        initLoopbackRoutes();
+    }
+
+    for (ptr = loRoutes, i=0; i<nRoutes; i++, ptr++) {
+        struct in6_addr *target_addr=&ptr->addr;
+        int dest_plen = ptr->plen;
+        byte_count = dest_plen >> 3;
+        extra_bits = dest_plen & 0x3;
+
+        if (byte_count > 0) {
+            if (memcmp(target_addr, dest_addr, byte_count)) {
+                continue;  /* no match */
+            }
+        }
+
+        if (extra_bits > 0) {
+            unsigned char c1 = ((unsigned char *)target_addr)[byte_count];
+            unsigned char c2 = ((unsigned char *)&dest_addr)[byte_count];
+            unsigned char mask = 0xff << (8 - extra_bits);
+            if ((c1 & mask) != (c2 & mask)) {
+                continue;
+            }
+        }
+        return JNI_TRUE;
+    }
+    return JNI_FALSE;
+}
+
+
+static void initLoopbackRoutes() {
+    FILE *f;
+    char srcp[8][5];
+    char hopp[8][5];
+    int dest_plen, src_plen, use, refcnt, metric;
+    unsigned long flags;
+    char dest_str[40];
+    struct in6_addr dest_addr;
+    char device[16];
+
+    if (loRoutes != 0) {
+        free (loRoutes);
+    }
+    loRoutes = calloc (loRoutes_size, sizeof(struct loopback_route));
+    if (loRoutes == 0) {
+        return;
+    }
+    /*
+     * Scan /proc/net/ipv6_route looking for a matching
+     * route.
+     */
+    if ((f = fopen("/proc/net/ipv6_route", "r")) == NULL) {
+        return ;
+    }
+    while (fscanf(f, "%4s%4s%4s%4s%4s%4s%4s%4s %02x "
+                     "%4s%4s%4s%4s%4s%4s%4s%4s %02x "
+                     "%4s%4s%4s%4s%4s%4s%4s%4s "
+                     "%08x %08x %08x %08lx %8s",
+                     dest_str, &dest_str[5], &dest_str[10], &dest_str[15],
+                     &dest_str[20], &dest_str[25], &dest_str[30], &dest_str[35],
+                     &dest_plen,
+                     srcp[0], srcp[1], srcp[2], srcp[3],
+                     srcp[4], srcp[5], srcp[6], srcp[7],
+                     &src_plen,
+                     hopp[0], hopp[1], hopp[2], hopp[3],
+                     hopp[4], hopp[5], hopp[6], hopp[7],
+                     &metric, &use, &refcnt, &flags, device) == 31) {
+
+        /*
+         * Some routes should be ignored
+         */
+        if ( (dest_plen < 0 || dest_plen > 128)  ||
+             (src_plen != 0) ||
+             (flags & (RTF_POLICY | RTF_FLOW)) ||
+             ((flags & RTF_REJECT) && dest_plen == 0) ) {
+            continue;
+        }
+
+        /*
+         * Convert the destination address
+         */
+        dest_str[4] = ':';
+        dest_str[9] = ':';
+        dest_str[14] = ':';
+        dest_str[19] = ':';
+        dest_str[24] = ':';
+        dest_str[29] = ':';
+        dest_str[34] = ':';
+        dest_str[39] = '\0';
+
+        if (inet_pton(AF_INET6, dest_str, &dest_addr) < 0) {
+            /* not an Ipv6 address */
+            continue;
+        }
+        if (strcmp(device, "lo") != 0) {
+            /* Not a loopback route */
+            continue;
+        } else {
+            if (nRoutes == loRoutes_size) {
+                loRoutes = realloc (loRoutes, loRoutes_size *
+                                sizeof (struct loopback_route) * 2);
+                if (loRoutes == 0) {
+                    return ;
+                }
+                loRoutes_size *= 2;
+            }
+            memcpy (&loRoutes[nRoutes].addr,&dest_addr,sizeof(struct in6_addr));
+            loRoutes[nRoutes].plen = dest_plen;
+            nRoutes ++;
+        }
+    }
+
+    fclose (f);
+    {
+        /* now find the scope_id for "lo" */
+
+        char devname[21];
+        char addr6p[8][5];
+        int plen, scope, dad_status, if_idx;
+
+        if ((f = fopen("/proc/net/if_inet6", "r")) != NULL) {
+            while (fscanf(f, "%4s%4s%4s%4s%4s%4s%4s%4s %02x %02x %02x %02x %20s\n",
+                      addr6p[0], addr6p[1], addr6p[2], addr6p[3],
+                      addr6p[4], addr6p[5], addr6p[6], addr6p[7],
+                  &if_idx, &plen, &scope, &dad_status, devname) == 13) {
+
+                if (strcmp(devname, "lo") == 0) {
+                    /*
+                     * Found - so just return the index
+                     */
+                    fclose(f);
+                    lo_scope_id = if_idx;
+                    return;
+                }
+            }
+            fclose(f);
+        }
+    }
+}
+
+/*
+ * Following is used for binding to local addresses. Equivalent
+ * to code above, for bind().
+ */
+
+struct localinterface {
+    int index;
+    char localaddr [16];
+};
+
+static struct localinterface *localifs = 0;
+static int localifsSize = 0;    /* size of array */
+static int nifs = 0;            /* number of entries used in array */
+
+/* not thread safe: make sure called once from one thread */
+
+static void initLocalIfs () {
+    FILE *f;
+    unsigned char staddr [16];
+    char ifname [33];
+    struct localinterface *lif=0;
+    int index, x1, x2, x3;
+    unsigned int u0,u1,u2,u3,u4,u5,u6,u7,u8,u9,ua,ub,uc,ud,ue,uf;
+
+    if ((f = fopen("/proc/net/if_inet6", "r")) == NULL) {
+        return ;
+    }
+    while (fscanf (f, "%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x "
+                "%d %x %x %x %32s",&u0,&u1,&u2,&u3,&u4,&u5,&u6,&u7,
+                &u8,&u9,&ua,&ub,&uc,&ud,&ue,&uf,
+                &index, &x1, &x2, &x3, ifname) == 21) {
+        staddr[0] = (unsigned char)u0;
+        staddr[1] = (unsigned char)u1;
+        staddr[2] = (unsigned char)u2;
+        staddr[3] = (unsigned char)u3;
+        staddr[4] = (unsigned char)u4;
+        staddr[5] = (unsigned char)u5;
+        staddr[6] = (unsigned char)u6;
+        staddr[7] = (unsigned char)u7;
+        staddr[8] = (unsigned char)u8;
+        staddr[9] = (unsigned char)u9;
+        staddr[10] = (unsigned char)ua;
+        staddr[11] = (unsigned char)ub;
+        staddr[12] = (unsigned char)uc;
+        staddr[13] = (unsigned char)ud;
+        staddr[14] = (unsigned char)ue;
+        staddr[15] = (unsigned char)uf;
+        nifs ++;
+        if (nifs > localifsSize) {
+            localifs = (struct localinterface *) realloc (
+                        localifs, sizeof (struct localinterface)* (localifsSize+5));
+            if (localifs == 0) {
+                nifs = 0;
+                fclose (f);
+                return;
+            }
+            lif = localifs + localifsSize;
+            localifsSize += 5;
+        } else {
+            lif ++;
+        }
+        memcpy (lif->localaddr, staddr, 16);
+        lif->index = index;
+    }
+    fclose (f);
+}
+
+/* return the scope_id (interface index) of the
+ * interface corresponding to the given address
+ * returns 0 if no match found
+ */
+
+static int getLocalScopeID (char *addr) {
+    struct localinterface *lif;
+    int i;
+    if (localifs == 0) {
+        initLocalIfs();
+    }
+    for (i=0, lif=localifs; i<nifs; i++, lif++) {
+        if (memcmp (addr, lif->localaddr, 16) == 0) {
+            return lif->index;
+        }
+    }
+    return 0;
+}
+
+void initLocalAddrTable () {
+    initLoopbackRoutes();
+    initLocalIfs();
+}
+
+#else
+
+void initLocalAddrTable () {}
+
+#endif
+
+void parseExclusiveBindProperty(JNIEnv *env) {
+#ifdef __solaris__
+    jstring s, flagSet;
+    jclass iCls;
+    jmethodID mid;
+
+    s = (*env)->NewStringUTF(env, "sun.net.useExclusiveBind");
+    CHECK_NULL(s);
+    iCls = (*env)->FindClass(env, "java/lang/System");
+    CHECK_NULL(iCls);
+    mid = (*env)->GetStaticMethodID(env, iCls, "getProperty",
+                "(Ljava/lang/String;)Ljava/lang/String;");
+    CHECK_NULL(mid);
+    flagSet = (*env)->CallStaticObjectMethod(env, iCls, mid, s);
+    if (flagSet != NULL) {
+        useExclBind = 1;
+    }
+#endif
+}
+/* In the case of an IPv4 Inetaddress this method will return an
+ * IPv4 mapped address where IPv6 is available and v4MappedAddress is TRUE.
+ * Otherwise it will return a sockaddr_in structure for an IPv4 InetAddress.
+*/
+JNIEXPORT int JNICALL
+NET_InetAddressToSockaddr(JNIEnv *env, jobject iaObj, int port, struct sockaddr *him,
+                          int *len, jboolean v4MappedAddress) {
+    jint family;
+    family = getInetAddress_family(env, iaObj);
+#ifdef AF_INET6
+    /* needs work. 1. family 2. clean up him6 etc deallocate memory */
+    if (ipv6_available() && !(family == IPv4 && v4MappedAddress == JNI_FALSE)) {
+        struct sockaddr_in6 *him6 = (struct sockaddr_in6 *)him;
+        jbyteArray ipaddress;
+        jbyte caddr[16];
+        jint address;
+
+
+        if (family == IPv4) { /* will convert to IPv4-mapped address */
+            memset((char *) caddr, 0, 16);
+            address = getInetAddress_addr(env, iaObj);
+            if (address == INADDR_ANY) {
+                /* we would always prefer IPv6 wildcard address
+                   caddr[10] = 0xff;
+                   caddr[11] = 0xff; */
+            } else {
+                caddr[10] = 0xff;
+                caddr[11] = 0xff;
+                caddr[12] = ((address >> 24) & 0xff);
+                caddr[13] = ((address >> 16) & 0xff);
+                caddr[14] = ((address >> 8) & 0xff);
+                caddr[15] = (address & 0xff);
+            }
+        } else {
+            ipaddress = (*env)->GetObjectField(env, iaObj, ia6_ipaddressID);
+            (*env)->GetByteArrayRegion(env, ipaddress, 0, 16, caddr);
+        }
+        memset((char *)him6, 0, sizeof(struct sockaddr_in6));
+        him6->sin6_port = htons(port);
+        memcpy((void *)&(him6->sin6_addr), caddr, sizeof(struct in6_addr) );
+        him6->sin6_family = AF_INET6;
+        *len = sizeof(struct sockaddr_in6) ;
+
+#if defined(_ALLBSD_SOURCE) && defined(_AF_INET6)
+// XXXBSD: should we do something with scope id here ? see below linux comment
+/* MMM: Come back to this! */
+#endif
+
+        /*
+         * On Linux if we are connecting to a link-local address
+         * we need to specify the interface in the scope_id (2.4 kernel only)
+         *
+         * If the scope was cached the we use the cached value. If not cached but
+         * specified in the Inet6Address we use that, but we first check if the
+         * address needs to be routed via the loopback interface. In this case,
+         * we override the specified value with that of the loopback interface.
+         * If no cached value exists and no value was specified by user, then
+         * we try to determine a value ffrom the routing table. In all these
+         * cases the used value is cached for further use.
+         */
+#ifdef __linux__
+        if (IN6_IS_ADDR_LINKLOCAL(&(him6->sin6_addr))) {
+            int cached_scope_id = 0, scope_id = 0;
+            int old_kernel = kernelIsV22();
+
+            if (ia6_cachedscopeidID && !old_kernel) {
+                cached_scope_id = (int)(*env)->GetIntField(env, iaObj, ia6_cachedscopeidID);
+                /* if cached value exists then use it. Otherwise, check
+                 * if scope is set in the address.
+                 */
+                if (!cached_scope_id) {
+                    if (ia6_scopeidID) {
+                        scope_id = (int)(*env)->GetIntField(env,iaObj,ia6_scopeidID);
+                    }
+                    if (scope_id != 0) {
+                        /* check user-specified value for loopback case
+                         * that needs to be overridden
+                         */
+                        if (kernelIsV24() && needsLoopbackRoute (&him6->sin6_addr)) {
+                            cached_scope_id = lo_scope_id;
+                            (*env)->SetIntField(env, iaObj, ia6_cachedscopeidID, cached_scope_id);
+                        }
+                    } else {
+                        /*
+                         * Otherwise consult the IPv6 routing tables to
+                         * try determine the appropriate interface.
+                         */
+                        if (kernelIsV24()) {
+                            cached_scope_id = getDefaultIPv6Interface( &(him6->sin6_addr) );
+                        } else {
+                            cached_scope_id = getLocalScopeID( (char *)&(him6->sin6_addr) );
+                            if (cached_scope_id == 0) {
+                                cached_scope_id = getDefaultIPv6Interface( &(him6->sin6_addr) );
+                            }
+                        }
+                        (*env)->SetIntField(env, iaObj, ia6_cachedscopeidID, cached_scope_id);
+                    }
+                }
+            }
+
+            /*
+             * If we have a scope_id use the extended form
+             * of sockaddr_in6.
+             */
+
+            if (!old_kernel) {
+                struct sockaddr_in6 *him6 =
+                        (struct sockaddr_in6 *)him;
+                him6->sin6_scope_id = cached_scope_id != 0 ?
+                                            cached_scope_id    : scope_id;
+                *len = sizeof(struct sockaddr_in6);
+            }
+        }
+#else
+        /* handle scope_id for solaris */
+
+        if (family != IPv4) {
+            if (ia6_scopeidID) {
+                him6->sin6_scope_id = (int)(*env)->GetIntField(env, iaObj, ia6_scopeidID);
+            }
+        }
+#endif
+    } else
+#endif /* AF_INET6 */
+        {
+            struct sockaddr_in *him4 = (struct sockaddr_in*)him;
+            jint address;
+            if (family == IPv6) {
+              JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Protocol family unavailable");
+              return -1;
+            }
+            memset((char *) him4, 0, sizeof(struct sockaddr_in));
+            address = getInetAddress_addr(env, iaObj);
+            him4->sin_port = htons((short) port);
+            him4->sin_addr.s_addr = (uint32_t) htonl(address);
+            him4->sin_family = AF_INET;
+            *len = sizeof(struct sockaddr_in);
+        }
+    return 0;
+}
+
+void
+NET_SetTrafficClass(struct sockaddr *him, int trafficClass) {
+#ifdef AF_INET6
+    if (him->sa_family == AF_INET6) {
+        struct sockaddr_in6 *him6 = (struct sockaddr_in6 *)him;
+        him6->sin6_flowinfo = htonl((trafficClass & 0xff) << 20);
+    }
+#endif /* AF_INET6 */
+}
+
+JNIEXPORT jint JNICALL
+NET_GetPortFromSockaddr(struct sockaddr *him) {
+#ifdef AF_INET6
+    if (him->sa_family == AF_INET6) {
+        return ntohs(((struct sockaddr_in6*)him)->sin6_port);
+
+        } else
+#endif /* AF_INET6 */
+            {
+                return ntohs(((struct sockaddr_in*)him)->sin_port);
+            }
+}
+
+int
+NET_IsIPv4Mapped(jbyte* caddr) {
+    int i;
+    for (i = 0; i < 10; i++) {
+        if (caddr[i] != 0x00) {
+            return 0; /* false */
+        }
+    }
+
+    if (((caddr[10] & 0xff) == 0xff) && ((caddr[11] & 0xff) == 0xff)) {
+        return 1; /* true */
+    }
+    return 0; /* false */
+}
+
+int
+NET_IPv4MappedToIPv4(jbyte* caddr) {
+    return ((caddr[12] & 0xff) << 24) | ((caddr[13] & 0xff) << 16) | ((caddr[14] & 0xff) << 8)
+        | (caddr[15] & 0xff);
+}
+
+int
+NET_IsEqual(jbyte* caddr1, jbyte* caddr2) {
+    int i;
+    for (i = 0; i < 16; i++) {
+        if (caddr1[i] != caddr2[i]) {
+            return 0; /* false */
+        }
+    }
+    return 1;
+}
+
+jboolean NET_addrtransAvailable() {
+    return (jboolean)(getaddrinfo_ptr != NULL);
+}
+
+int NET_IsZeroAddr(jbyte* caddr) {
+    int i;
+    for (i = 0; i < 16; i++) {
+        if (caddr[i] != 0) {
+            return 0;
+        }
+    }
+    return 1;
+}
+
+/*
+ * Map the Java level socket option to the platform specific
+ * level and option name.
+ */
+int
+NET_MapSocketOption(jint cmd, int *level, int *optname) {
+    static struct {
+        jint cmd;
+        int level;
+        int optname;
+    } const opts[] = {
+        { java_net_SocketOptions_TCP_NODELAY,           IPPROTO_TCP,    TCP_NODELAY },
+        { java_net_SocketOptions_SO_OOBINLINE,          SOL_SOCKET,     SO_OOBINLINE },
+        { java_net_SocketOptions_SO_LINGER,             SOL_SOCKET,     SO_LINGER },
+        { java_net_SocketOptions_SO_SNDBUF,             SOL_SOCKET,     SO_SNDBUF },
+        { java_net_SocketOptions_SO_RCVBUF,             SOL_SOCKET,     SO_RCVBUF },
+        { java_net_SocketOptions_SO_KEEPALIVE,          SOL_SOCKET,     SO_KEEPALIVE },
+        { java_net_SocketOptions_SO_REUSEADDR,          SOL_SOCKET,     SO_REUSEADDR },
+        { java_net_SocketOptions_SO_BROADCAST,          SOL_SOCKET,     SO_BROADCAST },
+        { java_net_SocketOptions_IP_TOS,                IPPROTO_IP,     IP_TOS },
+        { java_net_SocketOptions_IP_MULTICAST_IF,       IPPROTO_IP,     IP_MULTICAST_IF },
+        { java_net_SocketOptions_IP_MULTICAST_IF2,      IPPROTO_IP,     IP_MULTICAST_IF },
+        { java_net_SocketOptions_IP_MULTICAST_LOOP,     IPPROTO_IP,     IP_MULTICAST_LOOP },
+    };
+
+    int i;
+
+    /*
+     * Different multicast options if IPv6 is enabled
+     */
+#ifdef AF_INET6
+    if (ipv6_available()) {
+        switch (cmd) {
+            case java_net_SocketOptions_IP_MULTICAST_IF:
+            case java_net_SocketOptions_IP_MULTICAST_IF2:
+                *level = IPPROTO_IPV6;
+                *optname = IPV6_MULTICAST_IF;
+                return 0;
+
+            case java_net_SocketOptions_IP_MULTICAST_LOOP:
+                *level = IPPROTO_IPV6;
+                *optname = IPV6_MULTICAST_LOOP;
+                return 0;
+        }
+    }
+#endif
+
+    /*
+     * Map the Java level option to the native level
+     */
+    for (i=0; i<(int)(sizeof(opts) / sizeof(opts[0])); i++) {
+        if (cmd == opts[i].cmd) {
+            *level = opts[i].level;
+            *optname = opts[i].optname;
+            return 0;
+        }
+    }
+
+    /* not found */
+    return -1;
+}
+
+/*
+ * Determine the default interface for an IPv6 address.
+ *
+ * 1. Scans /proc/net/ipv6_route for a matching route
+ *    (eg: fe80::/10 or a route for the specific address).
+ *    This will tell us the interface to use (eg: "eth0").
+ *
+ * 2. Lookup /proc/net/if_inet6 to map the interface
+ *    name to an interface index.
+ *
+ * Returns :-
+ *      -1 if error
+ *       0 if no matching interface
+ *      >1 interface index to use for the link-local address.
+ */
+#if defined(__linux__) && defined(AF_INET6)
+int getDefaultIPv6Interface(struct in6_addr *target_addr) {
+    FILE *f;
+    char srcp[8][5];
+    char hopp[8][5];
+    int dest_plen, src_plen, use, refcnt, metric;
+    unsigned long flags;
+    char dest_str[40];
+    struct in6_addr dest_addr;
+    char device[16];
+    jboolean match = JNI_FALSE;
+
+    /*
+     * Scan /proc/net/ipv6_route looking for a matching
+     * route.
+     */
+    if ((f = fopen("/proc/net/ipv6_route", "r")) == NULL) {
+        return -1;
+    }
+    while (fscanf(f, "%4s%4s%4s%4s%4s%4s%4s%4s %02x "
+                     "%4s%4s%4s%4s%4s%4s%4s%4s %02x "
+                     "%4s%4s%4s%4s%4s%4s%4s%4s "
+                     "%08x %08x %08x %08lx %8s",
+                     dest_str, &dest_str[5], &dest_str[10], &dest_str[15],
+                     &dest_str[20], &dest_str[25], &dest_str[30], &dest_str[35],
+                     &dest_plen,
+                     srcp[0], srcp[1], srcp[2], srcp[3],
+                     srcp[4], srcp[5], srcp[6], srcp[7],
+                     &src_plen,
+                     hopp[0], hopp[1], hopp[2], hopp[3],
+                     hopp[4], hopp[5], hopp[6], hopp[7],
+                     &metric, &use, &refcnt, &flags, device) == 31) {
+
+        /*
+         * Some routes should be ignored
+         */
+        if ( (dest_plen < 0 || dest_plen > 128)  ||
+             (src_plen != 0) ||
+             (flags & (RTF_POLICY | RTF_FLOW)) ||
+             ((flags & RTF_REJECT) && dest_plen == 0) ) {
+            continue;
+        }
+
+        /*
+         * Convert the destination address
+         */
+        dest_str[4] = ':';
+        dest_str[9] = ':';
+        dest_str[14] = ':';
+        dest_str[19] = ':';
+        dest_str[24] = ':';
+        dest_str[29] = ':';
+        dest_str[34] = ':';
+        dest_str[39] = '\0';
+
+        if (inet_pton(AF_INET6, dest_str, &dest_addr) < 0) {
+            /* not an Ipv6 address */
+            continue;
+        } else {
+            /*
+             * The prefix len (dest_plen) indicates the number of bits we
+             * need to match on.
+             *
+             * dest_plen / 8    => number of bytes to match
+             * dest_plen % 8    => number of additional bits to match
+             *
+             * eg: fe80::/10 => match 1 byte + 2 additional bits in the
+             *                  the next byte.
+             */
+            int byte_count = dest_plen >> 3;
+            int extra_bits = dest_plen & 0x3;
+
+            if (byte_count > 0) {
+                if (memcmp(target_addr, &dest_addr, byte_count)) {
+                    continue;  /* no match */
+                }
+            }
+
+            if (extra_bits > 0) {
+                unsigned char c1 = ((unsigned char *)target_addr)[byte_count];
+                unsigned char c2 = ((unsigned char *)&dest_addr)[byte_count];
+                unsigned char mask = 0xff << (8 - extra_bits);
+                if ((c1 & mask) != (c2 & mask)) {
+                    continue;
+                }
+            }
+
+            /*
+             * We have a match
+             */
+            match = JNI_TRUE;
+            break;
+        }
+    }
+    fclose(f);
+
+    /*
+     * If there's a match then we lookup the interface
+     * index.
+     */
+    if (match) {
+        char devname[21];
+        char addr6p[8][5];
+        int plen, scope, dad_status, if_idx;
+
+        if ((f = fopen("/proc/net/if_inet6", "r")) != NULL) {
+            while (fscanf(f, "%4s%4s%4s%4s%4s%4s%4s%4s %02x %02x %02x %02x %20s\n",
+                      addr6p[0], addr6p[1], addr6p[2], addr6p[3],
+                      addr6p[4], addr6p[5], addr6p[6], addr6p[7],
+                  &if_idx, &plen, &scope, &dad_status, devname) == 13) {
+
+                if (strcmp(devname, device) == 0) {
+                    /*
+                     * Found - so just return the index
+                     */
+                    fclose(f);
+                    return if_idx;
+                }
+            }
+            fclose(f);
+        } else {
+            /*
+             * Couldn't open /proc/net/if_inet6
+             */
+            return -1;
+        }
+    }
+
+    /*
+     * If we get here it means we didn't there wasn't any
+     * route or we couldn't get the index of the interface.
+     */
+    return 0;
+}
+#endif
+
+
+/*
+ * Wrapper for getsockopt system routine - does any necessary
+ * pre/post processing to deal with OS specific oddies :-
+ *
+ * IP_TOS is a no-op with IPv6 sockets as it's setup when
+ * the connection is established.
+ *
+ * On Linux the SO_SNDBUF/SO_RCVBUF values must be post-processed
+ * to compensate for an incorrect value returned by the kernel.
+ */
+int
+NET_GetSockOpt(int fd, int level, int opt, void *result,
+               int *len)
+{
+    int rv;
+
+#ifdef AF_INET6
+    if ((level == IPPROTO_IP) && (opt == IP_TOS)) {
+        if (ipv6_available()) {
+
+            /*
+             * For IPv6 socket option implemented at Java-level
+             * so return -1.
+             */
+            int *tc = (int *)result;
+            *tc = -1;
+            return 0;
+        }
+    }
+#endif
+
+#ifdef __solaris__
+    rv = getsockopt(fd, level, opt, result, len);
+#else
+    {
+        socklen_t socklen = *len;
+        rv = getsockopt(fd, level, opt, result, &socklen);
+        *len = socklen;
+    }
+#endif
+
+    if (rv < 0) {
+        return rv;
+    }
+
+#ifdef __linux__
+    /*
+     * On Linux SO_SNDBUF/SO_RCVBUF aren't symmetric. This
+     * stems from additional socket structures in the send
+     * and receive buffers.
+     */
+    if ((level == SOL_SOCKET) && ((opt == SO_SNDBUF)
+                                  || (opt == SO_RCVBUF))) {
+        int n = *((int *)result);
+        n /= 2;
+        *((int *)result) = n;
+    }
+#endif
+
+/* Workaround for Mac OS treating linger value as
+ *  signed integer
+ */
+#ifdef MACOSX
+    if (level == SOL_SOCKET && opt == SO_LINGER) {
+        struct linger* to_cast = (struct linger*)result;
+        to_cast->l_linger = (unsigned short)to_cast->l_linger;
+    }
+#endif
+    return rv;
+}
+
+/*
+ * Wrapper for setsockopt system routine - performs any
+ * necessary pre/post processing to deal with OS specific
+ * issue :-
+ *
+ * On Solaris need to limit the suggested value for SO_SNDBUF
+ * and SO_RCVBUF to the kernel configured limit
+ *
+ * For IP_TOS socket option need to mask off bits as this
+ * aren't automatically masked by the kernel and results in
+ * an error. In addition IP_TOS is a noop with IPv6 as it
+ * should be setup as connection time.
+ */
+int
+NET_SetSockOpt(int fd, int level, int  opt, const void *arg,
+               int len)
+{
+#ifndef IPTOS_TOS_MASK
+#define IPTOS_TOS_MASK 0x1e
+#endif
+#ifndef IPTOS_PREC_MASK
+#define IPTOS_PREC_MASK 0xe0
+#endif
+
+#if defined(_ALLBSD_SOURCE)
+#if defined(KIPC_MAXSOCKBUF)
+    int mib[3];
+    size_t rlen;
+#endif
+
+    int *bufsize;
+
+#ifdef __APPLE__
+    static int maxsockbuf = -1;
+#else
+    static long maxsockbuf = -1;
+#endif
+
+    int addopt;
+    struct linger *ling;
+#endif
+
+    /*
+     * IPPROTO/IP_TOS :-
+     * 1. IPv6 on Solaris/Mac OS: no-op and will be set
+     *    in flowinfo field when connecting TCP socket,
+     *    or sending UDP packet.
+     * 2. IPv6 on Linux: By default Linux ignores flowinfo
+     *    field so enable IPV6_FLOWINFO_SEND so that flowinfo
+     *    will be examined.
+     * 3. IPv4: set socket option based on ToS and Precedence
+     *    fields (otherwise get invalid argument)
+     */
+    if (level == IPPROTO_IP && opt == IP_TOS) {
+        int *iptos;
+
+#if defined(AF_INET6) && (defined(__solaris__) || defined(MACOSX))
+        if (ipv6_available()) {
+            return 0;
+        }
+#endif
+
+#if defined(AF_INET6) && defined(__linux__)
+        if (ipv6_available()) {
+            int optval = 1;
+            return setsockopt(fd, IPPROTO_IPV6, IPV6_FLOWINFO_SEND,
+                              (void *)&optval, sizeof(optval));
+        }
+#endif
+
+        iptos = (int *)arg;
+        *iptos &= (IPTOS_TOS_MASK | IPTOS_PREC_MASK);
+    }
+
+    /*
+     * SOL_SOCKET/{SO_SNDBUF,SO_RCVBUF} - On Solaris we may need to clamp
+     * the value when it exceeds the system limit.
+     */
+#ifdef __solaris__
+    if (level == SOL_SOCKET) {
+        if (opt == SO_SNDBUF || opt == SO_RCVBUF) {
+            int sotype=0, arglen;
+            int *bufsize, maxbuf;
+            int ret;
+
+            /* Attempt with the original size */
+            ret = setsockopt(fd, level, opt, arg, len);
+            if ((ret == 0) || (ret == -1 && errno != ENOBUFS))
+                return ret;
+
+            /* Exceeded system limit so clamp and retry */
+
+            arglen = sizeof(sotype);
+            if (getsockopt(fd, SOL_SOCKET, SO_TYPE, (void *)&sotype,
+                           &arglen) < 0) {
+                return -1;
+            }
+
+            /*
+             * We try to get tcp_maxbuf (and udp_max_buf) using
+             * an ioctl() that isn't available on all versions of Solaris.
+             * If that fails, we use the search algorithm in findMaxBuf()
+             */
+            if (!init_tcp_max_buf && sotype == SOCK_STREAM) {
+                tcp_max_buf = getParam("/dev/tcp", "tcp_max_buf");
+                if (tcp_max_buf == -1) {
+                    tcp_max_buf = findMaxBuf(fd, opt, SOCK_STREAM);
+                    if (tcp_max_buf == -1) {
+                        return -1;
+                    }
+                }
+                init_tcp_max_buf = 1;
+            } else if (!init_udp_max_buf && sotype == SOCK_DGRAM) {
+                udp_max_buf = getParam("/dev/udp", "udp_max_buf");
+                if (udp_max_buf == -1) {
+                    udp_max_buf = findMaxBuf(fd, opt, SOCK_DGRAM);
+                    if (udp_max_buf == -1) {
+                        return -1;
+                    }
+                }
+                init_udp_max_buf = 1;
+            }
+
+            maxbuf = (sotype == SOCK_STREAM) ? tcp_max_buf : udp_max_buf;
+            bufsize = (int *)arg;
+            if (*bufsize > maxbuf) {
+                *bufsize = maxbuf;
+            }
+        }
+    }
+#endif
+
+    /*
+     * On Linux the receive buffer is used for both socket
+     * structures and the the packet payload. The implication
+     * is that if SO_RCVBUF is too small then small packets
+     * must be discard.
+     */
+#ifdef __linux__
+    if (level == SOL_SOCKET && opt == SO_RCVBUF) {
+        int *bufsize = (int *)arg;
+        if (*bufsize < 1024) {
+            *bufsize = 1024;
+        }
+    }
+#endif
+
+#if defined(_ALLBSD_SOURCE)
+    /*
+     * SOL_SOCKET/{SO_SNDBUF,SO_RCVBUF} - On FreeBSD need to
+     * ensure that value is <= kern.ipc.maxsockbuf as otherwise we get
+     * an ENOBUFS error.
+     */
+    if (level == SOL_SOCKET) {
+        if (opt == SO_SNDBUF || opt == SO_RCVBUF) {
+#ifdef KIPC_MAXSOCKBUF
+            if (maxsockbuf == -1) {
+               mib[0] = CTL_KERN;
+               mib[1] = KERN_IPC;
+               mib[2] = KIPC_MAXSOCKBUF;
+               rlen = sizeof(maxsockbuf);
+               if (sysctl(mib, 3, &maxsockbuf, &rlen, NULL, 0) == -1)
+                   maxsockbuf = 1024;
+
+#if 1
+               /* XXXBSD: This is a hack to workaround mb_max/mb_max_adj
+                  problem.  It should be removed when kern.ipc.maxsockbuf
+                  will be real value. */
+               maxsockbuf = (maxsockbuf/5)*4;
+#endif
+           }
+#elif defined(__OpenBSD__)
+           maxsockbuf = SB_MAX;
+#else
+           maxsockbuf = 64 * 1024;      /* XXX: NetBSD */
+#endif
+
+           bufsize = (int *)arg;
+           if (*bufsize > maxsockbuf) {
+               *bufsize = maxsockbuf;
+           }
+
+           if (opt == SO_RCVBUF && *bufsize < 1024) {
+                *bufsize = 1024;
+           }
+
+        }
+    }
+
+    /*
+     * On Solaris, SO_REUSEADDR will allow multiple datagram
+     * sockets to bind to the same port.  The network jck tests
+     * for this "feature", so we need to emulate it by turning on
+     * SO_REUSEPORT as well for that combination.
+     */
+    if (level == SOL_SOCKET && opt == SO_REUSEADDR) {
+        int sotype;
+        socklen_t arglen;
+
+        arglen = sizeof(sotype);
+        if (getsockopt(fd, SOL_SOCKET, SO_TYPE, (void *)&sotype, &arglen) < 0) {
+            return -1;
+        }
+
+        if (sotype == SOCK_DGRAM) {
+            addopt = SO_REUSEPORT;
+            setsockopt(fd, level, addopt, arg, len);
+        }
+    }
+
+#endif
+
+    return setsockopt(fd, level, opt, arg, len);
+}
+
+/*
+ * Wrapper for bind system call - performs any necessary pre/post
+ * processing to deal with OS specific issues :-
+ *
+ * Linux allows a socket to bind to 127.0.0.255 which must be
+ * caught.
+ *
+ * On Solaris with IPv6 enabled we must use an exclusive
+ * bind to guaranteed a unique port number across the IPv4 and
+ * IPv6 port spaces.
+ *
+ */
+int
+NET_Bind(int fd, struct sockaddr *him, int len)
+{
+#if defined(__solaris__) && defined(AF_INET6)
+    int level = -1;
+    int exclbind = -1;
+#endif
+    int rv;
+
+#ifdef __linux__
+    /*
+     * ## get bugId for this issue - goes back to 1.2.2 port ##
+     * ## When IPv6 is enabled this will be an IPv4-mapped
+     * ## with family set to AF_INET6
+     */
+    if (him->sa_family == AF_INET) {
+        struct sockaddr_in *sa = (struct sockaddr_in *)him;
+        if ((ntohl(sa->sin_addr.s_addr) & 0x7f0000ff) == 0x7f0000ff) {
+            errno = EADDRNOTAVAIL;
+            return -1;
+        }
+    }
+#endif
+
+#if defined(__solaris__) && defined(AF_INET6)
+    /*
+     * Solaris has seperate IPv4 and IPv6 port spaces so we
+     * use an exclusive bind when SO_REUSEADDR is not used to
+     * give the illusion of a unified port space.
+     * This also avoids problems with IPv6 sockets connecting
+     * to IPv4 mapped addresses whereby the socket conversion
+     * results in a late bind that fails because the
+     * corresponding IPv4 port is in use.
+     */
+    if (ipv6_available()) {
+        int arg, len;
+
+        len = sizeof(arg);
+        if (useExclBind || getsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
+                       (char *)&arg, &len) == 0) {
+            if (useExclBind || arg == 0) {
+                /*
+                 * SO_REUSEADDR is disabled or sun.net.useExclusiveBind
+                 * property is true so enable TCP_EXCLBIND or
+                 * UDP_EXCLBIND
+                 */
+                len = sizeof(arg);
+                if (getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&arg,
+                               &len) == 0) {
+                    if (arg == SOCK_STREAM) {
+                        level = IPPROTO_TCP;
+                        exclbind = TCP_EXCLBIND;
+                    } else {
+                        level = IPPROTO_UDP;
+                        exclbind = UDP_EXCLBIND;
+                    }
+                }
+
+                arg = 1;
+                setsockopt(fd, level, exclbind, (char *)&arg,
+                           sizeof(arg));
+            }
+        }
+    }
+
+#endif
+
+    rv = bind(fd, him, len);
+
+#if defined(__solaris__) && defined(AF_INET6)
+    if (rv < 0) {
+        int en = errno;
+        /* Restore *_EXCLBIND if the bind fails */
+        if (exclbind != -1) {
+            int arg = 0;
+            setsockopt(fd, level, exclbind, (char *)&arg,
+                       sizeof(arg));
+        }
+        errno = en;
+    }
+#endif
+
+    return rv;
+}
+
+/**
+ * Wrapper for select/poll with timeout on a single file descriptor.
+ *
+ * flags (defined in net_util_md.h can be any combination of
+ * NET_WAIT_READ, NET_WAIT_WRITE & NET_WAIT_CONNECT.
+ *
+ * The function will return when either the socket is ready for one
+ * of the specified operation or the timeout expired.
+ *
+ * It returns the time left from the timeout (possibly 0), or -1 if it expired.
+ */
+
+jint
+NET_Wait(JNIEnv *env, jint fd, jint flags, jint timeout)
+{
+    jlong prevTime = JVM_CurrentTimeMillis(env, 0);
+    jint read_rv;
+
+    while (1) {
+        jlong newTime;
+#ifndef USE_SELECT
+        {
+          struct pollfd pfd;
+          pfd.fd = fd;
+          pfd.events = 0;
+          if (flags & NET_WAIT_READ)
+            pfd.events |= POLLIN;
+          if (flags & NET_WAIT_WRITE)
+            pfd.events |= POLLOUT;
+          if (flags & NET_WAIT_CONNECT)
+            pfd.events |= POLLOUT;
+
+          errno = 0;
+          read_rv = NET_Poll(&pfd, 1, timeout);
+        }
+#else
+        {
+          fd_set rd, wr, ex;
+          struct timeval t;
+
+          t.tv_sec = timeout / 1000;
+          t.tv_usec = (timeout % 1000) * 1000;
+
+          FD_ZERO(&rd);
+          FD_ZERO(&wr);
+          FD_ZERO(&ex);
+          if (flags & NET_WAIT_READ) {
+            FD_SET(fd, &rd);
+          }
+          if (flags & NET_WAIT_WRITE) {
+            FD_SET(fd, &wr);
+          }
+          if (flags & NET_WAIT_CONNECT) {
+            FD_SET(fd, &wr);
+            FD_SET(fd, &ex);
+          }
+
+          errno = 0;
+          read_rv = NET_Select(fd+1, &rd, &wr, &ex, &t);
+        }
+#endif
+
+        newTime = JVM_CurrentTimeMillis(env, 0);
+        timeout -= (newTime - prevTime);
+        if (timeout <= 0) {
+          return read_rv > 0 ? 0 : -1;
+        }
+        newTime = prevTime;
+
+        if (read_rv > 0) {
+          break;
+        }
+
+
+      } /* while */
+
+    return timeout;
+}
diff --git a/ojluni/src/main/native/net_util_md.h b/ojluni/src/main/native/net_util_md.h
new file mode 100755
index 0000000..c72a07b
--- /dev/null
+++ b/ojluni/src/main/native/net_util_md.h
@@ -0,0 +1,159 @@
+/*
+ * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#ifndef NET_UTILS_MD_H
+#define NET_UTILS_MD_H
+
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <netdb.h>
+#include <netinet/in.h>
+#include <unistd.h>
+
+#ifndef USE_SELECT
+#include <sys/poll.h>
+#endif
+
+
+#if defined(__linux__) || defined(MACOSX)
+extern int NET_Timeout(int s, long timeout);
+extern int NET_Read(int s, void* buf, size_t len);
+extern int NET_RecvFrom(int s, void *buf, int len, unsigned int flags,
+       struct sockaddr *from, int *fromlen);
+extern int NET_ReadV(int s, const struct iovec * vector, int count);
+extern int NET_Send(int s, void *msg, int len, unsigned int flags);
+extern int NET_SendTo(int s, const void *msg, int len,  unsigned  int
+       flags, const struct sockaddr *to, int tolen);
+extern int NET_Writev(int s, const struct iovec * vector, int count);
+extern int NET_Connect(int s, struct sockaddr *addr, int addrlen);
+extern int NET_Accept(int s, struct sockaddr *addr, int *addrlen);
+extern int NET_SocketClose(int s);
+extern int NET_Dup2(int oldfd, int newfd);
+
+#ifdef USE_SELECT
+extern int NET_Select(int s, fd_set *readfds, fd_set *writefds,
+               fd_set *exceptfds, struct timeval *timeout);
+#else
+extern int NET_Poll(struct pollfd *ufds, unsigned int nfds, int timeout);
+#endif
+
+#else
+
+#define NET_Timeout     JVM_Timeout
+#define NET_Read        JVM_Read
+#define NET_RecvFrom    JVM_RecvFrom
+#define NET_ReadV       readv
+#define NET_Send        JVM_Send
+#define NET_SendTo      JVM_SendTo
+#define NET_WriteV      writev
+#define NET_Connect     JVM_Connect
+#define NET_Accept      JVM_Accept
+#define NET_SocketClose JVM_SocketClose
+#define NET_Dup2        dup2
+#define NET_Select      select
+#define NET_Poll        poll
+
+#endif
+
+#if defined(__linux__) && defined(AF_INET6)
+int getDefaultIPv6Interface(struct in6_addr *target_addr);
+#endif
+
+
+/* needed from libsocket on Solaris 8 */
+
+typedef int (*getaddrinfo_f)(const char *nodename, const char *servname,
+    const struct addrinfo *hints, struct addrinfo **res);
+
+typedef void (*freeaddrinfo_f)(struct addrinfo *);
+
+typedef const char * (*gai_strerror_f)(int ecode);
+
+typedef int (*getnameinfo_f)(const struct sockaddr *, size_t,
+    char *, size_t, char *, size_t, int);
+
+extern getaddrinfo_f getaddrinfo_ptr;
+extern freeaddrinfo_f freeaddrinfo_ptr;
+extern getnameinfo_f getnameinfo_ptr;
+
+void ThrowUnknownHostExceptionWithGaiError(JNIEnv *env,
+                                           const char* hostname,
+                                           int gai_error);
+
+/* do we have address translation support */
+
+extern jboolean NET_addrtransAvailable();
+
+#define NET_WAIT_READ   0x01
+#define NET_WAIT_WRITE  0x02
+#define NET_WAIT_CONNECT        0x04
+
+extern jint NET_Wait(JNIEnv *env, jint fd, jint flags, jint timeout);
+
+/************************************************************************
+ * Macros and constants
+ */
+
+/*
+ * On 64-bit JDKs we use a much larger stack and heap buffer.
+ */
+#ifdef _LP64
+#define MAX_BUFFER_LEN 65536
+#define MAX_HEAP_BUFFER_LEN 131072
+#else
+#define MAX_BUFFER_LEN 8192
+#define MAX_HEAP_BUFFER_LEN 65536
+#endif
+
+#ifdef AF_INET6
+
+#define SOCKADDR        union { \
+                            struct sockaddr_in him4; \
+                            struct sockaddr_in6 him6; \
+                        }
+
+#define SOCKADDR_LEN    (ipv6_available() ? sizeof(SOCKADDR) : \
+                         sizeof(struct sockaddr_in))
+
+#else
+
+#define SOCKADDR        union { struct sockaddr_in him4; }
+#define SOCKADDR_LEN    sizeof(SOCKADDR)
+
+#endif
+
+/************************************************************************
+ *  Utilities
+ */
+#ifdef __linux__
+extern int kernelIsV22();
+extern int kernelIsV24();
+#endif
+
+void NET_ThrowByNameWithLastError(JNIEnv *env, const char *name,
+                   const char *defaultDetail);
+
+
+#endif /* NET_UTILS_MD_H */
diff --git a/ojluni/src/main/native/nio.h b/ojluni/src/main/native/nio.h
new file mode 100755
index 0000000..738c6b3
--- /dev/null
+++ b/ojluni/src/main/native/nio.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2002, 2003, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include "sun_nio_ch_IOStatus.h"
+
+#define IOS_EOF              (sun_nio_ch_IOStatus_EOF)
+#define IOS_UNAVAILABLE      (sun_nio_ch_IOStatus_UNAVAILABLE)
+#define IOS_INTERRUPTED      (sun_nio_ch_IOStatus_INTERRUPTED)
+#define IOS_UNSUPPORTED      (sun_nio_ch_IOStatus_UNSUPPORTED)
+#define IOS_THROWN           (sun_nio_ch_IOStatus_THROWN)
+#define IOS_UNSUPPORTED_CASE (sun_nio_ch_IOStatus_UNSUPPORTED_CASE)
diff --git a/ojluni/src/main/native/nio_util.h b/ojluni/src/main/native/nio_util.h
new file mode 100755
index 0000000..441ea20
--- /dev/null
+++ b/ojluni/src/main/native/nio_util.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2001, 2008, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include "jni.h"
+#include "jni_util.h"
+#include "jvm.h"
+#include "jlong.h"
+#include <errno.h>
+#include <sys/types.h>
+
+#define RESTARTABLE(_cmd, _result) do { \
+  do { \
+    _result = _cmd; \
+  } while((_result == -1) && (errno == EINTR)); \
+} while(0)
+
+
+/* NIO utility procedures */
+
+
+/* Defined in IOUtil.c */
+
+jint fdval(JNIEnv *env, jobject fdo);
+
+jint convertReturnVal(JNIEnv *env, jint n, jboolean reading);
+jlong convertLongReturnVal(JNIEnv *env, jlong n, jboolean reading);
+
+
+/* Defined in Net.c */
+
+jint handleSocketError(JNIEnv *env, jint errorValue);
diff --git a/ojluni/src/main/native/sun_misc_NativeSignalHandler.h b/ojluni/src/main/native/sun_misc_NativeSignalHandler.h
new file mode 100755
index 0000000..266c578
--- /dev/null
+++ b/ojluni/src/main/native/sun_misc_NativeSignalHandler.h
@@ -0,0 +1,21 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class sun_misc_NativeSignalHandler */
+
+#ifndef _Included_sun_misc_NativeSignalHandler
+#define _Included_sun_misc_NativeSignalHandler
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class:     sun_misc_NativeSignalHandler
+ * Method:    handle0
+ * Signature: (IJ)V
+ */
+JNIEXPORT void JNICALL Java_sun_misc_NativeSignalHandler_handle0
+  (JNIEnv *, jclass, jint, jlong);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/ojluni/src/main/native/sun_misc_Signal.h b/ojluni/src/main/native/sun_misc_Signal.h
new file mode 100755
index 0000000..7196773
--- /dev/null
+++ b/ojluni/src/main/native/sun_misc_Signal.h
@@ -0,0 +1,37 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class sun_misc_Signal */
+
+#ifndef _Included_sun_misc_Signal
+#define _Included_sun_misc_Signal
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class:     sun_misc_Signal
+ * Method:    findSignal
+ * Signature: (Ljava/lang/String;)I
+ */
+JNIEXPORT jint JNICALL Java_sun_misc_Signal_findSignal
+  (JNIEnv *, jclass, jstring);
+
+/*
+ * Class:     sun_misc_Signal
+ * Method:    handle0
+ * Signature: (IJ)J
+ */
+JNIEXPORT jlong JNICALL Java_sun_misc_Signal_handle0
+  (JNIEnv *, jclass, jint, jlong);
+
+/*
+ * Class:     sun_misc_Signal
+ * Method:    raise0
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL Java_sun_misc_Signal_raise0
+  (JNIEnv *, jclass, jint);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/ojluni/src/main/native/sun_net_spi_DefaultProxySelector.h b/ojluni/src/main/native/sun_net_spi_DefaultProxySelector.h
new file mode 100755
index 0000000..eb1d0b9
--- /dev/null
+++ b/ojluni/src/main/native/sun_net_spi_DefaultProxySelector.h
@@ -0,0 +1,29 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class sun_net_spi_DefaultProxySelector */
+
+#ifndef _Included_sun_net_spi_DefaultProxySelector
+#define _Included_sun_net_spi_DefaultProxySelector
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class:     sun_net_spi_DefaultProxySelector
+ * Method:    init
+ * Signature: ()Z
+ */
+JNIEXPORT jboolean JNICALL Java_sun_net_spi_DefaultProxySelector_init
+  (JNIEnv *, jclass);
+
+/*
+ * Class:     sun_net_spi_DefaultProxySelector
+ * Method:    getSystemProxy
+ * Signature: (Ljava/lang/String;Ljava/lang/String;)Ljava/net/Proxy;
+ */
+JNIEXPORT jobject JNICALL Java_sun_net_spi_DefaultProxySelector_getSystemProxy
+  (JNIEnv *, jobject, jstring, jstring);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/ojluni/src/main/native/sun_nio_ch_FileChannelImpl.h b/ojluni/src/main/native/sun_nio_ch_FileChannelImpl.h
new file mode 100755
index 0000000..a8a053c
--- /dev/null
+++ b/ojluni/src/main/native/sun_nio_ch_FileChannelImpl.h
@@ -0,0 +1,63 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class sun_nio_ch_FileChannelImpl */
+
+#ifndef _Included_sun_nio_ch_FileChannelImpl
+#define _Included_sun_nio_ch_FileChannelImpl
+#ifdef __cplusplus
+extern "C" {
+#endif
+#undef sun_nio_ch_FileChannelImpl_MAPPED_TRANSFER_SIZE
+#define sun_nio_ch_FileChannelImpl_MAPPED_TRANSFER_SIZE 8388608LL
+#undef sun_nio_ch_FileChannelImpl_TRANSFER_SIZE
+#define sun_nio_ch_FileChannelImpl_TRANSFER_SIZE 8192L
+#undef sun_nio_ch_FileChannelImpl_MAP_RO
+#define sun_nio_ch_FileChannelImpl_MAP_RO 0L
+#undef sun_nio_ch_FileChannelImpl_MAP_RW
+#define sun_nio_ch_FileChannelImpl_MAP_RW 1L
+#undef sun_nio_ch_FileChannelImpl_MAP_PV
+#define sun_nio_ch_FileChannelImpl_MAP_PV 2L
+/*
+ * Class:     sun_nio_ch_FileChannelImpl
+ * Method:    map0
+ * Signature: (IJJ)J
+ */
+JNIEXPORT jlong JNICALL Java_sun_nio_ch_FileChannelImpl_map0
+  (JNIEnv *, jobject, jint, jlong, jlong);
+
+/*
+ * Class:     sun_nio_ch_FileChannelImpl
+ * Method:    unmap0
+ * Signature: (JJ)I
+ */
+JNIEXPORT jint JNICALL Java_sun_nio_ch_FileChannelImpl_unmap0
+  (JNIEnv *, jclass, jlong, jlong);
+
+/*
+ * Class:     sun_nio_ch_FileChannelImpl
+ * Method:    transferTo0
+ * Signature: (IJJI)J
+ */
+JNIEXPORT jlong JNICALL Java_sun_nio_ch_FileChannelImpl_transferTo0
+  (JNIEnv *, jobject, jint, jlong, jlong, jint);
+
+/*
+ * Class:     sun_nio_ch_FileChannelImpl
+ * Method:    position0
+ * Signature: (Ljava/io/FileDescriptor;J)J
+ */
+JNIEXPORT jlong JNICALL Java_sun_nio_ch_FileChannelImpl_position0
+  (JNIEnv *, jobject, jobject, jlong);
+
+/*
+ * Class:     sun_nio_ch_FileChannelImpl
+ * Method:    initIDs
+ * Signature: ()J
+ */
+JNIEXPORT jlong JNICALL Java_sun_nio_ch_FileChannelImpl_initIDs
+  (JNIEnv *, jclass);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/ojluni/src/main/native/sun_nio_ch_FileDispatcherImpl.h b/ojluni/src/main/native/sun_nio_ch_FileDispatcherImpl.h
new file mode 100755
index 0000000..df42fc1
--- /dev/null
+++ b/ojluni/src/main/native/sun_nio_ch_FileDispatcherImpl.h
@@ -0,0 +1,141 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class sun_nio_ch_FileDispatcherImpl */
+
+#ifndef _Included_sun_nio_ch_FileDispatcherImpl
+#define _Included_sun_nio_ch_FileDispatcherImpl
+#ifdef __cplusplus
+extern "C" {
+#endif
+#undef sun_nio_ch_FileDispatcherImpl_NO_LOCK
+#define sun_nio_ch_FileDispatcherImpl_NO_LOCK -1L
+#undef sun_nio_ch_FileDispatcherImpl_LOCKED
+#define sun_nio_ch_FileDispatcherImpl_LOCKED 0L
+#undef sun_nio_ch_FileDispatcherImpl_RET_EX_LOCK
+#define sun_nio_ch_FileDispatcherImpl_RET_EX_LOCK 1L
+#undef sun_nio_ch_FileDispatcherImpl_INTERRUPTED
+#define sun_nio_ch_FileDispatcherImpl_INTERRUPTED 2L
+/*
+ * Class:     sun_nio_ch_FileDispatcherImpl
+ * Method:    read0
+ * Signature: (Ljava/io/FileDescriptor;JI)I
+ */
+JNIEXPORT jint JNICALL Java_sun_nio_ch_FileDispatcherImpl_read0
+  (JNIEnv *, jclass, jobject, jlong, jint);
+
+/*
+ * Class:     sun_nio_ch_FileDispatcherImpl
+ * Method:    pread0
+ * Signature: (Ljava/io/FileDescriptor;JIJ)I
+ */
+JNIEXPORT jint JNICALL Java_sun_nio_ch_FileDispatcherImpl_pread0
+  (JNIEnv *, jclass, jobject, jlong, jint, jlong);
+
+/*
+ * Class:     sun_nio_ch_FileDispatcherImpl
+ * Method:    readv0
+ * Signature: (Ljava/io/FileDescriptor;JI)J
+ */
+JNIEXPORT jlong JNICALL Java_sun_nio_ch_FileDispatcherImpl_readv0
+  (JNIEnv *, jclass, jobject, jlong, jint);
+
+/*
+ * Class:     sun_nio_ch_FileDispatcherImpl
+ * Method:    write0
+ * Signature: (Ljava/io/FileDescriptor;JI)I
+ */
+JNIEXPORT jint JNICALL Java_sun_nio_ch_FileDispatcherImpl_write0
+  (JNIEnv *, jclass, jobject, jlong, jint);
+
+/*
+ * Class:     sun_nio_ch_FileDispatcherImpl
+ * Method:    pwrite0
+ * Signature: (Ljava/io/FileDescriptor;JIJ)I
+ */
+JNIEXPORT jint JNICALL Java_sun_nio_ch_FileDispatcherImpl_pwrite0
+  (JNIEnv *, jclass, jobject, jlong, jint, jlong);
+
+/*
+ * Class:     sun_nio_ch_FileDispatcherImpl
+ * Method:    writev0
+ * Signature: (Ljava/io/FileDescriptor;JI)J
+ */
+JNIEXPORT jlong JNICALL Java_sun_nio_ch_FileDispatcherImpl_writev0
+  (JNIEnv *, jclass, jobject, jlong, jint);
+
+/*
+ * Class:     sun_nio_ch_FileDispatcherImpl
+ * Method:    force0
+ * Signature: (Ljava/io/FileDescriptor;Z)I
+ */
+JNIEXPORT jint JNICALL Java_sun_nio_ch_FileDispatcherImpl_force0
+  (JNIEnv *, jclass, jobject, jboolean);
+
+/*
+ * Class:     sun_nio_ch_FileDispatcherImpl
+ * Method:    truncate0
+ * Signature: (Ljava/io/FileDescriptor;J)I
+ */
+JNIEXPORT jint JNICALL Java_sun_nio_ch_FileDispatcherImpl_truncate0
+  (JNIEnv *, jclass, jobject, jlong);
+
+/*
+ * Class:     sun_nio_ch_FileDispatcherImpl
+ * Method:    size0
+ * Signature: (Ljava/io/FileDescriptor;)J
+ */
+JNIEXPORT jlong JNICALL Java_sun_nio_ch_FileDispatcherImpl_size0
+  (JNIEnv *, jclass, jobject);
+
+/*
+ * Class:     sun_nio_ch_FileDispatcherImpl
+ * Method:    lock0
+ * Signature: (Ljava/io/FileDescriptor;ZJJZ)I
+ */
+JNIEXPORT jint JNICALL Java_sun_nio_ch_FileDispatcherImpl_lock0
+  (JNIEnv *, jclass, jobject, jboolean, jlong, jlong, jboolean);
+
+/*
+ * Class:     sun_nio_ch_FileDispatcherImpl
+ * Method:    release0
+ * Signature: (Ljava/io/FileDescriptor;JJ)V
+ */
+JNIEXPORT void JNICALL Java_sun_nio_ch_FileDispatcherImpl_release0
+  (JNIEnv *, jclass, jobject, jlong, jlong);
+
+/*
+ * Class:     sun_nio_ch_FileDispatcherImpl
+ * Method:    close0
+ * Signature: (Ljava/io/FileDescriptor;)V
+ */
+JNIEXPORT void JNICALL Java_sun_nio_ch_FileDispatcherImpl_close0
+  (JNIEnv *, jclass, jobject);
+
+/*
+ * Class:     sun_nio_ch_FileDispatcherImpl
+ * Method:    preClose0
+ * Signature: (Ljava/io/FileDescriptor;)V
+ */
+JNIEXPORT void JNICALL Java_sun_nio_ch_FileDispatcherImpl_preClose0
+  (JNIEnv *, jclass, jobject);
+
+/*
+ * Class:     sun_nio_ch_FileDispatcherImpl
+ * Method:    closeIntFD
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL Java_sun_nio_ch_FileDispatcherImpl_closeIntFD
+  (JNIEnv *, jclass, jint);
+
+/*
+ * Class:     sun_nio_ch_FileDispatcherImpl
+ * Method:    init
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_sun_nio_ch_FileDispatcherImpl_init
+  (JNIEnv *, jclass);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/ojluni/src/main/native/sun_nio_ch_FileKey.h b/ojluni/src/main/native/sun_nio_ch_FileKey.h
new file mode 100755
index 0000000..58f0659
--- /dev/null
+++ b/ojluni/src/main/native/sun_nio_ch_FileKey.h
@@ -0,0 +1,29 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class sun_nio_ch_FileKey */
+
+#ifndef _Included_sun_nio_ch_FileKey
+#define _Included_sun_nio_ch_FileKey
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class:     sun_nio_ch_FileKey
+ * Method:    init
+ * Signature: (Ljava/io/FileDescriptor;)V
+ */
+JNIEXPORT void JNICALL Java_sun_nio_ch_FileKey_init
+  (JNIEnv *, jobject, jobject);
+
+/*
+ * Class:     sun_nio_ch_FileKey
+ * Method:    initIDs
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_sun_nio_ch_FileKey_initIDs
+  (JNIEnv *, jclass);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/ojluni/src/main/native/sun_nio_ch_IOStatus.h b/ojluni/src/main/native/sun_nio_ch_IOStatus.h
new file mode 100755
index 0000000..0c2a02a
--- /dev/null
+++ b/ojluni/src/main/native/sun_nio_ch_IOStatus.h
@@ -0,0 +1,25 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class sun_nio_ch_IOStatus */
+
+#ifndef _Included_sun_nio_ch_IOStatus
+#define _Included_sun_nio_ch_IOStatus
+#ifdef __cplusplus
+extern "C" {
+#endif
+#undef sun_nio_ch_IOStatus_EOF
+#define sun_nio_ch_IOStatus_EOF -1L
+#undef sun_nio_ch_IOStatus_UNAVAILABLE
+#define sun_nio_ch_IOStatus_UNAVAILABLE -2L
+#undef sun_nio_ch_IOStatus_INTERRUPTED
+#define sun_nio_ch_IOStatus_INTERRUPTED -3L
+#undef sun_nio_ch_IOStatus_UNSUPPORTED
+#define sun_nio_ch_IOStatus_UNSUPPORTED -4L
+#undef sun_nio_ch_IOStatus_THROWN
+#define sun_nio_ch_IOStatus_THROWN -5L
+#undef sun_nio_ch_IOStatus_UNSUPPORTED_CASE
+#define sun_nio_ch_IOStatus_UNSUPPORTED_CASE -6L
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/ojluni/src/main/native/sun_nio_ch_IOUtil.h b/ojluni/src/main/native/sun_nio_ch_IOUtil.h
new file mode 100755
index 0000000..9eb2c99
--- /dev/null
+++ b/ojluni/src/main/native/sun_nio_ch_IOUtil.h
@@ -0,0 +1,85 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class sun_nio_ch_IOUtil */
+
+#ifndef _Included_sun_nio_ch_IOUtil
+#define _Included_sun_nio_ch_IOUtil
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class:     sun_nio_ch_IOUtil
+ * Method:    randomBytes
+ * Signature: ([B)Z
+ */
+JNIEXPORT jboolean JNICALL Java_sun_nio_ch_IOUtil_randomBytes
+  (JNIEnv *, jclass, jbyteArray);
+
+/*
+ * Class:     sun_nio_ch_IOUtil
+ * Method:    makePipe
+ * Signature: (Z)J
+ */
+JNIEXPORT jlong JNICALL Java_sun_nio_ch_IOUtil_makePipe
+  (JNIEnv *, jclass, jboolean);
+
+/*
+ * Class:     sun_nio_ch_IOUtil
+ * Method:    drain
+ * Signature: (I)Z
+ */
+JNIEXPORT jboolean JNICALL Java_sun_nio_ch_IOUtil_drain
+  (JNIEnv *, jclass, jint);
+
+/*
+ * Class:     sun_nio_ch_IOUtil
+ * Method:    configureBlocking
+ * Signature: (Ljava/io/FileDescriptor;Z)V
+ */
+JNIEXPORT void JNICALL Java_sun_nio_ch_IOUtil_configureBlocking
+  (JNIEnv *, jclass, jobject, jboolean);
+
+/*
+ * Class:     sun_nio_ch_IOUtil
+ * Method:    fdVal
+ * Signature: (Ljava/io/FileDescriptor;)I
+ */
+JNIEXPORT jint JNICALL Java_sun_nio_ch_IOUtil_fdVal
+  (JNIEnv *, jclass, jobject);
+
+/*
+ * Class:     sun_nio_ch_IOUtil
+ * Method:    setfdVal
+ * Signature: (Ljava/io/FileDescriptor;I)V
+ */
+JNIEXPORT void JNICALL Java_sun_nio_ch_IOUtil_setfdVal
+  (JNIEnv *, jclass, jobject, jint);
+
+/*
+ * Class:     sun_nio_ch_IOUtil
+ * Method:    iovMax
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL Java_sun_nio_ch_IOUtil_iovMax
+  (JNIEnv *, jclass);
+
+/*
+ * Class:     sun_nio_ch_IOUtil
+ * Method:    fdLimit
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL Java_sun_nio_ch_IOUtil_fdLimit
+  (JNIEnv *, jclass);
+
+/*
+ * Class:     sun_nio_ch_IOUtil
+ * Method:    initIDs
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_sun_nio_ch_IOUtil_initIDs
+  (JNIEnv *, jclass);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/ojluni/src/main/native/sun_nio_ch_NativeThread.h b/ojluni/src/main/native/sun_nio_ch_NativeThread.h
new file mode 100755
index 0000000..00d16c0
--- /dev/null
+++ b/ojluni/src/main/native/sun_nio_ch_NativeThread.h
@@ -0,0 +1,37 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class sun_nio_ch_NativeThread */
+
+#ifndef _Included_sun_nio_ch_NativeThread
+#define _Included_sun_nio_ch_NativeThread
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class:     sun_nio_ch_NativeThread
+ * Method:    current
+ * Signature: ()J
+ */
+JNIEXPORT jlong JNICALL Java_sun_nio_ch_NativeThread_current
+  (JNIEnv *, jclass);
+
+/*
+ * Class:     sun_nio_ch_NativeThread
+ * Method:    signal
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_sun_nio_ch_NativeThread_signal
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     sun_nio_ch_NativeThread
+ * Method:    init
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_sun_nio_ch_NativeThread_init
+  (JNIEnv *, jclass);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/ojluni/src/main/native/zip_util.c b/ojluni/src/main/native/zip_util.c
new file mode 100755
index 0000000..00c231b
--- /dev/null
+++ b/ojluni/src/main/native/zip_util.c
@@ -0,0 +1,1462 @@
+/*
+ * Copyright (c) 1995, 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * Support for reading ZIP/JAR files.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <string.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <time.h>
+#include <ctype.h>
+#include <assert.h>
+
+#include "jni.h"
+#include "jni_util.h"
+#include "jlong.h"
+#include "jvm.h"
+#include "io_util.h"
+#include "io_util_md.h"
+#include "zip_util.h"
+#include <zlib.h>
+
+#ifdef _ALLBSD_SOURCE
+#define off64_t off_t
+#define mmap64 mmap
+#endif
+
+/* USE_MMAP means mmap the CEN & ENDHDR part of the zip file. */
+#ifdef USE_MMAP
+#include <sys/mman.h>
+#endif
+
+#define MAXREFS 0xFFFF  /* max number of open zip file references */
+
+#define MCREATE()      JVM_RawMonitorCreate()
+#define MLOCK(lock)    JVM_RawMonitorEnter(lock)
+#define MUNLOCK(lock)  JVM_RawMonitorExit(lock)
+#define MDESTROY(lock) JVM_RawMonitorDestroy(lock)
+
+#define CENSIZE(cen) (CENHDR + CENNAM(cen) + CENEXT(cen) + CENCOM(cen))
+
+static jzfile *zfiles = 0;      /* currently open zip files */
+static void *zfiles_lock = 0;
+
+static void freeCEN(jzfile *);
+
+#ifndef PATH_MAX
+#define PATH_MAX 1024
+#endif
+
+static jint INITIAL_META_COUNT = 2;   /* initial number of entries in meta name array */
+
+/*
+ * The ZFILE_* functions exist to provide some platform-independence with
+ * respect to file access needs.
+ */
+
+/*
+ * Opens the named file for reading, returning a ZFILE.
+ *
+ * Compare this with winFileHandleOpen in windows/native/java/io/io_util_md.c.
+ * This function does not take JNIEnv* and uses CreateFile (instead of
+ * CreateFileW).  The expectation is that this function will be called only
+ * from ZIP_Open_Generic, which in turn is used by the JVM, where we do not
+ * need to concern ourselves with wide chars.
+ */
+static ZFILE
+ZFILE_Open(const char *fname, int flags) {
+#ifdef WIN32
+    const DWORD access =
+        (flags & O_RDWR)   ? (GENERIC_WRITE | GENERIC_READ) :
+        (flags & O_WRONLY) ?  GENERIC_WRITE :
+        GENERIC_READ;
+    const DWORD sharing =
+        FILE_SHARE_READ | FILE_SHARE_WRITE;
+    const DWORD disposition =
+        /* Note: O_TRUNC overrides O_CREAT */
+        (flags & O_TRUNC) ? CREATE_ALWAYS :
+        (flags & O_CREAT) ? OPEN_ALWAYS   :
+        OPEN_EXISTING;
+    const DWORD  maybeWriteThrough =
+        (flags & (O_SYNC | O_DSYNC)) ?
+        FILE_FLAG_WRITE_THROUGH :
+        FILE_ATTRIBUTE_NORMAL;
+    const DWORD maybeDeleteOnClose =
+        (flags & O_TEMPORARY) ?
+        FILE_FLAG_DELETE_ON_CLOSE :
+        FILE_ATTRIBUTE_NORMAL;
+    const DWORD flagsAndAttributes = maybeWriteThrough | maybeDeleteOnClose;
+
+    return (jlong) CreateFile(
+        fname,          /* Wide char path name */
+        access,         /* Read and/or write permission */
+        sharing,        /* File sharing flags */
+        NULL,           /* Security attributes */
+        disposition,        /* creation disposition */
+        flagsAndAttributes, /* flags and attributes */
+        NULL);
+#else
+    return JVM_Open(fname, flags, 0);
+#endif
+}
+
+/*
+ * The io_util_md.h files do not provide IO_CLOSE, hence we use platform
+ * specifics.
+ */
+static void
+ZFILE_Close(ZFILE zfd) {
+#ifdef WIN32
+    CloseHandle((HANDLE) zfd);
+#else
+    JVM_Close(zfd);
+#endif
+}
+
+static int
+ZFILE_read(ZFILE zfd, char *buf, jint nbytes) {
+#ifdef WIN32
+    return (int) IO_Read(zfd, buf, nbytes);
+#else
+    /*
+     * Calling JVM_Read will return JVM_IO_INTR when Thread.interrupt is called
+     * only on Solaris. Continue reading jar file in this case is the best
+     * thing to do since zip file reading is relatively fast and it is very onerous
+     * for a interrupted thread to deal with this kind of hidden I/O. However, handling
+     * JVM_IO_INTR is tricky and could cause undesired side effect. So we decided
+     * to simply call "read" on Solaris/Linux. See details in bug 6304463.
+     */
+    return read(zfd, buf, nbytes);
+#endif
+}
+
+/*
+ * Initialize zip file support. Return 0 if successful otherwise -1
+ * if could not be initialized.
+ */
+static jint
+InitializeZip()
+{
+    static jboolean inited = JNI_FALSE;
+
+    // Initialize errno to 0.  It may be set later (e.g. during memory
+    // allocation) but we can disregard previous values.
+    errno = 0;
+
+    if (inited)
+        return 0;
+    zfiles_lock = MCREATE();
+    if (zfiles_lock == 0) {
+        return -1;
+    }
+    inited = JNI_TRUE;
+
+    return 0;
+}
+
+/*
+ * Reads len bytes of data into buf.
+ * Returns 0 if all bytes could be read, otherwise returns -1.
+ */
+static int
+readFully(ZFILE zfd, void *buf, jlong len) {
+  char *bp = (char *) buf;
+
+  while (len > 0) {
+        jlong limit = ((((jlong) 1) << 31) - 1);
+        jint count = (len < limit) ?
+            (jint) len :
+            (jint) limit;
+        jint n = ZFILE_read(zfd, bp, count);
+        if (n > 0) {
+            bp += n;
+            len -= n;
+        } else if (n == JVM_IO_ERR && errno == EINTR) {
+          /* Retry after EINTR (interrupted by signal).
+             We depend on the fact that JVM_IO_ERR == -1. */
+            continue;
+        } else { /* EOF or IO error */
+            return -1;
+        }
+    }
+    return 0;
+}
+
+/*
+ * Reads len bytes of data from the specified offset into buf.
+ * Returns 0 if all bytes could be read, otherwise returns -1.
+ */
+static int
+readFullyAt(ZFILE zfd, void *buf, jlong len, jlong offset)
+{
+    if (IO_Lseek(zfd, offset, SEEK_SET) == -1) {
+        return -1; /* lseek failure. */
+    }
+
+    return readFully(zfd, buf, len);
+}
+
+/*
+ * Allocates a new zip file object for the specified file name.
+ * Returns the zip file object or NULL if not enough memory.
+ */
+static jzfile *
+allocZip(const char *name)
+{
+    jzfile *zip;
+    if (((zip = calloc(1, sizeof(jzfile))) != NULL) &&
+        ((zip->name = strdup(name))        != NULL) &&
+        ((zip->lock = MCREATE())           != NULL)) {
+        zip->zfd = -1;
+        return zip;
+    }
+
+    if (zip != NULL) {
+        free(zip->name);
+        free(zip);
+    }
+    return NULL;
+}
+
+/*
+ * Frees all native resources owned by the specified zip file object.
+ */
+static void
+freeZip(jzfile *zip)
+{
+    /* First free any cached jzentry */
+    ZIP_FreeEntry(zip,0);
+    if (zip->lock != NULL) MDESTROY(zip->lock);
+    free(zip->name);
+    freeCEN(zip);
+
+#ifdef USE_MMAP
+    if (zip->usemmap) {
+        if (zip->maddr != NULL)
+            munmap((char *)zip->maddr, zip->mlen);
+    } else
+#endif
+    {
+        free(zip->cencache.data);
+    }
+    if (zip->comment != NULL)
+        free(zip->comment);
+    if (zip->zfd != -1) ZFILE_Close(zip->zfd);
+    free(zip);
+}
+
+/* The END header is followed by a variable length comment of size < 64k. */
+static const jlong END_MAXLEN = 0xFFFF + ENDHDR;
+
+#define READBLOCKSZ 128
+
+static jboolean verifyEND(jzfile *zip, jlong endpos, char *endbuf) {
+    /* ENDSIG matched, however the size of file comment in it does not
+       match the real size. One "common" cause for this problem is some
+       "extra" bytes are padded at the end of the zipfile.
+       Let's do some extra verification, we don't care about the performance
+       in this situation.
+     */
+    jlong cenpos = endpos - ENDSIZ(endbuf);
+    jlong locpos = cenpos - ENDOFF(endbuf);
+    char buf[4];
+    return (cenpos >= 0 &&
+            locpos >= 0 &&
+            readFullyAt(zip->zfd, buf, sizeof(buf), cenpos) != -1 &&
+            GETSIG(buf) == CENSIG &&
+            readFullyAt(zip->zfd, buf, sizeof(buf), locpos) != -1 &&
+            GETSIG(buf) == LOCSIG);
+}
+
+/*
+ * Searches for end of central directory (END) header. The contents of
+ * the END header will be read and placed in endbuf. Returns the file
+ * position of the END header, otherwise returns -1 if the END header
+ * was not found or an error occurred.
+ */
+static jlong
+findEND(jzfile *zip, void *endbuf)
+{
+    char buf[READBLOCKSZ];
+    jlong pos;
+    const jlong len = zip->len;
+    const ZFILE zfd = zip->zfd;
+    const jlong minHDR = len - END_MAXLEN > 0 ? len - END_MAXLEN : 0;
+    const jlong minPos = minHDR - (sizeof(buf)-ENDHDR);
+    jint clen;
+
+    for (pos = len - sizeof(buf); pos >= minPos; pos -= (sizeof(buf)-ENDHDR)) {
+
+        int i;
+        jlong off = 0;
+        if (pos < 0) {
+            /* Pretend there are some NUL bytes before start of file */
+            off = -pos;
+            memset(buf, '\0', (size_t)off);
+        }
+
+        if (readFullyAt(zfd, buf + off, sizeof(buf) - off,
+                        pos + off) == -1) {
+            return -1;  /* System error */
+        }
+
+        /* Now scan the block backwards for END header signature */
+        for (i = sizeof(buf) - ENDHDR; i >= 0; i--) {
+            if (buf[i+0] == 'P'    &&
+                buf[i+1] == 'K'    &&
+                buf[i+2] == '\005' &&
+                buf[i+3] == '\006' &&
+                ((pos + i + ENDHDR + ENDCOM(buf + i) == len)
+                 || verifyEND(zip, pos + i, buf + i))) {
+                /* Found END header */
+                memcpy(endbuf, buf + i, ENDHDR);
+
+                clen = ENDCOM(endbuf);
+                if (clen != 0) {
+                    zip->comment = malloc(clen + 1);
+                    if (zip->comment == NULL) {
+                        return -1;
+                    }
+                    if (readFullyAt(zfd, zip->comment, clen, pos + i + ENDHDR)
+                        == -1) {
+                        free(zip->comment);
+                        zip->comment = NULL;
+                        return -1;
+                    }
+                    zip->comment[clen] = '\0';
+                    zip->clen = clen;
+                }
+                return pos + i;
+            }
+        }
+    }
+
+    return -1; /* END header not found */
+}
+
+/*
+ * Searches for the ZIP64 end of central directory (END) header. The
+ * contents of the ZIP64 END header will be read and placed in end64buf.
+ * Returns the file position of the ZIP64 END header, otherwise returns
+ * -1 if the END header was not found or an error occurred.
+ *
+ * The ZIP format specifies the "position" of each related record as
+ *   ...
+ *   [central directory]
+ *   [zip64 end of central directory record]
+ *   [zip64 end of central directory locator]
+ *   [end of central directory record]
+ *
+ * The offset of zip64 end locator can be calculated from endpos as
+ * "endpos - ZIP64_LOCHDR".
+ * The "offset" of zip64 end record is stored in zip64 end locator.
+ */
+static jlong
+findEND64(jzfile *zip, void *end64buf, jlong endpos)
+{
+    char loc64[ZIP64_LOCHDR];
+    jlong end64pos;
+    if (readFullyAt(zip->zfd, loc64, ZIP64_LOCHDR, endpos - ZIP64_LOCHDR) == -1) {
+        return -1;    // end64 locator not found
+    }
+    end64pos = ZIP64_LOCOFF(loc64);
+    if (readFullyAt(zip->zfd, end64buf, ZIP64_ENDHDR, end64pos) == -1) {
+        return -1;    // end64 record not found
+    }
+    return end64pos;
+}
+
+/*
+ * Returns a hash code value for a C-style NUL-terminated string.
+ */
+static unsigned int
+hash(const char *s)
+{
+    int h = 0;
+    while (*s != '\0')
+        h = 31*h + *s++;
+    return h;
+}
+
+/*
+ * Returns a hash code value for a string of a specified length.
+ */
+static unsigned int
+hashN(const char *s, int length)
+{
+    int h = 0;
+    while (length-- > 0)
+        h = 31*h + *s++;
+    return h;
+}
+
+static unsigned int
+hash_append(unsigned int hash, char c)
+{
+    return ((int)hash)*31 + c;
+}
+
+/*
+ * Returns true if the specified entry's name begins with the string
+ * "META-INF/" irrespective of case.
+ */
+static int
+isMetaName(const char *name, int length)
+{
+    const char *s;
+    if (length < (int)sizeof("META-INF/") - 1)
+        return 0;
+    for (s = "META-INF/"; *s != '\0'; s++) {
+        char c = *name++;
+        // Avoid toupper; it's locale-dependent
+        if (c >= 'a' && c <= 'z') c += 'A' - 'a';
+        if (*s != c)
+            return 0;
+    }
+    return 1;
+}
+
+/*
+ * Increases the capacity of zip->metanames.
+ * Returns non-zero in case of allocation error.
+ */
+static int
+growMetaNames(jzfile *zip)
+{
+    jint i;
+    /* double the meta names array */
+    const jint new_metacount = zip->metacount << 1;
+    zip->metanames =
+        realloc(zip->metanames, new_metacount * sizeof(zip->metanames[0]));
+    if (zip->metanames == NULL) return -1;
+    for (i = zip->metacount; i < new_metacount; i++)
+        zip->metanames[i] = NULL;
+    zip->metacurrent = zip->metacount;
+    zip->metacount = new_metacount;
+    return 0;
+}
+
+/*
+ * Adds name to zip->metanames.
+ * Returns non-zero in case of allocation error.
+ */
+static int
+addMetaName(jzfile *zip, const char *name, int length)
+{
+    jint i;
+    if (zip->metanames == NULL) {
+      zip->metacount = INITIAL_META_COUNT;
+      zip->metanames = calloc(zip->metacount, sizeof(zip->metanames[0]));
+      if (zip->metanames == NULL) return -1;
+      zip->metacurrent = 0;
+    }
+
+    i = zip->metacurrent;
+
+    /* current meta name array isn't full yet. */
+    if (i < zip->metacount) {
+      zip->metanames[i] = (char *) malloc(length+1);
+      if (zip->metanames[i] == NULL) return -1;
+      memcpy(zip->metanames[i], name, length);
+      zip->metanames[i][length] = '\0';
+      zip->metacurrent++;
+      return 0;
+    }
+
+    /* No free entries in zip->metanames? */
+    if (growMetaNames(zip) != 0) return -1;
+    return addMetaName(zip, name, length);
+}
+
+static void
+freeMetaNames(jzfile *zip)
+{
+    if (zip->metanames) {
+        jint i;
+        for (i = 0; i < zip->metacount; i++)
+            free(zip->metanames[i]);
+        free(zip->metanames);
+        zip->metanames = NULL;
+    }
+}
+
+/* Free Zip data allocated by readCEN() */
+static void
+freeCEN(jzfile *zip)
+{
+    free(zip->entries); zip->entries = NULL;
+    free(zip->table);   zip->table   = NULL;
+    freeMetaNames(zip);
+}
+
+/*
+ * Counts the number of CEN headers in a central directory extending
+ * from BEG to END.  Might return a bogus answer if the zip file is
+ * corrupt, but will not crash.
+ */
+static jint
+countCENHeaders(unsigned char *beg, unsigned char *end)
+{
+    jint count = 0;
+    ptrdiff_t i;
+    for (i = 0; i + CENHDR <= end - beg; i += CENSIZE(beg + i))
+        count++;
+    return count;
+}
+
+#define ZIP_FORMAT_ERROR(message) \
+if (1) { zip->msg = message; goto Catch; } else ((void)0)
+
+/*
+ * Reads zip file central directory. Returns the file position of first
+ * CEN header, otherwise returns -1 if an error occured. If zip->msg != NULL
+ * then the error was a zip format error and zip->msg has the error text.
+ * Always pass in -1 for knownTotal; it's used for a recursive call.
+ */
+static jlong
+readCEN(jzfile *zip, jint knownTotal)
+{
+    /* Following are unsigned 32-bit */
+    jlong endpos, end64pos, cenpos, cenlen, cenoff;
+    /* Following are unsigned 16-bit */
+    jint total, tablelen, i, j;
+    unsigned char *cenbuf = NULL;
+    unsigned char *cenend;
+    unsigned char *cp;
+#ifdef USE_MMAP
+    static jlong pagesize;
+    jlong offset;
+#endif
+    unsigned char endbuf[ENDHDR];
+    jint endhdrlen = ENDHDR;
+    jzcell *entries;
+    jint *table;
+
+    /* Clear previous zip error */
+    zip->msg = NULL;
+    /* Get position of END header */
+    if ((endpos = findEND(zip, endbuf)) == -1)
+        return -1; /* no END header or system error */
+
+    if (endpos == 0) return 0;  /* only END header present */
+
+    freeCEN(zip);
+   /* Get position and length of central directory */
+    cenlen = ENDSIZ(endbuf);
+    cenoff = ENDOFF(endbuf);
+    total  = ENDTOT(endbuf);
+    if (cenlen == ZIP64_MAGICVAL || cenoff == ZIP64_MAGICVAL ||
+        total == ZIP64_MAGICCOUNT) {
+        unsigned char end64buf[ZIP64_ENDHDR];
+        if ((end64pos = findEND64(zip, end64buf, endpos)) != -1) {
+            cenlen = ZIP64_ENDSIZ(end64buf);
+            cenoff = ZIP64_ENDOFF(end64buf);
+            total = (jint)ZIP64_ENDTOT(end64buf);
+            endpos = end64pos;
+            endhdrlen = ZIP64_ENDHDR;
+        }
+    }
+
+    if (cenlen > endpos)
+        ZIP_FORMAT_ERROR("invalid END header (bad central directory size)");
+    cenpos = endpos - cenlen;
+
+    /* Get position of first local file (LOC) header, taking into
+     * account that there may be a stub prefixed to the zip file. */
+    zip->locpos = cenpos - cenoff;
+    if (zip->locpos < 0)
+        ZIP_FORMAT_ERROR("invalid END header (bad central directory offset)");
+
+#ifdef USE_MMAP
+    if (zip->usemmap) {
+      /* On Solaris & Linux prior to JDK 6, we used to mmap the whole jar file to
+       * read the jar file contents. However, this greatly increased the perceived
+       * footprint numbers because the mmap'ed pages were adding into the totals shown
+       * by 'ps' and 'top'. We switched to mmaping only the central directory of jar
+       * file while calling 'read' to read the rest of jar file. Here are a list of
+       * reasons apart from above of why we are doing so:
+       * 1. Greatly reduces mmap overhead after startup complete;
+       * 2. Avoids dual path code maintainance;
+       * 3. Greatly reduces risk of address space (not virtual memory) exhaustion.
+       */
+        if (pagesize == 0) {
+            pagesize = (jlong)sysconf(_SC_PAGESIZE);
+            if (pagesize == 0) goto Catch;
+        }
+        if (cenpos > pagesize) {
+            offset = cenpos & ~(pagesize - 1);
+        } else {
+            offset = 0;
+        }
+        /* When we are not calling recursively, knownTotal is -1. */
+        if (knownTotal == -1) {
+            void* mappedAddr;
+            /* Mmap the CEN and END part only. We have to figure
+               out the page size in order to make offset to be multiples of
+               page size.
+            */
+            zip->mlen = cenpos - offset + cenlen + endhdrlen;
+            zip->offset = offset;
+            mappedAddr = mmap64(0, zip->mlen, PROT_READ, MAP_SHARED, zip->zfd, (off64_t) offset);
+            zip->maddr = (mappedAddr == (void*) MAP_FAILED) ? NULL :
+                (unsigned char*)mappedAddr;
+
+            if (zip->maddr == NULL) {
+                jio_fprintf(stderr, "mmap failed for CEN and END part of zip file\n");
+                goto Catch;
+            }
+        }
+        cenbuf = zip->maddr + cenpos - offset;
+    } else
+#endif
+    {
+        if ((cenbuf = malloc((size_t) cenlen)) == NULL ||
+            (readFullyAt(zip->zfd, cenbuf, cenlen, cenpos) == -1))
+        goto Catch;
+    }
+
+    cenend = cenbuf + cenlen;
+
+    /* Initialize zip file data structures based on the total number
+     * of central directory entries as stored in ENDTOT.  Since this
+     * is a 2-byte field, but we (and other zip implementations)
+     * support approx. 2**31 entries, we do not trust ENDTOT, but
+     * treat it only as a strong hint.  When we call ourselves
+     * recursively, knownTotal will have the "true" value.
+     *
+     * Keep this path alive even with the Zip64 END support added, just
+     * for zip files that have more than 0xffff entries but don't have
+     * the Zip64 enabled.
+     */
+    total = (knownTotal != -1) ? knownTotal : total;
+    entries  = zip->entries  = calloc(total, sizeof(entries[0]));
+    tablelen = zip->tablelen = ((total/2) | 1); // Odd -> fewer collisions
+    table    = zip->table    = malloc(tablelen * sizeof(table[0]));
+    if (entries == NULL || table == NULL) goto Catch;
+    for (j = 0; j < tablelen; j++)
+        table[j] = ZIP_ENDCHAIN;
+
+    /* Iterate through the entries in the central directory */
+    for (i = 0, cp = cenbuf; cp <= cenend - CENHDR; i++, cp += CENSIZE(cp)) {
+        /* Following are unsigned 16-bit */
+        jint method, nlen;
+        unsigned int hsh;
+
+        if (i >= total) {
+            /* This will only happen if the zip file has an incorrect
+             * ENDTOT field, which usually means it contains more than
+             * 65535 entries. */
+            cenpos = readCEN(zip, countCENHeaders(cenbuf, cenend));
+            goto Finally;
+        }
+
+        method = CENHOW(cp);
+        nlen   = CENNAM(cp);
+
+        if (GETSIG(cp) != CENSIG)
+            ZIP_FORMAT_ERROR("invalid CEN header (bad signature)");
+        if (CENFLG(cp) & 1)
+            ZIP_FORMAT_ERROR("invalid CEN header (encrypted entry)");
+        if (method != STORED && method != DEFLATED)
+            ZIP_FORMAT_ERROR("invalid CEN header (bad compression method)");
+        if (cp + CENHDR + nlen > cenend)
+            ZIP_FORMAT_ERROR("invalid CEN header (bad header size)");
+
+        /* if the entry is metadata add it to our metadata names */
+        if (isMetaName((char *)cp+CENHDR, nlen))
+            if (addMetaName(zip, (char *)cp+CENHDR, nlen) != 0)
+                goto Catch;
+
+        /* Record the CEN offset and the name hash in our hash cell. */
+        entries[i].cenpos = cenpos + (cp - cenbuf);
+        entries[i].hash = hashN((char *)cp+CENHDR, nlen);
+
+        /* Add the entry to the hash table */
+        hsh = entries[i].hash % tablelen;
+        entries[i].next = table[hsh];
+        table[hsh] = i;
+    }
+    if (cp != cenend)
+        ZIP_FORMAT_ERROR("invalid CEN header (bad header size)");
+
+    zip->total = i;
+    goto Finally;
+
+ Catch:
+    freeCEN(zip);
+    cenpos = -1;
+
+ Finally:
+#ifdef USE_MMAP
+    if (!zip->usemmap)
+#endif
+        free(cenbuf);
+
+    return cenpos;
+}
+
+/*
+ * Opens a zip file with the specified mode. Returns the jzfile object
+ * or NULL if an error occurred. If a zip error occurred then *pmsg will
+ * be set to the error message text if pmsg != 0. Otherwise, *pmsg will be
+ * set to NULL. Caller is responsible to free the error message.
+ */
+jzfile *
+ZIP_Open_Generic(const char *name, char **pmsg, int mode, jlong lastModified)
+{
+    jzfile *zip = NULL;
+
+    /* Clear zip error message */
+    if (pmsg != 0) {
+        *pmsg = NULL;
+    }
+
+    zip = ZIP_Get_From_Cache(name, pmsg, lastModified);
+
+    if (zip == NULL && *pmsg == NULL) {
+        ZFILE zfd = ZFILE_Open(name, mode);
+        zip = ZIP_Put_In_Cache(name, zfd, pmsg, lastModified);
+    }
+    return zip;
+}
+
+/*
+ * Returns the jzfile corresponding to the given file name from the cache of
+ * zip files, or NULL if the file is not in the cache.  If the name is longer
+ * than PATH_MAX or a zip error occurred then *pmsg will be set to the error
+ * message text if pmsg != 0. Otherwise, *pmsg will be set to NULL. Caller
+ * is responsible to free the error message.
+ */
+jzfile *
+ZIP_Get_From_Cache(const char *name, char **pmsg, jlong lastModified)
+{
+    char buf[PATH_MAX];
+    jzfile *zip;
+
+    if (InitializeZip()) {
+        return NULL;
+    }
+
+    /* Clear zip error message */
+    if (pmsg != 0) {
+        *pmsg = NULL;
+    }
+
+    if (strlen(name) >= PATH_MAX) {
+        if (pmsg) {
+            *pmsg = strdup("zip file name too long");
+        }
+        return NULL;
+    }
+    strcpy(buf, name);
+    JVM_NativePath(buf);
+    name = buf;
+
+    MLOCK(zfiles_lock);
+    for (zip = zfiles; zip != NULL; zip = zip->next) {
+        if (strcmp(name, zip->name) == 0
+            && (zip->lastModified == lastModified || zip->lastModified == 0)
+            && zip->refs < MAXREFS) {
+            zip->refs++;
+            break;
+        }
+    }
+    MUNLOCK(zfiles_lock);
+    return zip;
+}
+
+/*
+ * Reads data from the given file descriptor to create a jzfile, puts the
+ * jzfile in a cache, and returns that jzfile.  Returns NULL in case of error.
+ * If a zip error occurs, then *pmsg will be set to the error message text if
+ * pmsg != 0. Otherwise, *pmsg will be set to NULL. Caller is responsible to
+ * free the error message.
+ */
+
+jzfile *
+ZIP_Put_In_Cache(const char *name, ZFILE zfd, char **pmsg, jlong lastModified)
+{
+    return ZIP_Put_In_Cache0(name, zfd, pmsg, lastModified, JNI_TRUE);
+}
+
+jzfile *
+ZIP_Put_In_Cache0(const char *name, ZFILE zfd, char **pmsg, jlong lastModified,
+                 jboolean usemmap)
+{
+    char errbuf[256];
+    jlong len;
+    jzfile *zip;
+
+    if ((zip = allocZip(name)) == NULL) {
+        return NULL;
+    }
+
+#ifdef USE_MMAP
+    zip->usemmap = usemmap;
+#endif
+    zip->refs = 1;
+    zip->lastModified = lastModified;
+
+    if (zfd == -1) {
+        if (pmsg && JVM_GetLastErrorString(errbuf, sizeof(errbuf)) > 0)
+            *pmsg = strdup(errbuf);
+        freeZip(zip);
+        return NULL;
+    }
+
+    // Assumption, zfd refers to start of file. Trivially, reuse errbuf.
+    if (readFully(zfd, errbuf, 4) != -1) {  // errors will be handled later
+        if (GETSIG(errbuf) == LOCSIG)
+            zip->locsig = JNI_TRUE;
+        else
+            zip->locsig = JNI_FALSE;
+    }
+
+    len = zip->len = IO_Lseek(zfd, 0, SEEK_END);
+    if (len <= 0) {
+        if (len == 0) { /* zip file is empty */
+            if (pmsg) {
+                *pmsg = strdup("zip file is empty");
+            }
+        } else { /* error */
+            if (pmsg && JVM_GetLastErrorString(errbuf, sizeof(errbuf)) > 0)
+                *pmsg = strdup(errbuf);
+        }
+        ZFILE_Close(zfd);
+        freeZip(zip);
+        return NULL;
+    }
+
+    zip->zfd = zfd;
+    if (readCEN(zip, -1) < 0) {
+        /* An error occurred while trying to read the zip file */
+        if (pmsg != 0) {
+            /* Set the zip error message */
+            if (zip->msg != NULL)
+                *pmsg = strdup(zip->msg);
+        }
+        freeZip(zip);
+        return NULL;
+    }
+    MLOCK(zfiles_lock);
+    zip->next = zfiles;
+    zfiles = zip;
+    MUNLOCK(zfiles_lock);
+
+    return zip;
+}
+
+/*
+ * Opens a zip file for reading. Returns the jzfile object or NULL
+ * if an error occurred. If a zip error occurred then *msg will be
+ * set to the error message text if msg != 0. Otherwise, *msg will be
+ * set to NULL. Caller doesn't need to free the error message.
+ */
+jzfile * JNICALL
+ZIP_Open(const char *name, char **pmsg)
+{
+    jzfile *file = ZIP_Open_Generic(name, pmsg, O_RDONLY, 0);
+    if (file == NULL && pmsg != NULL && *pmsg != NULL) {
+        free(*pmsg);
+        *pmsg = "Zip file open error";
+    }
+    return file;
+}
+
+/*
+ * Closes the specified zip file object.
+ */
+void JNICALL
+ZIP_Close(jzfile *zip)
+{
+    MLOCK(zfiles_lock);
+    if (--zip->refs > 0) {
+        /* Still more references so just return */
+        MUNLOCK(zfiles_lock);
+        return;
+    }
+    /* No other references so close the file and remove from list */
+    if (zfiles == zip) {
+        zfiles = zfiles->next;
+    } else {
+        jzfile *zp;
+        for (zp = zfiles; zp->next != 0; zp = zp->next) {
+            if (zp->next == zip) {
+                zp->next = zip->next;
+                break;
+            }
+        }
+    }
+    MUNLOCK(zfiles_lock);
+    freeZip(zip);
+    return;
+}
+
+/* Empirically, most CEN headers are smaller than this. */
+#define AMPLE_CEN_HEADER_SIZE 160
+
+/* A good buffer size when we want to read CEN headers sequentially. */
+#define CENCACHE_PAGESIZE 8192
+
+static char *
+readCENHeader(jzfile *zip, jlong cenpos, jint bufsize)
+{
+    jint censize;
+    ZFILE zfd = zip->zfd;
+    char *cen;
+    if (bufsize > zip->len - cenpos)
+        bufsize = (jint)(zip->len - cenpos);
+    if ((cen = malloc(bufsize)) == NULL)       goto Catch;
+    if (readFullyAt(zfd, cen, bufsize, cenpos) == -1)     goto Catch;
+    censize = CENSIZE(cen);
+    if (censize <= bufsize) return cen;
+    if ((cen = realloc(cen, censize)) == NULL)              goto Catch;
+    if (readFully(zfd, cen+bufsize, censize-bufsize) == -1) goto Catch;
+    return cen;
+
+ Catch:
+    free(cen);
+    return NULL;
+}
+
+static char *
+sequentialAccessReadCENHeader(jzfile *zip, jlong cenpos)
+{
+    cencache *cache = &zip->cencache;
+    char *cen;
+    if (cache->data != NULL
+        && (cenpos >= cache->pos)
+        && (cenpos + CENHDR <= cache->pos + CENCACHE_PAGESIZE))
+    {
+        cen = cache->data + cenpos - cache->pos;
+        if (cenpos + CENSIZE(cen) <= cache->pos + CENCACHE_PAGESIZE)
+            /* A cache hit */
+            return cen;
+    }
+
+    if ((cen = readCENHeader(zip, cenpos, CENCACHE_PAGESIZE)) == NULL)
+        return NULL;
+    free(cache->data);
+    cache->data = cen;
+    cache->pos  = cenpos;
+    return cen;
+}
+
+typedef enum { ACCESS_RANDOM, ACCESS_SEQUENTIAL } AccessHint;
+
+/*
+ * Return a new initialized jzentry corresponding to a given hash cell.
+ * In case of error, returns NULL.
+ * We already sanity-checked all the CEN headers for ZIP format errors
+ * in readCEN(), so we don't check them again here.
+ * The ZIP lock should be held here.
+ */
+static jzentry *
+newEntry(jzfile *zip, jzcell *zc, AccessHint accessHint)
+{
+    jlong locoff;
+    jint nlen, elen, clen;
+    jzentry *ze;
+    char *cen;
+
+    if ((ze = (jzentry *) malloc(sizeof(jzentry))) == NULL) return NULL;
+    ze->name    = NULL;
+    ze->extra   = NULL;
+    ze->comment = NULL;
+
+#ifdef USE_MMAP
+    if (zip->usemmap) {
+        cen = (char*) zip->maddr + zc->cenpos - zip->offset;
+    } else
+#endif
+    {
+        if (accessHint == ACCESS_RANDOM)
+            cen = readCENHeader(zip, zc->cenpos, AMPLE_CEN_HEADER_SIZE);
+        else
+            cen = sequentialAccessReadCENHeader(zip, zc->cenpos);
+        if (cen == NULL) goto Catch;
+    }
+
+    nlen      = CENNAM(cen);
+    elen      = CENEXT(cen);
+    clen      = CENCOM(cen);
+    ze->time  = CENTIM(cen);
+    ze->size  = CENLEN(cen);
+    ze->csize = (CENHOW(cen) == STORED) ? 0 : CENSIZ(cen);
+    ze->crc   = CENCRC(cen);
+    locoff    = CENOFF(cen);
+    ze->pos   = -(zip->locpos + locoff);
+    ze->flag  = CENFLG(cen);
+
+    if ((ze->name = malloc(nlen + 1)) == NULL) goto Catch;
+    memcpy(ze->name, cen + CENHDR, nlen);
+    ze->name[nlen] = '\0';
+    if (elen > 0) {
+        char *extra = cen + CENHDR + nlen;
+
+        /* This entry has "extra" data */
+        if ((ze->extra = malloc(elen + 2)) == NULL) goto Catch;
+        ze->extra[0] = (unsigned char) elen;
+        ze->extra[1] = (unsigned char) (elen >> 8);
+        memcpy(ze->extra+2, extra, elen);
+        if (ze->csize == ZIP64_MAGICVAL || ze->size == ZIP64_MAGICVAL ||
+            locoff == ZIP64_MAGICVAL) {
+            jint off = 0;
+            while ((off + 4) < elen) {    // spec: HeaderID+DataSize+Data
+                jint sz = SH(extra, off + 2);
+                if (SH(extra, off) == ZIP64_EXTID) {
+                    off += 4;
+                    if (ze->size == ZIP64_MAGICVAL) {
+                        // if invalid zip64 extra fields, just skip
+                        if (sz < 8 || (off + 8) > elen)
+                            break;
+                        ze->size = LL(extra, off);
+                        sz -= 8;
+                        off += 8;
+                    }
+                    if (ze->csize == ZIP64_MAGICVAL) {
+                        if (sz < 8 || (off + 8) > elen)
+                            break;
+                        ze->csize = LL(extra, off);
+                        sz -= 8;
+                        off += 8;
+                    }
+                    if (locoff == ZIP64_MAGICVAL) {
+                        if (sz < 8 || (off + 8) > elen)
+                            break;
+                        ze->pos = -(zip->locpos +  LL(extra, off));
+                        sz -= 8;
+                        off += 8;
+                    }
+                    break;
+                }
+                off += (sz + 4);
+            }
+        }
+    }
+
+    if (clen > 0) {
+        /* This entry has a comment */
+        if ((ze->comment = malloc(clen + 1)) == NULL) goto Catch;
+        memcpy(ze->comment, cen + CENHDR + nlen + elen, clen);
+        ze->comment[clen] = '\0';
+    }
+    goto Finally;
+
+ Catch:
+    free(ze->name);
+    free(ze->extra);
+    free(ze->comment);
+    free(ze);
+    ze = NULL;
+
+ Finally:
+#ifdef USE_MMAP
+    if (!zip->usemmap)
+#endif
+        if (cen != NULL && accessHint == ACCESS_RANDOM) free(cen);
+    return ze;
+}
+
+/*
+ * Free the given jzentry.
+ * In fact we maintain a one-entry cache of the most recently used
+ * jzentry for each zip.  This optimizes a common access pattern.
+ */
+
+void
+ZIP_FreeEntry(jzfile *jz, jzentry *ze)
+{
+    jzentry *last;
+    ZIP_Lock(jz);
+    last = jz->cache;
+    jz->cache = ze;
+    ZIP_Unlock(jz);
+    if (last != NULL) {
+        /* Free the previously cached jzentry */
+        free(last->name);
+        if (last->extra)   free(last->extra);
+        if (last->comment) free(last->comment);
+        free(last);
+    }
+}
+
+/*
+ * Returns the zip entry corresponding to the specified name, or
+ * NULL if not found.
+ */
+jzentry *
+ZIP_GetEntry(jzfile *zip, char *name, jint ulen)
+{
+    unsigned int hsh = hash(name);
+    jint idx;
+    jzentry *ze = 0;
+
+    ZIP_Lock(zip);
+    if (zip->total == 0) {
+        goto Finally;
+    }
+
+    idx = zip->table[hsh % zip->tablelen];
+
+    /*
+     * This while loop is an optimization where a double lookup
+     * for name and name+/ is being performed. The name char
+     * array has enough room at the end to try again with a
+     * slash appended if the first table lookup does not succeed.
+     */
+    while(1) {
+
+        /* Check the cached entry first */
+        ze = zip->cache;
+        if (ze && strcmp(ze->name,name) == 0) {
+            /* Cache hit!  Remove and return the cached entry. */
+            zip->cache = 0;
+            ZIP_Unlock(zip);
+            return ze;
+        }
+        ze = 0;
+
+        /*
+         * Search down the target hash chain for a cell whose
+         * 32 bit hash matches the hashed name.
+         */
+        while (idx != ZIP_ENDCHAIN) {
+            jzcell *zc = &zip->entries[idx];
+
+            if (zc->hash == hsh) {
+                /*
+                 * OK, we've found a ZIP entry whose 32 bit hashcode
+                 * matches the name we're looking for.  Try to read
+                 * its entry information from the CEN.  If the CEN
+                 * name matches the name we're looking for, we're
+                 * done.
+                 * If the names don't match (which should be very rare)
+                 * we keep searching.
+                 */
+                ze = newEntry(zip, zc, ACCESS_RANDOM);
+                if (ze && strcmp(ze->name, name)==0) {
+                    break;
+                }
+                if (ze != 0) {
+                    /* We need to release the lock across the free call */
+                    ZIP_Unlock(zip);
+                    ZIP_FreeEntry(zip, ze);
+                    ZIP_Lock(zip);
+                }
+                ze = 0;
+            }
+            idx = zc->next;
+        }
+
+        /* Entry found, return it */
+        if (ze != 0) {
+            break;
+        }
+
+        /* If no real length was passed in, we are done */
+        if (ulen == 0) {
+            break;
+        }
+
+        /* Slash is already there? */
+        if (name[ulen-1] == '/') {
+            break;
+        }
+
+        /* Add slash and try once more */
+        name[ulen] = '/';
+        name[ulen+1] = '\0';
+        hsh = hash_append(hsh, '/');
+        idx = zip->table[hsh % zip->tablelen];
+        ulen = 0;
+    }
+
+Finally:
+    ZIP_Unlock(zip);
+    return ze;
+}
+
+/*
+ * Returns the n'th (starting at zero) zip file entry, or NULL if the
+ * specified index was out of range.
+ */
+jzentry * JNICALL
+ZIP_GetNextEntry(jzfile *zip, jint n)
+{
+    jzentry *result;
+    if (n < 0 || n >= zip->total) {
+        return 0;
+    }
+    ZIP_Lock(zip);
+    result = newEntry(zip, &zip->entries[n], ACCESS_SEQUENTIAL);
+    ZIP_Unlock(zip);
+    return result;
+}
+
+/*
+ * Locks the specified zip file for reading.
+ */
+void
+ZIP_Lock(jzfile *zip)
+{
+    MLOCK(zip->lock);
+}
+
+/*
+ * Unlocks the specified zip file.
+ */
+void
+ZIP_Unlock(jzfile *zip)
+{
+    MUNLOCK(zip->lock);
+}
+
+/*
+ * Returns the offset of the entry data within the zip file.
+ * Returns -1 if an error occurred, in which case zip->msg will
+ * contain the error text.
+ */
+jlong
+ZIP_GetEntryDataOffset(jzfile *zip, jzentry *entry)
+{
+    /* The Zip file spec explicitly allows the LOC extra data size to
+     * be different from the CEN extra data size, although the JDK
+     * never creates such zip files.  Since we cannot trust the CEN
+     * extra data size, we need to read the LOC to determine the entry
+     * data offset.  We do this lazily to avoid touching the virtual
+     * memory page containing the LOC when initializing jzentry
+     * objects.  (This speeds up javac by a factor of 10 when the JDK
+     * is installed on a very slow filesystem.)
+     */
+    if (entry->pos <= 0) {
+        unsigned char loc[LOCHDR];
+        if (readFullyAt(zip->zfd, loc, LOCHDR, -(entry->pos)) == -1) {
+            zip->msg = "error reading zip file";
+            return -1;
+        }
+        if (GETSIG(loc) != LOCSIG) {
+            zip->msg = "invalid LOC header (bad signature)";
+            return -1;
+        }
+        entry->pos = (- entry->pos) + LOCHDR + LOCNAM(loc) + LOCEXT(loc);
+    }
+    return entry->pos;
+}
+
+/*
+ * Reads bytes from the specified zip entry. Assumes that the zip
+ * file had been previously locked with ZIP_Lock(). Returns the
+ * number of bytes read, or -1 if an error occurred. If zip->msg != 0
+ * then a zip error occurred and zip->msg contains the error text.
+ *
+ * The current implementation does not support reading an entry that
+ * has the size bigger than 2**32 bytes in ONE invocation.
+ */
+jint
+ZIP_Read(jzfile *zip, jzentry *entry, jlong pos, void *buf, jint len)
+{
+    jlong entry_size = (entry->csize != 0) ? entry->csize : entry->size;
+    jlong start;
+
+    /* Clear previous zip error */
+    zip->msg = NULL;
+
+    /* Check specified position */
+    if (pos < 0 || pos > entry_size - 1) {
+        zip->msg = "ZIP_Read: specified offset out of range";
+        return -1;
+    }
+
+    /* Check specified length */
+    if (len <= 0)
+        return 0;
+    if (len > entry_size - pos)
+        len = (jint)(entry_size - pos);
+
+    /* Get file offset to start reading data */
+    start = ZIP_GetEntryDataOffset(zip, entry);
+    if (start < 0)
+        return -1;
+    start += pos;
+
+    if (start + len > zip->len) {
+        zip->msg = "ZIP_Read: corrupt zip file: invalid entry size";
+        return -1;
+    }
+
+    if (readFullyAt(zip->zfd, buf, len, start) == -1) {
+        zip->msg = "ZIP_Read: error reading zip file";
+        return -1;
+    }
+    return len;
+}
+
+
+/* The maximum size of a stack-allocated buffer.
+ */
+#define BUF_SIZE 4096
+
+/*
+ * This function is used by the runtime system to load compressed entries
+ * from ZIP/JAR files specified in the class path. It is defined here
+ * so that it can be dynamically loaded by the runtime if the zip library
+ * is found.
+ *
+ * The current implementation does not support reading an entry that
+ * has the size bigger than 2**32 bytes in ONE invocation.
+ */
+jboolean
+InflateFully(jzfile *zip, jzentry *entry, void *buf, char **msg)
+{
+    z_stream strm;
+    char tmp[BUF_SIZE];
+    jlong pos = 0;
+    jlong count = entry->csize;
+
+    *msg = 0; /* Reset error message */
+
+    if (count == 0) {
+        *msg = "inflateFully: entry not compressed";
+        return JNI_FALSE;
+    }
+
+    memset(&strm, 0, sizeof(z_stream));
+    if (inflateInit2(&strm, -MAX_WBITS) != Z_OK) {
+        *msg = strm.msg;
+        return JNI_FALSE;
+    }
+
+    strm.next_out = buf;
+    strm.avail_out = (uInt)entry->size;
+
+    while (count > 0) {
+        jint n = count > (jlong)sizeof(tmp) ? (jint)sizeof(tmp) : (jint)count;
+        ZIP_Lock(zip);
+        n = ZIP_Read(zip, entry, pos, tmp, n);
+        ZIP_Unlock(zip);
+        if (n <= 0) {
+            if (n == 0) {
+                *msg = "inflateFully: Unexpected end of file";
+            }
+            inflateEnd(&strm);
+            return JNI_FALSE;
+        }
+        pos += n;
+        count -= n;
+        strm.next_in = (Bytef *)tmp;
+        strm.avail_in = n;
+        do {
+            switch (inflate(&strm, Z_PARTIAL_FLUSH)) {
+            case Z_OK:
+                break;
+            case Z_STREAM_END:
+                if (count != 0 || strm.total_out != entry->size) {
+                    *msg = "inflateFully: Unexpected end of stream";
+                    inflateEnd(&strm);
+                    return JNI_FALSE;
+                }
+                break;
+            default:
+                break;
+            }
+        } while (strm.avail_in > 0);
+    }
+    inflateEnd(&strm);
+    return JNI_TRUE;
+}
+
+/*
+ * The current implementation does not support reading an entry that
+ * has the size bigger than 2**32 bytes in ONE invocation.
+ */
+jzentry * JNICALL
+ZIP_FindEntry(jzfile *zip, char *name, jint *sizeP, jint *nameLenP)
+{
+    jzentry *entry = ZIP_GetEntry(zip, name, 0);
+    if (entry) {
+        *sizeP = (jint)entry->size;
+        *nameLenP = strlen(entry->name);
+    }
+    return entry;
+}
+
+/*
+ * Reads a zip file entry into the specified byte array
+ * When the method completes, it releases the jzentry.
+ * Note: this is called from the separately delivered VM (hotspot/classic)
+ * so we have to be careful to maintain the expected behaviour.
+ */
+jboolean JNICALL
+ZIP_ReadEntry(jzfile *zip, jzentry *entry, unsigned char *buf, char *entryname)
+{
+    char *msg;
+
+    strcpy(entryname, entry->name);
+    if (entry->csize == 0) {
+        /* Entry is stored */
+        jlong pos = 0;
+        jlong size = entry->size;
+        while (pos < size) {
+            jint n;
+            jlong limit = ((((jlong) 1) << 31) - 1);
+            jint count = (size - pos < limit) ?
+                /* These casts suppress a VC++ Internal Compiler Error */
+                (jint) (size - pos) :
+                (jint) limit;
+            ZIP_Lock(zip);
+            n = ZIP_Read(zip, entry, pos, buf, count);
+            msg = zip->msg;
+            ZIP_Unlock(zip);
+            if (n == -1) {
+                jio_fprintf(stderr, "%s: %s\n", zip->name,
+                            msg != 0 ? msg : strerror(errno));
+                return JNI_FALSE;
+            }
+            buf += n;
+            pos += n;
+        }
+    } else {
+        /* Entry is compressed */
+        int ok = InflateFully(zip, entry, buf, &msg);
+        if (!ok) {
+            if ((msg == NULL) || (*msg == 0)) {
+                msg = zip->msg;
+            }
+            jio_fprintf(stderr, "%s: %s\n", zip->name,
+                        msg != 0 ? msg : strerror(errno));
+            return JNI_FALSE;
+        }
+    }
+
+    ZIP_FreeEntry(zip, entry);
+
+    return JNI_TRUE;
+}
diff --git a/ojluni/src/main/native/zip_util.h b/ojluni/src/main/native/zip_util.h
new file mode 100755
index 0000000..124e3f7
--- /dev/null
+++ b/ojluni/src/main/native/zip_util.h
@@ -0,0 +1,273 @@
+/*
+ * Copyright (c) 1995, 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * Prototypes for zip file support
+ */
+
+#ifndef _ZIP_H_
+#define _ZIP_H_
+
+/*
+ * Header signatures
+ */
+#define LOCSIG 0x04034b50L          /* "PK\003\004" */
+#define EXTSIG 0x08074b50L          /* "PK\007\008" */
+#define CENSIG 0x02014b50L          /* "PK\001\002" */
+#define ENDSIG 0x06054b50L          /* "PK\005\006" */
+
+#define ZIP64_ENDSIG 0x06064b50L    /* "PK\006\006" */
+#define ZIP64_LOCSIG 0x07064b50L    /* "PK\006\007" */
+
+/*
+ * Header sizes including signatures
+ */
+
+#define LOCHDR 30
+#define EXTHDR 16
+#define CENHDR 46
+#define ENDHDR 22
+
+#define ZIP64_ENDHDR 56       // ZIP64 end header size
+#define ZIP64_LOCHDR 20       // ZIP64 end loc header size
+#define ZIP64_EXTHDR 24       // EXT header size
+#define ZIP64_EXTID   1       // Extra field Zip64 header ID
+
+#define ZIP64_MAGICVAL 0xffffffffLL
+#define ZIP64_MAGICCOUNT 0xffff
+
+
+/*
+ * Header field access macros
+ */
+#define CH(b, n) (((unsigned char *)(b))[n])
+#define SH(b, n) (CH(b, n) | (CH(b, n+1) << 8))
+#define LG(b, n) ((SH(b, n) | (SH(b, n+2) << 16)) &0xffffffffUL)
+#define LL(b, n) (((jlong)LG(b, n)) | (((jlong)LG(b, n+4)) << 32))
+#define GETSIG(b) LG(b, 0)
+
+/*
+ * Macros for getting local file (LOC) header fields
+ */
+#define LOCVER(b) SH(b, 4)          /* version needed to extract */
+#define LOCFLG(b) SH(b, 6)          /* general purpose bit flags */
+#define LOCHOW(b) SH(b, 8)          /* compression method */
+#define LOCTIM(b) LG(b, 10)         /* modification time */
+#define LOCCRC(b) LG(b, 14)         /* crc of uncompressed data */
+#define LOCSIZ(b) LG(b, 18)         /* compressed data size */
+#define LOCLEN(b) LG(b, 22)         /* uncompressed data size */
+#define LOCNAM(b) SH(b, 26)         /* filename length */
+#define LOCEXT(b) SH(b, 28)         /* extra field length */
+
+/*
+ * Macros for getting extra local (EXT) header fields
+ */
+#define EXTCRC(b) LG(b, 4)          /* crc of uncompressed data */
+#define EXTSIZ(b) LG(b, 8)          /* compressed size */
+#define EXTLEN(b) LG(b, 12)         /* uncompressed size */
+
+/*
+ * Macros for getting central directory header (CEN) fields
+ */
+#define CENVEM(b) SH(b, 4)          /* version made by */
+#define CENVER(b) SH(b, 6)          /* version needed to extract */
+#define CENFLG(b) SH(b, 8)          /* general purpose bit flags */
+#define CENHOW(b) SH(b, 10)         /* compression method */
+#define CENTIM(b) LG(b, 12)         /* modification time */
+#define CENCRC(b) LG(b, 16)         /* crc of uncompressed data */
+#define CENSIZ(b) LG(b, 20)         /* compressed size */
+#define CENLEN(b) LG(b, 24)         /* uncompressed size */
+#define CENNAM(b) SH(b, 28)         /* length of filename */
+#define CENEXT(b) SH(b, 30)         /* length of extra field */
+#define CENCOM(b) SH(b, 32)         /* file comment length */
+#define CENDSK(b) SH(b, 34)         /* disk number start */
+#define CENATT(b) SH(b, 36)         /* internal file attributes */
+#define CENATX(b) LG(b, 38)         /* external file attributes */
+#define CENOFF(b) LG(b, 42)         /* offset of local header */
+
+/*
+ * Macros for getting end of central directory header (END) fields
+ */
+#define ENDSUB(b) SH(b, 8)          /* number of entries on this disk */
+#define ENDTOT(b) SH(b, 10)         /* total number of entries */
+#define ENDSIZ(b) LG(b, 12)         /* central directory size */
+#define ENDOFF(b) LG(b, 16)         /* central directory offset */
+#define ENDCOM(b) SH(b, 20)         /* size of zip file comment */
+
+/*
+ * Macros for getting Zip64 end of central directory header fields
+ */
+#define ZIP64_ENDLEN(b) LL(b, 4)      /* size of zip64 end of central dir */
+#define ZIP64_ENDVEM(b) SH(b, 12)     /* version made by */
+#define ZIP64_ENDVER(b) SH(b, 14)     /* version needed to extract */
+#define ZIP64_ENDNMD(b) LG(b, 16)     /* number of this disk */
+#define ZIP64_ENDDSK(b) LG(b, 20)     /* disk number of start */
+#define ZIP64_ENDTOD(b) LL(b, 24)     /* total number of entries on this disk */
+#define ZIP64_ENDTOT(b) LL(b, 32)     /* total number of entries */
+#define ZIP64_ENDSIZ(b) LL(b, 40)     /* central directory size in bytes */
+#define ZIP64_ENDOFF(b) LL(b, 48)     /* offset of first CEN header */
+
+/*
+ * Macros for getting Zip64 end of central directory locator fields
+ */
+#define ZIP64_LOCDSK(b) LG(b, 4)      /* disk number start */
+#define ZIP64_LOCOFF(b) LL(b, 8)      /* offset of zip64 end */
+#define ZIP64_LOCTOT(b) LG(b, 16)     /* total number of disks */
+
+/*
+ * Supported compression methods
+ */
+#define STORED      0
+#define DEFLATED    8
+
+/*
+ * Support for reading ZIP/JAR files. Some things worth noting:
+ *
+ * - Zip file entries larger than 2**32 bytes are not supported.
+ * - jzentry time and crc fields are signed even though they really
+ *   represent unsigned quantities.
+ * - If csize is zero then the entry is uncompressed.
+ * - If extra != 0 then the first two bytes are the length of the extra
+ *   data in intel byte order.
+ * - If pos <= 0 then it is the position of entry LOC header.
+ *   If pos > 0 then it is the position of entry data.
+ *   pos should not be accessed directly, but only by ZIP_GetEntryDataOffset.
+ */
+
+typedef struct jzentry {  /* Zip file entry */
+    char *name;           /* entry name */
+    jlong time;           /* modification time */
+    jlong size;           /* size of uncompressed data */
+    jlong csize;          /* size of compressed data (zero if uncompressed) */
+    jint crc;             /* crc of uncompressed data */
+    char *comment;        /* optional zip file comment */
+    jbyte *extra;         /* optional extra data */
+    jlong pos;            /* position of LOC header or entry data */
+    jint flag;            /* general purpose flag */
+} jzentry;
+
+/*
+ * In-memory hash table cell.
+ * In a typical system we have a *lot* of these, as we have one for
+ * every entry in every active JAR.
+ * Note that in order to save space we don't keep the name in memory,
+ * but merely remember a 32 bit hash.
+ */
+typedef struct jzcell {
+    unsigned int hash;    /* 32 bit hashcode on name */
+    unsigned int next;    /* hash chain: index into jzfile->entries */
+    jlong cenpos;         /* Offset of central directory file header */
+} jzcell;
+
+typedef struct cencache {
+    char *data;           /* A cached page of CEN headers */
+    jlong pos;            /* file offset of data */
+} cencache;
+
+/*
+ * Use ZFILE to represent access to a file in a platform-indepenent
+ * fashion.
+ */
+#ifdef WIN32
+#define ZFILE jlong
+#else
+#define ZFILE int
+#endif
+
+/*
+ * Descriptor for a ZIP file.
+ */
+typedef struct jzfile {   /* Zip file */
+    char *name;           /* zip file name */
+    jint refs;            /* number of active references */
+    jlong len;            /* length (in bytes) of zip file */
+#ifdef USE_MMAP
+    unsigned char *maddr; /* beginning address of the CEN & ENDHDR */
+    jlong mlen;           /* length (in bytes) mmaped */
+    jlong offset;         /* offset of the mmapped region from the
+                             start of the file. */
+    jboolean usemmap;     /* if mmap is used. */
+#endif
+    jboolean locsig;      /* if zip file starts with LOCSIG */
+    cencache cencache;    /* CEN header cache */
+    ZFILE zfd;            /* open file descriptor */
+    void *lock;           /* read lock */
+    char *comment;        /* zip file comment */
+    jint clen;            /* length of the zip file comment */
+    char *msg;            /* zip error message */
+    jzcell *entries;      /* array of hash cells */
+    jint total;           /* total number of entries */
+    jint *table;          /* Hash chain heads: indexes into entries */
+    jint tablelen;        /* number of hash heads */
+    struct jzfile *next;  /* next zip file in search list */
+    jzentry *cache;       /* we cache the most recently freed jzentry */
+    /* Information on metadata names in META-INF directory */
+    char **metanames;     /* array of meta names (may have null names) */
+    jint metacurrent;     /* the next empty slot in metanames array */
+    jint metacount;       /* number of slots in metanames array */
+    jlong lastModified;   /* last modified time */
+    jlong locpos;         /* position of first LOC header (usually 0) */
+} jzfile;
+
+/*
+ * Index representing end of hash chain
+ */
+#define ZIP_ENDCHAIN ((jint)-1)
+
+jzentry * JNICALL
+ZIP_FindEntry(jzfile *zip, char *name, jint *sizeP, jint *nameLenP);
+
+jboolean JNICALL
+ZIP_ReadEntry(jzfile *zip, jzentry *entry, unsigned char *buf, char *entrynm);
+
+jzentry * JNICALL
+ZIP_GetNextEntry(jzfile *zip, jint n);
+
+jzfile * JNICALL
+ZIP_Open(const char *name, char **pmsg);
+
+jzfile *
+ZIP_Open_Generic(const char *name, char **pmsg, int mode, jlong lastModified);
+
+jzfile *
+ZIP_Get_From_Cache(const char *name, char **pmsg, jlong lastModified);
+
+jzfile *
+ZIP_Put_In_Cache(const char *name, ZFILE zfd, char **pmsg, jlong lastModified);
+
+jzfile *
+ZIP_Put_In_Cache0(const char *name, ZFILE zfd, char **pmsg, jlong lastModified, jboolean usemmap);
+
+void JNICALL
+ZIP_Close(jzfile *zip);
+
+jzentry * ZIP_GetEntry(jzfile *zip, char *name, jint ulen);
+void ZIP_Lock(jzfile *zip);
+void ZIP_Unlock(jzfile *zip);
+jint ZIP_Read(jzfile *zip, jzentry *entry, jlong pos, void *buf, jint len);
+void ZIP_FreeEntry(jzfile *zip, jzentry *ze);
+jlong ZIP_GetEntryDataOffset(jzfile *zip, jzentry *entry);
+
+#endif /* !_ZIP_H_ */