Added CFURL support, and got base chaining to really work.
diff --git a/Mac/Modules/cf/CFmodule.c b/Mac/Modules/cf/CFmodule.c
index 628373e..d436c90 100644
--- a/Mac/Modules/cf/CFmodule.c
+++ b/Mac/Modules/cf/CFmodule.c
@@ -15,10 +15,12 @@
 #endif
 
 /* For now we declare them forward here. They'll go to mactoolbox later */
-extern PyObject *CFTypeRefObj_New(CFTypeRef);
-extern int CFTypeRefObj_Convert(PyObject *, CFTypeRef *);
-extern PyObject *CFStringRefObj_New(CFStringRef);
-extern int CFStringRefObj_Convert(PyObject *, CFStringRef *);
+staticforward PyObject *CFTypeRefObj_New(CFTypeRef);
+staticforward int CFTypeRefObj_Convert(PyObject *, CFTypeRef *);
+staticforward PyObject *CFStringRefObj_New(CFStringRef);
+staticforward int CFStringRefObj_Convert(PyObject *, CFStringRef *);
+
+staticforward int CFURLRefObj_Convert(PyObject *, CFURLRef *);
 
 // ADD declarations
 #ifdef NOTYET_USE_TOOLBOX_OBJECT_GLUE
@@ -30,7 +32,7 @@
 #endif
 
 /*
-** Parse/generate RGB records
+** Parse/generate CFRange records
 */
 PyObject *CFRange_New(CFRange *itself)
 {
@@ -49,6 +51,17 @@
 	return 1;
 }
 
+/* Optional CFURL argument or None (passed as NULL) */
+int
+OptionalCFURLRefObj_Convert(PyObject *v, CFURLRef *p_itself)
+{
+    if ( v == Py_None ) {
+    	p_itself = NULL;
+    	return 1;
+    }
+    return CFURLRefObj_Convert(v, p_itself);
+}
+
 
 static PyObject *CF_Error;
 
@@ -333,7 +346,7 @@
 	{NULL, NULL, 0}
 };
 
-PyMethodChain CFArrayRefObj_chain = { CFArrayRefObj_methods, NULL };
+PyMethodChain CFArrayRefObj_chain = { CFArrayRefObj_methods, &CFTypeRefObj_chain };
 
 static PyObject *CFArrayRefObj_getattr(CFArrayRefObject *self, char *name)
 {
@@ -353,7 +366,7 @@
 static PyObject * CFArrayRefObj_repr(CFArrayRefObject *self)
 {
 	char buf[100];
-	sprintf(buf, "<CFTypeRef type-%d object at 0x%08.8x for 0x%08.8x>", CFGetTypeID(self->ob_itself), self, self->ob_itself);
+	sprintf(buf, "<CFArrayRef object at 0x%08.8x for 0x%08.8x>", CFGetTypeID(self->ob_itself), self, self->ob_itself);
 	return PyString_FromString(buf);
 }
 
@@ -484,7 +497,7 @@
 	{NULL, NULL, 0}
 };
 
-PyMethodChain CFMutableArrayRefObj_chain = { CFMutableArrayRefObj_methods, NULL };
+PyMethodChain CFMutableArrayRefObj_chain = { CFMutableArrayRefObj_methods, &CFArrayRefObj_chain };
 
 static PyObject *CFMutableArrayRefObj_getattr(CFMutableArrayRefObject *self, char *name)
 {
@@ -504,7 +517,7 @@
 static PyObject * CFMutableArrayRefObj_repr(CFMutableArrayRefObject *self)
 {
 	char buf[100];
-	sprintf(buf, "<CFTypeRef type-%d object at 0x%08.8x for 0x%08.8x>", CFGetTypeID(self->ob_itself), self, self->ob_itself);
+	sprintf(buf, "<CFMutableArrayRef object at 0x%08.8x for 0x%08.8x>", CFGetTypeID(self->ob_itself), self, self->ob_itself);
 	return PyString_FromString(buf);
 }
 
@@ -601,7 +614,7 @@
 	{NULL, NULL, 0}
 };
 
-PyMethodChain CFDictionaryRefObj_chain = { CFDictionaryRefObj_methods, NULL };
+PyMethodChain CFDictionaryRefObj_chain = { CFDictionaryRefObj_methods, &CFTypeRefObj_chain };
 
 static PyObject *CFDictionaryRefObj_getattr(CFDictionaryRefObject *self, char *name)
 {
@@ -621,7 +634,7 @@
 static PyObject * CFDictionaryRefObj_repr(CFDictionaryRefObject *self)
 {
 	char buf[100];
-	sprintf(buf, "<CFTypeRef type-%d object at 0x%08.8x for 0x%08.8x>", CFGetTypeID(self->ob_itself), self, self->ob_itself);
+	sprintf(buf, "<CFDictionaryRef object at 0x%08.8x for 0x%08.8x>", CFGetTypeID(self->ob_itself), self, self->ob_itself);
 	return PyString_FromString(buf);
 }
 
@@ -717,7 +730,7 @@
 	{NULL, NULL, 0}
 };
 
