Project import
diff --git a/CoreFoundation/APPLE_LICENSE b/CoreFoundation/APPLE_LICENSE
new file mode 100644
index 0000000..fe81a60
--- /dev/null
+++ b/CoreFoundation/APPLE_LICENSE
@@ -0,0 +1,367 @@
+APPLE PUBLIC SOURCE LICENSE
+Version 2.0 - August 6, 2003
+
+Please read this License carefully before downloading this software.
+By downloading or using this software, you are agreeing to be bound by
+the terms of this License. If you do not or cannot agree to the terms
+of this License, please do not download or use the software.
+
+1. General; Definitions. This License applies to any program or other
+work which Apple Computer, Inc. ("Apple") makes publicly available and
+which contains a notice placed by Apple identifying such program or
+work as "Original Code" and stating that it is subject to the terms of
+this Apple Public Source License version 2.0 ("License"). As used in
+this License:
+
+1.1 "Applicable Patent Rights" mean: (a) in the case where Apple is
+the grantor of rights, (i) claims of patents that are now or hereafter
+acquired, owned by or assigned to Apple and (ii) that cover subject
+matter contained in the Original Code, but only to the extent
+necessary to use, reproduce and/or distribute the Original Code
+without infringement; and (b) in the case where You are the grantor of
+rights, (i) claims of patents that are now or hereafter acquired,
+owned by or assigned to You and (ii) that cover subject matter in Your
+Modifications, taken alone or in combination with Original Code.
+
+1.2 "Contributor" means any person or entity that creates or
+contributes to the creation of Modifications.
+
+1.3 "Covered Code" means the Original Code, Modifications, the
+combination of Original Code and any Modifications, and/or any
+respective portions thereof.
+
+1.4 "Externally Deploy" means: (a) to sublicense, distribute or
+otherwise make Covered Code available, directly or indirectly, to
+anyone other than You; and/or (b) to use Covered Code, alone or as
+part of a Larger Work, in any way to provide a service, including but
+not limited to delivery of content, through electronic communication
+with a client other than You.
+
+1.5 "Larger Work" means a work which combines Covered Code or portions
+thereof with code not governed by the terms of this License.
+
+1.6 "Modifications" mean any addition to, deletion from, and/or change
+to, the substance and/or structure of the Original Code, any previous
+Modifications, the combination of Original Code and any previous
+Modifications, and/or any respective portions thereof. When code is
+released as a series of files, a Modification is: (a) any addition to
+or deletion from the contents of a file containing Covered Code;
+and/or (b) any new file or other representation of computer program
+statements that contains any part of Covered Code.
+
+1.7 "Original Code" means (a) the Source Code of a program or other
+work as originally made available by Apple under this License,
+including the Source Code of any updates or upgrades to such programs
+or works made available by Apple under this License, and that has been
+expressly identified by Apple as such in the header file(s) of such
+work; and (b) the object code compiled from such Source Code and
+originally made available by Apple under this License.
+
+1.8 "Source Code" means the human readable form of a program or other
+work that is suitable for making modifications to it, including all
+modules it contains, plus any associated interface definition files,
+scripts used to control compilation and installation of an executable
+(object code).
+
+1.9 "You" or "Your" means an individual or a legal entity exercising
+rights under this License. For legal entities, "You" or "Your"
+includes any entity which controls, is controlled by, or is under
+common control with, You, where "control" means (a) the power, direct
+or indirect, to cause the direction or management of such entity,
+whether by contract or otherwise, or (b) ownership of fifty percent
+(50%) or more of the outstanding shares or beneficial ownership of
+such entity.
+
+2. Permitted Uses; Conditions & Restrictions. Subject to the terms
+and conditions of this License, Apple hereby grants You, effective on
+the date You accept this License and download the Original Code, a
+world-wide, royalty-free, non-exclusive license, to the extent of
+Apple's Applicable Patent Rights and copyrights covering the Original
+Code, to do the following:
+
+2.1 Unmodified Code. You may use, reproduce, display, perform,
+internally distribute within Your organization, and Externally Deploy
+verbatim, unmodified copies of the Original Code, for commercial or
+non-commercial purposes, provided that in each instance:
+
+(a) You must retain and reproduce in all copies of Original Code the
+copyright and other proprietary notices and disclaimers of Apple as
+they appear in the Original Code, and keep intact all notices in the
+Original Code that refer to this License; and
+
+(b) You must include a copy of this License with every copy of Source
+Code of Covered Code and documentation You distribute or Externally
+Deploy, and You may not offer or impose any terms on such Source Code
+that alter or restrict this License or the recipients' rights
+hereunder, except as permitted under Section 6.
+
+2.2 Modified Code. You may modify Covered Code and use, reproduce,
+display, perform, internally distribute within Your organization, and
+Externally Deploy Your Modifications and Covered Code, for commercial
+or non-commercial purposes, provided that in each instance You also
+meet all of these conditions:
+
+(a) You must satisfy all the conditions of Section 2.1 with respect to
+the Source Code of the Covered Code;
+
+(b) You must duplicate, to the extent it does not already exist, the
+notice in Exhibit A in each file of the Source Code of all Your
+Modifications, and cause the modified files to carry prominent notices
+stating that You changed the files and the date of any change; and
+
+(c) If You Externally Deploy Your Modifications, You must make
+Source Code of all Your Externally Deployed Modifications either
+available to those to whom You have Externally Deployed Your
+Modifications, or publicly available. Source Code of Your Externally
+Deployed Modifications must be released under the terms set forth in
+this License, including the license grants set forth in Section 3
+below, for as long as you Externally Deploy the Covered Code or twelve
+(12) months from the date of initial External Deployment, whichever is
+longer. You should preferably distribute the Source Code of Your
+Externally Deployed Modifications electronically (e.g. download from a
+web site).
+
+2.3 Distribution of Executable Versions. In addition, if You
+Externally Deploy Covered Code (Original Code and/or Modifications) in
+object code, executable form only, You must include a prominent
+notice, in the code itself as well as in related documentation,
+stating that Source Code of the Covered Code is available under the
+terms of this License with information on how and where to obtain such
+Source Code.
+
+2.4 Third Party Rights. You expressly acknowledge and agree that
+although Apple and each Contributor grants the licenses to their
+respective portions of the Covered Code set forth herein, no
+assurances are provided by Apple or any Contributor that the Covered
+Code does not infringe the patent or other intellectual property
+rights of any other entity. Apple and each Contributor disclaim any
+liability to You for claims brought by any other entity based on
+infringement of intellectual property rights or otherwise. As a
+condition to exercising the rights and licenses granted hereunder, You
+hereby assume sole responsibility to secure any other intellectual
+property rights needed, if any. For example, if a third party patent
+license is required to allow You to distribute the Covered Code, it is
+Your responsibility to acquire that license before distributing the
+Covered Code.
+
+3. Your Grants. In consideration of, and as a condition to, the
+licenses granted to You under this License, You hereby grant to any
+person or entity receiving or distributing Covered Code under this
+License a non-exclusive, royalty-free, perpetual, irrevocable license,
+under Your Applicable Patent Rights and other intellectual property
+rights (other than patent) owned or controlled by You, to use,
+reproduce, display, perform, modify, sublicense, distribute and
+Externally Deploy Your Modifications of the same scope and extent as
+Apple's licenses under Sections 2.1 and 2.2 above.
+
+4. Larger Works. You may create a Larger Work by combining Covered
+Code with other code not governed by the terms of this License and
+distribute the Larger Work as a single product. In each such instance,
+You must make sure the requirements of this License are fulfilled for
+the Covered Code or any portion thereof.
+
+5. Limitations on Patent License. Except as expressly stated in
+Section 2, no other patent rights, express or implied, are granted by
+Apple herein. Modifications and/or Larger Works may require additional
+patent licenses from Apple which Apple may grant in its sole
+discretion.
+
+6. Additional Terms. You may choose to offer, and to charge a fee for,
+warranty, support, indemnity or liability obligations and/or other
+rights consistent with the scope of the license granted herein
+("Additional Terms") to one or more recipients of Covered Code.
+However, You may do so only on Your own behalf and as Your sole
+responsibility, and not on behalf of Apple or any Contributor. You
+must obtain the recipient's agreement that any such Additional Terms
+are offered by You alone, and You hereby agree to indemnify, defend
+and hold Apple and every Contributor harmless for any liability
+incurred by or claims asserted against Apple or such Contributor by
+reason of any such Additional Terms.
+
+7. Versions of the License. Apple may publish revised and/or new
+versions of this License from time to time. Each version will be given
+a distinguishing version number. Once Original Code has been published
+under a particular version of this License, You may continue to use it
+under the terms of that version. You may also choose to use such
+Original Code under the terms of any subsequent version of this
+License published by Apple. No one other than Apple has the right to
+modify the terms applicable to Covered Code created under this
+License.
+
+8. NO WARRANTY OR SUPPORT. The Covered Code may contain in whole or in
+part pre-release, untested, or not fully tested works. The Covered
+Code may contain errors that could cause failures or loss of data, and
+may be incomplete or contain inaccuracies. You expressly acknowledge
+and agree that use of the Covered Code, or any portion thereof, is at
+Your sole and entire risk. THE COVERED CODE IS PROVIDED "AS IS" AND
+WITHOUT WARRANTY, UPGRADES OR SUPPORT OF ANY KIND AND APPLE AND
+APPLE'S LICENSOR(S) (COLLECTIVELY REFERRED TO AS "APPLE" FOR THE
+PURPOSES OF SECTIONS 8 AND 9) AND ALL CONTRIBUTORS EXPRESSLY DISCLAIM
+ALL WARRANTIES AND/OR CONDITIONS, EXPRESS OR IMPLIED, INCLUDING, BUT
+NOT LIMITED TO, THE IMPLIED WARRANTIES AND/OR CONDITIONS OF
+MERCHANTABILITY, OF SATISFACTORY QUALITY, OF FITNESS FOR A PARTICULAR
+PURPOSE, OF ACCURACY, OF QUIET ENJOYMENT, AND NONINFRINGEMENT OF THIRD
+PARTY RIGHTS. APPLE AND EACH CONTRIBUTOR DOES NOT WARRANT AGAINST
+INTERFERENCE WITH YOUR ENJOYMENT OF THE COVERED CODE, THAT THE
+FUNCTIONS CONTAINED IN THE COVERED CODE WILL MEET YOUR REQUIREMENTS,
+THAT THE OPERATION OF THE COVERED CODE WILL BE UNINTERRUPTED OR
+ERROR-FREE, OR THAT DEFECTS IN THE COVERED CODE WILL BE CORRECTED. NO
+ORAL OR WRITTEN INFORMATION OR ADVICE GIVEN BY APPLE, AN APPLE
+AUTHORIZED REPRESENTATIVE OR ANY CONTRIBUTOR SHALL CREATE A WARRANTY.
+You acknowledge that the Covered Code is not intended for use in the
+operation of nuclear facilities, aircraft navigation, communication
+systems, or air traffic control machines in which case the failure of
+the Covered Code could lead to death, personal injury, or severe
+physical or environmental damage.
+
+9. LIMITATION OF LIABILITY. TO THE EXTENT NOT PROHIBITED BY LAW, IN NO
+EVENT SHALL APPLE OR ANY CONTRIBUTOR BE LIABLE FOR ANY INCIDENTAL,
+SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR RELATING
+TO THIS LICENSE OR YOUR USE OR INABILITY TO USE THE COVERED CODE, OR
+ANY PORTION THEREOF, WHETHER UNDER A THEORY OF CONTRACT, WARRANTY,
+TORT (INCLUDING NEGLIGENCE), PRODUCTS LIABILITY OR OTHERWISE, EVEN IF
+APPLE OR SUCH CONTRIBUTOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES AND NOTWITHSTANDING THE FAILURE OF ESSENTIAL PURPOSE OF ANY
+REMEDY. SOME JURISDICTIONS DO NOT ALLOW THE LIMITATION OF LIABILITY OF
+INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THIS LIMITATION MAY NOT APPLY
+TO YOU. In no event shall Apple's total liability to You for all
+damages (other than as may be required by applicable law) under this
+License exceed the amount of fifty dollars ($50.00).
+
+10. Trademarks. This License does not grant any rights to use the
+trademarks or trade names "Apple", "Apple Computer", "Mac", "Mac OS",
+"QuickTime", "QuickTime Streaming Server" or any other trademarks,
+service marks, logos or trade names belonging to Apple (collectively
+"Apple Marks") or to any trademark, service mark, logo or trade name
+belonging to any Contributor. You agree not to use any Apple Marks in
+or as part of the name of products derived from the Original Code or
+to endorse or promote products derived from the Original Code other
+than as expressly permitted by and in strict compliance at all times
+with Apple's third party trademark usage guidelines which are posted
+at http://www.apple.com/legal/guidelinesfor3rdparties.html.
+
+11. Ownership. Subject to the licenses granted under this License,
+each Contributor retains all rights, title and interest in and to any
+Modifications made by such Contributor. Apple retains all rights,
+title and interest in and to the Original Code and any Modifications
+made by or on behalf of Apple ("Apple Modifications"), and such Apple
+Modifications will not be automatically subject to this License. Apple
+may, at its sole discretion, choose to license such Apple
+Modifications under this License, or on different terms from those
+contained in this License or may choose not to license them at all.
+
+12. Termination.
+
+12.1 Termination. This License and the rights granted hereunder will
+terminate:
+
+(a) automatically without notice from Apple if You fail to comply with
+any term(s) of this License and fail to cure such breach within 30
+days of becoming aware of such breach;
+
+(b) immediately in the event of the circumstances described in Section
+13.5(b); or
+
+(c) automatically without notice from Apple if You, at any time during
+the term of this License, commence an action for patent infringement
+against Apple; provided that Apple did not first commence
+an action for patent infringement against You in that instance.
+
+12.2 Effect of Termination. Upon termination, You agree to immediately
+stop any further use, reproduction, modification, sublicensing and
+distribution of the Covered Code. All sublicenses to the Covered Code
+which have been properly granted prior to termination shall survive
+any termination of this License. Provisions which, by their nature,
+should remain in effect beyond the termination of this License shall
+survive, including but not limited to Sections 3, 5, 8, 9, 10, 11,
+12.2 and 13. No party will be liable to any other for compensation,
+indemnity or damages of any sort solely as a result of terminating
+this License in accordance with its terms, and termination of this
+License will be without prejudice to any other right or remedy of
+any party.
+
+13. Miscellaneous.
+
+13.1 Government End Users. The Covered Code is a "commercial item" as
+defined in FAR 2.101. Government software and technical data rights in
+the Covered Code include only those rights customarily provided to the
+public as defined in this License. This customary commercial license
+in technical data and software is provided in accordance with FAR
+12.211 (Technical Data) and 12.212 (Computer Software) and, for
+Department of Defense purchases, DFAR 252.227-7015 (Technical Data --
+Commercial Items) and 227.7202-3 (Rights in Commercial Computer
+Software or Computer Software Documentation). Accordingly, all U.S.
+Government End Users acquire Covered Code with only those rights set
+forth herein.
+
+13.2 Relationship of Parties. This License will not be construed as
+creating an agency, partnership, joint venture or any other form of
+legal association between or among You, Apple or any Contributor, and
+You will not represent to the contrary, whether expressly, by
+implication, appearance or otherwise.
+
+13.3 Independent Development. Nothing in this License will impair
+Apple's right to acquire, license, develop, have others develop for
+it, market and/or distribute technology or products that perform the
+same or similar functions as, or otherwise compete with,
+Modifications, Larger Works, technology or products that You may
+develop, produce, market or distribute.
+
+13.4 Waiver; Construction. Failure by Apple or any Contributor to
+enforce any provision of this License will not be deemed a waiver of
+future enforcement of that or any other provision. Any law or
+regulation which provides that the language of a contract shall be
+construed against the drafter will not apply to this License.
+
+13.5 Severability. (a) If for any reason a court of competent
+jurisdiction finds any provision of this License, or portion thereof,
+to be unenforceable, that provision of the License will be enforced to
+the maximum extent permissible so as to effect the economic benefits
+and intent of the parties, and the remainder of this License will
+continue in full force and effect. (b) Notwithstanding the foregoing,
+if applicable law prohibits or restricts You from fully and/or
+specifically complying with Sections 2 and/or 3 or prevents the
+enforceability of either of those Sections, this License will
+immediately terminate and You must immediately discontinue any use of
+the Covered Code and destroy all copies of it that are in your
+possession or control.
+
+13.6 Dispute Resolution. Any litigation or other dispute resolution
+between You and Apple relating to this License shall take place in the
+Northern District of California, and You and Apple hereby consent to
+the personal jurisdiction of, and venue in, the state and federal
+courts within that District with respect to this License. The
+application of the United Nations Convention on Contracts for the
+International Sale of Goods is expressly excluded.
+
+13.7 Entire Agreement; Governing Law. This License constitutes the
+entire agreement between the parties with respect to the subject
+matter hereof. This License shall be governed by the laws of the
+United States and the State of California, except that body of
+California law concerning conflicts of law.
+
+Where You are located in the province of Quebec, Canada, the following
+clause applies: The parties hereby confirm that they have requested
+that this License and all related documents be drafted in English. Les
+parties ont exige que le present contrat et tous les documents
+connexes soient rediges en anglais.
+
+EXHIBIT A.
+
+"Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights
+Reserved.
+
+This file contains Original Code and/or Modifications of Original Code
+as defined in and that are subject to the Apple Public Source License
+Version 2.0 (the 'License'). You may not use this file except in
+compliance with the License. Please obtain a copy of the License at
+http://www.opensource.apple.com/apsl/ and read it before using this
+file.
+
+The Original Code and all software distributed under the License are
+distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+Please see the License for the specific language governing rights and
+limitations under the License."
diff --git a/CoreFoundation/Android.mk b/CoreFoundation/Android.mk
new file mode 100644
index 0000000..124957f
--- /dev/null
+++ b/CoreFoundation/Android.mk
@@ -0,0 +1,131 @@
+LOCAL_PATH := $(call my-dir)
+
+opencflite_src_files := \
+CFApplicationPreferences.c \
+CFArray.c \
+CFBag.c \
+CFBase.c \
+CFBinaryHeap.c \
+CFBinaryPList.c \
+CFBitVector.c \
+CFBuiltinConverters.c \
+CFBundle.c \
+CFBundle_Resources.c \
+CFCalendar.c \
+CFCharacterSet.c \
+CFConcreteStreams.c \
+CFData.c \
+CFDate.c \
+CFDateFormatter.c \
+CFDictionary.c \
+CFError.c \
+CFFileUtilities.c \
+CFLocale.c \
+CFLocaleIdentifier.c \
+CFNumber.c \
+CFNumberFormatter.c \
+CFPlatform.c \
+CFPlugIn.c \
+CFPlugIn_Factory.c \
+CFPlugIn_PlugIn.c \
+CFPreferences.c \
+CFPropertyList.c \
+CFRunLoop.c \
+CFRuntime.c \
+CFSet.c \
+CFSocket.c \
+CFSocketStream.c \
+CFSortFunctions.c \
+CFStorage.c \
+CFStream.c \
+CFString.c \
+CFStringEncodingConverter.c \
+CFStringEncodings.c \
+CFStringScanner.c \
+CFStringUtilities.c \
+CFSystemDirectories.c \
+CFTimeZone.c \
+CFTree.c \
+CFUniChar.c \
+CFUnicodeDecomposition.c \
+CFUnicodePrecomposition.c \
+CFURLAccess.c \
+CFURL.c \
+CFUtilities.c \
+CFUUID.c \
+CFVersion.c \
+CFWindowsMessageQueue.c \
+CFXMLPreferencesDomain.c \
+compat/flsl.c
+
+# disabled for now
+#CFMachPort.c
+#CFMessagePort.c
+#CFPlugIn_Instance.c
+#CFUserNotification.c
+#CFXMLInputStream.c
+#CFXMLNode.c
+#CFXMLParser.c
+#CFXMLTree.c
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := libopencflite
+LOCAL_SRC_FILES := $(opencflite_src_files)
+LOCAL_C_INCLUDES := $(LOCAL_PATH)/..
+LOCAL_C_INCLUDES += $(LOCAL_PATH)/include
+LOCAL_C_INCLUDES += ${ANDROID_BUILD_TOP}/external/icu/icu4c/source/common/
+LOCAL_C_INCLUDES += ${ANDROID_BUILD_TOP}/external/icu/icu4c/source/i18n/
+LOCAL_C_INCLUDES += ${ANDROID_BUILD_TOP}/external/icu/icu4c/source/tools/tzcode/
+LOCAL_C_INCLUDES += ${ANDROID_BUILD_TOP}/external/opencflite/libBlocksRuntime/
+# todo: remove Linux case
+LOCAL_EXPORT_CFLAGS := -DDEPLOYMENT_TARGET_LINUX -DDEPLOYMENT_TARGET_ANDROID
+LOCAL_CFLAGS = -x c -fblocks -std=gnu99 -Wno-trigraphs -fexceptions -DCF_BUILDING_CF=1 -DDISABLE_GCD -nostdlibinc -D__kCFDataDir=\"/etc/opencflite\" $(LOCAL_EXPORT_CFLAGS) -Wno-infinite-recursion -Wno-unused-parameter -Wno-unsequenced -Wno-date-time -Wno-implicit -Wno-tautological-pointer-compare
+#note: not all flags from MakefileLinux have been ported over.
+LOCAL_LDFLAGS = -fpic
+LOCAL_SHARED_LIBRARIES += libicuuc libicui18n
+include $(BUILD_SHARED_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := libopencflite
+LOCAL_SRC_FILES := $(opencflite_src_files)
+LOCAL_C_INCLUDES := $(LOCAL_PATH)/..
+LOCAL_C_INCLUDES += $(LOCAL_PATH)/include
+LOCAL_C_INCLUDES += ${ANDROID_BUILD_TOP}/external/icu/icu4c/source/common/
+LOCAL_C_INCLUDES += ${ANDROID_BUILD_TOP}/external/icu/icu4c/source/i18n/
+LOCAL_C_INCLUDES += ${ANDROID_BUILD_TOP}/external/icu/icu4c/source/tools/tzcode/
+LOCAL_C_INCLUDES += ${ANDROID_BUILD_TOP}/external/opencflite/libBlocksRuntime/
+# todo: remove Linux case
+LOCAL_EXPORT_CFLAGS := -DDEPLOYMENT_TARGET_LINUX -DDEPLOYMENT_TARGET_ANDROID
+LOCAL_CFLAGS = -x c -fblocks -std=gnu99 -Wno-trigraphs -fexceptions -DCF_BUILDING_CF=1 -DDISABLE_GCD -nostdlibinc -D__kCFDataDir=\"/etc/opencflite\" $(LOCAL_EXPORT_CFLAGS) -Wno-infinite-recursion -Wno-unused-parameter -Wno-unsequenced -Wno-date-time -Wno-implicit -Wno-tautological-pointer-compare
+#note: not all flags from MakefileLinux have been ported over.
+LOCAL_LDFLAGS = -fpic
+LOCAL_STATIC_LIBRARIES += libicuuc_static libicui18n_static
+include $(BUILD_STATIC_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := CFCharacterSetBitmaps.bitmap
+LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/opencflite/CoreFoundation/CharacterSets
+LOCAL_MODULE_CLASS := ETC
+LOCAL_SRC_FILES := CFCharacterSetBitmaps.bitmap
+include $(BUILD_PREBUILT)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := CFUnicodeData-B.mapping
+LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/opencflite/CoreFoundation/CharacterSets
+LOCAL_MODULE_CLASS := ETC
+LOCAL_SRC_FILES := CFUnicodeData-B.mapping
+include $(BUILD_PREBUILT)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := CFUniCharPropertyDatabase.data
+LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/opencflite/CoreFoundation/CharacterSets
+LOCAL_MODULE_CLASS := ETC
+LOCAL_SRC_FILES := CFUniCharPropertyDatabase.data
+include $(BUILD_PREBUILT)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := CFUnicodeData-L.mapping
+LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/opencflite/CoreFoundation/CharacterSets
+LOCAL_MODULE_CLASS := ETC
+LOCAL_SRC_FILES := CFUnicodeData-L.mapping
+include $(BUILD_PREBUILT)
diff --git a/CoreFoundation/BuildCFLite b/CoreFoundation/BuildCFLite
new file mode 100644
index 0000000..bbde7dd
--- /dev/null
+++ b/CoreFoundation/BuildCFLite
@@ -0,0 +1,92 @@
+#/bin/sh
+
+echo "Setup ..."
+
+ALL_CFILES=`ls *.c`
+ALL_HFILES=`ls *.h`
+
+MACHINE_TYPE=`uname -p`
+UNICODE_DATA_FILE="UNKNOWN"
+
+if [ "$MACHINE_TYPE" == "i386" ]; then
+	UNICODE_DATA_FILE="CFUnicodeData-L.mapping"
+fi
+
+if [ "$MACHINE_TYPE" == "powerpc" ]; then
+	UNICODE_DATA_FILE="CFUnicodeData-B.mapping"
+fi
+
+
+
+PUBLIC_HEADERS="CFArray.h CFBag.h CFBase.h CFBinaryHeap.h CFBitVector.h CFBundle.h CFByteOrder.h CFCalendar.h CFCharacterSet.h CFData.h CFDate.h CFDateFormatter.h CFDictionary.h CFError.h CFLocale.h CFMachPort.h CFMessagePort.h CFNumber.h CFNumberFormatter.h CFPlugIn.h CFPlugInCOM.h CFPreferences.h CFPropertyList.h CFRunLoop.h CFSet.h CFSocket.h CFStream.h CFString.h CFStringEncodingExt.h CFTimeZone.h CFTree.h CFURL.h CFURLAccess.h CFUUID.h CFUserNotification.h CFXMLNode.h CFXMLParser.h CoreFoundation.h"
+PRIVATE_HEADERS="CFBundlePriv.h CFCharacterSetPriv.h CFError_Private.h CFLogUtilities.h CFPriv.h CFRuntime.h CFStorage.h CFStreamAbstract.h CFStreamPriv.h CFStreamInternal.h CFStringDefaultEncoding.h CFStringEncodingConverter.h CFStringEncodingConverterExt.h CFUniChar.h CFUnicodeDecomposition.h CFUnicodePrecomposition.h ForFoundationOnly.h"
+
+OBJBASE=../CF-Objects
+ARCHFLAGS="-arch ppc -arch ppc64 -arch i386 -arch x86_64"
+CFLAGS="-c -pipe -std=gnu99 -g -Wmost -Wno-trigraphs -mmacosx-version-min=10.5 -fconstant-cfstrings -fexceptions -DCF_BUILDING_CF=1 -DDEPLOYMENT_TARGET_MACOSX=1 -DMAC_OS_X_VERSION_MAX_ALLOWED=MAC_OS_X_VERSION_10_5 -DU_SHOW_DRAFT_API=1 -I$OBJBASE -I. -I./include/mach_support -DVERSION=476.17"
+LFLAGS="-dynamiclib -mmacosx-version-min=10.5 -twolevel_namespace -init ___CFInitialize -compatibility_version 150 -current_version 476 -sectcreate __UNICODE __csbitmaps CFCharacterSetBitmaps.bitmap -sectcreate __UNICODE __properties CFUniCharPropertyDatabase.data -sectcreate __UNICODE __data $UNICODE_DATA_FILE -segprot __UNICODE r r"
+
+/bin/rm -rf $OBJBASE
+/bin/mkdir -p $OBJBASE
+/bin/mkdir $OBJBASE/normal
+/bin/mkdir $OBJBASE/CoreFoundation
+/bin/cp $ALL_HFILES $OBJBASE/CoreFoundation
+if [ $? -ne 0 ]; then
+	echo "Setup failed"
+	exit 1
+fi
+
+Build () {
+	echo "Compiling $STYLE ..."
+	for F in $ALL_CFILES ; do
+		echo /usr/bin/gcc $STYLE_CFLAGS $ARCHFLAGS $CFLAGS $F -o $OBJBASE/$STYLE/`basename $F .c`.o
+		/usr/bin/gcc $STYLE_CFLAGS $ARCHFLAGS $CFLAGS $F -o $OBJBASE/$STYLE/`basename $F .c`.o
+		if [ $? -ne 0 ]; then
+			echo "*** Compiling $STYLE failed ***"
+			exit 1
+		fi
+	done
+	echo "Linking $STYLE ..."
+	echo /usr/bin/gcc $STYLE_LFLAGS -install_name /System/Library/Frameworks/CFLite.framework/Versions/A/CFLite_$STYLE $ARCHFLAGS $LFLAGS $OBJBASE/$STYLE/*.o -licucore.A -lobjc -o $OBJBASE/CFLite_$STYLE
+	/usr/bin/gcc $STYLE_LFLAGS -install_name /System/Library/Frameworks/CFLite.framework/Versions/A/CFLite_$STYLE $ARCHFLAGS $LFLAGS $OBJBASE/$STYLE/*.o -licucore.A -lobjc -o $OBJBASE/CFLite_$STYLE
+	if [ $? -ne 0 ]; then
+		echo "*** Linking $STYLE failed ***"
+		exit 1
+	fi
+}
+
+STYLE=normal
+STYLE_CFLAGS="-O0"
+STYLE_LFLAGS=
+Build
+
+echo "Building done."
+
+echo "Installing ..."
+if [ -z "$DSTBASE" ]; then DSTBASE=../CF-Root ; fi
+
+/bin/rm -rf $DSTBASE/CFLite.framework
+/bin/mkdir -p $DSTBASE/CFLite.framework/Versions/A/Resources
+/bin/mkdir -p $DSTBASE/CFLite.framework/Versions/A/Headers
+/bin/mkdir -p $DSTBASE/CFLite.framework/Versions/A/PrivateHeaders
+/bin/ln -sf A $DSTBASE/CFLite.framework/Versions/Current
+/bin/ln -sf Versions/Current/Resources $DSTBASE/CFLite.framework/Resources
+/bin/ln -sf Versions/Current/Headers $DSTBASE/CFLite.framework/Headers
+/bin/ln -sf Versions/Current/PrivateHeaders $DSTBASE/CFLite.framework/PrivateHeaders
+/bin/ln -sf Versions/Current/CFLite $DSTBASE/CFLite.framework/CFLite
+/bin/cp Info.plist $DSTBASE/CFLite.framework/Versions/A/Resources
+/bin/mkdir -p $DSTBASE/CFLite.framework/Versions/A/Resources/en.lproj
+/bin/cp $PUBLIC_HEADERS $DSTBASE/CFLite.framework/Versions/A/Headers
+/bin/cp $PRIVATE_HEADERS $DSTBASE/CFLite.framework/Versions/A/PrivateHeaders
+#/usr/bin/strip -S -o $DSTBASE/CFLite.framework/Versions/A/CFLite $OBJBASE/CFLite_normal
+/bin/cp $OBJBASE/CFLite_normal $DSTBASE/CFLite.framework/Versions/A/CFLite 
+/usr/sbin/chown -RH -f root:wheel $DSTBASE/CFLite.framework
+/bin/chmod -RH a-w,a+rX $DSTBASE/CFLite.framework
+/bin/chmod -RH u+w $DSTBASE
+
+install_name_tool -id /System/Library/Frameworks/CFLite.framework/Versions/A/CFLite $DSTBASE/CFLite.framework/Versions/A/CFLite
+
+echo "Installing done.  The framework is in $DSTBASE"
+
+exit 0
+
diff --git a/CoreFoundation/BuildCFLite.windows b/CoreFoundation/BuildCFLite.windows
new file mode 100644
index 0000000..ba0ab1e
--- /dev/null
+++ b/CoreFoundation/BuildCFLite.windows
@@ -0,0 +1,101 @@
+#/bin/sh
+
+echo "Setup ..."
+
+ALL_CFILES=`ls *.c`
+ALL_HFILES=`ls *.h`
+CC="/mingw/bin/gcc"
+AR="/mingw/bin/ar"
+
+MACHINE_TYPE=`uname -p`
+UNICODE_DATA_FILE="UNKNOWN"
+# DEPLOYMENT_TARGET="-DDEPLOYMENT_TARGET_MACOSX=1"
+DEPLOYMENT_TARGET="-DDEPLOYMENT_TARGET_WIN32=1"
+#MACOSVERS="-mmacosx-version-min=10.5 -fconstant-cfstrings"
+MACOSVERS=""
+#WARNINGS="-Wmost"
+WARNINGS=""
+
+if [ "$MACHINE_TYPE" == "i386" ]; then
+	UNICODE_DATA_FILE="CFUnicodeData-L.mapping"
+fi
+
+if [ "$MACHINE_TYPE" == "powerpc" ]; then
+	UNICODE_DATA_FILE="CFUnicodeData-B.mapping"
+fi
+
+
+
+PUBLIC_HEADERS="CFArray.h CFBag.h CFBase.h CFBinaryHeap.h CFBitVector.h CFBundle.h CFByteOrder.h CFCalendar.h CFCharacterSet.h CFData.h CFDate.h CFDateFormatter.h CFDictionary.h CFError.h CFLocale.h CFMachPort.h CFMessagePort.h CFNumber.h CFNumberFormatter.h CFPlugIn.h CFPlugInCOM.h CFPreferences.h CFPropertyList.h CFRunLoop.h CFSet.h CFSocket.h CFStream.h CFString.h CFStringEncodingExt.h CFTimeZone.h CFTree.h CFURL.h CFURLAccess.h CFUUID.h CFUserNotification.h CFXMLNode.h CFXMLParser.h CoreFoundation.h"
+PRIVATE_HEADERS="CFBundlePriv.h CFCharacterSetPriv.h CFError_Private.h CFLogUtilities.h CFPriv.h CFRuntime.h CFStorage.h CFStreamAbstract.h CFStreamPriv.h CFStreamInternal.h CFStringDefaultEncoding.h CFStringEncodingConverter.h CFStringEncodingConverterExt.h CFUniChar.h CFUnicodeDecomposition.h CFUnicodePrecomposition.h ForFoundationOnly.h"
+
+OBJBASE=../CF-Objects
+#ARCHFLAGS="-arch ppc -arch ppc64 -arch i386 -arch x86_64"
+ARCHFLAGS=""
+CFLAGS="-c -pipe -std=gnu99 -g $WARNINGS -Wno-trigraphs $MACOSVERS -fexceptions -DCF_BUILDING_CF=1 $DEPLOYMENT_TARGET -DMAC_OS_X_VERSION_MAX_ALLOWED=MAC_OS_X_VERSION_10_5 -DU_SHOW_DRAFT_API=1 -I. -I./Compatability -I$OBJBASE -DVERSION=476.17 -DWINVER=0x0500 -D_WIN32_WINNT=0x0501"
+# LFLAGS="-dynamiclib -mmacosx-version-min=10.5 -twolevel_namespace -init ___CFInitialize -compatibility_version 150 -current_version 476 -sectcreate __UNICODE __csbitmaps CFCharacterSetBitmaps.bitmap -sectcreate __UNICODE __properties CFUniCharPropertyDatabase.data -sectcreate __UNICODE __data $UNICODE_DATA_FILE -segprot __UNICODE r r"
+LFLAGS="-lmsvcrt -lnetapi32 -lobjc -lole32 -lws2_32 -lkernel32 -lrpcrt4"
+
+/bin/rm -rf $OBJBASE
+/bin/mkdir -p $OBJBASE
+/bin/mkdir $OBJBASE/normal
+/bin/mkdir $OBJBASE/CoreFoundation
+/bin/cp $ALL_HFILES $OBJBASE/CoreFoundation
+if [ $? -ne 0 ]; then
+	echo "Setup failed"
+	exit 1
+fi
+
+Build () {
+	echo "Compiling $STYLE ..."
+	for F in $ALL_CFILES ; do
+		echo $CC $STYLE_CFLAGS $ARCHFLAGS $CFLAGS $F -o $OBJBASE/$STYLE/`basename $F .c`.o
+		$CC $STYLE_CFLAGS $ARCHFLAGS $CFLAGS $F -o $OBJBASE/$STYLE/`basename $F .c`.o
+		if [ $? -ne 0 ]; then
+			echo "*** Compiling $STYLE failed ***"
+			exit 1
+		fi
+	done
+	echo "Linking $STYLE ..."
+	echo $CC $STYLE_LFLAGS $ARCHFLAGS $OBJBASE/$STYLE/*.o $LFLAGS -licuuc -licuin -lobjc -o $OBJBASE/CoreFoundation_$STYLE
+	$CC -shared $STYLE_LFLAGS $ARCHFLAGS $OBJBASE/$STYLE/*.o $LFLAGS lib/icuuc.lib lib/icuin.lib -lobjc -o $OBJBASE/libCFlite_476_17.dll
+	if [ $? -ne 0 ]; then
+		echo "*** Linking $STYLE failed ***"
+		exit 1
+	fi
+}
+
+STYLE=normal
+STYLE_CFLAGS="-O2"
+STYLE_LFLAGS=
+Build
+
+echo "Building done."
+
+echo "Installing ..."
+if [ -z "$DSTBASE" ]; then DSTBASE=../CF-Root ; fi
+
+/bin/rm -rf $DSTBASE/CoreFoundation.framework
+/bin/mkdir -p $DSTBASE/CoreFoundation.framework/Versions/A/Resources
+/bin/mkdir -p $DSTBASE/CoreFoundation.framework/Versions/A/Headers
+/bin/mkdir -p $DSTBASE/CoreFoundation.framework/Versions/A/PrivateHeaders
+/bin/ln -sf A $DSTBASE/CoreFoundation.framework/Versions/Current
+/bin/ln -sf Versions/Current/Resources $DSTBASE/CoreFoundation.framework/Resources
+/bin/ln -sf Versions/Current/Headers $DSTBASE/CoreFoundation.framework/Headers
+/bin/ln -sf Versions/Current/PrivateHeaders $DSTBASE/CoreFoundation.framework/PrivateHeaders
+/bin/ln -sf Versions/Current/CoreFoundation $DSTBASE/CoreFoundation.framework/CoreFoundation
+/bin/cp Info.plist $DSTBASE/CoreFoundation.framework/Versions/A/Resources
+/bin/mkdir -p $DSTBASE/CoreFoundation.framework/Versions/A/Resources/en.lproj
+/bin/cp $PUBLIC_HEADERS $DSTBASE/CoreFoundation.framework/Versions/A/Headers
+/bin/cp $PRIVATE_HEADERS $DSTBASE/CoreFoundation.framework/Versions/A/PrivateHeaders
+/usr/bin/strip -S -o $DSTBASE/CoreFoundation.framework/Versions/A/CoreFoundation $OBJBASE/CoreFoundation_normal
+/usr/sbin/chown -RH -f root:wheel $DSTBASE/CoreFoundation.framework
+/bin/chmod -RH a-w,a+rX $DSTBASE/CoreFoundation.framework
+/bin/chmod -RH u+w $DSTBASE
+
+install_name_tool -id /System/Library/Frameworks/CoreFoundation/Versions/A/CoreFoundation $DSTBASE/CoreFoundation.framework/Versions/A/CoreFoundation
+
+echo "Installing done.  The framework is in $DSTBASE"
+
+exit 0
+
diff --git a/CoreFoundation/CFApplicationPreferences.c b/CoreFoundation/CFApplicationPreferences.c
new file mode 100644
index 0000000..2f5c68f
--- /dev/null
+++ b/CoreFoundation/CFApplicationPreferences.c
@@ -0,0 +1,682 @@
+/*
+ * Copyright (c) 2008-2009 Brent Fulgham <bfulgham@gmail.org>.  All rights reserved.
+ *
+ * This source code is a modified version of the CoreFoundation sources released by Apple Inc. under
+ * the terms of the APSL version 2.0 (see below).
+ *
+ * For information about changes from the original Apple source release can be found by reviewing the
+ * source control system for the project at https://sourceforge.net/svn/?group_id=246198.
+ *
+ * The original license information is as follows:
+ * 
+ * Copyright (c) 2008 Apple Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*	CFApplicationPreferences.c
+	Copyright 1998-2002, Apple, Inc. All rights reserved.
+	Responsibility: Chris Parker
+*/
+
+#include "CFInternal.h"
+#include <CoreFoundation/CFPreferences.h>
+#include <CoreFoundation/CFUniChar.h>
+#include <CoreFoundation/CFNumber.h>
+#include <CoreFoundation/CFString.h>
+#include <CoreFoundation/CFLocale.h>
+#include <CoreFoundation/CFNumberFormatter.h>
+#include <CoreFoundation/CFDateFormatter.h>
+#include <sys/types.h>
+#if __MACH__
+#include <unistd.h>
+#endif
+
+static Boolean _CFApplicationPreferencesSynchronizeNoLock(_CFApplicationPreferences *self);
+void _CFPreferencesDomainSetMultiple(CFPreferencesDomainRef domain, CFDictionaryRef dict);
+static void updateDictRep(_CFApplicationPreferences *self);
+static void _CFApplicationPreferencesSetSearchList(_CFApplicationPreferences *self, CFArrayRef newSearchList);
+Boolean _CFApplicationPreferencesContainsDomainNoLock(_CFApplicationPreferences *self, CFPreferencesDomainRef domain);
+static CFTypeRef _CFApplicationPreferencesCreateValueForKey2(_CFApplicationPreferences *self, CFStringRef defaultName);
+
+// Right now, nothing is getting destroyed pretty much ever.  We probably don't want this to be the case, but it's very tricky - domains live in the cache as well as a given application's preferences, and since they're not CFTypes, there's no reference count.  Also, it's not clear we ever want domains destroyed.  When they're synchronized, they clear their internal state (to force reading from the disk again), so they're not very big.... REW, 12/17/98
+
+CFPropertyListRef CFPreferencesCopyAppValue(CFStringRef key, CFStringRef appName) {
+    _CFApplicationPreferences *standardPrefs;
+    CFAssert1(appName != NULL, __kCFLogAssertion, "%s(): Cannot access application preferences with a NULL application name", __PRETTY_FUNCTION__);
+    CFAssert1(key != NULL, __kCFLogAssertion, "%s(): Cannot access preferences with a NULL key", __PRETTY_FUNCTION__);
+    
+    standardPrefs = _CFStandardApplicationPreferences(appName);
+    return standardPrefs ? _CFApplicationPreferencesCreateValueForKey2(standardPrefs, key) : NULL;
+}
+
+CF_EXPORT Boolean CFPreferencesAppBooleanValue(CFStringRef key, CFStringRef appName, Boolean *keyExistsAndHasValidFormat) {
+    CFPropertyListRef value;
+    Boolean result, valid;
+    CFTypeID typeID = 0;
+    CFAssert1(appName != NULL, __kCFLogAssertion, "%s(): Cannot access application preferences with a NULL application name", __PRETTY_FUNCTION__);
+    CFAssert1(key != NULL, __kCFLogAssertion, "%s(): Cannot access preferences with a NULL key", __PRETTY_FUNCTION__);
+
+    if (!keyExistsAndHasValidFormat) {
+        keyExistsAndHasValidFormat = &valid;
+    }
+    value = CFPreferencesCopyAppValue(key, appName);
+    if (!value) {
+        *keyExistsAndHasValidFormat = false;
+        return false;
+    }
+    typeID = CFGetTypeID(value);
+    if (typeID == CFStringGetTypeID()) {
+        if (CFStringCompare((CFStringRef)value, CFSTR("true"), kCFCompareCaseInsensitive) == kCFCompareEqualTo || CFStringCompare((CFStringRef)value, CFSTR("YES"), kCFCompareCaseInsensitive) == kCFCompareEqualTo) {
+            *keyExistsAndHasValidFormat = true;
+            result = true;
+        } else if (CFStringCompare((CFStringRef)value, CFSTR("false"), kCFCompareCaseInsensitive) == kCFCompareEqualTo || CFStringCompare((CFStringRef)value, CFSTR("NO"), kCFCompareCaseInsensitive) == kCFCompareEqualTo) {
+            *keyExistsAndHasValidFormat = true;
+            result = false;
+        } else {
+            *keyExistsAndHasValidFormat = false;
+            result = false;
+        }
+    } else if (typeID == CFNumberGetTypeID()) {
+        if (CFNumberIsFloatType((CFNumberRef)value)) {
+            *keyExistsAndHasValidFormat = false;
+            result = false;
+        } else {
+            int i;
+            *keyExistsAndHasValidFormat = true;
+            CFNumberGetValue((CFNumberRef)value, kCFNumberIntType, &i);
+            result = (i == 0) ? false : true;
+        }
+    } else if (typeID == CFBooleanGetTypeID()) {
+        result = (value == kCFBooleanTrue);
+        *keyExistsAndHasValidFormat = true;
+    } else {
+        // Unknown type
+        result = false;
+        *keyExistsAndHasValidFormat = false;
+    }
+    CFRelease(value);
+    return result;
+}
+
+__private_extern__ CFIndex CFPreferencesAppIntegerValue(CFStringRef key, CFStringRef appName, Boolean *keyExistsAndHasValidFormat) {
+    CFPropertyListRef value;
+    CFIndex result;
+    CFTypeID typeID = 0;
+    Boolean valid;
+    CFAssert1(appName != NULL, __kCFLogAssertion, "%s(): Cannot access application preferences with a NULL application name", __PRETTY_FUNCTION__);
+    CFAssert1(key != NULL, __kCFLogAssertion, "%s(): Cannot access preferences with a NULL key", __PRETTY_FUNCTION__);
+
+    value = CFPreferencesCopyAppValue(key, appName);
+    if (!keyExistsAndHasValidFormat) {
+        keyExistsAndHasValidFormat = &valid;
+    }
+    if (!value) {
+        *keyExistsAndHasValidFormat = false;
+        return 0;
+    }
+    typeID = CFGetTypeID(value);
+    if (typeID == CFStringGetTypeID()) {
+        SInt32 charIndex = 0;
+        SInt32 intVal;
+        CFStringInlineBuffer buf;
+        Boolean success;
+        CFStringInitInlineBuffer((CFStringRef)value, &buf, CFRangeMake(0, CFStringGetLength((CFStringRef)value)));
+        success = __CFStringScanInteger(&buf, NULL, &charIndex, false, &intVal);
+        *keyExistsAndHasValidFormat = (success && charIndex == CFStringGetLength((CFStringRef)value));
+        result = (*keyExistsAndHasValidFormat) ? intVal : 0;
+    } else if (typeID == CFNumberGetTypeID()) {
+        *keyExistsAndHasValidFormat = !CFNumberIsFloatType((CFNumberRef)value);
+        if (*keyExistsAndHasValidFormat) {
+            CFNumberGetValue((CFNumberRef)value, kCFNumberCFIndexType, &result);
+        } else {
+            result = 0;
+        }
+    } else {
+        // Unknown type
+        result = 0;
+        *keyExistsAndHasValidFormat = false;
+    }
+    CFRelease(value);
+    return result;
+}
+
+Boolean CFPreferencesGetAppBooleanValue(CFStringRef key, CFStringRef appName, Boolean *keyExistsAndHasValidFormat) {
+    CFAssert1(appName != NULL, __kCFLogAssertion, "%s(): Cannot access application preferences with a NULL application name", __PRETTY_FUNCTION__);
+    CFAssert1(key != NULL, __kCFLogAssertion, "%s(): Cannot access preferences with a NULL key", __PRETTY_FUNCTION__);
+    return CFPreferencesAppBooleanValue(key, appName, keyExistsAndHasValidFormat);
+}
+
+CFIndex CFPreferencesGetAppIntegerValue(CFStringRef key, CFStringRef appName, Boolean *keyExistsAndHasValidFormat) {
+    CFAssert1(appName != NULL, __kCFLogAssertion, "%s(): Cannot access application preferences with a NULL application name", __PRETTY_FUNCTION__);
+    CFAssert1(key != NULL, __kCFLogAssertion, "%s(): Cannot access preferences with a NULL key", __PRETTY_FUNCTION__);
+    return CFPreferencesAppIntegerValue(key, appName, keyExistsAndHasValidFormat);
+}
+
+void CFPreferencesSetAppValue(CFStringRef key, CFTypeRef value, CFStringRef appName) {
+    _CFApplicationPreferences *standardPrefs;
+    CFAssert1(appName != NULL, __kCFLogAssertion, "%s(): Cannot access application preferences with a NULL application name", __PRETTY_FUNCTION__);
+    CFAssert1(key != NULL, __kCFLogAssertion, "%s(): Cannot access preferences with a NULL key", __PRETTY_FUNCTION__);
+
+    standardPrefs = _CFStandardApplicationPreferences(appName);
+    if (standardPrefs) {
+        if (value) _CFApplicationPreferencesSet(standardPrefs, key, value);
+        else _CFApplicationPreferencesRemove(standardPrefs, key);
+    }
+}
+
+
+static CFSpinLock_t __CFApplicationPreferencesLock = CFSpinLockInit; // Locks access to __CFStandardUserPreferences
+static CFMutableDictionaryRef __CFStandardUserPreferences = NULL; // Mutable dictionary; keys are app names, values are _CFApplicationPreferences 
+
+Boolean CFPreferencesAppSynchronize(CFStringRef appName) {
+    _CFApplicationPreferences *standardPrefs;
+    Boolean result;
+    CFAssert1(appName != NULL, __kCFLogAssertion, "%s(): Cannot access application preferences with a NULL application name", __PRETTY_FUNCTION__);
+    
+    // Do not call _CFStandardApplicationPreferences(), as we do not want to create the preferences only to synchronize
+    __CFSpinLock(&__CFApplicationPreferencesLock);
+    if (__CFStandardUserPreferences)  {
+        standardPrefs = (_CFApplicationPreferences *)CFDictionaryGetValue(__CFStandardUserPreferences, appName);
+    } else {
+        standardPrefs = NULL;
+    }
+
+    result = standardPrefs ? _CFApplicationPreferencesSynchronizeNoLock(standardPrefs) : _CFSynchronizeDomainCache();
+    __CFSpinUnlock(&__CFApplicationPreferencesLock);
+    return result;
+}
+
+void CFPreferencesFlushCaches(void) {
+    CFAllocatorRef alloc = __CFPreferencesAllocator();
+    __CFSpinLock(&__CFApplicationPreferencesLock);
+    if (__CFStandardUserPreferences)  {
+        _CFApplicationPreferences **prefsArray, *prefsBuf[32];
+        CFIndex idx, count = CFDictionaryGetCount(__CFStandardUserPreferences);
+        if (count < 32) {
+            prefsArray = prefsBuf;
+        } else {
+            prefsArray = (_CFApplicationPreferences **)CFAllocatorAllocate(alloc, count * sizeof(_CFApplicationPreferences *), 0);
+        }
+        CFDictionaryGetKeysAndValues(__CFStandardUserPreferences, NULL, (const void **)prefsArray);
+
+        __CFSpinUnlock(&__CFApplicationPreferencesLock);
+        // DeallocateApplicationPreferences needs the lock
+        for (idx = 0; idx < count; idx ++) {
+            _CFApplicationPreferences *appPrefs = prefsArray[idx];
+            _CFApplicationPreferencesSynchronize(appPrefs);
+            _CFDeallocateApplicationPreferences(appPrefs);
+        }
+        __CFSpinLock(&__CFApplicationPreferencesLock);
+
+        CFRelease(__CFStandardUserPreferences);
+        __CFStandardUserPreferences = NULL;
+        if(prefsArray != prefsBuf) CFAllocatorDeallocate(alloc, prefsArray);
+    }
+    __CFSpinUnlock(&__CFApplicationPreferencesLock);
+    _CFPreferencesPurgeDomainCache();
+}
+
+// quick message to indicate that the given domain has changed, and we should go through and invalidate any dictReps that involve this domain.
+void _CFApplicationPreferencesDomainHasChanged(CFPreferencesDomainRef changedDomain) {
+    CFAllocatorRef alloc = __CFPreferencesAllocator();
+    __CFSpinLock(&__CFApplicationPreferencesLock);
+    if(__CFStandardUserPreferences) {  // only grovel over the prefs if there's something there to grovel
+        _CFApplicationPreferences **prefsArray, *prefsBuf[32];
+        CFIndex idx, count = CFDictionaryGetCount(__CFStandardUserPreferences);
+        if(count < 32) {
+            prefsArray = prefsBuf;
+        } else {
+            prefsArray = (_CFApplicationPreferences **)CFAllocatorAllocate(alloc, count * sizeof(_CFApplicationPreferences *), 0);
+        }
+        CFDictionaryGetKeysAndValues(__CFStandardUserPreferences, NULL, (const void **)prefsArray);
+        // For this operation, giving up the lock is the last thing we want to do, so use the modified flavor of _CFApplicationPreferencesContainsDomain
+        for(idx = 0; idx < count; idx++) {
+            _CFApplicationPreferences *appPrefs = prefsArray[idx];
+            if(_CFApplicationPreferencesContainsDomainNoLock(appPrefs, changedDomain)) {
+                updateDictRep(appPrefs);
+            }
+        }
+        if(prefsArray != prefsBuf) _CFAllocatorDeallocateGC(alloc, prefsArray);
+    }
+    __CFSpinUnlock(&__CFApplicationPreferencesLock);
+}
+
+
+// Begin ported code from NSUserDefaults.m
+
+
+static void updateDictRep(_CFApplicationPreferences *self) {
+    if (self->_dictRep) {
+        CFRelease(self->_dictRep);
+        self->_dictRep = NULL;
+    }
+}
+
+static void __addKeysAndValues(const void *key, const void *value, void *context) {
+    CFDictionarySetValue((CFMutableDictionaryRef)context, key, value);
+}
+
+static CFMutableDictionaryRef computeDictRep(_CFApplicationPreferences *self, Boolean skipC0C0A) {
+    CFAllocatorRef alloc = __CFPreferencesAllocator();
+    CFMutableArrayRef searchList = self->_search;
+    CFIndex idx;
+    CFIndex cnt = CFArrayGetCount(searchList);
+    CFDictionaryRef subdomainDict;
+    CFMutableDictionaryRef dictRep;
+    
+    dictRep = CFDictionaryCreateMutable(alloc, 0, &kCFTypeDictionaryKeyCallBacks, & kCFTypeDictionaryValueCallBacks);
+    _CFDictionarySetCapacity(dictRep, 260);	// avoid lots of rehashing
+    
+    // For each subdomain triplet in the domain, iterate over dictionaries, adding them if necessary to the dictRep
+    for (idx = cnt; idx--;) {
+        CFPreferencesDomainRef domain = (CFPreferencesDomainRef)CFArrayGetValueAtIndex(searchList, idx);
+
+        if (!domain) continue;
+
+        subdomainDict = _CFPreferencesDomainDeepCopyDictionary(domain);
+        if (subdomainDict) {
+            CFDictionaryApplyFunction(subdomainDict, __addKeysAndValues, dictRep);
+            CFRelease(subdomainDict);
+        }
+    }
+    return dictRep;
+}
+
+CFTypeRef _CFApplicationPreferencesSearchDownToDomain(_CFApplicationPreferences *self, CFPreferencesDomainRef stopper, CFStringRef key) {
+    return NULL;
+}
+
+
+void _CFApplicationPreferencesUpdate(_CFApplicationPreferences *self) {
+    __CFSpinLock(&__CFApplicationPreferencesLock);
+    updateDictRep(self);
+    __CFSpinUnlock(&__CFApplicationPreferencesLock);
+}
+
+CF_EXPORT CFDictionaryRef _CFApplicationPreferencesCopyRepresentation(_CFApplicationPreferences *self);
+
+__private_extern__ CFDictionaryRef __CFApplicationPreferencesCopyCurrentState(void) {
+    _CFApplicationPreferences *self = _CFStandardApplicationPreferences(kCFPreferencesCurrentApplication);
+    CFDictionaryRef result = _CFApplicationPreferencesCopyRepresentation(self);
+    return result;
+}
+
+// CACHING here - we will only return a value as current as the last time computeDictRep() was called
+static CFTypeRef _CFApplicationPreferencesCreateValueForKey2(_CFApplicationPreferences *self, CFStringRef defaultName) {
+    CFTypeRef result;
+    __CFSpinLock(&__CFApplicationPreferencesLock);
+    if (!self->_dictRep) {
+        self->_dictRep = computeDictRep(self, true);
+    }
+    result = (self->_dictRep) ? (CFTypeRef )CFDictionaryGetValue(self->_dictRep, defaultName) : NULL;
+    if (result) {
+        CFRetain(result);
+    }
+    __CFSpinUnlock(&__CFApplicationPreferencesLock);
+    return result;
+}
+
+
+void _CFApplicationPreferencesSet(_CFApplicationPreferences *self, CFStringRef defaultName, CFTypeRef value) {
+    CFPreferencesDomainRef applicationDomain;
+
+    __CFSpinLock(&__CFApplicationPreferencesLock);
+    applicationDomain = _CFPreferencesStandardDomain(self->_appName, kCFPreferencesCurrentUser, kCFPreferencesAnyHost);
+    if(applicationDomain) {
+        _CFPreferencesDomainSet(applicationDomain, defaultName, value);
+        if (CFArrayContainsValue(self->_search, CFRangeMake(0, CFArrayGetCount(self->_search)), applicationDomain)) {
+            // Expensive; can't we just check the relevant value throughout the appropriate sets of domains? -- REW, 7/19/99
+            updateDictRep(self);
+        }
+    }
+    __CFSpinUnlock(&__CFApplicationPreferencesLock);
+}
+
+void _CFApplicationPreferencesRemove(_CFApplicationPreferences *self, CFStringRef defaultName) {
+    CFPreferencesDomainRef appDomain;
+
+    __CFSpinLock(&__CFApplicationPreferencesLock);
+    appDomain = _CFPreferencesStandardDomain(self->_appName, kCFPreferencesCurrentUser, kCFPreferencesAnyHost);
+    if(appDomain) {
+        _CFPreferencesDomainSet(appDomain, defaultName, NULL);
+        if (CFArrayContainsValue(self->_search, CFRangeMake(0, CFArrayGetCount(self->_search)), appDomain)) {
+            // If key exists, it will be in the _dictRep (but possibly overridden)
+            updateDictRep(self);
+        }
+    }
+    __CFSpinUnlock(&__CFApplicationPreferencesLock);
+}
+
+static Boolean _CFApplicationPreferencesSynchronizeNoLock(_CFApplicationPreferences *self) {
+    Boolean success = _CFSynchronizeDomainCache();
+    updateDictRep(self);
+    return success;
+}
+
+Boolean _CFApplicationPreferencesSynchronize(_CFApplicationPreferences *self) {
+    Boolean result;
+    __CFSpinLock(&__CFApplicationPreferencesLock);
+    result = _CFApplicationPreferencesSynchronizeNoLock(self);
+    __CFSpinUnlock(&__CFApplicationPreferencesLock);
+    return result;
+}
+
+// appName should not be kCFPreferencesCurrentApplication going in to this call
+_CFApplicationPreferences *_CFApplicationPreferencesCreateWithUser(CFStringRef userName, CFStringRef appName) {
+    CFAllocatorRef alloc = __CFPreferencesAllocator();
+    _CFApplicationPreferences *self = (_CFApplicationPreferences*)CFAllocatorAllocate(alloc, sizeof(_CFApplicationPreferences), 0);
+    if (self) {
+        self->_dictRep = NULL;
+        self->_appName = (CFStringRef)CFRetain(appName);
+        self->_search = CFArrayCreateMutable(alloc, 0, &kCFTypeArrayCallBacks);
+        if (!self->_search) {
+            CFAllocatorDeallocate(alloc, self);
+            CFRelease(appName);
+            self = NULL;
+        }
+    }
+    return self;
+}
+
+// Do NOT release the domain after adding it to the array; domain_expression should not return a retained object  -- REW, 8/26/99 
+#define ADD_DOMAIN(domain_expression) domain = domain_expression; if (domain) {CFArrayAppendValue(search, domain);}
+void _CFApplicationPreferencesSetStandardSearchList(_CFApplicationPreferences *appPreferences) {
+    /* Here is how the domains end up in priority order in a search list.  Only a subset of these are setup by default.
+	argument domain
+	this app, this user, managed
+	this app, any user, managed
+        this app, this user, this host
+        this app, this user, any host (AppDomain)
+	suiteN, this user, this host
+	suiteN, this user, any host
+        ...
+	suite0, this user, this host
+	suite0, this user, any host
+        any app, this user, this host
+        any app, this user, any host (GlobalDomain)
+        NSUserDefaults backwards-compat ICU domain
+        this app, any user, this host
+        this app, any user, any host
+	suiteN, any user, this host
+	suiteN, any user, any host
+        ...
+	suite0, any user, this host
+	suite0, any user, any host
+        any app, any user, this host
+        any app, any user, any host
+	registration domain
+    */
+    CFPreferencesDomainRef domain;
+    CFMutableArrayRef search = CFArrayCreateMutable(kCFAllocatorSystemDefault, 0, &kCFTypeArrayCallBacks);
+    if (!search) {
+        // couldn't allocate memory!
+        return;
+    }
+
+    ADD_DOMAIN(_CFPreferencesStandardDomain(appPreferences->_appName, kCFPreferencesCurrentUser, kCFPreferencesCurrentHost));
+    ADD_DOMAIN(_CFPreferencesStandardDomain(appPreferences->_appName, kCFPreferencesCurrentUser, kCFPreferencesAnyHost));
+    ADD_DOMAIN(_CFPreferencesStandardDomain(kCFPreferencesAnyApplication, kCFPreferencesCurrentUser, kCFPreferencesCurrentHost));
+    ADD_DOMAIN(_CFPreferencesStandardDomain(kCFPreferencesAnyApplication, kCFPreferencesCurrentUser, kCFPreferencesAnyHost));
+    ADD_DOMAIN(_CFPreferencesStandardDomain(appPreferences->_appName, kCFPreferencesAnyUser, kCFPreferencesCurrentHost));
+    ADD_DOMAIN(_CFPreferencesStandardDomain(appPreferences->_appName, kCFPreferencesAnyUser, kCFPreferencesAnyHost));
+    ADD_DOMAIN(_CFPreferencesStandardDomain(kCFPreferencesAnyApplication, kCFPreferencesAnyUser, kCFPreferencesCurrentHost));
+    ADD_DOMAIN(_CFPreferencesStandardDomain(kCFPreferencesAnyApplication, kCFPreferencesAnyUser, kCFPreferencesAnyHost));
+
+    _CFApplicationPreferencesSetSearchList(appPreferences, search);
+    CFRelease(search);
+}
+#undef ADD_DOMAIN
+
+
+__private_extern__ _CFApplicationPreferences *_CFStandardApplicationPreferences(CFStringRef appName) {
+    _CFApplicationPreferences *appPreferences;
+//    CFAssert(appName != kCFPreferencesAnyApplication, __kCFLogAssertion, "Cannot use any of the CFPreferences...App... functions with an appName of kCFPreferencesAnyApplication");
+    __CFSpinLock(&__CFApplicationPreferencesLock);
+    if (!__CFStandardUserPreferences)  {
+        __CFStandardUserPreferences = CFDictionaryCreateMutable(kCFAllocatorSystemDefault, 0, & kCFTypeDictionaryKeyCallBacks, NULL);
+    }
+    if (!__CFStandardUserPreferences) {
+        // Couldn't create
+        __CFSpinUnlock(&__CFApplicationPreferencesLock);
+        return NULL;
+    }
+    if ((appPreferences = (_CFApplicationPreferences *)CFDictionaryGetValue(__CFStandardUserPreferences, appName)) == NULL ) {
+        appPreferences = _CFApplicationPreferencesCreateWithUser(kCFPreferencesCurrentUser, appName);
+        CFDictionarySetValue(__CFStandardUserPreferences, appName, appPreferences);
+        __CFSpinUnlock(&__CFApplicationPreferencesLock);
+        _CFApplicationPreferencesSetStandardSearchList(appPreferences);
+    } else {
+        __CFSpinUnlock(&__CFApplicationPreferencesLock);
+    }
+    return appPreferences;
+}
+
+// Exclusively for Foundation's use
+void _CFApplicationPreferencesSetCacheForApp(_CFApplicationPreferences *appPrefs, CFStringRef appName) {
+    __CFSpinLock(&__CFApplicationPreferencesLock);
+    if (!__CFStandardUserPreferences) {
+        __CFStandardUserPreferences = CFDictionaryCreateMutable(kCFAllocatorSystemDefault, 0, &kCFTypeDictionaryKeyCallBacks, NULL);
+        CFDictionarySetValue(__CFStandardUserPreferences, appName, appPrefs);
+        __CFSpinUnlock(&__CFApplicationPreferencesLock);
+    } else {
+        _CFApplicationPreferences *oldPrefs = (_CFApplicationPreferences *)CFDictionaryGetValue(__CFStandardUserPreferences, appName);
+        CFDictionarySetValue(__CFStandardUserPreferences, appName, appPrefs);
+        __CFSpinUnlock(&__CFApplicationPreferencesLock);
+        if (oldPrefs) {
+            _CFDeallocateApplicationPreferences(oldPrefs);
+        }
+    }
+}
+
+
+void _CFDeallocateApplicationPreferences(_CFApplicationPreferences *self) {
+    CFAllocatorRef alloc = __CFPreferencesAllocator();
+    _CFApplicationPreferences *cachedPrefs = NULL;
+    __CFSpinLock(&__CFApplicationPreferencesLock);
+
+    // Get us out of the cache before destroying!
+    if (__CFStandardUserPreferences)  {
+        cachedPrefs = (_CFApplicationPreferences *)CFDictionaryGetValue(__CFStandardUserPreferences, self->_appName);
+    }
+    if (cachedPrefs == self) {
+        CFDictionaryRemoveValue(__CFStandardUserPreferences, self->_appName);
+    }
+    
+    if (self->_dictRep) CFRelease(self->_dictRep);
+    CFRelease(self->_search);
+    CFRelease(self->_appName);
+    CFAllocatorDeallocate(alloc, self);
+    __CFSpinUnlock(&__CFApplicationPreferencesLock);
+}
+
+
+CF_EXPORT
+CFDictionaryRef _CFApplicationPreferencesCopyRepresentation(_CFApplicationPreferences *self) {
+    CFDictionaryRef dict;
+    __CFSpinLock(&__CFApplicationPreferencesLock);
+    if (!self->_dictRep) {
+        self->_dictRep = computeDictRep(self, true);
+    }
+    if (self->_dictRep) {
+        CFRetain(self->_dictRep);
+    }
+    dict = self->_dictRep;
+    __CFSpinUnlock(&__CFApplicationPreferencesLock);
+    return dict;
+}
+
+static void _CFApplicationPreferencesSetSearchList(_CFApplicationPreferences *self, CFArrayRef newSearchList) {
+    CFIndex idx, count;
+    __CFSpinLock(&__CFApplicationPreferencesLock);
+    CFArrayRemoveAllValues(self->_search);
+    count = CFArrayGetCount(newSearchList);
+    for (idx = 0; idx < count; idx ++) {
+        CFArrayAppendValue(self->_search, CFArrayGetValueAtIndex(newSearchList, idx));
+    }
+    updateDictRep(self);
+    __CFSpinUnlock(&__CFApplicationPreferencesLock);
+}
+
+void CFPreferencesAddSuitePreferencesToApp(CFStringRef appName, CFStringRef suiteName) {
+    _CFApplicationPreferences *appPrefs;
+    
+    appPrefs = _CFStandardApplicationPreferences(appName);
+    _CFApplicationPreferencesAddSuitePreferences(appPrefs, suiteName);
+}
+
+void _CFApplicationPreferencesAddSuitePreferences(_CFApplicationPreferences *appPrefs, CFStringRef suiteName) {
+    CFPreferencesDomainRef domain; 
+    CFIndex idx;
+    CFRange range;
+
+    // Find where to insert the new suite
+    __CFSpinLock(&__CFApplicationPreferencesLock);
+    domain = _CFPreferencesStandardDomain(appPrefs->_appName, kCFPreferencesCurrentUser, kCFPreferencesAnyHost);
+    range.location = 0;
+    range.length = CFArrayGetCount(appPrefs->_search);
+    idx = domain ? CFArrayGetFirstIndexOfValue(appPrefs->_search, range, domain) : kCFNotFound;
+    __CFSpinUnlock(&__CFApplicationPreferencesLock);
+    idx ++; // We want just below the app domain.  Coincidentally, this gives us the top of the list if the app domain has been removed.
+    domain = _CFPreferencesStandardDomain(suiteName, kCFPreferencesCurrentUser, kCFPreferencesAnyHost);
+    if (domain) {
+        __CFSpinLock(&__CFApplicationPreferencesLock);
+        CFArrayInsertValueAtIndex(appPrefs->_search, idx, domain);
+        __CFSpinUnlock(&__CFApplicationPreferencesLock);
+        range.length ++;
+    }
+    domain = _CFPreferencesStandardDomain(suiteName, kCFPreferencesCurrentUser, kCFPreferencesCurrentHost);
+    if (domain) {
+        __CFSpinLock(&__CFApplicationPreferencesLock);
+        CFArrayInsertValueAtIndex(appPrefs->_search, idx, domain);
+        __CFSpinUnlock(&__CFApplicationPreferencesLock);
+        range.length ++;
+    }
+
+    // Now the AnyUser domains
+    domain = _CFPreferencesStandardDomain(appPrefs->_appName, kCFPreferencesAnyUser, kCFPreferencesAnyHost);
+    idx = domain ? CFArrayGetFirstIndexOfValue(appPrefs->_search, range, domain) : kCFNotFound;
+    if (idx == kCFNotFound) {
+        // Someone blew away the app domain. For the any user case, we look for right below the global domain
+        domain = _CFPreferencesStandardDomain(kCFPreferencesAnyApplication, kCFPreferencesCurrentUser, kCFPreferencesAnyHost);
+        idx = domain ? CFArrayGetFirstIndexOfValue(appPrefs->_search, range, domain) : kCFNotFound;
+        if (idx == kCFNotFound) {
+            // Try the "any host" choice
+            domain = _CFPreferencesStandardDomain(kCFPreferencesAnyApplication, kCFPreferencesCurrentUser, kCFPreferencesCurrentHost);
+            idx = domain ? CFArrayGetFirstIndexOfValue(appPrefs->_search, range, domain) : kCFNotFound;
+            if (idx == kCFNotFound) {
+                // We give up; put the new domains at the bottom
+                idx = CFArrayGetCount(appPrefs->_search) - 1;
+            }
+        }
+    }
+    idx ++;
+    domain = _CFPreferencesStandardDomain(suiteName, kCFPreferencesAnyUser, kCFPreferencesAnyHost);
+    if (domain) {
+        __CFSpinLock(&__CFApplicationPreferencesLock);
+        CFArrayInsertValueAtIndex(appPrefs->_search, idx, domain);
+        __CFSpinUnlock(&__CFApplicationPreferencesLock);
+    }
+    domain = _CFPreferencesStandardDomain(suiteName, kCFPreferencesAnyUser, kCFPreferencesCurrentHost);
+    if (domain) {
+        __CFSpinLock(&__CFApplicationPreferencesLock);
+        CFArrayInsertValueAtIndex(appPrefs->_search, idx, domain);
+        __CFSpinUnlock(&__CFApplicationPreferencesLock);
+    }
+    __CFSpinLock(&__CFApplicationPreferencesLock);
+    updateDictRep(appPrefs);
+    __CFSpinUnlock(&__CFApplicationPreferencesLock);
+}
+
+void CFPreferencesRemoveSuitePreferencesFromApp(CFStringRef appName, CFStringRef suiteName) {
+    _CFApplicationPreferences *appPrefs;
+
+    appPrefs = _CFStandardApplicationPreferences(appName);
+    
+    _CFApplicationPreferencesRemoveSuitePreferences(appPrefs, suiteName);
+}
+
+void _CFApplicationPreferencesRemoveSuitePreferences(_CFApplicationPreferences *appPrefs, CFStringRef suiteName) {
+    CFPreferencesDomainRef domain;
+
+    __CFSpinLock(&__CFApplicationPreferencesLock);
+    domain = _CFPreferencesStandardDomain(suiteName, kCFPreferencesCurrentUser, kCFPreferencesAnyHost);
+    __CFSpinUnlock(&__CFApplicationPreferencesLock);
+    if (domain) _CFApplicationPreferencesRemoveDomain(appPrefs, domain);
+
+    __CFSpinLock(&__CFApplicationPreferencesLock);
+    domain = _CFPreferencesStandardDomain(suiteName, kCFPreferencesCurrentUser, kCFPreferencesCurrentHost);
+    __CFSpinUnlock(&__CFApplicationPreferencesLock);
+    if (domain) _CFApplicationPreferencesRemoveDomain(appPrefs, domain);
+
+    __CFSpinLock(&__CFApplicationPreferencesLock);
+    domain = _CFPreferencesStandardDomain(suiteName, kCFPreferencesAnyUser, kCFPreferencesAnyHost);
+    __CFSpinUnlock(&__CFApplicationPreferencesLock);
+    if (domain) _CFApplicationPreferencesRemoveDomain(appPrefs, domain);
+
+    __CFSpinLock(&__CFApplicationPreferencesLock);
+    domain = _CFPreferencesStandardDomain(suiteName, kCFPreferencesAnyUser, kCFPreferencesCurrentHost);
+    __CFSpinUnlock(&__CFApplicationPreferencesLock);
+    if (domain) _CFApplicationPreferencesRemoveDomain(appPrefs, domain);
+}
+
+void _CFApplicationPreferencesAddDomain(_CFApplicationPreferences *self, CFPreferencesDomainRef domain, Boolean addAtTop) {
+    __CFSpinLock(&__CFApplicationPreferencesLock);
+    if (addAtTop) {
+        CFArrayInsertValueAtIndex(self->_search, 0, domain);
+    } else {
+        CFArrayAppendValue(self->_search, domain);
+    }
+    updateDictRep(self);
+    __CFSpinUnlock(&__CFApplicationPreferencesLock);
+}
+
+Boolean _CFApplicationPreferencesContainsDomain(_CFApplicationPreferences *self, CFPreferencesDomainRef domain) {
+    Boolean result;
+
+    if (!domain) {
+        return false;
+    }
+
+    __CFSpinLock(&__CFApplicationPreferencesLock);
+    result = CFArrayContainsValue(self->_search, CFRangeMake(0, CFArrayGetCount(self->_search)), domain);
+    __CFSpinUnlock(&__CFApplicationPreferencesLock);
+    return result;
+}
+
+Boolean _CFApplicationPreferencesContainsDomainNoLock(_CFApplicationPreferences *self, CFPreferencesDomainRef domain) {
+    Boolean result;
+    result = CFArrayContainsValue(self->_search, CFRangeMake(0, CFArrayGetCount(self->_search)), domain);
+    return result;
+}
+
+void _CFApplicationPreferencesRemoveDomain(_CFApplicationPreferences *self, CFPreferencesDomainRef domain) {
+    CFIndex idx;
+    CFRange range;
+    __CFSpinLock(&__CFApplicationPreferencesLock);
+    range.location = 0;
+    range.length = CFArrayGetCount(self->_search);
+    while ((idx = CFArrayGetFirstIndexOfValue(self->_search, range, domain)) != kCFNotFound) {
+        CFArrayRemoveValueAtIndex(self->_search, idx);
+        range.location = idx;
+        range.length  = range.length - idx - 1;
+    }
+    updateDictRep(self);
+    __CFSpinUnlock(&__CFApplicationPreferencesLock);
+}
diff --git a/CoreFoundation/CFArray.c b/CoreFoundation/CFArray.c
new file mode 100644
index 0000000..6003c5e
--- /dev/null
+++ b/CoreFoundation/CFArray.c
@@ -0,0 +1,1201 @@
+/*
+ * Copyright (c) 2008-2009 Brent Fulgham <bfulgham@gmail.org>.  All rights reserved.
+ *
+ * This source code is a modified version of the CoreFoundation sources released by Apple Inc. under
+ * the terms of the APSL version 2.0 (see below).
+ *
+ * For information about changes from the original Apple source release can be found by reviewing the
+ * source control system for the project at https://sourceforge.net/svn/?group_id=246198.
+ *
+ * The original license information is as follows:
+ *
+ * Copyright (c) 2008 Apple Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*	CFArray.c
+	Copyright 1998-2002, Apple, Inc. All rights reserved.
+	Responsibility: Christopher Kane
+*/
+
+#include "CFInternal.h"
+#include <CoreFoundation/CFArray.h>
+#include "CFStorage.h"
+#include "CFPriv.h"
+#include <string.h>
+#include "auto_stubs.h"
+
+#if DEPLOYMENT_TARGET_WINDOWS
+#define bzero(buf, bytes)      ((void) memset ((buf), 0x00, (bytes)))
+CF_EXPORT bool _CFArrayIsMutable(CFArrayRef array);
+#endif
+
+__private_extern__ void _CFStorageSetWeak(CFStorageRef storage);
+
+const CFArrayCallBacks kCFTypeArrayCallBacks = {0, __CFTypeCollectionRetain, __CFTypeCollectionRelease, CFCopyDescription, CFEqual};
+static const CFArrayCallBacks __kCFNullArrayCallBacks = {0, NULL, NULL, NULL, NULL};
+
+struct __CFArrayBucket {
+    const void *_item;
+};
+
+enum {
+    __CF_MAX_BUCKETS_PER_DEQUE = 262140
+};
+
+CF_INLINE CFIndex __CFArrayDequeRoundUpCapacity(CFIndex capacity) {
+    if (capacity < 4) return 4;
+    return __CFMin((1 << flsl(capacity)), __CF_MAX_BUCKETS_PER_DEQUE);
+}
+
+struct __CFArrayDeque {
+    uint32_t _leftIdx;
+    uint32_t _capacity;
+    int32_t _bias;
+#if __LP64__
+    uint32_t _pad;   // GC:  pointers must be 8-byte aligned for the collector to find them.
+#endif
+    /* struct __CFArrayBucket buckets follow here */
+};
+
+struct __CFArray {
+    CFRuntimeBase _base;
+    CFIndex _count;		/* number of objects */
+    CFIndex _mutations;
+    void *_store;           /* can be NULL when MutableDeque */
+};
+
+/* Flag bits */
+enum {		/* Bits 0-1 */
+    __kCFArrayImmutable = 0,
+    __kCFArrayDeque = 2,
+    __kCFArrayStorage = 3
+};
+
+enum {		/* Bits 2-3 */
+    __kCFArrayHasNullCallBacks = 0,
+    __kCFArrayHasCFTypeCallBacks = 1,
+    __kCFArrayHasCustomCallBacks = 3	/* callbacks are at end of header */
+};
+
+/*
+    Bits 4 & 5 are reserved for GC use.
+    Bit 4, if set, indicates that the array is weak.
+    Bit 5 marks whether finalization has occured and, thus, whether to continue to do special retain/release processing of elements.
+ */
+
+CF_INLINE bool isStrongMemory(CFTypeRef collection) {
+    return __CFBitfieldGetValue(((const CFRuntimeBase *)collection)->_cfinfo[CF_INFO_BITS], 4, 4) == 0;
+}
+
+CF_INLINE bool isWeakMemory(CFTypeRef collection) {
+    return __CFBitfieldGetValue(((const CFRuntimeBase *)collection)->_cfinfo[CF_INFO_BITS], 4, 4) != 0;
+}
+
+CF_INLINE bool hasBeenFinalized(CFTypeRef collection) {
+    return __CFBitfieldGetValue(((const CFRuntimeBase *)collection)->_cfinfo[CF_INFO_BITS], 5, 5) != 0;
+}
+
+CF_INLINE void markFinalized(CFTypeRef collection) {
+    __CFBitfieldSetValue(((CFRuntimeBase *)collection)->_cfinfo[CF_INFO_BITS], 5, 5, 1);
+}
+
+CF_INLINE CFIndex __CFArrayGetType(CFArrayRef array) {
+    return __CFBitfieldGetValue(((const CFRuntimeBase *)array)->_cfinfo[CF_INFO_BITS], 1, 0);
+}
+
+CF_INLINE CFIndex __CFArrayGetSizeOfType(CFIndex t) {
+    CFIndex size = 0;
+        size += sizeof(struct __CFArray);
+    if (__CFBitfieldGetValue(t, 3, 2) == __kCFArrayHasCustomCallBacks) {
+	size += sizeof(CFArrayCallBacks);
+    }
+    return size;
+}
+
+CF_INLINE CFIndex __CFArrayGetCount(CFArrayRef array) {
+    return array->_count;
+}
+
+CF_INLINE void __CFArraySetCount(CFArrayRef array, CFIndex v) {
+    ((struct __CFArray *)array)->_count = v;
+}
+
+/* Only applies to immutable and mutable-deque-using arrays;
+ * Returns the bucket holding the left-most real value in the latter case. */
+CF_INLINE struct __CFArrayBucket *__CFArrayGetBucketsPtr(CFArrayRef array) {
+    switch (__CFArrayGetType(array)) {
+    case __kCFArrayImmutable:
+	return (struct __CFArrayBucket *)((uint8_t *)array + __CFArrayGetSizeOfType(((CFRuntimeBase *)array)->_cfinfo[CF_INFO_BITS]));
+    case __kCFArrayDeque: {
+	struct __CFArrayDeque *deque = (struct __CFArrayDeque *)array->_store;
+        return (struct __CFArrayBucket *)((uint8_t *)deque + sizeof(struct __CFArrayDeque) + deque->_leftIdx * sizeof(struct __CFArrayBucket));
+    }
+    }
+    return NULL;
+}
+
+/* This shouldn't be called if the array count is 0. */
+CF_INLINE struct __CFArrayBucket *__CFArrayGetBucketAtIndex(CFArrayRef array, CFIndex idx) {
+    switch (__CFArrayGetType(array)) {
+    case __kCFArrayImmutable:
+    case __kCFArrayDeque:
+	return __CFArrayGetBucketsPtr(array) + idx;
+    case __kCFArrayStorage: {
+	CFStorageRef store = (CFStorageRef)array->_store;
+	return (struct __CFArrayBucket *)CFStorageGetValueAtIndex(store, idx, NULL);
+    }
+    }
+    return NULL;
+}
+
+CF_INLINE CFArrayCallBacks *__CFArrayGetCallBacks(CFArrayRef array) {
+    CFArrayCallBacks *result = NULL;
+    switch (__CFBitfieldGetValue(((const CFRuntimeBase *)array)->_cfinfo[CF_INFO_BITS], 3, 2)) {
+    case __kCFArrayHasNullCallBacks:
+	return (CFArrayCallBacks *)&__kCFNullArrayCallBacks;
+    case __kCFArrayHasCFTypeCallBacks:
+	return (CFArrayCallBacks *)&kCFTypeArrayCallBacks;
+    case __kCFArrayHasCustomCallBacks:
+	break;
+    }
+    switch (__CFArrayGetType(array)) {
+    case __kCFArrayImmutable:
+	result = (CFArrayCallBacks *)((uint8_t *)array + sizeof(struct __CFArray));
+	break;
+    case __kCFArrayDeque:
+    case __kCFArrayStorage:
+	result = (CFArrayCallBacks *)((uint8_t *)array + sizeof(struct __CFArray));
+	break;
+    }
+    return result;
+}
+
+CF_INLINE bool __CFArrayCallBacksMatchNull(const CFArrayCallBacks *c) {
+    return (NULL == c ||
+	(c->retain == __kCFNullArrayCallBacks.retain &&
+	 c->release == __kCFNullArrayCallBacks.release &&
+	 c->copyDescription == __kCFNullArrayCallBacks.copyDescription &&
+	 c->equal == __kCFNullArrayCallBacks.equal));
+}
+
+CF_INLINE bool __CFArrayCallBacksMatchCFType(const CFArrayCallBacks *c) {
+    return (&kCFTypeArrayCallBacks == c ||
+	(c->retain == kCFTypeArrayCallBacks.retain &&
+	 c->release == kCFTypeArrayCallBacks.release &&
+	 c->copyDescription == kCFTypeArrayCallBacks.copyDescription &&
+	 c->equal == kCFTypeArrayCallBacks.equal));
+}
+
+struct _releaseContext {
+    void (*release)(CFAllocatorRef, const void *);
+    CFAllocatorRef allocator; 
+};
+
+static void __CFArrayStorageRelease(const void *itemptr, void *context) {
+    struct _releaseContext *rc = (struct _releaseContext *)context;
+    INVOKE_CALLBACK2(rc->release, rc->allocator, *(const void **)itemptr);
+    *(const void **)itemptr = NULL; // GC:  clear item to break strong reference.
+}
+
+static void __CFArrayReleaseValues(CFArrayRef array, CFRange range, bool releaseStorageIfPossible) {
+    const CFArrayCallBacks *cb = __CFArrayGetCallBacks(array);
+    CFAllocatorRef allocator;
+    CFIndex idx;
+    switch (__CFArrayGetType(array)) {
+    case __kCFArrayImmutable:
+	if (NULL != cb->release && 0 < range.length && !hasBeenFinalized(array)) {
+            // if we've been finalized then we know that
+            //   1) we're using the standard callback on GC memory
+            //   2) the slots don't' need to be zeroed
+	    struct __CFArrayBucket *buckets = __CFArrayGetBucketsPtr(array);
+	    allocator = __CFGetAllocator(array);
+	    for (idx = 0; idx < range.length; idx++) {
+		INVOKE_CALLBACK2(cb->release, allocator, buckets[idx + range.location]._item);
+		buckets[idx + range.location]._item = NULL; // GC:  break strong reference.
+	    }
+	}
+	break;
+    case __kCFArrayDeque: {
+	struct __CFArrayDeque *deque = (struct __CFArrayDeque *)array->_store;
+	if (0 < range.length && NULL != deque && !hasBeenFinalized(array)) {
+	    struct __CFArrayBucket *buckets = __CFArrayGetBucketsPtr(array);
+	    if (NULL != cb->release) {
+		allocator = __CFGetAllocator(array);
+		for (idx = 0; idx < range.length; idx++) {
+		    INVOKE_CALLBACK2(cb->release, allocator, buckets[idx + range.location]._item);
+		    buckets[idx + range.location]._item = NULL; // GC:  break strong reference.
+		}
+            } else {
+		for (idx = 0; idx < range.length; idx++) {
+		    buckets[idx + range.location]._item = NULL; // GC:  break strong reference.
+		}
+	    }
+	}
+	if (releaseStorageIfPossible && 0 == range.location && __CFArrayGetCount(array) == range.length) {
+	    allocator = __CFGetAllocator(array);
+	    if (NULL != deque) _CFAllocatorDeallocateGC(allocator, deque);
+	    __CFArraySetCount(array, 0);  // GC: _count == 0 ==> _store == NULL.
+	    ((struct __CFArray *)array)->_store = NULL;
+	}
+	break;
+    }
+    case __kCFArrayStorage: {
+	CFStorageRef store = (CFStorageRef)array->_store;
+	if (NULL != cb->release && 0 < range.length && !hasBeenFinalized(array)) {
+	    struct _releaseContext context;
+	    allocator = __CFGetAllocator(array);
+	    context.release = cb->release;
+	    context.allocator = allocator;
+	    CFStorageApplyFunction(store, range, __CFArrayStorageRelease, &context);
+	}
+	if (releaseStorageIfPossible && 0 == range.location && __CFArrayGetCount(array) == range.length) {
+	    _CFReleaseGC(store);
+	    __CFArraySetCount(array, 0);  // GC: _count == 0 ==> _store == NULL.
+	    ((struct __CFArray *)array)->_store = NULL;
+	    __CFBitfieldSetValue(((CFRuntimeBase *)array)->_cfinfo[CF_INFO_BITS], 1, 0, __kCFArrayDeque);
+	}
+	break;
+    }
+    }
+}
+
+#if defined(DEBUG)
+CF_INLINE void __CFArrayValidateRange(CFArrayRef array, CFRange range, const char *func) {
+    CFAssert3(0 <= range.location && range.location <= CFArrayGetCount(array), __kCFLogAssertion, "%s(): range.location index (%d) out of bounds (0, %d)", func, range.location, CFArrayGetCount(array));
+    CFAssert2(0 <= range.length, __kCFLogAssertion, "%s(): range.length (%d) cannot be less than zero", func, range.length);
+    CFAssert3(range.location + range.length <= CFArrayGetCount(array), __kCFLogAssertion, "%s(): ending index (%d) out of bounds (0, %d)", func, range.location + range.length, CFArrayGetCount(array));
+}
+#else
+#define __CFArrayValidateRange(a,r,f)
+#endif
+
+static Boolean __CFArrayEqual(CFTypeRef cf1, CFTypeRef cf2) {
+    CFArrayRef array1 = (CFArrayRef)cf1;
+    CFArrayRef array2 = (CFArrayRef)cf2;
+    const CFArrayCallBacks *cb1, *cb2;
+    CFIndex idx, cnt;
+    if (array1 == array2) return true;
+    cnt = __CFArrayGetCount(array1);
+    if (cnt != __CFArrayGetCount(array2)) return false;
+    cb1 = __CFArrayGetCallBacks(array1);
+    cb2 = __CFArrayGetCallBacks(array2);
+    if (cb1->equal != cb2->equal) return false;
+    if (0 == cnt) return true;	/* after function comparison! */
+    for (idx = 0; idx < cnt; idx++) {
+	const void *val1 = __CFArrayGetBucketAtIndex(array1, idx)->_item;
+	const void *val2 = __CFArrayGetBucketAtIndex(array2, idx)->_item;
+	if (val1 != val2) {
+	    if (NULL == cb1->equal) return false;
+	    if (!INVOKE_CALLBACK2(cb1->equal, val1, val2)) return false;
+	}
+    }
+    return true;
+}
+
+static CFHashCode __CFArrayHash(CFTypeRef cf) {
+    CFArrayRef array = (CFArrayRef)cf;
+    return __CFArrayGetCount(array);
+}
+
+static CFStringRef __CFArrayCopyDescription(CFTypeRef cf) {
+    CFArrayRef array = (CFArrayRef)cf;
+    CFMutableStringRef result;
+    const CFArrayCallBacks *cb;
+    CFAllocatorRef allocator;
+    CFIndex idx, cnt;
+    cnt = __CFArrayGetCount(array);
+    allocator = CFGetAllocator(array);
+    result = CFStringCreateMutable(allocator, 0);
+    switch (__CFArrayGetType(array)) {
+    case __kCFArrayImmutable:
+	CFStringAppendFormat(result, NULL, CFSTR("<CFArray %p [%p]>{type = immutable, count = %u, values = (\n"), cf, allocator, cnt);
+	break;
+    case __kCFArrayDeque:
+	CFStringAppendFormat(result, NULL, CFSTR("<CFArray %p [%p]>{type = mutable-small, count = %u, values = (\n"), cf, allocator, cnt);
+	break;
+    case __kCFArrayStorage:
+	CFStringAppendFormat(result, NULL, CFSTR("<CFArray %p [%p]>{type = mutable-large, count = %u, values = (\n"), cf, allocator, cnt);
+	break;
+    }
+    cb = __CFArrayGetCallBacks(array);
+    for (idx = 0; idx < cnt; idx++) {
+	CFStringRef desc = NULL;
+	const void *val = __CFArrayGetBucketAtIndex(array, idx)->_item;
+	if (NULL != cb->copyDescription) {
+	    desc = (CFStringRef)INVOKE_CALLBACK1(cb->copyDescription, val);
+	}
+	if (NULL != desc) {
+	    CFStringAppendFormat(result, NULL, CFSTR("\t%u : %@\n"), idx, desc);
+	    CFRelease(desc);
+	} else {
+	    CFStringAppendFormat(result, NULL, CFSTR("\t%u : <%p>\n"), idx, val);
+	}
+    }
+    CFStringAppend(result, CFSTR(")}"));
+    return result;
+}
+
+
+static void __CFResourceRelease(CFTypeRef cf, const void *ignored) {
+    kCFTypeArrayCallBacks.release(kCFAllocatorSystemDefault, cf);
+}
+
+static void __CFArrayDeallocate(CFTypeRef cf) {
+    CFArrayRef array = (CFArrayRef)cf;
+    // Under GC, keep contents alive when we know we can, either standard callbacks or NULL
+    // if (__CFBitfieldGetValue(cf->info, 5, 4)) return; // bits only ever set under GC
+    CFAllocatorRef allocator = __CFGetAllocator(array);
+    if (CF_IS_COLLECTABLE_ALLOCATOR(allocator)) {
+	// XXX_PCB keep array intact during finalization.
+	const CFArrayCallBacks *cb = __CFArrayGetCallBacks(array);
+	if (cb->retain == NULL && cb->release == NULL)
+            return;
+        if (cb == &kCFTypeArrayCallBacks || cb->release == kCFTypeArrayCallBacks.release) {
+            markFinalized(cf);
+            CFArrayApplyFunction((CFArrayRef)cf, CFRangeMake(0, __CFArrayGetCount(array)), (CFArrayApplierFunction)__CFResourceRelease, 0);
+            return;
+        }
+    }
+    __CFArrayReleaseValues(array, CFRangeMake(0, __CFArrayGetCount(array)), true);
+}
+
+static CFTypeID __kCFArrayTypeID = _kCFRuntimeNotATypeID;
+
+static const CFRuntimeClass __CFArrayClass = {
+    _kCFRuntimeScannedObject,
+    "CFArray",
+    NULL,	// init
+    NULL,	// copy
+    __CFArrayDeallocate,
+    __CFArrayEqual,
+    __CFArrayHash,
+    NULL,	// 
+    __CFArrayCopyDescription
+};
+
+__private_extern__ void __CFArrayInitialize(void) {
+    __kCFArrayTypeID = _CFRuntimeRegisterClass(&__CFArrayClass);
+}
+
+CFTypeID CFArrayGetTypeID(void) {
+    return __kCFArrayTypeID;
+}
+
+static CFArrayRef __CFArrayInit(CFAllocatorRef allocator, UInt32 flags, CFIndex capacity, const CFArrayCallBacks *callBacks) {
+    struct __CFArray *memory;
+    UInt32 size;
+    __CFBitfieldSetValue(flags, 31, 2, 0);
+    if (CF_IS_COLLECTABLE_ALLOCATOR(allocator)) {
+	if (!callBacks || (callBacks->retain == NULL && callBacks->release == NULL)) {
+	    __CFBitfieldSetValue(flags, 4, 4, 1); // setWeak
+	}
+    }
+    if (__CFArrayCallBacksMatchNull(callBacks)) {
+	__CFBitfieldSetValue(flags, 3, 2, __kCFArrayHasNullCallBacks);
+    } else if (__CFArrayCallBacksMatchCFType(callBacks)) {
+	__CFBitfieldSetValue(flags, 3, 2, __kCFArrayHasCFTypeCallBacks);
+    } else {
+	__CFBitfieldSetValue(flags, 3, 2, __kCFArrayHasCustomCallBacks);
+    }
+    size = __CFArrayGetSizeOfType(flags) - sizeof(CFRuntimeBase);
+    switch (__CFBitfieldGetValue(flags, 1, 0)) {
+    case __kCFArrayImmutable:
+	size += capacity * sizeof(struct __CFArrayBucket);
+	break;
+    case __kCFArrayDeque:
+    case __kCFArrayStorage:
+	break;
+    }
+    memory = (struct __CFArray*)_CFRuntimeCreateInstance(allocator, __kCFArrayTypeID, size, NULL);
+    if (NULL == memory) {
+	return NULL;
+    }
+    __CFBitfieldSetValue(memory->_base._cfinfo[CF_INFO_BITS], 6, 0, flags);
+    __CFArraySetCount((CFArrayRef)memory, 0);
+    switch (__CFBitfieldGetValue(flags, 1, 0)) {
+    case __kCFArrayImmutable:
+        if (isWeakMemory(memory)) {  // if weak, don't scan
+            auto_zone_set_layout_type(__CFCollectableZone, memory, AUTO_OBJECT_UNSCANNED);
+        }
+	if (__CFOASafe) __CFSetLastAllocationEventName(memory, "CFArray (immutable)");
+	break;
+    case __kCFArrayDeque:
+    case __kCFArrayStorage:
+	if (__CFOASafe) __CFSetLastAllocationEventName(memory, "CFArray (mutable-variable)");
+	((struct __CFArray *)memory)->_mutations = 1;
+	((struct __CFArray*)memory)->_store = NULL;
+	break;
+    }
+    if (__kCFArrayHasCustomCallBacks == __CFBitfieldGetValue(flags, 3, 2)) {
+	CFArrayCallBacks *cb = (CFArrayCallBacks *)__CFArrayGetCallBacks((CFArrayRef)memory);
+	*cb = *callBacks;
+	FAULT_CALLBACK((void **)&(cb->retain));
+	FAULT_CALLBACK((void **)&(cb->release));
+	FAULT_CALLBACK((void **)&(cb->copyDescription));
+	FAULT_CALLBACK((void **)&(cb->equal));
+    }
+    return (CFArrayRef)memory;
+}
+
+CFArrayRef CFArrayCreate(CFAllocatorRef allocator, const void **values, CFIndex numValues, const CFArrayCallBacks *callBacks) {
+    CFArrayRef result;
+    const CFArrayCallBacks *cb;
+    struct __CFArrayBucket *buckets;
+    CFAllocatorRef bucketsAllocator;
+    void* bucketsBase;
+    CFIndex idx;
+    CFAssert2(0 <= numValues, __kCFLogAssertion, "%s(): numValues (%d) cannot be less than zero", __PRETTY_FUNCTION__, numValues);
+    result = __CFArrayInit(allocator, __kCFArrayImmutable, numValues, callBacks);
+    cb = __CFArrayGetCallBacks(result);
+    buckets = __CFArrayGetBucketsPtr(result);
+    bucketsAllocator = isStrongMemory(result) ? allocator : kCFAllocatorNull;
+    bucketsBase = CF_IS_COLLECTABLE_ALLOCATOR(bucketsAllocator) ? (void *)auto_zone_base_pointer(__CFCollectableZone, buckets) : NULL;
+    if (NULL != cb->retain) {
+        for (idx = 0; idx < numValues; idx++) {
+	    CF_WRITE_BARRIER_BASE_ASSIGN(bucketsAllocator, bucketsBase, buckets->_item, (void *)INVOKE_CALLBACK2(cb->retain, allocator, *values));
+            values++;
+            buckets++;
+        }
+    }
+    else {
+        for (idx = 0; idx < numValues; idx++) {
+            CF_WRITE_BARRIER_BASE_ASSIGN(bucketsAllocator, bucketsBase, buckets->_item, *values);
+            values++;
+            buckets++;
+        }
+    }
+    __CFArraySetCount(result, numValues);
+    return result;
+}
+
+CFMutableArrayRef CFArrayCreateMutable(CFAllocatorRef allocator, CFIndex capacity, const CFArrayCallBacks *callBacks) {
+    CFAssert2(0 <= capacity, __kCFLogAssertion, "%s(): capacity (%d) cannot be less than zero", __PRETTY_FUNCTION__, capacity);
+    CFAssert2(capacity <= (CFIndex)(LONG_MAX / sizeof(void *)), __kCFLogAssertion, "%s(): capacity (%d) is too large for this architecture", __PRETTY_FUNCTION__, capacity);
+    return (CFMutableArrayRef)__CFArrayInit(allocator, __kCFArrayDeque, capacity, callBacks);
+}
+
+// This creates an array which is for CFTypes or NSObjects, with an ownership transfer --
+// the array does not take a retain, and the caller does not need to release the inserted objects.
+// The incoming objects must also be collectable if allocated out of a collectable allocator.
+CFArrayRef _CFArrayCreate_ex(CFAllocatorRef allocator, Boolean isMutable, const void **values, CFIndex numValues) {
+    CFArrayRef result;
+    result = __CFArrayInit(allocator, isMutable ? __kCFArrayDeque : __kCFArrayImmutable, numValues, &kCFTypeArrayCallBacks);
+    if (!isMutable) {
+	struct __CFArrayBucket *buckets = __CFArrayGetBucketsPtr(result);
+	CF_WRITE_BARRIER_MEMMOVE(buckets, values, numValues * sizeof(struct __CFArrayBucket));
+    } else {
+	if (__CF_MAX_BUCKETS_PER_DEQUE <= numValues) {
+	    CFStorageRef store = (CFStorageRef)CFMakeCollectable(CFStorageCreate(allocator, sizeof(const void *)));
+	    if (__CFOASafe) __CFSetLastAllocationEventName(store, "CFArray (store-storage)");
+	    CF_WRITE_BARRIER_BASE_ASSIGN(allocator, result, result->_store, store);
+	    CFStorageInsertValues(store, CFRangeMake(0, numValues));
+	    CFStorageReplaceValues(store, CFRangeMake(0, numValues), values);
+	    __CFBitfieldSetValue(((CFRuntimeBase *)result)->_cfinfo[CF_INFO_BITS], 1, 0, __kCFArrayStorage);
+	} else if (0 <= numValues) {
+	    struct __CFArrayDeque *deque;
+	    struct __CFArrayBucket *raw_buckets;
+	    CFIndex capacity = __CFArrayDequeRoundUpCapacity(numValues);
+	    CFIndex size = sizeof(struct __CFArrayDeque) + capacity * sizeof(struct __CFArrayBucket);
+	    deque = (struct __CFArrayDeque *)_CFAllocatorAllocateGC(allocator, size, isStrongMemory(result) ? __kCFAllocatorGCScannedMemory : 0);
+	    if (__CFOASafe) __CFSetLastAllocationEventName(deque, "CFArray (store-deque)");
+	    deque->_leftIdx = (capacity - numValues) / 2;
+	    deque->_capacity = capacity;
+	    deque->_bias = 0;
+	    CF_WRITE_BARRIER_BASE_ASSIGN(allocator, result, result->_store, deque);
+	    raw_buckets = (struct __CFArrayBucket *)((uint8_t *)deque + sizeof(struct __CFArrayDeque));
+	    CF_WRITE_BARRIER_MEMMOVE(raw_buckets + deque->_leftIdx + 0, values, numValues * sizeof(struct __CFArrayBucket));
+	    __CFBitfieldSetValue(((CFRuntimeBase *)result)->_cfinfo[CF_INFO_BITS], 1, 0, __kCFArrayDeque);
+	}
+    }
+    __CFArraySetCount(result, numValues);
+    return result;
+}
+
+CFArrayRef CFArrayCreateCopy(CFAllocatorRef allocator, CFArrayRef array) {
+    CFArrayRef result;
+    const CFArrayCallBacks *cb;
+    struct __CFArrayBucket *buckets;
+    CFAllocatorRef bucketsAllocator;
+    void* bucketsBase;
+    CFIndex numValues = CFArrayGetCount(array);
+    CFIndex idx;
+    if (CF_IS_OBJC(__kCFArrayTypeID, array)) {
+	cb = &kCFTypeArrayCallBacks;
+    } else {
+	cb = __CFArrayGetCallBacks(array);
+	    }
+    result = __CFArrayInit(allocator, __kCFArrayImmutable, numValues, cb);
+    cb = __CFArrayGetCallBacks(result); // GC: use the new array's callbacks so we don't leak.
+    buckets = __CFArrayGetBucketsPtr(result);
+    bucketsAllocator = isStrongMemory(result) ? allocator : kCFAllocatorNull;
+	bucketsBase = CF_IS_COLLECTABLE_ALLOCATOR(bucketsAllocator) ? (void *)auto_zone_base_pointer(__CFCollectableZone, buckets) : NULL;
+    for (idx = 0; idx < numValues; idx++) {
+	const void *value = CFArrayGetValueAtIndex(array, idx);
+	if (NULL != cb->retain) {
+	    value = (void *)INVOKE_CALLBACK2(cb->retain, allocator, value);
+	}
+	CF_WRITE_BARRIER_BASE_ASSIGN(bucketsAllocator, bucketsBase, buckets->_item, value);
+	buckets++;
+    }
+    __CFArraySetCount(result, numValues);
+    return result;
+}
+
+CFMutableArrayRef CFArrayCreateMutableCopy(CFAllocatorRef allocator, CFIndex capacity, CFArrayRef array) {
+    CFMutableArrayRef result;
+    const CFArrayCallBacks *cb;
+    CFIndex idx, numValues = CFArrayGetCount(array);
+    UInt32 flags;
+    if (CF_IS_OBJC(__kCFArrayTypeID, array)) {
+	cb = &kCFTypeArrayCallBacks;
+    }
+    else {
+	cb = __CFArrayGetCallBacks(array);
+    }
+    flags = __kCFArrayDeque;
+    result = (CFMutableArrayRef)__CFArrayInit(allocator, flags, capacity, cb);
+    if (0 == capacity) _CFArraySetCapacity(result, numValues);
+    for (idx = 0; idx < numValues; idx++) {
+	const void *value = CFArrayGetValueAtIndex(array, idx);
+	CFArrayAppendValue(result, value);
+    }
+    return result;
+}
+
+CFIndex CFArrayGetCount(CFArrayRef array) {
+    CF_OBJC_FUNCDISPATCH0(__kCFArrayTypeID, CFIndex, array, "count");
+    __CFGenericValidateType(array, __kCFArrayTypeID);
+    return __CFArrayGetCount(array);
+}
+
+
+CFIndex CFArrayGetCountOfValue(CFArrayRef array, CFRange range, const void *value) {
+    const CFArrayCallBacks *cb;
+    CFIndex idx, count = 0;
+// CF: this ignores range
+    CF_OBJC_FUNCDISPATCH1(__kCFArrayTypeID, CFIndex, array, "countOccurrences:", value);
+    __CFGenericValidateType(array, __kCFArrayTypeID);    
+    __CFArrayValidateRange(array, range, __PRETTY_FUNCTION__);
+    cb = __CFArrayGetCallBacks(array);
+    for (idx = 0; idx < range.length; idx++) {
+	const void *item = __CFArrayGetBucketAtIndex(array, range.location + idx)->_item;
+	if (value == item || (cb->equal && INVOKE_CALLBACK2(cb->equal, value, item))) {
+	    count++;
+	}
+    }
+    return count;
+}
+
+Boolean CFArrayContainsValue(CFArrayRef array, CFRange range, const void *value) {
+    CFIndex idx;
+    CF_OBJC_FUNCDISPATCH2(__kCFArrayTypeID, char, array, "containsObject:inRange:", value, range);
+    __CFGenericValidateType(array, __kCFArrayTypeID);
+    __CFArrayValidateRange(array, range, __PRETTY_FUNCTION__);
+    for (idx = 0; idx < range.length; idx++) {
+        const void *item = __CFArrayGetBucketAtIndex(array, range.location + idx)->_item;
+        if (value == item) {
+            return true;
+        }
+    }
+    const CFArrayCallBacks *cb = __CFArrayGetCallBacks(array);
+    if (cb->equal) {
+        for (idx = 0; idx < range.length; idx++) {
+            const void *item = __CFArrayGetBucketAtIndex(array, range.location + idx)->_item;
+            if (INVOKE_CALLBACK2(cb->equal, value, item)) {
+                return true;
+            }
+        }
+    }
+    return false;
+}
+
+const void *CFArrayGetValueAtIndex(CFArrayRef array, CFIndex idx) {
+    CF_OBJC_FUNCDISPATCH1(__kCFArrayTypeID, void *, array, "objectAtIndex:", idx);
+    __CFGenericValidateType(array, __kCFArrayTypeID);
+    CFAssert2(0 <= idx && idx < __CFArrayGetCount(array), __kCFLogAssertion, "%s(): index (%d) out of bounds", __PRETTY_FUNCTION__, idx);
+    return __CFArrayGetBucketAtIndex(array, idx)->_item;
+}
+
+// This is for use by NSCFArray; it avoids ObjC dispatch, and checks for out of bounds
+const void *_CFArrayCheckAndGetValueAtIndex(CFArrayRef array, CFIndex idx) {
+    if (0 <= idx && idx < __CFArrayGetCount(array)) return __CFArrayGetBucketAtIndex(array, idx)->_item;
+    return (void *)(-1);
+}
+
+
+void CFArrayGetValues(CFArrayRef array, CFRange range, const void **values) {
+    CF_OBJC_FUNCDISPATCH2(__kCFArrayTypeID, void, array, "getObjects:range:", values, range);
+    __CFGenericValidateType(array, __kCFArrayTypeID);
+    __CFArrayValidateRange(array, range, __PRETTY_FUNCTION__);
+    CFAssert1(NULL != values, __kCFLogAssertion, "%s(): pointer to values may not be NULL", __PRETTY_FUNCTION__);
+    if (0 < range.length) {
+	switch (__CFArrayGetType(array)) {
+	case __kCFArrayImmutable:
+	case __kCFArrayDeque:
+	    CF_WRITE_BARRIER_MEMMOVE(values, __CFArrayGetBucketsPtr(array) + range.location, range.length * sizeof(struct __CFArrayBucket));
+	    break;
+	case __kCFArrayStorage: {
+	    CFStorageRef store = (CFStorageRef)array->_store;
+	    CFStorageGetValues(store, range, values);
+	    break;
+	}
+	}
+    }
+}
+
+
+unsigned long _CFArrayFastEnumeration(CFArrayRef array, struct __objcFastEnumerationStateEquivalent *state, void *stackbuffer, unsigned long count) {
+    if (array->_count == 0) return 0;
+    enum { ATSTART = 0, ATEND = 1 };
+    switch (__CFArrayGetType(array)) {
+    case __kCFArrayImmutable:
+        if (state->state == ATSTART) { /* first time */
+            static const unsigned long const_mu = 1;
+            state->state = ATEND;
+            state->mutationsPtr = (unsigned long *)&const_mu;
+            state->itemsPtr = (unsigned long *)__CFArrayGetBucketsPtr(array);
+            return array->_count;
+        }
+        return 0;			
+    case __kCFArrayDeque:
+        if (state->state == ATSTART) { /* first time */
+            state->state = ATEND;
+            state->mutationsPtr = (unsigned long *)&array->_mutations;
+            state->itemsPtr = (unsigned long *)__CFArrayGetBucketsPtr(array);
+            return array->_count;
+        }
+        return 0;
+    case __kCFArrayStorage:
+        state->mutationsPtr = (unsigned long *)&array->_mutations;
+        return _CFStorageFastEnumeration((CFStorageRef)array->_store, state, stackbuffer, count);
+    }
+    return 0;
+}
+
+
+void CFArrayApplyFunction(CFArrayRef array, CFRange range, CFArrayApplierFunction applier, void *context) {
+    CFIndex idx;
+    FAULT_CALLBACK((void **)&(applier));
+    CF_OBJC_FUNCDISPATCH2(__kCFArrayTypeID, void, array, "apply:context:", applier, context);
+    __CFGenericValidateType(array, __kCFArrayTypeID);
+    __CFArrayValidateRange(array, range, __PRETTY_FUNCTION__);
+    CFAssert1(NULL != applier, __kCFLogAssertion, "%s(): pointer to applier function may not be NULL", __PRETTY_FUNCTION__);
+    for (idx = 0; idx < range.length; idx++) {
+	const void *item = __CFArrayGetBucketAtIndex(array, range.location + idx)->_item;
+	INVOKE_CALLBACK2(applier, item, context);
+    }
+}
+
+CFIndex CFArrayGetFirstIndexOfValue(CFArrayRef array, CFRange range, const void *value) {
+    const CFArrayCallBacks *cb;
+    CFIndex idx;
+    CF_OBJC_FUNCDISPATCH2(__kCFArrayTypeID, CFIndex, array, "_cfindexOfObject:inRange:", value, range);
+    __CFGenericValidateType(array, __kCFArrayTypeID);
+    __CFArrayValidateRange(array, range, __PRETTY_FUNCTION__);
+    cb = __CFArrayGetCallBacks(array);
+    for (idx = 0; idx < range.length; idx++) {
+	const void *item = __CFArrayGetBucketAtIndex(array, range.location + idx)->_item;
+	if (value == item || (cb->equal && INVOKE_CALLBACK2(cb->equal, value, item)))
+	    return idx + range.location;
+    }
+    return kCFNotFound;
+}
+
+CFIndex CFArrayGetLastIndexOfValue(CFArrayRef array, CFRange range, const void *value) {
+    const CFArrayCallBacks *cb;
+    CFIndex idx;
+    CF_OBJC_FUNCDISPATCH2(__kCFArrayTypeID, CFIndex, array, "_cflastIndexOfObject:inRange:", value, range);
+    __CFGenericValidateType(array, __kCFArrayTypeID);
+    __CFArrayValidateRange(array, range, __PRETTY_FUNCTION__);
+    cb = __CFArrayGetCallBacks(array);
+    for (idx = range.length; idx--;) {
+	const void *item = __CFArrayGetBucketAtIndex(array, range.location + idx)->_item;
+	if (value == item || (cb->equal && INVOKE_CALLBACK2(cb->equal, value, item)))
+	    return idx + range.location;
+    }
+    return kCFNotFound;
+}
+
+void CFArrayAppendValue(CFMutableArrayRef array, const void *value) {
+    CF_OBJC_FUNCDISPATCH1(__kCFArrayTypeID, void, array, "addObject:", value);
+    __CFGenericValidateType(array, __kCFArrayTypeID);
+    CFAssert1(__CFArrayGetType(array) != __kCFArrayImmutable, __kCFLogAssertion, "%s(): array is immutable", __PRETTY_FUNCTION__);
+    _CFArrayReplaceValues(array, CFRangeMake(__CFArrayGetCount(array), 0), &value, 1);
+}
+
+void CFArraySetValueAtIndex(CFMutableArrayRef array, CFIndex idx, const void *value) {
+    CF_OBJC_FUNCDISPATCH2(__kCFArrayTypeID, void, array, "setObject:atIndex:", value, idx);
+    __CFGenericValidateType(array, __kCFArrayTypeID);
+    CFAssert1(__CFArrayGetType(array) != __kCFArrayImmutable, __kCFLogAssertion, "%s(): array is immutable", __PRETTY_FUNCTION__);
+    CFAssert2(0 <= idx && idx <= __CFArrayGetCount(array), __kCFLogAssertion, "%s(): index (%d) out of bounds", __PRETTY_FUNCTION__, idx);
+    if (idx == __CFArrayGetCount(array)) {
+	_CFArrayReplaceValues(array, CFRangeMake(idx, 0), &value, 1);
+    } else {
+	const void *old_value;
+	const CFArrayCallBacks *cb = __CFArrayGetCallBacks(array);
+	CFAllocatorRef allocator = __CFGetAllocator(array);
+        CFAllocatorRef bucketsAllocator = isStrongMemory(array) ? allocator : kCFAllocatorNull;
+	struct __CFArrayBucket *bucket = __CFArrayGetBucketAtIndex(array, idx);
+	if (NULL != cb->retain && !hasBeenFinalized(array)) {
+	    value = (void *)INVOKE_CALLBACK2(cb->retain, allocator, value);
+	}
+	old_value = bucket->_item;
+	CF_WRITE_BARRIER_ASSIGN(bucketsAllocator, bucket->_item, value); // GC: handles deque/CFStorage cases.
+	if (NULL != cb->release && !hasBeenFinalized(array)) {
+	    INVOKE_CALLBACK2(cb->release, allocator, old_value);
+	}
+	array->_mutations++;
+    }
+}
+
+void CFArrayInsertValueAtIndex(CFMutableArrayRef array, CFIndex idx, const void *value) {
+    CF_OBJC_FUNCDISPATCH2(__kCFArrayTypeID, void, array, "insertObject:atIndex:", value, idx);
+    __CFGenericValidateType(array, __kCFArrayTypeID);
+    CFAssert1(__CFArrayGetType(array) != __kCFArrayImmutable, __kCFLogAssertion, "%s(): array is immutable", __PRETTY_FUNCTION__);
+    CFAssert2(0 <= idx && idx <= __CFArrayGetCount(array), __kCFLogAssertion, "%s(): index (%d) out of bounds", __PRETTY_FUNCTION__, idx);
+    _CFArrayReplaceValues(array, CFRangeMake(idx, 0), &value, 1);
+}
+
+void CFArrayExchangeValuesAtIndices(CFMutableArrayRef array, CFIndex idx1, CFIndex idx2) {
+    const void *tmp;
+    struct __CFArrayBucket *bucket1, *bucket2;
+    CFAllocatorRef bucketsAllocator;
+    CF_OBJC_FUNCDISPATCH2(__kCFArrayTypeID, void, array, "exchange::", idx1, idx2);
+    __CFGenericValidateType(array, __kCFArrayTypeID);
+    CFAssert2(0 <= idx1 && idx1 < __CFArrayGetCount(array), __kCFLogAssertion, "%s(): index #1 (%d) out of bounds", __PRETTY_FUNCTION__, idx1);
+    CFAssert2(0 <= idx2 && idx2 < __CFArrayGetCount(array), __kCFLogAssertion, "%s(): index #2 (%d) out of bounds", __PRETTY_FUNCTION__, idx2);
+    CFAssert1(__CFArrayGetType(array) != __kCFArrayImmutable, __kCFLogAssertion, "%s(): array is immutable", __PRETTY_FUNCTION__);
+    bucket1 = __CFArrayGetBucketAtIndex(array, idx1);
+    bucket2 = __CFArrayGetBucketAtIndex(array, idx2);
+    tmp = bucket1->_item;
+    bucketsAllocator = isStrongMemory(array) ? __CFGetAllocator(array) : kCFAllocatorNull;
+    // XXX these aren't needed.
+    CF_WRITE_BARRIER_ASSIGN(bucketsAllocator, bucket1->_item, bucket2->_item);
+    CF_WRITE_BARRIER_ASSIGN(bucketsAllocator, bucket2->_item, tmp);
+    array->_mutations++;
+
+}
+
+void CFArrayRemoveValueAtIndex(CFMutableArrayRef array, CFIndex idx) {
+    CF_OBJC_FUNCDISPATCH1(__kCFArrayTypeID, void, array, "removeObjectAtIndex:", idx);
+    __CFGenericValidateType(array, __kCFArrayTypeID);
+    CFAssert1(__CFArrayGetType(array) != __kCFArrayImmutable, __kCFLogAssertion, "%s(): array is immutable", __PRETTY_FUNCTION__);
+    CFAssert2(0 <= idx && idx < __CFArrayGetCount(array), __kCFLogAssertion, "%s(): index (%d) out of bounds", __PRETTY_FUNCTION__, idx);
+    _CFArrayReplaceValues(array, CFRangeMake(idx, 1), NULL, 0);
+}
+
+void CFArrayRemoveAllValues(CFMutableArrayRef array) {
+    CF_OBJC_FUNCDISPATCH0(__kCFArrayTypeID, void, array, "removeAllObjects");
+    __CFGenericValidateType(array, __kCFArrayTypeID);
+    CFAssert1(__CFArrayGetType(array) != __kCFArrayImmutable, __kCFLogAssertion, "%s(): array is immutable", __PRETTY_FUNCTION__);
+    __CFArrayReleaseValues(array, CFRangeMake(0, __CFArrayGetCount(array)), true);
+    __CFArraySetCount(array, 0);
+    array->_mutations++;
+}
+
+static void __CFArrayConvertDequeToStore(CFMutableArrayRef array) {
+    struct __CFArrayDeque *deque = (struct __CFArrayDeque *)array->_store;
+    struct __CFArrayBucket *raw_buckets = (struct __CFArrayBucket *)((uint8_t *)deque + sizeof(struct __CFArrayDeque));
+    CFStorageRef store;
+    CFIndex count = CFArrayGetCount(array);
+    CFAllocatorRef allocator = __CFGetAllocator(array);
+    store = (CFStorageRef)CFMakeCollectable(CFStorageCreate(allocator, sizeof(const void *)));
+    if (__CFOASafe) __CFSetLastAllocationEventName(store, "CFArray (store-storage)");
+    CF_WRITE_BARRIER_BASE_ASSIGN(allocator, array, array->_store, store);
+    CFStorageInsertValues(store, CFRangeMake(0, count));
+    CFStorageReplaceValues(store, CFRangeMake(0, count), raw_buckets + deque->_leftIdx);
+    _CFAllocatorDeallocateGC(__CFGetAllocator(array), deque);
+    __CFBitfieldSetValue(((CFRuntimeBase *)array)->_cfinfo[CF_INFO_BITS], 1, 0, __kCFArrayStorage);
+}
+
+static void __CFArrayConvertStoreToDeque(CFMutableArrayRef array) {
+    CFStorageRef store = (CFStorageRef)array->_store;
+    struct __CFArrayDeque *deque;
+    struct __CFArrayBucket *raw_buckets;
+    CFIndex count = CFStorageGetCount(store);// storage, not array, has correct count at this point
+    // do not resize down to a completely tight deque
+    CFIndex capacity = __CFArrayDequeRoundUpCapacity(count + 6);
+    CFIndex size = sizeof(struct __CFArrayDeque) + capacity * sizeof(struct __CFArrayBucket);
+    CFAllocatorRef allocator = __CFGetAllocator(array);
+    deque = (struct __CFArrayDeque *)_CFAllocatorAllocateGC(allocator, size, isStrongMemory(array) ? __kCFAllocatorGCScannedMemory : 0);
+    if (__CFOASafe) __CFSetLastAllocationEventName(deque, "CFArray (store-deque)");
+    deque->_leftIdx = (capacity - count) / 2;
+    deque->_capacity = capacity;
+    deque->_bias = 0;
+    CF_WRITE_BARRIER_BASE_ASSIGN(allocator, array, array->_store, deque);
+    raw_buckets = (struct __CFArrayBucket *)((uint8_t *)deque + sizeof(struct __CFArrayDeque));
+    CFStorageGetValues(store, CFRangeMake(0, count), raw_buckets + deque->_leftIdx);
+    _CFReleaseGC(store); // GC:  balances CFMakeCollectable() above.
+    __CFBitfieldSetValue(((CFRuntimeBase *)array)->_cfinfo[CF_INFO_BITS], 1, 0, __kCFArrayDeque);
+}
+
+// may move deque storage, as it may need to grow deque
+static void __CFArrayRepositionDequeRegions(CFMutableArrayRef array, CFRange range, CFIndex newCount) {
+    // newCount elements are going to replace the range, and the result will fit in the deque
+    struct __CFArrayDeque *deque = (struct __CFArrayDeque *)array->_store;
+    struct __CFArrayBucket *buckets;
+    CFIndex cnt, futureCnt, numNewElems;
+    CFIndex L, A, B, C, R;
+
+    buckets = (struct __CFArrayBucket *)((uint8_t *)deque + sizeof(struct __CFArrayDeque));
+    cnt = __CFArrayGetCount(array);
+    futureCnt = cnt - range.length + newCount;
+
+    L = deque->_leftIdx;		// length of region to left of deque
+    A = range.location;			// length of region in deque to left of replaced range
+    B = range.length;			// length of replaced range
+    C = cnt - B - A;			// length of region in deque to right of replaced range
+    R = deque->_capacity - cnt - L;	// length of region to right of deque
+    numNewElems = newCount - B;
+
+    CFIndex wiggle = deque->_capacity >> 17;
+    if (wiggle < 4) wiggle = 4;
+    if (deque->_capacity < (uint32_t)futureCnt || (cnt < futureCnt && L + R < wiggle)) {
+	// must be inserting or space is tight, reallocate and re-center everything
+	CFIndex capacity = __CFArrayDequeRoundUpCapacity(futureCnt + wiggle);
+	CFIndex size = sizeof(struct __CFArrayDeque) + capacity * sizeof(struct __CFArrayBucket);
+	CFAllocatorRef allocator = __CFGetAllocator(array);
+	struct __CFArrayDeque *newDeque = (struct __CFArrayDeque *)_CFAllocatorAllocateGC(allocator, size, isStrongMemory(array) ? __kCFAllocatorGCScannedMemory : 0);
+	if (__CFOASafe) __CFSetLastAllocationEventName(newDeque, "CFArray (store-deque)");
+	struct __CFArrayBucket *newBuckets = (struct __CFArrayBucket *)((uint8_t *)newDeque + sizeof(struct __CFArrayDeque));
+	CFIndex oldL = L;
+	CFIndex newL = (capacity - futureCnt) / 2;
+	CFIndex oldC0 = oldL + A + B;
+	CFIndex newC0 = newL + A + newCount;
+	newDeque->_leftIdx = newL;
+	newDeque->_capacity = capacity;
+	newDeque->_bias = 0;
+	if (0 < A) CF_WRITE_BARRIER_MEMMOVE(newBuckets + newL, buckets + oldL, A * sizeof(struct __CFArrayBucket));
+	if (0 < C) CF_WRITE_BARRIER_MEMMOVE(newBuckets + newC0, buckets + oldC0, C * sizeof(struct __CFArrayBucket));
+	if (deque) _CFAllocatorDeallocateGC(allocator, deque);
+	CF_WRITE_BARRIER_BASE_ASSIGN(allocator, array, array->_store, newDeque);
+	return;
+    }
+
+    if ((numNewElems < 0 && C < A) || (numNewElems <= R && C < A)) {	// move C
+	// deleting: C is smaller
+	// inserting: C is smaller and R has room
+	CFIndex oldC0 = L + A + B;
+	CFIndex newC0 = L + A + newCount;
+	if (0 < C) CF_WRITE_BARRIER_MEMMOVE(buckets + newC0, buckets + oldC0, C * sizeof(struct __CFArrayBucket));
+	// GrP GC: zero-out newly exposed space on the right, if any
+	if (oldC0 > newC0) memset(buckets + newC0 + C, 0x00, (oldC0 - newC0) * sizeof(struct __CFArrayBucket));
+    } else if ((numNewElems < 0) || (numNewElems <= L && A <= C)) {	// move A
+	// deleting: A is smaller or equal (covers remaining delete cases)
+	// inserting: A is smaller and L has room
+	CFIndex oldL = L;
+	CFIndex newL = L - numNewElems;
+	deque->_leftIdx = newL;
+	if (0 < A) CF_WRITE_BARRIER_MEMMOVE(buckets + newL, buckets + oldL, A * sizeof(struct __CFArrayBucket));
+	// GrP GC: zero-out newly exposed space on the left, if any
+	if (newL > oldL) memset(buckets + oldL, 0x00, (newL - oldL) * sizeof(struct __CFArrayBucket));
+    } else {
+	// now, must be inserting, and either:
+	//    A<=C, but L doesn't have room (R might have, but don't care)
+	//    C<A, but R doesn't have room (L might have, but don't care)
+	// re-center everything
+	CFIndex oldL = L;
+	CFIndex newL = (L + R - numNewElems) / 2;
+	CFIndex oldBias = deque->_bias;
+	deque->_bias = (newL < oldL) ? -1 : 1;
+	if (oldBias < 0) {
+	    newL = newL - newL / 2;
+	} else if (0 < oldBias) {
+	    newL = newL + newL / 2;
+	}
+	CFIndex oldC0 = oldL + A + B;
+	CFIndex newC0 = newL + A + newCount;
+	deque->_leftIdx = newL;
+	if (newL < oldL) {
+	    if (0 < A) CF_WRITE_BARRIER_MEMMOVE(buckets + newL, buckets + oldL, A * sizeof(struct __CFArrayBucket));
+	    if (0 < C) CF_WRITE_BARRIER_MEMMOVE(buckets + newC0, buckets + oldC0, C * sizeof(struct __CFArrayBucket));
+	    // GrP GC: zero-out newly exposed space on the right, if any
+	    if (oldC0 > newC0) memset(buckets + newC0 + C, 0x00, (oldC0 - newC0) * sizeof(struct __CFArrayBucket));
+	} else {
+	    if (0 < C) CF_WRITE_BARRIER_MEMMOVE(buckets + newC0, buckets + oldC0, C * sizeof(struct __CFArrayBucket));
+	    if (0 < A) CF_WRITE_BARRIER_MEMMOVE(buckets + newL, buckets + oldL, A * sizeof(struct __CFArrayBucket));
+	    // GrP GC: zero-out newly exposed space on the left, if any
+	    if (newL > oldL) memset(buckets + oldL, 0x00, (newL - oldL) * sizeof(struct __CFArrayBucket));
+	}
+    }
+}
+
+static void __CFArrayHandleOutOfMemory(CFTypeRef obj, CFIndex numBytes) {
+    CFStringRef msg = CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("Attempt to allocate %ld bytes for CFArray failed"), numBytes);
+    CFBadErrorCallBack cb = _CFGetOutOfMemoryErrorCallBack();
+    if (NULL == cb || !cb(obj, CFSTR("NS/CFArray"), msg)) {
+        CFLog(kCFLogLevelCritical, CFSTR("%@"), msg);
+        HALT;
+    }
+    CFRelease(msg);
+}
+
+// This function is for Foundation's benefit; no one else should use it.
+void _CFArraySetCapacity(CFMutableArrayRef array, CFIndex cap) {
+    if (CF_IS_OBJC(__kCFArrayTypeID, array)) return;
+    __CFGenericValidateType(array, __kCFArrayTypeID);
+    CFAssert1(__CFArrayGetType(array) != __kCFArrayImmutable, __kCFLogAssertion, "%s(): array is immutable", __PRETTY_FUNCTION__);
+    CFAssert3(__CFArrayGetCount(array) <= cap, __kCFLogAssertion, "%s(): desired capacity (%d) is less than count (%d)", __PRETTY_FUNCTION__, cap, __CFArrayGetCount(array));
+    // Currently, attempting to set the capacity of an array which is the CFStorage
+    // variant, or set the capacity larger than __CF_MAX_BUCKETS_PER_DEQUE, has no
+    // effect.  The primary purpose of this API is to help avoid a bunch of the
+    // resizes at the small capacities 4, 8, 16, etc.
+    if (__CFArrayGetType(array) == __kCFArrayDeque) {
+	struct __CFArrayDeque *deque = (struct __CFArrayDeque *)array->_store;
+	CFIndex capacity = __CFArrayDequeRoundUpCapacity(cap);
+	CFIndex size = sizeof(struct __CFArrayDeque) + capacity * sizeof(struct __CFArrayBucket);
+	CFAllocatorRef allocator = __CFGetAllocator(array);
+	if (NULL == deque) {
+	    deque = (struct __CFArrayDeque *)_CFAllocatorAllocateGC(allocator, size, isStrongMemory(array) ? __kCFAllocatorGCScannedMemory : 0);
+	    if (NULL == deque) __CFArrayHandleOutOfMemory(array, size);
+	    if (__CFOASafe) __CFSetLastAllocationEventName(deque, "CFArray (store-deque)");
+	    deque->_leftIdx = capacity / 2; 
+	} else {
+	    struct __CFArrayDeque *olddeque = deque;
+	    CFIndex oldcap = deque->_capacity;
+	    deque = (struct __CFArrayDeque *)_CFAllocatorAllocateGC(allocator, size, isStrongMemory(array) ? __kCFAllocatorGCScannedMemory : 0);
+	    if (NULL == deque) __CFArrayHandleOutOfMemory(array, size);
+	    CF_WRITE_BARRIER_MEMMOVE(deque, olddeque, sizeof(struct __CFArrayDeque) + oldcap * sizeof(struct __CFArrayBucket));
+	    _CFAllocatorDeallocateGC(allocator, olddeque);
+	    if (__CFOASafe) __CFSetLastAllocationEventName(deque, "CFArray (store-deque)");
+	}
+	deque->_capacity = capacity;
+	deque->_bias = 0;
+	CF_WRITE_BARRIER_BASE_ASSIGN(allocator, array, array->_store, deque);
+    }    
+}
+
+// This function is for Foundation's benefit; no one else should use it.
+bool _CFArrayIsMutable(CFArrayRef array) {
+    return (__CFArrayGetType(array) != __kCFArrayImmutable);
+}
+
+void CFArrayReplaceValues(CFMutableArrayRef array, CFRange range, const void **newValues, CFIndex newCount) {
+    CF_OBJC_FUNCDISPATCH3(__kCFArrayTypeID, void, array, "replaceObjectsInRange:withObjects:count:", range, (void **)newValues, newCount);
+    __CFGenericValidateType(array, __kCFArrayTypeID);
+    __CFArrayValidateRange(array, range, __PRETTY_FUNCTION__);
+    CFAssert1(__CFArrayGetType(array) != __kCFArrayImmutable, __kCFLogAssertion, "%s(): array is immutable", __PRETTY_FUNCTION__);
+    CFAssert2(0 <= newCount, __kCFLogAssertion, "%s(): newCount (%d) cannot be less than zero", __PRETTY_FUNCTION__, newCount);
+    return _CFArrayReplaceValues(array, range, newValues, newCount);
+}
+
+// This function does no ObjC dispatch or argument checking;
+// It should only be called from places where that dispatch and check has already been done, or NSCFArray
+void _CFArrayReplaceValues(CFMutableArrayRef array, CFRange range, const void **newValues, CFIndex newCount) {
+    const CFArrayCallBacks *cb;
+    CFAllocatorRef allocator;
+    CFIndex idx, cnt, futureCnt;
+    const void **newv, *buffer[256];
+    cnt = __CFArrayGetCount(array);
+    futureCnt = cnt - range.length + newCount;
+    CFAssert1(newCount <= futureCnt, __kCFLogAssertion, "%s(): internal error 1", __PRETTY_FUNCTION__);
+    cb = __CFArrayGetCallBacks(array);
+    allocator = __CFGetAllocator(array);
+    /* Retain new values if needed, possibly allocating a temporary buffer for them */
+    if (NULL != cb->retain && !hasBeenFinalized(array)) {
+	newv = (newCount <= 256) ? (const void **)buffer : (const void **)CFAllocatorAllocate(allocator, newCount * sizeof(void *), 0); // GC OK
+	if (newv != buffer && __CFOASafe) __CFSetLastAllocationEventName(newv, "CFArray (temp)");
+	for (idx = 0; idx < newCount; idx++) {
+	    newv[idx] = (void *)INVOKE_CALLBACK2(cb->retain, allocator, (void *)newValues[idx]);
+	}
+    } else {
+	newv = newValues;
+    }
+    array->_mutations++;
+
+    /* Now, there are three regions of interest, each of which may be empty:
+     *   A: the region from index 0 to one less than the range.location
+     *   B: the region of the range
+     *   C: the region from range.location + range.length to the end
+     * Note that index 0 is not necessarily at the lowest-address edge
+     * of the available storage. The values in region B need to get
+     * released, and the values in regions A and C (depending) need
+     * to get shifted if the number of new values is different from
+     * the length of the range being replaced.
+     */
+    if (0 < range.length) {
+	__CFArrayReleaseValues(array, range, false);
+    }
+    // region B elements are now "dead"
+    if (__kCFArrayStorage == __CFArrayGetType(array)) {
+	CFStorageRef store = (CFStorageRef)array->_store;
+	// reposition regions A and C for new region B elements in gap
+	if (range.length < newCount) {
+	    CFStorageInsertValues(store, CFRangeMake(range.location + range.length, newCount - range.length));
+	} else if (newCount < range.length) {
+	    CFStorageDeleteValues(store, CFRangeMake(range.location + newCount, range.length - newCount));
+	}
+	if (futureCnt <= __CF_MAX_BUCKETS_PER_DEQUE / 2) {
+	    __CFArrayConvertStoreToDeque(array);
+	}
+    } else if (NULL == array->_store) {
+	if (__CF_MAX_BUCKETS_PER_DEQUE <= futureCnt) {
+	    CFStorageRef store = (CFStorageRef)CFMakeCollectable(CFStorageCreate(allocator, sizeof(const void *)));
+	    if (! isStrongMemory(array)) _CFStorageSetWeak(store);
+	    if (__CFOASafe) __CFSetLastAllocationEventName(store, "CFArray (store-storage)");
+	    CF_WRITE_BARRIER_BASE_ASSIGN(allocator, array, array->_store, store);
+	    CFStorageInsertValues(store, CFRangeMake(0, newCount));
+	    __CFBitfieldSetValue(((CFRuntimeBase *)array)->_cfinfo[CF_INFO_BITS], 1, 0, __kCFArrayStorage);
+	} else if (0 <= futureCnt) {
+	    struct __CFArrayDeque *deque;
+	    CFIndex capacity = __CFArrayDequeRoundUpCapacity(futureCnt);
+	    CFIndex size = sizeof(struct __CFArrayDeque) + capacity * sizeof(struct __CFArrayBucket);
+	    deque = (struct __CFArrayDeque *)_CFAllocatorAllocateGC(allocator, size, isStrongMemory(array) ? __kCFAllocatorGCScannedMemory : 0);
+	    if (__CFOASafe) __CFSetLastAllocationEventName(deque, "CFArray (store-deque)");
+	    deque->_leftIdx = (capacity - newCount) / 2;
+	    deque->_capacity = capacity;
+	    deque->_bias = 0;
+	    CF_WRITE_BARRIER_BASE_ASSIGN(allocator, array, array->_store, deque);
+	}
+    } else {		// Deque
+	// reposition regions A and C for new region B elements in gap
+	if (__CF_MAX_BUCKETS_PER_DEQUE <= futureCnt) {
+	    CFStorageRef store;
+	    __CFArrayConvertDequeToStore(array);
+	    store = (CFStorageRef)array->_store;
+	    if (range.length < newCount) {
+		CFStorageInsertValues(store, CFRangeMake(range.location + range.length, newCount - range.length));
+	    } else if (newCount < range.length) { // this won't happen, but is here for completeness
+		CFStorageDeleteValues(store, CFRangeMake(range.location + newCount, range.length - newCount));
+	    }
+	} else if (range.length != newCount) {
+	    __CFArrayRepositionDequeRegions(array, range, newCount);
+	}
+    }
+    // copy in new region B elements
+    if (0 < newCount) {
+	if (__kCFArrayStorage == __CFArrayGetType(array)) {
+	    CFStorageRef store = (CFStorageRef)array->_store;
+	    CFStorageReplaceValues(store, CFRangeMake(range.location, newCount), newv);
+	} else {	// Deque
+	    struct __CFArrayDeque *deque = (struct __CFArrayDeque *)array->_store;
+	    struct __CFArrayBucket *raw_buckets = (struct __CFArrayBucket *)((uint8_t *)deque + sizeof(struct __CFArrayDeque));
+            CFAllocatorRef bucketsAllocator = isStrongMemory(array) ? allocator : kCFAllocatorNull;
+	    if (newCount == 1)
+		CF_WRITE_BARRIER_ASSIGN(bucketsAllocator, *((const void **)raw_buckets + deque->_leftIdx + range.location), newv[0]);
+	    else
+		CF_WRITE_BARRIER_MEMMOVE(raw_buckets + deque->_leftIdx + range.location, newv, newCount * sizeof(struct __CFArrayBucket));
+	}
+    }
+    __CFArraySetCount(array, futureCnt);
+    if (newv != buffer && newv != newValues) CFAllocatorDeallocate(allocator, newv);
+}
+
+struct _acompareContext {
+    CFComparatorFunction func;
+    void *context;
+};
+
+static CFComparisonResult __CFArrayCompareValues(const void *v1, const void *v2, struct _acompareContext *context) {
+    const void **val1 = (const void **)v1;
+    const void **val2 = (const void **)v2;
+    return (CFComparisonResult)(INVOKE_CALLBACK3(context->func, *val1, *val2, context->context));
+}
+
+void CFArraySortValues(CFMutableArrayRef array, CFRange range, CFComparatorFunction comparator, void *context) {
+    FAULT_CALLBACK((void **)&(comparator));
+    CF_OBJC_FUNCDISPATCH3(__kCFArrayTypeID, void, array, "sortUsingFunction:context:range:", comparator, context, range);
+    __CFGenericValidateType(array, __kCFArrayTypeID);
+    __CFArrayValidateRange(array, range, __PRETTY_FUNCTION__);
+    CFAssert1(__CFArrayGetType(array) != __kCFArrayImmutable, __kCFLogAssertion, "%s(): array is immutable", __PRETTY_FUNCTION__);
+    CFAssert1(NULL != comparator, __kCFLogAssertion, "%s(): pointer to comparator function may not be NULL", __PRETTY_FUNCTION__);
+    array->_mutations++;
+
+    if (1 < range.length) {
+	struct _acompareContext ctx;
+	struct __CFArrayBucket *bucket;
+	ctx.func = comparator;
+	ctx.context = context;
+	switch (__CFArrayGetType(array)) {
+	case __kCFArrayDeque:
+	    bucket = __CFArrayGetBucketsPtr(array) + range.location;
+	    if (CF_USING_COLLECTABLE_MEMORY && isStrongMemory(array)) {
+                size_t size = range.length * sizeof(void*);
+                __CFObjCWriteBarrierRange(bucket, size);
+                CFQSortArray(bucket, range.length, sizeof(void *), (CFComparatorFunction)__CFArrayCompareValues, &ctx);
+            } else {
+                CFQSortArray(bucket, range.length, sizeof(void *), (CFComparatorFunction)__CFArrayCompareValues, &ctx);
+            }
+	    break;
+	case __kCFArrayStorage: {
+	    CFStorageRef store = (CFStorageRef)array->_store;
+	    CFAllocatorRef allocator = __CFGetAllocator(array);
+	    const void **values, *buffer[256];
+	    values = (range.length <= 256) ? (const void **)buffer : (const void **)CFAllocatorAllocate(allocator, range.length * sizeof(void *), 0); // GC OK
+	    if (values != buffer && __CFOASafe) __CFSetLastAllocationEventName(values, "CFArray (temp)");
+	    CFStorageGetValues(store, range, values);
+	    CFQSortArray(values, range.length, sizeof(void *), (CFComparatorFunction)__CFArrayCompareValues, &ctx);
+	    CFStorageReplaceValues(store, range, values);
+	    if (values != buffer) CFAllocatorDeallocate(allocator, values);  // GC OK
+	    break;
+	}
+	}
+    }
+}
+
+CFIndex CFArrayBSearchValues(CFArrayRef array, CFRange range, const void *value, CFComparatorFunction comparator, void *context) {
+    __CFGenericValidateType(array, __kCFArrayTypeID);
+    __CFArrayValidateRange(array, range, __PRETTY_FUNCTION__);
+    CFAssert1(NULL != comparator, __kCFLogAssertion, "%s(): pointer to comparator function may not be NULL", __PRETTY_FUNCTION__);
+    bool isObjC = CF_IS_OBJC(__kCFArrayTypeID, array);
+    FAULT_CALLBACK((void **)&(comparator));
+    CFIndex idx = 0;
+    if (range.length <= 0) return range.location;
+    if (isObjC || __kCFArrayStorage == __CFArrayGetType(array)) {
+	const void *item;
+	SInt32 lg;
+	item = CFArrayGetValueAtIndex(array, range.location + range.length - 1);
+	if ((CFComparisonResult)(INVOKE_CALLBACK3(comparator, item, value, context)) < 0) {
+	    return range.location + range.length;
+	}
+	item = CFArrayGetValueAtIndex(array, range.location);
+	if ((CFComparisonResult)(INVOKE_CALLBACK3(comparator, value, item, context)) < 0) {
+	    return range.location;
+	}
+	lg = flsl(range.length) - 1;	// lg2(range.length)
+	item = CFArrayGetValueAtIndex(array, range.location + -1 + (1 << lg));
+	idx = range.location + ((CFComparisonResult)(INVOKE_CALLBACK3(comparator, item, value, context)) < 0) ? range.length - (1 << lg) : -1;
+        while (lg--) {
+	    item = CFArrayGetValueAtIndex(array, range.location + idx + (1 << lg));
+	    if ((CFComparisonResult)(INVOKE_CALLBACK3(comparator, item, value, context)) < 0) {
+		idx += (1 << lg);
+	    }
+	}
+	idx++;
+    } else {
+	struct _acompareContext ctx;
+	ctx.func = comparator;
+	ctx.context = context;
+	idx = CFBSearch(&value, sizeof(void *), __CFArrayGetBucketsPtr(array) + range.location, range.length, (CFComparatorFunction)__CFArrayCompareValues, &ctx);
+    }
+    return idx + range.location;
+}
+
+void CFArrayAppendArray(CFMutableArrayRef array, CFArrayRef otherArray, CFRange otherRange) {
+    CFIndex idx;
+    __CFGenericValidateType(array, __kCFArrayTypeID);
+    __CFGenericValidateType(otherArray, __kCFArrayTypeID);
+    CFAssert1(__CFArrayGetType(array) != __kCFArrayImmutable, __kCFLogAssertion, "%s(): array is immutable", __PRETTY_FUNCTION__);
+    __CFArrayValidateRange(otherArray, otherRange, __PRETTY_FUNCTION__);
+    for (idx = otherRange.location; idx < otherRange.location + otherRange.length; idx++) {
+	CFArrayAppendValue(array, CFArrayGetValueAtIndex(otherArray, idx));
+    }
+}
diff --git a/CoreFoundation/CFArray.h b/CoreFoundation/CFArray.h
new file mode 100644
index 0000000..5b84595
--- /dev/null
+++ b/CoreFoundation/CFArray.h
@@ -0,0 +1,703 @@
+/*
+ * Copyright (c) 2008-2009 Brent Fulgham <bfulgham@gmail.org>.  All rights reserved.
+ *
+ * This source code is a modified version of the CoreFoundation sources released by Apple Inc. under
+ * the terms of the APSL version 2.0 (see below).
+ *
+ * For information about changes from the original Apple source release can be found by reviewing the
+ * source control system for the project at https://sourceforge.net/svn/?group_id=246198.
+ *
+ * The original license information is as follows:
+ * 
+ * Copyright (c) 2008 Apple Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*	CFArray.h
+	Copyright (c) 1998-2007, Apple Inc. All rights reserved.
+*/
+
+/*!
+	@header CFArray
+	CFArray implements an ordered, compact container of pointer-sized
+	values. Values are accessed via integer keys (indices), from the
+	range 0 to N-1, where N is the number of values in the array when
+	an operation is performed. The array is said to be "compact" because
+	deleted or inserted values do not leave a gap in the key space --
+	the values with higher-numbered indices have their indices
+	renumbered lower (or higher, in the case of insertion) so that the
+	set of valid indices is always in the integer range [0, N-1]. Thus,
+	the index to access a particular value in the array may change over
+	time as other values are inserted into or deleted from the array.
+
+	Arrays come in two flavors, immutable, which cannot have values
+	added to them or removed from them after the array is created, and
+	mutable, to which you can add values or from which remove values.
+	Mutable arrays can have an unlimited number of values (or rather,
+	limited only by constraints external to CFArray, like the amount
+	of available memory).
+
+	As with all CoreFoundation collection types, arrays maintain hard
+	references on the values you put in them, but the retaining and
+	releasing functions are user-defined callbacks that can actually do
+	whatever the user wants (for example, nothing).
+
+	Computational Complexity
+	The access time for a value in the array is guaranteed to be at
+	worst O(lg N) for any implementation, current and future, but will
+	often be O(1) (constant time). Linear search operations similarly
+	have a worst case complexity of O(N*lg N), though typically the
+	bounds will be tighter, and so on. Insertion or deletion operations
+	will typically be linear in the number of values in the array, but
+	may be O(N*lg N) clearly in the worst case in some implementations.
+	There are no favored positions within the array for performance;
+	that is, it is not necessarily faster to access values with low
+	indices, or to insert or delete values with high indices, or
+	whatever.
+*/
+
+#if !defined(__COREFOUNDATION_CFARRAY__)
+#define __COREFOUNDATION_CFARRAY__ 1
+
+#include <CoreFoundation/CFBase.h>
+
+CF_EXTERN_C_BEGIN
+
+/*!
+	@typedef CFArrayCallBacks
+	Structure containing the callbacks of a CFArray.
+	@field version The version number of the structure type being passed
+		in as a parameter to the CFArray creation functions. This
+		structure is version 0.
+	@field retain The callback used to add a retain for the array on
+		values as they are put into the array. This callback returns
+		the value to store in the array, which is usually the value
+		parameter passed to this callback, but may be a different
+		value if a different value should be stored in the array.
+		The array's allocator is passed as the first argument.
+	@field release The callback used to remove a retain previously added
+		for the array from values as they are removed from the
+		array. The array's allocator is passed as the first
+		argument.
+	@field copyDescription The callback used to create a descriptive
+		string representation of each value in the array. This is
+		used by the CFCopyDescription() function.
+	@field equal The callback used to compare values in the array for
+		equality for some operations.
+*/
+typedef const void *	(*CFArrayRetainCallBack)(CFAllocatorRef allocator, const void *value);
+typedef void		(*CFArrayReleaseCallBack)(CFAllocatorRef allocator, const void *value);
+typedef CFStringRef	(*CFArrayCopyDescriptionCallBack)(const void *value);
+typedef Boolean		(*CFArrayEqualCallBack)(const void *value1, const void *value2);
+typedef struct {
+    CFIndex				version;
+    CFArrayRetainCallBack		retain;
+    CFArrayReleaseCallBack		release;
+    CFArrayCopyDescriptionCallBack	copyDescription;
+    CFArrayEqualCallBack		equal;
+} CFArrayCallBacks;
+
+/*!
+	@constant kCFTypeArrayCallBacks
+	Predefined CFArrayCallBacks structure containing a set of callbacks
+	appropriate for use when the values in a CFArray are all CFTypes.
+*/
+CF_EXPORT
+const CFArrayCallBacks kCFTypeArrayCallBacks;
+
+/*!
+	@typedef CFArrayApplierFunction
+	Type of the callback function used by the apply functions of
+		CFArrays.
+	@param value The current value from the array.
+	@param context The user-defined context parameter given to the apply
+		function.
+*/
+typedef void (*CFArrayApplierFunction)(const void *value, void *context);
+
+/*!
+	@typedef CFArrayRef
+	This is the type of a reference to immutable CFArrays.
+*/
+typedef const struct __CFArray * CFArrayRef;
+
+/*!
+	@typedef CFMutableArrayRef
+	This is the type of a reference to mutable CFArrays.
+*/
+typedef struct __CFArray * CFMutableArrayRef;
+
+/*!
+	@function CFArrayGetTypeID
+	Returns the type identifier of all CFArray instances.
+*/
+CF_EXPORT
+CFTypeID CFArrayGetTypeID(void);
+
+/*!
+	@function CFArrayCreate
+	Creates a new immutable array with the given values.
+	@param allocator The CFAllocator which should be used to allocate
+		memory for the array and its storage for values. This
+		parameter may be NULL in which case the current default
+		CFAllocator is used. If this reference is not a valid
+		CFAllocator, the behavior is undefined.
+	@param values A C array of the pointer-sized values to be in the
+		array. The values in the array are ordered in the same order
+		in which they appear in this C array. This parameter may be
+		NULL if the numValues parameter is 0. This C array is not
+		changed or freed by this function. If this parameter is not
+		a valid pointer to a C array of at least numValues pointers,
+		the behavior is undefined.
+	@param numValues The number of values to copy from the values C
+		array into the CFArray. This number will be the count of the
+		array.
+		If this parameter is negative, or greater than the number of
+		values actually in the value's C array, the behavior is
+		undefined.
+	@param callBacks A pointer to a CFArrayCallBacks structure
+		initialized with the callbacks for the array to use on each
+		value in the array. The retain callback will be used within
+		this function, for example, to retain all of the new values
+		from the values C array. A copy of the contents of the
+		callbacks structure is made, so that a pointer to a
+		structure on the stack can be passed in, or can be reused
+		for multiple array creations. If the version field of this
+		callbacks structure is not one of the defined ones for
+		CFArray, the behavior is undefined. The retain field may be
+		NULL, in which case the CFArray will do nothing to add a
+		retain to the contained values for the array. The release
+		field may be NULL, in which case the CFArray will do nothing
+		to remove the array's retain (if any) on the values when the
+		array is destroyed. If the copyDescription field is NULL,
+		the array will create a simple description for the value. If
+		the equal field is NULL, the array will use pointer equality
+		to test for equality of values. This callbacks parameter
+		itself may be NULL, which is treated as if a valid structure
+		of version 0 with all fields NULL had been passed in.
+		Otherwise, if any of the fields are not valid pointers to
+		functions of the correct type, or this parameter is not a
+		valid pointer to a  CFArrayCallBacks callbacks structure,
+		the behavior is undefined. If any of the values put into the
+		array is not one understood by one of the callback functions
+		the behavior when that callback function is used is
+		undefined.
+	@result A reference to the new immutable CFArray.
+*/
+CF_EXPORT
+CFArrayRef CFArrayCreate(CFAllocatorRef allocator, const void **values, CFIndex numValues, const CFArrayCallBacks *callBacks);
+
+/*!
+	@function CFArrayCreateCopy
+	Creates a new immutable array with the values from the given array.
+	@param allocator The CFAllocator which should be used to allocate
+		memory for the array and its storage for values. This
+		parameter may be NULL in which case the current default
+		CFAllocator is used. If this reference is not a valid
+		CFAllocator, the behavior is undefined.
+	@param theArray The array which is to be copied. The values from the
+		array are copied as pointers into the new array (that is,
+		the values themselves are copied, not that which the values
+		point to, if anything). However, the values are also
+		retained by the new array. The count of the new array will
+		be the same as the given array. The new array uses the same
+		callbacks as the array to be copied. If this parameter is
+		not a valid CFArray, the behavior is undefined.
+	@result A reference to the new immutable CFArray.
+*/
+CF_EXPORT
+CFArrayRef CFArrayCreateCopy(CFAllocatorRef allocator, CFArrayRef theArray);
+
+/*!
+	@function CFArrayCreateMutable
+	Creates a new empty mutable array.
+	@param allocator The CFAllocator which should be used to allocate
+		memory for the array and its storage for values. This
+		parameter may be NULL in which case the current default
+		CFAllocator is used. If this reference is not a valid
+		CFAllocator, the behavior is undefined.
+	@param capacity A hint about the number of values that will be held
+		by the CFArray. Pass 0 for no hint. The implementation may
+		ignore this hint, or may use it to optimize various
+		operations. An array's actual capacity is only limited by
+		address space and available memory constraints). If this
+		parameter is negative, the behavior is undefined.
+	@param callBacks A pointer to a CFArrayCallBacks structure
+		initialized with the callbacks for the array to use on each
+		value in the array. A copy of the contents of the
+		callbacks structure is made, so that a pointer to a
+		structure on the stack can be passed in, or can be reused
+		for multiple array creations. If the version field of this
+		callbacks structure is not one of the defined ones for
+		CFArray, the behavior is undefined. The retain field may be
+		NULL, in which case the CFArray will do nothing to add a
+		retain to the contained values for the array. The release
+		field may be NULL, in which case the CFArray will do nothing
+		to remove the array's retain (if any) on the values when the
+		array is destroyed. If the copyDescription field is NULL,
+		the array will create a simple description for the value. If
+		the equal field is NULL, the array will use pointer equality
+		to test for equality of values. This callbacks parameter
+		itself may be NULL, which is treated as if a valid structure
+		of version 0 with all fields NULL had been passed in.
+		Otherwise, if any of the fields are not valid pointers to
+		functions of the correct type, or this parameter is not a
+		valid pointer to a  CFArrayCallBacks callbacks structure,
+		the behavior is undefined. If any of the values put into the
+		array is not one understood by one of the callback functions
+		the behavior when that callback function is used is
+		undefined.
+	@result A reference to the new mutable CFArray.
+*/
+CF_EXPORT
+CFMutableArrayRef CFArrayCreateMutable(CFAllocatorRef allocator, CFIndex capacity, const CFArrayCallBacks *callBacks);
+
+/*!
+	@function CFArrayCreateMutableCopy
+	Creates a new mutable array with the values from the given array.
+	@param allocator The CFAllocator which should be used to allocate
+		memory for the array and its storage for values. This
+		parameter may be NULL in which case the current default
+		CFAllocator is used. If this reference is not a valid
+		CFAllocator, the behavior is undefined.
+        @param capacity A hint about the number of values that will be held
+                by the CFArray. Pass 0 for no hint. The implementation may
+                ignore this hint, or may use it to optimize various
+                operations. An array's actual capacity is only limited by 
+                address space and available memory constraints).
+		This parameter must be greater than or equal
+		to the count of the array which is to be copied, or the
+		behavior is undefined. If this parameter is negative, the
+		behavior is undefined.
+	@param theArray The array which is to be copied. The values from the
+		array are copied as pointers into the new array (that is,
+		the values themselves are copied, not that which the values
+		point to, if anything). However, the values are also
+		retained by the new array. The count of the new array will
+		be the same as the given array. The new array uses the same
+		callbacks as the array to be copied. If this parameter is
+		not a valid CFArray, the behavior is undefined.
+	@result A reference to the new mutable CFArray.
+*/
+CF_EXPORT
+CFMutableArrayRef CFArrayCreateMutableCopy(CFAllocatorRef allocator, CFIndex capacity, CFArrayRef theArray);
+
+/*!
+	@function CFArrayGetCount
+	Returns the number of values currently in the array.
+	@param theArray The array to be queried. If this parameter is not a valid
+		CFArray, the behavior is undefined.
+	@result The number of values in the array.
+*/
+CF_EXPORT
+CFIndex CFArrayGetCount(CFArrayRef theArray);
+
+/*!
+	@function CFArrayGetCountOfValue
+	Counts the number of times the given value occurs in the array.
+	@param theArray The array to be searched. If this parameter is not a
+		valid CFArray, the behavior is undefined.
+	@param range The range within the array to search. If the range
+		location or end point (defined by the location plus length
+		minus 1) is outside the index space of the array (0 to
+		N-1 inclusive, where N is the count of the array), the
+		behavior is undefined. If the range length is negative, the
+		behavior is undefined. The range may be empty (length 0).
+	@param value The value for which to find matches in the array. The
+		equal() callback provided when the array was created is
+		used to compare. If the equal() callback was NULL, pointer
+		equality (in C, ==) is used. If value, or any of the values
+		in the array, are not understood by the equal() callback,
+		the behavior is undefined.
+	@result The number of times the given value occurs in the array,
+		within the specified range.
+*/
+CF_EXPORT
+CFIndex CFArrayGetCountOfValue(CFArrayRef theArray, CFRange range, const void *value);
+
+/*!
+	@function CFArrayContainsValue
+	Reports whether or not the value is in the array.
+	@param theArray The array to be searched. If this parameter is not a
+		valid CFArray, the behavior is undefined.
+	@param range The range within the array to search. If the range
+		location or end point (defined by the location plus length
+		minus 1) is outside the index space of the array (0 to
+		N-1 inclusive, where N is the count of the array), the
+		behavior is undefined. If the range length is negative, the
+		behavior is undefined. The range may be empty (length 0).
+	@param value The value for which to find matches in the array. The
+		equal() callback provided when the array was created is
+		used to compare. If the equal() callback was NULL, pointer
+		equality (in C, ==) is used. If value, or any of the values
+		in the array, are not understood by the equal() callback,
+		the behavior is undefined.
+	@result true, if the value is in the specified range of the array,
+		otherwise false.
+*/
+CF_EXPORT
+Boolean CFArrayContainsValue(CFArrayRef theArray, CFRange range, const void *value);
+
+/*!
+	@function CFArrayGetValueAtIndex
+	Retrieves the value at the given index.
+	@param theArray The array to be queried. If this parameter is not a
+		valid CFArray, the behavior is undefined.
+	@param idx The index of the value to retrieve. If the index is
+		outside the index space of the array (0 to N-1 inclusive,
+		where N is the count of the array), the behavior is
+		undefined.
+	@result The value with the given index in the array.
+*/
+CF_EXPORT
+const void *CFArrayGetValueAtIndex(CFArrayRef theArray, CFIndex idx);
+
+/*!
+	@function CFArrayGetValues
+	Fills the buffer with values from the array.
+	@param theArray The array to be queried. If this parameter is not a
+		valid CFArray, the behavior is undefined.
+	@param range The range of values within the array to retrieve. If
+		the range location or end point (defined by the location
+		plus length minus 1) is outside the index space of the
+		array (0 to N-1 inclusive, where N is the count of the
+		array), the behavior is undefined. If the range length is
+		negative, the behavior is undefined. The range may be empty
+		(length 0), in which case no values are put into the buffer.
+	@param values A C array of pointer-sized values to be filled with
+		values from the array. The values in the C array are ordered
+		in the same order in which they appear in the array. If this
+		parameter is not a valid pointer to a C array of at least
+		range.length pointers, the behavior is undefined.
+*/
+CF_EXPORT
+void CFArrayGetValues(CFArrayRef theArray, CFRange range, const void **values);
+
+/*!
+	@function CFArrayApplyFunction
+	Calls a function once for each value in the array.
+	@param theArray The array to be operated upon. If this parameter is not
+		a valid CFArray, the behavior is undefined.
+	@param range The range of values within the array to which to apply
+		the function. If the range location or end point (defined by
+		the location plus length minus 1) is outside the index
+		space of the array (0 to N-1 inclusive, where N is the count
+		of the array), the behavior is undefined. If the range
+		length is negative, the behavior is undefined. The range may
+		be empty (length 0).
+	@param applier The callback function to call once for each value in
+		the given range in the array. If this parameter is not a
+		pointer to a function of the correct prototype, the behavior
+		is undefined. If there are values in the range which the
+		applier function does not expect or cannot properly apply
+		to, the behavior is undefined. 
+	@param context A pointer-sized user-defined value, which is passed
+		as the second parameter to the applier function, but is
+		otherwise unused by this function. If the context is not
+		what is expected by the applier function, the behavior is
+		undefined.
+*/
+CF_EXPORT
+void CFArrayApplyFunction(CFArrayRef theArray, CFRange range, CFArrayApplierFunction applier, void *context);
+
+/*!
+	@function CFArrayGetFirstIndexOfValue
+	Searches the array for the value.
+	@param theArray The array to be searched. If this parameter is not a
+		valid CFArray, the behavior is undefined.
+	@param range The range within the array to search. If the range
+		location or end point (defined by the location plus length
+		minus 1) is outside the index space of the array (0 to
+		N-1 inclusive, where N is the count of the array), the
+		behavior is undefined. If the range length is negative, the
+		behavior is undefined. The range may be empty (length 0).
+		The search progresses from the smallest index defined by
+		the range to the largest.
+	@param value The value for which to find a match in the array. The
+		equal() callback provided when the array was created is
+		used to compare. If the equal() callback was NULL, pointer
+		equality (in C, ==) is used. If value, or any of the values
+		in the array, are not understood by the equal() callback,
+		the behavior is undefined.
+	@result The lowest index of the matching values in the range, or
+		kCFNotFound if no value in the range matched.
+*/
+CF_EXPORT
+CFIndex CFArrayGetFirstIndexOfValue(CFArrayRef theArray, CFRange range, const void *value);
+
+/*!
+	@function CFArrayGetLastIndexOfValue
+	Searches the array for the value.
+	@param theArray The array to be searched. If this parameter is not a
+		valid CFArray, the behavior is undefined.
+	@param range The range within the array to search. If the range
+		location or end point (defined by the location plus length
+		minus 1) is outside the index space of the array (0 to
+		N-1 inclusive, where N is the count of the array), the
+		behavior is undefined. If the range length is negative, the
+		behavior is undefined. The range may be empty (length 0).
+		The search progresses from the largest index defined by the
+		range to the smallest.
+	@param value The value for which to find a match in the array. The
+		equal() callback provided when the array was created is
+		used to compare. If the equal() callback was NULL, pointer
+		equality (in C, ==) is used. If value, or any of the values
+		in the array, are not understood by the equal() callback,
+		the behavior is undefined.
+	@result The highest index of the matching values in the range, or
+		kCFNotFound if no value in the range matched.
+*/
+CF_EXPORT
+CFIndex CFArrayGetLastIndexOfValue(CFArrayRef theArray, CFRange range, const void *value);
+
+/*!
+	@function CFArrayBSearchValues
+	Searches the array for the value using a binary search algorithm.
+	@param theArray The array to be searched. If this parameter is not a
+		valid CFArray, the behavior is undefined. If the array is
+		not sorted from least to greatest according to the
+		comparator function, the behavior is undefined.
+	@param range The range within the array to search. If the range
+		location or end point (defined by the location plus length
+		minus 1) is outside the index space of the array (0 to
+		N-1 inclusive, where N is the count of the array), the
+		behavior is undefined. If the range length is negative, the
+		behavior is undefined. The range may be empty (length 0).
+	@param value The value for which to find a match in the array. If
+		value, or any of the values in the array, are not understood
+		by the comparator callback, the behavior is undefined.
+	@param comparator The function with the comparator function type
+		signature which is used in the binary search operation to
+		compare values in the array with the given value. If this
+		parameter is not a pointer to a function of the correct
+		prototype, the behavior is undefined. If there are values
+		in the range which the comparator function does not expect
+		or cannot properly compare, the behavior is undefined.
+	@param context A pointer-sized user-defined value, which is passed
+		as the third parameter to the comparator function, but is
+		otherwise unused by this function. If the context is not
+		what is expected by the comparator function, the behavior is
+		undefined.
+	@result The return value is either 1) the index of a value that
+		matched, if the target value matches one or more in the
+		range, 2) greater than or equal to the end point of the
+		range, if the value is greater than all the values in the
+		range, or 3) the index of the value greater than the target
+		value, if the value lies between two of (or less than all
+		of) the values in the range.
+*/
+CF_EXPORT
+CFIndex CFArrayBSearchValues(CFArrayRef theArray, CFRange range, const void *value, CFComparatorFunction comparator, void *context);
+
+/*!
+	@function CFArrayAppendValue
+	Adds the value to the array giving it a new largest index.
+	@param theArray The array to which the value is to be added. If this
+		parameter is not a valid mutable CFArray, the behavior is
+		undefined.
+	@param value The value to add to the array. The value is retained by
+		the array using the retain callback provided when the array
+		was created. If the value is not of the sort expected by the
+		retain callback, the behavior is undefined. The value is
+		assigned to the index one larger than the previous largest
+		index, and the count of the array is increased by one.
+*/
+CF_EXPORT
+void CFArrayAppendValue(CFMutableArrayRef theArray, const void *value);
+
+/*!
+	@function CFArrayInsertValueAtIndex
+	Adds the value to the array, giving it the given index.
+	@param theArray The array to which the value is to be added. If this
+		parameter is not a valid mutable CFArray, the behavior is
+		undefined.
+	@param idx The index to which to add the new value. If the index is
+		outside the index space of the array (0 to N inclusive,
+		where N is the count of the array before the operation), the
+		behavior is undefined. If the index is the same as N, this
+		function has the same effect as CFArrayAppendValue().
+	@param value The value to add to the array. The value is retained by
+		the array using the retain callback provided when the array
+		was created. If the value is not of the sort expected by the
+		retain callback, the behavior is undefined. The value is
+		assigned to the given index, and all values with equal and
+		larger indices have their indexes increased by one.
+*/
+CF_EXPORT
+void CFArrayInsertValueAtIndex(CFMutableArrayRef theArray, CFIndex idx, const void *value);
+
+/*!
+	@function CFArraySetValueAtIndex
+	Changes the value with the given index in the array.
+	@param theArray The array in which the value is to be changed. If this
+		parameter is not a valid mutable CFArray, the behavior is
+		undefined.
+	@param idx The index to which to set the new value. If the index is
+		outside the index space of the array (0 to N inclusive,
+		where N is the count of the array before the operation), the
+		behavior is undefined. If the index is the same as N, this
+		function has the same effect as CFArrayAppendValue().
+	@param value The value to set in the array. The value is retained by
+		the array using the retain callback provided when the array
+		was created, and the previous value with that index is
+		released. If the value is not of the sort expected by the
+		retain callback, the behavior is undefined. The indices of
+		other values is not affected.
+*/
+CF_EXPORT
+void CFArraySetValueAtIndex(CFMutableArrayRef theArray, CFIndex idx, const void *value);
+
+/*!
+	@function CFArrayRemoveValueAtIndex
+	Removes the value with the given index from the array.
+	@param theArray The array from which the value is to be removed. If
+		this parameter is not a valid mutable CFArray, the behavior
+		is undefined.
+	@param idx The index from which to remove the value. If the index is
+		outside the index space of the array (0 to N-1 inclusive,
+		where N is the count of the array before the operation), the
+		behavior is undefined.
+*/
+CF_EXPORT
+void CFArrayRemoveValueAtIndex(CFMutableArrayRef theArray, CFIndex idx);
+
+/*!
+	@function CFArrayRemoveAllValues
+	Removes all the values from the array, making it empty.
+	@param theArray The array from which all of the values are to be
+		removed. If this parameter is not a valid mutable CFArray,
+		the behavior is undefined.
+*/
+CF_EXPORT
+void CFArrayRemoveAllValues(CFMutableArrayRef theArray);
+
+/*!
+	@function CFArrayReplaceValues
+	Replaces a range of values in the array.
+	@param theArray The array from which all of the values are to be
+		removed. If this parameter is not a valid mutable CFArray,
+		the behavior is undefined.
+	@param range The range of values within the array to replace. If the
+		range location or end point (defined by the location plus
+		length minus 1) is outside the index space of the array (0
+		to N inclusive, where N is the count of the array), the
+		behavior is undefined. If the range length is negative, the
+		behavior is undefined. The range may be empty (length 0),
+		in which case the new values are merely inserted at the
+		range location.
+	@param newValues A C array of the pointer-sized values to be placed
+		into the array. The new values in the array are ordered in
+		the same order in which they appear in this C array. This
+		parameter may be NULL if the newCount parameter is 0. This
+		C array is not changed or freed by this function. If this
+		parameter is not a valid pointer to a C array of at least
+		newCount pointers, the behavior is undefined.
+	@param newCount The number of values to copy from the values C
+		array into the CFArray. If this parameter is different than
+		the range length, the excess newCount values will be
+		inserted after the range, or the excess range values will be
+		deleted. This parameter may be 0, in which case no new
+		values are replaced into the array and the values in the
+		range are simply removed. If this parameter is negative, or
+		greater than the number of values actually in the newValues
+		C array, the behavior is undefined.
+*/
+CF_EXPORT
+void CFArrayReplaceValues(CFMutableArrayRef theArray, CFRange range, const void **newValues, CFIndex newCount);
+
+/*!
+	@function CFArrayExchangeValuesAtIndices
+	Exchanges the values at two indices of the array.
+	@param theArray The array of which the values are to be swapped. If
+		this parameter is not a valid mutable CFArray, the behavior
+		is undefined.
+	@param idx1 The first index whose values should be swapped. If the
+		index is outside the index space of the array (0 to N-1
+		inclusive, where N is the count of the array before the
+		operation), the behavior is undefined.
+	@param idx2 The second index whose values should be swapped. If the
+		index is outside the index space of the array (0 to N-1
+		inclusive, where N is the count of the array before the
+		operation), the behavior is undefined.
+*/
+CF_EXPORT
+void CFArrayExchangeValuesAtIndices(CFMutableArrayRef theArray, CFIndex idx1, CFIndex idx2);
+
+/*!
+	@function CFArraySortValues
+	Sorts the values in the array using the given comparison function.
+	@param theArray The array whose values are to be sorted. If this
+		parameter is not a valid mutable CFArray, the behavior is
+		undefined.
+	@param range The range of values within the array to sort. If the
+		range location or end point (defined by the location plus
+		length minus 1) is outside the index space of the array (0
+		to N-1 inclusive, where N is the count of the array), the
+		behavior is undefined. If the range length is negative, the
+		behavior is undefined. The range may be empty (length 0).
+	@param comparator The function with the comparator function type
+		signature which is used in the sort operation to compare
+		values in the array with the given value. If this parameter
+		is not a pointer to a function of the correct prototype, the
+		the behavior is undefined. If there are values in the array
+		which the comparator function does not expect or cannot
+		properly compare, the behavior is undefined. The values in
+		the range are sorted from least to greatest according to
+		this function.
+	@param context A pointer-sized user-defined value, which is passed
+		as the third parameter to the comparator function, but is
+		otherwise unused by this function. If the context is not
+		what is expected by the comparator function, the behavior is
+		undefined.
+*/
+CF_EXPORT
+void CFArraySortValues(CFMutableArrayRef theArray, CFRange range, CFComparatorFunction comparator, void *context);
+
+/*!
+	@function CFArrayAppendArray
+	Adds the values from an array to another array.
+	@param theArray The array to which values from the otherArray are to
+		be added. If this parameter is not a valid mutable CFArray,
+		the behavior is undefined.
+	@param otherArray The array providing the values to be added to the
+		array. If this parameter is not a valid CFArray, the
+		behavior is undefined.
+	@param otherRange The range within the otherArray from which to add
+		the values to the array. If the range location or end point
+		(defined by the location plus length minus 1) is outside
+		the index space of the otherArray (0 to N-1 inclusive, where
+		N is the count of the otherArray), the behavior is
+		undefined. The new values are retained by the array using
+		the retain callback provided when the array was created. If
+		the values are not of the sort expected by the retain
+		callback, the behavior is undefined. The values are assigned
+		to the indices one larger than the previous largest index
+		in the array, and beyond, and the count of the array is
+		increased by range.length. The values are assigned new
+		indices in the array from smallest to largest index in the
+		order in which they appear in the otherArray.
+*/
+CF_EXPORT
+void CFArrayAppendArray(CFMutableArrayRef theArray, CFArrayRef otherArray, CFRange otherRange);
+
+CF_EXTERN_C_END
+
+#endif /* ! __COREFOUNDATION_CFARRAY__ */
+
diff --git a/CoreFoundation/CFBag.c b/CoreFoundation/CFBag.c
new file mode 100644
index 0000000..ee56261
--- /dev/null
+++ b/CoreFoundation/CFBag.c
@@ -0,0 +1,1479 @@
+/*
+ * Copyright (c) 2008-2009 Brent Fulgham <bfulgham@gmail.org>.  All rights reserved.
+ *
+ * This source code is a modified version of the CoreFoundation sources released by Apple Inc. under
+ * the terms of the APSL version 2.0 (see below).
+ *
+ * For information about changes from the original Apple source release can be found by reviewing the
+ * source control system for the project at https://sourceforge.net/svn/?group_id=246198.
+ *
+ * The original license information is as follows:
+ * 
+ * Copyright (c) 2008 Apple Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*	CFBag.c
+	Copyright 1998-2006, Apple, Inc. All rights reserved.
+	Responsibility: Christopher Kane
+        Machine generated from Notes/HashingCode.template
+*/
+
+
+
+
+#include "CFInternal.h"
+#include <CoreFoundation/CFBag.h>
+#if DEPLOYMENT_TARGET_MACOSX
+#include <mach-o/dyld.h>
+#endif
+
+#define CFDictionary 0
+#define CFSet 0
+#define CFBag 0
+#undef CFBag
+#define CFBag 1
+
+#if CFDictionary
+const CFBagKeyCallBacks kCFTypeBagKeyCallBacks = {0, __CFTypeCollectionRetain, __CFTypeCollectionRelease, CFCopyDescription, CFEqual, CFHash};
+const CFBagKeyCallBacks kCFCopyStringBagKeyCallBacks = {0, __CFStringCollectionCopy, __CFTypeCollectionRelease, CFCopyDescription, CFEqual, CFHash};
+const CFBagValueCallBacks kCFTypeBagValueCallBacks = {0, __CFTypeCollectionRetain, __CFTypeCollectionRelease, CFCopyDescription, CFEqual};
+static const CFBagKeyCallBacks __kCFNullBagKeyCallBacks = {0, NULL, NULL, NULL, NULL, NULL};
+static const CFBagValueCallBacks __kCFNullBagValueCallBacks = {0, NULL, NULL, NULL, NULL};
+
+#define CFHashRef CFDictionaryRef
+#define CFMutableHashRef CFMutableDictionaryRef
+#define __kCFHashTypeID __kCFDictionaryTypeID
+#endif
+
+#if CFSet
+const CFBagCallBacks kCFTypeBagCallBacks = {0, __CFTypeCollectionRetain, __CFTypeCollectionRelease, CFCopyDescription, CFEqual, CFHash};
+const CFBagCallBacks kCFCopyStringBagCallBacks = {0, __CFStringCollectionCopy, __CFTypeCollectionRelease, CFCopyDescription, CFEqual, CFHash};
+static const CFBagCallBacks __kCFNullBagCallBacks = {0, NULL, NULL, NULL, NULL, NULL};
+
+#define CFBagKeyCallBacks CFBagCallBacks
+#define CFBagValueCallBacks CFBagCallBacks
+#define kCFTypeBagKeyCallBacks kCFTypeBagCallBacks
+#define kCFTypeBagValueCallBacks kCFTypeBagCallBacks
+#define __kCFNullBagKeyCallBacks __kCFNullBagCallBacks
+#define __kCFNullBagValueCallBacks __kCFNullBagCallBacks
+
+#define CFHashRef CFSetRef
+#define CFMutableHashRef CFMutableSetRef
+#define __kCFHashTypeID __kCFSetTypeID
+#endif
+
+#if CFBag
+const CFBagCallBacks kCFTypeBagCallBacks = {0, __CFTypeCollectionRetain, __CFTypeCollectionRelease, CFCopyDescription, CFEqual, CFHash};
+const CFBagCallBacks kCFCopyStringBagCallBacks = {0, __CFStringCollectionCopy, __CFTypeCollectionRelease, CFCopyDescription, CFEqual, CFHash};
+static const CFBagCallBacks __kCFNullBagCallBacks = {0, NULL, NULL, NULL, NULL, NULL};
+
+#define CFBagKeyCallBacks CFBagCallBacks
+#define CFBagValueCallBacks CFBagCallBacks
+#define kCFTypeBagKeyCallBacks kCFTypeBagCallBacks
+#define kCFTypeBagValueCallBacks kCFTypeBagCallBacks
+#define __kCFNullBagKeyCallBacks __kCFNullBagCallBacks
+#define __kCFNullBagValueCallBacks __kCFNullBagCallBacks
+
+#define CFHashRef CFBagRef
+#define CFMutableHashRef CFMutableBagRef
+#define __kCFHashTypeID __kCFBagTypeID
+#endif
+
+#define GETNEWKEY(newKey, oldKey) \
+        any_t (*kretain)(CFAllocatorRef, any_t, any_pointer_t) = \
+          !hasBeenFinalized(hc) \
+            ? (any_t (*)(CFAllocatorRef,any_t,any_pointer_t))__CFBagGetKeyCallBacks(hc)->retain \
+            : (any_t (*)(CFAllocatorRef,any_t,any_pointer_t))0; \
+        any_t newKey = kretain ? (any_t)INVOKE_CALLBACK3(kretain, allocator, (any_t)key, hc->_context) : (any_t)oldKey
+
+#define RELEASEKEY(oldKey) \
+        void (*krelease)(CFAllocatorRef, any_t, any_pointer_t) = \
+          !hasBeenFinalized(hc) \
+            ? (void (*)(CFAllocatorRef,any_t,any_pointer_t))__CFBagGetKeyCallBacks(hc)->release \
+            : (void (*)(CFAllocatorRef,any_t,any_pointer_t))0; \
+        if (krelease) INVOKE_CALLBACK3(krelease, allocator, oldKey, hc->_context)
+        
+#if CFDictionary
+#define GETNEWVALUE(newValue) \
+        any_t (*vretain)(CFAllocatorRef, any_t, any_pointer_t) = \
+          !hasBeenFinalized(hc) \
+            ? (any_t (*)(CFAllocatorRef,any_t,any_pointer_t))__CFBagGetValueCallBacks(hc)->retain \
+            : (any_t (*)(CFAllocatorRef,any_t,any_pointer_t))0; \
+        any_t newValue = vretain ? (any_t)INVOKE_CALLBACK3(vretain, allocator, (any_t)value, hc->_context) : (any_t)value
+
+#define RELEASEVALUE(oldValue) \
+    void (*vrelease)(CFAllocatorRef, any_t, any_pointer_t) = \
+      !hasBeenFinalized(hc) \
+        ? (void (*)(CFAllocatorRef,any_t,any_pointer_t))__CFBagGetValueCallBacks(hc)->release \
+        : (void (*)(CFAllocatorRef,any_t,any_pointer_t))0; \
+    if (vrelease) INVOKE_CALLBACK3(vrelease, allocator, oldValue, hc->_context)
+
+#endif
+
+static void __CFBagHandleOutOfMemory(CFTypeRef obj, CFIndex numBytes) {
+    CFStringRef msg = CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("Attempt to allocate %ld bytes for NS/CFBag failed"), numBytes);
+    CFBadErrorCallBack cb = _CFGetOutOfMemoryErrorCallBack();
+    if (NULL == cb || !cb(obj, CFSTR("NS/CFBag"), msg)) {
+        CFLog(kCFLogLevelCritical, CFSTR("%@"), msg);
+	HALT;
+    }
+    CFRelease(msg);
+}
+
+
+// Max load is 3/4 number of buckets
+CF_INLINE CFIndex __CFHashRoundUpCapacity(CFIndex capacity) {
+    return 3 * ((CFIndex)1 << (flsl((capacity - 1) / 3)));
+}
+
+// Returns next power of two higher than the capacity
+// threshold for the given input capacity.
+CF_INLINE CFIndex __CFHashNumBucketsForCapacity(CFIndex capacity) {
+    return 4 * ((CFIndex)1 << (flsl((capacity - 1) / 3)));
+}
+
+enum {                /* Bits 1-0 */
+    __kCFHashImmutable = 0,        /* unchangable and fixed capacity */
+    __kCFHashMutable = 1,                /* changeable and variable capacity */
+};
+
+enum {                /* Bits 5-4 (value), 3-2 (key) */
+    __kCFHashHasNullCallBacks = 0,
+    __kCFHashHasCFTypeCallBacks = 1,
+    __kCFHashHasCustomCallBacks = 3        /* callbacks are at end of header */
+};
+
+// Under GC, we fudge the key/value memory in two ways
+// First, if we had null callbacks or null for both retain/release, we use unscanned memory and get
+// standard 'dangling' references.
+// This means that if people were doing addValue:[xxx new] and never removing, well, that doesn't work
+//
+// Second, if we notice standard retain/release implementations we use scanned memory, and fudge the
+// standard callbacks to generally do nothing if the collection was allocated in GC memory. On special
+// CF objects, however, like those used for precious resources like video-card buffers, we do indeed
+// do CFRetain on input and CFRelease on output.  The tricky case is GC finalization; we need to remember
+// that we did the CFReleases so that subsequent collection operations, like removal, don't double CFRelease.
+// (In fact we don't really use CFRetain/CFRelease but go directly to the collector)
+//
+
+enum {
+    __kCFHashFinalized =         (1 << 7),
+    __kCFHashWeakKeys =          (1 << 8),
+    __kCFHashWeakValues =        (1 << 9)
+};
+
+typedef uintptr_t any_t;
+typedef const void * const_any_pointer_t;
+typedef void * any_pointer_t;
+
+struct __CFBag {
+    CFRuntimeBase _base;
+    CFIndex _count;             /* number of values */
+    CFIndex _bucketsNum;        /* number of buckets */
+    CFIndex _bucketsUsed;       /* number of used buckets */
+    CFIndex _bucketsCap;        /* maximum number of used buckets */
+    CFIndex _mutations;
+    CFIndex _deletes;
+    any_pointer_t _context;     /* private */
+    CFOptionFlags _xflags;
+    any_t _marker;
+    any_t *_keys;     /* can be NULL if not allocated yet */
+    any_t *_values;   /* can be NULL if not allocated yet */
+};
+
+/* Bits 1-0 of the _xflags are used for mutability variety */
+/* Bits 3-2 of the _xflags are used for key callback indicator bits */
+/* Bits 5-4 of the _xflags are used for value callback indicator bits */
+/* Bit 6 of the _xflags is special KVO actions bit */
+/* Bits 7,8,9 are GC use */
+
+CF_INLINE bool hasBeenFinalized(CFTypeRef collection) {
+    return __CFBitfieldGetValue(((const struct __CFBag *)collection)->_xflags, 7, 7) != 0;
+}
+
+CF_INLINE void markFinalized(CFTypeRef collection) {
+    __CFBitfieldSetValue(((struct __CFBag *)collection)->_xflags, 7, 7, 1);
+}
+
+
+CF_INLINE CFIndex __CFHashGetType(CFHashRef hc) {
+    return __CFBitfieldGetValue(hc->_xflags, 1, 0);
+}
+
+CF_INLINE CFIndex __CFBagGetSizeOfType(CFIndex t) {
+    CFIndex size = sizeof(struct __CFBag);
+    if (__CFBitfieldGetValue(t, 3, 2) == __kCFHashHasCustomCallBacks) {
+        size += sizeof(CFBagKeyCallBacks);
+    }
+    if (__CFBitfieldGetValue(t, 5, 4) == __kCFHashHasCustomCallBacks) {
+        size += sizeof(CFBagValueCallBacks);
+    }
+    return size;
+}
+
+CF_INLINE const CFBagKeyCallBacks *__CFBagGetKeyCallBacks(CFHashRef hc) {
+    CFBagKeyCallBacks *result = NULL;
+    switch (__CFBitfieldGetValue(hc->_xflags, 3, 2)) {
+    case __kCFHashHasNullCallBacks:
+        return &__kCFNullBagKeyCallBacks;
+    case __kCFHashHasCFTypeCallBacks:
+        return &kCFTypeBagKeyCallBacks;
+    case __kCFHashHasCustomCallBacks:
+        break;
+    }
+    result = (CFBagKeyCallBacks *)((uint8_t *)hc + sizeof(struct __CFBag));
+    return result;
+}
+
+CF_INLINE Boolean __CFBagKeyCallBacksMatchNull(const CFBagKeyCallBacks *c) {
+    return (NULL == c ||
+        (c->retain == __kCFNullBagKeyCallBacks.retain &&
+         c->release == __kCFNullBagKeyCallBacks.release &&
+         c->copyDescription == __kCFNullBagKeyCallBacks.copyDescription &&
+         c->equal == __kCFNullBagKeyCallBacks.equal &&
+         c->hash == __kCFNullBagKeyCallBacks.hash));
+}
+
+CF_INLINE Boolean __CFBagKeyCallBacksMatchCFType(const CFBagKeyCallBacks *c) {
+    return (&kCFTypeBagKeyCallBacks == c ||
+        (c->retain == kCFTypeBagKeyCallBacks.retain &&
+         c->release == kCFTypeBagKeyCallBacks.release &&
+         c->copyDescription == kCFTypeBagKeyCallBacks.copyDescription &&
+         c->equal == kCFTypeBagKeyCallBacks.equal &&
+         c->hash == kCFTypeBagKeyCallBacks.hash));
+}
+
+CF_INLINE const CFBagValueCallBacks *__CFBagGetValueCallBacks(CFHashRef hc) {
+    CFBagValueCallBacks *result = NULL;
+    switch (__CFBitfieldGetValue(hc->_xflags, 5, 4)) {
+    case __kCFHashHasNullCallBacks:
+        return &__kCFNullBagValueCallBacks;
+    case __kCFHashHasCFTypeCallBacks:
+        return &kCFTypeBagValueCallBacks;
+    case __kCFHashHasCustomCallBacks:
+        break;
+    }
+    if (__CFBitfieldGetValue(hc->_xflags, 3, 2) == __kCFHashHasCustomCallBacks) {
+        result = (CFBagValueCallBacks *)((uint8_t *)hc + sizeof(struct __CFBag) + sizeof(CFBagKeyCallBacks));
+    } else {
+        result = (CFBagValueCallBacks *)((uint8_t *)hc + sizeof(struct __CFBag));
+    }
+    return result;
+}
+
+CF_INLINE Boolean __CFBagValueCallBacksMatchNull(const CFBagValueCallBacks *c) {
+    return (NULL == c ||
+        (c->retain == __kCFNullBagValueCallBacks.retain &&
+         c->release == __kCFNullBagValueCallBacks.release &&
+         c->copyDescription == __kCFNullBagValueCallBacks.copyDescription &&
+         c->equal == __kCFNullBagValueCallBacks.equal));
+}
+
+CF_INLINE Boolean __CFBagValueCallBacksMatchCFType(const CFBagValueCallBacks *c) {
+    return (&kCFTypeBagValueCallBacks == c ||
+        (c->retain == kCFTypeBagValueCallBacks.retain &&
+         c->release == kCFTypeBagValueCallBacks.release &&
+         c->copyDescription == kCFTypeBagValueCallBacks.copyDescription &&
+         c->equal == kCFTypeBagValueCallBacks.equal));
+}
+
+CFIndex _CFBagGetKVOBit(CFHashRef hc) {
+    return __CFBitfieldGetValue(hc->_xflags, 6, 6);
+}
+
+void _CFBagSetKVOBit(CFHashRef hc, CFIndex bit) {
+    __CFBitfieldSetValue(((CFMutableHashRef)hc)->_xflags, 6, 6, ((uintptr_t)bit & 0x1));
+}
+
+CF_INLINE Boolean __CFBagShouldShrink(CFHashRef hc) {
+    return (__kCFHashMutable == __CFHashGetType(hc)) &&
+                !(CF_USING_COLLECTABLE_MEMORY && auto_zone_is_finalized(__CFCollectableZone, hc)) && /* GC:  don't shrink finalizing hcs! */
+                (hc->_bucketsNum < 4 * hc->_deletes || (256 <= hc->_bucketsCap && hc-> _bucketsUsed < 3 * hc->_bucketsCap / 16));
+}
+
+CF_INLINE CFIndex __CFHashGetOccurrenceCount(CFHashRef hc, CFIndex idx) {
+#if CFBag
+    return (CFIndex)hc->_values[idx];
+#endif
+    return 1;
+}
+
+CF_INLINE Boolean __CFHashKeyIsValue(CFHashRef hc, any_t key) {
+    return (hc->_marker != key && ~hc->_marker != key) ? true : false;
+}
+
+CF_INLINE Boolean __CFHashKeyIsMagic(CFHashRef hc, any_t key) {
+    return (hc->_marker == key || ~hc->_marker == key) ? true : false;
+}
+
+
+#if !defined(CF_OBJC_KVO_WILLCHANGE)
+#define CF_OBJC_KVO_WILLCHANGE(obj, key)
+#define CF_OBJC_KVO_DIDCHANGE(obj, key)
+#endif
+
+CF_INLINE uintptr_t __CFBagScrambleHash(uintptr_t k) {
+#if 0
+    return k;
+#else
+#if __LP64__
+    uintptr_t a = 0x4368726973746F70ULL;
+    uintptr_t b = 0x686572204B616E65ULL;
+#else
+    uintptr_t a = 0x4B616E65UL;
+    uintptr_t b = 0x4B616E65UL;
+#endif
+    uintptr_t c = 1;
+    a += k;
+#if __LP64__
+    a -= b; a -= c; a ^= (c >> 43);
+    b -= c; b -= a; b ^= (a << 9);
+    c -= a; c -= b; c ^= (b >> 8);
+    a -= b; a -= c; a ^= (c >> 38);
+    b -= c; b -= a; b ^= (a << 23);
+    c -= a; c -= b; c ^= (b >> 5);
+    a -= b; a -= c; a ^= (c >> 35);
+    b -= c; b -= a; b ^= (a << 49);
+    c -= a; c -= b; c ^= (b >> 11);
+    a -= b; a -= c; a ^= (c >> 12);
+    b -= c; b -= a; b ^= (a << 18);
+    c -= a; c -= b; c ^= (b >> 22);
+#else
+    a -= b; a -= c; a ^= (c >> 13);
+    b -= c; b -= a; b ^= (a << 8);
+    c -= a; c -= b; c ^= (b >> 13);
+    a -= b; a -= c; a ^= (c >> 12);
+    b -= c; b -= a; b ^= (a << 16);
+    c -= a; c -= b; c ^= (b >> 5);
+    a -= b; a -= c; a ^= (c >> 3);
+    b -= c; b -= a; b ^= (a << 10);
+    c -= a; c -= b; c ^= (b >> 15);
+#endif
+    return c;
+#endif
+}
+
+static CFIndex __CFBagFindBuckets1a(CFHashRef hc, any_t key) {
+    CFHashCode keyHash = (CFHashCode)key;
+    keyHash = (CFHashCode)__CFBagScrambleHash(keyHash);
+    any_t *keys = hc->_keys;
+    any_t marker = hc->_marker;
+    CFIndex probe = keyHash & (hc->_bucketsNum - 1);
+    CFIndex probeskip = 1;        // See RemoveValue() for notes before changing this value
+    CFIndex start = probe;
+    for (;;) {
+        any_t currKey = keys[probe];
+        if (marker == currKey) {                /* empty */
+            return kCFNotFound;
+        } else if (~marker == currKey) {        /* deleted */
+            /* do nothing */
+        } else if (currKey == key) {
+            return probe;
+        }
+        probe = probe + probeskip;
+        // This alternative to probe % buckets assumes that
+        // probeskip is always positive and less than the
+        // number of buckets.
+        if (hc->_bucketsNum <= probe) {
+            probe -= hc->_bucketsNum;
+        }
+        if (start == probe) {
+            return kCFNotFound;
+        }
+    }
+}
+
+static CFIndex __CFBagFindBuckets1b(CFHashRef hc, any_t key) {
+    const CFBagKeyCallBacks *cb = __CFBagGetKeyCallBacks(hc);
+    CFHashCode keyHash = cb->hash ? (CFHashCode)INVOKE_CALLBACK2(((CFHashCode (*)(any_t, any_pointer_t))cb->hash), key, hc->_context) : (CFHashCode)key;
+    keyHash = (CFHashCode)__CFBagScrambleHash(keyHash);
+    any_t *keys = hc->_keys;
+    any_t marker = hc->_marker;
+    CFIndex probe = keyHash & (hc->_bucketsNum - 1);
+    CFIndex probeskip = 1;        // See RemoveValue() for notes before changing this value
+    CFIndex start = probe;
+    for (;;) {
+        any_t currKey = keys[probe];
+        if (marker == currKey) {                /* empty */
+            return kCFNotFound;
+        } else if (~marker == currKey) {        /* deleted */
+            /* do nothing */
+        } else if (currKey == key || (cb->equal && INVOKE_CALLBACK3((Boolean (*)(any_t, any_t, any_pointer_t))cb->equal, currKey, key, hc->_context))) {
+            return probe;
+        }
+        probe = probe + probeskip;
+        // This alternative to probe % buckets assumes that
+        // probeskip is always positive and less than the
+        // number of buckets.
+        if (hc->_bucketsNum <= probe) {
+            probe -= hc->_bucketsNum;
+        }
+        if (start == probe) {
+            return kCFNotFound;
+        }
+    }
+}
+
+CF_INLINE CFIndex __CFBagFindBuckets1(CFHashRef hc, any_t key) {
+    if (__kCFHashHasNullCallBacks == __CFBitfieldGetValue(hc->_xflags, 3, 2)) {
+        return __CFBagFindBuckets1a(hc, key);
+    }
+    return __CFBagFindBuckets1b(hc, key);
+}
+
+static void __CFBagFindBuckets2(CFHashRef hc, any_t key, CFIndex *match, CFIndex *nomatch) {
+    const CFBagKeyCallBacks *cb = __CFBagGetKeyCallBacks(hc);
+    CFHashCode keyHash = cb->hash ? (CFHashCode)INVOKE_CALLBACK2(((CFHashCode (*)(any_t, any_pointer_t))cb->hash), key, hc->_context) : (CFHashCode)key;
+    keyHash = (CFHashCode)__CFBagScrambleHash(keyHash);
+    any_t *keys = hc->_keys;
+    any_t marker = hc->_marker;
+    CFIndex probe = keyHash & (hc->_bucketsNum - 1);
+    CFIndex probeskip = 1;        // See RemoveValue() for notes before changing this value
+    CFIndex start = probe;
+    *match = kCFNotFound;
+    *nomatch = kCFNotFound;
+    for (;;) {
+        any_t currKey = keys[probe];
+        if (marker == currKey) {                /* empty */
+            if (nomatch) *nomatch = probe;
+            return;
+        } else if (~marker == currKey) {        /* deleted */
+            if (nomatch) {
+                *nomatch = probe;
+                nomatch = NULL;
+            }
+        } else if (currKey == key || (cb->equal && INVOKE_CALLBACK3((Boolean (*)(any_t, any_t, any_pointer_t))cb->equal, currKey, key, hc->_context))) {
+            *match = probe;
+            return;
+        }
+        probe = probe + probeskip;
+        // This alternative to probe % buckets assumes that
+        // probeskip is always positive and less than the
+        // number of buckets.
+        if (hc->_bucketsNum <= probe) {
+            probe -= hc->_bucketsNum;
+        }
+        if (start == probe) {
+            return;
+        }
+    }
+}
+
+static void __CFBagFindNewMarker(CFHashRef hc) {
+    any_t *keys = hc->_keys;
+    any_t newMarker;
+    CFIndex idx, nbuckets;
+    Boolean hit;
+
+    nbuckets = hc->_bucketsNum;
+    newMarker = hc->_marker;
+    do {
+        newMarker--;
+        hit = false;
+        for (idx = 0; idx < nbuckets; idx++) {
+            if (newMarker == keys[idx] || ~newMarker == keys[idx]) {
+                hit = true;
+                break;
+            }
+        }
+    } while (hit);
+    for (idx = 0; idx < nbuckets; idx++) {
+        if (hc->_marker == keys[idx]) {
+            keys[idx] = newMarker;
+        } else if (~hc->_marker == keys[idx]) {
+            keys[idx] = ~newMarker;
+        }
+    }
+    ((struct __CFBag *)hc)->_marker = newMarker;
+}
+
+static Boolean __CFBagEqual(CFTypeRef cf1, CFTypeRef cf2) {
+    CFHashRef hc1 = (CFHashRef)cf1;
+    CFHashRef hc2 = (CFHashRef)cf2;
+    const CFBagKeyCallBacks *cb1, *cb2;
+    const CFBagValueCallBacks *vcb1, *vcb2;
+    any_t *keys;
+    CFIndex idx, nbuckets;
+    if (hc1 == hc2) return true;
+    if (hc1->_count != hc2->_count) return false;
+    cb1 = __CFBagGetKeyCallBacks(hc1);
+    cb2 = __CFBagGetKeyCallBacks(hc2);
+    if (cb1->equal != cb2->equal) return false;
+    vcb1 = __CFBagGetValueCallBacks(hc1);
+    vcb2 = __CFBagGetValueCallBacks(hc2);
+    if (vcb1->equal != vcb2->equal) return false;
+    if (0 == hc1->_bucketsUsed) return true; /* after function comparison! */
+    keys = hc1->_keys;
+    nbuckets = hc1->_bucketsNum;
+    for (idx = 0; idx < nbuckets; idx++) {
+        if (hc1->_marker != keys[idx] && ~hc1->_marker != keys[idx]) {
+#if CFDictionary
+            const_any_pointer_t value;
+            if (!CFBagGetValueIfPresent(hc2, (any_pointer_t)keys[idx], &value)) return false;
+	    if (hc1->_values[idx] != (any_t)value) {
+		if (NULL == vcb1->equal) return false;
+	        if (!INVOKE_CALLBACK3((Boolean (*)(any_t, any_t, any_pointer_t))vcb1->equal, hc1->_values[idx], (any_t)value, hc1->_context)) return false;
+            }
+#endif
+#if  CFSet
+            const_any_pointer_t value;
+            if (!CFBagGetValueIfPresent(hc2, (any_pointer_t)keys[idx], &value)) return false;
+#endif
+#if CFBag
+            if (hc1->_values[idx] != CFBagGetCountOfValue(hc2, (any_pointer_t)keys[idx])) return false;
+#endif
+        }
+    }
+    return true;
+}
+
+static CFHashCode __CFBagHash(CFTypeRef cf) {
+    CFHashRef hc = (CFHashRef)cf;
+    return hc->_count;
+}
+
+static CFStringRef __CFBagCopyDescription(CFTypeRef cf) {
+    CFHashRef hc = (CFHashRef)cf;
+    CFAllocatorRef allocator;
+    const CFBagKeyCallBacks *cb;
+    const CFBagValueCallBacks *vcb;
+    any_t *keys;
+    CFIndex idx, nbuckets;
+    CFMutableStringRef result;
+    cb = __CFBagGetKeyCallBacks(hc);
+    vcb = __CFBagGetValueCallBacks(hc);
+    keys = hc->_keys;
+    nbuckets = hc->_bucketsNum;
+    allocator = CFGetAllocator(hc);
+    result = CFStringCreateMutable(allocator, 0);
+    const char *type = "?";
+    switch (__CFHashGetType(hc)) {
+    case __kCFHashImmutable: type = "immutable"; break;
+    case __kCFHashMutable: type = "mutable"; break;
+    }
+    CFStringAppendFormat(result, NULL, CFSTR("<CFBag %p [%p]>{type = %s, count = %u, capacity = %u, pairs = (\n"), cf, allocator, type, hc->_count, hc->_bucketsCap);
+    for (idx = 0; idx < nbuckets; idx++) {
+        if (__CFHashKeyIsValue(hc, keys[idx])) {
+            CFStringRef kDesc = NULL, vDesc = NULL;
+            if (NULL != cb->copyDescription) {
+                kDesc = (CFStringRef)INVOKE_CALLBACK2(((CFStringRef (*)(any_t, any_pointer_t))cb->copyDescription), keys[idx], hc->_context);
+            }
+            if (NULL != vcb->copyDescription) {
+                vDesc = (CFStringRef)INVOKE_CALLBACK2(((CFStringRef (*)(any_t, any_pointer_t))vcb->copyDescription), hc->_values[idx], hc->_context);
+            }
+#if CFDictionary
+            if (NULL != kDesc && NULL != vDesc) {
+                CFStringAppendFormat(result, NULL, CFSTR("\t%u : %@ = %@\n"), idx, kDesc, vDesc);
+                CFRelease(kDesc);
+                CFRelease(vDesc);
+            } else if (NULL != kDesc) {
+                CFStringAppendFormat(result, NULL, CFSTR("\t%u : %@ = <%p>\n"), idx, kDesc, hc->_values[idx]);
+                CFRelease(kDesc);
+            } else if (NULL != vDesc) {
+                CFStringAppendFormat(result, NULL, CFSTR("\t%u : <%p> = %@\n"), idx, keys[idx], vDesc);
+                CFRelease(vDesc);
+            } else {
+                CFStringAppendFormat(result, NULL, CFSTR("\t%u : <%p> = <%p>\n"), idx, keys[idx], hc->_values[idx]);
+            }
+#endif
+#if CFSet
+            if (NULL != kDesc) {
+                CFStringAppendFormat(result, NULL, CFSTR("\t%u : %@\n"), idx, kDesc);
+                CFRelease(kDesc);
+            } else {
+                CFStringAppendFormat(result, NULL, CFSTR("\t%u : <%p>\n"), idx, keys[idx]);
+            }
+#endif
+#if CFBag
+            if (NULL != kDesc) {
+                CFStringAppendFormat(result, NULL, CFSTR("\t%u : %@ (%ld)\n"), idx, kDesc, hc->_values[idx]);
+                CFRelease(kDesc);
+            } else {
+                CFStringAppendFormat(result, NULL, CFSTR("\t%u : <%p> (%ld)\n"), idx, keys[idx], hc->_values[idx]);
+            }
+#endif
+        }
+    }
+    CFStringAppend(result, CFSTR(")}"));
+    return result;
+}
+
+static void __CFBagDeallocate(CFTypeRef cf) {
+    CFMutableHashRef hc = (CFMutableHashRef)cf;
+    CFAllocatorRef allocator = __CFGetAllocator(hc);
+    const CFBagKeyCallBacks *cb = __CFBagGetKeyCallBacks(hc);
+    const CFBagValueCallBacks *vcb = __CFBagGetValueCallBacks(hc);
+
+    // mark now in case any callout somehow tries to add an entry back in
+    markFinalized(cf);
+    if (vcb->release || cb->release) {
+        any_t *keys = hc->_keys;
+        CFIndex idx, nbuckets = hc->_bucketsNum;
+        for (idx = 0; idx < nbuckets; idx++) {
+            any_t oldkey = keys[idx];
+            if (hc->_marker != oldkey && ~hc->_marker != oldkey) {
+                if (vcb->release) {
+                    INVOKE_CALLBACK3(((void (*)(CFAllocatorRef, any_t, any_pointer_t))vcb->release), allocator, hc->_values[idx], hc->_context);
+                }
+                if (cb->release) {
+                    INVOKE_CALLBACK3(((void (*)(CFAllocatorRef, any_t, any_pointer_t))cb->release), allocator, oldkey, hc->_context);
+                }
+            }
+        }
+    }
+
+    if (CF_IS_COLLECTABLE_ALLOCATOR(allocator)) {
+        // return early so that contents are preserved after finalization
+        return;
+    }
+    
+    _CFAllocatorDeallocateGC(allocator, hc->_keys);
+#if CFDictionary || CFBag
+    _CFAllocatorDeallocateGC(allocator, hc->_values);
+#endif
+    hc->_keys = NULL;
+    hc->_values = NULL;
+    hc->_count = 0;  // GC: also zero count, so the hc will appear empty.
+    hc->_bucketsUsed = 0;
+    hc->_bucketsNum = 0;
+}
+
+static CFTypeID __kCFBagTypeID = _kCFRuntimeNotATypeID;
+
+static const CFRuntimeClass __CFBagClass = {
+    _kCFRuntimeScannedObject,
+    "CFBag",
+    NULL,        // init
+    NULL,        // copy
+    __CFBagDeallocate,
+    __CFBagEqual,
+    __CFBagHash,
+    NULL,        //
+    __CFBagCopyDescription
+};
+
+__private_extern__ void __CFBagInitialize(void) {
+    __kCFHashTypeID = _CFRuntimeRegisterClass(&__CFBagClass);
+}
+
+CFTypeID CFBagGetTypeID(void) {
+    return __kCFHashTypeID;
+}
+
+static CFMutableHashRef __CFBagInit(CFAllocatorRef allocator, CFOptionFlags flags, CFIndex capacity, const CFBagKeyCallBacks *keyCallBacks
+#if CFDictionary
+, const CFBagValueCallBacks *valueCallBacks
+#endif
+) {
+    struct __CFBag *hc;
+    CFIndex size;
+    __CFBitfieldSetValue(flags, 31, 2, 0);
+    CFOptionFlags xflags = 0;
+    if (CF_IS_COLLECTABLE_ALLOCATOR(allocator)) {
+        // preserve NULL for key or value CB, otherwise fix up.
+        if (!keyCallBacks || (keyCallBacks->retain == NULL && keyCallBacks->release == NULL)) {
+            xflags = __kCFHashWeakKeys;
+        }
+#if CFDictionary
+        if (!valueCallBacks || (valueCallBacks->retain == NULL && valueCallBacks->release == NULL)) {
+            xflags |= __kCFHashWeakValues;
+        }
+#endif
+#if CFBag
+        xflags |= __kCFHashWeakValues;
+#endif
+    }
+    if (__CFBagKeyCallBacksMatchNull(keyCallBacks)) {
+        __CFBitfieldSetValue(flags, 3, 2, __kCFHashHasNullCallBacks);
+    } else if (__CFBagKeyCallBacksMatchCFType(keyCallBacks)) {
+        __CFBitfieldSetValue(flags, 3, 2, __kCFHashHasCFTypeCallBacks);
+    } else {
+        __CFBitfieldSetValue(flags, 3, 2, __kCFHashHasCustomCallBacks);
+    }
+#if CFDictionary
+    if (__CFBagValueCallBacksMatchNull(valueCallBacks)) {
+        __CFBitfieldSetValue(flags, 5, 4, __kCFHashHasNullCallBacks);
+    } else if (__CFBagValueCallBacksMatchCFType(valueCallBacks)) {
+        __CFBitfieldSetValue(flags, 5, 4, __kCFHashHasCFTypeCallBacks);
+    } else {
+        __CFBitfieldSetValue(flags, 5, 4, __kCFHashHasCustomCallBacks);
+    }
+#endif
+    size = __CFBagGetSizeOfType(flags) - sizeof(CFRuntimeBase);
+    hc = (struct __CFBag *)_CFRuntimeCreateInstance(allocator, __kCFHashTypeID, size, NULL);
+    if (NULL == hc) {
+        return NULL;
+    }
+    hc->_count = 0;
+    hc->_bucketsUsed = 0;
+    hc->_marker = (any_t)0xa1b1c1d3;
+    hc->_context = NULL;
+    hc->_deletes = 0;
+    hc->_mutations = 1;
+    hc->_xflags = xflags | flags;
+    switch (__CFBitfieldGetValue(flags, 1, 0)) {
+    case __kCFHashImmutable:
+        if (__CFOASafe) __CFSetLastAllocationEventName(hc, "CFBag (immutable)");
+        break;
+    case __kCFHashMutable:
+        if (__CFOASafe) __CFSetLastAllocationEventName(hc, "CFBag (mutable-variable)");
+        break;
+    }
+    hc->_bucketsCap = __CFHashRoundUpCapacity(1);
+    hc->_bucketsNum = 0;
+    hc->_keys = NULL;
+    hc->_values = NULL;
+    if (__kCFHashHasCustomCallBacks == __CFBitfieldGetValue(flags, 3, 2)) {
+        CFBagKeyCallBacks *cb = (CFBagKeyCallBacks *)__CFBagGetKeyCallBacks((CFHashRef)hc);
+        *cb = *keyCallBacks;
+        FAULT_CALLBACK((void **)&(cb->retain));
+        FAULT_CALLBACK((void **)&(cb->release));
+        FAULT_CALLBACK((void **)&(cb->copyDescription));
+        FAULT_CALLBACK((void **)&(cb->equal));
+        FAULT_CALLBACK((void **)&(cb->hash));
+    }
+#if CFDictionary
+    if (__kCFHashHasCustomCallBacks == __CFBitfieldGetValue(flags, 5, 4)) {
+        CFBagValueCallBacks *vcb = (CFBagValueCallBacks *)__CFBagGetValueCallBacks((CFHashRef)hc);
+        *vcb = *valueCallBacks;
+        FAULT_CALLBACK((void **)&(vcb->retain));
+        FAULT_CALLBACK((void **)&(vcb->release));
+        FAULT_CALLBACK((void **)&(vcb->copyDescription));
+        FAULT_CALLBACK((void **)&(vcb->equal));
+    }
+#endif
+    return hc;
+}
+
+#if CFDictionary
+CFHashRef CFBagCreate(CFAllocatorRef allocator, const_any_pointer_t *keys, const_any_pointer_t *values, CFIndex numValues, const CFBagKeyCallBacks *keyCallBacks, const CFBagValueCallBacks *valueCallBacks) {
+#endif
+#if CFSet || CFBag
+CFHashRef CFBagCreate(CFAllocatorRef allocator, const_any_pointer_t *keys, CFIndex numValues, const CFBagKeyCallBacks *keyCallBacks) {
+#endif
+    CFAssert2(0 <= numValues, __kCFLogAssertion, "%s(): numValues (%ld) cannot be less than zero", __PRETTY_FUNCTION__, numValues);
+#if CFDictionary
+    CFMutableHashRef hc = __CFBagInit(allocator, __kCFHashImmutable, numValues, keyCallBacks, valueCallBacks);
+#endif
+#if CFSet || CFBag
+    CFMutableHashRef hc = __CFBagInit(allocator, __kCFHashImmutable, numValues, keyCallBacks);
+#endif
+    __CFBitfieldSetValue(hc->_xflags, 1, 0, __kCFHashMutable);
+    for (CFIndex idx = 0; idx < numValues; idx++) {
+#if CFDictionary
+        CFBagAddValue(hc, keys[idx], values[idx]);
+#endif
+#if CFSet || CFBag
+        CFBagAddValue(hc, keys[idx]);
+#endif
+    }
+    __CFBitfieldSetValue(hc->_xflags, 1, 0, __kCFHashImmutable);
+    return (CFHashRef)hc;
+}
+
+#if CFDictionary
+CFMutableHashRef CFBagCreateMutable(CFAllocatorRef allocator, CFIndex capacity, const CFBagKeyCallBacks *keyCallBacks, const CFBagValueCallBacks *valueCallBacks) {
+#endif
+#if CFSet || CFBag
+CFMutableHashRef CFBagCreateMutable(CFAllocatorRef allocator, CFIndex capacity, const CFBagKeyCallBacks *keyCallBacks) {
+#endif
+    CFAssert2(0 <= capacity, __kCFLogAssertion, "%s(): capacity (%ld) cannot be less than zero", __PRETTY_FUNCTION__, capacity);
+#if CFDictionary
+    CFMutableHashRef hc = __CFBagInit(allocator, __kCFHashMutable, capacity, keyCallBacks, valueCallBacks);
+#endif
+#if CFSet || CFBag
+    CFMutableHashRef hc = __CFBagInit(allocator, __kCFHashMutable, capacity, keyCallBacks);
+#endif
+    return hc;
+}
+
+#if CFDictionary || CFSet
+// does not have Add semantics for Bag; it has Set semantics ... is that best?
+static void __CFBagGrow(CFMutableHashRef hc, CFIndex numNewValues);
+
+// This creates a hc which is for CFTypes or NSObjects, with a CFRetain style ownership transfer;
+// the hc does not take a retain (since it claims 1), and the caller does not need to release the inserted objects (since we do it).
+// The incoming objects must also be collectable if allocated out of a collectable allocator - and are neither released nor retained.
+#if CFDictionary
+CFHashRef _CFBagCreate_ex(CFAllocatorRef allocator, Boolean isMutable, const_any_pointer_t *keys, const_any_pointer_t *values, CFIndex numValues) {
+#endif
+#if CFSet || CFBag
+CFHashRef _CFBagCreate_ex(CFAllocatorRef allocator, Boolean isMutable, const_any_pointer_t *keys, CFIndex numValues) {
+#endif
+    CFAssert2(0 <= numValues, __kCFLogAssertion, "%s(): numValues (%ld) cannot be less than zero", __PRETTY_FUNCTION__, numValues);
+#if CFDictionary
+    CFMutableHashRef hc = __CFBagInit(allocator, __kCFHashMutable, numValues, &kCFTypeBagKeyCallBacks, &kCFTypeBagValueCallBacks);
+#endif
+#if CFSet || CFBag
+    CFMutableHashRef hc = __CFBagInit(allocator, __kCFHashMutable, numValues, &kCFTypeBagKeyCallBacks);
+#endif
+    __CFBagGrow(hc, numValues);
+    for (CFIndex idx = 0; idx < numValues; idx++) {
+        CFIndex match, nomatch;
+        __CFBagFindBuckets2(hc, (any_t)keys[idx], &match, &nomatch);
+        if (kCFNotFound == match) {
+            CFAllocatorRef allocator = __CFGetAllocator(hc);
+            any_t newKey = (any_t)keys[idx];
+            if (__CFHashKeyIsMagic(hc, newKey)) {
+                __CFBagFindNewMarker(hc);
+            }
+            if (hc->_keys[nomatch] == ~hc->_marker) {
+                hc->_deletes--;
+            }
+            CFAllocatorRef keysAllocator = (hc->_xflags & __kCFHashWeakKeys) ? kCFAllocatorNull : allocator;
+            CF_WRITE_BARRIER_ASSIGN(keysAllocator, hc->_keys[nomatch], newKey);
+#if CFDictionary
+            any_t newValue = (any_t)values[idx];
+            CFAllocatorRef valuesAllocator = (hc->_xflags & __kCFHashWeakValues) ? kCFAllocatorNull : allocator;
+            CF_WRITE_BARRIER_ASSIGN(valuesAllocator, hc->_values[nomatch], newValue);
+#endif
+#if CFBag
+            hc->_values[nomatch] = 1;
+#endif
+            hc->_bucketsUsed++;
+            hc->_count++;
+        } else {
+            CFAllocatorRef allocator = __CFGetAllocator(hc);
+#if CFSet || CFBag
+            any_t oldKey = hc->_keys[match];
+            any_t newKey = (any_t)keys[idx];
+            CFAllocatorRef keysAllocator = (hc->_xflags & __kCFHashWeakKeys) ? kCFAllocatorNull : allocator;
+            CF_WRITE_BARRIER_ASSIGN(keysAllocator, hc->_keys[match], ~hc->_marker);
+            if (__CFHashKeyIsMagic(hc, newKey)) {
+                __CFBagFindNewMarker(hc);
+            }
+            CF_WRITE_BARRIER_ASSIGN(keysAllocator, hc->_keys[match], newKey);
+            RELEASEKEY(oldKey);
+#endif
+#if CFDictionary
+            any_t oldValue = hc->_values[match];
+            any_t newValue = (any_t)values[idx];
+            CFAllocatorRef valuesAllocator = (hc->_xflags & __kCFHashWeakValues) ? kCFAllocatorNull : allocator;
+            CF_WRITE_BARRIER_ASSIGN(valuesAllocator, hc->_values[match], newValue);
+            RELEASEVALUE(oldValue);
+#endif
+        }
+    }
+    if (!isMutable) __CFBitfieldSetValue(hc->_xflags, 1, 0, __kCFHashImmutable);
+    return (CFHashRef)hc;
+}
+#endif
+
+CFHashRef CFBagCreateCopy(CFAllocatorRef allocator, CFHashRef other) {
+    CFMutableHashRef hc = CFBagCreateMutableCopy(allocator, CFBagGetCount(other), other);
+    __CFBitfieldSetValue(hc->_xflags, 1, 0, __kCFHashImmutable);
+    if (__CFOASafe) __CFSetLastAllocationEventName(hc, "CFBag (immutable)");
+    return hc;
+}
+
+CFMutableHashRef CFBagCreateMutableCopy(CFAllocatorRef allocator, CFIndex capacity, CFHashRef other) {
+    CFIndex numValues = CFBagGetCount(other);
+    const_any_pointer_t *list, buffer[256];
+    list = (numValues <= 256) ? buffer : (const_any_pointer_t *)CFAllocatorAllocate(allocator, numValues * sizeof(const_any_pointer_t), 0);
+    if (list != buffer && __CFOASafe) __CFSetLastAllocationEventName(list, "CFBag (temp)");
+#if CFDictionary
+    const_any_pointer_t *vlist, vbuffer[256];
+    vlist = (numValues <= 256) ? vbuffer : (const_any_pointer_t *)CFAllocatorAllocate(allocator, numValues * sizeof(const_any_pointer_t), 0);
+    if (vlist != vbuffer && __CFOASafe) __CFSetLastAllocationEventName(vlist, "CFBag (temp)");
+#endif
+#if CFSet || CFBag
+    CFBagGetValues(other, list);
+#endif
+#if CFDictionary
+    CFBagGetKeysAndValues(other, list, vlist);
+#endif
+    const CFBagKeyCallBacks *kcb;
+    const CFBagValueCallBacks *vcb;
+    if (CF_IS_OBJC(__kCFHashTypeID, other)) {
+        kcb = &kCFTypeBagKeyCallBacks;
+        vcb = &kCFTypeBagValueCallBacks;
+    } else {
+        kcb = __CFBagGetKeyCallBacks(other);
+        vcb = __CFBagGetValueCallBacks(other);
+    }
+#if CFDictionary
+    CFMutableHashRef hc = __CFBagInit(allocator, __kCFHashMutable, capacity, kcb, vcb);
+#endif
+#if CFSet || CFBag
+    CFMutableHashRef hc = __CFBagInit(allocator, __kCFHashMutable, capacity, kcb);
+#endif
+    if (0 == capacity) _CFBagSetCapacity(hc, numValues);
+    for (CFIndex idx = 0; idx < numValues; idx++) {
+#if CFDictionary
+        CFBagAddValue(hc, list[idx], vlist[idx]);
+#endif
+#if CFSet || CFBag
+        CFBagAddValue(hc, list[idx]);
+#endif
+    }
+    if (list != buffer) CFAllocatorDeallocate(allocator, list);
+#if CFDictionary
+    if (vlist != vbuffer) CFAllocatorDeallocate(allocator, vlist);
+#endif
+    return hc;
+}
+
+// Used by NSHashTables/NSMapTables and KVO
+void _CFBagSetContext(CFHashRef hc, any_pointer_t context) {
+    __CFGenericValidateType(hc, __kCFHashTypeID);
+    CF_WRITE_BARRIER_BASE_ASSIGN(__CFGetAllocator(hc), hc, hc->_context, context);
+}
+
+any_pointer_t _CFBagGetContext(CFHashRef hc) {
+    __CFGenericValidateType(hc, __kCFHashTypeID);
+    return hc->_context;
+}
+
+CFIndex CFBagGetCount(CFHashRef hc) {
+    if (CFDictionary || CFSet) CF_OBJC_FUNCDISPATCH0(__kCFHashTypeID, CFIndex, hc, "count");
+    __CFGenericValidateType(hc, __kCFHashTypeID);
+    return hc->_count;
+}
+
+#if CFDictionary
+CFIndex CFBagGetCountOfKey(CFHashRef hc, const_any_pointer_t key) {
+#endif
+#if CFSet || CFBag
+CFIndex CFBagGetCountOfValue(CFHashRef hc, const_any_pointer_t key) {
+#endif
+    if (CFDictionary) CF_OBJC_FUNCDISPATCH1(__kCFHashTypeID, CFIndex, hc, "countForKey:", key);
+    if (CFSet) CF_OBJC_FUNCDISPATCH1(__kCFHashTypeID, CFIndex, hc, "countForObject:", key);
+    __CFGenericValidateType(hc, __kCFHashTypeID);
+    if (0 == hc->_bucketsUsed) return 0;
+    CFIndex match = __CFBagFindBuckets1(hc, (any_t)key);
+    return (kCFNotFound != match ? __CFHashGetOccurrenceCount(hc, match) : 0);
+}
+
+#if CFDictionary
+Boolean CFBagContainsKey(CFHashRef hc, const_any_pointer_t key) {
+#endif
+#if CFSet || CFBag
+Boolean CFBagContainsValue(CFHashRef hc, const_any_pointer_t key) {
+#endif
+    if (CFDictionary) CF_OBJC_FUNCDISPATCH1(__kCFHashTypeID, char, hc, "containsKey:", key);
+    if (CFSet) CF_OBJC_FUNCDISPATCH1(__kCFHashTypeID, char, hc, "containsObject:", key);
+    __CFGenericValidateType(hc, __kCFHashTypeID);
+    if (0 == hc->_bucketsUsed) return false;
+    CFIndex match = __CFBagFindBuckets1(hc, (any_t)key);
+    return (kCFNotFound != match ? true : false);
+}
+
+#if CFDictionary
+CFIndex CFBagGetCountOfValue(CFHashRef hc, const_any_pointer_t value) {
+    CF_OBJC_FUNCDISPATCH1(__kCFHashTypeID, CFIndex, hc, "countForObject:", value);
+    __CFGenericValidateType(hc, __kCFHashTypeID);
+    if (0 == hc->_bucketsUsed) return 0;
+    any_t *keys = hc->_keys;
+    Boolean (*equal)(any_t, any_t, any_pointer_t) = (Boolean (*)(any_t, any_t, any_pointer_t))__CFBagGetValueCallBacks(hc)->equal;
+    CFIndex cnt = 0;
+    for (CFIndex idx = 0, nbuckets = hc->_bucketsNum; idx < nbuckets; idx++) {
+        if (__CFHashKeyIsValue(hc, keys[idx])) {
+            if ((hc->_values[idx] == (any_t)value) || (equal && INVOKE_CALLBACK3(equal, hc->_values[idx], (any_t)value, hc->_context))) {
+                cnt++;
+            }
+        }
+    }
+    return cnt;
+}
+
+Boolean CFBagContainsValue(CFHashRef hc, const_any_pointer_t value) {
+    CF_OBJC_FUNCDISPATCH1(__kCFHashTypeID, char, hc, "containsObject:", value);
+    __CFGenericValidateType(hc, __kCFHashTypeID);
+    if (0 == hc->_bucketsUsed) return false;
+    any_t *keys = hc->_keys;
+    Boolean (*equal)(any_t, any_t, any_pointer_t) = (Boolean (*)(any_t, any_t, any_pointer_t))__CFBagGetValueCallBacks(hc)->equal;
+    for (CFIndex idx = 0, nbuckets = hc->_bucketsNum; idx < nbuckets; idx++) {
+        if (__CFHashKeyIsValue(hc, keys[idx])) {
+            if ((hc->_values[idx] == (any_t)value) || (equal && INVOKE_CALLBACK3(equal, hc->_values[idx], (any_t)value, hc->_context))) {
+                return true;
+            }
+        }
+    }
+    return false;
+}
+#endif
+
+const_any_pointer_t CFBagGetValue(CFHashRef hc, const_any_pointer_t key) {
+    if (CFDictionary) CF_OBJC_FUNCDISPATCH1(__kCFHashTypeID, const_any_pointer_t, hc, "objectForKey:", key);
+    if (CFSet) CF_OBJC_FUNCDISPATCH1(__kCFHashTypeID, const_any_pointer_t, hc, "member:", key);
+    __CFGenericValidateType(hc, __kCFHashTypeID);
+    if (0 == hc->_bucketsUsed) return 0;
+    CFIndex match = __CFBagFindBuckets1(hc, (any_t)key);
+    return (kCFNotFound != match ? (const_any_pointer_t)(CFDictionary ? hc->_values[match] : hc->_keys[match]) : 0);
+}
+
+Boolean CFBagGetValueIfPresent(CFHashRef hc, const_any_pointer_t key, const_any_pointer_t *value) {
+    if (CFDictionary) CF_OBJC_FUNCDISPATCH2(__kCFHashTypeID, Boolean, hc, "_getValue:forKey:", (any_t *)value, key);
+    if (CFSet) CF_OBJC_FUNCDISPATCH2(__kCFHashTypeID, Boolean, hc, "_getValue:forObj:", (any_t *)value, key);
+    __CFGenericValidateType(hc, __kCFHashTypeID);
+    if (0 == hc->_bucketsUsed) return false;
+    CFIndex match = __CFBagFindBuckets1(hc, (any_t)key);
+    return (kCFNotFound != match ? ((value ? __CFObjCStrongAssign((const_any_pointer_t)(CFDictionary ? hc->_values[match] : hc->_keys[match]), value) : 0), true) : false);
+}
+
+#if CFDictionary
+Boolean CFBagGetKeyIfPresent(CFHashRef hc, const_any_pointer_t key, const_any_pointer_t *actualkey) {
+    CF_OBJC_FUNCDISPATCH2(__kCFHashTypeID, Boolean, hc, "getActualKey:forKey:", actualkey, key);
+    __CFGenericValidateType(hc, __kCFHashTypeID);
+    if (0 == hc->_bucketsUsed) return false;
+    CFIndex match = __CFBagFindBuckets1(hc, (any_t)key);
+    return (kCFNotFound != match ? ((actualkey ? __CFObjCStrongAssign((const_any_pointer_t)hc->_keys[match], actualkey) : NULL), true) : false);
+}
+#endif
+
+#if CFDictionary
+void CFBagGetKeysAndValues(CFHashRef hc, const_any_pointer_t *keybuf, const_any_pointer_t *valuebuf) {
+#endif
+#if CFSet || CFBag
+void CFBagGetValues(CFHashRef hc, const_any_pointer_t *keybuf) {
+    const_any_pointer_t *valuebuf = 0;
+#endif
+    if (CFDictionary) CF_OBJC_FUNCDISPATCH2(__kCFHashTypeID, void, hc, "getObjects:andKeys:", (any_t *)valuebuf, (any_t *)keybuf);
+    if (CFSet) CF_OBJC_FUNCDISPATCH1(__kCFHashTypeID, void, hc, "getObjects:", (any_t *)keybuf);
+    __CFGenericValidateType(hc, __kCFHashTypeID);
+    if (CF_USING_COLLECTABLE_MEMORY) {
+        // GC: speculatively issue a write-barrier on the copied to buffers
+        __CFObjCWriteBarrierRange(keybuf, hc->_count * sizeof(any_t));
+        __CFObjCWriteBarrierRange(valuebuf, hc->_count * sizeof(any_t));
+    }
+    any_t *keys = hc->_keys;
+    for (CFIndex idx = 0, nbuckets = hc->_bucketsNum; idx < nbuckets; idx++) {
+        if (__CFHashKeyIsValue(hc, keys[idx])) {
+            for (CFIndex cnt = __CFHashGetOccurrenceCount(hc, idx); cnt--;) {
+                if (keybuf) *keybuf++ = (const_any_pointer_t)keys[idx];
+                if (valuebuf) *valuebuf++ = (const_any_pointer_t)hc->_values[idx];
+            }
+        }
+    }
+}
+
+#if CFDictionary || CFSet
+unsigned long _CFBagFastEnumeration(CFHashRef hc, struct __objcFastEnumerationStateEquivalent *state, void *stackbuffer, unsigned long count) {
+    /* copy as many as count items over */
+    if (0 == state->state) {        /* first time */
+        state->mutationsPtr = (unsigned long *)&hc->_mutations;
+    }
+    state->itemsPtr = (unsigned long *)stackbuffer;
+    CFIndex cnt = 0;
+    any_t *keys = hc->_keys;
+    for (CFIndex idx = (CFIndex)state->state, nbuckets = hc->_bucketsNum; idx < nbuckets && cnt < (CFIndex)count; idx++) {
+        if (__CFHashKeyIsValue(hc, keys[idx])) {
+            state->itemsPtr[cnt++] = (unsigned long)keys[idx];
+        }
+        state->state++;
+    }
+    return cnt;
+}
+#endif
+
+void CFBagApplyFunction(CFHashRef hc, CFBagApplierFunction applier, any_pointer_t context) {
+    FAULT_CALLBACK((void **)&(applier));
+    if (CFDictionary) CF_OBJC_FUNCDISPATCH2(__kCFHashTypeID, void, hc, "_apply:context:", applier, context);
+    if (CFSet) CF_OBJC_FUNCDISPATCH2(__kCFHashTypeID, void, hc, "_applyValues:context:", applier, context);
+    __CFGenericValidateType(hc, __kCFHashTypeID);
+    any_t *keys = hc->_keys;
+    for (CFIndex idx = 0, nbuckets = hc->_bucketsNum; idx < nbuckets; idx++) {
+        if (__CFHashKeyIsValue(hc, keys[idx])) {
+            for (CFIndex cnt = __CFHashGetOccurrenceCount(hc, idx); cnt--;) {
+#if CFDictionary
+                INVOKE_CALLBACK3(applier, (const_any_pointer_t)keys[idx], (const_any_pointer_t)hc->_values[idx], context);
+#endif
+#if CFSet || CFBag
+                INVOKE_CALLBACK2(applier, (const_any_pointer_t)keys[idx], context);
+#endif
+            }
+        }
+    }
+}
+
+static void __CFBagGrow(CFMutableHashRef hc, CFIndex numNewValues) {
+    any_t *oldkeys = hc->_keys;
+    any_t *oldvalues = hc->_values;
+    CFIndex nbuckets = hc->_bucketsNum;
+    hc->_bucketsCap = __CFHashRoundUpCapacity(hc->_bucketsUsed + numNewValues);
+    hc->_bucketsNum = __CFHashNumBucketsForCapacity(hc->_bucketsCap);
+    hc->_deletes = 0;
+    CFAllocatorRef allocator = __CFGetAllocator(hc);
+    CFOptionFlags weakOrStrong = (hc->_xflags & __kCFHashWeakKeys) ? 0 : __kCFAllocatorGCScannedMemory;
+    any_t *mem = (any_t *)_CFAllocatorAllocateGC(allocator, hc->_bucketsNum * sizeof(any_t), weakOrStrong);
+    if (NULL == mem) __CFBagHandleOutOfMemory(hc, hc->_bucketsNum * sizeof(any_t));
+    if (__CFOASafe) __CFSetLastAllocationEventName(mem, "CFBag (key-store)");
+    CF_WRITE_BARRIER_BASE_ASSIGN(allocator, hc, hc->_keys, mem);
+    CFAllocatorRef keysAllocator = (hc->_xflags & __kCFHashWeakKeys) ? kCFAllocatorNull : allocator;  // GC: avoids write-barrier in weak case.
+    any_t *keysBase = mem;
+#if CFDictionary || CFBag
+    weakOrStrong = (hc->_xflags & __kCFHashWeakValues) ? 0 : __kCFAllocatorGCScannedMemory;
+    mem = (any_t *)_CFAllocatorAllocateGC(allocator, hc->_bucketsNum * sizeof(any_t), weakOrStrong);
+    if (NULL == mem) __CFBagHandleOutOfMemory(hc, hc->_bucketsNum * sizeof(any_t));
+    if (__CFOASafe) __CFSetLastAllocationEventName(mem, "CFBag (value-store)");
+    CF_WRITE_BARRIER_BASE_ASSIGN(allocator, hc, hc->_values, mem);
+#endif
+#if CFDictionary
+    CFAllocatorRef valuesAllocator = (hc->_xflags & __kCFHashWeakValues) ? kCFAllocatorNull : allocator; // GC: avoids write-barrier in weak case.
+    any_t *valuesBase = mem;
+#endif
+    for (CFIndex idx = 0, nbuckets = hc->_bucketsNum; idx < nbuckets; idx++) {
+        hc->_keys[idx] = hc->_marker;
+#if CFDictionary || CFBag
+        hc->_values[idx] = 0;
+#endif
+    }
+    if (NULL == oldkeys) return;
+    for (CFIndex idx = 0; idx < nbuckets; idx++) {
+        if (__CFHashKeyIsValue(hc, oldkeys[idx])) {
+            CFIndex match, nomatch;
+            __CFBagFindBuckets2(hc, oldkeys[idx], &match, &nomatch);
+            CFAssert3(kCFNotFound == match, __kCFLogAssertion, "%s(): two values (%p, %p) now hash to the same slot; mutable value changed while in table or hash value is not immutable", __PRETTY_FUNCTION__, oldkeys[idx], hc->_keys[match]);
+            if (kCFNotFound != nomatch) {
+                CF_WRITE_BARRIER_BASE_ASSIGN(keysAllocator, keysBase, hc->_keys[nomatch], oldkeys[idx]);
+#if CFDictionary
+                CF_WRITE_BARRIER_BASE_ASSIGN(valuesAllocator, valuesBase, hc->_values[nomatch], oldvalues[idx]);
+#endif
+#if CFBag
+                hc->_values[nomatch] = oldvalues[idx];
+#endif
+            }
+        }
+    }
+    _CFAllocatorDeallocateGC(allocator, oldkeys);
+    _CFAllocatorDeallocateGC(allocator, oldvalues);
+}
+
+// This function is for Foundation's benefit; no one else should use it.
+void _CFBagSetCapacity(CFMutableHashRef hc, CFIndex cap) {
+    if (CF_IS_OBJC(__kCFHashTypeID, hc)) return;
+    __CFGenericValidateType(hc, __kCFHashTypeID);
+    CFAssert1(__CFHashGetType(hc) != __kCFHashImmutable, __kCFLogAssertion, "%s(): collection is immutable", __PRETTY_FUNCTION__);
+    CFAssert3(hc->_bucketsUsed <= cap, __kCFLogAssertion, "%s(): desired capacity (%ld) is less than bucket count (%ld)", __PRETTY_FUNCTION__, cap, hc->_bucketsUsed);
+    __CFBagGrow(hc, cap - hc->_bucketsUsed);
+}
+
+
+#if CFDictionary
+void CFBagAddValue(CFMutableHashRef hc, const_any_pointer_t key, const_any_pointer_t value) {
+#endif
+#if CFSet || CFBag
+void CFBagAddValue(CFMutableHashRef hc, const_any_pointer_t key) {
+    #define value 0
+#endif
+    if (CFDictionary) CF_OBJC_FUNCDISPATCH2(__kCFHashTypeID, void, hc, "_addObject:forKey:", value, key);
+    if (CFSet) CF_OBJC_FUNCDISPATCH1(__kCFHashTypeID, void, hc, "addObject:", key);
+    __CFGenericValidateType(hc, __kCFHashTypeID);
+    switch (__CFHashGetType(hc)) {
+    case __kCFHashMutable:
+        if (hc->_bucketsUsed == hc->_bucketsCap || NULL == hc->_keys) {
+            __CFBagGrow(hc, 1);
+        }
+        break;
+    default:
+        CFAssert2(__CFHashGetType(hc) != __kCFHashImmutable, __kCFLogAssertion, "%s(): immutable collection %p passed to mutating operation", __PRETTY_FUNCTION__, hc);
+        break;
+    }
+    hc->_mutations++;
+    CFIndex match, nomatch;
+    __CFBagFindBuckets2(hc, (any_t)key, &match, &nomatch);
+    if (kCFNotFound != match) {
+#if CFBag
+        CF_OBJC_KVO_WILLCHANGE(hc, hc->_keys[match]);
+        hc->_values[match]++;
+        hc->_count++;
+        CF_OBJC_KVO_DIDCHANGE(hc, hc->_keys[match]);
+#endif
+    } else {
+        CFAllocatorRef allocator = __CFGetAllocator(hc);
+        GETNEWKEY(newKey, key);
+#if CFDictionary
+        GETNEWVALUE(newValue);
+#endif
+        if (__CFHashKeyIsMagic(hc, newKey)) {
+            __CFBagFindNewMarker(hc);
+        }
+        if (hc->_keys[nomatch] == ~hc->_marker) {
+            hc->_deletes--;
+        }
+        CF_OBJC_KVO_WILLCHANGE(hc, key);
+        CFAllocatorRef keysAllocator = (hc->_xflags & __kCFHashWeakKeys) ? kCFAllocatorNull : allocator;
+        CF_WRITE_BARRIER_ASSIGN(keysAllocator, hc->_keys[nomatch], newKey);
+#if CFDictionary
+        CFAllocatorRef valuesAllocator = (hc->_xflags & __kCFHashWeakValues) ? kCFAllocatorNull : allocator;
+        CF_WRITE_BARRIER_ASSIGN(valuesAllocator, hc->_values[nomatch], newValue);
+#endif
+#if CFBag
+        hc->_values[nomatch] = 1;
+#endif
+        hc->_bucketsUsed++;
+        hc->_count++;
+        CF_OBJC_KVO_DIDCHANGE(hc, key);
+    }
+}
+
+#if CFDictionary
+void CFBagReplaceValue(CFMutableHashRef hc, const_any_pointer_t key, const_any_pointer_t value) {
+#endif
+#if CFSet || CFBag
+void CFBagReplaceValue(CFMutableHashRef hc, const_any_pointer_t key) {
+    #define value 0
+#endif
+    if (CFDictionary) CF_OBJC_FUNCDISPATCH2(__kCFHashTypeID, void, hc, "_replaceObject:forKey:", value, key);
+    if (CFSet) CF_OBJC_FUNCDISPATCH1(__kCFHashTypeID, void, hc, "_replaceObject:", key);
+    __CFGenericValidateType(hc, __kCFHashTypeID);
+    switch (__CFHashGetType(hc)) {
+    case __kCFHashMutable:
+        break;
+    default:
+        CFAssert2(__CFHashGetType(hc) != __kCFHashImmutable, __kCFLogAssertion, "%s(): immutable collection %p passed to mutating operation", __PRETTY_FUNCTION__, hc);
+        break;
+    }
+    hc->_mutations++;
+    if (0 == hc->_bucketsUsed) return;
+    CFIndex match = __CFBagFindBuckets1(hc, (any_t)key);
+    if (kCFNotFound == match) return;
+    CFAllocatorRef allocator = __CFGetAllocator(hc);
+#if CFSet || CFBag
+    GETNEWKEY(newKey, key);
+#endif
+#if CFDictionary
+    GETNEWVALUE(newValue);
+#endif
+    any_t oldKey = hc->_keys[match];
+    CF_OBJC_KVO_WILLCHANGE(hc, oldKey);
+#if CFSet || CFBag
+    CFAllocatorRef keysAllocator = (hc->_xflags & __kCFHashWeakKeys) ? kCFAllocatorNull : allocator;
+    CF_WRITE_BARRIER_ASSIGN(keysAllocator, hc->_keys[match], ~hc->_marker);
+    if (__CFHashKeyIsMagic(hc, newKey)) {
+        __CFBagFindNewMarker(hc);
+    }
+    CF_WRITE_BARRIER_ASSIGN(keysAllocator, hc->_keys[match], newKey);
+#endif
+#if CFDictionary
+    any_t oldValue = hc->_values[match];
+    CFAllocatorRef valuesAllocator = (hc->_xflags & __kCFHashWeakValues) ? kCFAllocatorNull : allocator;
+    CF_WRITE_BARRIER_ASSIGN(valuesAllocator, hc->_values[match], newValue);
+#endif
+    CF_OBJC_KVO_DIDCHANGE(hc, oldKey);
+#if CFSet || CFBag
+    RELEASEKEY(oldKey);
+#endif
+#if CFDictionary
+    RELEASEVALUE(oldValue);
+#endif
+}
+
+#if CFDictionary
+void CFBagSetValue(CFMutableHashRef hc, const_any_pointer_t key, const_any_pointer_t value) {
+#endif
+#if CFSet || CFBag
+void CFBagSetValue(CFMutableHashRef hc, const_any_pointer_t key) {
+    #define value 0
+#endif
+    if (CFDictionary) CF_OBJC_FUNCDISPATCH2(__kCFHashTypeID, void, hc, "setObject:forKey:", value, key);
+    if (CFSet) CF_OBJC_FUNCDISPATCH1(__kCFHashTypeID, void, hc, "_setObject:", key);
+    __CFGenericValidateType(hc, __kCFHashTypeID);
+    switch (__CFHashGetType(hc)) {
+    case __kCFHashMutable:
+        if (hc->_bucketsUsed == hc->_bucketsCap || NULL == hc->_keys) {
+            __CFBagGrow(hc, 1);
+        }
+        break;
+    default:
+        CFAssert2(__CFHashGetType(hc) != __kCFHashImmutable, __kCFLogAssertion, "%s(): immutable collection %p passed to mutating operation", __PRETTY_FUNCTION__, hc);
+        break;
+    }
+    hc->_mutations++;
+    CFIndex match, nomatch;
+    __CFBagFindBuckets2(hc, (any_t)key, &match, &nomatch);
+    if (kCFNotFound == match) {
+        CFAllocatorRef allocator = __CFGetAllocator(hc);
+        GETNEWKEY(newKey, key);
+#if CFDictionary
+        GETNEWVALUE(newValue);
+#endif
+        if (__CFHashKeyIsMagic(hc, newKey)) {
+            __CFBagFindNewMarker(hc);
+        }
+        if (hc->_keys[nomatch] == ~hc->_marker) {
+            hc->_deletes--;
+        }
+        CF_OBJC_KVO_WILLCHANGE(hc, key);
+        CFAllocatorRef keysAllocator = (hc->_xflags & __kCFHashWeakKeys) ? kCFAllocatorNull : allocator;
+        CF_WRITE_BARRIER_ASSIGN(keysAllocator, hc->_keys[nomatch], newKey);
+#if CFDictionary
+        CFAllocatorRef valuesAllocator = (hc->_xflags & __kCFHashWeakValues) ? kCFAllocatorNull : allocator;
+        CF_WRITE_BARRIER_ASSIGN(valuesAllocator, hc->_values[nomatch], newValue);
+#endif
+#if CFBag
+        hc->_values[nomatch] = 1;
+#endif
+        hc->_bucketsUsed++;
+        hc->_count++;
+        CF_OBJC_KVO_DIDCHANGE(hc, key);
+    } else {
+        CFAllocatorRef allocator = __CFGetAllocator(hc);
+#if CFSet || CFBag
+        GETNEWKEY(newKey, key);
+#endif
+#if CFDictionary
+        GETNEWVALUE(newValue);
+#endif
+        any_t oldKey = hc->_keys[match];
+        CF_OBJC_KVO_WILLCHANGE(hc, oldKey);
+#if CFSet || CFBag
+        CFAllocatorRef keysAllocator = (hc->_xflags & __kCFHashWeakKeys) ? kCFAllocatorNull : allocator;
+        CF_WRITE_BARRIER_ASSIGN(keysAllocator, hc->_keys[match], ~hc->_marker);
+        if (__CFHashKeyIsMagic(hc, newKey)) {
+            __CFBagFindNewMarker(hc);
+        }
+        CF_WRITE_BARRIER_ASSIGN(keysAllocator, hc->_keys[match], newKey);
+#endif
+#if CFDictionary
+        any_t oldValue = hc->_values[match];
+        CFAllocatorRef valuesAllocator = (hc->_xflags & __kCFHashWeakValues) ? kCFAllocatorNull : allocator;
+        CF_WRITE_BARRIER_ASSIGN(valuesAllocator, hc->_values[match], newValue);
+#endif
+        CF_OBJC_KVO_DIDCHANGE(hc, oldKey);
+#if CFSet || CFBag
+        RELEASEKEY(oldKey);
+#endif
+#if CFDictionary
+        RELEASEVALUE(oldValue);
+#endif
+    }
+}
+
+void CFBagRemoveValue(CFMutableHashRef hc, const_any_pointer_t key) {
+    if (CFDictionary) CF_OBJC_FUNCDISPATCH1(__kCFHashTypeID, void, hc, "removeObjectForKey:", key);
+    if (CFSet) CF_OBJC_FUNCDISPATCH1(__kCFHashTypeID, void, hc, "removeObject:", key);
+    __CFGenericValidateType(hc, __kCFHashTypeID);
+    switch (__CFHashGetType(hc)) {
+    case __kCFHashMutable:
+        break;
+    default:
+        CFAssert2(__CFHashGetType(hc) != __kCFHashImmutable, __kCFLogAssertion, "%s(): immutable collection %p passed to mutating operation", __PRETTY_FUNCTION__, hc);
+        break;
+    }
+    hc->_mutations++;
+    if (0 == hc->_bucketsUsed) return;
+    CFIndex match = __CFBagFindBuckets1(hc, (any_t)key);
+    if (kCFNotFound == match) return;
+    if (1 < __CFHashGetOccurrenceCount(hc, match)) {
+#if CFBag
+        CF_OBJC_KVO_WILLCHANGE(hc, hc->_keys[match]);
+        hc->_values[match]--;
+        hc->_count--;
+        CF_OBJC_KVO_DIDCHANGE(hc, hc->_keys[match]);
+#endif
+    } else {
+        CFAllocatorRef allocator = __CFGetAllocator(hc);
+        any_t oldKey = hc->_keys[match];
+        CF_OBJC_KVO_WILLCHANGE(hc, oldKey);
+        CFAllocatorRef keysAllocator = (hc->_xflags & __kCFHashWeakKeys) ? kCFAllocatorNull : allocator;
+        CF_WRITE_BARRIER_ASSIGN(keysAllocator, hc->_keys[match], ~hc->_marker);
+#if CFDictionary
+        any_t oldValue = hc->_values[match];
+        CFAllocatorRef valuesAllocator = (hc->_xflags & __kCFHashWeakValues) ? kCFAllocatorNull : allocator;
+        CF_WRITE_BARRIER_ASSIGN(valuesAllocator, hc->_values[match], 0);
+#endif
+#if CFBag
+        hc->_values[match] = 0;
+#endif
+        hc->_count--;
+        hc->_bucketsUsed--;
+        hc->_deletes++;
+        CF_OBJC_KVO_DIDCHANGE(hc, oldKey);
+        RELEASEKEY(oldKey);
+#if CFDictionary
+        RELEASEVALUE(oldValue);
+#endif
+        if (__CFBagShouldShrink(hc)) {
+            __CFBagGrow(hc, 0);
+        } else {
+            // When the probeskip == 1 always and only, a DELETED slot followed by an EMPTY slot
+            // can be converted to an EMPTY slot.  By extension, a chain of DELETED slots followed
+            // by an EMPTY slot can be converted to EMPTY slots, which is what we do here.
+            if (match < hc->_bucketsNum - 1 && hc->_keys[match + 1] == hc->_marker) {
+                while (0 <= match && hc->_keys[match] == ~hc->_marker) {
+                    hc->_keys[match] = hc->_marker;
+                    hc->_deletes--;
+                    match--;
+                }
+            }
+        }
+    }
+}
+
+void CFBagRemoveAllValues(CFMutableHashRef hc) {
+    if (CFDictionary) CF_OBJC_FUNCDISPATCH0(__kCFHashTypeID, void, hc, "removeAllObjects");
+    if (CFSet) CF_OBJC_FUNCDISPATCH0(__kCFHashTypeID, void, hc, "removeAllObjects");
+    __CFGenericValidateType(hc, __kCFHashTypeID);
+    switch (__CFHashGetType(hc)) {
+    case __kCFHashMutable:
+        break;
+    default:
+        CFAssert2(__CFHashGetType(hc) != __kCFHashImmutable, __kCFLogAssertion, "%s(): immutable collection %p passed to mutating operation", __PRETTY_FUNCTION__, hc);
+        break;
+    }
+    hc->_mutations++;
+    if (0 == hc->_bucketsUsed) return;
+    CFAllocatorRef allocator = __CFGetAllocator(hc);
+    any_t *keys = hc->_keys;
+    for (CFIndex idx = 0, nbuckets = hc->_bucketsNum; idx < nbuckets; idx++) {
+        if (__CFHashKeyIsValue(hc, keys[idx])) {
+            any_t oldKey = keys[idx];
+            CF_OBJC_KVO_WILLCHANGE(hc, oldKey);
+#if CFDictionary || CFSet
+            hc->_count--;
+#endif
+#if CFBag
+            hc->_count -= (CFIndex)hc->_values[idx];
+#endif
+            CFAllocatorRef keysAllocator = (hc->_xflags & __kCFHashWeakKeys) ? kCFAllocatorNull : allocator;
+            CF_WRITE_BARRIER_ASSIGN(keysAllocator, hc->_keys[idx], ~hc->_marker);
+#if CFDictionary
+            any_t oldValue = hc->_values[idx];
+            CFAllocatorRef valuesAllocator = (hc->_xflags & __kCFHashWeakValues) ? kCFAllocatorNull : allocator;
+            CF_WRITE_BARRIER_ASSIGN(valuesAllocator, hc->_values[idx], 0);
+#endif
+#if CFBag
+            hc->_values[idx] = 0;
+#endif
+            hc->_bucketsUsed--;
+            hc->_deletes++;
+            CF_OBJC_KVO_DIDCHANGE(hc, oldKey);
+            RELEASEKEY(oldKey);
+#if CFDictionary
+            RELEASEVALUE(oldValue);
+#endif
+        }
+    }
+    for (CFIndex idx = 0, nbuckets = hc->_bucketsNum; idx < nbuckets; idx++) {
+        keys[idx] = hc->_marker;
+    }
+    hc->_deletes = 0;
+    hc->_bucketsUsed = 0;
+    hc->_count = 0;
+    if (__CFBagShouldShrink(hc) && (256 <= hc->_bucketsCap)) {
+        __CFBagGrow(hc, 128);
+    }
+}
+
+#undef CF_OBJC_KVO_WILLCHANGE
+#undef CF_OBJC_KVO_DIDCHANGE
+
diff --git a/CoreFoundation/CFBag.h b/CoreFoundation/CFBag.h
new file mode 100644
index 0000000..e23cf84
--- /dev/null
+++ b/CoreFoundation/CFBag.h
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2008-2009 Brent Fulgham <bfulgham@gmail.org>.  All rights reserved.
+ *
+ * This source code is a modified version of the CoreFoundation sources released by Apple Inc. under
+ * the terms of the APSL version 2.0 (see below).
+ *
+ * For information about changes from the original Apple source release can be found by reviewing the
+ * source control system for the project at https://sourceforge.net/svn/?group_id=246198.
+ *
+ * The original license information is as follows:
+ * 
+ * Copyright (c) 2008 Apple Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*	CFBag.h
+	Copyright (c) 1998-2007, Apple Inc. All rights reserved.
+*/
+
+#if !defined(__COREFOUNDATION_CFBAG__)
+#define __COREFOUNDATION_CFBAG__ 1
+
+#include <CoreFoundation/CFBase.h>
+
+CF_EXTERN_C_BEGIN
+
+typedef const void *	(*CFBagRetainCallBack)(CFAllocatorRef allocator, const void *value);
+typedef void		(*CFBagReleaseCallBack)(CFAllocatorRef allocator, const void *value);
+typedef CFStringRef	(*CFBagCopyDescriptionCallBack)(const void *value);
+typedef Boolean		(*CFBagEqualCallBack)(const void *value1, const void *value2);
+typedef CFHashCode	(*CFBagHashCallBack)(const void *value);
+typedef struct {
+    CFIndex				version;
+    CFBagRetainCallBack			retain;
+    CFBagReleaseCallBack		release;
+    CFBagCopyDescriptionCallBack	copyDescription;
+    CFBagEqualCallBack			equal;
+    CFBagHashCallBack			hash;
+} CFBagCallBacks;
+
+CF_EXPORT
+const CFBagCallBacks kCFTypeBagCallBacks;
+CF_EXPORT
+const CFBagCallBacks kCFCopyStringBagCallBacks;
+
+typedef void (*CFBagApplierFunction)(const void *value, void *context);
+
+typedef const struct __CFBag * CFBagRef;
+typedef struct __CFBag * CFMutableBagRef;
+
+CF_EXPORT
+CFTypeID CFBagGetTypeID(void);
+
+CF_EXPORT
+CFBagRef CFBagCreate(CFAllocatorRef allocator, const void **values, CFIndex numValues, const CFBagCallBacks *callBacks);
+
+CF_EXPORT
+CFBagRef CFBagCreateCopy(CFAllocatorRef allocator, CFBagRef theBag);
+
+CF_EXPORT
+CFMutableBagRef CFBagCreateMutable(CFAllocatorRef allocator, CFIndex capacity, const CFBagCallBacks *callBacks);
+
+CF_EXPORT
+CFMutableBagRef CFBagCreateMutableCopy(CFAllocatorRef allocator, CFIndex capacity, CFBagRef theBag);
+
+CF_EXPORT
+CFIndex CFBagGetCount(CFBagRef theBag);
+
+CF_EXPORT
+CFIndex CFBagGetCountOfValue(CFBagRef theBag, const void *value);
+
+CF_EXPORT
+Boolean CFBagContainsValue(CFBagRef theBag, const void *value);
+
+CF_EXPORT
+const void *CFBagGetValue(CFBagRef theBag, const void *value);
+
+CF_EXPORT
+Boolean CFBagGetValueIfPresent(CFBagRef theBag, const void *candidate, const void **value);
+
+CF_EXPORT
+void CFBagGetValues(CFBagRef theBag, const void **values);
+
+CF_EXPORT
+void CFBagApplyFunction(CFBagRef theBag, CFBagApplierFunction applier, void *context);
+
+CF_EXPORT
+void CFBagAddValue(CFMutableBagRef theBag, const void *value);
+
+CF_EXPORT
+void CFBagReplaceValue(CFMutableBagRef theBag, const void *value);
+
+CF_EXPORT
+void CFBagSetValue(CFMutableBagRef theBag, const void *value);
+
+CF_EXPORT
+void CFBagRemoveValue(CFMutableBagRef theBag, const void *value);
+
+CF_EXPORT
+void CFBagRemoveAllValues(CFMutableBagRef theBag);
+
+CF_EXTERN_C_END
+
+#endif /* ! __COREFOUNDATION_CFBAG__ */
+
diff --git a/CoreFoundation/CFBase.c b/CoreFoundation/CFBase.c
new file mode 100644
index 0000000..fcf42f6
--- /dev/null
+++ b/CoreFoundation/CFBase.c
@@ -0,0 +1,1110 @@
+/*
+ * Copyright (c) 2008-2009 Brent Fulgham <bfulgham@gmail.org>.  All rights reserved.
+ * Copyright (c) 2009 Grant Erickson <gerickson@nuovations.com>. All rights reserved.
+ *
+ * This source code is a modified version of the CoreFoundation sources released by Apple Inc. under
+ * the terms of the APSL version 2.0 (see below).
+ *
+ * For information about changes from the original Apple source release can be found by reviewing the
+ * source control system for the project at https://sourceforge.net/svn/?group_id=246198.
+ *
+ * The original license information is as follows:
+ * 
+ * Copyright (c) 2008 Apple Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*	CFBase.c
+	Copyright 1998-2002, Apple, Inc. All rights reserved.
+	Responsibility: Christopher Kane
+*/
+
+#include <CoreFoundation/CFBase.h>
+#include "CFInternal.h"
+#if DEPLOYMENT_TARGET_MACOSX
+#include <pthread.h>
+#include <malloc/malloc.h>
+#include <mach/mach.h>
+#include <dlfcn.h>
+#elif DEPLOYMENT_TARGET_LINUX
+#if defined(DEBUG)
+#include <mcheck.h>
+#endif
+#include <pthread.h>
+#elif DEPLOYMENT_TARGET_WINDOWS
+#include <windows.h>
+#endif
+#include <stdlib.h>
+#include <string.h>
+
+extern size_t malloc_good_size(size_t size);
+
+#if defined(__CYGWIN32__) || defined (D__CYGWIN_)
+#error CoreFoundation is currently built with the Microsoft C Runtime, which is incompatible with the Cygwin DLL.  You must either use the -mno-cygwin flag, or complete a port of CF to the Cygwin environment.
+#endif
+
+// -------- -------- -------- -------- -------- -------- -------- --------
+
+// CFAllocator structure must match struct _malloc_zone_t!
+// The first two reserved fields in struct _malloc_zone_t are for us with CFRuntimeBase
+struct __CFAllocator {
+    CFRuntimeBase _base;
+#if DEPLOYMENT_TARGET_MACOSX
+    size_t (*size)(struct _malloc_zone_t *zone, const void *ptr); /* returns the size of a block or 0 if not in this zone; must be fast, especially for negative answers */
+    void *(*malloc)(struct _malloc_zone_t *zone, size_t size);
+    void *(*calloc)(struct _malloc_zone_t *zone, size_t num_items, size_t size); /* same as malloc, but block returned is set to zero */
+    void *(*valloc)(struct _malloc_zone_t *zone, size_t size); /* same as malloc, but block returned is set to zero and is guaranteed to be page aligned */
+    void (*free)(struct _malloc_zone_t *zone, void *ptr);
+    void *(*realloc)(struct _malloc_zone_t *zone, void *ptr, size_t size);
+    void (*destroy)(struct _malloc_zone_t *zone); /* zone is destroyed and all memory reclaimed */
+    const char	*zone_name;
+    unsigned (*batch_malloc)(struct _malloc_zone_t *zone, size_t size, void **results, unsigned num_requested); /* given a size, returns pointers capable of holding that size; returns the number of pointers allocated (maybe 0 or less than num_requested) */
+    void (*batch_free)(struct _malloc_zone_t *zone, void **to_be_freed, unsigned num_to_be_freed); /* frees all the pointers in to_be_freed; note that to_be_freed may be overwritten during the process */
+    struct malloc_introspection_t	*introspect;
+    void	*reserved5;
+#endif
+    CFAllocatorRef _allocator;
+    CFAllocatorContext _context;
+};
+
+CF_INLINE CFAllocatorRetainCallBack __CFAllocatorGetRetainFunction(const CFAllocatorContext *context) {
+    CFAllocatorRetainCallBack retval = NULL;
+	retval = context->retain;
+    return retval;
+}
+
+CF_INLINE CFAllocatorReleaseCallBack __CFAllocatorGetReleaseFunction(const CFAllocatorContext *context) {
+    CFAllocatorReleaseCallBack retval = NULL;
+	retval = context->release;
+    return retval;
+}
+
+CF_INLINE CFAllocatorCopyDescriptionCallBack __CFAllocatorGetCopyDescriptionFunction(const CFAllocatorContext *context) {
+    CFAllocatorCopyDescriptionCallBack retval = NULL;
+	retval = context->copyDescription;
+    return retval;
+}
+
+CF_INLINE CFAllocatorAllocateCallBack __CFAllocatorGetAllocateFunction(const CFAllocatorContext *context) {
+    CFAllocatorAllocateCallBack retval = NULL;
+	retval = context->allocate;
+    return retval;
+}
+
+CF_INLINE CFAllocatorReallocateCallBack __CFAllocatorGetReallocateFunction(const CFAllocatorContext *context) {
+    CFAllocatorReallocateCallBack retval = NULL;
+	retval = context->reallocate;
+    return retval;
+}
+
+CF_INLINE CFAllocatorDeallocateCallBack __CFAllocatorGetDeallocateFunction(const CFAllocatorContext *context) {
+    CFAllocatorDeallocateCallBack retval = NULL;
+	retval = context->deallocate;
+    return retval;
+}
+
+CF_INLINE CFAllocatorPreferredSizeCallBack __CFAllocatorGetPreferredSizeFunction(const CFAllocatorContext *context) {
+    CFAllocatorPreferredSizeCallBack retval = NULL;
+	retval = context->preferredSize;
+    return retval;
+}
+
+#if DEPLOYMENT_TARGET_MACOSX
+
+__private_extern__ void __CFAllocatorDeallocate(CFTypeRef cf);
+
+static kern_return_t __CFAllocatorZoneIntrospectNoOp(void) {
+    return 0;
+}
+
+static boolean_t __CFAllocatorZoneIntrospectTrue(void) {
+    return 1;
+}
+
+static size_t __CFAllocatorCustomSize(malloc_zone_t *zone, const void *ptr) {
+    return 0;
+
+    // The only way to implement this with a version 0 allocator would be
+    // for CFAllocator to keep track of all blocks allocated itself, which
+    // could be done, but would be bad for performance, so we don't do it.
+    //    size_t (*size)(struct _malloc_zone_t *zone, const void *ptr);
+    /* returns the size of a block or 0 if not in this zone;
+     * must be fast, especially for negative answers */
+}
+
+static void *__CFAllocatorCustomMalloc(malloc_zone_t *zone, size_t size) {
+    CFAllocatorRef allocator = (CFAllocatorRef)zone;
+    return CFAllocatorAllocate(allocator, size, 0);
+}
+
+static void *__CFAllocatorCustomCalloc(malloc_zone_t *zone, size_t num_items, size_t size) {
+    CFAllocatorRef allocator = (CFAllocatorRef)zone;
+    void *newptr = CFAllocatorAllocate(allocator, size, 0);
+    if (newptr) memset(newptr, 0, size);
+    return newptr;
+}
+
+static void *__CFAllocatorCustomValloc(malloc_zone_t *zone, size_t size) {
+    CFAllocatorRef allocator = (CFAllocatorRef)zone;
+    void *newptr = CFAllocatorAllocate(allocator, size + vm_page_size, 0);
+    newptr = (void *)round_page((uintptr_t)newptr);
+    return newptr;
+}
+
+static void __CFAllocatorCustomFree(malloc_zone_t *zone, void *ptr) {
+    CFAllocatorRef allocator = (CFAllocatorRef)zone;
+    CFAllocatorDeallocate(allocator, ptr);
+}
+
+static void *__CFAllocatorCustomRealloc(malloc_zone_t *zone, void *ptr, size_t size) {
+    CFAllocatorRef allocator = (CFAllocatorRef)zone;
+    return CFAllocatorReallocate(allocator, ptr, size, 0);
+}
+
+static void __CFAllocatorCustomDestroy(malloc_zone_t *zone) {
+    CFAllocatorRef allocator = (CFAllocatorRef)zone;
+    // !!! we do it, and caller of malloc_destroy_zone() assumes
+    // COMPLETE responsibility for the result; NO Apple library
+    // code should be modified as a result of discovering that
+    // some activity results in inconveniences to developers
+    // trying to use malloc_destroy_zone() with a CFAllocatorRef;
+    // that's just too bad for them.
+    __CFAllocatorDeallocate(allocator);
+}
+
+static size_t __CFAllocatorCustomGoodSize(malloc_zone_t *zone, size_t size) {
+    CFAllocatorRef allocator = (CFAllocatorRef)zone;
+    return CFAllocatorGetPreferredSizeForSize(allocator, size, 0);
+}
+
+// These should live in the malloc.h heaer file
+typedef double (*Fx)(double);
+typedef kern_return_t (*mit_EnumType)(task_t task, void *, unsigned type_mask, vm_address_t zone_address, memory_reader_t reader, vm_range_recorder_t recorder);
+typedef size_t        (*mit_GoodSize)(malloc_zone_t *zone, size_t size);
+typedef boolean_t     (*mit_Check)(malloc_zone_t *zone);
+typedef void          (*mit_Print)(malloc_zone_t *zone, boolean_t verbose);
+typedef void          (*mit_Log)(malloc_zone_t *zone, void *address);
+typedef void          (*mit_ZoneAction)(malloc_zone_t *zone);
+typedef void          (*mit_Statistics)(malloc_zone_t *zone, malloc_statistics_t *stats);
+
+static struct malloc_introspection_t __CFAllocatorZoneIntrospect = {
+    (mit_EnumType)__CFAllocatorZoneIntrospectNoOp,
+    (mit_GoodSize)__CFAllocatorCustomGoodSize,
+    (mit_Check)__CFAllocatorZoneIntrospectTrue,
+    (mit_Print)__CFAllocatorZoneIntrospectNoOp,
+    (mit_Log)__CFAllocatorZoneIntrospectNoOp,
+    (mit_ZoneAction)__CFAllocatorZoneIntrospectNoOp,
+    (mit_ZoneAction)__CFAllocatorZoneIntrospectNoOp,
+    (mit_Statistics)__CFAllocatorZoneIntrospectNoOp
+};
+
+static size_t __CFAllocatorNullSize(malloc_zone_t *zone, const void *ptr) {
+    return 0;
+}
+
+static void * __CFAllocatorNullMalloc(malloc_zone_t *zone, size_t size) {
+    return NULL;
+}
+
+static void * __CFAllocatorNullCalloc(malloc_zone_t *zone, size_t num_items, size_t size) {
+    return NULL;
+}
+
+static void * __CFAllocatorNullValloc(malloc_zone_t *zone, size_t size) {
+    return NULL;
+}
+
+static void __CFAllocatorNullFree(malloc_zone_t *zone, void *ptr) {
+}
+
+static void * __CFAllocatorNullRealloc(malloc_zone_t *zone, void *ptr, size_t size) {
+    return NULL;
+}
+
+static void __CFAllocatorNullDestroy(malloc_zone_t *zone) {
+}
+
+static size_t __CFAllocatorNullGoodSize(malloc_zone_t *zone, size_t size) {
+    return size;
+}
+
+static struct malloc_introspection_t __CFAllocatorNullZoneIntrospect = {
+    (mit_EnumType)__CFAllocatorZoneIntrospectNoOp,
+    (mit_GoodSize)__CFAllocatorNullGoodSize,
+    (mit_Check)__CFAllocatorZoneIntrospectTrue,
+    (mit_Print)__CFAllocatorZoneIntrospectNoOp,
+    (mit_Log)__CFAllocatorZoneIntrospectNoOp,
+    (mit_ZoneAction)__CFAllocatorZoneIntrospectNoOp,
+    (mit_ZoneAction)__CFAllocatorZoneIntrospectNoOp,
+    (mit_Statistics)__CFAllocatorZoneIntrospectNoOp
+};
+
+static void *__CFAllocatorSystemAllocate(CFIndex size, CFOptionFlags hint, void *info) {
+    return malloc_zone_malloc((malloc_zone_t*)info, size);
+}
+
+static void *__CFAllocatorSystemReallocate(void *ptr, CFIndex newsize, CFOptionFlags hint, void *info) {
+    return malloc_zone_realloc((malloc_zone_t*)info, ptr, newsize);
+}
+
+static void __CFAllocatorSystemDeallocate(void *ptr, void *info) {
+#if defined(DEBUG)
+    size_t size = malloc_size(ptr);
+    if (size) memset(ptr, 0xCC, size);
+#endif
+    malloc_zone_free((malloc_zone_t*)info, ptr);
+}
+
+#endif /* DEPLOYMENT_TARGET_MACOSX */
+
+#if DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX || DEPLOYMENT_TARGET_FREEBSD
+static void *__CFAllocatorSystemAllocate(CFIndex size, CFOptionFlags hint, void *info) {
+    return malloc(size);
+}
+
+static void *__CFAllocatorSystemReallocate(void *ptr, CFIndex newsize, CFOptionFlags hint, void *info) {
+    return realloc(ptr, newsize);
+}
+
+static void __CFAllocatorSystemDeallocate(void *ptr, void *info) {
+#if defined(DEBUG)
+    const enum mcheck_status status = mprobe(ptr);
+
+    CFAssert3(status == MCHECK_OK || status == MCHECK_DISABLED,
+              __kCFLogAssertion, "%s: ptr %p status %d",
+              __PRETTY_FUNCTION__, ptr, status);
+#endif
+
+    free(ptr);
+}
+#endif
+
+static void *__CFAllocatorNullAllocate(CFIndex size, CFOptionFlags hint, void *info) {
+    return NULL;
+}
+
+static void *__CFAllocatorNullReallocate(void *ptr, CFIndex newsize, CFOptionFlags hint, void *info) {
+    return NULL;
+}
+
+#if defined (__cplusplus)
+static void * __CFAllocatorCPPMalloc(CFIndex allocSize, CFOptionFlags hint, void *info)
+{
+	return malloc(allocSize);	
+}
+static void * __CFAllocatorCPPReAlloc(void *ptr, CFIndex newsize, CFOptionFlags hint, void *info)
+{
+	return realloc(ptr, newsize);
+}
+static void __CFAllocatorCPPFree(void *ptr, void *info)
+{
+	free(ptr);
+}
+#endif // C++
+
+
+static struct __CFAllocator __kCFAllocatorMalloc = {
+    INIT_CFRUNTIME_BASE(),
+#if DEPLOYMENT_TARGET_MACOSX
+    __CFAllocatorCustomSize,
+    __CFAllocatorCustomMalloc,
+    __CFAllocatorCustomCalloc,
+    __CFAllocatorCustomValloc,
+    __CFAllocatorCustomFree,
+    __CFAllocatorCustomRealloc,
+    __CFAllocatorNullDestroy,
+    "kCFAllocatorMalloc",
+    NULL,
+    NULL,
+    &__CFAllocatorZoneIntrospect,
+    NULL,
+#endif
+    NULL,	// _allocator
+    // Using the malloc functions directly is a total cheat, but works (in C)
+    // because the function signatures match in their common prefix of arguments.
+    // This saves us one hop through an adaptor function.
+#if !defined (__cplusplus)
+	{0, NULL, NULL, NULL, NULL, (void *)malloc, (void *)realloc, (void *)free, NULL}
+#else
+	{0, NULL, NULL, NULL, NULL, __CFAllocatorCPPMalloc,__CFAllocatorCPPReAlloc, __CFAllocatorCPPFree, NULL}
+#endif // __cplusplus
+};
+
+static struct __CFAllocator __kCFAllocatorMallocZone = {
+    INIT_CFRUNTIME_BASE(),
+#if DEPLOYMENT_TARGET_MACOSX
+    __CFAllocatorCustomSize,
+    __CFAllocatorCustomMalloc,
+    __CFAllocatorCustomCalloc,
+    __CFAllocatorCustomValloc,
+    __CFAllocatorCustomFree,
+    __CFAllocatorCustomRealloc,
+    __CFAllocatorNullDestroy,
+    "kCFAllocatorMallocZone",
+    NULL,
+    NULL,
+    &__CFAllocatorZoneIntrospect,
+    NULL,
+#endif
+    NULL,	// _allocator
+    {0, NULL, NULL, NULL, NULL, __CFAllocatorSystemAllocate, __CFAllocatorSystemReallocate, __CFAllocatorSystemDeallocate, NULL}
+};
+
+static struct __CFAllocator __kCFAllocatorSystemDefault = {
+    INIT_CFRUNTIME_BASE(),
+#if DEPLOYMENT_TARGET_MACOSX
+    __CFAllocatorCustomSize,
+    __CFAllocatorCustomMalloc,
+    __CFAllocatorCustomCalloc,
+    __CFAllocatorCustomValloc,
+    __CFAllocatorCustomFree,
+    __CFAllocatorCustomRealloc,
+    __CFAllocatorNullDestroy,
+    "kCFAllocatorSystemDefault",
+    NULL,
+    NULL,
+    &__CFAllocatorZoneIntrospect,
+    NULL,
+#endif
+    NULL,	// _allocator
+    {0, NULL, NULL, NULL, NULL, __CFAllocatorSystemAllocate, __CFAllocatorSystemReallocate, __CFAllocatorSystemDeallocate, NULL}
+};
+
+static struct __CFAllocator __kCFAllocatorNull = {
+    INIT_CFRUNTIME_BASE(),
+#if DEPLOYMENT_TARGET_MACOSX
+    __CFAllocatorNullSize,
+    __CFAllocatorNullMalloc,
+    __CFAllocatorNullCalloc,
+    __CFAllocatorNullValloc,
+    __CFAllocatorNullFree,
+    __CFAllocatorNullRealloc,
+    __CFAllocatorNullDestroy,
+    "kCFAllocatorNull",
+    NULL,
+    NULL,
+    &__CFAllocatorNullZoneIntrospect,
+    NULL,
+#endif
+    NULL,	// _allocator
+    {0, NULL, NULL, NULL, NULL, __CFAllocatorNullAllocate, __CFAllocatorNullReallocate, NULL, NULL}
+};
+
+const CFAllocatorRef kCFAllocatorDefault = NULL;
+const CFAllocatorRef kCFAllocatorSystemDefault = &__kCFAllocatorSystemDefault;
+const CFAllocatorRef kCFAllocatorMalloc = &__kCFAllocatorMalloc;
+const CFAllocatorRef kCFAllocatorMallocZone = &__kCFAllocatorMallocZone;
+const CFAllocatorRef kCFAllocatorNull = &__kCFAllocatorNull;
+const CFAllocatorRef kCFAllocatorUseContext = (CFAllocatorRef)0x0257;
+
+static CFStringRef __CFAllocatorCopyDescription(CFTypeRef cf) {
+    CFAllocatorRef self = (CFAllocatorRef)cf;
+    CFAllocatorRef allocator = (kCFAllocatorUseContext == self->_allocator) ? self : self->_allocator;
+    return CFStringCreateWithFormat(allocator, NULL, CFSTR("<CFAllocator %p [%p]>{info = %p}"), cf, allocator, self->_context.info);
+// CF: should use copyDescription function here to describe info field
+// remember to release value returned from copydescr function when this happens
+}
+
+__private_extern__ CFAllocatorRef __CFAllocatorGetAllocator(CFTypeRef cf) {
+    CFAllocatorRef allocator = (CFAllocatorRef)cf;
+    return (kCFAllocatorUseContext == allocator->_allocator) ? allocator : allocator->_allocator;
+}
+
+__private_extern__ void __CFAllocatorDeallocate(CFTypeRef cf) {
+    CFAllocatorRef self = (CFAllocatorRef)cf;
+    CFAllocatorRef allocator = self->_allocator;
+    CFAllocatorReleaseCallBack releaseFunc = __CFAllocatorGetReleaseFunction(&self->_context);
+    if (kCFAllocatorUseContext == allocator) {
+	/* Rather a chicken and egg problem here, so we do things
+	   in the reverse order from what was done at create time. */
+	CFAllocatorDeallocateCallBack deallocateFunc = __CFAllocatorGetDeallocateFunction(&self->_context);
+	void *info = self->_context.info;
+	if (NULL != deallocateFunc) {
+	    INVOKE_CALLBACK2(deallocateFunc, (void *)self, info);
+	}
+	if (NULL != releaseFunc) {
+	    INVOKE_CALLBACK1(releaseFunc, info);
+	}
+    } else {
+	if (NULL != releaseFunc) {
+	    INVOKE_CALLBACK1(releaseFunc, self->_context.info);
+	}
+	_CFAllocatorDeallocateGC(allocator, (void *)self);
+    }
+}
+
+static CFTypeID __kCFAllocatorTypeID = _kCFRuntimeNotATypeID;
+
+static const CFRuntimeClass __CFAllocatorClass = {
+    0,
+    "CFAllocator",
+    NULL,	// init
+    NULL,	// copy
+    __CFAllocatorDeallocate,
+    NULL,	// equal
+    NULL,	// hash
+    NULL,	// 
+    __CFAllocatorCopyDescription
+};
+
+__private_extern__ void __CFAllocatorInitialize(void) {
+    __kCFAllocatorTypeID = _CFRuntimeRegisterClass(&__CFAllocatorClass);
+
+    _CFRuntimeSetInstanceTypeID(&__kCFAllocatorSystemDefault, __kCFAllocatorTypeID);
+    __kCFAllocatorSystemDefault._base._cfisa = __CFISAForTypeID(__kCFAllocatorTypeID);
+#if DEPLOYMENT_TARGET_MACOSX
+    __kCFAllocatorSystemDefault._context.info = (CF_USING_COLLECTABLE_MEMORY ? __CFCollectableZone : malloc_default_zone());
+    memset(malloc_default_zone(), 0, 2 * sizeof(void *));
+#endif
+    __kCFAllocatorSystemDefault._allocator = kCFAllocatorSystemDefault;
+#ifdef DEPLOYMENT_TARGET_WINDOWS
+    __kCFAllocatorSystemDefault._context.allocate = __CFAllocatorSystemAllocate;
+    __kCFAllocatorSystemDefault._context.reallocate = __CFAllocatorSystemReallocate;
+    __kCFAllocatorSystemDefault._context.deallocate = __CFAllocatorSystemDeallocate;
+#endif // DEPLOYMENT_TARGET_WINDOWS
+   
+    _CFRuntimeSetInstanceTypeID(&__kCFAllocatorMalloc, __kCFAllocatorTypeID);
+    __kCFAllocatorMalloc._base._cfisa = __CFISAForTypeID(__kCFAllocatorTypeID);
+    __kCFAllocatorMalloc._allocator = kCFAllocatorSystemDefault;
+
+#if DEPLOYMENT_TARGET_MACOSX
+	_CFRuntimeSetInstanceTypeID(&__kCFAllocatorMallocZone, __kCFAllocatorTypeID);
+    __kCFAllocatorMallocZone._base._cfisa = __CFISAForTypeID(__kCFAllocatorTypeID);
+    __kCFAllocatorMallocZone._allocator = kCFAllocatorSystemDefault;
+    __kCFAllocatorMallocZone._context.info = malloc_default_zone();
+#endif //__MACH__
+
+    _CFRuntimeSetInstanceTypeID(&__kCFAllocatorNull, __kCFAllocatorTypeID);
+    __kCFAllocatorNull._base._cfisa = __CFISAForTypeID(__kCFAllocatorTypeID);
+    __kCFAllocatorNull._allocator = kCFAllocatorSystemDefault;
+
+}
+
+CFTypeID CFAllocatorGetTypeID(void) {
+    return __kCFAllocatorTypeID;
+}
+
+CFAllocatorRef CFAllocatorGetDefault(void) {
+    CFAllocatorRef allocator = (CFAllocatorRef)__CFGetThreadSpecificData_inline()->_allocator;
+    if (NULL == allocator) {
+	allocator = kCFAllocatorSystemDefault;
+    }
+    return allocator;
+}
+
+void CFAllocatorSetDefault(CFAllocatorRef allocator) {
+    CFAllocatorRef current = (CFAllocatorRef)__CFGetThreadSpecificData_inline()->_allocator;
+#if defined(DEBUG) 
+    if (NULL != allocator) {
+	__CFGenericValidateType(allocator, __kCFAllocatorTypeID);
+    }
+#endif
+#if DEPLOYMENT_TARGET_MACOSX
+    if (allocator && allocator->_base._cfisa != __CFISAForTypeID(__kCFAllocatorTypeID)) {	// malloc_zone_t *
+	return;		// require allocator to this function to be an allocator
+    }
+#endif
+    if (NULL != allocator && allocator != current) {
+	if (current) CFRelease(current);
+	CFRetain(allocator);
+	// We retain an extra time so that anything set as the default
+	// allocator never goes away.
+	CFRetain(allocator);
+	__CFGetThreadSpecificData_inline()->_allocator = (void *)allocator;
+    }
+}
+
+static CFAllocatorRef __CFAllocatorCreate(CFAllocatorRef allocator, CFAllocatorContext *context) {
+    struct __CFAllocator *memory = NULL;
+    CFAllocatorRetainCallBack retainFunc;
+    CFAllocatorAllocateCallBack allocateFunc;
+    void *retainedInfo;
+#if DEPLOYMENT_TARGET_MACOSX
+    if (allocator && kCFAllocatorUseContext != allocator && allocator->_base._cfisa != __CFISAForTypeID(__kCFAllocatorTypeID)) {	// malloc_zone_t *
+	return NULL;	// require allocator to this function to be an allocator
+    }
+#endif
+    retainFunc = context->retain;
+    FAULT_CALLBACK((void **)&retainFunc);
+    allocateFunc = context->allocate;
+    FAULT_CALLBACK((void **)&allocateFunc);
+    if (NULL != retainFunc) {
+	retainedInfo = (void *)INVOKE_CALLBACK1(retainFunc, context->info);
+    } else {
+	retainedInfo = context->info;
+    }
+    // We don't use _CFRuntimeCreateInstance()
+    if (kCFAllocatorUseContext == allocator) {
+	memory = NULL;
+	if (allocateFunc) {
+		memory = (struct __CFAllocator *)INVOKE_CALLBACK3(allocateFunc, sizeof(struct __CFAllocator), 0, retainedInfo);
+	}
+	if (NULL == memory) {
+	    return NULL;
+	}
+    } else {
+	allocator = (NULL == allocator) ? __CFGetDefaultAllocator() : allocator;
+	memory = (struct __CFAllocator *)CFAllocatorAllocate(allocator, sizeof(struct __CFAllocator), __kCFAllocatorGCObjectMemory);
+	if (__CFOASafe) __CFSetLastAllocationEventName(memory, "CFAllocator");
+	if (NULL == memory) {
+	    return NULL;
+	}
+    }
+    memory->_base._cfisa = 0;
+#if __LP64__
+    memory->_base._rc = 1;
+#else
+    memory->_base._cfinfo[CF_RC_BITS] = 1;
+#endif
+    memory->_base._cfinfo[CF_INFO_BITS] = 0;
+    _CFRuntimeSetInstanceTypeID(memory, __kCFAllocatorTypeID);
+    memory->_base._cfisa = __CFISAForTypeID(__kCFAllocatorTypeID);
+#if DEPLOYMENT_TARGET_MACOSX
+    memory->size = __CFAllocatorCustomSize;
+    memory->malloc = __CFAllocatorCustomMalloc;
+    memory->calloc = __CFAllocatorCustomCalloc;
+    memory->valloc = __CFAllocatorCustomValloc;
+    memory->free = __CFAllocatorCustomFree;
+    memory->realloc = __CFAllocatorCustomRealloc;
+    memory->destroy = __CFAllocatorCustomDestroy;
+    memory->zone_name = "Custom CFAllocator";
+    memory->batch_malloc = NULL;
+    memory->batch_free = NULL;
+    memory->introspect = &__CFAllocatorZoneIntrospect;
+    memory->reserved5 = NULL;
+#endif
+    memory->_allocator = allocator;
+    memory->_context.version = context->version;
+    memory->_context.info = retainedInfo;
+    memory->_context.retain = retainFunc;
+    memory->_context.release = context->release;
+    FAULT_CALLBACK((void **)&(memory->_context.release));
+    memory->_context.copyDescription = context->copyDescription;
+    FAULT_CALLBACK((void **)&(memory->_context.copyDescription));
+    memory->_context.allocate = allocateFunc;
+    memory->_context.reallocate = context->reallocate;
+    FAULT_CALLBACK((void **)&(memory->_context.reallocate));
+    memory->_context.deallocate = context->deallocate;
+    FAULT_CALLBACK((void **)&(memory->_context.deallocate));
+    memory->_context.preferredSize = context->preferredSize;
+    FAULT_CALLBACK((void **)&(memory->_context.preferredSize));
+
+    return memory;
+}
+
+CFAllocatorRef CFAllocatorCreate(CFAllocatorRef allocator, CFAllocatorContext *context) {
+    CFAssert1(!CF_USING_COLLECTABLE_MEMORY, __kCFLogAssertion, "%s(): Shouldn't be called when GC is enabled!", __PRETTY_FUNCTION__);
+#if defined(DEBUG)
+    if (CF_USING_COLLECTABLE_MEMORY)
+        HALT;
+#endif
+    return __CFAllocatorCreate(allocator, context);
+}
+
+CFAllocatorRef _CFAllocatorCreateGC(CFAllocatorRef allocator, CFAllocatorContext *context) {
+    return __CFAllocatorCreate(allocator, context);
+}
+
+void *CFAllocatorAllocate(CFAllocatorRef allocator, CFIndex size, CFOptionFlags hint) {
+    CFAllocatorAllocateCallBack allocateFunc;
+    void *newptr = NULL;
+    allocator = (NULL == allocator) ? __CFGetDefaultAllocator() : allocator;
+#if (DEPLOYMENT_TARGET_MACOSX) && defined(DEBUG)
+    if (allocator->_base._cfisa == __CFISAForTypeID(__kCFAllocatorTypeID)) {
+	__CFGenericValidateType(allocator, __kCFAllocatorTypeID);
+    }
+#else
+    __CFGenericValidateType(allocator, __kCFAllocatorTypeID);
+#endif
+    if (0 == size) return NULL;
+#if DEPLOYMENT_TARGET_MACOSX
+    if (allocator->_base._cfisa != __CFISAForTypeID(__kCFAllocatorTypeID)) {	// malloc_zone_t *
+	return malloc_zone_malloc((malloc_zone_t *)allocator, size);
+    }
+#endif
+    if (CF_IS_COLLECTABLE_ALLOCATOR(allocator)) {
+	newptr = auto_zone_allocate_object((auto_zone_t*)allocator->_context.info, size, CF_GET_GC_MEMORY_TYPE(hint), true, false);
+    } else {
+	newptr = NULL;
+	allocateFunc = __CFAllocatorGetAllocateFunction(&allocator->_context);
+	if (allocateFunc) {
+		newptr = (void *)INVOKE_CALLBACK3(allocateFunc, size, hint, allocator->_context.info);
+	}
+    }
+    return newptr;
+}
+
+void *CFAllocatorReallocate(CFAllocatorRef allocator, void *ptr, CFIndex newsize, CFOptionFlags hint) {
+    CFAllocatorAllocateCallBack allocateFunc;
+    CFAllocatorReallocateCallBack reallocateFunc;
+    CFAllocatorDeallocateCallBack deallocateFunc;
+    void *newptr;
+    allocator = (NULL == allocator) ? __CFGetDefaultAllocator() : allocator;
+#if (DEPLOYMENT_TARGET_MACOSX) && defined(DEBUG)
+    if (allocator->_base._cfisa == __CFISAForTypeID(__kCFAllocatorTypeID)) {
+	__CFGenericValidateType(allocator, __kCFAllocatorTypeID);
+    }
+#else
+    __CFGenericValidateType(allocator, __kCFAllocatorTypeID);
+#endif
+    if (NULL == ptr && 0 < newsize) {
+#if DEPLOYMENT_TARGET_MACOSX
+	if (allocator->_base._cfisa != __CFISAForTypeID(__kCFAllocatorTypeID)) {	// malloc_zone_t *
+	    return malloc_zone_malloc((malloc_zone_t *)allocator, newsize);
+	}
+#endif
+	newptr = NULL;
+	allocateFunc = __CFAllocatorGetAllocateFunction(&allocator->_context);
+	if (allocateFunc) {
+		newptr = (void *)INVOKE_CALLBACK3(allocateFunc, newsize, hint, allocator->_context.info);
+	}
+	return newptr;
+    }
+    if (NULL != ptr && 0 == newsize) {
+#if DEPLOYMENT_TARGET_MACOSX
+	if (allocator->_base._cfisa != __CFISAForTypeID(__kCFAllocatorTypeID)) {	// malloc_zone_t *
+#if defined(DEBUG)
+	    size_t size = malloc_size(ptr);
+	    if (size) memset(ptr, 0xCC, size);
+#endif
+	    malloc_zone_free((malloc_zone_t *)allocator, ptr);
+	    return NULL;
+	}
+#endif /* DEPLOYMENT_TARGET_MACOSX */
+	deallocateFunc = __CFAllocatorGetDeallocateFunction(&allocator->_context);
+	if (NULL != deallocateFunc) {
+	    INVOKE_CALLBACK2(deallocateFunc, ptr, allocator->_context.info);
+	}
+	return NULL;
+    }
+    if (NULL == ptr && 0 == newsize) return NULL;
+#if DEPLOYMENT_TARGET_MACOSX
+    if (allocator->_base._cfisa != __CFISAForTypeID(__kCFAllocatorTypeID)) {	// malloc_zone_t *
+	return malloc_zone_realloc((malloc_zone_t *)allocator, ptr, newsize);
+    }
+#endif
+    reallocateFunc = __CFAllocatorGetReallocateFunction(&allocator->_context);
+    if (NULL == reallocateFunc) return NULL;
+    newptr = (void *)INVOKE_CALLBACK4(reallocateFunc, ptr, newsize, hint, allocator->_context.info);
+    return newptr;
+}
+
+void CFAllocatorDeallocate(CFAllocatorRef allocator, void *ptr) {
+    CFAllocatorDeallocateCallBack deallocateFunc;
+    allocator = (NULL == allocator) ? __CFGetDefaultAllocator() : allocator;
+#if (DEPLOYMENT_TARGET_MACOSX) && defined(DEBUG)
+    if (allocator->_base._cfisa == __CFISAForTypeID(__kCFAllocatorTypeID)) {
+	__CFGenericValidateType(allocator, __kCFAllocatorTypeID);
+    }
+#else
+    __CFGenericValidateType(allocator, __kCFAllocatorTypeID);
+#endif
+#if DEPLOYMENT_TARGET_MACOSX
+    if (allocator->_base._cfisa != __CFISAForTypeID(__kCFAllocatorTypeID)) {	// malloc_zone_t *
+#if defined(DEBUG)
+	size_t size = malloc_size(ptr);
+	if (size) memset(ptr, 0xCC, size);
+#endif
+	return malloc_zone_free((malloc_zone_t *)allocator, ptr);
+    }
+#endif /* DEPLOYMENT_TARGET_MACOSX */
+    deallocateFunc = __CFAllocatorGetDeallocateFunction(&allocator->_context);
+    if (NULL != ptr && NULL != deallocateFunc) {
+	INVOKE_CALLBACK2(deallocateFunc, ptr, allocator->_context.info);
+    }
+}
+
+CFIndex CFAllocatorGetPreferredSizeForSize(CFAllocatorRef allocator, CFIndex size, CFOptionFlags hint) {
+    CFAllocatorPreferredSizeCallBack prefFunc;
+    CFIndex newsize = 0;
+    allocator = (NULL == allocator) ? __CFGetDefaultAllocator() : allocator;
+#if (DEPLOYMENT_TARGET_MACOSX) && defined(DEBUG)
+    if (allocator->_base._cfisa == __CFISAForTypeID(__kCFAllocatorTypeID)) {
+	__CFGenericValidateType(allocator, __kCFAllocatorTypeID);
+    }
+#else
+    __CFGenericValidateType(allocator, __kCFAllocatorTypeID);
+#endif
+#if DEPLOYMENT_TARGET_MACOSX
+    if (allocator->_base._cfisa != __CFISAForTypeID(__kCFAllocatorTypeID)) {	// malloc_zone_t *
+	return malloc_good_size(size);
+    }
+#endif
+    prefFunc = __CFAllocatorGetPreferredSizeFunction(&allocator->_context);
+    if (0 < size && NULL != prefFunc) {
+	newsize = (CFIndex)(INVOKE_CALLBACK3(prefFunc, size, hint, allocator->_context.info));
+    }
+    if (newsize < size) newsize = size;
+    return newsize;
+}
+
+void CFAllocatorGetContext(CFAllocatorRef allocator, CFAllocatorContext *context) {
+    allocator = (NULL == allocator) ? __CFGetDefaultAllocator() : allocator;
+#if (DEPLOYMENT_TARGET_MACOSX) && defined(DEBUG)
+    if (allocator->_base._cfisa == __CFISAForTypeID(__kCFAllocatorTypeID)) {
+	__CFGenericValidateType(allocator, __kCFAllocatorTypeID);
+    }
+#else
+    __CFGenericValidateType(allocator, __kCFAllocatorTypeID);
+#endif
+    CFAssert1(0 == context->version, __kCFLogAssertion, "%s(): context version not initialized to 0", __PRETTY_FUNCTION__);
+#if DEPLOYMENT_TARGET_MACOSX
+    if (allocator->_base._cfisa != __CFISAForTypeID(__kCFAllocatorTypeID)) {	// malloc_zone_t *
+	return;
+    }
+#endif
+    context->version = 0;
+    context->info = allocator->_context.info;
+    context->retain = __CFAllocatorGetRetainFunction(&allocator->_context);
+    context->release = __CFAllocatorGetReleaseFunction(&allocator->_context);
+    context->copyDescription = __CFAllocatorGetCopyDescriptionFunction(&allocator->_context);
+    context->allocate = __CFAllocatorGetAllocateFunction(&allocator->_context);
+    context->reallocate = __CFAllocatorGetReallocateFunction(&allocator->_context);
+    context->deallocate = __CFAllocatorGetDeallocateFunction(&allocator->_context);
+    context->preferredSize = __CFAllocatorGetPreferredSizeFunction(&allocator->_context);
+#if (DEPLOYMENT_TARGET_MACOSX) && defined(__ppc__)
+    context->retain = (void *)((uintptr_t)context->retain & ~0x3);
+    context->release = (void *)((uintptr_t)context->release & ~0x3);
+    context->copyDescription = (void *)((uintptr_t)context->copyDescription & ~0x3);
+    context->allocate = (void *)((uintptr_t)context->allocate & ~0x3);
+    context->reallocate = (void *)((uintptr_t)context->reallocate & ~0x3);
+    context->deallocate = (void *)((uintptr_t)context->deallocate & ~0x3);
+    context->preferredSize = (void *)((uintptr_t)context->preferredSize & ~0x3);
+#endif
+}
+
+void *_CFAllocatorAllocateGC(CFAllocatorRef allocator, CFIndex size, CFOptionFlags hint)
+{
+    if (CF_IS_COLLECTABLE_ALLOCATOR(allocator))
+        return auto_zone_allocate_object((auto_zone_t*)kCFAllocatorSystemDefault->_context.info, size, CF_GET_GC_MEMORY_TYPE(hint), false, false);
+    else
+        return CFAllocatorAllocate(allocator, size, hint);
+}
+
+void *_CFAllocatorReallocateGC(CFAllocatorRef allocator, void *ptr, CFIndex newsize, CFOptionFlags hint)
+{
+    if (CF_IS_COLLECTABLE_ALLOCATOR(allocator)) {
+	if (ptr && (newsize == 0)) {
+	    return NULL; // equivalent to _CFAllocatorDeallocateGC.
+	}
+	if (ptr == NULL) {
+	    return auto_zone_allocate_object((auto_zone_t*)kCFAllocatorSystemDefault->_context.info, newsize, CF_GET_GC_MEMORY_TYPE(hint), false, false); // eq. to _CFAllocator
+	}
+    }
+    // otherwise, auto_realloc() now preserves layout type and refCount.
+    return CFAllocatorReallocate(allocator, ptr, newsize, hint);
+}
+
+void _CFAllocatorDeallocateGC(CFAllocatorRef allocator, void *ptr)
+{
+    // when running GC, don't deallocate.
+    if (!CF_IS_COLLECTABLE_ALLOCATOR(allocator)) CFAllocatorDeallocate(allocator, ptr);
+}
+
+// -------- -------- -------- -------- -------- -------- -------- --------
+
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_LINUX || DEPLOYMENT_TARGET_FREEBSD
+__private_extern__ pthread_key_t __CFTSDKey = (pthread_key_t)NULL;
+#elif DEPLOYMENT_TARGET_WINDOWS
+__private_extern__ DWORD __CFTSDKey = 0xFFFFFFFF;
+#endif
+
+extern void _CFRunLoop1(void);
+
+// Called for each thread as it exits
+__private_extern__ void __CFFinalizeThreadData(void *arg) {
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_LINUX || DEPLOYMENT_TARGET_FREEBSD
+    __CFThreadSpecificData *tsd = (__CFThreadSpecificData *)arg;
+#elif DEPLOYMENT_TARGET_WINDOWS
+    __CFThreadSpecificData *tsd = (__CFThreadSpecificData*)TlsGetValue(__CFTSDKey);
+    TlsSetValue(__CFTSDKey, NULL);
+#endif
+    if (NULL == tsd) return; 
+    if (tsd->_allocator) CFRelease(tsd->_allocator);
+#if DEPLOYMENT_TARGET_MACOSX
+    _CFRunLoop1();
+#endif
+#if DEPLOYMENT_TARGET_WINDOWS || 0
+
+    if (tsd->_messageHook) UnhookWindowsHookEx(tsd->_messageHook);
+
+#endif
+
+    CFAllocatorDeallocate(kCFAllocatorSystemDefault, tsd);
+}
+
+__private_extern__ __CFThreadSpecificData *__CFGetThreadSpecificData(void) {
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_LINUX || DEPLOYMENT_TARGET_FREEBSD
+    __CFThreadSpecificData *data;
+    data = (__CFThreadSpecificData*)pthread_getspecific(__CFTSDKey);
+    if (data) {
+        return data;
+    }
+    data =(__CFThreadSpecificData*)CFAllocatorAllocate(kCFAllocatorSystemDefault, sizeof(__CFThreadSpecificData), 0);
+    if (__CFOASafe) __CFSetLastAllocationEventName(data, "CFUtilities (thread-data)");
+    memset(data, 0, sizeof(__CFThreadSpecificData));
+    pthread_setspecific(__CFTSDKey, data);
+    return data;
+#elif DEPLOYMENT_TARGET_WINDOWS
+    __CFThreadSpecificData *data;
+    data = (__CFThreadSpecificData *)TlsGetValue(__CFTSDKey);
+    if (data) {
+        return data;
+    }
+    data = (__CFThreadSpecificData *)CFAllocatorAllocate(kCFAllocatorSystemDefault, sizeof(__CFThreadSpecificData), 0);
+    if (__CFOASafe) __CFSetLastAllocationEventName(data, "CFUtilities (thread-data)");
+    memset(data, 0, sizeof(__CFThreadSpecificData));
+    TlsSetValue(__CFTSDKey, data);
+    return data;
+#endif
+}
+
+__private_extern__ void __CFBaseInitialize(void) {
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_LINUX || DEPLOYMENT_TARGET_FREEBSD
+    pthread_key_create(&__CFTSDKey, __CFFinalizeThreadData);
+#elif DEPLOYMENT_TARGET_WINDOWS || 0
+    __CFTSDKey = TlsAlloc();
+#endif
+}
+
+#if DEPLOYMENT_TARGET_WINDOWS || 0
+__private_extern__ void __CFBaseCleanup(void) {
+    TlsFree(__CFTSDKey);
+}
+#endif
+
+
+static CFBadErrorCallBack __CFOutOfMemoryCallBack = NULL;
+
+CFBadErrorCallBack _CFGetOutOfMemoryErrorCallBack(void) {
+    return __CFOutOfMemoryCallBack;
+}
+
+void _CFSetOutOfMemoryErrorCallBack(CFBadErrorCallBack callBack) {
+    __CFOutOfMemoryCallBack = callBack;
+}
+
+
+CFRange __CFRangeMake(CFIndex loc, CFIndex len) {
+    CFRange range;
+    range.location = loc;
+    range.length = len;
+    return range;
+}
+
+
+struct __CFNull {
+    CFRuntimeBase _base;
+};
+
+static struct __CFNull __kCFNull = {
+    INIT_CFRUNTIME_BASE()
+};
+const CFNullRef kCFNull = &__kCFNull;
+
+static CFStringRef __CFNullCopyDescription(CFTypeRef cf) {
+    return CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("<CFNull %p [%p]>"), cf, CFGetAllocator(cf));
+}
+
+static CFStringRef __CFNullCopyFormattingDescription(CFTypeRef cf, CFDictionaryRef formatOptions) {
+    return (CFStringRef)CFRetain(CFSTR("null"));
+}
+
+static void __CFNullDeallocate(CFTypeRef cf) {
+    CFAssert(false, __kCFLogAssertion, "Deallocated CFNull!");
+}
+
+static CFTypeID __kCFNullTypeID = _kCFRuntimeNotATypeID;
+
+static const CFRuntimeClass __CFNullClass = {
+    0,
+    "CFNull",
+    NULL,      // init
+    NULL,      // copy
+    __CFNullDeallocate,
+    NULL,
+    NULL,
+    __CFNullCopyFormattingDescription,
+    __CFNullCopyDescription
+};
+
+__private_extern__ void __CFNullInitialize(void) {
+    __kCFNullTypeID = _CFRuntimeRegisterClass(&__CFNullClass);
+    _CFRuntimeSetInstanceTypeID(&__kCFNull, __kCFNullTypeID);
+    __kCFNull._base._cfisa = __CFISAForTypeID(__kCFNullTypeID);
+}
+
+CFTypeID CFNullGetTypeID(void) {
+    return __kCFNullTypeID;
+}
+
+void CFCollection_non_gc_storage_error(void) { }
+
+
+static int hasCFM = 0;
+
+void _CFRuntimeSetCFMPresent(void *addr) {
+    hasCFM = 1;
+}
+
+#if (DEPLOYMENT_TARGET_MACOSX) && defined(__ppc__)
+
+/* See comments below */
+__private_extern__ void __CF_FAULT_CALLBACK(void **ptr) {
+    uintptr_t p = (uintptr_t)*ptr;
+    if ((0 == p) || (p & 0x1)) return;
+    if (0 == hasCFM || (0x90000000 <= p && p < 0xA0000000)) {
+	*ptr = (void *)(p | 0x1);
+    } else {
+	static CFMutableDictionaryRef cache = NULL;
+	static CFSpinLock_t lock = CFSpinLockInit;
+	uintptr_t known = ~0;
+	__CFSpinLock(&lock);
+	if (!cache || !CFDictionaryGetValueIfPresent(cache, (const void *)p, (const void **)&known)) {
+	    if (!cache) {
+		cache = CFDictionaryCreateMutable(kCFAllocatorSystemDefault, 0, NULL, NULL);
+	    }
+	    Dl_info info;
+	    known = dladdr((void *)p, &info);
+	    CFDictionarySetValue(cache, (const void *)p, (const void *)known);
+	}
+	__CFSpinUnlock(&lock);
+	*ptr = (void *)(p | (known ? 0x1 : 0x3));
+    }
+}
+
+/*
+Jump to callback function.  r2 is not saved and restored
+in the jump-to-CFM case, since we assume that dyld code
+never uses that register and that CF is dyld.
+
+There are three states for (ptr & 0x3):
+	0b00:	check not yet done (or not going to be done, and is a dyld func ptr)
+	0b01:	check done, dyld function pointer
+	0b11:	check done, CFM tvector pointer
+(but a NULL callback just stays NULL)
+
+There may be up to 5 word-sized arguments. Floating point
+arguments can be done, but count as two word arguments.
+Return value can be integral or real.
+*/
+
+/* Keep this assembly at the bottom of the source file! */
+
+__asm__ (
+".text\n"
+"        .align 2\n"
+".private_extern ___CF_INVOKE_CALLBACK\n"
+"___CF_INVOKE_CALLBACK:\n"
+	"rlwinm r12,r3,0,0,29\n"
+	"andi. r0,r3,0x2\n"
+	"or r3,r4,r4\n"
+	"or r4,r5,r5\n"
+	"or r5,r6,r6\n"
+	"or r6,r7,r7\n"
+	"or r7,r8,r8\n"
+	"beq- Lcall\n"
+	"lwz r2,0x4(r12)\n"
+	"lwz r12,0x0(r12)\n"
+"Lcall:  mtspr ctr,r12\n"
+	"bctr\n");
+
+#endif
+
+
+// void __HALT(void);
+
+#if defined(__powerpc__) || defined(__ppc__) || defined(__ppc64__)
+__asm__ (
+".text\n"
+"	.align 2\n"
+#if DEPLOYMENT_TARGET_MACOSX
+".private_extern ___HALT\n"
+"___HALT:\n"
+#elif DEPLOYMENT_TARGET_LINUX
+".globl __HALT\n"
+"__HALT:\n"
+#else
+".globl ___HALT\n"
+"___HALT:\n"
+#endif
+"	trap\n"
+);
+#endif
+
+#if defined(__i386__) || defined(__x86_64__)
+#if defined(_MSC_VER)
+void __HALT() {
+    __asm int 3;
+}
+#else
+__asm__ (
+".text\n"
+"	.align 2, 0x90\n"
+#if DEPLOYMENT_TARGET_MACOSX
+".private_extern ___HALT\n"
+"___HALT:\n"
+#elif DEPLOYMENT_TARGET_LINUX
+".globl __HALT\n"
+"__HALT:\n"
+#else
+".globl ___HALT\n"
+"___HALT:\n"
+#endif
+"	int3\n"
+);
+#endif
+#endif
+
+#if defined(__arm__)
+__asm__ (
+".text\n"
+"	.align 2\n"
+#if DEPLOYMENT_TARGET_MACOSX
+".private_extern ___HALT\n"
+"___HALT:\n"
+#elif DEPLOYMENT_TARGET_LINUX
+".globl __HALT\n"
+"__HALT:\n"
+#else
+".globl ___HALT\n"
+"___HALT:\n"
+#endif
+"	bkpt\n"
+);
+#endif /* defined(__arm__) */
+
+#if defined(__aarch64__)
+__asm__ (
+".text\n"
+"	.align 2\n"
+#if DEPLOYMENT_TARGET_MACOSX
+".private_extern ___HALT\n"
+"___HALT:\n"
+#elif DEPLOYMENT_TARGET_LINUX
+".globl __HALT\n"
+"__HALT:\n"
+#else
+".globl ___HALT\n"
+"___HALT:\n"
+#endif
+"	brk #0000\n"
+);
+#endif /* defined(__aarch64__) */
diff --git a/CoreFoundation/CFBase.h b/CoreFoundation/CFBase.h
new file mode 100644
index 0000000..55fe89b
--- /dev/null
+++ b/CoreFoundation/CFBase.h
@@ -0,0 +1,469 @@
+/*
+ * Copyright (c) 2008-2009 Brent Fulgham <bfulgham@gmail.org>.  All rights reserved.
+ * Copyright (c) 2009 Grant Erickson <gerickson@nuovations.com>. All rights reserved.
+ *
+ * This source code is a modified version of the CoreFoundation sources released by Apple Inc. under
+ * the terms of the APSL version 2.0 (see below).
+ *
+ * For information about changes from the original Apple source release can be found by reviewing the
+ * source control system for the project at https://sourceforge.net/svn/?group_id=246198.
+ *
+ * The original license information is as follows:
+ * 
+ * Copyright (c) 2008 Apple Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*	CFBase.h
+	Copyright (c) 1998-2007, Apple Inc. All rights reserved.
+*/
+
+#if !defined(__COREFOUNDATION_CFBASE__)
+#define __COREFOUNDATION_CFBASE__ 1
+
+#if (defined(__CYGWIN32__) || defined(_WIN32) || defined(WIN32)) && !defined (__WIN32__)
+#define __WIN32__ 1
+#endif
+
+#if defined(_MSC_VER) && defined(_M_IX86)
+#define __i386__ 1
+#endif
+
+#if (defined(__i386__) || defined(__x86_64__)) && !defined(__LITTLE_ENDIAN__)
+    #define __LITTLE_ENDIAN__ 1
+#endif
+
+#if (defined(__ARMEL__) && !defined(__LITTLE_ENDIAN__))
+	#define __LITTLE_ENDIAN__ 1
+#endif
+
+#if !defined(__BIG_ENDIAN__) && !defined(__LITTLE_ENDIAN__)
+#error Do not know the endianess of this architecture
+#endif
+
+#if !__BIG_ENDIAN__ && !__LITTLE_ENDIAN__
+#error Both __BIG_ENDIAN__ and __LITTLE_ENDIAN__ cannot be false
+#endif
+
+#if __BIG_ENDIAN__ && __LITTLE_ENDIAN__
+#error Both __BIG_ENDIAN__ and __LITTLE_ENDIAN__ cannot be true
+#endif
+
+#if defined(__WIN32__)
+#include <windows.h>
+#include <winsock2.h>
+#endif
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#if !(defined(__APPLE__) || defined(__GNUC__))
+#define weak_import
+#define __private_extern__
+#elif defined(__GNUC__)
+#define weak_import
+#define __private_extern__ __attribute__((visibility("hidden")))
+#endif
+
+#include <AvailabilityMacros.h>
+
+#if defined(__MACH__)
+    #include <libkern/OSTypes.h>
+#endif
+
+#if !defined(__MACTYPES__)
+#if !defined(_OS_OSTYPES_H)
+    typedef unsigned char           Boolean;
+    typedef unsigned char           UInt8;
+    typedef signed char             SInt8;
+    typedef unsigned short          UInt16;
+    typedef signed short            SInt16;
+    typedef unsigned int            UInt32;
+    typedef signed int              SInt32;
+    typedef uint64_t		    UInt64;
+    typedef int64_t		    SInt64;
+    typedef SInt32                  OSStatus;
+#endif
+    typedef float                   Float32;
+    typedef double                  Float64;
+    typedef unsigned short          UniChar;
+    typedef unsigned char *         StringPtr;
+    typedef const unsigned char *   ConstStringPtr;
+    typedef unsigned char           Str255[256];
+    typedef const unsigned char *   ConstStr255Param;
+    typedef SInt16                  OSErr;
+    typedef SInt16                  RegionCode;
+    typedef SInt16                  LangCode;
+#endif
+#if !defined(__MACTYPES__) || (defined(UNIVERSAL_INTERFACES_VERSION) && UNIVERSAL_INTERFACES_VERSION < 0x0340)
+    typedef UInt32                  UTF32Char;
+    typedef UInt16                  UTF16Char;
+    typedef UInt8                   UTF8Char;
+#endif
+
+// Select correct deployment type
+#if defined(__APPLE__) && !defined(DEPLOYMENT_TARGET_MACOSX)
+#define DEPLOYMENT_TARGET_MACOSX 1
+#elif (defined (_WIN32) || defined(__WIN32__)) && defined(_MSC_VER) && !defined(DEPLOYMENT_TARGET_WINDOWS)
+#define DEPLOYMENT_TARGET_WINDOWS 1
+#elif (defined(linux) || defined(__linux) || defined (__linux__)) && !defined(DEPLOYMENT_TARGET_LINUX)
+#define DEPLOYMENT_TARGET_LINUX 1
+#endif
+
+#if !defined(CF_EXTERN_C_BEGIN)
+#if defined(__cplusplus)
+#define CF_EXTERN_C_BEGIN extern "C" {
+#define CF_EXTERN_C_END   }
+#else
+#define CF_EXTERN_C_BEGIN
+#define CF_EXTERN_C_END
+#endif
+#endif
+
+CF_EXTERN_C_BEGIN
+
+#if !defined(NULL)
+#if defined(__GNUG__)
+    #define NULL __null
+#elif defined(__cplusplus)
+    #define NULL 0
+#else
+    #define NULL ((void *)0)
+#endif
+#endif
+
+#if !defined(TRUE)
+    #define TRUE	1
+#endif
+
+#if !defined(FALSE)
+    #define FALSE	0
+#endif
+
+#if defined(__WIN32__)
+    #undef CF_EXPORT
+    #if defined(CF_BUILDING_CF)
+        #define CF_EXPORT __declspec(dllexport) extern
+    #else
+        #define CF_EXPORT __declspec(dllimport) extern
+    #endif
+    #ifdef __GNUC__
+        #define WIN_STDCALL __attribute__((stdcall))
+    #else
+        #define WIN_STDCALL __stdcall
+    #endif
+#elif defined(macintosh)
+    #if defined(__MWERKS__)
+        #define CF_EXPORT __declspec(export) extern
+    #endif
+#endif
+
+#if !defined(CF_EXPORT)
+    #define CF_EXPORT extern
+#endif
+
+#if !defined(CF_INLINE)
+    #if defined(__GNUC__) && (__GNUC__ == 4) && !defined(DEBUG)
+        #define CF_INLINE static __inline__ __attribute__((always_inline))
+    #elif defined(__GNUC__)
+        #define CF_INLINE static __inline__
+    #elif defined(__MWERKS__) || defined(__cplusplus)
+        #define CF_INLINE static inline
+    #elif defined(_MSC_VER)
+        #define CF_INLINE static __inline
+    #elif defined(__WIN32__)
+        #define CF_INLINE static __inline__
+    #endif
+#endif
+
+
+CF_EXPORT double                kCFCoreFoundationVersionNumber;
+CF_EXPORT const unsigned char   kCFCoreFoundationVersionString[];
+
+#define kCFCoreFoundationVersionNumber10_0	196.40
+#define kCFCoreFoundationVersionNumber10_0_3	196.50
+#define kCFCoreFoundationVersionNumber10_1	226.00
+#define kCFCoreFoundationVersionNumber10_1_1	226.00
+/* Note the next three do not follow the usual numbering policy from the base release */
+#define kCFCoreFoundationVersionNumber10_1_2	227.20
+#define kCFCoreFoundationVersionNumber10_1_3	227.20
+#define kCFCoreFoundationVersionNumber10_1_4	227.30
+#define kCFCoreFoundationVersionNumber10_2	263.00
+#define kCFCoreFoundationVersionNumber10_2_1	263.10
+#define kCFCoreFoundationVersionNumber10_2_2	263.10
+#define kCFCoreFoundationVersionNumber10_2_3	263.30
+#define kCFCoreFoundationVersionNumber10_2_4	263.30
+#define kCFCoreFoundationVersionNumber10_2_5	263.50
+#define kCFCoreFoundationVersionNumber10_2_6	263.50
+#define kCFCoreFoundationVersionNumber10_2_7	263.50
+#define kCFCoreFoundationVersionNumber10_2_8	263.50
+#define kCFCoreFoundationVersionNumber10_3	299.00
+#define kCFCoreFoundationVersionNumber10_3_1	299.00
+#define kCFCoreFoundationVersionNumber10_3_2	299.00
+#define kCFCoreFoundationVersionNumber10_3_3	299.30
+#define kCFCoreFoundationVersionNumber10_3_4	299.31
+#define kCFCoreFoundationVersionNumber10_3_5	299.31
+#define kCFCoreFoundationVersionNumber10_3_6	299.32
+#define kCFCoreFoundationVersionNumber10_3_7	299.33
+#define kCFCoreFoundationVersionNumber10_3_8	299.33
+#define kCFCoreFoundationVersionNumber10_3_9	299.35
+#define kCFCoreFoundationVersionNumber10_4	368.00
+#define kCFCoreFoundationVersionNumber10_4_1	368.10
+#define kCFCoreFoundationVersionNumber10_4_2	368.11
+#define kCFCoreFoundationVersionNumber10_4_3	368.18
+#define kCFCoreFoundationVersionNumber10_4_4_Intel	368.26
+#define kCFCoreFoundationVersionNumber10_4_4_PowerPC	368.25
+#define kCFCoreFoundationVersionNumber10_4_5_Intel	368.26
+#define kCFCoreFoundationVersionNumber10_4_5_PowerPC	368.25
+#define kCFCoreFoundationVersionNumber10_4_6_Intel	368.26
+#define kCFCoreFoundationVersionNumber10_4_6_PowerPC	368.25
+#define kCFCoreFoundationVersionNumber10_4_7	368.27
+#define kCFCoreFoundationVersionNumber10_4_8	368.27
+#define kCFCoreFoundationVersionNumber10_4_9	368.28
+#define kCFCoreFoundationVersionNumber10_4_10	368.28
+#define kCFCoreFoundationVersionNumber10_4_11	368.31
+
+typedef unsigned long CFTypeID;
+typedef unsigned long CFOptionFlags;
+typedef unsigned long CFHashCode;
+typedef signed long CFIndex;
+
+/* Base "type" of all "CF objects", and polymorphic functions on them */
+typedef const void * CFTypeRef;
+
+typedef const struct __CFString * CFStringRef;
+typedef struct __CFString * CFMutableStringRef;
+
+/*
+        Type to mean any instance of a property list type;
+        currently, CFString, CFData, CFNumber, CFBoolean, CFDate,
+        CFArray, and CFDictionary.
+*/
+typedef CFTypeRef CFPropertyListRef;
+
+/* Values returned from comparison functions */
+enum {
+    kCFCompareLessThan = -1,
+    kCFCompareEqualTo = 0,
+    kCFCompareGreaterThan = 1
+};
+typedef CFIndex CFComparisonResult;
+
+/* A standard comparison function */
+typedef CFComparisonResult (*CFComparatorFunction)(const void *val1, const void *val2, void *context);
+
+/* Constant used by some functions to indicate failed searches. */
+/* This is of type CFIndex. */
+enum {
+    kCFNotFound = -1
+};
+
+
+/* Range type */
+typedef struct {
+    CFIndex location;
+    CFIndex length;
+} CFRange;
+
+#if defined(CF_INLINE)
+CF_INLINE CFRange CFRangeMake(CFIndex loc, CFIndex len) {
+    CFRange range;
+    range.location = loc;
+    range.length = len;
+    return range;
+}
+#else
+#define CFRangeMake(LOC, LEN) __CFRangeMake(LOC, LEN)
+#endif
+
+/* Private; do not use */
+CF_EXPORT
+CFRange __CFRangeMake(CFIndex loc, CFIndex len);
+
+
+#if MAC_OS_X_VERSION_10_2 <= MAC_OS_X_VERSION_MAX_ALLOWED
+/* Null representant */
+
+typedef const struct __CFNull * CFNullRef;
+
+CF_EXPORT
+CFTypeID CFNullGetTypeID(void);
+
+CF_EXPORT
+const CFNullRef kCFNull;	// the singleton null instance
+
+#endif
+
+
+/* Allocator API
+
+   Most of the time when specifying an allocator to Create functions, the NULL
+   argument indicates "use the default"; this is the same as using kCFAllocatorDefault
+   or the return value from CFAllocatorGetDefault().  This assures that you will use
+   the allocator in effect at that time.
+
+   You should rarely use kCFAllocatorSystemDefault, the default default allocator.
+*/
+typedef const struct __CFAllocator * CFAllocatorRef;
+
+/* This is a synonym for NULL, if you'd rather use a named constant. */
+CF_EXPORT
+const CFAllocatorRef kCFAllocatorDefault;
+
+/* Default system allocator; you rarely need to use this. */
+CF_EXPORT
+const CFAllocatorRef kCFAllocatorSystemDefault;
+
+/* This allocator uses malloc(), realloc(), and free(). This should not be
+   generally used; stick to kCFAllocatorDefault whenever possible. This
+   allocator is useful as the "bytesDeallocator" in CFData or
+   "contentsDeallocator" in CFString where the memory was obtained as a
+   result of malloc() type functions.
+*/
+CF_EXPORT
+const CFAllocatorRef kCFAllocatorMalloc;
+
+/* This allocator explicitly uses the default malloc zone, returned by
+   malloc_default_zone(). It should only be used when an object is
+   safe to be allocated in non-scanned memory.
+ */
+CF_EXPORT
+const CFAllocatorRef kCFAllocatorMallocZone AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;
+
+/* Null allocator which does nothing and allocates no memory. This allocator
+   is useful as the "bytesDeallocator" in CFData or "contentsDeallocator"
+   in CFString where the memory should not be freed. 
+*/
+CF_EXPORT
+const CFAllocatorRef kCFAllocatorNull;
+
+/* Special allocator argument to CFAllocatorCreate() which means
+   "use the functions given in the context to allocate the allocator
+   itself as well". 
+*/
+CF_EXPORT
+const CFAllocatorRef kCFAllocatorUseContext;
+
+typedef const void *	(*CFAllocatorRetainCallBack)(const void *info);
+typedef void		(*CFAllocatorReleaseCallBack)(const void *info);
+typedef CFStringRef	(*CFAllocatorCopyDescriptionCallBack)(const void *info);
+typedef void *		(*CFAllocatorAllocateCallBack)(CFIndex allocSize, CFOptionFlags hint, void *info);
+typedef void *		(*CFAllocatorReallocateCallBack)(void *ptr, CFIndex newsize, CFOptionFlags hint, void *info);
+typedef void		(*CFAllocatorDeallocateCallBack)(void *ptr, void *info);
+typedef CFIndex		(*CFAllocatorPreferredSizeCallBack)(CFIndex size, CFOptionFlags hint, void *info);
+typedef struct {
+    CFIndex				version;
+    void *				info;
+    CFAllocatorRetainCallBack		retain;
+    CFAllocatorReleaseCallBack		release;        
+    CFAllocatorCopyDescriptionCallBack	copyDescription;
+    CFAllocatorAllocateCallBack		allocate;
+    CFAllocatorReallocateCallBack	reallocate;
+    CFAllocatorDeallocateCallBack	deallocate;
+    CFAllocatorPreferredSizeCallBack	preferredSize;
+} CFAllocatorContext;
+
+CF_EXPORT
+CFTypeID	CFAllocatorGetTypeID(void);
+
+/*
+	CFAllocatorSetDefault() sets the allocator that is used in the current
+	thread whenever NULL is specified as an allocator argument. This means
+	that most, if not all allocations will go through this allocator. It
+	also means that any allocator set as the default needs to be ready to
+	deal with arbitrary memory allocation requests; in addition, the size
+	and number of requests will change between releases.
+
+	An allocator set as the default will never be released, even if later
+	another allocator replaces it as the default. Not only is it impractical
+	for it to be released (as there might be caches created under the covers
+	that refer to the allocator), in general it's also safer and more
+	efficient to keep it around.
+
+	If you wish to use a custom allocator in a context, it's best to provide
+	it as the argument to the various creation functions rather than setting
+	it as the default. Setting the default allocator is not encouraged.
+
+	If you do set an allocator as the default, either do it for all time in
+	your app, or do it in a nested fashion (by restoring the previous allocator
+	when you exit your context). The latter might be appropriate for plug-ins
+	or libraries that wish to set the default allocator.
+*/
+CF_EXPORT
+void CFAllocatorSetDefault(CFAllocatorRef allocator);
+
+CF_EXPORT
+CFAllocatorRef CFAllocatorGetDefault(void);
+
+CF_EXPORT
+CFAllocatorRef CFAllocatorCreate(CFAllocatorRef allocator, CFAllocatorContext *context);
+
+CF_EXPORT
+void *CFAllocatorAllocate(CFAllocatorRef allocator, CFIndex size, CFOptionFlags hint);
+
+CF_EXPORT
+void *CFAllocatorReallocate(CFAllocatorRef allocator, void *ptr, CFIndex newsize, CFOptionFlags hint);
+
+CF_EXPORT
+void CFAllocatorDeallocate(CFAllocatorRef allocator, void *ptr);
+
+CF_EXPORT
+CFIndex CFAllocatorGetPreferredSizeForSize(CFAllocatorRef allocator, CFIndex size, CFOptionFlags hint);
+
+CF_EXPORT
+void CFAllocatorGetContext(CFAllocatorRef allocator, CFAllocatorContext *context);
+
+
+/* Polymorphic CF functions */
+
+CF_EXPORT
+CFTypeID CFGetTypeID(CFTypeRef cf);
+
+CF_EXPORT
+CFStringRef CFCopyTypeIDDescription(CFTypeID type_id);
+
+CF_EXPORT
+CFTypeRef CFRetain(CFTypeRef cf);
+
+CF_EXPORT
+void CFRelease(CFTypeRef cf);
+
+CF_EXPORT
+CFIndex CFGetRetainCount(CFTypeRef cf);
+
+CF_EXPORT
+CFTypeRef CFMakeCollectable(CFTypeRef cf) AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;
+
+CF_EXPORT
+Boolean CFEqual(CFTypeRef cf1, CFTypeRef cf2);
+
+CF_EXPORT
+CFHashCode CFHash(CFTypeRef cf);
+
+CF_EXPORT
+CFStringRef CFCopyDescription(CFTypeRef cf);
+
+CF_EXPORT
+CFAllocatorRef CFGetAllocator(CFTypeRef cf);
+
+CF_EXTERN_C_END
+
+#endif /* ! __COREFOUNDATION_CFBASE__ */
+
diff --git a/CoreFoundation/CFBinaryHeap.c b/CoreFoundation/CFBinaryHeap.c
new file mode 100644
index 0000000..885428d
--- /dev/null
+++ b/CoreFoundation/CFBinaryHeap.c
@@ -0,0 +1,459 @@
+/*
+ * Copyright (c) 2008-2009 Brent Fulgham <bfulgham@gmail.org>.  All rights reserved.
+ *
+ * This source code is a modified version of the CoreFoundation sources released by Apple Inc. under
+ * the terms of the APSL version 2.0 (see below).
+ *
+ * For information about changes from the original Apple source release can be found by reviewing the
+ * source control system for the project at https://sourceforge.net/svn/?group_id=246198.
+ *
+ * The original license information is as follows:
+ * 
+ * Copyright (c) 2008 Apple Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*	CFBinaryHeap.c
+	Copyright 1998-2002, Apple, Inc. All rights reserved.
+	Responsibility: Christopher Kane
+*/
+
+#include <CoreFoundation/CFBinaryHeap.h>
+#include "CFPriv.h"
+#include "CFInternal.h"
+
+const CFBinaryHeapCallBacks kCFStringBinaryHeapCallBacks = {0, __CFTypeCollectionRetain, __CFTypeCollectionRelease, CFCopyDescription, (CFComparisonResult (*)(const void *, const void *, void *))CFStringCompare};
+
+struct __CFBinaryHeapBucket {
+    void *_item;
+};
+
+CF_INLINE CFIndex __CFBinaryHeapRoundUpCapacity(CFIndex capacity) {
+    if (capacity < 4) return 4;
+    return (1 << flsl(capacity));
+}
+
+CF_INLINE CFIndex __CFBinaryHeapNumBucketsForCapacity(CFIndex capacity) {
+    return capacity;
+}
+
+struct __CFBinaryHeap {
+    CFRuntimeBase _base;
+    CFIndex _count;	/* number of objects */
+    CFIndex _capacity;	/* maximum number of objects */
+    CFBinaryHeapCallBacks _callbacks;
+    CFBinaryHeapCompareContext _context;
+    struct __CFBinaryHeapBucket *_buckets;
+};
+
+CF_INLINE CFIndex __CFBinaryHeapCount(CFBinaryHeapRef heap) {
+    return heap->_count;
+}
+
+CF_INLINE void __CFBinaryHeapSetCount(CFBinaryHeapRef heap, CFIndex v) {
+    /* for a CFBinaryHeap, _bucketsUsed == _count */
+}
+
+CF_INLINE CFIndex __CFBinaryHeapCapacity(CFBinaryHeapRef heap) {
+    return heap->_capacity;
+}
+
+CF_INLINE void __CFBinaryHeapSetCapacity(CFBinaryHeapRef heap, CFIndex v) {
+    /* for a CFBinaryHeap, _bucketsNum == _capacity */
+}
+
+CF_INLINE CFIndex __CFBinaryHeapNumBucketsUsed(CFBinaryHeapRef heap) {
+    return heap->_count;
+}
+
+CF_INLINE void __CFBinaryHeapSetNumBucketsUsed(CFBinaryHeapRef heap, CFIndex v) {
+    heap->_count = v;
+}
+
+CF_INLINE CFIndex __CFBinaryHeapNumBuckets(CFBinaryHeapRef heap) {
+    return heap->_capacity;
+}
+
+CF_INLINE void __CFBinaryHeapSetNumBuckets(CFBinaryHeapRef heap, CFIndex v) {
+    heap->_capacity = v;
+}
+
+enum {      /* bits 1-0 */
+    kCFBinaryHeapMutable = 0x1,		/* changeable and variable capacity */
+};
+
+/* Bits 4-5 are used by GC */
+
+CF_INLINE bool isStrongMemory_Heap(CFTypeRef collection) {
+    return __CFBitfieldGetValue(((const CFRuntimeBase *)collection)->_cfinfo[CF_INFO_BITS], 4, 4) == 0;
+}
+
+CF_INLINE bool isWeakMemory_Heap(CFTypeRef collection) {
+    return __CFBitfieldGetValue(((const CFRuntimeBase *)collection)->_cfinfo[CF_INFO_BITS], 4, 4) != 0;
+}
+
+CF_INLINE UInt32 __CFBinaryHeapMutableVariety(const void *cf) {
+    return __CFBitfieldGetValue(((const CFRuntimeBase *)cf)->_cfinfo[CF_INFO_BITS], 3, 2);
+}
+
+CF_INLINE void __CFBinaryHeapSetMutableVariety(void *cf, UInt32 v) {
+    __CFBitfieldSetValue(((CFRuntimeBase *)cf)->_cfinfo[CF_INFO_BITS], 3, 2, v);
+}
+
+CF_INLINE UInt32 __CFBinaryHeapMutableVarietyFromFlags(UInt32 flags) {
+    return __CFBitfieldGetValue(flags, 1, 0);
+}
+
+static Boolean __CFBinaryHeapEqual(CFTypeRef cf1, CFTypeRef cf2) {
+    CFBinaryHeapRef heap1 = (CFBinaryHeapRef)cf1;
+    CFBinaryHeapRef heap2 = (CFBinaryHeapRef)cf2;
+    CFComparisonResult (*compare)(const void *, const void *, void *);
+    CFIndex idx;
+    CFIndex cnt;
+    const void **list1, **list2, *buffer[256];
+    cnt = __CFBinaryHeapCount(heap1);
+    if (cnt != __CFBinaryHeapCount(heap2)) return false;
+    compare = heap1->_callbacks.compare;
+    if (compare != heap2->_callbacks.compare) return false;
+    if (0 == cnt) return true;	/* after function comparison */
+    list1 = (cnt <= 128) ? (const void **)buffer : (const void **)CFAllocatorAllocate(kCFAllocatorSystemDefault, 2 * cnt * sizeof(void *), 0); // GC OK
+    if (__CFOASafe && list1 != buffer) __CFSetLastAllocationEventName(list1, "CFBinaryHeap (temp)");
+    list2 = (cnt <= 128) ? buffer + 128 : list1 + cnt;
+    CFBinaryHeapGetValues(heap1, list1);
+    CFBinaryHeapGetValues(heap2, list2);
+    for (idx = 0; idx < cnt; idx++) {
+	const void *val1 = list1[idx];
+	const void *val2 = list2[idx];
+// CF: which context info should be passed in? both?
+// CF: if the context infos are not equal, should the heaps not be equal?
+        if (val1 != val2) { 
+            if (NULL == compare) return false;
+            if (!compare(val1, val2, heap1->_context.info)) return false;
+        }
+    }
+    if (list1 != buffer) CFAllocatorDeallocate(CFGetAllocator(heap1), list1); // GC OK
+    return true;
+}
+
+static CFHashCode __CFBinaryHeapHash(CFTypeRef cf) {
+    CFBinaryHeapRef heap = (CFBinaryHeapRef)cf;
+    return __CFBinaryHeapCount(heap);
+}
+
+static CFStringRef __CFBinaryHeapCopyDescription(CFTypeRef cf) {
+    CFBinaryHeapRef heap = (CFBinaryHeapRef)cf;
+    CFMutableStringRef result;
+    CFIndex idx;
+    CFIndex cnt;
+    const void **list, *buffer[256];
+    cnt = __CFBinaryHeapCount(heap);
+    result = CFStringCreateMutable(CFGetAllocator(heap), 0);
+    CFStringAppendFormat(result, NULL, CFSTR("<CFBinaryHeap %p [%p]>{count = %u, capacity = %u, objects = (\n"), cf, CFGetAllocator(heap), cnt, __CFBinaryHeapCapacity(heap));
+    list = (cnt <= 128) ? (const void **)buffer : (const void **)CFAllocatorAllocate(kCFAllocatorSystemDefault, cnt * sizeof(void *), 0); // GC OK
+    if (__CFOASafe && list != buffer) __CFSetLastAllocationEventName(list, "CFBinaryHeap (temp)");
+    CFBinaryHeapGetValues(heap, list);
+    for (idx = 0; idx < cnt; idx++) {
+	CFStringRef desc = NULL;
+	const void *item = list[idx];
+	if (NULL != heap->_callbacks.copyDescription) {
+	    desc = heap->_callbacks.copyDescription(item);
+	}
+	if (NULL != desc) {
+	    CFStringAppendFormat(result, NULL, CFSTR("\t%u : %s\n"), idx, desc);
+	    CFRelease(desc);
+	} else {
+	    CFStringAppendFormat(result, NULL, CFSTR("\t%u : <%p>\n"), idx, item);
+	}
+    }
+    CFStringAppend(result, CFSTR(")}"));
+    if (list != buffer) CFAllocatorDeallocate(CFGetAllocator(heap), list); // GC OK
+    return result;
+}
+
+static void __CFBinaryHeapDeallocate(CFTypeRef cf) {
+    CFBinaryHeapRef heap = (CFBinaryHeapRef)cf;
+    CFAllocatorRef allocator = CFGetAllocator(heap);
+    if (CF_IS_COLLECTABLE_ALLOCATOR(allocator)) {
+	if (heap->_callbacks.retain == NULL && heap->_callbacks.release == NULL)
+	    return; // GC: keep heap intact during finalization.
+    }
+// CF: should make the heap mutable here first, a la CFArrayDeallocate
+    CFBinaryHeapRemoveAllValues(heap);
+// CF: does not release the context info
+    if (__CFBinaryHeapMutableVariety(heap) == kCFBinaryHeapMutable) {
+	_CFAllocatorDeallocateGC(allocator, heap->_buckets);
+    }
+}
+
+static CFTypeID __kCFBinaryHeapTypeID = _kCFRuntimeNotATypeID;
+
+static const CFRuntimeClass __CFBinaryHeapClass = {
+    _kCFRuntimeScannedObject,
+    "CFBinaryHeap",
+    NULL,	// init
+    NULL,	// copy
+    __CFBinaryHeapDeallocate,
+    __CFBinaryHeapEqual,
+    __CFBinaryHeapHash,
+    NULL,	// 
+    __CFBinaryHeapCopyDescription
+};
+
+__private_extern__ void __CFBinaryHeapInitialize(void) {
+    __kCFBinaryHeapTypeID = _CFRuntimeRegisterClass(&__CFBinaryHeapClass);
+}
+
+CFTypeID CFBinaryHeapGetTypeID(void) {
+    return __kCFBinaryHeapTypeID;
+}
+
+static CFBinaryHeapRef __CFBinaryHeapInit(CFAllocatorRef allocator, UInt32 flags, CFIndex capacity, const void **values, CFIndex numValues, const CFBinaryHeapCallBacks *callBacks, const CFBinaryHeapCompareContext *compareContext) {
+    CFBinaryHeapRef memory;
+    CFIndex idx;
+    CFIndex size;
+
+    CFAssert2(0 <= capacity, __kCFLogAssertion, "%s(): capacity (%d) cannot be less than zero", __PRETTY_FUNCTION__, capacity);
+    CFAssert2(0 <= numValues, __kCFLogAssertion, "%s(): numValues (%d) cannot be less than zero", __PRETTY_FUNCTION__, numValues);
+    size = sizeof(struct __CFBinaryHeap) - sizeof(CFRuntimeBase);
+    if (CF_IS_COLLECTABLE_ALLOCATOR(allocator)) {
+	if (!callBacks || (callBacks->retain == NULL && callBacks->release == NULL)) {
+	    __CFBitfieldSetValue(flags, 4, 4, 1); // setWeak
+	}
+    }
+
+    memory = (CFBinaryHeapRef)_CFRuntimeCreateInstance(allocator, __kCFBinaryHeapTypeID, size, NULL);
+    if (NULL == memory) {
+	return NULL;
+    }
+	__CFBinaryHeapSetCapacity(memory, __CFBinaryHeapRoundUpCapacity(1));
+	__CFBinaryHeapSetNumBuckets(memory, __CFBinaryHeapNumBucketsForCapacity(__CFBinaryHeapRoundUpCapacity(1)));
+	void *buckets = _CFAllocatorAllocateGC(allocator, __CFBinaryHeapNumBuckets(memory) * sizeof(struct __CFBinaryHeapBucket), isStrongMemory_Heap(memory) ? __kCFAllocatorGCScannedMemory : 0);
+	CF_WRITE_BARRIER_BASE_ASSIGN(allocator, memory, memory->_buckets, buckets);
+	if (__CFOASafe) __CFSetLastAllocationEventName(memory->_buckets, "CFBinaryHeap (store)");
+	if (NULL == memory->_buckets) {
+	    CFRelease(memory);
+	    return NULL;
+	}
+    __CFBinaryHeapSetNumBucketsUsed(memory, 0);
+    __CFBinaryHeapSetCount(memory, 0);
+    if (NULL != callBacks) {
+	memory->_callbacks.retain = callBacks->retain;
+	memory->_callbacks.release = callBacks->release;
+	memory->_callbacks.copyDescription = callBacks->copyDescription;
+	memory->_callbacks.compare = callBacks->compare;
+    } else {
+	memory->_callbacks.retain = 0;
+	memory->_callbacks.release = 0;
+	memory->_callbacks.copyDescription = 0;
+	memory->_callbacks.compare = 0;
+    }
+    __CFBinaryHeapSetMutableVariety(memory, kCFBinaryHeapMutable);
+    for (idx = 0; idx < numValues; idx++) {
+	CFBinaryHeapAddValue(memory, values[idx]);
+    }
+    __CFBinaryHeapSetMutableVariety(memory, __CFBinaryHeapMutableVarietyFromFlags(flags));
+    if (compareContext) memcpy(&memory->_context, compareContext, sizeof(CFBinaryHeapCompareContext));
+    return memory;
+}
+
+CFBinaryHeapRef CFBinaryHeapCreate(CFAllocatorRef allocator, CFIndex capacity, const CFBinaryHeapCallBacks *callBacks, const CFBinaryHeapCompareContext *compareContext) {
+   return __CFBinaryHeapInit(allocator, kCFBinaryHeapMutable, capacity, NULL, 0, callBacks, compareContext);
+}
+
+CFBinaryHeapRef CFBinaryHeapCreateCopy(CFAllocatorRef allocator, CFIndex capacity, CFBinaryHeapRef heap) {
+   __CFGenericValidateType(heap, __kCFBinaryHeapTypeID);
+    return __CFBinaryHeapInit(allocator, kCFBinaryHeapMutable, capacity, (const void **)heap->_buckets, __CFBinaryHeapCount(heap), &(heap->_callbacks), &(heap->_context));
+}
+
+CFIndex CFBinaryHeapGetCount(CFBinaryHeapRef heap) {
+    __CFGenericValidateType(heap, __kCFBinaryHeapTypeID);
+    return __CFBinaryHeapCount(heap);
+}
+
+CFIndex CFBinaryHeapGetCountOfValue(CFBinaryHeapRef heap, const void *value) {
+    CFComparisonResult (*compare)(const void *, const void *, void *);
+    CFIndex idx;
+    CFIndex cnt = 0, length;
+    __CFGenericValidateType(heap, __kCFBinaryHeapTypeID);
+    compare = heap->_callbacks.compare;
+    length = __CFBinaryHeapCount(heap);
+    for (idx = 0; idx < length; idx++) {
+	const void *item = heap->_buckets[idx]._item;
+	if (value == item || (compare && kCFCompareEqualTo == compare(value, item, heap->_context.info))) {
+	    cnt++;
+	}
+    }
+    return cnt;
+}
+
+Boolean CFBinaryHeapContainsValue(CFBinaryHeapRef heap, const void *value) {
+    CFComparisonResult (*compare)(const void *, const void *, void *);
+    CFIndex idx;
+    CFIndex length;
+    __CFGenericValidateType(heap, __kCFBinaryHeapTypeID);
+    compare = heap->_callbacks.compare;
+    length = __CFBinaryHeapCount(heap);
+    for (idx = 0; idx < length; idx++) {
+	const void *item = heap->_buckets[idx]._item;
+	if (value == item || (compare && kCFCompareEqualTo == compare(value, item, heap->_context.info))) {
+	    return true;
+	}
+    }
+    return false;
+}
+
+const void *CFBinaryHeapGetMinimum(CFBinaryHeapRef heap) {
+    __CFGenericValidateType(heap, __kCFBinaryHeapTypeID);
+    CFAssert1(0 < __CFBinaryHeapCount(heap), __kCFLogAssertion, "%s(): binary heap is empty", __PRETTY_FUNCTION__);
+    return (0 < __CFBinaryHeapCount(heap)) ? heap->_buckets[0]._item : NULL;
+}
+
+Boolean CFBinaryHeapGetMinimumIfPresent(CFBinaryHeapRef heap, const void **value) {
+    __CFGenericValidateType(heap, __kCFBinaryHeapTypeID);
+    if (0 == __CFBinaryHeapCount(heap)) return false;
+    if (NULL != value) __CFObjCStrongAssign(heap->_buckets[0]._item, value);
+    return true;
+}
+
+void CFBinaryHeapGetValues(CFBinaryHeapRef heap, const void **values) {
+    CFBinaryHeapRef heapCopy;
+    CFIndex idx;
+    CFIndex cnt;
+    __CFGenericValidateType(heap, __kCFBinaryHeapTypeID);
+    CFAssert1(NULL != values, __kCFLogAssertion, "%s(): pointer to values may not be NULL", __PRETTY_FUNCTION__);
+    cnt = __CFBinaryHeapCount(heap);
+    if (0 == cnt) return;
+    if (CF_USING_COLLECTABLE_MEMORY) {
+	// GC: speculatively issue a write-barrier on the copied to buffers (3743553).
+	__CFObjCWriteBarrierRange(values, cnt * sizeof(void *));
+    }
+    heapCopy = CFBinaryHeapCreateCopy(CFGetAllocator(heap), cnt, heap);
+    idx = 0;
+    while (0 < __CFBinaryHeapCount(heapCopy)) {
+	const void *value = CFBinaryHeapGetMinimum(heapCopy);
+	CFBinaryHeapRemoveMinimumValue(heapCopy);
+	values[idx++] = value;
+    }
+    CFRelease(heapCopy);
+}
+
+void CFBinaryHeapApplyFunction(CFBinaryHeapRef heap, CFBinaryHeapApplierFunction applier, void *context) {
+    CFBinaryHeapRef heapCopy;
+    CFIndex cnt;
+    __CFGenericValidateType(heap, __kCFBinaryHeapTypeID);
+    CFAssert1(NULL != applier, __kCFLogAssertion, "%s(): pointer to applier function may not be NULL", __PRETTY_FUNCTION__);
+    cnt = __CFBinaryHeapCount(heap);
+    if (0 == cnt) return;
+    heapCopy = CFBinaryHeapCreateCopy(CFGetAllocator(heap), cnt, heap);
+    while (0 < __CFBinaryHeapCount(heapCopy)) {
+	const void *value = CFBinaryHeapGetMinimum(heapCopy);
+	CFBinaryHeapRemoveMinimumValue(heapCopy);
+	applier(value, context);
+    }
+    CFRelease(heapCopy);
+}
+
+static void __CFBinaryHeapGrow(CFBinaryHeapRef heap, CFIndex numNewValues) {
+    CFIndex oldCount = __CFBinaryHeapCount(heap);
+    CFIndex capacity = __CFBinaryHeapRoundUpCapacity(oldCount + numNewValues);
+    CFAllocatorRef allocator = CFGetAllocator(heap);
+    __CFBinaryHeapSetCapacity(heap, capacity);
+    __CFBinaryHeapSetNumBuckets(heap, __CFBinaryHeapNumBucketsForCapacity(capacity));
+    void *buckets = _CFAllocatorReallocateGC(allocator, heap->_buckets, __CFBinaryHeapNumBuckets(heap) * sizeof(struct __CFBinaryHeapBucket), isStrongMemory_Heap(heap) ? __kCFAllocatorGCScannedMemory : 0);
+    CF_WRITE_BARRIER_BASE_ASSIGN(allocator, heap, heap->_buckets, buckets);
+    if (__CFOASafe) __CFSetLastAllocationEventName(heap->_buckets, "CFBinaryHeap (store)");
+    if (NULL == heap->_buckets) HALT;
+}
+
+void CFBinaryHeapAddValue(CFBinaryHeapRef heap, const void *value) {
+    CFIndex idx, pidx;
+    CFIndex cnt;
+    CFAllocatorRef allocator = CFGetAllocator(heap);
+    __CFGenericValidateType(heap, __kCFBinaryHeapTypeID);
+    switch (__CFBinaryHeapMutableVariety(heap)) {
+    case kCFBinaryHeapMutable:
+	if (__CFBinaryHeapNumBucketsUsed(heap) == __CFBinaryHeapCapacity(heap))
+	    __CFBinaryHeapGrow(heap, 1);
+	break;
+    }
+    cnt = __CFBinaryHeapCount(heap);
+    idx = cnt;
+    __CFBinaryHeapSetNumBucketsUsed(heap, cnt + 1);
+    __CFBinaryHeapSetCount(heap, cnt + 1);
+    pidx = (idx - 1) >> 1;
+    while (0 < idx) {
+	void *item = heap->_buckets[pidx]._item;
+	if (kCFCompareGreaterThan != heap->_callbacks.compare(item, value, heap->_context.info)) break;
+	CF_WRITE_BARRIER_BASE_ASSIGN(allocator, heap->_buckets, heap->_buckets[idx]._item, item);
+	idx = pidx;
+	pidx = (idx - 1) >> 1;
+    }
+    if (heap->_callbacks.retain) {
+	CF_WRITE_BARRIER_BASE_ASSIGN(allocator, heap->_buckets, heap->_buckets[idx]._item, (void *)heap->_callbacks.retain(allocator, (void *)value));
+    } else {
+	CF_WRITE_BARRIER_BASE_ASSIGN(allocator, heap->_buckets, heap->_buckets[idx]._item, (void *)value);
+    }
+}
+
+void CFBinaryHeapRemoveMinimumValue(CFBinaryHeapRef heap) {
+    void *val;
+    CFIndex idx, cidx;
+    CFIndex cnt;
+    CFAllocatorRef allocator;
+    __CFGenericValidateType(heap, __kCFBinaryHeapTypeID);
+    cnt = __CFBinaryHeapCount(heap);
+    if (0 == cnt) return;
+    idx = 0;
+    __CFBinaryHeapSetNumBucketsUsed(heap, cnt - 1);
+    __CFBinaryHeapSetCount(heap, cnt - 1);
+    allocator = CFGetAllocator(heap);
+    if (heap->_callbacks.release)
+	heap->_callbacks.release(allocator, heap->_buckets[idx]._item);
+    val = heap->_buckets[cnt - 1]._item;
+    cidx = (idx << 1) + 1;
+    while (cidx < __CFBinaryHeapCount(heap)) {
+	void *item = heap->_buckets[cidx]._item;
+	if (cidx + 1 < __CFBinaryHeapCount(heap)) {
+	    void *item2 = heap->_buckets[cidx + 1]._item;
+	    if (kCFCompareGreaterThan == heap->_callbacks.compare(item, item2, heap->_context.info)) {
+		cidx++;
+		item = item2;
+	    }
+	}
+	if (kCFCompareGreaterThan == heap->_callbacks.compare(item, val, heap->_context.info)) break;
+	CF_WRITE_BARRIER_BASE_ASSIGN(allocator, heap->_buckets, heap->_buckets[idx]._item, item);
+	idx = cidx;
+	cidx = (idx << 1) + 1;
+    }
+    CF_WRITE_BARRIER_BASE_ASSIGN(allocator, heap->_buckets, heap->_buckets[idx]._item, val);
+}
+
+void CFBinaryHeapRemoveAllValues(CFBinaryHeapRef heap) {
+    CFIndex idx;
+    CFIndex cnt;
+    __CFGenericValidateType(heap, __kCFBinaryHeapTypeID);
+    cnt = __CFBinaryHeapCount(heap);
+    if (heap->_callbacks.release)
+	for (idx = 0; idx < cnt; idx++)
+	    heap->_callbacks.release(CFGetAllocator(heap), heap->_buckets[idx]._item);
+    __CFBinaryHeapSetNumBucketsUsed(heap, 0);
+    __CFBinaryHeapSetCount(heap, 0);
+}
+
diff --git a/CoreFoundation/CFBinaryHeap.h b/CoreFoundation/CFBinaryHeap.h
new file mode 100644
index 0000000..09cf438
--- /dev/null
+++ b/CoreFoundation/CFBinaryHeap.h
@@ -0,0 +1,319 @@
+/*
+ * Copyright (c) 2008-2009 Brent Fulgham <bfulgham@gmail.org>.  All rights reserved.
+ *
+ * This source code is a modified version of the CoreFoundation sources released by Apple Inc. under
+ * the terms of the APSL version 2.0 (see below).
+ *
+ * For information about changes from the original Apple source release can be found by reviewing the
+ * source control system for the project at https://sourceforge.net/svn/?group_id=246198.
+ *
+ * The original license information is as follows:
+ * 
+ * Copyright (c) 2008 Apple Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*	CFBinaryHeap.h
+	Copyright (c) 1998-2007, Apple Inc. All rights reserved.
+*/
+/*!
+        @header CFBinaryHeap
+        CFBinaryHeap implements a container which stores values sorted using
+        a binary search algorithm.  CFBinaryHeaps can be useful as priority
+	queues.
+*/
+
+#if !defined(__COREFOUNDATION_CFBINARYHEAP__)
+#define __COREFOUNDATION_CFBINARYHEAP__ 1
+
+#include <CoreFoundation/CFBase.h>
+
+CF_EXTERN_C_BEGIN
+
+typedef struct {
+    CFIndex	version;
+    void *	info;
+    const void *(*retain)(const void *info);
+    void	(*release)(const void *info);
+    CFStringRef	(*copyDescription)(const void *info);
+} CFBinaryHeapCompareContext;
+
+/*!
+        @typedef CFBinaryHeapCallBacks
+	Structure containing the callbacks for values of a CFBinaryHeap.
+        @field version The version number of the structure type being passed
+                in as a parameter to the CFBinaryHeap creation functions.
+                This structure is version 0.
+	@field retain The callback used to add a retain for the binary heap
+		on values as they are put into the binary heap.
+		This callback returns the value to use as the value in the
+		binary heap, which is usually the value parameter passed to
+		this callback, but may be a different value if a different
+		value should be added to the binary heap. The binary heap's
+		allocator is passed as the first argument.
+	@field release The callback used to remove a retain previously added
+		for the binary heap from values as they are removed from
+		the binary heap. The binary heap's allocator is passed as the
+		first argument.
+	@field copyDescription The callback used to create a descriptive
+		string representation of each value in the binary heap. This
+		is used by the CFCopyDescription() function.
+	@field compare The callback used to compare values in the binary heap for
+		equality in some operations.
+*/
+typedef struct {
+    CFIndex	version;
+    const void *(*retain)(CFAllocatorRef allocator, const void *ptr);
+    void	(*release)(CFAllocatorRef allocator, const void *ptr);
+    CFStringRef	(*copyDescription)(const void *ptr);
+    CFComparisonResult	(*compare)(const void *ptr1, const void *ptr2, void *context);
+} CFBinaryHeapCallBacks;
+
+/*!
+	@constant kCFStringBinaryHeapCallBacks
+	Predefined CFBinaryHeapCallBacks structure containing a set
+	of callbacks appropriate for use when the values in a CFBinaryHeap
+	are all CFString types.
+*/
+CF_EXPORT const CFBinaryHeapCallBacks kCFStringBinaryHeapCallBacks;
+
+/*!
+	@typedef CFBinaryHeapApplierFunction
+	Type of the callback function used by the apply functions of
+		CFBinaryHeap.
+	@param value The current value from the binary heap.
+	@param context The user-defined context parameter given to the apply
+		function.
+*/
+typedef void (*CFBinaryHeapApplierFunction)(const void *val, void *context);
+
+/*!
+	@typedef CFBinaryHeapRef
+	This is the type of a reference to CFBinaryHeaps.
+*/
+typedef struct __CFBinaryHeap * CFBinaryHeapRef;
+
+/*!
+	@function CFBinaryHeapGetTypeID
+	Returns the type identifier of all CFBinaryHeap instances.
+*/
+CF_EXPORT CFTypeID	CFBinaryHeapGetTypeID(void);
+
+/*!
+	@function CFBinaryHeapCreate
+	Creates a new mutable binary heap with the given values.
+	@param allocator The CFAllocator which should be used to allocate
+		memory for the binary heap and its storage for values. This
+		parameter may be NULL in which case the current default
+		CFAllocator is used. If this reference is not a valid
+		CFAllocator, the behavior is undefined.
+        @param capacity A hint about the number of values that will be held
+                by the CFBinaryHeap. Pass 0 for no hint. The implementation may
+                ignore this hint, or may use it to optimize various
+                operations. A heap's actual capacity is only limited by 
+                address space and available memory constraints). If this 
+                parameter is negative, the behavior is undefined.
+	@param callBacks A pointer to a CFBinaryHeapCallBacks structure
+		initialized with the callbacks for the binary heap to use on
+		each value in the binary heap. A copy of the contents of the
+		callbacks structure is made, so that a pointer to a structure
+		on the stack can be passed in, or can be reused for multiple
+		binary heap creations. If the version field of this callbacks
+		structure is not one of the defined ones for CFBinaryHeap, the
+		behavior is undefined. The retain field may be NULL, in which
+		case the CFBinaryHeap will do nothing to add a retain to values
+		as they are put into the binary heap. The release field may be
+		NULL, in which case the CFBinaryHeap will do nothing to remove
+		the binary heap's retain (if any) on the values when the
+		heap is destroyed or a key-value pair is removed. If the
+		copyDescription field is NULL, the binary heap will create a
+		simple description for a value. If the equal field is NULL, the
+		binary heap will use pointer equality to test for equality of
+		values. This callbacks parameter itself may be NULL, which is
+		treated as if a valid structure of version 0 with all fields
+		NULL had been passed in. Otherwise,
+		if any of the fields are not valid pointers to functions
+		of the correct type, or this parameter is not a valid
+		pointer to a CFBinaryHeapCallBacks callbacks structure,
+		the behavior is undefined. If any of the values put into the
+		binary heap is not one understood by one of the callback functions
+		the behavior when that callback function is used is undefined.
+        @param compareContext A pointer to a CFBinaryHeapCompareContext structure.
+	@result A reference to the new CFBinaryHeap.
+*/
+CF_EXPORT CFBinaryHeapRef	CFBinaryHeapCreate(CFAllocatorRef allocator, CFIndex capacity, const CFBinaryHeapCallBacks *callBacks, const CFBinaryHeapCompareContext *compareContext);
+
+/*!
+	@function CFBinaryHeapCreateCopy
+	Creates a new mutable binary heap with the values from the given binary heap.
+	@param allocator The CFAllocator which should be used to allocate
+		memory for the binary heap and its storage for values. This
+		parameter may be NULL in which case the current default
+		CFAllocator is used. If this reference is not a valid
+		CFAllocator, the behavior is undefined.
+        @param capacity A hint about the number of values that will be held
+                by the CFBinaryHeap. Pass 0 for no hint. The implementation may
+                ignore this hint, or may use it to optimize various
+                operations. A heap's actual capacity is only limited by
+                address space and available memory constraints). 
+                This parameter must be greater than or equal
+                to the count of the heap which is to be copied, or the
+                behavior is undefined. If this parameter is negative, the
+                behavior is undefined.
+	@param heap The binary heap which is to be copied. The values from the
+		binary heap are copied as pointers into the new binary heap (that is,
+		the values themselves are copied, not that which the values
+		point to, if anything). However, the values are also
+		retained by the new binary heap. The count of the new binary will
+		be the same as the given binary heap. The new binary heap uses the same
+		callbacks as the binary heap to be copied. If this parameter is
+		not a valid CFBinaryHeap, the behavior is undefined.
+	@result A reference to the new mutable binary heap.
+*/
+CF_EXPORT CFBinaryHeapRef	CFBinaryHeapCreateCopy(CFAllocatorRef allocator, CFIndex capacity, CFBinaryHeapRef heap);
+
+/*!
+	@function CFBinaryHeapGetCount
+	Returns the number of values currently in the binary heap.
+	@param heap The binary heap to be queried. If this parameter is not a valid
+		CFBinaryHeap, the behavior is undefined.
+	@result The number of values in the binary heap.
+*/
+CF_EXPORT CFIndex	CFBinaryHeapGetCount(CFBinaryHeapRef heap);
+
+/*!
+	@function CFBinaryHeapGetCountOfValue
+	Counts the number of times the given value occurs in the binary heap.
+	@param heap The binary heap to be searched. If this parameter is not a
+		valid CFBinaryHeap, the behavior is undefined.
+	@param value The value for which to find matches in the binary heap. The
+		compare() callback provided when the binary heap was created is
+		used to compare. If the compare() callback was NULL, pointer
+		equality (in C, ==) is used. If value, or any of the values
+		in the binary heap, are not understood by the compare() callback,
+		the behavior is undefined.
+	@result The number of times the given value occurs in the binary heap.
+*/
+CF_EXPORT CFIndex	CFBinaryHeapGetCountOfValue(CFBinaryHeapRef heap, const void *value);
+
+/*!
+	@function CFBinaryHeapContainsValue
+	Reports whether or not the value is in the binary heap.
+	@param heap The binary heap to be searched. If this parameter is not a
+		valid CFBinaryHeap, the behavior is undefined.
+	@param value The value for which to find matches in the binary heap. The
+		compare() callback provided when the binary heap was created is
+		used to compare. If the compare() callback was NULL, pointer
+		equality (in C, ==) is used. If value, or any of the values
+		in the binary heap, are not understood by the compare() callback,
+		the behavior is undefined.
+	@result true, if the value is in the specified binary heap, otherwise false.
+*/
+CF_EXPORT Boolean	CFBinaryHeapContainsValue(CFBinaryHeapRef heap, const void *value);
+
+/*!
+	@function CFBinaryHeapGetMinimum
+	Returns the minimum value is in the binary heap.  If the heap contains several equal
+                minimum values, any one may be returned.
+	@param heap The binary heap to be searched. If this parameter is not a
+		valid CFBinaryHeap, the behavior is undefined.
+	@result A reference to the minimum value in the binary heap, or NULL if the
+                binary heap contains no values.
+*/
+CF_EXPORT const void *	CFBinaryHeapGetMinimum(CFBinaryHeapRef heap);
+
+/*!
+	@function CFBinaryHeapGetMinimumIfPresent
+	Returns the minimum value is in the binary heap, if present.  If the heap contains several equal
+                minimum values, any one may be returned.
+	@param heap The binary heap to be searched. If this parameter is not a
+		valid CFBinaryHeap, the behavior is undefined.
+        @param value A C pointer to pointer-sized storage to be filled with the minimum value in 
+                the binary heap.  If this value is not a valid C pointer to a pointer-sized block
+                of storage, the result is undefined.  If the result of the function is false, the value
+                stored at this address is undefined.
+	@result true, if a minimum value was found in the specified binary heap, otherwise false.
+*/
+CF_EXPORT Boolean	CFBinaryHeapGetMinimumIfPresent(CFBinaryHeapRef heap, const void **value);
+
+/*!
+	@function CFBinaryHeapGetValues
+	Fills the buffer with values from the binary heap.
+	@param heap The binary heap to be queried. If this parameter is not a
+		valid CFBinaryHeap, the behavior is undefined.
+	@param values A C array of pointer-sized values to be filled with
+		values from the binary heap. The values in the C array are ordered
+		from least to greatest. If this parameter is not a valid pointer to a 
+                C array of at least CFBinaryHeapGetCount() pointers, the behavior is undefined.
+*/
+CF_EXPORT void		CFBinaryHeapGetValues(CFBinaryHeapRef heap, const void **values);
+
+/*!
+	@function CFBinaryHeapApplyFunction
+	Calls a function once for each value in the binary heap.
+	@param heap The binary heap to be operated upon. If this parameter is not a
+		valid CFBinaryHeap, the behavior is undefined.
+	@param applier The callback function to call once for each value in
+		the given binary heap. If this parameter is not a
+		pointer to a function of the correct prototype, the behavior
+		is undefined. If there are values in the binary heap which the
+		applier function does not expect or cannot properly apply
+		to, the behavior is undefined. 
+	@param context A pointer-sized user-defined value, which is passed
+		as the second parameter to the applier function, but is
+		otherwise unused by this function. If the context is not
+		what is expected by the applier function, the behavior is
+		undefined.
+*/
+CF_EXPORT void		CFBinaryHeapApplyFunction(CFBinaryHeapRef heap, CFBinaryHeapApplierFunction applier, void *context);
+
+/*!
+	@function CFBinaryHeapAddValue
+	Adds the value to the binary heap.
+	@param heap The binary heap to which the value is to be added. If this parameter is not a
+		valid mutable CFBinaryHeap, the behavior is undefined.
+	@param value The value to add to the binary heap. The value is retained by
+		the binary heap using the retain callback provided when the binary heap
+		was created. If the value is not of the sort expected by the
+		retain callback, the behavior is undefined.
+*/
+CF_EXPORT void		CFBinaryHeapAddValue(CFBinaryHeapRef heap, const void *value);
+
+/*!
+	@function CFBinaryHeapRemoveMinimumValue
+	Removes the minimum value from the binary heap.
+	@param heap The binary heap from which the minimum value is to be removed. If this 
+                parameter is not a valid mutable CFBinaryHeap, the behavior is undefined.
+*/
+CF_EXPORT void		CFBinaryHeapRemoveMinimumValue(CFBinaryHeapRef heap);
+
+/*!
+	@function CFBinaryHeapRemoveAllValues
+	Removes all the values from the binary heap, making it empty.
+	@param heap The binary heap from which all of the values are to be
+		removed. If this parameter is not a valid mutable CFBinaryHeap,
+		the behavior is undefined.
+*/
+CF_EXPORT void		CFBinaryHeapRemoveAllValues(CFBinaryHeapRef heap);
+
+CF_EXTERN_C_END
+
+#endif /* ! __COREFOUNDATION_CFBINARYHEAP__ */
+
diff --git a/CoreFoundation/CFBinaryPList.c b/CoreFoundation/CFBinaryPList.c
new file mode 100644
index 0000000..e284ecb
--- /dev/null
+++ b/CoreFoundation/CFBinaryPList.c
@@ -0,0 +1,1296 @@
+/*
+ * Copyright (c) 2008-2009 Brent Fulgham <bfulgham@gmail.org>.  All rights reserved.
+ * Copyright (c) 2009 Stuart Crook <stuart@echus.demon.co.uk>.  All rights reserved.
+ *
+ * This source code is a modified version of the CoreFoundation sources released by Apple Inc. under
+ * the terms of the APSL version 2.0 (see below).
+ *
+ * For information about changes from the original Apple source release can be found by reviewing the
+ * source control system for the project at https://sourceforge.net/svn/?group_id=246198.
+ *
+ * The original license information is as follows:
+ * 
+ * Copyright (c) 2008 Apple Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*	CFBinaryPList.c
+	Copyright 2000-2002, Apple, Inc. All rights reserved.
+	Responsibility: Christopher Kane
+*/
+
+
+#include <CoreFoundation/CFString.h>
+#include <CoreFoundation/CFNumber.h>
+#include <CoreFoundation/CFDate.h>
+#include <CoreFoundation/CFData.h>
+#include <CoreFoundation/CFArray.h>
+#include <CoreFoundation/CFDictionary.h>
+#include <CoreFoundation/CFSet.h>
+#include <CoreFoundation/CFPropertyList.h>
+#include <CoreFoundation/CFByteOrder.h>
+#include <CoreFoundation/CFRuntime.h>
+#include <CoreFoundation/CFStream.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <limits.h>
+#include <string.h>
+#include "CFInternal.h"
+
+typedef struct {
+    int64_t high;
+    uint64_t low;
+} CFSInt128Struct;
+
+enum {
+    kCFNumberSInt128Type = 17
+};
+
+extern CFNumberType _CFNumberGetType2(CFNumberRef number);
+
+enum {
+	CF_NO_ERROR = 0,
+	CF_OVERFLOW_ERROR = (1 << 0),
+};
+
+CF_INLINE uint32_t __check_uint32_add_unsigned_unsigned(uint32_t x, uint32_t y, int32_t* err) {
+   if((UINT_MAX - y) < x)
+        *err = *err | CF_OVERFLOW_ERROR;
+   return x + y;
+};
+
+CF_INLINE uint64_t __check_uint64_add_unsigned_unsigned(uint64_t x, uint64_t y, int32_t* err) {
+   if((ULLONG_MAX - y) < x)
+        *err = *err | CF_OVERFLOW_ERROR;
+   return x + y;
+};
+
+CF_INLINE uint32_t __check_uint32_mul_unsigned_unsigned(uint32_t x, uint32_t y, int32_t* err) {
+   uint64_t tmp = (uint64_t) x * (uint64_t) y;
+   /* If any of the upper 32 bits touched, overflow */
+   if(tmp & 0xffffffff00000000ULL)
+        *err = *err | CF_OVERFLOW_ERROR;
+   return (uint32_t) tmp;
+};
+
+CF_INLINE uint64_t __check_uint64_mul_unsigned_unsigned(uint64_t x, uint64_t y, int32_t* err) {
+  if(x == 0) return 0;
+  if(ULLONG_MAX/x < y)
+     *err = *err | CF_OVERFLOW_ERROR;
+  return x * y;
+};
+
+#if __LP64__
+#define check_ptr_add(p, a, err)	(const uint8_t *)__check_uint64_add_unsigned_unsigned((uintptr_t)p, (uintptr_t)a, err)
+#define check_size_t_mul(b, a, err)	(size_t)__check_uint64_mul_unsigned_unsigned((size_t)b, (size_t)a, err)
+#else
+#define check_ptr_add(p, a, err)	(const uint8_t *)__check_uint32_add_unsigned_unsigned((uintptr_t)p, (uintptr_t)a, err)
+#define check_size_t_mul(b, a, err)	(size_t)__check_uint32_mul_unsigned_unsigned((size_t)b, (size_t)a, err)
+#endif
+
+
+CF_INLINE CFTypeID __CFGenericTypeID_genericobj_inline(const void *cf) {
+    CFTypeID typeID = (*(uint32_t *)(((CFRuntimeBase *)cf)->_cfinfo) >> 8) & 0xFFFF;
+    return CF_IS_OBJC(typeID, cf) ? CFGetTypeID(cf) : typeID;
+}
+
+struct __CFKeyedArchiverUID {
+    CFRuntimeBase _base;
+    uint32_t _value;
+};
+
+static CFStringRef __CFKeyedArchiverUIDCopyDescription(CFTypeRef cf) {
+    CFKeyedArchiverUIDRef uid = (CFKeyedArchiverUIDRef)cf;
+    return CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("<CFKeyedArchiverUID %p [%p]>{value = %u}"), cf, CFGetAllocator(cf), uid->_value);
+}
+
+static CFStringRef __CFKeyedArchiverUIDCopyFormattingDescription(CFTypeRef cf, CFDictionaryRef formatOptions) {
+    CFKeyedArchiverUIDRef uid = (CFKeyedArchiverUIDRef)cf;
+    return CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("@%u@"), uid->_value);
+}
+
+static CFTypeID __kCFKeyedArchiverUIDTypeID = _kCFRuntimeNotATypeID;
+
+static const CFRuntimeClass __CFKeyedArchiverUIDClass = {
+    0,
+    "CFKeyedArchiverUID",
+    NULL,	// init
+    NULL,	// copy
+    NULL,	// finalize
+    NULL,	// equal -- pointer equality only
+    NULL,	// hash -- pointer hashing only
+    __CFKeyedArchiverUIDCopyFormattingDescription,
+    __CFKeyedArchiverUIDCopyDescription
+};
+
+__private_extern__ void __CFKeyedArchiverUIDInitialize(void) {
+    __kCFKeyedArchiverUIDTypeID = _CFRuntimeRegisterClass(&__CFKeyedArchiverUIDClass);
+}
+
+CFTypeID _CFKeyedArchiverUIDGetTypeID(void) {
+    return __kCFKeyedArchiverUIDTypeID;
+}
+
+CFKeyedArchiverUIDRef _CFKeyedArchiverUIDCreate(CFAllocatorRef allocator, uint32_t value) {
+    CFKeyedArchiverUIDRef uid;
+    uid = (CFKeyedArchiverUIDRef)_CFRuntimeCreateInstance(allocator, __kCFKeyedArchiverUIDTypeID, sizeof(struct __CFKeyedArchiverUID) - sizeof(CFRuntimeBase), NULL);
+    if (NULL == uid) {
+	return NULL;
+    }
+    ((struct __CFKeyedArchiverUID *)uid)->_value = value;
+    return uid;
+}
+
+
+uint32_t _CFKeyedArchiverUIDGetValue(CFKeyedArchiverUIDRef uid) {
+    return uid->_value;
+}
+
+
+typedef struct {
+    CFTypeRef stream;
+    CFTypeRef error;
+    uint64_t written;
+    int32_t used;
+    bool streamIsData;
+    uint8_t buffer[8192 - 32];
+} __CFBinaryPlistWriteBuffer;
+
+static void writeBytes(__CFBinaryPlistWriteBuffer *buf, const UInt8 *bytes, CFIndex length) {
+    if (0 == length) return;
+    if (buf->error) return;
+    if (buf->streamIsData) {
+        CFDataAppendBytes((CFMutableDataRef)buf->stream, bytes, length);
+        buf->written += length;
+    } else {
+        /* SystemConfiguration relies on being able to serialize a plist to a write stream.
+         * There seems no reason why this isn't supported. The old code read:
+        CFAssert(false, __kCFLogAssertion, "Streams are not supported on this platform");
+         */
+        CFIndex lengthWritten = CFWriteStreamWrite((CFWriteStreamRef)buf->stream, bytes, length);
+        buf->written += lengthWritten;
+    }
+}
+
+static void bufferWrite(__CFBinaryPlistWriteBuffer *buf, const uint8_t *buffer, CFIndex count) {
+    if (0 == count) return;
+    if ((CFIndex)sizeof(buf->buffer) <= count) {
+	writeBytes(buf, buf->buffer, buf->used);
+	buf->used = 0;
+	writeBytes(buf, buffer, count);
+	return;
+    }
+    CFIndex copyLen = __CFMin(count, (CFIndex)sizeof(buf->buffer) - buf->used);
+    memmove(buf->buffer + buf->used, buffer, copyLen);
+    buf->used += copyLen;
+    if (sizeof(buf->buffer) == buf->used) {
+	writeBytes(buf, buf->buffer, sizeof(buf->buffer));
+	memmove(buf->buffer, buffer + copyLen, count - copyLen);
+	buf->used = count - copyLen;
+    }
+}
+
+static void bufferFlush(__CFBinaryPlistWriteBuffer *buf) {
+    writeBytes(buf, buf->buffer, buf->used);
+    buf->used = 0;
+}
+
+/*
+HEADER
+	magic number ("bplist")
+	file format version
+
+OBJECT TABLE
+	variable-sized objects
+
+	Object Formats (marker byte followed by additional info in some cases)
+	null	0000 0000
+	bool	0000 1000			// false
+	bool	0000 1001			// true
+	fill	0000 1111			// fill byte
+	int	0001 nnnn	...		// # of bytes is 2^nnnn, big-endian bytes
+	real	0010 nnnn	...		// # of bytes is 2^nnnn, big-endian bytes
+	date	0011 0011	...		// 8 byte float follows, big-endian bytes
+	data	0100 nnnn	[int]	...	// nnnn is number of bytes unless 1111 then int count follows, followed by bytes
+	string	0101 nnnn	[int]	...	// ASCII string, nnnn is # of chars, else 1111 then int count, then bytes
+	string	0110 nnnn	[int]	...	// Unicode string, nnnn is # of chars, else 1111 then int count, then big-endian 2-byte uint16_t
+		0111 xxxx			// unused
+	uid	1000 nnnn	...		// nnnn+1 is # of bytes
+		1001 xxxx			// unused
+	array	1010 nnnn	[int]	objref*	// nnnn is count, unless '1111', then int count follows
+		1011 xxxx			// unused
+	set	1100 nnnn	[int]	objref* // nnnn is count, unless '1111', then int count follows
+	dict	1101 nnnn	[int]	keyref* objref*	// nnnn is count, unless '1111', then int count follows
+		1110 xxxx			// unused
+		1111 xxxx			// unused
+
+OFFSET TABLE
+	list of ints, byte size of which is given in trailer
+	-- these are the byte offsets into the file
+	-- number of these is in the trailer
+
+TRAILER
+	byte size of offset ints in offset table
+	byte size of object refs in arrays and dicts
+	number of offsets in offset table (also is number of objects)
+	element # in offset table which is top level object
+	offset table offset
+
+*/
+
+
+static CFTypeID stringtype = -1, datatype = -1, numbertype = -1, datetype = -1;
+static CFTypeID booltype = -1, nulltype = -1, dicttype = -1, arraytype = -1, settype = -1;
+
+static void _appendInt(__CFBinaryPlistWriteBuffer *buf, uint64_t bigint) {
+    uint8_t marker;
+    uint8_t *bytes;
+    CFIndex nbytes;
+    if (bigint <= (uint64_t)0xff) {
+	nbytes = 1;
+	marker = kCFBinaryPlistMarkerInt | 0;
+    } else if (bigint <= (uint64_t)0xffff) {
+	nbytes = 2;
+	marker = kCFBinaryPlistMarkerInt | 1;
+    } else if (bigint <= (uint64_t)0xffffffff) {
+	nbytes = 4;
+	marker = kCFBinaryPlistMarkerInt | 2;
+    } else {
+	nbytes = 8;
+	marker = kCFBinaryPlistMarkerInt | 3;
+    }
+    bigint = CFSwapInt64HostToBig(bigint);
+    bytes = (uint8_t *)&bigint + sizeof(bigint) - nbytes;
+    bufferWrite(buf, &marker, 1);
+    bufferWrite(buf, bytes, nbytes);
+}
+
+static void _appendUID(__CFBinaryPlistWriteBuffer *buf, CFKeyedArchiverUIDRef uid) {
+    uint8_t marker;
+    uint8_t *bytes;
+    CFIndex nbytes;
+    uint64_t bigint = _CFKeyedArchiverUIDGetValue(uid);
+    if (bigint <= (uint64_t)0xff) {
+	nbytes = 1;
+    } else if (bigint <= (uint64_t)0xffff) {
+	nbytes = 2;
+    } else if (bigint <= (uint64_t)0xffffffff) {
+	nbytes = 4;
+    } else {
+	nbytes = 8;
+    }
+    marker = kCFBinaryPlistMarkerUID | (uint8_t)(nbytes - 1);
+    bigint = CFSwapInt64HostToBig(bigint);
+    bytes = (uint8_t *)&bigint + sizeof(bigint) - nbytes;
+    bufferWrite(buf, &marker, 1);
+    bufferWrite(buf, bytes, nbytes);
+}
+
+static Boolean __plistNumberEqual(CFTypeRef cf1, CFTypeRef cf2) {
+    // As long as this equals function is more restrictive than the
+    // existing one, for any given type, the hash function need not
+    // also be provided for the uniquing set.
+    if (CFNumberIsFloatType((CFNumberRef)cf1) != CFNumberIsFloatType((CFNumberRef)cf2)) return false;
+    return CFEqual(cf1, cf2);
+}
+
+static CFHashCode __plistDataHash(CFTypeRef cf) {
+    CFDataRef data = (CFDataRef)cf;
+    return CFHashBytes((UInt8 *)CFDataGetBytePtr(data), __CFMin(CFDataGetLength(data), 1280));
+}
+
+static void _flattenPlist(CFPropertyListRef plist, CFMutableArrayRef objlist, CFMutableDictionaryRef objtable, CFMutableSetRef uniquingsets[]) {
+    CFPropertyListRef unique;
+    uint32_t refnum;
+    CFTypeID type = __CFGenericTypeID_genericobj_inline(plist);
+    CFIndex idx;
+    CFPropertyListRef *list, buffer[256];
+
+    // Do not unique dictionaries or arrays, because: they
+    // are slow to compare, and have poor hash codes.
+    // Uniquing bools is unnecessary.
+    int which = -1;
+    if (stringtype == type) {
+	which = 0;
+    } else if (numbertype == type) {
+	which = 1;
+    } else if (datetype == type) {
+	which = 2;
+    } else if (datatype == type) {
+	which = 3;
+    }
+    if (1 && -1 != which) {
+	CFMutableSetRef uniquingset = uniquingsets[which];
+	CFIndex before = CFSetGetCount(uniquingset);
+	CFSetAddValue(uniquingset, plist);
+	CFIndex after = CFSetGetCount(uniquingset);
+	if (after == before) {	// already in set
+	    unique = CFSetGetValue(uniquingset, plist);
+	    if (unique != plist) {
+		refnum = (uint32_t)(uintptr_t)CFDictionaryGetValue(objtable, unique);
+		CFDictionaryAddValue(objtable, plist, (const void *)(uintptr_t)refnum);
+	    }
+	    return;
+	}
+    }
+    refnum = CFArrayGetCount(objlist);
+    CFArrayAppendValue(objlist, plist);
+    CFDictionaryAddValue(objtable, plist, (const void *)(uintptr_t)refnum);
+    if (dicttype == type) {
+	CFIndex count = CFDictionaryGetCount((CFDictionaryRef)plist);
+	list = (count <= 128) ? buffer : (CFPropertyListRef *)CFAllocatorAllocate(kCFAllocatorSystemDefault, 2 * count * sizeof(CFTypeRef), 0);
+        CFDictionaryGetKeysAndValues((CFDictionaryRef)plist, list, list + count);
+        for (idx = 0; idx < 2 * count; idx++) {
+            _flattenPlist(list[idx], objlist, objtable, uniquingsets);
+        }
+        if (list != buffer) CFAllocatorDeallocate(kCFAllocatorSystemDefault, list);
+    } else if (arraytype == type) {
+	CFIndex count = CFArrayGetCount((CFArrayRef)plist);
+	list = (count <= 256) ? buffer : (CFPropertyListRef *)CFAllocatorAllocate(kCFAllocatorSystemDefault, count * sizeof(CFTypeRef), 0);
+        CFArrayGetValues((CFArrayRef)plist, CFRangeMake(0, count), list);
+        for (idx = 0; idx < count; idx++) {
+            _flattenPlist(list[idx], objlist, objtable, uniquingsets);
+        }
+        if (list != buffer) CFAllocatorDeallocate(kCFAllocatorSystemDefault, list);
+    }
+}
+
+// stream must be a CFMutableDataRef
+CFIndex __CFBinaryPlistWriteToStream(CFPropertyListRef plist, CFTypeRef stream) {
+    CFMutableDictionaryRef objtable;
+    CFMutableArrayRef objlist;
+    CFBinaryPlistTrailer trailer;
+    uint64_t *offsets, length_so_far;
+    uint64_t mask, refnum;
+    int64_t idx, idx2, cnt;
+    __CFBinaryPlistWriteBuffer *buf;
+
+    if ((CFTypeID)-1 == stringtype) {
+	stringtype = CFStringGetTypeID();
+    }
+    if ((CFTypeID)-1 == datatype) {
+	datatype = CFDataGetTypeID();
+    }
+    if ((CFTypeID)-1 == numbertype) {
+	numbertype = CFNumberGetTypeID();
+    }
+    if ((CFTypeID)-1 == booltype) {
+	booltype = CFBooleanGetTypeID();
+    }
+    if ((CFTypeID)-1 == datetype) {
+	datetype = CFDateGetTypeID();
+    }
+    if ((CFTypeID)-1 == dicttype) {
+	dicttype = CFDictionaryGetTypeID();
+    }
+    if ((CFTypeID)-1 == arraytype) {
+	arraytype = CFArrayGetTypeID();
+    }
+    if ((CFTypeID)-1 == settype) {
+	settype = CFSetGetTypeID();
+    }
+    if ((CFTypeID)-1 == nulltype) {
+	nulltype = CFNullGetTypeID();
+    }
+
+    objtable = CFDictionaryCreateMutable(kCFAllocatorSystemDefault, 0, NULL, NULL);
+    _CFDictionarySetCapacity(objtable, 640);
+    objlist = CFArrayCreateMutable(kCFAllocatorSystemDefault, 0, NULL);
+    _CFArraySetCapacity(objlist, 640);
+    CFSetCallBacks cb = kCFTypeSetCallBacks;
+    cb.retain = NULL;
+    cb.release = NULL;
+    CFMutableSetRef uniquingsets[4];
+    uniquingsets[0] = CFSetCreateMutable(kCFAllocatorSystemDefault, 0, &cb);
+    _CFSetSetCapacity(uniquingsets[0], 1000);
+    cb.equal = __plistNumberEqual;
+    uniquingsets[1] = CFSetCreateMutable(kCFAllocatorSystemDefault, 0, &cb);
+    _CFSetSetCapacity(uniquingsets[1], 500);
+    cb.equal = kCFTypeSetCallBacks.equal;
+    uniquingsets[2] = CFSetCreateMutable(kCFAllocatorSystemDefault, 0, &cb);
+    _CFSetSetCapacity(uniquingsets[2], 500);
+    cb.hash = __plistDataHash;
+    uniquingsets[3] = CFSetCreateMutable(kCFAllocatorSystemDefault, 0, &cb);
+    _CFSetSetCapacity(uniquingsets[3], 500);
+
+    _flattenPlist(plist, objlist, objtable, uniquingsets);
+
+    CFRelease(uniquingsets[0]);
+    CFRelease(uniquingsets[1]);
+    CFRelease(uniquingsets[2]);
+    CFRelease(uniquingsets[3]);
+
+    cnt = CFArrayGetCount(objlist);
+    offsets = (uint64_t *)CFAllocatorAllocate(kCFAllocatorSystemDefault, (CFIndex)(cnt * sizeof(*offsets)), 0);
+
+    buf = (__CFBinaryPlistWriteBuffer *)CFAllocatorAllocate(kCFAllocatorSystemDefault, sizeof(__CFBinaryPlistWriteBuffer), 0);
+    buf->stream = stream;
+    buf->error = NULL;
+    buf->streamIsData = (CFGetTypeID(stream) == CFDataGetTypeID());
+    buf->written = 0;
+    buf->used = 0;
+    bufferWrite(buf, (uint8_t *)"bplist00", 8);	// header
+
+    memset(&trailer, 0, sizeof(trailer));
+    trailer._numObjects = CFSwapInt64HostToBig(cnt);
+    trailer._topObject = 0;	// true for this implementation
+    mask = ~(uint64_t)0;
+    while (cnt & mask) {
+	trailer._objectRefSize++;
+	mask = mask << 8;
+    }
+
+    for (idx = 0; idx < cnt; idx++) {
+	CFPropertyListRef obj = CFArrayGetValueAtIndex(objlist, (CFIndex)idx);
+	CFTypeID type = __CFGenericTypeID_genericobj_inline(obj);
+	offsets[idx] = buf->written + buf->used;
+	if (stringtype == type) {
+	    CFIndex ret, count = CFStringGetLength((CFStringRef)obj);
+	    CFIndex needed;
+	    uint8_t *bytes, buffer[1024];
+	    bytes = (count <= 1024) ? buffer : (uint8_t *)CFAllocatorAllocate(kCFAllocatorSystemDefault, count, 0);
+	    // presumption, believed to be true, is that ASCII encoding may need
+	    // less bytes, but will not need greater, than the # of unichars
+	    ret = CFStringGetBytes((CFStringRef)obj, CFRangeMake(0, count), kCFStringEncodingASCII, 0, false, bytes, count, &needed);
+	    if (ret == count) {
+		uint8_t marker = (uint8_t)(kCFBinaryPlistMarkerASCIIString | (needed < 15 ? needed : 0xf));
+		bufferWrite(buf, &marker, 1);
+		if (15 <= needed) {
+		    _appendInt(buf, (uint64_t)needed);
+		}
+		bufferWrite(buf, bytes, needed);
+	    } else {
+		UniChar *chars;
+		uint8_t marker = (uint8_t)(kCFBinaryPlistMarkerUnicode16String | (count < 15 ? count : 0xf));
+		bufferWrite(buf, &marker, 1);
+		if (15 <= count) {
+		    _appendInt(buf, (uint64_t)count);
+		}
+		chars = (UniChar *)CFAllocatorAllocate(kCFAllocatorSystemDefault, count * sizeof(UniChar), 0);
+		CFStringGetCharacters((CFStringRef)obj, CFRangeMake(0, count), chars);
+		for (idx2 = 0; idx2 < count; idx2++) {
+		    chars[idx2] = CFSwapInt16HostToBig(chars[idx2]);
+		}
+		bufferWrite(buf, (uint8_t *)chars, count * sizeof(UniChar));
+		CFAllocatorDeallocate(kCFAllocatorSystemDefault, chars);
+	    }
+	    if (bytes != buffer) CFAllocatorDeallocate(kCFAllocatorSystemDefault, bytes);
+	} else if (numbertype == type) {
+	    uint8_t marker;
+	    uint64_t bigint;
+	    uint8_t *bytes;
+	    CFIndex nbytes;
+	    if (CFNumberIsFloatType((CFNumberRef)obj)) {
+		CFSwappedFloat64 swapped64;
+		CFSwappedFloat32 swapped32;
+		if (CFNumberGetByteSize((CFNumberRef)obj) <= (CFIndex)sizeof(float)) {
+		    float v;
+		    CFNumberGetValue((CFNumberRef)obj, kCFNumberFloat32Type, &v);
+		    swapped32 = CFConvertFloat32HostToSwapped(v);
+		    bytes = (uint8_t *)&swapped32;
+		    nbytes = sizeof(float);
+		    marker = kCFBinaryPlistMarkerReal | 2;
+		} else {
+		    double v;
+		    CFNumberGetValue((CFNumberRef)obj, kCFNumberFloat64Type, &v);
+		    swapped64 = CFConvertFloat64HostToSwapped(v);
+		    bytes = (uint8_t *)&swapped64;
+		    nbytes = sizeof(double);
+		    marker = kCFBinaryPlistMarkerReal | 3;
+		}
+		bufferWrite(buf, &marker, 1);
+		bufferWrite(buf, bytes, nbytes);
+	    } else {
+		CFNumberType type = _CFNumberGetType2((CFNumberRef)obj);
+		if (kCFNumberSInt128Type == type) {
+		    CFSInt128Struct s;
+		    CFNumberGetValue((CFNumberRef)obj, kCFNumberSInt128Type, &s);
+		    struct {
+			int64_t high;
+			uint64_t low;
+		    } storage;
+		    storage.high = CFSwapInt64HostToBig(s.high);
+		    storage.low = CFSwapInt64HostToBig(s.low);
+		    uint8_t *bytes = (uint8_t *)&storage;
+		    uint8_t marker = kCFBinaryPlistMarkerInt | 4;
+		    CFIndex nbytes = 16;
+		    bufferWrite(buf, &marker, 1);
+		    bufferWrite(buf, bytes, nbytes);
+		} else {
+		    CFNumberGetValue((CFNumberRef)obj, kCFNumberSInt64Type, &bigint);
+		    _appendInt(buf, bigint);
+		}
+	    }
+	} else if (_CFKeyedArchiverUIDGetTypeID() == type) {
+	    _appendUID(buf, (CFKeyedArchiverUIDRef)obj);
+	} else if (booltype == type) {
+	    uint8_t marker = CFBooleanGetValue((CFBooleanRef)obj) ? kCFBinaryPlistMarkerTrue : kCFBinaryPlistMarkerFalse;
+	    bufferWrite(buf, &marker, 1);
+	} else if (datatype == type) {
+	    CFIndex count = CFDataGetLength((CFDataRef)obj);
+	    uint8_t marker = (uint8_t)(kCFBinaryPlistMarkerData | (count < 15 ? count : 0xf));
+	    bufferWrite(buf, &marker, 1);
+	    if (15 <= count) {
+		_appendInt(buf, (uint64_t)count);
+	    }
+	    bufferWrite(buf, CFDataGetBytePtr((CFDataRef)obj), count);
+	} else if (datetype == type) {
+	    CFSwappedFloat64 swapped;
+	    uint8_t marker = kCFBinaryPlistMarkerDate;
+	    bufferWrite(buf, &marker, 1);
+	    swapped = CFConvertFloat64HostToSwapped(CFDateGetAbsoluteTime((CFDateRef)obj));
+	    bufferWrite(buf, (uint8_t *)&swapped, sizeof(swapped));
+	} else if (dicttype == type) {
+	    CFIndex count = CFDictionaryGetCount((CFDictionaryRef)obj);
+	    CFPropertyListRef *list, buffer[512];
+	    uint8_t marker = (uint8_t)(kCFBinaryPlistMarkerDict | (count < 15 ? count : 0xf));
+	    bufferWrite(buf, &marker, 1);
+	    if (15 <= count) {
+		_appendInt(buf, (uint64_t)count);
+	    }
+	    list = (count <= 256) ? buffer : (CFPropertyListRef *)CFAllocatorAllocate(kCFAllocatorSystemDefault, 2 * count * sizeof(CFTypeRef), 0);
+	    CFDictionaryGetKeysAndValues((CFDictionaryRef)obj, list, list + count);
+	    for (idx2 = 0; idx2 < 2 * count; idx2++) {
+		CFPropertyListRef value = list[idx2];
+		uint32_t swapped = 0;
+		uint8_t *source = (uint8_t *)&swapped;
+                refnum = (uint32_t)(uintptr_t)CFDictionaryGetValue(objtable, value);
+                swapped = CFSwapInt32HostToBig((uint32_t)refnum);
+		bufferWrite(buf, source + sizeof(swapped) - trailer._objectRefSize, trailer._objectRefSize);
+	    }
+	    if (list != buffer) CFAllocatorDeallocate(kCFAllocatorSystemDefault, list);
+	} else if (arraytype == type) {
+	    CFIndex count = CFArrayGetCount((CFArrayRef)obj);
+	    CFPropertyListRef *list, buffer[256];
+	    uint8_t marker = (uint8_t)(kCFBinaryPlistMarkerArray | (count < 15 ? count : 0xf));
+	    bufferWrite(buf, &marker, 1);
+	    if (15 <= count) {
+		_appendInt(buf, (uint64_t)count);
+	    }
+	    list = (count <= 256) ? buffer : (CFPropertyListRef *)CFAllocatorAllocate(kCFAllocatorSystemDefault, count * sizeof(CFTypeRef), 0);
+	    CFArrayGetValues((CFArrayRef)obj, CFRangeMake(0, count), list);
+	    for (idx2 = 0; idx2 < count; idx2++) {
+		CFPropertyListRef value = list[idx2];
+		uint32_t swapped = 0;
+		uint8_t *source = (uint8_t *)&swapped;
+                refnum = (uint32_t)(uintptr_t)CFDictionaryGetValue(objtable, value);
+                swapped = CFSwapInt32HostToBig((uint32_t)refnum);
+		bufferWrite(buf, source + sizeof(swapped) - trailer._objectRefSize, trailer._objectRefSize);
+	    }
+	    if (list != buffer) CFAllocatorDeallocate(kCFAllocatorSystemDefault, list);
+	} else {
+	    CFRelease(objtable);
+	    CFRelease(objlist);
+	    if (buf->error) CFRelease(buf->error);
+	    CFAllocatorDeallocate(kCFAllocatorSystemDefault, buf);
+            CFAllocatorDeallocate(kCFAllocatorSystemDefault, offsets);
+	    return 0;
+	}
+    }
+    CFRelease(objtable);
+    CFRelease(objlist);
+
+    length_so_far = buf->written + buf->used;
+    trailer._offsetTableOffset = CFSwapInt64HostToBig(length_so_far);
+    trailer._offsetIntSize = 0;
+    mask = ~(uint64_t)0;
+    while (length_so_far & mask) {
+	trailer._offsetIntSize++;
+	mask = mask << 8;
+    }
+
+    for (idx = 0; idx < cnt; idx++) {
+	uint64_t swapped = CFSwapInt64HostToBig(offsets[idx]);
+	uint8_t *source = (uint8_t *)&swapped;
+	bufferWrite(buf, source + sizeof(*offsets) - trailer._offsetIntSize, trailer._offsetIntSize);
+    }
+    length_so_far += cnt * trailer._offsetIntSize;
+
+    bufferWrite(buf, (uint8_t *)&trailer, sizeof(trailer));
+    bufferFlush(buf);
+    length_so_far += sizeof(trailer);
+    if (buf->error) {
+	CFRelease(buf->error);
+	return 0;
+    }
+    CFAllocatorDeallocate(kCFAllocatorSystemDefault, buf);
+    CFAllocatorDeallocate(kCFAllocatorSystemDefault, offsets);
+    return (CFIndex)length_so_far;
+}
+
+
+#define FAIL_FALSE	do { return false; } while (0)
+#define FAIL_MAXOFFSET	do { return UINT64_MAX; } while (0)
+
+bool __CFBinaryPlistGetTopLevelInfo(const uint8_t *databytes, uint64_t datalen, uint8_t *marker, uint64_t *offset, CFBinaryPlistTrailer *trailer) {
+    CFBinaryPlistTrailer trail;
+
+    if ((CFTypeID)-1 == stringtype) {
+	stringtype = CFStringGetTypeID();
+    }
+    if ((CFTypeID)-1 == datatype) {
+	datatype = CFDataGetTypeID();
+    }
+    if ((CFTypeID)-1 == numbertype) {
+	numbertype = CFNumberGetTypeID();
+    }
+    if ((CFTypeID)-1 == booltype) {
+	booltype = CFBooleanGetTypeID();
+    }
+    if ((CFTypeID)-1 == datetype) {
+	datetype = CFDateGetTypeID();
+    }
+    if ((CFTypeID)-1 == dicttype) {
+	dicttype = CFDictionaryGetTypeID();
+    }
+    if ((CFTypeID)-1 == arraytype) {
+	arraytype = CFArrayGetTypeID();
+    }
+    if ((CFTypeID)-1 == settype) {
+	settype = CFSetGetTypeID();
+    }
+    if ((CFTypeID)-1 == nulltype) {
+	nulltype = CFNullGetTypeID();
+    }
+
+    if (!databytes || datalen < sizeof(trail) + 8 + 1) FAIL_FALSE;
+    if (0 != memcmp("bplist00", databytes, 8) && 0 != memcmp("bplist01", databytes, 8)) return false;
+    memmove(&trail, databytes + datalen - sizeof(trail), sizeof(trail));
+    if (trail._unused[0] != 0 || trail._unused[1] != 0 || trail._unused[2] != 0 || trail._unused[3] != 0 || trail._unused[4] != 0 || trail._unused[5] != 0) FAIL_FALSE;
+    trail._numObjects = CFSwapInt64BigToHost(trail._numObjects);
+    trail._topObject = CFSwapInt64BigToHost(trail._topObject);
+    trail._offsetTableOffset = CFSwapInt64BigToHost(trail._offsetTableOffset);
+    if (LONG_MAX < trail._numObjects) FAIL_FALSE;
+    if (LONG_MAX < trail._offsetTableOffset) FAIL_FALSE;
+    if (trail._numObjects < 1) FAIL_FALSE;
+    if (trail._numObjects <= trail._topObject) FAIL_FALSE;
+    if (trail._offsetTableOffset < 9) FAIL_FALSE;
+    if (datalen - sizeof(trail) <= trail._offsetTableOffset) FAIL_FALSE;
+    if (trail._offsetIntSize < 1) FAIL_FALSE;
+    if (trail._objectRefSize < 1) FAIL_FALSE;
+    int32_t err = CF_NO_ERROR;
+    uint64_t offsetIntSize = trail._offsetIntSize;
+    uint64_t offsetTableSize = __check_uint64_mul_unsigned_unsigned(trail._numObjects, offsetIntSize, &err);
+    if (CF_NO_ERROR!= err) FAIL_FALSE;
+    if (offsetTableSize < 1) FAIL_FALSE;
+    uint64_t objectDataSize = trail._offsetTableOffset - 8;
+    uint64_t tmpSum = __check_uint64_add_unsigned_unsigned(8, objectDataSize, &err);
+    tmpSum = __check_uint64_add_unsigned_unsigned(tmpSum, offsetTableSize, &err);
+    tmpSum = __check_uint64_add_unsigned_unsigned(tmpSum, sizeof(trail), &err);
+    if (CF_NO_ERROR != err) FAIL_FALSE;
+    if (datalen != tmpSum) FAIL_FALSE;
+    if (trail._objectRefSize < 8 && (1ULL << (8 * trail._objectRefSize)) <= trail._numObjects) FAIL_FALSE;
+    if (trail._offsetIntSize < 8 && (1ULL << (8 * trail._offsetIntSize)) <= trail._offsetTableOffset) FAIL_FALSE;
+    const uint8_t *objectsFirstByte;
+    objectsFirstByte = check_ptr_add(databytes, 8, &err);
+    if (CF_NO_ERROR != err) FAIL_FALSE;
+    const uint8_t *offsetsFirstByte = check_ptr_add(databytes, trail._offsetTableOffset, &err);
+    if (CF_NO_ERROR != err) FAIL_FALSE;
+    const uint8_t *offsetsLastByte;
+    offsetsLastByte = check_ptr_add(offsetsFirstByte, offsetTableSize - 1, &err);
+    if (CF_NO_ERROR != err) FAIL_FALSE;
+
+    const uint8_t *bytesptr = databytes + trail._offsetTableOffset;
+    uint64_t maxOffset = trail._offsetTableOffset - 1;
+    for (CFIndex idx = 0; idx < trail._numObjects; idx++) {
+	uint64_t off = 0;
+	for (CFIndex idx2 = 0; idx2 < trail._offsetIntSize; idx2++) {
+	    off = (off << 8) + bytesptr[idx2];
+	}
+	if (maxOffset < off) FAIL_FALSE;
+	bytesptr += trail._offsetIntSize;
+    }
+
+    bytesptr = databytes + trail._offsetTableOffset + trail._topObject * trail._offsetIntSize;
+    uint64_t off = 0;
+    for (CFIndex idx = 0; idx < trail._offsetIntSize; idx++) {
+	off = (off << 8) + bytesptr[idx];
+    }
+    if (off < 8 || trail._offsetTableOffset <= off) FAIL_FALSE;
+    if (trailer) *trailer = trail;
+    if (offset) *offset = off;
+    if (marker) *marker = *(databytes + off);
+    return true;
+}
+
+CF_INLINE Boolean _plistIsPrimitive(CFPropertyListRef pl) {
+    CFTypeID type = __CFGenericTypeID_genericobj_inline(pl);
+    if (dicttype == type || arraytype == type || settype == type) FAIL_FALSE;
+    return true;
+}
+
+CF_INLINE bool _readInt(const uint8_t *ptr, const uint8_t *end_byte_ptr, uint64_t *bigint, const uint8_t **newptr) {
+    if (end_byte_ptr < ptr) FAIL_FALSE;
+    uint8_t marker = *ptr++;
+    if ((marker & 0xf0) != kCFBinaryPlistMarkerInt) FAIL_FALSE;
+    uint64_t cnt = 1 << (marker & 0x0f);
+    int32_t err = CF_NO_ERROR;
+    const uint8_t *extent = check_ptr_add(ptr, cnt, &err) - 1;
+    if (CF_NO_ERROR != err) FAIL_FALSE;
+    if (end_byte_ptr < extent) FAIL_FALSE;
+    // integers are not required to be in the most compact possible representation, but only the last 64 bits are significant currently
+    *bigint = 0;
+    for (CFIndex idx = 0; idx < cnt; idx++) {
+        *bigint = (*bigint << 8) + *ptr++;
+    }
+    if (newptr) *newptr = ptr;
+    return true;
+}
+
+// bytesptr points at a ref
+CF_INLINE uint64_t _getOffsetOfRefAt(const uint8_t *databytes, const uint8_t *bytesptr, const CFBinaryPlistTrailer *trailer) {
+    // *trailer contents are trusted, even for overflows -- was checked when the trailer was parsed;
+    // this pointer arithmetic and the multiplication was also already done once and checked,
+    // and the offsetTable was already validated.
+    const uint8_t *objectsFirstByte = databytes + 8;
+    const uint8_t *offsetsFirstByte = databytes + trailer->_offsetTableOffset;
+    if (bytesptr < objectsFirstByte || offsetsFirstByte - trailer->_objectRefSize < bytesptr) FAIL_MAXOFFSET;
+
+    uint64_t ref = 0;
+    for (CFIndex idx = 0; idx < trailer->_objectRefSize; idx++) {
+	ref = (ref << 8) + bytesptr[idx];
+    }
+    if (trailer->_numObjects <= ref) FAIL_MAXOFFSET;
+
+    bytesptr = databytes + trailer->_offsetTableOffset + ref * trailer->_offsetIntSize;
+    uint64_t off = 0;
+    for (CFIndex idx = 0; idx < trailer->_offsetIntSize; idx++) {
+	off = (off << 8) + bytesptr[idx];
+    }
+    return off;
+}
+
+static bool __CFBinaryPlistCreateObject2(const uint8_t *databytes, uint64_t datalen, uint64_t startOffset, const CFBinaryPlistTrailer *trailer, CFAllocatorRef allocator, CFOptionFlags mutabilityOption, CFMutableDictionaryRef objects, CFMutableSetRef set, CFIndex curDepth, CFPropertyListRef *plist);
+
+bool __CFBinaryPlistGetOffsetForValueFromArray2(const uint8_t *databytes, uint64_t datalen, uint64_t startOffset, const CFBinaryPlistTrailer *trailer, CFIndex idx, uint64_t *offset, CFMutableDictionaryRef objects) {
+    uint64_t objectsRangeStart = 8, objectsRangeEnd = trailer->_offsetTableOffset - 1;
+    if (startOffset < objectsRangeStart || objectsRangeEnd < startOffset) FAIL_FALSE;
+    const uint8_t *ptr = databytes + startOffset;
+    uint8_t marker = *ptr;
+    if ((marker & 0xf0) != kCFBinaryPlistMarkerArray) FAIL_FALSE;
+    int32_t err = CF_NO_ERROR;
+    ptr = check_ptr_add(ptr, 1, &err);
+    if (CF_NO_ERROR != err) FAIL_FALSE;
+    uint64_t cnt = (marker & 0x0f);
+    if (0xf == cnt) {
+	uint64_t bigint;
+	if (!_readInt(ptr, databytes + objectsRangeEnd, &bigint, &ptr)) FAIL_FALSE;
+	if (LONG_MAX < bigint) FAIL_FALSE;
+	cnt = bigint;
+    }
+    if (cnt <= idx) FAIL_FALSE;
+    size_t byte_cnt = check_size_t_mul(cnt, trailer->_objectRefSize, &err);
+    if (CF_NO_ERROR != err) FAIL_FALSE;
+    const uint8_t *extent = check_ptr_add(ptr, byte_cnt, &err) - 1;
+    if (CF_NO_ERROR != err) FAIL_FALSE;
+    if (databytes + objectsRangeEnd < extent) FAIL_FALSE;
+    uint64_t off = _getOffsetOfRefAt(databytes, ptr + idx * trailer->_objectRefSize, trailer);
+    if (offset) *offset = off;
+    return true;
+}
+
+bool __CFBinaryPlistGetOffsetForValueFromDictionary2(const uint8_t *databytes, uint64_t datalen, uint64_t startOffset, const CFBinaryPlistTrailer *trailer, CFTypeRef key, uint64_t *koffset, uint64_t *voffset, CFMutableDictionaryRef objects) {
+    if (!key || !_plistIsPrimitive(key)) FAIL_FALSE;
+    uint64_t objectsRangeStart = 8, objectsRangeEnd = trailer->_offsetTableOffset - 1;
+    if (startOffset < objectsRangeStart || objectsRangeEnd < startOffset) FAIL_FALSE;
+    const uint8_t *ptr = databytes + startOffset;
+    uint8_t marker = *ptr;
+    if ((marker & 0xf0) != kCFBinaryPlistMarkerDict) FAIL_FALSE;
+    int32_t err = CF_NO_ERROR;
+    ptr = check_ptr_add(ptr, 1, &err);
+    if (CF_NO_ERROR != err) FAIL_FALSE;
+    uint64_t cnt = (marker & 0x0f);
+    if (0xf == cnt) {
+	uint64_t bigint = 0;
+	if (!_readInt(ptr, databytes + objectsRangeEnd, &bigint, &ptr)) FAIL_FALSE;
+	if (LONG_MAX < bigint) FAIL_FALSE;
+	cnt = bigint;
+    }
+    cnt = check_size_t_mul(cnt, 2, &err);
+    if (CF_NO_ERROR != err) FAIL_FALSE;
+    size_t byte_cnt = check_size_t_mul(cnt, trailer->_objectRefSize, &err);
+    if (CF_NO_ERROR != err) FAIL_FALSE;
+    const uint8_t *extent = check_ptr_add(ptr, byte_cnt, &err) - 1;
+    if (CF_NO_ERROR != err) FAIL_FALSE;
+    if (databytes + objectsRangeEnd < extent) FAIL_FALSE;
+    CFIndex stringKeyLen = -1;
+    UniChar ubuffer[16];
+    if (__CFGenericTypeID_genericobj_inline(key) == stringtype) {
+	stringKeyLen = CFStringGetLength((CFStringRef)key);
+	if (stringKeyLen < 0xf) {
+	    CFStringGetCharacters((CFStringRef)key, CFRangeMake(0, stringKeyLen), ubuffer);
+	}
+    }
+    cnt = cnt / 2;
+    for (CFIndex idx = 0; idx < cnt; idx++) {
+	uint64_t off = _getOffsetOfRefAt(databytes, ptr, trailer);
+	uint8_t marker = *(databytes + off);
+	CFIndex len = marker & 0x0f;
+	// if it is a short ascii string in the data, and the key is a string
+	if ((marker & 0xf0) == kCFBinaryPlistMarkerASCIIString && len < 0xf && stringKeyLen != -1) {
+	    if (len != stringKeyLen) goto miss;
+	    err = CF_NO_ERROR;
+	    const uint8_t *ptr2 = databytes + off;
+	    extent = check_ptr_add(ptr2, len, &err);
+	    if (CF_NO_ERROR != err) FAIL_FALSE;
+	    if (databytes + trailer->_offsetTableOffset <= extent) FAIL_FALSE;
+            for (CFIndex idx2 = 0; idx2 < stringKeyLen; idx2++) {
+                if ((UniChar)ptr2[idx2 + 1] != ubuffer[idx2]) goto miss;
+            }
+	    if (koffset) *koffset = off;
+	    if (voffset) {
+		off = _getOffsetOfRefAt(databytes, ptr + cnt * trailer->_objectRefSize, trailer);
+		*voffset = off;
+	    }
+	    return true;
+	    miss:;
+	} else {
+	    CFPropertyListRef pl = NULL;
+	    if (!__CFBinaryPlistCreateObject2(databytes, datalen, off, trailer, kCFAllocatorSystemDefault, kCFPropertyListImmutable, objects, NULL, 0, &pl) || !_plistIsPrimitive(pl)) {
+		if (pl) CFRelease(pl);
+		FAIL_FALSE;
+	    }
+	    if (CFEqual(key, pl)) {
+		CFRelease(pl);
+		if (koffset) *koffset = off;
+		if (voffset) {
+		    off = _getOffsetOfRefAt(databytes, ptr + cnt * trailer->_objectRefSize, trailer);
+		    *voffset = off;
+		}
+		return true;
+	    }
+	    CFRelease(pl);
+	}
+	ptr += trailer->_objectRefSize;
+    }
+    return false;
+}
+
+extern CFArrayRef _CFArrayCreate_ex(CFAllocatorRef allocator, Boolean isMutable, const void **values, CFIndex numValues);
+extern CFSetRef _CFSetCreate_ex(CFAllocatorRef allocator, Boolean isMutable, const void **values, CFIndex numValues);
+extern CFDictionaryRef _CFDictionaryCreate_ex(CFAllocatorRef allocator, Boolean isMutable, const void **keys, const void **values, CFIndex numValues);
+
+static bool __CFBinaryPlistCreateObject2(const uint8_t *databytes, uint64_t datalen, uint64_t startOffset, const CFBinaryPlistTrailer *trailer, CFAllocatorRef allocator, CFOptionFlags mutabilityOption, CFMutableDictionaryRef objects, CFMutableSetRef set, CFIndex curDepth, CFPropertyListRef *plist) {
+
+    if (objects) {
+	*plist = CFDictionaryGetValue(objects, (const void *)(uintptr_t)startOffset);
+	if (*plist) {
+	    CFRetain(*plist);
+	    return true;
+	}
+    }
+
+    // at any one invocation of this function, set should contain the offsets in the "path" down to this object
+    if (set && CFSetContainsValue(set, (const void *)(uintptr_t)startOffset)) return false;
+
+    // databytes is trusted to be at least datalen bytes long
+    // *trailer contents are trusted, even for overflows -- was checked when the trailer was parsed
+    uint64_t objectsRangeStart = 8, objectsRangeEnd = trailer->_offsetTableOffset - 1;
+    if (startOffset < objectsRangeStart || objectsRangeEnd < startOffset) FAIL_FALSE;
+
+    uint64_t off;
+    CFPropertyListRef *list, buffer[256];
+    CFAllocatorRef listAllocator;
+
+    uint8_t marker = *(databytes + startOffset);
+    switch (marker & 0xf0) {
+    case kCFBinaryPlistMarkerNull:
+	switch (marker) {
+	case kCFBinaryPlistMarkerNull:
+	    *plist = kCFNull;
+	    return true;
+	case kCFBinaryPlistMarkerFalse:
+	    *plist = CFRetain(kCFBooleanFalse);
+	    return true;
+	case kCFBinaryPlistMarkerTrue:
+	    *plist = CFRetain(kCFBooleanTrue);
+	    return true;
+	}
+	FAIL_FALSE;
+    case kCFBinaryPlistMarkerInt:
+    {
+	const uint8_t *ptr = (databytes + startOffset);
+	int32_t err = CF_NO_ERROR;
+	ptr = check_ptr_add(ptr, 1, &err);
+	if (CF_NO_ERROR != err) FAIL_FALSE;
+	uint64_t cnt = 1 << (marker & 0x0f);
+	const uint8_t *extent = check_ptr_add(ptr, cnt, &err) - 1;
+	if (CF_NO_ERROR != err) FAIL_FALSE;
+	if (databytes + objectsRangeEnd < extent) FAIL_FALSE;
+	if (16 < cnt) FAIL_FALSE;
+	// in format version '00', 1, 2, and 4-byte integers have to be interpreted as unsigned,
+	// whereas 8-byte integers are signed (and 16-byte when available)
+	// negative 1, 2, 4-byte integers are always emitted as 8 bytes in format '00'
+	uint64_t bigint = 0;
+	// integers are not required to be in the most compact possible representation, but only the last 64 bits are significant currently
+	for (CFIndex idx = 0; idx < cnt; idx++) {
+	    bigint = (bigint << 8) + *ptr++;
+	}
+	if (8 < cnt) {
+	    CFSInt128Struct val;
+	    val.high = 0;
+	    val.low = bigint;
+	    *plist = CFNumberCreate(allocator, kCFNumberSInt128Type, &val);
+	} else {
+	    *plist = CFNumberCreate(allocator, kCFNumberSInt64Type, &bigint);
+	}
+	// these are always immutable
+	if (objects && *plist) {
+	    CFDictionarySetValue(objects, (const void *)(uintptr_t)startOffset, *plist);
+	}
+	return (*plist) ? true : false;
+    }
+    case kCFBinaryPlistMarkerReal:
+	switch (marker & 0x0f) {
+	case 2: {
+	    const uint8_t *ptr = (databytes + startOffset);
+	    int32_t err = CF_NO_ERROR;
+	    ptr = check_ptr_add(ptr, 1, &err);
+	    if (CF_NO_ERROR != err) FAIL_FALSE;
+	    const uint8_t *extent = check_ptr_add(ptr, 4, &err) - 1;
+	    if (CF_NO_ERROR != err) FAIL_FALSE;
+	    if (databytes + objectsRangeEnd < extent) FAIL_FALSE;
+	    CFSwappedFloat32 swapped32;
+	    memmove(&swapped32, ptr, 4);
+	    float f = CFConvertFloat32SwappedToHost(swapped32);
+	    *plist = CFNumberCreate(allocator, kCFNumberFloat32Type, &f);
+	    // these are always immutable
+	    if (objects && *plist) {
+		CFDictionarySetValue(objects, (const void *)(uintptr_t)startOffset, *plist);
+	    }
+	    return (*plist) ? true : false;
+	}
+	case 3: {
+	    const uint8_t *ptr = (databytes + startOffset);
+	    int32_t err = CF_NO_ERROR;
+	    ptr = check_ptr_add(ptr, 1, &err);
+	    if (CF_NO_ERROR != err) FAIL_FALSE;
+	    const uint8_t *extent = check_ptr_add(ptr, 8, &err) - 1;
+	    if (CF_NO_ERROR != err) FAIL_FALSE;
+	    if (databytes + objectsRangeEnd < extent) FAIL_FALSE;
+	    CFSwappedFloat64 swapped64;
+	    memmove(&swapped64, ptr, 8);
+	    double d = CFConvertFloat64SwappedToHost(swapped64);
+	    *plist = CFNumberCreate(allocator, kCFNumberFloat64Type, &d);
+	    // these are always immutable
+	    if (objects && *plist) {
+		CFDictionarySetValue(objects, (const void *)(uintptr_t)startOffset, *plist);
+	    }
+	    return (*plist) ? true : false;
+	}
+	}
+	FAIL_FALSE;
+    case kCFBinaryPlistMarkerDate & 0xf0:
+	switch (marker) {
+	case kCFBinaryPlistMarkerDate: {
+	    const uint8_t *ptr = (databytes + startOffset);
+	    int32_t err = CF_NO_ERROR;
+	    ptr = check_ptr_add(ptr, 1, &err);
+	    if (CF_NO_ERROR != err) FAIL_FALSE;
+	    const uint8_t *extent = check_ptr_add(ptr, 8, &err) - 1;
+	    if (CF_NO_ERROR != err) FAIL_FALSE;
+	    if (databytes + objectsRangeEnd < extent) FAIL_FALSE;
+	    CFSwappedFloat64 swapped64;
+	    memmove(&swapped64, ptr, 8);
+	    double d = CFConvertFloat64SwappedToHost(swapped64);
+	    *plist = CFDateCreate(allocator, d);
+	    // these are always immutable
+	    if (objects && *plist) {
+		CFDictionarySetValue(objects, (const void *)(uintptr_t)startOffset, *plist);
+	    }
+	    return (*plist) ? true : false;
+	}
+	}
+	FAIL_FALSE;
+    case kCFBinaryPlistMarkerData: {
+	const uint8_t *ptr = databytes + startOffset;
+	int32_t err = CF_NO_ERROR;
+	ptr = check_ptr_add(ptr, 1, &err);
+	if (CF_NO_ERROR != err) FAIL_FALSE;
+	CFIndex cnt = marker & 0x0f;
+	if (0xf == cnt) {
+	    uint64_t bigint = 0;
+	    if (!_readInt(ptr, databytes + objectsRangeEnd, &bigint, &ptr)) FAIL_FALSE;
+	    if (LONG_MAX < bigint) FAIL_FALSE;
+	    cnt = (CFIndex)bigint;
+	}
+	const uint8_t *extent = check_ptr_add(ptr, cnt, &err) - 1;
+	if (CF_NO_ERROR != err) FAIL_FALSE;
+	if (databytes + objectsRangeEnd < extent) FAIL_FALSE;
+	if (mutabilityOption == kCFPropertyListMutableContainersAndLeaves) {
+	    *plist = CFDataCreateMutable(allocator, 0);
+	    if (*plist) CFDataAppendBytes((CFMutableDataRef)*plist, ptr, cnt);
+	} else {
+	    *plist = CFDataCreate(allocator, ptr, cnt);
+	}
+        if (objects && *plist && (mutabilityOption != kCFPropertyListMutableContainersAndLeaves)) {
+	    CFDictionarySetValue(objects, (const void *)(uintptr_t)startOffset, *plist);
+	}
+	return (*plist) ? true : false;
+	}
+    case kCFBinaryPlistMarkerASCIIString: {
+	const uint8_t *ptr = databytes + startOffset;
+	int32_t err = CF_NO_ERROR;
+	ptr = check_ptr_add(ptr, 1, &err);
+	if (CF_NO_ERROR != err) FAIL_FALSE;
+	CFIndex cnt = marker & 0x0f;
+	if (0xf == cnt) {
+            uint64_t bigint = 0;
+	    if (!_readInt(ptr, databytes + objectsRangeEnd, &bigint, &ptr)) FAIL_FALSE;
+	    if (LONG_MAX < bigint) FAIL_FALSE;
+	    cnt = (CFIndex)bigint;
+	}
+	const uint8_t *extent = check_ptr_add(ptr, cnt, &err) - 1;
+	if (CF_NO_ERROR != err) FAIL_FALSE;
+	if (databytes + objectsRangeEnd < extent) FAIL_FALSE;
+	if (mutabilityOption == kCFPropertyListMutableContainersAndLeaves) {
+	    CFStringRef str = CFStringCreateWithBytes(allocator, ptr, cnt, kCFStringEncodingASCII, false);
+	    *plist = str ? CFStringCreateMutableCopy(allocator, 0, str) : NULL;
+	    if (str) CFRelease(str);
+	} else {
+	    *plist = CFStringCreateWithBytes(allocator, ptr, cnt, kCFStringEncodingASCII, false);
+	}
+        if (objects && *plist && (mutabilityOption != kCFPropertyListMutableContainersAndLeaves)) {
+	    CFDictionarySetValue(objects, (const void *)(uintptr_t)startOffset, *plist);
+	}
+	return (*plist) ? true : false;
+	}
+    case kCFBinaryPlistMarkerUnicode16String: {
+	const uint8_t *ptr = databytes + startOffset;
+	int32_t err = CF_NO_ERROR;
+	ptr = check_ptr_add(ptr, 1, &err);
+	if (CF_NO_ERROR != err) FAIL_FALSE;
+	CFIndex cnt = marker & 0x0f;
+	if (0xf == cnt) {
+            uint64_t bigint = 0;
+	    if (!_readInt(ptr, databytes + objectsRangeEnd, &bigint, &ptr)) FAIL_FALSE;
+	    if (LONG_MAX < bigint) FAIL_FALSE;
+	    cnt = (CFIndex)bigint;
+	}
+	const uint8_t *extent = check_ptr_add(ptr, cnt, &err) - 1;
+	extent = check_ptr_add(extent, cnt, &err);	// 2 bytes per character
+	if (CF_NO_ERROR != err) FAIL_FALSE;
+	if (databytes + objectsRangeEnd < extent) FAIL_FALSE;
+	size_t byte_cnt = check_size_t_mul(cnt, sizeof(UniChar), &err);
+	if (CF_NO_ERROR != err) FAIL_FALSE;
+	UniChar *chars = (UniChar *)CFAllocatorAllocate(allocator, byte_cnt, 0);
+	if (!chars) FAIL_FALSE;
+	memmove(chars, ptr, byte_cnt);
+	for (CFIndex idx = 0; idx < cnt; idx++) {
+	    chars[idx] = CFSwapInt16BigToHost(chars[idx]);
+	}
+	if (mutabilityOption == kCFPropertyListMutableContainersAndLeaves) {
+	    CFStringRef str = CFStringCreateWithCharactersNoCopy(allocator, chars, cnt, allocator);
+	    *plist = str ? CFStringCreateMutableCopy(allocator, 0, str) : NULL;
+	    if (str) CFRelease(str);
+	} else {
+	    *plist = CFStringCreateWithCharactersNoCopy(allocator, chars, cnt, allocator);
+	}
+        if (objects && *plist && (mutabilityOption != kCFPropertyListMutableContainersAndLeaves)) {
+	    CFDictionarySetValue(objects, (const void *)(uintptr_t)startOffset, *plist);
+	}
+	return (*plist) ? true : false;
+	}
+    case kCFBinaryPlistMarkerUID: {
+	const uint8_t *ptr = databytes + startOffset;
+	int32_t err = CF_NO_ERROR;
+	ptr = check_ptr_add(ptr, 1, &err);
+	if (CF_NO_ERROR != err) FAIL_FALSE;
+	CFIndex cnt = (marker & 0x0f) + 1;
+	const uint8_t *extent = check_ptr_add(ptr, cnt, &err) - 1;
+	if (CF_NO_ERROR != err) FAIL_FALSE;
+	if (databytes + objectsRangeEnd < extent) FAIL_FALSE;
+	// uids are not required to be in the most compact possible representation, but only the last 64 bits are significant currently
+	uint64_t bigint = 0;
+	for (CFIndex idx = 0; idx < cnt; idx++) {
+	    bigint = (bigint << 8) + *ptr++;
+	}
+	if (UINT32_MAX < bigint) FAIL_FALSE;
+	*plist = _CFKeyedArchiverUIDCreate(allocator, (uint32_t)bigint);
+	// these are always immutable
+	if (objects && *plist) {
+	    CFDictionarySetValue(objects, (const void *)(uintptr_t)startOffset, *plist);
+	}
+	return (*plist) ? true : false;
+	}
+    case kCFBinaryPlistMarkerArray:
+    case kCFBinaryPlistMarkerSet: {
+	const uint8_t *ptr = databytes + startOffset;
+	int32_t err = CF_NO_ERROR;
+	ptr = check_ptr_add(ptr, 1, &err);
+	if (CF_NO_ERROR != err) FAIL_FALSE;
+	CFIndex cnt = marker & 0x0f;
+	if (0xf == cnt) {
+	    uint64_t bigint = 0;
+	    if (!_readInt(ptr, databytes + objectsRangeEnd, &bigint, &ptr)) FAIL_FALSE;
+	    if (LONG_MAX < bigint) FAIL_FALSE;
+	    cnt = (CFIndex)bigint;
+	}
+	size_t byte_cnt = check_size_t_mul(cnt, trailer->_objectRefSize, &err);
+	if (CF_NO_ERROR != err) FAIL_FALSE;
+	const uint8_t *extent = check_ptr_add(ptr, byte_cnt, &err) - 1;
+	if (CF_NO_ERROR != err) FAIL_FALSE;
+	if (databytes + objectsRangeEnd < extent) FAIL_FALSE;
+	byte_cnt = check_size_t_mul(cnt, sizeof(CFPropertyListRef), &err);
+	if (CF_NO_ERROR != err) FAIL_FALSE;
+	list = (cnt <= 256) ? buffer : (CFPropertyListRef *)CFAllocatorAllocate(kCFAllocatorSystemDefault, byte_cnt, __kCFAllocatorGCScannedMemory);
+	listAllocator = (list == buffer ? kCFAllocatorNull : kCFAllocatorSystemDefault);
+	if (!list) FAIL_FALSE;
+	Boolean madeSet = false;
+	if (!set && 15 < curDepth) {
+	    set = CFSetCreateMutable(kCFAllocatorSystemDefault, 0, NULL);
+	    madeSet = set ? true : false;
+	}
+	if (set) CFSetAddValue(set, (const void *)(uintptr_t)startOffset);
+	for (CFIndex idx = 0; idx < cnt; idx++) {
+	    CFPropertyListRef pl;
+	    off = _getOffsetOfRefAt(databytes, ptr, trailer);
+	    if (!__CFBinaryPlistCreateObject2(databytes, datalen, off, trailer, allocator, mutabilityOption, objects, set, curDepth + 1, &pl)) {
+		if (!CF_IS_COLLECTABLE_ALLOCATOR(allocator)) {
+		    while (idx--) {
+			CFRelease(list[idx]);
+		    }
+		}
+		if (list != buffer) CFAllocatorDeallocate(kCFAllocatorSystemDefault, list);
+		FAIL_FALSE;
+	    }
+	    if (CF_IS_COLLECTABLE_ALLOCATOR(allocator)) {
+		CF_WRITE_BARRIER_BASE_ASSIGN(listAllocator, list, list[idx], CFMakeCollectable(pl));
+	    } else {
+		list[idx] = pl;
+	    }
+	    ptr += trailer->_objectRefSize;
+	}
+	if (set) CFSetRemoveValue(set, (const void *)(uintptr_t)startOffset);
+	if (madeSet) {
+	    CFRelease(set);
+	    set = NULL;
+	}
+	if ((marker & 0xf0) == kCFBinaryPlistMarkerArray) {
+	    *plist = _CFArrayCreate_ex(allocator, (mutabilityOption != kCFPropertyListImmutable), list, cnt);
+	} else {
+	    *plist = _CFSetCreate_ex(allocator, (mutabilityOption != kCFPropertyListImmutable), list, cnt);
+	}
+	if (objects && *plist && (mutabilityOption == kCFPropertyListImmutable)) {
+	    CFDictionarySetValue(objects, (const void *)(uintptr_t)startOffset, *plist);
+	}
+	if (list != buffer) CFAllocatorDeallocate(kCFAllocatorSystemDefault, list);
+	return (*plist) ? true : false;
+	}
+    case kCFBinaryPlistMarkerDict: {
+	const uint8_t *ptr = databytes + startOffset;
+	int32_t err = CF_NO_ERROR;
+	ptr = check_ptr_add(ptr, 1, &err);
+	if (CF_NO_ERROR != err) FAIL_FALSE;
+	CFIndex cnt = marker & 0x0f;
+	if (0xf == cnt) {
+	    uint64_t bigint = 0;
+	    if (!_readInt(ptr, databytes + objectsRangeEnd, &bigint, &ptr)) FAIL_FALSE;
+	    if (LONG_MAX < bigint) FAIL_FALSE;
+	    cnt = (CFIndex)bigint;
+	}
+	cnt = (CFIndex)check_size_t_mul(cnt, 2, &err);
+	if (CF_NO_ERROR != err) FAIL_FALSE;
+	size_t byte_cnt = check_size_t_mul(cnt, trailer->_objectRefSize, &err);
+	if (CF_NO_ERROR != err) FAIL_FALSE;
+	const uint8_t *extent = check_ptr_add(ptr, byte_cnt, &err) - 1;
+	if (CF_NO_ERROR != err) FAIL_FALSE;
+	if (databytes + objectsRangeEnd < extent) FAIL_FALSE;
+	byte_cnt = check_size_t_mul(cnt, sizeof(CFPropertyListRef), &err);
+	if (CF_NO_ERROR != err) FAIL_FALSE;
+	list = (cnt <= 256) ? buffer : (CFPropertyListRef *)CFAllocatorAllocate(kCFAllocatorSystemDefault, byte_cnt, __kCFAllocatorGCScannedMemory);
+	listAllocator = (list == buffer ? kCFAllocatorNull : kCFAllocatorSystemDefault);
+	if (!list) FAIL_FALSE;
+	Boolean madeSet = false;
+	if (!set && 15 < curDepth) {
+	    set = CFSetCreateMutable(kCFAllocatorSystemDefault, 0, NULL);
+	    madeSet = set ? true : false;
+	}
+	if (set) CFSetAddValue(set, (const void *)(uintptr_t)startOffset);
+	for (CFIndex idx = 0; idx < cnt; idx++) {
+	    CFPropertyListRef pl = NULL;
+	    off = _getOffsetOfRefAt(databytes, ptr, trailer);
+	    if (!__CFBinaryPlistCreateObject2(databytes, datalen, off, trailer, allocator, mutabilityOption, objects, set, curDepth + 1, &pl) || (idx < cnt / 2 && !_plistIsPrimitive(pl))) {
+		if (!CF_IS_COLLECTABLE_ALLOCATOR(allocator)) {
+		    if (pl) CFRelease(pl);
+		    while (idx--) {
+			CFRelease(list[idx]);
+		    }
+		}
+		if (list != buffer) CFAllocatorDeallocate(kCFAllocatorSystemDefault, list);
+		FAIL_FALSE;
+	    }
+	    if (CF_IS_COLLECTABLE_ALLOCATOR(allocator)) {
+		CF_WRITE_BARRIER_BASE_ASSIGN(listAllocator, list, list[idx], CFMakeCollectable(pl));
+	    } else {
+		list[idx] = pl;
+	    }
+	    ptr += trailer->_objectRefSize;
+	}
+	if (set) CFSetRemoveValue(set, (const void *)(uintptr_t)startOffset);
+	if (madeSet) {
+	    CFRelease(set);
+	    set = NULL;
+	}
+	*plist = _CFDictionaryCreate_ex(allocator, (mutabilityOption != kCFPropertyListImmutable), list, list + cnt / 2, cnt / 2);
+	if (objects && *plist && (mutabilityOption == kCFPropertyListImmutable)) {
+	    CFDictionarySetValue(objects, (const void *)(uintptr_t)startOffset, *plist);
+	}
+	if (list != buffer) CFAllocatorDeallocate(kCFAllocatorSystemDefault, list);
+	return (*plist) ? true : false;
+	}
+    }
+    FAIL_FALSE;
+}
+
+bool __CFBinaryPlistCreateObject(const uint8_t *databytes, uint64_t datalen, uint64_t startOffset, const CFBinaryPlistTrailer *trailer, CFAllocatorRef allocator, CFOptionFlags mutabilityOption, CFMutableDictionaryRef objects, CFPropertyListRef *plist) {
+	// for compatibility with Foundation's use, need to leave this here
+    return __CFBinaryPlistCreateObject2(databytes, datalen, startOffset, trailer, allocator, mutabilityOption, objects, NULL, 0, plist);
+}
+
+__private_extern__ bool __CFTryParseBinaryPlist(CFAllocatorRef allocator, CFDataRef data, CFOptionFlags option, CFPropertyListRef *plist, CFStringRef *errorString) {
+    uint8_t marker;    
+    CFBinaryPlistTrailer trailer;
+    uint64_t offset;
+    const uint8_t *databytes = CFDataGetBytePtr(data);
+    uint64_t datalen = CFDataGetLength(data);
+
+    if (8 <= datalen && __CFBinaryPlistGetTopLevelInfo(databytes, datalen, &marker, &offset, &trailer)) {
+	// FALSE: We know for binary plist parsing that the result objects will be retained
+	// by their containing collections as the parsing proceeds, so we do not need
+	// to use retaining callbacks for the objects map in this case. WHY: the file might
+	// be malformed and contain hash-equal keys for the same dictionary (for example)
+	// and the later key will cause the previous one to be released when we set the second
+	// in the dictionary.
+	CFMutableDictionaryRef objects = CFDictionaryCreateMutable(kCFAllocatorSystemDefault, 0, NULL, &kCFTypeDictionaryValueCallBacks);
+	_CFDictionarySetCapacity(objects, 4000);
+	CFPropertyListRef pl = NULL;
+        if (__CFBinaryPlistCreateObject2(databytes, datalen, offset, &trailer, allocator, option, objects, NULL, 0, &pl)) {
+	    if (plist) *plist = pl;
+        } else {
+	    if (plist) *plist = NULL;
+            if (errorString) *errorString = (CFStringRef)CFRetain(CFSTR("binary data is corrupt"));
+	}
+	CFRelease(objects);
+        return true;
+    }
+    return false;
+}
+
diff --git a/CoreFoundation/CFBitVector.c b/CoreFoundation/CFBitVector.c
new file mode 100644
index 0000000..56a477f
--- /dev/null
+++ b/CoreFoundation/CFBitVector.c
@@ -0,0 +1,556 @@
+/*
+ * Copyright (c) 2008-2009 Brent Fulgham <bfulgham@gmail.org>.  All rights reserved.
+ *
+ * This source code is a modified version of the CoreFoundation sources released by Apple Inc. under
+ * the terms of the APSL version 2.0 (see below).
+ *
+ * For information about changes from the original Apple source release can be found by reviewing the
+ * source control system for the project at https://sourceforge.net/svn/?group_id=246198.
+ *
+ * The original license information is as follows:
+ * 
+ * Copyright (c) 2008 Apple Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*	CFBitVector.c
+	Copyright 1998-2002, Apple, Inc. All rights reserved.
+	Responsibility: Christopher Kane
+*/
+
+#include <CoreFoundation/CFBitVector.h>
+#include "CFInternal.h"
+#include <string.h>
+
+/* The bucket type must be unsigned, at least one byte in size, and
+   a power of 2 in number of bits; bits are numbered from 0 from left
+   to right (bit 0 is the most significant) */
+typedef uint8_t __CFBitVectorBucket;
+
+enum {
+    __CF_BITS_PER_BYTE = 8
+};
+
+enum {
+    __CF_BITS_PER_BUCKET = (__CF_BITS_PER_BYTE * sizeof(__CFBitVectorBucket))
+};
+
+CF_INLINE CFIndex __CFBitVectorRoundUpCapacity(CFIndex capacity) {
+    return ((capacity + 63) / 64) * 64;
+}
+
+CF_INLINE CFIndex __CFBitVectorNumBucketsForCapacity(CFIndex capacity) {
+    return (capacity + __CF_BITS_PER_BUCKET - 1) / __CF_BITS_PER_BUCKET;
+}
+
+struct __CFBitVector {
+    CFRuntimeBase _base;
+    CFIndex _count;	/* number of bits */
+    CFIndex _capacity;	/* maximum number of bits */
+    __CFBitVectorBucket *_buckets;
+};
+
+CF_INLINE UInt32 __CFBitVectorMutableVariety(const void *cf) {
+    return __CFBitfieldGetValue(((const CFRuntimeBase *)cf)->_cfinfo[CF_INFO_BITS], 3, 2);
+}
+
+CF_INLINE void __CFBitVectorSetMutableVariety(void *cf, UInt32 v) {
+    __CFBitfieldSetValue(((CFRuntimeBase *)cf)->_cfinfo[CF_INFO_BITS], 3, 2, v);
+}
+
+CF_INLINE UInt32 __CFBitVectorMutableVarietyFromFlags(UInt32 flags) {
+    return __CFBitfieldGetValue(flags, 1, 0);
+}
+
+// ensure that uses of these inlines are correct, bytes vs. buckets vs. bits
+CF_INLINE CFIndex __CFBitVectorCount(CFBitVectorRef bv) {
+    return bv->_count;
+}
+
+CF_INLINE void __CFBitVectorSetCount(CFMutableBitVectorRef bv, CFIndex v) {
+    bv->_count = v;
+}
+
+CF_INLINE CFIndex __CFBitVectorCapacity(CFBitVectorRef bv) {
+    return bv->_capacity;
+}
+
+CF_INLINE void __CFBitVectorSetCapacity(CFMutableBitVectorRef bv, CFIndex v) {
+    bv->_capacity = v;
+}
+
+CF_INLINE CFIndex __CFBitVectorNumBucketsUsed(CFBitVectorRef bv) {
+    return bv->_count / __CF_BITS_PER_BUCKET + 1;
+}
+
+CF_INLINE void __CFBitVectorSetNumBucketsUsed(CFMutableBitVectorRef bv, CFIndex v) {
+    /* for a CFBitVector, _bucketsUsed == _count / __CF_BITS_PER_BUCKET + 1 */
+}
+
+CF_INLINE CFIndex __CFBitVectorNumBuckets(CFBitVectorRef bv) {
+    return bv->_capacity / __CF_BITS_PER_BUCKET + 1;
+}
+
+CF_INLINE void __CFBitVectorSetNumBuckets(CFMutableBitVectorRef bv, CFIndex v) {
+    /* for a CFBitVector, _bucketsNum == _capacity / __CF_BITS_PER_BUCKET + 1 */
+}
+
+static __CFBitVectorBucket __CFBitBucketMask(CFIndex bottomBit, CFIndex topBit) {
+    CFIndex shiftL = __CF_BITS_PER_BUCKET - topBit + bottomBit - 1;
+    __CFBitVectorBucket result = ~(__CFBitVectorBucket)0;
+    result = (result << shiftL);
+    result = (result >> bottomBit);
+    return result;
+}
+
+CF_INLINE CFBit __CFBitVectorBit(__CFBitVectorBucket *buckets, CFIndex idx) {
+    CFIndex bucketIdx = idx / __CF_BITS_PER_BUCKET;
+    CFIndex bitOfBucket = idx & (__CF_BITS_PER_BUCKET - 1);
+    return (buckets[bucketIdx] >> (__CF_BITS_PER_BUCKET - 1 - bitOfBucket)) & 0x1;
+}
+
+CF_INLINE void __CFSetBitVectorBit(__CFBitVectorBucket *buckets, CFIndex idx, CFBit value) {
+    CFIndex bucketIdx = idx / __CF_BITS_PER_BUCKET;
+    CFIndex bitOfBucket = idx & (__CF_BITS_PER_BUCKET - 1);
+    if (value) {
+	buckets[bucketIdx] |= (1 << (__CF_BITS_PER_BUCKET - 1 - bitOfBucket));
+    } else {
+	buckets[bucketIdx] &= ~(1 << (__CF_BITS_PER_BUCKET - 1 - bitOfBucket));
+    }
+}
+
+CF_INLINE void __CFFlipBitVectorBit(__CFBitVectorBucket *buckets, CFIndex idx) {
+    CFIndex bucketIdx = idx / __CF_BITS_PER_BUCKET;
+    CFIndex bitOfBucket = idx & (__CF_BITS_PER_BUCKET - 1);
+    buckets[bucketIdx] ^= (1 << (__CF_BITS_PER_BUCKET - 1 - bitOfBucket));
+}
+
+#if defined(DEBUG)
+CF_INLINE void __CFBitVectorValidateRange(CFBitVectorRef bv, CFRange range, const char *func) {
+    CFAssert2(0 <= range.location && range.location < __CFBitVectorCount(bv), __kCFLogAssertion, "%s(): range.location index (%d) out of bounds", func, range.location);
+    CFAssert2(0 <= range.length, __kCFLogAssertion, "%s(): range.length (%d) cannot be less than zero", func, range.length);
+    CFAssert2(range.location + range.length <= __CFBitVectorCount(bv), __kCFLogAssertion, "%s(): ending index (%d) out of bounds", func, range.location + range.length);
+}
+#else
+#define __CFBitVectorValidateRange(bf,r,f)
+#endif
+
+static Boolean __CFBitVectorEqual(CFTypeRef cf1, CFTypeRef cf2) {
+    CFBitVectorRef bv1 = (CFBitVectorRef)cf1;
+    CFBitVectorRef bv2 = (CFBitVectorRef)cf2;
+    CFIndex idx, cnt;
+    cnt = __CFBitVectorCount(bv1);
+    if (cnt != __CFBitVectorCount(bv2)) return false;
+    if (0 == cnt) return true;
+    for (idx = 0; idx < (cnt / __CF_BITS_PER_BUCKET) + 1; idx++) {
+	__CFBitVectorBucket val1 = bv1->_buckets[idx];
+	__CFBitVectorBucket val2 = bv2->_buckets[idx];
+	if (val1 != val2) return false;
+    }
+    return true;
+}
+
+static CFHashCode __CFBitVectorHash(CFTypeRef cf) {
+    CFBitVectorRef bv = (CFBitVectorRef)cf;
+    return __CFBitVectorCount(bv);
+}
+
+static CFStringRef __CFBitVectorCopyDescription(CFTypeRef cf) {
+    CFBitVectorRef bv = (CFBitVectorRef)cf;
+    CFMutableStringRef result;
+    CFIndex idx, cnt;
+    __CFBitVectorBucket *buckets;
+    cnt = __CFBitVectorCount(bv);
+    buckets = bv->_buckets;
+    result = CFStringCreateMutable(kCFAllocatorSystemDefault, 0);
+    CFStringAppendFormat(result, NULL, CFSTR("<CFBitVector %p [%p]>{count = %u, capacity = %u, objects = (\n"), cf, CFGetAllocator(bv), cnt, __CFBitVectorCapacity(bv));
+    for (idx = 0; idx < (cnt / 64); idx++) {	/* Print groups of 64 */
+	CFIndex idx2;
+	CFStringAppendFormat(result, NULL, CFSTR("\t%u : "), (idx * 64));
+	for (idx2 = 0; idx2 < 64; idx2 += 4) {
+	    CFIndex bucketIdx = (idx << 6) + idx2;
+	    CFStringAppendFormat(result, NULL, CFSTR("%d%d%d%d"),
+		__CFBitVectorBit(buckets, bucketIdx + 0),
+		__CFBitVectorBit(buckets, bucketIdx + 1),
+		__CFBitVectorBit(buckets, bucketIdx + 2),
+		__CFBitVectorBit(buckets, bucketIdx + 3));
+	}
+	CFStringAppend(result, CFSTR("\n"));
+    }
+    if (idx * 64 < cnt) {
+	CFStringAppendFormat(result, NULL, CFSTR("\t%u : "), (idx * 64));
+	for (idx = (idx * 64); idx < cnt; idx++) {	/* Print remainder */
+	    CFStringAppendFormat(result, NULL, CFSTR("%d"), __CFBitVectorBit(buckets, idx));
+	}
+    }
+    CFStringAppend(result, CFSTR("\n)}"));
+    return result;
+}
+
+enum {
+    kCFBitVectorImmutable = 0x0,		/* unchangable and fixed capacity; default */
+    kCFBitVectorMutable = 0x1,		/* changeable and variable capacity */
+    kCFBitVectorFixedMutable = 0x3	/* changeable and fixed capacity */
+};
+
+static void __CFBitVectorDeallocate(CFTypeRef cf) {
+    CFMutableBitVectorRef bv = (CFMutableBitVectorRef)cf;
+    CFAllocatorRef allocator = CFGetAllocator(bv);
+    if (__CFBitVectorMutableVariety(bv) == kCFBitVectorMutable) {
+	_CFAllocatorDeallocateGC(allocator, bv->_buckets);
+    }
+}
+
+static CFTypeID __kCFBitVectorTypeID = _kCFRuntimeNotATypeID;
+
+static const CFRuntimeClass __CFBitVectorClass = {
+    _kCFRuntimeScannedObject,
+    "CFBitVector",
+    NULL,	// init
+    NULL,	// copy
+    __CFBitVectorDeallocate,
+    __CFBitVectorEqual,
+    __CFBitVectorHash,
+    NULL,	// 
+    __CFBitVectorCopyDescription
+};
+
+__private_extern__ void __CFBitVectorInitialize(void) {
+    __kCFBitVectorTypeID = _CFRuntimeRegisterClass(&__CFBitVectorClass);
+}
+
+CFTypeID CFBitVectorGetTypeID(void) {
+    return __kCFBitVectorTypeID;
+}
+
+static CFMutableBitVectorRef __CFBitVectorInit(CFAllocatorRef allocator, CFOptionFlags flags, CFIndex capacity, const uint8_t *bytes, CFIndex numBits) {
+    CFMutableBitVectorRef memory;
+    CFIndex size;
+    CFAssert2(0 <= capacity, __kCFLogAssertion, "%s(): capacity (%d) cannot be less than zero", __PRETTY_FUNCTION__, capacity);
+    CFAssert3(kCFBitVectorFixedMutable != __CFBitVectorMutableVarietyFromFlags(flags) || numBits <= capacity, __kCFLogAssertion, "%s(): for fixed mutable bit vectors, capacity (%d) must be greater than or equal to number of initial elements (%d)", __PRETTY_FUNCTION__, capacity, numBits);
+    CFAssert2(0 <= numBits, __kCFLogAssertion, "%s(): numValues (%d) cannot be less than zero", __PRETTY_FUNCTION__, numBits);
+    size = sizeof(struct __CFBitVector) - sizeof(CFRuntimeBase);
+    if (__CFBitVectorMutableVarietyFromFlags(flags) != kCFBitVectorMutable)
+	size += sizeof(__CFBitVectorBucket) * __CFBitVectorNumBucketsForCapacity(capacity);
+    memory = (CFMutableBitVectorRef)_CFRuntimeCreateInstance(allocator, __kCFBitVectorTypeID, size, NULL);
+    if (NULL == memory) {
+	return NULL;
+    }
+    switch (__CFBitVectorMutableVarietyFromFlags(flags)) {
+    case kCFBitVectorMutable:
+	__CFBitVectorSetCapacity(memory, __CFBitVectorRoundUpCapacity(1));
+	__CFBitVectorSetNumBuckets(memory, __CFBitVectorNumBucketsForCapacity(__CFBitVectorRoundUpCapacity(1)));
+	CF_WRITE_BARRIER_BASE_ASSIGN(allocator, memory, memory->_buckets, _CFAllocatorAllocateGC(allocator, __CFBitVectorNumBuckets(memory) * sizeof(__CFBitVectorBucket), 0));
+	if (__CFOASafe) __CFSetLastAllocationEventName(memory->_buckets, "CFBitVector (store)");
+	if (NULL == memory->_buckets) {
+	    CFRelease(memory);
+	    return NULL;
+	}
+	break;
+    case kCFBitVectorFixedMutable:
+    case kCFBitVectorImmutable:
+	/* Don't round up capacity */
+	__CFBitVectorSetCapacity(memory, capacity);
+	__CFBitVectorSetNumBuckets(memory, __CFBitVectorNumBucketsForCapacity(capacity));
+	memory->_buckets = (__CFBitVectorBucket *)((int8_t *)memory + sizeof(struct __CFBitVector));
+	break;
+    }
+    __CFBitVectorSetNumBucketsUsed(memory, numBits / __CF_BITS_PER_BUCKET + 1);
+    __CFBitVectorSetCount(memory, numBits);
+    if (bytes) {
+	/* This move is possible because bits are numbered from 0 on the left */
+	memmove(memory->_buckets, bytes, (numBits + __CF_BITS_PER_BYTE - 1) / __CF_BITS_PER_BYTE);
+    }
+    __CFBitVectorSetMutableVariety(memory, __CFBitVectorMutableVarietyFromFlags(flags));
+    return memory;
+}
+
+CFBitVectorRef CFBitVectorCreate(CFAllocatorRef allocator, const uint8_t *bytes, CFIndex numBits) {
+   return __CFBitVectorInit(allocator, kCFBitVectorImmutable, numBits, bytes, numBits);
+}
+
+CFMutableBitVectorRef CFBitVectorCreateMutable(CFAllocatorRef allocator, CFIndex capacity) {
+   return __CFBitVectorInit(allocator, (0 == capacity) ? kCFBitVectorMutable : kCFBitVectorFixedMutable, capacity, NULL, 0);
+}
+
+CFBitVectorRef CFBitVectorCreateCopy(CFAllocatorRef allocator, CFBitVectorRef bv) {
+   __CFGenericValidateType(bv, __kCFBitVectorTypeID);
+    return __CFBitVectorInit(allocator, kCFBitVectorImmutable, __CFBitVectorCount(bv), (const uint8_t *)bv->_buckets, __CFBitVectorCount(bv));
+}
+
+CFMutableBitVectorRef CFBitVectorCreateMutableCopy(CFAllocatorRef allocator, CFIndex capacity, CFBitVectorRef bv) {
+   __CFGenericValidateType(bv, __kCFBitVectorTypeID);
+    return __CFBitVectorInit(allocator, (0 == capacity) ? kCFBitVectorMutable : kCFBitVectorFixedMutable, capacity, (const uint8_t *)bv->_buckets, __CFBitVectorCount(bv));
+}
+
+CFIndex CFBitVectorGetCount(CFBitVectorRef bv) {
+    __CFGenericValidateType(bv, __kCFBitVectorTypeID);
+    return __CFBitVectorCount(bv);
+}
+
+typedef __CFBitVectorBucket (*__CFInternalMapper)(__CFBitVectorBucket bucketValue, __CFBitVectorBucket bucketValueMask, void *context);
+
+static void __CFBitVectorInternalMap(CFMutableBitVectorRef bv, CFRange range, __CFInternalMapper mapper, void *context) {
+    CFIndex bucketIdx, bitOfBucket;
+    CFIndex nBuckets;
+    __CFBitVectorBucket bucketValMask, newBucketVal;
+    if (0 == range.length) return;
+    bucketIdx = range.location / __CF_BITS_PER_BUCKET;
+    bitOfBucket = range.location & (__CF_BITS_PER_BUCKET - 1);
+    /* Follow usual pattern of ramping up to a bit bucket boundary ...*/
+    if (bitOfBucket + range.length < __CF_BITS_PER_BUCKET) {
+	bucketValMask = __CFBitBucketMask(bitOfBucket, bitOfBucket + range.length - 1);
+	range.length = 0;
+    } else {
+	bucketValMask = __CFBitBucketMask(bitOfBucket, __CF_BITS_PER_BUCKET - 1);
+	range.length -= __CF_BITS_PER_BUCKET - bitOfBucket;
+    }
+    newBucketVal = mapper(bv->_buckets[bucketIdx], bucketValMask, context);
+    bv->_buckets[bucketIdx] = (bv->_buckets[bucketIdx] & ~bucketValMask) | (newBucketVal & bucketValMask);
+    bucketIdx++;
+    /* ... clipping along with entire bit buckets ... */
+    nBuckets = range.length / __CF_BITS_PER_BUCKET;
+    range.length -= nBuckets * __CF_BITS_PER_BUCKET;
+    while (nBuckets--) {
+	newBucketVal = mapper(bv->_buckets[bucketIdx], ~0, context);
+	bv->_buckets[bucketIdx] = newBucketVal;
+	bucketIdx++;
+    }
+    /* ... and ramping down with the last fragmentary bit bucket. */
+    if (0 != range.length) {
+	bucketValMask = __CFBitBucketMask(0, range.length - 1);
+	newBucketVal = mapper(bv->_buckets[bucketIdx], bucketValMask, context);
+	bv->_buckets[bucketIdx] = (bv->_buckets[bucketIdx] & ~bucketValMask) | (newBucketVal & bucketValMask);
+    }
+}
+
+struct _occursContext {
+    CFBit value;
+    CFIndex count;
+};
+
+static __CFBitVectorBucket __CFBitVectorCountBits(__CFBitVectorBucket bucketValue, __CFBitVectorBucket bucketValueMask, struct _occursContext *context) {
+    static const __CFBitVectorBucket __CFNibbleBitCount[16] = {0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4};
+    __CFBitVectorBucket val;
+    CFIndex idx;
+    val = (context->value) ? (bucketValue & bucketValueMask) : (~bucketValue & bucketValueMask);
+    for (idx = 0; idx < (CFIndex)sizeof(__CFBitVectorBucket) * 2; idx++) {
+	context->count += __CFNibbleBitCount[val & 0xF];
+	val = val >> 4;
+    }
+    return bucketValue;
+}
+
+CFIndex CFBitVectorGetCountOfBit(CFBitVectorRef bv, CFRange range, CFBit value) {
+    struct _occursContext context;
+    __CFGenericValidateType(bv, __kCFBitVectorTypeID);
+    __CFBitVectorValidateRange(bv, range, __PRETTY_FUNCTION__);
+    if (0 == range.length) return 0;
+    context.value = value;
+    context.count = 0;
+    __CFBitVectorInternalMap((CFMutableBitVectorRef)bv, range, (__CFInternalMapper)__CFBitVectorCountBits, &context);
+    return context.count;
+}
+
+Boolean CFBitVectorContainsBit(CFBitVectorRef bv, CFRange range, CFBit value) {
+    __CFGenericValidateType(bv, __kCFBitVectorTypeID);
+    __CFBitVectorValidateRange(bv, range, __PRETTY_FUNCTION__);
+    return (CFBitVectorGetCountOfBit(bv, range, value) != 0) ? true : false;
+}
+
+CFBit CFBitVectorGetBitAtIndex(CFBitVectorRef bv, CFIndex idx) {
+    __CFGenericValidateType(bv, __kCFBitVectorTypeID);
+    CFAssert2(0 <= idx && idx < __CFBitVectorCount(bv), __kCFLogAssertion, "%s(): index (%d) out of bounds", __PRETTY_FUNCTION__, idx);
+    return __CFBitVectorBit(bv->_buckets, idx);
+}
+
+struct _getBitsContext {
+    uint8_t *curByte;
+    CFIndex initBits;	/* Bits to extract off the front for the prev. byte */
+    CFIndex totalBits;	/* This is for stopping at the end */
+    bool ignoreFirstInitBits;
+};
+
+static __CFBitVectorBucket __CFBitVectorGetBits(__CFBitVectorBucket bucketValue, __CFBitVectorBucket bucketValueMask, void *ctx) {
+    struct _getBitsContext *context = (struct _getBitsContext *)ctx;
+    __CFBitVectorBucket val;
+    CFIndex nBits;
+    val = bucketValue & bucketValueMask;
+    nBits = __CFMin(__CF_BITS_PER_BUCKET - context->initBits, context->totalBits);
+    /* First initBits bits go in *curByte ... */
+    if (0 < context->initBits) {
+	if (!context->ignoreFirstInitBits) {
+	    *context->curByte |= (uint8_t)(val >> (__CF_BITS_PER_BUCKET - context->initBits));
+	    context->curByte++;
+	    context->totalBits -= context->initBits;
+	    context->ignoreFirstInitBits = false;
+	}
+	val <<= context->initBits;
+    }
+    /* ... then next groups of __CF_BITS_PER_BYTE go in *curByte ... */
+    while (__CF_BITS_PER_BYTE <= nBits) {
+	*context->curByte = (uint8_t)(val >> (__CF_BITS_PER_BUCKET - __CF_BITS_PER_BYTE));
+	context->curByte++;
+	context->totalBits -= context->initBits;
+	nBits -= __CF_BITS_PER_BYTE;
+	val <<= __CF_BITS_PER_BYTE;
+    }
+    /* ... then remaining bits go in *curByte */
+    if (0 < nBits) {
+	*context->curByte = (uint8_t)(val >> (__CF_BITS_PER_BUCKET - __CF_BITS_PER_BYTE));
+	context->totalBits -= nBits;
+    }
+    return bucketValue;
+}
+
+void CFBitVectorGetBits(CFBitVectorRef bv, CFRange range, uint8_t *bytes) {
+    struct _getBitsContext context;
+    __CFGenericValidateType(bv, __kCFBitVectorTypeID);
+    __CFBitVectorValidateRange(bv, range, __PRETTY_FUNCTION__);
+    if (0 == range.length) return;
+    context.curByte = bytes;
+    context.initBits = range.location & (__CF_BITS_PER_BUCKET - 1);
+    context.totalBits = range.length;
+    context.ignoreFirstInitBits = true;
+    __CFBitVectorInternalMap((CFMutableBitVectorRef)bv, range, __CFBitVectorGetBits, &context);
+}
+
+CFIndex CFBitVectorGetFirstIndexOfBit(CFBitVectorRef bv, CFRange range, CFBit value) {
+    CFIndex idx;
+    __CFGenericValidateType(bv, __kCFBitVectorTypeID);
+    __CFBitVectorValidateRange(bv, range, __PRETTY_FUNCTION__);
+    for (idx = 0; idx < range.length; idx++) {
+	if (value == CFBitVectorGetBitAtIndex(bv, range.location + idx)) {
+	    return range.location + idx;
+	}
+    }
+    return kCFNotFound;
+}
+
+CFIndex CFBitVectorGetLastIndexOfBit(CFBitVectorRef bv, CFRange range, CFBit value) {
+    CFIndex idx;
+    __CFGenericValidateType(bv, __kCFBitVectorTypeID);
+    __CFBitVectorValidateRange(bv, range, __PRETTY_FUNCTION__);
+    for (idx = range.length; idx--;) {
+	if (value == CFBitVectorGetBitAtIndex(bv, range.location + idx)) {
+	    return range.location + idx;
+	}
+    }
+    return kCFNotFound;
+}
+
+static void __CFBitVectorGrow(CFMutableBitVectorRef bv, CFIndex numNewValues) {
+    CFIndex oldCount = __CFBitVectorCount(bv);
+    CFIndex capacity = __CFBitVectorRoundUpCapacity(oldCount + numNewValues);
+    CFAllocatorRef allocator = CFGetAllocator(bv);
+    __CFBitVectorSetCapacity(bv, capacity);
+    __CFBitVectorSetNumBuckets(bv, __CFBitVectorNumBucketsForCapacity(capacity));
+    CF_WRITE_BARRIER_BASE_ASSIGN(allocator, bv, bv->_buckets, CFAllocatorReallocate(allocator, bv->_buckets, __CFBitVectorNumBuckets(bv) * sizeof(__CFBitVectorBucket), 0));
+    if (__CFOASafe) __CFSetLastAllocationEventName(bv->_buckets, "CFBitVector (store)");
+    if (NULL == bv->_buckets) HALT;
+}
+
+static __CFBitVectorBucket __CFBitVectorZeroBits(__CFBitVectorBucket bucketValue, __CFBitVectorBucket bucketValueMask, void *context) {
+    return 0;
+}
+
+static __CFBitVectorBucket __CFBitVectorOneBits(__CFBitVectorBucket bucketValue, __CFBitVectorBucket bucketValueMask, void *context) {
+    return ~(__CFBitVectorBucket)0;
+}
+
+void CFBitVectorSetCount(CFMutableBitVectorRef bv, CFIndex count) {
+    CFIndex cnt;
+    CFAssert1(__CFBitVectorMutableVariety(bv) == kCFBitVectorMutable || __CFBitVectorMutableVariety(bv) == kCFBitVectorFixedMutable, __kCFLogAssertion, "%s(): bit vector is immutable", __PRETTY_FUNCTION__);
+    cnt = __CFBitVectorCount(bv);
+    switch (__CFBitVectorMutableVariety(bv)) {
+    case kCFBitVectorMutable:
+	if (cnt < count) {
+	    __CFBitVectorGrow(bv, count - cnt);
+	}
+	break;
+    case kCFBitVectorFixedMutable:
+	CFAssert1(count <= __CFBitVectorCapacity(bv), __kCFLogAssertion, "%s(): fixed-capacity bit vector is full", __PRETTY_FUNCTION__);
+	break;
+    }
+    if (cnt < count) {
+	CFRange range = CFRangeMake(cnt, count - cnt);
+        __CFBitVectorInternalMap(bv, range, __CFBitVectorZeroBits, NULL);
+    }
+    __CFBitVectorSetNumBucketsUsed(bv, count / __CF_BITS_PER_BUCKET + 1);
+    __CFBitVectorSetCount(bv, count);
+}
+
+void CFBitVectorFlipBitAtIndex(CFMutableBitVectorRef bv, CFIndex idx) {
+    __CFGenericValidateType(bv, __kCFBitVectorTypeID);
+    CFAssert2(0 <= idx && idx < __CFBitVectorCount(bv), __kCFLogAssertion, "%s(): index (%d) out of bounds", __PRETTY_FUNCTION__, idx);
+    CFAssert1(__CFBitVectorMutableVariety(bv) == kCFBitVectorMutable || __CFBitVectorMutableVariety(bv) == kCFBitVectorFixedMutable, __kCFLogAssertion, "%s(): bit vector is immutable", __PRETTY_FUNCTION__);
+    __CFFlipBitVectorBit(bv->_buckets, idx);
+}
+
+static __CFBitVectorBucket __CFBitVectorFlipBits(__CFBitVectorBucket bucketValue, __CFBitVectorBucket bucketValueMask, void *context) {
+    return (~(__CFBitVectorBucket)0) ^ bucketValue;
+}
+
+void CFBitVectorFlipBits(CFMutableBitVectorRef bv, CFRange range) {
+    __CFGenericValidateType(bv, __kCFBitVectorTypeID);
+    __CFBitVectorValidateRange(bv, range, __PRETTY_FUNCTION__);
+    CFAssert1(__CFBitVectorMutableVariety(bv) == kCFBitVectorMutable || __CFBitVectorMutableVariety(bv) == kCFBitVectorFixedMutable, __kCFLogAssertion, "%s(): bit vector is immutable", __PRETTY_FUNCTION__);
+    if (0 == range.length) return;
+    __CFBitVectorInternalMap(bv, range, __CFBitVectorFlipBits, NULL);
+}
+
+void CFBitVectorSetBitAtIndex(CFMutableBitVectorRef bv, CFIndex idx, CFBit value) {
+    __CFGenericValidateType(bv, __kCFBitVectorTypeID);
+    CFAssert2(0 <= idx && idx < __CFBitVectorCount(bv), __kCFLogAssertion, "%s(): index (%d) out of bounds", __PRETTY_FUNCTION__, idx);
+    CFAssert1(__CFBitVectorMutableVariety(bv) == kCFBitVectorMutable || __CFBitVectorMutableVariety(bv) == kCFBitVectorFixedMutable, __kCFLogAssertion, "%s(): bit vector is immutable", __PRETTY_FUNCTION__);
+    __CFSetBitVectorBit(bv->_buckets, idx, value);
+}
+
+void CFBitVectorSetBits(CFMutableBitVectorRef bv, CFRange range, CFBit value) {
+    __CFGenericValidateType(bv, __kCFBitVectorTypeID);
+    __CFBitVectorValidateRange(bv, range, __PRETTY_FUNCTION__);
+    CFAssert1(__CFBitVectorMutableVariety(bv) == kCFBitVectorMutable || __CFBitVectorMutableVariety(bv) == kCFBitVectorFixedMutable, __kCFLogAssertion, "%s(): bit vector is immutable", __PRETTY_FUNCTION__);
+    if (0 == range.length) return;
+    if (value) {
+	__CFBitVectorInternalMap(bv, range, __CFBitVectorOneBits, NULL);
+    } else {
+	__CFBitVectorInternalMap(bv, range, __CFBitVectorZeroBits, NULL);
+    }
+}
+
+void CFBitVectorSetAllBits(CFMutableBitVectorRef bv, CFBit value) {
+    CFIndex nBuckets, leftover;
+    __CFGenericValidateType(bv, __kCFBitVectorTypeID);
+    CFAssert1(__CFBitVectorMutableVariety(bv) == kCFBitVectorMutable || __CFBitVectorMutableVariety(bv) == kCFBitVectorFixedMutable, __kCFLogAssertion, "%s(): bit vector is immutable", __PRETTY_FUNCTION__);
+    nBuckets = __CFBitVectorCount(bv) / __CF_BITS_PER_BUCKET;
+    leftover = __CFBitVectorCount(bv) - nBuckets * __CF_BITS_PER_BUCKET;
+    if (0 < leftover) {
+	CFRange range = CFRangeMake(nBuckets * __CF_BITS_PER_BUCKET, leftover);
+	if (value) {
+	    __CFBitVectorInternalMap(bv, range, __CFBitVectorOneBits, NULL);
+	} else {
+	    __CFBitVectorInternalMap(bv, range, __CFBitVectorZeroBits, NULL);
+	}
+    }
+    memset(bv->_buckets, (value ? ~0 : 0), nBuckets);
+}
+
+#undef __CFBitVectorValidateRange
+
diff --git a/CoreFoundation/CFBitVector.h b/CoreFoundation/CFBitVector.h
new file mode 100644
index 0000000..0cd0a74
--- /dev/null
+++ b/CoreFoundation/CFBitVector.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2008-2009 Brent Fulgham <bfulgham@gmail.org>.  All rights reserved.
+ *
+ * This source code is a modified version of the CoreFoundation sources released by Apple Inc. under
+ * the terms of the APSL version 2.0 (see below).
+ *
+ * For information about changes from the original Apple source release can be found by reviewing the
+ * source control system for the project at https://sourceforge.net/svn/?group_id=246198.
+ *
+ * The original license information is as follows:
+ * 
+ * Copyright (c) 2008 Apple Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*	CFBitVector.h
+	Copyright (c) 1998-2007, Apple Inc. All rights reserved.
+*/
+
+#if !defined(__COREFOUNDATION_CFBITVECTOR__)
+#define __COREFOUNDATION_CFBITVECTOR__ 1
+
+#include <CoreFoundation/CFBase.h>
+
+CF_EXTERN_C_BEGIN
+
+typedef UInt32 CFBit;
+
+typedef const struct __CFBitVector * CFBitVectorRef;
+typedef struct __CFBitVector * CFMutableBitVectorRef;
+
+CF_EXPORT CFTypeID	CFBitVectorGetTypeID(void);
+
+CF_EXPORT CFBitVectorRef	CFBitVectorCreate(CFAllocatorRef allocator, const UInt8 *bytes, CFIndex numBits);
+CF_EXPORT CFBitVectorRef	CFBitVectorCreateCopy(CFAllocatorRef allocator, CFBitVectorRef bv);
+CF_EXPORT CFMutableBitVectorRef	CFBitVectorCreateMutable(CFAllocatorRef allocator, CFIndex capacity);
+CF_EXPORT CFMutableBitVectorRef	CFBitVectorCreateMutableCopy(CFAllocatorRef allocator, CFIndex capacity, CFBitVectorRef bv);
+
+CF_EXPORT CFIndex	CFBitVectorGetCount(CFBitVectorRef bv);
+CF_EXPORT CFIndex	CFBitVectorGetCountOfBit(CFBitVectorRef bv, CFRange range, CFBit value);
+CF_EXPORT Boolean	CFBitVectorContainsBit(CFBitVectorRef bv, CFRange range, CFBit value);
+CF_EXPORT CFBit		CFBitVectorGetBitAtIndex(CFBitVectorRef bv, CFIndex idx);
+CF_EXPORT void		CFBitVectorGetBits(CFBitVectorRef bv, CFRange range, UInt8 *bytes);
+CF_EXPORT CFIndex	CFBitVectorGetFirstIndexOfBit(CFBitVectorRef bv, CFRange range, CFBit value);
+CF_EXPORT CFIndex	CFBitVectorGetLastIndexOfBit(CFBitVectorRef bv, CFRange range, CFBit value);
+
+CF_EXPORT void		CFBitVectorSetCount(CFMutableBitVectorRef bv, CFIndex count);
+CF_EXPORT void		CFBitVectorFlipBitAtIndex(CFMutableBitVectorRef bv, CFIndex idx);
+CF_EXPORT void		CFBitVectorFlipBits(CFMutableBitVectorRef bv, CFRange range);
+CF_EXPORT void		CFBitVectorSetBitAtIndex(CFMutableBitVectorRef bv, CFIndex idx, CFBit value);
+CF_EXPORT void		CFBitVectorSetBits(CFMutableBitVectorRef bv, CFRange range, CFBit value);
+CF_EXPORT void		CFBitVectorSetAllBits(CFMutableBitVectorRef bv, CFBit value);
+
+CF_EXTERN_C_END
+
+#endif /* ! __COREFOUNDATION_CFBITVECTOR__ */
+
diff --git a/CoreFoundation/CFBuiltinConverters.c b/CoreFoundation/CFBuiltinConverters.c
new file mode 100644
index 0000000..b6e55ae
--- /dev/null
+++ b/CoreFoundation/CFBuiltinConverters.c
@@ -0,0 +1,1206 @@
+/*
+ * Copyright (c) 2008-2009 Brent Fulgham <bfulgham@gmail.org>.  All rights reserved.
+ *
+ * This source code is a modified version of the CoreFoundation sources released by Apple Inc. under
+ * the terms of the APSL version 2.0 (see below).
+ *
+ * For information about changes from the original Apple source release can be found by reviewing the
+ * source control system for the project at https://sourceforge.net/svn/?group_id=246198.
+ *
+ * The original license information is as follows:
+ * 
+ * Copyright (c) 2008 Apple Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*	CFBuiltinConverters.c
+	Copyright 1999-2002, Apple, Inc. All rights reserved.
+	Responsibility: Aki Inoue
+*/
+
+#include "CFStringEncodingConverterExt.h"
+#include "CFUniChar.h"
+#include "CFUnicodeDecomposition.h"
+#include "CFUnicodePrecomposition.h"
+#include "CFStringEncodingConverterPriv.h"
+#include "CFInternal.h"
+
+#define ParagraphSeparator 0x2029
+#define ASCIINewLine 0x0a
+static int8_t __CFMapsParagraphSeparator = -1;
+
+CF_INLINE bool __CFIsParagraphSeparator(UTF16Char character) {
+    if (-1 == __CFMapsParagraphSeparator) __CFMapsParagraphSeparator = (_CFExecutableLinkedOnOrAfter(CFSystemVersionLeopard) ? false : true);
+
+    return ((__CFMapsParagraphSeparator && (ParagraphSeparator == character)) ? true : false);
+}
+
+/* Precomposition */
+static const uint32_t __CFLatin1CombiningCharBitmap[] = { // 0x300 ~ 0x35FF
+    0xFBB94010, 0x01800000, 0x0000000,
+};
+
+bool CFStringEncodingIsValidCombiningCharacterForLatin1(UniChar character) {
+    return ((character >= 0x300) && (character < 0x360) && (__CFLatin1CombiningCharBitmap[(character - 0x300) / 32] & (1 << (31 - ((character - 0x300) % 32)))) ? true : false);
+}
+
+UniChar CFStringEncodingPrecomposeLatinCharacter(const UniChar *character, CFIndex numChars, CFIndex *usedChars) {
+    if (numChars > 0) {
+        UTF32Char ch = *(character++), nextCh, composedChar;
+        CFIndex usedCharLen = 1;
+
+        if (CFUniCharIsSurrogateHighCharacter(ch) || CFUniCharIsSurrogateLowCharacter(ch)) {
+            if (usedChars) (*usedChars) = usedCharLen;
+            return ch;
+        }
+
+        while (usedCharLen < numChars) {
+            nextCh = *(character++);
+
+            if (CFUniCharIsSurrogateHighCharacter(nextCh) || CFUniCharIsSurrogateLowCharacter(nextCh)) break;
+
+            if (CFUniCharIsMemberOf(nextCh, kCFUniCharNonBaseCharacterSet) && ((composedChar = CFUniCharPrecomposeCharacter(ch, nextCh)) != 0xFFFD)) {
+                if (composedChar > 0xFFFF) { // Non-base
+                    break;
+                } else {
+                    ch = composedChar;
+                }
+            } else {
+                break;
+            }
+            ++usedCharLen;
+        }
+        if (usedChars) (*usedChars) = usedCharLen;
+        return ch;
+    }
+    return 0xFFFD;
+}
+
+/* ASCII */
+static bool __CFToASCII(uint32_t flags, UniChar character, uint8_t *byte) {
+    if (character < 0x80) {
+        *byte = (uint8_t)character;
+    } else if (__CFIsParagraphSeparator(character)) {
+        *byte = ASCIINewLine;
+    } else {
+        return false;
+    }
+    return true;
+}
+
+static bool __CFFromASCII(uint32_t flags, uint8_t byte, UniChar *character) {
+    if (byte < 0x80) {
+        *character = (UniChar)byte;
+        return true;
+    } else {
+        return false;
+    }
+}
+
+
+__private_extern__ const CFStringEncodingConverter __CFConverterASCII = {
+    (void*)__CFToASCII, (void*)__CFFromASCII, 1, 1, kCFStringEncodingConverterCheapEightBit,
+    NULL, NULL, NULL, NULL, NULL, NULL,
+};
+
+/* ISO Latin 1 (8859-1) */
+static bool __CFToISOLatin1(uint32_t flags, UniChar character, uint8_t *byte) {
+    if (character <= 0xFF) {
+        *byte = (uint8_t)character;
+    } else if (__CFIsParagraphSeparator(character)) {
+        *byte = ASCIINewLine;
+    } else {
+        return false;
+    }
+
+    return true;
+}
+
+static bool __CFFromISOLatin1(uint32_t flags, uint8_t byte, UniChar *character) {
+    *character = (UniChar)byte;
+    return true;
+}
+
+static CFIndex __CFToISOLatin1Precompose(uint32_t flags, const UniChar *character, CFIndex numChars, uint8_t *bytes, CFIndex maxByteLen, CFIndex *usedByteLen) {
+    uint8_t byte;
+    CFIndex usedCharLen;
+
+    if (__CFToISOLatin1(flags, CFStringEncodingPrecomposeLatinCharacter(character, numChars, &usedCharLen), &byte) && byte && (usedCharLen > 1)) {
+        if (maxByteLen) *bytes = byte;
+        *usedByteLen = 1;
+        return usedCharLen;
+    } else {
+        return 0;
+    }
+}
+
+__private_extern__ const CFStringEncodingConverter __CFConverterISOLatin1 = {
+    (void*)__CFToISOLatin1, (void*)__CFFromISOLatin1, 1, 1, kCFStringEncodingConverterCheapEightBit,
+    NULL, NULL, NULL, NULL, __CFToISOLatin1Precompose, CFStringEncodingIsValidCombiningCharacterForLatin1,
+};
+
+/* Mac Roman */
+#define NUM_MACROMAN_FROM_UNI 129
+static const CFStringEncodingUnicodeTo8BitCharMap macRoman_from_uni[NUM_MACROMAN_FROM_UNI] = {
+    { 0x00A0, 0xCA }, /* NO-BREAK SPACE */
+    { 0x00A1, 0xC1 }, /* INVERTED EXCLAMATION MARK */
+    { 0x00A2, 0xA2 }, /* CENT SIGN */
+    { 0x00A3, 0xA3 }, /* POUND SIGN */
+    { 0x00A5, 0xB4 }, /* YEN SIGN */
+    { 0x00A7, 0xA4 }, /* SECTION SIGN */
+    { 0x00A8, 0xAC }, /* DIAERESIS */
+    { 0x00A9, 0xA9 }, /* COPYRIGHT SIGN */
+    { 0x00AA, 0xBB }, /* FEMININE ORDINAL INDICATOR */
+    { 0x00AB, 0xC7 }, /* LEFT-POINTING DOUBLE ANGLE QUOTATION MARK */
+    { 0x00AC, 0xC2 }, /* NOT SIGN */
+    { 0x00AE, 0xA8 }, /* REGISTERED SIGN */
+    { 0x00AF, 0xF8 }, /* MACRON */
+    { 0x00B0, 0xA1 }, /* DEGREE SIGN */
+    { 0x00B1, 0xB1 }, /* PLUS-MINUS SIGN */
+    { 0x00B4, 0xAB }, /* ACUTE ACCENT */
+    { 0x00B5, 0xB5 }, /* MICRO SIGN */
+    { 0x00B6, 0xA6 }, /* PILCROW SIGN */
+    { 0x00B7, 0xE1 }, /* MIDDLE DOT */
+    { 0x00B8, 0xFC }, /* CEDILLA */
+    { 0x00BA, 0xBC }, /* MASCULINE ORDINAL INDICATOR */
+    { 0x00BB, 0xC8 }, /* RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK */
+    { 0x00BF, 0xC0 }, /* INVERTED QUESTION MARK */
+    { 0x00C0, 0xCB }, /* LATIN CAPITAL LETTER A WITH GRAVE */
+    { 0x00C1, 0xE7 }, /* LATIN CAPITAL LETTER A WITH ACUTE */
+    { 0x00C2, 0xE5 }, /* LATIN CAPITAL LETTER A WITH CIRCUMFLEX */
+    { 0x00C3, 0xCC }, /* LATIN CAPITAL LETTER A WITH TILDE */
+    { 0x00C4, 0x80 }, /* LATIN CAPITAL LETTER A WITH DIAERESIS */
+    { 0x00C5, 0x81 }, /* LATIN CAPITAL LETTER A WITH RING ABOVE */
+    { 0x00C6, 0xAE }, /* LATIN CAPITAL LIGATURE AE */
+    { 0x00C7, 0x82 }, /* LATIN CAPITAL LETTER C WITH CEDILLA */
+    { 0x00C8, 0xE9 }, /* LATIN CAPITAL LETTER E WITH GRAVE */
+    { 0x00C9, 0x83 }, /* LATIN CAPITAL LETTER E WITH ACUTE */
+    { 0x00CA, 0xE6 }, /* LATIN CAPITAL LETTER E WITH CIRCUMFLEX */
+    { 0x00CB, 0xE8 }, /* LATIN CAPITAL LETTER E WITH DIAERESIS */
+    { 0x00CC, 0xED }, /* LATIN CAPITAL LETTER I WITH GRAVE */
+    { 0x00CD, 0xEA }, /* LATIN CAPITAL LETTER I WITH ACUTE */
+    { 0x00CE, 0xEB }, /* LATIN CAPITAL LETTER I WITH CIRCUMFLEX */
+    { 0x00CF, 0xEC }, /* LATIN CAPITAL LETTER I WITH DIAERESIS */
+    { 0x00D1, 0x84 }, /* LATIN CAPITAL LETTER N WITH TILDE */
+    { 0x00D2, 0xF1 }, /* LATIN CAPITAL LETTER O WITH GRAVE */
+    { 0x00D3, 0xEE }, /* LATIN CAPITAL LETTER O WITH ACUTE */
+    { 0x00D4, 0xEF }, /* LATIN CAPITAL LETTER O WITH CIRCUMFLEX */
+    { 0x00D5, 0xCD }, /* LATIN CAPITAL LETTER O WITH TILDE */
+    { 0x00D6, 0x85 }, /* LATIN CAPITAL LETTER O WITH DIAERESIS */
+    { 0x00D8, 0xAF }, /* LATIN CAPITAL LETTER O WITH STROKE */
+    { 0x00D9, 0xF4 }, /* LATIN CAPITAL LETTER U WITH GRAVE */
+    { 0x00DA, 0xF2 }, /* LATIN CAPITAL LETTER U WITH ACUTE */
+    { 0x00DB, 0xF3 }, /* LATIN CAPITAL LETTER U WITH CIRCUMFLEX */
+    { 0x00DC, 0x86 }, /* LATIN CAPITAL LETTER U WITH DIAERESIS */
+    { 0x00DF, 0xA7 }, /* LATIN SMALL LETTER SHARP S */
+    { 0x00E0, 0x88 }, /* LATIN SMALL LETTER A WITH GRAVE */
+    { 0x00E1, 0x87 }, /* LATIN SMALL LETTER A WITH ACUTE */
+    { 0x00E2, 0x89 }, /* LATIN SMALL LETTER A WITH CIRCUMFLEX */
+    { 0x00E3, 0x8B }, /* LATIN SMALL LETTER A WITH TILDE */
+    { 0x00E4, 0x8A }, /* LATIN SMALL LETTER A WITH DIAERESIS */
+    { 0x00E5, 0x8C }, /* LATIN SMALL LETTER A WITH RING ABOVE */
+    { 0x00E6, 0xBE }, /* LATIN SMALL LIGATURE AE */
+    { 0x00E7, 0x8D }, /* LATIN SMALL LETTER C WITH CEDILLA */
+    { 0x00E8, 0x8F }, /* LATIN SMALL LETTER E WITH GRAVE */
+    { 0x00E9, 0x8E }, /* LATIN SMALL LETTER E WITH ACUTE */
+    { 0x00EA, 0x90 }, /* LATIN SMALL LETTER E WITH CIRCUMFLEX */
+    { 0x00EB, 0x91 }, /* LATIN SMALL LETTER E WITH DIAERESIS */
+    { 0x00EC, 0x93 }, /* LATIN SMALL LETTER I WITH GRAVE */
+    { 0x00ED, 0x92 }, /* LATIN SMALL LETTER I WITH ACUTE */
+    { 0x00EE, 0x94 }, /* LATIN SMALL LETTER I WITH CIRCUMFLEX */
+    { 0x00EF, 0x95 }, /* LATIN SMALL LETTER I WITH DIAERESIS */
+    { 0x00F1, 0x96 }, /* LATIN SMALL LETTER N WITH TILDE */
+    { 0x00F2, 0x98 }, /* LATIN SMALL LETTER O WITH GRAVE */
+    { 0x00F3, 0x97 }, /* LATIN SMALL LETTER O WITH ACUTE */
+    { 0x00F4, 0x99 }, /* LATIN SMALL LETTER O WITH CIRCUMFLEX */
+    { 0x00F5, 0x9B }, /* LATIN SMALL LETTER O WITH TILDE */
+    { 0x00F6, 0x9A }, /* LATIN SMALL LETTER O WITH DIAERESIS */
+    { 0x00F7, 0xD6 }, /* DIVISION SIGN */
+    { 0x00F8, 0xBF }, /* LATIN SMALL LETTER O WITH STROKE */
+    { 0x00F9, 0x9D }, /* LATIN SMALL LETTER U WITH GRAVE */
+    { 0x00FA, 0x9C }, /* LATIN SMALL LETTER U WITH ACUTE */
+    { 0x00FB, 0x9E }, /* LATIN SMALL LETTER U WITH CIRCUMFLEX */
+    { 0x00FC, 0x9F }, /* LATIN SMALL LETTER U WITH DIAERESIS */
+    { 0x00FF, 0xD8 }, /* LATIN SMALL LETTER Y WITH DIAERESIS */
+    { 0x0131, 0xF5 }, /* LATIN SMALL LETTER DOTLESS I */
+    { 0x0152, 0xCE }, /* LATIN CAPITAL LIGATURE OE */
+    { 0x0153, 0xCF }, /* LATIN SMALL LIGATURE OE */
+    { 0x0178, 0xD9 }, /* LATIN CAPITAL LETTER Y WITH DIAERESIS */
+    { 0x0192, 0xC4 }, /* LATIN SMALL LETTER F WITH HOOK */
+    { 0x02C6, 0xF6 }, /* MODIFIER LETTER CIRCUMFLEX ACCENT */
+    { 0x02C7, 0xFF }, /* CARON */
+    { 0x02D8, 0xF9 }, /* BREVE */
+    { 0x02D9, 0xFA }, /* DOT ABOVE */
+    { 0x02DA, 0xFB }, /* RING ABOVE */
+    { 0x02DB, 0xFE }, /* OGONEK */
+    { 0x02DC, 0xF7 }, /* SMALL TILDE */
+    { 0x02DD, 0xFD }, /* DOUBLE ACUTE ACCENT */
+    { 0x03A9, 0xBD }, /* OHM SIGN (Canonical ?) */
+    { 0x03C0, 0xB9 }, /* GREEK SMALL LETTER PI */
+    { 0x2013, 0xD0 }, /* EN DASH */
+    { 0x2014, 0xD1 }, /* EM DASH */
+    { 0x2018, 0xD4 }, /* LEFT SINGLE QUOTATION MARK */
+    { 0x2019, 0xD5 }, /* RIGHT SINGLE QUOTATION MARK */
+    { 0x201A, 0xE2 }, /* SINGLE LOW-9 QUOTATION MARK */
+    { 0x201C, 0xD2 }, /* LEFT DOUBLE QUOTATION MARK */
+    { 0x201D, 0xD3 }, /* RIGHT DOUBLE QUOTATION MARK */
+    { 0x201E, 0xE3 }, /* DOUBLE LOW-9 QUOTATION MARK */
+    { 0x2020, 0xA0 }, /* DAGGER */
+    { 0x2021, 0xE0 }, /* DOUBLE DAGGER */
+    { 0x2022, 0xA5 }, /* BULLET */
+    { 0x2026, 0xC9 }, /* HORIZONTAL ELLIPSIS */
+    { 0x2030, 0xE4 }, /* PER MILLE SIGN */
+    { 0x2039, 0xDC }, /* SINGLE LEFT-POINTING ANGLE QUOTATION MARK */
+    { 0x203A, 0xDD }, /* SINGLE RIGHT-POINTING ANGLE QUOTATION MARK */
+    { 0x2044, 0xDA }, /* FRACTION SLASH */
+    { 0x20AC, 0xDB }, /* EURO SIGN */
+    { 0x2122, 0xAA }, /* TRADE MARK SIGN */
+    { 0x2126, 0xBD }, /* OHM SIGN */
+    { 0x2202, 0xB6 }, /* PARTIAL DIFFERENTIAL */
+    { 0x2206, 0xC6 }, /* INCREMENT */
+    { 0x220F, 0xB8 }, /* N-ARY PRODUCT */
+    { 0x2211, 0xB7 }, /* N-ARY SUMMATION */
+    { 0x221A, 0xC3 }, /* SQUARE ROOT */
+    { 0x221E, 0xB0 }, /* INFINITY */
+    { 0x222B, 0xBA }, /* INTEGRAL */
+    { 0x2248, 0xC5 }, /* ALMOST EQUAL TO */
+    { 0x2260, 0xAD }, /* NOT EQUAL TO */
+    { 0x2264, 0xB2 }, /* LESS-THAN OR EQUAL TO */
+    { 0x2265, 0xB3 }, /* GREATER-THAN OR EQUAL TO */
+    { 0x25CA, 0xD7 }, /* LOZENGE */
+    { 0xF8FF, 0xF0 }, /* Apple logo */
+    { 0xFB01, 0xDE }, /* LATIN SMALL LIGATURE FI */
+    { 0xFB02, 0xDF }, /* LATIN SMALL LIGATURE FL */
+};
+
+static bool __CFToMacRoman(uint32_t flags, UniChar character, uint8_t *byte) {
+    if (character < 0x80) {
+        *byte = (uint8_t)character;
+        return true;
+    } else {
+        return CFStringEncodingUnicodeTo8BitEncoding(macRoman_from_uni, NUM_MACROMAN_FROM_UNI, character, byte);
+    }
+}
+
+static const UniChar macRoman_to_uni[128] = {
+    0x00C4, /* LATIN CAPITAL LETTER A WITH DIAERESIS */
+    0x00C5, /* LATIN CAPITAL LETTER A WITH RING ABOVE */
+    0x00C7, /* LATIN CAPITAL LETTER C WITH CEDILLA */
+    0x00C9, /* LATIN CAPITAL LETTER E WITH ACUTE */
+    0x00D1, /* LATIN CAPITAL LETTER N WITH TILDE */
+    0x00D6, /* LATIN CAPITAL LETTER O WITH DIAERESIS */
+    0x00DC, /* LATIN CAPITAL LETTER U WITH DIAERESIS */
+    0x00E1, /* LATIN SMALL LETTER A WITH ACUTE */
+    0x00E0, /* LATIN SMALL LETTER A WITH GRAVE */
+    0x00E2, /* LATIN SMALL LETTER A WITH CIRCUMFLEX */
+    0x00E4, /* LATIN SMALL LETTER A WITH DIAERESIS */
+    0x00E3, /* LATIN SMALL LETTER A WITH TILDE */
+    0x00E5, /* LATIN SMALL LETTER A WITH RING ABOVE */
+    0x00E7, /* LATIN SMALL LETTER C WITH CEDILLA */
+    0x00E9, /* LATIN SMALL LETTER E WITH ACUTE */
+    0x00E8, /* LATIN SMALL LETTER E WITH GRAVE */
+    0x00EA, /* LATIN SMALL LETTER E WITH CIRCUMFLEX */
+    0x00EB, /* LATIN SMALL LETTER E WITH DIAERESIS */
+    0x00ED, /* LATIN SMALL LETTER I WITH ACUTE */
+    0x00EC, /* LATIN SMALL LETTER I WITH GRAVE */
+    0x00EE, /* LATIN SMALL LETTER I WITH CIRCUMFLEX */
+    0x00EF, /* LATIN SMALL LETTER I WITH DIAERESIS */
+    0x00F1, /* LATIN SMALL LETTER N WITH TILDE */
+    0x00F3, /* LATIN SMALL LETTER O WITH ACUTE */
+    0x00F2, /* LATIN SMALL LETTER O WITH GRAVE */
+    0x00F4, /* LATIN SMALL LETTER O WITH CIRCUMFLEX */
+    0x00F6, /* LATIN SMALL LETTER O WITH DIAERESIS */
+    0x00F5, /* LATIN SMALL LETTER O WITH TILDE */
+    0x00FA, /* LATIN SMALL LETTER U WITH ACUTE */
+    0x00F9, /* LATIN SMALL LETTER U WITH GRAVE */
+    0x00FB, /* LATIN SMALL LETTER U WITH CIRCUMFLEX */
+    0x00FC, /* LATIN SMALL LETTER U WITH DIAERESIS */
+    0x2020, /* DAGGER */
+    0x00B0, /* DEGREE SIGN */
+    0x00A2, /* CENT SIGN */
+    0x00A3, /* POUND SIGN */
+    0x00A7, /* SECTION SIGN */
+    0x2022, /* BULLET */
+    0x00B6, /* PILCROW SIGN */
+    0x00DF, /* LATIN SMALL LETTER SHARP S */
+    0x00AE, /* REGISTERED SIGN */
+    0x00A9, /* COPYRIGHT SIGN */
+    0x2122, /* TRADE MARK SIGN */
+    0x00B4, /* ACUTE ACCENT */
+    0x00A8, /* DIAERESIS */
+    0x2260, /* NOT EQUAL TO */
+    0x00C6, /* LATIN CAPITAL LIGATURE AE */
+    0x00D8, /* LATIN CAPITAL LETTER O WITH STROKE */
+    0x221E, /* INFINITY */
+    0x00B1, /* PLUS-MINUS SIGN */
+    0x2264, /* LESS-THAN OR EQUAL TO */
+    0x2265, /* GREATER-THAN OR EQUAL TO */
+    0x00A5, /* YEN SIGN */
+    0x00B5, /* MICRO SIGN */
+    0x2202, /* PARTIAL DIFFERENTIAL */
+    0x2211, /* N-ARY SUMMATION */
+    0x220F, /* N-ARY PRODUCT */
+    0x03C0, /* GREEK SMALL LETTER PI */
+    0x222B, /* INTEGRAL */
+    0x00AA, /* FEMININE ORDINAL INDICATOR */
+    0x00BA, /* MASCULINE ORDINAL INDICATOR */
+    0x03A9, /* OHM SIGN (Canonical mapping) */
+    0x00E6, /* LATIN SMALL LIGATURE AE */
+    0x00F8, /* LATIN SMALL LETTER O WITH STROKE */
+    0x00BF, /* INVERTED QUESTION MARK */
+    0x00A1, /* INVERTED EXCLAMATION MARK */
+    0x00AC, /* NOT SIGN */
+    0x221A, /* SQUARE ROOT */
+    0x0192, /* LATIN SMALL LETTER F WITH HOOK */
+    0x2248, /* ALMOST EQUAL TO */
+    0x2206, /* INCREMENT */
+    0x00AB, /* LEFT-POINTING DOUBLE ANGLE QUOTATION MARK */
+    0x00BB, /* RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK */
+    0x2026, /* HORIZONTAL ELLIPSIS */
+    0x00A0, /* NO-BREAK SPACE */
+    0x00C0, /* LATIN CAPITAL LETTER A WITH GRAVE */
+    0x00C3, /* LATIN CAPITAL LETTER A WITH TILDE */
+    0x00D5, /* LATIN CAPITAL LETTER O WITH TILDE */
+    0x0152, /* LATIN CAPITAL LIGATURE OE */
+    0x0153, /* LATIN SMALL LIGATURE OE */
+    0x2013, /* EN DASH */
+    0x2014, /* EM DASH */
+    0x201C, /* LEFT DOUBLE QUOTATION MARK */
+    0x201D, /* RIGHT DOUBLE QUOTATION MARK */
+    0x2018, /* LEFT SINGLE QUOTATION MARK */
+    0x2019, /* RIGHT SINGLE QUOTATION MARK */
+    0x00F7, /* DIVISION SIGN */
+    0x25CA, /* LOZENGE */
+    0x00FF, /* LATIN SMALL LETTER Y WITH DIAERESIS */
+    0x0178, /* LATIN CAPITAL LETTER Y WITH DIAERESIS */
+    0x2044, /* FRACTION SLASH */
+    0x20AC, /* EURO SIGN */
+    0x2039, /* SINGLE LEFT-POINTING ANGLE QUOTATION MARK */
+    0x203A, /* SINGLE RIGHT-POINTING ANGLE QUOTATION MARK */
+    0xFB01, /* LATIN SMALL LIGATURE FI */
+    0xFB02, /* LATIN SMALL LIGATURE FL */
+    0x2021, /* DOUBLE DAGGER */
+    0x00B7, /* MIDDLE DOT */
+    0x201A, /* SINGLE LOW-9 QUOTATION MARK */
+    0x201E, /* DOUBLE LOW-9 QUOTATION MARK */
+    0x2030, /* PER MILLE SIGN */
+    0x00C2, /* LATIN CAPITAL LETTER A WITH CIRCUMFLEX */
+    0x00CA, /* LATIN CAPITAL LETTER E WITH CIRCUMFLEX */
+    0x00C1, /* LATIN CAPITAL LETTER A WITH ACUTE */
+    0x00CB, /* LATIN CAPITAL LETTER E WITH DIAERESIS */
+    0x00C8, /* LATIN CAPITAL LETTER E WITH GRAVE */
+    0x00CD, /* LATIN CAPITAL LETTER I WITH ACUTE */
+    0x00CE, /* LATIN CAPITAL LETTER I WITH CIRCUMFLEX */
+    0x00CF, /* LATIN CAPITAL LETTER I WITH DIAERESIS */
+    0x00CC, /* LATIN CAPITAL LETTER I WITH GRAVE */
+    0x00D3, /* LATIN CAPITAL LETTER O WITH ACUTE */
+    0x00D4, /* LATIN CAPITAL LETTER O WITH CIRCUMFLEX */
+    0xF8FF, /* Apple logo */
+    0x00D2, /* LATIN CAPITAL LETTER O WITH GRAVE */
+    0x00DA, /* LATIN CAPITAL LETTER U WITH ACUTE */
+    0x00DB, /* LATIN CAPITAL LETTER U WITH CIRCUMFLEX */
+    0x00D9, /* LATIN CAPITAL LETTER U WITH GRAVE */
+    0x0131, /* LATIN SMALL LETTER DOTLESS I */
+    0x02C6, /* MODIFIER LETTER CIRCUMFLEX ACCENT */
+    0x02DC, /* SMALL TILDE */
+    0x00AF, /* MACRON */
+    0x02D8, /* BREVE */
+    0x02D9, /* DOT ABOVE */
+    0x02DA, /* RING ABOVE */
+    0x00B8, /* CEDILLA */
+    0x02DD, /* DOUBLE ACUTE ACCENT */
+    0x02DB, /* OGONEK */
+    0x02C7, /* CARON */
+};
+
+static bool __CFFromMacRoman(uint32_t flags, uint8_t byte, UniChar *character) {
+    *character = (byte < 0x80 ? (UniChar)byte : macRoman_to_uni[byte - 0x80]);
+    return true;
+}
+
+static CFIndex __CFToMacRomanPrecompose(uint32_t flags, const UniChar *character, CFIndex numChars, uint8_t *bytes, CFIndex maxByteLen, CFIndex *usedByteLen) {
+    uint8_t byte;
+    CFIndex usedCharLen;
+
+    if (__CFToMacRoman(flags, CFStringEncodingPrecomposeLatinCharacter(character, numChars, &usedCharLen), &byte) && byte && (usedCharLen > 1)) {
+        if (maxByteLen) *bytes = byte;
+        *usedByteLen = 1;
+        return usedCharLen;
+    } else {
+        return 0;
+    }
+}
+
+__private_extern__ const CFStringEncodingConverter __CFConverterMacRoman = {
+    (void*)__CFToMacRoman, (void*)__CFFromMacRoman, 1, 1, kCFStringEncodingConverterCheapEightBit,
+    NULL, NULL, NULL, NULL, __CFToMacRomanPrecompose, CFStringEncodingIsValidCombiningCharacterForLatin1,
+};
+
+/* Win Latin1 (ANSI CodePage 1252) */
+#define NUM_1252_FROM_UNI 27
+static const CFStringEncodingUnicodeTo8BitCharMap cp1252_from_uni[NUM_1252_FROM_UNI] = {
+    {0x0152, 0x8C}, // LATIN CAPITAL LIGATURE OE
+    {0x0153, 0x9C}, // LATIN SMALL LIGATURE OE
+    {0x0160, 0x8A}, // LATIN CAPITAL LETTER S WITH CARON
+    {0x0161, 0x9A}, // LATIN SMALL LETTER S WITH CARON
+    {0x0178, 0x9F}, // LATIN CAPITAL LETTER Y WITH DIAERESIS
+    {0x017D, 0x8E}, // LATIN CAPITAL LETTER Z WITH CARON
+    {0x017E, 0x9E}, // LATIN SMALL LETTER Z WITH CARON
+    {0x0192, 0x83}, // LATIN SMALL LETTER F WITH HOOK
+    {0x02C6, 0x88}, // MODIFIER LETTER CIRCUMFLEX ACCENT
+    {0x02DC, 0x98}, // SMALL TILDE
+    {0x2013, 0x96}, // EN DASH
+    {0x2014, 0x97}, // EM DASH
+    {0x2018, 0x91}, // LEFT SINGLE QUOTATION MARK
+    {0x2019, 0x92}, // RIGHT SINGLE QUOTATION MARK
+    {0x201A, 0x82}, // SINGLE LOW-9 QUOTATION MARK
+    {0x201C, 0x93}, // LEFT DOUBLE QUOTATION MARK
+    {0x201D, 0x94}, // RIGHT DOUBLE QUOTATION MARK
+    {0x201E, 0x84}, // DOUBLE LOW-9 QUOTATION MARK
+    {0x2020, 0x86}, // DAGGER
+    {0x2021, 0x87}, // DOUBLE DAGGER
+    {0x2022, 0x95}, // BULLET
+    {0x2026, 0x85}, // HORIZONTAL ELLIPSIS
+    {0x2030, 0x89}, // PER MILLE SIGN
+    {0x2039, 0x8B}, // SINGLE LEFT-POINTING ANGLE QUOTATION MARK
+    {0x203A, 0x9B}, // SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
+    {0x20AC, 0x80}, // EURO SIGN
+    {0x2122, 0x99}, // TRADE MARK SIGN
+};
+
+static bool __CFToWinLatin1(uint32_t flags, UniChar character, uint8_t *byte) {
+    if ((character < 0x80) || ((character > 0x9F) && (character <= 0x00FF))) {
+        *byte = (uint8_t)character;
+        return true;
+    }
+    return CFStringEncodingUnicodeTo8BitEncoding(cp1252_from_uni, NUM_1252_FROM_UNI, character, byte);
+}
+
+static const uint16_t cp1252_to_uni[32] = {
+    0x20AC, //  EURO SIGN
+    0xFFFD, //  NOT USED
+    0x201A, //  SINGLE LOW-9 QUOTATION MARK
+    0x0192, //  LATIN SMALL LETTER F WITH HOOK
+    0x201E, //  DOUBLE LOW-9 QUOTATION MARK
+    0x2026, //  HORIZONTAL ELLIPSIS
+    0x2020, //  DAGGER
+    0x2021, //  DOUBLE DAGGER
+    0x02C6, //  MODIFIER LETTER CIRCUMFLEX ACCENT
+    0x2030, //  PER MILLE SIGN
+    0x0160, //  LATIN CAPITAL LETTER S WITH CARON
+    0x2039, //  SINGLE LEFT-POINTING ANGLE QUOTATION MARK
+    0x0152, //  LATIN CAPITAL LIGATURE OE
+    0xFFFD, //  NOT USED
+    0x017D, //  LATIN CAPITAL LETTER Z WITH CARON
+    0xFFFD, //  NOT USED
+    0xFFFD, //  NOT USED
+    0x2018, //  LEFT SINGLE QUOTATION MARK
+    0x2019, //  RIGHT SINGLE QUOTATION MARK
+    0x201C, //  LEFT DOUBLE QUOTATION MARK
+    0x201D, //  RIGHT DOUBLE QUOTATION MARK
+    0x2022, //  BULLET
+    0x2013, //  EN DASH
+    0x2014, //  EM DASH
+    0x02DC, //  SMALL TILDE
+    0x2122, //  TRADE MARK SIGN
+    0x0161, //  LATIN SMALL LETTER S WITH CARON
+    0x203A, //  SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
+    0x0153, //  LATIN SMALL LIGATURE OE
+    0xFFFD, //  NOT USED
+    0x017E, //  LATIN SMALL LETTER Z WITH CARON
+    0x0178, //  LATIN CAPITAL LETTER Y WITH DIAERESIS
+};
+
+static bool __CFFromWinLatin1(uint32_t flags, uint8_t byte, UniChar *character) {
+    *character = (byte < 0x80 || byte > 0x9F ? (UniChar)byte : cp1252_to_uni[byte - 0x80]);
+    return (*character != 0xFFFD);
+}
+
+static CFIndex __CFToWinLatin1Precompose(uint32_t flags, const UniChar *character, CFIndex numChars, uint8_t *bytes, CFIndex maxByteLen, CFIndex *usedByteLen) {
+    uint8_t byte;
+    CFIndex usedCharLen;
+
+    if (__CFToWinLatin1(flags, CFStringEncodingPrecomposeLatinCharacter(character, numChars, &usedCharLen), &byte) && byte && (usedCharLen > 1)) {
+        if (maxByteLen) *bytes = byte;
+        *usedByteLen = 1;
+        return usedCharLen;
+    } else {
+        return 0;
+    }
+}
+
+__private_extern__ const CFStringEncodingConverter __CFConverterWinLatin1 = {
+    (void*)__CFToWinLatin1, (void*)__CFFromWinLatin1, 1, 1, kCFStringEncodingConverterCheapEightBit,
+    NULL, NULL, NULL, NULL, __CFToWinLatin1Precompose, CFStringEncodingIsValidCombiningCharacterForLatin1,
+};
+
+/* NEXTSTEP Encoding */
+#define NUM_NEXTSTEP_FROM_UNI	127
+
+static const CFStringEncodingUnicodeTo8BitCharMap nextstep_from_tab[NUM_NEXTSTEP_FROM_UNI] = {
+        { 0x00a0, 0x80 },
+        { 0x00a1, 0xa1 },
+        { 0x00a2, 0xa2 },
+        { 0x00a3, 0xa3 },
+        { 0x00a4, 0xa8 },
+        { 0x00a5, 0xa5 },
+        { 0x00a6, 0xb5 },
+        { 0x00a7, 0xa7 },
+        { 0x00a8, 0xc8 },
+        { 0x00a9, 0xa0 },
+        { 0x00aa, 0xe3 },
+        { 0x00ab, 0xab },
+        { 0x00ac, 0xbe },
+/*	{ 0x00ad, 0x2d }, <= 96/10/25 rick removed; converts soft-hyphen to hyphen! */
+        { 0x00ae, 0xb0 },
+        { 0x00af, 0xc5 },
+        { 0x00b1, 0xd1 },
+        { 0x00b2, 0xc9 },
+        { 0x00b3, 0xcc },
+        { 0x00b4, 0xc2 },
+        { 0x00b5, 0x9d },
+        { 0x00b6, 0xb6 },
+        { 0x00b7, 0xb4 },
+        { 0x00b8, 0xcb },
+        { 0x00b9, 0xc0 },
+        { 0x00ba, 0xeb },
+        { 0x00bb, 0xbb },
+        { 0x00bc, 0xd2 },
+        { 0x00bd, 0xd3 },
+        { 0x00be, 0xd4 },
+        { 0x00bf, 0xbf },
+        { 0x00c0, 0x81 },
+        { 0x00c1, 0x82 },
+        { 0x00c2, 0x83 },
+        { 0x00c3, 0x84 },
+        { 0x00c4, 0x85 },
+        { 0x00c5, 0x86 },
+        { 0x00c6, 0xe1 },
+        { 0x00c7, 0x87 },
+        { 0x00c8, 0x88 },
+        { 0x00c9, 0x89 },
+        { 0x00ca, 0x8a },
+        { 0x00cb, 0x8b },
+        { 0x00cc, 0x8c },
+        { 0x00cd, 0x8d },
+        { 0x00ce, 0x8e },
+        { 0x00cf, 0x8f },
+        { 0x00d0, 0x90 },
+        { 0x00d1, 0x91 },
+        { 0x00d2, 0x92 },
+        { 0x00d3, 0x93 },
+        { 0x00d4, 0x94 },
+        { 0x00d5, 0x95 },
+        { 0x00d6, 0x96 },
+        { 0x00d7, 0x9e },
+        { 0x00d8, 0xe9 },
+        { 0x00d9, 0x97 },
+        { 0x00da, 0x98 },
+        { 0x00db, 0x99 },
+        { 0x00dc, 0x9a },
+        { 0x00dd, 0x9b },
+        { 0x00de, 0x9c },
+        { 0x00df, 0xfb },
+        { 0x00e0, 0xd5 },
+        { 0x00e1, 0xd6 },
+        { 0x00e2, 0xd7 },
+        { 0x00e3, 0xd8 },
+        { 0x00e4, 0xd9 },
+        { 0x00e5, 0xda },
+        { 0x00e6, 0xf1 },
+        { 0x00e7, 0xdb },
+        { 0x00e8, 0xdc },
+        { 0x00e9, 0xdd },
+        { 0x00ea, 0xde },
+        { 0x00eb, 0xdf },
+        { 0x00ec, 0xe0 },
+        { 0x00ed, 0xe2 },
+        { 0x00ee, 0xe4 },
+        { 0x00ef, 0xe5 },
+        { 0x00f0, 0xe6 },
+        { 0x00f1, 0xe7 },
+        { 0x00f2, 0xec },
+        { 0x00f3, 0xed },
+        { 0x00f4, 0xee },
+        { 0x00f5, 0xef },
+        { 0x00f6, 0xf0 },
+        { 0x00f7, 0x9f },
+        { 0x00f8, 0xf9 },
+        { 0x00f9, 0xf2 },
+        { 0x00fa, 0xf3 },
+        { 0x00fb, 0xf4 },
+        { 0x00fc, 0xf6 },
+        { 0x00fd, 0xf7 },
+        { 0x00fe, 0xfc },
+        { 0x00ff, 0xfd },
+        { 0x0131, 0xf5 },
+        { 0x0141, 0xe8 },
+        { 0x0142, 0xf8 },
+        { 0x0152, 0xea },
+        { 0x0153, 0xfa },
+        { 0x0192, 0xa6 },
+        { 0x02c6, 0xc3 },
+        { 0x02c7, 0xcf },
+        { 0x02cb, 0xc1 },
+        { 0x02d8, 0xc6 },
+        { 0x02d9, 0xc7 },
+        { 0x02da, 0xca },
+        { 0x02db, 0xce },
+        { 0x02dc, 0xc4 },
+        { 0x02dd, 0xcd },
+        { 0x2013, 0xb1 },
+        { 0x2014, 0xd0 },
+        { 0x2019, 0xa9 },
+        { 0x201a, 0xb8 },
+        { 0x201c, 0xaa },
+        { 0x201d, 0xba },
+        { 0x201e, 0xb9 },
+        { 0x2020, 0xb2 },
+        { 0x2021, 0xb3 },
+        { 0x2022, 0xb7 },
+        { 0x2026, 0xbc },
+        { 0x2030, 0xbd },
+        { 0x2039, 0xac },
+        { 0x203a, 0xad },
+        { 0x2044, 0xa4 },
+        { 0xfb01, 0xae },
+        { 0xfb02, 0xaf },
+        { 0xfffd, 0xff },
+};
+
+static bool __CFToNextStepLatin(uint32_t flags, UniChar character, uint8_t *byte) {
+    if (character < 0x80) {
+        *byte = (uint8_t)character;
+        return true;
+    } else if (__CFIsParagraphSeparator(character)) {
+        *byte = ASCIINewLine;
+        return true;
+    } else {
+        return CFStringEncodingUnicodeTo8BitEncoding(nextstep_from_tab, NUM_NEXTSTEP_FROM_UNI, character, byte);
+    }
+};
+
+static const UniChar NSToPrecompUnicodeTable[128] = {
+        /* NextStep Encoding	Unicode */
+        /*  128	figspace */	0x00a0,		/* 0x2007 is fig space */
+        /*  129	Agrave */	0x00c0,
+        /*  130	Aacute */	0x00c1,
+        /*  131	Acircumflex */	0x00c2,
+        /*  132	Atilde */	0x00c3,
+        /*  133	Adieresis */	0x00c4,
+        /*  134	Aring */	0x00c5,
+        /*  135	Ccedilla */	0x00c7,
+        /*  136	Egrave */	0x00c8,
+        /*  137	Eacute */	0x00c9,
+        /*  138	Ecircumflex */	0x00ca,
+        /*  139	Edieresis */	0x00cb,
+        /*  140	Igrave */	0x00cc,
+        /*  141	Iacute */	0x00cd,
+        /*  142	Icircumflex */	0x00ce,
+        /*  143	Idieresis */	0x00cf,
+        /*  144	Eth */		0x00d0,
+        /*  145	Ntilde */	0x00d1,
+        /*  146	Ograve */	0x00d2,
+        /*  147	Oacute */	0x00d3,
+        /*  148	Ocircumflex */	0x00d4,
+        /*  149	Otilde */	0x00d5,
+        /*  150	Odieresis */	0x00d6,
+        /*  151	Ugrave */	0x00d9,
+        /*  152	Uacute */	0x00da,
+        /*  153	Ucircumflex */	0x00db,
+        /*  154	Udieresis */	0x00dc,
+        /*  155	Yacute */	0x00dd,
+        /*  156	Thorn */	0x00de,
+        /*  157	mu */		0x00b5,
+        /*  158	multiply */	0x00d7,
+        /*  159	divide */	0x00f7,
+        /*  160	copyright */	0x00a9,
+        /*  161	exclamdown */	0x00a1,
+        /*  162	cent */		0x00a2,
+        /*  163	sterling */	0x00a3,
+        /*  164	fraction */	0x2044,
+        /*  165	yen */		0x00a5,
+        /*  166	florin */	0x0192,
+        /*  167	section */	0x00a7,
+        /*  168	currency */	0x00a4,
+        /*  169	quotesingle */	0x2019,
+        /*  170	quotedblleft */	0x201c,
+        /*  171	guillemotleft */ 0x00ab,
+        /*  172	guilsinglleft */ 0x2039,
+        /*  173	guilsinglright */ 0x203a,
+        /*  174	fi */		0xFB01,
+        /*  175	fl */		0xFB02,
+        /*  176	registered */	0x00ae,
+        /*  177	endash */	0x2013,
+        /*  178	dagger */	0x2020,
+        /*  179	daggerdbl */	0x2021,
+        /*  180	periodcentered */ 0x00b7,
+        /*  181	brokenbar */	0x00a6,
+        /*  182	paragraph */	0x00b6,
+        /*  183	bullet */	0x2022,
+        /*  184	quotesinglbase */ 0x201a,
+        /*  185	quotedblbase */	0x201e,
+        /*  186	quotedblright */ 0x201d,
+        /*  187	guillemotright */ 0x00bb,
+        /*  188	ellipsis */	0x2026,
+        /*  189	perthousand */	0x2030,
+        /*  190	logicalnot */	0x00ac,
+        /*  191	questiondown */	0x00bf,
+        /*  192	onesuperior */	0x00b9,
+        /*  193	grave */	0x02cb,
+        /*  194	acute */	0x00b4,
+        /*  195	circumflex */	0x02c6,
+        /*  196	tilde */	0x02dc,
+        /*  197	macron */	0x00af,
+        /*  198	breve */	0x02d8,
+        /*  199	dotaccent */	0x02d9,
+        /*  200	dieresis */	0x00a8,
+        /*  201	twosuperior */	0x00b2,
+        /*  202	ring */		0x02da,
+        /*  203	cedilla */	0x00b8,
+        /*  204	threesuperior */ 0x00b3,
+        /*  205	hungarumlaut */	0x02dd,
+        /*  206	ogonek */	0x02db,
+        /*  207	caron */	0x02c7,
+        /*  208	emdash */	0x2014,
+        /*  209	plusminus */	0x00b1,
+        /*  210	onequarter */	0x00bc,
+        /*  211	onehalf */	0x00bd,
+        /*  212	threequarters */ 0x00be,
+        /*  213	agrave */	0x00e0,
+        /*  214	aacute */	0x00e1,
+        /*  215	acircumflex */	0x00e2,
+        /*  216	atilde */	0x00e3,
+        /*  217	adieresis */	0x00e4,
+        /*  218	aring */	0x00e5,
+        /*  219	ccedilla */	0x00e7,
+        /*  220	egrave */	0x00e8,
+        /*  221	eacute */	0x00e9,
+        /*  222	ecircumflex */	0x00ea,
+        /*  223	edieresis */	0x00eb,
+        /*  224	igrave */	0x00ec,
+        /*  225	AE */		0x00c6,
+        /*  226	iacute */	0x00ed,
+        /*  227	ordfeminine */	0x00aa,
+        /*  228	icircumflex */	0x00ee,
+        /*  229	idieresis */	0x00ef,
+        /*  230	eth */		0x00f0,
+        /*  231	ntilde */	0x00f1,
+        /*  232	Lslash */	0x0141,
+        /*  233	Oslash */	0x00d8,
+        /*  234	OE */		0x0152,
+        /*  235	ordmasculine */	0x00ba,
+        /*  236	ograve */	0x00f2,
+        /*  237	oacute */	0x00f3,
+        /*  238	ocircumflex */	0x00f4,
+        /*  239	otilde */	0x00f5,
+        /*  240	odieresis */	0x00f6,
+        /*  241	ae */		0x00e6,
+        /*  242	ugrave */	0x00f9,
+        /*  243	uacute */	0x00fa,
+        /*  244	ucircumflex */	0x00fb,
+        /*  245	dotlessi */	0x0131,
+        /*  246	udieresis */	0x00fc,
+        /*  247	yacute */	0x00fd,
+        /*  248	lslash */	0x0142,
+        /*  249	oslash */	0x00f8,
+        /*  250	oe */		0x0153,
+        /*  251	germandbls */	0x00df,
+        /*  252	thorn */	0x00fe,
+        /*  253	ydieresis */	0x00ff,
+        /*  254	.notdef */	0xFFFD,
+        /*  255	.notdef */	0xFFFD
+};
+
+static bool __CFFromNextStepLatin(uint32_t flags, uint8_t byte, UniChar *character) {
+    return ((*character = (byte < 0x80 ? (UniChar)byte : NSToPrecompUnicodeTable[byte - 0x80])) != 0xFFFD);
+}
+
+static CFIndex __CFToNextStepLatinPrecompose(uint32_t flags, const UniChar *character, CFIndex numChars, uint8_t *bytes, CFIndex maxByteLen, CFIndex *usedByteLen) {
+    uint8_t byte;
+    CFIndex usedCharLen;
+
+    if (__CFToNextStepLatin(flags, CFStringEncodingPrecomposeLatinCharacter(character, numChars, &usedCharLen), &byte) && byte && (usedCharLen > 1)) {
+        if (maxByteLen) *bytes = byte;
+        *usedByteLen = 1;
+        return usedCharLen;
+    } else {
+        return 0;
+    }
+}
+
+__private_extern__ const CFStringEncodingConverter __CFConverterNextStepLatin = {
+    (void*)__CFToNextStepLatin, (void*)__CFFromNextStepLatin, 1, 1, kCFStringEncodingConverterCheapEightBit,
+    NULL, NULL, NULL, NULL, __CFToNextStepLatinPrecompose, CFStringEncodingIsValidCombiningCharacterForLatin1,
+};
+
+/* UTF8 */
+/*
+ * Copyright 2001 Unicode, Inc.
+ * 
+ * Disclaimer
+ * 
+ * This source code is provided as is by Unicode, Inc. No claims are
+ * made as to fitness for any particular purpose. No warranties of any
+ * kind are expressed or implied. The recipient agrees to determine
+ * applicability of information provided. If this file has been
+ * purchased on magnetic or optical media from Unicode, Inc., the
+ * sole remedy for any claim will be exchange of defective media
+ * within 90 days of receipt.
+ * 
+ * Limitations on Rights to Redistribute This Code
+ * 
+ * Unicode, Inc. hereby grants the right to freely use the information
+ * supplied in this file in the creation of products supporting the
+ * Unicode Standard, and to make copies of this file in any form
+ * for internal or external distribution as long as this notice
+ * remains attached.
+ */
+
+static const uint32_t kReplacementCharacter =   0x0000FFFDUL;
+static const uint32_t kMaximumUCS2 =		0x0000FFFFUL;
+static const uint32_t kMaximumUTF16 =		0x0010FFFFUL;
+static const uint32_t kMaximumUCS4 =		0x7FFFFFFFUL;
+
+static const int halfShift			= 10;
+static const uint32_t halfBase		= 0x0010000UL;
+static const uint32_t halfMask		= 0x3FFUL;
+static const uint32_t kSurrogateHighStart	= 0xD800UL;
+static const uint32_t kSurrogateHighEnd	= 0xDBFFUL;
+static const uint32_t kSurrogateLowStart	= 0xDC00UL;
+static const uint32_t kSurrogateLowEnd	= 0xDFFFUL;
+
+/*
+ * Index into the table below with the first byte of a UTF-8 sequence to
+ * get the number of trailing bytes that are supposed to follow it.
+ */
+static const char trailingBytesForUTF8[256] = {
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+	2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5
+};
+
+/*
+ * Magic values subtracted from a buffer value during UTF8 conversion.
+ * This table contains as many values as there might be trailing bytes
+ * in a UTF-8 sequence.
+ */
+static const UTF32Char offsetsFromUTF8[6] = { 0x00000000UL, 0x00003080UL, 0x000E2080UL, 
+					 0x03C82080UL, 0xFA082080UL, 0x82082080UL };
+
+static const uint8_t firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
+
+/* This code is similar in effect to making successive calls on the mbtowc and wctomb routines in FSS-UTF. However, it is considerably different in code:
+        * it is adapted to be consistent with UTF16,
+        * constants have been gathered.
+        * loops & conditionals have been removed as much as possible for
+        * efficiency, in favor of drop-through switch statements.
+*/
+
+CF_INLINE uint16_t __CFUTF8BytesToWriteForCharacter(uint32_t ch) {
+    if (ch < 0x80) return  1;
+    else if (ch < 0x800) return 2;
+    else if (ch < 0x10000) return 3;
+    else if (ch < 0x200000) return 4;
+    else if (ch < 0x4000000) return 5;
+    else if (ch <= kMaximumUCS4) return 6;
+    else return 0;
+}
+
+CF_INLINE uint16_t __CFToUTF8Core(uint32_t ch, uint8_t *bytes, uint32_t maxByteLen) {
+    uint16_t bytesToWrite = __CFUTF8BytesToWriteForCharacter(ch);
+    const uint32_t byteMask = 0xBF;
+    const uint32_t byteMark = 0x80;
+
+    if (!bytesToWrite) {
+        bytesToWrite = 2;
+        ch = kReplacementCharacter;
+    }
+
+    if (maxByteLen < bytesToWrite) return 0;
+
+    switch (bytesToWrite) {	/* note: code falls through cases! */
+        case 6: bytes[5] = (ch | byteMark) & byteMask; ch >>= 6;
+        case 5: bytes[4] = (ch | byteMark) & byteMask; ch >>= 6;
+        case 4: bytes[3] = (ch | byteMark) & byteMask; ch >>= 6;
+        case 3: bytes[2] = (ch | byteMark) & byteMask; ch >>= 6;
+        case 2: bytes[1] = (ch | byteMark) & byteMask; ch >>= 6;
+        case 1: bytes[0] =  ch | firstByteMark[bytesToWrite];
+    }
+    return bytesToWrite;
+}
+
+static CFIndex __CFToUTF8(uint32_t flags, const UniChar *characters, CFIndex numChars, uint8_t *bytes, CFIndex maxByteLen, CFIndex *usedByteLen) {
+    uint16_t bytesWritten;
+    uint32_t ch;
+    const UniChar *beginCharacter = characters;
+    const UniChar *endCharacter = characters + numChars;
+    const uint8_t *beginBytes = bytes;
+    const uint8_t *endBytes = bytes + maxByteLen;
+    bool isStrict = (flags & kCFStringEncodingUseHFSPlusCanonical ? false : true);
+
+    while ((characters < endCharacter) && (!maxByteLen || (bytes < endBytes))) {
+        ch = *(characters++);
+
+        if (ch < 0x80) { // ASCII
+            if (maxByteLen) *bytes = ch;
+            ++bytes;
+        } else {
+            if (ch >= kSurrogateHighStart) {
+                if (ch <= kSurrogateHighEnd) {
+                    if ((characters < endCharacter) && ((*characters >= kSurrogateLowStart) && (*characters <= kSurrogateLowEnd))) {
+                        ch = ((ch - kSurrogateHighStart) << halfShift) + (*(characters++) - kSurrogateLowStart) + halfBase;
+                    } else if (isStrict) {
+                        --characters;
+                        break;
+                    }
+                } else if (isStrict && (ch <= kSurrogateLowEnd)) {
+                    --characters;
+                    break;
+                }
+            }
+    
+            if (!(bytesWritten = (maxByteLen ? __CFToUTF8Core(ch, bytes, endBytes - bytes) : __CFUTF8BytesToWriteForCharacter(ch)))) {
+                characters -= (ch < 0x10000 ? 1 : 2);
+                break;
+            }
+            bytes += bytesWritten;
+        }
+    }
+
+    if (usedByteLen) *usedByteLen = bytes - beginBytes;
+    return characters - beginCharacter;
+}
+
+/*
+ * Utility routine to tell whether a sequence of bytes is legal UTF-8.
+ * This must be called with the length pre-determined by the first byte.
+ * If not calling this from ConvertUTF8to*, then the length can be set by:
+ *	length = trailingBytesForUTF8[*source]+1;
+ * and the sequence is illegal right away if there aren't that many bytes
+ * available.
+ * If presented with a length > 4, this returns false.  The Unicode
+ * definition of UTF-8 goes up to 4-byte sequences.
+ */
+
+CF_INLINE bool __CFIsLegalUTF8(const uint8_t *source, CFIndex length) {
+    if (length > 4) return false;
+
+    const uint8_t *srcptr = source+length;
+    uint8_t head = *source;
+
+    while (--srcptr > source) if ((*srcptr & 0xC0) != 0x80) return false;
+
+    if (((head >= 0x80) && (head < 0xC2)) || (head > 0xF4)) return false;
+
+    if (((head == 0xE0) && (*(source + 1) < 0xA0)) || ((head == 0xED) && (*(source + 1) > 0x9F)) || ((head == 0xF0) && (*(source + 1) < 0x90)) || ((head == 0xF4) && (*(source + 1) > 0x8F))) return false;
+    return true;
+}
+
+static CFIndex __CFFromUTF8(uint32_t flags, const uint8_t *bytes, CFIndex numBytes, UniChar *characters, CFIndex maxCharLen, CFIndex *usedCharLen) {
+    const uint8_t *source = bytes;
+    uint16_t extraBytesToRead;
+    CFIndex theUsedCharLen = 0;
+    uint32_t ch;
+    bool isHFSPlus = (flags & kCFStringEncodingUseHFSPlusCanonical ? true : false);
+    bool needsToDecompose = (flags & kCFStringEncodingUseCanonical || isHFSPlus ? true : false);
+    bool strictUTF8 = (flags & kCFStringEncodingLenientUTF8Conversion ? false : true);
+    UTF32Char decomposed[MAX_DECOMPOSED_LENGTH];
+    CFIndex decompLength;
+    bool isStrict = !isHFSPlus;
+
+    while (numBytes && (!maxCharLen || (theUsedCharLen < maxCharLen))) {
+        extraBytesToRead = trailingBytesForUTF8[*source];
+
+        if (extraBytesToRead > --numBytes) break;
+        numBytes -= extraBytesToRead;
+
+        /* Do this check whether lenient or strict */
+        // We need to allow 0xA9 (copyright in MacRoman and Unicode) not to break existing apps
+        // Will use a flag passed in from upper layers to switch restriction mode for this case in the next release
+        if ((extraBytesToRead > 3) || (strictUTF8 && !__CFIsLegalUTF8(source, extraBytesToRead + 1))) {
+            if ((*source == 0xA9) || (flags & kCFStringEncodingAllowLossyConversion)) {
+                numBytes += extraBytesToRead;
+                ++source;
+                if (maxCharLen) *(characters++) = (UTF16Char)kReplacementCharacter;
+                ++theUsedCharLen;
+                continue;
+            } else {
+                break;
+            }
+        }
+
+        ch = 0;
+        /*
+         * The cases all fall through. See "Note A" below.
+         */
+        switch (extraBytesToRead) {
+            case 3:	ch += *source++; ch <<= 6;
+            case 2:	ch += *source++; ch <<= 6;
+            case 1:	ch += *source++; ch <<= 6;
+            case 0:	ch += *source++;
+        }
+        ch -= offsetsFromUTF8[extraBytesToRead];
+
+        if (ch <= kMaximumUCS2) {
+            if (isStrict && (ch >= kSurrogateHighStart && ch <= kSurrogateLowEnd)) {
+                source -= (extraBytesToRead + 1);
+                break;
+            }
+            if (needsToDecompose && CFUniCharIsDecomposableCharacter(ch, isHFSPlus)) {
+                decompLength = CFUniCharDecomposeCharacter(ch, decomposed, MAX_DECOMPOSED_LENGTH);
+
+                if (maxCharLen) {
+                    if (!CFUniCharFillDestinationBuffer(decomposed, decompLength, (void **)&characters, maxCharLen, &theUsedCharLen, kCFUniCharUTF16Format)) break;
+                } else {
+                    theUsedCharLen += decompLength;
+                }
+            } else {
+                if (maxCharLen) *(characters++) = (UTF16Char)ch;
+                ++theUsedCharLen;
+            }
+        } else if (ch > kMaximumUTF16) {
+            if (isStrict) {
+                source -= (extraBytesToRead + 1);
+                break;
+            }
+            if (maxCharLen) *(characters++) = (UTF16Char)kReplacementCharacter;
+            ++theUsedCharLen;
+        } else {
+            if (needsToDecompose && CFUniCharIsDecomposableCharacter(ch, isHFSPlus)) {
+                decompLength = CFUniCharDecomposeCharacter(ch, decomposed, MAX_DECOMPOSED_LENGTH);
+
+                if (maxCharLen) {
+                    if (!CFUniCharFillDestinationBuffer(decomposed, decompLength, (void **)&characters, maxCharLen, &theUsedCharLen, kCFUniCharUTF16Format)) break;
+                } else {
+                    while (--decompLength >= 0) theUsedCharLen += (decomposed[decompLength] < 0x10000 ? 1 : 2);
+                }
+            } else {
+                if (maxCharLen) {
+                    if ((theUsedCharLen + 2) > maxCharLen) break;
+                    ch -= halfBase;
+                    *(characters++) = (ch >> halfShift) + kSurrogateHighStart;
+                    *(characters++) = (ch & halfMask) + kSurrogateLowStart;
+                }
+                theUsedCharLen += 2;
+            }
+        }
+    }
+
+    if (usedCharLen) *usedCharLen = theUsedCharLen;
+
+    return source - bytes;
+}
+
+static CFIndex __CFToUTF8Len(uint32_t flags, const UniChar *characters, CFIndex numChars) {
+    uint32_t bytesToWrite = 0;
+    uint32_t ch;
+
+    while (numChars) {
+        ch = *characters++;
+        numChars--;
+        if ((ch >= kSurrogateHighStart && ch <= kSurrogateHighEnd) && numChars && (*characters >= kSurrogateLowStart && *characters <= kSurrogateLowEnd)) {
+            ch = ((ch - kSurrogateHighStart) << halfShift) + (*characters++ - kSurrogateLowStart) + halfBase;
+            numChars--;
+        }
+        bytesToWrite += __CFUTF8BytesToWriteForCharacter(ch);
+    }
+
+    return bytesToWrite;
+}
+
+static CFIndex __CFFromUTF8Len(uint32_t flags, const uint8_t *source, CFIndex numBytes) {
+    uint16_t extraBytesToRead;
+    CFIndex theUsedCharLen = 0;
+    uint32_t ch;
+    bool isHFSPlus = (flags & kCFStringEncodingUseHFSPlusCanonical ? true : false);
+    bool needsToDecompose = (flags & kCFStringEncodingUseCanonical || isHFSPlus ? true : false);
+    bool strictUTF8 = (flags & kCFStringEncodingLenientUTF8Conversion ? false : true);
+    UTF32Char decomposed[MAX_DECOMPOSED_LENGTH];
+    CFIndex decompLength;
+    bool isStrict = !isHFSPlus;
+
+    while (numBytes) {
+        extraBytesToRead = trailingBytesForUTF8[*source];
+
+        if (extraBytesToRead > --numBytes) break;
+        numBytes -= extraBytesToRead;
+
+        /* Do this check whether lenient or strict */
+        // We need to allow 0xA9 (copyright in MacRoman and Unicode) not to break existing apps
+        // Will use a flag passed in from upper layers to switch restriction mode for this case in the next release
+        if ((extraBytesToRead > 3) || (strictUTF8 && !__CFIsLegalUTF8(source, extraBytesToRead + 1))) {
+            if ((*source == 0xA9) || (flags & kCFStringEncodingAllowLossyConversion)) {
+                numBytes += extraBytesToRead;
+                ++source;
+                ++theUsedCharLen;
+                continue;
+            } else {
+                break;
+            }
+        }
+
+
+        ch = 0;
+        /*
+         * The cases all fall through. See "Note A" below.
+         */
+        switch (extraBytesToRead) {
+            case 3:	ch += *source++; ch <<= 6;
+            case 2:	ch += *source++; ch <<= 6;
+            case 1:	ch += *source++; ch <<= 6;
+            case 0:	ch += *source++;
+        }
+        ch -= offsetsFromUTF8[extraBytesToRead];
+
+        if (ch <= kMaximumUCS2) {
+            if (isStrict && (ch >= kSurrogateHighStart && ch <= kSurrogateLowEnd)) {
+                break;
+            }
+            if (needsToDecompose && CFUniCharIsDecomposableCharacter(ch, isHFSPlus)) {
+                decompLength = CFUniCharDecomposeCharacter(ch, decomposed, MAX_DECOMPOSED_LENGTH);
+                theUsedCharLen += decompLength;
+            } else {
+                ++theUsedCharLen;
+            }
+        } else if (ch > kMaximumUTF16) {
+            ++theUsedCharLen;
+        } else {
+            if (needsToDecompose && CFUniCharIsDecomposableCharacter(ch, isHFSPlus)) {
+                decompLength = CFUniCharDecomposeCharacter(ch, decomposed, MAX_DECOMPOSED_LENGTH);
+                while (--decompLength >= 0) theUsedCharLen += (decomposed[decompLength] < 0x10000 ? 1 : 2);
+            } else {
+                theUsedCharLen += 2;
+            }
+        }
+    }
+
+    return theUsedCharLen;
+}
+
+__private_extern__ const CFStringEncodingConverter __CFConverterUTF8 = {
+    (void*)__CFToUTF8, (void*)__CFFromUTF8, 3, 2, kCFStringEncodingConverterStandard,
+    __CFToUTF8Len, __CFFromUTF8Len, NULL, NULL, NULL, NULL,
+};
diff --git a/CoreFoundation/CFBundle.c b/CoreFoundation/CFBundle.c
new file mode 100644
index 0000000..e25bff0
--- /dev/null
+++ b/CoreFoundation/CFBundle.c
@@ -0,0 +1,4051 @@
+/*
+ * Copyright (c) 2008-2009 Brent Fulgham <bfulgham@gmail.org>.  All rights reserved.
+ * Copyright (c) 2009 Grant Erickson <gerickson@nuovations.com>. All rights reserved.
+ *
+ * This source code is a modified version of the CoreFoundation sources released by Apple Inc. under
+ * the terms of the APSL version 2.0 (see below).
+ *
+ * For information about changes from the original Apple source release can be found by reviewing the
+ * source control system for the project at https://sourceforge.net/svn/?group_id=246198.
+ *
+ * The original license information is as follows:
+ * 
+ * Copyright (c) 2008 Apple Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*	CFBundle.c
+	Copyright (c) 1999-2007 Apple Inc.  All rights reserved.
+	Responsibility: Doug Davidson
+*/
+
+#include "CFBundle_Internal.h"
+#include <CoreFoundation/CFPropertyList.h>
+#include <CoreFoundation/CFNumber.h>
+#include <CoreFoundation/CFSet.h>
+#include <CoreFoundation/CFURLAccess.h>
+#include <CoreFoundation/CFError.h>
+#include <string.h>
+#include "CFPriv.h"
+#include "CFInternal.h"
+#include <CoreFoundation/CFByteOrder.h>
+#include "CFBundle_BinaryTypes.h"
+#include <ctype.h>
+#include <sys/stat.h>
+#include <stdlib.h>
+
+#if defined(BINARY_SUPPORT_DYLD)
+// Import the mach-o headers that define the macho magic numbers
+#include <mach-o/loader.h>
+#include <mach-o/fat.h>
+#include <mach-o/arch.h>
+#include <mach-o/dyld.h>
+#include <mach-o/getsect.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+#endif /* BINARY_SUPPORT_DYLD */
+
+#if defined(BINARY_SUPPORT_DLFCN)
+#include <dlfcn.h>
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_SOLARIS
+#define CF_RTLD_FIRST	RTLD_FIRST
+#else
+#define CF_RTLD_FIRST	0
+#endif /* DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_SOLARIS */
+#endif /* BINARY_SUPPORT_DLFCN */
+
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX
+#include <fcntl.h>
+#endif
+
+#if DEPLOYMENT_TARGET_WINDOWS
+#include <io.h>
+#include <stdio.h>
+#define lseek _lseek
+#define open _open
+#define read _read
+#define write _write
+#define close _close
+#endif
+
+#if DEPLOYMENT_TARGET_LINUX
+#include <unistd.h>
+#endif
+
+#define LOG_BUNDLE_LOAD 0
+
+// Public CFBundle Info plist keys
+CONST_STRING_DECL(kCFBundleInfoDictionaryVersionKey, "CFBundleInfoDictionaryVersion")
+CONST_STRING_DECL(kCFBundleExecutableKey, "CFBundleExecutable")
+CONST_STRING_DECL(kCFBundleIdentifierKey, "CFBundleIdentifier")
+CONST_STRING_DECL(kCFBundleVersionKey, "CFBundleVersion")
+CONST_STRING_DECL(kCFBundleDevelopmentRegionKey, "CFBundleDevelopmentRegion")
+CONST_STRING_DECL(kCFBundleLocalizationsKey, "CFBundleLocalizations")
+
+// Finder stuff
+CONST_STRING_DECL(_kCFBundlePackageTypeKey, "CFBundlePackageType")
+CONST_STRING_DECL(_kCFBundleSignatureKey, "CFBundleSignature")
+CONST_STRING_DECL(_kCFBundleIconFileKey, "CFBundleIconFile")
+CONST_STRING_DECL(_kCFBundleDocumentTypesKey, "CFBundleDocumentTypes")
+CONST_STRING_DECL(_kCFBundleURLTypesKey, "CFBundleURLTypes")
+
+// Keys that are usually localized in InfoPlist.strings
+CONST_STRING_DECL(kCFBundleNameKey, "CFBundleName")
+CONST_STRING_DECL(_kCFBundleDisplayNameKey, "CFBundleDisplayName")
+CONST_STRING_DECL(_kCFBundleShortVersionStringKey, "CFBundleShortVersionString")
+CONST_STRING_DECL(_kCFBundleGetInfoStringKey, "CFBundleGetInfoString")
+CONST_STRING_DECL(_kCFBundleGetInfoHTMLKey, "CFBundleGetInfoHTML")
+
+// Sub-keys for CFBundleDocumentTypes dictionaries
+CONST_STRING_DECL(_kCFBundleTypeNameKey, "CFBundleTypeName")
+CONST_STRING_DECL(_kCFBundleTypeRoleKey, "CFBundleTypeRole")
+CONST_STRING_DECL(_kCFBundleTypeIconFileKey, "CFBundleTypeIconFile")
+CONST_STRING_DECL(_kCFBundleTypeOSTypesKey, "CFBundleTypeOSTypes")
+CONST_STRING_DECL(_kCFBundleTypeExtensionsKey, "CFBundleTypeExtensions")
+CONST_STRING_DECL(_kCFBundleTypeMIMETypesKey, "CFBundleTypeMIMETypes")
+
+// Sub-keys for CFBundleURLTypes dictionaries
+CONST_STRING_DECL(_kCFBundleURLNameKey, "CFBundleURLName")
+CONST_STRING_DECL(_kCFBundleURLIconFileKey, "CFBundleURLIconFile")
+CONST_STRING_DECL(_kCFBundleURLSchemesKey, "CFBundleURLSchemes")
+
+// Compatibility key names
+CONST_STRING_DECL(_kCFBundleOldExecutableKey, "NSExecutable")
+CONST_STRING_DECL(_kCFBundleOldInfoDictionaryVersionKey, "NSInfoPlistVersion")
+CONST_STRING_DECL(_kCFBundleOldNameKey, "NSHumanReadableName")
+CONST_STRING_DECL(_kCFBundleOldIconFileKey, "NSIcon")
+CONST_STRING_DECL(_kCFBundleOldDocumentTypesKey, "NSTypes")
+CONST_STRING_DECL(_kCFBundleOldShortVersionStringKey, "NSAppVersion")
+
+// Compatibility CFBundleDocumentTypes key names
+CONST_STRING_DECL(_kCFBundleOldTypeNameKey, "NSName")
+CONST_STRING_DECL(_kCFBundleOldTypeRoleKey, "NSRole")
+CONST_STRING_DECL(_kCFBundleOldTypeIconFileKey, "NSIcon")
+CONST_STRING_DECL(_kCFBundleOldTypeExtensions1Key, "NSUnixExtensions")
+CONST_STRING_DECL(_kCFBundleOldTypeExtensions2Key, "NSDOSExtensions")
+CONST_STRING_DECL(_kCFBundleOldTypeOSTypesKey, "NSMacOSType")
+
+// Internally used keys for loaded Info plists.
+CONST_STRING_DECL(_kCFBundleInfoPlistURLKey, "CFBundleInfoPlistURL")
+CONST_STRING_DECL(_kCFBundleRawInfoPlistURLKey, "CFBundleRawInfoPlistURL")
+CONST_STRING_DECL(_kCFBundleNumericVersionKey, "CFBundleNumericVersion")
+CONST_STRING_DECL(_kCFBundleExecutablePathKey, "CFBundleExecutablePath")
+CONST_STRING_DECL(_kCFBundleResourcesFileMappedKey, "CSResourcesFileMapped")
+CONST_STRING_DECL(_kCFBundleCFMLoadAsBundleKey, "CFBundleCFMLoadAsBundle")
+CONST_STRING_DECL(_kCFBundleAllowMixedLocalizationsKey, "CFBundleAllowMixedLocalizations")
+
+// Keys used by NSBundle for loaded Info plists.
+CONST_STRING_DECL(_kCFBundleInitialPathKey, "NSBundleInitialPath")
+CONST_STRING_DECL(_kCFBundleResolvedPathKey, "NSBundleResolvedPath")
+CONST_STRING_DECL(_kCFBundlePrincipalClassKey, "NSPrincipalClass")
+
+static CFTypeID __kCFBundleTypeID = _kCFRuntimeNotATypeID;
+
+struct __CFBundle {
+    CFRuntimeBase _base;
+
+    CFURLRef _url;
+    CFDateRef _modDate;
+
+    CFDictionaryRef _infoDict;
+    CFDictionaryRef _localInfoDict;
+    CFArrayRef _searchLanguages;
+
+    __CFPBinaryType _binaryType;
+    Boolean _isLoaded;
+    uint8_t _version;
+    Boolean _sharesStringsFiles;
+    char _padding[1];
+
+    /* CFM goop */
+    void *_connectionCookie;
+
+    /* DYLD goop */
+    const void *_imageCookie;
+    const void *_moduleCookie;
+
+    /* dlfcn goop */
+    void *_handleCookie;
+    
+    /* CFM<->DYLD glue */
+    CFMutableDictionaryRef _glueDict;
+    
+    /* Resource fork goop */
+    _CFResourceData _resourceData;
+
+    _CFPlugInData _plugInData;
+
+#if defined(BINARY_SUPPORT_DLL)
+    HMODULE _hModule;
+#endif /* BINARY_SUPPORT_DLL */
+
+};
+
+static CFSpinLock_t CFBundleGlobalDataLock = CFSpinLockInit;
+
+static CFMutableDictionaryRef _bundlesByURL = NULL;
+static CFMutableDictionaryRef _bundlesByIdentifier = NULL;
+
+// For scheduled lazy unloading.  Used by CFPlugIn.
+static CFMutableSetRef _bundlesToUnload = NULL;
+static Boolean _scheduledBundlesAreUnloading = false;
+
+// Various lists of all bundles.
+static CFMutableArrayRef _allBundles = NULL;
+
+static Boolean _initedMainBundle = false;
+static CFBundleRef _mainBundle = NULL;
+static CFStringRef _defaultLocalization = NULL;
+
+static Boolean _useDlfcn = false;
+
+// Forward declares functions.
+static CFBundleRef _CFBundleCreate(CFAllocatorRef allocator, CFURLRef bundleURL, Boolean alreadyLocked, Boolean doFinalProcessing);
+static CFStringRef _CFBundleCopyExecutableName(CFAllocatorRef alloc, CFBundleRef bundle, CFURLRef url, CFDictionaryRef infoDict);
+static CFURLRef _CFBundleCopyExecutableURLIgnoringCache(CFBundleRef bundle);
+static void _CFBundleEnsureBundlesUpToDateWithHintAlreadyLocked(CFStringRef hint);
+static void _CFBundleEnsureAllBundlesUpToDateAlreadyLocked(void);
+static void _CFBundleCheckWorkarounds(CFBundleRef bundle);
+static void _CFBundleEnsureBundleExistsForImagePath(CFStringRef imagePath);
+static void _CFBundleEnsureBundlesExistForImagePaths(CFArrayRef imagePaths);
+#if defined(BINARY_SUPPORT_DYLD)
+static CFDictionaryRef _CFBundleGrokInfoDictFromMainExecutable(void);
+static Boolean _CFBundleGrokObjCImageInfoFromMainExecutable(uint32_t *objcVersion, uint32_t *objcFlags);
+static CFStringRef _CFBundleDYLDCopyLoadedImagePathForPointer(void *p);
+static void *_CFBundleDYLDGetSymbolByNameWithSearch(CFBundleRef bundle, CFStringRef symbolName, Boolean globalSearch);
+#endif /* BINARY_SUPPORT_DYLD */
+#if defined(BINARY_SUPPORT_DLFCN)
+static CFStringRef _CFBundleDlfcnCopyLoadedImagePathForPointer(void *p);
+static void *_CFBundleDlfcnGetSymbolByNameWithSearch(CFBundleRef bundle, CFStringRef symbolName, Boolean globalSearch);
+#endif /* BINARY_SUPPORT_DLFCN */
+#if defined(BINARY_SUPPORT_DYLD) && defined(BINARY_SUPPORT_CFM)
+static void *_CFBundleFunctionPointerForTVector(CFAllocatorRef allocator, void *tvp);
+static void *_CFBundleTVectorForFunctionPointer(CFAllocatorRef allocator, void *fp);
+#endif /* BINARY_SUPPORT_DYLD && BINARY_SUPPORT_CFM */
+
+static void _CFBundleAddToTables(CFBundleRef bundle, Boolean alreadyLocked) {
+    CFStringRef bundleID = CFBundleGetIdentifier(bundle);
+
+    if (!alreadyLocked) __CFSpinLock(&CFBundleGlobalDataLock);
+    
+    // Add to the _allBundles list
+    if (!_allBundles) {
+        // Create this from the default allocator
+        CFArrayCallBacks nonRetainingArrayCallbacks = kCFTypeArrayCallBacks;
+        nonRetainingArrayCallbacks.retain = NULL;
+        nonRetainingArrayCallbacks.release = NULL;
+        _allBundles = CFArrayCreateMutable(kCFAllocatorSystemDefault, 0, &nonRetainingArrayCallbacks);
+    }
+    CFArrayAppendValue(_allBundles, bundle);
+    
+    // Add to the table that maps urls to bundles
+    if (!_bundlesByURL) {
+        // Create this from the default allocator
+        CFDictionaryValueCallBacks nonRetainingDictionaryValueCallbacks = kCFTypeDictionaryValueCallBacks;
+        nonRetainingDictionaryValueCallbacks.retain = NULL;
+        nonRetainingDictionaryValueCallbacks.release = NULL;
+        _bundlesByURL = CFDictionaryCreateMutable(kCFAllocatorSystemDefault, 0, &kCFTypeDictionaryKeyCallBacks, &nonRetainingDictionaryValueCallbacks);
+    }
+    CFDictionarySetValue(_bundlesByURL, bundle->_url, bundle);
+
+    // Add to the table that maps identifiers to bundles
+    if (bundleID) {
+        CFMutableArrayRef bundlesWithThisID = NULL;
+        CFBundleRef existingBundle = NULL;
+        if (!_bundlesByIdentifier) {
+            // Create this from the default allocator
+            _bundlesByIdentifier = CFDictionaryCreateMutable(kCFAllocatorSystemDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+        }
+        bundlesWithThisID = (CFMutableArrayRef)CFDictionaryGetValue(_bundlesByIdentifier, bundleID);
+        if (bundlesWithThisID) {
+            CFIndex i, count = CFArrayGetCount(bundlesWithThisID);
+            UInt32 existingVersion, newVersion = CFBundleGetVersionNumber(bundle);
+            for (i = 0; i < count; i++) {
+                existingBundle = (CFBundleRef)CFArrayGetValueAtIndex(bundlesWithThisID, i);
+                existingVersion = CFBundleGetVersionNumber(existingBundle);
+                // If you load two bundles with the same identifier and the same version, the last one wins.
+                if (newVersion >= existingVersion) break;
+            }
+            CFArrayInsertValueAtIndex(bundlesWithThisID, i, bundle);
+        } else {
+            // Create this from the default allocator
+            CFArrayCallBacks nonRetainingArrayCallbacks = kCFTypeArrayCallBacks;
+            nonRetainingArrayCallbacks.retain = NULL;
+            nonRetainingArrayCallbacks.release = NULL;
+            bundlesWithThisID = CFArrayCreateMutable(kCFAllocatorSystemDefault, 0, &nonRetainingArrayCallbacks);
+            CFArrayAppendValue(bundlesWithThisID, bundle);
+            CFDictionarySetValue(_bundlesByIdentifier, bundleID, bundlesWithThisID);
+            CFRelease(bundlesWithThisID);
+        }
+    }
+    if (!alreadyLocked) __CFSpinUnlock(&CFBundleGlobalDataLock);
+}
+
+static void _CFBundleRemoveFromTables(CFBundleRef bundle) {
+    CFStringRef bundleID = CFBundleGetIdentifier(bundle);
+
+    __CFSpinLock(&CFBundleGlobalDataLock);
+
+    // Remove from the various lists
+    if (_allBundles) {
+        CFIndex i = CFArrayGetFirstIndexOfValue(_allBundles, CFRangeMake(0, CFArrayGetCount(_allBundles)), bundle);
+        if (i >= 0) CFArrayRemoveValueAtIndex(_allBundles, i);
+    }
+
+    // Remove from the table that maps urls to bundles
+    if (_bundlesByURL) CFDictionaryRemoveValue(_bundlesByURL, bundle->_url);
+    
+    // Remove from the table that maps identifiers to bundles
+    if (bundleID && _bundlesByIdentifier) {
+        CFMutableArrayRef bundlesWithThisID = (CFMutableArrayRef)CFDictionaryGetValue(_bundlesByIdentifier, bundleID);
+        if (bundlesWithThisID) {
+            CFIndex count = CFArrayGetCount(bundlesWithThisID);
+            while (count-- > 0) if (bundle == (CFBundleRef)CFArrayGetValueAtIndex(bundlesWithThisID, count)) CFArrayRemoveValueAtIndex(bundlesWithThisID, count);
+            if (0 == CFArrayGetCount(bundlesWithThisID)) CFDictionaryRemoveValue(_bundlesByIdentifier, bundleID);
+        }
+    }
+    
+    __CFSpinUnlock(&CFBundleGlobalDataLock);
+}
+
+__private_extern__ CFBundleRef _CFBundleFindByURL(CFURLRef url, Boolean alreadyLocked) {
+    CFBundleRef result = NULL;
+    if (!alreadyLocked) __CFSpinLock(&CFBundleGlobalDataLock);
+    if (_bundlesByURL) result = (CFBundleRef)CFDictionaryGetValue(_bundlesByURL, url);
+    if (!alreadyLocked) __CFSpinUnlock(&CFBundleGlobalDataLock);
+    return result;
+}
+
+static CFURLRef _CFBundleCopyBundleURLForExecutablePath(CFStringRef str) {
+    //!!! need to handle frameworks, NT; need to integrate with NSBundle - drd
+    UniChar buff[CFMaxPathSize];
+    CFIndex buffLen;
+    CFURLRef url = NULL;
+    CFStringRef outstr;
+    
+    buffLen = CFStringGetLength(str);
+    if (buffLen > CFMaxPathSize) buffLen = CFMaxPathSize;
+    CFStringGetCharacters(str, CFRangeMake(0, buffLen), buff);
+
+    if (!url) {
+        buffLen = _CFLengthAfterDeletingLastPathComponent(buff, buffLen);  // Remove exe name
+
+        if (buffLen > 0) {
+            // See if this is a new bundle.  If it is, we have to remove more path components.
+            CFIndex startOfLastDir = _CFStartOfLastPathComponent(buff, buffLen);
+            if ((startOfLastDir > 0) && (startOfLastDir < buffLen)) {
+                CFStringRef lastDirName = CFStringCreateWithCharacters(kCFAllocatorSystemDefault, &(buff[startOfLastDir]), buffLen - startOfLastDir);
+
+                if (CFEqual(lastDirName, _CFBundleGetPlatformExecutablesSubdirectoryName()) || CFEqual(lastDirName, _CFBundleGetAlternatePlatformExecutablesSubdirectoryName()) || CFEqual(lastDirName, _CFBundleGetOtherPlatformExecutablesSubdirectoryName()) || CFEqual(lastDirName, _CFBundleGetOtherAlternatePlatformExecutablesSubdirectoryName())) {
+                    // This is a new bundle.  Back off a few more levels
+                    if (buffLen > 0) {
+                        // Remove platform folder
+                        buffLen = _CFLengthAfterDeletingLastPathComponent(buff, buffLen);
+                    }
+                    if (buffLen > 0) {
+                        // Remove executables folder (if present)
+                        CFIndex startOfNextDir = _CFStartOfLastPathComponent(buff, buffLen);
+                        if ((startOfNextDir > 0) && (startOfNextDir < buffLen)) {
+                            CFStringRef nextDirName = CFStringCreateWithCharacters(kCFAllocatorSystemDefault, &(buff[startOfNextDir]), buffLen - startOfNextDir);
+                            if (CFEqual(nextDirName, _CFBundleExecutablesDirectoryName)) buffLen = _CFLengthAfterDeletingLastPathComponent(buff, buffLen);
+                            CFRelease(nextDirName);
+                        }
+                    }
+                    if (buffLen > 0) {
+                        // Remove support files folder
+                        buffLen = _CFLengthAfterDeletingLastPathComponent(buff, buffLen);
+                    }
+                }
+                CFRelease(lastDirName);
+            }
+        }
+
+        if (buffLen > 0) {
+            outstr = CFStringCreateWithCharactersNoCopy(kCFAllocatorSystemDefault, buff, buffLen, kCFAllocatorNull);
+            url = CFURLCreateWithFileSystemPath(kCFAllocatorSystemDefault, outstr, PLATFORM_PATH_STYLE, true);
+            CFRelease(outstr);
+        }
+    }
+    return url;
+}
+
+static CFURLRef _CFBundleCopyResolvedURLForExecutableURL(CFURLRef url) {
+    // this is necessary so that we match any sanitization CFURL may perform on the result of _CFBundleCopyBundleURLForExecutableURL()
+    CFURLRef absoluteURL, url1, url2, outURL = NULL;
+    CFStringRef str, str1, str2;
+    absoluteURL = CFURLCopyAbsoluteURL(url);
+    str = CFURLCopyFileSystemPath(absoluteURL, PLATFORM_PATH_STYLE);
+    if (str) {
+        UniChar buff[CFMaxPathSize];
+        CFIndex buffLen = CFStringGetLength(str), len1;
+        if (buffLen > CFMaxPathSize) buffLen = CFMaxPathSize;
+        CFStringGetCharacters(str, CFRangeMake(0, buffLen), buff);
+        len1 = _CFLengthAfterDeletingLastPathComponent(buff, buffLen);
+        if (len1 > 0 && len1 + 1 < buffLen) {
+            str1 = CFStringCreateWithCharacters(kCFAllocatorSystemDefault, buff, len1);
+            str2 = CFStringCreateWithCharacters(kCFAllocatorSystemDefault, buff + len1 + 1, buffLen - len1 - 1);
+            if (str1 && str2) {
+                url1 = CFURLCreateWithFileSystemPath(kCFAllocatorSystemDefault, str1, PLATFORM_PATH_STYLE, true);
+                if (url1) {
+                    url2 = CFURLCreateWithFileSystemPathRelativeToBase(kCFAllocatorSystemDefault, str2, PLATFORM_PATH_STYLE, false, url1);
+                    if (url2) {
+                        outURL = CFURLCopyAbsoluteURL(url2);
+                        CFRelease(url2);
+                    }
+                    CFRelease(url1);
+                }
+            }
+            if (str1) CFRelease(str1);
+            if (str2) CFRelease(str2);
+        }
+        CFRelease(str);
+    }
+    if (!outURL) {
+        outURL = absoluteURL;
+    } else {
+        CFRelease(absoluteURL);
+    }
+    return outURL;
+}
+
+CFURLRef _CFBundleCopyBundleURLForExecutableURL(CFURLRef url) {
+    CFURLRef resolvedURL, outurl = NULL;
+    CFStringRef str;
+    resolvedURL = _CFBundleCopyResolvedURLForExecutableURL(url);
+    str = CFURLCopyFileSystemPath(resolvedURL, PLATFORM_PATH_STYLE);
+    if (str) {
+        outurl = _CFBundleCopyBundleURLForExecutablePath(str);
+        CFRelease(str);
+    }
+    CFRelease(resolvedURL);
+    return outurl;
+}
+
+CFBundleRef _CFBundleCreateIfLooksLikeBundle(CFAllocatorRef allocator, CFURLRef url) {
+    CFBundleRef bundle = CFBundleCreate(allocator, url);
+    
+    // exclude type 0 bundles with no binary (or CFM binary) and no Info.plist, since they give too many false positives
+    if (bundle && 0 == bundle->_version) {
+        CFDictionaryRef infoDict = CFBundleGetInfoDictionary(bundle);
+        if (!infoDict || 0 == CFDictionaryGetCount(infoDict)) {
+#if defined(BINARY_SUPPORT_CFM) && defined(BINARY_SUPPORT_DYLD)
+            CFURLRef executableURL = CFBundleCopyExecutableURL(bundle);
+            if (executableURL) {
+                if (bundle->_binaryType == __CFBundleUnknownBinary) bundle->_binaryType = _CFBundleGrokBinaryType(executableURL);
+                if (bundle->_binaryType == __CFBundleCFMBinary || bundle->_binaryType == __CFBundleUnreadableBinary) {
+                    bundle->_version = 4;
+                } else {
+                    bundle->_resourceData._executableLacksResourceFork = true;
+                }
+                CFRelease(executableURL);
+            } else {
+                bundle->_version = 4;
+            }
+#elif defined(BINARY_SUPPORT_CFM)
+            bundle->_version = 4;
+#else 
+            CFURLRef executableURL = CFBundleCopyExecutableURL(bundle);
+            if (executableURL) {
+                CFRelease(executableURL);
+            } else {
+                bundle->_version = 4;
+            }
+#endif /* BINARY_SUPPORT_CFM && BINARY_SUPPORT_DYLD */
+        }
+    }
+    if (bundle && (3 == bundle->_version || 4 == bundle->_version)) {
+        CFRelease(bundle);
+        bundle = NULL;
+    }
+    return bundle;
+}
+
+CFBundleRef _CFBundleGetMainBundleIfLooksLikeBundle(void) {
+    CFBundleRef mainBundle = CFBundleGetMainBundle();
+    if (mainBundle && (3 == mainBundle->_version || 4 == mainBundle->_version)) mainBundle = NULL;
+    return mainBundle;
+}
+
+Boolean _CFBundleMainBundleInfoDictionaryComesFromResourceFork(void) {
+    CFBundleRef mainBundle = CFBundleGetMainBundle();
+    return (mainBundle && mainBundle->_resourceData._infoDictionaryFromResourceFork);
+}
+
+CFBundleRef _CFBundleCreateWithExecutableURLIfLooksLikeBundle(CFAllocatorRef allocator, CFURLRef url) {
+    CFBundleRef bundle = NULL;
+    CFURLRef bundleURL = _CFBundleCopyBundleURLForExecutableURL(url), resolvedURL = _CFBundleCopyResolvedURLForExecutableURL(url);
+    if (bundleURL && resolvedURL) {
+        bundle = _CFBundleCreateIfLooksLikeBundle(allocator, bundleURL);
+        if (bundle) {
+            CFURLRef executableURL = _CFBundleCopyExecutableURLIgnoringCache(bundle);
+            char buff1[CFMaxPathSize], buff2[CFMaxPathSize];
+            if (!executableURL || !CFURLGetFileSystemRepresentation(resolvedURL, true, (uint8_t *)buff1, CFMaxPathSize) || !CFURLGetFileSystemRepresentation(executableURL, true, (uint8_t *)buff2, CFMaxPathSize) || 0 != strcmp(buff1, buff2)) {
+                CFRelease(bundle);
+                bundle = NULL;
+            }
+            if (executableURL) CFRelease(executableURL);
+        }
+    }
+    if (bundleURL) CFRelease(bundleURL);
+    if (resolvedURL) CFRelease(resolvedURL);
+    return bundle;
+}
+
+CFURLRef _CFBundleCopyMainBundleExecutableURL(Boolean *looksLikeBundle) {
+    // This function is for internal use only; _mainBundle is deliberately accessed outside of the lock to get around a reentrancy issue
+    const char *processPath;
+    CFStringRef str = NULL;
+    CFURLRef executableURL = NULL;
+    processPath = _CFProcessPath();
+    if (processPath) {
+        str = CFStringCreateWithFileSystemRepresentation(kCFAllocatorSystemDefault, processPath);
+        if (str) {
+            executableURL = CFURLCreateWithFileSystemPath(kCFAllocatorSystemDefault, str, PLATFORM_PATH_STYLE, false);
+            CFRelease(str);
+        }
+    }
+    if (looksLikeBundle) {
+        CFBundleRef mainBundle = _mainBundle;
+        if (mainBundle && (3 == mainBundle->_version || 4 == mainBundle->_version)) mainBundle = NULL;
+        *looksLikeBundle = (mainBundle ? true : false);
+    }
+    return executableURL;
+}
+
+static void _CFBundleInitializeMainBundleInfoDictionaryAlreadyLocked(CFStringRef executablePath) {
+#if defined(BINARY_SUPPORT_CFM)
+    Boolean versRegionOverrides = false;
+#endif /* BINARY_SUPPORT_CFM */
+    CFBundleGetInfoDictionary(_mainBundle);
+    if (!_mainBundle->_infoDict || CFDictionaryGetCount(_mainBundle->_infoDict) == 0) {
+        // if type 3 bundle and no Info.plist, treat as unbundled, since this gives too many false positives
+        if (_mainBundle->_version == 3) _mainBundle->_version = 4;
+        if (_mainBundle->_version == 0) {
+            // if type 0 bundle and no Info.plist and not main executable for bundle, treat as unbundled, since this gives too many false positives
+            CFStringRef executableName = _CFBundleCopyExecutableName(kCFAllocatorSystemDefault, _mainBundle, NULL, NULL);
+            if (!executableName || !executablePath || !CFStringHasSuffix(executablePath, executableName)) _mainBundle->_version = 4;
+            if (executableName) CFRelease(executableName);
+        }
+#if defined(BINARY_SUPPORT_DYLD)
+        if (_mainBundle->_binaryType == __CFBundleDYLDExecutableBinary) {
+            if (_mainBundle->_infoDict) CFRelease(_mainBundle->_infoDict);
+            _mainBundle->_infoDict = _CFBundleGrokInfoDictFromMainExecutable();
+        }
+#endif /* BINARY_SUPPORT_DYLD */
+#if defined(BINARY_SUPPORT_CFM)
+        if (_mainBundle->_binaryType == __CFBundleCFMBinary || _mainBundle->_binaryType == __CFBundleUnreadableBinary) {
+            // if type 0 bundle and CFM binary and no Info.plist, treat as unbundled, since this also gives too many false positives
+            if (_mainBundle->_version == 0) _mainBundle->_version = 4;
+            if (_mainBundle->_version != 4) {
+                // if CFM binary and no Info.plist and not main executable for bundle, treat as unbundled, since this also gives too many false positives
+                // except for Macromedia Director MX, which is unbundled but wants to be treated as bundled
+                CFStringRef executableName = _CFBundleCopyExecutableName(kCFAllocatorSystemDefault, _mainBundle, NULL, NULL);
+                Boolean treatAsBundled = false;
+                if (executablePath) {
+                    CFIndex strLength = CFStringGetLength(executablePath);
+                    if (strLength > 10) treatAsBundled = CFStringFindWithOptions(executablePath, CFSTR(" MX"), CFRangeMake(strLength - 10, 10), 0, NULL);
+                }
+                if (!treatAsBundled && (!executableName || !executablePath || !CFStringHasSuffix(executablePath, executableName))) _mainBundle->_version = 4;
+                if (executableName) CFRelease(executableName);
+            }
+            if (_mainBundle->_infoDict) CFRelease(_mainBundle->_infoDict);
+            if (executablePath) {
+                CFURLRef executableURL = CFURLCreateWithFileSystemPath(kCFAllocatorSystemDefault, executablePath, PLATFORM_PATH_STYLE, false);
+                if (executableURL) {
+                    _mainBundle->_infoDict = _CFBundleCopyInfoDictionaryInResourceForkWithAllocator(CFGetAllocator(_mainBundle), executableURL);
+                    if (_mainBundle->_infoDict) _mainBundle->_resourceData._infoDictionaryFromResourceFork = true;
+                    CFRelease(executableURL);
+                }
+            }
+            if (_mainBundle->_binaryType == __CFBundleUnreadableBinary && _mainBundle->_infoDict && CFDictionaryGetValue(_mainBundle->_infoDict, kCFBundleDevelopmentRegionKey)) versRegionOverrides = true;
+        }
+#endif /* BINARY_SUPPORT_CFM */
+    }
+    if (!_mainBundle->_infoDict) _mainBundle->_infoDict = CFDictionaryCreateMutable(CFGetAllocator(_mainBundle), 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+    if (!CFDictionaryGetValue(_mainBundle->_infoDict, _kCFBundleExecutablePathKey)) CFDictionarySetValue((CFMutableDictionaryRef)(_mainBundle->_infoDict), _kCFBundleExecutablePathKey, executablePath);
+#if defined(BINARY_SUPPORT_CFM)
+    if (versRegionOverrides) {
+        // This is a hack to preserve backward compatibility for certain broken applications (2761067)
+        CFStringRef devLang = _CFBundleCopyBundleDevelopmentRegionFromVersResource(_mainBundle);
+        if (devLang) {
+            CFDictionarySetValue((CFMutableDictionaryRef)(_mainBundle->_infoDict), kCFBundleDevelopmentRegionKey, devLang);
+            CFRelease(devLang);
+        }
+    }
+#endif /* BINARY_SUPPORT_CFM */
+}
+
+CF_EXPORT void _CFBundleFlushBundleCaches(CFBundleRef bundle) {
+    CFDictionaryRef oldInfoDict = bundle->_infoDict;
+    CFTypeRef val;
+    
+    _CFBundleFlushCachesForURL(bundle->_url);
+    bundle->_infoDict = NULL;
+    if (bundle->_localInfoDict) {
+        CFRelease(bundle->_localInfoDict);
+        bundle->_localInfoDict = NULL;
+    }
+    if (bundle->_searchLanguages) {
+        CFRelease(bundle->_searchLanguages);
+        bundle->_searchLanguages = NULL;
+    }
+    if (bundle->_resourceData._stringTableCache) {
+        CFRelease(bundle->_resourceData._stringTableCache);
+        bundle->_resourceData._stringTableCache = NULL;
+    }
+    if (bundle == _mainBundle) {
+        CFStringRef executablePath = oldInfoDict ? (CFStringRef)CFDictionaryGetValue(oldInfoDict, _kCFBundleExecutablePathKey) : NULL;
+        __CFSpinLock(&CFBundleGlobalDataLock);
+        _CFBundleInitializeMainBundleInfoDictionaryAlreadyLocked(executablePath);
+        __CFSpinUnlock(&CFBundleGlobalDataLock);
+    } else {
+        CFBundleGetInfoDictionary(bundle);
+    }
+    if (oldInfoDict) {
+        if (!bundle->_infoDict) bundle->_infoDict = CFDictionaryCreateMutable(CFGetAllocator(bundle), 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+        val = CFDictionaryGetValue(oldInfoDict, _kCFBundleInitialPathKey);
+        if (val) CFDictionarySetValue((CFMutableDictionaryRef)bundle->_infoDict, _kCFBundleInitialPathKey, val);
+        val = CFDictionaryGetValue(oldInfoDict, _kCFBundleResolvedPathKey);
+        if (val) CFDictionarySetValue((CFMutableDictionaryRef)bundle->_infoDict, _kCFBundleResolvedPathKey, val);
+        val = CFDictionaryGetValue(oldInfoDict, _kCFBundlePrincipalClassKey);
+        if (val) CFDictionarySetValue((CFMutableDictionaryRef)bundle->_infoDict, _kCFBundlePrincipalClassKey, val);
+        CFRelease(oldInfoDict);
+    }
+}
+
+static CFBundleRef _CFBundleGetMainBundleAlreadyLocked(void) {
+    if (!_initedMainBundle) {
+        const char *processPath;
+        CFStringRef str = NULL;
+        CFURLRef executableURL = NULL, bundleURL = NULL;
+        _initedMainBundle = true;
+        processPath = _CFProcessPath();
+        if (processPath) {
+            str = CFStringCreateWithFileSystemRepresentation(kCFAllocatorSystemDefault, processPath);
+            if (!executableURL) executableURL = CFURLCreateWithFileSystemPath(kCFAllocatorSystemDefault, str, PLATFORM_PATH_STYLE, false);
+        }
+        if (executableURL) bundleURL = _CFBundleCopyBundleURLForExecutableURL(executableURL);
+        if (bundleURL) {
+            // make sure that main bundle has executable path
+            //??? what if we are not the main executable in the bundle?
+            // NB doFinalProcessing must be false here, see below
+            _mainBundle = _CFBundleCreate(kCFAllocatorSystemDefault, bundleURL, true, false);
+            if (_mainBundle) {
+                // make sure that the main bundle is listed as loaded, and mark it as executable
+                _mainBundle->_isLoaded = true;
+#if defined(BINARY_SUPPORT_DYLD)
+                if (_mainBundle->_binaryType == __CFBundleUnknownBinary) {
+                    if (!executableURL) {
+                        _mainBundle->_binaryType = __CFBundleNoBinary;
+                    } else {
+                        _mainBundle->_binaryType = _CFBundleGrokBinaryType(executableURL);
+#if defined(BINARY_SUPPORT_CFM)
+                        if (_mainBundle->_binaryType != __CFBundleCFMBinary && _mainBundle->_binaryType != __CFBundleUnreadableBinary) _mainBundle->_resourceData._executableLacksResourceFork = true;
+#endif /* BINARY_SUPPORT_CFM */
+                    }
+                }                
+#endif /* BINARY_SUPPORT_DYLD */
+#if defined(BINARY_SUPPORT_DYLD)
+                // get cookie for already-loaded main bundle
+                if (_mainBundle->_binaryType == __CFBundleDYLDExecutableBinary && !_mainBundle->_imageCookie) {
+                    // ??? need better way to specify main executable image
+                    _mainBundle->_imageCookie = (void *)_dyld_get_image_header(0);
+#if LOG_BUNDLE_LOAD
+                    printf("main bundle %p getting image %p\n", _mainBundle, _mainBundle->_imageCookie);
+#endif /* LOG_BUNDLE_LOAD */
+                }
+#endif /* BINARY_SUPPORT_DYLD */
+                _CFBundleInitializeMainBundleInfoDictionaryAlreadyLocked(str);
+                // Perform delayed final processing steps.
+                // This must be done after _isLoaded has been set, for security reasons (3624341).
+                _CFBundleCheckWorkarounds(_mainBundle);
+                if (_CFBundleNeedsInitPlugIn(_mainBundle)) {
+                    __CFSpinUnlock(&CFBundleGlobalDataLock);
+                    _CFBundleInitPlugIn(_mainBundle);
+                    __CFSpinLock(&CFBundleGlobalDataLock);
+                }
+            }
+        }
+        if (bundleURL) CFRelease(bundleURL);
+        if (str) CFRelease(str);
+        if (executableURL) CFRelease(executableURL);
+    }
+    return _mainBundle;
+}
+
+CFBundleRef CFBundleGetMainBundle(void) {
+    CFBundleRef mainBundle;
+    __CFSpinLock(&CFBundleGlobalDataLock);
+    mainBundle = _CFBundleGetMainBundleAlreadyLocked();
+    __CFSpinUnlock(&CFBundleGlobalDataLock);
+    return mainBundle;
+}
+
+CFBundleRef CFBundleGetBundleWithIdentifier(CFStringRef bundleID) {
+    CFBundleRef result = NULL;
+    CFArrayRef bundlesWithThisID;
+    if (bundleID) {
+        __CFSpinLock(&CFBundleGlobalDataLock);
+        (void)_CFBundleGetMainBundleAlreadyLocked();
+        if (_bundlesByIdentifier) {
+            bundlesWithThisID = (CFArrayRef)CFDictionaryGetValue(_bundlesByIdentifier, bundleID);
+            if (bundlesWithThisID && CFArrayGetCount(bundlesWithThisID) > 0) result = (CFBundleRef)CFArrayGetValueAtIndex(bundlesWithThisID, 0);
+        }
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_LINUX
+        if (!result) {
+            // Try to create the bundle for the caller and try again
+            void *p = __builtin_return_address(0);
+            if (p) {
+                CFStringRef imagePath = NULL;
+#if defined(BINARY_SUPPORT_DLFCN)
+                if (!imagePath && _useDlfcn) imagePath = _CFBundleDlfcnCopyLoadedImagePathForPointer(p);
+#endif /* BINARY_SUPPORT_DLFCN */
+#if defined(BINARY_SUPPORT_DYLD)
+                if (!imagePath) imagePath = _CFBundleDYLDCopyLoadedImagePathForPointer(p);
+#endif /* BINARY_SUPPORT_DYLD */
+                if (imagePath) {
+                    _CFBundleEnsureBundleExistsForImagePath(imagePath);
+                    CFRelease(imagePath);
+                }
+                if (_bundlesByIdentifier) {
+                    bundlesWithThisID = (CFArrayRef)CFDictionaryGetValue(_bundlesByIdentifier, bundleID);
+                    if (bundlesWithThisID && CFArrayGetCount(bundlesWithThisID) > 0) result = (CFBundleRef)CFArrayGetValueAtIndex(bundlesWithThisID, 0);
+                }
+            }
+        }
+#endif
+        if (!result) {
+            // Try to guess the bundle from the identifier and try again
+            _CFBundleEnsureBundlesUpToDateWithHintAlreadyLocked(bundleID);
+            if (_bundlesByIdentifier) {
+                bundlesWithThisID = (CFArrayRef)CFDictionaryGetValue(_bundlesByIdentifier, bundleID);
+                if (bundlesWithThisID && CFArrayGetCount(bundlesWithThisID) > 0) result = (CFBundleRef)CFArrayGetValueAtIndex(bundlesWithThisID, 0);
+            }
+        }
+        if (!result) {
+            // Make sure all bundles have been created and try again.
+            _CFBundleEnsureAllBundlesUpToDateAlreadyLocked();
+            if (_bundlesByIdentifier) {
+                bundlesWithThisID = (CFArrayRef)CFDictionaryGetValue(_bundlesByIdentifier, bundleID);
+                if (bundlesWithThisID && CFArrayGetCount(bundlesWithThisID) > 0) result = (CFBundleRef)CFArrayGetValueAtIndex(bundlesWithThisID, 0);
+            }
+        }
+        __CFSpinUnlock(&CFBundleGlobalDataLock);
+    }
+    return result;
+}
+
+static CFStringRef __CFBundleCopyDescription(CFTypeRef cf) {
+    char buff[CFMaxPathSize];
+    CFStringRef path = NULL, binaryType = NULL, retval = NULL;
+    if (((CFBundleRef)cf)->_url && CFURLGetFileSystemRepresentation(((CFBundleRef)cf)->_url, true, (uint8_t *)buff, CFMaxPathSize)) path = CFStringCreateWithFileSystemRepresentation(kCFAllocatorSystemDefault, buff);
+    switch (((CFBundleRef)cf)->_binaryType) {
+        case __CFBundleCFMBinary:
+            binaryType = CFSTR("");
+            break;
+        case __CFBundleDYLDExecutableBinary:
+            binaryType = CFSTR("executable, ");
+            break;
+        case __CFBundleDYLDBundleBinary:
+            binaryType = CFSTR("bundle, ");
+            break;
+        case __CFBundleDYLDFrameworkBinary:
+            binaryType = CFSTR("framework, ");
+            break;
+        case __CFBundleDLLBinary:
+            binaryType = CFSTR("DLL, ");
+            break;
+        case __CFBundleUnreadableBinary:
+            binaryType = CFSTR("");
+            break;
+        default:
+            binaryType = CFSTR("");
+            break;
+    }
+    if (((CFBundleRef)cf)->_plugInData._isPlugIn) {
+        retval = CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("CFBundle/CFPlugIn %p <%@> (%@%sloaded)"), cf, path, binaryType, ((CFBundleRef)cf)->_isLoaded ? "" : "not ");
+    } else {
+        retval = CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("CFBundle %p <%@> (%@%sloaded)"), cf, path, binaryType, ((CFBundleRef)cf)->_isLoaded ? "" : "not ");
+    }
+    if (path) CFRelease(path);
+    return retval;
+}
+
+static void _CFBundleDeallocateGlue(const void *key, const void *value, void *context) {
+    CFAllocatorRef allocator = (CFAllocatorRef)context;
+    if (value) CFAllocatorDeallocate(allocator, (void *)value);
+}
+
+static void __CFBundleDeallocate(CFTypeRef cf) {
+    CFBundleRef bundle = (CFBundleRef)cf;
+    CFAllocatorRef allocator;
+    
+    __CFGenericValidateType(cf, __kCFBundleTypeID);
+
+    allocator = CFGetAllocator(bundle);
+
+    /* Unload it */
+    CFBundleUnloadExecutable(bundle);
+
+    // Clean up plugIn stuff
+    _CFBundleDeallocatePlugIn(bundle);
+    
+    _CFBundleRemoveFromTables(bundle);
+
+    if (bundle->_url) {
+        _CFBundleFlushCachesForURL(bundle->_url);
+        CFRelease(bundle->_url);
+    }
+    if (bundle->_infoDict) CFRelease(bundle->_infoDict);
+    if (bundle->_modDate) CFRelease(bundle->_modDate);
+    if (bundle->_localInfoDict) CFRelease(bundle->_localInfoDict);
+    if (bundle->_searchLanguages) CFRelease(bundle->_searchLanguages);
+    if (bundle->_glueDict) {
+        CFDictionaryApplyFunction(bundle->_glueDict, _CFBundleDeallocateGlue, (void *)allocator);
+        CFRelease(bundle->_glueDict);
+    }
+    if (bundle->_resourceData._stringTableCache) CFRelease(bundle->_resourceData._stringTableCache);
+}
+
+static const CFRuntimeClass __CFBundleClass = {
+    0,
+    "CFBundle",
+    NULL,      // init
+    NULL,      // copy
+    __CFBundleDeallocate,
+    NULL,      // equal
+    NULL,      // hash
+    NULL,      // 
+    __CFBundleCopyDescription
+};
+
+__private_extern__ void __CFBundleInitialize(void) {
+    __kCFBundleTypeID = _CFRuntimeRegisterClass(&__CFBundleClass);
+#if defined(BINARY_SUPPORT_DLFCN)
+    _useDlfcn = true;
+#if defined(BINARY_SUPPORT_DYLD)
+    if (getenv("CFBundleUseDYLD")) _useDlfcn = false;
+#endif /* BINARY_SUPPORT_DYLD */
+#endif /* BINARY_SUPPORT_DLFCN */
+}
+
+Boolean _CFBundleUseDlfcn(void) {
+    return _useDlfcn;
+}
+
+CFTypeID CFBundleGetTypeID(void) {
+    return __kCFBundleTypeID;
+}
+
+CFBundleRef _CFBundleGetExistingBundleWithBundleURL(CFURLRef bundleURL) {
+    CFBundleRef bundle = NULL;
+    char buff[CFMaxPathSize];
+    CFURLRef newURL = NULL;
+    
+    if (!CFURLGetFileSystemRepresentation(bundleURL, true, (uint8_t *)buff, CFMaxPathSize)) return NULL;
+    
+    newURL = CFURLCreateFromFileSystemRepresentation(kCFAllocatorSystemDefault, (uint8_t *)buff, (CFIndex)strlen(buff), true);
+    if (!newURL) newURL = (CFURLRef)CFRetain(bundleURL);
+    bundle = _CFBundleFindByURL(newURL, false);
+    CFRelease(newURL);
+    return bundle;
+}
+
+static CFBundleRef _CFBundleCreate(CFAllocatorRef allocator, CFURLRef bundleURL, Boolean alreadyLocked, Boolean doFinalProcessing) {
+    CFBundleRef bundle = NULL;
+    char buff[CFMaxPathSize];
+    CFDateRef modDate = NULL;
+    Boolean exists = false;
+    SInt32 mode = 0;
+    CFURLRef newURL = NULL;
+    uint8_t localVersion = 0;
+    
+    if (!CFURLGetFileSystemRepresentation(bundleURL, true, (uint8_t *)buff, CFMaxPathSize)) return NULL;
+
+    newURL = CFURLCreateFromFileSystemRepresentation(allocator, (uint8_t *)buff, (CFIndex)strlen(buff), true);
+    if (!newURL) newURL = (CFURLRef)CFRetain(bundleURL);
+    bundle = _CFBundleFindByURL(newURL, alreadyLocked);
+    if (bundle) {
+        CFRetain(bundle);
+        CFRelease(newURL);
+        return bundle;
+    }
+    
+    if (!_CFBundleURLLooksLikeBundleVersion(newURL, &localVersion)) {
+        localVersion = 3;
+        if (_CFGetFileProperties(allocator, newURL, &exists, &mode, NULL, &modDate, NULL, NULL) == 0) {
+            if (!exists || ((mode & S_IFMT) != S_IFDIR)) {
+                if (modDate) CFRelease(modDate);
+                CFRelease(newURL);
+                return NULL;
+            }
+        } else {
+            CFRelease(newURL);
+            return NULL;
+        }
+    }
+
+    bundle = (CFBundleRef)_CFRuntimeCreateInstance(allocator, __kCFBundleTypeID, sizeof(struct __CFBundle) - sizeof(CFRuntimeBase), NULL);
+    if (!bundle) {
+        CFRelease(newURL);
+        return NULL;
+    }
+
+    bundle->_url = newURL;
+
+    bundle->_modDate = modDate;
+    bundle->_version = localVersion;
+    bundle->_infoDict = NULL;
+    bundle->_localInfoDict = NULL;
+    bundle->_searchLanguages = NULL;
+    
+#if defined(BINARY_SUPPORT_DYLD)
+    /* We'll have to figure it out later */
+    bundle->_binaryType = __CFBundleUnknownBinary;
+#elif defined(BINARY_SUPPORT_CFM)
+    /* We support CFM only */
+    bundle->_binaryType = __CFBundleCFMBinary;
+#elif defined(BINARY_SUPPORT_DLL)
+    /* We support DLL only */
+    bundle->_binaryType = __CFBundleDLLBinary;
+    bundle->_hModule = NULL;
+#else
+    /* We'll have to figure it out later */
+    bundle->_binaryType = __CFBundleUnknownBinary;
+#endif /* BINARY_SUPPORT_DYLD */
+
+    bundle->_isLoaded = false;
+    bundle->_sharesStringsFiles = false;
+    
+    if (!getenv("CFBundleDisableStringsSharing") && 
+#if DEPLOYMENT_TARGET_MACOSX
+        (strncmp(buff, "/System/Library/Frameworks", 26) == 0) && 
+#endif
+        (strncmp(buff + strlen(buff) - 10, ".framework", 10) == 0)) bundle->_sharesStringsFiles = true;
+
+    bundle->_connectionCookie = NULL;
+    bundle->_handleCookie = NULL;
+    bundle->_imageCookie = NULL;
+    bundle->_moduleCookie = NULL;
+
+    bundle->_glueDict = NULL;
+    
+#if defined(BINARY_SUPPORT_CFM)
+    bundle->_resourceData._executableLacksResourceFork = false;
+#else /* BINARY_SUPPORT_CFM */
+    bundle->_resourceData._executableLacksResourceFork = true;
+#endif /* BINARY_SUPPORT_CFM */
+    bundle->_resourceData._infoDictionaryFromResourceFork = false;
+    bundle->_resourceData._stringTableCache = NULL;
+
+    bundle->_plugInData._isPlugIn = false;
+    bundle->_plugInData._loadOnDemand = false;
+    bundle->_plugInData._isDoingDynamicRegistration = false;
+    bundle->_plugInData._instanceCount = 0;
+    bundle->_plugInData._factories = NULL;
+
+    CFBundleGetInfoDictionary(bundle);
+    
+    _CFBundleAddToTables(bundle, alreadyLocked);
+
+    if (doFinalProcessing) {
+        _CFBundleCheckWorkarounds(bundle);
+        if (_CFBundleNeedsInitPlugIn(bundle)) {
+            if (alreadyLocked) __CFSpinUnlock(&CFBundleGlobalDataLock);
+            _CFBundleInitPlugIn(bundle);
+            if (alreadyLocked) __CFSpinLock(&CFBundleGlobalDataLock);
+        }
+    }
+    
+    return bundle;
+}
+
+CFBundleRef CFBundleCreate(CFAllocatorRef allocator, CFURLRef bundleURL) {return _CFBundleCreate(allocator, bundleURL, false, true);}
+
+CFArrayRef CFBundleCreateBundlesFromDirectory(CFAllocatorRef alloc, CFURLRef directoryURL, CFStringRef bundleType) {
+    CFMutableArrayRef bundles = CFArrayCreateMutable(alloc, 0, &kCFTypeArrayCallBacks);
+    CFArrayRef URLs = _CFContentsOfDirectory(alloc, NULL, NULL, directoryURL, bundleType);
+    if (URLs) {
+        CFIndex i, c = CFArrayGetCount(URLs);
+        CFURLRef curURL;
+        CFBundleRef curBundle;
+
+        for (i = 0; i < c; i++) {
+            curURL = (CFURLRef)CFArrayGetValueAtIndex(URLs, i);
+            curBundle = CFBundleCreate(alloc, curURL);
+            if (curBundle) CFArrayAppendValue(bundles, curBundle);
+        }
+        CFRelease(URLs);
+    }
+
+    return bundles;
+}
+
+CFURLRef CFBundleCopyBundleURL(CFBundleRef bundle) {
+    if (bundle->_url) {
+        CFRetain(bundle->_url);
+    }
+    return bundle->_url;
+}
+
+void _CFBundleSetDefaultLocalization(CFStringRef localizationName) {
+    CFStringRef newLocalization = localizationName ? (CFStringRef)CFStringCreateCopy(kCFAllocatorSystemDefault, localizationName) : NULL;
+    if (_defaultLocalization) CFRelease(_defaultLocalization);
+    _defaultLocalization = newLocalization;
+}
+
+CFArrayRef _CFBundleGetLanguageSearchList(CFBundleRef bundle) {
+    if (!bundle->_searchLanguages) {
+        CFMutableArrayRef langs = CFArrayCreateMutable(kCFAllocatorSystemDefault, 0, &kCFTypeArrayCallBacks);
+        CFStringRef devLang = CFBundleGetDevelopmentRegion(bundle);
+        
+        _CFBundleAddPreferredLprojNamesInDirectory(CFGetAllocator(bundle), bundle->_url, bundle->_version, bundle->_infoDict, langs, devLang);
+
+        if (CFArrayGetCount(langs) == 0) {
+            // If the user does not prefer any of our languages, and devLang is not present, try English
+            _CFBundleAddPreferredLprojNamesInDirectory(CFGetAllocator(bundle), bundle->_url, bundle->_version, bundle->_infoDict, langs, CFSTR("en_US"));
+        }
+        if (CFArrayGetCount(langs) == 0) {
+            // if none of the preferred localizations are present, fall back on a random localization that is present
+            CFArrayRef localizations = CFBundleCopyBundleLocalizations(bundle);
+            if (localizations) {
+                if (CFArrayGetCount(localizations) > 0) {
+                    _CFBundleAddPreferredLprojNamesInDirectory(CFGetAllocator(bundle), bundle->_url, bundle->_version, bundle->_infoDict, langs, (CFStringRef)CFArrayGetValueAtIndex(localizations, 0));
+                }
+                CFRelease(localizations);
+            }
+        }
+        
+        if (devLang && !CFArrayContainsValue(langs, CFRangeMake(0, CFArrayGetCount(langs)), devLang)) {
+            // Make sure that devLang is on the list as a fallback for individual resources that are not present
+            CFArrayAppendValue(langs, devLang);
+        } else if (!devLang) {
+            // Or if there is no devLang, try some variation of English that is present
+            CFArrayRef localizations = CFBundleCopyBundleLocalizations(bundle);
+            if (localizations) {
+                CFStringRef en_US = CFSTR("en_US"), en = CFSTR("en"), English = CFSTR("English");
+                CFRange range = CFRangeMake(0, CFArrayGetCount(localizations));
+                if (CFArrayContainsValue(localizations, range, en)) {
+                    if (!CFArrayContainsValue(langs, CFRangeMake(0, CFArrayGetCount(langs)), en)) CFArrayAppendValue(langs, en);
+                } else if (CFArrayContainsValue(localizations, range, English)) {
+                    if (!CFArrayContainsValue(langs, CFRangeMake(0, CFArrayGetCount(langs)), English)) CFArrayAppendValue(langs, English);
+                } else if (CFArrayContainsValue(localizations, range, en_US)) {
+                    if (!CFArrayContainsValue(langs, CFRangeMake(0, CFArrayGetCount(langs)), en_US)) CFArrayAppendValue(langs, en_US);
+                }
+                CFRelease(localizations);
+            }
+        }
+        if (CFArrayGetCount(langs) == 0) {
+            // Total backstop behavior to avoid having an empty array.
+            if (_defaultLocalization) {
+                CFArrayAppendValue(langs, _defaultLocalization);
+            } else {
+                CFArrayAppendValue(langs, CFSTR("en"));
+            }
+        }
+        bundle->_searchLanguages = langs;
+    }
+    return bundle->_searchLanguages;
+}
+
+CFDictionaryRef CFBundleCopyInfoDictionaryInDirectory(CFURLRef url) {return _CFBundleCopyInfoDictionaryInDirectory(kCFAllocatorSystemDefault, url, NULL);}
+
+CFDictionaryRef CFBundleGetInfoDictionary(CFBundleRef bundle) {
+    if (!bundle->_infoDict) bundle->_infoDict = _CFBundleCopyInfoDictionaryInDirectoryWithVersion(CFGetAllocator(bundle), bundle->_url, bundle->_version);
+    return bundle->_infoDict;
+}
+
+CFDictionaryRef _CFBundleGetLocalInfoDictionary(CFBundleRef bundle) {return CFBundleGetLocalInfoDictionary(bundle);}
+
+CFDictionaryRef CFBundleGetLocalInfoDictionary(CFBundleRef bundle) {
+    if (!bundle->_localInfoDict) {
+        CFURLRef url = CFBundleCopyResourceURL(bundle, _CFBundleLocalInfoName, _CFBundleStringTableType, NULL);
+        if (url) {
+            CFDataRef data;
+            SInt32 errCode;
+            CFStringRef errStr = NULL;
+            
+            if (CFURLCreateDataAndPropertiesFromResource(CFGetAllocator(bundle), url, &data, NULL, NULL, &errCode)) {
+                bundle->_localInfoDict = (CFDictionaryRef)CFPropertyListCreateFromXMLData(CFGetAllocator(bundle), data, kCFPropertyListImmutable, &errStr);
+                if (errStr) CFRelease(errStr);
+                if (bundle->_localInfoDict && CFDictionaryGetTypeID() != CFGetTypeID(bundle->_localInfoDict)) {
+                    CFRelease(bundle->_localInfoDict);
+                    bundle->_localInfoDict = NULL;
+                }
+                CFRelease(data);
+            }
+            CFRelease(url);
+        }
+    }
+    return bundle->_localInfoDict;
+}
+
+CFPropertyListRef _CFBundleGetValueForInfoKey(CFBundleRef bundle, CFStringRef key) {return (CFPropertyListRef)CFBundleGetValueForInfoDictionaryKey(bundle, key);}
+
+CFTypeRef CFBundleGetValueForInfoDictionaryKey(CFBundleRef bundle, CFStringRef key) {
+    // Look in InfoPlist.strings first.  Then look in Info.plist
+    CFTypeRef result = NULL;
+    if (bundle && key) {
+        CFDictionaryRef dict = CFBundleGetLocalInfoDictionary(bundle);
+        if (dict) result = CFDictionaryGetValue(dict, key);
+        if (!result) {
+            dict = CFBundleGetInfoDictionary(bundle);
+            if (dict) result = CFDictionaryGetValue(dict, key);
+        }
+    }
+    return result;
+}
+
+CFStringRef CFBundleGetIdentifier(CFBundleRef bundle) {
+    CFStringRef bundleID = NULL;
+    CFDictionaryRef infoDict = CFBundleGetInfoDictionary(bundle);
+    if (infoDict) bundleID = (CFStringRef)CFDictionaryGetValue(infoDict, kCFBundleIdentifierKey);
+    return bundleID;
+}
+
+#define DEVELOPMENT_STAGE 0x20
+#define ALPHA_STAGE 0x40
+#define BETA_STAGE 0x60
+#define RELEASE_STAGE 0x80
+
+#define MAX_VERS_LEN 10
+
+CF_INLINE Boolean _isDigit(UniChar aChar) {return (((aChar >= (UniChar)'0') && (aChar <= (UniChar)'9')) ? true : false);}
+
+__private_extern__ CFStringRef _CFCreateStringFromVersionNumber(CFAllocatorRef alloc, UInt32 vers) {
+    CFStringRef result = NULL;
+    uint8_t major1, major2, minor1, minor2, stage, build;
+
+    major1 = (vers & 0xF0000000) >> 28;
+    major2 = (vers & 0x0F000000) >> 24;
+    minor1 = (vers & 0x00F00000) >> 20;
+    minor2 = (vers & 0x000F0000) >> 16;
+    stage = (vers & 0x0000FF00) >> 8;
+    build = (vers & 0x000000FF);
+
+    if (stage == RELEASE_STAGE) {
+        if (major1 > 0) {
+            result = CFStringCreateWithFormat(alloc, NULL, CFSTR("%d%d.%d.%d"), major1, major2, minor1, minor2);
+        } else {
+            result = CFStringCreateWithFormat(alloc, NULL, CFSTR("%d.%d.%d"), major2, minor1, minor2);
+        }
+    } else {
+        if (major1 > 0) {
+            result = CFStringCreateWithFormat(alloc, NULL, CFSTR("%d%d.%d.%d%s%d"), major1, major2, minor1, minor2, ((stage == DEVELOPMENT_STAGE) ? "d" : ((stage == ALPHA_STAGE) ? "a" : "b")), build);
+        } else {
+            result = CFStringCreateWithFormat(alloc, NULL, CFSTR("%d.%d.%d%s%d"), major2, minor1, minor2, ((stage == DEVELOPMENT_STAGE) ? "d" : ((stage == ALPHA_STAGE) ? "a" : "b")), build);
+        }
+    }
+    return result;
+}
+
+__private_extern__ UInt32 _CFVersionNumberFromString(CFStringRef versStr) {
+    // Parse version number from string.
+    // String can begin with "." for major version number 0.  String can end at any point, but elements within the string cannot be skipped.
+    UInt32 major1 = 0, major2 = 0, minor1 = 0, minor2 = 0, stage = RELEASE_STAGE, build = 0;
+    UniChar versChars[MAX_VERS_LEN];
+    UniChar *chars = NULL;
+    CFIndex len;
+    UInt32 theVers;
+    Boolean digitsDone = false;
+
+    if (!versStr) return 0;
+
+    len = CFStringGetLength(versStr);
+
+    if ((len == 0) || (len > MAX_VERS_LEN)) return 0;
+
+    CFStringGetCharacters(versStr, CFRangeMake(0, len), versChars);
+    chars = versChars;
+    
+    // Get major version number.
+    major1 = major2 = 0;
+    if (_isDigit(*chars)) {
+        major2 = *chars - (UniChar)'0';
+        chars++;
+        len--;
+        if (len > 0) {
+            if (_isDigit(*chars)) {
+                major1 = major2;
+                major2 = *chars - (UniChar)'0';
+                chars++;
+                len--;
+                if (len > 0) {
+                    if (*chars == (UniChar)'.') {
+                        chars++;
+                        len--;
+                    } else {
+                        digitsDone = true;
+                    }
+                }
+            } else if (*chars == (UniChar)'.') {
+                chars++;
+                len--;
+            } else {
+                digitsDone = true;
+            }
+        }
+    } else if (*chars == (UniChar)'.') {
+        chars++;
+        len--;
+    } else {
+        digitsDone = true;
+    }
+
+    // Now major1 and major2 contain first and second digit of the major version number as ints.
+    // Now either len is 0 or chars points at the first char beyond the first decimal point.
+
+    // Get the first minor version number.  
+    if (len > 0 && !digitsDone) {
+        if (_isDigit(*chars)) {
+            minor1 = *chars - (UniChar)'0';
+            chars++;
+            len--;
+            if (len > 0) {
+                if (*chars == (UniChar)'.') {
+                    chars++;
+                    len--;
+                } else {
+                    digitsDone = true;
+                }
+            }
+        } else {
+            digitsDone = true;
+        }
+    }
+
+    // Now minor1 contains the first minor version number as an int.
+    // Now either len is 0 or chars points at the first char beyond the second decimal point.
+
+    // Get the second minor version number. 
+    if (len > 0 && !digitsDone) {
+        if (_isDigit(*chars)) {
+            minor2 = *chars - (UniChar)'0';
+            chars++;
+            len--;
+        } else {
+            digitsDone = true;
+        }
+    }
+
+    // Now minor2 contains the second minor version number as an int.
+    // Now either len is 0 or chars points at the build stage letter.
+
+    // Get the build stage letter.  We must find 'd', 'a', 'b', or 'f' next, if there is anything next.
+    if (len > 0) {
+        if (*chars == (UniChar)'d') {
+            stage = DEVELOPMENT_STAGE;
+        } else if (*chars == (UniChar)'a') {
+            stage = ALPHA_STAGE;
+        } else if (*chars == (UniChar)'b') {
+            stage = BETA_STAGE;
+        } else if (*chars == (UniChar)'f') {
+            stage = RELEASE_STAGE;
+        } else {
+            return 0;
+        }
+        chars++;
+        len--;
+    }
+
+    // Now stage contains the release stage.
+    // Now either len is 0 or chars points at the build number.
+
+    // Get the first digit of the build number.
+    if (len > 0) {
+        if (_isDigit(*chars)) {
+            build = *chars - (UniChar)'0';
+            chars++;
+            len--;
+        } else {
+            return 0;
+        }
+    }
+    // Get the second digit of the build number.
+    if (len > 0) {
+        if (_isDigit(*chars)) {
+            build *= 10;
+            build += *chars - (UniChar)'0';
+            chars++;
+            len--;
+        } else {
+            return 0;
+        }
+    }
+    // Get the third digit of the build number.
+    if (len > 0) {
+        if (_isDigit(*chars)) {
+            build *= 10;
+            build += *chars - (UniChar)'0';
+            chars++;
+            len--;
+        } else {
+            return 0;
+        }
+    }
+
+    // Range check the build number and make sure we exhausted the string.
+    if ((build > 0xFF) || (len > 0)) return 0;
+
+    // Build the number
+    theVers = major1 << 28;
+    theVers += major2 << 24;
+    theVers += minor1 << 20;
+    theVers += minor2 << 16;
+    theVers += stage << 8;
+    theVers += build;
+
+    return theVers;
+}
+
+UInt32 CFBundleGetVersionNumber(CFBundleRef bundle) {
+    CFDictionaryRef infoDict = CFBundleGetInfoDictionary(bundle);
+    CFTypeRef unknownVersionValue = CFDictionaryGetValue(infoDict, _kCFBundleNumericVersionKey);
+    CFNumberRef versNum;
+    UInt32 vers = 0;
+
+    if (!unknownVersionValue) unknownVersionValue = CFDictionaryGetValue(infoDict, kCFBundleVersionKey);
+    if (unknownVersionValue) {
+        if (CFGetTypeID(unknownVersionValue) == CFStringGetTypeID()) {
+            // Convert a string version number into a numeric one.
+            vers = _CFVersionNumberFromString((CFStringRef)unknownVersionValue);
+
+            versNum = CFNumberCreate(CFGetAllocator(bundle), kCFNumberSInt32Type, &vers);
+            CFDictionarySetValue((CFMutableDictionaryRef)infoDict, _kCFBundleNumericVersionKey, versNum);
+            CFRelease(versNum);
+        } else if (CFGetTypeID(unknownVersionValue) == CFNumberGetTypeID()) {
+            CFNumberGetValue((CFNumberRef)unknownVersionValue, kCFNumberSInt32Type, &vers);
+        } else {
+            CFDictionaryRemoveValue((CFMutableDictionaryRef)infoDict, _kCFBundleNumericVersionKey);
+        }
+    }
+    return vers;
+}
+
+CFStringRef CFBundleGetDevelopmentRegion(CFBundleRef bundle) {
+    CFStringRef devLang = NULL;
+    CFDictionaryRef infoDict = CFBundleGetInfoDictionary(bundle);
+    if (infoDict) {
+        devLang = (CFStringRef)CFDictionaryGetValue(infoDict, kCFBundleDevelopmentRegionKey);
+        if (devLang && (CFGetTypeID(devLang) != CFStringGetTypeID() || CFStringGetLength(devLang) == 0)) {
+            devLang = NULL;
+            CFDictionaryRemoveValue((CFMutableDictionaryRef)infoDict, kCFBundleDevelopmentRegionKey);
+        }
+    }
+
+    return devLang;
+}
+
+Boolean _CFBundleGetHasChanged(CFBundleRef bundle) {
+    CFDateRef modDate;
+    Boolean result = false;
+    Boolean exists = false;
+    SInt32 mode = 0;
+
+    if (_CFGetFileProperties(CFGetAllocator(bundle), bundle->_url, &exists, &mode, NULL, &modDate, NULL, NULL) == 0) {
+        // If the bundle no longer exists or is not a folder, it must have "changed"
+        if (!exists || ((mode & S_IFMT) != S_IFDIR)) result = true;
+    } else {
+        // Something is wrong.  The stat failed.
+        result = true;
+    }
+    if (bundle->_modDate && !CFEqual(bundle->_modDate, modDate)) {
+        // mod date is different from when we created.
+        result = true;
+    }
+    CFRelease(modDate);
+    return result;
+}
+
+void _CFBundleSetStringsFilesShared(CFBundleRef bundle, Boolean flag) {
+    bundle->_sharesStringsFiles = flag;
+}
+
+Boolean _CFBundleGetStringsFilesShared(CFBundleRef bundle) {
+    return bundle->_sharesStringsFiles;
+}
+
+static Boolean _urlExists(CFAllocatorRef alloc, CFURLRef url) {
+    Boolean exists;
+    return url && (0 == _CFGetFileProperties(alloc, url, &exists, NULL, NULL, NULL, NULL, NULL)) && exists;
+}
+
+__private_extern__ CFURLRef _CFBundleCopySupportFilesDirectoryURLInDirectory(CFAllocatorRef alloc, CFURLRef bundleURL, uint8_t version) {
+    CFURLRef result = NULL;
+    if (bundleURL) {
+        if (1 == version) {
+            result = CFURLCreateWithString(alloc, _CFBundleSupportFilesURLFromBase1, bundleURL);
+        } else if (2 == version) {
+            result = CFURLCreateWithString(alloc, _CFBundleSupportFilesURLFromBase2, bundleURL);
+        } else {
+            result = (CFURLRef)CFRetain(bundleURL);
+        }
+    }
+    return result;
+}
+
+CF_EXPORT CFURLRef CFBundleCopySupportFilesDirectoryURL(CFBundleRef bundle) {return _CFBundleCopySupportFilesDirectoryURLInDirectory(CFGetAllocator(bundle), bundle->_url, bundle->_version);}
+
+__private_extern__ CFURLRef _CFBundleCopyResourcesDirectoryURLInDirectory(CFAllocatorRef alloc, CFURLRef bundleURL, uint8_t version) {
+    CFURLRef result = NULL;
+    if (bundleURL) {
+        if (0 == version) {
+            result = CFURLCreateWithString(alloc, _CFBundleResourcesURLFromBase0, bundleURL);
+        } else if (1 == version) {
+            result = CFURLCreateWithString(alloc, _CFBundleResourcesURLFromBase1, bundleURL);
+        } else if (2 == version) {
+            result = CFURLCreateWithString(alloc, _CFBundleResourcesURLFromBase2, bundleURL);
+        } else {
+            result = (CFURLRef)CFRetain(bundleURL);
+        }
+    }
+    return result;
+}
+
+CFURLRef CFBundleCopyResourcesDirectoryURL(CFBundleRef bundle) {return _CFBundleCopyResourcesDirectoryURLInDirectory(CFGetAllocator(bundle), bundle->_url, bundle->_version);}
+
+static CFURLRef _CFBundleCopyExecutableURLRaw(CFAllocatorRef alloc, CFURLRef urlPath, CFStringRef exeName) {
+    // Given an url to a folder and a name, this returns the url to the executable in that folder with that name, if it exists, and NULL otherwise.  This function deals with appending the ".exe" or ".dll" on Windows.
+    CFURLRef executableURL = NULL;
+    if (!urlPath || !exeName) return NULL;
+    
+#if DEPLOYMENT_TARGET_MACOSX
+    const uint8_t *image_suffix = (uint8_t *)getenv("DYLD_IMAGE_SUFFIX");
+    if (image_suffix) {
+        CFStringRef newExeName, imageSuffix;
+        imageSuffix = CFStringCreateWithCString(kCFAllocatorSystemDefault, (char *)image_suffix, kCFStringEncodingUTF8);
+        if (CFStringHasSuffix(exeName, CFSTR(".dylib"))) {
+            CFStringRef bareExeName = CFStringCreateWithSubstring(alloc, exeName, CFRangeMake(0, CFStringGetLength(exeName)-6));
+            newExeName = CFStringCreateWithFormat(alloc, NULL, CFSTR("%@%@.dylib"), exeName, imageSuffix);
+            CFRelease(bareExeName);
+        } else {
+            newExeName = CFStringCreateWithFormat(alloc, NULL, CFSTR("%@%@"), exeName, imageSuffix);
+        }
+        executableURL = CFURLCreateWithFileSystemPathRelativeToBase(alloc, newExeName, kCFURLPOSIXPathStyle, false, urlPath);
+        if (executableURL && !_urlExists(alloc, executableURL)) {
+            CFRelease(executableURL);
+            executableURL = NULL;
+        }
+        CFRelease(newExeName);
+        CFRelease(imageSuffix);
+    }
+#endif
+    if (!executableURL) {
+        executableURL = CFURLCreateWithFileSystemPathRelativeToBase(alloc, exeName, kCFURLPOSIXPathStyle, false, urlPath);
+        if (executableURL && !_urlExists(alloc, executableURL)) {
+            CFRelease(executableURL);
+            executableURL = NULL;
+        }
+    }
+#if defined(DEPLOYMENT_TARGET_WINDOWS)
+    if (executableURL == NULL) {
+        if (!CFStringHasSuffix(exeName, CFSTR(".dll"))) {
+            CFStringRef newExeName = CFStringCreateWithFormat(alloc, NULL, CFSTR("%@%@"), exeName, CFSTR(".dll"));
+            executableURL = CFURLCreateWithString(alloc, newExeName, urlPath);
+            if (executableURL != NULL && !_urlExists(alloc, executableURL)) {
+                CFRelease(executableURL);
+                executableURL = NULL;
+            }
+            CFRelease(newExeName);
+        }
+    }
+    if (executableURL == NULL) {
+        if (!CFStringHasSuffix(exeName, CFSTR(".exe"))) {
+            CFStringRef newExeName = CFStringCreateWithFormat(alloc, NULL, CFSTR("%@%@"), exeName, CFSTR(".exe"));
+            executableURL = CFURLCreateWithString(alloc, newExeName, urlPath);
+            if (executableURL != NULL && !_urlExists(alloc, executableURL)) {
+                CFRelease(executableURL);
+                executableURL = NULL;
+            }
+            CFRelease(newExeName);
+        }
+    }
+#endif
+    return executableURL;
+}
+
+static CFStringRef _CFBundleCopyExecutableName(CFAllocatorRef alloc, CFBundleRef bundle, CFURLRef url, CFDictionaryRef infoDict) {
+    CFStringRef executableName = NULL;
+    
+    if (!alloc && bundle) alloc = CFGetAllocator(bundle);
+    if (!infoDict && bundle) infoDict = CFBundleGetInfoDictionary(bundle);
+    if (!url && bundle) url = bundle->_url;
+    
+    if (infoDict) {
+        // Figure out the name of the executable.
+        // First try for the new key in the plist.
+        executableName = (CFStringRef)CFDictionaryGetValue(infoDict, kCFBundleExecutableKey);
+        // Second try for the old key in the plist.
+        if (!executableName) executableName = (CFStringRef)CFDictionaryGetValue(infoDict, _kCFBundleOldExecutableKey);
+        if (executableName && CFGetTypeID(executableName) == CFStringGetTypeID() && CFStringGetLength(executableName) > 0) {
+            CFRetain(executableName);
+        } else {
+            executableName = NULL;
+        }
+    }
+    if (!executableName && url) {
+        // Third, take the name of the bundle itself (with path extension stripped)
+        CFURLRef absoluteURL = CFURLCopyAbsoluteURL(url);
+        CFStringRef bundlePath = CFURLCopyFileSystemPath(absoluteURL, PLATFORM_PATH_STYLE);
+        UniChar buff[CFMaxPathSize];
+        CFIndex len = CFStringGetLength(bundlePath);
+        CFIndex startOfBundleName, endOfBundleName;
+
+        CFRelease(absoluteURL);
+        if (len > CFMaxPathSize) len = CFMaxPathSize;
+        CFStringGetCharacters(bundlePath, CFRangeMake(0, len), buff);
+        startOfBundleName = _CFStartOfLastPathComponent(buff, len);
+        endOfBundleName = _CFLengthAfterDeletingPathExtension(buff, len);
+
+        if ((startOfBundleName <= len) && (endOfBundleName <= len) && (startOfBundleName < endOfBundleName)) {
+            executableName = CFStringCreateWithCharacters(alloc, &(buff[startOfBundleName]), (endOfBundleName - startOfBundleName));
+        }
+        CFRelease(bundlePath);
+    }
+    
+    return executableName;
+}
+
+__private_extern__ CFURLRef _CFBundleCopyResourceForkURLMayBeLocal(CFBundleRef bundle, Boolean mayBeLocal) {
+    CFStringRef executableName = _CFBundleCopyExecutableName(kCFAllocatorSystemDefault, bundle, NULL, NULL);
+    CFURLRef resourceForkURL = NULL;
+    if (executableName) {
+        if (mayBeLocal) {
+            resourceForkURL = CFBundleCopyResourceURL(bundle, executableName, CFSTR("rsrc"), NULL);
+        } else {
+            resourceForkURL = CFBundleCopyResourceURLForLocalization(bundle, executableName, CFSTR("rsrc"), NULL, NULL);
+        }
+        CFRelease(executableName);
+    }
+    
+    return resourceForkURL;
+}
+
+CFURLRef _CFBundleCopyResourceForkURL(CFBundleRef bundle) {return _CFBundleCopyResourceForkURLMayBeLocal(bundle, true);}
+
+static CFURLRef _CFBundleCopyExecutableURLInDirectoryWithAllocator(CFAllocatorRef alloc, CFBundleRef bundle, CFURLRef url, CFStringRef executableName, Boolean ignoreCache, Boolean useOtherPlatform) {
+    uint8_t version = 0;
+    CFDictionaryRef infoDict = NULL;
+    CFStringRef executablePath = NULL;
+    CFURLRef executableURL = NULL;
+    Boolean foundIt = false;
+    Boolean lookupMainExe = (executableName ? false : true);
+    
+    if (bundle) {
+        infoDict = CFBundleGetInfoDictionary(bundle);
+        version = bundle->_version;
+    } else {
+        infoDict = _CFBundleCopyInfoDictionaryInDirectory(alloc, url, &version);
+    }
+
+    // If we have a bundle instance and an info dict, see if we have already cached the path
+    if (lookupMainExe && !ignoreCache && !useOtherPlatform && bundle && infoDict) {
+        executablePath = (CFStringRef)CFDictionaryGetValue(infoDict, _kCFBundleExecutablePathKey);
+        if (executablePath) {
+#if DEPLOYMENT_TARGET_MACOSX
+            executableURL = CFURLCreateWithFileSystemPath(alloc, executablePath, kCFURLPOSIXPathStyle, false);
+#else
+            executableURL = CFURLCreateWithFileSystemPath(alloc, executablePath, kCFURLWindowsPathStyle, false);
+#endif
+            if (executableURL) foundIt = true;
+            if (!foundIt) {
+                executablePath = NULL;
+                CFDictionaryRemoveValue((CFMutableDictionaryRef)infoDict, _kCFBundleExecutablePathKey);
+            }
+        }
+    }
+
+    if (!foundIt) {
+        if (lookupMainExe) {
+            executableName = _CFBundleCopyExecutableName(alloc, bundle, url, infoDict);
+        }
+        if (executableName) {
+            Boolean doExecSearch = true;
+            // Now, look for the executable inside the bundle.
+            if (doExecSearch && 0 != version) {
+                CFURLRef exeDirURL;
+                CFURLRef exeSubdirURL;
+
+                if (1 == version) {
+                    exeDirURL = CFURLCreateWithString(alloc, _CFBundleExecutablesURLFromBase1, url);
+                } else if (2 == version) {
+                    exeDirURL = CFURLCreateWithString(alloc, _CFBundleExecutablesURLFromBase2, url);
+                } else {
+                    exeDirURL = (CFURLRef)CFRetain(url);
+                }
+                CFStringRef platformSubDir = useOtherPlatform ? _CFBundleGetOtherPlatformExecutablesSubdirectoryName() : _CFBundleGetPlatformExecutablesSubdirectoryName();
+                exeSubdirURL = CFURLCreateWithFileSystemPathRelativeToBase(alloc, platformSubDir, kCFURLPOSIXPathStyle, true, exeDirURL);
+                executableURL = _CFBundleCopyExecutableURLRaw(alloc, exeSubdirURL, executableName);
+                if (!executableURL) {
+                    CFRelease(exeSubdirURL);
+                    platformSubDir = useOtherPlatform ? _CFBundleGetOtherAlternatePlatformExecutablesSubdirectoryName() : _CFBundleGetAlternatePlatformExecutablesSubdirectoryName();
+                    exeSubdirURL = CFURLCreateWithFileSystemPathRelativeToBase(alloc, platformSubDir, kCFURLPOSIXPathStyle, true, exeDirURL);
+                    executableURL = _CFBundleCopyExecutableURLRaw(alloc, exeSubdirURL, executableName);
+                }
+                if (!executableURL) {
+                    CFRelease(exeSubdirURL);
+                    platformSubDir = useOtherPlatform ? _CFBundleGetPlatformExecutablesSubdirectoryName() : _CFBundleGetOtherPlatformExecutablesSubdirectoryName();
+                    exeSubdirURL = CFURLCreateWithFileSystemPathRelativeToBase(alloc, platformSubDir, kCFURLPOSIXPathStyle, true, exeDirURL);
+                    executableURL = _CFBundleCopyExecutableURLRaw(alloc, exeSubdirURL, executableName);
+                }
+                if (!executableURL) {
+                    CFRelease(exeSubdirURL);
+                    platformSubDir = useOtherPlatform ? _CFBundleGetAlternatePlatformExecutablesSubdirectoryName() : _CFBundleGetOtherAlternatePlatformExecutablesSubdirectoryName();
+                    exeSubdirURL = CFURLCreateWithFileSystemPathRelativeToBase(alloc, platformSubDir, kCFURLPOSIXPathStyle, true, exeDirURL);
+                    executableURL = _CFBundleCopyExecutableURLRaw(alloc, exeSubdirURL, executableName);
+                }
+                if (!executableURL) {
+                    executableURL = _CFBundleCopyExecutableURLRaw(alloc, exeDirURL, executableName);
+                }
+
+                CFRelease(exeDirURL);
+                CFRelease(exeSubdirURL);
+            }
+
+#if defined(DEPLOYMENT_TARGET_WINDOWS)
+            // Windows only: If we still haven't found the exe, look in the Executables folder.
+            // But only for the main bundle exe
+            if (lookupMainExe && (executableURL == NULL)) {
+                CFURLRef exeDirURL;
+
+                exeDirURL = CFURLCreateWithString(alloc, CFSTR("../../Executables"), url);
+
+                executableURL = _CFBundleCopyExecutableURLRaw(alloc, exeDirURL, executableName);
+
+                CFRelease(exeDirURL);
+            }
+#endif
+
+            // If this was an old bundle, or we did not find the executable in the Excutables subdirectory, look directly in the bundle wrapper.
+            if (!executableURL) executableURL = _CFBundleCopyExecutableURLRaw(alloc, url, executableName);
+            if (lookupMainExe && !ignoreCache && !useOtherPlatform && bundle && infoDict && executableURL) {
+                // We found it.  Cache the path.
+                CFURLRef absURL = CFURLCopyAbsoluteURL(executableURL);
+#if DEPLOYMENT_TARGET_MACOSX
+                executablePath = CFURLCopyFileSystemPath(absURL, kCFURLPOSIXPathStyle);
+#else
+                executablePath = CFURLCopyFileSystemPath(absURL, kCFURLWindowsPathStyle);
+#endif
+                CFRelease(absURL);
+                CFDictionarySetValue((CFMutableDictionaryRef)infoDict, _kCFBundleExecutablePathKey, executablePath);
+                CFRelease(executablePath);
+            }
+            if (lookupMainExe && !useOtherPlatform && bundle && !executableURL) bundle->_binaryType = __CFBundleNoBinary;
+            if (lookupMainExe) CFRelease(executableName);
+        }
+    }
+
+    if (!bundle && infoDict) CFRelease(infoDict);
+
+    return executableURL;
+}
+
+CFURLRef _CFBundleCopyExecutableURLInDirectory(CFURLRef url) {return _CFBundleCopyExecutableURLInDirectoryWithAllocator(kCFAllocatorSystemDefault, NULL, url, NULL, true, false);}
+
+CFURLRef _CFBundleCopyOtherExecutableURLInDirectory(CFURLRef url) {return _CFBundleCopyExecutableURLInDirectoryWithAllocator(kCFAllocatorSystemDefault, NULL, url, NULL, true, true);}
+
+CFURLRef CFBundleCopyExecutableURL(CFBundleRef bundle) {return _CFBundleCopyExecutableURLInDirectoryWithAllocator(CFGetAllocator(bundle), bundle, bundle->_url, NULL, false, false);}
+
+static CFURLRef _CFBundleCopyExecutableURLIgnoringCache(CFBundleRef bundle) {return _CFBundleCopyExecutableURLInDirectoryWithAllocator(CFGetAllocator(bundle), bundle, bundle->_url, NULL, true, false);}
+
+CFURLRef CFBundleCopyAuxiliaryExecutableURL(CFBundleRef bundle, CFStringRef executableName) {return _CFBundleCopyExecutableURLInDirectoryWithAllocator(CFGetAllocator(bundle), bundle, bundle->_url, executableName, true, false);}
+
+Boolean CFBundleIsExecutableLoaded(CFBundleRef bundle) {return bundle->_isLoaded;}
+
+CFBundleExecutableType CFBundleGetExecutableType(CFBundleRef bundle) {
+    CFBundleExecutableType result = kCFBundleOtherExecutableType;
+    CFURLRef executableURL = CFBundleCopyExecutableURL(bundle);
+
+    if (!executableURL) bundle->_binaryType = __CFBundleNoBinary;
+#if defined(BINARY_SUPPORT_DYLD)
+    if (bundle->_binaryType == __CFBundleUnknownBinary) {
+        bundle->_binaryType = _CFBundleGrokBinaryType(executableURL);
+#if defined(BINARY_SUPPORT_CFM)
+        if (bundle->_binaryType != __CFBundleCFMBinary && bundle->_binaryType != __CFBundleUnreadableBinary) bundle->_resourceData._executableLacksResourceFork = true;
+#endif /* BINARY_SUPPORT_CFM */
+    }
+#endif /* BINARY_SUPPORT_DYLD */
+    if (executableURL) CFRelease(executableURL);
+
+    if (bundle->_binaryType == __CFBundleCFMBinary) {
+        result = kCFBundlePEFExecutableType;
+    } else if (bundle->_binaryType == __CFBundleDYLDExecutableBinary || bundle->_binaryType == __CFBundleDYLDBundleBinary || bundle->_binaryType == __CFBundleDYLDFrameworkBinary) {
+        result = kCFBundleMachOExecutableType;
+    } else if (bundle->_binaryType == __CFBundleDLLBinary) {
+        result = kCFBundleDLLExecutableType;
+    } else if (bundle->_binaryType == __CFBundleELFBinary) {
+        result = kCFBundleELFExecutableType;    
+    }
+    return result;
+}
+
+#define UNKNOWN_FILETYPE 0x0
+#define PEF_FILETYPE 0x1000
+#define PEF_MAGIC 0x4a6f7921
+#define PEF_CIGAM 0x21796f4a
+#define TEXT_SEGMENT "__TEXT"
+#define PLIST_SECTION "__info_plist"
+#define OBJC_SEGMENT "__OBJC"
+#define IMAGE_INFO_SECTION "__image_info"
+#define LIB_X11 "/usr/X11R6/lib/libX"
+
+#define XLS_NAME "Book"
+#define XLS_NAME2 "Workbook"
+#define DOC_NAME "WordDocument"
+#define PPT_NAME "PowerPoint Document"
+
+#define ustrncmp(x, y, z) strncmp((char *)(x), (char *)(y), (z))
+#if DEPLOYMENT_TARGET_WINDOWS
+#if _MSC_VER
+#define ustrncasecmp(x, y, z) _strnicmp_l((char *)(x), (char *)(y), (z), NULL)
+#else
+#define ustrncasecmp(x, y, z) strncasecmp((char *)(x), (char *)(y), (z))
+#endif
+#elif DEPLOYMENT_TARGET_LINUX
+// When compiling with -Wall the GNU C library complains about passing
+// NULL to strncasecmp_l as the locale. Since a locale is never
+// passed, the C locale version should be a suitable replacement.
+#define ustrncasecmp(x, y, z) strncasecmp((char *)(x), (char *)(y), (z))
+#else
+#define ustrncasecmp(x, y, z) strncasecmp_l((char *)(x), (char *)(y), (z), NULL)
+#endif
+
+static const uint32_t __CFBundleMagicNumbersArray[] = {
+    0xcafebabe, 0xbebafeca, 0xfeedface, 0xcefaedfe, 0xfeedfacf, 0xcffaedfe, 0x4a6f7921, 0x21796f4a, 
+    0x7f454c46, 0xffd8ffe0, 0x4d4d002a, 0x49492a00, 0x47494638, 0x89504e47, 0x69636e73, 0x00000100, 
+    0x7b5c7274, 0x25504446, 0x2e7261fd, 0x2e524d46, 0x2e736e64, 0x2e736400, 0x464f524d, 0x52494646, 
+    0x38425053, 0x000001b3, 0x000001ba, 0x4d546864, 0x504b0304, 0x53495421, 0x53495432, 0x53495435, 
+    0x53495444, 0x53747566, 0x30373037, 0x3c212d2d, 0x25215053, 0xd0cf11e0, 0x62656769, 0x3d796265,
+    0x6b6f6c79, 0x3026b275, 0x0000000c, 0xfe370023, 0x09020600, 0x09040600, 0x4f676753, 0x664c6143, 
+    0x00010000, 0x74727565, 0x4f54544f, 0x41433130, 0xc809fe02, 0x0809fe02, 0x2356524d, 0x67696d70, 
+    0x3c435058, 0x28445746, 0x424f4d53, 0x49544f4c, 0x72746664
+};
+
+// string, with groups of 5 characters being 1 element in the array
+static const char * __CFBundleExtensionsArray =
+    "mach\0"  "mach\0"  "mach\0"  "mach\0"  "mach\0"  "mach\0"  "pef\0\0" "pef\0\0" 
+    "elf\0\0" "jpeg\0"  "tiff\0"  "tiff\0"  "gif\0\0" "png\0\0" "icns\0"  "ico\0\0" 
+    "rtf\0\0" "pdf\0\0" "ra\0\0\0""rm\0\0\0""au\0\0\0""au\0\0\0""iff\0\0" "riff\0"  
+    "psd\0\0" "mpeg\0"  "mpeg\0"  "mid\0\0" "zip\0\0" "sit\0\0" "sit\0\0" "sit\0\0" 
+    "sit\0\0" "sit\0\0" "cpio\0"  "html\0"  "ps\0\0\0""ole\0\0" "uu\0\0\0""ync\0\0"
+    "dmg\0\0" "wmv\0\0" "jp2\0\0" "doc\0\0" "xls\0\0" "xls\0\0" "ogg\0\0" "flac\0"
+    "ttf\0\0" "ttf\0\0" "otf\0\0" "dwg\0\0" "dgn\0\0" "dgn\0\0" "wrl\0\0" "xcf\0\0"
+    "cpx\0\0" "dwf\0\0" "bom\0\0" "lit\0\0" "rtfd\0";
+
+static const char * __CFBundleOOExtensionsArray = "sxc\0\0" "sxd\0\0" "sxg\0\0" "sxi\0\0" "sxm\0\0" "sxw\0\0";
+static const char * __CFBundleODExtensionsArray = "odc\0\0" "odf\0\0" "odg\0\0" "oth\0\0" "odi\0\0" "odm\0\0" "odp\0\0" "ods\0\0" "odt\0\0";
+
+#define EXTENSION_LENGTH                5
+#define NUM_EXTENSIONS                  61
+#define MAGIC_BYTES_TO_READ             512
+#define DMG_BYTES_TO_READ               512
+#define ZIP_BYTES_TO_READ               1024
+#define OLE_BYTES_TO_READ               512
+#define X11_BYTES_TO_READ               4096
+#define IMAGE_INFO_BYTES_TO_READ        4096
+
+#if defined(BINARY_SUPPORT_DYLD)
+
+CF_INLINE uint32_t _CFBundleSwapInt32Conditional(uint32_t arg, Boolean swap) {return swap ? CFSwapInt32(arg) : arg;}
+CF_INLINE uint32_t _CFBundleSwapInt64Conditional(uint64_t arg, Boolean swap) {return swap ? CFSwapInt64(arg) : arg;}
+
+static CFDictionaryRef _CFBundleGrokInfoDictFromData(const char *bytes, uint32_t length) {
+    CFMutableDictionaryRef result = NULL;
+    CFDataRef infoData = NULL;
+    if (bytes && 0 < length) {
+        infoData = CFDataCreateWithBytesNoCopy(kCFAllocatorSystemDefault, (uint8_t *)bytes, length, kCFAllocatorNull);
+        if (infoData) {
+            result = (CFMutableDictionaryRef)CFPropertyListCreateFromXMLData(kCFAllocatorSystemDefault, infoData, kCFPropertyListMutableContainers, NULL);
+            if (result && CFDictionaryGetTypeID() != CFGetTypeID(result)) {
+                CFRelease(result);
+                result = NULL;
+            }
+            CFRelease(infoData);
+        }
+        if (!result) result = CFDictionaryCreateMutable(kCFAllocatorSystemDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+    }
+    return result;
+}
+
+static CFDictionaryRef _CFBundleGrokInfoDictFromMainExecutable() {
+    unsigned long length = 0;
+    char *bytes = getsectdata(TEXT_SEGMENT, PLIST_SECTION, &length);
+    return _CFBundleGrokInfoDictFromData(bytes, length);
+}
+
+static Boolean _CFBundleGrokObjCImageInfoFromMainExecutable(uint32_t *objcVersion, uint32_t *objcFlags) {
+    Boolean retval = false;
+    uint32_t localVersion = 0, localFlags = 0;
+    if (getsegbyname(OBJC_SEGMENT)) {
+        unsigned long length = 0;
+        char *bytes = getsectdata(OBJC_SEGMENT, IMAGE_INFO_SECTION, &length);
+        if (bytes && length >= 8) {
+            localVersion = *(uint32_t *)bytes;
+            localFlags = *(uint32_t *)(bytes + 4);
+        }
+        retval = true;
+    }
+    if (objcVersion) *objcVersion = localVersion;
+    if (objcFlags) *objcFlags = localFlags;
+    return retval;
+}
+
+static Boolean _CFBundleGrokX11FromFile(int fd, const void *bytes, CFIndex length, uint32_t offset, Boolean swapped, Boolean sixtyFour) {
+    static const char libX11name[] = LIB_X11;
+    char *buffer = NULL;
+    const char *loc = NULL;
+    unsigned i;
+    Boolean result = false;
+    
+    if (fd >= 0 && lseek(fd, offset, SEEK_SET) == (off_t)offset) {
+        buffer = (char*)malloc(X11_BYTES_TO_READ);
+        if (buffer && read(fd, buffer, X11_BYTES_TO_READ) >= X11_BYTES_TO_READ) loc = buffer;
+    } else if (bytes && length >= offset + X11_BYTES_TO_READ) {
+        loc = (const char*)bytes + offset;
+    }
+    if (loc) {
+        if (sixtyFour) {
+            uint32_t ncmds = _CFBundleSwapInt32Conditional(((struct mach_header_64 *)loc)->ncmds, swapped);
+            uint32_t sizeofcmds = _CFBundleSwapInt32Conditional(((struct mach_header_64 *)loc)->sizeofcmds, swapped);
+            const char *startofcmds = loc + sizeof(struct mach_header_64);
+            const char *endofcmds = startofcmds + sizeofcmds;
+            struct dylib_command *dlp = (struct dylib_command *)startofcmds;
+            if (endofcmds > loc + X11_BYTES_TO_READ) endofcmds = loc + X11_BYTES_TO_READ;
+            for (i = 0; !result && i < ncmds && startofcmds <= (char *)dlp && (char *)dlp < endofcmds; i++) {
+                if (LC_LOAD_DYLIB == _CFBundleSwapInt32Conditional(dlp->cmd, swapped)) {
+                    uint32_t nameoffset = _CFBundleSwapInt32Conditional(dlp->dylib.name.offset, swapped);
+                    const char *name = (const char *)dlp + nameoffset;
+                    if (startofcmds <= name && name + sizeof(libX11name) <= endofcmds && 0 == strncmp(name, libX11name, sizeof(libX11name) - 1)) result = true;
+                }
+                dlp = (struct dylib_command *)((char *)dlp + _CFBundleSwapInt32Conditional(dlp->cmdsize, swapped));
+            }
+        } else {
+            uint32_t ncmds = _CFBundleSwapInt32Conditional(((struct mach_header *)loc)->ncmds, swapped);
+            uint32_t sizeofcmds = _CFBundleSwapInt32Conditional(((struct mach_header *)loc)->sizeofcmds, swapped);
+            const char *startofcmds = loc + sizeof(struct mach_header);
+            const char *endofcmds = startofcmds + sizeofcmds;
+            struct dylib_command *dlp = (struct dylib_command *)startofcmds;
+            if (endofcmds > loc + X11_BYTES_TO_READ) endofcmds = loc + X11_BYTES_TO_READ;
+            for (i = 0; !result && i < ncmds && startofcmds <= (char *)dlp && (char *)dlp < endofcmds; i++) {
+                if (LC_LOAD_DYLIB == _CFBundleSwapInt32Conditional(dlp->cmd, swapped)) {
+                    uint32_t nameoffset = _CFBundleSwapInt32Conditional(dlp->dylib.name.offset, swapped);
+                    const char *name = (const char *)dlp + nameoffset;
+                    if (startofcmds <= name && name + sizeof(libX11name) <= endofcmds && 0 == strncmp(name, libX11name, sizeof(libX11name) - 1)) result = true;
+                }
+                dlp = (struct dylib_command *)((char *)dlp + _CFBundleSwapInt32Conditional(dlp->cmdsize, swapped));
+            }
+        }
+    }
+    
+    if (buffer) free(buffer);
+    
+    return result;
+}
+    
+static CFDictionaryRef _CFBundleGrokInfoDictFromFile(int fd, const void *bytes, CFIndex length, uint32_t offset, Boolean swapped, Boolean sixtyFour) {
+    struct stat statBuf;
+    off_t fileLength = 0;
+    char *maploc = NULL;
+    const char *loc;
+    unsigned i, j;
+    CFDictionaryRef result = NULL;
+    Boolean foundit = false;
+    if (fd >= 0 && fstat(fd, &statBuf) == 0 && (maploc = (char*)mmap(0, statBuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0)) != (void *)-1) {
+        loc = maploc;
+        fileLength = statBuf.st_size;
+    } else {
+        loc = (const char*)bytes;
+        fileLength = length;
+    }
+    if (fileLength > offset + sizeof(struct mach_header_64)) {
+        if (sixtyFour) {
+            uint32_t ncmds = _CFBundleSwapInt32Conditional(((struct mach_header_64 *)(loc + offset))->ncmds, swapped);
+            uint32_t sizeofcmds = _CFBundleSwapInt32Conditional(((struct mach_header_64 *)(loc + offset))->sizeofcmds, swapped);
+            const char *startofcmds = loc + offset + sizeof(struct mach_header_64);
+            const char *endofcmds = startofcmds + sizeofcmds;
+            struct segment_command_64 *sgp = (struct segment_command_64 *)startofcmds;
+            if (endofcmds > loc + fileLength) endofcmds = loc + fileLength;
+            for (i = 0; !foundit && i < ncmds && startofcmds <= (char *)sgp && (char *)sgp < endofcmds; i++) {
+                if (LC_SEGMENT_64 == _CFBundleSwapInt32Conditional(sgp->cmd, swapped)) {
+                    struct section_64 *sp = (struct section_64 *)((char *)sgp + sizeof(struct segment_command_64));
+                    uint32_t nsects = _CFBundleSwapInt32Conditional(sgp->nsects, swapped);
+                    for (j = 0; !foundit && j < nsects && startofcmds <= (char *)sp && (char *)sp < endofcmds; j++) {
+                        if (0 == strncmp(sp->sectname, PLIST_SECTION, sizeof(sp->sectname)) && 0 == strncmp(sp->segname, TEXT_SEGMENT, sizeof(sp->segname))) {
+                            uint64_t sectlength64 = _CFBundleSwapInt64Conditional(sp->size, swapped);
+                            uint32_t sectlength = (uint32_t)(sectlength64 & 0xffffffff);
+                            uint32_t sectoffset = _CFBundleSwapInt32Conditional(sp->offset, swapped);
+                            const char *sectbytes = loc + offset + sectoffset;
+                            // we don't support huge-sized plists
+                            if (sectlength64 <= 0xffffffff && loc <= sectbytes && sectbytes + sectlength <= loc + fileLength) result = _CFBundleGrokInfoDictFromData(sectbytes, sectlength);
+                            foundit = true;
+                        }
+                        sp = (struct section_64 *)((char *)sp + sizeof(struct section_64));
+                    }
+                }
+                sgp = (struct segment_command_64 *)((char *)sgp + _CFBundleSwapInt32Conditional(sgp->cmdsize, swapped));
+            }
+        } else {
+            uint32_t ncmds = _CFBundleSwapInt32Conditional(((struct mach_header *)(loc + offset))->ncmds, swapped);
+            uint32_t sizeofcmds = _CFBundleSwapInt32Conditional(((struct mach_header *)(loc + offset))->sizeofcmds, swapped);
+            const char *startofcmds = loc + offset + sizeof(struct mach_header);
+            const char *endofcmds = startofcmds + sizeofcmds;
+            struct segment_command *sgp = (struct segment_command *)startofcmds;
+            if (endofcmds > loc + fileLength) endofcmds = loc + fileLength;
+            for (i = 0; !foundit && i < ncmds && startofcmds <= (char *)sgp && (char *)sgp < endofcmds; i++) {
+                if (LC_SEGMENT == _CFBundleSwapInt32Conditional(sgp->cmd, swapped)) {
+                    struct section *sp = (struct section *)((char *)sgp + sizeof(struct segment_command));
+                    uint32_t nsects = _CFBundleSwapInt32Conditional(sgp->nsects, swapped);
+                    for (j = 0; !foundit && j < nsects && startofcmds <= (char *)sp && (char *)sp < endofcmds; j++) {
+                        if (0 == strncmp(sp->sectname, PLIST_SECTION, sizeof(sp->sectname)) && 0 == strncmp(sp->segname, TEXT_SEGMENT, sizeof(sp->segname))) {
+                            uint32_t sectlength = _CFBundleSwapInt32Conditional(sp->size, swapped);
+                            uint32_t sectoffset = _CFBundleSwapInt32Conditional(sp->offset, swapped);
+                            const char *sectbytes = loc + offset + sectoffset;
+                            if (loc <= sectbytes && sectbytes + sectlength <= loc + fileLength) result = _CFBundleGrokInfoDictFromData(sectbytes, sectlength);
+                            foundit = true;
+                        }
+                        sp = (struct section *)((char *)sp + sizeof(struct section));
+                    }
+                }
+                sgp = (struct segment_command *)((char *)sgp + _CFBundleSwapInt32Conditional(sgp->cmdsize, swapped));
+            }
+        }
+    }
+    if (maploc) munmap(maploc, statBuf.st_size);
+    return result;
+}
+
+static void _CFBundleGrokObjcImageInfoFromFile(int fd, const void *bytes, CFIndex length, uint32_t offset, Boolean swapped, Boolean sixtyFour, Boolean *hasObjc, uint32_t *objcVersion, uint32_t *objcFlags) {
+    uint32_t sectlength = 0, sectoffset = 0, localVersion = 0, localFlags = 0;
+    char *buffer = NULL;
+    char sectbuffer[8];
+    const char *loc = NULL;
+    unsigned i, j;
+    Boolean foundit = false, localHasObjc = false;
+    
+    if (fd >= 0 && lseek(fd, offset, SEEK_SET) == (off_t)offset) {
+        buffer = (char*)malloc(IMAGE_INFO_BYTES_TO_READ);
+        if (buffer && read(fd, buffer, IMAGE_INFO_BYTES_TO_READ) >= IMAGE_INFO_BYTES_TO_READ) loc = buffer;
+    } else if (bytes && length >= offset + IMAGE_INFO_BYTES_TO_READ) {
+        loc = (const char*)bytes + offset;
+    }
+    if (loc) {
+        if (sixtyFour) {
+            uint32_t ncmds = _CFBundleSwapInt32Conditional(((struct mach_header_64 *)loc)->ncmds, swapped);
+            uint32_t sizeofcmds = _CFBundleSwapInt32Conditional(((struct mach_header_64 *)loc)->sizeofcmds, swapped);
+            const char *startofcmds = loc + sizeof(struct mach_header_64);
+            const char *endofcmds = startofcmds + sizeofcmds;
+            struct segment_command_64 *sgp = (struct segment_command_64 *)startofcmds;
+            if (endofcmds > loc + IMAGE_INFO_BYTES_TO_READ) endofcmds = loc + IMAGE_INFO_BYTES_TO_READ;
+            for (i = 0; !foundit && i < ncmds && startofcmds <= (char *)sgp && (char *)sgp < endofcmds; i++) {
+                if (LC_SEGMENT_64 == _CFBundleSwapInt32Conditional(sgp->cmd, swapped)) {
+                    struct section_64 *sp = (struct section_64 *)((char *)sgp + sizeof(struct segment_command_64));
+                    uint32_t nsects = _CFBundleSwapInt32Conditional(sgp->nsects, swapped);
+                    for (j = 0; !foundit && j < nsects && startofcmds <= (char *)sp && (char *)sp < endofcmds; j++) {
+                        if (0 == strncmp(sp->segname, OBJC_SEGMENT, sizeof(sp->segname))) localHasObjc = true;
+                        if (0 == strncmp(sp->sectname, IMAGE_INFO_SECTION, sizeof(sp->sectname)) && 0 == strncmp(sp->segname, OBJC_SEGMENT, sizeof(sp->segname))) {
+                            uint64_t sectlength64 = _CFBundleSwapInt64Conditional(sp->size, swapped);
+                            sectlength = (uint32_t)(sectlength64 & 0xffffffff);
+                            sectoffset = _CFBundleSwapInt32Conditional(sp->offset, swapped);
+                            foundit = true;
+                        }
+                        sp = (struct section_64 *)((char *)sp + sizeof(struct section_64));
+                    }
+                }
+                sgp = (struct segment_command_64 *)((char *)sgp + _CFBundleSwapInt32Conditional(sgp->cmdsize, swapped));
+            }
+        } else {
+            uint32_t ncmds = _CFBundleSwapInt32Conditional(((struct mach_header *)loc)->ncmds, swapped);
+            uint32_t sizeofcmds = _CFBundleSwapInt32Conditional(((struct mach_header *)loc)->sizeofcmds, swapped);
+            const char *startofcmds = loc + sizeof(struct mach_header);
+            const char *endofcmds = startofcmds + sizeofcmds;
+            struct segment_command *sgp = (struct segment_command *)startofcmds;
+            if (endofcmds > loc + IMAGE_INFO_BYTES_TO_READ) endofcmds = loc + IMAGE_INFO_BYTES_TO_READ;
+            for (i = 0; !foundit && i < ncmds && startofcmds <= (char *)sgp && (char *)sgp < endofcmds; i++) {
+                if (LC_SEGMENT == _CFBundleSwapInt32Conditional(sgp->cmd, swapped)) {
+                    struct section *sp = (struct section *)((char *)sgp + sizeof(struct segment_command));
+                    uint32_t nsects = _CFBundleSwapInt32Conditional(sgp->nsects, swapped);
+                    for (j = 0; !foundit && j < nsects && startofcmds <= (char *)sp && (char *)sp < endofcmds; j++) {
+                        if (0 == strncmp(sp->segname, OBJC_SEGMENT, sizeof(sp->segname))) localHasObjc = true;
+                        if (0 == strncmp(sp->sectname, IMAGE_INFO_SECTION, sizeof(sp->sectname)) && 0 == strncmp(sp->segname, OBJC_SEGMENT, sizeof(sp->segname))) {
+                            sectlength = _CFBundleSwapInt32Conditional(sp->size, swapped);
+                            sectoffset = _CFBundleSwapInt32Conditional(sp->offset, swapped);
+                            foundit = true;
+                        }
+                        sp = (struct section *)((char *)sp + sizeof(struct section));
+                    }
+                }
+                sgp = (struct segment_command *)((char *)sgp + _CFBundleSwapInt32Conditional(sgp->cmdsize, swapped));
+            }
+        }
+        if (sectlength >= 8) {
+            if (fd >= 0 && lseek(fd, offset + sectoffset, SEEK_SET) == (off_t)(offset + sectoffset) && read(fd, sectbuffer, 8) >= 8) {
+                localVersion = _CFBundleSwapInt32Conditional(*(uint32_t *)sectbuffer, swapped);
+                localFlags = _CFBundleSwapInt32Conditional(*(uint32_t *)(sectbuffer + 4), swapped);
+            } else if (bytes && length >= offset + sectoffset + 8) {
+                localVersion = _CFBundleSwapInt32Conditional(*(uint32_t *)((uint32_t*)bytes + offset + sectoffset), swapped);
+                localFlags = _CFBundleSwapInt32Conditional(*(uint32_t *)((uint32_t*)bytes + offset + sectoffset + 4), swapped);
+            }
+        }
+    }
+    
+    if (buffer) free(buffer);
+    
+    if (hasObjc) *hasObjc = localHasObjc;
+    if (objcVersion) *objcVersion = localVersion;
+    if (objcFlags) *objcFlags = localFlags;
+}
+    
+static UInt32 _CFBundleGrokMachTypeForFatFile(int fd, const void *bytes, CFIndex length, Boolean *isX11, CFArrayRef *architectures, CFDictionaryRef *infodict, Boolean *hasObjc, uint32_t *objcVersion, uint32_t *objcFlags) {
+    UInt32 machtype = UNKNOWN_FILETYPE, magic, numFatHeaders = ((struct fat_header *)bytes)->nfat_arch, maxFatHeaders = (length - sizeof(struct fat_header)) / sizeof(struct fat_arch), i;
+    unsigned char buffer[sizeof(struct mach_header_64)];
+    const unsigned char *moreBytes = NULL;
+    const NXArchInfo *archInfo = NXGetLocalArchInfo();
+    struct fat_arch *fat = NULL;
+
+    if (isX11) *isX11 = false;
+    if (architectures) *architectures = NULL;
+    if (infodict) *infodict = NULL;
+    if (hasObjc) *hasObjc = false;
+    if (objcVersion) *objcVersion = 0;
+    if (objcFlags) *objcFlags = 0;
+    if (numFatHeaders > maxFatHeaders) numFatHeaders = maxFatHeaders;
+    if (numFatHeaders > 0) {
+        fat = NXFindBestFatArch(archInfo->cputype, archInfo->cpusubtype, (struct fat_arch *)((struct fat_arch*)bytes + sizeof(struct fat_header)), numFatHeaders);
+        if (!fat) fat = (struct fat_arch *)((struct fat_arch *)bytes + sizeof(struct fat_header));
+        if (architectures) {
+            CFMutableArrayRef mutableArchitectures = CFArrayCreateMutable(kCFAllocatorSystemDefault, 0, &kCFTypeArrayCallBacks);
+            for (i = 0; i < numFatHeaders; i++) {
+                CFNumberRef architecture = CFNumberCreate(kCFAllocatorSystemDefault, kCFNumberSInt32Type, (struct fat_header *)bytes + sizeof(struct fat_header) + i * sizeof(struct fat_arch));
+                if (CFArrayGetFirstIndexOfValue(mutableArchitectures, CFRangeMake(0, CFArrayGetCount(mutableArchitectures)), architecture) < 0) CFArrayAppendValue(mutableArchitectures, architecture);
+                CFRelease(architecture);
+            }
+            *architectures = (CFArrayRef)mutableArchitectures;
+        }
+    } 
+    if (fat) {
+        if (fd >= 0 && lseek(fd, fat->offset, SEEK_SET) == (off_t)fat->offset && read(fd, buffer, sizeof(struct mach_header_64)) >= (int)sizeof(struct mach_header_64)) {
+            moreBytes = buffer;
+        } else if (bytes && (uint32_t)length >= fat->offset + sizeof(struct mach_header_64)) {
+            moreBytes = (const unsigned char *)bytes + fat->offset;
+        }
+        if (moreBytes) {
+            magic = *((UInt32 *)moreBytes);
+            if (MH_MAGIC == magic) {
+                machtype = ((struct mach_header *)moreBytes)->filetype;
+                if (isX11 && MH_EXECUTE == machtype) *isX11 = _CFBundleGrokX11FromFile(fd, bytes, length, fat->offset, false, false);
+                if (infodict) *infodict = _CFBundleGrokInfoDictFromFile(fd, bytes, length, fat->offset, false, false);
+                if (hasObjc || objcVersion || objcFlags) _CFBundleGrokObjcImageInfoFromFile(fd, bytes, length, fat->offset, false, false, hasObjc, objcVersion, objcFlags);
+            } else if (MH_CIGAM == magic) {
+                machtype = CFSwapInt32(((struct mach_header *)moreBytes)->filetype);
+                if (isX11 && MH_EXECUTE == machtype) *isX11 = _CFBundleGrokX11FromFile(fd, bytes, length, fat->offset, true, false);
+                if (infodict) *infodict = _CFBundleGrokInfoDictFromFile(fd, bytes, length, fat->offset, true, false);
+                if (hasObjc || objcVersion || objcFlags) _CFBundleGrokObjcImageInfoFromFile(fd, bytes, length, fat->offset, true, false, hasObjc, objcVersion, objcFlags);
+            } else if (MH_MAGIC_64 == magic) {
+                machtype = ((struct mach_header_64 *)moreBytes)->filetype;
+                if (isX11 && MH_EXECUTE == machtype) *isX11 = _CFBundleGrokX11FromFile(fd, bytes, length, fat->offset, false, true);
+                if (infodict) *infodict = _CFBundleGrokInfoDictFromFile(fd, bytes, length, fat->offset, false, true);
+                if (hasObjc || objcVersion || objcFlags) _CFBundleGrokObjcImageInfoFromFile(fd, bytes, length, fat->offset, false, true, hasObjc, objcVersion, objcFlags);
+            } else if (MH_CIGAM_64 == magic) {
+                machtype = CFSwapInt32(((struct mach_header_64 *)moreBytes)->filetype);
+                if (isX11 && MH_EXECUTE == machtype) *isX11 = _CFBundleGrokX11FromFile(fd, bytes, length, fat->offset, true, true);
+                if (infodict) *infodict = _CFBundleGrokInfoDictFromFile(fd, bytes, length, fat->offset, true, true);
+                if (hasObjc || objcVersion || objcFlags) _CFBundleGrokObjcImageInfoFromFile(fd, bytes, length, fat->offset, true, true, hasObjc, objcVersion, objcFlags);
+            }
+        }
+    }
+    return machtype;
+}
+
+static UInt32 _CFBundleGrokMachType(int fd, const void *bytes, CFIndex length, Boolean *isX11, CFArrayRef *architectures, CFDictionaryRef *infodict, Boolean *hasObjc, uint32_t *objcVersion, uint32_t *objcFlags) {
+    unsigned int magic = *((UInt32 *)bytes), machtype = UNKNOWN_FILETYPE;
+    CFNumberRef architecture = NULL;
+    CFIndex i;
+
+    if (isX11) *isX11 = false;
+    if (architectures) *architectures = NULL;
+    if (infodict) *infodict = NULL;
+    if (hasObjc) *hasObjc = false;
+    if (objcVersion) *objcVersion = 0;
+    if (objcFlags) *objcFlags = 0;
+    if (MH_MAGIC == magic) {
+        machtype = ((struct mach_header *)bytes)->filetype;
+        if (isX11 && MH_EXECUTE == machtype) *isX11 = _CFBundleGrokX11FromFile(fd, bytes, length, 0, false, false);
+        if (architectures) architecture = CFNumberCreate(kCFAllocatorSystemDefault, kCFNumberSInt32Type, (char*)bytes + 4);
+        if (infodict) *infodict = _CFBundleGrokInfoDictFromFile(fd, bytes, length, 0, false, false);
+        if (hasObjc || objcVersion || objcFlags) _CFBundleGrokObjcImageInfoFromFile(fd, bytes, length, 0, false, false, hasObjc, objcVersion, objcFlags);
+    } else if (MH_CIGAM == magic) {
+        for (i = 0; i < length; i += 4) *(UInt32 *)((char*)bytes + i) = CFSwapInt32(*(UInt32 *)((char*)bytes + i));
+        machtype = ((struct mach_header *)bytes)->filetype;
+        if (isX11 && MH_EXECUTE == machtype) *isX11 = _CFBundleGrokX11FromFile(fd, bytes, length, 0, true, false);
+        if (architectures) architecture = CFNumberCreate(kCFAllocatorSystemDefault, kCFNumberSInt32Type, (char*)bytes + 4);
+        if (infodict) *infodict = _CFBundleGrokInfoDictFromFile(fd, bytes, length, 0, true, false);
+        if (hasObjc || objcVersion || objcFlags) _CFBundleGrokObjcImageInfoFromFile(fd, bytes, length, 0, true, false, hasObjc, objcVersion, objcFlags);
+    } else if (MH_MAGIC_64 == magic) {
+        machtype = ((struct mach_header_64 *)bytes)->filetype;
+        if (isX11 && MH_EXECUTE == machtype) *isX11 = _CFBundleGrokX11FromFile(fd, bytes, length, 0, false, true);
+        if (architectures) architecture = CFNumberCreate(kCFAllocatorSystemDefault, kCFNumberSInt32Type, (char*)bytes + 4);
+        if (infodict) *infodict = _CFBundleGrokInfoDictFromFile(fd, bytes, length, 0, false, true);
+        if (hasObjc || objcVersion || objcFlags) _CFBundleGrokObjcImageInfoFromFile(fd, bytes, length, 0, false, true, hasObjc, objcVersion, objcFlags);
+    } else if (MH_CIGAM_64 == magic) {
+        for (i = 0; i < length; i += 4) *(UInt32 *)((char*)bytes + i) = CFSwapInt32(*(UInt32 *)((char*)bytes + i));
+        machtype = ((struct mach_header_64 *)bytes)->filetype;
+        if (isX11 && MH_EXECUTE == machtype) *isX11 = _CFBundleGrokX11FromFile(fd, bytes, length, 0, true, true);
+        if (architectures) architecture = CFNumberCreate(kCFAllocatorSystemDefault, kCFNumberSInt32Type, (char*)bytes + 4);
+        if (infodict) *infodict = _CFBundleGrokInfoDictFromFile(fd, bytes, length, 0, true, true);
+        if (hasObjc || objcVersion || objcFlags) _CFBundleGrokObjcImageInfoFromFile(fd, bytes, length, 0, true, true, hasObjc, objcVersion, objcFlags);
+    } else if (FAT_MAGIC == magic) {
+        machtype = _CFBundleGrokMachTypeForFatFile(fd, bytes, length, isX11, architectures, infodict, hasObjc, objcVersion, objcFlags);
+    } else if (FAT_CIGAM == magic) {
+        for (i = 0; i < length; i += 4) *(UInt32 *)((char*)bytes + i) = CFSwapInt32(*(UInt32 *)((char*)bytes + i));
+        machtype = _CFBundleGrokMachTypeForFatFile(fd, bytes, length, isX11, architectures, infodict, hasObjc, objcVersion, objcFlags);
+    } else if (PEF_MAGIC == magic || PEF_CIGAM == magic) {
+        machtype = PEF_FILETYPE;
+    }
+    if (architectures && architecture) *architectures = CFArrayCreate(kCFAllocatorSystemDefault, (const void **)&architecture, 1, &kCFTypeArrayCallBacks);
+    if (architecture) CFRelease(architecture);
+    return machtype;
+}
+
+#endif /* BINARY_SUPPORT_DYLD */
+
+static Boolean _CFBundleGrokFileTypeForZipMimeType(const unsigned char *bytes, CFIndex length, const char **ext) {
+    unsigned namelength = CFSwapInt16HostToLittle(*((UInt16 *)(bytes + 26))), extralength = CFSwapInt16HostToLittle(*((UInt16 *)(bytes + 28)));
+    const unsigned char *data = bytes + 30 + namelength + extralength;
+    int i = -1;
+    if (bytes < data && data + 56 <= bytes + length && 0 == CFSwapInt16HostToLittle(*((UInt16 *)(bytes + 8))) && (0 == ustrncasecmp(data, "application/vnd.", 16) || 0 == ustrncasecmp(data, "application/x-vnd.", 18))) {
+        data += ('.' == *(data + 15)) ? 16 : 18;
+        if (0 == ustrncasecmp(data, "sun.xml.", 8)) {
+            data += 8;
+            if (0 == ustrncasecmp(data, "calc", 4)) i = 0;
+            else if (0 == ustrncasecmp(data, "draw", 4)) i = 1;
+            else if (0 == ustrncasecmp(data, "writer.global", 13)) i = 2;
+            else if (0 == ustrncasecmp(data, "impress", 7)) i = 3;
+            else if (0 == ustrncasecmp(data, "math", 4)) i = 4;
+            else if (0 == ustrncasecmp(data, "writer", 6)) i = 5;
+            if (i >= 0 && ext) *ext = __CFBundleOOExtensionsArray + i * EXTENSION_LENGTH;
+        } else if (0 == ustrncasecmp(data, "oasis.opendocument.", 19)) {
+            data += 19;
+            if (0 == ustrncasecmp(data, "chart", 5)) i = 0;
+            else if (0 == ustrncasecmp(data, "formula", 7)) i = 1;
+            else if (0 == ustrncasecmp(data, "graphics", 8)) i = 2;
+            else if (0 == ustrncasecmp(data, "text-web", 8)) i = 3;
+            else if (0 == ustrncasecmp(data, "image", 5)) i = 4;
+            else if (0 == ustrncasecmp(data, "text-master", 11)) i = 5;
+            else if (0 == ustrncasecmp(data, "presentation", 12)) i = 6;
+            else if (0 == ustrncasecmp(data, "spreadsheet", 11)) i = 7;
+            else if (0 == ustrncasecmp(data, "text", 4)) i = 8;
+            if (i >= 0 && ext) *ext = __CFBundleODExtensionsArray + i * EXTENSION_LENGTH;
+        }
+    } else if (bytes < data && data + 41 <= bytes + length && 8 == CFSwapInt16HostToLittle(*((UInt16 *)(bytes + 8))) && 0x4b2c28c8 == CFSwapInt32HostToBig(*((UInt32 *)data)) && 0xc94c4e2c == CFSwapInt32HostToBig(*((UInt32 *)(data + 4)))) {
+        // AbiWord compressed mimetype odt
+        if (ext) *ext = "odt";
+    }
+    return (i >= 0);
+}
+
+static const char *_CFBundleGrokFileTypeForZipFile(int fd, const unsigned char *bytes, CFIndex length, off_t fileLength) {
+    const char *ext = "zip";
+    const unsigned char *moreBytes = NULL;
+    unsigned char *buffer = NULL;
+    CFIndex i;
+    Boolean foundMimetype = false, hasMetaInf = false, hasContentXML = false, hasManifestMF = false, hasManifestXML = false, hasRels = false, hasContentTypes = false, hasWordDocument = false, hasExcelDocument = false, hasPowerPointDocument = false, hasOPF = false, hasSMIL = false;
+
+    if (bytes) {
+        for (i = 0; !foundMimetype && i + 30 < length; i++) {
+            if (0x50 == bytes[i] && 0x4b == bytes[i + 1]) {
+                unsigned namelength = 0, offset = 0;
+                if (0x01 == bytes[i + 2] && 0x02 == bytes[i + 3]) {
+                    namelength = (unsigned)CFSwapInt16HostToLittle(*((UInt16 *)(bytes + i + 28)));
+                    offset = 46;
+                } else if (0x03 == bytes[i + 2] && 0x04 == bytes[i + 3]) {
+                    namelength = (unsigned)CFSwapInt16HostToLittle(*((UInt16 *)(bytes + i + 26)));
+                    offset = 30;
+                }
+                if (offset > 0 && (CFIndex)(i + offset + namelength) <= length) {
+                    //printf("%.*s\n", namelength, bytes + i + offset);
+                    if (8 == namelength && 30 == offset && 0 == ustrncasecmp(bytes + i + offset, "mimetype", 8)) foundMimetype = _CFBundleGrokFileTypeForZipMimeType(bytes + i, length - i, &ext);
+                    else if (9 == namelength && 0 == ustrncasecmp(bytes + i + offset, "META-INF/", 9)) hasMetaInf = true;
+                    else if (11 == namelength && 0 == ustrncasecmp(bytes + i + offset, "content.xml", 11)) hasContentXML = true;
+                    else if (11 == namelength && 0 == ustrncasecmp(bytes + i + offset, "_rels/.rels", 11)) hasRels = true;
+                    else if (19 == namelength && 0 == ustrncasecmp(bytes + i + offset, "[Content_Types].xml", 19)) hasContentTypes = true;
+                    else if (20 == namelength && 0 == ustrncasecmp(bytes + i + offset, "META-INF/MANIFEST.MF", 20)) hasManifestMF = true;
+                    else if (21 == namelength && 0 == ustrncasecmp(bytes + i + offset, "META-INF/manifest.xml", 21)) hasManifestXML = true;
+                    else if (4 < namelength && 0 == ustrncasecmp(bytes + i + offset + namelength - 4, ".opf", 4)) hasOPF = true;
+                    else if (4 < namelength && 0 == ustrncasecmp(bytes + i + offset + namelength - 4, ".sml", 4)) hasSMIL = true;
+                    else if (5 < namelength && 0 == ustrncasecmp(bytes + i + offset + namelength - 5, ".smil", 5)) hasSMIL = true;
+                    else if (9 < namelength && 0 == ustrncasecmp(bytes + i + offset, "word/", 5) && 0 == ustrncasecmp(bytes + i + offset + namelength - 4, ".xml", 4)) hasWordDocument = true;
+                    else if (10 < namelength && 0 == ustrncasecmp(bytes + i + offset, "excel/", 6) && 0 == ustrncasecmp(bytes + i + offset + namelength - 4, ".xml", 4)) hasExcelDocument = true;
+                    else if (15 < namelength && 0 == ustrncasecmp(bytes + i + offset, "powerpoint/", 11) && 0 == ustrncasecmp(bytes + i + offset + namelength - 4, ".xml", 4)) hasPowerPointDocument = true;
+                    i += offset + namelength - 1;
+                }
+            }
+        }
+    }
+    if (!foundMimetype) {
+        if (fileLength >= ZIP_BYTES_TO_READ) {
+            if (fd >= 0 && lseek(fd, fileLength - ZIP_BYTES_TO_READ, SEEK_SET) == fileLength - ZIP_BYTES_TO_READ) {
+                buffer = (unsigned char *)malloc(ZIP_BYTES_TO_READ);
+                if (buffer && read(fd, buffer, ZIP_BYTES_TO_READ) >= ZIP_BYTES_TO_READ) moreBytes = buffer;
+            } else if (bytes && length >= ZIP_BYTES_TO_READ) {
+                moreBytes = bytes + length - ZIP_BYTES_TO_READ;
+            }
+        }
+        if (moreBytes) {
+            for (i = 0; i + 30 < ZIP_BYTES_TO_READ; i++) {
+                if (0x50 == moreBytes[i] && 0x4b == moreBytes[i + 1]) {
+                    unsigned namelength = 0, offset = 0;
+                    if (0x01 == moreBytes[i + 2] && 0x02 == moreBytes[i + 3]) {
+                        namelength = CFSwapInt16HostToLittle(*((UInt16 *)(moreBytes + i + 28)));
+                        offset = 46;
+                    } else if (0x03 == moreBytes[i + 2] && 0x04 == moreBytes[i + 3]) {
+                        namelength = CFSwapInt16HostToLittle(*((UInt16 *)(moreBytes + i + 26)));
+                        offset = 30;
+                    }
+                    if (offset > 0 && i + offset + namelength <= ZIP_BYTES_TO_READ) {
+                        //printf("%.*s\n", namelength, moreBytes + i + offset);
+                        if (9 == namelength && 0 == ustrncasecmp(moreBytes + i + offset, "META-INF/", 9)) hasMetaInf = true;
+                        else if (11 == namelength && 0 == ustrncasecmp(moreBytes + i + offset, "content.xml", 11)) hasContentXML = true;
+                        else if (11 == namelength && 0 == ustrncasecmp(moreBytes + i + offset, "_rels/.rels", 11)) hasRels = true;
+                        else if (19 == namelength && 0 == ustrncasecmp(moreBytes + i + offset, "[Content_Types].xml", 19)) hasContentTypes = true;
+                        else if (20 == namelength && 0 == ustrncasecmp(moreBytes + i + offset, "META-INF/MANIFEST.MF", 20)) hasManifestMF = true;
+                        else if (21 == namelength && 0 == ustrncasecmp(moreBytes + i + offset, "META-INF/manifest.xml", 21)) hasManifestXML = true;
+                        else if (4 < namelength && 0 == ustrncasecmp(moreBytes + i + offset + namelength - 4, ".opf", 4)) hasOPF = true;
+                        else if (4 < namelength && 0 == ustrncasecmp(moreBytes + i + offset + namelength - 4, ".sml", 4)) hasSMIL = true;
+                        else if (5 < namelength && 0 == ustrncasecmp(moreBytes + i + offset + namelength - 5, ".smil", 5)) hasSMIL = true;
+                        else if (9 < namelength && 0 == ustrncasecmp(moreBytes + i + offset, "word/", 5) && 0 == ustrncasecmp(moreBytes + i + offset + namelength - 4, ".xml", 4)) hasWordDocument = true;
+                        else if (10 < namelength && 0 == ustrncasecmp(moreBytes + i + offset, "excel/", 6) && 0 == ustrncasecmp(moreBytes + i + offset + namelength - 4, ".xml", 4)) hasExcelDocument = true;
+                        else if (15 < namelength && 0 == ustrncasecmp(moreBytes + i + offset, "powerpoint/", 11) && 0 == ustrncasecmp(moreBytes + i + offset + namelength - 4, ".xml", 4)) hasPowerPointDocument = true;
+                        i += offset + namelength - 1;
+                    }
+                }
+            }
+        }
+        //printf("hasManifestMF %d hasManifestXML %d hasContentXML %d hasRels %d hasContentTypes %d hasWordDocument %d hasExcelDocument %d hasPowerPointDocument %d hasMetaInf %d hasOPF %d hasSMIL %d\n", hasManifestMF, hasManifestXML, hasContentXML, hasRels, hasContentTypes, hasWordDocument, hasExcelDocument, hasPowerPointDocument, hasMetaInf, hasOPF, hasSMIL);
+        if (hasManifestMF) ext = "jar";
+        else if ((hasRels || hasContentTypes) && hasWordDocument) ext = "docx";
+        else if ((hasRels || hasContentTypes) && hasExcelDocument) ext = "xlsx";
+        else if ((hasRels || hasContentTypes) && hasPowerPointDocument) ext = "pptx";
+        else if (hasManifestXML || hasContentXML) ext = "odt";
+        else if (hasMetaInf) ext = "jar";
+        else if (hasOPF && hasSMIL) ext = "dtb";
+        else if (hasOPF) ext = "oeb";
+
+        if (buffer) free(buffer);
+    }
+    return ext;
+}
+
+static Boolean _CFBundleCheckOLEName(const char *name, const char *bytes, unsigned length) {
+    Boolean retval = true;
+    unsigned j;
+    for (j = 0; retval && j < length; j++) if (bytes[2 * j] != name[j]) retval = false;
+    return retval;
+}
+
+static const char *_CFBundleGrokFileTypeForOLEFile(int fd, const void *bytes, CFIndex length, off_t offset) {
+    const char *ext = "ole", *moreBytes = NULL;
+    char *buffer = NULL;
+    
+    if (fd >= 0 && lseek(fd, offset, SEEK_SET) == (off_t)offset) {
+        buffer = (char *)malloc(OLE_BYTES_TO_READ);
+        if (buffer && read(fd, buffer, OLE_BYTES_TO_READ) >= OLE_BYTES_TO_READ) moreBytes = buffer;
+    } else if (bytes && length >= offset + OLE_BYTES_TO_READ) {
+        moreBytes = (char *)bytes + offset;
+    }
+    if (moreBytes) {
+        Boolean foundit = false;
+        unsigned i;
+        for (i = 0; !foundit && i < 4; i++) {
+            char namelength = moreBytes[128 * i + 64] / 2;
+            foundit = true;
+            if (sizeof(XLS_NAME) == namelength && _CFBundleCheckOLEName(XLS_NAME, moreBytes + 128 * i, namelength - 1)) ext = "xls";
+            else if (sizeof(XLS_NAME2) == namelength && _CFBundleCheckOLEName(XLS_NAME2, moreBytes + 128 * i, namelength - 1)) ext = "xls";
+            else if (sizeof(DOC_NAME) == namelength && _CFBundleCheckOLEName(DOC_NAME, moreBytes + 128 * i, namelength - 1)) ext = "doc";
+            else if (sizeof(PPT_NAME) == namelength && _CFBundleCheckOLEName(PPT_NAME, moreBytes + 128 * i, namelength - 1)) ext = "ppt";
+            else foundit = false;
+        }
+    }
+
+    if (buffer) free(buffer);
+
+    return ext;
+}
+
+static Boolean _CFBundleGrokFileType(CFURLRef url, CFDataRef data, CFStringRef *extension, UInt32 *machtype, CFArrayRef *architectures, CFDictionaryRef *infodict, Boolean *hasObjc, uint32_t *objcVersion, uint32_t *objcFlags) {
+    struct stat statBuf;
+    int fd = -1;
+    char path[CFMaxPathSize];
+    const unsigned char *bytes = NULL;
+    unsigned char buffer[MAGIC_BYTES_TO_READ];
+    CFIndex i, length = 0;
+    off_t fileLength = 0;
+    const char *ext = NULL;
+    UInt32 mt = UNKNOWN_FILETYPE;
+#if defined(BINARY_SUPPORT_DYLD)
+    Boolean isX11 = false;
+#endif /* BINARY_SUPPORT_DYLD */
+    Boolean isFile = false, isPlain = true, isZero = true, isHTML = false;
+    // extensions returned:  o, tool, x11app, pef, core, dylib, bundle, elf, jpeg, jp2, tiff, gif, png, pict, icns, ico, rtf, rtfd, pdf, ra, rm, au, aiff, aifc, wav, avi, wmv, ogg, flac, psd, mpeg, mid, zip, jar, sit, cpio, html, ps, mov, qtif, ttf, otf, sfont, bmp, hqx, bin, class, tar, txt, gz, Z, uu, ync, bz, bz2, sh, pl, py, rb, dvi, sgi, tga, mp3, xml, plist, xls, doc, ppt, mp4, m4a, m4b, m4p, dmg, cwk, webarchive, dwg, dgn, pfa, pfb, afm, tfm, xcf, cpx, dwf, swf, swc, abw, bom, lit, svg, rdf, x3d, oeb, dtb, docx, xlsx, pptx, sxc, sxd, sxg, sxi, sxm, sxw, odc, odf, odg, oth, odi, odm, odp, ods
+    // ??? we do not distinguish between different wm types, returning wmv for any of wmv, wma, or asf
+    // ??? we do not distinguish between ordinary documents and template versions (often there is no difference in file contents)
+    // ??? the distinctions between docx, xlsx, and pptx may not be entirely reliable
+    if (architectures) *architectures = NULL;
+    if (infodict) *infodict = NULL;
+    if (hasObjc) *hasObjc = false;
+    if (objcVersion) *objcVersion = 0;
+    if (objcFlags) *objcFlags = 0;
+    if (url && CFURLGetFileSystemRepresentation(url, true, (uint8_t *)path, CFMaxPathSize) && stat(path, &statBuf) == 0 && (statBuf.st_mode & S_IFMT) == S_IFREG && (fd = open(path, O_RDONLY, 0777)) >= 0) {
+        length = read(fd, buffer, MAGIC_BYTES_TO_READ);
+        fileLength = statBuf.st_size;
+        bytes = buffer;
+        isFile = true;
+    } else if (data) {
+        length = CFDataGetLength(data);
+        fileLength = (off_t)length;
+        bytes = CFDataGetBytePtr(data);
+        if (length == 0) ext = "txt";
+    }
+    if (bytes) {
+        if (length >= 4) {
+            UInt32 magic = CFSwapInt32HostToBig(*((UInt32 *)bytes));
+            for (i = 0; !ext && i < NUM_EXTENSIONS; i++) {
+                if (__CFBundleMagicNumbersArray[i] == magic) ext = __CFBundleExtensionsArray + i * EXTENSION_LENGTH;
+            }
+            if (ext) {
+                if (0xcafebabe == magic && 8 <= length && 0 != *((UInt16 *)(bytes + 4))) ext = "class";
+#if defined(BINARY_SUPPORT_DYLD)
+                else if ((int)sizeof(struct mach_header_64) <= length) mt = _CFBundleGrokMachType(fd, bytes, length, extension ? &isX11 : NULL, architectures, infodict, hasObjc, objcVersion, objcFlags);
+                
+                if (MH_OBJECT == mt) ext = "o";
+                else if (MH_EXECUTE == mt) ext = isX11 ? "x11app" : "tool";
+                else if (PEF_FILETYPE == mt) ext = "pef";
+                else if (MH_CORE == mt) ext = "core";
+                else if (MH_DYLIB == mt) ext = "dylib";
+                else if (MH_BUNDLE == mt) ext = "bundle";
+#endif /* BINARY_SUPPORT_DYLD */
+                else if (0x7b5c7274 == magic && (6 > length || 'f' != bytes[4])) ext = NULL;
+                else if (0x00010000 == magic && (6 > length || 0 != bytes[4])) ext = NULL;
+                else if (0x47494638 == magic && (6 > length || (0x3761 != CFSwapInt16HostToBig(*((UInt16 *)(bytes + 4))) && 0x3961 != CFSwapInt16HostToBig(*((UInt16 *)(bytes + 4))))))  ext = NULL;
+                else if (0x0000000c == magic && (6 > length || 0x6a50 != CFSwapInt16HostToBig(*((UInt16 *)(bytes + 4))))) ext = NULL;
+                else if (0x2356524d == magic && (6 > length || 0x4c20 != CFSwapInt16HostToBig(*((UInt16 *)(bytes + 4))))) ext = NULL;
+                else if (0x28445746 == magic && (6 > length || 0x2056 != CFSwapInt16HostToBig(*((UInt16 *)(bytes + 4))))) ext = NULL;
+                else if (0x30373037 == magic && (6 > length || 0x30 != bytes[4] || !isdigit(bytes[5]))) ext = NULL;
+                else if (0x41433130 == magic && (6 > length || 0x31 != bytes[4] || !isdigit(bytes[5]))) ext = NULL;
+                else if (0x89504e47 == magic && (8 > length || 0x0d0a1a0a != CFSwapInt32HostToBig(*((UInt32 *)(bytes + 4))))) ext = NULL;
+                else if (0x53747566 == magic && (8 > length || 0x66497420 != CFSwapInt32HostToBig(*((UInt32 *)(bytes + 4))))) ext = NULL;
+                else if (0x3026b275 == magic && (8 > length || 0x8e66cf11 != CFSwapInt32HostToBig(*((UInt32 *)(bytes + 4))))) ext = NULL;
+                else if (0x67696d70 == magic && (8 > length || 0x20786366 != CFSwapInt32HostToBig(*((UInt32 *)(bytes + 4))))) ext = NULL;
+                else if (0x424f4d53 == magic && (8 > length || 0x746f7265 != CFSwapInt32HostToBig(*((UInt32 *)(bytes + 4))))) ext = NULL;
+                else if (0x49544f4c == magic && (8 > length || 0x49544c53 != CFSwapInt32HostToBig(*((UInt32 *)(bytes + 4))))) ext = NULL;
+                else if (0x72746664 == magic && (8 > length || 0x00000000 != CFSwapInt32HostToBig(*((UInt32 *)(bytes + 4))))) ext = NULL;
+                else if (0x3d796265 == magic && (12 > length || 0x67696e20 != CFSwapInt32HostToBig(*((UInt32 *)(bytes + 4))) || (0x6c696e65 != CFSwapInt32HostToBig(*((UInt32 *)(bytes + 8))) && 0x70617274 != CFSwapInt32HostToBig(*((UInt32 *)(bytes + 8)))))) ext = NULL;
+                else if (0x25215053 == magic && 14 <= length && 0 == ustrncmp(bytes + 4, "-AdobeFont", 10)) ext = "pfa"; 
+                else if (0x504b0304 == magic) ext = _CFBundleGrokFileTypeForZipFile(fd, bytes, length, fileLength);
+                else if (0x464f524d == magic) {
+                    // IFF
+                    ext = NULL;
+                    if (12 <= length) {
+                        UInt32 iffMagic = CFSwapInt32HostToBig(*((UInt32 *)(bytes + 8)));
+                        if (0x41494646 == iffMagic) ext = "aiff";
+                        else if (0x414946 == iffMagic) ext = "aifc";
+                    }
+                } else if (0x52494646 == magic) {
+                    // RIFF
+                    ext = NULL;
+                    if (12 <= length) {
+                        UInt32 riffMagic = CFSwapInt32HostToBig(*((UInt32 *)(bytes + 8)));
+                        if (0x57415645 == riffMagic) ext = "wav";
+                        else if (0x41564920 == riffMagic) ext = "avi";
+                    }
+                } else if (0xd0cf11e0 == magic) {
+                    // OLE
+                    if (52 <= length) ext = _CFBundleGrokFileTypeForOLEFile(fd, bytes, length, 512 * (1 + CFSwapInt32HostToLittle(*((UInt32 *)(bytes + 48)))));
+                } else if (0x62656769 == magic) {
+                    // uu
+                    ext = NULL;
+                    if (76 <= length && 'n' == bytes[4] && ' ' == bytes[5] && isdigit(bytes[6]) && isdigit(bytes[7]) && isdigit(bytes[8]) && ' ' == bytes[9]) {
+                        CFIndex endOfLine = 0;
+                        for (i = 10; 0 == endOfLine && i < length; i++) if ('\n' == bytes[i]) endOfLine = i;
+                        if (10 <= endOfLine && endOfLine + 62 < length && 'M' == bytes[endOfLine + 1] && '\n' == bytes[endOfLine + 62]) {
+                            ext = "uu";
+                            for (i = endOfLine + 1; ext && i < endOfLine + 62; i++) if (!isprint(bytes[i])) ext = NULL;
+                        }
+                    }
+                }
+            }
+            if (extension && !ext) {
+                UInt16 shortMagic = CFSwapInt16HostToBig(*((UInt16 *)bytes));
+                if (5 <= length && 0 == bytes[3] && 0 == bytes[4] && ((1 == bytes[1] && 1 == (0xf7 & bytes[2])) || (0 == bytes[1] && (2 == (0xf7 & bytes[2]) || (3 == (0xf7 & bytes[2])))))) ext = "tga";
+                else if (8 <= length && (0x6d6f6f76 == CFSwapInt32HostToBig(*((UInt32 *)(bytes + 4))) || 0x6d646174 == CFSwapInt32HostToBig(*((UInt32 *)(bytes + 4))) || 0x77696465 == CFSwapInt32HostToBig(*((UInt32 *)(bytes + 4))))) ext = "mov";
+                else if (8 <= length && (0x69647363 == CFSwapInt32HostToBig(*((UInt32 *)(bytes + 4))) || 0x69646174 == CFSwapInt32HostToBig(*((UInt32 *)(bytes + 4))))) ext = "qtif";
+                else if (8 <= length && 0x424f424f == CFSwapInt32HostToBig(*((UInt32 *)(bytes + 4)))) ext = "cwk";
+                else if (8 <= length && 0x62706c69 == magic && 0x7374 == CFSwapInt16HostToBig(*((UInt16 *)(bytes + 4))) && isdigit(bytes[6]) && isdigit(bytes[7])) {
+                    for (i = 8; !ext && i < 128 && i + 16 <= length; i++) {
+                        if (0 == ustrncmp(bytes + i, "WebMainResource", 15)) ext = "webarchive";
+                    }
+                    if (!ext) ext = "plist";
+                } else if (12 <= length && 0x66747970 == CFSwapInt32HostToBig(*((UInt32 *)(bytes + 4)))) {
+                    // ??? list of ftyp values needs to be checked
+                    if (0x6d703432 == CFSwapInt32HostToBig(*((UInt32 *)(bytes + 8)))) ext = "mp4";
+                    else if (0x4d344120 == CFSwapInt32HostToBig(*((UInt32 *)(bytes + 8)))) ext = "m4a";
+                    else if (0x4d344220 == CFSwapInt32HostToBig(*((UInt32 *)(bytes + 8)))) ext = "m4b";
+                    else if (0x4d345020 == CFSwapInt32HostToBig(*((UInt32 *)(bytes + 8)))) ext = "m4p";
+                } else if (0x424d == shortMagic && 18 <= length && 40 == CFSwapInt32HostToLittle(*((UInt32 *)(bytes + 14)))) ext = "bmp";
+                else if (20 <= length && 0 == ustrncmp(bytes + 6, "%!PS-AdobeFont", 14)) ext = "pfb";
+                else if (40 <= length && 0x42696e48 == CFSwapInt32HostToBig(*((UInt32 *)(bytes + 34))) && 0x6578 == CFSwapInt16HostToBig(*((UInt16 *)(bytes + 38)))) ext = "hqx";
+                else if (128 <= length && 0x6d42494e == CFSwapInt32HostToBig(*((UInt32 *)(bytes + 102)))) ext = "bin";
+                else if (128 <= length && 0 == bytes[0] && 0 < bytes[1] && bytes[1] < 64 && 0 == bytes[74] && 0 == bytes[82] && 0 == (fileLength % 128)) {
+                    unsigned df = CFSwapInt32HostToBig(*((UInt32 *)(bytes + 83))), rf = CFSwapInt32HostToBig(*((UInt32 *)(bytes + 87))), blocks = 1 + (df + 127) / 128 + (rf + 127) / 128;
+                    if (df < 0x00800000 && rf < 0x00800000 && 1 < blocks && (off_t)(128 * blocks) == fileLength) ext = "bin";
+                } else if (265 <= length && 0x75737461 == CFSwapInt32HostToBig(*((UInt32 *)(bytes + 257))) && (0x72202000 == CFSwapInt32HostToBig(*((UInt32 *)(bytes + 261))) || 0x7200 == CFSwapInt16HostToBig(*((UInt16 *)(bytes + 261))))) ext = "tar";
+                else if (0xfeff == shortMagic || 0xfffe == shortMagic) ext = "txt";
+                else if (0x1f9d == shortMagic) ext = "Z";
+                else if (0x1f8b == shortMagic) ext = "gz";
+                else if (0x71c7 == shortMagic || 0xc771 == shortMagic) ext = "cpio";
+                else if (0xf702 == shortMagic) ext = "dvi";
+                else if (0x01da == shortMagic && (0 == bytes[2] || 1 == bytes[2]) && (0 < bytes[3] && 16 > bytes[3])) ext = "sgi";
+                else if (0x2321 == shortMagic) {
+                    CFIndex endOfLine = 0, lastSlash = 0;
+                    for (i = 2; 0 == endOfLine && i < length; i++) if ('\n' == bytes[i]) endOfLine = i;
+                    if (endOfLine > 3) {
+                        for (i = endOfLine - 1; 0 == lastSlash && i > 1; i--) if ('/' == bytes[i]) lastSlash = i;
+                        if (lastSlash > 0) {
+                            if (0 == ustrncmp(bytes + lastSlash + 1, "perl", 4)) ext = "pl";
+                            else if (0 == ustrncmp(bytes + lastSlash + 1, "python", 6)) ext = "py";
+                            else if (0 == ustrncmp(bytes + lastSlash + 1, "ruby", 4)) ext = "rb";
+                            else ext = "sh";
+                        }
+                    } 
+                } else if (0xffd8 == shortMagic && 0xff == bytes[2]) ext = "jpeg";
+                else if (0x4657 == shortMagic && 0x53 == bytes[2]) ext = "swf";
+                else if (0x4357 == shortMagic && 0x53 == bytes[2]) ext = "swc";
+                else if (0x4944 == shortMagic && '3' == bytes[2] && 0x20 > bytes[3]) ext = "mp3";
+                else if (0x425a == shortMagic && isdigit(bytes[2]) && isdigit(bytes[3])) ext = "bz";
+                else if (0x425a == shortMagic && 'h' == bytes[2] && isdigit(bytes[3]) && 8 <= length && (0x31415926 == CFSwapInt32HostToBig(*((UInt32 *)(bytes + 4))) || 0x17724538 == CFSwapInt32HostToBig(*((UInt32 *)(bytes + 4))))) ext = "bz2";
+                else if (0x0011 == CFSwapInt16HostToBig(*((UInt16 *)(bytes + 2))) || 0x0012 == CFSwapInt16HostToBig(*((UInt16 *)(bytes + 2)))) ext = "tfm";
+                else if ('<' == bytes[0] && 14 <= length) {
+                    if (0 == ustrncasecmp(bytes + 1, "!doctype html", 13) || 0 == ustrncasecmp(bytes + 1, "head", 4) || 0 == ustrncasecmp(bytes + 1, "title", 5) || 0 == ustrncasecmp(bytes + 1, "html", 4)) {
+                        ext = "html";
+                    } else if (0 == ustrncasecmp(bytes + 1, "?xml", 4)) {
+                        for (i = 4; !ext && i < 128 && i + 20 <= length; i++) {
+                            if ('<' == bytes[i]) {
+                                if (0 == ustrncasecmp(bytes + i + 1, "abiword", 7)) ext = "abw";
+                                else if (0 == ustrncasecmp(bytes + i + 1, "!doctype svg", 12)) ext = "svg";
+                                else if (0 == ustrncasecmp(bytes + i + 1, "!doctype rdf", 12)) ext = "rdf";
+                                else if (0 == ustrncasecmp(bytes + i + 1, "!doctype x3d", 12)) ext = "x3d";
+                                else if (0 == ustrncasecmp(bytes + i + 1, "!doctype html", 13)) ext = "html";
+                                else if (0 == ustrncasecmp(bytes + i + 1, "!doctype plist", 14)) ext = "plist";
+                                else if (0 == ustrncasecmp(bytes + i + 1, "!doctype posingfont", 19)) ext = "sfont";
+                            }
+                        }
+                        if (!ext) ext = "xml";
+                    }
+                }
+            }
+        }
+        if (extension && !ext) {
+            //??? what about MacOSRoman?
+            for (i = 0; (isPlain || isZero) && !isHTML && i < length && i < 512; i++) {
+                char c = bytes[i];
+                if (0x7f <= c || (0x20 > c && !isspace(c))) isPlain = false;
+                if (0 != c) isZero = false;
+                if (isPlain && '<' == c && i + 14 <= length && 0 == ustrncasecmp(bytes + i + 1, "!doctype html", 13)) isHTML = true;
+            }
+            if (isHTML) {
+                ext = "html";
+            } else if (isPlain) {
+                if (16 <= length && 0 == ustrncmp(bytes, "StartFontMetrics", 16)) ext = "afm";
+                else ext = "txt";
+            } else if (isZero && length >= MAGIC_BYTES_TO_READ && fileLength >= 526) {
+                if (isFile) {
+                    if (lseek(fd, 512, SEEK_SET) == 512 && read(fd, buffer, MAGIC_BYTES_TO_READ) >= 14) {
+                        if (0x001102ff == CFSwapInt32HostToBig(*((UInt32 *)(buffer + 10)))) ext = "pict";
+                    }
+                } else {
+                    if (526 <= length && 0x001102ff == CFSwapInt32HostToBig(*((UInt32 *)(bytes + 522)))) ext = "pict";
+                }
+            }
+        }
+        if (extension && (!ext || 0 == strcmp(ext, "bz2")) && length >= MAGIC_BYTES_TO_READ && fileLength >= DMG_BYTES_TO_READ) {
+            if (isFile) {
+                if (lseek(fd, fileLength - DMG_BYTES_TO_READ, SEEK_SET) == fileLength - DMG_BYTES_TO_READ && read(fd, buffer, DMG_BYTES_TO_READ) >= DMG_BYTES_TO_READ) {
+                    if (0x6b6f6c79 == CFSwapInt32HostToBig(*((UInt32 *)buffer)) || (0x63647361 == CFSwapInt32HostToBig(*((UInt32 *)(buffer + DMG_BYTES_TO_READ - 8))) && 0x656e6372 == CFSwapInt32HostToBig(*((UInt32 *)(buffer + DMG_BYTES_TO_READ - 4))))) ext = "dmg";
+                }
+            } else {
+                if (DMG_BYTES_TO_READ <= length && (0x6b6f6c79 == CFSwapInt32HostToBig(*((UInt32 *)(bytes + length - DMG_BYTES_TO_READ))) || (0x63647361 == CFSwapInt32HostToBig(*((UInt32 *)(bytes + length - 8))) && 0x656e6372 == CFSwapInt32HostToBig(*((UInt32 *)(bytes + length - 4)))))) ext = "dmg";
+            }
+        }
+    }
+    if (extension) *extension = ext ? CFStringCreateWithCStringNoCopy(kCFAllocatorSystemDefault, ext, kCFStringEncodingUTF8, kCFAllocatorNull) : NULL;
+    if (machtype) *machtype = mt;
+    if (fd >= 0) close(fd);
+    return (ext ? true : false);
+}
+
+CFStringRef _CFBundleCopyFileTypeForFileURL(CFURLRef url) {
+    CFStringRef extension = NULL;
+    (void)_CFBundleGrokFileType(url, NULL, &extension, NULL, NULL, NULL, NULL, NULL, NULL);
+    return extension;
+}
+
+CFStringRef _CFBundleCopyFileTypeForFileData(CFDataRef data) {
+    CFStringRef extension = NULL;
+    (void)_CFBundleGrokFileType(NULL, data, &extension, NULL, NULL, NULL, NULL, NULL, NULL);
+    return extension;
+}
+
+__private_extern__ CFDictionaryRef _CFBundleCopyInfoDictionaryInExecutable(CFURLRef url) {
+    CFDictionaryRef result = NULL;
+    (void)_CFBundleGrokFileType(url, NULL, NULL, NULL, NULL, &result, NULL, NULL, NULL);
+    return result;
+}
+
+__private_extern__ CFArrayRef _CFBundleCopyArchitecturesForExecutable(CFURLRef url) {
+    CFArrayRef result = NULL;
+    (void)_CFBundleGrokFileType(url, NULL, NULL, NULL, &result, NULL, NULL, NULL, NULL);
+    return result;
+}
+
+static Boolean _CFBundleGetObjCImageInfoForExecutable(CFURLRef url, uint32_t *objcVersion, uint32_t *objcFlags) {
+    Boolean retval = false;
+    (void)_CFBundleGrokFileType(url, NULL, NULL, NULL, NULL, NULL, &retval, objcVersion, objcFlags);
+    return retval;
+}
+
+#if defined(BINARY_SUPPORT_DYLD)
+
+__private_extern__ __CFPBinaryType _CFBundleGrokBinaryType(CFURLRef executableURL) {
+    // Attempt to grok the type of the binary by looking for DYLD magic numbers.  If one of the DYLD magic numbers is found, find out what type of Mach-o file it is.  Otherwise, look for the PEF magic numbers to see if it is CFM (if we understand CFM).
+    __CFPBinaryType result = executableURL ? __CFBundleUnreadableBinary : __CFBundleNoBinary;
+    UInt32 machtype = UNKNOWN_FILETYPE;
+    if (_CFBundleGrokFileType(executableURL, NULL, NULL, &machtype, NULL, NULL, NULL, NULL, NULL)) {
+        switch (machtype) {
+            case MH_EXECUTE:
+                result = __CFBundleDYLDExecutableBinary;
+                break;
+            case MH_BUNDLE:
+                result = __CFBundleDYLDBundleBinary;
+                break;
+            case MH_DYLIB:
+                result = __CFBundleDYLDFrameworkBinary;
+                break;
+#if defined(BINARY_SUPPORT_CFM)
+            case PEF_FILETYPE:
+                result = __CFBundleCFMBinary;
+                break;
+#endif /* BINARY_SUPPORT_CFM */
+        }
+    }
+    return result;
+}
+
+#endif /* BINARY_SUPPORT_DYLD */
+
+void _CFBundleSetCFMConnectionID(CFBundleRef bundle, void *connectionID) {
+#if defined(BINARY_SUPPORT_CFM)
+    if (bundle->_binaryType == __CFBundleUnknownBinary || bundle->_binaryType == __CFBundleUnreadableBinary) {
+        bundle->_binaryType = __CFBundleCFMBinary;
+    }
+#endif /* BINARY_SUPPORT_CFM */
+    bundle->_connectionCookie = connectionID;
+    bundle->_isLoaded = true;
+}
+
+static CFStringRef _CFBundleCopyLastPathComponent(CFBundleRef bundle) {
+    CFURLRef bundleURL = CFBundleCopyBundleURL(bundle);
+    CFStringRef str = CFURLCopyFileSystemPath(bundleURL, kCFURLPOSIXPathStyle);
+    UniChar buff[CFMaxPathSize];
+    CFIndex buffLen = CFStringGetLength(str), startOfLastDir = 0;
+
+    CFRelease(bundleURL);
+    if (buffLen > CFMaxPathSize) buffLen = CFMaxPathSize;
+    CFStringGetCharacters(str, CFRangeMake(0, buffLen), buff);
+    CFRelease(str);
+    if (buffLen > 0) startOfLastDir = _CFStartOfLastPathComponent(buff, buffLen);
+    return CFStringCreateWithCharacters(kCFAllocatorSystemDefault, &(buff[startOfLastDir]), buffLen - startOfLastDir);
+}
+
+static CFErrorRef _CFBundleCreateErrorDebug(CFAllocatorRef allocator, CFBundleRef bundle, CFIndex code, CFStringRef debugString) {
+    const void *userInfoKeys[6], *userInfoValues[6];
+    CFIndex numKeys = 0;
+    CFURLRef bundleURL = CFBundleCopyBundleURL(bundle), absoluteURL = CFURLCopyAbsoluteURL(bundleURL), executableURL = CFBundleCopyExecutableURL(bundle);
+    CFBundleRef bdl = CFBundleGetBundleWithIdentifier(CFSTR("com.apple.CoreFoundation"));
+    CFStringRef bundlePath = CFURLCopyFileSystemPath(absoluteURL, PLATFORM_PATH_STYLE), executablePath = executableURL ? CFURLCopyFileSystemPath(executableURL, PLATFORM_PATH_STYLE) : NULL, descFormat = NULL, desc = NULL, reason = NULL, suggestion = NULL;
+    CFErrorRef error;
+    if (bdl) {
+        CFStringRef name = (CFStringRef)CFBundleGetValueForInfoDictionaryKey(bundle, kCFBundleNameKey);
+        name = name ? (CFStringRef)CFRetain(name) : _CFBundleCopyLastPathComponent(bundle);
+        if (CFBundleExecutableNotFoundError == code) {
+            descFormat = CFCopyLocalizedStringWithDefaultValue(CFSTR("BundleErr4"), CFSTR("Error"), bdl, CFSTR("The bundle \\U201c%@\\U201d could not be loaded because its executable could not be located."), "NSFileNoSuchFileError");
+            reason = CFCopyLocalizedStringWithDefaultValue(CFSTR("BundleErr4-C"), CFSTR("Error"), bdl, CFSTR("The bundle\\U2019s executable could not be located."), "NSFileNoSuchFileError");
+            suggestion = CFCopyLocalizedStringWithDefaultValue(CFSTR("BundleErr4-R"), CFSTR("Error"), bdl, CFSTR("Try reinstalling the bundle."), "NSFileNoSuchFileError");
+        } else if (CFBundleExecutableNotLoadableError == code) {
+            descFormat = CFCopyLocalizedStringWithDefaultValue(CFSTR("BundleErr3584"), CFSTR("Error"), bdl, CFSTR("The bundle \\U201c%@\\U201d could not be loaded because its executable is not loadable."), "NSExecutableNotLoadableError");
+            reason = CFCopyLocalizedStringWithDefaultValue(CFSTR("BundleErr3584-C"), CFSTR("Error"), bdl, CFSTR("The bundle\\U2019s executable is not loadable."), "NSExecutableNotLoadableError");
+            suggestion = CFCopyLocalizedStringWithDefaultValue(CFSTR("BundleErr3584-R"), CFSTR("Error"), bdl, CFSTR("Try reinstalling the bundle."), "NSExecutableNotLoadableError");
+        } else if (CFBundleExecutableArchitectureMismatchError == code) {
+            descFormat = CFCopyLocalizedStringWithDefaultValue(CFSTR("BundleErr3585"), CFSTR("Error"), bdl, CFSTR("The bundle \\U201c%@\\U201d could not be loaded because it does not contain a version for the current architecture."), "NSExecutableArchitectureMismatchError");
+            reason = CFCopyLocalizedStringWithDefaultValue(CFSTR("BundleErr3585-C"), CFSTR("Error"), bdl, CFSTR("The bundle does not contain a version for the current architecture."), "NSExecutableArchitectureMismatchError");
+            suggestion = CFCopyLocalizedStringWithDefaultValue(CFSTR("BundleErr3585-R"), CFSTR("Error"), bdl, CFSTR("Try installing a universal version of the bundle."), "NSExecutableArchitectureMismatchError");
+        } else if (CFBundleExecutableRuntimeMismatchError == code) {
+            descFormat = CFCopyLocalizedStringWithDefaultValue(CFSTR("BundleErr3586"), CFSTR("Error"), bdl, CFSTR("The bundle \\U201c%@\\U201d could not be loaded because it is not compatible with the current application."), "NSExecutableRuntimeMismatchError");
+            reason = CFCopyLocalizedStringWithDefaultValue(CFSTR("BundleErr3586-C"), CFSTR("Error"), bdl, CFSTR("The bundle is not compatible with this application."), "NSExecutableRuntimeMismatchError");
+            suggestion = CFCopyLocalizedStringWithDefaultValue(CFSTR("BundleErr3586-R"), CFSTR("Error"), bdl, CFSTR("Try installing a newer version of the bundle."), "NSExecutableRuntimeMismatchError");
+        } else if (CFBundleExecutableLoadError == code) {
+            descFormat = CFCopyLocalizedStringWithDefaultValue(CFSTR("BundleErr3587"), CFSTR("Error"), bdl, CFSTR("The bundle \\U201c%@\\U201d could not be loaded because it is damaged or missing necessary resources."), "NSExecutableLoadError");
+            reason = CFCopyLocalizedStringWithDefaultValue(CFSTR("BundleErr3587-C"), CFSTR("Error"), bdl, CFSTR("The bundle is damaged or missing necessary resources."), "NSExecutableLoadError");
+            suggestion = CFCopyLocalizedStringWithDefaultValue(CFSTR("BundleErr3587-R"), CFSTR("Error"), bdl, CFSTR("Try reinstalling the bundle."), "NSExecutableLoadError");
+        } else if (CFBundleExecutableLinkError == code) {
+            descFormat = CFCopyLocalizedStringWithDefaultValue(CFSTR("BundleErr3588"), CFSTR("Error"), bdl, CFSTR("The bundle \\U201c%@\\U201d could not be loaded."), "NSExecutableLinkError");
+            reason = CFCopyLocalizedStringWithDefaultValue(CFSTR("BundleErr3588-C"), CFSTR("Error"), bdl, CFSTR("The bundle could not be loaded."), "NSExecutableLinkError");
+            suggestion = CFCopyLocalizedStringWithDefaultValue(CFSTR("BundleErr3588-R"), CFSTR("Error"), bdl, CFSTR("Try reinstalling the bundle."), "NSExecutableLinkError");
+        }
+        if (descFormat) {
+            desc = CFStringCreateWithFormat(allocator, NULL, descFormat, name);
+            CFRelease(descFormat);
+        }
+        CFRelease(name);
+    }
+    if (bundlePath) {
+        userInfoKeys[numKeys] = CFSTR("NSBundlePath");
+        userInfoValues[numKeys] = bundlePath;
+        numKeys++;
+    }
+    if (executablePath) {
+        userInfoKeys[numKeys] = CFSTR("NSFilePath");
+        userInfoValues[numKeys] = executablePath;
+        numKeys++;
+    }
+    if (desc) {
+        userInfoKeys[numKeys] = kCFErrorLocalizedDescriptionKey;
+        userInfoValues[numKeys] = desc;
+        numKeys++;
+    }
+    if (reason) {
+        userInfoKeys[numKeys] = kCFErrorLocalizedFailureReasonKey;
+        userInfoValues[numKeys] = reason;
+        numKeys++;
+    }
+    if (suggestion) {
+        userInfoKeys[numKeys] = kCFErrorLocalizedRecoverySuggestionKey;
+        userInfoValues[numKeys] = suggestion;
+        numKeys++;
+    }
+    if (debugString) {
+        userInfoKeys[numKeys] = CFSTR("NSDebugDescription");
+        userInfoValues[numKeys] = debugString;
+        numKeys++;
+    }
+    error = CFErrorCreateWithUserInfoKeysAndValues(allocator, kCFErrorDomainCocoa, code, userInfoKeys, userInfoValues, numKeys);
+    if (bundleURL) CFRelease(bundleURL);
+    if (absoluteURL) CFRelease(absoluteURL);
+    if (executableURL) CFRelease(executableURL);
+    if (bundlePath) CFRelease(bundlePath);
+    if (executablePath) CFRelease(executablePath);
+    if (desc) CFRelease(desc);
+    if (reason) CFRelease(reason);
+    if (suggestion) CFRelease(suggestion);
+    return error;
+}
+
+CFErrorRef _CFBundleCreateError(CFAllocatorRef allocator, CFBundleRef bundle, CFIndex code) {
+    return _CFBundleCreateErrorDebug(allocator, bundle, code, NULL);
+}
+
+Boolean _CFBundleLoadExecutableAndReturnError(CFBundleRef bundle, Boolean forceGlobal, CFErrorRef *error) {