Index: main/waeup.kofa/trunk/src/waeup/kofa/hostels/browser.py
===================================================================
--- main/waeup.kofa/trunk/src/waeup/kofa/hostels/browser.py	(revision 9400)
+++ main/waeup.kofa/trunk/src/waeup/kofa/hostels/browser.py	(revision 9414)
@@ -37,5 +37,5 @@
 from waeup.kofa.hostels.hostel import Hostel
 from waeup.kofa.hostels.interfaces import (
-    IHostelsContainer, IHostel, IBed, IBedAllocateStudent)
+    IHostelsContainer, IHostel, IBed)
 from waeup.kofa.widgets.datewidget import FriendlyDatetimeDisplayWidget
 
@@ -350,8 +350,8 @@
     """ View to edit bed data
     """
-    grok.context(IBedAllocateStudent)
+    grok.context(IBed)
     grok.name('index')
     grok.require('waeup.manageHostels')
-    form_fields = grok.AutoFields(IBedAllocateStudent).omit(
+    form_fields = grok.AutoFields(IBed).omit(
         'bed_id', 'bed_number', 'bed_type')
     label = _('Allocate student')
Index: main/waeup.kofa/trunk/src/waeup/kofa/hostels/hostel.py
===================================================================
--- main/waeup.kofa/trunk/src/waeup/kofa/hostels/hostel.py	(revision 9400)
+++ main/waeup.kofa/trunk/src/waeup/kofa/hostels/hostel.py	(revision 9414)
@@ -26,5 +26,5 @@
 from waeup.kofa.utils.helpers import attrs_to_fields
 from waeup.kofa.hostels.vocabularies import NOT_OCCUPIED
-from waeup.kofa.hostels.interfaces import IHostel, IBed, IBedAllocateStudent
+from waeup.kofa.hostels.interfaces import IHostel, IBed
 from waeup.kofa.students.interfaces import IBedTicket
 from waeup.kofa.interfaces import IKofaUtils
@@ -143,5 +143,5 @@
     """This is a bed.
     """
-    grok.implements(IBed, IBedAllocateStudent)
+    grok.implements(IBed)
     grok.provides(IBed)
 
Index: main/waeup.kofa/trunk/src/waeup/kofa/hostels/interfaces.py
===================================================================
--- main/waeup.kofa/trunk/src/waeup/kofa/hostels/interfaces.py	(revision 9400)
+++ main/waeup.kofa/trunk/src/waeup/kofa/hostels/interfaces.py	(revision 9414)
@@ -16,5 +16,8 @@
 ## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 ##
+from  grok import getSite
 from datetime import datetime
+from zope.component import getUtility
+from zope.catalog.interfaces import ICatalog
 from zope.interface import invariant, Invalid, Attribute
 from zope import schema
@@ -23,5 +26,6 @@
 from waeup.kofa.interfaces import MessageFactory as _
 from waeup.kofa.hostels.vocabularies import (
-    bed_letters, blocks, SpecialHandlingSource, StudentSource)
+    bed_letters, blocks, SpecialHandlingSource,
+    NOT_OCCUPIED)
 
 class IHostelsContainer(IKofaObject):
@@ -236,15 +240,20 @@
         )
 
-
-
-class IBedAllocateStudent(IBed):
-    """A representation of beds for allocation form only.
-
-    """
-
-    owner = schema.Choice(
-        title = _(u'Owner (Student)'),
-        source = StudentSource(),
-        default = None,
-        required = True,
-        )
+    @invariant
+    def allowed_owners(bed):
+        if bed.owner == NOT_OCCUPIED:
+            return
+        catalog = getUtility(ICatalog, name='students_catalog')
+        accommodation_session = getSite()['hostels'].accommodation_session
+        students = catalog.searchResults(current_session=(
+            accommodation_session,accommodation_session))
+        student_ids = [student.student_id for student in students]
+        if not bed.owner in student_ids:
+            raise Invalid(_(
+                "Either student does not exist or is not in accommodation session."))
+        catalog = getUtility(ICatalog, name='beds_catalog')
+        beds = catalog.searchResults(owner=(bed.owner,bed.owner))
+        if len(beds):
+            allocated_bed = [bed.bed_id for bed in beds][0]
+            raise Invalid(_(
+                "This student resides in bed ${a}.", mapping = {'a':allocated_bed}))
Index: main/waeup.kofa/trunk/src/waeup/kofa/hostels/tests.py
===================================================================
--- main/waeup.kofa/trunk/src/waeup/kofa/hostels/tests.py	(revision 9400)
+++ main/waeup.kofa/trunk/src/waeup/kofa/hostels/tests.py	(revision 9414)
@@ -313,9 +313,21 @@
         self.assertMatches(
           '...No allocated bed selected...', self.browser.contents)
-        # Managers can manually allocate students after cancellation
+        # Managers can manually allocate eligible students after cancellation
         self.browser.open(self.container_path + '/hall-1/hall-1_A_101_A')
-        self.browser.getControl(name="form.owner").value = [self.student_id]
+        self.browser.getControl(name="form.owner").value = 'nonsense'
+        self.browser.getControl("Save").click()
+        self.assertMatches(
+            "...Either student does not exist or is not in accommodation session...",
+            self.browser.contents)
+        self.browser.getControl(name="form.owner").value = self.student_id
         self.browser.getControl("Save").click()
         self.assertMatches("...Form has been saved...", self.browser.contents)
+        # Students can only be allocated once
+        self.browser.open(self.container_path + '/hall-1/hall-1_A_101_B')
+        self.browser.getControl(name="form.owner").value = self.student_id
+        self.browser.getControl("Save").click()
+        self.assertMatches(
+            "...This student resides in bed hall-1_A_101_A...",
+            self.browser.contents)
         # If we open the same form again, we will be redirected to hostel
         # manage page. Beds must be released first before they can be
@@ -347,5 +359,5 @@
         # Also the number of the bed has changed.
         self.assertFalse(new_number == old_number)
-        # The number of occupied bed are displayed on container page.
+        # The number of occupied beds are displayed on container page.
         self.browser.open(self.container_path)
         self.assertTrue('1 of 8' in self.browser.contents)
Index: main/waeup.kofa/trunk/src/waeup/kofa/hostels/vocabularies.py
===================================================================
--- main/waeup.kofa/trunk/src/waeup/kofa/hostels/vocabularies.py	(revision 9400)
+++ main/waeup.kofa/trunk/src/waeup/kofa/hostels/vocabularies.py	(revision 9414)
@@ -27,31 +27,4 @@
 
 NOT_OCCUPIED = u'not occupied'
-
-class StudentSource(BasicContextualSourceFactory):
-    """A students source delivers all students in accommodation session.
-    """
-
-    def acco_students(self, context):
-        catalog = getUtility(ICatalog, name='students_catalog')
-        accommodation_session = getSite()['hostels'].accommodation_session
-        students = catalog.searchResults(current_session=(
-            accommodation_session,accommodation_session))
-        existing_students = [
-            context.__parent__[key].owner
-            for key in context.__parent__.keys()]
-        students = [student for student in students
-                      if not student.student_id in existing_students]
-        students = sorted(list(students),
-                          key=lambda value: value.student_id)
-        return dict([(student.student_id,student.fullname) for student in students])
-
-    def getValues(self, context):
-        return self.acco_students(context).keys()
-
-    def getToken(self, context, value):
-        return value
-
-    def getTitle(self, context, value):
-        return "%s - %s" % (value, self.acco_students(context)[value])
 
 class SpecialHandlingSource(ContextualDictSourceFactoryBase):
