Index: /main/waeup.sirp/trunk/src/waeup/sirp/app.txt
===================================================================
--- /main/waeup.sirp/trunk/src/waeup/sirp/app.txt	(revision 7332)
+++ /main/waeup.sirp/trunk/src/waeup/sirp/app.txt	(revision 7333)
@@ -21,5 +21,5 @@
      An arbitrary object containing "faculties". In the case of
      `University` it is a container of type
-     `waeup.sirp.interfaces.IFacultyContainer`.
+     `waeup.sirp.interfaces.IFacultiesContainer`.
 
 
@@ -59,5 +59,5 @@
 
     >>> myuniversity['faculties']
-    <waeup.sirp.university.facultycontainer.FacultyContainer object at 0x...>
+    <waeup.sirp.university.facultiescontainer.FacultiesContainer object at 0x...>
 
   >>> myuniversity['students']
Index: /main/waeup.sirp/trunk/src/waeup/sirp/browser/breadcrumbs.py
===================================================================
--- /main/waeup.sirp/trunk/src/waeup/sirp/browser/breadcrumbs.py	(revision 7332)
+++ /main/waeup.sirp/trunk/src/waeup/sirp/browser/breadcrumbs.py	(revision 7333)
@@ -109,8 +109,8 @@
         return (self.context, 'administration')
 
-class FacultyContainerBreadcrumb(Breadcrumb):
+class FacultiesContainerBreadcrumb(Breadcrumb):
     """A breadcrumb for faculty containers.
     """
-    grok.context(interfaces.IFacultyContainer)
+    grok.context(interfaces.IFacultiesContainer)
     title = u'Academics'
 
@@ -179,14 +179,14 @@
     grok.context(interfaces.ICertificate)        
 
-class CourseContainerBreadcrumb(Breadcrumb):
+class CoursesContainerBreadcrumb(Breadcrumb):
     """ We don't want course container breadcrumbs.
     """
-    grok.context(interfaces.ICourseContainer)
+    grok.context(interfaces.ICoursesContainer)
     grok.implements(IBreadcrumbIgnorable)
 
-class CertificateContainerBreadcrumb(Breadcrumb):
+class CertificatesContainerBreadcrumb(Breadcrumb):
     """ We don't want course container breadcrumbs.
     """
-    grok.context(interfaces.ICertificateContainer)
+    grok.context(interfaces.ICertificatesContainer)
     grok.implements(IBreadcrumbIgnorable)
 
Index: /main/waeup.sirp/trunk/src/waeup/sirp/browser/browser.txt
===================================================================
--- /main/waeup.sirp/trunk/src/waeup/sirp/browser/browser.txt	(revision 7332)
+++ /main/waeup.sirp/trunk/src/waeup/sirp/browser/browser.txt	(revision 7333)
@@ -517,11 +517,11 @@
 --------------
 
-Courses are stored in :class:`ICourseContainer` instances with their
-code as key. CourseContainers are normally availabe as `course`
+Courses are stored in :class:`ICoursesContainer` instances with their
+code as key. CoursesContainers are normally availabe as `course`
 attribute of :class:`waeup.sirp.university.department.Department`
 instances.
 
 To ease the life of users we do not require to browse the
-coursecontainers (which have a rather flat user interface), but
+coursescontainers (which have a rather flat user interface), but
 provide adding of courses in department views.
 
@@ -728,11 +728,11 @@
 -------------------
 
-Certificates are stored in :class:`ICertificateContainer` instances
-with their code as key. CertificateContainers are normally availabe as
+Certificates are stored in :class:`ICertificatesContainer` instances
+with their code as key. CertificatesContainers are normally availabe as
 `certificates` attribute of
 :class:`waeup.sirp.university.department.Department` instances.
 
 To ease the life of users we do not require to browse the
-certificatecontainers (which have in fact no user interface), but
+certificatescontainers (which have in fact no user interface), but
 provide adding of certificates in department views.
 
Index: /main/waeup.sirp/trunk/src/waeup/sirp/browser/interfaces.py
===================================================================
--- /main/waeup.sirp/trunk/src/waeup/sirp/browser/interfaces.py	(revision 7332)
+++ /main/waeup.sirp/trunk/src/waeup/sirp/browser/interfaces.py	(revision 7333)
@@ -23,6 +23,6 @@
     ISIRPObject, IUniversity, IUsersContainer, IDataCenter)
 from waeup.sirp.university.interfaces import (
-    IFacultyContainer, IFaculty, IFacultyAdd, IDepartment, IDepartmentAdd,
-    ICourseContainer, ICourse, ICourseAdd, ICertificateContainer,
+    IFacultiesContainer, IFaculty, IFacultyAdd, IDepartment, IDepartmentAdd,
+    ICoursesContainer, ICourse, ICourseAdd, ICertificatesContainer,
     ICertificate, ICertificateAdd, ICertificateCourse, ICertificateCourseAdd)
 
Index: /main/waeup.sirp/trunk/src/waeup/sirp/browser/pages.py
===================================================================
--- /main/waeup.sirp/trunk/src/waeup/sirp/browser/pages.py	(revision 7332)
+++ /main/waeup.sirp/trunk/src/waeup/sirp/browser/pages.py	(revision 7333)
@@ -41,5 +41,5 @@
     SIRPDisplayFormPage, NullValidator)
 from waeup.sirp.browser.interfaces import (
-    IUniversity, IFacultyContainer, IFaculty, IFacultyAdd,
+    IUniversity, IFacultiesContainer, IFaculty, IFacultyAdd,
     IDepartment, IDepartmentAdd, ICourse, ICourseAdd, ICertificate,
     ICertificateAdd, ICertificateCourse, ICertificateCourseAdd)
@@ -539,5 +539,5 @@
     """General search page for the academics section.
     """
-    grok.context(IFacultyContainer)
+    grok.context(IFacultiesContainer)
     grok.name('search')
     grok.template('searchpage')
@@ -1173,11 +1173,11 @@
 
 #
-# FacultyContainer pages...
-#
-
-class FacultyContainerPage(SIRPPage):
+# FacultiesContainer pages...
+#
+
+class FacultiesContainerPage(SIRPPage):
     """ Index page for faculty containers.
     """
-    grok.context(IFacultyContainer)
+    grok.context(IFacultiesContainer)
     grok.require('waeup.viewAcademics')
     grok.name('index')
@@ -1187,11 +1187,11 @@
     grok.template('facultypage')
 
-class FacultyContainerManageFormPage(SIRPEditFormPage):
+class FacultiesContainerManageFormPage(SIRPEditFormPage):
     """Manage the basic properties of a `Faculty` instance.
     """
-    grok.context(IFacultyContainer)
+    grok.context(IFacultiesContainer)
     grok.name('manage')
     grok.require('waeup.manageUniversity')
-    grok.template('facultycontainermanagepage')
+    grok.template('facultiescontainermanagepage')
     pnav = 1
     taboneactions = ['Add faculty', 'Remove selected','Cancel']
@@ -1206,5 +1206,5 @@
         tabs.need()
         warning.need()
-        return super(FacultyContainerManageFormPage, self).update()
+        return super(FacultiesContainerManageFormPage, self).update()
 
     @jsaction('Remove selected')
@@ -1227,5 +1227,5 @@
     """ Page form to add a new faculty to a faculty container.
     """
-    grok.context(IFacultyContainer)
+    grok.context(IFacultiesContainer)
     grok.require('waeup.manageUniversity')
     grok.name('add')
Index: /main/waeup.sirp/trunk/src/waeup/sirp/browser/templates/facultiescontainermanagepage.pt
===================================================================
--- /main/waeup.sirp/trunk/src/waeup/sirp/browser/templates/facultiescontainermanagepage.pt	(revision 7333)
+++ /main/waeup.sirp/trunk/src/waeup/sirp/browser/templates/facultiescontainermanagepage.pt	(revision 7333)
@@ -0,0 +1,63 @@
+<h2 i18n:translate=""
+    tal:condition="view/label"
+    tal:content="view/label">Label</h2>
+
+<div class="form-status"
+    tal:define="status view/status"
+    tal:condition="status">
+    Form Status:
+    <span i18n:translate="" tal:content="view/status">
+      Form status summary
+    </span>
+</div>
+
+<form action="." tal:attributes="action request/URL" method="POST"
+      class="edit-form" enctype="multipart/form-data">
+
+  <div id="tabs">
+    <ul>
+      <li><a href="#tab-1">
+        <span tal:content="view/subunits">Contents</span>
+      </a></li>
+    </ul>
+
+    <div id="tab-1">
+      <h3 tal:content="view/subunits">Faculties</h3>
+      <table class="zebra">
+        <thead>
+          <tr>
+            <th>&nbsp;</th><th>Code</th><th>Title</th>
+          </tr>
+        </thead>
+        <tbody>
+          <tr tal:repeat="dep context/values">
+            <td>
+              <input type="checkbox"
+                     name="val_id"
+                     tal:attributes="value dep/code" />
+            </td>
+            <td>
+              <a tal:attributes="href python: view.url(dep)"
+                 tal:content="dep/__name__">
+                ID
+              </a>
+            </td>
+            <td>
+              <span tal:content="dep/title">
+                ID
+              </span>
+            </td>
+          </tr>
+        </tbody>
+      </table>
+      <div class="actionButtons" tal:condition="view/availableActions">
+        <span tal:repeat="action view/actions"
+              tal:omit-tag="">
+          <input tal:condition="python:action.label in view.taboneactions"
+                 tal:replace="structure action/render"/>
+        </span>
+      </div>
+
+    </div>
+  </div>
+</form>
Index: in/waeup.sirp/trunk/src/waeup/sirp/browser/templates/facultycontainermanagepage.pt
===================================================================
--- /main/waeup.sirp/trunk/src/waeup/sirp/browser/templates/facultycontainermanagepage.pt	(revision 7332)
+++ 	(revision )
@@ -1,63 +1,0 @@
-<h2 i18n:translate=""
-    tal:condition="view/label"
-    tal:content="view/label">Label</h2>
-
-<div class="form-status"
-    tal:define="status view/status"
-    tal:condition="status">
-    Form Status:
-    <span i18n:translate="" tal:content="view/status">
-      Form status summary
-    </span>
-</div>
-
-<form action="." tal:attributes="action request/URL" method="POST"
-      class="edit-form" enctype="multipart/form-data">
-
-  <div id="tabs">
-    <ul>
-      <li><a href="#tab-1">
-        <span tal:content="view/subunits">Contents</span>
-      </a></li>
-    </ul>
-
-    <div id="tab-1">
-      <h3 tal:content="view/subunits">Faculties</h3>
-      <table class="zebra">
-        <thead>
-          <tr>
-            <th>&nbsp;</th><th>Code</th><th>Title</th>
-          </tr>
-        </thead>
-        <tbody>
-          <tr tal:repeat="dep context/values">
-            <td>
-              <input type="checkbox"
-                     name="val_id"
-                     tal:attributes="value dep/code" />
-            </td>
-            <td>
-              <a tal:attributes="href python: view.url(dep)"
-                 tal:content="dep/__name__">
-                ID
-              </a>
-            </td>
-            <td>
-              <span tal:content="dep/title">
-                ID
-              </span>
-            </td>
-          </tr>
-        </tbody>
-      </table>
-      <div class="actionButtons" tal:condition="view/availableActions">
-        <span tal:repeat="action view/actions"
-              tal:omit-tag="">
-          <input tal:condition="python:action.label in view.taboneactions"
-                 tal:replace="structure action/render"/>
-        </span>
-      </div>
-
-    </div>
-  </div>
-</form>
Index: /main/waeup.sirp/trunk/src/waeup/sirp/browser/viewlets.py
===================================================================
--- /main/waeup.sirp/trunk/src/waeup/sirp/browser/viewlets.py	(revision 7332)
+++ /main/waeup.sirp/trunk/src/waeup/sirp/browser/viewlets.py	(revision 7333)
@@ -22,9 +22,9 @@
 from zope.traversing.browser import absoluteURL
 from waeup.sirp.browser.pages import (
-    UniversityPage, FacultyContainerPage, DatacenterPage, FacultyPage,
+    UniversityPage, FacultiesContainerPage, DatacenterPage, FacultyPage,
     DepartmentPage, CoursePage, CertificatePage, CertificateCoursePage,
     UsersContainerPage, UserManageFormPage)
 from waeup.sirp.browser.interfaces import (
-    IFacultyContainer, IFaculty, IDepartment, ICourse, ICertificate,
+    IFacultiesContainer, IFaculty, IDepartment, ICourse, ICertificate,
     ICertificateCourse, IBreadcrumbContainer, IUniversity, IUsersContainer)
 from waeup.sirp.interfaces import (ISIRPObject, ISIRPXMLExporter,
@@ -396,16 +396,16 @@
     text = 'Edit settings'
 
-class ManageFacultyContainerActionButton(ManageActionButton):
+class ManageFacultiesContainerActionButton(ManageActionButton):
     """ 'Manage settings' button for faculties.
     """
-    grok.context(IFacultyContainer)
-    grok.view(FacultyContainerPage)
+    grok.context(IFacultiesContainer)
+    grok.view(FacultiesContainerPage)
     text = 'Manage academic section'
 
-class SearchFacultyContainerActionButton(ManageActionButton):
+class SearchFacultiesContainerActionButton(ManageActionButton):
     """ 'Manage settings' button for faculties.
     """
-    grok.context(IFacultyContainer)
-    grok.view(FacultyContainerPage)
+    grok.context(IFacultiesContainer)
+    grok.view(FacultiesContainerPage)
     text = 'Search academic section'
     icon = 'actionicon_search.png'
@@ -468,6 +468,6 @@
 
 #class AddFacultyActionButton(AddActionButton):
-#    grok.context(IFacultyContainer)
-#    grok.view(FacultyContainerPage)
+#    grok.context(IFacultiesContainer)
+#    grok.view(FacultiesContainerPage)
 #    text = 'Add faculty'
     
@@ -504,6 +504,6 @@
 
 #class RemoveFacultyActionButton(RemoveActionButton):
-#    grok.context(IFacultyContainer)
-#    grok.view(FacultyContainerPage)
+#    grok.context(IFacultiesContainer)
+#    grok.view(FacultiesContainerPage)
 #    text = 'Remove faculty'
    
@@ -715,10 +715,10 @@
 
 
-class FacultyContainerListHead(grok.Viewlet):
+class FacultiesContainerListHead(grok.Viewlet):
     """The header line of faculty container subobject lists.
     """
     grok.order(1)
     grok.viewletmanager(SubobjectLister)
-    grok.context(IFacultyContainer)
+    grok.context(IFacultiesContainer)
     grok.require('waeup.viewAcademics')
 
Index: /main/waeup.sirp/trunk/src/waeup/sirp/university/__init__.py
===================================================================
--- /main/waeup.sirp/trunk/src/waeup/sirp/university/__init__.py	(revision 7332)
+++ /main/waeup.sirp/trunk/src/waeup/sirp/university/__init__.py	(revision 7333)
@@ -1,7 +1,7 @@
 # Make this a package.
 from waeup.sirp.university.course import Course
-from waeup.sirp.university.coursecontainer import CourseContainer
+from waeup.sirp.university.coursescontainer import CoursesContainer
 from waeup.sirp.university.faculty import Faculty
-from waeup.sirp.university.facultycontainer import FacultyContainer
+from waeup.sirp.university.facultiescontainer import FacultiesContainer
 __all__ = (
-    'Course', 'CourseContainer', 'Faculty', 'FacultyContainer')
+    'Course', 'CoursesContainer', 'Faculty', 'FacultiesContainer')
Index: /main/waeup.sirp/trunk/src/waeup/sirp/university/api.txt
===================================================================
--- /main/waeup.sirp/trunk/src/waeup/sirp/university/api.txt	(revision 7332)
+++ /main/waeup.sirp/trunk/src/waeup/sirp/university/api.txt	(revision 7333)
@@ -15,10 +15,10 @@
 
    certificate.txt
