/*	CFApplicationPreferences.c
	Copyright (c) 1998-2016, Apple Inc. and the Swift project authors
 
	Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors
	Licensed under Apache License v2.0 with Runtime Library Exception
	See http://swift.org/LICENSE.txt for license information
	See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
	Responsibility: David Smith
*/

#include <CoreFoundation/CFPreferences.h>
#include "CFInternal.h"
#include <CoreFoundation/CFUniChar.h>
#include <CoreFoundation/CFNumber.h>
#include <CoreFoundation/CFString.h>
#include <CoreFoundation/CFLocale.h>
#include <CoreFoundation/CFNumberFormatter.h>
#include <CoreFoundation/CFDateFormatter.h>
#include <sys/types.h>
#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_LINUX
#include <unistd.h>
#endif

static Boolean _CFApplicationPreferencesSynchronizeNoLock(_CFApplicationPreferences *self);
void _CFPreferencesDomainSetMultiple(CFPreferencesDomainRef domain, CFDictionaryRef dict);
static void updateDictRep(_CFApplicationPreferences *self);
static void _CFApplicationPreferencesSetSearchList(_CFApplicationPreferences *self, CFArrayRef newSearchList);
Boolean _CFApplicationPreferencesContainsDomainNoLock(_CFApplicationPreferences *self, CFPreferencesDomainRef domain);
static CFTypeRef _CFApplicationPreferencesCreateValueForKey2(_CFApplicationPreferences *self, CFStringRef defaultName);

// Right now, nothing is getting destroyed pretty much ever.  We probably don't want this to be the case, but it's very tricky - domains live in the cache as well as a given application's preferences, and since they're not CFTypes, there's no reference count.  Also, it's not clear we ever want domains destroyed.  When they're synchronized, they clear their internal state (to force reading from the disk again), so they're not very big.... REW, 12/17/98

CFPropertyListRef CFPreferencesCopyAppValue(CFStringRef key, CFStringRef appName) {
    _CFApplicationPreferences *standardPrefs;
    CFAssert1(appName != NULL, __kCFLogAssertion, "%s(): Cannot access application preferences with a NULL application name", __PRETTY_FUNCTION__);
    CFAssert1(key != NULL, __kCFLogAssertion, "%s(): Cannot access preferences with a NULL key", __PRETTY_FUNCTION__);
    
    standardPrefs = _CFStandardApplicationPreferences(appName);
    return standardPrefs ? _CFApplicationPreferencesCreateValueForKey2(standardPrefs, key) : NULL;
}

CF_EXPORT Boolean CFPreferencesAppBooleanValue(CFStringRef key, CFStringRef appName, Boolean *keyExistsAndHasValidFormat) {
    CFPropertyListRef value;
    Boolean result, valid;
    CFTypeID typeID = 0;
    CFAssert1(appName != NULL, __kCFLogAssertion, "%s(): Cannot access application preferences with a NULL application name", __PRETTY_FUNCTION__);
    CFAssert1(key != NULL, __kCFLogAssertion, "%s(): Cannot access preferences with a NULL key", __PRETTY_FUNCTION__);

    if (!keyExistsAndHasValidFormat) {
        keyExistsAndHasValidFormat = &valid;
    }
    value = CFPreferencesCopyAppValue(key, appName);
    if (!value) {
        *keyExistsAndHasValidFormat = false;
        return false;
    }
    typeID = CFGetTypeID(value);
    if (typeID == CFStringGetTypeID()) {
        if (CFStringCompare((CFStringRef)value, CFSTR("true"), kCFCompareCaseInsensitive) == kCFCompareEqualTo || CFStringCompare((CFStringRef)value, CFSTR("YES"), kCFCompareCaseInsensitive) == kCFCompareEqualTo) {
            *keyExistsAndHasValidFormat = true;
            result = true;
        } else if (CFStringCompare((CFStringRef)value, CFSTR("false"), kCFCompareCaseInsensitive) == kCFCompareEqualTo || CFStringCompare((CFStringRef)value, CFSTR("NO"), kCFCompareCaseInsensitive) == kCFCompareEqualTo) {
            *keyExistsAndHasValidFormat = true;
            result = false;
        } else {
            *keyExistsAndHasValidFormat = false;
            result = false;
        }
    } else if (typeID == CFNumberGetTypeID()) {
        if (CFNumberIsFloatType((CFNumberRef)value)) {
            *keyExistsAndHasValidFormat = false;
            result = false;
        } else {
            int i;
            *keyExistsAndHasValidFormat = true;
            CFNumberGetValue((CFNumberRef)value, kCFNumberIntType, &i);
            result = (i == 0) ? false : true;
        }
    } else if (typeID == CFBooleanGetTypeID()) {
        result = (value == kCFBooleanTrue);
        *keyExistsAndHasValidFormat = true;
    } else {
        // Unknown type
        result = false;
        *keyExistsAndHasValidFormat = false;
    }
    CFRelease(value);
    return result;
}

