[CalendarServer-changes] [5062] CalendarServer/trunk

source_changes at macosforge.org source_changes at macosforge.org
Mon Feb 8 15:05:01 PST 2010


Revision: 5062
          http://trac.macosforge.org/projects/calendarserver/changeset/5062
Author:   sagen at apple.com
Date:     2010-02-08 15:05:01 -0800 (Mon, 08 Feb 2010)
Log Message:
-----------
Landing branch with locations/resources coming from separate service

Modified Paths:
--------------
    CalendarServer/trunk/calendarserver/tap/caldav.py
    CalendarServer/trunk/calendarserver/tools/principals.py
    CalendarServer/trunk/calendarserver/tools/util.py
    CalendarServer/trunk/conf/auth/accounts-test.xml
    CalendarServer/trunk/conf/caldavd-apple.plist
    CalendarServer/trunk/conf/caldavd-test.plist
    CalendarServer/trunk/python
    CalendarServer/trunk/setup.py
    CalendarServer/trunk/twistedcaldav/directory/aggregate.py
    CalendarServer/trunk/twistedcaldav/directory/appleopendirectory.py
    CalendarServer/trunk/twistedcaldav/directory/cachingdirectory.py
    CalendarServer/trunk/twistedcaldav/directory/directory.py
    CalendarServer/trunk/twistedcaldav/directory/test/accounts.xml
    CalendarServer/trunk/twistedcaldav/directory/test/test_aggregate.py
    CalendarServer/trunk/twistedcaldav/directory/test/test_cachedirectory.py
    CalendarServer/trunk/twistedcaldav/directory/test/test_opendirectory.py
    CalendarServer/trunk/twistedcaldav/directory/test/test_xmlfile.py
    CalendarServer/trunk/twistedcaldav/directory/xmlfile.py
    CalendarServer/trunk/twistedcaldav/stdconfig.py

Added Paths:
-----------
    CalendarServer/trunk/bin/calendarserver_command_gateway
    CalendarServer/trunk/calendarserver/tools/gateway.py
    CalendarServer/trunk/calendarserver/tools/test/
    CalendarServer/trunk/calendarserver/tools/test/__init__.py
    CalendarServer/trunk/calendarserver/tools/test/gateway/
    CalendarServer/trunk/calendarserver/tools/test/gateway/augments.xml
    CalendarServer/trunk/calendarserver/tools/test/gateway/caldavd.plist
    CalendarServer/trunk/calendarserver/tools/test/gateway/resources-locations.xml
    CalendarServer/trunk/calendarserver/tools/test/gateway/users-groups.xml
    CalendarServer/trunk/calendarserver/tools/test/test_gateway.py
    CalendarServer/trunk/conf/auth/resources-test.xml
    CalendarServer/trunk/conf/resources/
    CalendarServer/trunk/conf/resources/caldavd-resources.plist
    CalendarServer/trunk/conf/resources/locations-resources-orig.xml
    CalendarServer/trunk/conf/resources/locations-resources.xml
    CalendarServer/trunk/conf/resources/users-groups.xml
    CalendarServer/trunk/conf/resources.xml
    CalendarServer/trunk/twistedcaldav/directory/test/modify/
    CalendarServer/trunk/twistedcaldav/directory/test/modify/augments.xml
    CalendarServer/trunk/twistedcaldav/directory/test/modify/caldavd.plist
    CalendarServer/trunk/twistedcaldav/directory/test/modify/resources-locations.xml
    CalendarServer/trunk/twistedcaldav/directory/test/modify/users-groups.xml
    CalendarServer/trunk/twistedcaldav/directory/test/resources/
    CalendarServer/trunk/twistedcaldav/directory/test/resources/augments.xml
    CalendarServer/trunk/twistedcaldav/directory/test/resources/caldavd.plist
    CalendarServer/trunk/twistedcaldav/directory/test/resources/resources-locations.xml
    CalendarServer/trunk/twistedcaldav/directory/test/resources/users-groups.xml
    CalendarServer/trunk/twistedcaldav/directory/test/test_modify.py
    CalendarServer/trunk/twistedcaldav/directory/test/test_resources.py

Removed Paths:
-------------
    CalendarServer/trunk/calendarserver/tools/test/__init__.py
    CalendarServer/trunk/calendarserver/tools/test/gateway/
    CalendarServer/trunk/calendarserver/tools/test/gateway/augments.xml
    CalendarServer/trunk/calendarserver/tools/test/gateway/caldavd.plist
    CalendarServer/trunk/calendarserver/tools/test/gateway/resources-locations.xml
    CalendarServer/trunk/calendarserver/tools/test/gateway/users-groups.xml
    CalendarServer/trunk/calendarserver/tools/test/test_gateway.py
    CalendarServer/trunk/conf/resources/caldavd-resources.plist
    CalendarServer/trunk/conf/resources/locations-resources-orig.xml
    CalendarServer/trunk/conf/resources/locations-resources.xml
    CalendarServer/trunk/conf/resources/users-groups.xml
    CalendarServer/trunk/twistedcaldav/directory/test/modify/augments.xml
    CalendarServer/trunk/twistedcaldav/directory/test/modify/caldavd.plist
    CalendarServer/trunk/twistedcaldav/directory/test/modify/resources-locations.xml
    CalendarServer/trunk/twistedcaldav/directory/test/modify/users-groups.xml
    CalendarServer/trunk/twistedcaldav/directory/test/resources/augments.xml
    CalendarServer/trunk/twistedcaldav/directory/test/resources/caldavd.plist
    CalendarServer/trunk/twistedcaldav/directory/test/resources/resources-locations.xml
    CalendarServer/trunk/twistedcaldav/directory/test/resources/users-groups.xml

Property Changed:
----------------
    CalendarServer/trunk/


Property changes on: CalendarServer/trunk
___________________________________________________________________
Modified: svn:mergeinfo
   - /CalendarServer/branches/config-separation:4379-4443
/CalendarServer/branches/egg-info-351:4589-4625
/CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627:3628-3644
/CalendarServer/branches/users/cdaboo/partition-4464:4465-4957
/CalendarServer/branches/users/sagen/resource-delegates-4038:4040-4067
/CalendarServer/branches/users/sagen/resource-delegates-4066:4068-4075
   + /CalendarServer/branches/config-separation:4379-4443
/CalendarServer/branches/egg-info-351:4589-4625
/CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627:3628-3644
/CalendarServer/branches/users/cdaboo/partition-4464:4465-4957
/CalendarServer/branches/users/sagen/locations-resources:5032-5051
/CalendarServer/branches/users/sagen/locations-resources-2:5052-5061
/CalendarServer/branches/users/sagen/resource-delegates-4038:4040-4067
/CalendarServer/branches/users/sagen/resource-delegates-4066:4068-4075

Copied: CalendarServer/trunk/bin/calendarserver_command_gateway (from rev 5061, CalendarServer/branches/users/sagen/locations-resources-2/bin/calendarserver_command_gateway)
===================================================================
--- CalendarServer/trunk/bin/calendarserver_command_gateway	                        (rev 0)
+++ CalendarServer/trunk/bin/calendarserver_command_gateway	2010-02-08 23:05:01 UTC (rev 5062)
@@ -0,0 +1,44 @@
+#!/usr/bin/env python
+
+##
+# Copyright (c) 2006-2010 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 sys
+
+#PYTHONPATH
+
+if __name__ == "__main__":
+    if "PYTHONPATH" in globals():
+        sys.path.insert(0, PYTHONPATH)
+    else:
+        from os.path import dirname, abspath, join
+        from subprocess import Popen, PIPE
+
+        home = dirname(dirname(abspath(__file__)))
+        run = join(home, "run")
+
+        child = Popen((run, "-p"), stdout=PIPE)
+        path, stderr = child.communicate()
+
+        path = path.rstrip("\n")
+
+        if child.wait() == 0:
+            sys.path[0:0] = path.split(":")
+
+        sys.argv[1:1] = ["-f", join(home, "conf", "caldavd-dev.plist")]
+
+    from calendarserver.tools.gateway import main
+    main()

Modified: CalendarServer/trunk/calendarserver/tap/caldav.py
===================================================================
--- CalendarServer/trunk/calendarserver/tap/caldav.py	2010-02-08 22:31:59 UTC (rev 5061)
+++ CalendarServer/trunk/calendarserver/tap/caldav.py	2010-02-08 23:05:01 UTC (rev 5062)
@@ -487,6 +487,20 @@
 
         directories.append(baseDirectory)
 
+        #
+        # Setup the Locations and Resources Service
+        #
+        if config.ResourceService.Enabled:
+            resourceClass = namedClass(config.ResourceService.type)
+
+            self.log_info("Configuring resource service of type: %s" % (resourceClass,))
+
+            resourceDirectory = resourceClass(config.ResourceService.params)
+            directories.append(resourceDirectory)
+
+        #
+        # Add sudoers directory
+        #
         sudoDirectory = None
 
         if config.SudoersFile and os.path.exists(config.SudoersFile):
@@ -1083,6 +1097,8 @@
         
                 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)
         

Copied: CalendarServer/trunk/calendarserver/tools/gateway.py (from rev 5061, CalendarServer/branches/users/sagen/locations-resources-2/calendarserver/tools/gateway.py)
===================================================================
--- CalendarServer/trunk/calendarserver/tools/gateway.py	                        (rev 0)
+++ CalendarServer/trunk/calendarserver/tools/gateway.py	2010-02-08 23:05:01 UTC (rev 5062)
@@ -0,0 +1,297 @@
+#!/usr/bin/env python
+
+##
+# Copyright (c) 2006-2010 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 getopt import getopt, GetoptError
+from grp import getgrnam
+from pwd import getpwnam
+import os
+import plistlib
+import sys
+import xml
+
+from twisted.internet import reactor
+from twisted.internet.defer import inlineCallbacks
+from twisted.python.util import switchUID
+from twistedcaldav.config import config, ConfigurationError
+from twistedcaldav.directory.directory import DirectoryError
+from twisted.web2.dav import davxml
+
+from calendarserver.tools.util import loadConfig, getDirectory, setupMemcached, setupNotifications
+from calendarserver.tools.principals import principalForPrincipalID, proxySubprincipal, addProxy, removeProxy, ProxyError, ProxyWarning
+
+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 "  -f --config <path>: Specify caldavd.plist configuration path"
+    print ""
+
+    if e:
+        sys.exit(64)
+    else:
+        sys.exit(0)
+
+
+def main():
+
+    try:
+        (optargs, args) = getopt(
+            sys.argv[1:], "hf:", [
+                "help",
+                "config=",
+            ],
+        )
+    except GetoptError, e:
+        usage(e)
+
+    #
+    # Get configuration
+    #
+    configFileName = None
+
+    for opt, arg in optargs:
+        if opt in ("-h", "--help"):
+            usage()
+
+        elif opt in ("-f", "--config"):
+            configFileName = arg
+
+        else:
+            raise NotImplementedError(opt)
+
+    try:
+        loadConfig(configFileName)
+
+        # 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)
+
+        try:
+            config.directory = getDirectory()
+        except DirectoryError, e:
+            abort(e)
+        setupMemcached(config)
+        setupNotifications(config)
+    except ConfigurationError, e:
+        abort(e)
+
+    #
+    # Read commands from stdin
+    #
+    rawInput = sys.stdin.read()
+    try:
+        plist = plistlib.readPlistFromString(rawInput)
+    except xml.parsers.expat.ExpatError, e:
+        abort(str(e))
+
+    # If the plist is an array, each element of the array is a separate
+    # command dictionary.
+    if isinstance(plist, list):
+        commands = plist
+    else:
+        commands = [plist]
+
+    runner = Runner(config.directory, commands)
+    runner.validate()
+
+    #
+    # Start the reactor
+    #
+    reactor.callLater(0, runner.run)
+    reactor.run()
+
+
+class Runner(object):
+
+    def __init__(self, directory, commands):
+        self.dir = directory
+        self.commands = commands
+
+    def validate(self):
+        # Make sure commands are valid
+        for command in self.commands:
+            if not command.has_key('command'):
+                abort("'command' missing from plist")
+            commandName = command['command']
+            methodName = "command_%s" % (commandName,)
+            if not hasattr(self, methodName):
+                abort("Unknown command '%s'" % (commandName,))
+
+    @inlineCallbacks
+    def run(self):
+        for command in self.commands:
+            commandName = command['command']
+            methodName = "command_%s" % (commandName,)
+            if hasattr(self, methodName):
+                (yield getattr(self, methodName)(command))
+            else:
+                abort("Unknown command '%s'" % (commandName,))
+
+        reactor.stop()
+
+    # Locations
+
+    def command_getLocationList(self, command):
+        respondWithRecordsOfType(self.dir, command, "locations")
+
+    def command_createLocation(self, command):
+
+        try:
+            self.dir.createRecord("locations", guid=command['GeneratedUID'],
+                shortNames=command['RecordName'], fullName=command['RealName'])
+        except DirectoryError, e:
+            abort(str(e))
+        respondWithRecordsOfType(self.dir, command, "locations")
+
+    def command_deleteLocation(self, command):
+        try:
+            self.dir.destroyRecord("locations", guid=command['GeneratedUID'])
+        except DirectoryError, e:
+            abort(str(e))
+        respondWithRecordsOfType(self.dir, command, "locations")
+
+    # Resources
+
+    def command_getResourceList(self, command):
+        respondWithRecordsOfType(self.dir, command, "resources")
+
+    def command_createResource(self, command):
+        try:
+            self.dir.createRecord("resources", guid=command['GeneratedUID'],
+                shortNames=command['RecordName'], fullName=command['RealName'])
+        except DirectoryError, e:
+            abort(str(e))
+        respondWithRecordsOfType(self.dir, command, "resources")
+
+    def command_deleteResource(self, command):
+        try:
+            self.dir.destroyRecord("resources", guid=command['GeneratedUID'])
+        except DirectoryError, e:
+            abort(str(e))
+        respondWithRecordsOfType(self.dir, command, "resources")
+
+    # Proxies
+
+    @inlineCallbacks
+    def command_listWriteProxies(self, command):
+        principal = principalForPrincipalID(command['Principal'], directory=self.dir)
+        (yield respondWithProxies(self.dir, command, principal, "write"))
+
+    @inlineCallbacks
+    def command_addWriteProxy(self, command):
+        principal = principalForPrincipalID(command['Principal'], directory=self.dir)
+        proxy = principalForPrincipalID(command['Proxy'], directory=self.dir)
+        try:
+            (yield addProxy(principal, "write", proxy))
+        except ProxyError, e:
+            abort(str(e))
+        except ProxyWarning, e:
+            pass
+        (yield respondWithProxies(self.dir, command, principal, "write"))
+
+    @inlineCallbacks
+    def command_removeWriteProxy(self, command):
+        principal = principalForPrincipalID(command['Principal'], directory=self.dir)
+        proxy = principalForPrincipalID(command['Proxy'], directory=self.dir)
+        try:
+            (yield removeProxy(principal, proxy, proxyTypes=("write",)))
+        except ProxyError, e:
+            abort(str(e))
+        except ProxyWarning, e:
+            pass
+        (yield respondWithProxies(self.dir, command, principal, "write"))
+
+    @inlineCallbacks
+    def command_listReadProxies(self, command):
+        principal = principalForPrincipalID(command['Principal'], directory=self.dir)
+        (yield respondWithProxies(self.dir, command, principal, "read"))
+
+    @inlineCallbacks
+    def command_addReadProxy(self, command):
+        principal = principalForPrincipalID(command['Principal'], directory=self.dir)
+        proxy = principalForPrincipalID(command['Proxy'], directory=self.dir)
+        try:
+            (yield addProxy(principal, "read", proxy))
+        except ProxyError, e:
+            abort(str(e))
+        except ProxyWarning, e:
+            pass
+        (yield respondWithProxies(self.dir, command, principal, "read"))
+
+    @inlineCallbacks
+    def command_removeReadProxy(self, command):
+        principal = principalForPrincipalID(command['Principal'], directory=self.dir)
+        proxy = principalForPrincipalID(command['Proxy'], directory=self.dir)
+        try:
+            (yield removeProxy(principal, proxy, proxyTypes=("read",)))
+        except ProxyError, e:
+            abort(str(e))
+        except ProxyWarning, e:
+            pass
+        (yield respondWithProxies(self.dir, command, principal, "read"))
+
+
+ at inlineCallbacks
+def respondWithProxies(directory, command, principal, proxyType):
+    proxies = []
+    subPrincipal = proxySubprincipal(principal, proxyType)
+    if subPrincipal is not None:
+        membersProperty = (yield subPrincipal.readProperty(davxml.GroupMemberSet, None))
+        if membersProperty.children:
+            for member in membersProperty.children:
+                proxyPrincipal = principalForPrincipalID(str(member))
+                proxies.append(proxyPrincipal.record.guid)
+
+    respond(command, {
+        'Principal' : principal.record.guid, 'Proxies' : proxies
+    })
+
+
+def respondWithRecordsOfType(directory, command, recordType):
+    result = []
+    for record in directory.listRecords(recordType):
+        result.append( {
+            'GeneratedUID' : record.guid,
+            'RecordName' : [n for n in record.shortNames],
+            'RealName' : record.fullName,
+            'AutoSchedule' : record.autoSchedule,
+        } )
+    respond(command, result)
+
+def respond(command, result):
+    sys.stdout.write(plistlib.writePlistToString( { 'command' : command['command'], 'result' : result } ) )
+
+def abort(msg, status=1):
+    sys.stdout.write(plistlib.writePlistToString( { 'error' : msg, } ) )
+    try:
+        reactor.stop()
+    except RuntimeError:
+        pass
+    sys.exit(status)
+
+if __name__ == "__main__":
+    main()

Modified: CalendarServer/trunk/calendarserver/tools/principals.py
===================================================================
--- CalendarServer/trunk/calendarserver/tools/principals.py	2010-02-08 22:31:59 UTC (rev 5061)
+++ CalendarServer/trunk/calendarserver/tools/principals.py	2010-02-08 23:05:01 UTC (rev 5062)
@@ -33,15 +33,10 @@
 from twext.python.log import StandardIOObserver
 from twext.web2.dav.davxml import sname2qname, qname2sname
 
-from twistedcaldav import memcachepool
 from twistedcaldav.config import config, ConfigurationError
-from twistedcaldav.notify import installNotificationClient
-from twistedcaldav.static import CalendarHomeProvisioningFile
 from twistedcaldav.directory.directory import UnknownRecordTypeError, DirectoryError
 
-from calendarserver.tools.util import booleanArgument, autoDisableMemcached
-from calendarserver.tools.util import loadConfig, getDirectory
-from calendarserver.provision.root import RootResource
+from calendarserver.tools.util import loadConfig, getDirectory, setupMemcached, setupNotifications, booleanArgument
 
 def usage(e=None):
     if e:
@@ -210,7 +205,8 @@
             config.directory = getDirectory()
         except DirectoryError, e:
             abort(e)
-        autoDisableMemcached(config)
+        setupMemcached(config)
+        setupNotifications(config)
     except ConfigurationError, e:
         abort(e)
 
@@ -261,40 +257,6 @@
 @inlineCallbacks
 def run(principalIDs, actions):
     try:
-        #
-        # Connect to memcached, notifications
-        #
-        memcachepool.installPools(
-            config.Memcached.Pools,
-            config.Memcached.MaxClients
-        )
-        if config.Notifications.Enabled:
-            installNotificationClient(
-                config.Notifications.InternalNotificationHost,
-                config.Notifications.InternalNotificationPort,
-            )
-
-        #
-        # Wire up the resource hierarchy
-        #
-        principalCollection = config.directory.getPrincipalCollection()
-        root = RootResource(
-            config.DocumentRoot,
-            principalCollections=(principalCollection,),
-        )
-        root.putChild("principals", principalCollection)
-        calendarCollection = CalendarHomeProvisioningFile(
-            os.path.join(config.DocumentRoot, "calendars"),
-            config.directory, "/calendars/",
-        )
-        root.putChild("calendars", calendarCollection)
-
-        #
-        # Wrap root resource
-        #
-        # FIXME: not a fan -wsanchez
-        #root = ResourceWrapper(root)
-
         for principalID in principalIDs:
             # Resolve the given principal IDs to principals
             try:
@@ -317,6 +279,7 @@
         #
         reactor.stop()
 
+
 def principalForPrincipalID(principalID, checkOnly=False, directory=None):
     
     # Allow a directory parameter to be passed in, but default to config.directory
@@ -326,11 +289,19 @@
         directory = config.directory
 
     if principalID.startswith("/"):
-        raise ValueError("Can't resolve paths yet")
+        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(")")
@@ -363,7 +334,7 @@
         if checkOnly:
             return None
 
-        return directory.principalCollection.principalForUID(guid)
+        return directory.principalCollection.principalForUID(str(guid))
     except ValueError:
         pass
 
@@ -407,31 +378,40 @@
 
 @inlineCallbacks
 def action_addProxyPrincipal(principal, proxyType, proxyPrincipal):