-   certificatecontainer.txt
+   certificatescontainer.txt
    course.txt
-   coursecontainer.txt
+   coursescontainer.txt
    department.txt
    faculty.txt
-   facultycontainer.txt
+   facultiescontainer.txt
 
 Additional infos about the referrers of courses and how they are
Index: /main/waeup.sirp/trunk/src/waeup/sirp/university/batching.py
===================================================================
--- /main/waeup.sirp/trunk/src/waeup/sirp/university/batching.py	(revision 7332)
+++ /main/waeup.sirp/trunk/src/waeup/sirp/university/batching.py	(revision 7333)
@@ -28,5 +28,5 @@
 from waeup.sirp.interfaces import IBatchProcessor
 from waeup.sirp.university.interfaces import (
-    IFacultyContainer, IFaculty, ICourse, IDepartment, ICertificate,
+    IFacultiesContainer, IFaculty, ICourse, IDepartment, ICertificate,
     ICertificateCourse)
 from waeup.sirp.utils.batching import BatchProcessor
Index: in/waeup.sirp/trunk/src/waeup/sirp/university/certificatecontainer.py
===================================================================
--- /main/waeup.sirp/trunk/src/waeup/sirp/university/certificatecontainer.py	(revision 7332)
+++ 	(revision )
@@ -1,131 +1,0 @@
-## $Id$
-##
-## Copyright (C) 2011 Uli Fouquet & Henrik Bettermann
-## This program is free software; you can redistribute it and/or modify
-## it under the terms of the GNU General Public License as published by
-## the Free Software Foundation; either version 2 of the License, or
-## (at your option) any later version.
-##
-## This program is distributed in the hope that it will be useful,
-## but WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-## GNU General Public License for more details.
-##
-## You should have received a copy of the GNU General Public License
-## along with this program; if not, write to the Free Software
-## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-##
-"""Containers for certificates.
-"""
-import grok
-from zope.catalog.interfaces import ICatalog
-from zope.component.interfaces import IFactory
-from zope.component import queryUtility
-from zope.interface import implementedBy
-from waeup.sirp.interfaces import DuplicationError
-from waeup.sirp.university.interfaces import (
-    ICertificateContainer, ICertificate)
-
-class CertificateContainer(grok.Container):
-    """A storage for certificates.
-
-    A :class:`CertificateContainer` stores
-    :class:`waeup.sirp.university.Certificate` instances.
-
-    It is a :class:`grok.Container` basically acting like a standard
-    Python dictionary. That means you can add certificates like items
-    in a normal dictionary and also get certificates by using
-    :meth:`values`, :meth:`keys`, and :meth:`items`.
-
-    This container type is picky about its contents: only real
-    certificates can be stored here and each new certificate must
-    provide a unique `code`. See :meth:`addCertificate` for details.
-
-    Each :class:`CertificateContainer` provides
-    :class:`ICertificateContainer`.
-    """
-    grok.implements(ICertificateContainer)
-    grok.require('waeup.manageUniversity')
-
-    def __setitem__(self, name, certificate):
-        """Insert `certificate` with `name` as key into container.
-
-        The `certificate` must be an object implementing
-        :class:`waeup.sirp.university.interfaces.ICertificate`. If
-        not, a :exc:`TypeError` is raised.
-
-        If the certificate `code` does not equal `name` a
-        :exc:`ValueError` is raised.
-
-        If the `code` attribute of `certificate` is already in use by
-        another certificate stored in the local site
-        (:class:`waeup.sirp.app.University` instance), then a
-        :exc:`waeup.sirp.interfaces.DuplicationError` will be raised.
-
-        If `name` is already used as a key, a :exc:`KeyError` will be
-        raised.
-        """
-        if not ICertificate.providedBy(certificate):
-            raise TypeError('CertificateContainers contain only '
-                            'ICertificate instances')
-
-        # Only accept certs with code == key.
-        if certificate.code != name:
-            raise ValueError('key must match certificate code: '
-                             '%s, %s' % (name, certificate.code))
-
-        # Lookup catalog. If we find none: no duplicates possible.
-        cat = queryUtility(ICatalog, name='certificates_catalog', default=None)
-        if cat is not None:
-            entries = cat.searchResults(
-                code=(certificate.code,certificate.code))
-            if len(entries) > 0:
-                raise DuplicationError(
-                    'Certificate exists already elsewhere.', entries)
-        else:
-            # No catalog, then this addition won't do harm to anything.
-            pass
-        super(CertificateContainer, self).__setitem__(name, certificate)
-
-    def addCertificate(self, certificate):
-        """Add `certificate` to the container.
-
-        The certificate must be an object implementing
-        :class:`waeup.sirp.university.interfaces.ICertificate`. If
-        not, a :exc:`TypeError` is raised.
-
-        The certificate will be stored in the container with its
-        `code` attribute as key. If this key is already used for
-        another certificate stored in the local site
-        (:class:`waeup.sirp.app.University` instance), then a
-        :exc:`waeup.sirp.interfaces.DuplicationError` will be raised.
-        """
-        self[getattr(certificate, 'code', None)] = certificate
-
-    def clear(self):
-        """Remove all contents from the certificate container.
-
-        This methods is pretty fast and optimized. Use it instead of
-        removing all items manually yourself.
-        """
-        # This internal function is implemented in C and thus much
-        # faster as we could do it in pure Python.
-        self._SampleContainer__data.clear()
-        # The length attribute is 'lazy'. See `zope.container` for details.
-        # This way we make sure, the next time len() is called, it returns
-        # the real value and not a cached one.
-        del self.__dict__['_BTreeContainer__len']
-
-class CertificateContainerFactory(grok.GlobalUtility):
-    """A factory for certificate containers.
-    """
-    grok.implements(IFactory)
-    grok.name(u'waeup.CertificateContainer')
-    title = u"Create a new certificate container.",
-    description = u"This factory instantiates new certificate containers."
-
-    def __call__(self, *args, **kw):
-        return CertificateContainer(*args, **kw)
-
-    def getInterfaces(self):
-        return implementedBy(CertificateContainer)
Index: in/waeup.sirp/trunk/src/waeup/sirp/university/certificatecontainer.txt
===================================================================
--- /main/waeup.sirp/trunk/src/waeup/sirp/university/certificatecontainer.txt	(revision 7332)
+++ 	(revision )
@@ -1,149 +1,0 @@
-:mod:`waeup.sirp.university.certificatecontainer` -- Certificate containers
-***************************************************************************
-
-.. module:: waeup.sirp.university.certificatecontainer
-
-Containers for certificates.
-
-.. :doctest:
-.. :layer: waeup.sirp.testing.SIRPUnitTestLayer
-
-
-Content Classes (models and containers)
-=======================================
-
-:class:`CertificateContainer`
------------------------------
-
-.. class:: CertificateContainer()
-
-   Create a certificate container instance.
-
-   .. attribute:: grok.implements(ICertificateContainer)
-
-   .. attribute:: grok.require('waeup.manageUniversity')
-
-   :class:`CertificateContainer` instances are instances of
-   :class:`grok.Container` that hold and manage instances of
-   :class:`waeup.sirp.university.certificate.Certificate`.
-
-     >>> from waeup.sirp.university.certificatecontainer import CertificateContainer
-     >>> mycontainer = CertificateContainer()
-     >>> mycontainer
-     <waeup.sirp.university.certificatecontainer.CertificateContainer object at 0x...>
-
-   Certificate containers provide `ICertificateContainer`:
-
-     >>> from waeup.sirp.university.interfaces import ICertificateContainer
-     >>> ICertificateContainer.providedBy(mycontainer)
-     True
-
-   We can be sure, that the full interface is supported by the
-   CertificateContainer class:
-
-     >>> from zope.interface.verify import verifyClass
-     >>> verifyClass(ICertificateContainer, CertificateContainer)
-     True
-
-   As normal ``grok.Container``, :class:`CertificateContainer` instances
-   can be used like dicts:
-
-     >>> list(mycontainer.keys())
-     []
-
-   .. method:: addCertificate(certificate)
-
-      Add a certificate.
-
-      *certificate* must be an instance of
-      :class:`waeup.sirp.university.certificate.Certificate`:
-
-        >>> from waeup.sirp.university.certificatecontainer import (
-        ...   CertificateContainer)
-        >>> mycontainer = CertificateContainer()
-        >>> mycontainer.addCertificate('blah')
-        Traceback (most recent call last):
-        ...
-        TypeError: CertificateContainers contain only ICertificate instances
-
-      The key of added items is the ``code`` attribute:
-
-        >>> from waeup.sirp.university.certificate import Certificate
-        >>> mycertificate = Certificate(code='CERTIFICATE1')
-        >>> mycontainer.addCertificate(mycertificate)
-        >>> list(mycontainer.keys())
-        [u'CERTIFICATE1']
-
-   .. method:: clear()
-
-      Remove all contained certificates:
-
-        >>> len(mycontainer.items())
-        1
-
-        >>> mycontainer.clear()
-        >>> len(mycontainer.items())
-        0
-
-Utilities
-=========
-
-:class:`CertificateContainerFactory`
-------------------------------------
-
-.. class:: CertificateContainerFactory()
-
-   .. attribute:: grok.name(u'waeup.CertificateContainer')
-
-   .. attribute:: grok.implements(IFactory)
-
-   A named utility to deliver new instances of :class:`CertificateContainer`
-   without the need to import the implementation before:
-
-     >>> from zope.component import createObject
-     >>> mycertificatecontainer = createObject(u'waeup.CertificateContainer')
-     >>> mycertificatecontainer
-     <waeup.sirp.university.certificatecontainer.CertificateContainer object at 0x...>
-
-   The factory complies with the specifications from the
-   :class:`IFactory` insterface:
-
-     >>> from zope.interface.verify import verifyClass
-     >>> from zope.component.interfaces import IFactory
-     >>> from waeup.sirp.university.certificatecontainer import (
-     ...   CertificateContainerFactory)
-     >>> verifyClass(IFactory, CertificateContainerFactory)
-     True
-
-   This means also, that we can get the interfaces of the created
-   object from the factory:
-
-     >>> certificatecontainer_factory = CertificateContainerFactory()
-     >>> certificatecontainer_factory.getInterfaces()
-     <implementedBy waeup.sirp.university.certificatecontainer.CertificateContainer>
-
-
-Examples
-========
-
-Getting a certificate container
--------------------------------
-
-We can easily create `CertificateContainers`:
-
-    >>> from waeup.sirp.university.certificatecontainer import CertificateContainer
-    >>> mycontainer = CertificateContainer()
-
-
-Another way to get a certificate container -- without importing the
-class -- is via factories. We registered a factory for certificate
-containers under the name ``waeup.CertificateContainer``. Now we can
-ask for an object by calling the appropriate factory:
-
-    >>> from zope.component import createObject
-    >>> createObject(u'waeup.CertificateContainer')
-    <waeup.sirp.university.certificatecontainer.CertificateContainer object at 0x...>
-
-This way we get a thing that implements ICertificateContainer without
-imports or similar.
-
Index: /main/waeup.sirp/trunk/src/waeup/sirp/university/certificatescontainer.py
===================================================================
--- /main/waeup.sirp/trunk/src/waeup/sirp/university/certificatescontainer.py	(revision 7333)
+++ /main/waeup.sirp/trunk/src/waeup/sirp/university/certificatescontainer.py	(revision 7333)
@@ -0,0 +1,131 @@
+## $Id$
+##
+## Copyright (C) 2011 Uli Fouquet & Henrik Bettermann
+## This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 2 of the License, or
+## (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##
+"""Containers for certificates.
+"""
+import grok
+from zope.catalog.interfaces import ICatalog
+from zope.component.interfaces import IFactory
+from zope.component import queryUtility
+from zope.interface import implementedBy
+from waeup.sirp.interfaces import DuplicationError
+from waeup.sirp.university.interfaces import (
+    ICertificatesContainer, ICertificate)
+
+class CertificatesContainer(grok.Container):
+    """A storage for certificates.
+
+    A :class:`CertificatesContainer` stores
+    :class:`waeup.sirp.university.Certificate` instances.
+
+    It is a :class:`grok.Container` basically acting like a standard
+    Python dictionary. That means you can add certificates like items
+    in a normal dictionary and also get certificates by using
+    :meth:`values`, :meth:`keys`, and :meth:`items`.
+
+    This container type is picky about its contents: only real
+    certificates can be stored here and each new certificate must
+    provide a unique `code`. See :meth:`addCertificate` for details.
+
+    Each :class:`CertificatesContainer` provides
+    :class:`ICertificatesContainer`.
+    """
+    grok.implements(ICertificatesContainer)
+    grok.require('waeup.manageUniversity')
+
+    def __setitem__(self, name, certificate):
+        """Insert `certificate` with `name` as key into container.
+
+        The `certificate` must be an object implementing
+        :class:`waeup.sirp.university.interfaces.ICertificate`. If
+        not, a :exc:`TypeError` is raised.
+
+        If the certificate `code` does not equal `name` a
+        :exc:`ValueError` is raised.
+
+        If the `code` attribute of `certificate` is already in use by
+        another certificate stored in the local site
+        (:class:`waeup.sirp.app.University` instance), then a
+        :exc:`waeup.sirp.interfaces.DuplicationError` will be raised.
+
+        If `name` is already used as a key, a :exc:`KeyError` will be
+        raised.
+        """
+        if not ICertificate.providedBy(certificate):
+            raise TypeError('CertificatesContainers contain only '
+                            'ICertificate instances')
+
+        # Only accept certs with code == key.
+        if certificate.code != name:
+            raise ValueError('key must match certificate code: '
+                             '%s, %s' % (name, certificate.code))
+
+        # Lookup catalog. If we find none: no duplicates possible.
+        cat = queryUtility(ICatalog, name='certificates_catalog', default=None)
+        if cat is not None:
+            entries = cat.searchResults(
+                code=(certificate.code,certificate.code))
+            if len(entries) > 0:
+                raise DuplicationError(
+                    'Certificate exists already elsewhere.', entries)
+        else:
+            # No catalog, then this addition won't do harm to anything.
+            pass
+        super(CertificatesContainer, self).__setitem__(name, certificate)
+
+    def addCertificate(self, certificate):
+        """Add `certificate` to the container.
+
+        The certificate must be an object implementing
+        :class:`waeup.sirp.university.interfaces.ICertificate`. If
+        not, a :exc:`TypeError` is raised.
+
+        The certificate will be stored in the container with its
+        `code` attribute as key. If this key is already used for
+        another certificate stored in the local site
+        (:class:`waeup.sirp.app.University` instance), then a
+        :exc:`waeup.sirp.interfaces.DuplicationError` will be raised.
+        """
+        self[getattr(certificate, 'code', None)] = certificate
+
+    def clear(self):
+        """Remove all contents from the certificate container.
+
+        This methods is pretty fast and optimized. Use it instead of
+        removing all items manually yourself.
+        """
+        # This internal function is implemented in C and thus much
+        # faster as we could do it in pure Python.
+        self._SampleContainer__data.clear()
+        # The length attribute is 'lazy'. See `zope.container` for details.
+        # This way we make sure, the next time len() is called, it returns
+        # the real value and not a cached one.
+        del self.__dict__['_BTreeContainer__len']
+
+class CertificatesContainerFactory(grok.GlobalUtility):
+    """A factory for certificate containers.
+    """
+    grok.implements(IFactory)
+    grok.name(u'waeup.CertificatesContainer')
+    title = u"Create a new container for certificates.",
+    description = u"This factory instantiates new containers for certificates."
+
+    def __call__(self, *args, **kw):
+        return CertificatesContainer(*args, **kw)
+
+    def getInterfaces(self):
+        return implementedBy(CertificatesContainer)
Index: /main/waeup.sirp/trunk/src/waeup/sirp/university/certificatescontainer.txt
===================================================================
--- /main/waeup.sirp/trunk/src/waeup/sirp/university/certificatescontainer.txt	(revision 7333)
+++ /main/waeup.sirp/trunk/src/waeup/sirp/university/certificatescontainer.txt	(revision 7333)
@@ -0,0 +1,149 @@
+:mod:`waeup.sirp.university.certificatescontainer` -- Certificate containers
+****************************************************************************
+
+.. module:: waeup.sirp.university.certificatescontainer
+
+Containers for certificates.
+
+.. :doctest:
+.. :layer: waeup.sirp.testing.SIRPUnitTestLayer
+
+
+Content Classes (models and containers)
+=======================================
+
+:class:`CertificatesContainer`
+------------------------------
+
+.. class:: CertificatesContainer()
+
+   Create a certificate container instance.
+
+   .. attribute:: grok.implements(ICertificatesContainer)
+
+   .. attribute:: grok.require('waeup.manageUniversity')
+
+   :class:`CertificatesContainer` instances are instances of
+   :class:`grok.Container` that hold and manage instances of
+   :class:`waeup.sirp.university.certificate.Certificate`.
+
+     >>> from waeup.sirp.university.certificatescontainer import CertificatesContainer
+     >>> mycontainer = CertificatesContainer()
+     >>> mycontainer
+     <waeup.sirp.university.certificatescontainer.CertificatesContainer object at 0x...>
+
+   Certificate containers provide `ICertificatesContainer`:
+
+     >>> from waeup.sirp.university.interfaces import ICertificatesContainer
+     >>> ICertificatesContainer.providedBy(mycontainer)
+     True
+
+   We can be sure, that the full interface is supported by the
+   CertificatesContainer class:
+
+     >>> from zope.interface.verify import verifyClass
+     >>> verifyClass(ICertificatesContainer, CertificatesContainer)
+     True
+
+   As normal ``grok.Container``, :class:`CertificatesContainer` instances
+   can be used like dicts:
+
+     >>> list(mycontainer.keys())
+     []
+
+   .. method:: addCertificate(certificate)
+
+      Add a certificate.
+
+      *certificate* must be an instance of
+      :class:`waeup.sirp.university.certificate.Certificate`:
+
+        >>> from waeup.sirp.university.certificatescontainer import (
+        ...   CertificatesContainer)
+        >>> mycontainer = CertificatesContainer()
+        >>> mycontainer.addCertificate('blah')
+        Traceback (most recent call last):
+        ...
+        TypeError: CertificatesContainers contain only ICertificate instances
+
+      The key of added items is the ``code`` attribute:
+
+        >>> from waeup.sirp.university.certificate import Certificate
+        >>> mycertificate = Certificate(code='CERTIFICATE1')
+        >>> mycontainer.addCertificate(mycertificate)
+        >>> list(mycontainer.keys())
+        [u'CERTIFICATE1']
+
+   .. method:: clear()
+
+      Remove all contained certificates:
+
+        >>> len(mycontainer.items())
+        1
+
+        >>> mycontainer.clear()
+        >>> len(mycontainer.items())
+        0
+
+Utilities
+=========
+
+:class:`CertificatesContainerFactory`
+-------------------------------------
+
+.. class:: CertificatesContainerFactory()
+
+   .. attribute:: grok.name(u'waeup.CertificatesContainer')
+
+   .. attribute:: grok.implements(IFactory)
+
+   A named utility to deliver new instances of :class:`CertificatesContainer`
+   without the need to import the implementation before:
+
+     >>> from zope.component import createObject
+     >>> mycertificatescontainer = createObject(u'waeup.CertificatesContainer')
+     >>> mycertificatescontainer
+     <waeup.sirp.university.certificatescontainer.CertificatesContainer object at 0x...>
+
+   The factory complies with the specifications from the
+   :class:`IFactory` insterface:
+
+     >>> from zope.interface.verify import verifyClass
+     >>> from zope.component.interfaces import IFactory
+     >>> from waeup.sirp.university.certificatescontainer import (
+     ...   CertificatesContainerFactory)
+     >>> verifyClass(IFactory, CertificatesContainerFactory)
+     True
+
+   This means also, that we can get the interfaces of the created
+   object from the factory:
+
+     >>> certificatescontainer_factory = CertificatesContainerFactory()
+     >>> certificatescontainer_factory.getInterfaces()
+     <implementedBy waeup.sirp.university.certificatescontainer.CertificatesContainer>
+
+
+Examples
+========
+
+Getting a certificate container
+-------------------------------
+
+We can easily create `CertificatesContainers`:
+
+    >>> from waeup.sirp.university.certificatescontainer import CertificatesContainer
+    >>> mycontainer = CertificatesContainer()
+
+
+Another way to get a certificate container -- without importing the
+class -- is via factories. We registered a factory for certificate
+containers under the name ``waeup.CertificatesContainer``. Now we can
+ask for an object by calling the appropriate factory:
+
+    >>> from zope.component import createObject
+    >>> createObject(u'waeup.CertificatesContainer')
+    <waeup.sirp.university.certificatescontainer.CertificatesContainer object at 0x...>
+
+This way we get a thing that implements ICertificatesContainer without
+imports or similar.
+
Index: /main/waeup.sirp/trunk/src/waeup/sirp/university/course.py
===================================================================
--- /main/waeup.sirp/trunk/src/waeup/sirp/university/course.py	(revision 7332)
+++ /main/waeup.sirp/trunk/src/waeup/sirp/university/course.py	(revision 7333)
@@ -63,5 +63,5 @@
 def handle_course_removed(course, event):
     """If a course is deleted, we make sure that also referrers in a
-       certificatecontainer are removed.
+       certificatescontainer are removed.
     """
     code = course.code