CF_PRIVATE CFIndex CFPreferencesAppIntegerValue(CFStringRef key, CFStringRef appName, Boolean *keyExistsAndHasValidFormat) {
    CFPropertyListRef value;
    CFIndex result;
    CFTypeID typeID = 0;
    Boolean valid;
    CFAssert1(appName != NULL, __kCFLogAssertion, "%s(): Cannot access application preferences with a NULL application name", __PRETTY_FUNCTION__);
    CFAssert1(key != NULL, __kCFLogAssertion, "%s(): Cannot access preferences with a NULL key", __PRETTY_FUNCTION__);

    value = CFPreferencesCopyAppValue(key, appName);
    if (!keyExistsAndHasValidFormat) {
        keyExistsAndHasValidFormat = &valid;
    }
    if (!value) {
        *keyExistsAndHasValidFormat = false;
        return 0;
    }
    typeID = CFGetTypeID(value);
    if (typeID == CFStringGetTypeID()) {
        SInt32 charIndex = 0;
        SInt32 intVal;
        CFStringInlineBuffer buf;
        Boolean success;
        CFStringInitInlineBuffer((CFStringRef)value, &buf, CFRangeMake(0, CFStringGetLength((CFStringRef)value)));
        success = __CFStringScanInteger(&buf, NULL, &charIndex, false, &intVal);
        *keyExistsAndHasValidFormat = (success && charIndex == CFStringGetLength((CFStringRef)value));
        result = (*keyExistsAndHasValidFormat) ? intVal : 0;
    } else if (typeID == CFNumberGetTypeID()) {
        *keyExistsAndHasValidFormat = !CFNumberIsFloatType((CFNumberRef)value);
        if (*keyExistsAndHasValidFormat) {
            CFNumberGetValue((CFNumberRef)value, kCFNumberCFIndexType, &result);
        } else {
            result = 0;
        }
    } else {
        // Unknown type
        result = 0;
        *keyExistsAndHasValidFormat = false;
    }
    CFRelease(value);
    return result;
}

Boolean CFPreferencesGetAppBooleanValue(CFStringRef key, CFStringRef appName, Boolean *keyExistsAndHasValidFormat) {
    CFAssert1(appName != NULL, __kCFLogAssertion, "%s(): Cannot access application preferences with a NULL application name", __PRETTY_FUNCTION__);
    CFAssert1(key != NULL, __kCFLogAssertion, "%s(): Cannot access preferences with a NULL key", __PRETTY_FUNCTION__);
    return CFPreferencesAppBooleanValue(key, appName, keyExistsAndHasValidFormat);
}

CFIndex CFPreferencesGetAppIntegerValue(CFStringRef key, CFStringRef appName, Boolean *keyExistsAndHasValidFormat) {
    CFAssert1(appName != NULL, __kCFLogAssertion, "%s(): Cannot access application preferences with a NULL application name", __PRETTY_FUNCTION__);
    CFAssert1(key != NULL, __kCFLogAssertion, "%s(): Cannot access preferences with a NULL key", __PRETTY_FUNCTION__);
    return CFPreferencesAppIntegerValue(key, appName, keyExistsAndHasValidFormat);
}

void CFPreferencesSetAppValue(CFStringRef key, CFTypeRef value, CFStringRef appName) {
    _CFApplicationPreferences *standardPrefs;
    CFAssert1(appName != NULL, __kCFLogAssertion, "%s(): Cannot access application preferences with a NULL application name", __PRETTY_FUNCTION__);
    CFAssert1(key != NULL, __kCFLogAssertion, "%s(): Cannot access preferences with a NULL key", __PRETTY_FUNCTION__);

    standardPrefs = _CFStandardApplicationPreferences(appName);
    if (standardPrefs) {
        if (value) _CFApplicationPreferencesSet(standardPrefs, key, value);
        else _CFApplicationPreferencesRemove(standardPrefs, key);
    }
}