+    try:
+        (yield addProxy(principal, proxyType, proxyPrincipal))
+        print "Added %s as a %s proxy for %s" % (proxyPrincipal, proxyType, 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:
-        sys.stderr.write("Unable to edit %s proxies for %s\n" % (proxyType, principal))
-        return
+        raise ProxyError("Unable to edit %s proxies for %s\n" % (proxyType, principal))
 
     membersProperty = (yield subPrincipal.readProperty(davxml.GroupMemberSet, None))
 
     for memberURL in membersProperty.children:
         if str(memberURL) == proxyURL:
-            print "%s is already a %s proxy for %s" % (proxyPrincipal, proxyType, principal)
-            break
+            raise ProxyWarning("%s is already a %s proxy for %s" % (proxyPrincipal, proxyType, principal))
+
     else:
         memberURLs = list(membersProperty.children)
         memberURLs.append(davxml.HRef(proxyURL))
         membersProperty = davxml.GroupMemberSet(*memberURLs)
         (yield subPrincipal.writeProperty(membersProperty, None))
-        print "Added %s as a %s proxy for %s" % (proxyPrincipal, proxyType, principal)
 
     proxyTypes = ["read", "write"]
     proxyTypes.remove(proxyType)
 
     (yield action_removeProxyPrincipal(principal, proxyPrincipal, proxyTypes=proxyTypes))
 
+
 @inlineCallbacks
 def action_removeProxy(principal, *proxyIDs, **kwargs):
     for proxyID in proxyIDs:
@@ -440,14 +420,23 @@
 
 @inlineCallbacks
 def action_removeProxyPrincipal(principal, proxyPrincipal, **kwargs):
+    try:
+        (yield removeProxy(principal, proxyPrincipal, **kwargs))
+    except ProxyError, e:
+        print "Error:", e
+    except ProxyWarning, e:
+        print e
+
+
+ at inlineCallbacks
+def removeProxy(principal, proxyPrincipal, **kwargs):
     proxyTypes = kwargs.get("proxyTypes", ("read", "write"))
     for proxyType in proxyTypes:
         proxyURL = proxyPrincipal.url()
 
         subPrincipal = proxySubprincipal(principal, proxyType)
         if subPrincipal is None:
-            sys.stderr.write("Unable to edit %s proxies for %s\n" % (proxyType, principal))
-            continue
+            raise ProxyError("Unable to edit %s proxies for %s\n" % (proxyType, principal))
 
         membersProperty = (yield subPrincipal.readProperty(davxml.GroupMemberSet, None))
 
@@ -462,8 +451,9 @@
 
         membersProperty = davxml.GroupMemberSet(*memberURLs)
         (yield subPrincipal.writeProperty(membersProperty, None))
-        print "Removed %s as a %s proxy for %s" % (proxyPrincipal, proxyType, principal)
 
+
+
 @inlineCallbacks
 def action_setAutoSchedule(principal, autoSchedule):
     if autoSchedule and principal.record.recordType in ("users", "groups"):
@@ -530,5 +520,16 @@
         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.
+    """
+
 if __name__ == "__main__":
     main()

Deleted: CalendarServer/trunk/calendarserver/tools/test/__init__.py
===================================================================
--- CalendarServer/branches/users/sagen/locations-resources-2/calendarserver/tools/test/__init__.py	2010-02-08 22:31:59 UTC (rev 5061)
+++ CalendarServer/trunk/calendarserver/tools/test/__init__.py	2010-02-08 23:05:01 UTC (rev 5062)
@@ -1,19 +0,0 @@
-##
-# Copyright (c) 2005-2010 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.
-##
-
-"""
-Tests for the calendarserver.tools module.
-"""

Copied: CalendarServer/trunk/calendarserver/tools/test/__init__.py (from rev 5061, CalendarServer/branches/users/sagen/locations-resources-2/calendarserver/tools/test/__init__.py)
===================================================================
--- CalendarServer/trunk/calendarserver/tools/test/__init__.py	                        (rev 0)
+++ CalendarServer/trunk/calendarserver/tools/test/__init__.py	2010-02-08 23:05:01 UTC (rev 5062)
@@ -0,0 +1,19 @@
+##
+# Copyright (c) 2005-2010 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.
+##
+
+"""
+Tests for the calendarserver.tools module.
+"""

Deleted: CalendarServer/trunk/calendarserver/tools/test/gateway/augments.xml
===================================================================
--- CalendarServer/branches/users/sagen/locations-resources-2/calendarserver/tools/test/gateway/augments.xml	2010-02-08 22:31:59 UTC (rev 5061)
+++ CalendarServer/trunk/calendarserver/tools/test/gateway/augments.xml	2010-02-08 23:05:01 UTC (rev 5062)
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<!--
-Copyright (c) 2009-2010 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 "../../../conf/auth/augments.dtd">
-
-<augments>
-  <record>
-    <guid>user01</guid>
-    <enable>true</enable>
-    <enable-calendar>true</enable-calendar>
-  </record>
-  <record>
-    <guid>user02</guid>
-    <enable>false</enable>
-    <enable-calendar>false</enable-calendar>
-  </record>
-  <record>
-    <guid>location01</guid>
-    <enable>true</enable>
-    <enable-calendar>true</enable-calendar>
-  </record>
-</augments>

Copied: CalendarServer/trunk/calendarserver/tools/test/gateway/augments.xml (from rev 5061, CalendarServer/branches/users/sagen/locations-resources-2/calendarserver/tools/test/gateway/augments.xml)
===================================================================
--- CalendarServer/trunk/calendarserver/tools/test/gateway/augments.xml	                        (rev 0)
+++ CalendarServer/trunk/calendarserver/tools/test/gateway/augments.xml	2010-02-08 23:05:01 UTC (rev 5062)
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+Copyright (c) 2009-2010 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 "../../../conf/auth/augments.dtd">
+
+<augments>
+  <record>
+    <guid>user01</guid>
+    <enable>true</enable>
+    <enable-calendar>true</enable-calendar>
+  </record>
+  <record>
+    <guid>user02</guid>
+    <enable>false</enable>
+    <enable-calendar>false</enable-calendar>
+  </record>
+  <record>
+    <guid>location01</guid>
+    <enable>true</enable>
+    <enable-calendar>true</enable-calendar>
+  </record>
+</augments>

Deleted: CalendarServer/trunk/calendarserver/tools/test/gateway/caldavd.plist
===================================================================
--- CalendarServer/branches/users/sagen/locations-resources-2/calendarserver/tools/test/gateway/caldavd.plist	2010-02-08 22:31:59 UTC (rev 5061)
+++ CalendarServer/trunk/calendarserver/tools/test/gateway/caldavd.plist	2010-02-08 23:05:01 UTC (rev 5062)
@@ -1,760 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-
-<!--
-    Copyright (c) 2006-2010 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 plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-  <dict>
-
-    <!--
-        Public network address information
-
-        This is the server's public network address, which is provided to
-        clients in URLs and the like.  It may or may not be the network
-        address that the server is listening to directly, though it is by
-        default.  For example, it may be the address of a load balancer or
-        proxy which forwards connections to the server.
-      -->
-
-    <!-- Network host name [empty = system host name] -->
-    <key>ServerHostName</key>
-    <string></string> <!-- The hostname clients use when connecting -->
-
-    <!-- HTTP port [0 = disable HTTP] -->
-    <key>HTTPPort</key>
-    <integer>8008</integer>
-
-    <!-- SSL port [0 = disable HTTPS] -->
-    <!-- (Must also configure SSLCertificate and SSLPrivateKey below) -->
-    <key>SSLPort</key>
-    <integer>8443</integer>
-
-    <!-- Redirect non-SSL ports to an SSL port -->
-    <key>RedirectHTTPToHTTPS</key>
-    <false/>
-
-    <!--
-        Network address configuration information
-
-        This configures the actual network address that the server binds to.
-      -->
-
-    <!-- List of IP addresses to bind to [empty = all] -->
-    <key>BindAddresses</key>
-    <array>
-    </array>
-
-    <!-- List of port numbers to bind to for HTTP [empty = same as "Port"] -->
-    <key>BindHTTPPorts</key>
-    <array>
-    </array>
-
-    <!-- List of port numbers to bind to for SSL [empty = same as "SSLPort"] -->
-    <key>BindSSLPorts</key>
-    <array>
-    </array>
-
-
-    <!--
-        Data Store
-      -->
-
-    <!-- Data root -->
-    <key>DataRoot</key>
-    <string>%(DataRoot)s</string>
-
-    <!-- Document root -->
-    <key>DocumentRoot</key>
-    <string>%(DocumentRoot)s</string>
-
-    <!-- Child aliases -->
-    <key>Aliases</key>
-    <dict>
-      <!--
-      <key>foo</key>
-      <dict>
-        <key>path</key>
-        <string>/path/to/foo</string>
-      </dict>
-       -->
-    </dict>
-
-    <!-- User quota (in bytes) -->
-    <key>UserQuota</key>
-    <integer>104857600</integer><!-- 100Mb -->
-
-    <!-- Attachment size limit (in bytes) -->
-    <key>MaximumAttachmentSize</key>
-    <integer>1048576</integer><!-- 1Mb -->
-
-    <!-- Maximum number of unique attendees per entire event -->
-    <!-- 0 for no limit -->
-    <key>MaxAttendeesPerInstance</key>
-    <integer>100</integer>
-
-    <!-- Maximum number of instances allowed for a single RRULE -->
-    <!-- 0 for no limit -->
-    <key>MaxInstancesForRRULE</key>
-    <integer>400</integer>
-
-
-    <!--
-        Directory service
-
-        A directory service provides information about principals (eg.
-        users, groups, locations and resources) to the server.
-
-        A variety of directory services are available for use.
-      -->
-
-    <!-- XML File Directory Service -->
-    <key>DirectoryService</key>
-    <dict>
-      <key>type</key>
-      <string>twistedcaldav.directory.xmlfile.XMLDirectoryService</string>
-      
-      <key>params</key>
-      <dict>
-        <key>xmlFile</key>
-        <string>%(DirectoryXMLFile)s</string>
-        <key>recordTypes</key>
-        <array>
-            <string>users</string>
-            <string>groups</string>
-        </array>
-      </dict>
-    </dict>
-
-    <!-- XML File Resource Service -->
-    <key>ResourceService</key>
-    <dict>
-      <key>Enabled</key>
-      <true/>
-      <key>type</key>
-      <string>twistedcaldav.directory.xmlfile.XMLDirectoryService</string>
-      
-      <key>params</key>
-      <dict>
-        <key>xmlFile</key>
-        <string>%(ResourceXMLFile)s</string>
-        <key>recordTypes</key>
-        <array>
-            <string>resources</string>
-            <string>locations</string>
-        </array>
-        <key>cacheTimeout</key>
-        <integer>30</integer>
-      </dict>
-    </dict>
-    
-    <!-- Open Directory Service (Mac OS X) -->
-    <!--
-    <key>DirectoryService</key>
-    <dict>
-      <key>type</key>
-      <string>twistedcaldav.directory.appleopendirectory.OpenDirectoryService</string>
-      
-      <key>params</key>
-      <dict>
-        <key>node</key>
-        <string>/Search</string>
-        <key>cacheTimeout</key>
-        <integer>30</integer>
-      </dict>
-    </dict>
-    -->
-
-    <!--
-        Augment service
-
-        Augments for the directory service records to add calendar specific attributes.
-
-        A variety of augment services are available for use.
-        When using a partitioned server, a service that can be accessed from each host will be needed.
-      -->
-
-    <!-- XML File Augment Service -->
-    <key>AugmentService</key>
-    <dict>
-      <key>type</key>
-      <string>twistedcaldav.directory.augment.AugmentXMLDB</string>
-      
-      <key>params</key>
-      <dict>
-        <key>xmlFiles</key>
-        <array>
-	      <string>%(AugmentXMLFile)s</string>
-        </array>
-      </dict>
-    </dict>
-    
-    <!-- Sqlite Augment Service -->
-    <!--
-    <key>AugmentService</key>
-    <dict>
-      <key>type</key>
-      <string>twistedcaldav.directory.augment.AugmentSqliteDB</string>
-      
-      <key>params</key>
-      <dict>
-        <key>dbpath</key>
-        <string>/etc/caldavd/augments.sqlite</string>
-      </dict>
-    </dict>
-     -->
-
-    <!-- PostgreSQL Augment Service -->
-    <!--
-    <key>AugmentService</key>
-    <dict>
-      <key>type</key>
-      <string>twistedcaldav.directory.augment.AugmentPostgreSQLDB</string>
-      
-      <key>params</key>
-      <dict>
-        <key>host</key>
-        <string>localhost</string>
-        <key>database</key>
-        <string>augments</string>
-      </dict>
-    </dict>
-     -->
-
-    <!-- Sqlite ProxyDB Service -->
-    <key>ProxyDBService</key>
-    <dict>
-      <key>type</key>
-      <string>twistedcaldav.directory.calendaruserproxy.ProxySqliteDB</string>
-      
-      <key>params</key>
-      <dict>
-        <key>dbpath</key>
-        <string>%(ProxyDBFile)s</string>
-      </dict>
-    </dict>
-
-    <!-- PostgreSQL ProxyDB Service -->
-    <!--
-    <key>ProxyDBService</key>
-    <dict>
-      <key>type</key>
-      <string>twistedcaldav.directory.calendaruserproxy.ProxyPostgreSQLDB</string>
-      
-      <key>params</key>
-      <dict>
-        <key>host</key>
-        <string>localhost</string>
-        <key>database</key>
-        <string>proxies</string>
-      </dict>
-    </dict>
-     -->
-
-	<key>ProxyLoadFromFile</key>
-    <string>conf/auth/proxies-test.xml</string>
-
-    <!--
-        Special principals
-
-        These principals are granted special access and/or perform
-        special roles on the server.
-      -->
-
-    <!-- Principals with "DAV:all" access (relative URLs) -->
-    <key>AdminPrincipals</key>
-    <array>
-      <string>/principals/__uids__/admin/</string>
-    </array>
-
-    <!-- Principals with "DAV:read" access (relative URLs) -->
-    <key>ReadPrincipals</key>
-    <array>
-      <!-- <string>/principals/__uids__/983C8238-FB6B-4D92-9242-89C0A39E5F81/</string> -->
-    </array>
-
-    <!-- Principals that can pose as other principals -->
-    <key>SudoersFile</key>
-    <string>conf/sudoers.plist</string>
-
-    <!-- Create "proxy access" principals -->
-    <key>EnableProxyPrincipals</key>
-    <true/>
-
-
-    <!--
-        Permissions
-      -->
-
-    <!-- Anonymous read access for root resource -->
-    <key>EnableAnonymousReadRoot</key>
-    <true/>
-
-    <!-- Anonymous read access for resource hierarchy -->
-    <key>EnableAnonymousReadNav</key>
-    <false/>
-
-    <!-- Enables directory listings for principals -->
-    <key>EnablePrincipalListings</key>
-    <true/>
-
-    <!-- Render calendar collections as a monolithic iCalendar object -->
-    <key>EnableMonolithicCalendars</key>
-    <true/>
-
-
-    <!--
-        Authentication
-      -->
-
-    <key>Authentication</key>
-    <dict>
-
-      <!-- Clear text; best avoided -->
-      <key>Basic</key>
-      <dict>
-        <key>Enabled</key>
-        <true/>
-      </dict>
-
-      <!-- Digest challenge/response -->
-      <key>Digest</key>
-      <dict>
-        <key>Enabled</key>
-        <true/>
-        <key>Algorithm</key>
-        <string>md5</string>
-        <key>Qop</key>
-        <string></string>
-      </dict>
-
-      <!-- Kerberos/SPNEGO -->
-      <key>Kerberos</key>
-      <dict>
-        <key>Enabled</key>
-        <false/>
-        <key>ServicePrincipal</key>
-        <string></string>
-      </dict>
-
-      <!-- Wikiserver authentication (Mac OS X) -->
-      <key>Wiki</key>
-      <dict>
-        <key>Enabled</key>
-        <true/>
-        <key>Cookie</key>
-        <string>sessionID</string>
-        <key>URL</key>
-        <string>http://127.0.0.1/RPC2</string>
-        <key>UserMethod</key>
-        <string>userForSession</string>
-        <key>WikiMethod</key>
-        <string>accessLevelForUserWikiCalendar</string>
-      </dict>
-
-    </dict>
-
-
-    <!--
-        Logging
-      -->
-
-    <!-- Apache-style access log -->
-    <key>AccessLogFile</key>
-    <string>logs/access.log</string>
-    <key>RotateAccessLog</key>
-    <false/>
-
-    <!-- Server activity log -->
-    <key>ErrorLogFile</key>
-    <string>logs/error.log</string>
-
-    <!-- Log levels -->
-    <key>DefaultLogLevel</key>
-    <string>info</string> <!-- debug, info, warn, error -->
-
-    <!-- Log level overrides for specific functionality -->
-    <key>LogLevels</key>
-    <dict>
-      <!--
-      <key>twistedcaldav.directory.appleopendirectory.OpenDirectoryService</key>
-      <string>debug</string>
-      -->
-    </dict>
-
-    <!-- Global server stats --> 
-    <key>GlobalStatsSocket</key> 
-    <string>logs/caldavd-stats.sock</string> 
-
-    <!-- Global server stats logging period --> 
-    <key>GlobalStatsLoggingPeriod</key> 
-    <integer>60</integer> 
-
-    <!-- Global server stats logging frequency [0 = disable stats] --> 
-    <key>GlobalStatsLoggingFrequency</key> 
-    <integer>12</integer>
-
-    <!-- Server statistics file -->
-    <key>ServerStatsFile</key>
-    <string>logs/stats.plist</string>
-
-    <!-- Server process ID file -->
-    <key>PIDFile</key>
-    <string>logs/caldavd.pid</string>
-
-
-    <!--
-        Accounting
-      -->
-
-    <!-- Enable accounting for certain operations -->
-    <key>AccountingCategories</key>
-    <dict>
-      <key>iTIP</key>
-      <false/>
-      <key>HTTP</key>
-      <false/>
-    </dict>
-    <!-- Enable accounting for specific principals -->
-    <key>AccountingPrincipals</key>
-    <array>
-      <!-- <string>/principals/__uids__/454D85C0-09F0-4DC6-A3C6-97DFEB4622CD/</string> -->
-    </array>
-
-
-    <!--
-        SSL/TLS
-      -->
-
-    <!-- Public key -->
-    <key>SSLCertificate</key>
-    <string>twistedcaldav/test/data/server.pem</string>
-
-    <!-- SSL authority chain (for intermediate certs) -->
-    <key>SSLAuthorityChain</key>
-    <string></string>
-
-    <!-- Private key -->
-    <key>SSLPrivateKey</key>
-    <string>twistedcaldav/test/data/server.pem</string>
-
-
-    <!--
-        Process management
-      -->
-
-    <key>UserName</key>
-    <string></string>
-
-    <key>GroupName</key>
-    <string></string>
-
-    <key>ProcessType</key>
-    <string>Combined</string>
-
-    <key>MultiProcess</key>
-    <dict>
-      <key>ProcessCount</key>
-      <integer>2</integer> <!-- 0 = larger of: 4 or (2 * CPU count) -->
-    </dict>
-
-
-    <!--
-        Notifications
-      -->
-
-    <key>Notifications</key>
-    <dict>
-      <!-- Time spent coalescing notifications before delivery -->
-      <key>CoalesceSeconds</key>
-      <integer>3</integer>
-
-      <key>InternalNotificationHost</key>
-      <string>localhost</string>
-
-      <key>InternalNotificationPort</key>
-      <integer>62309</integer>
-
-      <key>Services</key>
-      <dict>
-        <key>SimpleLineNotifier</key>
-        <dict>
-          <!-- Simple line notification service (for testing) -->
-          <key>Service</key>
-          <string>twistedcaldav.notify.SimpleLineNotifierService</string>
-          <key>Enabled</key>
-          <false/>
-          <key>Port</key>
-          <integer>62308</integer>
-        </dict>
-
-        <key>XMPPNotifier</key>
-        <dict>
-          <!-- XMPP notification service -->
-          <key>Service</key>
-          <string>twistedcaldav.notify.XMPPNotifierService</string>
-          <key>Enabled</key>
-          <false/>
-
-          <!-- XMPP host and port to contact -->
-          <key>Host</key>
-          <string>xmpp.host.name</string>
-          <key>Port</key>
-          <integer>5222</integer>
-
-          <!-- Jabber ID and password for the server -->
-          <key>JID</key>
-          <string>jid at xmpp.host.name/resource</string>
-          <key>Password</key>
-          <string>password_goes_here</string>
-
-          <!-- PubSub service address -->
-          <key>ServiceAddress</key>
-          <string>pubsub.xmpp.host.name</string>
-
-          <key>NodeConfiguration</key>
-          <dict>
-            <key>pubsub#deliver_payloads</key>
-            <string>1</string>
-            <key>pubsub#persist_items</key>
-            <string>1</string>
-          </dict>
-
-          <!-- Sends a presence notification to XMPP server at this interval (prevents disconnect) -->
-          <key>KeepAliveSeconds</key>
-          <integer>120</integer>
-
-          <!-- Sends a pubsub publish to a particular heartbeat node at this interval -->
-          <key>HeartbeatMinutes</key>
-          <integer>30</integer>
-
-          <!-- List of glob-like expressions defining which XMPP JIDs can converse with the server (for debugging) -->
-          <key>AllowedJIDs</key>
-          <array>
-            <!--
-            <string>*.example.com</string>
-             -->
-          </array>
-        </dict>
-      </dict>
-    </dict>
-
-
-    <!--
-        Server-to-server protocol
-      -->
-
-    <key>Scheduling</key>
-    <dict>
-
-      <!-- CalDAV protocol options -->
-      <key>CalDAV</key>
-      <dict>
-        <key>EmailDomain</key>
-        <string></string>
-        <key>HTTPDomain</key>
-        <string></string>
-        <key>AddressPatterns</key>
-        <array>
-        </array>
-        <key>OldDraftCompatibility</key>
-        <true/>
-        <key>ScheduleTagCompatibility</key>
-        <true/>
-        <key>EnablePrivateComments</key>
-        <true/>
-      </dict>
-
-      <!-- iSchedule protocol options -->
-      <key>iSchedule</key>
-      <dict>
-        <key>Enabled</key>
-        <false/>
-        <key>AddressPatterns</key>
-        <array>
-        </array>
-        <key>Servers</key>
-        <string>conf/servertoserver-test.xml</string>
-      </dict>
-
-      <!-- iMIP protocol options -->
-      <key>iMIP</key>
-      <dict>
-        <key>Enabled</key>
-        <false/>
-        <key>MailGatewayServer</key>
-        <string>localhost</string>
-        <key>MailGatewayPort</key>
-        <integer>62310</integer>
-        <key>Sending</key>
-        <dict>
-          <key>Server</key>
-          <string></string>
-          <key>Port</key>
-          <integer>587</integer>
-          <key>UseSSL</key>
-          <true/>
-          <key>Username</key>
-          <string></string>
-          <key>Password</key>
-          <string></string>
-          <key>Address</key>
-          <string></string> <!-- Address email will be sent from -->
-        </dict>
-        <key>Receiving</key>
-        <dict>
-          <key>Server</key>
-          <string></string>
-          <key>Port</key>
-          <integer>995</integer>
-          <key>Type</key>
-          <string></string> <!-- Either "pop" or "imap" -->
-          <key>UseSSL</key>
-          <true/>
-          <key>Username</key>
-          <string></string>
-          <key>Password</key>
-          <string></string>
-          <key>PollingSeconds</key>
-          <integer>30</integer>
-        </dict>
-        <key>AddressPatterns</key>
-        <array>
-          <string>mailto:.*</string>
-        </array>
-      </dict>
-
-	  <!-- General options for scheduling -->
-	  <key>Options</key>
-	  <dict>
-        <key>AllowGroupAsOrganizer</key>
-        <false/>
-        <key>AllowLocationAsOrganizer</key>
-        <false/>
-        <key>AllowResourceAsOrganizer</key>
-        <false/>
-       </dict>
-
-    </dict>
-
-
-    <!--
-        Free-busy URL protocol
-      -->
-
-    <key>FreeBusyURL</key>
-    <dict>
-      <key>Enabled</key>
-      <true/>
-      <key>TimePeriod</key>
-      <integer>14</integer>
-      <key>AnonymousAccess</key>
-      <false/>
-    </dict>
-
-
-    <!--
-        Non-standard CalDAV extensions
-      -->
-
-    <!-- Calendar Drop Box -->
-    <key>EnableDropBox</key>
-    <true/>
-
-    <!-- Private Events -->
-    <key>EnablePrivateEvents</key>
-    <true/>
-
-    <!-- Timezone Service -->
-    <key>EnableTimezoneService</key>
-    <true/>
-
-
-    <!--
-        Miscellaneous items
-      -->
-
-    <!-- Service ACLs (Mac OS X) -->
-    <key>EnableSACLs</key>
-    <false/>
-
-    <!-- Web-based administration -->
-    <key>EnableWebAdmin</key>
-    <true/>
-
-    <!-- Support for Content-Encoding compression options as specified in RFC2616 Section 3.5 -->
-    <key>ResponseCompression</key>
-    <false/>
-    
-    <!-- The retry-after value (in seconds) to return with a 503 error. -->
-    <key>HTTPRetryAfter</key>
-    <integer>180</integer>
-
-    <!-- A unix socket used for communication between the child and master processes.
-         An empty value tells the server to use a tcp socket instead. -->
-    <key>ControlSocket</key>
-    <string>logs/caldavd.sock</string>
-
-    <!-- Support for Memcached -->
-    <key>Memcached</key>
-    <dict>
-      <key>MaxClients</key>
-      <integer>5</integer>
-      <key>memcached</key>
-      <string>memcached</string> <!-- Find in PATH -->
-      <key>Options</key>
-      <array>
-        <!--<string>-vv</string>-->
-      </array>
-      <key>Pools</key>
-        <dict>
-        <key>Default</key>
-            <dict>
-                <key>ClientEnabled</key>
-                <false/>
-                <key>ServerEnabled</key>
-                <false/>
-            </dict>
-        </dict>
-    </dict>
-
-    <!-- Response Caching -->
-    <key>ResponseCacheTimeout</key>
-    <integer>30</integer> <!-- in minutes -->
-
-
-    <!--
-        Twisted
-      -->
-
-    <key>Twisted</key>
-    <dict>
-      <key>twistd</key>
-      <string>../Twisted/bin/twistd</string>
-    </dict>
-
-
-    <key>Localization</key>
-    <dict>
-      <key>LocalesDirectory</key>
-      <string>locales</string>
-      <key>Language</key>
-      <string>English</string>
-    </dict>
-
-
-  </dict>
-</plist>

Copied: CalendarServer/trunk/calendarserver/tools/test/gateway/caldavd.plist (from rev 5061, CalendarServer/branches/users/sagen/locations-resources-2/calendarserver/tools/test/gateway/caldavd.plist)
===================================================================
--- CalendarServer/trunk/calendarserver/tools/test/gateway/caldavd.plist	                        (rev 0)
+++ CalendarServer/trunk/calendarserver/tools/test/gateway/caldavd.plist	2010-02-08 23:05:01 UTC (rev 5062)
@@ -0,0 +1,760 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+    Copyright (c) 2006-2010 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 plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+  <dict>
+
+    <!--
+        Public network address information
+
+        This is the server's public network address, which is provided to
+        clients in URLs and the like.  It may or may not be the network
+        address that the server is listening to directly, though it is by
+        default.  For example, it may be the address of a load balancer or
+        proxy which forwards connections to the server.
+      -->
+
+    <!-- Network host name [empty = system host name] -->
+    <key>ServerHostName</key>
+    <string></string> <!-- The hostname clients use when connecting -->
+
+    <!-- HTTP port [0 = disable HTTP] -->
+    <key>HTTPPort</key>
+    <integer>8008</integer>
+
+    <!-- SSL port [0 = disable HTTPS] -->
+    <!-- (Must also configure SSLCertificate and SSLPrivateKey below) -->
+    <key>SSLPort</key>
+    <integer>8443</integer>
+
+    <!-- Redirect non-SSL ports to an SSL port -->
+    <key>RedirectHTTPToHTTPS</key>
+    <false/>
+
+    <!--
+        Network address configuration information
+
+        This configures the actual network address that the server binds to.
+      -->
+
+    <!-- List of IP addresses to bind to [empty = all] -->
+    <key>BindAddresses</key>
+    <array>
+    </array>
+
+    <!-- List of port numbers to bind to for HTTP [empty = same as "Port"] -->
+    <key>BindHTTPPorts</key>
+    <array>
+    </array>
+
+    <!-- List of port numbers to bind to for SSL [empty = same as "SSLPort"] -->
+    <key>BindSSLPorts</key>
+    <array>
+    </array>
+
+
+    <!--
+        Data Store
+      -->
+
+    <!-- Data root -->
+    <key>DataRoot</key>
+    <string>%(DataRoot)s</string>
+
+    <!-- Document root -->
+    <key>DocumentRoot</key>
+    <string>%(DocumentRoot)s</string>
+
+    <!-- Child aliases -->
+    <key>Aliases</key>
+    <dict>
+      <!--
+      <key>foo</key>
+      <dict>
+        <key>path</key>
+        <string>/path/to/foo</string>
+      </dict>
+       -->
+    </dict>
+
+    <!-- User quota (in bytes) -->
+    <key>UserQuota</key>
+    <integer>104857600</integer><!-- 100Mb -->
+
+    <!-- Attachment size limit (in bytes) -->
+    <key>MaximumAttachmentSize</key>
+    <integer>1048576</integer><!-- 1Mb -->
+
+    <!-- Maximum number of unique attendees per entire event -->
+    <!-- 0 for no limit -->
+    <key>MaxAttendeesPerInstance</key>
+    <integer>100</integer>
+
+    <!-- Maximum number of instances allowed for a single RRULE -->
+    <!-- 0 for no limit -->
+    <key>MaxInstancesForRRULE</key>
+    <integer>400</integer>
+
+
+    <!--
+        Directory service
+
+        A directory service provides information about principals (eg.
+        users, groups, locations and resources) to the server.
+
+        A variety of directory services are available for use.
+      -->
+
+    <!-- XML File Directory Service -->
+    <key>DirectoryService</key>
+    <dict>
+      <key>type</key>
+      <string>twistedcaldav.directory.xmlfile.XMLDirectoryService</string>
+      
+      <key>params</key>
+      <dict>
+        <key>xmlFile</key>
+        <string>%(DirectoryXMLFile)s</string>
+        <key>recordTypes</key>
+        <array>
+            <string>users</string>
+            <string>groups</string>
+        </array>
+      </dict>
+    </dict>
+
+    <!-- XML File Resource Service -->
+    <key>ResourceService</key>
+    <dict>
+      <key>Enabled</key>
+      <true/>
+      <key>type</key>
+      <string>twistedcaldav.directory.xmlfile.XMLDirectoryService</string>
+      
+      <key>params</key>
+      <dict>
+        <key>xmlFile</key>
+        <string>%(ResourceXMLFile)s</string>
+        <key>recordTypes</key>
+        <array>
+            <string>resources</string>
+            <string>locations</string>
+        </array>
+        <key>cacheTimeout</key>
+        <integer>30</integer>
+      </dict>
+    </dict>
+    
+    <!-- Open Directory Service (Mac OS X) -->
+    <!--
+    <key>DirectoryService</key>
+    <dict>
+      <key>type</key>
+      <string>twistedcaldav.directory.appleopendirectory.OpenDirectoryService</string>
+      
+      <key>params</key>
+      <dict>
+        <key>node</key>
+        <string>/Search</string>
+        <key>cacheTimeout</key>
+        <integer>30</integer>
+      </dict>
+    </dict>
+    -->
+
+    <!--
+        Augment service
+
+        Augments for the directory service records to add calendar specific attributes.
+
+        A variety of augment services are available for use.
+        When using a partitioned server, a service that can be accessed from each host will be needed.
+      -->
+
+    <!-- XML File Augment Service -->
+    <key>AugmentService</key>
+    <dict>
+      <key>type</key>
+      <string>twistedcaldav.directory.augment.AugmentXMLDB</string>
+      
+      <key>params</key>
+      <dict>
+        <key>xmlFiles</key>
+        <array>
+	      <string>%(AugmentXMLFile)s</string>
+        </array>
+      </dict>
+    </dict>
+    
+    <!-- Sqlite Augment Service -->
+    <!--
+    <key>AugmentService</key>
+    <dict>
+      <key>type</key>
+      <string>twistedcaldav.directory.augment.AugmentSqliteDB</string>
+      
+      <key>params</key>
+      <dict>
+        <key>dbpath</key>
+        <string>/etc/caldavd/augments.sqlite</string>
+      </dict>
+    </dict>
+     -->
+
+    <!-- PostgreSQL Augment Service -->
+    <!--
+    <key>AugmentService</key>
+    <dict>
+      <key>type</key>
+      <string>twistedcaldav.directory.augment.AugmentPostgreSQLDB</string>
+      
+      <key>params</key>
+      <dict>
+        <key>host</key>
+        <string>localhost</string>
+        <key>database</key>
+        <string>augments</string>
+      </dict>
+    </dict>
+     -->
+
+    <!-- Sqlite ProxyDB Service -->
+    <key>ProxyDBService</key>
+    <dict>
+      <key>type</key>
+      <string>twistedcaldav.directory.calendaruserproxy.ProxySqliteDB</string>
+      
+      <key>params</key>
+      <dict>
+        <key>dbpath</key>
+        <string>%(ProxyDBFile)s</string>
+      </dict>
+    </dict>
+
+    <!-- PostgreSQL ProxyDB Service -->
+    <!--
+    <key>ProxyDBService</key>
+    <dict>
+      <key>type</key>
+      <string>twistedcaldav.directory.calendaruserproxy.ProxyPostgreSQLDB</string>
+      
+      <key>params</key>
+      <dict>
+        <key>host</key>
+        <string>localhost</string>
+        <key>database</key>
+        <string>proxies</string>
+      </dict>
+    </dict>
+     -->
+
+	<key>ProxyLoadFromFile</key>
+    <string>conf/auth/proxies-test.xml</string>
+
+    <!--
+        Special principals
+
+        These principals are granted special access and/or perform
+        special roles on the server.
+      -->
+
+    <!-- Principals with "DAV:all" access (relative URLs) -->
+    <key>AdminPrincipals</key>
+    <array>
+      <string>/principals/__uids__/admin/</string>
+    </array>
+
+    <!-- Principals with "DAV:read" access (relative URLs) -->
+    <key>ReadPrincipals</key>
+    <array>
+      <!-- <string>/principals/__uids__/983C8238-FB6B-4D92-9242-89C0A39E5F81/</string> -->
+    </array>
+
+    <!-- Principals that can pose as other principals -->
+    <key>SudoersFile</key>
+    <string>conf/sudoers.plist</string>
+
+    <!-- Create "proxy access" principals -->
+    <key>EnableProxyPrincipals</key>
+    <true/>
+
+
+    <!--
+        Permissions
+      -->
+
+    <!-- Anonymous read access for root resource -->
+    <key>EnableAnonymousReadRoot</key>
+    <true/>
+
+    <!-- Anonymous read access for resource hierarchy -->
+    <key>EnableAnonymousReadNav</key>
+    <false/>
+
+    <!-- Enables directory listings for principals -->
+    <key>EnablePrincipalListings</key>
+    <true/>
+
+    <!-- Render calendar collections as a monolithic iCalendar object -->
+    <key>EnableMonolithicCalendars</key>
+    <true/>
+
+
+    <!--
+        Authentication
+      -->
+
+    <key>Authentication</key>
+    <dict>
+
+      <!-- Clear text; best avoided -->
+      <key>Basic</key>
+      <dict>
+        <key>Enabled</key>
+        <true/>
+      </dict>
+
+      <!-- Digest challenge/response -->
+      <key>Digest</key>
+      <dict>
+        <key>Enabled</key>
+        <true/>
+        <key>Algorithm</key>
+        <string>md5</string>
+        <key>Qop</key>
+        <string></string>
+      </dict>
+
+      <!-- Kerberos/SPNEGO -->
+      <key>Kerberos</key>
+      <dict>
+        <key>Enabled</key>
+        <false/>
+        <key>ServicePrincipal</key>
+        <string></string>
+      </dict>
+
+      <!-- Wikiserver authentication (Mac OS X) -->
+      <key>Wiki</key>
+      <dict>
+        <key>Enabled</key>
+        <true/>
+        <key>Cookie</key>
+        <string>sessionID</string>
+        <key>URL</key>
+        <string>http://127.0.0.1/RPC2</string>
+        <key>UserMethod</key>
+        <string>userForSession</string>
+        <key>WikiMethod</key>
+        <string>accessLevelForUserWikiCalendar</string>
+      </dict>
+
+    </dict>
+
+
+    <!--
+        Logging
+      -->
+
+    <!-- Apache-style access log -->
+    <key>AccessLogFile</key>
+    <string>logs/access.log</string>
+    <key>RotateAccessLog</key>
+    <false/>
+
+    <!-- Server activity log -->
+    <key>ErrorLogFile</key>
+    <string>logs/error.log</string>
+
+    <!-- Log levels -->
+    <key>DefaultLogLevel</key>
+    <string>info</string> <!-- debug, info, warn, error -->
+
+    <!-- Log level overrides for specific functionality -->
+    <key>LogLevels</key>
+    <dict>
+      <!--
+      <key>twistedcaldav.directory.appleopendirectory.OpenDirectoryService</key>
+      <string>debug</string>
+      -->
+    </dict>
+
+    <!-- Global server stats --> 
+    <key>GlobalStatsSocket</key> 
+    <string>logs/caldavd-stats.sock</string> 
+
+    <!-- Global server stats logging period --> 
+    <key>GlobalStatsLoggingPeriod</key> 
+    <integer>60</integer> 
+
+    <!-- Global server stats logging frequency [0 = disable stats] --> 
+    <key>GlobalStatsLoggingFrequency</key> 
+    <integer>12</integer>
+
+    <!-- Server statistics file -->
+    <key>ServerStatsFile</key>
+    <string>logs/stats.plist</string>
+
+    <!-- Server process ID file -->
+    <key>PIDFile</key>
+    <string>logs/caldavd.pid</string>
+
+
+    <!--
+        Accounting
+      -->
+
+    <!-- Enable accounting for certain operations -->
+    <key>AccountingCategories</key>
+    <dict>
+      <key>iTIP</key>
+      <false/>
+      <key>HTTP</key>
+      <false/>
+    </dict>
+    <!-- Enable accounting for specific principals -->
+    <key>AccountingPrincipals</key>
+    <array>
+      <!-- <string>/principals/__uids__/454D85C0-09F0-4DC6-A3C6-97DFEB4622CD/</string> -->
+    </array>
+
+
+    <!--
+        SSL/TLS
+      -->
+
+    <!-- Public key -->
+    <key>SSLCertificate</key>
+    <string>twistedcaldav/test/data/server.pem</string>
+
+    <!-- SSL authority chain (for intermediate certs) -->
+    <key>SSLAuthorityChain</key>
+    <string></string>
+
+    <!-- Private key -->
+    <key>SSLPrivateKey</key>
+    <string>twistedcaldav/test/data/server.pem</string>
+
+
+    <!--
+        Process management
+      -->
+
+    <key>UserName</key>
+    <string></string>
+
+    <key>GroupName</key>
+    <string></string>
+
+    <key>ProcessType</key>
+    <string>Combined</string>
+
+    <key>MultiProcess</key>
+    <dict>
+      <key>ProcessCount</key>
+      <integer>2</integer> <!-- 0 = larger of: 4 or (2 * CPU count) -->
+    </dict>
+
+
+    <!--
+        Notifications
+      -->
+
+    <key>Notifications</key>
+    <dict>
+      <!-- Time spent coalescing notifications before delivery -->
+      <key>CoalesceSeconds</key>
+      <integer>3</integer>
+
+      <key>InternalNotificationHost</key>
+      <string>localhost</string>
+
+      <key>InternalNotificationPort</key>
+      <integer>62309</integer>
+
+      <key>Services</key>
+      <dict>
+        <key>SimpleLineNotifier</key>
+        <dict>
+          <!-- Simple line notification service (for testing) -->
+          <key>Service</key>
+          <string>twistedcaldav.notify.SimpleLineNotifierService</string>
+          <key>Enabled</key>
+          <false/>
+          <key>Port</key>
+          <integer>62308</integer>
+        </dict>
+
+        <key>XMPPNotifier</key>
+        <dict>
+          <!-- XMPP notification service -->
+          <key>Service</key>
+          <string>twistedcaldav.notify.XMPPNotifierService</string>
+          <key>Enabled</key>
+          <false/>
+
+          <!-- XMPP host and port to contact -->
+          <key>Host</key>
+          <string>xmpp.host.name</string>
+          <key>Port</key>
+          <integer>5222</integer>
+
+          <!-- Jabber ID and password for the server -->
+          <key>JID</key>
+          <string>jid at xmpp.host.name/resource</string>
+          <key>Password</key>
+          <string>password_goes_here</string>
+
+          <!-- PubSub service address -->
+          <key>ServiceAddress</key>
+          <string>pubsub.xmpp.host.name</string>
+
+          <key>NodeConfiguration</key>
+          <dict>
+            <key>pubsub#deliver_payloads</key>
+            <string>1</string>
+            <key>pubsub#persist_items</key>
+            <string>1</string>
+          </dict>
+
+          <!-- Sends a presence notification to XMPP server at this interval (prevents disconnect) -->
+          <key>KeepAliveSeconds</key>
+          <integer>120</integer>
+
+          <!-- Sends a pubsub publish to a particular heartbeat node at this interval -->
+          <key>HeartbeatMinutes</key>
+          <integer>30</integer>
+
+          <!-- List of glob-like expressions defining which XMPP JIDs can converse with the server (for debugging) -->
+          <key>AllowedJIDs</key>
+          <array>
+            <!--
+            <string>*.example.com</string>
+             -->
+          </array>
+        </dict>
+      </dict>
+    </dict>
+
+
+    <!--
+        Server-to-server protocol
+      -->
+
+    <key>Scheduling</key>
+    <dict>
+
+      <!-- CalDAV protocol options -->
+      <key>CalDAV</key>
+      <dict>
+        <key>EmailDomain</key>
+        <string></string>
+        <key>HTTPDomain</key>
+        <string></string>
+        <key>AddressPatterns</key>
+        <array>
+        </array>
+        <key>OldDraftCompatibility</key>
+        <true/>
+        <key>ScheduleTagCompatibility</key>
+        <true/>
+        <key>EnablePrivateComments</key>
+        <true/>
+      </dict>
+
+      <!-- iSchedule protocol options -->
+      <key>iSchedule</key>
+      <dict>
+        <key>Enabled</key>
+        <false/>
+        <key>AddressPatterns</key>
+        <array>
+        </array>
+        <key>Servers</key>
+        <string>conf/servertoserver-test.xml</string>
+      </dict>
+
+      <!-- iMIP protocol options -->
+      <key>iMIP</key>
+      <dict>
+        <key>Enabled</key>
+        <false/>
+        <key>MailGatewayServer</key>
+        <string>localhost</string>
+        <key>MailGatewayPort</key>
+        <integer>62310</integer>
+        <key>Sending</key>
+        <dict>
+          <key>Server</key>
+          <string></string>
+          <key>Port</key>
+          <integer>587</integer>
+          <key>UseSSL</key>
+          <true/>
+          <key>Username</key>
+          <string></string>
+          <key>Password</key>
+          <string></string>
+          <key>Address</key>
+          <string></string> <!-- Address email will be sent from -->
+        </dict>
+        <key>Receiving</key>
+        <dict>
+          <key>Server</key>
+          <string></string>
+          <key>Port</key>
+          <integer>995</integer>
+          <key>Type</key>
+          <string></string> <!-- Either "pop" or "imap" -->
+          <key>UseSSL</key>
+          <true/>
+          <key>Username</key>
+          <string></string>
+          <key>Password</key>
+          <string></string>
+          <key>PollingSeconds</key>
+          <integer>30</integer>
+        </dict>
+        <key>AddressPatterns</key>
+        <array>
+          <string>mailto:.*</string>
+        </array>
+      </dict>
+
+	  <!-- General options for scheduling -->
+	  <key>Options</key>
+	  <dict>
+        <key>AllowGroupAsOrganizer</key>
+        <false/>
+        <key>AllowLocationAsOrganizer</key>
+        <false/>
+        <key>AllowResourceAsOrganizer</key>
+        <false/>
+       </dict>
+
+    </dict>
+
+
+    <!--
+        Free-busy URL protocol
+      -->
+
+    <key>FreeBusyURL</key>
+    <dict>
+      <key>Enabled</key>
+      <true/>
+      <key>TimePeriod</key>
+      <integer>14</integer>
+      <key>AnonymousAccess</key>
+      <false/>
+    </dict>
+
+
+    <!--
+        Non-standard CalDAV extensions
+      -->
+
+    <!-- Calendar Drop Box -->
+    <key>EnableDropBox</key>
+    <true/>
+
+    <!-- Private Events -->
+    <key>EnablePrivateEvents</key>
+    <true/>
+
+    <!-- Timezone Service -->
+    <key>EnableTimezoneService</key>
+    <true/>
+
+
+    <!--
+        Miscellaneous items
+      -->
+
+    <!-- Service ACLs (Mac OS X) -->
+    <key>EnableSACLs</key>
+    <false/>
+
+    <!-- Web-based administration -->
+    <key>EnableWebAdmin</key>
+    <true/>
+
+    <!-- Support for Content-Encoding compression options as specified in RFC2616 Section 3.5 -->
+    <key>ResponseCompression</key>
+    <false/>
+    
+    <!-- The retry-after value (in seconds) to return with a 503 error. -->
+    <key>HTTPRetryAfter</key>
+    <integer>180</integer>
+
+    <!-- A unix socket used for communication between the child and master processes.
+         An empty value tells the server to use a tcp socket instead. -->
+    <key>ControlSocket</key>
+    <string>logs/caldavd.sock</string>
+
+    <!-- Support for Memcached -->
+    <key>Memcached</key>
+    <dict>
+      <key>MaxClients</key>
+      <integer>5</integer>
+      <key>memcached</key>
+      <string>memcached</string> <!-- Find in PATH -->
+      <key>Options</key>
+      <array>
+        <!--<string>-vv</string>-->
+      </array>
+      <key>Pools</key>
+        <dict>
+        <key>Default</key>
+            <dict>
+                <key>ClientEnabled</key>
+                <false/>
+                <key>ServerEnabled</key>
+                <false/>
+            </dict>
+        </dict>
+    </dict>
+
+    <!-- Response Caching -->
+    <key>ResponseCacheTimeout</key>
+    <integer>30</integer> <!-- in minutes -->
+
+
+    <!--
+        Twisted
+      -->
+
+    <key>Twisted</key>
+    <dict>
+      <key>twistd</key>
+      <string>../Twisted/bin/twistd</string>
+    </dict>
+
+
+    <key>Localization</key>
+    <dict>
+      <key>LocalesDirectory</key>
+      <string>locales</string>
+      <key>Language</key>
+      <string>English</string>
+    </dict>
+
+
+  </dict>
+</plist>

Deleted: CalendarServer/trunk/calendarserver/tools/test/gateway/resources-locations.xml
===================================================================
--- CalendarServer/branches/users/sagen/locations-resources-2/calendarserver/tools/test/gateway/resources-locations.xml	2010-02-08 22:31:59 UTC (rev 5061)
+++ CalendarServer/trunk/calendarserver/tools/test/gateway/resources-locations.xml	2010-02-08 23:05:01 UTC (rev 5062)
@@ -1,34 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<!--
-Copyright (c) 2006-2010 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>
-  <resource repeat="10">
-    <uid>resource%02d</uid>
-    <guid>resource%02d</guid>
-    <password>resource%02d</password>
-    <name>Resource %02d</name>
-  </resource>
-</accounts>

Copied: CalendarServer/trunk/calendarserver/tools/test/gateway/resources-locations.xml (from rev 5061, CalendarServer/branches/users/sagen/locations-resources-2/calendarserver/tools/test/gateway/resources-locations.xml)
===================================================================
--- CalendarServer/trunk/calendarserver/tools/test/gateway/resources-locations.xml	                        (rev 0)
+++ CalendarServer/trunk/calendarserver/tools/test/gateway/resources-locations.xml	2010-02-08 23:05:01 UTC (rev 5062)
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+Copyright (c) 2006-2010 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>
+  <resource repeat="10">
+    <uid>resource%02d</uid>
+    <guid>resource%02d</guid>
+    <password>resource%02d</password>
+    <name>Resource %02d</name>
+  </resource>
+</accounts>

Deleted: CalendarServer/trunk/calendarserver/tools/test/gateway/users-groups.xml
===================================================================
--- CalendarServer/branches/users/sagen/locations-resources-2/calendarserver/tools/test/gateway/users-groups.xml	2010-02-08 22:31:59 UTC (rev 5061)
+++ CalendarServer/trunk/calendarserver/tools/test/gateway/users-groups.xml	2010-02-08 23:05:01 UTC (rev 5062)
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<!--
-Copyright (c) 2006-2010 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">
-  <user repeat="10">
-    <uid>user%02d</uid>
-    <guid>user%02d</guid>
-    <password>test</password>
-    <name>Test User %02d</name>
-    <first-name>Test</first-name>
-    <last-name>User %02d</last-name>
-  </user>
-  <group>
-    <uid>testgroup1</uid>
-    <guid>e5a6142c-4189-4e9e-90b0-9cd0268b314b</guid>
-    <password>test</password>
-    <name>Group 01</name>
-    <members>
-      <member type="users">user01</member>
-      <member type="users">user02</member>
-    </members>
-  </group>
-</accounts>

Copied: CalendarServer/trunk/calendarserver/tools/test/gateway/users-groups.xml (from rev 5061, CalendarServer/branches/users/sagen/locations-resources-2/calendarserver/tools/test/gateway/users-groups.xml)
===================================================================
--- CalendarServer/trunk/calendarserver/tools/test/gateway/users-groups.xml	                        (rev 0)
+++ CalendarServer/trunk/calendarserver/tools/test/gateway/users-groups.xml	2010-02-08 23:05:01 UTC (rev 5062)
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+Copyright (c) 2006-2010 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">
+  <user repeat="10">
+    <uid>user%02d</uid>
+    <guid>user%02d</guid>
+    <password>test</password>
+    <name>Test User %02d</name>
+    <first-name>Test</first-name>
+    <last-name>User %02d</last-name>
+  </user>
+  <group>
+    <uid>testgroup1</uid>
+    <guid>e5a6142c-4189-4e9e-90b0-9cd0268b314b</guid>
+    <password>test</password>
+    <name>Group 01</name>
+    <members>
+      <member type="users">user01</member>
+      <member type="users">user02</member>
+    </members>
+  </group>
+</accounts>

Deleted: CalendarServer/trunk/calendarserver/tools/test/test_gateway.py
===================================================================
--- CalendarServer/branches/users/sagen/locations-resources-2/calendarserver/tools/test/test_gateway.py	2010-02-08 22:31:59 UTC (rev 5061)
+++ CalendarServer/trunk/calendarserver/tools/test/test_gateway.py	2010-02-08 23:05:01 UTC (rev 5062)
@@ -1,409 +0,0 @@
-##
-# Copyright (c) 2005-2010 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 plistlib
-import xml
-
-from twisted.internet import reactor
-from twisted.internet.defer import inlineCallbacks, Deferred, returnValue
-from twisted.internet.error import ProcessDone
-from twisted.internet.protocol import ProcessProtocol
-
-from twistedcaldav.config import config
-from twistedcaldav.test.util import TestCase
-from calendarserver.tools.util import getDirectory
-from twisted.python.filepath import FilePath
-from twistedcaldav.directory.directory import DirectoryError
-
-class ErrorOutput(Exception):
-    """
-    The process produced some error output and exited with a non-zero exit
-    code.
-    """
-
-
-class CapturingProcessProtocol(ProcessProtocol):
-    """
-    A L{ProcessProtocol} that captures its output and error.
-
-    @ivar output: a C{list} of all C{str}s received to stderr.
-
-    @ivar error: a C{list} of all C{str}s received to stderr.
-    """
-
-    def __init__(self, deferred, inputData):
-        """
-        Initialize a L{CapturingProcessProtocol}.
-
-        @param deferred: the L{Deferred} to fire when the process is complete.
-
-        @param inputData: a C{str} to feed to the subprocess's stdin.
-        """
-        self.deferred = deferred
-        self.input = inputData
-        self.output = []
-        self.error = []
-
-
-    def connectionMade(self):
-        """
-        The process started; feed its input on stdin.
-        """
-        self.transport.write(self.input)
-        self.transport.closeStdin()
-
-
-    def outReceived(self, data):
-        """
-        Some output was received on stdout.
-        """
-        self.output.append(data)
-
-
-    def errReceived(self, data):
-        """
-        Some output was received on stderr.
-        """
-        self.error.append(data)
-        # Attempt to exit promptly if a traceback is displayed, so we don't
-        # deal with timeouts.
-        lines = ''.join(self.error).split("\n")
-        if len(lines) > 1:
-            errorReportLine = lines[-2].split(": ", 1)
-            if len(errorReportLine) == 2 and ' ' not in errorReportLine[0] and '\t' not in errorReportLine[0]:
-                self.transport.signalProcess("TERM")
-
-
-    def processEnded(self, why):
-        """
-        The process is over, fire the Deferred with the output.
-        """
-        if why.check(ProcessDone) and not self.error:
-            self.deferred.callback(''.join(self.output))
-        else:
-            self.deferred.errback(ErrorOutput(''.join(self.error)))
-
-
-class GatewayTestCase(TestCase):
-
-    def setUp(self):
-        testRoot = os.path.join(os.path.dirname(__file__), "gateway")
-        templateName = os.path.join(testRoot, "caldavd.plist")
-        templateFile = open(templateName)
-        template = templateFile.read()
-        templateFile.close()
-
-        tmpDir = FilePath(self.mktemp())
-        tmpDir.makedirs()
-        dataRoot = tmpDir.child("data")
-        dataRoot.makedirs()
-        docRoot = tmpDir.child("documents")
-        docRoot.makedirs()
-
-        # Copy xml files to a temp directory because they may get modified
-
-        origUsersFile = FilePath(os.path.join(os.path.dirname(__file__),
-            "gateway", "users-groups.xml"))
-        copyUsersFile = tmpDir.child("users-groups.xml")
-        origUsersFile.copyTo(copyUsersFile)
-
-        origResourcesFile = FilePath(os.path.join(os.path.dirname(__file__),
-            "gateway", "resources-locations.xml"))
-        copyResourcesFile = tmpDir.child("resources-locations.xml")
-        origResourcesFile.copyTo(copyResourcesFile)
-
-        origAugmentFile = FilePath(os.path.join(os.path.dirname(__file__),
-            "gateway", "augments.xml"))
-        copyAugmentFile = tmpDir.child("augments.xml")
-        origAugmentFile.copyTo(copyAugmentFile)
-
-        proxyFile = tmpDir.child("proxies.sqlite")
-
-        newConfig = template % {
-            'DataRoot' : dataRoot.path,
-            'DocumentRoot' : docRoot.path,
-            'DirectoryXMLFile' : copyUsersFile.path,
-            'ResourceXMLFile' : copyResourcesFile.path,
-            'AugmentXMLFile' : copyAugmentFile.path,
-            'ProxyDBFile' : proxyFile.path,
-        }
-        configFilePath = tmpDir.child("caldavd.plist")
-        configFilePath.setContent(newConfig)
-
-        self.configFileName = configFilePath.path
-        config.load(self.configFileName)
-
-        super(GatewayTestCase, self).setUp()
-
-        # Make sure trial puts the reactor in the right state, by letting it
-        # run one reactor iteration.  (Ignore me, please.)
-        d = Deferred()
-        reactor.callLater(0, d.callback, True)
-        return d
-
-    @inlineCallbacks
-    def runCommand(self, command):
-        """
-        Run the given command by feeding it as standard input to
-        calendarserver_command_gateway in a subprocess.
-        """
-        sourceRoot = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(__file__))))
-        python = os.path.join(sourceRoot, "python")
-        gateway = os.path.join(sourceRoot, "bin", "calendarserver_command_gateway")
-
-        args = [python, gateway, "-f", self.configFileName]
-        cwd = sourceRoot
-
-        deferred = Deferred()
-        reactor.spawnProcess(CapturingProcessProtocol(deferred, command), python, args, env=os.environ, path=cwd)
-        output = yield deferred
-        try:
-            plist = plistlib.readPlistFromString(output)
-        except xml.parsers.expat.ExpatError, e:
-            print "Error (%s) parsing (%s)" % (e, output)
-            raise
-
-        returnValue(plist)
-
-    @inlineCallbacks
-    def test_getLocationList(self):
-        results = yield self.runCommand(command_getLocationList)
-        self.assertEquals(len(results['result']), 10)
-
-    @inlineCallbacks
-    def test_getResourceList(self):
-        results = yield self.runCommand(command_getResourceList)
-        self.assertEquals(len(results['result']), 10)
-
-    @inlineCallbacks
-    def test_createLocation(self):
-        directory = getDirectory()
-
-        record = directory.recordWithUID("createdlocation01")
-        self.assertEquals(record, None)
-
-        yield self.runCommand(command_createLocation)
-
-        directory.flushCaches()
-        record = directory.recordWithUID("createdlocation01")
-        self.assertNotEquals(record, None)
-
-    @inlineCallbacks
-    def test_destroyRecord(self):
-        directory = getDirectory()
-
-        record = directory.recordWithUID("location01")
-        self.assertNotEquals(record, None)
-
-        yield self.runCommand(command_deleteLocation)
-
-        directory.flushCaches()
-        record = directory.recordWithUID("location01")
-        self.assertEquals(record, None)
-
-    @inlineCallbacks
-    def test_addWriteProxy(self):
-        directory = getDirectory()
-
-        results = yield self.runCommand(command_addWriteProxy)
-        self.assertEquals(len(results['result']['Proxies']), 1)
-
-    @inlineCallbacks
-    def test_removeWriteProxy(self):
-        directory = getDirectory()
-
-        results = yield self.runCommand(command_addWriteProxy)
-        results = yield self.runCommand(command_removeWriteProxy)
-        self.assertEquals(len(results['result']['Proxies']), 0)
-
-
-
-command_deleteLocation = """<?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>command</key>
-        <string>deleteLocation</string>
-        <key>GeneratedUID</key>
-        <string>guidoffice3</string>
-</dict>
-</plist>
-"""
-
-command_addReadProxy = """<?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>command</key>
-        <string>addReadProxy</string>
-        <key>Principal</key>
-        <string>locations:location01</string>
-        <key>Proxy</key>
-        <string>users:user03</string>
-</dict>
-</plist>
-"""
-
-command_addWriteProxy = """<?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>command</key>
-        <string>addWriteProxy</string>
-        <key>Principal</key>
-        <string>locations:location01</string>
-        <key>Proxy</key>
-        <string>users:user01</string>
-</dict>
-</plist>
-"""
-
-command_createLocation = """<?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>command</key>
-        <string>createLocation</string>
-        <key>AutoSchedule</key>
-        <true/>
-        <key>GeneratedUID</key>
-        <string>createdlocation01</string>
-        <key>RealName</key>
-        <string>Created Location 01</string>
-        <key>RecordName</key>
-        <array>
-                <string>createdlocation01</string>
-        </array>
-</dict>
-</plist>
-"""
-
-command_createResource = """<?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>command</key>
-        <string>createResource</string>
-        <key>AutoSchedule</key>
-        <true/>
-        <key>GeneratedUID</key>
-        <string>guidlaptop1</string>
-        <key>RealName</key>
-        <string>Laptop 1</string>
-        <key>RecordName</key>
-        <array>
-                <string>laptop1</string>
-        </array>
-</dict>
-</plist>
-"""
-
-command_deleteLocation = """<?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>command</key>
-        <string>deleteLocation</string>
-        <key>GeneratedUID</key>
-        <string>location01</string>
-</dict>
-</plist>
-"""
-
-command_deleteResource = """<?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>command</key>
-        <string>deleteResource</string>
-        <key>GeneratedUID</key>
-        <string>guidlaptop1</string>
-</dict>
-</plist>
-"""
-
-command_getLocationList = """<?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>command</key>
-        <string>getLocationList</string>
-</dict>
-</plist>
-"""
-
-command_getResourceList = """<?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>command</key>
-        <string>getResourceList</string>
-</dict>
-</plist>
-"""
-
-command_listReadProxies = """<?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>command</key>
-        <string>listReadProxies</string>
-        <key>Principal</key>
-        <string>locations:location01</string>
-</dict>
-</plist>
-"""
-
-command_listWriteProxies = """<?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>command</key>
-        <string>listWriteProxies</string>
-        <key>Principal</key>
-        <string>locations:location01</string>
-</dict>
-</plist>
-"""
-
-command_removeReadProxy = """<?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>command</key>
-        <string>removeReadProxy</string>
-        <key>Principal</key>
-        <string>locations:location01</string>
-        <key>Proxy</key>
-        <string>users:user03</string>
-</dict>
-</plist>
-"""
-
-command_removeWriteProxy = """<?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>command</key>
-        <string>removeWriteProxy</string>
-        <key>Principal</key>
-        <string>locations:location01</string>
-        <key>Proxy</key>
-        <string>users:user01</string>
-</dict>
-</plist>
-"""

Copied: CalendarServer/trunk/calendarserver/tools/test/test_gateway.py (from rev 5061, CalendarServer/branches/users/sagen/locations-resources-2/calendarserver/tools/test/test_gateway.py)
===================================================================
--- CalendarServer/trunk/calendarserver/tools/test/test_gateway.py	                        (rev 0)
+++ CalendarServer/trunk/calendarserver/tools/test/test_gateway.py	2010-02-08 23:05:01 UTC (rev 5062)
@@ -0,0 +1,409 @@
+##
+# Copyright (c) 2005-2010 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 plistlib
+import xml
+
+from twisted.internet import reactor
+from twisted.internet.defer import inlineCallbacks, Deferred, returnValue
+from twisted.internet.error import ProcessDone
+from twisted.internet.protocol import ProcessProtocol
+
+from twistedcaldav.config import config
+from twistedcaldav.test.util import TestCase
+from calendarserver.tools.util import getDirectory
+from twisted.python.filepath import FilePath
+from twistedcaldav.directory.directory import DirectoryError
+
+class ErrorOutput(Exception):
+    """
+    The process produced some error output and exited with a non-zero exit
+    code.
+    """
+
+
+class CapturingProcessProtocol(ProcessProtocol):
+    """
+    A L{ProcessProtocol} that captures its output and error.
+
+    @ivar output: a C{list} of all C{str}s received to stderr.
+
+    @ivar error: a C{list} of all C{str}s received to stderr.
+    """
+
+    def __init__(self, deferred, inputData):
+        """
+        Initialize a L{CapturingProcessProtocol}.
+
+        @param deferred: the L{Deferred} to fire when the process is complete.
+
+        @param inputData: a C{str} to feed to the subprocess's stdin.
+        """
+        self.deferred = deferred
+        self.input = inputData
+        self.output = []
+        self.error = []
+
+
+    def connectionMade(self):
+        """
+        The process started; feed its input on stdin.
+        """
+        self.transport.write(self.input)
+        self.transport.closeStdin()
+
+
+    def outReceived(self, data):
+        """
+        Some output was received on stdout.
+        """
+        self.output.append(data)
+
+
+    def errReceived(self, data):
+        """
+        Some output was received on stderr.
+        """
+        self.error.append(data)
+        # Attempt to exit promptly if a traceback is displayed, so we don't
+        # deal with timeouts.
+        lines = ''.join(self.error).split("\n")
+        if len(lines) > 1:
+            errorReportLine = lines[-2].split(": ", 1)
+            if len(errorReportLine) == 2 and ' ' not in errorReportLine[0] and '\t' not in errorReportLine[0]:
+                self.transport.signalProcess("TERM")
+
+
+    def processEnded(self, why):
+        """
+        The process is over, fire the Deferred with the output.
+        """
+        if why.check(ProcessDone) and not self.error:
+            self.deferred.callback(''.join(self.output))
+        else:
+            self.deferred.errback(ErrorOutput(''.join(self.error)))
+
+
+class GatewayTestCase(TestCase):
+
+    def setUp(self):
+        testRoot = os.path.join(os.path.dirname(__file__), "gateway")
+        templateName = os.path.join(testRoot, "caldavd.plist")
+        templateFile = open(templateName)
+        template = templateFile.read()
+        templateFile.close()
+
+        tmpDir = FilePath(self.mktemp())
+        tmpDir.makedirs()
+        dataRoot = tmpDir.child("data")
+        dataRoot.makedirs()
+        docRoot = tmpDir.child("documents")
+        docRoot.makedirs()
+
+        # Copy xml files to a temp directory because they may get modified
+
+        origUsersFile = FilePath(os.path.join(os.path.dirname(__file__),
+            "gateway", "users-groups.xml"))
+        copyUsersFile = tmpDir.child("users-groups.xml")
+        origUsersFile.copyTo(copyUsersFile)
+
+        origResourcesFile = FilePath(os.path.join(os.path.dirname(__file__),
+            "gateway", "resources-locations.xml"))
+        copyResourcesFile = tmpDir.child("resources-locations.xml")
+        origResourcesFile.copyTo(copyResourcesFile)
+
+        origAugmentFile = FilePath(os.path.join(os.path.dirname(__file__),
+            "gateway", "augments.xml"))
+        copyAugmentFile = tmpDir.child("augments.xml")
+        origAugmentFile.copyTo(copyAugmentFile)
+
+        proxyFile = tmpDir.child("proxies.sqlite")
+
+        newConfig = template % {
+            'DataRoot' : dataRoot.path,
+            'DocumentRoot' : docRoot.path,
+            'DirectoryXMLFile' : copyUsersFile.path,
+            'ResourceXMLFile' : copyResourcesFile.path,
+            'AugmentXMLFile' : copyAugmentFile.path,
+            'ProxyDBFile' : proxyFile.path,
+        }
+        configFilePath = tmpDir.child("caldavd.plist")
+        configFilePath.setContent(newConfig)
+
+        self.configFileName = configFilePath.path
+        config.load(self.configFileName)
+
+        super(GatewayTestCase, self).setUp()
+
+        # Make sure trial puts the reactor in the right state, by letting it
+        # run one reactor iteration.  (Ignore me, please.)
+        d = Deferred()
+        reactor.callLater(0, d.callback, True)
+        return d
+
+    @inlineCallbacks
+    def runCommand(self, command):
+        """
+        Run the given command by feeding it as standard input to
+        calendarserver_command_gateway in a subprocess.
+        """
+        sourceRoot = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(__file__))))
+        python = os.path.join(sourceRoot, "python")
+        gateway = os.path.join(sourceRoot, "bin", "calendarserver_command_gateway")
+
+        args = [python, gateway, "-f", self.configFileName]
+        cwd = sourceRoot
+
+        deferred = Deferred()
+        reactor.spawnProcess(CapturingProcessProtocol(deferred, command), python, args, env=os.environ, path=cwd)
+        output = yield deferred
+        try:
+            plist = plistlib.readPlistFromString(output)
+        except xml.parsers.expat.ExpatError, e:
+            print "Error (%s) parsing (%s)" % (e, output)
+            raise
+
+        returnValue(plist)
+
+    @inlineCallbacks
+    def test_getLocationList(self):
+        results = yield self.runCommand(command_getLocationList)
+        self.assertEquals(len(results['result']), 10)
+
+    @inlineCallbacks
+    def test_getResourceList(self):
+        results = yield self.runCommand(command_getResourceList)
+        self.assertEquals(len(results['result']), 10)
+
+    @inlineCallbacks
+    def test_createLocation(self):
+        directory = getDirectory()
+
+        record = directory.recordWithUID("createdlocation01")
+        self.assertEquals(record, None)
+
+        yield self.runCommand(command_createLocation)
+
+        directory.flushCaches()
+        record = directory.recordWithUID("createdlocation01")
+        self.assertNotEquals(record, None)
+
+    @inlineCallbacks
+    def test_destroyRecord(self):
+        directory = getDirectory()
+
+        record = directory.recordWithUID("location01")
+        self.assertNotEquals(record, None)
+
+        yield self.runCommand(command_deleteLocation)
+
+        directory.flushCaches()
+        record = directory.recordWithUID("location01")
+        self.assertEquals(record, None)
+
+    @inlineCallbacks
+    def test_addWriteProxy(self):
+        directory = getDirectory()
+
+        results = yield self.runCommand(command_addWriteProxy)
+        self.assertEquals(len(results['result']['Proxies']), 1)
+
+    @inlineCallbacks
+    def test_removeWriteProxy(self):
+        directory = getDirectory()
+
+        results = yield self.runCommand(command_addWriteProxy)
+        results = yield self.runCommand(command_removeWriteProxy)
+        self.assertEquals(len(results['result']['Proxies']), 0)
+
+
+
+command_deleteLocation = """<?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>command</key>
+        <string>deleteLocation</string>
+        <key>GeneratedUID</key>
+        <string>guidoffice3</string>
+</dict>
+</plist>
+"""
+
+command_addReadProxy = """<?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>command</key>
+        <string>addReadProxy</string>
+        <key>Principal</key>
+        <string>locations:location01</string>
+        <key>Proxy</key>
+        <string>users:user03</string>
+</dict>
+</plist>
+"""
+
+command_addWriteProxy = """<?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>command</key>
+        <string>addWriteProxy</string>
+        <key>Principal</key>
+        <string>locations:location01</string>
+        <key>Proxy</key>
+        <string>users:user01</string>
+</dict>
+</plist>
+"""
+
+command_createLocation = """<?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>command</key>
+        <string>createLocation</string>
+        <key>AutoSchedule</key>
+        <true/>
+        <key>GeneratedUID</key>
+        <string>createdlocation01</string>
+        <key>RealName</key>
+        <string>Created Location 01</string>
+        <key>RecordName</key>
+        <array>
+                <string>createdlocation01</string>
+        </array>
+</dict>
+</plist>
+"""
+
+command_createResource = """<?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>command</key>
+        <string>createResource</string>
+        <key>AutoSchedule</key>
+        <true/>
+        <key>GeneratedUID</key>
+        <string>guidlaptop1</string>
+        <key>RealName</key>
+        <string>Laptop 1</string>
+        <key>RecordName</key>
+        <array>
+                <string>laptop1</string>
+        </array>
+</dict>
+</plist>
+"""
+
+command_deleteLocation = """<?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>command</key>
+        <string>deleteLocation</string>
+        <key>GeneratedUID</key>
+        <string>location01</string>
+</dict>
+</plist>
+"""
+
+command_deleteResource = """<?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>command</key>
+        <string>deleteResource</string>
+        <key>GeneratedUID</key>
+        <string>guidlaptop1</string>
+</dict>
+</plist>
+"""
+
+command_getLocationList = """<?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>command</key>
+        <string>getLocationList</string>
+</dict>
+</plist>
+"""
+
+command_getResourceList = """<?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>command</key>
+        <string>getResourceList</string>
+</dict>
+</plist>
+"""
+
+command_listReadProxies = """<?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>command</key>
+        <string>listReadProxies</string>
+        <key>Principal</key>
+        <string>locations:location01</string>
+</dict>
+</plist>
+"""
+
+command_listWriteProxies = """<?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>command</key>
+        <string>listWriteProxies</string>
+        <key>Principal</key>
+        <string>locations:location01</string>
+</dict>
+</plist>
+"""
+
+command_removeReadProxy = """<?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>command</key>
+        <string>removeReadProxy</string>
+        <key>Principal</key>
+        <string>locations:location01</string>
+        <key>Proxy</key>
+        <string>users:user03</string>
+</dict>
+</plist>
+"""
+
+command_removeWriteProxy = """<?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>command</key>
+        <string>removeWriteProxy</string>
+        <key>Principal</key>
+        <string>locations:location01</string>
+        <key>Proxy</key>
+        <string>users:user01</string>
+</dict>
+</plist>
+"""

Modified: CalendarServer/trunk/calendarserver/tools/util.py
===================================================================
--- CalendarServer/trunk/calendarserver/tools/util.py	2010-02-08 22:31:59 UTC (rev 5061)
+++ CalendarServer/trunk/calendarserver/tools/util.py	2010-02-08 23:05:01 UTC (rev 5062)
@@ -24,15 +24,21 @@
 
 import os
 from time import sleep
+import socket
 
 from twisted.python.reflect import namedClass
 
-import socket
+from calendarserver.provision.root import RootResource
+from twistedcaldav import memcachepool
 from twistedcaldav.config import config, ConfigurationError
 from twistedcaldav.directory import augment, calendaruserproxy
+from twistedcaldav.directory.aggregate import AggregateDirectoryService
 from twistedcaldav.directory.directory import DirectoryService, DirectoryRecord
+from twistedcaldav.notify import installNotificationClient
+from twistedcaldav.static import CalendarHomeProvisioningFile
 from twistedcaldav.stdconfig import DEFAULT_CONFIG_FILE
 
+
 def loadConfig(configFileName):
     if configFileName is None:
         configFileName = DEFAULT_CONFIG_FILE
@@ -45,9 +51,8 @@
     return config
 
 def getDirectory():
-    BaseDirectoryService = namedClass(config.DirectoryService.type)
 
-    class MyDirectoryService (BaseDirectoryService):
+    class MyDirectoryService (AggregateDirectoryService):
         def getPrincipalCollection(self):
             if not hasattr(self, "_principalCollection"):
                 #
@@ -97,12 +102,38 @@
     calendaruserproxy.ProxyDBService = proxydbClass(**config.ProxyDBService.params)
 
     # Wait for directory service to become available
-    directory = MyDirectoryService(config.DirectoryService.params)
+    BaseDirectoryService = namedClass(config.DirectoryService.type)
+    directory = BaseDirectoryService(config.DirectoryService.params)
     while not directory.isAvailable():
         sleep(5)
 
-    return directory
 
+    directories = [directory]
+
+    if config.ResourceService.Enabled:
+        resourceClass = namedClass(config.ResourceService.type)
+        resourceDirectory = resourceClass(config.ResourceService.params)
+        directories.append(resourceDirectory)
+
+    aggregate = MyDirectoryService(directories)
+
+    #
+    # Wire up the resource hierarchy
+    #
+    principalCollection = aggregate.getPrincipalCollection()
+    root = RootResource(
+        config.DocumentRoot,
+        principalCollections=(principalCollection,),
+    )
+    root.putChild("principals", principalCollection)
+    calendarCollection = CalendarHomeProvisioningFile(
+        os.path.join(config.DocumentRoot, "calendars"),
+        aggregate, "/calendars/",
+    )
+    root.putChild("calendars", calendarCollection)
+
+    return aggregate
+
 class DummyDirectoryService (DirectoryService):
     realmName = ""
     baseGUID = "51856FD4-5023-4890-94FE-4356C4AAC3E4"
@@ -147,3 +178,25 @@
 
     except socket.error:
         config.Memcached.Pools.Default.ClientEnabled = False
+
+
+def setupMemcached(config):
+    #
+    # Connect to memcached
+    #
+    memcachepool.installPools(
+        config.Memcached.Pools,
+        config.Memcached.MaxClients
+    )
+    autoDisableMemcached(config)
+
+def setupNotifications(config):
+    #
+    # Connect to notifications
+    #
+    if config.Notifications.Enabled:
+        installNotificationClient(
+            config.Notifications.InternalNotificationHost,
+            config.Notifications.InternalNotificationPort,
+        )
+

Modified: CalendarServer/trunk/conf/auth/accounts-test.xml
===================================================================
--- CalendarServer/trunk/conf/auth/accounts-test.xml	2010-02-08 22:31:59 UTC (rev 5061)
+++ CalendarServer/trunk/conf/auth/accounts-test.xml	2010-02-08 23:05:01 UTC (rev 5062)
@@ -53,18 +53,6 @@
     <first-name>Public</first-name>
     <last-name>%02d</last-name>
   </user>
-  <location repeat="10">
-    <uid>location%02d</uid>
-    <guid>location%02d</guid>
-    <password>location%02d</password>
-    <name>Room %02d</name>
-  </location>
-  <resource repeat="10">
-    <uid>resource%02d</uid>
-    <guid>resource%02d</guid>
-    <password>resource%02d</password>
-    <name>Resource %02d</name>
-  </resource>
   <group>
     <uid>group01</uid>
     <guid>group01</guid>

Copied: CalendarServer/trunk/conf/auth/resources-test.xml (from rev 5061, CalendarServer/branches/users/sagen/locations-resources-2/conf/auth/resources-test.xml)
===================================================================
--- CalendarServer/trunk/conf/auth/resources-test.xml	                        (rev 0)
+++ CalendarServer/trunk/conf/auth/resources-test.xml	2010-02-08 23:05:01 UTC (rev 5062)
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+Copyright (c) 2006-2010 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>
+  <resource repeat="10">
+    <uid>resource%02d</uid>
+    <guid>resource%02d</guid>
+    <password>resource%02d</password>
+    <name>Resource %02d</name>
+  </resource>
+</accounts>

Modified: CalendarServer/trunk/conf/caldavd-apple.plist
===================================================================
--- CalendarServer/trunk/conf/caldavd-apple.plist	2010-02-08 22:31:59 UTC (rev 5061)
+++ CalendarServer/trunk/conf/caldavd-apple.plist	2010-02-08 23:05:01 UTC (rev 5062)
@@ -159,6 +159,22 @@
     </dict>
 
 
+    <!-- Resource and Locations service -->
+    <key>ResourceService</key>
+    <dict>
+      <key>Enabled</key>
+      <true/>
+      <key>type</key>
+      <string>twistedcaldav.directory.xmlfile.XMLDirectoryService</string>
+
+      <key>params</key>
+      <dict>
+        <key>xmlFile</key>
+        <string>/Library/CalendarServer/Data/resources.xml</string>
+      </dict>
+    </dict>
+
+
     <!--
         Augment service
 
@@ -224,7 +240,7 @@
       <key>params</key>
       <dict>
         <key>dbpath</key>
-        <string>/etc/caldavd/proxies.sqlite</string>
+        <string>/Library/CalendarServer/Data/proxies.sqlite</string>
       </dict>
     </dict>
 

Modified: CalendarServer/trunk/conf/caldavd-test.plist
===================================================================
--- CalendarServer/trunk/conf/caldavd-test.plist	2010-02-08 22:31:59 UTC (rev 5061)
+++ CalendarServer/trunk/conf/caldavd-test.plist	2010-02-08 23:05:01 UTC (rev 5062)
@@ -131,9 +131,34 @@
       <dict>
         <key>xmlFile</key>
         <string>conf/auth/accounts-test.xml</string>
+        <key>recordTypes</key>
+        <array>
+            <string>users</string>
+            <string>groups</string>
+        </array>
       </dict>
     </dict>
     
+    <!-- Resource and Location Service -->
+    <key>ResourceService</key>
+    <dict>
+      <key>Enabled</key>
+      <true/>
+      <key>type</key>
+      <string>twistedcaldav.directory.xmlfile.XMLDirectoryService</string>
+      
+      <key>params</key>
+      <dict>
+        <key>xmlFile</key>
+        <string>conf/auth/resources-test.xml</string>
+        <key>recordTypes</key>
+        <array>
+            <string>locations</string>
+            <string>resources</string>
+        </array>
+      </dict>
+    </dict>
+    
     <!-- Open Directory Service (Mac OS X) -->
     <!--
     <key>DirectoryService</key>

Deleted: CalendarServer/trunk/conf/resources/caldavd-resources.plist
===================================================================
--- CalendarServer/branches/users/sagen/locations-resources-2/conf/resources/caldavd-resources.plist	2010-02-08 22:31:59 UTC (rev 5061)
+++ CalendarServer/trunk/conf/resources/caldavd-resources.plist	2010-02-08 23:05:01 UTC (rev 5062)
@@ -1,747 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-
-<!--
-    Copyright (c) 2006-2010 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 plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-  <dict>
-
-    <!--
-        Public network address information
-
-        This is the server's public network address, which is provided to
-        clients in URLs and the like.  It may or may not be the network
-        address that the server is listening to directly, though it is by
-        default.  For example, it may be the address of a load balancer or
-        proxy which forwards connections to the server.
-      -->
-
-    <!-- Network host name [empty = system host name] -->
-    <key>ServerHostName</key>
-    <string></string> <!-- The hostname clients use when connecting -->
-
-    <!-- HTTP port [0 = disable HTTP] -->
-    <key>HTTPPort</key>
-    <integer>8008</integer>
-
-    <!-- SSL port [0 = disable HTTPS] -->
-    <!-- (Must also configure SSLCertificate and SSLPrivateKey below) -->
-    <key>SSLPort</key>
-    <integer>8443</integer>
-
-    <!-- Redirect non-SSL ports to an SSL port -->
-    <key>RedirectHTTPToHTTPS</key>
-    <false/>
-
-    <!--
-        Network address configuration information
-
-        This configures the actual network address that the server binds to.
-      -->
-
-    <!-- List of IP addresses to bind to [empty = all] -->
-    <key>BindAddresses</key>
-    <array>
-    </array>
-
-    <!-- List of port numbers to bind to for HTTP [empty = same as "Port"] -->
-    <key>BindHTTPPorts</key>
-    <array>
-    </array>
-
-    <!-- List of port numbers to bind to for SSL [empty = same as "SSLPort"] -->
-    <key>BindSSLPorts</key>
-    <array>
-    </array>
-
-
-    <!--
-        Data Store
-      -->
-
-    <!-- Data root -->
-    <key>DataRoot</key>
-    <string>data/</string>
-
-    <!-- Document root -->
-    <key>DocumentRoot</key>
-    <string>twistedcaldav/test/data/</string>
-
-    <!-- Child aliases -->
-    <key>Aliases</key>
-    <dict>
-      <!--
-      <key>foo</key>
-      <dict>
-        <key>path</key>
-        <string>/path/to/foo</string>
-      </dict>
-       -->
-    </dict>
-
-    <!-- User quota (in bytes) -->
-    <key>UserQuota</key>
-    <integer>104857600</integer><!-- 100Mb -->
-
-    <!-- Attachment size limit (in bytes) -->
-    <key>MaximumAttachmentSize</key>
-    <integer>1048576</integer><!-- 1Mb -->
-
-    <!-- Maximum number of unique attendees per entire event -->
-    <!-- 0 for no limit -->
-    <key>MaxAttendeesPerInstance</key>
-    <integer>100</integer>
-
-    <!-- Maximum number of instances allowed for a single RRULE -->
-    <!-- 0 for no limit -->
-    <key>MaxInstancesForRRULE</key>
-    <integer>400</integer>
-
-
-    <!--
-        Directory service
-
-        A directory service provides information about principals (eg.
-        users, groups, locations and resources) to the server.
-
-        A variety of directory services are available for use.
-      -->
-
-    <!-- XML File Directory Service -->
-    <key>DirectoryService</key>
-    <dict>
-      <key>type</key>
-      <string>twistedcaldav.directory.xmlfile.XMLDirectoryService</string>
-      
-      <key>params</key>
-      <dict>
-        <key>xmlFile</key>
-        <string>conf/resources/users-groups.xml</string>
-        <key>recordTypes</key>
-        <array>
-            <string>users</string>
-            <string>groups</string>
-        </array>
-      </dict>
-    </dict>
-    
-    <key>ResourceService</key>
-    <dict>
-      <key>Enabled</key>
-      <true/>
-      <key>type</key>
-      <string>twistedcaldav.directory.xmlfile.XMLDirectoryService</string>
-      
-      <key>params</key>
-      <dict>
-        <key>xmlFile</key>
-        <string>conf/resources/locations-resources.xml</string>
-        <key>recordTypes</key>
-        <array>
-            <string>locations</string>
-            <string>resources</string>
-        </array>
-      </dict>
-    </dict>
-    
-    <!-- Open Directory Service (Mac OS X) -->
-    <!--
-    <key>DirectoryService</key>
-    <dict>
-      <key>type</key>
-      <string>twistedcaldav.directory.appleopendirectory.OpenDirectoryService</string>
-      
-      <key>params</key>
-      <dict>
-        <key>node</key>
-        <string>/Search</string>
-        <key>cacheTimeout</key>
-        <integer>30</integer>
-      </dict>
-    </dict>
-    -->
-
-    <!--
-        Augment service
-
-        Augments for the directory service records to add calendar specific attributes.
-
-        A variety of augment services are available for use.
-        When using a partitioned server, a service that can be accessed from each host will be needed.
-      -->
-
-    <!-- XML File Augment Service -->
-    <key>AugmentService</key>
-    <dict>
-      <key>type</key>
-      <string>twistedcaldav.directory.augment.AugmentXMLDB</string>
-      
-      <key>params</key>
-      <dict>
-        <key>xmlFiles</key>
-        <array>
-	      <string>conf/auth/augments-test.xml</string>
-        </array>
-      </dict>
-    </dict>
-    
-    <!-- Sqlite Augment Service -->
-    <!--
-    <key>AugmentService</key>
-    <dict>
-      <key>type</key>
-      <string>twistedcaldav.directory.augment.AugmentSqliteDB</string>
-      
-      <key>params</key>
-      <dict>
-        <key>dbpath</key>
-        <string>/etc/caldavd/augments.sqlite</string>
-      </dict>
-    </dict>
-     -->
-
-    <!-- PostgreSQL Augment Service -->
-    <!--
-    <key>AugmentService</key>
-    <dict>
-      <key>type</key>
-      <string>twistedcaldav.directory.augment.AugmentPostgreSQLDB</string>
-      
-      <key>params</key>
-      <dict>
-        <key>host</key>
-        <string>localhost</string>
-        <key>database</key>
-        <string>augments</string>
-      </dict>
-    </dict>
-     -->
-
-    <!-- Sqlite ProxyDB Service -->
-    <key>ProxyDBService</key>
-    <dict>
-      <key>type</key>
-      <string>twistedcaldav.directory.calendaruserproxy.ProxySqliteDB</string>
-      
-      <key>params</key>
-      <dict>
-        <key>dbpath</key>
-        <string>data/proxies.sqlite</string>
-      </dict>
-    </dict>
-
-    <!-- PostgreSQL ProxyDB Service -->
-    <!--
-    <key>ProxyDBService</key>
-    <dict>
-      <key>type</key>
-      <string>twistedcaldav.directory.calendaruserproxy.ProxyPostgreSQLDB</string>
-      
-      <key>params</key>
-      <dict>
-        <key>host</key>
-        <string>localhost</string>
-        <key>database</key>
-        <string>proxies</string>
-      </dict>
-    </dict>
-     -->
-
-	<key>ProxyLoadFromFile</key>
-    <string>conf/auth/proxies-test.xml</string>
-
-    <!--
-        Special principals
-
-        These principals are granted special access and/or perform
-        special roles on the server.
-      -->
-
-    <!-- Principals with "DAV:all" access (relative URLs) -->
-    <key>AdminPrincipals</key>
-    <array>
-      <string>/principals/__uids__/admin/</string>
-    </array>
-
-    <!-- Principals with "DAV:read" access (relative URLs) -->
-    <key>ReadPrincipals</key>
-    <array>
-      <!-- <string>/principals/__uids__/983C8238-FB6B-4D92-9242-89C0A39E5F81/</string> -->
-    </array>
-
-    <!-- Principals that can pose as other principals -->
-    <key>SudoersFile</key>
-    <string>conf/sudoers.plist</string>
-
-    <!-- Create "proxy access" principals -->
-    <key>EnableProxyPrincipals</key>
-    <true/>
-
-
-    <!--
-        Permissions
-      -->
-
-    <!-- Anonymous read access for root resource -->
-    <key>EnableAnonymousReadRoot</key>
-    <true/>
-
-    <!-- Anonymous read access for resource hierarchy -->
-    <key>EnableAnonymousReadNav</key>
-    <false/>
-
-    <!-- Enables directory listings for principals -->
-    <key>EnablePrincipalListings</key>
-    <true/>
-
-    <!-- Render calendar collections as a monolithic iCalendar object -->
-    <key>EnableMonolithicCalendars</key>
-    <true/>
-
-
-    <!--
-        Authentication
-      -->
-
-    <key>Authentication</key>
-    <dict>
-
-      <!-- Clear text; best avoided -->
-      <key>Basic</key>
-      <dict>
-        <key>Enabled</key>
-        <true/>
-      </dict>
-
-      <!-- Digest challenge/response -->
-      <key>Digest</key>
-      <dict>
-        <key>Enabled</key>
-        <true/>
-        <key>Algorithm</key>
-        <string>md5</string>
-        <key>Qop</key>
-        <string></string>
-      </dict>
-
-      <!-- Kerberos/SPNEGO -->
-      <key>Kerberos</key>
-      <dict>
-        <key>Enabled</key>
-        <false/>
-        <key>ServicePrincipal</key>
-        <string></string>
-      </dict>
-
-      <!-- Wikiserver authentication (Mac OS X) -->
-      <key>Wiki</key>
-      <dict>
-        <key>Enabled</key>
-        <true/>
-        <key>Cookie</key>
-        <string>sessionID</string>
-        <key>URL</key>
-        <string>http://127.0.0.1/RPC2</string>
-        <key>UserMethod</key>
-        <string>userForSession</string>
-        <key>WikiMethod</key>
-        <string>accessLevelForUserWikiCalendar</string>
-      </dict>
-
-    </dict>
-
-
-    <!--
-        Logging
-      -->
-
-    <!-- Apache-style access log -->
-    <key>AccessLogFile</key>
-    <string>logs/access.log</string>
-    <key>RotateAccessLog</key>
-    <false/>
-
-    <!-- Server activity log -->
-    <key>ErrorLogFile</key>
-    <string>logs/error.log</string>
-
-    <!-- Log levels -->
-    <key>DefaultLogLevel</key>
-    <string>info</string> <!-- debug, info, warn, error -->
-
-    <!-- Log level overrides for specific functionality -->
-    <key>LogLevels</key>
-    <dict>
-      <!--
-      <key>twistedcaldav.directory.appleopendirectory.OpenDirectoryService</key>
-      <string>debug</string>
-      -->
-    </dict>
-
-    <!-- Global server stats --> 
-    <key>GlobalStatsSocket</key> 
-    <string>logs/caldavd-stats.sock</string> 
-
-    <!-- Global server stats logging period --> 
-    <key>GlobalStatsLoggingPeriod</key> 
-    <integer>60</integer> 
-
-    <!-- Global server stats logging frequency [0 = disable stats] --> 
-    <key>GlobalStatsLoggingFrequency</key> 
-    <integer>12</integer>
-
-    <!-- Server statistics file -->
-    <key>ServerStatsFile</key>
-    <string>logs/stats.plist</string>
-
-    <!-- Server process ID file -->
-    <key>PIDFile</key>
-    <string>logs/caldavd.pid</string>
-
-
-    <!--
-        Accounting
-      -->
-
-    <!-- Enable accounting for certain operations -->
-    <key>AccountingCategories</key>
-    <dict>
-      <key>iTIP</key>
-      <false/>
-      <key>HTTP</key>
-      <false/>
-    </dict>
-    <!-- Enable accounting for specific principals -->
-    <key>AccountingPrincipals</key>
-    <array>
-      <!-- <string>/principals/__uids__/454D85C0-09F0-4DC6-A3C6-97DFEB4622CD/</string> -->
-    </array>
-
-
-    <!--
-        SSL/TLS
-      -->
-
-    <!-- Public key -->
-    <key>SSLCertificate</key>
-    <string>twistedcaldav/test/data/server.pem</string>
-
-    <!-- SSL authority chain (for intermediate certs) -->
-    <key>SSLAuthorityChain</key>
-    <string></string>
-
-    <!-- Private key -->
-    <key>SSLPrivateKey</key>
-    <string>twistedcaldav/test/data/server.pem</string>
-
-
-    <!--
-        Process management
-      -->
-
-    <key>UserName</key>
-    <string></string>
-
-    <key>GroupName</key>
-    <string></string>
-
-    <key>ProcessType</key>
-    <string>Combined</string>
-
-    <key>MultiProcess</key>
-    <dict>
-      <key>ProcessCount</key>
-      <integer>2</integer> <!-- 0 = larger of: 4 or (2 * CPU count) -->
-    </dict>
-
-
-    <!--
-        Notifications
-      -->
-
-    <key>Notifications</key>
-    <dict>
-      <!-- Time spent coalescing notifications before delivery -->
-      <key>CoalesceSeconds</key>
-      <integer>3</integer>
-
-      <key>InternalNotificationHost</key>
-      <string>localhost</string>
-
-      <key>InternalNotificationPort</key>
-      <integer>62309</integer>
-
-      <key>Services</key>
-      <dict>
-        <key>SimpleLineNotifier</key>
-        <dict>
-          <!-- Simple line notification service (for testing) -->
-          <key>Service</key>
-          <string>twistedcaldav.notify.SimpleLineNotifierService</string>
-          <key>Enabled</key>
-          <false/>
-          <key>Port</key>
-          <integer>62308</integer>
-        </dict>
-
-        <key>XMPPNotifier</key>
-        <dict>
-          <!-- XMPP notification service -->
-          <key>Service</key>
-          <string>twistedcaldav.notify.XMPPNotifierService</string>
-          <key>Enabled</key>
-          <false/>
-
-          <!-- XMPP host and port to contact -->
-          <key>Host</key>
-          <string>xmpp.host.name</string>
-          <key>Port</key>
-          <integer>5222</integer>
-
-          <!-- Jabber ID and password for the server -->
-          <key>JID</key>
-          <string>jid at xmpp.host.name/resource</string>
-          <key>Password</key>
-          <string>password_goes_here</string>
-
-          <!-- PubSub service address -->
-          <key>ServiceAddress</key>
-          <string>pubsub.xmpp.host.name</string>
-
-          <key>NodeConfiguration</key>
-          <dict>
-            <key>pubsub#deliver_payloads</key>
-            <string>1</string>
-            <key>pubsub#persist_items</key>
-            <string>1</string>
-          </dict>
-
-          <!-- Sends a presence notification to XMPP server at this interval (prevents disconnect) -->
-          <key>KeepAliveSeconds</key>
-          <integer>120</integer>
-
-          <!-- Sends a pubsub publish to a particular heartbeat node at this interval -->
-          <key>HeartbeatMinutes</key>
-          <integer>30</integer>
-
-          <!-- List of glob-like expressions defining which XMPP JIDs can converse with the server (for debugging) -->
-          <key>AllowedJIDs</key>
-          <array>
-            <!--
-            <string>*.example.com</string>
-             -->
-          </array>
-        </dict>
-      </dict>
-    </dict>
-
-
-    <!--
-        Server-to-server protocol
-      -->
-
-    <key>Scheduling</key>
-    <dict>
-
-      <!-- CalDAV protocol options -->
-      <key>CalDAV</key>
-      <dict>
-        <key>EmailDomain</key>
-        <string></string>
-        <key>HTTPDomain</key>
-        <string></string>
-        <key>AddressPatterns</key>
-        <array>
-        </array>
-        <key>OldDraftCompatibility</key>
-        <true/>
-        <key>ScheduleTagCompatibility</key>
-        <true/>
-        <key>EnablePrivateComments</key>
-        <true/>
-      </dict>
-
-      <!-- iSchedule protocol options -->
-      <key>iSchedule</key>
-      <dict>
-        <key>Enabled</key>
-        <false/>
-        <key>AddressPatterns</key>
-        <array>
-        </array>
-        <key>Servers</key>
-        <string>conf/servertoserver-test.xml</string>
-      </dict>
-
-      <!-- iMIP protocol options -->
-      <key>iMIP</key>
-      <dict>
-        <key>Enabled</key>
-        <false/>
-        <key>MailGatewayServer</key>
-        <string>localhost</string>
-        <key>MailGatewayPort</key>
-        <integer>62310</integer>
-        <key>Sending</key>
-        <dict>
-          <key>Server</key>
-          <string></string>
-          <key>Port</key>
-          <integer>587</integer>
-          <key>UseSSL</key>
-          <true/>
-          <key>Username</key>
-          <string></string>
-          <key>Password</key>
-          <string></string>
-          <key>Address</key>
-          <string></string> <!-- Address email will be sent from -->
-        </dict>
-        <key>Receiving</key>
-        <dict>
-          <key>Server</key>
-          <string></string>
-          <key>Port</key>
-          <integer>995</integer>
-          <key>Type</key>
-          <string></string> <!-- Either "pop" or "imap" -->
-          <key>UseSSL</key>
-          <true/>
-          <key>Username</key>
-          <string></string>
-          <key>Password</key>
-          <string></string>
-          <key>PollingSeconds</key>
-          <integer>30</integer>
-        </dict>
-        <key>AddressPatterns</key>
-        <array>
-          <string>mailto:.*</string>
-        </array>
-      </dict>
-
-	  <!-- General options for scheduling -->
-	  <key>Options</key>
-	  <dict>
-        <key>AllowGroupAsOrganizer</key>
-        <false/>
-        <key>AllowLocationAsOrganizer</key>
-        <false/>
-        <key>AllowResourceAsOrganizer</key>
-        <false/>
-       </dict>
-
-    </dict>
-
-
-    <!--
-        Free-busy URL protocol
-      -->
-
-    <key>FreeBusyURL</key>
-    <dict>
-      <key>Enabled</key>
-      <true/>
-      <key>TimePeriod</key>
-      <integer>14</integer>
-      <key>AnonymousAccess</key>
-      <false/>
-    </dict>
-
-
-    <!--
-        Non-standard CalDAV extensions
-      -->
-
-    <!-- Calendar Drop Box -->
-    <key>EnableDropBox</key>
-    <true/>
-
-    <!-- Private Events -->
-    <key>EnablePrivateEvents</key>
-    <true/>
-
-    <!-- Timezone Service -->
-    <key>EnableTimezoneService</key>
-    <true/>
-
-
-    <!--
-        Miscellaneous items
-      -->
-
-    <!-- Service ACLs (Mac OS X) -->
-    <key>EnableSACLs</key>
-    <false/>
-
-    <!-- Web-based administration -->
-    <key>EnableWebAdmin</key>
-    <true/>
-
-    <!-- Support for Content-Encoding compression options as specified in RFC2616 Section 3.5 -->
-    <key>ResponseCompression</key>
-    <false/>
-    
-    <!-- The retry-after value (in seconds) to return with a 503 error. -->
-    <key>HTTPRetryAfter</key>
-    <integer>180</integer>
-
-    <!-- A unix socket used for communication between the child and master processes.
-         An empty value tells the server to use a tcp socket instead. -->
-    <key>ControlSocket</key>
-    <string>logs/caldavd.sock</string>
-
-    <!-- Support for Memcached -->
-    <key>Memcached</key>
-    <dict>
-      <key>MaxClients</key>
-      <integer>5</integer>
-      <key>memcached</key>
-      <string>memcached</string> <!-- Find in PATH -->
-      <key>Options</key>
-      <array>
-        <!--<string>-vv</string>-->
-      </array>
-    </dict>
-
-    <!-- Response Caching -->
-    <key>ResponseCacheTimeout</key>
-    <integer>30</integer> <!-- in minutes -->
-
-
-    <!--
-        Twisted
-      -->
-
-    <key>Twisted</key>
-    <dict>
-      <key>twistd</key>
-      <string>../Twisted/bin/twistd</string>
-    </dict>
-
-
-    <key>Localization</key>
-    <dict>
-      <key>LocalesDirectory</key>
-      <string>locales</string>
-      <key>Language</key>
-      <string>English</string>
-    </dict>
-
-
-  </dict>
-</plist>

Copied: CalendarServer/trunk/conf/resources/caldavd-resources.plist (from rev 5061, CalendarServer/branches/users/sagen/locations-resources-2/conf/resources/caldavd-resources.plist)
===================================================================
--- CalendarServer/trunk/conf/resources/caldavd-resources.plist	                        (rev 0)
+++ CalendarServer/trunk/conf/resources/caldavd-resources.plist	2010-02-08 23:05:01 UTC (rev 5062)
@@ -0,0 +1,747 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+    Copyright (c) 2006-2010 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 plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+  <dict>
+
+    <!--
+        Public network address information
+
+        This is the server's public network address, which is provided to
+        clients in URLs and the like.  It may or may not be the network
+        address that the server is listening to directly, though it is by
+        default.  For example, it may be the address of a load balancer or
+        proxy which forwards connections to the server.
+      -->
+
+    <!-- Network host name [empty = system host name] -->
+    <key>ServerHostName</key>
+    <string></string> <!-- The hostname clients use when connecting -->
+
+    <!-- HTTP port [0 = disable HTTP] -->
+    <key>HTTPPort</key>
+    <integer>8008</integer>
+
+    <!-- SSL port [0 = disable HTTPS] -->
+    <!-- (Must also configure SSLCertificate and SSLPrivateKey below) -->
+    <key>SSLPort</key>
+    <integer>8443</integer>
+
+    <!-- Redirect non-SSL ports to an SSL port -->
+    <key>RedirectHTTPToHTTPS</key>
+    <false/>
+
+    <!--
+        Network address configuration information
+
+        This configures the actual network address that the server binds to.
+      -->
+
+    <!-- List of IP addresses to bind to [empty = all] -->
+    <key>BindAddresses</key>
+    <array>
+    </array>
+
+    <!-- List of port numbers to bind to for HTTP [empty = same as "Port"] -->
+    <key>BindHTTPPorts</key>
+    <array>
+    </array>
+
+    <!-- List of port numbers to bind to for SSL [empty = same as "SSLPort"] -->
+    <key>BindSSLPorts</key>
+    <array>
+    </array>
+
+
+    <!--
+        Data Store
+      -->
+
+    <!-- Data root -->
+    <key>DataRoot</key>
+    <string>data/</string>
+
+    <!-- Document root -->
+    <key>DocumentRoot</key>
+    <string>twistedcaldav/test/data/</string>
+
+    <!-- Child aliases -->
+    <key>Aliases</key>
+    <dict>
+      <!--
+      <key>foo</key>
+      <dict>
+        <key>path</key>
+        <string>/path/to/foo</string>
+      </dict>
+       -->
+    </dict>
+
+    <!-- User quota (in bytes) -->
+    <key>UserQuota</key>
+    <integer>104857600</integer><!-- 100Mb -->
+
+    <!-- Attachment size limit (in bytes) -->
+    <key>MaximumAttachmentSize</key>
+    <integer>1048576</integer><!-- 1Mb -->
+
+    <!-- Maximum number of unique attendees per entire event -->
+    <!-- 0 for no limit -->
+    <key>MaxAttendeesPerInstance</key>
+    <integer>100</integer>
+
+    <!-- Maximum number of instances allowed for a single RRULE -->
+    <!-- 0 for no limit -->
+    <key>MaxInstancesForRRULE</key>
+    <integer>400</integer>
+
+
+    <!--
+        Directory service
+
+        A directory service provides information about principals (eg.
+        users, groups, locations and resources) to the server.
+
+        A variety of directory services are available for use.
+      -->
+
+    <!-- XML File Directory Service -->
+    <key>DirectoryService</key>
+    <dict>
+      <key>type</key>
+      <string>twistedcaldav.directory.xmlfile.XMLDirectoryService</string>
+      
+      <key>params</key>
+      <dict>
+        <key>xmlFile</key>
+        <string>conf/resources/users-groups.xml</string>
+        <key>recordTypes</key>
+        <array>
+            <string>users</string>
+            <string>groups</string>
+        </array>
+      </dict>
+    </dict>
+    
+    <key>ResourceService</key>
+    <dict>
+      <key>Enabled</key>
+      <true/>
+      <key>type</key>
+      <string>twistedcaldav.directory.xmlfile.XMLDirectoryService</string>
+      
+      <key>params</key>
+      <dict>
+        <key>xmlFile</key>
+        <string>conf/resources/locations-resources.xml</string>
+        <key>recordTypes</key>
+        <array>
+            <string>locations</string>
+            <string>resources</string>
+        </array>
+      </dict>
+    </dict>
+    
+    <!-- Open Directory Service (Mac OS X) -->
+    <!--
+    <key>DirectoryService</key>
+    <dict>
+      <key>type</key>
+      <string>twistedcaldav.directory.appleopendirectory.OpenDirectoryService</string>
+      
+      <key>params</key>
+      <dict>
+        <key>node</key>
+        <string>/Search</string>
+        <key>cacheTimeout</key>
+        <integer>30</integer>
+      </dict>
+    </dict>
+    -->
+
+    <!--
+        Augment service
+
+        Augments for the directory service records to add calendar specific attributes.
+
+        A variety of augment services are available for use.
+        When using a partitioned server, a service that can be accessed from each host will be needed.
+      -->
+
+    <!-- XML File Augment Service -->
+    <key>AugmentService</key>
+    <dict>
+      <key>type</key>
+      <string>twistedcaldav.directory.augment.AugmentXMLDB</string>
+      
+      <key>params</key>
+      <dict>
+        <key>xmlFiles</key>
+        <array>
+	      <string>conf/auth/augments-test.xml</string>
+        </array>
+      </dict>
+    </dict>
+    
+    <!-- Sqlite Augment Service -->
+    <!--
+    <key>AugmentService</key>
+    <dict>
+      <key>type</key>
+      <string>twistedcaldav.directory.augment.AugmentSqliteDB</string>
+      
+      <key>params</key>
+      <dict>
+        <key>dbpath</key>
+        <string>/etc/caldavd/augments.sqlite</string>
+      </dict>
+    </dict>
+     -->
+
+    <!-- PostgreSQL Augment Service -->
+    <!--
+    <key>AugmentService</key>
+    <dict>
+      <key>type</key>
+      <string>twistedcaldav.directory.augment.AugmentPostgreSQLDB</string>
+      
+      <key>params</key>
+      <dict>
+        <key>host</key>
+        <string>localhost</string>
+        <key>database</key>
+        <string>augments</string>
+      </dict>
+    </dict>
+     -->
+
+    <!-- Sqlite ProxyDB Service -->
+    <key>ProxyDBService</key>
+    <dict>
+      <key>type</key>
+      <string>twistedcaldav.directory.calendaruserproxy.ProxySqliteDB</string>
+      
+      <key>params</key>
+      <dict>
+        <key>dbpath</key>
+        <string>data/proxies.sqlite</string>
+      </dict>
+    </dict>
+
+    <!-- PostgreSQL ProxyDB Service -->
+    <!--
+    <key>ProxyDBService</key>
+    <dict>
+      <key>type</key>
+      <string>twistedcaldav.directory.calendaruserproxy.ProxyPostgreSQLDB</string>
+      
+      <key>params</key>
+      <dict>
+        <key>host</key>
+        <string>localhost</string>
+        <key>database</key>
+        <string>proxies</string>
+      </dict>
+    </dict>
+     -->
+
+	<key>ProxyLoadFromFile</key>
+    <string>conf/auth/proxies-test.xml</string>
+
+    <!--
+        Special principals
+
+        These principals are granted special access and/or perform
+        special roles on the server.
+      -->
+
+    <!-- Principals with "DAV:all" access (relative URLs) -->
+    <key>AdminPrincipals</key>
+    <array>
+      <string>/principals/__uids__/admin/</string>
+    </array>
+
+    <!-- Principals with "DAV:read" access (relative URLs) -->
+    <key>ReadPrincipals</key>
+    <array>
+      <!-- <string>/principals/__uids__/983C8238-FB6B-4D92-9242-89C0A39E5F81/</string> -->
+    </array>
+
+    <!-- Principals that can pose as other principals -->
+    <key>SudoersFile</key>
+    <string>conf/sudoers.plist</string>
+
+    <!-- Create "proxy access" principals -->
+    <key>EnableProxyPrincipals</key>
+    <true/>
+
+
+    <!--
+        Permissions
+      -->
+
+    <!-- Anonymous read access for root resource -->
+    <key>EnableAnonymousReadRoot</key>
+    <true/>
+
+    <!-- Anonymous read access for resource hierarchy -->
+    <key>EnableAnonymousReadNav</key>
+    <false/>
+
+    <!-- Enables directory listings for principals -->
+    <key>EnablePrincipalListings</key>
+    <true/>
+
+    <!-- Render calendar collections as a monolithic iCalendar object -->
+    <key>EnableMonolithicCalendars</key>
+    <true/>
+
+
+    <!--
+        Authentication
+      -->
+
+    <key>Authentication</key>
+    <dict>
+
+      <!-- Clear text; best avoided -->
+      <key>Basic</key>
+      <dict>
+        <key>Enabled</key>
+        <true/>
+      </dict>
+
+      <!-- Digest challenge/response -->
+      <key>Digest</key>
+      <dict>
+        <key>Enabled</key>
+        <true/>
+        <key>Algorithm</key>
+        <string>md5</string>
+        <key>Qop</key>
+        <string></string>
+      </dict>
+
+      <!-- Kerberos/SPNEGO -->
+      <key>Kerberos</key>
+      <dict>
+        <key>Enabled</key>
+        <false/>
+        <key>ServicePrincipal</key>
+        <string></string>
+      </dict>
+
+      <!-- Wikiserver authentication (Mac OS X) -->
+      <key>Wiki</key>
+      <dict>
+        <key>Enabled</key>
+        <true/>
+        <key>Cookie</key>
+        <string>sessionID</string>
+        <key>URL</key>
+        <string>http://127.0.0.1/RPC2</string>
+        <key>UserMethod</key>
+        <string>userForSession</string>
+        <key>WikiMethod</key>
+        <string>accessLevelForUserWikiCalendar</string>
+      </dict>
+
+    </dict>
+
+
+    <!--
+        Logging
+      -->
+
+    <!-- Apache-style access log -->
+    <key>AccessLogFile</key>
+    <string>logs/access.log</string>
+    <key>RotateAccessLog</key>
+    <false/>
+
+    <!-- Server activity log -->
+    <key>ErrorLogFile</key>
+    <string>logs/error.log</string>
+
+    <!-- Log levels -->
+    <key>DefaultLogLevel</key>
+    <string>info</string> <!-- debug, info, warn, error -->
+
+    <!-- Log level overrides for specific functionality -->
+    <key>LogLevels</key>
+    <dict>
+      <!--
+      <key>twistedcaldav.directory.appleopendirectory.OpenDirectoryService</key>
+      <string>debug</string>
+      -->
+    </dict>
+
+    <!-- Global server stats --> 
+    <key>GlobalStatsSocket</key> 
+    <string>logs/caldavd-stats.sock</string> 
+
+    <!-- Global server stats logging period --> 
+    <key>GlobalStatsLoggingPeriod</key> 
+    <integer>60</integer> 
+
+    <!-- Global server stats logging frequency [0 = disable stats] --> 
+    <key>GlobalStatsLoggingFrequency</key> 
+    <integer>12</integer>
+
+    <!-- Server statistics file -->
+    <key>ServerStatsFile</key>
+    <string>logs/stats.plist</string>
+
+    <!-- Server process ID file -->
+    <key>PIDFile</key>
+    <string>logs/caldavd.pid</string>
+
+
+    <!--
+        Accounting
+      -->
+
+    <!-- Enable accounting for certain operations -->
+    <key>AccountingCategories</key>
+    <dict>
+      <key>iTIP</key>
+      <false/>
+      <key>HTTP</key>
+      <false/>
+    </dict>
+    <!-- Enable accounting for specific principals -->
+    <key>AccountingPrincipals</key>
+    <array>
+      <!-- <string>/principals/__uids__/454D85C0-09F0-4DC6-A3C6-97DFEB4622CD/</string> -->
+    </array>
+
+
+    <!--
+        SSL/TLS
+      -->
+
+    <!-- Public key -->
+    <key>SSLCertificate</key>
+    <string>twistedcaldav/test/data/server.pem</string>
+
+    <!-- SSL authority chain (for intermediate certs) -->
+    <key>SSLAuthorityChain</key>
+    <string></string>
+
+    <!-- Private key -->
+    <key>SSLPrivateKey</key>
+    <string>twistedcaldav/test/data/server.pem</string>
+
+
+    <!--
+        Process management
+      -->
+
+    <key>UserName</key>
+    <string></string>
+
+    <key>GroupName</key>
+    <string></string>
+
+    <key>ProcessType</key>
+    <string>Combined</string>
+
+    <key>MultiProcess</key>
+    <dict>
+      <key>ProcessCount</key>
+      <integer>2</integer> <!-- 0 = larger of: 4 or (2 * CPU count) -->
+    </dict>
+
+
+    <!--
+        Notifications
+      -->
+
+    <key>Notifications</key>
+    <dict>
+      <!-- Time spent coalescing notifications before delivery -->
+      <key>CoalesceSeconds</key>
+      <integer>3</integer>
+
+      <key>InternalNotificationHost</key>
+      <string>localhost</string>
+
+      <key>InternalNotificationPort</key>
+      <integer>62309</integer>
+
+      <key>Services</key>
+      <dict>
+        <key>SimpleLineNotifier</key>
+        <dict>
+          <!-- Simple line notification service (for testing) -->
+          <key>Service</key>
+          <string>twistedcaldav.notify.SimpleLineNotifierService</string>
+          <key>Enabled</key>
+          <false/>
+          <key>Port</key>
+          <integer>62308</integer>
+        </dict>
+
+        <key>XMPPNotifier</key>
+        <dict>
+          <!-- XMPP notification service -->
+          <key>Service</key>
+          <string>twistedcaldav.notify.XMPPNotifierService</string>
+          <key>Enabled</key>
+          <false/>
+
+          <!-- XMPP host and port to contact -->
+          <key>Host</key>
+          <string>xmpp.host.name</string>
+          <key>Port</key>
+          <integer>5222</integer>
+
+          <!-- Jabber ID and password for the server -->
+          <key>JID</key>
+          <string>jid at xmpp.host.name/resource</string>
+          <key>Password</key>
+          <string>password_goes_here</string>
+
+          <!-- PubSub service address -->
+          <key>ServiceAddress</key>
+          <string>pubsub.xmpp.host.name</string>
+
+          <key>NodeConfiguration</key>
+          <dict>
+            <key>pubsub#deliver_payloads</key>
+            <string>1</string>
+            <key>pubsub#persist_items</key>
+            <string>1</string>
+          </dict>
+
+          <!-- Sends a presence notification to XMPP server at this interval (prevents disconnect) -->
+          <key>KeepAliveSeconds</key>
+          <integer>120</integer>
+
+          <!-- Sends a pubsub publish to a particular heartbeat node at this interval -->
+          <key>HeartbeatMinutes</key>
+          <integer>30</integer>
+
+          <!-- List of glob-like expressions defining which XMPP JIDs can converse with the server (for debugging) -->
+          <key>AllowedJIDs</key>
+          <array>
+            <!--
+            <string>*.example.com</string>
+             -->
+          </array>
+        </dict>
+      </dict>
+    </dict>
+
+
+    <!--
+        Server-to-server protocol
+      -->
+
+    <key>Scheduling</key>
+    <dict>
+
+      <!-- CalDAV protocol options -->
+      <key>CalDAV</key>
+      <dict>
+        <key>EmailDomain</key>
+        <string></string>
+        <key>HTTPDomain</key>
+        <string></string>
+        <key>AddressPatterns</key>
+        <array>
+        </array>
+        <key>OldDraftCompatibility</key>
+        <true/>
+        <key>ScheduleTagCompatibility</key>
+        <true/>
+        <key>EnablePrivateComments</key>
+        <true/>
+      </dict>
+
+      <!-- iSchedule protocol options -->
+      <key>iSchedule</key>
+      <dict>
+        <key>Enabled</key>
+        <false/>
+        <key>AddressPatterns</key>
+        <array>
+        </array>
+        <key>Servers</key>
+        <string>conf/servertoserver-test.xml</string>
+      </dict>
+
+      <!-- iMIP protocol options -->
+      <key>iMIP</key>
+      <dict>
+        <key>Enabled</key>
+        <false/>
+        <key>MailGatewayServer</key>
+        <string>localhost</string>
+        <key>MailGatewayPort</key>
+        <integer>62310</integer>
+        <key>Sending</key>
+        <dict>
+          <key>Server</key>
+          <string></string>
+          <key>Port</key>
+          <integer>587</integer>
+          <key>UseSSL</key>
+          <true/>
+          <key>Username</key>
+          <string></string>
+          <key>Password</key>
+          <string></string>
+          <key>Address</key>
+          <string></string> <!-- Address email will be sent from -->
+        </dict>
+        <key>Receiving</key>
+        <dict>
+          <key>Server</key>
+          <string></string>
+          <key>Port</key>
+          <integer>995</integer>
+          <key>Type</key>
+          <string></string> <!-- Either "pop" or "imap" -->
+          <key>UseSSL</key>
+          <true/>
+          <key>Username</key>
+          <string></string>
+          <key>Password</key>
+          <string></string>
+          <key>PollingSeconds</key>
+          <integer>30</integer>
+        </dict>
+        <key>AddressPatterns</key>
+        <array>
+          <string>mailto:.*</string>
+        </array>
+      </dict>
+
+	  <!-- General options for scheduling -->
+	  <key>Options</key>
+	  <dict>
+        <key>AllowGroupAsOrganizer</key>
+        <false/>
+        <key>AllowLocationAsOrganizer</key>
+        <false/>
+        <key>AllowResourceAsOrganizer</key>
+        <false/>
+       </dict>
+
+    </dict>
+
+
+    <!--
+        Free-busy URL protocol
+      -->
+
+    <key>FreeBusyURL</key>
+    <dict>
+      <key>Enabled</key>
+      <true/>
+      <key>TimePeriod</key>
+      <integer>14</integer>
+      <key>AnonymousAccess</key>
+      <false/>
+    </dict>
+
+
+    <!--
+        Non-standard CalDAV extensions
+      -->
+
+    <!-- Calendar Drop Box -->
+    <key>EnableDropBox</key>
+    <true/>
+
+    <!-- Private Events -->
+    <key>EnablePrivateEvents</key>
+    <true/>
+
+    <!-- Timezone Service -->
+    <key>EnableTimezoneService</key>
+    <true/>
+
+
+    <!--
+        Miscellaneous items
+      -->
+
+    <!-- Service ACLs (Mac OS X) -->
+    <key>EnableSACLs</key>
+    <false/>
+
+    <!-- Web-based administration -->
+    <key>EnableWebAdmin</key>
+    <true/>
+
+    <!-- Support for Content-Encoding compression options as specified in RFC2616 Section 3.5 -->
+    <key>ResponseCompression</key>
+    <false/>
+    
+    <!-- The retry-after value (in seconds) to return with a 503 error. -->
+    <key>HTTPRetryAfter</key>
+    <integer>180</integer>
+
+    <!-- A unix socket used for communication between the child and master processes.
+         An empty value tells the server to use a tcp socket instead. -->
+    <key>ControlSocket</key>
+    <string>logs/caldavd.sock</string>
+
+    <!-- Support for Memcached -->
+    <key>Memcached</key>
+    <dict>
+      <key>MaxClients</key>
+      <integer>5</integer>
+      <key>memcached</key>
+      <string>memcached</string> <!-- Find in PATH -->
+      <key>Options</key>
+      <array>
+        <!--<string>-vv</string>-->
+      </array>
+    </dict>
+
+    <!-- Response Caching -->
+    <key>ResponseCacheTimeout</key>
+    <integer>30</integer> <!-- in minutes -->
+
+
+    <!--
+        Twisted
+      -->
+
+    <key>Twisted</key>
+    <dict>
+      <key>twistd</key>
+      <string>../Twisted/bin/twistd</string>
+    </dict>
+
+
+    <key>Localization</key>
+    <dict>
+      <key>LocalesDirectory</key>
+      <string>locales</string>
+      <key>Language</key>
+      <string>English</string>
+    </dict>
+
+
+  </dict>
+</plist>

Deleted: CalendarServer/trunk/conf/resources/locations-resources-orig.xml
===================================================================
--- CalendarServer/branches/users/sagen/locations-resources-2/conf/resources/locations-resources-orig.xml	2010-02-08 22:31:59 UTC (rev 5061)
+++ CalendarServer/trunk/conf/resources/locations-resources-orig.xml	2010-02-08 23:05:01 UTC (rev 5062)
@@ -1,34 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<!--
-Copyright (c) 2006-2010 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>
-  <resource repeat="10">
-    <uid>resource%02d</uid>
-    <guid>resource%02d</guid>
-    <password>resource%02d</password>
-    <name>Resource %02d</name>
-  </resource>
-</accounts>

Copied: CalendarServer/trunk/conf/resources/locations-resources-orig.xml (from rev 5061, CalendarServer/branches/users/sagen/locations-resources-2/conf/resources/locations-resources-orig.xml)
===================================================================
--- CalendarServer/trunk/conf/resources/locations-resources-orig.xml	                        (rev 0)
+++ CalendarServer/trunk/conf/resources/locations-resources-orig.xml	2010-02-08 23:05:01 UTC (rev 5062)
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+Copyright (c) 2006-2010 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>
+  <resource repeat="10">
+    <uid>resource%02d</uid>
+    <guid>resource%02d</guid>
+    <password>resource%02d</password>
+    <name>Resource %02d</name>
+  </resource>
+</accounts>

Deleted: CalendarServer/trunk/conf/resources/locations-resources.xml
===================================================================
--- CalendarServer/branches/users/sagen/locations-resources-2/conf/resources/locations-resources.xml	2010-02-08 22:31:59 UTC (rev 5061)
+++ CalendarServer/trunk/conf/resources/locations-resources.xml	2010-02-08 23:05:01 UTC (rev 5062)
@@ -1,34 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<!--
-Copyright (c) 2006-2010 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>
-  <resource repeat="10">
-    <uid>resource%02d</uid>
-    <guid>resource%02d</guid>
-    <password>resource%02d</password>
-    <name>Resource %02d</name>
-  </resource>
-</accounts>

Copied: CalendarServer/trunk/conf/resources/locations-resources.xml (from rev 5061, CalendarServer/branches/users/sagen/locations-resources-2/conf/resources/locations-resources.xml)
===================================================================
--- CalendarServer/trunk/conf/resources/locations-resources.xml	                        (rev 0)
+++ CalendarServer/trunk/conf/resources/locations-resources.xml	2010-02-08 23:05:01 UTC (rev 5062)
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+Copyright (c) 2006-2010 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>
+  <resource repeat="10">
+    <uid>resource%02d</uid>
+    <guid>resource%02d</guid>
+    <password>resource%02d</password>
+    <name>Resource %02d</name>
+  </resource>
+</accounts>

Deleted: CalendarServer/trunk/conf/resources/users-groups.xml
===================================================================
--- CalendarServer/branches/users/sagen/locations-resources-2/conf/resources/users-groups.xml	2010-02-08 22:31:59 UTC (rev 5061)
+++ CalendarServer/trunk/conf/resources/users-groups.xml	2010-02-08 23:05:01 UTC (rev 5062)
@@ -1,105 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<!--
-Copyright (c) 2006-2010 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">
-  <user>
-    <uid>admin</uid>
-    <guid>admin</guid>
-    <password>admin</password>
-    <name>Super User</name>
-    <first-name>Super</first-name>
-    <last-name>User</last-name>
-  </user>
-  <user>
-    <uid>apprentice</uid>
-    <guid>apprentice</guid>
-    <password>apprentice</password>
-    <name>Apprentice Super User</name>
-    <first-name>Apprentice</first-name>
-    <last-name>Super User</last-name>
-  </user>
-  <user repeat="99">
-    <uid>user%02d</uid>
-    <uid>User %02d</uid>
-    <guid>user%02d</guid>
-    <password>user%02d</password>
-    <name>User %02d</name>
-    <first-name>User</first-name>
-    <last-name>%02d</last-name>
-    <email-address>user%02d at example.com</email-address>
-  </user>
-  <user repeat="10">
-    <uid>public%02d</uid>
-    <guid>public%02d</guid>
-    <password>public%02d</password>
-    <name>Public %02d</name>
-    <first-name>Public</first-name>
-    <last-name>%02d</last-name>
-  </user>
-  <group>
-    <uid>group01</uid>
-    <guid>group01</guid>
-    <password>group01</password>
-    <name>Group 01</name>
-    <members>
-      <member type="users">user01</member>
-    </members>
-  </group>
-  <group>
-    <uid>group02</uid>
-    <guid>group02</guid>
-    <password>group02</password>
-    <name>Group 02</name>
-    <members>
-      <member type="users">user06</member>
-      <member type="users">user07</member>
-    </members>
-  </group>
-  <group>
-    <uid>group03</uid>
-    <guid>group03</guid>
-    <password>group03</password>
-    <name>Group 03</name>
-    <members>
-      <member type="users">user08</member>
-      <member type="users">user09</member>
-    </members>
-  </group>
-  <group>
-    <uid>group04</uid>
-    <guid>group04</guid>
-    <password>group04</password>
-    <name>Group 04</name>
-    <members>
-      <member type="groups">group02</member>
-      <member type="groups">group03</member>
-      <member type="users">user10</member>
-    </members>
-  </group>
-  <group>
-    <uid>disabledgroup</uid>
-    <guid>disabledgroup</guid>
-    <password>disabledgroup</password>
-    <name>Disabled Group</name>
-    <members>
-      <member type="users">user01</member>
-    </members>
-  </group>
-</accounts>

Copied: CalendarServer/trunk/conf/resources/users-groups.xml (from rev 5061, CalendarServer/branches/users/sagen/locations-resources-2/conf/resources/users-groups.xml)
===================================================================
--- CalendarServer/trunk/conf/resources/users-groups.xml	                        (rev 0)
+++ CalendarServer/trunk/conf/resources/users-groups.xml	2010-02-08 23:05:01 UTC (rev 5062)
@@ -0,0 +1,105 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+Copyright (c) 2006-2010 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">
+  <user>
+    <uid>admin</uid>
+    <guid>admin</guid>
+    <password>admin</password>
+    <name>Super User</name>
+    <first-name>Super</first-name>
+    <last-name>User</last-name>
+  </user>
+  <user>
+    <uid>apprentice</uid>
+    <guid>apprentice</guid>
+    <password>apprentice</password>
+    <name>Apprentice Super User</name>
+    <first-name>Apprentice</first-name>
+    <last-name>Super User</last-name>
+  </user>
+  <user repeat="99">
+    <uid>user%02d</uid>
+    <uid>User %02d</uid>
+    <guid>user%02d</guid>
+    <password>user%02d</password>
+    <name>User %02d</name>
+    <first-name>User</first-name>
+    <last-name>%02d</last-name>
+    <email-address>user%02d at example.com</email-address>
+  </user>
+  <user repeat="10">
+    <uid>public%02d</uid>
+    <guid>public%02d</guid>
+    <password>public%02d</password>
+    <name>Public %02d</name>
+    <first-name>Public</first-name>
+    <last-name>%02d</last-name>
+  </user>
+  <group>
+    <uid>group01</uid>
+    <guid>group01</guid>
+    <password>group01</password>
+    <name>Group 01</name>
+    <members>
+      <member type="users">user01</member>
+    </members>
+  </group>
+  <group>
+    <uid>group02</uid>
+    <guid>group02</guid>
+    <password>group02</password>
+    <name>Group 02</name>
+    <members>
+      <member type="users">user06</member>
+      <member type="users">user07</member>
+    </members>
+  </group>
+  <group>
+    <uid>group03</uid>
+    <guid>group03</guid>
+    <password>group03</password>
+    <name>Group 03</name>
+    <members>
+      <member type="users">user08</member>
+      <member type="users">user09</member>
+    </members>
+  </group>
+  <group>
+    <uid>group04</uid>
+    <guid>group04</guid>
+    <password>group04</password>
+    <name>Group 04</name>
+    <members>
+      <member type="groups">group02</member>
+      <member type="groups">group03</member>
+      <member type="users">user10</member>
+    </members>
+  </group>
+  <group>
+    <uid>disabledgroup</uid>
+    <guid>disabledgroup</guid>
+    <password>disabledgroup</password>
+    <name>Disabled Group</name>
+    <members>
+      <member type="users">user01</member>
+    </members>
+  </group>
+</accounts>

Copied: CalendarServer/trunk/conf/resources.xml (from rev 5061, CalendarServer/branches/users/sagen/locations-resources-2/conf/resources.xml)
===================================================================
--- CalendarServer/trunk/conf/resources.xml	                        (rev 0)
+++ CalendarServer/trunk/conf/resources.xml	2010-02-08 23:05:01 UTC (rev 5062)
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+Copyright (c) 2006-2010 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="/Search">
+</accounts>

Modified: CalendarServer/trunk/python
===================================================================
--- CalendarServer/trunk/python	2010-02-08 22:31:59 UTC (rev 5061)
+++ CalendarServer/trunk/python	2010-02-08 23:05:01 UTC (rev 5062)
@@ -4,4 +4,4 @@
 
 export PYTHONPATH="$("${wd}/run" -p)";
 
-python "$@";
+exec python "$@";

Modified: CalendarServer/trunk/setup.py
===================================================================
--- CalendarServer/trunk/setup.py	2010-02-08 22:31:59 UTC (rev 5061)
+++ CalendarServer/trunk/setup.py	2010-02-08 23:05:01 UTC (rev 5062)
@@ -108,7 +108,8 @@
     scripts          = [
                          "bin/caldavd",
                          "bin/calendarserver_export",
-                         "bin/calendarserver_manage_principals"
+                         "bin/calendarserver_manage_principals",
+                         "bin/calendarserver_command_gateway"
                        ],
     data_files       = [ ("caldavd", ["conf/caldavd.plist"]) ],
     ext_modules      = extensions,

Modified: CalendarServer/trunk/twistedcaldav/directory/aggregate.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/directory/aggregate.py	2010-02-08 22:31:59 UTC (rev 5061)
+++ CalendarServer/trunk/twistedcaldav/directory/aggregate.py	2010-02-08 23:05:01 UTC (rev 5062)
@@ -145,12 +145,20 @@
 
     def _queryAll(self, query, *args):
         for service in self._recordTypes.values():
-            record = getattr(service, query)(*args)
+            try:
+                record = getattr(service, query)(*args)
+            except UnknownRecordTypeError:
+                record = None
             if record is not None:
                 return record
         else:
             return None
 
+    def flushCaches(self):
+        for service in self._recordTypes.values():
+            if hasattr(service, "_initCaches"):
+                service._initCaches()
+
     userRecordTypes = [DirectoryService.recordType_users]
 
     def requestAvatarId(self, credentials):
@@ -168,6 +176,28 @@
                     results.append(result)
         return results
 
+    def createRecord(self, recordType, guid=None, shortNames=(), authIDs=set(),
+        fullName=None, firstName=None, lastName=None, emailAddresses=set(),
+        uid=None, password=None, **kwds):
+        service = self.serviceForRecordType(recordType)
+        return service.createRecord(recordType, guid=guid,
+            shortNames=shortNames, authIDs=authIDs, fullName=fullName,
+            firstName=firstName, lastName=lastName,
+            emailAddresses=emailAddresses, uid=uid, password=password, **kwds)
+
+    def updateRecord(self, recordType, guid, shortNames=(), authIDs=set(),
+        fullName=None, firstName=None, lastName=None, emailAddresses=set(),
+        uid=None, password=None, **kwds):
+        service = self.serviceForRecordType(recordType)
+        return service.updateRecord(recordType, guid, shortNames=shortNames,
+            authIDs=authIDs, fullName=fullName, firstName=firstName,
+            lastName=lastName, emailAddresses=emailAddresses, uid=uid,
+            password=password, **kwds)
+
+    def destroyRecord(self, recordType, guid):
+        service = self.serviceForRecordType(recordType)
+        return service.destroyRecord(recordType, guid)
+
 class DuplicateRecordTypeError(DirectoryError):
     """
     Duplicate record type.

Modified: CalendarServer/trunk/twistedcaldav/directory/appleopendirectory.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/directory/appleopendirectory.py	2010-02-08 22:31:59 UTC (rev 5061)
+++ CalendarServer/trunk/twistedcaldav/directory/appleopendirectory.py	2010-02-08 23:05:01 UTC (rev 5062)
@@ -64,6 +64,12 @@
         defaults = {
             'node' : '/Search',
             'cacheTimeout' : 30,
+            'recordTypes' : (
+                self.recordType_users,
+                self.recordType_groups,
+                self.recordType_locations,
+                self.recordType_resources,
+            ),
         }
         ignored = (
             'requireComputerRecord',
@@ -72,6 +78,8 @@
         )
         params = self.getParams(params, defaults, ignored)
 
+        self._recordTypes = params['recordTypes']
+
         super(OpenDirectoryService, self).__init__(params['cacheTimeout'])
 
         try:
@@ -161,12 +169,7 @@
                 yield GUID
 
     def recordTypes(self):
-        return (
-            self.recordType_users,
-            self.recordType_groups,
-            self.recordType_locations,
-            self.recordType_resources,
-        )
+        return self._recordTypes
 
     def groupsForGUID(self, guid):
         

Modified: CalendarServer/trunk/twistedcaldav/directory/cachingdirectory.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/directory/cachingdirectory.py	2010-02-08 22:31:59 UTC (rev 5061)
+++ CalendarServer/trunk/twistedcaldav/directory/cachingdirectory.py	2010-02-08 23:05:01 UTC (rev 5062)
@@ -73,6 +73,7 @@
             CachingDirectoryService.INDEX_TYPE_CUA    : {},
             CachingDirectoryService.INDEX_TYPE_AUTHID   : {},
         }