Index: in/waeup.sirp/trunk/src/waeup/sirp/university/coursecontainer.py
===================================================================
--- /main/waeup.sirp/trunk/src/waeup/sirp/university/coursecontainer.py	(revision 7332)
+++ 	(revision )
@@ -1,82 +1,0 @@
-## $Id$
-##
-## Copyright (C) 2011 Uli Fouquet & Henrik Bettermann
-## This program is free software; you can redistribute it and/or modify
-## it under the terms of the GNU General Public License as published by
-## the Free Software Foundation; either version 2 of the License, or
-## (at your option) any later version.
-##
-## This program is distributed in the hope that it will be useful,
-## but WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-## GNU General Public License for more details.
-##
-## You should have received a copy of the GNU General Public License
-## along with this program; if not, write to the Free Software
-## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-##
-"""Course containers.
-"""
-import grok
-from zope.interface import implementedBy
-from zope.component.interfaces import IFactory, ComponentLookupError
-from zope.catalog.interfaces import ICatalog
-from zope.component import queryUtility
-from waeup.sirp.interfaces import DuplicationError
-from waeup.sirp.university.interfaces import ICourseContainer, ICourse
-
-class CourseContainer(grok.Container):
-    """See interfaces for description.
-    """
-    grok.implements(ICourseContainer)
-    grok.require('waeup.manageUniversity')
-
-    def __setitem__(self, name, course):
-        """See corresponding docstring in certificatecontainer.py.
-        """
-        if not ICourse.providedBy(course):
-            raise TypeError('CourseContainers contain only '
-                            'ICourse instances')
-
-        # Only accept courses with code == key.
-        if course.code != name:
-            raise ValueError('key must match course code: '
-                             '%s, %s' % (name, course.code))
-
-        # Lookup catalog. If we find none: no duplicates possible.
-        cat = queryUtility(ICatalog, name='courses_catalog', default=None)
-        if cat is not None:
-            entries = cat.searchResults(
-                code=(course.code,course.code))
-            if len(entries) > 0:
-                raise DuplicationError(
-                    'Course exists already elsewhere.', entries)
-        else:
-            # No catalog, then this addition won't do harm to anything.
-            pass
-        super(CourseContainer, self).__setitem__(name, course)
-
-    def addCourse(self, course):
-        """See corresponding docstring in certificatecontainer.py.
-        """
-        self[getattr(course, 'code', None)] = course
-
-    def clear(self):
-        """See corresponding docstring and comments in certificatecontainer.py.
-        """
-        self._SampleContainer__data.clear()
-        del self.__dict__['_BTreeContainer__len']
-
-class CourseContainerFactory(grok.GlobalUtility):
-    """A factory for course containers.
-    """
-    grok.implements(IFactory)
-    grok.name(u'waeup.CourseContainer')
-    title = u"Create a new course container.",
-    description = u"This factory instantiates new course containers."
-
-    def __call__(self, *args, **kw):
-        return CourseContainer(*args, **kw)
-
-    def getInterfaces(self):
-        return implementedBy(CourseContainer)
Index: in/waeup.sirp/trunk/src/waeup/sirp/university/coursecontainer.txt
===================================================================
--- /main/waeup.sirp/trunk/src/waeup/sirp/university/coursecontainer.txt	(revision 7332)
+++ 	(revision )
@@ -1,147 +1,0 @@
-:mod:`waeup.sirp.university.coursecontainer` -- Course containers
-*****************************************************************
-
-.. module:: waeup.sirp.university.coursecontainer
-
-Containers for courses.
-
-.. :doctest:
-.. :layer: waeup.sirp.testing.SIRPUnitTestLayer
-
-
-Content Classes (models and containers)
-=======================================
-
-:class:`CourseContainer`
-------------------------
-
-.. class:: CourseContainer()
-
-   Create a course container instance.
-
-   .. attribute:: grok.implements(ICourseContainer)
-
-   .. attribute:: grok.require('waeup.manageUniversity')
-
-   :class:`CourseContainer` instances are instances of
-   :class:`grok.Container` that hold and manage instances of
-   :class:`waeup.sirp.university.course.Course`.
-
-     >>> from waeup.sirp.university.coursecontainer import CourseContainer
-     >>> mycontainer = CourseContainer()
-     >>> mycontainer
-     <waeup.sirp.university.coursecontainer.CourseContainer object at 0x...>
-
-   Course containers provide `ICourseContainer`:
-
-     >>> from waeup.sirp.university.interfaces import ICourseContainer
-     >>> ICourseContainer.providedBy(mycontainer)
-     True
-
-   We can be sure, that the full interface is supported by the
-   CourseContainer class:
-
-     >>> from zope.interface.verify import verifyClass
-     >>> verifyClass(ICourseContainer, CourseContainer)
-     True
-
-   As normal ``grok.Container``, :class:`CourseContainer` instances
-   can be used like dicts:
-
-     >>> list(mycontainer.keys())
-     []
-
-   .. method:: addCourse(course)
-
-      Add a course.
-
-      *course* must be an instance of
-      :class:`waeup.sirp.university.course.Course`:
-
-        >>> from waeup.sirp.university.coursecontainer import CourseContainer
-        >>> mycontainer = CourseContainer()
-        >>> mycontainer.addCourse('blah')
-        Traceback (most recent call last):
-        ...
-        TypeError: CourseContainers contain only ICourse instances
-
-      The key of added items is the ``code`` attribute:
-
-        >>> from waeup.sirp.university.course import Course
-        >>> mycourse = Course(code='COURSE1')
-        >>> mycontainer.addCourse(mycourse)
-        >>> list(mycontainer.keys())
-        [u'COURSE1']
-
-   .. method:: clear()
-
-      Remove all contained courses:
-
-        >>> len(mycontainer.items())
-        1
-
-        >>> mycontainer.clear()
-        >>> len(mycontainer.items())
-        0
-
-Utilities
-=========
-
-:class:`CourseContainerFactory`
--------------------------------
-
-.. class:: CourseContainerFactory()
-
-   .. attribute:: grok.name(u'waeup.CourseContainer')
-
-   .. attribute:: grok.implements(IFactory)
-
-   A named utility to deliver new instances of :class:`CourseContainer`
-   without the need to import the implementation before:
-
-     >>> from zope.component import createObject
-     >>> mycoursecontainer = createObject(u'waeup.CourseContainer')
-     >>> mycoursecontainer
-     <waeup.sirp.university.coursecontainer.CourseContainer object at 0x...>
-
-   The factory complies with the specifications from the
-   :class:`IFactory` insterface:
-
-     >>> from zope.interface.verify import verifyClass
-     >>> from zope.component.interfaces import IFactory
-     >>> from waeup.sirp.university.coursecontainer import CourseContainerFactory
-     >>> verifyClass(IFactory, CourseContainerFactory)
-     True
-
-   This means also, that we can get the interfaces of the created
-   object from the factory:
-
-     >>> coursecontainer_factory = CourseContainerFactory()
-     >>> coursecontainer_factory.getInterfaces()
-     <implementedBy waeup.sirp.university.coursecontainer.CourseContainer>
-
-
-Examples
-========
-
-Getting a course container
---------------------------
-
-We can easily create `CourseContainers`:
-
-    >>> from waeup.sirp.university.coursecontainer import CourseContainer
-    >>> mycontainer = CourseContainer()
-
-
-Another way to get a course container -- without importing the class
--- is via factories. We registered a factory for course containers
-under the name ``waeup.CourseContainer``. Now we can ask for an object
-by calling the appropriate factory:
-
-    >>> from zope.component import createObject
-    >>> createObject(u'waeup.CourseContainer')
-    <waeup.sirp.university.coursecontainer.CourseContainer object at 0x...>
-
-This way we get a thing that implements ICourseContainer without
-imports or similar.
-
Index: /main/waeup.sirp/trunk/src/waeup/sirp/university/coursescontainer.py
===================================================================
--- /main/waeup.sirp/trunk/src/waeup/sirp/university/coursescontainer.py	(revision 7333)
+++ /main/waeup.sirp/trunk/src/waeup/sirp/university/coursescontainer.py	(revision 7333)
@@ -0,0 +1,82 @@
+## $Id$
+##
+## Copyright (C) 2011 Uli Fouquet & Henrik Bettermann
+## This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 2 of the License, or
+## (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##
+"""Course containers.
+"""
+import grok
+from zope.interface import implementedBy
+from zope.component.interfaces import IFactory, ComponentLookupError
+from zope.catalog.interfaces import ICatalog
+from zope.component import queryUtility
+from waeup.sirp.interfaces import DuplicationError
+from waeup.sirp.university.interfaces import ICoursesContainer, ICourse
+
+class CoursesContainer(grok.Container):
+    """See interfaces for description.
+    """
+    grok.implements(ICoursesContainer)
+    grok.require('waeup.manageUniversity')
+
+    def __setitem__(self, name, course):
+        """See corresponding docstring in certificatescontainer.py.
+        """
+        if not ICourse.providedBy(course):
+            raise TypeError('CoursesContainers contain only '
+                            'ICourse instances')
+
+        # Only accept courses with code == key.
+        if course.code != name:
+            raise ValueError('key must match course code: '
+                             '%s, %s' % (name, course.code))
+
+        # Lookup catalog. If we find none: no duplicates possible.
+        cat = queryUtility(ICatalog, name='courses_catalog', default=None)
+        if cat is not None:
+            entries = cat.searchResults(
+                code=(course.code,course.code))
+            if len(entries) > 0:
+                raise DuplicationError(
+                    'Course exists already elsewhere.', entries)
+        else:
+            # No catalog, then this addition won't do harm to anything.
+            pass
+        super(CoursesContainer, self).__setitem__(name, course)
+
+    def addCourse(self, course):
+        """See corresponding docstring in certificatescontainer.py.
+        """
+        self[getattr(course, 'code', None)] = course
+
+    def clear(self):
+        """See corresponding docstring and comments in certificatescontainer.py.
+        """
+        self._SampleContainer__data.clear()
+        del self.__dict__['_BTreeContainer__len']
+
+class CoursesContainerFactory(grok.GlobalUtility):
+    """A factory for course containers.
+    """
+    grok.implements(IFactory)
+    grok.name(u'waeup.CoursesContainer')
+    title = u"Create a new container for courses.",
+    description = u"This factory instantiates new containers for courses."
+
+    def __call__(self, *args, **kw):
+        return CoursesContainer(*args, **kw)
+
+    def getInterfaces(self):
+        return implementedBy(CoursesContainer)
Index: /main/waeup.sirp/trunk/src/waeup/sirp/university/coursescontainer.txt
===================================================================
--- /main/waeup.sirp/trunk/src/waeup/sirp/university/coursescontainer.txt	(revision 7333)
+++ /main/waeup.sirp/trunk/src/waeup/sirp/university/coursescontainer.txt	(revision 7333)
@@ -0,0 +1,147 @@
+:mod:`waeup.sirp.university.coursescontainer` -- Course containers
+******************************************************************
+
+.. module:: waeup.sirp.university.coursescontainer
+
+Containers for courses.
+
+.. :doctest:
+.. :layer: waeup.sirp.testing.SIRPUnitTestLayer
+
+
+Content Classes (models and containers)
+=======================================
+
+:class:`CoursesContainer`
+-------------------------
+
+.. class:: CoursesContainer()
+
+   Create a course container instance.
+
+   .. attribute:: grok.implements(ICoursesContainer)
+
+   .. attribute:: grok.require('waeup.manageUniversity')
+
+   :class:`CoursesContainer` instances are instances of
+   :class:`grok.Container` that hold and manage instances of
+   :class:`waeup.sirp.university.course.Course`.
+
+     >>> from waeup.sirp.university.coursescontainer import CoursesContainer
+     >>> mycontainer = CoursesContainer()
+     >>> mycontainer
+     <waeup.sirp.university.coursescontainer.CoursesContainer object at 0x...>
+
+   Course containers provide `ICoursesContainer`:
+
+     >>> from waeup.sirp.university.interfaces import ICoursesContainer
+     >>> ICoursesContainer.providedBy(mycontainer)
+     True
+
+   We can be sure, that the full interface is supported by the
+   CoursesContainer class:
+
+     >>> from zope.interface.verify import verifyClass
+     >>> verifyClass(ICoursesContainer, CoursesContainer)
+     True
+
+   As normal ``grok.Container``, :class:`CoursesContainer` instances
+   can be used like dicts:
+
+     >>> list(mycontainer.keys())
+     []
+
+   .. method:: addCourse(course)
+
+      Add a course.
+
+      *course* must be an instance of
+      :class:`waeup.sirp.university.course.Course`:
+
+        >>> from waeup.sirp.university.coursescontainer import CoursesContainer
+        >>> mycontainer = CoursesContainer()
+        >>> mycontainer.addCourse('blah')
+        Traceback (most recent call last):
+        ...
+        TypeError: CoursesContainers contain only ICourse instances
+
+      The key of added items is the ``code`` attribute:
+
+        >>> from waeup.sirp.university.course import Course
+        >>> mycourse = Course(code='COURSE1')
+        >>> mycontainer.addCourse(mycourse)
+        >>> list(mycontainer.keys())
+        [u'COURSE1']
+
+   .. method:: clear()
+
+      Remove all contained courses:
+
+        >>> len(mycontainer.items())
+        1
+
+        >>> mycontainer.clear()
+        >>> len(mycontainer.items())
+        0
+
+Utilities
+=========
+
+:class:`CoursesContainerFactory`
+--------------------------------
+
+.. class:: CoursesContainerFactory()
+
+   .. attribute:: grok.name(u'waeup.CoursesContainer')
+
+   .. attribute:: grok.implements(IFactory)
+
+   A named utility to deliver new instances of :class:`CoursesContainer`
+   without the need to import the implementation before:
+
+     >>> from zope.component import createObject
+     >>> mycoursescontainer = createObject(u'waeup.CoursesContainer')
+     >>> mycoursescontainer
+     <waeup.sirp.university.coursescontainer.CoursesContainer object at 0x...>
+
+   The factory complies with the specifications from the
+   :class:`IFactory` insterface:
+
+     >>> from zope.interface.verify import verifyClass
+     >>> from zope.component.interfaces import IFactory
+     >>> from waeup.sirp.university.coursescontainer import CoursesContainerFactory
+     >>> verifyClass(IFactory, CoursesContainerFactory)
+     True
+
+   This means also, that we can get the interfaces of the created
+   object from the factory:
+
+     >>> coursescontainer_factory = CoursesContainerFactory()
+     >>> coursescontainer_factory.getInterfaces()
+     <implementedBy waeup.sirp.university.coursescontainer.CoursesContainer>
+
+
+Examples
+========
+
+Getting a course container
+--------------------------
+
+We can easily create `CoursesContainers`:
+
+    >>> from waeup.sirp.university.coursescontainer import CoursesContainer
+    >>> mycontainer = CoursesContainer()
+
+
+Another way to get a course container -- without importing the class
+-- is via factories. We registered a factory for course containers
+under the name ``waeup.CoursesContainer``. Now we can ask for an object
+by calling the appropriate factory:
+
+    >>> from zope.component import createObject
+    >>> createObject(u'waeup.CoursesContainer')
+    <waeup.sirp.university.coursescontainer.CoursesContainer object at 0x...>
+
+This way we get a thing that implements ICoursesContainer without
+imports or similar.
+
Index: /main/waeup.sirp/trunk/src/waeup/sirp/university/department.py
===================================================================
--- /main/waeup.sirp/trunk/src/waeup/sirp/university/department.py	(revision 7332)
+++ /main/waeup.sirp/trunk/src/waeup/sirp/university/department.py	(revision 7333)
@@ -46,8 +46,8 @@
         self.title_prefix = title_prefix
         self.code = code
