Index: /main/waeup.sirp/trunk/src/waeup/sirp/browser/browser.txt
===================================================================
--- /main/waeup.sirp/trunk/src/waeup/sirp/browser/browser.txt	(revision 6244)
+++ /main/waeup.sirp/trunk/src/waeup/sirp/browser/browser.txt	(revision 6245)
@@ -337,5 +337,5 @@
   >>> print browser.contents
   <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"...
-  ...<li class="message">Course exists already in...</li>
+  ...<li class="message">A course with same code already exists:...</li>
   ...
 
Index: /main/waeup.sirp/trunk/src/waeup/sirp/browser/pages.py
===================================================================
--- /main/waeup.sirp/trunk/src/waeup/sirp/browser/pages.py	(revision 6244)
+++ /main/waeup.sirp/trunk/src/waeup/sirp/browser/pages.py	(revision 6245)
@@ -1292,5 +1292,19 @@
         course = createObject(u'waeup.Course')
         self.applyData(course, **data)
-        message = self.context.courses.addCourse(course)
+        try:
+            self.context.courses.addCourse(course)
+        except DuplicationError, error:
+            # signals duplication error
+            entries = error.entries
+            for entry in entries:
+                # do not use error.msg but render a more detailed message instead
+                # and show links to all certs with same code
+                message = 'A course with same code already exists: '
+                message += '<a href="%s">%s</a>' % (
+                    self.url(entry), getattr(entry, '__name__', u'Unnamed'))
+                self.flash(message)
+            self.redirect(self.url(self.context, u'@@addcourse'))
+            return
+        message = u'Course %s successfully created.' % (course.code)
         self.flash(message)
         self.redirect(self.url(self.context, u'@@manage')+'#tab-2')
Index: /main/waeup.sirp/trunk/src/waeup/sirp/university/coursecontainer.py
===================================================================
--- /main/waeup.sirp/trunk/src/waeup/sirp/university/coursecontainer.py	(revision 6244)
+++ /main/waeup.sirp/trunk/src/waeup/sirp/university/coursecontainer.py	(revision 6245)
@@ -5,5 +5,6 @@
 from zope.component.interfaces import IFactory, ComponentLookupError
 from zope.catalog.interfaces import ICatalog
-from zope.component import getUtility
+from zope.component import queryUtility
+from waeup.sirp.interfaces import DuplicationError
 from waeup.sirp.university.interfaces import ICourseContainer, ICourse
 
@@ -14,29 +15,39 @@
     grok.require('waeup.manageUniversity')
 
-    def addCourse(self, course):
-        """Add a course.
+    def __setitem__(self, name, course):
+        """See corresponding docstring in certificatecontainer.py.
         """
         if not ICourse.providedBy(course):
-            raise TypeError('CourseContainers contain only ICourse instances')
-        try:
-            cat = getUtility(ICatalog, name='courses_catalog')
-        except ComponentLookupError:
-            # catalog not available. This might happen during tests.
-            self[course.code] = course
-            return 'Course added (for tests only).'
-        results = list(cat.searchResults(code=(course.code,course.code)))
-        if results:
-            dep = results[0].__parent__.__parent__.longtitle()
-            fac = results[0].__parent__.__parent__.__parent__.longtitle()
-            return 'Course exists already in %s / %s.' % (fac,dep)
-        self[course.code] = course
-        return 'Course added.'
+            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):
-        """Remove all objects from course container.
+        """See corresponding docstring and comments in certificatecontainer.py.
         """
-        keys = self.keys()
-        for key in keys:
-            del self[key]
+        self._SampleContainer__data.clear()
+        del self.__dict__['_BTreeContainer__len']
 
 class CourseContainerFactory(grok.GlobalUtility):
Index: /main/waeup.sirp/trunk/src/waeup/sirp/university/coursecontainer.txt
===================================================================
--- /main/waeup.sirp/trunk/src/waeup/sirp/university/coursecontainer.txt	(revision 6244)
+++ /main/waeup.sirp/trunk/src/waeup/sirp/university/coursecontainer.txt	(revision 6245)
@@ -71,5 +71,4 @@
         >>> mycourse = Course(code='COURSE1')
         >>> mycontainer.addCourse(mycourse)
-        'Course added (for tests only).'
         >>> list(mycontainer.keys())
         [u'COURSE1']
