changeset 9271:ed1286219d60

8034043: Native methods for preferences API should not be in libjava 8034026: SCDynamicStoreConfig.m should not be in src/macosx/native/java/util Reviewed-by: erikj, weijun, mchung
author alanb
date Tue, 11 Feb 2014 09:59:34 +0000
parents 3b9976cf131f
children 3f1729e76f9f
files make/lib/CoreLibraries.gmk make/lib/PlatformLibraries.gmk make/lib/SecurityLibraries.gmk make/mapfiles/libjava/mapfile-vers make/mapfiles/libprefs/mapfile-vers make/profile-includes.txt src/macosx/classes/java/util/prefs/MacOSXPreferencesFile.java src/macosx/native/java/util/MacOSXPreferencesFile.m src/macosx/native/java/util/SCDynamicStoreConfig.m src/macosx/native/java/util/prefs/MacOSXPreferencesFile.m src/macosx/native/sun/security/krb5/SCDynamicStoreConfig.m src/share/classes/java/util/logging/FileHandler.java src/share/classes/sun/misc/VM.java src/share/classes/sun/security/krb5/SCDynamicStoreConfig.java src/solaris/classes/java/util/prefs/FileSystemPreferences.java src/solaris/native/java/util/FileSystemPreferences.c src/solaris/native/java/util/logging.c src/solaris/native/java/util/prefs/FileSystemPreferences.c src/solaris/native/sun/misc/VM_md.c src/windows/classes/java/util/prefs/WindowsPreferences.java src/windows/native/java/util/WindowsPreferences.c src/windows/native/java/util/logging.c src/windows/native/java/util/prefs/WindowsPreferences.c src/windows/native/sun/misc/VM_md.c
diffstat 24 files changed, 1773 insertions(+), 1691 deletions(-) [+]
line wrap: on
line diff
--- a/make/lib/CoreLibraries.gmk	Mon Feb 10 18:09:40 2014 -0800
+++ b/make/lib/CoreLibraries.gmk	Tue Feb 11 09:59:34 2014 +0000
@@ -123,6 +123,7 @@
     $(JDK_TOPDIR)/src/share/native/java/security \
     $(JDK_TOPDIR)/src/share/native/common \
     $(JDK_TOPDIR)/src/share/native/sun/misc \
+    $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/misc \
     $(JDK_TOPDIR)/src/share/native/sun/reflect \
     $(JDK_TOPDIR)/src/share/native/java/util \
     $(JDK_TOPDIR)/src/share/native/java/util/concurrent/atomic \
@@ -187,7 +188,7 @@
     LIBRARY := java, \
     OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
     SRC := $(LIBJAVA_SRC_DIRS), \
-    EXCLUDES := fdlibm/src zip, \
+    EXCLUDES := fdlibm/src zip prefs, \
     EXCLUDE_FILES := $(LIBJAVA_EXCLUDE_FILES), \
     LANG := C, \
     OPTIMIZATION := HIGH, \
@@ -285,6 +286,41 @@
 
 ##########################################################################################
 
+ifeq ($(OPENJDK_TARGET_OS), macosx)
+  LIBPREF_SRC_DIRS := $(JDK_TOPDIR)/src/macosx/native/java/util/prefs
+else
+  LIBPREF_SRC_DIRS := $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/java/util/prefs
+endif
+
+$(eval $(call SetupNativeCompilation,BUILD_LIBPREFS, \
+    LIBRARY := prefs, \
+    OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
+    SRC := $(LIBPREF_SRC_DIRS), \
+    LANG := C, \
+    OPTIMIZATION := HIGH, \
+    CFLAGS := $(CFLAGS_JDKLIB), \
+    MAPFILE := $(JDK_TOPDIR)/make/mapfiles/libprefs/mapfile-vers, \
+    LDFLAGS := $(LDFLAGS_JDKLIB) \
+        $(call SET_SHARED_LIBRARY_ORIGIN), \
+    LDFLAGS_SUFFIX_linux := -ljvm -ljava, \
+    LDFLAGS_SUFFIX_solaris := -ljvm -ljava -lc, \
+    LDFLAGS_SUFFIX_aix := -ljvm -ljava, \
+    LDFLAGS_SUFFIX_windows := advapi32.lib, \
+    LDFLAGS_SUFFIX_macosx := -ljvm -framework CoreFoundation, \
+    VERSIONINFO_RESOURCE := $(JDK_TOPDIR)/src/windows/resource/version.rc, \
+    RC_FLAGS := $(RC_FLAGS) \
+        -D "JDK_FNAME=prefs.dll" \
+        -D "JDK_INTERNAL_NAME=prefs" \
+        -D "JDK_FTYPE=0x2L", \
+    OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libprefs, \
+    DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES)))
+
+$(BUILD_LIBPREFS): $(BUILD_LIBJAVA)
+    
+BUILD_LIBRARIES += $(BUILD_LIBPREFS)
+
+##########################################################################################
+
 $(eval $(call SetupNativeCompilation,BUILD_LIBUNPACK, \
     LIBRARY := unpack, \
     OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
--- a/make/lib/PlatformLibraries.gmk	Mon Feb 10 18:09:40 2014 -0800
+++ b/make/lib/PlatformLibraries.gmk	Tue Feb 11 09:59:34 2014 +0000
@@ -95,7 +95,6 @@
 
   LIBOSX_DIRS := \
       $(JDK_TOPDIR)/src/macosx/native/com/apple/concurrent \
-      $(JDK_TOPDIR)/src/macosx/native/java/util \
       $(JDK_TOPDIR)/src/macosx/native/com/apple/eio \
       $(JDK_TOPDIR)/src/macosx/native/apple/security \
       $(JDK_TOPDIR)/src/macosx/native/apple/launcher
--- a/make/lib/SecurityLibraries.gmk	Mon Feb 10 18:09:40 2014 -0800
+++ b/make/lib/SecurityLibraries.gmk	Tue Feb 11 09:59:34 2014 +0000
@@ -128,8 +128,13 @@
         ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib
   else ifeq ($(OPENJDK_TARGET_OS), macosx)
     BUILD_LIBKRB5_NAME := osxkrb5
-    BUILD_LIBKRB5_SRC := $(JDK_TOPDIR)/src/share/native/sun/security/krb5
-    BUILD_LIBKRB5_LIBS := -framework Kerberos
+    BUILD_LIBKRB5_SRC := $(JDK_TOPDIR)/src/share/native/sun/security/krb5 \
+        $(JDK_TOPDIR)/src/macosx/native/sun/security/krb5
+    BUILD_LIBKRB5_LIBS := -F/System/Library/Frameworks/JavaVM.framework/Frameworks \
+        -framework JavaNativeFoundation \
+        -framework Cocoa \
+        -framework SystemConfiguration \
+        -framework Kerberos
   endif
 
   ifneq ($(BUILD_LIBKRB5_NAME), )
@@ -140,8 +145,9 @@
         LANG := C, \
         OPTIMIZATION := LOW, \
         CFLAGS := $(CFLAGS_JDKLIB) \
-            -I$(JDK_TOPDIR)/src/share/native/sun/security/krb5 \
-            -I$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/security/krb5, \
+            -I$(JDK_TOPDIR)/src/share/native/sun/security/krb5, \
+        CFLAGS_windows := -I$(JDK_TOPDIR)/src/windows/native/sun/security/krb5, \
+        CFLAGS_macosx := -F/System/Library/Frameworks/JavaVM.framework/Frameworks, \
         LDFLAGS := $(LDFLAGS_JDKLIB) \
             $(call SET_SHARED_LIBRARY_ORIGIN), \
         LDFLAGS_SUFFIX := $(BUILD_LIBKRB5_LIBS), \
--- a/make/mapfiles/libjava/mapfile-vers	Mon Feb 10 18:09:40 2014 -0800
+++ b/make/mapfiles/libjava/mapfile-vers	Tue Feb 11 09:59:34 2014 +0000
@@ -236,10 +236,6 @@
 		Java_java_util_TimeZone_getSystemTimeZoneID;
 		Java_java_util_TimeZone_getSystemGMTOffsetID;
 		Java_java_util_concurrent_atomic_AtomicLong_VMSupportsCS8;
-		Java_java_util_prefs_FileSystemPreferences_chmod;
-		Java_java_util_prefs_FileSystemPreferences_lockFile0;
-		Java_java_util_prefs_FileSystemPreferences_unlockFile0;
-		Java_java_util_logging_FileHandler_isSetUID;
 		Java_sun_misc_MessageUtils_toStderr;
 		Java_sun_misc_MessageUtils_toStdout;
 		Java_sun_misc_NativeSignalHandler_handle0;
@@ -274,17 +270,13 @@
                 Java_sun_misc_Version_getJvmVersionInfo;
                 Java_sun_misc_Version_getJvmSpecialVersion;
 		Java_sun_misc_VM_latestUserDefinedLoader;
+                Java_sun_misc_VM_isSetUID;
                 Java_sun_misc_VM_initialize;
 		Java_sun_misc_VMSupport_initAgentProperties;
 
                 # ZipFile.c needs this one
 		throwFileNotFoundException;
 
-#		Java_sun_misc_VM_getState;			threads.c
-#		Java_sun_misc_VM_threadsSuspended;		threads.c
-#		Java_sun_misc_VM_unsuspendSomeThreads;		threads.c
-#		Java_sun_misc_VM_unsuspendThreads;		threads.c
-
 	# Outcalls from libjvm done using dlsym().
 
 		VerifyClassCodes;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/mapfiles/libprefs/mapfile-vers	Tue Feb 11 09:59:34 2014 +0000
@@ -0,0 +1,36 @@
+#
+# Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.  Oracle designates this
+# particular file as subject to the "Classpath" exception as provided
+# by Oracle in the LICENSE file that accompanied this code.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+# Define public interface.
+
+SUNWprivate_1.1 {
+	global:
+		Java_java_util_prefs_FileSystemPreferences_chmod;
+		Java_java_util_prefs_FileSystemPreferences_lockFile0;
+		Java_java_util_prefs_FileSystemPreferences_unlockFile0;
+
+	local:
+		*;
+};
--- a/make/profile-includes.txt	Mon Feb 10 18:09:40 2014 -0800
+++ b/make/profile-includes.txt	Tue Feb 11 09:59:34 2014 +0000
@@ -130,6 +130,7 @@
     $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)management.diz \
     $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)npt$(SHARED_LIBRARY_SUFFIX) \
     $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)npt.diz \
+    $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)prefs$(SHARED_LIBRARY_SUFFIX) \
     $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)sctp$(SHARED_LIBRARY_SUFFIX) \
     jvm.hprof.txt \
     management-agent.jar \
--- a/src/macosx/classes/java/util/prefs/MacOSXPreferencesFile.java	Mon Feb 10 18:09:40 2014 -0800
+++ b/src/macosx/classes/java/util/prefs/MacOSXPreferencesFile.java	Tue Feb 11 09:59:34 2014 +0000
@@ -82,7 +82,7 @@
         java.security.AccessController.doPrivileged(
             new java.security.PrivilegedAction<Void>() {
                 public Void run() {
-                    System.loadLibrary("osx");
+                    System.loadLibrary("prefs");
                     return null;
                 }
             });