-        self.courses = createObject(u'waeup.CourseContainer')
+        self.courses = createObject(u'waeup.CoursesContainer')
         self.courses.__parent__ = self
         self.courses.__name__ = 'courses'
-        self.certificates = createObject(u'waeup.CertificateContainer')
+        self.certificates = createObject(u'waeup.CertificatesContainer')
         self.certificates.__parent__ = self
         self.certificates.__name__ = 'certificates'
Index: /main/waeup.sirp/trunk/src/waeup/sirp/university/department.txt
===================================================================
--- /main/waeup.sirp/trunk/src/waeup/sirp/university/department.txt	(revision 7332)
+++ /main/waeup.sirp/trunk/src/waeup/sirp/university/department.txt	(revision 7333)
@@ -81,15 +81,15 @@
    .. attribute:: courses
 
-      (ICourseContainer instance) A container for courses.
+      (ICoursesContainer instance) A container for courses.
 
       Each department has a courses container:
 
         >>> mydept.courses
-        <waeup.sirp.university.coursecontainer.CourseContainer object at 0x...>
+        <waeup.sirp.university.coursescontainer.CoursesContainer object at 0x...>
 
 
    .. attribute:: certificates
 
-      (ICertificateContainer instance) A container for certificates.
+      (ICertificatesContainer instance) A container for certificates.
 
       Each department has a certificate container, that holds the
