/*	CFPropertyList.c
	Copyright (c) 1999-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: Tony Parker
*/

#include <CoreFoundation/CFPropertyList.h>
#include <CoreFoundation/CFByteOrder.h>
#include <CoreFoundation/CFDate.h>
#include <CoreFoundation/CFNumber.h>
#include <CoreFoundation/CFSet.h>
#include <CoreFoundation/CFError.h>
#include <CoreFoundation/CFError_Private.h>
#include <CoreFoundation/CFPriv.h>
#include <CoreFoundation/CFStringEncodingConverter.h>
#include "CFInternal.h"
#include <CoreFoundation/CFBurstTrie.h>
#include <CoreFoundation/CFString.h>
#include <CoreFoundation/CFStream.h>
#include <CoreFoundation/CFCalendar.h>
#include "CFLocaleInternal.h"
#include <limits.h>
#include <float.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#include <ctype.h>


CF_EXPORT CFNumberType _CFNumberGetType2(CFNumberRef number);

#define PLIST_IX    0
#define ARRAY_IX    1
#define DICT_IX     2
#define KEY_IX      3
#define STRING_IX   4
#define DATA_IX     5
#define DATE_IX     6
#define REAL_IX     7
#define INTEGER_IX  8
#define TRUE_IX     9
#define FALSE_IX    10
#define DOCTYPE_IX  11
#define CDSECT_IX   12

#define PLIST_TAG_LENGTH	5
#define ARRAY_TAG_LENGTH	5
#define DICT_TAG_LENGTH		4
#define KEY_TAG_LENGTH		3
#define STRING_TAG_LENGTH	6
#define DATA_TAG_LENGTH		4
#define DATE_TAG_LENGTH		4
#define REAL_TAG_LENGTH		4
#define INTEGER_TAG_LENGTH	7
#define TRUE_TAG_LENGTH		4
#define FALSE_TAG_LENGTH	5
#define DOCTYPE_TAG_LENGTH	7
#define CDSECT_TAG_LENGTH	9