static CFLock_t __CFApplicationPreferencesLock = CFLockInit; // Locks access to __CFStandardUserPreferences
static CFMutableDictionaryRef __CFStandardUserPreferences = NULL; // Mutable dictionary; keys are app names, values are _CFApplicationPreferences 

Boolean CFPreferencesAppSynchronize(CFStringRef appName) {
    _CFApplicationPreferences *standardPrefs;
    Boolean result;
    CFAssert1(appName != NULL, __kCFLogAssertion, "%s(): Cannot access application preferences with a NULL application name", __PRETTY_FUNCTION__);
    
    // Do not call _CFStandardApplicationPreferences(), as we do not want to create the preferences only to synchronize
    __CFLock(&__CFApplicationPreferencesLock);
    if (__CFStandardUserPreferences)  {
        standardPrefs = (_CFApplicationPreferences *)CFDictionaryGetValue(__CFStandardUserPreferences, appName);
    } else {
        standardPrefs = NULL;
    }

    result = standardPrefs ? _CFApplicationPreferencesSynchronizeNoLock(standardPrefs) : _CFSynchronizeDomainCache();
    __CFUnlock(&__CFApplicationPreferencesLock);
    return result;
}

void CFPreferencesFlushCaches(void) {
    CFAllocatorRef alloc = __CFPreferencesAllocator();
    __CFLock(&__CFApplicationPreferencesLock);
    if (__CFStandardUserPreferences)  {
        _CFApplicationPreferences **prefsArray, *prefsBuf[32];
        CFIndex idx, count = CFDictionaryGetCount(__CFStandardUserPreferences);
        if (count < 32) {
            prefsArray = prefsBuf;
        } else {
            prefsArray = (_CFApplicationPreferences **)CFAllocatorAllocate(alloc, count * sizeof(_CFApplicationPreferences *), 0);
        }
        CFDictionaryGetKeysAndValues(__CFStandardUserPreferences, NULL, (const void **)prefsArray);

        __CFUnlock(&__CFApplicationPreferencesLock);
        // DeallocateApplicationPreferences needs the lock
        for (idx = 0; idx < count; idx ++) {
            _CFApplicationPreferences *appPrefs = prefsArray[idx];
            _CFApplicationPreferencesSynchronize(appPrefs);
            _CFDeallocateApplicationPreferences(appPrefs);
        }
        __CFLock(&__CFApplicationPreferencesLock);

        CFRelease(__CFStandardUserPreferences);
        __CFStandardUserPreferences = NULL;
        if(prefsArray != prefsBuf) CFAllocatorDeallocate(alloc, prefsArray);
    }
    __CFUnlock(&__CFApplicationPreferencesLock);
    _CFPreferencesPurgeDomainCache();
}

// quick message to indicate that the given domain has changed, and we should go through and invalidate any dictReps that involve this domain.
void _CFApplicationPreferencesDomainHasChanged(CFPreferencesDomainRef changedDomain) {
    CFAllocatorRef alloc = __CFPreferencesAllocator();
    __CFLock(&__CFApplicationPreferencesLock);
    if(__CFStandardUserPreferences) {  // only grovel over the prefs if there's something there to grovel
        _CFApplicationPreferences **prefsArray, *prefsBuf[32];
        CFIndex idx, count = CFDictionaryGetCount(__CFStandardUserPreferences);
        if(count < 32) {
            prefsArray = prefsBuf;
        } else {
            prefsArray = (_CFApplicationPreferences **)CFAllocatorAllocate(alloc, count * sizeof(_CFApplicationPreferences *), 0);
        }
        CFDictionaryGetKeysAndValues(__CFStandardUserPreferences, NULL, (const void **)prefsArray);
        // For this operation, giving up the lock is the last thing we want to do, so use the modified flavor of _CFApplicationPreferencesContainsDomain
        for(idx = 0; idx < count; idx++) {
            _CFApplicationPreferences *appPrefs = prefsArray[idx];
            if(_CFApplicationPreferencesContainsDomainNoLock(appPrefs, changedDomain)) {
                updateDictRep(appPrefs);
            }
        }
        if(prefsArray != prefsBuf) CFAllocatorDeallocate(alloc, prefsArray);
    }
    __CFUnlock(&__CFApplicationPreferencesLock);
}