-PyMethodChain CFMutableDictionaryRefObj_chain = { CFMutableDictionaryRefObj_methods, NULL };
+PyMethodChain CFMutableDictionaryRefObj_chain = { CFMutableDictionaryRefObj_methods, &CFDictionaryRefObj_chain };
 
 static PyObject *CFMutableDictionaryRefObj_getattr(CFMutableDictionaryRefObject *self, char *name)
 {
@@ -737,7 +750,7 @@
 static PyObject * CFMutableDictionaryRefObj_repr(CFMutableDictionaryRefObject *self)
 {
 	char buf[100];
-	sprintf(buf, "<CFTypeRef type-%d object at 0x%08.8x for 0x%08.8x>", CFGetTypeID(self->ob_itself), self, self->ob_itself);
+	sprintf(buf, "<CFMutableDictionaryRef object at 0x%08.8x for 0x%08.8x>", CFGetTypeID(self->ob_itself), self, self->ob_itself);
 	return PyString_FromString(buf);
 }
 
@@ -834,7 +847,7 @@
 	{NULL, NULL, 0}
 };
 
-PyMethodChain CFDataRefObj_chain = { CFDataRefObj_methods, NULL };
+PyMethodChain CFDataRefObj_chain = { CFDataRefObj_methods, &CFTypeRefObj_chain };
 
 static PyObject *CFDataRefObj_getattr(CFDataRefObject *self, char *name)
 {
@@ -854,7 +867,7 @@
 static PyObject * CFDataRefObj_repr(CFDataRefObject *self)
 {
 	char buf[100];
-	sprintf(buf, "<CFTypeRef type-%d object at 0x%08.8x for 0x%08.8x>", CFGetTypeID(self->ob_itself), self, self->ob_itself);
+	sprintf(buf, "<CFDataRef object at 0x%08.8x for 0x%08.8x>", CFGetTypeID(self->ob_itself), self, self->ob_itself);
 	return PyString_FromString(buf);
 }
 
@@ -1028,7 +1041,7 @@
 	{NULL, NULL, 0}
 };
 
-PyMethodChain CFMutableDataRefObj_chain = { CFMutableDataRefObj_methods, NULL };
+PyMethodChain CFMutableDataRefObj_chain = { CFMutableDataRefObj_methods, &CFDataRefObj_chain };
 
 static PyObject *CFMutableDataRefObj_getattr(CFMutableDataRefObject *self, char *name)
 {
@@ -1048,7 +1061,7 @@
 static PyObject * CFMutableDataRefObj_repr(CFMutableDataRefObject *self)
 {
 	char buf[100];
-	sprintf(buf, "<CFTypeRef type-%d object at 0x%08.8x for 0x%08.8x>", CFGetTypeID(self->ob_itself), self, self->ob_itself);
+	sprintf(buf, "<CFMutableDataRef object at 0x%08.8x for 0x%08.8x>", CFGetTypeID(self->ob_itself), self, self->ob_itself);
 	return PyString_FromString(buf);
 }
 
@@ -1433,7 +1446,7 @@
 	{NULL, NULL, 0}
 };
 
-PyMethodChain CFStringRefObj_chain = { CFStringRefObj_methods, NULL };
+PyMethodChain CFStringRefObj_chain = { CFStringRefObj_methods, &CFTypeRefObj_chain };
 
 static PyObject *CFStringRefObj_getattr(CFStringRefObject *self, char *name)
 {
@@ -1453,7 +1466,7 @@
 static PyObject * CFStringRefObj_repr(CFStringRefObject *self)
 {
 	char buf[100];
-	sprintf(buf, "<CFTypeRef type-%d object at 0x%08.8x for 0x%08.8x>", CFGetTypeID(self->ob_itself), self, self->ob_itself);
+	sprintf(buf, "<CFStringRef object at 0x%08.8x for 0x%08.8x>", CFGetTypeID(self->ob_itself), self, self->ob_itself);
 	return PyString_FromString(buf);
 }
 
@@ -1711,7 +1724,7 @@
 	{NULL, NULL, 0}
 };
 
