[CalendarServer-changes] [11083] CalendarServer/branches/users/gaya/directorybacker

source_changes at macosforge.org source_changes at macosforge.org
Mon Apr 22 11:46:29 PDT 2013


Revision: 11083
          http://trac.calendarserver.org//changeset/11083
Author:   gaya at apple.com
Date:     2013-04-22 11:46:28 -0700 (Mon, 22 Apr 2013)
Log Message:
-----------
merge from trunk

Modified Paths:
--------------
    CalendarServer/branches/users/gaya/directorybacker/README
    CalendarServer/branches/users/gaya/directorybacker/bin/caldavd
    CalendarServer/branches/users/gaya/directorybacker/calendarserver/tap/caldav.py
    CalendarServer/branches/users/gaya/directorybacker/calendarserver/tap/test/test_caldav.py
    CalendarServer/branches/users/gaya/directorybacker/calendarserver/tap/test/test_util.py
    CalendarServer/branches/users/gaya/directorybacker/calendarserver/tap/util.py
    CalendarServer/branches/users/gaya/directorybacker/calendarserver/tools/calverify.py
    CalendarServer/branches/users/gaya/directorybacker/calendarserver/tools/cmdline.py
    CalendarServer/branches/users/gaya/directorybacker/calendarserver/tools/config.py
    CalendarServer/branches/users/gaya/directorybacker/calendarserver/tools/gateway.py
    CalendarServer/branches/users/gaya/directorybacker/calendarserver/tools/principals.py
    CalendarServer/branches/users/gaya/directorybacker/calendarserver/tools/purge.py
    CalendarServer/branches/users/gaya/directorybacker/calendarserver/tools/test/gateway/caldavd.plist
    CalendarServer/branches/users/gaya/directorybacker/calendarserver/tools/test/principals/caldavd.plist
    CalendarServer/branches/users/gaya/directorybacker/calendarserver/tools/test/test_calverify.py
    CalendarServer/branches/users/gaya/directorybacker/calendarserver/tools/test/test_config.py
    CalendarServer/branches/users/gaya/directorybacker/calendarserver/tools/test/test_gateway.py
    CalendarServer/branches/users/gaya/directorybacker/calendarserver/tools/test/test_principals.py
    CalendarServer/branches/users/gaya/directorybacker/calendarserver/tools/util.py
    CalendarServer/branches/users/gaya/directorybacker/calendarserver/webadmin/resource.py
    CalendarServer/branches/users/gaya/directorybacker/calendarserver/webadmin/test/test_resource.py
    CalendarServer/branches/users/gaya/directorybacker/conf/auth/augments-test.xml
    CalendarServer/branches/users/gaya/directorybacker/conf/auth/resources-test.xml
    CalendarServer/branches/users/gaya/directorybacker/conf/caldavd-apple.plist
    CalendarServer/branches/users/gaya/directorybacker/conf/caldavd-test.plist
    CalendarServer/branches/users/gaya/directorybacker/contrib/performance/loadtest/ical.py
    CalendarServer/branches/users/gaya/directorybacker/support/CalendarServer.xcodeproj/project.pbxproj
    CalendarServer/branches/users/gaya/directorybacker/support/build.sh
    CalendarServer/branches/users/gaya/directorybacker/support/submit
    CalendarServer/branches/users/gaya/directorybacker/twext/enterprise/dal/syntax.py
    CalendarServer/branches/users/gaya/directorybacker/twext/enterprise/fixtures.py
    CalendarServer/branches/users/gaya/directorybacker/twext/enterprise/queue.py
    CalendarServer/branches/users/gaya/directorybacker/twext/enterprise/test/test_adbapi2.py
    CalendarServer/branches/users/gaya/directorybacker/twext/enterprise/test/test_queue.py
    CalendarServer/branches/users/gaya/directorybacker/twext/python/sendmsg.c
    CalendarServer/branches/users/gaya/directorybacker/twisted/plugins/caldav.py
    CalendarServer/branches/users/gaya/directorybacker/twistedcaldav/cache.py
    CalendarServer/branches/users/gaya/directorybacker/twistedcaldav/directory/calendaruserproxy.py
    CalendarServer/branches/users/gaya/directorybacker/twistedcaldav/directory/directory.py
    CalendarServer/branches/users/gaya/directorybacker/twistedcaldav/directory/ldapdirectory.py
    CalendarServer/branches/users/gaya/directorybacker/twistedcaldav/directory/test/test_directory.py
    CalendarServer/branches/users/gaya/directorybacker/twistedcaldav/ical.py
    CalendarServer/branches/users/gaya/directorybacker/twistedcaldav/method/propfind.py
    CalendarServer/branches/users/gaya/directorybacker/twistedcaldav/method/put_addressbook_common.py
    CalendarServer/branches/users/gaya/directorybacker/twistedcaldav/method/put_common.py
    CalendarServer/branches/users/gaya/directorybacker/twistedcaldav/scheduling/caldav/delivery.py
    CalendarServer/branches/users/gaya/directorybacker/twistedcaldav/scheduling/caldav/resource.py
    CalendarServer/branches/users/gaya/directorybacker/twistedcaldav/scheduling/imip/inbound.py
    CalendarServer/branches/users/gaya/directorybacker/twistedcaldav/scheduling/imip/test/test_inbound.py
    CalendarServer/branches/users/gaya/directorybacker/twistedcaldav/scheduling/implicit.py
    CalendarServer/branches/users/gaya/directorybacker/twistedcaldav/stdconfig.py
    CalendarServer/branches/users/gaya/directorybacker/twistedcaldav/storebridge.py
    CalendarServer/branches/users/gaya/directorybacker/twistedcaldav/test/test_config.py
    CalendarServer/branches/users/gaya/directorybacker/twistedcaldav/test/test_icalendar.py
    CalendarServer/branches/users/gaya/directorybacker/twistedcaldav/test/test_stdconfig.py
    CalendarServer/branches/users/gaya/directorybacker/twistedcaldav/test/test_validation.py
    CalendarServer/branches/users/gaya/directorybacker/twistedcaldav/test/util.py
    CalendarServer/branches/users/gaya/directorybacker/twistedcaldav/upgrade.py
    CalendarServer/branches/users/gaya/directorybacker/twistedcaldav/util.py
    CalendarServer/branches/users/gaya/directorybacker/txdav/base/datastore/dbapiclient.py
    CalendarServer/branches/users/gaya/directorybacker/txdav/base/datastore/subpostgres.py
    CalendarServer/branches/users/gaya/directorybacker/txdav/base/datastore/test/test_subpostgres.py
    CalendarServer/branches/users/gaya/directorybacker/txdav/caldav/datastore/test/common.py
    CalendarServer/branches/users/gaya/directorybacker/txdav/caldav/datastore/test/test_file.py
    CalendarServer/branches/users/gaya/directorybacker/txdav/common/datastore/file.py
    CalendarServer/branches/users/gaya/directorybacker/txdav/common/datastore/sql.py
    CalendarServer/branches/users/gaya/directorybacker/txdav/common/datastore/sql_schema/current-oracle-dialect.sql
    CalendarServer/branches/users/gaya/directorybacker/txdav/common/datastore/sql_schema/current.sql
    CalendarServer/branches/users/gaya/directorybacker/txdav/common/datastore/sql_schema/old/oracle-dialect/v14.sql
    CalendarServer/branches/users/gaya/directorybacker/txdav/common/datastore/sql_schema/old/oracle-dialect/v15.sql
    CalendarServer/branches/users/gaya/directorybacker/txdav/common/datastore/sql_schema/upgrades/oracle-dialect/upgrade_from_13_to_14.sql
    CalendarServer/branches/users/gaya/directorybacker/txdav/common/datastore/sql_schema/upgrades/oracle-dialect/upgrade_from_16_to_17.sql
    CalendarServer/branches/users/gaya/directorybacker/txdav/common/datastore/sql_tables.py
    CalendarServer/branches/users/gaya/directorybacker/txdav/common/datastore/test/test_sql_tables.py

Added Paths:
-----------
    CalendarServer/branches/users/gaya/directorybacker/.gitignore
    CalendarServer/branches/users/gaya/directorybacker/bin/calendarserver_monitor_work
    CalendarServer/branches/users/gaya/directorybacker/calendarserver/tools/workitems.py
    CalendarServer/branches/users/gaya/directorybacker/doc/RFC/RFC6868-Parameter Value Encoding.txt
    CalendarServer/branches/users/gaya/directorybacker/support/Apple.make
    CalendarServer/branches/users/gaya/directorybacker/support/CalendarServer.xcodeproj/project.xcworkspace/
    CalendarServer/branches/users/gaya/directorybacker/support/CalendarServer.xcodeproj/project.xcworkspace/contents.xcworkspacedata
    CalendarServer/branches/users/gaya/directorybacker/support/XCode.make

Removed Paths:
-------------
    CalendarServer/branches/users/gaya/directorybacker/support/CalendarServer.tmproj
    CalendarServer/branches/users/gaya/directorybacker/support/CalendarServer.xcodeproj/project.xcworkspace/contents.xcworkspacedata
    CalendarServer/branches/users/gaya/directorybacker/support/Makefile.Apple

Property Changed:
----------------
    CalendarServer/branches/users/gaya/directorybacker/
    CalendarServer/branches/users/gaya/directorybacker/conf/auth/resources-test.xml
    CalendarServer/branches/users/gaya/directorybacker/support/CalendarServer.xcodeproj/


Property changes on: CalendarServer/branches/users/gaya/directorybacker
___________________________________________________________________
Modified: svn:mergeinfo
   - /CalendarServer/branches/config-separation:4379-4443
/CalendarServer/branches/egg-info-351:4589-4625
/CalendarServer/branches/generic-sqlstore:6167-6191
/CalendarServer/branches/new-store:5594-5934
/CalendarServer/branches/new-store-no-caldavfile:5911-5935
/CalendarServer/branches/new-store-no-caldavfile-2:5936-5981
/CalendarServer/branches/release/CalendarServer-4.3-dev:10180-10190,10192
/CalendarServer/branches/users/cdaboo/batchupload-6699:6700-7198
/CalendarServer/branches/users/cdaboo/cached-subscription-calendars-5692:5693-5702
/CalendarServer/branches/users/cdaboo/component-set-fixes:8130-8346
/CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627:3628-3644
/CalendarServer/branches/users/cdaboo/implicituidrace:8137-8141
/CalendarServer/branches/users/cdaboo/ischedule-dkim:9747-9979
/CalendarServer/branches/users/cdaboo/managed-attachments:9985-10145
/CalendarServer/branches/users/cdaboo/more-sharing-5591:5592-5601
/CalendarServer/branches/users/cdaboo/partition-4464:4465-4957
/CalendarServer/branches/users/cdaboo/pods:7297-7377
/CalendarServer/branches/users/cdaboo/pycalendar:7085-7206
/CalendarServer/branches/users/cdaboo/pycard:7227-7237
/CalendarServer/branches/users/cdaboo/queued-attendee-refreshes:7740-8287
/CalendarServer/branches/users/cdaboo/relative-config-paths-5070:5071-5105
/CalendarServer/branches/users/cdaboo/shared-calendars-5187:5188-5440
/CalendarServer/branches/users/cdaboo/timezones:7443-7699
/CalendarServer/branches/users/cdaboo/txn-debugging:8730-8743
/CalendarServer/branches/users/glyph/always-abort-txn-on-error:9958-9969
/CalendarServer/branches/users/glyph/case-insensitive-uid:8772-8805
/CalendarServer/branches/users/glyph/conn-limit:6574-6577
/CalendarServer/branches/users/glyph/contacts-server-merge:4971-5080
/CalendarServer/branches/users/glyph/dalify:6932-7023
/CalendarServer/branches/users/glyph/db-reconnect:6824-6876
/CalendarServer/branches/users/glyph/deploybuild:7563-7572
/CalendarServer/branches/users/glyph/digest-auth-redux:10624-10635
/CalendarServer/branches/users/glyph/disable-quota:7718-7727
/CalendarServer/branches/users/glyph/dont-start-postgres:6592-6614
/CalendarServer/branches/users/glyph/imip-and-admin-html:7866-7984
/CalendarServer/branches/users/glyph/ipv6-client:9054-9105
/CalendarServer/branches/users/glyph/linux-tests:6893-6900
/CalendarServer/branches/users/glyph/migrate-merge:8690-8713
/CalendarServer/branches/users/glyph/misc-portability-fixes:7365-7374
/CalendarServer/branches/users/glyph/more-deferreds-6:6322-6368
/CalendarServer/branches/users/glyph/more-deferreds-7:6369-6445
/CalendarServer/branches/users/glyph/multiget-delete:8321-8330
/CalendarServer/branches/users/glyph/new-export:7444-7485
/CalendarServer/branches/users/glyph/one-home-list-api:10048-10073
/CalendarServer/branches/users/glyph/oracle:7106-7155
/CalendarServer/branches/users/glyph/oracle-nulls:7340-7351
/CalendarServer/branches/users/glyph/other-html:8062-8091
/CalendarServer/branches/users/glyph/parallel-sim:8240-8251
/CalendarServer/branches/users/glyph/parallel-upgrade:8376-8400
/CalendarServer/branches/users/glyph/parallel-upgrade_to_1:8571-8583
/CalendarServer/branches/users/glyph/q:9560-9688
/CalendarServer/branches/users/glyph/queue-locking-and-timing:10204-10289
/CalendarServer/branches/users/glyph/quota:7604-7637
/CalendarServer/branches/users/glyph/sendfdport:5388-5424
/CalendarServer/branches/users/glyph/shared-pool-fixes:8436-8443
/CalendarServer/branches/users/glyph/shared-pool-take2:8155-8174
/CalendarServer/branches/users/glyph/sharedpool:6490-6550
/CalendarServer/branches/users/glyph/sharing-api:9192-9205
/CalendarServer/branches/users/glyph/skip-lonely-vtimezones:8524-8535
/CalendarServer/branches/users/glyph/sql-store:5929-6073
/CalendarServer/branches/users/glyph/subtransactions:7248-7258
/CalendarServer/branches/users/glyph/table-alias:8651-8664
/CalendarServer/branches/users/glyph/uidexport:7673-7676
/CalendarServer/branches/users/glyph/unshare-when-access-revoked:10562-10595
/CalendarServer/branches/users/glyph/use-system-twisted:5084-5149
/CalendarServer/branches/users/glyph/uuid-normalize:9268-9296
/CalendarServer/branches/users/glyph/xattrs-from-files:7757-7769
/CalendarServer/branches/users/sagen/applepush:8126-8184
/CalendarServer/branches/users/sagen/inboxitems:7380-7381
/CalendarServer/branches/users/sagen/locations-resources:5032-5051
/CalendarServer/branches/users/sagen/locations-resources-2:5052-5061
/CalendarServer/branches/users/sagen/purge_old_events:6735-6746
/CalendarServer/branches/users/sagen/resource-delegates-4038:4040-4067
/CalendarServer/branches/users/sagen/resource-delegates-4066:4068-4075
/CalendarServer/branches/users/sagen/resources-2:5084-5093
/CalendarServer/branches/users/sagen/testing:10827-10851,10853-10855
/CalendarServer/branches/users/wsanchez/transations:5515-5593
/CalendarServer/trunk:9759-9832
   + /CalendarServer/branches/config-separation:4379-4443
/CalendarServer/branches/egg-info-351:4589-4625
/CalendarServer/branches/generic-sqlstore:6167-6191
/CalendarServer/branches/new-store:5594-5934
/CalendarServer/branches/new-store-no-caldavfile:5911-5935
/CalendarServer/branches/new-store-no-caldavfile-2:5936-5981
/CalendarServer/branches/release/CalendarServer-4.3-dev:10180-10190,10192
/CalendarServer/branches/users/cdaboo/batchupload-6699:6700-7198
/CalendarServer/branches/users/cdaboo/cached-subscription-calendars-5692:5693-5702
/CalendarServer/branches/users/cdaboo/component-set-fixes:8130-8346
/CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627:3628-3644
/CalendarServer/branches/users/cdaboo/implicituidrace:8137-8141
/CalendarServer/branches/users/cdaboo/ischedule-dkim:9747-9979
/CalendarServer/branches/users/cdaboo/managed-attachments:9985-10145
/CalendarServer/branches/users/cdaboo/more-sharing-5591:5592-5601
/CalendarServer/branches/users/cdaboo/partition-4464:4465-4957
/CalendarServer/branches/users/cdaboo/pods:7297-7377
/CalendarServer/branches/users/cdaboo/pycalendar:7085-7206
/CalendarServer/branches/users/cdaboo/pycard:7227-7237
/CalendarServer/branches/users/cdaboo/queued-attendee-refreshes:7740-8287
/CalendarServer/branches/users/cdaboo/relative-config-paths-5070:5071-5105
/CalendarServer/branches/users/cdaboo/shared-calendars-5187:5188-5440
/CalendarServer/branches/users/cdaboo/timezones:7443-7699
/CalendarServer/branches/users/cdaboo/txn-debugging:8730-8743
/CalendarServer/branches/users/glyph/always-abort-txn-on-error:9958-9969
/CalendarServer/branches/users/glyph/case-insensitive-uid:8772-8805
/CalendarServer/branches/users/glyph/conn-limit:6574-6577
/CalendarServer/branches/users/glyph/contacts-server-merge:4971-5080
/CalendarServer/branches/users/glyph/dalify:6932-7023
/CalendarServer/branches/users/glyph/db-reconnect:6824-6876
/CalendarServer/branches/users/glyph/deploybuild:7563-7572
/CalendarServer/branches/users/glyph/digest-auth-redux:10624-10635
/CalendarServer/branches/users/glyph/disable-quota:7718-7727
/CalendarServer/branches/users/glyph/dont-start-postgres:6592-6614
/CalendarServer/branches/users/glyph/imip-and-admin-html:7866-7984
/CalendarServer/branches/users/glyph/ipv6-client:9054-9105
/CalendarServer/branches/users/glyph/linux-tests:6893-6900
/CalendarServer/branches/users/glyph/migrate-merge:8690-8713
/CalendarServer/branches/users/glyph/misc-portability-fixes:7365-7374
/CalendarServer/branches/users/glyph/more-deferreds-6:6322-6368
/CalendarServer/branches/users/glyph/more-deferreds-7:6369-6445
/CalendarServer/branches/users/glyph/multiget-delete:8321-8330
/CalendarServer/branches/users/glyph/new-export:7444-7485
/CalendarServer/branches/users/glyph/one-home-list-api:10048-10073
/CalendarServer/branches/users/glyph/oracle:7106-7155
/CalendarServer/branches/users/glyph/oracle-nulls:7340-7351
/CalendarServer/branches/users/glyph/other-html:8062-8091
/CalendarServer/branches/users/glyph/parallel-sim:8240-8251
/CalendarServer/branches/users/glyph/parallel-upgrade:8376-8400
/CalendarServer/branches/users/glyph/parallel-upgrade_to_1:8571-8583
/CalendarServer/branches/users/glyph/q:9560-9688
/CalendarServer/branches/users/glyph/queue-locking-and-timing:10204-10289
/CalendarServer/branches/users/glyph/quota:7604-7637
/CalendarServer/branches/users/glyph/sendfdport:5388-5424
/CalendarServer/branches/users/glyph/shared-pool-fixes:8436-8443
/CalendarServer/branches/users/glyph/shared-pool-take2:8155-8174
/CalendarServer/branches/users/glyph/sharedpool:6490-6550
/CalendarServer/branches/users/glyph/sharing-api:9192-9205
/CalendarServer/branches/users/glyph/skip-lonely-vtimezones:8524-8535
/CalendarServer/branches/users/glyph/sql-store:5929-6073
/CalendarServer/branches/users/glyph/start-service-start-loop:11060-11065
/CalendarServer/branches/users/glyph/subtransactions:7248-7258
/CalendarServer/branches/users/glyph/table-alias:8651-8664
/CalendarServer/branches/users/glyph/uidexport:7673-7676
/CalendarServer/branches/users/glyph/unshare-when-access-revoked:10562-10595
/CalendarServer/branches/users/glyph/use-system-twisted:5084-5149
/CalendarServer/branches/users/glyph/uuid-normalize:9268-9296
/CalendarServer/branches/users/glyph/xattrs-from-files:7757-7769
/CalendarServer/branches/users/sagen/applepush:8126-8184
/CalendarServer/branches/users/sagen/inboxitems:7380-7381
/CalendarServer/branches/users/sagen/locations-resources:5032-5051
/CalendarServer/branches/users/sagen/locations-resources-2:5052-5061
/CalendarServer/branches/users/sagen/purge_old_events:6735-6746
/CalendarServer/branches/users/sagen/resource-delegates-4038:4040-4067
/CalendarServer/branches/users/sagen/resource-delegates-4066:4068-4075
/CalendarServer/branches/users/sagen/resources-2:5084-5093
/CalendarServer/branches/users/sagen/testing:10827-10851,10853-10855
/CalendarServer/branches/users/wsanchez/transations:5515-5593
/CalendarServer/trunk:9759-9832

Copied: CalendarServer/branches/users/gaya/directorybacker/.gitignore (from rev 11081, CalendarServer/trunk/.gitignore)
===================================================================
--- CalendarServer/branches/users/gaya/directorybacker/.gitignore	                        (rev 0)
+++ CalendarServer/branches/users/gaya/directorybacker/.gitignore	2013-04-22 18:46:28 UTC (rev 11083)
@@ -0,0 +1,8 @@
+*.pyc
+*.so
+dropin.cache
+
+/build/
+/data/
+/calendarserver/version.py
+/conf/caldavd-dev.plist
\ No newline at end of file

Modified: CalendarServer/branches/users/gaya/directorybacker/README
===================================================================
--- CalendarServer/branches/users/gaya/directorybacker/README	2013-04-22 18:44:41 UTC (rev 11082)
+++ CalendarServer/branches/users/gaya/directorybacker/README	2013-04-22 18:46:28 UTC (rev 11083)
@@ -110,4 +110,3 @@
 8443 for HTTPS.  You should then be able to connect to the server
 using your web browser (eg. Safari, Firefox) or with a CalDAV client
 (eg. iCal).
-

Modified: CalendarServer/branches/users/gaya/directorybacker/bin/caldavd
===================================================================
--- CalendarServer/branches/users/gaya/directorybacker/bin/caldavd	2013-04-22 18:44:41 UTC (rev 11082)
+++ CalendarServer/branches/users/gaya/directorybacker/bin/caldavd	2013-04-22 18:46:28 UTC (rev 11083)
@@ -125,4 +125,6 @@
 
 export PYTHONPATH
 
-exec "${python}" "${twistdpath}" ${twistd_profile} ${twistd_reactor} ${daemonize} ${username} ${groupname} "${plugin_name}" ${configfile} ${service_type} ${errorlogenabled} ${profile} ${child_reactor};
+extra="-o FailIfUpgradeNeeded=False";
+
+exec "${python}" "${twistdpath}" ${twistd_profile} ${twistd_reactor} ${daemonize} ${username} ${groupname} "${plugin_name}" ${configfile} ${service_type} ${errorlogenabled} ${profile} ${child_reactor} ${extra};

Copied: CalendarServer/branches/users/gaya/directorybacker/bin/calendarserver_monitor_work (from rev 11081, CalendarServer/trunk/bin/calendarserver_monitor_work)
===================================================================
--- CalendarServer/branches/users/gaya/directorybacker/bin/calendarserver_monitor_work	                        (rev 0)
+++ CalendarServer/branches/users/gaya/directorybacker/bin/calendarserver_monitor_work	2013-04-22 18:46:28 UTC (rev 11083)
@@ -0,0 +1,38 @@
+#!/usr/bin/env python
+
+##
+# Copyright (c) 2006-2013 Apple Inc. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+##
+
+import os
+import sys
+
+# In OS X Server context, add to PATH to find Postgres utilities (initdb, pg_ctl)
+if "Server.app" in sys.argv[0]:
+    os.environ["PATH"] += ":" + os.path.join(os.path.dirname(os.path.dirname(sys.argv[0])), "bin")
+
+#PYTHONPATH
+
+if __name__ == "__main__":
+    if "PYTHONPATH" in globals():
+        sys.path.insert(0, PYTHONPATH)
+    else:
+        try:
+            import _calendarserver_preamble
+        except ImportError:
+            sys.exc_clear()
+
+    from calendarserver.tools.workitems import main
+    main()

Modified: CalendarServer/branches/users/gaya/directorybacker/calendarserver/tap/caldav.py
===================================================================
--- CalendarServer/branches/users/gaya/directorybacker/calendarserver/tap/caldav.py	2013-04-22 18:44:41 UTC (rev 11082)
+++ CalendarServer/branches/users/gaya/directorybacker/calendarserver/tap/caldav.py	2013-04-22 18:46:28 UTC (rev 11083)
@@ -53,6 +53,8 @@
 from twisted.application.service import MultiService, IServiceMaker
 from twisted.application.service import Service
 
+from twistedcaldav.config import config, ConfigurationError
+from twistedcaldav.stdconfig import DEFAULT_CONFIG, DEFAULT_CONFIG_FILE
 from twext.web2.server import Site
 from twext.python.log import Logger, LoggingMixIn
 from twext.python.log import logLevelForNamespace, setLogLevelForNamespace
@@ -68,14 +70,14 @@
 )
 from txdav.common.datastore.upgrade.migrate import UpgradeToDatabaseService
 
-from twistedcaldav.config import ConfigurationError
-from twistedcaldav.config import config
+from twistedcaldav.directory import calendaruserproxy
+from twistedcaldav.directory.directory import GroupMembershipCacheUpdater
 from twistedcaldav.localization import processLocalizationFiles
 from twistedcaldav import memcachepool
-from twistedcaldav.stdconfig import DEFAULT_CONFIG, DEFAULT_CONFIG_FILE
 from twistedcaldav.upgrade import UpgradeFileSystemFormatService, PostDBImportService
 
 from calendarserver.tap.util import pgServiceFromConfig, getDBPool, MemoryLimitService
+from calendarserver.tap.util import directoryFromConfig, checkDirectories
 
 from twext.enterprise.ienterprise import POSTGRES_DIALECT
 from twext.enterprise.ienterprise import ORACLE_DIALECT
@@ -99,13 +101,11 @@
 from calendarserver.accesslog import AMPCommonAccessLoggingObserver
 from calendarserver.accesslog import AMPLoggingFactory
 from calendarserver.accesslog import RotatingFileAccessLoggingObserver
-from calendarserver.tap.util import getRootResource, computeProcessCount
-
+from calendarserver.tap.util import getRootResource
 from calendarserver.tap.util import storeFromConfig
 from calendarserver.tap.util import pgConnectorFromConfig
 from calendarserver.tap.util import oracleConnectorFromConfig
 from calendarserver.tap.cfgchild import ConfiguredChildSpawner
-from calendarserver.tools.util import checkDirectory
 from calendarserver.push.notifier import PushDistributor
 from calendarserver.push.amppush import AMPPushMaster, AMPPushForwarder
 from calendarserver.push.applepush import ApplePushNotifierService
@@ -384,8 +384,8 @@
         config.updateDefaults(self.overrides)
 
 
-    def checkDirectory(self, dirpath, description, access=None, create=None, wait=False):
-        checkDirectory(dirpath, description, access=access, create=create, wait=wait)
+    def checkDirectories(self, config):
+        checkDirectories(config)
 
 
     def checkConfiguration(self):
@@ -415,59 +415,9 @@
 
         self.parent["pidfile"] = config.PIDFile
 
-        #
-        # Verify that server root actually exists
-        #
-        self.checkDirectory(
-            config.ServerRoot,
-            "Server root",
-            # Require write access because one might not allow editing on /
-            access=os.W_OK,
-            wait=True # Wait in a loop until ServerRoot exists
-        )
+        self.checkDirectories(config)
 
-        #
-        # Verify that other root paths are OK
-        #
-        if config.DataRoot.startswith(config.ServerRoot + os.sep):
-            self.checkDirectory(
-                config.DataRoot,
-                "Data root",
-                access=os.W_OK,
-                create=(0750, config.UserName, config.GroupName),
-            )
-        if config.DocumentRoot.startswith(config.DataRoot + os.sep):
-            self.checkDirectory(
-                config.DocumentRoot,
-                "Document root",
-                # Don't require write access because one might not allow editing on /
-                access=os.R_OK,
-                create=(0750, config.UserName, config.GroupName),
-            )
-        if config.ConfigRoot.startswith(config.ServerRoot + os.sep):
-            self.checkDirectory(
-                config.ConfigRoot,
-                "Config root",
-                access=os.W_OK,
-                create=(0750, config.UserName, config.GroupName),
-            )
 
-        if config.LogRoot.startswith(config.ServerRoot + os.sep):
-            self.checkDirectory(
-                config.LogRoot,
-                "Log root",
-                access=os.W_OK,
-                create=(0750, config.UserName, config.GroupName),
-            )
-
-        # Always create RunRoot (for pid files, socket files) if it does not exist
-        self.checkDirectory(
-            config.RunRoot,
-            "Run root",
-            access=os.W_OK,
-            create=(0770, config.UserName, config.GroupName),
-        )
-
         #
         # Nuke the file log observer's time format.
         #
@@ -542,29 +492,8 @@
             )
             self.monitor.addProcessObject(process, PARENT_ENVIRONMENT)
 
-        if config.GroupCaching.Enabled and config.GroupCaching.EnableUpdater:
-            self.maker.log_info("Adding group caching service")
 
-            groupMembershipCacherArgv = [
-                sys.executable,
-                sys.argv[0],
-            ]
-            if config.UserName:
-                groupMembershipCacherArgv.extend(("-u", config.UserName))
-            if config.GroupName:
-                groupMembershipCacherArgv.extend(("-g", config.GroupName))
-            groupMembershipCacherArgv.extend((
-                "--reactor=%s" % (config.Twisted.reactor,),
-                "-n", self.maker.groupMembershipCacherTapName,
-                "-f", self.configPath,
-                "-o", "PIDFile=groupcacher.pid",
-            ))
 
-            self.monitor.addProcess("groupcacher", groupMembershipCacherArgv,
-                               env=PARENT_ENVIRONMENT)
-
-
-
 class ReExecService(MultiService, LoggingMixIn):
     """
     A MultiService which catches SIGHUP and re-exec's the process.
@@ -621,12 +550,7 @@
     description = "Calendar and Contacts Server"
     options = CalDAVOptions
 
-    #
-    # Default tap names
-    #
-    groupMembershipCacherTapName = "caldav_groupcacher"
 
-
     def makeService(self, options):
         """
         Create the top-level service.
@@ -634,15 +558,18 @@
         self.log_info("%s %s starting %s process..." % (self.description, version, config.ProcessType))
 
         try:
-            from setproctitle import setproctitle
+            from setproctitle import setproctitle, getproctitle
         except ImportError:
             pass
         else:
+            origTitle = getproctitle()
             if config.LogID:
                 logID = " #%s" % (config.LogID,)
             else:
                 logID = ""
-            setproctitle("CalendarServer %s [%s%s]" % (version, config.ProcessType, logID))
+            if config.ProcessType is not "Utility":
+                origTitle = ""
+            setproctitle("CalendarServer %s [%s%s] %s" % (version, config.ProcessType, logID, origTitle))
 
         serviceMethod = getattr(self, "makeService_%s" % (config.ProcessType,), None)
 
@@ -771,10 +698,24 @@
         else:
             mailRetriever = None
 
+        # Optionally set up group cacher
+        if config.GroupCaching.Enabled:
+            groupCacher = GroupMembershipCacheUpdater(
+                calendaruserproxy.ProxyDBService,
+                directory,
+                config.GroupCaching.UpdateSeconds,
+                config.GroupCaching.ExpireSeconds,
+                namespace=config.GroupCaching.MemcachedPool,
+                useExternalProxies=config.GroupCaching.UseExternalProxies
+                )
+        else:
+            groupCacher = None
+
         def decorateTransaction(txn):
             txn._pushDistributor = pushDistributor
             txn._rootResource = result.rootResource
             txn._mailRetriever = mailRetriever
+            txn._groupCacher = groupCacher
 
         store.callWithNewTransactions(decorateTransaction)
 
@@ -1013,11 +954,35 @@
     def makeService_Single(self, options):
         """
         Create a service to be used in a single-process, stand-alone
-        configuration.
+        configuration.  Memcached will be spawned automatically.
         """
         def slaveSvcCreator(pool, store, logObserver):
             result = self.requestProcessingService(options, store, logObserver)
 
+            # Optionally launch memcached.  Note, this is not going through a
+            # ProcessMonitor because there is code elsewhere that needs to
+            # access memcached before startService() gets called, so we're just
+            # directly using Popen to spawn memcached.
+            for name, pool in config.Memcached.Pools.items():
+                if pool.ServerEnabled:
+                    self.log_info(
+                        "Adding memcached service for pool: %s" % (name,)
+                    )
+                    memcachedArgv = [
+                        config.Memcached.memcached,
+                        "-p", str(pool.Port),
+                        "-l", pool.BindAddress,
+                        "-U", "0",
+                    ]
+                    if config.Memcached.MaxMemory is not 0:
+                        memcachedArgv.extend(
+                            ["-m", str(config.Memcached.MaxMemory)]
+                        )
+                    if config.UserName:
+                        memcachedArgv.extend(["-u", config.UserName])
+                    memcachedArgv.extend(config.Memcached.Options)
+                    Popen(memcachedArgv)
+
             # Optionally set up push notifications
             pushDistributor = None
             if config.Notifications.Enabled:
@@ -1037,19 +1002,34 @@
                 if observers:
                     pushDistributor = PushDistributor(observers)
 
+            directory = result.rootResource.getDirectory()
+            
             # Optionally set up mail retrieval
             if config.Scheduling.iMIP.Enabled:
-                directory = result.rootResource.getDirectory()
                 mailRetriever = MailRetriever(store, directory,
                     config.Scheduling.iMIP.Receiving)
                 mailRetriever.setServiceParent(result)
             else:
                 mailRetriever = None
 
+            # Optionally set up group cacher
+            if config.GroupCaching.Enabled:
+                groupCacher = GroupMembershipCacheUpdater(
+                    calendaruserproxy.ProxyDBService,
+                    directory,
+                    config.GroupCaching.UpdateSeconds,
+                    config.GroupCaching.ExpireSeconds,
+                    namespace=config.GroupCaching.MemcachedPool,
+                    useExternalProxies=config.GroupCaching.UseExternalProxies
+                    )
+            else:
+                groupCacher = None
+
             def decorateTransaction(txn):
                 txn._pushDistributor = pushDistributor
                 txn._rootResource = result.rootResource
                 txn._mailRetriever = mailRetriever
+                txn._groupCacher = groupCacher
 
             store.callWithNewTransactions(decorateTransaction)
 
@@ -1289,18 +1269,6 @@
                 monitor.addProcess('memcached-%s' % (name,), memcachedArgv,
                                    env=PARENT_ENVIRONMENT)
 
-        #
-        # Calculate the number of processes to spawn
-        #
-        if config.MultiProcess.ProcessCount == 0:
-            # TODO: this should probably be happening in a configuration hook.
-            processCount = computeProcessCount(
-                config.MultiProcess.MinProcessCount,
-                config.MultiProcess.PerCPU,
-                config.MultiProcess.PerGB,
-            )
-            config.MultiProcess.ProcessCount = processCount
-            self.log_info("Configuring %d processes." % (processCount,))
 
         # Open the socket(s) to be inherited by the slaves
         inheritFDs = []
@@ -1394,6 +1362,7 @@
             from twisted.internet import reactor
             pool = PeerConnectionPool(reactor, store.newTransaction,
                                       7654, schema)
+            store.queuer = store.queuer.transferProposalCallbacks(pool)
             controlSocket.addFactory(_QUEUE_ROUTE,
                                      pool.workerListenerFactory())
             # TODO: now that we have the shared control socket, we should get
@@ -1414,8 +1383,42 @@
             spawner.setServiceParent(multi)
             if config.UseMetaFD:
                 cl.setServiceParent(multi)
+
+            directory = directoryFromConfig(config)
+            rootResource = getRootResource(config, store, [])
+
+            # Optionally set up mail retrieval
+            if config.Scheduling.iMIP.Enabled:
+                mailRetriever = MailRetriever(store, directory,
+                    config.Scheduling.iMIP.Receiving)
+                mailRetriever.setServiceParent(multi)
+            else:
+                mailRetriever = None
+
+            # Optionally set up group cacher
+            if config.GroupCaching.Enabled:
+                groupCacher = GroupMembershipCacheUpdater(
+                    calendaruserproxy.ProxyDBService,
+                    directory,
+                    config.GroupCaching.UpdateSeconds,
+                    config.GroupCaching.ExpireSeconds,
+                    namespace=config.GroupCaching.MemcachedPool,
+                    useExternalProxies=config.GroupCaching.UseExternalProxies
+                    )
+            else:
+                groupCacher = None
+
+            def decorateTransaction(txn):
+                txn._pushDistributor = None
+                txn._rootResource = rootResource
+                txn._mailRetriever = mailRetriever
+                txn._groupCacher = groupCacher
+
+            store.callWithNewTransactions(decorateTransaction)
+
             return multi
-        ssvc = self.storageService(spawnerSvcCreator, uid, gid)
+
+        ssvc = self.storageService(spawnerSvcCreator, None, uid, gid)
         ssvc.setServiceParent(s)
         return s
 

Modified: CalendarServer/branches/users/gaya/directorybacker/calendarserver/tap/test/test_caldav.py
===================================================================
--- CalendarServer/branches/users/gaya/directorybacker/calendarserver/tap/test/test_caldav.py	2013-04-22 18:44:41 UTC (rev 11082)
+++ CalendarServer/branches/users/gaya/directorybacker/calendarserver/tap/test/test_caldav.py	2013-04-22 18:46:28 UTC (rev 11083)
@@ -33,11 +33,12 @@
 
 from twisted.internet.interfaces import IProcessTransport, IReactorProcess
 from twisted.internet.protocol import ServerFactory
-from twisted.internet.defer import Deferred, inlineCallbacks
+from twisted.internet.defer import Deferred, inlineCallbacks, passthru
 from twisted.internet.task import Clock
 from twisted.internet import reactor
 
-from twisted.application.service import IService, IServiceCollection
+from twisted.application.service import (IService, IServiceCollection,
+                                         MultiService)
 from twisted.application import internet
 
 from twext.web2.dav import auth
@@ -62,6 +63,7 @@
     _CONTROL_SERVICE_NAME, getSystemIDs
 )
 from calendarserver.provision.root import RootResource
+from twext.enterprise.queue import PeerConnectionPool, LocalQueuer
 from StringIO import StringIO
 
 
@@ -150,6 +152,8 @@
     def checkFile(self, *args, **kwargs):
         pass
 
+    def checkDirectories(self, *args, **kwargs):
+        pass
 
     def loadConfiguration(self):
         """
@@ -358,14 +362,16 @@
         writePlist(self.config, self.configFile)
 
 
-    def makeService(self):
+    def makeService(self, patcher=passthru):
         """
         Create a service by calling into CalDAVServiceMaker with
         self.configFile
         """
         self.options.parseOptions(["-f", self.configFile])
 
-        return CalDAVServiceMaker().makeService(self.options)
+        maker = CalDAVServiceMaker()
+        maker = patcher(maker)
+        return maker.makeService(self.options)
 
 
     def getSite(self):
@@ -507,8 +513,41 @@
         )
 
 
+    def test_storeQueuerSetInMaster(self):
+        """
+        In the master, the store's queuer should be set to a
+        L{PeerConnectionPool}, so that work can be distributed to other
+        processes.
+        """
+        self.config["ProcessType"] = "Combined"
+        self.writeConfig()
+        class NotAStore(object):
+            queuer = LocalQueuer(None)
+            def newTransaction(self):
+                return None
+            def callWithNewTransactions(self, x):
+                pass
+        store = NotAStore()
+        def something(proposal):
+            pass
+        store.queuer.callWithNewProposals(something)
+        def patch(maker):
+            def storageServiceStandIn(createMainService, logObserver,
+                                      uid=None, gid=None):
+                pool = None
+                logObserver = None
+                svc = createMainService(pool, store, logObserver)
+                multi = MultiService()
+                svc.setServiceParent(multi)
+                return multi
+            self.patch(maker, "storageService", storageServiceStandIn)
+            return maker
+        self.makeService(patch)
+        self.assertIsInstance(store.queuer, PeerConnectionPool)
+        self.assertIn(something, store.queuer.proposalCallbacks)
 
 
+
 class SlaveServiceTest(BaseServiceMakerTests):
     """
     Test various configurations of the Slave service

Modified: CalendarServer/branches/users/gaya/directorybacker/calendarserver/tap/test/test_util.py
===================================================================
--- CalendarServer/branches/users/gaya/directorybacker/calendarserver/tap/test/test_util.py	2013-04-22 18:44:41 UTC (rev 11082)
+++ CalendarServer/branches/users/gaya/directorybacker/calendarserver/tap/test/test_util.py	2013-04-22 18:46:28 UTC (rev 11083)
@@ -14,7 +14,8 @@
 # limitations under the License.
 ##
 
-from calendarserver.tap.util import computeProcessCount, directoryFromConfig, MemoryLimitService
+from calendarserver.tap.util import directoryFromConfig, MemoryLimitService
+from twistedcaldav.util import computeProcessCount
 from twistedcaldav.test.util import TestCase
 from twistedcaldav.config import config
 from twistedcaldav.directory.augment import AugmentXMLDB

Modified: CalendarServer/branches/users/gaya/directorybacker/calendarserver/tap/util.py
===================================================================
--- CalendarServer/branches/users/gaya/directorybacker/calendarserver/tap/util.py	2013-04-22 18:44:41 UTC (rev 11082)
+++ CalendarServer/branches/users/gaya/directorybacker/calendarserver/tap/util.py	2013-04-22 18:46:28 UTC (rev 11083)
@@ -68,7 +68,6 @@
 from twistedcaldav.timezones import TimezoneCache
 from twistedcaldav.timezoneservice import TimezoneServiceResource
 from twistedcaldav.timezonestdservice import TimezoneStdServiceResource
-from twistedcaldav.util import getMemorySize, getNCPU
 from twext.enterprise.ienterprise import POSTGRES_DIALECT
 from twext.enterprise.ienterprise import ORACLE_DIALECT
 from twext.enterprise.adbapi2 import ConnectionPool, ConnectionPoolConnection
@@ -87,6 +86,7 @@
 
 from calendarserver.accesslog import DirectoryLogWrapperResource
 from calendarserver.provision.root import RootResource
+from calendarserver.tools.util import checkDirectory
 from calendarserver.webadmin.resource import WebAdminResource
 from calendarserver.webcal.resource import WebCalendarResource
 
@@ -652,6 +652,7 @@
             config.WebCalendarRoot,
             root,
             directory,
+            newStore,
             principalCollections=(principalCollection,),
         )
         root.putChild("admin", webAdmin)
@@ -765,37 +766,8 @@
 
 
 
-def computeProcessCount(minimum, perCPU, perGB, cpuCount=None, memSize=None):
-    """
-    Determine how many process to spawn based on installed RAM and CPUs,
-    returning at least "mininum"
-    """
 
-    if cpuCount is None:
-        try:
-            cpuCount = getNCPU()
-        except NotImplementedError, e:
-            log.error("Unable to detect number of CPUs: %s" % (str(e),))
-            return minimum
 
-    if memSize is None:
-        try:
-            memSize = getMemorySize()
-        except NotImplementedError, e:
-            log.error("Unable to detect amount of installed RAM: %s" % (str(e),))
-            return minimum
-
-    countByCore = perCPU * cpuCount
-    countByMemory = perGB * (memSize / (1024 * 1024 * 1024))
-
-    # Pick the smaller of the two:
-    count = min(countByCore, countByMemory)
-
-    # ...but at least "minimum"
-    return max(count, minimum)
-
-
-
 class FakeRequest(object):
 
     def __init__(self, rootResource, method, path, uri='/', transaction=None):
@@ -961,3 +933,59 @@
                         self._processMonitor.stopProcess(name)
         finally:
             self._delayedCall = self._reactor.callLater(self._seconds, self.checkMemory)
+
+
+def checkDirectories(config):
+    """
+    Make sure that various key directories exist (and create if needed)
+    """
+    
+    #
+    # Verify that server root actually exists
+    #
+    checkDirectory(
+        config.ServerRoot,
+        "Server root",
+        # Require write access because one might not allow editing on /
+        access=os.W_OK,
+        wait=True # Wait in a loop until ServerRoot exists
+    )
+
+    #
+    # Verify that other root paths are OK
+    #
+    if config.DataRoot.startswith(config.ServerRoot + os.sep):
+        checkDirectory(
+            config.DataRoot,
+            "Data root",
+            access=os.W_OK,
+            create=(0750, config.UserName, config.GroupName),
+        )
+    if config.DocumentRoot.startswith(config.DataRoot + os.sep):
+        checkDirectory(
+            config.DocumentRoot,
+            "Document root",
+            # Don't require write access because one might not allow editing on /
+            access=os.R_OK,
+            create=(0750, config.UserName, config.GroupName),
+        )
+    if config.ConfigRoot.startswith(config.ServerRoot + os.sep):
+        checkDirectory(
+            config.ConfigRoot,
+            "Config root",
+            access=os.W_OK,
+            create=(0750, config.UserName, config.GroupName),
+        )
+    # Always create  these:
+    checkDirectory(
+        config.LogRoot,
+        "Log root",
+        access=os.W_OK,
+        create=(0750, config.UserName, config.GroupName),
+    )
+    checkDirectory(
+        config.RunRoot,
+        "Run root",
+        access=os.W_OK,
+        create=(0770, config.UserName, config.GroupName),
+    )

Modified: CalendarServer/branches/users/gaya/directorybacker/calendarserver/tools/calverify.py
===================================================================
--- CalendarServer/branches/users/gaya/directorybacker/calendarserver/tools/calverify.py	2013-04-22 18:44:41 UTC (rev 11082)
+++ CalendarServer/branches/users/gaya/directorybacker/calendarserver/tools/calverify.py	2013-04-22 18:46:28 UTC (rev 11083)
@@ -17,8 +17,6 @@
 ##
 from __future__ import print_function
 
-from twistedcaldav.directory.directory import DirectoryService
-from twistedcaldav.datafilters.peruserdata import PerUserDataFilter
 
 """
 This tool scans the calendar store to analyze organizer/attendee event
@@ -42,30 +40,39 @@
 
 """
 
+from calendarserver.tools.cmdline import utilityMain
+
 from calendarserver.tools import tables
-from calendarserver.tools.cmdline import utilityMain
 from calendarserver.tools.util import getDirectory
+
 from pycalendar import definitions
 from pycalendar.calendar import PyCalendar
 from pycalendar.datetime import PyCalendarDateTime
 from pycalendar.exceptions import PyCalendarError
 from pycalendar.period import PyCalendarPeriod
 from pycalendar.timezone import PyCalendarTimezone
+
 from twext.enterprise.dal.syntax import Select, Parameter, Count
+
 from twisted.application.service import Service
 from twisted.internet.defer import inlineCallbacks, returnValue
 from twisted.python import log, usage
 from twisted.python.usage import Options
+
 from twistedcaldav import caldavxml
+from twistedcaldav.datafilters.peruserdata import PerUserDataFilter
 from twistedcaldav.dateops import pyCalendarTodatetime
+from twistedcaldav.directory.directory import DirectoryService
 from twistedcaldav.ical import Component, ignoredComponents, \
     InvalidICalendarDataError, Property
 from twistedcaldav.scheduling.itip import iTipGenerator
 from twistedcaldav.stdconfig import DEFAULT_CONFIG_FILE
 from twistedcaldav.util import normalizationLookup
+
 from txdav.base.propertystore.base import PropertyName
 from txdav.common.datastore.sql_tables import schema, _BIND_MODE_OWN
 from txdav.common.icommondatastore import InternalDataStoreError
+
 import base64
 import collections
 import sys
@@ -195,7 +202,7 @@
 if not hasattr(Component, "maxAlarmCounts"):
     Component.hasDuplicateAlarms = new_hasDuplicateAlarms
 
-VERSION = "9"
+VERSION = "10"
 
 def printusage(e=None):
     if e:
@@ -228,6 +235,7 @@
 --missing           : display orphaned calendar homes - can be used.
                       with either --ical or --mismatch.
 --double            : detect double-bookings.
+--dark-purge        : purge room/resource events with invalid organizer
 
 --nuke PATH|RID     : remove specific calendar resources - can
                       only be used by itself. PATH is the full
@@ -263,6 +271,19 @@
 --summary  : report only which GUIDs have double-bookings - no details.
 --days     : number of days ahead to scan [DEFAULT: 365]
 
+Options for --dark-purge:
+
+--uuid     : only scan specified calendar homes. Can be a partial GUID
+             to scan all GUIDs with that as a prefix or "*" for all GUIDS
+             (that are marked as resources or locations in the directory).
+--summary  : report only which GUIDs have double-bookings - no details.
+--no-organizer       : only detect events without an organizer
+--invalid-organizer  : only detect events with an organizer not in the directory
+--disabled-organizer : only detect events with an organizer disabled for calendaring
+
+If none of (--no-organizer, --invalid-organizer, --disabled-organizer) is present, it
+will default to (--invalid-organizer, --disabled-organizer).
+
 CHANGES
 v8: Detects ORGANIZER or ATTENDEE properties with mailto: calendar user
     addresses for users that have valid directory records. Fix is to
@@ -293,13 +314,18 @@
         ['mismatch', 's', "Detect organizer/attendee mismatches."],
         ['missing', 'm', "Show 'orphaned' homes."],
         ['double', 'd', "Detect double-bookings."],
+        ['dark-purge', 'p', "Purge room/resource events with invalid organizer."],
         ['fix', 'x', "Fix problems."],
         ['verbose', 'v', "Verbose logging."],
         ['details', 'V', "Detailed logging."],
         ['summary', 'S', "Summary of double-bookings."],
         ['tzid', 't', "Timezone to adjust displayed times to."],
-    ]
 
+        ['no-organizer', '', "Detect dark events without an organizer"],
+        ['invalid-organizer', '', "Detect dark events with an organizer not in the directory"],
+        ['disabled-organizer', '', "Detect dark events with a disabled organizer"],
+]
+
     optParameters = [
         ['config', 'f', DEFAULT_CONFIG_FILE, "Specify caldavd.plist configuration path."],
         ['uuid', 'u', "", "Only check this user."],
@@ -564,7 +590,32 @@
         cb = schema.CALENDAR_BIND
         ch = schema.CALENDAR_HOME
         tr = schema.TIME_RANGE
+        kwds = {
+            "Start" : pyCalendarTodatetime(start),
+            "Max"   : pyCalendarTodatetime(PyCalendarDateTime(1900, 1, 1, 0, 0, 0)),
+            "UUID" : uuid,
+        }
+        rows = (yield Select(
+            [ch.OWNER_UID, co.RESOURCE_ID, co.ICALENDAR_UID, cb.CALENDAR_RESOURCE_NAME, co.MD5, co.ORGANIZER, co.CREATED, co.MODIFIED],
+            From=ch.join(
+                cb, type="inner", on=(ch.RESOURCE_ID == cb.CALENDAR_HOME_RESOURCE_ID)).join(
+                co, type="inner", on=(cb.CALENDAR_RESOURCE_ID == co.CALENDAR_RESOURCE_ID).And(
+                    cb.BIND_MODE == _BIND_MODE_OWN).And(
+                    cb.CALENDAR_RESOURCE_NAME != "inbox")).join(
+                tr, type="left", on=(co.RESOURCE_ID == tr.CALENDAR_OBJECT_RESOURCE_ID)),
+            Where=(ch.OWNER_UID == Parameter("UUID")).And((tr.START_DATE >= Parameter("Start")).Or(co.RECURRANCE_MAX <= Parameter("Start"))),
+            GroupBy=(ch.OWNER_UID, co.RESOURCE_ID, co.ICALENDAR_UID, cb.CALENDAR_RESOURCE_NAME, co.MD5, co.ORGANIZER, co.CREATED, co.MODIFIED,),
+        ).on(self.txn, **kwds))
+        returnValue(tuple(rows))
 
+
+    @inlineCallbacks
+    def getAllResourceInfoTimeRangeWithUUIDForAllUID(self, start, uuid):
+        co = schema.CALENDAR_OBJECT
+        cb = schema.CALENDAR_BIND
+        ch = schema.CALENDAR_HOME
+        tr = schema.TIME_RANGE
+
         cojoin = (cb.CALENDAR_RESOURCE_ID == co.CALENDAR_RESOURCE_ID).And(
                 cb.BIND_MODE == _BIND_MODE_OWN).And(
                 cb.CALENDAR_RESOURCE_NAME != "inbox")
@@ -1370,8 +1421,8 @@
             rows = yield self.getAllResourceInfoWithUID(self.options["uid"])
             descriptor = "getAllResourceInfoWithUID"
         elif self.options["uuid"]:
-            rows = yield self.getAllResourceInfoTimeRangeWithUUID(self.start, self.options["uuid"])
-            descriptor = "getAllResourceInfoTimeRangeWithUUID"
+            rows = yield self.getAllResourceInfoTimeRangeWithUUIDForAllUID(self.start, self.options["uuid"])
+            descriptor = "getAllResourceInfoTimeRangeWithUUIDForAllUID"
             self.options["uuid"] = None
         else:
             rows = yield self.getAllResourceInfoTimeRange(self.start)
@@ -2357,6 +2408,244 @@
 
 
 
+class DarkPurgeService(CalVerifyService):
+    """
+    Service which detects room/resource events that have an invalid organizer.
+    """
+
+    def title(self):
+        return "Dark Purge Service"
+
+
+    @inlineCallbacks
+    def doAction(self):
+
+        if not self.options["no-organizer"] and not self.options["invalid-organizer"] and not self.options["disabled-organizer"]:
+            self.options["invalid-organizer"] = self.options["disabled-organizer"] = True
+
+        self.output.write("\n---- Scanning calendar data ----\n")
+
+        self.tzid = PyCalendarTimezone(tzid=self.options["tzid"] if self.options["tzid"] else "America/Los_Angeles")
+        self.now = PyCalendarDateTime.getNowUTC()
+        self.start = self.options["start"] if "start" in self.options else PyCalendarDateTime.getToday()
+        self.start.setDateOnly(False)
+        self.start.setTimezone(self.tzid)
+        self.fix = self.options["fix"]
+
+        if self.options["verbose"] and self.options["summary"]:
+            ot = time.time()
+
+        # Check loop over uuid
+        UUIDDetails = collections.namedtuple("UUIDDetails", ("uuid", "rname", "purged",))
+        self.uuid_details = []
+        if len(self.options["uuid"]) != 36:
+            self.txn = self.store.newTransaction()
+            if self.options["uuid"]:
+                homes = yield self.getMatchingHomeUIDs(self.options["uuid"])
+            else:
+                homes = yield self.getAllHomeUIDs()
+            yield self.txn.commit()
+            self.txn = None
+            uuids = []
+            if self.options["verbose"]:
+                self.output.write("%d uuids to check\n" % (len(homes,)))
+            for uuid in sorted(homes):
+                record = self.directoryService().recordWithGUID(uuid)
+                if record is not None and record.recordType in (DirectoryService.recordType_locations, DirectoryService.recordType_resources):
+                    uuids.append(uuid)
+        else:
+            uuids = [self.options["uuid"], ]
+        if self.options["verbose"]:
+            self.output.write("%d uuids to scan\n" % (len(uuids,)))
+
+        count = 0
+        for uuid in uuids:
+            self.results = {}
+            self.summary = []
+            self.total = 0
+            count += 1
+
+            record = self.directoryService().recordWithGUID(uuid)
+            if record is None:
+                continue
+            if not record.thisServer() or not record.enabledForCalendaring:
+                continue
+
+            rname = record.fullName
+
+            if len(uuids) > 1 and not self.options["summary"]:
+                self.output.write("\n\n-----------------------------\n")
+
+            self.txn = self.store.newTransaction()
+
+            if self.options["verbose"]:
+                t = time.time()
+            rows = yield self.getAllResourceInfoTimeRangeWithUUID(self.start, uuid)
+            descriptor = "getAllResourceInfoTimeRangeWithUUID"
+
+            yield self.txn.commit()
+            self.txn = None
+
+            if self.options["verbose"]:
+                if not self.options["summary"]:
+                    self.output.write("%s time: %.1fs\n" % (descriptor, time.time() - t,))
+                else:
+                    self.output.write("%s (%d/%d)" % (uuid, count, len(uuids),))
+                    self.output.flush()
+
+            self.total = len(rows)
+            if not self.options["summary"]:
+                self.logResult("UUID to process", uuid)
+                self.logResult("Record name", rname)
+                self.addSummaryBreak()
+                self.logResult("Number of events to process", self.total)
+
+            if rows:
+                if not self.options["summary"]:
+                    self.addSummaryBreak()
+                purged = yield self.darkPurge(rows, uuid)
+            else:
+                purged = False
+
+            self.uuid_details.append(UUIDDetails(uuid, rname, purged))
+
+            if not self.options["summary"]:
+                self.printSummary()
+            else:
+                self.output.write(" - %s\n" % ("Dark Events" if purged else "OK",))
+                self.output.flush()
+
+        if count == 0:
+            self.output.write("Nothing to scan\n")
+
+        if self.options["summary"]:
+            table = tables.Table()
+            table.addHeader(("GUID", "Name", "RID", "UID", "Organizer",))
+            purged = 0
+            for item in sorted(self.uuid_details):
+                if not item.purged:
+                    continue
+                uuid = item.uuid
+                rname = item.rname
+                for detail in item.purged:
+                    table.addRow((
+                        uuid,
+                        rname,
+                        detail.resid,
+                        detail.uid,
+                        detail.organizer,
+                    ))
+                    uuid = ""
+                    rname = ""
+                    purged += 1
+            table.addFooter(("Total", "%d" % (purged,), "", "", "",))
+            self.output.write("\n")
+            table.printTable(os=self.output)
+
+            if self.options["verbose"]:
+                self.output.write("%s time: %.1fs\n" % ("Summary", time.time() - ot,))
+
+
+    @inlineCallbacks
+    def darkPurge(self, rows, uuid):
+        """
+        Check each calendar resource by looking at any ORGANIER property value and verifying it is valid.
+        """
+
+        if not self.options["summary"]:
+            self.output.write("\n---- Checking for dark events ----\n")
+        self.txn = self.store.newTransaction()
+
+        if self.options["verbose"]:
+            t = time.time()
+
+        Details = collections.namedtuple("Details", ("resid", "uid", "organizer",))
+
+        count = 0
+        total = len(rows)
+        details = []
+        fixed = 0
+        rjust = 10
+        for resid in rows:
+            resid = resid[1]
+            caldata = yield self.getCalendar(resid, self.fix)
+            if caldata is None:
+                if self.parseError:
+                    returnValue((False, self.parseError))
+                else:
+                    returnValue((True, "Nothing to scan"))
+
+            cal = Component(None, pycalendar=caldata)
+            uid = cal.resourceUID()
+
+            fail = False
+            organizer = cal.getOrganizer()
+            if organizer is None:
+                if self.options["no-organizer"]:
+                    fail = True
+            else:
+                principal = self.directoryService().principalForCalendarUserAddress(organizer)
+                if principal is None and organizer.startswith("urn:uuid:"):
+                    principal = self.directoryService().principalCollection.principalForUID(organizer[9:])
+                if principal is None:
+                    if self.options["invalid-organizer"]:
+                        fail = True
+                elif not principal.calendarsEnabled():
+                    if self.options["disabled-organizer"]:
+                        fail = True
+
+            if fail:
+                details.append(Details(resid, uid, organizer,))
+                if self.fix:
+                    yield self.removeEvent(resid)
+                    fixed += 1
+
+            if self.options["verbose"] and not self.options["summary"]:
+                if count == 1:
+                    self.output.write("Current".rjust(rjust) + "Total".rjust(rjust) + "Complete".rjust(rjust) + "\n")
+                if divmod(count, 100)[1] == 0:
+                    self.output.write((
+                        "\r" +
+                        ("%s" % count).rjust(rjust) +
+                        ("%s" % total).rjust(rjust) +
+                        ("%d%%" % safePercent(count, total)).rjust(rjust)
+                    ).ljust(80))
+                    self.output.flush()
+
+            # To avoid holding locks on all the rows scanned, commit every 100 resources
+            if divmod(count, 100)[1] == 0:
+                yield self.txn.commit()
+                self.txn = self.store.newTransaction()
+
+        yield self.txn.commit()
+        self.txn = None
+        if self.options["verbose"] and not self.options["summary"]:
+            self.output.write((
+                "\r" +
+                ("%s" % count).rjust(rjust) +
+                ("%s" % total).rjust(rjust) +
+                ("%d%%" % safePercent(count, total)).rjust(rjust)
+            ).ljust(80) + "\n")
+
+        # Print table of results
+        if not self.options["summary"]:
+            self.logResult("Number of dark events", len(details))
+
+        self.results["Dark Events"] = details
+        if self.fix:
+            self.results["Fix dark events"] = fixed
+
+        if self.options["verbose"] and not self.options["summary"]:
+            diff_time = time.time() - t
+            self.output.write("Time: %.2f s  Average: %.1f ms/resource\n" % (
+                diff_time,
+                safePercent(diff_time, total, 1000.0),
+            ))
+
+        returnValue(details)
+
+
+
 def main(argv=sys.argv, stderr=sys.stderr, reactor=None):
 
     if reactor is None:
@@ -2387,6 +2676,11 @@
             return SchedulingMismatchService(store, options, output, reactor, config)
         elif options["double"]:
             return DoubleBookingService(store, options, output, reactor, config)
+        elif options["dark-purge"]:
+            return DarkPurgeService(store, options, output, reactor, config)
+        else:
+            printusage("Invalid operation")
+            sys.exit(1)
 
     utilityMain(options['config'], makeService, reactor)
 

Modified: CalendarServer/branches/users/gaya/directorybacker/calendarserver/tools/cmdline.py
===================================================================
--- CalendarServer/branches/users/gaya/directorybacker/calendarserver/tools/cmdline.py	2013-04-22 18:44:41 UTC (rev 11082)
+++ CalendarServer/branches/users/gaya/directorybacker/calendarserver/tools/cmdline.py	2013-04-22 18:46:28 UTC (rev 11083)
@@ -19,14 +19,19 @@
 """
 
 from calendarserver.tap.caldav import CalDAVServiceMaker, CalDAVOptions
+from calendarserver.tap.util import checkDirectories
 from calendarserver.tools.util import loadConfig, autoDisableMemcached
 
 from twext.python.log import StandardIOObserver
 
 from twistedcaldav.config import ConfigurationError
+from twisted.internet.defer import inlineCallbacks
 
-import os
 import sys
+from calendarserver.tap.util import getRootResource
+from twisted.application.service import Service
+from errno import ENOENT, EACCES
+from twext.enterprise.queue import NonPerformingQueuer
 
 # TODO: direct unit tests for these functions.
 
@@ -74,10 +79,7 @@
         if patchConfig is not None:
             patchConfig(config)
 
-        # If we don't have permission to access the DataRoot directory, we
-        # can't proceed.  If this fails it should raise OSError which we
-        # catch below.
-        os.listdir(config.DataRoot)
+        checkDirectories(config)
 
         config.ProcessType = "Utility"
         config.UtilityServiceClass = serviceClass
@@ -85,6 +87,10 @@
         autoDisableMemcached(config)
 
         maker = serviceMaker()
+
+        # Only perform post-import duties if someone has explicitly said to
+        maker.doPostImport =  getattr(maker, "doPostImport", False)
+
         options = CalDAVOptions
         service = maker.makeService(options)
 
@@ -98,3 +104,49 @@
         return
 
     reactor.run()
+
+
+
+class WorkerService(Service):
+
+    def __init__(self, store):
+        self._store = store
+        # Work can be queued but will not be performed by the command line tool
+        store.queuer = NonPerformingQueuer()
+
+
+    def rootResource(self):
+        try:
+            from twistedcaldav.config import config
+            rootResource = getRootResource(config, self._store)
+        except OSError, e:
+            if e.errno == ENOENT:
+                # Trying to re-write resources.xml but its parent directory does
+                # not exist.  The server's never been started, so we're missing
+                # state required to do any work.
+                raise ConfigurationError(
+                    "It appears that the server has never been started.\n"
+                    "Please start it at least once before running this tool.")
+            elif e.errno == EACCES:
+                # Trying to re-write resources.xml but it is not writable by the
+                # current user.  This most likely means we're in a system
+                # configuration and the user doesn't have sufficient privileges
+                # to do the other things the tool might need to do either.
+                raise ConfigurationError("You must run this tool as root.")
+            else:
+                raise
+        return rootResource
+
+    @inlineCallbacks
+    def startService(self):
+        from twisted.internet import reactor
+        try:
+            yield self.doWork()
+        except ConfigurationError, ce:
+            sys.stderr.write("Error: %s\n" % (str(ce),))
+        except Exception, e:
+            sys.stderr.write("Error: %s\n" % (e,))
+            raise
+        finally:
+            reactor.stop()
+

Modified: CalendarServer/branches/users/gaya/directorybacker/calendarserver/tools/config.py
===================================================================
--- CalendarServer/branches/users/gaya/directorybacker/calendarserver/tools/config.py	2013-04-22 18:44:41 UTC (rev 11082)
+++ CalendarServer/branches/users/gaya/directorybacker/calendarserver/tools/config.py	2013-04-22 18:46:28 UTC (rev 11083)
@@ -32,40 +32,47 @@
 from twistedcaldav.config import config, ConfigDict, ConfigurationError, mergeData
 from twistedcaldav.stdconfig import DEFAULT_CONFIG_FILE
 WRITABLE_CONFIG_KEYS = [
-    "EnableSSL",
-    "RedirectHTTPToHTTPS",
-    "EnableCalDAV",
-    "EnableCardDAV",
-    "DataRoot",
-    "SSLCertificate",
-    "SSLPrivateKey",
-    "SSLAuthorityChain",
-    "EnableSearchAddressBook",
+    "Authentication.Basic.AllowedOverWireUnencrypted",
     "Authentication.Basic.Enabled",
-    "Authentication.Basic.AllowedOverWireUnencrypted",
+    "Authentication.Digest.AllowedOverWireUnencrypted",
     "Authentication.Digest.Enabled",
-    "Authentication.Digest.AllowedOverWireUnencrypted",
+    "Authentication.Kerberos.AllowedOverWireUnencrypted",
     "Authentication.Kerberos.Enabled",
-    "Authentication.Kerberos.AllowedOverWireUnencrypted",
     "Authentication.Wiki.Enabled",
+    "DataRoot",
+    "DefaultLogLevel",
+    "DirectoryAddressBook.params.queryPeopleRecords",
+    "DirectoryAddressBook.params.queryUserRecords",
+    "EnableCalDAV",
+    "EnableCardDAV",
+    "EnableSearchAddressBook",
+    "EnableSSL",
+    "HTTPPort",
+    "LogLevels",
+    "Notifications.Services.APNS.CalDAV.AuthorityChainPath",
+    "Notifications.Services.APNS.CalDAV.CertificatePath",
+    "Notifications.Services.APNS.CalDAV.PrivateKeyPath",
+    "Notifications.Services.APNS.CardDAV.AuthorityChainPath",
+    "Notifications.Services.APNS.CardDAV.CertificatePath",
+    "Notifications.Services.APNS.CardDAV.PrivateKeyPath",
+    "Notifications.Services.APNS.Enabled",
+    "RedirectHTTPToHTTPS",
     "Scheduling.iMIP.Enabled",
-    "Scheduling.iMIP.Receiving.Username",
+    "Scheduling.iMIP.Receiving.Port",
     "Scheduling.iMIP.Receiving.Server",
-    "Scheduling.iMIP.Receiving.Port",
     "Scheduling.iMIP.Receiving.Type",
+    "Scheduling.iMIP.Receiving.Username",
     "Scheduling.iMIP.Receiving.UseSSL",
+    "Scheduling.iMIP.Sending.Address",
+    "Scheduling.iMIP.Sending.Port",
+    "Scheduling.iMIP.Sending.Server",
     "Scheduling.iMIP.Sending.Username",
-    "Scheduling.iMIP.Sending.Server",
-    "Scheduling.iMIP.Sending.Port",
     "Scheduling.iMIP.Sending.UseSSL",
-    "Scheduling.iMIP.Sending.Address",
-    "Notifications.Services.APNS.Enabled",
-    "Notifications.Services.APNS.CalDAV.CertificatePath",
-    "Notifications.Services.APNS.CalDAV.AuthorityChainPath",
-    "Notifications.Services.APNS.CalDAV.PrivateKeyPath",
-    "Notifications.Services.APNS.CardDAV.CertificatePath",
-    "Notifications.Services.APNS.CardDAV.AuthorityChainPath",
-    "Notifications.Services.APNS.CardDAV.PrivateKeyPath",
+    "ServerHostName",
+    "SSLAuthorityChain",
+    "SSLCertificate",
+    "SSLPort",
+    "SSLPrivateKey",
 ]
 
 def usage(e=None):
@@ -155,6 +162,7 @@
         rawInput = sys.stdin.read()
         try:
             plist = readPlistFromString(rawInput)
+            # Note: values in plist will already be unicode
         except xml.parsers.expat.ExpatError, e:
             respondWithError(str(e))
             return
@@ -231,6 +239,10 @@
         for keyPath in WRITABLE_CONFIG_KEYS:
             value = getKeyPath(config, keyPath)
             if value is not None:
+                # Note: config contains utf-8 encoded strings, but plistlib
+                # wants unicode, so decode here:
+                if isinstance(value, str):
+                    value = value.decode("utf-8")
                 setKeyPath(result, keyPath, value)
         respond(command, result)
 
@@ -244,6 +256,7 @@
         writable = WritableConfig(config, config.WritableConfigFile)
         writable.read()
         valuesToWrite = command.get("Values", {})
+        # Note: values are unicode if they contain non-ascii
         for keyPath, value in flattenDictionary(valuesToWrite):
             if keyPath in WRITABLE_CONFIG_KEYS:
                 writable.set(setKeyPath(ConfigDict(), keyPath, value))

Modified: CalendarServer/branches/users/gaya/directorybacker/calendarserver/tools/gateway.py
===================================================================
--- CalendarServer/branches/users/gaya/directorybacker/calendarserver/tools/gateway.py	2013-04-22 18:44:41 UTC (rev 11082)
+++ CalendarServer/branches/users/gaya/directorybacker/calendarserver/tools/gateway.py	2013-04-22 18:46:28 UTC (rev 11083)
@@ -28,10 +28,11 @@
 from twistedcaldav.directory.directory import DirectoryError
 from txdav.xml import element as davxml
 
-from calendarserver.tools.principals import (
+from calendarserver.tools.util import (
     principalForPrincipalID, proxySubprincipal, addProxy, removeProxy,
-    getProxies, setProxies, ProxyError, ProxyWarning, updateRecord
+    ProxyError, ProxyWarning
 )
+from calendarserver.tools.principals import getProxies, setProxies, updateRecord
 from calendarserver.tools.purge import WorkerService, PurgeOldEventsService, DEFAULT_BATCH_SIZE, DEFAULT_RETAIN_DAYS
 from calendarserver.tools.cmdline import utilityMain
 
@@ -212,7 +213,7 @@
         readProxies = command.get("ReadProxies", None)
         writeProxies = command.get("WriteProxies", None)
         principal = principalForPrincipalID(record.guid, directory=self.dir)
-        (yield setProxies(principal, readProxies, writeProxies, directory=self.dir))
+        (yield setProxies(self.store, principal, readProxies, writeProxies, directory=self.dir))
 
         respondWithRecordsOfType(self.dir, command, "locations")
 
@@ -260,7 +261,7 @@
         readProxies = command.get("ReadProxies", None)
         writeProxies = command.get("WriteProxies", None)
         principal = principalForPrincipalID(record.guid, directory=self.dir)
-        (yield setProxies(principal, readProxies, writeProxies, directory=self.dir))
+        (yield setProxies(self.store, principal, readProxies, writeProxies, directory=self.dir))
 
         yield self.command_getLocationAttributes(command)
 
@@ -300,7 +301,7 @@
         readProxies = command.get("ReadProxies", None)
         writeProxies = command.get("WriteProxies", None)
         principal = principalForPrincipalID(record.guid, directory=self.dir)
-        (yield setProxies(principal, readProxies, writeProxies, directory=self.dir))
+        (yield setProxies(self.store, principal, readProxies, writeProxies, directory=self.dir))
 
         respondWithRecordsOfType(self.dir, command, "resources")
 
@@ -328,7 +329,7 @@
         readProxies = command.get("ReadProxies", None)
         writeProxies = command.get("WriteProxies", None)
         principal = principalForPrincipalID(record.guid, directory=self.dir)
-        (yield setProxies(principal, readProxies, writeProxies, directory=self.dir))
+        (yield setProxies(self.store, principal, readProxies, writeProxies, directory=self.dir))
 
         yield self.command_getResourceAttributes(command)
 
@@ -370,7 +371,7 @@
             respondWithError("Proxy not found: %s" % (command['Proxy'],))
             return
         try:
-            (yield addProxy(principal, "write", proxy))
+            (yield addProxy(self.root, self.dir, self.store, principal, "write", proxy))
         except ProxyError, e:
             respondWithError(str(e))
             return
@@ -390,7 +391,7 @@
             respondWithError("Proxy not found: %s" % (command['Proxy'],))
             return
         try:
-            (yield removeProxy(principal, proxy, proxyTypes=("write",)))
+            (yield removeProxy(self.root, self.dir, self.store, principal, proxy, proxyTypes=("write",)))
         except ProxyError, e:
             respondWithError(str(e))
             return
@@ -419,7 +420,7 @@
             respondWithError("Proxy not found: %s" % (command['Proxy'],))
             return
         try:
-            (yield addProxy(principal, "read", proxy))
+            (yield addProxy(self.root, self.dir, self.store, principal, "read", proxy))
         except ProxyError, e:
             respondWithError(str(e))
             return
@@ -439,7 +440,7 @@
             respondWithError("Proxy not found: %s" % (command['Proxy'],))
             return
         try:
-            (yield removeProxy(principal, proxy, proxyTypes=("read",)))
+            (yield removeProxy(self.root, self.dir, self.store, principal, proxy, proxyTypes=("read",)))
         except ProxyError, e:
             respondWithError(str(e))
             return

Modified: CalendarServer/branches/users/gaya/directorybacker/calendarserver/tools/principals.py
===================================================================
--- CalendarServer/branches/users/gaya/directorybacker/calendarserver/tools/principals.py	2013-04-22 18:44:41 UTC (rev 11082)
+++ CalendarServer/branches/users/gaya/directorybacker/calendarserver/tools/principals.py	2013-04-22 18:46:28 UTC (rev 11083)
@@ -20,33 +20,29 @@
 import sys
 import os
 import operator
-import signal
 from getopt import getopt, GetoptError
 from uuid import UUID
-from pwd import getpwnam
-from grp import getgrnam
 
-from twisted.python.util import switchUID
 from twisted.internet import reactor
-from twisted.internet.defer import inlineCallbacks, returnValue
+from twisted.internet.defer import inlineCallbacks, returnValue, succeed
 from txdav.xml import element as davxml
 
-from twext.python.log import clearLogLevels
-from twext.python.log import StandardIOObserver
-
 from txdav.xml.base import decodeXMLName, encodeXMLName
 
-from twistedcaldav.config import config, ConfigurationError
+from twistedcaldav.config import config
 from twistedcaldav.directory.directory import UnknownRecordTypeError, DirectoryError
+from twistedcaldav.directory.directory import schedulePolledGroupCachingUpdate
 
-from calendarserver.tools.util import loadConfig, getDirectory, setupMemcached,  booleanArgument, checkDirectory
+from calendarserver.tools.util import (
+    booleanArgument, proxySubprincipal, action_addProxyPrincipal,
+    principalForPrincipalID, prettyPrincipal, ProxyError,
+    action_removeProxyPrincipal
+)
 from twistedcaldav.directory.augment import allowedAutoScheduleModes
 
-__all__ = [
-    "principalForPrincipalID", "proxySubprincipal", "addProxy", "removeProxy",
-    "ProxyError", "ProxyWarning", "updateRecord"
-]
+from calendarserver.tools.cmdline import utilityMain, WorkerService
 
+
 def usage(e=None):
     if e:
         if isinstance(e, UnknownRecordTypeError):
@@ -99,6 +95,27 @@
     else:
         sys.exit(0)
 
+
+class PrincipalService(WorkerService):
+    """
+    Executes principals-related functions in a context which has access to the store
+    """
+
+    function = None
+    params = []
+
+    @inlineCallbacks
+    def doWork(self):
+        """
+        Calls the function that's been assigned to "function" and passes the root
+        resource, directory, store, and whatever has been assigned to "params".
+        """
+        if self.function is not None:
+            rootResource = self.rootResource()
+            directory = rootResource.getDirectory()
+            yield self.function(rootResource, directory, self._store, *self.params) 
+
+
 def main():
     try:
         (optargs, args) = getopt(
@@ -243,54 +260,7 @@
         else:
             raise NotImplementedError(opt)
 
-    #
-    # Get configuration
-    #
-    try:
-        loadConfig(configFileName)
 
-        # Do this first, because modifying the config object will cause
-        # some logging activity at whatever log level the plist says
-        clearLogLevels()
-
-
-        config.DefaultLogLevel = "debug" if verbose else "error"
-
-        #
-        # Send logging output to stdout
-        #
-        observer = StandardIOObserver()
-        observer.start()
-
-        # Create the DataRoot directory before shedding privileges
-        if config.DataRoot.startswith(config.ServerRoot + os.sep):
-            checkDirectory(
-                config.DataRoot,
-                "Data root",
-                access=os.W_OK,
-                create=(0750, config.UserName, config.GroupName),
-            )
-
-        # Shed privileges
-        if config.UserName and config.GroupName and os.getuid() == 0:
-            uid = getpwnam(config.UserName).pw_uid
-            gid = getgrnam(config.GroupName).gr_gid
-            switchUID(uid, uid, gid)
-
-        os.umask(config.umask)
-
-        # Configure memcached client settings prior to setting up resource
-        # hierarchy (in getDirectory)
-        setupMemcached(config)
-
-        try:
-            config.directory = getDirectory()
-        except DirectoryError, e:
-            abort(e)
-
-    except ConfigurationError, e:
-        abort(e)
-
     #
     # List principals
     #
@@ -298,10 +268,9 @@
         if args:
             usage("Too many arguments")
 
-        for recordType in config.directory.recordTypes():
-            print(recordType)
+        function = runListPrincipalTypes
+        params = ()
 
-        return
 
     elif addType:
 
@@ -322,7 +291,8 @@
         else:
             shortNames = ()
 
-        params = (runAddPrincipal, addType, guid, shortNames, fullName)
+        function = runAddPrincipal
+        params = (addType, guid, shortNames, fullName)
 
 
     elif listPrincipals:
@@ -336,19 +306,13 @@
         if args:
             usage("Too many arguments")
 
-        try:
-            records = list(config.directory.listRecords(listPrincipals))
-            if records:
-                printRecordList(records)
-            else:
-                print("No records of type %s" % (listPrincipals,))
-        except UnknownRecordTypeError, e:
-            usage(e)
+        function = runListPrincipals
+        params = (listPrincipals,)
 
-        return
 
     elif searchPrincipals:
-        params = (runSearch, searchPrincipals)
+        function = runSearch
+        params = (searchPrincipals,)
 
     else:
         #
@@ -364,178 +328,115 @@
             except ValueError, e:
                 abort(e)
 
-        params = (runPrincipalActions, args, principalActions)
+        function = runPrincipalActions
+        params = (args, principalActions)
 
-    #
-    # Start the reactor
-    #
-    reactor.callLater(0, *params)
-    reactor.run()
 
+    PrincipalService.function = function
+    PrincipalService.params = params
+    utilityMain(configFileName, PrincipalService, verbose=verbose)
 
 
- at inlineCallbacks
-def runPrincipalActions(principalIDs, actions):
-    try:
-        for principalID in principalIDs:
-            # Resolve the given principal IDs to principals
-            try:
-                principal = principalForPrincipalID(principalID)
-            except ValueError:
-                principal = None
+def runListPrincipalTypes(service, rootResource, directory, store):
+    for recordType in directory.recordTypes():
+        print(recordType)
+    return succeed(None)
 
-            if principal is None:
-                sys.stderr.write("Invalid principal ID: %s\n" % (principalID,))
-                continue
 
-            # Performs requested actions
-            for action in actions:
-                (yield action[0](principal, *action[1:]))
-                print("")
-
-    finally:
-        #
-        # Stop the reactor
-        #
-        reactor.stop()
-
- at inlineCallbacks
-def runSearch(searchTerm):
-
+def runListPrincipals(service, rootResource, directory, store, listPrincipals):
     try:
-        fields = []
-        for fieldName in ("fullName", "firstName", "lastName", "emailAddresses"):
-            fields.append((fieldName, searchTerm, True, "contains"))
-
-        records = list((yield config.directory.recordsMatchingTokens(searchTerm.strip().split())))
+        records = list(directory.listRecords(listPrincipals))
         if records:
-            records.sort(key=operator.attrgetter('fullName'))
-            print("%d matches found:" % (len(records),))
-            for record in records:
-                print("\n%s (%s)" % (record.fullName,
-                    { "users"     : "User",
-                      "groups"    : "Group",
-                      "locations" : "Place",
-                      "resources" : "Resource",
-                    }.get(record.recordType),
-                ))
-                print("   GUID: %s" % (record.guid,))
-                print("   Record name(s): %s" % (", ".join(record.shortNames),))
-                if record.authIDs:
-                    print("   Auth ID(s): %s" % (", ".join(record.authIDs),))
-                if record.emailAddresses:
-                    print("   Email(s): %s" % (", ".join(record.emailAddresses),))
+            printRecordList(records)
         else:
-            print("No matches found")
+            print("No records of type %s" % (listPrincipals,))
+    except UnknownRecordTypeError, e:
+        usage(e)
+    return succeed(None)
 
-        print("")
 
-    finally:
-        #
-        # Stop the reactor
-        #
-        reactor.stop()
-
 @inlineCallbacks
-def runAddPrincipal(addType, guid, shortNames, fullName):
-    try:
+def runPrincipalActions(service, rootResource, directory, store, principalIDs,
+    actions):
+    for principalID in principalIDs:
+        # Resolve the given principal IDs to principals
         try:
-            yield updateRecord(True, config.directory, addType, guid=guid,
-                shortNames=shortNames, fullName=fullName)
-            print("Added '%s'" % (fullName,))
-        except DirectoryError, e:
-            print(e)
+            principal = principalForPrincipalID(principalID, directory=directory)
+        except ValueError:
+            principal = None
 
-    finally:
-        #
-        # Stop the reactor
-        #
-        reactor.stop()
+        if principal is None:
+            sys.stderr.write("Invalid principal ID: %s\n" % (principalID,))
+            continue
 
+        # Performs requested actions
+        for action in actions:
+            (yield action[0](rootResource, directory, store, principal,
+                *action[1:]))
+            print("")
 
-def principalForPrincipalID(principalID, checkOnly=False, directory=None):
-    
-    # Allow a directory parameter to be passed in, but default to config.directory
-    # But config.directory isn't set right away, so only use it when we're doing more 
-    # than checking.
-    if not checkOnly and not directory:
-        directory = config.directory
 
-    if principalID.startswith("/"):
-        segments = principalID.strip("/").split("/")
-        if (len(segments) == 3 and
-            segments[0] == "principals" and segments[1] == "__uids__"):
-            uid = segments[2]
-        else:
-            raise ValueError("Can't resolve all paths yet")
+ at inlineCallbacks
+def runSearch(service, rootResource, directory, store, searchTerm):
 
-        if checkOnly:
-            return None
+    fields = []
+    for fieldName in ("fullName", "firstName", "lastName", "emailAddresses"):
+        fields.append((fieldName, searchTerm, True, "contains"))
 
-        return directory.principalCollection.principalForUID(uid)
+    records = list((yield directory.recordsMatchingTokens(searchTerm.strip().split())))
+    if records:
+        records.sort(key=operator.attrgetter('fullName'))
+        print("%d matches found:" % (len(records),))
+        for record in records:
+            print("\n%s (%s)" % (record.fullName,
+                { "users"     : "User",
+                  "groups"    : "Group",
+                  "locations" : "Place",
+                  "resources" : "Resource",
+                }.get(record.recordType),
+            ))
+            print("   GUID: %s" % (record.guid,))
+            print("   Record name(s): %s" % (", ".join(record.shortNames),))
+            if record.authIDs:
+                print("   Auth ID(s): %s" % (", ".join(record.authIDs),))
+            if record.emailAddresses:
+                print("   Email(s): %s" % (", ".join(record.emailAddresses),))
+    else:
+        print("No matches found")
 
+    print("")
 
-    if principalID.startswith("("):
-        try:
-            i = principalID.index(")")
 
-            if checkOnly:
-                return None
-
-            recordType = principalID[1:i]
-            shortName = principalID[i+1:]
-
-            if not recordType or not shortName or "(" in recordType:
-                raise ValueError()
-
-            return directory.principalCollection.principalForShortName(recordType, shortName)
-
-        except ValueError:
-            pass
-
-    if ":" in principalID:
-        if checkOnly:
-            return None
-
-        recordType, shortName = principalID.split(":", 1)
-
-        return directory.principalCollection.principalForShortName(recordType, shortName)
-
+ at inlineCallbacks
+def runAddPrincipal(service, rootResource, directory, store, addType, guid,
+    shortNames, fullName):
     try:
-        UUID(principalID)
+        yield updateRecord(True, directory, addType, guid=guid,
+            shortNames=shortNames, fullName=fullName)
+        print("Added '%s'" % (fullName,))
+    except DirectoryError, e:
+        print(e)
 
-        if checkOnly:
-            return None
 
-        x = directory.principalCollection.principalForUID(principalID)
-        return x
-    except ValueError:
-        pass
-
-    raise ValueError("Invalid principal identifier: %s" % (principalID,))
-
-def proxySubprincipal(principal, proxyType):
-    return principal.getChild("calendar-proxy-" + proxyType)
-
-def action_removePrincipal(principal):
+def action_removePrincipal(rootResource, directory, store, principal):
     record = principal.record
     fullName = record.fullName
     shortName = record.shortNames[0]
     guid = record.guid
 
-    config.directory.destroyRecord(record.recordType, guid=guid)
+    directory.destroyRecord(record.recordType, guid=guid)
     print("Removed '%s' %s %s" % (fullName, shortName, guid))
 
 
 @inlineCallbacks
-def action_readProperty(resource, qname):
+def action_readProperty(rootResource, directory, store, resource, qname):
     property = (yield resource.readProperty(qname, None))
     print("%r on %s:" % (encodeXMLName(*qname), resource))
     print("")
     print(property.toxml())
 
 @inlineCallbacks
-def action_listProxies(principal, *proxyTypes):
+def action_listProxies(rootResource, directory, store, principal, *proxyTypes):
     for proxyType in proxyTypes:
         subPrincipal = proxySubprincipal(principal, proxyType)
         if subPrincipal is None:
@@ -553,7 +454,7 @@
             records = []
             for member in membersProperty.children:
                 proxyPrincipal = principalForPrincipalID(str(member),
-                    directory=config.directory)
+                    directory=directory)
                 records.append(proxyPrincipal.record)
 
             printRecordList(records)
@@ -563,59 +464,21 @@
                 prettyPrincipal(principal)))
 
 @inlineCallbacks
-def action_addProxy(principal, proxyType, *proxyIDs):
+def action_addProxy(rootResource, directory, store, principal, proxyType, *proxyIDs):
     for proxyID in proxyIDs:
-        proxyPrincipal = principalForPrincipalID(proxyID)
+        proxyPrincipal = principalForPrincipalID(proxyID, directory=directory)
         if proxyPrincipal is None:
             print("Invalid principal ID: %s" % (proxyID,))
         else:
-            (yield action_addProxyPrincipal(principal, proxyType, proxyPrincipal))
+            (yield action_addProxyPrincipal(rootResource, directory, store, 
+                principal, proxyType, proxyPrincipal))
 
- at inlineCallbacks
-def action_addProxyPrincipal(principal, proxyType, proxyPrincipal):
-    try:
-        (yield addProxy(principal, proxyType, proxyPrincipal))
-        print("Added %s as a %s proxy for %s" % (
-            prettyPrincipal(proxyPrincipal), proxyType,
-            prettyPrincipal(principal)))
-    except ProxyError, e:
-        print("Error:", e)
-    except ProxyWarning, e:
-        print(e)
 
- at inlineCallbacks
-def addProxy(principal, proxyType, proxyPrincipal):
-    proxyURL = proxyPrincipal.url()
 
-    subPrincipal = proxySubprincipal(principal, proxyType)
-    if subPrincipal is None:
-        raise ProxyError("Unable to edit %s proxies for %s\n" % (proxyType,
-            prettyPrincipal(principal)))
 
-    membersProperty = (yield subPrincipal.readProperty(davxml.GroupMemberSet, None))
 
-    for memberURL in membersProperty.children:
-        if str(memberURL) == proxyURL:
-            raise ProxyWarning("%s is already a %s proxy for %s" % (
-                prettyPrincipal(proxyPrincipal), proxyType,
-                prettyPrincipal(principal)))
-
-    else:
-        memberURLs = list(membersProperty.children)
-        memberURLs.append(davxml.HRef(proxyURL))
-        membersProperty = davxml.GroupMemberSet(*memberURLs)
-        (yield subPrincipal.writeProperty(membersProperty, None))
-
-    proxyTypes = ["read", "write"]
-    proxyTypes.remove(proxyType)
-
-    (yield action_removeProxyPrincipal(principal, proxyPrincipal, proxyTypes=proxyTypes))
-
-    triggerGroupCacherUpdate(config)
-
-
 @inlineCallbacks
-def setProxies(principal, readProxyPrincipals, writeProxyPrincipals, directory=None):
+def setProxies(store, principal, readProxyPrincipals, writeProxyPrincipals, directory=None):
     """
     Set read/write proxies en masse for a principal
     @param principal: DirectoryPrincipalResource
@@ -640,8 +503,10 @@
             proxyURL = proxyPrincipal.url()
             memberURLs.append(davxml.HRef(proxyURL))
         membersProperty = davxml.GroupMemberSet(*memberURLs)
-        (yield subPrincipal.writeProperty(membersProperty, None))
-        triggerGroupCacherUpdate(config)
+        yield subPrincipal.writeProperty(membersProperty, None)
+        if store is not None:
+            # Schedule work the PeerConnectionPool will pick up as overdue
+            yield schedulePolledGroupCachingUpdate(store)
 
 
 @inlineCallbacks
@@ -668,63 +533,20 @@
 
 
 @inlineCallbacks
-def action_removeProxy(principal, *proxyIDs, **kwargs):
+def action_removeProxy(rootResource, directory, store, principal, *proxyIDs, **kwargs):
     for proxyID in proxyIDs:
-        proxyPrincipal = principalForPrincipalID(proxyID)
+        proxyPrincipal = principalForPrincipalID(proxyID, directory=directory)
         if proxyPrincipal is None:
             print("Invalid principal ID: %s" % (proxyID,))
         else:
-            (yield action_removeProxyPrincipal(principal, proxyPrincipal, **kwargs))
+            (yield action_removeProxyPrincipal(rootResource, directory, store,
+                principal, proxyPrincipal, **kwargs))
 
- at inlineCallbacks
-def action_removeProxyPrincipal(principal, proxyPrincipal, **kwargs):
-    try:
-        removed = (yield removeProxy(principal, proxyPrincipal, **kwargs))
-        if removed:
-            print("Removed %s as a proxy for %s" % (
-                prettyPrincipal(proxyPrincipal),
-                prettyPrincipal(principal)))
-    except ProxyError, e:
-        print("Error:", e)
-    except ProxyWarning, e:
-        print(e)
 
 
- at inlineCallbacks
-def removeProxy(principal, proxyPrincipal, **kwargs):
-    removed = False
-    proxyTypes = kwargs.get("proxyTypes", ("read", "write"))
-    for proxyType in proxyTypes:
-        proxyURL = proxyPrincipal.url()
 
-        subPrincipal = proxySubprincipal(principal, proxyType)
-        if subPrincipal is None:
-            raise ProxyError("Unable to edit %s proxies for %s\n" % (proxyType,
-                prettyPrincipal(principal)))
-
-        membersProperty = (yield subPrincipal.readProperty(davxml.GroupMemberSet, None))
-
-        memberURLs = [
-            m for m in membersProperty.children
-            if str(m) != proxyURL
-        ]
-
-        if len(memberURLs) == len(membersProperty.children):
-            # No change
-            continue
-        else:
-            removed = True
-
-        membersProperty = davxml.GroupMemberSet(*memberURLs)
-        (yield subPrincipal.writeProperty(membersProperty, None))
-
-    if removed:
-        triggerGroupCacherUpdate(config)
-    returnValue(removed)
-
-
 @inlineCallbacks
-def action_setAutoSchedule(principal, autoSchedule):
+def action_setAutoSchedule(rootResource, directory, store, principal, autoSchedule):
     if principal.record.recordType == "groups":
         print("Enabling auto-schedule for %s is not allowed." % (principal,))
 
@@ -737,7 +559,7 @@
             prettyPrincipal(principal),
         ))
 
-        (yield updateRecord(False, config.directory,
+        (yield updateRecord(False, directory,
             principal.record.recordType,
             guid=principal.record.guid,
             shortNames=principal.record.shortNames,
@@ -746,7 +568,7 @@
             **principal.record.extras
         ))
 
-def action_getAutoSchedule(principal):
+def action_getAutoSchedule(rootResource, directory, store, principal):
     autoSchedule = principal.getAutoSchedule()
     print("Auto-schedule for %s is %s" % (
         prettyPrincipal(principal),
@@ -754,7 +576,7 @@
     ))
 
 @inlineCallbacks
-def action_setAutoScheduleMode(principal, autoScheduleMode):
+def action_setAutoScheduleMode(rootResource, directory, store, principal, autoScheduleMode):
     if principal.record.recordType == "groups":
         print("Setting auto-schedule mode for %s is not allowed." % (principal,))
 
@@ -767,7 +589,7 @@
             prettyPrincipal(principal),
         ))
 
-        (yield updateRecord(False, config.directory,
+        (yield updateRecord(False, directory,
             principal.record.recordType,
             guid=principal.record.guid,
             shortNames=principal.record.shortNames,
@@ -776,7 +598,7 @@
             **principal.record.extras
         ))
 
-def action_getAutoScheduleMode(principal):
+def action_getAutoScheduleMode(rootResource, directory, store, principal):
     autoScheduleMode = principal.getAutoScheduleMode()
     if not autoScheduleMode:
         autoScheduleMode = "automatic"
@@ -786,7 +608,7 @@
     ))
 
 @inlineCallbacks
-def action_setAutoAcceptGroup(principal, autoAcceptGroup):
+def action_setAutoAcceptGroup(rootResource, directory, store, principal, autoAcceptGroup):
     if principal.record.recordType == "groups":
         print("Setting auto-accept-group for %s is not allowed." % (principal,))
 
@@ -794,7 +616,7 @@
         print("Setting auto-accept-group for %s is not allowed." % (principal,))
 
     else:
-        groupPrincipal = principalForPrincipalID(autoAcceptGroup)
+        groupPrincipal = principalForPrincipalID(autoAcceptGroup, directory=directory)
         if groupPrincipal is None or groupPrincipal.record.recordType != "groups":
             print("Invalid principal ID: %s" % (autoAcceptGroup,))
         else:
@@ -803,7 +625,7 @@
                 prettyPrincipal(principal),
             ))
 
-            (yield updateRecord(False, config.directory,
+            (yield updateRecord(False, directory,
                 principal.record.recordType,
                 guid=principal.record.guid,
                 shortNames=principal.record.shortNames,
@@ -812,12 +634,12 @@
                 **principal.record.extras
             ))
 
-def action_getAutoAcceptGroup(principal):
+def action_getAutoAcceptGroup(rootResource, directory, store, principal):
     autoAcceptGroup = principal.getAutoAcceptGroup()
     if autoAcceptGroup:
-        record = config.directory.recordWithGUID(autoAcceptGroup)
+        record = directory.recordWithGUID(autoAcceptGroup)
         if record is not None:
-            groupPrincipal = config.directory.principalCollection.principalForUID(record.uid)
+            groupPrincipal = directory.principalCollection.principalForUID(record.uid)
             if groupPrincipal is not None:
                 print("Auto-accept-group for %s is %s" % (
                     prettyPrincipal(principal),
@@ -837,17 +659,7 @@
         pass
     sys.exit(status)
 
-class ProxyError(Exception):
-    """
-    Raised when proxy assignments cannot be performed
-    """
 
-class ProxyWarning(Exception):
-    """
-    Raised for harmless proxy assignment failures such as trying to add a
-    duplicate or remove a non-existent assignment.
-    """
-
 def parseCreationArgs(args):
     """
     Look at the command line arguments for --add, and figure out which
@@ -900,10 +712,6 @@
     for fullName, shortName, guid in results:
         print(format % (fullName, shortName, guid))
 
-def prettyPrincipal(principal):
-    record = principal.record
-    return "\"%s\" (%s:%s)" % (record.fullName, record.recordType,
-        record.shortNames[0])
 
 
 @inlineCallbacks
@@ -984,28 +792,6 @@
     returnValue(record)
 
 
-def triggerGroupCacherUpdate(config, killMethod=None):
-    """
-    Look up the pid of the group cacher sidecar and HUP it to trigger an update
-    """
-    if killMethod is None:
-        killMethod = os.kill
 
-    pidFilename = os.path.join(config.RunRoot, "groupcacher.pid")
-    if os.path.exists(pidFilename):
-        pidFile = open(pidFilename, "r")
-        pid = pidFile.read().strip()
-        pidFile.close()
-        try:
-            pid = int(pid)
-        except ValueError:
-            return
-        try:
-            killMethod(pid, signal.SIGHUP)
-        except OSError:
-            pass
-
-
-
 if __name__ == "__main__":
     main()

Modified: CalendarServer/branches/users/gaya/directorybacker/calendarserver/tools/purge.py
===================================================================
--- CalendarServer/branches/users/gaya/directorybacker/calendarserver/tools/purge.py	2013-04-22 18:44:41 UTC (rev 11082)
+++ CalendarServer/branches/users/gaya/directorybacker/calendarserver/tools/purge.py	2013-04-22 18:46:28 UTC (rev 11083)
@@ -18,12 +18,10 @@
 from __future__ import print_function
 
 from calendarserver.tap.util import FakeRequest
-from calendarserver.tap.util import getRootResource
 from calendarserver.tools import tables
-from calendarserver.tools.cmdline import utilityMain
-from calendarserver.tools.principals import removeProxy
+from calendarserver.tools.cmdline import utilityMain, WorkerService
+from calendarserver.tools.util import removeProxy
 
-from errno import ENOENT, EACCES
 from getopt import getopt, GetoptError
 
 from pycalendar.datetime import PyCalendarDateTime
@@ -31,13 +29,10 @@
 from twext.python.log import Logger
 from twext.web2.responsecode import NO_CONTENT
 
-from twisted.application.service import Service
-from twisted.internet import reactor
 from twisted.internet.defer import inlineCallbacks, returnValue
 
 from twistedcaldav import caldavxml
 from twistedcaldav.caldavxml import TimeRange
-from twistedcaldav.config import config, ConfigurationError
 from twistedcaldav.datafilters.peruserdata import PerUserDataFilter
 from twistedcaldav.directory.directory import DirectoryRecord
 from twistedcaldav.method.put_common import StoreCalendarObjectResource
@@ -45,6 +40,7 @@
 
 from txdav.xml import element as davxml
 
+
 import collections
 import os
 import sys
@@ -54,49 +50,9 @@
 DEFAULT_BATCH_SIZE = 100
 DEFAULT_RETAIN_DAYS = 365
 
-class WorkerService(Service):
 
-    def __init__(self, store):
-        self._store = store
 
 
-    def rootResource(self):
-        try:
-            rootResource = getRootResource(config, self._store)
-        except OSError, e:
-            if e.errno == ENOENT:
-                # Trying to re-write resources.xml but its parent directory does
-                # not exist.  The server's never been started, so we're missing
-                # state required to do any work.  (Plus, what would be the point
-                # of purging stuff from a server that's completely empty?)
-                raise ConfigurationError(
-                    "It appears that the server has never been started.\n"
-                    "Please start it at least once before purging anything.")
-            elif e.errno == EACCES:
-                # Trying to re-write resources.xml but it is not writable by the
-                # current user.  This most likely means we're in a system
-                # configuration and the user doesn't have sufficient privileges
-                # to do the other things the tool might need to do either.
-                raise ConfigurationError("You must run this tool as root.")
-            else:
-                raise
-        return rootResource
-
-
-    @inlineCallbacks
-    def startService(self):
-        try:
-            yield self.doWork()
-        except ConfigurationError, ce:
-            sys.stderr.write("Error: %s\n" % (str(ce),))
-        except Exception, e:
-            sys.stderr.write("Error: %s\n" % (e,))
-            raise
-        finally:
-            reactor.stop()
-
-
-
 class PurgeOldEventsService(WorkerService):
 
     cutoff = None
@@ -1163,9 +1119,8 @@
             return cls.CANCELEVENT_NOT_MODIFIED
 
 
-    @classmethod
     @inlineCallbacks
-    def _purgeProxyAssignments(cls, principal):
+    def _purgeProxyAssignments(self, principal):
 
         assignments = []
 
@@ -1174,7 +1129,7 @@
             proxyFor = (yield principal.proxyFor(proxyType == "write"))
             for other in proxyFor:
                 assignments.append((principal.record.uid, proxyType, other.record.uid))
-                (yield removeProxy(other, principal))
+                (yield removeProxy(self.root, self.directory, self._store, other, principal))
 
             subPrincipal = principal.getChild("calendar-proxy-" + proxyType)
             proxies = (yield subPrincipal.readProperty(davxml.GroupMemberSet, None))

Modified: CalendarServer/branches/users/gaya/directorybacker/calendarserver/tools/test/gateway/caldavd.plist
===================================================================
--- CalendarServer/branches/users/gaya/directorybacker/calendarserver/tools/test/gateway/caldavd.plist	2013-04-22 18:44:41 UTC (rev 11082)
+++ CalendarServer/branches/users/gaya/directorybacker/calendarserver/tools/test/gateway/caldavd.plist	2013-04-22 18:46:28 UTC (rev 11083)
@@ -718,6 +718,10 @@
     <integer>30</integer> <!-- in minutes -->
 
 
+    <!-- For unit tests, enable SharedConnectionPool so we don't use up shared memory -->
+    <key>SharedConnectionPool</key>
+    <true/>
+
     <!--
         Twisted
       -->

Modified: CalendarServer/branches/users/gaya/directorybacker/calendarserver/tools/test/principals/caldavd.plist
===================================================================
--- CalendarServer/branches/users/gaya/directorybacker/calendarserver/tools/test/principals/caldavd.plist	2013-04-22 18:44:41 UTC (rev 11082)
+++ CalendarServer/branches/users/gaya/directorybacker/calendarserver/tools/test/principals/caldavd.plist	2013-04-22 18:46:28 UTC (rev 11083)
@@ -79,23 +79,23 @@
 
     <!-- Data root -->
     <key>DataRoot</key>
-    <string>Data</string>
+    <string>%(DataRoot)s</string>
 
     <!-- Document root -->
     <key>DocumentRoot</key>
-    <string>Documents</string>
+    <string>%(DocumentRoot)s</string>
 
     <!-- Configuration root -->
     <key>ConfigRoot</key>
-    <string>/etc/caldavd</string>
+    <string>Config</string>
 
     <!-- Log root -->
     <key>LogRoot</key>
-    <string>/var/log/caldavd</string>
+    <string>%(LogRoot)s</string>
 
     <!-- Run root -->
     <key>RunRoot</key>
-    <string>/var/run</string>
+    <string>%(LogRoot)s</string>
 
     <!-- Child aliases -->
     <key>Aliases</key>
@@ -279,7 +279,7 @@
      -->
 
 	<key>ProxyLoadFromFile</key>
-    <string>conf/auth/proxies-test.xml</string>
+    <string></string>
 
     <!--
         Special principals
@@ -743,6 +743,9 @@
     <key>ResponseCacheTimeout</key>
     <integer>30</integer> <!-- in minutes -->
 
+    <!-- For unit tests, enable SharedConnectionPool so we don't use up shared memory -->
+    <key>SharedConnectionPool</key>
+    <true/>
 
     <!--
         Twisted

Modified: CalendarServer/branches/users/gaya/directorybacker/calendarserver/tools/test/test_calverify.py
===================================================================
--- CalendarServer/branches/users/gaya/directorybacker/calendarserver/tools/test/test_calverify.py	2013-04-22 18:44:41 UTC (rev 11082)
+++ CalendarServer/branches/users/gaya/directorybacker/calendarserver/tools/test/test_calverify.py	2013-04-22 18:46:28 UTC (rev 11083)
@@ -19,10 +19,11 @@
 Tests for calendarserver.tools.calverify
 """
 
+from calendarserver.tools.calverify import BadDataService, \
+    SchedulingMismatchService, DoubleBookingService, DarkPurgeService
+
 from StringIO import StringIO
 from calendarserver.tap.util import getRootResource
-from calendarserver.tools.calverify import BadDataService, \
-    SchedulingMismatchService, DoubleBookingService
 from pycalendar.datetime import PyCalendarDateTime
 from twisted.internet import reactor
 from twisted.internet.defer import inlineCallbacks, returnValue
@@ -2525,67 +2526,338 @@
         self.assertEqual(sync_token_oldl1, sync_token_newl1)
 
 
-    def test_instance(self):
-        """
-        CalVerifyService.doScan without fix for mismatches. Make sure it detects
-        as much as it can. Make sure sync-token is not changed.
-        """
 
-        s = """BEGIN:VCALENDAR
+class CalVerifyDarkPurge(CalVerifyMismatchTestsBase):
+    """
+    Tests calverify for events.
+    """
+
+    # No organizer
+    INVITE_NO_ORGANIZER_ICS = """BEGIN:VCALENDAR
 VERSION:2.0
+PRODID:-//Apple Inc.//iCal 4.0.1//EN
 CALSCALE:GREGORIAN
-PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
-BEGIN:VTIMEZONE
-TZID:America/Los_Angeles
-BEGIN:DAYLIGHT
-DTSTART:20070311T020000
-RRULE:FREQ=YEARLY;BYDAY=2SU;BYMONTH=3
-TZNAME:PDT
-TZOFFSETFROM:-0800
-TZOFFSETTO:-0700
-END:DAYLIGHT
-BEGIN:STANDARD
-DTSTART:20071104T020000
-RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=11
-TZNAME:PST
-TZOFFSETFROM:-0700
-TZOFFSETTO:-0800
-END:STANDARD
-END:VTIMEZONE
 BEGIN:VEVENT
-UID:4760FF93-C7F8-4EB0-B3E8-0B22A96DB1BC
-DTSTART;TZID=America/Los_Angeles:20130221T170000
-DTEND;TZID=America/Los_Angeles:20130221T180000
-ATTENDEE;CN=Casa Blanca APPLE EMP ONLY (12) DA03 4th;CUTYPE=ROOM;PARTSTAT=
- ACCEPTED;ROLE=REQ-PARTICIPANT:urn:uuid:366CC7BE-FEF7-4FFF-B713-6B883538A24
- 9
-ATTENDEE;CN=Mark Chu;CUTYPE=INDIVIDUAL;EMAIL=markchu at apple.com;PARTSTAT=AC
- CEPTED;ROLE=REQ-PARTICIPANT:urn:uuid:46F9D5D9-08E8-4987-9636-CC796F4093C6
-ATTENDEE;CN=Kristie Phan;CUTYPE=INDIVIDUAL;EMAIL=kristie_phan at apple.com;PA
- RTSTAT=ACCEPTED:urn:uuid:97E8720F-4364-DBEC-6721-123E9A92B980
-CREATED:20130220T200530Z
-DTSTAMP:20130222T002246Z
-EXDATE:20130228T010000Z
-EXDATE:20130314T000000Z
-EXDATE:20130321T000000Z
-EXDATE:20130327T000000Z
-EXDATE:20130328T000000Z
-EXDATE:20130403T000000Z
-LOCATION:Casa Blanca APPLE EMP ONLY (12) DA03 4th
-ORGANIZER;CN=Kristie Phan;EMAIL=kristie_phan at apple.com;SCHEDULE-STATUS=1.2
- :urn:uuid:97E8720F-4364-DBEC-6721-123E9A92B980
-RRULE:FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,FR;WKST=SU
-SEQUENCE:13
-SUMMARY:ESD Daily Meeting
+CREATED:20100303T181216Z
+UID:INVITE_NO_ORGANIZER_ICS
+TRANSP:OPAQUE
+SUMMARY:INVITE_NO_ORGANIZER_ICS
+DTSTART:%(year)s%(month)02d07T100000Z
+DURATION:PT1H
+DTSTAMP:20100303T181220Z
+SEQUENCE:2
 END:VEVENT
 END:VCALENDAR
-"""
-        from twistedcaldav.ical import Component
-        c = Component.fromString(s)
-        start = PyCalendarDateTime.getToday()
-        start.setDateOnly(False)
-        end = start.duplicate()
-        end.offsetDay(30)
-        config.MaxAllowedInstances = 3000
-        i = c.expandTimeRanges(end, start, ignoreInvalidInstances=True)
-        print(i)
+""".replace("\n", "\r\n") % {"year": nowYear, "month": nowMonth}
+
+    # Valid organizer
+    INVITE_VALID_ORGANIZER_ICS = """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//Apple Inc.//iCal 4.0.1//EN
+CALSCALE:GREGORIAN
+BEGIN:VEVENT
+CREATED:20100303T181216Z
+UID:INVITE_VALID_ORGANIZER_ICS
+TRANSP:OPAQUE
+SUMMARY:INVITE_VALID_ORGANIZER_ICS
+DTSTART:%(year)s%(month)02d08T100000Z
+DURATION:PT1H
+DTSTAMP:20100303T181220Z
+SEQUENCE:2
+ORGANIZER:urn:uuid:D46F3D71-04B7-43C2-A7B6-6F92F92E61D0
+ATTENDEE:urn:uuid:D46F3D71-04B7-43C2-A7B6-6F92F92E61D0
+ATTENDEE:urn:uuid:75EA36BE-F71B-40F9-81F9-CF59BF40CA8F
+END:VEVENT
+END:VCALENDAR
+""".replace("\n", "\r\n") % {"year": nowYear, "month": nowMonth}
+
+    # Invalid organizer #1
+    INVITE_INVALID_ORGANIZER_1_ICS = """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//Apple Inc.//iCal 4.0.1//EN
+CALSCALE:GREGORIAN
+BEGIN:VEVENT
+CREATED:20100303T181216Z
+UID:INVITE_INVALID_ORGANIZER_1_ICS
+TRANSP:OPAQUE
+SUMMARY:INVITE_INVALID_ORGANIZER_1_ICS
+DTSTART:%(year)s%(month)02d09T100000Z
+DURATION:PT1H
+DTSTAMP:20100303T181220Z
+SEQUENCE:2
+ORGANIZER:urn:uuid:D46F3D71-04B7-43C2-A7B6-6F92F92E61D0-1
+ATTENDEE:urn:uuid:D46F3D71-04B7-43C2-A7B6-6F92F92E61D0-1
+ATTENDEE:urn:uuid:75EA36BE-F71B-40F9-81F9-CF59BF40CA8F
+END:VEVENT
+END:VCALENDAR
+""".replace("\n", "\r\n") % {"year": nowYear, "month": nowMonth}
+
+    # Invalid organizer #2
+    INVITE_INVALID_ORGANIZER_2_ICS = """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//Apple Inc.//iCal 4.0.1//EN
+CALSCALE:GREGORIAN
+BEGIN:VEVENT
+CREATED:20100303T181216Z
+UID:INVITE_INVALID_ORGANIZER_2_ICS
+TRANSP:OPAQUE
+SUMMARY:INVITE_INVALID_ORGANIZER_2_ICS
+DTSTART:%(year)s%(month)02d10T100000Z
+DURATION:PT1H
+DTSTAMP:20100303T181220Z
+SEQUENCE:2
+ORGANIZER:mailto:foobar at example.com
+ATTENDEE:mailto:foobar at example.com
+ATTENDEE:urn:uuid:75EA36BE-F71B-40F9-81F9-CF59BF40CA8F
+END:VEVENT
+END:VCALENDAR
+""".replace("\n", "\r\n") % {"year": nowYear, "month": nowMonth}
+
+    allEvents = {
+        "invite1.ics"      : (INVITE_NO_ORGANIZER_ICS, CalVerifyMismatchTestsBase.metadata,),
+        "invite2.ics"      : (INVITE_VALID_ORGANIZER_ICS, CalVerifyMismatchTestsBase.metadata,),
+        "invite3.ics"      : (INVITE_INVALID_ORGANIZER_1_ICS, CalVerifyMismatchTestsBase.metadata,),
+        "invite4.ics"      : (INVITE_INVALID_ORGANIZER_2_ICS, CalVerifyMismatchTestsBase.metadata,),
+    }
+
+    requirements = {
+        CalVerifyMismatchTestsBase.uuid1 : {
+            "calendar" : {},
+            "inbox" : {},
+        },
+        CalVerifyMismatchTestsBase.uuid2 : {
+            "calendar" : {},
+            "inbox" : {},
+        },
+        CalVerifyMismatchTestsBase.uuid3 : {
+            "calendar" : {},
+            "inbox" : {},
+        },
+        CalVerifyMismatchTestsBase.uuidl1 : {
+            "calendar" : allEvents,
+            "inbox" : {},
+        },
+    }
+
+    @inlineCallbacks
+    def test_scanDarkEvents(self):
+        """
+        CalVerifyService.doScan without fix for dark events. Make sure it detects
+        as much as it can. Make sure sync-token is not changed.
+        """
+
+        sync_token_oldl1 = (yield (yield self.calendarUnderTest(self.uuidl1)).syncToken())
+        self.commit()
+
+        options = {
+            "ical": False,
+            "badcua": False,
+            "mismatch": False,
+            "nobase64": False,
+            "double": True,
+            "dark-purge": False,
+            "fix": False,
+            "verbose": False,
+            "details": False,
+            "summary": False,
+            "days": 365,
+            "uid": "",
+            "uuid": self.uuidl1,
+            "tzid": "utc",
+            "start": PyCalendarDateTime(nowYear, 1, 1, 0, 0, 0),
+            "no-organizer": False,
+            "invalid-organizer": False,
+            "disabled-organizer": False,
+        }
+        output = StringIO()
+        calverify = DarkPurgeService(self._sqlCalendarStore, options, output, reactor, config)
+        yield calverify.doAction()
+
+        self.assertEqual(calverify.results["Number of events to process"], len(self.requirements[CalVerifyMismatchTestsBase.uuidl1]["calendar"]))
+        self.assertEqual(
+            sorted([i.uid for i in calverify.results["Dark Events"]]),
+            ["INVITE_INVALID_ORGANIZER_1_ICS", "INVITE_INVALID_ORGANIZER_2_ICS", ]
+        )
+        self.assertEqual(calverify.results["Number of dark events"], 2)
+        self.assertTrue("Fix dark events" not in calverify.results)
+        self.assertTrue("Fix remove" not in calverify.results)
+
+        sync_token_newl1 = (yield (yield self.calendarUnderTest(self.uuidl1)).syncToken())
+        self.assertEqual(sync_token_oldl1, sync_token_newl1)
+
+
+    @inlineCallbacks
+    def test_fixDarkEvents(self):
+        """
+        CalVerifyService.doScan with fix for dark events. Make sure it detects
+        as much as it can. Make sure sync-token is changed.
+        """
+
+        sync_token_oldl1 = (yield (yield self.calendarUnderTest(self.uuidl1)).syncToken())
+        self.commit()
+
+        options = {
+            "ical": False,
+            "badcua": False,
+            "mismatch": False,
+            "nobase64": False,
+            "double": True,
+            "dark-purge": False,
+            "fix": True,
+            "verbose": False,
+            "details": False,
+            "summary": False,
+            "days": 365,
+            "uid": "",
+            "uuid": self.uuidl1,
+            "tzid": "utc",
+            "start": PyCalendarDateTime(nowYear, 1, 1, 0, 0, 0),
+            "no-organizer": False,
+            "invalid-organizer": False,
+            "disabled-organizer": False,
+        }
+        output = StringIO()
+        calverify = DarkPurgeService(self._sqlCalendarStore, options, output, reactor, config)
+        yield calverify.doAction()
+
+        self.assertEqual(calverify.results["Number of events to process"], len(self.requirements[CalVerifyMismatchTestsBase.uuidl1]["calendar"]))
+        self.assertEqual(
+            sorted([i.uid for i in calverify.results["Dark Events"]]),
+            ["INVITE_INVALID_ORGANIZER_1_ICS", "INVITE_INVALID_ORGANIZER_2_ICS", ]
+        )
+        self.assertEqual(calverify.results["Number of dark events"], 2)
+        self.assertEqual(calverify.results["Fix dark events"], 2)
+        self.assertTrue("Fix remove" in calverify.results)
+
+        sync_token_newl1 = (yield (yield self.calendarUnderTest(self.uuidl1)).syncToken())
+        self.assertNotEqual(sync_token_oldl1, sync_token_newl1)
+
+        # Re-scan after changes to make sure there are no errors
+        self.commit()
+        options["fix"] = False
+        options["uuid"] = self.uuidl1
+        calverify = DarkPurgeService(self._sqlCalendarStore, options, output, reactor, config)
+        yield calverify.doAction()
+
+        self.assertEqual(calverify.results["Number of events to process"], 2)
+        self.assertEqual(len(calverify.results["Dark Events"]), 0)
+        self.assertTrue("Fix dark events" not in calverify.results)
+        self.assertTrue("Fix remove" not in calverify.results)
+
+
+    @inlineCallbacks
+    def test_fixDarkEventsNoOrganizerOnly(self):
+        """
+        CalVerifyService.doScan with fix for dark events. Make sure it detects
+        as much as it can. Make sure sync-token is changed.
+        """
+
+        sync_token_oldl1 = (yield (yield self.calendarUnderTest(self.uuidl1)).syncToken())
+        self.commit()
+
+        options = {
+            "ical": False,
+            "badcua": False,
+            "mismatch": False,
+            "nobase64": False,
+            "double": True,
+            "dark-purge": False,
+            "fix": True,
+            "verbose": False,
+            "details": False,
+            "summary": False,
+            "days": 365,
+            "uid": "",
+            "uuid": self.uuidl1,
+            "tzid": "utc",
+            "start": PyCalendarDateTime(nowYear, 1, 1, 0, 0, 0),
+            "no-organizer": True,
+            "invalid-organizer": False,
+            "disabled-organizer": False,
+        }
+        output = StringIO()
+        calverify = DarkPurgeService(self._sqlCalendarStore, options, output, reactor, config)
+        yield calverify.doAction()
+
+        self.assertEqual(calverify.results["Number of events to process"], len(self.requirements[CalVerifyMismatchTestsBase.uuidl1]["calendar"]))
+        self.assertEqual(
+            sorted([i.uid for i in calverify.results["Dark Events"]]),
+            ["INVITE_NO_ORGANIZER_ICS", ]
+        )
+        self.assertEqual(calverify.results["Number of dark events"], 1)
+        self.assertEqual(calverify.results["Fix dark events"], 1)
+        self.assertTrue("Fix remove" in calverify.results)
+
+        sync_token_newl1 = (yield (yield self.calendarUnderTest(self.uuidl1)).syncToken())
+        self.assertNotEqual(sync_token_oldl1, sync_token_newl1)
+
+        # Re-scan after changes to make sure there are no errors
+        self.commit()
+        options["fix"] = False
+        options["uuid"] = self.uuidl1
+        calverify = DarkPurgeService(self._sqlCalendarStore, options, output, reactor, config)
+        yield calverify.doAction()
+
+        self.assertEqual(calverify.results["Number of events to process"], 3)
+        self.assertEqual(len(calverify.results["Dark Events"]), 0)
+        self.assertTrue("Fix dark events" not in calverify.results)
+        self.assertTrue("Fix remove" not in calverify.results)
+
+
+    @inlineCallbacks
+    def test_fixDarkEventsAllTypes(self):
+        """
+        CalVerifyService.doScan with fix for dark events. Make sure it detects
+        as much as it can. Make sure sync-token is changed.
+        """
+
+        sync_token_oldl1 = (yield (yield self.calendarUnderTest(self.uuidl1)).syncToken())
+        self.commit()
+
+        options = {
+            "ical": False,
+            "badcua": False,
+            "mismatch": False,
+            "nobase64": False,
+            "double": True,
+            "dark-purge": False,
+            "fix": True,
+            "verbose": False,
+            "details": False,
+            "summary": False,
+            "days": 365,
+            "uid": "",
+            "uuid": self.uuidl1,
+            "tzid": "utc",
+            "start": PyCalendarDateTime(nowYear, 1, 1, 0, 0, 0),
+            "no-organizer": True,
+            "invalid-organizer": True,
+            "disabled-organizer": True,
+        }
+        output = StringIO()
+        calverify = DarkPurgeService(self._sqlCalendarStore, options, output, reactor, config)
+        yield calverify.doAction()
+
+        self.assertEqual(calverify.results["Number of events to process"], len(self.requirements[CalVerifyMismatchTestsBase.uuidl1]["calendar"]))
+        self.assertEqual(
+            sorted([i.uid for i in calverify.results["Dark Events"]]),
+            ["INVITE_INVALID_ORGANIZER_1_ICS", "INVITE_INVALID_ORGANIZER_2_ICS", "INVITE_NO_ORGANIZER_ICS", ]
+        )
+        self.assertEqual(calverify.results["Number of dark events"], 3)
+        self.assertEqual(calverify.results["Fix dark events"], 3)
+        self.assertTrue("Fix remove" in calverify.results)
+
+        sync_token_newl1 = (yield (yield self.calendarUnderTest(self.uuidl1)).syncToken())
+        self.assertNotEqual(sync_token_oldl1, sync_token_newl1)
+
+        # Re-scan after changes to make sure there are no errors
+        self.commit()
+        options["fix"] = False
+        options["uuid"] = self.uuidl1
+        calverify = DarkPurgeService(self._sqlCalendarStore, options, output, reactor, config)
+        yield calverify.doAction()
+
+        self.assertEqual(calverify.results["Number of events to process"], 1)
+        self.assertEqual(len(calverify.results["Dark Events"]), 0)
+        self.assertTrue("Fix dark events" not in calverify.results)
+        self.assertTrue("Fix remove" not in calverify.results)

Modified: CalendarServer/branches/users/gaya/directorybacker/calendarserver/tools/test/test_config.py
===================================================================
--- CalendarServer/branches/users/gaya/directorybacker/calendarserver/tools/test/test_config.py	2013-04-22 18:44:41 UTC (rev 11082)
+++ CalendarServer/branches/users/gaya/directorybacker/calendarserver/tools/test/test_config.py	2013-04-22 18:46:28 UTC (rev 11083)
@@ -100,6 +100,8 @@
         self.assertEquals(results["result"]["EnableCalDAV"], True)
         self.assertEquals(results["result"]["EnableCardDAV"], True)
         self.assertEquals(results["result"]["EnableSSL"], False)
+        self.assertEquals(results["result"]["DefaultLogLevel"], "warn")
+
         self.assertEquals(results["result"]["Notifications"]["Services"]["APNS"]["Enabled"], False)
         self.assertEquals(results["result"]["Notifications"]["Services"]["APNS"]["CalDAV"]["CertificatePath"], "/example/calendar.cer")
 
@@ -119,6 +121,8 @@
         self.assertEquals(results["result"]["EnableSSL"], True)
         self.assertEquals(results["result"]["Notifications"]["Services"]["APNS"]["Enabled"], True)
         self.assertEquals(results["result"]["Notifications"]["Services"]["APNS"]["CalDAV"]["CertificatePath"], "/example/changed.cer")
+        dataRoot = "Data/%s/%s" % (unichr(208), u"\ud83d\udca3")
+        self.assertTrue(results["result"]["DataRoot"].endswith(dataRoot))
 
         # The static plist should still have EnableCalDAV = True
         staticPlist = plistlib.readPlist(self.configFileName)
@@ -204,10 +208,12 @@
             <true/>
             <key>Notifications.Services.APNS.CalDAV.CertificatePath</key>
             <string>/example/changed.cer</string>
+            <key>DataRoot</key>
+            <string>Data/%s/%s</string>
         </dict>
 </dict>
 </plist>
-"""
+""" % (unichr(208), u"\ud83d\udca3")
 
 command_bogusCommand = """<?xml version="1.0" encoding="UTF-8"?>
 <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">

Modified: CalendarServer/branches/users/gaya/directorybacker/calendarserver/tools/test/test_gateway.py
===================================================================
--- CalendarServer/branches/users/gaya/directorybacker/calendarserver/tools/test/test_gateway.py	2013-04-22 18:44:41 UTC (rev 11082)
+++ CalendarServer/branches/users/gaya/directorybacker/calendarserver/tools/test/test_gateway.py	2013-04-22 18:46:28 UTC (rev 11083)
@@ -124,7 +124,8 @@
         self.assertEquals(results["result"]["RecordName"], ["createdlocation01"])
         self.assertEquals(results["result"]["State"], "CA")
         self.assertEquals(results["result"]["Street"], "1 Infinite Loop")
-        self.assertEquals(results["result"]["RealName"], "Created Location 01 %s" % unichr(208))
+        self.assertEquals(results["result"]["RealName"],
+            "Created Location 01 %s %s" % (unichr(208), u"\ud83d\udca3" ))
         self.assertEquals(results["result"]["Comment"], "Test Comment")
         self.assertEquals(results["result"]["AutoSchedule"], True)
         self.assertEquals(results["result"]["AutoAcceptGroup"], "E5A6142C-4189-4E9E-90B0-9CD0268B314B")
@@ -151,7 +152,6 @@
 
         record = directory.recordWithUID("836B1B66-2E9A-4F46-8B1C-3DD6772C20B2")
         self.assertEquals(record, None)
-
         yield self.runCommand(command_createLocation)
 
         directory.flushCaches()
@@ -162,7 +162,8 @@
         augmentService.refresh()
 
         record = directory.recordWithUID("836B1B66-2E9A-4F46-8B1C-3DD6772C20B2")
-        self.assertEquals(record.fullName.decode("utf-8"), "Created Location 01 %s" % unichr(208))
+        self.assertEquals(record.fullName.decode("utf-8"),
+            "Created Location 01 %s %s" % (unichr(208), u"\ud83d\udca3"))
 
         self.assertNotEquals(record, None)
         self.assertEquals(record.autoSchedule, True)
@@ -334,7 +335,7 @@
         <key>GeneratedUID</key>
         <string>836B1B66-2E9A-4F46-8B1C-3DD6772C20B2</string>
         <key>RealName</key>
-        <string>Created Location 01 %s</string>
+        <string>Created Location 01 %s %s</string>
         <key>RecordName</key>
         <array>
                 <string>createdlocation01</string>
@@ -373,7 +374,7 @@
         </array>
 </dict>
 </plist>
-""" % unichr(208)
+""" % (unichr(208), u"\ud83d\udca3")
 
 
 command_createResource = """<?xml version="1.0" encoding="UTF-8"?>

Modified: CalendarServer/branches/users/gaya/directorybacker/calendarserver/tools/test/test_principals.py
===================================================================
--- CalendarServer/branches/users/gaya/directorybacker/calendarserver/tools/test/test_principals.py	2013-04-22 18:44:41 UTC (rev 11082)
+++ CalendarServer/branches/users/gaya/directorybacker/calendarserver/tools/test/test_principals.py	2013-04-22 18:46:28 UTC (rev 11083)
@@ -15,7 +15,6 @@
 ##
 
 import os
-import signal
 import sys
 
 from twext.python.filepath import CachingFilePath as FilePath
@@ -31,8 +30,7 @@
 
 from calendarserver.tap.util import directoryFromConfig
 from calendarserver.tools.principals import (parseCreationArgs, matchStrings,
-    updateRecord, principalForPrincipalID, getProxies, setProxies,
-    triggerGroupCacherUpdate)
+    updateRecord, principalForPrincipalID, getProxies, setProxies)
 
 
 class ManagePrincipalsTestCase(TestCase):
@@ -53,6 +51,9 @@
 
         newConfig = template % {
             "ServerRoot" : os.path.abspath(config.ServerRoot),
+            "DataRoot" : os.path.abspath(config.DataRoot),
+            "DocumentRoot" : os.path.abspath(config.DocumentRoot),
+            "LogRoot" : os.path.abspath(config.LogRoot),
         }
         configFilePath = FilePath(os.path.join(config.ConfigRoot, "caldavd.plist"))
         configFilePath.setContent(newConfig)
@@ -339,36 +340,13 @@
         self.assertEquals(readProxies, []) # initially empty
         self.assertEquals(writeProxies, []) # initially empty
 
-        (yield setProxies(principal, ["users:user03", "users:user04"], ["users:user05"], directory=directory))
+        (yield setProxies(None, principal, ["users:user03", "users:user04"], ["users:user05"], directory=directory))
         readProxies, writeProxies = (yield getProxies(principal, directory=directory))
         self.assertEquals(set(readProxies), set(["user03", "user04"]))
         self.assertEquals(set(writeProxies), set(["user05"]))
 
         # Using None for a proxy list indicates a no-op
-        (yield setProxies(principal, [], None, directory=directory))
+        (yield setProxies(None, principal, [], None, directory=directory))
         readProxies, writeProxies = (yield getProxies(principal, directory=directory))
         self.assertEquals(readProxies, []) # now empty
         self.assertEquals(set(writeProxies), set(["user05"])) # unchanged
-
-
-    def test_triggerGroupCacherUpdate(self):
-        """
-        Verify triggerGroupCacherUpdate can read a pidfile and send a SIGHUP
-        """
-
-        self.calledArgs = None
-        def killMethod(pid, sig):
-            self.calledArgs = (pid, sig)
-
-        class StubConfig(object):
-            def __init__(self, runRootPath):
-                self.RunRoot = runRootPath
-
-        runRootDir = FilePath(self.mktemp())
-        runRootDir.createDirectory()
-        pidFile = runRootDir.child("groupcacher.pid")
-        pidFile.setContent("1234")
-        testConfig = StubConfig(runRootDir.path)
-        triggerGroupCacherUpdate(testConfig, killMethod=killMethod)
-        self.assertEquals(self.calledArgs, (1234, signal.SIGHUP))
-        runRootDir.remove()

Modified: CalendarServer/branches/users/gaya/directorybacker/calendarserver/tools/util.py
===================================================================
--- CalendarServer/branches/users/gaya/directorybacker/calendarserver/tools/util.py	2013-04-22 18:44:41 UTC (rev 11082)
+++ CalendarServer/branches/users/gaya/directorybacker/calendarserver/tools/util.py	2013-04-22 18:46:28 UTC (rev 11083)
@@ -31,21 +31,27 @@
 import socket
 from pwd import getpwnam
 from grp import getgrnam
+from uuid import UUID
 
+from twistedcaldav.config import config, ConfigurationError
+from twistedcaldav.stdconfig import DEFAULT_CONFIG_FILE
+
+
 from twisted.python.filepath import FilePath
 from twisted.python.reflect import namedClass
 from twext.python.log import Logger
+from twisted.internet.defer import inlineCallbacks, returnValue
 
+from txdav.xml import element as davxml
 
 from calendarserver.provision.root import RootResource
 
 from twistedcaldav import memcachepool
-from twistedcaldav.config import config, ConfigurationError
 from twistedcaldav.directory import calendaruserproxy
 from twistedcaldav.directory.aggregate import AggregateDirectoryService
 from twistedcaldav.directory.directory import DirectoryService, DirectoryRecord
+from twistedcaldav.directory.directory import schedulePolledGroupCachingUpdate
 from calendarserver.push.notifier import NotifierFactory
-from twistedcaldav.stdconfig import DEFAULT_CONFIG_FILE
 
 from txdav.common.datastore.file import CommonDataStore
 
@@ -70,6 +76,8 @@
 
     return config
 
+
+
 def getDirectory(config=config):
 
     class MyDirectoryService (AggregateDirectoryService):
@@ -87,7 +95,7 @@
                     notifierFactory = None
 
                 # Need a data store
-                _newStore = CommonDataStore(FilePath(config.DocumentRoot), 
+                _newStore = CommonDataStore(FilePath(config.DocumentRoot),
                     notifierFactory, True, False)
                 if notifierFactory is not None:
                     notifierFactory.store = _newStore
@@ -130,6 +138,8 @@
         def principalForCalendarUserAddress(self, cua):
             return self.principalCollection.principalForCalendarUserAddress(cua)
 
+        def principalForUID(self, uid):
+            return self.principalCollection.principalForUID(uid)
 
     # Load augment/proxy db classes now
     if config.AugmentService.type:
@@ -148,7 +158,6 @@
     while not directory.isAvailable():
         sleep(5)
 
-
     directories = [directory]
 
     if config.ResourceService.Enabled:
@@ -183,34 +192,47 @@
 
     return aggregate
 
+
+
 class DummyDirectoryService (DirectoryService):
     realmName = ""
     baseGUID = "51856FD4-5023-4890-94FE-4356C4AAC3E4"
-    def recordTypes(self): return ()
-    def listRecords(self): return ()
-    def recordWithShortName(self): return None
+    def recordTypes(self):
+        return ()
 
+
+    def listRecords(self):
+        return ()
+
+
+    def recordWithShortName(self):
+        return None
+
 dummyDirectoryRecord = DirectoryRecord(
-    service = DummyDirectoryService(),
-    recordType = "dummy",
-    guid = "8EF0892F-7CB6-4B8E-B294-7C5A5321136A",
-    shortNames = ("dummy",),
-    fullName = "Dummy McDummerson",
-    firstName = "Dummy",
-    lastName = "McDummerson",
+    service=DummyDirectoryService(),
+    recordType="dummy",
+    guid="8EF0892F-7CB6-4B8E-B294-7C5A5321136A",
+    shortNames=("dummy",),
+    fullName="Dummy McDummerson",
+    firstName="Dummy",
+    lastName="McDummerson",
 )
 
 class UsageError (StandardError):
     pass
 
+
+
 def booleanArgument(arg):
-    if   arg in ("true",  "yes", "yup",  "uh-huh", "1", "t", "y"):
+    if   arg in ("true", "yes", "yup", "uh-huh", "1", "t", "y"):
         return True
-    elif arg in ("false", "no",  "nope", "nuh-uh", "0", "f", "n"):
+    elif arg in ("false", "no", "nope", "nuh-uh", "0", "f", "n"):
         return False
     else:
         raise ValueError("Not a boolean: %s" % (arg,))
 
+
+
 def autoDisableMemcached(config):
     """
     If memcached is not running, set config.Memcached.ClientEnabled to False
@@ -229,6 +251,7 @@
         config.Memcached.Pools.Default.ClientEnabled = False
 
 
+
 def setupMemcached(config):
     #
     # Connect to memcached
@@ -240,6 +263,7 @@
     autoDisableMemcached(config)
 
 
+
 def checkDirectory(dirpath, description, access=None, create=None, wait=False):
     """
     Make sure dirpath is an existing directory, and optionally ensure it has the
@@ -312,3 +336,188 @@
 
 
 
+def principalForPrincipalID(principalID, checkOnly=False, directory=None):
+
+    # Allow a directory parameter to be passed in, but default to config.directory
+    # But config.directory isn't set right away, so only use it when we're doing more
+    # than checking.
+    if not checkOnly and not directory:
+        directory = config.directory
+
+    if principalID.startswith("/"):
+        segments = principalID.strip("/").split("/")
+        if (len(segments) == 3 and
+            segments[0] == "principals" and segments[1] == "__uids__"):
+            uid = segments[2]
+        else:
+            raise ValueError("Can't resolve all paths yet")
+
+        if checkOnly:
+            return None
+
+        return directory.principalCollection.principalForUID(uid)
+
+    if principalID.startswith("("):
+        try:
+            i = principalID.index(")")
+
+            if checkOnly:
+                return None
+
+            recordType = principalID[1:i]
+            shortName = principalID[i + 1:]
+
+            if not recordType or not shortName or "(" in recordType:
+                raise ValueError()
+
+            return directory.principalCollection.principalForShortName(recordType, shortName)
+
+        except ValueError:
+            pass
+
+    if ":" in principalID:
+        if checkOnly:
+            return None
+
+        recordType, shortName = principalID.split(":", 1)
+
+        return directory.principalCollection.principalForShortName(recordType, shortName)
+
+    try:
+        UUID(principalID)
+
+        if checkOnly:
+            return None
+
+        x = directory.principalCollection.principalForUID(principalID)
+        return x
+    except ValueError:
+        pass
+
+    raise ValueError("Invalid principal identifier: %s" % (principalID,))
+
+
+
+def proxySubprincipal(principal, proxyType):
+    return principal.getChild("calendar-proxy-" + proxyType)
+
+
+
+ at inlineCallbacks
+def action_addProxyPrincipal(rootResource, directory, store, principal, proxyType, proxyPrincipal):
+    try:
+        (yield addProxy(rootResource, directory, store, principal, proxyType, proxyPrincipal))
+        print("Added %s as a %s proxy for %s" % (
+            prettyPrincipal(proxyPrincipal), proxyType,
+            prettyPrincipal(principal)))
+    except ProxyError, e:
+        print("Error:", e)
+    except ProxyWarning, e:
+        print(e)
+
+
+
+ at inlineCallbacks
+def action_removeProxyPrincipal(rootResource, directory, store, principal, proxyPrincipal, **kwargs):
+    try:
+        removed = (yield removeProxy(rootResource, directory, store,
+            principal, proxyPrincipal, **kwargs))
+        if removed:
+            print("Removed %s as a proxy for %s" % (
+                prettyPrincipal(proxyPrincipal),
+                prettyPrincipal(principal)))
+    except ProxyError, e:
+        print("Error:", e)
+    except ProxyWarning, e:
+        print(e)
+
+
+
+ at inlineCallbacks
+def addProxy(rootResource, directory, store, principal, proxyType, proxyPrincipal):
+    proxyURL = proxyPrincipal.url()
+
+    subPrincipal = proxySubprincipal(principal, proxyType)
+    if subPrincipal is None:
+        raise ProxyError("Unable to edit %s proxies for %s\n" % (proxyType,
+            prettyPrincipal(principal)))
+
+    membersProperty = (yield subPrincipal.readProperty(davxml.GroupMemberSet, None))
+
+    for memberURL in membersProperty.children:
+        if str(memberURL) == proxyURL:
+            raise ProxyWarning("%s is already a %s proxy for %s" % (
+                prettyPrincipal(proxyPrincipal), proxyType,
+                prettyPrincipal(principal)))
+
+    else:
+        memberURLs = list(membersProperty.children)
+        memberURLs.append(davxml.HRef(proxyURL))
+        membersProperty = davxml.GroupMemberSet(*memberURLs)
+        (yield subPrincipal.writeProperty(membersProperty, None))
+
+    proxyTypes = ["read", "write"]
+    proxyTypes.remove(proxyType)
+
+    (yield action_removeProxyPrincipal(rootResource, directory, store,
+        principal, proxyPrincipal, proxyTypes=proxyTypes))
+
+    # Schedule work the PeerConnectionPool will pick up as overdue
+    yield schedulePolledGroupCachingUpdate(store)
+
+
+
+ at inlineCallbacks
+def removeProxy(rootResource, directory, store, principal, proxyPrincipal, **kwargs):
+    removed = False
+    proxyTypes = kwargs.get("proxyTypes", ("read", "write"))
+    for proxyType in proxyTypes:
+        proxyURL = proxyPrincipal.url()
+
+        subPrincipal = proxySubprincipal(principal, proxyType)
+        if subPrincipal is None:
+            raise ProxyError("Unable to edit %s proxies for %s\n" % (proxyType,
+                prettyPrincipal(principal)))
+
+        membersProperty = (yield subPrincipal.readProperty(davxml.GroupMemberSet, None))
+
+        memberURLs = [
+            m for m in membersProperty.children
+            if str(m) != proxyURL
+        ]
+
+        if len(memberURLs) == len(membersProperty.children):
+            # No change
+            continue
+        else:
+            removed = True
+
+        membersProperty = davxml.GroupMemberSet(*memberURLs)
+        (yield subPrincipal.writeProperty(membersProperty, None))
+
+    if removed:
+        # Schedule work the PeerConnectionPool will pick up as overdue
+        yield schedulePolledGroupCachingUpdate(store)
+    returnValue(removed)
+
+
+
+def prettyPrincipal(principal):
+    record = principal.record
+    return "\"%s\" (%s:%s)" % (record.fullName, record.recordType,
+        record.shortNames[0])
+
+
+
+class ProxyError(Exception):
+    """
+    Raised when proxy assignments cannot be performed
+    """
+
+
+
+class ProxyWarning(Exception):
+    """
+    Raised for harmless proxy assignment failures such as trying to add a
+    duplicate or remove a non-existent assignment.
+    """

Copied: CalendarServer/branches/users/gaya/directorybacker/calendarserver/tools/workitems.py (from rev 11081, CalendarServer/trunk/calendarserver/tools/workitems.py)
===================================================================
--- CalendarServer/branches/users/gaya/directorybacker/calendarserver/tools/workitems.py	                        (rev 0)
+++ CalendarServer/branches/users/gaya/directorybacker/calendarserver/tools/workitems.py	2013-04-22 18:46:28 UTC (rev 11083)
@@ -0,0 +1,188 @@
+#!/usr/bin/env python
+
+##
+# Copyright (c) 2006-2013 Apple Inc. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+##
+from __future__ import print_function
+
+from getopt import getopt, GetoptError
+import os
+import sys
+import curses
+import datetime
+
+from twisted.internet.defer import inlineCallbacks
+from calendarserver.tools.cmdline import utilityMain
+from twisted.application.service import Service
+from calendarserver.push.notifier import PushNotificationWork
+from twistedcaldav.directory.directory import GroupCacherPollingWork
+from twistedcaldav.scheduling.imip.inbound import IMIPPollingWork, IMIPReplyWork
+
+def usage(e=None):
+
+    name = os.path.basename(sys.argv[0])
+    print("usage: %s [options]" % (name,))
+    print("")
+    print("  TODO: describe usage")
+    print("")
+    print("options:")
+    print("  -h --help: print this help and exit")
+    print("  -e --error: send stderr to stdout")
+    print("  -f --config <path>: Specify caldavd.plist configuration path")
+    print("")
+
+    if e:
+        sys.exit(64)
+    else:
+        sys.exit(0)
+
+
+
+def main():
+
+    try:
+        (optargs, _ignore_args) = getopt(
+            sys.argv[1:], "hef:", [
+                "help",
+                "error",
+                "config=",
+            ],
+        )
+    except GetoptError, e:
+        usage(e)
+
+    #
+    # Get configuration
+    #
+    configFileName = None
+    debug = False
+
+    for opt, arg in optargs:
+        if opt in ("-h", "--help"):
+            usage()
+
+        if opt in ("-e", "--error"):
+            debug = True
+
+        elif opt in ("-f", "--config"):
+            configFileName = arg
+
+        else:
+            raise NotImplementedError(opt)
+
+    utilityMain(configFileName, WorkItemMonitorService, verbose=debug)
+
+class WorkItemMonitorService(Service):
+
+    def __init__(self, store):
+        self.store = store
+        from twisted.internet import reactor
+        self.reactor = reactor
+
+
+    def startService(self):
+        self.screen = curses.initscr()
+        self.windows = []
+        self.updateScreenGeometry()
+        self.reactor.callLater(0, self.updateDisplay)
+
+    def updateScreenGeometry(self):
+        for win in self.windows:
+            del win
+        winY, winX = self.screen.getmaxyx()
+        seencolumns = [1]
+        seenrows = [1]
+        heightSoFar = 0
+        begin_x = 0
+        begin_y = 0
+        # Specify height and width of each window as one of:
+        #    absolute value (int), e.g.: 42
+        #    percentage of window height / width (string), e.g.: "42%"
+        # Specify row and column for each window as though it is a cell in an invisible html table
+        # Itemize windows in ascending order by row, col
+        for title, height, width, row, col, workItemClass, fmt, attrs in (
+            ("Group Membership Indexing",   "10%", "50%",  1, 1, GroupCacherPollingWork, "", ()),
+            ("IMIP Reply Polling",          "10%", "50%",  1, 2, IMIPPollingWork, "", ()),
+            ("IMIP Reply Processing",       "20%", "100%", 2, 1, IMIPReplyWork, "%s %s", ("organizer", "attendee")),
+            ("Push Notifications",          "69%", "100%", 3, 1, PushNotificationWork, "%s", ("pushID",)),
+        ):
+            if (isinstance(height, basestring)):
+                height = max(int(winY * (float(height.strip("%")) / 100.0)), 3)
+            if (isinstance(width, basestring)):
+                width = max(int(winX * (float(width.strip("%")) / 100.0)), 10)
+            if col not in seencolumns:
+                heightSoFar = max(height, heightSoFar)
+                seencolumns.append(col)
+            if row not in seenrows:
+                begin_y = heightSoFar
+                heightSoFar += height
+                begin_x = 0
+                seenrows.append(row)
+                seencolumns = [col]
+            window = WorkWindow(height, width, begin_y, begin_x,
+                self.store, title, workItemClass, fmt, attrs)
+            self.windows.append(window)
+            begin_x += width
+
+
+    @inlineCallbacks
+    def updateDisplay(self):
+        for window in self.windows:
+            yield window.update()
+
+        self.reactor.callLater(1, self.updateDisplay)
+
+class WorkWindow(object):
+    def __init__(self, nlines, ncols, begin_y, begin_x,
+        store, title, workItemClass, fmt, attrs):
+        self.window = curses.newwin(nlines, ncols, begin_y, begin_x)
+        self.ncols = ncols
+        self.store = store
+        self.title = title
+        self.workItemClass = workItemClass
+        self.fmt = fmt
+        self.attrs = attrs
+
+    @inlineCallbacks
+    def update(self):
+        self.window.erase()
+        self.window.border()
+        self.window.addstr(0, 2, self.title)
+        txn = self.store.newTransaction()
+        records = (yield self.workItemClass.all(txn))
+
+        x = 1
+        y = 1
+        for record in records:
+            seconds = record.notBefore - datetime.datetime.utcnow()
+            try:
+                self.window.addstr(y, x, "%d seconds" % int(seconds.total_seconds()))
+            except curses.error:
+                continue
+            y += 1
+            if self.attrs:
+                try:
+                    s = self.fmt % tuple([getattr(record, str(a)) for a in self.attrs])
+                except Exception, e:
+                    s = "Error: %s" % (str(e),)
+                try:
+                    self.window.addnstr(y, x, s, self.ncols-2)
+                except curses.error:
+                    pass
+                y += 1
+        self.window.refresh()
+
+if __name__ == "__main__":
+    main()

Modified: CalendarServer/branches/users/gaya/directorybacker/calendarserver/webadmin/resource.py
===================================================================
--- CalendarServer/branches/users/gaya/directorybacker/calendarserver/webadmin/resource.py	2013-04-22 18:44:41 UTC (rev 11082)
+++ CalendarServer/branches/users/gaya/directorybacker/calendarserver/webadmin/resource.py	2013-04-22 18:46:28 UTC (rev 11083)
@@ -28,7 +28,7 @@
 import operator
 import urlparse
 
-from calendarserver.tools.principals import (
+from calendarserver.tools.util import (
     principalForPrincipalID, proxySubprincipal, action_addProxyPrincipal,
     action_removeProxyPrincipal
 )
@@ -569,9 +569,10 @@
     Web administration HTTP resource.
     """
 
-    def __init__(self, path, root, directory, principalCollections=()):
+    def __init__(self, path, root, directory, store, principalCollections=()):
         self.root = root
         self.directory = directory
+        self.store = store
         super(WebAdminResource, self).__init__(path,
             principalCollections=principalCollections)
 
@@ -642,16 +643,18 @@
         # Update the proxies if specified.
         for proxyId in removeProxies:
             proxy = self.getResourceById(request, proxyId)
-            (yield action_removeProxyPrincipal(principal, proxy,
-                                               proxyTypes=["read", "write"]))
+            (yield action_removeProxyPrincipal(self.root, self.directory, self.store,
+                principal, proxy, proxyTypes=["read", "write"]))
 
         for proxyId in makeReadProxies:
             proxy = self.getResourceById(request, proxyId)
-            (yield action_addProxyPrincipal(principal, "read", proxy))
+            (yield action_addProxyPrincipal(self.root, self.directory, self.store,
+                principal, "read", proxy))
 
         for proxyId in makeWriteProxies:
             proxy = self.getResourceById(request, proxyId)
-            (yield action_addProxyPrincipal(principal, "write", proxy))
+            (yield action_addProxyPrincipal(self.root, self.directory, self.store,
+                principal, "write", proxy))
 
 
     @inlineCallbacks

Modified: CalendarServer/branches/users/gaya/directorybacker/calendarserver/webadmin/test/test_resource.py
===================================================================
--- CalendarServer/branches/users/gaya/directorybacker/calendarserver/webadmin/test/test_resource.py	2013-04-22 18:44:41 UTC (rev 11082)
+++ CalendarServer/branches/users/gaya/directorybacker/calendarserver/webadmin/test/test_resource.py	2013-04-22 18:46:28 UTC (rev 11083)
@@ -22,7 +22,7 @@
 
 from functools import partial
 
-from twisted.trial.unittest import TestCase
+from twistedcaldav.test.util import TestCase
 
 from twisted.web.microdom import parseString, getElementsByTagName
 from twisted.web.domhelpers import gatherTextNodes
@@ -66,7 +66,7 @@
 
     def setUp(self):
         self.expectedSearches = {}
-        self.resource = WebAdminResource(self.mktemp(), None, self)
+        self.resource = WebAdminResource(self.mktemp(), None, self, None)
 
 
     @inlineCallbacks

Modified: CalendarServer/branches/users/gaya/directorybacker/conf/auth/augments-test.xml
===================================================================
--- CalendarServer/branches/users/gaya/directorybacker/conf/auth/augments-test.xml	2013-04-22 18:44:41 UTC (rev 11082)
+++ CalendarServer/branches/users/gaya/directorybacker/conf/auth/augments-test.xml	2013-04-22 18:46:28 UTC (rev 11083)
@@ -1,21 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-
-<!--
-Copyright (c) 2009-2013 Apple Inc. All rights reserved.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
- -->
-
 <!DOCTYPE augments SYSTEM "augments.dtd">
 
 <augments>
@@ -111,4 +94,46 @@
     <enable-addressbook>false</enable-addressbook>
     <auto-schedule>false</auto-schedule>
   </record>
+  <record>
+    <uid>03DFF660-8BCC-4198-8588-DD77F776F518</uid>
+    <enable>true</enable>
+    <enable-calendar>true</enable-calendar>
+    <enable-addressbook>true</enable-addressbook>
+    <enable-login>true</enable-login>
+    <auto-schedule>true</auto-schedule>
+  </record>
+  <record>
+    <uid>80689D41-DAF8-4189-909C-DB017B271892</uid>
+    <enable>true</enable>
+    <enable-calendar>true</enable-calendar>
+    <enable-addressbook>true</enable-addressbook>
+    <enable-login>true</enable-login>
+    <auto-schedule>true</auto-schedule>
+  </record>
+  <record>
+    <uid>C38BEE7A-36EE-478C-9DCB-CBF4612AFE65</uid>
+    <enable>true</enable>
+    <enable-calendar>true</enable-calendar>
+    <enable-addressbook>true</enable-addressbook>
+    <enable-login>true</enable-login>
+    <auto-schedule>true</auto-schedule>
+    <auto-schedule-mode>default</auto-schedule-mode>
+    <auto-accept-group>group01</auto-accept-group>
+  </record>
+  <record>
+    <uid>CCE95217-A57B-481A-AC3D-FEC9AB6CE3A9</uid>
+    <enable>true</enable>
+    <enable-calendar>true</enable-calendar>
+    <enable-addressbook>true</enable-addressbook>
+    <enable-login>true</enable-login>
+    <auto-schedule>true</auto-schedule>
+  </record>
+  <record>
+    <uid>0CE0BF31-5F9E-4801-A489-8C70CF287F5F</uid>
+    <enable>true</enable>
+    <enable-calendar>true</enable-calendar>
+    <enable-addressbook>true</enable-addressbook>
+    <enable-login>true</enable-login>
+    <auto-schedule>true</auto-schedule>
+  </record>
 </augments>

Modified: CalendarServer/branches/users/gaya/directorybacker/conf/auth/resources-test.xml
===================================================================
--- CalendarServer/branches/users/gaya/directorybacker/conf/auth/resources-test.xml	2013-04-22 18:44:41 UTC (rev 11082)
+++ CalendarServer/branches/users/gaya/directorybacker/conf/auth/resources-test.xml	2013-04-22 18:46:28 UTC (rev 11083)
@@ -1,94 +1,227 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<!--
-Copyright (c) 2006-2013 Apple Inc. All rights reserved.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
- -->
-
-<!DOCTYPE accounts SYSTEM "accounts.dtd">
-
 <accounts realm="Test Realm">
-  <location repeat="10">
-    <uid>location%02d</uid>
-    <guid>location%02d</guid>
-    <password>location%02d</password>
-    <name>Room %02d</name>
+  <location>
+    <uid>jupiter</uid>
+    <guid>jupiter</guid>
+    <name>Jupiter Conference Room, Building 2, 1st Floor</name>
   </location>
-  <resource repeat="20">
-    <uid>resource%02d</uid>
-    <guid>resource%02d</guid>
-    <password>resource%02d</password>
-    <name>Resource %02d</name>
-  </resource>
   <location>
+    <uid>uranus</uid>
+    <guid>uranus</guid>
+    <name>Uranus Conference Room, Building 3, 1st Floor</name>
+  </location>
+  <location>
+    <uid>morgensroom</uid>
+    <guid>03DFF660-8BCC-4198-8588-DD77F776F518</guid>
+    <name>Morgen's Room</name>
+  </location>
+  <location>
     <uid>mercury</uid>
     <guid>mercury</guid>
-    <password>test</password>
     <name>Mercury Conference Room, Building 1, 2nd Floor</name>
   </location>
   <location>
-    <uid>venus</uid>
-    <guid>venus</guid>
-    <password>test</password>
-    <name>Venus Conference Room, Building 1, 2nd Floor</name>
+    <uid>location09</uid>
+    <guid>location09</guid>
+    <name>Room 09</name>
   </location>
   <location>
-    <uid>Earth</uid>
-    <guid>Earth</guid>
-    <password>test</password>
-    <name>Earth Conference Room, Building 1, 1st Floor</name>
+    <uid>location08</uid>
+    <guid>location08</guid>
+    <name>Room 08</name>
   </location>
   <location>
+    <uid>location07</uid>
+    <guid>location07</guid>
+    <name>Room 07</name>
+  </location>
+  <location>
+    <uid>location06</uid>
+    <guid>location06</guid>
+    <name>Room 06</name>
+  </location>
+  <location>
+    <uid>location05</uid>
+    <guid>location05</guid>
+    <name>Room 05</name>
+  </location>
+  <location>
+    <uid>location04</uid>
+    <guid>location04</guid>
+    <name>Room 04</name>
+  </location>
+  <location>
+    <uid>location03</uid>
+    <guid>location03</guid>
+    <name>Room 03</name>
+  </location>
+  <location>
+    <uid>location02</uid>
+    <guid>location02</guid>
+    <name>Room 02</name>
+  </location>
+  <location>
+    <uid>location01</uid>
+    <guid>location01</guid>
+    <name>Room 01</name>
+  </location>
+  <location>
+    <uid>delegatedroom</uid>
+    <guid>delegatedroom</guid>
+    <name>Delegated Conference Room</name>
+  </location>
+  <location>
     <uid>mars</uid>
     <guid>redplanet</guid>
-    <password>test</password>
     <name>Mars Conference Room, Building 1, 1st Floor</name>
   </location>
   <location>
-    <uid>jupiter</uid>
-    <guid>jupiter</guid>
-    <password>test</password>
-    <name>Jupiter Conference Room, Building 2, 1st Floor</name>
+    <uid>sharissroom</uid>
+    <guid>80689D41-DAF8-4189-909C-DB017B271892</guid>
+    <name>Shari's Room</name>
   </location>
   <location>
-    <uid>neptune</uid>
-    <guid>neptune</guid>
-    <password>test</password>
-    <name>Neptune Conference Room, Building 2, 1st Floor</name>
-  </location>
-  <location>
     <uid>pluto</uid>
     <guid>pluto</guid>
-    <password>test</password>
     <name>Pluto Conference Room, Building 2, 1st Floor</name>
   </location>
   <location>
     <uid>saturn</uid>
     <guid>saturn</guid>
-    <password>test</password>
     <name>Saturn Conference Room, Building 2, 1st Floor</name>
   </location>
   <location>
-    <uid>uranus</uid>
-    <guid>uranus</guid>
-    <password>test</password>
-    <name>Uranus Conference Room, Building 3, 1st Floor</name>
+    <uid>location10</uid>
+    <guid>location10</guid>
+    <name>Room 10</name>
   </location>
   <location>
-    <uid>delegatedroom</uid>
-    <guid>delegatedroom</guid>
-    <password>delegatedroom</password>
-    <name>Delegated Conference Room</name>
+    <uid>neptune</uid>
+    <guid>neptune</guid>
+    <name>Neptune Conference Room, Building 2, 1st Floor</name>
   </location>
+  <location>
+    <uid>Earth</uid>
+    <guid>Earth</guid>
+    <name>Earth Conference Room, Building 1, 1st Floor</name>
+  </location>
+  <location>
+    <uid>venus</uid>
+    <guid>venus</guid>
+    <name>Venus Conference Room, Building 1, 2nd Floor</name>
+  </location>
+  <resource>
+    <uid>sharisotherresource</uid>
+    <guid>CCE95217-A57B-481A-AC3D-FEC9AB6CE3A9</guid>
+    <name>Shari's Other Resource</name>
+  </resource>
+  <resource>
+    <uid>resource15</uid>
+    <guid>resource15</guid>
+    <name>Resource 15</name>
+  </resource>
+  <resource>
+    <uid>resource14</uid>
+    <guid>resource14</guid>
+    <name>Resource 14</name>
+  </resource>
+  <resource>
+    <uid>resource17</uid>
+    <guid>resource17</guid>
+    <name>Resource 17</name>
+  </resource>
+  <resource>
+    <uid>resource16</uid>
+    <guid>resource16</guid>
+    <name>Resource 16</name>
+  </resource>
+  <resource>
+    <uid>resource11</uid>
+    <guid>resource11</guid>
+    <name>Resource 11</name>
+  </resource>
+  <resource>
+    <uid>resource10</uid>
+    <guid>resource10</guid>
+    <name>Resource 10</name>
+  </resource>
+  <resource>
+    <uid>resource13</uid>
+    <guid>resource13</guid>
+    <name>Resource 13</name>
+  </resource>
+  <resource>
+    <uid>resource12</uid>
+    <guid>resource12</guid>
+    <name>Resource 12</name>
+  </resource>
+  <resource>
+    <uid>resource19</uid>
+    <guid>resource19</guid>
+    <name>Resource 19</name>
+  </resource>
+  <resource>
+    <uid>resource18</uid>
+    <guid>resource18</guid>
+    <name>Resource 18</name>
+  </resource>
+  <resource>
+    <uid>sharisresource</uid>
+    <guid>C38BEE7A-36EE-478C-9DCB-CBF4612AFE65</guid>
+    <name>Shari's Resource</name>
+  </resource>
+  <resource>
+    <uid>resource20</uid>
+    <guid>resource20</guid>
+    <name>Resource 20</name>
+  </resource>
+  <resource>
+    <uid>resource06</uid>
+    <guid>resource06</guid>
+    <name>Resource 06</name>
+  </resource>
+  <resource>
+    <uid>resource07</uid>
+    <guid>resource07</guid>
+    <name>Resource 07</name>
+  </resource>
+  <resource>
+    <uid>resource04</uid>
+    <guid>resource04</guid>
+    <name>Resource 04</name>
+  </resource>
+  <resource>
+    <uid>resource05</uid>
+    <guid>resource05</guid>
+    <name>Resource 05</name>
+  </resource>
+  <resource>
+    <uid>resource02</uid>
+    <guid>resource02</guid>
+    <name>Resource 02</name>
+  </resource>
+  <resource>
+    <uid>resource03</uid>
+    <guid>resource03</guid>
+    <name>Resource 03</name>
+  </resource>
+  <resource>
+    <uid>resource01</uid>
+    <guid>resource01</guid>
+    <name>Resource 01</name>
+  </resource>
+  <resource>
+    <uid>sharisotherresource1</uid>
+    <guid>0CE0BF31-5F9E-4801-A489-8C70CF287F5F</guid>
+    <name>Shari's Other Resource1</name>
+  </resource>
+  <resource>
+    <uid>resource08</uid>
+    <guid>resource08</guid>
+    <name>Resource 08</name>
+  </resource>
+  <resource>
+    <uid>resource09</uid>
+    <guid>resource09</guid>
+    <name>Resource 09</name>
+  </resource>
 </accounts>


Property changes on: CalendarServer/branches/users/gaya/directorybacker/conf/auth/resources-test.xml
___________________________________________________________________
Added: svn:executable
   + *

Modified: CalendarServer/branches/users/gaya/directorybacker/conf/caldavd-apple.plist
===================================================================
--- CalendarServer/branches/users/gaya/directorybacker/conf/caldavd-apple.plist	2013-04-22 18:44:41 UTC (rev 11082)
+++ CalendarServer/branches/users/gaya/directorybacker/conf/caldavd-apple.plist	2013-04-22 18:46:28 UTC (rev 11083)
@@ -105,6 +105,15 @@
     <dict>
         <key>Ctl</key>
         <string>xpg_ctl</string>
+        <key>Options</key>
+        <array>
+        <!-- <string>-c log_statement=all</string> -->
+            <string>-c log_lock_waits=TRUE</string>
+            <string>-c deadlock_timeout=10</string>
+            <string>-c log_line_prefix='%m [%p] '</string>
+        </array>
+        <key>ExtraConnections</key>
+        <integer>20</integer>
     </dict>
 
     <!-- Data root -->

Modified: CalendarServer/branches/users/gaya/directorybacker/conf/caldavd-test.plist
===================================================================
--- CalendarServer/branches/users/gaya/directorybacker/conf/caldavd-test.plist	2013-04-22 18:44:41 UTC (rev 11082)
+++ CalendarServer/branches/users/gaya/directorybacker/conf/caldavd-test.plist	2013-04-22 18:46:28 UTC (rev 11083)
@@ -772,8 +772,6 @@
         <false/>
         <key>AttendeeRefreshBatch</key>
         <integer>0</integer>
-        <key>V1Compatibility</key> <!-- Allow /path-based CUAs in scheduling replies -->
-        <false/>
 
 		<key>AutoSchedule</key>
 		<dict>

Modified: CalendarServer/branches/users/gaya/directorybacker/contrib/performance/loadtest/ical.py
===================================================================
--- CalendarServer/branches/users/gaya/directorybacker/contrib/performance/loadtest/ical.py	2013-04-22 18:44:41 UTC (rev 11082)
+++ CalendarServer/branches/users/gaya/directorybacker/contrib/performance/loadtest/ical.py	2013-04-22 18:46:28 UTC (rev 11083)
@@ -1186,7 +1186,7 @@
         self._pushFactories.append(factory)
         connect(GAIEndpoint(self.reactor, host, port), factory)
 
-    def _receivedPush(self, inboundID):
+    def _receivedPush(self, inboundID, dataChangedTimestamp):
         for href, id in self.ampPushKeys.iteritems():
             if inboundID == id:
                 self._checkCalendarsForEvents(href, push=True)

Copied: CalendarServer/branches/users/gaya/directorybacker/doc/RFC/RFC6868-Parameter Value Encoding.txt (from rev 11081, CalendarServer/trunk/doc/RFC/RFC6868-Parameter Value Encoding.txt)
===================================================================
--- CalendarServer/branches/users/gaya/directorybacker/doc/RFC/RFC6868-Parameter Value Encoding.txt	                        (rev 0)
+++ CalendarServer/branches/users/gaya/directorybacker/doc/RFC/RFC6868-Parameter Value Encoding.txt	2013-04-22 18:46:28 UTC (rev 11083)
@@ -0,0 +1,395 @@
+
+
+
+
+
+
+Internet Engineering Task Force (IETF)                          C. Daboo
+Request for Comments: 6868                                         Apple
+Updates: 5545, 6321, 6350, 6351                            February 2013
+Category: Standards Track
+ISSN: 2070-1721
+
+
+            Parameter Value Encoding in iCalendar and vCard
+
+Abstract
+
+   This specification updates the data formats for iCalendar (RFC 5545)
+   and vCard (RFC 6350) to allow parameter values to include certain
+   characters forbidden by the existing specifications.
+
+Status of This Memo
+
+   This is an Internet Standards Track document.
+
+   This document is a product of the Internet Engineering Task Force
+   (IETF).  It represents the consensus of the IETF community.  It has
+   received public review and has been approved for publication by the
+   Internet Engineering Steering Group (IESG).  Further information on
+   Internet Standards is available in Section 2 of RFC 5741.
+
+   Information about the current status of this document, any errata,
+   and how to provide feedback on it may be obtained at
+   http://www.rfc-editor.org/info/rfc6868.
+
+Copyright Notice
+
+   Copyright (c) 2013 IETF Trust and the persons identified as the
+   document authors.  All rights reserved.
+
+   This document is subject to BCP 78 and the IETF Trust's Legal
+   Provisions Relating to IETF Documents
+   (http://trustee.ietf.org/license-info) in effect on the date of
+   publication of this document.  Please review these documents
+   carefully, as they describe your rights and restrictions with respect
+   to this document.  Code Components extracted from this document must
+   include Simplified BSD License text as described in Section 4.e of
+   the Trust Legal Provisions and are provided without warranty as
+   described in the Simplified BSD License.
+
+
+
+
+
+
+
+
+Daboo                        Standards Track                    [Page 1]
+
+RFC 6868                   Parameter Encoding              February 2013
+
+
+Table of Contents
+
+   1. Introduction ....................................................2
+   2. Conventions Used in This Document ...............................2
+   3. Parameter Value Encoding Scheme .................................3
+      3.1. iCalendar Example ..........................................4
+      3.2. vCard Example ..............................................4
+   4. Security Considerations .........................................4
+   5. Acknowledgments .................................................4
+   6. Normative References ............................................5
+   Appendix A. Choice of Quoting Mechanism ............................6
+
+1.  Introduction
+
+   The iCalendar [RFC5545] specification defines a standard way to
+   describe calendar data.  The vCard [RFC6350] specification defines a
+   standard way to describe contact data.  Both of these use a similar
+   text-based data format.  Each iCalendar and vCard data object can
+   include "properties" that have "parameters" and a "value".  The value
+   of a "parameter" is typically a token or URI value, but a "generic"
+   text value is also allowed.  However, the syntax rules for both
+   iCalendar and vCard prevent the use of a double-quote character or
+   control characters in such values, though double-quote characters and
+   some subset of control characters are allowed in the actual property
+   values.
+
+   As more and more extensions are being developed for these data
+   formats, there is a need to allow at least double-quotes and line
+   feeds to be included in parameter values.  The \-escaping mechanism
+   used for property text values is not defined for use with parameter
+   values and cannot be easily used in a backwards-compatible manner.
+   This specification defines a new character escaping mechanism,
+   compatible with existing parsers and chosen to minimize any impact on
+   existing data.
+
+2.  Conventions Used in This Document
+
+   The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
+   "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and
+   "OPTIONAL" in this document are to be interpreted as described in
+   [RFC2119].
+
+
+
+
+
+
+
+
+
+
+Daboo                        Standards Track                    [Page 2]
+
+RFC 6868                   Parameter Encoding              February 2013
+
+
+3.  Parameter Value Encoding Scheme
+
+   This specification defines the ^ character (U+005E -- Circumflex
+   Accent) as an escape character in parameter values whose value type
+   is defined using the "param-value" syntax element (Section 3.1 of
+   iCalendar [RFC5545] and Section 3.3 of vCard [RFC6350]).  The
+   ^-escaping mechanism can be used when the value is either unquoted or
+   quoted (i.e., whether or not the value is surrounded by double-
+   quotes).
+
+   When generating iCalendar or vCard parameter values, the following
+   apply:
+
+   o  formatted text line breaks are encoded into ^n (U+005E, U+006E)
+
+   o  the ^ character (U+005E) is encoded into ^^ (U+005E, U+005E)
+
+   o  the " character (U+0022) is encoded into ^' (U+005E, U+0027)
+
+   When parsing iCalendar or vCard parameter values, the following
+   apply:
+
+   o  the character sequence ^n (U+005E, U+006E) is decoded into an
+      appropriate formatted line break according to the type of system
+      being used
+
+   o  the character sequence ^^ (U+005E, U+005E) is decoded into the ^
+      character (U+005E)
+
+   o  the character sequence ^' (U+005E, U+0027) is decoded into the "
+      character (U+0022)
+
+   o  if a ^ (U+005E) character is followed by any character other than
+      the ones above, parsers MUST leave both the ^ and the following
+      character in place
+
+   When converting between iCalendar and vCard text-based data formats
+   and alternative data-format representations such as XML (as described
+   in [RFC6321] and [RFC6351], respectively), implementations MUST
+   ensure that parameter value escape sequences are generated correctly
+   in the text-based format and are decoded when the parameter values
+   appear in the alternate data formats.
+
+
+
+
+
+
+
+
+
+Daboo                        Standards Track                    [Page 3]
+
+RFC 6868                   Parameter Encoding              February 2013
+
+
+3.1.  iCalendar Example
+
+   The following example is an "ATTENDEE" property with a "CN" parameter
+   whose value includes two double-quote characters.  The parameter
+   value is not quoted, as there are no characters in the value that
+   would trigger quoting as required by iCalendar.
+
+   ATTENDEE;CN=George Herman ^'Babe^' Ruth:mailto:babe at example.com
+
+   The unescaped parameter value is
+
+   George Herman "Babe" Ruth
+
+3.2.  vCard Example
+
+   The following example is a "GEO" property with an "X-ADDRESS"
+   parameter whose value includes several line feed characters.  The
+   parameter value is also quoted, since it contains a comma, which
+   triggers quoting as required by vCard.
+
+   GEO;X-ADDRESS="Pittsburgh Pirates^n115 Federal St^nPitt
+    sburgh, PA 15212":geo:40.446816,-80.00566
+
+   The unescaped parameter value (where each line is terminated by a
+   line break character sequence) is
+
+   Pittsburgh Pirates
+   115 Federal St
+   Pittsburgh, PA 15212
+
+4.  Security Considerations
+
+   There are no additional security issues beyond those of iCalendar
+   [RFC5545] and vCard [RFC6350].
+
+5.  Acknowledgments
+
+   Thanks to Michael Angstadt, Tim Bray, Mike Douglass, Barry Leiba,
+   Simon Perreault, and Pete Resnick for feedback on this specification.
+
+
+
+
+
+
+
+
+
+
+
+
+Daboo                        Standards Track                    [Page 4]
+
+RFC 6868                   Parameter Encoding              February 2013
+
+
+6.  Normative References
+
+   [RFC2119]  Bradner, S., "Key words for use in RFCs to Indicate
+              Requirement Levels", BCP 14, RFC 2119, March 1997.
+
+   [RFC5545]  Desruisseaux, B., "Internet Calendaring and Scheduling
+              Core Object Specification (iCalendar)", RFC 5545,
+              September 2009.
+
+   [RFC6321]  Daboo, C., Douglass, M., and S. Lees, "xCal: The XML
+              Format for iCalendar", RFC 6321, August 2011.
+
+   [RFC6350]  Perreault, S., "vCard Format Specification", RFC 6350,
+              August 2011.
+
+   [RFC6351]  Perreault, S., "xCard: vCard XML Representation",
+              RFC 6351, August 2011.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Daboo                        Standards Track                    [Page 5]
+
+RFC 6868                   Parameter Encoding              February 2013
+
+
+Appendix A.  Choice of Quoting Mechanism
+
+   Having recognized the need for escaping parameter values, the
+   question is what mechanism to use?  One obvious choice would be to
+   adopt the \-escaping used for property values.  However, that could
+   not be used as-is, because it escapes a double-quote as the sequence
+   of \ followed by double-quote.  Consider what the example in
+   Section 3.1 might look like using \-escaping:
+
+   ATTENDEE;CN="George Herman \"Babe\" Ruth":mailto:babe at example.com
+
+   Existing iCalendar/vCard parsers know nothing about escape sequences
+   in parameters.  So they would parse the parameter value as:
+
+   George Herman \
+
+   i.e., the text between the first and second occurrence of a double-
+   quote.  However, the text after the second double-quote ought to be
+   either a : or a ; (to delimit the parameter value from the following
+   parameter or property) but is not, so the parser could legitimately
+   throw an error at that point because the data is syntactically
+   invalid.  Thus, for backwards-compatibility reasons, a double-quote
+   cannot be escaped using a sequence that itself includes a double-
+   quote, and hence the choice of using a single-quote in this
+   specification.
+
+   Another option would be to use a form of \-escaping modified for use
+   in parameter values only.  However, some incorrect, non-interoperable
+   use of \ in parameter values has been observed, and thus it is best
+   to steer clear of that to achieve guaranteed, reliable
+   interoperability.  Also, given that double-quote gets changed to
+   single-quote in the escape sequence for a parameter, but not for a
+   value, it is better to not give the impression that the same escape
+   mechanism (and thus code) can be used for both (which could lead to
+   other issues, such as an implementation incorrectly escaping a ; as
+   \; as opposed to quoting the parameter value).
+
+   The choice of ^ as the escape character was made based on the
+   requirement that an ASCII symbol (non-alphanumeric character) be
+   used, and it ought to be one least likely to be found in existing
+   data.
+
+
+
+
+
+
+
+
+
+
+Daboo                        Standards Track                    [Page 6]
+
+RFC 6868                   Parameter Encoding              February 2013
+
+
+Author's Address
+
+   Cyrus Daboo
+   Apple Inc.
+   1 Infinite Loop
+   Cupertino, CA  95014
+   USA
+
+   EMail: cyrus at daboo.name
+   URI:   http://www.apple.com/
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Daboo                        Standards Track                    [Page 7]
+
\ No newline at end of file

Copied: CalendarServer/branches/users/gaya/directorybacker/support/Apple.make (from rev 11081, CalendarServer/trunk/support/Apple.make)
===================================================================
--- CalendarServer/branches/users/gaya/directorybacker/support/Apple.make	                        (rev 0)
+++ CalendarServer/branches/users/gaya/directorybacker/support/Apple.make	2013-04-22 18:46:28 UTC (rev 11083)
@@ -0,0 +1,170 @@
+# -*- mode: Makefile; -*-
+##
+# B&I Makefile for CalendarServer
+#
+# This is only useful internally at Apple, probably.
+##
+# Copyright (c) 2005-2013 Apple Inc. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+##
+
+# Project info
+Project	    = CalendarServer
+ProjectName = CalendarServer
+UserType    = Server
+ToolType    = Applications
+
+# Include common makefile targets for B&I
+include $(MAKEFILEPATH)/CoreOS/ReleaseControl/Common.make
+include /AppleInternal/ServerTools/ServerBuildVariables.xcconfig
+
+SIPP = $(SERVER_INSTALL_PATH_PREFIX)
+SERVERSETUP = $(SIPP)$(NSSYSTEMDIR)$(NSLIBRARYSUBDIR)/ServerSetup
+
+Cruft += .dependencies
+Extra_Environment += PATH="$(SIPP)/usr/bin:$$PATH"
+
+CALDAVDSUBDIR = /caldavd
+
+PYTHON = $(USRBINDIR)/python
+PY_HOME = $(SIPP)$(SHAREDIR)$(CALDAVDSUBDIR)
+PY_INSTALL_FLAGS = --root="$(DSTROOT)" --prefix="$(SIPP)" --install-lib="$(PY_HOME)/lib/python" --install-scripts="$(SIPP)$(LIBEXECDIR)$(CALDAVDSUBDIR)"
+CS_INSTALL_FLAGS = --install-scripts="$(SIPP)$(USRSBINDIR)" --install-data="$(SIPP)$(ETCDIR)"
+CS_BUILD_EXT_FLAGS = --include-dirs="$(SIPP)/usr/include" --library-dirs="$(SIPP)/usr/lib"
+
+CS_USER  = _calendar
+CS_GROUP = _calendar
+
+#
+# Build
+#
+
+.phony: $(Project) pycalendar build setup prep install install-ossfiles buildit
+
+CalDAVTester::          $(BuildDirectory)/CalDAVTester
+PyKerberos::            $(BuildDirectory)/PyKerberos
+pycalendar::            $(BuildDirectory)/pycalendar
+PyGreSQL-4.0::          $(BuildDirectory)/PyGreSQL-4.0
+sqlparse-0.1.2::        $(BuildDirectory)/sqlparse-0.1.2
+setproctitle-1.1.6::	$(BuildDirectory)/setproctitle-1.1.6
+psutil-0.6.1::		$(BuildDirectory)/psutil-0.6.1
+pycrypto-2.5::		$(BuildDirectory)/pycrypto-2.5
+$(Project)::            $(BuildDirectory)/$(Project)
+
+build:: PyKerberos pycalendar PyGreSQL-4.0 sqlparse-0.1.2 setproctitle-1.1.6 psutil-0.6.1 pycrypto-2.5 $(Project)
+
+setup:
+	$(_v) ./run -g
+
+prep:: setup CalDAVTester.tgz PyKerberos.tgz pycalendar.tgz PyGreSQL-4.0.tgz sqlparse-0.1.2.tgz setproctitle-1.1.6.tgz psutil-0.6.1.tgz pycrypto-2.5.tgz
+
+PyKerberos pycalendar PyGreSQL-4.0 sqlparse-0.1.2 setproctitle-1.1.6 psutil-0.6.1 pycrypto-2.5 $(Project)::
+	@echo "Building $@..."
+	$(_v) cd $(BuildDirectory)/$@ && $(Environment) $(PYTHON) setup.py build
+
+install:: build
+	$(_v) cd $(BuildDirectory)/$(Project)         && $(Environment) $(PYTHON) setup.py build_ext $(CS_BUILD_EXT_FLAGS) install $(PY_INSTALL_FLAGS) $(CS_INSTALL_FLAGS)
+	$(_v) cd $(BuildDirectory)/PyKerberos         && $(Environment) $(PYTHON) setup.py install $(PY_INSTALL_FLAGS)
+	$(_v) cd $(BuildDirectory)/pycalendar         && $(Environment) $(PYTHON) setup.py install $(PY_INSTALL_FLAGS)
+	$(_v) cd $(BuildDirectory)/PyGreSQL-4.0       && $(Environment) $(PYTHON) setup.py install $(PY_INSTALL_FLAGS)
+	$(_v) cd $(BuildDirectory)/sqlparse-0.1.2     && $(Environment) $(PYTHON) setup.py install $(PY_INSTALL_FLAGS)
+	$(_v) cd $(BuildDirectory)/setproctitle-1.1.6 && $(Environment) $(PYTHON) setup.py install $(PY_INSTALL_FLAGS)
+	$(_v) cd $(BuildDirectory)/psutil-0.6.1       && $(Environment) $(PYTHON) setup.py install $(PY_INSTALL_FLAGS)
+	$(_v) cd $(BuildDirectory)/pycrypto-2.5       && $(Environment) $(PYTHON) setup.py install $(PY_INSTALL_FLAGS)
+	$(_v) for so in $$(find "$(DSTROOT)$(PY_HOME)/lib" -type f -name '*.so'); do $(STRIP) -Sx "$${so}"; done 
+	$(_v) $(INSTALL_DIRECTORY) "$(DSTROOT)$(SIPP)$(ETCDIR)$(CALDAVDSUBDIR)"
+	$(_v) $(INSTALL_FILE) "$(Sources)/conf/caldavd-apple.plist" "$(DSTROOT)$(SIPP)$(ETCDIR)$(CALDAVDSUBDIR)/caldavd-apple.plist"
+	$(_v) chmod -R ugo+r "$(DSTROOT)$(PY_HOME)"
+	$(_v) for f in $$(find "$(DSTROOT)$(SIPP)$(ETCDIR)" -type f ! -name '*.default'); do cp "$${f}" "$${f}.default"; done
+
+install::
+	@echo "Installing manual pages..."
+	$(_v) $(INSTALL_DIRECTORY) "$(DSTROOT)$(SIPP)$(MANDIR)/man8"
+	$(_v) $(INSTALL_FILE) "$(Sources)/doc/caldavd.8"                              "$(DSTROOT)$(SIPP)$(MANDIR)/man8"
+	$(_v) $(INSTALL_FILE) "$(Sources)/doc/calendarserver_bootstrap_database.8"    "$(DSTROOT)$(SIPP)$(MANDIR)/man8"
+	$(_v) $(INSTALL_FILE) "$(Sources)/doc/calendarserver_command_gateway.8"       "$(DSTROOT)$(SIPP)$(MANDIR)/man8"
+	$(_v) $(INSTALL_FILE) "$(Sources)/doc/calendarserver_export.8"                "$(DSTROOT)$(SIPP)$(MANDIR)/man8"
+	$(_v) $(INSTALL_FILE) "$(Sources)/doc/calendarserver_manage_principals.8"     "$(DSTROOT)$(SIPP)$(MANDIR)/man8"
+	$(_v) $(INSTALL_FILE) "$(Sources)/doc/calendarserver_migrate_resources.8"     "$(DSTROOT)$(SIPP)$(MANDIR)/man8"
+	$(_v) $(INSTALL_FILE) "$(Sources)/doc/calendarserver_purge_attachments.8"     "$(DSTROOT)$(SIPP)$(MANDIR)/man8"
+	$(_v) $(INSTALL_FILE) "$(Sources)/doc/calendarserver_purge_events.8"          "$(DSTROOT)$(SIPP)$(MANDIR)/man8"
+	$(_v) $(INSTALL_FILE) "$(Sources)/doc/calendarserver_purge_principals.8"      "$(DSTROOT)$(SIPP)$(MANDIR)/man8"
+	$(_v) $(INSTALL_FILE) "$(Sources)/doc/calendarserver_manage_push.8"           "$(DSTROOT)$(SIPP)$(MANDIR)/man8"
+	$(_v) $(INSTALL_FILE) "$(Sources)/doc/calendarserver_shell.8"                 "$(DSTROOT)$(SIPP)$(MANDIR)/man8"
+	$(_v) gzip -9 -f "$(DSTROOT)$(SIPP)$(MANDIR)/man8/"*.[0-9]
+	@echo "Installing launchd config..."
+	$(_v) $(INSTALL_DIRECTORY) "$(DSTROOT)$(NSLOCALDIR)/$(NSLIBRARYSUBDIR)/Server/Calendar and Contacts"
+	$(_v) $(INSTALL_DIRECTORY) -o "$(CS_USER)" -g "$(CS_GROUP)" -m 0755 "$(DSTROOT)$(VARDIR)/log$(CALDAVDSUBDIR)"
+	$(_v) $(INSTALL_DIRECTORY) "$(DSTROOT)$(SIPP)$(NSLIBRARYDIR)/LaunchDaemons"
+	$(_v) $(INSTALL_FILE) "$(Sources)/contrib/launchd/calendarserver.plist" "$(DSTROOT)$(SIPP)$(NSLIBRARYDIR)/LaunchDaemons/org.calendarserver.calendarserver.plist"
+	@echo "Installing changeip script..."
+	$(_v) $(INSTALL_DIRECTORY) "$(DSTROOT)$(SIPP)$(LIBEXECDIR)/changeip"
+	$(_v) $(INSTALL_FILE) "$(Sources)/calendarserver/tools/changeip_calendar.py" "$(DSTROOT)$(SIPP)$(LIBEXECDIR)/changeip/changeip_calendar.py"
+	$(_v) chmod ugo+x "$(DSTROOT)$(SIPP)$(LIBEXECDIR)/changeip/changeip_calendar.py"
+
+install::
+	@echo "Installing CalDAVTester package..."
+	$(_v) $(INSTALL_DIRECTORY) "$(DSTROOT)/AppleInternal/ServerTools"
+	$(_v) $(INSTALL_FILE) "$(Sources)/CalDAVTester.tgz" "$(DSTROOT)/AppleInternal/ServerTools/CalDAVTester.tgz"
+
+#
+# Automatic Extract
+#
+
+$(BuildDirectory)/$(Project):
+	@echo "Copying source for $(Project)..."
+	$(_v) $(MKDIR) -p "$@"
+	$(_v) pax -rw bin conf Makefile lib-patches setup.py calendarserver twistedcaldav twext txdav twisted support "$@/"
+
+$(BuildDirectory)/%: %.tgz
+	@echo "Extracting source for $(notdir $<)..."
+	$(_v) $(MKDIR) -p "$(BuildDirectory)"
+	$(_v) $(RMDIR) "$@"
+	$(_v) $(TAR) -C "$(BuildDirectory)" -xzf "$<"
+
+%.tgz: ../%
+	@echo "Archiving sources for $(notdir $<)..."
+	$(_v) if [ -f "$</setup.py" ] && grep setuptools "$</setup.py" > /dev/null; then \
+	        echo "Working around setuptools' stupid need to download a new version."; \
+	        cd "$<" && $(PYTHON) "setup.py" --help >/dev/null; \
+	      fi
+	$(_v) $(TAR) -C "$(dir $<)"        \
+	          --exclude=.svn           \
+	          --exclude=build          \
+	          --exclude=_trial_temp    \
+	          --exclude=dropin.cache   \
+	          -czf "$@" "$(notdir $<)"
+
+#
+# Open Source Hooey
+#
+
+OSV = $(USRDIR)/local/OpenSourceVersions
+OSL = $(USRDIR)/local/OpenSourceLicenses
+
+#install:: install-ossfiles
+
+install-ossfiles::
+	$(_v) $(INSTALL_DIRECTORY) $(DSTROOT)/$(OSV)
+	$(_v) $(INSTALL_FILE) $(Sources)/$(ProjectName).plist $(DSTROOT)/$(OSV)/$(ProjectName).plist
+	$(_v) $(INSTALL_DIRECTORY) $(DSTROOT)/$(OSL)
+	$(_v) $(INSTALL_FILE) $(BuildDirectory)/$(Project)/LICENSE $(DSTROOT)/$(OSL)/$(ProjectName).txt
+
+#
+# B&I Hooey
+#
+
+buildit: prep
+	@echo "Running buildit..."
+	$(_v) sudo ~rc/bin/buildit $(CC_Archs) $(Sources)

Deleted: CalendarServer/branches/users/gaya/directorybacker/support/CalendarServer.tmproj
===================================================================
--- CalendarServer/branches/users/gaya/directorybacker/support/CalendarServer.tmproj	2013-04-22 18:44:41 UTC (rev 11082)
+++ CalendarServer/branches/users/gaya/directorybacker/support/CalendarServer.tmproj	2013-04-22 18:46:28 UTC (rev 11083)
@@ -1,122 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-<dict>
-	<key>documents</key>
-	<array>
-		<dict>
-			<key>expanded</key>
-			<true/>
-			<key>name</key>
-			<string>twistedcaldav</string>
-			<key>regexFolderFilter</key>
-			<string>!.*/(\.[^/]*)$</string>
-			<key>sourceDirectory</key>
-			<string>../twistedcaldav</string>
-		</dict>
-		<dict>
-			<key>name</key>
-			<string>web2</string>
-			<key>regexFolderFilter</key>
-			<string>!.*/(\.[^/]*)$</string>
-			<key>sourceDirectory</key>
-			<string>../../Twisted/twisted/web2</string>
-		</dict>
-		<dict>
-			<key>name</key>
-			<string>twisted</string>
-			<key>regexFolderFilter</key>
-			<string>!.*/(\.[^/]*)$</string>
-			<key>sourceDirectory</key>
-			<string>../../Twisted/twisted</string>
-		</dict>
-		<dict>
-			<key>name</key>
-			<string>PyOpenDirectory</string>
-			<key>regexFolderFilter</key>
-			<string>!.*/(\.[^/]*)$</string>
-			<key>sourceDirectory</key>
-			<string>../../PyOpenDirectory</string>
-		</dict>
-		<dict>
-			<key>name</key>
-			<string>PyKerberos</string>
-			<key>regexFolderFilter</key>
-			<string>!.*/(\.[^/]*)$</string>
-			<key>sourceDirectory</key>
-			<string>../../PyKerberos</string>
-		</dict>
-		<dict>
-			<key>name</key>
-			<string>conf</string>
-			<key>regexFolderFilter</key>
-			<string>!.*/(\.[^/]*)$</string>
-			<key>sourceDirectory</key>
-			<string>../conf</string>
-		</dict>
-		<dict>
-			<key>name</key>
-			<string>bin</string>
-			<key>regexFolderFilter</key>
-			<string>!.*/(\.[^/]*)$</string>
-			<key>sourceDirectory</key>
-			<string>../bin</string>
-		</dict>
-		<dict>
-			<key>name</key>
-			<string>doc</string>
-			<key>regexFolderFilter</key>
-			<string>!.*/(\.[^/]*)$</string>
-			<key>sourceDirectory</key>
-			<string>../doc</string>
-		</dict>
-		<dict>
-			<key>name</key>
-			<string>support</string>
-			<key>regexFolderFilter</key>
-			<string>!.*/(\.[^/]*|.*\.xcodeproj)$</string>
-			<key>sourceDirectory</key>
-			<string></string>
-		</dict>
-		<dict>
-			<key>children</key>
-			<array>
-				<dict>
-					<key>filename</key>
-					<string>../run</string>
-				</dict>
-				<dict>
-					<key>filename</key>
-					<string>../test</string>
-				</dict>
-				<dict>
-					<key>filename</key>
-					<string>../testcaldav</string>
-				</dict>
-				<dict>
-					<key>filename</key>
-					<string>../setup.py</string>
-				</dict>
-				<dict>
-					<key>filename</key>
-					<string>../LICENSE</string>
-				</dict>
-				<dict>
-					<key>filename</key>
-					<string>../README</string>
-				</dict>
-			</array>
-			<key>name</key>
-			<string>topfiles</string>
-		</dict>
-	</array>
-	<key>fileHierarchyDrawerWidth</key>
-	<integer>249</integer>
-	<key>metaData</key>
-	<dict/>
-	<key>showFileHierarchyDrawer</key>
-	<true/>
-	<key>windowFrame</key>
-	<string>{{414, 114}, {987, 1030}}</string>
-</dict>
-</plist>


Property changes on: CalendarServer/branches/users/gaya/directorybacker/support/CalendarServer.xcodeproj
___________________________________________________________________
Modified: svn:ignore
   - *.mode*
*.pbxuser

   + xcuserdata


Modified: CalendarServer/branches/users/gaya/directorybacker/support/CalendarServer.xcodeproj/project.pbxproj
===================================================================
--- CalendarServer/branches/users/gaya/directorybacker/support/CalendarServer.xcodeproj/project.pbxproj	2013-04-22 18:44:41 UTC (rev 11082)
+++ CalendarServer/branches/users/gaya/directorybacker/support/CalendarServer.xcodeproj/project.pbxproj	2013-04-22 18:46:28 UTC (rev 11083)
@@ -3,5060 +3,110 @@
 	archiveVersion = 1;
 	classes = {
 	};
-	objectVersion = 42;
+	objectVersion = 46;
 	objects = {
 
 /* Begin PBXFileReference section */
-		66FA9961155B16B500B6FAC1 /* benchmark */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; name = benchmark; path = ../benchmark; sourceTree = "<group>"; };
-		66FA9962155B16B500B6FAC1 /* benchreport */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; name = benchreport; path = ../benchreport; sourceTree = "<group>"; };
-		66FA9964155B16B500B6FAC1 /* _calendarserver_preamble.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = _calendarserver_preamble.py; sourceTree = "<group>"; };
-		66FA9965155B16B500B6FAC1 /* caldavd */ = {isa = PBXFileReference; lastKnownFileType = text; path = caldavd; sourceTree = "<group>"; };
-		66FA9966155B16B500B6FAC1 /* calendarserver_backup */ = {isa = PBXFileReference; lastKnownFileType = text; path = calendarserver_backup; sourceTree = "<group>"; };
-		66FA9967155B16B500B6FAC1 /* calendarserver_bootstrap_database */ = {isa = PBXFileReference; lastKnownFileType = text; path = calendarserver_bootstrap_database; sourceTree = "<group>"; };
-		66FA9968155B16B500B6FAC1 /* calendarserver_command_gateway */ = {isa = PBXFileReference; lastKnownFileType = text; path = calendarserver_command_gateway; sourceTree = "<group>"; };
-		66FA9969155B16B500B6FAC1 /* calendarserver_config */ = {isa = PBXFileReference; lastKnownFileType = text; path = calendarserver_config; sourceTree = "<group>"; };
-		66FA996A155B16B500B6FAC1 /* calendarserver_dbinspect */ = {isa = PBXFileReference; lastKnownFileType = text; path = calendarserver_dbinspect; sourceTree = "<group>"; };
-		66FA996B155B16B500B6FAC1 /* calendarserver_export */ = {isa = PBXFileReference; lastKnownFileType = text; path = calendarserver_export; sourceTree = "<group>"; };
-		66FA996C155B16B500B6FAC1 /* calendarserver_load_augmentdb */ = {isa = PBXFileReference; lastKnownFileType = text; path = calendarserver_load_augmentdb; sourceTree = "<group>"; };
-		66FA996D155B16B500B6FAC1 /* calendarserver_make_partition */ = {isa = PBXFileReference; lastKnownFileType = text; path = calendarserver_make_partition; sourceTree = "<group>"; };
-		66FA996E155B16B500B6FAC1 /* calendarserver_manage_postgres */ = {isa = PBXFileReference; lastKnownFileType = text; path = calendarserver_manage_postgres; sourceTree = "<group>"; };
-		66FA996F155B16B500B6FAC1 /* calendarserver_manage_principals */ = {isa = PBXFileReference; lastKnownFileType = text; path = calendarserver_manage_principals; sourceTree = "<group>"; };
-		66FA9970155B16B500B6FAC1 /* calendarserver_manage_push */ = {isa = PBXFileReference; lastKnownFileType = text; path = calendarserver_manage_push; sourceTree = "<group>"; };
-		66FA9971155B16B500B6FAC1 /* calendarserver_manage_timezones */ = {isa = PBXFileReference; lastKnownFileType = text; path = calendarserver_manage_timezones; sourceTree = "<group>"; };
-		66FA9972155B16B500B6FAC1 /* calendarserver_migrate_resources */ = {isa = PBXFileReference; lastKnownFileType = text; path = calendarserver_migrate_resources; sourceTree = "<group>"; };
-		66FA9973155B16B500B6FAC1 /* calendarserver_monitor_amp_notifications */ = {isa = PBXFileReference; lastKnownFileType = text; path = calendarserver_monitor_amp_notifications; sourceTree = "<group>"; };
-		66FA9974155B16B500B6FAC1 /* calendarserver_monitor_notifications */ = {isa = PBXFileReference; lastKnownFileType = text; path = calendarserver_monitor_notifications; sourceTree = "<group>"; };
-		66FA9975155B16B500B6FAC1 /* calendarserver_purge_attachments */ = {isa = PBXFileReference; lastKnownFileType = text; path = calendarserver_purge_attachments; sourceTree = "<group>"; };
-		66FA9976155B16B500B6FAC1 /* calendarserver_purge_events */ = {isa = PBXFileReference; lastKnownFileType = text; path = calendarserver_purge_events; sourceTree = "<group>"; };
-		66FA9977155B16B500B6FAC1 /* calendarserver_purge_principals */ = {isa = PBXFileReference; lastKnownFileType = text; path = calendarserver_purge_principals; sourceTree = "<group>"; };
-		66FA9978155B16B500B6FAC1 /* calendarserver_shell */ = {isa = PBXFileReference; lastKnownFileType = text; path = calendarserver_shell; sourceTree = "<group>"; };
-		66FA9979155B16B500B6FAC1 /* calendarserver_upgrade */ = {isa = PBXFileReference; lastKnownFileType = text; path = calendarserver_upgrade; sourceTree = "<group>"; };
-		66FA997A155B16B500B6FAC1 /* calendarserver_verify_data */ = {isa = PBXFileReference; lastKnownFileType = text; path = calendarserver_verify_data; sourceTree = "<group>"; };
-		66FA997B155B16B500B6FAC1 /* calendarserver_warmup */ = {isa = PBXFileReference; lastKnownFileType = text; path = calendarserver_warmup; sourceTree = "<group>"; };
-		66FA997C155B16B500B6FAC1 /* icalendar_split */ = {isa = PBXFileReference; lastKnownFileType = text; path = icalendar_split; sourceTree = "<group>"; };
-		66FA997D155B16B500B6FAC1 /* make-ssl-ca */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = "make-ssl-ca"; sourceTree = "<group>"; };
-		66FA997E155B16B500B6FAC1 /* make-ssl-key */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = "make-ssl-key"; sourceTree = "<group>"; };
-		66FA997F155B16B500B6FAC1 /* proxyclean */ = {isa = PBXFileReference; lastKnownFileType = text; path = proxyclean; sourceTree = "<group>"; };
-		66FA9980155B16B500B6FAC1 /* watch_memcached */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = watch_memcached; sourceTree = "<group>"; };
-		66FA9982155B16B500B6FAC1 /* __init__.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = __init__.py; sourceTree = "<group>"; };
-		66FA9983155B16B500B6FAC1 /* accesslog.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = accesslog.py; sourceTree = "<group>"; };
-		66FA9985155B16B500B6FAC1 /* __init__.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = __init__.py; sourceTree = "<group>"; };
-		66FA9987155B16B500B6FAC1 /* __init__.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = __init__.py; sourceTree = "<group>"; };
-		66FA9988155B16B500B6FAC1 /* _sacl.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = _sacl.c; sourceTree = "<group>"; };
-		66FA998A155B16B500B6FAC1 /* __init__.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = __init__.py; sourceTree = "<group>"; };
-		66FA998B155B16B500B6FAC1 /* dsattributes.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = dsattributes.py; sourceTree = "<group>"; };
-		66FA998C155B16B500B6FAC1 /* dsquery.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = dsquery.py; sourceTree = "<group>"; };
-		66FA998D155B16B500B6FAC1 /* odframework.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = odframework.py; sourceTree = "<group>"; };
-		66FA998E155B16B500B6FAC1 /* opendirectory.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = opendirectory.py; sourceTree = "<group>"; };
-		66FA998F155B16B500B6FAC1 /* setup_directory.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = setup_directory.py; sourceTree = "<group>"; };
-		66FA9990155B16B500B6FAC1 /* setup_testusers.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = setup_testusers.py; sourceTree = "<group>"; };
-		66FA9992155B16B500B6FAC1 /* __init__.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = __init__.py; sourceTree = "<group>"; };
-		66FA9993155B16B500B6FAC1 /* test_opendirectory.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_opendirectory.py; sourceTree = "<group>"; };
-		66FA9994155B16B500B6FAC1 /* wiki.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = wiki.py; sourceTree = "<group>"; };
-		66FA9996155B16B500B6FAC1 /* __init__.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = __init__.py; sourceTree = "<group>"; };
-		66FA9997155B16B500B6FAC1 /* root.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = root.py; sourceTree = "<group>"; };
-		66FA9999155B16B500B6FAC1 /* __init__.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = __init__.py; sourceTree = "<group>"; };
-		66FA999A155B16B500B6FAC1 /* test_root.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_root.py; sourceTree = "<group>"; };
-		66FA999C155B16B500B6FAC1 /* __init__.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = __init__.py; sourceTree = "<group>"; };
-		66FA999D155B16B500B6FAC1 /* amppush.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = amppush.py; sourceTree = "<group>"; };
-		66FA999E155B16B500B6FAC1 /* applepush.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = applepush.py; sourceTree = "<group>"; };
-		66FA99A0155B16B500B6FAC1 /* __init__.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = __init__.py; sourceTree = "<group>"; };
-		66FA99A1155B16B500B6FAC1 /* test_amppush.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_amppush.py; sourceTree = "<group>"; };
-		66FA99A2155B16B500B6FAC1 /* test_applepush.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_applepush.py; sourceTree = "<group>"; };
-		66FA99A3155B16B500B6FAC1 /* util.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = util.py; sourceTree = "<group>"; };
-		66FA99A5155B16B500B6FAC1 /* __init__.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = __init__.py; sourceTree = "<group>"; };
-		66FA99A6155B16B500B6FAC1 /* caldav.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = caldav.py; sourceTree = "<group>"; };
-		66FA99A7155B16B500B6FAC1 /* cfgchild.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = cfgchild.py; sourceTree = "<group>"; };
-		66FA99A8155B16B500B6FAC1 /* profiling.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = profiling.py; sourceTree = "<group>"; };
-		66FA99AA155B16B500B6FAC1 /* __init__.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = __init__.py; sourceTree = "<group>"; };
-		66FA99AB155B16B500B6FAC1 /* longlines.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = longlines.py; sourceTree = "<group>"; };
-		66FA99AC155B16B500B6FAC1 /* test_caldav.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_caldav.py; sourceTree = "<group>"; };
-		66FA99AD155B16B500B6FAC1 /* test_util.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_util.py; sourceTree = "<group>"; };
-		66FA99AE155B16B500B6FAC1 /* util.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = util.py; sourceTree = "<group>"; };
-		66FA99B0155B16B500B6FAC1 /* __init__.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = __init__.py; sourceTree = "<group>"; };
-		66FA99B2155B16B500B6FAC1 /* __init__.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = __init__.py; sourceTree = "<group>"; };
-		66FA99B3155B16B500B6FAC1 /* ampnotifications.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = ampnotifications.py; sourceTree = "<group>"; };
-		66FA99B4155B16B500B6FAC1 /* anonymize.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = anonymize.py; sourceTree = "<group>"; };
-		66FA99B5155B16B500B6FAC1 /* backup.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = backup.py; sourceTree = "<group>"; };
-		66FA99B6155B16B500B6FAC1 /* backup_pg.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = backup_pg.py; sourceTree = "<group>"; };
-		66FA99B7155B16B500B6FAC1 /* bootstrapdatabase.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = bootstrapdatabase.py; sourceTree = "<group>"; };
-		66FA99B8155B16B500B6FAC1 /* calverify.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = calverify.py; sourceTree = "<group>"; };
-		66FA99B9155B16B500B6FAC1 /* calverify_diff.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = calverify_diff.py; sourceTree = "<group>"; };
-		66FA99BA155B16B500B6FAC1 /* changeip_calendar.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = changeip_calendar.py; sourceTree = "<group>"; };
-		66FA99BB155B16B500B6FAC1 /* cmdline.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = cmdline.py; sourceTree = "<group>"; };
-		66FA99BC155B16B500B6FAC1 /* config.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = config.py; sourceTree = "<group>"; };
-		66FA99BD155B16B500B6FAC1 /* dbinspect.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = dbinspect.py; sourceTree = "<group>"; };
-		66FA99BE155B16B500B6FAC1 /* doublequotefix.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = doublequotefix.py; sourceTree = "<group>"; };
-		66FA99BF155B16B500B6FAC1 /* export.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = export.py; sourceTree = "<group>"; };
-		66FA99C0155B16B500B6FAC1 /* fixcalendardata.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = fixcalendardata.py; sourceTree = "<group>"; };
-		66FA99C1155B16B500B6FAC1 /* gateway.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = gateway.py; sourceTree = "<group>"; };
-		66FA99C2155B16B500B6FAC1 /* icalsplit.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = icalsplit.py; sourceTree = "<group>"; };
-		66FA99C3155B16B500B6FAC1 /* loadaugmentdb.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = loadaugmentdb.py; sourceTree = "<group>"; };
-		66FA99C4155B16B500B6FAC1 /* managepostgres.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = managepostgres.py; sourceTree = "<group>"; };
-		66FA99C5155B16B500B6FAC1 /* managetimezones.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = managetimezones.py; sourceTree = "<group>"; };
-		66FA99C6155B16B500B6FAC1 /* migrate.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = migrate.py; sourceTree = "<group>"; };
-		66FA99C7155B16B500B6FAC1 /* notifications.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = notifications.py; sourceTree = "<group>"; };
-		66FA99C8155B16B500B6FAC1 /* principals.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = principals.py; sourceTree = "<group>"; };
-		66FA99C9155B16B500B6FAC1 /* purge.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = purge.py; sourceTree = "<group>"; };
-		66FA99CA155B16B500B6FAC1 /* push.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = push.py; sourceTree = "<group>"; };
-		66FA99CB155B16B500B6FAC1 /* resources.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = resources.py; sourceTree = "<group>"; };
-		66FA99CD155B16B500B6FAC1 /* __init__.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = __init__.py; sourceTree = "<group>"; };
-		66FA99CE155B16B500B6FAC1 /* cmd.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = cmd.py; sourceTree = "<group>"; };
-		66FA99CF155B16B500B6FAC1 /* directory.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = directory.py; sourceTree = "<group>"; };
-		66FA99D0155B16B500B6FAC1 /* terminal.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = terminal.py; sourceTree = "<group>"; };
-		66FA99D2155B16B500B6FAC1 /* __init__.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = __init__.py; sourceTree = "<group>"; };
-		66FA99D3155B16B500B6FAC1 /* test_cmd.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_cmd.py; sourceTree = "<group>"; };
-		66FA99D4155B16B500B6FAC1 /* test_vfs.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_vfs.py; sourceTree = "<group>"; };
-		66FA99D5155B16B500B6FAC1 /* vfs.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = vfs.py; sourceTree = "<group>"; };
-		66FA99D6155B16B500B6FAC1 /* tables.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = tables.py; sourceTree = "<group>"; };
-		66FA99D8155B16B500B6FAC1 /* __init__.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = __init__.py; sourceTree = "<group>"; };
-		66FA99DA155B16B500B6FAC1 /* accounts.xml */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = accounts.xml; sourceTree = "<group>"; };
-		66FA99DB155B16B500B6FAC1 /* augments.xml */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = augments.xml; sourceTree = "<group>"; };
-		66FA99DC155B16B500B6FAC1 /* resources.xml */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = resources.xml; sourceTree = "<group>"; };
-		66FA99DE155B16B500B6FAC1 /* augments.xml */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = augments.xml; sourceTree = "<group>"; };
-		66FA99DF155B16B500B6FAC1 /* caldavd.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = caldavd.plist; sourceTree = "<group>"; };
-		66FA99E0155B16B500B6FAC1 /* resources-locations.xml */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = "resources-locations.xml"; sourceTree = "<group>"; };
-		66FA99E1155B16B500B6FAC1 /* users-groups.xml */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = "users-groups.xml"; sourceTree = "<group>"; };
-		66FA99E3155B16B500B6FAC1 /* augments.xml */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = augments.xml; sourceTree = "<group>"; };
-		66FA99E4155B16B500B6FAC1 /* caldavd.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = caldavd.plist; sourceTree = "<group>"; };
-		66FA99E5155B16B500B6FAC1 /* resources-locations.xml */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = "resources-locations.xml"; sourceTree = "<group>"; };
-		66FA99E6155B16B500B6FAC1 /* users-groups.xml */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = "users-groups.xml"; sourceTree = "<group>"; };
-		66FA99E8155B16B500B6FAC1 /* augments.xml */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = augments.xml; sourceTree = "<group>"; };
-		66FA99E9155B16B500B6FAC1 /* caldavd.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = caldavd.plist; sourceTree = "<group>"; };
-		66FA99EA155B16B500B6FAC1 /* resources-locations.xml */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = "resources-locations.xml"; sourceTree = "<group>"; };
-		66FA99EB155B16B500B6FAC1 /* users-groups.xml */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = "users-groups.xml"; sourceTree = "<group>"; };
-		66FA99ED155B16B500B6FAC1 /* accounts.xml */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = accounts.xml; sourceTree = "<group>"; };
-		66FA99EE155B16B500B6FAC1 /* resources.xml */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = resources.xml; sourceTree = "<group>"; };
-		66FA99EF155B16B500B6FAC1 /* test_calverify.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_calverify.py; sourceTree = "<group>"; };
-		66FA99F0155B16B500B6FAC1 /* test_changeip.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_changeip.py; sourceTree = "<group>"; };
-		66FA99F1155B16B500B6FAC1 /* test_export.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_export.py; sourceTree = "<group>"; };
-		66FA99F2155B16B500B6FAC1 /* test_gateway.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_gateway.py; sourceTree = "<group>"; };
-		66FA99F3155B16B500B6FAC1 /* test_principals.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_principals.py; sourceTree = "<group>"; };
-		66FA99F4155B16B500B6FAC1 /* test_purge.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_purge.py; sourceTree = "<group>"; };
-		66FA99F5155B16B500B6FAC1 /* test_purge_old_events.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_purge_old_events.py; sourceTree = "<group>"; };
-		66FA99F6155B16B500B6FAC1 /* test_resources.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_resources.py; sourceTree = "<group>"; };
-		66FA99F7155B16B500B6FAC1 /* test_util.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_util.py; sourceTree = "<group>"; };
-		66FA99F9155B16B500B6FAC1 /* caldavd.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = caldavd.plist; sourceTree = "<group>"; };
-		66FA99FA155B16B500B6FAC1 /* upgrade.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = upgrade.py; sourceTree = "<group>"; };
-		66FA99FB155B16B500B6FAC1 /* util.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = util.py; sourceTree = "<group>"; };
-		66FA99FC155B16B500B6FAC1 /* validcalendardata.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = validcalendardata.py; sourceTree = "<group>"; };
-		66FA99FD155B16B500B6FAC1 /* warmup.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = warmup.py; sourceTree = "<group>"; };
-		66FA99FF155B16B500B6FAC1 /* __init__.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = __init__.py; sourceTree = "<group>"; };
-		66FA9A00155B16B500B6FAC1 /* resource.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = resource.py; sourceTree = "<group>"; };
-		66FA9A01155B16B500B6FAC1 /* template.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = template.html; sourceTree = "<group>"; };
-		66FA9A03155B16B500B6FAC1 /* __init__.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = __init__.py; sourceTree = "<group>"; };
-		66FA9A04155B16B500B6FAC1 /* test_resource.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_resource.py; sourceTree = "<group>"; };
-		66FA9A06155B16B500B6FAC1 /* __init__.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = __init__.py; sourceTree = "<group>"; };
-		66FA9A07155B16B500B6FAC1 /* resource.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = resource.py; sourceTree = "<group>"; };
-		66FA9A0A155B16B500B6FAC1 /* accounts-test.xml */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = "accounts-test.xml"; sourceTree = "<group>"; };
-		66FA9A0B155B16B500B6FAC1 /* accounts.dtd */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = accounts.dtd; sourceTree = "<group>"; };
-		66FA9A0C155B16B500B6FAC1 /* accounts.xml */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = accounts.xml; sourceTree = "<group>"; };
-		66FA9A0D155B16B500B6FAC1 /* augments-default.xml */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = "augments-default.xml"; sourceTree = "<group>"; };
-		66FA9A0E155B16B500B6FAC1 /* augments-test.xml */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = "augments-test.xml"; sourceTree = "<group>"; };
-		66FA9A0F155B16B500B6FAC1 /* augments.dtd */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = augments.dtd; sourceTree = "<group>"; };
-		66FA9A10155B16B500B6FAC1 /* proxies-test.xml */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = "proxies-test.xml"; sourceTree = "<group>"; };
-		66FA9A11155B16B500B6FAC1 /* proxies.dtd */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = proxies.dtd; sourceTree = "<group>"; };
-		66FA9A12155B16B500B6FAC1 /* resources-test.xml */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = "resources-test.xml"; sourceTree = "<group>"; };
-		66FA9A13155B16B500B6FAC1 /* caldavd-apple.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "caldavd-apple.plist"; sourceTree = "<group>"; };
-		66FA9A14155B16B500B6FAC1 /* caldavd-partitioning-primary.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "caldavd-partitioning-primary.plist"; sourceTree = "<group>"; };
-		66FA9A15155B16B500B6FAC1 /* caldavd-partitioning-secondary.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "caldavd-partitioning-secondary.plist"; sourceTree = "<group>"; };
-		66FA9A16155B16B500B6FAC1 /* caldavd-test.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "caldavd-test.plist"; sourceTree = "<group>"; };
-		66FA9A17155B16B500B6FAC1 /* caldavd.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = caldavd.plist; sourceTree = "<group>"; };
-		66FA9A18155B16B500B6FAC1 /* mime.types */ = {isa = PBXFileReference; lastKnownFileType = text; path = mime.types; sourceTree = "<group>"; };
-		66FA9A1A155B16B500B6FAC1 /* caldavd-resources.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "caldavd-resources.plist"; sourceTree = "<group>"; };
-		66FA9A1B155B16B500B6FAC1 /* locations-resources-orig.xml */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = "locations-resources-orig.xml"; sourceTree = "<group>"; };
-		66FA9A1C155B16B500B6FAC1 /* locations-resources.xml */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = "locations-resources.xml"; sourceTree = "<group>"; };
-		66FA9A1D155B16B500B6FAC1 /* users-groups.xml */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = "users-groups.xml"; sourceTree = "<group>"; };
-		66FA9A1E155B16B500B6FAC1 /* resources.xml */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = resources.xml; sourceTree = "<group>"; };
-		66FA9A1F155B16B500B6FAC1 /* servers-test.xml */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = "servers-test.xml"; sourceTree = "<group>"; };
-		66FA9A20155B16B500B6FAC1 /* servers.dtd */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = servers.dtd; sourceTree = "<group>"; };
-		66FA9A21155B16B500B6FAC1 /* servers.xml */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = servers.xml; sourceTree = "<group>"; };
-		66FA9A22155B16B500B6FAC1 /* servertoserver-test.xml */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = "servertoserver-test.xml"; sourceTree = "<group>"; };
-		66FA9A23155B16B500B6FAC1 /* servertoserver.dtd */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = servertoserver.dtd; sourceTree = "<group>"; };
-		66FA9A24155B16B500B6FAC1 /* servertoserver.xml */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = servertoserver.xml; sourceTree = "<group>"; };
-		66FA9A25155B16B500B6FAC1 /* sudoers.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = sudoers.plist; sourceTree = "<group>"; };
-		66FA9A27155B16B500B6FAC1 /* __init__.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = __init__.py; sourceTree = "<group>"; };
-		66FA9A28155B16B500B6FAC1 /* CalendarServer.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = CalendarServer.png; sourceTree = "<group>"; };
-		66FA9A2A155B16B500B6FAC1 /* __init__.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = __init__.py; sourceTree = "<group>"; };
-		66FA9A2B155B16B500B6FAC1 /* calendarcertupdate.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = calendarcertupdate.py; sourceTree = "<group>"; };
-		66FA9A2D155B16B500B6FAC1 /* __init__.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = __init__.py; sourceTree = "<group>"; };
-		66FA9A2E155B16B500B6FAC1 /* test_certupdate.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_certupdate.py; sourceTree = "<group>"; };
-		66FA9A2F155B16B500B6FAC1 /* create_caldavd_db.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = create_caldavd_db.sh; sourceTree = "<group>"; };
-		66FA9A30155B16B500B6FAC1 /* iCalServer.ico */ = {isa = PBXFileReference; lastKnownFileType = image.ico; path = iCalServer.ico; sourceTree = "<group>"; };
-		66FA9A32155B16B500B6FAC1 /* calendarserver.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = calendarserver.plist; sourceTree = "<group>"; };
-		66FA9A34155B16B500B6FAC1 /* __init__.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = __init__.py; sourceTree = "<group>"; };
-		66FA9A35155B16B500B6FAC1 /* calendarmigrator.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = calendarmigrator.py; sourceTree = "<group>"; };
-		66FA9A36155B16B500B6FAC1 /* calendarpromotion.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = calendarpromotion.py; sourceTree = "<group>"; };
-		66FA9A38155B16B500B6FAC1 /* __init__.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = __init__.py; sourceTree = "<group>"; };
-		66FA9A39155B16B500B6FAC1 /* test_migrator.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_migrator.py; sourceTree = "<group>"; };
-		66FA9A3B155B16B500B6FAC1 /* __init__.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = __init__.py; sourceTree = "<group>"; };
-		66FA9A3C155B16B500B6FAC1 /* _event_change.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = _event_change.py; sourceTree = "<group>"; };
-		66FA9A3D155B16B500B6FAC1 /* _event_create.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = _event_create.py; sourceTree = "<group>"; };
-		66FA9A3E155B16B500B6FAC1 /* benchlib.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = benchlib.py; sourceTree = "<group>"; };
-		66FA9A3F155B16B500B6FAC1 /* benchlib.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = benchlib.sh; sourceTree = "<group>"; };
-		66FA9A40155B16B500B6FAC1 /* benchmark */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = benchmark; sourceTree = "<group>"; };
-		66FA9A41155B16B500B6FAC1 /* benchmark.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = benchmark.py; sourceTree = "<group>"; };
-		66FA9A43155B16B500B6FAC1 /* __init__.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = __init__.py; sourceTree = "<group>"; };
-		66FA9A44155B16B500B6FAC1 /* bounded_recurrence.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = bounded_recurrence.py; sourceTree = "<group>"; };
-		66FA9A45155B16B500B6FAC1 /* bounded_recurrence_autoaccept.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = bounded_recurrence_autoaccept.py; sourceTree = "<group>"; };
-		66FA9A46155B16B500B6FAC1 /* event.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = event.py; sourceTree = "<group>"; };
-		66FA9A47155B16B500B6FAC1 /* event_add_attendee.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = event_add_attendee.py; sourceTree = "<group>"; };
-		66FA9A48155B16B500B6FAC1 /* event_autoaccept.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = event_autoaccept.py; sourceTree = "<group>"; };
-		66FA9A49155B16B500B6FAC1 /* event_change_date.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = event_change_date.py; sourceTree = "<group>"; };
-		66FA9A4A155B16B500B6FAC1 /* event_change_summary.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = event_change_summary.py; sourceTree = "<group>"; };
-		66FA9A4B155B16B500B6FAC1 /* event_delete.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = event_delete.py; sourceTree = "<group>"; };
-		66FA9A4C155B16B500B6FAC1 /* event_delete_attendee.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = event_delete_attendee.py; sourceTree = "<group>"; };
-		66FA9A4D155B16B500B6FAC1 /* event_move.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = event_move.py; sourceTree = "<group>"; };
-		66FA9A4E155B16B500B6FAC1 /* find_calendars.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = find_calendars.py; sourceTree = "<group>"; };
-		66FA9A4F155B16B500B6FAC1 /* find_events.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = find_events.py; sourceTree = "<group>"; };
-		66FA9A50155B16B500B6FAC1 /* unbounded_recurrence.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = unbounded_recurrence.py; sourceTree = "<group>"; };
-		66FA9A51155B16B500B6FAC1 /* unbounded_recurrence_autoaccept.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = unbounded_recurrence_autoaccept.py; sourceTree = "<group>"; };
-		66FA9A52155B16B500B6FAC1 /* vfreebusy.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = vfreebusy.py; sourceTree = "<group>"; };
-		66FA9A53155B16B500B6FAC1 /* vfreebusy_vary_attendees.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = vfreebusy_vary_attendees.py; sourceTree = "<group>"; };
-		66FA9A54155B16B500B6FAC1 /* compare */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = compare; sourceTree = "<group>"; };
-		66FA9A55155B16B500B6FAC1 /* compare.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = compare.py; sourceTree = "<group>"; };
-		66FA9A56155B16B500B6FAC1 /* display-calendar-events.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = "display-calendar-events.py"; sourceTree = "<group>"; };
-		66FA9A57155B16B500B6FAC1 /* eventkitframework.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = eventkitframework.py; sourceTree = "<group>"; };
-		66FA9A58155B16B500B6FAC1 /* extractconf */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = extractconf; sourceTree = "<group>"; };
-		66FA9A59155B16B500B6FAC1 /* fix-units.sql */ = {isa = PBXFileReference; lastKnownFileType = text; path = "fix-units.sql"; sourceTree = "<group>"; };
-		66FA9A5A155B16B500B6FAC1 /* graph */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = graph; sourceTree = "<group>"; };
-		66FA9A5B155B16B500B6FAC1 /* graph.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = graph.py; sourceTree = "<group>"; };
-		66FA9A5C155B16B500B6FAC1 /* httpauth.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = httpauth.py; sourceTree = "<group>"; };
-		66FA9A5D155B16B500B6FAC1 /* httpclient.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = httpclient.py; sourceTree = "<group>"; };
-		66FA9A5E155B16B500B6FAC1 /* io_measure.d */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.dtrace; path = io_measure.d; sourceTree = "<group>"; };
-		66FA9A60155B16B500B6FAC1 /* __init__.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = __init__.py; sourceTree = "<group>"; };
-		66FA9A61155B16B500B6FAC1 /* accounts.csv */ = {isa = PBXFileReference; lastKnownFileType = text; path = accounts.csv; sourceTree = "<group>"; };
-		66FA9A62155B16B500B6FAC1 /* ampsim.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = ampsim.py; sourceTree = "<group>"; };
-		66FA9A63155B16B500B6FAC1 /* config.dist.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = config.dist.plist; sourceTree = "<group>"; };
-		66FA9A64155B16B500B6FAC1 /* config.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = config.plist; sourceTree = "<group>"; };
-		66FA9A65155B16B500B6FAC1 /* ical.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = ical.py; sourceTree = "<group>"; };
-		66FA9A66155B16B500B6FAC1 /* logger.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = logger.py; sourceTree = "<group>"; };
-		66FA9A67155B16B500B6FAC1 /* population.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = population.py; sourceTree = "<group>"; };
-		66FA9A68155B16B500B6FAC1 /* profiles.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = profiles.py; sourceTree = "<group>"; };
-		66FA9A6B155B16B500B6FAC1 /* poll_calendar_multiget.request */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = poll_calendar_multiget.request; sourceTree = "<group>"; };
-		66FA9A6C155B16B500B6FAC1 /* poll_calendar_multiget_hrefs.request */ = {isa = PBXFileReference; lastKnownFileType = text; path = poll_calendar_multiget_hrefs.request; sourceTree = "<group>"; };
-		66FA9A6D155B16B500B6FAC1 /* poll_calendar_propfind.request */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = poll_calendar_propfind.request; sourceTree = "<group>"; };
-		66FA9A6E155B16B500B6FAC1 /* poll_calendar_propfind_d1.request */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = poll_calendar_propfind_d1.request; sourceTree = "<group>"; };
-		66FA9A6F155B16B500B6FAC1 /* poll_calendar_vevent_tr_query.request */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = poll_calendar_vevent_tr_query.request; sourceTree = "<group>"; };
-		66FA9A70155B16B500B6FAC1 /* poll_calendar_vtodo_query.request */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = poll_calendar_vtodo_query.request; sourceTree = "<group>"; };
-		66FA9A71155B16B500B6FAC1 /* poll_calendarhome_propfind.request */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = poll_calendarhome_propfind.request; sourceTree = "<group>"; };
-		66FA9A72155B16B500B6FAC1 /* Profile */ = {isa = PBXFileReference; lastKnownFileType = text; path = Profile; sourceTree = "<group>"; };
-		66FA9A73155B16B500B6FAC1 /* startup_calendar_color_proppatch.request */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = startup_calendar_color_proppatch.request; sourceTree = "<group>"; };
-		66FA9A74155B16B500B6FAC1 /* startup_calendar_order_proppatch.request */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = startup_calendar_order_proppatch.request; sourceTree = "<group>"; };
-		66FA9A75155B16B500B6FAC1 /* startup_principal_propfind.request */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = startup_principal_propfind.request; sourceTree = "<group>"; };
-		66FA9A76155B16B500B6FAC1 /* startup_principal_propfind_initial.request */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = startup_principal_propfind_initial.request; sourceTree = "<group>"; };
-		66FA9A77155B16B500B6FAC1 /* startup_principals_report.request */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = startup_principals_report.request; sourceTree = "<group>"; };
-		66FA9A78155B16B500B6FAC1 /* startup_well_known.request */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = startup_well_known.request; sourceTree = "<group>"; };
-		66FA9A7A155B16B500B6FAC1 /* poll_calendar_multiget.request */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = poll_calendar_multiget.request; sourceTree = "<group>"; };
-		66FA9A7B155B16B500B6FAC1 /* poll_calendar_multiget_hrefs.request */ = {isa = PBXFileReference; lastKnownFileType = text; path = poll_calendar_multiget_hrefs.request; sourceTree = "<group>"; };
-		66FA9A7C155B16B500B6FAC1 /* poll_calendar_propfind.request */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = poll_calendar_propfind.request; sourceTree = "<group>"; };
-		66FA9A7D155B16B500B6FAC1 /* poll_calendar_propfind_d1.request */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = poll_calendar_propfind_d1.request; sourceTree = "<group>"; };
-		66FA9A7E155B16B500B6FAC1 /* poll_calendarhome_propfind.request */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = poll_calendarhome_propfind.request; sourceTree = "<group>"; };
-		66FA9A7F155B16B500B6FAC1 /* poll_notification_propfind_d1.request */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = poll_notification_propfind_d1.request; sourceTree = "<group>"; };
-		66FA9A80155B16B500B6FAC1 /* post_availability.request */ = {isa = PBXFileReference; lastKnownFileType = text; path = post_availability.request; sourceTree = "<group>"; };
-		66FA9A81155B16B500B6FAC1 /* startup_calendar_color_proppatch.request */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = startup_calendar_color_proppatch.request; sourceTree = "<group>"; };
-		66FA9A82155B16B500B6FAC1 /* startup_calendar_order_proppatch.request */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = startup_calendar_order_proppatch.request; sourceTree = "<group>"; };
-		66FA9A83155B16B500B6FAC1 /* startup_calendar_timezone_proppatch.request */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = startup_calendar_timezone_proppatch.request; sourceTree = "<group>"; };
-		66FA9A84155B16B500B6FAC1 /* startup_notification_propfind.request */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = startup_notification_propfind.request; sourceTree = "<group>"; };
-		66FA9A85155B16B500B6FAC1 /* startup_principal_expand.request */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = startup_principal_expand.request; sourceTree = "<group>"; };
-		66FA9A86155B16B500B6FAC1 /* startup_principal_propfind.request */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = startup_principal_propfind.request; sourceTree = "<group>"; };
-		66FA9A87155B16B500B6FAC1 /* startup_principal_propfind_initial.request */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = startup_principal_propfind_initial.request; sourceTree = "<group>"; };
-		66FA9A88155B16B500B6FAC1 /* startup_principals_report.request */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = startup_principals_report.request; sourceTree = "<group>"; };
-		66FA9A89155B16B500B6FAC1 /* startup_well_known.request */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = startup_well_known.request; sourceTree = "<group>"; };
-		66FA9A8A155B16B500B6FAC1 /* user_list_principal_property_search.request */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = user_list_principal_property_search.request; sourceTree = "<group>"; };
-		66FA9A8C155B16B500B6FAC1 /* poll_calendar_multiget.request */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = poll_calendar_multiget.request; sourceTree = "<group>"; };
-		66FA9A8D155B16B500B6FAC1 /* poll_calendar_multiget_hrefs.request */ = {isa = PBXFileReference; lastKnownFileType = text; path = poll_calendar_multiget_hrefs.request; sourceTree = "<group>"; };
-		66FA9A8E155B16B500B6FAC1 /* poll_calendar_propfind.request */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = poll_calendar_propfind.request; sourceTree = "<group>"; };
-		66FA9A8F155B16B500B6FAC1 /* poll_calendar_propfind_d1.request */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = poll_calendar_propfind_d1.request; sourceTree = "<group>"; };
-		66FA9A90155B16B500B6FAC1 /* poll_calendar_sync.request */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = poll_calendar_sync.request; sourceTree = "<group>"; };
-		66FA9A91155B16B500B6FAC1 /* poll_calendarhome_propfind.request */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = poll_calendarhome_propfind.request; sourceTree = "<group>"; };
-		66FA9A92155B16B500B6FAC1 /* poll_notification_propfind_d1.request */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = poll_notification_propfind_d1.request; sourceTree = "<group>"; };
-		66FA9A93155B16B500B6FAC1 /* post_availability.request */ = {isa = PBXFileReference; lastKnownFileType = text; path = post_availability.request; sourceTree = "<group>"; };
-		66FA9A94155B16B500B6FAC1 /* Profile */ = {isa = PBXFileReference; lastKnownFileType = text; path = Profile; sourceTree = "<group>"; };
-		66FA9A95155B16B500B6FAC1 /* startup_calendar_color_proppatch.request */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = startup_calendar_color_proppatch.request; sourceTree = "<group>"; };
-		66FA9A96155B16B500B6FAC1 /* startup_calendar_order_proppatch.request */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = startup_calendar_order_proppatch.request; sourceTree = "<group>"; };
-		66FA9A97155B16B500B6FAC1 /* startup_calendar_timezone_proppatch.request */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = startup_calendar_timezone_proppatch.request; sourceTree = "<group>"; };
-		66FA9A98155B16B500B6FAC1 /* startup_delegate_principal_propfind.request */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = startup_delegate_principal_propfind.request; sourceTree = "<group>"; };
-		66FA9A99155B16B500B6FAC1 /* startup_principal_expand.request */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = startup_principal_expand.request; sourceTree = "<group>"; };
-		66FA9A9A155B16B500B6FAC1 /* startup_principal_propfind.request */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = startup_principal_propfind.request; sourceTree = "<group>"; };
-		66FA9A9B155B16B500B6FAC1 /* startup_principal_propfind_initial.request */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = startup_principal_propfind_initial.request; sourceTree = "<group>"; };
-		66FA9A9C155B16B500B6FAC1 /* startup_principals_report.request */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = startup_principals_report.request; sourceTree = "<group>"; };
-		66FA9A9D155B16B500B6FAC1 /* startup_well_known.request */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = startup_well_known.request; sourceTree = "<group>"; };
-		66FA9A9E155B16B500B6FAC1 /* user_list_principal_property_search.request */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = user_list_principal_property_search.request; sourceTree = "<group>"; };
-		66FA9A9F155B16B500B6FAC1 /* sim.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = sim.py; sourceTree = "<group>"; };
-		66FA9AA0155B16B500B6FAC1 /* subscribe.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = subscribe.py; sourceTree = "<group>"; };
-		66FA9AA1155B16B500B6FAC1 /* test_ical.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_ical.py; sourceTree = "<group>"; };
-		66FA9AA2155B16B500B6FAC1 /* test_population.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_population.py; sourceTree = "<group>"; };
-		66FA9AA3155B16B500B6FAC1 /* test_profiles.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_profiles.py; sourceTree = "<group>"; };
-		66FA9AA4155B16B500B6FAC1 /* test_sim.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_sim.py; sourceTree = "<group>"; };
-		66FA9AA5155B16B500B6FAC1 /* test_trafficlogger.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_trafficlogger.py; sourceTree = "<group>"; };
-		66FA9AA6155B16B500B6FAC1 /* test_webadmin.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_webadmin.py; sourceTree = "<group>"; };
-		66FA9AA7155B16B500B6FAC1 /* trafficlogger.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = trafficlogger.py; sourceTree = "<group>"; };
-		66FA9AA8155B16B500B6FAC1 /* webadmin.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = webadmin.py; sourceTree = "<group>"; };
-		66FA9AA9155B16B500B6FAC1 /* massupload */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = massupload; sourceTree = "<group>"; };
-		66FA9AAA155B16B500B6FAC1 /* massupload.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = massupload.py; sourceTree = "<group>"; };
-		66FA9AAB155B16B500B6FAC1 /* nightly.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = nightly.sh; sourceTree = "<group>"; };
-		66FA9AAC155B16B500B6FAC1 /* pgsql.d */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.dtrace; path = pgsql.d; sourceTree = "<group>"; };
-		66FA9AAD155B16B500B6FAC1 /* profile.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = profile.sh; sourceTree = "<group>"; };
-		66FA9AAE155B16B500B6FAC1 /* report */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = report; sourceTree = "<group>"; };
-		66FA9AAF155B16B500B6FAC1 /* report.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = report.py; sourceTree = "<group>"; };
-		66FA9AB0155B16B500B6FAC1 /* report_principals.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = report_principals.py; sourceTree = "<group>"; };
-		66FA9AB1155B16B500B6FAC1 /* reupload.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = reupload.sh; sourceTree = "<group>"; };
-		66FA9AB2155B16B500B6FAC1 /* sample-many.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = "sample-many.sh"; sourceTree = "<group>"; };
-		66FA9AB3155B16B500B6FAC1 /* sample.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = sample.sh; sourceTree = "<group>"; };
-		66FA9AB4155B16B500B6FAC1 /* setbackend */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = setbackend; sourceTree = "<group>"; };
-		66FA9AB5155B16B500B6FAC1 /* setbackend.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = setbackend.py; sourceTree = "<group>"; };
-		66FA9AB6155B16B500B6FAC1 /* sim */ = {isa = PBXFileReference; lastKnownFileType = text; path = sim; sourceTree = "<group>"; };
-		66FA9AB7155B16B500B6FAC1 /* some-more-data.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = "some-more-data.sh"; sourceTree = "<group>"; };
-		66FA9AB8155B16B500B6FAC1 /* speedcenter.tac */ = {isa = PBXFileReference; lastKnownFileType = text; path = speedcenter.tac; sourceTree = "<group>"; };
-		66FA9AB9155B16B500B6FAC1 /* sql_measure.d */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.dtrace; path = sql_measure.d; sourceTree = "<group>"; };
-		66FA9ABA155B16B500B6FAC1 /* sqlwatch */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = sqlwatch; sourceTree = "<group>"; };
-		66FA9ABB155B16B500B6FAC1 /* sqlwatch.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = sqlwatch.py; sourceTree = "<group>"; };
-		66FA9ABC155B16B500B6FAC1 /* stackedbar.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = stackedbar.py; sourceTree = "<group>"; };
-		66FA9ABD155B16B500B6FAC1 /* stats.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = stats.py; sourceTree = "<group>"; };
-		66FA9ABE155B16B500B6FAC1 /* sudo-run.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = "sudo-run.sh"; sourceTree = "<group>"; };
-		66FA9ABF155B16B500B6FAC1 /* svn-committime */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = "svn-committime"; sourceTree = "<group>"; };
-		66FA9AC0155B16B500B6FAC1 /* svn-revno */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = "svn-revno"; sourceTree = "<group>"; };
-		66FA9AC1155B16B500B6FAC1 /* test_benchmark.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_benchmark.py; sourceTree = "<group>"; };
-		66FA9AC2155B16B500B6FAC1 /* test_event_change_date.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_event_change_date.py; sourceTree = "<group>"; };
-		66FA9AC3155B16B500B6FAC1 /* test_stats.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_stats.py; sourceTree = "<group>"; };
-		66FA9AC4155B16B500B6FAC1 /* upload */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = upload; sourceTree = "<group>"; };
-		66FA9AC5155B16B500B6FAC1 /* upload.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = upload.py; sourceTree = "<group>"; };
-		66FA9AC7155B16B500B6FAC1 /* anonymous_log.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = anonymous_log.py; sourceTree = "<group>"; };
-		66FA9AC8155B16B500B6FAC1 /* dtraceanalyze.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = dtraceanalyze.py; sourceTree = "<group>"; };
-		66FA9AC9155B16B500B6FAC1 /* fakecalendardata.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = fakecalendardata.py; sourceTree = "<group>"; };
-		66FA9ACA155B16B500B6FAC1 /* fix_calendar */ = {isa = PBXFileReference; lastKnownFileType = text; path = fix_calendar; sourceTree = "<group>"; };
-		66FA9ACB155B16B500B6FAC1 /* harpoon.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = harpoon.py; sourceTree = "<group>"; };
-		66FA9ACC155B16B500B6FAC1 /* monitoranalysis.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = monitoranalysis.py; sourceTree = "<group>"; };
-		66FA9ACD155B16B500B6FAC1 /* monitorsplit.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = monitorsplit.py; sourceTree = "<group>"; };
-		66FA9ACE155B16B500B6FAC1 /* netstatus.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = netstatus.py; sourceTree = "<group>"; };
-		66FA9ACF155B16B500B6FAC1 /* pg_stats_analysis.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = pg_stats_analysis.py; sourceTree = "<group>"; };
-		66FA9AD0155B16B500B6FAC1 /* pgtrace.d */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.dtrace; path = pgtrace.d; sourceTree = "<group>"; };
-		66FA9AD1155B16B500B6FAC1 /* protocolanalysis.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = protocolanalysis.py; sourceTree = "<group>"; };
-		66FA9AD2155B16B500B6FAC1 /* request_monitor.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = request_monitor.py; sourceTree = "<group>"; };
-		66FA9AD3155B16B500B6FAC1 /* sortrecurrences.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = sortrecurrences.py; sourceTree = "<group>"; };
-		66FA9AD4155B16B500B6FAC1 /* sqldata_from_path.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = sqldata_from_path.py; sourceTree = "<group>"; };
-		66FA9AD5155B16B500B6FAC1 /* tables.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = tables.py; sourceTree = "<group>"; };
-		66FA9AD6155B16B500B6FAC1 /* test_protocolanalysis.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_protocolanalysis.py; sourceTree = "<group>"; };
-		66FA9AD7155B16B500B6FAC1 /* trace.d */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.dtrace; path = trace.d; sourceTree = "<group>"; };
-		66FA9ADA155B16B500B6FAC1 /* DirectoryService-Apache.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = "DirectoryService-Apache.txt"; sourceTree = "<group>"; };
-		66FA9ADB155B16B500B6FAC1 /* DirectoryService-OpenDirectory.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = "DirectoryService-OpenDirectory.txt"; sourceTree = "<group>"; };
-		66FA9ADC155B16B500B6FAC1 /* DirectoryService-XML.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = "DirectoryService-XML.txt"; sourceTree = "<group>"; };
-		66FA9ADD155B16B500B6FAC1 /* DirectoryServices.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = DirectoryServices.txt; sourceTree = "<group>"; };
-		66FA9ADE155B16B500B6FAC1 /* ExtendedLogItems.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = ExtendedLogItems.txt; sourceTree = "<group>"; };
-		66FA9ADF155B16B500B6FAC1 /* LoadSimulation.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = LoadSimulation.txt; sourceTree = "<group>"; };
-		66FA9AE0155B16B500B6FAC1 /* MultiServerDeployment.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = MultiServerDeployment.txt; sourceTree = "<group>"; };
-		66FA9AE1155B16B500B6FAC1 /* caldavd.8 */ = {isa = PBXFileReference; lastKnownFileType = text; path = caldavd.8; sourceTree = "<group>"; };
-		66FA9AE2155B16B500B6FAC1 /* calendarserver_bootstrap_database.8 */ = {isa = PBXFileReference; lastKnownFileType = text; path = calendarserver_bootstrap_database.8; sourceTree = "<group>"; };
-		66FA9AE3155B16B500B6FAC1 /* calendarserver_command_gateway.8 */ = {isa = PBXFileReference; lastKnownFileType = text; path = calendarserver_command_gateway.8; sourceTree = "<group>"; };
-		66FA9AE4155B16B500B6FAC1 /* calendarserver_export.8 */ = {isa = PBXFileReference; lastKnownFileType = text; path = calendarserver_export.8; sourceTree = "<group>"; };
-		66FA9AE5155B16B500B6FAC1 /* calendarserver_manage_principals.8 */ = {isa = PBXFileReference; lastKnownFileType = text; path = calendarserver_manage_principals.8; sourceTree = "<group>"; };
-		66FA9AE6155B16B500B6FAC1 /* calendarserver_manage_push.8 */ = {isa = PBXFileReference; lastKnownFileType = text; path = calendarserver_manage_push.8; sourceTree = "<group>"; };
-		66FA9AE7155B16B500B6FAC1 /* calendarserver_migrate_resources.8 */ = {isa = PBXFileReference; lastKnownFileType = text; path = calendarserver_migrate_resources.8; sourceTree = "<group>"; };
-		66FA9AE8155B16B500B6FAC1 /* calendarserver_monitor_notifications.8 */ = {isa = PBXFileReference; lastKnownFileType = text; path = calendarserver_monitor_notifications.8; sourceTree = "<group>"; };
-		66FA9AE9155B16B500B6FAC1 /* calendarserver_purge_attachments.8 */ = {isa = PBXFileReference; lastKnownFileType = text; path = calendarserver_purge_attachments.8; sourceTree = "<group>"; };
-		66FA9AEA155B16B500B6FAC1 /* calendarserver_purge_events.8 */ = {isa = PBXFileReference; lastKnownFileType = text; path = calendarserver_purge_events.8; sourceTree = "<group>"; };
-		66FA9AEB155B16B500B6FAC1 /* calendarserver_purge_principals.8 */ = {isa = PBXFileReference; lastKnownFileType = text; path = calendarserver_purge_principals.8; sourceTree = "<group>"; };
-		66FA9AEC155B16B500B6FAC1 /* calendarserver_shell.8 */ = {isa = PBXFileReference; lastKnownFileType = text; path = calendarserver_shell.8; sourceTree = "<group>"; };
-		66FA9AEE155B16B500B6FAC1 /* Principal Bootstrap.graffle.zip */ = {isa = PBXFileReference; lastKnownFileType = archive.zip; path = "Principal Bootstrap.graffle.zip"; sourceTree = "<group>"; };
-		66FA9AEF155B16B500B6FAC1 /* Principal Bootstrap.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; path = "Principal Bootstrap.pdf"; sourceTree = "<group>"; };
-		66FA9AF1155B16B500B6FAC1 /* Calendar Store API.graffle */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = "Calendar Store API.graffle"; sourceTree = "<group>"; };
-		66FA9AF2155B16B500B6FAC1 /* Calendar Store Schema.graffle */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = "Calendar Store Schema.graffle"; sourceTree = "<group>"; };
-		66FA9AF3155B16B500B6FAC1 /* gendocs */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = gendocs; sourceTree = "<group>"; };
-		66FA9AF5155B16B500B6FAC1 /* caldav-ctag.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = "caldav-ctag.txt"; sourceTree = "<group>"; };
-		66FA9AF6155B16B500B6FAC1 /* caldav-ctag.xml */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = "caldav-ctag.xml"; sourceTree = "<group>"; };
-		66FA9AF7155B16B500B6FAC1 /* caldav-notifications.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = "caldav-notifications.txt"; sourceTree = "<group>"; };
-		66FA9AF8155B16B500B6FAC1 /* caldav-notifications.xml */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = "caldav-notifications.xml"; sourceTree = "<group>"; };
-		66FA9AF9155B16B500B6FAC1 /* caldav-privatecomments.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = "caldav-privatecomments.txt"; sourceTree = "<group>"; };
-		66FA9AFA155B16B500B6FAC1 /* caldav-privatecomments.xml */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = "caldav-privatecomments.xml"; sourceTree = "<group>"; };
-		66FA9AFB155B16B500B6FAC1 /* caldav-privateevents.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = "caldav-privateevents.txt"; sourceTree = "<group>"; };
-		66FA9AFC155B16B500B6FAC1 /* caldav-privateevents.xml */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = "caldav-privateevents.xml"; sourceTree = "<group>"; };
-		66FA9AFD155B16B500B6FAC1 /* caldav-proxy.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = "caldav-proxy.txt"; sourceTree = "<group>"; };
-		66FA9AFE155B16B500B6FAC1 /* caldav-proxy.xml */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = "caldav-proxy.xml"; sourceTree = "<group>"; };
-		66FA9AFF155B16B500B6FAC1 /* caldav-pubsubdiscovery.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = "caldav-pubsubdiscovery.txt"; sourceTree = "<group>"; };
-		66FA9B00155B16B500B6FAC1 /* caldav-pubsubdiscovery.xml */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = "caldav-pubsubdiscovery.xml"; sourceTree = "<group>"; };
-		66FA9B01155B16B500B6FAC1 /* caldav-schedulingchanges.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = "caldav-schedulingchanges.txt"; sourceTree = "<group>"; };
-		66FA9B02155B16B500B6FAC1 /* caldav-schedulingchanges.xml */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = "caldav-schedulingchanges.xml"; sourceTree = "<group>"; };
-		66FA9B03155B16B500B6FAC1 /* caldav-sharing-02.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = "caldav-sharing-02.txt"; sourceTree = "<group>"; };
-		66FA9B04155B16B500B6FAC1 /* caldav-sharing-02.xml */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = "caldav-sharing-02.xml"; sourceTree = "<group>"; };
-		66FA9B05155B16B500B6FAC1 /* icalendar-maskuids.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = "icalendar-maskuids.txt"; sourceTree = "<group>"; };
-		66FA9B06155B16B500B6FAC1 /* icalendar-maskuids.xml */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = "icalendar-maskuids.xml"; sourceTree = "<group>"; };
-		66FA9B08155B16B500B6FAC1 /* draft-daboo-caldav-extensions.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = "draft-daboo-caldav-extensions.txt"; sourceTree = "<group>"; };
-		66FA9B09155B16B500B6FAC1 /* draft-daboo-calendar-availability.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = "draft-daboo-calendar-availability.txt"; sourceTree = "<group>"; };
-		66FA9B0A155B16B500B6FAC1 /* draft-daboo-carddav-directory-gateway.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = "draft-daboo-carddav-directory-gateway.txt"; sourceTree = "<group>"; };
-		66FA9B0B155B16B500B6FAC1 /* draft-daboo-srv-caldav.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = "draft-daboo-srv-caldav.txt"; sourceTree = "<group>"; };
-		66FA9B0C155B16B500B6FAC1 /* draft-desruisseaux-caldav-sched.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = "draft-desruisseaux-caldav-sched.txt"; sourceTree = "<group>"; };
-		66FA9B0D155B16B500B6FAC1 /* draft-desruisseaux-ischedule.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = "draft-desruisseaux-ischedule.txt"; sourceTree = "<group>"; };
-		66FA9B0E155B16B500B6FAC1 /* rfc2616-HTTP.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = "rfc2616-HTTP.txt"; sourceTree = "<group>"; };
-		66FA9B0F155B16B500B6FAC1 /* rfc2617-HTTP Auth.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = "rfc2617-HTTP Auth.txt"; sourceTree = "<group>"; };
-		66FA9B10155B16B500B6FAC1 /* rfc3253-DeltaV.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = "rfc3253-DeltaV.txt"; sourceTree = "<group>"; };
-		66FA9B11155B16B500B6FAC1 /* rfc3283-Calendaring.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = "rfc3283-Calendaring.txt"; sourceTree = "<group>"; };
-		66FA9B12155B16B500B6FAC1 /* rfc3744-WebDAV ACL.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = "rfc3744-WebDAV ACL.txt"; sourceTree = "<group>"; };
-		66FA9B13155B16B500B6FAC1 /* rfc4331-WebDAV Quota.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = "rfc4331-WebDAV Quota.txt"; sourceTree = "<group>"; };
-		66FA9B14155B16B500B6FAC1 /* rfc4559-SPNEGO.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = "rfc4559-SPNEGO.txt"; sourceTree = "<group>"; };
-		66FA9B15155B16B500B6FAC1 /* rfc4791-CalDAV.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = "rfc4791-CalDAV.txt"; sourceTree = "<group>"; };
-		66FA9B16155B16B500B6FAC1 /* rfc4918-WebDAV.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = "rfc4918-WebDAV.txt"; sourceTree = "<group>"; };
-		66FA9B17155B16B500B6FAC1 /* rfc5397-Current Principal.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = "rfc5397-Current Principal.txt"; sourceTree = "<group>"; };
-		66FA9B18155B16B500B6FAC1 /* rfc5545-iCalendar.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = "rfc5545-iCalendar.txt"; sourceTree = "<group>"; };
-		66FA9B19155B16B500B6FAC1 /* rfc5546-iTIP.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = "rfc5546-iTIP.txt"; sourceTree = "<group>"; };
-		66FA9B1A155B16B500B6FAC1 /* rfc5689-Extended MKCOL.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = "rfc5689-Extended MKCOL.txt"; sourceTree = "<group>"; };
-		66FA9B1B155B16B500B6FAC1 /* rfc5785-well-known-uris.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = "rfc5785-well-known-uris.txt"; sourceTree = "<group>"; };
-		66FA9B1C155B16B500B6FAC1 /* rfc5842-BIND.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = "rfc5842-BIND.txt"; sourceTree = "<group>"; };
-		66FA9B1D155B16B500B6FAC1 /* rfc5995-POST addmember.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = "rfc5995-POST addmember.txt"; sourceTree = "<group>"; };
-		66FA9B1E155B16B500B6FAC1 /* rfc6047-iMIP.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = "rfc6047-iMIP.txt"; sourceTree = "<group>"; };
-		66FA9B1F155B16B500B6FAC1 /* rfc6321-xCal.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = "rfc6321-xCal.txt"; sourceTree = "<group>"; };
-		66FA9B20155B16B500B6FAC1 /* rfc6350-vCard4.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = "rfc6350-vCard4.txt"; sourceTree = "<group>"; };
-		66FA9B21155B16B500B6FAC1 /* rfc6351-xCard.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = "rfc6351-xCard.txt"; sourceTree = "<group>"; };
-		66FA9B22155B16B500B6FAC1 /* rfc6352-CardDAV.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = "rfc6352-CardDAV.txt"; sourceTree = "<group>"; };
-		66FA9B23155B16B500B6FAC1 /* rfc6578-WebDAV Sync.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = "rfc6578-WebDAV Sync.txt"; sourceTree = "<group>"; };
-		66FA9B24155B16B500B6FAC1 /* HACKING */ = {isa = PBXFileReference; lastKnownFileType = text; name = HACKING; path = ../HACKING; sourceTree = "<group>"; };
-		66FA9B27155B16B500B6FAC1 /* bytes-per-nclob-character.patch */ = {isa = PBXFileReference; lastKnownFileType = text; path = "bytes-per-nclob-character.patch"; sourceTree = "<group>"; };
-		66FA9B28155B16B500B6FAC1 /* LICENSE */ = {isa = PBXFileReference; lastKnownFileType = text; name = LICENSE; path = ../LICENSE; sourceTree = "<group>"; };
-		66FA9B2C155B16B500B6FAC1 /* calendarserver.mo */ = {isa = PBXFileReference; lastKnownFileType = file; path = calendarserver.mo; sourceTree = "<group>"; };
-		66FA9B2D155B16B500B6FAC1 /* calendarserver.po */ = {isa = PBXFileReference; lastKnownFileType = text; path = calendarserver.po; sourceTree = "<group>"; };
-		66FA9B2F155B16B500B6FAC1 /* English */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/calendarserver.strings; sourceTree = "<group>"; };
-		66FA9B32155B16B500B6FAC1 /* calendarserver.mo */ = {isa = PBXFileReference; lastKnownFileType = file; path = calendarserver.mo; sourceTree = "<group>"; };
-		66FA9B33155B16B500B6FAC1 /* calendarserver.po */ = {isa = PBXFileReference; lastKnownFileType = text; path = calendarserver.po; sourceTree = "<group>"; };
-		66FA9B36155B16B500B6FAC1 /* calendarserver.mo */ = {isa = PBXFileReference; lastKnownFileType = file; path = calendarserver.mo; sourceTree = "<group>"; };
-		66FA9B37155B16B500B6FAC1 /* calendarserver.po */ = {isa = PBXFileReference; lastKnownFileType = text; path = calendarserver.po; sourceTree = "<group>"; };
-		66FA9B38155B16B500B6FAC1 /* pyflakes */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; name = pyflakes; path = ../pyflakes; sourceTree = "<group>"; };
-		66FA9B39155B16B500B6FAC1 /* python */ = {isa = PBXFileReference; lastKnownFileType = text; name = python; path = ../python; sourceTree = "<group>"; };
-		66FA9B3A155B16B500B6FAC1 /* README */ = {isa = PBXFileReference; lastKnownFileType = text; name = README; path = ../README; sourceTree = "<group>"; };
-		66FA9B3B155B16B500B6FAC1 /* run */ = {isa = PBXFileReference; lastKnownFileType = text; name = run; path = ../run; sourceTree = "<group>"; };
-		66FA9B3C155B16B500B6FAC1 /* setup.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; name = setup.py; path = ../setup.py; sourceTree = "<group>"; };
-		66FA9B3D155B16B500B6FAC1 /* sim */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; name = sim; path = ../sim; sourceTree = "<group>"; };
-		66FA9B3F155B16B500B6FAC1 /* build.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = build.sh; sourceTree = "<group>"; };
-		66FA9B44155B16B500B6FAC1 /* diffbranch */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = diffbranch; sourceTree = "<group>"; };
-		66FA9B45155B16B500B6FAC1 /* directorysetup.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = directorysetup.py; sourceTree = "<group>"; };
-		66FA9B46155B16B500B6FAC1 /* Makefile.Apple */ = {isa = PBXFileReference; lastKnownFileType = text; path = Makefile.Apple; sourceTree = "<group>"; };
-		66FA9B47155B16B500B6FAC1 /* mergebranch */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = mergebranch; sourceTree = "<group>"; };
-		66FA9B48155B16B500B6FAC1 /* patchapply */ = {isa = PBXFileReference; lastKnownFileType = text; path = patchapply; sourceTree = "<group>"; };
-		66FA9B49155B16B500B6FAC1 /* patchmaker */ = {isa = PBXFileReference; lastKnownFileType = text; path = patchmaker; sourceTree = "<group>"; };
-		66FA9B4A155B16B500B6FAC1 /* pull-up */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = "pull-up"; sourceTree = "<group>"; };
-		66FA9B4B155B16B500B6FAC1 /* py.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = py.sh; sourceTree = "<group>"; };
-		66FA9B4C155B16B500B6FAC1 /* pydoctor */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = pydoctor; sourceTree = "<group>"; };
-		66FA9B4D155B16B500B6FAC1 /* pygettext.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = pygettext.py; sourceTree = "<group>"; };
-		66FA9B4E155B16B500B6FAC1 /* shell.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = shell.sh; sourceTree = "<group>"; };
-		66FA9B4F155B16B500B6FAC1 /* submit */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = submit; sourceTree = "<group>"; };
-		66FA9B50155B16B500B6FAC1 /* version.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = version.py; sourceTree = "<group>"; };
-		66FA9B51155B16B500B6FAC1 /* build.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = build.sh; sourceTree = "<group>"; };
-		66FA9B52155B16B500B6FAC1 /* diffbranch */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = diffbranch; sourceTree = "<group>"; };
-		66FA9B53155B16B500B6FAC1 /* directorysetup.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = directorysetup.py; sourceTree = "<group>"; };
-		66FA9B54155B16B500B6FAC1 /* Makefile.Apple */ = {isa = PBXFileReference; lastKnownFileType = text; path = Makefile.Apple; sourceTree = "<group>"; };
-		66FA9B55155B16B500B6FAC1 /* mergebranch */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = mergebranch; sourceTree = "<group>"; };
-		66FA9B56155B16B500B6FAC1 /* patchapply */ = {isa = PBXFileReference; lastKnownFileType = text; path = patchapply; sourceTree = "<group>"; };
-		66FA9B57155B16B500B6FAC1 /* patchmaker */ = {isa = PBXFileReference; lastKnownFileType = text; path = patchmaker; sourceTree = "<group>"; };
-		66FA9B58155B16B500B6FAC1 /* pull-up */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = "pull-up"; sourceTree = "<group>"; };
-		66FA9B59155B16B500B6FAC1 /* py.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = py.sh; sourceTree = "<group>"; };
-		66FA9B5A155B16B500B6FAC1 /* pydoctor */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = pydoctor; sourceTree = "<group>"; };
-		66FA9B5B155B16B500B6FAC1 /* pygettext.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = pygettext.py; sourceTree = "<group>"; };
-		66FA9B5C155B16B500B6FAC1 /* shell.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = shell.sh; sourceTree = "<group>"; };
-		66FA9B5D155B16B500B6FAC1 /* submit */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = submit; sourceTree = "<group>"; };
-		66FA9B5E155B16B500B6FAC1 /* version.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = version.py; sourceTree = "<group>"; };
-		66FA9B5F155B16B500B6FAC1 /* test */ = {isa = PBXFileReference; lastKnownFileType = text; name = test; path = ../test; sourceTree = "<group>"; };
-		66FA9B60155B16B500B6FAC1 /* testserver */ = {isa = PBXFileReference; lastKnownFileType = text; name = testserver; path = ../testserver; sourceTree = "<group>"; };
-		66FA9B62155B16B500B6FAC1 /* __init__.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = __init__.py; sourceTree = "<group>"; };
-		66FA9B64155B16B500B6FAC1 /* __init__.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = __init__.py; sourceTree = "<group>"; };
-		66FA9B66155B16B500B6FAC1 /* __init__.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = __init__.py; sourceTree = "<group>"; };
-		66FA9B67155B16B500B6FAC1 /* address.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = address.py; sourceTree = "<group>"; };
-		66FA9B68155B16B500B6FAC1 /* endpoints.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = endpoints.py; sourceTree = "<group>"; };
-		66FA9B69155B16B500B6FAC1 /* tcp.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = tcp.py; sourceTree = "<group>"; };
-		66FA9B6B155B16B500B6FAC1 /* __init__.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = __init__.py; sourceTree = "<group>"; };
-		66FA9B6C155B16B500B6FAC1 /* adbapi2.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = adbapi2.py; sourceTree = "<group>"; };
-		66FA9B6E155B16B500B6FAC1 /* __init__.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = __init__.py; sourceTree = "<group>"; };
-		66FA9B6F155B16B500B6FAC1 /* model.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = model.py; sourceTree = "<group>"; };
-		66FA9B70155B16B500B6FAC1 /* parseschema.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = parseschema.py; sourceTree = "<group>"; };
-		66FA9B71155B16B500B6FAC1 /* syntax.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = syntax.py; sourceTree = "<group>"; };
-		66FA9B73155B16B500B6FAC1 /* __init__.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = __init__.py; sourceTree = "<group>"; };
-		66FA9B74155B16B500B6FAC1 /* test_parseschema.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_parseschema.py; sourceTree = "<group>"; };
-		66FA9B75155B16B500B6FAC1 /* test_sqlsyntax.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_sqlsyntax.py; sourceTree = "<group>"; };
-		66FA9B76155B16B500B6FAC1 /* ienterprise.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = ienterprise.py; sourceTree = "<group>"; };
-		66FA9B78155B16B500B6FAC1 /* __init__.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = __init__.py; sourceTree = "<group>"; };
-		66FA9B79155B16B500B6FAC1 /* test_adbapi2.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_adbapi2.py; sourceTree = "<group>"; };
-		66FA9B7A155B16B500B6FAC1 /* util.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = util.py; sourceTree = "<group>"; };
-		66FA9B7C155B16B500B6FAC1 /* __init__.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = __init__.py; sourceTree = "<group>"; };
-		66FA9B7D155B16B500B6FAC1 /* adaptendpoint.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = adaptendpoint.py; sourceTree = "<group>"; };
-		66FA9B7E155B16B500B6FAC1 /* decorate.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = decorate.py; sourceTree = "<group>"; };
-		66FA9B7F155B16B500B6FAC1 /* gaiendpoint.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = gaiendpoint.py; sourceTree = "<group>"; };
-		66FA9B80155B16B500B6FAC1 /* kqreactor.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = kqreactor.py; sourceTree = "<group>"; };
-		66FA9B81155B16B500B6FAC1 /* sendfdport.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = sendfdport.py; sourceTree = "<group>"; };
-		66FA9B82155B16B500B6FAC1 /* spawnsvc.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = spawnsvc.py; sourceTree = "<group>"; };
-		66FA9B83155B16B500B6FAC1 /* ssl.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = ssl.py; sourceTree = "<group>"; };
-		66FA9B84155B16B500B6FAC1 /* tcp.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = tcp.py; sourceTree = "<group>"; };
-		66FA9B86155B16B500B6FAC1 /* __init__.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = __init__.py; sourceTree = "<group>"; };
-		66FA9B87155B16B500B6FAC1 /* test_adaptendpoint.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_adaptendpoint.py; sourceTree = "<group>"; };
-		66FA9B88155B16B500B6FAC1 /* test_gaiendpoint.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_gaiendpoint.py; sourceTree = "<group>"; };
-		66FA9B89155B16B500B6FAC1 /* test_sendfdport.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_sendfdport.py; sourceTree = "<group>"; };
-		66FA9B8A155B16B500B6FAC1 /* threadutils.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = threadutils.py; sourceTree = "<group>"; };
-		66FA9B8B155B16B500B6FAC1 /* patches.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = patches.py; sourceTree = "<group>"; };
-		66FA9B8D155B16B500B6FAC1 /* __init__.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = __init__.py; sourceTree = "<group>"; };
-		66FA9B8E155B16B500B6FAC1 /* memcache.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = memcache.py; sourceTree = "<group>"; };
-		66FA9B90155B16B500B6FAC1 /* __init__.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = __init__.py; sourceTree = "<group>"; };
-		66FA9B91155B16B500B6FAC1 /* test_memcache.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_memcache.py; sourceTree = "<group>"; };
-		66FA9B93155B16B500B6FAC1 /* __init__.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = __init__.py; sourceTree = "<group>"; };
-		66FA9B94155B16B500B6FAC1 /* _plistlib.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = _plistlib.py; sourceTree = "<group>"; };
-		66FA9B95155B16B500B6FAC1 /* clsprop.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = clsprop.py; sourceTree = "<group>"; };
-		66FA9B96155B16B500B6FAC1 /* filepath.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = filepath.py; sourceTree = "<group>"; };
-		66FA9B97155B16B500B6FAC1 /* log.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = log.py; sourceTree = "<group>"; };
-		66FA9B98155B16B500B6FAC1 /* memcacheclient.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = memcacheclient.py; sourceTree = "<group>"; };
-		66FA9B99155B16B500B6FAC1 /* parallel.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = parallel.py; sourceTree = "<group>"; };
-		66FA9B9A155B16B500B6FAC1 /* plistlib.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = plistlib.py; sourceTree = "<group>"; };
-		66FA9B9B155B16B500B6FAC1 /* sendfd.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = sendfd.py; sourceTree = "<group>"; };
-		66FA9B9C155B16B500B6FAC1 /* sendmsg.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = sendmsg.c; sourceTree = "<group>"; };
-		66FA9B9E155B16B500B6FAC1 /* __init__.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = __init__.py; sourceTree = "<group>"; };
-		66FA9B9F155B16B500B6FAC1 /* pullpipe.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = pullpipe.py; sourceTree = "<group>"; };
-		66FA9BA0155B16B500B6FAC1 /* test_filepath.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_filepath.py; sourceTree = "<group>"; };
-		66FA9BA1155B16B500B6FAC1 /* test_log.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_log.py; sourceTree = "<group>"; };
-		66FA9BA2155B16B500B6FAC1 /* test_parallel.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_parallel.py; sourceTree = "<group>"; };
-		66FA9BA3155B16B500B6FAC1 /* test_sendmsg.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_sendmsg.py; sourceTree = "<group>"; };
-		66FA9BA4155B16B500B6FAC1 /* vcomponent.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = vcomponent.py; sourceTree = "<group>"; };
-		66FA9BA6155B16B500B6FAC1 /* __init__.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = __init__.py; sourceTree = "<group>"; };
-		66FA9BA7155B16B500B6FAC1 /* _version.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = _version.py; sourceTree = "<group>"; };
-		66FA9BA9155B16B500B6FAC1 /* __init__.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = __init__.py; sourceTree = "<group>"; };
-		66FA9BAA155B16B500B6FAC1 /* basic.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = basic.py; sourceTree = "<group>"; };
-		66FA9BAB155B16B500B6FAC1 /* digest.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = digest.py; sourceTree = "<group>"; };
-		66FA9BAC155B16B500B6FAC1 /* interfaces.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = interfaces.py; sourceTree = "<group>"; };
-		66FA9BAD155B16B500B6FAC1 /* wrapper.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = wrapper.py; sourceTree = "<group>"; };
-		66FA9BAF155B16B500B6FAC1 /* __init__.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = __init__.py; sourceTree = "<group>"; };
-		66FA9BB0155B16B500B6FAC1 /* http.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = http.py; sourceTree = "<group>"; };
-		66FA9BB2155B16B500B6FAC1 /* __init__.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = __init__.py; sourceTree = "<group>"; };
-		66FA9BB3155B16B500B6FAC1 /* http.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = http.py; sourceTree = "<group>"; };
-		66FA9BB4155B16B500B6FAC1 /* interfaces.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = interfaces.py; sourceTree = "<group>"; };
-		66FA9BB6155B16B500B6FAC1 /* __init__.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = __init__.py; sourceTree = "<group>"; };
-		66FA9BB7155B16B500B6FAC1 /* auth.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = auth.py; sourceTree = "<group>"; };
-		66FA9BB8155B16B500B6FAC1 /* fileop.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = fileop.py; sourceTree = "<group>"; };
-		66FA9BB9155B16B500B6FAC1 /* http.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = http.py; sourceTree = "<group>"; };
-		66FA9BBA155B16B500B6FAC1 /* idav.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = idav.py; sourceTree = "<group>"; };
-		66FA9BBC155B16B500B6FAC1 /* __init__.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = __init__.py; sourceTree = "<group>"; };
-		66FA9BBD155B16B500B6FAC1 /* acl.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = acl.py; sourceTree = "<group>"; };
-		66FA9BBE155B16B500B6FAC1 /* copymove.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = copymove.py; sourceTree = "<group>"; };
-		66FA9BBF155B16B500B6FAC1 /* delete.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = delete.py; sourceTree = "<group>"; };
-		66FA9BC0155B16B500B6FAC1 /* delete_common.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = delete_common.py; sourceTree = "<group>"; };
-		66FA9BC1155B16B500B6FAC1 /* get.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = get.py; sourceTree = "<group>"; };
-		66FA9BC2155B16B500B6FAC1 /* lock.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = lock.py; sourceTree = "<group>"; };
-		66FA9BC3155B16B500B6FAC1 /* mkcol.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = mkcol.py; sourceTree = "<group>"; };
-		66FA9BC4155B16B500B6FAC1 /* prop_common.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = prop_common.py; sourceTree = "<group>"; };
-		66FA9BC5155B16B500B6FAC1 /* propfind.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = propfind.py; sourceTree = "<group>"; };
-		66FA9BC6155B16B500B6FAC1 /* proppatch.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = proppatch.py; sourceTree = "<group>"; };
-		66FA9BC7155B16B500B6FAC1 /* put.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = put.py; sourceTree = "<group>"; };
-		66FA9BC8155B16B500B6FAC1 /* put_common.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = put_common.py; sourceTree = "<group>"; };
-		66FA9BC9155B16B500B6FAC1 /* report.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = report.py; sourceTree = "<group>"; };
-		66FA9BCA155B16B500B6FAC1 /* report_acl_principal_prop_set.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = report_acl_principal_prop_set.py; sourceTree = "<group>"; };
-		66FA9BCB155B16B500B6FAC1 /* report_expand.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = report_expand.py; sourceTree = "<group>"; };
-		66FA9BCC155B16B500B6FAC1 /* report_principal_match.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = report_principal_match.py; sourceTree = "<group>"; };
-		66FA9BCD155B16B500B6FAC1 /* report_principal_property_search.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = report_principal_property_search.py; sourceTree = "<group>"; };
-		66FA9BCE155B16B500B6FAC1 /* report_principal_search_property_set.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = report_principal_search_property_set.py; sourceTree = "<group>"; };
-		66FA9BCF155B16B500B6FAC1 /* noneprops.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = noneprops.py; sourceTree = "<group>"; };
-		66FA9BD0155B16B500B6FAC1 /* resource.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = resource.py; sourceTree = "<group>"; };
-		66FA9BD1155B16B500B6FAC1 /* static.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = static.py; sourceTree = "<group>"; };
-		66FA9BD3155B16B500B6FAC1 /* __init__.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = __init__.py; sourceTree = "<group>"; };
-		66FA9BD5155B16B500B6FAC1 /* quota_100.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = quota_100.txt; sourceTree = "<group>"; };
-		66FA9BD7155B16B500B6FAC1 /* PROPFIND_bad.xml */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = PROPFIND_bad.xml; sourceTree = "<group>"; };
-		66FA9BD8155B16B500B6FAC1 /* PROPFIND_nonamespace.xml */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = PROPFIND_nonamespace.xml; sourceTree = "<group>"; };
-		66FA9BD9155B16B500B6FAC1 /* PROPFIND_request.xml */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = PROPFIND_request.xml; sourceTree = "<group>"; };
-		66FA9BDA155B16B500B6FAC1 /* PROPFIND_response.xml */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = PROPFIND_response.xml; sourceTree = "<group>"; };
-		66FA9BDB155B16B500B6FAC1 /* PROPPATCH_request.xml */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = PROPPATCH_request.xml; sourceTree = "<group>"; };
-		66FA9BDC155B16B500B6FAC1 /* REPORT_request.xml */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = REPORT_request.xml; sourceTree = "<group>"; };
-		66FA9BDD155B16B500B6FAC1 /* REPORT_response.xml */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = REPORT_response.xml; sourceTree = "<group>"; };
-		66FA9BDE155B16B500B6FAC1 /* test_acl.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_acl.py; sourceTree = "<group>"; };
-		66FA9BDF155B16B500B6FAC1 /* test_copy.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_copy.py; sourceTree = "<group>"; };
-		66FA9BE0155B16B500B6FAC1 /* test_delete.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_delete.py; sourceTree = "<group>"; };
-		66FA9BE1155B16B500B6FAC1 /* test_http.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_http.py; sourceTree = "<group>"; };
-		66FA9BE2155B16B500B6FAC1 /* test_lock.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_lock.py; sourceTree = "<group>"; };
-		66FA9BE3155B16B500B6FAC1 /* test_mkcol.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_mkcol.py; sourceTree = "<group>"; };
-		66FA9BE4155B16B500B6FAC1 /* test_move.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_move.py; sourceTree = "<group>"; };
-		66FA9BE5155B16B500B6FAC1 /* test_options.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_options.py; sourceTree = "<group>"; };
-		66FA9BE6155B16B500B6FAC1 /* test_pipeline.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_pipeline.py; sourceTree = "<group>"; };
-		66FA9BE7155B16B500B6FAC1 /* test_prop.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_prop.py; sourceTree = "<group>"; };
-		66FA9BE8155B16B500B6FAC1 /* test_put.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_put.py; sourceTree = "<group>"; };
-		66FA9BE9155B16B500B6FAC1 /* test_quota.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_quota.py; sourceTree = "<group>"; };
-		66FA9BEA155B16B500B6FAC1 /* test_report.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_report.py; sourceTree = "<group>"; };
-		66FA9BEB155B16B500B6FAC1 /* test_report_expand.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_report_expand.py; sourceTree = "<group>"; };
-		66FA9BEC155B16B500B6FAC1 /* test_resource.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_resource.py; sourceTree = "<group>"; };
-		66FA9BED155B16B500B6FAC1 /* test_static.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_static.py; sourceTree = "<group>"; };
-		66FA9BEE155B16B500B6FAC1 /* test_util.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_util.py; sourceTree = "<group>"; };
-		66FA9BEF155B16B500B6FAC1 /* test_xattrprops.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_xattrprops.py; sourceTree = "<group>"; };
-		66FA9BF0155B16B500B6FAC1 /* tworequest_client.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = tworequest_client.py; sourceTree = "<group>"; };
-		66FA9BF1155B16B500B6FAC1 /* util.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = util.py; sourceTree = "<group>"; };
-		66FA9BF2155B16B500B6FAC1 /* util.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = util.py; sourceTree = "<group>"; };
-		66FA9BF3155B16B500B6FAC1 /* xattrprops.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = xattrprops.py; sourceTree = "<group>"; };
-		66FA9BF4155B16B500B6FAC1 /* error.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = error.py; sourceTree = "<group>"; };
-		66FA9BF5155B16B500B6FAC1 /* fileupload.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = fileupload.py; sourceTree = "<group>"; };
-		66FA9BF7155B16B500B6FAC1 /* __init__.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = __init__.py; sourceTree = "<group>"; };
-		66FA9BF8155B16B500B6FAC1 /* gzip.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = gzip.py; sourceTree = "<group>"; };
-		66FA9BF9155B16B500B6FAC1 /* location.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = location.py; sourceTree = "<group>"; };
-		66FA9BFA155B16B500B6FAC1 /* range.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = range.py; sourceTree = "<group>"; };
-		66FA9BFB155B16B500B6FAC1 /* http.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = http.py; sourceTree = "<group>"; };
-		66FA9BFC155B16B500B6FAC1 /* http_headers.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = http_headers.py; sourceTree = "<group>"; };
-		66FA9BFD155B16B500B6FAC1 /* iweb.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = iweb.py; sourceTree = "<group>"; };
-		66FA9BFE155B16B500B6FAC1 /* log.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = log.py; sourceTree = "<group>"; };
-		66FA9BFF155B16B500B6FAC1 /* metafd.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = metafd.py; sourceTree = "<group>"; };
-		66FA9C00155B16B500B6FAC1 /* resource.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = resource.py; sourceTree = "<group>"; };
-		66FA9C01155B16B500B6FAC1 /* responsecode.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = responsecode.py; sourceTree = "<group>"; };
-		66FA9C02155B16B500B6FAC1 /* server.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = server.py; sourceTree = "<group>"; };
-		66FA9C03155B16B500B6FAC1 /* static.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = static.py; sourceTree = "<group>"; };
-		66FA9C04155B16B500B6FAC1 /* stream.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = stream.py; sourceTree = "<group>"; };
-		66FA9C06155B16B500B6FAC1 /* __init__.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = __init__.py; sourceTree = "<group>"; };
-		66FA9C07155B16B500B6FAC1 /* server.pem */ = {isa = PBXFileReference; lastKnownFileType = text; path = server.pem; sourceTree = "<group>"; };
-		66FA9C08155B16B500B6FAC1 /* simple_client.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = simple_client.py; sourceTree = "<group>"; };
-		66FA9C09155B16B500B6FAC1 /* stream_data.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = stream_data.txt; sourceTree = "<group>"; };
-		66FA9C0A155B16B500B6FAC1 /* test_client.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_client.py; sourceTree = "<group>"; };
-		66FA9C0B155B16B500B6FAC1 /* test_fileupload.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_fileupload.py; sourceTree = "<group>"; };
-		66FA9C0C155B16B500B6FAC1 /* test_http.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_http.py; sourceTree = "<group>"; };
-		66FA9C0D155B16B500B6FAC1 /* test_http_headers.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_http_headers.py; sourceTree = "<group>"; };
-		66FA9C0E155B16B500B6FAC1 /* test_httpauth.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_httpauth.py; sourceTree = "<group>"; };
-		66FA9C0F155B16B500B6FAC1 /* test_log.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_log.py; sourceTree = "<group>"; };
-		66FA9C10155B16B500B6FAC1 /* test_metafd.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_metafd.py; sourceTree = "<group>"; };
-		66FA9C11155B16B500B6FAC1 /* test_resource.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_resource.py; sourceTree = "<group>"; };
-		66FA9C12155B16B500B6FAC1 /* test_server.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_server.py; sourceTree = "<group>"; };
-		66FA9C13155B16B500B6FAC1 /* test_static.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_static.py; sourceTree = "<group>"; };
-		66FA9C14155B16B500B6FAC1 /* test_stream.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_stream.py; sourceTree = "<group>"; };
-		66FA9C17155B16B500B6FAC1 /* caldav.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = caldav.py; sourceTree = "<group>"; };
-		66FA9C18155B16B500B6FAC1 /* kqueuereactor.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = kqueuereactor.py; sourceTree = "<group>"; };
-		66FA9C1A155B16B500B6FAC1 /* __init__.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = __init__.py; sourceTree = "<group>"; };
-		66FA9C1B155B16B500B6FAC1 /* accounting.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = accounting.py; sourceTree = "<group>"; };
-		66FA9C1C155B16B500B6FAC1 /* authkerb.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = authkerb.py; sourceTree = "<group>"; };
-		66FA9C1D155B16B500B6FAC1 /* backup.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = backup.py; sourceTree = "<group>"; };
-		66FA9C1E155B16B500B6FAC1 /* bind.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = bind.py; sourceTree = "<group>"; };
-		66FA9C1F155B16B500B6FAC1 /* cache.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = cache.py; sourceTree = "<group>"; };
-		66FA9C20155B16B500B6FAC1 /* caldavxml.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = caldavxml.py; sourceTree = "<group>"; };
-		66FA9C21155B16B500B6FAC1 /* carddavxml.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = carddavxml.py; sourceTree = "<group>"; };
-		66FA9C23155B16B500B6FAC1 /* __init__.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = __init__.py; sourceTree = "<group>"; };
-		66FA9C24155B16B500B6FAC1 /* geturl.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = geturl.py; sourceTree = "<group>"; };
-		66FA9C25155B16B500B6FAC1 /* pool.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = pool.py; sourceTree = "<group>"; };
-		66FA9C26155B16B500B6FAC1 /* reverseproxy.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = reverseproxy.py; sourceTree = "<group>"; };
-		66FA9C28155B16B500B6FAC1 /* __init__.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = __init__.py; sourceTree = "<group>"; };
-		66FA9C29155B16B500B6FAC1 /* test_reverseproxy.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_reverseproxy.py; sourceTree = "<group>"; };
-		66FA9C2A155B16B500B6FAC1 /* config.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = config.py; sourceTree = "<group>"; };
-		66FA9C2B155B16B500B6FAC1 /* customxml.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = customxml.py; sourceTree = "<group>"; };
-		66FA9C2C155B16B500B6FAC1 /* database.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = database.py; sourceTree = "<group>"; };
-		66FA9C2E155B16B500B6FAC1 /* __init__.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = __init__.py; sourceTree = "<group>"; };
-		66FA9C2F155B16B500B6FAC1 /* addressdata.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = addressdata.py; sourceTree = "<group>"; };
-		66FA9C30155B16B500B6FAC1 /* calendardata.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = calendardata.py; sourceTree = "<group>"; };
-		66FA9C31155B16B500B6FAC1 /* filter.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = filter.py; sourceTree = "<group>"; };
-		66FA9C32155B16B500B6FAC1 /* peruserdata.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = peruserdata.py; sourceTree = "<group>"; };
-		66FA9C33155B16B500B6FAC1 /* privateevents.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = privateevents.py; sourceTree = "<group>"; };
-		66FA9C35155B16B500B6FAC1 /* __init__.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = __init__.py; sourceTree = "<group>"; };
-		66FA9C36155B16B500B6FAC1 /* test_calendardata.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_calendardata.py; sourceTree = "<group>"; };
-		66FA9C37155B16B500B6FAC1 /* test_peruserdata.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_peruserdata.py; sourceTree = "<group>"; };
-		66FA9C38155B16B500B6FAC1 /* test_privateevents.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_privateevents.py; sourceTree = "<group>"; };
-		66FA9C39155B16B500B6FAC1 /* dateops.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = dateops.py; sourceTree = "<group>"; };
-		66FA9C3B155B16B500B6FAC1 /* __init__.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = __init__.py; sourceTree = "<group>"; };
-		66FA9C3C155B16B500B6FAC1 /* addressbook.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = addressbook.py; sourceTree = "<group>"; };
-		66FA9C3D155B16B500B6FAC1 /* aggregate.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = aggregate.py; sourceTree = "<group>"; };
-		66FA9C3E155B16B500B6FAC1 /* appleopendirectory.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = appleopendirectory.py; sourceTree = "<group>"; };
-		66FA9C3F155B16B500B6FAC1 /* augment.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = augment.py; sourceTree = "<group>"; };
-		66FA9C40155B16B500B6FAC1 /* cachingdirectory.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = cachingdirectory.py; sourceTree = "<group>"; };
-		66FA9C41155B16B500B6FAC1 /* calendar-user-proxy-principal-resource.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = "calendar-user-proxy-principal-resource.html"; sourceTree = "<group>"; };
-		66FA9C42155B16B500B6FAC1 /* calendar.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = calendar.py; sourceTree = "<group>"; };
-		66FA9C43155B16B500B6FAC1 /* calendaruserproxy.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = calendaruserproxy.py; sourceTree = "<group>"; };
-		66FA9C44155B16B500B6FAC1 /* calendaruserproxyloader.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = calendaruserproxyloader.py; sourceTree = "<group>"; };
-		66FA9C45155B16B500B6FAC1 /* common.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = common.py; sourceTree = "<group>"; };
-		66FA9C46155B16B500B6FAC1 /* digest.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = digest.py; sourceTree = "<group>"; };
-		66FA9C47155B16B500B6FAC1 /* directory-principal-resource.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = "directory-principal-resource.html"; sourceTree = "<group>"; };
-		66FA9C48155B16B500B6FAC1 /* directory.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = directory.py; sourceTree = "<group>"; };
-		66FA9C49155B16B500B6FAC1 /* idirectory.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = idirectory.py; sourceTree = "<group>"; };
-		66FA9C4A155B16B500B6FAC1 /* internal.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = internal.py; sourceTree = "<group>"; };
-		66FA9C4B155B16B500B6FAC1 /* ldapdirectory.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = ldapdirectory.py; sourceTree = "<group>"; };
-		66FA9C4C155B16B500B6FAC1 /* opendirectorybacker.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = opendirectorybacker.py; sourceTree = "<group>"; };
-		66FA9C4D155B16B500B6FAC1 /* principal.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = principal.py; sourceTree = "<group>"; };
-		66FA9C4E155B16B500B6FAC1 /* resource.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = resource.py; sourceTree = "<group>"; };
-		66FA9C4F155B16B500B6FAC1 /* resourceinfo.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = resourceinfo.py; sourceTree = "<group>"; };
-		66FA9C51155B16B500B6FAC1 /* __init__.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = __init__.py; sourceTree = "<group>"; };
-		66FA9C52155B16B500B6FAC1 /* accounts.xml */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = accounts.xml; sourceTree = "<group>"; };
-		66FA9C53155B16B500B6FAC1 /* augments-test-default.xml */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = "augments-test-default.xml"; sourceTree = "<group>"; };
-		66FA9C54155B16B500B6FAC1 /* augments-test.xml */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = "augments-test.xml"; sourceTree = "<group>"; };
-		66FA9C55155B16B500B6FAC1 /* augments.xml */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = augments.xml; sourceTree = "<group>"; };
-		66FA9C57155B16B500B6FAC1 /* augments.xml */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = augments.xml; sourceTree = "<group>"; };
-		66FA9C58155B16B500B6FAC1 /* resources-locations.xml */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = "resources-locations.xml"; sourceTree = "<group>"; };
-		66FA9C59155B16B500B6FAC1 /* users-groups.xml */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = "users-groups.xml"; sourceTree = "<group>"; };
-		66FA9C5A155B16B500B6FAC1 /* proxies.xml */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = proxies.xml; sourceTree = "<group>"; };
-		66FA9C5C155B16B500B6FAC1 /* augments.xml */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = augments.xml; sourceTree = "<group>"; };
-		66FA9C5D155B16B500B6FAC1 /* caldavd.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = caldavd.plist; sourceTree = "<group>"; };
-		66FA9C5E155B16B500B6FAC1 /* resources-locations.xml */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = "resources-locations.xml"; sourceTree = "<group>"; };
-		66FA9C5F155B16B500B6FAC1 /* users-groups.xml */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = "users-groups.xml"; sourceTree = "<group>"; };
-		66FA9C60155B16B500B6FAC1 /* resources.xml */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = resources.xml; sourceTree = "<group>"; };
-		66FA9C61155B16B500B6FAC1 /* sudoers.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = sudoers.plist; sourceTree = "<group>"; };
-		66FA9C62155B16B500B6FAC1 /* sudoers2.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = sudoers2.plist; sourceTree = "<group>"; };
-		66FA9C63155B16B500B6FAC1 /* test_aggregate.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_aggregate.py; sourceTree = "<group>"; };
-		66FA9C64155B16B500B6FAC1 /* test_augment.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_augment.py; sourceTree = "<group>"; };
-		66FA9C65155B16B500B6FAC1 /* test_buildquery.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_buildquery.py; sourceTree = "<group>"; };
-		66FA9C66155B16B500B6FAC1 /* test_cachedirectory.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_cachedirectory.py; sourceTree = "<group>"; };
-		66FA9C67155B16B500B6FAC1 /* test_calendar.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_calendar.py; sourceTree = "<group>"; };
-		66FA9C68155B16B500B6FAC1 /* test_digest.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_digest.py; sourceTree = "<group>"; };
-		66FA9C69155B16B500B6FAC1 /* test_directory.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_directory.py; sourceTree = "<group>"; };
-		66FA9C6A155B16B500B6FAC1 /* test_guidchange.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_guidchange.py; sourceTree = "<group>"; };
-		66FA9C6B155B16B500B6FAC1 /* test_ldapdirectory.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_ldapdirectory.py; sourceTree = "<group>"; };
-		66FA9C6C155B16B500B6FAC1 /* test_livedirectory.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_livedirectory.py; sourceTree = "<group>"; };
-		66FA9C6D155B16B500B6FAC1 /* test_modify.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_modify.py; sourceTree = "<group>"; };
-		66FA9C6E155B16B500B6FAC1 /* test_opendirectory.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_opendirectory.py; sourceTree = "<group>"; };
-		66FA9C6F155B16B500B6FAC1 /* test_opendirectorybacker.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_opendirectorybacker.py; sourceTree = "<group>"; };
-		66FA9C70155B16B500B6FAC1 /* test_principal.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_principal.py; sourceTree = "<group>"; };
-		66FA9C71155B16B500B6FAC1 /* test_proxyprincipaldb.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_proxyprincipaldb.py; sourceTree = "<group>"; };
-		66FA9C72155B16B500B6FAC1 /* test_proxyprincipalmembers.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_proxyprincipalmembers.py; sourceTree = "<group>"; };
-		66FA9C73155B16B500B6FAC1 /* test_resources.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_resources.py; sourceTree = "<group>"; };
-		66FA9C74155B16B500B6FAC1 /* test_util.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_util.py; sourceTree = "<group>"; };
-		66FA9C75155B16B500B6FAC1 /* test_wiki.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_wiki.py; sourceTree = "<group>"; };
-		66FA9C76155B16B500B6FAC1 /* test_xmlfile.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_xmlfile.py; sourceTree = "<group>"; };
-		66FA9C77155B16B500B6FAC1 /* util.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = util.py; sourceTree = "<group>"; };
-		66FA9C78155B16B500B6FAC1 /* util.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = util.py; sourceTree = "<group>"; };
-		66FA9C79155B16B500B6FAC1 /* wiki.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = wiki.py; sourceTree = "<group>"; };
-		66FA9C7A155B16B500B6FAC1 /* xmlaccountsparser.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = xmlaccountsparser.py; sourceTree = "<group>"; };
-		66FA9C7B155B16B500B6FAC1 /* xmlaugmentsparser.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = xmlaugmentsparser.py; sourceTree = "<group>"; };
-		66FA9C7C155B16B500B6FAC1 /* xmlfile.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = xmlfile.py; sourceTree = "<group>"; };
-		66FA9C7D155B16B500B6FAC1 /* directory-listing.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = "directory-listing.html"; sourceTree = "<group>"; };
-		66FA9C7E155B16B500B6FAC1 /* directorybackedaddressbook.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = directorybackedaddressbook.py; sourceTree = "<group>"; };
-		66FA9C7F155B16B500B6FAC1 /* dropbox.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = dropbox.py; sourceTree = "<group>"; };
-		66FA9C80155B16B500B6FAC1 /* extensions.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = extensions.py; sourceTree = "<group>"; };
-		66FA9C81155B16B500B6FAC1 /* freebusyurl.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = freebusyurl.py; sourceTree = "<group>"; };
-		66FA9C82155B16B500B6FAC1 /* ical.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = ical.py; sourceTree = "<group>"; };
-		66FA9C83155B16B500B6FAC1 /* icaldav.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = icaldav.py; sourceTree = "<group>"; };
-		66FA9C86155B16B500B6FAC1 /* ical.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = ical.jpg; sourceTree = "<group>"; };
-		66FA9C87155B16B500B6FAC1 /* instance.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = instance.py; sourceTree = "<group>"; };
-		66FA9C88155B16B500B6FAC1 /* linkresource.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = linkresource.py; sourceTree = "<group>"; };
-		66FA9C89155B16B500B6FAC1 /* localization.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = localization.py; sourceTree = "<group>"; };
-		66FA9C8A155B16B500B6FAC1 /* mail.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = mail.py; sourceTree = "<group>"; };
-		66FA9C8B155B16B500B6FAC1 /* memcachelock.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = memcachelock.py; sourceTree = "<group>"; };
-		66FA9C8C155B16B500B6FAC1 /* memcachepool.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = memcachepool.py; sourceTree = "<group>"; };
-		66FA9C8D155B16B500B6FAC1 /* memcacheprops.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = memcacheprops.py; sourceTree = "<group>"; };
-		66FA9C8E155B16B500B6FAC1 /* memcacher.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = memcacher.py; sourceTree = "<group>"; };
-		66FA9C90155B16B500B6FAC1 /* __init__.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = __init__.py; sourceTree = "<group>"; };
-		66FA9C91155B16B500B6FAC1 /* acl.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = acl.py; sourceTree = "<group>"; };
-		66FA9C92155B16B500B6FAC1 /* copymove.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = copymove.py; sourceTree = "<group>"; };
-		66FA9C93155B16B500B6FAC1 /* copymove_contact.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = copymove_contact.py; sourceTree = "<group>"; };
-		66FA9C94155B16B500B6FAC1 /* delete.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = delete.py; sourceTree = "<group>"; };
-		66FA9C95155B16B500B6FAC1 /* delete_common.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = delete_common.py; sourceTree = "<group>"; };
-		66FA9C96155B16B500B6FAC1 /* get.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = get.py; sourceTree = "<group>"; };
-		66FA9C97155B16B500B6FAC1 /* mkcalendar.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = mkcalendar.py; sourceTree = "<group>"; };
-		66FA9C98155B16B500B6FAC1 /* mkcol.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = mkcol.py; sourceTree = "<group>"; };
-		66FA9C99155B16B500B6FAC1 /* post.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = post.py; sourceTree = "<group>"; };
-		66FA9C9A155B16B500B6FAC1 /* propfind.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = propfind.py; sourceTree = "<group>"; };
-		66FA9C9B155B16B500B6FAC1 /* put.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = put.py; sourceTree = "<group>"; };
-		66FA9C9C155B16B500B6FAC1 /* put_addressbook_common.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = put_addressbook_common.py; sourceTree = "<group>"; };
-		66FA9C9D155B16B500B6FAC1 /* put_common.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = put_common.py; sourceTree = "<group>"; };
-		66FA9C9E155B16B500B6FAC1 /* report.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = report.py; sourceTree = "<group>"; };
-		66FA9C9F155B16B500B6FAC1 /* report_addressbook_multiget.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = report_addressbook_multiget.py; sourceTree = "<group>"; };
-		66FA9CA0155B16B600B6FAC1 /* report_addressbook_query.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = report_addressbook_query.py; sourceTree = "<group>"; };
-		66FA9CA1155B16B600B6FAC1 /* report_calendar_multiget.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = report_calendar_multiget.py; sourceTree = "<group>"; };
-		66FA9CA2155B16B600B6FAC1 /* report_calendar_query.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = report_calendar_query.py; sourceTree = "<group>"; };
-		66FA9CA3155B16B600B6FAC1 /* report_common.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = report_common.py; sourceTree = "<group>"; };
-		66FA9CA4155B16B600B6FAC1 /* report_freebusy.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = report_freebusy.py; sourceTree = "<group>"; };
-		66FA9CA5155B16B600B6FAC1 /* report_multiget_common.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = report_multiget_common.py; sourceTree = "<group>"; };
-		66FA9CA6155B16B600B6FAC1 /* report_sync_collection.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = report_sync_collection.py; sourceTree = "<group>"; };
-		66FA9CA7155B16B600B6FAC1 /* mkcolxml.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = mkcolxml.py; sourceTree = "<group>"; };
-		66FA9CA8155B16B600B6FAC1 /* notifications.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = notifications.py; sourceTree = "<group>"; };
-		66FA9CA9155B16B600B6FAC1 /* notify.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = notify.py; sourceTree = "<group>"; };
-		66FA9CAB155B16B600B6FAC1 /* __init__.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = __init__.py; sourceTree = "<group>"; };
-		66FA9CAC155B16B600B6FAC1 /* addressbookquery.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = addressbookquery.py; sourceTree = "<group>"; };
-		66FA9CAD155B16B600B6FAC1 /* addressbookqueryfilter.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = addressbookqueryfilter.py; sourceTree = "<group>"; };
-		66FA9CAE155B16B600B6FAC1 /* calendarquery.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = calendarquery.py; sourceTree = "<group>"; };
-		66FA9CAF155B16B600B6FAC1 /* calendarqueryfilter.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = calendarqueryfilter.py; sourceTree = "<group>"; };
-		66FA9CB0155B16B600B6FAC1 /* expression.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = expression.py; sourceTree = "<group>"; };
-		66FA9CB1155B16B600B6FAC1 /* sqlgenerator.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = sqlgenerator.py; sourceTree = "<group>"; };
-		66FA9CB3155B16B600B6FAC1 /* __init__.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = __init__.py; sourceTree = "<group>"; };
-		66FA9CB4155B16B600B6FAC1 /* test_addressbookquery.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_addressbookquery.py; sourceTree = "<group>"; };
-		66FA9CB5155B16B600B6FAC1 /* test_calendarquery.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_calendarquery.py; sourceTree = "<group>"; };
-		66FA9CB6155B16B600B6FAC1 /* test_expression.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_expression.py; sourceTree = "<group>"; };
-		66FA9CB7155B16B600B6FAC1 /* test_queryfilter.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_queryfilter.py; sourceTree = "<group>"; };
-		66FA9CB8155B16B600B6FAC1 /* resource.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = resource.py; sourceTree = "<group>"; };
-		66FA9CB9155B16B600B6FAC1 /* schedule.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = schedule.py; sourceTree = "<group>"; };
-		66FA9CBB155B16B600B6FAC1 /* __init__.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = __init__.py; sourceTree = "<group>"; };
-		66FA9CBC155B16B600B6FAC1 /* addressmapping.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = addressmapping.py; sourceTree = "<group>"; };
-		66FA9CBD155B16B600B6FAC1 /* caldav.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = caldav.py; sourceTree = "<group>"; };
-		66FA9CBE155B16B600B6FAC1 /* cuaddress.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = cuaddress.py; sourceTree = "<group>"; };
-		66FA9CBF155B16B600B6FAC1 /* delivery.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = delivery.py; sourceTree = "<group>"; };
-		66FA9CC0155B16B600B6FAC1 /* icaldiff.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = icaldiff.py; sourceTree = "<group>"; };
-		66FA9CC1155B16B600B6FAC1 /* imip.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = imip.py; sourceTree = "<group>"; };
-		66FA9CC2155B16B600B6FAC1 /* implicit.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = implicit.py; sourceTree = "<group>"; };
-		66FA9CC3155B16B600B6FAC1 /* ischedule.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = ischedule.py; sourceTree = "<group>"; };
-		66FA9CC4155B16B600B6FAC1 /* ischeduleservers.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = ischeduleservers.py; sourceTree = "<group>"; };
-		66FA9CC5155B16B600B6FAC1 /* itip.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = itip.py; sourceTree = "<group>"; };
-		66FA9CC6155B16B600B6FAC1 /* processing.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = processing.py; sourceTree = "<group>"; };
-		66FA9CC7155B16B600B6FAC1 /* scheduler.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = scheduler.py; sourceTree = "<group>"; };
-		66FA9CC9155B16B600B6FAC1 /* __init__.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = __init__.py; sourceTree = "<group>"; };
-		66FA9CCA155B16B600B6FAC1 /* test_caldav.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_caldav.py; sourceTree = "<group>"; };
-		66FA9CCB155B16B600B6FAC1 /* test_icaldiff.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_icaldiff.py; sourceTree = "<group>"; };
-		66FA9CCC155B16B600B6FAC1 /* test_imip.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_imip.py; sourceTree = "<group>"; };
-		66FA9CCD155B16B600B6FAC1 /* test_implicit.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_implicit.py; sourceTree = "<group>"; };
-		66FA9CCE155B16B600B6FAC1 /* test_itip.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_itip.py; sourceTree = "<group>"; };
-		66FA9CCF155B16B600B6FAC1 /* utils.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = utils.py; sourceTree = "<group>"; };
-		66FA9CD0155B16B600B6FAC1 /* servers.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = servers.py; sourceTree = "<group>"; };
-		66FA9CD1155B16B600B6FAC1 /* sharedcollection.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = sharedcollection.py; sourceTree = "<group>"; };
-		66FA9CD2155B16B600B6FAC1 /* sharing.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = sharing.py; sourceTree = "<group>"; };
-		66FA9CD3155B16B600B6FAC1 /* simpleresource.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = simpleresource.py; sourceTree = "<group>"; };
-		66FA9CD4155B16B600B6FAC1 /* sql.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = sql.py; sourceTree = "<group>"; };
-		66FA9CD5155B16B600B6FAC1 /* stdconfig.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = stdconfig.py; sourceTree = "<group>"; };
-		66FA9CD6155B16B600B6FAC1 /* storebridge.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = storebridge.py; sourceTree = "<group>"; };
-		66FA9CD8155B16B600B6FAC1 /* __init__.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = __init__.py; sourceTree = "<group>"; };
-		66FA9CDA155B16B600B6FAC1 /* 2445AllExamples.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = 2445AllExamples.ics; sourceTree = "<group>"; };
-		66FA9CDB155B16B600B6FAC1 /* 2445AllExamples.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = 2445AllExamples.txt; sourceTree = "<group>"; };
-		66FA9CDC155B16B600B6FAC1 /* AnotherEvent.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = AnotherEvent.ics; sourceTree = "<group>"; };
-		66FA9CDD155B16B600B6FAC1 /* calendar.10.tgz */ = {isa = PBXFileReference; lastKnownFileType = file; path = calendar.10.tgz; sourceTree = "<group>"; };
-		66FA9CDE155B16B600B6FAC1 /* calendar.100.tgz */ = {isa = PBXFileReference; lastKnownFileType = file; path = calendar.100.tgz; sourceTree = "<group>"; };
-		66FA9CDF155B16B600B6FAC1 /* calendar.1000.tgz */ = {isa = PBXFileReference; lastKnownFileType = file; path = calendar.1000.tgz; sourceTree = "<group>"; };
-		66FA9CE0155B16B600B6FAC1 /* csv2ical.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = csv2ical.py; sourceTree = "<group>"; };
-		66FA9CE2155B16B600B6FAC1 /* C3184A66-1ED0-11D9-A5E0-000A958A3252.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = "C3184A66-1ED0-11D9-A5E0-000A958A3252.ics"; sourceTree = "<group>"; };
-		66FA9CE3155B16B600B6FAC1 /* C3184D26-1ED0-11D9-A5E0-000A958A3252.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = "C3184D26-1ED0-11D9-A5E0-000A958A3252.ics"; sourceTree = "<group>"; };
-		66FA9CE4155B16B600B6FAC1 /* C3185326-1ED0-11D9-A5E0-000A958A3252.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = "C3185326-1ED0-11D9-A5E0-000A958A3252.ics"; sourceTree = "<group>"; };
-		66FA9CE5155B16B600B6FAC1 /* C31854DA-1ED0-11D9-A5E0-000A958A3252.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = "C31854DA-1ED0-11D9-A5E0-000A958A3252.ics"; sourceTree = "<group>"; };
-		66FA9CE6155B16B600B6FAC1 /* C31856AC-1ED0-11D9-A5E0-000A958A3252.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = "C31856AC-1ED0-11D9-A5E0-000A958A3252.ics"; sourceTree = "<group>"; };
-		66FA9CE7155B16B600B6FAC1 /* C318585A-1ED0-11D9-A5E0-000A958A3252.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = "C318585A-1ED0-11D9-A5E0-000A958A3252.ics"; sourceTree = "<group>"; };
-		66FA9CE8155B16B600B6FAC1 /* C3185A14-1ED0-11D9-A5E0-000A958A3252.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = "C3185A14-1ED0-11D9-A5E0-000A958A3252.ics"; sourceTree = "<group>"; };
-		66FA9CE9155B16B600B6FAC1 /* C3185BBD-1ED0-11D9-A5E0-000A958A3252.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = "C3185BBD-1ED0-11D9-A5E0-000A958A3252.ics"; sourceTree = "<group>"; };
-		66FA9CEA155B16B600B6FAC1 /* C3185D63-1ED0-11D9-A5E0-000A958A3252.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = "C3185D63-1ED0-11D9-A5E0-000A958A3252.ics"; sourceTree = "<group>"; };
-		66FA9CEB155B16B600B6FAC1 /* C3185F20-1ED0-11D9-A5E0-000A958A3252.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = "C3185F20-1ED0-11D9-A5E0-000A958A3252.ics"; sourceTree = "<group>"; };
-		66FA9CEC155B16B600B6FAC1 /* C31860C8-1ED0-11D9-A5E0-000A958A3252.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = "C31860C8-1ED0-11D9-A5E0-000A958A3252.ics"; sourceTree = "<group>"; };
-		66FA9CED155B16B600B6FAC1 /* C318627C-1ED0-11D9-A5E0-000A958A3252.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = "C318627C-1ED0-11D9-A5E0-000A958A3252.ics"; sourceTree = "<group>"; };
-		66FA9CEE155B16B600B6FAC1 /* C3186426-1ED0-11D9-A5E0-000A958A3252.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = "C3186426-1ED0-11D9-A5E0-000A958A3252.ics"; sourceTree = "<group>"; };
-		66FA9CEF155B16B600B6FAC1 /* C31865E4-1ED0-11D9-A5E0-000A958A3252.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = "C31865E4-1ED0-11D9-A5E0-000A958A3252.ics"; sourceTree = "<group>"; };
-		66FA9CF0155B16B600B6FAC1 /* C3186792-1ED0-11D9-A5E0-000A958A3252.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = "C3186792-1ED0-11D9-A5E0-000A958A3252.ics"; sourceTree = "<group>"; };
-		66FA9CF1155B16B600B6FAC1 /* C3186938-1ED0-11D9-A5E0-000A958A3252.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = "C3186938-1ED0-11D9-A5E0-000A958A3252.ics"; sourceTree = "<group>"; };
-		66FA9CF2155B16B600B6FAC1 /* C3186ADE-1ED0-11D9-A5E0-000A958A3252.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = "C3186ADE-1ED0-11D9-A5E0-000A958A3252.ics"; sourceTree = "<group>"; };
-		66FA9CF3155B16B600B6FAC1 /* C3186C96-1ED0-11D9-A5E0-000A958A3252.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = "C3186C96-1ED0-11D9-A5E0-000A958A3252.ics"; sourceTree = "<group>"; };
-		66FA9CF4155B16B600B6FAC1 /* C3186E3A-1ED0-11D9-A5E0-000A958A3252.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = "C3186E3A-1ED0-11D9-A5E0-000A958A3252.ics"; sourceTree = "<group>"; };
-		66FA9CF5155B16B600B6FAC1 /* C3186FE7-1ED0-11D9-A5E0-000A958A3252.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = "C3186FE7-1ED0-11D9-A5E0-000A958A3252.ics"; sourceTree = "<group>"; };
-		66FA9CF6155B16B600B6FAC1 /* C318719A-1ED0-11D9-A5E0-000A958A3252.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = "C318719A-1ED0-11D9-A5E0-000A958A3252.ics"; sourceTree = "<group>"; };
-		66FA9CF7155B16B600B6FAC1 /* C3187343-1ED0-11D9-A5E0-000A958A3252.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = "C3187343-1ED0-11D9-A5E0-000A958A3252.ics"; sourceTree = "<group>"; };
-		66FA9CF8155B16B600B6FAC1 /* C3188906-1ED0-11D9-A5E0-000A958A3252.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = "C3188906-1ED0-11D9-A5E0-000A958A3252.ics"; sourceTree = "<group>"; };
-		66FA9CF9155B16B600B6FAC1 /* C3188B3A-1ED0-11D9-A5E0-000A958A3252.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = "C3188B3A-1ED0-11D9-A5E0-000A958A3252.ics"; sourceTree = "<group>"; };
-		66FA9CFA155B16B600B6FAC1 /* C3188CFF-1ED0-11D9-A5E0-000A958A3252.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = "C3188CFF-1ED0-11D9-A5E0-000A958A3252.ics"; sourceTree = "<group>"; };
-		66FA9CFB155B16B600B6FAC1 /* C3188EAA-1ED0-11D9-A5E0-000A958A3252.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = "C3188EAA-1ED0-11D9-A5E0-000A958A3252.ics"; sourceTree = "<group>"; };
-		66FA9CFC155B16B600B6FAC1 /* C3189058-1ED0-11D9-A5E0-000A958A3252.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = "C3189058-1ED0-11D9-A5E0-000A958A3252.ics"; sourceTree = "<group>"; };
-		66FA9CFD155B16B600B6FAC1 /* C3189203-1ED0-11D9-A5E0-000A958A3252.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = "C3189203-1ED0-11D9-A5E0-000A958A3252.ics"; sourceTree = "<group>"; };
-		66FA9CFE155B16B600B6FAC1 /* C31893C2-1ED0-11D9-A5E0-000A958A3252.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = "C31893C2-1ED0-11D9-A5E0-000A958A3252.ics"; sourceTree = "<group>"; };
-		66FA9CFF155B16B600B6FAC1 /* C3189572-1ED0-11D9-A5E0-000A958A3252.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = "C3189572-1ED0-11D9-A5E0-000A958A3252.ics"; sourceTree = "<group>"; };
-		66FA9D00155B16B600B6FAC1 /* C3189716-1ED0-11D9-A5E0-000A958A3252.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = "C3189716-1ED0-11D9-A5E0-000A958A3252.ics"; sourceTree = "<group>"; };
-		66FA9D01155B16B600B6FAC1 /* C31898D4-1ED0-11D9-A5E0-000A958A3252.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = "C31898D4-1ED0-11D9-A5E0-000A958A3252.ics"; sourceTree = "<group>"; };
-		66FA9D02155B16B600B6FAC1 /* C3189A88-1ED0-11D9-A5E0-000A958A3252.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = "C3189A88-1ED0-11D9-A5E0-000A958A3252.ics"; sourceTree = "<group>"; };
-		66FA9D03155B16B600B6FAC1 /* C3189C32-1ED0-11D9-A5E0-000A958A3252.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = "C3189C32-1ED0-11D9-A5E0-000A958A3252.ics"; sourceTree = "<group>"; };
-		66FA9D04155B16B600B6FAC1 /* C3189DEC-1ED0-11D9-A5E0-000A958A3252.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = "C3189DEC-1ED0-11D9-A5E0-000A958A3252.ics"; sourceTree = "<group>"; };
-		66FA9D05155B16B600B6FAC1 /* C3189F94-1ED0-11D9-A5E0-000A958A3252.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = "C3189F94-1ED0-11D9-A5E0-000A958A3252.ics"; sourceTree = "<group>"; };
-		66FA9D06155B16B600B6FAC1 /* C318A148-1ED0-11D9-A5E0-000A958A3252.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = "C318A148-1ED0-11D9-A5E0-000A958A3252.ics"; sourceTree = "<group>"; };
-		66FA9D07155B16B600B6FAC1 /* C318A2F3-1ED0-11D9-A5E0-000A958A3252.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = "C318A2F3-1ED0-11D9-A5E0-000A958A3252.ics"; sourceTree = "<group>"; };
-		66FA9D08155B16B600B6FAC1 /* C318A4BA-1ED0-11D9-A5E0-000A958A3252.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = "C318A4BA-1ED0-11D9-A5E0-000A958A3252.ics"; sourceTree = "<group>"; };
-		66FA9D09155B16B600B6FAC1 /* C318A6E1-1ED0-11D9-A5E0-000A958A3252.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = "C318A6E1-1ED0-11D9-A5E0-000A958A3252.ics"; sourceTree = "<group>"; };
-		66FA9D0A155B16B600B6FAC1 /* C318A898-1ED0-11D9-A5E0-000A958A3252.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = "C318A898-1ED0-11D9-A5E0-000A958A3252.ics"; sourceTree = "<group>"; };
-		66FA9D0B155B16B600B6FAC1 /* C318AA54-1ED0-11D9-A5E0-000A958A3252.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = "C318AA54-1ED0-11D9-A5E0-000A958A3252.ics"; sourceTree = "<group>"; };
-		66FA9D0C155B16B600B6FAC1 /* C318ABFE-1ED0-11D9-A5E0-000A958A3252.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = "C318ABFE-1ED0-11D9-A5E0-000A958A3252.ics"; sourceTree = "<group>"; };
-		66FA9D0D155B16B600B6FAC1 /* C318ADAA-1ED0-11D9-A5E0-000A958A3252.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = "C318ADAA-1ED0-11D9-A5E0-000A958A3252.ics"; sourceTree = "<group>"; };
-		66FA9D0E155B16B600B6FAC1 /* C318AF53-1ED0-11D9-A5E0-000A958A3252.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = "C318AF53-1ED0-11D9-A5E0-000A958A3252.ics"; sourceTree = "<group>"; };
-		66FA9D0F155B16B600B6FAC1 /* C318B108-1ED0-11D9-A5E0-000A958A3252.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = "C318B108-1ED0-11D9-A5E0-000A958A3252.ics"; sourceTree = "<group>"; };
-		66FA9D10155B16B600B6FAC1 /* C318B2D2-1ED0-11D9-A5E0-000A958A3252.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = "C318B2D2-1ED0-11D9-A5E0-000A958A3252.ics"; sourceTree = "<group>"; };
-		66FA9D11155B16B600B6FAC1 /* Holidays.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Holidays.ics; sourceTree = "<group>"; };
-		66FA9D15155B16B600B6FAC1 /* calendarserver.mo */ = {isa = PBXFileReference; lastKnownFileType = file; path = calendarserver.mo; sourceTree = "<group>"; };
-		66FA9D16155B16B600B6FAC1 /* calendarserver.po */ = {isa = PBXFileReference; lastKnownFileType = text; path = calendarserver.po; sourceTree = "<group>"; };
-		66FA9D19155B16B600B6FAC1 /* calendarserver.mo */ = {isa = PBXFileReference; lastKnownFileType = file; path = calendarserver.mo; sourceTree = "<group>"; };
-		66FA9D1A155B16B600B6FAC1 /* calendarserver.po */ = {isa = PBXFileReference; lastKnownFileType = text; path = calendarserver.po; sourceTree = "<group>"; };
-		66FA9D1C155B16B600B6FAC1 /* dsn_failure_no_ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = dsn_failure_no_ics; sourceTree = "<group>"; };
-		66FA9D1D155B16B600B6FAC1 /* dsn_failure_no_original */ = {isa = PBXFileReference; lastKnownFileType = text; path = dsn_failure_no_original; sourceTree = "<group>"; };
-		66FA9D1E155B16B600B6FAC1 /* dsn_failure_with_ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = dsn_failure_with_ics; sourceTree = "<group>"; };
-		66FA9D1F155B16B600B6FAC1 /* good_reply */ = {isa = PBXFileReference; lastKnownFileType = text; path = good_reply; sourceTree = "<group>"; };
-		66FA9D20155B16B600B6FAC1 /* reply_missing_attachment */ = {isa = PBXFileReference; lastKnownFileType = text; path = reply_missing_attachment; sourceTree = "<group>"; };
-		66FA9D21155B16B600B6FAC1 /* reply_missing_attendee */ = {isa = PBXFileReference; lastKnownFileType = text; path = reply_missing_attendee; sourceTree = "<group>"; };
-		66FA9D22155B16B600B6FAC1 /* reply_missing_organizer */ = {isa = PBXFileReference; lastKnownFileType = text; path = reply_missing_organizer; sourceTree = "<group>"; };
-		66FA9D23155B16B600B6FAC1 /* makelargecalendars.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = makelargecalendars.py; sourceTree = "<group>"; };
-		66FA9D24155B16B600B6FAC1 /* makelargefbset.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = makelargefbset.py; sourceTree = "<group>"; };
-		66FA9D25155B16B600B6FAC1 /* OneEvent.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = OneEvent.ics; sourceTree = "<group>"; };
-		66FA9D26155B16B600B6FAC1 /* PayDay.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = PayDay.ics; sourceTree = "<group>"; };
-		66FA9D27155B16B600B6FAC1 /* PayDay.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = PayDay.txt; sourceTree = "<group>"; };
-		66FA9D29155B16B600B6FAC1 /* README */ = {isa = PBXFileReference; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
-		66FA9D2A155B16B600B6FAC1 /* Test-01A.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = "Test-01A.ics"; sourceTree = "<group>"; };
-		66FA9D2B155B16B600B6FAC1 /* Test-01A.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = "Test-01A.txt"; sourceTree = "<group>"; };
-		66FA9D2C155B16B600B6FAC1 /* Test-01B.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = "Test-01B.ics"; sourceTree = "<group>"; };
-		66FA9D2D155B16B600B6FAC1 /* Test-01B.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = "Test-01B.txt"; sourceTree = "<group>"; };
-		66FA9D2E155B16B600B6FAC1 /* Test-02A.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = "Test-02A.ics"; sourceTree = "<group>"; };
-		66FA9D2F155B16B600B6FAC1 /* Test-02A.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = "Test-02A.txt"; sourceTree = "<group>"; };
-		66FA9D30155B16B600B6FAC1 /* Test-02B.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = "Test-02B.ics"; sourceTree = "<group>"; };
-		66FA9D31155B16B600B6FAC1 /* Test-02B.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = "Test-02B.txt"; sourceTree = "<group>"; };
-		66FA9D32155B16B600B6FAC1 /* Test-03A.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = "Test-03A.ics"; sourceTree = "<group>"; };
-		66FA9D33155B16B600B6FAC1 /* Test-03A.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = "Test-03A.txt"; sourceTree = "<group>"; };
-		66FA9D34155B16B600B6FAC1 /* Test-03B.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = "Test-03B.ics"; sourceTree = "<group>"; };
-		66FA9D35155B16B600B6FAC1 /* Test-03B.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = "Test-03B.txt"; sourceTree = "<group>"; };
-		66FA9D36155B16B600B6FAC1 /* Test-03C.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = "Test-03C.ics"; sourceTree = "<group>"; };
-		66FA9D37155B16B600B6FAC1 /* Test-03C.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = "Test-03C.txt"; sourceTree = "<group>"; };
-		66FA9D38155B16B600B6FAC1 /* Test-03D.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = "Test-03D.ics"; sourceTree = "<group>"; };
-		66FA9D39155B16B600B6FAC1 /* Test-03D.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = "Test-03D.txt"; sourceTree = "<group>"; };
-		66FA9D3A155B16B600B6FAC1 /* Test-03E.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = "Test-03E.ics"; sourceTree = "<group>"; };
-		66FA9D3B155B16B600B6FAC1 /* Test-03E.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = "Test-03E.txt"; sourceTree = "<group>"; };
-		66FA9D3C155B16B600B6FAC1 /* server.pem */ = {isa = PBXFileReference; lastKnownFileType = text; path = server.pem; sourceTree = "<group>"; };
-		66FA9D3D155B16B600B6FAC1 /* split_holidays.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = split_holidays.py; sourceTree = "<group>"; };
-		66FA9D3E155B16B600B6FAC1 /* ThirdEvent.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = ThirdEvent.ics; sourceTree = "<group>"; };
-		66FA9D3F155B16B600B6FAC1 /* TruncatedApr01.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = TruncatedApr01.ics; sourceTree = "<group>"; };
-		66FA9D40155B16B600B6FAC1 /* TruncatedDec10.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = TruncatedDec10.ics; sourceTree = "<group>"; };
-		66FA9D42155B16B600B6FAC1 /* 3765A955-1B96-41EA-994D-335192BEDCCD.vcf */ = {isa = PBXFileReference; lastKnownFileType = text; path = "3765A955-1B96-41EA-994D-335192BEDCCD.vcf"; sourceTree = "<group>"; };
-		66FA9D43155B16B600B6FAC1 /* 44745975-AE6D-4FB0-80A6-A298427E047A.vcf */ = {isa = PBXFileReference; lastKnownFileType = text; path = "44745975-AE6D-4FB0-80A6-A298427E047A.vcf"; sourceTree = "<group>"; };
-		66FA9D44155B16B600B6FAC1 /* 44EE78BF-8814-4471-899C-92280CEFB098.vcf */ = {isa = PBXFileReference; lastKnownFileType = text; path = "44EE78BF-8814-4471-899C-92280CEFB098.vcf"; sourceTree = "<group>"; };
-		66FA9D45155B16B600B6FAC1 /* 8424B7F0-C878-4722-B522-EBB07CF48AD7.vcf */ = {isa = PBXFileReference; lastKnownFileType = text; path = "8424B7F0-C878-4722-B522-EBB07CF48AD7.vcf"; sourceTree = "<group>"; };
-		66FA9D46155B16B600B6FAC1 /* 934731C6-1C95-4C40-BE1F-FA4215B2307B.vcf */ = {isa = PBXFileReference; lastKnownFileType = text; path = "934731C6-1C95-4C40-BE1F-FA4215B2307B.vcf"; sourceTree = "<group>"; };
-		66FA9D47155B16B600B6FAC1 /* AFBB77B8-0438-4825-A1DB-A75D76B6C3A8.vcf */ = {isa = PBXFileReference; lastKnownFileType = text; path = "AFBB77B8-0438-4825-A1DB-A75D76B6C3A8.vcf"; sourceTree = "<group>"; };
-		66FA9D48155B16B600B6FAC1 /* ED7A5AEC-AB19-4CE0-AD6A-2923A3E5C4E1.vcf */ = {isa = PBXFileReference; lastKnownFileType = text; path = "ED7A5AEC-AB19-4CE0-AD6A-2923A3E5C4E1.vcf"; sourceTree = "<group>"; };
-		66FA9D49155B16B600B6FAC1 /* ED7A5AEC-AB19-4CE0-AD6A-2923A3E5C4E2.vcf */ = {isa = PBXFileReference; lastKnownFileType = text; path = "ED7A5AEC-AB19-4CE0-AD6A-2923A3E5C4E2.vcf"; sourceTree = "<group>"; };
-		66FA9D4A155B16B600B6FAC1 /* F0A6918D-8E09-43FA-9684-226810B8A96F.vcf */ = {isa = PBXFileReference; lastKnownFileType = text; path = "F0A6918D-8E09-43FA-9684-226810B8A96F.vcf"; sourceTree = "<group>"; };
-		66FA9D4B155B16B600B6FAC1 /* FCBA0FA3-00B2-4C95-B4EC-4CCC4843F8B1.vcf */ = {isa = PBXFileReference; lastKnownFileType = text; path = "FCBA0FA3-00B2-4C95-B4EC-4CCC4843F8B1.vcf"; sourceTree = "<group>"; };
-		66FA9D4C155B16B600B6FAC1 /* test_accounting.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_accounting.py; sourceTree = "<group>"; };
-		66FA9D4D155B16B600B6FAC1 /* test_addressbookmultiget.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_addressbookmultiget.py; sourceTree = "<group>"; };
-		66FA9D4E155B16B600B6FAC1 /* test_addressbookquery.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_addressbookquery.py; sourceTree = "<group>"; };
-		66FA9D4F155B16B600B6FAC1 /* test_cache.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_cache.py; sourceTree = "<group>"; };
-		66FA9D50155B16B600B6FAC1 /* test_caldavxml.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_caldavxml.py; sourceTree = "<group>"; };
-		66FA9D51155B16B600B6FAC1 /* test_calendarquery.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_calendarquery.py; sourceTree = "<group>"; };
-		66FA9D52155B16B600B6FAC1 /* test_collectioncontents.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_collectioncontents.py; sourceTree = "<group>"; };
-		66FA9D53155B16B600B6FAC1 /* test_config.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_config.py; sourceTree = "<group>"; };
-		66FA9D54155B16B600B6FAC1 /* test_customxml.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_customxml.py; sourceTree = "<group>"; };
-		66FA9D55155B16B600B6FAC1 /* test_database.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_database.py; sourceTree = "<group>"; };
-		66FA9D56155B16B600B6FAC1 /* test_dateops.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_dateops.py; sourceTree = "<group>"; };
-		66FA9D57155B16B600B6FAC1 /* test_extensions.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_extensions.py; sourceTree = "<group>"; };
-		66FA9D58155B16B600B6FAC1 /* test_freebusyquery.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_freebusyquery.py; sourceTree = "<group>"; };
-		66FA9D59155B16B600B6FAC1 /* test_icalendar.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_icalendar.py; sourceTree = "<group>"; };
-		66FA9D5A155B16B600B6FAC1 /* test_kerberos.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_kerberos.py; sourceTree = "<group>"; };
-		66FA9D5B155B16B600B6FAC1 /* test_link.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_link.py; sourceTree = "<group>"; };
-		66FA9D5C155B16B600B6FAC1 /* test_localization.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_localization.py; sourceTree = "<group>"; };
-		66FA9D5D155B16B600B6FAC1 /* test_mail.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_mail.py; sourceTree = "<group>"; };
-		66FA9D5E155B16B600B6FAC1 /* test_memcachelock.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_memcachelock.py; sourceTree = "<group>"; };
-		66FA9D5F155B16B600B6FAC1 /* test_memcachepool.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_memcachepool.py; sourceTree = "<group>"; };
-		66FA9D60155B16B600B6FAC1 /* test_memcacheprops.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_memcacheprops.py; sourceTree = "<group>"; };
-		66FA9D61155B16B600B6FAC1 /* test_memcacher.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_memcacher.py; sourceTree = "<group>"; };
-		66FA9D62155B16B600B6FAC1 /* test_mkcalendar.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_mkcalendar.py; sourceTree = "<group>"; };
-		66FA9D63155B16B600B6FAC1 /* test_multiget.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_multiget.py; sourceTree = "<group>"; };
-		66FA9D64155B16B600B6FAC1 /* test_notify.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_notify.py; sourceTree = "<group>"; };
-		66FA9D65155B16B600B6FAC1 /* test_options.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_options.py; sourceTree = "<group>"; };
-		66FA9D66155B16B600B6FAC1 /* test_props.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_props.py; sourceTree = "<group>"; };
-		66FA9D67155B16B600B6FAC1 /* test_resource.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_resource.py; sourceTree = "<group>"; };
-		66FA9D68155B16B600B6FAC1 /* test_schedule.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_schedule.py; sourceTree = "<group>"; };
-		66FA9D69155B16B600B6FAC1 /* test_servers.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_servers.py; sourceTree = "<group>"; };
-		66FA9D6A155B16B600B6FAC1 /* test_sharing.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_sharing.py; sourceTree = "<group>"; };
-		66FA9D6B155B16B600B6FAC1 /* test_sql.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_sql.py; sourceTree = "<group>"; };
-		66FA9D6C155B16B600B6FAC1 /* test_stdconfig.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_stdconfig.py; sourceTree = "<group>"; };
-		66FA9D6D155B16B600B6FAC1 /* test_timezones.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_timezones.py; sourceTree = "<group>"; };
-		66FA9D6E155B16B600B6FAC1 /* test_timezonestdservice.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_timezonestdservice.py; sourceTree = "<group>"; };
-		66FA9D6F155B16B600B6FAC1 /* test_upgrade.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_upgrade.py; sourceTree = "<group>"; };
-		66FA9D70155B16B600B6FAC1 /* test_validation.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_validation.py; sourceTree = "<group>"; };
-		66FA9D71155B16B600B6FAC1 /* test_wrapping.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_wrapping.py; sourceTree = "<group>"; };
-		66FA9D72155B16B600B6FAC1 /* test_xml.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_xml.py; sourceTree = "<group>"; };
-		66FA9D73155B16B600B6FAC1 /* test_xmlutil.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_xmlutil.py; sourceTree = "<group>"; };
-		66FA9D74155B16B600B6FAC1 /* util.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = util.py; sourceTree = "<group>"; };
-		66FA9D75155B16B600B6FAC1 /* timezones.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = timezones.py; sourceTree = "<group>"; };
-		66FA9D76155B16B600B6FAC1 /* timezoneservice.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = timezoneservice.py; sourceTree = "<group>"; };
-		66FA9D77155B16B600B6FAC1 /* timezonestdservice.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = timezonestdservice.py; sourceTree = "<group>"; };
-		66FA9D78155B16B600B6FAC1 /* timezonexml.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = timezonexml.py; sourceTree = "<group>"; };
-		66FA9D79155B16B600B6FAC1 /* upgrade.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = upgrade.py; sourceTree = "<group>"; };
-		66FA9D7A155B16B600B6FAC1 /* util.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = util.py; sourceTree = "<group>"; };
-		66FA9D7B155B16B600B6FAC1 /* vcard.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = vcard.py; sourceTree = "<group>"; };
-		66FA9D7C155B16B600B6FAC1 /* xmlutil.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = xmlutil.py; sourceTree = "<group>"; };
-		66FA9D7F155B16B600B6FAC1 /* Abidjan.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Abidjan.ics; sourceTree = "<group>"; };
-		66FA9D80155B16B600B6FAC1 /* Accra.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Accra.ics; sourceTree = "<group>"; };
-		66FA9D81155B16B600B6FAC1 /* Addis_Ababa.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Addis_Ababa.ics; sourceTree = "<group>"; };
-		66FA9D82155B16B600B6FAC1 /* Algiers.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Algiers.ics; sourceTree = "<group>"; };
-		66FA9D83155B16B600B6FAC1 /* Asmara.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Asmara.ics; sourceTree = "<group>"; };
-		66FA9D84155B16B600B6FAC1 /* Asmera.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Asmera.ics; sourceTree = "<group>"; };
-		66FA9D85155B16B600B6FAC1 /* Bamako.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Bamako.ics; sourceTree = "<group>"; };
-		66FA9D86155B16B600B6FAC1 /* Bangui.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Bangui.ics; sourceTree = "<group>"; };
-		66FA9D87155B16B600B6FAC1 /* Banjul.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Banjul.ics; sourceTree = "<group>"; };
-		66FA9D88155B16B600B6FAC1 /* Bissau.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Bissau.ics; sourceTree = "<group>"; };
-		66FA9D89155B16B600B6FAC1 /* Blantyre.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Blantyre.ics; sourceTree = "<group>"; };
-		66FA9D8A155B16B600B6FAC1 /* Brazzaville.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Brazzaville.ics; sourceTree = "<group>"; };
-		66FA9D8B155B16B600B6FAC1 /* Bujumbura.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Bujumbura.ics; sourceTree = "<group>"; };
-		66FA9D8C155B16B600B6FAC1 /* Cairo.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Cairo.ics; sourceTree = "<group>"; };
-		66FA9D8D155B16B600B6FAC1 /* Casablanca.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Casablanca.ics; sourceTree = "<group>"; };
-		66FA9D8E155B16B600B6FAC1 /* Ceuta.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Ceuta.ics; sourceTree = "<group>"; };
-		66FA9D8F155B16B600B6FAC1 /* Conakry.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Conakry.ics; sourceTree = "<group>"; };
-		66FA9D90155B16B600B6FAC1 /* Dakar.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Dakar.ics; sourceTree = "<group>"; };
-		66FA9D91155B16B600B6FAC1 /* Dar_es_Salaam.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Dar_es_Salaam.ics; sourceTree = "<group>"; };
-		66FA9D92155B16B600B6FAC1 /* Djibouti.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Djibouti.ics; sourceTree = "<group>"; };
-		66FA9D93155B16B600B6FAC1 /* Douala.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Douala.ics; sourceTree = "<group>"; };
-		66FA9D94155B16B600B6FAC1 /* El_Aaiun.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = El_Aaiun.ics; sourceTree = "<group>"; };
-		66FA9D95155B16B600B6FAC1 /* Freetown.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Freetown.ics; sourceTree = "<group>"; };
-		66FA9D96155B16B600B6FAC1 /* Gaborone.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Gaborone.ics; sourceTree = "<group>"; };
-		66FA9D97155B16B600B6FAC1 /* Harare.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Harare.ics; sourceTree = "<group>"; };
-		66FA9D98155B16B600B6FAC1 /* Johannesburg.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Johannesburg.ics; sourceTree = "<group>"; };
-		66FA9D99155B16B600B6FAC1 /* Juba.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Juba.ics; sourceTree = "<group>"; };
-		66FA9D9A155B16B600B6FAC1 /* Kampala.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Kampala.ics; sourceTree = "<group>"; };
-		66FA9D9B155B16B600B6FAC1 /* Khartoum.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Khartoum.ics; sourceTree = "<group>"; };
-		66FA9D9C155B16B600B6FAC1 /* Kigali.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Kigali.ics; sourceTree = "<group>"; };
-		66FA9D9D155B16B600B6FAC1 /* Kinshasa.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Kinshasa.ics; sourceTree = "<group>"; };
-		66FA9D9E155B16B600B6FAC1 /* Lagos.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Lagos.ics; sourceTree = "<group>"; };
-		66FA9D9F155B16B600B6FAC1 /* Libreville.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Libreville.ics; sourceTree = "<group>"; };
-		66FA9DA0155B16B600B6FAC1 /* Lome.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Lome.ics; sourceTree = "<group>"; };
-		66FA9DA1155B16B600B6FAC1 /* Luanda.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Luanda.ics; sourceTree = "<group>"; };
-		66FA9DA2155B16B600B6FAC1 /* Lubumbashi.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Lubumbashi.ics; sourceTree = "<group>"; };
-		66FA9DA3155B16B600B6FAC1 /* Lusaka.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Lusaka.ics; sourceTree = "<group>"; };
-		66FA9DA4155B16B600B6FAC1 /* Malabo.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Malabo.ics; sourceTree = "<group>"; };
-		66FA9DA5155B16B600B6FAC1 /* Maputo.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Maputo.ics; sourceTree = "<group>"; };
-		66FA9DA6155B16B600B6FAC1 /* Maseru.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Maseru.ics; sourceTree = "<group>"; };
-		66FA9DA7155B16B600B6FAC1 /* Mbabane.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Mbabane.ics; sourceTree = "<group>"; };
-		66FA9DA8155B16B600B6FAC1 /* Mogadishu.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Mogadishu.ics; sourceTree = "<group>"; };
-		66FA9DA9155B16B600B6FAC1 /* Monrovia.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Monrovia.ics; sourceTree = "<group>"; };
-		66FA9DAA155B16B600B6FAC1 /* Nairobi.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Nairobi.ics; sourceTree = "<group>"; };
-		66FA9DAB155B16B600B6FAC1 /* Ndjamena.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Ndjamena.ics; sourceTree = "<group>"; };
-		66FA9DAC155B16B600B6FAC1 /* Niamey.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Niamey.ics; sourceTree = "<group>"; };
-		66FA9DAD155B16B600B6FAC1 /* Nouakchott.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Nouakchott.ics; sourceTree = "<group>"; };
-		66FA9DAE155B16B600B6FAC1 /* Ouagadougou.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Ouagadougou.ics; sourceTree = "<group>"; };
-		66FA9DAF155B16B600B6FAC1 /* Porto-Novo.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = "Porto-Novo.ics"; sourceTree = "<group>"; };
-		66FA9DB0155B16B600B6FAC1 /* Sao_Tome.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Sao_Tome.ics; sourceTree = "<group>"; };
-		66FA9DB1155B16B600B6FAC1 /* Timbuktu.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Timbuktu.ics; sourceTree = "<group>"; };
-		66FA9DB2155B16B600B6FAC1 /* Tripoli.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Tripoli.ics; sourceTree = "<group>"; };
-		66FA9DB3155B16B600B6FAC1 /* Tunis.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Tunis.ics; sourceTree = "<group>"; };
-		66FA9DB4155B16B600B6FAC1 /* Windhoek.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Windhoek.ics; sourceTree = "<group>"; };
-		66FA9DB6155B16B600B6FAC1 /* Adak.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Adak.ics; sourceTree = "<group>"; };
-		66FA9DB7155B16B600B6FAC1 /* Anchorage.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Anchorage.ics; sourceTree = "<group>"; };
-		66FA9DB8155B16B600B6FAC1 /* Anguilla.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Anguilla.ics; sourceTree = "<group>"; };
-		66FA9DB9155B16B600B6FAC1 /* Antigua.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Antigua.ics; sourceTree = "<group>"; };
-		66FA9DBA155B16B600B6FAC1 /* Araguaina.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Araguaina.ics; sourceTree = "<group>"; };
-		66FA9DBC155B16B600B6FAC1 /* Buenos_Aires.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Buenos_Aires.ics; sourceTree = "<group>"; };
-		66FA9DBD155B16B600B6FAC1 /* Catamarca.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Catamarca.ics; sourceTree = "<group>"; };
-		66FA9DBE155B16B600B6FAC1 /* ComodRivadavia.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = ComodRivadavia.ics; sourceTree = "<group>"; };
-		66FA9DBF155B16B600B6FAC1 /* Cordoba.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Cordoba.ics; sourceTree = "<group>"; };
-		66FA9DC0155B16B600B6FAC1 /* Jujuy.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Jujuy.ics; sourceTree = "<group>"; };
-		66FA9DC1155B16B600B6FAC1 /* La_Rioja.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = La_Rioja.ics; sourceTree = "<group>"; };
-		66FA9DC2155B16B600B6FAC1 /* Mendoza.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Mendoza.ics; sourceTree = "<group>"; };
-		66FA9DC3155B16B600B6FAC1 /* Rio_Gallegos.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Rio_Gallegos.ics; sourceTree = "<group>"; };
-		66FA9DC4155B16B600B6FAC1 /* Salta.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Salta.ics; sourceTree = "<group>"; };
-		66FA9DC5155B16B600B6FAC1 /* San_Juan.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = San_Juan.ics; sourceTree = "<group>"; };
-		66FA9DC6155B16B600B6FAC1 /* San_Luis.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = San_Luis.ics; sourceTree = "<group>"; };
-		66FA9DC7155B16B600B6FAC1 /* Tucuman.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Tucuman.ics; sourceTree = "<group>"; };
-		66FA9DC8155B16B600B6FAC1 /* Ushuaia.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Ushuaia.ics; sourceTree = "<group>"; };
-		66FA9DC9155B16B600B6FAC1 /* Aruba.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Aruba.ics; sourceTree = "<group>"; };
-		66FA9DCA155B16B600B6FAC1 /* Asuncion.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Asuncion.ics; sourceTree = "<group>"; };
-		66FA9DCB155B16B600B6FAC1 /* Atikokan.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Atikokan.ics; sourceTree = "<group>"; };
-		66FA9DCC155B16B600B6FAC1 /* Atka.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Atka.ics; sourceTree = "<group>"; };
-		66FA9DCD155B16B600B6FAC1 /* Bahia.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Bahia.ics; sourceTree = "<group>"; };
-		66FA9DCE155B16B600B6FAC1 /* Bahia_Banderas.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Bahia_Banderas.ics; sourceTree = "<group>"; };
-		66FA9DCF155B16B600B6FAC1 /* Barbados.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Barbados.ics; sourceTree = "<group>"; };
-		66FA9DD0155B16B600B6FAC1 /* Belem.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Belem.ics; sourceTree = "<group>"; };
-		66FA9DD1155B16B600B6FAC1 /* Belize.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Belize.ics; sourceTree = "<group>"; };
-		66FA9DD2155B16B600B6FAC1 /* Blanc-Sablon.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = "Blanc-Sablon.ics"; sourceTree = "<group>"; };
-		66FA9DD3155B16B600B6FAC1 /* Boa_Vista.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Boa_Vista.ics; sourceTree = "<group>"; };
-		66FA9DD4155B16B600B6FAC1 /* Bogota.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Bogota.ics; sourceTree = "<group>"; };
-		66FA9DD5155B16B600B6FAC1 /* Boise.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Boise.ics; sourceTree = "<group>"; };
-		66FA9DD6155B16B600B6FAC1 /* Buenos_Aires.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Buenos_Aires.ics; sourceTree = "<group>"; };
-		66FA9DD7155B16B600B6FAC1 /* Cambridge_Bay.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Cambridge_Bay.ics; sourceTree = "<group>"; };
-		66FA9DD8155B16B600B6FAC1 /* Campo_Grande.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Campo_Grande.ics; sourceTree = "<group>"; };
-		66FA9DD9155B16B600B6FAC1 /* Cancun.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Cancun.ics; sourceTree = "<group>"; };
-		66FA9DDA155B16B600B6FAC1 /* Caracas.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Caracas.ics; sourceTree = "<group>"; };
-		66FA9DDB155B16B600B6FAC1 /* Catamarca.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Catamarca.ics; sourceTree = "<group>"; };
-		66FA9DDC155B16B600B6FAC1 /* Cayenne.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Cayenne.ics; sourceTree = "<group>"; };
-		66FA9DDD155B16B600B6FAC1 /* Cayman.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Cayman.ics; sourceTree = "<group>"; };
-		66FA9DDE155B16B600B6FAC1 /* Chicago.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Chicago.ics; sourceTree = "<group>"; };
-		66FA9DDF155B16B600B6FAC1 /* Chihuahua.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Chihuahua.ics; sourceTree = "<group>"; };
-		66FA9DE0155B16B600B6FAC1 /* Coral_Harbour.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Coral_Harbour.ics; sourceTree = "<group>"; };
-		66FA9DE1155B16B600B6FAC1 /* Cordoba.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Cordoba.ics; sourceTree = "<group>"; };
-		66FA9DE2155B16B600B6FAC1 /* Costa_Rica.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Costa_Rica.ics; sourceTree = "<group>"; };
-		66FA9DE3155B16B600B6FAC1 /* Cuiaba.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Cuiaba.ics; sourceTree = "<group>"; };
-		66FA9DE4155B16B600B6FAC1 /* Curacao.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Curacao.ics; sourceTree = "<group>"; };
-		66FA9DE5155B16B600B6FAC1 /* Danmarkshavn.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Danmarkshavn.ics; sourceTree = "<group>"; };
-		66FA9DE6155B16B600B6FAC1 /* Dawson.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Dawson.ics; sourceTree = "<group>"; };
-		66FA9DE7155B16B600B6FAC1 /* Dawson_Creek.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Dawson_Creek.ics; sourceTree = "<group>"; };
-		66FA9DE8155B16B600B6FAC1 /* Denver.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Denver.ics; sourceTree = "<group>"; };
-		66FA9DE9155B16B600B6FAC1 /* Detroit.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Detroit.ics; sourceTree = "<group>"; };
-		66FA9DEA155B16B600B6FAC1 /* Dominica.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Dominica.ics; sourceTree = "<group>"; };
-		66FA9DEB155B16B600B6FAC1 /* Edmonton.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Edmonton.ics; sourceTree = "<group>"; };
-		66FA9DEC155B16B600B6FAC1 /* Eirunepe.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Eirunepe.ics; sourceTree = "<group>"; };
-		66FA9DED155B16B600B6FAC1 /* El_Salvador.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = El_Salvador.ics; sourceTree = "<group>"; };
-		66FA9DEE155B16B600B6FAC1 /* Ensenada.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Ensenada.ics; sourceTree = "<group>"; };
-		66FA9DEF155B16B600B6FAC1 /* Fort_Wayne.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Fort_Wayne.ics; sourceTree = "<group>"; };
-		66FA9DF0155B16B600B6FAC1 /* Fortaleza.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Fortaleza.ics; sourceTree = "<group>"; };
-		66FA9DF1155B16B600B6FAC1 /* Glace_Bay.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Glace_Bay.ics; sourceTree = "<group>"; };
-		66FA9DF2155B16B600B6FAC1 /* Godthab.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Godthab.ics; sourceTree = "<group>"; };
-		66FA9DF3155B16B600B6FAC1 /* Goose_Bay.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Goose_Bay.ics; sourceTree = "<group>"; };
-		66FA9DF4155B16B600B6FAC1 /* Grand_Turk.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Grand_Turk.ics; sourceTree = "<group>"; };
-		66FA9DF5155B16B600B6FAC1 /* Grenada.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Grenada.ics; sourceTree = "<group>"; };
-		66FA9DF6155B16B600B6FAC1 /* Guadeloupe.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Guadeloupe.ics; sourceTree = "<group>"; };
-		66FA9DF7155B16B600B6FAC1 /* Guatemala.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Guatemala.ics; sourceTree = "<group>"; };
-		66FA9DF8155B16B600B6FAC1 /* Guayaquil.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Guayaquil.ics; sourceTree = "<group>"; };
-		66FA9DF9155B16B600B6FAC1 /* Guyana.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Guyana.ics; sourceTree = "<group>"; };
-		66FA9DFA155B16B600B6FAC1 /* Halifax.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Halifax.ics; sourceTree = "<group>"; };
-		66FA9DFB155B16B600B6FAC1 /* Havana.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Havana.ics; sourceTree = "<group>"; };
-		66FA9DFC155B16B600B6FAC1 /* Hermosillo.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Hermosillo.ics; sourceTree = "<group>"; };
-		66FA9DFE155B16B600B6FAC1 /* Indianapolis.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Indianapolis.ics; sourceTree = "<group>"; };
-		66FA9DFF155B16B600B6FAC1 /* Knox.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Knox.ics; sourceTree = "<group>"; };
-		66FA9E00155B16B600B6FAC1 /* Marengo.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Marengo.ics; sourceTree = "<group>"; };
-		66FA9E01155B16B600B6FAC1 /* Petersburg.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Petersburg.ics; sourceTree = "<group>"; };
-		66FA9E02155B16B600B6FAC1 /* Tell_City.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Tell_City.ics; sourceTree = "<group>"; };
-		66FA9E03155B16B600B6FAC1 /* Vevay.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Vevay.ics; sourceTree = "<group>"; };
-		66FA9E04155B16B600B6FAC1 /* Vincennes.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Vincennes.ics; sourceTree = "<group>"; };
-		66FA9E05155B16B600B6FAC1 /* Winamac.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Winamac.ics; sourceTree = "<group>"; };
-		66FA9E06155B16B600B6FAC1 /* Indianapolis.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Indianapolis.ics; sourceTree = "<group>"; };
-		66FA9E07155B16B600B6FAC1 /* Inuvik.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Inuvik.ics; sourceTree = "<group>"; };
-		66FA9E08155B16B600B6FAC1 /* Iqaluit.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Iqaluit.ics; sourceTree = "<group>"; };
-		66FA9E09155B16B600B6FAC1 /* Jamaica.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Jamaica.ics; sourceTree = "<group>"; };
-		66FA9E0A155B16B600B6FAC1 /* Jujuy.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Jujuy.ics; sourceTree = "<group>"; };
-		66FA9E0B155B16B600B6FAC1 /* Juneau.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Juneau.ics; sourceTree = "<group>"; };
-		66FA9E0D155B16B600B6FAC1 /* Louisville.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Louisville.ics; sourceTree = "<group>"; };
-		66FA9E0E155B16B600B6FAC1 /* Monticello.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Monticello.ics; sourceTree = "<group>"; };
-		66FA9E0F155B16B600B6FAC1 /* Knox_IN.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Knox_IN.ics; sourceTree = "<group>"; };
-		66FA9E10155B16B600B6FAC1 /* Kralendijk.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Kralendijk.ics; sourceTree = "<group>"; };
-		66FA9E11155B16B600B6FAC1 /* La_Paz.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = La_Paz.ics; sourceTree = "<group>"; };
-		66FA9E12155B16B600B6FAC1 /* Lima.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Lima.ics; sourceTree = "<group>"; };
-		66FA9E13155B16B600B6FAC1 /* Los_Angeles.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Los_Angeles.ics; sourceTree = "<group>"; };
-		66FA9E14155B16B600B6FAC1 /* Louisville.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Louisville.ics; sourceTree = "<group>"; };
-		66FA9E15155B16B600B6FAC1 /* Lower_Princes.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Lower_Princes.ics; sourceTree = "<group>"; };
-		66FA9E16155B16B600B6FAC1 /* Maceio.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Maceio.ics; sourceTree = "<group>"; };
-		66FA9E17155B16B600B6FAC1 /* Managua.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Managua.ics; sourceTree = "<group>"; };
-		66FA9E18155B16B600B6FAC1 /* Manaus.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Manaus.ics; sourceTree = "<group>"; };
-		66FA9E19155B16B600B6FAC1 /* Marigot.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Marigot.ics; sourceTree = "<group>"; };
-		66FA9E1A155B16B600B6FAC1 /* Martinique.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Martinique.ics; sourceTree = "<group>"; };
-		66FA9E1B155B16B600B6FAC1 /* Matamoros.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Matamoros.ics; sourceTree = "<group>"; };
-		66FA9E1C155B16B600B6FAC1 /* Mazatlan.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Mazatlan.ics; sourceTree = "<group>"; };
-		66FA9E1D155B16B600B6FAC1 /* Mendoza.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Mendoza.ics; sourceTree = "<group>"; };
-		66FA9E1E155B16B600B6FAC1 /* Menominee.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Menominee.ics; sourceTree = "<group>"; };
-		66FA9E1F155B16B600B6FAC1 /* Merida.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Merida.ics; sourceTree = "<group>"; };
-		66FA9E20155B16B600B6FAC1 /* Metlakatla.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Metlakatla.ics; sourceTree = "<group>"; };
-		66FA9E21155B16B600B6FAC1 /* Mexico_City.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Mexico_City.ics; sourceTree = "<group>"; };
-		66FA9E22155B16B600B6FAC1 /* Miquelon.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Miquelon.ics; sourceTree = "<group>"; };
-		66FA9E23155B16B600B6FAC1 /* Moncton.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Moncton.ics; sourceTree = "<group>"; };
-		66FA9E24155B16B600B6FAC1 /* Monterrey.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Monterrey.ics; sourceTree = "<group>"; };
-		66FA9E25155B16B600B6FAC1 /* Montevideo.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Montevideo.ics; sourceTree = "<group>"; };
-		66FA9E26155B16B600B6FAC1 /* Montreal.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Montreal.ics; sourceTree = "<group>"; };
-		66FA9E27155B16B600B6FAC1 /* Montserrat.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Montserrat.ics; sourceTree = "<group>"; };
-		66FA9E28155B16B600B6FAC1 /* Nassau.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Nassau.ics; sourceTree = "<group>"; };
-		66FA9E29155B16B600B6FAC1 /* New_York.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = New_York.ics; sourceTree = "<group>"; };
-		66FA9E2A155B16B600B6FAC1 /* Nipigon.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Nipigon.ics; sourceTree = "<group>"; };
-		66FA9E2B155B16B600B6FAC1 /* Nome.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Nome.ics; sourceTree = "<group>"; };
-		66FA9E2C155B16B600B6FAC1 /* Noronha.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Noronha.ics; sourceTree = "<group>"; };
-		66FA9E2E155B16B600B6FAC1 /* Beulah.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Beulah.ics; sourceTree = "<group>"; };
-		66FA9E2F155B16B600B6FAC1 /* Center.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Center.ics; sourceTree = "<group>"; };
-		66FA9E30155B16B600B6FAC1 /* New_Salem.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = New_Salem.ics; sourceTree = "<group>"; };
-		66FA9E31155B16B600B6FAC1 /* Ojinaga.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Ojinaga.ics; sourceTree = "<group>"; };
-		66FA9E32155B16B600B6FAC1 /* Panama.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Panama.ics; sourceTree = "<group>"; };
-		66FA9E33155B16B600B6FAC1 /* Pangnirtung.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Pangnirtung.ics; sourceTree = "<group>"; };
-		66FA9E34155B16B600B6FAC1 /* Paramaribo.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Paramaribo.ics; sourceTree = "<group>"; };
-		66FA9E35155B16B600B6FAC1 /* Phoenix.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Phoenix.ics; sourceTree = "<group>"; };
-		66FA9E36155B16B600B6FAC1 /* Port-au-Prince.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = "Port-au-Prince.ics"; sourceTree = "<group>"; };
-		66FA9E37155B16B600B6FAC1 /* Port_of_Spain.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Port_of_Spain.ics; sourceTree = "<group>"; };
-		66FA9E38155B16B600B6FAC1 /* Porto_Acre.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Porto_Acre.ics; sourceTree = "<group>"; };
-		66FA9E39155B16B600B6FAC1 /* Porto_Velho.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Porto_Velho.ics; sourceTree = "<group>"; };
-		66FA9E3A155B16B600B6FAC1 /* Puerto_Rico.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Puerto_Rico.ics; sourceTree = "<group>"; };
-		66FA9E3B155B16B600B6FAC1 /* Rainy_River.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Rainy_River.ics; sourceTree = "<group>"; };
-		66FA9E3C155B16B600B6FAC1 /* Rankin_Inlet.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Rankin_Inlet.ics; sourceTree = "<group>"; };
-		66FA9E3D155B16B600B6FAC1 /* Recife.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Recife.ics; sourceTree = "<group>"; };
-		66FA9E3E155B16B600B6FAC1 /* Regina.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Regina.ics; sourceTree = "<group>"; };
-		66FA9E3F155B16B600B6FAC1 /* Resolute.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Resolute.ics; sourceTree = "<group>"; };
-		66FA9E40155B16B600B6FAC1 /* Rio_Branco.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Rio_Branco.ics; sourceTree = "<group>"; };
-		66FA9E41155B16B600B6FAC1 /* Rosario.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Rosario.ics; sourceTree = "<group>"; };
-		66FA9E42155B16B600B6FAC1 /* Santa_Isabel.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Santa_Isabel.ics; sourceTree = "<group>"; };
-		66FA9E43155B16B600B6FAC1 /* Santarem.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Santarem.ics; sourceTree = "<group>"; };
-		66FA9E44155B16B600B6FAC1 /* Santiago.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Santiago.ics; sourceTree = "<group>"; };
-		66FA9E45155B16B600B6FAC1 /* Santo_Domingo.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Santo_Domingo.ics; sourceTree = "<group>"; };
-		66FA9E46155B16B600B6FAC1 /* Sao_Paulo.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Sao_Paulo.ics; sourceTree = "<group>"; };
-		66FA9E47155B16B600B6FAC1 /* Scoresbysund.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Scoresbysund.ics; sourceTree = "<group>"; };
-		66FA9E48155B16B600B6FAC1 /* Shiprock.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Shiprock.ics; sourceTree = "<group>"; };
-		66FA9E49155B16B600B6FAC1 /* Sitka.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Sitka.ics; sourceTree = "<group>"; };
-		66FA9E4A155B16B600B6FAC1 /* St_Barthelemy.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = St_Barthelemy.ics; sourceTree = "<group>"; };
-		66FA9E4B155B16B600B6FAC1 /* St_Johns.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = St_Johns.ics; sourceTree = "<group>"; };
-		66FA9E4C155B16B600B6FAC1 /* St_Kitts.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = St_Kitts.ics; sourceTree = "<group>"; };
-		66FA9E4D155B16B600B6FAC1 /* St_Lucia.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = St_Lucia.ics; sourceTree = "<group>"; };
-		66FA9E4E155B16B600B6FAC1 /* St_Thomas.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = St_Thomas.ics; sourceTree = "<group>"; };
-		66FA9E4F155B16B600B6FAC1 /* St_Vincent.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = St_Vincent.ics; sourceTree = "<group>"; };
-		66FA9E50155B16B600B6FAC1 /* Swift_Current.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Swift_Current.ics; sourceTree = "<group>"; };
-		66FA9E51155B16B600B6FAC1 /* Tegucigalpa.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Tegucigalpa.ics; sourceTree = "<group>"; };
-		66FA9E52155B16B600B6FAC1 /* Thule.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Thule.ics; sourceTree = "<group>"; };
-		66FA9E53155B16B600B6FAC1 /* Thunder_Bay.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Thunder_Bay.ics; sourceTree = "<group>"; };
-		66FA9E54155B16B600B6FAC1 /* Tijuana.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Tijuana.ics; sourceTree = "<group>"; };
-		66FA9E55155B16B600B6FAC1 /* Toronto.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Toronto.ics; sourceTree = "<group>"; };
-		66FA9E56155B16B600B6FAC1 /* Tortola.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Tortola.ics; sourceTree = "<group>"; };
-		66FA9E57155B16B600B6FAC1 /* Vancouver.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Vancouver.ics; sourceTree = "<group>"; };
-		66FA9E58155B16B600B6FAC1 /* Virgin.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Virgin.ics; sourceTree = "<group>"; };
-		66FA9E59155B16B600B6FAC1 /* Whitehorse.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Whitehorse.ics; sourceTree = "<group>"; };
-		66FA9E5A155B16B600B6FAC1 /* Winnipeg.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Winnipeg.ics; sourceTree = "<group>"; };
-		66FA9E5B155B16B600B6FAC1 /* Yakutat.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Yakutat.ics; sourceTree = "<group>"; };
-		66FA9E5C155B16B600B6FAC1 /* Yellowknife.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Yellowknife.ics; sourceTree = "<group>"; };
-		66FA9E5E155B16B600B6FAC1 /* Casey.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Casey.ics; sourceTree = "<group>"; };
-		66FA9E5F155B16B600B6FAC1 /* Davis.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Davis.ics; sourceTree = "<group>"; };
-		66FA9E60155B16B600B6FAC1 /* DumontDUrville.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = DumontDUrville.ics; sourceTree = "<group>"; };
-		66FA9E61155B16B600B6FAC1 /* Macquarie.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Macquarie.ics; sourceTree = "<group>"; };
-		66FA9E62155B16B600B6FAC1 /* Mawson.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Mawson.ics; sourceTree = "<group>"; };
-		66FA9E63155B16B600B6FAC1 /* McMurdo.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = McMurdo.ics; sourceTree = "<group>"; };
-		66FA9E64155B16B600B6FAC1 /* Palmer.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Palmer.ics; sourceTree = "<group>"; };
-		66FA9E65155B16B600B6FAC1 /* Rothera.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Rothera.ics; sourceTree = "<group>"; };
-		66FA9E66155B16B600B6FAC1 /* South_Pole.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = South_Pole.ics; sourceTree = "<group>"; };
-		66FA9E67155B16B600B6FAC1 /* Syowa.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Syowa.ics; sourceTree = "<group>"; };
-		66FA9E68155B16B600B6FAC1 /* Vostok.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Vostok.ics; sourceTree = "<group>"; };
-		66FA9E6A155B16B600B6FAC1 /* Longyearbyen.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Longyearbyen.ics; sourceTree = "<group>"; };
-		66FA9E6C155B16B600B6FAC1 /* Aden.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Aden.ics; sourceTree = "<group>"; };
-		66FA9E6D155B16B600B6FAC1 /* Almaty.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Almaty.ics; sourceTree = "<group>"; };
-		66FA9E6E155B16B600B6FAC1 /* Amman.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Amman.ics; sourceTree = "<group>"; };
-		66FA9E6F155B16B600B6FAC1 /* Anadyr.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Anadyr.ics; sourceTree = "<group>"; };
-		66FA9E70155B16B600B6FAC1 /* Aqtau.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Aqtau.ics; sourceTree = "<group>"; };
-		66FA9E71155B16B600B6FAC1 /* Aqtobe.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Aqtobe.ics; sourceTree = "<group>"; };
-		66FA9E72155B16B600B6FAC1 /* Ashgabat.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Ashgabat.ics; sourceTree = "<group>"; };
-		66FA9E73155B16B600B6FAC1 /* Ashkhabad.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Ashkhabad.ics; sourceTree = "<group>"; };
-		66FA9E74155B16B600B6FAC1 /* Baghdad.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Baghdad.ics; sourceTree = "<group>"; };
-		66FA9E75155B16B600B6FAC1 /* Bahrain.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Bahrain.ics; sourceTree = "<group>"; };
-		66FA9E76155B16B600B6FAC1 /* Baku.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Baku.ics; sourceTree = "<group>"; };
-		66FA9E77155B16B600B6FAC1 /* Bangkok.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Bangkok.ics; sourceTree = "<group>"; };
-		66FA9E78155B16B600B6FAC1 /* Beirut.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Beirut.ics; sourceTree = "<group>"; };
-		66FA9E79155B16B600B6FAC1 /* Bishkek.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Bishkek.ics; sourceTree = "<group>"; };
-		66FA9E7A155B16B600B6FAC1 /* Brunei.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Brunei.ics; sourceTree = "<group>"; };
-		66FA9E7B155B16B600B6FAC1 /* Calcutta.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Calcutta.ics; sourceTree = "<group>"; };
-		66FA9E7C155B16B600B6FAC1 /* Choibalsan.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Choibalsan.ics; sourceTree = "<group>"; };
-		66FA9E7D155B16B600B6FAC1 /* Chongqing.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Chongqing.ics; sourceTree = "<group>"; };
-		66FA9E7E155B16B600B6FAC1 /* Chungking.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Chungking.ics; sourceTree = "<group>"; };
-		66FA9E7F155B16B600B6FAC1 /* Colombo.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Colombo.ics; sourceTree = "<group>"; };
-		66FA9E80155B16B600B6FAC1 /* Dacca.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Dacca.ics; sourceTree = "<group>"; };
-		66FA9E81155B16B600B6FAC1 /* Damascus.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Damascus.ics; sourceTree = "<group>"; };
-		66FA9E82155B16B600B6FAC1 /* Dhaka.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Dhaka.ics; sourceTree = "<group>"; };
-		66FA9E83155B16B600B6FAC1 /* Dili.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Dili.ics; sourceTree = "<group>"; };
-		66FA9E84155B16B600B6FAC1 /* Dubai.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Dubai.ics; sourceTree = "<group>"; };
-		66FA9E85155B16B600B6FAC1 /* Dushanbe.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Dushanbe.ics; sourceTree = "<group>"; };
-		66FA9E86155B16B600B6FAC1 /* Gaza.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Gaza.ics; sourceTree = "<group>"; };
-		66FA9E87155B16B600B6FAC1 /* Harbin.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Harbin.ics; sourceTree = "<group>"; };
-		66FA9E88155B16B600B6FAC1 /* Hebron.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Hebron.ics; sourceTree = "<group>"; };
-		66FA9E89155B16B600B6FAC1 /* Ho_Chi_Minh.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Ho_Chi_Minh.ics; sourceTree = "<group>"; };
-		66FA9E8A155B16B600B6FAC1 /* Hong_Kong.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Hong_Kong.ics; sourceTree = "<group>"; };
-		66FA9E8B155B16B600B6FAC1 /* Hovd.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Hovd.ics; sourceTree = "<group>"; };
-		66FA9E8C155B16B600B6FAC1 /* Irkutsk.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Irkutsk.ics; sourceTree = "<group>"; };
-		66FA9E8D155B16B600B6FAC1 /* Istanbul.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Istanbul.ics; sourceTree = "<group>"; };
-		66FA9E8E155B16B600B6FAC1 /* Jakarta.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Jakarta.ics; sourceTree = "<group>"; };
-		66FA9E8F155B16B600B6FAC1 /* Jayapura.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Jayapura.ics; sourceTree = "<group>"; };
-		66FA9E90155B16B600B6FAC1 /* Jerusalem.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Jerusalem.ics; sourceTree = "<group>"; };
-		66FA9E91155B16B600B6FAC1 /* Kabul.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Kabul.ics; sourceTree = "<group>"; };
-		66FA9E92155B16B600B6FAC1 /* Kamchatka.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Kamchatka.ics; sourceTree = "<group>"; };
-		66FA9E93155B16B600B6FAC1 /* Karachi.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Karachi.ics; sourceTree = "<group>"; };
-		66FA9E94155B16B600B6FAC1 /* Kashgar.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Kashgar.ics; sourceTree = "<group>"; };
-		66FA9E95155B16B600B6FAC1 /* Kathmandu.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Kathmandu.ics; sourceTree = "<group>"; };
-		66FA9E96155B16B600B6FAC1 /* Katmandu.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Katmandu.ics; sourceTree = "<group>"; };
-		66FA9E97155B16B600B6FAC1 /* Kolkata.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Kolkata.ics; sourceTree = "<group>"; };
-		66FA9E98155B16B600B6FAC1 /* Krasnoyarsk.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Krasnoyarsk.ics; sourceTree = "<group>"; };
-		66FA9E99155B16B600B6FAC1 /* Kuala_Lumpur.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Kuala_Lumpur.ics; sourceTree = "<group>"; };
-		66FA9E9A155B16B600B6FAC1 /* Kuching.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Kuching.ics; sourceTree = "<group>"; };
-		66FA9E9B155B16B600B6FAC1 /* Kuwait.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Kuwait.ics; sourceTree = "<group>"; };
-		66FA9E9C155B16B600B6FAC1 /* Macao.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Macao.ics; sourceTree = "<group>"; };
-		66FA9E9D155B16B600B6FAC1 /* Macau.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Macau.ics; sourceTree = "<group>"; };
-		66FA9E9E155B16B600B6FAC1 /* Magadan.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Magadan.ics; sourceTree = "<group>"; };
-		66FA9E9F155B16B600B6FAC1 /* Makassar.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Makassar.ics; sourceTree = "<group>"; };
-		66FA9EA0155B16B600B6FAC1 /* Manila.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Manila.ics; sourceTree = "<group>"; };
-		66FA9EA1155B16B600B6FAC1 /* Muscat.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Muscat.ics; sourceTree = "<group>"; };
-		66FA9EA2155B16B600B6FAC1 /* Nicosia.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Nicosia.ics; sourceTree = "<group>"; };
-		66FA9EA3155B16B600B6FAC1 /* Novokuznetsk.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Novokuznetsk.ics; sourceTree = "<group>"; };
-		66FA9EA4155B16B600B6FAC1 /* Novosibirsk.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Novosibirsk.ics; sourceTree = "<group>"; };
-		66FA9EA5155B16B600B6FAC1 /* Omsk.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Omsk.ics; sourceTree = "<group>"; };
-		66FA9EA6155B16B600B6FAC1 /* Oral.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Oral.ics; sourceTree = "<group>"; };
-		66FA9EA7155B16B600B6FAC1 /* Phnom_Penh.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Phnom_Penh.ics; sourceTree = "<group>"; };
-		66FA9EA8155B16B600B6FAC1 /* Pontianak.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Pontianak.ics; sourceTree = "<group>"; };
-		66FA9EA9155B16B600B6FAC1 /* Pyongyang.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Pyongyang.ics; sourceTree = "<group>"; };
-		66FA9EAA155B16B600B6FAC1 /* Qatar.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Qatar.ics; sourceTree = "<group>"; };
-		66FA9EAB155B16B600B6FAC1 /* Qyzylorda.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Qyzylorda.ics; sourceTree = "<group>"; };
-		66FA9EAC155B16B600B6FAC1 /* Rangoon.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Rangoon.ics; sourceTree = "<group>"; };
-		66FA9EAD155B16B600B6FAC1 /* Riyadh.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Riyadh.ics; sourceTree = "<group>"; };
-		66FA9EAE155B16B600B6FAC1 /* Saigon.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Saigon.ics; sourceTree = "<group>"; };
-		66FA9EAF155B16B600B6FAC1 /* Sakhalin.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Sakhalin.ics; sourceTree = "<group>"; };
-		66FA9EB0155B16B600B6FAC1 /* Samarkand.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Samarkand.ics; sourceTree = "<group>"; };
-		66FA9EB1155B16B600B6FAC1 /* Seoul.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Seoul.ics; sourceTree = "<group>"; };
-		66FA9EB2155B16B600B6FAC1 /* Shanghai.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Shanghai.ics; sourceTree = "<group>"; };
-		66FA9EB3155B16B600B6FAC1 /* Singapore.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Singapore.ics; sourceTree = "<group>"; };
-		66FA9EB4155B16B600B6FAC1 /* Taipei.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Taipei.ics; sourceTree = "<group>"; };
-		66FA9EB5155B16B600B6FAC1 /* Tashkent.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Tashkent.ics; sourceTree = "<group>"; };
-		66FA9EB6155B16B600B6FAC1 /* Tbilisi.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Tbilisi.ics; sourceTree = "<group>"; };
-		66FA9EB7155B16B600B6FAC1 /* Tehran.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Tehran.ics; sourceTree = "<group>"; };
-		66FA9EB8155B16B600B6FAC1 /* Tel_Aviv.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Tel_Aviv.ics; sourceTree = "<group>"; };
-		66FA9EB9155B16B600B6FAC1 /* Thimbu.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Thimbu.ics; sourceTree = "<group>"; };
-		66FA9EBA155B16B600B6FAC1 /* Thimphu.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Thimphu.ics; sourceTree = "<group>"; };
-		66FA9EBB155B16B600B6FAC1 /* Tokyo.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Tokyo.ics; sourceTree = "<group>"; };
-		66FA9EBC155B16B600B6FAC1 /* Ujung_Pandang.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Ujung_Pandang.ics; sourceTree = "<group>"; };
-		66FA9EBD155B16B600B6FAC1 /* Ulaanbaatar.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Ulaanbaatar.ics; sourceTree = "<group>"; };
-		66FA9EBE155B16B600B6FAC1 /* Ulan_Bator.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Ulan_Bator.ics; sourceTree = "<group>"; };
-		66FA9EBF155B16B600B6FAC1 /* Urumqi.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Urumqi.ics; sourceTree = "<group>"; };
-		66FA9EC0155B16B600B6FAC1 /* Vientiane.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Vientiane.ics; sourceTree = "<group>"; };
-		66FA9EC1155B16B600B6FAC1 /* Vladivostok.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Vladivostok.ics; sourceTree = "<group>"; };
-		66FA9EC2155B16B600B6FAC1 /* Yakutsk.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Yakutsk.ics; sourceTree = "<group>"; };
-		66FA9EC3155B16B600B6FAC1 /* Yekaterinburg.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Yekaterinburg.ics; sourceTree = "<group>"; };
-		66FA9EC4155B16B600B6FAC1 /* Yerevan.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Yerevan.ics; sourceTree = "<group>"; };
-		66FA9EC6155B16B600B6FAC1 /* Azores.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Azores.ics; sourceTree = "<group>"; };
-		66FA9EC7155B16B600B6FAC1 /* Bermuda.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Bermuda.ics; sourceTree = "<group>"; };
-		66FA9EC8155B16B600B6FAC1 /* Canary.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Canary.ics; sourceTree = "<group>"; };
-		66FA9EC9155B16B600B6FAC1 /* Cape_Verde.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Cape_Verde.ics; sourceTree = "<group>"; };
-		66FA9ECA155B16B600B6FAC1 /* Faeroe.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Faeroe.ics; sourceTree = "<group>"; };
-		66FA9ECB155B16B600B6FAC1 /* Faroe.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Faroe.ics; sourceTree = "<group>"; };
-		66FA9ECC155B16B600B6FAC1 /* Jan_Mayen.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Jan_Mayen.ics; sourceTree = "<group>"; };
-		66FA9ECD155B16B600B6FAC1 /* Madeira.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Madeira.ics; sourceTree = "<group>"; };
-		66FA9ECE155B16B600B6FAC1 /* Reykjavik.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Reykjavik.ics; sourceTree = "<group>"; };
-		66FA9ECF155B16B600B6FAC1 /* South_Georgia.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = South_Georgia.ics; sourceTree = "<group>"; };
-		66FA9ED0155B16B600B6FAC1 /* St_Helena.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = St_Helena.ics; sourceTree = "<group>"; };
-		66FA9ED1155B16B600B6FAC1 /* Stanley.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Stanley.ics; sourceTree = "<group>"; };
-		66FA9ED3155B16B600B6FAC1 /* ACT.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = ACT.ics; sourceTree = "<group>"; };
-		66FA9ED4155B16B600B6FAC1 /* Adelaide.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Adelaide.ics; sourceTree = "<group>"; };
-		66FA9ED5155B16B600B6FAC1 /* Brisbane.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Brisbane.ics; sourceTree = "<group>"; };
-		66FA9ED6155B16B600B6FAC1 /* Broken_Hill.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Broken_Hill.ics; sourceTree = "<group>"; };
-		66FA9ED7155B16B600B6FAC1 /* Canberra.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Canberra.ics; sourceTree = "<group>"; };
-		66FA9ED8155B16B600B6FAC1 /* Currie.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Currie.ics; sourceTree = "<group>"; };
-		66FA9ED9155B16B600B6FAC1 /* Darwin.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Darwin.ics; sourceTree = "<group>"; };
-		66FA9EDA155B16B600B6FAC1 /* Eucla.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Eucla.ics; sourceTree = "<group>"; };
-		66FA9EDB155B16B600B6FAC1 /* Hobart.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Hobart.ics; sourceTree = "<group>"; };
-		66FA9EDC155B16B600B6FAC1 /* LHI.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = LHI.ics; sourceTree = "<group>"; };
-		66FA9EDD155B16B600B6FAC1 /* Lindeman.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Lindeman.ics; sourceTree = "<group>"; };
-		66FA9EDE155B16B600B6FAC1 /* Lord_Howe.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Lord_Howe.ics; sourceTree = "<group>"; };
-		66FA9EDF155B16B600B6FAC1 /* Melbourne.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Melbourne.ics; sourceTree = "<group>"; };
-		66FA9EE0155B16B600B6FAC1 /* North.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = North.ics; sourceTree = "<group>"; };
-		66FA9EE1155B16B600B6FAC1 /* NSW.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = NSW.ics; sourceTree = "<group>"; };
-		66FA9EE2155B16B600B6FAC1 /* Perth.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Perth.ics; sourceTree = "<group>"; };
-		66FA9EE3155B16B600B6FAC1 /* Queensland.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Queensland.ics; sourceTree = "<group>"; };
-		66FA9EE4155B16B600B6FAC1 /* South.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = South.ics; sourceTree = "<group>"; };
-		66FA9EE5155B16B600B6FAC1 /* Sydney.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Sydney.ics; sourceTree = "<group>"; };
-		66FA9EE6155B16B600B6FAC1 /* Tasmania.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Tasmania.ics; sourceTree = "<group>"; };
-		66FA9EE7155B16B600B6FAC1 /* Victoria.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Victoria.ics; sourceTree = "<group>"; };
-		66FA9EE8155B16B600B6FAC1 /* West.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = West.ics; sourceTree = "<group>"; };
-		66FA9EE9155B16B600B6FAC1 /* Yancowinna.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Yancowinna.ics; sourceTree = "<group>"; };
-		66FA9EEB155B16B600B6FAC1 /* Acre.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Acre.ics; sourceTree = "<group>"; };
-		66FA9EEC155B16B600B6FAC1 /* DeNoronha.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = DeNoronha.ics; sourceTree = "<group>"; };
-		66FA9EED155B16B600B6FAC1 /* East.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = East.ics; sourceTree = "<group>"; };
-		66FA9EEE155B16B600B6FAC1 /* West.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = West.ics; sourceTree = "<group>"; };
-		66FA9EF0155B16B600B6FAC1 /* Atlantic.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Atlantic.ics; sourceTree = "<group>"; };
-		66FA9EF1155B16B600B6FAC1 /* Central.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Central.ics; sourceTree = "<group>"; };
-		66FA9EF2155B16B600B6FAC1 /* East-Saskatchewan.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = "East-Saskatchewan.ics"; sourceTree = "<group>"; };
-		66FA9EF3155B16B600B6FAC1 /* Eastern.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Eastern.ics; sourceTree = "<group>"; };
-		66FA9EF4155B16B600B6FAC1 /* Mountain.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Mountain.ics; sourceTree = "<group>"; };
-		66FA9EF5155B16B600B6FAC1 /* Newfoundland.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Newfoundland.ics; sourceTree = "<group>"; };
-		66FA9EF6155B16B600B6FAC1 /* Pacific.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Pacific.ics; sourceTree = "<group>"; };
-		66FA9EF7155B16B600B6FAC1 /* Saskatchewan.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Saskatchewan.ics; sourceTree = "<group>"; };
-		66FA9EF8155B16B600B6FAC1 /* Yukon.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Yukon.ics; sourceTree = "<group>"; };
-		66FA9EF9155B16B600B6FAC1 /* CET.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = CET.ics; sourceTree = "<group>"; };
-		66FA9EFB155B16B600B6FAC1 /* Continental.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Continental.ics; sourceTree = "<group>"; };
-		66FA9EFC155B16B600B6FAC1 /* EasterIsland.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = EasterIsland.ics; sourceTree = "<group>"; };
-		66FA9EFD155B16B600B6FAC1 /* CST6CDT.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = CST6CDT.ics; sourceTree = "<group>"; };
-		66FA9EFE155B16B600B6FAC1 /* Cuba.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Cuba.ics; sourceTree = "<group>"; };
-		66FA9EFF155B16B600B6FAC1 /* EET.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = EET.ics; sourceTree = "<group>"; };
-		66FA9F00155B16B600B6FAC1 /* Egypt.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Egypt.ics; sourceTree = "<group>"; };
-		66FA9F01155B16B600B6FAC1 /* Eire.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Eire.ics; sourceTree = "<group>"; };
-		66FA9F02155B16B600B6FAC1 /* EST.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = EST.ics; sourceTree = "<group>"; };
-		66FA9F03155B16B600B6FAC1 /* EST5EDT.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = EST5EDT.ics; sourceTree = "<group>"; };
-		66FA9F05155B16B600B6FAC1 /* GMT+0.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = "GMT+0.ics"; sourceTree = "<group>"; };
-		66FA9F06155B16B600B6FAC1 /* GMT+1.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = "GMT+1.ics"; sourceTree = "<group>"; };
-		66FA9F07155B16B600B6FAC1 /* GMT+10.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = "GMT+10.ics"; sourceTree = "<group>"; };
-		66FA9F08155B16B600B6FAC1 /* GMT+11.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = "GMT+11.ics"; sourceTree = "<group>"; };
-		66FA9F09155B16B600B6FAC1 /* GMT+12.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = "GMT+12.ics"; sourceTree = "<group>"; };
-		66FA9F0A155B16B600B6FAC1 /* GMT+2.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = "GMT+2.ics"; sourceTree = "<group>"; };
-		66FA9F0B155B16B600B6FAC1 /* GMT+3.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = "GMT+3.ics"; sourceTree = "<group>"; };
-		66FA9F0C155B16B600B6FAC1 /* GMT+4.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = "GMT+4.ics"; sourceTree = "<group>"; };
-		66FA9F0D155B16B600B6FAC1 /* GMT+5.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = "GMT+5.ics"; sourceTree = "<group>"; };
-		66FA9F0E155B16B600B6FAC1 /* GMT+6.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = "GMT+6.ics"; sourceTree = "<group>"; };
-		66FA9F0F155B16B600B6FAC1 /* GMT+7.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = "GMT+7.ics"; sourceTree = "<group>"; };
-		66FA9F10155B16B600B6FAC1 /* GMT+8.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = "GMT+8.ics"; sourceTree = "<group>"; };
-		66FA9F11155B16B600B6FAC1 /* GMT+9.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = "GMT+9.ics"; sourceTree = "<group>"; };
-		66FA9F12155B16B600B6FAC1 /* GMT-0.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = "GMT-0.ics"; sourceTree = "<group>"; };
-		66FA9F13155B16B600B6FAC1 /* GMT-1.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = "GMT-1.ics"; sourceTree = "<group>"; };
-		66FA9F14155B16B600B6FAC1 /* GMT-10.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = "GMT-10.ics"; sourceTree = "<group>"; };
-		66FA9F15155B16B600B6FAC1 /* GMT-11.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = "GMT-11.ics"; sourceTree = "<group>"; };
-		66FA9F16155B16B600B6FAC1 /* GMT-12.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = "GMT-12.ics"; sourceTree = "<group>"; };
-		66FA9F17155B16B600B6FAC1 /* GMT-13.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = "GMT-13.ics"; sourceTree = "<group>"; };
-		66FA9F18155B16B600B6FAC1 /* GMT-14.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = "GMT-14.ics"; sourceTree = "<group>"; };
-		66FA9F19155B16B600B6FAC1 /* GMT-2.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = "GMT-2.ics"; sourceTree = "<group>"; };
-		66FA9F1A155B16B600B6FAC1 /* GMT-3.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = "GMT-3.ics"; sourceTree = "<group>"; };
-		66FA9F1B155B16B600B6FAC1 /* GMT-4.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = "GMT-4.ics"; sourceTree = "<group>"; };
-		66FA9F1C155B16B600B6FAC1 /* GMT-5.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = "GMT-5.ics"; sourceTree = "<group>"; };
-		66FA9F1D155B16B600B6FAC1 /* GMT-6.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = "GMT-6.ics"; sourceTree = "<group>"; };
-		66FA9F1E155B16B600B6FAC1 /* GMT-7.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = "GMT-7.ics"; sourceTree = "<group>"; };
-		66FA9F1F155B16B600B6FAC1 /* GMT-8.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = "GMT-8.ics"; sourceTree = "<group>"; };
-		66FA9F20155B16B600B6FAC1 /* GMT-9.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = "GMT-9.ics"; sourceTree = "<group>"; };
-		66FA9F21155B16B600B6FAC1 /* GMT.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = GMT.ics; sourceTree = "<group>"; };
-		66FA9F22155B16B600B6FAC1 /* GMT0.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = GMT0.ics; sourceTree = "<group>"; };
-		66FA9F23155B16B600B6FAC1 /* Greenwich.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Greenwich.ics; sourceTree = "<group>"; };
-		66FA9F24155B16B600B6FAC1 /* UCT.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = UCT.ics; sourceTree = "<group>"; };
-		66FA9F25155B16B600B6FAC1 /* Universal.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Universal.ics; sourceTree = "<group>"; };
-		66FA9F26155B16B600B6FAC1 /* UTC.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = UTC.ics; sourceTree = "<group>"; };
-		66FA9F27155B16B600B6FAC1 /* Zulu.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Zulu.ics; sourceTree = "<group>"; };
-		66FA9F29155B16B600B6FAC1 /* Amsterdam.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Amsterdam.ics; sourceTree = "<group>"; };
-		66FA9F2A155B16B600B6FAC1 /* Andorra.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Andorra.ics; sourceTree = "<group>"; };
-		66FA9F2B155B16B600B6FAC1 /* Athens.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Athens.ics; sourceTree = "<group>"; };
-		66FA9F2C155B16B600B6FAC1 /* Belfast.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Belfast.ics; sourceTree = "<group>"; };
-		66FA9F2D155B16B600B6FAC1 /* Belgrade.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Belgrade.ics; sourceTree = "<group>"; };
-		66FA9F2E155B16B600B6FAC1 /* Berlin.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Berlin.ics; sourceTree = "<group>"; };
-		66FA9F2F155B16B600B6FAC1 /* Bratislava.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Bratislava.ics; sourceTree = "<group>"; };
-		66FA9F30155B16B600B6FAC1 /* Brussels.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Brussels.ics; sourceTree = "<group>"; };
-		66FA9F31155B16B600B6FAC1 /* Bucharest.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Bucharest.ics; sourceTree = "<group>"; };
-		66FA9F32155B16B600B6FAC1 /* Budapest.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Budapest.ics; sourceTree = "<group>"; };
-		66FA9F33155B16B600B6FAC1 /* Chisinau.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Chisinau.ics; sourceTree = "<group>"; };
-		66FA9F34155B16B600B6FAC1 /* Copenhagen.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Copenhagen.ics; sourceTree = "<group>"; };
-		66FA9F35155B16B600B6FAC1 /* Dublin.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Dublin.ics; sourceTree = "<group>"; };
-		66FA9F36155B16B600B6FAC1 /* Gibraltar.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Gibraltar.ics; sourceTree = "<group>"; };
-		66FA9F37155B16B600B6FAC1 /* Guernsey.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Guernsey.ics; sourceTree = "<group>"; };
-		66FA9F38155B16B600B6FAC1 /* Helsinki.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Helsinki.ics; sourceTree = "<group>"; };
-		66FA9F39155B16B600B6FAC1 /* Isle_of_Man.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Isle_of_Man.ics; sourceTree = "<group>"; };
-		66FA9F3A155B16B600B6FAC1 /* Istanbul.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Istanbul.ics; sourceTree = "<group>"; };
-		66FA9F3B155B16B600B6FAC1 /* Jersey.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Jersey.ics; sourceTree = "<group>"; };
-		66FA9F3C155B16B600B6FAC1 /* Kaliningrad.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Kaliningrad.ics; sourceTree = "<group>"; };
-		66FA9F3D155B16B600B6FAC1 /* Kiev.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Kiev.ics; sourceTree = "<group>"; };
-		66FA9F3E155B16B600B6FAC1 /* Lisbon.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Lisbon.ics; sourceTree = "<group>"; };
-		66FA9F3F155B16B600B6FAC1 /* Ljubljana.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Ljubljana.ics; sourceTree = "<group>"; };
-		66FA9F40155B16B600B6FAC1 /* London.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = London.ics; sourceTree = "<group>"; };
-		66FA9F41155B16B600B6FAC1 /* Luxembourg.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Luxembourg.ics; sourceTree = "<group>"; };
-		66FA9F42155B16B600B6FAC1 /* Madrid.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Madrid.ics; sourceTree = "<group>"; };
-		66FA9F43155B16B600B6FAC1 /* Malta.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Malta.ics; sourceTree = "<group>"; };
-		66FA9F44155B16B600B6FAC1 /* Mariehamn.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Mariehamn.ics; sourceTree = "<group>"; };
-		66FA9F45155B16B600B6FAC1 /* Minsk.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Minsk.ics; sourceTree = "<group>"; };
-		66FA9F46155B16B600B6FAC1 /* Monaco.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Monaco.ics; sourceTree = "<group>"; };
-		66FA9F47155B16B600B6FAC1 /* Moscow.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Moscow.ics; sourceTree = "<group>"; };
-		66FA9F48155B16B600B6FAC1 /* Nicosia.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Nicosia.ics; sourceTree = "<group>"; };
-		66FA9F49155B16B600B6FAC1 /* Oslo.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Oslo.ics; sourceTree = "<group>"; };
-		66FA9F4A155B16B600B6FAC1 /* Paris.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Paris.ics; sourceTree = "<group>"; };
-		66FA9F4B155B16B600B6FAC1 /* Podgorica.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Podgorica.ics; sourceTree = "<group>"; };
-		66FA9F4C155B16B600B6FAC1 /* Prague.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Prague.ics; sourceTree = "<group>"; };
-		66FA9F4D155B16B600B6FAC1 /* Riga.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Riga.ics; sourceTree = "<group>"; };
-		66FA9F4E155B16B600B6FAC1 /* Rome.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Rome.ics; sourceTree = "<group>"; };
-		66FA9F4F155B16B600B6FAC1 /* Samara.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Samara.ics; sourceTree = "<group>"; };
-		66FA9F50155B16B600B6FAC1 /* San_Marino.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = San_Marino.ics; sourceTree = "<group>"; };
-		66FA9F51155B16B600B6FAC1 /* Sarajevo.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Sarajevo.ics; sourceTree = "<group>"; };
-		66FA9F52155B16B600B6FAC1 /* Simferopol.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Simferopol.ics; sourceTree = "<group>"; };
-		66FA9F53155B16B600B6FAC1 /* Skopje.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Skopje.ics; sourceTree = "<group>"; };
-		66FA9F54155B16B600B6FAC1 /* Sofia.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Sofia.ics; sourceTree = "<group>"; };
-		66FA9F55155B16B600B6FAC1 /* Stockholm.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Stockholm.ics; sourceTree = "<group>"; };
-		66FA9F56155B16B600B6FAC1 /* Tallinn.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Tallinn.ics; sourceTree = "<group>"; };
-		66FA9F57155B16B600B6FAC1 /* Tirane.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Tirane.ics; sourceTree = "<group>"; };
-		66FA9F58155B16B600B6FAC1 /* Tiraspol.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Tiraspol.ics; sourceTree = "<group>"; };
-		66FA9F59155B16B600B6FAC1 /* Uzhgorod.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Uzhgorod.ics; sourceTree = "<group>"; };
-		66FA9F5A155B16B600B6FAC1 /* Vaduz.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Vaduz.ics; sourceTree = "<group>"; };
-		66FA9F5B155B16B600B6FAC1 /* Vatican.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Vatican.ics; sourceTree = "<group>"; };
-		66FA9F5C155B16B600B6FAC1 /* Vienna.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Vienna.ics; sourceTree = "<group>"; };
-		66FA9F5D155B16B600B6FAC1 /* Vilnius.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Vilnius.ics; sourceTree = "<group>"; };
-		66FA9F5E155B16B600B6FAC1 /* Volgograd.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Volgograd.ics; sourceTree = "<group>"; };
-		66FA9F5F155B16B600B6FAC1 /* Warsaw.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Warsaw.ics; sourceTree = "<group>"; };
-		66FA9F60155B16B600B6FAC1 /* Zagreb.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Zagreb.ics; sourceTree = "<group>"; };
-		66FA9F61155B16B600B6FAC1 /* Zaporozhye.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Zaporozhye.ics; sourceTree = "<group>"; };
-		66FA9F62155B16B600B6FAC1 /* Zurich.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Zurich.ics; sourceTree = "<group>"; };
-		66FA9F63155B16B600B6FAC1 /* GB-Eire.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = "GB-Eire.ics"; sourceTree = "<group>"; };
-		66FA9F64155B16B600B6FAC1 /* GB.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = GB.ics; sourceTree = "<group>"; };
-		66FA9F65155B16B600B6FAC1 /* GMT+0.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = "GMT+0.ics"; sourceTree = "<group>"; };
-		66FA9F66155B16B600B6FAC1 /* GMT-0.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = "GMT-0.ics"; sourceTree = "<group>"; };
-		66FA9F67155B16B600B6FAC1 /* GMT.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = GMT.ics; sourceTree = "<group>"; };
-		66FA9F68155B16B600B6FAC1 /* GMT0.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = GMT0.ics; sourceTree = "<group>"; };
-		66FA9F69155B16B600B6FAC1 /* Greenwich.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Greenwich.ics; sourceTree = "<group>"; };
-		66FA9F6A155B16B600B6FAC1 /* Hongkong.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Hongkong.ics; sourceTree = "<group>"; };
-		66FA9F6B155B16B600B6FAC1 /* HST.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = HST.ics; sourceTree = "<group>"; };
-		66FA9F6C155B16B600B6FAC1 /* Iceland.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Iceland.ics; sourceTree = "<group>"; };
-		66FA9F6E155B16B600B6FAC1 /* Antananarivo.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Antananarivo.ics; sourceTree = "<group>"; };
-		66FA9F6F155B16B600B6FAC1 /* Chagos.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Chagos.ics; sourceTree = "<group>"; };
-		66FA9F70155B16B600B6FAC1 /* Christmas.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Christmas.ics; sourceTree = "<group>"; };
-		66FA9F71155B16B600B6FAC1 /* Cocos.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Cocos.ics; sourceTree = "<group>"; };
-		66FA9F72155B16B600B6FAC1 /* Comoro.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Comoro.ics; sourceTree = "<group>"; };
-		66FA9F73155B16B600B6FAC1 /* Kerguelen.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Kerguelen.ics; sourceTree = "<group>"; };
-		66FA9F74155B16B600B6FAC1 /* Mahe.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Mahe.ics; sourceTree = "<group>"; };
-		66FA9F75155B16B600B6FAC1 /* Maldives.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Maldives.ics; sourceTree = "<group>"; };
-		66FA9F76155B16B600B6FAC1 /* Mauritius.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Mauritius.ics; sourceTree = "<group>"; };
-		66FA9F77155B16B600B6FAC1 /* Mayotte.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Mayotte.ics; sourceTree = "<group>"; };
-		66FA9F78155B16B600B6FAC1 /* Reunion.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Reunion.ics; sourceTree = "<group>"; };
-		66FA9F79155B16B600B6FAC1 /* Iran.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Iran.ics; sourceTree = "<group>"; };
-		66FA9F7A155B16B600B6FAC1 /* Israel.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Israel.ics; sourceTree = "<group>"; };
-		66FA9F7B155B16B600B6FAC1 /* Jamaica.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Jamaica.ics; sourceTree = "<group>"; };
-		66FA9F7C155B16B600B6FAC1 /* Japan.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Japan.ics; sourceTree = "<group>"; };
-		66FA9F7D155B16B600B6FAC1 /* Kwajalein.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Kwajalein.ics; sourceTree = "<group>"; };
-		66FA9F7E155B16B600B6FAC1 /* Libya.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Libya.ics; sourceTree = "<group>"; };
-		66FA9F7F155B16B600B6FAC1 /* links.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = links.txt; sourceTree = "<group>"; };
-		66FA9F80155B16B600B6FAC1 /* MET.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = MET.ics; sourceTree = "<group>"; };
-		66FA9F82155B16B600B6FAC1 /* BajaNorte.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = BajaNorte.ics; sourceTree = "<group>"; };
-		66FA9F83155B16B600B6FAC1 /* BajaSur.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = BajaSur.ics; sourceTree = "<group>"; };
-		66FA9F84155B16B600B6FAC1 /* General.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = General.ics; sourceTree = "<group>"; };
-		66FA9F85155B16B600B6FAC1 /* MST.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = MST.ics; sourceTree = "<group>"; };
-		66FA9F86155B16B600B6FAC1 /* MST7MDT.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = MST7MDT.ics; sourceTree = "<group>"; };
-		66FA9F87155B16B600B6FAC1 /* Navajo.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Navajo.ics; sourceTree = "<group>"; };
-		66FA9F88155B16B600B6FAC1 /* NZ-CHAT.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = "NZ-CHAT.ics"; sourceTree = "<group>"; };
-		66FA9F89155B16B600B6FAC1 /* NZ.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = NZ.ics; sourceTree = "<group>"; };
-		66FA9F8B155B16B600B6FAC1 /* Apia.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Apia.ics; sourceTree = "<group>"; };
-		66FA9F8C155B16B600B6FAC1 /* Auckland.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Auckland.ics; sourceTree = "<group>"; };
-		66FA9F8D155B16B600B6FAC1 /* Chatham.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Chatham.ics; sourceTree = "<group>"; };
-		66FA9F8E155B16B600B6FAC1 /* Chuuk.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Chuuk.ics; sourceTree = "<group>"; };
-		66FA9F8F155B16B600B6FAC1 /* Easter.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Easter.ics; sourceTree = "<group>"; };
-		66FA9F90155B16B600B6FAC1 /* Efate.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Efate.ics; sourceTree = "<group>"; };
-		66FA9F91155B16B600B6FAC1 /* Enderbury.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Enderbury.ics; sourceTree = "<group>"; };
-		66FA9F92155B16B600B6FAC1 /* Fakaofo.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Fakaofo.ics; sourceTree = "<group>"; };
-		66FA9F93155B16B600B6FAC1 /* Fiji.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Fiji.ics; sourceTree = "<group>"; };
-		66FA9F94155B16B600B6FAC1 /* Funafuti.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Funafuti.ics; sourceTree = "<group>"; };
-		66FA9F95155B16B600B6FAC1 /* Galapagos.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Galapagos.ics; sourceTree = "<group>"; };
-		66FA9F96155B16B600B6FAC1 /* Gambier.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Gambier.ics; sourceTree = "<group>"; };
-		66FA9F97155B16B600B6FAC1 /* Guadalcanal.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Guadalcanal.ics; sourceTree = "<group>"; };
-		66FA9F98155B16B600B6FAC1 /* Guam.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Guam.ics; sourceTree = "<group>"; };
-		66FA9F99155B16B600B6FAC1 /* Honolulu.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Honolulu.ics; sourceTree = "<group>"; };
-		66FA9F9A155B16B600B6FAC1 /* Johnston.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Johnston.ics; sourceTree = "<group>"; };
-		66FA9F9B155B16B600B6FAC1 /* Kiritimati.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Kiritimati.ics; sourceTree = "<group>"; };
-		66FA9F9C155B16B600B6FAC1 /* Kosrae.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Kosrae.ics; sourceTree = "<group>"; };
-		66FA9F9D155B16B600B6FAC1 /* Kwajalein.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Kwajalein.ics; sourceTree = "<group>"; };
-		66FA9F9E155B16B600B6FAC1 /* Majuro.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Majuro.ics; sourceTree = "<group>"; };
-		66FA9F9F155B16B600B6FAC1 /* Marquesas.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Marquesas.ics; sourceTree = "<group>"; };
-		66FA9FA0155B16B600B6FAC1 /* Midway.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Midway.ics; sourceTree = "<group>"; };
-		66FA9FA1155B16B600B6FAC1 /* Nauru.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Nauru.ics; sourceTree = "<group>"; };
-		66FA9FA2155B16B600B6FAC1 /* Niue.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Niue.ics; sourceTree = "<group>"; };
-		66FA9FA3155B16B600B6FAC1 /* Norfolk.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Norfolk.ics; sourceTree = "<group>"; };
-		66FA9FA4155B16B600B6FAC1 /* Noumea.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Noumea.ics; sourceTree = "<group>"; };
-		66FA9FA5155B16B600B6FAC1 /* Pago_Pago.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Pago_Pago.ics; sourceTree = "<group>"; };
-		66FA9FA6155B16B600B6FAC1 /* Palau.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Palau.ics; sourceTree = "<group>"; };
-		66FA9FA7155B16B600B6FAC1 /* Pitcairn.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Pitcairn.ics; sourceTree = "<group>"; };
-		66FA9FA8155B16B600B6FAC1 /* Pohnpei.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Pohnpei.ics; sourceTree = "<group>"; };
-		66FA9FA9155B16B600B6FAC1 /* Ponape.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Ponape.ics; sourceTree = "<group>"; };
-		66FA9FAA155B16B600B6FAC1 /* Port_Moresby.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Port_Moresby.ics; sourceTree = "<group>"; };
-		66FA9FAB155B16B600B6FAC1 /* Rarotonga.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Rarotonga.ics; sourceTree = "<group>"; };
-		66FA9FAC155B16B600B6FAC1 /* Saipan.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Saipan.ics; sourceTree = "<group>"; };
-		66FA9FAD155B16B600B6FAC1 /* Samoa.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Samoa.ics; sourceTree = "<group>"; };
-		66FA9FAE155B16B600B6FAC1 /* Tahiti.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Tahiti.ics; sourceTree = "<group>"; };
-		66FA9FAF155B16B600B6FAC1 /* Tarawa.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Tarawa.ics; sourceTree = "<group>"; };
-		66FA9FB0155B16B600B6FAC1 /* Tongatapu.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Tongatapu.ics; sourceTree = "<group>"; };
-		66FA9FB1155B16B600B6FAC1 /* Truk.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Truk.ics; sourceTree = "<group>"; };
-		66FA9FB2155B16B600B6FAC1 /* Wake.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Wake.ics; sourceTree = "<group>"; };
-		66FA9FB3155B16B600B6FAC1 /* Wallis.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Wallis.ics; sourceTree = "<group>"; };
-		66FA9FB4155B16B600B6FAC1 /* Yap.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Yap.ics; sourceTree = "<group>"; };
-		66FA9FB5155B16B600B6FAC1 /* Poland.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Poland.ics; sourceTree = "<group>"; };
-		66FA9FB6155B16B600B6FAC1 /* Portugal.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Portugal.ics; sourceTree = "<group>"; };
-		66FA9FB7155B16B600B6FAC1 /* PRC.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = PRC.ics; sourceTree = "<group>"; };
-		66FA9FB8155B16B600B6FAC1 /* PST8PDT.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = PST8PDT.ics; sourceTree = "<group>"; };
-		66FA9FB9155B16B600B6FAC1 /* ROC.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = ROC.ics; sourceTree = "<group>"; };
-		66FA9FBA155B16B600B6FAC1 /* ROK.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = ROK.ics; sourceTree = "<group>"; };
-		66FA9FBB155B16B600B6FAC1 /* Singapore.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Singapore.ics; sourceTree = "<group>"; };
-		66FA9FBC155B16B600B6FAC1 /* timezones.xml */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = timezones.xml; sourceTree = "<group>"; };
-		66FA9FBD155B16B600B6FAC1 /* Turkey.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Turkey.ics; sourceTree = "<group>"; };
-		66FA9FBE155B16B600B6FAC1 /* UCT.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = UCT.ics; sourceTree = "<group>"; };
-		66FA9FBF155B16B600B6FAC1 /* Universal.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Universal.ics; sourceTree = "<group>"; };
-		66FA9FC1155B16B600B6FAC1 /* Alaska.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Alaska.ics; sourceTree = "<group>"; };
-		66FA9FC2155B16B600B6FAC1 /* Aleutian.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Aleutian.ics; sourceTree = "<group>"; };
-		66FA9FC3155B16B600B6FAC1 /* Arizona.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Arizona.ics; sourceTree = "<group>"; };
-		66FA9FC4155B16B600B6FAC1 /* Central.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Central.ics; sourceTree = "<group>"; };
-		66FA9FC5155B16B600B6FAC1 /* East-Indiana.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = "East-Indiana.ics"; sourceTree = "<group>"; };
-		66FA9FC6155B16B600B6FAC1 /* Eastern.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Eastern.ics; sourceTree = "<group>"; };
-		66FA9FC7155B16B600B6FAC1 /* Hawaii.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Hawaii.ics; sourceTree = "<group>"; };
-		66FA9FC8155B16B600B6FAC1 /* Indiana-Starke.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = "Indiana-Starke.ics"; sourceTree = "<group>"; };
-		66FA9FC9155B16B600B6FAC1 /* Michigan.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Michigan.ics; sourceTree = "<group>"; };
-		66FA9FCA155B16B600B6FAC1 /* Mountain.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Mountain.ics; sourceTree = "<group>"; };
-		66FA9FCB155B16B600B6FAC1 /* Pacific.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Pacific.ics; sourceTree = "<group>"; };
-		66FA9FCC155B16B600B6FAC1 /* Samoa.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Samoa.ics; sourceTree = "<group>"; };
-		66FA9FCD155B16B600B6FAC1 /* UTC.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = UTC.ics; sourceTree = "<group>"; };
-		66FA9FCE155B16B600B6FAC1 /* version.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = version.txt; sourceTree = "<group>"; };
-		66FA9FCF155B16B600B6FAC1 /* W-SU.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = "W-SU.ics"; sourceTree = "<group>"; };
-		66FA9FD0155B16B600B6FAC1 /* WET.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = WET.ics; sourceTree = "<group>"; };
-		66FA9FD1155B16B600B6FAC1 /* Zulu.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = Zulu.ics; sourceTree = "<group>"; };
-		66FA9FD3155B16B600B6FAC1 /* __init__.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = __init__.py; sourceTree = "<group>"; };
-		66FA9FD5155B16B600B6FAC1 /* __init__.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = __init__.py; sourceTree = "<group>"; };
-		66FA9FD7155B16B600B6FAC1 /* __init__.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = __init__.py; sourceTree = "<group>"; };
-		66FA9FD8155B16B600B6FAC1 /* dbapiclient.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = dbapiclient.py; sourceTree = "<group>"; };
-		66FA9FD9155B16B600B6FAC1 /* file.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = file.py; sourceTree = "<group>"; };
-		66FA9FDA155B16B600B6FAC1 /* subpostgres.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = subpostgres.py; sourceTree = "<group>"; };
-		66FA9FDC155B16B600B6FAC1 /* __init__.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = __init__.py; sourceTree = "<group>"; };
-		66FA9FDD155B16B600B6FAC1 /* test_subpostgres.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_subpostgres.py; sourceTree = "<group>"; };
-		66FA9FDE155B16B600B6FAC1 /* util.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = util.py; sourceTree = "<group>"; };
-		66FA9FE0155B16B600B6FAC1 /* __init__.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = __init__.py; sourceTree = "<group>"; };
-		66FA9FE1155B16B600B6FAC1 /* appledouble_xattr.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = appledouble_xattr.py; sourceTree = "<group>"; };
-		66FA9FE2155B16B600B6FAC1 /* base.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = base.py; sourceTree = "<group>"; };
-		66FA9FE3155B16B600B6FAC1 /* none.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = none.py; sourceTree = "<group>"; };
-		66FA9FE4155B16B600B6FAC1 /* sql.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = sql.py; sourceTree = "<group>"; };
-		66FA9FE6155B16B600B6FAC1 /* __init__.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = __init__.py; sourceTree = "<group>"; };
-		66FA9FE7155B16B600B6FAC1 /* base.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = base.py; sourceTree = "<group>"; };
-		66FA9FE8155B16B600B6FAC1 /* test_appledouble.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_appledouble.py; sourceTree = "<group>"; };
-		66FA9FE9155B16B600B6FAC1 /* test_base.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_base.py; sourceTree = "<group>"; };
-		66FA9FEA155B16B600B6FAC1 /* test_none.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_none.py; sourceTree = "<group>"; };
-		66FA9FEB155B16B600B6FAC1 /* test_sql.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_sql.py; sourceTree = "<group>"; };
-		66FA9FEC155B16B600B6FAC1 /* test_xattr.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_xattr.py; sourceTree = "<group>"; };
-		66FA9FED155B16B600B6FAC1 /* xattr.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = xattr.py; sourceTree = "<group>"; };
-		66FA9FEF155B16B600B6FAC1 /* __init__.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = __init__.py; sourceTree = "<group>"; };
-		66FA9FF1155B16B600B6FAC1 /* __init__.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = __init__.py; sourceTree = "<group>"; };
-		66FA9FF2155B16B600B6FAC1 /* file.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = file.py; sourceTree = "<group>"; };
-		66FA9FF3155B16B600B6FAC1 /* index_file.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = index_file.py; sourceTree = "<group>"; };
-		66FA9FF4155B16B600B6FAC1 /* scheduling.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = scheduling.py; sourceTree = "<group>"; };
-		66FA9FF5155B16B600B6FAC1 /* sql.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = sql.py; sourceTree = "<group>"; };
-		66FA9FF7155B16B600B6FAC1 /* __init__.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = __init__.py; sourceTree = "<group>"; };
-		66FA9FFD155B16B600B6FAC1 /* 1.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = 1.ics; sourceTree = "<group>"; };
-		66FA9FFE155B16B600B6FAC1 /* 2.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = 2.ics; sourceTree = "<group>"; };
-		66FA9FFF155B16B600B6FAC1 /* 3.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = 3.ics; sourceTree = "<group>"; };
-		66FAA000155B16B600B6FAC1 /* 4.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = 4.ics; sourceTree = "<group>"; };
-		66FAA002155B16B600B6FAC1 /* 24204e8682b99527cbda64d7423acda7.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = 24204e8682b99527cbda64d7423acda7.ics; sourceTree = "<group>"; };
-		66FAA003155B16B600B6FAC1 /* 61038c41bd02ae5daf9f7fe9d54199fd.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = 61038c41bd02ae5daf9f7fe9d54199fd.ics; sourceTree = "<group>"; };
-		66FAA004155B16B600B6FAC1 /* 84be58ced1f1bb34057e1bd7e602c9c8.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = 84be58ced1f1bb34057e1bd7e602c9c8.ics; sourceTree = "<group>"; };
-		66FAA005155B16B600B6FAC1 /* acc1015b7dc300c1b5665f6833960994.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = acc1015b7dc300c1b5665f6833960994.ics; sourceTree = "<group>"; };
-		66FAA006155B16B600B6FAC1 /* b0d5785f275c064117ffd1fc20f4ed40.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = b0d5785f275c064117ffd1fc20f4ed40.ics; sourceTree = "<group>"; };
-		66FAA007155B16B600B6FAC1 /* b495c5dd5aa53392078eb43b1f906a80.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = b495c5dd5aa53392078eb43b1f906a80.ics; sourceTree = "<group>"; };
-		66FAA008155B16B600B6FAC1 /* b88dd50941e4a31520ee396fd7894c96.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = b88dd50941e4a31520ee396fd7894c96.ics; sourceTree = "<group>"; };
-		66FAA00C155B16B600B6FAC1 /* 1.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = 1.ics; sourceTree = "<group>"; };
-		66FAA00D155B16B600B6FAC1 /* 2.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = 2.ics; sourceTree = "<group>"; };
-		66FAA00E155B16B600B6FAC1 /* 3.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = 3.ics; sourceTree = "<group>"; };
-		66FAA011155B16B600B6FAC1 /* test.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = test.txt; sourceTree = "<group>"; };
-		66FAA013155B16B600B6FAC1 /* test.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = test.txt; sourceTree = "<group>"; };
-		66FAA016155B16B600B6FAC1 /* 1.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = 1.ics; sourceTree = "<group>"; };
-		66FAA017155B16B600B6FAC1 /* 2.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = 2.ics; sourceTree = "<group>"; };
-		66FAA018155B16B600B6FAC1 /* 3.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = 3.ics; sourceTree = "<group>"; };
-		66FAA01A155B16B600B6FAC1 /* 1.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = 1.ics; sourceTree = "<group>"; };
-		66FAA01B155B16B600B6FAC1 /* 2.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = 2.ics; sourceTree = "<group>"; };
-		66FAA01C155B16B600B6FAC1 /* 3.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = 3.ics; sourceTree = "<group>"; };
-		66FAA01F155B16B600B6FAC1 /* 1.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = 1.ics; sourceTree = "<group>"; };
-		66FAA020155B16B600B6FAC1 /* 2.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = 2.ics; sourceTree = "<group>"; };
-		66FAA021155B16B600B6FAC1 /* 3.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = 3.ics; sourceTree = "<group>"; };
-		66FAA024155B16B600B6FAC1 /* 1.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = 1.ics; sourceTree = "<group>"; };
-		66FAA025155B16B600B6FAC1 /* 2.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = 2.ics; sourceTree = "<group>"; };
-		66FAA026155B16B600B6FAC1 /* 3.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = 3.ics; sourceTree = "<group>"; };
-		66FAA028155B16B600B6FAC1 /* 1.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = 1.ics; sourceTree = "<group>"; };
-		66FAA029155B16B600B6FAC1 /* 2.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = 2.ics; sourceTree = "<group>"; };
-		66FAA02A155B16B600B6FAC1 /* 3.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = 3.ics; sourceTree = "<group>"; };
-		66FAA02B155B16B600B6FAC1 /* 4.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = 4.ics; sourceTree = "<group>"; };
-		66FAA02C155B16B600B6FAC1 /* 5.ics */ = {isa = PBXFileReference; lastKnownFileType = text; path = 5.ics; sourceTree = "<group>"; };
-		66FAA02F155B16B600B6FAC1 /* common.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = common.py; sourceTree = "<group>"; };
-		66FAA030155B16B600B6FAC1 /* test_file.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_file.py; sourceTree = "<group>"; };
-		66FAA031155B16B600B6FAC1 /* test_index_file.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_index_file.py; sourceTree = "<group>"; };
-		66FAA032155B16B600B6FAC1 /* test_scheduling.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_scheduling.py; sourceTree = "<group>"; };
-		66FAA033155B16B600B6FAC1 /* test_sql.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_sql.py; sourceTree = "<group>"; };
-		66FAA034155B16B600B6FAC1 /* test_util.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_util.py; sourceTree = "<group>"; };
-		66FAA035155B16B600B6FAC1 /* util.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = util.py; sourceTree = "<group>"; };
-		66FAA036155B16B600B6FAC1 /* icalendarstore.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = icalendarstore.py; sourceTree = "<group>"; };
-		66FAA037155B16B600B6FAC1 /* resource.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = resource.py; sourceTree = "<group>"; };
-		66FAA039155B16B600B6FAC1 /* __init__.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = __init__.py; sourceTree = "<group>"; };
-		66FAA03B155B16B600B6FAC1 /* __init__.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = __init__.py; sourceTree = "<group>"; };
-		66FAA03C155B16B600B6FAC1 /* file.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = file.py; sourceTree = "<group>"; };
-		66FAA03D155B16B600B6FAC1 /* index_file.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = index_file.py; sourceTree = "<group>"; };
-		66FAA03E155B16B600B6FAC1 /* sql.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = sql.py; sourceTree = "<group>"; };
-		66FAA040155B16B600B6FAC1 /* __init__.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = __init__.py; sourceTree = "<group>"; };
-		66FAA046155B16B600B6FAC1 /* 1.vcf */ = {isa = PBXFileReference; lastKnownFileType = text; path = 1.vcf; sourceTree = "<group>"; };
-		66FAA047155B16B600B6FAC1 /* 2.vcf */ = {isa = PBXFileReference; lastKnownFileType = text; path = 2.vcf; sourceTree = "<group>"; };
-		66FAA048155B16B600B6FAC1 /* 3.vcf */ = {isa = PBXFileReference; lastKnownFileType = text; path = 3.vcf; sourceTree = "<group>"; };
-		66FAA04A155B16B600B6FAC1 /* 3765A955-1B96-41EA-994D-335192BEDCCD.vcf */ = {isa = PBXFileReference; lastKnownFileType = text; path = "3765A955-1B96-41EA-994D-335192BEDCCD.vcf"; sourceTree = "<group>"; };
-		66FAA04B155B16B600B6FAC1 /* 44745975-AE6D-4FB0-80A6-A298427E047A.vcf */ = {isa = PBXFileReference; lastKnownFileType = text; path = "44745975-AE6D-4FB0-80A6-A298427E047A.vcf"; sourceTree = "<group>"; };
-		66FAA04C155B16B600B6FAC1 /* 44EE78BF-8814-4471-899C-92280CEFB098.vcf */ = {isa = PBXFileReference; lastKnownFileType = text; path = "44EE78BF-8814-4471-899C-92280CEFB098.vcf"; sourceTree = "<group>"; };
-		66FAA04D155B16B600B6FAC1 /* 8424B7F0-C878-4722-B522-EBB07CF48AD7.vcf */ = {isa = PBXFileReference; lastKnownFileType = text; path = "8424B7F0-C878-4722-B522-EBB07CF48AD7.vcf"; sourceTree = "<group>"; };
-		66FAA04E155B16B600B6FAC1 /* 934731C6-1C95-4C40-BE1F-FA4215B2307B.vcf */ = {isa = PBXFileReference; lastKnownFileType = text; path = "934731C6-1C95-4C40-BE1F-FA4215B2307B.vcf"; sourceTree = "<group>"; };
-		66FAA04F155B16B600B6FAC1 /* AFBB77B8-0438-4825-A1DB-A75D76B6C3A8.vcf */ = {isa = PBXFileReference; lastKnownFileType = text; path = "AFBB77B8-0438-4825-A1DB-A75D76B6C3A8.vcf"; sourceTree = "<group>"; };
-		66FAA050155B16B600B6FAC1 /* ED7A5AEC-AB19-4CE0-AD6A-2923A3E5C4E1.vcf */ = {isa = PBXFileReference; lastKnownFileType = text; path = "ED7A5AEC-AB19-4CE0-AD6A-2923A3E5C4E1.vcf"; sourceTree = "<group>"; };
-		66FAA051155B16B600B6FAC1 /* ED7A5AEC-AB19-4CE0-AD6A-2923A3E5C4E2.vcf */ = {isa = PBXFileReference; lastKnownFileType = text; path = "ED7A5AEC-AB19-4CE0-AD6A-2923A3E5C4E2.vcf"; sourceTree = "<group>"; };
-		66FAA052155B16B600B6FAC1 /* F0A6918D-8E09-43FA-9684-226810B8A96F.vcf */ = {isa = PBXFileReference; lastKnownFileType = text; path = "F0A6918D-8E09-43FA-9684-226810B8A96F.vcf"; sourceTree = "<group>"; };
-		66FAA053155B16B600B6FAC1 /* FCBA0FA3-00B2-4C95-B4EC-4CCC4843F8B1.vcf */ = {isa = PBXFileReference; lastKnownFileType = text; path = "FCBA0FA3-00B2-4C95-B4EC-4CCC4843F8B1.vcf"; sourceTree = "<group>"; };
-		66FAA057155B16B600B6FAC1 /* 1.vcf */ = {isa = PBXFileReference; lastKnownFileType = text; path = 1.vcf; sourceTree = "<group>"; };
-		66FAA058155B16B600B6FAC1 /* 2.vcf */ = {isa = PBXFileReference; lastKnownFileType = text; path = 2.vcf; sourceTree = "<group>"; };
-		66FAA059155B16B600B6FAC1 /* common.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = common.py; sourceTree = "<group>"; };
-		66FAA05A155B16B600B6FAC1 /* test_file.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_file.py; sourceTree = "<group>"; };
-		66FAA05B155B16B600B6FAC1 /* test_index_file.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_index_file.py; sourceTree = "<group>"; };
-		66FAA05C155B16B600B6FAC1 /* test_sql.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_sql.py; sourceTree = "<group>"; };
-		66FAA05D155B16B600B6FAC1 /* util.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = util.py; sourceTree = "<group>"; };
-		66FAA05E155B16B600B6FAC1 /* iaddressbookstore.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = iaddressbookstore.py; sourceTree = "<group>"; };
-		66FAA05F155B16B600B6FAC1 /* resource.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = resource.py; sourceTree = "<group>"; };
-		66FAA061155B16B600B6FAC1 /* __init__.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = __init__.py; sourceTree = "<group>"; };
-		66FAA063155B16B600B6FAC1 /* __init__.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = __init__.py; sourceTree = "<group>"; };
-		66FAA064155B16B600B6FAC1 /* file.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = file.py; sourceTree = "<group>"; };
-		66FAA065155B16B600B6FAC1 /* sql.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = sql.py; sourceTree = "<group>"; };
-		66FAA066155B16B600B6FAC1 /* sql_legacy.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = sql_legacy.py; sourceTree = "<group>"; };
-		66FAA068155B16B600B6FAC1 /* current.sql */ = {isa = PBXFileReference; lastKnownFileType = text; path = current.sql; sourceTree = "<group>"; };
-		66FAA06A155B16B600B6FAC1 /* v3.sql */ = {isa = PBXFileReference; lastKnownFileType = text; path = v3.sql; sourceTree = "<group>"; };
-		66FAA06B155B16B600B6FAC1 /* v4.sql */ = {isa = PBXFileReference; lastKnownFileType = text; path = v4.sql; sourceTree = "<group>"; };
-		66FAA06C155B16B600B6FAC1 /* v5.sql */ = {isa = PBXFileReference; lastKnownFileType = text; path = v5.sql; sourceTree = "<group>"; };
-		66FAA06D155B16B600B6FAC1 /* v6.sql */ = {isa = PBXFileReference; lastKnownFileType = text; path = v6.sql; sourceTree = "<group>"; };
-		66FAA06E155B16B600B6FAC1 /* v7.sql */ = {isa = PBXFileReference; lastKnownFileType = text; path = v7.sql; sourceTree = "<group>"; };
-		66FAA071155B16B600B6FAC1 /* upgrade_from_3_to_4.sql */ = {isa = PBXFileReference; lastKnownFileType = text; path = upgrade_from_3_to_4.sql; sourceTree = "<group>"; };
-		66FAA072155B16B600B6FAC1 /* upgrade_from_4_to_5.sql */ = {isa = PBXFileReference; lastKnownFileType = text; path = upgrade_from_4_to_5.sql; sourceTree = "<group>"; };
-		66FAA073155B16B600B6FAC1 /* upgrade_from_5_to_6.sql */ = {isa = PBXFileReference; lastKnownFileType = text; path = upgrade_from_5_to_6.sql; sourceTree = "<group>"; };
-		66FAA074155B16B600B6FAC1 /* upgrade_from_6_to_7.sql */ = {isa = PBXFileReference; lastKnownFileType = text; path = upgrade_from_6_to_7.sql; sourceTree = "<group>"; };
-		66FAA075155B16B600B6FAC1 /* upgrade_from_7_to_8.sql */ = {isa = PBXFileReference; lastKnownFileType = text; path = upgrade_from_7_to_8.sql; sourceTree = "<group>"; };
-		66FAA077155B16B600B6FAC1 /* upgrade_from_3_to_4.sql */ = {isa = PBXFileReference; lastKnownFileType = text; path = upgrade_from_3_to_4.sql; sourceTree = "<group>"; };
-		66FAA078155B16B600B6FAC1 /* upgrade_from_4_to_5.sql */ = {isa = PBXFileReference; lastKnownFileType = text; path = upgrade_from_4_to_5.sql; sourceTree = "<group>"; };
-		66FAA079155B16B600B6FAC1 /* upgrade_from_5_to_6.sql */ = {isa = PBXFileReference; lastKnownFileType = text; path = upgrade_from_5_to_6.sql; sourceTree = "<group>"; };
-		66FAA07A155B16B600B6FAC1 /* upgrade_from_6_to_7.sql */ = {isa = PBXFileReference; lastKnownFileType = text; path = upgrade_from_6_to_7.sql; sourceTree = "<group>"; };
-		66FAA07B155B16B600B6FAC1 /* upgrade_from_7_to_8.sql */ = {isa = PBXFileReference; lastKnownFileType = text; path = upgrade_from_7_to_8.sql; sourceTree = "<group>"; };
-		66FAA07C155B16B600B6FAC1 /* upgrade_template.sql */ = {isa = PBXFileReference; lastKnownFileType = text; path = upgrade_template.sql; sourceTree = "<group>"; };
-		66FAA07D155B16B600B6FAC1 /* sql_tables.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = sql_tables.py; sourceTree = "<group>"; };
-		66FAA07F155B16B600B6FAC1 /* __init__.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = __init__.py; sourceTree = "<group>"; };
-		66FAA080155B16B600B6FAC1 /* test_sql.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_sql.py; sourceTree = "<group>"; };
-		66FAA081155B16B600B6FAC1 /* test_sql_tables.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_sql_tables.py; sourceTree = "<group>"; };
-		66FAA082155B16B600B6FAC1 /* util.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = util.py; sourceTree = "<group>"; };
-		66FAA084155B16B600B6FAC1 /* __init__.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = __init__.py; sourceTree = "<group>"; };
-		66FAA086155B16B600B6FAC1 /* __init__.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = __init__.py; sourceTree = "<group>"; };
-		66FAA087155B16B600B6FAC1 /* migrate.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = migrate.py; sourceTree = "<group>"; };
-		66FAA089155B16B600B6FAC1 /* __init__.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = __init__.py; sourceTree = "<group>"; };
-		66FAA08B155B16B600B6FAC1 /* __init__.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = __init__.py; sourceTree = "<group>"; };
-		66FAA08D155B16B600B6FAC1 /* current.sql */ = {isa = PBXFileReference; lastKnownFileType = text; path = current.sql; sourceTree = "<group>"; };
-		66FAA090155B16B600B6FAC1 /* upgrade_from_3_to_4.sql */ = {isa = PBXFileReference; lastKnownFileType = text; path = upgrade_from_3_to_4.sql; sourceTree = "<group>"; };
-		66FAA092155B16B600B6FAC1 /* current.sql */ = {isa = PBXFileReference; lastKnownFileType = text; path = current.sql; sourceTree = "<group>"; };
-		66FAA095155B16B600B6FAC1 /* upgrade_from_3_to_4.sql */ = {isa = PBXFileReference; lastKnownFileType = text; path = upgrade_from_3_to_4.sql; sourceTree = "<group>"; };
-		66FAA096155B16B600B6FAC1 /* upgrade_from_3_to_5.sql */ = {isa = PBXFileReference; lastKnownFileType = text; path = upgrade_from_3_to_5.sql; sourceTree = "<group>"; };
-		66FAA097155B16B600B6FAC1 /* upgrade_from_4_to_5.sql */ = {isa = PBXFileReference; lastKnownFileType = text; path = upgrade_from_4_to_5.sql; sourceTree = "<group>"; };
-		66FAA099155B16B600B6FAC1 /* current.sql */ = {isa = PBXFileReference; lastKnownFileType = text; path = current.sql; sourceTree = "<group>"; };
-		66FAA09C155B16B600B6FAC1 /* upgrade_from_3_to_4.sql */ = {isa = PBXFileReference; lastKnownFileType = text; path = upgrade_from_3_to_4.sql; sourceTree = "<group>"; };
-		66FAA09D155B16B600B6FAC1 /* upgrade_from_4_to_5.sql */ = {isa = PBXFileReference; lastKnownFileType = text; path = upgrade_from_4_to_5.sql; sourceTree = "<group>"; };
-		66FAA09E155B16B600B6FAC1 /* test_upgrade.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_upgrade.py; sourceTree = "<group>"; };
-		66FAA09F155B16B600B6FAC1 /* upgrade.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = upgrade.py; sourceTree = "<group>"; };
-		66FAA0A1155B16B600B6FAC1 /* __init__.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = __init__.py; sourceTree = "<group>"; };
-		66FAA0A2155B16B600B6FAC1 /* upgrade_from_1_to_2.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = upgrade_from_1_to_2.py; sourceTree = "<group>"; };
-		66FAA0A3155B16B600B6FAC1 /* util.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = util.py; sourceTree = "<group>"; };
-		66FAA0A5155B16B600B6FAC1 /* __init__.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = __init__.py; sourceTree = "<group>"; };
-		66FAA0A6155B16B600B6FAC1 /* test_migrate.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_migrate.py; sourceTree = "<group>"; };
-		66FAA0A7155B16B600B6FAC1 /* icommondatastore.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = icommondatastore.py; sourceTree = "<group>"; };
-		66FAA0A8155B16B600B6FAC1 /* inotifications.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = inotifications.py; sourceTree = "<group>"; };
-		66FAA0A9155B16B600B6FAC1 /* idav.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = idav.py; sourceTree = "<group>"; };
-		66FAA0AB155B16B600B6FAC1 /* __init__.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = __init__.py; sourceTree = "<group>"; };
-		66FAA0AC155B16B600B6FAC1 /* base.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = base.py; sourceTree = "<group>"; };
-		66FAA0AD155B16B600B6FAC1 /* draft_sync.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = draft_sync.py; sourceTree = "<group>"; };
-		66FAA0AE155B16B600B6FAC1 /* element.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = element.py; sourceTree = "<group>"; };
-		66FAA0AF155B16B600B6FAC1 /* extensions.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = extensions.py; sourceTree = "<group>"; };
-		66FAA0B0155B16B600B6FAC1 /* parser.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = parser.py; sourceTree = "<group>"; };
-		66FAA0B1155B16B600B6FAC1 /* parser_base.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = parser_base.py; sourceTree = "<group>"; };
-		66FAA0B2155B16B600B6FAC1 /* parser_sax.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = parser_sax.py; sourceTree = "<group>"; };
-		66FAA0B3155B16B600B6FAC1 /* rfc2518.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = rfc2518.py; sourceTree = "<group>"; };
-		66FAA0B4155B16B600B6FAC1 /* rfc3253.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = rfc3253.py; sourceTree = "<group>"; };
-		66FAA0B5155B16B600B6FAC1 /* rfc3744.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = rfc3744.py; sourceTree = "<group>"; };
-		66FAA0B6155B16B600B6FAC1 /* rfc4331.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = rfc4331.py; sourceTree = "<group>"; };
-		66FAA0B7155B16B600B6FAC1 /* rfc5397.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = rfc5397.py; sourceTree = "<group>"; };
-		66FAA0B8155B16B600B6FAC1 /* rfc5842.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = rfc5842.py; sourceTree = "<group>"; };
-		66FAA0B9155B16B600B6FAC1 /* rfc5995.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = rfc5995.py; sourceTree = "<group>"; };
-		66FAA0BB155B16B600B6FAC1 /* __init__.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = __init__.py; sourceTree = "<group>"; };
-		66FAA0BC155B16B600B6FAC1 /* test_base.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_base.py; sourceTree = "<group>"; };
-		66FAA0BD155B16B600B6FAC1 /* test_xml.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_xml.py; sourceTree = "<group>"; };
-		66FAA0BE155B16B600B6FAC1 /* test_xml_rfc3744.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = test_xml_rfc3744.py; sourceTree = "<group>"; };
-		66FAA0BF155B16B600B6FAC1 /* xmlext.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = xmlext.py; sourceTree = "<group>"; };
+		3519AFAB170E546B0054F087 /* CalendarServer */ = {isa = PBXFileReference; lastKnownFileType = folder; name = CalendarServer; path = ..; sourceTree = "<group>"; };
 /* End PBXFileReference section */
 
 /* Begin PBXGroup section */
-		35069C090922B94100389D48 = {
+		35E050F7170E534C00D4A7CA = {
 			isa = PBXGroup;
 			children = (
-				66FA9961155B16B500B6FAC1 /* benchmark */,
-				66FA9962155B16B500B6FAC1 /* benchreport */,
-				66FA9963155B16B500B6FAC1 /* bin */,
-				66FA9981155B16B500B6FAC1 /* calendarserver */,
-				66FA9A08155B16B500B6FAC1 /* conf */,
-				66FA9A26155B16B500B6FAC1 /* contrib */,
-				66FA9AD8155B16B500B6FAC1 /* doc */,
-				66FA9B24155B16B500B6FAC1 /* HACKING */,
-				66FA9B25155B16B500B6FAC1 /* lib-patches */,
-				66FA9B28155B16B500B6FAC1 /* LICENSE */,
-				66FA9B29155B16B500B6FAC1 /* locales */,
-				66FA9B38155B16B500B6FAC1 /* pyflakes */,
-				66FA9B39155B16B500B6FAC1 /* python */,
-				66FA9B3A155B16B500B6FAC1 /* README */,
-				66FA9B3B155B16B500B6FAC1 /* run */,
-				66FA9B3C155B16B500B6FAC1 /* setup.py */,
-				66FA9B3D155B16B500B6FAC1 /* sim */,
-				66FA9B3E155B16B500B6FAC1 /* support */,
-				66FA9B51155B16B500B6FAC1 /* build.sh */,
-				66FA9B52155B16B500B6FAC1 /* diffbranch */,
-				66FA9B53155B16B500B6FAC1 /* directorysetup.py */,
-				66FA9B54155B16B500B6FAC1 /* Makefile.Apple */,
-				66FA9B55155B16B500B6FAC1 /* mergebranch */,
-				66FA9B56155B16B500B6FAC1 /* patchapply */,
-				66FA9B57155B16B500B6FAC1 /* patchmaker */,
-				66FA9B58155B16B500B6FAC1 /* pull-up */,
-				66FA9B59155B16B500B6FAC1 /* py.sh */,
-				66FA9B5A155B16B500B6FAC1 /* pydoctor */,
-				66FA9B5B155B16B500B6FAC1 /* pygettext.py */,
-				66FA9B5C155B16B500B6FAC1 /* shell.sh */,
-				66FA9B5D155B16B500B6FAC1 /* submit */,
-				66FA9B5E155B16B500B6FAC1 /* version.py */,
-				66FA9B5F155B16B500B6FAC1 /* test */,
-				66FA9B60155B16B500B6FAC1 /* testserver */,
-				66FA9B61155B16B500B6FAC1 /* twext */,
-				66FA9C15155B16B500B6FAC1 /* twisted */,
-				66FA9C19155B16B500B6FAC1 /* twistedcaldav */,
-				66FA9FD2155B16B600B6FAC1 /* txdav */,
+				3519AFAB170E546B0054F087 /* CalendarServer */,
 			);
 			sourceTree = "<group>";
 		};
-		66FA9963155B16B500B6FAC1 /* bin */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9964155B16B500B6FAC1 /* _calendarserver_preamble.py */,
-				66FA9965155B16B500B6FAC1 /* caldavd */,
-				66FA9966155B16B500B6FAC1 /* calendarserver_backup */,
-				66FA9967155B16B500B6FAC1 /* calendarserver_bootstrap_database */,
-				66FA9968155B16B500B6FAC1 /* calendarserver_command_gateway */,
-				66FA9969155B16B500B6FAC1 /* calendarserver_config */,
-				66FA996A155B16B500B6FAC1 /* calendarserver_dbinspect */,
-				66FA996B155B16B500B6FAC1 /* calendarserver_export */,
-				66FA996C155B16B500B6FAC1 /* calendarserver_load_augmentdb */,
-				66FA996D155B16B500B6FAC1 /* calendarserver_make_partition */,
-				66FA996E155B16B500B6FAC1 /* calendarserver_manage_postgres */,
-				66FA996F155B16B500B6FAC1 /* calendarserver_manage_principals */,
-				66FA9970155B16B500B6FAC1 /* calendarserver_manage_push */,
-				66FA9971155B16B500B6FAC1 /* calendarserver_manage_timezones */,
-				66FA9972155B16B500B6FAC1 /* calendarserver_migrate_resources */,
-				66FA9973155B16B500B6FAC1 /* calendarserver_monitor_amp_notifications */,
-				66FA9974155B16B500B6FAC1 /* calendarserver_monitor_notifications */,
-				66FA9975155B16B500B6FAC1 /* calendarserver_purge_attachments */,
-				66FA9976155B16B500B6FAC1 /* calendarserver_purge_events */,
-				66FA9977155B16B500B6FAC1 /* calendarserver_purge_principals */,
-				66FA9978155B16B500B6FAC1 /* calendarserver_shell */,
-				66FA9979155B16B500B6FAC1 /* calendarserver_upgrade */,
-				66FA997A155B16B500B6FAC1 /* calendarserver_verify_data */,
-				66FA997B155B16B500B6FAC1 /* calendarserver_warmup */,
-				66FA997C155B16B500B6FAC1 /* icalendar_split */,
-				66FA997D155B16B500B6FAC1 /* make-ssl-ca */,
-				66FA997E155B16B500B6FAC1 /* make-ssl-key */,
-				66FA997F155B16B500B6FAC1 /* proxyclean */,
-				66FA9980155B16B500B6FAC1 /* watch_memcached */,
+/* End PBXGroup section */
+
+/* Begin PBXLegacyTarget section */
+		35E050FC170E534C00D4A7CA /* CalendarServer */ = {
+			isa = PBXLegacyTarget;
+			buildArgumentsString = "-f XCode.make $(ACTION)";
+			buildConfigurationList = 35E050FF170E534C00D4A7CA /* Build configuration list for PBXLegacyTarget "CalendarServer" */;
+			buildPhases = (
 			);
-			name = bin;
-			path = ../bin;
-			sourceTree = "<group>";
-		};
-		66FA9981155B16B500B6FAC1 /* calendarserver */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9982155B16B500B6FAC1 /* __init__.py */,
-				66FA9983155B16B500B6FAC1 /* accesslog.py */,
-				66FA9984155B16B500B6FAC1 /* platform */,
-				66FA9995155B16B500B6FAC1 /* provision */,
-				66FA999B155B16B500B6FAC1 /* push */,
-				66FA99A4155B16B500B6FAC1 /* tap */,
-				66FA99AF155B16B500B6FAC1 /* test */,
-				66FA99B1155B16B500B6FAC1 /* tools */,
-				66FA99FE155B16B500B6FAC1 /* webadmin */,
-				66FA9A05155B16B500B6FAC1 /* webcal */,
+			buildToolPath = /usr/bin/make;
+			buildWorkingDirectory = "";
+			dependencies = (
 			);
-			name = calendarserver;
-			path = ../calendarserver;
-			sourceTree = "<group>";
+			name = CalendarServer;
+			passBuildSettingsInEnvironment = 0;
+			productName = CalendarServer;
 		};
-		66FA9984155B16B500B6FAC1 /* platform */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9985155B16B500B6FAC1 /* __init__.py */,
-				66FA9986155B16B500B6FAC1 /* darwin */,
-			);
-			path = platform;
-			sourceTree = "<group>";
-		};
-		66FA9986155B16B500B6FAC1 /* darwin */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9987155B16B500B6FAC1 /* __init__.py */,
-				66FA9988155B16B500B6FAC1 /* _sacl.c */,
-				66FA9989155B16B500B6FAC1 /* od */,
-				66FA9994155B16B500B6FAC1 /* wiki.py */,
-			);
-			path = darwin;
-			sourceTree = "<group>";
-		};
-		66FA9989155B16B500B6FAC1 /* od */ = {
-			isa = PBXGroup;
-			children = (
-				66FA998A155B16B500B6FAC1 /* __init__.py */,
-				66FA998B155B16B500B6FAC1 /* dsattributes.py */,
-				66FA998C155B16B500B6FAC1 /* dsquery.py */,
-				66FA998D155B16B500B6FAC1 /* odframework.py */,
-				66FA998E155B16B500B6FAC1 /* opendirectory.py */,
-				66FA998F155B16B500B6FAC1 /* setup_directory.py */,
-				66FA9990155B16B500B6FAC1 /* setup_testusers.py */,
-				66FA9991155B16B500B6FAC1 /* test */,
-			);
-			path = od;
-			sourceTree = "<group>";
-		};
-		66FA9991155B16B500B6FAC1 /* test */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9992155B16B500B6FAC1 /* __init__.py */,
-				66FA9993155B16B500B6FAC1 /* test_opendirectory.py */,
-			);
-			path = test;
-			sourceTree = "<group>";
-		};
-		66FA9995155B16B500B6FAC1 /* provision */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9996155B16B500B6FAC1 /* __init__.py */,
-				66FA9997155B16B500B6FAC1 /* root.py */,
-				66FA9998155B16B500B6FAC1 /* test */,
-			);
-			path = provision;
-			sourceTree = "<group>";
-		};
-		66FA9998155B16B500B6FAC1 /* test */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9999155B16B500B6FAC1 /* __init__.py */,
-				66FA999A155B16B500B6FAC1 /* test_root.py */,
-			);
-			path = test;
-			sourceTree = "<group>";
-		};
-		66FA999B155B16B500B6FAC1 /* push */ = {
-			isa = PBXGroup;
-			children = (
-				66FA999C155B16B500B6FAC1 /* __init__.py */,
-				66FA999D155B16B500B6FAC1 /* amppush.py */,
-				66FA999E155B16B500B6FAC1 /* applepush.py */,
-				66FA999F155B16B500B6FAC1 /* test */,
-				66FA99A3155B16B500B6FAC1 /* util.py */,
-			);
-			path = push;
-			sourceTree = "<group>";
-		};
-		66FA999F155B16B500B6FAC1 /* test */ = {
-			isa = PBXGroup;
-			children = (
-				66FA99A0155B16B500B6FAC1 /* __init__.py */,
-				66FA99A1155B16B500B6FAC1 /* test_amppush.py */,
-				66FA99A2155B16B500B6FAC1 /* test_applepush.py */,
-			);
-			path = test;
-			sourceTree = "<group>";
-		};
-		66FA99A4155B16B500B6FAC1 /* tap */ = {
-			isa = PBXGroup;
-			children = (
-				66FA99A5155B16B500B6FAC1 /* __init__.py */,
-				66FA99A6155B16B500B6FAC1 /* caldav.py */,
-				66FA99A7155B16B500B6FAC1 /* cfgchild.py */,
-				66FA99A8155B16B500B6FAC1 /* profiling.py */,
-				66FA99A9155B16B500B6FAC1 /* test */,
-				66FA99AE155B16B500B6FAC1 /* util.py */,
-			);
-			path = tap;
-			sourceTree = "<group>";
-		};
-		66FA99A9155B16B500B6FAC1 /* test */ = {
-			isa = PBXGroup;
-			children = (
-				66FA99AA155B16B500B6FAC1 /* __init__.py */,
-				66FA99AB155B16B500B6FAC1 /* longlines.py */,
-				66FA99AC155B16B500B6FAC1 /* test_caldav.py */,
-				66FA99AD155B16B500B6FAC1 /* test_util.py */,
-			);
-			path = test;
-			sourceTree = "<group>";
-		};
-		66FA99AF155B16B500B6FAC1 /* test */ = {
-			isa = PBXGroup;
-			children = (
-				66FA99B0155B16B500B6FAC1 /* __init__.py */,
-			);
-			path = test;
-			sourceTree = "<group>";
-		};
-		66FA99B1155B16B500B6FAC1 /* tools */ = {
-			isa = PBXGroup;
-			children = (
-				66FA99B2155B16B500B6FAC1 /* __init__.py */,
-				66FA99B3155B16B500B6FAC1 /* ampnotifications.py */,
-				66FA99B4155B16B500B6FAC1 /* anonymize.py */,
-				66FA99B5155B16B500B6FAC1 /* backup.py */,
-				66FA99B6155B16B500B6FAC1 /* backup_pg.py */,
-				66FA99B7155B16B500B6FAC1 /* bootstrapdatabase.py */,
-				66FA99B8155B16B500B6FAC1 /* calverify.py */,
-				66FA99B9155B16B500B6FAC1 /* calverify_diff.py */,
-				66FA99BA155B16B500B6FAC1 /* changeip_calendar.py */,
-				66FA99BB155B16B500B6FAC1 /* cmdline.py */,
-				66FA99BC155B16B500B6FAC1 /* config.py */,
-				66FA99BD155B16B500B6FAC1 /* dbinspect.py */,
-				66FA99BE155B16B500B6FAC1 /* doublequotefix.py */,
-				66FA99BF155B16B500B6FAC1 /* export.py */,
-				66FA99C0155B16B500B6FAC1 /* fixcalendardata.py */,
-				66FA99C1155B16B500B6FAC1 /* gateway.py */,
-				66FA99C2155B16B500B6FAC1 /* icalsplit.py */,
-				66FA99C3155B16B500B6FAC1 /* loadaugmentdb.py */,
-				66FA99C4155B16B500B6FAC1 /* managepostgres.py */,
-				66FA99C5155B16B500B6FAC1 /* managetimezones.py */,
-				66FA99C6155B16B500B6FAC1 /* migrate.py */,
-				66FA99C7155B16B500B6FAC1 /* notifications.py */,
-				66FA99C8155B16B500B6FAC1 /* principals.py */,
-				66FA99C9155B16B500B6FAC1 /* purge.py */,
-				66FA99CA155B16B500B6FAC1 /* push.py */,
-				66FA99CB155B16B500B6FAC1 /* resources.py */,
-				66FA99CC155B16B500B6FAC1 /* shell */,
-				66FA99D6155B16B500B6FAC1 /* tables.py */,
-				66FA99D7155B16B500B6FAC1 /* test */,
-				66FA99FA155B16B500B6FAC1 /* upgrade.py */,
-				66FA99FB155B16B500B6FAC1 /* util.py */,
-				66FA99FC155B16B500B6FAC1 /* validcalendardata.py */,
-				66FA99FD155B16B500B6FAC1 /* warmup.py */,
-			);
-			path = tools;
-			sourceTree = "<group>";
-		};
-		66FA99CC155B16B500B6FAC1 /* shell */ = {
-			isa = PBXGroup;
-			children = (
-				66FA99CD155B16B500B6FAC1 /* __init__.py */,
-				66FA99CE155B16B500B6FAC1 /* cmd.py */,
-				66FA99CF155B16B500B6FAC1 /* directory.py */,
-				66FA99D0155B16B500B6FAC1 /* terminal.py */,
-				66FA99D1155B16B500B6FAC1 /* test */,
-				66FA99D5155B16B500B6FAC1 /* vfs.py */,
-			);
-			path = shell;
-			sourceTree = "<group>";
-		};
-		66FA99D1155B16B500B6FAC1 /* test */ = {
-			isa = PBXGroup;
-			children = (
-				66FA99D2155B16B500B6FAC1 /* __init__.py */,
-				66FA99D3155B16B500B6FAC1 /* test_cmd.py */,
-				66FA99D4155B16B500B6FAC1 /* test_vfs.py */,
-			);
-			path = test;
-			sourceTree = "<group>";
-		};
-		66FA99D7155B16B500B6FAC1 /* test */ = {
-			isa = PBXGroup;
-			children = (
-				66FA99D8155B16B500B6FAC1 /* __init__.py */,
-				66FA99D9155B16B500B6FAC1 /* calverify */,
-				66FA99DD155B16B500B6FAC1 /* deprovision */,
-				66FA99E2155B16B500B6FAC1 /* gateway */,
-				66FA99E7155B16B500B6FAC1 /* principals */,
-				66FA99EC155B16B500B6FAC1 /* purge */,
-				66FA99EF155B16B500B6FAC1 /* test_calverify.py */,
-				66FA99F0155B16B500B6FAC1 /* test_changeip.py */,
-				66FA99F1155B16B500B6FAC1 /* test_export.py */,
-				66FA99F2155B16B500B6FAC1 /* test_gateway.py */,
-				66FA99F3155B16B500B6FAC1 /* test_principals.py */,
-				66FA99F4155B16B500B6FAC1 /* test_purge.py */,
-				66FA99F5155B16B500B6FAC1 /* test_purge_old_events.py */,
-				66FA99F6155B16B500B6FAC1 /* test_resources.py */,
-				66FA99F7155B16B500B6FAC1 /* test_util.py */,
-				66FA99F8155B16B500B6FAC1 /* util */,
-			);
-			path = test;
-			sourceTree = "<group>";
-		};
-		66FA99D9155B16B500B6FAC1 /* calverify */ = {
-			isa = PBXGroup;
-			children = (
-				66FA99DA155B16B500B6FAC1 /* accounts.xml */,
-				66FA99DB155B16B500B6FAC1 /* augments.xml */,
-				66FA99DC155B16B500B6FAC1 /* resources.xml */,
-			);
-			path = calverify;
-			sourceTree = "<group>";
-		};
-		66FA99DD155B16B500B6FAC1 /* deprovision */ = {
-			isa = PBXGroup;
-			children = (
-				66FA99DE155B16B500B6FAC1 /* augments.xml */,
-				66FA99DF155B16B500B6FAC1 /* caldavd.plist */,
-				66FA99E0155B16B500B6FAC1 /* resources-locations.xml */,
-				66FA99E1155B16B500B6FAC1 /* users-groups.xml */,
-			);
-			path = deprovision;
-			sourceTree = "<group>";
-		};
-		66FA99E2155B16B500B6FAC1 /* gateway */ = {
-			isa = PBXGroup;
-			children = (
-				66FA99E3155B16B500B6FAC1 /* augments.xml */,
-				66FA99E4155B16B500B6FAC1 /* caldavd.plist */,
-				66FA99E5155B16B500B6FAC1 /* resources-locations.xml */,
-				66FA99E6155B16B500B6FAC1 /* users-groups.xml */,
-			);
-			path = gateway;
-			sourceTree = "<group>";
-		};
-		66FA99E7155B16B500B6FAC1 /* principals */ = {
-			isa = PBXGroup;
-			children = (
-				66FA99E8155B16B500B6FAC1 /* augments.xml */,
-				66FA99E9155B16B500B6FAC1 /* caldavd.plist */,
-				66FA99EA155B16B500B6FAC1 /* resources-locations.xml */,
-				66FA99EB155B16B500B6FAC1 /* users-groups.xml */,
-			);
-			path = principals;
-			sourceTree = "<group>";
-		};
-		66FA99EC155B16B500B6FAC1 /* purge */ = {
-			isa = PBXGroup;
-			children = (
-				66FA99ED155B16B500B6FAC1 /* accounts.xml */,
-				66FA99EE155B16B500B6FAC1 /* resources.xml */,
-			);
-			path = purge;
-			sourceTree = "<group>";
-		};
-		66FA99F8155B16B500B6FAC1 /* util */ = {
-			isa = PBXGroup;
-			children = (
-				66FA99F9155B16B500B6FAC1 /* caldavd.plist */,
-			);
-			path = util;
-			sourceTree = "<group>";
-		};
-		66FA99FE155B16B500B6FAC1 /* webadmin */ = {
-			isa = PBXGroup;
-			children = (
-				66FA99FF155B16B500B6FAC1 /* __init__.py */,
-				66FA9A00155B16B500B6FAC1 /* resource.py */,
-				66FA9A01155B16B500B6FAC1 /* template.html */,
-				66FA9A02155B16B500B6FAC1 /* test */,
-			);
-			path = webadmin;
-			sourceTree = "<group>";
-		};
-		66FA9A02155B16B500B6FAC1 /* test */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9A03155B16B500B6FAC1 /* __init__.py */,
-				66FA9A04155B16B500B6FAC1 /* test_resource.py */,
-			);
-			path = test;
-			sourceTree = "<group>";
-		};
-		66FA9A05155B16B500B6FAC1 /* webcal */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9A06155B16B500B6FAC1 /* __init__.py */,
-				66FA9A07155B16B500B6FAC1 /* resource.py */,
-			);
-			path = webcal;
-			sourceTree = "<group>";
-		};
-		66FA9A08155B16B500B6FAC1 /* conf */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9A09155B16B500B6FAC1 /* auth */,
-				66FA9A13155B16B500B6FAC1 /* caldavd-apple.plist */,
-				66FA9A14155B16B500B6FAC1 /* caldavd-partitioning-primary.plist */,
-				66FA9A15155B16B500B6FAC1 /* caldavd-partitioning-secondary.plist */,
-				66FA9A16155B16B500B6FAC1 /* caldavd-test.plist */,
-				66FA9A17155B16B500B6FAC1 /* caldavd.plist */,
-				66FA9A18155B16B500B6FAC1 /* mime.types */,
-				66FA9A19155B16B500B6FAC1 /* resources */,
-				66FA9A1E155B16B500B6FAC1 /* resources.xml */,
-				66FA9A1F155B16B500B6FAC1 /* servers-test.xml */,
-				66FA9A20155B16B500B6FAC1 /* servers.dtd */,
-				66FA9A21155B16B500B6FAC1 /* servers.xml */,
-				66FA9A22155B16B500B6FAC1 /* servertoserver-test.xml */,
-				66FA9A23155B16B500B6FAC1 /* servertoserver.dtd */,
-				66FA9A24155B16B500B6FAC1 /* servertoserver.xml */,
-				66FA9A25155B16B500B6FAC1 /* sudoers.plist */,
-			);
-			name = conf;
-			path = ../conf;
-			sourceTree = "<group>";
-		};
-		66FA9A09155B16B500B6FAC1 /* auth */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9A0A155B16B500B6FAC1 /* accounts-test.xml */,
-				66FA9A0B155B16B500B6FAC1 /* accounts.dtd */,
-				66FA9A0C155B16B500B6FAC1 /* accounts.xml */,
-				66FA9A0D155B16B500B6FAC1 /* augments-default.xml */,
-				66FA9A0E155B16B500B6FAC1 /* augments-test.xml */,
-				66FA9A0F155B16B500B6FAC1 /* augments.dtd */,
-				66FA9A10155B16B500B6FAC1 /* proxies-test.xml */,
-				66FA9A11155B16B500B6FAC1 /* proxies.dtd */,
-				66FA9A12155B16B500B6FAC1 /* resources-test.xml */,
-			);
-			path = auth;
-			sourceTree = "<group>";
-		};
-		66FA9A19155B16B500B6FAC1 /* resources */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9A1A155B16B500B6FAC1 /* caldavd-resources.plist */,
-				66FA9A1B155B16B500B6FAC1 /* locations-resources-orig.xml */,
-				66FA9A1C155B16B500B6FAC1 /* locations-resources.xml */,
-				66FA9A1D155B16B500B6FAC1 /* users-groups.xml */,
-			);
-			path = resources;
-			sourceTree = "<group>";
-		};
-		66FA9A26155B16B500B6FAC1 /* contrib */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9A27155B16B500B6FAC1 /* __init__.py */,
-				66FA9A28155B16B500B6FAC1 /* CalendarServer.png */,
-				66FA9A29155B16B500B6FAC1 /* certupdate */,
-				66FA9A2F155B16B500B6FAC1 /* create_caldavd_db.sh */,
-				66FA9A30155B16B500B6FAC1 /* iCalServer.ico */,
-				66FA9A31155B16B500B6FAC1 /* launchd */,
-				66FA9A33155B16B500B6FAC1 /* migration */,
-				66FA9A3A155B16B500B6FAC1 /* performance */,
-				66FA9AC6155B16B500B6FAC1 /* tools */,
-			);
-			name = contrib;
-			path = ../contrib;
-			sourceTree = "<group>";
-		};
-		66FA9A29155B16B500B6FAC1 /* certupdate */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9A2A155B16B500B6FAC1 /* __init__.py */,
-				66FA9A2B155B16B500B6FAC1 /* calendarcertupdate.py */,
-				66FA9A2C155B16B500B6FAC1 /* test */,
-			);
-			path = certupdate;
-			sourceTree = "<group>";
-		};
-		66FA9A2C155B16B500B6FAC1 /* test */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9A2D155B16B500B6FAC1 /* __init__.py */,
-				66FA9A2E155B16B500B6FAC1 /* test_certupdate.py */,
-			);
-			path = test;
-			sourceTree = "<group>";
-		};
-		66FA9A31155B16B500B6FAC1 /* launchd */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9A32155B16B500B6FAC1 /* calendarserver.plist */,
-			);
-			path = launchd;
-			sourceTree = "<group>";
-		};
-		66FA9A33155B16B500B6FAC1 /* migration */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9A34155B16B500B6FAC1 /* __init__.py */,
-				66FA9A35155B16B500B6FAC1 /* calendarmigrator.py */,
-				66FA9A36155B16B500B6FAC1 /* calendarpromotion.py */,
-				66FA9A37155B16B500B6FAC1 /* test */,
-			);
-			path = migration;
-			sourceTree = "<group>";
-		};
-		66FA9A37155B16B500B6FAC1 /* test */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9A38155B16B500B6FAC1 /* __init__.py */,
-				66FA9A39155B16B500B6FAC1 /* test_migrator.py */,
-			);
-			path = test;
-			sourceTree = "<group>";
-		};
-		66FA9A3A155B16B500B6FAC1 /* performance */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9A3B155B16B500B6FAC1 /* __init__.py */,
-				66FA9A3C155B16B500B6FAC1 /* _event_change.py */,
-				66FA9A3D155B16B500B6FAC1 /* _event_create.py */,
-				66FA9A3E155B16B500B6FAC1 /* benchlib.py */,
-				66FA9A3F155B16B500B6FAC1 /* benchlib.sh */,
-				66FA9A40155B16B500B6FAC1 /* benchmark */,
-				66FA9A41155B16B500B6FAC1 /* benchmark.py */,
-				66FA9A42155B16B500B6FAC1 /* benchmarks */,
-				66FA9A54155B16B500B6FAC1 /* compare */,
-				66FA9A55155B16B500B6FAC1 /* compare.py */,
-				66FA9A56155B16B500B6FAC1 /* display-calendar-events.py */,
-				66FA9A57155B16B500B6FAC1 /* eventkitframework.py */,
-				66FA9A58155B16B500B6FAC1 /* extractconf */,
-				66FA9A59155B16B500B6FAC1 /* fix-units.sql */,
-				66FA9A5A155B16B500B6FAC1 /* graph */,
-				66FA9A5B155B16B500B6FAC1 /* graph.py */,
-				66FA9A5C155B16B500B6FAC1 /* httpauth.py */,
-				66FA9A5D155B16B500B6FAC1 /* httpclient.py */,
-				66FA9A5E155B16B500B6FAC1 /* io_measure.d */,
-				66FA9A5F155B16B500B6FAC1 /* loadtest */,
-				66FA9AA9155B16B500B6FAC1 /* massupload */,
-				66FA9AAA155B16B500B6FAC1 /* massupload.py */,
-				66FA9AAB155B16B500B6FAC1 /* nightly.sh */,
-				66FA9AAC155B16B500B6FAC1 /* pgsql.d */,
-				66FA9AAD155B16B500B6FAC1 /* profile.sh */,
-				66FA9AAE155B16B500B6FAC1 /* report */,
-				66FA9AAF155B16B500B6FAC1 /* report.py */,
-				66FA9AB0155B16B500B6FAC1 /* report_principals.py */,
-				66FA9AB1155B16B500B6FAC1 /* reupload.sh */,
-				66FA9AB2155B16B500B6FAC1 /* sample-many.sh */,
-				66FA9AB3155B16B500B6FAC1 /* sample.sh */,
-				66FA9AB4155B16B500B6FAC1 /* setbackend */,
-				66FA9AB5155B16B500B6FAC1 /* setbackend.py */,
-				66FA9AB6155B16B500B6FAC1 /* sim */,
-				66FA9AB7155B16B500B6FAC1 /* some-more-data.sh */,
-				66FA9AB8155B16B500B6FAC1 /* speedcenter.tac */,
-				66FA9AB9155B16B500B6FAC1 /* sql_measure.d */,
-				66FA9ABA155B16B500B6FAC1 /* sqlwatch */,
-				66FA9ABB155B16B500B6FAC1 /* sqlwatch.py */,
-				66FA9ABC155B16B500B6FAC1 /* stackedbar.py */,
-				66FA9ABD155B16B500B6FAC1 /* stats.py */,
-				66FA9ABE155B16B500B6FAC1 /* sudo-run.sh */,
-				66FA9ABF155B16B500B6FAC1 /* svn-committime */,
-				66FA9AC0155B16B500B6FAC1 /* svn-revno */,
-				66FA9AC1155B16B500B6FAC1 /* test_benchmark.py */,
-				66FA9AC2155B16B500B6FAC1 /* test_event_change_date.py */,
-				66FA9AC3155B16B500B6FAC1 /* test_stats.py */,
-				66FA9AC4155B16B500B6FAC1 /* upload */,
-				66FA9AC5155B16B500B6FAC1 /* upload.py */,
-			);
-			path = performance;
-			sourceTree = "<group>";
-		};
-		66FA9A42155B16B500B6FAC1 /* benchmarks */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9A43155B16B500B6FAC1 /* __init__.py */,
-				66FA9A44155B16B500B6FAC1 /* bounded_recurrence.py */,
-				66FA9A45155B16B500B6FAC1 /* bounded_recurrence_autoaccept.py */,
-				66FA9A46155B16B500B6FAC1 /* event.py */,
-				66FA9A47155B16B500B6FAC1 /* event_add_attendee.py */,
-				66FA9A48155B16B500B6FAC1 /* event_autoaccept.py */,
-				66FA9A49155B16B500B6FAC1 /* event_change_date.py */,
-				66FA9A4A155B16B500B6FAC1 /* event_change_summary.py */,
-				66FA9A4B155B16B500B6FAC1 /* event_delete.py */,
-				66FA9A4C155B16B500B6FAC1 /* event_delete_attendee.py */,
-				66FA9A4D155B16B500B6FAC1 /* event_move.py */,
-				66FA9A4E155B16B500B6FAC1 /* find_calendars.py */,
-				66FA9A4F155B16B500B6FAC1 /* find_events.py */,
-				66FA9A50155B16B500B6FAC1 /* unbounded_recurrence.py */,
-				66FA9A51155B16B500B6FAC1 /* unbounded_recurrence_autoaccept.py */,
-				66FA9A52155B16B500B6FAC1 /* vfreebusy.py */,
-				66FA9A53155B16B500B6FAC1 /* vfreebusy_vary_attendees.py */,
-			);
-			path = benchmarks;
-			sourceTree = "<group>";
-		};
-		66FA9A5F155B16B500B6FAC1 /* loadtest */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9A60155B16B500B6FAC1 /* __init__.py */,
-				66FA9A61155B16B500B6FAC1 /* accounts.csv */,
-				66FA9A62155B16B500B6FAC1 /* ampsim.py */,
-				66FA9A63155B16B500B6FAC1 /* config.dist.plist */,
-				66FA9A64155B16B500B6FAC1 /* config.plist */,
-				66FA9A65155B16B500B6FAC1 /* ical.py */,
-				66FA9A66155B16B500B6FAC1 /* logger.py */,
-				66FA9A67155B16B500B6FAC1 /* population.py */,
-				66FA9A68155B16B500B6FAC1 /* profiles.py */,
-				66FA9A69155B16B500B6FAC1 /* request-data */,
-				66FA9A9F155B16B500B6FAC1 /* sim.py */,
-				66FA9AA0155B16B500B6FAC1 /* subscribe.py */,
-				66FA9AA1155B16B500B6FAC1 /* test_ical.py */,
-				66FA9AA2155B16B500B6FAC1 /* test_population.py */,
-				66FA9AA3155B16B500B6FAC1 /* test_profiles.py */,
-				66FA9AA4155B16B500B6FAC1 /* test_sim.py */,
-				66FA9AA5155B16B500B6FAC1 /* test_trafficlogger.py */,
-				66FA9AA6155B16B500B6FAC1 /* test_webadmin.py */,
-				66FA9AA7155B16B500B6FAC1 /* trafficlogger.py */,
-				66FA9AA8155B16B500B6FAC1 /* webadmin.py */,
-			);
-			path = loadtest;
-			sourceTree = "<group>";
-		};
-		66FA9A69155B16B500B6FAC1 /* request-data */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9A6A155B16B500B6FAC1 /* iOS_5 */,
-				66FA9A79155B16B500B6FAC1 /* OS_X_10_6 */,
-				66FA9A8B155B16B500B6FAC1 /* OS_X_10_7 */,
-			);
-			path = "request-data";
-			sourceTree = "<group>";
-		};
-		66FA9A6A155B16B500B6FAC1 /* iOS_5 */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9A6B155B16B500B6FAC1 /* poll_calendar_multiget.request */,
-				66FA9A6C155B16B500B6FAC1 /* poll_calendar_multiget_hrefs.request */,
-				66FA9A6D155B16B500B6FAC1 /* poll_calendar_propfind.request */,
-				66FA9A6E155B16B500B6FAC1 /* poll_calendar_propfind_d1.request */,
-				66FA9A6F155B16B500B6FAC1 /* poll_calendar_vevent_tr_query.request */,
-				66FA9A70155B16B500B6FAC1 /* poll_calendar_vtodo_query.request */,
-				66FA9A71155B16B500B6FAC1 /* poll_calendarhome_propfind.request */,
-				66FA9A72155B16B500B6FAC1 /* Profile */,
-				66FA9A73155B16B500B6FAC1 /* startup_calendar_color_proppatch.request */,
-				66FA9A74155B16B500B6FAC1 /* startup_calendar_order_proppatch.request */,
-				66FA9A75155B16B500B6FAC1 /* startup_principal_propfind.request */,
-				66FA9A76155B16B500B6FAC1 /* startup_principal_propfind_initial.request */,
-				66FA9A77155B16B500B6FAC1 /* startup_principals_report.request */,
-				66FA9A78155B16B500B6FAC1 /* startup_well_known.request */,
-			);
-			path = iOS_5;
-			sourceTree = "<group>";
-		};
-		66FA9A79155B16B500B6FAC1 /* OS_X_10_6 */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9A7A155B16B500B6FAC1 /* poll_calendar_multiget.request */,
-				66FA9A7B155B16B500B6FAC1 /* poll_calendar_multiget_hrefs.request */,
-				66FA9A7C155B16B500B6FAC1 /* poll_calendar_propfind.request */,
-				66FA9A7D155B16B500B6FAC1 /* poll_calendar_propfind_d1.request */,
-				66FA9A7E155B16B500B6FAC1 /* poll_calendarhome_propfind.request */,
-				66FA9A7F155B16B500B6FAC1 /* poll_notification_propfind_d1.request */,
-				66FA9A80155B16B500B6FAC1 /* post_availability.request */,
-				66FA9A81155B16B500B6FAC1 /* startup_calendar_color_proppatch.request */,
-				66FA9A82155B16B500B6FAC1 /* startup_calendar_order_proppatch.request */,
-				66FA9A83155B16B500B6FAC1 /* startup_calendar_timezone_proppatch.request */,
-				66FA9A84155B16B500B6FAC1 /* startup_notification_propfind.request */,
-				66FA9A85155B16B500B6FAC1 /* startup_principal_expand.request */,
-				66FA9A86155B16B500B6FAC1 /* startup_principal_propfind.request */,
-				66FA9A87155B16B500B6FAC1 /* startup_principal_propfind_initial.request */,
-				66FA9A88155B16B500B6FAC1 /* startup_principals_report.request */,
-				66FA9A89155B16B500B6FAC1 /* startup_well_known.request */,
-				66FA9A8A155B16B500B6FAC1 /* user_list_principal_property_search.request */,
-			);
-			path = OS_X_10_6;
-			sourceTree = "<group>";
-		};
-		66FA9A8B155B16B500B6FAC1 /* OS_X_10_7 */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9A8C155B16B500B6FAC1 /* poll_calendar_multiget.request */,
-				66FA9A8D155B16B500B6FAC1 /* poll_calendar_multiget_hrefs.request */,
-				66FA9A8E155B16B500B6FAC1 /* poll_calendar_propfind.request */,
-				66FA9A8F155B16B500B6FAC1 /* poll_calendar_propfind_d1.request */,
-				66FA9A90155B16B500B6FAC1 /* poll_calendar_sync.request */,
-				66FA9A91155B16B500B6FAC1 /* poll_calendarhome_propfind.request */,
-				66FA9A92155B16B500B6FAC1 /* poll_notification_propfind_d1.request */,
-				66FA9A93155B16B500B6FAC1 /* post_availability.request */,
-				66FA9A94155B16B500B6FAC1 /* Profile */,
-				66FA9A95155B16B500B6FAC1 /* startup_calendar_color_proppatch.request */,
-				66FA9A96155B16B500B6FAC1 /* startup_calendar_order_proppatch.request */,
-				66FA9A97155B16B500B6FAC1 /* startup_calendar_timezone_proppatch.request */,
-				66FA9A98155B16B500B6FAC1 /* startup_delegate_principal_propfind.request */,
-				66FA9A99155B16B500B6FAC1 /* startup_principal_expand.request */,
-				66FA9A9A155B16B500B6FAC1 /* startup_principal_propfind.request */,
-				66FA9A9B155B16B500B6FAC1 /* startup_principal_propfind_initial.request */,
-				66FA9A9C155B16B500B6FAC1 /* startup_principals_report.request */,
-				66FA9A9D155B16B500B6FAC1 /* startup_well_known.request */,
-				66FA9A9E155B16B500B6FAC1 /* user_list_principal_property_search.request */,
-			);
-			path = OS_X_10_7;
-			sourceTree = "<group>";
-		};
-		66FA9AC6155B16B500B6FAC1 /* tools */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9AC7155B16B500B6FAC1 /* anonymous_log.py */,
-				66FA9AC8155B16B500B6FAC1 /* dtraceanalyze.py */,
-				66FA9AC9155B16B500B6FAC1 /* fakecalendardata.py */,
-				66FA9ACA155B16B500B6FAC1 /* fix_calendar */,
-				66FA9ACB155B16B500B6FAC1 /* harpoon.py */,
-				66FA9ACC155B16B500B6FAC1 /* monitoranalysis.py */,
-				66FA9ACD155B16B500B6FAC1 /* monitorsplit.py */,
-				66FA9ACE155B16B500B6FAC1 /* netstatus.py */,
-				66FA9ACF155B16B500B6FAC1 /* pg_stats_analysis.py */,
-				66FA9AD0155B16B500B6FAC1 /* pgtrace.d */,
-				66FA9AD1155B16B500B6FAC1 /* protocolanalysis.py */,
-				66FA9AD2155B16B500B6FAC1 /* request_monitor.py */,
-				66FA9AD3155B16B500B6FAC1 /* sortrecurrences.py */,
-				66FA9AD4155B16B500B6FAC1 /* sqldata_from_path.py */,
-				66FA9AD5155B16B500B6FAC1 /* tables.py */,
-				66FA9AD6155B16B500B6FAC1 /* test_protocolanalysis.py */,
-				66FA9AD7155B16B500B6FAC1 /* trace.d */,
-			);
-			path = tools;
-			sourceTree = "<group>";
-		};
-		66FA9AD8155B16B500B6FAC1 /* doc */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9AD9155B16B500B6FAC1 /* Admin */,
-				66FA9AE1155B16B500B6FAC1 /* caldavd.8 */,
-				66FA9AE2155B16B500B6FAC1 /* calendarserver_bootstrap_database.8 */,
-				66FA9AE3155B16B500B6FAC1 /* calendarserver_command_gateway.8 */,
-				66FA9AE4155B16B500B6FAC1 /* calendarserver_export.8 */,
-				66FA9AE5155B16B500B6FAC1 /* calendarserver_manage_principals.8 */,
-				66FA9AE6155B16B500B6FAC1 /* calendarserver_manage_push.8 */,
-				66FA9AE7155B16B500B6FAC1 /* calendarserver_migrate_resources.8 */,
-				66FA9AE8155B16B500B6FAC1 /* calendarserver_monitor_notifications.8 */,
-				66FA9AE9155B16B500B6FAC1 /* calendarserver_purge_attachments.8 */,
-				66FA9AEA155B16B500B6FAC1 /* calendarserver_purge_events.8 */,
-				66FA9AEB155B16B500B6FAC1 /* calendarserver_purge_principals.8 */,
-				66FA9AEC155B16B500B6FAC1 /* calendarserver_shell.8 */,
-				66FA9AED155B16B500B6FAC1 /* Client-Server */,
-				66FA9AF0155B16B500B6FAC1 /* Developer */,
-				66FA9AF4155B16B500B6FAC1 /* Extensions */,
-				66FA9B07155B16B500B6FAC1 /* RFC */,
-			);
-			name = doc;
-			path = ../doc;
-			sourceTree = "<group>";
-		};
-		66FA9AD9155B16B500B6FAC1 /* Admin */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9ADA155B16B500B6FAC1 /* DirectoryService-Apache.txt */,
-				66FA9ADB155B16B500B6FAC1 /* DirectoryService-OpenDirectory.txt */,
-				66FA9ADC155B16B500B6FAC1 /* DirectoryService-XML.txt */,
-				66FA9ADD155B16B500B6FAC1 /* DirectoryServices.txt */,
-				66FA9ADE155B16B500B6FAC1 /* ExtendedLogItems.txt */,
-				66FA9ADF155B16B500B6FAC1 /* LoadSimulation.txt */,
-				66FA9AE0155B16B500B6FAC1 /* MultiServerDeployment.txt */,
-			);
-			path = Admin;
-			sourceTree = "<group>";
-		};
-		66FA9AED155B16B500B6FAC1 /* Client-Server */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9AEE155B16B500B6FAC1 /* Principal Bootstrap.graffle.zip */,
-				66FA9AEF155B16B500B6FAC1 /* Principal Bootstrap.pdf */,
-			);
-			path = "Client-Server";
-			sourceTree = "<group>";
-		};
-		66FA9AF0155B16B500B6FAC1 /* Developer */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9AF1155B16B500B6FAC1 /* Calendar Store API.graffle */,
-				66FA9AF2155B16B500B6FAC1 /* Calendar Store Schema.graffle */,
-				66FA9AF3155B16B500B6FAC1 /* gendocs */,
-			);
-			path = Developer;
-			sourceTree = "<group>";
-		};
-		66FA9AF4155B16B500B6FAC1 /* Extensions */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9AF5155B16B500B6FAC1 /* caldav-ctag.txt */,
-				66FA9AF6155B16B500B6FAC1 /* caldav-ctag.xml */,
-				66FA9AF7155B16B500B6FAC1 /* caldav-notifications.txt */,
-				66FA9AF8155B16B500B6FAC1 /* caldav-notifications.xml */,
-				66FA9AF9155B16B500B6FAC1 /* caldav-privatecomments.txt */,
-				66FA9AFA155B16B500B6FAC1 /* caldav-privatecomments.xml */,
-				66FA9AFB155B16B500B6FAC1 /* caldav-privateevents.txt */,
-				66FA9AFC155B16B500B6FAC1 /* caldav-privateevents.xml */,
-				66FA9AFD155B16B500B6FAC1 /* caldav-proxy.txt */,
-				66FA9AFE155B16B500B6FAC1 /* caldav-proxy.xml */,
-				66FA9AFF155B16B500B6FAC1 /* caldav-pubsubdiscovery.txt */,
-				66FA9B00155B16B500B6FAC1 /* caldav-pubsubdiscovery.xml */,
-				66FA9B01155B16B500B6FAC1 /* caldav-schedulingchanges.txt */,
-				66FA9B02155B16B500B6FAC1 /* caldav-schedulingchanges.xml */,
-				66FA9B03155B16B500B6FAC1 /* caldav-sharing-02.txt */,
-				66FA9B04155B16B500B6FAC1 /* caldav-sharing-02.xml */,
-				66FA9B05155B16B500B6FAC1 /* icalendar-maskuids.txt */,
-				66FA9B06155B16B500B6FAC1 /* icalendar-maskuids.xml */,
-			);
-			path = Extensions;
-			sourceTree = "<group>";
-		};
-		66FA9B07155B16B500B6FAC1 /* RFC */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9B08155B16B500B6FAC1 /* draft-daboo-caldav-extensions.txt */,
-				66FA9B09155B16B500B6FAC1 /* draft-daboo-calendar-availability.txt */,
-				66FA9B0A155B16B500B6FAC1 /* draft-daboo-carddav-directory-gateway.txt */,
-				66FA9B0B155B16B500B6FAC1 /* draft-daboo-srv-caldav.txt */,
-				66FA9B0C155B16B500B6FAC1 /* draft-desruisseaux-caldav-sched.txt */,
-				66FA9B0D155B16B500B6FAC1 /* draft-desruisseaux-ischedule.txt */,
-				66FA9B0E155B16B500B6FAC1 /* rfc2616-HTTP.txt */,
-				66FA9B0F155B16B500B6FAC1 /* rfc2617-HTTP Auth.txt */,
-				66FA9B10155B16B500B6FAC1 /* rfc3253-DeltaV.txt */,
-				66FA9B11155B16B500B6FAC1 /* rfc3283-Calendaring.txt */,
-				66FA9B12155B16B500B6FAC1 /* rfc3744-WebDAV ACL.txt */,
-				66FA9B13155B16B500B6FAC1 /* rfc4331-WebDAV Quota.txt */,
-				66FA9B14155B16B500B6FAC1 /* rfc4559-SPNEGO.txt */,
-				66FA9B15155B16B500B6FAC1 /* rfc4791-CalDAV.txt */,
-				66FA9B16155B16B500B6FAC1 /* rfc4918-WebDAV.txt */,
-				66FA9B17155B16B500B6FAC1 /* rfc5397-Current Principal.txt */,
-				66FA9B18155B16B500B6FAC1 /* rfc5545-iCalendar.txt */,
-				66FA9B19155B16B500B6FAC1 /* rfc5546-iTIP.txt */,
-				66FA9B1A155B16B500B6FAC1 /* rfc5689-Extended MKCOL.txt */,
-				66FA9B1B155B16B500B6FAC1 /* rfc5785-well-known-uris.txt */,
-				66FA9B1C155B16B500B6FAC1 /* rfc5842-BIND.txt */,
-				66FA9B1D155B16B500B6FAC1 /* rfc5995-POST addmember.txt */,
-				66FA9B1E155B16B500B6FAC1 /* rfc6047-iMIP.txt */,
-				66FA9B1F155B16B500B6FAC1 /* rfc6321-xCal.txt */,
-				66FA9B20155B16B500B6FAC1 /* rfc6350-vCard4.txt */,
-				66FA9B21155B16B500B6FAC1 /* rfc6351-xCard.txt */,
-				66FA9B22155B16B500B6FAC1 /* rfc6352-CardDAV.txt */,
-				66FA9B23155B16B500B6FAC1 /* rfc6578-WebDAV Sync.txt */,
-			);
-			path = RFC;
-			sourceTree = "<group>";
-		};
-		66FA9B25155B16B500B6FAC1 /* lib-patches */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9B26155B16B500B6FAC1 /* cx_Oracle */,
-			);
-			name = "lib-patches";
-			path = "../lib-patches";
-			sourceTree = "<group>";
-		};
-		66FA9B26155B16B500B6FAC1 /* cx_Oracle */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9B27155B16B500B6FAC1 /* bytes-per-nclob-character.patch */,
-			);
-			path = cx_Oracle;
-			sourceTree = "<group>";
-		};
-		66FA9B29155B16B500B6FAC1 /* locales */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9B2A155B16B500B6FAC1 /* en_EN.ISO8859-1 */,
-				66FA9B2E155B16B500B6FAC1 /* calendarserver.strings */,
-				66FA9B30155B16B500B6FAC1 /* fr */,
-				66FA9B34155B16B500B6FAC1 /* pig */,
-			);
-			name = locales;
-			path = ../locales;
-			sourceTree = "<group>";
-		};
-		66FA9B2A155B16B500B6FAC1 /* en_EN.ISO8859-1 */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9B2B155B16B500B6FAC1 /* LC_MESSAGES */,
-			);
-			path = "en_EN.ISO8859-1";
-			sourceTree = "<group>";
-		};
-		66FA9B2B155B16B500B6FAC1 /* LC_MESSAGES */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9B2C155B16B500B6FAC1 /* calendarserver.mo */,
-				66FA9B2D155B16B500B6FAC1 /* calendarserver.po */,
-			);
-			path = LC_MESSAGES;
-			sourceTree = "<group>";
-		};
-		66FA9B30155B16B500B6FAC1 /* fr */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9B31155B16B500B6FAC1 /* LC_MESSAGES */,
-			);
-			path = fr;
-			sourceTree = "<group>";
-		};
-		66FA9B31155B16B500B6FAC1 /* LC_MESSAGES */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9B32155B16B500B6FAC1 /* calendarserver.mo */,
-				66FA9B33155B16B500B6FAC1 /* calendarserver.po */,
-			);
-			path = LC_MESSAGES;
-			sourceTree = "<group>";
-		};
-		66FA9B34155B16B500B6FAC1 /* pig */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9B35155B16B500B6FAC1 /* LC_MESSAGES */,
-			);
-			path = pig;
-			sourceTree = "<group>";
-		};
-		66FA9B35155B16B500B6FAC1 /* LC_MESSAGES */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9B36155B16B500B6FAC1 /* calendarserver.mo */,
-				66FA9B37155B16B500B6FAC1 /* calendarserver.po */,
-			);
-			path = LC_MESSAGES;
-			sourceTree = "<group>";
-		};
-		66FA9B3E155B16B500B6FAC1 /* support */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9B3F155B16B500B6FAC1 /* build.sh */,
-				66FA9B44155B16B500B6FAC1 /* diffbranch */,
-				66FA9B45155B16B500B6FAC1 /* directorysetup.py */,
-				66FA9B46155B16B500B6FAC1 /* Makefile.Apple */,
-				66FA9B47155B16B500B6FAC1 /* mergebranch */,
-				66FA9B48155B16B500B6FAC1 /* patchapply */,
-				66FA9B49155B16B500B6FAC1 /* patchmaker */,
-				66FA9B4A155B16B500B6FAC1 /* pull-up */,
-				66FA9B4B155B16B500B6FAC1 /* py.sh */,
-				66FA9B4C155B16B500B6FAC1 /* pydoctor */,
-				66FA9B4D155B16B500B6FAC1 /* pygettext.py */,
-				66FA9B4E155B16B500B6FAC1 /* shell.sh */,
-				66FA9B4F155B16B500B6FAC1 /* submit */,
-				66FA9B50155B16B500B6FAC1 /* version.py */,
-			);
-			name = support;
-			sourceTree = "<group>";
-		};
-		66FA9B61155B16B500B6FAC1 /* twext */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9B62155B16B500B6FAC1 /* __init__.py */,
-				66FA9B63155B16B500B6FAC1 /* backport */,
-				66FA9B6A155B16B500B6FAC1 /* enterprise */,
-				66FA9B7B155B16B500B6FAC1 /* internet */,
-				66FA9B8B155B16B500B6FAC1 /* patches.py */,
-				66FA9B8C155B16B500B6FAC1 /* protocols */,
-				66FA9B92155B16B500B6FAC1 /* python */,
-				66FA9BA5155B16B500B6FAC1 /* web2 */,
-			);
-			name = twext;
-			path = ../twext;
-			sourceTree = "<group>";
-		};
-		66FA9B63155B16B500B6FAC1 /* backport */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9B64155B16B500B6FAC1 /* __init__.py */,
-				66FA9B65155B16B500B6FAC1 /* internet */,
-			);
-			path = backport;
-			sourceTree = "<group>";
-		};
-		66FA9B65155B16B500B6FAC1 /* internet */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9B66155B16B500B6FAC1 /* __init__.py */,
-				66FA9B67155B16B500B6FAC1 /* address.py */,
-				66FA9B68155B16B500B6FAC1 /* endpoints.py */,
-				66FA9B69155B16B500B6FAC1 /* tcp.py */,
-			);
-			path = internet;
-			sourceTree = "<group>";
-		};
-		66FA9B6A155B16B500B6FAC1 /* enterprise */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9B6B155B16B500B6FAC1 /* __init__.py */,
-				66FA9B6C155B16B500B6FAC1 /* adbapi2.py */,
-				66FA9B6D155B16B500B6FAC1 /* dal */,
-				66FA9B76155B16B500B6FAC1 /* ienterprise.py */,
-				66FA9B77155B16B500B6FAC1 /* test */,
-				66FA9B7A155B16B500B6FAC1 /* util.py */,
-			);
-			path = enterprise;
-			sourceTree = "<group>";
-		};
-		66FA9B6D155B16B500B6FAC1 /* dal */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9B6E155B16B500B6FAC1 /* __init__.py */,
-				66FA9B6F155B16B500B6FAC1 /* model.py */,
-				66FA9B70155B16B500B6FAC1 /* parseschema.py */,
-				66FA9B71155B16B500B6FAC1 /* syntax.py */,
-				66FA9B72155B16B500B6FAC1 /* test */,
-			);
-			path = dal;
-			sourceTree = "<group>";
-		};
-		66FA9B72155B16B500B6FAC1 /* test */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9B73155B16B500B6FAC1 /* __init__.py */,
-				66FA9B74155B16B500B6FAC1 /* test_parseschema.py */,
-				66FA9B75155B16B500B6FAC1 /* test_sqlsyntax.py */,
-			);
-			path = test;
-			sourceTree = "<group>";
-		};
-		66FA9B77155B16B500B6FAC1 /* test */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9B78155B16B500B6FAC1 /* __init__.py */,
-				66FA9B79155B16B500B6FAC1 /* test_adbapi2.py */,
-			);
-			path = test;
-			sourceTree = "<group>";
-		};
-		66FA9B7B155B16B500B6FAC1 /* internet */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9B7C155B16B500B6FAC1 /* __init__.py */,
-				66FA9B7D155B16B500B6FAC1 /* adaptendpoint.py */,
-				66FA9B7E155B16B500B6FAC1 /* decorate.py */,
-				66FA9B7F155B16B500B6FAC1 /* gaiendpoint.py */,
-				66FA9B80155B16B500B6FAC1 /* kqreactor.py */,
-				66FA9B81155B16B500B6FAC1 /* sendfdport.py */,
-				66FA9B82155B16B500B6FAC1 /* spawnsvc.py */,
-				66FA9B83155B16B500B6FAC1 /* ssl.py */,
-				66FA9B84155B16B500B6FAC1 /* tcp.py */,
-				66FA9B85155B16B500B6FAC1 /* test */,
-				66FA9B8A155B16B500B6FAC1 /* threadutils.py */,
-			);
-			path = internet;
-			sourceTree = "<group>";
-		};
-		66FA9B85155B16B500B6FAC1 /* test */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9B86155B16B500B6FAC1 /* __init__.py */,
-				66FA9B87155B16B500B6FAC1 /* test_adaptendpoint.py */,
-				66FA9B88155B16B500B6FAC1 /* test_gaiendpoint.py */,
-				66FA9B89155B16B500B6FAC1 /* test_sendfdport.py */,
-			);
-			path = test;
-			sourceTree = "<group>";
-		};
-		66FA9B8C155B16B500B6FAC1 /* protocols */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9B8D155B16B500B6FAC1 /* __init__.py */,
-				66FA9B8E155B16B500B6FAC1 /* memcache.py */,
-				66FA9B8F155B16B500B6FAC1 /* test */,
-			);
-			path = protocols;
-			sourceTree = "<group>";
-		};
-		66FA9B8F155B16B500B6FAC1 /* test */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9B90155B16B500B6FAC1 /* __init__.py */,
-				66FA9B91155B16B500B6FAC1 /* test_memcache.py */,
-			);
-			path = test;
-			sourceTree = "<group>";
-		};
-		66FA9B92155B16B500B6FAC1 /* python */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9B93155B16B500B6FAC1 /* __init__.py */,
-				66FA9B94155B16B500B6FAC1 /* _plistlib.py */,
-				66FA9B95155B16B500B6FAC1 /* clsprop.py */,
-				66FA9B96155B16B500B6FAC1 /* filepath.py */,
-				66FA9B97155B16B500B6FAC1 /* log.py */,
-				66FA9B98155B16B500B6FAC1 /* memcacheclient.py */,
-				66FA9B99155B16B500B6FAC1 /* parallel.py */,
-				66FA9B9A155B16B500B6FAC1 /* plistlib.py */,
-				66FA9B9B155B16B500B6FAC1 /* sendfd.py */,
-				66FA9B9C155B16B500B6FAC1 /* sendmsg.c */,
-				66FA9B9D155B16B500B6FAC1 /* test */,
-				66FA9BA4155B16B500B6FAC1 /* vcomponent.py */,
-			);
-			path = python;
-			sourceTree = "<group>";
-		};
-		66FA9B9D155B16B500B6FAC1 /* test */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9B9E155B16B500B6FAC1 /* __init__.py */,
-				66FA9B9F155B16B500B6FAC1 /* pullpipe.py */,
-				66FA9BA0155B16B500B6FAC1 /* test_filepath.py */,
-				66FA9BA1155B16B500B6FAC1 /* test_log.py */,
-				66FA9BA2155B16B500B6FAC1 /* test_parallel.py */,
-				66FA9BA3155B16B500B6FAC1 /* test_sendmsg.py */,
-			);
-			path = test;
-			sourceTree = "<group>";
-		};
-		66FA9BA5155B16B500B6FAC1 /* web2 */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9BA6155B16B500B6FAC1 /* __init__.py */,
-				66FA9BA7155B16B500B6FAC1 /* _version.py */,
-				66FA9BA8155B16B500B6FAC1 /* auth */,
-				66FA9BAE155B16B500B6FAC1 /* channel */,
-				66FA9BB1155B16B500B6FAC1 /* client */,
-				66FA9BB5155B16B500B6FAC1 /* dav */,
-				66FA9BF4155B16B500B6FAC1 /* error.py */,
-				66FA9BF5155B16B500B6FAC1 /* fileupload.py */,
-				66FA9BF6155B16B500B6FAC1 /* filter */,
-				66FA9BFB155B16B500B6FAC1 /* http.py */,
-				66FA9BFC155B16B500B6FAC1 /* http_headers.py */,
-				66FA9BFD155B16B500B6FAC1 /* iweb.py */,
-				66FA9BFE155B16B500B6FAC1 /* log.py */,
-				66FA9BFF155B16B500B6FAC1 /* metafd.py */,
-				66FA9C00155B16B500B6FAC1 /* resource.py */,
-				66FA9C01155B16B500B6FAC1 /* responsecode.py */,
-				66FA9C02155B16B500B6FAC1 /* server.py */,
-				66FA9C03155B16B500B6FAC1 /* static.py */,
-				66FA9C04155B16B500B6FAC1 /* stream.py */,
-				66FA9C05155B16B500B6FAC1 /* test */,
-			);
-			path = web2;
-			sourceTree = "<group>";
-		};
-		66FA9BA8155B16B500B6FAC1 /* auth */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9BA9155B16B500B6FAC1 /* __init__.py */,
-				66FA9BAA155B16B500B6FAC1 /* basic.py */,
-				66FA9BAB155B16B500B6FAC1 /* digest.py */,
-				66FA9BAC155B16B500B6FAC1 /* interfaces.py */,
-				66FA9BAD155B16B500B6FAC1 /* wrapper.py */,
-			);
-			path = auth;
-			sourceTree = "<group>";
-		};
-		66FA9BAE155B16B500B6FAC1 /* channel */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9BAF155B16B500B6FAC1 /* __init__.py */,
-				66FA9BB0155B16B500B6FAC1 /* http.py */,
-			);
-			path = channel;
-			sourceTree = "<group>";
-		};
-		66FA9BB1155B16B500B6FAC1 /* client */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9BB2155B16B500B6FAC1 /* __init__.py */,
-				66FA9BB3155B16B500B6FAC1 /* http.py */,
-				66FA9BB4155B16B500B6FAC1 /* interfaces.py */,
-			);
-			path = client;
-			sourceTree = "<group>";
-		};
-		66FA9BB5155B16B500B6FAC1 /* dav */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9BB6155B16B500B6FAC1 /* __init__.py */,
-				66FA9BB7155B16B500B6FAC1 /* auth.py */,
-				66FA9BB8155B16B500B6FAC1 /* fileop.py */,
-				66FA9BB9155B16B500B6FAC1 /* http.py */,
-				66FA9BBA155B16B500B6FAC1 /* idav.py */,
-				66FA9BBB155B16B500B6FAC1 /* method */,
-				66FA9BCF155B16B500B6FAC1 /* noneprops.py */,
-				66FA9BD0155B16B500B6FAC1 /* resource.py */,
-				66FA9BD1155B16B500B6FAC1 /* static.py */,
-				66FA9BD2155B16B500B6FAC1 /* test */,
-				66FA9BF2155B16B500B6FAC1 /* util.py */,
-				66FA9BF3155B16B500B6FAC1 /* xattrprops.py */,
-			);
-			path = dav;
-			sourceTree = "<group>";
-		};
-		66FA9BBB155B16B500B6FAC1 /* method */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9BBC155B16B500B6FAC1 /* __init__.py */,
-				66FA9BBD155B16B500B6FAC1 /* acl.py */,
-				66FA9BBE155B16B500B6FAC1 /* copymove.py */,
-				66FA9BBF155B16B500B6FAC1 /* delete.py */,
-				66FA9BC0155B16B500B6FAC1 /* delete_common.py */,
-				66FA9BC1155B16B500B6FAC1 /* get.py */,
-				66FA9BC2155B16B500B6FAC1 /* lock.py */,
-				66FA9BC3155B16B500B6FAC1 /* mkcol.py */,
-				66FA9BC4155B16B500B6FAC1 /* prop_common.py */,
-				66FA9BC5155B16B500B6FAC1 /* propfind.py */,
-				66FA9BC6155B16B500B6FAC1 /* proppatch.py */,
-				66FA9BC7155B16B500B6FAC1 /* put.py */,
-				66FA9BC8155B16B500B6FAC1 /* put_common.py */,
-				66FA9BC9155B16B500B6FAC1 /* report.py */,
-				66FA9BCA155B16B500B6FAC1 /* report_acl_principal_prop_set.py */,
-				66FA9BCB155B16B500B6FAC1 /* report_expand.py */,
-				66FA9BCC155B16B500B6FAC1 /* report_principal_match.py */,
-				66FA9BCD155B16B500B6FAC1 /* report_principal_property_search.py */,
-				66FA9BCE155B16B500B6FAC1 /* report_principal_search_property_set.py */,
-			);
-			path = method;
-			sourceTree = "<group>";
-		};
-		66FA9BD2155B16B500B6FAC1 /* test */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9BD3155B16B500B6FAC1 /* __init__.py */,
-				66FA9BD4155B16B500B6FAC1 /* data */,
-				66FA9BDE155B16B500B6FAC1 /* test_acl.py */,
-				66FA9BDF155B16B500B6FAC1 /* test_copy.py */,
-				66FA9BE0155B16B500B6FAC1 /* test_delete.py */,
-				66FA9BE1155B16B500B6FAC1 /* test_http.py */,
-				66FA9BE2155B16B500B6FAC1 /* test_lock.py */,
-				66FA9BE3155B16B500B6FAC1 /* test_mkcol.py */,
-				66FA9BE4155B16B500B6FAC1 /* test_move.py */,
-				66FA9BE5155B16B500B6FAC1 /* test_options.py */,
-				66FA9BE6155B16B500B6FAC1 /* test_pipeline.py */,
-				66FA9BE7155B16B500B6FAC1 /* test_prop.py */,
-				66FA9BE8155B16B500B6FAC1 /* test_put.py */,
-				66FA9BE9155B16B500B6FAC1 /* test_quota.py */,
-				66FA9BEA155B16B500B6FAC1 /* test_report.py */,
-				66FA9BEB155B16B500B6FAC1 /* test_report_expand.py */,
-				66FA9BEC155B16B500B6FAC1 /* test_resource.py */,
-				66FA9BED155B16B500B6FAC1 /* test_static.py */,
-				66FA9BEE155B16B500B6FAC1 /* test_util.py */,
-				66FA9BEF155B16B500B6FAC1 /* test_xattrprops.py */,
-				66FA9BF0155B16B500B6FAC1 /* tworequest_client.py */,
-				66FA9BF1155B16B500B6FAC1 /* util.py */,
-			);
-			path = test;
-			sourceTree = "<group>";
-		};
-		66FA9BD4155B16B500B6FAC1 /* data */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9BD5155B16B500B6FAC1 /* quota_100.txt */,
-				66FA9BD6155B16B500B6FAC1 /* xml */,
-			);
-			path = data;
-			sourceTree = "<group>";
-		};
-		66FA9BD6155B16B500B6FAC1 /* xml */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9BD7155B16B500B6FAC1 /* PROPFIND_bad.xml */,
-				66FA9BD8155B16B500B6FAC1 /* PROPFIND_nonamespace.xml */,
-				66FA9BD9155B16B500B6FAC1 /* PROPFIND_request.xml */,
-				66FA9BDA155B16B500B6FAC1 /* PROPFIND_response.xml */,
-				66FA9BDB155B16B500B6FAC1 /* PROPPATCH_request.xml */,
-				66FA9BDC155B16B500B6FAC1 /* REPORT_request.xml */,
-				66FA9BDD155B16B500B6FAC1 /* REPORT_response.xml */,
-			);
-			path = xml;
-			sourceTree = "<group>";
-		};
-		66FA9BF6155B16B500B6FAC1 /* filter */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9BF7155B16B500B6FAC1 /* __init__.py */,
-				66FA9BF8155B16B500B6FAC1 /* gzip.py */,
-				66FA9BF9155B16B500B6FAC1 /* location.py */,
-				66FA9BFA155B16B500B6FAC1 /* range.py */,
-			);
-			path = filter;
-			sourceTree = "<group>";
-		};
-		66FA9C05155B16B500B6FAC1 /* test */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9C06155B16B500B6FAC1 /* __init__.py */,
-				66FA9C07155B16B500B6FAC1 /* server.pem */,
-				66FA9C08155B16B500B6FAC1 /* simple_client.py */,
-				66FA9C09155B16B500B6FAC1 /* stream_data.txt */,
-				66FA9C0A155B16B500B6FAC1 /* test_client.py */,
-				66FA9C0B155B16B500B6FAC1 /* test_fileupload.py */,
-				66FA9C0C155B16B500B6FAC1 /* test_http.py */,
-				66FA9C0D155B16B500B6FAC1 /* test_http_headers.py */,
-				66FA9C0E155B16B500B6FAC1 /* test_httpauth.py */,
-				66FA9C0F155B16B500B6FAC1 /* test_log.py */,
-				66FA9C10155B16B500B6FAC1 /* test_metafd.py */,
-				66FA9C11155B16B500B6FAC1 /* test_resource.py */,
-				66FA9C12155B16B500B6FAC1 /* test_server.py */,
-				66FA9C13155B16B500B6FAC1 /* test_static.py */,
-				66FA9C14155B16B500B6FAC1 /* test_stream.py */,
-			);
-			path = test;
-			sourceTree = "<group>";
-		};
-		66FA9C15155B16B500B6FAC1 /* twisted */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9C16155B16B500B6FAC1 /* plugins */,
-			);
-			name = twisted;
-			path = ../twisted;
-			sourceTree = "<group>";
-		};
-		66FA9C16155B16B500B6FAC1 /* plugins */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9C17155B16B500B6FAC1 /* caldav.py */,
-				66FA9C18155B16B500B6FAC1 /* kqueuereactor.py */,
-			);
-			path = plugins;
-			sourceTree = "<group>";
-		};
-		66FA9C19155B16B500B6FAC1 /* twistedcaldav */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9C1A155B16B500B6FAC1 /* __init__.py */,
-				66FA9C1B155B16B500B6FAC1 /* accounting.py */,
-				66FA9C1C155B16B500B6FAC1 /* authkerb.py */,
-				66FA9C1D155B16B500B6FAC1 /* backup.py */,
-				66FA9C1E155B16B500B6FAC1 /* bind.py */,
-				66FA9C1F155B16B500B6FAC1 /* cache.py */,
-				66FA9C20155B16B500B6FAC1 /* caldavxml.py */,
-				66FA9C21155B16B500B6FAC1 /* carddavxml.py */,
-				66FA9C22155B16B500B6FAC1 /* client */,
-				66FA9C2A155B16B500B6FAC1 /* config.py */,
-				66FA9C2B155B16B500B6FAC1 /* customxml.py */,
-				66FA9C2C155B16B500B6FAC1 /* database.py */,
-				66FA9C2D155B16B500B6FAC1 /* datafilters */,
-				66FA9C39155B16B500B6FAC1 /* dateops.py */,
-				66FA9C3A155B16B500B6FAC1 /* directory */,
-				66FA9C7D155B16B500B6FAC1 /* directory-listing.html */,
-				66FA9C7E155B16B500B6FAC1 /* directorybackedaddressbook.py */,
-				66FA9C7F155B16B500B6FAC1 /* dropbox.py */,
-				66FA9C80155B16B500B6FAC1 /* extensions.py */,
-				66FA9C81155B16B500B6FAC1 /* freebusyurl.py */,
-				66FA9C82155B16B500B6FAC1 /* ical.py */,
-				66FA9C83155B16B500B6FAC1 /* icaldav.py */,
-				66FA9C84155B16B500B6FAC1 /* images */,
-				66FA9C87155B16B500B6FAC1 /* instance.py */,
-				66FA9C88155B16B500B6FAC1 /* linkresource.py */,
-				66FA9C89155B16B500B6FAC1 /* localization.py */,
-				66FA9C8A155B16B500B6FAC1 /* mail.py */,
-				66FA9C8B155B16B500B6FAC1 /* memcachelock.py */,
-				66FA9C8C155B16B500B6FAC1 /* memcachepool.py */,
-				66FA9C8D155B16B500B6FAC1 /* memcacheprops.py */,
-				66FA9C8E155B16B500B6FAC1 /* memcacher.py */,
-				66FA9C8F155B16B500B6FAC1 /* method */,
-				66FA9CA7155B16B600B6FAC1 /* mkcolxml.py */,
-				66FA9CA8155B16B600B6FAC1 /* notifications.py */,
-				66FA9CA9155B16B600B6FAC1 /* notify.py */,
-				66FA9CAA155B16B600B6FAC1 /* query */,
-				66FA9CB8155B16B600B6FAC1 /* resource.py */,
-				66FA9CB9155B16B600B6FAC1 /* schedule.py */,
-				66FA9CBA155B16B600B6FAC1 /* scheduling */,
-				66FA9CD0155B16B600B6FAC1 /* servers.py */,
-				66FA9CD1155B16B600B6FAC1 /* sharedcollection.py */,
-				66FA9CD2155B16B600B6FAC1 /* sharing.py */,
-				66FA9CD3155B16B600B6FAC1 /* simpleresource.py */,
-				66FA9CD4155B16B600B6FAC1 /* sql.py */,
-				66FA9CD5155B16B600B6FAC1 /* stdconfig.py */,
-				66FA9CD6155B16B600B6FAC1 /* storebridge.py */,
-				66FA9CD7155B16B600B6FAC1 /* test */,
-				66FA9D75155B16B600B6FAC1 /* timezones.py */,
-				66FA9D76155B16B600B6FAC1 /* timezoneservice.py */,
-				66FA9D77155B16B600B6FAC1 /* timezonestdservice.py */,
-				66FA9D78155B16B600B6FAC1 /* timezonexml.py */,
-				66FA9D79155B16B600B6FAC1 /* upgrade.py */,
-				66FA9D7A155B16B600B6FAC1 /* util.py */,
-				66FA9D7B155B16B600B6FAC1 /* vcard.py */,
-				66FA9D7C155B16B600B6FAC1 /* xmlutil.py */,
-				66FA9D7D155B16B600B6FAC1 /* zoneinfo */,
-			);
-			name = twistedcaldav;
-			path = ../twistedcaldav;
-			sourceTree = "<group>";
-		};
-		66FA9C22155B16B500B6FAC1 /* client */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9C23155B16B500B6FAC1 /* __init__.py */,
-				66FA9C24155B16B500B6FAC1 /* geturl.py */,
-				66FA9C25155B16B500B6FAC1 /* pool.py */,
-				66FA9C26155B16B500B6FAC1 /* reverseproxy.py */,
-				66FA9C27155B16B500B6FAC1 /* test */,
-			);
-			path = client;
-			sourceTree = "<group>";
-		};
-		66FA9C27155B16B500B6FAC1 /* test */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9C28155B16B500B6FAC1 /* __init__.py */,
-				66FA9C29155B16B500B6FAC1 /* test_reverseproxy.py */,
-			);
-			path = test;
-			sourceTree = "<group>";
-		};
-		66FA9C2D155B16B500B6FAC1 /* datafilters */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9C2E155B16B500B6FAC1 /* __init__.py */,
-				66FA9C2F155B16B500B6FAC1 /* addressdata.py */,
-				66FA9C30155B16B500B6FAC1 /* calendardata.py */,
-				66FA9C31155B16B500B6FAC1 /* filter.py */,
-				66FA9C32155B16B500B6FAC1 /* peruserdata.py */,
-				66FA9C33155B16B500B6FAC1 /* privateevents.py */,
-				66FA9C34155B16B500B6FAC1 /* test */,
-			);
-			path = datafilters;
-			sourceTree = "<group>";
-		};
-		66FA9C34155B16B500B6FAC1 /* test */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9C35155B16B500B6FAC1 /* __init__.py */,
-				66FA9C36155B16B500B6FAC1 /* test_calendardata.py */,
-				66FA9C37155B16B500B6FAC1 /* test_peruserdata.py */,
-				66FA9C38155B16B500B6FAC1 /* test_privateevents.py */,
-			);
-			path = test;
-			sourceTree = "<group>";
-		};
-		66FA9C3A155B16B500B6FAC1 /* directory */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9C3B155B16B500B6FAC1 /* __init__.py */,
-				66FA9C3C155B16B500B6FAC1 /* addressbook.py */,
-				66FA9C3D155B16B500B6FAC1 /* aggregate.py */,
-				66FA9C3E155B16B500B6FAC1 /* appleopendirectory.py */,
-				66FA9C3F155B16B500B6FAC1 /* augment.py */,
-				66FA9C40155B16B500B6FAC1 /* cachingdirectory.py */,
-				66FA9C41155B16B500B6FAC1 /* calendar-user-proxy-principal-resource.html */,
-				66FA9C42155B16B500B6FAC1 /* calendar.py */,
-				66FA9C43155B16B500B6FAC1 /* calendaruserproxy.py */,
-				66FA9C44155B16B500B6FAC1 /* calendaruserproxyloader.py */,
-				66FA9C45155B16B500B6FAC1 /* common.py */,
-				66FA9C46155B16B500B6FAC1 /* digest.py */,
-				66FA9C47155B16B500B6FAC1 /* directory-principal-resource.html */,
-				66FA9C48155B16B500B6FAC1 /* directory.py */,
-				66FA9C49155B16B500B6FAC1 /* idirectory.py */,
-				66FA9C4A155B16B500B6FAC1 /* internal.py */,
-				66FA9C4B155B16B500B6FAC1 /* ldapdirectory.py */,
-				66FA9C4C155B16B500B6FAC1 /* opendirectorybacker.py */,
-				66FA9C4D155B16B500B6FAC1 /* principal.py */,
-				66FA9C4E155B16B500B6FAC1 /* resource.py */,
-				66FA9C4F155B16B500B6FAC1 /* resourceinfo.py */,
-				66FA9C50155B16B500B6FAC1 /* test */,
-				66FA9C78155B16B500B6FAC1 /* util.py */,
-				66FA9C79155B16B500B6FAC1 /* wiki.py */,
-				66FA9C7A155B16B500B6FAC1 /* xmlaccountsparser.py */,
-				66FA9C7B155B16B500B6FAC1 /* xmlaugmentsparser.py */,
-				66FA9C7C155B16B500B6FAC1 /* xmlfile.py */,
-			);
-			path = directory;
-			sourceTree = "<group>";
-		};
-		66FA9C50155B16B500B6FAC1 /* test */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9C51155B16B500B6FAC1 /* __init__.py */,
-				66FA9C52155B16B500B6FAC1 /* accounts.xml */,
-				66FA9C53155B16B500B6FAC1 /* augments-test-default.xml */,
-				66FA9C54155B16B500B6FAC1 /* augments-test.xml */,
-				66FA9C55155B16B500B6FAC1 /* augments.xml */,
-				66FA9C56155B16B500B6FAC1 /* modify */,
-				66FA9C5A155B16B500B6FAC1 /* proxies.xml */,
-				66FA9C5B155B16B500B6FAC1 /* resources */,
-				66FA9C60155B16B500B6FAC1 /* resources.xml */,
-				66FA9C61155B16B500B6FAC1 /* sudoers.plist */,
-				66FA9C62155B16B500B6FAC1 /* sudoers2.plist */,
-				66FA9C63155B16B500B6FAC1 /* test_aggregate.py */,
-				66FA9C64155B16B500B6FAC1 /* test_augment.py */,
-				66FA9C65155B16B500B6FAC1 /* test_buildquery.py */,
-				66FA9C66155B16B500B6FAC1 /* test_cachedirectory.py */,
-				66FA9C67155B16B500B6FAC1 /* test_calendar.py */,
-				66FA9C68155B16B500B6FAC1 /* test_digest.py */,
-				66FA9C69155B16B500B6FAC1 /* test_directory.py */,
-				66FA9C6A155B16B500B6FAC1 /* test_guidchange.py */,
-				66FA9C6B155B16B500B6FAC1 /* test_ldapdirectory.py */,
-				66FA9C6C155B16B500B6FAC1 /* test_livedirectory.py */,
-				66FA9C6D155B16B500B6FAC1 /* test_modify.py */,
-				66FA9C6E155B16B500B6FAC1 /* test_opendirectory.py */,
-				66FA9C6F155B16B500B6FAC1 /* test_opendirectorybacker.py */,
-				66FA9C70155B16B500B6FAC1 /* test_principal.py */,
-				66FA9C71155B16B500B6FAC1 /* test_proxyprincipaldb.py */,
-				66FA9C72155B16B500B6FAC1 /* test_proxyprincipalmembers.py */,
-				66FA9C73155B16B500B6FAC1 /* test_resources.py */,
-				66FA9C74155B16B500B6FAC1 /* test_util.py */,
-				66FA9C75155B16B500B6FAC1 /* test_wiki.py */,
-				66FA9C76155B16B500B6FAC1 /* test_xmlfile.py */,
-				66FA9C77155B16B500B6FAC1 /* util.py */,
-			);
-			path = test;
-			sourceTree = "<group>";
-		};
-		66FA9C56155B16B500B6FAC1 /* modify */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9C57155B16B500B6FAC1 /* augments.xml */,
-				66FA9C58155B16B500B6FAC1 /* resources-locations.xml */,
-				66FA9C59155B16B500B6FAC1 /* users-groups.xml */,
-			);
-			path = modify;
-			sourceTree = "<group>";
-		};
-		66FA9C5B155B16B500B6FAC1 /* resources */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9C5C155B16B500B6FAC1 /* augments.xml */,
-				66FA9C5D155B16B500B6FAC1 /* caldavd.plist */,
-				66FA9C5E155B16B500B6FAC1 /* resources-locations.xml */,
-				66FA9C5F155B16B500B6FAC1 /* users-groups.xml */,
-			);
-			path = resources;
-			sourceTree = "<group>";
-		};
-		66FA9C84155B16B500B6FAC1 /* images */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9C85155B16B500B6FAC1 /* mail */,
-			);
-			path = images;
-			sourceTree = "<group>";
-		};
-		66FA9C85155B16B500B6FAC1 /* mail */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9C86155B16B500B6FAC1 /* ical.jpg */,
-			);
-			path = mail;
-			sourceTree = "<group>";
-		};
-		66FA9C8F155B16B500B6FAC1 /* method */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9C90155B16B500B6FAC1 /* __init__.py */,
-				66FA9C91155B16B500B6FAC1 /* acl.py */,
-				66FA9C92155B16B500B6FAC1 /* copymove.py */,
-				66FA9C93155B16B500B6FAC1 /* copymove_contact.py */,
-				66FA9C94155B16B500B6FAC1 /* delete.py */,
-				66FA9C95155B16B500B6FAC1 /* delete_common.py */,
-				66FA9C96155B16B500B6FAC1 /* get.py */,
-				66FA9C97155B16B500B6FAC1 /* mkcalendar.py */,
-				66FA9C98155B16B500B6FAC1 /* mkcol.py */,
-				66FA9C99155B16B500B6FAC1 /* post.py */,
-				66FA9C9A155B16B500B6FAC1 /* propfind.py */,
-				66FA9C9B155B16B500B6FAC1 /* put.py */,
-				66FA9C9C155B16B500B6FAC1 /* put_addressbook_common.py */,
-				66FA9C9D155B16B500B6FAC1 /* put_common.py */,
-				66FA9C9E155B16B500B6FAC1 /* report.py */,
-				66FA9C9F155B16B500B6FAC1 /* report_addressbook_multiget.py */,
-				66FA9CA0155B16B600B6FAC1 /* report_addressbook_query.py */,
-				66FA9CA1155B16B600B6FAC1 /* report_calendar_multiget.py */,
-				66FA9CA2155B16B600B6FAC1 /* report_calendar_query.py */,
-				66FA9CA3155B16B600B6FAC1 /* report_common.py */,
-				66FA9CA4155B16B600B6FAC1 /* report_freebusy.py */,
-				66FA9CA5155B16B600B6FAC1 /* report_multiget_common.py */,
-				66FA9CA6155B16B600B6FAC1 /* report_sync_collection.py */,
-			);
-			path = method;
-			sourceTree = "<group>";
-		};
-		66FA9CAA155B16B600B6FAC1 /* query */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9CAB155B16B600B6FAC1 /* __init__.py */,
-				66FA9CAC155B16B600B6FAC1 /* addressbookquery.py */,
-				66FA9CAD155B16B600B6FAC1 /* addressbookqueryfilter.py */,
-				66FA9CAE155B16B600B6FAC1 /* calendarquery.py */,
-				66FA9CAF155B16B600B6FAC1 /* calendarqueryfilter.py */,
-				66FA9CB0155B16B600B6FAC1 /* expression.py */,
-				66FA9CB1155B16B600B6FAC1 /* sqlgenerator.py */,
-				66FA9CB2155B16B600B6FAC1 /* test */,
-			);
-			path = query;
-			sourceTree = "<group>";
-		};
-		66FA9CB2155B16B600B6FAC1 /* test */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9CB3155B16B600B6FAC1 /* __init__.py */,
-				66FA9CB4155B16B600B6FAC1 /* test_addressbookquery.py */,
-				66FA9CB5155B16B600B6FAC1 /* test_calendarquery.py */,
-				66FA9CB6155B16B600B6FAC1 /* test_expression.py */,
-				66FA9CB7155B16B600B6FAC1 /* test_queryfilter.py */,
-			);
-			path = test;
-			sourceTree = "<group>";
-		};
-		66FA9CBA155B16B600B6FAC1 /* scheduling */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9CBB155B16B600B6FAC1 /* __init__.py */,
-				66FA9CBC155B16B600B6FAC1 /* addressmapping.py */,
-				66FA9CBD155B16B600B6FAC1 /* caldav.py */,
-				66FA9CBE155B16B600B6FAC1 /* cuaddress.py */,
-				66FA9CBF155B16B600B6FAC1 /* delivery.py */,
-				66FA9CC0155B16B600B6FAC1 /* icaldiff.py */,
-				66FA9CC1155B16B600B6FAC1 /* imip.py */,
-				66FA9CC2155B16B600B6FAC1 /* implicit.py */,
-				66FA9CC3155B16B600B6FAC1 /* ischedule.py */,
-				66FA9CC4155B16B600B6FAC1 /* ischeduleservers.py */,
-				66FA9CC5155B16B600B6FAC1 /* itip.py */,
-				66FA9CC6155B16B600B6FAC1 /* processing.py */,
-				66FA9CC7155B16B600B6FAC1 /* scheduler.py */,
-				66FA9CC8155B16B600B6FAC1 /* test */,
-				66FA9CCF155B16B600B6FAC1 /* utils.py */,
-			);
-			path = scheduling;
-			sourceTree = "<group>";
-		};
-		66FA9CC8155B16B600B6FAC1 /* test */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9CC9155B16B600B6FAC1 /* __init__.py */,
-				66FA9CCA155B16B600B6FAC1 /* test_caldav.py */,
-				66FA9CCB155B16B600B6FAC1 /* test_icaldiff.py */,
-				66FA9CCC155B16B600B6FAC1 /* test_imip.py */,
-				66FA9CCD155B16B600B6FAC1 /* test_implicit.py */,
-				66FA9CCE155B16B600B6FAC1 /* test_itip.py */,
-			);
-			path = test;
-			sourceTree = "<group>";
-		};
-		66FA9CD7155B16B600B6FAC1 /* test */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9CD8155B16B600B6FAC1 /* __init__.py */,
-				66FA9CD9155B16B600B6FAC1 /* data */,
-				66FA9D4C155B16B600B6FAC1 /* test_accounting.py */,
-				66FA9D4D155B16B600B6FAC1 /* test_addressbookmultiget.py */,
-				66FA9D4E155B16B600B6FAC1 /* test_addressbookquery.py */,
-				66FA9D4F155B16B600B6FAC1 /* test_cache.py */,
-				66FA9D50155B16B600B6FAC1 /* test_caldavxml.py */,
-				66FA9D51155B16B600B6FAC1 /* test_calendarquery.py */,
-				66FA9D52155B16B600B6FAC1 /* test_collectioncontents.py */,
-				66FA9D53155B16B600B6FAC1 /* test_config.py */,
-				66FA9D54155B16B600B6FAC1 /* test_customxml.py */,
-				66FA9D55155B16B600B6FAC1 /* test_database.py */,
-				66FA9D56155B16B600B6FAC1 /* test_dateops.py */,
-				66FA9D57155B16B600B6FAC1 /* test_extensions.py */,
-				66FA9D58155B16B600B6FAC1 /* test_freebusyquery.py */,
-				66FA9D59155B16B600B6FAC1 /* test_icalendar.py */,
-				66FA9D5A155B16B600B6FAC1 /* test_kerberos.py */,
-				66FA9D5B155B16B600B6FAC1 /* test_link.py */,
-				66FA9D5C155B16B600B6FAC1 /* test_localization.py */,
-				66FA9D5D155B16B600B6FAC1 /* test_mail.py */,
-				66FA9D5E155B16B600B6FAC1 /* test_memcachelock.py */,
-				66FA9D5F155B16B600B6FAC1 /* test_memcachepool.py */,
-				66FA9D60155B16B600B6FAC1 /* test_memcacheprops.py */,
-				66FA9D61155B16B600B6FAC1 /* test_memcacher.py */,
-				66FA9D62155B16B600B6FAC1 /* test_mkcalendar.py */,
-				66FA9D63155B16B600B6FAC1 /* test_multiget.py */,
-				66FA9D64155B16B600B6FAC1 /* test_notify.py */,
-				66FA9D65155B16B600B6FAC1 /* test_options.py */,
-				66FA9D66155B16B600B6FAC1 /* test_props.py */,
-				66FA9D67155B16B600B6FAC1 /* test_resource.py */,
-				66FA9D68155B16B600B6FAC1 /* test_schedule.py */,
-				66FA9D69155B16B600B6FAC1 /* test_servers.py */,
-				66FA9D6A155B16B600B6FAC1 /* test_sharing.py */,
-				66FA9D6B155B16B600B6FAC1 /* test_sql.py */,
-				66FA9D6C155B16B600B6FAC1 /* test_stdconfig.py */,
-				66FA9D6D155B16B600B6FAC1 /* test_timezones.py */,
-				66FA9D6E155B16B600B6FAC1 /* test_timezonestdservice.py */,
-				66FA9D6F155B16B600B6FAC1 /* test_upgrade.py */,
-				66FA9D70155B16B600B6FAC1 /* test_validation.py */,
-				66FA9D71155B16B600B6FAC1 /* test_wrapping.py */,
-				66FA9D72155B16B600B6FAC1 /* test_xml.py */,
-				66FA9D73155B16B600B6FAC1 /* test_xmlutil.py */,
-				66FA9D74155B16B600B6FAC1 /* util.py */,
-			);
-			path = test;
-			sourceTree = "<group>";
-		};
-		66FA9CD9155B16B600B6FAC1 /* data */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9CDA155B16B600B6FAC1 /* 2445AllExamples.ics */,
-				66FA9CDB155B16B600B6FAC1 /* 2445AllExamples.txt */,
-				66FA9CDC155B16B600B6FAC1 /* AnotherEvent.ics */,
-				66FA9CDD155B16B600B6FAC1 /* calendar.10.tgz */,
-				66FA9CDE155B16B600B6FAC1 /* calendar.100.tgz */,
-				66FA9CDF155B16B600B6FAC1 /* calendar.1000.tgz */,
-				66FA9CE0155B16B600B6FAC1 /* csv2ical.py */,
-				66FA9CE1155B16B600B6FAC1 /* Holidays */,
-				66FA9D11155B16B600B6FAC1 /* Holidays.ics */,
-				66FA9D12155B16B600B6FAC1 /* locales */,
-				66FA9D1B155B16B600B6FAC1 /* mail */,
-				66FA9D23155B16B600B6FAC1 /* makelargecalendars.py */,
-				66FA9D24155B16B600B6FAC1 /* makelargefbset.py */,
-				66FA9D25155B16B600B6FAC1 /* OneEvent.ics */,
-				66FA9D26155B16B600B6FAC1 /* PayDay.ics */,
-				66FA9D27155B16B600B6FAC1 /* PayDay.txt */,
-				66FA9D28155B16B600B6FAC1 /* recurrance */,
-				66FA9D3C155B16B600B6FAC1 /* server.pem */,
-				66FA9D3D155B16B600B6FAC1 /* split_holidays.py */,
-				66FA9D3E155B16B600B6FAC1 /* ThirdEvent.ics */,
-				66FA9D3F155B16B600B6FAC1 /* TruncatedApr01.ics */,
-				66FA9D40155B16B600B6FAC1 /* TruncatedDec10.ics */,
-				66FA9D41155B16B600B6FAC1 /* vCards */,
-			);
-			path = data;
-			sourceTree = "<group>";
-		};
-		66FA9CE1155B16B600B6FAC1 /* Holidays */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9CE2155B16B600B6FAC1 /* C3184A66-1ED0-11D9-A5E0-000A958A3252.ics */,
-				66FA9CE3155B16B600B6FAC1 /* C3184D26-1ED0-11D9-A5E0-000A958A3252.ics */,
-				66FA9CE4155B16B600B6FAC1 /* C3185326-1ED0-11D9-A5E0-000A958A3252.ics */,
-				66FA9CE5155B16B600B6FAC1 /* C31854DA-1ED0-11D9-A5E0-000A958A3252.ics */,
-				66FA9CE6155B16B600B6FAC1 /* C31856AC-1ED0-11D9-A5E0-000A958A3252.ics */,
-				66FA9CE7155B16B600B6FAC1 /* C318585A-1ED0-11D9-A5E0-000A958A3252.ics */,
-				66FA9CE8155B16B600B6FAC1 /* C3185A14-1ED0-11D9-A5E0-000A958A3252.ics */,
-				66FA9CE9155B16B600B6FAC1 /* C3185BBD-1ED0-11D9-A5E0-000A958A3252.ics */,
-				66FA9CEA155B16B600B6FAC1 /* C3185D63-1ED0-11D9-A5E0-000A958A3252.ics */,
-				66FA9CEB155B16B600B6FAC1 /* C3185F20-1ED0-11D9-A5E0-000A958A3252.ics */,
-				66FA9CEC155B16B600B6FAC1 /* C31860C8-1ED0-11D9-A5E0-000A958A3252.ics */,
-				66FA9CED155B16B600B6FAC1 /* C318627C-1ED0-11D9-A5E0-000A958A3252.ics */,
-				66FA9CEE155B16B600B6FAC1 /* C3186426-1ED0-11D9-A5E0-000A958A3252.ics */,
-				66FA9CEF155B16B600B6FAC1 /* C31865E4-1ED0-11D9-A5E0-000A958A3252.ics */,
-				66FA9CF0155B16B600B6FAC1 /* C3186792-1ED0-11D9-A5E0-000A958A3252.ics */,
-				66FA9CF1155B16B600B6FAC1 /* C3186938-1ED0-11D9-A5E0-000A958A3252.ics */,
-				66FA9CF2155B16B600B6FAC1 /* C3186ADE-1ED0-11D9-A5E0-000A958A3252.ics */,
-				66FA9CF3155B16B600B6FAC1 /* C3186C96-1ED0-11D9-A5E0-000A958A3252.ics */,
-				66FA9CF4155B16B600B6FAC1 /* C3186E3A-1ED0-11D9-A5E0-000A958A3252.ics */,
-				66FA9CF5155B16B600B6FAC1 /* C3186FE7-1ED0-11D9-A5E0-000A958A3252.ics */,
-				66FA9CF6155B16B600B6FAC1 /* C318719A-1ED0-11D9-A5E0-000A958A3252.ics */,
-				66FA9CF7155B16B600B6FAC1 /* C3187343-1ED0-11D9-A5E0-000A958A3252.ics */,
-				66FA9CF8155B16B600B6FAC1 /* C3188906-1ED0-11D9-A5E0-000A958A3252.ics */,
-				66FA9CF9155B16B600B6FAC1 /* C3188B3A-1ED0-11D9-A5E0-000A958A3252.ics */,
-				66FA9CFA155B16B600B6FAC1 /* C3188CFF-1ED0-11D9-A5E0-000A958A3252.ics */,
-				66FA9CFB155B16B600B6FAC1 /* C3188EAA-1ED0-11D9-A5E0-000A958A3252.ics */,
-				66FA9CFC155B16B600B6FAC1 /* C3189058-1ED0-11D9-A5E0-000A958A3252.ics */,
-				66FA9CFD155B16B600B6FAC1 /* C3189203-1ED0-11D9-A5E0-000A958A3252.ics */,
-				66FA9CFE155B16B600B6FAC1 /* C31893C2-1ED0-11D9-A5E0-000A958A3252.ics */,
-				66FA9CFF155B16B600B6FAC1 /* C3189572-1ED0-11D9-A5E0-000A958A3252.ics */,
-				66FA9D00155B16B600B6FAC1 /* C3189716-1ED0-11D9-A5E0-000A958A3252.ics */,
-				66FA9D01155B16B600B6FAC1 /* C31898D4-1ED0-11D9-A5E0-000A958A3252.ics */,
-				66FA9D02155B16B600B6FAC1 /* C3189A88-1ED0-11D9-A5E0-000A958A3252.ics */,
-				66FA9D03155B16B600B6FAC1 /* C3189C32-1ED0-11D9-A5E0-000A958A3252.ics */,
-				66FA9D04155B16B600B6FAC1 /* C3189DEC-1ED0-11D9-A5E0-000A958A3252.ics */,
-				66FA9D05155B16B600B6FAC1 /* C3189F94-1ED0-11D9-A5E0-000A958A3252.ics */,
-				66FA9D06155B16B600B6FAC1 /* C318A148-1ED0-11D9-A5E0-000A958A3252.ics */,
-				66FA9D07155B16B600B6FAC1 /* C318A2F3-1ED0-11D9-A5E0-000A958A3252.ics */,
-				66FA9D08155B16B600B6FAC1 /* C318A4BA-1ED0-11D9-A5E0-000A958A3252.ics */,
-				66FA9D09155B16B600B6FAC1 /* C318A6E1-1ED0-11D9-A5E0-000A958A3252.ics */,
-				66FA9D0A155B16B600B6FAC1 /* C318A898-1ED0-11D9-A5E0-000A958A3252.ics */,
-				66FA9D0B155B16B600B6FAC1 /* C318AA54-1ED0-11D9-A5E0-000A958A3252.ics */,
-				66FA9D0C155B16B600B6FAC1 /* C318ABFE-1ED0-11D9-A5E0-000A958A3252.ics */,
-				66FA9D0D155B16B600B6FAC1 /* C318ADAA-1ED0-11D9-A5E0-000A958A3252.ics */,
-				66FA9D0E155B16B600B6FAC1 /* C318AF53-1ED0-11D9-A5E0-000A958A3252.ics */,
-				66FA9D0F155B16B600B6FAC1 /* C318B108-1ED0-11D9-A5E0-000A958A3252.ics */,
-				66FA9D10155B16B600B6FAC1 /* C318B2D2-1ED0-11D9-A5E0-000A958A3252.ics */,
-			);
-			path = Holidays;
-			sourceTree = "<group>";
-		};
-		66FA9D12155B16B600B6FAC1 /* locales */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9D13155B16B600B6FAC1 /* en */,
-				66FA9D17155B16B600B6FAC1 /* pig */,
-			);
-			path = locales;
-			sourceTree = "<group>";
-		};
-		66FA9D13155B16B600B6FAC1 /* en */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9D14155B16B600B6FAC1 /* LC_MESSAGES */,
-			);
-			path = en;
-			sourceTree = "<group>";
-		};
-		66FA9D14155B16B600B6FAC1 /* LC_MESSAGES */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9D15155B16B600B6FAC1 /* calendarserver.mo */,
-				66FA9D16155B16B600B6FAC1 /* calendarserver.po */,
-			);
-			path = LC_MESSAGES;
-			sourceTree = "<group>";
-		};
-		66FA9D17155B16B600B6FAC1 /* pig */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9D18155B16B600B6FAC1 /* LC_MESSAGES */,
-			);
-			path = pig;
-			sourceTree = "<group>";
-		};
-		66FA9D18155B16B600B6FAC1 /* LC_MESSAGES */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9D19155B16B600B6FAC1 /* calendarserver.mo */,
-				66FA9D1A155B16B600B6FAC1 /* calendarserver.po */,
-			);
-			path = LC_MESSAGES;
-			sourceTree = "<group>";
-		};
-		66FA9D1B155B16B600B6FAC1 /* mail */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9D1C155B16B600B6FAC1 /* dsn_failure_no_ics */,
-				66FA9D1D155B16B600B6FAC1 /* dsn_failure_no_original */,
-				66FA9D1E155B16B600B6FAC1 /* dsn_failure_with_ics */,
-				66FA9D1F155B16B600B6FAC1 /* good_reply */,
-				66FA9D20155B16B600B6FAC1 /* reply_missing_attachment */,
-				66FA9D21155B16B600B6FAC1 /* reply_missing_attendee */,
-				66FA9D22155B16B600B6FAC1 /* reply_missing_organizer */,
-			);
-			path = mail;
-			sourceTree = "<group>";
-		};
-		66FA9D28155B16B600B6FAC1 /* recurrance */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9D29155B16B600B6FAC1 /* README */,
-				66FA9D2A155B16B600B6FAC1 /* Test-01A.ics */,
-				66FA9D2B155B16B600B6FAC1 /* Test-01A.txt */,
-				66FA9D2C155B16B600B6FAC1 /* Test-01B.ics */,
-				66FA9D2D155B16B600B6FAC1 /* Test-01B.txt */,
-				66FA9D2E155B16B600B6FAC1 /* Test-02A.ics */,
-				66FA9D2F155B16B600B6FAC1 /* Test-02A.txt */,
-				66FA9D30155B16B600B6FAC1 /* Test-02B.ics */,
-				66FA9D31155B16B600B6FAC1 /* Test-02B.txt */,
-				66FA9D32155B16B600B6FAC1 /* Test-03A.ics */,
-				66FA9D33155B16B600B6FAC1 /* Test-03A.txt */,
-				66FA9D34155B16B600B6FAC1 /* Test-03B.ics */,
-				66FA9D35155B16B600B6FAC1 /* Test-03B.txt */,
-				66FA9D36155B16B600B6FAC1 /* Test-03C.ics */,
-				66FA9D37155B16B600B6FAC1 /* Test-03C.txt */,
-				66FA9D38155B16B600B6FAC1 /* Test-03D.ics */,
-				66FA9D39155B16B600B6FAC1 /* Test-03D.txt */,
-				66FA9D3A155B16B600B6FAC1 /* Test-03E.ics */,
-				66FA9D3B155B16B600B6FAC1 /* Test-03E.txt */,
-			);
-			path = recurrance;
-			sourceTree = "<group>";
-		};
-		66FA9D41155B16B600B6FAC1 /* vCards */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9D42155B16B600B6FAC1 /* 3765A955-1B96-41EA-994D-335192BEDCCD.vcf */,
-				66FA9D43155B16B600B6FAC1 /* 44745975-AE6D-4FB0-80A6-A298427E047A.vcf */,
-				66FA9D44155B16B600B6FAC1 /* 44EE78BF-8814-4471-899C-92280CEFB098.vcf */,
-				66FA9D45155B16B600B6FAC1 /* 8424B7F0-C878-4722-B522-EBB07CF48AD7.vcf */,
-				66FA9D46155B16B600B6FAC1 /* 934731C6-1C95-4C40-BE1F-FA4215B2307B.vcf */,
-				66FA9D47155B16B600B6FAC1 /* AFBB77B8-0438-4825-A1DB-A75D76B6C3A8.vcf */,
-				66FA9D48155B16B600B6FAC1 /* ED7A5AEC-AB19-4CE0-AD6A-2923A3E5C4E1.vcf */,
-				66FA9D49155B16B600B6FAC1 /* ED7A5AEC-AB19-4CE0-AD6A-2923A3E5C4E2.vcf */,
-				66FA9D4A155B16B600B6FAC1 /* F0A6918D-8E09-43FA-9684-226810B8A96F.vcf */,
-				66FA9D4B155B16B600B6FAC1 /* FCBA0FA3-00B2-4C95-B4EC-4CCC4843F8B1.vcf */,
-			);
-			path = vCards;
-			sourceTree = "<group>";
-		};
-		66FA9D7D155B16B600B6FAC1 /* zoneinfo */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9D7E155B16B600B6FAC1 /* Africa */,
-				66FA9DB5155B16B600B6FAC1 /* America */,
-				66FA9E5D155B16B600B6FAC1 /* Antarctica */,
-				66FA9E69155B16B600B6FAC1 /* Arctic */,
-				66FA9E6B155B16B600B6FAC1 /* Asia */,
-				66FA9EC5155B16B600B6FAC1 /* Atlantic */,
-				66FA9ED2155B16B600B6FAC1 /* Australia */,
-				66FA9EEA155B16B600B6FAC1 /* Brazil */,
-				66FA9EEF155B16B600B6FAC1 /* Canada */,
-				66FA9EF9155B16B600B6FAC1 /* CET.ics */,
-				66FA9EFA155B16B600B6FAC1 /* Chile */,
-				66FA9EFD155B16B600B6FAC1 /* CST6CDT.ics */,
-				66FA9EFE155B16B600B6FAC1 /* Cuba.ics */,
-				66FA9EFF155B16B600B6FAC1 /* EET.ics */,
-				66FA9F00155B16B600B6FAC1 /* Egypt.ics */,
-				66FA9F01155B16B600B6FAC1 /* Eire.ics */,
-				66FA9F02155B16B600B6FAC1 /* EST.ics */,
-				66FA9F03155B16B600B6FAC1 /* EST5EDT.ics */,
-				66FA9F04155B16B600B6FAC1 /* Etc */,
-				66FA9F28155B16B600B6FAC1 /* Europe */,
-				66FA9F63155B16B600B6FAC1 /* GB-Eire.ics */,
-				66FA9F64155B16B600B6FAC1 /* GB.ics */,
-				66FA9F65155B16B600B6FAC1 /* GMT+0.ics */,
-				66FA9F66155B16B600B6FAC1 /* GMT-0.ics */,
-				66FA9F67155B16B600B6FAC1 /* GMT.ics */,
-				66FA9F68155B16B600B6FAC1 /* GMT0.ics */,
-				66FA9F69155B16B600B6FAC1 /* Greenwich.ics */,
-				66FA9F6A155B16B600B6FAC1 /* Hongkong.ics */,
-				66FA9F6B155B16B600B6FAC1 /* HST.ics */,
-				66FA9F6C155B16B600B6FAC1 /* Iceland.ics */,
-				66FA9F6D155B16B600B6FAC1 /* Indian */,
-				66FA9F79155B16B600B6FAC1 /* Iran.ics */,
-				66FA9F7A155B16B600B6FAC1 /* Israel.ics */,
-				66FA9F7B155B16B600B6FAC1 /* Jamaica.ics */,
-				66FA9F7C155B16B600B6FAC1 /* Japan.ics */,
-				66FA9F7D155B16B600B6FAC1 /* Kwajalein.ics */,
-				66FA9F7E155B16B600B6FAC1 /* Libya.ics */,
-				66FA9F7F155B16B600B6FAC1 /* links.txt */,
-				66FA9F80155B16B600B6FAC1 /* MET.ics */,
-				66FA9F81155B16B600B6FAC1 /* Mexico */,
-				66FA9F85155B16B600B6FAC1 /* MST.ics */,
-				66FA9F86155B16B600B6FAC1 /* MST7MDT.ics */,
-				66FA9F87155B16B600B6FAC1 /* Navajo.ics */,
-				66FA9F88155B16B600B6FAC1 /* NZ-CHAT.ics */,
-				66FA9F89155B16B600B6FAC1 /* NZ.ics */,
-				66FA9F8A155B16B600B6FAC1 /* Pacific */,
-				66FA9FB5155B16B600B6FAC1 /* Poland.ics */,
-				66FA9FB6155B16B600B6FAC1 /* Portugal.ics */,
-				66FA9FB7155B16B600B6FAC1 /* PRC.ics */,
-				66FA9FB8155B16B600B6FAC1 /* PST8PDT.ics */,
-				66FA9FB9155B16B600B6FAC1 /* ROC.ics */,
-				66FA9FBA155B16B600B6FAC1 /* ROK.ics */,
-				66FA9FBB155B16B600B6FAC1 /* Singapore.ics */,
-				66FA9FBC155B16B600B6FAC1 /* timezones.xml */,
-				66FA9FBD155B16B600B6FAC1 /* Turkey.ics */,
-				66FA9FBE155B16B600B6FAC1 /* UCT.ics */,
-				66FA9FBF155B16B600B6FAC1 /* Universal.ics */,
-				66FA9FC0155B16B600B6FAC1 /* US */,
-				66FA9FCD155B16B600B6FAC1 /* UTC.ics */,
-				66FA9FCE155B16B600B6FAC1 /* version.txt */,
-				66FA9FCF155B16B600B6FAC1 /* W-SU.ics */,
-				66FA9FD0155B16B600B6FAC1 /* WET.ics */,
-				66FA9FD1155B16B600B6FAC1 /* Zulu.ics */,
-			);
-			path = zoneinfo;
-			sourceTree = "<group>";
-		};
-		66FA9D7E155B16B600B6FAC1 /* Africa */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9D7F155B16B600B6FAC1 /* Abidjan.ics */,
-				66FA9D80155B16B600B6FAC1 /* Accra.ics */,
-				66FA9D81155B16B600B6FAC1 /* Addis_Ababa.ics */,
-				66FA9D82155B16B600B6FAC1 /* Algiers.ics */,
-				66FA9D83155B16B600B6FAC1 /* Asmara.ics */,
-				66FA9D84155B16B600B6FAC1 /* Asmera.ics */,
-				66FA9D85155B16B600B6FAC1 /* Bamako.ics */,
-				66FA9D86155B16B600B6FAC1 /* Bangui.ics */,
-				66FA9D87155B16B600B6FAC1 /* Banjul.ics */,
-				66FA9D88155B16B600B6FAC1 /* Bissau.ics */,
-				66FA9D89155B16B600B6FAC1 /* Blantyre.ics */,
-				66FA9D8A155B16B600B6FAC1 /* Brazzaville.ics */,
-				66FA9D8B155B16B600B6FAC1 /* Bujumbura.ics */,
-				66FA9D8C155B16B600B6FAC1 /* Cairo.ics */,
-				66FA9D8D155B16B600B6FAC1 /* Casablanca.ics */,
-				66FA9D8E155B16B600B6FAC1 /* Ceuta.ics */,
-				66FA9D8F155B16B600B6FAC1 /* Conakry.ics */,
-				66FA9D90155B16B600B6FAC1 /* Dakar.ics */,
-				66FA9D91155B16B600B6FAC1 /* Dar_es_Salaam.ics */,
-				66FA9D92155B16B600B6FAC1 /* Djibouti.ics */,
-				66FA9D93155B16B600B6FAC1 /* Douala.ics */,
-				66FA9D94155B16B600B6FAC1 /* El_Aaiun.ics */,
-				66FA9D95155B16B600B6FAC1 /* Freetown.ics */,
-				66FA9D96155B16B600B6FAC1 /* Gaborone.ics */,
-				66FA9D97155B16B600B6FAC1 /* Harare.ics */,
-				66FA9D98155B16B600B6FAC1 /* Johannesburg.ics */,
-				66FA9D99155B16B600B6FAC1 /* Juba.ics */,
-				66FA9D9A155B16B600B6FAC1 /* Kampala.ics */,
-				66FA9D9B155B16B600B6FAC1 /* Khartoum.ics */,
-				66FA9D9C155B16B600B6FAC1 /* Kigali.ics */,
-				66FA9D9D155B16B600B6FAC1 /* Kinshasa.ics */,
-				66FA9D9E155B16B600B6FAC1 /* Lagos.ics */,
-				66FA9D9F155B16B600B6FAC1 /* Libreville.ics */,
-				66FA9DA0155B16B600B6FAC1 /* Lome.ics */,
-				66FA9DA1155B16B600B6FAC1 /* Luanda.ics */,
-				66FA9DA2155B16B600B6FAC1 /* Lubumbashi.ics */,
-				66FA9DA3155B16B600B6FAC1 /* Lusaka.ics */,
-				66FA9DA4155B16B600B6FAC1 /* Malabo.ics */,
-				66FA9DA5155B16B600B6FAC1 /* Maputo.ics */,
-				66FA9DA6155B16B600B6FAC1 /* Maseru.ics */,
-				66FA9DA7155B16B600B6FAC1 /* Mbabane.ics */,
-				66FA9DA8155B16B600B6FAC1 /* Mogadishu.ics */,
-				66FA9DA9155B16B600B6FAC1 /* Monrovia.ics */,
-				66FA9DAA155B16B600B6FAC1 /* Nairobi.ics */,
-				66FA9DAB155B16B600B6FAC1 /* Ndjamena.ics */,
-				66FA9DAC155B16B600B6FAC1 /* Niamey.ics */,
-				66FA9DAD155B16B600B6FAC1 /* Nouakchott.ics */,
-				66FA9DAE155B16B600B6FAC1 /* Ouagadougou.ics */,
-				66FA9DAF155B16B600B6FAC1 /* Porto-Novo.ics */,
-				66FA9DB0155B16B600B6FAC1 /* Sao_Tome.ics */,
-				66FA9DB1155B16B600B6FAC1 /* Timbuktu.ics */,
-				66FA9DB2155B16B600B6FAC1 /* Tripoli.ics */,
-				66FA9DB3155B16B600B6FAC1 /* Tunis.ics */,
-				66FA9DB4155B16B600B6FAC1 /* Windhoek.ics */,
-			);
-			path = Africa;
-			sourceTree = "<group>";
-		};
-		66FA9DB5155B16B600B6FAC1 /* America */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9DB6155B16B600B6FAC1 /* Adak.ics */,
-				66FA9DB7155B16B600B6FAC1 /* Anchorage.ics */,
-				66FA9DB8155B16B600B6FAC1 /* Anguilla.ics */,
-				66FA9DB9155B16B600B6FAC1 /* Antigua.ics */,
-				66FA9DBA155B16B600B6FAC1 /* Araguaina.ics */,
-				66FA9DBB155B16B600B6FAC1 /* Argentina */,
-				66FA9DC9155B16B600B6FAC1 /* Aruba.ics */,
-				66FA9DCA155B16B600B6FAC1 /* Asuncion.ics */,
-				66FA9DCB155B16B600B6FAC1 /* Atikokan.ics */,
-				66FA9DCC155B16B600B6FAC1 /* Atka.ics */,
-				66FA9DCD155B16B600B6FAC1 /* Bahia.ics */,
-				66FA9DCE155B16B600B6FAC1 /* Bahia_Banderas.ics */,
-				66FA9DCF155B16B600B6FAC1 /* Barbados.ics */,
-				66FA9DD0155B16B600B6FAC1 /* Belem.ics */,
-				66FA9DD1155B16B600B6FAC1 /* Belize.ics */,
-				66FA9DD2155B16B600B6FAC1 /* Blanc-Sablon.ics */,
-				66FA9DD3155B16B600B6FAC1 /* Boa_Vista.ics */,
-				66FA9DD4155B16B600B6FAC1 /* Bogota.ics */,
-				66FA9DD5155B16B600B6FAC1 /* Boise.ics */,
-				66FA9DD6155B16B600B6FAC1 /* Buenos_Aires.ics */,
-				66FA9DD7155B16B600B6FAC1 /* Cambridge_Bay.ics */,
-				66FA9DD8155B16B600B6FAC1 /* Campo_Grande.ics */,
-				66FA9DD9155B16B600B6FAC1 /* Cancun.ics */,
-				66FA9DDA155B16B600B6FAC1 /* Caracas.ics */,
-				66FA9DDB155B16B600B6FAC1 /* Catamarca.ics */,
-				66FA9DDC155B16B600B6FAC1 /* Cayenne.ics */,
-				66FA9DDD155B16B600B6FAC1 /* Cayman.ics */,
-				66FA9DDE155B16B600B6FAC1 /* Chicago.ics */,
-				66FA9DDF155B16B600B6FAC1 /* Chihuahua.ics */,
-				66FA9DE0155B16B600B6FAC1 /* Coral_Harbour.ics */,
-				66FA9DE1155B16B600B6FAC1 /* Cordoba.ics */,
-				66FA9DE2155B16B600B6FAC1 /* Costa_Rica.ics */,
-				66FA9DE3155B16B600B6FAC1 /* Cuiaba.ics */,
-				66FA9DE4155B16B600B6FAC1 /* Curacao.ics */,
-				66FA9DE5155B16B600B6FAC1 /* Danmarkshavn.ics */,
-				66FA9DE6155B16B600B6FAC1 /* Dawson.ics */,
-				66FA9DE7155B16B600B6FAC1 /* Dawson_Creek.ics */,
-				66FA9DE8155B16B600B6FAC1 /* Denver.ics */,
-				66FA9DE9155B16B600B6FAC1 /* Detroit.ics */,
-				66FA9DEA155B16B600B6FAC1 /* Dominica.ics */,
-				66FA9DEB155B16B600B6FAC1 /* Edmonton.ics */,
-				66FA9DEC155B16B600B6FAC1 /* Eirunepe.ics */,
-				66FA9DED155B16B600B6FAC1 /* El_Salvador.ics */,
-				66FA9DEE155B16B600B6FAC1 /* Ensenada.ics */,
-				66FA9DEF155B16B600B6FAC1 /* Fort_Wayne.ics */,
-				66FA9DF0155B16B600B6FAC1 /* Fortaleza.ics */,
-				66FA9DF1155B16B600B6FAC1 /* Glace_Bay.ics */,
-				66FA9DF2155B16B600B6FAC1 /* Godthab.ics */,
-				66FA9DF3155B16B600B6FAC1 /* Goose_Bay.ics */,
-				66FA9DF4155B16B600B6FAC1 /* Grand_Turk.ics */,
-				66FA9DF5155B16B600B6FAC1 /* Grenada.ics */,
-				66FA9DF6155B16B600B6FAC1 /* Guadeloupe.ics */,
-				66FA9DF7155B16B600B6FAC1 /* Guatemala.ics */,
-				66FA9DF8155B16B600B6FAC1 /* Guayaquil.ics */,
-				66FA9DF9155B16B600B6FAC1 /* Guyana.ics */,
-				66FA9DFA155B16B600B6FAC1 /* Halifax.ics */,
-				66FA9DFB155B16B600B6FAC1 /* Havana.ics */,
-				66FA9DFC155B16B600B6FAC1 /* Hermosillo.ics */,
-				66FA9DFD155B16B600B6FAC1 /* Indiana */,
-				66FA9E06155B16B600B6FAC1 /* Indianapolis.ics */,
-				66FA9E07155B16B600B6FAC1 /* Inuvik.ics */,
-				66FA9E08155B16B600B6FAC1 /* Iqaluit.ics */,
-				66FA9E09155B16B600B6FAC1 /* Jamaica.ics */,
-				66FA9E0A155B16B600B6FAC1 /* Jujuy.ics */,
-				66FA9E0B155B16B600B6FAC1 /* Juneau.ics */,
-				66FA9E0C155B16B600B6FAC1 /* Kentucky */,
-				66FA9E0F155B16B600B6FAC1 /* Knox_IN.ics */,
-				66FA9E10155B16B600B6FAC1 /* Kralendijk.ics */,
-				66FA9E11155B16B600B6FAC1 /* La_Paz.ics */,
-				66FA9E12155B16B600B6FAC1 /* Lima.ics */,
-				66FA9E13155B16B600B6FAC1 /* Los_Angeles.ics */,
-				66FA9E14155B16B600B6FAC1 /* Louisville.ics */,
-				66FA9E15155B16B600B6FAC1 /* Lower_Princes.ics */,
-				66FA9E16155B16B600B6FAC1 /* Maceio.ics */,
-				66FA9E17155B16B600B6FAC1 /* Managua.ics */,
-				66FA9E18155B16B600B6FAC1 /* Manaus.ics */,
-				66FA9E19155B16B600B6FAC1 /* Marigot.ics */,
-				66FA9E1A155B16B600B6FAC1 /* Martinique.ics */,
-				66FA9E1B155B16B600B6FAC1 /* Matamoros.ics */,
-				66FA9E1C155B16B600B6FAC1 /* Mazatlan.ics */,
-				66FA9E1D155B16B600B6FAC1 /* Mendoza.ics */,
-				66FA9E1E155B16B600B6FAC1 /* Menominee.ics */,
-				66FA9E1F155B16B600B6FAC1 /* Merida.ics */,
-				66FA9E20155B16B600B6FAC1 /* Metlakatla.ics */,
-				66FA9E21155B16B600B6FAC1 /* Mexico_City.ics */,
-				66FA9E22155B16B600B6FAC1 /* Miquelon.ics */,
-				66FA9E23155B16B600B6FAC1 /* Moncton.ics */,
-				66FA9E24155B16B600B6FAC1 /* Monterrey.ics */,
-				66FA9E25155B16B600B6FAC1 /* Montevideo.ics */,
-				66FA9E26155B16B600B6FAC1 /* Montreal.ics */,
-				66FA9E27155B16B600B6FAC1 /* Montserrat.ics */,
-				66FA9E28155B16B600B6FAC1 /* Nassau.ics */,
-				66FA9E29155B16B600B6FAC1 /* New_York.ics */,
-				66FA9E2A155B16B600B6FAC1 /* Nipigon.ics */,
-				66FA9E2B155B16B600B6FAC1 /* Nome.ics */,
-				66FA9E2C155B16B600B6FAC1 /* Noronha.ics */,
-				66FA9E2D155B16B600B6FAC1 /* North_Dakota */,
-				66FA9E31155B16B600B6FAC1 /* Ojinaga.ics */,
-				66FA9E32155B16B600B6FAC1 /* Panama.ics */,
-				66FA9E33155B16B600B6FAC1 /* Pangnirtung.ics */,
-				66FA9E34155B16B600B6FAC1 /* Paramaribo.ics */,
-				66FA9E35155B16B600B6FAC1 /* Phoenix.ics */,
-				66FA9E36155B16B600B6FAC1 /* Port-au-Prince.ics */,
-				66FA9E37155B16B600B6FAC1 /* Port_of_Spain.ics */,
-				66FA9E38155B16B600B6FAC1 /* Porto_Acre.ics */,
-				66FA9E39155B16B600B6FAC1 /* Porto_Velho.ics */,
-				66FA9E3A155B16B600B6FAC1 /* Puerto_Rico.ics */,
-				66FA9E3B155B16B600B6FAC1 /* Rainy_River.ics */,
-				66FA9E3C155B16B600B6FAC1 /* Rankin_Inlet.ics */,
-				66FA9E3D155B16B600B6FAC1 /* Recife.ics */,
-				66FA9E3E155B16B600B6FAC1 /* Regina.ics */,
-				66FA9E3F155B16B600B6FAC1 /* Resolute.ics */,
-				66FA9E40155B16B600B6FAC1 /* Rio_Branco.ics */,
-				66FA9E41155B16B600B6FAC1 /* Rosario.ics */,
-				66FA9E42155B16B600B6FAC1 /* Santa_Isabel.ics */,
-				66FA9E43155B16B600B6FAC1 /* Santarem.ics */,
-				66FA9E44155B16B600B6FAC1 /* Santiago.ics */,
-				66FA9E45155B16B600B6FAC1 /* Santo_Domingo.ics */,
-				66FA9E46155B16B600B6FAC1 /* Sao_Paulo.ics */,
-				66FA9E47155B16B600B6FAC1 /* Scoresbysund.ics */,
-				66FA9E48155B16B600B6FAC1 /* Shiprock.ics */,
-				66FA9E49155B16B600B6FAC1 /* Sitka.ics */,
-				66FA9E4A155B16B600B6FAC1 /* St_Barthelemy.ics */,
-				66FA9E4B155B16B600B6FAC1 /* St_Johns.ics */,
-				66FA9E4C155B16B600B6FAC1 /* St_Kitts.ics */,
-				66FA9E4D155B16B600B6FAC1 /* St_Lucia.ics */,
-				66FA9E4E155B16B600B6FAC1 /* St_Thomas.ics */,
-				66FA9E4F155B16B600B6FAC1 /* St_Vincent.ics */,
-				66FA9E50155B16B600B6FAC1 /* Swift_Current.ics */,
-				66FA9E51155B16B600B6FAC1 /* Tegucigalpa.ics */,
-				66FA9E52155B16B600B6FAC1 /* Thule.ics */,
-				66FA9E53155B16B600B6FAC1 /* Thunder_Bay.ics */,
-				66FA9E54155B16B600B6FAC1 /* Tijuana.ics */,
-				66FA9E55155B16B600B6FAC1 /* Toronto.ics */,
-				66FA9E56155B16B600B6FAC1 /* Tortola.ics */,
-				66FA9E57155B16B600B6FAC1 /* Vancouver.ics */,
-				66FA9E58155B16B600B6FAC1 /* Virgin.ics */,
-				66FA9E59155B16B600B6FAC1 /* Whitehorse.ics */,
-				66FA9E5A155B16B600B6FAC1 /* Winnipeg.ics */,
-				66FA9E5B155B16B600B6FAC1 /* Yakutat.ics */,
-				66FA9E5C155B16B600B6FAC1 /* Yellowknife.ics */,
-			);
-			path = America;
-			sourceTree = "<group>";
-		};
-		66FA9DBB155B16B600B6FAC1 /* Argentina */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9DBC155B16B600B6FAC1 /* Buenos_Aires.ics */,
-				66FA9DBD155B16B600B6FAC1 /* Catamarca.ics */,
-				66FA9DBE155B16B600B6FAC1 /* ComodRivadavia.ics */,
-				66FA9DBF155B16B600B6FAC1 /* Cordoba.ics */,
-				66FA9DC0155B16B600B6FAC1 /* Jujuy.ics */,
-				66FA9DC1155B16B600B6FAC1 /* La_Rioja.ics */,
-				66FA9DC2155B16B600B6FAC1 /* Mendoza.ics */,
-				66FA9DC3155B16B600B6FAC1 /* Rio_Gallegos.ics */,
-				66FA9DC4155B16B600B6FAC1 /* Salta.ics */,
-				66FA9DC5155B16B600B6FAC1 /* San_Juan.ics */,
-				66FA9DC6155B16B600B6FAC1 /* San_Luis.ics */,
-				66FA9DC7155B16B600B6FAC1 /* Tucuman.ics */,
-				66FA9DC8155B16B600B6FAC1 /* Ushuaia.ics */,
-			);
-			path = Argentina;
-			sourceTree = "<group>";
-		};
-		66FA9DFD155B16B600B6FAC1 /* Indiana */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9DFE155B16B600B6FAC1 /* Indianapolis.ics */,
-				66FA9DFF155B16B600B6FAC1 /* Knox.ics */,
-				66FA9E00155B16B600B6FAC1 /* Marengo.ics */,
-				66FA9E01155B16B600B6FAC1 /* Petersburg.ics */,
-				66FA9E02155B16B600B6FAC1 /* Tell_City.ics */,
-				66FA9E03155B16B600B6FAC1 /* Vevay.ics */,
-				66FA9E04155B16B600B6FAC1 /* Vincennes.ics */,
-				66FA9E05155B16B600B6FAC1 /* Winamac.ics */,
-			);
-			path = Indiana;
-			sourceTree = "<group>";
-		};
-		66FA9E0C155B16B600B6FAC1 /* Kentucky */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9E0D155B16B600B6FAC1 /* Louisville.ics */,
-				66FA9E0E155B16B600B6FAC1 /* Monticello.ics */,
-			);
-			path = Kentucky;
-			sourceTree = "<group>";
-		};
-		66FA9E2D155B16B600B6FAC1 /* North_Dakota */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9E2E155B16B600B6FAC1 /* Beulah.ics */,
-				66FA9E2F155B16B600B6FAC1 /* Center.ics */,
-				66FA9E30155B16B600B6FAC1 /* New_Salem.ics */,
-			);
-			path = North_Dakota;
-			sourceTree = "<group>";
-		};
-		66FA9E5D155B16B600B6FAC1 /* Antarctica */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9E5E155B16B600B6FAC1 /* Casey.ics */,
-				66FA9E5F155B16B600B6FAC1 /* Davis.ics */,
-				66FA9E60155B16B600B6FAC1 /* DumontDUrville.ics */,
-				66FA9E61155B16B600B6FAC1 /* Macquarie.ics */,
-				66FA9E62155B16B600B6FAC1 /* Mawson.ics */,
-				66FA9E63155B16B600B6FAC1 /* McMurdo.ics */,
-				66FA9E64155B16B600B6FAC1 /* Palmer.ics */,
-				66FA9E65155B16B600B6FAC1 /* Rothera.ics */,
-				66FA9E66155B16B600B6FAC1 /* South_Pole.ics */,
-				66FA9E67155B16B600B6FAC1 /* Syowa.ics */,
-				66FA9E68155B16B600B6FAC1 /* Vostok.ics */,
-			);
-			path = Antarctica;
-			sourceTree = "<group>";
-		};
-		66FA9E69155B16B600B6FAC1 /* Arctic */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9E6A155B16B600B6FAC1 /* Longyearbyen.ics */,
-			);
-			path = Arctic;
-			sourceTree = "<group>";
-		};
-		66FA9E6B155B16B600B6FAC1 /* Asia */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9E6C155B16B600B6FAC1 /* Aden.ics */,
-				66FA9E6D155B16B600B6FAC1 /* Almaty.ics */,
-				66FA9E6E155B16B600B6FAC1 /* Amman.ics */,
-				66FA9E6F155B16B600B6FAC1 /* Anadyr.ics */,
-				66FA9E70155B16B600B6FAC1 /* Aqtau.ics */,
-				66FA9E71155B16B600B6FAC1 /* Aqtobe.ics */,
-				66FA9E72155B16B600B6FAC1 /* Ashgabat.ics */,
-				66FA9E73155B16B600B6FAC1 /* Ashkhabad.ics */,
-				66FA9E74155B16B600B6FAC1 /* Baghdad.ics */,
-				66FA9E75155B16B600B6FAC1 /* Bahrain.ics */,
-				66FA9E76155B16B600B6FAC1 /* Baku.ics */,
-				66FA9E77155B16B600B6FAC1 /* Bangkok.ics */,
-				66FA9E78155B16B600B6FAC1 /* Beirut.ics */,
-				66FA9E79155B16B600B6FAC1 /* Bishkek.ics */,
-				66FA9E7A155B16B600B6FAC1 /* Brunei.ics */,
-				66FA9E7B155B16B600B6FAC1 /* Calcutta.ics */,
-				66FA9E7C155B16B600B6FAC1 /* Choibalsan.ics */,
-				66FA9E7D155B16B600B6FAC1 /* Chongqing.ics */,
-				66FA9E7E155B16B600B6FAC1 /* Chungking.ics */,
-				66FA9E7F155B16B600B6FAC1 /* Colombo.ics */,
-				66FA9E80155B16B600B6FAC1 /* Dacca.ics */,
-				66FA9E81155B16B600B6FAC1 /* Damascus.ics */,
-				66FA9E82155B16B600B6FAC1 /* Dhaka.ics */,
-				66FA9E83155B16B600B6FAC1 /* Dili.ics */,
-				66FA9E84155B16B600B6FAC1 /* Dubai.ics */,
-				66FA9E85155B16B600B6FAC1 /* Dushanbe.ics */,
-				66FA9E86155B16B600B6FAC1 /* Gaza.ics */,
-				66FA9E87155B16B600B6FAC1 /* Harbin.ics */,
-				66FA9E88155B16B600B6FAC1 /* Hebron.ics */,
-				66FA9E89155B16B600B6FAC1 /* Ho_Chi_Minh.ics */,
-				66FA9E8A155B16B600B6FAC1 /* Hong_Kong.ics */,
-				66FA9E8B155B16B600B6FAC1 /* Hovd.ics */,
-				66FA9E8C155B16B600B6FAC1 /* Irkutsk.ics */,
-				66FA9E8D155B16B600B6FAC1 /* Istanbul.ics */,
-				66FA9E8E155B16B600B6FAC1 /* Jakarta.ics */,
-				66FA9E8F155B16B600B6FAC1 /* Jayapura.ics */,
-				66FA9E90155B16B600B6FAC1 /* Jerusalem.ics */,
-				66FA9E91155B16B600B6FAC1 /* Kabul.ics */,
-				66FA9E92155B16B600B6FAC1 /* Kamchatka.ics */,
-				66FA9E93155B16B600B6FAC1 /* Karachi.ics */,
-				66FA9E94155B16B600B6FAC1 /* Kashgar.ics */,
-				66FA9E95155B16B600B6FAC1 /* Kathmandu.ics */,
-				66FA9E96155B16B600B6FAC1 /* Katmandu.ics */,
-				66FA9E97155B16B600B6FAC1 /* Kolkata.ics */,
-				66FA9E98155B16B600B6FAC1 /* Krasnoyarsk.ics */,
-				66FA9E99155B16B600B6FAC1 /* Kuala_Lumpur.ics */,
-				66FA9E9A155B16B600B6FAC1 /* Kuching.ics */,
-				66FA9E9B155B16B600B6FAC1 /* Kuwait.ics */,
-				66FA9E9C155B16B600B6FAC1 /* Macao.ics */,
-				66FA9E9D155B16B600B6FAC1 /* Macau.ics */,
-				66FA9E9E155B16B600B6FAC1 /* Magadan.ics */,
-				66FA9E9F155B16B600B6FAC1 /* Makassar.ics */,
-				66FA9EA0155B16B600B6FAC1 /* Manila.ics */,
-				66FA9EA1155B16B600B6FAC1 /* Muscat.ics */,
-				66FA9EA2155B16B600B6FAC1 /* Nicosia.ics */,
-				66FA9EA3155B16B600B6FAC1 /* Novokuznetsk.ics */,
-				66FA9EA4155B16B600B6FAC1 /* Novosibirsk.ics */,
-				66FA9EA5155B16B600B6FAC1 /* Omsk.ics */,
-				66FA9EA6155B16B600B6FAC1 /* Oral.ics */,
-				66FA9EA7155B16B600B6FAC1 /* Phnom_Penh.ics */,
-				66FA9EA8155B16B600B6FAC1 /* Pontianak.ics */,
-				66FA9EA9155B16B600B6FAC1 /* Pyongyang.ics */,
-				66FA9EAA155B16B600B6FAC1 /* Qatar.ics */,
-				66FA9EAB155B16B600B6FAC1 /* Qyzylorda.ics */,
-				66FA9EAC155B16B600B6FAC1 /* Rangoon.ics */,
-				66FA9EAD155B16B600B6FAC1 /* Riyadh.ics */,
-				66FA9EAE155B16B600B6FAC1 /* Saigon.ics */,
-				66FA9EAF155B16B600B6FAC1 /* Sakhalin.ics */,
-				66FA9EB0155B16B600B6FAC1 /* Samarkand.ics */,
-				66FA9EB1155B16B600B6FAC1 /* Seoul.ics */,
-				66FA9EB2155B16B600B6FAC1 /* Shanghai.ics */,
-				66FA9EB3155B16B600B6FAC1 /* Singapore.ics */,
-				66FA9EB4155B16B600B6FAC1 /* Taipei.ics */,
-				66FA9EB5155B16B600B6FAC1 /* Tashkent.ics */,
-				66FA9EB6155B16B600B6FAC1 /* Tbilisi.ics */,
-				66FA9EB7155B16B600B6FAC1 /* Tehran.ics */,
-				66FA9EB8155B16B600B6FAC1 /* Tel_Aviv.ics */,
-				66FA9EB9155B16B600B6FAC1 /* Thimbu.ics */,
-				66FA9EBA155B16B600B6FAC1 /* Thimphu.ics */,
-				66FA9EBB155B16B600B6FAC1 /* Tokyo.ics */,
-				66FA9EBC155B16B600B6FAC1 /* Ujung_Pandang.ics */,
-				66FA9EBD155B16B600B6FAC1 /* Ulaanbaatar.ics */,
-				66FA9EBE155B16B600B6FAC1 /* Ulan_Bator.ics */,
-				66FA9EBF155B16B600B6FAC1 /* Urumqi.ics */,
-				66FA9EC0155B16B600B6FAC1 /* Vientiane.ics */,
-				66FA9EC1155B16B600B6FAC1 /* Vladivostok.ics */,
-				66FA9EC2155B16B600B6FAC1 /* Yakutsk.ics */,
-				66FA9EC3155B16B600B6FAC1 /* Yekaterinburg.ics */,
-				66FA9EC4155B16B600B6FAC1 /* Yerevan.ics */,
-			);
-			path = Asia;
-			sourceTree = "<group>";
-		};
-		66FA9EC5155B16B600B6FAC1 /* Atlantic */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9EC6155B16B600B6FAC1 /* Azores.ics */,
-				66FA9EC7155B16B600B6FAC1 /* Bermuda.ics */,
-				66FA9EC8155B16B600B6FAC1 /* Canary.ics */,
-				66FA9EC9155B16B600B6FAC1 /* Cape_Verde.ics */,
-				66FA9ECA155B16B600B6FAC1 /* Faeroe.ics */,
-				66FA9ECB155B16B600B6FAC1 /* Faroe.ics */,
-				66FA9ECC155B16B600B6FAC1 /* Jan_Mayen.ics */,
-				66FA9ECD155B16B600B6FAC1 /* Madeira.ics */,
-				66FA9ECE155B16B600B6FAC1 /* Reykjavik.ics */,
-				66FA9ECF155B16B600B6FAC1 /* South_Georgia.ics */,
-				66FA9ED0155B16B600B6FAC1 /* St_Helena.ics */,
-				66FA9ED1155B16B600B6FAC1 /* Stanley.ics */,
-			);
-			path = Atlantic;
-			sourceTree = "<group>";
-		};
-		66FA9ED2155B16B600B6FAC1 /* Australia */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9ED3155B16B600B6FAC1 /* ACT.ics */,
-				66FA9ED4155B16B600B6FAC1 /* Adelaide.ics */,
-				66FA9ED5155B16B600B6FAC1 /* Brisbane.ics */,
-				66FA9ED6155B16B600B6FAC1 /* Broken_Hill.ics */,
-				66FA9ED7155B16B600B6FAC1 /* Canberra.ics */,
-				66FA9ED8155B16B600B6FAC1 /* Currie.ics */,
-				66FA9ED9155B16B600B6FAC1 /* Darwin.ics */,
-				66FA9EDA155B16B600B6FAC1 /* Eucla.ics */,
-				66FA9EDB155B16B600B6FAC1 /* Hobart.ics */,
-				66FA9EDC155B16B600B6FAC1 /* LHI.ics */,
-				66FA9EDD155B16B600B6FAC1 /* Lindeman.ics */,
-				66FA9EDE155B16B600B6FAC1 /* Lord_Howe.ics */,
-				66FA9EDF155B16B600B6FAC1 /* Melbourne.ics */,
-				66FA9EE0155B16B600B6FAC1 /* North.ics */,
-				66FA9EE1155B16B600B6FAC1 /* NSW.ics */,
-				66FA9EE2155B16B600B6FAC1 /* Perth.ics */,
-				66FA9EE3155B16B600B6FAC1 /* Queensland.ics */,
-				66FA9EE4155B16B600B6FAC1 /* South.ics */,
-				66FA9EE5155B16B600B6FAC1 /* Sydney.ics */,
-				66FA9EE6155B16B600B6FAC1 /* Tasmania.ics */,
-				66FA9EE7155B16B600B6FAC1 /* Victoria.ics */,
-				66FA9EE8155B16B600B6FAC1 /* West.ics */,
-				66FA9EE9155B16B600B6FAC1 /* Yancowinna.ics */,
-			);
-			path = Australia;
-			sourceTree = "<group>";
-		};
-		66FA9EEA155B16B600B6FAC1 /* Brazil */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9EEB155B16B600B6FAC1 /* Acre.ics */,
-				66FA9EEC155B16B600B6FAC1 /* DeNoronha.ics */,
-				66FA9EED155B16B600B6FAC1 /* East.ics */,
-				66FA9EEE155B16B600B6FAC1 /* West.ics */,
-			);
-			path = Brazil;
-			sourceTree = "<group>";
-		};
-		66FA9EEF155B16B600B6FAC1 /* Canada */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9EF0155B16B600B6FAC1 /* Atlantic.ics */,
-				66FA9EF1155B16B600B6FAC1 /* Central.ics */,
-				66FA9EF2155B16B600B6FAC1 /* East-Saskatchewan.ics */,
-				66FA9EF3155B16B600B6FAC1 /* Eastern.ics */,
-				66FA9EF4155B16B600B6FAC1 /* Mountain.ics */,
-				66FA9EF5155B16B600B6FAC1 /* Newfoundland.ics */,
-				66FA9EF6155B16B600B6FAC1 /* Pacific.ics */,
-				66FA9EF7155B16B600B6FAC1 /* Saskatchewan.ics */,
-				66FA9EF8155B16B600B6FAC1 /* Yukon.ics */,
-			);
-			path = Canada;
-			sourceTree = "<group>";
-		};
-		66FA9EFA155B16B600B6FAC1 /* Chile */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9EFB155B16B600B6FAC1 /* Continental.ics */,
-				66FA9EFC155B16B600B6FAC1 /* EasterIsland.ics */,
-			);
-			path = Chile;
-			sourceTree = "<group>";
-		};
-		66FA9F04155B16B600B6FAC1 /* Etc */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9F05155B16B600B6FAC1 /* GMT+0.ics */,
-				66FA9F06155B16B600B6FAC1 /* GMT+1.ics */,
-				66FA9F07155B16B600B6FAC1 /* GMT+10.ics */,
-				66FA9F08155B16B600B6FAC1 /* GMT+11.ics */,
-				66FA9F09155B16B600B6FAC1 /* GMT+12.ics */,
-				66FA9F0A155B16B600B6FAC1 /* GMT+2.ics */,
-				66FA9F0B155B16B600B6FAC1 /* GMT+3.ics */,
-				66FA9F0C155B16B600B6FAC1 /* GMT+4.ics */,
-				66FA9F0D155B16B600B6FAC1 /* GMT+5.ics */,
-				66FA9F0E155B16B600B6FAC1 /* GMT+6.ics */,
-				66FA9F0F155B16B600B6FAC1 /* GMT+7.ics */,
-				66FA9F10155B16B600B6FAC1 /* GMT+8.ics */,
-				66FA9F11155B16B600B6FAC1 /* GMT+9.ics */,
-				66FA9F12155B16B600B6FAC1 /* GMT-0.ics */,
-				66FA9F13155B16B600B6FAC1 /* GMT-1.ics */,
-				66FA9F14155B16B600B6FAC1 /* GMT-10.ics */,
-				66FA9F15155B16B600B6FAC1 /* GMT-11.ics */,
-				66FA9F16155B16B600B6FAC1 /* GMT-12.ics */,
-				66FA9F17155B16B600B6FAC1 /* GMT-13.ics */,
-				66FA9F18155B16B600B6FAC1 /* GMT-14.ics */,
-				66FA9F19155B16B600B6FAC1 /* GMT-2.ics */,
-				66FA9F1A155B16B600B6FAC1 /* GMT-3.ics */,
-				66FA9F1B155B16B600B6FAC1 /* GMT-4.ics */,
-				66FA9F1C155B16B600B6FAC1 /* GMT-5.ics */,
-				66FA9F1D155B16B600B6FAC1 /* GMT-6.ics */,
-				66FA9F1E155B16B600B6FAC1 /* GMT-7.ics */,
-				66FA9F1F155B16B600B6FAC1 /* GMT-8.ics */,
-				66FA9F20155B16B600B6FAC1 /* GMT-9.ics */,
-				66FA9F21155B16B600B6FAC1 /* GMT.ics */,
-				66FA9F22155B16B600B6FAC1 /* GMT0.ics */,
-				66FA9F23155B16B600B6FAC1 /* Greenwich.ics */,
-				66FA9F24155B16B600B6FAC1 /* UCT.ics */,
-				66FA9F25155B16B600B6FAC1 /* Universal.ics */,
-				66FA9F26155B16B600B6FAC1 /* UTC.ics */,
-				66FA9F27155B16B600B6FAC1 /* Zulu.ics */,
-			);
-			path = Etc;
-			sourceTree = "<group>";
-		};
-		66FA9F28155B16B600B6FAC1 /* Europe */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9F29155B16B600B6FAC1 /* Amsterdam.ics */,
-				66FA9F2A155B16B600B6FAC1 /* Andorra.ics */,
-				66FA9F2B155B16B600B6FAC1 /* Athens.ics */,
-				66FA9F2C155B16B600B6FAC1 /* Belfast.ics */,
-				66FA9F2D155B16B600B6FAC1 /* Belgrade.ics */,
-				66FA9F2E155B16B600B6FAC1 /* Berlin.ics */,
-				66FA9F2F155B16B600B6FAC1 /* Bratislava.ics */,
-				66FA9F30155B16B600B6FAC1 /* Brussels.ics */,
-				66FA9F31155B16B600B6FAC1 /* Bucharest.ics */,
-				66FA9F32155B16B600B6FAC1 /* Budapest.ics */,
-				66FA9F33155B16B600B6FAC1 /* Chisinau.ics */,
-				66FA9F34155B16B600B6FAC1 /* Copenhagen.ics */,
-				66FA9F35155B16B600B6FAC1 /* Dublin.ics */,
-				66FA9F36155B16B600B6FAC1 /* Gibraltar.ics */,
-				66FA9F37155B16B600B6FAC1 /* Guernsey.ics */,
-				66FA9F38155B16B600B6FAC1 /* Helsinki.ics */,
-				66FA9F39155B16B600B6FAC1 /* Isle_of_Man.ics */,
-				66FA9F3A155B16B600B6FAC1 /* Istanbul.ics */,
-				66FA9F3B155B16B600B6FAC1 /* Jersey.ics */,
-				66FA9F3C155B16B600B6FAC1 /* Kaliningrad.ics */,
-				66FA9F3D155B16B600B6FAC1 /* Kiev.ics */,
-				66FA9F3E155B16B600B6FAC1 /* Lisbon.ics */,
-				66FA9F3F155B16B600B6FAC1 /* Ljubljana.ics */,
-				66FA9F40155B16B600B6FAC1 /* London.ics */,
-				66FA9F41155B16B600B6FAC1 /* Luxembourg.ics */,
-				66FA9F42155B16B600B6FAC1 /* Madrid.ics */,
-				66FA9F43155B16B600B6FAC1 /* Malta.ics */,
-				66FA9F44155B16B600B6FAC1 /* Mariehamn.ics */,
-				66FA9F45155B16B600B6FAC1 /* Minsk.ics */,
-				66FA9F46155B16B600B6FAC1 /* Monaco.ics */,
-				66FA9F47155B16B600B6FAC1 /* Moscow.ics */,
-				66FA9F48155B16B600B6FAC1 /* Nicosia.ics */,
-				66FA9F49155B16B600B6FAC1 /* Oslo.ics */,
-				66FA9F4A155B16B600B6FAC1 /* Paris.ics */,
-				66FA9F4B155B16B600B6FAC1 /* Podgorica.ics */,
-				66FA9F4C155B16B600B6FAC1 /* Prague.ics */,
-				66FA9F4D155B16B600B6FAC1 /* Riga.ics */,
-				66FA9F4E155B16B600B6FAC1 /* Rome.ics */,
-				66FA9F4F155B16B600B6FAC1 /* Samara.ics */,
-				66FA9F50155B16B600B6FAC1 /* San_Marino.ics */,
-				66FA9F51155B16B600B6FAC1 /* Sarajevo.ics */,
-				66FA9F52155B16B600B6FAC1 /* Simferopol.ics */,
-				66FA9F53155B16B600B6FAC1 /* Skopje.ics */,
-				66FA9F54155B16B600B6FAC1 /* Sofia.ics */,
-				66FA9F55155B16B600B6FAC1 /* Stockholm.ics */,
-				66FA9F56155B16B600B6FAC1 /* Tallinn.ics */,
-				66FA9F57155B16B600B6FAC1 /* Tirane.ics */,
-				66FA9F58155B16B600B6FAC1 /* Tiraspol.ics */,
-				66FA9F59155B16B600B6FAC1 /* Uzhgorod.ics */,
-				66FA9F5A155B16B600B6FAC1 /* Vaduz.ics */,
-				66FA9F5B155B16B600B6FAC1 /* Vatican.ics */,
-				66FA9F5C155B16B600B6FAC1 /* Vienna.ics */,
-				66FA9F5D155B16B600B6FAC1 /* Vilnius.ics */,
-				66FA9F5E155B16B600B6FAC1 /* Volgograd.ics */,
-				66FA9F5F155B16B600B6FAC1 /* Warsaw.ics */,
-				66FA9F60155B16B600B6FAC1 /* Zagreb.ics */,
-				66FA9F61155B16B600B6FAC1 /* Zaporozhye.ics */,
-				66FA9F62155B16B600B6FAC1 /* Zurich.ics */,
-			);
-			path = Europe;
-			sourceTree = "<group>";
-		};
-		66FA9F6D155B16B600B6FAC1 /* Indian */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9F6E155B16B600B6FAC1 /* Antananarivo.ics */,
-				66FA9F6F155B16B600B6FAC1 /* Chagos.ics */,
-				66FA9F70155B16B600B6FAC1 /* Christmas.ics */,
-				66FA9F71155B16B600B6FAC1 /* Cocos.ics */,
-				66FA9F72155B16B600B6FAC1 /* Comoro.ics */,
-				66FA9F73155B16B600B6FAC1 /* Kerguelen.ics */,
-				66FA9F74155B16B600B6FAC1 /* Mahe.ics */,
-				66FA9F75155B16B600B6FAC1 /* Maldives.ics */,
-				66FA9F76155B16B600B6FAC1 /* Mauritius.ics */,
-				66FA9F77155B16B600B6FAC1 /* Mayotte.ics */,
-				66FA9F78155B16B600B6FAC1 /* Reunion.ics */,
-			);
-			path = Indian;
-			sourceTree = "<group>";
-		};
-		66FA9F81155B16B600B6FAC1 /* Mexico */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9F82155B16B600B6FAC1 /* BajaNorte.ics */,
-				66FA9F83155B16B600B6FAC1 /* BajaSur.ics */,
-				66FA9F84155B16B600B6FAC1 /* General.ics */,
-			);
-			path = Mexico;
-			sourceTree = "<group>";
-		};
-		66FA9F8A155B16B600B6FAC1 /* Pacific */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9F8B155B16B600B6FAC1 /* Apia.ics */,
-				66FA9F8C155B16B600B6FAC1 /* Auckland.ics */,
-				66FA9F8D155B16B600B6FAC1 /* Chatham.ics */,
-				66FA9F8E155B16B600B6FAC1 /* Chuuk.ics */,
-				66FA9F8F155B16B600B6FAC1 /* Easter.ics */,
-				66FA9F90155B16B600B6FAC1 /* Efate.ics */,
-				66FA9F91155B16B600B6FAC1 /* Enderbury.ics */,
-				66FA9F92155B16B600B6FAC1 /* Fakaofo.ics */,
-				66FA9F93155B16B600B6FAC1 /* Fiji.ics */,
-				66FA9F94155B16B600B6FAC1 /* Funafuti.ics */,
-				66FA9F95155B16B600B6FAC1 /* Galapagos.ics */,
-				66FA9F96155B16B600B6FAC1 /* Gambier.ics */,
-				66FA9F97155B16B600B6FAC1 /* Guadalcanal.ics */,
-				66FA9F98155B16B600B6FAC1 /* Guam.ics */,
-				66FA9F99155B16B600B6FAC1 /* Honolulu.ics */,
-				66FA9F9A155B16B600B6FAC1 /* Johnston.ics */,
-				66FA9F9B155B16B600B6FAC1 /* Kiritimati.ics */,
-				66FA9F9C155B16B600B6FAC1 /* Kosrae.ics */,
-				66FA9F9D155B16B600B6FAC1 /* Kwajalein.ics */,
-				66FA9F9E155B16B600B6FAC1 /* Majuro.ics */,
-				66FA9F9F155B16B600B6FAC1 /* Marquesas.ics */,
-				66FA9FA0155B16B600B6FAC1 /* Midway.ics */,
-				66FA9FA1155B16B600B6FAC1 /* Nauru.ics */,
-				66FA9FA2155B16B600B6FAC1 /* Niue.ics */,
-				66FA9FA3155B16B600B6FAC1 /* Norfolk.ics */,
-				66FA9FA4155B16B600B6FAC1 /* Noumea.ics */,
-				66FA9FA5155B16B600B6FAC1 /* Pago_Pago.ics */,
-				66FA9FA6155B16B600B6FAC1 /* Palau.ics */,
-				66FA9FA7155B16B600B6FAC1 /* Pitcairn.ics */,
-				66FA9FA8155B16B600B6FAC1 /* Pohnpei.ics */,
-				66FA9FA9155B16B600B6FAC1 /* Ponape.ics */,
-				66FA9FAA155B16B600B6FAC1 /* Port_Moresby.ics */,
-				66FA9FAB155B16B600B6FAC1 /* Rarotonga.ics */,
-				66FA9FAC155B16B600B6FAC1 /* Saipan.ics */,
-				66FA9FAD155B16B600B6FAC1 /* Samoa.ics */,
-				66FA9FAE155B16B600B6FAC1 /* Tahiti.ics */,
-				66FA9FAF155B16B600B6FAC1 /* Tarawa.ics */,
-				66FA9FB0155B16B600B6FAC1 /* Tongatapu.ics */,
-				66FA9FB1155B16B600B6FAC1 /* Truk.ics */,
-				66FA9FB2155B16B600B6FAC1 /* Wake.ics */,
-				66FA9FB3155B16B600B6FAC1 /* Wallis.ics */,
-				66FA9FB4155B16B600B6FAC1 /* Yap.ics */,
-			);
-			path = Pacific;
-			sourceTree = "<group>";
-		};
-		66FA9FC0155B16B600B6FAC1 /* US */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9FC1155B16B600B6FAC1 /* Alaska.ics */,
-				66FA9FC2155B16B600B6FAC1 /* Aleutian.ics */,
-				66FA9FC3155B16B600B6FAC1 /* Arizona.ics */,
-				66FA9FC4155B16B600B6FAC1 /* Central.ics */,
-				66FA9FC5155B16B600B6FAC1 /* East-Indiana.ics */,
-				66FA9FC6155B16B600B6FAC1 /* Eastern.ics */,
-				66FA9FC7155B16B600B6FAC1 /* Hawaii.ics */,
-				66FA9FC8155B16B600B6FAC1 /* Indiana-Starke.ics */,
-				66FA9FC9155B16B600B6FAC1 /* Michigan.ics */,
-				66FA9FCA155B16B600B6FAC1 /* Mountain.ics */,
-				66FA9FCB155B16B600B6FAC1 /* Pacific.ics */,
-				66FA9FCC155B16B600B6FAC1 /* Samoa.ics */,
-			);
-			path = US;
-			sourceTree = "<group>";
-		};
-		66FA9FD2155B16B600B6FAC1 /* txdav */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9FD3155B16B600B6FAC1 /* __init__.py */,
-				66FA9FD4155B16B600B6FAC1 /* base */,
-				66FA9FEE155B16B600B6FAC1 /* caldav */,
-				66FAA038155B16B600B6FAC1 /* carddav */,
-				66FAA060155B16B600B6FAC1 /* common */,
-				66FAA0A9155B16B600B6FAC1 /* idav.py */,
-				66FAA0AA155B16B600B6FAC1 /* xml */,
-			);
-			name = txdav;
-			path = ../txdav;
-			sourceTree = "<group>";
-		};
-		66FA9FD4155B16B600B6FAC1 /* base */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9FD5155B16B600B6FAC1 /* __init__.py */,
-				66FA9FD6155B16B600B6FAC1 /* datastore */,
-				66FA9FDF155B16B600B6FAC1 /* propertystore */,
-			);
-			path = base;
-			sourceTree = "<group>";
-		};
-		66FA9FD6155B16B600B6FAC1 /* datastore */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9FD7155B16B600B6FAC1 /* __init__.py */,
-				66FA9FD8155B16B600B6FAC1 /* dbapiclient.py */,
-				66FA9FD9155B16B600B6FAC1 /* file.py */,
-				66FA9FDA155B16B600B6FAC1 /* subpostgres.py */,
-				66FA9FDB155B16B600B6FAC1 /* test */,
-				66FA9FDE155B16B600B6FAC1 /* util.py */,
-			);
-			path = datastore;
-			sourceTree = "<group>";
-		};
-		66FA9FDB155B16B600B6FAC1 /* test */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9FDC155B16B600B6FAC1 /* __init__.py */,
-				66FA9FDD155B16B600B6FAC1 /* test_subpostgres.py */,
-			);
-			path = test;
-			sourceTree = "<group>";
-		};
-		66FA9FDF155B16B600B6FAC1 /* propertystore */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9FE0155B16B600B6FAC1 /* __init__.py */,
-				66FA9FE1155B16B600B6FAC1 /* appledouble_xattr.py */,
-				66FA9FE2155B16B600B6FAC1 /* base.py */,
-				66FA9FE3155B16B600B6FAC1 /* none.py */,
-				66FA9FE4155B16B600B6FAC1 /* sql.py */,
-				66FA9FE5155B16B600B6FAC1 /* test */,
-				66FA9FED155B16B600B6FAC1 /* xattr.py */,
-			);
-			path = propertystore;
-			sourceTree = "<group>";
-		};
-		66FA9FE5155B16B600B6FAC1 /* test */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9FE6155B16B600B6FAC1 /* __init__.py */,
-				66FA9FE7155B16B600B6FAC1 /* base.py */,
-				66FA9FE8155B16B600B6FAC1 /* test_appledouble.py */,
-				66FA9FE9155B16B600B6FAC1 /* test_base.py */,
-				66FA9FEA155B16B600B6FAC1 /* test_none.py */,
-				66FA9FEB155B16B600B6FAC1 /* test_sql.py */,
-				66FA9FEC155B16B600B6FAC1 /* test_xattr.py */,
-			);
-			path = test;
-			sourceTree = "<group>";
-		};
-		66FA9FEE155B16B600B6FAC1 /* caldav */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9FEF155B16B600B6FAC1 /* __init__.py */,
-				66FA9FF0155B16B600B6FAC1 /* datastore */,
-				66FAA036155B16B600B6FAC1 /* icalendarstore.py */,
-				66FAA037155B16B600B6FAC1 /* resource.py */,
-			);
-			path = caldav;
-			sourceTree = "<group>";
-		};
-		66FA9FF0155B16B600B6FAC1 /* datastore */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9FF1155B16B600B6FAC1 /* __init__.py */,
-				66FA9FF2155B16B600B6FAC1 /* file.py */,
-				66FA9FF3155B16B600B6FAC1 /* index_file.py */,
-				66FA9FF4155B16B600B6FAC1 /* scheduling.py */,
-				66FA9FF5155B16B600B6FAC1 /* sql.py */,
-				66FA9FF6155B16B600B6FAC1 /* test */,
-				66FAA035155B16B600B6FAC1 /* util.py */,
-			);
-			path = datastore;
-			sourceTree = "<group>";
-		};
-		66FA9FF6155B16B600B6FAC1 /* test */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9FF7155B16B600B6FAC1 /* __init__.py */,
-				66FA9FF8155B16B600B6FAC1 /* calendar_store */,
-				66FAA02F155B16B600B6FAC1 /* common.py */,
-				66FAA030155B16B600B6FAC1 /* test_file.py */,
-				66FAA031155B16B600B6FAC1 /* test_index_file.py */,
-				66FAA032155B16B600B6FAC1 /* test_scheduling.py */,
-				66FAA033155B16B600B6FAC1 /* test_sql.py */,
-				66FAA034155B16B600B6FAC1 /* test_util.py */,
-			);
-			path = test;
-			sourceTree = "<group>";
-		};
-		66FA9FF8155B16B600B6FAC1 /* calendar_store */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9FF9155B16B600B6FAC1 /* ho */,
-			);
-			path = calendar_store;
-			sourceTree = "<group>";
-		};
-		66FA9FF9155B16B600B6FAC1 /* ho */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9FFA155B16B600B6FAC1 /* me */,
-			);
-			path = ho;
-			sourceTree = "<group>";
-		};
-		66FA9FFA155B16B600B6FAC1 /* me */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9FFB155B16B600B6FAC1 /* home1 */,
-				66FAA00A155B16B600B6FAC1 /* home_attachments */,
-				66FAA014155B16B600B6FAC1 /* home_bad */,
-				66FAA01D155B16B600B6FAC1 /* home_no_splits */,
-				66FAA022155B16B600B6FAC1 /* home_splits */,
-				66FAA02D155B16B600B6FAC1 /* home_splits_shared */,
-			);
-			path = me;
-			sourceTree = "<group>";
-		};
-		66FA9FFB155B16B600B6FAC1 /* home1 */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9FFC155B16B600B6FAC1 /* calendar_1 */,
-				66FAA001155B16B600B6FAC1 /* calendar_2 */,
-				66FAA009155B16B600B6FAC1 /* calendar_empty */,
-			);
-			path = home1;
-			sourceTree = "<group>";
-		};
-		66FA9FFC155B16B600B6FAC1 /* calendar_1 */ = {
-			isa = PBXGroup;
-			children = (
-				66FA9FFD155B16B600B6FAC1 /* 1.ics */,
-				66FA9FFE155B16B600B6FAC1 /* 2.ics */,
-				66FA9FFF155B16B600B6FAC1 /* 3.ics */,
-				66FAA000155B16B600B6FAC1 /* 4.ics */,
-			);
-			path = calendar_1;
-			sourceTree = "<group>";
-		};
-		66FAA001155B16B600B6FAC1 /* calendar_2 */ = {
-			isa = PBXGroup;
-			children = (
-				66FAA002155B16B600B6FAC1 /* 24204e8682b99527cbda64d7423acda7.ics */,
-				66FAA003155B16B600B6FAC1 /* 61038c41bd02ae5daf9f7fe9d54199fd.ics */,
-				66FAA004155B16B600B6FAC1 /* 84be58ced1f1bb34057e1bd7e602c9c8.ics */,
-				66FAA005155B16B600B6FAC1 /* acc1015b7dc300c1b5665f6833960994.ics */,
-				66FAA006155B16B600B6FAC1 /* b0d5785f275c064117ffd1fc20f4ed40.ics */,
-				66FAA007155B16B600B6FAC1 /* b495c5dd5aa53392078eb43b1f906a80.ics */,
-				66FAA008155B16B600B6FAC1 /* b88dd50941e4a31520ee396fd7894c96.ics */,
-			);
-			path = calendar_2;
-			sourceTree = "<group>";
-		};
-		66FAA009155B16B600B6FAC1 /* calendar_empty */ = {
-			isa = PBXGroup;
-			children = (
-			);
-			path = calendar_empty;
-			sourceTree = "<group>";
-		};
-		66FAA00A155B16B600B6FAC1 /* home_attachments */ = {
-			isa = PBXGroup;
-			children = (
-				66FAA00B155B16B600B6FAC1 /* calendar_1 */,
-				66FAA00F155B16B600B6FAC1 /* dropbox */,
-			);
-			path = home_attachments;
-			sourceTree = "<group>";
-		};
-		66FAA00B155B16B600B6FAC1 /* calendar_1 */ = {
-			isa = PBXGroup;
-			children = (
-				66FAA00C155B16B600B6FAC1 /* 1.ics */,
-				66FAA00D155B16B600B6FAC1 /* 2.ics */,
-				66FAA00E155B16B600B6FAC1 /* 3.ics */,
-			);
-			path = calendar_1;
-			sourceTree = "<group>";
-		};
-		66FAA00F155B16B600B6FAC1 /* dropbox */ = {
-			isa = PBXGroup;
-			children = (
-				66FAA010155B16B600B6FAC1 /* uid1.dropbox */,
-				66FAA012155B16B600B6FAC1 /* uid2.dropbox */,
-			);
-			path = dropbox;
-			sourceTree = "<group>";
-		};
-		66FAA010155B16B600B6FAC1 /* uid1.dropbox */ = {
-			isa = PBXGroup;
-			children = (
-				66FAA011155B16B600B6FAC1 /* test.txt */,
-			);
-			path = uid1.dropbox;
-			sourceTree = "<group>";
-		};
-		66FAA012155B16B600B6FAC1 /* uid2.dropbox */ = {
-			isa = PBXGroup;
-			children = (
-				66FAA013155B16B600B6FAC1 /* test.txt */,
-			);
-			path = uid2.dropbox;
-			sourceTree = "<group>";
-		};
-		66FAA014155B16B600B6FAC1 /* home_bad */ = {
-			isa = PBXGroup;
-			children = (
-				66FAA015155B16B600B6FAC1 /* calendar_bad */,
-				66FAA019155B16B600B6FAC1 /* calendar_fix_recurrence */,
-			);
-			path = home_bad;
-			sourceTree = "<group>";
-		};
-		66FAA015155B16B600B6FAC1 /* calendar_bad */ = {
-			isa = PBXGroup;
-			children = (
-				66FAA016155B16B600B6FAC1 /* 1.ics */,
-				66FAA017155B16B600B6FAC1 /* 2.ics */,
-				66FAA018155B16B600B6FAC1 /* 3.ics */,
-			);
-			path = calendar_bad;
-			sourceTree = "<group>";
-		};
-		66FAA019155B16B600B6FAC1 /* calendar_fix_recurrence */ = {
-			isa = PBXGroup;
-			children = (
-				66FAA01A155B16B600B6FAC1 /* 1.ics */,
-				66FAA01B155B16B600B6FAC1 /* 2.ics */,
-				66FAA01C155B16B600B6FAC1 /* 3.ics */,
-			);
-			path = calendar_fix_recurrence;
-			sourceTree = "<group>";
-		};
-		66FAA01D155B16B600B6FAC1 /* home_no_splits */ = {
-			isa = PBXGroup;
-			children = (
-				66FAA01E155B16B600B6FAC1 /* calendar_1 */,
-			);
-			path = home_no_splits;
-			sourceTree = "<group>";
-		};
-		66FAA01E155B16B600B6FAC1 /* calendar_1 */ = {
-			isa = PBXGroup;
-			children = (
-				66FAA01F155B16B600B6FAC1 /* 1.ics */,
-				66FAA020155B16B600B6FAC1 /* 2.ics */,
-				66FAA021155B16B600B6FAC1 /* 3.ics */,
-			);
-			path = calendar_1;
-			sourceTree = "<group>";
-		};
-		66FAA022155B16B600B6FAC1 /* home_splits */ = {
-			isa = PBXGroup;
-			children = (
-				66FAA023155B16B600B6FAC1 /* calendar_1 */,
-				66FAA027155B16B600B6FAC1 /* calendar_2 */,
-			);
-			path = home_splits;
-			sourceTree = "<group>";
-		};
-		66FAA023155B16B600B6FAC1 /* calendar_1 */ = {
-			isa = PBXGroup;
-			children = (
-				66FAA024155B16B600B6FAC1 /* 1.ics */,
-				66FAA025155B16B600B6FAC1 /* 2.ics */,
-				66FAA026155B16B600B6FAC1 /* 3.ics */,
-			);
-			path = calendar_1;
-			sourceTree = "<group>";
-		};
-		66FAA027155B16B600B6FAC1 /* calendar_2 */ = {
-			isa = PBXGroup;
-			children = (
-				66FAA028155B16B600B6FAC1 /* 1.ics */,
-				66FAA029155B16B600B6FAC1 /* 2.ics */,
-				66FAA02A155B16B600B6FAC1 /* 3.ics */,
-				66FAA02B155B16B600B6FAC1 /* 4.ics */,
-				66FAA02C155B16B600B6FAC1 /* 5.ics */,
-			);
-			path = calendar_2;
-			sourceTree = "<group>";
-		};
-		66FAA02D155B16B600B6FAC1 /* home_splits_shared */ = {
-			isa = PBXGroup;
-			children = (
-				66FAA02E155B16B600B6FAC1 /* calendar_1 */,
-			);
-			path = home_splits_shared;
-			sourceTree = "<group>";
-		};
-		66FAA02E155B16B600B6FAC1 /* calendar_1 */ = {
-			isa = PBXGroup;
-			children = (
-			);
-			path = calendar_1;
-			sourceTree = "<group>";
-		};
-		66FAA038155B16B600B6FAC1 /* carddav */ = {
-			isa = PBXGroup;
-			children = (
-				66FAA039155B16B600B6FAC1 /* __init__.py */,
-				66FAA03A155B16B600B6FAC1 /* datastore */,
-				66FAA05E155B16B600B6FAC1 /* iaddressbookstore.py */,
-				66FAA05F155B16B600B6FAC1 /* resource.py */,
-			);
-			path = carddav;
-			sourceTree = "<group>";
-		};
-		66FAA03A155B16B600B6FAC1 /* datastore */ = {
-			isa = PBXGroup;
-			children = (
-				66FAA03B155B16B600B6FAC1 /* __init__.py */,
-				66FAA03C155B16B600B6FAC1 /* file.py */,
-				66FAA03D155B16B600B6FAC1 /* index_file.py */,
-				66FAA03E155B16B600B6FAC1 /* sql.py */,
-				66FAA03F155B16B600B6FAC1 /* test */,
-				66FAA05D155B16B600B6FAC1 /* util.py */,
-			);
-			path = datastore;
-			sourceTree = "<group>";
-		};
-		66FAA03F155B16B600B6FAC1 /* test */ = {
-			isa = PBXGroup;
-			children = (
-				66FAA040155B16B600B6FAC1 /* __init__.py */,
-				66FAA041155B16B600B6FAC1 /* addressbook_store */,
-				66FAA059155B16B600B6FAC1 /* common.py */,
-				66FAA05A155B16B600B6FAC1 /* test_file.py */,
-				66FAA05B155B16B600B6FAC1 /* test_index_file.py */,
-				66FAA05C155B16B600B6FAC1 /* test_sql.py */,
-			);
-			path = test;
-			sourceTree = "<group>";
-		};
-		66FAA041155B16B600B6FAC1 /* addressbook_store */ = {
-			isa = PBXGroup;
-			children = (
-				66FAA042155B16B600B6FAC1 /* ho */,
-			);
-			path = addressbook_store;
-			sourceTree = "<group>";
-		};
-		66FAA042155B16B600B6FAC1 /* ho */ = {
-			isa = PBXGroup;
-			children = (
-				66FAA043155B16B600B6FAC1 /* me */,
-			);
-			path = ho;
-			sourceTree = "<group>";
-		};
-		66FAA043155B16B600B6FAC1 /* me */ = {
-			isa = PBXGroup;
-			children = (
-				66FAA044155B16B600B6FAC1 /* home1 */,
-				66FAA055155B16B600B6FAC1 /* home_bad */,
-			);
-			path = me;
-			sourceTree = "<group>";
-		};
-		66FAA044155B16B600B6FAC1 /* home1 */ = {
-			isa = PBXGroup;
-			children = (
-				66FAA045155B16B600B6FAC1 /* addressbook_1 */,
-				66FAA049155B16B600B6FAC1 /* addressbook_2 */,
-				66FAA054155B16B600B6FAC1 /* addressbook_empty */,
-			);
-			path = home1;
-			sourceTree = "<group>";
-		};
-		66FAA045155B16B600B6FAC1 /* addressbook_1 */ = {
-			isa = PBXGroup;
-			children = (
-				66FAA046155B16B600B6FAC1 /* 1.vcf */,
-				66FAA047155B16B600B6FAC1 /* 2.vcf */,
-				66FAA048155B16B600B6FAC1 /* 3.vcf */,
-			);
-			path = addressbook_1;
-			sourceTree = "<group>";
-		};
-		66FAA049155B16B600B6FAC1 /* addressbook_2 */ = {
-			isa = PBXGroup;
-			children = (
-				66FAA04A155B16B600B6FAC1 /* 3765A955-1B96-41EA-994D-335192BEDCCD.vcf */,
-				66FAA04B155B16B600B6FAC1 /* 44745975-AE6D-4FB0-80A6-A298427E047A.vcf */,
-				66FAA04C155B16B600B6FAC1 /* 44EE78BF-8814-4471-899C-92280CEFB098.vcf */,
-				66FAA04D155B16B600B6FAC1 /* 8424B7F0-C878-4722-B522-EBB07CF48AD7.vcf */,
-				66FAA04E155B16B600B6FAC1 /* 934731C6-1C95-4C40-BE1F-FA4215B2307B.vcf */,
-				66FAA04F155B16B600B6FAC1 /* AFBB77B8-0438-4825-A1DB-A75D76B6C3A8.vcf */,
-				66FAA050155B16B600B6FAC1 /* ED7A5AEC-AB19-4CE0-AD6A-2923A3E5C4E1.vcf */,
-				66FAA051155B16B600B6FAC1 /* ED7A5AEC-AB19-4CE0-AD6A-2923A3E5C4E2.vcf */,
-				66FAA052155B16B600B6FAC1 /* F0A6918D-8E09-43FA-9684-226810B8A96F.vcf */,
-				66FAA053155B16B600B6FAC1 /* FCBA0FA3-00B2-4C95-B4EC-4CCC4843F8B1.vcf */,
-			);
-			path = addressbook_2;
-			sourceTree = "<group>";
-		};
-		66FAA054155B16B600B6FAC1 /* addressbook_empty */ = {
-			isa = PBXGroup;
-			children = (
-			);
-			path = addressbook_empty;
-			sourceTree = "<group>";
-		};
-		66FAA055155B16B600B6FAC1 /* home_bad */ = {
-			isa = PBXGroup;
-			children = (
-				66FAA056155B16B600B6FAC1 /* addressbook_bad */,
-			);
-			path = home_bad;
-			sourceTree = "<group>";
-		};
-		66FAA056155B16B600B6FAC1 /* addressbook_bad */ = {
-			isa = PBXGroup;
-			children = (
-				66FAA057155B16B600B6FAC1 /* 1.vcf */,
-				66FAA058155B16B600B6FAC1 /* 2.vcf */,
-			);
-			path = addressbook_bad;
-			sourceTree = "<group>";
-		};
-		66FAA060155B16B600B6FAC1 /* common */ = {
-			isa = PBXGroup;
-			children = (
-				66FAA061155B16B600B6FAC1 /* __init__.py */,
-				66FAA062155B16B600B6FAC1 /* datastore */,
-				66FAA0A7155B16B600B6FAC1 /* icommondatastore.py */,
-				66FAA0A8155B16B600B6FAC1 /* inotifications.py */,
-			);
-			path = common;
-			sourceTree = "<group>";
-		};
-		66FAA062155B16B600B6FAC1 /* datastore */ = {
-			isa = PBXGroup;
-			children = (
-				66FAA063155B16B600B6FAC1 /* __init__.py */,
-				66FAA064155B16B600B6FAC1 /* file.py */,
-				66FAA065155B16B600B6FAC1 /* sql.py */,
-				66FAA066155B16B600B6FAC1 /* sql_legacy.py */,
-				66FAA067155B16B600B6FAC1 /* sql_schema */,
-				66FAA07D155B16B600B6FAC1 /* sql_tables.py */,
-				66FAA07E155B16B600B6FAC1 /* test */,
-				66FAA083155B16B600B6FAC1 /* upgrade */,
-			);
-			path = datastore;
-			sourceTree = "<group>";
-		};
-		66FAA067155B16B600B6FAC1 /* sql_schema */ = {
-			isa = PBXGroup;
-			children = (
-				66FAA068155B16B600B6FAC1 /* current.sql */,
-				66FAA069155B16B600B6FAC1 /* old */,
-				66FAA06F155B16B600B6FAC1 /* upgrades */,
-			);
-			path = sql_schema;
-			sourceTree = "<group>";
-		};
-		66FAA069155B16B600B6FAC1 /* old */ = {
-			isa = PBXGroup;
-			children = (
-				66FAA06A155B16B600B6FAC1 /* v3.sql */,
-				66FAA06B155B16B600B6FAC1 /* v4.sql */,
-				66FAA06C155B16B600B6FAC1 /* v5.sql */,
-				66FAA06D155B16B600B6FAC1 /* v6.sql */,
-				66FAA06E155B16B600B6FAC1 /* v7.sql */,
-			);
-			path = old;
-			sourceTree = "<group>";
-		};
-		66FAA06F155B16B600B6FAC1 /* upgrades */ = {
-			isa = PBXGroup;
-			children = (
-				66FAA070155B16B600B6FAC1 /* oracle-dialect */,
-				66FAA076155B16B600B6FAC1 /* postgres-dialect */,
-				66FAA07C155B16B600B6FAC1 /* upgrade_template.sql */,
-			);
-			path = upgrades;
-			sourceTree = "<group>";
-		};
-		66FAA070155B16B600B6FAC1 /* oracle-dialect */ = {
-			isa = PBXGroup;
-			children = (
-				66FAA071155B16B600B6FAC1 /* upgrade_from_3_to_4.sql */,
-				66FAA072155B16B600B6FAC1 /* upgrade_from_4_to_5.sql */,
-				66FAA073155B16B600B6FAC1 /* upgrade_from_5_to_6.sql */,
-				66FAA074155B16B600B6FAC1 /* upgrade_from_6_to_7.sql */,
-				66FAA075155B16B600B6FAC1 /* upgrade_from_7_to_8.sql */,
-			);
-			path = "oracle-dialect";
-			sourceTree = "<group>";
-		};
-		66FAA076155B16B600B6FAC1 /* postgres-dialect */ = {
-			isa = PBXGroup;
-			children = (
-				66FAA077155B16B600B6FAC1 /* upgrade_from_3_to_4.sql */,
-				66FAA078155B16B600B6FAC1 /* upgrade_from_4_to_5.sql */,
-				66FAA079155B16B600B6FAC1 /* upgrade_from_5_to_6.sql */,
-				66FAA07A155B16B600B6FAC1 /* upgrade_from_6_to_7.sql */,
-				66FAA07B155B16B600B6FAC1 /* upgrade_from_7_to_8.sql */,
-			);
-			path = "postgres-dialect";
-			sourceTree = "<group>";
-		};
-		66FAA07E155B16B600B6FAC1 /* test */ = {
-			isa = PBXGroup;
-			children = (
-				66FAA07F155B16B600B6FAC1 /* __init__.py */,
-				66FAA080155B16B600B6FAC1 /* test_sql.py */,
-				66FAA081155B16B600B6FAC1 /* test_sql_tables.py */,
-				66FAA082155B16B600B6FAC1 /* util.py */,
-			);
-			path = test;
-			sourceTree = "<group>";
-		};
-		66FAA083155B16B600B6FAC1 /* upgrade */ = {
-			isa = PBXGroup;
-			children = (
-				66FAA084155B16B600B6FAC1 /* __init__.py */,
-				66FAA085155B16B600B6FAC1 /* file */,
-				66FAA087155B16B600B6FAC1 /* migrate.py */,
-				66FAA088155B16B600B6FAC1 /* sql */,
-				66FAA0A4155B16B600B6FAC1 /* test */,
-			);
-			path = upgrade;
-			sourceTree = "<group>";
-		};
-		66FAA085155B16B600B6FAC1 /* file */ = {
-			isa = PBXGroup;
-			children = (
-				66FAA086155B16B600B6FAC1 /* __init__.py */,
-			);
-			path = file;
-			sourceTree = "<group>";
-		};
-		66FAA088155B16B600B6FAC1 /* sql */ = {
-			isa = PBXGroup;
-			children = (
-				66FAA089155B16B600B6FAC1 /* __init__.py */,
-				66FAA08A155B16B600B6FAC1 /* test */,
-				66FAA09F155B16B600B6FAC1 /* upgrade.py */,
-				66FAA0A0155B16B600B6FAC1 /* upgrades */,
-			);
-			path = sql;
-			sourceTree = "<group>";
-		};
-		66FAA08A155B16B600B6FAC1 /* test */ = {
-			isa = PBXGroup;
-			children = (
-				66FAA08B155B16B600B6FAC1 /* __init__.py */,
-				66FAA08C155B16B600B6FAC1 /* fake_schema1 */,
-				66FAA091155B16B600B6FAC1 /* fake_schema2 */,
-				66FAA098155B16B600B6FAC1 /* fake_schema3 */,
-				66FAA09E155B16B600B6FAC1 /* test_upgrade.py */,
-			);
-			path = test;
-			sourceTree = "<group>";
-		};
-		66FAA08C155B16B600B6FAC1 /* fake_schema1 */ = {
-			isa = PBXGroup;
-			children = (
-				66FAA08D155B16B600B6FAC1 /* current.sql */,
-				66FAA08E155B16B600B6FAC1 /* upgrades */,
-			);
-			path = fake_schema1;
-			sourceTree = "<group>";
-		};
-		66FAA08E155B16B600B6FAC1 /* upgrades */ = {
-			isa = PBXGroup;
-			children = (
-				66FAA08F155B16B600B6FAC1 /* fake_dialect */,
-			);
-			path = upgrades;
-			sourceTree = "<group>";
-		};
-		66FAA08F155B16B600B6FAC1 /* fake_dialect */ = {
-			isa = PBXGroup;
-			children = (
-				66FAA090155B16B600B6FAC1 /* upgrade_from_3_to_4.sql */,
-			);
-			path = fake_dialect;
-			sourceTree = "<group>";
-		};
-		66FAA091155B16B600B6FAC1 /* fake_schema2 */ = {
-			isa = PBXGroup;
-			children = (
-				66FAA092155B16B600B6FAC1 /* current.sql */,
-				66FAA093155B16B600B6FAC1 /* upgrades */,
-			);
-			path = fake_schema2;
-			sourceTree = "<group>";
-		};
-		66FAA093155B16B600B6FAC1 /* upgrades */ = {
-			isa = PBXGroup;
-			children = (
-				66FAA094155B16B600B6FAC1 /* fake_dialect */,
-			);
-			path = upgrades;
-			sourceTree = "<group>";
-		};
-		66FAA094155B16B600B6FAC1 /* fake_dialect */ = {
-			isa = PBXGroup;
-			children = (
-				66FAA095155B16B600B6FAC1 /* upgrade_from_3_to_4.sql */,
-				66FAA096155B16B600B6FAC1 /* upgrade_from_3_to_5.sql */,
-				66FAA097155B16B600B6FAC1 /* upgrade_from_4_to_5.sql */,
-			);
-			path = fake_dialect;
-			sourceTree = "<group>";
-		};
-		66FAA098155B16B600B6FAC1 /* fake_schema3 */ = {
-			isa = PBXGroup;
-			children = (
-				66FAA099155B16B600B6FAC1 /* current.sql */,
-				66FAA09A155B16B600B6FAC1 /* upgrades */,
-			);
-			path = fake_schema3;
-			sourceTree = "<group>";
-		};
-		66FAA09A155B16B600B6FAC1 /* upgrades */ = {
-			isa = PBXGroup;
-			children = (
-				66FAA09B155B16B600B6FAC1 /* fake_dialect */,
-			);
-			path = upgrades;
-			sourceTree = "<group>";
-		};
-		66FAA09B155B16B600B6FAC1 /* fake_dialect */ = {
-			isa = PBXGroup;
-			children = (
-				66FAA09C155B16B600B6FAC1 /* upgrade_from_3_to_4.sql */,
-				66FAA09D155B16B600B6FAC1 /* upgrade_from_4_to_5.sql */,
-			);
-			path = fake_dialect;
-			sourceTree = "<group>";
-		};
-		66FAA0A0155B16B600B6FAC1 /* upgrades */ = {
-			isa = PBXGroup;
-			children = (
-				66FAA0A1155B16B600B6FAC1 /* __init__.py */,
-				66FAA0A2155B16B600B6FAC1 /* upgrade_from_1_to_2.py */,
-				66FAA0A3155B16B600B6FAC1 /* util.py */,
-			);
-			path = upgrades;
-			sourceTree = "<group>";
-		};
-		66FAA0A4155B16B600B6FAC1 /* test */ = {
-			isa = PBXGroup;
-			children = (
-				66FAA0A5155B16B600B6FAC1 /* __init__.py */,
-				66FAA0A6155B16B600B6FAC1 /* test_migrate.py */,
-			);
-			path = test;
-			sourceTree = "<group>";
-		};
-		66FAA0AA155B16B600B6FAC1 /* xml */ = {
-			isa = PBXGroup;
-			children = (
-				66FAA0AB155B16B600B6FAC1 /* __init__.py */,
-				66FAA0AC155B16B600B6FAC1 /* base.py */,
-				66FAA0AD155B16B600B6FAC1 /* draft_sync.py */,
-				66FAA0AE155B16B600B6FAC1 /* element.py */,
-				66FAA0AF155B16B600B6FAC1 /* extensions.py */,
-				66FAA0B0155B16B600B6FAC1 /* parser.py */,
-				66FAA0B1155B16B600B6FAC1 /* parser_base.py */,
-				66FAA0B2155B16B600B6FAC1 /* parser_sax.py */,
-				66FAA0B3155B16B600B6FAC1 /* rfc2518.py */,
-				66FAA0B4155B16B600B6FAC1 /* rfc3253.py */,
-				66FAA0B5155B16B600B6FAC1 /* rfc3744.py */,
-				66FAA0B6155B16B600B6FAC1 /* rfc4331.py */,
-				66FAA0B7155B16B600B6FAC1 /* rfc5397.py */,
-				66FAA0B8155B16B600B6FAC1 /* rfc5842.py */,
-				66FAA0B9155B16B600B6FAC1 /* rfc5995.py */,
-				66FAA0BA155B16B600B6FAC1 /* test */,
-				66FAA0BF155B16B600B6FAC1 /* xmlext.py */,
-			);
-			path = xml;
-			sourceTree = "<group>";
-		};
-		66FAA0BA155B16B600B6FAC1 /* test */ = {
-			isa = PBXGroup;
-			children = (
-				66FAA0BB155B16B600B6FAC1 /* __init__.py */,
-				66FAA0BC155B16B600B6FAC1 /* test_base.py */,
-				66FAA0BD155B16B600B6FAC1 /* test_xml.py */,
-				66FAA0BE155B16B600B6FAC1 /* test_xml_rfc3744.py */,
-			);
-			path = test;
-			sourceTree = "<group>";
-		};
-/* End PBXGroup section */
+/* End PBXLegacyTarget section */
 
 /* Begin PBXProject section */
-		35069C0B0922B94100389D48 /* Project object */ = {
+		35E050F8170E534C00D4A7CA /* Project object */ = {
 			isa = PBXProject;
-			buildConfigurationList = 35069C0C0922B94100389D48 /* Build configuration list for PBXProject "CalendarServer" */;
-			compatibilityVersion = "Xcode 2.4";
+			attributes = {
+				LastUpgradeCheck = 0460;
+				ORGANIZATIONNAME = "Mac OS Forge";
+			};
+			buildConfigurationList = 35E050FB170E534C00D4A7CA /* Build configuration list for PBXProject "CalendarServer" */;
+			compatibilityVersion = "Xcode 3.2";
 			developmentRegion = English;
 			hasScannedForEncodings = 0;
 			knownRegions = (
 				en,
-				English,
 			);
-			mainGroup = 35069C090922B94100389D48;
+			mainGroup = 35E050F7170E534C00D4A7CA;
 			projectDirPath = "";
 			projectRoot = "";
 			targets = (
+				35E050FC170E534C00D4A7CA /* CalendarServer */,
 			);
 		};
 /* End PBXProject section */
 
-/* Begin PBXVariantGroup section */
-		66FA9B2E155B16B500B6FAC1 /* calendarserver.strings */ = {
-			isa = PBXVariantGroup;
-			children = (
-				66FA9B2F155B16B500B6FAC1 /* English */,
-			);
-			name = calendarserver.strings;
-			sourceTree = "<group>";
-		};
-/* End PBXVariantGroup section */
-
 /* Begin XCBuildConfiguration section */
-		35069C0D0922B94100389D48 /* Debug */ = {
+		35E050FD170E534C00D4A7CA /* Debug */ = {
 			isa = XCBuildConfiguration;
 			buildSettings = {
-				COPY_PHASE_STRIP = NO;
 			};
 			name = Debug;
 		};
-		35069C0E0922B94100389D48 /* Release */ = {
+		35E050FE170E534C00D4A7CA /* Release */ = {
 			isa = XCBuildConfiguration;
 			buildSettings = {
-				COPY_PHASE_STRIP = YES;
 			};
 			name = Release;
 		};
+		35E05100170E534C00D4A7CA /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+			};
+			name = Debug;
+		};
+		35E05101170E534C00D4A7CA /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+			};
+			name = Release;
+		};
 /* End XCBuildConfiguration section */
 
 /* Begin XCConfigurationList section */
-		35069C0C0922B94100389D48 /* Build configuration list for PBXProject "CalendarServer" */ = {
+		35E050FB170E534C00D4A7CA /* Build configuration list for PBXProject "CalendarServer" */ = {
 			isa = XCConfigurationList;
 			buildConfigurations = (
-				35069C0D0922B94100389D48 /* Debug */,
-				35069C0E0922B94100389D48 /* Release */,
+				35E050FD170E534C00D4A7CA /* Debug */,
+				35E050FE170E534C00D4A7CA /* Release */,
 			);
 			defaultConfigurationIsVisible = 0;
 			defaultConfigurationName = Release;
 		};
+		35E050FF170E534C00D4A7CA /* Build configuration list for PBXLegacyTarget "CalendarServer" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				35E05100170E534C00D4A7CA /* Debug */,
+				35E05101170E534C00D4A7CA /* Release */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
 /* End XCConfigurationList section */
 	};
-	rootObject = 35069C0B0922B94100389D48 /* Project object */;
+	rootObject = 35E050F8170E534C00D4A7CA /* Project object */;
 }


Property changes on: CalendarServer/branches/users/gaya/directorybacker/support/CalendarServer.xcodeproj/project.xcworkspace
___________________________________________________________________
Added: svn:ignore
   + xcuserdata


Deleted: CalendarServer/branches/users/gaya/directorybacker/support/CalendarServer.xcodeproj/project.xcworkspace/contents.xcworkspacedata
===================================================================
--- CalendarServer/trunk/support/CalendarServer.xcodeproj/project.xcworkspace/contents.xcworkspacedata	2013-04-21 14:53:53 UTC (rev 11081)
+++ CalendarServer/branches/users/gaya/directorybacker/support/CalendarServer.xcodeproj/project.xcworkspace/contents.xcworkspacedata	2013-04-22 18:46:28 UTC (rev 11083)
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<Workspace
-   version = "1.0">
-   <FileRef
-      location = "self:CalendarServer.xcodeproj">
-   </FileRef>
-</Workspace>

Copied: CalendarServer/branches/users/gaya/directorybacker/support/CalendarServer.xcodeproj/project.xcworkspace/contents.xcworkspacedata (from rev 11081, CalendarServer/trunk/support/CalendarServer.xcodeproj/project.xcworkspace/contents.xcworkspacedata)
===================================================================
--- CalendarServer/branches/users/gaya/directorybacker/support/CalendarServer.xcodeproj/project.xcworkspace/contents.xcworkspacedata	                        (rev 0)
+++ CalendarServer/branches/users/gaya/directorybacker/support/CalendarServer.xcodeproj/project.xcworkspace/contents.xcworkspacedata	2013-04-22 18:46:28 UTC (rev 11083)
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Workspace
+   version = "1.0">
+   <FileRef
+      location = "self:CalendarServer.xcodeproj">
+   </FileRef>
+</Workspace>

Deleted: CalendarServer/branches/users/gaya/directorybacker/support/Makefile.Apple
===================================================================
--- CalendarServer/branches/users/gaya/directorybacker/support/Makefile.Apple	2013-04-22 18:44:41 UTC (rev 11082)
+++ CalendarServer/branches/users/gaya/directorybacker/support/Makefile.Apple	2013-04-22 18:46:28 UTC (rev 11083)
@@ -1,170 +0,0 @@
-# -*- mode: Makefile; -*-
-##
-# B&I Makefile for CalendarServer
-#
-# This is only useful internally at Apple, probably.
-##
-# Copyright (c) 2005-2013 Apple Inc. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-##
-
-# Project info
-Project	    = CalendarServer
-ProjectName = CalendarServer
-UserType    = Server
-ToolType    = Applications
-
-# Include common makefile targets for B&I
-include $(MAKEFILEPATH)/CoreOS/ReleaseControl/Common.make
-include /AppleInternal/ServerTools/ServerBuildVariables.xcconfig
-
-SIPP = $(SERVER_INSTALL_PATH_PREFIX)
-SERVERSETUP = $(SIPP)$(NSSYSTEMDIR)$(NSLIBRARYSUBDIR)/ServerSetup
-
-Cruft += .dependencies
-Extra_Environment += PATH="$(SIPP)/usr/bin:$$PATH"
-
-CALDAVDSUBDIR = /caldavd
-
-PYTHON = $(USRBINDIR)/python
-PY_HOME = $(SIPP)$(SHAREDIR)$(CALDAVDSUBDIR)
-PY_INSTALL_FLAGS = --root="$(DSTROOT)" --prefix="$(SIPP)" --install-lib="$(PY_HOME)/lib/python" --install-scripts="$(SIPP)$(LIBEXECDIR)$(CALDAVDSUBDIR)"
-CS_INSTALL_FLAGS = --install-scripts="$(SIPP)$(USRSBINDIR)" --install-data="$(SIPP)$(ETCDIR)"
-CS_BUILD_EXT_FLAGS = --include-dirs="$(SIPP)/usr/include" --library-dirs="$(SIPP)/usr/lib"
-
-CS_USER  = _calendar
-CS_GROUP = _calendar
-
-#
-# Build
-#
-
-.phony: $(Project) pycalendar build setup prep install install-ossfiles buildit
-
-CalDAVTester::          $(BuildDirectory)/CalDAVTester
-PyKerberos::            $(BuildDirectory)/PyKerberos
-pycalendar::            $(BuildDirectory)/pycalendar
-PyGreSQL-4.0::          $(BuildDirectory)/PyGreSQL-4.0
-sqlparse-0.1.2::        $(BuildDirectory)/sqlparse-0.1.2
-setproctitle-1.1.6::	$(BuildDirectory)/setproctitle-1.1.6
-psutil-0.6.1::		$(BuildDirectory)/psutil-0.6.1
-pycrypto-2.5::		$(BuildDirectory)/pycrypto-2.5
-$(Project)::            $(BuildDirectory)/$(Project)
-
-build:: PyKerberos pycalendar PyGreSQL-4.0 sqlparse-0.1.2 setproctitle-1.1.6 psutil-0.6.1 pycrypto-2.5 $(Project)
-
-setup:
-	$(_v) ./run -g
-
-prep:: setup CalDAVTester.tgz PyKerberos.tgz pycalendar.tgz PyGreSQL-4.0.tgz sqlparse-0.1.2.tgz setproctitle-1.1.6.tgz psutil-0.6.1.tgz pycrypto-2.5.tgz
-
-PyKerberos pycalendar PyGreSQL-4.0 sqlparse-0.1.2 setproctitle-1.1.6 psutil-0.6.1 pycrypto-2.5 $(Project)::
-	@echo "Building $@..."
-	$(_v) cd $(BuildDirectory)/$@ && $(Environment) $(PYTHON) setup.py build
-
-install:: build
-	$(_v) cd $(BuildDirectory)/$(Project)         && $(Environment) $(PYTHON) setup.py build_ext $(CS_BUILD_EXT_FLAGS) install $(PY_INSTALL_FLAGS) $(CS_INSTALL_FLAGS)
-	$(_v) cd $(BuildDirectory)/PyKerberos         && $(Environment) $(PYTHON) setup.py install $(PY_INSTALL_FLAGS)
-	$(_v) cd $(BuildDirectory)/pycalendar         && $(Environment) $(PYTHON) setup.py install $(PY_INSTALL_FLAGS)
-	$(_v) cd $(BuildDirectory)/PyGreSQL-4.0       && $(Environment) $(PYTHON) setup.py install $(PY_INSTALL_FLAGS)
-	$(_v) cd $(BuildDirectory)/sqlparse-0.1.2     && $(Environment) $(PYTHON) setup.py install $(PY_INSTALL_FLAGS)
-	$(_v) cd $(BuildDirectory)/setproctitle-1.1.6 && $(Environment) $(PYTHON) setup.py install $(PY_INSTALL_FLAGS)
-	$(_v) cd $(BuildDirectory)/psutil-0.6.1       && $(Environment) $(PYTHON) setup.py install $(PY_INSTALL_FLAGS)
-	$(_v) cd $(BuildDirectory)/pycrypto-2.5       && $(Environment) $(PYTHON) setup.py install $(PY_INSTALL_FLAGS)
-	$(_v) for so in $$(find "$(DSTROOT)$(PY_HOME)/lib" -type f -name '*.so'); do $(STRIP) -Sx "$${so}"; done 
-	$(_v) $(INSTALL_DIRECTORY) "$(DSTROOT)$(SIPP)$(ETCDIR)$(CALDAVDSUBDIR)"
-	$(_v) $(INSTALL_FILE) "$(Sources)/conf/caldavd-apple.plist" "$(DSTROOT)$(SIPP)$(ETCDIR)$(CALDAVDSUBDIR)/caldavd-apple.plist"
-	$(_v) chmod -R ugo+r "$(DSTROOT)$(PY_HOME)"
-	$(_v) for f in $$(find "$(DSTROOT)$(SIPP)$(ETCDIR)" -type f ! -name '*.default'); do cp "$${f}" "$${f}.default"; done
-
-install::
-	@echo "Installing manual pages..."
-	$(_v) $(INSTALL_DIRECTORY) "$(DSTROOT)$(SIPP)$(MANDIR)/man8"
-	$(_v) $(INSTALL_FILE) "$(Sources)/doc/caldavd.8"                              "$(DSTROOT)$(SIPP)$(MANDIR)/man8"
-	$(_v) $(INSTALL_FILE) "$(Sources)/doc/calendarserver_bootstrap_database.8"    "$(DSTROOT)$(SIPP)$(MANDIR)/man8"
-	$(_v) $(INSTALL_FILE) "$(Sources)/doc/calendarserver_command_gateway.8"       "$(DSTROOT)$(SIPP)$(MANDIR)/man8"
-	$(_v) $(INSTALL_FILE) "$(Sources)/doc/calendarserver_export.8"                "$(DSTROOT)$(SIPP)$(MANDIR)/man8"
-	$(_v) $(INSTALL_FILE) "$(Sources)/doc/calendarserver_manage_principals.8"     "$(DSTROOT)$(SIPP)$(MANDIR)/man8"
-	$(_v) $(INSTALL_FILE) "$(Sources)/doc/calendarserver_migrate_resources.8"     "$(DSTROOT)$(SIPP)$(MANDIR)/man8"
-	$(_v) $(INSTALL_FILE) "$(Sources)/doc/calendarserver_purge_attachments.8"     "$(DSTROOT)$(SIPP)$(MANDIR)/man8"
-	$(_v) $(INSTALL_FILE) "$(Sources)/doc/calendarserver_purge_events.8"          "$(DSTROOT)$(SIPP)$(MANDIR)/man8"
-	$(_v) $(INSTALL_FILE) "$(Sources)/doc/calendarserver_purge_principals.8"      "$(DSTROOT)$(SIPP)$(MANDIR)/man8"
-	$(_v) $(INSTALL_FILE) "$(Sources)/doc/calendarserver_manage_push.8"           "$(DSTROOT)$(SIPP)$(MANDIR)/man8"
-	$(_v) $(INSTALL_FILE) "$(Sources)/doc/calendarserver_shell.8"                 "$(DSTROOT)$(SIPP)$(MANDIR)/man8"
-	$(_v) gzip -9 -f "$(DSTROOT)$(SIPP)$(MANDIR)/man8/"*.[0-9]
-	@echo "Installing launchd config..."
-	$(_v) $(INSTALL_DIRECTORY) "$(DSTROOT)$(NSLOCALDIR)/$(NSLIBRARYSUBDIR)/Server/Calendar and Contacts"
-	$(_v) $(INSTALL_DIRECTORY) -o "$(CS_USER)" -g "$(CS_GROUP)" -m 0755 "$(DSTROOT)$(VARDIR)/log$(CALDAVDSUBDIR)"
-	$(_v) $(INSTALL_DIRECTORY) "$(DSTROOT)$(SIPP)$(NSLIBRARYDIR)/LaunchDaemons"
-	$(_v) $(INSTALL_FILE) "$(Sources)/contrib/launchd/calendarserver.plist" "$(DSTROOT)$(SIPP)$(NSLIBRARYDIR)/LaunchDaemons/org.calendarserver.calendarserver.plist"
-	@echo "Installing changeip script..."
-	$(_v) $(INSTALL_DIRECTORY) "$(DSTROOT)$(SIPP)$(LIBEXECDIR)/changeip"
-	$(_v) $(INSTALL_FILE) "$(Sources)/calendarserver/tools/changeip_calendar.py" "$(DSTROOT)$(SIPP)$(LIBEXECDIR)/changeip/changeip_calendar.py"
-	$(_v) chmod ugo+x "$(DSTROOT)$(SIPP)$(LIBEXECDIR)/changeip/changeip_calendar.py"
-
-install::
-	@echo "Installing CalDAVTester package..."
-	$(_v) $(INSTALL_DIRECTORY) "$(DSTROOT)/AppleInternal/ServerTools"
-	$(_v) $(INSTALL_FILE) "$(Sources)/CalDAVTester.tgz" "$(DSTROOT)/AppleInternal/ServerTools/CalDAVTester.tgz"
-
-#
-# Automatic Extract
-#
-
-$(BuildDirectory)/$(Project):
-	@echo "Copying source for $(Project)..."
-	$(_v) $(MKDIR) -p "$@"
-	$(_v) pax -rw bin conf Makefile lib-patches setup.py calendarserver twistedcaldav twext txdav twisted support "$@/"
-
-$(BuildDirectory)/%: %.tgz
-	@echo "Extracting source for $(notdir $<)..."
-	$(_v) $(MKDIR) -p "$(BuildDirectory)"
-	$(_v) $(RMDIR) "$@"
-	$(_v) $(TAR) -C "$(BuildDirectory)" -xzf "$<"
-
-%.tgz: ../%
-	@echo "Archiving sources for $(notdir $<)..."
-	$(_v) if [ -f "$</setup.py" ] && grep setuptools "$</setup.py" > /dev/null; then \
-	        echo "Working around setuptools' stupid need to download a new version."; \
-	        cd "$<" && $(PYTHON) "setup.py" --help >/dev/null; \
-	      fi
-	$(_v) $(TAR) -C "$(dir $<)"        \
-	          --exclude=.svn           \
-	          --exclude=build          \
-	          --exclude=_trial_temp    \
-	          --exclude=dropin.cache   \
-	          -czf "$@" "$(notdir $<)"
-
-#
-# Open Source Hooey
-#
-
-OSV = $(USRDIR)/local/OpenSourceVersions
-OSL = $(USRDIR)/local/OpenSourceLicenses
-
-#install:: install-ossfiles
-
-install-ossfiles::
-	$(_v) $(INSTALL_DIRECTORY) $(DSTROOT)/$(OSV)
-	$(_v) $(INSTALL_FILE) $(Sources)/$(ProjectName).plist $(DSTROOT)/$(OSV)/$(ProjectName).plist
-	$(_v) $(INSTALL_DIRECTORY) $(DSTROOT)/$(OSL)
-	$(_v) $(INSTALL_FILE) $(BuildDirectory)/$(Project)/LICENSE $(DSTROOT)/$(OSL)/$(ProjectName).txt
-
-#
-# B&I Hooey
-#
-
-buildit: prep
-	@echo "Running buildit..."
-	$(_v) sudo ~rc/bin/buildit $(CC_Archs) $(Sources)

Copied: CalendarServer/branches/users/gaya/directorybacker/support/XCode.make (from rev 11081, CalendarServer/trunk/support/XCode.make)
===================================================================
--- CalendarServer/branches/users/gaya/directorybacker/support/XCode.make	                        (rev 0)
+++ CalendarServer/branches/users/gaya/directorybacker/support/XCode.make	2013-04-22 18:46:28 UTC (rev 11083)
@@ -0,0 +1,34 @@
+# -*- mode: Makefile; -*-
+##
+# XCode Makefile for CalendarServer
+##
+# Copyright (c) 2005-2013 Apple Inc. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+##
+
+default: build
+
+#
+# Run sed to suppress XCode's misguided attempts to interpret our output.
+#
+build::
+	../run -s 2>&1 \
+	  | sed \
+	    -e 's|error|oops|' \
+	    -e 's|warning|oopsie|' \
+	    -e 's|^\(..*\):\([0-9][0-9]*\):\([0-9][0-9]*\): |\1-\2-\3: |';
+
+clean::
+	rm -rf ../.dependencies/ ../build/ ../data/ ../calendarserver/version.py;
+	find .. -name '*.pyc' -o -name '*.so' -o -name dropin.cache -print0 | xargs -0 rm -f;

Modified: CalendarServer/branches/users/gaya/directorybacker/support/build.sh
===================================================================
--- CalendarServer/branches/users/gaya/directorybacker/support/build.sh	2013-04-22 18:44:41 UTC (rev 11082)
+++ CalendarServer/branches/users/gaya/directorybacker/support/build.sh	2013-04-22 18:46:28 UTC (rev 11083)
@@ -552,7 +552,7 @@
       ;;
     FreeBSD)
       ncpu="$(sysctl hw.ncpu)";
-      ncpu="${cpu##hw.ncpu: }";
+      ncpu="${ncpu##hw.ncpu: }";
       ;;
   esac;
 
@@ -775,7 +775,7 @@
     "${pypi}/p/python-ldap/${ld}.tar.gz";
 
   # XXX actually PyCalendar should be imported in-place.
-  py_dependency -fe -i "src" -r 10554 \
+  py_dependency -fe -i "src" -r 11005 \
     "pycalendar" "pycalendar" "pycalendar" \
     "${svn_uri_base}/PyCalendar/trunk";
 

Modified: CalendarServer/branches/users/gaya/directorybacker/support/submit
===================================================================
--- CalendarServer/branches/users/gaya/directorybacker/support/submit	2013-04-22 18:44:41 UTC (rev 11082)
+++ CalendarServer/branches/users/gaya/directorybacker/support/submit	2013-04-22 18:46:28 UTC (rev 11083)
@@ -144,7 +144,7 @@
 
 echo ""
 echo "Tweaking for B&I...";
-ln -s support/Makefile.Apple "${wc}/Makefile";
+ln -s support/Apple.make "${wc}/Makefile";
 
 version_file="${wc}/SubmissionInfo.xml";
 cat - >> "${version_file}" <<EOF

Modified: CalendarServer/branches/users/gaya/directorybacker/twext/enterprise/dal/syntax.py
===================================================================
--- CalendarServer/branches/users/gaya/directorybacker/twext/enterprise/dal/syntax.py	2013-04-22 18:44:41 UTC (rev 11082)
+++ CalendarServer/branches/users/gaya/directorybacker/twext/enterprise/dal/syntax.py	2013-04-22 18:46:28 UTC (rev 11083)
@@ -147,7 +147,8 @@
 
     _paramstyles = {
         'pyformat': partial(FixedPlaceholder, "%s"),
-        'numeric': NumericPlaceholder
+        'numeric': NumericPlaceholder,
+        'qmark': defaultPlaceholder,
     }
 
 
@@ -1655,6 +1656,12 @@
 
 
     def _toSQL(self, queryGenerator):
+        if queryGenerator.dialect == SQLITE_DIALECT:
+            # FIXME - this is only stubbed out for testing right now, actual
+            # concurrency would require some kind of locking statement here.
+            # BEGIN IMMEDIATE maybe, if that's okay in the middle of a
+            # transaction or repeatedly?
+            return SQLFragment('select null')
         return SQLFragment('lock table ').append(
             self.table.subSQL(queryGenerator, [self.table])).append(
             SQLFragment(' in %s mode' % (self.mode,)))

Modified: CalendarServer/branches/users/gaya/directorybacker/twext/enterprise/fixtures.py
===================================================================
--- CalendarServer/branches/users/gaya/directorybacker/twext/enterprise/fixtures.py	2013-04-22 18:44:41 UTC (rev 11082)
+++ CalendarServer/branches/users/gaya/directorybacker/twext/enterprise/fixtures.py	2013-04-22 18:46:28 UTC (rev 11083)
@@ -20,10 +20,24 @@
 """
 
 import sqlite3
+from Queue import Empty
+from itertools import count
 
+from zope.interface import implementer
+from zope.interface.verify import verifyClass
+
+from twisted.internet.interfaces import IReactorThreads
+from twisted.python.threadpool import ThreadPool
+
+from twisted.internet.task import Clock
+
 from twext.enterprise.adbapi2 import ConnectionPool
 from twext.enterprise.ienterprise import SQLITE_DIALECT
+from twext.enterprise.ienterprise import POSTGRES_DIALECT
+from twext.enterprise.adbapi2 import DEFAULT_PARAM_STYLE
+from twext.internet.threadutils import ThreadHolder
 
+
 def buildConnectionPool(testCase, schemaText="", dialect=SQLITE_DIALECT):
     """
     Build a L{ConnectionPool} for testing purposes, with the given C{testCase}.
@@ -57,3 +71,513 @@
     pool.startService()
     testCase.addCleanup(pool.stopService)
     return pool
+
+
+
+def resultOf(deferred, propagate=False):
+    """
+    Add a callback and errback which will capture the result of a L{Deferred} in
+    a list, and return that list.  If 'propagate' is True, pass through the
+    results.
+    """
+    results = []
+    if propagate:
+        def cb(r):
+            results.append(r)
+            return r
+    else:
+        cb = results.append
+    deferred.addBoth(cb)
+    return results
+
+
+
+class FakeThreadHolder(ThreadHolder):
+    """
+    Run things to submitted this ThreadHolder on the main thread, so that
+    execution is easier to control.
+    """
+
+    def __init__(self, test):
+        super(FakeThreadHolder, self).__init__(self)
+        self.test = test
+        self.started = False
+        self.stopped = False
+        self._workerIsRunning = False
+
+
+    def start(self):
+        self.started = True
+        return super(FakeThreadHolder, self).start()
+
+
+    def stop(self):
+        result = super(FakeThreadHolder, self).stop()
+        self.stopped = True
+        return result
+
+
+    @property
+    def _get_q(self):
+        return self._q_
+
+
+    @_get_q.setter
+    def _q(self, newq):
+        if newq is not None:
+            oget = newq.get
+            newq.get = lambda: oget(timeout=0)
+            oput = newq.put
+            def putit(x):
+                p = oput(x)
+                if not self.test.paused:
+                    self.flush()
+                return p
+            newq.put = putit
+        self._q_ = newq
+
+
+    def callFromThread(self, f, *a, **k):
+        result = f(*a, **k)
+        return result
+
+
+    def callInThread(self, f, *a, **k):
+        """
+        This should be called only once, to start the worker function that
+        dedicates a thread to this L{ThreadHolder}.
+        """
+        self._workerIsRunning = True
+
+
+    def flush(self):
+        """
+        Fire all deferreds previously returned from submit.
+        """
+        try:
+            while self._workerIsRunning and self._qpull():
+                pass
+            else:
+                self._workerIsRunning = False
+        except Empty:
+            pass
+
+
+
+ at implementer(IReactorThreads)
+class ClockWithThreads(Clock):
+    """
+    A testing reactor that supplies L{IReactorTime} and L{IReactorThreads}.
+    """
+
+    def __init__(self):
+        super(ClockWithThreads, self).__init__()
+        self._pool = ThreadPool()
+
+
+    def getThreadPool(self):
+        """
+        Get the threadpool.
+        """
+        return self._pool
+
+
+    def suggestThreadPoolSize(self, size):
+        """
+        Approximate the behavior of a 'real' reactor.
+        """
+        self._pool.adjustPoolsize(maxthreads=size)
+
+
+    def callInThread(self, thunk, *a, **kw):
+        """
+        No implementation.
+        """
+
+
+    def callFromThread(self, thunk, *a, **kw):
+        """
+        No implementation.
+        """
+
+verifyClass(IReactorThreads, ClockWithThreads)
+
+
+
+class ConnectionPoolHelper(object):
+    """
+    Connection pool setting-up facilities for tests that need a
+    L{ConnectionPool}.
+    """
+
+    dialect = POSTGRES_DIALECT
+    paramstyle = DEFAULT_PARAM_STYLE
+
+    def setUp(self, test=None, connect=None):
+        """
+        Support inheritance by L{TestCase} classes.
+        """
+        if test is None:
+            test = self
+        if connect is None:
+            self.factory = ConnectionFactory()
+            connect = self.factory.connect
+        self.connect = connect
+        self.paused             = False
+        self.holders            = []
+        self.pool               = ConnectionPool(connect,
+                                                 maxConnections=2,
+                                                 dialect=self.dialect,
+                                                 paramstyle=self.paramstyle)
+        self.pool._createHolder = self.makeAHolder
+        self.clock              = self.pool.reactor = ClockWithThreads()
+        self.pool.startService()
+        test.addCleanup(self.flushHolders)
+
+
+    def flushHolders(self):
+        """
+        Flush all pending C{submit}s since C{pauseHolders} was called.  This
+        makes sure the service is stopped and the fake ThreadHolders are all
+        executing their queues so failed tsets can exit cleanly.
+        """
+        self.paused = False
+        for holder in self.holders:
+            holder.flush()
+
+
+    def pauseHolders(self):
+        """
+        Pause all L{FakeThreadHolder}s, causing C{submit} to return an unfired
+        L{Deferred}.
+        """
+        self.paused = True
+
+
+    def makeAHolder(self):
+        """
+        Make a ThreadHolder-alike.
+        """
+        fth = FakeThreadHolder(self)
+        self.holders.append(fth)
+        return fth
+
+
+    def resultOf(self, it):
+        return resultOf(it)
+
+
+    def createTransaction(self):
+        return self.pool.connection()
+
+
+    def translateError(self, err):
+        return err
+
+
+
+class SteppablePoolHelper(ConnectionPoolHelper):
+    """
+    A version of L{ConnectionPoolHelper} that can set up a connection pool
+    capable of firing all its L{Deferred}s on demand, synchronously, by using
+    SQLite.
+    """
+    dialect = SQLITE_DIALECT
+    paramstyle = sqlite3.paramstyle
+
+    def __init__(self, schema):
+        self.schema = schema
+
+
+    def setUp(self, test):
+        connect = synchronousConnectionFactory(test)
+        con = connect()
+        cur = con.cursor()
+        cur.executescript(self.schema)
+        con.commit()
+        super(SteppablePoolHelper, self).setUp(test, connect)
+
+
+    def rows(self, sql):
+        """
+        Get some rows from the database to compare in a test.
+        """
+        con = self.connect()
+        cur = con.cursor()
+        cur.execute(sql)
+        result = cur.fetchall()
+        con.commit()
+        return result
+
+
+
+def synchronousConnectionFactory(test):
+    tmpdb = test.mktemp()
+    def connect():
+        return sqlite3.connect(tmpdb)
+    return connect
+
+
+
+class Child(object):
+    """
+    An object with a L{Parent}, in its list of C{children}.
+    """
+    def __init__(self, parent):
+        self.closed = False
+        self.parent = parent
+        self.parent.children.append(self)
+
+
+    def close(self):
+        if self.parent._closeFailQueue:
+            raise self.parent._closeFailQueue.pop(0)
+        self.closed = True
+
+
+
+class Parent(object):
+    """
+    An object with a list of L{Child}ren.
+    """
+
+    def __init__(self):
+        self.children = []
+        self._closeFailQueue = []
+
+
+    def childCloseWillFail(self, exception):
+        """
+        Closing children of this object will result in the given exception.
+
+        @see: L{ConnectionFactory}
+        """
+        self._closeFailQueue.append(exception)
+
+
+
+class FakeConnection(Parent, Child):
+    """
+    Fake Stand-in for DB-API 2.0 connection.
+
+    @ivar executions: the number of statements which have been executed.
+
+    """
+
+    executions = 0
+
+    def __init__(self, factory):
+        """
+        Initialize list of cursors
+        """
+        Parent.__init__(self)
+        Child.__init__(self, factory)
+        self.id = factory.idcounter.next()
+        self._executeFailQueue = []
+        self._commitCount = 0
+        self._rollbackCount = 0
+
+
+    def executeWillFail(self, thunk):
+        """
+        The next call to L{FakeCursor.execute} will fail with an exception
+        returned from the given callable.
+        """
+        self._executeFailQueue.append(thunk)
+
+
+    @property
+    def cursors(self):
+        "Alias to make tests more readable."
+        return self.children
+
+
+    def cursor(self):
+        return FakeCursor(self)
+
+
+    def commit(self):
+        self._commitCount += 1
+        if self.parent.commitFail:
+            self.parent.commitFail = False
+            raise CommitFail()
+
+
+    def rollback(self):
+        self._rollbackCount += 1
+        if self.parent.rollbackFail:
+            self.parent.rollbackFail = False
+            raise RollbackFail()
+
+
+
+class RollbackFail(Exception):
+    """
+    Sample rollback-failure exception.
+    """
+
+
+
+class CommitFail(Exception):
+    """
+    Sample Commit-failure exception.
+    """
+
+
+
+class FakeCursor(Child):
+    """
+    Fake stand-in for a DB-API 2.0 cursor.
+    """
+    def __init__(self, connection):
+        Child.__init__(self, connection)
+        self.rowcount = 0
+        # not entirely correct, but all we care about is its truth value.
+        self.description = False
+        self.variables = []
+        self.allExecutions = []
+
+
+    @property
+    def connection(self):
+        "Alias to make tests more readable."
+        return self.parent
+
+
+    def execute(self, sql, args=()):
+        self.connection.executions += 1
+        if self.connection._executeFailQueue:
+            raise self.connection._executeFailQueue.pop(0)()
+        self.allExecutions.append((sql, args))
+        self.sql = sql
+        factory = self.connection.parent
+        self.description = factory.hasResults
+        if factory.hasResults and factory.shouldUpdateRowcount:
+            self.rowcount = 1
+        else:
+            self.rowcount = 0
+        return
+
+
+    def var(self, type, *args):
+        """
+        Return a database variable in the style of the cx_Oracle bindings.
+        """
+        v = FakeVariable(self, type, args)
+        self.variables.append(v)
+        return v
+
+
+    def fetchall(self):
+        """
+        Just echo the SQL that was executed in the last query.
+        """
+        if self.connection.parent.hasResults:
+            return [[self.connection.id, self.sql]]
+        if self.description:
+            return []
+        return None
+
+
+
+class FakeVariable(object):
+    def __init__(self, cursor, type, args):
+        self.cursor = cursor
+        self.type = type
+        self.args = args
+
+
+    def getvalue(self):
+        vv = self.cursor.connection.parent.varvals
+        if vv:
+            return vv.pop(0)
+        return self.cursor.variables.index(self) + 300
+
+
+    def __reduce__(self):
+        raise RuntimeError("Not pickleable (since oracle vars aren't)")
+
+
+
+class ConnectionFactory(Parent):
+    """
+    A factory for L{FakeConnection} objects.
+
+    @ivar shouldUpdateRowcount: Should C{execute} on cursors produced by
+        connections produced by this factory update their C{rowcount} or just
+        their C{description} attribute?
+
+    @ivar hasResults: should cursors produced by connections by this factory
+        have any results returned by C{fetchall()}?
+    """
+
+    rollbackFail = False
+    commitFail = False
+
+    def __init__(self, shouldUpdateRowcount=True, hasResults=True):
+        Parent.__init__(self)
+        self.idcounter = count(1)
+        self._connectResultQueue = []
+        self.defaultConnect()
+        self.varvals = []
+        self.shouldUpdateRowcount = shouldUpdateRowcount
+        self.hasResults = hasResults
+
+
+    @property
+    def connections(self):
+        "Alias to make tests more readable."
+        return self.children
+
+
+    def connect(self):
+        """
+        Implement the C{ConnectionFactory} callable expected by
+        L{ConnectionPool}.
+        """
+        if self._connectResultQueue:
+            thunk = self._connectResultQueue.pop(0)
+        else:
+            thunk = self._default
+        return thunk()
+
+
+    def willConnect(self):
+        """
+        Used by tests to queue a successful result for connect().
+        """
+        def thunk():
+            return FakeConnection(self)
+        self._connectResultQueue.append(thunk)
+
+
+    def willFail(self):
+        """
+        Used by tests to queue a successful result for connect().
+        """
+        def thunk():
+            raise FakeConnectionError()
+        self._connectResultQueue.append(thunk)
+
+
+    def defaultConnect(self):
+        """
+        By default, connection attempts will succeed.
+        """
+        self.willConnect()
+        self._default = self._connectResultQueue.pop()
+
+
+    def defaultFail(self):
+        """
+        By default, connection attempts will fail.
+        """
+        self.willFail()
+        self._default = self._connectResultQueue.pop()
+
+
+
+class FakeConnectionError(Exception):
+    """
+    Synthetic error that might occur during connection.
+    """

Modified: CalendarServer/branches/users/gaya/directorybacker/twext/enterprise/queue.py
===================================================================
--- CalendarServer/branches/users/gaya/directorybacker/twext/enterprise/queue.py	2013-04-22 18:44:41 UTC (rev 11082)
+++ CalendarServer/branches/users/gaya/directorybacker/twext/enterprise/queue.py	2013-04-22 18:46:28 UTC (rev 11083)
@@ -87,7 +87,7 @@
 from twisted.application.service import MultiService
 from twisted.internet.protocol import Factory
 from twisted.internet.defer import (
-    inlineCallbacks, returnValue, Deferred, passthru
+    inlineCallbacks, returnValue, Deferred, passthru, succeed
 )
 from twisted.internet.endpoints import TCP4ClientEndpoint
 from twisted.protocols.amp import AMP, Command, Integer, Argument, String
@@ -635,7 +635,7 @@
         """
         The total load of all currently connected workers.
         """
-        return sum(worker.currentLoad() for worker in self.workers)
+        return sum(worker.currentLoad for worker in self.workers)
 
 
     def _selectLowestLoadWorker(self):
@@ -646,7 +646,7 @@
         @return: a worker connection with the lowest current load.
         @rtype: L{ConnectionFromWorker}
         """
-        return sorted(self.workers[:], key=lambda w: w.currentLoad())[0]
+        return sorted(self.workers[:], key=lambda w: w.currentLoad)[0]
 
 
     def performWork(self, table, workID):
@@ -865,6 +865,9 @@
 
 
 
+
+
+
 class WorkerFactory(Factory, object):
     """
     Factory, to be used as the client to connect from the worker to the
@@ -1339,6 +1342,7 @@
         def done(result):
             self._startingUp = None
             super(PeerConnectionPool, self).startService()
+            self._lostWorkCheckLoop()
             return result
 
 
@@ -1446,4 +1450,41 @@
         """
         Choose to perform the work locally.
         """
-        return LocalPerformer(self.txnFactory)
\ No newline at end of file
+        return LocalPerformer(self.txnFactory)
+
+
+
+class NonPerformer(object):
+    """
+    Implementor of C{performWork} that doesn't actual perform any work.  This
+    is used in the case where you want to be able to enqueue work for someone
+    else to do, but not take on any work yourself (such as a command line tool).
+    """
+    implements(_IWorkPerformer)
+
+    def performWork(self, table, workID):
+        """
+        Don't perform work.
+        """
+        return succeed(None)
+
+
+class NonPerformingQueuer(_BaseQueuer):
+    """
+    When work is enqueued with this queuer, it is never executed locally.
+    It's expected that the polling machinery will find the work and perform it.
+    """
+    implements(IQueuer)
+
+    def __init__(self, reactor=None):
+        super(NonPerformingQueuer, self).__init__()
+        if reactor is None:
+            from twisted.internet import reactor
+        self.reactor = reactor
+
+
+    def choosePerformer(self):
+        """
+        Choose to perform the work locally.
+        """
+        return NonPerformer()
\ No newline at end of file

Modified: CalendarServer/branches/users/gaya/directorybacker/twext/enterprise/test/test_adbapi2.py
===================================================================
--- CalendarServer/branches/users/gaya/directorybacker/twext/enterprise/test/test_adbapi2.py	2013-04-22 18:44:41 UTC (rev 11082)
+++ CalendarServer/branches/users/gaya/directorybacker/twext/enterprise/test/test_adbapi2.py	2013-04-22 18:46:28 UTC (rev 11083)
@@ -18,22 +18,14 @@
 Tests for L{twext.enterprise.adbapi2}.
 """
 
-from itertools import count
-from Queue import Empty
+from zope.interface.verify import verifyObject
 
-from zope.interface.verify import verifyClass, verifyObject
-from zope.interface.declarations import implements
-
-from twisted.python.threadpool import ThreadPool
 from twisted.python.failure import Failure
 
 from twisted.trial.unittest import TestCase
 
-from twisted.internet.task import Clock
 from twisted.internet.defer import Deferred, fail
 
-from twisted.internet.interfaces import IReactorThreads
-
 from twisted.test.proto_helpers import StringTransport
 
 from twext.enterprise.ienterprise import ConnectionError
@@ -41,33 +33,17 @@
 from twext.enterprise.adbapi2 import ConnectionPoolClient
 from twext.enterprise.adbapi2 import ConnectionPoolConnection
 from twext.enterprise.ienterprise import IAsyncTransaction
-from twext.enterprise.ienterprise import POSTGRES_DIALECT
 from twext.enterprise.ienterprise import ICommandBlock
 from twext.enterprise.adbapi2 import FailsafeException
-from twext.enterprise.adbapi2 import DEFAULT_PARAM_STYLE
 from twext.enterprise.adbapi2 import ConnectionPool
-from twext.internet.threadutils import ThreadHolder
+from twext.enterprise.fixtures import ConnectionPoolHelper
+from twext.enterprise.fixtures import resultOf
+from twext.enterprise.fixtures import ClockWithThreads
+from twext.enterprise.fixtures import FakeConnectionError
+from twext.enterprise.fixtures import RollbackFail
+from twext.enterprise.fixtures import CommitFail
 from twext.enterprise.adbapi2 import Commit
 
-
-def resultOf(deferred, propagate=False):
-    """
-    Add a callback and errback which will capture the result of a L{Deferred} in
-    a list, and return that list.  If 'propagate' is True, pass through the
-    results.
-    """
-    results = []
-    if propagate:
-        def cb(r):
-            results.append(r)
-            return r
-    else:
-        cb = results.append
-    deferred.addBoth(cb)
-    return results
-
-
-
 class AssertResultHelper(object):
     """
     Mixin for asserting about synchronous Deferred results.
@@ -97,384 +73,6 @@
 
 
 
-class Child(object):
-    """
-    An object with a L{Parent}, in its list of C{children}.
-    """
-    def __init__(self, parent):
-        self.closed = False
-        self.parent = parent
-        self.parent.children.append(self)
-
-
-    def close(self):
-        if self.parent._closeFailQueue:
-            raise self.parent._closeFailQueue.pop(0)
-        self.closed = True
-
-
-
-class Parent(object):
-    """
-    An object with a list of L{Child}ren.
-    """
-
-    def __init__(self):
-        self.children = []
-        self._closeFailQueue = []
-
-
-    def childCloseWillFail(self, exception):
-        """
-        Closing children of this object will result in the given exception.
-
-        @see: L{ConnectionFactory}
-        """
-        self._closeFailQueue.append(exception)
-
-
-
-class FakeConnection(Parent, Child):
-    """
-    Fake Stand-in for DB-API 2.0 connection.
-
-    @ivar executions: the number of statements which have been executed.
-
-    """
-
-    executions = 0
-
-    def __init__(self, factory):
-        """
-        Initialize list of cursors
-        """
-        Parent.__init__(self)
-        Child.__init__(self, factory)
-        self.id = factory.idcounter.next()
-        self._executeFailQueue = []
-        self._commitCount = 0
-        self._rollbackCount = 0
-
-
-    def executeWillFail(self, thunk):
-        """
-        The next call to L{FakeCursor.execute} will fail with an exception
-        returned from the given callable.
-        """
-        self._executeFailQueue.append(thunk)
-
-
-    @property
-    def cursors(self):
-        "Alias to make tests more readable."
-        return self.children
-
-
-    def cursor(self):
-        return FakeCursor(self)
-
-
-    def commit(self):
-        self._commitCount += 1
-        if self.parent.commitFail:
-            self.parent.commitFail = False
-            raise CommitFail()
-
-
-    def rollback(self):
-        self._rollbackCount += 1
-        if self.parent.rollbackFail:
-            self.parent.rollbackFail = False
-            raise RollbackFail()
-
-
-
-class RollbackFail(Exception):
-    """
-    Sample rollback-failure exception.
-    """
-
-
-
-class CommitFail(Exception):
-    """
-    Sample Commit-failure exception.
-    """
-
-
-
-class FakeCursor(Child):
-    """
-    Fake stand-in for a DB-API 2.0 cursor.
-    """
-    def __init__(self, connection):
-        Child.__init__(self, connection)
-        self.rowcount = 0
-        # not entirely correct, but all we care about is its truth value.
-        self.description = False
-        self.variables = []
-        self.allExecutions = []
-
-
-    @property
-    def connection(self):
-        "Alias to make tests more readable."
-        return self.parent
-
-
-    def execute(self, sql, args=()):
-        self.connection.executions += 1
-        if self.connection._executeFailQueue:
-            raise self.connection._executeFailQueue.pop(0)()
-        self.allExecutions.append((sql, args))
-        self.sql = sql
-        factory = self.connection.parent
-        self.description = factory.hasResults
-        if factory.hasResults and factory.shouldUpdateRowcount:
-            self.rowcount = 1
-        else:
-            self.rowcount = 0
-        return
-
-
-    def var(self, type, *args):
-        """
-        Return a database variable in the style of the cx_Oracle bindings.
-        """
-        v = FakeVariable(self, type, args)
-        self.variables.append(v)
-        return v
-
-
-    def fetchall(self):
-        """
-        Just echo the SQL that was executed in the last query.
-        """
-        if self.connection.parent.hasResults:
-            return [[self.connection.id, self.sql]]
-        if self.description:
-            return []
-        return None
-
-
-
-class FakeVariable(object):
-    def __init__(self, cursor, type, args):
-        self.cursor = cursor
-        self.type = type
-        self.args = args
-
-
-    def getvalue(self):
-        vv = self.cursor.connection.parent.varvals
-        if vv:
-            return vv.pop(0)
-        return self.cursor.variables.index(self) + 300
-
-
-    def __reduce__(self):
-        raise RuntimeError("Not pickleable (since oracle vars aren't)")
-
-
-
-class ConnectionFactory(Parent):
-    """
-    A factory for L{FakeConnection} objects.
-
-    @ivar shouldUpdateRowcount: Should C{execute} on cursors produced by
-        connections produced by this factory update their C{rowcount} or just
-        their C{description} attribute?
-
-    @ivar hasResults: should cursors produced by connections by this factory
-        have any results returned by C{fetchall()}?
-    """
-
-    rollbackFail = False
-    commitFail = False
-
-    def __init__(self, shouldUpdateRowcount=True, hasResults=True):
-        Parent.__init__(self)
-        self.idcounter = count(1)
-        self._connectResultQueue = []
-        self.defaultConnect()
-        self.varvals = []
-        self.shouldUpdateRowcount = shouldUpdateRowcount
-        self.hasResults = hasResults
-
-
-    @property
-    def connections(self):
-        "Alias to make tests more readable."
-        return self.children
-
-
-    def connect(self):
-        """
-        Implement the C{ConnectionFactory} callable expected by
-        L{ConnectionPool}.
-        """
-        if self._connectResultQueue:
-            thunk = self._connectResultQueue.pop(0)
-        else:
-            thunk = self._default
-        return thunk()
-
-
-    def willConnect(self):
-        """
-        Used by tests to queue a successful result for connect().
-        """
-        def thunk():
-            return FakeConnection(self)
-        self._connectResultQueue.append(thunk)
-
-
-    def willFail(self):
-        """
-        Used by tests to queue a successful result for connect().
-        """
-        def thunk():
-            raise FakeConnectionError()
-        self._connectResultQueue.append(thunk)
-
-
-    def defaultConnect(self):
-        """
-        By default, connection attempts will succeed.
-        """
-        self.willConnect()
-        self._default = self._connectResultQueue.pop()
-
-
-    def defaultFail(self):
-        """
-        By default, connection attempts will fail.
-        """
-        self.willFail()
-        self._default = self._connectResultQueue.pop()
-
-
-
-class FakeConnectionError(Exception):
-    """
-    Synthetic error that might occur during connection.
-    """
-
-
-
-class FakeThreadHolder(ThreadHolder):
-    """
-    Run things to submitted this ThreadHolder on the main thread, so that
-    execution is easier to control.
-    """
-
-    def __init__(self, test):
-        super(FakeThreadHolder, self).__init__(self)
-        self.test = test
-        self.started = False
-        self.stopped = False
-        self._workerIsRunning = False
-
-
-    def start(self):
-        self.started = True
-        return super(FakeThreadHolder, self).start()
-
-
-    def stop(self):
-        result = super(FakeThreadHolder, self).stop()
-        self.stopped = True
-        return result
-
-
-    @property
-    def _get_q(self):
-        return self._q_
-
-
-    @_get_q.setter
-    def _q(self, newq):
-        if newq is not None:
-            oget = newq.get
-            newq.get = lambda: oget(timeout=0)
-            oput = newq.put
-            def putit(x):
-                p = oput(x)
-                if not self.test.paused:
-                    self.flush()
-                return p
-            newq.put = putit
-        self._q_ = newq
-
-
-    def callFromThread(self, f, *a, **k):
-        result = f(*a, **k)
-        return result
-
-
-    def callInThread(self, f, *a, **k):
-        """
-        This should be called only once, to start the worker function that
-        dedicates a thread to this L{ThreadHolder}.
-        """
-        self._workerIsRunning = True
-
-
-    def flush(self):
-        """
-        Fire all deferreds previously returned from submit.
-        """
-        try:
-            while self._workerIsRunning and self._qpull():
-                pass
-            else:
-                self._workerIsRunning = False
-        except Empty:
-            pass
-
-
-
-class ClockWithThreads(Clock):
-    """
-    A testing reactor that supplies L{IReactorTime} and L{IReactorThreads}.
-    """
-    implements(IReactorThreads)
-
-    def __init__(self):
-        super(ClockWithThreads, self).__init__()
-        self._pool = ThreadPool()
-
-
-    def getThreadPool(self):
-        """
-        Get the threadpool.
-        """
-        return self._pool
-
-
-    def suggestThreadPoolSize(self, size):
-        """
-        Approximate the behavior of a 'real' reactor.
-        """
-        self._pool.adjustPoolsize(maxthreads=size)
-
-
-    def callInThread(self, thunk, *a, **kw):
-        """
-        No implementation.
-        """
-
-
-    def callFromThread(self, thunk, *a, **kw):
-        """
-        No implementation.
-        """
-
-
-verifyClass(IReactorThreads, ClockWithThreads)
-
-
-
 class ConnectionPoolBootTests(TestCase):
     """
     Tests for the start-up phase of L{ConnectionPool}.
@@ -521,74 +119,6 @@
 
 
 
-class ConnectionPoolHelper(object):
-    """
-    Connection pool setting-up facilities for tests that need a
-    L{ConnectionPool}.
-    """
-
-    dialect = POSTGRES_DIALECT
-    paramstyle = DEFAULT_PARAM_STYLE
-
-    def setUp(self):
-        """
-        Create a L{ConnectionPool} attached to a C{ConnectionFactory}.  Start
-        the L{ConnectionPool}.
-        """
-        self.paused             = False
-        self.holders            = []
-        self.factory            = ConnectionFactory()
-        self.pool               = ConnectionPool(self.factory.connect,
-                                                 maxConnections=2,
-                                                 dialect=self.dialect,
-                                                 paramstyle=self.paramstyle)
-        self.pool._createHolder = self.makeAHolder
-        self.clock              = self.pool.reactor = ClockWithThreads()
-        self.pool.startService()
-        self.addCleanup(self.flushHolders)
-
-
-    def flushHolders(self):
-        """
-        Flush all pending C{submit}s since C{pauseHolders} was called.  This
-        makes sure the service is stopped and the fake ThreadHolders are all
-        executing their queues so failed tests can exit cleanly.
-        """
-        self.paused = False
-        for holder in self.holders:
-            holder.flush()
-
-
-    def pauseHolders(self):
-        """
-        Pause all L{FakeThreadHolder}s, causing C{submit} to return an unfired
-        L{Deferred}.
-        """
-        self.paused = True
-
-
-    def makeAHolder(self):
-        """
-        Make a ThreadHolder-alike.
-        """
-        fth = FakeThreadHolder(self)
-        self.holders.append(fth)
-        return fth
-
-
-    def resultOf(self, it):
-        return resultOf(it)
-
-
-    def createTransaction(self):
-        return self.pool.connection()
-
-
-    def translateError(self, err):
-        return err
-
-
-
 class ConnectionPoolTests(ConnectionPoolHelper, TestCase, AssertResultHelper):
     """
     Tests for L{ConnectionPool}.

Modified: CalendarServer/branches/users/gaya/directorybacker/twext/enterprise/test/test_queue.py
===================================================================
--- CalendarServer/branches/users/gaya/directorybacker/twext/enterprise/test/test_queue.py	2013-04-22 18:44:41 UTC (rev 11082)
+++ CalendarServer/branches/users/gaya/directorybacker/twext/enterprise/test/test_queue.py	2013-04-22 18:46:28 UTC (rev 11083)
@@ -52,9 +52,10 @@
 from twext.enterprise.queue import ConnectionFromPeerNode
 from twext.enterprise.fixtures import buildConnectionPool
 from zope.interface.verify import verifyObject
-from twisted.test.proto_helpers import StringTransport
+from twisted.test.proto_helpers import StringTransport, MemoryReactor
+from twext.enterprise.fixtures import SteppablePoolHelper
 
-from twext.enterprise.queue import _BaseQueuer
+from twext.enterprise.queue import _BaseQueuer, NonPerformingQueuer
 import twext.enterprise.queue
 
 class Clock(_Clock):
@@ -70,6 +71,16 @@
 
 
 
+class MemoryReactorWithClock(MemoryReactor, Clock):
+    """
+    Simulate a real reactor.
+    """
+    def __init__(self):
+        MemoryReactor.__init__(self)
+        Clock.__init__(self)
+
+
+
 def transactionally(transactionCreator):
     """
     Perform the decorated function immediately in a transaction, replacing its
@@ -213,7 +224,6 @@
 
 
 
-
 class WorkItemTests(TestCase):
     """
     A L{WorkItem} is an item of work that can be executed.
@@ -467,7 +477,64 @@
         self.assertIdentical(result, proposal)
 
 
+    def test_workerConnectionPoolPerformWork(self):
+        """
+        L{WorkerConnectionPool.performWork} performs work by selecting a
+        L{ConnectionFromWorker} and sending it a L{PerformWork} command.
+        """
+        clock = Clock()
+        peerPool = PeerConnectionPool(clock, None, 4322, schema)
+        factory = peerPool.workerListenerFactory()
+        def peer():
+            p = factory.buildProtocol(None)
+            t = StringTransport()
+            p.makeConnection(t)
+            return p, t
+        worker1, trans1 = peer()
+        worker2, trans2 = peer()
+        # Ask the worker to do something.
+        worker1.performWork(schema.DUMMY_WORK_ITEM, 1)
+        self.assertEquals(worker1.currentLoad, 1)
+        self.assertEquals(worker2.currentLoad, 0)
 
+        # Now ask the pool to do something
+        peerPool.workerPool.performWork(schema.DUMMY_WORK_ITEM, 2)
+        self.assertEquals(worker1.currentLoad, 1)
+        self.assertEquals(worker2.currentLoad, 1)
+
+
+    def test_poolStartServiceChecksForWork(self):
+        """
+        L{PeerConnectionPool.startService} kicks off the idle work-check loop.
+        """
+        reactor = MemoryReactorWithClock()
+        cph = SteppablePoolHelper(nodeSchema + schemaText)
+        then = datetime.datetime(2012, 12, 12, 12, 12, 0)
+        reactor.advance(astimestamp(then))
+        cph.setUp(self)
+        pcp = PeerConnectionPool(reactor, cph.pool.connection, 4321, schema)
+        now = then + datetime.timedelta(seconds=pcp.queueProcessTimeout * 2)
+        @transactionally(cph.pool.connection)
+        def createOldWork(txn):
+            one = DummyWorkItem.create(txn, workID=1, a=3, b=4, notBefore=then)
+            two = DummyWorkItem.create(txn, workID=2, a=7, b=9, notBefore=now)
+            return gatherResults([one, two])
+        pcp.startService()
+        cph.flushHolders()
+        reactor.advance(pcp.queueProcessTimeout * 2)
+        self.assertEquals(
+            cph.rows("select * from DUMMY_WORK_DONE"),
+            [(1, 7)]
+        )
+        cph.rows("delete from DUMMY_WORK_DONE")
+        reactor.advance(pcp.queueProcessTimeout * 2)
+        self.assertEquals(
+            cph.rows("select * from DUMMY_WORK_DONE"),
+            [(2, 16)]
+        )
+
+
+
 class HalfConnection(object):
     def __init__(self, protocol):
         self.protocol = protocol
@@ -654,3 +721,14 @@
         queuer.enqueueWork(None, None)
         self.assertNotEqual(self.proposal, None)
 
+
+class NonPerformingQueuerTests(TestCase):
+
+    @inlineCallbacks
+    def test_choosePerformer(self):
+        queuer = NonPerformingQueuer()
+        performer = queuer.choosePerformer()
+        result = (yield performer.performWork(None, None))
+        self.assertEquals(result, None)
+
+

Modified: CalendarServer/branches/users/gaya/directorybacker/twext/python/sendmsg.c
===================================================================
--- CalendarServer/branches/users/gaya/directorybacker/twext/python/sendmsg.c	2013-04-22 18:44:41 UTC (rev 11082)
+++ CalendarServer/branches/users/gaya/directorybacker/twext/python/sendmsg.c	2013-04-22 18:46:28 UTC (rev 11083)
@@ -117,6 +117,7 @@
     struct msghdr message_header;
     struct iovec iov[1];
     PyObject *ancillary = NULL;
+    PyObject *ultimate_result = NULL;
     static char *kwlist[] = {"fd", "data", "flags", "ancillary", NULL};
 
     if (!PyArg_ParseTupleAndKeywords(
@@ -148,14 +149,14 @@
             PyErr_Format(PyExc_TypeError,
                          "sendmsg argument 3 expected list, got %s",
                          ancillary->ob_type->tp_name);
-            return NULL;
+            goto finished;
         }
 
         PyObject *iterator = PyObject_GetIter(ancillary);
         PyObject *item = NULL;
 
         if (iterator == NULL) {
-            return NULL;
+            goto finished;
         }
 
         size_t all_data_len = 0;
@@ -172,7 +173,7 @@
                         &level, &type, &data, &data_len)) {
                 Py_DECREF(item);
                 Py_DECREF(iterator);
-                return NULL;
+                goto finished;
             }
 
             prev_all_data_len = all_data_len;
@@ -185,7 +186,7 @@
                 PyErr_Format(PyExc_OverflowError,
                              "Too much msg_control to fit in a size_t: %zu",
                              prev_all_data_len);
-                return NULL;
+                goto finished;
             }
         }
 
@@ -199,15 +200,13 @@
                 PyErr_Format(PyExc_OverflowError,
                              "Too much msg_control to fit in a socklen_t: %zu",
                              all_data_len);
-                return NULL;
+                goto finished;
             }
             message_header.msg_control = malloc(all_data_len);
             if (!message_header.msg_control) {
                 PyErr_NoMemory();
-                return NULL;
+                goto finished;
             }
-        } else {
-            message_header.msg_control = NULL;
         }
         message_header.msg_controllen = (socklen_t) all_data_len;
 
@@ -215,8 +214,7 @@
         item = NULL;
 
         if (!iterator) {
-            free(message_header.msg_control);
-            return NULL;
+            goto finished;
         }
 
         /* Unpack the tuples into the control message. */
@@ -239,8 +237,7 @@
                                   &data_len)) {
                 Py_DECREF(item);
                 Py_DECREF(iterator);
-                free(message_header.msg_control);
-                return NULL;
+                goto finished;
             }
 
             control_message->cmsg_level = level;
@@ -250,12 +247,9 @@
             if (data_size > SOCKLEN_MAX) {
                 Py_DECREF(item);
                 Py_DECREF(iterator);
-                free(message_header.msg_control);
-
                 PyErr_Format(PyExc_OverflowError,
                              "CMSG_LEN(%zd) > SOCKLEN_MAX", data_len);
-
-                return NULL;
+                goto finished;
             }
 
             control_message->cmsg_len = (socklen_t) data_size;
@@ -271,8 +265,7 @@
         Py_DECREF(iterator);
 
         if (PyErr_Occurred()) {
-            free(message_header.msg_control);
-            return NULL;
+            goto finished;
         }
     }
 
@@ -280,13 +273,16 @@
 
     if (sendmsg_result < 0) {
         PyErr_SetFromErrno(sendmsg_socket_error);
-        if (message_header.msg_control) {
-            free(message_header.msg_control);
-        }
-        return NULL;
+        goto finished;
+    } else {
+        ultimate_result = Py_BuildValue("n", sendmsg_result);
     }
 
-    return Py_BuildValue("n", sendmsg_result);
+  finished:
+    if (message_header.msg_control) {
+        free(message_header.msg_control);
+    }
+    return ultimate_result;
 }
 
 static PyObject *sendmsg_recvmsg(PyObject *self, PyObject *args, PyObject *keywds) {

Modified: CalendarServer/branches/users/gaya/directorybacker/twisted/plugins/caldav.py
===================================================================
--- CalendarServer/branches/users/gaya/directorybacker/twisted/plugins/caldav.py	2013-04-22 18:44:41 UTC (rev 11082)
+++ CalendarServer/branches/users/gaya/directorybacker/twisted/plugins/caldav.py	2013-04-22 18:46:28 UTC (rev 11083)
@@ -53,4 +53,3 @@
 
 
 TwistedCalDAV = TAP("calendarserver.tap.caldav.CalDAVServiceMaker")
-CalDAVGroupCacher = TAP("twistedcaldav.directory.directory.GroupMembershipCacherServiceMaker")

Modified: CalendarServer/branches/users/gaya/directorybacker/twistedcaldav/cache.py
===================================================================
--- CalendarServer/branches/users/gaya/directorybacker/twistedcaldav/cache.py	2013-04-22 18:44:41 UTC (rev 11082)
+++ CalendarServer/branches/users/gaya/directorybacker/twistedcaldav/cache.py	2013-04-22 18:46:28 UTC (rev 11083)
@@ -20,7 +20,7 @@
 
 from zope.interface import implements
 
-from twisted.internet.defer import succeed, maybeDeferred, inlineCallbacks,\
+from twisted.internet.defer import succeed, maybeDeferred, inlineCallbacks, \
     returnValue
 from twext.web2.dav.util import allDataFromStream
 from twext.web2.http import Response
@@ -50,15 +50,15 @@
   - directoryToken - a hash of that principal's directory record
   - uriToken - a token for the request uri
   - childTokens - tokens for any child resources the request uri depends on (for depth:1)
-  
+
   The current principalToken, uriToken and childTokens values are themselves stored in the cache using the key prefix 'cacheToken:'.
 When the 'changeCache' api is called the cached value for the matching token is updated.
-  
+
 (4) When a request is being checked in the cache, the response cache entry key is first computed and any value extracted. The
 tokens in the value are then checked against the current set of tokens in the cache. If there is any mismatch between tokens, the
 cache entry is considered invalid and the cached response is not returned. If everything matches up, the cached response is returned
 to the caller and ultimately sent directly back to the client.
- 
+
 (5) Because of shared calendars/address books that can affect the calendar/address book homes of several different users at once, we
 need to keep track of the separate childTokens for each child resource. The tokens for shared resources are keyed of the sharer's uri,
 so sharee's homes use that token. That way a single token for all shared instances is used and changed just once.
@@ -72,18 +72,22 @@
     def __init__(self, *args, **kwargs):
         pass
 
+
     def changed(self):
         return succeed(None)
 
 
+
 class DisabledCache(object):
     def getResponseForRequest(self, request):
         return succeed(None)
 
+
     def cacheResponseForRequest(self, request, response):
         return succeed(response)
 
 
+
 class URINotFoundException(Exception):
     def __init__(self, uri):
         self.uri = uri
@@ -95,6 +99,7 @@
             self.uri)
 
 
+
 class MemcacheChangeNotifier(LoggingMixIn, CachePoolUserMixIn):
 
     def __init__(self, resource, cachePool=None, cacheHandle="Default"):
@@ -102,22 +107,31 @@
         self._cachePool = cachePool
         self._cachePoolHandle = cacheHandle
 
+
     def _newCacheToken(self):
         return str(uuid.uuid4())
 
+
     def changed(self):
         """
         Change the cache token for a resource
 
         return: A L{Deferred} that fires when the token has been changed.
         """
-        url = self._resource.url()
 
+        # For shared resources we use the owner URL as the cache key
+        if hasattr(self._resource, "owner_url"):
+            url = self._resource.owner_url()
+        else:
+            url = self._resource.url()
+
         self.log_debug("Changing Cache Token for %r" % (url,))
         return self.getCachePool().set(
             'cacheToken:%s' % (url,),
-            self._newCacheToken(), expireTime=config.ResponseCacheTimeout*60)
-            
+            self._newCacheToken(), expireTime=config.ResponseCacheTimeout * 60)
+
+
+
 class BaseResponseCache(LoggingMixIn):
     """
     A base class which provides some common operations
@@ -149,10 +163,10 @@
     def _canonicalizeURIForRequest(self, uri, request):
         """
         Always use canonicalized forms of the URIs for caching (i.e. __uids__ paths).
-        
-        Do this without calling locateResource which may cause a query on the store. 
+
+        Do this without calling locateResource which may cause a query on the store.
         """
-        
+
         uribits = uri.split("/")
         if len(uribits) > 1 and uribits[1] in ("principals", "calendars", "addressbooks"):
             if uribits[2] == "__uids__":
@@ -166,8 +180,7 @@
                     uribits[2] = "__uids__"
                     uribits[3] = record.uid
                     return succeed("/".join(uribits))
-                
-            
+
         # Fall back to the locateResource approach
         try:
             return request.locateResource(uri).addCallback(
@@ -190,6 +203,7 @@
 
         return d
 
+
     @inlineCallbacks
     def _requestKey(self, request):
         """
@@ -201,7 +215,7 @@
             # Give it back to the request so it can be read again
             request.stream = MemoryStream(requestBody)
             request.stream.doStartReading = None
-            
+
             # Normalize the property order by doing a "dumb" sort on lines
             requestLines = requestBody.splitlines()
             requestLines.sort()
@@ -222,6 +236,7 @@
         return d1
 
 
+
 class MemcacheResponseCache(BaseResponseCache, CachePoolUserMixIn):
     def __init__(self, docroot, cachePool=None):
         self._docroot = docroot
@@ -238,6 +253,7 @@
         else:
             return self.getCachePool().get('cacheToken:%s' % (uri,))
 
+
     @inlineCallbacks
     def _tokenForRecord(self, uri, request):
         """
@@ -247,19 +263,21 @@
         record = (yield self._getRecordForURI(uri, request))
         returnValue(record.cacheToken())
 
+
     @inlineCallbacks
     def _tokensForChildren(self, rURI, request):
         """
         Create a dict of child resource tokens for any "recorded" during this request in the childCacheURIs attribute.
         """
-        
+
         if hasattr(request, "childCacheURIs"):
             tokens = dict([(uri, (yield self._tokenForURI(uri)),) for uri in request.childCacheURIs])
             returnValue(tokens)
         else:
             returnValue({})
-    
-    @inlineCallbacks 
+
+
+    @inlineCallbacks
     def _getTokens(self, request):
         """
         Tokens are a principal token, directory record token, resource token and list
@@ -296,19 +314,19 @@
         """
         try:
             key = (yield self._hashedRequestKey(request))
-    
+
             self.log_debug("Checking cache for: %r" % (key,))
             _ignore_flags, value = (yield self.getCachePool().get(key))
-    
+
             if value is None:
                 self.log_debug("Not in cache: %r" % (key,))
                 returnValue(None)
-    
+
             self.log_debug("Found in cache: %r = %r" % (key, value))
-    
+
             (principalToken, directoryToken, uriToken, childTokens, (code, headers, body)) = cPickle.loads(value)
             currentTokens = (yield self._getTokens(request))
-    
+
             if currentTokens[0] != principalToken:
                 self.log_debug(
                     "Principal token doesn't match for %r: %r != %r" % (
@@ -316,7 +334,7 @@
                         currentTokens[0],
                         principalToken))
                 returnValue(None)
-    
+
             if currentTokens[1] != directoryToken:
                 self.log_debug(
                     "Directory Record Token doesn't match for %r: %r != %r" % (
@@ -324,7 +342,7 @@
                         currentTokens[1],
                         directoryToken))
                 returnValue(None)
-    
+
             if currentTokens[2] != uriToken:
                 self.log_debug(
                     "URI token doesn't match for %r: %r != %r" % (
@@ -332,7 +350,7 @@
                         currentTokens[2],
                         uriToken))
                 returnValue(None)
-    
+
             for childuri, token in childTokens.items():
                 currentToken = (yield self._tokenForURI(childuri))
                 if currentToken != token:
@@ -343,19 +361,20 @@
                             currentToken,
                             token))
                     returnValue(None)
-                     
+
             r = Response(code,
                          stream=MemoryStream(body))
-    
+
             for key, value in headers.iteritems():
                 r.headers.setRawHeaders(key, value)
-    
+
             returnValue(r)
 
         except URINotFoundException, e:
             self.log_debug("Could not locate URI: %r" % (e,))
             returnValue(None)
 
+
     @inlineCallbacks
     def cacheResponseForRequest(self, request, response):
         """
@@ -368,9 +387,9 @@
                 key = request.cacheKey
             else:
                 key = (yield self._hashedRequestKey(request))
-    
+
             key, responseBody = (yield self._getResponseBody(key, response))
-    
+
             response.headers.removeHeader('date')
             response.stream = MemoryStream(responseBody)
             pToken, dToken, uToken, cTokens = (yield self._getTokens(request))
@@ -388,30 +407,34 @@
             ))
             self.log_debug("Adding to cache: %r = %r" % (key, cacheEntry))
             yield self.getCachePool().set(key, cacheEntry,
-                expireTime=config.ResponseCacheTimeout*60)
+                expireTime=config.ResponseCacheTimeout * 60)
 
         except URINotFoundException, e:
             self.log_debug("Could not locate URI: %r" % (e,))
 
-        returnValue(response)            
+        returnValue(response)
 
 
+
 class _CachedResponseResource(object):
     implements(IResource)
 
     def __init__(self, response):
         self._response = response
 
+
     def renderHTTP(self, request):
         if not hasattr(request, "extendedLogItems"):
             request.extendedLogItems = {}
         request.extendedLogItems["cached"] = "1"
         return self._response
 
+
     def locateChild(self, request, segments):
         return self, []
 
 
+
 class PropfindCacheMixin(object):
     """
     A mixin that causes a resource's PROPFIND response to be cached. It also adds an api to change the
@@ -433,12 +456,15 @@
             d.addCallback(_getResponseCache)
         return d
 
+
     def changeCache(self):
         if hasattr(self, 'cacheNotifier'):
             return self.cacheNotifier.changed()
         else:
             self.log_debug("%r does not have a cacheNotifier but was changed" % (self,))
 
+
+
 class ResponseCacheMixin(object):
     """
     This is a mixin for a child resource that does not itself cache PROPFINDs, but needs to invalidate a parent
@@ -451,19 +477,25 @@
         else:
             self.log_debug("%r does not have a cacheNotifier but was changed" % (self,))
 
+
+
 class CacheStoreNotifier(object):
-    
+
     def __init__(self, resource):
         self.resource = resource
-    
+
+
     def notify(self, op="update"):
         self.resource.changeCache()
 
+
     def clone(self, label="default", id=None):
         return self
 
+
     def getID(self, label="default"):
         return None
 
+
     def nodeName(self, label="default"):
         return succeed(None)

Modified: CalendarServer/branches/users/gaya/directorybacker/twistedcaldav/directory/calendaruserproxy.py
===================================================================
--- CalendarServer/branches/users/gaya/directorybacker/twistedcaldav/directory/calendaruserproxy.py	2013-04-22 18:44:41 UTC (rev 11082)
+++ CalendarServer/branches/users/gaya/directorybacker/twistedcaldav/directory/calendaruserproxy.py	2013-04-22 18:46:28 UTC (rev 11083)
@@ -594,7 +594,8 @@
 
         @param principalUID: the UID of the principal to remove.
         """
-
+        # FIXME: This method doesn't appear to be used anywhere.  Still needed?
+        
         if delay:
             # We are going to remove the principal only after <delay> seconds
             # has passed since we first chose to remove it, to protect against

Modified: CalendarServer/branches/users/gaya/directorybacker/twistedcaldav/directory/directory.py
===================================================================
--- CalendarServer/branches/users/gaya/directorybacker/twistedcaldav/directory/directory.py	2013-04-22 18:44:41 UTC (rev 11082)
+++ CalendarServer/branches/users/gaya/directorybacker/twistedcaldav/directory/directory.py	2013-04-22 18:46:28 UTC (rev 11083)
@@ -26,6 +26,7 @@
     "DirectoryError",
     "DirectoryConfigurationError",
     "UnknownRecordTypeError",
+    "GroupMembershipCacheUpdater",
 ]
 
 import cPickle as pickle
@@ -34,7 +35,6 @@
 import itertools
 import os
 import pwd
-import signal
 import sys
 import types
 
@@ -46,24 +46,26 @@
 from twext.web2.dav.auth import IPrincipalCredentials
 from twisted.internet.defer import succeed, inlineCallbacks, returnValue
 
-from twext.python.log import LoggingMixIn
+from twext.python.log import Logger, LoggingMixIn
 
 from twistedcaldav.config import config
+
 from twistedcaldav.directory.idirectory import IDirectoryService, IDirectoryRecord
 from twistedcaldav.directory.util import uuidFromName, normalizeUUID
 from twistedcaldav.scheduling.cuaddress import normalizeCUAddr
 from twistedcaldav.scheduling.ischedule.localservers import Servers
 from twistedcaldav.memcacher import Memcacher
-from twistedcaldav import memcachepool
 from twisted.python.filepath import FilePath
-from twisted.python.reflect import namedClass
-from twisted.python.usage import Options, UsageError
-from twistedcaldav.stdconfig import DEFAULT_CONFIG, DEFAULT_CONFIG_FILE
-from twisted.application import service
-from twisted.plugin import IPlugin
 from xml.parsers.expat import ExpatError
 from plistlib import readPlistFromString
+from twext.enterprise.dal.record import fromTable
+from twext.enterprise.queue import WorkItem, PeerConnectionPool
+from txdav.common.datastore.sql_tables import schema
+from twext.enterprise.dal.syntax import Delete
 
+log = Logger()
+
+
 class DirectoryService(LoggingMixIn):
     implements(IDirectoryService, ICredentialsChecker)
 
@@ -564,20 +566,16 @@
 
     "group-cacher-populated" : contains a datestamp indicating the most recent
     population.
-
-    "group-cacher-lock" : used to prevent multiple updates, it has a value of "1"
-
     """
 
     def __init__(self, namespace, pickle=True, no_invalidation=False,
-        key_normalization=True, expireSeconds=0, lockSeconds=60):
+        key_normalization=True, expireSeconds=0):
 
         super(GroupMembershipCache, self).__init__(namespace, pickle=pickle,
             no_invalidation=no_invalidation,
             key_normalization=key_normalization)
 
         self.expireSeconds = expireSeconds
-        self.lockSeconds = lockSeconds
 
 
     def setGroupsFor(self, guid, memberships):
@@ -616,17 +614,7 @@
         returnValue(value is not None)
 
 
-    def acquireLock(self):
-        self.log_debug("add group-cacher-lock")
-        return self.add("group-cacher-lock", "1", expireTime=self.lockSeconds)
 
-
-    def releaseLock(self):
-        self.log_debug("delete group-cacher-lock")
-        return self.delete("group-cacher-lock")
-
-
-
 class GroupMembershipCacheUpdater(LoggingMixIn):
     """
     Responsible for updating memcached with group memberships.  This will run
@@ -634,11 +622,12 @@
     proxy database, and the location/resource info in the directory system.
     """
 
-    def __init__(self, proxyDB, directory, expireSeconds, lockSeconds,
+    def __init__(self, proxyDB, directory, updateSeconds, expireSeconds,
         cache=None, namespace=None, useExternalProxies=False,
         externalProxiesSource=None):
         self.proxyDB = proxyDB
         self.directory = directory
+        self.updateSeconds = updateSeconds
         self.useExternalProxies = useExternalProxies
         if useExternalProxies and externalProxiesSource is None:
             externalProxiesSource = self.directory.getExternalProxyAssignments
@@ -646,8 +635,7 @@
 
         if cache is None:
             assert namespace is not None, "namespace must be specified if GroupMembershipCache is not provided"
-            cache = GroupMembershipCache(namespace, expireSeconds=expireSeconds,
-                lockSeconds=lockSeconds)
+            cache = GroupMembershipCache(namespace, expireSeconds=expireSeconds)
         self.cache = cache
 
 
@@ -738,8 +726,6 @@
         # See if anyone has completely populated the group membership cache
         isPopulated = (yield self.cache.isPopulated())
 
-        useLock = True
-
         if fast:
             # We're in quick-start mode.  Check first to see if someone has
             # populated the membership cache, and if so, return immediately
@@ -747,9 +733,6 @@
                 self.log_info("Group membership cache is already populated")
                 returnValue((fast, 0))
 
-            # We don't care what others are doing right now, we need to update
-            useLock = False
-
         self.log_info("Updating group membership cache")
 
         dataRoot = FilePath(config.DataRoot)
@@ -767,14 +750,6 @@
             previousMembers = pickle.loads(membershipsCacheFile.getContent())
             callGroupsChanged = True
 
-        if useLock:
-            self.log_info("Attempting to acquire group membership cache lock")
-            acquiredLock = (yield self.cache.acquireLock())
-            if not acquiredLock:
-                self.log_info("Group membership cache lock held by another process")
-                returnValue((fast, 0))
-            self.log_info("Acquired lock")
-
         if not fast and self.useExternalProxies:
 
             # Load in cached copy of external proxies so we can diff against them
@@ -944,257 +919,60 @@
 
         yield self.cache.setPopulatedMarker()
 
-        if useLock:
-            self.log_info("Releasing lock")
-            yield self.cache.releaseLock()
-
         self.log_info("Group memberships cache updated")
 
         returnValue((fast, len(members), len(changedMembers)))
 
 
+class GroupCacherPollingWork(WorkItem, fromTable(schema.GROUP_CACHER_POLLING_WORK)):
 
-class GroupMembershipCacherOptions(Options):
-    optParameters = [[
-        "config", "f", DEFAULT_CONFIG_FILE, "Path to configuration file."
-    ]]
+    group = "group_cacher_polling"
 
-    def __init__(self, *args, **kwargs):
-        super(GroupMembershipCacherOptions, self).__init__(*args, **kwargs)
+    @inlineCallbacks
+    def doWork(self):
 
-        self.overrides = {}
+        # Delete all other work items
+        yield Delete(From=self.table, Where=None).on(self.transaction)
 
-
-    def _coerceOption(self, configDict, key, value):
-        """
-        Coerce the given C{val} to type of C{configDict[key]}
-        """
-        if key in configDict:
-            if isinstance(configDict[key], bool):
-                value = value == "True"
-
-            elif isinstance(configDict[key], (int, float, long)):
-                value = type(configDict[key])(value)
-
-            elif isinstance(configDict[key], (list, tuple)):
-                value = value.split(',')
-
-            elif isinstance(configDict[key], dict):
-                raise UsageError(
-                    "Dict options not supported on the command line"
-                )
-
-            elif value == 'None':
-                value = None
-
-        return value
-
-
-    def _setOverride(self, configDict, path, value, overrideDict):
-        """
-        Set the value at path in configDict
-        """
-        key = path[0]
-
-        if len(path) == 1:
-            overrideDict[key] = self._coerceOption(configDict, key, value)
-            return
-
-        if key in configDict:
-            if not isinstance(configDict[key], dict):
-                raise UsageError(
-                    "Found intermediate path element that is not a dictionary"
-                )
-
-            if key not in overrideDict:
-                overrideDict[key] = {}
-
-            self._setOverride(
-                configDict[key], path[1:],
-                value, overrideDict[key]
-            )
-
-
-    def opt_option(self, option):
-        """
-        Set an option to override a value in the config file. True, False, int,
-        and float options are supported, as well as comma seperated lists. Only
-        one option may be given for each --option flag, however multiple
-        --option flags may be specified.
-        """
-
-        if "=" in option:
-            path, value = option.split('=')
-            self._setOverride(
-                DEFAULT_CONFIG,
-                path.split('/'),
-                value,
-                self.overrides
-            )
+        groupCacher = getattr(self.transaction, "_groupCacher", None)
+        if groupCacher is not None:
+            try:
+                yield groupCacher.updateCache()
+            except Exception, e:
+                log.error("Failed to update group membership cache (%s)" % (e,))
+            finally:
+                notBefore = (datetime.datetime.utcnow() +
+                    datetime.timedelta(seconds=groupCacher.updateSeconds))
+                log.debug("Scheduling next group cacher update: %s" % (notBefore,))
+                yield self.transaction.enqueue(GroupCacherPollingWork,
+                    notBefore=notBefore)
         else:
-            self.opt_option('%s=True' % (option,))
+            notBefore = (datetime.datetime.utcnow() +
+                datetime.timedelta(seconds=10))
+            log.debug("Rescheduling group cacher update: %s" % (notBefore,))
+            yield self.transaction.enqueue(GroupCacherPollingWork,
+                notBefore=notBefore)
 
-    opt_o = opt_option
 
-    def postOptions(self):
-        config.load(self['config'])
-        config.updateDefaults(self.overrides)
-        self.parent['pidfile'] = config.PIDFile
+ at inlineCallbacks
+def scheduleNextGroupCachingUpdate(store, seconds):
+    txn = store.newTransaction()
+    notBefore = datetime.datetime.utcnow() + datetime.timedelta(seconds=seconds)
+    log.debug("Scheduling next group cacher update: %s" % (notBefore,))
+    wp = (yield txn.enqueue(GroupCacherPollingWork, notBefore=notBefore))
+    yield txn.commit()
+    returnValue(wp)
 
 
-
-class GroupMembershipCacherService(service.Service, LoggingMixIn):
+def schedulePolledGroupCachingUpdate(store):
     """
-    Service to update the group membership cache at a configured interval
+    Schedules a group caching update work item in "the past" so PeerConnectionPool's
+    overdue-item logic picks it up quickly.
     """
+    seconds = -PeerConnectionPool.queueProcessTimeout
+    return scheduleNextGroupCachingUpdate(store, seconds)
 
-    def __init__(self, proxyDB, directory, namespace, updateSeconds,
-        expireSeconds, lockSeconds, reactor=None, updateMethod=None,
-        useExternalProxies=False):
 
-        if updateSeconds >= expireSeconds:
-            expireSeconds = updateSeconds * 2
-            self.log_warn("Configuration warning: GroupCaching.ExpireSeconds needs to be longer than UpdateSeconds; setting to %d seconds" % (expireSeconds,))
-
-        self.updater = GroupMembershipCacheUpdater(proxyDB, directory,
-            expireSeconds, lockSeconds, namespace=namespace,
-            useExternalProxies=useExternalProxies)
-
-        if reactor is None:
-            from twisted.internet import reactor
-        self.reactor = reactor
-
-        self.updateSeconds = updateSeconds
-        self.nextUpdate = None
-        self.updateInProgress = False
-        self.updateAwaiting = False
-
-        if updateMethod:
-            self.updateMethod = updateMethod
-        else:
-            self.updateMethod = self.updater.updateCache
-
-
-    def startService(self):
-        self.previousHandler = signal.signal(signal.SIGHUP, self.sighupHandler)
-        self.log_warn("Starting group membership cacher service")
-        service.Service.startService(self)
-        return self.update()
-
-
-    def sighupHandler(self, num, frame):
-        self.reactor.callFromThread(self.update)
-
-
-    def stopService(self):
-        signal.signal(signal.SIGHUP, self.previousHandler)
-        self.log_warn("Stopping group membership cacher service")
-        service.Service.stopService(self)
-        if self.nextUpdate is not None:
-            self.nextUpdate.cancel()
-            self.nextUpdate = None
-
-
-    @inlineCallbacks
-    def update(self):
-        """
-        A wrapper around updateCache, this method manages the scheduling of the
-        subsequent update, as well as prevents multiple updates from running
-        simultaneously, which could otherwise happen because SIGHUP now triggers
-        an update on demand.  If update is called while an update is in progress,
-        as soon as the first update is finished a new one is started.  Otherwise,
-        when an update finishes and there is not another one waiting, the next
-        update is scheduled for updateSeconds in the future.
-
-        @return: True if an update was already in progress, False otherwise
-        @rtype: C{bool}
-        """
-
-        self.log_debug("Group membership update called")
-
-        # A call to update while an update is in progress sets the updateAwaiting flag
-        # so that an update happens again right after the current one is complete.
-        if self.updateInProgress:
-            self.updateAwaiting = True
-            returnValue(True)
-
-        self.nextUpdate = None
-        self.updateInProgress = True
-        self.updateAwaiting = False
-        try:
-            yield self.updateMethod()
-        finally:
-            self.updateInProgress = False
-            if self.updateAwaiting:
-                self.log_info("Performing group membership update")
-                yield self.update()
-            else:
-                self.log_info("Scheduling next group membership update")
-                self.nextUpdate = self.reactor.callLater(self.updateSeconds,
-                    self.update)
-        returnValue(False)
-
-
-
-class GroupMembershipCacherServiceMaker(LoggingMixIn):
-    """
-    Configures and returns a GroupMembershipCacherService
-    """
-    implements(IPlugin, service.IServiceMaker)
-
-    tapname = "caldav_groupcacher"
-    description = "Group Membership Cacher"
-    options = GroupMembershipCacherOptions
-
-    def makeService(self, options):
-        try:
-            from setproctitle import setproctitle
-        except ImportError:
-            pass
-        else:
-            setproctitle("CalendarServer [Group Cacher]")
-
-        # Setup the directory
-        from calendarserver.tap.util import directoryFromConfig
-        directory = directoryFromConfig(config)
-
-        # We have to set cacheNotifierFactory otherwise group cacher can't
-        # invalidate the cache tokens for principals whose membership has
-        # changed
-        if config.EnableResponseCache and config.Memcached.Pools.Default.ClientEnabled:
-            from twistedcaldav.directory.principal import DirectoryPrincipalResource
-            from twistedcaldav.cache import MemcacheChangeNotifier
-            DirectoryPrincipalResource.cacheNotifierFactory = MemcacheChangeNotifier
-
-        # Setup the ProxyDB Service
-        proxydbClass = namedClass(config.ProxyDBService.type)
-
-        self.log_warn("Configuring proxydb service of type: %s" % (proxydbClass,))
-
-        try:
-            proxyDB = proxydbClass(**config.ProxyDBService.params)
-        except IOError:
-            self.log_error("Could not start proxydb service")
-            raise
-
-        # Setup memcached pools
-        memcachepool.installPools(
-            config.Memcached.Pools,
-            config.Memcached.MaxClients,
-        )
-
-        cacherService = GroupMembershipCacherService(proxyDB, directory,
-            config.GroupCaching.MemcachedPool,
-            config.GroupCaching.UpdateSeconds,
-            config.GroupCaching.ExpireSeconds,
-            config.GroupCaching.LockSeconds,
-            useExternalProxies=config.GroupCaching.UseExternalProxies
-            )
-
-        return cacherService
-
-
-
 def diffAssignments(old, new):
     """
     Compare two proxy assignment lists and return their differences in the form of

Modified: CalendarServer/branches/users/gaya/directorybacker/twistedcaldav/directory/ldapdirectory.py
===================================================================
--- CalendarServer/branches/users/gaya/directorybacker/twistedcaldav/directory/ldapdirectory.py	2013-04-22 18:44:41 UTC (rev 11082)
+++ CalendarServer/branches/users/gaya/directorybacker/twistedcaldav/directory/ldapdirectory.py	2013-04-22 18:46:28 UTC (rev 11083)
@@ -480,6 +480,11 @@
                 # Seen when using an empty password, treat as invalid creds
                 raise ldap.INVALID_CREDENTIALS()
 
+            except ldap.NO_SUCH_OBJECT:
+                self.log_error("LDAP Authentication error for %s: NO_SUCH_OBJECT"
+                    % (dn,))
+                # fall through to try again; could be transient
+
             except ldap.INVALID_CREDENTIALS:
                 raise
 

Modified: CalendarServer/branches/users/gaya/directorybacker/twistedcaldav/directory/test/test_directory.py
===================================================================
--- CalendarServer/branches/users/gaya/directorybacker/twistedcaldav/directory/test/test_directory.py	2013-04-22 18:44:41 UTC (rev 11082)
+++ CalendarServer/branches/users/gaya/directorybacker/twistedcaldav/directory/test/test_directory.py	2013-04-22 18:46:28 UTC (rev 11083)
@@ -15,18 +15,18 @@
 ##
 
 from twisted.internet.defer import inlineCallbacks
-from twisted.internet.task import Clock
 from twisted.python.filepath import FilePath
 
 from twistedcaldav.test.util import TestCase
 from twistedcaldav.test.util import xmlFile, augmentsFile, proxiesFile, dirTest
 from twistedcaldav.config import config
-from twistedcaldav.directory.directory import DirectoryService, DirectoryRecord, GroupMembershipCacherService, GroupMembershipCache, GroupMembershipCacheUpdater, diffAssignments
+from twistedcaldav.directory.directory import DirectoryService, DirectoryRecord, GroupMembershipCache, GroupMembershipCacheUpdater, diffAssignments, schedulePolledGroupCachingUpdate
 from twistedcaldav.directory.xmlfile import XMLDirectoryService
 from twistedcaldav.directory.calendaruserproxyloader import XMLCalendarUserProxyLoader
 from twistedcaldav.directory import augment, calendaruserproxy
 from twistedcaldav.directory.util import normalizeUUID
 from twistedcaldav.directory.principal import DirectoryPrincipalProvisioningResource
+from txdav.common.datastore.test.util import buildStore
 
 import cPickle as pickle
 import uuid
@@ -121,46 +121,7 @@
         self.count += 1
 
 
-    @inlineCallbacks
-    def test_groupMembershipCacherService(self):
-        """
-        Instantiate a GroupMembershipCacherService and make sure its update
-        method fires at the right interval, in this case 30 seconds.  The
-        updateMethod keyword arg is purely for testing purposes, so we can
-        directly detect it getting called in this test.
-        """
-        clock = Clock()
-        self.count = 0
 
-        # Deliberately set the expireSeconds lower than updateSeconds to verify
-        # expireSeconds gets set to 2 * updateSeconds in that scenario
-
-        service = GroupMembershipCacherService(
-            None, None, "Testing", 30, 20, 30, reactor=clock,
-            updateMethod=self._updateMethod)
-
-        # expireSeconds = 2 * 30 updateSeconds
-        self.assertEquals(service.updater.cache.expireSeconds, 60)
-
-        yield service.startService()
-
-        self.assertEquals(self.count, 1)
-        clock.advance(29)
-        self.assertEquals(self.count, 1)
-        clock.advance(1)
-        self.assertEquals(self.count, 2)
-
-        service.stopService()
-
-        service.updateInProgress = True
-        self.assertTrue((yield service.update()))
-        self.assertTrue(service.updateAwaiting)
-
-        service.updateInProgress = False
-        self.assertFalse((yield service.update()))
-        self.assertFalse(service.updateAwaiting)
-
-
     def test_expandedMembers(self):
         """
         Make sure expandedMembers( ) returns a complete, flattened set of
@@ -279,17 +240,6 @@
             )
         )
 
-        # Prevent an update by locking the cache
-        acquiredLock = (yield cache.acquireLock())
-        self.assertTrue(acquiredLock)
-        self.assertEquals((False, 0), (yield updater.updateCache()))
-
-        # You can't lock when already locked:
-        acquiredLockAgain = (yield cache.acquireLock())
-        self.assertFalse(acquiredLockAgain)
-
-        # Allow an update by unlocking the cache
-        yield cache.releaseLock()
         self.assertEquals((False, 9, 9), (yield updater.updateCache()))
 
         # Verify cache is populated:
@@ -686,10 +636,6 @@
         # time), but since the snapshot doesn't exist we fault in from the
         # directory (fast now is False), and snapshot will get created
 
-        # Note that because fast=True and isPopulated() is False, locking is
-        # ignored:
-        yield cache.acquireLock()
-
         self.assertFalse((yield cache.isPopulated()))
         fast, numMembers, numChanged = (yield updater.updateCache(fast=True))
         self.assertEquals(fast, False)
@@ -698,8 +644,6 @@
         self.assertTrue(snapshotFile.exists())
         self.assertTrue((yield cache.isPopulated()))
 
-        yield cache.releaseLock()
-
         # Try another fast update where the snapshot already exists (as in a
         # server-restart scenario), which will only read from the snapshot
         # as indicated by the return value for "fast".  Note that the cache
@@ -795,8 +739,34 @@
             ])
         )
 
+    @inlineCallbacks
+    def testScheduling(self):
+        """
+        Exercise schedulePolledGroupCachingUpdate
+        """
 
+        groupCacher = StubGroupCacher()
 
+        def decorateTransaction(txn):
+            txn._groupCacher = groupCacher
+
+        store = yield buildStore(self, None)
+        store.callWithNewTransactions(decorateTransaction)
+        wp = (yield schedulePolledGroupCachingUpdate(store))
+        yield wp.whenExecuted()
+        self.assertTrue(groupCacher.called)
+
+    testScheduling.skip = "Fix WorkProposal to track delayed calls and cancel them"
+
+class StubGroupCacher(object):
+    def __init__(self):
+        self.called = False
+        self.updateSeconds = 99
+
+    def updateCache(self):
+        self.called = True
+
+
 class RecordsMatchingTokensTests(TestCase):
 
     @inlineCallbacks

Modified: CalendarServer/branches/users/gaya/directorybacker/twistedcaldav/ical.py
===================================================================
--- CalendarServer/branches/users/gaya/directorybacker/twistedcaldav/ical.py	2013-04-22 18:44:41 UTC (rev 11082)
+++ CalendarServer/branches/users/gaya/directorybacker/twistedcaldav/ical.py	2013-04-22 18:46:28 UTC (rev 11083)
@@ -57,7 +57,6 @@
 from pycalendar.timezone import PyCalendarTimezone
 from pycalendar.utcoffsetvalue import PyCalendarUTCOffsetValue
 
-import base64
 
 log = Logger()
 
@@ -2979,8 +2978,7 @@
                 # Check that we can lookup this calendar user address - if not
                 # we cannot do anything with it
                 cuaddr = normalizeCUAddr(prop.value())
-                name, guid, cuaddrs = lookupFunction(cuaddr, principalFunction,
-                    config)
+                name, guid, cuaddrs = lookupFunction(cuaddr, principalFunction, config)
                 if guid is None:
                     continue
 
@@ -2989,27 +2987,19 @@
                 if oldemail:
                     oldemail = "mailto:%s" % (oldemail,)
 
-                if toUUID:
-                    # Store the original CUA if http(s) or /path:
-                    if config.Scheduling.Options.V1Compatibility:
-                        if cuaddr.startswith("http") or cuaddr.startswith("/"):
-                            prop.setParameter("CALENDARSERVER-OLD-CUA",
-                                "base64-%s" % (base64.b64encode(prop.value())))
+                # Get any CN parameter
+                oldCN = prop.parameterValue("CN")
 
+                cutype = prop.parameterValue("CUTYPE")
+
+                if toUUID:
                     # Always re-write value to urn:uuid
                     prop.setValue("urn:uuid:%s" % (guid,))
 
                 # If it is already a non-UUID address leave it be
                 elif cuaddr.startswith("urn:uuid:"):
 
-                    # Restore old CUA
-                    oldExternalCUA = prop.parameterValue("CALENDARSERVER-OLD-CUA")
-                    if oldExternalCUA:
-                        if oldExternalCUA.startswith("base64-"):
-                            oldExternalCUA = base64.b64decode(oldExternalCUA[7:])
-                        newaddr = oldExternalCUA
-                        prop.removeParameter("CALENDARSERVER-OLD-CUA")
-                    elif oldemail:
+                    if oldemail:
                         # Use the EMAIL parameter if it exists
                         newaddr = oldemail
                     else:
@@ -3049,9 +3039,17 @@
                     if newaddr:
                         prop.setValue(newaddr)
 
-                # Always re-write the CN parameter
+                # Re-write the CN parameter
                 if name:
-                    prop.setParameter("CN", name)
+                    if name != oldCN:
+                        prop.setParameter("CN", name)
+
+                        # Also adjust any previously matching location property
+                        if cutype == "ROOM":
+                            location = component.getProperty("LOCATION")
+                            if location is not None:
+                                if location.value() == oldCN:
+                                    location.setValue(name)
                 else:
                     prop.removeParameter("CN")
 

Modified: CalendarServer/branches/users/gaya/directorybacker/twistedcaldav/method/propfind.py
===================================================================
--- CalendarServer/branches/users/gaya/directorybacker/twistedcaldav/method/propfind.py	2013-04-22 18:44:41 UTC (rev 11082)
+++ CalendarServer/branches/users/gaya/directorybacker/twistedcaldav/method/propfind.py	2013-04-22 18:46:28 UTC (rev 11083)
@@ -219,8 +219,11 @@
 
             # This needed for propfind cache tracking of children changes
             if depth == "1":
-                if resource != self and hasattr(resource, "url"):
-                    request.childCacheURIs.append(resource.url())
+                if resource != self:
+                    if hasattr(resource, "owner_url"):
+                        request.childCacheURIs.append(resource.owner_url())
+                    elif hasattr(resource, "url"):
+                        request.childCacheURIs.append(resource.url())
         else:
             xml_response = davxml.StatusResponse(davxml.HRef(uri), davxml.Status.fromResponseCode(responsecode.FORBIDDEN))
 

Modified: CalendarServer/branches/users/gaya/directorybacker/twistedcaldav/method/put_addressbook_common.py
===================================================================
--- CalendarServer/branches/users/gaya/directorybacker/twistedcaldav/method/put_addressbook_common.py	2013-04-22 18:44:41 UTC (rev 11082)
+++ CalendarServer/branches/users/gaya/directorybacker/twistedcaldav/method/put_addressbook_common.py	2013-04-22 18:46:28 UTC (rev 11083)
@@ -20,28 +20,29 @@
 
 __all__ = ["StoreAddressObjectResource"]
 
-import types
-
-from twisted.internet import reactor
-
-from txdav.common.icommondatastore import ReservationError
-
-from twisted.internet.defer import Deferred, inlineCallbacks
-from twisted.internet.defer import returnValue
+from twext.python.log import Logger
 from twext.web2 import responsecode
-from txdav.xml import element as davxml
 from twext.web2.dav.http import ErrorResponse
 from twext.web2.dav.util import joinURL, parentForURL
 from twext.web2.http import HTTPError
 from twext.web2.http import StatusResponse
 from twext.web2.stream import MemoryStream
 
+from twisted.internet import reactor
+from twisted.internet.defer import Deferred, inlineCallbacks
+from twisted.internet.defer import returnValue
+from twisted.python.failure import Failure
+
+from twistedcaldav import customxml
+from twistedcaldav.carddavxml import NoUIDConflict, carddav_namespace
 from twistedcaldav.config import config
-from twistedcaldav.carddavxml import NoUIDConflict, carddav_namespace
-from twistedcaldav import customxml
 from twistedcaldav.vcard import Component
-from twext.python.log import Logger
 
+from txdav.common.icommondatastore import ReservationError
+from txdav.xml import element as davxml
+
+import types
+
 log = Logger()
 
 class StoreAddressObjectResource(object):
@@ -485,12 +486,18 @@
 
             returnValue(response)
 
-        except Exception, err:
+        except Exception:
 
+            # Grab the current exception state here so we can use it in a re-raise - we need this because
+            # an inlineCallback might be called and that raises an exception when it returns, wiping out the
+            # original exception "context".
+            ex = Failure()
+
             if reservation:
                 yield reservation.unreserve()
 
-            raise err
+            # Return the original failure (exception) state
+            ex.raiseException()
 
 
     @inlineCallbacks
@@ -576,9 +583,15 @@
 
             returnValue(response)
 
-        except Exception, err:
+        except Exception:
 
+            # Grab the current exception state here so we can use it in a re-raise - we need this because
+            # an inlineCallback might be called and that raises an exception when it returns, wiping out the
+            # original exception "context".
+            ex = Failure()
+
             if reservation:
                 yield reservation.unreserve()
 
-            raise err
+            # Return the original failure (exception) state
+            ex.raiseException()

Modified: CalendarServer/branches/users/gaya/directorybacker/twistedcaldav/method/put_common.py
===================================================================
--- CalendarServer/branches/users/gaya/directorybacker/twistedcaldav/method/put_common.py	2013-04-22 18:44:41 UTC (rev 11082)
+++ CalendarServer/branches/users/gaya/directorybacker/twistedcaldav/method/put_common.py	2013-04-22 18:46:28 UTC (rev 11083)
@@ -21,42 +21,41 @@
 
 __all__ = ["StoreCalendarObjectResource"]
 
-import types
-import uuid
-from urlparse import urlparse, urlunparse
-
-from twisted.internet import reactor
-from twisted.internet.defer import Deferred, inlineCallbacks, succeed
-from twisted.internet.defer import returnValue
-from twisted.python import hashlib
-
+from twext.python.log import Logger
+from twext.web2 import responsecode
+from twext.web2.dav.http import ErrorResponse
 from twext.web2.dav.util import joinURL, parentForURL
-from twext.web2 import responsecode
-from txdav.xml import element as davxml
-
 from twext.web2.http import HTTPError
 from twext.web2.http import StatusResponse
 from twext.web2.iweb import IResponse
 from twext.web2.stream import MemoryStream
 
-from twext.python.log import Logger
-from twext.web2.dav.http import ErrorResponse
+from twisted.internet import reactor
+from twisted.internet.defer import Deferred, inlineCallbacks, succeed
+from twisted.internet.defer import returnValue
+from twisted.python import hashlib
+from twisted.python.failure import Failure
 
-from txdav.caldav.icalendarstore import AttachmentStoreValidManagedID
-from txdav.common.icommondatastore import ReservationError
-
+from twistedcaldav import customxml
+from twistedcaldav.caldavxml import caldav_namespace, NoUIDConflict, MaxInstances, MaxAttendeesPerInstance
 from twistedcaldav.config import config
-from twistedcaldav.caldavxml import caldav_namespace, NoUIDConflict, MaxInstances, MaxAttendeesPerInstance
-from twistedcaldav import customxml
 from twistedcaldav.customxml import calendarserver_namespace
 from twistedcaldav.datafilters.peruserdata import PerUserDataFilter
-
 from twistedcaldav.ical import Component, Property
 from twistedcaldav.instance import TooManyInstancesError, \
     InvalidOverriddenInstanceError
 from twistedcaldav.memcachelock import MemcacheLock, MemcacheLockTimeoutError
 from twistedcaldav.scheduling.implicit import ImplicitScheduler
 
+from txdav.caldav.icalendarstore import AttachmentStoreValidManagedID
+from txdav.common.icommondatastore import ReservationError
+from txdav.xml import element as davxml
+
+from urlparse import urlparse, urlunparse
+
+import types
+import uuid
+
 log = Logger()
 
 class StoreCalendarObjectResource(object):
@@ -203,6 +202,7 @@
         self.access = None
         self.hasPrivateComments = False
         self.isScheduleResource = False
+        self.dataChanged = False
 
 
     @inlineCallbacks
@@ -365,6 +365,9 @@
             # Check that moves to shared calendars are OK
             yield self.validCopyMoveOperation()
 
+            # Check location/resource organizer requirement
+            yield self.validLocationResourceOrganizer()
+
             # Check access
             if self.destinationcal and config.EnablePrivateEvents:
                 result = (yield self.validAccess())
@@ -662,6 +665,53 @@
 
 
     @inlineCallbacks
+    def validLocationResourceOrganizer(self):
+        """
+        If the calendar owner is a location or resource, check whether an ORGANIZER property is required.
+        """
+
+        if not self.internal_request:
+            originatorPrincipal = (yield self.destination.ownerPrincipal(self.request))
+            cutype = originatorPrincipal.getCUType() if originatorPrincipal is not None else "INDIVIDUAL"
+            organizer = self.calendar.getOrganizer()
+
+            # Check for an allowed change
+            if organizer is None and (
+                cutype == "ROOM" and not config.Scheduling.Options.AllowLocationWithoutOrganizer or
+                cutype == "RESOURCE" and not config.Scheduling.Options.AllowResourceWithoutOrganizer):
+                raise HTTPError(ErrorResponse(
+                    responsecode.FORBIDDEN,
+                    (calendarserver_namespace, "valid-organizer"),
+                    "Organizer required in calendar data",
+                ))
+
+            # Check for tracking the modifier
+            if organizer is None and (
+                cutype == "ROOM" and config.Scheduling.Options.TrackUnscheduledLocationData or
+                cutype == "RESOURCE" and config.Scheduling.Options.TrackUnscheduledResourceData):
+
+                # Find current principal
+                authz = None
+                authz_principal = self.destinationparent.currentPrincipal(self.request).children[0]
+                if isinstance(authz_principal, davxml.HRef):
+                    principalURL = str(authz_principal)
+                    if principalURL:
+                        authz = (yield self.request.locateResource(principalURL))
+
+                if authz is not None:
+                    prop = Property("X-CALENDARSERVER-MODIFIED-BY", "urn:uuid:%s" % (authz.record.guid,))
+                    prop.setParameter("CN", authz.displayName())
+                    for candidate in authz.calendarUserAddresses():
+                        if candidate.startswith("mailto:"):
+                            prop.setParameter("EMAIL", candidate[7:])
+                            break
+                    self.calendar.replacePropertyInAllComponents(prop)
+                else:
+                    self.calendar.removeAllPropertiesWithName("X-CALENDARSERVER-MODIFIED-BY")
+                self.dataChanged = True
+
+
+    @inlineCallbacks
     def preservePrivateComments(self):
         # Check for private comments on the old resource and the new resource and re-insert
         # ones that are lost.
@@ -769,7 +819,6 @@
         """
 
         # Only relevant if calendar is sharee collection
-        changed = False
         if self.destinationparent.isShareeCollection():
 
             # Get all X-APPLE-DROPBOX's and ATTACH's that are http URIs
@@ -813,59 +862,52 @@
                     uri = uriNormalize(xdropbox.value())
                     if uri:
                         xdropbox.setValue(uri)
-                        changed = True
+                        self.dataChanged = True
                 for attachment in attachments:
                     uri = uriNormalize(attachment.value())
                     if uri:
                         attachment.setValue(uri)
-                        changed = True
+                        self.dataChanged = True
 
-        returnValue(changed)
 
-
     def processAlarms(self):
         """
         Remove duplicate alarms. Add a default alarm if required.
-
-        @return: indicate whether a change was made
-        @rtype: C{bool}
         """
 
         # Remove duplicate alarms
-        changed = False
-        if config.RemoveDuplicateAlarms:
-            changed = self.calendar.hasDuplicateAlarms(doFix=True)
+        if config.RemoveDuplicateAlarms and self.calendar.hasDuplicateAlarms(doFix=True):
+            self.dataChanged = True
 
         # Only if feature enabled
         if not config.EnableDefaultAlarms:
-            return changed
+            return
 
         # Check that we are creating and this is not the inbox
         if not self.destinationcal or self.destination.exists() or self.isiTIP:
-            return changed
+            return
 
         # Never add default alarms to calendar data in shared calendars
         if self.destinationparent.isShareeCollection():
-            return changed
+            return
 
         # Add default alarm for VEVENT and VTODO only
         mtype = self.calendar.mainType().upper()
         if self.calendar.mainType().upper() not in ("VEVENT", "VTODO"):
-            return changed
+            return
         vevent = mtype == "VEVENT"
 
         # Check timed or all-day
         start, _ignore_end = self.calendar.mainComponent(allow_multiple=True).getEffectiveStartEnd()
         if start is None:
             # Yes VTODOs might have no DTSTART or DUE - in this case we do not add a default
-            return changed
+            return
         timed = not start.isDateOnly()
 
         # See if default exists and add using appropriate logic
         alarm = self.destinationparent.getDefaultAlarm(vevent, timed)
-        if alarm:
-            changed = self.calendar.addAlarms(alarm)
-        return changed
+        if alarm and self.calendar.addAlarms(alarm):
+            self.dataChanged = True
 
 
     @inlineCallbacks
@@ -996,11 +1038,14 @@
                 # Cannot do implicit in sharee's shared calendar
                 isShareeCollection = self.destinationparent.isShareeCollection()
                 if isShareeCollection:
-                    raise HTTPError(ErrorResponse(
-                        responsecode.FORBIDDEN,
-                        (calendarserver_namespace, "sharee-privilege-needed",),
-                        description="Sharee's cannot schedule"
-                    ))
+                    scheduler.setSchedulingNotAllowed(
+                        HTTPError,
+                        ErrorResponse(
+                            responsecode.FORBIDDEN,
+                            (calendarserver_namespace, "sharee-privilege-needed",),
+                            description="Sharee's cannot schedule",
+                        ),
+                    )
 
                 new_calendar = (yield scheduler.doImplicitScheduling(self.schedule_tag_match))
                 if new_calendar:
@@ -1221,14 +1266,14 @@
             yield self.replaceMissingToDoProperties()
 
             # Handle sharing dropbox normalization
-            dropboxChanged = (yield self.dropboxPathNormalization())
+            yield self.dropboxPathNormalization()
 
             # Pre-process managed attachments
             if not self.internal_request and not self.attachmentProcessingDone:
                 managed_copied, managed_removed = (yield self.destination.preProcessManagedAttachments(self.calendar))
 
             # Default/duplicate alarms
-            alarmChanged = self.processAlarms()
+            self.processAlarms()
 
             # Do scheduling
             implicit_result = (yield self.doImplicitScheduling())
@@ -1276,7 +1321,7 @@
                 yield self.destination.postProcessManagedAttachments(managed_copied, managed_removed)
 
             # Must not set ETag in response if data changed
-            if did_implicit_action or dropboxChanged or alarmChanged:
+            if did_implicit_action or self.dataChanged:
                 def _removeEtag(request, response):
                     response.headers.removeHeader('etag')
                     return response
@@ -1291,6 +1336,11 @@
 
         except Exception, err:
 
+            # Grab the current exception state here so we can use it in a re-raise - we need this because
+            # an inlineCallback might be called and that raises an exception when it returns, wiping out the
+            # original exception "context".
+            ex = Failure()
+
             if reservation:
                 yield reservation.unreserve()
 
@@ -1313,7 +1363,8 @@
                     "Invalid Managed-ID parameter in calendar data",
                 ))
             else:
-                raise err
+                # Return the original failure (exception) state
+                ex.raiseException()
 
 
     @inlineCallbacks
@@ -1409,6 +1460,11 @@
 
         except Exception, err:
 
+            # Grab the current exception state here so we can use it in a re-raise - we need this because
+            # an inlineCallback might be called and that raises an exception when it returns, wiping out the
+            # original exception "context".
+            ex = Failure()
+
             if reservation:
                 yield reservation.unreserve()
 
@@ -1431,4 +1487,5 @@
                     "Invalid Managed-ID parameter in calendar data",
                 ))
             else:
-                raise err
+                # Return the original failure (exception) state
+                ex.raiseException()

Modified: CalendarServer/branches/users/gaya/directorybacker/twistedcaldav/scheduling/caldav/delivery.py
===================================================================
--- CalendarServer/branches/users/gaya/directorybacker/twistedcaldav/scheduling/caldav/delivery.py	2013-04-22 18:44:41 UTC (rev 11082)
+++ CalendarServer/branches/users/gaya/directorybacker/twistedcaldav/scheduling/caldav/delivery.py	2013-04-22 18:46:28 UTC (rev 11083)
@@ -114,6 +114,8 @@
                     yield recipient.inbox.checkPrivileges(self.scheduler.request, (caldavxml.ScheduleDeliver(),), principal=organizerPrincipal)
                 except AccessDeniedError:
                     log.err("Could not access Inbox for recipient: %s" % (recipient.cuaddr,))
+                    if log.willLogAtLevel("debug"):
+                        log.debug("Bare Exception: %s" % (Failure().getTraceback(),))
                     err = HTTPError(ErrorResponse(
                         responsecode.NOT_FOUND,
                         (caldav_namespace, "recipient-permissions"),
@@ -164,6 +166,8 @@
             ))
         except ImplicitProcessorException, e:
             log.err("Could not store data in Inbox : %s" % (recipient.inbox,))
+            if log.willLogAtLevel("debug"):
+                log.debug("%s: %s" % (e, Failure().getTraceback(),))
             err = HTTPError(ErrorResponse(
                 responsecode.FORBIDDEN,
                 (caldav_namespace, "recipient-permissions"),
@@ -189,6 +193,8 @@
             except:
                 # FIXME: Bare except
                 log.err("Could not store data in Inbox : %s" % (recipient.inbox,))
+                if log.willLogAtLevel("debug"):
+                    log.debug("Bare Exception: %s" % (Failure().getTraceback(),))
                 err = HTTPError(ErrorResponse(
                     responsecode.FORBIDDEN,
                     (caldav_namespace, "recipient-permissions"),
@@ -230,6 +236,8 @@
             ))
         except:
             log.err("Could not determine free busy information: %s" % (recipient.cuaddr,))
+            if log.willLogAtLevel("debug"):
+                log.debug("Bare Exception: %s" % (Failure().getTraceback(),))
             err = HTTPError(ErrorResponse(
                 responsecode.FORBIDDEN,
                 (caldav_namespace, "recipient-permissions"),

Modified: CalendarServer/branches/users/gaya/directorybacker/twistedcaldav/scheduling/caldav/resource.py
===================================================================
--- CalendarServer/branches/users/gaya/directorybacker/twistedcaldav/scheduling/caldav/resource.py	2013-04-22 18:44:41 UTC (rev 11082)
+++ CalendarServer/branches/users/gaya/directorybacker/twistedcaldav/scheduling/caldav/resource.py	2013-04-22 18:46:28 UTC (rev 11083)
@@ -40,6 +40,11 @@
 from twistedcaldav.caldavxml import caldav_namespace, Opaque, \
     CalendarFreeBusySet, ScheduleCalendarTransp
 from twistedcaldav.config import config
+# _schedulePrivilegeSet implicitly depends on config being initilialized. The
+# following line is wrong because _schedulePrivilegeSet won't actually use the
+# config file, it will pick up stdconfig whenver it is imported, so this works
+# around that for now.
+__import__("twistedcaldav.stdconfig") # FIXME
 from twistedcaldav.customxml import calendarserver_namespace
 from twistedcaldav.ical import allowedComponents
 from twistedcaldav.resource import CalDAVResource

Modified: CalendarServer/branches/users/gaya/directorybacker/twistedcaldav/scheduling/imip/inbound.py
===================================================================
--- CalendarServer/branches/users/gaya/directorybacker/twistedcaldav/scheduling/imip/inbound.py	2013-04-22 18:44:41 UTC (rev 11082)
+++ CalendarServer/branches/users/gaya/directorybacker/twistedcaldav/scheduling/imip/inbound.py	2013-04-22 18:46:28 UTC (rev 11083)
@@ -120,22 +120,25 @@
         self.point = GAIEndpoint(self.reactor, settings.Server,
             settings.Port, contextFactory=contextFactory)
 
-    def startService(self):
-        return self.scheduleNextPoll(seconds=0)
 
-
     def fetchMail(self):
         return self.point.connect(self.factory(self.settings, self.mailReceiver))
 
+
     @inlineCallbacks
     def scheduleNextPoll(self, seconds=None):
         if seconds is None:
             seconds = self.settings["PollingSeconds"]
-        txn = self.store.newTransaction()
-        notBefore = datetime.datetime.utcnow() + datetime.timedelta(seconds=seconds)
-        yield txn.enqueue(IMIPPollingWork, notBefore=notBefore)
-        yield txn.commit()
+        yield scheduleNextMailPoll(self.store, seconds)
+        
 
+ at inlineCallbacks
+def scheduleNextMailPoll(store, seconds):
+    txn = store.newTransaction()
+    notBefore = datetime.datetime.utcnow() + datetime.timedelta(seconds=seconds)
+    log.debug("Scheduling next mail poll: %s" % (notBefore,))
+    yield txn.enqueue(IMIPPollingWork, notBefore=notBefore)
+    yield txn.commit()
 
 
 class MailReceiver(object):

Modified: CalendarServer/branches/users/gaya/directorybacker/twistedcaldav/scheduling/imip/test/test_inbound.py
===================================================================
--- CalendarServer/branches/users/gaya/directorybacker/twistedcaldav/scheduling/imip/test/test_inbound.py	2013-04-22 18:44:41 UTC (rev 11082)
+++ CalendarServer/branches/users/gaya/directorybacker/twistedcaldav/scheduling/imip/test/test_inbound.py	2013-04-22 18:46:28 UTC (rev 11083)
@@ -15,6 +15,7 @@
 ##
 
 
+from twistedcaldav.test.util import TestCase
 import email
 from twisted.internet.defer import inlineCallbacks
 from twisted.python.modules import getModule
@@ -24,7 +25,6 @@
 from twistedcaldav.scheduling.imip.inbound import injectMessage
 from twistedcaldav.scheduling.imip.inbound import IMIPReplyWork
 from twistedcaldav.scheduling.itip import iTIPRequestStatus
-from twistedcaldav.test.util import TestCase
 from twistedcaldav.test.util import xmlFile
 from txdav.common.datastore.test.util import buildStore
 from calendarserver.tap.util import getRootResource

Modified: CalendarServer/branches/users/gaya/directorybacker/twistedcaldav/scheduling/implicit.py
===================================================================
--- CalendarServer/branches/users/gaya/directorybacker/twistedcaldav/scheduling/implicit.py	2013-04-22 18:44:41 UTC (rev 11082)
+++ CalendarServer/branches/users/gaya/directorybacker/twistedcaldav/scheduling/implicit.py	2013-04-22 18:46:28 UTC (rev 11083)
@@ -35,6 +35,8 @@
 from twistedcaldav.scheduling.utils import getCalendarObjectForPrincipals
 from twistedcaldav.config import config
 
+import collections
+
 __all__ = [
     "ImplicitScheduler",
 ]
@@ -57,8 +59,34 @@
     def __init__(self):
 
         self.return_status = ImplicitScheduler.STATUS_OK
+        self.allowed_to_schedule = True
 
+    NotAllowedExceptionDetails = collections.namedtuple("NotAllowedExceptionDetails", ("type", "args", "kwargs",))
 
+    def setSchedulingNotAllowed(self, ex, *ex_args, **ex_kwargs):
+        """
+        Set indicator that scheduling is not actually allowed. Pass in exception details to raise.
+
+        @param ex: the exception class to raise
+        @type ex: C{class}
+        @param ex_args: the list of arguments for the exception
+        @type ex_args: C{list}
+        """
+
+        self.not_allowed = ImplicitScheduler.NotAllowedExceptionDetails(ex, ex_args, ex_kwargs)
+        self.allowed_to_schedule = False
+
+
+    def testSchedulingAllowed(self):
+        """
+        Called to raise an exception if scheduling is not allowed. This method should be called
+        any time a valid scheduling operation needs to occur.
+        """
+
+        if not self.allowed_to_schedule:
+            raise self.not_allowed.type(*self.not_allowed.args, **self.not_allowed.kwargs)
+
+
     @inlineCallbacks
     def testImplicitSchedulingPUT(self, request, resource, resource_uri, calendar, internal_request=False):
 
@@ -545,10 +573,6 @@
     @inlineCallbacks
     def doImplicitOrganizer(self):
 
-        # Do access control
-        if not self.internal_request:
-            yield self.doAccessControl(self.organizerPrincipal, True)
-
         self.oldcalendar = None
         self.changed_rids = None
         self.cancelledAttendees = ()
@@ -933,6 +957,13 @@
     @inlineCallbacks
     def scheduleWithAttendees(self):
 
+        # First make sure we are allowed to schedule
+        self.testSchedulingAllowed()
+
+        # Do access control
+        if not self.internal_request:
+            yield self.doAccessControl(self.organizerPrincipal, True)
+
         # First process cancelled attendees
         total = (yield self.processCancels())
 
@@ -1052,10 +1083,6 @@
     @inlineCallbacks
     def doImplicitAttendee(self):
 
-        # Do access control
-        if not self.internal_request:
-            yield self.doAccessControl(self.attendeePrincipal, False)
-
         # Check SCHEDULE-AGENT
         doScheduling = self.checkOrganizerScheduleAgent()
 
@@ -1283,8 +1310,16 @@
         return differ.attendeeMerge(self.attendee)
 
 
+    @inlineCallbacks
     def scheduleWithOrganizer(self, changedRids=None):
 
+        # First make sure we are allowed to schedule
+        self.testSchedulingAllowed()
+
+        # Do access control
+        if not self.internal_request:
+            yield self.doAccessControl(self.attendeePrincipal, False)
+
         if not hasattr(self.request, "extendedLogItems"):
             self.request.extendedLogItems = {}
         self.request.extendedLogItems["itip.reply"] = "reply"
@@ -1292,11 +1327,19 @@
         itipmsg = iTipGenerator.generateAttendeeReply(self.calendar, self.attendee, changedRids=changedRids)
 
         # Send scheduling message
-        return self.sendToOrganizer("REPLY", itipmsg)
+        yield self.sendToOrganizer("REPLY", itipmsg)
 
 
+    @inlineCallbacks
     def scheduleCancelWithOrganizer(self):
 
+        # First make sure we are allowed to schedule
+        self.testSchedulingAllowed()
+
+        # Do access control
+        if not self.internal_request:
+            yield self.doAccessControl(self.attendeePrincipal, False)
+
         if not hasattr(self.request, "extendedLogItems"):
             self.request.extendedLogItems = {}
         self.request.extendedLogItems["itip.reply"] = "cancel"
@@ -1304,7 +1347,7 @@
         itipmsg = iTipGenerator.generateAttendeeReply(self.calendar, self.attendee, force_decline=True)
 
         # Send scheduling message
-        return self.sendToOrganizer("CANCEL", itipmsg)
+        yield self.sendToOrganizer("CANCEL", itipmsg)
 
 
     def sendToOrganizer(self, action, itipmsg):

Modified: CalendarServer/branches/users/gaya/directorybacker/twistedcaldav/stdconfig.py
===================================================================
--- CalendarServer/branches/users/gaya/directorybacker/twistedcaldav/stdconfig.py	2013-04-22 18:44:41 UTC (rev 11082)
+++ CalendarServer/branches/users/gaya/directorybacker/twistedcaldav/stdconfig.py	2013-04-22 18:46:28 UTC (rev 11083)
@@ -37,7 +37,9 @@
 from twisted.python.runtime import platform
 
 from calendarserver.push.util import getAPNTopicFromCertificate
+from twistedcaldav.util import computeProcessCount
 
+
 log = Logger()
 
 if platform.isMacOSX():
@@ -730,13 +732,16 @@
             "AllowGroupAsOrganizer"               : False, # Allow groups to be Organizers
             "AllowLocationAsOrganizer"            : False, # Allow locations to be Organizers
             "AllowResourceAsOrganizer"            : False, # Allow resources to be Organizers
+            "AllowLocationWithoutOrganizer"       : True, # Allow locations to have events without an Organizer
+            "AllowResourceWithoutOrganizer"       : True, # Allow resources to have events without an Organizer
+            "TrackUnscheduledLocationData"        : True, # Track who the last modifier of an unscheduled location event is
+            "TrackUnscheduledResourceData"        : True, # Track who the last modifier of an unscheduled resource event is
             "LimitFreeBusyAttendees"              : 30, # Maximum number of attendees to request freebusy for
             "AttendeeRefreshBatch"                : 5, # Number of attendees to do batched refreshes: 0 - no batching
             "AttendeeRefreshBatchDelaySeconds"    : 5, # Time after an iTIP REPLY for first batched attendee refresh
             "AttendeeRefreshBatchIntervalSeconds" : 5, # Time between attendee batch refreshes
             "UIDLockTimeoutSeconds"               : 60, # Time for implicit UID lock timeout
             "UIDLockExpirySeconds"                : 300, # Expiration time for UID lock,
-            "V1Compatibility"                     : False, # Allow /path-based CUAs in scheduling replies
             "PrincipalHostAliases"                : [], # Host names matched in http(s) CUAs
             "TimestampAttendeePartStatChanges"    : True, # Add a time stamp when an Attendee changes their PARTSTAT
 
@@ -940,8 +945,14 @@
         "DatabaseName": "caldav",
         "LogFile": "postgres.log",
         "ListenAddresses": [],
-        "SharedBuffers": 30,
-        "MaxConnections": 20,
+        "SharedBuffers": 0, # BuffersToConnectionsRatio * MaxConnections
+                            # Note: don't set this, it will be computed dynamically
+                            # See _updateMultiProcess( ) below for details
+        "MaxConnections": 0, # Dynamically computed based on ProcessCount, etc.
+                             # Note: don't set this, it will be computed dynamically
+                             # See _updateMultiProcess( ) below for details
+        "ExtraConnections": 3, # how many extra connections to leave for utilities
+        "BuffersToConnectionsRatio": 1.5,
         "Options": [
             "-c standard_conforming_strings=on",
         ],
@@ -963,7 +974,6 @@
         "MemcachedPool" : "Default",
         "UpdateSeconds" : 300,
         "ExpireSeconds" : 3600,
-        "LockSeconds" : 300,
         "EnableUpdater" : True,
         "UseExternalProxies" : False,
     },
@@ -1071,6 +1081,7 @@
         return configDict
 
 
+
 def _expandPath(path):
     if '$' in path:
         return path.replace('$', getfqdn())
@@ -1112,9 +1123,11 @@
     # Remove possible trailing slash from ServerRoot
     try:
         configDict["ServerRoot"] = configDict["ServerRoot"].rstrip("/")
+        configDict["ServerRoot"] = os.path.abspath(configDict["ServerRoot"])
     except KeyError:
         pass
 
+
     for root, relativePath in RELATIVE_PATHS:
         if root in configDict:
             if isinstance(relativePath, str):
@@ -1161,7 +1174,38 @@
         configDict.ServerHostName = hostname
 
 
+def _updateMultiProcess(configDict, reloading=False):
+    """
+    Dynamically compute ProcessCount if it's set to 0.  Always compute
+    MaxConnections and SharedBuffers based on ProcessCount, ExtraConnections,
+    SharedConnectionPool, MaxDBConnectionsPerPool, and BuffersToConnectionsRatio
+    """
+    if configDict.MultiProcess.ProcessCount == 0:
+        processCount = computeProcessCount(
+            configDict.MultiProcess.MinProcessCount,
+            configDict.MultiProcess.PerCPU,
+            configDict.MultiProcess.PerGB,
+        )
+        configDict.MultiProcess.ProcessCount = processCount
 
+    # Start off with extra connections to be used by command line utilities and
+    # administration/inspection tools
+    maxConnections = configDict.Postgres.ExtraConnections
+
+    if configDict.SharedConnectionPool:
+        # If SharedConnectionPool is enabled, then only the master process will
+        # be connection to the database, therefore use MaxDBConnectionsPerPool
+        maxConnections += configDict.MaxDBConnectionsPerPool
+    else:
+        # Otherwise the master *and* each worker process will be connecting
+        maxConnections += ((configDict.MultiProcess.ProcessCount + 1) *
+            configDict.MaxDBConnectionsPerPool)
+
+    configDict.Postgres.MaxConnections = maxConnections
+    configDict.Postgres.SharedBuffers = int(configDict.Postgres.MaxConnections *
+        configDict.Postgres.BuffersToConnectionsRatio)
+
+
 def _preUpdateDirectoryService(configDict, items, reloading=False):
     # Special handling for directory services configs
     dsType = items.get("DirectoryService", {}).get("type", None)
@@ -1535,6 +1579,7 @@
     _preUpdateDirectoryAddressBookBackingDirectoryService,
     )
 POST_UPDATE_HOOKS = (
+    _updateMultiProcess,
     _updateDataStore,
     _updateHostName,
     _postUpdateDirectoryService,

Modified: CalendarServer/branches/users/gaya/directorybacker/twistedcaldav/storebridge.py
===================================================================
--- CalendarServer/branches/users/gaya/directorybacker/twistedcaldav/storebridge.py	2013-04-22 18:44:41 UTC (rev 11082)
+++ CalendarServer/branches/users/gaya/directorybacker/twistedcaldav/storebridge.py	2013-04-22 18:46:28 UTC (rev 11083)
@@ -265,6 +265,13 @@
         return joinURL(self._parentResource.url(), self._name, "/")
 
 
+    def owner_url(self):
+        if self.isShareeCollection():
+            return joinURL(self._share.url(), "/")
+        else:
+            return self.url()
+
+
     def parentResource(self):
         return self._parentResource
 

Modified: CalendarServer/branches/users/gaya/directorybacker/twistedcaldav/test/test_config.py
===================================================================
--- CalendarServer/branches/users/gaya/directorybacker/twistedcaldav/test/test_config.py	2013-04-22 18:44:41 UTC (rev 11082)
+++ CalendarServer/branches/users/gaya/directorybacker/twistedcaldav/test/test_config.py	2013-04-22 18:46:28 UTC (rev 11083)
@@ -83,7 +83,8 @@
 
     def testDefaults(self):
         for key, value in DEFAULT_CONFIG.iteritems():
-            if key in ("ServerHostName", "Notifications"):
+            if key in ("ServerHostName", "Notifications", "MultiProcess",
+                "Postgres"):
                 # Value is calculated and may vary
                 continue
             for item in RELATIVE_PATHS:

Modified: CalendarServer/branches/users/gaya/directorybacker/twistedcaldav/test/test_icalendar.py
===================================================================
--- CalendarServer/branches/users/gaya/directorybacker/twistedcaldav/test/test_icalendar.py	2013-04-22 18:44:41 UTC (rev 11082)
+++ CalendarServer/branches/users/gaya/directorybacker/twistedcaldav/test/test_icalendar.py	2013-04-22 18:46:28 UTC (rev 11083)
@@ -20,7 +20,6 @@
 
 from twisted.trial.unittest import SkipTest
 
-from twistedcaldav.config import config
 from twistedcaldav.ical import Component, Property, InvalidICalendarDataError, \
     normalizeCUAddress
 from twistedcaldav.instance import InvalidOverriddenInstanceError
@@ -7323,7 +7322,6 @@
     def test_normalizeCalendarUserAddressesFromUUID(self):
         """
         Ensure mailto is preferred, followed by path form, then http form.
-        If CALENDARSERVER-OLD-CUA parameter is present, restore that value.
         """
 
         data = """BEGIN:VCALENDAR
@@ -7335,7 +7333,6 @@
 ATTENDEE:urn:uuid:foo
 ATTENDEE:urn:uuid:bar
 ATTENDEE:urn:uuid:baz
-ATTENDEE;CALENDARSERVER-OLD-CUA="base64-aHR0cDovL2V4YW1wbGUuY29tL3ByaW5jaXBhbHMvdXNlcnMvYnV6":urn:uuid:buz
 DTSTAMP:20071114T000000Z
 END:VEVENT
 END:VCALENDAR
@@ -7361,11 +7358,6 @@
                     "baz",
                     ("urn:uuid:baz", "http://example.com/baz")
                 ),
-                "urn:uuid:buz" : (
-                    "Buz",
-                    "buz",
-                    ("urn:uuid:buz",)
-                ),
             }[cuaddr]
 
         component.normalizeCalendarUserAddresses(lookupFunction, None, toUUID=False)
@@ -7376,11 +7368,11 @@
             component.getAttendeeProperty(("/foo",)).value())
         self.assertEquals("http://example.com/baz",
             component.getAttendeeProperty(("http://example.com/baz",)).value())
-        self.assertEquals("http://example.com/principals/users/buz",
-            component.getAttendeeProperty(("http://example.com/principals/users/buz",)).value())
 
 
-    def test_normalizeCalendarUserAddressesToUUID(self):
+
+
+    def test_normalizeCalendarUserAddressesAndLocationChange(self):
         """
         Ensure http(s) and /path CUA values are tucked away into the property
         using CALENDARSERVER-OLD-CUA parameter.
@@ -7393,7 +7385,9 @@
 UID:12345-67890
 DTSTART:20071114T000000Z
 ATTENDEE:/principals/users/foo
-ATTENDEE:http://example.com/principals/users/buz
+ATTENDEE:http://example.com/principals/users/bar
+ATTENDEE;CN=Buzz;CUTYPE=ROOM:http://example.com/principals/locations/buzz
+LOCATION:Buzz
 DTSTAMP:20071114T000000Z
 END:VEVENT
 END:VCALENDAR
@@ -7409,29 +7403,134 @@
                     "foo",
                     ("urn:uuid:foo",)
                 ),
-                "http://example.com/principals/users/buz" : (
-                    "Buz",
-                    "buz",
-                    ("urn:uuid:buz",)
+                "http://example.com/principals/users/bar" : (
+                    "Bar",
+                    "bar",
+                    ("urn:uuid:bar",)
                 ),
+                "http://example.com/principals/locations/buzz" : (
+                    "{Restricted} Buzz",
+                    "buzz",
+                    ("urn:uuid:buzz",)
+                ),
             }[cuaddr]
 
-        self.patch(config.Scheduling.Options, "V1Compatibility", True)
         component.normalizeCalendarUserAddresses(lookupFunction, None, toUUID=True)
 
-        # /principal CUAs are stored in CALENDARSERVER-OLD-CUA
-        prop = component.getAttendeeProperty(("urn:uuid:foo",))
-        self.assertEquals("urn:uuid:foo", prop.value())
-        self.assertEquals(prop.parameterValue("CALENDARSERVER-OLD-CUA"),
-            "base64-L3ByaW5jaXBhbHMvdXNlcnMvZm9v")
+        # Location value changed
+        prop = component.mainComponent().getProperty("LOCATION")
+        self.assertEquals(prop.value(), "{Restricted} Buzz")
+        prop = component.getAttendeeProperty(("urn:uuid:buzz",))
+        self.assertEquals("urn:uuid:buzz", prop.value())
+        self.assertEquals(prop.parameterValue("CN"), "{Restricted} Buzz")
 
-        # http CUAs are stored in CALENDARSERVER-OLD-CUA
-        prop = component.getAttendeeProperty(("urn:uuid:buz",))
-        self.assertEquals("urn:uuid:buz", prop.value())
-        self.assertEquals(prop.parameterValue("CALENDARSERVER-OLD-CUA"),
-            "base64-aHR0cDovL2V4YW1wbGUuY29tL3ByaW5jaXBhbHMvdXNlcnMvYnV6")
 
+    def test_normalizeCalendarUserAddressesAndLocationNoChange(self):
+        """
+        Ensure http(s) and /path CUA values are tucked away into the property
+        using CALENDARSERVER-OLD-CUA parameter.
+        """
 
+        data = """BEGIN:VCALENDAR
+VERSION:2.0
+DTSTART:20071114T000000Z
+BEGIN:VEVENT
+UID:12345-67890
+DTSTART:20071114T000000Z
+ATTENDEE:/principals/users/foo
+ATTENDEE:http://example.com/principals/users/bar
+ATTENDEE;CN=Buzz;CUTYPE=ROOM:http://example.com/principals/locations/buzz
+LOCATION:Fuzz
+DTSTAMP:20071114T000000Z
+END:VEVENT
+END:VCALENDAR
+"""
+
+        component = Component.fromString(data)
+
+
+        def lookupFunction(cuaddr, ignored1, ignored2):
+            return {
+                "/principals/users/foo" : (
+                    "Foo",
+                    "foo",
+                    ("urn:uuid:foo",)
+                ),
+                "http://example.com/principals/users/bar" : (
+                    "Bar",
+                    "bar",
+                    ("urn:uuid:bar",)
+                ),
+                "http://example.com/principals/locations/buzz" : (
+                    "{Restricted} Buzz",
+                    "buzz",
+                    ("urn:uuid:buzz",)
+                ),
+            }[cuaddr]
+
+        component.normalizeCalendarUserAddresses(lookupFunction, None, toUUID=True)
+
+        # Location value changed
+        prop = component.mainComponent().getProperty("LOCATION")
+        self.assertEquals(prop.value(), "Fuzz")
+        prop = component.getAttendeeProperty(("urn:uuid:buzz",))
+        self.assertEquals("urn:uuid:buzz", prop.value())
+        self.assertEquals(prop.parameterValue("CN"), "{Restricted} Buzz")
+
+
+    def test_normalizeCalendarUserAddressesAndLocationNoChangeOtherCUType(self):
+        """
+        Ensure http(s) and /path CUA values are tucked away into the property
+        using CALENDARSERVER-OLD-CUA parameter.
+        """
+
+        data = """BEGIN:VCALENDAR
+VERSION:2.0
+DTSTART:20071114T000000Z
+BEGIN:VEVENT
+UID:12345-67890
+DTSTART:20071114T000000Z
+ATTENDEE:/principals/users/foo
+ATTENDEE:http://example.com/principals/users/bar
+ATTENDEE;CN=Buzz;CUTYPE=RESOURCE:http://example.com/principals/locations/buzz
+LOCATION:Buzz
+DTSTAMP:20071114T000000Z
+END:VEVENT
+END:VCALENDAR
+"""
+
+        component = Component.fromString(data)
+
+
+        def lookupFunction(cuaddr, ignored1, ignored2):
+            return {
+                "/principals/users/foo" : (
+                    "Foo",
+                    "foo",
+                    ("urn:uuid:foo",)
+                ),
+                "http://example.com/principals/users/bar" : (
+                    "Bar",
+                    "bar",
+                    ("urn:uuid:bar",)
+                ),
+                "http://example.com/principals/locations/buzz" : (
+                    "{Restricted} Buzz",
+                    "buzz",
+                    ("urn:uuid:buzz",)
+                ),
+            }[cuaddr]
+
+        component.normalizeCalendarUserAddresses(lookupFunction, None, toUUID=True)
+
+        # Location value changed
+        prop = component.mainComponent().getProperty("LOCATION")
+        self.assertEquals(prop.value(), "Buzz")
+        prop = component.getAttendeeProperty(("urn:uuid:buzz",))
+        self.assertEquals("urn:uuid:buzz", prop.value())
+        self.assertEquals(prop.parameterValue("CN"), "{Restricted} Buzz")
+
+
     def test_serializationCaching(self):
 
         data = """BEGIN:VCALENDAR

Modified: CalendarServer/branches/users/gaya/directorybacker/twistedcaldav/test/test_stdconfig.py
===================================================================
--- CalendarServer/branches/users/gaya/directorybacker/twistedcaldav/test/test_stdconfig.py	2013-04-22 18:44:41 UTC (rev 11082)
+++ CalendarServer/branches/users/gaya/directorybacker/twistedcaldav/test/test_stdconfig.py	2013-04-22 18:46:28 UTC (rev 11083)
@@ -15,14 +15,16 @@
 # limitations under the License.
 ##
 
+import os
 from cStringIO import StringIO
 
 from twext.python.filepath import CachingFilePath as FilePath
 from twisted.trial.unittest import TestCase
 
-from twistedcaldav.config import Config
+from twistedcaldav.config import Config, ConfigDict
 from twistedcaldav.stdconfig import NoUnicodePlistParser, PListConfigProvider,\
-    _updateDataStore
+    _updateDataStore, _updateMultiProcess
+import twistedcaldav.stdconfig
 
 nonASCIIValue = "→←"
 nonASCIIPlist = "<plist version='1.0'><string>%s</string></plist>" % (
@@ -149,3 +151,31 @@
         }
         _updateDataStore(configDict)
         self.assertEquals(configDict["ServerRoot"], "/a/b/c")
+
+        configDict = {
+            "ServerRoot" : "./a",
+        }
+        _updateDataStore(configDict)
+        self.assertEquals(configDict["ServerRoot"], os.path.join(os.getcwd(), "a"))
+
+    def test_updateMultiProcess(self):
+        def stubProcessCount(*args):
+            return 3
+        self.patch(twistedcaldav.stdconfig, "computeProcessCount", stubProcessCount)
+        configDict = ConfigDict({
+            "MultiProcess" : {
+                "ProcessCount" : 0,
+                "MinProcessCount" : 2,
+                "PerCPU" : 1,
+                "PerGB" : 1,
+            },
+            "Postgres" : {
+                "ExtraConnections" : 5,
+                "BuffersToConnectionsRatio" : 1.5,
+            },
+            "SharedConnectionPool" : False,
+            "MaxDBConnectionsPerPool" : 10,
+        })
+        _updateMultiProcess(configDict)
+        self.assertEquals(45, configDict.Postgres.MaxConnections)
+        self.assertEquals(67, configDict.Postgres.SharedBuffers)

Modified: CalendarServer/branches/users/gaya/directorybacker/twistedcaldav/test/test_validation.py
===================================================================
--- CalendarServer/branches/users/gaya/directorybacker/twistedcaldav/test/test_validation.py	2013-04-22 18:44:41 UTC (rev 11082)
+++ CalendarServer/branches/users/gaya/directorybacker/twistedcaldav/test/test_validation.py	2013-04-22 18:46:28 UTC (rev 11083)
@@ -23,6 +23,7 @@
 # to address this to use system twisted.
 from twext.web2.test.test_server import SimpleRequest
 from twext.web2.http import HTTPError
+from twext.web2.resource import Resource
 
 from twistedcaldav.config import config
 from twistedcaldav.ical import Component, Property
@@ -31,16 +32,20 @@
 from twistedcaldav.resource import CalDAVResource
 
 class InMemoryCalendarObjectResource(CalDAVResource):
-    
+
     def exists(self):
         return hasattr(self, "_data") and self._data is not None
 
+
     def iCalendarForUser(self, user):
         return self._data
-    
+
+
     def setData(self, data):
         self._data = data
 
+
+
 class TestCopyMoveValidation(TestCase):
     """
     Tests for the validation code in L{twistedcaldav.method.put_common}.
@@ -52,11 +57,12 @@
         """
 
         self.destination = InMemoryCalendarObjectResource()
-        self.destination.name = lambda : '1'
+        self.destination.name = lambda : 'bar'
         self.destinationParent = CalDAVResource()
-        self.destinationParent.name = lambda : '2'
+        self.destinationParent.name = lambda : 'foo'
         self.destinationParent.isSupportedComponent = lambda x: True
 
+
     def _getSampleCalendar(self):
         return Component.fromString("""BEGIN:VCALENDAR
 VERSION:2.0
@@ -72,9 +78,13 @@
 END:VCALENDAR
 """)
 
+
     def _getStorer(self, calendar):
         self.sampleCalendar = calendar
         req = SimpleRequest(None, "COPY", "http://example.com/foo/bar")
+        req._rememberResource(self.destination, "/foo/bar")
+        req._rememberResource(self.destinationParent, "/foo/")
+        req._rememberResource(Resource(), "/")
         self.storer = StoreCalendarObjectResource(
             req,
             destination=self.destination,
@@ -83,7 +93,8 @@
             calendar=self.sampleCalendar
         )
         return self.storer
-                
+
+
     @inlineCallbacks
     def test_simpleValidRequest(self):
         """
@@ -110,7 +121,7 @@
         eventComponent = list(self.sampleCalendar.subcomponents())[0]
         for x in xrange(config.MaxAttendeesPerInstance):
             eventComponent.addProperty(
-                Property("ATTENDEE", "mailto:user%d at example.com" % (x+3,)))
+                Property("ATTENDEE", "mailto:user%d at example.com" % (x + 3,)))
 
         try:
             yield self._getStorer(self.sampleCalendar).fullValidation()
@@ -143,7 +154,7 @@
         eventComponent = list(self.sampleCalendar.subcomponents())[0]
         for x in xrange(config.MaxAttendeesPerInstance - 5):
             eventComponent.addProperty(
-                Property("ATTENDEE", "mailto:user%d at example.com" % (x+3,)))
+                Property("ATTENDEE", "mailto:user%d at example.com" % (x + 3,)))
 
         try:
             yield self._getStorer(self.sampleCalendar).fullValidation()
@@ -155,7 +166,7 @@
         config.MaxAttendeesPerInstance -= 10
         eventComponent.addProperty(
             Property("ATTENDEE", "mailto:user-extra at example.com"))
-        
+
         try:
             yield self._getStorer(self.sampleCalendar).fullValidation()
         except HTTPError, err:
@@ -187,7 +198,7 @@
         eventComponent = list(self.sampleCalendar.subcomponents())[0]
         for x in xrange(config.MaxAttendeesPerInstance - 5):
             eventComponent.addProperty(
-                Property("ATTENDEE", "mailto:user%d at example.com" % (x+3,)))
+                Property("ATTENDEE", "mailto:user%d at example.com" % (x + 3,)))
 
         try:
             yield self._getStorer(self.sampleCalendar).fullValidation()
@@ -197,7 +208,7 @@
 
         # Now reduce the limit and try to store without any additional attendees.
         config.MaxAttendeesPerInstance -= 10
-        
+
         try:
             yield self._getStorer(self.sampleCalendar).fullValidation()
         except HTTPError:
@@ -209,8 +220,8 @@
         eventComponent = list(self.sampleCalendar.subcomponents())[0]
         for x in xrange(config.MaxAttendeesPerInstance + 2):
             eventComponent.addProperty(
-                Property("ATTENDEE", "mailto:user%d at example.com" % (x+3,)))
-        
+                Property("ATTENDEE", "mailto:user%d at example.com" % (x + 3,)))
+
         try:
             yield self._getStorer(self.sampleCalendar).fullValidation()
         except HTTPError:

Modified: CalendarServer/branches/users/gaya/directorybacker/twistedcaldav/test/util.py
===================================================================
--- CalendarServer/branches/users/gaya/directorybacker/twistedcaldav/test/util.py	2013-04-22 18:44:41 UTC (rev 11082)
+++ CalendarServer/branches/users/gaya/directorybacker/twistedcaldav/test/util.py	2013-04-22 18:46:28 UTC (rev 11083)
@@ -19,7 +19,7 @@
 import os
 import xattr
 
-from calendarserver.provision.root import RootResource
+from twistedcaldav.stdconfig import config
 
 from twisted.python.failure import Failure
 from twisted.internet.base import DelayedCall
@@ -34,7 +34,6 @@
 
 from twistedcaldav import memcacher
 from twistedcaldav.bind import doBind
-from twistedcaldav.config import config
 from twistedcaldav.directory import augment
 from twistedcaldav.directory.addressbook import DirectoryAddressBookHomeProvisioningResource
 from twistedcaldav.directory.calendar import (
@@ -48,6 +47,8 @@
 from txdav.common.datastore.test.util import deriveQuota
 from txdav.common.datastore.file import CommonDataStore
 
+from calendarserver.provision.root import RootResource
+
 from twext.python.log import Logger
 
 log = Logger()

Modified: CalendarServer/branches/users/gaya/directorybacker/twistedcaldav/upgrade.py
===================================================================
--- CalendarServer/branches/users/gaya/directorybacker/twistedcaldav/upgrade.py	2013-04-22 18:44:41 UTC (rev 11082)
+++ CalendarServer/branches/users/gaya/directorybacker/twistedcaldav/upgrade.py	2013-04-22 18:46:28 UTC (rev 11083)
@@ -39,7 +39,9 @@
 from twistedcaldav.directory import calendaruserproxy
 from twistedcaldav.directory.appleopendirectory import OpenDirectoryService
 from twistedcaldav.directory.calendaruserproxyloader import XMLCalendarUserProxyLoader
-from twistedcaldav.directory.directory import DirectoryService, GroupMembershipCacheUpdater
+from twistedcaldav.directory.directory import DirectoryService
+from twistedcaldav.directory.directory import GroupMembershipCacheUpdater
+from twistedcaldav.directory.directory import scheduleNextGroupCachingUpdate
 from twistedcaldav.directory.principal import DirectoryCalendarPrincipalResource
 from twistedcaldav.directory.resourceinfo import ResourceInfoDatabase
 from twistedcaldav.directory.xmlfile import XMLDirectoryService
@@ -67,6 +69,7 @@
 
 from twext.python.parallel import Parallelizer
 from twistedcaldav.scheduling.imip.mailgateway import migrateTokensToStore
+from twistedcaldav.scheduling.imip.inbound import scheduleNextMailPoll
 
 
 deadPropertyXattrPrefix = namedAny(
@@ -1069,11 +1072,14 @@
                 proxydb = proxydbClass(**self.config.ProxyDBService.params)
 
             updater = GroupMembershipCacheUpdater(proxydb,
-                directory, self.config.GroupCaching.ExpireSeconds,
-                self.config.GroupCaching.LockSeconds,
+                directory,
+                self.config.GroupCaching.UpdateSeconds,
+                self.config.GroupCaching.ExpireSeconds,
                 namespace=self.config.GroupCaching.MemcachedPool,
                 useExternalProxies=self.config.GroupCaching.UseExternalProxies)
             yield updater.updateCache(fast=True)
+            # Set in motion the work queue based updates:
+            yield scheduleNextGroupCachingUpdate(self.store, 0)
 
             uid, gid = getCalendarServerIDs(self.config)
             dbPath = os.path.join(self.config.DataRoot, "proxies.sqlite")
@@ -1087,6 +1093,9 @@
 
         # Migrate mail tokens from sqlite to store
         yield migrateTokensToStore(self.config.DataRoot, self.store)
+        # Set mail polling in motion
+        if self.config.Scheduling.iMIP.Enabled:
+            yield scheduleNextMailPoll(self.store, 0)
 
 
 

Modified: CalendarServer/branches/users/gaya/directorybacker/twistedcaldav/util.py
===================================================================
--- CalendarServer/branches/users/gaya/directorybacker/twistedcaldav/util.py	2013-04-22 18:44:41 UTC (rev 11082)
+++ CalendarServer/branches/users/gaya/directorybacker/twistedcaldav/util.py	2013-04-22 18:46:28 UTC (rev 11083)
@@ -106,6 +106,37 @@
     def getMemorySize():
         raise NotImplementedError("getMemorySize not yet supported on %s" % (sys.platform))
 
+
+def computeProcessCount(minimum, perCPU, perGB, cpuCount=None, memSize=None):
+    """
+    Determine how many process to spawn based on installed RAM and CPUs,
+    returning at least "mininum"
+    """
+
+    if cpuCount is None:
+        try:
+            cpuCount = getNCPU()
+        except NotImplementedError, e:
+            log.error("Unable to detect number of CPUs: %s" % (str(e),))
+            return minimum
+
+    if memSize is None:
+        try:
+            memSize = getMemorySize()
+        except NotImplementedError, e:
+            log.error("Unable to detect amount of installed RAM: %s" % (str(e),))
+            return minimum
+
+    countByCore = perCPU * cpuCount
+    countByMemory = perGB * (memSize / (1024 * 1024 * 1024))
+
+    # Pick the smaller of the two:
+    count = min(countByCore, countByMemory)
+
+    # ...but at least "minimum"
+    return max(count, minimum)
+
+
 ##
 # Module management
 ##
@@ -464,11 +495,6 @@
         # to single-quotes.
         fullName = rec.fullName.replace('"', "'")
 
-        # TODO: remove V1Compatibility when V1 migration is complete
-        if config.Scheduling.Options.V1Compatibility:
-            # Allow /principals-form CUA
-            cuas = principal.calendarUserAddresses()
-        else:
-            cuas = principal.record.calendarUserAddresses
+        cuas = principal.record.calendarUserAddresses
 
         return (fullName, rec.guid, cuas)

Modified: CalendarServer/branches/users/gaya/directorybacker/txdav/base/datastore/dbapiclient.py
===================================================================
--- CalendarServer/branches/users/gaya/directorybacker/txdav/base/datastore/dbapiclient.py	2013-04-22 18:44:41 UTC (rev 11082)
+++ CalendarServer/branches/users/gaya/directorybacker/txdav/base/datastore/dbapiclient.py	2013-04-22 18:46:28 UTC (rev 11083)
@@ -39,7 +39,7 @@
     # however, process-global; after the first call to connect(), all
     # subsequent connections inherit this encoding even if the environment
     # variable changes.) -glyph
-    os.environ['NLS_LANG'] = '.UTF8'
+    os.environ['NLS_LANG'] = '.AL32UTF8'
     import cx_Oracle
 except ImportError:
     cx_Oracle = None

Modified: CalendarServer/branches/users/gaya/directorybacker/txdav/base/datastore/subpostgres.py
===================================================================
--- CalendarServer/branches/users/gaya/directorybacker/txdav/base/datastore/subpostgres.py	2013-04-22 18:44:41 UTC (rev 11082)
+++ CalendarServer/branches/users/gaya/directorybacker/txdav/base/datastore/subpostgres.py	2013-04-22 18:46:28 UTC (rev 11083)
@@ -27,14 +27,12 @@
 from twisted.python.procutils import which
 from twisted.internet.protocol import ProcessProtocol
 
-from twisted.python.reflect import namedAny
 from twext.python.log import Logger
 from twext.python.filepath import CachingFilePath
 
-pgdb = namedAny("pgdb")
+import pgdb
 
 from twisted.protocols.basic import LineReceiver
-from twisted.internet import reactor
 from twisted.internet.defer import Deferred
 from txdav.base.datastore.dbapiclient import DBAPIConnector
 from txdav.base.datastore.dbapiclient import postgresPreflight
@@ -168,7 +166,8 @@
                  spawnedDBUser="caldav",
                  importFileName=None,
                  pgCtl="pg_ctl",
-                 initDB="initdb"):
+                 initDB="initdb",
+                 reactor=None):
         """
         Initialize a L{PostgresService} pointed at a data store directory.
 
@@ -194,6 +193,7 @@
         MultiService.__init__(self)
         self.subServiceFactory = subServiceFactory
         self.dataStoreDirectory = dataStoreDirectory
+        self.workingDir = self.dataStoreDirectory.child("working")
         self.resetSchema = resetSchema
 
         # In order to delay a shutdown until database initialization has
@@ -239,8 +239,16 @@
         self.openConnections = []
         self._pgCtl = pgCtl
         self._initdb = initDB
+        self._reactor = reactor
 
+    @property
+    def reactor(self):
+        if self._reactor is None:
+            from twisted.internet import reactor
+            self._reactor = reactor
+        return self._reactor
 
+
     def pgCtl(self):
         """
         Locate the path to pg_ctl.
@@ -300,17 +308,12 @@
         return self._connectorFor(databaseName).connect(label)
 
 
-    def ready(self):
+    def ready(self, createDatabaseConn, createDatabaseCursor):
         """
         Subprocess is ready.  Time to initialize the subservice.
         If the database has not been created and there is a dump file,
         then the dump file is imported.
         """
-        createDatabaseConn = self.produceConnection(
-            'schema creation', 'postgres'
-        )
-        createDatabaseCursor = createDatabaseConn.cursor()
-        createDatabaseCursor.execute("commit")
 
         if self.resetSchema:
             try:
@@ -347,9 +350,6 @@
             connection.commit()
             connection.close()
 
-        # TODO: anyone know why these two lines are here?
-        connection = self.produceConnection()
-        cursor = connection.cursor()
 
         if self.shutdownDeferred is None:
             # Only continue startup if we've not begun shutdown
@@ -383,6 +383,30 @@
         """
         Start the database and initialize the subservice.
         """
+
+        def createConnection():
+            createDatabaseConn = self.produceConnection(
+                'schema creation', 'postgres'
+            )
+            createDatabaseCursor = createDatabaseConn.cursor()
+            createDatabaseCursor.execute("commit")
+            return createDatabaseConn, createDatabaseCursor
+
+        try:
+            createDatabaseConn, createDatabaseCursor = createConnection()
+        except pgdb.DatabaseError:
+            # We could not connect the database, so attempt to start it
+            pass
+        except Exception, e:
+            # Some other unexpected error is preventing us from connecting
+            # to the database
+            log.warn("Failed to connect to Postgres: %s" % (str(e)))
+        else:
+            # Database is running, so just use our connection
+            self.ready(createDatabaseConn, createDatabaseCursor)
+            self.deactivateDelayedShutdown()
+            return
+
         monitor = _PostgresMonitor(self)
         pgCtl = self.pgCtl()
         # check consistency of initdb and postgres?
@@ -400,7 +424,7 @@
         options.append("-c standard_conforming_strings=on")
         options.extend(self.options)
 
-        reactor.spawnProcess(
+        self.reactor.spawnProcess(
             monitor, pgCtl,
             [
                 pgCtl,
@@ -412,13 +436,13 @@
                 "-o",
                 " ".join(options),
             ],
-            self.env,
+            env=self.env, path=self.workingDir.path,
             uid=self.uid, gid=self.gid,
         )
         self.monitor = monitor
         def gotReady(result):
             self.shouldStopDatabase = result
-            self.ready()
+            self.ready(*createConnection())
             self.deactivateDelayedShutdown()
         def reportit(f):
             log.err(f)
@@ -432,7 +456,6 @@
         MultiService.startService(self)
         self.activateDelayedShutdown()
         clusterDir = self.dataStoreDirectory.child("cluster")
-        workingDir = self.dataStoreDirectory.child("working")
         env = self.env = os.environ.copy()
         env.update(PGDATA=clusterDir.path,
                    PGHOST=self.host,
@@ -448,15 +471,16 @@
         else:
             if not self.dataStoreDirectory.isdir():
                 self.dataStoreDirectory.createDirectory()
-            if not workingDir.isdir():
-                workingDir.createDirectory()
+            if not self.workingDir.isdir():
+                self.workingDir.createDirectory()
             if self.uid and self.gid:
                 os.chown(self.dataStoreDirectory.path, self.uid, self.gid)
-                os.chown(workingDir.path, self.uid, self.gid)
+                os.chown(self.workingDir.path, self.uid, self.gid)
             dbInited = Deferred()
-            reactor.spawnProcess(
+            self.reactor.spawnProcess(
                 CapturingProcessProtocol(dbInited, None),
-                initdb, [initdb, "-E", "UTF8", "-U", self.spawnedDBUser], env, workingDir.path,
+                initdb, [initdb, "-E", "UTF8", "-U", self.spawnedDBUser],
+                env=env, path=self.workingDir.path,
                 uid=self.uid, gid=self.gid,
             )
             def doCreate(result):
@@ -486,9 +510,9 @@
             if self.shouldStopDatabase:
                 monitor = _PostgresMonitor()
                 pgCtl = self.pgCtl()
-                reactor.spawnProcess(monitor, pgCtl,
+                self.reactor.spawnProcess(monitor, pgCtl,
                     [pgCtl, '-l', 'logfile', 'stop'],
-                    self.env,
+                    env=self.env, path=self.workingDir.path,
                     uid=self.uid, gid=self.gid,
                 )
                 return monitor.completionDeferred

Modified: CalendarServer/branches/users/gaya/directorybacker/txdav/base/datastore/test/test_subpostgres.py
===================================================================
--- CalendarServer/branches/users/gaya/directorybacker/txdav/base/datastore/test/test_subpostgres.py	2013-04-22 18:44:41 UTC (rev 11082)
+++ CalendarServer/branches/users/gaya/directorybacker/txdav/base/datastore/test/test_subpostgres.py	2013-04-22 18:46:28 UTC (rev 11083)
@@ -20,12 +20,19 @@
 
 from twisted.trial.unittest import TestCase
 
+# NOTE: This import will fail eventuall when this functionality is added to 
+# MemoryReactor:
+from twisted.runner.test.test_procmon import DummyProcessReactor
+
+from twisted.python.filepath import FilePath
 from twext.python.filepath import CachingFilePath
 
 from txdav.base.datastore.subpostgres import PostgresService
 from twisted.internet.defer import inlineCallbacks, Deferred
 from twisted.application.service import Service
 
+import pgdb
+
 class SubprocessStartup(TestCase):
     """
     Tests for starting and stopping the subprocess.
@@ -185,3 +192,73 @@
         values = cursor.fetchall()
         self.assertEquals(values, [["value1"],["value2"]])
 
+    def test_startDatabaseRunning(self):
+        """ Ensure that if we can connect to postgres we don't spawn pg_ctl """
+
+        self.cursorHistory = []
+
+        class DummyCursor(object):
+            def __init__(self, historyHolder):
+                self.historyHolder = historyHolder 
+
+            def execute(self, *args):
+                self.historyHolder.cursorHistory.append(args)
+
+            def close(self):
+                pass
+
+        class DummyConnection(object):
+            def __init__(self, historyHolder):
+                self.historyHolder = historyHolder
+
+            def cursor(self):
+                return DummyCursor(self.historyHolder)
+
+            def commit(self):
+                pass
+
+            def close(self):
+                pass
+
+        def produceConnection(*args):
+            return DummyConnection(self)
+
+        dummyReactor = DummyProcessReactor()
+        svc = PostgresService(
+            FilePath("postgres_4.pgdb"),
+            lambda x : Service(),
+            "",
+             reactor=dummyReactor,
+        )
+        svc.produceConnection = produceConnection
+        svc.env = {}
+        svc.startDatabase()
+        self.assertEquals(
+            self.cursorHistory,
+            [
+                ('commit',),
+                ("create database subpostgres with encoding 'UTF8'",),
+                ('',)
+            ]
+        )
+        self.assertEquals(dummyReactor.spawnedProcesses, [])
+
+
+    def test_startDatabaseNotRunning(self):
+        """ Ensure that if we can't connect to postgres we spawn pg_ctl """
+
+        def produceConnection(*args):
+            raise pgdb.DatabaseError
+
+        dummyReactor = DummyProcessReactor()
+        svc = PostgresService(
+            FilePath("postgres_4.pgdb"),
+            lambda x : Service(),
+            "",
+             reactor=dummyReactor,
+        )
+        svc.produceConnection = produceConnection
+        svc.env = {}
+        svc.startDatabase()
+        self.assertEquals(len(dummyReactor.spawnedProcesses), 1)
+        self.assertTrue(dummyReactor.spawnedProcesses[0]._executable.endswith("pg_ctl"))

Modified: CalendarServer/branches/users/gaya/directorybacker/txdav/caldav/datastore/test/common.py
===================================================================
--- CalendarServer/branches/users/gaya/directorybacker/txdav/caldav/datastore/test/common.py	2013-04-22 18:44:41 UTC (rev 11082)
+++ CalendarServer/branches/users/gaya/directorybacker/txdav/caldav/datastore/test/common.py	2013-04-22 18:46:28 UTC (rev 11083)
@@ -536,7 +536,6 @@
         self.assertEquals(name, "/CalDAV/example.com/home1/")
 
 
-
     @inlineCallbacks
     def test_displayNameNone(self):
         """
@@ -1110,6 +1109,26 @@
 
 
     @inlineCallbacks
+    def test_sharedNotifierID(self):
+        yield self.test_shareWith()
+        yield self.commit()
+
+        home = yield self.homeUnderTest()
+        self.assertEquals(home.notifierID(), "CalDAV|home1")
+        calendar = yield home.calendarWithName("calendar_1")
+        self.assertEquals(calendar.notifierID(), "CalDAV|home1")
+        self.assertEquals(calendar.notifierID(label="collection"), "CalDAV|home1/calendar_1")
+        yield self.commit()
+
+        home = yield self.homeUnderTest(name=OTHER_HOME_UID)
+        self.assertEquals(home.notifierID(), "CalDAV|%s" % (OTHER_HOME_UID,))
+        calendar = yield home.calendarWithName(self.sharedName)
+        self.assertEquals(calendar.notifierID(), "CalDAV|home1")
+        self.assertEquals(calendar.notifierID(label="collection"), "CalDAV|home1/calendar_1")
+        yield self.commit()
+
+
+    @inlineCallbacks
     def test_hasCalendarResourceUIDSomewhereElse(self):
         """
         L{ICalendarHome.hasCalendarResourceUIDSomewhereElse} will determine if

Modified: CalendarServer/branches/users/gaya/directorybacker/txdav/caldav/datastore/test/test_file.py
===================================================================
--- CalendarServer/branches/users/gaya/directorybacker/txdav/caldav/datastore/test/test_file.py	2013-04-22 18:44:41 UTC (rev 11082)
+++ CalendarServer/branches/users/gaya/directorybacker/txdav/caldav/datastore/test/test_file.py	2013-04-22 18:46:28 UTC (rev 11083)
@@ -490,6 +490,7 @@
     test_asShared = test_shareWith
     test_unshareSharerSide = test_shareWith
     test_unshareShareeSide = test_shareWith
+    test_sharedNotifierID = test_shareWith
 
 
     def test_init(self):

Modified: CalendarServer/branches/users/gaya/directorybacker/txdav/common/datastore/file.py
===================================================================
--- CalendarServer/branches/users/gaya/directorybacker/txdav/common/datastore/file.py	2013-04-22 18:44:41 UTC (rev 11082)
+++ CalendarServer/branches/users/gaya/directorybacker/txdav/common/datastore/file.py	2013-04-22 18:46:28 UTC (rev 11083)
@@ -77,6 +77,14 @@
 )
 UIDPATH = "__uids__"
 
+
+
+class _StubQueuer(object):
+    def transferProposalCallbacks(self, otherQueuer):
+        return otherQueuer
+
+
+
 class CommonDataStore(DataStore):
     """
     Shared logic for SQL-based data stores, between calendar and addressbook
@@ -87,7 +95,6 @@
 
     @ivar quota: the amount of space granted to each calendar home (in bytes)
         for storing attachments, or C{None} if quota should not be enforced.
-
     @type quota: C{int} or C{NoneType}
 
     @ivar _propertyStoreClass: The class (or callable object / factory) that
@@ -95,6 +102,10 @@
         signature of the L{XattrPropertyStore} type: take 2 arguments
         C{(default-user-uid, path-factory)}, return an L{IPropertyStore}
         provider.
+
+    @ivar queuer: For compatibility with SQL-based store; currently a
+        non-functional implementation just for tests, but could be fixed to be
+        backed by SQLite or something.
     """
     implements(ICalendarStore)
 
@@ -118,6 +129,8 @@
         self._migrating = False
         self._enableNotifications = True
         self._newTransactionCallbacks = set()
+        # FIXME: see '@ivar queuer' above.
+        self.queuer = _StubQueuer()
 
     def callWithNewTransactions(self, callback):
         """

Modified: CalendarServer/branches/users/gaya/directorybacker/txdav/common/datastore/sql.py
===================================================================
--- CalendarServer/branches/users/gaya/directorybacker/txdav/common/datastore/sql.py	2013-04-22 18:44:41 UTC (rev 11082)
+++ CalendarServer/branches/users/gaya/directorybacker/txdav/common/datastore/sql.py	2013-04-22 18:46:28 UTC (rev 11083)
@@ -57,7 +57,7 @@
 from txdav.carddav.iaddressbookstore import IAddressBookTransaction
 
 from txdav.common.datastore.common import HomeChildBase
-from txdav.common.datastore.sql_tables import schema
+from txdav.common.datastore.sql_tables import schema, splitSQLString
 from txdav.common.datastore.sql_tables import _BIND_MODE_OWN, \
     _BIND_STATUS_ACCEPTED, _BIND_STATUS_DECLINED, \
     NOTIFICATION_OBJECT_REVISIONS_TABLE
@@ -71,7 +71,6 @@
 
 from twext.python.clsprop import classproperty
 from twext.enterprise.ienterprise import AlreadyFinishedError
-from twext.enterprise.dal.parseschema import significant
 
 from twext.enterprise.dal.syntax import \
     Delete, utcNowSQL, Union, Insert, Len, Max, Parameter, SavepointAction, \
@@ -94,7 +93,6 @@
 from pycalendar.datetime import PyCalendarDateTime
 
 from cStringIO import StringIO
-from sqlparse import parse
 import time
 
 current_sql_schema = getModule(__name__).filePath.sibling("sql_schema").child("current.sql").getContent()
@@ -1004,19 +1002,11 @@
     @inlineCallbacks
     def execSQLBlock(self, sql):
         """
-        Execute a block of SQL by parsing it out into individual statements and execute
-        each of those.
-
+        Execute SQL statements parsed by splitSQLString.
         FIXME: temporary measure for handling large schema upgrades. This should NOT be used
         for regular SQL operations - only upgrades.
         """
-        parsed = parse(sql)
-        for stmt in parsed:
-            while stmt.tokens and not significant(stmt.tokens[0]):
-                stmt.tokens.pop(0)
-            if not stmt.tokens:
-                continue
-            stmt = str(stmt).rstrip(";")
+        for stmt in splitSQLString(sql):
             yield self.execSQL(stmt)
 
 
@@ -2467,15 +2457,8 @@
     _objectTable = None
 
 
-    def __init__(self, home, name, resourceID, mode, status, message=None, ownerHome=None):
+    def __init__(self, home, name, resourceID, mode, status, message=None, ownerHome=None, ownerName=None):
 
-        if home._notifiers:
-            childID = "%s/%s" % (home.uid(), name)
-            notifiers = [notifier.clone(label="collection", id=childID)
-                         for notifier in home._notifiers]
-        else:
-            notifiers = None
-
         self._home = home
         self._name = name
         self._resourceID = resourceID
@@ -2483,12 +2466,24 @@
         self._bindStatus = status
         self._bindMessage = message
         self._ownerHome = home if ownerHome is None else ownerHome
+        self._ownerName = name if ownerName is None else ownerName
         self._created = None
         self._modified = None
         self._objects = {}
         self._objectNames = None
         self._syncTokenRevision = None
-        self._notifiers = notifiers
+
+        # Always use notifiers based off the owner home so that shared collections use tokens common
+        # to the owner - and thus will be the same for each sharee. Without that, each sharee would have
+        # a different token to subscribe to and thus would each need a separate push - whereas a common
+        # token only requires one push (to multiple subscribers).
+        if self._ownerHome._notifiers:
+            childID = "%s/%s" % (self._ownerHome.uid(), self._ownerName)
+            self._notifiers = [notifier.clone(label="collection", id=childID)
+                         for notifier in self._ownerHome._notifiers]
+        else:
+            self._notifiers = None
+
         self._index = None  # Derived classes need to set this
 
 
@@ -3000,17 +2995,18 @@
 
             if bindStatus == _BIND_MODE_OWN:
                 ownerHome = home
+                ownerName = resourceName
             else:
                 #TODO: get all ownerHomeIDs at once
-                ownerHomeID = (yield cls._ownerHomeWithResourceID.on(
-                                home._txn, resourceID=resourceID))[0][0]
+                ownerHomeID, ownerName = (yield cls._ownerHomeWithResourceID.on(home._txn, resourceID=resourceID))[0]
                 ownerHome = yield home._txn.homeWithResourceID(home._homeType, ownerHomeID)
 
             child = cls(
                 home=home,
                 name=resourceName, resourceID=resourceID,
                 mode=bindMode, status=bindStatus,
-                message=bindMessage, ownerHome=ownerHome
+                message=bindMessage,
+                ownerHome=ownerHome, ownerName=ownerName
             )
             for attr, value in zip(cls.metadataAttributes(), metadata):
                 setattr(child, attr, value)
@@ -3059,15 +3055,15 @@
         bindMode, homeID, resourceID, resourceName, bindStatus, bindMessage = rows[0] #@UnusedVariable
 
         #TODO:  combine with _invitedBindForNameAndHomeID and sort results
-        ownerHomeID = (yield cls._ownerHomeWithResourceID.on(
-                        home._txn, resourceID=resourceID))[0][0]
+        ownerHomeID, ownerName = (yield cls._ownerHomeWithResourceID.on(home._txn, resourceID=resourceID))[0]
         ownerHome = yield home._txn.homeWithResourceID(home._homeType, ownerHomeID)
 
         child = cls(
             home=home,
             name=resourceName, resourceID=resourceID,
             mode=bindMode, status=bindStatus,
-            message=bindMessage, ownerHome=ownerHome,
+            message=bindMessage,
+            ownerHome=ownerHome, ownerName=ownerName,
         )
         yield child.initFromStore()
         returnValue(child)
@@ -3114,10 +3110,12 @@
                 # get ownerHomeID
                 if bindMode == _BIND_MODE_OWN:
                     ownerHomeID = homeID
+                    ownerName = resourceName
                 else:
-                    ownerHomeID = (yield cls._ownerHomeWithResourceID.on(
-                                    home._txn, resourceID=resourceID))[0][0]
+                    ownerHomeID, ownerName = (yield cls._ownerHomeWithResourceID.on(
+                                    home._txn, resourceID=resourceID))[0]
                 rows[0].append(ownerHomeID)
+                rows[0].append(ownerName)
 
             if rows and queryCacher:
                 # Cache the result
@@ -3126,7 +3124,7 @@
         if not rows:
             returnValue(None)
 
-        bindMode, homeID, resourceID, resourceName, bindStatus, bindMessage, ownerHomeID = rows[0] #@UnusedVariable
+        bindMode, homeID, resourceID, resourceName, bindStatus, bindMessage, ownerHomeID, ownerName = rows[0] #@UnusedVariable
 
         if bindMode == _BIND_MODE_OWN:
             ownerHome = home
@@ -3137,7 +3135,8 @@
             home=home,
             name=name, resourceID=resourceID,
             mode=bindMode, status=bindStatus,
-            message=bindMessage, ownerHome=ownerHome,
+            message=bindMessage,
+            ownerHome=ownerHome, ownerName=ownerName,
         )
         yield child.initFromStore()
         returnValue(child)
@@ -3176,15 +3175,16 @@
 
         if bindMode == _BIND_MODE_OWN:
             ownerHome = home
+            ownerName = resourceName
         else:
-            ownerHomeID = (yield cls._ownerHomeWithResourceID.on(
-                            home._txn, resourceID=resourceID))[0][0]
+            ownerHomeID, ownerName = (yield cls._ownerHomeWithResourceID.on(home._txn, resourceID=resourceID))[0]
             ownerHome = yield home._txn.homeWithResourceID(home._homeType, ownerHomeID)
         child = cls(
             home=home,
             name=resourceName, resourceID=resourceID,
             mode=bindMode, status=bindStatus,
-            message=bindMessage, ownerHome=ownerHome,
+            message=bindMessage,
+            ownerHome=ownerHome, ownerName=ownerName,
         )
         yield child.initFromStore()
         returnValue(child)
@@ -3435,15 +3435,16 @@
     @classproperty
     def _ownerHomeWithResourceID(cls): #@NoSelf
         """
-        DAL query to retrieve the home resource ID of the owner from the bound
+        DAL query to retrieve the home resource ID and resource name of the owner from the bound
         home-child ID.
         """
         bind = cls._bindSchema
-        return Select([bind.HOME_RESOURCE_ID],
-                     From=bind,
-                     Where=(bind.RESOURCE_ID ==
-                            Parameter("resourceID")).And(
-                                bind.BIND_MODE == _BIND_MODE_OWN))
+        return Select(
+            [bind.HOME_RESOURCE_ID, bind.RESOURCE_NAME, ],
+            From=bind,
+            Where=(bind.RESOURCE_ID == Parameter("resourceID")).And(
+                bind.BIND_MODE == _BIND_MODE_OWN)
+        )
 
 
     @inlineCallbacks
@@ -3459,8 +3460,7 @@
             # we already know who the owner is.
             returnValue(self._home._resourceID)
         else:
-            rid = (yield self._ownerHomeWithResourceID.on(
-                self._txn, resourceID=self._resourceID))[0][0]
+            rid, _ignore_rname = (yield self._ownerHomeWithResourceID.on(self._txn, resourceID=self._resourceID))[0]
             returnValue(rid)
 
 

Modified: CalendarServer/branches/users/gaya/directorybacker/txdav/common/datastore/sql_schema/current-oracle-dialect.sql
===================================================================
--- CalendarServer/branches/users/gaya/directorybacker/txdav/common/datastore/sql_schema/current-oracle-dialect.sql	2013-04-22 18:44:41 UTC (rev 11082)
+++ CalendarServer/branches/users/gaya/directorybacker/txdav/common/datastore/sql_schema/current-oracle-dialect.sql	2013-04-22 18:46:28 UTC (rev 11083)
@@ -300,12 +300,17 @@
     "PUSH_ID" nvarchar2(255)
 );
 
+create table GROUP_CACHER_POLLING_WORK (
+    "WORK_ID" integer primary key not null,
+    "NOT_BEFORE" timestamp default CURRENT_TIMESTAMP at time zone 'UTC'
+);
+
 create table CALENDARSERVER (
     "NAME" nvarchar2(255) primary key,
     "VALUE" nvarchar2(255)
 );
 
-insert into CALENDARSERVER (NAME, VALUE) values ('VERSION', '17');
+insert into CALENDARSERVER (NAME, VALUE) values ('VERSION', '18');
 insert into CALENDARSERVER (NAME, VALUE) values ('CALENDAR-DATAVERSION', '3');
 insert into CALENDARSERVER (NAME, VALUE) values ('ADDRESSBOOK-DATAVERSION', '1');
 create index NOTIFICATION_NOTIFICA_f891f5f9 on NOTIFICATION (

Modified: CalendarServer/branches/users/gaya/directorybacker/txdav/common/datastore/sql_schema/current.sql
===================================================================
--- CalendarServer/branches/users/gaya/directorybacker/txdav/common/datastore/sql_schema/current.sql	2013-04-22 18:44:41 UTC (rev 11082)
+++ CalendarServer/branches/users/gaya/directorybacker/txdav/common/datastore/sql_schema/current.sql	2013-04-22 18:46:28 UTC (rev 11083)
@@ -557,7 +557,16 @@
   PUSH_ID                       varchar(255) not null
 );
 
+-----------------
+-- GroupCacher --
+-----------------
 
+create table GROUP_CACHER_POLLING_WORK (
+  WORK_ID                       integer primary key default nextval('WORKITEM_SEQ') not null,
+  NOT_BEFORE                    timestamp    default timezone('UTC', CURRENT_TIMESTAMP)
+);
+
+
 --------------------
 -- Schema Version --
 --------------------
@@ -567,6 +576,6 @@
   VALUE                         varchar(255)
 );
 
-insert into CALENDARSERVER values ('VERSION', '17');
+insert into CALENDARSERVER values ('VERSION', '18');
 insert into CALENDARSERVER values ('CALENDAR-DATAVERSION', '3');
 insert into CALENDARSERVER values ('ADDRESSBOOK-DATAVERSION', '1');

Modified: CalendarServer/branches/users/gaya/directorybacker/txdav/common/datastore/sql_schema/old/oracle-dialect/v14.sql
===================================================================
--- CalendarServer/branches/users/gaya/directorybacker/txdav/common/datastore/sql_schema/old/oracle-dialect/v14.sql	2013-04-22 18:44:41 UTC (rev 11082)
+++ CalendarServer/branches/users/gaya/directorybacker/txdav/common/datastore/sql_schema/old/oracle-dialect/v14.sql	2013-04-22 18:46:28 UTC (rev 11083)
@@ -54,7 +54,7 @@
 create table CALENDAR_BIND (
     "CALENDAR_HOME_RESOURCE_ID" integer not null references CALENDAR_HOME,
     "CALENDAR_RESOURCE_ID" integer not null references CALENDAR on delete cascade,
-    "CALENDAR_RESOURCE_NAME" nvarchar2(255) not null,
+    "CALENDAR_RESOURCE_NAME" nvarchar2(255),
     "BIND_MODE" integer not null,
     "BIND_STATUS" integer not null,
     "MESSAGE" nclob, 
@@ -203,7 +203,7 @@
 create table ADDRESSBOOK_BIND (
     "ADDRESSBOOK_HOME_RESOURCE_ID" integer not null references ADDRESSBOOK_HOME,
     "ADDRESSBOOK_RESOURCE_ID" integer not null references ADDRESSBOOK on delete cascade,
-    "ADDRESSBOOK_RESOURCE_NAME" nvarchar2(255) not null,
+    "ADDRESSBOOK_RESOURCE_NAME" nvarchar2(255),
     "BIND_MODE" integer not null,
     "BIND_STATUS" integer not null,
     "MESSAGE" nclob, 
@@ -268,7 +268,6 @@
 insert into CALENDARSERVER (NAME, VALUE) values ('VERSION', '14');
 insert into CALENDARSERVER (NAME, VALUE) values ('CALENDAR-DATAVERSION', '3');
 insert into CALENDARSERVER (NAME, VALUE) values ('ADDRESSBOOK-DATAVERSION', '1');
-
 create index NOTIFICATION_NOTIFICA_f891f5f9 on NOTIFICATION (
     NOTIFICATION_HOME_RESOURCE_ID
 );

Modified: CalendarServer/branches/users/gaya/directorybacker/txdav/common/datastore/sql_schema/old/oracle-dialect/v15.sql
===================================================================
--- CalendarServer/branches/users/gaya/directorybacker/txdav/common/datastore/sql_schema/old/oracle-dialect/v15.sql	2013-04-22 18:44:41 UTC (rev 11082)
+++ CalendarServer/branches/users/gaya/directorybacker/txdav/common/datastore/sql_schema/old/oracle-dialect/v15.sql	2013-04-22 18:46:28 UTC (rev 11083)
@@ -58,7 +58,7 @@
 create table CALENDAR_BIND (
     "CALENDAR_HOME_RESOURCE_ID" integer not null references CALENDAR_HOME,
     "CALENDAR_RESOURCE_ID" integer not null references CALENDAR on delete cascade,
-    "CALENDAR_RESOURCE_NAME" nvarchar2(255) not null,
+    "CALENDAR_RESOURCE_NAME" nvarchar2(255),
     "BIND_MODE" integer not null,
     "BIND_STATUS" integer not null,
     "MESSAGE" nclob, 
@@ -207,7 +207,7 @@
 create table ADDRESSBOOK_BIND (
     "ADDRESSBOOK_HOME_RESOURCE_ID" integer not null references ADDRESSBOOK_HOME,
     "ADDRESSBOOK_RESOURCE_ID" integer not null references ADDRESSBOOK on delete cascade,
-    "ADDRESSBOOK_RESOURCE_NAME" nvarchar2(255) not null,
+    "ADDRESSBOOK_RESOURCE_NAME" nvarchar2(255),
     "BIND_MODE" integer not null,
     "BIND_STATUS" integer not null,
     "MESSAGE" nclob, 
@@ -272,7 +272,6 @@
 insert into CALENDARSERVER (NAME, VALUE) values ('VERSION', '15');
 insert into CALENDARSERVER (NAME, VALUE) values ('CALENDAR-DATAVERSION', '3');
 insert into CALENDARSERVER (NAME, VALUE) values ('ADDRESSBOOK-DATAVERSION', '1');
-
 create index NOTIFICATION_NOTIFICA_f891f5f9 on NOTIFICATION (
     NOTIFICATION_HOME_RESOURCE_ID
 );

Modified: CalendarServer/branches/users/gaya/directorybacker/txdav/common/datastore/sql_schema/upgrades/oracle-dialect/upgrade_from_13_to_14.sql
===================================================================
--- CalendarServer/branches/users/gaya/directorybacker/txdav/common/datastore/sql_schema/upgrades/oracle-dialect/upgrade_from_13_to_14.sql	2013-04-22 18:44:41 UTC (rev 11082)
+++ CalendarServer/branches/users/gaya/directorybacker/txdav/common/datastore/sql_schema/upgrades/oracle-dialect/upgrade_from_13_to_14.sql	2013-04-22 18:46:28 UTC (rev 11083)
@@ -26,15 +26,11 @@
  drop column SEEN_BY_OWNER;
 alter table CALENDAR_BIND
  drop column SEEN_BY_SHAREE;
-alter table CALENDAR_BIND
- modify (CALENDAR_RESOURCE_NAME not null);
  
 alter table ADDRESSBOOK_BIND
  drop column SEEN_BY_OWNER;
 alter table ADDRESSBOOK_BIND
  drop column SEEN_BY_SHAREE;
-alter table ADDRESSBOOK_BIND
- modify (ADDRESSBOOK_RESOURCE_NAME not null);
 
 -- Now update the version
 -- No data upgrades

Modified: CalendarServer/branches/users/gaya/directorybacker/txdav/common/datastore/sql_schema/upgrades/oracle-dialect/upgrade_from_16_to_17.sql
===================================================================
--- CalendarServer/branches/users/gaya/directorybacker/txdav/common/datastore/sql_schema/upgrades/oracle-dialect/upgrade_from_16_to_17.sql	2013-04-22 18:44:41 UTC (rev 11082)
+++ CalendarServer/branches/users/gaya/directorybacker/txdav/common/datastore/sql_schema/upgrades/oracle-dialect/upgrade_from_16_to_17.sql	2013-04-22 18:46:28 UTC (rev 11083)
@@ -23,6 +23,13 @@
 -- CALENDAR_OBJECT clean-up --
 ------------------------------
 
+begin
+for i in (select constraint_name from user_cons_columns where column_name = 'ORGANIZER_OBJECT')
+loop
+execute immediate 'alter table calendar_object drop constraint ' || i.constraint_name;
+end loop;
+end;
+
 alter table CALENDAR_OBJECT
  drop (ORGANIZER_OBJECT);
 

Modified: CalendarServer/branches/users/gaya/directorybacker/txdav/common/datastore/sql_tables.py
===================================================================
--- CalendarServer/branches/users/gaya/directorybacker/txdav/common/datastore/sql_tables.py	2013-04-22 18:44:41 UTC (rev 11082)
+++ CalendarServer/branches/users/gaya/directorybacker/txdav/common/datastore/sql_tables.py	2013-04-22 18:46:28 UTC (rev 11083)
@@ -27,8 +27,9 @@
 from twext.enterprise.ienterprise import ORACLE_DIALECT, POSTGRES_DIALECT
 from twext.enterprise.dal.syntax import Insert
 from twext.enterprise.ienterprise import ORACLE_TABLE_NAME_MAX
-from twext.enterprise.dal.parseschema import schemaFromPath
-
+from twext.enterprise.dal.parseschema import schemaFromPath, significant
+from sqlparse import parse
+from re import compile
 import hashlib
 
 
@@ -384,6 +385,43 @@
         out.write('\n);\n\n')
 
 
+def splitSQLString(sqlString):
+    """
+    Strings which mix zero or more sql statements with zero or more pl/sql
+    statements need to be split into individual sql statements for execution.
+    This function was written to allow execution of pl/sql during Oracle schema
+    upgrades.
+    """
+    aggregated = ''
+    inPlSQL = None
+    parsed = parse(sqlString)
+    for stmt in parsed:
+        while stmt.tokens and not significant(stmt.tokens[0]):
+            stmt.tokens.pop(0)
+        if not stmt.tokens:
+            continue
+        if inPlSQL is not None:
+            agg = str(stmt).strip()
+            if "end;".lower() in agg.lower():
+                inPlSQL = None
+                aggregated += agg
+                rex = compile("\n +")
+                aggregated = rex.sub('\n', aggregated)
+                yield aggregated.strip()
+                continue
+            aggregated += agg
+            continue
+        if inPlSQL is None:
+            #if 'begin'.lower() in str(stmt).split()[0].lower():
+            if 'begin'.lower() in str(stmt).lower():
+                inPlSQL = True
+                aggregated += str(stmt)
+                continue
+        else:
+            continue
+        yield str(stmt).rstrip().rstrip(";")
+
+
 if __name__ == '__main__':
     import sys
     if len(sys.argv) == 2:

Modified: CalendarServer/branches/users/gaya/directorybacker/txdav/common/datastore/test/test_sql_tables.py
===================================================================
--- CalendarServer/branches/users/gaya/directorybacker/txdav/common/datastore/test/test_sql_tables.py	2013-04-22 18:44:41 UTC (rev 11082)
+++ CalendarServer/branches/users/gaya/directorybacker/txdav/common/datastore/test/test_sql_tables.py	2013-04-22 18:46:28 UTC (rev 11083)
@@ -31,10 +31,12 @@
 from twext.enterprise.dal.syntax import SchemaSyntax
 
 from txdav.common.datastore.sql_tables import schema, _translateSchema
-from txdav.common.datastore.sql_tables import SchemaBroken
+from txdav.common.datastore.sql_tables import SchemaBroken, splitSQLString
 
 from twext.enterprise.dal.test.test_parseschema import SchemaTestHelper
 
+from textwrap import dedent
+
 class SampleSomeColumns(TestCase, SchemaTestHelper):
     """
     Sample some columns from the tables defined by L{schema} and verify that
@@ -268,3 +270,175 @@
 
 
 
+class SQLSplitterTests(TestCase):
+    """
+    Test that strings which mix zero or more sql statements with zero or more
+    pl/sql statements are split into individual statements.
+    """
+
+    def test_dontSplitOneStatement(self):
+        """
+        A single sql statement yields a single string
+        """
+        result = splitSQLString("select * from foo;")
+        r1 = result.next()
+        self.assertEquals(r1, "select * from foo")
+        self.assertRaises(StopIteration, result.next)
+
+
+    def test_returnTwoSimpleStatements(self):
+        """
+        Two simple sql statements yield two separate strings
+        """
+        result = splitSQLString("select count(*) from baz; select bang from boop;")
+        r1 = result.next()
+        self.assertEquals(r1, "select count(*) from baz")
+        r2 = result.next()
+        self.assertEquals(r2, "select bang from boop")
+        self.assertRaises(StopIteration, result.next)
+        
+
+    def test_returnOneComplexStatement(self):
+        """
+        One complex sql statement yields a single string
+        """
+        bigSQL = dedent(
+        '''SELECT
+              CL.CODE,
+              CL.CATEGORY,
+           FROM
+              CLIENTS_SUPPLIERS CL
+              INVOICES I
+           WHERE
+              CL.CODE = I.CODE AND
+              CL.CATEGORY = I.CATEGORY AND
+              CL.UP_DATE = 
+                (SELECT
+                   MAX(CL2.UP_DATE)
+                 FROM
+                   CLIENTS_SUPPLIERS CL2
+                 WHERE
+                   CL2.CODE = I.CODE AND
+                   CL2.CATEGORY = I.CATEGORY AND
+                   CL2.UP_DATE <= I.EMISSION
+                ) AND
+                I.EMISSION BETWEEN DATE1 AND DATE2;''')
+        result = splitSQLString(bigSQL)
+        r1 = result.next()
+        self.assertEquals(r1, bigSQL.rstrip(";")) 
+        self.assertRaises(StopIteration, result.next)
+
+
+    def test_returnOnePlSQL(self):
+        """
+        One pl/sql block yields a single string
+        """
+        plsql = dedent(
+        '''BEGIN
+           LOOP
+               INSERT INTO T1 VALUES(i,i);
+               i := i+1;
+               EXIT WHEN i>100;
+           END LOOP;
+           END;''')
+        s1 = 'BEGIN\nLOOP\nINSERT INTO T1 VALUES(i,i);i := i+1;EXIT WHEN i>100;END LOOP;END;'
+        result = splitSQLString(plsql)
+        r1 = result.next()
+        self.assertEquals(r1, s1)
+        self.assertRaises(StopIteration, result.next)
+
+
+    def test_returnOnePlSQLAndOneSQL(self):
+        """
+        One sql statement and one pl/sql statement yields two separate strings
+        """
+        sql = dedent(
+        '''SELECT EGM.Name, BioEntity.BioEntityId INTO AUX
+            FROM EGM 
+            INNER JOIN BioEntity 
+                ON EGM.name LIKE BioEntity.Name AND EGM.TypeId = BioEntity.TypeId
+            OPTION (MERGE JOIN);''')
+        plsql = dedent(
+        '''BEGIN
+           FOR i IN 1..10 LOOP
+               IF MOD(i,2) = 0 THEN
+                   INSERT INTO temp VALUES (i, x, 'i is even');
+               ELSE
+                   INSERT INTO temp VALUES (i, x, 'i is odd');
+               END IF;
+               x := x + 100;
+           END LOOP;
+           COMMIT;
+           END;''')
+        s2 = "BEGIN\nFOR i IN 1..10 LOOP\nIF MOD(i,2) = 0 THEN\nINSERT INTO temp VALUES (i, x, 'i is even');ELSE\nINSERT INTO temp VALUES (i, x, 'i is odd');END IF;x := x + 100;END LOOP;COMMIT;END;"
+        result = splitSQLString(sql+plsql)
+        r1 = result.next()
+        self.assertEquals(r1, sql.rstrip(";"))
+        r2 = result.next()
+        self.assertEquals(r2, s2)
+        self.assertRaises(StopIteration, result.next)
+
+    def test_actualSchemaUpgrade(self):
+        """
+        A real-world schema upgrade is split into the expected number of statements,
+        ignoring comments
+        """
+        realsql = dedent(
+        '''
+        ----
+        -- Copyright (c) 2011-2013 Apple Inc. All rights reserved.
+        --
+        -- Licensed under the Apache License, Version 2.0 (the "License");
+        -- you may not use this file except in compliance with the License.
+        -- You may obtain a copy of the License at
+        --
+        -- http://www.apache.org/licenses/LICENSE-2.0
+        --
+        -- Unless required by applicable law or agreed to in writing, software
+        -- distributed under the License is distributed on an "AS IS" BASIS,
+        -- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+        -- See the License for the specific language governing permissions and
+        -- limitations under the License.
+        ----
+
+        ---------------------------------------------------
+        -- Upgrade database schema from VERSION 16 to 17 --
+        ---------------------------------------------------
+
+
+        ------------------------------
+        -- CALENDAR_OBJECT clean-up --
+        ------------------------------
+
+        begin
+        for i in (select constraint_name from user_cons_columns where column_name = 'ORGANIZER_OBJECT')
+        loop
+        execute immediate 'alter table calendar_object drop constraint ' || i.constraint_name;
+        end loop;
+        end;
+
+        alter table CALENDAR_OBJECT
+         drop (ORGANIZER_OBJECT);
+
+        create index CALENDAR_OBJECT_ICALE_82e731d5 on CALENDAR_OBJECT (
+            ICALENDAR_UID
+        );
+
+
+        -- Now update the version
+        update CALENDARSERVER set VALUE = '17' where NAME = 'VERSION';
+        ''')
+        s1 = "begin\nfor i in (select constraint_name from user_cons_columns where column_name = 'ORGANIZER_OBJECT')\nloop\nexecute immediate 'alter table calendar_object drop constraint ' || i.constraint_name;end loop;end;"
+        s2 = 'alter table CALENDAR_OBJECT\n drop (ORGANIZER_OBJECT)'
+        s3 = 'create index CALENDAR_OBJECT_ICALE_82e731d5 on CALENDAR_OBJECT (\n    ICALENDAR_UID\n)'
+        s4 = "update CALENDARSERVER set VALUE = '17' where NAME = 'VERSION'"
+        result = splitSQLString(realsql)
+        r1 = result.next()
+        self.assertEquals(r1, s1)
+        r2 = result.next()
+        self.assertEquals(r2, s2)
+        r3 = result.next()
+        self.assertEquals(r3, s3)
+        r4 = result.next()
+        self.assertEquals(r4, s4)
+        self.assertRaises(StopIteration, result.next)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20130422/f758078e/attachment-0001.html>


More information about the calendarserver-changes mailing list