// Begin ported code from NSUserDefaults.m


static void updateDictRep(_CFApplicationPreferences *self) {
    if (self->_dictRep) {
        CFRelease(self->_dictRep);
        self->_dictRep = NULL;
    }
}

static void __addKeysAndValues(const void *key, const void *value, void *context) {
    CFDictionarySetValue((CFMutableDictionaryRef)context, key, value);
}

static CFMutableDictionaryRef computeDictRep(_CFApplicationPreferences *self, Boolean skipC0C0A) {
    CFAllocatorRef alloc = __CFPreferencesAllocator();
    CFMutableArrayRef searchList = self->_search;
    CFIndex idx;
    CFIndex cnt = CFArrayGetCount(searchList);
    CFDictionaryRef subdomainDict;
    CFMutableDictionaryRef dictRep;
    
    dictRep = CFDictionaryCreateMutable(alloc, 0, &kCFTypeDictionaryKeyCallBacks, & kCFTypeDictionaryValueCallBacks);
    _CFDictionarySetCapacity(dictRep, 260);	// avoid lots of rehashing
    
    // For each subdomain triplet in the domain, iterate over dictionaries, adding them if necessary to the dictRep
    for (idx = cnt; idx--;) {
        CFPreferencesDomainRef domain = (CFPreferencesDomainRef)CFArrayGetValueAtIndex(searchList, idx);

        if (!domain) continue;

        subdomainDict = _CFPreferencesDomainDeepCopyDictionary(domain);
        if (subdomainDict) {
            CFDictionaryApplyFunction(subdomainDict, __addKeysAndValues, dictRep);
            CFRelease(subdomainDict);
        }
    }
    return dictRep;
}

CFTypeRef _CFApplicationPreferencesSearchDownToDomain(_CFApplicationPreferences *self, CFPreferencesDomainRef stopper, CFStringRef key) {
    return NULL;
}


void _CFApplicationPreferencesUpdate(_CFApplicationPreferences *self) {
    __CFLock(&__CFApplicationPreferencesLock);
    updateDictRep(self);
    __CFUnlock(&__CFApplicationPreferencesLock);
}

CF_EXPORT CFDictionaryRef _CFApplicationPreferencesCopyRepresentation(_CFApplicationPreferences *self);

CF_PRIVATE CFDictionaryRef __CFApplicationPreferencesCopyCurrentState(void) {
    _CFApplicationPreferences *self = _CFStandardApplicationPreferences(kCFPreferencesCurrentApplication);
    CFDictionaryRef result = _CFApplicationPreferencesCopyRepresentation(self);
    return result;
}

// CACHING here - we will only return a value as current as the last time computeDictRep() was called
static CFTypeRef _CFApplicationPreferencesCreateValueForKey2(_CFApplicationPreferences *self, CFStringRef defaultName) {
    CFTypeRef result;
    __CFLock(&__CFApplicationPreferencesLock);
    if (!self->_dictRep) {
        self->_dictRep = computeDictRep(self, true);
    }
    result = (self->_dictRep) ? (CFTypeRef )CFDictionaryGetValue(self->_dictRep, defaultName) : NULL;
    if (result) {
        CFRetain(result);
    }
    __CFUnlock(&__CFApplicationPreferencesLock);
    return result;
}


void _CFApplicationPreferencesSet(_CFApplicationPreferences *self, CFStringRef defaultName, CFTypeRef value) {
    CFPreferencesDomainRef applicationDomain;

    __CFLock(&__CFApplicationPreferencesLock);
    applicationDomain = _CFPreferencesStandardDomain(self->_appName, kCFPreferencesCurrentUser, kCFPreferencesAnyHost);
    if(applicationDomain) {
        _CFPreferencesDomainSet(applicationDomain, defaultName, value);
        if (CFArrayContainsValue(self->_search, CFRangeMake(0, CFArrayGetCount(self->_search)), applicationDomain)) {
            // Expensive; can't we just check the relevant value throughout the appropriate sets of domains? -- REW, 7/19/99
            updateDictRep(self);
        }
    }
    __CFUnlock(&__CFApplicationPreferencesLock);
}