-PyMethodChain CFMutableStringRefObj_chain = { CFMutableStringRefObj_methods, NULL };
+PyMethodChain CFMutableStringRefObj_chain = { CFMutableStringRefObj_methods, &CFStringRefObj_chain };
 
 static PyObject *CFMutableStringRefObj_getattr(CFMutableStringRefObject *self, char *name)
 {
@@ -1731,7 +1744,7 @@
 static PyObject * CFMutableStringRefObj_repr(CFMutableStringRefObject *self)
 {
 	char buf[100];
-	sprintf(buf, "<CFTypeRef type-%d object at 0x%08.8x for 0x%08.8x>", CFGetTypeID(self->ob_itself), self, self->ob_itself);
+	sprintf(buf, "<CFMutableStringRef object at 0x%08.8x for 0x%08.8x>", CFGetTypeID(self->ob_itself), self, self->ob_itself);
 	return PyString_FromString(buf);
 }
 
@@ -1763,6 +1776,342 @@
 /* --------------- End object type CFMutableStringRef --------------- */
 
 
+/* ---------------------- Object type CFURLRef ---------------------- */
+
+PyTypeObject CFURLRef_Type;
+
+#define CFURLRefObj_Check(x) ((x)->ob_type == &CFURLRef_Type)
+
+typedef struct CFURLRefObject {
+	PyObject_HEAD
+	CFURLRef ob_itself;
+	void (*ob_freeit)(CFTypeRef ptr);
+} CFURLRefObject;
+
+PyObject *CFURLRefObj_New(CFURLRef itself)
+{
+	CFURLRefObject *it;
+	if (itself == NULL) return PyMac_Error(resNotFound);
+	CFRetain(itself);
+	it = PyObject_NEW(CFURLRefObject, &CFURLRef_Type);
+	if (it == NULL) return NULL;
+	it->ob_itself = itself;
+	it->ob_freeit = CFRelease;
+	return (PyObject *)it;
+}
+CFURLRefObj_Convert(PyObject *v, CFURLRef *p_itself)
+{
+
+	if (v == Py_None) { *p_itself = NULL; return 1; }
+	/* Check for other CF objects here */
+
+	if (!CFURLRefObj_Check(v))
+	{
+		PyErr_SetString(PyExc_TypeError, "CFURLRef required");
+		return 0;
+	}
+	*p_itself = ((CFURLRefObject *)v)->ob_itself;
+	return 1;
+}
+
+static void CFURLRefObj_dealloc(CFURLRefObject *self)
+{
+	if (self->ob_freeit && self->ob_itself)
+	{
+		self->ob_freeit((CFTypeRef)self->ob_itself);
+	}
+	PyMem_DEL(self);
+}
+
+static PyObject *CFURLRefObj_CFURLCopyAbsoluteURL(CFURLRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFURLRef _rv;
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = CFURLCopyAbsoluteURL(_self->ob_itself);
+	_res = Py_BuildValue("O&",
+	                     CFURLRefObj_New, _rv);
+	return _res;
+}
+
+static PyObject *CFURLRefObj_CFURLGetString(CFURLRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFStringRef _rv;
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = CFURLGetString(_self->ob_itself);
+	_res = Py_BuildValue("O&",
+	                     CFStringRefObj_New, _rv);
+	return _res;
+}
+
+static PyObject *CFURLRefObj_CFURLGetBaseURL(CFURLRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFURLRef _rv;
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = CFURLGetBaseURL(_self->ob_itself);
+	_res = Py_BuildValue("O&",
+	                     CFURLRefObj_New, _rv);
+	return _res;
+}
+
+static PyObject *CFURLRefObj_CFURLCanBeDecomposed(CFURLRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = CFURLCanBeDecomposed(_self->ob_itself);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *CFURLRefObj_CFURLCopyScheme(CFURLRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFStringRef _rv;
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = CFURLCopyScheme(_self->ob_itself);
+	_res = Py_BuildValue("O&",
+	                     CFStringRefObj_New, _rv);
+	return _res;
+}
+
+static PyObject *CFURLRefObj_CFURLCopyNetLocation(CFURLRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFStringRef _rv;
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = CFURLCopyNetLocation(_self->ob_itself);
+	_res = Py_BuildValue("O&",
+	                     CFStringRefObj_New, _rv);
+	return _res;
+}
+
+static PyObject *CFURLRefObj_CFURLCopyPath(CFURLRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFStringRef _rv;
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = CFURLCopyPath(_self->ob_itself);
+	_res = Py_BuildValue("O&",
+	                     CFStringRefObj_New, _rv);
+	return _res;
+}
+
+static PyObject *CFURLRefObj_CFURLHasDirectoryPath(CFURLRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	Boolean _rv;
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = CFURLHasDirectoryPath(_self->ob_itself);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *CFURLRefObj_CFURLCopyResourceSpecifier(CFURLRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFStringRef _rv;
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = CFURLCopyResourceSpecifier(_self->ob_itself);
+	_res = Py_BuildValue("O&",
+	                     CFStringRefObj_New, _rv);
+	return _res;
+}
+
+static PyObject *CFURLRefObj_CFURLCopyHostName(CFURLRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFStringRef _rv;
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = CFURLCopyHostName(_self->ob_itself);
+	_res = Py_BuildValue("O&",
+	                     CFStringRefObj_New, _rv);
+	return _res;
+}
+
+static PyObject *CFURLRefObj_CFURLGetPortNumber(CFURLRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	SInt32 _rv;
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = CFURLGetPortNumber(_self->ob_itself);
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *CFURLRefObj_CFURLCopyUserName(CFURLRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFStringRef _rv;
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = CFURLCopyUserName(_self->ob_itself);
+	_res = Py_BuildValue("O&",
+	                     CFStringRefObj_New, _rv);
+	return _res;
+}
+
+static PyObject *CFURLRefObj_CFURLCopyPassword(CFURLRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFStringRef _rv;
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = CFURLCopyPassword(_self->ob_itself);
+	_res = Py_BuildValue("O&",
+	                     CFStringRefObj_New, _rv);
+	return _res;
+}
+
+static PyObject *CFURLRefObj_CFURLCopyParameterString(CFURLRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFStringRef _rv;
+	CFStringRef charactersToLeaveEscaped;
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CFStringRefObj_Convert, &charactersToLeaveEscaped))
+		return NULL;
+	_rv = CFURLCopyParameterString(_self->ob_itself,
+	                               charactersToLeaveEscaped);
+	_res = Py_BuildValue("O&",
+	                     CFStringRefObj_New, _rv);
+	return _res;
+}
+
+static PyObject *CFURLRefObj_CFURLCopyQueryString(CFURLRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFStringRef _rv;
+	CFStringRef charactersToLeaveEscaped;
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CFStringRefObj_Convert, &charactersToLeaveEscaped))
+		return NULL;
+	_rv = CFURLCopyQueryString(_self->ob_itself,
+	                           charactersToLeaveEscaped);
+	_res = Py_BuildValue("O&",
+	                     CFStringRefObj_New, _rv);
+	return _res;
+}
+
+static PyObject *CFURLRefObj_CFURLCopyFragment(CFURLRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFStringRef _rv;
+	CFStringRef charactersToLeaveEscaped;
+	if (!PyArg_ParseTuple(_args, "O&",
+	                      CFStringRefObj_Convert, &charactersToLeaveEscaped))
+		return NULL;
+	_rv = CFURLCopyFragment(_self->ob_itself,
+	                        charactersToLeaveEscaped);
+	_res = Py_BuildValue("O&",
+	                     CFStringRefObj_New, _rv);
+	return _res;
+}
+
+static PyMethodDef CFURLRefObj_methods[] = {
+	{"CFURLCopyAbsoluteURL", (PyCFunction)CFURLRefObj_CFURLCopyAbsoluteURL, 1,
+	 "() -> (CFURLRef _rv)"},
+	{"CFURLGetString", (PyCFunction)CFURLRefObj_CFURLGetString, 1,
+	 "() -> (CFStringRef _rv)"},
+	{"CFURLGetBaseURL", (PyCFunction)CFURLRefObj_CFURLGetBaseURL, 1,
+	 "() -> (CFURLRef _rv)"},
+	{"CFURLCanBeDecomposed", (PyCFunction)CFURLRefObj_CFURLCanBeDecomposed, 1,
+	 "() -> (Boolean _rv)"},
+	{"CFURLCopyScheme", (PyCFunction)CFURLRefObj_CFURLCopyScheme, 1,
+	 "() -> (CFStringRef _rv)"},
+	{"CFURLCopyNetLocation", (PyCFunction)CFURLRefObj_CFURLCopyNetLocation, 1,
+	 "() -> (CFStringRef _rv)"},
+	{"CFURLCopyPath", (PyCFunction)CFURLRefObj_CFURLCopyPath, 1,
+	 "() -> (CFStringRef _rv)"},
+	{"CFURLHasDirectoryPath", (PyCFunction)CFURLRefObj_CFURLHasDirectoryPath, 1,
+	 "() -> (Boolean _rv)"},
+	{"CFURLCopyResourceSpecifier", (PyCFunction)CFURLRefObj_CFURLCopyResourceSpecifier, 1,
+	 "() -> (CFStringRef _rv)"},
+	{"CFURLCopyHostName", (PyCFunction)CFURLRefObj_CFURLCopyHostName, 1,
+	 "() -> (CFStringRef _rv)"},
+	{"CFURLGetPortNumber", (PyCFunction)CFURLRefObj_CFURLGetPortNumber, 1,
+	 "() -> (SInt32 _rv)"},
+	{"CFURLCopyUserName", (PyCFunction)CFURLRefObj_CFURLCopyUserName, 1,
+	 "() -> (CFStringRef _rv)"},
+	{"CFURLCopyPassword", (PyCFunction)CFURLRefObj_CFURLCopyPassword, 1,
+	 "() -> (CFStringRef _rv)"},
+	{"CFURLCopyParameterString", (PyCFunction)CFURLRefObj_CFURLCopyParameterString, 1,
+	 "(CFStringRef charactersToLeaveEscaped) -> (CFStringRef _rv)"},
+	{"CFURLCopyQueryString", (PyCFunction)CFURLRefObj_CFURLCopyQueryString, 1,
+	 "(CFStringRef charactersToLeaveEscaped) -> (CFStringRef _rv)"},
+	{"CFURLCopyFragment", (PyCFunction)CFURLRefObj_CFURLCopyFragment, 1,
+	 "(CFStringRef charactersToLeaveEscaped) -> (CFStringRef _rv)"},
+	{NULL, NULL, 0}
+};
+
+PyMethodChain CFURLRefObj_chain = { CFURLRefObj_methods, &CFTypeRefObj_chain };
+
+static PyObject *CFURLRefObj_getattr(CFURLRefObject *self, char *name)
+{
+	return Py_FindMethodInChain(&CFURLRefObj_chain, (PyObject *)self, name);
+}
+
+#define CFURLRefObj_setattr NULL
+
+static int CFURLRefObj_compare(CFURLRefObject *self, CFURLRefObject *other)
+{
+	/* XXXX Or should we use CFEqual?? */
+	if ( self->ob_itself > other->ob_itself ) return 1;
+	if ( self->ob_itself < other->ob_itself ) return -1;
+	return 0;
+}
+
+static PyObject * CFURLRefObj_repr(CFURLRefObject *self)
+{
+	char buf[100];
+	sprintf(buf, "<CFURL object at 0x%08.8x for 0x%08.8x>", CFGetTypeID(self->ob_itself), self, self->ob_itself);
+	return PyString_FromString(buf);
+}
+
+static int CFURLRefObj_hash(CFURLRefObject *self)
+{
+	/* XXXX Or should we use CFHash?? */
+	return (int)self->ob_itself;
+}
+
+PyTypeObject CFURLRef_Type = {
+	PyObject_HEAD_INIT(&PyType_Type)
+	0, /*ob_size*/
+	"CFURLRef", /*tp_name*/
+	sizeof(CFURLRefObject), /*tp_basicsize*/
+	0, /*tp_itemsize*/
+	/* methods */
+	(destructor) CFURLRefObj_dealloc, /*tp_dealloc*/
+	0, /*tp_print*/
+	(getattrfunc) CFURLRefObj_getattr, /*tp_getattr*/
+	(setattrfunc) CFURLRefObj_setattr, /*tp_setattr*/
+	(cmpfunc) CFURLRefObj_compare, /*tp_compare*/
+	(reprfunc) CFURLRefObj_repr, /*tp_repr*/
+	(PyNumberMethods *)0, /* tp_as_number */
+	(PySequenceMethods *)0, /* tp_as_sequence */
+	(PyMappingMethods *)0, /* tp_as_mapping */
+	(hashfunc) CFURLRefObj_hash, /*tp_hash*/
+};
+
+/* -------------------- End object type CFURLRef -------------------- */
+
+
 static PyObject *CF_CFAllocatorGetTypeID(PyObject *_self, PyObject *_args)
 {
 	PyObject *_res = NULL;
@@ -2446,6 +2795,100 @@
 	return _res;
 }
 