--- a/src/macosx/native/java/util/MacOSXPreferencesFile.m	Mon Feb 10 18:09:40 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,999 +0,0 @@
-/*
- * Copyright (c) 2011, 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.
- */
-
-/*
-   Hierarchical storage layout:
-
-   <dict>
-     <key>/</key>
-     <dict>
-       <key>foo</key>
-       <string>/foo's value</string>
-       <key>foo/</key>
-       <dict>
-         <key>bar</key>
-         <string>/foo/bar's value</string>
-       </dict>
-     </dict>
-   </dict>
-
-   Java pref nodes are stored in several different files. Pref nodes
-   with at least three components in the node name (e.g. /com/MyCompany/MyApp/)
-   are stored in a CF prefs file with the first three components as the name.
-   This way, all preferences for MyApp end up in com.MyCompany.MyApp.plist .
-   Pref nodes with shorter names are stored in com.apple.java.util.prefs.plist
-
-   The filesystem is assumed to be case-insensitive (like HFS+).
-   Java pref node names are case-sensitive. If two pref node names differ
-   only in case, they may end up in the same pref file. This is ok
-   because the CF keys identifying the node span the entire absolute path
-   to the node and are case-sensitive.
-
-   Java node names may contain '.' . When mapping to the CF file name,
-   these dots are left as-is, even though '/' is mapped to '.' .
-   This is ok because the CF key contains the correct node name.
-*/
-
-
-
-#include <CoreFoundation/CoreFoundation.h>
-
-#include "jni_util.h"
-#include "jlong.h"
-#include "jvm.h"
-
-
-// Throw an OutOfMemoryError with the given message.
-static void throwOutOfMemoryError(JNIEnv *env, const char *msg)
-{
-    static jclass exceptionClass = NULL;
-    jclass c;
-
-    if (exceptionClass) {
-        c = exceptionClass;
-    } else {
-        c = (*env)->FindClass(env, "java/lang/OutOfMemoryError");
-        if ((*env)->ExceptionOccurred(env)) return;
-        exceptionClass = (*env)->NewGlobalRef(env, c);
-    }
-
-    (*env)->ThrowNew(env, c, msg);
-}
-
-
-// throwIfNull macro
-// If var is NULL, throw an OutOfMemoryError and goto badvar.
-// var must be a variable. env must be the current JNIEnv.
-// fixme throw BackingStoreExceptions sometimes?
-#define throwIfNull(var, msg) \
-    do { \
-        if (var == NULL) { \
-            throwOutOfMemoryError(env, msg); \
-            goto bad##var; \
-        } \
-    } while (0)
-
-
-// Converts CFNumber, CFBoolean, CFString to CFString
-// returns NULL if value is of some other type
-// throws and returns NULL on memory error
-// result must be released (even if value was already a CFStringRef)
-// value must not be null
-static CFStringRef copyToCFString(JNIEnv *env, CFTypeRef value)
-{
-    CFStringRef result;
-    CFTypeID type;
-
-    type = CFGetTypeID(value);
-
-    if (type == CFStringGetTypeID()) {
-        result = (CFStringRef)CFRetain(value);
-    }
-    else if (type == CFBooleanGetTypeID()) {
-        // Java Preferences API expects "true" and "false" for boolean values.
-        result = CFStringCreateCopy(NULL, (value == kCFBooleanTrue) ? CFSTR("true") : CFSTR("false"));
-        throwIfNull(result, "copyToCFString failed");
-    }
-    else if (type == CFNumberGetTypeID()) {
-        CFNumberRef number = (CFNumberRef) value;
-        if (CFNumberIsFloatType(number)) {
-            double d;
-            CFNumberGetValue(number, kCFNumberDoubleType, &d);
-            result = CFStringCreateWithFormat(NULL, NULL, CFSTR("%g"), d);
-            throwIfNull(result, "copyToCFString failed");
-        }
-        else {
-            long l;
-            CFNumberGetValue(number, kCFNumberLongType, &l);
-            result = CFStringCreateWithFormat(NULL, NULL, CFSTR("%ld"), l);
-            throwIfNull(result, "copyToCFString failed");
-        }
-    }
-    else {
-        // unknown type - return NULL
-        result = NULL;
-    }
-
- badresult:
-    return result;
-}
-
-
-// Create a Java string from the given CF string.
-// returns NULL if cfString is NULL
-// throws and returns NULL on memory error
-static jstring toJavaString(JNIEnv *env, CFStringRef cfString)
-{
-    if (cfString == NULL) {
-        return NULL;
-    } else {
-        jstring javaString = NULL;
-
-        CFIndex length = CFStringGetLength(cfString);
-        const UniChar *constchars = CFStringGetCharactersPtr(cfString);
-        if (constchars) {
-            javaString = (*env)->NewString(env, constchars, length);
-        } else {
-            UniChar *chars = malloc(length * sizeof(UniChar));
-            throwIfNull(chars, "toJavaString failed");
-            CFStringGetCharacters(cfString, CFRangeMake(0, length), chars);
-            javaString = (*env)->NewString(env, chars, length);
-            free(chars);
-        }
-    badchars:
-        return javaString;
-    }
-}
-
-
-
-// Create a CF string from the given Java string.
-// returns NULL if javaString is NULL
-// throws and returns NULL on memory error
-static CFStringRef toCF(JNIEnv *env, jstring javaString)
-{
-    if (javaString == NULL) {
-        return NULL;
-    } else {
-        CFStringRef result = NULL;
-        jsize length = (*env)->GetStringLength(env, javaString);
-        const jchar *chars = (*env)->GetStringChars(env, javaString, NULL);
-        throwIfNull(chars, "toCF failed");
-        result =
-            CFStringCreateWithCharacters(NULL, (const UniChar *)chars, length);
-        (*env)->ReleaseStringChars(env, javaString, chars);
-        throwIfNull(result, "toCF failed");
-    badchars:
-    badresult:
-        return result;
-    }
-}
-
-
-// Create an empty Java string array of the given size.
-// Throws and returns NULL on error.
-static jarray createJavaStringArray(JNIEnv *env, CFIndex count)
-{
-    static jclass stringClass = NULL;
-    jclass c;
-
-    if (stringClass) {
-        c = stringClass;
-    } else {
-        c = (*env)->FindClass(env, "java/lang/String");
-        if ((*env)->ExceptionOccurred(env)) return NULL;
-        stringClass = (*env)->NewGlobalRef(env, c);
-    }
-
-    return (*env)->NewObjectArray(env, count, c, NULL); // AWT_THREADING Safe (known object)
-}
-
-
-// Java accessors for CF constants.
-JNIEXPORT jlong JNICALL
-Java_java_util_prefs_MacOSXPreferencesFile_currentUser(JNIEnv *env,
-                                                       jobject klass)
-{
-    return ptr_to_jlong(kCFPreferencesCurrentUser);
-}
-
-JNIEXPORT jlong JNICALL
-Java_java_util_prefs_MacOSXPreferencesFile_anyUser(JNIEnv *env, jobject klass)
-{
-    return ptr_to_jlong(kCFPreferencesAnyUser);
-}
-
-JNIEXPORT jlong JNICALL
-Java_java_util_prefs_MacOSXPreferencesFile_currentHost(JNIEnv *env,
-                                                       jobject klass)
-{
-    return ptr_to_jlong(kCFPreferencesCurrentHost);
-}
-
-JNIEXPORT jlong JNICALL
-Java_java_util_prefs_MacOSXPreferencesFile_anyHost(JNIEnv *env, jobject klass)
-{
-    return ptr_to_jlong(kCFPreferencesAnyHost);
-}
-
-
-// Create an empty node.
-// Does not store the node in any prefs file.
-// returns NULL on memory error
-static CFMutableDictionaryRef createEmptyNode(void)
-{
-    return CFDictionaryCreateMutable(NULL, 0,
-                                     &kCFTypeDictionaryKeyCallBacks,
-                                     &kCFTypeDictionaryValueCallBacks);
-}
-
-
-// Create a string that consists of path minus its last component.
-// path must end with '/'
-// The result will end in '/' (unless path itself is '/')
-static CFStringRef copyParentOf(CFStringRef path)
-{
-    CFRange searchRange;
-    CFRange slashRange;
-    CFRange parentRange;
-    Boolean found;
-
-    searchRange = CFRangeMake(0, CFStringGetLength(path) - 1);
-    found = CFStringFindWithOptions(path, CFSTR("/"), searchRange,
-                                    kCFCompareBackwards, &slashRange);
-    if (!found) return CFSTR("");
-    parentRange = CFRangeMake(0, slashRange.location + 1); // include '/'
-    return CFStringCreateWithSubstring(NULL, path, parentRange);
-}
-
-
-// Create a string that consists of path's last component.
-// path must end with '/'
-// The result will end in '/'.
-// The result will not start with '/' (unless path itself is '/')
-static CFStringRef copyChildOf(CFStringRef path)
-{
-    CFRange searchRange;
-    CFRange slashRange;
-    CFRange childRange;
-    Boolean found;
-    CFIndex length = CFStringGetLength(path);
-
-    searchRange = CFRangeMake(0, length - 1);
-    found = CFStringFindWithOptions(path, CFSTR("/"), searchRange,
-                                    kCFCompareBackwards, &slashRange);
-    if (!found) return CFSTR("");
-    childRange = CFRangeMake(slashRange.location + 1,
-                             length - slashRange.location - 1); // skip '/'
-    return CFStringCreateWithSubstring(NULL, path, childRange);
-}
-
-
-// Return the first three components of path, with leading and trailing '/'.
-// If path does not have three components, return NULL.
-// path must begin and end in '/'
-static CFStringRef copyFirstThreeComponentsOf(CFStringRef path)
-{
-    CFRange searchRange;
-    CFRange slashRange;
-    CFRange prefixRange;
-    CFStringRef prefix;
-    Boolean found;
-    CFIndex length = CFStringGetLength(path);
-
-    searchRange = CFRangeMake(1, length - 1);  // skip leading '/'
-    found = CFStringFindWithOptions(path, CFSTR("/"), searchRange, 0,
-                                    &slashRange);
-    if (!found) return NULL;  // no second slash!
-
-    searchRange = CFRangeMake(slashRange.location + 1,
-                              length - slashRange.location - 1);
-    found = CFStringFindWithOptions(path, CFSTR("/"), searchRange, 0,
-                                    &slashRange);
-    if (!found) return NULL;  // no third slash!
-
-    searchRange = CFRangeMake(slashRange.location + 1,
-                              length - slashRange.location - 1);
-    found = CFStringFindWithOptions(path, CFSTR("/"), searchRange, 0,
-                                    &slashRange);
-    if (!found) return NULL;  // no fourth slash!
-
-    prefixRange = CFRangeMake(0, slashRange.location + 1); // keep last '/'
-    prefix = CFStringCreateWithSubstring(NULL, path, prefixRange);
-
-    return prefix;
-}
-
-
-// Copy the CFPreferences key and value at the base of path's tree.
-// path must end in '/'
-// topKey or topValue may be NULL
-// Returns NULL on error or if there is no tree for path in this file.
-static void copyTreeForPath(CFStringRef path, CFStringRef name,
-                            CFStringRef user, CFStringRef host,
-                            CFStringRef *topKey, CFDictionaryRef *topValue)
-{
-    CFStringRef key;
-    CFPropertyListRef value;
-
-    if (topKey) *topKey = NULL;
-    if (topValue) *topValue = NULL;
-
-    if (CFEqual(name, CFSTR("com.apple.java.util.prefs"))) {
-        // Top-level file. Only key "/" is an acceptable root.
-        key = (CFStringRef) CFRetain(CFSTR("/"));
-    } else {
-        // Second-level file. Key must be the first three components of path.
-        key = copyFirstThreeComponentsOf(path);
-        if (!key) return;
-    }
-
-    value = CFPreferencesCopyValue(key, name, user, host);
-    if (value) {
-        if (CFGetTypeID(value) == CFDictionaryGetTypeID()) {
-            // (key, value) is acceptable
-            if (topKey) *topKey = (CFStringRef)CFRetain(key);
-            if (topValue) *topValue = (CFDictionaryRef)CFRetain(value);
-        }
-        CFRelease(value);
-    }
-    CFRelease(key);
-}
-
-
-// Find the node for path in the given tree.
-// Returns NULL on error or if path doesn't have a node in this tree.
-// path must end in '/'
-static CFDictionaryRef copyNodeInTree(CFStringRef path, CFStringRef topKey,
-                                      CFDictionaryRef topValue)
-{
-    CFMutableStringRef p;
-    CFDictionaryRef result = NULL;
-
-    p = CFStringCreateMutableCopy(NULL, 0, path);
-    if (!p) return NULL;
-    CFStringDelete(p, CFRangeMake(0, CFStringGetLength(topKey)));
-    result = topValue;
-
-    while (CFStringGetLength(p) > 0) {
-        CFDictionaryRef child;
-        CFStringRef part = NULL;
-        CFRange slashRange = CFStringFind(p, CFSTR("/"), 0);
-        // guaranteed to succeed because path must end in '/'
-        CFRange partRange = CFRangeMake(0, slashRange.location + 1);
-        part = CFStringCreateWithSubstring(NULL, p, partRange);
-        if (!part) { result = NULL; break; }
-        CFStringDelete(p, partRange);
-
-        child = CFDictionaryGetValue(result, part);
-        CFRelease(part);
-        if (child  &&  CFGetTypeID(child) == CFDictionaryGetTypeID()) {
-            // continue search
-            result = child;
-        } else {
-            // didn't find target node
-            result = NULL;
-            break;
-        }
-    }
-
-    CFRelease(p);
-    if (result) return (CFDictionaryRef)CFRetain(result);
-    else return NULL;
-}
-
-
-// Return a retained copy of the node at path from the given file.
-// path must end in '/'
-// returns NULL if node doesn't exist.
-// returns NULL if the value for key "path" isn't a valid node.
-static CFDictionaryRef copyNodeIfPresent(CFStringRef path, CFStringRef name,
-                                         CFStringRef user, CFStringRef host)
-{
-    CFStringRef topKey;
-    CFDictionaryRef topValue;
-    CFDictionaryRef result;
-
-    copyTreeForPath(path, name, user, host, &topKey, &topValue);
-    if (!topKey) return NULL;
-
-    result = copyNodeInTree(path, topKey, topValue);
-
-    CFRelease(topKey);
-    if (topValue) CFRelease(topValue);
-    return result;
-}
-
-
-// Create a new tree that would store path in the given file.
-// Only the root of the tree is created, not all of the links leading to path.
-// returns NULL on error
-static void createTreeForPath(CFStringRef path, CFStringRef name,
-                              CFStringRef user, CFStringRef host,
-                              CFStringRef *outTopKey,
-                              CFMutableDictionaryRef *outTopValue)
-{
-    *outTopKey = NULL;
-    *outTopValue = NULL;
-
-    // if name is "com.apple.java.util.prefs" then create tree "/"
-    // else create tree "/foo/bar/baz/"
-    // "com.apple.java.util.prefs.plist" is also in MacOSXPreferences.java
-    if (CFEqual(name, CFSTR("com.apple.java.util.prefs"))) {
-        *outTopKey = CFSTR("/");
-        *outTopValue = createEmptyNode();
-    } else {
-        CFStringRef prefix = copyFirstThreeComponentsOf(path);
-        if (prefix) {
-            *outTopKey = prefix;
-            *outTopValue = createEmptyNode();
-        }
-    }
-}
-
-
-// Return a mutable copy of the tree containing path and the dict for
-//   path itself. *outTopKey and *outTopValue can be used to write the
-//   modified tree back to the prefs file.
-// *outTopKey and *outTopValue must be released iff the actual return
-//   value is not NULL.
-static CFMutableDictionaryRef
-copyMutableNode(CFStringRef path, CFStringRef name,
-                CFStringRef user, CFStringRef host,
-                CFStringRef *outTopKey,
-                CFMutableDictionaryRef *outTopValue)
-{
-    CFStringRef topKey = NULL;
-    CFDictionaryRef oldTopValue = NULL;
-    CFMutableDictionaryRef topValue;
-    CFMutableDictionaryRef result = NULL;
-    CFMutableStringRef p;
-
-    if (outTopKey) *outTopKey = NULL;
-    if (outTopValue) *outTopValue = NULL;
-
-    copyTreeForPath(path, name, user, host, &topKey, &oldTopValue);
-    if (!topKey) {
-        createTreeForPath(path, name, user, host, &topKey, &topValue);
-    } else {
-        topValue = (CFMutableDictionaryRef)
-            CFPropertyListCreateDeepCopy(NULL, (CFPropertyListRef)oldTopValue,
-                                         kCFPropertyListMutableContainers);
-    }
-    if (!topValue) goto badtopValue;
-
-    p = CFStringCreateMutableCopy(NULL, 0, path);
-    if (!p) goto badp;
-    CFStringDelete(p, CFRangeMake(0, CFStringGetLength(topKey)));
-    result = topValue;
-
-    while (CFStringGetLength(p) > 0) {
-        CFMutableDictionaryRef child;
-        CFStringRef part = NULL;
-        CFRange slashRange = CFStringFind(p, CFSTR("/"), 0);
-        // guaranteed to succeed because path must end in '/'
-        CFRange partRange = CFRangeMake(0, slashRange.location + 1);
-        part = CFStringCreateWithSubstring(NULL, p, partRange);
-        if (!part) { result = NULL; break; }
-        CFStringDelete(p, partRange);
-
-        child = (CFMutableDictionaryRef)CFDictionaryGetValue(result, part);
-        if (child  &&  CFGetTypeID(child) == CFDictionaryGetTypeID()) {
-            // continue search
-            result = child;
-        } else {
-            // didn't find target node - add it and continue
-            child = createEmptyNode();
-            if (!child) { CFRelease(part); result = NULL; break; }
-            CFDictionaryAddValue(result, part, child);
-            result = child;
-        }
-        CFRelease(part);
-    }
-
-    if (result) {
-        *outTopKey = (CFStringRef)CFRetain(topKey);
-        *outTopValue = (CFMutableDictionaryRef)CFRetain(topValue);
-        CFRetain(result);
-    }
-
-    CFRelease(p);
- badp:
-    CFRelease(topValue);
- badtopValue:
-    if (topKey) CFRelease(topKey);
-    if (oldTopValue) CFRelease(oldTopValue);
-    return result;
-}
-
-
-JNIEXPORT jboolean JNICALL
-Java_java_util_prefs_MacOSXPreferencesFile_addNode
-(JNIEnv *env, jobject klass, jobject jpath,
- jobject jname, jlong juser, jlong jhost)
-{
-    CFStringRef path = toCF(env, jpath);
-    CFStringRef name = toCF(env, jname);
-    CFStringRef user = (CFStringRef)jlong_to_ptr(juser);
-    CFStringRef host = (CFStringRef)jlong_to_ptr(jhost);
-    CFDictionaryRef node = NULL;
-    jboolean neededNewNode = false;
-
-    if (!path  ||  !name) goto badparams;
-
-    node = copyNodeIfPresent(path, name, user, host);
-
-    if (node) {
-        neededNewNode = false;
-        CFRelease(node);
-    } else {
-        CFStringRef topKey = NULL;
-        CFMutableDictionaryRef topValue = NULL;
-
-        neededNewNode = true;
-
-        // copyMutableNode creates the node if necessary
-        node = copyMutableNode(path, name, user, host, &topKey, &topValue);
-        throwIfNull(node, "copyMutableNode failed");
-
-        CFPreferencesSetValue(topKey, topValue, name, user, host);
-
-        CFRelease(node);
-        if (topKey) CFRelease(topKey);
-        if (topValue) CFRelease(topValue);
-    }
-
- badnode:
- badparams:
-    if (path) CFRelease(path);
-    if (name) CFRelease(name);
-
-    return neededNewNode;
-}
-
-
-JNIEXPORT void JNICALL
-Java_java_util_prefs_MacOSXPreferencesFile_removeNode
-(JNIEnv *env, jobject klass, jobject jpath,
- jobject jname, jlong juser, jlong jhost)
-{
-    CFStringRef path = toCF(env, jpath);
-    CFStringRef name = toCF(env, jname);
-    CFStringRef user = (CFStringRef)jlong_to_ptr(juser);
-    CFStringRef host = (CFStringRef)jlong_to_ptr(jhost);
-    CFStringRef parentName;
-    CFStringRef childName;
-    CFDictionaryRef constParent;
-
-    if (!path  ||  !name) goto badparams;
-
-    parentName = copyParentOf(path);
-    throwIfNull(parentName, "copyParentOf failed");
-    childName  = copyChildOf(path);
-    throwIfNull(childName, "copyChildOf failed");
-
-    // root node is not allowed to be removed, so parentName is never empty
-
-    constParent = copyNodeIfPresent(parentName, name, user, host);
-    if (constParent  &&  CFDictionaryContainsKey(constParent, childName)) {
-        CFStringRef topKey;
-        CFMutableDictionaryRef topValue;
-        CFMutableDictionaryRef parent;
-
-        parent = copyMutableNode(parentName, name, user, host,
-                                 &topKey, &topValue);
-        throwIfNull(parent, "copyMutableNode failed");
-
-        CFDictionaryRemoveValue(parent, childName);
-        CFPreferencesSetValue(topKey, topValue, name, user, host);
-
-        CFRelease(parent);
-        if (topKey) CFRelease(topKey);
-        if (topValue) CFRelease(topValue);
-    } else {
-        // might be trying to remove the root itself in a non-root file
-        CFStringRef topKey;
-        CFDictionaryRef topValue;
-        copyTreeForPath(path, name, user, host, &topKey, &topValue);
-        if (topKey) {
-            if (CFEqual(topKey, path)) {
-                CFPreferencesSetValue(topKey, NULL, name, user, host);
-            }
-
-            if (topKey) CFRelease(topKey);
-            if (topValue) CFRelease(topValue);
-        }
-    }
-
-
- badparent:
-    if (constParent) CFRelease(constParent);
-    CFRelease(childName);
- badchildName:
-    CFRelease(parentName);
- badparentName:
- badparams:
-    if (path) CFRelease(path);
-    if (name) CFRelease(name);
-}
-
-
-// child must end with '/'
-JNIEXPORT Boolean JNICALL
-Java_java_util_prefs_MacOSXPreferencesFile_addChildToNode
-(JNIEnv *env, jobject klass, jobject jpath, jobject jchild,
- jobject jname, jlong juser, jlong jhost)
-{
-    // like addNode, but can put a three-level-deep dict into the root file
-    CFStringRef path = toCF(env, jpath);
-    CFStringRef child = toCF(env, jchild);
-    CFStringRef name = toCF(env, jname);
-    CFStringRef user = (CFStringRef)jlong_to_ptr(juser);
-    CFStringRef host = (CFStringRef)jlong_to_ptr(jhost);
-    CFMutableDictionaryRef parent;
-    CFDictionaryRef node;
-    CFStringRef topKey;
-    CFMutableDictionaryRef topValue;
-    Boolean beforeAdd = false;
-
-    if (!path  ||  !child  ||  !name) goto badparams;
-
-    node = createEmptyNode();
-    throwIfNull(node, "createEmptyNode failed");
-
-    // copyMutableNode creates the node if necessary
-    parent = copyMutableNode(path, name, user, host, &topKey, &topValue);
-    throwIfNull(parent, "copyMutableNode failed");
-    beforeAdd = CFDictionaryContainsKey(parent, child);
-    CFDictionaryAddValue(parent, child, node);
-    if (!beforeAdd)
-        beforeAdd = CFDictionaryContainsKey(parent, child);
-    else
-        beforeAdd = false;
-    CFPreferencesSetValue(topKey, topValue, name, user, host);
-
-    CFRelease(parent);
-    if (topKey) CFRelease(topKey);
-    if (topValue) CFRelease(topValue);
- badparent:
-    CFRelease(node);
- badnode:
- badparams:
-    if (path) CFRelease(path);
-    if (child) CFRelease(child);
-    if (name) CFRelease(name);
-    return beforeAdd;
-}
-
-
-JNIEXPORT void JNICALL
-Java_java_util_prefs_MacOSXPreferencesFile_removeChildFromNode
-(JNIEnv *env, jobject klass, jobject jpath, jobject jchild,
- jobject jname, jlong juser, jlong jhost)
-{
-    CFStringRef path = toCF(env, jpath);
-    CFStringRef child = toCF(env, jchild);
-    CFStringRef name = toCF(env, jname);
-    CFStringRef user = (CFStringRef)jlong_to_ptr(juser);
-    CFStringRef host = (CFStringRef)jlong_to_ptr(jhost);
-    CFDictionaryRef constParent;
-
-    if (!path  ||  !child  ||  !name) goto badparams;
-
-    constParent = copyNodeIfPresent(path, name, user, host);
-    if (constParent  &&  CFDictionaryContainsKey(constParent, child)) {
-        CFStringRef topKey;
-        CFMutableDictionaryRef topValue;
-        CFMutableDictionaryRef parent;
-
-        parent = copyMutableNode(path, name, user, host, &topKey, &topValue);
-        throwIfNull(parent, "copyMutableNode failed");
-
-        CFDictionaryRemoveValue(parent, child);
-        CFPreferencesSetValue(topKey, topValue, name, user, host);
-
-        CFRelease(parent);
-        if (topKey) CFRelease(topKey);
-        if (topValue) CFRelease(topValue);
-    }
-
- badparent:
-    if (constParent) CFRelease(constParent);
- badparams:
-    if (path) CFRelease(path);
-    if (child) CFRelease(child);
-    if (name) CFRelease(name);
-}
-
-
-
-JNIEXPORT void JNICALL
-Java_java_util_prefs_MacOSXPreferencesFile_addKeyToNode
-(JNIEnv *env, jobject klass, jobject jpath, jobject jkey, jobject jvalue,
- jobject jname, jlong juser, jlong jhost)
-{
-    CFStringRef path = toCF(env, jpath);
-    CFStringRef key = toCF(env, jkey);
-    CFStringRef value = toCF(env, jvalue);
-    CFStringRef name = toCF(env, jname);
-    CFStringRef user = (CFStringRef)jlong_to_ptr(juser);
-    CFStringRef host = (CFStringRef)jlong_to_ptr(jhost);
-    CFMutableDictionaryRef node = NULL;
-    CFStringRef topKey;
-    CFMutableDictionaryRef topValue;
-
-    if (!path  ||  !key  || !value  ||  !name) goto badparams;
-
-    // fixme optimization: check whether old value and new value are identical
-    node = copyMutableNode(path, name, user, host, &topKey, &topValue);
-    throwIfNull(node, "copyMutableNode failed");
-
-    CFDictionarySetValue(node, key, value);
-    CFPreferencesSetValue(topKey, topValue, name, user, host);
-
-    CFRelease(node);
-    if (topKey) CFRelease(topKey);
-    if (topValue) CFRelease(topValue);
-
- badnode:
- badparams:
-    if (path) CFRelease(path);
-    if (key) CFRelease(key);
-    if (value) CFRelease(value);
-    if (name) CFRelease(name);
-}
-
-
-JNIEXPORT void JNICALL
-Java_java_util_prefs_MacOSXPreferencesFile_removeKeyFromNode
-(JNIEnv *env, jobject klass, jobject jpath, jobject jkey,
- jobject jname, jlong juser, jlong jhost)
-{
-    CFStringRef path = toCF(env, jpath);
-    CFStringRef key = toCF(env, jkey);
-    CFStringRef name = toCF(env, jname);
-    CFStringRef user = (CFStringRef)jlong_to_ptr(juser);
-    CFStringRef host = (CFStringRef)jlong_to_ptr(jhost);
-    CFDictionaryRef constNode;
-
-    if (!path  ||  !key  ||  !name) goto badparams;
-
-    constNode = copyNodeIfPresent(path, name, user, host);
-    if (constNode  &&  CFDictionaryContainsKey(constNode, key)) {
-        CFStringRef topKey;
-        CFMutableDictionaryRef topValue;
-        CFMutableDictionaryRef node;
-
-        node = copyMutableNode(path, name, user, host, &topKey, &topValue);
-        throwIfNull(node, "copyMutableNode failed");
-
-        CFDictionaryRemoveValue(node, key);
-        CFPreferencesSetValue(topKey, topValue, name, user, host);
-
-        CFRelease(node);
-        if (topKey) CFRelease(topKey);
-        if (topValue) CFRelease(topValue);
-    }
-
- badnode:
-    if (constNode) CFRelease(constNode);
- badparams:
-    if (path) CFRelease(path);
-    if (key) CFRelease(key);
-    if (name) CFRelease(name);
-}
-
-
-// path must end in '/'
-JNIEXPORT jstring JNICALL
-Java_java_util_prefs_MacOSXPreferencesFile_getKeyFromNode
-(JNIEnv *env, jobject klass, jobject jpath, jobject jkey,
- jobject jname, jlong juser, jlong jhost)
-{
-    CFStringRef path = toCF(env, jpath);
-    CFStringRef key = toCF(env, jkey);
-    CFStringRef name = toCF(env, jname);
-    CFStringRef user = (CFStringRef)jlong_to_ptr(juser);
-    CFStringRef host = (CFStringRef)jlong_to_ptr(jhost);
-    CFPropertyListRef value;
-    CFDictionaryRef node;
-    jstring result = NULL;
-
-    if (!path  ||  !key  ||  !name) goto badparams;
-
-    node = copyNodeIfPresent(path, name, user, host);
-    if (node) {
-        value = (CFPropertyListRef)CFDictionaryGetValue(node, key);
-        if (!value) {
-            // key doesn't exist, or other error - no Java errors available
-            result = NULL;
-        } else {
-            CFStringRef cfString = copyToCFString(env, value);
-            if ((*env)->ExceptionOccurred(env)) {
-                // memory error in copyToCFString
-                result = NULL;
-            } else if (cfString == NULL) {
-                // bogus value type in prefs file - no Java errors available
-                result = NULL;
-            } else {
-                // good cfString
-                result = toJavaString(env, cfString);
-                CFRelease(cfString);
-            }
-        }
-        CFRelease(node);
-    }
-
- badparams:
-    if (path) CFRelease(path);
-    if (key) CFRelease(key);
-    if (name) CFRelease(name);
-
-    return result;
-}
-
-
-typedef struct {
-    jarray result;
-    JNIEnv *env;
-    CFIndex used;
-    Boolean allowSlash;
-} BuildJavaArrayArgs;
-
-// CFDictionary applier function that builds an array of Java strings
-//   from a CFDictionary of CFPropertyListRefs.
-// If args->allowSlash, only strings that end in '/' are added to the array,
-//   with the slash removed. Otherwise, only strings that do not end in '/'
-//   are added.
-// args->result must already exist and be large enough to hold all
-//   strings from the dictionary.
-// After complete application, args->result may not be full because
-//   some of the dictionary values weren't convertible to string. In
-//   this case, args->used will be the count of used elements.
-static void BuildJavaArrayFn(const void *key, const void *value, void *context)
-{
-    BuildJavaArrayArgs *args = (BuildJavaArrayArgs *)context;
-    CFPropertyListRef propkey = (CFPropertyListRef)key;
-    CFStringRef cfString = NULL;
-    JNIEnv *env = args->env;
-
-    if ((*env)->ExceptionOccurred(env)) return; // already failed
-
-    cfString = copyToCFString(env, propkey);
-    if ((*env)->ExceptionOccurred(env)) {
-        // memory error in copyToCFString
-    } else if (!cfString) {
-        // bogus value type in prefs file - no Java errors available
-    } else if (args->allowSlash != CFStringHasSuffix(cfString, CFSTR("/"))) {
-        // wrong suffix - ignore
-    } else {
-        // good cfString
-        jstring javaString;
-        if (args->allowSlash) {
-            CFRange range = CFRangeMake(0, CFStringGetLength(cfString) - 1);
-            CFStringRef s = CFStringCreateWithSubstring(NULL, cfString, range);
-            CFRelease(cfString);
-            cfString = s;
-        }
-        if (CFStringGetLength(cfString) <= 0) goto bad; // ignore empty
-        javaString = toJavaString(env, cfString);
-        if ((*env)->ExceptionOccurred(env)) goto bad;
-        (*env)->SetObjectArrayElement(env, args->result,args->used,javaString);
-        if ((*env)->ExceptionOccurred(env)) goto bad;
-        args->used++;
-    }
-
- bad:
-    if (cfString) CFRelease(cfString);
-}
-
-
-static jarray getStringsForNode(JNIEnv *env, jobject klass, jobject jpath,
-                                jobject jname, jlong juser, jlong jhost,
-                                Boolean allowSlash)
-{
-    CFStringRef path = toCF(env, jpath);
-    CFStringRef name = toCF(env, jname);
-    CFStringRef user = (CFStringRef)jlong_to_ptr(juser);
-    CFStringRef host = (CFStringRef)jlong_to_ptr(jhost);
-    CFDictionaryRef node;
-    jarray result = NULL;
-    CFIndex count;
-
-    if (!path  ||  !name) goto badparams;
-
-    node = copyNodeIfPresent(path, name, user, host);
-    if (!node) {
-        result = createJavaStringArray(env, 0);
-    } else {
-        count = CFDictionaryGetCount(node);
-        result = createJavaStringArray(env, count);
-        if (result) {
-            BuildJavaArrayArgs args;
-            args.result = result;
-            args.env = env;
-            args.used = 0;
-            args.allowSlash = allowSlash;
-            CFDictionaryApplyFunction(node, BuildJavaArrayFn, &args);
-            if (!(*env)->ExceptionOccurred(env)) {
-                // array construction succeeded
-                if (args.used < count) {
-                    // finished array is smaller than expected.
-                    // Make a new array of precisely the right size.
-                    jarray newresult = createJavaStringArray(env, args.used);
-                    if (newresult) {
-                        JVM_ArrayCopy(env,0, result,0, newresult,0, args.used);
-                        result = newresult;
-                    }
-                }
-            }
-        }
-
-        CFRelease(node);
-    }
-
- badparams:
-    if (path) CFRelease(path);
-    if (name) CFRelease(name);
-
-    return result;
-}
-
-
-JNIEXPORT jarray JNICALL
-Java_java_util_prefs_MacOSXPreferencesFile_getKeysForNode
-(JNIEnv *env, jobject klass, jobject jpath,
- jobject jname, jlong juser, jlong jhost)
-{
-    return getStringsForNode(env, klass, jpath, jname, juser, jhost, false);
-}
-
-JNIEXPORT jarray JNICALL
-Java_java_util_prefs_MacOSXPreferencesFile_getChildrenForNode
-(JNIEnv *env, jobject klass, jobject jpath,
- jobject jname, jlong juser, jlong jhost)
-{
-    return getStringsForNode(env, klass, jpath, jname, juser, jhost, true);
-}
-
-
-// Returns false on error instead of throwing.
-JNIEXPORT jboolean JNICALL
-Java_java_util_prefs_MacOSXPreferencesFile_synchronize
-(JNIEnv *env, jobject klass,
- jstring jname, jlong juser, jlong jhost)
-{
-    CFStringRef name = toCF(env, jname);
-    CFStringRef user = (CFStringRef)jlong_to_ptr(juser);
-    CFStringRef host = (CFStringRef)jlong_to_ptr(jhost);
-    jboolean result = 0;
-
-    if (name) {
-        result = CFPreferencesSynchronize(name, user, host);
-        CFRelease(name);
-    }
-
-    return result;
-}
--- a/src/macosx/native/java/util/SCDynamicStoreConfig.m	Mon Feb 10 18:09:40 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,222 +0,0 @@
-/*
- * Copyright (c) 2011, 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.
- */
-
-#import <Cocoa/Cocoa.h>
-#import <JavaNativeFoundation/JavaNativeFoundation.h>
-#import <SystemConfiguration/SystemConfiguration.h>
-
-
-@interface JNFVectorCoercion : NSObject <JNFTypeCoercion> { }
-@end
-
-@implementation JNFVectorCoercion
-
-- (jobject) coerceNSObject:(id)obj withEnv:(JNIEnv *)env usingCoercer:(JNFTypeCoercion *)coercer {
-    static JNF_CLASS_CACHE(jc_Vector, "java/util/Vector");
-    static JNF_CTOR_CACHE(jm_Vector_ctor, jc_Vector, "(I)V");
-    static JNF_MEMBER_CACHE(jm_Vector_add, jc_Vector, "add", "(Ljava/lang/Object;)Z");
-
-    NSArray *nsArray = (NSArray *)obj;
-    jobject javaArray = JNFNewObject(env, jm_Vector_ctor, (jint)[nsArray count]);
-
-    for (id obj in nsArray) {
-        jobject jobj = [coercer coerceNSObject:obj withEnv:env usingCoercer:coercer];
-        JNFCallBooleanMethod(env, javaArray, jm_Vector_add, jobj);
-        if (jobj != NULL) (*env)->DeleteLocalRef(env, jobj);
-    }
-
-    return javaArray;
-}
-
-- (id) coerceJavaObject:(jobject)obj withEnv:(JNIEnv *)env usingCoercer:(JNFTypeCoercion *)coercer {
-    return nil;
-}
-
-@end
-
-
-@interface JNFHashtableCoercion : NSObject <JNFTypeCoercion> { }
-@end
-
-@implementation JNFHashtableCoercion
-
-- (jobject) coerceNSObject:(id)obj withEnv:(JNIEnv *)env usingCoercer:(JNFTypeCoercion *)coercer {
-    static JNF_CLASS_CACHE(jc_Hashtable, "java/util/Hashtable");
-    static JNF_CTOR_CACHE(jm_Hashtable_ctor, jc_Hashtable, "()V");
-    static JNF_MEMBER_CACHE(jm_Hashtable_put, jc_Hashtable, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
-
-    NSDictionary *nsDict = (NSDictionary *)obj;
-    NSEnumerator *keyEnum = [nsDict keyEnumerator];
-
-    jobject jHashTable = JNFNewObject(env, jm_Hashtable_ctor);
-
-    id key = nil;
-    while ((key = [keyEnum nextObject]) != nil) {
-        jobject jkey = [coercer coerceNSObject:key withEnv:env usingCoercer:coercer];
-
-        id value = [nsDict objectForKey:key];
-        jobject jvalue = [coercer coerceNSObject:value withEnv:env usingCoercer:coercer];
-
-        JNFCallObjectMethod(env, jHashTable, jm_Hashtable_put, jkey, jvalue);
-
-        if (jkey != NULL) (*env)->DeleteLocalRef(env, jkey);
-        if (jvalue != NULL) (*env)->DeleteLocalRef(env, jvalue);
-    }
-
-    return jHashTable;
-}
-
-- (id) coerceJavaObject:(jobject)obj withEnv:(JNIEnv *)env usingCoercer:(JNFTypeCoercion *)coercer {
-    return nil;
-}
-
-@end
-
-
-
-NSDictionary *realmConfigsForRealms(SCDynamicStoreRef store, NSArray *realms) {
-    NSMutableDictionary *dict = [NSMutableDictionary dictionary];
-
-    for (NSString *realm in realms) {
-        CFTypeRef realmInfo = SCDynamicStoreCopyValue(store, (CFStringRef) [NSString stringWithFormat:@"Kerberos:%@", realm]);
-
-        if (CFGetTypeID(realmInfo) != CFDictionaryGetTypeID()) {
-            return nil;
-        }
-
-        [dict setObject:(NSArray *)realmInfo forKey:realm];
-        CFRelease(realmInfo);
-    }
-
-    return dict;
-}
-
-
-#define KERBEROS_DEFAULT_REALMS @"Kerberos-Default-Realms"
-#define KERBEROS_DEFAULT_REALM_MAPPINGS @"Kerberos-Domain-Realm-Mappings"
-
-void _SCDynamicStoreCallBack(SCDynamicStoreRef store, CFArrayRef changedKeys, void *info) {
-   NSArray *keys = (NSArray *)changedKeys;
-    if ([keys count] == 0) return;
-    if (![keys containsObject:KERBEROS_DEFAULT_REALMS] && ![keys containsObject:KERBEROS_DEFAULT_REALM_MAPPINGS]) return;
-
-    JNFPerformEnvBlock(JNFThreadDetachOnThreadDeath | JNFThreadSetSystemClassLoaderOnAttach | JNFThreadAttachAsDaemon, ^(JNIEnv *env) {
-        static JNF_CLASS_CACHE(jc_Config, "sun/security/krb5/Config");
-        static JNF_STATIC_MEMBER_CACHE(jm_Config_refresh, jc_Config, "refresh", "()V");
-        JNFCallStaticVoidMethod(env, jm_Config_refresh);
-    });
-}
-
-/*
- * Class:     sun_security_krb5_SCDynamicStoreConfig
- * Method:    installNotificationCallback
- */
-JNIEXPORT void JNICALL Java_sun_security_krb5_SCDynamicStoreConfig_installNotificationCallback(JNIEnv *env, jclass klass) {
-
-JNF_COCOA_ENTER(env);
-
-    SCDynamicStoreRef store = SCDynamicStoreCreate(NULL, CFSTR("java"), _SCDynamicStoreCallBack, NULL);
-    if (store == NULL) {
-        return;
-    }
-
-    NSArray *keys = [NSArray arrayWithObjects:KERBEROS_DEFAULT_REALMS, KERBEROS_DEFAULT_REALM_MAPPINGS, nil];
-    SCDynamicStoreSetNotificationKeys(store, (CFArrayRef) keys, NULL);
-
-    CFRunLoopSourceRef rls = SCDynamicStoreCreateRunLoopSource(NULL, store, 0);
-    if (rls != NULL) {
-        CFRunLoopAddSource(CFRunLoopGetMain(), rls, kCFRunLoopDefaultMode);
-        CFRelease(rls);
-    }
-
-    CFRelease(store);
-
-JNF_COCOA_EXIT(env);
-
-}
-
-/*
- * Class:     sun_security_krb5_SCDynamicStoreConfig
- * Method:    getKerberosConfig
- * Signature: ()Ljava/util/Hashtable;
- */
-JNIEXPORT jobject JNICALL Java_sun_security_krb5_SCDynamicStoreConfig_getKerberosConfig(JNIEnv *env, jclass klass) {
-    jobject jHashTable = NULL;
-
-JNF_COCOA_ENTER(env);
-
-    SCDynamicStoreRef store = SCDynamicStoreCreate(NULL, CFSTR("java-kerberos"), NULL, NULL);
-    if (store == NULL) {
-        return NULL;
-    }
-
-    CFTypeRef realms = SCDynamicStoreCopyValue(store, (CFStringRef) KERBEROS_DEFAULT_REALMS);
-    if (realms == NULL || CFGetTypeID(realms) != CFArrayGetTypeID()) {
-        if (realms) CFRelease(realms);
-        CFRelease(store);
-        return NULL;
-    }
-
-    CFTypeRef realmMappings = SCDynamicStoreCopyValue(store, (CFStringRef) KERBEROS_DEFAULT_REALM_MAPPINGS);
-
-    if (realmMappings == NULL || CFGetTypeID(realmMappings) != CFArrayGetTypeID()) {
-        if (realmMappings) CFRelease(realmMappings);
-        CFRelease(realms);
-        CFRelease(store);
-        return NULL;
-    }
-
-    NSMutableDictionary *dict = [NSMutableDictionary dictionary];
-
-    if (CFArrayGetCount(realms) > 0) {
-        NSDictionary *defaultRealmsDict = [NSDictionary dictionaryWithObject:[(NSArray *)realms objectAtIndex:0] forKey:@"default_realm"];
-        [dict setObject:defaultRealmsDict forKey:@"libdefaults"];
-
-        NSDictionary *realmConfigs = realmConfigsForRealms(store, (NSArray *)realms);
-        [dict setObject:realmConfigs forKey:@"realms"];
-    }
-    CFRelease(realms);
-    CFRelease(store);
-
-    if (CFArrayGetCount(realmMappings) > 0) {
-        [dict setObject:[(NSArray *)realmMappings objectAtIndex:0] forKey:@"domain_realm"];
-    }
-    CFRelease(realmMappings);
-
-
-    // create and load a coercer with all of the different coercions to convert each type of object
-    JNFTypeCoercer *coercer = [[[JNFTypeCoercer alloc] init] autorelease];
-    [JNFDefaultCoercions addStringCoercionTo:coercer];
-    [JNFDefaultCoercions addNumberCoercionTo:coercer];
-    [coercer addCoercion:[[[JNFHashtableCoercion alloc] init] autorelease] forNSClass:[NSDictionary class] javaClass:@"java/util/Map"];
-    [coercer addCoercion:[[[JNFVectorCoercion alloc] init] autorelease] forNSClass:[NSArray class] javaClass:@"java/util/List"];
-
-    // convert Cocoa graph to Java graph
-    jHashTable = [coercer coerceNSObject:dict withEnv:env];
-
-JNF_COCOA_EXIT(env);
-
-    return jHashTable;
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/macosx/native/java/util/prefs/MacOSXPreferencesFile.m	Tue Feb 11 09:59:34 2014 +0000
@@ -0,0 +1,999 @@
+/*
+ * Copyright (c) 2011, 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.
+ */
+
+/*
+   Hierarchical storage layout:
+
+   <dict>
+     <key>/</key>
+     <dict>
+       <key>foo</key>
+       <string>/foo's value</string>
+       <key>foo/</key>
+       <dict>
+         <key>bar</key>
+         <string>/foo/bar's value</string>
+       </dict>
+     </dict>
+   </dict>
+
+   Java pref nodes are stored in several different files. Pref nodes
+   with at least three components in the node name (e.g. /com/MyCompany/MyApp/)
+   are stored in a CF prefs file with the first three components as the name.
+   This way, all preferences for MyApp end up in com.MyCompany.MyApp.plist .
+   Pref nodes with shorter names are stored in com.apple.java.util.prefs.plist
+
+   The filesystem is assumed to be case-insensitive (like HFS+).
+   Java pref node names are case-sensitive. If two pref node names differ
+   only in case, they may end up in the same pref file. This is ok
+   because the CF keys identifying the node span the entire absolute path
+   to the node and are case-sensitive.
+
+   Java node names may contain '.' . When mapping to the CF file name,
+   these dots are left as-is, even though '/' is mapped to '.' .
+   This is ok because the CF key contains the correct node name.
+*/
+
+
+
+#include <CoreFoundation/CoreFoundation.h>
+
+#include "jni_util.h"
+#include "jlong.h"
+#include "jvm.h"
+
+
+// Throw an OutOfMemoryError with the given message.
+static void throwOutOfMemoryError(JNIEnv *env, const char *msg)
+{
+    static jclass exceptionClass = NULL;
+    jclass c;
+
+    if (exceptionClass) {
+        c = exceptionClass;
+    } else {
+        c = (*env)->FindClass(env, "java/lang/OutOfMemoryError");
+        if ((*env)->ExceptionOccurred(env)) return;
+        exceptionClass = (*env)->NewGlobalRef(env, c);
+    }
+
+    (*env)->ThrowNew(env, c, msg);
+}
+
+
+// throwIfNull macro
+// If var is NULL, throw an OutOfMemoryError and goto badvar.
+// var must be a variable. env must be the current JNIEnv.
+// fixme throw BackingStoreExceptions sometimes?
+#define throwIfNull(var, msg) \
+    do { \
+        if (var == NULL) { \
+            throwOutOfMemoryError(env, msg); \
+            goto bad##var; \
+        } \
+    } while (0)
+
+
+// Converts CFNumber, CFBoolean, CFString to CFString
+// returns NULL if value is of some other type
+// throws and returns NULL on memory error
+// result must be released (even if value was already a CFStringRef)
+// value must not be null
+static CFStringRef copyToCFString(JNIEnv *env, CFTypeRef value)
+{
+    CFStringRef result;
+    CFTypeID type;
+
+    type = CFGetTypeID(value);
+
+    if (type == CFStringGetTypeID()) {
+        result = (CFStringRef)CFRetain(value);
+    }
+    else if (type == CFBooleanGetTypeID()) {
+        // Java Preferences API expects "true" and "false" for boolean values.
+        result = CFStringCreateCopy(NULL, (value == kCFBooleanTrue) ? CFSTR("true") : CFSTR("false"));
+        throwIfNull(result, "copyToCFString failed");
+    }
+    else if (type == CFNumberGetTypeID()) {
+        CFNumberRef number = (CFNumberRef) value;
+        if (CFNumberIsFloatType(number)) {
+            double d;
+            CFNumberGetValue(number, kCFNumberDoubleType, &d);
+            result = CFStringCreateWithFormat(NULL, NULL, CFSTR("%g"), d);
+            throwIfNull(result, "copyToCFString failed");
+        }
+        else {
+            long l;
+            CFNumberGetValue(number, kCFNumberLongType, &l);
+            result = CFStringCreateWithFormat(NULL, NULL, CFSTR("%ld"), l);
+            throwIfNull(result, "copyToCFString failed");
+        }
+    }
+    else {
+        // unknown type - return NULL
+        result = NULL;
+    }
+
+ badresult:
+    return result;
+}
+
+
+// Create a Java string from the given CF string.
+// returns NULL if cfString is NULL
+// throws and returns NULL on memory error
+static jstring toJavaString(JNIEnv *env, CFStringRef cfString)
+{
+    if (cfString == NULL) {
+        return NULL;
+    } else {
+        jstring javaString = NULL;
+
+        CFIndex length = CFStringGetLength(cfString);
+        const UniChar *constchars = CFStringGetCharactersPtr(cfString);
+        if (constchars) {
+            javaString = (*env)->NewString(env, constchars, length);
+        } else {
+            UniChar *chars = malloc(length * sizeof(UniChar));
+            throwIfNull(chars, "toJavaString failed");
+            CFStringGetCharacters(cfString, CFRangeMake(0, length), chars);
+            javaString = (*env)->NewString(env, chars, length);
+            free(chars);
+        }
+    badchars:
+        return javaString;
+    }
+}
+
+
+
+// Create a CF string from the given Java string.
+// returns NULL if javaString is NULL
+// throws and returns NULL on memory error
+static CFStringRef toCF(JNIEnv *env, jstring javaString)
+{
+    if (javaString == NULL) {
+        return NULL;
+    } else {
+        CFStringRef result = NULL;
+        jsize length = (*env)->GetStringLength(env, javaString);
+        const jchar *chars = (*env)->GetStringChars(env, javaString, NULL);
+        throwIfNull(chars, "toCF failed");
+        result =
+            CFStringCreateWithCharacters(NULL, (const UniChar *)chars, length);
+        (*env)->ReleaseStringChars(env, javaString, chars);
+        throwIfNull(result, "toCF failed");
+    badchars:
+    badresult:
+        return result;
+    }
+}
+
+
+// Create an empty Java string array of the given size.
+// Throws and returns NULL on error.
+static jarray createJavaStringArray(JNIEnv *env, CFIndex count)
+{
+    static jclass stringClass = NULL;
+    jclass c;
+
+    if (stringClass) {
+        c = stringClass;
+    } else {
+        c = (*env)->FindClass(env, "java/lang/String");
+        if ((*env)->ExceptionOccurred(env)) return NULL;
+        stringClass = (*env)->NewGlobalRef(env, c);
+    }
+
+    return (*env)->NewObjectArray(env, count, c, NULL); // AWT_THREADING Safe (known object)
+}
+
+
+// Java accessors for CF constants.
+JNIEXPORT jlong JNICALL
+Java_java_util_prefs_MacOSXPreferencesFile_currentUser(JNIEnv *env,
+                                                       jobject klass)
+{
+    return ptr_to_jlong(kCFPreferencesCurrentUser);
+}
+
+JNIEXPORT jlong JNICALL
+Java_java_util_prefs_MacOSXPreferencesFile_anyUser(JNIEnv *env, jobject klass)
+{
+    return ptr_to_jlong(kCFPreferencesAnyUser);
+}
+
+JNIEXPORT jlong JNICALL
+Java_java_util_prefs_MacOSXPreferencesFile_currentHost(JNIEnv *env,
+                                                       jobject klass)
+{
+    return ptr_to_jlong(kCFPreferencesCurrentHost);
+}
+
+JNIEXPORT jlong JNICALL
+Java_java_util_prefs_MacOSXPreferencesFile_anyHost(JNIEnv *env, jobject klass)
+{
+    return ptr_to_jlong(kCFPreferencesAnyHost);
+}
+
+
+// Create an empty node.
+// Does not store the node in any prefs file.
+// returns NULL on memory error
+static CFMutableDictionaryRef createEmptyNode(void)
+{
+    return CFDictionaryCreateMutable(NULL, 0,
+                                     &kCFTypeDictionaryKeyCallBacks,
+                                     &kCFTypeDictionaryValueCallBacks);
+}
+
+
+// Create a string that consists of path minus its last component.
+// path must end with '/'
+// The result will end in '/' (unless path itself is '/')
+static CFStringRef copyParentOf(CFStringRef path)
+{
+    CFRange searchRange;
+    CFRange slashRange;
+    CFRange parentRange;
+    Boolean found;
+
+    searchRange = CFRangeMake(0, CFStringGetLength(path) - 1);
+    found = CFStringFindWithOptions(path, CFSTR("/"), searchRange,
+                                    kCFCompareBackwards, &slashRange);
+    if (!found) return CFSTR("");
+    parentRange = CFRangeMake(0, slashRange.location + 1); // include '/'
+    return CFStringCreateWithSubstring(NULL, path, parentRange);
+}
+
+
+// Create a string that consists of path's last component.
+// path must end with '/'
+// The result will end in '/'.
+// The result will not start with '/' (unless path itself is '/')
+static CFStringRef copyChildOf(CFStringRef path)
+{
+    CFRange searchRange;
+    CFRange slashRange;
+    CFRange childRange;
+    Boolean found;
+    CFIndex length = CFStringGetLength(path);
+
+    searchRange = CFRangeMake(0, length - 1);
+    found = CFStringFindWithOptions(path, CFSTR("/"), searchRange,
+                                    kCFCompareBackwards, &slashRange);
+    if (!found) return CFSTR("");
+    childRange = CFRangeMake(slashRange.location + 1,
+                             length - slashRange.location - 1); // skip '/'
+    return CFStringCreateWithSubstring(NULL, path, childRange);
+}
+
+
+// Return the first three components of path, with leading and trailing '/'.
+// If path does not have three components, return NULL.
+// path must begin and end in '/'
+static CFStringRef copyFirstThreeComponentsOf(CFStringRef path)
+{
+    CFRange searchRange;
+    CFRange slashRange;
+    CFRange prefixRange;
+    CFStringRef prefix;
+    Boolean found;
+    CFIndex length = CFStringGetLength(path);
+
+    searchRange = CFRangeMake(1, length - 1);  // skip leading '/'
+    found = CFStringFindWithOptions(path, CFSTR("/"), searchRange, 0,
+                                    &slashRange);
+    if (!found) return NULL;  // no second slash!
+
+    searchRange = CFRangeMake(slashRange.location + 1,
+                              length - slashRange.location - 1);
+    found = CFStringFindWithOptions(path, CFSTR("/"), searchRange, 0,
+                                    &slashRange);
+    if (!found) return NULL;  // no third slash!
+
+    searchRange = CFRangeMake(slashRange.location + 1,
+                              length - slashRange.location - 1);
+    found = CFStringFindWithOptions(path, CFSTR("/"), searchRange, 0,
+                                    &slashRange);
+    if (!found) return NULL;  // no fourth slash!
+
+    prefixRange = CFRangeMake(0, slashRange.location + 1); // keep last '/'
+    prefix = CFStringCreateWithSubstring(NULL, path, prefixRange);
+
+    return prefix;
+}
+
+
+// Copy the CFPreferences key and value at the base of path's tree.
+// path must end in '/'
+// topKey or topValue may be NULL
+// Returns NULL on error or if there is no tree for path in this file.
+static void copyTreeForPath(CFStringRef path, CFStringRef name,
+                            CFStringRef user, CFStringRef host,
+                            CFStringRef *topKey, CFDictionaryRef *topValue)
+{
+    CFStringRef key;
+    CFPropertyListRef value;
+
+    if (topKey) *topKey = NULL;
+    if (topValue) *topValue = NULL;
+
+    if (CFEqual(name, CFSTR("com.apple.java.util.prefs"))) {
+        // Top-level file. Only key "/" is an acceptable root.
+        key = (CFStringRef) CFRetain(CFSTR("/"));
+    } else {
+        // Second-level file. Key must be the first three components of path.
+        key = copyFirstThreeComponentsOf(path);
+        if (!key) return;
+    }
+
+    value = CFPreferencesCopyValue(key, name, user, host);
+    if (value) {
+        if (CFGetTypeID(value) == CFDictionaryGetTypeID()) {
+            // (key, value) is acceptable
+            if (topKey) *topKey = (CFStringRef)CFRetain(key);
+            if (topValue) *topValue = (CFDictionaryRef)CFRetain(value);
+        }
+        CFRelease(value);
+    }
+    CFRelease(key);
+}
+
+
+// Find the node for path in the given tree.
+// Returns NULL on error or if path doesn't have a node in this tree.
+// path must end in '/'
+static CFDictionaryRef copyNodeInTree(CFStringRef path, CFStringRef topKey,
+                                      CFDictionaryRef topValue)
+{
+    CFMutableStringRef p;
+    CFDictionaryRef result = NULL;
+
+    p = CFStringCreateMutableCopy(NULL, 0, path);
+    if (!p) return NULL;
+    CFStringDelete(p, CFRangeMake(0, CFStringGetLength(topKey)));
+    result = topValue;
+
+    while (CFStringGetLength(p) > 0) {
+        CFDictionaryRef child;
+        CFStringRef part = NULL;
+        CFRange slashRange = CFStringFind(p, CFSTR("/"), 0);
+        // guaranteed to succeed because path must end in '/'
+        CFRange partRange = CFRangeMake(0, slashRange.location + 1);
+        part = CFStringCreateWithSubstring(NULL, p, partRange);
+        if (!part) { result = NULL; break; }
+        CFStringDelete(p, partRange);
+
+        child = CFDictionaryGetValue(result, part);
+        CFRelease(part);
+        if (child  &&  CFGetTypeID(child) == CFDictionaryGetTypeID()) {
+            // continue search
+            result = child;
+        } else {
+            // didn't find target node
+            result = NULL;
+            break;
+        }
+    }
+
+    CFRelease(p);
+    if (result) return (CFDictionaryRef)CFRetain(result);
+    else return NULL;
+}
+
+
+// Return a retained copy of the node at path from the given file.
+// path must end in '/'
+// returns NULL if node doesn't exist.
+// returns NULL if the value for key "path" isn't a valid node.
+static CFDictionaryRef copyNodeIfPresent(CFStringRef path, CFStringRef name,
+                                         CFStringRef user, CFStringRef host)
+{
+    CFStringRef topKey;
+    CFDictionaryRef topValue;
+    CFDictionaryRef result;
+
+    copyTreeForPath(path, name, user, host, &topKey, &topValue);
+    if (!topKey) return NULL;
+
+    result = copyNodeInTree(path, topKey, topValue);
+
+    CFRelease(topKey);
+    if (topValue) CFRelease(topValue);
+    return result;
+}
+
+
+// Create a new tree that would store path in the given file.
+// Only the root of the tree is created, not all of the links leading to path.
+// returns NULL on error
+static void createTreeForPath(CFStringRef path, CFStringRef name,
+                              CFStringRef user, CFStringRef host,
+                              CFStringRef *outTopKey,
+                              CFMutableDictionaryRef *outTopValue)
+{
+    *outTopKey = NULL;
+    *outTopValue = NULL;
+
+    // if name is "com.apple.java.util.prefs" then create tree "/"
+    // else create tree "/foo/bar/baz/"
+    // "com.apple.java.util.prefs.plist" is also in MacOSXPreferences.java
+    if (CFEqual(name, CFSTR("com.apple.java.util.prefs"))) {
+        *outTopKey = CFSTR("/");
+        *outTopValue = createEmptyNode();
+    } else {
+        CFStringRef prefix = copyFirstThreeComponentsOf(path);
+        if (prefix) {
+            *outTopKey = prefix;
+            *outTopValue = createEmptyNode();
+        }
+    }
+}
+
+
+// Return a mutable copy of the tree containing path and the dict for
+//   path itself. *outTopKey and *outTopValue can be used to write the
+//   modified tree back to the prefs file.
+// *outTopKey and *outTopValue must be released iff the actual return
+//   value is not NULL.
+static CFMutableDictionaryRef
+copyMutableNode(CFStringRef path, CFStringRef name,
+                CFStringRef user, CFStringRef host,
+                CFStringRef *outTopKey,
+                CFMutableDictionaryRef *outTopValue)
+{
+    CFStringRef topKey = NULL;
+    CFDictionaryRef oldTopValue = NULL;
+    CFMutableDictionaryRef topValue;
+    CFMutableDictionaryRef result = NULL;
+    CFMutableStringRef p;
+
+    if (outTopKey) *outTopKey = NULL;
+    if (outTopValue) *outTopValue = NULL;
+
+    copyTreeForPath(path, name, user, host, &topKey, &oldTopValue);
+    if (!topKey) {
+        createTreeForPath(path, name, user, host, &topKey, &topValue);
+    } else {
+        topValue = (CFMutableDictionaryRef)
+            CFPropertyListCreateDeepCopy(NULL, (CFPropertyListRef)oldTopValue,
+                                         kCFPropertyListMutableContainers);
+    }
+    if (!topValue) goto badtopValue;
+
+    p = CFStringCreateMutableCopy(NULL, 0, path);
+    if (!p) goto badp;
+    CFStringDelete(p, CFRangeMake(0, CFStringGetLength(topKey)));
+    result = topValue;
+
+    while (CFStringGetLength(p) > 0) {
+        CFMutableDictionaryRef child;
+        CFStringRef part = NULL;
+        CFRange slashRange = CFStringFind(p, CFSTR("/"), 0);
+        // guaranteed to succeed because path must end in '/'
+        CFRange partRange = CFRangeMake(0, slashRange.location + 1);
+        part = CFStringCreateWithSubstring(NULL, p, partRange);
+        if (!part) { result = NULL; break; }
+        CFStringDelete(p, partRange);
+
+        child = (CFMutableDictionaryRef)CFDictionaryGetValue(result, part);
+        if (child  &&  CFGetTypeID(child) == CFDictionaryGetTypeID()) {
+            // continue search
+            result = child;
+        } else {
+            // didn't find target node - add it and continue
+            child = createEmptyNode();
+            if (!child) { CFRelease(part); result = NULL; break; }
+            CFDictionaryAddValue(result, part, child);
+            result = child;
+        }
+        CFRelease(part);
+    }
+
+    if (result) {
+        *outTopKey = (CFStringRef)CFRetain(topKey);
+        *outTopValue = (CFMutableDictionaryRef)CFRetain(topValue);
+        CFRetain(result);
+    }
+
+    CFRelease(p);
+ badp:
+    CFRelease(topValue);
+ badtopValue:
+    if (topKey) CFRelease(topKey);
+    if (oldTopValue) CFRelease(oldTopValue);
+    return result;
+}
+
+
+JNIEXPORT jboolean JNICALL
+Java_java_util_prefs_MacOSXPreferencesFile_addNode
+(JNIEnv *env, jobject klass, jobject jpath,
+ jobject jname, jlong juser, jlong jhost)
+{
+    CFStringRef path = toCF(env, jpath);
+    CFStringRef name = toCF(env, jname);
+    CFStringRef user = (CFStringRef)jlong_to_ptr(juser);
+    CFStringRef host = (CFStringRef)jlong_to_ptr(jhost);
+    CFDictionaryRef node = NULL;
+    jboolean neededNewNode = false;
+
+    if (!path  ||  !name) goto badparams;
+
+    node = copyNodeIfPresent(path, name, user, host);
+
+    if (node) {
+        neededNewNode = false;
+        CFRelease(node);
+    } else {
+        CFStringRef topKey = NULL;
+        CFMutableDictionaryRef topValue = NULL;
+
+        neededNewNode = true;
+
+        // copyMutableNode creates the node if necessary
+        node = copyMutableNode(path, name, user, host, &topKey, &topValue);
+        throwIfNull(node, "copyMutableNode failed");
+
+        CFPreferencesSetValue(topKey, topValue, name, user, host);
+
+        CFRelease(node);
+        if (topKey) CFRelease(topKey);
+        if (topValue) CFRelease(topValue);
+    }
+
+ badnode:
+ badparams:
+    if (path) CFRelease(path);
+    if (name) CFRelease(name);
+
+    return neededNewNode;
+}
+
+
+JNIEXPORT void JNICALL
+Java_java_util_prefs_MacOSXPreferencesFile_removeNode
+(JNIEnv *env, jobject klass, jobject jpath,
+ jobject jname, jlong juser, jlong jhost)
+{
+    CFStringRef path = toCF(env, jpath);
+    CFStringRef name = toCF(env, jname);
+    CFStringRef user = (CFStringRef)jlong_to_ptr(juser);
+    CFStringRef host = (CFStringRef)jlong_to_ptr(jhost);
+    CFStringRef parentName;
+    CFStringRef childName;
+    CFDictionaryRef constParent;
+
+    if (!path  ||  !name) goto badparams;
+
+    parentName = copyParentOf(path);
+    throwIfNull(parentName, "copyParentOf failed");
+    childName  = copyChildOf(path);
+    throwIfNull(childName, "copyChildOf failed");
+
+    // root node is not allowed to be removed, so parentName is never empty
+
+    constParent = copyNodeIfPresent(parentName, name, user, host);
+    if (constParent  &&  CFDictionaryContainsKey(constParent, childName)) {
+        CFStringRef topKey;
+        CFMutableDictionaryRef topValue;
+        CFMutableDictionaryRef parent;
+
+        parent = copyMutableNode(parentName, name, user, host,
+                                 &topKey, &topValue);
+        throwIfNull(parent, "copyMutableNode failed");
+
+        CFDictionaryRemoveValue(parent, childName);
+        CFPreferencesSetValue(topKey, topValue, name, user, host);
+
+        CFRelease(parent);
+        if (topKey) CFRelease(topKey);
+        if (topValue) CFRelease(topValue);
+    } else {
+        // might be trying to remove the root itself in a non-root file
+        CFStringRef topKey;
+        CFDictionaryRef topValue;
+        copyTreeForPath(path, name, user, host, &topKey, &topValue);
+        if (topKey) {
+            if (CFEqual(topKey, path)) {
+                CFPreferencesSetValue(topKey, NULL, name, user, host);
+            }
+
+            if (topKey) CFRelease(topKey);
+            if (topValue) CFRelease(topValue);
+        }
+    }
+
+
+ badparent:
+    if (constParent) CFRelease(constParent);
+    CFRelease(childName);
+ badchildName:
+    CFRelease(parentName);
+ badparentName:
+ badparams:
+    if (path) CFRelease(path);
+    if (name) CFRelease(name);
+}
+
+
+// child must end with '/'
+JNIEXPORT Boolean JNICALL
+Java_java_util_prefs_MacOSXPreferencesFile_addChildToNode
+(JNIEnv *env, jobject klass, jobject jpath, jobject jchild,
+ jobject jname, jlong juser, jlong jhost)
+{
+    // like addNode, but can put a three-level-deep dict into the root file
+    CFStringRef path = toCF(env, jpath);
+    CFStringRef child = toCF(env, jchild);
+    CFStringRef name = toCF(env, jname);
+    CFStringRef user = (CFStringRef)jlong_to_ptr(juser);
+    CFStringRef host = (CFStringRef)jlong_to_ptr(jhost);
+    CFMutableDictionaryRef parent;
+    CFDictionaryRef node;
+    CFStringRef topKey;
+    CFMutableDictionaryRef topValue;
+    Boolean beforeAdd = false;
+
+    if (!path  ||  !child  ||  !name) goto badparams;
+
+    node = createEmptyNode();
+    throwIfNull(node, "createEmptyNode failed");
+
+    // copyMutableNode creates the node if necessary
+    parent = copyMutableNode(path, name, user, host, &topKey, &topValue);
+    throwIfNull(parent, "copyMutableNode failed");
+    beforeAdd = CFDictionaryContainsKey(parent, child);
+    CFDictionaryAddValue(parent, child, node);
+    if (!beforeAdd)
+        beforeAdd = CFDictionaryContainsKey(parent, child);
+    else
+        beforeAdd = false;
+    CFPreferencesSetValue(topKey, topValue, name, user, host);
+
+    CFRelease(parent);
+    if (topKey) CFRelease(topKey);
+    if (topValue) CFRelease(topValue);
+ badparent:
+    CFRelease(node);
+ badnode:
+ badparams:
+    if (path) CFRelease(path);
+    if (child) CFRelease(child);
+    if (name) CFRelease(name);
+    return beforeAdd;
+}
+
+
+JNIEXPORT void JNICALL
+Java_java_util_prefs_MacOSXPreferencesFile_removeChildFromNode
+(JNIEnv *env, jobject klass, jobject jpath, jobject jchild,
+ jobject jname, jlong juser, jlong jhost)
+{
+    CFStringRef path = toCF(env, jpath);
+    CFStringRef child = toCF(env, jchild);
+    CFStringRef name = toCF(env, jname);
+    CFStringRef user = (CFStringRef)jlong_to_ptr(juser);
+    CFStringRef host = (CFStringRef)jlong_to_ptr(jhost);
+    CFDictionaryRef constParent;
+
+    if (!path  ||  !child  ||  !name) goto badparams;
+
+    constParent = copyNodeIfPresent(path, name, user, host);
+    if (constParent  &&  CFDictionaryContainsKey(constParent, child)) {
+        CFStringRef topKey;
+        CFMutableDictionaryRef topValue;
+        CFMutableDictionaryRef parent;
+
+        parent = copyMutableNode(path, name, user, host, &topKey, &topValue);
+        throwIfNull(parent, "copyMutableNode failed");
+
+        CFDictionaryRemoveValue(parent, child);
+        CFPreferencesSetValue(topKey, topValue, name, user, host);
+
+        CFRelease(parent);
+        if (topKey) CFRelease(topKey);
+        if (topValue) CFRelease(topValue);
+    }
+
+ badparent:
+    if (constParent) CFRelease(constParent);
+ badparams:
+    if (path) CFRelease(path);
+    if (child) CFRelease(child);
+    if (name) CFRelease(name);
+}
+
+
+
+JNIEXPORT void JNICALL
+Java_java_util_prefs_MacOSXPreferencesFile_addKeyToNode
+(JNIEnv *env, jobject klass, jobject jpath, jobject jkey, jobject jvalue,
+ jobject jname, jlong juser, jlong jhost)
+{
+    CFStringRef path = toCF(env, jpath);
+    CFStringRef key = toCF(env, jkey);
+    CFStringRef value = toCF(env, jvalue);
+    CFStringRef name = toCF(env, jname);
+    CFStringRef user = (CFStringRef)jlong_to_ptr(juser);
+    CFStringRef host = (CFStringRef)jlong_to_ptr(jhost);
+    CFMutableDictionaryRef node = NULL;
+    CFStringRef topKey;
+    CFMutableDictionaryRef topValue;
+
+    if (!path  ||  !key  || !value  ||  !name) goto badparams;
+
+    // fixme optimization: check whether old value and new value are identical
+    node = copyMutableNode(path, name, user, host, &topKey, &topValue);
+    throwIfNull(node, "copyMutableNode failed");
+
+    CFDictionarySetValue(node, key, value);
+    CFPreferencesSetValue(topKey, topValue, name, user, host);
+
+    CFRelease(node);
+    if (topKey) CFRelease(topKey);
+    if (topValue) CFRelease(topValue);
+
+ badnode:
+ badparams:
+    if (path) CFRelease(path);
+    if (key) CFRelease(key);
+    if (value) CFRelease(value);
+    if (name) CFRelease(name);
+}
+
+
+JNIEXPORT void JNICALL
+Java_java_util_prefs_MacOSXPreferencesFile_removeKeyFromNode
+(JNIEnv *env, jobject klass, jobject jpath, jobject jkey,
+ jobject jname, jlong juser, jlong jhost)
+{
+    CFStringRef path = toCF(env, jpath);
+    CFStringRef key = toCF(env, jkey);
+    CFStringRef name = toCF(env, jname);
+    CFStringRef user = (CFStringRef)jlong_to_ptr(juser);
+    CFStringRef host = (CFStringRef)jlong_to_ptr(jhost);
+    CFDictionaryRef constNode;
+
+    if (!path  ||  !key  ||  !name) goto badparams;
+
+    constNode = copyNodeIfPresent(path, name, user, host);
+    if (constNode  &&  CFDictionaryContainsKey(constNode, key)) {
+        CFStringRef topKey;
+        CFMutableDictionaryRef topValue;
+        CFMutableDictionaryRef node;
+
+        node = copyMutableNode(path, name, user, host, &topKey, &topValue);
+        throwIfNull(node, "copyMutableNode failed");
+
+        CFDictionaryRemoveValue(node, key);
+        CFPreferencesSetValue(topKey, topValue, name, user, host);
+
+        CFRelease(node);
+        if (topKey) CFRelease(topKey);
+        if (topValue) CFRelease(topValue);
+    }
+
+ badnode:
+    if (constNode) CFRelease(constNode);
+ badparams:
+    if (path) CFRelease(path);
+    if (key) CFRelease(key);
+    if (name) CFRelease(name);
+}
+
+
+// path must end in '/'
+JNIEXPORT jstring JNICALL
+Java_java_util_prefs_MacOSXPreferencesFile_getKeyFromNode
+(JNIEnv *env, jobject klass, jobject jpath, jobject jkey,
+ jobject jname, jlong juser, jlong jhost)
+{
+    CFStringRef path = toCF(env, jpath);
+    CFStringRef key = toCF(env, jkey);
+    CFStringRef name = toCF(env, jname);
+    CFStringRef user = (CFStringRef)jlong_to_ptr(juser);
+    CFStringRef host = (CFStringRef)jlong_to_ptr(jhost);
+    CFPropertyListRef value;
+    CFDictionaryRef node;
+    jstring result = NULL;
+
+    if (!path  ||  !key  ||  !name) goto badparams;
+
+    node = copyNodeIfPresent(path, name, user, host);
+    if (node) {
+        value = (CFPropertyListRef)CFDictionaryGetValue(node, key);
+        if (!value) {
+            // key doesn't exist, or other error - no Java errors available
+            result = NULL;
+        } else {
+            CFStringRef cfString = copyToCFString(env, value);
+            if ((*env)->ExceptionOccurred(env)) {
+                // memory error in copyToCFString
+                result = NULL;
+            } else if (cfString == NULL) {
+                // bogus value type in prefs file - no Java errors available
+                result = NULL;
+            } else {
+                // good cfString
+                result = toJavaString(env, cfString);
+                CFRelease(cfString);
+            }
+        }
+        CFRelease(node);
+    }
+
+ badparams:
+    if (path) CFRelease(path);
+    if (key) CFRelease(key);
+    if (name) CFRelease(name);
+
+    return result;
+}
+
+
+typedef struct {
+    jarray result;
+    JNIEnv *env;
+    CFIndex used;
+    Boolean allowSlash;
+} BuildJavaArrayArgs;
+
+// CFDictionary applier function that builds an array of Java strings
+//   from a CFDictionary of CFPropertyListRefs.
+// If args->allowSlash, only strings that end in '/' are added to the array,
+//   with the slash removed. Otherwise, only strings that do not end in '/'
+//   are added.
+// args->result must already exist and be large enough to hold all
+//   strings from the dictionary.
+// After complete application, args->result may not be full because
+//   some of the dictionary values weren't convertible to string. In
+//   this case, args->used will be the count of used elements.
+static void BuildJavaArrayFn(const void *key, const void *value, void *context)
+{
+    BuildJavaArrayArgs *args = (BuildJavaArrayArgs *)context;
+    CFPropertyListRef propkey = (CFPropertyListRef)key;
+    CFStringRef cfString = NULL;
+    JNIEnv *env = args->env;
+
+    if ((*env)->ExceptionOccurred(env)) return; // already failed
+
+    cfString = copyToCFString(env, propkey);
+    if ((*env)->ExceptionOccurred(env)) {
+        // memory error in copyToCFString
+    } else if (!cfString) {
+        // bogus value type in prefs file - no Java errors available
+    } else if (args->allowSlash != CFStringHasSuffix(cfString, CFSTR("/"))) {
+        // wrong suffix - ignore
+    } else {
+        // good cfString
+        jstring javaString;
+        if (args->allowSlash) {
+            CFRange range = CFRangeMake(0, CFStringGetLength(cfString) - 1);
+            CFStringRef s = CFStringCreateWithSubstring(NULL, cfString, range);
+            CFRelease(cfString);
+            cfString = s;
+        }
+        if (CFStringGetLength(cfString) <= 0) goto bad; // ignore empty
+        javaString = toJavaString(env, cfString);
+        if ((*env)->ExceptionOccurred(env)) goto bad;
+        (*env)->SetObjectArrayElement(env, args->result,args->used,javaString);
+        if ((*env)->ExceptionOccurred(env)) goto bad;
+        args->used++;
+    }
+
+ bad:
+    if (cfString) CFRelease(cfString);
+}
+
+
+static jarray getStringsForNode(JNIEnv *env, jobject klass, jobject jpath,
+                                jobject jname, jlong juser, jlong jhost,
+                                Boolean allowSlash)
+{
+    CFStringRef path = toCF(env, jpath);
+    CFStringRef name = toCF(env, jname);
+    CFStringRef user = (CFStringRef)jlong_to_ptr(juser);
+    CFStringRef host = (CFStringRef)jlong_to_ptr(jhost);
+    CFDictionaryRef node;
+    jarray result = NULL;
+    CFIndex count;
+
+    if (!path  ||  !name) goto badparams;
+
+    node = copyNodeIfPresent(path, name, user, host);
+    if (!node) {
+        result = createJavaStringArray(env, 0);
+    } else {
+        count = CFDictionaryGetCount(node);
+        result = createJavaStringArray(env, count);
+        if (result) {
+            BuildJavaArrayArgs args;
+            args.result = result;
+            args.env = env;
+            args.used = 0;
+            args.allowSlash = allowSlash;
+            CFDictionaryApplyFunction(node, BuildJavaArrayFn, &args);
+            if (!(*env)->ExceptionOccurred(env)) {
+                // array construction succeeded
+                if (args.used < count) {
+                    // finished array is smaller than expected.
+                    // Make a new array of precisely the right size.
+                    jarray newresult = createJavaStringArray(env, args.used);
+                    if (newresult) {
+                        JVM_ArrayCopy(env,0, result,0, newresult,0, args.used);
+                        result = newresult;
+                    }
+                }
+            }
+        }
+
+        CFRelease(node);
+    }
+
+ badparams:
+    if (path) CFRelease(path);
+    if (name) CFRelease(name);
+
+    return result;
+}
+
+
+JNIEXPORT jarray JNICALL
+Java_java_util_prefs_MacOSXPreferencesFile_getKeysForNode
+(JNIEnv *env, jobject klass, jobject jpath,
+ jobject jname, jlong juser, jlong jhost)
+{
+    return getStringsForNode(env, klass, jpath, jname, juser, jhost, false);
+}
+
+JNIEXPORT jarray JNICALL
+Java_java_util_prefs_MacOSXPreferencesFile_getChildrenForNode
+(JNIEnv *env, jobject klass, jobject jpath,
+ jobject jname, jlong juser, jlong jhost)
+{
+    return getStringsForNode(env, klass, jpath, jname, juser, jhost, true);
+}
+
+
+// Returns false on error instead of throwing.
+JNIEXPORT jboolean JNICALL
+Java_java_util_prefs_MacOSXPreferencesFile_synchronize
+(JNIEnv *env, jobject klass,
+ jstring jname, jlong juser, jlong jhost)
+{
+    CFStringRef name = toCF(env, jname);
+    CFStringRef user = (CFStringRef)jlong_to_ptr(juser);
+    CFStringRef host = (CFStringRef)jlong_to_ptr(jhost);
+    jboolean result = 0;
+
+    if (name) {
+        result = CFPreferencesSynchronize(name, user, host);
+        CFRelease(name);
+    }
+
+    return result;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/macosx/native/sun/security/krb5/SCDynamicStoreConfig.m	Tue Feb 11 09:59:34 2014 +0000
@@ -0,0 +1,222 @@
+/*
+ * Copyright (c) 2011, 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.
+ */
+
+#import <Cocoa/Cocoa.h>
+#import <JavaNativeFoundation/JavaNativeFoundation.h>
+#import <SystemConfiguration/SystemConfiguration.h>
+
+
+@interface JNFVectorCoercion : NSObject <JNFTypeCoercion> { }
+@end
+
+@implementation JNFVectorCoercion
+
+- (jobject) coerceNSObject:(id)obj withEnv:(JNIEnv *)env usingCoercer:(JNFTypeCoercion *)coercer {
+    static JNF_CLASS_CACHE(jc_Vector, "java/util/Vector");
+    static JNF_CTOR_CACHE(jm_Vector_ctor, jc_Vector, "(I)V");
+    static JNF_MEMBER_CACHE(jm_Vector_add, jc_Vector, "add", "(Ljava/lang/Object;)Z");
+
+    NSArray *nsArray = (NSArray *)obj;
+    jobject javaArray = JNFNewObject(env, jm_Vector_ctor, (jint)[nsArray count]);
+
+    for (id obj in nsArray) {
+        jobject jobj = [coercer coerceNSObject:obj withEnv:env usingCoercer:coercer];
+        JNFCallBooleanMethod(env, javaArray, jm_Vector_add, jobj);
+        if (jobj != NULL) (*env)->DeleteLocalRef(env, jobj);
+    }
+
+    return javaArray;
+}
+
+- (id) coerceJavaObject:(jobject)obj withEnv:(JNIEnv *)env usingCoercer:(JNFTypeCoercion *)coercer {
+    return nil;
+}
+
+@end
+
+
+@interface JNFHashtableCoercion : NSObject <JNFTypeCoercion> { }
+@end
+
+@implementation JNFHashtableCoercion
+
+- (jobject) coerceNSObject:(id)obj withEnv:(JNIEnv *)env usingCoercer:(JNFTypeCoercion *)coercer {
+    static JNF_CLASS_CACHE(jc_Hashtable, "java/util/Hashtable");
+    static JNF_CTOR_CACHE(jm_Hashtable_ctor, jc_Hashtable, "()V");
+    static JNF_MEMBER_CACHE(jm_Hashtable_put, jc_Hashtable, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
+
+    NSDictionary *nsDict = (NSDictionary *)obj;
+    NSEnumerator *keyEnum = [nsDict keyEnumerator];
+
+    jobject jHashTable = JNFNewObject(env, jm_Hashtable_ctor);
+
+    id key = nil;
+    while ((key = [keyEnum nextObject]) != nil) {
+        jobject jkey = [coercer coerceNSObject:key withEnv:env usingCoercer:coercer];
+
+        id value = [nsDict objectForKey:key];
+        jobject jvalue = [coercer coerceNSObject:value withEnv:env usingCoercer:coercer];
+
+        JNFCallObjectMethod(env, jHashTable, jm_Hashtable_put, jkey, jvalue);
+
+        if (jkey != NULL) (*env)->DeleteLocalRef(env, jkey);
+        if (jvalue != NULL) (*env)->DeleteLocalRef(env, jvalue);
+    }
+
+    return jHashTable;
+}
+
+- (id) coerceJavaObject:(jobject)obj withEnv:(JNIEnv *)env usingCoercer:(JNFTypeCoercion *)coercer {
+    return nil;
+}
+
+@end
+
+
+
+NSDictionary *realmConfigsForRealms(SCDynamicStoreRef store, NSArray *realms) {
+    NSMutableDictionary *dict = [NSMutableDictionary dictionary];
+
+    for (NSString *realm in realms) {
+        CFTypeRef realmInfo = SCDynamicStoreCopyValue(store, (CFStringRef) [NSString stringWithFormat:@"Kerberos:%@", realm]);
+
+        if (CFGetTypeID(realmInfo) != CFDictionaryGetTypeID()) {
+            return nil;
+        }
+
+        [dict setObject:(NSArray *)realmInfo forKey:realm];
+        CFRelease(realmInfo);
+    }
+
+    return dict;
+}
+
+
+#define KERBEROS_DEFAULT_REALMS @"Kerberos-Default-Realms"
+#define KERBEROS_DEFAULT_REALM_MAPPINGS @"Kerberos-Domain-Realm-Mappings"
+
+void _SCDynamicStoreCallBack(SCDynamicStoreRef store, CFArrayRef changedKeys, void *info) {
+   NSArray *keys = (NSArray *)changedKeys;
+    if ([keys count] == 0) return;
+    if (![keys containsObject:KERBEROS_DEFAULT_REALMS] && ![keys containsObject:KERBEROS_DEFAULT_REALM_MAPPINGS]) return;
+
+    JNFPerformEnvBlock(JNFThreadDetachOnThreadDeath | JNFThreadSetSystemClassLoaderOnAttach | JNFThreadAttachAsDaemon, ^(JNIEnv *env) {
+        static JNF_CLASS_CACHE(jc_Config, "sun/security/krb5/Config");
+        static JNF_STATIC_MEMBER_CACHE(jm_Config_refresh, jc_Config, "refresh", "()V");
+        JNFCallStaticVoidMethod(env, jm_Config_refresh);
+    });
+}
+
+/*
+ * Class:     sun_security_krb5_SCDynamicStoreConfig
+ * Method:    installNotificationCallback
+ */
+JNIEXPORT void JNICALL Java_sun_security_krb5_SCDynamicStoreConfig_installNotificationCallback(JNIEnv *env, jclass klass) {
+
+JNF_COCOA_ENTER(env);
+
+    SCDynamicStoreRef store = SCDynamicStoreCreate(NULL, CFSTR("java"), _SCDynamicStoreCallBack, NULL);
+    if (store == NULL) {
+        return;
+    }
+
+    NSArray *keys = [NSArray arrayWithObjects:KERBEROS_DEFAULT_REALMS, KERBEROS_DEFAULT_REALM_MAPPINGS, nil];
+    SCDynamicStoreSetNotificationKeys(store, (CFArrayRef) keys, NULL);
+
+    CFRunLoopSourceRef rls = SCDynamicStoreCreateRunLoopSource(NULL, store, 0);
+    if (rls != NULL) {
+        CFRunLoopAddSource(CFRunLoopGetMain(), rls, kCFRunLoopDefaultMode);
+        CFRelease(rls);
+    }
+
+    CFRelease(store);
+
+JNF_COCOA_EXIT(env);
+
+}
+
+/*
+ * Class:     sun_security_krb5_SCDynamicStoreConfig
+ * Method:    getKerberosConfig
+ * Signature: ()Ljava/util/Hashtable;
+ */
+JNIEXPORT jobject JNICALL Java_sun_security_krb5_SCDynamicStoreConfig_getKerberosConfig(JNIEnv *env, jclass klass) {
+    jobject jHashTable = NULL;
+
+JNF_COCOA_ENTER(env);
+
+    SCDynamicStoreRef store = SCDynamicStoreCreate(NULL, CFSTR("java-kerberos"), NULL, NULL);
+    if (store == NULL) {
+        return NULL;
+    }
+
+    CFTypeRef realms = SCDynamicStoreCopyValue(store, (CFStringRef) KERBEROS_DEFAULT_REALMS);
+    if (realms == NULL || CFGetTypeID(realms) != CFArrayGetTypeID()) {
+        if (realms) CFRelease(realms);
+        CFRelease(store);
+        return NULL;
+    }
+
+    CFTypeRef realmMappings = SCDynamicStoreCopyValue(store, (CFStringRef) KERBEROS_DEFAULT_REALM_MAPPINGS);
+
+    if (realmMappings == NULL || CFGetTypeID(realmMappings) != CFArrayGetTypeID()) {
+        if (realmMappings) CFRelease(realmMappings);
+        CFRelease(realms);
+        CFRelease(store);
+        return NULL;
+    }
+
+    NSMutableDictionary *dict = [NSMutableDictionary dictionary];
+
+    if (CFArrayGetCount(realms) > 0) {
+        NSDictionary *defaultRealmsDict = [NSDictionary dictionaryWithObject:[(NSArray *)realms objectAtIndex:0] forKey:@"default_realm"];
+        [dict setObject:defaultRealmsDict forKey:@"libdefaults"];
+
+        NSDictionary *realmConfigs = realmConfigsForRealms(store, (NSArray *)realms);
+        [dict setObject:realmConfigs forKey:@"realms"];
+    }
+    CFRelease(realms);
+    CFRelease(store);
+
+    if (CFArrayGetCount(realmMappings) > 0) {
+        [dict setObject:[(NSArray *)realmMappings objectAtIndex:0] forKey:@"domain_realm"];
+    }
+    CFRelease(realmMappings);
+
+
+    // create and load a coercer with all of the different coercions to convert each type of object
+    JNFTypeCoercer *coercer = [[[JNFTypeCoercer alloc] init] autorelease];
+    [JNFDefaultCoercions addStringCoercionTo:coercer];
+    [JNFDefaultCoercions addNumberCoercionTo:coercer];
+    [coercer addCoercion:[[[JNFHashtableCoercion alloc] init] autorelease] forNSClass:[NSDictionary class] javaClass:@"java/util/Map"];
+    [coercer addCoercion:[[[JNFVectorCoercion alloc] init] autorelease] forNSClass:[NSArray class] javaClass:@"java/util/List"];
+
+    // convert Cocoa graph to Java graph
+    jHashTable = [coercer coerceNSObject:dict withEnv:env];
+
+JNF_COCOA_EXIT(env);
+
+    return jHashTable;
+}
--- a/src/share/classes/java/util/logging/FileHandler.java	Mon Feb 10 18:09:40 2014 -0800
+++ b/src/share/classes/java/util/logging/FileHandler.java	Tue Feb 11 09:59:34 2014 +0000
@@ -535,7 +535,7 @@
                     continue;
                 } else if (ch2 == 'h') {
                     file = new File(System.getProperty("user.home"));
-                    if (isSetUID()) {
+                    if (sun.misc.VM.isSetUID()) {
                         // Ok, we are in a set UID program.  For safety's sake
                         // we disallow attempts to open files relative to %h.
                         throw new IOException("can't use %h in set UID program");
@@ -669,9 +669,4 @@
             lastException = ex;
         }
     }
-
-    /**
-     * check if we are in a set UID program.
-     */
-    private static native boolean isSetUID();
 }
--- a/src/share/classes/sun/misc/VM.java	Mon Feb 10 18:09:40 2014 -0800
+++ b/src/share/classes/sun/misc/VM.java	Tue Feb 11 09:59:34 2014 +0000
@@ -367,6 +367,11 @@
      */
     public static native ClassLoader latestUserDefinedLoader();
 
+    /**
+     * Returns {@code true} if we are in a set UID program.
+     */
+    public static native boolean isSetUID();
+
     static {
         initialize();
     }
--- a/src/share/classes/sun/security/krb5/SCDynamicStoreConfig.java	Mon Feb 10 18:09:40 2014 -0800
+++ b/src/share/classes/sun/security/krb5/SCDynamicStoreConfig.java	Tue Feb 11 09:59:34 2014 +0000
@@ -42,7 +42,7 @@
                 public Boolean run() {
                     String osname = System.getProperty("os.name");
                     if (osname.contains("OS X")) {
-                        System.loadLibrary("osx");
+                        System.loadLibrary("osxkrb5");
                         return true;
                     }
                     return false;
--- a/src/solaris/classes/java/util/prefs/FileSystemPreferences.java	Mon Feb 10 18:09:40 2014 -0800
+++ b/src/solaris/classes/java/util/prefs/FileSystemPreferences.java	Tue Feb 11 09:59:34 2014 +0000
@@ -48,6 +48,15 @@
  * @since   1.4
  */
 class FileSystemPreferences extends AbstractPreferences {
+
+    static {
+        PrivilegedAction<Void> load = () -> {
+            System.loadLibrary("prefs");
+            return null;
+        };
+        AccessController.doPrivileged(load);
+    }
+
     /**
      * Sync interval in seconds.
      */
@@ -868,7 +877,7 @@
 
     /**
      * Returns the node name corresponding to the specified directory name.
- * (Inverts the transformation of dirName(String).
+     * (Inverts the transformation of dirName(String).
      */
     private static String nodeName(String dirName) {
         if (dirName.charAt(0) != '_')
--- a/src/solaris/native/java/util/FileSystemPreferences.c	Mon Feb 10 18:09:40 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,147 +0,0 @@
-/*
- * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * Solaris/Linux platform specific code to support the Prefs API.
- */
-
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <utime.h>
-#include "jni_util.h"
-
-JNIEXPORT jint JNICALL
-Java_java_util_prefs_FileSystemPreferences_chmod(JNIEnv *env,
-                       jclass thisclass, jstring java_fname, jint permission) {
-    const char *fname = JNU_GetStringPlatformChars(env, java_fname, NULL);
-    int result = -1;
-    if (fname) {
-        result =  chmod(fname, permission);
-        if (result != 0)
-            result = errno;
-        JNU_ReleaseStringPlatformChars(env, java_fname, fname);
-    }
-    return (jint) result;
-}
-
-#if defined(_ALLBSD_SOURCE)
-typedef struct flock FLOCK;
-#else
-typedef struct flock64 FLOCK;
-#endif
-
-/**
- * Try to open a named lock file.
- * The result is a cookie that can be used later to unlock the file.
- * On failure the result is zero.
- */
-JNIEXPORT jintArray JNICALL
-Java_java_util_prefs_FileSystemPreferences_lockFile0(JNIEnv *env,
-    jclass thisclass, jstring java_fname, jint permission, jboolean shared) {
-    const char *fname = JNU_GetStringPlatformChars(env, java_fname, NULL);
-    int fd, rc;
-    int result[2];
-    jintArray javaResult = NULL;
-    int old_umask;
-    FLOCK fl;
-
-    if (!fname)
-        return javaResult;
-
-    fl.l_whence = SEEK_SET;
-    fl.l_len = 0;
-    fl.l_start = 0;
-    if (shared == JNI_TRUE) {
-        fl.l_type = F_RDLCK;
-    } else {
-        fl.l_type = F_WRLCK;
-    }
-
-    if (shared == JNI_TRUE) {
-        fd = open(fname, O_RDONLY, 0);
-    } else {
-        old_umask = umask(0);
-        fd = open(fname, O_WRONLY|O_CREAT, permission);
-        result[1] = errno;
-        umask(old_umask);
-    }
-
-    if (fd < 0) {
-        result[0] = 0;
-    } else {
-#if defined(_ALLBSD_SOURCE)
-        rc = fcntl(fd, F_SETLK, &fl);
-#else
-        rc = fcntl(fd, F_SETLK64, &fl);
-#endif
-        result[1] = errno;
-        if (rc < 0) {
-            result[0]= 0;
-            close(fd);
-        } else {
-          result[0] = fd;
-        }
-    }
-    JNU_ReleaseStringPlatformChars(env, java_fname, fname);
-    javaResult = (*env)->NewIntArray(env,2);
-    if (javaResult)
-        (*env)->SetIntArrayRegion(env, javaResult, 0, 2, result);
-    return javaResult;
-}
-
-
-/**
- * Try to unlock a lock file, using a cookie returned by lockFile.
- */
-JNIEXPORT jint JNICALL
-Java_java_util_prefs_FileSystemPreferences_unlockFile0(JNIEnv *env,
-                                      jclass thisclass, jint fd) {
-
-    int rc;
-    FLOCK fl;
-    fl.l_whence = SEEK_SET;
-    fl.l_len = 0;
-    fl.l_start = 0;
-    fl.l_type = F_UNLCK;
-
-#if defined(_ALLBSD_SOURCE)
-    rc = fcntl(fd, F_SETLK, &fl);
-#else
-    rc = fcntl(fd, F_SETLK64, &fl);
-#endif
-
-    if (rc < 0) {
-        close(fd);
-        return (jint)errno;
-    }
-    rc = close(fd);
-    if (rc < 0) {
-        return (jint) errno;
-    }
-    return 0;
-}
--- a/src/solaris/native/java/util/logging.c	Mon Feb 10 18:09:40 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,42 +0,0 @@
-/*
- * Copyright (c) 2001, 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.
- */
-
-/*
- * Solaris/Linux specific code to support logging.
- */
-
-#include <unistd.h>
-#include "jni_util.h"
-
-
-JNIEXPORT jboolean JNICALL
-Java_java_util_logging_FileHandler_isSetUID(JNIEnv *env, jclass thisclass) {
-
-    /* Return true if we are in a set UID or set GID process. */
-    if (getuid() != geteuid() || getgid() != getegid()) {
-        return JNI_TRUE;
-    }
-    return JNI_FALSE;
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/solaris/native/java/util/prefs/FileSystemPreferences.c	Tue Feb 11 09:59:34 2014 +0000
@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * Solaris/Linux platform specific code to support the Prefs API.
+ */
+
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <utime.h>
+#include "jni_util.h"
+
+JNIEXPORT jint JNICALL
+Java_java_util_prefs_FileSystemPreferences_chmod(JNIEnv *env,
+                       jclass thisclass, jstring java_fname, jint permission) {
+    const char *fname = JNU_GetStringPlatformChars(env, java_fname, NULL);
+    int result = -1;
+    if (fname) {
+        result =  chmod(fname, permission);
+        if (result != 0)
+            result = errno;
+        JNU_ReleaseStringPlatformChars(env, java_fname, fname);
+    }
+    return (jint) result;
+}
+
+#if defined(_ALLBSD_SOURCE)
+typedef struct flock FLOCK;
+#else
+typedef struct flock64 FLOCK;
+#endif
+
+/**
+ * Try to open a named lock file.
+ * The result is a cookie that can be used later to unlock the file.
+ * On failure the result is zero.
+ */
+JNIEXPORT jintArray JNICALL
+Java_java_util_prefs_FileSystemPreferences_lockFile0(JNIEnv *env,
+    jclass thisclass, jstring java_fname, jint permission, jboolean shared) {
+    const char *fname = JNU_GetStringPlatformChars(env, java_fname, NULL);
+    int fd, rc;
+    int result[2];
+    jintArray javaResult = NULL;
+    int old_umask;
+    FLOCK fl;
+
+    if (!fname)
+        return javaResult;
+
+    fl.l_whence = SEEK_SET;
+    fl.l_len = 0;
+    fl.l_start = 0;
+    if (shared == JNI_TRUE) {
+        fl.l_type = F_RDLCK;
+    } else {
+        fl.l_type = F_WRLCK;
+    }
+
+    if (shared == JNI_TRUE) {
+        fd = open(fname, O_RDONLY, 0);
+    } else {
+        old_umask = umask(0);
+        fd = open(fname, O_WRONLY|O_CREAT, permission);
+        result[1] = errno;
+        umask(old_umask);
+    }
+
+    if (fd < 0) {
+        result[0] = 0;
+    } else {
+#if defined(_ALLBSD_SOURCE)
+        rc = fcntl(fd, F_SETLK, &fl);
+#else
+        rc = fcntl(fd, F_SETLK64, &fl);
+#endif
+        result[1] = errno;
+        if (rc < 0) {
+            result[0]= 0;
+            close(fd);
+        } else {
+          result[0] = fd;
+        }
+    }
+    JNU_ReleaseStringPlatformChars(env, java_fname, fname);
+    javaResult = (*env)->NewIntArray(env,2);
+    if (javaResult)
+        (*env)->SetIntArrayRegion(env, javaResult, 0, 2, result);
+    return javaResult;
+}
+
+
+/**
+ * Try to unlock a lock file, using a cookie returned by lockFile.
+ */
+JNIEXPORT jint JNICALL
+Java_java_util_prefs_FileSystemPreferences_unlockFile0(JNIEnv *env,
+                                      jclass thisclass, jint fd) {
+
+    int rc;
+    FLOCK fl;
+    fl.l_whence = SEEK_SET;
+    fl.l_len = 0;
+    fl.l_start = 0;
+    fl.l_type = F_UNLCK;
+
+#if defined(_ALLBSD_SOURCE)
+    rc = fcntl(fd, F_SETLK, &fl);
+#else
+    rc = fcntl(fd, F_SETLK64, &fl);
+#endif
+
+    if (rc < 0) {
+        close(fd);
+        return (jint)errno;
+    }
+    rc = close(fd);
+    if (rc < 0) {
+        return (jint) errno;
+    }
+    return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/solaris/native/sun/misc/VM_md.c	Tue Feb 11 09:59:34 2014 +0000
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2001, 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 <unistd.h>
+#include "jni_util.h"
+
+
+JNIEXPORT jboolean JNICALL
+Java_sun_misc_VM_isSetUID(JNIEnv *env, jclass thisclass) {
+
+    /* Return true if we are in a set UID or set GID process. */
+    if (getuid() != geteuid() || getgid() != getegid()) {
+        return JNI_TRUE;
+    }
+    return JNI_FALSE;
+}
--- a/src/windows/classes/java/util/prefs/WindowsPreferences.java	Mon Feb 10 18:09:40 2014 -0800
+++ b/src/windows/classes/java/util/prefs/WindowsPreferences.java	Tue Feb 11 09:59:34 2014 +0000
@@ -29,6 +29,9 @@
 import java.util.TreeMap;
 import java.util.StringTokenizer;
 import java.io.ByteArrayOutputStream;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
 import sun.util.logging.PlatformLogger;
 
 /**
@@ -45,6 +48,14 @@
 
 class WindowsPreferences extends AbstractPreferences{
 
+    static {
+        PrivilegedAction<Void> load = () -> {
+            System.loadLibrary("prefs");
+            return null;
+        };
+        AccessController.doPrivileged(load);
+    }
+
     /**
      * Logger for error messages
      */
--- a/src/windows/native/java/util/WindowsPreferences.c	Mon Feb 10 18:09:40 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,219 +0,0 @@
-/*
- * 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 <stdlib.h>
-#include <jni.h>
-#include <windows.h>
-#ifdef __cplusplus
-extern "C" {
-#endif
-    JNIEXPORT jintArray JNICALL Java_java_util_prefs_WindowsPreferences_WindowsRegOpenKey
-               (JNIEnv* env, jclass this_class, jint hKey, jbyteArray lpSubKey, jint securityMask) {
-        HKEY handle;
-        char* str;
-        int tmp[2];
-        int errorCode=-1;
-        jintArray result;
-        str = (*env)->GetByteArrayElements(env, lpSubKey, NULL);
-        errorCode =  RegOpenKeyEx((HKEY)hKey, str, 0, securityMask, &handle);
-        (*env)->ReleaseByteArrayElements(env, lpSubKey, str, 0);
-        tmp[0]= (int) handle;
-        tmp[1]= errorCode;
-        result = (*env)->NewIntArray(env,2);
-        (*env)->SetIntArrayRegion(env, result, 0, 2, tmp);
-        return result;
-    }
-
-    JNIEXPORT jint JNICALL Java_java_util_prefs_WindowsPreferences_WindowsRegCloseKey
-               (JNIEnv* env, jclass this_class, jint hKey) {
-        return (jint) RegCloseKey((HKEY) hKey);
-    };
-
-    JNIEXPORT jintArray JNICALL Java_java_util_prefs_WindowsPreferences_WindowsRegCreateKeyEx
-               (JNIEnv* env, jclass this_class, jint hKey, jbyteArray lpSubKey) {
-        HKEY handle;
-        char* str;
-        int tmp[3];
-        DWORD lpdwDisposition;
-        int errorCode;
-        jintArray result;
-        str = (*env)->GetByteArrayElements(env, lpSubKey, NULL);
-        errorCode =  RegCreateKeyEx((HKEY)hKey, str, 0, NULL,
-                      REG_OPTION_NON_VOLATILE, KEY_READ,
-                      NULL, &handle, &lpdwDisposition);
-        (*env)->ReleaseByteArrayElements(env, lpSubKey, str, 0);
-        tmp[0]= (int) handle;
-        tmp[1]= errorCode;
-        tmp[2]= lpdwDisposition;
-        result = (*env)->NewIntArray(env,3);
-        (*env)->SetIntArrayRegion(env, result, 0, 3, tmp);
-        return result;
-    }
-
-    JNIEXPORT jint JNICALL Java_java_util_prefs_WindowsPreferences_WindowsRegDeleteKey
-              (JNIEnv* env, jclass this_class, jint hKey, jbyteArray lpSubKey) {
-        char* str;
-        int result;
-        str = (*env)->GetByteArrayElements(env, lpSubKey, NULL);
-        result = RegDeleteKey((HKEY)hKey, str);
-        (*env)->ReleaseByteArrayElements(env, lpSubKey, str, 0);
-        return  result;
-
-    };
-
-    JNIEXPORT jint JNICALL Java_java_util_prefs_WindowsPreferences_WindowsRegFlushKey
-        (JNIEnv* env, jclass this_class, jint hKey) {
-        return RegFlushKey ((HKEY)hKey);
-        }
-
-    JNIEXPORT jbyteArray JNICALL Java_java_util_prefs_WindowsPreferences_WindowsRegQueryValueEx
-         (JNIEnv* env, jclass this_class, jint hKey, jbyteArray valueName) {
-        char* valueNameStr;
-        char* buffer;
-        jbyteArray result;
-        DWORD valueType;
-        DWORD valueSize;
-        valueNameStr = (*env)->GetByteArrayElements(env, valueName, NULL);
-        if (RegQueryValueEx((HKEY)hKey, valueNameStr, NULL, &valueType, NULL,
-                                                 &valueSize) != ERROR_SUCCESS) {
-        (*env)->ReleaseByteArrayElements(env, valueName, valueNameStr, 0);
-        return NULL;
-        }
-
-        buffer = (char*)malloc(valueSize);
-
-        if (RegQueryValueEx((HKEY)hKey, valueNameStr, NULL, &valueType, buffer,
-            &valueSize) != ERROR_SUCCESS) {
-            free(buffer);
-            (*env)->ReleaseByteArrayElements(env, valueName, valueNameStr, 0);
-        return NULL;
-        }
-
-        if (valueType == REG_SZ) {
-        result = (*env)->NewByteArray(env, valueSize);
-        (*env)->SetByteArrayRegion(env, result, 0, valueSize, buffer);
-        } else {
-        result = NULL;
-        }
-        free(buffer);
-        (*env)->ReleaseByteArrayElements(env, valueName, valueNameStr, 0);
-        return result;
-    }
-
-
-
-
-    JNIEXPORT jint JNICALL Java_java_util_prefs_WindowsPreferences_WindowsRegSetValueEx
-    (JNIEnv* env, jclass this_class, jint hKey, jbyteArray valueName, jbyteArray data) {
-        char* valueNameStr;
-        char* dataStr;
-        int size = -1;
-        int nameSize = -1;
-        int error_code = -1;
-        if ((valueName == NULL)||(data == NULL)) {return -1;}
-        size = (*env)->GetArrayLength(env, data);
-        dataStr = (*env)->GetByteArrayElements(env, data, NULL);
-        valueNameStr = (*env)->GetByteArrayElements(env, valueName, NULL);
-        error_code = RegSetValueEx((HKEY)hKey, valueNameStr, 0,
-                                                        REG_SZ, dataStr, size);
-        (*env)->ReleaseByteArrayElements(env, data, dataStr, 0);
-        (*env)->ReleaseByteArrayElements(env, valueName, valueNameStr, 0);
-        return error_code;
-    }
-
-     JNIEXPORT jint JNICALL Java_java_util_prefs_WindowsPreferences_WindowsRegDeleteValue
-            (JNIEnv* env, jclass this_class, jint hKey, jbyteArray valueName) {
-        char* valueNameStr;
-        int error_code = -1;
-        if (valueName == NULL) {return -1;}
-        valueNameStr = (*env)->GetByteArrayElements(env, valueName, NULL);
-        error_code = RegDeleteValue((HKEY)hKey, valueNameStr);
-        (*env)->ReleaseByteArrayElements(env, valueName, valueNameStr, 0);
-        return error_code;
-     }
-
-    JNIEXPORT jintArray JNICALL Java_java_util_prefs_WindowsPreferences_WindowsRegQueryInfoKey
-                                  (JNIEnv* env, jclass this_class, jint hKey) {
-        jintArray result;
-        int tmp[5];
-        int valuesNumber = -1;
-        int maxValueNameLength = -1;
-        int maxSubKeyLength = -1;
-        int subKeysNumber = -1;
-        int errorCode = -1;
-        errorCode = RegQueryInfoKey((HKEY)hKey, NULL, NULL, NULL,
-                 &subKeysNumber, &maxSubKeyLength, NULL,
-                 &valuesNumber, &maxValueNameLength,
-                 NULL, NULL, NULL);
-        tmp[0]= subKeysNumber;
-        tmp[1]= (int)errorCode;
-        tmp[2]= valuesNumber;
-        tmp[3]= maxSubKeyLength;
-        tmp[4]= maxValueNameLength;
-        result = (*env)->NewIntArray(env,5);
-        (*env)->SetIntArrayRegion(env, result, 0, 5, tmp);
-        return result;
-    }
-
-     JNIEXPORT jbyteArray JNICALL Java_java_util_prefs_WindowsPreferences_WindowsRegEnumKeyEx
-     (JNIEnv* env, jclass this_class, jint hKey , jint subKeyIndex, jint maxKeyLength) {
-        int size = maxKeyLength;
-        jbyteArray result;
-        char* buffer = NULL;
-        buffer = (char*)malloc(maxKeyLength);
-        if (RegEnumKeyEx((HKEY) hKey, subKeyIndex, buffer, &size, NULL, NULL,
-                                                 NULL, NULL) != ERROR_SUCCESS){
-        free(buffer);
-        return NULL;
-        }
-        result = (*env)->NewByteArray(env, size + 1);
-        (*env)->SetByteArrayRegion(env, result, 0, size + 1, buffer);
-        free(buffer);
-        return result;
-     }
-
-     JNIEXPORT jbyteArray JNICALL Java_java_util_prefs_WindowsPreferences_WindowsRegEnumValue
-          (JNIEnv* env, jclass this_class, jint hKey , jint valueIndex, jint maxValueNameLength){
-          int size = maxValueNameLength;
-          jbyteArray result;
-          char* buffer = NULL;
-          int error_code;
-          buffer = (char*)malloc(maxValueNameLength);
-          error_code = RegEnumValue((HKEY) hKey, valueIndex, buffer,
-                                             &size, NULL, NULL, NULL, NULL);
-          if (error_code!= ERROR_SUCCESS){
-            free(buffer);
-            return NULL;
-          }
-          result = (*env)->NewByteArray(env, size + 1);
-          (*env)->SetByteArrayRegion(env, result, 0, size + 1, buffer);
-          free(buffer);
-          return result;
-     }
-
-
-#ifdef __cplusplus
-}
-#endif
--- a/src/windows/native/java/util/logging.c	Mon Feb 10 18:09:40 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,38 +0,0 @@
-/*
- * Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * Win32 specific code to support logging.
- */
-
-#include "jni_util.h"
-
-
-JNIEXPORT jboolean JNICALL
-Java_java_util_logging_FileHandler_isSetUID(JNIEnv *env, jclass thisclass) {
-
-    /* There is no set UID on Windows. */
-    return JNI_FALSE;
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/windows/native/java/util/prefs/WindowsPreferences.c	Tue Feb 11 09:59:34 2014 +0000
@@ -0,0 +1,219 @@
+/*
+ * 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 <stdlib.h>
+#include <jni.h>
+#include <windows.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+    JNIEXPORT jintArray JNICALL Java_java_util_prefs_WindowsPreferences_WindowsRegOpenKey
+               (JNIEnv* env, jclass this_class, jint hKey, jbyteArray lpSubKey, jint securityMask) {
+        HKEY handle;
+        char* str;
+        int tmp[2];
+        int errorCode=-1;
+        jintArray result;
+        str = (*env)->GetByteArrayElements(env, lpSubKey, NULL);
+        errorCode =  RegOpenKeyEx((HKEY)hKey, str, 0, securityMask, &handle);
+        (*env)->ReleaseByteArrayElements(env, lpSubKey, str, 0);
+        tmp[0]= (int) handle;
+        tmp[1]= errorCode;
+        result = (*env)->NewIntArray(env,2);
+        (*env)->SetIntArrayRegion(env, result, 0, 2, tmp);
+        return result;
+    }
+
+    JNIEXPORT jint JNICALL Java_java_util_prefs_WindowsPreferences_WindowsRegCloseKey
+               (JNIEnv* env, jclass this_class, jint hKey) {
+        return (jint) RegCloseKey((HKEY) hKey);
+    };
+
+    JNIEXPORT jintArray JNICALL Java_java_util_prefs_WindowsPreferences_WindowsRegCreateKeyEx
+               (JNIEnv* env, jclass this_class, jint hKey, jbyteArray lpSubKey) {
+        HKEY handle;
+        char* str;
+        int tmp[3];
+        DWORD lpdwDisposition;
+        int errorCode;
+        jintArray result;
+        str = (*env)->GetByteArrayElements(env, lpSubKey, NULL);
+        errorCode =  RegCreateKeyEx((HKEY)hKey, str, 0, NULL,
+                      REG_OPTION_NON_VOLATILE, KEY_READ,
+                      NULL, &handle, &lpdwDisposition);
+        (*env)->ReleaseByteArrayElements(env, lpSubKey, str, 0);
+        tmp[0]= (int) handle;
+        tmp[1]= errorCode;
+        tmp[2]= lpdwDisposition;
+        result = (*env)->NewIntArray(env,3);
+        (*env)->SetIntArrayRegion(env, result, 0, 3, tmp);
+        return result;
+    }
+
+    JNIEXPORT jint JNICALL Java_java_util_prefs_WindowsPreferences_WindowsRegDeleteKey
+              (JNIEnv* env, jclass this_class, jint hKey, jbyteArray lpSubKey) {
+        char* str;
+        int result;
+        str = (*env)->GetByteArrayElements(env, lpSubKey, NULL);
+        result = RegDeleteKey((HKEY)hKey, str);
+        (*env)->ReleaseByteArrayElements(env, lpSubKey, str, 0);
+        return  result;
+
+    };
+
+    JNIEXPORT jint JNICALL Java_java_util_prefs_WindowsPreferences_WindowsRegFlushKey
+        (JNIEnv* env, jclass this_class, jint hKey) {
+        return RegFlushKey ((HKEY)hKey);
+        }
+
+    JNIEXPORT jbyteArray JNICALL Java_java_util_prefs_WindowsPreferences_WindowsRegQueryValueEx
+         (JNIEnv* env, jclass this_class, jint hKey, jbyteArray valueName) {
+        char* valueNameStr;
+        char* buffer;
+        jbyteArray result;
+        DWORD valueType;
+        DWORD valueSize;
+        valueNameStr = (*env)->GetByteArrayElements(env, valueName, NULL);
+        if (RegQueryValueEx((HKEY)hKey, valueNameStr, NULL, &valueType, NULL,
+                                                 &valueSize) != ERROR_SUCCESS) {
+        (*env)->ReleaseByteArrayElements(env, valueName, valueNameStr, 0);
+        return NULL;
+        }
+
+        buffer = (char*)malloc(valueSize);
+
+        if (RegQueryValueEx((HKEY)hKey, valueNameStr, NULL, &valueType, buffer,
+            &valueSize) != ERROR_SUCCESS) {
+            free(buffer);
+            (*env)->ReleaseByteArrayElements(env, valueName, valueNameStr, 0);
+        return NULL;
+        }
+
+        if (valueType == REG_SZ) {
+        result = (*env)->NewByteArray(env, valueSize);
+        (*env)->SetByteArrayRegion(env, result, 0, valueSize, buffer);
+        } else {
+        result = NULL;
+        }
+        free(buffer);
+        (*env)->ReleaseByteArrayElements(env, valueName, valueNameStr, 0);
+        return result;
+    }
+
+
+
+
+    JNIEXPORT jint JNICALL Java_java_util_prefs_WindowsPreferences_WindowsRegSetValueEx
+    (JNIEnv* env, jclass this_class, jint hKey, jbyteArray valueName, jbyteArray data) {
+        char* valueNameStr;
+        char* dataStr;
+        int size = -1;
+        int nameSize = -1;
+        int error_code = -1;
+        if ((valueName == NULL)||(data == NULL)) {return -1;}
+        size = (*env)->GetArrayLength(env, data);
+        dataStr = (*env)->GetByteArrayElements(env, data, NULL);
+        valueNameStr = (*env)->GetByteArrayElements(env, valueName, NULL);
+        error_code = RegSetValueEx((HKEY)hKey, valueNameStr, 0,
+                                                        REG_SZ, dataStr, size);
+        (*env)->ReleaseByteArrayElements(env, data, dataStr, 0);
+        (*env)->ReleaseByteArrayElements(env, valueName, valueNameStr, 0);
+        return error_code;
+    }
+
+     JNIEXPORT jint JNICALL Java_java_util_prefs_WindowsPreferences_WindowsRegDeleteValue
+            (JNIEnv* env, jclass this_class, jint hKey, jbyteArray valueName) {
+        char* valueNameStr;
+        int error_code = -1;
+        if (valueName == NULL) {return -1;}
+        valueNameStr = (*env)->GetByteArrayElements(env, valueName, NULL);
+        error_code = RegDeleteValue((HKEY)hKey, valueNameStr);
+        (*env)->ReleaseByteArrayElements(env, valueName, valueNameStr, 0);
+        return error_code;
+     }
+
+    JNIEXPORT jintArray JNICALL Java_java_util_prefs_WindowsPreferences_WindowsRegQueryInfoKey
+                                  (JNIEnv* env, jclass this_class, jint hKey) {
+        jintArray result;
+        int tmp[5];
+        int valuesNumber = -1;
+        int maxValueNameLength = -1;
+        int maxSubKeyLength = -1;
+        int subKeysNumber = -1;
+        int errorCode = -1;
+        errorCode = RegQueryInfoKey((HKEY)hKey, NULL, NULL, NULL,
+                 &subKeysNumber, &maxSubKeyLength, NULL,
+                 &valuesNumber, &maxValueNameLength,
+                 NULL, NULL, NULL);
+        tmp[0]= subKeysNumber;
+        tmp[1]= (int)errorCode;
+        tmp[2]= valuesNumber;
+        tmp[3]= maxSubKeyLength;
+        tmp[4]= maxValueNameLength;
+        result = (*env)->NewIntArray(env,5);
+        (*env)->SetIntArrayRegion(env, result, 0, 5, tmp);
+        return result;
+    }
+
+     JNIEXPORT jbyteArray JNICALL Java_java_util_prefs_WindowsPreferences_WindowsRegEnumKeyEx
+     (JNIEnv* env, jclass this_class, jint hKey , jint subKeyIndex, jint maxKeyLength) {
+        int size = maxKeyLength;
+        jbyteArray result;
+        char* buffer = NULL;
+        buffer = (char*)malloc(maxKeyLength);
+        if (RegEnumKeyEx((HKEY) hKey, subKeyIndex, buffer, &size, NULL, NULL,
+                                                 NULL, NULL) != ERROR_SUCCESS){
+        free(buffer);
+        return NULL;
+        }
+        result = (*env)->NewByteArray(env, size + 1);
+        (*env)->SetByteArrayRegion(env, result, 0, size + 1, buffer);
+        free(buffer);
+        return result;
+     }
+
+     JNIEXPORT jbyteArray JNICALL Java_java_util_prefs_WindowsPreferences_WindowsRegEnumValue
+          (JNIEnv* env, jclass this_class, jint hKey , jint valueIndex, jint maxValueNameLength){
+          int size = maxValueNameLength;
+          jbyteArray result;
+          char* buffer = NULL;
+          int error_code;
+          buffer = (char*)malloc(maxValueNameLength);
+          error_code = RegEnumValue((HKEY) hKey, valueIndex, buffer,
+                                             &size, NULL, NULL, NULL, NULL);
+          if (error_code!= ERROR_SUCCESS){
+            free(buffer);
+            return NULL;
+          }
+          result = (*env)->NewByteArray(env, size + 1);
+          (*env)->SetByteArrayRegion(env, result, 0, size + 1, buffer);
+          free(buffer);
+          return result;
+     }
+
+
+#ifdef __cplusplus
+}
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/windows/native/sun/misc/VM_md.c	Tue Feb 11 09:59:34 2014 +0000
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include "jni_util.h"
+
+
+JNIEXPORT jboolean JNICALL
+Java_sun_misc_VM_isSetUID(JNIEnv *env, jclass thisclass) {
+
+    /* There is no set UID on Windows. */
+    return JNI_FALSE;
+}