Index: src/main/java/de/mpiwg/itgroup/annotations/Actor.java
===================================================================
--- src/main/java/de/mpiwg/itgroup/annotations/Actor.java	(revision 9)
+++ src/main/java/de/mpiwg/itgroup/annotations/Actor.java	(revision 10)
@@ -4,39 +4,21 @@
 package de.mpiwg.itgroup.annotations;
 
+import de.mpiwg.itgroup.annotations.old.NS;
+
 /**
  * @author casties
  *
  */
-public class Actor {
+public abstract class Actor {
 
-    public boolean isGroup;
     public String uri;
     public String name;
+    public String id;
     
     /**
-     * @param isGroup
-     * @param id
-     * @param uri
-     * @param name
+     * @return if this Actor is a Group
      */
-    public Actor(boolean isGroup, String uri, String name) {
-        super();
-        this.isGroup = isGroup;
-        this.uri = uri;
-        this.name = name;
-    }
+    public abstract boolean isGroup();
     
-    /**
-     * @return the isGroup
-     */
-    public boolean isGroup() {
-        return isGroup;
-    }
-    /**
-     * @param isGroup the isGroup to set
-     */
-    public void setGroup(boolean isGroup) {
-        this.isGroup = isGroup;
-    }
     /**
      * @return the uri
@@ -63,3 +45,61 @@
         this.name = name;
     }
+
+    /**
+     * @return the id
+     */
+    public String getId() {
+        return id;
+    }
+    
+    /**
+     * Returns id as a String starting with "group:" for groups.
+     * 
+     * @return
+     */
+    public abstract String getIdString();
+    
+    /**
+     * @param id the id to set
+     */
+    public void setId(String id) {
+        this.id = id;
+    }
+    
+    /**
+     * Returns a short id from an uri.
+     * 
+     * @param uri
+     * @return
+     */
+    public static String getIdFromUri(String uri, boolean isGroup) {
+        String id = null;
+        String prefix = NS.MPIWG_PERSONS_URL;
+        if (isGroup) {
+            prefix = NS.MPIWG_GROUPS_URL;
+        }
+        if (uri != null && uri.startsWith(prefix)) {
+            id = uri.replace(prefix, "");
+        }
+        return id;
+    }
+
+    /**
+     * Returns an uri from a short id.
+     * 
+     * @param id
+     * @return
+     */
+    public static String getUriFromId(String id, boolean isGroup) {
+        String uri = null;
+        String prefix = NS.MPIWG_PERSONS_URL;
+        if (isGroup) {
+            prefix = NS.MPIWG_GROUPS_URL;
+        }
+        if (id != null && ! id.startsWith("http://")) {
+            uri = prefix + id; 
+        }
+        return uri;
+    }
+
 }
Index: src/main/java/de/mpiwg/itgroup/annotations/Annotation.java
===================================================================
--- src/main/java/de/mpiwg/itgroup/annotations/Annotation.java	(revision 9)
+++ src/main/java/de/mpiwg/itgroup/annotations/Annotation.java	(revision 10)
@@ -57,5 +57,27 @@
     protected String created;
 
-    protected String adminPermission;
+    /**
+     * The user or group that has admin permissions.
+     * null means any user.
+     */
+    protected Actor adminPermission;
+    
+    /**
+     * The user or group that has delete permissions.
+     * null means any user.
+     */
+    protected Actor deletePermission;
+    
+    /**
+     * The user or group that has update permissions.
+     * null means any user.
+     */
+    protected Actor updatePermission;
+    
+    /**
+     * The user or group that has read permissions.
+     * null means any user.
+     */
+    protected Actor readPermission;
     
     /**
@@ -190,4 +212,60 @@
         this.created = created;
     }
+
+    /**
+     * @return the adminPermission
+     */
+    public Actor getAdminPermission() {
+        return adminPermission;
+    }
+
+    /**
+     * @param adminPermission the adminPermission to set
+     */
+    public void setAdminPermission(Actor adminPermission) {
+        this.adminPermission = adminPermission;
+    }
+
+    /**
+     * @return the deletePermission
+     */
+    public Actor getDeletePermission() {
+        return deletePermission;
+    }
+
+    /**
+     * @param deletePermission the deletePermission to set
+     */
+    public void setDeletePermission(Actor deletePermission) {
+        this.deletePermission = deletePermission;
+    }
+
+    /**
+     * @return the updatePermission
+     */
+    public Actor getUpdatePermission() {
+        return updatePermission;
+    }
+
+    /**
+     * @param updatePermission the updatePermission to set
+     */
+    public void setUpdatePermission(Actor updatePermission) {
+        this.updatePermission = updatePermission;
+    }
+
+    /**
+     * @return the readPermission
+     */
+    public Actor getReadPermission() {
+        return readPermission;
+    }
+
+    /**
+     * @param readPermission the readPermission to set
+     */
+    public void setReadPermission(Actor readPermission) {
+        this.readPermission = readPermission;
+    }
     
     
Index: src/main/java/de/mpiwg/itgroup/annotations/Group.java
===================================================================
--- src/main/java/de/mpiwg/itgroup/annotations/Group.java	(revision 10)
+++ src/main/java/de/mpiwg/itgroup/annotations/Group.java	(revision 10)
@@ -0,0 +1,28 @@
+/**
+ * 
+ */
+package de.mpiwg.itgroup.annotations;
+
+/**
+ * @author casties
+ *
+ */
+public class Group extends Actor {
+
+    public Group(String id) {
+        this.id = id;
+    }
+
+    @Override
+    public boolean isGroup() {
+        return true;
+    }
+
+    public String getIdString() {
+        if (id == null) {
+            id = getIdFromUri(uri, true);
+        }
+        return "group:" + id;
+    }
+
+}
Index: src/main/java/de/mpiwg/itgroup/annotations/Person.java
===================================================================
--- src/main/java/de/mpiwg/itgroup/annotations/Person.java	(revision 10)
+++ src/main/java/de/mpiwg/itgroup/annotations/Person.java	(revision 10)
@@ -0,0 +1,37 @@
+/**
+ * 
+ */
+package de.mpiwg.itgroup.annotations;
+
+/**
+ * @author casties
+ *
+ */
+public class Person extends Actor {
+
+    public Person(String uri, String name) {
+        super();
+        this.uri = uri;
+        this.name = name;
+    }
+
+    public Person() {
+    }
+
+    public Person(String id) {
+        this.id = id;
+    }
+
+    @Override
+    public boolean isGroup() {
+        return false;
+    }
+
+    public String getIdString() {
+        if (id == null) {
+            id = getIdFromUri(uri, false);
+        }
+        return id;
+    }
+
+}
Index: src/main/java/de/mpiwg/itgroup/annotations/neo4j/AnnotationStore.java
===================================================================
--- src/main/java/de/mpiwg/itgroup/annotations/neo4j/AnnotationStore.java	(revision 9)
+++ src/main/java/de/mpiwg/itgroup/annotations/neo4j/AnnotationStore.java	(revision 10)
@@ -21,4 +21,5 @@
 import de.mpiwg.itgroup.annotations.Annotation;
 import de.mpiwg.itgroup.annotations.Annotation.FragmentTypes;
+import de.mpiwg.itgroup.annotations.Person;
 
 /**
@@ -103,5 +104,5 @@
 			String uri = (String) creatorNode.getProperty("uri", null);
 			String name = (String) creatorNode.getProperty("name", null);
-            Actor creator = new Actor(false, uri, name);
+            Actor creator = new Person(uri, name);
             annot.setCreator(creator);
 			// just the first one
@@ -164,15 +165,10 @@
 
 			/*
-			 * The name of the creator of this annotation.
-			 */
-			String creatorName = annot.getCreatorName();
-
-			/*
-			 * The URI of the creator of this annotation.
-			 */
-			String creatorUri = annot.getCreatorUri();
-			if (creatorUri != null) {
-				Node creator = getOrCreatePersonNode(creatorUri, creatorName);
-				getOrCreateRelation(creator, RelationTypes.CREATED, annotNode);
+			 * The creator of this annotation.
+			 */
+			Actor creator = annot.getCreator();
+			if (creator != null) {
+				Node creatorNode = getOrCreatePersonNode(creator);
+				getOrCreateRelation(creatorNode, RelationTypes.CREATED, annotNode);
 			}
 
@@ -342,5 +338,6 @@
 	}
 
-	protected Node getOrCreatePersonNode(String uri, String name) {
+	protected Node getOrCreatePersonNode(Actor actor) {
+	    /*
 		// Person is identified by URI
 		Index<Node> idx = getNodeIndex(NodeTypes.PERSON);
@@ -364,4 +361,6 @@
 		}
 		return person;
+		*/
+	    return null;
 	}
 
Index: src/main/java/de/mpiwg/itgroup/annotations/old/NS.java
===================================================================
--- src/main/java/de/mpiwg/itgroup/annotations/old/NS.java	(revision 4)
+++ src/main/java/de/mpiwg/itgroup/annotations/old/NS.java	(revision 10)
@@ -3,6 +3,5 @@
 public class NS {
     public static final String MPIWG_PERSONS_URL = "http://entities.mpiwg-berlin.mpg.de/persons/";
-    // public static String
-    // ANNOTATION_TYPE="http://www.w3.org/2000/10/annotationType#";
+    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/";
     public static final String CNT_NS = "http://www.w3.org/2011/content#";
Index: src/main/java/de/mpiwg/itgroup/annotations/restlet/AnnotatorResourceImpl.java
===================================================================
--- src/main/java/de/mpiwg/itgroup/annotations/restlet/AnnotatorResourceImpl.java	(revision 9)
+++ src/main/java/de/mpiwg/itgroup/annotations/restlet/AnnotatorResourceImpl.java	(revision 10)
@@ -37,4 +37,6 @@
 import de.mpiwg.itgroup.annotations.Annotation;
 import de.mpiwg.itgroup.annotations.Annotation.FragmentTypes;
+import de.mpiwg.itgroup.annotations.Group;
+import de.mpiwg.itgroup.annotations.Person;
 import de.mpiwg.itgroup.annotations.neo4j.AnnotationStore;
 import de.mpiwg.itgroup.annotations.old.NS;
@@ -189,16 +191,13 @@
                 // create user object
                 JSONObject userObject = new JSONObject();
+                Actor creator = annot.getCreator();
                 // save creator as uri
-                userObject.put("uri", annot.getCreatorUri());
+                userObject.put("uri", creator.getUri());
                 // make short user id
-                String userId = annot.getCreatorUri();
-                // remove namespace from user uri to get id
-                if (userId != null && userId.startsWith(NS.MPIWG_PERSONS_URL)) {
-                    userId = userId.replace(NS.MPIWG_PERSONS_URL, "");
-                }
+                String userId = creator.getIdString();
                 // set as id
                 userObject.put("id", userId);
                 // get full name
-                String userName = annot.getCreatorName();
+                String userName = creator.getName();
                 if (userName == null) {
                     RestServer restServer = (RestServer) getApplication();
@@ -224,4 +223,37 @@
                 }
             }
+            
+            // permissions
+            JSONObject perms = new JSONObject();
+            jo.put("permissions", perms);
+            // admin
+            JSONArray adminPerms = new JSONArray();
+            perms.put("admin", adminPerms);
+            Actor adminPerm = annot.getAdminPermission();
+            if (adminPerm != null) {
+                adminPerms.put(adminPerm.getIdString());
+            }
+            // delete
+            JSONArray deletePerms = new JSONArray();
+            perms.put("delete", deletePerms);
+            Actor deletePerm = annot.getDeletePermission();
+            if (deletePerm != null) {
+                deletePerms.put(deletePerm.getIdString());
+            }
+            // update
+            JSONArray updatePerms = new JSONArray();
+            perms.put("update", updatePerms);
+            Actor updatePerm = annot.getUpdatePermission();
+            if (updatePerm != null) {
+                updatePerms.put(updatePerm.getIdString());
+            }
+            // read
+            JSONArray readPerms = new JSONArray();
+            perms.put("read", readPerms);
+            Actor readPerm = annot.getReadPermission();
+            if (readPerm != null) {
+                readPerms.put(readPerm.getIdString());
+            }
+            
             // encode Annotation URL (=id) in base64
             String annotUrl = annot.getUri();
@@ -246,5 +278,5 @@
         try {
             for (String xpointer : xpointers) {
-                //String decoded = URLDecoder.decode(xpointer, "utf-8");
+                // String decoded = URLDecoder.decode(xpointer, "utf-8");
                 String decoded = xpointer;
                 Matcher m = rg.matcher(decoded);
@@ -284,5 +316,5 @@
         try {
             for (String xpointer : xpointers) {
-                //String decoded = URLDecoder.decode(xpointer, "utf-8");
+                // String decoded = URLDecoder.decode(xpointer, "utf-8");
                 String decoded = xpointer;
                 Matcher m = rg.matcher(decoded);
@@ -291,4 +323,5 @@
                     {
                         JSONObject jo = new JSONObject();
+                        @SuppressWarnings("unused")
                         String unit = m.group(1);
                         jo.put("x", m.group(2));
@@ -393,14 +426,15 @@
         Actor creator = annot.getCreator();
         if (creator == null) {
-            creator = new Actor(false, null, null);
+            creator = new Person();
             annot.setCreator(creator);
         }
         // username not required, if no username given authuser will be used
         String username = null;
-        String userUri = annot.getCreatorUri();
+        String userUri = creator.getUri();
         if (jo.has("user")) {
             if (jo.get("user") instanceof String) {
                 // user is just a String
                 username = jo.getString("user");
+                creator.setId(username);
                 // TODO: what if username and authUser are different?
             } else {
@@ -408,5 +442,7 @@
                 JSONObject user = jo.getJSONObject("user");
                 if (user.has("id")) {
-                    username = user.getString("id");
+                    String id = user.getString("id");
+                    creator.setId(id);
+                    username = id;
                 }
                 if (user.has("uri")) {
@@ -436,5 +472,5 @@
             creator.setUri(userUri);
         }
-        
+
         if (annot.getCreated() == null) {
             // set creation date
@@ -457,6 +493,49 @@
             annot.setTargetFragment(fragment);
         }
+
+        // permissions
+        if (jo.has("permissions")) {
+            JSONObject permissions = jo.getJSONObject("permissions");
+            if (permissions.has("admin")) {
+                JSONArray perms = permissions.getJSONArray("admin");
+                Actor actor = getActorFromPermissions(perms);
+                annot.setAdminPermission(actor);
+            }
+            if (permissions.has("delete")) {
+                JSONArray perms = permissions.getJSONArray("delete");
+                Actor actor = getActorFromPermissions(perms);
+                annot.setDeletePermission(actor);
+            }
+            if (permissions.has("update")) {
+                JSONArray perms = permissions.getJSONArray("update");
+                Actor actor = getActorFromPermissions(perms);
+                annot.setUpdatePermission(actor);
+            }
+            if (permissions.has("read")) {
+                JSONArray perms = permissions.getJSONArray("read");
+                Actor actor = getActorFromPermissions(perms);
+                annot.setReadPermission(actor);
+            }
+        }
+
         return annot;
     }
 
+    @SuppressWarnings("unused")
+    protected Actor getActorFromPermissions(JSONArray perms) throws JSONException {
+        Actor actor = null;
+        for (int i = 0; i < perms.length(); ++i) {
+            String perm = perms.getString(i);
+            if (perm.toLowerCase().startsWith("group:")) {
+                String groupId = perm.substring(6);
+                actor = new Group(groupId);
+            } else {
+                actor = new Person(perm);
+            }
+            // we just take the first one
+            break;
+        }
+        return actor;
+    }
+
 }