+        self.directoryService = directoryService
 
     def addRecord(self, record, indexType, indexKey, useMemcache=True,
         neverExpire=False):
@@ -92,7 +93,9 @@
         for indexType, indexKey in indexTypes:
             self.recordsIndexedBy[indexType][indexKey] = record
             if useMemcache:
-                key = "dir|%s|%s" % (indexType, indexKey)
+                key = "dir|%s|%s|%s|%s" % (self.directoryService.baseGUID,
+                    indexType, indexKey,
+                    "|".join(self.directoryService.recordTypes()))
                 self.log_debug("Memcache: storing %s" % (key,))
                 try:
                     self.directoryService.memcacheSet(key, record)
@@ -150,7 +153,8 @@
         
         self.cacheTimeout = cacheTimeout * 60
 
-        self._initCaches(cacheClass)
+        self.cacheClass = cacheClass
+        self._initCaches()
 
         super(CachingDirectoryService, self).__init__()
 
@@ -200,9 +204,9 @@
                 raise DirectoryMemcacheError("Failed to read from memcache")
         return record
 
-    def _initCaches(self, cacheClass):
+    def _initCaches(self):
         self._recordCaches = dict([
-            (recordType, cacheClass(self, recordType))
+            (recordType, self.cacheClass(self, recordType))
             for recordType in self.recordTypes()
         ])
             