+static PyObject *CF_CFURLGetTypeID(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFTypeID _rv;
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_rv = CFURLGetTypeID();
+	_res = Py_BuildValue("l",
+	                     _rv);
+	return _res;
+}
+
+static PyObject *CF_CFURLCreateWithBytes(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFURLRef _rv;
+	unsigned char *URLBytes__in__;
+	long URLBytes__len__;
+	int URLBytes__in_len__;
+	CFStringEncoding encoding;
+	CFURLRef baseURL;
+	if (!PyArg_ParseTuple(_args, "s#lO&",
+	                      &URLBytes__in__, &URLBytes__in_len__,
+	                      &encoding,
+	                      OptionalCFURLRefObj_Convert, &baseURL))
+		return NULL;
+	URLBytes__len__ = URLBytes__in_len__;
+	_rv = CFURLCreateWithBytes((CFAllocatorRef)NULL,
+	                           URLBytes__in__, URLBytes__len__,
+	                           encoding,
+	                           baseURL);
+	_res = Py_BuildValue("O&",
+	                     CFURLRefObj_New, _rv);
+ URLBytes__error__: ;
+	return _res;
+}
+
+static PyObject *CF_CFURLCreateData(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFDataRef _rv;
+	CFURLRef url;
+	CFStringEncoding encoding;
+	Boolean escapeWhitespace;
+	if (!PyArg_ParseTuple(_args, "O&ll",
+	                      CFURLRefObj_Convert, &url,
+	                      &encoding,
+	                      &escapeWhitespace))
+		return NULL;
+	_rv = CFURLCreateData((CFAllocatorRef)NULL,
+	                      url,
+	                      encoding,
+	                      escapeWhitespace);
+	_res = Py_BuildValue("O&",
+	                     CFDataRefObj_New, _rv);
+	return _res;
+}
+
+static PyObject *CF_CFURLCreateWithString(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFURLRef _rv;
+	CFStringRef URLString;
+	CFURLRef baseURL;
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CFStringRefObj_Convert, &URLString,
+	                      OptionalCFURLRefObj_Convert, &baseURL))
+		return NULL;
+	_rv = CFURLCreateWithString((CFAllocatorRef)NULL,
+	                            URLString,
+	                            baseURL);
+	_res = Py_BuildValue("O&",
+	                     CFURLRefObj_New, _rv);
+	return _res;
+}
+
+static PyObject *CF_CFURLCreateStringByReplacingPercentEscapes(PyObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+	CFStringRef _rv;
+	CFStringRef originalString;
+	CFStringRef charactersToLeaveEscaped;
+	if (!PyArg_ParseTuple(_args, "O&O&",
+	                      CFStringRefObj_Convert, &originalString,
+	                      CFStringRefObj_Convert, &charactersToLeaveEscaped))
+		return NULL;
+	_rv = CFURLCreateStringByReplacingPercentEscapes((CFAllocatorRef)NULL,
+	                                                 originalString,
+	                                                 charactersToLeaveEscaped);
+	_res = Py_BuildValue("O&",
+	                     CFStringRefObj_New, _rv);
+	return _res;
+}
+
 static PyMethodDef CF_methods[] = {
 	{"CFAllocatorGetTypeID", (PyCFunction)CF_CFAllocatorGetTypeID, 1,
 	 "() -> (CFTypeID _rv)"},
@@ -2531,6 +2974,16 @@
 	 "(CFStringEncoding encoding) -> (CFStringRef _rv)"},
 	{"__CFStringMakeConstantString", (PyCFunction)CF___CFStringMakeConstantString, 1,
 	 "(char* cStr) -> (CFStringRef _rv)"},
