Index: waeup/branches/ulif-rewrite/src/waeup/university/courserefs.txt
===================================================================
--- waeup/branches/ulif-rewrite/src/waeup/university/courserefs.txt	(revision 4488)
+++ waeup/branches/ulif-rewrite/src/waeup/university/courserefs.txt	(revision 4488)
@@ -0,0 +1,118 @@
+Course references
+*****************
+
+Courses are referenced by certificate courses.
+
+:Test-Layer: functional
+
+We can be sure, that when removing courses or references to them,
+other data will be handled in a way we expect. That is, 
+
+* when we remove a course, we want all references to it be removed as
+  well
+
+* when we remove a reference to a course, nothing else should be
+  touched but only this very reference.
+
+
+As correct deletion of references needs support of catalogs (we lookup
+catalogs to find references), we need a fully blown ZODB here,
+including an instance of :class:`waeup.app.University`, as this is our
+`ISite` object where the catalogs are stored.
+
+We create a complete university tree, starting with a
+:class:`University` instance and going down to courses, certificats
+and course certificates:
+
+    >>> from waeup.app import University
+    >>> root = getRootFolder()
+    >>> root['app'] = University()
+
+We have to set the site, to enable proper working of catalogs and
+`IObjectRemoved` handlers:
+
+    >>> from zope.app.component.hooks import setSite
+    >>> setSite(root['app'])
+
+    >>> from zope.component import createObject
+    >>> faculty = createObject('waeup.Faculty')
+    >>> faculty.code = 'FAC'
+    >>> root['app'].faculties.addFaculty(faculty)
+    >>> fac = root['app'].faculties['FAC']
+
+    >>> dept = createObject('waeup.Department')
+    >>> dept.code = 'DEPT'
+    >>> root['app'].faculties['FAC'].addDepartment(dept)
+
+    >>> course = createObject('waeup.Course')
+    >>> course.code = 'CRS1'
+    >>> fac['DEPT'].courses.addCourse(course)
+
+Now let's add another department, which will also hold a course:
+
+    >>> dept2 = createObject('waeup.Department')
+    >>> dept2.code = 'DEPT2'
+    >>> root['app'].faculties['FAC'].addDepartment(dept2)
+
+    >>> course = createObject('waeup.Course')
+    >>> course.code = 'CRS2'
+    >>> fac['DEPT2'].courses.addCourse(course)
+
+Finally, we add a certificate with references (certificate courses) to
+the created courses:
+
+    >>> cert = createObject('waeup.Certificate')
+    >>> cert.code = 'CERT'
+    >>> fac['DEPT'].certificates.addCertificate(cert)
+
+    >>> fac['DEPT'].certificates['CERT'].addCourseRef(
+    ...   fac['DEPT'].courses['CRS1'])
+
+    >>> fac['DEPT'].certificates['CERT'].addCourseRef(
+    ...   fac['DEPT2'].courses['CRS2'])
+
+We add the latter course again, but this time for the second level:
+
+    >>> fac['DEPT'].certificates['CERT'].addCourseRef(
+    ...   fac['DEPT2'].courses['CRS2'], level=200)
+
+So, we have three references in our certificate to two different
+courses stored somewhere in the application:
+
+    >>> list(fac['DEPT'].certificates['CERT'])
+    [u'CRS1_100', u'CRS2_100', u'CRS2_200']
+
+Both, the courses themselves and the references to them, are the same
+(not only equal):
+
+    >>> a = root['app'].faculties['FAC']['DEPT']
+    >>> b1 = a.courses['CRS1']
+    >>> b2 = a.certificates['CERT']['CRS1_100'].course
+    >>> b1 is b2
+    True
+
+If we remove the course, also the reference to it in the cert course
+will be gone:
+
+    >>> list(a.certificates['CERT'])
+    [u'CRS1_100', u'CRS2_100', u'CRS2_200']
+
+    >>> list(a.courses)
+    [u'CRS1']
+
+    >>> del root['app'].faculties['FAC']['DEPT'].courses['CRS1']
+    >>> list(a.certificates['CERT'])
+    [u'CRS2_100', u'CRS2_200']
+
+    >>> list(a.courses)
+    []
+
+If we remove a reference, this will not touch the referenced course
+nor other references:
+
+    >>> del fac['DEPT'].certificates['CERT']['CRS2_200']
+    >>> list(a.certificates['CERT'])
+    [u'CRS2_100']
+
+    >>> list(fac['DEPT2'].courses)
+    [u'CRS2']
