/*
 * Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please 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"
#include "java_util_prefs_MacOSXPreferencesFile.h"

/*
 * Declare library specific JNI_Onload entry if static build
 */
DEF_STATIC_JNI_OnLoad


// Throw an OutOfMemoryError with the given message.
static void throwOutOfMemoryError(JNIEnv *env, const char *msg)
{
    static jclass exceptionClass = NULL;
    jclass c;

    (*env)->ExceptionClear(env);  // If an exception is pending, clear it before
                                  // calling FindClass() and/or ThrowNew().
    if (exceptionClass) {
        c = exceptionClass;
    } else {
        c = (*env)->FindClass(env, "java/lang/OutOfMemoryError");
        if ((*env)->ExceptionCheck(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)->ExceptionCheck(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 = NULL;
    CFStringRef name = NULL;

    path = toCF(env, jpath);
    if (path != NULL) {
        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 = NULL;
    CFStringRef name = NULL;

    path = toCF(env, jpath);
    if (path != NULL) {
        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 jboolean 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 = NULL;
    CFStringRef child = NULL;
    CFStringRef name = NULL;

    path = toCF(env, jpath);
    if (path != NULL) {
        child = toCF(env, jchild);
    }
    if (child != NULL) {
        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;
    jboolean beforeAdd = JNI_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) ? JNI_TRUE : JNI_FALSE;
    CFDictionaryAddValue(parent, child, node);
    if (!beforeAdd)
        beforeAdd = CFDictionaryContainsKey(parent, child) ? JNI_TRUE : JNI_FALSE;
    else
        beforeAdd = JNI_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 = NULL;
    CFStringRef child = NULL;
    CFStringRef name = NULL;

    path = toCF(env, jpath);
    if (path != NULL) {
        child = toCF(env, jchild);
    }
    if (child != NULL) {
        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 = NULL;
    CFStringRef key = NULL;
    CFStringRef value = NULL;
    CFStringRef name = NULL;

    path = toCF(env, jpath);
    if (path != NULL) {
        key = toCF(env, jkey);
    }
    if (key != NULL) {
        value = toCF(env, jvalue);
    }
    if (value != NULL) {
        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 = NULL;
    CFStringRef key = NULL;
    CFStringRef name = NULL;

    path = toCF(env, jpath);
    if (path != NULL) {
        key = toCF(env, jkey);
    }
    if (key != NULL) {
        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 = NULL;
    CFStringRef key = NULL;
    CFStringRef name = NULL;

    path = toCF(env, jpath);
    if (path != NULL) {
        key = toCF(env, jkey);
    }
    if (key != NULL) {
        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)->ExceptionCheck(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)->ExceptionCheck(env)) return; // already failed

    cfString = copyToCFString(env, propkey);
    if ((*env)->ExceptionCheck(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)->ExceptionCheck(env)) goto bad;
        (*env)->SetObjectArrayElement(env, args->result,args->used,javaString);
        if ((*env)->ExceptionCheck(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 = NULL;
    CFStringRef name = NULL;

    path = toCF(env, jpath);
    if (path != NULL) {
        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)->ExceptionCheck(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;
}
