Index: src/main/java/de/mpiwg/itgroup/annotations/NS.java
===================================================================
--- src/main/java/de/mpiwg/itgroup/annotations/NS.java	(revision 18)
+++ src/main/java/de/mpiwg/itgroup/annotations/NS.java	(revision 28)
@@ -3,4 +3,5 @@
 public class NS {
     public static final String MPIWG_PERSONS_URL = "http://entities.mpiwg-berlin.mpg.de/persons/";
+    public static final String MPIWG_TAGS_URL = "http://entities.mpiwg-berlin.mpg.de/tags/";
     public static final String MPIWG_GROUPS_URL = "http://entities.mpiwg-berlin.mpg.de/groups/";
     public static final String OAC_NS = "http://www.openannotation.org/ns/";
Index: src/main/java/de/mpiwg/itgroup/annotations/Tag.java
===================================================================
--- src/main/java/de/mpiwg/itgroup/annotations/Tag.java	(revision 28)
+++ src/main/java/de/mpiwg/itgroup/annotations/Tag.java	(revision 28)
@@ -0,0 +1,44 @@
+package de.mpiwg.itgroup.annotations;
+
+/**
+ * @author dwinter
+ *
+ */
+public class Tag {
+
+	    public String uri;
+	    public String name;
+	    public String id;
+	    
+	    
+		public Tag(String id, String uri, String name) {
+			this.uri=uri;
+			this.id=id;
+			this.name=name;
+		}
+		public String getUri() {
+			if (uri==null){
+				return NS.MPIWG_TAGS_URL+getId(); // erzeuge uri aus if falls keine ID
+			}
+			return uri;
+		}
+		public void setUri(String uri) {
+			this.uri = uri;
+		}
+		public String getName() {
+			return name;
+		}
+		public void setName(String name) {
+			this.name = name;
+		}
+		public String getId() {
+			if (id==null){
+				return getName(); //take name if id not defined
+			}
+			return id;
+		}
+		public void setId(String id) {
+			this.id = id;
+		}
+
+}
Index: src/main/java/de/mpiwg/itgroup/annotations/neo4j/AnnotationStore.java
===================================================================
--- src/main/java/de/mpiwg/itgroup/annotations/neo4j/AnnotationStore.java	(revision 25)
+++ src/main/java/de/mpiwg/itgroup/annotations/neo4j/AnnotationStore.java	(revision 28)
@@ -25,4 +25,5 @@
 import de.mpiwg.itgroup.annotations.Group;
 import de.mpiwg.itgroup.annotations.Person;
+import de.mpiwg.itgroup.annotations.Tag;
 
 /**
@@ -74,4 +75,14 @@
     }
 
+    /**
+     * @param tagUri
+     * @return
+     */
+    public Node getTagNodeByUri(String tagUri) {
+        if (tagUri == null) return null;
+        Node person = getNodeIndex(NodeTypes.TAG).get("uri", tagUri).getSingle();
+        return person;
+    }
+
     public List<Actor> getActors(String key, String query, NodeTypes type) {
         ArrayList<Actor> actors = new ArrayList<Actor>();
@@ -111,6 +122,31 @@
         return groups;
     }
-
-    /**
+    
+    
+    /**
+     * Returns List of Tags.
+     * Key has to be indexed.
+     * 
+     * @param key
+     * @param query
+     * @return
+     */
+    public List<Tag> getTags(String key, String query) {
+        ArrayList<Tag> tags = new ArrayList<Tag>();
+        Index<Node> idx = getNodeIndex(NodeTypes.TAG);
+        if (key == null) {
+            key = "uri";
+            query = "*";
+        }
+        IndexHits<Node> groupNodes = idx.query(key, query);
+        for (Node groupNode : groupNodes) {
+            Tag tag = createTagFromNode(groupNode);
+            tags.add(tag);
+        }
+        return tags;
+    }
+
+ 
+   /**
      * Returns List of Groups the person is member of.
      * 
@@ -176,40 +212,4 @@
         }
         return members;
-    }
-    
-    /**
-     * Add Person newMember to Group group.
-     * 
-     * @param group
-     * @param member
-     */
-    public Person addGroupMember(Group group, Person member) {
-        Node gn = getActorNode(group);
-        Node pn = getActorNode(member);
-        Person addedMember = null;
-        if (gn != null && pn != null) {
-            getOrCreateRelation(pn, RelationTypes.MEMBER_OF, gn);
-            addedMember = member;
-        }
-        return addedMember;
-    }
-    
-    /**
-     * Delete Person oldMember from Group group.
-     * 
-     * @param group
-     * @param member
-     */
-    public void deleteGroupMember(Group group, Person member) {
-        Node gn = getActorNode(group);
-        Iterable<Relationship> rels = gn.getRelationships(RelationTypes.MEMBER_OF);
-        for (Relationship rel : rels) {
-            Node mn = rel.getStartNode();
-            if (mn.equals(member)) {
-                rel.delete();
-                // there should be only one
-                break;
-            }
-        }        
     }
     
@@ -351,4 +351,14 @@
         return null;
     }