@@ -291,7 +295,8 @@
             
             # Check memcache
             if config.Memcached.Pools.Default.ClientEnabled:
-                key = "dir|%s|%s" % (indexType, indexKey)
+                key = "dir|%s|%s|%s|%s" % (self.baseGUID, indexType, indexKey,
+                    "|".join(self.recordTypes()))
                 self.log_debug("Memcache: checking %s" % (key,))
 
                 try:
@@ -328,7 +333,6 @@
                 self.log_debug("Found record for attribute '%s' with value '%s'" % (indexType, indexKey,))
                 return record
 
-
             # Add to negative cache with timestamp
             self.log_debug("Failed to fault record for attribute '%s' with value '%s'" % (indexType, indexKey,))
             self._disabledKeys[indexType][indexKey] = time.time()

Modified: CalendarServer/trunk/twistedcaldav/directory/directory.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/directory/directory.py	2010-02-08 22:31:59 UTC (rev 5061)
+++ CalendarServer/trunk/twistedcaldav/directory/directory.py	2010-02-08 23:05:01 UTC (rev 5062)
@@ -282,6 +282,29 @@
         return result
 
 
+    def createRecord(self, recordType, guid=None, shortNames=(), authIDs=set(),
+        fullName=None, firstName=None, lastName=None, emailAddresses=set(),
+        uid=None, password=None, **kwds):
+        """
+        Create/persist a directory record based on the given values
+        """
+        raise NotImplementedError("Subclass must implement createRecord")
+
+    def updateRecord(self, recordType, guid, shortNames=(), authIDs=set(),
+        fullName=None, firstName=None, lastName=None, emailAddresses=set(),
+        uid=None, password=None, **kwds):
+        """
+        Update/persist a directory record based on the given values
+        """
+        raise NotImplementedError("Subclass must implement updateRecord")
+
+    def destroyRecord(self, recordType, guid):
+        """
+        Remove a directory record from the directory
+        """
+        raise NotImplementedError("Subclass must implement destroyRecord")
+
+
 class DirectoryRecord(LoggingMixIn):
     implements(IDirectoryRecord)
 