void _CFApplicationPreferencesRemove(_CFApplicationPreferences *self, CFStringRef defaultName) {
    CFPreferencesDomainRef appDomain;

    __CFLock(&__CFApplicationPreferencesLock);
    appDomain = _CFPreferencesStandardDomain(self->_appName, kCFPreferencesCurrentUser, kCFPreferencesAnyHost);
    if(appDomain) {
        _CFPreferencesDomainSet(appDomain, defaultName, NULL);
        if (CFArrayContainsValue(self->_search, CFRangeMake(0, CFArrayGetCount(self->_search)), appDomain)) {
            // If key exists, it will be in the _dictRep (but possibly overridden)
            updateDictRep(self);
        }
    }
    __CFUnlock(&__CFApplicationPreferencesLock);
}

static Boolean _CFApplicationPreferencesSynchronizeNoLock(_CFApplicationPreferences *self) {
    Boolean success = _CFSynchronizeDomainCache();
    updateDictRep(self);
    return success;
}

Boolean _CFApplicationPreferencesSynchronize(_CFApplicationPreferences *self) {
    Boolean result;
    __CFLock(&__CFApplicationPreferencesLock);
    result = _CFApplicationPreferencesSynchronizeNoLock(self);
    __CFUnlock(&__CFApplicationPreferencesLock);
    return result;
}

// appName should not be kCFPreferencesCurrentApplication going in to this call
_CFApplicationPreferences *_CFApplicationPreferencesCreateWithUser(CFStringRef userName, CFStringRef appName) {
    CFAllocatorRef alloc = __CFPreferencesAllocator();
    _CFApplicationPreferences *self = (_CFApplicationPreferences*)CFAllocatorAllocate(alloc, sizeof(_CFApplicationPreferences), 0);
    if (self) {
        self->_dictRep = NULL;
        self->_appName = (CFStringRef)CFRetain(appName);
        self->_search = CFArrayCreateMutable(alloc, 0, &kCFTypeArrayCallBacks);
        if (!self->_search) {
            CFAllocatorDeallocate(alloc, self);
            CFRelease(appName);
            self = NULL;
        }
    }
    return self;
}

// Do NOT release the domain after adding it to the array; domain_expression should not return a retained object  -- REW, 8/26/99 
#define ADD_DOMAIN(domain_expression) domain = domain_expression; if (domain) {CFArrayAppendValue(search, domain);}
void _CFApplicationPreferencesSetStandardSearchList(_CFApplicationPreferences *appPreferences) {
    /* Here is how the domains end up in priority order in a search list.  Only a subset of these are setup by default.
	argument domain
	this app, this user, managed
	this app, any user, managed
        this app, this user, this host
        this app, this user, any host (AppDomain)
	suiteN, this user, this host
	suiteN, this user, any host
        ...
	suite0, this user, this host
	suite0, this user, any host
        any app, this user, this host
        any app, this user, any host (GlobalDomain)
        NSUserDefaults backwards-compat ICU domain
        this app, any user, this host
        this app, any user, any host
	suiteN, any user, this host
	suiteN, any user, any host
        ...
	suite0, any user, this host
	suite0, any user, any host
        any app, any user, this host
        any app, any user, any host
	registration domain
    */
    CFPreferencesDomainRef domain;
    CFMutableArrayRef search = CFArrayCreateMutable(kCFAllocatorSystemDefault, 0, &kCFTypeArrayCallBacks);
    if (!search) {
        // couldn't allocate memory!
        return;
    }

    ADD_DOMAIN(_CFPreferencesStandardDomain(appPreferences->_appName, kCFPreferencesCurrentUser, kCFPreferencesCurrentHost));
    ADD_DOMAIN(_CFPreferencesStandardDomain(appPreferences->_appName, kCFPreferencesCurrentUser, kCFPreferencesAnyHost));
    ADD_DOMAIN(_CFPreferencesStandardDomain(kCFPreferencesAnyApplication, kCFPreferencesCurrentUser, kCFPreferencesCurrentHost));
    ADD_DOMAIN(_CFPreferencesStandardDomain(kCFPreferencesAnyApplication, kCFPreferencesCurrentUser, kCFPreferencesAnyHost));
    ADD_DOMAIN(_CFPreferencesStandardDomain(appPreferences->_appName, kCFPreferencesAnyUser, kCFPreferencesCurrentHost));
    ADD_DOMAIN(_CFPreferencesStandardDomain(appPreferences->_appName, kCFPreferencesAnyUser, kCFPreferencesAnyHost));
    ADD_DOMAIN(_CFPreferencesStandardDomain(kCFPreferencesAnyApplication, kCFPreferencesAnyUser, kCFPreferencesCurrentHost));
    ADD_DOMAIN(_CFPreferencesStandardDomain(kCFPreferencesAnyApplication, kCFPreferencesAnyUser, kCFPreferencesAnyHost));

    _CFApplicationPreferencesSetSearchList(appPreferences, search);
    CFRelease(search);
}
#undef ADD_DOMAIN