+    
+    public Tag createTagFromNode(Node tagNode) {
+    	String name = (String) tagNode.getProperty("name", null);
+    	String uri = (String) tagNode.getProperty("uri", null);
+    	String id = (String) tagNode.getProperty("id", null);
+    	
+    	return new Tag(id, uri, name);
+		
+	}
+
 
     /**
@@ -466,5 +476,5 @@
                         for (String tag : newTags) {
                             // create new tag
-                            Node tagNode = getOrCreateTagNode(tag);
+                            Node tagNode = getOrCreateTagNode(new Tag(null,null,tag));
                             getOrCreateRelation(annotNode, RelationTypes.HAS_TAG, tagNode);
                         }
@@ -687,6 +697,7 @@
     }
 
-    protected Node getOrCreateTagNode(String tagname) {
+    protected Node getOrCreateTagNode(Tag inTag) {
         Index<Node> idx = getNodeIndex(NodeTypes.TAG);
+        String tagname = inTag.getName();
         IndexHits<Node> tags = idx.get("name", tagname);
         Node tag = tags.getSingle();
@@ -699,4 +710,9 @@
                 tag.setProperty("name", tagname);
                 idx.add(tag, "name", tagname);
+                
+                tag.setProperty("id", inTag.getId());
+                tag.setProperty("uri", inTag.getUri());
+                idx.add(tag, "uri", inTag.getUri());
+                
                 tx.success();
             } finally {
@@ -802,3 +818,19 @@
     }
 
+	public List<Annotation> getAnnotationsByTag(String tagUri) {
+		
+		ArrayList<Annotation> ret = new  ArrayList<Annotation>();
+		Node tag = getTagNodeByUri(tagUri);
+		
+		
+		Iterable<Relationship> rels = tag.getRelationships(Direction.INCOMING,RelationTypes.HAS_TAG);
+		
+		for (Relationship rel:rels){
+			Node node = rel.getStartNode();
+			ret.add(createAnnotationFromNode(node));
+			
+		}
+		return ret;
+	}
+
 }
Index: src/main/java/de/mpiwg/itgroup/annotations/restlet/AnnotatorAnnotationsByTags.java
===================================================================
--- src/main/java/de/mpiwg/itgroup/annotations/restlet/AnnotatorAnnotationsByTags.java	(revision 28)
+++ src/main/java/de/mpiwg/itgroup/annotations/restlet/AnnotatorAnnotationsByTags.java	(revision 28)
@@ -0,0 +1,105 @@
+package de.mpiwg.itgroup.annotations.restlet;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+import org.neo4j.graphdb.Node;
+import org.restlet.data.Form;
+import org.restlet.data.Parameter;
+import org.restlet.data.Status;
+import org.restlet.ext.json.JsonRepresentation;
+import org.restlet.representation.Representation;
+import org.restlet.resource.Get;
+import org.restlet.resource.ServerResource;
+
+import de.mpiwg.itgroup.annotations.Annotation;
+import de.mpiwg.itgroup.annotations.NS;
+import de.mpiwg.itgroup.annotations.Tag;
+import de.mpiwg.itgroup.annotations.neo4j.AnnotationStore;
+import de.mpiwg.itgroup.annotations.restlet.utils.JSONObjectComparator;
+
+/**
+ * API for accessing tags in the Annotation store.
+ * 
+ * @author dwinter
+ *
+ */
+public class AnnotatorAnnotationsByTags extends AnnotatorResourceImpl {
+    protected String getAllowedMethodsForHeader() {
+        return "OPTIONS,GET";
+    }
+    
+    @Get("json")
+    public Representation doGetJSON(Representation entity) {
+        logger.debug("AnnotatorAnnotatonsBytag doGetJSON!");
+        setCorsHeaders();
+       
+        String jsonId = (String) getRequest().getAttributes().get("id");
+        
+        Form form = getRequest().getResourceRef().getQueryAsForm();
+        String sortBy=null;
+        for (Parameter parameter : form) {
+          if (parameter.getName().equals("sortBy")){
+          sortBy =  parameter.getValue();
+          }
+        }
+        
+        //String id = decodeJsonId(jsonId);
+        String id = jsonId;
+        logger.debug("annotation-id=" + id);
+        
+        AnnotationStore store = getAnnotationStore();
+  	  	String tagUri=NS.MPIWG_TAGS_URL+id;
+        List<Annotation> annotations = store.getAnnotationsByTag(tagUri);
+        
+		//JSONArray results = new JSONArray();
+        ArrayList<JSONObject> results = new ArrayList<JSONObject>();
+        
+		for (Annotation annot : annotations) {
+            JSONObject jo = createAnnotatorJson(annot,false);
+            results.add(jo);
+        }
+    
+	if (sortBy!=null){
+		sortAnnotations(results,sortBy);
+	}
+		
+	JSONArray resultsJa = new JSONArray();
+	for (JSONObject result:results){
+		resultsJa.put(result);
+	}
+	
+    // assemble result object
+    JSONObject result = new JSONObject();
+    try {
+        result.put("rows", resultsJa);
+        result.put("total", resultsJa.length());
+    } catch (JSONException e) {
+        setStatus(Status.SERVER_ERROR_INTERNAL, "JSON Error");
+        return null;
+    }
+    logger.debug("sending:");
+    logger.debug(result);
+    return new JsonRepresentation(result);
+}
+
+    
+	/**
+	 * Sortiere array nach einem Parameter in den Annotationen
+	 * @param results
+	 * @return
+	 */
+	private void sortAnnotations(List<JSONObject> results,String attribute) {
+		JSONObjectComparator comp = new JSONObjectComparator(attribute);
+		
+		
+	
+		java.util.Collections.sort( results, comp);
+		
+		
+
+	}        	
+}
Index: src/main/java/de/mpiwg/itgroup/annotations/restlet/AnnotatorRestlet.java
===================================================================
--- src/main/java/de/mpiwg/itgroup/annotations/restlet/AnnotatorRestlet.java	(revision 18)
+++ src/main/java/de/mpiwg/itgroup/annotations/restlet/AnnotatorRestlet.java	(revision 28)
@@ -42,5 +42,8 @@
         router.attach("/search", AnnotatorSearch.class);
         router.attach("/groups", AnnotatorGroups.class);