Modified: CalendarServer/trunk/twistedcaldav/directory/test/accounts.xml
===================================================================
--- CalendarServer/trunk/twistedcaldav/directory/test/accounts.xml	2010-02-08 22:31:59 UTC (rev 5061)
+++ CalendarServer/trunk/twistedcaldav/directory/test/accounts.xml	2010-02-08 23:05:01 UTC (rev 5062)
@@ -54,13 +54,6 @@
     <email-address>dreid at example.com</email-address>
   </user>
   <user>
-    <uid>sagen</uid>
-    <guid>34360DAD-9BDE-4508-3C34-250394720345</guid>
-    <password>negas</password>
-    <name>Morgen Sagen</name>
-    <email-address>sagen at example.com</email-address>
-  </user>
-  <user>
     <uid>nocalendar</uid>
     <guid>543D28BA-F74F-4D5F-9243-B3E3A61171E5</guid>
     <password>radnelacon</password>

Deleted: CalendarServer/trunk/twistedcaldav/directory/test/modify/augments.xml
===================================================================
--- CalendarServer/branches/users/sagen/locations-resources-2/twistedcaldav/directory/test/modify/augments.xml	2010-02-08 22:31:59 UTC (rev 5061)
+++ CalendarServer/trunk/twistedcaldav/directory/test/modify/augments.xml	2010-02-08 23:05:01 UTC (rev 5062)
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<!--
-Copyright (c) 2009-2010 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 "../../../conf/auth/augments.dtd">
-
-<augments>
-  <record>
-    <guid>user01</guid>
-    <enable>true</enable>
-    <enable-calendar>true</enable-calendar>
-  </record>
-  <record>
-    <guid>user02</guid>
-    <enable>false</enable>
-    <enable-calendar>false</enable-calendar>
-  </record>
-</augments>

Copied: CalendarServer/trunk/twistedcaldav/directory/test/modify/augments.xml (from rev 5061, CalendarServer/branches/users/sagen/locations-resources-2/twistedcaldav/directory/test/modify/augments.xml)
===================================================================
--- CalendarServer/trunk/twistedcaldav/directory/test/modify/augments.xml	                        (rev 0)
+++ CalendarServer/trunk/twistedcaldav/directory/test/modify/augments.xml	2010-02-08 23:05:01 UTC (rev 5062)
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+Copyright (c) 2009-2010 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 "../../../conf/auth/augments.dtd">
+
+<augments>
+  <record>
+    <guid>user01</guid>
+    <enable>true</enable>
+    <enable-calendar>true</enable-calendar>
+  </record>
+  <record>
+    <guid>user02</guid>
+    <enable>false</enable>
+    <enable-calendar>false</enable-calendar>
+  </record>
+</augments>

Deleted: CalendarServer/trunk/twistedcaldav/directory/test/modify/caldavd.plist
===================================================================
--- CalendarServer/branches/users/sagen/locations-resources-2/twistedcaldav/directory/test/modify/caldavd.plist	2010-02-08 22:31:59 UTC (rev 5061)
+++ CalendarServer/trunk/twistedcaldav/directory/test/modify/caldavd.plist	2010-02-08 23:05:01 UTC (rev 5062)
@@ -1,748 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-
-<!--
-    Copyright (c) 2006-2010 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 plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-  <dict>
-
-    <!--
-        Public network address information
-
-        This is the server's public network address, which is provided to
-        clients in URLs and the like.  It may or may not be the network
-        address that the server is listening to directly, though it is by
-        default.  For example, it may be the address of a load balancer or
-        proxy which forwards connections to the server.
-      -->
-
-    <!-- Network host name [empty = system host name] -->
-    <key>ServerHostName</key>
-    <string></string> <!-- The hostname clients use when connecting -->
-
-    <!-- HTTP port [0 = disable HTTP] -->
-    <key>HTTPPort</key>
-    <integer>8008</integer>
-
-    <!-- SSL port [0 = disable HTTPS] -->
-    <!-- (Must also configure SSLCertificate and SSLPrivateKey below) -->
-    <key>SSLPort</key>
-    <integer>8443</integer>
-
-    <!-- Redirect non-SSL ports to an SSL port -->
-    <key>RedirectHTTPToHTTPS</key>
-    <false/>
-
-    <!--
-        Network address configuration information
-
-        This configures the actual network address that the server binds to.
-      -->
-
-    <!-- List of IP addresses to bind to [empty = all] -->
-    <key>BindAddresses</key>
-    <array>
-    </array>
-
-    <!-- List of port numbers to bind to for HTTP [empty = same as "Port"] -->
-    <key>BindHTTPPorts</key>
-    <array>
-    </array>
-
-    <!-- List of port numbers to bind to for SSL [empty = same as "SSLPort"] -->
-    <key>BindSSLPorts</key>
-    <array>
-    </array>
-
-
-    <!--
-        Data Store
-      -->
-
-    <!-- Data root -->
-    <key>DataRoot</key>
-    <string>data/</string>
-
-    <!-- Document root -->
-    <key>DocumentRoot</key>
-    <string>twistedcaldav/test/data/</string>
-
-    <!-- Child aliases -->
-    <key>Aliases</key>
-    <dict>
-      <!--
-      <key>foo</key>
-      <dict>
-        <key>path</key>
-        <string>/path/to/foo</string>
-      </dict>
-       -->
-    </dict>
-
-    <!-- User quota (in bytes) -->
-    <key>UserQuota</key>
-    <integer>104857600</integer><!-- 100Mb -->
-
-    <!-- Attachment size limit (in bytes) -->
-    <key>MaximumAttachmentSize</key>
-    <integer>1048576</integer><!-- 1Mb -->
-
-    <!-- Maximum number of unique attendees per entire event -->
-    <!-- 0 for no limit -->
-    <key>MaxAttendeesPerInstance</key>
-    <integer>100</integer>
-
-    <!-- Maximum number of instances allowed for a single RRULE -->
-    <!-- 0 for no limit -->
-    <key>MaxInstancesForRRULE</key>
-    <integer>400</integer>
-
-
-    <!--
-        Directory service
-
-        A directory service provides information about principals (eg.
-        users, groups, locations and resources) to the server.
-
-        A variety of directory services are available for use.
-      -->
-
-    <!-- XML File Directory Service -->
-    <key>DirectoryService</key>
-    <dict>
-      <key>type</key>
-      <string>twistedcaldav.directory.xmlfile.XMLDirectoryService</string>
-      
-      <key>params</key>
-      <dict>
-        <key>xmlFile</key>
-        <string>SET IN TEST</string>
-        <key>recordTypes</key>
-        <array>
-            <string>users</string>
-            <string>groups</string>
-        </array>
-      </dict>
-    </dict>
-
-    <!-- XML File Resource Service -->
-    <key>ResourceService</key>
-    <dict>
-      <key>Enabled</key>
-      <true/>
-      <key>type</key>
-      <string>twistedcaldav.directory.xmlfile.XMLDirectoryService</string>
-      
-      <key>params</key>
-      <dict>
-        <key>xmlFile</key>
-        <string>SET IN TEST</string>
-        <key>recordTypes</key>
-        <array>
-            <string>resources</string>
-            <string>locations</string>
-        </array>
-      </dict>
-    </dict>
-    
-    <!-- Open Directory Service (Mac OS X) -->
-    <!--
-    <key>DirectoryService</key>
-    <dict>
-      <key>type</key>
-      <string>twistedcaldav.directory.appleopendirectory.OpenDirectoryService</string>
-      
-      <key>params</key>
-      <dict>
-        <key>node</key>
-        <string>/Search</string>
-        <key>cacheTimeout</key>
-        <integer>30</integer>
-      </dict>
-    </dict>
-    -->
-
-    <!--
-        Augment service
-
-        Augments for the directory service records to add calendar specific attributes.
-
-        A variety of augment services are available for use.
-        When using a partitioned server, a service that can be accessed from each host will be needed.
-      -->
-
-    <!-- XML File Augment Service -->
-    <key>AugmentService</key>
-    <dict>
-      <key>type</key>
-      <string>twistedcaldav.directory.augment.AugmentXMLDB</string>
-      
-      <key>params</key>
-      <dict>
-        <key>xmlFiles</key>
-        <array>
-	      <string>SET IN TEST</string>
-        </array>
-      </dict>
-    </dict>
-    
-    <!-- Sqlite Augment Service -->
-    <!--
-    <key>AugmentService</key>
-    <dict>
-      <key>type</key>
-      <string>twistedcaldav.directory.augment.AugmentSqliteDB</string>
-      
-      <key>params</key>
-      <dict>
-        <key>dbpath</key>
-        <string>/etc/caldavd/augments.sqlite</string>
-      </dict>
-    </dict>
-     -->
-
-    <!-- PostgreSQL Augment Service -->
-    <!--
-    <key>AugmentService</key>
-    <dict>
-      <key>type</key>
-      <string>twistedcaldav.directory.augment.AugmentPostgreSQLDB</string>
-      
-      <key>params</key>
-      <dict>
-        <key>host</key>
-        <string>localhost</string>
-        <key>database</key>
-        <string>augments</string>
-      </dict>
-    </dict>
-     -->
-
-    <!-- Sqlite ProxyDB Service -->
-    <key>ProxyDBService</key>
-    <dict>
-      <key>type</key>
-      <string>twistedcaldav.directory.calendaruserproxy.ProxySqliteDB</string>
-      
-      <key>params</key>
-      <dict>
-        <key>dbpath</key>
-        <string>data/proxies.sqlite</string>
-      </dict>
-    </dict>
-
-    <!-- PostgreSQL ProxyDB Service -->
-    <!--
-    <key>ProxyDBService</key>
-    <dict>
-      <key>type</key>
-      <string>twistedcaldav.directory.calendaruserproxy.ProxyPostgreSQLDB</string>
-      
-      <key>params</key>
-      <dict>
-        <key>host</key>
-        <string>localhost</string>
-        <key>database</key>
-        <string>proxies</string>
-      </dict>
-    </dict>
-     -->
-
-	<key>ProxyLoadFromFile</key>
-    <string>conf/auth/proxies-test.xml</string>
-
-    <!--
-        Special principals
-
-        These principals are granted special access and/or perform
-        special roles on the server.
-      -->
-
-    <!-- Principals with "DAV:all" access (relative URLs) -->
-    <key>AdminPrincipals</key>
-    <array>
-      <string>/principals/__uids__/admin/</string>
-    </array>
-
-    <!-- Principals with "DAV:read" access (relative URLs) -->
-    <key>ReadPrincipals</key>
-    <array>
-      <!-- <string>/principals/__uids__/983C8238-FB6B-4D92-9242-89C0A39E5F81/</string> -->
-    </array>
-
-    <!-- Principals that can pose as other principals -->
-    <key>SudoersFile</key>
-    <string>conf/sudoers.plist</string>
-
-    <!-- Create "proxy access" principals -->
-    <key>EnableProxyPrincipals</key>
-    <true/>
-
-
-    <!--
-        Permissions
-      -->
-
-    <!-- Anonymous read access for root resource -->
-    <key>EnableAnonymousReadRoot</key>
-    <true/>
-
-    <!-- Anonymous read access for resource hierarchy -->
-    <key>EnableAnonymousReadNav</key>
-    <false/>
-
-    <!-- Enables directory listings for principals -->
-    <key>EnablePrincipalListings</key>
-    <true/>
-
-    <!-- Render calendar collections as a monolithic iCalendar object -->
-    <key>EnableMonolithicCalendars</key>
-    <true/>
-
-
-    <!--
-        Authentication
-      -->
-
-    <key>Authentication</key>
-    <dict>
-
-      <!-- Clear text; best avoided -->
-      <key>Basic</key>
-      <dict>
-        <key>Enabled</key>
-        <true/>
-      </dict>
-
-      <!-- Digest challenge/response -->
-      <key>Digest</key>
-      <dict>
-        <key>Enabled</key>
-        <true/>
-        <key>Algorithm</key>
-        <string>md5</string>
-        <key>Qop</key>
-        <string></string>
-      </dict>
-
-      <!-- Kerberos/SPNEGO -->
-      <key>Kerberos</key>
-      <dict>
-        <key>Enabled</key>
-        <false/>
-        <key>ServicePrincipal</key>
-        <string></string>
-      </dict>
-
-      <!-- Wikiserver authentication (Mac OS X) -->
-      <key>Wiki</key>
-      <dict>
-        <key>Enabled</key>
-        <true/>
-        <key>Cookie</key>
-        <string>sessionID</string>
-        <key>URL</key>
-        <string>http://127.0.0.1/RPC2</string>
-        <key>UserMethod</key>
-        <string>userForSession</string>
-        <key>WikiMethod</key>
-        <string>accessLevelForUserWikiCalendar</string>
-      </dict>
-
-    </dict>
-
-
-    <!--
-        Logging
-      -->
-
-    <!-- Apache-style access log -->
-    <key>AccessLogFile</key>
-    <string>logs/access.log</string>
-    <key>RotateAccessLog</key>
-    <false/>
-
-    <!-- Server activity log -->
-    <key>ErrorLogFile</key>
-    <string>logs/error.log</string>
-
-    <!-- Log levels -->
-    <key>DefaultLogLevel</key>
-    <string>info</string> <!-- debug, info, warn, error -->
-
-    <!-- Log level overrides for specific functionality -->
-    <key>LogLevels</key>
-    <dict>
-      <!--
-      <key>twistedcaldav.directory.appleopendirectory.OpenDirectoryService</key>
-      <string>debug</string>
-      -->
-    </dict>
-
-    <!-- Global server stats --> 
-    <key>GlobalStatsSocket</key> 
-    <string>logs/caldavd-stats.sock</string> 
-
-    <!-- Global server stats logging period --> 
-    <key>GlobalStatsLoggingPeriod</key> 
-    <integer>60</integer> 
-
-    <!-- Global server stats logging frequency [0 = disable stats] --> 
-    <key>GlobalStatsLoggingFrequency</key> 
-    <integer>12</integer>
-
-    <!-- Server statistics file -->
-    <key>ServerStatsFile</key>
-    <string>logs/stats.plist</string>
-
-    <!-- Server process ID file -->
-    <key>PIDFile</key>
-    <string>logs/caldavd.pid</string>
-
-
-    <!--
-        Accounting
-      -->
-
-    <!-- Enable accounting for certain operations -->
-    <key>AccountingCategories</key>
-    <dict>
-      <key>iTIP</key>
-      <false/>
-      <key>HTTP</key>
-      <false/>
-    </dict>
-    <!-- Enable accounting for specific principals -->
-    <key>AccountingPrincipals</key>
-    <array>
-      <!-- <string>/principals/__uids__/454D85C0-09F0-4DC6-A3C6-97DFEB4622CD/</string> -->
-    </array>
-
-
-    <!--
-        SSL/TLS
-      -->
-
-    <!-- Public key -->
-    <key>SSLCertificate</key>
-    <string>twistedcaldav/test/data/server.pem</string>
-
-    <!-- SSL authority chain (for intermediate certs) -->
-    <key>SSLAuthorityChain</key>
-    <string></string>
-
-    <!-- Private key -->
-    <key>SSLPrivateKey</key>
-    <string>twistedcaldav/test/data/server.pem</string>
-
-
-    <!--
-        Process management
-      -->
-
-    <key>UserName</key>
-    <string></string>
-
-    <key>GroupName</key>
-    <string></string>
-
-    <key>ProcessType</key>
-    <string>Combined</string>
-
-    <key>MultiProcess</key>
-    <dict>
-      <key>ProcessCount</key>
-      <integer>2</integer> <!-- 0 = larger of: 4 or (2 * CPU count) -->
-    </dict>
-
-
-    <!--
-        Notifications
-      -->
-
-    <key>Notifications</key>
-    <dict>
-      <!-- Time spent coalescing notifications before delivery -->
-      <key>CoalesceSeconds</key>
-      <integer>3</integer>
-
-      <key>InternalNotificationHost</key>
-      <string>localhost</string>
-
-      <key>InternalNotificationPort</key>
-      <integer>62309</integer>
-
-      <key>Services</key>
-      <dict>
-        <key>SimpleLineNotifier</key>
-        <dict>
-          <!-- Simple line notification service (for testing) -->
-          <key>Service</key>
-          <string>twistedcaldav.notify.SimpleLineNotifierService</string>
-          <key>Enabled</key>
-          <false/>
-          <key>Port</key>
-          <integer>62308</integer>
-        </dict>
-
-        <key>XMPPNotifier</key>
-        <dict>
-          <!-- XMPP notification service -->
-          <key>Service</key>
-          <string>twistedcaldav.notify.XMPPNotifierService</string>
-          <key>Enabled</key>
-          <false/>
-
-          <!-- XMPP host and port to contact -->
-          <key>Host</key>
-          <string>xmpp.host.name</string>
-          <key>Port</key>
-          <integer>5222</integer>
-
-          <!-- Jabber ID and password for the server -->
-          <key>JID</key>
-          <string>jid at xmpp.host.name/resource</string>
-          <key>Password</key>
-          <string>password_goes_here</string>
-
-          <!-- PubSub service address -->
-          <key>ServiceAddress</key>
-          <string>pubsub.xmpp.host.name</string>
-
-          <key>NodeConfiguration</key>
-          <dict>
-            <key>pubsub#deliver_payloads</key>
-            <string>1</string>
-            <key>pubsub#persist_items</key>
-            <string>1</string>
-          </dict>
-
-          <!-- Sends a presence notification to XMPP server at this interval (prevents disconnect) -->
-          <key>KeepAliveSeconds</key>
-          <integer>120</integer>
-
-          <!-- Sends a pubsub publish to a particular heartbeat node at this interval -->
-          <key>HeartbeatMinutes</key>
-          <integer>30</integer>
-
-          <!-- List of glob-like expressions defining which XMPP JIDs can converse with the server (for debugging) -->
-          <key>AllowedJIDs</key>
-          <array>
-            <!--
-            <string>*.example.com</string>
-             -->
-          </array>
-        </dict>
-      </dict>
-    </dict>
-
-
-    <!--
-        Server-to-server protocol
-      -->
-
-    <key>Scheduling</key>
-    <dict>
-
-      <!-- CalDAV protocol options -->
-      <key>CalDAV</key>
-      <dict>
-        <key>EmailDomain</key>
-        <string></string>
-        <key>HTTPDomain</key>
-        <string></string>
-        <key>AddressPatterns</key>
-        <array>
-        </array>
-        <key>OldDraftCompatibility</key>
-        <true/>
-        <key>ScheduleTagCompatibility</key>
-        <true/>
-        <key>EnablePrivateComments</key>
-        <true/>
-      </dict>
-
-      <!-- iSchedule protocol options -->
-      <key>iSchedule</key>
-      <dict>
-        <key>Enabled</key>
-        <false/>
-        <key>AddressPatterns</key>
-        <array>
-        </array>
-        <key>Servers</key>
-        <string>conf/servertoserver-test.xml</string>
-      </dict>
-
-      <!-- iMIP protocol options -->
-      <key>iMIP</key>
-      <dict>
-        <key>Enabled</key>
-        <false/>
-        <key>MailGatewayServer</key>
-        <string>localhost</string>
-        <key>MailGatewayPort</key>
-        <integer>62310</integer>
-        <key>Sending</key>
-        <dict>
-          <key>Server</key>
-          <string></string>
-          <key>Port</key>
-          <integer>587</integer>
-          <key>UseSSL</key>
-          <true/>
-          <key>Username</key>
-          <string></string>
-          <key>Password</key>
-          <string></string>
-          <key>Address</key>
-          <string></string> <!-- Address email will be sent from -->
-        </dict>
-        <key>Receiving</key>
-        <dict>
-          <key>Server</key>
-          <string></string>
-          <key>Port</key>
-          <integer>995</integer>
-          <key>Type</key>
-          <string></string> <!-- Either "pop" or "imap" -->
-          <key>UseSSL</key>
-          <true/>
-          <key>Username</key>
-          <string></string>
-          <key>Password</key>
-          <string></string>
-          <key>PollingSeconds</key>
-          <integer>30</integer>
-        </dict>
-        <key>AddressPatterns</key>
-        <array>
-          <string>mailto:.*</string>
-        </array>
-      </dict>
-
-	  <!-- General options for scheduling -->
-	  <key>Options</key>
-	  <dict>
-        <key>AllowGroupAsOrganizer</key>
-        <false/>
-        <key>AllowLocationAsOrganizer</key>
-        <false/>
-        <key>AllowResourceAsOrganizer</key>
-        <false/>
-       </dict>
-
-    </dict>
-
-
-    <!--
-        Free-busy URL protocol
-      -->
-
-    <key>FreeBusyURL</key>
-    <dict>
-      <key>Enabled</key>
-      <true/>
-      <key>TimePeriod</key>
-      <integer>14</integer>
-      <key>AnonymousAccess</key>
-      <false/>
-    </dict>
-
-
-    <!--
-        Non-standard CalDAV extensions
-      -->
-
-    <!-- Calendar Drop Box -->
-    <key>EnableDropBox</key>
-    <true/>
-
-    <!-- Private Events -->
-    <key>EnablePrivateEvents</key>
-    <true/>
-
-    <!-- Timezone Service -->
-    <key>EnableTimezoneService</key>
-    <true/>
-
-
-    <!--
-        Miscellaneous items
-      -->
-
-    <!-- Service ACLs (Mac OS X) -->
-    <key>EnableSACLs</key>
-    <false/>
-
-    <!-- Web-based administration -->
-    <key>EnableWebAdmin</key>
-    <true/>
-
-    <!-- Support for Content-Encoding compression options as specified in RFC2616 Section 3.5 -->
-    <key>ResponseCompression</key>
-    <false/>
-    
-    <!-- The retry-after value (in seconds) to return with a 503 error. -->
-    <key>HTTPRetryAfter</key>
-    <integer>180</integer>
-
-    <!-- A unix socket used for communication between the child and master processes.
-         An empty value tells the server to use a tcp socket instead. -->
-    <key>ControlSocket</key>
-    <string>logs/caldavd.sock</string>
-
-    <!-- Support for Memcached -->
-    <key>Memcached</key>
-    <dict>
-      <key>MaxClients</key>
-      <integer>5</integer>
-      <key>memcached</key>
-      <string>memcached</string> <!-- Find in PATH -->
-      <key>Options</key>
-      <array>
-        <!--<string>-vv</string>-->
-      </array>
-    </dict>
-
-    <!-- Response Caching -->
-    <key>ResponseCacheTimeout</key>
-    <integer>30</integer> <!-- in minutes -->
-
-
-    <!--
-        Twisted
-      -->
-
-    <key>Twisted</key>
-    <dict>
-      <key>twistd</key>
-      <string>../Twisted/bin/twistd</string>
-    </dict>
-
-
-    <key>Localization</key>
-    <dict>
-      <key>LocalesDirectory</key>
-      <string>locales</string>
-      <key>Language</key>
-      <string>English</string>
-    </dict>
-
-
-  </dict>
-</plist>