+	{"CFURLGetTypeID", (PyCFunction)CF_CFURLGetTypeID, 1,
+	 "() -> (CFTypeID _rv)"},
+	{"CFURLCreateWithBytes", (PyCFunction)CF_CFURLCreateWithBytes, 1,
+	 "(Buffer URLBytes, CFStringEncoding encoding, CFURLRef baseURL) -> (CFURLRef _rv)"},
+	{"CFURLCreateData", (PyCFunction)CF_CFURLCreateData, 1,
+	 "(CFURLRef url, CFStringEncoding encoding, Boolean escapeWhitespace) -> (CFDataRef _rv)"},
+	{"CFURLCreateWithString", (PyCFunction)CF_CFURLCreateWithString, 1,
+	 "(CFStringRef URLString, CFURLRef baseURL) -> (CFURLRef _rv)"},
+	{"CFURLCreateStringByReplacingPercentEscapes", (PyCFunction)CF_CFURLCreateStringByReplacingPercentEscapes, 1,
+	 "(CFStringRef originalString, CFStringRef charactersToLeaveEscaped) -> (CFStringRef _rv)"},
 	{NULL, NULL, 0}
 };
 
@@ -2590,6 +3043,10 @@
 	Py_INCREF(&CFMutableStringRef_Type);
 	if (PyDict_SetItemString(d, "CFMutableStringRefType", (PyObject *)&CFMutableStringRef_Type) != 0)
 		Py_FatalError("can't initialize CFMutableStringRefType");