-
+        router.attach("/tags", AnnotatorTags.class);
+        router.attach("/tags/{id}", AnnotatorTags.class);
+        router.attach("/tags/{id}", AnnotatorTags.class);
+        router.attach("/tags/{id}/annotations", AnnotatorAnnotationsByTags.class);
         router.attach("/", AnnotatorInfo.class);
         // authenticator.setNext(router);
Index: src/main/java/de/mpiwg/itgroup/annotations/restlet/AnnotatorTags.java
===================================================================
--- src/main/java/de/mpiwg/itgroup/annotations/restlet/AnnotatorTags.java	(revision 28)
+++ src/main/java/de/mpiwg/itgroup/annotations/restlet/AnnotatorTags.java	(revision 28)
@@ -0,0 +1,112 @@
+/**
+ * ReST API for accessing groups in the Annotation store.
+ */
+package de.mpiwg.itgroup.annotations.restlet;
+
+import java.util.List;
+
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+import org.neo4j.graphdb.Node;
+import org.restlet.data.Form;
+import org.restlet.data.Status;
+import org.restlet.ext.json.JsonRepresentation;
+import org.restlet.representation.Representation;
+import org.restlet.resource.Get;
+
+import de.mpiwg.itgroup.annotations.Actor;
+import de.mpiwg.itgroup.annotations.Group;
+import de.mpiwg.itgroup.annotations.NS;
+import de.mpiwg.itgroup.annotations.Tag;
+import de.mpiwg.itgroup.annotations.neo4j.AnnotationStore;
+import de.mpiwg.itgroup.annotations.neo4j.AnnotationStore.NodeTypes;
+
+
+/**
+ * API for accessing tags in the Annotation store.
+ * 
+ * @author dwinter
+ *
+ */
+public class AnnotatorTags extends AnnotatorResourceImpl {
+    protected String getAllowedMethodsForHeader() {
+        return "OPTIONS,GET";
+    }
+
+    /**
+     * GET with JSON content-type.
+     * Parameters: 
+     *   user: short user name
+     *   uri: user uri
+     *   
+     * @param entity
+     * @return
+     */
+    @Get("json")
+    public Representation doGetJSON(Representation entity) {
+        logger.debug("AnnotatorGroups doGetJSON!");
+        setCorsHeaders();
+       
+        String jsonId = (String) getRequest().getAttributes().get("id");
+        //String id = decodeJsonId(jsonId);
+        String id = jsonId;
+        logger.debug("annotation-id=" + id);
+
+        if (id==null){
+        return getAllTags();
+        } else {
+
+        	return getTag(id);
+        }
+    }
+    
+    protected Representation getTag(String id){
+    	  AnnotationStore store = getAnnotationStore();
+    	  String tagUri=NS.MPIWG_TAGS_URL+id;
+          Node tagNode = store.getTagNodeByUri(tagUri);
+          Tag tag = store.createTagFromNode(tagNode);
+          JSONObject jo = new JSONObject();
+          try {
+              jo.put("id", tag.getId());
+              jo.put("name", tag.getName());
+              jo.put("uri", tag.getUri());
+          } catch (JSONException e) {
+          }
+          
+          return new JsonRepresentation(jo);
+    }
+	protected Representation getAllTags() {
+		JSONArray results = new JSONArray();
+        AnnotationStore store = getAnnotationStore();
+        
+       
+            List<Tag> tags = store.getTags(null, null);
+            for (Tag tag : tags) {
+                JSONObject jo = new JSONObject();
+                try {
+                    jo.put("id", tag.getId());
+                    jo.put("name", tag.getName());
+                    jo.put("uri", tag.getUri());
+                } catch (JSONException e) {
+                }
+                results.put(jo);
+            }
+        
+        // assemble result object
+        JSONObject result = new JSONObject();
+        try {
+            result.put("rows", results);
+            result.put("total", results.length());
+        } catch (JSONException e) {
+            setStatus(Status.SERVER_ERROR_INTERNAL, "JSON Error");
+            return null;
+        }
+        logger.debug("sending:");
+        logger.debug(result);
+        return new JsonRepresentation(result);
+	}        	
+        
+
+    
+}
Index: src/main/java/de/mpiwg/itgroup/annotations/restlet/annotations_ui/GroupMembersResource.java
===================================================================
--- src/main/java/de/mpiwg/itgroup/annotations/restlet/annotations_ui/GroupMembersResource.java	(revision 27)
+++ src/main/java/de/mpiwg/itgroup/annotations/restlet/annotations_ui/GroupMembersResource.java	(revision 24)
@@ -47,13 +47,11 @@
         result += String.format("<p>Group: %s <a href=\"%s\">(%s)</a></p>\n", group.getName(), groupsUrl, group.getId());
         result += "<p>Members:</p>\n";
