Index: DASISH/t5.6/backend/annotator-backend/trunk/annotator-backend/src/main/java/eu/dasish/annotation/backend/MatchMode.java
===================================================================
--- DASISH/t5.6/backend/annotator-backend/trunk/annotator-backend/src/main/java/eu/dasish/annotation/backend/MatchMode.java	(revision 5686)
+++ DASISH/t5.6/backend/annotator-backend/trunk/annotator-backend/src/main/java/eu/dasish/annotation/backend/MatchMode.java	(revision 5686)
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2013 DASISH
+ *
+ * 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.
+ */
+package eu.dasish.annotation.backend;
+
+/**
+ *
+ * @author olhsha
+ */
+public enum MatchMode {
+    EXACT, STARTS_WITH, ENDS_WITH, CONTAINS
+}
Index: DASISH/t5.6/backend/annotator-backend/trunk/annotator-backend/src/main/java/eu/dasish/annotation/backend/dao/DBDispatcher.java
===================================================================
--- DASISH/t5.6/backend/annotator-backend/trunk/annotator-backend/src/main/java/eu/dasish/annotation/backend/dao/DBDispatcher.java	(revision 5685)
+++ DASISH/t5.6/backend/annotator-backend/trunk/annotator-backend/src/main/java/eu/dasish/annotation/backend/dao/DBDispatcher.java	(revision 5686)
@@ -18,4 +18,5 @@
 package eu.dasish.annotation.backend.dao;
 
+import eu.dasish.annotation.backend.MatchMode;
 import eu.dasish.annotation.backend.NotInDataBaseException;
 import eu.dasish.annotation.backend.PrincipalCannotBeDeleted;
@@ -77,5 +78,5 @@
      * created after time-samp "after and before time-stamp "before".
      */
-    List<Number> getFilteredAnnotationIDs(UUID ownerId, String link, String text, Number inloggedPrincipalID, String  accessMode, String namespace, String after, String before) throws NotInDataBaseException;
+    List<Number> getFilteredAnnotationIDs(UUID ownerId, String link, MatchMode matchMode, String text, Number inloggedPrincipalID, String  accessMode, String namespace, String after, String before) throws NotInDataBaseException;
 
     AnnotationInfoList getAllAnnotationInfos();
@@ -96,5 +97,5 @@
      * created after time-samp "after and before time-stamp "before".
      */
-    AnnotationInfoList getFilteredAnnotationInfos(UUID ownerId, String link, String text, Number inloggedPrincipalID, String access, String namespace, String after, String before) throws NotInDataBaseException;
+    AnnotationInfoList getFilteredAnnotationInfos(UUID ownerId, String link, MatchMode matchMode, String text, Number inloggedPrincipalID, String access, String namespace, String after, String before) throws NotInDataBaseException;
 
   
Index: DASISH/t5.6/backend/annotator-backend/trunk/annotator-backend/src/main/java/eu/dasish/annotation/backend/dao/impl/DBDispatcherImlp.java
===================================================================
--- DASISH/t5.6/backend/annotator-backend/trunk/annotator-backend/src/main/java/eu/dasish/annotation/backend/dao/impl/DBDispatcherImlp.java	(revision 5685)
+++ DASISH/t5.6/backend/annotator-backend/trunk/annotator-backend/src/main/java/eu/dasish/annotation/backend/dao/impl/DBDispatcherImlp.java	(revision 5686)
@@ -21,4 +21,5 @@
 import eu.dasish.annotation.backend.Resource;
 import eu.dasish.annotation.backend.Helpers;
+import eu.dasish.annotation.backend.MatchMode;
 import eu.dasish.annotation.backend.PrincipalCannotBeDeleted;
 import eu.dasish.annotation.backend.PrincipalExists;
@@ -173,11 +174,11 @@
 
 ////////////////////////////////////////////////////////////////////////
