From a29ca62bae9d0d689c66f2330fdf80dcc0f6c3b5 Mon Sep 17 00:00:00 2001
From: Emil Siverhall <emil-siv@dsv.su.se>
Date: Mon, 27 Feb 2012 13:41:36 +0100
Subject: [PATCH 1/7] Added support for sortable params to KeywordDao

---
 .../match/dao/interfaces/KeywordDao.java      | 40 +++++++++++++++++++
 .../match/dao/jpa/KeywordDaoJPAImp.java       | 21 ++++++++++
 2 files changed, 61 insertions(+)

diff --git a/src/main/java/se/su/dsv/scipro/match/dao/interfaces/KeywordDao.java b/src/main/java/se/su/dsv/scipro/match/dao/interfaces/KeywordDao.java
index eb4d64b5a8..80e609f010 100644
--- a/src/main/java/se/su/dsv/scipro/match/dao/interfaces/KeywordDao.java
+++ b/src/main/java/se/su/dsv/scipro/match/dao/interfaces/KeywordDao.java
@@ -1,8 +1,10 @@
 package se.su.dsv.scipro.match.dao.interfaces;
 
+import java.io.Serializable;
 import java.util.List;
 import java.util.Set;
 
+import se.su.dsv.scipro.data.dao.interfaces.Dao;
 import se.su.dsv.scipro.data.dao.interfaces.LazyDeleteDao;
 import se.su.dsv.scipro.match.dataobject.Keyword;
 import se.su.dsv.scipro.match.dataobject.KeywordType;
@@ -10,6 +12,7 @@ import se.su.dsv.scipro.match.dataobject.KeywordType;
 public interface KeywordDao extends LazyDeleteDao<Keyword>{
 
     Set<Keyword> getKeywords(KeywordType type, boolean includeDeleted);
+    List<Keyword> getKeywordList(Params params);
     
     public List<Keyword> findAllFromType(KeywordType kt, boolean includeDeleted);
     
@@ -17,4 +20,41 @@ public interface KeywordDao extends LazyDeleteDao<Keyword>{
     Keyword getKeywordByNameAndType(String keywordName, KeywordType type);
 
 
+    public static class Params extends Dao.SortableParams implements Serializable {
+
+		private static final long serialVersionUID = 5317030582030781723L;
+		
+		private String keyword;
+		private KeywordType type;
+		private boolean includeDeleted = false;
+
+		public Params() {
+			//Sort keywords on their name in ascending order as default when using Params
+			setSortOn("keyword", Sort.ASCENDING);
+		}
+		
+		public void setKeyword(String keyword) {
+			this.keyword = keyword;
+		}
+
+		public String getKeyword() {
+			return keyword;
+		}
+
+		public void setType(KeywordType type) {
+			this.type = type;
+		}
+
+		public KeywordType getType() {
+			return type;
+		}
+
+		public void setIncludeDeleted(boolean includeDeleted) {
+			this.includeDeleted = includeDeleted;
+		}
+
+		public boolean isIncludeDeleted() {
+			return includeDeleted;
+		}
+    }
 }
diff --git a/src/main/java/se/su/dsv/scipro/match/dao/jpa/KeywordDaoJPAImp.java b/src/main/java/se/su/dsv/scipro/match/dao/jpa/KeywordDaoJPAImp.java
index f1b466f4a7..9b4860b570 100644
--- a/src/main/java/se/su/dsv/scipro/match/dao/jpa/KeywordDaoJPAImp.java
+++ b/src/main/java/se/su/dsv/scipro/match/dao/jpa/KeywordDaoJPAImp.java
@@ -14,6 +14,7 @@ import org.springframework.orm.jpa.JpaCallback;
 import org.springframework.stereotype.Repository;
 import org.springframework.transaction.annotation.Transactional;
 
+import se.su.dsv.scipro.data.dao.jpa.AbstractQuerySet;
 import se.su.dsv.scipro.data.dao.jpa.AbstractSortableQuerySet;
 import se.su.dsv.scipro.data.dao.jpa.LazyDeleteAbstractDaoJPAImp;
 import se.su.dsv.scipro.data.dao.jpa.Query;
@@ -41,6 +42,18 @@ public class KeywordDaoJPAImp extends LazyDeleteAbstractDaoJPAImp<Keyword> imple
         }
     }
 