-        result += String.format("<form method=\"post\" action=\"%s\">", thisUrl);
         result += "<table>";
         List<Person> members = store.getMembersOfGroup(group);
         for (Person p : members) {
             result += String.format("<tr><td>%s</td><td>(%s)</td>", p.getName(), p.getIdString());
-            result += String.format("<td><input type=\"submit\" name=\"del_member\" value=\"delete:%s\"></td></tr>\n", p.getIdString());
+            //result += String.format("<td></td></tr>\n", p.getName(), p.getIdString());
         }
         result += "</table>\n";
-        result += "</form>\n";
         result += String.format("<form method=\"post\" action=\"%s\">\n", thisUrl);
         result += "<p>Add new member: <select name=\"add_member\">\n";
@@ -87,16 +85,5 @@
             return null;
         }
-        if (addMemberId != null) {
-            logger.debug("adding member: "+addMemberId);
-            Person member = new Person(addMemberId);
-            store.addGroupMember(group, member);
-        } else if (delMemberId != null) {
-            if (delMemberId.startsWith("delete:")) {
-                delMemberId = delMemberId.substring(7);
-            }
-            logger.debug("deleting member: "+delMemberId);
-            Person member = new Person(delMemberId);
-            store.deleteGroupMember(group, member);
-        }
+        
         // return 303: see other
         setStatus(Status.REDIRECTION_SEE_OTHER);
Index: src/main/java/de/mpiwg/itgroup/annotations/restlet/utils/JSONObjectComparator.java
===================================================================
--- src/main/java/de/mpiwg/itgroup/annotations/restlet/utils/JSONObjectComparator.java	(revision 28)
+++ src/main/java/de/mpiwg/itgroup/annotations/restlet/utils/JSONObjectComparator.java	(revision 28)
@@ -0,0 +1,38 @@
+package de.mpiwg.itgroup.annotations.restlet.utils;
+
+import java.util.Comparator;
+
+import de.mpiwg.itgroup.annotations.Annotation;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+
+public class JSONObjectComparator implements Comparator<JSONObject>{
+   
+	private String attributeToSort;
+	public JSONObjectComparator(String attribute){
+		this.attributeToSort=attribute;
+	}
+	
+	public int compare( JSONObject a, JSONObject b ) {
+        // je quadratischer, desto grösser
+		String sortA;
+		try {
+			sortA = a.getString(attributeToSort);
+		} catch (JSONException e) {
+			sortA ="";
+		}
+		String sortB;
+		try {
+			sortB = b.getString(attributeToSort);
+		} catch (JSONException e) {
+			sortB="";
+		}
+        
+		
+        return sortA.compareToIgnoreCase(sortB);
+    }
+        
+  
+	
+}