@@ -97,5 +97,5 @@
 
         >>> mydept.certificates
-        <waeup.sirp...certificatecontainer.CertificateContainer object at 0x...>
+        <waeup.sirp...certificatescontainer.CertificatesContainer object at 0x...>
 
 Utilities
Index: /main/waeup.sirp/trunk/src/waeup/sirp/university/facultiescontainer.py
===================================================================
--- /main/waeup.sirp/trunk/src/waeup/sirp/university/facultiescontainer.py	(revision 7333)
+++ /main/waeup.sirp/trunk/src/waeup/sirp/university/facultiescontainer.py	(revision 7333)
@@ -0,0 +1,67 @@
+## $Id$
+##
+## Copyright (C) 2011 Uli Fouquet & Henrik Bettermann
+## This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 2 of the License, or
+## (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##
+import grok
+from zope.component.interfaces import IFactory
+from zope.interface import implementedBy
+from waeup.sirp.interfaces import ISIRPPluggable
+from waeup.sirp.university.interfaces import IFacultiesContainer, IFaculty
+
+class FacultiesContainer(grok.Container):
+    """See interfaces for description.
+    """
+    grok.implements(IFacultiesContainer)
+    grok.require('waeup.manageUniversity')
+
+    def addFaculty(self, faculty):
+        if not IFaculty.providedBy(faculty):
+            raise TypeError('FacultiesContainers contain only IFaculty instances')
+        self[faculty.code] = faculty
+        return
+
+class FacultiesContainerFactory(grok.GlobalUtility):
+    """A factory for faculty containers.
+    """
+    grok.implements(IFactory)
+    grok.name(u'waeup.FacultiesContainer')
+    title = u"Create a new facultiescontainer.",
+    description = u"This factory instantiates new containers for faculties."
+
+    def __call__(self, *args, **kw):
+        return FacultiesContainer(*args, **kw)
+
+    def getInterfaces(self):
+        return implementedBy(FacultiesContainer)
+
+class AcademicsPlugin(grok.GlobalUtility):
+    """A plugin that creates container for faculties inside a university.
+    """
+    grok.implements(ISIRPPluggable)
+    grok.name('faculties')
+
+    def setup(self, site, name, logger):
+        if 'faculties' in site.keys():
+            logger.warn('Could not create container for faculties in SIRP.')
+            return
+        site['faculties'] = FacultiesContainer()
+        logger.info('Container for faculties created')
+        return
+
+    def update(self, site, name, logger):
+        if not 'faculties' in site.keys():
+            self.setup(site, name, logger)
+
Index: /main/waeup.sirp/trunk/src/waeup/sirp/university/facultiescontainer.txt
===================================================================
--- /main/waeup.sirp/trunk/src/waeup/sirp/university/facultiescontainer.txt	(revision 7333)
+++ /main/waeup.sirp/trunk/src/waeup/sirp/university/facultiescontainer.txt	(revision 7333)
@@ -0,0 +1,178 @@
+:mod:`waeup.sirp.university.facultiescontainer` -- Faculty Containers
+*********************************************************************
+
+.. module:: waeup.sirp.university.facultiescontainer
+
+Components that represent faculty containers.
+
+.. :doctest:
+.. :layer: waeup.sirp.testing.SIRPUnitTestLayer
+
+
+Content Classes (models and containers)
+=======================================
+
+:class:`FacultiesContainer`
+---------------------------
+
+.. class:: FacultiesContainer()
+
+   Create a faculty container:
+
+     >>> from waeup.sirp.university.facultiescontainer import FacultiesContainer
+     >>> mycontainer = FacultiesContainer()
+     >>> mycontainer
+     <waeup.sirp.university.facultiescontainer.FacultiesContainer object at 0x...>
+
+   Another way to create :class:`FacultiesContainer` instances is by asking
+   for a factory called ``waeup.FacultiesContainer``. This way we can create a
+   faculty without importing a class:
+
+     >>> from zope.component import createObject
+     >>> mycontainer = createObject(u'waeup.FacultiesContainer')
+     >>> mycontainer
+     <waeup.sirp.university.facultiescontainer.FacultiesContainer object at 0x...>
+
+   :class:`FacultiesContainer` instances have the attributes required by the
+   `IFacultiesContainer` interface:
+
+     >>> from waeup.sirp.university.interfaces import IFacultiesContainer
+     >>> IFacultiesContainer.providedBy(mycontainer)
+     True
+
+     >>> from zope.interface.verify import verifyObject
+     >>> verifyObject(IFacultiesContainer, mycontainer)
+     True
+
+   .. method:: addFaculty(faculty)
+
+      Add a faculty into this container. Added objects are checked and
+      only `IFaculty` objects accepted:
+
+        >>> mycontainer.addFaculty(object())
+        Traceback (most recent call last):
+        ...
+        TypeError: FacultiesContainers contain only IFaculty instances
+
+        >>> list(mycontainer.values())
+        []
+
+      Regular faculties are accepted:
+
+        >>> from waeup.sirp.university.faculty import Faculty
+        >>> mycontainer.addFaculty(Faculty(title='Physics',
+        ...                                code='FP'))
+
+        >>> list(mycontainer.items())
+        [(u'FP', <waeup.sirp.university.faculty.Faculty object at 0x...>)]
+
+
+
+Utilities
+=========
+
+:class:`AcademicsPlugin`
+------------------------
+
+.. class:: AcademicsPlugin()
+
+   .. attribute:: grok.implements(ISIRPPluggable)
+
+   This plugin component tells under which name (``faculties``) an
+   instance of academics stuff should be created in plain SIRP
+   instances. It also tells the factory name for FacultiesContainer
+   instances, which serve as root object for academics stuff in SIRP apps.
+
+
+:class:`FacultiesContainerFactory`
+----------------------------------
+
+.. class:: FacultiesContainerFactory()
+
+   .. attribute:: grok.name(u'waeup.FacultiesContainer')
+
+   .. attribute:: grok.implements(IFactoryContainer)
+
+   A named utility to deliver new instances of :class:`FacultiesContainer`
+   without the need to import the implementation before:
+
+     >>> from zope.component import createObject
+     >>> mycontainer = createObject(u'waeup.FacultiesContainer')
+     >>> mycontainer
+     <waeup.sirp.university.facultiescontainer.FacultiesContainer object at 0x...>
+
+   The factory complies with the specifications from the
+   :class:`IFactory` insterface:
+
+     >>> from zope.interface.verify import verifyClass
+     >>> from zope.component.interfaces import IFactory
+     >>> from waeup.sirp.university.facultiescontainer import (
+     ...   FacultiesContainerFactory)
+     >>> verifyClass(IFactory, FacultiesContainerFactory)
+     True
+
+   This means also, that we can get the interfaces of the created
+   object from the factory:
+
+     >>> fac_container_factory = FacultiesContainerFactory()
+     >>> fac_container_factory.getInterfaces()
+     <implementedBy waeup.sirp.university.facultiescontainer.FacultiesContainer>
+
+Examples
+========
+
+We can easily create `FacultiesContainers`:
+
+    >>> from waeup.sirp.university.facultiescontainer import FacultiesContainer
+    >>> mycontainer = FacultiesContainer()
+
+Faculty containers provide `IFacultiesContainer`:
+
+    >>> from waeup.sirp.university.interfaces import IFacultiesContainer
+    >>> IFacultiesContainer.providedBy(mycontainer)
+    True
+
+Another way to get a faculty container -- without importing the class
+-- is via factories. We registered a factory for faculty containers
+under the name ``waeup.facultiescontainer``:
+
+    >>> from zope.component import createObject
+    >>> createObject(u'waeup.FacultiesContainer')
+    <waeup.sirp.university.facultiescontainer.FacultiesContainer object at 0x...>
+
+This way we get a thing that implements IFacultiesContainer without
+imports or similar.
+
+We can be sure, that the full interface is supported by the
+FacultiesContainer class::
+
+    >>> from zope.interface.verify import verifyClass
+    >>> verifyClass(IFacultiesContainer, FacultiesContainer)
+    True
+
+
+Storing things in faculty containers
+====================================
+
+We can, of course, store things in a faculty container. But when we
+really store an object, then it must be a faculty::
+
+    >>> mycontainer.addFaculty(42)
+    Traceback (most recent call last):
+    ...
+    TypeError: FacultiesContainers contain only IFaculty instances
+
+Okay, so we have to get a faculty first::
+
+    >>> from waeup.sirp.university.faculty import Faculty
+    >>> myfaculty = Faculty()
+
+We can add this faculty to our container::
+
+    >>> mycontainer.addFaculty(myfaculty)
+
+We get back the key, under which the faculty was stored. It will be
+some string, but there is no guarantee at all, how this key looks
+like. It might be a string of integers, a name or whatever; you cannot
+know before.
+
Index: in/waeup.sirp/trunk/src/waeup/sirp/university/facultycontainer.py
===================================================================
--- /main/waeup.sirp/trunk/src/waeup/sirp/university/facultycontainer.py	(revision 7332)
+++ 	(revision )
@@ -1,67 +1,0 @@
-## $Id$
-##
-## Copyright (C) 2011 Uli Fouquet & Henrik Bettermann
-## This program is free software; you can redistribute it and/or modify
-## it under the terms of the GNU General Public License as published by
-## the Free Software Foundation; either version 2 of the License, or
-## (at your option) any later version.
-##
-## This program is distributed in the hope that it will be useful,
-## but WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-## GNU General Public License for more details.
-##
-## You should have received a copy of the GNU General Public License
-## along with this program; if not, write to the Free Software
-## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-##
-import grok
-from zope.component.interfaces import IFactory
-from zope.interface import implementedBy
-from waeup.sirp.interfaces import ISIRPPluggable
-from waeup.sirp.university.interfaces import IFacultyContainer, IFaculty
-
-class FacultyContainer(grok.Container):
-    """See interfaces for description.
-    """
-    grok.implements(IFacultyContainer)
-    grok.require('waeup.manageUniversity')
-
-    def addFaculty(self, faculty):
-        if not IFaculty.providedBy(faculty):
-            raise TypeError('FacultyContainers contain only IFaculty instances')
-        self[faculty.code] = faculty
-        return
-
-class FacultyContainerFactory(grok.GlobalUtility):
-    """A factory for faculty containers.
-    """
-    grok.implements(IFactory)
-    grok.name(u'waeup.FacultyContainer')
-    title = u"Create a new faculty container.",
-    description = u"This factory instantiates new faculty containers."
-
-    def __call__(self, *args, **kw):
-        return FacultyContainer(*args, **kw)
-
-    def getInterfaces(self):
-        return implementedBy(FacultyContainer)
-
-class AcademicsPlugin(grok.GlobalUtility):
-    """A plugin that creates a faculty container inside a university.
-    """
-    grok.implements(ISIRPPluggable)
-    grok.name('faculties')
-
-    def setup(self, site, name, logger):
-        if 'faculties' in site.keys():
-            logger.warn('Could not create faculty container in SIRP.')
-            return
-        site['faculties'] = FacultyContainer()
-        logger.info('Created faculty container for University')
-        return
-
-    def update(self, site, name, logger):
-        if not 'faculties' in site.keys():
-            self.setup(site, name, logger)
-
Index: in/waeup.sirp/trunk/src/waeup/sirp/university/facultycontainer.txt
===================================================================
--- /main/waeup.sirp/trunk/src/waeup/sirp/university/facultycontainer.txt	(revision 7332)
+++ 	(revision )
@@ -1,178 +1,0 @@
-:mod:`waeup.sirp.university.facultycontainer` -- Faculty Containers
-*******************************************************************
-
-.. module:: waeup.sirp.university.facultycontainer
-
-Components that represent faculty containers.
-
-.. :doctest:
-.. :layer: waeup.sirp.testing.SIRPUnitTestLayer
-
-
-Content Classes (models and containers)
-=======================================
-
-:class:`FacultyContainer`
--------------------------
-
-.. class:: FacultyContainer()
-
-   Create a faculty container:
-
-     >>> from waeup.sirp.university.facultycontainer import FacultyContainer
-     >>> mycontainer = FacultyContainer()
-     >>> mycontainer
-     <waeup.sirp.university.facultycontainer.FacultyContainer object at 0x...>
-
-   Another way to create :class:`FacultyContainer` instances is by asking
-   for a factory called ``waeup.FacultyContainer``. This way we can create a
-   faculty without importing a class:
-
-     >>> from zope.component import createObject
-     >>> mycontainer = createObject(u'waeup.FacultyContainer')
-     >>> mycontainer
-     <waeup.sirp.university.facultycontainer.FacultyContainer object at 0x...>
-
-   :class:`FacultyContainer` instances have the attributes required by the
-   `IFacultyContainer` interface:
-
-     >>> from waeup.sirp.university.interfaces import IFacultyContainer
-     >>> IFacultyContainer.providedBy(mycontainer)
-     True
-
-     >>> from zope.interface.verify import verifyObject
-     >>> verifyObject(IFacultyContainer, mycontainer)
-     True
-
-   .. method:: addFaculty(faculty)
-
-      Add a faculty into this container. Added objects are checked and
-      only `IFaculty` objects accepted:
-
-        >>> mycontainer.addFaculty(object())
-        Traceback (most recent call last):
-        ...
-        TypeError: FacultyContainers contain only IFaculty instances
-
-        >>> list(mycontainer.values())
-        []
-
-      Regular faculties are accepted:
-
-        >>> from waeup.sirp.university.faculty import Faculty
-        >>> mycontainer.addFaculty(Faculty(title='Physics',
-        ...                                code='FP'))
-
-        >>> list(mycontainer.items())
-        [(u'FP', <waeup.sirp.university.faculty.Faculty object at 0x...>)]
-
-
-
-Utilities
-=========
-
-:class:`AcademicsPlugin`
-------------------------
-
-.. class:: AcademicsPlugin()
-
-   .. attribute:: grok.implements(ISIRPPluggable)
-
-   This plugin component tells under which name (``faculties``) an
-   instance of academics stuff should be created in plain SIRP
-   instances. It also tells the factory name for FacultyContainer
-   instances, which serve as root object for academics stuff in SIRP apps.
-
-
-:class:`FacultyContainerFactory`
---------------------------------
-
-.. class:: FacultyContainerFactory()
-
-   .. attribute:: grok.name(u'waeup.FacultyContainer')
-
-   .. attribute:: grok.implements(IFactoryContainer)
-
-   A named utility to deliver new instances of :class:`FacultyContainer`
-   without the need to import the implementation before:
-
-     >>> from zope.component import createObject
-     >>> mycontainer = createObject(u'waeup.FacultyContainer')
-     >>> mycontainer
-     <waeup.sirp.university.facultycontainer.FacultyContainer object at 0x...>
-
-   The factory complies with the specifications from the
-   :class:`IFactory` insterface:
-
-     >>> from zope.interface.verify import verifyClass
-     >>> from zope.component.interfaces import IFactory
-     >>> from waeup.sirp.university.facultycontainer import (
-     ...   FacultyContainerFactory)
-     >>> verifyClass(IFactory, FacultyContainerFactory)
-     True
-
-   This means also, that we can get the interfaces of the created
-   object from the factory:
-
-     >>> fac_container_factory = FacultyContainerFactory()
-     >>> fac_container_factory.getInterfaces()
-     <implementedBy waeup.sirp.university.facultycontainer.FacultyContainer>
-
-Examples
-========
-
-We can easily create `FacultyContainers`:
-
-    >>> from waeup.sirp.university.facultycontainer import FacultyContainer
-    >>> mycontainer = FacultyContainer()
-
-Faculty containers provide `IFacultyContainer`:
-
-    >>> from waeup.sirp.university.interfaces import IFacultyContainer
-    >>> IFacultyContainer.providedBy(mycontainer)
-    True
-
-Another way to get a faculty container -- without importing the class
--- is via factories. We registered a factory for faculty containers
-under the name ``waeup.facultycontainer``:
-
-    >>> from zope.component import createObject
-    >>> createObject(u'waeup.FacultyContainer')
-    <waeup.sirp.university.facultycontainer.FacultyContainer object at 0x...>
-
-This way we get a thing that implements IFacultyContainer without
-imports or similar.
-
-We can be sure, that the full interface is supported by the
-FacultyContainer class::
-
-    >>> from zope.interface.verify import verifyClass
-    >>> verifyClass(IFacultyContainer, FacultyContainer)
-    True
-
-
-Storing things in faculty containers
-====================================
-
-We can, of course, store things in a faculty container. But when we
-really store an object, then it must be a faculty::
-
-    >>> mycontainer.addFaculty(42)
-    Traceback (most recent call last):
-    ...
-    TypeError: FacultyContainers contain only IFaculty instances
-
-Okay, so we have to get a faculty first::
-
-    >>> from waeup.sirp.university.faculty import Faculty
-    >>> myfaculty = Faculty()
-
-We can add this faculty to our container::
-
-    >>> mycontainer.addFaculty(myfaculty)
-
-We get back the key, under which the faculty was stored. It will be
-some string, but there is no guarantee at all, how this key looks
-like. It might be a string of integers, a name or whatever; you cannot
-know before.
-
Index: /main/waeup.sirp/trunk/src/waeup/sirp/university/interfaces.py
===================================================================
--- /main/waeup.sirp/trunk/src/waeup/sirp/university/interfaces.py	(revision 7332)
+++ /main/waeup.sirp/trunk/src/waeup/sirp/university/interfaces.py	(revision 7333)
@@ -73,5 +73,5 @@
 IFacultyAdd['code'].order =  IFaculty['code'].order
 