Copied: CalendarServer/trunk/twistedcaldav/directory/test/modify/caldavd.plist (from rev 5061, CalendarServer/branches/users/sagen/locations-resources-2/twistedcaldav/directory/test/modify/caldavd.plist)
===================================================================
--- CalendarServer/trunk/twistedcaldav/directory/test/modify/caldavd.plist	                        (rev 0)
+++ CalendarServer/trunk/twistedcaldav/directory/test/modify/caldavd.plist	2010-02-08 23:05:01 UTC (rev 5062)
@@ -0,0 +1,748 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+    Copyright (c) 2006-2010 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 plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+  <dict>
+
+    <!--
+        Public network address information
+
+        This is the server's public network address, which is provided to
+        clients in URLs and the like.  It may or may not be the network
+        address that the server is listening to directly, though it is by
+        default.  For example, it may be the address of a load balancer or
+        proxy which forwards connections to the server.
+      -->
+
+    <!-- Network host name [empty = system host name] -->
+    <key>ServerHostName</key>
+    <string></string> <!-- The hostname clients use when connecting -->
+
+    <!-- HTTP port [0 = disable HTTP] -->
+    <key>HTTPPort</key>
+    <integer>8008</integer>
+
+    <!-- SSL port [0 = disable HTTPS] -->
+    <!-- (Must also configure SSLCertificate and SSLPrivateKey below) -->
+    <key>SSLPort</key>
+    <integer>8443</integer>
+
+    <!-- Redirect non-SSL ports to an SSL port -->
+    <key>RedirectHTTPToHTTPS</key>
+    <false/>
+
+    <!--
+        Network address configuration information
+
+        This configures the actual network address that the server binds to.
+      -->
+
+    <!-- List of IP addresses to bind to [empty = all] -->
+    <key>BindAddresses</key>
+    <array>
+    </array>
+
+    <!-- List of port numbers to bind to for HTTP [empty = same as "Port"] -->
+    <key>BindHTTPPorts</key>
+    <array>
+    </array>
+
+    <!-- List of port numbers to bind to for SSL [empty = same as "SSLPort"] -->
+    <key>BindSSLPorts</key>
+    <array>
+    </array>
+
+
+    <!--
+        Data Store
+      -->
+
+    <!-- Data root -->
+    <key>DataRoot</key>
+    <string>data/</string>
+
+    <!-- Document root -->
+    <key>DocumentRoot</key>
+    <string>twistedcaldav/test/data/</string>
+
+    <!-- Child aliases -->
+    <key>Aliases</key>
+    <dict>
+      <!--
+      <key>foo</key>
+      <dict>
+        <key>path</key>
+        <string>/path/to/foo</string>
+      </dict>
+       -->
+    </dict>
+
+    <!-- User quota (in bytes) -->
+    <key>UserQuota</key>
+    <integer>104857600</integer><!-- 100Mb -->
+
+    <!-- Attachment size limit (in bytes) -->
+    <key>MaximumAttachmentSize</key>
+    <integer>1048576</integer><!-- 1Mb -->
+
+    <!-- Maximum number of unique attendees per entire event -->
+    <!-- 0 for no limit -->
+    <key>MaxAttendeesPerInstance</key>
+    <integer>100</integer>
+
+    <!-- Maximum number of instances allowed for a single RRULE -->
+    <!-- 0 for no limit -->
+    <key>MaxInstancesForRRULE</key>
+    <integer>400</integer>
+
+
+    <!--
+        Directory service
+
+        A directory service provides information about principals (eg.
+        users, groups, locations and resources) to the server.
+
+        A variety of directory services are available for use.
+      -->
+
+    <!-- XML File Directory Service -->
+    <key>DirectoryService</key>
+    <dict>
+      <key>type</key>
+      <string>twistedcaldav.directory.xmlfile.XMLDirectoryService</string>
+      
+      <key>params</key>
+      <dict>
+        <key>xmlFile</key>
+        <string>SET IN TEST</string>
+        <key>recordTypes</key>
+        <array>
+            <string>users</string>
+            <string>groups</string>
+        </array>
+      </dict>
+    </dict>
+
+    <!-- XML File Resource Service -->
+    <key>ResourceService</key>
+    <dict>
+      <key>Enabled</key>
+      <true/>
+      <key>type</key>
+      <string>twistedcaldav.directory.xmlfile.XMLDirectoryService</string>
+      
+      <key>params</key>
+      <dict>
+        <key>xmlFile</key>
+        <string>SET IN TEST</string>
+        <key>recordTypes</key>
+        <array>
+            <string>resources</string>
+            <string>locations</string>
+        </array>
+      </dict>
+    </dict>
+    
+    <!-- Open Directory Service (Mac OS X) -->
+    <!--
+    <key>DirectoryService</key>
+    <dict>
+      <key>type</key>
+      <string>twistedcaldav.directory.appleopendirectory.OpenDirectoryService</string>
+      
+      <key>params</key>
+      <dict>
+        <key>node</key>
+        <string>/Search</string>
+        <key>cacheTimeout</key>
+        <integer>30</integer>
+      </dict>
+    </dict>
+    -->
+
+    <!--
+        Augment service
+
+        Augments for the directory service records to add calendar specific attributes.
+
+        A variety of augment services are available for use.
+        When using a partitioned server, a service that can be accessed from each host will be needed.
+      -->
+
+    <!-- XML File Augment Service -->
+    <key>AugmentService</key>
+    <dict>
+      <key>type</key>
+      <string>twistedcaldav.directory.augment.AugmentXMLDB</string>
+      
+      <key>params</key>
+      <dict>
+        <key>xmlFiles</key>
+        <array>
+	      <string>SET IN TEST</string>
+        </array>
+      </dict>
+    </dict>
+    
+    <!-- Sqlite Augment Service -->
+    <!--
+    <key>AugmentService</key>
+    <dict>
+      <key>type</key>
+      <string>twistedcaldav.directory.augment.AugmentSqliteDB</string>
+      
+      <key>params</key>
+      <dict>
+        <key>dbpath</key>
+        <string>/etc/caldavd/augments.sqlite</string>
+      </dict>
+    </dict>
+     -->
+
+    <!-- PostgreSQL Augment Service -->
+    <!--
+    <key>AugmentService</key>
+    <dict>
+      <key>type</key>
+      <string>twistedcaldav.directory.augment.AugmentPostgreSQLDB</string>
+      
+      <key>params</key>
+      <dict>
+        <key>host</key>
+        <string>localhost</string>
+        <key>database</key>
+        <string>augments</string>
+      </dict>
+    </dict>
+     -->
+
+    <!-- Sqlite ProxyDB Service -->
+    <key>ProxyDBService</key>
+    <dict>
+      <key>type</key>
+      <string>twistedcaldav.directory.calendaruserproxy.ProxySqliteDB</string>
+      
+      <key>params</key>
+      <dict>
+        <key>dbpath</key>
+        <string>data/proxies.sqlite</string>
+      </dict>
+    </dict>
+
+    <!-- PostgreSQL ProxyDB Service -->
+    <!--
+    <key>ProxyDBService</key>
+    <dict>
+      <key>type</key>
+      <string>twistedcaldav.directory.calendaruserproxy.ProxyPostgreSQLDB</string>
+      
+      <key>params</key>
+      <dict>
+        <key>host</key>
+        <string>localhost</string>
+        <key>database</key>
+        <string>proxies</string>
+      </dict>
+    </dict>
+     -->
+
+	<key>ProxyLoadFromFile</key>
+    <string>conf/auth/proxies-test.xml</string>
+
+    <!--
+        Special principals
+
+        These principals are granted special access and/or perform
+        special roles on the server.
+      -->
+
+    <!-- Principals with "DAV:all" access (relative URLs) -->
+    <key>AdminPrincipals</key>
+    <array>
+      <string>/principals/__uids__/admin/</string>
+    </array>
+
+    <!-- Principals with "DAV:read" access (relative URLs) -->
+    <key>ReadPrincipals</key>
+    <array>
+      <!-- <string>/principals/__uids__/983C8238-FB6B-4D92-9242-89C0A39E5F81/</string> -->
+    </array>
+
+    <!-- Principals that can pose as other principals -->
+    <key>SudoersFile</key>
+    <string>conf/sudoers.plist</string>
+
+    <!-- Create "proxy access" principals -->
+    <key>EnableProxyPrincipals</key>
+    <true/>
+
+
+    <!--
+        Permissions
+      -->
+
+    <!-- Anonymous read access for root resource -->
+    <key>EnableAnonymousReadRoot</key>
+    <true/>
+
+    <!-- Anonymous read access for resource hierarchy -->
+    <key>EnableAnonymousReadNav</key>
+    <false/>
+
+    <!-- Enables directory listings for principals -->
+    <key>EnablePrincipalListings</key>
+    <true/>
+
+    <!-- Render calendar collections as a monolithic iCalendar object -->
+    <key>EnableMonolithicCalendars</key>
+    <true/>
+
+
+    <!--
+        Authentication
+      -->
+
+    <key>Authentication</key>
+    <dict>
+
+      <!-- Clear text; best avoided -->
+      <key>Basic</key>
+      <dict>
+        <key>Enabled</key>
+        <true/>
+      </dict>
+
+      <!-- Digest challenge/response -->
+      <key>Digest</key>
+      <dict>
+        <key>Enabled</key>
+        <true/>
+        <key>Algorithm</key>
+        <string>md5</string>
+        <key>Qop</key>
+        <string></string>
+      </dict>
+
+      <!-- Kerberos/SPNEGO -->
+      <key>Kerberos</key>
+      <dict>
+        <key>Enabled</key>
+        <false/>
+        <key>ServicePrincipal</key>
+        <string></string>
+      </dict>
+
+      <!-- Wikiserver authentication (Mac OS X) -->
+      <key>Wiki</key>
+      <dict>
+        <key>Enabled</key>
+        <true/>
+        <key>Cookie</key>
+        <string>sessionID</string>
+        <key>URL</key>
+        <string>http://127.0.0.1/RPC2</string>
+        <key>UserMethod</key>
+        <string>userForSession</string>
+        <key>WikiMethod</key>
+        <string>accessLevelForUserWikiCalendar</string>
+      </dict>
+
+    </dict>
+
+
+    <!--
+        Logging
+      -->
+
+    <!-- Apache-style access log -->
+    <key>AccessLogFile</key>
+    <string>logs/access.log</string>
+    <key>RotateAccessLog</key>
+    <false/>
+
+    <!-- Server activity log -->
+    <key>ErrorLogFile</key>
+    <string>logs/error.log</string>
+
+    <!-- Log levels -->
+    <key>DefaultLogLevel</key>
+    <string>info</string> <!-- debug, info, warn, error -->
+
+    <!-- Log level overrides for specific functionality -->
+    <key>LogLevels</key>
+    <dict>
+      <!--
+      <key>twistedcaldav.directory.appleopendirectory.OpenDirectoryService</key>
+      <string>debug</string>
+      -->
+    </dict>
+
+    <!-- Global server stats --> 
+    <key>GlobalStatsSocket</key> 
+    <string>logs/caldavd-stats.sock</string> 
+
+    <!-- Global server stats logging period --> 
+    <key>GlobalStatsLoggingPeriod</key> 
+    <integer>60</integer> 
+
+    <!-- Global server stats logging frequency [0 = disable stats] --> 
+    <key>GlobalStatsLoggingFrequency</key> 
+    <integer>12</integer>
+
+    <!-- Server statistics file -->
+    <key>ServerStatsFile</key>
+    <string>logs/stats.plist</string>
+
+    <!-- Server process ID file -->
+    <key>PIDFile</key>
+    <string>logs/caldavd.pid</string>
+
+
+    <!--
+        Accounting
+      -->
+
+    <!-- Enable accounting for certain operations -->
+    <key>AccountingCategories</key>
+    <dict>
+      <key>iTIP</key>
+      <false/>
+      <key>HTTP</key>
+      <false/>
+    </dict>
+    <!-- Enable accounting for specific principals -->
+    <key>AccountingPrincipals</key>
+    <array>
+      <!-- <string>/principals/__uids__/454D85C0-09F0-4DC6-A3C6-97DFEB4622CD/</string> -->
+    </array>
+
+
+    <!--
+        SSL/TLS
+      -->
+
+    <!-- Public key -->
+    <key>SSLCertificate</key>
+    <string>twistedcaldav/test/data/server.pem</string>
+
+    <!-- SSL authority chain (for intermediate certs) -->
+    <key>SSLAuthorityChain</key>
+    <string></string>
+
+    <!-- Private key -->
+    <key>SSLPrivateKey</key>
+    <string>twistedcaldav/test/data/server.pem</string>
+
+
+    <!--
+        Process management
+      -->
+
+    <key>UserName</key>
+    <string></string>
+
+    <key>GroupName</key>
+    <string></string>
+
+    <key>ProcessType</key>
+    <string>Combined</string>
+
+    <key>MultiProcess</key>
+    <dict>
+      <key>ProcessCount</key>
+      <integer>2</integer> <!-- 0 = larger of: 4 or (2 * CPU count) -->
+    </dict>
+
+
+    <!--
+        Notifications
+      -->
+
+    <key>Notifications</key>
+    <dict>
+      <!-- Time spent coalescing notifications before delivery -->
+      <key>CoalesceSeconds</key>
+      <integer>3</integer>
+
+      <key>InternalNotificationHost</key>
+      <string>localhost</string>
+
+      <key>InternalNotificationPort</key>
+      <integer>62309</integer>
+
+      <key>Services</key>
+      <dict>
+        <key>SimpleLineNotifier</key>
+        <dict>
+          <!-- Simple line notification service (for testing) -->
+          <key>Service</key>
+          <string>twistedcaldav.notify.SimpleLineNotifierService</string>
+          <key>Enabled</key>
+          <false/>
+          <key>Port</key>
+          <integer>62308</integer>
+        </dict>
+
+        <key>XMPPNotifier</key>
+        <dict>
+          <!-- XMPP notification service -->
+          <key>Service</key>
+          <string>twistedcaldav.notify.XMPPNotifierService</string>
+          <key>Enabled</key>
+          <false/>
+
+          <!-- XMPP host and port to contact -->
+          <key>Host</key>
+          <string>xmpp.host.name</string>
+          <key>Port</key>
+          <integer>5222</integer>
+
+          <!-- Jabber ID and password for the server -->
+          <key>JID</key>
+          <string>jid at xmpp.host.name/resource</string>
+          <key>Password</key>
+          <string>password_goes_here</string>
+
+          <!-- PubSub service address -->
+          <key>ServiceAddress</key>
+          <string>pubsub.xmpp.host.name</string>
+
+          <key>NodeConfiguration</key>
+          <dict>
+            <key>pubsub#deliver_payloads</key>
+            <string>1</string>
+            <key>pubsub#persist_items</key>
+            <string>1</string>
+          </dict>
+
+          <!-- Sends a presence notification to XMPP server at this interval (prevents disconnect) -->
+          <key>KeepAliveSeconds</key>
+          <integer>120</integer>
+
+          <!-- Sends a pubsub publish to a particular heartbeat node at this interval -->
+          <key>HeartbeatMinutes</key>
+          <integer>30</integer>
+
+          <!-- List of glob-like expressions defining which XMPP JIDs can converse with the server (for debugging) -->
+          <key>AllowedJIDs</key>
+          <array>
+            <!--
+            <string>*.example.com</string>
+             -->
+          </array>
+        </dict>
+      </dict>
+    </dict>
+
+
+    <!--
+        Server-to-server protocol
+      -->
+
+    <key>Scheduling</key>
+    <dict>
+
+      <!-- CalDAV protocol options -->
+      <key>CalDAV</key>
+      <dict>
+        <key>EmailDomain</key>
+        <string></string>
+        <key>HTTPDomain</key>
+        <string></string>
+        <key>AddressPatterns</key>
+        <array>
+        </array>
+        <key>OldDraftCompatibility</key>
+        <true/>
+        <key>ScheduleTagCompatibility</key>
+        <true/>
+        <key>EnablePrivateComments</key>
+        <true/>
+      </dict>
+
+      <!-- iSchedule protocol options -->
+      <key>iSchedule</key>
+      <dict>
+        <key>Enabled</key>
+        <false/>
+        <key>AddressPatterns</key>
+        <array>
+        </array>
+        <key>Servers</key>
+        <string>conf/servertoserver-test.xml</string>
+      </dict>
+
+      <!-- iMIP protocol options -->
+      <key>iMIP</key>
+      <dict>
+        <key>Enabled</key>
+        <false/>
+        <key>MailGatewayServer</key>
+        <string>localhost</string>
+        <key>MailGatewayPort</key>
+        <integer>62310</integer>
+        <key>Sending</key>
+        <dict>
+          <key>Server</key>
+          <string></string>
+          <key>Port</key>
+          <integer>587</integer>
+          <key>UseSSL</key>
+          <true/>
+          <key>Username</key>
+          <string></string>
+          <key>Password</key>
+          <string></string>
+          <key>Address</key>
+          <string></string> <!-- Address email will be sent from -->
+        </dict>
+        <key>Receiving</key>
+        <dict>
+          <key>Server</key>
+          <string></string>
+          <key>Port</key>
+          <integer>995</integer>
+          <key>Type</key>
+          <string></string> <!-- Either "pop" or "imap" -->
+          <key>UseSSL</key>
+          <true/>
+          <key>Username</key>
+          <string></string>
+          <key>Password</key>
+          <string></string>
+          <key>PollingSeconds</key>
+          <integer>30</integer>
+        </dict>
+        <key>AddressPatterns</key>
+        <array>
+          <string>mailto:.*</string>
+        </array>
+      </dict>
+
+	  <!-- General options for scheduling -->
+	  <key>Options</key>
+	  <dict>
+        <key>AllowGroupAsOrganizer</key>
+        <false/>
+        <key>AllowLocationAsOrganizer</key>
+        <false/>
+        <key>AllowResourceAsOrganizer</key>
+        <false/>
+       </dict>
+
+    </dict>
+
+
+    <!--
+        Free-busy URL protocol
+      -->
+
+    <key>FreeBusyURL</key>
+    <dict>
+      <key>Enabled</key>
+      <true/>
+      <key>TimePeriod</key>
+      <integer>14</integer>
+      <key>AnonymousAccess</key>
+      <false/>
+    </dict>
+
+
+    <!--
+        Non-standard CalDAV extensions
+      -->
+
+    <!-- Calendar Drop Box -->
+    <key>EnableDropBox</key>
+    <true/>
+
+    <!-- Private Events -->
+    <key>EnablePrivateEvents</key>
+    <true/>
+
+    <!-- Timezone Service -->
+    <key>EnableTimezoneService</key>
+    <true/>
+
+
+    <!--
+        Miscellaneous items
+      -->
+
+    <!-- Service ACLs (Mac OS X) -->
+    <key>EnableSACLs</key>
+    <false/>
+
+    <!-- Web-based administration -->
+    <key>EnableWebAdmin</key>
+    <true/>
+
+    <!-- Support for Content-Encoding compression options as specified in RFC2616 Section 3.5 -->
+    <key>ResponseCompression</key>
+    <false/>
+    
+    <!-- The retry-after value (in seconds) to return with a 503 error. -->
+    <key>HTTPRetryAfter</key>
+    <integer>180</integer>
+
+    <!-- A unix socket used for communication between the child and master processes.
+         An empty value tells the server to use a tcp socket instead. -->
+    <key>ControlSocket</key>
+    <string>logs/caldavd.sock</string>
+
+    <!-- Support for Memcached -->
+    <key>Memcached</key>
+    <dict>
+      <key>MaxClients</key>
+      <integer>5</integer>
+      <key>memcached</key>
+      <string>memcached</string> <!-- Find in PATH -->
+      <key>Options</key>
+      <array>
+        <!--<string>-vv</string>-->
+      </array>
+    </dict>
+
+    <!-- Response Caching -->
+    <key>ResponseCacheTimeout</key>
+    <integer>30</integer> <!-- in minutes -->
+
+
+    <!--
+        Twisted
+      -->
+
+    <key>Twisted</key>
+    <dict>
+      <key>twistd</key>
+      <string>../Twisted/bin/twistd</string>
+    </dict>
+
+
+    <key>Localization</key>
+    <dict>
+      <key>LocalesDirectory</key>
+      <string>locales</string>
+      <key>Language</key>
+      <string>English</string>
+    </dict>
+
+
+  </dict>
+</plist>

Deleted: CalendarServer/trunk/twistedcaldav/directory/test/modify/resources-locations.xml
===================================================================
--- CalendarServer/branches/users/sagen/locations-resources-2/twistedcaldav/directory/test/modify/resources-locations.xml	2010-02-08 22:31:59 UTC (rev 5061)
+++ CalendarServer/trunk/twistedcaldav/directory/test/modify/resources-locations.xml	2010-02-08 23:05:01 UTC (rev 5062)
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<!--
-Copyright (c) 2006-2010 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>
-    <uid>location01</uid>
-    <guid>location01</guid>
-    <password>test</password>
-    <name>Room 01</name>
-  </location>
-</accounts>

Copied: CalendarServer/trunk/twistedcaldav/directory/test/modify/resources-locations.xml (from rev 5061, CalendarServer/branches/users/sagen/locations-resources-2/twistedcaldav/directory/test/modify/resources-locations.xml)
===================================================================
--- CalendarServer/trunk/twistedcaldav/directory/test/modify/resources-locations.xml	                        (rev 0)
+++ CalendarServer/trunk/twistedcaldav/directory/test/modify/resources-locations.xml	2010-02-08 23:05:01 UTC (rev 5062)
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+Copyright (c) 2006-2010 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>
+    <uid>location01</uid>
+    <guid>location01</guid>
+    <password>test</password>
+    <name>Room 01</name>
+  </location>
+</accounts>

Deleted: CalendarServer/trunk/twistedcaldav/directory/test/modify/users-groups.xml
===================================================================
--- CalendarServer/branches/users/sagen/locations-resources-2/twistedcaldav/directory/test/modify/users-groups.xml	2010-02-08 22:31:59 UTC (rev 5061)
+++ CalendarServer/trunk/twistedcaldav/directory/test/modify/users-groups.xml	2010-02-08 23:05:01 UTC (rev 5062)
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<!--
-Copyright (c) 2006-2010 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">
-  <user repeat="10">
-    <uid>user%02d</uid>
-    <guid>user%02d</guid>
-    <password>test</password>
-    <name>Test User %02d</name>
-    <first-name>Test</first-name>
-    <last-name>User %02d</last-name>
-  </user>
-  <group>
-    <uid>testgroup1</uid>
-    <guid>e5a6142c-4189-4e9e-90b0-9cd0268b314b</guid>
-    <password>test</password>
-    <name>Group 01</name>
-    <members>
-      <member type="users">user01</member>
-      <member type="users">user02</member>
-    </members>
-  </group>
-</accounts>

Copied: CalendarServer/trunk/twistedcaldav/directory/test/modify/users-groups.xml (from rev 5061, CalendarServer/branches/users/sagen/locations-resources-2/twistedcaldav/directory/test/modify/users-groups.xml)
===================================================================
--- CalendarServer/trunk/twistedcaldav/directory/test/modify/users-groups.xml	                        (rev 0)
+++ CalendarServer/trunk/twistedcaldav/directory/test/modify/users-groups.xml	2010-02-08 23:05:01 UTC (rev 5062)
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+Copyright (c) 2006-2010 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">
+  <user repeat="10">
+    <uid>user%02d</uid>
+    <guid>user%02d</guid>
+    <password>test</password>
+    <name>Test User %02d</name>
+    <first-name>Test</first-name>
+    <last-name>User %02d</last-name>
+  </user>
+  <group>
+    <uid>testgroup1</uid>
+    <guid>e5a6142c-4189-4e9e-90b0-9cd0268b314b</guid>
+    <password>test</password>
+    <name>Group 01</name>
+    <members>
+      <member type="users">user01</member>
+      <member type="users">user02</member>
+    </members>
+  </group>
+</accounts>

Deleted: CalendarServer/trunk/twistedcaldav/directory/test/resources/augments.xml
===================================================================
--- CalendarServer/branches/users/sagen/locations-resources-2/twistedcaldav/directory/test/resources/augments.xml	2010-02-08 22:31:59 UTC (rev 5061)
+++ CalendarServer/trunk/twistedcaldav/directory/test/resources/augments.xml	2010-02-08 23:05:01 UTC (rev 5062)
@@ -1,44 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<!--
-Copyright (c) 2009-2010 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 "../../../conf/auth/augments.dtd">
-
-<augments>
-  <record>
-    <guid>user01</guid>
-    <enable>true</enable>
-    <enable-calendar>true</enable-calendar>
-  </record>
-  <record>
-    <guid>user02</guid>
-    <enable>false</enable>
-    <enable-calendar>false</enable-calendar>
-  </record>
-  <record>
-    <guid>resource01</guid>
-    <enable>true</enable>
-    <enable-calendar>true</enable-calendar>
-    <auto-schedule>true</auto-schedule>
-  </record>
-  <record>
-    <guid>resource02</guid>
-    <enable>false</enable>
-    <enable-calendar>false</enable-calendar>
-    <auto-schedule>false</auto-schedule>
-  </record>
-</augments>