CF_PRIVATE _CFApplicationPreferences *_CFStandardApplicationPreferences(CFStringRef appName) {
    _CFApplicationPreferences *appPreferences;
//    CFAssert(appName != kCFPreferencesAnyApplication, __kCFLogAssertion, "Cannot use any of the CFPreferences...App... functions with an appName of kCFPreferencesAnyApplication");
    __CFLock(&__CFApplicationPreferencesLock);
    if (!__CFStandardUserPreferences)  {
        __CFStandardUserPreferences = CFDictionaryCreateMutable(kCFAllocatorSystemDefault, 0, & kCFTypeDictionaryKeyCallBacks, NULL);
    }
    if (!__CFStandardUserPreferences) {
        // Couldn't create
        __CFUnlock(&__CFApplicationPreferencesLock);
        return NULL;
    }
    if ((appPreferences = (_CFApplicationPreferences *)CFDictionaryGetValue(__CFStandardUserPreferences, appName)) == NULL ) {
        appPreferences = _CFApplicationPreferencesCreateWithUser(kCFPreferencesCurrentUser, appName);
        CFDictionarySetValue(__CFStandardUserPreferences, appName, appPreferences);
        __CFUnlock(&__CFApplicationPreferencesLock);
        _CFApplicationPreferencesSetStandardSearchList(appPreferences);
    } else {
        __CFUnlock(&__CFApplicationPreferencesLock);
    }
    return appPreferences;
}

// Exclusively for Foundation's use
void _CFApplicationPreferencesSetCacheForApp(_CFApplicationPreferences *appPrefs, CFStringRef appName) {
    __CFLock(&__CFApplicationPreferencesLock);
    if (!__CFStandardUserPreferences) {
        __CFStandardUserPreferences = CFDictionaryCreateMutable(kCFAllocatorSystemDefault, 0, &kCFTypeDictionaryKeyCallBacks, NULL);
        CFDictionarySetValue(__CFStandardUserPreferences, appName, appPrefs);
        __CFUnlock(&__CFApplicationPreferencesLock);
    } else {
        _CFApplicationPreferences *oldPrefs = (_CFApplicationPreferences *)CFDictionaryGetValue(__CFStandardUserPreferences, appName);
        CFDictionarySetValue(__CFStandardUserPreferences, appName, appPrefs);
        __CFUnlock(&__CFApplicationPreferencesLock);
        if (oldPrefs) {
            _CFDeallocateApplicationPreferences(oldPrefs);
        }
    }
}


void _CFDeallocateApplicationPreferences(_CFApplicationPreferences *self) {
    CFAllocatorRef alloc = __CFPreferencesAllocator();
    _CFApplicationPreferences *cachedPrefs = NULL;
    __CFLock(&__CFApplicationPreferencesLock);

    // Get us out of the cache before destroying!
    if (__CFStandardUserPreferences)  {
        cachedPrefs = (_CFApplicationPreferences *)CFDictionaryGetValue(__CFStandardUserPreferences, self->_appName);
    }
    if (cachedPrefs == self) {
        CFDictionaryRemoveValue(__CFStandardUserPreferences, self->_appName);
    }
    
    if (self->_dictRep) CFRelease(self->_dictRep);
    CFRelease(self->_search);
    CFRelease(self->_appName);
    CFAllocatorDeallocate(alloc, self);
    __CFUnlock(&__CFApplicationPreferencesLock);
}


CF_EXPORT
CFDictionaryRef _CFApplicationPreferencesCopyRepresentation(_CFApplicationPreferences *self) {
    CFDictionaryRef dict;
    __CFLock(&__CFApplicationPreferencesLock);
    if (!self->_dictRep) {
        self->_dictRep = computeDictRep(self, true);
    }
    if (self->_dictRep) {
        CFRetain(self->_dictRep);
    }
    dict = self->_dictRep;
    __CFUnlock(&__CFApplicationPreferencesLock);
    return dict;
}