+	CFURLRef_Type.ob_type = &PyType_Type;
+	Py_INCREF(&CFURLRef_Type);
+	if (PyDict_SetItemString(d, "CFURLRefType", (PyObject *)&CFURLRef_Type) != 0)
+		Py_FatalError("can't initialize CFURLRefType");
 }
 
 /* ========================= End module CF ========================== */
diff --git a/Mac/Modules/cf/cfscan.py b/Mac/Modules/cf/cfscan.py
index a4dab2d..2d11867 100644
--- a/Mac/Modules/cf/cfscan.py
+++ b/Mac/Modules/cf/cfscan.py
@@ -13,7 +13,8 @@
 		"CFArrayRef", "CFMutableArrayRef",
 		"CFDataRef", "CFMutableDataRef",
 		"CFDictionaryRef", "CFMutableDictionaryRef",
-		"CFStringRef", "CFMutableStringRef", 
+		"CFStringRef", "CFMutableStringRef",
+		"CFURLRef",
 		)
 # ADD object typenames here
 
@@ -35,7 +36,7 @@
 		"CFString.h",
 ##		"CFStringEncodingExt.h",
 ##		"CFTimeZone.h",
-##		"CFURL.h",
+		"CFURL.h",
 		]
 	output = SHORT + "gen.py"
 	defsoutput = TOOLBOXDIR + LONG + ".py"
@@ -81,7 +82,10 @@
 			"CFStringGetPascalString", # Use the C-string methods.
 			"CFStringGetPascalStringPtr", # TBD automatically
 			"CFStringGetCStringPtr", 
-			"CFStringGetCharactersPtr", 
+			"CFStringGetCharactersPtr",
+			# OSX only, to be done
+			"CFURLCreateWithFileSystemPath",
+			"CFURLCreateStringWithFileSystemPath",
 			]
 
 	def makegreylist(self):
@@ -104,10 +108,18 @@
 
 	def makerepairinstructions(self):
 		return [
+			# Buffers in CF seem to be passed as UInt8 * normally.
 			([("UInt8_ptr", "*", "InMode"), ("CFIndex", "*", "InMode")],
 			 [("UcharInBuffer", "*", "*")]),
+			 
+			# Some functions return a const char *. Don't worry, we won't modify it.
 			([("const_char_ptr", "*", "ReturnMode")],
 			 [("return_stringptr", "*", "*")]),
+			 
+			# base URLs are optional (pass None for NULL)
+			([("CFURLRef", "baseURL", "InMode")],
+			 [("OptionalCFURLRef", "*", "*")]),
+			 
 			]
 			
 if __name__ == "__main__":
diff --git a/Mac/Modules/cf/cfsupport.py b/Mac/Modules/cf/cfsupport.py
index e73dd68..bdc20f8 100644
--- a/Mac/Modules/cf/cfsupport.py
+++ b/Mac/Modules/cf/cfsupport.py
@@ -27,10 +27,12 @@
 #endif
 
 /* For now we declare them forward here. They'll go to mactoolbox later */
-extern PyObject *CFTypeRefObj_New(CFTypeRef);
-extern int CFTypeRefObj_Convert(PyObject *, CFTypeRef *);
-extern PyObject *CFStringRefObj_New(CFStringRef);
-extern int CFStringRefObj_Convert(PyObject *, CFStringRef *);
+staticforward PyObject *CFTypeRefObj_New(CFTypeRef);
+staticforward int CFTypeRefObj_Convert(PyObject *, CFTypeRef *);
+staticforward PyObject *CFStringRefObj_New(CFStringRef);
+staticforward int CFStringRefObj_Convert(PyObject *, CFStringRef *);
+
+staticforward int CFURLRefObj_Convert(PyObject *, CFURLRef *);
 
 // ADD declarations
 #ifdef NOTYET_USE_TOOLBOX_OBJECT_GLUE
@@ -42,7 +44,7 @@
 #endif
 
 /*
-** Parse/generate RGB records
+** Parse/generate CFRange records
 */
 PyObject *CFRange_New(CFRange *itself)
 {
@@ -61,6 +63,17 @@
 	return 1;
 }
 
+/* Optional CFURL argument or None (passed as NULL) */
+int
+OptionalCFURLRefObj_Convert(PyObject *v, CFURLRef *p_itself)
+{
+    if ( v == Py_None ) {
+    	p_itself = NULL;
+    	return 1;
+    }
+    return CFURLRefObj_Convert(v, p_itself);
+}
+
 """
 
 initstuff = initstuff + """