Copied: CalendarServer/trunk/twistedcaldav/directory/test/resources/augments.xml (from rev 5061, CalendarServer/branches/users/sagen/locations-resources-2/twistedcaldav/directory/test/resources/augments.xml)
===================================================================
--- CalendarServer/trunk/twistedcaldav/directory/test/resources/augments.xml	                        (rev 0)
+++ CalendarServer/trunk/twistedcaldav/directory/test/resources/augments.xml	2010-02-08 23:05:01 UTC (rev 5062)
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+Copyright (c) 2009-2010 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 "../../../conf/auth/augments.dtd">
+
+<augments>
+  <record>
+    <guid>user01</guid>
+    <enable>true</enable>
+    <enable-calendar>true</enable-calendar>
+  </record>
+  <record>
+    <guid>user02</guid>
+    <enable>false</enable>
+    <enable-calendar>false</enable-calendar>
+  </record>
+  <record>
+    <guid>resource01</guid>
+    <enable>true</enable>
+    <enable-calendar>true</enable-calendar>
+    <auto-schedule>true</auto-schedule>
+  </record>
+  <record>
+    <guid>resource02</guid>
+    <enable>false</enable>
+    <enable-calendar>false</enable-calendar>
+    <auto-schedule>false</auto-schedule>
+  </record>
+</augments>

Deleted: CalendarServer/trunk/twistedcaldav/directory/test/resources/caldavd.plist
===================================================================
--- CalendarServer/branches/users/sagen/locations-resources-2/twistedcaldav/directory/test/resources/caldavd.plist	2010-02-08 22:31:59 UTC (rev 5061)
+++ CalendarServer/trunk/twistedcaldav/directory/test/resources/caldavd.plist	2010-02-08 23:05:01 UTC (rev 5062)
@@ -1,748 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-
-<!--
-    Copyright (c) 2006-2010 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 plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-  <dict>
-
-    <!--
-        Public network address information
-
-        This is the server's public network address, which is provided to
-        clients in URLs and the like.  It may or may not be the network
-        address that the server is listening to directly, though it is by
-        default.  For example, it may be the address of a load balancer or
-        proxy which forwards connections to the server.
-      -->
-
-    <!-- Network host name [empty = system host name] -->
-    <key>ServerHostName</key>
-    <string></string> <!-- The hostname clients use when connecting -->
-
-    <!-- HTTP port [0 = disable HTTP] -->
-    <key>HTTPPort</key>
-    <integer>8008</integer>
-
-    <!-- SSL port [0 = disable HTTPS] -->
-    <!-- (Must also configure SSLCertificate and SSLPrivateKey below) -->
-    <key>SSLPort</key>
-    <integer>8443</integer>
-
-    <!-- Redirect non-SSL ports to an SSL port -->
-    <key>RedirectHTTPToHTTPS</key>
-    <false/>
-
-    <!--
-        Network address configuration information
-
-        This configures the actual network address that the server binds to.
-      -->
-
-    <!-- List of IP addresses to bind to [empty = all] -->
-    <key>BindAddresses</key>
-    <array>
-    </array>
-
-    <!-- List of port numbers to bind to for HTTP [empty = same as "Port"] -->
-    <key>BindHTTPPorts</key>
-    <array>
-    </array>
-
-    <!-- List of port numbers to bind to for SSL [empty = same as "SSLPort"] -->
-    <key>BindSSLPorts</key>
-    <array>
-    </array>
-
-
-    <!--
-        Data Store
-      -->
-
-    <!-- Data root -->
-    <key>DataRoot</key>
-    <string>data/</string>
-
-    <!-- Document root -->
-    <key>DocumentRoot</key>
-    <string>twistedcaldav/test/data/</string>
-
-    <!-- Child aliases -->
-    <key>Aliases</key>
-    <dict>
-      <!--
-      <key>foo</key>
-      <dict>
-        <key>path</key>
-        <string>/path/to/foo</string>
-      </dict>
-       -->
-    </dict>
-
-    <!-- User quota (in bytes) -->
-    <key>UserQuota</key>
-    <integer>104857600</integer><!-- 100Mb -->
-
-    <!-- Attachment size limit (in bytes) -->
-    <key>MaximumAttachmentSize</key>
-    <integer>1048576</integer><!-- 1Mb -->
-
-    <!-- Maximum number of unique attendees per entire event -->
-    <!-- 0 for no limit -->
-    <key>MaxAttendeesPerInstance</key>
-    <integer>100</integer>
-
-    <!-- Maximum number of instances allowed for a single RRULE -->
-    <!-- 0 for no limit -->
-    <key>MaxInstancesForRRULE</key>
-    <integer>400</integer>
-
-
-    <!--
-        Directory service
-
-        A directory service provides information about principals (eg.
-        users, groups, locations and resources) to the server.
-
-        A variety of directory services are available for use.
-      -->
-
-    <!-- XML File Directory Service -->
-    <key>DirectoryService</key>
-    <dict>
-      <key>type</key>
-      <string>twistedcaldav.directory.xmlfile.XMLDirectoryService</string>
-      
-      <key>params</key>
-      <dict>
-        <key>xmlFile</key>
-        <string>SET IN TEST</string>
-        <key>recordTypes</key>
-        <array>
-            <string>users</string>
-            <string>groups</string>
-        </array>
-      </dict>
-    </dict>
-
-    <!-- XML File Resource Service -->
-    <key>ResourceService</key>
-    <dict>
-      <key>Enabled</key>
-      <true/>
-      <key>type</key>
-      <string>twistedcaldav.directory.xmlfile.XMLDirectoryService</string>
-      
-      <key>params</key>
-      <dict>
-        <key>xmlFile</key>
-        <string>SET IN TEST</string>
-        <key>recordTypes</key>
-        <array>
-            <string>resources</string>
-            <string>locations</string>
-        </array>
-      </dict>
-    </dict>
-    
-    <!-- Open Directory Service (Mac OS X) -->
-    <!--
-    <key>DirectoryService</key>
-    <dict>
-      <key>type</key>
-      <string>twistedcaldav.directory.appleopendirectory.OpenDirectoryService</string>
-      
-      <key>params</key>
-      <dict>
-        <key>node</key>
-        <string>/Search</string>
-        <key>cacheTimeout</key>
-        <integer>30</integer>
-      </dict>
-    </dict>
-    -->
-
-    <!--
-        Augment service
-
-        Augments for the directory service records to add calendar specific attributes.
-
-        A variety of augment services are available for use.
-        When using a partitioned server, a service that can be accessed from each host will be needed.
-      -->
-
-    <!-- XML File Augment Service -->
-    <key>AugmentService</key>
-    <dict>
-      <key>type</key>
-      <string>twistedcaldav.directory.augment.AugmentXMLDB</string>
-      
-      <key>params</key>
-      <dict>
-        <key>xmlFiles</key>
-        <array>
-	      <string>SET IN TEST</string>
-        </array>
-      </dict>
-    </dict>
-    
-    <!-- Sqlite Augment Service -->
-    <!--
-    <key>AugmentService</key>
-    <dict>
-      <key>type</key>
-      <string>twistedcaldav.directory.augment.AugmentSqliteDB</string>
-      
-      <key>params</key>
-      <dict>
-        <key>dbpath</key>
-        <string>/etc/caldavd/augments.sqlite</string>
-      </dict>
-    </dict>
-     -->
-
-    <!-- PostgreSQL Augment Service -->
-    <!--
-    <key>AugmentService</key>
-    <dict>
-      <key>type</key>
-      <string>twistedcaldav.directory.augment.AugmentPostgreSQLDB</string>
-      
-      <key>params</key>
-      <dict>
-        <key>host</key>
-        <string>localhost</string>
-        <key>database</key>
-        <string>augments</string>
-      </dict>
-    </dict>
-     -->
-
-    <!-- Sqlite ProxyDB Service -->
-    <key>ProxyDBService</key>
-    <dict>
-      <key>type</key>
-      <string>twistedcaldav.directory.calendaruserproxy.ProxySqliteDB</string>
-      
-      <key>params</key>
-      <dict>
-        <key>dbpath</key>
-        <string>data/proxies.sqlite</string>
-      </dict>
-    </dict>
-
-    <!-- PostgreSQL ProxyDB Service -->
-    <!--
-    <key>ProxyDBService</key>
-    <dict>
-      <key>type</key>
-      <string>twistedcaldav.directory.calendaruserproxy.ProxyPostgreSQLDB</string>
-      
-      <key>params</key>
-      <dict>
-        <key>host</key>
-        <string>localhost</string>
-        <key>database</key>
-        <string>proxies</string>
-      </dict>
-    </dict>
-     -->
-
-	<key>ProxyLoadFromFile</key>
-    <string>conf/auth/proxies-test.xml</string>
-
-    <!--
-        Special principals
-
-        These principals are granted special access and/or perform
-        special roles on the server.
-      -->
-
-    <!-- Principals with "DAV:all" access (relative URLs) -->
-    <key>AdminPrincipals</key>
-    <array>
-      <string>/principals/__uids__/admin/</string>
-    </array>
-
-    <!-- Principals with "DAV:read" access (relative URLs) -->
-    <key>ReadPrincipals</key>
-    <array>
-      <!-- <string>/principals/__uids__/983C8238-FB6B-4D92-9242-89C0A39E5F81/</string> -->
-    </array>
-
-    <!-- Principals that can pose as other principals -->
-    <key>SudoersFile</key>
-    <string>conf/sudoers.plist</string>
-
-    <!-- Create "proxy access" principals -->
-    <key>EnableProxyPrincipals</key>
-    <true/>
-
-
-    <!--
-        Permissions
-      -->
-
-    <!-- Anonymous read access for root resource -->
-    <key>EnableAnonymousReadRoot</key>
-    <true/>
-
-    <!-- Anonymous read access for resource hierarchy -->
-    <key>EnableAnonymousReadNav</key>
-    <false/>
-
-    <!-- Enables directory listings for principals -->
-    <key>EnablePrincipalListings</key>
-    <true/>
-
-    <!-- Render calendar collections as a monolithic iCalendar object -->
-    <key>EnableMonolithicCalendars</key>
-    <true/>
-
-
-    <!--
-        Authentication
-      -->
-
-    <key>Authentication</key>
-    <dict>
-
-      <!-- Clear text; best avoided -->
-      <key>Basic</key>
-      <dict>
-        <key>Enabled</key>
-        <true/>
-      </dict>
-
-      <!-- Digest challenge/response -->
-      <key>Digest</key>
-      <dict>
-        <key>Enabled</key>
-        <true/>
-        <key>Algorithm</key>
-        <string>md5</string>
-        <key>Qop</key>
-        <string></string>
-      </dict>
-
-      <!-- Kerberos/SPNEGO -->
-      <key>Kerberos</key>
-      <dict>
-        <key>Enabled</key>
-        <false/>
-        <key>ServicePrincipal</key>
-        <string></string>
-      </dict>
-
-      <!-- Wikiserver authentication (Mac OS X) -->
-      <key>Wiki</key>
-      <dict>
-        <key>Enabled</key>
-        <true/>
-        <key>Cookie</key>
-        <string>sessionID</string>
-        <key>URL</key>
-        <string>http://127.0.0.1/RPC2</string>
-        <key>UserMethod</key>
-        <string>userForSession</string>
-        <key>WikiMethod</key>
-        <string>accessLevelForUserWikiCalendar</string>
-      </dict>
-
-    </dict>
-
-
-    <!--
-        Logging
-      -->
-
-    <!-- Apache-style access log -->
-    <key>AccessLogFile</key>
-    <string>logs/access.log</string>
-    <key>RotateAccessLog</key>
-    <false/>
-
-    <!-- Server activity log -->
-    <key>ErrorLogFile</key>
-    <string>logs/error.log</string>
-
-    <!-- Log levels -->
-    <key>DefaultLogLevel</key>
-    <string>info</string> <!-- debug, info, warn, error -->
-
-    <!-- Log level overrides for specific functionality -->
-    <key>LogLevels</key>
-    <dict>
-      <!--
-      <key>twistedcaldav.directory.appleopendirectory.OpenDirectoryService</key>
-      <string>debug</string>
-      -->
-    </dict>
-
-    <!-- Global server stats --> 
-    <key>GlobalStatsSocket</key> 
-    <string>logs/caldavd-stats.sock</string> 
-
-    <!-- Global server stats logging period --> 
-    <key>GlobalStatsLoggingPeriod</key> 
-    <integer>60</integer> 
-
-    <!-- Global server stats logging frequency [0 = disable stats] --> 
-    <key>GlobalStatsLoggingFrequency</key> 
-    <integer>12</integer>
-
-    <!-- Server statistics file -->
-    <key>ServerStatsFile</key>
-    <string>logs/stats.plist</string>
-
-    <!-- Server process ID file -->
-    <key>PIDFile</key>
-    <string>logs/caldavd.pid</string>
-
-
-    <!--
-        Accounting
-      -->
-
-    <!-- Enable accounting for certain operations -->
-    <key>AccountingCategories</key>
-    <dict>
-      <key>iTIP</key>
-      <false/>
-      <key>HTTP</key>
-      <false/>
-    </dict>
-    <!-- Enable accounting for specific principals -->
-    <key>AccountingPrincipals</key>
-    <array>
-      <!-- <string>/principals/__uids__/454D85C0-09F0-4DC6-A3C6-97DFEB4622CD/</string> -->
-    </array>
-
-
-    <!--
-        SSL/TLS
-      -->
-
-    <!-- Public key -->
-    <key>SSLCertificate</key>
-    <string>twistedcaldav/test/data/server.pem</string>
-
-    <!-- SSL authority chain (for intermediate certs) -->
-    <key>SSLAuthorityChain</key>
-    <string></string>
-
-    <!-- Private key -->
-    <key>SSLPrivateKey</key>
-    <string>twistedcaldav/test/data/server.pem</string>
-
-
-    <!--
-        Process management
-      -->
-
-    <key>UserName</key>
-    <string></string>
-
-    <key>GroupName</key>
-    <string></string>
-
-    <key>ProcessType</key>
-    <string>Combined</string>
-
-    <key>MultiProcess</key>
-    <dict>
-      <key>ProcessCount</key>
-      <integer>2</integer> <!-- 0 = larger of: 4 or (2 * CPU count) -->
-    </dict>
-
-
-    <!--
-        Notifications
-      -->
-
-    <key>Notifications</key>
-    <dict>
-      <!-- Time spent coalescing notifications before delivery -->
-      <key>CoalesceSeconds</key>
-      <integer>3</integer>
-
-      <key>InternalNotificationHost</key>
-      <string>localhost</string>
-
-      <key>InternalNotificationPort</key>
-      <integer>62309</integer>
-
-      <key>Services</key>
-      <dict>
-        <key>SimpleLineNotifier</key>
-        <dict>
-          <!-- Simple line notification service (for testing) -->
-          <key>Service</key>
-          <string>twistedcaldav.notify.SimpleLineNotifierService</string>
-          <key>Enabled</key>
-          <false/>
-          <key>Port</key>
-          <integer>62308</integer>
-        </dict>
-
-        <key>XMPPNotifier</key>
-        <dict>
-          <!-- XMPP notification service -->
-          <key>Service</key>
-          <string>twistedcaldav.notify.XMPPNotifierService</string>
-          <key>Enabled</key>
-          <false/>
-
-          <!-- XMPP host and port to contact -->
-          <key>Host</key>
-          <string>xmpp.host.name</string>
-          <key>Port</key>
-          <integer>5222</integer>
-
-          <!-- Jabber ID and password for the server -->
-          <key>JID</key>
-          <string>jid at xmpp.host.name/resource</string>
-          <key>Password</key>
-          <string>password_goes_here</string>
-
-          <!-- PubSub service address -->
-          <key>ServiceAddress</key>
-          <string>pubsub.xmpp.host.name</string>
-
-          <key>NodeConfiguration</key>
-          <dict>
-            <key>pubsub#deliver_payloads</key>
-            <string>1</string>
-            <key>pubsub#persist_items</key>
-            <string>1</string>
-          </dict>
-
-          <!-- Sends a presence notification to XMPP server at this interval (prevents disconnect) -->
-          <key>KeepAliveSeconds</key>
-          <integer>120</integer>
-
-          <!-- Sends a pubsub publish to a particular heartbeat node at this interval -->
-          <key>HeartbeatMinutes</key>
-          <integer>30</integer>
-
-          <!-- List of glob-like expressions defining which XMPP JIDs can converse with the server (for debugging) -->
-          <key>AllowedJIDs</key>
-          <array>
-            <!--
-            <string>*.example.com</string>
-             -->
-          </array>
-        </dict>
-      </dict>
-    </dict>
-
-
-    <!--
-        Server-to-server protocol
-      -->
-
-    <key>Scheduling</key>
-    <dict>
-
-      <!-- CalDAV protocol options -->
-      <key>CalDAV</key>
-      <dict>
-        <key>EmailDomain</key>
-        <string></string>
-        <key>HTTPDomain</key>
-        <string></string>
-        <key>AddressPatterns</key>
-        <array>
-        </array>
-        <key>OldDraftCompatibility</key>
-        <true/>
-        <key>ScheduleTagCompatibility</key>
-        <true/>
-        <key>EnablePrivateComments</key>
-        <true/>
-      </dict>
-
-      <!-- iSchedule protocol options -->
-      <key>iSchedule</key>
-      <dict>
-        <key>Enabled</key>
-        <false/>
-        <key>AddressPatterns</key>
-        <array>
-        </array>
-        <key>Servers</key>
-        <string>conf/servertoserver-test.xml</string>
-      </dict>
-
-      <!-- iMIP protocol options -->
-      <key>iMIP</key>
-      <dict>
-        <key>Enabled</key>
-        <false/>
-        <key>MailGatewayServer</key>
-        <string>localhost</string>
-        <key>MailGatewayPort</key>
-        <integer>62310</integer>
-        <key>Sending</key>
-        <dict>
-          <key>Server</key>
-          <string></string>
-          <key>Port</key>
-          <integer>587</integer>
-          <key>UseSSL</key>
-          <true/>
-          <key>Username</key>
-          <string></string>
-          <key>Password</key>
-          <string></string>
-          <key>Address</key>
-          <string></string> <!-- Address email will be sent from -->
-        </dict>
-        <key>Receiving</key>
-        <dict>
-          <key>Server</key>
-          <string></string>
-          <key>Port</key>
-          <integer>995</integer>
-          <key>Type</key>
-          <string></string> <!-- Either "pop" or "imap" -->
-          <key>UseSSL</key>
-          <true/>
-          <key>Username</key>
-          <string></string>
-          <key>Password</key>
-          <string></string>
-          <key>PollingSeconds</key>
-          <integer>30</integer>
-        </dict>
-        <key>AddressPatterns</key>
-        <array>
-          <string>mailto:.*</string>
-        </array>
-      </dict>
-
-	  <!-- General options for scheduling -->
-	  <key>Options</key>
-	  <dict>
-        <key>AllowGroupAsOrganizer</key>
-        <false/>
-        <key>AllowLocationAsOrganizer</key>
-        <false/>
-        <key>AllowResourceAsOrganizer</key>
-        <false/>
-       </dict>
-
-    </dict>
-
-
-    <!--
-        Free-busy URL protocol
-      -->
-
-    <key>FreeBusyURL</key>
-    <dict>
-      <key>Enabled</key>
-      <true/>
-      <key>TimePeriod</key>
-      <integer>14</integer>
-      <key>AnonymousAccess</key>
-      <false/>
-    </dict>
-
-
-    <!--
-        Non-standard CalDAV extensions
-      -->
-
-    <!-- Calendar Drop Box -->
-    <key>EnableDropBox</key>
-    <true/>
-
-    <!-- Private Events -->
-    <key>EnablePrivateEvents</key>
-    <true/>
-
-    <!-- Timezone Service -->
-    <key>EnableTimezoneService</key>
-    <true/>
-
-
-    <!--
-        Miscellaneous items
-      -->
-
-    <!-- Service ACLs (Mac OS X) -->
-    <key>EnableSACLs</key>
-    <false/>
-
-    <!-- Web-based administration -->
-    <key>EnableWebAdmin</key>
-    <true/>
-
-    <!-- Support for Content-Encoding compression options as specified in RFC2616 Section 3.5 -->
-    <key>ResponseCompression</key>
-    <false/>
-    
-    <!-- The retry-after value (in seconds) to return with a 503 error. -->
-    <key>HTTPRetryAfter</key>
-    <integer>180</integer>
-
-    <!-- A unix socket used for communication between the child and master processes.
-         An empty value tells the server to use a tcp socket instead. -->
-    <key>ControlSocket</key>
-    <string>logs/caldavd.sock</string>
-
-    <!-- Support for Memcached -->
-    <key>Memcached</key>
-    <dict>
-      <key>MaxClients</key>
-      <integer>5</integer>
-      <key>memcached</key>
-      <string>memcached</string> <!-- Find in PATH -->
-      <key>Options</key>
-      <array>
-        <!--<string>-vv</string>-->
-      </array>
-    </dict>
-
-    <!-- Response Caching -->
-    <key>ResponseCacheTimeout</key>
-    <integer>30</integer> <!-- in minutes -->
-
-
-    <!--
-        Twisted
-      -->
-
-    <key>Twisted</key>
-    <dict>
-      <key>twistd</key>
-      <string>../Twisted/bin/twistd</string>
-    </dict>
-
-
-    <key>Localization</key>
-    <dict>
-      <key>LocalesDirectory</key>
-      <string>locales</string>
-      <key>Language</key>
-      <string>English</string>
-    </dict>
-
-
-  </dict>
-</plist>

Copied: CalendarServer/trunk/twistedcaldav/directory/test/resources/caldavd.plist (from rev 5061, CalendarServer/branches/users/sagen/locations-resources-2/twistedcaldav/directory/test/resources/caldavd.plist)
===================================================================
--- CalendarServer/trunk/twistedcaldav/directory/test/resources/caldavd.plist	                        (rev 0)
+++ CalendarServer/trunk/twistedcaldav/directory/test/resources/caldavd.plist	2010-02-08 23:05:01 UTC (rev 5062)
@@ -0,0 +1,748 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+    Copyright (c) 2006-2010 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 plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+  <dict>
+
+    <!--
+        Public network address information
+
+        This is the server's public network address, which is provided to
+        clients in URLs and the like.  It may or may not be the network
+        address that the server is listening to directly, though it is by
+        default.  For example, it may be the address of a load balancer or
+        proxy which forwards connections to the server.
+      -->
+
+    <!-- Network host name [empty = system host name] -->
+    <key>ServerHostName</key>
+    <string></string> <!-- The hostname clients use when connecting -->
+
+    <!-- HTTP port [0 = disable HTTP] -->
+    <key>HTTPPort</key>
+    <integer>8008</integer>
+
+    <!-- SSL port [0 = disable HTTPS] -->
+    <!-- (Must also configure SSLCertificate and SSLPrivateKey below) -->
+    <key>SSLPort</key>
+    <integer>8443</integer>
+
+    <!-- Redirect non-SSL ports to an SSL port -->
+    <key>RedirectHTTPToHTTPS</key>
+    <false/>
+
+    <!--
+        Network address configuration information
+
+        This configures the actual network address that the server binds to.
+      -->
+
+    <!-- List of IP addresses to bind to [empty = all] -->
+    <key>BindAddresses</key>
+    <array>
+    </array>
+
+    <!-- List of port numbers to bind to for HTTP [empty = same as "Port"] -->
+    <key>BindHTTPPorts</key>
+    <array>
+    </array>
+
+    <!-- List of port numbers to bind to for SSL [empty = same as "SSLPort"] -->
+    <key>BindSSLPorts</key>
+    <array>
+    </array>
+
+
+    <!--
+        Data Store
+      -->
+
+    <!-- Data root -->
+    <key>DataRoot</key>
+    <string>data/</string>
+
+    <!-- Document root -->
+    <key>DocumentRoot</key>
+    <string>twistedcaldav/test/data/</string>
+
+    <!-- Child aliases -->
+    <key>Aliases</key>
+    <dict>
+      <!--
+      <key>foo</key>
+      <dict>
+        <key>path</key>
+        <string>/path/to/foo</string>
+      </dict>
+       -->
+    </dict>
+
+    <!-- User quota (in bytes) -->
+    <key>UserQuota</key>
+    <integer>104857600</integer><!-- 100Mb -->
+
+    <!-- Attachment size limit (in bytes) -->
+    <key>MaximumAttachmentSize</key>
+    <integer>1048576</integer><!-- 1Mb -->
+
+    <!-- Maximum number of unique attendees per entire event -->
+    <!-- 0 for no limit -->
+    <key>MaxAttendeesPerInstance</key>
+    <integer>100</integer>
+
+    <!-- Maximum number of instances allowed for a single RRULE -->
+    <!-- 0 for no limit -->
+    <key>MaxInstancesForRRULE</key>
+    <integer>400</integer>
+
+
+    <!--
+        Directory service
+
+        A directory service provides information about principals (eg.
+        users, groups, locations and resources) to the server.
+
+        A variety of directory services are available for use.
+      -->
+
+    <!-- XML File Directory Service -->
+    <key>DirectoryService</key>
+    <dict>
+      <key>type</key>
+      <string>twistedcaldav.directory.xmlfile.XMLDirectoryService</string>
+      
+      <key>params</key>
+      <dict>
+        <key>xmlFile</key>
+        <string>SET IN TEST</string>
+        <key>recordTypes</key>
+        <array>
+            <string>users</string>
+            <string>groups</string>
+        </array>
+      </dict>
+    </dict>
+
+    <!-- XML File Resource Service -->
+    <key>ResourceService</key>
+    <dict>
+      <key>Enabled</key>
+      <true/>
+      <key>type</key>
+      <string>twistedcaldav.directory.xmlfile.XMLDirectoryService</string>
+      
+      <key>params</key>
+      <dict>
+        <key>xmlFile</key>
+        <string>SET IN TEST</string>
+        <key>recordTypes</key>
+        <array>
+            <string>resources</string>
+            <string>locations</string>
+        </array>
+      </dict>
+    </dict>
+    
+    <!-- Open Directory Service (Mac OS X) -->
+    <!--
+    <key>DirectoryService</key>
+    <dict>
+      <key>type</key>
+      <string>twistedcaldav.directory.appleopendirectory.OpenDirectoryService</string>
+      
+      <key>params</key>
+      <dict>
+        <key>node</key>
+        <string>/Search</string>
+        <key>cacheTimeout</key>
+        <integer>30</integer>
+      </dict>
+    </dict>
+    -->
+
+    <!--
+        Augment service
+
+        Augments for the directory service records to add calendar specific attributes.
+
+        A variety of augment services are available for use.
+        When using a partitioned server, a service that can be accessed from each host will be needed.
+      -->
+
+    <!-- XML File Augment Service -->
+    <key>AugmentService</key>
+    <dict>
+      <key>type</key>
+      <string>twistedcaldav.directory.augment.AugmentXMLDB</string>
+      
+      <key>params</key>
+      <dict>
+        <key>xmlFiles</key>
+        <array>
+	      <string>SET IN TEST</string>
+        </array>
+      </dict>
+    </dict>
+    
+    <!-- Sqlite Augment Service -->
+    <!--
+    <key>AugmentService</key>
+    <dict>
+      <key>type</key>
+      <string>twistedcaldav.directory.augment.AugmentSqliteDB</string>
+      
+      <key>params</key>
+      <dict>
+        <key>dbpath</key>
+        <string>/etc/caldavd/augments.sqlite</string>
+      </dict>
+    </dict>
+     -->
+
+    <!-- PostgreSQL Augment Service -->
+    <!--
+    <key>AugmentService</key>
+    <dict>
+      <key>type</key>
+      <string>twistedcaldav.directory.augment.AugmentPostgreSQLDB</string>
+      
+      <key>params</key>
+      <dict>
+        <key>host</key>
+        <string>localhost</string>
+        <key>database</key>
+        <string>augments</string>
+      </dict>
+    </dict>
+     -->
+
+    <!-- Sqlite ProxyDB Service -->
+    <key>ProxyDBService</key>
+    <dict>
+      <key>type</key>
+      <string>twistedcaldav.directory.calendaruserproxy.ProxySqliteDB</string>
+      
+      <key>params</key>
+      <dict>
+        <key>dbpath</key>
+        <string>data/proxies.sqlite</string>
+      </dict>
+    </dict>
+
+    <!-- PostgreSQL ProxyDB Service -->
+    <!--
+    <key>ProxyDBService</key>
+    <dict>
+      <key>type</key>
+      <string>twistedcaldav.directory.calendaruserproxy.ProxyPostgreSQLDB</string>
+      
+      <key>params</key>
+      <dict>
+        <key>host</key>
+        <string>localhost</string>
+        <key>database</key>
+        <string>proxies</string>
+      </dict>
+    </dict>
+     -->
+
+	<key>ProxyLoadFromFile</key>
+    <string>conf/auth/proxies-test.xml</string>
+
+    <!--
+        Special principals
+
+        These principals are granted special access and/or perform
+        special roles on the server.
+      -->
+
+    <!-- Principals with "DAV:all" access (relative URLs) -->
+    <key>AdminPrincipals</key>
+    <array>
+      <string>/principals/__uids__/admin/</string>
+    </array>
+
+    <!-- Principals with "DAV:read" access (relative URLs) -->
+    <key>ReadPrincipals</key>
+    <array>
+      <!-- <string>/principals/__uids__/983C8238-FB6B-4D92-9242-89C0A39E5F81/</string> -->
+    </array>
+
+    <!-- Principals that can pose as other principals -->
+    <key>SudoersFile</key>
+    <string>conf/sudoers.plist</string>
+
+    <!-- Create "proxy access" principals -->
+    <key>EnableProxyPrincipals</key>
+    <true/>
+
+
+    <!--
+        Permissions
+      -->
+
+    <!-- Anonymous read access for root resource -->
+    <key>EnableAnonymousReadRoot</key>
+    <true/>
+
+    <!-- Anonymous read access for resource hierarchy -->
+    <key>EnableAnonymousReadNav</key>
+    <false/>
+
+    <!-- Enables directory listings for principals -->
+    <key>EnablePrincipalListings</key>
+    <true/>
+
+    <!-- Render calendar collections as a monolithic iCalendar object -->
+    <key>EnableMonolithicCalendars</key>
+    <true/>
+
+
+    <!--
+        Authentication
+      -->
+
+    <key>Authentication</key>
+    <dict>
+
+      <!-- Clear text; best avoided -->
+      <key>Basic</key>
+      <dict>
+        <key>Enabled</key>
+        <true/>
+      </dict>
+
+      <!-- Digest challenge/response -->
+      <key>Digest</key>
+      <dict>
+        <key>Enabled</key>
+        <true/>
+        <key>Algorithm</key>
+        <string>md5</string>
+        <key>Qop</key>
+        <string></string>
+      </dict>
+
+      <!-- Kerberos/SPNEGO -->
+      <key>Kerberos</key>
+      <dict>
+        <key>Enabled</key>
+        <false/>
+        <key>ServicePrincipal</key>
+        <string></string>
+      </dict>
+
+      <!-- Wikiserver authentication (Mac OS X) -->
+      <key>Wiki</key>
+      <dict>
+        <key>Enabled</key>
+        <true/>
+        <key>Cookie</key>
+        <string>sessionID</string>
+        <key>URL</key>
+        <string>http://127.0.0.1/RPC2</string>
+        <key>UserMethod</key>
+        <string>userForSession</string>
+        <key>WikiMethod</key>
+        <string>accessLevelForUserWikiCalendar</string>
+      </dict>
+
+    </dict>
+
+
+    <!--
+        Logging
+      -->
+
+    <!-- Apache-style access log -->
+    <key>AccessLogFile</key>
+    <string>logs/access.log</string>
+    <key>RotateAccessLog</key>
+    <false/>
+
+    <!-- Server activity log -->
+    <key>ErrorLogFile</key>
+    <string>logs/error.log</string>
+
+    <!-- Log levels -->
+    <key>DefaultLogLevel</key>
+    <string>info</string> <!-- debug, info, warn, error -->
+
+    <!-- Log level overrides for specific functionality -->
+    <key>LogLevels</key>
+    <dict>
+      <!--
+      <key>twistedcaldav.directory.appleopendirectory.OpenDirectoryService</key>
+      <string>debug</string>
+      -->
+    </dict>
+
+    <!-- Global server stats --> 
+    <key>GlobalStatsSocket</key> 
+    <string>logs/caldavd-stats.sock</string> 
+
+    <!-- Global server stats logging period --> 
+    <key>GlobalStatsLoggingPeriod</key> 
+    <integer>60</integer> 
+
+    <!-- Global server stats logging frequency [0 = disable stats] --> 
+    <key>GlobalStatsLoggingFrequency</key> 
+    <integer>12</integer>
+
+    <!-- Server statistics file -->
+    <key>ServerStatsFile</key>
+    <string>logs/stats.plist</string>
+
+    <!-- Server process ID file -->
+    <key>PIDFile</key>
+    <string>logs/caldavd.pid</string>
+
+
+    <!--
+        Accounting
+      -->
+
+    <!-- Enable accounting for certain operations -->
+    <key>AccountingCategories</key>
+    <dict>
+      <key>iTIP</key>
+      <false/>
+      <key>HTTP</key>
+      <false/>
+    </dict>
+    <!-- Enable accounting for specific principals -->
+    <key>AccountingPrincipals</key>
+    <array>
+      <!-- <string>/principals/__uids__/454D85C0-09F0-4DC6-A3C6-97DFEB4622CD/</string> -->
+    </array>
+
+
+    <!--
+        SSL/TLS
+      -->
+
+    <!-- Public key -->
+    <key>SSLCertificate</key>
+    <string>twistedcaldav/test/data/server.pem</string>
+
+    <!-- SSL authority chain (for intermediate certs) -->
+    <key>SSLAuthorityChain</key>
+    <string></string>
+
+    <!-- Private key -->
+    <key>SSLPrivateKey</key>
+    <string>twistedcaldav/test/data/server.pem</string>
+
+
+    <!--
+        Process management
+      -->
+
+    <key>UserName</key>
+    <string></string>
+
+    <key>GroupName</key>
+    <string></string>
+
+    <key>ProcessType</key>
+    <string>Combined</string>
+
+    <key>MultiProcess</key>
+    <dict>
+      <key>ProcessCount</key>
+      <integer>2</integer> <!-- 0 = larger of: 4 or (2 * CPU count) -->
+    </dict>
+
+
+    <!--
+        Notifications
+      -->
+
+    <key>Notifications</key>
+    <dict>
+      <!-- Time spent coalescing notifications before delivery -->
+      <key>CoalesceSeconds</key>
+      <integer>3</integer>
+
+      <key>InternalNotificationHost</key>
+      <string>localhost</string>
+
+      <key>InternalNotificationPort</key>
+      <integer>62309</integer>
+
+      <key>Services</key>
+      <dict>
+        <key>SimpleLineNotifier</key>
+        <dict>
+          <!-- Simple line notification service (for testing) -->
+          <key>Service</key>
+          <string>twistedcaldav.notify.SimpleLineNotifierService</string>
+          <key>Enabled</key>
+          <false/>
+          <key>Port</key>
+          <integer>62308</integer>
+        </dict>
+
+        <key>XMPPNotifier</key>
+        <dict>
+          <!-- XMPP notification service -->
+          <key>Service</key>
+          <string>twistedcaldav.notify.XMPPNotifierService</string>
+          <key>Enabled</key>
+          <false/>
+
+          <!-- XMPP host and port to contact -->
+          <key>Host</key>
+          <string>xmpp.host.name</string>
+          <key>Port</key>
+          <integer>5222</integer>
+
+          <!-- Jabber ID and password for the server -->
+          <key>JID</key>
+          <string>jid at xmpp.host.name/resource</string>
+          <key>Password</key>
+          <string>password_goes_here</string>
+
+          <!-- PubSub service address -->
+          <key>ServiceAddress</key>
+          <string>pubsub.xmpp.host.name</string>
+
+          <key>NodeConfiguration</key>
+          <dict>
+            <key>pubsub#deliver_payloads</key>
+            <string>1</string>
+            <key>pubsub#persist_items</key>
+            <string>1</string>
+          </dict>
+
+          <!-- Sends a presence notification to XMPP server at this interval (prevents disconnect) -->
+          <key>KeepAliveSeconds</key>
+          <integer>120</integer>
+
+          <!-- Sends a pubsub publish to a particular heartbeat node at this interval -->
+          <key>HeartbeatMinutes</key>
+          <integer>30</integer>
+
+          <!-- List of glob-like expressions defining which XMPP JIDs can converse with the server (for debugging) -->
+          <key>AllowedJIDs</key>
+          <array>
+            <!--
+            <string>*.example.com</string>
+             -->
+          </array>
+        </dict>
+      </dict>
+    </dict>
+
+
+    <!--
+        Server-to-server protocol
+      -->
+
+    <key>Scheduling</key>
+    <dict>
+
+      <!-- CalDAV protocol options -->
+      <key>CalDAV</key>
+      <dict>
+        <key>EmailDomain</key>
+        <string></string>
+        <key>HTTPDomain</key>
+        <string></string>
+        <key>AddressPatterns</key>
+        <array>
+        </array>
+        <key>OldDraftCompatibility</key>
+        <true/>
+        <key>ScheduleTagCompatibility</key>
+        <true/>
+        <key>EnablePrivateComments</key>
+        <true/>
+      </dict>
+
+      <!-- iSchedule protocol options -->
+      <key>iSchedule</key>
+      <dict>
+        <key>Enabled</key>
+        <false/>
+        <key>AddressPatterns</key>
+        <array>
+        </array>
+        <key>Servers</key>
+        <string>conf/servertoserver-test.xml</string>
+      </dict>
+
+      <!-- iMIP protocol options -->
+      <key>iMIP</key>
+      <dict>
+        <key>Enabled</key>
+        <false/>
+        <key>MailGatewayServer</key>
+        <string>localhost</string>
+        <key>MailGatewayPort</key>
+        <integer>62310</integer>
+        <key>Sending</key>
+        <dict>
+          <key>Server</key>
+          <string></string>
+          <key>Port</key>
+          <integer>587</integer>
+          <key>UseSSL</key>
+          <true/>
+          <key>Username</key>
+          <string></string>
+          <key>Password</key>
+          <string></string>
+          <key>Address</key>
+          <string></string> <!-- Address email will be sent from -->
+        </dict>
+        <key>Receiving</key>
+        <dict>
+          <key>Server</key>
+          <string></string>
+          <key>Port</key>
+          <integer>995</integer>
+          <key>Type</key>
+          <string></string> <!-- Either "pop" or "imap" -->
+          <key>UseSSL</key>
+          <true/>
+          <key>Username</key>
+          <string></string>
+          <key>Password</key>
+          <string></string>
+          <key>PollingSeconds</key>
+          <integer>30</integer>
+        </dict>
+        <key>AddressPatterns</key>
+        <array>
+          <string>mailto:.*</string>
+        </array>
+      </dict>
+
+	  <!-- General options for scheduling -->
+	  <key>Options</key>
+	  <dict>
+        <key>AllowGroupAsOrganizer</key>
+        <false/>
+        <key>AllowLocationAsOrganizer</key>
+        <false/>
+        <key>AllowResourceAsOrganizer</key>
+        <false/>
+       </dict>
+
+    </dict>
+
+
+    <!--
+        Free-busy URL protocol
+      -->
+
+    <key>FreeBusyURL</key>
+    <dict>
+      <key>Enabled</key>
+      <true/>
+      <key>TimePeriod</key>
+      <integer>14</integer>
+      <key>AnonymousAccess</key>
+      <false/>
+    </dict>
+
+
+    <!--
+        Non-standard CalDAV extensions
+      -->
+
+    <!-- Calendar Drop Box -->
+    <key>EnableDropBox</key>
+    <true/>
+
+    <!-- Private Events -->
+    <key>EnablePrivateEvents</key>
+    <true/>
+
+    <!-- Timezone Service -->
+    <key>EnableTimezoneService</key>
+    <true/>
+
+
+    <!--
+        Miscellaneous items
+      -->
+
+    <!-- Service ACLs (Mac OS X) -->
+    <key>EnableSACLs</key>
+    <false/>
+
+    <!-- Web-based administration -->
+    <key>EnableWebAdmin</key>
+    <true/>
+
+    <!-- Support for Content-Encoding compression options as specified in RFC2616 Section 3.5 -->
+    <key>ResponseCompression</key>
+    <false/>
+    
+    <!-- The retry-after value (in seconds) to return with a 503 error. -->
+    <key>HTTPRetryAfter</key>
+    <integer>180</integer>
+
+    <!-- A unix socket used for communication between the child and master processes.
+         An empty value tells the server to use a tcp socket instead. -->
+    <key>ControlSocket</key>
+    <string>logs/caldavd.sock</string>
+
+    <!-- Support for Memcached -->
+    <key>Memcached</key>
+    <dict>
+      <key>MaxClients</key>
+      <integer>5</integer>
+      <key>memcached</key>
+      <string>memcached</string> <!-- Find in PATH -->
+      <key>Options</key>
+      <array>
+        <!--<string>-vv</string>-->
+      </array>
+    </dict>
+
+    <!-- Response Caching -->
+    <key>ResponseCacheTimeout</key>
+    <integer>30</integer> <!-- in minutes -->
+
+
+    <!--
+        Twisted
+      -->
+
+    <key>Twisted</key>
+    <dict>
+      <key>twistd</key>
+      <string>../Twisted/bin/twistd</string>
+    </dict>
+
+
+    <key>Localization</key>
+    <dict>
+      <key>LocalesDirectory</key>
+      <string>locales</string>
+      <key>Language</key>
+      <string>English</string>
+    </dict>
+
+
+  </dict>
+</plist>