static void _CFApplicationPreferencesSetSearchList(_CFApplicationPreferences *self, CFArrayRef newSearchList) {
    CFIndex idx, count;
    __CFLock(&__CFApplicationPreferencesLock);
    CFArrayRemoveAllValues(self->_search);
    count = CFArrayGetCount(newSearchList);
    for (idx = 0; idx < count; idx ++) {
        CFArrayAppendValue(self->_search, CFArrayGetValueAtIndex(newSearchList, idx));
    }
    updateDictRep(self);
    __CFUnlock(&__CFApplicationPreferencesLock);
}

void CFPreferencesAddSuitePreferencesToApp(CFStringRef appName, CFStringRef suiteName) {
    _CFApplicationPreferences *appPrefs;
    
    appPrefs = _CFStandardApplicationPreferences(appName);
    _CFApplicationPreferencesAddSuitePreferences(appPrefs, suiteName);
}

void _CFApplicationPreferencesAddSuitePreferences(_CFApplicationPreferences *appPrefs, CFStringRef suiteName) {
    CFPreferencesDomainRef domain; 
    CFIndex idx;
    CFRange range;

    // Find where to insert the new suite
    __CFLock(&__CFApplicationPreferencesLock);
    domain = _CFPreferencesStandardDomain(appPrefs->_appName, kCFPreferencesCurrentUser, kCFPreferencesAnyHost);
    range.location = 0;
    range.length = CFArrayGetCount(appPrefs->_search);
    idx = domain ? CFArrayGetFirstIndexOfValue(appPrefs->_search, range, domain) : kCFNotFound;
    __CFUnlock(&__CFApplicationPreferencesLock);
    idx ++; // We want just below the app domain.  Coincidentally, this gives us the top of the list if the app domain has been removed.
    domain = _CFPreferencesStandardDomain(suiteName, kCFPreferencesCurrentUser, kCFPreferencesAnyHost);
    if (domain) {
        __CFLock(&__CFApplicationPreferencesLock);
        CFArrayInsertValueAtIndex(appPrefs->_search, idx, domain);
        __CFUnlock(&__CFApplicationPreferencesLock);
        range.length ++;
    }
    domain = _CFPreferencesStandardDomain(suiteName, kCFPreferencesCurrentUser, kCFPreferencesCurrentHost);
    if (domain) {
        __CFLock(&__CFApplicationPreferencesLock);
        CFArrayInsertValueAtIndex(appPrefs->_search, idx, domain);
        __CFUnlock(&__CFApplicationPreferencesLock);
        range.length ++;
    }

    // Now the AnyUser domains
    domain = _CFPreferencesStandardDomain(appPrefs->_appName, kCFPreferencesAnyUser, kCFPreferencesAnyHost);
    idx = domain ? CFArrayGetFirstIndexOfValue(appPrefs->_search, range, domain) : kCFNotFound;
    if (idx == kCFNotFound) {
        // Someone blew away the app domain. For the any user case, we look for right below the global domain
        domain = _CFPreferencesStandardDomain(kCFPreferencesAnyApplication, kCFPreferencesCurrentUser, kCFPreferencesAnyHost);
        idx = domain ? CFArrayGetFirstIndexOfValue(appPrefs->_search, range, domain) : kCFNotFound;
        if (idx == kCFNotFound) {
            // Try the "any host" choice
            domain = _CFPreferencesStandardDomain(kCFPreferencesAnyApplication, kCFPreferencesCurrentUser, kCFPreferencesCurrentHost);
            idx = domain ? CFArrayGetFirstIndexOfValue(appPrefs->_search, range, domain) : kCFNotFound;
            if (idx == kCFNotFound) {
                // We give up; put the new domains at the bottom
                idx = CFArrayGetCount(appPrefs->_search) - 1;
            }
        }
    }
    idx ++;
    domain = _CFPreferencesStandardDomain(suiteName, kCFPreferencesAnyUser, kCFPreferencesAnyHost);
    if (domain) {
        __CFLock(&__CFApplicationPreferencesLock);
        CFArrayInsertValueAtIndex(appPrefs->_search, idx, domain);
        __CFUnlock(&__CFApplicationPreferencesLock);
    }
    domain = _CFPreferencesStandardDomain(suiteName, kCFPreferencesAnyUser, kCFPreferencesCurrentHost);
    if (domain) {
        __CFLock(&__CFApplicationPreferencesLock);
        CFArrayInsertValueAtIndex(appPrefs->_search, idx, domain);
        __CFUnlock(&__CFApplicationPreferencesLock);
    }
    __CFLock(&__CFApplicationPreferencesLock);
    updateDictRep(appPrefs);
    __CFUnlock(&__CFApplicationPreferencesLock);
}