#if !defined(new_cftype_array)
#define new_cftype_array(N, C) \
    size_t N ## _count__ = (C); \
    if (N ## _count__ > LONG_MAX / sizeof(CFTypeRef)) { \
        CRSetCrashLogMessage("CFPropertyList ran out of memory while attempting to allocate temporary storage."); \
        HALT; \
    } \
    Boolean N ## _is_stack__ = (N ## _count__ <= 256); \
    if (N ## _count__ == 0) N ## _count__ = 1; \
    STACK_BUFFER_DECL(CFTypeRef, N ## _buffer__, N ## _is_stack__ ? N ## _count__ : 1); \
    if (N ## _is_stack__) memset(N ## _buffer__, 0, N ## _count__ * sizeof(CFTypeRef)); \
    CFTypeRef * N = N ## _is_stack__ ? N ## _buffer__ : (CFTypeRef *)CFAllocatorAllocate(kCFAllocatorSystemDefault, (N ## _count__) * sizeof(CFTypeRef), 0); \
    if (! N) { \
        CRSetCrashLogMessage("CFPropertyList ran out of memory while attempting to allocate temporary storage."); \
        HALT; \
    } \
    do {} while (0)
#endif

#if !defined(free_cftype_array)
#define free_cftype_array(N) \
    if (! N ## _is_stack__) { \
        CFAllocatorDeallocate(kCFAllocatorSystemDefault, N); \
    } \
    do {} while (0)
#endif

// Used to reference an old-style plist parser error inside of a more general XML error
#define CFPropertyListOldStyleParserErrorKey     CFSTR("kCFPropertyListOldStyleParsingError")

static CFTypeID stringtype, datatype, numbertype, datetype;
static CFTypeID booltype, nulltype, dicttype, arraytype, settype;

static void initStatics() {
    static dispatch_once_t once;
    dispatch_once(&once, ^{
        stringtype = CFStringGetTypeID();
        datatype = CFDataGetTypeID();        
        numbertype = CFNumberGetTypeID();
        booltype = CFBooleanGetTypeID();
        datetype = CFDateGetTypeID();
        dicttype = CFDictionaryGetTypeID();
        arraytype = CFArrayGetTypeID();
        settype = CFSetGetTypeID();
        nulltype = CFNullGetTypeID();
    });
}

CF_PRIVATE CFErrorRef __CFPropertyListCreateError(CFIndex code, CFStringRef debugString, ...) {    
    va_list argList;        
    CFErrorRef error = NULL;
    
    if (debugString != NULL) {
        CFStringRef debugMessage = NULL;
        va_start(argList, debugString);
        debugMessage = CFStringCreateWithFormatAndArguments(kCFAllocatorSystemDefault, NULL, debugString, argList);
        va_end(argList);
    
        CFMutableDictionaryRef userInfo = CFDictionaryCreateMutable(kCFAllocatorSystemDefault, 0, &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); 
        CFDictionarySetValue(userInfo, kCFErrorDebugDescriptionKey, debugMessage);
                
        error = CFErrorCreate(kCFAllocatorSystemDefault, kCFErrorDomainCocoa, code, userInfo);
        
        CFRelease(debugMessage);
        CFRelease(userInfo);
    } else {
        error = CFErrorCreate(kCFAllocatorSystemDefault, kCFErrorDomainCocoa, code, NULL);
    }
    
    return error;
}

static CFStringRef __copyErrorDebugDescription(CFErrorRef error) {
    CFStringRef result = NULL;
    if (error) {
        CFDictionaryRef userInfo = CFErrorCopyUserInfo(error);
        if (userInfo != NULL) {
            CFStringRef desc = (CFStringRef) CFDictionaryGetValue(userInfo, kCFErrorDebugDescriptionKey);
            if (desc != NULL) {
                result = CFStringCreateCopy(kCFAllocatorSystemDefault, desc);
            }
            CFRelease(userInfo);
        }
    }
    return result;
}

#pragma mark -
#pragma mark Property List Validation

// don't allow _CFKeyedArchiverUID here
#define __CFAssertIsPList(cf) CFAssert2(CFGetTypeID(cf) == CFStringGetTypeID() || CFGetTypeID(cf) == CFArrayGetTypeID() || CFGetTypeID(cf) == CFBooleanGetTypeID() || CFGetTypeID(cf) == CFNumberGetTypeID() || CFGetTypeID(cf) == CFDictionaryGetTypeID() || CFGetTypeID(cf) == CFDateGetTypeID() || CFGetTypeID(cf) == CFDataGetTypeID(), __kCFLogAssertion, "%s(): %p not of a property list type", __PRETTY_FUNCTION__, cf);

struct context {
    bool answer;
    CFMutableSetRef set;
    CFPropertyListFormat format;
    CFStringRef *error;
};

static bool __CFPropertyListIsValidAux(CFPropertyListRef plist, bool recursive, CFMutableSetRef set, CFPropertyListFormat format, CFStringRef *error);

static void __CFPropertyListIsArrayPlistAux(const void *value, void *context) {
    struct context *ctx = (struct context *)context;
    if (!ctx->answer) return;
    if (!value && ctx->error && !*(ctx->error)) {
	*(ctx->error) = (CFStringRef)CFRetain(CFSTR("property list arrays cannot contain NULL"));
    }
    ctx->answer = value && __CFPropertyListIsValidAux(value, true, ctx->set, ctx->format, ctx->error);
}

static void __CFPropertyListIsDictPlistAux(const void *key, const void *value, void *context) {
    struct context *ctx = (struct context *)context;
    if (!ctx->answer) return;
    if (!key && ctx->error && !*(ctx->error)) *(ctx->error) = (CFStringRef)CFRetain(CFSTR("property list dictionaries cannot contain NULL keys"));
    if (!value && ctx->error && !*(ctx->error)) *(ctx->error) = (CFStringRef)CFRetain(CFSTR("property list dictionaries cannot contain NULL values"));
    if (stringtype != CFGetTypeID(key) && ctx->error && !*(ctx->error)) {
	CFStringRef desc = CFCopyTypeIDDescription(CFGetTypeID(key));
	*(ctx->error) = CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("property list dictionaries may only have keys which are CFStrings, not '%@'"), desc);
	CFRelease(desc);
    }
    ctx->answer = key && value && (stringtype == CFGetTypeID(key)) && __CFPropertyListIsValidAux(value, true, ctx->set, ctx->format, ctx->error);
}

static bool __CFPropertyListIsValidAux(CFPropertyListRef plist, bool recursive, CFMutableSetRef set, CFPropertyListFormat format, CFStringRef *error) {
    if (!plist) {
	if (error) *error = (CFStringRef)CFRetain(CFSTR("property lists cannot contain NULL"));
    	return false;
    }
    CFTypeID type = CFGetTypeID(plist);
    if (stringtype == type) return true;
    if (datatype == type) return true;
    if (kCFPropertyListOpenStepFormat != format) {
	if (booltype == type) return true;
	if (numbertype == type) return true;
	if (datetype == type) return true;        
	if (_CFKeyedArchiverUIDGetTypeID() == type) return true;
    }
    if (!recursive && arraytype == type) return true;
    if (!recursive && dicttype == type) return true;
    
    // at any one invocation of this function, set should contain the objects in the "path" down to this object. For the outermost invocation it can be NULL.
    Boolean createdSet = false;
    if (!set) {
        set = CFSetCreateMutable(kCFAllocatorSystemDefault, 0, NULL);
        createdSet = true;
    } else if (CFSetContainsValue(set, plist)) {
	if (error) *error = (CFStringRef)CFRetain(CFSTR("property lists cannot contain recursive container references"));
	return false;
    }
    Boolean result = false;
    if (arraytype == type) {
	struct context ctx = {true, set, format, error}; 
	CFSetAddValue(set, plist);
	CFArrayApplyFunction((CFArrayRef)plist, CFRangeMake(0, CFArrayGetCount((CFArrayRef)plist)), __CFPropertyListIsArrayPlistAux, &ctx);
	CFSetRemoveValue(set, plist);
	result = ctx.answer;
    } else if (dicttype == type) {
	struct context ctx = {true, set, format, error}; 
	CFSetAddValue(set, plist);
	CFDictionaryApplyFunction((CFDictionaryRef)plist, __CFPropertyListIsDictPlistAux, &ctx);
	CFSetRemoveValue(set, plist);
        result = ctx.answer;
    } else if (error) {
        CFStringRef desc = CFCopyTypeIDDescription(type);
        *error = CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("property lists cannot contain objects of type '%@'"), desc);
        CFRelease(desc);
    }

    if (createdSet) {
        CFRelease(set);
    }

    return result;
}

static Boolean _CFPropertyListIsValidWithErrorString(CFPropertyListRef plist, CFPropertyListFormat format, CFStringRef *error) {
    initStatics();
    CFAssert1(plist != NULL, __kCFLogAssertion, "%s(): NULL is not a property list", __PRETTY_FUNCTION__);
    return __CFPropertyListIsValidAux(plist, true, NULL, format, error);
}

#pragma mark -
#pragma mark Writing Property Lists

static const char CFXMLPlistTags[13][10]= {
{'p', 'l', 'i', 's', 't',   '\0', '\0', '\0', '\0', '\0'},
{'a', 'r', 'r', 'a', 'y',   '\0', '\0', '\0', '\0', '\0'},
{'d', 'i', 'c', 't',  '\0', '\0', '\0', '\0', '\0', '\0'},
{'k', 'e', 'y', '\0', '\0', '\0', '\0', '\0', '\0', '\0'},
{'s', 't', 'r', 'i', 'n', 'g',    '\0', '\0', '\0', '\0'},
{'d', 'a', 't', 'a',  '\0', '\0', '\0', '\0', '\0', '\0'},
{'d', 'a', 't', 'e',  '\0', '\0', '\0', '\0', '\0', '\0'},
{'r', 'e', 'a', 'l',  '\0', '\0', '\0', '\0', '\0', '\0'},
{'i', 'n', 't', 'e', 'g', 'e', 'r',     '\0', '\0', '\0'},
{'t', 'r', 'u', 'e',  '\0', '\0', '\0', '\0', '\0', '\0'},
{'f', 'a', 'l', 's', 'e',   '\0', '\0', '\0', '\0', '\0'},
{'D', 'O', 'C', 'T', 'Y', 'P', 'E',     '\0', '\0', '\0'},
{'<', '!', '[', 'C', 'D', 'A', 'T', 'A', '[',       '\0'}
};

static const UniChar CFXMLPlistTagsUnicode[13][10]= {
    {'p', 'l', 'i', 's', 't',   '\0', '\0', '\0', '\0', '\0'},
    {'a', 'r', 'r', 'a', 'y',   '\0', '\0', '\0', '\0', '\0'},
    {'d', 'i', 'c', 't',  '\0', '\0', '\0', '\0', '\0', '\0'},
    {'k', 'e', 'y', '\0', '\0', '\0', '\0', '\0', '\0', '\0'},
    {'s', 't', 'r', 'i', 'n', 'g',    '\0', '\0', '\0', '\0'},
    {'d', 'a', 't', 'a',  '\0', '\0', '\0', '\0', '\0', '\0'},
    {'d', 'a', 't', 'e',  '\0', '\0', '\0', '\0', '\0', '\0'},
    {'r', 'e', 'a', 'l',  '\0', '\0', '\0', '\0', '\0', '\0'},
    {'i', 'n', 't', 'e', 'g', 'e', 'r',     '\0', '\0', '\0'},
    {'t', 'r', 'u', 'e',  '\0', '\0', '\0', '\0', '\0', '\0'},
    {'f', 'a', 'l', 's', 'e',   '\0', '\0', '\0', '\0', '\0'},
    {'D', 'O', 'C', 'T', 'Y', 'P', 'E',     '\0', '\0', '\0'},
    {'<', '!', '[', 'C', 'D', 'A', 'T', 'A', '[',       '\0'}
};

typedef struct {
    const char *begin; // first character of the XML to be parsed
    const char *curr;  // current parse location
    const char *end;   // the first character _after_ the end of the XML
    CFErrorRef error;
    CFAllocatorRef allocator;
    UInt32 mutabilityOption;
    CFBurstTrieRef stringTrie; // map of cached strings
    CFMutableArrayRef stringCache; // retaining array of strings
    Boolean allowNewTypes; // Whether to allow the new types supported by XML property lists, but not by the old, OPENSTEP ASCII property lists (CFNumber, CFBoolean, CFDate)
    CFSetRef keyPaths; // if NULL, no filtering
    Boolean skip; // if true, do not create any objects.
} _CFXMLPlistParseInfo;

CF_PRIVATE CFTypeRef __CFCreateOldStylePropertyListOrStringsFile(CFAllocatorRef allocator, CFDataRef xmlData, CFStringRef originalString, CFStringEncoding guessedEncoding, CFOptionFlags option, CFErrorRef *outError,CFPropertyListFormat *format);

CF_INLINE void __CFPListRelease(CFTypeRef cf, CFAllocatorRef allocator) {
    if (cf) CFRelease(cf);
}


// The following set of _plist... functions append various things to a mutable data which is in UTF8 encoding. These are pretty general. Assumption is call characters and CFStrings can be converted to UTF8 and appeneded.

// Null-terminated, ASCII or UTF8 string
//
static void _plistAppendUTF8CString(CFMutableDataRef mData, const char *cString) {
    CFDataAppendBytes (mData, (const UInt8 *)cString, strlen(cString));
}

// UniChars
//
static void _plistAppendCharacters(CFMutableDataRef mData, const UniChar *chars, CFIndex length) {
    CFIndex curLoc = 0;

    do {	// Flush out ASCII chars, BUFLEN at a time
        #define BUFLEN 400
	UInt8 buf[BUFLEN], *bufPtr = buf;
	CFIndex cnt = 0;
        while (cnt < length && (cnt - curLoc < BUFLEN) && (chars[cnt] < 128)) *bufPtr++ = (UInt8)(chars[cnt++]);
        if (cnt > curLoc) {	// Flush any ASCII bytes
            CFDataAppendBytes(mData, buf, cnt - curLoc);
            curLoc = cnt;
        }
    } while (curLoc < length && (chars[curLoc] < 128));	// We will exit out of here when we run out of chars or hit a non-ASCII char

    if (curLoc < length) {	// Now deal with non-ASCII chars
        CFDataRef data = NULL;
        CFStringRef str = NULL;
        if ((str = CFStringCreateWithCharactersNoCopy(kCFAllocatorSystemDefault, chars + curLoc, length - curLoc, kCFAllocatorNull))) {
            if ((data = CFStringCreateExternalRepresentation(kCFAllocatorSystemDefault, str, kCFStringEncodingUTF8, 0))) {
                CFDataAppendBytes (mData, CFDataGetBytePtr(data), CFDataGetLength(data));
                CFRelease(data);
            }
            CFRelease(str);
        }
        CFAssert1(str && data, __kCFLogAssertion, "%s(): Error writing plist", __PRETTY_FUNCTION__); 
    }
}

// Append CFString
//
static void _plistAppendString(CFMutableDataRef mData, CFStringRef str) {
    const UniChar *chars;
    const char *cStr;
    CFDataRef data;
    if ((chars = CFStringGetCharactersPtr(str))) {
        _plistAppendCharacters(mData, chars, CFStringGetLength(str));
    } else if ((cStr = CFStringGetCStringPtr(str, kCFStringEncodingASCII)) || (cStr = CFStringGetCStringPtr(str, kCFStringEncodingUTF8))) {
        _plistAppendUTF8CString(mData, cStr);
    } else if ((data = CFStringCreateExternalRepresentation(kCFAllocatorSystemDefault, str, kCFStringEncodingUTF8, 0))) {
        CFDataAppendBytes (mData, CFDataGetBytePtr(data), CFDataGetLength(data));
        CFRelease(data);
    } else {
	CFAssert1(TRUE, __kCFLogAssertion, "%s(): Error in plist writing", __PRETTY_FUNCTION__);
    }
}


// Append CFString-style format + arguments
//
static void _plistAppendFormat(CFMutableDataRef mData, CFStringRef format, ...) {
    CFStringRef fStr; 
    va_list argList;

    va_start(argList, format);
    fStr = CFStringCreateWithFormatAndArguments(kCFAllocatorSystemDefault, NULL, format, argList);
    va_end(argList);

    CFAssert1(fStr, __kCFLogAssertion, "%s(): Error writing plist", __PRETTY_FUNCTION__);
    _plistAppendString(mData, fStr);
    CFRelease(fStr);
}



static void _appendIndents(CFIndex numIndents, CFMutableDataRef str) {
#define NUMTABS 4
    static const UniChar tabs[NUMTABS] = {'\t','\t','\t','\t'};
    for (; numIndents > 0; numIndents -= NUMTABS) _plistAppendCharacters(str, tabs, (numIndents >= NUMTABS) ? NUMTABS : numIndents);
}

/* Append the escaped version of origStr to mStr.
*/
static void _appendEscapedString(CFStringRef origStr, CFMutableDataRef mStr) {
#define BUFSIZE 64
    CFIndex i, length = CFStringGetLength(origStr);
    CFIndex bufCnt = 0;
    UniChar buf[BUFSIZE];
    CFStringInlineBuffer inlineBuffer;

    CFStringInitInlineBuffer(origStr, &inlineBuffer, CFRangeMake(0, length));

    for (i = 0; i < length; i ++) {
	UniChar ch = __CFStringGetCharacterFromInlineBufferQuick(&inlineBuffer, i);
	if (CFStringIsSurrogateHighCharacter(ch) && (bufCnt + 2 >= BUFSIZE)) {
	    // flush the buffer first so we have room for a low/high pair and do not split them
	    _plistAppendCharacters(mStr, buf, bufCnt);
	    bufCnt = 0;
	}
	
        switch(ch) {
            case '<':
		if (bufCnt) _plistAppendCharacters(mStr, buf, bufCnt);
		bufCnt = 0;
	  	_plistAppendUTF8CString(mStr, "&lt;");
                break;
            case '>':
		if (bufCnt) _plistAppendCharacters(mStr, buf, bufCnt);
		bufCnt = 0;
	  	_plistAppendUTF8CString(mStr, "&gt;");
                break;
            case '&':
		if (bufCnt) _plistAppendCharacters(mStr, buf, bufCnt);
		bufCnt = 0;
	  	_plistAppendUTF8CString(mStr, "&amp;");
                break;
            default:
		buf[bufCnt++] = ch;
		if (bufCnt == BUFSIZE) {
		    _plistAppendCharacters(mStr, buf, bufCnt);
		    bufCnt = 0;
		}
		break;
        }
    }
    if (bufCnt) _plistAppendCharacters(mStr, buf, bufCnt);
}



/* Base-64 encoding/decoding */

/* The base-64 encoding packs three 8-bit bytes into four 7-bit ASCII
 * characters.  If the number of bytes in the original data isn't divisable
 * by three, "=" characters are used to pad the encoded data.  The complete
 * set of characters used in base-64 are:
 *
 *      'A'..'Z' => 00..25
 *      'a'..'z' => 26..51
 *      '0'..'9' => 52..61
 *      '+'      => 62
 *      '/'      => 63
 *      '='      => pad
 */

// Write the inputData to the mData using Base 64 encoding

static void _XMLPlistAppendDataUsingBase64(CFMutableDataRef mData, CFDataRef inputData, CFIndex indent) {
    static const char __CFPLDataEncodeTable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
    #define MAXLINELEN 76
    char buf[MAXLINELEN + 4 + 2];	// For the slop and carriage return and terminating NULL
    
    const uint8_t *bytes = CFDataGetBytePtr(inputData);
    CFIndex length = CFDataGetLength(inputData);
    CFIndex i, pos;
    const uint8_t *p;

    if (indent > 8) indent = 8; // refuse to indent more than 64 characters

    pos = 0;		// position within buf

    for (i = 0, p = bytes; i < length; i++, p++) {
        /* 3 bytes are encoded as 4 */
        switch (i % 3) {
            case 0:
                buf[pos++] = __CFPLDataEncodeTable [ ((p[0] >> 2) & 0x3f)];
                break;
            case 1:
                buf[pos++] = __CFPLDataEncodeTable [ ((((p[-1] << 8) | p[0]) >> 4) & 0x3f)];
                break;
            case 2:
                buf[pos++] = __CFPLDataEncodeTable [ ((((p[-1] << 8) | p[0]) >> 6) & 0x3f)];
                buf[pos++] = __CFPLDataEncodeTable [ (p[0] & 0x3f)];
                break;
        }
        /* Flush the line out every 76 (or fewer) chars --- indents count against the line length*/
        if (pos >= MAXLINELEN - 8 * indent) {
            buf[pos++] = '\n';
            buf[pos++] = 0;
            _appendIndents(indent, mData);
            _plistAppendUTF8CString(mData, buf);
            pos = 0;
        }
    }
        
    switch (i % 3) {
	case 0:
            break;
	case 1:
            buf[pos++] = __CFPLDataEncodeTable [ ((p[-1] << 4) & 0x30)];
            buf[pos++] = '=';
            buf[pos++] = '=';
            break;
	case 2:
            buf[pos++] =  __CFPLDataEncodeTable [ ((p[-1] << 2) & 0x3c)];
            buf[pos++] = '=';
            break;
    }
    
    if (pos > 0) {
        buf[pos++] = '\n';
        buf[pos++] = 0;
        _appendIndents(indent, mData);
        _plistAppendUTF8CString(mData, buf);
    }
}

extern CFStringRef __CFNumberCopyFormattingDescriptionAsFloat64(CFTypeRef cf);

static void _CFAppendXML0(CFTypeRef object, UInt32 indentation, CFMutableDataRef xmlString) {
    UInt32 typeID = CFGetTypeID(object);
    _appendIndents(indentation, xmlString);
    if (typeID == stringtype) {
        _plistAppendUTF8CString(xmlString, "<");
        _plistAppendCharacters(xmlString, CFXMLPlistTagsUnicode[STRING_IX], STRING_TAG_LENGTH);
        _plistAppendUTF8CString(xmlString, ">");
	_appendEscapedString((CFStringRef)object, xmlString);
        _plistAppendUTF8CString(xmlString, "</");
        _plistAppendCharacters(xmlString, CFXMLPlistTagsUnicode[STRING_IX], STRING_TAG_LENGTH);
        _plistAppendUTF8CString(xmlString, ">\n");
    } else if (typeID == _CFKeyedArchiverUIDGetTypeID()) {
        // This is only used for the keyed archiver
        _plistAppendUTF8CString(xmlString, "<");
        _plistAppendCharacters(xmlString, CFXMLPlistTagsUnicode[DICT_IX], DICT_TAG_LENGTH);
        _plistAppendUTF8CString(xmlString, ">\n");
	    _appendIndents(indentation+1, xmlString);
	    _plistAppendUTF8CString(xmlString, "<");
	    _plistAppendCharacters(xmlString, CFXMLPlistTagsUnicode[KEY_IX], KEY_TAG_LENGTH);
	    _plistAppendUTF8CString(xmlString, ">");
	    _appendEscapedString(CFSTR("CF$UID"), xmlString);
	    _plistAppendUTF8CString(xmlString, "</");
	    _plistAppendCharacters(xmlString, CFXMLPlistTagsUnicode[KEY_IX], KEY_TAG_LENGTH);
	    _plistAppendUTF8CString(xmlString, ">\n");
	    _appendIndents(indentation + 1, xmlString);
            _plistAppendUTF8CString(xmlString, "<");
            _plistAppendCharacters(xmlString, CFXMLPlistTagsUnicode[INTEGER_IX], INTEGER_TAG_LENGTH);
            _plistAppendUTF8CString(xmlString, ">");

	    uint64_t v = _CFKeyedArchiverUIDGetValue((CFKeyedArchiverUIDRef)object);
	    CFNumberRef num = CFNumberCreate(kCFAllocatorSystemDefault, kCFNumberSInt64Type, &v);
            _plistAppendFormat(xmlString, CFSTR("%@"), num);
	    CFRelease(num);

            _plistAppendUTF8CString(xmlString, "</");
            _plistAppendCharacters(xmlString, CFXMLPlistTagsUnicode[INTEGER_IX], INTEGER_TAG_LENGTH);
            _plistAppendUTF8CString(xmlString, ">\n");
        _appendIndents(indentation, xmlString);
        _plistAppendUTF8CString(xmlString, "</");
        _plistAppendCharacters(xmlString, CFXMLPlistTagsUnicode[DICT_IX], DICT_TAG_LENGTH);
        _plistAppendUTF8CString(xmlString, ">\n");
    } else if (typeID == arraytype) {
        UInt32 i, count = CFArrayGetCount((CFArrayRef)object);
        if (count == 0) {
            _plistAppendUTF8CString(xmlString, "<");
            _plistAppendCharacters(xmlString, CFXMLPlistTagsUnicode[ARRAY_IX], ARRAY_TAG_LENGTH);
            _plistAppendUTF8CString(xmlString, "/>\n");
            return;
        }
        _plistAppendUTF8CString(xmlString, "<");
        _plistAppendCharacters(xmlString, CFXMLPlistTagsUnicode[ARRAY_IX], ARRAY_TAG_LENGTH);
        _plistAppendUTF8CString(xmlString, ">\n");
        for (i = 0; i < count; i ++) {
            _CFAppendXML0(CFArrayGetValueAtIndex((CFArrayRef)object, i), indentation+1, xmlString);
        }
        _appendIndents(indentation, xmlString);
        _plistAppendUTF8CString(xmlString, "</");
        _plistAppendCharacters(xmlString, CFXMLPlistTagsUnicode[ARRAY_IX], ARRAY_TAG_LENGTH);
        _plistAppendUTF8CString(xmlString, ">\n");
    } else if (typeID == dicttype) {
        UInt32 i, count = CFDictionaryGetCount((CFDictionaryRef)object);
        CFMutableArrayRef keyArray;
        if (count == 0) {
            _plistAppendUTF8CString(xmlString, "<");
            _plistAppendCharacters(xmlString, CFXMLPlistTagsUnicode[DICT_IX], DICT_TAG_LENGTH);
            _plistAppendUTF8CString(xmlString, "/>\n");
            return;
        }
        _plistAppendUTF8CString(xmlString, "<");
        _plistAppendCharacters(xmlString, CFXMLPlistTagsUnicode[DICT_IX], DICT_TAG_LENGTH);
        _plistAppendUTF8CString(xmlString, ">\n");
        new_cftype_array(keys, count);
        CFDictionaryGetKeysAndValues((CFDictionaryRef)object, keys, NULL);
        keyArray = CFArrayCreateMutable(kCFAllocatorSystemDefault, count, &kCFTypeArrayCallBacks);
        CFArrayReplaceValues(keyArray, CFRangeMake(0, 0), keys, count);
        CFArraySortValues(keyArray, CFRangeMake(0, count), (CFComparatorFunction)CFStringCompare, NULL);
        CFArrayGetValues(keyArray, CFRangeMake(0, count), keys);
        CFRelease(keyArray);
        for (i = 0; i < count; i ++) {
            CFTypeRef key = keys[i];
            _appendIndents(indentation+1, xmlString);
            _plistAppendUTF8CString(xmlString, "<");
            _plistAppendCharacters(xmlString, CFXMLPlistTagsUnicode[KEY_IX], KEY_TAG_LENGTH);
            _plistAppendUTF8CString(xmlString, ">");
	    _appendEscapedString((CFStringRef)key, xmlString);
            _plistAppendUTF8CString(xmlString, "</");
            _plistAppendCharacters(xmlString, CFXMLPlistTagsUnicode[KEY_IX], KEY_TAG_LENGTH);
            _plistAppendUTF8CString(xmlString, ">\n");
            _CFAppendXML0(CFDictionaryGetValue((CFDictionaryRef)object, key), indentation+1, xmlString);
        }
        free_cftype_array(keys);
        _appendIndents(indentation, xmlString);
        _plistAppendUTF8CString(xmlString, "</");
        _plistAppendCharacters(xmlString, CFXMLPlistTagsUnicode[DICT_IX], DICT_TAG_LENGTH);
        _plistAppendUTF8CString(xmlString, ">\n");
    } else if (typeID == datatype) {
        _plistAppendUTF8CString(xmlString, "<");
        _plistAppendCharacters(xmlString, CFXMLPlistTagsUnicode[DATA_IX], DATA_TAG_LENGTH);
        _plistAppendUTF8CString(xmlString, ">\n");
        _XMLPlistAppendDataUsingBase64(xmlString, (CFDataRef)object, indentation);       
        _appendIndents(indentation, xmlString);
        _plistAppendUTF8CString(xmlString, "</");
        _plistAppendCharacters(xmlString, CFXMLPlistTagsUnicode[DATA_IX], DATA_TAG_LENGTH);
        _plistAppendUTF8CString(xmlString, ">\n");
    } else if (typeID == datetype) {
        // YYYY '-' MM '-' DD 'T' hh ':' mm ':' ss 'Z'
	int32_t y = 0, M = 0, d = 0, H = 0, m = 0, s = 0;
        CFAbsoluteTime at = CFDateGetAbsoluteTime((CFDateRef)object);
#if 0
        // Alternative to the CFAbsoluteTimeGetGregorianDate() code which works well
        struct timeval tv;
        struct tm mine;
        tv.tv_sec = floor(at + kCFAbsoluteTimeIntervalSince1970);
        gmtime_r(&tv.tv_sec, &mine);
	y = mine.tm_year + 1900;
	M = mine.tm_mon + 1;
	d = mine.tm_mday;
	H = mine.tm_hour;
	m = mine.tm_min;
	s = mine.tm_sec;
#endif

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated"
        CFGregorianDate date = CFAbsoluteTimeGetGregorianDate(at, NULL);
#pragma GCC diagnostic pop

#if 0
if (date.year != y || date.month != M || date.day != d || date.hour != H || date.minute != m || (int32_t)date.second != s) {
    CFLog(4, CFSTR("DATE ERROR {%d, %d, %d, %d, %d, %d} != {%d,  %d, %d, %d, %d, %d}\n"), (int)date.year, (int)date.month, (int)date.day, (int)date.hour, (int)date.minute, (int32_t)date.second, y, M, d, H, m, s);
}
#endif
        y = date.year;
        M = date.month;
        d = date.day;
        H = date.hour;
        m = date.minute;
        s = (int32_t)date.second;

        _plistAppendUTF8CString(xmlString, "<");
        _plistAppendCharacters(xmlString, CFXMLPlistTagsUnicode[DATE_IX], DATE_TAG_LENGTH);
        _plistAppendUTF8CString(xmlString, ">");
        _plistAppendFormat(xmlString, CFSTR("%04d-%02d-%02dT%02d:%02d:%02dZ"), y, M, d, H, m, s);
        _plistAppendUTF8CString(xmlString, "</");
        _plistAppendCharacters(xmlString, CFXMLPlistTagsUnicode[DATE_IX], DATE_TAG_LENGTH);
        _plistAppendUTF8CString(xmlString, ">\n");
    } else if (typeID == numbertype) {
        if (CFNumberIsFloatType((CFNumberRef)object)) {
            _plistAppendUTF8CString(xmlString, "<");
            _plistAppendCharacters(xmlString, CFXMLPlistTagsUnicode[REAL_IX], REAL_TAG_LENGTH);
            _plistAppendUTF8CString(xmlString, ">");
                CFStringRef s = __CFNumberCopyFormattingDescriptionAsFloat64(object);
                _plistAppendString(xmlString, s);
                CFRelease(s);
            _plistAppendUTF8CString(xmlString, "</");
            _plistAppendCharacters(xmlString, CFXMLPlistTagsUnicode[REAL_IX], REAL_TAG_LENGTH);
            _plistAppendUTF8CString(xmlString, ">\n");
        } else {
            _plistAppendUTF8CString(xmlString, "<");
            _plistAppendCharacters(xmlString, CFXMLPlistTagsUnicode[INTEGER_IX], INTEGER_TAG_LENGTH);
            _plistAppendUTF8CString(xmlString, ">");

            _plistAppendFormat(xmlString, CFSTR("%@"), object);

            _plistAppendUTF8CString(xmlString, "</");
            _plistAppendCharacters(xmlString, CFXMLPlistTagsUnicode[INTEGER_IX], INTEGER_TAG_LENGTH);
            _plistAppendUTF8CString(xmlString, ">\n");
        }
    } else if (typeID == booltype) {
        if (CFBooleanGetValue((CFBooleanRef)object)) {
            _plistAppendUTF8CString(xmlString, "<");
            _plistAppendCharacters(xmlString, CFXMLPlistTagsUnicode[TRUE_IX], TRUE_TAG_LENGTH);
            _plistAppendUTF8CString(xmlString, "/>\n");
        } else {
            _plistAppendUTF8CString(xmlString, "<");
            _plistAppendCharacters(xmlString, CFXMLPlistTagsUnicode[FALSE_IX], FALSE_TAG_LENGTH);
            _plistAppendUTF8CString(xmlString, "/>\n");
        }
    }
}

static void _CFGenerateXMLPropertyListToData(CFMutableDataRef xml, CFTypeRef propertyList) {
    _plistAppendUTF8CString(xml, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE ");
    _plistAppendCharacters(xml, CFXMLPlistTagsUnicode[PLIST_IX], PLIST_TAG_LENGTH);
    _plistAppendUTF8CString(xml, " PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<");
    _plistAppendCharacters(xml, CFXMLPlistTagsUnicode[PLIST_IX], PLIST_TAG_LENGTH);
    _plistAppendUTF8CString(xml, " version=\"1.0\">\n");

    _CFAppendXML0(propertyList, 0, xml);

    _plistAppendUTF8CString(xml, "</");
    _plistAppendCharacters(xml, CFXMLPlistTagsUnicode[PLIST_IX], PLIST_TAG_LENGTH);
    _plistAppendUTF8CString(xml, ">\n");
}

// ========================================================================
#pragma mark -
#pragma mark Exported Creation Functions

CFDataRef _CFPropertyListCreateXMLData(CFAllocatorRef allocator, CFPropertyListRef propertyList, Boolean checkValidPlist) {
    initStatics();
    CFMutableDataRef xml;
    CFAssert1(propertyList != NULL, __kCFLogAssertion, "%s(): Cannot be called with a NULL property list", __PRETTY_FUNCTION__);
    if (checkValidPlist && !CFPropertyListIsValid(propertyList, kCFPropertyListXMLFormat_v1_0)) {
        __CFAssertIsPList(propertyList);
        return NULL;
    }
    xml = CFDataCreateMutable(allocator, 0);
    _CFGenerateXMLPropertyListToData(xml, propertyList);
    return xml;
}

CFDataRef CFPropertyListCreateXMLData(CFAllocatorRef allocator, CFPropertyListRef propertyList) {
    return _CFPropertyListCreateXMLData(allocator, propertyList, true);
}

CF_EXPORT CFDataRef _CFPropertyListCreateXMLDataWithExtras(CFAllocatorRef allocator, CFPropertyListRef propertyList) {
    return _CFPropertyListCreateXMLData(allocator, propertyList, false);
}

Boolean CFPropertyListIsValid(CFPropertyListRef plist, CFPropertyListFormat format) {
    initStatics();
    CFAssert1(plist != NULL, __kCFLogAssertion, "%s(): NULL is not a property list", __PRETTY_FUNCTION__);
    return __CFPropertyListIsValidAux(plist, true, NULL, format, NULL);
#if defined(DEBUG)
    CFStringRef error = NULL;
    bool result = __CFPropertyListIsValidAux(plist, true, NULL, format, &error);
    if (error) {
	CFLog(kCFLogLevelWarning, CFSTR("CFPropertyListIsValid(): %@"), error);
	CFRelease(error);
    }
    return result;
#endif
}

// ========================================================================
#pragma mark -
#pragma mark Reading Plists

//
// ------------------------- Reading plists ------------------
// 

static void skipInlineDTD(_CFXMLPlistParseInfo *pInfo);
static Boolean parseXMLElement(_CFXMLPlistParseInfo *pInfo, Boolean *isKey, CFTypeRef *out);

// warning: doesn't have a good idea of Unicode line separators
static UInt32 lineNumber(_CFXMLPlistParseInfo *pInfo) {
    const char *p = pInfo->begin;
    UInt32 count = 1;
    while (p < pInfo->curr) {
        if (*p == '\r') {
            count ++;
            if (*(p + 1) == '\n')
                p ++;
        } else if (*p == '\n') {
            count ++;
        }
        p ++;
    }
    return count;
}

// warning: doesn't have a good idea of Unicode white space
CF_INLINE void skipWhitespace(_CFXMLPlistParseInfo *pInfo) {
    while (pInfo->curr < pInfo->end) {
        switch (*(pInfo->curr)) {
            case ' ':
            case '\t':
            case '\n':
            case '\r':
                pInfo->curr ++;
                continue;
            default:
                return;
        }
    }
}

/* All of these advance to the end of the given construct and return a pointer to the first character beyond the construct.  If the construct doesn't parse properly, NULL is returned. */

// pInfo should be just past "<!--"
static void skipXMLComment(_CFXMLPlistParseInfo *pInfo) {
    const char *p = pInfo->curr;
    const char *end = pInfo->end - 3; // Need at least 3 characters to compare against
    while (p < end) {
        if (*p == '-' && *(p+1) == '-' && *(p+2) == '>') {
            pInfo->curr = p+3;
            return;
        }
        p ++; 
    }
    pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Unterminated comment started on line %d"), lineNumber(pInfo));
}

// pInfo should be set to the first character after "<?"
static void skipXMLProcessingInstruction(_CFXMLPlistParseInfo *pInfo) {
    const char *begin = pInfo->curr, *end = pInfo->end - 2; // Looking for "?>" so we need at least 2 characters
    while (pInfo->curr < end) {
        if (*(pInfo->curr) == '?' && *(pInfo->curr+1) == '>') {
            pInfo->curr += 2;
            return;
        }
        pInfo->curr ++; 
    }
    pInfo->curr = begin;
    pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Encountered unexpected EOF while parsing the processing instruction begun on line %d"), lineNumber(pInfo));
}

// first character should be immediately after the "<!"
static void skipDTD(_CFXMLPlistParseInfo *pInfo) {
    // First pass "DOCTYPE"
    if (pInfo->end - pInfo->curr < DOCTYPE_TAG_LENGTH || memcmp(pInfo->curr, CFXMLPlistTags[DOCTYPE_IX], DOCTYPE_TAG_LENGTH)) {
        pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Malformed DTD on line %d"), lineNumber(pInfo));
        return;
    }
    pInfo->curr += DOCTYPE_TAG_LENGTH;
    skipWhitespace(pInfo);

    // Look for either the beginning of a complex DTD or the end of the DOCTYPE structure
    while (pInfo->curr < pInfo->end) {
        char ch = *(pInfo->curr);
        if (ch == '[') break; // inline DTD
        if (ch == '>') {  // End of the DTD
            pInfo->curr ++;
            return;
        }
        pInfo->curr ++;
    }
    if (pInfo->curr == pInfo->end) {
        pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Encountered unexpected EOF while parsing DTD"));
        return;
    }

    // *Sigh* Must parse in-line DTD
    skipInlineDTD(pInfo);
    if (pInfo->error)  return;
    skipWhitespace(pInfo);
    if (pInfo->error) return;
    if (pInfo->curr < pInfo->end) {
        if (*(pInfo->curr) == '>') {
            pInfo->curr ++;
        } else {
            pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Encountered unexpected character %c on line %d while parsing DTD"), *(pInfo->curr), lineNumber(pInfo));
        }
    } else {
        pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Encountered unexpected EOF while parsing DTD"));
    }
}

static void skipPERef(_CFXMLPlistParseInfo *pInfo) {
    const char *p = pInfo->curr;
    while (p < pInfo->end) {
        if (*p == ';') {
            pInfo->curr = p+1;
            return;
        }
        p ++;
    }
    pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Encountered unexpected EOF while parsing percent-escape sequence begun on line %d"), lineNumber(pInfo));
}

// First character should be just past '['
static void skipInlineDTD(_CFXMLPlistParseInfo *pInfo) {
    while (!pInfo->error && pInfo->curr < pInfo->end) {
        UniChar ch;
        skipWhitespace(pInfo);
        ch = *pInfo->curr;
        if (ch == '%') {
            pInfo->curr ++;
            skipPERef(pInfo);
        } else if (ch == '<') {
            pInfo->curr ++;
            if (pInfo->curr >= pInfo->end) {
                pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Encountered unexpected EOF while parsing inline DTD"));
                return;
            }
            ch = *(pInfo->curr);
            if (ch == '?') {
                pInfo->curr ++;
                skipXMLProcessingInstruction(pInfo);
            } else if (ch == '!') {
                if (pInfo->curr + 2 < pInfo->end && (*(pInfo->curr+1) == '-' && *(pInfo->curr+2) == '-')) {
                    pInfo->curr += 3;
                    skipXMLComment(pInfo);
                } else {
                    // Skip the myriad of DTD declarations of the form "<!string" ... ">"
                    pInfo->curr ++; // Past both '<' and '!'
                    while (pInfo->curr < pInfo->end) {
                        if (*(pInfo->curr) == '>') break;
                        pInfo->curr ++;
                    }
                    if (*(pInfo->curr) != '>') {
                        pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Encountered unexpected EOF while parsing inline DTD"));
                        return;
                    }
                    pInfo->curr ++;
                }
            } else {
                pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Encountered unexpected character %c on line %d while parsing inline DTD"), ch, lineNumber(pInfo));
                return;
            }
        } else if (ch == ']') {
            pInfo->curr ++;
            return;
        } else {
            pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Encountered unexpected character %c on line %d while parsing inline DTD"), ch, lineNumber(pInfo));
            return;
        }
    }
    if (!pInfo->error) {
        pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Encountered unexpected EOF while parsing inline DTD"));
    }
}

// content ::== (element | CharData | Reference | CDSect | PI | Comment)*
// In the context of a plist, CharData, Reference and CDSect are not legal (they all resolve to strings).  Skipping whitespace, then, the next character should be '<'.  From there, we figure out which of the three remaining cases we have (element, PI, or Comment).
static Boolean getContentObject(_CFXMLPlistParseInfo *pInfo, Boolean *isKey, CFTypeRef *out) {
    if (isKey) *isKey = false;
    while (!pInfo->error && pInfo->curr < pInfo->end) {
        skipWhitespace(pInfo);
        if (pInfo->curr >= pInfo->end) {
            pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Encountered unexpected EOF"));
            return false;
        }
        if (*(pInfo->curr) != '<') {
            pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Encountered unexpected character %c on line %d while looking for open tag"), *(pInfo->curr), lineNumber(pInfo));
            return false;
        }
        pInfo->curr ++;
        if (pInfo->curr >= pInfo->end) {
            pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Encountered unexpected EOF"));
            return false;
        }
        switch (*(pInfo->curr)) {
            case '?':
                // Processing instruction
                skipXMLProcessingInstruction(pInfo);
                break;
            case '!':
                // Could be a comment
                if (pInfo->curr+2 >= pInfo->end) {
                    pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Encountered unexpected EOF"));
                    return false;
                }
                if (*(pInfo->curr+1) == '-' && *(pInfo->curr+2) == '-') {
                    pInfo->curr += 2;
                    skipXMLComment(pInfo);
                } else {
                    pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Encountered unexpected EOF"));
                    return false;
                }
                break;
            case '/':
                // Whoops!  Looks like we got to the end tag for the element whose content we're parsing
                pInfo->curr --; // Back off to the '<'
                return false;
            default:
                // Should be an element
                return parseXMLElement(pInfo, isKey, out);
        }
    }
    // Do not set the error string here; if it wasn't already set by one of the recursive parsing calls, the caller will quickly detect the failure (b/c pInfo->curr >= pInfo->end) and provide a more useful one of the form "end tag for <blah> not found"
    return false;
}

static void parseCDSect_pl(_CFXMLPlistParseInfo *pInfo, CFMutableDataRef stringData) {
    const char *end, *begin;
    if (pInfo->end - pInfo->curr < CDSECT_TAG_LENGTH) {
        pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Encountered unexpected EOF"));
        return;
    }
    if (memcmp(pInfo->curr, CFXMLPlistTags[CDSECT_IX], CDSECT_TAG_LENGTH)) {
        pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Encountered improper CDATA opening at line %d"), lineNumber(pInfo));
        return;
    }
    pInfo->curr += CDSECT_TAG_LENGTH;
    begin = pInfo->curr; // Marks the first character of the CDATA content
    end = pInfo->end-2; // So we can safely look 2 characters beyond p
    while (pInfo->curr < end) {
        if (*(pInfo->curr) == ']' && *(pInfo->curr+1) == ']' && *(pInfo->curr+2) == '>') {
            // Found the end!
            CFDataAppendBytes(stringData, (const UInt8 *)begin, pInfo->curr-begin);
            pInfo->curr += 3;
            return;
        }
        pInfo->curr ++;
    }
    // Never found the end mark
    pInfo->curr = begin;
    pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Could not find end of CDATA started on line %d"), lineNumber(pInfo));
}

// Only legal references are {lt, gt, amp, apos, quote, #ddd, #xAAA}
static void parseEntityReference_pl(_CFXMLPlistParseInfo *pInfo, CFMutableDataRef stringData) {
    int len;
    pInfo->curr ++; // move past the '&';
    len = pInfo->end - pInfo->curr; // how many bytes we can safely scan
    if (len < 1) {
        pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Encountered unexpected EOF"));
        return;
    }

    char ch;
    switch (*(pInfo->curr)) {
        case 'l':  // "lt"
            if (len >= 3 && *(pInfo->curr+1) == 't' && *(pInfo->curr+2) == ';') {
                ch = '<';
                pInfo->curr += 3;
                break;
            }
            pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Encountered unknown ampersand-escape sequence at line %d"), lineNumber(pInfo));
            return;
        case 'g': // "gt"
            if (len >= 3 && *(pInfo->curr+1) == 't' && *(pInfo->curr+2) == ';') {
                ch = '>';
                pInfo->curr += 3;
                break;
            }
            pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Encountered unknown ampersand-escape sequence at line %d"), lineNumber(pInfo));
            return;
        case 'a': // "apos" or "amp"
            if (len < 4) {   // Not enough characters for either conversion
                pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Encountered unexpected EOF"));
                return;
            }
            if (*(pInfo->curr+1) == 'm') {
                // "amp"
                if (*(pInfo->curr+2) == 'p' && *(pInfo->curr+3) == ';') {
                    ch = '&';
                    pInfo->curr += 4;
                    break;
                }
            } else if (*(pInfo->curr+1) == 'p') {
                // "apos"
                if (len > 4 && *(pInfo->curr+2) == 'o' && *(pInfo->curr+3) == 's' && *(pInfo->curr+4) == ';') {
                    ch = '\'';
                    pInfo->curr += 5;
                    break;
                }
            }
            pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Encountered unknown ampersand-escape sequence at line %d"), lineNumber(pInfo));
            return;
        case 'q':  // "quote"
            if (len >= 5 && *(pInfo->curr+1) == 'u' && *(pInfo->curr+2) == 'o' && *(pInfo->curr+3) == 't' && *(pInfo->curr+4) == ';') {
                ch = '\"';
                pInfo->curr += 5;
                break;
            }
            pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Encountered unknown ampersand-escape sequence at line %d"), lineNumber(pInfo));
            return;
        case '#':
        {
            uint32_t num = 0;
            Boolean isHex = false;
            if ( len < 4) {  // Not enough characters to make it all fit!  Need at least "&#d;"
                pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Encountered unexpected EOF"));
                return;
            }
            pInfo->curr ++;
            if (*(pInfo->curr) == 'x') {
                isHex = true;
                pInfo->curr ++;
            }
            int numberOfCharactersSoFar = 0;
            while (pInfo->curr < pInfo->end) {
                ch = *(pInfo->curr);
                pInfo->curr ++;
                numberOfCharactersSoFar++;
                if (ch == ';') {
                    // The value in num always refers to the unicode code point. We'll have to convert since the calling function expects UTF8 data. Swap to BE always so we know what encoding to use.
                    num = CFSwapInt32HostToBig(num);
                    CFStringRef oneChar = CFStringCreateWithBytes(pInfo->allocator, (const uint8_t *)&num, sizeof(num), kCFStringEncodingUTF32BE, NO);
                    if (!oneChar) {
                        pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Encountered unparseable Unicode sequence at line %d while parsing data (input did not result in a real string)"), lineNumber(pInfo));
                        return;
                    }
                    uint8_t tmpBuf[6]; // max of 6 bytes for UTF8
                    CFIndex tmpBufLength = 0;
                    CFStringGetBytes(oneChar, CFRangeMake(0, CFStringGetLength(oneChar)), kCFStringEncodingUTF8, 0, NO, tmpBuf, 6, &tmpBufLength);
                    CFDataAppendBytes(stringData, tmpBuf, tmpBufLength);
                    __CFPListRelease(oneChar, pInfo->allocator);
                    return;
                } else if (numberOfCharactersSoFar > 8) {
                    pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Encountered unparseable unicode sequence at line %d while parsing data (too large of a value for a Unicode sequence)"), lineNumber(pInfo));
                    return;
                }
                if (!isHex) num = num*10;
                else num = num << 4;
                if (ch <= '9' && ch >= '0') {
                    num += (ch - '0');
                } else if (!isHex) {
                    pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Encountered unexpected character %c at line %d while parsing data"), ch, lineNumber(pInfo));
                    return;
                } else if (ch >= 'a' && ch <= 'f') {
                    num += 10 + (ch - 'a');
                } else if (ch >= 'A' && ch <= 'F') {
                    num += 10 + (ch - 'A');
                } else {
                    pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Encountered unexpected character %c at line %d while parsing data"), ch, lineNumber(pInfo));
                    return;                    
                }
            }
            pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Encountered unexpected EOF"));
            return;
        }
        default:
            pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Encountered unknown ampersand-escape sequence at line %d"), lineNumber(pInfo));
            return;
    }
    CFDataAppendBytes(stringData, (const UInt8 *)&ch, 1);
}

static void _createStringMap(_CFXMLPlistParseInfo *pInfo) {
    pInfo->stringTrie = CFBurstTrieCreate();
    pInfo->stringCache = CFArrayCreateMutable(pInfo->allocator, 0, &kCFTypeArrayCallBacks);
}

static void _cleanupStringMap(_CFXMLPlistParseInfo *pInfo) {
    CFBurstTrieRelease(pInfo->stringTrie);
    CFRelease(pInfo->stringCache);
    pInfo->stringTrie = NULL;
    pInfo->stringCache = NULL;
}

static CFStringRef _createUniqueStringWithUTF8Bytes(_CFXMLPlistParseInfo *pInfo, const char *base, CFIndex length) {
    if (length == 0) return (CFStringRef)CFRetain(CFSTR(""));
    
    CFStringRef result = NULL;
    uint32_t payload = 0;
    Boolean uniqued = CFBurstTrieContainsUTF8String(pInfo->stringTrie, (UInt8 *)base, length, &payload);
    if (uniqued && payload > 0) {
        // The index is at payload - 1 (see below).
        result = (CFStringRef)CFArrayGetValueAtIndex(pInfo->stringCache, (CFIndex)payload - 1);
        CFRetain(result);
    } else {
        result = CFStringCreateWithBytes(pInfo->allocator, (const UInt8 *)base, length, kCFStringEncodingUTF8, NO);
        if (!result) return NULL;
        // Payload must be >0, so the actual index of the value is at payload - 1
        // We also get add to the array after we make sure that CFBurstTrieAddUTF8String succeeds (it can fail, if the string is too large, for example)
        payload = CFArrayGetCount(pInfo->stringCache) + 1;
        Boolean didAddToBurstTrie = CFBurstTrieAddUTF8String(pInfo->stringTrie, (UInt8 *)base, length, payload);
        if (didAddToBurstTrie) {
            CFArrayAppendValue(pInfo->stringCache, result);
        }
    }
    return result;
}

// String could be comprised of characters, CDSects, or references to one of the "well-known" entities ('<', '>', '&', ''', '"')
static Boolean parseStringTag(_CFXMLPlistParseInfo *pInfo, CFStringRef *out) {
    const char *mark = pInfo->curr;
    CFMutableDataRef stringData = NULL;
    while (!pInfo->error && pInfo->curr < pInfo->end) {
        char ch = *(pInfo->curr);
        if (ch == '<') {
	    if (pInfo->curr + 1 >= pInfo->end) break;
            // Could be a CDSect; could be the end of the string
            if (*(pInfo->curr+1) != '!') break; // End of the string
            if (!stringData) stringData = CFDataCreateMutable(pInfo->allocator, 0);
            CFDataAppendBytes(stringData, (const UInt8 *)mark, pInfo->curr - mark);
            parseCDSect_pl(pInfo, stringData); // TODO: move to return boolean
            mark = pInfo->curr;
        } else if (ch == '&') {
            if (!stringData) stringData = CFDataCreateMutable(pInfo->allocator, 0);
            CFDataAppendBytes(stringData, (const UInt8 *)mark, pInfo->curr - mark);
            parseEntityReference_pl(pInfo, stringData); // TODO: move to return boolean
            mark = pInfo->curr;
        } else {
            pInfo->curr ++;
        }
    }

    if (pInfo->error) {
        __CFPListRelease(stringData, pInfo->allocator);
        return false;
    }
        
    if (!stringData) {
        if (pInfo->skip) {
            *out = NULL;
        } else {
            if (pInfo->mutabilityOption != kCFPropertyListMutableContainersAndLeaves) {
                CFStringRef s = _createUniqueStringWithUTF8Bytes(pInfo, mark, pInfo->curr - mark);
                if (!s) {
                    pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Unable to convert string to correct encoding"));
                    return false;
                }                    
                *out = s;
            } else {
                CFStringRef s = CFStringCreateWithBytes(pInfo->allocator, (const UInt8 *)mark, pInfo->curr - mark, kCFStringEncodingUTF8, NO);
                if (!s) {
                    pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Unable to convert string to correct encoding"));
                    return false;
                }
                *out = CFStringCreateMutableCopy(pInfo->allocator, 0, s);
                __CFPListRelease(s, pInfo->allocator);
            }
        }
        return true;
    } else {
        if (pInfo->skip) {
            *out = NULL;
        } else {
            CFDataAppendBytes(stringData, (const UInt8 *)mark, pInfo->curr - mark);
            if (pInfo->mutabilityOption != kCFPropertyListMutableContainersAndLeaves) {
                CFStringRef s = _createUniqueStringWithUTF8Bytes(pInfo, (const char *)CFDataGetBytePtr(stringData), CFDataGetLength(stringData));
                if (!s) {
                    CFRelease(stringData);
                    pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Unable to convert string to correct encoding"));
                    return false;
                }
                *out = s;
            } else {
                CFStringRef s = CFStringCreateWithBytes(pInfo->allocator, (const UInt8 *)CFDataGetBytePtr(stringData), CFDataGetLength(stringData), kCFStringEncodingUTF8, NO);
                if (!s) {
                    CFRelease(stringData);
                    pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Unable to convert string to correct encoding"));
                    return false;
                }
                *out = CFStringCreateMutableCopy(pInfo->allocator, 0, s);
                __CFPListRelease(s, pInfo->allocator);
            }
        }
        __CFPListRelease(stringData, pInfo->allocator);
        return true;
    }
}

static Boolean checkForCloseTag(_CFXMLPlistParseInfo *pInfo, const char *tag, CFIndex tagLen) {
    if (pInfo->end - pInfo->curr < tagLen + 3) {
        if (!pInfo->error) {
            pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Encountered unexpected EOF"));
        }
        return false;
    }
    if (*(pInfo->curr) != '<' || *(++pInfo->curr) != '/') {
        if (!pInfo->error) {
            pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Encountered unexpected character %c on line %d while looking for close tag"), *(pInfo->curr), lineNumber(pInfo));
        }
        return false;
    }
    pInfo->curr ++;
    if (memcmp(pInfo->curr, tag, tagLen)) {
        CFStringRef str = CFStringCreateWithBytes(kCFAllocatorSystemDefault, (const UInt8 *)tag, tagLen, kCFStringEncodingUTF8, NO);
        if (!pInfo->error) {
            pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Close tag on line %d does not match open tag %@"), lineNumber(pInfo), str);
        }
        CFRelease(str);
        return false;
    }
    pInfo->curr += tagLen;
    skipWhitespace(pInfo);
    if (pInfo->curr == pInfo->end) {
        if (!pInfo->error) {
            pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Encountered unexpected EOF"));
        }
        return false;
    }
    if (*(pInfo->curr) != '>') {
        if (!pInfo->error) {
            pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Encountered unexpected character %c on line %d while looking for close tag"), *(pInfo->curr), lineNumber(pInfo));
        }
        return false;
    }
    pInfo->curr ++;
    return true;
}

// pInfo should be set to the first content character of the <plist>
static Boolean parsePListTag(_CFXMLPlistParseInfo *pInfo, CFTypeRef *out) {
    CFTypeRef result = NULL;
    if (!getContentObject(pInfo, NULL, &result)) {
        if (!pInfo->error) pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Encountered empty plist tag"));
        return false;
    }
    const char *save = pInfo->curr; // Save this in case the next step fails
    CFTypeRef tmp = NULL;
    if (getContentObject(pInfo, NULL, &tmp)) {
        // Got an extra object
        __CFPListRelease(tmp, pInfo->allocator);
        __CFPListRelease(result, pInfo->allocator);
        pInfo->curr = save;
        pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Encountered unexpected element at line %d (plist can only include one object)"), lineNumber(pInfo));
        return false;
    }
    if (pInfo->error) {
        // Parse failed catastrophically
        __CFPListRelease(result, pInfo->allocator);
        return false;
    }
    if (!checkForCloseTag(pInfo, CFXMLPlistTags[PLIST_IX], PLIST_TAG_LENGTH)) {
        __CFPListRelease(result, pInfo->allocator);
        return false;
    }
    *out = result;
    return true;
}

static int allowImmutableCollections = -1;

static void checkImmutableCollections(void) {
    allowImmutableCollections = (NULL == __CFgetenv("CFPropertyListAllowImmutableCollections")) ? 0 : 1;
}

// This converts the input value, a set of strings, into the form that's efficient for using during recursive decent parsing, a set of arrays
static CFSetRef createTopLevelKeypaths(CFAllocatorRef allocator, CFSetRef keyPaths) {
    if (!keyPaths) return NULL;
    
    CFIndex count = CFSetGetCount(keyPaths);
    new_cftype_array(keyPathValues, count);
    CFSetGetValues(keyPaths, keyPathValues);
    CFMutableSetRef splitKeyPathSet = CFSetCreateMutable(allocator, count, &kCFTypeSetCallBacks);
    for (CFIndex i = 0; i < count; i++) {
        // Split each key path and add it to the split path set, which we will reference throughout parsing
        CFArrayRef split = CFStringCreateArrayBySeparatingStrings(allocator, (CFStringRef)(keyPathValues[i]), CFSTR(":"));
        CFSetAddValue(splitKeyPathSet, split);
        __CFPListRelease(split, allocator);
    }
    free_cftype_array(keyPathValues);
    return splitKeyPathSet;
}

// This splits up the keypaths into the ones relevant for this level (of array or dictionary), and the ones for the next level (of array or dictionary)
CF_PRIVATE void __CFPropertyListCreateSplitKeypaths(CFAllocatorRef allocator, CFSetRef currentKeys, CFSetRef *theseKeys, CFSetRef *nextKeys) {
    if (!currentKeys) { *theseKeys = NULL; *nextKeys = NULL; return; }
    
    CFIndex count = CFSetGetCount(currentKeys);
    
    // For each array in the current key path set, grab the item at the start of the list and put it into theseKeys. The rest of the array goes into nextKeys.
    CFMutableSetRef outTheseKeys = NULL;
    CFMutableSetRef outNextKeys = NULL;
    
    new_cftype_array(currentKeyPaths, count);
    CFSetGetValues(currentKeys, currentKeyPaths);
    for (CFIndex i = 0; i < count; i++) {
        CFArrayRef oneKeyPath = (CFArrayRef)currentKeyPaths[i];
        CFIndex keyPathCount = CFArrayGetCount(oneKeyPath);
        
        if (keyPathCount > 0) {
            if (!outTheseKeys) outTheseKeys = CFSetCreateMutable(allocator, 0, &kCFTypeSetCallBacks);
            
            CFSetAddValue(outTheseKeys, CFArrayGetValueAtIndex(oneKeyPath, 0));
        }
        
        if (keyPathCount > 1) {
            if (!outNextKeys) outNextKeys = CFSetCreateMutable(allocator, 0, &kCFTypeSetCallBacks);
            
            // Create an array with values from 1 - end of list
            new_cftype_array(restOfKeys, keyPathCount - 1);
            CFArrayGetValues(oneKeyPath, CFRangeMake(1, CFArrayGetCount(oneKeyPath) - 1), restOfKeys);
            CFArrayRef newNextKeys = CFArrayCreate(allocator, restOfKeys, CFArrayGetCount(oneKeyPath) - 1, &kCFTypeArrayCallBacks);
            CFSetAddValue(outNextKeys, newNextKeys);
            __CFPListRelease(newNextKeys, allocator);
            free_cftype_array(restOfKeys);
            
        }
    }
    
    *theseKeys = outTheseKeys;
    *nextKeys = outNextKeys;
}

static Boolean parseArrayTag(_CFXMLPlistParseInfo *pInfo, CFTypeRef *out) {
    CFTypeRef tmp = NULL;

    if (pInfo->skip) {
        Boolean result = getContentObject(pInfo, NULL, &tmp);
        while (result) {
            if (tmp) {
                // Shouldn't happen (if skipping, all content values should be null), but just in case
                __CFPListRelease(tmp, pInfo->allocator);
            }
            result = getContentObject(pInfo, NULL, &tmp);
        }
        
        if (pInfo->error) {
            // getContentObject encountered a parse error
            return false;
        }
        if (!checkForCloseTag(pInfo, CFXMLPlistTags[ARRAY_IX], ARRAY_TAG_LENGTH)) {
            return false;
        } else {
            *out = NULL;
            return true;
        }
    }
    
    CFMutableArrayRef array = CFArrayCreateMutable(pInfo->allocator, 0, &kCFTypeArrayCallBacks);
    Boolean result;
    
    CFIndex count = 0;
    CFSetRef oldKeyPaths = pInfo->keyPaths;
    CFSetRef newKeyPaths, keys;
    __CFPropertyListCreateSplitKeypaths(pInfo->allocator, pInfo->keyPaths, &keys, &newKeyPaths);
    
    if (keys) {
        CFStringRef countString = CFStringCreateWithFormat(pInfo->allocator, NULL, CFSTR("%ld"), count);
        if (!CFSetContainsValue(keys, countString)) pInfo->skip = true;
        __CFPListRelease(countString, pInfo->allocator);
        count++;
        pInfo->keyPaths = newKeyPaths;
    }
    result = getContentObject(pInfo, NULL, &tmp);
    if (keys) {
        pInfo->keyPaths = oldKeyPaths;
        pInfo->skip = false;
    }

    while (result) {
        if (tmp) {
            CFArrayAppendValue(array, tmp);
            __CFPListRelease(tmp, pInfo->allocator);
        }
        
        if (keys) {
            // prep for getting next object
            CFStringRef countString = CFStringCreateWithFormat(pInfo->allocator, NULL, CFSTR("%ld"), count);
            if (!CFSetContainsValue(keys, countString)) pInfo->skip = true;
            __CFPListRelease(countString, pInfo->allocator);
            count++;
            pInfo->keyPaths = newKeyPaths;
        }
        result = getContentObject(pInfo, NULL, &tmp);
        if (keys) {
            // reset after getting object
            pInfo->keyPaths = oldKeyPaths;
            pInfo->skip = false;
        }

    }
    
    __CFPListRelease(newKeyPaths, pInfo->allocator);
    __CFPListRelease(keys, pInfo->allocator);

    if (pInfo->error) { // getContentObject encountered a parse error
        __CFPListRelease(array, pInfo->allocator);
        return false;
    }
    if (!checkForCloseTag(pInfo, CFXMLPlistTags[ARRAY_IX], ARRAY_TAG_LENGTH)) {
        __CFPListRelease(array, pInfo->allocator);
        return false;
    }
    if (-1 == allowImmutableCollections) {
        checkImmutableCollections();
    }
    if (1 == allowImmutableCollections) {
        if (pInfo->mutabilityOption == kCFPropertyListImmutable) {
            CFArrayRef newArray = CFArrayCreateCopy(pInfo->allocator, array);
            __CFPListRelease(array, pInfo->allocator);
            array = (CFMutableArrayRef)newArray;
        }
    }
    *out = array;
    return true;
}

static Boolean parseDictTag(_CFXMLPlistParseInfo *pInfo, CFTypeRef *out) {
    Boolean gotKey;
    Boolean result;
    CFTypeRef key = NULL, value = NULL;
    
    if (pInfo->skip) {
        result = getContentObject(pInfo, &gotKey, &key);
        while (result) {
            if (!gotKey) { 
                if (!pInfo->error) pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Found non-key inside <dict> at line %d"), lineNumber(pInfo));
                return false;
            }
            result = getContentObject(pInfo, NULL, &value);
            if (!result) { 
                if (!pInfo->error) pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Value missing for key inside <dict> at line %d"), lineNumber(pInfo)); 
                return false; 
            }
            // key and value should be null, but we'll release just in case here
            __CFPListRelease(key, pInfo->allocator);
            key = NULL;
            __CFPListRelease(value, pInfo->allocator);
            value = NULL;            
            result = getContentObject(pInfo, &gotKey, &key);
        }
        if (checkForCloseTag(pInfo, CFXMLPlistTags[DICT_IX], DICT_TAG_LENGTH)) {
            *out = NULL;
            return true;
        } else {
            return false;
        }
    }
    
    CFSetRef oldKeyPaths = pInfo->keyPaths;
    CFSetRef nextKeyPaths, theseKeyPaths;
    __CFPropertyListCreateSplitKeypaths(pInfo->allocator, pInfo->keyPaths, &theseKeyPaths, &nextKeyPaths);
    
    CFMutableDictionaryRef dict = NULL;
    
    result = getContentObject(pInfo, &gotKey, &key);
    while (result && key) {
        if (!gotKey) { 
            if (!pInfo->error) pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Found non-key inside <dict> at line %d"), lineNumber(pInfo)); 
            __CFPListRelease(key, pInfo->allocator);
            __CFPListRelease(nextKeyPaths, pInfo->allocator);
            __CFPListRelease(theseKeyPaths, pInfo->allocator);
            __CFPListRelease(dict, pInfo->allocator);
            return false;
        }
        
        if (theseKeyPaths) {
            if (!CFSetContainsValue(theseKeyPaths, key)) pInfo->skip = true;
            pInfo->keyPaths = nextKeyPaths;
        }
        result = getContentObject(pInfo, NULL, &value);
        if (theseKeyPaths) {
            pInfo->keyPaths = oldKeyPaths;
            pInfo->skip = false;
        }
        
        if (!result) { 
            if (!pInfo->error) pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Value missing for key inside <dict> at line %d"), lineNumber(pInfo)); 
            __CFPListRelease(key, pInfo->allocator);
            __CFPListRelease(nextKeyPaths, pInfo->allocator);
            __CFPListRelease(theseKeyPaths, pInfo->allocator);
            __CFPListRelease(dict, pInfo->allocator);
            return false;
        }
        
        if (key && value) {
            if (NULL == dict) {
                dict = CFDictionaryCreateMutable(pInfo->allocator, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
                _CFDictionarySetCapacity(dict, 10);
            }
            CFDictionarySetValue(dict, key, value);
        }
        
        __CFPListRelease(key, pInfo->allocator);
        key = NULL;
        __CFPListRelease(value, pInfo->allocator);
        value = NULL;
        
        result = getContentObject(pInfo, &gotKey, &key);
    }
    
    __CFPListRelease(nextKeyPaths, pInfo->allocator);
    __CFPListRelease(theseKeyPaths, pInfo->allocator);

    if (checkForCloseTag(pInfo, CFXMLPlistTags[DICT_IX], DICT_TAG_LENGTH)) {
	if (NULL == dict) {
	    if (pInfo->mutabilityOption == kCFPropertyListImmutable) {
		dict = (CFMutableDictionaryRef)CFDictionaryCreate(pInfo->allocator, NULL, NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
	    } else {
		dict = CFDictionaryCreateMutable(pInfo->allocator, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
	    }
	} else {
	    CFIndex cnt = CFDictionaryGetCount(dict);
	    if (1 == cnt) {
		CFTypeRef val = CFDictionaryGetValue(dict, CFSTR("CF$UID"));
		if (val && CFGetTypeID(val) == numbertype) {
		    CFTypeRef uid;
		    uint32_t v;
		    CFNumberGetValue((CFNumberRef)val, kCFNumberSInt32Type, &v);
		    uid = (CFTypeRef)_CFKeyedArchiverUIDCreate(pInfo->allocator, v);
		    __CFPListRelease(dict, pInfo->allocator);
                    *out = uid;
                    return true;
		}
	    }
	    if (-1 == allowImmutableCollections) checkImmutableCollections();
	    if (1 == allowImmutableCollections) {
		if (pInfo->mutabilityOption == kCFPropertyListImmutable) {
		    CFDictionaryRef newDict = CFDictionaryCreateCopy(pInfo->allocator, dict);
		    __CFPListRelease(dict, pInfo->allocator);
		    dict = (CFMutableDictionaryRef)newDict;
		}
	    }
	}
        *out = dict;
        return true;
    }
    
    if (dict) __CFPListRelease(dict, pInfo->allocator);
    return false;
}

static Boolean parseDataTag(_CFXMLPlistParseInfo *pInfo, CFTypeRef *out) {
    const char *base = pInfo->curr;
    static const signed char dataDecodeTable[128] = {
        /* 000 */ -1, -1, -1, -1, -1, -1, -1, -1,
        /* 010 */ -1, -1, -1, -1, -1, -1, -1, -1,
        /* 020 */ -1, -1, -1, -1, -1, -1, -1, -1,
        /* 030 */ -1, -1, -1, -1, -1, -1, -1, -1,
        /* ' ' */ -1, -1, -1, -1, -1, -1, -1, -1,
        /* '(' */ -1, -1, -1, 62, -1, -1, -1, 63,
        /* '0' */ 52, 53, 54, 55, 56, 57, 58, 59,
        /* '8' */ 60, 61, -1, -1, -1,  0, -1, -1,
        /* '@' */ -1,  0,  1,  2,  3,  4,  5,  6,
        /* 'H' */  7,  8,  9, 10, 11, 12, 13, 14,
        /* 'P' */ 15, 16, 17, 18, 19, 20, 21, 22,
        /* 'X' */ 23, 24, 25, -1, -1, -1, -1, -1,
        /* '`' */ -1, 26, 27, 28, 29, 30, 31, 32,
        /* 'h' */ 33, 34, 35, 36, 37, 38, 39, 40,
        /* 'p' */ 41, 42, 43, 44, 45, 46, 47, 48,
        /* 'x' */ 49, 50, 51, -1, -1, -1, -1, -1
    };
    
    int tmpbufpos = 0;
    int tmpbuflen = 256;
    uint8_t *tmpbuf = pInfo->skip ? NULL : (uint8_t *)CFAllocatorAllocate(pInfo->allocator, tmpbuflen, 0);
    int numeq = 0;
    int acc = 0;
    int cntr = 0;
    
    for (; pInfo->curr < pInfo->end; pInfo->curr++) {
        signed char c = *(pInfo->curr);
        if (c == '<') {
            break;
        }
        if ('=' == c) {
            numeq++;
        } else if (!isspace(c)) {
            numeq = 0;
        }
        if (dataDecodeTable[c] < 0)
            continue;
        cntr++;
        acc <<= 6;
        acc += dataDecodeTable[c];
        if (!pInfo->skip && 0 == (cntr & 0x3)) {
            if (tmpbuflen <= tmpbufpos + 2) {
                if (tmpbuflen < 256 * 1024) {
                    tmpbuflen *= 4;
                } else if (tmpbuflen < 16 * 1024 * 1024) {
                    tmpbuflen *= 2;
                } else {
                    // once in this stage, this will be really slow
                    // and really potentially fragment memory
                    tmpbuflen += 256 * 1024;
                }
                tmpbuf = (uint8_t *)CFAllocatorReallocate(pInfo->allocator, tmpbuf, tmpbuflen, 0);
                if (!tmpbuf) HALT; // out of memory
            }
            tmpbuf[tmpbufpos++] = (acc >> 16) & 0xff;
            if (numeq < 2) tmpbuf[tmpbufpos++] = (acc >> 8) & 0xff;
            if (numeq < 1) tmpbuf[tmpbufpos++] = acc & 0xff;
        }
    }
    
    CFDataRef result = NULL;
    if (!pInfo->skip) {
        if (pInfo->mutabilityOption == kCFPropertyListMutableContainersAndLeaves) {
            result = (CFDataRef)CFDataCreateMutable(pInfo->allocator, 0);
            CFDataAppendBytes((CFMutableDataRef)result, tmpbuf, tmpbufpos);
            CFAllocatorDeallocate(pInfo->allocator, tmpbuf);
        } else {
            result = CFDataCreateWithBytesNoCopy(pInfo->allocator, tmpbuf, tmpbufpos, pInfo->allocator);
        }
        if (!result) {
            pInfo->curr = base;
            pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Could not interpret <data> at line %d (should be base64-encoded)"), lineNumber(pInfo));
            return false;
        }
    }
    
    if (checkForCloseTag(pInfo, CFXMLPlistTags[DATA_IX], DATA_TAG_LENGTH)) {
        *out = result;
        return true;
    } else {
        __CFPListRelease(result, pInfo->allocator);
        return false;
    }
}

CF_INLINE Boolean read2DigitNumber(_CFXMLPlistParseInfo *pInfo, int32_t *result) {
    char ch1, ch2;
    if (pInfo->curr + 2 >= pInfo->end) {
        return false;
    }
    ch1 = *pInfo->curr;
    ch2 = *(pInfo->curr + 1);
    pInfo->curr += 2;
    if (!isdigit(ch1) || !isdigit(ch2)) {
        return false;
    }
    *result = (ch1 - '0')*10 + (ch2 - '0');
    return true;
}

// YYYY '-' MM '-' DD 'T' hh ':' mm ':' ss 'Z'
static Boolean parseDateTag(_CFXMLPlistParseInfo *pInfo, CFTypeRef *out) {
    int32_t year = 0, month = 0, day = 0, hour = 0, minute = 0, second = 0;
    int32_t num = 0;
    Boolean badForm = false;
    Boolean yearIsNegative = false;
    
    if (pInfo->curr < pInfo->end && *pInfo->curr == '-') {
        yearIsNegative = true;
        pInfo->curr++;
    }
    
    while (pInfo->curr < pInfo->end && isdigit(*pInfo->curr)) {
        year = 10*year + (*pInfo->curr) - '0';
        pInfo->curr ++;
    }
    if (pInfo->curr >= pInfo->end || *pInfo->curr != '-') {
        badForm = true;
    } else {
        pInfo->curr ++;
    }

    if (!badForm && read2DigitNumber(pInfo, &month) && pInfo->curr < pInfo->end && *pInfo->curr == '-') {
        pInfo->curr ++;
    } else {
        badForm = true;
    }

    if (!badForm && read2DigitNumber(pInfo, &day) && pInfo->curr < pInfo->end && *pInfo->curr == 'T') {
        pInfo->curr ++;
    } else {
        badForm = true;
    }

    if (!badForm && read2DigitNumber(pInfo, &hour) && pInfo->curr < pInfo->end && *pInfo->curr == ':') {
        pInfo->curr ++;
    } else {
        badForm = true;
    }

    if (!badForm && read2DigitNumber(pInfo, &minute) && pInfo->curr < pInfo->end && *pInfo->curr == ':') {
        pInfo->curr ++;
    } else {
        badForm = true;
    }

    if (!badForm && read2DigitNumber(pInfo, &num) && pInfo->curr < pInfo->end && *pInfo->curr == 'Z') {
        second = num;
        pInfo->curr ++;
    } else {
        badForm = true;
    }

    if (badForm || !checkForCloseTag(pInfo, CFXMLPlistTags[DATE_IX], DATE_TAG_LENGTH)) {
        pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Could not interpret <date> at line %d"), lineNumber(pInfo));
        return false;
    }

    CFAbsoluteTime at = 0.0;

#if 0
    { // alternative to CFGregorianDateGetAbsoluteTime() below; also, cheaper than CFCalendar would be;
      // clearly not thread-safe with that environment variable having to be set;
      // timegm() could be used instead of mktime(), on platforms which have it
        struct tm mine;
        mine.tm_year = (yearIsNegative ? -year : year) - 1900;
        mine.tm_mon = month - 1;
        mine.tm_mday = day;
        mine.tm_hour = hour;
        mine.tm_min = minute;
        mine.tm_sec = second;
        char *tz = getenv("TZ");
        setenv("TZ", "", 1);
        tzset();
        at = mktime(tm) - kCFAbsoluteTimeIntervalSince1970;
        if (tz) {
            setenv("TZ", tz, 1);
        } else {
            unsetenv("TZ");
        }
        tzset();
    }
#endif

    // See <rdar://problem/5052483> Revisit the CFGregorianDate -> CFCalendar change in CFPropertyList.c
    // for why we can't use CFCalendar
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated"
    CFGregorianDate date = {yearIsNegative ? -year : year, month, day, hour, minute, second};
    at = CFGregorianDateGetAbsoluteTime(date, NULL);
#pragma GCC diagnostic pop

    if (pInfo->skip) {
        *out = NULL;
    } else {
        *out = CFDateCreate(pInfo->allocator, at);
    }
    return true;
}

static Boolean parseRealTag(_CFXMLPlistParseInfo *pInfo, CFTypeRef *out) {
    CFStringRef str = NULL;
    if (!parseStringTag(pInfo, &str)) {
        if (!pInfo->error) pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Encountered empty <real> on line %d"), lineNumber(pInfo));
        return false;
    }
    
    CFNumberRef result = NULL;
    
    if (!pInfo->skip) {
        if (kCFCompareEqualTo == CFStringCompare(str, CFSTR("nan"), kCFCompareCaseInsensitive)) result = kCFNumberNaN;
        else if (kCFCompareEqualTo == CFStringCompare(str, CFSTR("+infinity"), kCFCompareCaseInsensitive)) result = kCFNumberPositiveInfinity;
        else if (kCFCompareEqualTo == CFStringCompare(str, CFSTR("-infinity"), kCFCompareCaseInsensitive)) result = kCFNumberNegativeInfinity;
        else if (kCFCompareEqualTo == CFStringCompare(str, CFSTR("infinity"), kCFCompareCaseInsensitive)) result = kCFNumberPositiveInfinity;
        else if (kCFCompareEqualTo == CFStringCompare(str, CFSTR("-inf"), kCFCompareCaseInsensitive)) result = kCFNumberNegativeInfinity;
        else if (kCFCompareEqualTo == CFStringCompare(str, CFSTR("inf"), kCFCompareCaseInsensitive)) result = kCFNumberPositiveInfinity;
        else if (kCFCompareEqualTo == CFStringCompare(str, CFSTR("+inf"), kCFCompareCaseInsensitive)) result = kCFNumberPositiveInfinity;
        
        if (result) {
            CFRetain(result);
        } else {
            CFIndex len = CFStringGetLength(str);
            CFStringInlineBuffer buf;
            CFStringInitInlineBuffer(str, &buf, CFRangeMake(0, len));
            SInt32 idx = 0;
            double val;
            if (!__CFStringScanDouble(&buf, NULL, &idx, &val) || idx != len) {
                __CFPListRelease(str, pInfo->allocator);
                pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Encountered misformatted real on line %d"), lineNumber(pInfo));
                return false;
            }
            result = CFNumberCreate(pInfo->allocator, kCFNumberDoubleType, &val);
        }
    }
    
    __CFPListRelease(str, pInfo->allocator);
    if (checkForCloseTag(pInfo, CFXMLPlistTags[REAL_IX], REAL_TAG_LENGTH)) {
        *out = result;
        return true;
    } else {
        __CFPListRelease(result, pInfo->allocator);
        return false;
    }
}

#define GET_CH	if (pInfo->curr == pInfo->end) {	\
			pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Premature end of file after <integer> on line %d"), lineNumber(pInfo)); \
			return false;			\
		}					\
		ch = *(pInfo->curr)

typedef struct {
    int64_t high;
    uint64_t low;
} CFSInt128Struct;

enum {
    kCFNumberSInt128Type = 17
};

CF_INLINE bool isWhitespace(const char *utf8bytes, const char *end) {
    // Converted UTF-16 isWhitespace from CFString to UTF8 bytes to get full list of UTF8 whitespace
    /*
     0020 -> <20>
     0009 -> <09>
     00a0 -> <c2a0>
     1680 -> <e19a80>
     2000 -> <e28080>
     2001 -> <e28081>
     2002 -> <e28082>
     2003 -> <e28083>
     2004 -> <e28084>
     2005 -> <e28085>
     2006 -> <e28086>
     2007 -> <e28087>
     2008 -> <e28088>
     2009 -> <e28089>
     200a -> <e2808a>
     200b -> <e2808b>
     202f -> <e280af>
     205f -> <e2819f>
     3000 -> <e38080>
     */
    // Except we consider some additional values from 0x0 to 0x21 and 0x7E to 0xA1 as whitespace, for compatability
    unsigned char byte1 = *utf8bytes;
    if (byte1 < 0x21 || (byte1 > 0x7E && byte1 < 0xA1)) return true;
    if ((byte1 == 0xe2 || byte1 == 0xe3) && (end - utf8bytes >= 3)) {
        // Check other possibilities in the 3-bytes range
        unsigned char byte2 = *(utf8bytes + 1);
        unsigned char byte3 = *(utf8bytes + 2);
        if (byte1 == 0xe2 && byte2 == 0x80) {
            return ((byte3 >= 80 && byte3 <= 0x8b) || byte3 == 0xaf);
        } else if (byte1 == 0xe2 && byte2 == 0x81) {
            return byte3 == 0x9f;
        } else if (byte1 == 0xe3 && byte2 == 0x80 && byte3 == 0x80) {
            return true;
        }
    }
    return false;
}

static Boolean parseIntegerTag(_CFXMLPlistParseInfo *pInfo, CFTypeRef *out) {
    bool isHex = false, isNeg = false, hadLeadingZero = false;
    char ch = 0;
    
    // decimal_constant         S*(-|+)?S*[0-9]+		(S == space)
    // hex_constant		S*(-|+)?S*0[xX][0-9a-fA-F]+	(S == space)
    
    while (pInfo->curr < pInfo->end && isWhitespace(pInfo->curr, pInfo->end)) pInfo->curr++;
    GET_CH;
    if ('<' == ch) {
        pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Encountered empty <integer> on line %d"), lineNumber(pInfo));
        return false;
    }
    if ('-' == ch || '+' == ch) {
	isNeg = ('-' == ch);
	pInfo->curr++;
	while (pInfo->curr < pInfo->end && isWhitespace(pInfo->curr, pInfo->end)) pInfo->curr++;
    }
    GET_CH;
    if ('0' == ch) {
	if (pInfo->curr + 1 < pInfo->end && ('x' == *(pInfo->curr + 1) || 'X' == *(pInfo->curr + 1))) {
	    pInfo->curr++;
	    isHex = true;
	} else {
	    hadLeadingZero = true;
	}
	pInfo->curr++;
    }
    GET_CH;
    while ('0' == ch) {
	hadLeadingZero = true;
	pInfo->curr++;
	GET_CH;
    }
    if ('<' == ch && hadLeadingZero) {	// nothing but zeros
	int32_t val = 0;
        if (!checkForCloseTag(pInfo, CFXMLPlistTags[INTEGER_IX], INTEGER_TAG_LENGTH)) {
	    // checkForCloseTag() sets error string
	    return false;
        }
        if (pInfo->skip) {
            *out = NULL;
        } else {
            *out = CFNumberCreate(pInfo->allocator, kCFNumberSInt32Type, &val);
        }
        return true;
    }
    if ('<' == ch) {
        pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Incomplete <integer> on line %d"), lineNumber(pInfo));
	return false;
    }
    uint64_t value = 0;
    uint32_t multiplier = (isHex ? 16 : 10);
    while ('<' != ch) {
	uint32_t new_digit = 0;
	switch (ch) {
            case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9':
                new_digit = (ch - '0');
                break;
            case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
                new_digit = (ch - 'a' + 10);
                break;
            case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
                new_digit = (ch - 'A' + 10);
                break;
            default:	// other character
                pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Unknown character '%c' (0x%x) in <integer> on line %d"), ch, ch, lineNumber(pInfo));
                return false;
	}
	if (!isHex && new_digit > 9) {
            pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Hex digit in non-hex <integer> on line %d"), lineNumber(pInfo));
	    return false;
	}
	if (UINT64_MAX / multiplier < value) {
            pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Integer overflow in <integer> on line %d"), lineNumber(pInfo));
	    return false;
	}
	value = multiplier * value;
	if (UINT64_MAX - new_digit < value) {
            pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Integer overflow in <integer> on line %d"), lineNumber(pInfo));
	    return false;
	}
	value = value + new_digit;
	if (isNeg && (uint64_t)INT64_MAX + 1 < value) {
            pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Integer underflow in <integer> on line %d"), lineNumber(pInfo));
	    return false;
	}
	pInfo->curr++;
	GET_CH;
    }
    if (!checkForCloseTag(pInfo, CFXMLPlistTags[INTEGER_IX], INTEGER_TAG_LENGTH)) {
	// checkForCloseTag() sets error string
	return false;
    }
    
    if (pInfo->skip) {
        *out = NULL;
    } else {
        if (isNeg || value <= INT64_MAX) {
            int64_t v = value;
            if (isNeg) v = -v;	// no-op if INT64_MIN
            *out = CFNumberCreate(pInfo->allocator, kCFNumberSInt64Type, &v);
        } else {
            CFSInt128Struct val;
            val.high = 0;
            val.low = value;
            *out = CFNumberCreate(pInfo->allocator, kCFNumberSInt128Type, &val);
        }
    }
    return true;
}

#undef GET_CH

// Returned object is retained; caller must free.  pInfo->curr expected to point to the first character after the '<'
static Boolean parseXMLElement(_CFXMLPlistParseInfo *pInfo, Boolean *isKey, CFTypeRef *out) {
    const char *marker = pInfo->curr;
    int markerLength = -1;
    Boolean isEmpty;
    int markerIx = -1;
    
    if (isKey) *isKey = false;
    while (pInfo->curr < pInfo->end) {
        char ch = *(pInfo->curr);
        if (ch == ' ' || ch ==  '\t' || ch == '\n' || ch =='\r') {
            if (markerLength == -1) markerLength = pInfo->curr - marker;
        } else if (ch == '>') {
            break;
        }
        pInfo->curr ++;
    }
    if (pInfo->curr >= pInfo->end) {
        return false;
    }
    isEmpty = (*(pInfo->curr-1) == '/');
    if (markerLength == -1)
        markerLength = pInfo->curr - (isEmpty ? 1 : 0) - marker;
    pInfo->curr ++; // Advance past '>'
    if (markerLength == 0) {
        // Back up to the beginning of the marker
        pInfo->curr = marker;
        pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Malformed tag on line %d"), lineNumber(pInfo));
        return false;
    }
    switch (*marker) {
        case 'a':   // Array
            if (markerLength == ARRAY_TAG_LENGTH && !memcmp(marker, CFXMLPlistTags[ARRAY_IX], ARRAY_TAG_LENGTH))
                markerIx = ARRAY_IX;
            break;
        case 'd': // Dictionary, data, or date; Fortunately, they all have the same marker length....
            if (markerLength != DICT_TAG_LENGTH)
                break;
            if (!memcmp(marker, CFXMLPlistTags[DICT_IX], DICT_TAG_LENGTH))
                markerIx = DICT_IX;
            else if (!memcmp(marker, CFXMLPlistTags[DATA_IX], DATA_TAG_LENGTH))
                markerIx = DATA_IX;
            else if (!memcmp(marker, CFXMLPlistTags[DATE_IX], DATE_TAG_LENGTH))
                markerIx = DATE_IX;
            break;
        case 'f': // false (boolean)
            if (markerLength == FALSE_TAG_LENGTH && !memcmp(marker, CFXMLPlistTags[FALSE_IX], FALSE_TAG_LENGTH)) {
                markerIx = FALSE_IX;
            }
            break;
        case 'i': // integer
            if (markerLength == INTEGER_TAG_LENGTH && !memcmp(marker, CFXMLPlistTags[INTEGER_IX], INTEGER_TAG_LENGTH))
                markerIx = INTEGER_IX;
            break;
        case 'k': // Key of a dictionary
            if (markerLength == KEY_TAG_LENGTH && !memcmp(marker, CFXMLPlistTags[KEY_IX], KEY_TAG_LENGTH)) {
                markerIx = KEY_IX;
                if (isKey) *isKey = true;
            }
            break;
        case 'p': // Plist
            if (markerLength == PLIST_TAG_LENGTH && !memcmp(marker, CFXMLPlistTags[PLIST_IX], PLIST_TAG_LENGTH))
                markerIx = PLIST_IX;
            break;
        case 'r': // real
            if (markerLength == REAL_TAG_LENGTH && !memcmp(marker, CFXMLPlistTags[REAL_IX], REAL_TAG_LENGTH))
                markerIx = REAL_IX;
            break;
        case 's': // String
            if (markerLength == STRING_TAG_LENGTH && !memcmp(marker, CFXMLPlistTags[STRING_IX], STRING_TAG_LENGTH))
                markerIx = STRING_IX;
            break;
        case 't': // true (boolean)
            if (markerLength == TRUE_TAG_LENGTH && !memcmp(marker, CFXMLPlistTags[TRUE_IX], TRUE_TAG_LENGTH))
                markerIx = TRUE_IX;
            break;
    }

    if (!pInfo->allowNewTypes && markerIx != PLIST_IX && markerIx != ARRAY_IX && markerIx != DICT_IX && markerIx != STRING_IX && markerIx != KEY_IX && markerIx != DATA_IX) {
        pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Encountered new tag when expecting only old-style property list objects"));
        return false;
    }

    switch (markerIx) {
        case PLIST_IX:
            if (isEmpty) {
                pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Encountered empty plist tag"));
                return false;
            }
            return parsePListTag(pInfo, out);
        case ARRAY_IX: 
            if (isEmpty) {
                if (pInfo->skip) {
                    *out = NULL;
                } else {
                    if (pInfo->mutabilityOption == kCFPropertyListImmutable) {
                        *out = CFArrayCreate(pInfo->allocator, NULL, 0, &kCFTypeArrayCallBacks);
                    } else {
                        *out = CFArrayCreateMutable(pInfo->allocator, 0, &kCFTypeArrayCallBacks);
                    }
                }
                return true;
            } else {
                return parseArrayTag(pInfo, out);
            }
        case DICT_IX:
            if (isEmpty) {
                if (pInfo->skip) {
                    *out = NULL;
                } else {
                    if (pInfo->mutabilityOption == kCFPropertyListImmutable) {
                        *out = CFDictionaryCreate(pInfo->allocator, NULL, NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
                    } else {
                        *out = CFDictionaryCreateMutable(pInfo->allocator, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
                    }
                }
                return true;
            } else {
                return parseDictTag(pInfo, out);
            }
        case KEY_IX:
        case STRING_IX:
        {
            int tagLen = (markerIx == KEY_IX) ? KEY_TAG_LENGTH : STRING_TAG_LENGTH;
            if (isEmpty) {
                if (pInfo->skip) {
                    *out = NULL;
                } else {
                    if (pInfo->mutabilityOption == kCFPropertyListMutableContainersAndLeaves) {
                        *out = CFStringCreateMutable(pInfo->allocator, 0);
                    } else {
                        *out = CFStringCreateWithCharacters(pInfo->allocator, NULL, 0);
                    }
                }
                return true;
            }
            if (!parseStringTag(pInfo, (CFStringRef *)out)) {
                return false; // parseStringTag will already have set the error string
            }
            if (!checkForCloseTag(pInfo, CFXMLPlistTags[markerIx], tagLen)) {
                __CFPListRelease(*out, pInfo->allocator);
                return false;
            } else {
                return true;
            }
        }
        case DATA_IX:
            if (isEmpty) {
                pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Encountered empty <data> on line %d"), lineNumber(pInfo));
                return false;
            } else {
                return parseDataTag(pInfo, out);
            }
        case DATE_IX:
            if (isEmpty) {
                pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Encountered empty <date> on line %d"), lineNumber(pInfo));
                return false;
            } else {
                return parseDateTag(pInfo, out);
            }
        case TRUE_IX:
            if (!isEmpty) {
		if (!checkForCloseTag(pInfo, CFXMLPlistTags[TRUE_IX], TRUE_TAG_LENGTH)) {
                    pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Encountered non-empty <true> on line %d"), lineNumber(pInfo));
                    return false;
                }
	    }
            if (pInfo->skip) {
                *out = NULL;
            } else {
                *out = CFRetain(kCFBooleanTrue);
            }
            return true;
        case FALSE_IX:
            if (!isEmpty) {
		if (!checkForCloseTag(pInfo, CFXMLPlistTags[FALSE_IX], FALSE_TAG_LENGTH)) {
                    pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Encountered non-empty <false> on line %d"), lineNumber(pInfo));
                    return false;
                }
	    }
            if (pInfo->skip) {
                *out = NULL;
            } else {
                *out = CFRetain(kCFBooleanFalse);
            }
            return true;
        case REAL_IX:
            if (isEmpty) {
                pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Encountered empty <real> on line %d"), lineNumber(pInfo));
                return false;
            } else {
                return parseRealTag(pInfo, out);
            }
        case INTEGER_IX:
            if (isEmpty) {
                pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Encountered empty <integer> on line %d"), lineNumber(pInfo));
                return false;
            } else {
                return parseIntegerTag(pInfo, out);
            }
        default:  {
            CFStringRef markerStr = CFStringCreateWithBytes(kCFAllocatorSystemDefault, (const UInt8 *)marker, markerLength, kCFStringEncodingUTF8, NO);
            pInfo->curr = marker;
            pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Encountered unknown tag %@ on line %d"), markerStr ? markerStr : CFSTR("<unknown>"), lineNumber(pInfo));
            if (markerStr) CFRelease(markerStr);
            return false;
        }
    }
}

static Boolean parseXMLPropertyList(_CFXMLPlistParseInfo *pInfo, CFTypeRef *out) {
    while (!pInfo->error && pInfo->curr < pInfo->end) {
        UniChar ch;
        skipWhitespace(pInfo);
        if (pInfo->curr+1 >= pInfo->end) {
            pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("No XML content found"));
            return false;
        }
        if (*(pInfo->curr) != '<') {
            pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Unexpected character %c at line %d"), *(pInfo->curr), lineNumber(pInfo));
            return false;
        }
        ch = *(++ pInfo->curr);
        if (ch == '!') {
            // Comment or DTD
            ++ pInfo->curr;
            if (pInfo->curr+1 < pInfo->end && *pInfo->curr == '-' && *(pInfo->curr+1) == '-') {
                // Comment
                pInfo->curr += 2;
                skipXMLComment(pInfo);
            } else {
                skipDTD(pInfo);
            }
        } else if (ch == '?') {
            // Processing instruction
            pInfo->curr++;
            skipXMLProcessingInstruction(pInfo);
        } else {
            // Tag or malformed
            return parseXMLElement(pInfo, NULL, out);
            // Note we do not verify that there was only one element, so a file that has garbage after the first element will nonetheless successfully parse
        }
    }
    // Should never get here
    if (!(pInfo->error)) {
        pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Encountered unexpected EOF"));
    }
    return false;
}

static CFStringEncoding encodingForXMLData(CFDataRef data, CFErrorRef *error, CFIndex *skip) {
    const uint8_t *bytes = (uint8_t *)CFDataGetBytePtr(data);
    UInt32 length = CFDataGetLength(data);
    const uint8_t *idx, *end;
    char quote;
    
    // Check for the byte order mark first. If we find it, set the skip value so the parser doesn't attempt to parse the BOM itself.
    if (length > 4) {
        if (*bytes == 0x00 && *(bytes+1) == 0x00 && *(bytes+2) == 0xFE && *(bytes+3) == 0xFF) {
            *skip = 4;
            return kCFStringEncodingUTF32BE;
        } else if (*bytes == 0xFF && *(bytes+1) == 0xFE && *(bytes+2) == 0x00 && *(bytes+3) == 0x00) {
            *skip = 4;
            return kCFStringEncodingUTF32LE;
        }
    }
    
    if (length > 3) {
        if (*bytes == 0xEF && *(bytes+1) == 0xBB && *(bytes+2) == 0xBF) {
            *skip = 3;
            return kCFStringEncodingUTF8;
        }
    }

    if (length > 2) {
        if (*bytes == 0xFF && *(bytes+1) == 0xFE) {
            *skip = 2;
            return kCFStringEncodingUTF16LE;
        } else if (*bytes == 0xFE && *(bytes+1) == 0xFF) {
            *skip = 2;
            return kCFStringEncodingUTF16BE;            
        } else if (*bytes == 0x00 || *(bytes+1) == 0x00) { // This clause checks for a Unicode sequence lacking the byte order mark; technically an error, but this check is recommended by the XML spec
            *skip = 2;
            return kCFStringEncodingUnicode;
        }
    }
        
    // Scan for the <?xml.... ?> opening
    if (length < 5 || strncmp((char const *) bytes, "<?xml", 5) != 0) return kCFStringEncodingUTF8;
    idx = bytes + 5;
    end = bytes + length;
    // Found "<?xml"; now we scan for "encoding"
    while (idx < end) {
        uint8_t ch = *idx;
        const uint8_t *scan;
        if ( ch == '?' || ch == '>') return kCFStringEncodingUTF8;
        idx ++;
        scan = idx;
	if (idx + 8 >= end) {
	    if (error) *error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("End of buffer while looking for encoding name"));
	    return 0;
	}
        if (ch == 'e' && *scan++ == 'n' && *scan++ == 'c' && *scan++ == 'o' && *scan++ == 'd' && *scan++ == 'i'
            && *scan++ == 'n' && *scan++ == 'g' && *scan++ == '=') {
            idx = scan;
            break;
        }
    }
    if (idx >= end) return kCFStringEncodingUTF8;
    quote = *idx;
    if (quote != '\'' && quote != '\"') return kCFStringEncodingUTF8;
    else {
        CFStringRef encodingName;
        const uint8_t *base = idx+1; // Move past the quote character
        UInt32 len;
        idx ++;
        while (idx < end && *idx != quote) idx ++;
        if (idx >= end) return kCFStringEncodingUTF8;
        len = idx - base;
        if (len == 5 && (*base == 'u' || *base == 'U') && (base[1] == 't' || base[1] == 'T') && (base[2] == 'f' || base[2] == 'F') && (base[3] == '-') && (base[4] == '8'))
            return kCFStringEncodingUTF8;
        encodingName = CFStringCreateWithBytes(kCFAllocatorSystemDefault, base, len, kCFStringEncodingISOLatin1, false);
#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX
        CFStringEncoding enc = CFStringConvertIANACharSetNameToEncoding(encodingName);
        if (enc != kCFStringEncodingInvalidId) {
            CFRelease(encodingName);
            return enc;
        }
#endif

        if (error) {
            *error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Encountered unknown encoding (%@)"), encodingName);
            CFRelease(encodingName);
        }
        return 0;
    }
}

bool __CFTryParseBinaryPlist(CFAllocatorRef allocator, CFDataRef data, CFOptionFlags option, CFPropertyListRef *plist, CFStringRef *errorString);

#define SAVE_PLISTS 0

#if SAVE_PLISTS
static Boolean __savePlistData(CFDataRef data, CFOptionFlags opt) {
    uint8_t pn[2048];
    uint8_t fn[2048];
    uint32_t pnlen = sizeof(pn);
    uint8_t *pnp = NULL;
    if (0 == _NSGetExecutablePath((char *)pn, &pnlen)) {
	pnp = strrchr((char *)pn, '/');
    }
    if (!pnp) {
	pnp = pn;
    } else {
	pnp++;
    }
    if (0 == strcmp((char *)pnp, "parse_plists")) return true;
    CFUUIDRef r = CFUUIDCreate(kCFAllocatorSystemDefault);
    CFStringRef s = CFUUIDCreateString(kCFAllocatorSystemDefault, r);
    CFStringRef p = CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("/tmp/plists/%s#%@#0x%x"), pnp, s, opt);
    _CFStringGetFileSystemRepresentation(p, fn, sizeof(fn));
    CFRelease(r);
    CFRelease(s);
    CFRelease(p);
    int fd = open((const char *)fn, O_WRONLY|O_CREAT|O_TRUNC, 0666);
    if (fd < 0) return false;
    int len = CFDataGetLength(data);
    int w = write(fd, CFDataGetBytePtr(data), len);
    fsync(fd);
    close(fd);
    if (w != len) return false;
    return true;
}
#endif

// If the data is from a converted string, then originalString is non-NULL. If originalString is NULL, then pass in guessedEncoding.
// keyPaths is a set of CFStrings, ':'-separated paths
static Boolean _CFPropertyListCreateFromUTF8Data(CFAllocatorRef allocator, CFDataRef xmlData, CFIndex skipBytes, CFStringRef originalString, CFStringEncoding guessedEncoding, CFOptionFlags option, CFErrorRef *outError, Boolean allowNewTypes, CFPropertyListFormat *format, CFSetRef keyPaths, CFTypeRef *out) {
    initStatics();
    
    CFAssert1(xmlData != NULL, __kCFLogAssertion, "%s(): NULL data not allowed", __PRETTY_FUNCTION__);
    CFAssert2(option == kCFPropertyListImmutable || option == kCFPropertyListMutableContainers || option == kCFPropertyListMutableContainersAndLeaves, __kCFLogAssertion, "%s(): Unrecognized option %lu", __PRETTY_FUNCTION__, option);
    
    CFIndex length = CFDataGetLength(xmlData);
    if (!length) {
        if (outError) *outError = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Conversion of string failed. The string is empty."));
        return false;
    }
    
    _CFXMLPlistParseInfo pInfoBuf;
    _CFXMLPlistParseInfo *pInfo = &pInfoBuf;
    CFTypeRef result;
    
    // Ensure that the data is not collected while we are using it
    CFRetain(xmlData);
    const char *buf = (const char *)CFDataGetBytePtr(xmlData);
    
    // We may have to skip over starting stuff like BOM markers.
    buf += skipBytes;
    
    pInfo->begin = buf;
    pInfo->end = buf+length;
    pInfo->curr = buf;
    pInfo->allocator = allocator;
    pInfo->error = NULL;
    _createStringMap(pInfo);
    pInfo->mutabilityOption = option;
    pInfo->allowNewTypes = allowNewTypes;
    pInfo->skip = false;
    pInfo->keyPaths = createTopLevelKeypaths(allocator, keyPaths);
    
    Boolean success = parseXMLPropertyList(pInfo, &result);
    if (success && result && format) *format = kCFPropertyListXMLFormat_v1_0;
    
    _cleanupStringMap(pInfo);
    if (pInfo->keyPaths) CFRelease(pInfo->keyPaths);
    CFRelease(xmlData);

    if (success) {
        *out = result; // caller releases
        return true;
    }
    
    // Try again, old-style
    CFErrorRef oldStyleError = NULL;
    result = __CFCreateOldStylePropertyListOrStringsFile(allocator, xmlData, originalString, guessedEncoding, option, outError ? &oldStyleError : NULL, format);
    if (result) {
        // Release old error, return
        if (pInfo->error) CFRelease(pInfo->error);
        *out = result;
        return true;
    }
    
    // Failure, both ways. Set up the error to be given back to caller.
    if (!outError) {
        if (pInfo->error) CFRelease(pInfo->error);
        return false;
    }
    
    // Caller's responsibility to release outError
    if (pInfo->error && oldStyleError) {
        // Add the error from the old-style property list parser to the user info of the original error (pInfo->error), which had better exist
        CFDictionaryRef oldUserInfo = CFErrorCopyUserInfo(pInfo->error);
        CFMutableDictionaryRef newUserInfo = CFDictionaryCreateMutableCopy(kCFAllocatorSystemDefault, CFDictionaryGetCount(oldUserInfo) + 1, oldUserInfo);
        CFDictionaryAddValue(newUserInfo, CFPropertyListOldStyleParserErrorKey, oldStyleError);
        
        // Re-create the xml parser error with this new user info dictionary
        CFErrorRef newError = CFErrorCreate(kCFAllocatorSystemDefault, CFErrorGetDomain(pInfo->error), CFErrorGetCode(pInfo->error), newUserInfo);
        
        CFRelease(oldUserInfo);
        CFRelease(newUserInfo);
        CFRelease(oldStyleError);
        CFRelease(pInfo->error);
        *outError = newError;
        
    } else if (pInfo->error && !oldStyleError) {
        // Return original error
        *outError = pInfo->error;
    } else if (!pInfo->error && oldStyleError) {
        // Return only old-style error
        // Probably shouldn't get here
        *outError = oldStyleError;
    } else if (!pInfo->error && !oldStyleError) {
        // Return unknown error
        *outError = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Encountered unknown error during parse"));
    }
    return false;    
}

static CFDataRef _createUTF8DataFromString(CFAllocatorRef allocator, CFStringRef str) {
    CFIndex bytesNeeded = 0;
    CFStringGetBytes(str, CFRangeMake(0, CFStringGetLength(str)), kCFStringEncodingUTF8, 0, false, NULL, 0, &bytesNeeded);

    const char *bytes = (const char *)CFAllocatorAllocate(allocator, bytesNeeded, 0);
    CFStringGetBytes(str, CFRangeMake(0, CFStringGetLength(str)), kCFStringEncodingUTF8, 0, false, (uint8_t *)bytes, bytesNeeded, NULL);
   
    CFDataRef utf8Data = CFDataCreateWithBytesNoCopy(allocator, (const UInt8 *)bytes, bytesNeeded, allocator);
    return utf8Data;
}

// Set topLevelKeys to a set of top level keys to decode. If NULL, all keys are decoded. If the top level object is not a dictionary, all objects are decoded. If the plist is not XML, all objects are decoded.
static Boolean _CFPropertyListCreateWithData(CFAllocatorRef allocator, CFDataRef data, CFOptionFlags option, CFErrorRef *outError, Boolean allowNewTypes, CFPropertyListFormat *format, CFSetRef topLevelKeys, CFTypeRef *out) {
    initStatics();
    CFStringEncoding encoding;
    
    if (!data || CFDataGetLength(data) == 0) {
        if (outError) {
            *outError = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Cannot parse a NULL or zero-length data"));
        }
        return false;
    }
    
#if SAVE_PLISTS
    __savePlistData(data, option);
#endif
    
    // Ignore the error from CFTryParseBinaryPlist -- if it doesn't work, we're going to try again anyway using the XML parser
    if (__CFTryParseBinaryPlist(allocator, data, option, out, NULL)) {
	if (format) *format = kCFPropertyListBinaryFormat_v1_0;
        return true;
    }
    
    // Use our own error variable here so we can check it against NULL later
    CFErrorRef subError = NULL;
    CFIndex skip = 0;
    encoding = encodingForXMLData(data, &subError, &skip); // 0 is an error return, NOT MacRoman.
    
    if (encoding == 0) {
        // Couldn't find an encoding
        // Note that encodingForXMLData() will give us the right values for a standard plist, too.
        if (outError && subError == NULL) {
	    // encodingForXMLData didn't set an error, so we create a new one here
            *outError = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Could not determine the encoding of the XML data"));
        } else if (outError && subError) {
	    // give the caller the subError, they will release
	    *outError = subError;
	} else if (!outError && subError) {
	    // Release the error
	    CFRelease(subError);
	}
        return false;
    }
    
    if (encoding == kCFStringEncodingUTF8) {
        // Use fast path
        return _CFPropertyListCreateFromUTF8Data(allocator, data, skip, NULL, encoding, option, outError, allowNewTypes, format, topLevelKeys, out);
    }
    
    // Convert to UTF8 first
    CFStringRef xmlString = CFStringCreateWithBytes(allocator, CFDataGetBytePtr(data) + skip, CFDataGetLength(data) - skip, encoding, false);
    if (!xmlString) {
        if (outError) *outError = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Could not determine the encoding of the XML data (string creation failed)"));
        return false;
    }
    
    CFDataRef utf8Data = _createUTF8DataFromString(allocator, xmlString);

    Boolean result = _CFPropertyListCreateFromUTF8Data(allocator, utf8Data, 0, xmlString, 0, option, outError, allowNewTypes, format, topLevelKeys, out);
    
    if (xmlString) CFRelease(xmlString);
    if (utf8Data) CFRelease(utf8Data);
    
    return result;
}

// -----------------------------------------------------------------------------------------------------------------------

#pragma mark -
#pragma mark Exported Parsing Functions

CFTypeRef _CFPropertyListCreateFromXMLStringError(CFAllocatorRef allocator, CFStringRef xmlString, CFOptionFlags option, CFErrorRef *error, Boolean allowNewTypes, CFPropertyListFormat *format) {
    // Convert to UTF8 first
    CFDataRef utf8Data = _createUTF8DataFromString(allocator, xmlString);
    CFTypeRef result = NULL;
    _CFPropertyListCreateFromUTF8Data(allocator, utf8Data, 0, xmlString, 0, option, error, allowNewTypes, format, NULL, &result);    
    if (utf8Data) CFRelease(utf8Data);

    return result;
}

CFTypeRef _CFPropertyListCreateFromXMLString(CFAllocatorRef allocator, CFStringRef xmlString, CFOptionFlags option, CFStringRef *errorString, Boolean allowNewTypes, CFPropertyListFormat *format) {
    initStatics();
    if (errorString) *errorString = NULL;
    CFErrorRef error = NULL;
    CFTypeRef result = _CFPropertyListCreateFromXMLStringError(allocator, xmlString, option, &error, allowNewTypes, format);

    if (errorString && error) {
        // The caller is interested in receiving an error message. Pull the debug string out of the CFError returned above
        CFDictionaryRef userInfo = CFErrorCopyUserInfo(error);
        CFStringRef debugString = NULL;
        
        // Handle a special-case for compatibility - if the XML parse failed and the old-style plist parse failed, construct a special string
        CFErrorRef underlyingError = NULL;

        Boolean oldStyleFailed = CFDictionaryGetValueIfPresent(userInfo, CFPropertyListOldStyleParserErrorKey, (const void **)&underlyingError);
        
        if (oldStyleFailed) {
            CFStringRef xmlParserErrorString, oldStyleParserErrorString;
            xmlParserErrorString = (CFStringRef)CFDictionaryGetValue(userInfo, kCFErrorDebugDescriptionKey);
            
            CFDictionaryRef oldStyleParserUserInfo = CFErrorCopyUserInfo(underlyingError);
            oldStyleParserErrorString = (CFStringRef)CFDictionaryGetValue(userInfo, kCFErrorDebugDescriptionKey);
            
            // Combine the two strings into a single one that matches the previous implementation
            debugString = CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("XML parser error:\n\t%@\nOld-style plist parser error:\n\t%@\n"), xmlParserErrorString, oldStyleParserErrorString);
            
            CFRelease(oldStyleParserUserInfo);
        } else {
            debugString = (CFStringRef)CFDictionaryGetValue(userInfo, kCFErrorDebugDescriptionKey);
            if (debugString) CFRetain(debugString);
        }
        
        // Give the debugString to the caller, who is responsible for releasing it
        CFRelease(userInfo);
        *errorString = debugString;
    }
    
    if (error) {
        CFRelease(error);
    }
    
    return result;
}

CF_PRIVATE bool __CFBinaryPlistCreateObjectFiltered(const uint8_t *databytes, uint64_t datalen, uint64_t startOffset, const CFBinaryPlistTrailer *trailer, CFAllocatorRef allocator, CFOptionFlags mutabilityOption, CFMutableDictionaryRef objects, CFMutableSetRef set, CFIndex curDepth, CFSetRef keyPaths, CFPropertyListRef *plist);

// Returns a subset of the property list, only including the key paths in the CFSet.
bool _CFPropertyListCreateFiltered(CFAllocatorRef allocator, CFDataRef data, CFOptionFlags option, CFSetRef keyPaths, CFPropertyListRef *value, CFErrorRef *error) {
    
    initStatics();
    
    if (!keyPaths || !data) {
        return false;
    }
    
    uint8_t marker;    
    CFBinaryPlistTrailer trailer;
    uint64_t offset;
    const uint8_t *databytes = CFDataGetBytePtr(data);
    uint64_t datalen = CFDataGetLength(data);
    Boolean success = false;
    CFTypeRef out = NULL;

    // First check to see if it is a binary property list
    if (8 <= datalen && __CFBinaryPlistGetTopLevelInfo(databytes, datalen, &marker, &offset, &trailer)) {        
        uint64_t valueOffset = offset;
        
        // Split up the key path
        CFSetRef splitKeyPaths = createTopLevelKeypaths(allocator, keyPaths);

        // Create a dictionary to cache objects in
        CFMutableDictionaryRef objects = CFDictionaryCreateMutable(allocator, 0, NULL, &kCFTypeDictionaryValueCallBacks);
        success = __CFBinaryPlistCreateObjectFiltered(databytes, datalen, valueOffset, &trailer, allocator, option, objects, NULL, 0, splitKeyPaths, &out);
        
        CFRelease(splitKeyPaths);
        CFRelease(objects);        
    } else {
	// Try an XML property list
        success = _CFPropertyListCreateWithData(allocator, data, option, error, true, NULL, keyPaths, &out);
    }
    
    if (success && value) {
        *value = out; // caller releases
    } else if (out) {
        CFRelease(out);
    }
    return success;
}

/* Get a single value for a given key in a top-level dictionary in a property list.
 @param allocator The allocator to use.
 @param data The property list data.
 @param option Currently unused, set to 0.
 @param keyPath The keyPath to search for in the property list. Keys are colon-separated. Indexes into arrays are specified with an integer (zero-based).
 @param value If the key is found and the parameter is non-NULL, this will be set to a reference to the value. It is the caller's responsibility to release the object. If no object is found, will be set to NULL. If this parameter is NULL, this function can be used to check for the existence of a key without creating it by just checking the return value.
 @param error If an error occurs, will be set to a valid CFErrorRef. It is the caller's responsibility to release this value.
 @return True if the key is found, false otherwise.
 */
bool _CFPropertyListCreateSingleValue(CFAllocatorRef allocator, CFDataRef data, CFOptionFlags option, CFStringRef keyPath, CFPropertyListRef *value, CFErrorRef *error) {
    
    initStatics();
    
    if (!keyPath || CFStringGetLength(keyPath) == 0) {
        return false;
    }
    
    uint8_t marker;    
    CFBinaryPlistTrailer trailer;
    uint64_t offset;
    const uint8_t *databytes = CFDataGetBytePtr(data);
    uint64_t datalen = CFDataGetLength(data);
    Boolean success = false;
    
    // First check to see if it is a binary property list
    if (8 <= datalen && __CFBinaryPlistGetTopLevelInfo(databytes, datalen, &marker, &offset, &trailer)) {
        // Split up the key path
        CFArrayRef keyPathArray = CFStringCreateArrayBySeparatingStrings(kCFAllocatorSystemDefault, keyPath, CFSTR(":"));
        uint64_t keyOffset, valueOffset = offset;
        
        // Create a dictionary to cache objects in
        CFMutableDictionaryRef objects = CFDictionaryCreateMutable(kCFAllocatorSystemDefault, 0, NULL, &kCFTypeDictionaryValueCallBacks);
        CFIndex keyPathCount = CFArrayGetCount(keyPathArray);
        _CFDictionarySetCapacity(objects, keyPathCount + 1);

        for (CFIndex i = 0; i < keyPathCount; i++) {
            CFStringRef oneKey = (CFStringRef)CFArrayGetValueAtIndex(keyPathArray, i);
            SInt32 intValue = CFStringGetIntValue(oneKey);
            if ((intValue == 0 && CFStringCompare(CFSTR("0"), oneKey, 0) != kCFCompareEqualTo) || intValue == INT_MAX || intValue == INT_MIN || intValue < 0) {
                // Treat as a string key into a dictionary
                success = __CFBinaryPlistGetOffsetForValueFromDictionary3(databytes, datalen, valueOffset, &trailer, (CFTypeRef)oneKey, &keyOffset, &valueOffset, false, objects);
            } else {
                // Treat as integer index into an array
                success = __CFBinaryPlistGetOffsetForValueFromArray2(databytes, datalen, valueOffset, &trailer, intValue, &valueOffset, objects);
            }
            
            if (!success) {
                break;
            }
        }
        
        // value could be null if the caller wanted to check for the existence of a key but not bother creating it
        if (success && value) {
            CFPropertyListRef pl;
	    success = __CFBinaryPlistCreateObjectFiltered(databytes, datalen, valueOffset, &trailer, allocator, option, objects, NULL, 0, NULL, &pl);
	    if (success) {
		// caller's responsibility to release the created object
		*value = pl;
	    }
	}
        
        CFRelease(keyPathArray);
        CFRelease(objects);
    } else {
	// Try an XML property list
	// Note: This is currently not any more efficient than grabbing the whole thing. This could be improved in the future.
	CFPropertyListRef plist = CFPropertyListCreateWithData(allocator, data, option, NULL, error);
        if (plist) {
            CFPropertyListRef nextObject = plist;
            success = true;
            CFArrayRef keyPathArray = CFStringCreateArrayBySeparatingStrings(kCFAllocatorSystemDefault, keyPath, CFSTR(":"));
            for (CFIndex i = 0;  i < CFArrayGetCount(keyPathArray); i++) {
                CFStringRef oneKey = (CFStringRef)CFArrayGetValueAtIndex(keyPathArray, i);
                SInt32 intValue = CFStringGetIntValue(oneKey);
                if (((intValue == 0 && CFStringCompare(CFSTR("0"), oneKey, 0) != kCFCompareEqualTo) || intValue == INT_MAX || intValue == INT_MIN) && nextObject && CFGetTypeID((CFTypeRef)nextObject) == dicttype) {
                    // Treat as a string key into a dictionary
                    nextObject = (CFPropertyListRef)CFDictionaryGetValue((CFDictionaryRef)nextObject, oneKey);
                } else if (nextObject && CFGetTypeID((CFTypeRef)nextObject) == arraytype) {
                    // Treat as integer index into an array
                    nextObject = (CFPropertyListRef)CFArrayGetValueAtIndex((CFArrayRef)nextObject, intValue);
                } else {
                    success = false;
                    break;
                }
            }
            
            if (success && nextObject && value) {
                *value = nextObject;
                // caller's responsibility to release the created object
                CFRetain(*value);
            } else if (!nextObject) {
                success = false;
            }
            
            CFRelease(keyPathArray);
            CFRelease(plist);
        }
    }
    
    return success;
}

// Legacy
CFTypeRef _CFPropertyListCreateFromXMLData(CFAllocatorRef allocator, CFDataRef xmlData, CFOptionFlags option, CFStringRef *errorString, Boolean allowNewTypes, CFPropertyListFormat *format) {
    initStatics();
    CFTypeRef out = NULL;
    if (errorString) *errorString = NULL;
    CFErrorRef error = NULL;
    Boolean result = _CFPropertyListCreateWithData(allocator, xmlData, option, &error, allowNewTypes, format, NULL, &out);
    if (!result && error && errorString) {
        *errorString = __copyErrorDebugDescription(error);
    }
    if (error) CFRelease(error);
    return out;
}

CFPropertyListRef CFPropertyListCreateWithData(CFAllocatorRef allocator, CFDataRef data, CFOptionFlags options, CFPropertyListFormat *format, CFErrorRef *error) {
    initStatics();
    CFAssert1(data != NULL, __kCFLogAssertion, "%s(): NULL data not allowed", __PRETTY_FUNCTION__);
    CFAssert2(options == kCFPropertyListImmutable || options == kCFPropertyListMutableContainers || options == kCFPropertyListMutableContainersAndLeaves, __kCFLogAssertion, "%s(): Unrecognized option %lu", __PRETTY_FUNCTION__, options);
    CFPropertyListRef out = NULL;
    _CFPropertyListCreateWithData(allocator, data, options, error, true, format, NULL, &out);
    return out;
}

CFPropertyListRef CFPropertyListCreateFromXMLData(CFAllocatorRef allocator, CFDataRef xmlData, CFOptionFlags option, CFStringRef *errorString) {
    initStatics();
    if (errorString) *errorString = NULL;
    CFErrorRef error = NULL;
    CFPropertyListRef result = CFPropertyListCreateWithData(allocator, xmlData, option, NULL, &error);
    if (error && errorString) {
        *errorString = __copyErrorDebugDescription(error);
    }
    if (error) CFRelease(error);
    return result;
}

CFDataRef CFPropertyListCreateData(CFAllocatorRef allocator, CFPropertyListRef propertyList, CFPropertyListFormat format, CFOptionFlags options, CFErrorRef *error) {
    initStatics();
    CFAssert1(format != kCFPropertyListOpenStepFormat, __kCFLogAssertion, "%s(): kCFPropertyListOpenStepFormat not supported for writing", __PRETTY_FUNCTION__);
    CFAssert2(format == kCFPropertyListXMLFormat_v1_0 || format == kCFPropertyListBinaryFormat_v1_0, __kCFLogAssertion, "%s(): Unrecognized option %ld", __PRETTY_FUNCTION__, format);
    CFAssert1(propertyList != NULL, __kCFLogAssertion, "%s(): Cannot be called with a NULL property list", __PRETTY_FUNCTION__);
    __CFAssertIsPList(propertyList);
    
    CFDataRef data = NULL;
    
    
    CFStringRef validErr = NULL;
    if (!_CFPropertyListIsValidWithErrorString(propertyList, format, &validErr)) {
        if (error) {
            *error = __CFPropertyListCreateError(kCFPropertyListWriteStreamError, CFSTR("Property list invalid for format: %d (%@)"), format, validErr);
        }
	if (validErr) CFRelease(validErr);
        return NULL;
    }
    
    if (format == kCFPropertyListOpenStepFormat) {
        CFLog(kCFLogLevelError, CFSTR("Property list format kCFPropertyListOpenStepFormat not supported for writing"));
        return NULL;
    } else if (format == kCFPropertyListXMLFormat_v1_0) {
        data = _CFPropertyListCreateXMLData(allocator, propertyList, true);
    } else if (format == kCFPropertyListBinaryFormat_v1_0) {        // TODO: Is it more efficient to create a stream here or just use a mutable data?
        CFWriteStreamRef stream = CFWriteStreamCreateWithAllocatedBuffers(kCFAllocatorSystemDefault, allocator);
        CFWriteStreamOpen(stream);
        CFIndex len = CFPropertyListWrite(propertyList, stream, format, options, error);
        if (0 < len) {
            data = (CFDataRef)CFWriteStreamCopyProperty(stream, kCFStreamPropertyDataWritten);
        }
        CFWriteStreamClose(stream);
	CFRelease(stream);
    } else {
	CFLog(kCFLogLevelError, CFSTR("Unknown format option"));
    }
    
    return data;
}

CFIndex CFPropertyListWrite(CFPropertyListRef propertyList, CFWriteStreamRef stream, CFPropertyListFormat format, CFOptionFlags options, CFErrorRef *error) {
    initStatics();
    CFAssert1(stream != NULL, __kCFLogAssertion, "%s(): NULL stream not allowed", __PRETTY_FUNCTION__);
    CFAssert1(format != kCFPropertyListOpenStepFormat, __kCFLogAssertion, "%s(): kCFPropertyListOpenStepFormat not supported for writing", __PRETTY_FUNCTION__);
    CFAssert2(format == kCFPropertyListXMLFormat_v1_0 || format == kCFPropertyListBinaryFormat_v1_0, __kCFLogAssertion, "%s(): Unrecognized option %ld", __PRETTY_FUNCTION__, format);
    CFAssert1(propertyList != NULL, __kCFLogAssertion, "%s(): Cannot be called with a NULL property list", __PRETTY_FUNCTION__);
    __CFAssertIsPList(propertyList);
    CFAssert1(CFWriteStreamGetTypeID() == CFGetTypeID(stream), __kCFLogAssertion, "%s(): stream argument is not a write stream", __PRETTY_FUNCTION__);
    CFAssert1(kCFStreamStatusOpen == CFWriteStreamGetStatus(stream) || kCFStreamStatusWriting == CFWriteStreamGetStatus(stream), __kCFLogAssertion, "%s():  stream is not open", __PRETTY_FUNCTION__);
    
    CFStringRef validErr = NULL;
    if (!_CFPropertyListIsValidWithErrorString(propertyList, format, &validErr)) {
        CFLog(kCFLogLevelError, CFSTR("Property list invalid for format: %ld (%@)"), format, validErr);
	if (validErr) CFRelease(validErr);
        return 0;
    }
    if (format == kCFPropertyListOpenStepFormat) {
        CFLog(kCFLogLevelError, CFSTR("Property list format kCFPropertyListOpenStepFormat not supported for writing"));
        return 0;
    }
    if (format == kCFPropertyListXMLFormat_v1_0) {
        CFDataRef data = _CFPropertyListCreateXMLData(kCFAllocatorSystemDefault, propertyList, true);
        if (!data) {
            CFLog(kCFLogLevelError, CFSTR("Property list format kCFPropertyListXMLFormat_v1_0 specified but was not a valid property list type"));
            return 0;
        }
        CFIndex len = CFDataGetLength(data);
	const uint8_t *ptr = CFDataGetBytePtr(data);
	while (0 < len) {
	    CFIndex ret = CFWriteStreamWrite(stream, ptr, len);
	    if (ret == 0) {
                if (error) *error = __CFPropertyListCreateError(kCFPropertyListWriteStreamError, CFSTR("Property list writing could not be completed because stream is full."));
                CFRelease(data);
	        return 0;
	    }
	    if (ret < 0) {
		CFErrorRef underlyingError = CFWriteStreamCopyError(stream);
                if (underlyingError) {
                    if (error) {
                        // Wrap the error from CFWriteStreamCopy in a new error
                        CFMutableDictionaryRef userInfo = CFDictionaryCreateMutable(kCFAllocatorSystemDefault, 0, &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); 
                        CFDictionarySetValue(userInfo, kCFErrorDebugDescriptionKey, CFSTR("Property list writing could not be completed because the stream had an unknown error."));
                        CFDictionarySetValue(userInfo, kCFErrorUnderlyingErrorKey, underlyingError);
                        *error = CFErrorCreate(kCFAllocatorSystemDefault, kCFErrorDomainCocoa, kCFPropertyListWriteStreamError, userInfo);
                        CFRelease(userInfo);
                    }
                    CFRelease(underlyingError);
                }
		CFRelease(data);
		return 0;
	    }
	    ptr += ret;
	    len -= ret;
	}
	len = CFDataGetLength(data);
	CFRelease(data);
        return len;
    }
    if (format == kCFPropertyListBinaryFormat_v1_0) {
        CFIndex len = __CFBinaryPlistWrite(propertyList, stream, 0, options, error);
        return len;
    }
    CFLog(kCFLogLevelError, CFSTR("Unknown format option"));
    return 0;
}

CFIndex CFPropertyListWriteToStream(CFPropertyListRef propertyList, CFWriteStreamRef stream, CFPropertyListFormat format, CFStringRef *errorString) {
    initStatics();
    if (errorString) *errorString = NULL;
    CFErrorRef error = NULL;
    
    // For backwards compatibility, we check the format parameter up front since these do not have CFError counterparts in the newer API
    CFStringRef validErr = NULL;
    if (!_CFPropertyListIsValidWithErrorString(propertyList, format, &validErr)) {
	if (errorString) *errorString = CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("Property list invalid for format (%@)"), validErr);
	if (validErr) CFRelease(validErr);
        return 0;
    }
    if (format == kCFPropertyListOpenStepFormat) {
        if (errorString) *errorString = (CFStringRef)CFRetain(CFSTR("Property list format kCFPropertyListOpenStepFormat not supported for writing"));
        return 0;
    }
    if (format != kCFPropertyListBinaryFormat_v1_0 && format != kCFPropertyListXMLFormat_v1_0) {
        if (errorString) *errorString = (CFStringRef)CFRetain(CFSTR("Unknown format option"));
        return 0;
    }
    
    CFIndex result = CFPropertyListWrite(propertyList, stream, format, 0, &error);
    if (error && errorString) {
        *errorString = __copyErrorDebugDescription(error);
    }
    if (error) CFRelease(error);
    return result;    
}

static bool __convertReadStreamToBytes(CFReadStreamRef stream, CFIndex max, uint8_t **buffer, CFIndex *length, CFErrorRef *error) {
    int32_t buflen = 0, bufsize = 0, retlen;
    uint8_t *buf = NULL, sbuf[8192];
    for (;;) {
	retlen = CFReadStreamRead(stream, sbuf, __CFMin(8192, max));
        if (retlen <= 0) {
            *buffer = buf;
            *length = buflen;
            
            if (retlen < 0 && error) {
                // Copy the error out
                *error = CFReadStreamCopyError(stream);
                return false;
            }
            
	    return true;
	}
        if (bufsize < buflen + retlen) {
	    if (bufsize < 256 * 1024) {
		bufsize *= 4;
	    } else if (bufsize < 16 * 1024 * 1024) {
		bufsize *= 2;
	    } else {
		// once in this stage, this will be really slow
		// and really potentially fragment memory
		bufsize += 256 * 1024;
	    }
	    if (bufsize < buflen + retlen) bufsize = buflen + retlen;
	    buf = (uint8_t *)CFAllocatorReallocate(kCFAllocatorSystemDefault, buf, bufsize, 0);
	    if (!buf) HALT;
	}
	memmove(buf + buflen, sbuf, retlen);
	buflen += retlen;
        max -= retlen;
	if (max <= 0) {
	    *buffer = buf;
	    *length = buflen;
	    return true;
	}
    }
    return true;
}

CFPropertyListRef CFPropertyListCreateWithStream(CFAllocatorRef allocator, CFReadStreamRef stream, CFIndex streamLength, CFOptionFlags mutabilityOption, CFPropertyListFormat *format, CFErrorRef *error) {
    initStatics();
    
    CFAssert1(stream != NULL, __kCFLogAssertion, "%s(): NULL stream not allowed", __PRETTY_FUNCTION__);
    CFAssert1(CFReadStreamGetTypeID() == CFGetTypeID(stream), __kCFLogAssertion, "%s(): stream argument is not a read stream", __PRETTY_FUNCTION__);
    CFAssert1(kCFStreamStatusOpen == CFReadStreamGetStatus(stream) || kCFStreamStatusReading == CFReadStreamGetStatus(stream), __kCFLogAssertion, "%s():  stream is not open", __PRETTY_FUNCTION__);
    CFAssert2(mutabilityOption == kCFPropertyListImmutable || mutabilityOption == kCFPropertyListMutableContainers || mutabilityOption == kCFPropertyListMutableContainersAndLeaves, __kCFLogAssertion, "%s(): Unrecognized option %lu", __PRETTY_FUNCTION__, mutabilityOption);
    
    if (0 == streamLength) streamLength = LONG_MAX;
    CFErrorRef underlyingError = NULL;
    CFIndex buflen = 0;
    uint8_t *buffer = NULL;
    if (!__convertReadStreamToBytes(stream, streamLength, &buffer, &buflen, &underlyingError)) {
        if (error) {
            // Wrap the error from CFReadStream in a new error in the cocoa domain
            CFMutableDictionaryRef userInfo = CFDictionaryCreateMutable(kCFAllocatorSystemDefault, 0, &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); 
            CFDictionarySetValue(userInfo, kCFErrorDebugDescriptionKey, CFSTR("Property list reading could not be completed because the stream had an unknown error. Did you forget to open the stream?"));
            if (underlyingError) {
                CFDictionarySetValue(userInfo, kCFErrorUnderlyingErrorKey, underlyingError);
            }
            *error = CFErrorCreate(kCFAllocatorSystemDefault, kCFErrorDomainCocoa, kCFPropertyListReadStreamError, userInfo);
            CFRelease(userInfo);
        }
        if (underlyingError) {
            CFRelease(underlyingError);
        }
        return NULL;
    }
    
    if (!buffer || buflen < 6) {
        if (buffer) CFAllocatorDeallocate(kCFAllocatorSystemDefault, buffer);
        if (error) *error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("stream had too few bytes"));
        return NULL;
    }
    
    CFDataRef data = CFDataCreateWithBytesNoCopy(kCFAllocatorSystemDefault, buffer, buflen, kCFAllocatorSystemDefault);
    CFPropertyListRef pl = NULL; // initialize to null, because if the following call fails we must return NULL
    _CFPropertyListCreateWithData(allocator, data, mutabilityOption, error, true, format, NULL, &pl);
    CFRelease(data);
    
    return pl;
}

CFPropertyListRef CFPropertyListCreateFromStream(CFAllocatorRef allocator, CFReadStreamRef stream, CFIndex length, CFOptionFlags mutabilityOption, CFPropertyListFormat *format, CFStringRef *errorString) {
    initStatics();
    if (errorString) *errorString = NULL;
    CFErrorRef error = NULL;
    CFPropertyListRef result = CFPropertyListCreateWithStream(allocator, stream, length, mutabilityOption, format, &error);
    if (error && errorString) {
        *errorString = __copyErrorDebugDescription(error);
    }
    if (error) CFRelease(error);
    return result;
}


#pragma mark -
#pragma mark Property List Copies

static CFArrayRef _arrayDeepImmutableCopy(CFAllocatorRef allocator, CFArrayRef array, CFOptionFlags mutabilityOption) {
    CFArrayRef result = NULL;
    CFIndex i, c = CFArrayGetCount(array);
    if (c == 0) {
        result = CFArrayCreate(allocator, NULL, 0, &kCFTypeArrayCallBacks);
    } else {
        new_cftype_array(values, c);
        CFArrayGetValues(array, CFRangeMake(0, c), values);
        for (i = 0; i < c; i ++) {
            CFTypeRef newValue = CFPropertyListCreateDeepCopy(allocator, values[i], mutabilityOption);
            if (newValue == NULL) {
                break;
            }
            *((void **)values + i) = (void *)newValue;
        }
        result = (i == c) ? CFArrayCreate(allocator, values, c, &kCFTypeArrayCallBacks) : NULL;
        c = i;
        for (i = 0; i < c; i ++) CFRelease(values[i]);
        free_cftype_array(values);
    }
    return result;
}

static CFMutableArrayRef _arrayDeepMutableCopy(CFAllocatorRef allocator, CFArrayRef array, CFOptionFlags mutabilityOption) {
    CFIndex i, c = CFArrayGetCount(array);
    CFMutableArrayRef result = CFArrayCreateMutable(allocator, 0, &kCFTypeArrayCallBacks);
    if (result) {
        for (i = 0; i < c; i ++) {
            CFTypeRef newValue = CFPropertyListCreateDeepCopy(allocator, CFArrayGetValueAtIndex(array, i), mutabilityOption);
            if (!newValue) break;
            CFArrayAppendValue(result, newValue);
            CFRelease(newValue);
        }
        if (i != c) {
            CFRelease(result);
            result = NULL;
        }
    }
    return result;
}

CFPropertyListRef CFPropertyListCreateDeepCopy(CFAllocatorRef allocator, CFPropertyListRef propertyList, CFOptionFlags mutabilityOption) {
    initStatics();
    CFPropertyListRef result = NULL;
    CFAssert1(propertyList != NULL, __kCFLogAssertion, "%s(): cannot copy a NULL property list", __PRETTY_FUNCTION__);
    __CFAssertIsPList(propertyList);
    CFAssert2(mutabilityOption == kCFPropertyListImmutable || mutabilityOption == kCFPropertyListMutableContainers || mutabilityOption == kCFPropertyListMutableContainersAndLeaves, __kCFLogAssertion, "%s(): Unrecognized option %lu", __PRETTY_FUNCTION__, mutabilityOption);
	if (!CFPropertyListIsValid(propertyList, kCFPropertyListBinaryFormat_v1_0)) return NULL;
    
    CFTypeID typeID = CFGetTypeID(propertyList);
    if (typeID == dicttype) {
        CFDictionaryRef dict = (CFDictionaryRef)propertyList;
        Boolean isMutable = (mutabilityOption != kCFPropertyListImmutable);
        CFIndex count = CFDictionaryGetCount(dict);
        if (count == 0) {
            result = isMutable ? CFDictionaryCreateMutable(allocator, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks): CFDictionaryCreate(allocator, NULL, NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
        } else {
            new_cftype_array(keys, 2 * count);
            CFTypeRef *values;
            CFIndex i;
            values = keys+count;
            CFDictionaryGetKeysAndValues(dict, keys, values);
            for (i = 0; i < count; i ++) {
                CFTypeRef newKey = CFStringCreateCopy(allocator, (CFStringRef)keys[i]);
                if (newKey == NULL) {
                    break;
                }
                *((void **)keys + i) = (void *)newKey;
                CFTypeRef newValue = CFPropertyListCreateDeepCopy(allocator, values[i], mutabilityOption);
                if (newValue == NULL) {
                    CFRelease(keys[i]);
                    break;
                }
                *((void **)values + i) = (void *)newValue;
            }
            if (i == count) {
                result = isMutable ? CFDictionaryCreateMutable(allocator, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks) : CFDictionaryCreate(allocator, keys, values, count, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
                for (i = 0; i < count; i ++) {
                    if (isMutable) {
                        CFDictionarySetValue((CFMutableDictionaryRef)result, keys[i], values[i]);
                    }
                    CFRelease(keys[i]);
                    CFRelease(values[i]);
                }
            } else {
                result = NULL;
                count = i;
                for (i = 0; i < count; i ++) {
                    CFRelease(keys[i]);
                    CFRelease(values[i]);
                }
            }
            free_cftype_array(keys);
        }
    } else if (typeID == arraytype) {
        if (mutabilityOption == kCFPropertyListImmutable) {
            result = _arrayDeepImmutableCopy(allocator, (CFArrayRef)propertyList, mutabilityOption);
        } else {
            result = _arrayDeepMutableCopy(allocator, (CFArrayRef)propertyList, mutabilityOption);
        }
    } else if (typeID == datatype) {
        if (mutabilityOption == kCFPropertyListMutableContainersAndLeaves) {
            result = CFDataCreateMutableCopy(allocator, 0, (CFDataRef)propertyList);
        } else {
            result = CFDataCreateCopy(allocator, (CFDataRef)propertyList);
        }
    } else if (typeID == numbertype) {
        // Warning - this will break if byteSize is ever greater than 128
        uint8_t bytes[128];
        CFNumberType numType = _CFNumberGetType2((CFNumberRef)propertyList);
        CFNumberGetValue((CFNumberRef)propertyList, numType, (void *)bytes);
        result = CFNumberCreate(allocator, numType, (void *)bytes);
    } else if (typeID == booltype) {
        // Booleans are immutable & shared instances
        CFRetain(propertyList);
        result = propertyList;
    } else if (typeID == datetype) {
        // Dates are immutable
        result = CFDateCreate(allocator, CFDateGetAbsoluteTime((CFDateRef)propertyList));
    } else if (typeID == stringtype) {
        if (mutabilityOption == kCFPropertyListMutableContainersAndLeaves) {
            result = CFStringCreateMutableCopy(allocator, 0, (CFStringRef)propertyList);
        } else {
            result = CFStringCreateCopy(allocator, (CFStringRef)propertyList);
        }
    } else {
        CFAssert2(false, __kCFLogAssertion, "%s(): %p is not a property list type", __PRETTY_FUNCTION__, propertyList);
        result = NULL;
    }
    return result;
}