Deleted: CalendarServer/trunk/twistedcaldav/directory/test/resources/resources-locations.xml
===================================================================
--- CalendarServer/branches/users/sagen/locations-resources-2/twistedcaldav/directory/test/resources/resources-locations.xml	2010-02-08 22:31:59 UTC (rev 5061)
+++ CalendarServer/trunk/twistedcaldav/directory/test/resources/resources-locations.xml	2010-02-08 23:05:01 UTC (rev 5062)
@@ -1,34 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<!--
-Copyright (c) 2006-2010 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>
-  <resource repeat="10">
-    <uid>resource%02d</uid>
-    <guid>resource%02d</guid>
-    <password>resource%02d</password>
-    <name>Resource %02d</name>
-  </resource>
-</accounts>

Copied: CalendarServer/trunk/twistedcaldav/directory/test/resources/resources-locations.xml (from rev 5061, CalendarServer/branches/users/sagen/locations-resources-2/twistedcaldav/directory/test/resources/resources-locations.xml)
===================================================================
--- CalendarServer/trunk/twistedcaldav/directory/test/resources/resources-locations.xml	                        (rev 0)
+++ CalendarServer/trunk/twistedcaldav/directory/test/resources/resources-locations.xml	2010-02-08 23:05:01 UTC (rev 5062)
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+Copyright (c) 2006-2010 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>
+  <resource repeat="10">
+    <uid>resource%02d</uid>
+    <guid>resource%02d</guid>
+    <password>resource%02d</password>
+    <name>Resource %02d</name>
+  </resource>
+</accounts>

Deleted: CalendarServer/trunk/twistedcaldav/directory/test/resources/users-groups.xml
===================================================================
--- CalendarServer/branches/users/sagen/locations-resources-2/twistedcaldav/directory/test/resources/users-groups.xml	2010-02-08 22:31:59 UTC (rev 5061)
+++ CalendarServer/trunk/twistedcaldav/directory/test/resources/users-groups.xml	2010-02-08 23:05:01 UTC (rev 5062)
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<!--
-Copyright (c) 2006-2010 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">
-  <user repeat="10">
-    <uid>user%02d</uid>
-    <guid>user%02d</guid>
-    <password>test</password>
-    <name>Test User %02d</name>
-    <first-name>Test</first-name>
-    <last-name>User %02d</last-name>
-  </user>
-  <group>
-    <uid>testgroup1</uid>
-    <guid>e5a6142c-4189-4e9e-90b0-9cd0268b314b</guid>
-    <password>test</password>
-    <name>Group 01</name>
-    <members>
-      <member type="users">user01</member>
-      <member type="users">user02</member>
-    </members>
-  </group>
-</accounts>

Copied: CalendarServer/trunk/twistedcaldav/directory/test/resources/users-groups.xml (from rev 5061, CalendarServer/branches/users/sagen/locations-resources-2/twistedcaldav/directory/test/resources/users-groups.xml)
===================================================================
--- CalendarServer/trunk/twistedcaldav/directory/test/resources/users-groups.xml	                        (rev 0)
+++ CalendarServer/trunk/twistedcaldav/directory/test/resources/users-groups.xml	2010-02-08 23:05:01 UTC (rev 5062)
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+Copyright (c) 2006-2010 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">
+  <user repeat="10">
+    <uid>user%02d</uid>
+    <guid>user%02d</guid>
+    <password>test</password>
+    <name>Test User %02d</name>
+    <first-name>Test</first-name>
+    <last-name>User %02d</last-name>
+  </user>
+  <group>
+    <uid>testgroup1</uid>
+    <guid>e5a6142c-4189-4e9e-90b0-9cd0268b314b</guid>
+    <password>test</password>
+    <name>Group 01</name>
+    <members>
+      <member type="users">user01</member>
+      <member type="users">user02</member>
+    </members>
+  </group>
+</accounts>

Modified: CalendarServer/trunk/twistedcaldav/directory/test/test_aggregate.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/directory/test/test_aggregate.py	2010-02-08 22:31:59 UTC (rev 5061)
+++ CalendarServer/trunk/twistedcaldav/directory/test/test_aggregate.py	2010-02-08 23:05:01 UTC (rev 5062)
@@ -22,7 +22,6 @@
 import twistedcaldav.directory.test.util
 from twistedcaldav.directory import augment
 
-apache_prefix = "apache:"
 xml_prefix = "xml:"
 
 testServices = (

Modified: CalendarServer/trunk/twistedcaldav/directory/test/test_cachedirectory.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/directory/test/test_cachedirectory.py	2010-02-08 22:31:59 UTC (rev 5061)
+++ CalendarServer/trunk/twistedcaldav/directory/test/test_cachedirectory.py	2010-02-08 23:05:01 UTC (rev 5062)
@@ -86,7 +86,7 @@
         self.service.queried = False
 
     def loadRecords(self, records):
-        self.service._initCaches(DictRecordTypeCache)
+        self.service._initCaches()
         self.service.fakerecords = records
         self.service.queried = False
 

Copied: CalendarServer/trunk/twistedcaldav/directory/test/test_modify.py (from rev 5061, CalendarServer/branches/users/sagen/locations-resources-2/twistedcaldav/directory/test/test_modify.py)
===================================================================
--- CalendarServer/trunk/twistedcaldav/directory/test/test_modify.py	                        (rev 0)
+++ CalendarServer/trunk/twistedcaldav/directory/test/test_modify.py	2010-02-08 23:05:01 UTC (rev 5062)
@@ -0,0 +1,122 @@
+##
+# Copyright (c) 2005-2010 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
+from twistedcaldav.config import config
+from twistedcaldav.test.util import TestCase
+from calendarserver.tools.util import getDirectory
+from twisted.python.filepath import FilePath
+from twistedcaldav.directory.directory import DirectoryError
+
+
+class ModificationTestCase(TestCase):
+
+    def setUp(self):
+        testRoot = os.path.join(os.path.dirname(__file__), "modify")
+        configFileName = os.path.join(testRoot, "caldavd.plist")
+        config.load(configFileName)
+
+        usersFile = os.path.join(testRoot, "users-groups.xml")
+        config.DirectoryService.params.xmlFile = usersFile
+
+        # Copy xml file containgin locations/resources to a temp file because
+        # we're going to be modifying it during testing
+
+        origResourcesFile = FilePath(os.path.join(os.path.dirname(__file__),
+            "modify", "resources-locations.xml"))
+        copyResourcesFile = FilePath(self.mktemp())
+        origResourcesFile.copyTo(copyResourcesFile)
+        config.ResourceService.params.xmlFile = copyResourcesFile
+
+        augmentsFile = os.path.join(testRoot, "augments.xml")
+        config.AugmentService.params.xmlFiles = (augmentsFile,)
+
+        super(ModificationTestCase, self).setUp()
+
+    def test_createRecord(self):
+        directory = getDirectory()
+
+        record = directory.recordWithUID("resource01")
+        self.assertEquals(record, None)
+
+        directory.createRecord("resources", "resource01", shortNames=("resource01",), uid="resource01")
+
+        record = directory.recordWithUID("resource01")
+        self.assertNotEquals(record, None)
+
+        directory.createRecord("resources", "resource02", shortNames=("resource02",), uid="resource02")
+
+        record = directory.recordWithUID("resource02")
+        self.assertNotEquals(record, None)
+
+        # Make sure old records are still there:
+        record = directory.recordWithUID("resource01")
+        self.assertNotEquals(record, None)
+        record = directory.recordWithUID("location01")
+        self.assertNotEquals(record, None)
+
+    def test_destroyRecord(self):
+        directory = getDirectory()
+
+        record = directory.recordWithUID("resource01")
+        self.assertEquals(record, None)
+
+        directory.createRecord("resources", "resource01", shortNames=("resource01",), uid="resource01")
+
+        record = directory.recordWithUID("resource01")
+        self.assertNotEquals(record, None)
+
+        directory.destroyRecord("resources", "resource01")
+
+        record = directory.recordWithUID("resource01")
+        self.assertEquals(record, None)
+
+        # Make sure old records are still there:
+        record = directory.recordWithUID("location01")
+        self.assertNotEquals(record, None)
+
+    def test_updateRecord(self):
+        directory = getDirectory()
+
+        directory.createRecord("resources", "resource01",
+            shortNames=("resource01",), uid="resource01",
+            fullName="Resource number 1")
+
+        record = directory.recordWithUID("resource01")
+        self.assertEquals(record.fullName, "Resource number 1")
+
+        directory.updateRecord("resources", "resource01",
+            shortNames=("resource01", "r01"), uid="resource01",
+            fullName="Resource #1", firstName="First", lastName="Last",
+            emailAddresses=("resource01 at example.com", "r01 at example.com"))
+
+        record = directory.recordWithUID("resource01")
+        self.assertEquals(record.fullName, "Resource #1")
+        self.assertEquals(record.firstName, "First")
+        self.assertEquals(record.lastName, "Last")
+        self.assertEquals(set(record.shortNames), set(["resource01", "r01"]))
+        self.assertEquals(record.emailAddresses,
+            set(["resource01 at example.com", "r01 at example.com"]))
+
+        # Make sure old records are still there:
+        record = directory.recordWithUID("location01")
+        self.assertNotEquals(record, None)
+
+    def test_createDuplicateRecord(self):
+        directory = getDirectory()
+
+        directory.createRecord("resources", "resource01", shortNames=("resource01",), uid="resource01")
+        self.assertRaises(DirectoryError, directory.createRecord, "resources", "resource01", shortNames=("resource01",), uid="resource01")

Modified: CalendarServer/trunk/twistedcaldav/directory/test/test_opendirectory.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/directory/test/test_opendirectory.py	2010-02-08 22:31:59 UTC (rev 5061)
+++ CalendarServer/trunk/twistedcaldav/directory/test/test_opendirectory.py	2010-02-08 23:05:01 UTC (rev 5062)
@@ -261,3 +261,18 @@
             self.assertEquals(len(results), 2)
             for record in results:
                 self.assertTrue(isinstance(record, OpenDirectoryRecord))
+
+
+    class OpenDirectorySubset (OpenDirectory):
+        """
+        Test the recordTypes subset feature of Apple OpenDirectoryService.
+        """
+        recordTypes = set((
+            DirectoryService.recordType_users,
+            DirectoryService.recordType_groups,
+        ))
+
+        def setUp(self):
+            super(OpenDirectorySubset, self).setUp()
+            self._service = OpenDirectoryService({'node' : "/Search", 'recordTypes' : (DirectoryService.recordType_users, DirectoryService.recordType_groups)}, dosetup=False)
+            augment.AugmentService = augment.AugmentXMLDB(xmlFiles=())

Copied: CalendarServer/trunk/twistedcaldav/directory/test/test_resources.py (from rev 5061, CalendarServer/branches/users/sagen/locations-resources-2/twistedcaldav/directory/test/test_resources.py)
===================================================================
--- CalendarServer/trunk/twistedcaldav/directory/test/test_resources.py	                        (rev 0)
+++ CalendarServer/trunk/twistedcaldav/directory/test/test_resources.py	2010-02-08 23:05:01 UTC (rev 5062)
@@ -0,0 +1,76 @@
+##
+# Copyright (c) 2005-2010 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
+from twistedcaldav.config import config
+from twistedcaldav.test.util import TestCase
+from calendarserver.tools.util import getDirectory
+
+class ResourcesTestCase(TestCase):
+
+    def setUp(self):
+        testRoot = os.path.join(os.path.dirname(__file__), "resources")
+        configFileName = os.path.join(testRoot, "caldavd.plist")
+        config.load(configFileName)
+
+        xmlFile = os.path.join(testRoot, "users-groups.xml")
+        config.DirectoryService.params.xmlFile = xmlFile
+
+        xmlFile = os.path.join(testRoot, "resources-locations.xml")
+        config.ResourceService.params.xmlFile = xmlFile
+
+        xmlFile = os.path.join(testRoot, "augments.xml")
+        config.AugmentService.params.xmlFiles = (xmlFile,)
+
+        super(ResourcesTestCase, self).setUp()
+
+    def test_loadConfig(self):
+        directory = getDirectory()
+
+    def test_recordInPrimaryDirectory(self):
+        directory = getDirectory()
+
+        # Look up a user, which comes out of primary directory service
+        record = directory.recordWithUID("user01")
+        self.assertNotEquals(record, None)
+
+    def test_recordInSupplementalDirectory(self):
+        directory = getDirectory()
+
+        # Look up a resource, which comes out of locations/resources service
+        record = directory.recordWithUID("resource01")
+        self.assertNotEquals(record, None)
+
+    def test_augments(self):
+        directory = getDirectory()
+
+        # Primary directory
+        record = directory.recordWithUID("user01")
+        self.assertEquals(record.enabled, True)
+        self.assertEquals(record.enabledForCalendaring, True)
+        record = directory.recordWithUID("user02")
+        self.assertEquals(record.enabled, False)
+        self.assertEquals(record.enabledForCalendaring, False)
+
+        # Supplemental directory
+        record = directory.recordWithUID("resource01")
+        self.assertEquals(record.enabled, True)
+        self.assertEquals(record.enabledForCalendaring, True)
+        self.assertEquals(record.autoSchedule, True)
+        record = directory.recordWithUID("resource02")
+        self.assertEquals(record.enabled, False)
+        self.assertEquals(record.enabledForCalendaring, False)
+        self.assertEquals(record.autoSchedule, False)

Modified: CalendarServer/trunk/twistedcaldav/directory/test/test_xmlfile.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/directory/test/test_xmlfile.py	2010-02-08 22:31:59 UTC (rev 5061)
+++ CalendarServer/trunk/twistedcaldav/directory/test/test_xmlfile.py	2010-02-08 23:05:01 UTC (rev 5062)
@@ -18,6 +18,7 @@
 
 from twisted.python.filepath import FilePath
 
+from twistedcaldav.test.util import TestCase
 from twistedcaldav.directory import augment
 from twistedcaldav.directory.directory import DirectoryService
 import twistedcaldav.directory.test.util
@@ -194,11 +195,13 @@
 <accounts realm="Test Realm">
   <group>
     <uid>enabled</uid>
+    <guid>enabled</guid>
     <password>enabled</password>
     <name>Enabled</name>
   </group>
   <group>
     <uid>disabled</uid>
+    <guid>disabled</guid>
     <password>disabled</password>
     <name>Disabled</name>
   </group>
@@ -225,3 +228,16 @@
         self.assertFalse(service.recordWithShortName(DirectoryService.recordType_groups, "enabled").enabledForCalendaring)
         self.assertFalse(service.recordWithShortName(DirectoryService.recordType_groups, "disabled").enabledForCalendaring)
 
+
+class XMLFileSubset (XMLFileBase, TestCase):
+    """
+    Test the recordTypes subset feature of XMLFile service.
+    """
+    recordTypes = set((
+        DirectoryService.recordType_users,
+        DirectoryService.recordType_groups,
+    ))
+
+    def test_recordTypesSubset(self):
+        directory = XMLDirectoryService({'xmlFile' : self.xmlFile(), 'recordTypes' : (DirectoryService.recordType_users, DirectoryService.recordType_groups)}, alwaysStat=True)
+        self.assertEquals(set(("users", "groups")), set(directory.recordTypes()))

Modified: CalendarServer/trunk/twistedcaldav/directory/xmlfile.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/directory/xmlfile.py	2010-02-08 22:31:59 UTC (rev 5061)
+++ CalendarServer/trunk/twistedcaldav/directory/xmlfile.py	2010-02-08 23:05:01 UTC (rev 5062)
@@ -24,17 +24,22 @@
 
 from time import time
 import types
+import os, pwd, grp
 
 from twisted.cred.credentials import UsernamePassword
 from twisted.web2.auth.digest import DigestedCredentials
 from twisted.python.filepath import FilePath
+from twistedcaldav.config import config
 
 from twistedcaldav.directory import augment
-from twistedcaldav.directory.directory import DirectoryService
+from twistedcaldav.directory.directory import DirectoryService, DirectoryError
 from twistedcaldav.directory.cachingdirectory import CachingDirectoryService,\
     CachingDirectoryRecord
-from twistedcaldav.directory.xmlaccountsparser import XMLAccountsParser
+from twistedcaldav.directory.xmlaccountsparser import XMLAccountsParser, XMLAccountRecord
+import xml.etree.ElementTree as ET
+from uuid import uuid4
 
+
 class XMLDirectoryService(CachingDirectoryService):
     """
     XML based implementation of L{IDirectoryService}.
@@ -50,16 +55,52 @@
 
         defaults = {
             'xmlFile' : None,
+            'recordTypes' : (
+                self.recordType_users,
+                self.recordType_groups,
+                self.recordType_locations,
+                self.recordType_resources,
+            ),
+            'cacheTimeout' : 30,
+            'realmName' : '/Search',
         }
         ignored = None
         params = self.getParams(params, defaults, ignored)
 
-        super(XMLDirectoryService, self).__init__()
+        self._recordTypes = params['recordTypes']
+        self.realmName = params['realmName']
 
+        super(XMLDirectoryService, self).__init__(params['cacheTimeout'])
+
         xmlFile = params.get("xmlFile")
         if type(xmlFile) is str:
             xmlFile = FilePath(xmlFile)
 
+        if not xmlFile.exists():
+            xmlFile.setContent("""<?xml version="1.0" encoding="utf-8"?>
+
+<accounts realm="%s">
+</accounts>
+""" % (self.realmName,))
+
+        uid = -1
+        if config.UserName:
+            try:
+                uid = pwd.getpwnam(config.UserName).pw_uid
+            except KeyError:
+                log.error("User not found: %s" % (config.UserName,))
+
+        gid = -1
+        if config.GroupName:
+            try:
+                gid = grp.getgrnam(config.GroupName).gr_gid
+            except KeyError:
+                log.error("Group not found: %s" % (config.GroupName,))
+
+        if uid != -1 and gid != -1:
+            os.chown(xmlFile.path, uid, gid)
+
+
         self.xmlFile = xmlFile
         self._fileInfo = None
         self._lastCheck = 0
@@ -67,16 +108,27 @@
         self._accounts()
 
     def recordTypes(self):
-        recordTypes = (
-            DirectoryService.recordType_users,
-            DirectoryService.recordType_groups,
-            DirectoryService.recordType_locations,
-            DirectoryService.recordType_resources
-        )
-        return recordTypes
+        return self._recordTypes
 
+    def listRecords(self, recordType):
+        self._lastCheck = 0
+        for xmlPrincipal in self._accounts()[recordType].itervalues():
+            record = self.recordWithGUID(xmlPrincipal.guid)
+            if record is not None:
+                yield record
+
     def queryDirectory(self, recordTypes, indexType, indexKey):
-        
+        """
+        If the query is a miss, re-read from the XML file and try again
+        """
+        if not self._queryDirectory(recordTypes, indexType, indexKey):
+            self._lastCheck = 0
+            self._queryDirectory(recordTypes, indexType, indexKey)
+
+    def _queryDirectory(self, recordTypes, indexType, indexKey):
+
+        anyMatches = False
+
         for recordType in recordTypes:
             for xmlPrincipal in self._accounts()[recordType].itervalues():
                 record = XMLDirectoryRecord(
@@ -86,13 +138,6 @@
                     xmlPrincipal  = xmlPrincipal,
                 )
 
-                record = XMLDirectoryRecord(
-                    service       = self,
-                    recordType    = recordType,
-                    shortNames    = tuple(xmlPrincipal.shortNames),
-                    xmlPrincipal  = xmlPrincipal,
-                )
-                
                 # Look up augment information
                 # TODO: this needs to be deferred but for now we hard code the deferred result because
                 # we know it is completing immediately.
@@ -108,7 +153,10 @@
                     matched = indexKey in record.calendarUserAddresses
                 
                 if matched:
+                    anyMatches = True
                     self.recordCacheForType(recordType).addRecord(record, indexType, indexKey)
+
+        return anyMatches
             
     def recordsMatchingFields(self, fields, operand="or", recordType=None):
         # Default, brute force method search of underlying XML data
@@ -177,6 +225,10 @@
                     if record:
                         yield record
 
+    def _initCaches(self):
+        super(XMLDirectoryService, self)._initCaches()
+        self._lastCheck = 0
+
     def _accounts(self):
         currentTime = time()
         if self._alwaysStat or currentTime - self._lastCheck > 60:
@@ -190,6 +242,155 @@
                 self._fileInfo = fileInfo
         return self._parsedAccounts
 
+
+    def _addElement(self, parent, principal):
+        """
+        Create an XML element from principal and add it as a child of parent
+        """
+
+        # TODO: derive this from xmlaccountsparser.py
+        xmlTypes = {
+            'users'     : 'user',
+            'groups'    : 'group',
+            'locations' : 'location',
+            'resources' : 'resource',
+        }
+        xmlType = xmlTypes[principal.recordType]
+
+        element = ET.SubElement(parent, xmlType)
+        for value in principal.shortNames:
+            ET.SubElement(element, "uid").text = value
+        ET.SubElement(element, "guid").text = principal.guid
+        ET.SubElement(element, "name").text = principal.fullName
+        ET.SubElement(element, "first-name").text = principal.firstName
+        ET.SubElement(element, "last-name").text = principal.lastName
+        for value in principal.emailAddresses:
+            ET.SubElement(element, "email-address").text = value
+
+        return element
+
+
+    def _persistRecords(self, element):
+
+        def indent(elem, level=0):
+            i = "\n" + level*"  "
+            if len(elem):
+                if not elem.text or not elem.text.strip():
+                    elem.text = i + "  "
+                if not elem.tail or not elem.tail.strip():
+                    elem.tail = i
+                for elem in elem:
+                    indent(elem, level+1)
+                if not elem.tail or not elem.tail.strip():
+                    elem.tail = i
+            else:
+                if level and (not elem.tail or not elem.tail.strip()):
+                    elem.tail = i
+
+        indent(element)
+
+        # TODO: make this robust:
+        ET.ElementTree(element).write(self.xmlFile.path)
+
+        # Reload
+        self._initCaches() # nuke local cache
+        self._lastCheck = 0
+        self._accounts()
+        # TODO: nuke memcache entries, or prepopulate them
+
+
+    def createRecord(self, recordType, guid=None, shortNames=(), authIDs=set(),
+        fullName=None, firstName=None, lastName=None, emailAddresses=set(),
+        uid=None, password=None, **kwds):
+        """
+        Create and persist a record using the provided information.  In this
+        XML-based implementation, the xml accounts are read in and converted
+        to elementtree elements, a new element is added for the new record,
+        and the document is serialized to disk.
+        """
+
+        if guid is None:
+            guid = str(uuid4())
+
+        # Make sure latest XML records are read in
+        self._lastCheck = 0
+        accounts = self._accounts()
+
+        accountsElement = ET.Element("accounts", realm=self.realmName)
+        for recType in self.recordTypes():
+            for xmlPrincipal in accounts[recType].itervalues():
+                if xmlPrincipal.guid == guid:
+                    raise DirectoryError("Duplicate guid: %s" % (guid,))
+                self._addElement(accountsElement, xmlPrincipal)
+
+        xmlPrincipal = XMLAccountRecord(recordType)
+        xmlPrincipal.shortNames = shortNames
+        xmlPrincipal.guid = guid
+        xmlPrincipal.password = password
+        xmlPrincipal.fullName = fullName
+        xmlPrincipal.firstName = firstName
+        xmlPrincipal.lastName = lastName
+        xmlPrincipal.emailAddresses = emailAddresses
+        self._addElement(accountsElement, xmlPrincipal)
+
+        self._persistRecords(accountsElement)
+
+
+    def destroyRecord(self, recordType, guid):
+        """
+        Remove the record matching guid.  In this XML-based implementation,
+        the xml accounts are read in and those not matching the given guid are
+        converted to elementtree elements, then the document is serialized to
+        disk.
+        """
+
+        # Make sure latest XML records are read in
+        self._lastCheck = 0
+        accounts = self._accounts()
+
+        accountsElement = ET.Element("accounts", realm=self.realmName)
+        for recType in self.recordTypes():
+
+            for xmlPrincipal in accounts[recType].itervalues():
+                if xmlPrincipal.guid != guid:
+                    self._addElement(accountsElement, xmlPrincipal)
+
+        self._persistRecords(accountsElement)
+
+
+    def updateRecord(self, recordType, guid, shortNames=(), authIDs=set(),
+        fullName=None, firstName=None, lastName=None, emailAddresses=set(),
+        uid=None, password=None, **kwds):
+        """
+        Update the record matching guid.  In this XML-based implementation,
+        the xml accounts are read in and converted to elementtree elements.
+        The account matching the given guid is replaced, then the document
+        is serialized to disk.
+        """
+
+        # Make sure latest XML records are read in
+        self._lastCheck = 0
+        accounts = self._accounts()
+
+        accountsElement = ET.Element("accounts", realm=self.realmName)
+        for recType in self.recordTypes():
+
+            for xmlPrincipal in accounts[recType].itervalues():
+                if xmlPrincipal.guid == guid:
+                    # Replace this record
+                    xmlPrincipal.shortNames = shortNames
+                    xmlPrincipal.password = password
+                    xmlPrincipal.fullName = fullName
+                    xmlPrincipal.firstName = firstName
+                    xmlPrincipal.lastName = lastName
+                    xmlPrincipal.emailAddresses = emailAddresses
+                    self._addElement(accountsElement, xmlPrincipal)
+                else:
+                    self._addElement(accountsElement, xmlPrincipal)
+
+        self._persistRecords(accountsElement)
+
+
 class XMLDirectoryRecord(CachingDirectoryRecord):
     """
     XML based implementation implementation of L{IDirectoryRecord}.

Modified: CalendarServer/trunk/twistedcaldav/stdconfig.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/stdconfig.py	2010-02-08 22:31:59 UTC (rev 5061)
+++ CalendarServer/trunk/twistedcaldav/stdconfig.py	2010-02-08 23:05:01 UTC (rev 5062)
@@ -39,13 +39,25 @@
 DEFAULT_SERVICE_PARAMS = {
     "twistedcaldav.directory.xmlfile.XMLDirectoryService": {
         "xmlFile": "/etc/caldavd/accounts.xml",
+        "cacheTimeout": 30,
+        "recordTypes": ("users", "groups"),
     },
     "twistedcaldav.directory.appleopendirectory.OpenDirectoryService": {
         "node": "/Search",
         "cacheTimeout": 30,
+        "recordTypes": ("users", "groups"),
     },
 }
 
+DEFAULT_RESOURCE_PARAMS = {
+    "twistedcaldav.directory.xmlfile.XMLDirectoryService": {
+        "xmlFile": "/etc/caldavd/resources.xml",
+        "cacheTimeout": 30,
+        "realmName": "/Search",
+        "recordTypes" : ("locations", "resources"),
+    },
+}
+
 DEFAULT_AUGMENT_PARAMS = {
     "twistedcaldav.directory.augment.AugmentXMLDB": {
         "xmlFiles": ["/etc/caldavd/augments.xml",],
@@ -127,6 +139,18 @@
     },
 
     #
+    # Locations and Resources service
+    #
+    #    Supplements the directory service with information about locations
+    #    and resources.
+    #
+    "ResourceService": {
+        "Enabled" : False,
+        "type": "twistedcaldav.directory.xmlfile.XMLDirectoryService",
+        "params": DEFAULT_RESOURCE_PARAMS["twistedcaldav.directory.xmlfile.XMLDirectoryService"],
+    },
+
+    #
     # Augment service
     #
     #    Augments for the directory service records to add calendar specific attributes.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20100208/5d47bd48/attachment-0001.html>


More information about the calendarserver-changes mailing list