Index: /main/waeup.sirp/trunk/src/waeup/sirp/browser/pages.py
===================================================================
--- /main/waeup.sirp/trunk/src/waeup/sirp/browser/pages.py	(revision 5006)
+++ /main/waeup.sirp/trunk/src/waeup/sirp/browser/pages.py	(revision 5007)
@@ -16,5 +16,6 @@
     IUniversity, IFacultyContainer, IFaculty, IDepartment, ICourse,
     ICertificate, ICertificateCourse)
-from waeup.sirp.catalog import search, search_context
+from waeup.sirp.university.catalog import search
+from waeup.sirp.catalog import search_context
 from waeup.sirp.interfaces import(
     IWAeUPObject, IUserContainer, IUserAccount, IDataCenter,
Index: /main/waeup.sirp/trunk/src/waeup/sirp/catalog.py
===================================================================
--- /main/waeup.sirp/trunk/src/waeup/sirp/catalog.py	(revision 5006)
+++ /main/waeup.sirp/trunk/src/waeup/sirp/catalog.py	(revision 5007)
@@ -5,10 +5,6 @@
 from hurry.query import Eq
 from waeup.sirp.app import University
-from waeup.sirp.university.interfaces import ICourse, ICertificateCourse
+from waeup.sirp.interfaces import IQueryResultItem
 from waeup.sirp.student.interfaces import IStudent
-from zope.app.catalog.interfaces import ICatalog
-from zope.app.intid.interfaces import IIntIds
-from zope.component import getUtility
-from zope.component.interfaces import ComponentLookupError
 
 
@@ -18,57 +14,6 @@
      grok.context(IStudent)
 
-     name = index.Field(attribute='name')
+     name = grok.index.Field(attribute='name')
 
-
-class CourseIndexes(grok.Indexes):
-     grok.site(University)
-     grok.name('courses_catalog')
-     grok.context(ICourse)
-
-     code = index.Field(attribute='code')
-     title = index.Text(attribute='title')
-
-class CourseCertificatesIndexes(grok.Indexes):
-     grok.site(University)
-     grok.name('certcourses_catalog')
-     grok.context(ICertificateCourse)
-
-     course_code = index.Field(attribute='getCourseCode')
-
-@grok.subscribe(ICourse, grok.IObjectAddedEvent)
-def handleCourseAdd(obj, event):
-     """Index an added course with the local catalog.
-
-     Courses are not indexed automatically, as they are not a
-     dictionary subitem of the accompanied site object
-     (`IUniversity`). I.e. one cannot get them by asking for
-     ``app['FACCODE']['DEPTCODE']['COURSECODE']`` but one has to ask for
-     ``app.faculties['FACCODE']['DEPTCODE'].courses['COURSECODE']``.
-
-     Once, a course is indexed we can leave the further handling to
-     the default component architechture. At least removals will
-     be handled correctly then (and the course unindexed).
-     """
-     try:
-          cat = getUtility(ICatalog, name='courses_catalog')
-     except ComponentLookupError:
-          # catalog not available. This might happen during tests.
-          return
-     intids = getUtility(IIntIds)
-     index = cat['code']
-     index.index_doc(intids.getId(obj), obj)
-
-from zope.interface import Interface
-from zope import schema
-
-class IQueryResultItem(Interface):
-     url = schema.TextLine(
-          title = u'URL that links to the found item')
-     title = schema.TextLine(
-          title = u'Title displayed in search results.')
-     description = schema.Text(
-          title = u'Longer description of the item found.')
-     
-     
 class QueryResultItem(object):
      grok.implements(IQueryResultItem)
@@ -82,31 +27,4 @@
           self.title = context.title
           self.description = ''
-     
-class CourseQueryResultItem(QueryResultItem):
-     def __init__(self, context, view):
-          self.context = context
-          self.url = view.url(context)
-          self.title = "COURSE: " + context.title
-          self.description = 'code: %s' % context.code
-
-def search(query=None, view=None):
-     if not query:
-          return []
-     cat = getUtility(ICatalog, name='courses_catalog')
-     results = list(cat.searchResults(code=(query, query)))
-          
-     hitlist = []
-     results = Query().searchResults(
-          Eq(('courses_catalog', 'code'), query))
-     for result in results:
-          hitlist.append(CourseQueryResultItem(result, view=view))
-
-     results = Query().searchResults(
-          Text(('courses_catalog', 'title'), query))
-          
-     for result in results:
-          hitlist.append(CourseQueryResultItem(result, view=view))
-
-     return hitlist
 
 def search_context(query):
Index: /main/waeup.sirp/trunk/src/waeup/sirp/interfaces.py
===================================================================
--- /main/waeup.sirp/trunk/src/waeup/sirp/interfaces.py	(revision 5006)
+++ /main/waeup.sirp/trunk/src/waeup/sirp/interfaces.py	(revision 5007)
@@ -202,2 +202,13 @@
     """Emitted, when the storage of a datacenter changes.
     """
+
+class IQueryResultItem(Interface):
+    """An item in a search result.
+    """
+    url = schema.TextLine(
+        title = u'URL that links to the found item')
+    title = schema.TextLine(
+        title = u'Title displayed in search results.')
+    description = schema.Text(
+        title = u'Longer description of the item found.')
+     
Index: /main/waeup.sirp/trunk/src/waeup/sirp/university/catalog.py
===================================================================
--- /main/waeup.sirp/trunk/src/waeup/sirp/university/catalog.py	(revision 5007)
+++ /main/waeup.sirp/trunk/src/waeup/sirp/university/catalog.py	(revision 5007)
@@ -0,0 +1,76 @@
+"""Catalog and searching components for academics stuff.
+"""
+import grok
+from hurry.query import Eq
+from zope.app.catalog.interfaces import ICatalog
+from zope.app.intid.interfaces import IIntIds
+from zope.component import getUtility
+from zope.component.interfaces import ComponentLookupError
+from waeup.sirp.interfaces import IUniversity
+from waeup.sirp.catalog import QueryResultItem
+from waeup.sirp.university.interfaces import ICourse, ICertificateCourse
+
+class CourseIndexes(grok.Indexes):
+     grok.site(IUniversity)
+     grok.name('courses_catalog')
+     grok.context(ICourse)
+
+     code = grok.index.Field(attribute='code')
+     title = grok.index.Text(attribute='title')
+
+class CourseCertificatesIndexes(grok.Indexes):
+     grok.site(IUniversity)
+     grok.name('certcourses_catalog')
+     grok.context(ICertificateCourse)
+
+     course_code = grok.index.Field(attribute='getCourseCode')
+
+@grok.subscribe(ICourse, grok.IObjectAddedEvent)
+def handleCourseAdd(obj, event):
+     """Index an added course with the local catalog.
+
+     Courses are not indexed automatically, as they are not a
+     dictionary subitem of the accompanied site object
+     (`IUniversity`). I.e. one cannot get them by asking for
+     ``app['FACCODE']['DEPTCODE']['COURSECODE']`` but one has to ask for
+     ``app.faculties['FACCODE']['DEPTCODE'].courses['COURSECODE']``.
+
+     Once, a course is indexed we can leave the further handling to
+     the default component architechture. At least removals will
+     be handled correctly then (and the course unindexed).
+     """
+     try:
+          cat = getUtility(ICatalog, name='courses_catalog')
+     except ComponentLookupError:
+          # catalog not available. This might happen during tests.
+          return
+     intids = getUtility(IIntIds)
+     index = cat['code']
+     index.index_doc(intids.getId(obj), obj)
+
+class CourseQueryResultItem(QueryResultItem):
+     def __init__(self, context, view):
+          self.context = context
+          self.url = view.url(context)
+          self.title = "COURSE: " + context.title
+          self.description = 'code: %s' % context.code
+
+def search(query=None, view=None):
+     if not query:
+          return []
+     cat = getUtility(ICatalog, name='courses_catalog')
+     results = list(cat.searchResults(code=(query, query)))
+          
+     hitlist = []
+     results = Query().searchResults(
+          Eq(('courses_catalog', 'code'), query))
+     for result in results:
+          hitlist.append(CourseQueryResultItem(result, view=view))
+
+     results = Query().searchResults(
+          Text(('courses_catalog', 'title'), query))
+          
+     for result in results:
+          hitlist.append(CourseQueryResultItem(result, view=view))
+
+     return hitlist
