Index: main/waeup.uniben/trunk/src/waeup/uniben/students/interfaces.py
===================================================================
--- main/waeup.uniben/trunk/src/waeup/uniben/students/interfaces.py	(revision 8325)
+++ main/waeup.uniben/trunk/src/waeup/uniben/students/interfaces.py	(revision 8326)
@@ -23,6 +23,7 @@
 from waeup.kofa.students.vocabularies import nats_vocab
 from waeup.kofa.students.interfaces import (
-    IStudentBase,IUGStudentClearance,IPGStudentClearance,
-    IStudentPersonal,IStudentNavigation,
+    IStudentBase, IUGStudentClearance, IPGStudentClearance,
+    IStudentPersonal, IStudentNavigation, IStudentStudyLevel,
+    IStudentStudyCourse, ICourseTicket
     )
 from waeup.kofa.students.vocabularies import (
@@ -341,4 +342,14 @@
     """
 
+class ICustomStudentStudyCourse(IStudentStudyCourse):
+    """A container for student study levels.
+
+    """
+
+class ICustomStudentStudyLevel(IStudentStudyLevel):
+    """A container for course tickets.
+
+    """
+
 class ICustomStudentOnlinePayment(ICustomOnlinePayment):
     """A student payment via payment gateways.
@@ -355,2 +366,7 @@
 ICustomStudentOnlinePayment['p_level'].order = ICustomStudentOnlinePayment[
     'p_session'].order
+
+class ICustomCourseTicket(ICourseTicket):
+    """A course ticket.
+
+    """
Index: main/waeup.uniben/trunk/src/waeup/uniben/students/studycourse.py
===================================================================
--- main/waeup.uniben/trunk/src/waeup/uniben/students/studycourse.py	(revision 8326)
+++ main/waeup.uniben/trunk/src/waeup/uniben/students/studycourse.py	(revision 8326)
@@ -0,0 +1,51 @@
+## $Id$
+##
+## Copyright (C) 2012 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
+##
+"""
+Container which holds the data of the student study courses
+and contains the (student) study level objects.
+"""
+import grok
+from waeup.kofa.students.studycourse import (
+    StudentStudyCourse, StudentStudyCourseFactory)
+from waeup.uniben.students.interfaces import (
+    ICustomStudentStudyCourse, IStudentNavigation)
+from zope.interface import implementedBy
+from waeup.kofa.utils.helpers import attrs_to_fields
+
+class CustomStudentStudyCourse(StudentStudyCourse):
+    """This is a container for study levels.
+    """
+
+    grok.implements(ICustomStudentStudyCourse, IStudentNavigation)
+    grok.provides(ICustomStudentStudyCourse)
+
+    @property
+    def may_register(self):
+        return True
+
+CustomStudentStudyCourse = attrs_to_fields(CustomStudentStudyCourse)
+
+class CustomStudentStudyCourseFactory(StudentStudyCourseFactory):
+    """A factory for student study courses.
+    """
+
+    def __call__(self, *args, **kw):
+        return CustomStudentStudyCourse()
+
+    def getInterfaces(self):
+        return implementedBy(CustomStudentStudyCourse)
Index: main/waeup.uniben/trunk/src/waeup/uniben/students/studylevel.py
===================================================================
--- main/waeup.uniben/trunk/src/waeup/uniben/students/studylevel.py	(revision 8326)
+++ main/waeup.uniben/trunk/src/waeup/uniben/students/studylevel.py	(revision 8326)
@@ -0,0 +1,74 @@
+## $Id$
+##
+## Copyright (C) 2012 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
+##
+"""
+Container which holds the data of a student study level
+and contains the course tickets.
+"""
+import grok
+from zope.component.interfaces import IFactory
+from zope.interface import implementedBy
+from waeup.kofa.utils.helpers import attrs_to_fields
+from waeup.kofa.students.studylevel import (
+    StudentStudyLevel, CourseTicket,
+    CourseTicketFactory, StudentStudyLevelFactory)
+from waeup.uniben.students.interfaces import (
+    ICustomStudentStudyLevel, IStudentNavigation, ICustomCourseTicket)
+
+
+class CustomStudentStudyLevel(StudentStudyLevel):
+    """This is a container for course tickets.
+    """
+    grok.implements(ICustomStudentStudyLevel, IStudentNavigation)
+    grok.provides(ICustomStudentStudyLevel)
+
+CustomStudentStudyLevel = attrs_to_fields(CustomStudentStudyLevel)
+
+class CustomStudentStudyLevelFactory(StudentStudyLevelFactory):
+    """A factory for student study levels.
+    """
+
+    def __call__(self, *args, **kw):
+        return CustomStudentStudyLevel()
+
+    def getInterfaces(self):
+        return implementedBy(CustomStudentStudyLevel)
+
+class CustomCourseTicket(CourseTicket):
+    """This is a course ticket which allows the
+    student to attend the course. Lecturers will enter scores and more at
+    the end of the term.
+
+    A course ticket contains a copy of the original course and
+    course referrer data. If the courses and/or their referrers are removed, the
+    corresponding tickets remain unchanged. So we do not need any event
+    triggered actions on course tickets.
+    """
+    grok.implements(ICustomCourseTicket, IStudentNavigation)
+    grok.provides(ICustomCourseTicket)
+
+CustomCourseTicket = attrs_to_fields(CustomCourseTicket)
+
+class CustomCourseTicketFactory(CourseTicketFactory):
+    """A factory for student study levels.
+    """
+
+    def __call__(self, *args, **kw):
+        return CustomCourseTicket()
+
+    def getInterfaces(self):
+        return implementedBy(CustomCourseTicket)
Index: main/waeup.uniben/trunk/src/waeup/uniben/students/tests/test_browser.py
===================================================================
--- main/waeup.uniben/trunk/src/waeup/uniben/students/tests/test_browser.py	(revision 8325)
+++ main/waeup.uniben/trunk/src/waeup/uniben/students/tests/test_browser.py	(revision 8326)
@@ -21,5 +21,6 @@
 from hurry.workflow.interfaces import IWorkflowState
 from zope.component.hooks import setSite, clearSite
-from zope.component import getUtility
+from zope.component import getUtility, createObject
+from zope.interface import verify
 from waeup.kofa.app import University
 from waeup.kofa.students.tests.test_browser import StudentsFullSetup
@@ -30,4 +31,7 @@
 from waeup.uniben.testing import FunctionalLayer
 from waeup.uniben.students.utils import get_school_fee
+from waeup.uniben.students.interfaces import (
+    ICustomStudentStudyCourse, ICustomStudent,
+    ICustomStudentStudyLevel, ICustomCourseTicket)
 
 
@@ -99,4 +103,15 @@
     layer = FunctionalLayer
 
+    def test_classes(self):
+        # Let's see if objects created in the customized
+        # portal really implement the customized interfaces
+        verify.verifyObject(ICustomStudent, self.student)
+        verify.verifyObject(
+            ICustomStudentStudyCourse, self.student['studycourse'])
+        studylevel = createObject(u'waeup.StudentStudyLevel')
+        verify.verifyObject(ICustomStudentStudyLevel, studylevel)
+        ticket = createObject(u'waeup.CourseTicket')
+        verify.verifyObject(ICustomCourseTicket, ticket)
+
     def test_manage_access(self):
         # Managers can access the pages of students
Index: main/waeup.uniben/trunk/src/waeup/uniben/students/tests/test_student.py
===================================================================
--- main/waeup.uniben/trunk/src/waeup/uniben/students/tests/test_student.py	(revision 8326)
+++ main/waeup.uniben/trunk/src/waeup/uniben/students/tests/test_student.py	(revision 8326)
@@ -0,0 +1,127 @@
+## $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 students and related.
+"""
+from datetime import tzinfo
+from zope.component.interfaces import IFactory
+from zope.interface import verify
+from waeup.kofa.testing import FunctionalTestCase
+from waeup.uniben.students.student import CustomStudent, CustomStudentFactory
+from waeup.uniben.students.studycourse import (
+    CustomStudentStudyCourse, CustomStudentStudyCourseFactory)
+from waeup.uniben.students.studylevel import (
+    CustomStudentStudyLevel, CustomCourseTicket,
+    CustomStudentStudyLevelFactory,
+    CustomCourseTicketFactory)
+from waeup.uniben.students.interfaces import (
+    ICustomStudent, ICustomStudentStudyCourse,
+    ICustomStudentStudyLevel, ICustomCourseTicket)
+from waeup.uniben.testing import FunctionalLayer
+
+
+class CustomStudentFactoryTest(FunctionalTestCase):
+
+    layer = FunctionalLayer
+
+    def setUp(self):
+        super(CustomStudentFactoryTest, self).setUp()
+        self.factory = CustomStudentFactory()
+
+    def tearDown(self):
+        super(CustomStudentFactoryTest, self).tearDown()
+
+    def test_interfaces(self):
+        verify.verifyClass(IFactory, CustomStudentFactory)
+        verify.verifyObject(IFactory, self.factory)
+
+    def test_factory(self):
+        obj = self.factory()
+        assert isinstance(obj, CustomStudent)
+
+    def test_getInterfaces(self):
+        implemented_by = self.factory.getInterfaces()
+        assert implemented_by.isOrExtends(ICustomStudent)
+
+class CustomStudentStudyCourseFactoryTest(FunctionalTestCase):
+
+    layer = FunctionalLayer
+
+    def setUp(self):
+        super(CustomStudentStudyCourseFactoryTest, self).setUp()
+        self.factory = CustomStudentStudyCourseFactory()
+
+    def tearDown(self):
+        super(CustomStudentStudyCourseFactoryTest, self).tearDown()
+
+    def test_interfaces(self):
+        verify.verifyClass(IFactory, CustomStudentStudyCourseFactory)
+        verify.verifyObject(IFactory, self.factory)
+
+    def test_factory(self):
+        obj = self.factory()
+        assert isinstance(obj, CustomStudentStudyCourse)
+
+    def test_getInterfaces(self):
+        implemented_by = self.factory.getInterfaces()
+        assert implemented_by.isOrExtends(ICustomStudentStudyCourse)
+
+class CustomStudentStudyLevelFactoryTest(FunctionalTestCase):
+
+    layer = FunctionalLayer
+
+    def setUp(self):
+        super(CustomStudentStudyLevelFactoryTest, self).setUp()
+        self.factory = CustomStudentStudyLevelFactory()
+
+    def tearDown(self):
+        super(CustomStudentStudyLevelFactoryTest, self).tearDown()
+
+    def test_interfaces(self):
+        verify.verifyClass(IFactory, CustomStudentStudyLevelFactory)
+        verify.verifyObject(IFactory, self.factory)
+
+    def test_factory(self):
+        obj = self.factory()
+        assert isinstance(obj, CustomStudentStudyLevel)
+
+    def test_getInterfaces(self):
+        implemented_by = self.factory.getInterfaces()
+        assert implemented_by.isOrExtends(ICustomStudentStudyLevel)
+
+class CustomCourseTicketFactoryTest(FunctionalTestCase):
+
+    layer = FunctionalLayer
+
+    def setUp(self):
+        super(CustomCourseTicketFactoryTest, self).setUp()
+        self.factory = CustomCourseTicketFactory()
+
+    def tearDown(self):
+        super(CustomCourseTicketFactoryTest, self).tearDown()
+
+    def test_interfaces(self):
+        verify.verifyClass(IFactory, CustomCourseTicketFactory)
+        verify.verifyObject(IFactory, self.factory)
+
+    def test_factory(self):
+        obj = self.factory()
+        assert isinstance(obj, CustomCourseTicket)
+
+    def test_getInterfaces(self):
+        implemented_by = self.factory.getInterfaces()
+        assert implemented_by.isOrExtends(ICustomCourseTicket)