@@ -75,7 +88,8 @@
 CFRange = OpaqueByValueType('CFRange', 'CFRange')
 CFOptionFlags = Type("CFOptionFlags", "l")
 CFStringEncoding = Type("CFStringEncoding", "l")
-CFComparisonResult = Type("CFComparisonResult", "l")  # a bit dangerous...
+CFComparisonResult = Type("CFComparisonResult", "l")  # a bit dangerous, it's an enum
+CFURLPathStyle = Type("CFURLPathStyle", "l") #  a bit dangerous, it's an enum
 
 char_ptr = stringptr
 return_stringptr = Type("char *", "s")	# ONLY FOR RETURN VALUES!!
@@ -96,6 +110,8 @@
 CFMutableDictionaryRef = OpaqueByValueType("CFMutableDictionaryRef", "CFMutableDictionaryRefObj")
 CFStringRef = OpaqueByValueType("CFStringRef", "CFStringRefObj")
 CFMutableStringRef = OpaqueByValueType("CFMutableStringRef", "CFMutableStringRefObj")
+CFURLRef = OpaqueByValueType("CFURLRef", "CFURLRefObj")
+OptionalCFURLRef  = OpaqueByValueType("CFURLRef", "OptionalCFURLRefObj")
 # ADD object type here
 
 # Our (opaque) objects
@@ -160,7 +176,7 @@
 		Output("static PyObject * %s_repr(%s *self)", self.prefix, self.objecttype)
 		OutLbrace()
 		Output("char buf[100];")
-		Output("""sprintf(buf, "<CFArrayRef object at 0x%%08.8x for 0x%%08.8x>", CFGetTypeID(self->ob_itself), self, self->ob_itself);""")
+		Output("""sprintf(buf, "<CFArrayRef object at 0x%%08.8x for 0x%%08.8x>", self, self->ob_itself);""")
 		Output("return PyString_FromString(buf);")
 		OutRbrace()
 	
@@ -172,7 +188,7 @@
 		Output("static PyObject * %s_repr(%s *self)", self.prefix, self.objecttype)
 		OutLbrace()
 		Output("char buf[100];")
-		Output("""sprintf(buf, "<CFMutableArrayRef object at 0x%%08.8x for 0x%%08.8x>", CFGetTypeID(self->ob_itself), self, self->ob_itself);""")
+		Output("""sprintf(buf, "<CFMutableArrayRef object at 0x%%08.8x for 0x%%08.8x>", self, self->ob_itself);""")
 		Output("return PyString_FromString(buf);")
 		OutRbrace()
 	
@@ -184,7 +200,7 @@
 		Output("static PyObject * %s_repr(%s *self)", self.prefix, self.objecttype)
 		OutLbrace()
 		Output("char buf[100];")
-		Output("""sprintf(buf, "<CFDictionaryRef object at 0x%%08.8x for 0x%%08.8x>", CFGetTypeID(self->ob_itself), self, self->ob_itself);""")
+		Output("""sprintf(buf, "<CFDictionaryRef object at 0x%%08.8x for 0x%%08.8x>", self, self->ob_itself);""")
 		Output("return PyString_FromString(buf);")
 		OutRbrace()
 	
@@ -196,7 +212,7 @@
 		Output("static PyObject * %s_repr(%s *self)", self.prefix, self.objecttype)
 		OutLbrace()
 		Output("char buf[100];")
-		Output("""sprintf(buf, "<CFMutableDictionaryRef object at 0x%%08.8x for 0x%%08.8x>", CFGetTypeID(self->ob_itself), self, self->ob_itself);""")
+		Output("""sprintf(buf, "<CFMutableDictionaryRef object at 0x%%08.8x for 0x%%08.8x>", self, self->ob_itself);""")
 		Output("return PyString_FromString(buf);")
 		OutRbrace()
 	
@@ -208,7 +224,7 @@
 		Output("static PyObject * %s_repr(%s *self)", self.prefix, self.objecttype)
 		OutLbrace()
 		Output("char buf[100];")
-		Output("""sprintf(buf, "<CFDataRef object at 0x%%08.8x for 0x%%08.8x>", CFGetTypeID(self->ob_itself), self, self->ob_itself);""")
+		Output("""sprintf(buf, "<CFDataRef object at 0x%%08.8x for 0x%%08.8x>", self, self->ob_itself);""")
 		Output("return PyString_FromString(buf);")
 		OutRbrace()
 	
@@ -220,7 +236,7 @@
 		Output("static PyObject * %s_repr(%s *self)", self.prefix, self.objecttype)
 		OutLbrace()
 		Output("char buf[100];")
-		Output("""sprintf(buf, "<CFMutableDataRef object at 0x%%08.8x for 0x%%08.8x>", CFGetTypeID(self->ob_itself), self, self->ob_itself);""")
+		Output("""sprintf(buf, "<CFMutableDataRef object at 0x%%08.8x for 0x%%08.8x>", self, self->ob_itself);""")
 		Output("return PyString_FromString(buf);")
 		OutRbrace()
 
@@ -232,7 +248,7 @@
 		Output("static PyObject * %s_repr(%s *self)", self.prefix, self.objecttype)
 		OutLbrace()
 		Output("char buf[100];")