-    @Override
-    public List<Number> getFilteredAnnotationIDs(UUID ownerId, String linkSubstring, String text, Number inloggedPrincipalID, String accessMode, String namespace, String after, String before) throws NotInDataBaseException {
+    @Override 
+    public List<Number> getFilteredAnnotationIDs(UUID ownerId, String link, MatchMode matchMode, String text, Number inloggedPrincipalID, String accessMode, String namespace, String after, String before) throws NotInDataBaseException {
 
         Number ownerID;
 
         if (ownerId != null) {
-            if (accessMode.equals("owner")) {
+            if (accessMode.equals("owner")) { // inloggedUser is the owner of the annotations
                 if (!ownerId.equals(principalDao.getExternalID(inloggedPrincipalID))) {
                     logger.info("The inlogged principal is demanded to be the owner of the annotations, however the expected owner is different and has the UUID " + ownerId.toString());
@@ -218,5 +219,5 @@
 
             // filtering on reference        
-            return this.filterAnnotationIDsOnReference(annotationIDs, linkSubstring);
+            return this.filterAnnotationIDsOnReference(annotationIDs, link, matchMode);
         }
 
@@ -226,12 +227,12 @@
 
     /// helpers ///
-    private List<Number> filterAnnotationIDsOnReference(List<Number> annotationIDs, String linkSubstring) {
-        if (linkSubstring != null) {
-            if (!linkSubstring.isEmpty()) {
+    private List<Number> filterAnnotationIDsOnReference(List<Number> annotationIDs, String link, MatchMode matchMode) {
+        if (link != null) {
+            if (!link.isEmpty()) {
                 if (annotationIDs != null) {
-                    String partiallyEncoded = this.encodeURLNoSlashEncoded(linkSubstring);
+                    String partiallyEncoded = this.encodeURLNoSlashEncoded(link);
                     String urlEncoded = null;
                     try {
-                        urlEncoded = URLEncoder.encode(linkSubstring, "UTF-8");
+                        urlEncoded = URLEncoder.encode(link, "UTF-8");
                     } catch (UnsupportedEncodingException e) {
                         logger.debug(e.toString());
@@ -243,10 +244,10 @@
                         for (Number targetID : targets) {
                             if (!result.contains(annotationID)) {
-                                String link = targetDao.getLink(targetID);
-                                if (link.contains(linkSubstring) || link.contains(partiallyEncoded)) {
+                                String linkRunner = targetDao.getLink(targetID);
+                                if (matchCriterium(linkRunner, link, matchMode) || matchCriterium(linkRunner, partiallyEncoded, matchMode)) {
                                     result.add(annotationID);
                                 } else {
                                     if (urlEncoded != null) {
-                                        if (link.contains(urlEncoded)) {
+                                        if (matchCriterium(linkRunner, urlEncoded, matchMode)) {
                                             result.add(annotationID);
                                         }
@@ -261,4 +262,14 @@
         }
         return annotationIDs;
+    }
+    
+    private boolean matchCriterium(String currentString, String pattern, MatchMode matchMode){        
+        switch (matchMode) {
+            case EXACT: return currentString.equals(pattern);
+            case STARTS_WITH: return currentString.startsWith(pattern);
+            case ENDS_WITH: return currentString.endsWith(pattern);
+            case CONTAINS: return currentString.contains(pattern);
+            default: return false;
+        }
     }
 
@@ -339,6 +350,6 @@
 
     @Override
-    public AnnotationInfoList getFilteredAnnotationInfos(UUID ownerId, String link, String text, Number inloggedPrincipalID, String access, String namespace, String after, String before) throws NotInDataBaseException {
-        List<Number> annotationIDs = this.getFilteredAnnotationIDs(ownerId, link, text, inloggedPrincipalID, access, namespace, after, before);
+    public AnnotationInfoList getFilteredAnnotationInfos(UUID ownerId, String link, MatchMode matchMode, String text, Number inloggedPrincipalID, String access, String namespace, String after, String before) throws NotInDataBaseException {
+        List<Number> annotationIDs = this.getFilteredAnnotationIDs(ownerId, link, matchMode, text, inloggedPrincipalID, access, namespace, after, before);
         AnnotationInfoList result = new AnnotationInfoList();
         for (Number annotationID : annotationIDs) {
@@ -401,5 +412,7 @@
         ReferenceList referenceList = new ReferenceList();
         for (Number siblingID : targetIDs) {
+            if (!siblingID.equals(targetID)) {
             referenceList.getHref().add(targetDao.getHrefFromInternalID(siblingID));
+            }
         }
         return referenceList;
Index: DASISH/t5.6/backend/annotator-backend/trunk/annotator-backend/src/main/java/eu/dasish/annotation/backend/rest/AnnotationResource.java
===================================================================
--- DASISH/t5.6/backend/annotator-backend/trunk/annotator-backend/src/main/java/eu/dasish/annotation/backend/rest/AnnotationResource.java	(revision 5685)
+++ DASISH/t5.6/backend/annotator-backend/trunk/annotator-backend/src/main/java/eu/dasish/annotation/backend/rest/AnnotationResource.java	(revision 5686)
@@ -20,4 +20,5 @@
 import eu.dasish.annotation.backend.BackendConstants;
 import eu.dasish.annotation.backend.ForbiddenException;
+import eu.dasish.annotation.backend.MatchMode;
 import eu.dasish.annotation.backend.NotInDataBaseException;
 import eu.dasish.annotation.backend.Resource;
@@ -66,4 +67,7 @@
 @Transactional(rollbackFor = {Exception.class})
 public class AnnotationResource extends ResourceResource {
+    
+    final private String defaultMatchMode = "exact";
+    final private String[] admissibleMatchModes = {"exact", "starts_with", "ends_with", "contains"};
 
     public void setHttpServletResponse(HttpServletResponse httpServletResponse) {
@@ -81,4 +85,5 @@
     public AnnotationResource() {
     }
+    
 
     @GET
@@ -149,4 +154,5 @@
     @Transactional(readOnly = true)
     public JAXBElement<AnnotationInfoList> getFilteredAnnotations(@QueryParam("link") String link,
+            @QueryParam("matchMode") String matchMode,
             @QueryParam("text") String text,
             @QueryParam("access") String access,
@@ -160,6 +166,16 @@
             return new ObjectFactory().createAnnotationInfoList(new AnnotationInfoList());
         }
+        
+         if (matchMode == null) {
+            matchMode = defaultMatchMode;
+        }
+        if (!Arrays.asList(admissibleMatchModes).contains(matchMode)) {
+            httpServletResponse.sendError(HttpServletResponse.SC_NOT_FOUND, "ivalide match mode " + matchMode);
+            return new ObjectFactory().createAnnotationInfoList(new AnnotationInfoList());
+        }
 
         UUID ownerExternalUUID = (ownerExternalId != null) ? UUID.fromString(ownerExternalId) : null;
+        
+        
         if (access == null) {
             access = defaultAccess;
@@ -170,6 +186,8 @@
             return new ObjectFactory().createAnnotationInfoList(new AnnotationInfoList());
         }
-        try {
-            final AnnotationInfoList annotationInfoList = dbDispatcher.getFilteredAnnotationInfos(ownerExternalUUID, link, text, principalID, access, namespace, after, before);
+        
+        
+        try {
+            final AnnotationInfoList annotationInfoList = dbDispatcher.getFilteredAnnotationInfos(ownerExternalUUID, link, MatchMode.valueOf(matchMode.toUpperCase()), text, principalID, access, namespace, after, before);
             return new ObjectFactory().createAnnotationInfoList(annotationInfoList);
         } catch (NotInDataBaseException e) {
@@ -193,5 +211,5 @@
             
             System.out.print("Preparing the data: getting the list of all annotations, picking up "+n+" of them randomly, and initializing threads");            
-            final List<Number> annotationIDs = dbDispatcher.getFilteredAnnotationIDs(null, null, null, remotePrincipalID, "read", null, null, null);
+            final List<Number> annotationIDs = dbDispatcher.getFilteredAnnotationIDs(null, null, null, null, remotePrincipalID, "read", null, null, null);
             final int size = annotationIDs.size();
             List<GetThread> threads = new ArrayList<GetThread>(n);
Index: DASISH/t5.6/backend/annotator-backend/trunk/annotator-backend/src/main/webapp/index.jsp
===================================================================
--- DASISH/t5.6/backend/annotator-backend/trunk/annotator-backend/src/main/webapp/index.jsp	(revision 5685)
+++ DASISH/t5.6/backend/annotator-backend/trunk/annotator-backend/src/main/webapp/index.jsp	(revision 5686)
@@ -57,6 +57,10 @@
 <!--        !Problem: how to ask the servlet if the given user is logged in, may be by some other running somewhere client<br> -->
         GET <a href="api/principals/info?email=Twan.Goosen@mpi.nl">api/principals/info?email=Twan.Goosen@mpi.nl</a>  <br>
-        GET <a href="api/annotations?link=Sagrada_Fam%C3%ADlia">api/annotations?link=Sagrada_Fam%C3%ADlia</a>  <br>
-        GET <a href="api/annotations?link=Antoni_Gaud%C3%AD">api/annotations?link=Antoni_Gaud%C3%AD</a>  <br>
+        GET <a href="api/annotations?link=Sagrada&matchMode=contains">api/annotations?link=Sagrada&matchMode=contains</a>  <br>
+        GET <a href="api/annotations?link=http://nl.wikipedia.org/wiki/Sagrada_Fam%C3%ADlia&matchMode=exact">api/annotations?link=http://nl.wikipedia.org/wiki/Sagrada_Fam%C3%ADlia&matchMode=exact</a>  <br>
+        GET <a href="api/annotations?link=http://nl.wikipedia.org/wiki&matchMode=starts_with">api/annotations?link=http://nl.wikipedia.org/wiki&matchMode=starts_with</a>  <br>
+        GET <a href="api/annotations?link=_Fam%C3%ADlia&matchMode=ends_with">api/annotations?link=_Fam%C3%ADlia&matchMode=ends_with</a>  <br>
+        GET <a href="api/annotations?link=http://nl.wikipedia.org/wiki/Sagrada_Fam%C3%ADlia">api/annotations?link=http://nl.wikipedia.org/wiki/Sagrada_Fam%C3%ADlia</a>  <br>
+        GET <a href="api/annotations?link=http://nl.wikipedia.org/wiki/Antoni_Gaud%C3%AD">api/annotations?link=http://nl.wikipedia.org/wiki/Antoni_Gaud%C3%AD</a>  <br>
         GET <a href="api/annotations?after=2013-02-04 15:57:58.046908&before=2014-06-25 10:08:16.213186">api/annotations?after=2014-02-04 15:57:58.046908&before=2014-04-06 10:08:16.213186</a><br> 
 <!--        !Comment: What is "namespace" query parameter? Must be implemented and tested <br>-->
Index: DASISH/t5.6/backend/annotator-backend/trunk/annotator-backend/src/test/java/eu/dasish/annotation/backend/dao/impl/DBDispatcherTest.java
===================================================================
--- DASISH/t5.6/backend/annotator-backend/trunk/annotator-backend/src/test/java/eu/dasish/annotation/backend/dao/impl/DBDispatcherTest.java	(revision 5685)
+++ DASISH/t5.6/backend/annotator-backend/trunk/annotator-backend/src/test/java/eu/dasish/annotation/backend/dao/impl/DBDispatcherTest.java	(revision 5686)
@@ -19,4 +19,5 @@
 
 import eu.dasish.annotation.backend.Helpers;
+import eu.dasish.annotation.backend.MatchMode;
 import eu.dasish.annotation.backend.NotInDataBaseException;
 import eu.dasish.annotation.backend.PrincipalCannotBeDeleted;
@@ -305,5 +306,5 @@
      */
     @Test
-    public void testGetFilteredAnnotationIDs() throws NotInDataBaseException {
+    public void testGetFilteredAnnotationIDsContains() throws NotInDataBaseException {
         System.out.println("test getFilteredAnnotationIDs");
         
@@ -366,11 +367,234 @@
 
 
-        List result = dbDispatcher.getFilteredAnnotationIDs(null, "Sagrada_Fam%C3%ADlia", "some html 1", 3, "read", null, after, before);
-        assertEquals(1, result.size());
-        assertEquals(1, result.get(0));
-    }
-
-    @Test
-    public void testGetFilteredAnnotationIDs2() throws NotInDataBaseException {
+        List resultContains = dbDispatcher.getFilteredAnnotationIDs(null, "Sagrada_", MatchMode.CONTAINS, "some html 1", 3, "read", null, after, before);
+        assertEquals(1, resultContains.size());
+        assertEquals(1, resultContains.get(0));
+        
+        
+        
+    }
+    
+    
+    /**
+     * Test of getFilteredAnnotationIDs method, of class DBIntegrityServiceImlp.
+     */
+    @Test
+    public void testGetFilteredAnnotationIDsExact() throws NotInDataBaseException {
+        System.out.println("test getFilteredAnnotationIDs");
+        
+        final List<Number> mockAnnotationIDs1 = new ArrayList<Number>();
+        mockAnnotationIDs1.add(1);
+     
+        final List<Number> mockAnnotationIDsOwned = new ArrayList<Number>();
+        //mockAnnotationIDsOwned.add(3);
+
+        final List<Number> mockAnnotationIDsRead = new ArrayList<Number>();
+        mockAnnotationIDsRead.add(1);
+        mockAnnotationIDsRead.add(2);
+        
+
+        final List<Number> mockAnnotationIDsPublicRead = new ArrayList<Number>();
+        mockAnnotationIDsPublicRead.add(1);
+        mockAnnotationIDsPublicRead.add(2);
+        
+        final List<Number> mockTargets1 = new ArrayList<Number>();
+        mockTargets1.add(1);
+        mockTargets1.add(2);
+        
+        
+        final String link1 = "http://nl.wikipedia.org/wiki/Sagrada_Fam%C3%ADlia";
+        final String link2 = "http://nl.wikipedia.org/wiki/Antoni_Gaud%C3%AD";
+
+        final String after = (new Timestamp(0)).toString();
+        final String before = (new Timestamp(System.currentTimeMillis())).toString();
+
+        final Number loggedIn = 3;
+
+        mockeryDao.checking(new Expectations() {
+            {
+               
+
+                oneOf(annotationDao).getFilteredAnnotationIDs(null, "some html 1", null, after, before);
+                will(returnValue(mockAnnotationIDs1));
+
+                oneOf(annotationDao).getAnnotationIDsForPermission(loggedIn, Access.READ);
+                will(returnValue(mockAnnotationIDsRead));
+
+                oneOf(annotationDao).getAnnotationIDsForPublicAccess(Access.READ);
+                will(returnValue(mockAnnotationIDsPublicRead));               
+
+                oneOf(annotationDao).getFilteredAnnotationIDs(loggedIn, "some html 1", null, after, before);
+                will(returnValue(mockAnnotationIDsOwned));
+                
+                oneOf(targetDao).getTargetIDs(1);
+                will(returnValue(mockTargets1));
+                
+                oneOf(targetDao).getLink(1);
+                will(returnValue(link1));
+                
+                oneOf(targetDao).getLink(2);
+                will(returnValue(link2));
+              
+
+            }
+        });
+
+
+        
+        List resultExact = dbDispatcher.getFilteredAnnotationIDs(null, "http://nl.wikipedia.org/wiki/Sagrada_Fam%C3%ADlia", MatchMode.EXACT, "some html 1", 3, "read", null, after, before);
+        assertEquals(1, resultExact.size());
+        assertEquals(1, resultExact.get(0));
+        
+      
+    }
+    
+    /**
+     * Test of getFilteredAnnotationIDs method, of class DBIntegrityServiceImlp.
+     */
+    @Test
+    public void testGetFilteredAnnotationIDsStartsWith() throws NotInDataBaseException {
+        System.out.println("test getFilteredAnnotationIDs");
+        
+        final List<Number> mockAnnotationIDs1 = new ArrayList<Number>();
+        mockAnnotationIDs1.add(1);
+     
+        final List<Number> mockAnnotationIDsOwned = new ArrayList<Number>();
+        //mockAnnotationIDsOwned.add(3);
+
+        final List<Number> mockAnnotationIDsRead = new ArrayList<Number>();
+        mockAnnotationIDsRead.add(1);
+        mockAnnotationIDsRead.add(2);
+        
+
+        final List<Number> mockAnnotationIDsPublicRead = new ArrayList<Number>();
+        mockAnnotationIDsPublicRead.add(1);
+        mockAnnotationIDsPublicRead.add(2);
+        
+        final List<Number> mockTargets1 = new ArrayList<Number>();
+        mockTargets1.add(1);
+        mockTargets1.add(2);
+        
+        
+        final String link1 = "http://nl.wikipedia.org/wiki/Sagrada_Fam%C3%ADlia";
+        final String link2 = "http://nl.wikipedia.org/wiki/Antoni_Gaud%C3%AD";
+
+        final String after = (new Timestamp(0)).toString();
+        final String before = (new Timestamp(System.currentTimeMillis())).toString();
+
+        final Number loggedIn = 3;
+
+        mockeryDao.checking(new Expectations() {
+            {
+               
+
+                oneOf(annotationDao).getFilteredAnnotationIDs(null, "some html 1", null, after, before);
+                will(returnValue(mockAnnotationIDs1));
+
+                oneOf(annotationDao).getAnnotationIDsForPermission(loggedIn, Access.READ);
+                will(returnValue(mockAnnotationIDsRead));
+
+                oneOf(annotationDao).getAnnotationIDsForPublicAccess(Access.READ);
+                will(returnValue(mockAnnotationIDsPublicRead));               
+
+                oneOf(annotationDao).getFilteredAnnotationIDs(loggedIn, "some html 1", null, after, before);
+                will(returnValue(mockAnnotationIDsOwned));
+                
+                oneOf(targetDao).getTargetIDs(1);
+                will(returnValue(mockTargets1));
+                
+                oneOf(targetDao).getLink(1);
+                will(returnValue(link1));
+                
+                oneOf(targetDao).getLink(2);
+                will(returnValue(link2));
+              
+
+            }
+        });
+
+
+        
+        List resultStartsWith = dbDispatcher.getFilteredAnnotationIDs(null, "http://nl.wikipedia.org/wiki/Sagrada_", MatchMode.STARTS_WITH, "some html 1", 3, "read", null, after, before);
+        assertEquals(1, resultStartsWith.size());
+        assertEquals(1, resultStartsWith.get(0));
+        
+        
+        
+    }
+    
+    /**
+     * Test of getFilteredAnnotationIDs method, of class DBIntegrityServiceImlp.
+     */
+    @Test
+    public void testGetFilteredAnnotationIDsEndsWith() throws NotInDataBaseException {
+        System.out.println("test getFilteredAnnotationIDs");
+        
+        final List<Number> mockAnnotationIDs1 = new ArrayList<Number>();
+        mockAnnotationIDs1.add(1);
+     
+        final List<Number> mockAnnotationIDsOwned = new ArrayList<Number>();
+        //mockAnnotationIDsOwned.add(3);
+
+        final List<Number> mockAnnotationIDsRead = new ArrayList<Number>();
+        mockAnnotationIDsRead.add(1);
+        mockAnnotationIDsRead.add(2);
+        
+
+        final List<Number> mockAnnotationIDsPublicRead = new ArrayList<Number>();
+        mockAnnotationIDsPublicRead.add(1);
+        mockAnnotationIDsPublicRead.add(2);
+        
+        final List<Number> mockTargets1 = new ArrayList<Number>();
+        mockTargets1.add(1);
+        mockTargets1.add(2);
+        
+        
+        final String link1 = "http://nl.wikipedia.org/wiki/Sagrada_Fam%C3%ADlia";
+        final String link2 = "http://nl.wikipedia.org/wiki/Antoni_Gaud%C3%AD";
+
+        final String after = (new Timestamp(0)).toString();
+        final String before = (new Timestamp(System.currentTimeMillis())).toString();
+
+        final Number loggedIn = 3;
+
+        mockeryDao.checking(new Expectations() {
+            {
+               
+
+                oneOf(annotationDao).getFilteredAnnotationIDs(null, "some html 1", null, after, before);
+                will(returnValue(mockAnnotationIDs1));
+
+                oneOf(annotationDao).getAnnotationIDsForPermission(loggedIn, Access.READ);
+                will(returnValue(mockAnnotationIDsRead));
+
+                oneOf(annotationDao).getAnnotationIDsForPublicAccess(Access.READ);
+                will(returnValue(mockAnnotationIDsPublicRead));               
+
+                oneOf(annotationDao).getFilteredAnnotationIDs(loggedIn, "some html 1", null, after, before);
+                will(returnValue(mockAnnotationIDsOwned));
+                
+                oneOf(targetDao).getTargetIDs(1);
+                will(returnValue(mockTargets1));
+                
+                oneOf(targetDao).getLink(1);
+                will(returnValue(link1));
+                
+                oneOf(targetDao).getLink(2);
+                will(returnValue(link2));
+              
+
+            }
+        });
+
+        
+        List resultEndsWith = dbDispatcher.getFilteredAnnotationIDs(null, "Fam%C3%ADlia", MatchMode.ENDS_WITH, "some html 1", 3, "read", null, after, before);
+        assertEquals(1, resultEndsWith.size());
+        assertEquals(1, resultEndsWith.get(0));
+        
+    }
+
+   
+    @Test
+    public void testGetFilteredAnnotationIDs2Contains() throws NotInDataBaseException {
         System.out.println("test getFilteredAnnotationIDs");
        
@@ -404,6 +628,4 @@
         mockeryDao.checking(new Expectations() {
             {
-               
-
                 oneOf(annotationDao).getFilteredAnnotationIDs(null, "some html 1", null, after, before);
                 will(returnValue(mockAnnotationIDs1));
@@ -426,12 +648,208 @@
                 oneOf(targetDao).getLink(2);
                 will(returnValue(link2));
-               
-            }
-        });
-
-
-        List result = dbDispatcher.getFilteredAnnotationIDs(null, "Sagrada_Fam%C3%ADlia", "some html 1", 3, "write", null, after, before);
-        assertEquals(1, result.size());
-        assertEquals(1, result.get(0));
+                
+            }
+        });
+
+
+        
+        List resultContains = dbDispatcher.getFilteredAnnotationIDs(null, "Sagrada_", MatchMode.CONTAINS, "some html 1", 3, "write", null, after, before);
+        assertEquals(1, resultContains.size());
+        assertEquals(1, resultContains.get(0));
+    }
+    
+    @Test
+    public void testGetFilteredAnnotationIDs2Exact() throws NotInDataBaseException {
+        System.out.println("test getFilteredAnnotationIDs");
+       
+        final List<Number> mockAnnotationIDs1 = new ArrayList<Number>();
+        mockAnnotationIDs1.add(1);
+
+     
+        final List<Number> mockAnnotationIDsOwned = new ArrayList<Number>();
+        //mockAnnotationIDsOwned.add(3);
+
+        final List<Number> mockAnnotationIDsWrite = new ArrayList<Number>();
+        mockAnnotationIDsWrite.add(2);
+        
+
+        final List<Number> mockAnnotationIDsPublicWrite = new ArrayList<Number>();
+        mockAnnotationIDsPublicWrite.add(1);
+        
+        final List<Number> mockTargets1 = new ArrayList<Number>();
+        mockTargets1.add(1);
+        mockTargets1.add(2);
+        
+       
+        final String link1 = "http://nl.wikipedia.org/wiki/Sagrada_Fam%C3%ADlia";
+        final String link2 = "http://nl.wikipedia.org/wiki/Antoni_Gaud%C3%AD";
+
+        final String after = (new Timestamp(0)).toString();
+        final String before = (new Timestamp(System.currentTimeMillis())).toString();
+
+        final Number loggedIn = 3;
+
+        mockeryDao.checking(new Expectations() {
+            {
+                oneOf(annotationDao).getFilteredAnnotationIDs(null, "some html 1", null, after, before);
+                will(returnValue(mockAnnotationIDs1));
+
+                oneOf(annotationDao).getAnnotationIDsForPermission(loggedIn, Access.WRITE);
+                will(returnValue(mockAnnotationIDsWrite));
+
+                oneOf(annotationDao).getAnnotationIDsForPublicAccess(Access.WRITE);
+                will(returnValue(mockAnnotationIDsPublicWrite));               
+
+                oneOf(annotationDao).getFilteredAnnotationIDs(loggedIn, "some html 1", null, after, before);
+                will(returnValue(mockAnnotationIDsOwned));
+                
+                oneOf(targetDao).getTargetIDs(1);
+                will(returnValue(mockTargets1));
+                
+                oneOf(targetDao).getLink(1);
+                will(returnValue(link1));
+                
+                oneOf(targetDao).getLink(2);
+                will(returnValue(link2));
+                
+            }
+        });
+
+
+        
+        List resultExact = dbDispatcher.getFilteredAnnotationIDs(null, "http://nl.wikipedia.org/wiki/Sagrada_Fam%C3%ADlia", MatchMode.EXACT, "some html 1", 3, "write", null, after, before);
+        assertEquals(1, resultExact.size());
+        assertEquals(1, resultExact.get(0));
+        
+       
+    }
+    
+    @Test
+    public void testGetFilteredAnnotationIDs2StartsWith() throws NotInDataBaseException {
+        System.out.println("test getFilteredAnnotationIDs");
+       
+        final List<Number> mockAnnotationIDs1 = new ArrayList<Number>();
+        mockAnnotationIDs1.add(1);
+
+     
+        final List<Number> mockAnnotationIDsOwned = new ArrayList<Number>();
+        //mockAnnotationIDsOwned.add(3);
+
+        final List<Number> mockAnnotationIDsWrite = new ArrayList<Number>();
+        mockAnnotationIDsWrite.add(2);
+        
+
+        final List<Number> mockAnnotationIDsPublicWrite = new ArrayList<Number>();
+        mockAnnotationIDsPublicWrite.add(1);
+        
+        final List<Number> mockTargets1 = new ArrayList<Number>();
+        mockTargets1.add(1);
+        mockTargets1.add(2);
+        
+       
+        final String link1 = "http://nl.wikipedia.org/wiki/Sagrada_Fam%C3%ADlia";
+        final String link2 = "http://nl.wikipedia.org/wiki/Antoni_Gaud%C3%AD";
+
+        final String after = (new Timestamp(0)).toString();
+        final String before = (new Timestamp(System.currentTimeMillis())).toString();
+
+        final Number loggedIn = 3;
+
+        mockeryDao.checking(new Expectations() {
+            {
+                oneOf(annotationDao).getFilteredAnnotationIDs(null, "some html 1", null, after, before);
+                will(returnValue(mockAnnotationIDs1));
+
+                oneOf(annotationDao).getAnnotationIDsForPermission(loggedIn, Access.WRITE);
+                will(returnValue(mockAnnotationIDsWrite));
+
+                oneOf(annotationDao).getAnnotationIDsForPublicAccess(Access.WRITE);
+                will(returnValue(mockAnnotationIDsPublicWrite));               
+
+                oneOf(annotationDao).getFilteredAnnotationIDs(loggedIn, "some html 1", null, after, before);
+                will(returnValue(mockAnnotationIDsOwned));
+                
+                oneOf(targetDao).getTargetIDs(1);
+                will(returnValue(mockTargets1));
+                
+                oneOf(targetDao).getLink(1);
+                will(returnValue(link1));
+                
+                oneOf(targetDao).getLink(2);
+                will(returnValue(link2));
+                
+            }
+        });
+
+
+        List resultStartsWith = dbDispatcher.getFilteredAnnotationIDs(null, "http://nl.wikipedia.org/wiki/Sagrada_", MatchMode.STARTS_WITH, "some html 1", 3, "write", null, after, before);
+        assertEquals(1, resultStartsWith.size());
+        assertEquals(1, resultStartsWith.get(0));
+        
+       
+    }
+    
+    @Test
+    public void testGetFilteredAnnotationIDs2EndsWith() throws NotInDataBaseException {
+        System.out.println("test getFilteredAnnotationIDs");
+       
+        final List<Number> mockAnnotationIDs1 = new ArrayList<Number>();
+        mockAnnotationIDs1.add(1);
+
+     
+        final List<Number> mockAnnotationIDsOwned = new ArrayList<Number>();
+        //mockAnnotationIDsOwned.add(3);
+
+        final List<Number> mockAnnotationIDsWrite = new ArrayList<Number>();
+        mockAnnotationIDsWrite.add(2);
+        
+
+        final List<Number> mockAnnotationIDsPublicWrite = new ArrayList<Number>();
+        mockAnnotationIDsPublicWrite.add(1);
+        
+        final List<Number> mockTargets1 = new ArrayList<Number>();
+        mockTargets1.add(1);
+        mockTargets1.add(2);
+        
+       
+        final String link1 = "http://nl.wikipedia.org/wiki/Sagrada_Fam%C3%ADlia";
+        final String link2 = "http://nl.wikipedia.org/wiki/Antoni_Gaud%C3%AD";
+
+        final String after = (new Timestamp(0)).toString();
+        final String before = (new Timestamp(System.currentTimeMillis())).toString();
+
+        final Number loggedIn = 3;
+
+        mockeryDao.checking(new Expectations() {
+            {
+                oneOf(annotationDao).getFilteredAnnotationIDs(null, "some html 1", null, after, before);
+                will(returnValue(mockAnnotationIDs1));
+
+                oneOf(annotationDao).getAnnotationIDsForPermission(loggedIn, Access.WRITE);
+                will(returnValue(mockAnnotationIDsWrite));
+
+                oneOf(annotationDao).getAnnotationIDsForPublicAccess(Access.WRITE);
+                will(returnValue(mockAnnotationIDsPublicWrite));               
+
+                oneOf(annotationDao).getFilteredAnnotationIDs(loggedIn, "some html 1", null, after, before);
+                will(returnValue(mockAnnotationIDsOwned));
+                
+                oneOf(targetDao).getTargetIDs(1);
+                will(returnValue(mockTargets1));
+                
+                oneOf(targetDao).getLink(1);
+                will(returnValue(link1));
+                
+                oneOf(targetDao).getLink(2);
+                will(returnValue(link2));
+                
+            }
+        });
+
+
+        
+        List resultEndsWith = dbDispatcher.getFilteredAnnotationIDs(null, "Fam%C3%ADlia", MatchMode.ENDS_WITH, "some html 1", 3, "write", null, after, before);
+        assertEquals(1, resultEndsWith.size());
+        assertEquals(1, resultEndsWith.get(0));
 
     }
@@ -452,13 +870,32 @@
                 oneOf(annotationDao).getFilteredAnnotationIDs(3, "some html 1", null, after, before);
                 will(returnValue(mockAnnotationIDs1));
-
-            }
-        });
-
-
-        List result = dbDispatcher.getFilteredAnnotationIDs(null, "Sagrada_Fam%C3%ADlia", "some html 1", 3, "owner", null, after, before);
-        assertEquals(0, result.size());
-    }
-
+                
+                oneOf(annotationDao).getFilteredAnnotationIDs(3, "some html 1", null, after, before);
+                will(returnValue(mockAnnotationIDs1));
+                
+                oneOf(annotationDao).getFilteredAnnotationIDs(3, "some html 1", null, after, before);
+                will(returnValue(mockAnnotationIDs1));
+                
+                oneOf(annotationDao).getFilteredAnnotationIDs(3, "some html 1", null, after, before);
+                will(returnValue(mockAnnotationIDs1));
+
+            }
+        });
+
+
+        List resultContains = dbDispatcher.getFilteredAnnotationIDs(null, "Sagrada_", MatchMode.CONTAINS, "some html 1", 3, "owner", null, after, before);
+        assertEquals(0, resultContains.size());
+        
+        List resultExact = dbDispatcher.getFilteredAnnotationIDs(null, "http://nl.wikipedia.org/wiki/Sagrada_Fam%C3%ADlia", MatchMode.EXACT, "some html 1", 3, "owner", null, after, before);
+        assertEquals(0, resultExact.size());
+        
+        List resultStartsWith = dbDispatcher.getFilteredAnnotationIDs(null, "http://nl.wikipedia.org/wiki/Sagrada_", MatchMode.STARTS_WITH, "some html 1", 3, "owner", null, after, before);
+        assertEquals(0, resultStartsWith.size());
+        
+        List resultEndsWith = dbDispatcher.getFilteredAnnotationIDs(null, "Fam%C3%ADlia", MatchMode.ENDS_WITH, "some html 1", 3, "owner", null, after, before);
+        assertEquals(0, resultEndsWith.size());
+    }
+
+    
     @Test
     public void testGetFilteredAnnotationIDs4() throws NotInDataBaseException {
@@ -484,5 +921,5 @@
 
 
-        List result = dbDispatcher.getFilteredAnnotationIDs(UUID.fromString("00000000-0000-0000-0000-000000000111"), "nl.wikipedia.org", "some html 1", 3, "owner", null, after, before);
+        List result = dbDispatcher.getFilteredAnnotationIDs(UUID.fromString("00000000-0000-0000-0000-000000000111"), "nl.wikipedia.org", MatchMode.CONTAINS, "some html 1", 3, "owner", null, after, before);
         assertEquals(0, result.size());
     }
@@ -630,5 +1067,5 @@
 
 
-        AnnotationInfoList result = dbDispatcher.getFilteredAnnotationInfos(ownerUUID, "nl.wikipedia.org", "some html 1", 3, "read", null, after, before);
+        AnnotationInfoList result = dbDispatcher.getFilteredAnnotationInfos(ownerUUID, "http://nl.wikipedia.org/wiki/Sagrada_Fam%C3%ADlia", MatchMode.EXACT, "some html 1", 3, "read", null, after, before);
         assertEquals(1, result.getAnnotationInfo().size());
         AnnotationInfo resultAnnotInfo = result.getAnnotationInfo().get(0);