+    @Override
+    public List<Keyword> getKeywordList(Params params) {
+    	return getJpaTemplate().execute(createQuerySet(params).fetchCallback());
+    }
+    
+    private AbstractQuerySet<Keyword> createQuerySet(Params params) {
+        return new QuerySet()
+        	.type(params.getType())
+        	.includeDeleted(params.isIncludeDeleted())
+        	.sort(params);
+    }
+    
     private static class QuerySet extends AbstractSortableQuerySet<Keyword> {
         public QuerySet() {
             super(Keyword.class);
@@ -55,6 +68,14 @@ public class KeywordDaoJPAImp extends LazyDeleteAbstractDaoJPAImp<Keyword> imple
             return this;
         }
         
+        public QuerySet includeDeleted(boolean includeDeleted) {
+        	if(!includeDeleted) {
+        		getQuery().combine(
+        				new Query().where("k.deleted = false"));
+        	}
+        	return this;
+        }
+        
         public QuerySet noDeleted() {
         	getQuery().combine(
         		new Query().where("k.deleted = false"));

From e21b6c7039d368ab48a5d999b2186707761791dc Mon Sep 17 00:00:00 2001
From: Emil Siverhall <emil-siv@dsv.su.se>
Date: Mon, 27 Feb 2012 13:42:11 +0100
Subject: [PATCH 2/7] changes in keyword data provider to match new params

---
 .../dataprovider/KeywordsDataProvider.java     | 18 ++++++++++++------
 1 file changed, 12 insertions(+), 6 deletions(-)

diff --git a/src/main/java/se/su/dsv/scipro/match/dataprovider/KeywordsDataProvider.java b/src/main/java/se/su/dsv/scipro/match/dataprovider/KeywordsDataProvider.java
index 82e4409e98..19c9e821fd 100644
--- a/src/main/java/se/su/dsv/scipro/match/dataprovider/KeywordsDataProvider.java
+++ b/src/main/java/se/su/dsv/scipro/match/dataprovider/KeywordsDataProvider.java
@@ -5,6 +5,7 @@ import java.util.Iterator;
 import org.apache.wicket.spring.injection.annot.SpringBean;
 
 import se.su.dsv.scipro.data.dao.interfaces.Dao;
+import se.su.dsv.scipro.data.dao.interfaces.Dao.SortableParams.Sort;
 import se.su.dsv.scipro.dataproviders.SortSpecifier;
 import se.su.dsv.scipro.dataproviders.SortableDataProvider;
 import se.su.dsv.scipro.match.dao.interfaces.KeywordDao;
@@ -15,29 +16,34 @@ public class KeywordsDataProvider extends SortableDataProvider<Keyword>{
 
 	private static final long serialVersionUID = 1L;
 
-	private KeywordType keywordType = null;
-
 	@SpringBean
 	protected KeywordDao keywordDao;
+	private KeywordDao.Params params;
 
 	@Override
 	protected Dao<Keyword> getDao() {
 		return keywordDao;
 	}
 	
-	public KeywordsDataProvider(final SortSpecifier sortSpecifier, KeywordType keywordType) {
+	public KeywordsDataProvider(KeywordType keywordType, boolean includeDeleted) {
+		this(null, keywordType, includeDeleted);
+	}
+	
+	public KeywordsDataProvider(final SortSpecifier sortSpecifier, KeywordType keywordType, boolean includeDeleted) {
 		super(sortSpecifier, Keyword.class);
-		this.keywordType = keywordType;
+		params = new KeywordDao.Params();
+		params.setIncludeDeleted(includeDeleted);
+		params.setType(keywordType);
 	}
 	
 	public Iterator<Keyword> iterator(int first, int count) {
-		Iterator<Keyword> iter = keywordDao.getKeywords(keywordType, true).iterator();
+		Iterator<Keyword> iter = keywordDao.getKeywordList(params).iterator();
 		return iter;
 	}
 	
 	@Override
 	public int size() {
-		return keywordDao.getKeywords(keywordType, true).size();
+		return keywordDao.getKeywordList(params).size();
 	}
 
 }
\ No newline at end of file

From 9d7f9e4343132098bf8cda49810eb9425de57310 Mon Sep 17 00:00:00 2001
From: Emil Siverhall <emil-siv@dsv.su.se>
Date: Mon, 27 Feb 2012 13:43:50 +0100
Subject: [PATCH 3/7] Switched to new param implementation when retrieving
 keywords on a few pages

---
 .../admin/panels/match/ManageKeywordPanel.java   |  2 +-
 .../match/panel/FilterFormKeywordPanel.java      |  6 ++++--
 .../project/panels/KeywordSelectionPanel.java    | 16 +++++++++++-----
 3 files changed, 16 insertions(+), 8 deletions(-)

diff --git a/src/main/java/se/su/dsv/scipro/admin/panels/match/ManageKeywordPanel.java b/src/main/java/se/su/dsv/scipro/admin/panels/match/ManageKeywordPanel.java
index a75eca0610..631bae94a0 100644
--- a/src/main/java/se/su/dsv/scipro/admin/panels/match/ManageKeywordPanel.java
+++ b/src/main/java/se/su/dsv/scipro/admin/panels/match/ManageKeywordPanel.java
@@ -58,7 +58,7 @@ public class ManageKeywordPanel extends Panel {
 		dialog.add(new EmptyPanel("dialogContent"));
 		dialog.setOutputMarkupId(true);
 		
-		keywordsDataProvider = new KeywordsDataProvider(null, keywordType);
+		keywordsDataProvider = new KeywordsDataProvider(keywordType, true);
 		
 		tableContainer = new WebMarkupContainer("table");
 		tableContainer.setOutputMarkupId(true);
diff --git a/src/main/java/se/su/dsv/scipro/match/panel/FilterFormKeywordPanel.java b/src/main/java/se/su/dsv/scipro/match/panel/FilterFormKeywordPanel.java
index 707767139c..76510c3fd1 100644
--- a/src/main/java/se/su/dsv/scipro/match/panel/FilterFormKeywordPanel.java
+++ b/src/main/java/se/su/dsv/scipro/match/panel/FilterFormKeywordPanel.java
@@ -47,8 +47,10 @@ public class FilterFormKeywordPanel extends Panel {
 		
 		
 		KeywordType kwType = keywordTypeDao.findByType(type);
-		Set<Keyword> tmpWords = keywordDao.getKeywords(kwType, true);
-		keywords = new ArrayList<Keyword>(tmpWords);
+		KeywordDao.Params params = new KeywordDao.Params();
+		params.setType(kwType);
+		params.setIncludeDeleted(true);
+		keywords = keywordDao.getKeywordList(params);
 		CompoundPropertyModel<List<Keyword>> keyWordModel = new CompoundPropertyModel<List<Keyword>>(keywords);
 		
 		checkGroup = new CheckGroup<Keyword>("checkGroup", new ArrayList<Keyword>());
diff --git a/src/main/java/se/su/dsv/scipro/project/panels/KeywordSelectionPanel.java b/src/main/java/se/su/dsv/scipro/project/panels/KeywordSelectionPanel.java
index b76ca424a8..ae907f9960 100644
--- a/src/main/java/se/su/dsv/scipro/project/panels/KeywordSelectionPanel.java
+++ b/src/main/java/se/su/dsv/scipro/project/panels/KeywordSelectionPanel.java
@@ -133,8 +133,9 @@ public class KeywordSelectionPanel extends Panel {
 		if (keywordProvider.getObject() != null) {
 			ideaAreaKeywords = new ArrayList<Keyword>(keywordProvider.getObject().getKeywords().getFiltered(area));
 		}
-		Set<Keyword> areaKeySet = keywordDao.getKeywords(area, false);
-		List<Keyword> areaKeyList = new ArrayList<Keyword>(areaKeySet);
+		KeywordDao.Params params = new KeywordDao.Params();
+		params.setType(area);
+		List<Keyword> areaKeyList = keywordDao.getKeywordList(params);
 		CompoundPropertyModel<List<Keyword>> listModel = new CompoundPropertyModel<List<Keyword>>(areaKeyList);
 		
 		researchAreaGroup = new CheckGroup<Keyword>("researchAreaGroup", ideaAreaKeywords);
@@ -162,13 +163,18 @@ public class KeywordSelectionPanel extends Panel {
 		}
 	}
 	private void addRegularKeywordSelection() {
-		KeywordType keyword = keywordTypeDao.findByType(KeywordTypeDao.TYPE.REGULAR);
-		List<Keyword> selectedWords = keywordProvider.getObject().getKeywords().getFiltered(keyword);
+		KeywordType keywordType = keywordTypeDao.findByType(KeywordTypeDao.TYPE.REGULAR);
+		List<Keyword> selectedWords = keywordProvider.getObject().getKeywords().getFiltered(keywordType);
 		ideaKeywords = new ArrayList<Keyword>();
 		if(!selectedWords.isEmpty()) 
 			ideaKeywords = new ArrayList<Keyword>(selectedWords);
 		
-		Set<Keyword> keySet = keywordDao.getKeywords(keyword, false);
+		KeywordDao.Params params = new KeywordDao.Params();
+		params.setType(keywordType);
+		
+		List<Keyword> keywordList = keywordDao.getKeywordList(params);
+		Set<Keyword> keySet = new HashSet<Keyword>(keywordList);
+		//Set<Keyword> keySet = keywordDao.getKeywords(keywordType, false);
 		regularKeywordsPalette = new Palette<Keyword>("keywordPalette",
 				new ListModel<Keyword>(ideaKeywords),
 				new CollectionModel<Keyword>(keySet),

From 974f95864cbe412e4149a2c12ed5b78064351414 Mon Sep 17 00:00:00 2001
From: Emil Siverhall <emil-siv@dsv.su.se>
Date: Mon, 27 Feb 2012 13:44:20 +0100
Subject: [PATCH 4/7] unit test for new keyword dao method

---
 .../java/se/su/dsv/scipro/match/dao/TestKeywordDao.java    | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/src/test/java/se/su/dsv/scipro/match/dao/TestKeywordDao.java b/src/test/java/se/su/dsv/scipro/match/dao/TestKeywordDao.java
index e7dfbf2b91..ecdde37710 100644
--- a/src/test/java/se/su/dsv/scipro/match/dao/TestKeywordDao.java
+++ b/src/test/java/se/su/dsv/scipro/match/dao/TestKeywordDao.java
@@ -1,6 +1,7 @@
 package se.su.dsv.scipro.match.dao;
 
 import java.util.HashSet;
+import java.util.List;
 import java.util.Set;
 
 import org.junit.Assert;
@@ -70,6 +71,12 @@ public class TestKeywordDao {
         Set<Keyword> keywords = target.getKeywords(standard, true);
         Assert.assertEquals(new HashSet<Keyword>(
             Arrays.asList(new Keyword[] { keyword1, keyword2 })), keywords);
+        
+        KeywordDao.Params params = new KeywordDao.Params();
+        params.setType(standard);
+        
+        List<Keyword> keywordList = target.getKeywordList(params);
+        Assert.assertEquals(Arrays.asList(new Keyword[]{keyword1, keyword2}), keywordList);
     }
 
     @Test

From f547468a501eae756f15d7cde2227502891e4d4e Mon Sep 17 00:00:00 2001
From: Tom Vahlman <tom@dsv.su.se>
Date: Mon, 27 Feb 2012 16:32:01 +0100
Subject: [PATCH 5/7] Added a test with three project ideas which where matched
 against three supervisors. There is a need for more extensive tests for
 covering all cases.

---
 .../match/TestGreedyMatchingAlgorithm.java    | 249 ++++++++++++++----
 1 file changed, 197 insertions(+), 52 deletions(-)

diff --git a/src/test/java/se/su/dsv/scipro/match/TestGreedyMatchingAlgorithm.java b/src/test/java/se/su/dsv/scipro/match/TestGreedyMatchingAlgorithm.java
index 541f700bc2..998d5fd839 100644
--- a/src/test/java/se/su/dsv/scipro/match/TestGreedyMatchingAlgorithm.java
+++ b/src/test/java/se/su/dsv/scipro/match/TestGreedyMatchingAlgorithm.java
@@ -71,8 +71,9 @@ public class TestGreedyMatchingAlgorithm {
     private Set<Language> languages;
     private KeywordType keywordTypeArea;
     private KeywordType keywordTypeWord;
+    private ApplicationPeriod applicationPeriod;
 
-    private Employee createSupervisor(final String firstName, final String lastName, Set<Language> languages1) {
+    private Employee createEmployee(final String firstName, final String lastName, Set<Language> languages1) {
         Employee employee = new Employee();
         User user = new User();
         user.setFirstName(firstName);
@@ -109,17 +110,30 @@ public class TestGreedyMatchingAlgorithm {
         keywordTypeWord = keywordTypeDao.save(new KeywordType("Word"));
     }
 
-    private void addKeyWords(final Employee supervisor, final ProjectIdea projectIdea, final Keyword keyword) {
-        supervisor.getKeywords().getAll().add(keyword);
-        projectIdea.getKeywords().getAll().add(keyword);
+    private void addKeyWords(List<Employee> supervisorList, List<ProjectIdea> projectIdeaList, final Keyword keyword) {
+        if(supervisorList != null && !supervisorList.isEmpty()) {
+            for(int i = 0; i < supervisorList.size(); i++) {
+                supervisorList.get(i).getKeywords().getAll().add(keyword);
+            }
+        }
+        if(projectIdeaList != null && !projectIdeaList.isEmpty()) {
+            for(int i = 0; i < projectIdeaList.size(); i++) {
+                projectIdeaList.get(i).getKeywords().getAll().add(keyword); 
+            }
+        }
     }
 
     private Keyword createKeyword(final KeywordType keyWordType , final String keyWordName, final boolean deleted) {
-        Keyword keyword = new Keyword();
-        keyword.setType(keyWordType);
-        keyword.setKeyword(keyWordName);
-        keyword.setDeleted(deleted);
-        return keywordDao.save(keyword);
+        Keyword keyword = keywordDao.getKeywordByNameAndType(keyWordName, keyWordType);
+        if(keyword == null)  {
+            keyword = new Keyword();
+            keyword.setType(keyWordType);
+            keyword.setKeyword(keyWordName);
+            keyword.setDeleted(deleted);
+            return keywordDao.save(keyword);
+        } else {
+            return keyword;
+        }
     }
 
     @Before
@@ -131,17 +145,17 @@ public class TestGreedyMatchingAlgorithm {
         languages = new HashSet<Language>();
         languages.add(languageDao.save(new Language("Swedish")));
         languages.add(languageDao.save(new Language("English")));
-        bachelorSupervisor = createSupervisor("Henrik", "Hansson", languages);
+        bachelorSupervisor = createEmployee("Henrik", "Hansson", languages);
 		bachelorProjectClass = createProjectClass(ProjectClass.BACHELOR, "Bachelor", "Bachelor project class");
         Set<ProjectClass> projectClassSet = new HashSet<ProjectClass>();
         projectClassSet.add(bachelorProjectClass);
         projectClassSet.add(masterProjectClass);
         List<ApplicationPeriod> myList = new ArrayList<ApplicationPeriod>();
         myList.addAll(applicationPeriodDao.findAll());
-        ApplicationPeriod applicationPeriod = applicationPeriodFacade.createApplicationPeriod(projectClassSet, "name1");
+        applicationPeriod = applicationPeriodFacade.createApplicationPeriod(projectClassSet, "name1");
         
         bachelorProjectIdea = createProjectIdea(bachelorProjectClass, applicationPeriod);
-        masterSupervisor = createSupervisor("Birger", "Andersson", languages);
+        masterSupervisor = createEmployee("Birger", "Andersson", languages);
         masterProjectClass = createProjectClass(ProjectClass.MASTER, "Master", "Master project class");
         masterProjectIdea = createProjectIdea(masterProjectClass, applicationPeriod);
 	}
@@ -239,10 +253,14 @@ public class TestGreedyMatchingAlgorithm {
     @Rollback
     /* a bachelor supervisor can handle a projectIdea which has been rejected by another (bachelor) supervisor, even if the other supervisor has a higher score */
     public void testRejectByOtherSupervisor()  {
-        Employee bachelorSupervisor2 = createSupervisor("David", "Hallberg", languages);
+        Employee bachelorSupervisor2 = createEmployee("David", "Hallberg", languages);
         supervisorAvailability.add(new Availability(bachelorSupervisor, 0L, 1, bachelorProjectClass));
         supervisorAvailability.add(new Availability(bachelorSupervisor2, 0L, 1, bachelorProjectClass));
-        addKeyWords(bachelorSupervisor2, bachelorProjectIdea, createKeyword(keywordTypeWord, "test unit", false));   // 3
+        List<ProjectIdea> projectIdeaList = new ArrayList<ProjectIdea>();
+        projectIdeaList.add(bachelorProjectIdea);
+        List<Employee> supervisorList = new ArrayList<Employee>();
+        supervisorList.add(bachelorSupervisor2);
+        addKeyWords(supervisorList, projectIdeaList, createKeyword(keywordTypeWord, "test unit", false));   // 3
         addRejectedMatch(bachelorSupervisor2, bachelorProjectIdea);
         unmatchedProjectIdeas.add(bachelorProjectIdea);
         Result result = new GreedyMatchingAlgorithm().match(supervisorAvailability, unmatchedProjectIdeas, weights);
@@ -256,7 +274,7 @@ public class TestGreedyMatchingAlgorithm {
     @Rollback
     /* a preferred bachelor supervisor should be chosen prior to another bachelor supervisor */
 	public void testPreferredSupervisor() {
-		Employee bachelorSupervisor2 = createSupervisor("David", "Hallberg", languages);
+		Employee bachelorSupervisor2 = createEmployee("David", "Hallberg", languages);
         supervisorAvailability.add(new Availability(bachelorSupervisor2, 0L, 1, bachelorProjectClass));
         supervisorAvailability.add(new Availability(bachelorSupervisor, 0L, 1, bachelorProjectClass));
 		bachelorProjectIdea.setPreferredSupervisor(bachelorSupervisor2);
@@ -274,7 +292,7 @@ public class TestGreedyMatchingAlgorithm {
     @Rollback
     /* a preferred "bachelor" supervisor should NOT handle a master projectIdea */
     public void testIncorrectProjectClass() {
-        Employee bachelorSupervisor2 = createSupervisor("David", "Hallberg", languages);
+        Employee bachelorSupervisor2 = createEmployee("David", "Hallberg", languages);
         supervisorAvailability.add(new Availability(bachelorSupervisor2, 0L, 1, bachelorProjectClass));
         supervisorAvailability.add(new Availability(masterSupervisor, 0L, 1, masterProjectClass));
         masterProjectIdea.setPreferredSupervisor(bachelorSupervisor2);
@@ -291,10 +309,14 @@ public class TestGreedyMatchingAlgorithm {
     @Rollback
     /* keywords of 16 points should supersede a preferred supervisor of 15 points */
     public void testHighestScore() {
-        Employee bachelorSupervisor2 = createSupervisor("David", "Hallberg", languages);
-        addKeyWords(bachelorSupervisor2, bachelorProjectIdea, createKeyword(keywordTypeArea, "test area", false));   // 10
-        addKeyWords(bachelorSupervisor2, bachelorProjectIdea, createKeyword(keywordTypeWord, "test unit", false));   // 3
-        addKeyWords(bachelorSupervisor2, bachelorProjectIdea, createKeyword(keywordTypeWord, "Java", false));        // 3
+        Employee bachelorSupervisor2 = createEmployee("David", "Hallberg", languages);
+        List<ProjectIdea> projectIdeaList = new ArrayList<ProjectIdea>();
+        projectIdeaList.add(bachelorProjectIdea);
+        List<Employee> supervisorList = new ArrayList<Employee>();
+        supervisorList.add(bachelorSupervisor2);
+        addKeyWords(supervisorList, projectIdeaList, createKeyword(keywordTypeArea, "test area", false));   // 10
+        addKeyWords(supervisorList, projectIdeaList, createKeyword(keywordTypeWord, "test unit", false));   // 3
+        addKeyWords(supervisorList, projectIdeaList, createKeyword(keywordTypeWord, "Java", false));        // 3
         supervisorAvailability.add(new Availability(bachelorSupervisor2, 0L, 1, bachelorProjectClass));
         supervisorAvailability.add(new Availability(bachelorSupervisor, 0L, 1, bachelorProjectClass));
         bachelorProjectIdea.setPreferredSupervisor(bachelorSupervisor);                                      // 15
@@ -311,10 +333,16 @@ public class TestGreedyMatchingAlgorithm {
     @Rollback
     /*  keywords of 6 points should supersede keywords of 3 points */
     public void testHighestScore_v2() {
-        Employee bachelorSupervisor2 = createSupervisor("David", "Hallberg", languages);
-        addKeyWords(bachelorSupervisor, bachelorProjectIdea, createKeyword(keywordTypeWord, "test unit", false));   // 3
-        addKeyWords(bachelorSupervisor2, bachelorProjectIdea, createKeyword(keywordTypeWord, "UML", false));         // 3
-        addKeyWords(bachelorSupervisor2, bachelorProjectIdea, createKeyword(keywordTypeWord, "Design", false));      // 3
+        Employee bachelorSupervisor2 = createEmployee("David", "Hallberg", languages);
+        List<ProjectIdea> projectIdeaList = new ArrayList<ProjectIdea>();
+        projectIdeaList.add(bachelorProjectIdea);
+        List<Employee> supervisorList = new ArrayList<Employee>();
+        supervisorList.add(bachelorSupervisor);
+        addKeyWords(supervisorList, projectIdeaList, createKeyword(keywordTypeWord, "test unit", false));   // 3
+        supervisorList.clear();
+        supervisorList.add(bachelorSupervisor2);
+        addKeyWords(supervisorList, projectIdeaList, createKeyword(keywordTypeWord, "UML", false));         // 3
+        addKeyWords(supervisorList, projectIdeaList, createKeyword(keywordTypeWord, "Design", false));      // 3
         supervisorAvailability.add(new Availability(bachelorSupervisor2, 0L, 1, bachelorProjectClass));
         supervisorAvailability.add(new Availability(bachelorSupervisor, 0L, 1, bachelorProjectClass));
         unmatchedProjectIdeas.add(bachelorProjectIdea);
@@ -330,10 +358,16 @@ public class TestGreedyMatchingAlgorithm {
     @Rollback
     /*  deleted keywords of 6 points should NOT supersede valid keywords of 3 points */
     public void testHighestScore_v3() {
-        Employee bachelorSupervisor2 = createSupervisor("David", "Hallberg", languages);
-        addKeyWords(bachelorSupervisor, bachelorProjectIdea, createKeyword(keywordTypeWord, "test unit", false));   // 3
-        addKeyWords(bachelorSupervisor2, bachelorProjectIdea, createKeyword(keywordTypeWord, "UML", true));         // 3
-        addKeyWords(bachelorSupervisor2, bachelorProjectIdea, createKeyword(keywordTypeWord, "Design", true));      // 3
+        Employee bachelorSupervisor2 = createEmployee("David", "Hallberg", languages);
+        List<ProjectIdea> projectIdeaList = new ArrayList<ProjectIdea>();
+        projectIdeaList.add(bachelorProjectIdea);
+        List<Employee> supervisorList = new ArrayList<Employee>();
+        supervisorList.add(bachelorSupervisor);
+        addKeyWords(supervisorList, projectIdeaList, createKeyword(keywordTypeWord, "test unit", false));   // 3
+        supervisorList.clear();
+        supervisorList.add(bachelorSupervisor2);
+        addKeyWords(supervisorList, projectIdeaList, createKeyword(keywordTypeWord, "UML", true));         // 3
+        addKeyWords(supervisorList, projectIdeaList, createKeyword(keywordTypeWord, "Design", true));      // 3
         supervisorAvailability.add(new Availability(bachelorSupervisor2, 0L, 1, bachelorProjectClass));
         supervisorAvailability.add(new Availability(bachelorSupervisor, 0L, 1, bachelorProjectClass));
         unmatchedProjectIdeas.add(bachelorProjectIdea);
@@ -352,18 +386,23 @@ public class TestGreedyMatchingAlgorithm {
         Set<Language> languageSet = new HashSet<Language>();
         Language language_sv = languageDao.save(new Language("Swedish"));
         languageSet.add(language_sv);
-        Employee bachelorSupervisor_sv = createSupervisor("David", "Hallberg", languageSet);
+        Employee bachelorSupervisor_sv = createEmployee("David", "Hallberg", languageSet);
 
         bachelorSupervisor.getCapabilities().getLanguages().clear();
         bachelorSupervisor.getCapabilities().getLanguages().add(languageDao.save(new Language("English")));
         bachelorProjectIdea.getLanguages().clear();
         bachelorProjectIdea.getLanguages().add(language_sv);
         bachelorProjectIdea.setPreferredSupervisor(bachelorSupervisor);                         // 15
-
-        addKeyWords(bachelorSupervisor, bachelorProjectIdea, createKeyword(keywordTypeWord, "C++", false));      // 3
-        addKeyWords(bachelorSupervisor, bachelorProjectIdea, createKeyword(keywordTypeWord, "Java", false));     // 3
-        addKeyWords(bachelorSupervisor, bachelorProjectIdea, createKeyword(keywordTypeWord, "Design", false));   // 3
-        addKeyWords(bachelorSupervisor_sv, bachelorProjectIdea, createKeyword(keywordTypeWord, "UML", false));   // 3
+        List<ProjectIdea> projectIdeaList = new ArrayList<ProjectIdea>();
+        projectIdeaList.add(bachelorProjectIdea);
+        List<Employee> supervisorList = new ArrayList<Employee>();
+        supervisorList.add(bachelorSupervisor);
+        addKeyWords(supervisorList, projectIdeaList, createKeyword(keywordTypeWord, "C++", false));      // 3
+        addKeyWords(supervisorList, projectIdeaList, createKeyword(keywordTypeWord, "Java", false));     // 3
+        addKeyWords(supervisorList, projectIdeaList, createKeyword(keywordTypeWord, "Design", false));   // 3
+        supervisorList.clear();
+        supervisorList.add(bachelorSupervisor_sv);
+        addKeyWords(supervisorList, projectIdeaList, createKeyword(keywordTypeWord, "UML", false));   // 3
         supervisorAvailability.add(new Availability(bachelorSupervisor_sv, 0L, 1, bachelorProjectClass));
         supervisorAvailability.add(new Availability(bachelorSupervisor, 0L, 1, bachelorProjectClass));
         unmatchedProjectIdeas.add(bachelorProjectIdea);
@@ -379,10 +418,14 @@ public class TestGreedyMatchingAlgorithm {
     @Rollback
     /*  a supervisor should not be chosen if he/she is "deleted"  */
     public void testForDeletedSupervisor() {
-        Employee bachelorSupervisor2 = createSupervisor("David", "Hallberg", languages);
+        Employee bachelorSupervisor2 = createEmployee("David", "Hallberg", languages);
         bachelorSupervisor2.setDeleted(true);
 
-        addKeyWords(bachelorSupervisor2, bachelorProjectIdea, createKeyword(keywordTypeWord, "UML", false));         // 3
+        List<ProjectIdea> projectIdeaList = new ArrayList<ProjectIdea>();
+        projectIdeaList.add(bachelorProjectIdea);
+        List<Employee> supervisorList = new ArrayList<Employee>();
+        supervisorList.add(bachelorSupervisor2);
+        addKeyWords(supervisorList, projectIdeaList, createKeyword(keywordTypeWord, "UML", false));         // 3
         supervisorAvailability.add(new Availability(bachelorSupervisor2, 0L, 1, bachelorProjectClass));
         supervisorAvailability.add(new Availability(bachelorSupervisor, 0L, 1, bachelorProjectClass));
         unmatchedProjectIdeas.add(bachelorProjectIdea);
@@ -399,13 +442,16 @@ public class TestGreedyMatchingAlgorithm {
     @Rollback
     /*  a supervisor cannot be supervisor to herself  */
     public void testSupervisorCannotSuperviseHerself() {
-        Employee bachelorSupervisor2 = createSupervisor("David", "Hallberg", languages);
+        Employee bachelorSupervisor2 = createEmployee("David", "Hallberg", languages);
         Role role = new Student();
         role.setUser(bachelorSupervisor2.getUser());
         role = roleDao.save(role);
         bachelorProjectIdea.getAuthors().add((Student) role);
-
-        addKeyWords(bachelorSupervisor2, bachelorProjectIdea, createKeyword(keywordTypeWord, "UML", false));         // 3
+        List<ProjectIdea> projectIdeaList = new ArrayList<ProjectIdea>();
+        projectIdeaList.add(bachelorProjectIdea);
+        List<Employee> supervisorList = new ArrayList<Employee>();
+        supervisorList.add(bachelorSupervisor2);
+        addKeyWords(supervisorList, projectIdeaList, createKeyword(keywordTypeWord, "UML", false));         // 3
         supervisorAvailability.add(new Availability(bachelorSupervisor2, 0L, 1, bachelorProjectClass));
         supervisorAvailability.add(new Availability(bachelorSupervisor, 0L, 1, bachelorProjectClass));
         unmatchedProjectIdeas.add(bachelorProjectIdea);
@@ -422,8 +468,12 @@ public class TestGreedyMatchingAlgorithm {
     @Rollback
     /*  the supervisor with no available "slots" should NOT be chosen even when this supervisor has the highest score */
     public void testNoAvailableSlots() {
-        Employee bachelorSupervisor2 = createSupervisor("David", "Hallberg", languages);
-        addKeyWords(bachelorSupervisor, bachelorProjectIdea, createKeyword(keywordTypeWord, "Design", false));   // 3
+        Employee bachelorSupervisor2 = createEmployee("David", "Hallberg", languages);
+        List<ProjectIdea> projectIdeaList = new ArrayList<ProjectIdea>();
+        projectIdeaList.add(bachelorProjectIdea);
+        List<Employee> supervisorList = new ArrayList<Employee>();
+        supervisorList.add(bachelorSupervisor);
+        addKeyWords(supervisorList, projectIdeaList, createKeyword(keywordTypeWord, "Design", false));   // 3
         supervisorAvailability.add(new Availability(bachelorSupervisor2, 0L, 1, bachelorProjectClass));
         supervisorAvailability.add(new Availability(bachelorSupervisor, 1L, 1, bachelorProjectClass));    // availability = numCapable - numMatched
         unmatchedProjectIdeas.add(bachelorProjectIdea);
@@ -441,9 +491,12 @@ public class TestGreedyMatchingAlgorithm {
     @Rollback
     /*  a supervisor with the highest available slot should NOT be chosen when this supervisor has less score */
     public void testHighestAvailableSlot() {
-        Employee bachelorSupervisor2 = createSupervisor("David", "Hallberg", languages);
-
-        addKeyWords(bachelorSupervisor, bachelorProjectIdea, createKeyword(keywordTypeWord, "UML", false));         // 3
+        Employee bachelorSupervisor2 = createEmployee("David", "Hallberg", languages);
+        List<ProjectIdea> projectIdeaList = new ArrayList<ProjectIdea>();
+        projectIdeaList.add(bachelorProjectIdea);
+        List<Employee> supervisorList = new ArrayList<Employee>();
+        supervisorList.add(bachelorSupervisor);
+        addKeyWords(supervisorList, projectIdeaList, createKeyword(keywordTypeWord, "UML", false));         // 3
         supervisorAvailability.add(new Availability(bachelorSupervisor2, 0L, 4, bachelorProjectClass));
         supervisorAvailability.add(new Availability(bachelorSupervisor, 0L, 1, bachelorProjectClass));
         unmatchedProjectIdeas.add(bachelorProjectIdea);
@@ -460,7 +513,7 @@ public class TestGreedyMatchingAlgorithm {
     @Rollback
     /*  test that the number Availability#numMatched has increased with one and that the supervisor with highest available slots are chosen  */
     public void testNumMatchedHasIncreased() {
-        Employee bachelorSupervisor2 = createSupervisor("David", "Hallberg", languages);
+        Employee bachelorSupervisor2 = createEmployee("David", "Hallberg", languages);
         supervisorAvailability.add(new Availability(bachelorSupervisor2, 0L, 4, bachelorProjectClass));
         supervisorAvailability.add(new Availability(bachelorSupervisor, 0L, 1, bachelorProjectClass));
         unmatchedProjectIdeas.add(bachelorProjectIdea);
@@ -497,10 +550,14 @@ public class TestGreedyMatchingAlgorithm {
     @Rollback
     /*  neither a bachelor or a master supervisor are preferred to handle a bachelor idea when compatibility, keywords, scores etc are equal   */
     public void testBachelorOrMaster() {
-        Employee bachelorSupervisor2 = createSupervisor("David", "Hallberg", languages);
+        Employee bachelorSupervisor2 = createEmployee("David", "Hallberg", languages);
         supervisorAvailability.add(new Availability(masterSupervisor, 0L, 1, bachelorProjectClass));
         supervisorAvailability.add(new Availability(bachelorSupervisor2, 0L, 1, bachelorProjectClass));
-        addKeyWords(bachelorSupervisor2, bachelorProjectIdea, createKeyword(keywordTypeWord, "Design", false));
+        List<ProjectIdea> projectIdeaList = new ArrayList<ProjectIdea>();
+        projectIdeaList.add(bachelorProjectIdea);
+        List<Employee> supervisorList = new ArrayList<Employee>();
+        supervisorList.add(bachelorSupervisor2);
+        addKeyWords(supervisorList, projectIdeaList, createKeyword(keywordTypeWord, "Design", false));
         unmatchedProjectIdeas.add(bachelorProjectIdea);
         Result result = new GreedyMatchingAlgorithm().match(supervisorAvailability, unmatchedProjectIdeas, weights);
         assertTrue(result.matches.size() > 0);
@@ -514,7 +571,7 @@ public class TestGreedyMatchingAlgorithm {
     @Rollback
     /*  test that a master which has filled up his slot for bachelor but has slots left for master can supervise a bachelor idea */
     public void testSlotForMasterSupervisor() {
-//Employee bachelorSupervisor2 = createSupervisor("David", "Hallberg", languages);
+//Employee bachelorSupervisor2 = createEmployee("David", "Hallberg", languages);
         supervisorAvailability.add(new Availability(masterSupervisor, 3L, 3, bachelorProjectClass));
         supervisorAvailability.add(new Availability(masterSupervisor, 3L, 4, bachelorProjectClass));
 //supervisorAvailability.add(new Availability(bachelorSupervisor2, 0L, 1, bachelorProjectClass));
@@ -531,7 +588,7 @@ public class TestGreedyMatchingAlgorithm {
     @Rollback
     /*  test that a master which has filled up his slot for bachelor but has slots left for master can supervise a bachelor idea */
     public void testIncreaseSlotForMasterSupervisor() {
-        Employee bachelorSupervisor2 = createSupervisor("David", "Hallberg", languages);
+        Employee bachelorSupervisor2 = createEmployee("David", "Hallberg", languages);
         supervisorAvailability.add(new Availability(masterSupervisor, 3L, 3, bachelorProjectClass));
         supervisorAvailability.add(new Availability(masterSupervisor, 3L, 4, masterProjectClass));
         supervisorAvailability.add(new Availability(bachelorSupervisor2, 0L, 1, bachelorProjectClass));
@@ -561,7 +618,10 @@ public class TestGreedyMatchingAlgorithm {
     @Rollback
     /*  test that a master which has filled up his slot for bachelor but has slots left for master can supervise a bachelor idea */
     public void testIncreaseSlotForMasterSupervisor_v2() {
-        Employee bachelorSupervisor2 = createSupervisor("David", "Hallberg", languages);
+    /*
+        supervisorAvailability.clear();
+        unmatchedProjectIdeas.clear();
+        Employee bachelorSupervisor2 = createEmployee("David", "Hallberg", languages);
         supervisorAvailability.add(new Availability(masterSupervisor, 3L, 3, bachelorProjectClass));
         supervisorAvailability.add(new Availability(masterSupervisor, 3L, 4, masterProjectClass));
         supervisorAvailability.add(new Availability(bachelorSupervisor2, 0L, 1, bachelorProjectClass));
@@ -569,7 +629,11 @@ public class TestGreedyMatchingAlgorithm {
         unmatchedProjectIdeas.add(masterProjectIdea);
         bachelorProjectIdea.setPreferredSupervisor(masterSupervisor);
         masterProjectIdea.setPreferredSupervisor(masterSupervisor);
-        addKeyWords(masterSupervisor, masterProjectIdea, createKeyword(keywordTypeWord, "UML", false));
+        List<ProjectIdea> projectIdeaList = new ArrayList<ProjectIdea>();
+        projectIdeaList.add(bachelorProjectIdea);
+        List<Employee> supervisorList = new ArrayList<Employee>();
+        supervisorList.add(masterSupervisor);
+        addKeyWords(supervisorList, projectIdeaList, createKeyword(keywordTypeWord, "UML", false));
         Result result = new GreedyMatchingAlgorithm().match(supervisorAvailability, unmatchedProjectIdeas, weights);
         assertTrue(result.matches.size() > 0);            
         boolean foundMasterProjIdea = false;
@@ -593,7 +657,88 @@ public class TestGreedyMatchingAlgorithm {
         assertTrue(foundBachelorProjIdea);
         assertTrue(foundBachelorSuperVisor);
         assertTrue(foundMasterSuperVisor);
-        assertTrue(result.unmatched.size() == 0);
+        assertTrue(result.unmatched.size() == 0);   */
     }
 
+    @Test
+    @Transactional
+    @Rollback
+    /*  three supervisors which are matched against three project ideas  */
+    public void testIncreaseSlotForMasterSupervisor_v3() {
+        List<ProjectIdea> projectIdeaList = new ArrayList<ProjectIdea>();
+        List<Employee> supervisorList = new ArrayList<Employee>();
+
+        Employee davidH = createEmployee("David", "Hallberg", languages);
+        supervisorAvailability.clear();
+        supervisorAvailability.add(new Availability(davidH, 0L, 5, bachelorProjectClass));
+        supervisorAvailability.add(new Availability(davidH, 0L, 5, masterProjectClass));
+
+        supervisorList.clear();
+        supervisorList.add(davidH);
+        addKeyWords(supervisorList, null, createKeyword(keywordTypeArea, "IT för lärande", false));
+        addKeyWords(supervisorList, null, createKeyword(keywordTypeWord, "Business process management (BPM)", false));
+        addKeyWords(supervisorList, null, createKeyword(keywordTypeWord, "Flexibelt lärande", false));
+
+        Employee henrikH = createEmployee("Henrik", "Hansson", languages);
+        supervisorAvailability.add(new Availability(henrikH, 0L, 5, bachelorProjectClass));
+        supervisorAvailability.add(new Availability(henrikH, 0L, 5, masterProjectClass));
+
+        supervisorList.clear();
+        supervisorList.add(henrikH);
+        addKeyWords(supervisorList, null, createKeyword(keywordTypeArea, "Technology Enhanced Learning", false));
+        addKeyWords(supervisorList, null, createKeyword(keywordTypeArea, "ICT for Development", false));
+        addKeyWords(supervisorList, null, createKeyword(keywordTypeWord, "Flexibelt lärande", false));
+
+        Employee henrikBergstr = createEmployee("Henrik", "Bergström", languages);        // login henrikbe
+        supervisorAvailability.add(new Availability(henrikBergstr, 0L, 5, bachelorProjectClass));
+        supervisorAvailability.add(new Availability(henrikBergstr, 0L, 5, masterProjectClass));
+
+        supervisorList.clear();
+        supervisorList.add(henrikBergstr);
+        addKeyWords(supervisorList, null, createKeyword(keywordTypeWord, "ACT Agera i kommunikation med teknik", false));
+        addKeyWords(supervisorList, null, createKeyword(keywordTypeWord, "System development", false));
+        addKeyWords(supervisorList, null, createKeyword(keywordTypeWord, "IT-architectures", false));
+
+        ProjectIdea firstBachelorIdea = createProjectIdea(bachelorProjectClass, applicationPeriod);
+        projectIdeaList.clear();
+        projectIdeaList.add(firstBachelorIdea); // no preferred supervisor for this project idea
+        addKeyWords(null, projectIdeaList, createKeyword(keywordTypeArea, "ICT for Development", false));
+        addKeyWords(null, projectIdeaList, createKeyword(keywordTypeWord, "System development", false));
+        addKeyWords(null, projectIdeaList, createKeyword(keywordTypeWord, "Enterprise 2.0", false));
+
+        ProjectIdea masterIdea = createProjectIdea(masterProjectClass, applicationPeriod);
+        projectIdeaList.clear();
+        projectIdeaList.add(masterIdea); // no preferred supervisor for this project idea
+        addKeyWords(null, projectIdeaList, createKeyword(keywordTypeArea, "Interaction design", false));
+        addKeyWords(null, projectIdeaList, createKeyword(keywordTypeArea, "ICT for Development", false));
+        addKeyWords(null, projectIdeaList, createKeyword(keywordTypeArea, "Digital Systems Security", false));
+        addKeyWords(null, projectIdeaList, createKeyword(keywordTypeWord, "System development", false));
+        addKeyWords(null, projectIdeaList, createKeyword(keywordTypeWord, "Information system theory", false));
+
+        ProjectIdea secondBachelorIdea = createProjectIdea(bachelorProjectClass, applicationPeriod);
+        projectIdeaList.clear();
+        projectIdeaList.add(secondBachelorIdea); // David Hallberg is preferred supervisor for this project idea
+        secondBachelorIdea.setPreferredSupervisor(davidH);
+        addKeyWords(null, projectIdeaList, createKeyword(keywordTypeArea, "E-government and E-democracy", false));
+
+        unmatchedProjectIdeas.clear();
+        unmatchedProjectIdeas.add(firstBachelorIdea);
+        unmatchedProjectIdeas.add(secondBachelorIdea);
+        unmatchedProjectIdeas.add(masterIdea);
+
+        Result result = new GreedyMatchingAlgorithm().match(supervisorAvailability, unmatchedProjectIdeas, weights);
+        assertTrue(result.matches.size() == 3);
+
+        assertTrue(result.matches.get(0).getPoints() == 10);
+        assertTrue(result.matches.get(1).getPoints() == 5);
+        assertTrue(result.matches.get(2).getPoints() == 5);
+
+        assertTrue(result.matches.get(0).getSupervisor().equals(davidH));
+        assertTrue(result.matches.get(1).getSupervisor().equals(henrikH));
+        assertTrue(result.matches.get(2).getSupervisor().equals(henrikH));
+
+        assertTrue(result.matches.get(0).getProjectIdea().equals(secondBachelorIdea));
+        assertTrue(result.matches.get(1).getProjectIdea().equals(firstBachelorIdea));
+        assertTrue(result.matches.get(2).getProjectIdea().equals(masterIdea));
+    }
 }

From 604a38152c3e5739d4d3f73eb4ab9808ebf0d312 Mon Sep 17 00:00:00 2001
From: Tom Vahlman <tom@dsv.su.se>
Date: Mon, 27 Feb 2012 21:33:06 +0100
Subject: [PATCH 6/7] We must sort on the highest (individual availability)
 when the project classes are the same.

---
 .../scipro/match/GreedyMatchingAlgorithm.java |  4 +-
 .../scipro/match/dataobject/Availability.java | 13 ++-
 .../match/TestGreedyMatchingAlgorithm.java    | 89 +++++++------------
 3 files changed, 45 insertions(+), 61 deletions(-)

diff --git a/src/main/java/se/su/dsv/scipro/match/GreedyMatchingAlgorithm.java b/src/main/java/se/su/dsv/scipro/match/GreedyMatchingAlgorithm.java
index 9ffe337766..1a7a45b8f2 100644
--- a/src/main/java/se/su/dsv/scipro/match/GreedyMatchingAlgorithm.java
+++ b/src/main/java/se/su/dsv/scipro/match/GreedyMatchingAlgorithm.java
@@ -280,8 +280,8 @@ public class GreedyMatchingAlgorithm implements MatchingAlgorithm {
                     } else  if(!match.getProjectIdea().getProjectClass().equals(availability.getProjectClass()) &&
                             otherPair.getMatch().getProjectIdea().getProjectClass().equals(otherPair.getAvailability().getProjectClass())) {
                         return 1;
-                    } else {   // the supervisor can only one type of project class
-                        return 0;
+                    } else {   // the project class is the same sort on the highest availability
+                        return availability.compareTo(otherPair.getAvailability());
                     }
                 }
             }
diff --git a/src/main/java/se/su/dsv/scipro/match/dataobject/Availability.java b/src/main/java/se/su/dsv/scipro/match/dataobject/Availability.java
index ac83863365..3f06503a3f 100644
--- a/src/main/java/se/su/dsv/scipro/match/dataobject/Availability.java
+++ b/src/main/java/se/su/dsv/scipro/match/dataobject/Availability.java
@@ -8,7 +8,7 @@ import se.su.dsv.scipro.data.dataobjects.ProjectClass;
 /**
  * A class that specifies how available a supervisor is(in terms of thesis supervision)
  */
-public class Availability implements Serializable {
+public class Availability implements Serializable, Comparable<Availability> {
 
 	private static final long serialVersionUID = 1L;
 	
@@ -54,6 +54,17 @@ public class Availability implements Serializable {
     	numMatched = num;
     }
     
+    @Override
+    public int compareTo(Availability availability) {
+        if(getAvailability() > availability.getAvailability()) {
+            return -1;
+        } else if(availability.getAvailability() > getAvailability()) {
+            return 1;
+        } else {
+            return 0;
+        }
+    }
+    
     @Override
     public String toString() {
         return "Availability [supervisorId=" + supervisor + ", numMatched="
diff --git a/src/test/java/se/su/dsv/scipro/match/TestGreedyMatchingAlgorithm.java b/src/test/java/se/su/dsv/scipro/match/TestGreedyMatchingAlgorithm.java
index 998d5fd839..9e66082e26 100644
--- a/src/test/java/se/su/dsv/scipro/match/TestGreedyMatchingAlgorithm.java
+++ b/src/test/java/se/su/dsv/scipro/match/TestGreedyMatchingAlgorithm.java
@@ -578,6 +578,7 @@ public class TestGreedyMatchingAlgorithm {
         unmatchedProjectIdeas.add(bachelorProjectIdea);
         Result result = new GreedyMatchingAlgorithm().match(supervisorAvailability, unmatchedProjectIdeas, weights);
         assertTrue(result.matches.size() > 0);
+
         assertTrue(result.matches.get(0).getProjectIdea().equals(bachelorProjectIdea));
         assertTrue(result.matches.get(0).getSupervisor().equals(masterSupervisor));
         assertTrue(result.unmatched.size() == 0);
@@ -586,78 +587,50 @@ public class TestGreedyMatchingAlgorithm {
     @Test
     @Transactional
     @Rollback
-    /*  test that a master which has filled up his slot for bachelor but has slots left for master can supervise a bachelor idea */
+    /*  test that the supervisor who has the highest total slot available will be chosen */
     public void testIncreaseSlotForMasterSupervisor() {
-        Employee bachelorSupervisor2 = createEmployee("David", "Hallberg", languages);
-        supervisorAvailability.add(new Availability(masterSupervisor, 3L, 3, bachelorProjectClass));
-        supervisorAvailability.add(new Availability(masterSupervisor, 3L, 4, masterProjectClass));
-        supervisorAvailability.add(new Availability(bachelorSupervisor2, 0L, 1, bachelorProjectClass));
-        unmatchedProjectIdeas.add(bachelorProjectIdea);
-        bachelorProjectIdea.setPreferredSupervisor(masterSupervisor);
-        Result result = new GreedyMatchingAlgorithm().match(supervisorAvailability, unmatchedProjectIdeas, weights);
-        assertTrue(result.matches.size() > 0);
-        assertTrue(result.matches.get(0).getProjectIdea().equals(bachelorProjectIdea));
-        assertTrue(result.matches.get(0).getSupervisor().equals(masterSupervisor));
-        assertTrue(result.unmatched.size() == 0);
-// increase num capable for the supervisor
+        Employee davidH = createEmployee("David", "Hallberg", languages);
+        Employee henrikH = createEmployee("Henrik", "Hansson", languages);
+//ProjectIdea firstBachelorIdea = createProjectIdea(bachelorProjectClass, applicationPeriod);
+        supervisorAvailability.add(new Availability(henrikH, 2L, 3, bachelorProjectClass)); // total slot = 2
+        supervisorAvailability.add(new Availability(henrikH, 3L, 4, masterProjectClass));
+        supervisorAvailability.add(new Availability(davidH, 1L, 1, bachelorProjectClass));          // total slot = 1
+        supervisorAvailability.add(new Availability(davidH, 0L, 1, masterProjectClass));
         unmatchedProjectIdeas.add(masterProjectIdea);
-        for (Availability availability : supervisorAvailability) {
-            if(availability.getProjectClass().equals(masterProjectClass)) {
-                availability.setNumCapable(availability.getNumCapable() + 1);
-            }
-        }
-        result = new GreedyMatchingAlgorithm().match(supervisorAvailability, unmatchedProjectIdeas, weights);
+        unmatchedProjectIdeas.add(bachelorProjectIdea);
+
+        Result result = new GreedyMatchingAlgorithm().match(supervisorAvailability, unmatchedProjectIdeas, weights);
         assertTrue(result.matches.size() > 0);
         assertTrue(result.matches.get(0).getProjectIdea().equals(masterProjectIdea));
-        assertTrue(result.matches.get(0).getSupervisor().equals(masterSupervisor));
+        assertTrue(result.matches.get(0).getSupervisor().equals(henrikH));
+        assertTrue(result.matches.get(1).getProjectIdea().equals(bachelorProjectIdea));
+        assertTrue(result.matches.get(1).getSupervisor().equals(henrikH));
         assertTrue(result.unmatched.size() == 0);
     }
 
     @Test
     @Transactional
     @Rollback
-    /*  test that a master which has filled up his slot for bachelor but has slots left for master can supervise a bachelor idea */
+    /*  test that a master supervisor is chosen for a master project idea which has the same points as a bachelor project idea */
     public void testIncreaseSlotForMasterSupervisor_v2() {
-    /*
-        supervisorAvailability.clear();
-        unmatchedProjectIdeas.clear();
-        Employee bachelorSupervisor2 = createEmployee("David", "Hallberg", languages);
-        supervisorAvailability.add(new Availability(masterSupervisor, 3L, 3, bachelorProjectClass));
-        supervisorAvailability.add(new Availability(masterSupervisor, 3L, 4, masterProjectClass));
-        supervisorAvailability.add(new Availability(bachelorSupervisor2, 0L, 1, bachelorProjectClass));
+        Employee davidH = createEmployee("David", "Hallberg", languages);
+        Employee henrikH = createEmployee("Henrik", "Hansson", languages);
+        supervisorAvailability.add(new Availability(henrikH, 3L, 3, bachelorProjectClass));
+        supervisorAvailability.add(new Availability(henrikH, 3L, 4, masterProjectClass));
+        supervisorAvailability.add(new Availability(davidH, 0L, 1, bachelorProjectClass));
         unmatchedProjectIdeas.add(bachelorProjectIdea);
         unmatchedProjectIdeas.add(masterProjectIdea);
-        bachelorProjectIdea.setPreferredSupervisor(masterSupervisor);
-        masterProjectIdea.setPreferredSupervisor(masterSupervisor);
-        List<ProjectIdea> projectIdeaList = new ArrayList<ProjectIdea>();
-        projectIdeaList.add(bachelorProjectIdea);
-        List<Employee> supervisorList = new ArrayList<Employee>();
-        supervisorList.add(masterSupervisor);
-        addKeyWords(supervisorList, projectIdeaList, createKeyword(keywordTypeWord, "UML", false));
+        bachelorProjectIdea.setPreferredSupervisor(henrikH);
+        masterProjectIdea.setPreferredSupervisor(henrikH);
         Result result = new GreedyMatchingAlgorithm().match(supervisorAvailability, unmatchedProjectIdeas, weights);
-        assertTrue(result.matches.size() > 0);            
-        boolean foundMasterProjIdea = false;
-        boolean foundMasterSuperVisor= false;
-
-        boolean foundBachelorProjIdea = false;
-        boolean foundBachelorSuperVisor= false;
-
-        for(Match match : result.matches) {
-            if(match.getProjectIdea().equals(masterProjectIdea) && match.getSupervisor().equals(masterSupervisor)) {
-                foundMasterProjIdea = true;
-                foundMasterSuperVisor = true;
-            }
-
-            if(match.getProjectIdea().equals(bachelorProjectIdea) && match.getSupervisor().equals(bachelorSupervisor2)) {
-                foundBachelorProjIdea = true;
-                foundBachelorSuperVisor = true;
-            }
-        }
-        assertTrue(foundMasterProjIdea);
-        assertTrue(foundBachelorProjIdea);
-        assertTrue(foundBachelorSuperVisor);
-        assertTrue(foundMasterSuperVisor);
-        assertTrue(result.unmatched.size() == 0);   */
+        assertTrue(result.matches.size() > 0);
+        assertTrue(result.matches.get(0).getPoints() == 10);
+        assertTrue(result.matches.get(1).getPoints() == 0);
+        assertTrue(result.matches.get(0).getSupervisor().equals(henrikH));
+        assertTrue(result.matches.get(1).getSupervisor().equals(davidH));
+        assertTrue(result.matches.get(0).getProjectIdea().equals(masterProjectIdea));
+        assertTrue(result.matches.get(1).getProjectIdea().equals(bachelorProjectIdea));
+        assertTrue(result.unmatched.size() == 0);
     }
 
     @Test

From 91f9a4584b553623a2f124bed32bf60e08219c9f Mon Sep 17 00:00:00 2001
From: Tom Vahlman <tom@dsv.su.se>
Date: Mon, 27 Feb 2012 21:57:27 +0100
Subject: [PATCH 7/7] Moved the availability comparison to the class Pair.
 Tests should be written for this...

---
 .../scipro/match/GreedyMatchingAlgorithm.java | 35 +++++++++++--------
 .../scipro/match/dataobject/Availability.java | 15 ++------
 2 files changed, 23 insertions(+), 27 deletions(-)

diff --git a/src/main/java/se/su/dsv/scipro/match/GreedyMatchingAlgorithm.java b/src/main/java/se/su/dsv/scipro/match/GreedyMatchingAlgorithm.java
index 1a7a45b8f2..8aa6930b03 100644
--- a/src/main/java/se/su/dsv/scipro/match/GreedyMatchingAlgorithm.java
+++ b/src/main/java/se/su/dsv/scipro/match/GreedyMatchingAlgorithm.java
@@ -263,7 +263,7 @@ public class GreedyMatchingAlgorithm implements MatchingAlgorithm {
          */
         @Override
         public int compareTo(Pair otherPair) {
-            if(match.getPoints() > otherPair.getMatch().getPoints()) {
+            if(match.getPoints() > otherPair.getMatch().getPoints()) {    // points is the most important criteria
                 return -1;
             } else if(otherPair.getMatch().getPoints() > match.getPoints()) {
                 return 1;
@@ -272,20 +272,27 @@ public class GreedyMatchingAlgorithm implements MatchingAlgorithm {
                     return -1;
                 } else if(otherPair.getTotalAvailability() > totalAvailability) {
                     return 1;
-                } else {     // the points and the slots are equal, we must now sort on Project Class because a master supervisor can supervise
-                    // both a master project idea and a bachelor project idea, the "best" match however is if a master supervisor supervises a master project idea...
-                    if(match.getProjectIdea().getProjectClass().equals(availability.getProjectClass()) &&
-                            !otherPair.getMatch().getProjectIdea().getProjectClass().equals(otherPair.getAvailability().getProjectClass())) {
-                        return -1;
-                    } else  if(!match.getProjectIdea().getProjectClass().equals(availability.getProjectClass()) &&
-                            otherPair.getMatch().getProjectIdea().getProjectClass().equals(otherPair.getAvailability().getProjectClass())) {
-                        return 1;
-                    } else {   // the project class is the same sort on the highest availability
-                        return availability.compareTo(otherPair.getAvailability());
+                } else {
+                        // we must now sort on Project Class because a master supervisor can supervise both a master project idea and
+                        //  a bachelor project idea, however the "best" match is if a "master supervisor" handles a "master project idea"...
+                        if(match.getProjectIdea().getProjectClass().equals(availability.getProjectClass()) &&
+                                !otherPair.getMatch().getProjectIdea().getProjectClass().equals(otherPair.getAvailability().getProjectClass())) {
+                            return -1;
+                        } else  if(!match.getProjectIdea().getProjectClass().equals(availability.getProjectClass()) &&
+                                otherPair.getMatch().getProjectIdea().getProjectClass().equals(otherPair.getAvailability().getProjectClass())) {
+                            return 1;
+                        } else {
+                                // the most suited supervisor is now the one that has highest slots for the specific project class
+                                if(availability.getAvailability() > otherPair.getAvailability().getAvailability()) {
+                                    return -1;
+                                } else if(otherPair.getAvailability().getAvailability() > availability.getAvailability()) {
+                                    return 1;
+                                } else {   // the project classes is the same
+                                    return 0;
+                                }
+                        }
                     }
                 }
             }
-        }
-        
-	}
+	    }
 }
\ No newline at end of file
diff --git a/src/main/java/se/su/dsv/scipro/match/dataobject/Availability.java b/src/main/java/se/su/dsv/scipro/match/dataobject/Availability.java
index 3f06503a3f..954e152d9d 100644
--- a/src/main/java/se/su/dsv/scipro/match/dataobject/Availability.java
+++ b/src/main/java/se/su/dsv/scipro/match/dataobject/Availability.java
@@ -8,7 +8,7 @@ import se.su.dsv.scipro.data.dataobjects.ProjectClass;
 /**
  * A class that specifies how available a supervisor is(in terms of thesis supervision)
  */
-public class Availability implements Serializable, Comparable<Availability> {
+public class Availability implements Serializable {
 
 	private static final long serialVersionUID = 1L;
 	
@@ -53,18 +53,7 @@ public class Availability implements Serializable, Comparable<Availability> {
     public void setNumMatched(Long num) {
     	numMatched = num;
     }
-    
-    @Override
-    public int compareTo(Availability availability) {
-        if(getAvailability() > availability.getAvailability()) {
-            return -1;
-        } else if(availability.getAvailability() > getAvailability()) {
-            return 1;
-        } else {
-            return 0;
-        }
-    }
-    
+
     @Override
     public String toString() {
         return "Availability [supervisorId=" + supervisor + ", numMatched="