void CFPreferencesRemoveSuitePreferencesFromApp(CFStringRef appName, CFStringRef suiteName) {
    _CFApplicationPreferences *appPrefs;

    appPrefs = _CFStandardApplicationPreferences(appName);
    
    _CFApplicationPreferencesRemoveSuitePreferences(appPrefs, suiteName);
}

void _CFApplicationPreferencesRemoveSuitePreferences(_CFApplicationPreferences *appPrefs, CFStringRef suiteName) {
    CFPreferencesDomainRef domain;

    __CFLock(&__CFApplicationPreferencesLock);
    domain = _CFPreferencesStandardDomain(suiteName, kCFPreferencesCurrentUser, kCFPreferencesAnyHost);
    __CFUnlock(&__CFApplicationPreferencesLock);
    if (domain) _CFApplicationPreferencesRemoveDomain(appPrefs, domain);

    __CFLock(&__CFApplicationPreferencesLock);
    domain = _CFPreferencesStandardDomain(suiteName, kCFPreferencesCurrentUser, kCFPreferencesCurrentHost);
    __CFUnlock(&__CFApplicationPreferencesLock);
    if (domain) _CFApplicationPreferencesRemoveDomain(appPrefs, domain);

    __CFLock(&__CFApplicationPreferencesLock);
    domain = _CFPreferencesStandardDomain(suiteName, kCFPreferencesAnyUser, kCFPreferencesAnyHost);
    __CFUnlock(&__CFApplicationPreferencesLock);
    if (domain) _CFApplicationPreferencesRemoveDomain(appPrefs, domain);

    __CFLock(&__CFApplicationPreferencesLock);
    domain = _CFPreferencesStandardDomain(suiteName, kCFPreferencesAnyUser, kCFPreferencesCurrentHost);
    __CFUnlock(&__CFApplicationPreferencesLock);
    if (domain) _CFApplicationPreferencesRemoveDomain(appPrefs, domain);
}

void _CFApplicationPreferencesAddDomain(_CFApplicationPreferences *self, CFPreferencesDomainRef domain, Boolean addAtTop) {
    __CFLock(&__CFApplicationPreferencesLock);
    if (addAtTop) {
        CFArrayInsertValueAtIndex(self->_search, 0, domain);
    } else {
        CFArrayAppendValue(self->_search, domain);
    }
    updateDictRep(self);
    __CFUnlock(&__CFApplicationPreferencesLock);
}

Boolean _CFApplicationPreferencesContainsDomain(_CFApplicationPreferences *self, CFPreferencesDomainRef domain) {
    Boolean result;

    if (!domain) {
        return false;
    }

    __CFLock(&__CFApplicationPreferencesLock);
    result = CFArrayContainsValue(self->_search, CFRangeMake(0, CFArrayGetCount(self->_search)), domain);
    __CFUnlock(&__CFApplicationPreferencesLock);
    return result;
}

Boolean _CFApplicationPreferencesContainsDomainNoLock(_CFApplicationPreferences *self, CFPreferencesDomainRef domain) {
    Boolean result;
    result = CFArrayContainsValue(self->_search, CFRangeMake(0, CFArrayGetCount(self->_search)), domain);
    return result;
}

void _CFApplicationPreferencesRemoveDomain(_CFApplicationPreferences *self, CFPreferencesDomainRef domain) {
    CFIndex idx;
    CFRange range;
    __CFLock(&__CFApplicationPreferencesLock);
    range.location = 0;
    range.length = CFArrayGetCount(self->_search);
    while ((idx = CFArrayGetFirstIndexOfValue(self->_search, range, domain)) != kCFNotFound) {
        CFArrayRemoveValueAtIndex(self->_search, idx);
        range.location = idx;
        range.length  = range.length - idx - 1;
    }
    updateDictRep(self);
    __CFUnlock(&__CFApplicationPreferencesLock);
}