-class IFacultyContainer(ISIRPContainer):
+class IFacultiesContainer(ISIRPContainer):
     """A container for faculties.
     """
@@ -124,5 +124,5 @@
 IDepartmentAdd['code'].order =  IDepartment['code'].order
 
-class ICourseContainer(ISIRPContainer):
+class ICoursesContainer(ISIRPContainer):
     """A container for faculties.
     """
@@ -248,5 +248,5 @@
 ICertificateAdd['code'].order =  ICertificate['code'].order
 
-class ICertificateContainer(ISIRPContainer):
+class ICertificatesContainer(ISIRPContainer):
     """A container for certificates.
     """
Index: in/waeup.sirp/trunk/src/waeup/sirp/university/tests/test_certificatecontainer.py
===================================================================
--- /main/waeup.sirp/trunk/src/waeup/sirp/university/tests/test_certificatecontainer.py	(revision 7332)
+++ 	(revision )
@@ -1,139 +1,0 @@
-## $Id$
-##
-## Copyright (C) 2011 Uli Fouquet & Henrik Bettermann
-## This program is free software; you can redistribute it and/or modify
-## it under the terms of the GNU General Public License as published by
-## the Free Software Foundation; either version 2 of the License, or
-## (at your option) any later version.
-##
-## This program is distributed in the hope that it will be useful,
-## but WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-## GNU General Public License for more details.
-##
-## You should have received a copy of the GNU General Public License
-## along with this program; if not, write to the Free Software
-## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-##
-"""
-Tests for certificate containers and related components.
-"""
-import shutil
-import tempfile
-import unittest
-from zope.component.hooks import setSite, clearSite
-from zope.interface.verify import verifyClass, verifyObject
-
-from waeup.sirp.app import University
-from waeup.sirp.interfaces import DuplicationError
-from waeup.sirp.testing import (
-    FunctionalLayer, doctestsuite_for_module, FunctionalTestCase)
-from waeup.sirp.university.certificate import Certificate
-from waeup.sirp.university.certificatecontainer import CertificateContainer
-from waeup.sirp.university.interfaces import ICertificateContainer
-
-
-class CertificateContainerTests(FunctionalTestCase):
-
-    layer = FunctionalLayer
-
-    def setUp(self):
-        super(CertificateContainerTests, self).setUp()
-
-        # Setup a sample site for each test
-        app = University()
-        self.dc_root = tempfile.mkdtemp()
-        app['datacenter'].setStoragePath(self.dc_root)
-
-        # Prepopulate the ZODB...
-        self.getRootFolder()['app'] = app
-        self.app = self.getRootFolder()['app']
-        setSite(self.app)
-
-    def tearDown(self):
-        super(CertificateContainerTests, self).tearDown()
-        clearSite()
-        shutil.rmtree(self.dc_root)
-
-    def test_create(self):
-        # we can create instances
-        container = CertificateContainer()
-        result = isinstance(container, CertificateContainer)
-        assert result is True
-
-    def test_provides_icertificatecontainer(self):
-        # instances tell they provide their main interface
-        container = CertificateContainer()
-        result = ICertificateContainer.providedBy(container)
-        assert result is True
-
-    def test_interfaces(self):
-        # class and instances comply with their main interface
-        container = CertificateContainer()
-        self.assertTrue(verifyClass(ICertificateContainer, CertificateContainer))
-        self.assertTrue(verifyObject(ICertificateContainer, container))
-
-    def test_add_certificate_non_icertificate(self):
-        # we cannot add certificates that do not implement ICertificate.
-        container = CertificateContainer()
-        self.assertRaises(
-            TypeError, container.addCertificate, 'some_string')
-
-    def test_add_certificate_no_duplicate_entry(self):
-        # we cannot add certificates that are registered already.
-        container = CertificateContainer()
-        # We must place this container in the ZODB to make catalogs work.
-        self.app['certs'] = container
-        cert1 = Certificate(code="CERT1")
-        cert2 = Certificate(code="CERT1")
-        container.addCertificate(cert1)
-        self.assertRaises(
-            DuplicationError,
-            container.addCertificate, cert2)
-
-    def test_setitem_duplicate_entry(self):
-        # we cannot add certificates whose code exists already in catalog
-        container1 = CertificateContainer()
-        container2 = CertificateContainer()
-        self.app['certs1'] = container1 # enable catalogs
-        self.app['certs2'] = container2
-        cert1 = Certificate(code="CERT1")
-        cert2 = Certificate(code="CERT1")
-        self.app['certs1']['CERT1'] = cert1
-        self.assertRaises(
-            DuplicationError,
-            self.app['certs2'].__setitem__, 'CERT1', cert2)
-        assert len(container2) == 0
-
-    def test_setitem_name_unequal_code(self):
-        # we cannot add certificates whose code != key
-        container = CertificateContainer()
-        self.app['certs'] = container # enable catalogs
-        cert1 = Certificate(code="CERT1")
-        self.assertRaises(
-            ValueError,
-            container.__setitem__, 'OtherKey', cert1)
-        assert len(container) == 0
-
-    def test_clear(self):
-        # clear() really empties the container.
-        container = CertificateContainer()
-        self.app['certs'] = container # enable catalogs
-        cert1 = Certificate(code="CERT1")
-        cert2 = Certificate(code="CERT2")
-        container['CERT1'] = cert1
-        container['CERT2'] = cert2
-        container.clear()
-        assert len(container) == 0
-
-
-def test_suite():
-    suite = unittest.TestSuite((
-        unittest.makeSuite(CertificateContainerTests),
-        doctestsuite_for_module(
-                'waeup.sirp.university.certificatecontainer'),
-        ))
-    return suite
-
-if __name__=='__main__':
-    unittest.main(defaultTest='test_suite')
Index: /main/waeup.sirp/trunk/src/waeup/sirp/university/tests/test_certificatescontainer.py
===================================================================
--- /main/waeup.sirp/trunk/src/waeup/sirp/university/tests/test_certificatescontainer.py	(revision 7333)
+++ /main/waeup.sirp/trunk/src/waeup/sirp/university/tests/test_certificatescontainer.py	(revision 7333)
@@ -0,0 +1,139 @@
+## $Id$
+##
+## Copyright (C) 2011 Uli Fouquet & Henrik Bettermann
+## This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 2 of the License, or
+## (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##
+"""
+Tests for certificate containers and related components.
+"""
+import shutil
+import tempfile
+import unittest
+from zope.component.hooks import setSite, clearSite
+from zope.interface.verify import verifyClass, verifyObject
+
+from waeup.sirp.app import University
+from waeup.sirp.interfaces import DuplicationError
+from waeup.sirp.testing import (
+    FunctionalLayer, doctestsuite_for_module, FunctionalTestCase)
+from waeup.sirp.university.certificate import Certificate
+from waeup.sirp.university.certificatescontainer import CertificatesContainer
+from waeup.sirp.university.interfaces import ICertificatesContainer
+
+
+class CertificatesContainerTests(FunctionalTestCase):
+
+    layer = FunctionalLayer
+
+    def setUp(self):
+        super(CertificatesContainerTests, self).setUp()
+
+        # Setup a sample site for each test
+        app = University()
+        self.dc_root = tempfile.mkdtemp()
+        app['datacenter'].setStoragePath(self.dc_root)
+
+        # Prepopulate the ZODB...
+        self.getRootFolder()['app'] = app
+        self.app = self.getRootFolder()['app']
+        setSite(self.app)
+
+    def tearDown(self):
+        super(CertificatesContainerTests, self).tearDown()
+        clearSite()
+        shutil.rmtree(self.dc_root)
+
+    def test_create(self):
+        # we can create instances
+        container = CertificatesContainer()
+        result = isinstance(container, CertificatesContainer)
+        assert result is True
+
+    def test_provides_icertificatescontainer(self):
+        # instances tell they provide their main interface
+        container = CertificatesContainer()
+        result = ICertificatesContainer.providedBy(container)
+        assert result is True
+
+    def test_interfaces(self):
+        # class and instances comply with their main interface
+        container = CertificatesContainer()
+        self.assertTrue(verifyClass(ICertificatesContainer, CertificatesContainer))
+        self.assertTrue(verifyObject(ICertificatesContainer, container))
+
+    def test_add_certificate_non_icertificate(self):
+        # we cannot add certificates that do not implement ICertificate.
+        container = CertificatesContainer()
+        self.assertRaises(
+            TypeError, container.addCertificate, 'some_string')
+
+    def test_add_certificate_no_duplicate_entry(self):
+        # we cannot add certificates that are registered already.
+        container = CertificatesContainer()
+        # We must place this container in the ZODB to make catalogs work.
+        self.app['certs'] = container
+        cert1 = Certificate(code="CERT1")
+        cert2 = Certificate(code="CERT1")
+        container.addCertificate(cert1)
+        self.assertRaises(
+            DuplicationError,
+            container.addCertificate, cert2)
+
+    def test_setitem_duplicate_entry(self):
+        # we cannot add certificates whose code exists already in catalog
+        container1 = CertificatesContainer()
+        container2 = CertificatesContainer()
+        self.app['certs1'] = container1 # enable catalogs
+        self.app['certs2'] = container2
+        cert1 = Certificate(code="CERT1")
+        cert2 = Certificate(code="CERT1")
+        self.app['certs1']['CERT1'] = cert1
+        self.assertRaises(
+            DuplicationError,
+            self.app['certs2'].__setitem__, 'CERT1', cert2)
+        assert len(container2) == 0
+
+    def test_setitem_name_unequal_code(self):
+        # we cannot add certificates whose code != key
+        container = CertificatesContainer()
+        self.app['certs'] = container # enable catalogs
+        cert1 = Certificate(code="CERT1")
+        self.assertRaises(
+            ValueError,
+            container.__setitem__, 'OtherKey', cert1)
+        assert len(container) == 0
+
+    def test_clear(self):
+        # clear() really empties the container.
+        container = CertificatesContainer()
+        self.app['certs'] = container # enable catalogs
+        cert1 = Certificate(code="CERT1")
+        cert2 = Certificate(code="CERT2")
+        container['CERT1'] = cert1
+        container['CERT2'] = cert2
+        container.clear()
+        assert len(container) == 0
+
+
+def test_suite():
+    suite = unittest.TestSuite((
+        unittest.makeSuite(CertificatesContainerTests),
+        doctestsuite_for_module(
+                'waeup.sirp.university.certificatescontainer'),
+        ))
+    return suite
+
+if __name__=='__main__':
+    unittest.main(defaultTest='test_suite')
Index: in/waeup.sirp/trunk/src/waeup/sirp/university/tests/test_coursecontainer.py
===================================================================
--- /main/waeup.sirp/trunk/src/waeup/sirp/university/tests/test_coursecontainer.py	(revision 7332)
+++ 	(revision )
@@ -1,39 +1,0 @@
-## $Id$
-##
-## Copyright (C) 2011 Uli Fouquet & Henrik Bettermann
-## This program is free software; you can redistribute it and/or modify
-## it under the terms of the GNU General Public License as published by
-## the Free Software Foundation; either version 2 of the License, or
-## (at your option) any later version.
-##
-## This program is distributed in the hope that it will be useful,
-## but WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-## GNU General Public License for more details.
-##
-## You should have received a copy of the GNU General Public License
-## along with this program; if not, write to the Free Software
-## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-##
-
-# Test course containers
-
-import unittest
-from zope.interface.verify import verifyClass, verifyObject
-from waeup.sirp.university.interfaces import ICourseContainer
-from waeup.sirp.university import CourseContainer, Course
-
-class CourseContainerTests(unittest.TestCase):
-
-    def test_ifaces(self):
-        container = CourseContainer()
-        self.assertTrue(verifyClass(ICourseContainer, CourseContainer))
-        self.assertTrue(verifyObject(ICourseContainer, container))
-
-    def test_setitem_name_ne_code(self):
-        # If we add a course under a wrong name that will give an error
-        container = CourseContainer()
-        course = Course(code='MYCOURSE')
-        self.assertRaises(
-            ValueError,
-            container.__setitem__, 'NOTMYCOURSE', course)
Index: /main/waeup.sirp/trunk/src/waeup/sirp/university/tests/test_coursescontainer.py
===================================================================
--- /main/waeup.sirp/trunk/src/waeup/sirp/university/tests/test_coursescontainer.py	(revision 7333)
+++ /main/waeup.sirp/trunk/src/waeup/sirp/university/tests/test_coursescontainer.py	(revision 7333)
@@ -0,0 +1,39 @@
+## $Id$
+##
+## Copyright (C) 2011 Uli Fouquet & Henrik Bettermann
+## This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 2 of the License, or
+## (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##
+
+# Test course containers
+
+import unittest
+from zope.interface.verify import verifyClass, verifyObject
+from waeup.sirp.university.interfaces import ICoursesContainer
+from waeup.sirp.university import CoursesContainer, Course
+
+class CoursesContainerTests(unittest.TestCase):
+
+    def test_ifaces(self):
+        container = CoursesContainer()
+        self.assertTrue(verifyClass(ICoursesContainer, CoursesContainer))
+        self.assertTrue(verifyObject(ICoursesContainer, container))
+
+    def test_setitem_name_ne_code(self):
+        # If we add a course under a wrong name that will give an error
+        container = CoursesContainer()
+        course = Course(code='MYCOURSE')
+        self.assertRaises(
+            ValueError,
+            container.__setitem__, 'NOTMYCOURSE', course)
Index: /main/waeup.sirp/trunk/src/waeup/sirp/university/tests/test_facultiescontainer.py
===================================================================
--- /main/waeup.sirp/trunk/src/waeup/sirp/university/tests/test_facultiescontainer.py	(revision 7333)
+++ /main/waeup.sirp/trunk/src/waeup/sirp/university/tests/test_facultiescontainer.py	(revision 7333)
@@ -0,0 +1,114 @@
+## $Id$
+##
+## Copyright (C) 2011 Uli Fouquet & Henrik Bettermann
+## This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 2 of the License, or
+## (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##
+
+# Tests for FacultiesContainer.
+import logging
+import unittest
+from StringIO import StringIO
+from zope.interface.verify import verifyObject, verifyClass
+from waeup.sirp.testing import FunctionalTestCase, FunctionalLayer
+from waeup.sirp.university.interfaces import IFacultiesContainer
+from waeup.sirp.university import FacultiesContainer
+from waeup.sirp.university.facultiescontainer import AcademicsPlugin
+
+class FakeLogger(object):
+
+    _stream = None
+
+    def get_logger(self):
+        logger = logging.getLogger('test')
+        logger.propagate = False
+        self._stream = StringIO()
+        self.handler = logging.StreamHandler(self._stream)
+        logger.setLevel(logging.DEBUG)
+        logger.addHandler(self.handler)
+        return logger
+
+    def close(self, logger):
+        # Remove handler from logger
+        handler = self.handler
+        if handler not in logger.handlers:
+            return
+        del logger.handlers[logger.handlers.index(handler)]
+        return
+
+    def get_messages(self):
+        self._stream.seek(0)
+        result = self._stream.read()
+        self._stream.seek(0, 2) # Seek to end of stream
+        return result
+
+class FacultiesContainerTests(unittest.TestCase):
+
+    def test_ifaces(self):
+        container = FacultiesContainer()
+        self.assertTrue(verifyClass(IFacultiesContainer, FacultiesContainer))
+        self.assertTrue(verifyObject(IFacultiesContainer, container))
+
+class AcademicsPluginTests(unittest.TestCase):
+
+    def setUp(self):
+        self._logger_factory = FakeLogger()
+        self.logger = self._logger_factory.get_logger()
+
+    def tearDown(self):
+        self._logger_factory.close(self.logger)
+
+    def test_setup(self):
+        site = dict()
+        logger = self.logger
+        plugin = AcademicsPlugin()
+        plugin.setup(site, 'testsite', logger)
+        self.assertTrue('faculties' in site.keys())
+        self.assertTrue(isinstance(site['faculties'], FacultiesContainer))
+        self.assertEqual(
+            self._logger_factory.get_messages(),
+            'Container for faculties created\n'
+            )
+
+    def test_setup_already_set_up(self):
+        site = dict(faculties=object())
+        logger = self.logger
+        plugin = AcademicsPlugin()
+        plugin.setup(site, 'testsite', logger)
+        self.assertTrue('faculties' in site.keys())
+        self.assertEqual(
+            self._logger_factory.get_messages(),
+            'Could not create container for faculties in SIRP.\n'
+            )
+
+    def test_update(self):
+        site = dict()
+        logger = self.logger
+        plugin = AcademicsPlugin()
+        plugin.update(site, 'testsite', logger)
+        self.assertTrue('faculties' in site.keys())
+        self.assertTrue(isinstance(site['faculties'], FacultiesContainer))
+        self.assertEqual(
+            self._logger_factory.get_messages(),
+            'Container for faculties created\n'
+            )
+
+    def test_update_already_set_up(self):
+        site = dict(faculties=object())
+        logger = self.logger
+        plugin = AcademicsPlugin()
+        plugin.update(site, 'testsite', logger)
+        self.assertTrue('faculties' in site.keys())
+        self.assertEqual(
+            self._logger_factory.get_messages(), '')
Index: in/waeup.sirp/trunk/src/waeup/sirp/university/tests/test_facultycontainer.py
===================================================================
--- /main/waeup.sirp/trunk/src/waeup/sirp/university/tests/test_facultycontainer.py	(revision 7332)
+++ 	(revision )
@@ -1,114 +1,0 @@
-## $Id$
-##
-## Copyright (C) 2011 Uli Fouquet & Henrik Bettermann
-## This program is free software; you can redistribute it and/or modify
-## it under the terms of the GNU General Public License as published by
-## the Free Software Foundation; either version 2 of the License, or
-## (at your option) any later version.
-##
-## This program is distributed in the hope that it will be useful,
-## but WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-## GNU General Public License for more details.
-##
-## You should have received a copy of the GNU General Public License
-## along with this program; if not, write to the Free Software
-## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-##
-
-# Tests for FacultyContainer.
-import logging
-import unittest
-from StringIO import StringIO
-from zope.interface.verify import verifyObject, verifyClass
-from waeup.sirp.testing import FunctionalTestCase, FunctionalLayer
-from waeup.sirp.university.interfaces import IFacultyContainer
-from waeup.sirp.university import FacultyContainer
-from waeup.sirp.university.facultycontainer import AcademicsPlugin
-
-class FakeLogger(object):
-
-    _stream = None
-
-    def get_logger(self):
-        logger = logging.getLogger('test')
-        logger.propagate = False
-        self._stream = StringIO()
-        self.handler = logging.StreamHandler(self._stream)
-        logger.setLevel(logging.DEBUG)
-        logger.addHandler(self.handler)
-        return logger
-
-    def close(self, logger):
-        # Remove handler from logger
-        handler = self.handler
-        if handler not in logger.handlers:
-            return
-        del logger.handlers[logger.handlers.index(handler)]
-        return
-
-    def get_messages(self):
-        self._stream.seek(0)
-        result = self._stream.read()
-        self._stream.seek(0, 2) # Seek to end of stream
-        return result
-
-class FacultyContainerTests(unittest.TestCase):
-
-    def test_ifaces(self):
-        container = FacultyContainer()
-        self.assertTrue(verifyClass(IFacultyContainer, FacultyContainer))
-        self.assertTrue(verifyObject(IFacultyContainer, container))
-
-class AcademicsPluginTests(unittest.TestCase):
-
-    def setUp(self):
-        self._logger_factory = FakeLogger()
-        self.logger = self._logger_factory.get_logger()
-
-    def tearDown(self):
-        self._logger_factory.close(self.logger)
-
-    def test_setup(self):
-        site = dict()
-        logger = self.logger
-        plugin = AcademicsPlugin()
-        plugin.setup(site, 'testsite', logger)
-        self.assertTrue('faculties' in site.keys())
-        self.assertTrue(isinstance(site['faculties'], FacultyContainer))
-        self.assertEqual(
-            self._logger_factory.get_messages(),
-            'Created faculty container for University\n'
-            )
-
-    def test_setup_already_set_up(self):
-        site = dict(faculties=object())
-        logger = self.logger
-        plugin = AcademicsPlugin()
-        plugin.setup(site, 'testsite', logger)
-        self.assertTrue('faculties' in site.keys())
-        self.assertEqual(
-            self._logger_factory.get_messages(),
-            'Could not create faculty container in SIRP.\n'
-            )
-
-    def test_update(self):
-        site = dict()
-        logger = self.logger
-        plugin = AcademicsPlugin()
-        plugin.update(site, 'testsite', logger)
-        self.assertTrue('faculties' in site.keys())
-        self.assertTrue(isinstance(site['faculties'], FacultyContainer))
-        self.assertEqual(
-            self._logger_factory.get_messages(),
-            'Created faculty container for University\n'
-            )
-
-    def test_update_already_set_up(self):
-        site = dict(faculties=object())
-        logger = self.logger
-        plugin = AcademicsPlugin()
-        plugin.update(site, 'testsite', logger)
-        self.assertTrue('faculties' in site.keys())
-        self.assertEqual(
-            self._logger_factory.get_messages(), '')
Index: /main/waeup.sirp/trunk/src/waeup/sirp/university/tests/test_university.py
===================================================================
--- /main/waeup.sirp/trunk/src/waeup/sirp/university/tests/test_university.py	(revision 7332)
+++ /main/waeup.sirp/trunk/src/waeup/sirp/university/tests/test_university.py	(revision 7333)
@@ -27,7 +27,7 @@
         names = globals().keys()
         self.assertTrue('Course' in names)
-        self.assertTrue('CourseContainer' in names)
+        self.assertTrue('CoursesContainer' in names)
         self.assertTrue('Faculty' in names)
-        self.assertTrue('FacultyContainer' in names)
+        self.assertTrue('FacultiesContainer' in names)
 
 def test_suite():