-		Output("""sprintf(buf, "<CFStringRef object at 0x%%08.8x for 0x%%08.8x>", CFGetTypeID(self->ob_itself), self, self->ob_itself);""")
+		Output("""sprintf(buf, "<CFStringRef object at 0x%%08.8x for 0x%%08.8x>", self, self->ob_itself);""")
 		Output("return PyString_FromString(buf);")
 		OutRbrace()
 
@@ -244,7 +260,19 @@
 		Output("static PyObject * %s_repr(%s *self)", self.prefix, self.objecttype)
 		OutLbrace()
 		Output("char buf[100];")
-		Output("""sprintf(buf, "<CFMutableStringRef object at 0x%%08.8x for 0x%%08.8x>", CFGetTypeID(self->ob_itself), self, self->ob_itself);""")
+		Output("""sprintf(buf, "<CFMutableStringRef object at 0x%%08.8x for 0x%%08.8x>", self, self->ob_itself);""")
+		Output("return PyString_FromString(buf);")
+		OutRbrace()
+
+class CFURLRefObjectDefinition(MyGlobalObjectDefinition):
+	basechain = "&CFTypeRefObj_chain"
+	
+	def outputRepr(self):
+		Output()
+		Output("static PyObject * %s_repr(%s *self)", self.prefix, self.objecttype)
+		OutLbrace()
+		Output("char buf[100];")
+		Output("""sprintf(buf, "<CFURL object at 0x%%08.8x for 0x%%08.8x>", self, self->ob_itself);""")
 		Output("return PyString_FromString(buf);")
 		OutRbrace()
 
@@ -256,14 +284,15 @@
 # Create the generator groups and link them
 module = MacModule(MODNAME, MODPREFIX, includestuff, finalstuff, initstuff)
 CFTypeRef_object = CFTypeRefObjectDefinition('CFTypeRef', 'CFTypeRefObj', 'CFTypeRef')
-CFArrayRef_object = CFTypeRefObjectDefinition('CFArrayRef', 'CFArrayRefObj', 'CFArrayRef')
-CFMutableArrayRef_object = CFTypeRefObjectDefinition('CFMutableArrayRef', 'CFMutableArrayRefObj', 'CFMutableArrayRef')
-CFDictionaryRef_object = CFTypeRefObjectDefinition('CFDictionaryRef', 'CFDictionaryRefObj', 'CFDictionaryRef')
-CFMutableDictionaryRef_object = CFTypeRefObjectDefinition('CFMutableDictionaryRef', 'CFMutableDictionaryRefObj', 'CFMutableDictionaryRef')
-CFDataRef_object = CFTypeRefObjectDefinition('CFDataRef', 'CFDataRefObj', 'CFDataRef')
-CFMutableDataRef_object = CFTypeRefObjectDefinition('CFMutableDataRef', 'CFMutableDataRefObj', 'CFMutableDataRef')
-CFStringRef_object = CFTypeRefObjectDefinition('CFStringRef', 'CFStringRefObj', 'CFStringRef')
-CFMutableStringRef_object = CFTypeRefObjectDefinition('CFMutableStringRef', 'CFMutableStringRefObj', 'CFMutableStringRef')
+CFArrayRef_object = CFArrayRefObjectDefinition('CFArrayRef', 'CFArrayRefObj', 'CFArrayRef')
+CFMutableArrayRef_object = CFMutableArrayRefObjectDefinition('CFMutableArrayRef', 'CFMutableArrayRefObj', 'CFMutableArrayRef')
+CFDictionaryRef_object = CFDictionaryRefObjectDefinition('CFDictionaryRef', 'CFDictionaryRefObj', 'CFDictionaryRef')
+CFMutableDictionaryRef_object = CFMutableDictionaryRefObjectDefinition('CFMutableDictionaryRef', 'CFMutableDictionaryRefObj', 'CFMutableDictionaryRef')
+CFDataRef_object = CFDataRefObjectDefinition('CFDataRef', 'CFDataRefObj', 'CFDataRef')
+CFMutableDataRef_object = CFMutableDataRefObjectDefinition('CFMutableDataRef', 'CFMutableDataRefObj', 'CFMutableDataRef')
+CFStringRef_object = CFStringRefObjectDefinition('CFStringRef', 'CFStringRefObj', 'CFStringRef')
+CFMutableStringRef_object = CFMutableStringRefObjectDefinition('CFMutableStringRef', 'CFMutableStringRefObj', 'CFMutableStringRef')
+CFURLRef_object = CFURLRefObjectDefinition('CFURLRef', 'CFURLRefObj', 'CFURLRef')
 
 # ADD object here
 
@@ -276,6 +305,7 @@
 module.addobject(CFMutableDataRef_object)
 module.addobject(CFStringRef_object)
 module.addobject(CFMutableStringRef_object)
+module.addobject(CFURLRef_object)
 # ADD addobject call here
 
 # Create the generator classes used to populate the lists
@@ -293,6 +323,7 @@
 CFMutableDataRef_methods = []
 CFStringRef_methods = []
 CFMutableStringRef_methods = []
+CFURLRef_methods = []
 
 # ADD _methods initializer here
 execfile(INPUTFILE)
@@ -310,6 +341,7 @@
 for f in CFMutableDataRef_methods: CFMutableDataRef_object.add(f)
 for f in CFStringRef_methods: CFStringRef_object.add(f)
 for f in CFMutableStringRef_methods: CFMutableStringRef_object.add(f)
+for f in CFURLRef_methods: CFURLRef_object.add(f)
 
 # ADD add forloop here