Index: src/test/java/com/xpn/xwiki/render/XWikiRadeoxRendererTest.java
===================================================================
--- src/test/java/com/xpn/xwiki/render/XWikiRadeoxRendererTest.java	(revision 3976)
+++ src/test/java/com/xpn/xwiki/render/XWikiRadeoxRendererTest.java	(working copy)
@@ -26,6 +26,7 @@
 import com.xpn.xwiki.XWiki;
 import com.xpn.xwiki.XWikiConfig;
 import com.xpn.xwiki.web.XWikiURLFactory;
+import com.xpn.xwiki.api.DocumentAction;
 import com.xpn.xwiki.doc.XWikiDocument;
 
 import java.net.URL;
@@ -88,7 +89,7 @@
 
         Mock mockUrlFactory = mock(XWikiURLFactory.class);
         mockUrlFactory.expects(once()).method("createURL").with(new Constraint[] {
-            eq("Main"), eq("new link"), eq("edit"), eq("parent=Main.WebHome"), ANYTHING, ANYTHING})
+            eq("Main"), eq("new link"), eq(DocumentAction.EDIT), eq("parent=Main.WebHome"), ANYTHING, ANYTHING})
             .will(returnValue(new URL("http://server.com/Main/new link")));
         mockUrlFactory.expects(atLeastOnce()).method("getURL").will(returnValue("/Main/new link"));
         this.context.setURLFactory((XWikiURLFactory) mockUrlFactory.proxy());
Index: src/test/java/com/xpn/xwiki/api/TestAccessLevel.java
===================================================================
--- src/test/java/com/xpn/xwiki/api/TestAccessLevel.java	(revision 0)
+++ src/test/java/com/xpn/xwiki/api/TestAccessLevel.java	(revision 0)
@@ -0,0 +1,135 @@
+package com.xpn.xwiki.api;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import junit.framework.TestCase;
+
+public class TestAccessLevel extends TestCase
+{
+
+    public void testValues()
+    {
+        // test them to be more than the constants defined in the class
+        int expectedCount = 9;
+        AccessLevel[] levels = AccessLevel.values();
+        assertTrue(expectedCount <= levels.length);
+    }
+
+    public void testIsAccessLevelDefined()
+    {
+        String expectedDefined = "login";
+        String expectedUndefined = "logout";
+
+        assertTrue(AccessLevel.isAccessLevelDefined(expectedDefined));
+        assertFalse(AccessLevel.isAccessLevelDefined(expectedUndefined));
+    }
+
+    public void testValueOfString()
+    {
+        AccessLevel expected = AccessLevel.LOGIN;
+        String accessLevelString1 = "login";
+        String accessLevelString2 = "Login";
+        String accessLevelString3 = " login";
+        String accessLevelString4 = "log in";
+        assertSame(expected, AccessLevel.valueOf(accessLevelString1));
+        assertSame(expected, AccessLevel.valueOf(accessLevelString2));
+        assertSame(expected, AccessLevel.valueOf(accessLevelString3));
+        assertNotSame(expected, AccessLevel.valueOf(accessLevelString4));
+
+        ArrayList beforeList = new ArrayList(Arrays.asList(AccessLevel.values()));
+        AccessLevel newAccessLevel1 = AccessLevel.valueOf("testValueOfString1");
+        AccessLevel newAccessLevel2 = AccessLevel.valueOf("testvalueOfString1  ");
+        
+        ArrayList afterList = new ArrayList(Arrays.asList(AccessLevel.values()));
+        List regularAccessLevels = AccessLevel.listRegularAccessLevels();
+        List globalAccessLevels = AccessLevel.listGlobalAccessLevels();
+
+        assertSame(newAccessLevel1, newAccessLevel2);
+        assertFalse(beforeList.contains(newAccessLevel1));
+        assertFalse(regularAccessLevels.contains(newAccessLevel1));
+        assertFalse(globalAccessLevels.contains(newAccessLevel1));
+        assertTrue(afterList.contains(newAccessLevel1));
+    }
+
+    public void testValueOfStringBooleanBoolean()
+    {
+        // same behaviour as the valueOfString
+        AccessLevel expected = AccessLevel.LOGIN;
+        String accessLevelString1 = "login";
+        String accessLevelString2 = "Login";
+        String accessLevelString3 = " login";
+        String accessLevelString4 = "log in";
+        assertSame(expected, AccessLevel.valueOf(accessLevelString1));
+        assertSame(expected, AccessLevel.valueOf(accessLevelString2));
+        assertSame(expected, AccessLevel.valueOf(accessLevelString3));
+        assertNotSame(expected, AccessLevel.valueOf(accessLevelString4));
+
+        // different behaviour
+        ArrayList beforeList = new ArrayList(Arrays.asList(AccessLevel.values()));
+        boolean isRegular = true;
+        boolean isGlobal = false;
+        AccessLevel newAccessLevel =
+            AccessLevel.valueOf("testValueOfStringBooleanBoolean1", isRegular, isGlobal);
+        
+        ArrayList afterList = new ArrayList(Arrays.asList(AccessLevel.values()));
+        List regularAccessLevels = AccessLevel.listRegularAccessLevels();
+        List globalAccessLevels = AccessLevel.listGlobalAccessLevels();
+
+        assertFalse(beforeList.contains(newAccessLevel));
+        assertTrue(regularAccessLevels.contains(newAccessLevel) == isRegular);
+        assertTrue(globalAccessLevels.contains(newAccessLevel) == isGlobal);
+        assertTrue(afterList.contains(newAccessLevel));
+
+        // test can't change existing settings
+        AccessLevel newAccessLevelChange =
+            AccessLevel.valueOf("testValueOfStringBooleanBoolean1", isRegular, isGlobal);
+        assertTrue(regularAccessLevels.contains(newAccessLevelChange) == isRegular);
+        assertTrue(globalAccessLevels.contains(newAccessLevelChange) == isGlobal);
+    }
+
+    public void testListRegularAccessLevels()
+    {
+        List regularAccessLevels = AccessLevel.listRegularAccessLevels();
+        // must have at least edit, view, comment
+        int expectedCount = 3;
+        assertTrue(expectedCount <= regularAccessLevels.size());
+        assertTrue(regularAccessLevels.contains(AccessLevel.EDIT));
+        assertTrue(regularAccessLevels.contains(AccessLevel.VIEW));
+        assertTrue(regularAccessLevels.contains(AccessLevel.COMMENT));
+    }
+
+    public void testListGlobalAccessLevels()
+    {
+        List globalAccessLevels = AccessLevel.listGlobalAccessLevels();
+        // must have at least admin, view, edit, comment, delete, register, programming
+        int expectedCount = 7;
+        assertTrue(expectedCount <= globalAccessLevels.size());
+        assertTrue(globalAccessLevels.contains(AccessLevel.ADMIN));
+        assertTrue(globalAccessLevels.contains(AccessLevel.VIEW));
+        assertTrue(globalAccessLevels.contains(AccessLevel.EDIT));
+        assertTrue(globalAccessLevels.contains(AccessLevel.COMMENT));
+        assertTrue(globalAccessLevels.contains(AccessLevel.DELETE));
+        assertTrue(globalAccessLevels.contains(AccessLevel.REGISTER));
+        assertTrue(globalAccessLevels.contains(AccessLevel.PROGRAMMING));
+    }
+
+    public void testToString()
+    {
+        String expected1 = "login";
+        assertEquals(AccessLevel.LOGIN.toString(), expected1);
+        String expected2 = "testtostring1";
+        assertEquals(AccessLevel.valueOf("testToString1").toString(), expected2);
+        assertEquals(AccessLevel.valueOf("   testToString1 ").toString(), expected2);
+    }
+
+    public void testGetRightString()
+    {
+        String expected1 = "login";
+        assertEquals(AccessLevel.LOGIN.getRightString(), expected1);
+        String expected2 = "testgetrightstring1";
+        assertEquals(AccessLevel.valueOf("testGetRightString1").getRightString(), expected2);
+        assertEquals(AccessLevel.valueOf("   testGetRightString1 ").getRightString(), expected2);
+    }
+}
Index: src/test/java/com/xpn/xwiki/api/TestDocumentAction.java
===================================================================
--- src/test/java/com/xpn/xwiki/api/TestDocumentAction.java	(revision 0)
+++ src/test/java/com/xpn/xwiki/api/TestDocumentAction.java	(revision 0)
@@ -0,0 +1,154 @@
+/*
+ * Copyright 2004-2007, XpertNet SARL, and individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ *
+ *
+ * This distribution includes the following modules:
+ *
+ * http://jakarta.apache.org: velocity, struts, jrcs, commons, etc..
+ * This distribution also includes libraries from the Apache Software
+ * Foundation distributed under the terms of the Apache Software License.
+ * See http://www.opensource.org/licenses/apachepl.php
+ *
+ * http://www.hibernate.org:
+ * This distribution includes libraries from hibernate.org distributed
+ * under the terms of the Lesser General Public License.
+ * See http://www.gnu.org/copyleft/lesser.html
+ *
+ * http://www.junit.org
+ * This distribution includes libraries from junit.org distributed 
+ * under the terms of the Common Public License
+ * See http://www.opensource.org/licenses/cpl.php
+ *
+ * ===================================================================
+ */
+package com.xpn.xwiki.api;
+
+import java.util.Arrays;
+import java.util.Comparator;
+
+import junit.framework.TestCase;
+
+public class TestDocumentAction extends TestCase
+{
+    public void testValues()
+    {
+        //we'll test them to be exactly or more than 38 (maybe some other action has been defined in 
+        //the mean time).
+        DocumentAction[] actions = DocumentAction.values();
+        assertTrue(38 <= actions.length);
+    }
+
+    public void testGetAction()
+    {
+        //lowercase, trimmed
+        String expected = "view";
+        assertEquals(DocumentAction.VIEW.getAction(), expected);
+        String notExpected1 = "View";
+        assertFalse(DocumentAction.VIEW.getAction().equals(notExpected1));
+        String notExpected2 = " view";
+        assertFalse(DocumentAction.VIEW.getAction().equals(notExpected2));
+    }
+
+    public void testValueOf()
+    {
+        DocumentAction expected = DocumentAction.EDIT;
+        DocumentAction actual1 = DocumentAction.valueOf(" edit");
+        DocumentAction actual2 = DocumentAction.valueOf("EDIT");
+        DocumentAction actual3 = DocumentAction.valueOf("edit");
+        //must be THE SAME object
+        assertSame(expected, actual1);
+        assertSame(expected, actual2);
+        assertSame(expected, actual3);
+        
+        //get the values
+        DocumentAction[] existingValues = DocumentAction.values();
+        //now let's create a new action and then ask for it
+        DocumentAction actual4 = DocumentAction.valueOf("editing");
+        //should not be in values
+        Comparator comparator = new Comparator()
+        {
+            public int compare(java.lang.Object da1, java.lang.Object da2)
+            {
+                return da1.hashCode() - da2.hashCode();
+            }
+        };
+        Arrays.sort(existingValues, comparator);
+        int sResult = Arrays.binarySearch(existingValues, actual4, comparator);
+        assertFalse(sResult >= 0);
+        //now get the same value, again and test for the same object
+        DocumentAction actual5 = DocumentAction.valueOf("editing");
+        assertSame(actual4, actual5);
+        DocumentAction actual6 = DocumentAction.valueOf("Editing");
+        assertSame(actual4, actual6);
+    }
+    
+    public void testIsActionDefined() 
+    {
+        //test for an existing action, let's say, view
+        String actionString1 = "view";
+        assertTrue(DocumentAction.isActionDefined(actionString1));
+        String actionString2 = "View";
+        assertTrue(DocumentAction.isActionDefined(actionString2));
+        //create a new action and test for it
+        String actionString3 = "newActionActDefTest";
+        assertFalse(DocumentAction.isActionDefined(actionString3));
+        DocumentAction.valueOf(actionString3);
+        assertTrue(DocumentAction.isActionDefined(actionString3));
+    }
+
+    public void testEqualsObject()
+    {
+        DocumentAction editDA1 = DocumentAction.ADMIN;
+        DocumentAction editDA2 = DocumentAction.valueOf("admin");
+        
+        //of my knowledge this tests using the equals function
+        assertEquals(editDA1, editDA2);
+        
+        //another test: two newly created elements, test for equality
+        DocumentAction newAction1 = DocumentAction.valueOf("newAction");
+        DocumentAction newAction2 = DocumentAction.valueOf(" NewAction ");
+        assertEquals(newAction1, newAction2);
+    }
+    
+    public void testGetAccessLevel() 
+    {
+        DocumentAction loginAction = DocumentAction.LOGIN;
+        AccessLevel expectedAccess = AccessLevel.LOGIN;
+        AccessLevel actualAccess = DocumentAction.getAccessLevel(loginAction);
+        assertSame(expectedAccess, actualAccess);
+        
+        DocumentAction loginAction2 = DocumentAction.valueOf(" login ");
+        AccessLevel actualAccess2 = loginAction2.getAccessLevel();
+        assertSame(expectedAccess, actualAccess2);
+    }
+    
+    public void testValueOfRight() 
+    {
+        //try to change the access level
+        AccessLevel beforeAccess = DocumentAction.getAccessLevel(DocumentAction.LOGIN);
+        DocumentAction.valueOf("login", AccessLevel.ADMIN);
+        AccessLevel afterAccess = DocumentAction.getAccessLevel(DocumentAction.LOGIN);
+        assertSame(beforeAccess, afterAccess);
+        
+        //create a new action with an access level defined
+        DocumentAction theNewAction = DocumentAction.valueOf("testValueOfRight1", AccessLevel.VIEW);
+        AccessLevel actual = DocumentAction.getAccessLevel(theNewAction);
+        assertSame(actual, AccessLevel.VIEW);
+    }
+
+}
Index: src/test/java/com/xpn/xwiki/plugin/zipexplorer/ZipExplorerTest.java
===================================================================
--- src/test/java/com/xpn/xwiki/plugin/zipexplorer/ZipExplorerTest.java	(revision 3976)
+++ src/test/java/com/xpn/xwiki/plugin/zipexplorer/ZipExplorerTest.java	(working copy)
@@ -24,6 +24,7 @@
 import com.xpn.xwiki.XWikiContext;
 import com.xpn.xwiki.objects.classes.ListItem;
 import com.xpn.xwiki.api.Document;
+import com.xpn.xwiki.api.DocumentAction;
 import com.xpn.xwiki.doc.XWikiAttachment;
 import com.xpn.xwiki.doc.XWikiDocument;
 import com.xpn.xwiki.web.XWikiRequest;
@@ -60,23 +61,23 @@
     {
         assertTrue(this.plugin.isValidZipURL(
             "http://server/xwiki/bin/download/Main/Document/zipfile.zip/Directory/File.txt",
-            "download"));
+            DocumentAction.DOWNLOAD));
         assertFalse(this.plugin.isValidZipURL(
             "http://server/xwiki/bin/download/Main/Document/zipfile.zip/Directory/File.txt",
-            "view"));
+            DocumentAction.VIEW));
         assertFalse(this.plugin.isValidZipURL(
-            "http://server/xwiki/bin/download/Main/Document/zipfile.zip", "download"));
+            "http://server/xwiki/bin/download/Main/Document/zipfile.zip", DocumentAction.DOWNLOAD));
         assertFalse(this.plugin.isValidZipURL(
-            "http://server/xwiki/bin/download/Main/Document", "download"));
+            "http://server/xwiki/bin/download/Main/Document", DocumentAction.DOWNLOAD));
 
         // These tests should normally fail but we haven't implemented the check to verify if the
         // ZIP URL points to a file rather than a dir.
         assertTrue(this.plugin.isValidZipURL(
             "http://server/xwiki/bin/download/Main/Document/zipfile.zip/Directory/Dir2/",
-            "download"));
+            DocumentAction.DOWNLOAD));
         assertTrue(this.plugin.isValidZipURL(
             "http://server/xwiki/bin/download/Main/Document/zipfile.zip/Directory/Dir2",
-            "download"));
+            DocumentAction.DOWNLOAD));
     }
 
     public void testDownloadAttachmentWithInvalidZipURL() throws Exception {
@@ -176,10 +177,10 @@
         String urlPrefix = "server/xwiki/bin/download/Main/Document/zipfile.zip";
 
         assertEquals("Directory/File.txt", this.plugin.getFileLocationFromZipURL(
-            urlPrefix + "/Directory/File.txt", "download"));
-        assertEquals("", this.plugin.getFileLocationFromZipURL(urlPrefix, "download"));
+            urlPrefix + "/Directory/File.txt", DocumentAction.DOWNLOAD));
+        assertEquals("", this.plugin.getFileLocationFromZipURL(urlPrefix, DocumentAction.DOWNLOAD));
         assertEquals("Some Directory/File WithSpace.txt",  this.plugin.getFileLocationFromZipURL(
-            urlPrefix + "/Some%20Directory/File%20WithSpace.txt", "download"));
+            urlPrefix + "/Some%20Directory/File%20WithSpace.txt", DocumentAction.DOWNLOAD));
     }
 
     private XWikiDocument createXWikiDocumentWithZipFileAttachment() throws Exception {
@@ -197,7 +198,7 @@
         mockRequest.expects(once()).method("getRequestURI").will(returnValue(url));
         XWikiContext context = new XWikiContext();
         context.setRequest((XWikiRequest) mockRequest.proxy());
-        context.setAction("download");
+        context.setAction(DocumentAction.DOWNLOAD);
         return context;
     }
 
Index: src/main/java/com/xpn/xwiki/render/XWikiWikiBaseRenderer.java
===================================================================
--- src/main/java/com/xpn/xwiki/render/XWikiWikiBaseRenderer.java	(revision 3976)
+++ src/main/java/com/xpn/xwiki/render/XWikiWikiBaseRenderer.java	(working copy)
@@ -25,6 +25,7 @@
 import com.xpn.xwiki.XWiki;
 import com.xpn.xwiki.XWikiContext;
 import com.xpn.xwiki.XWikiException;
+import com.xpn.xwiki.api.DocumentAction;
 import com.xpn.xwiki.doc.XWikiDocument;
 import com.xpn.xwiki.plugin.XWikiPluginManager;
 import com.xpn.xwiki.util.Util;
@@ -96,7 +97,7 @@
         output.append(start);
         if (!doc.isNew()) {
             output.append("<a href=\"");
-            output.append(doc.getURL("view", context));
+            output.append(doc.getURL(DocumentAction.VIEW, context));
             if ((anchor != null)&&(!anchor.equals(""))) {
               output.append("#");
               output.append(anchor);
@@ -108,7 +109,7 @@
             output.append("<span class=\"newtopiclink\">");
             output.append(link);
             output.append("</span><a href=\"");
-            output.append(doc.getURL("edit", context));
+            output.append(doc.getURL(DocumentAction.EDIT, context));
             output.append("?parent=");
             output.append(parentdoc.getFullName());
             output.append("\">?</a>");
Index: src/main/java/com/xpn/xwiki/render/filter/XWikiHeadingFilter.java
===================================================================
--- src/main/java/com/xpn/xwiki/render/filter/XWikiHeadingFilter.java	(revision 3976)
+++ src/main/java/com/xpn/xwiki/render/filter/XWikiHeadingFilter.java	(working copy)
@@ -21,6 +21,8 @@
 
 import com.xpn.xwiki.XWikiContext;
 import com.xpn.xwiki.XWikiException;
+import com.xpn.xwiki.api.AccessLevel;
+import com.xpn.xwiki.api.DocumentAction;
 import com.xpn.xwiki.doc.XWikiDocument;
 import com.xpn.xwiki.render.XWikiRadeoxRenderEngine;
 import com.xpn.xwiki.util.TOCGenerator;
@@ -119,7 +121,8 @@
         // Only show the section edit button for view action and when the user has edit rights on
         // the current document
         boolean showEditButton = false;
-        if (xcontext.getWiki().hasSectionEdit(xcontext) && ("view".equals(xcontext.getAction()))) {
+        if (xcontext.getWiki().hasSectionEdit(xcontext) 
+                && (DocumentAction.VIEW.equals(xcontext.getAction()))) {
             try {
                 // TODO: The user should always be set and never be null when this code gets
                 // executed. Unfortunately this is currently happening. It should be set to XWiki
@@ -129,7 +132,7 @@
                 // document and that doesn't make sense... 
                 if ((doc != null) && ((xcontext.getUser() != null)
                     && xcontext.getWiki().getRightService().hasAccessLevel(
-                    "edit", xcontext.getUser(), doc.getFullName(), xcontext)))
+                    AccessLevel.EDIT, xcontext.getUser(), doc.getFullName(), xcontext)))
                 {
                     showEditButton = true;
                 }
@@ -167,7 +170,7 @@
                     } catch (XWikiException e) {
                     }
 
-                    String url = doc.getURL("edit", editparams.toString(), xcontext);
+                    String url = doc.getURL(DocumentAction.EDIT, editparams.toString(), xcontext);
                     return heading + "<span class='edit_section'>&#91;"
                         + "<a style='text-decoration: none;' title='Edit section: "
                         + text.replaceAll("'", "&#39;") + "' href='" + url + "'>" + "edit"
Index: src/main/java/com/xpn/xwiki/render/macro/ImageMacro.java
===================================================================
--- src/main/java/com/xpn/xwiki/render/macro/ImageMacro.java	(revision 3976)
+++ src/main/java/com/xpn/xwiki/render/macro/ImageMacro.java	(working copy)
@@ -28,6 +28,7 @@
 import org.radeox.macro.parameter.MacroParameter;
 
 import com.xpn.xwiki.XWikiContext;
+import com.xpn.xwiki.api.DocumentAction;
 import com.xpn.xwiki.doc.XWikiDocument;
 import com.xpn.xwiki.render.XWikiRadeoxRenderEngine;
 
@@ -155,14 +156,15 @@
             str.append("<div class=\"img" + halign.trim() + "\">");
         }
         if (link != null) {
-            str.append("<a href=\"" + doc.getAttachmentURL(img, "download", xcontext) + "\">");
+            str.append("<a href=\""
+                + doc.getAttachmentURL(img, DocumentAction.DOWNLOAD, xcontext) + "\">");
         }
         str.append("<img src=\"");
 
         if (img.indexOf("tp://") != -1) {
             str.append(img);
         } else {
-            str.append(doc.getAttachmentURL(img, "download", downloadParams, xcontext));
+            str.append(doc.getAttachmentURL(img, DocumentAction.DOWNLOAD, downloadParams, xcontext));
         }
         str.append("\" ");
         if (heightSpecified) {
Index: src/main/java/com/xpn/xwiki/render/macro/StyleMacro.java
===================================================================
--- src/main/java/com/xpn/xwiki/render/macro/StyleMacro.java	(revision 3976)
+++ src/main/java/com/xpn/xwiki/render/macro/StyleMacro.java	(working copy)
@@ -31,6 +31,7 @@
 
 import com.xpn.xwiki.XWikiContext;
 import com.xpn.xwiki.XWikiException;
+import com.xpn.xwiki.api.DocumentAction;
 import com.xpn.xwiki.doc.XWikiDocument;
 import com.xpn.xwiki.doc.XWikiAttachment;
 import com.xpn.xwiki.render.XWikiRadeoxRenderEngine;
@@ -94,7 +95,7 @@
         XWikiAttachment image = doc.getAttachment(icon);
         String path = "";
         if (image != null) {
-            path = doc.getAttachmentURL(icon, "download", xcontext);
+            path = doc.getAttachmentURL(icon, DocumentAction.DOWNLOAD, xcontext);
         } else {
             icon = "icons/" + icon; // icons default directory that contain icon image. 
             path = xcontext.getWiki().getSkinFile(icon, xcontext);
Index: src/main/java/com/xpn/xwiki/render/macro/AttachMacro.java
===================================================================
--- src/main/java/com/xpn/xwiki/render/macro/AttachMacro.java	(revision 3976)
+++ src/main/java/com/xpn/xwiki/render/macro/AttachMacro.java	(working copy)
@@ -30,6 +30,7 @@
 import org.radeox.util.Encoder;
 
 import com.xpn.xwiki.XWikiContext;
+import com.xpn.xwiki.api.DocumentAction;
 import com.xpn.xwiki.doc.XWikiDocument;
 import com.xpn.xwiki.render.XWikiRadeoxRenderEngine;
 
@@ -125,7 +126,7 @@
         if (filename.indexOf("tp://") != -1) {
             str.append(filename);
         } else {
-            str.append(doc.getAttachmentURL(filename, "download", xcontext));
+            str.append(doc.getAttachmentURL(filename, DocumentAction.DOWNLOAD, xcontext));
         }
         str.append("\"");
         if (rel != null) {
Index: src/main/java/com/xpn/xwiki/render/XWikiRadeoxRenderEngine.java
===================================================================
--- src/main/java/com/xpn/xwiki/render/XWikiRadeoxRenderEngine.java	(revision 3976)
+++ src/main/java/com/xpn/xwiki/render/XWikiRadeoxRenderEngine.java	(working copy)
@@ -23,6 +23,7 @@
 package com.xpn.xwiki.render;
 
 import com.xpn.xwiki.XWikiContext;
+import com.xpn.xwiki.api.DocumentAction;
 import com.xpn.xwiki.doc.XWikiDocument;
 import com.xpn.xwiki.render.filter.XWikiFilter;
 import com.xpn.xwiki.util.Util;
@@ -211,7 +212,7 @@
                  addLinkToContext(newdoc.getFullName(), context);
 
                 URL url = context.getURLFactory().createURL(newdoc.getSpace(), newdoc.getName(),
-                        "view", querystring, anchor, context);
+                        DocumentAction.VIEW, querystring, anchor, context);
                 buffer.append(context.getURLFactory().getURL(url, context));
                 buffer.append("\">");
                 buffer.append(view);
@@ -296,7 +297,7 @@
                 querystring += "&editor=" + editor;
 
             URL url = context.getURLFactory().createURL(newdoc.getSpace(), newdoc.getName(),
-                    "edit", querystring, null, context);
+                    DocumentAction.EDIT, querystring, null, context);
             String surl = context.getURLFactory().getURL(url, context);
             buffer.append("<a class=\"wikicreatelink\" href=\"");
             buffer.append(surl);
Index: src/main/java/com/xpn/xwiki/XWikiContext.java
===================================================================
--- src/main/java/com/xpn/xwiki/XWikiContext.java	(revision 3976)
+++ src/main/java/com/xpn/xwiki/XWikiContext.java	(working copy)
@@ -30,6 +30,7 @@
 import org.apache.commons.collections.map.LRUMap;
 import org.apache.xmlrpc.server.XmlRpcServer;
 
+import com.xpn.xwiki.api.DocumentAction;
 import com.xpn.xwiki.doc.XWikiDocument;
 import com.xpn.xwiki.objects.classes.BaseClass;
 import com.xpn.xwiki.user.api.XWikiUser;
@@ -58,7 +59,7 @@
    private XWikiRequest request;
    private XWikiResponse response;
    private XWikiForm form;
-   private String action;
+   private DocumentAction action;
    private String orig_database;
    private String database;
    private boolean virtual;
@@ -118,11 +119,17 @@
         this.request = request;
     }
 
+    /*
     public String getAction() {
         return action;
     }
+    */
+    
+    public DocumentAction getAction() {
+        return this.action;
+    }
 
-    public void setAction(String action) {
+    public void setAction(DocumentAction action) {
         this.action = action;
     }
 
@@ -308,7 +315,7 @@
         return archiveCache.get(key);
     }
 
-    public void setLinksAction(String action) {
+    public void setLinksAction(DocumentAction action) {
         put("links_action", action);
     }
 
@@ -316,8 +323,8 @@
         remove("links_action");
     }
 
-    public String getLinksAction() {
-        return (String) get("links_action");
+    public DocumentAction getLinksAction() {
+        return (DocumentAction) get("links_action");
     }
 
     public void setLinksQueryString(String value) {
Index: src/main/java/com/xpn/xwiki/monitor/api/MonitorData.java
===================================================================
--- src/main/java/com/xpn/xwiki/monitor/api/MonitorData.java	(revision 3976)
+++ src/main/java/com/xpn/xwiki/monitor/api/MonitorData.java	(working copy)
@@ -24,6 +24,8 @@
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
+import com.xpn.xwiki.api.DocumentAction;
+
 import java.net.URL;
 import java.util.*;
 
@@ -32,7 +34,7 @@
 
     private URL url;
     private String wikiPage;
-    private String action;
+    private DocumentAction action;
     private String threadName;
     private Date startTime;
     private Date endTime;
@@ -41,7 +43,7 @@
     private Map timerSummaries = new HashMap();
     private List timerList = new ArrayList();
 
-    public MonitorData(String wikiPage, String action, URL url, String threadName) {
+    public MonitorData(String wikiPage, DocumentAction action, URL url, String threadName) {
         this.setWikiPage(wikiPage);
         this.setURL(url);
         this.setThreadName(threadName);
@@ -164,7 +166,7 @@
           }
           tsummary.addTimer(timer.getDuration());
             if (log.isDebugEnabled()) {
-                   log.debug("MONITOR " + wikiPage + " " + action + " " + timer.getName() + ": " + timer.getDuration() + "ms " + timer.getDetails());
+                   log.debug("MONITOR " + wikiPage + " " + action.toString() + " " + timer.getName() + ": " + timer.getDuration() + "ms " + timer.getDetails());
             }
         }
     }
@@ -183,7 +185,7 @@
             Iterator it = timerSummaries.values().iterator();
             while (it.hasNext()) {
                 MonitorTimerSummary tsummary = (MonitorTimerSummary) it.next();
-                log.debug("MONITOR " + wikiPage + " " + action + " " + tsummary.getName() + ": " + tsummary.getDuration() + "ms " + tsummary.getNbCalls());
+                log.debug("MONITOR " + wikiPage + " " + action.toString() + " " + tsummary.getName() + ": " + tsummary.getDuration() + "ms " + tsummary.getNbCalls());
             }
         }
     }
@@ -204,11 +206,11 @@
          return tsummary.getNbCalls();
     }
     
-    public String getAction() {
+    public DocumentAction getAction() {
         return action;
     }
 
-    public void setAction(String action) {
+    public void setAction(DocumentAction action) {
         this.action = action;
     }
 
@@ -217,7 +219,7 @@
         str.append("WikiPage: ");
         str.append(wikiPage);
         str.append(" Action: ");
-        str.append(action);
+        str.append(action.toString());
         str.append(" URL: ");
         str.append(url.toString());
         str.append(" Thread: ");
Index: src/main/java/com/xpn/xwiki/monitor/api/MonitorPlugin.java
===================================================================
--- src/main/java/com/xpn/xwiki/monitor/api/MonitorPlugin.java	(revision 3976)
+++ src/main/java/com/xpn/xwiki/monitor/api/MonitorPlugin.java	(working copy)
@@ -22,6 +22,7 @@
 package com.xpn.xwiki.monitor.api;
 
 import com.xpn.xwiki.XWikiContext;
+import com.xpn.xwiki.api.DocumentAction;
 import com.xpn.xwiki.plugin.XWikiDefaultPlugin;
 import org.apache.commons.collections.buffer.CircularFifoBuffer;
 import org.apache.commons.logging.Log;
@@ -68,7 +69,7 @@
         return "monitor";
     }
 
-    public void startRequest(String page, String action, URL url) {
+    public void startRequest(String page, DocumentAction action, URL url) {
         if (isActive()==false)
             return;
 
Index: src/main/java/com/xpn/xwiki/objects/classes/LevelsClass.java
===================================================================
--- src/main/java/com/xpn/xwiki/objects/classes/LevelsClass.java	(revision 3976)
+++ src/main/java/com/xpn/xwiki/objects/classes/LevelsClass.java	(working copy)
@@ -36,7 +36,7 @@
 
         XWikiRequest req = context.getRequest();
         if (("editrights".equals(req.get("xpage")) || "rights".equals(req.get("editor")))
-		&&(!"1".equals(req.get("global")))) {
+            &&(!"1".equals(req.get("global")))) {
             list.remove("admin");
             list.remove("programming");
             list.remove("delete");
Index: src/main/java/com/xpn/xwiki/store/XWikiHibernateStore.java
===================================================================
--- src/main/java/com/xpn/xwiki/store/XWikiHibernateStore.java	(revision 3976)
+++ src/main/java/com/xpn/xwiki/store/XWikiHibernateStore.java	(working copy)
@@ -22,6 +22,7 @@
 import com.xpn.xwiki.XWiki;
 import com.xpn.xwiki.XWikiContext;
 import com.xpn.xwiki.XWikiException;
+import com.xpn.xwiki.api.DocumentAction;
 import com.xpn.xwiki.doc.XWikiAttachment;
 import com.xpn.xwiki.doc.XWikiDocument;
 import com.xpn.xwiki.doc.XWikiLink;
@@ -1798,7 +1799,7 @@
 
                 XWikiDocument doc = new XWikiDocument((String)result[0], (String)result[1]);
                 if (checkRight) {
-                    if (context.getWiki().getRightService().checkAccess("view", doc, context)==false)
+                    if (context.getWiki().getRightService().checkAccess(DocumentAction.VIEW, doc, context)==false)
                         continue;
                 }
 
Index: src/main/java/com/xpn/xwiki/XWikiInterface.java
===================================================================
--- src/main/java/com/xpn/xwiki/XWikiInterface.java	(revision 3976)
+++ src/main/java/com/xpn/xwiki/XWikiInterface.java	(working copy)
@@ -21,6 +21,7 @@
 
 package com.xpn.xwiki;
 
+import com.xpn.xwiki.api.DocumentAction;
 import com.xpn.xwiki.api.User;
 import com.xpn.xwiki.doc.XWikiDocument;
 import com.xpn.xwiki.notify.XWikiNotificationManager;
@@ -211,8 +212,15 @@
 
     XWikiUser checkAuth(XWikiContext context) throws XWikiException;
 
+    /**
+     * @deprecated use
+     *             {@link XWikiInterface#checkAccess(DocumentAction, XWikiDocument, XWikiContext)}
+     */
     boolean checkAccess(String action, XWikiDocument doc, XWikiContext context)
             throws XWikiException;
+    
+    boolean checkAccess(DocumentAction action, XWikiDocument doc, XWikiContext context)
+            throws XWikiException;
 
     String include(String topic, XWikiContext context, boolean isForm) throws XWikiException;
 
@@ -246,11 +254,24 @@
     String getEncoding();
 
     URL getServerURL(String database, XWikiContext context) throws MalformedURLException;
-
+    
+    /**
+     * @deprecated use {@link XWikiInterface#getURL(String, DocumentAction, XWikiContext)}
+     */
     String getURL(String fullname, String action, XWikiContext context) throws XWikiException;
 
-    String getURL(String fullname, String action, String querystring, XWikiContext context) throws XWikiException;
+    String getURL(String fullname, DocumentAction action, XWikiContext context)
+        throws XWikiException;
 
+    /**
+     * @deprecated use {@link XWikiInterface#getURL(String, DocumentAction, String, XWikiContext)}
+     */
+    String getURL(String fullname, String action, String querystring, XWikiContext context)
+        throws XWikiException;
+
+    String getURL(String fullname, DocumentAction action, String querystring, XWikiContext context)
+        throws XWikiException;
+
     // Usefull date functions
     Date getCurrentDate();
 
Index: src/main/java/com/xpn/xwiki/stats/impl/DocumentStats.java
===================================================================
--- src/main/java/com/xpn/xwiki/stats/impl/DocumentStats.java	(revision 3976)
+++ src/main/java/com/xpn/xwiki/stats/impl/DocumentStats.java	(working copy)
@@ -22,12 +22,18 @@
 package com.xpn.xwiki.stats.impl;
 
 import java.util.Date;
+
+import com.xpn.xwiki.api.DocumentAction;
 
 public class DocumentStats extends XWikiStats {
 
     public DocumentStats() {
     }
-
+
+    /**
+     * @see DocumentStats#DocumentStats(String, DocumentAction, Date, int)
+     * @deprecated use {@link DocumentStats#DocumentStats(String, DocumentAction, Date, int)} 
+     */
     public DocumentStats(String docName, String action, Date period, int periodtype) {
         super(period, periodtype);
         setName(docName);
@@ -35,7 +41,16 @@
         String nb = action + getPeriod();
         setNumber(nb.hashCode());
         setAction(action);
-    }
+    }
+    
+    public DocumentStats(String docName, DocumentAction action, Date period, int periodtype) {
+        super(period, periodtype);
+        setName(docName);
+        setClassName("internal");
+        String nb = action.toString() + getPeriod();
+        setNumber(nb.hashCode());
+        setAction(action.toString());
+    }    
 
     public String getAction() {
         return getStringValue("action");
Index: src/main/java/com/xpn/xwiki/stats/impl/XWikiStatsServiceImpl.java
===================================================================
--- src/main/java/com/xpn/xwiki/stats/impl/XWikiStatsServiceImpl.java	(revision 3976)
+++ src/main/java/com/xpn/xwiki/stats/impl/XWikiStatsServiceImpl.java	(working copy)
@@ -23,6 +23,7 @@
 
 import com.xpn.xwiki.XWikiContext;
 import com.xpn.xwiki.XWikiException;
+import com.xpn.xwiki.api.DocumentAction;
 import com.xpn.xwiki.doc.XWikiDocument;
 import com.xpn.xwiki.notify.XWikiActionRule;
 import com.xpn.xwiki.notify.XWikiNotificationRule;
@@ -76,15 +77,33 @@
     }
 
     /**
+     * @see XWikiStatsServiceImpl#getDocTotalStats(String, DocumentAction, XWikiContext)
+     * @deprecated use {@link XWikiStatsServiceImpl#getDocTotalStats(String, DocumentAction, XWikiContext)}
+     */
+    public DocumentStats getDocTotalStats(String docname, String action, XWikiContext context) {
+        DocumentAction documentAction = DocumentAction.valueOf(action);
+        return this.getDocTotalStats(docname, documentAction, context);
+    }
+    
+    /**
      * Gets total statistics on a document for a specific action
      *
      * @param docname fully qualified document named
      * @param action can be "view", "edit", "save", etc..
      * @param context
      * @return DocStats - statistics object
+     */    
+    public DocumentStats getDocTotalStats(String docname, DocumentAction action, XWikiContext context) {
+        return new DocumentStats();
+    }    
+
+    /**
+     * @see XWikiStatsServiceImpl#getDocMonthStats(String, DocumentAction, Date, XWikiContext)
+     * @deprecated use {@link XWikiStatsServiceImpl#getDocMonthStats(String, DocumentAction, Date, XWikiContext)}
      */
-    public DocumentStats getDocTotalStats(String docname, String action, XWikiContext context) {
-        return new DocumentStats();
+    public DocumentStats getDocMonthStats(String docname, String action, Date month, XWikiContext context) {
+        DocumentAction documentAction = DocumentAction.valueOf(action);
+        return this.getDocMonthStats(docname, documentAction, month, context);
     }
 
     /**
@@ -95,7 +114,7 @@
      * @param context
      * @return
      */
-    public DocumentStats getDocMonthStats(String docname, String action, Date month, XWikiContext context) {
+    public DocumentStats getDocMonthStats(String docname, DocumentAction action, Date month, XWikiContext context) {
         XWikiHibernateStore store = context.getWiki().getHibernateStore();
         DocumentStats object = new DocumentStats(docname, action, month, XWikiStats.PERIOD_MONTH);
         try {
@@ -104,20 +123,29 @@
         } catch (XWikiException e) {
             e.printStackTrace();
             return new DocumentStats();
-        }
+        }        
     }
 
     /**
+     * @see XWikiStatsServiceImpl#getDocDayStats(String, DocumentAction, Date, XWikiContext)
+     * @deprecated use {@link XWikiStatsServiceImpl#getDocDayStats(String, DocumentAction, Date, XWikiContext)} 
+     */
+    public DocumentStats getDocDayStats(String docname, String action, Date day, XWikiContext context) {
+        DocumentAction documentAction = DocumentAction.valueOf(action);
+        return this.getDocDayStats(docname, documentAction, day, context);
+    }
+    
+    /**
      * Gets daily statistics on a document for a specific action
      * @param docname
      * @param action
      * @param day
      * @param context
      * @return
-     */
-    public DocumentStats getDocDayStats(String docname, String action, Date day, XWikiContext context) {
+     */    
+    public DocumentStats getDocDayStats(String docname, DocumentAction action, Date day, XWikiContext context) {
         return new DocumentStats();
-    }
+    }    
 
     public List getRefMonthStats(String docname, Date month, XWikiContext context) throws XWikiException {
     	XWikiStoreInterface store = context.getWiki().getNotCacheStore();
@@ -129,12 +157,20 @@
     	}
         return solist;
     }
+    
+    /**
+     * @deprecated use {@link XWikiStatsServiceImpl#getRecentActions(DocumentAction, int, XWikiContext)}
+     */
+    public Collection getRecentActions(String action, int size, XWikiContext context) {
+        DocumentAction documentAction = DocumentAction.valueOf(action);
+        return this.getRecentActions(documentAction, size, context);
+    }
 
-    public Collection getRecentActions(String action, int size, XWikiContext context) {
+    public Collection getRecentActions(DocumentAction action, int size, XWikiContext context) {
         ArrayList list = new ArrayList();
-        if ((action.equals("view")||(action.equals("save")))) {
+        if ((action.equals(DocumentAction.VIEW)||(action.equals(DocumentAction.SAVE)))) {
             HttpSession session = context.getRequest().getSession();
-            Collection actions = (Collection) session.getAttribute("recent_" + action);
+            Collection actions = (Collection) session.getAttribute("recent_" + action.toString());
 
             if (actions!=null) {
                Object[] actionsarray = actions.toArray();
@@ -154,24 +190,25 @@
      * @param action
      * @param context
      */
-    public void notify(XWikiNotificationRule rule, XWikiDocument doc, String action, XWikiContext context) {
+    public void notify(XWikiNotificationRule rule, XWikiDocument doc, DocumentAction action, XWikiContext context) {
 
         if (context.getWiki().isReadOnly()) {
             // the server is in read-only mode, forget about the statistics
             return;
         }
         // Unless this is a "view", "save" or "download" action, we are not interested
-        if (!(action.equals("view")||action.equals("save")||action.equals("download")))
+        if (!(action.equals(DocumentAction.VIEW)||action.equals(DocumentAction.SAVE)
+            ||action.equals(DocumentAction.DOWNLOAD)))
             return;
 
         // Let's save in the session the last elements view, saved
         synchronized (this) {
-            if (!action.equals("download")) {
+            if (!action.equals(DocumentAction.DOWNLOAD)) {
                 HttpSession session = context.getRequest().getSession();
-                Collection actions = (Collection) session.getAttribute("recent_" + action);
+                Collection actions = (Collection) session.getAttribute("recent_" + action.toString());
                 if (actions==null) {
                     actions = new CircularFifoBuffer(context.getWiki().getXWikiPreferenceAsInt("recent_visits_size", 20, context));
-                    session.setAttribute("recent_" + action, actions);
+                    session.setAttribute("recent_" + action.toString(), actions);
                 }
                 String element = context.getDatabase() + ":" + doc.getFullName();
                 if (actions.contains(element))
@@ -194,12 +231,12 @@
 
         VisitStats vobject = findVisit(context);
             // We count page views in the sessions only for the "view" action
-            if (action.equals("view"))
+            if (action.equals(DocumentAction.VIEW))
                 vobject.incPageViews();
             // We count "save" and "download" actions separately
-            else if (action.equals("save"))
+            else if (action.equals(DocumentAction.SAVE))
                 vobject.incPageSaves();
-            else if (action.equals("download"))
+            else if (action.equals(DocumentAction.DOWNLOAD))
                 vobject.incDownloads();
 
             vobject.setEndDate(new Date());
@@ -230,7 +267,7 @@
         addPageView("", action, XWikiStats.PERIOD_DAY, store, context, vobject);
 
         // In case of a "view" action we want to store referer info
-        if (action.equals("view")) {
+        if (action.equals(DocumentAction.VIEW)) {
             String referer = getReferer(context);
             if ((referer !=null)&&(!referer.equals(""))) {
                 // Visits of the web
@@ -253,7 +290,7 @@
 
     }
 
-    private void addPageView(String docname, String action, int periodtype, XWikiHibernateStore store, XWikiContext context, VisitStats vobject) {
+    private void addPageView(String docname, DocumentAction action, int periodtype, XWikiHibernateStore store, XWikiContext context, VisitStats vobject) {
         DocumentStats object;
         object = new DocumentStats(docname, action, new Date(), periodtype);
         try {
@@ -264,7 +301,7 @@
 
         // Visits are only for viewing pages
         if (docname.equals("")) {
-         if ((vobject.getPageViews()==1)&&(action.equals("view"))) {
+         if ((vobject.getPageViews()==1)&&(action.equals(DocumentAction.VIEW))) {
             object.incVisits();
          }
         }
Index: src/main/java/com/xpn/xwiki/stats/api/XWikiStatsService.java
===================================================================
--- src/main/java/com/xpn/xwiki/stats/api/XWikiStatsService.java	(revision 3976)
+++ src/main/java/com/xpn/xwiki/stats/api/XWikiStatsService.java	(working copy)
@@ -23,6 +23,7 @@
 
 import com.xpn.xwiki.XWikiContext;
 import com.xpn.xwiki.XWikiException;
+import com.xpn.xwiki.api.DocumentAction;
 import com.xpn.xwiki.notify.XWikiActionNotificationInterface;
 import com.xpn.xwiki.stats.impl.DocumentStats;
 
@@ -32,9 +33,25 @@
 
 public interface XWikiStatsService extends XWikiActionNotificationInterface {
     public void init(XWikiContext context);
+    /**
+     * @deprecated use {@link XWikiStatsService#getDocTotalStats(String, DocumentAction, XWikiContext)} 
+     */
     public DocumentStats getDocTotalStats(String docname, String action, XWikiContext context);
+    public DocumentStats getDocTotalStats(String docname, DocumentAction action, XWikiContext context);
+    /**
+     * @deprecated use {@link XWikiStatsService#getDocMonthStats(String, DocumentAction, Date, XWikiContext)} 
+     */
     public DocumentStats getDocMonthStats(String docname, String action, Date month, XWikiContext context);
+    public DocumentStats getDocMonthStats(String docname, DocumentAction action, Date month, XWikiContext context);
+    /**
+     * @deprecated {@link XWikiStatsService#getDocDayStats(String, DocumentAction, Date, XWikiContext)} 
+     */
     public DocumentStats getDocDayStats(String docname, String action, Date day, XWikiContext context);
+    public DocumentStats getDocDayStats(String docname, DocumentAction action, Date day, XWikiContext context);
     public List getRefMonthStats(String docName, Date month, XWikiContext context) throws XWikiException;
+    /**
+     * @deprecated use {@link XWikiStatsService#getRecentActions(DocumentAction, int, XWikiContext)} 
+     */
     public Collection getRecentActions(String action, int size, XWikiContext context);
+    public Collection getRecentActions(DocumentAction action, int size, XWikiContext context);
 }
Index: src/main/java/com/xpn/xwiki/plugin/zipexplorer/ZipExplorerPlugin.java
===================================================================
--- src/main/java/com/xpn/xwiki/plugin/zipexplorer/ZipExplorerPlugin.java	(revision 3976)
+++ src/main/java/com/xpn/xwiki/plugin/zipexplorer/ZipExplorerPlugin.java	(working copy)
@@ -40,6 +40,7 @@
 import com.xpn.xwiki.api.Api;
 import com.xpn.xwiki.api.Attachment;
 import com.xpn.xwiki.api.Document;
+import com.xpn.xwiki.api.DocumentAction;
 import com.xpn.xwiki.doc.XWikiAttachment;
 import com.xpn.xwiki.objects.classes.ListItem;
 import com.xpn.xwiki.plugin.XWikiDefaultPlugin;
@@ -114,12 +115,12 @@
         // Verify if we should return the original attachment. This will happen if the requested
         // download URL doesn't point to a zip or if the URL doesn't point to a file inside the ZIP.
         if (!isZipFile(attachment.getFilename())
-            || !isValidZipURL(url, context.getAction().trim()))
+            || !isValidZipURL(url, context.getAction()))
         {
             return attachment;
         }
 
-        String filename = getFileLocationFromZipURL(url, context.getAction().trim());
+        String filename = getFileLocationFromZipURL(url, context.getAction());
 
         // Create the new attachment pointing to the file inside the ZIP
         XWikiAttachment newAttachment = new XWikiAttachment();
@@ -257,7 +258,7 @@
 
     /**
      * @param url the URL to parse and from which to extract the relative file location
-     * @param action the XWiki requested action (for example "download", "edit", "view", etc).
+     * @param action the XWiki requested action.
      * @return the relative file location of a file in the ZIP file pointed to by the passed URL.
      *         The ZIP URL must be of the format
      *         <code>http://[...]/zipfile.zip/SomeDirectory/SomeFile.txt</code>.
@@ -268,9 +269,10 @@
      *       manipulation. Once this exists remove this code.
      *       See http://jira.xwiki.org/jira/browse/XWIKI-437
      */
-    protected String getFileLocationFromZipURL(String url, String action)
+    protected String getFileLocationFromZipURL(String url, DocumentAction action)
     {
-        String path = url.substring(url.indexOf(URL_SEPARATOR + action));
+        String actionString = action.toString();
+        String path = url.substring(url.indexOf(URL_SEPARATOR + actionString));
         int pos = 0;
         for (int i = 0; pos > -1 && i < 4; i++) {
             pos = path.indexOf(URL_SEPARATOR, pos + 1);
@@ -305,10 +307,10 @@
 
     /**
      * @param url the ZIP URL to check
-     * @param action the XWiki requested action (for example "download", "edit", "view", etc).
+     * @param action the XWiki requested action.
      * @return true if the ZIP URL points to a file inside the ZIP or false otherwise
      */
-    protected boolean isValidZipURL(String url, String action)
+    protected boolean isValidZipURL(String url, DocumentAction action)
     {
         boolean isValidZipURL = false;
         try {
Index: src/main/java/com/xpn/xwiki/plugin/packaging/DocumentInfo.java
===================================================================
--- src/main/java/com/xpn/xwiki/plugin/packaging/DocumentInfo.java	(revision 3976)
+++ src/main/java/com/xpn/xwiki/plugin/packaging/DocumentInfo.java	(working copy)
@@ -23,6 +23,7 @@
 
 import com.xpn.xwiki.XWikiContext;
 import com.xpn.xwiki.XWikiException;
+import com.xpn.xwiki.api.DocumentAction;
 import com.xpn.xwiki.doc.XWikiDocument;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
@@ -105,7 +106,7 @@
             if (this.doc == null)
                 return installable;
             try {
-                if ((!isAdmin)&&(!context.getWiki().checkAccess("edit", this.doc, context)))
+                if ((!isAdmin)&&(!context.getWiki().checkAccess(DocumentAction.EDIT, this.doc, context)))
                     return installable;
                 XWikiDocument doc1 = context.getWiki().getDocument(doc.getFullName(), context);
                 boolean isNew = doc1.isNew();
Index: src/main/java/com/xpn/xwiki/plugin/packaging/Package.java
===================================================================
--- src/main/java/com/xpn/xwiki/plugin/packaging/Package.java	(revision 3976)
+++ src/main/java/com/xpn/xwiki/plugin/packaging/Package.java	(working copy)
@@ -50,6 +50,7 @@
 import com.xpn.xwiki.XWiki;
 import com.xpn.xwiki.XWikiContext;
 import com.xpn.xwiki.XWikiException;
+import com.xpn.xwiki.api.DocumentAction;
 import com.xpn.xwiki.doc.XWikiDocument;
 import com.xpn.xwiki.objects.classes.BaseClass;
 
@@ -187,7 +188,7 @@
     public boolean add(XWikiDocument doc, int defaultAction, XWikiContext context)
         throws XWikiException
     {
-        if (!context.getWiki().checkAccess("edit", doc, context)) {
+        if (!context.getWiki().checkAccess(DocumentAction.EDIT, doc, context)) {
             return false;
         }
         for (int i = 0; i < files.size(); i++) {
Index: src/main/java/com/xpn/xwiki/plugin/charts/actions/CreateChartAction.java
===================================================================
--- src/main/java/com/xpn/xwiki/plugin/charts/actions/CreateChartAction.java	(revision 3976)
+++ src/main/java/com/xpn/xwiki/plugin/charts/actions/CreateChartAction.java	(working copy)
@@ -22,6 +22,7 @@
 
 import com.xpn.xwiki.XWikiContext;
 import com.xpn.xwiki.XWikiException;
+import com.xpn.xwiki.api.DocumentAction;
 import com.xpn.xwiki.doc.XWikiDocument;
 import com.xpn.xwiki.plugin.charts.RadeoxHelper;
 import com.xpn.xwiki.plugin.charts.exceptions.ParamException;
@@ -55,7 +56,7 @@
         doc.setContent(doc.getContent()+"\n\n"+chartRadeoxMacro);
         context.getWiki().saveDocument(doc, context);
 		try {
-			response.sendRedirect(doc.getURL("view", true, context));
+			response.sendRedirect(doc.getURL(DocumentAction.VIEW, true, context));
 		} catch(IOException ex) {
         	throw new XWikiException(XWikiException.MODULE_XWIKI_PLUGINS,
         			XWikiException.ERROR_XWIKI_UNKNOWN, ex.getMessage(), ex);
Index: src/main/java/com/xpn/xwiki/plugin/charts/ChartingPlugin.java
===================================================================
--- src/main/java/com/xpn/xwiki/plugin/charts/ChartingPlugin.java	(revision 3976)
+++ src/main/java/com/xpn/xwiki/plugin/charts/ChartingPlugin.java	(working copy)
@@ -21,7 +21,9 @@
 package com.xpn.xwiki.plugin.charts;
 
 import com.xpn.xwiki.XWikiContext;
+import com.xpn.xwiki.api.AccessLevel;
 import com.xpn.xwiki.api.Api;
+import com.xpn.xwiki.api.DocumentAction;
 import com.xpn.xwiki.plugin.XWikiDefaultPlugin;
 import com.xpn.xwiki.plugin.XWikiPluginInterface;
 import com.xpn.xwiki.plugin.charts.exceptions.DataSourceException;
@@ -76,7 +78,9 @@
             } catch (Exception e2) {
             	log.error("Could not create charts temporary directory: "+tempDir, e2);
             }
-        };
+        }
+        //create and put this plugin's action in the action map
+        DocumentAction.valueOf("charting", AccessLevel.VIEW);
     }
 
     public String getName() {
@@ -169,7 +173,7 @@
 				params.getInteger(ChartParams.HEIGHT).intValue());
 		
         String imageURL = context.getDoc().getAttachmentURL(
-        		file.getName(), "charting", context);
+        		file.getName(), DocumentAction.valueOf("charting"), context);
 		String pageURL = imageURL;
 		return new ChartImpl(params, imageURL, pageURL);
 	}
Index: src/main/java/com/xpn/xwiki/plugin/graphviz/GraphVizPlugin.java
===================================================================
--- src/main/java/com/xpn/xwiki/plugin/graphviz/GraphVizPlugin.java	(revision 3976)
+++ src/main/java/com/xpn/xwiki/plugin/graphviz/GraphVizPlugin.java	(working copy)
@@ -22,7 +22,9 @@
 package com.xpn.xwiki.plugin.graphviz;
 
 import com.xpn.xwiki.XWikiContext;
+import com.xpn.xwiki.api.AccessLevel;
 import com.xpn.xwiki.api.Api;
+import com.xpn.xwiki.api.DocumentAction;
 import com.xpn.xwiki.plugin.XWikiDefaultPlugin;
 import com.xpn.xwiki.plugin.XWikiPluginInterface;
 import com.xpn.xwiki.web.XWikiResponse;
@@ -91,7 +93,9 @@
                     mLogger.error("Cannot find graphiz neato program at " + neatoPath);
             } catch (Exception e) {}
         }
-
+        
+        //declare the "dot" action with the view access level
+        DocumentAction.valueOf("dot", AccessLevel.VIEW);
     }
 
     public byte[] getDotImage(String content, boolean dot) throws IOException {
@@ -213,6 +217,6 @@
 
     public String getDotImageURL(String content, boolean dot, XWikiContext context) throws IOException {
         String filename = writeDotImage(content, "gif", dot);
-        return context.getDoc().getAttachmentURL(filename, "dot", context);
+        return context.getDoc().getAttachmentURL(filename, DocumentAction.valueOf("dot"), context);
     }
 }
Index: src/main/java/com/xpn/xwiki/plugin/svg/SVGPlugin.java
===================================================================
--- src/main/java/com/xpn/xwiki/plugin/svg/SVGPlugin.java	(revision 3976)
+++ src/main/java/com/xpn/xwiki/plugin/svg/SVGPlugin.java	(working copy)
@@ -22,7 +22,9 @@
 package com.xpn.xwiki.plugin.svg;
 
 import com.xpn.xwiki.XWikiContext;
+import com.xpn.xwiki.api.AccessLevel;
 import com.xpn.xwiki.api.Api;
+import com.xpn.xwiki.api.DocumentAction;
 import com.xpn.xwiki.plugin.XWikiDefaultPlugin;
 import com.xpn.xwiki.plugin.XWikiPluginInterface;
 import com.xpn.xwiki.web.XWikiResponse;
@@ -76,6 +78,9 @@
         } catch (Exception ex) {
             mLogger.warn("Cannot create temporary files", ex);
         }
+        
+        //create the svg action with view access level
+        DocumentAction.valueOf("svg", AccessLevel.VIEW);
     }
 
     public byte[] getSVGImage(String content, int height, int width) throws IOException, SVGConverterException {
@@ -193,6 +198,6 @@
 
     public String getSVGImageURL(String content, int height, int width, XWikiContext context) throws IOException, SVGConverterException {
         String filename = writeSVGImage(content, "png", height, width);
-        return context.getDoc().getAttachmentURL(filename, "svg", context);
+        return context.getDoc().getAttachmentURL(filename, DocumentAction.valueOf("svg"), context);
     }
 }
Index: src/main/java/com/xpn/xwiki/plugin/captcha/CaptchaPlugin.java
===================================================================
--- src/main/java/com/xpn/xwiki/plugin/captcha/CaptchaPlugin.java	(revision 3976)
+++ src/main/java/com/xpn/xwiki/plugin/captcha/CaptchaPlugin.java	(working copy)
@@ -27,6 +27,7 @@
 import com.xpn.xwiki.XWikiContext;
 import com.xpn.xwiki.XWikiException;
 import com.xpn.xwiki.api.Api;
+import com.xpn.xwiki.api.DocumentAction;
 import com.xpn.xwiki.plugin.XWikiDefaultPlugin;
 import com.xpn.xwiki.plugin.XWikiPluginInterface;
 import com.xpn.xwiki.web.XWikiRequest;
@@ -91,7 +92,7 @@
             output.append("<td><img class=\"");
             output.append(classname);
             output.append("\" ");
-            output.append("src=\"" + context.getDoc().getURL("jcaptcha", context) + "\">");
+            output.append("src=\"" + context.getDoc().getURL(DocumentAction.valueOf("jcaptcha"), context) + "\">");
             output.append("</td></tr>");
             output.append("</table>");
         } else if (typecaptcha.equalsIgnoreCase("text")) {
Index: src/main/java/com/xpn/xwiki/plugin/feed/FeedPlugin.java
===================================================================
--- src/main/java/com/xpn/xwiki/plugin/feed/FeedPlugin.java	(revision 3976)
+++ src/main/java/com/xpn/xwiki/plugin/feed/FeedPlugin.java	(working copy)
@@ -34,6 +34,7 @@
 import com.xpn.xwiki.XWikiException;
 import com.xpn.xwiki.web.XWikiEngineContext;
 import com.xpn.xwiki.api.Api;
+import com.xpn.xwiki.api.DocumentAction;
 import com.xpn.xwiki.cache.api.XWikiCache;
 import com.xpn.xwiki.cache.api.XWikiCacheNeedsRefreshException;
 import com.xpn.xwiki.doc.XWikiDocument;
@@ -159,7 +160,8 @@
         {
             outputFeed.setTitle(context.getDoc().getFullName());
             try {
-                outputFeed.setUri(context.getWiki().getURL(context.getDoc().getFullName(), "view", context));
+                outputFeed.setUri(context.getWiki().getURL(context.getDoc().getFullName(),
+                    DocumentAction.VIEW, context));
             } catch (XWikiException e) {
                 e.printStackTrace();
             }
@@ -650,7 +652,7 @@
                 try {
                     Object obj[] = (Object[]) it.next();
                     XWikiDocument doc = context.getWiki().getDocument((String) obj[1], context);
-                    if (context.getWiki().getRightService().checkAccess("view", doc, context))
+                    if (context.getWiki().getRightService().checkAccess(DocumentAction.VIEW, doc, context))
                     {
                         BaseObject bObj = doc.getObject("XWiki.FeedEntryClass", ((Integer)obj[0]).intValue());
                         com.xpn.xwiki.api.Object apiObj = new com.xpn.xwiki.api.Object(bObj, context);
Index: src/main/java/com/xpn/xwiki/plugin/query/SecHibernateQuery.java
===================================================================
--- src/main/java/com/xpn/xwiki/plugin/query/SecHibernateQuery.java	(revision 3976)
+++ src/main/java/com/xpn/xwiki/plugin/query/SecHibernateQuery.java	(working copy)
@@ -31,6 +31,7 @@
 import org.apache.jackrabbit.name.QName;
 
 import com.xpn.xwiki.XWikiException;
+import com.xpn.xwiki.api.AccessLevel;
 import com.xpn.xwiki.doc.XWikiAttachment;
 import com.xpn.xwiki.doc.XWikiDocument;
 import com.xpn.xwiki.objects.BaseObject;
@@ -140,7 +141,7 @@
 				try {
 					boolean r = true;
 					for (int i=0; i<rights.size(); i++) {
-						r &= rightserv.hasAccessLevel((String) rights.get(i), user, (String)element[1], getContext());
+						r &= rightserv.hasAccessLevel((AccessLevel) rights.get(i), user, (String)element[1], getContext());
 						if (!r)
 							break;
 					}
@@ -177,11 +178,15 @@
 		return result;
 	}
 	public List getNeededRight() {
+        //because here's the spot where the query right is used for the first time, let's initialize
+        //it here
+        //TODO: move it in a more appropriate place
+        AccessLevel queryAccessLevel = AccessLevel.valueOf("query", true, true);
 		final List r = new ArrayList(2);
 		if (isViewRight)
-			r.add("view");
+			r.add(AccessLevel.VIEW);
 		if (isQueryRight)
-			r.add("query");
+			r.add(queryAccessLevel);
 		return r;
 	}
 	public boolean isAllowed() {
Index: src/main/java/com/xpn/xwiki/plugin/lucene/SearchResult.java
===================================================================
--- src/main/java/com/xpn/xwiki/plugin/lucene/SearchResult.java	(revision 3976)
+++ src/main/java/com/xpn/xwiki/plugin/lucene/SearchResult.java	(working copy)
@@ -21,6 +21,8 @@
 
 import com.xpn.xwiki.XWikiException;
 import com.xpn.xwiki.api.Document;
+import com.xpn.xwiki.api.DocumentAction;
+
 import org.apache.log4j.Logger;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
@@ -90,7 +92,7 @@
                 .append(name).toString();
             try {
                 document = xwiki.getDocument(fullDocName);
-                url = document.getAttachmentURL(filename, "download");
+                url = document.getAttachmentURL(filename, DocumentAction.DOWNLOAD);
             } catch (XWikiException e) {
                 LOG.error("error retrieving url for attachment " + filename + " of document " +
                     fullDocName);
Index: src/main/java/com/xpn/xwiki/plugin/lucene/SearchResults.java
===================================================================
--- src/main/java/com/xpn/xwiki/plugin/lucene/SearchResults.java	(revision 3976)
+++ src/main/java/com/xpn/xwiki/plugin/lucene/SearchResults.java	(working copy)
@@ -19,6 +19,7 @@
  */
 package com.xpn.xwiki.plugin.lucene;
 
+import com.xpn.xwiki.api.DocumentAction;
 import com.xpn.xwiki.api.XWiki;
 import org.apache.log4j.Logger;
 import org.apache.lucene.search.Hits;
@@ -69,7 +70,7 @@
                         pageName = result.getWeb() + "." + result.getName();
                     }
                     if (result != null && result.isWikiContent() &&
-                        xwiki.checkAccess(pageName, "view") && xwiki.exists(pageName))
+                        xwiki.checkAccess(pageName, DocumentAction.VIEW) && xwiki.exists(pageName))
                     {
                         relevantResults.add(result);
                     }
@@ -172,7 +173,7 @@
                         pageName = result.getWeb() + "." + result.getName();
                     }
                     if (result != null && result.isWikiContent() && xwiki.exists(pageName) &&
-                            xwiki.checkAccess(pageName, "view"))
+                            xwiki.checkAccess(pageName, DocumentAction.VIEW))
                     {
                         if (resultcount>=listStartIndex) {
                             relResults.add(result);
Index: src/main/java/com/xpn/xwiki/plugin/lucene/IndexUpdater.java
===================================================================
--- src/main/java/com/xpn/xwiki/plugin/lucene/IndexUpdater.java	(revision 3976)
+++ src/main/java/com/xpn/xwiki/plugin/lucene/IndexUpdater.java	(working copy)
@@ -39,6 +39,7 @@
 
 import com.xpn.xwiki.XWiki;
 import com.xpn.xwiki.XWikiContext;
+import com.xpn.xwiki.api.DocumentAction;
 import com.xpn.xwiki.doc.XWikiAttachment;
 import com.xpn.xwiki.doc.XWikiDocument;
 import com.xpn.xwiki.notify.XWikiActionNotificationInterface;
@@ -485,12 +486,12 @@
      * Notification of attachment uploads.
      *
      * @see com.xpn.xwiki.notify.XWikiActionNotificationInterface#notify(com.xpn.xwiki.notify.XWikiNotificationRule,
-     *com.xpn.xwiki.doc.XWikiDocument,java.lang.String,com.xpn.xwiki.XWikiContext)
+     *com.xpn.xwiki.doc.XWikiDocument,com.xpn.xwiki.api.DocumentAction,com.xpn.xwiki.XWikiContext)
      */
-    public void notify(XWikiNotificationRule arg0, XWikiDocument doc, String action,
+    public void notify(XWikiNotificationRule arg0, XWikiDocument doc, DocumentAction action,
                        XWikiContext context)
     {
-        if ("upload".equals(action)) {
+        if (DocumentAction.UPLOAD.equals(action)) {
             if (LOG.isDebugEnabled()) {
                 LOG.debug("upload action notification for doc " + doc.getName());
             }
Index: src/main/java/com/xpn/xwiki/atom/XWikiHelper.java
===================================================================
--- src/main/java/com/xpn/xwiki/atom/XWikiHelper.java	(revision 3976)
+++ src/main/java/com/xpn/xwiki/atom/XWikiHelper.java	(working copy)
@@ -24,6 +24,8 @@
 import com.xpn.xwiki.XWiki;
 import com.xpn.xwiki.XWikiContext;
 import com.xpn.xwiki.XWikiException;
+import com.xpn.xwiki.api.AccessLevel;
+import com.xpn.xwiki.api.DocumentAction;
 import com.xpn.xwiki.atom.lifeblog.UserBlog;
 import com.xpn.xwiki.doc.XWikiDocument;
 import com.xpn.xwiki.objects.BaseObject;
@@ -97,11 +99,11 @@
     Iterator it = searchResults.iterator();
     while (it.hasNext()) {
       XWikiDocument doc = (XWikiDocument)it.next();
-      if (xwiki.getRightService().hasAccessLevel("edit", userName, doc.getFullName(), xwikiContext)) {
+      if (xwiki.getRightService().hasAccessLevel(AccessLevel.EDIT, userName, doc.getFullName(), xwikiContext)) {
         UserBlog userBlog = new UserBlog();
-        userBlog.setPostHref(doc.getExternalURL("lifeblog", "", xwikiContext));
-        userBlog.setFeedHref(doc.getExternalURL("view", "xpage=rdf", xwikiContext));
-        userBlog.setAlternateHref(doc.getExternalURL("view", "", xwikiContext));
+        userBlog.setPostHref(doc.getExternalURL(DocumentAction.valueOf("lifeblog"), "", xwikiContext));
+        userBlog.setFeedHref(doc.getExternalURL(DocumentAction.VIEW, "xpage=rdf", xwikiContext));
+        userBlog.setAlternateHref(doc.getExternalURL(DocumentAction.VIEW, "", xwikiContext));
         userBlogs.add(userBlog);
       }
     }
@@ -113,13 +115,33 @@
    * 
    * @param context
    * @return
-   * @throws XWikiException 
+   * @throws XWikiException
+   * @deprecated use {@link XWikiHelper#initXWikiContext(DocumentAction, HttpServletRequest, 
+   *             HttpServletResponse, ServletContext)} 
    */
   public void initXWikiContext(
       String action, 
       HttpServletRequest request, 
       HttpServletResponse response,
       ServletContext servletContext) throws XWikiException {
+    
+    this.initXWikiContext(DocumentAction.valueOf(action), request, 
+                          response, servletContext);  
+  }
+  
+  /**
+   * The version of {@link XWikiHelper#initXWikiContext(String, 
+   * HttpServletRequest, HttpServletResponse, ServletContext)} that uses {@link DocumentAction} as 
+   * a parameter.
+   * 
+   * @see XWikiHelper#initXWikiContext(String, HttpServletRequest, 
+   *      HttpServletResponse, ServletContext)
+   */
+  public void initXWikiContext(
+      DocumentAction action, 
+      HttpServletRequest request, 
+      HttpServletResponse response,
+      ServletContext servletContext) throws XWikiException {
     XWikiRequest xwikiRequest = new XWikiServletRequest(request);
     XWikiResponse xwikiResponse = new XWikiServletResponse(response);
     XWikiContext xwikiContext = Utils.prepareContext(
Index: src/main/java/com/xpn/xwiki/cache/impl/XWikiCacheListener.java
===================================================================
--- src/main/java/com/xpn/xwiki/cache/impl/XWikiCacheListener.java	(revision 3976)
+++ src/main/java/com/xpn/xwiki/cache/impl/XWikiCacheListener.java	(working copy)
@@ -29,6 +29,7 @@
 import com.opensymphony.oscache.base.events.*;
 import com.xpn.xwiki.XWiki;
 import com.xpn.xwiki.XWikiContext;
+import com.xpn.xwiki.api.DocumentAction;
 import com.xpn.xwiki.doc.XWikiDocument;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
@@ -103,7 +104,7 @@
             // email notification, lucene plugin)
             //
             // This doesn't really work since the context may not have stuff like the request object
-            xwiki.getNotificationManager().verify(doc, "flush", context);
+            xwiki.getNotificationManager().verify(doc, DocumentAction.valueOf("flush"), context);
         }
         else
         {
Index: src/main/java/com/xpn/xwiki/xmlrpc/Comment.java
===================================================================
--- src/main/java/com/xpn/xwiki/xmlrpc/Comment.java	(revision 3976)
+++ src/main/java/com/xpn/xwiki/xmlrpc/Comment.java	(working copy)
@@ -22,6 +22,7 @@
 package com.xpn.xwiki.xmlrpc;
 
 import com.xpn.xwiki.XWikiContext;
+import com.xpn.xwiki.api.DocumentAction;
 import com.xpn.xwiki.doc.XWikiDocument;
 import com.xpn.xwiki.objects.BaseObject;
 
@@ -51,7 +52,7 @@
         setContent(obj.getStringValue("content"));
         // setDate(obj.getDateValue("created"));
         setCreator(obj.getStringValue("creator"));
-        setUrl(doc.getURL("view", context));
+        setUrl(doc.getURL(DocumentAction.VIEW, context));
     }
 
     public String getId()
Index: src/main/java/com/xpn/xwiki/xmlrpc/BaseRpcHandler.java
===================================================================
--- src/main/java/com/xpn/xwiki/xmlrpc/BaseRpcHandler.java	(revision 3976)
+++ src/main/java/com/xpn/xwiki/xmlrpc/BaseRpcHandler.java	(working copy)
@@ -24,6 +24,7 @@
 import com.xpn.xwiki.XWiki;
 import com.xpn.xwiki.XWikiContext;
 import com.xpn.xwiki.XWikiException;
+import com.xpn.xwiki.api.DocumentAction;
 import com.xpn.xwiki.render.XWikiVelocityRenderer;
 import com.xpn.xwiki.web.*;
 
@@ -61,7 +62,8 @@
 
     protected XWikiContext getXWikiContext() throws XWikiException
     {
-        XWikiContext context = Utils.prepareContext("", request, response, econtext);
+        XWikiContext context = Utils.prepareContext(DocumentAction.NONE, 
+                                                    request, response, econtext);
         XWiki xwiki = XWiki.getXWiki(context);
         XWikiURLFactory urlf =
             xwiki.getURLFactoryService().createURLFactory(context.getMode(), context);
Index: src/main/java/com/xpn/xwiki/xmlrpc/User.java
===================================================================
--- src/main/java/com/xpn/xwiki/xmlrpc/User.java	(revision 3976)
+++ src/main/java/com/xpn/xwiki/xmlrpc/User.java	(working copy)
@@ -22,6 +22,7 @@
 package com.xpn.xwiki.xmlrpc;
 
 import com.xpn.xwiki.XWikiContext;
+import com.xpn.xwiki.api.DocumentAction;
 import com.xpn.xwiki.doc.XWikiDocument;
 
 public class User
@@ -39,7 +40,7 @@
         this.name = userdoc.getName();
         this.fullname = userdoc.getStringValue("XWiki.XWikiUsers", "fullName");
         this.email = userdoc.getStringValue("XWiki.XWikiUsers", "email");
-        this.url = userdoc.getURL("view", context);
+        this.url = userdoc.getURL(DocumentAction.VIEW, context);
     }
 
     public String getName()
Index: src/main/java/com/xpn/xwiki/xmlrpc/ConfluenceRpcHandler.java
===================================================================
--- src/main/java/com/xpn/xwiki/xmlrpc/ConfluenceRpcHandler.java	(revision 3976)
+++ src/main/java/com/xpn/xwiki/xmlrpc/ConfluenceRpcHandler.java	(working copy)
@@ -24,6 +24,7 @@
 import com.xpn.xwiki.XWiki;
 import com.xpn.xwiki.XWikiContext;
 import com.xpn.xwiki.XWikiException;
+import com.xpn.xwiki.api.DocumentAction;
 import com.xpn.xwiki.doc.XWikiAttachment;
 import com.xpn.xwiki.doc.XWikiDocument;
 import com.xpn.xwiki.objects.BaseObject;
@@ -179,8 +180,11 @@
         checkToken(token, context);
 
         XWikiDocument doc = new XWikiDocument(spaceKey, "WebHome");
-        return (new Space(spaceKey, spaceKey, doc.getURL("view", context), spaceKey, "WebHome"))
-            .getParameters();
+        return (new Space(spaceKey,
+            spaceKey,
+            doc.getURL(DocumentAction.VIEW, context),
+            spaceKey,
+            "WebHome")).getParameters();
     }
 
     /**
@@ -294,7 +298,7 @@
         try {
             context = getXWikiContext();
             XWiki xwiki = context.getWiki();
-            context.setAction("view");
+            context.setAction(DocumentAction.VIEW);
 
             // Verify authentication token
             checkToken(token, context);
@@ -321,7 +325,7 @@
         XWikiContext context = null;
         context = getXWikiContext();
         XWiki xwiki = context.getWiki();
-        context.setAction("view");
+        context.setAction(DocumentAction.VIEW);
 
         // Verify authentication token
         checkToken(token, context);
@@ -351,7 +355,7 @@
         XWikiContext context = null;
         context = getXWikiContext();
         XWiki xwiki = context.getWiki();
-        context.setAction("view");
+        context.setAction(DocumentAction.VIEW);
 
         // Verify authentication token
         checkToken(token, context);
@@ -386,7 +390,7 @@
             XWikiContext context = null;
             context = getXWikiContext();
             XWiki xwiki = context.getWiki();
-            context.setAction("save");
+            context.setAction(DocumentAction.SAVE);
 
             // Verify authentication token
             checkToken(token, context);
@@ -420,7 +424,7 @@
         XWikiContext context = null;
         context = getXWikiContext();
         XWiki xwiki = context.getWiki();
-        context.setAction("delete");
+        context.setAction(DocumentAction.DELETE);
 
         // Verify authentication token
         checkToken(token, context);
@@ -538,7 +542,7 @@
         Space space = new Space(new HashMap(spaceProperties));
 
         XWikiContext context = getXWikiContext();
-        context.setAction("save");
+        context.setAction(DocumentAction.SAVE);
 
         // Verify authentication token
         checkToken(token, context);
@@ -550,7 +554,7 @@
         context.getWiki().saveDocument(document, context);
 
         // Set space settings
-        space.setUrl(document.getURL("view", context));
+        space.setUrl(document.getURL(DocumentAction.VIEW, context));
         space.setHomepage(new Long(document.getId()).toString());
 
         return space.getParameters();
Index: src/main/java/com/xpn/xwiki/xmlrpc/Attachment.java
===================================================================
--- src/main/java/com/xpn/xwiki/xmlrpc/Attachment.java	(revision 3976)
+++ src/main/java/com/xpn/xwiki/xmlrpc/Attachment.java	(working copy)
@@ -24,6 +24,7 @@
 import java.util.Map;
 
 import com.xpn.xwiki.XWikiContext;
+import com.xpn.xwiki.api.DocumentAction;
 import com.xpn.xwiki.doc.XWikiAttachment;
 import com.xpn.xwiki.doc.XWikiDocument;
 
@@ -146,7 +147,7 @@
         setCreator(attachment.getAuthor());
         setCreated(attachment.getDate());
         setContentType(context.getWiki().getEngineContext().getMimeType(attachment.getFilename()));
-        setUrl(doc.getAttachmentURL(attachment.getFilename(), "download", context));
+        setUrl(doc.getAttachmentURL(attachment.getFilename(), DocumentAction.DOWNLOAD, context));
     }
 
     /**
Index: src/main/java/com/xpn/xwiki/xmlrpc/PageSummary.java
===================================================================
--- src/main/java/com/xpn/xwiki/xmlrpc/PageSummary.java	(revision 3976)
+++ src/main/java/com/xpn/xwiki/xmlrpc/PageSummary.java	(working copy)
@@ -20,6 +20,7 @@
 package com.xpn.xwiki.xmlrpc;
 
 import com.xpn.xwiki.XWikiContext;
+import com.xpn.xwiki.api.DocumentAction;
 import com.xpn.xwiki.doc.XWikiDocument;
 
 import java.util.HashMap;
@@ -68,7 +69,7 @@
         this.setSpace(doc.getSpace());
         this.setParentId(doc.getParent());
         this.setTitle(doc.getFullName());
-        this.setUrl(doc.getURL("view", context));
+        this.setUrl(doc.getURL(DocumentAction.VIEW, context));
         this.setLocks(0);
     }
 
Index: src/main/java/com/xpn/xwiki/doc/XWikiDocument.java
===================================================================
--- src/main/java/com/xpn/xwiki/doc/XWikiDocument.java	(revision 3976)
+++ src/main/java/com/xpn/xwiki/doc/XWikiDocument.java	(working copy)
@@ -28,6 +28,7 @@
 import com.xpn.xwiki.content.parsers.ReplacementResultCollection;
 import com.xpn.xwiki.content.parsers.RenamePageReplaceLinkHandler;
 import com.xpn.xwiki.content.Link;
+import com.xpn.xwiki.api.DocumentAction;
 import com.xpn.xwiki.api.DocumentSection;
 import com.xpn.xwiki.notify.XWikiNotificationRule;
 import com.xpn.xwiki.objects.BaseCollection;
@@ -661,21 +662,21 @@
 
     public String getAttachmentURL(String filename, XWikiContext context)
     {
-        return getAttachmentURL(filename, "download", context);
+        return getAttachmentURL(filename, DocumentAction.DOWNLOAD, context);
     }
 
-    public String getAttachmentURL(String filename, String action, XWikiContext context)
+    public String getAttachmentURL(String filename, DocumentAction action, XWikiContext context)
     {
         URL url = context.getURLFactory().createAttachmentURL(filename, getSpace(), getName(),
             action, null, getDatabase(), context);
         return context.getURLFactory().getURL(url, context);
     }
 
-    public String getExternalAttachmentURL(String filename, String action, XWikiContext context) {
+    public String getExternalAttachmentURL(String filename, DocumentAction action, XWikiContext context) {
         URL url = context.getURLFactory().createAttachmentURL(filename, getSpace(), getName(), action, null, getDatabase(), context);
         return url.toString();
     }
-    public String getAttachmentURL(String filename, String action, String querystring,
+    public String getAttachmentURL(String filename, DocumentAction action, String querystring,
         XWikiContext context)
     {
         URL url = context.getURLFactory().createAttachmentURL(filename, getSpace(), getName(),
@@ -698,7 +699,7 @@
         return context.getURLFactory().getURL(url, context);
     }
 
-    public String getURL(String action, boolean redirect, XWikiContext context)
+    public String getURL(DocumentAction action, boolean redirect, XWikiContext context)
     {
         URL url = context.getURLFactory()
             .createURL(getSpace(), getName(), action, null, null, getDatabase(), context);
@@ -713,38 +714,58 @@
         }
     }
 
-    public String getURL(String action, XWikiContext context)
+    public String getURL(DocumentAction action, XWikiContext context)
     {
         return getURL(action, false, context);
     }
 
-    public String getURL(String action, String querystring, XWikiContext context)
+    public String getURL(DocumentAction action, String querystring, XWikiContext context)
     {
         URL url = context.getURLFactory().createURL(getSpace(), getName(), action,
             querystring, null, getDatabase(), context);
         return context.getURLFactory().getURL(url, context);
     }
 
-    public String getExternalURL(String action, XWikiContext context)
+    public String getExternalURL(DocumentAction action, XWikiContext context)
     {
         URL url = context.getURLFactory().createExternalURL(getSpace(), getName(), action,
             null, null, getDatabase(), context);
         return url.toString();
     }
+    
+    /**
+     * @see XWikiDocument#getExternalURL(DocumentAction, XWikiContext)
+     * @deprecated use {@link XWikiDocument#getExternalURL(DocumentAction, XWikiContext)} 
+     */
+    public String getExternalURL(String action, XWikiContext context)
+    {
+        DocumentAction documentAction = DocumentAction.valueOf(action);
+        return this.getExternalURL(documentAction, context);
+    }
 
-    public String getExternalURL(String action, String querystring, XWikiContext context)
+    public String getExternalURL(DocumentAction action, String querystring, XWikiContext context)
     {
         URL url = context.getURLFactory().createExternalURL(getSpace(), getName(), action,
             querystring, null, getDatabase(), context);
         return url.toString();
     }
+    
+    /**
+     * @see XWikiDocument#getExternalURL(DocumentAction, String, XWikiContext)
+     * @deprecated {@link XWikiDocument#getExternalURL(DocumentAction, XWikiContext)} 
+     */
+    public String getExternalURL(String action, String querystring, XWikiContext context)
+    {
+        DocumentAction documentAction = DocumentAction.valueOf(action);
+        return this.getExternalURL(documentAction, querystring, context);
+    }    
 
     public String getParentURL(XWikiContext context) throws XWikiException
     {
         XWikiDocument doc = new XWikiDocument();
         doc.setFullName(getParent(), context);
         URL url = context.getURLFactory()
-            .createURL(doc.getSpace(), doc.getName(), "view", null, null, getDatabase(), context);
+            .createURL(doc.getSpace(), doc.getName(), DocumentAction.VIEW, null, null, getDatabase(), context);
         return context.getURLFactory().getURL(url, context);
     }
 
@@ -3454,14 +3475,14 @@
     {
         com.xpn.xwiki.XWiki xwiki = context.getWiki();
         if (getContent().indexOf("includeForm(") != -1) {
-            return getEditURL("inline", "", context);
+            return getEditURL(DocumentAction.INLINE, "", context);
         } else {
             String editor = xwiki.getEditorPreference(context);
-            return getEditURL("edit", editor, context);
+            return getEditURL(DocumentAction.EDIT, editor, context);
         }
     }
 
-    public String getEditURL(String action, String mode, XWikiContext context) throws XWikiException
+    public String getEditURL(DocumentAction action, String mode, XWikiContext context) throws XWikiException
     {
         com.xpn.xwiki.XWiki xwiki = context.getWiki();
         String language = "";
@@ -3473,7 +3494,7 @@
         return getEditURL(action, mode, language, context);
     }
 
-    public String getEditURL(String action, String mode, String language, XWikiContext context)
+    public String getEditURL(DocumentAction action, String mode, String language, XWikiContext context)
     {
         StringBuffer editparams = new StringBuffer();
         if (!mode.equals("")) {
Index: src/main/java/com/xpn/xwiki/notify/XWikiPageNotification.java
===================================================================
--- src/main/java/com/xpn/xwiki/notify/XWikiPageNotification.java	(revision 3976)
+++ src/main/java/com/xpn/xwiki/notify/XWikiPageNotification.java	(working copy)
@@ -3,6 +3,7 @@
 import com.xpn.xwiki.XWiki;
 import com.xpn.xwiki.XWikiContext;
 import com.xpn.xwiki.XWikiException;
+import com.xpn.xwiki.api.DocumentAction;
 import com.xpn.xwiki.doc.XWikiDocument;
 import org.apache.commons.lang.StringUtils;
 import org.apache.commons.logging.Log;
@@ -11,7 +12,7 @@
 public class XWikiPageNotification implements XWikiActionNotificationInterface {
     private static final Log log = LogFactory.getLog(XWikiPageNotification.class);
 
-    public void notify(XWikiNotificationRule rule, XWikiDocument doc, String action, XWikiContext context) {
+    public void notify(XWikiNotificationRule rule, XWikiDocument doc, DocumentAction action, XWikiContext context) {
         try {
             String notifpages = context.getWiki().getXWikiPreference("notification_pages", context);
             if ((notifpages!=null)&&(!notifpages.equals(""))) {
@@ -31,7 +32,7 @@
         }
     }
 
-    protected void notifyPage(String page, XWikiNotificationRule rule, XWikiDocument doc, String action, XWikiContext context) {
+    protected void notifyPage(String page, XWikiNotificationRule rule, XWikiDocument doc, DocumentAction action, XWikiContext context) {
         XWikiActionNotificationInterface notif = null;
         try {
             XWiki xwiki = context.getWiki();
Index: src/main/java/com/xpn/xwiki/notify/XWikiActionRule.java
===================================================================
--- src/main/java/com/xpn/xwiki/notify/XWikiActionRule.java	(revision 3976)
+++ src/main/java/com/xpn/xwiki/notify/XWikiActionRule.java	(working copy)
@@ -22,6 +22,7 @@
 package com.xpn.xwiki.notify;
 
 import com.xpn.xwiki.XWikiContext;
+import com.xpn.xwiki.api.DocumentAction;
 import com.xpn.xwiki.doc.XWikiDocument;
 
 public class XWikiActionRule implements XWikiNotificationRule {
@@ -53,7 +54,7 @@
     public void verify(XWikiDocument newdoc, XWikiDocument olddoc, XWikiContext context) {
     }
 
-    public void verify(XWikiDocument doc, String action, XWikiContext context) {
+    public void verify(XWikiDocument doc, DocumentAction action, XWikiContext context) {
     	if(!isPostverify()) return;
         try {
             getTarget().notify(this, doc, action, context);
@@ -64,7 +65,7 @@
         }
     }
 
-    public void preverify(XWikiDocument doc, String action, XWikiContext context) {
+    public void preverify(XWikiDocument doc, DocumentAction action, XWikiContext context) {
     	if(!isPreverify()) return;
         try {
             getTarget().notify(this, doc, action, context);
Index: src/main/java/com/xpn/xwiki/notify/XWikiActionNotificationInterface.java
===================================================================
--- src/main/java/com/xpn/xwiki/notify/XWikiActionNotificationInterface.java	(revision 3976)
+++ src/main/java/com/xpn/xwiki/notify/XWikiActionNotificationInterface.java	(working copy)
@@ -22,8 +22,9 @@
 package com.xpn.xwiki.notify;
 
 import com.xpn.xwiki.XWikiContext;
+import com.xpn.xwiki.api.DocumentAction;
 import com.xpn.xwiki.doc.XWikiDocument;
 
 public interface XWikiActionNotificationInterface {
-    public void notify(XWikiNotificationRule rule, XWikiDocument doc, String action, XWikiContext context);
+    public void notify(XWikiNotificationRule rule, XWikiDocument doc, DocumentAction action, XWikiContext context);
 }
Index: src/main/java/com/xpn/xwiki/notify/DocChangeRule.java
===================================================================
--- src/main/java/com/xpn/xwiki/notify/DocChangeRule.java	(revision 3976)
+++ src/main/java/com/xpn/xwiki/notify/DocChangeRule.java	(working copy)
@@ -22,6 +22,7 @@
 package com.xpn.xwiki.notify;
 
 import com.xpn.xwiki.XWikiContext;
+import com.xpn.xwiki.api.DocumentAction;
 import com.xpn.xwiki.doc.XWikiDocument;
 
 public class DocChangeRule implements XWikiNotificationRule {
@@ -46,9 +47,9 @@
         getTarget().notify(this, newdoc, olddoc, XWikiDocChangeNotificationInterface.EVENT_CHANGE, context);
     }
 
-    public void verify(XWikiDocument doc, String action, XWikiContext context) {
+    public void verify(XWikiDocument doc, DocumentAction action, XWikiContext context) {
     }
 
-    public void preverify(XWikiDocument doc, String action, XWikiContext context) {
+    public void preverify(XWikiDocument doc, DocumentAction action, XWikiContext context) {
     }
 }
Index: src/main/java/com/xpn/xwiki/notify/XWikiNotificationRule.java
===================================================================
--- src/main/java/com/xpn/xwiki/notify/XWikiNotificationRule.java	(revision 3976)
+++ src/main/java/com/xpn/xwiki/notify/XWikiNotificationRule.java	(working copy)
@@ -22,10 +22,11 @@
 package com.xpn.xwiki.notify;
 
 import com.xpn.xwiki.XWikiContext;
+import com.xpn.xwiki.api.DocumentAction;
 import com.xpn.xwiki.doc.XWikiDocument;
 
 public interface XWikiNotificationRule {
     public void verify(XWikiDocument newdoc, XWikiDocument olddoc, XWikiContext context);
-    public void verify(XWikiDocument doc, String action, XWikiContext context);
-    public void preverify(XWikiDocument doc, String action, XWikiContext context);
+    public void verify(XWikiDocument doc, DocumentAction action, XWikiContext context);
+    public void preverify(XWikiDocument doc, DocumentAction action, XWikiContext context);
 }
Index: src/main/java/com/xpn/xwiki/notify/XWikiNotificationManager.java
===================================================================
--- src/main/java/com/xpn/xwiki/notify/XWikiNotificationManager.java	(revision 3976)
+++ src/main/java/com/xpn/xwiki/notify/XWikiNotificationManager.java	(working copy)
@@ -22,6 +22,7 @@
 package com.xpn.xwiki.notify;
 
 import com.xpn.xwiki.XWikiContext;
+import com.xpn.xwiki.api.DocumentAction;
 import com.xpn.xwiki.doc.XWikiDocument;
 
 import java.util.HashMap;
@@ -112,7 +113,7 @@
             ((XWikiNotificationRule)grules.get(i)).verify(newdoc, olddoc, context);
     }
 
-    public void verify(XWikiDocument doc, String action, XWikiContext context) {
+    public void verify(XWikiDocument doc, DocumentAction action, XWikiContext context) {
         // Call rules explicitely for any actions of this document
         Vector vnamedrules;
         String name = doc.getFullName();
@@ -143,7 +144,7 @@
             ((XWikiNotificationRule)grules.get(i)).verify(doc, action, context);
     }
 
-    public void preverify(XWikiDocument doc, String action, XWikiContext context) {
+    public void preverify(XWikiDocument doc, DocumentAction action, XWikiContext context) {
         // Call rules explicitely for any actions of this document
         Vector vnamedrules;
         String name = doc.getFullName();
Index: src/main/java/com/xpn/xwiki/api/Api.java
===================================================================
--- src/main/java/com/xpn/xwiki/api/Api.java	(revision 3976)
+++ src/main/java/com/xpn/xwiki/api/Api.java	(working copy)
@@ -86,13 +86,25 @@
     }
 
     /**
+     * @see Api#hasAccessLevel(AccessLevel, String)
+     * @deprecated use {@link Api#hasAccessLevel(AccessLevel, String)} 
+     * 
+     */
+    public boolean hasAccessLevel(String right, String docname) throws XWikiException
+    {
+        AccessLevel accessLevel = AccessLevel.valueOf(right);
+        return this.hasAccessLevel(accessLevel, docname);
+    }
+    
+    
+    /**
      * @param right the name of the right to verify (eg "programming", "admin", "register", etc)
      * @param docname the document for which to verify the right
      * @return true if the current user has the specified right
      * @exception XWikiException in case of an error finding the document or accessing groups
      *            information
-     */
-    public boolean hasAccessLevel(String right, String docname) throws XWikiException
+     */    
+    public boolean hasAccessLevel(AccessLevel right, String docname) throws XWikiException
     {
         com.xpn.xwiki.XWiki xwiki = context.getWiki();
         return xwiki.getRightService().hasAccessLevel(right, context.getUser(), docname, context);
Index: src/main/java/com/xpn/xwiki/api/DocumentAction.java
===================================================================
--- src/main/java/com/xpn/xwiki/api/DocumentAction.java	(revision 0)
+++ src/main/java/com/xpn/xwiki/api/DocumentAction.java	(revision 0)
@@ -0,0 +1,510 @@
+/*
+ * Copyright 2004-2007, XpertNet SARL, and individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ *
+ *
+ * This distribution includes the following modules:
+ *
+ * http://jakarta.apache.org: velocity, struts, jrcs, commons, etc..
+ * This distribution also includes libraries from the Apache Software
+ * Foundation distributed under the terms of the Apache Software License.
+ * See http://www.opensource.org/licenses/apachepl.php
+ *
+ * http://www.hibernate.org:
+ * This distribution includes libraries from hibernate.org distributed
+ * under the terms of the Lesser General Public License.
+ * See http://www.gnu.org/copyleft/lesser.html
+ *
+ * http://www.junit.org
+ * This distribution includes libraries from junit.org distributed 
+ * under the terms of the Common Public License
+ * See http://www.opensource.org/licenses/cpl.php
+ *
+ * ===================================================================
+ */
+package com.xpn.xwiki.api;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+
+/**
+ * Actions for the documents, to be used instead of string values like "view", "download", etc.
+ * The names of the constants are exactly the names of the actions in the upper-case. E.g. for the 
+ * "view" action, the corresponding constant is DocumentAction.VIEW. An exception to this rule is 
+ * the {@link DocumentAction#NONE} constant, associated to an empty action string, "".
+ * <br />
+ * <strong>NOTE:</strong> the string value of the action, stored by an instance of this class, is 
+ * always trimmed and lowercased. So the tests performed by {@link DocumentAction#valueOf(String)}, 
+ * {@link DocumentAction#isActionDefined(String)}, etc. are case insensitive. 
+ * 
+ * @author Anca-Paula Luca
+ */
+public class DocumentAction
+{
+    public static final DocumentAction LOGIN = new DocumentAction("login");
+    public static final DocumentAction LOGOUT = new DocumentAction("logout");
+    public static final DocumentAction LOGINERROR = new DocumentAction("loginerror");
+    public static final DocumentAction LOGINSUBMIT = new DocumentAction("loginsubmit");
+    public static final DocumentAction VIEW = new DocumentAction("view");
+    public static final DocumentAction VIEWREV = new DocumentAction("viewrev");
+    public static final DocumentAction DOWNLOADREV = new DocumentAction("downloadrev");
+    
+    //this action is used in this class, but it appears in the struts-config.xml file, 
+    //the view action
+    public static final DocumentAction PLAIN = new DocumentAction("plain");
+    
+    public static final DocumentAction ATTACH = new DocumentAction("attach");
+    public static final DocumentAction SKIN = new DocumentAction("skin");
+    public static final DocumentAction DOWNLOAD = new DocumentAction("download");
+    
+    //DOT and SVG are not a constants because they are plugin actions
+    //public static final DocumentAction DOT = new DocumentAction("dot");
+    //public static final DocumentAction SVG = new DocumentAction("svg");
+    
+    public static final DocumentAction PDF = new DocumentAction("pdf");
+    
+    public static final DocumentAction DELETE = new DocumentAction("delete");
+    public static final DocumentAction RESET = new DocumentAction("reset");
+    public static final DocumentAction REDIRECT = new DocumentAction("redirect");
+    public static final DocumentAction UNKNOWN = new DocumentAction("unknown");
+    
+    public static final DocumentAction COMMENTADD = new DocumentAction("commentadd");
+    public static final DocumentAction REGISTER = new DocumentAction("register");
+    public static final DocumentAction ADMIN = new DocumentAction("admin");
+    public static final DocumentAction EXPORT = new DocumentAction("export");
+    public static final DocumentAction IMPORT = new DocumentAction("import");
+    
+    public static final DocumentAction EDIT = new DocumentAction("edit");
+    public static final DocumentAction INLINE = new DocumentAction("inline");
+    
+    public static final DocumentAction SAVE = new DocumentAction("save");
+        
+    public static final DocumentAction PREVIEW = new DocumentAction("preview");
+    public static final DocumentAction VIEWATTACHREV = new DocumentAction("viewattachrev");
+    
+    public static final DocumentAction LOCK = new DocumentAction("lock");
+    public static final DocumentAction CANCEL = new DocumentAction("cancel");
+    public static final DocumentAction ROLLBACK = new DocumentAction("rollback");
+    public static final DocumentAction OBJECTADD = new DocumentAction("objectadd");
+    public static final DocumentAction OBJECTREMOVE = new DocumentAction("objectremove");
+    public static final DocumentAction PROPADD = new DocumentAction("propadd");
+    public static final DocumentAction PROPUPDATE = new DocumentAction("propupdate");
+    public static final DocumentAction UPLOAD = new DocumentAction("upload");
+    public static final DocumentAction DELATTACHMENT = new DocumentAction("delattachment");
+    
+    public static final DocumentAction PROPDELETE = new DocumentAction("propdelete");
+    public static final DocumentAction EDITPREFS = new DocumentAction("editprefs");
+    
+    //this constant matches no action, that is, an empty string "". Don't mistake it for  
+    //a "none" action or something.
+    public static final DocumentAction NONE = new DocumentAction(""); 
+        
+    /**
+     * holds all constants defined in this class.
+     */
+    private static ArrayList values;
+    
+    /**
+     * The string value corresponding to this DocumentAction instance.
+     */
+    private String action;
+        
+    private static HashMap actionRightMap;
+    
+    //initialization block for actionRightMap
+    static 
+    {
+        DocumentAction.actionRightMap = new HashMap();
+        DocumentAction.actionRightMap.put(DocumentAction.LOGIN, AccessLevel.LOGIN);
+        DocumentAction.actionRightMap.put(DocumentAction.LOGOUT, AccessLevel.LOGIN);
+        DocumentAction.actionRightMap.put(DocumentAction.LOGINERROR, AccessLevel.LOGIN);
+        DocumentAction.actionRightMap.put(DocumentAction.LOGINSUBMIT, AccessLevel.LOGIN);
+        DocumentAction.actionRightMap.put(DocumentAction.VIEW, AccessLevel.VIEW);
+        DocumentAction.actionRightMap.put(DocumentAction.VIEWREV, AccessLevel.VIEW);
+        DocumentAction.actionRightMap.put(DocumentAction.DOWNLOADREV, AccessLevel.DOWNLOAD);
+        DocumentAction.actionRightMap.put(DocumentAction.PLAIN, AccessLevel.VIEW);
+        DocumentAction.actionRightMap.put(DocumentAction.ATTACH, AccessLevel.VIEW);
+        DocumentAction.actionRightMap.put(DocumentAction.SKIN, AccessLevel.VIEW);
+        DocumentAction.actionRightMap.put(DocumentAction.DOWNLOAD, AccessLevel.VIEW);
+        DocumentAction.actionRightMap.put(DocumentAction.PDF, AccessLevel.VIEW);
+        DocumentAction.actionRightMap.put(DocumentAction.DELETE, AccessLevel.DELETE);
+        DocumentAction.actionRightMap.put(DocumentAction.RESET, AccessLevel.DELETE);
+        DocumentAction.actionRightMap.put(DocumentAction.COMMENTADD, AccessLevel.COMMENT);
+        DocumentAction.actionRightMap.put(DocumentAction.REGISTER, AccessLevel.REGISTER);
+        DocumentAction.actionRightMap.put(DocumentAction.REDIRECT, AccessLevel.VIEW);
+        DocumentAction.actionRightMap.put(DocumentAction.ADMIN, AccessLevel.ADMIN);
+        DocumentAction.actionRightMap.put(DocumentAction.EXPORT, AccessLevel.VIEW);
+        DocumentAction.actionRightMap.put(DocumentAction.IMPORT, AccessLevel.ADMIN);
+        DocumentAction.actionRightMap.put(DocumentAction.UNKNOWN, AccessLevel.VIEW);        
+    }
+    
+
+    /**
+     * Builds the DocumentAction from the string value. The value is trimmed as well as transformed 
+     * to lower case.
+     * TODO: Should be uppercased for compatibility with the 5.0 enum type.
+     * 
+     * @param action The {@link String} value of the document action.
+     */
+    private DocumentAction(String action)
+    {
+        //trim it, lowercase it
+        this.action = action.trim().toLowerCase();
+        //add this to the values array
+        if (DocumentAction.values == null) {
+            DocumentAction.values = new ArrayList();
+        }
+        DocumentAction.values.add(this);
+    }
+    
+    /**
+     * @return the list of all DocumentAction constants.
+     */
+    public static DocumentAction[] values() {
+        DocumentAction[] returnArray = new DocumentAction[DocumentAction.values.size()]; 
+        DocumentAction.values.toArray(returnArray);
+        return returnArray;
+    }
+    
+    /**
+     * Provides the right for a specified action, according to the rights map hold by this class. 
+     * If the action is not found in the rights map hold by this class, the default right, 
+     * {@link AccessLevel#EDIT} is returned.
+     * 
+     * @param action the action to provide the right for
+     * @return the right
+     */
+    public static AccessLevel getAccessLevel(DocumentAction action) {
+        AccessLevel rightFound = (AccessLevel)DocumentAction.actionRightMap.get(action);
+        if (rightFound == null) {
+            rightFound = AccessLevel.EDIT;
+        }
+        
+        return rightFound;
+    }
+    
+    public AccessLevel getAccessLevel() {
+        return DocumentAction.getAccessLevel(this);
+    }
+
+    /**
+     * @return the action
+     */
+    public String getAction()
+    {
+        return action;
+    }
+
+    /**
+     * Returns the DocumentAction constant correspnding to the given actionString, testing equality 
+     * with the trimmed, lowercased value of the actionString. If no match is found, a new 
+     * <tt>DocumentAction</tt> is built and added to the list of actions.
+     * 
+     * @param actionString the string value of the action
+     * @return the DocumentAction constant that matches the string value
+     */
+    public static DocumentAction valueOf(String actionString)
+    {
+        String cleanActionString = actionString.trim().toLowerCase();
+        DocumentAction[] constants = DocumentAction.values();
+        for (int i = 0; i < constants.length; i++) {
+            if (constants[i].getAction().equals(cleanActionString)) {
+                //found, return it
+                return constants[i];
+            }
+        }
+        //if it wasn't found, it's a new action.
+        DocumentAction newAction = new DocumentAction(actionString);
+        //put it in the values array
+        DocumentAction.values.add(newAction);
+        return newAction;
+    }
+    
+    /**
+     * Returns the action matching to actionString (as {@link DocumentAction#valueOf(String)} does),
+     * only that, when creating the action, it also associates it with <tt>right</tt>. If the action
+     * has been previously defined, no changes are made on it's rights. If you want 
+     * to create an action and set the access right for it, you must use this function.
+     * 
+     * TODO: find a better, more intuitive name for this function. 
+     * 
+     * @param actionString the string value of the action.
+     * @param right the right to associate to the action, if it is a newly created action.
+     * @return the DocumentAction that matches the <tt>actionString</tt>
+     * @see DocumentAction#valueOf(String)
+     */
+    public static DocumentAction valueOf(String actionString, AccessLevel right) {
+        boolean actionDefined = DocumentAction.isActionDefined(actionString);
+        //get the action
+        DocumentAction theAction = DocumentAction.valueOf(actionString);
+        if (!actionDefined) {
+            //if it wasn't defined before this, associate the right
+            DocumentAction.actionRightMap.put(theAction, right);
+        }
+        
+        return theAction;
+    }
+    
+    /**
+     * Tests whether a DocumentAction is defined for the provided action string, trimmed and 
+     * lowercased.
+     * 
+     * @param actionString the string value of the action.
+     * @return true if an action with a matching string value was found and false otherwise. 
+     */
+    public static boolean isActionDefined(String actionString) {
+        String cleanActionString = actionString.trim().toLowerCase();
+        DocumentAction[] constants = DocumentAction.values();
+        for (int i = 0; i < constants.length; i++) {
+            if (constants[i].getAction().equals(cleanActionString)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * {@inheritDoc}
+     * 
+     * @see Object#equals
+     */
+    public boolean equals(java.lang.Object obj)
+    {
+        //arrrrgh com.xpn.xwiki.api.Object...
+        if ((obj != null) && (obj instanceof DocumentAction)) {
+            DocumentAction documentAction = (DocumentAction) obj;
+            if (documentAction == this) {
+                return true;
+            } else {
+                return false;
+            }
+        } else {
+            return false;
+        }
+        
+    }
+
+    /**
+     * {@inheritDoc}
+     * 
+     * @see Object#hashCode
+     */
+    public int hashCode()
+    {
+        return this.action.hashCode();
+    }
+
+    /**
+     * {@inheritDoc}
+     * 
+     * @see Object#toString
+     */
+    public String toString()
+    {
+        return this.action;
+    }
+
+    public static DocumentAction getADMIN()
+    {
+        return ADMIN;
+    }
+
+    public static DocumentAction getATTACH()
+    {
+        return ATTACH;
+    }
+
+    public static DocumentAction getCANCEL()
+    {
+        return CANCEL;
+    }
+
+    public static DocumentAction getCOMMENTADD()
+    {
+        return COMMENTADD;
+    }
+
+    public static DocumentAction getDELATTACHMENT()
+    {
+        return DELATTACHMENT;
+    }
+
+    public static DocumentAction getDELETE()
+    {
+        return DELETE;
+    }
+
+    public static DocumentAction getDOWNLOAD()
+    {
+        return DOWNLOAD;
+    }
+
+    public static DocumentAction getDOWNLOADREV()
+    {
+        return DOWNLOADREV;
+    }
+
+    public static DocumentAction getEDIT()
+    {
+        return EDIT;
+    }
+
+    public static DocumentAction getEDITPREFS()
+    {
+        return EDITPREFS;
+    }
+
+    public static DocumentAction getEXPORT()
+    {
+        return EXPORT;
+    }
+
+    public static DocumentAction getIMPORT()
+    {
+        return IMPORT;
+    }
+
+    public static DocumentAction getINLINE()
+    {
+        return INLINE;
+    }
+
+    public static DocumentAction getLOCK()
+    {
+        return LOCK;
+    }
+
+    public static DocumentAction getLOGIN()
+    {
+        return LOGIN;
+    }
+
+    public static DocumentAction getLOGINERROR()
+    {
+        return LOGINERROR;
+    }
+
+    public static DocumentAction getLOGINSUBMIT()
+    {
+        return LOGINSUBMIT;
+    }
+
+    public static DocumentAction getLOGOUT()
+    {
+        return LOGOUT;
+    }
+
+    public static DocumentAction getNONE()
+    {
+        return NONE;
+    }
+
+    public static DocumentAction getOBJECTADD()
+    {
+        return OBJECTADD;
+    }
+
+    public static DocumentAction getOBJECTREMOVE()
+    {
+        return OBJECTREMOVE;
+    }
+
+    public static DocumentAction getPDF()
+    {
+        return PDF;
+    }
+
+    public static DocumentAction getPLAIN()
+    {
+        return PLAIN;
+    }
+
+    public static DocumentAction getPREVIEW()
+    {
+        return PREVIEW;
+    }
+
+    public static DocumentAction getPROPADD()
+    {
+        return PROPADD;
+    }
+
+    public static DocumentAction getPROPDELETE()
+    {
+        return PROPDELETE;
+    }
+
+    public static DocumentAction getPROPUPDATE()
+    {
+        return PROPUPDATE;
+    }
+
+    public static DocumentAction getREDIRECT()
+    {
+        return REDIRECT;
+    }
+
+    public static DocumentAction getREGISTER()
+    {
+        return REGISTER;
+    }
+
+    public static DocumentAction getRESET()
+    {
+        return RESET;
+    }
+
+    public static DocumentAction getROLLBACK()
+    {
+        return ROLLBACK;
+    }
+
+    public static DocumentAction getSAVE()
+    {
+        return SAVE;
+    }
+
+    public static DocumentAction getSKIN()
+    {
+        return SKIN;
+    }
+
+    public static DocumentAction getUNKNOWN()
+    {
+        return UNKNOWN;
+    }
+
+    public static DocumentAction getUPLOAD()
+    {
+        return UPLOAD;
+    }
+
+    public static DocumentAction getVIEW()
+    {
+        return VIEW;
+    }
+
+    public static DocumentAction getVIEWATTACHREV()
+    {
+        return VIEWATTACHREV;
+    }
+
+    public static DocumentAction getVIEWREV()
+    {
+        return VIEWREV;
+    }
+}
Index: src/main/java/com/xpn/xwiki/api/Document.java
===================================================================
--- src/main/java/com/xpn/xwiki/api/Document.java	(revision 3976)
+++ src/main/java/com/xpn/xwiki/api/Document.java	(working copy)
@@ -391,29 +391,50 @@
      */
     public String getAttachmentURL(String filename)
     {
-        return doc.getAttachmentURL(filename, "download", getXWikiContext());
+        return doc.getAttachmentURL(filename, DocumentAction.DOWNLOAD, getXWikiContext());
     }
 
+
     /**
+     * @see Document#getAttachmentURL(String, DocumentAction)
+     * @deprecated use {@link Document#getAttachmentURL(String, DocumentAction)}
+     */
+    public String getAttachmentURL(String filename, String action)
+    {
+        DocumentAction documentAction = DocumentAction.valueOf(action);
+        return this.getAttachmentURL(filename, documentAction);
+    }
+    
+    /**
      * return the URL of the given action for the  the given attachment name
      *
      * @return A string with the URL
      */
-    public String getAttachmentURL(String filename, String action)
+    public String getAttachmentURL(String filename, DocumentAction action)
     {
         return doc.getAttachmentURL(filename, action, getXWikiContext());
     }
 
     /**
+     * @see Document#getAttachmentURL(String, DocumentAction, String)
+     * @deprecated use {@link Document#getAttachmentURL(String, DocumentAction, String)}
+     */
+    public String getAttachmentURL(String filename, String action, String queryString)
+    {
+        DocumentAction documentAction = DocumentAction.valueOf(action);
+        return this.getAttachmentURL(filename, documentAction, queryString);
+    }
+    
+    /**
      * return the URL of the given action for the  the given attachment name with "queryString"
      * parameters
      *
      * @param queryString parameters added to the URL
      */
-    public String getAttachmentURL(String filename, String action, String queryString)
+    public String getAttachmentURL(String filename, DocumentAction action, String queryString)
     {
         return doc.getAttachmentURL(filename, action, queryString, getXWikiContext());
-    }
+    }    
 
     /**
      * return the URL for accessing to the archive of the attachment "filename" at the version
@@ -438,45 +459,84 @@
      */
     public String getURL()
     {
-        return doc.getURL("view", getXWikiContext());
+        return doc.getURL(DocumentAction.VIEW, getXWikiContext());
     }
 
     /**
      * return the URL of this document with the given action
      */
-    public String getURL(String action)
+    public String getURL(DocumentAction action)
     {
         return doc.getURL(action, getXWikiContext());
     }
-
+    
     /**
+     *  @see Document#getURL(DocumentAction)
+     *  @deprecated use {@link Document#getURL(DocumentAction)} 
+     */
+    public String getURL(String action)
+    {
+        DocumentAction documentAction = DocumentAction.valueOf(action);
+        return this.getURL(documentAction);
+    }
+    
+    /**
      * return the URL of this document with the given action and queryString as parameters
      */
-    public String getURL(String action, String querystring)
+    public String getURL(DocumentAction action, String querystring)
     {
         return doc.getURL(action, querystring, getXWikiContext());
     }
+    
+    /**
+     * @see Document#getURL(DocumentAction, String)
+     * @deprecated use {@link Document#getURL(DocumentAction, String)}
+     */
+    public String getURL(String action, String querystring)
+    {
+        DocumentAction documentAction = DocumentAction.valueOf(action);
+        return this.getURL(documentAction, querystring);
+    }    
 
     /**
      * return the full URL of the document
      */
     public String getExternalURL()
     {
-        return doc.getExternalURL("view", getXWikiContext());
+        return doc.getExternalURL(DocumentAction.VIEW, getXWikiContext());
     }
 
     /**
-     * return the full URL of the document for the given action
+     * @see Document#getExternalURL(DocumentAction)
+     * @deprecated use {@link Document#getExternalURL(DocumentAction)} 
      */
     public String getExternalURL(String action)
     {
+        return doc.getExternalURL(DocumentAction.valueOf(action), getXWikiContext());
+    }
+    
+    /**
+     * @param action
+     * @return the full URL of the document for the given action
+     */
+    public String getExternalURL(DocumentAction action)
+    {
         return doc.getExternalURL(action, getXWikiContext());
     }
 
+    /**
+     * @deprecated use {@link Document#getExternalURL(DocumentAction, String)} 
+     */
     public String getExternalURL(String action, String querystring)
     {
+        DocumentAction documentAction = DocumentAction.valueOf(action);
+        return this.getExternalURL(documentAction, querystring);
+    }
+    
+    public String getExternalURL(DocumentAction action, String querystring)
+    {
         return doc.getExternalURL(action, querystring, getXWikiContext());
-    }
+    } 
 
     public String getParentURL() throws XWikiException
     {
@@ -1135,17 +1195,37 @@
         return doc.getLastChanges(getXWikiContext());
     }
 
-    public DocumentStats getCurrentMonthPageStats(String action)
+    public DocumentStats getCurrentMonthPageStats(DocumentAction action)
     {
         return getXWikiContext().getWiki().getStatsService(getXWikiContext())
             .getDocMonthStats(doc.getFullName(), action, new Date(), getXWikiContext());
     }
+    
+    /**
+     * @see Document#getCurrentMonthPageStats(DocumentAction)
+     * @deprecated use {@link Document#getCurrentMonthPageStats(DocumentAction)}
+     */
+    public DocumentStats getCurrentMonthPageStats(String action)
+    {
+        DocumentAction documentAction = DocumentAction.valueOf(action);
+        return this.getCurrentMonthPageStats(documentAction);
+    }
 
-    public DocumentStats getCurrentMonthWebStats(String action)
+    public DocumentStats getCurrentMonthWebStats(DocumentAction action)
     {
         return getXWikiContext().getWiki().getStatsService(getXWikiContext())
             .getDocMonthStats(doc.getSpace(), action, new Date(), getXWikiContext());
     }
+    
+    /**
+     * @see Document#getCurrentMonthWebStats(DocumentAction)
+     * @deprecated use {@link Document#getCurrentMonthWebStats(DocumentAction)} 
+     */
+    public DocumentStats getCurrentMonthWebStats(String action)
+    {
+        DocumentAction documentAction = DocumentAction.valueOf(action);
+        return this.getCurrentMonthWebStats(documentAction);
+    }
 
     public List getCurrentMonthRefStats() throws XWikiException
     {
@@ -1153,27 +1233,48 @@
             .getRefMonthStats(doc.getFullName(), new Date(), getXWikiContext());
     }
 
+    /**
+     * @deprecated use {@link Document#checkAccess(DocumentAction)}
+     * @param right
+     * @return
+     */
     public boolean checkAccess(String right)
     {
+        DocumentAction docAction = DocumentAction.valueOf(right);
+        return this.checkAccess(docAction);
+    }
+    
+    public boolean checkAccess(DocumentAction action)
+    {
         try {
-            return getXWikiContext().getWiki().checkAccess(right, getDoc(), getXWikiContext());
+            return getXWikiContext().getWiki().checkAccess(action, getDoc(), getXWikiContext());
         } catch (XWikiException e) {
             return false;
         }
     }
-
-    public boolean hasAccessLevel(String level)
+    
+    public boolean hasAccessLevel(AccessLevel level) 
     {
         try {
             return getXWikiContext().getWiki().getRightService().hasAccessLevel(level,
                 getXWikiContext().getUser(), getDoc().getFullName(), getXWikiContext());
         } catch (Exception e) {
             return false;
-        }
+        }        
     }
 
-    public boolean hasAccessLevel(String level, String user)
+    /**
+     * @see Document#hasAccessLevel(AccessLevel)
+     * @deprecated use {@link Document#hasAccessLevel(AccessLevel)} 
+     */
+    public boolean hasAccessLevel(String level)
     {
+        AccessLevel accessLevel = AccessLevel.valueOf(level);
+        return this.hasAccessLevel(accessLevel);
+    }
+    
+    public boolean hasAccessLevel(AccessLevel level, String user)
+    {
         try {
             return getXWikiContext().getWiki().getRightService()
                 .hasAccessLevel(level, user, doc.getFullName(), getXWikiContext());
@@ -1182,6 +1283,16 @@
         }
     }
 
+    /**
+     * @see Document#hasAccessLevel(AccessLevel, String)
+     * @deprecated use {@link Document#hasAccessLevel(AccessLevel, String)}
+     */
+    public boolean hasAccessLevel(String level, String user)
+    {
+        AccessLevel accessLevel = AccessLevel.valueOf(level);
+        return this.hasAccessLevel(accessLevel, user);
+    }
+
     public boolean getLocked()
     {
         try {
@@ -1326,15 +1437,31 @@
         return doc.getDefaultEditURL(getXWikiContext());
     }
 
+    /**
+     * @deprecated use {@link Document#getEditURL(DocumentAction, String)}
+     */
     public String getEditURL(String action, String mode) throws XWikiException
     {
+        return doc.getEditURL(DocumentAction.valueOf(action), mode, getXWikiContext());
+    }
+    
+    public String getEditURL(DocumentAction action, String mode) throws XWikiException
+    {
         return doc.getEditURL(action, mode, getXWikiContext());
-    }
+    }    
 
+    /**
+     * @deprecated use {@link Document#getEditURL(DocumentAction, String, String)} 
+     */
     public String getEditURL(String action, String mode, String language)
     {
+        return doc.getEditURL(DocumentAction.valueOf(action), mode, language, getXWikiContext());
+    }
+    
+    public String getEditURL(DocumentAction action, String mode, String language)
+    {
         return doc.getEditURL(action, mode, language, getXWikiContext());
-    }
+    }    
 
     public boolean isCurrentUserCreator()
     {
Index: src/main/java/com/xpn/xwiki/api/Context.java
===================================================================
--- src/main/java/com/xpn/xwiki/api/Context.java	(revision 3976)
+++ src/main/java/com/xpn/xwiki/api/Context.java	(working copy)
@@ -104,9 +104,17 @@
 
     /**
      * @return the requested action
+     * @deprecated use {@link Context#getDocumentAction()}  
      */
     public String getAction()
     {
+        return this.getDocumentAction().toString();
+    }
+    
+    /**
+     * @return the requested action, as a {@link DocumentAction} constant.
+     */
+    public DocumentAction getDocumentAction() {
         return getXWikiContext().getAction();
     }
 
@@ -235,21 +243,38 @@
         getXWikiContext().setCacheDuration(duration);
     }
 
-    public void setLinksAction(String action)
+    public void setLinksAction(DocumentAction action)
     {
         getXWikiContext().setLinksAction(action);
     }
+    
+    /**
+     * @see Context#setLinksAction(DocumentAction)
+     * @deprecated use {@link Context#setLinksAction(DocumentAction)}
+     */
+    public void setLinksAction(String action)
+    {
+        this.setLinksAction(DocumentAction.valueOf(action));
+    }    
 
     public void unsetLinksAction()
     {
         getXWikiContext().unsetLinksAction();
     }
 
+    /**
+     * @deprecated use {@link Context#getLinksDocumentAction()}
+     */
     public String getLinksAction()
     {
-        return getXWikiContext().getLinksAction();
+        return this.getLinksDocumentAction().toString();
     }
 
+    public DocumentAction getLinksDocumentAction()
+    {
+        return getXWikiContext().getLinksAction();
+    }    
+
     public void setLinksQueryString(String value)
     {
         getXWikiContext().setLinksQueryString(value);
Index: src/main/java/com/xpn/xwiki/api/AccessLevel.java
===================================================================
--- src/main/java/com/xpn/xwiki/api/AccessLevel.java	(revision 0)
+++ src/main/java/com/xpn/xwiki/api/AccessLevel.java	(revision 0)
@@ -0,0 +1,254 @@
+/*
+ * Copyright 2004-2007, XpertNet SARL, and individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ *
+ *
+ * This distribution includes the following modules:
+ *
+ * http://jakarta.apache.org: velocity, struts, jrcs, commons, etc..
+ * This distribution also includes libraries from the Apache Software
+ * Foundation distributed under the terms of the Apache Software License.
+ * See http://www.opensource.org/licenses/apachepl.php
+ *
+ * http://www.hibernate.org:
+ * This distribution includes libraries from hibernate.org distributed
+ * under the terms of the Lesser General Public License.
+ * See http://www.gnu.org/copyleft/lesser.html
+ *
+ * http://www.junit.org
+ * This distribution includes libraries from junit.org distributed 
+ * under the terms of the Common Public License
+ * See http://www.opensource.org/licenses/cpl.php
+ *
+ * ===================================================================
+ */
+package com.xpn.xwiki.api;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * Enumerated class to manage the access levels used in xwiki, such as "view", "edit", "login", etc.
+ * Two lists are maintained for the access levels: "regular" access levels, to be used for 
+ * documents/spaces and "global" access levels, used for global access level settings.  
+ * 
+ * @author Anca-Paula Luca
+ */
+public class AccessLevel
+{
+    //put the constants here
+    public static final AccessLevel VIEW = new AccessLevel("view", true, true);
+    public static final AccessLevel LOGIN = new AccessLevel("login", false, false);
+    public static final AccessLevel DOWNLOAD = new AccessLevel("download", false, false);
+    public static final AccessLevel DELETE = new AccessLevel("delete", false, true);
+    public static final AccessLevel COMMENT = new AccessLevel("comment", true, true);
+    public static final AccessLevel REGISTER = new AccessLevel("register", false, true);
+    public static final AccessLevel ADMIN = new AccessLevel("admin", false, true);
+    public static final AccessLevel EDIT = new AccessLevel("edit", true, true);
+    public static final AccessLevel PROGRAMMING = new AccessLevel("programming", false, true);
+        
+    /**
+     * holds the list of accessLevels that can be set for a given document / space.
+     */
+    private static List regularAccessLevels;
+    /**
+     * holds the list of accessLevels that can be set for the entire wiki.
+     * The present assignment of levels to categories has been done according to the code in 
+     * {@link com.xpn.xwiki.objects.classes.LevelsClass#getList(com.xpn.xwiki.XWikiContext)}. 
+     */
+    private static List globalAccessLevels;
+    /**
+     * array holding all the constants defined by this class.
+     */
+    private static ArrayList values;    
+        
+    /**
+     * The string value of this right. e.g. "view", "admin", "edit"
+     */
+    private String rightString;
+    
+    /**
+     * Returns a new instance of an AccessLevel from the given string value, trimmed and lowercased.
+     *  
+     * @param right the String value of the right. 
+     * @param isRegular specifies wheather this is a regular access level.
+     * @param isGlobal specifies wheather this is a global access level.
+     */
+    private AccessLevel(String right, boolean isRegular, boolean isGlobal) 
+    {
+        this.rightString = right.trim().toLowerCase();
+        if (isRegular) {
+            if (AccessLevel.regularAccessLevels == null) {
+                AccessLevel.regularAccessLevels = new ArrayList();
+            }
+            //put it in the regularAccessLevels
+            AccessLevel.regularAccessLevels.add(this);
+        }
+        if (isGlobal) {
+            if (AccessLevel.globalAccessLevels == null) {
+                AccessLevel.globalAccessLevels = new ArrayList();
+            }
+            //put it in the globals list
+            AccessLevel.globalAccessLevels.add(this);
+        }
+        //put it in the values array
+        if (AccessLevel.values == null) {
+            AccessLevel.values = new ArrayList();
+        }
+        AccessLevel.values.add(this);
+    }
+    
+    /**
+     * @return all the access level constants provided by this class.
+     */
+    public static AccessLevel[] values() 
+    {
+        AccessLevel[] valuesToReturn = new AccessLevel[AccessLevel.values.size()];
+        AccessLevel.values.toArray(valuesToReturn);
+        return valuesToReturn;
+    }
+    
+    /**
+     * @return true if an access level matching <tt>rightString</tt> is found, and false otherwise.
+     * The comparison is made with the trimmed and lowercased value of rightString. 
+     */
+    public static boolean isAccessLevelDefined(String rightString) {
+        String cleanRightString = rightString.trim().toLowerCase();
+        for (Iterator it = AccessLevel.values.iterator(); it.hasNext();) {
+            AccessLevel current = (AccessLevel)it.next();
+            if (current.getRightString().equals(cleanRightString)) {
+                return true;
+            }
+        }
+        return false;
+    }
+    
+    /**
+     * Returns the AccessLevel constant matching rightString. if such a constant does not exist, it 
+     * is created and then returned. The newly created access level is not a regular nor a global 
+     * access level. To create an access level and specify it's type, use 
+     * {@link AccessLevel#valueOf(String, boolean, boolean)}.
+     * 
+     * @param rightString the String value of the access level.
+     * @return the matching constant, or a newly created AccessLevel object if no match is found.
+     * 
+     * @see AccessLevel#valueOf(String, boolean, boolean) 
+     */
+    public static AccessLevel valueOf(String rightString) 
+    {
+        String cleanRightString = rightString.trim().toLowerCase();
+        for (Iterator it = AccessLevel.values.iterator(); it.hasNext();) {
+            AccessLevel current = (AccessLevel)it.next();
+            if (current.getRightString().equals(cleanRightString)) {
+                return current;
+            }
+        }
+        //create a new accessLevel, that defaults on false, false
+        return new AccessLevel(rightString, false, false);
+    }
+    
+    /**
+     * Behaves like {@link AccessLevel#valueOf(String)}, only that, upon the creation of the new
+     * AccessLevel object, <tt>isRegular</tt> and <tt>isGlobal</tt> are used to specify the type 
+     * of this access level.
+     * <br />
+     * Note that this function does not change the type of an existing AccessLevel: if a match for 
+     * <tt>stringRight</tt> is found, <tt>isRegular</tt> and <tt>isGlobal</tt> are ignored.
+     * 
+     * @see AccessLevel#valueOf(String)
+     */
+    public static AccessLevel valueOf(String stringRight, boolean isRegular, boolean isGlobal) {
+        String cleanRightString = stringRight.trim().toLowerCase();
+        for (Iterator it = AccessLevel.values.iterator(); it.hasNext();) {
+            AccessLevel current = (AccessLevel)it.next();
+            if (current.getRightString().equals(cleanRightString)) {
+                return current;
+            }
+        }
+        //create a new accessLevel, that defaults on false, false
+        return new AccessLevel(stringRight, isRegular, isGlobal);        
+    }
+
+    public String getRightString()
+    {
+        return rightString;
+    }
+    
+    public int hashCode()
+    {
+        return this.rightString.hashCode();
+    }
+    
+    public String toString()
+    {
+        return this.rightString;
+    }
+    
+    public static List listRegularAccessLevels() {
+        return new ArrayList(AccessLevel.regularAccessLevels);
+    }
+    
+    public static List listGlobalAccessLevels() {
+        return new ArrayList(AccessLevel.globalAccessLevels);
+    }
+
+    public static AccessLevel getADMIN()
+    {
+        return ADMIN;
+    }
+
+    public static AccessLevel getCOMMENT()
+    {
+        return COMMENT;
+    }
+
+    public static AccessLevel getDELETE()
+    {
+        return DELETE;
+    }
+
+    public static AccessLevel getDOWNLOAD()
+    {
+        return DOWNLOAD;
+    }
+
+    public static AccessLevel getEDIT()
+    {
+        return EDIT;
+    }
+
+    public static AccessLevel getLOGIN()
+    {
+        return LOGIN;
+    }
+
+    public static AccessLevel getPROGRAMMING()
+    {
+        return PROGRAMMING;
+    }
+
+    public static AccessLevel getREGISTER()
+    {
+        return REGISTER;
+    }
+
+    public static AccessLevel getVIEW()
+    {
+        return VIEW;
+    }
+}
Index: src/main/java/com/xpn/xwiki/api/XWiki.java
===================================================================
--- src/main/java/com/xpn/xwiki/api/XWiki.java	(revision 3976)
+++ src/main/java/com/xpn/xwiki/api/XWiki.java	(working copy)
@@ -101,7 +101,7 @@
     public Document getDocument(String fullname) throws XWikiException
     {
         XWikiDocument doc = xwiki.getDocument(fullname, getXWikiContext());
-        if (xwiki.getRightService().hasAccessLevel("view", getXWikiContext().getUser(),
+        if (xwiki.getRightService().hasAccessLevel(AccessLevel.VIEW, getXWikiContext().getUser(),
             doc.getFullName(), getXWikiContext()) == false) {
             return null;
         }
@@ -123,24 +123,34 @@
     }
 
     /**
+     * @see XWiki#checkAccess(String, DocumentAction)
+     * @deprecated use {@link XWiki#checkAccess(String, DocumentAction)}
+     */
+    public boolean checkAccess(String docname, String right)
+    {
+        DocumentAction action = DocumentAction.valueOf(right);
+        return this.checkAccess(docname, action);
+    }
+    
+    /**
      * Verify the rights the current user has on a document. If the document requires rights and the
      * user is not authenticated he will be redirected to the login page.
      * 
      * @param docname fullname of the document
-     * @param right right to check ("view", "edit", "admin", "delete")
+     * @param right right to check
      * @return true if it exists
      */
-    public boolean checkAccess(String docname, String right)
+    public boolean checkAccess(String docname, DocumentAction action)
     {
         try {
             XWikiDocument doc = new XWikiDocument();
             doc.setFullName(docname, getXWikiContext());
-            return getXWikiContext().getWiki().checkAccess(right, doc, getXWikiContext());
+            return getXWikiContext().getWiki().checkAccess(action, doc, getXWikiContext());
         } catch (XWikiException e) {
             return false;
         }
     }
-
+    
     /**
      * Loads an Document from the database. Rights are checked before sending back the document.
      * 
@@ -152,7 +162,7 @@
     public Document getDocument(String web, String fullname) throws XWikiException
     {
         XWikiDocument doc = xwiki.getDocument(web, fullname, getXWikiContext());
-        if (xwiki.getRightService().hasAccessLevel("view", getXWikiContext().getUser(),
+        if (xwiki.getRightService().hasAccessLevel(AccessLevel.VIEW, getXWikiContext().getUser(),
             doc.getFullName(), getXWikiContext()) == false) {
             return null;
         }
@@ -174,7 +184,7 @@
         if ((doc == null) || (doc.getDoc() == null))
             return null;
 
-        if (xwiki.getRightService().hasAccessLevel("view", getXWikiContext().getUser(),
+        if (xwiki.getRightService().hasAccessLevel(AccessLevel.VIEW, getXWikiContext().getUser(),
             doc.getFullName(), getXWikiContext()) == false) {
             // Finally we return null, otherwise showing search result is a real pain
             return null;
@@ -947,7 +957,7 @@
                 registerRight = true;
             } else {
                 registerRight =
-                    xwiki.getRightService().hasAccessLevel("register",
+                    xwiki.getRightService().hasAccessLevel(AccessLevel.REGISTER,
                         getXWikiContext().getUser(), "XWiki.XWikiPreferences", getXWikiContext());
             }
 
@@ -1304,22 +1314,42 @@
     }
 
     /**
+     * @see XWiki#hasAccessLevel(AccessLevel)
+     * @deprecated use {@link XWiki#hasAccessLevel(AccessLevel)} 
+     */
+    public boolean hasAccessLevel(String level)
+    {
+        AccessLevel accessLevel = AccessLevel.valueOf(level);
+        return this.hasAccessLevel(accessLevel);
+    }
+
+    /**
      * API to check rights on the current document for the current user
      * 
      * @param level right to check (view, edit, comment, delete)
      * @return true if right is granted/false if not
      */
-    public boolean hasAccessLevel(String level)
+    public boolean hasAccessLevel(AccessLevel level)
     {
         try {
             return xwiki.getRightService().hasAccessLevel(level, getXWikiContext().getUser(),
                 getXWikiContext().getDoc().getFullName(), getXWikiContext());
         } catch (Exception e) {
             return false;
-        }
+        }        
     }
 
     /**
+     * @see XWiki#hasAccessLevel(AccessLevel, String, String) 
+     * @deprecated use {@link XWiki#hasAccessLevel(AccessLevel, String, String)}
+     */
+    public boolean hasAccessLevel(String level, String user, String docname)
+    {
+        AccessLevel accessLevel = AccessLevel.valueOf(level);
+        return this.hasAccessLevel(accessLevel, user, docname);
+    }
+    
+    /**
      * v * API to check rights on a document for a given user
      * 
      * @param level right to check (view, edit, comment, delete)
@@ -1327,14 +1357,14 @@
      * @param docname document on which to check the rights
      * @return true if right is granted/false if not
      */
-    public boolean hasAccessLevel(String level, String user, String docname)
+    public boolean hasAccessLevel(AccessLevel level, String user, String docname) 
     {
         try {
             return xwiki.getRightService()
                 .hasAccessLevel(level, user, docname, getXWikiContext());
         } catch (Exception e) {
             return false;
-        }
+        }        
     }
 
     /**
@@ -1537,7 +1567,7 @@
      */
     public String getURL(String fullname) throws XWikiException
     {
-        return xwiki.getURL(fullname, "view", getXWikiContext());
+        return xwiki.getURL(fullname, DocumentAction.VIEW, getXWikiContext());
     }
 
     /**
@@ -1553,10 +1583,20 @@
      * @return a URL as a string pointing to the wiki document in view mode
      * @throws XWikiException if the URL could not be generated properly
      */
-    public String getURL(String fullname, String action) throws XWikiException
+    public String getURL(String fullname, DocumentAction action) throws XWikiException
     {
         return xwiki.getURL(fullname, action, getXWikiContext());
     }
+    
+    /**
+     *  @see XWiki#getURL(String, DocumentAction)
+     *  @deprecated use {@link XWiki#getURL(String, DocumentAction)} 
+     */
+    public String getURL(String fullname, String action) throws XWikiException
+    {
+        DocumentAction documentAction = DocumentAction.valueOf(action);
+        return this.getURL(fullname, documentAction);
+    }    
 
     /**
      * API to retrieve the URL of an a Wiki Document in any mode, optionally adding a query string
@@ -1574,11 +1614,22 @@
      * @return a URL as a string pointing to the wiki document in view mode
      * @throws XWikiException if the URL could not be generated properly
      */
-    public String getURL(String fullname, String action, String querystring)
+    public String getURL(String fullname, DocumentAction action, String querystring)
         throws XWikiException
     {
         return xwiki.getURL(fullname, action, querystring, getXWikiContext());
     }
+    
+    /**
+     *  @see XWiki#getURL(String, DocumentAction, String)
+     *  @deprecated use {@link XWiki#getURL(String, DocumentAction, String)} 
+     */
+    public String getURL(String fullname, String action, String querystring)
+        throws XWikiException
+    {
+        DocumentAction documentAction = DocumentAction.valueOf(action);
+        return this.getURL(fullname, documentAction, querystring);
+    }    
 
     /**
      * @see #getExoService(String)
@@ -1723,11 +1774,21 @@
      * @return A DocumentStats object with number of actions performed, unique visitors, number of
      *         visits
      */
-    public DocumentStats getCurrentMonthXWikiStats(String action)
+    public DocumentStats getCurrentMonthXWikiStats(DocumentAction action)
     {
         return getXWikiContext().getWiki().getStatsService(getXWikiContext()).getDocMonthStats(
             "", action, new Date(), getXWikiContext());
     }
+    
+    /**
+     * @see XWiki#getCurrentMonthXWikiStats(DocumentAction)
+     * @deprecated use {@link XWiki#getCurrentMonthXWikiStats(DocumentAction)}
+     */
+    public DocumentStats getCurrentMonthXWikiStats(String action)
+    {
+        DocumentAction documentAction = DocumentAction.valueOf(action);
+        return this.getCurrentMonthXWikiStats(documentAction);
+    }
 
     /**
      * API to retrieve a viewable referer text for a referer Referers are URL where users have
@@ -1988,17 +2049,27 @@
     /**
      * Returns the recently visited pages for a specific action
      * 
-     * @param action ("view" or "edit")
+     * @param action ({@link DocumentAction#VIEW} or {@link DocumentAction#EDIT})
      * @param size how many recent actions to retrieve
      * @return a ArrayList of document names
      */
-    public java.util.Collection getRecentActions(String action, int size)
+    public java.util.Collection getRecentActions(DocumentAction action, int size)
     {
         XWikiStatsService stats = getXWikiContext().getWiki().getStatsService(getXWikiContext());
         if (stats == null)
             return new ArrayList();
         return stats.getRecentActions(action, size, getXWikiContext());
     }
+    
+    /**
+     * @see XWiki#getRecentActions(DocumentAction, int)
+     * @deprecated use {@link XWiki#getRecentActions(DocumentAction, int)} 
+     */
+    public java.util.Collection getRecentActions(String action, int size)
+    {
+        DocumentAction documentAction = DocumentAction.valueOf(action);
+        return this.getRecentActions(documentAction, size);
+    }    
 
     /**
      * Returns the Advertisement system from the preferences
@@ -2334,10 +2405,10 @@
     {
         try {
             if (xwiki.exists(newFullName, getXWikiContext())
-                && !xwiki.getRightService().hasAccessLevel("delete", getXWikiContext().getUser(),
+                && !xwiki.getRightService().hasAccessLevel(AccessLevel.DELETE, getXWikiContext().getUser(),
                     newFullName, getXWikiContext()))
                 return false;
-            if (xwiki.getRightService().hasAccessLevel("edit", getXWikiContext().getUser(),
+            if (xwiki.getRightService().hasAccessLevel(AccessLevel.EDIT, getXWikiContext().getUser(),
                 doc.getFullName(), getXWikiContext())) {
                 xwiki.renamePage(doc.getFullName(), newFullName, getXWikiContext());
             }
Index: src/main/java/com/xpn/xwiki/pdf/impl/PdfURLFactory.java
===================================================================
--- src/main/java/com/xpn/xwiki/pdf/impl/PdfURLFactory.java	(revision 3976)
+++ src/main/java/com/xpn/xwiki/pdf/impl/PdfURLFactory.java	(working copy)
@@ -22,6 +22,7 @@
 package com.xpn.xwiki.pdf.impl;
 
 import com.xpn.xwiki.XWikiContext;
+import com.xpn.xwiki.api.DocumentAction;
 import com.xpn.xwiki.doc.XWikiAttachment;
 import com.xpn.xwiki.doc.XWikiDocument;
 import com.xpn.xwiki.web.XWikiServletURLFactory;
@@ -35,7 +36,7 @@
     public PdfURLFactory() {
     }
 
-    public URL createAttachmentURL(String filename, String web, String name, String action, String querystring, String xwikidb, XWikiContext context) {
+    public URL createAttachmentURL(String filename, String web, String name, DocumentAction action, String querystring, String xwikidb, XWikiContext context) {
         try {
             File tempdir = (File) context.get("pdfexportdir");
             File file = new File(tempdir, web + "." + name + "." + filename);
Index: src/main/java/com/xpn/xwiki/XWiki.java
===================================================================
--- src/main/java/com/xpn/xwiki/XWiki.java	(revision 3976)
+++ src/main/java/com/xpn/xwiki/XWiki.java	(working copy)
@@ -75,8 +75,10 @@
 import org.hibernate.HibernateException;
 import org.securityfilter.filter.URLPatternMatcher;
 
+import com.xpn.xwiki.api.AccessLevel;
 import com.xpn.xwiki.api.Api;
 import com.xpn.xwiki.api.Document;
+import com.xpn.xwiki.api.DocumentAction;
 import com.xpn.xwiki.api.User;
 import com.xpn.xwiki.cache.api.XWikiCache;
 import com.xpn.xwiki.cache.api.XWikiCacheNeedsRefreshException;
@@ -206,7 +208,7 @@
     private XWikiCache virtualWikiMap;
 
     private static Map threadMap = new HashMap();
-
+    
     private boolean isReadOnly = false;
 
     public static final String CFG_ENV_NAME = "XWikiConfig";
@@ -1435,7 +1437,7 @@
         }
         try {
             if (skin.indexOf(".") != -1) {
-                if (!getRightService().hasAccessLevel("view", context.getUser(), skin, context))
+                if (!getRightService().hasAccessLevel(AccessLevel.VIEW, context.getUser(), skin, context))
                     skin = Param("xwiki.defaultskin", getDefaultBaseSkin(context));
             }
         } catch (XWikiException e) {
@@ -3011,11 +3013,23 @@
     {
         return getAuthService().checkAuth(context);
     }
-
+    
+    /**
+     * @see XWiki#checkAccess(DocumentAction, XWikiDocument, XWikiContext)
+     * 
+     * @deprecated use {@link XWiki#checkAccess(DocumentAction, XWikiDocument, XWikiContext)}
+     */
     public boolean checkAccess(String action, XWikiDocument doc, XWikiContext context)
         throws XWikiException
     {
-        if (action.equals("skin") && doc.getSpace().equals("skins"))
+        DocumentAction documentAction = DocumentAction.valueOf(action);
+        return this.checkAccess(documentAction, doc, context);
+    }    
+    
+    public boolean checkAccess(DocumentAction action, XWikiDocument doc, XWikiContext context)
+        throws XWikiException
+    {
+        if (action.equals(DocumentAction.SKIN) && doc.getSpace().equals("skins"))
             return true;
         return getRightService().checkAccess(action, doc, context);
     }
@@ -3088,7 +3102,7 @@
                 doc =
                     getDocument(((XWikiDocument) context.get("doc")).getSpace(), topic, context);
 
-                if (checkAccess("view", doc, context) == false) {
+                if (checkAccess(DocumentAction.VIEW, doc, context) == false) {
                     throw new XWikiException(XWikiException.MODULE_XWIKI_ACCESS,
                         XWikiException.ERROR_XWIKI_ACCESS_DENIED,
                         "Access to this document is denied");
@@ -3641,7 +3655,7 @@
             return null;
     }
 
-    public String getURL(String fullname, String action, XWikiContext context)
+    public String getURL(String fullname, DocumentAction action, XWikiContext context)
         throws XWikiException
     {
         XWikiDocument doc = new XWikiDocument();
@@ -3652,10 +3666,21 @@
                 doc.getDatabase(), context);
         return context.getURLFactory().getURL(url, context);
     }
-
-    public String getExternalURL(String fullname, String action, XWikiContext context)
+    
+    /**
+     * @see XWiki#getURL(String, DocumentAction, XWikiContext)
+     * @deprecated use {@link XWiki#getURL(String, DocumentAction, XWikiContext)}
+     */
+    public String getURL(String fullname, String action, XWikiContext context)
         throws XWikiException
     {
+        DocumentAction documentAction = DocumentAction.valueOf(action);
+        return this.getURL(fullname, documentAction, context);
+    }
+    
+    public String getExternalURL(String fullname, DocumentAction action, XWikiContext context)
+        throws XWikiException
+    {
         XWikiDocument doc = new XWikiDocument();
         doc.setFullName(fullname, context);
 
@@ -3664,8 +3689,19 @@
                 null, null, doc.getDatabase(), context);
         return url.toString();
     }
+    
+    /**
+     * @see XWiki#getExternalURL(String, DocumentAction, XWikiContext)
+     * @deprecated use {@link XWiki#getExternalURL(String, DocumentAction, XWikiContext)} 
+     */
+    public String getExternalURL(String fullname, String action, XWikiContext context)
+        throws XWikiException     
+    {
+        DocumentAction documentAction = DocumentAction.valueOf(action);
+        return this.getExternalURL(fullname, documentAction, context);
+    }
 
-    public String getExternalURL(String fullname, String action, String querystring,
+    public String getExternalURL(String fullname, DocumentAction action, String querystring,
         XWikiContext context) throws XWikiException
     {
         XWikiDocument doc = new XWikiDocument();
@@ -3676,10 +3712,21 @@
                 querystring, null, doc.getDatabase(), context);
         return url.toString();
     }
-
-    public String getURL(String fullname, String action, String querystring, XWikiContext context)
-        throws XWikiException
+    
+    /**
+     *  @see XWiki#getExternalURL(String, DocumentAction, String, XWikiContext)
+     *  @deprecated  use {@link XWiki#getExternalURL(String, DocumentAction, String, XWikiContext)}
+     */
+    public String getExternalURL(String fullname, String action, String querystring,
+        XWikiContext context) throws XWikiException
     {
+        DocumentAction documentAction = DocumentAction.valueOf(action);
+        return this.getExternalURL(fullname, documentAction, querystring, context);
+    }
+    
+    public String getURL(String fullname, DocumentAction action, String querystring,
+        XWikiContext context) throws XWikiException
+    {
         XWikiDocument doc = new XWikiDocument();
         doc.setFullName(fullname, context);
 
@@ -3688,13 +3735,24 @@
                 null, doc.getDatabase(), context);
         return context.getURLFactory().getURL(url, context);
     }
-
+    
+    /**
+     * @see XWiki#getURL(String, DocumentAction, String, XWikiContext)
+     * @deprecated use {@link XWiki#getURL(String, DocumentAction, String, XWikiContext)} 
+     */
+    public String getURL(String fullname, String action, String querystring,
+        XWikiContext context) throws XWikiException 
+    {
+        DocumentAction documentAction = DocumentAction.valueOf(action);
+        return this.getURL(fullname, documentAction, querystring, context);
+    }
+    
     public String getAttachmentURL(String fullname, String filename, XWikiContext context)
         throws XWikiException
     {
         XWikiDocument doc = new XWikiDocument();
         doc.setFullName(fullname, context);
-        return doc.getAttachmentURL(filename, "download", context);
+        return doc.getAttachmentURL(filename, DocumentAction.DOWNLOAD, context);
     }
 
     // Usefull date functions
@@ -3771,9 +3829,9 @@
         } else if (context.getMode() == XWikiContext.MODE_XMLRPC) {
             docname = context.getDoc().getFullName();
         } else {
-            String action = context.getAction();
+            DocumentAction action = context.getAction();
             if ((request.getParameter("topic") != null)
-                && (action.equals("edit") || action.equals("inline")))
+                && (action.equals(DocumentAction.EDIT) || action.equals(DocumentAction.INLINE)))
                 docname = request.getParameter("topic");
             else {
                 // TODO: Introduce a XWikiURL class in charge of getting the information relevant
@@ -3843,7 +3901,7 @@
         XWikiDocument doc;
         context.getWiki().prepareResources(context);
         String docName = getDocumentName(request, context);
-        if (context.getAction().equals("register")) {
+        if (context.getAction().equals(DocumentAction.REGISTER)) {
             setPhonyDocument(docName, context, vcontext);
             doc = context.getDoc();
         } else {
@@ -3851,11 +3909,11 @@
                 doc = getDocument(docName, context);
             } catch (XWikiException e) {
                 doc = context.getDoc();
-                if (context.getAction().equals("delete")) {
+                if (context.getAction().equals(DocumentAction.DELETE)) {
                     if (doc == null) {
                         setPhonyDocument(docName, context, vcontext);
                     }
-                    if (!checkAccess("admin", doc, context)) {
+                    if (!checkAccess(DocumentAction.ADMIN, doc, context)) {
                         throw e;
                     }
                 } else {
@@ -4327,8 +4385,8 @@
             if (link == false)
                 return text;
             else {
-                return "<span class=\"wikilink\"><a href=\"" + userdoc.getURL("view", context)
-                    + "\">" + text + "</a></span>";
+                return "<span class=\"wikilink\"><a href=\""
+                    + userdoc.getURL(DocumentAction.VIEW, context) + "\">" + text + "</a></span>";
             }
         } catch (Exception e) {
             e.printStackTrace();
@@ -5393,7 +5451,7 @@
     {
         XWikiDocument doc = new XWikiDocument();
         doc.setFullName(fullName, context);
-        return doc.getExternalAttachmentURL(filename, "download", context);
+        return doc.getExternalAttachmentURL(filename, DocumentAction.DOWNLOAD, context);
     }
 
     public int getMaxRecursiveSpaceChecks(XWikiContext context)
Index: src/main/java/com/xpn/xwiki/web/Utils.java
===================================================================
--- src/main/java/com/xpn/xwiki/web/Utils.java	(revision 3976)
+++ src/main/java/com/xpn/xwiki/web/Utils.java	(working copy)
@@ -25,6 +25,7 @@
 import com.xpn.xwiki.XWiki;
 import com.xpn.xwiki.XWikiContext;
 import com.xpn.xwiki.XWikiException;
+import com.xpn.xwiki.api.DocumentAction;
 import com.xpn.xwiki.plugin.fileupload.FileUploadPlugin;
 import com.xpn.xwiki.xmlrpc.XWikiXMLRPCRequest;
 import org.apache.commons.fileupload.FileItem;
@@ -58,9 +59,9 @@
             response.setContentType("text/html; charset=" + context.getWiki().getEncoding());
         }
 
-        String action = context.getAction();
-        if ((!"download".equals(action))
-                && (!"skin".equals(action))) {
+        DocumentAction action = context.getAction();
+        if ((!DocumentAction.DOWNLOAD.equals(action))
+                && (!DocumentAction.SKIN.equals(action))) {
             if (context.getResponse() instanceof XWikiServletResponse) {
                 // Add a last modified to tell when the page was last updated
                 if (context.getWiki().getXWikiPreferenceAsLong("headers_lastmodified", 0, context) != 0) {
@@ -82,8 +83,8 @@
             }
         }
 
-        if (("download".equals(action))
-                || ("skin".equals(action))) {
+        if ((DocumentAction.DOWNLOAD.equals(action))
+                || (DocumentAction.SKIN.equals(action))) {
             // Set a nocache to make sure these files are not cached by proxies
             if (context.getWiki().getXWikiPreferenceAsLong("headers_nocache", 1, context) != 0) {
                 response.setHeader("Cache-Control", "no-cache");
@@ -136,7 +137,7 @@
         return redirect;
     }
 
-    public static String getRedirect(String action, XWikiContext context) {
+    public static String getRedirect(DocumentAction action, XWikiContext context) {
         String redirect;
         redirect = context.getRequest().getParameter("xredirect");
         if ((redirect == null) || (redirect.equals("")))
@@ -194,8 +195,19 @@
         }
         return data;
     }
+    
+    /**
+     * @see Utils#prepareContext(DocumentAction, XWikiRequest, XWikiResponse, XWikiEngineContext)
+     * @deprecated use
+     *             {@link Utils#prepareContext(DocumentAction, XWikiRequest, XWikiResponse, XWikiEngineContext)}
+     */
+    public static XWikiContext prepareContext(String action, XWikiRequest request, XWikiResponse response,
+        XWikiEngineContext engine_context) throws XWikiException {
+        DocumentAction documentAction = DocumentAction.valueOf(action);
+        return Utils.prepareContext(documentAction, request, response, engine_context);
+    }
 
-    public static XWikiContext prepareContext(String action, XWikiRequest request, XWikiResponse response,
+    public static XWikiContext prepareContext(DocumentAction action, XWikiRequest request, XWikiResponse response,
                                               XWikiEngineContext engine_context) throws XWikiException {
         // Test works with xwiki-test.cfg instead of xwiki.cfg
         XWikiContext context = new XWikiContext();
Index: src/main/java/com/xpn/xwiki/web/XWikiDefaultURLFactory.java
===================================================================
--- src/main/java/com/xpn/xwiki/web/XWikiDefaultURLFactory.java	(revision 3976)
+++ src/main/java/com/xpn/xwiki/web/XWikiDefaultURLFactory.java	(working copy)
@@ -22,23 +22,24 @@
 package com.xpn.xwiki.web;
 
 import com.xpn.xwiki.XWikiContext;
+import com.xpn.xwiki.api.DocumentAction;
 
 import java.net.URL;
 
 public abstract class XWikiDefaultURLFactory implements XWikiURLFactory {
     public URL createURL(String web, String name, XWikiContext context) {
-        return createURL(web, name, "view", null, null, context);
+        return createURL(web, name, DocumentAction.VIEW, null, null, context);
     }
 
-    public URL createExternalURL(String web, String name, String action, String querystring, String anchor, XWikiContext context) {
+    public URL createExternalURL(String web, String name, DocumentAction action, String querystring, String anchor, XWikiContext context) {
         return createExternalURL(web, name, action, querystring, anchor, context.getDatabase(), context);
     }
 
-    public URL createURL(String web, String name, String action, XWikiContext context) {
+    public URL createURL(String web, String name, DocumentAction action, XWikiContext context) {
         return createURL(web, name, action, null, null, context);
     }
 
-    public URL createURL(String web, String name, String action, String querystring, String anchor, XWikiContext context) {
+    public URL createURL(String web, String name, DocumentAction action, String querystring, String anchor, XWikiContext context) {
         return createURL(web, name, action, querystring, anchor, context.getDatabase(), context);
     }
 
@@ -46,7 +47,7 @@
         return createSkinURL(filename, web, name, context.getDatabase(), context);
     }
 
-    public URL createAttachmentURL(String filename, String web, String name, String action, String querystring, XWikiContext context) {
+    public URL createAttachmentURL(String filename, String web, String name, DocumentAction action, String querystring, XWikiContext context) {
         return createAttachmentURL(filename, web, name, action, querystring, context.getDatabase(), context);
     }
 
Index: src/main/java/com/xpn/xwiki/web/AdminAction.java
===================================================================
--- src/main/java/com/xpn/xwiki/web/AdminAction.java	(revision 3976)
+++ src/main/java/com/xpn/xwiki/web/AdminAction.java	(working copy)
@@ -23,7 +23,6 @@
 
 import com.xpn.xwiki.XWikiContext;
 import com.xpn.xwiki.XWikiException;
-import com.xpn.xwiki.api.Document;
 import com.xpn.xwiki.doc.XWikiDocument;
 import com.xpn.xwiki.doc.XWikiLock;
 import org.apache.commons.logging.Log;
Index: src/main/java/com/xpn/xwiki/web/XWikiAction.java
===================================================================
--- src/main/java/com/xpn/xwiki/web/XWikiAction.java	(revision 3976)
+++ src/main/java/com/xpn/xwiki/web/XWikiAction.java	(working copy)
@@ -25,6 +25,7 @@
 import com.xpn.xwiki.XWiki;
 import com.xpn.xwiki.XWikiContext;
 import com.xpn.xwiki.XWikiException;
+import com.xpn.xwiki.api.DocumentAction;
 import com.xpn.xwiki.doc.XWikiDocument;
 import com.xpn.xwiki.monitor.api.MonitorPlugin;
 import com.xpn.xwiki.plugin.fileupload.FileUploadPlugin;
@@ -75,7 +76,8 @@
                                  HttpServletRequest req,
                                  HttpServletResponse resp)
             throws Exception, ServletException {
-        String action = mapping.getName();
+        
+        DocumentAction action = DocumentAction.valueOf(mapping.getName());
 
         MonitorPlugin monitor = null;
         FileUploadPlugin fileupload = null;
@@ -84,7 +86,7 @@
         try {
             XWikiRequest request = new XWikiServletRequest(req);
             XWikiResponse response = new XWikiServletResponse(resp);
-            context = Utils.prepareContext(mapping.getName(), request, response,
+            context = Utils.prepareContext(action, request, response,
                     new XWikiServletContext(servlet.getServletContext()));
 
             // Add the form to the context
@@ -119,7 +121,7 @@
             // Start monitoring timer
             monitor = (MonitorPlugin) xwiki.getPlugin("monitor", context);
             if (monitor != null)
-                monitor.startRequest("", mapping.getName(), context.getURL());
+                monitor.startRequest("", action, context.getURL());
             if (monitor != null)
                 monitor.startTimer("request");
 
@@ -134,7 +136,7 @@
 
                 // Let's handle the notification and make sure it never fails
                 try {
-                    xwiki.getNotificationManager().preverify(context.getDoc(), mapping.getName(), context);
+                    xwiki.getNotificationManager().preverify(context.getDoc(), action, context);
                 }
                 catch (Throwable e) {
                     e.printStackTrace();
@@ -149,7 +151,8 @@
                 }
 
                 if (renderResult != null) {
-                    if ((doc.isNew() && ("view".equals(action) || "delete".equals(action)))) {
+                    if ((doc.isNew() && (DocumentAction.VIEW.equals(action) 
+                        || DocumentAction.DELETE.equals(action)))) {
                         String page = Utils.getPage(request, "docdoesnotexist");
                         Utils.parseTemplate(page, context);
                     } else {
@@ -160,8 +163,8 @@
                 return null;
             } catch (Throwable e) {
                 if (!(e instanceof XWikiException)) {
-                   e = new XWikiException(XWikiException.MODULE_XWIKI_APP, XWikiException.ERROR_XWIKI_UNKNOWN,
-                            "Uncaught exception", e);
+                   e = new XWikiException(XWikiException.MODULE_XWIKI_APP, 
+                                          XWikiException.ERROR_XWIKI_UNKNOWN, "Uncaught exception", e);
                 }
 
                 try {
@@ -207,7 +210,7 @@
 
                 // Let's handle the notification and make sure it never fails
                 try {
-                    xwiki.getNotificationManager().verify(context.getDoc(), mapping.getName(), context);
+                    xwiki.getNotificationManager().verify(context.getDoc(), action, context);
                 } catch (Throwable e) {
                     e.printStackTrace();
                     }
Index: src/main/java/com/xpn/xwiki/web/XWikiURLFactory.java
===================================================================
--- src/main/java/com/xpn/xwiki/web/XWikiURLFactory.java	(revision 3976)
+++ src/main/java/com/xpn/xwiki/web/XWikiURLFactory.java	(working copy)
@@ -22,27 +22,28 @@
 package com.xpn.xwiki.web;
 
 import com.xpn.xwiki.XWikiContext;
+import com.xpn.xwiki.api.DocumentAction;
 
 import java.net.URL;
 
 public interface XWikiURLFactory {
     public void init(XWikiContext context);
     public URL createURL(String web, String name, XWikiContext context);
-    public URL createURL(String web, String name, String action, XWikiContext context);
-    public URL createURL(String web, String name, String action, boolean redirect, XWikiContext context);
-    public URL createURL(String web, String name, String action, String querystring, String anchor,
+    public URL createURL(String web, String name, DocumentAction action, XWikiContext context);
+    public URL createURL(String web, String name, DocumentAction action, boolean redirect, XWikiContext context);
+    public URL createURL(String web, String name, DocumentAction action, String querystring, String anchor,
                          XWikiContext context);
-    public URL createExternalURL(String web, String name, String action, String querystring, String anchor,
+    public URL createExternalURL(String web, String name, DocumentAction action, String querystring, String anchor,
                          XWikiContext context);
-    public URL createURL(String web, String name, String action, String querystring, String anchor,
+    public URL createURL(String web, String name, DocumentAction action, String querystring, String anchor,
                          String xwikidb, XWikiContext context);
-    public URL createExternalURL(String web, String name, String action, String querystring, String anchor,
+    public URL createExternalURL(String web, String name, DocumentAction action, String querystring, String anchor,
                          String xwikidb, XWikiContext context);
     public URL createSkinURL(String filename, String skin, XWikiContext context);
     public URL createSkinURL(String filename, String web, String name, XWikiContext context);
     public URL createSkinURL(String filename, String web, String name, String xwikidb, XWikiContext context);
-    public URL createAttachmentURL(String filename, String web, String name, String action, String querystring, XWikiContext context);
-    public URL createAttachmentURL(String filename, String web, String name, String action, String querystring, String xwikidb, XWikiContext context);
+    public URL createAttachmentURL(String filename, String web, String name, DocumentAction action, String querystring, XWikiContext context);
+    public URL createAttachmentURL(String filename, String web, String name, DocumentAction action, String querystring, String xwikidb, XWikiContext context);
     public URL createAttachmentRevisionURL(String filename, String web, String name, String revision, String querystring, XWikiContext context);
     public URL createAttachmentRevisionURL(String filename, String web, String name, String revision, String querystring, String xwikidb, XWikiContext context);
     public URL getRequestURL(XWikiContext context);
Index: src/main/java/com/xpn/xwiki/web/LogoutAction.java
===================================================================
--- src/main/java/com/xpn/xwiki/web/LogoutAction.java	(revision 3976)
+++ src/main/java/com/xpn/xwiki/web/LogoutAction.java	(working copy)
@@ -18,21 +18,26 @@
  * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
  *
  */
-package com.xpn.xwiki.web;
-
-import com.xpn.xwiki.XWikiContext;
-import com.xpn.xwiki.XWikiException;
-
-public class LogoutAction extends XWikiAction {
-	public boolean action(XWikiContext context) throws XWikiException {
-        XWikiRequest request = context.getRequest();
-        XWikiResponse response = context.getResponse();
-
-        String redirect;
-        redirect = context.getRequest().getParameter("xredirect");
-        if ((redirect == null)||(redirect.equals("")))
-            redirect = context.getURLFactory().createURL("Main", "WebHome", "view", context).toString();
-        sendRedirect(response, redirect);
-        return false;
-	}
-}
+package com.xpn.xwiki.web;
+
+import com.xpn.xwiki.XWikiContext;
+import com.xpn.xwiki.XWikiException;
+import com.xpn.xwiki.api.DocumentAction;
+
+public class LogoutAction extends XWikiAction
+{
+    public boolean action(XWikiContext context) throws XWikiException
+    {
+        XWikiRequest request = context.getRequest();
+        XWikiResponse response = context.getResponse();
+
+        String redirect;
+        redirect = context.getRequest().getParameter("xredirect");
+        if ((redirect == null) || (redirect.equals("")))
+            redirect =
+                context.getURLFactory()
+                    .createURL("Main", "WebHome", DocumentAction.VIEW, context).toString();
+        sendRedirect(response, redirect);
+        return false;
+    }
+}
Index: src/main/java/com/xpn/xwiki/web/CommentAddAction.java
===================================================================
--- src/main/java/com/xpn/xwiki/web/CommentAddAction.java	(revision 3976)
+++ src/main/java/com/xpn/xwiki/web/CommentAddAction.java	(working copy)
@@ -23,6 +23,7 @@
 import com.xpn.xwiki.XWiki;
 import com.xpn.xwiki.XWikiContext;
 import com.xpn.xwiki.XWikiException;
+import com.xpn.xwiki.api.DocumentAction;
 import com.xpn.xwiki.doc.XWikiDocument;
 import com.xpn.xwiki.objects.BaseObject;
 import com.xpn.xwiki.objects.classes.BaseClass;
@@ -60,10 +61,10 @@
                 xwiki.saveDocument(doc, olddoc, context.getMessageTool().get("core.comment.addComment"), context);
             }
             // forward to edit
-            String redirect = Utils.getRedirect("edit", context);
+            String redirect = Utils.getRedirect(DocumentAction.EDIT, context);
             sendRedirect(response, redirect);
         } else {
-                String url = context.getDoc().getURL("view", "xpage=comments&confirm=false",context);
+                String url = context.getDoc().getURL(DocumentAction.VIEW, "xpage=comments&confirm=false",context);
             try {
                 response.sendRedirect(url);
             } catch (Exception e) {
Index: src/main/java/com/xpn/xwiki/web/XWikiServletURLFactory.java
===================================================================
--- src/main/java/com/xpn/xwiki/web/XWikiServletURLFactory.java	(revision 3976)
+++ src/main/java/com/xpn/xwiki/web/XWikiServletURLFactory.java	(working copy)
@@ -24,6 +24,7 @@
 import com.xpn.xwiki.XWiki;
 import com.xpn.xwiki.XWikiContext;
 import com.xpn.xwiki.XWikiException;
+import com.xpn.xwiki.api.DocumentAction;
 import com.xpn.xwiki.doc.XWikiAttachment;
 import com.xpn.xwiki.doc.XWikiDocument;
 import org.apache.commons.logging.Log;
@@ -139,17 +140,17 @@
         }
     }
 
-    public URL createURL(String web, String name, String action, boolean redirect,
+    public URL createURL(String web, String name, DocumentAction action, boolean redirect,
         XWikiContext context)
     {
         return createURL(web, name, action, context);
     }
 
-    public URL createURL(String web, String name, String action, String querystring,
+    public URL createURL(String web, String name, DocumentAction action, String querystring,
         String anchor, String xwikidb, XWikiContext context)
     {
         // Action and Query String transformers
-        if (("view".equals(action)) && (context.getLinksAction() != null)) {
+        if ((DocumentAction.VIEW.equals(action)) && (context.getLinksAction() != null)) {
             action = context.getLinksAction();
         }
         if (context.getLinksQueryString() != null) {
@@ -185,21 +186,22 @@
         }
     }
 
-    private void addAction(StringBuffer newpath, String action, XWikiContext context)
+    private void addAction(StringBuffer newpath, DocumentAction action, XWikiContext context)
     {
         boolean showViewAction = context.getWiki().showViewAction(context);
-        if ((!"view".equals(action) || (showViewAction))) {
-            newpath.append(action);
+        if ((!DocumentAction.VIEW.equals(action) || (showViewAction))) {
+            newpath.append(action.toString());
             newpath.append("/");
         }
     }
 
-    private void addSpace(StringBuffer newpath, String web, String action, XWikiContext context)
+    private void addSpace(StringBuffer newpath, String web, DocumentAction action,
+        XWikiContext context)
     {
         boolean useDefaultWeb = context.getWiki().useDefaultWeb(context);
         if (useDefaultWeb) {
             String defaultWeb = context.getWiki().getDefaultWeb(context);
-            useDefaultWeb = (web.equals(defaultWeb)) && ("view".equals(action));
+            useDefaultWeb = (web.equals(defaultWeb)) && (DocumentAction.VIEW.equals(action));
         }
         if (!useDefaultWeb) {
             newpath.append(encode(web, context));
@@ -207,11 +209,13 @@
         }
     }
 
-    private void addName(StringBuffer newpath, String name, String action, XWikiContext context)
+    private void addName(StringBuffer newpath, String name, DocumentAction action,
+        XWikiContext context)
     {
         XWiki xwiki = context.getWiki();
         if ((xwiki.useDefaultAction(context))
-            || (!name.equals(xwiki.getDefaultPage(context)) || (!"view".equals(action)))) {
+            || (!name.equals(xwiki.getDefaultPage(context)) || (!DocumentAction.VIEW
+                .equals(action)))) {
             newpath.append(encode(name, context));
         }
     }
@@ -236,8 +240,8 @@
         return Utils.encode(name, context);
     }
 
-    public URL createExternalURL(String web, String name, String action, String querystring,
-        String anchor, String xwikidb, XWikiContext context)
+    public URL createExternalURL(String web, String name, DocumentAction action,
+        String querystring, String anchor, String xwikidb, XWikiContext context)
     {
         return this.createURL(web, name, action, querystring, anchor, xwikidb, context);
     }
@@ -261,9 +265,9 @@
     {
         StringBuffer newpath = new StringBuffer(servletPath);
         newpath.append(actionPath);
-        addAction(newpath, "skin", context);
-        addSpace(newpath, web, "skin", context);
-        addName(newpath, name, "skin", context);
+        addAction(newpath, DocumentAction.SKIN, context);
+        addSpace(newpath, web, DocumentAction.SKIN, context);
+        addName(newpath, name, DocumentAction.SKIN, context);
         addFileName(newpath, filename, false, context);
         try {
             return new URL(getServerURL(xwikidb, context), newpath.toString());
@@ -286,8 +290,8 @@
         }
     }
 
-    public URL createAttachmentURL(String filename, String web, String name, String action,
-        String querystring, String xwikidb, XWikiContext context)
+    public URL createAttachmentURL(String filename, String web, String name,
+        DocumentAction action, String querystring, String xwikidb, XWikiContext context)
     {
         StringBuffer newpath = new StringBuffer(servletPath);
         newpath.append(actionPath);
@@ -305,7 +309,7 @@
             newpath.append(querystring);
         }
 
-        if ((context != null) && "viewrev".equals(context.getAction())) {
+        if ((context != null) && DocumentAction.VIEWREV.equals(context.getAction())) {
             revdoc = context.get("rev").toString();
             Log log = LogFactory.getLog(XWikiServletURLFactory.class);
             try {
@@ -344,7 +348,7 @@
     public URL createAttachmentRevisionURL(String filename, String web, String name,
         String revision, String querystring, String xwikidb, XWikiContext context)
     {
-        String action = "downloadrev";
+        DocumentAction action = DocumentAction.DOWNLOADREV;
         StringBuffer newpath = new StringBuffer(servletPath);
         newpath.append(actionPath);
         addAction(newpath, action, context);
Index: src/main/java/com/xpn/xwiki/web/UploadAction.java
===================================================================
--- src/main/java/com/xpn/xwiki/web/UploadAction.java	(revision 3976)
+++ src/main/java/com/xpn/xwiki/web/UploadAction.java	(working copy)
@@ -29,6 +29,7 @@
 
 import com.xpn.xwiki.XWikiContext;
 import com.xpn.xwiki.XWikiException;
+import com.xpn.xwiki.api.DocumentAction;
 import com.xpn.xwiki.doc.XWikiAttachment;
 import com.xpn.xwiki.doc.XWikiDocument;
 import com.xpn.xwiki.plugin.fileupload.FileUploadPlugin;
@@ -129,7 +130,7 @@
         // forward to attach page
         String redirect = fileupload.getFileItemAsString("xredirect", context);
         if ((redirect == null) || (redirect.equals("")))
-            redirect = context.getDoc().getURL("attach", true, context);
+            redirect = context.getDoc().getURL(DocumentAction.ATTACH, true, context);
         sendRedirect(response, redirect);
         return false;
     }
Index: src/main/java/com/xpn/xwiki/web/ObjectRemoveAction.java
===================================================================
--- src/main/java/com/xpn/xwiki/web/ObjectRemoveAction.java	(revision 3976)
+++ src/main/java/com/xpn/xwiki/web/ObjectRemoveAction.java	(working copy)
@@ -23,6 +23,7 @@
 import com.xpn.xwiki.XWiki;
 import com.xpn.xwiki.XWikiContext;
 import com.xpn.xwiki.XWikiException;
+import com.xpn.xwiki.api.DocumentAction;
 import com.xpn.xwiki.doc.XWikiDocument;
 import com.xpn.xwiki.objects.BaseObject;
 
@@ -48,7 +49,7 @@
         xwiki.saveDocument(doc, olddoc, context.getMessageTool().get("core.comment.deleteObject"), context);
 
         // forward to edit
-        String redirect = Utils.getRedirect("edit", context);
+        String redirect = Utils.getRedirect(DocumentAction.EDIT, context);
         sendRedirect(response, redirect);
         return false;
 	}
Index: src/main/java/com/xpn/xwiki/web/EditAction.java
===================================================================
--- src/main/java/com/xpn/xwiki/web/EditAction.java	(revision 3976)
+++ src/main/java/com/xpn/xwiki/web/EditAction.java	(working copy)
@@ -23,7 +23,6 @@
 import com.xpn.xwiki.XWiki;
 import com.xpn.xwiki.XWikiContext;
 import com.xpn.xwiki.XWikiException;
-import com.xpn.xwiki.api.Document;
 import com.xpn.xwiki.doc.XWikiDocument;
 import com.xpn.xwiki.doc.XWikiLock;
 import com.xpn.xwiki.plugin.captcha.CaptchaPluginApi;
Index: src/main/java/com/xpn/xwiki/web/RollbackAction.java
===================================================================
--- src/main/java/com/xpn/xwiki/web/RollbackAction.java	(revision 3976)
+++ src/main/java/com/xpn/xwiki/web/RollbackAction.java	(working copy)
@@ -23,6 +23,7 @@
 import com.xpn.xwiki.XWiki;
 import com.xpn.xwiki.XWikiContext;
 import com.xpn.xwiki.XWikiException;
+import com.xpn.xwiki.api.DocumentAction;
 import com.xpn.xwiki.doc.XWikiDocument;
 
 import java.util.List;
@@ -70,7 +71,7 @@
         xwiki.saveDocument(newdoc, olddoc, context.getMessageTool().get("core.comment.rollback", params), context);
 
         // forward to view
-        String redirect = Utils.getRedirect("view", context);
+        String redirect = Utils.getRedirect(DocumentAction.VIEW, context);
         sendRedirect(response, redirect);
         return false;
 	}
Index: src/main/java/com/xpn/xwiki/web/SaveAction.java
===================================================================
--- src/main/java/com/xpn/xwiki/web/SaveAction.java	(revision 3976)
+++ src/main/java/com/xpn/xwiki/web/SaveAction.java	(working copy)
@@ -23,6 +23,7 @@
 import com.xpn.xwiki.XWiki;
 import com.xpn.xwiki.XWikiContext;
 import com.xpn.xwiki.XWikiException;
+import com.xpn.xwiki.api.DocumentAction;
 import com.xpn.xwiki.doc.XWikiDocument;
 import com.xpn.xwiki.doc.XWikiLock;
 import com.xpn.xwiki.plugin.captcha.CaptchaPluginApi;
@@ -124,7 +125,7 @@
 			return true;
 		}
 		// forward to view
-		sendRedirect(context.getResponse(), Utils.getRedirect("view", context));
+		sendRedirect(context.getResponse(), Utils.getRedirect(DocumentAction.VIEW, context));
 		return false;
 	}
 
Index: src/main/java/com/xpn/xwiki/web/XWikiMessageTool.java
===================================================================
--- src/main/java/com/xpn/xwiki/web/XWikiMessageTool.java	(revision 3976)
+++ src/main/java/com/xpn/xwiki/web/XWikiMessageTool.java	(working copy)
@@ -41,6 +41,7 @@
 
 import com.xpn.xwiki.XWikiContext;
 import com.xpn.xwiki.XWikiException;
+import com.xpn.xwiki.api.AccessLevel;
 import com.xpn.xwiki.doc.XWikiDocument;
 
 /**
@@ -269,7 +270,7 @@
         Properties props = null;
         try {
             XWikiDocument docBundle = context.getWiki().getDocument(documentName, context);
-            if (context.getWiki().getRightService().hasAccessLevel("view", context.getUser(),
+            if (context.getWiki().getRightService().hasAccessLevel(AccessLevel.VIEW, context.getUser(),
                 documentName, context) && !docBundle.isNew())
             {
                 props = getDocumentBundleProperties(docBundle);
Index: src/main/java/com/xpn/xwiki/web/RedirectAction.java
===================================================================
--- src/main/java/com/xpn/xwiki/web/RedirectAction.java	(revision 3976)
+++ src/main/java/com/xpn/xwiki/web/RedirectAction.java	(working copy)
@@ -22,6 +22,7 @@
 
 import com.xpn.xwiki.XWikiContext;
 import com.xpn.xwiki.XWikiException;
+import com.xpn.xwiki.api.DocumentAction;
 
 public class RedirectAction extends XWikiAction {
 	public boolean action(XWikiContext context) throws XWikiException {
@@ -31,7 +32,7 @@
         String redirect;
         redirect = context.getRequest().getParameter("xredirect");
         if ((redirect == null)||(redirect.equals("")))
-            redirect = context.getURLFactory().createURL("Main", "WebHome", "view", context).toString();
+            redirect = context.getURLFactory().createURL("Main", "WebHome", DocumentAction.VIEW, context).toString();
         sendRedirect(response, redirect);
         return false;
 	}
Index: src/main/java/com/xpn/xwiki/web/ViewAction.java
===================================================================
--- src/main/java/com/xpn/xwiki/web/ViewAction.java	(revision 3976)
+++ src/main/java/com/xpn/xwiki/web/ViewAction.java	(working copy)
@@ -22,6 +22,7 @@
 import com.xpn.xwiki.XWiki;
 import com.xpn.xwiki.XWikiContext;
 import com.xpn.xwiki.XWikiException;
+import com.xpn.xwiki.api.DocumentAction;
 import com.xpn.xwiki.doc.XWikiDocument;
 import com.xpn.xwiki.plugin.captcha.CaptchaPluginApi;
 import org.apache.velocity.VelocityContext;
@@ -56,7 +57,7 @@
         // view a specific revision of a document).
         String rev = request.getParameter("rev");
         if (rev != null) {
-            String url = context.getDoc().getURL("viewrev", request.getQueryString(), context);
+            String url = context.getDoc().getURL(DocumentAction.VIEWREV, request.getQueryString(), context);
             try {
                 context.getResponse().sendRedirect(url);
             } catch (IOException e) {
Index: src/main/java/com/xpn/xwiki/web/XWikiPortletURLFactory.java
===================================================================
--- src/main/java/com/xpn/xwiki/web/XWikiPortletURLFactory.java	(revision 3976)
+++ src/main/java/com/xpn/xwiki/web/XWikiPortletURLFactory.java	(working copy)
@@ -22,6 +22,8 @@
 package com.xpn.xwiki.web;
 
 import com.xpn.xwiki.XWikiContext;
+import com.xpn.xwiki.api.DocumentAction;
+
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
@@ -45,22 +47,22 @@
         actionPath = "bin/";
     }
 
-    public URL createAttachmentURL(String filename, String web, String name, String action, String xwikidb, XWikiContext context) {
+    public URL createAttachmentURL(String filename, String web, String name, DocumentAction action, String xwikidb, XWikiContext context) {
         try {
             XWikiResponse response = context.getResponse();
             PortletURL purl;
-            if (action.equals("download"))
+            if (action.equals(DocumentAction.DOWNLOAD))
                 return super.createAttachmentURL(filename, web, name, action, xwikidb, context);    //To change body of overridden methods use File | Settings | File Templates.
-            else if (action.equals("viewattachrev")) {
+            else if (action.equals(DocumentAction.VIEWATTACHREV)) {
                 purl = response.createRenderURL();
                 purl.setParameter("filename", filename);
-                purl.setParameter("action", action);
+                purl.setParameter("action", action.toString());
                 purl.setParameter("topic", web + "." + name);
             } else {
                 purl = response.createActionURL();
                 purl.setParameter("topic", web + "." + name);
                 purl.setParameter("filename", filename);
-                purl.setParameter("action", action);
+                purl.setParameter("action", action.toString());
             }
 
             if (log.isDebugEnabled())
@@ -74,17 +76,17 @@
         }
     }
 
-    public URL createURL(String web, String name, String action, String querystring, String anchor, String xwikidb, XWikiContext context) {
+    public URL createURL(String web, String name, DocumentAction action, String querystring, String anchor, String xwikidb, XWikiContext context) {
         try {
             if (log.isDebugEnabled())
-                log.debug("Generating URL for: " + xwikidb + ":" + web + "." + name + " for action " + action
+                log.debug("Generating URL for: " + xwikidb + ":" + web + "." + name + " for action " + action.toString()
                         + " with querystring " + querystring + " and anchor " + anchor);
 
             XWikiResponse response = context.getResponse();
             PortletURL purl;
 
             // Action and Query String transformers
-            if ((action.equals("view"))&&(context.getLinksAction()!=null)) {
+            if ((action.equals(DocumentAction.VIEW))&&(context.getLinksAction()!=null)) {
                 action = context.getLinksAction();
             }
             if (context.getLinksQueryString()!=null) {
@@ -94,15 +96,16 @@
                  querystring = querystring + "&" + context.getLinksQueryString();
             }
 
-            if (action.equals("view") || action.equals("viewrev") || action.equals("attach") || action.equals("download") || action.equals("downloadrev") || action.equals("viewattachrev") || action.equals("skin") || action.equals("dot"))
+            if (action.equals(DocumentAction.VIEW) || action.equals(DocumentAction.VIEWREV) || action.equals(DocumentAction.ATTACH) || action.equals(DocumentAction.DOWNLOAD) || action.equals(DocumentAction.DOWNLOADREV) || action.equals(DocumentAction.VIEWATTACHREV) || action.equals(DocumentAction.SKIN) || action.equals(DocumentAction.valueOf("dot")))
                 purl = response.createRenderURL();
             else
-            if (action.equals("save") || action.equals("cancel") || action.equals("delete") || action.equals("propupdate")
-                    || action.equals("propadd") || action.equals("propdelete")
-                    || action.equals("objectadd") || action.equals("objectremove")
-                    || action.equals("commentadd") || action.equals("editprefs")
-                    || action.equals("upload") || action.equals("delattachment")
-                    || action.equals("login") || action.equals("logout"))
+            if (action.equals(DocumentAction.SAVE) || action.equals(DocumentAction.CANCEL)
+                || action.equals(DocumentAction.DELETE) || action.equals(DocumentAction.PROPUPDATE)
+                || action.equals(DocumentAction.PROPADD) || action.equals(DocumentAction.PROPDELETE)
+                || action.equals(DocumentAction.OBJECTADD) || action.equals(DocumentAction.OBJECTREMOVE)
+                || action.equals(DocumentAction.COMMENTADD) || action.equals(DocumentAction.EDITPREFS)
+                || action.equals(DocumentAction.UPLOAD) || action.equals(DocumentAction.DELATTACHMENT)
+                || action.equals(DocumentAction.LOGIN) || action.equals(DocumentAction.LOGOUT))
                 purl = response.createActionURL();
             else
                 purl = response.createRenderURL();
@@ -116,7 +119,7 @@
             }
 
             purl.setParameter("topic", web + "." + name);
-            purl.setParameter("action", action);
+            purl.setParameter("action", action.toString());
 
             if (log.isDebugEnabled())
                 log.debug("Generated URL is: " + purl.toString());
@@ -129,17 +132,17 @@
         }
     }
 
-    public URL createURL(String web, String name, String action, boolean redirect, XWikiContext context) {
+    public URL createURL(String web, String name, DocumentAction action, boolean redirect, XWikiContext context) {
         if (redirect == false)
             return createURL(web, name, action, context);
 
         try {
             if (log.isDebugEnabled())
-                log.debug("Generating Redirect URL for: " + web + "." + name + " for action " + action);
+                log.debug("Generating Redirect URL for: " + web + "." + name + " for action " + action.toString());
 
             XWikiResponse response = context.getResponse();
             response.setRenderParameter("topic", web + "." + name);
-            response.setRenderParameter("action", action);
+            response.setRenderParameter("action", action.toString());
             return null;
         }
         catch (Exception e) {
@@ -148,7 +151,7 @@
         }
     }
 
-    public URL createExternalURL(String web, String name, String action, String querystring, String anchor, String xwikidb, XWikiContext context) {
+    public URL createExternalURL(String web, String name, DocumentAction action, String querystring, String anchor, String xwikidb, XWikiContext context) {
         return super.createURL(web, name, action, querystring, anchor, xwikidb, context);
     }
 
Index: src/main/java/com/xpn/xwiki/web/StatusAction.java
===================================================================
--- src/main/java/com/xpn/xwiki/web/StatusAction.java	(revision 3976)
+++ src/main/java/com/xpn/xwiki/web/StatusAction.java	(working copy)
@@ -23,6 +23,7 @@
 import com.xpn.xwiki.XWiki;
 import com.xpn.xwiki.XWikiContext;
 import com.xpn.xwiki.XWikiException;
+import com.xpn.xwiki.api.DocumentAction;
 import com.xpn.xwiki.render.XWikiVelocityRenderer;
 import org.apache.struts.action.Action;
 import org.apache.struts.action.ActionForm;
@@ -38,7 +39,7 @@
 	public ActionForward execute(ActionMapping mapping, ActionForm form,
 			HttpServletRequest req, HttpServletResponse resp) throws Exception {
 		
-		String action = mapping.getName();
+		DocumentAction action = DocumentAction.valueOf(mapping.getName());
         XWikiRequest request = new XWikiServletRequest(req);
         XWikiResponse response = new XWikiServletResponse(resp);
         XWikiContext context = Utils.prepareContext(action, request,
Index: src/main/java/com/xpn/xwiki/web/DownloadRevAction.java
===================================================================
--- src/main/java/com/xpn/xwiki/web/DownloadRevAction.java	(revision 3976)
+++ src/main/java/com/xpn/xwiki/web/DownloadRevAction.java	(working copy)
@@ -2,6 +2,7 @@
 
 import com.xpn.xwiki.XWikiContext;
 import com.xpn.xwiki.XWikiException;
+import com.xpn.xwiki.api.DocumentAction;
 import com.xpn.xwiki.doc.XWikiAttachment;
 import com.xpn.xwiki.doc.XWikiDocument;
 import com.xpn.xwiki.plugin.XWikiPluginManager;
@@ -36,7 +37,7 @@
             try {
                 attachment = attachment.getAttachmentRevision(rev, context);
             } catch(XWikiException e){
-                String url = context.getDoc().getURL("viewattachrev", true, context);
+                String url = context.getDoc().getURL(DocumentAction.VIEWATTACHREV, true, context);
                 try {
                     context.getResponse().sendRedirect(url+"/" + filename);
                 } catch (IOException ioe) {
Index: src/main/java/com/xpn/xwiki/web/SaveAndContinueAction.java
===================================================================
--- src/main/java/com/xpn/xwiki/web/SaveAndContinueAction.java	(revision 3976)
+++ src/main/java/com/xpn/xwiki/web/SaveAndContinueAction.java	(working copy)
@@ -22,6 +22,7 @@
 
 import com.xpn.xwiki.XWikiContext;
 import com.xpn.xwiki.XWikiException;
+import com.xpn.xwiki.api.DocumentAction;
 
 import java.io.IOException;
 
@@ -36,7 +37,7 @@
             if (back == null || back.equals("")) {
                 back = request.getHeader("Referer");
                 if (back == null || back.equals("")) {
-                    back = context.getDoc().getURL("edit", context);
+                    back = context.getDoc().getURL(DocumentAction.EDIT, context);
                 } else {
                     int qm = back.indexOf('?');
                     String base = back.substring(0, qm != -1 ? qm : back.length());
Index: src/main/java/com/xpn/xwiki/web/PropAddAction.java
===================================================================
--- src/main/java/com/xpn/xwiki/web/PropAddAction.java	(revision 3976)
+++ src/main/java/com/xpn/xwiki/web/PropAddAction.java	(working copy)
@@ -23,6 +23,7 @@
 import com.xpn.xwiki.XWiki;
 import com.xpn.xwiki.XWikiContext;
 import com.xpn.xwiki.XWikiException;
+import com.xpn.xwiki.api.DocumentAction;
 import com.xpn.xwiki.doc.XWikiDocument;
 import com.xpn.xwiki.objects.classes.BaseClass;
 import com.xpn.xwiki.objects.classes.PropertyClass;
@@ -68,7 +69,7 @@
             }
         }
         // forward to edit
-        String redirect = Utils.getRedirect("edit", context);
+        String redirect = Utils.getRedirect(DocumentAction.EDIT, context);
         sendRedirect(response, redirect);
         return false;
 	}
Index: src/main/java/com/xpn/xwiki/web/AttachAction.java
===================================================================
--- src/main/java/com/xpn/xwiki/web/AttachAction.java	(revision 3976)
+++ src/main/java/com/xpn/xwiki/web/AttachAction.java	(working copy)
@@ -24,7 +24,7 @@
 import com.xpn.xwiki.XWikiException;
 
 public class AttachAction extends XWikiAction {
-	public String render(XWikiContext context) throws XWikiException {
+	public String render(XWikiContext context) throws XWikiException { 
         return "attach";
 	}
 }
Index: src/main/java/com/xpn/xwiki/web/XWikiPortlet.java
===================================================================
--- src/main/java/com/xpn/xwiki/web/XWikiPortlet.java	(revision 3976)
+++ src/main/java/com/xpn/xwiki/web/XWikiPortlet.java	(working copy)
@@ -24,6 +24,7 @@
 import com.xpn.xwiki.XWiki;
 import com.xpn.xwiki.XWikiContext;
 import com.xpn.xwiki.XWikiException;
+import com.xpn.xwiki.api.DocumentAction;
 import com.xpn.xwiki.plugin.fileupload.FileUploadPlugin;
 import com.xpn.xwiki.plugin.charts.actions.ChartingAction;
 import com.xpn.xwiki.plugin.charts.actions.PreviewChartAction;
@@ -50,7 +51,7 @@
         return name;
     }
 
-    protected XWikiContext prepareContext(String action, XWikiRequest request, XWikiResponse response, XWikiEngineContext engine_context) throws XWikiException {
+    protected XWikiContext prepareContext(DocumentAction action, XWikiRequest request, XWikiResponse response, XWikiEngineContext engine_context) throws XWikiException {
         return Utils.prepareContext(action, request, response, engine_context);
     }
 
@@ -69,7 +70,7 @@
         }
     }
 
-    protected boolean prepareAction(String action, XWikiRequest request, XWikiResponse response,
+    protected boolean prepareAction(DocumentAction action, XWikiRequest request, XWikiResponse response,
                                     XWikiEngineContext engine_context, XWikiContext context) throws XWikiException, IOException {
         XWiki xwiki = XWiki.getXWiki(context);
 
@@ -150,9 +151,9 @@
             XWikiEngineContext engine_context = new XWikiPortletContext(actionRequest.getPortletSession().getPortletContext());
 
             try {
-                String action = request.getParameter("action");
-                if ((action == null) || (action.equals("")))
-                    action = "view";
+                DocumentAction action = DocumentAction.valueOf(request.getParameter("action"));
+                if ((action == null) || (action.equals(DocumentAction.NONE)))
+                    action = DocumentAction.VIEW;
 
                 context = prepareContext(action, request, response, engine_context);
                 if (prepareAction(action, request, response, engine_context, context) == false)
@@ -163,21 +164,21 @@
 
                 XWikiForm form = null;
 
-                if (action.equals("save"))
+                if (action.equals(DocumentAction.SAVE))
                     form = new EditForm();
-                else if (action.equals("lock"))
+                else if (action.equals(DocumentAction.LOCK))
                     form = new EditForm();
-                else if (action.equals("cancel"))
+                else if (action.equals(DocumentAction.CANCEL))
                     form = new EditForm();
-                else if (action.equals("rollback"))
+                else if (action.equals(DocumentAction.ROLLBACK))
                     form = new RollbackForm();
-                else if (action.equals("objectadd"))
+                else if (action.equals(DocumentAction.OBJECTADD))
                     form = new ObjectAddForm();
-                else if (action.equals("commentadd"))
+                else if (action.equals(DocumentAction.COMMENTADD))
                     form = new ObjectAddForm();
-                else if (action.equals("objectremove"))
+                else if (action.equals(DocumentAction.OBJECTREMOVE))
                     form = new ObjectRemoveForm();
-                else if (action.equals("propadd"))
+                else if (action.equals(DocumentAction.PROPADD))
                     form = new PropAddForm();
 
                 if (form != null) {
@@ -185,37 +186,37 @@
                     context.setForm(form);
                 }
 
-                if (action.equals("save")) {
+                if (action.equals(DocumentAction.SAVE)) {
                     (new SaveAction()).action(context);
-                } else if (action.equals("rollback")) {
+                } else if (action.equals(DocumentAction.ROLLBACK)) {
                     (new RollbackAction()).action(context);
-                } else if (action.equals("cancel")) {
+                } else if (action.equals(DocumentAction.CANCEL)) {
                     (new CancelAction()).action(context);
-                } else if (action.equals("lock")) {
+                } else if (action.equals(DocumentAction.LOCK)) {
                     (new LockAction()).action(context);
-                } else if (action.equals("delete")) {
+                } else if (action.equals(DocumentAction.DELETE)) {
                     (new DeleteAction()).action(context);
-                } else if (action.equals("propupdate")) {
+                } else if (action.equals(DocumentAction.PROPUPDATE)) {
                     (new PropUpdateAction()).action(context);
-                } else if (action.equals("propadd")) {
+                } else if (action.equals(DocumentAction.PROPADD)) {
                     (new PropAddAction()).action(context);
-                } else if (action.equals("objectadd")) {
+                } else if (action.equals(DocumentAction.OBJECTADD)) {
                     (new ObjectAddAction()).action(context);
-                } else if (action.equals("commentadd")) {
+                } else if (action.equals(DocumentAction.COMMENTADD)) {
                     (new CommentAddAction()).action(context);
-                } else if (action.equals("objectremove")) {
+                } else if (action.equals(DocumentAction.OBJECTREMOVE)) {
                     (new ObjectRemoveAction()).action(context);
-                } else if (action.equals("upload")) {
+                } else if (action.equals(DocumentAction.UPLOAD)) {
                     (new UploadAction()).action(context);
-                } else if (action.equals("delattachment")) {
+                } else if (action.equals(DocumentAction.DELATTACHMENT)) {
                     (new DeleteAttachmentAction()).action(context);
-                } else if (action.equals("skin")) {
+                } else if (action.equals(DocumentAction.SKIN)) {
                     (new SkinAction()).action(context);
-                } else if (action.equals("logout")) {
+                } else if (action.equals(DocumentAction.LOGOUT)) {
                     (new LogoutAction()).action(context);
-                } else if (action.equals("register")) {
+                } else if (action.equals(DocumentAction.REGISTER)) {
                     (new RegisterAction()).action(context);
-                } else if (action.equals("inline")) {
+                } else if (action.equals(DocumentAction.INLINE)) {
                     (new InlineAction()).action(context);
                 }
             } catch (Throwable e) {
@@ -243,14 +244,15 @@
         XWikiRequest request = new XWikiPortletRequest(renderRequest);
         XWikiResponse response = new XWikiPortletResponse(renderResponse);
         XWikiEngineContext engine_context = new XWikiPortletContext(renderRequest.getPortletSession().getPortletContext());
-        String action = null;
+        DocumentAction action = null;
 
         try {
-            action = request.getParameter("action");
-            if ((action == null) || (action.equals(""))) {
+            DocumentAction portletConfigAction = DocumentAction.valueOf("portletConfig");
+            action = DocumentAction.valueOf(request.getParameter("action"));
+            if ((action == null) || (action.equals(DocumentAction.NONE))) {
                 action = renderRequest.getPortletMode().equals(CONFIG_PORTLET_MODE)
-                        ? "portletConfig"
-                        : "view";
+                        ? portletConfigAction
+                        : DocumentAction.VIEW;
             }
             context = prepareContext(action, request, response, engine_context);
             if (prepareAction(action, request, response, engine_context, context) == false)
@@ -258,10 +260,10 @@
 
             XWikiForm form = null;
 
-            if (action.equals("edit")
-                    || action.equals("inline"))
+            if (action.equals(DocumentAction.EDIT)
+                    || action.equals(DocumentAction.INLINE))
                 form = new EditForm();
-            else if (action.equals("preview"))
+            else if (action.equals(DocumentAction.PREVIEW))
                 form = new EditForm();
 
             if (form != null) {
@@ -271,45 +273,45 @@
 
             String renderResult = null;
             // Determine what to do
-            if (action.equals("view")) {
+            if (action.equals(DocumentAction.VIEW)) {
                 renderResult = (new ViewAction()).render(context);
-            } else if (action.equals("viewrev")) {
+            } else if (action.equals(DocumentAction.VIEWREV)) {
                 renderResult = (new ViewrevAction()).render(context);
-            } else if (action.equals("inline")) {
+            } else if (action.equals(DocumentAction.INLINE)) {
                 renderResult = (new InlineAction()).render(context);
-            } else if (action.equals("edit")) {
+            } else if (action.equals(DocumentAction.EDIT)) {
                 renderResult = (new EditAction()).render(context);
-            } else if (action.equals("preview")) {
+            } else if (action.equals(DocumentAction.PREVIEW)) {
                 renderResult = (new PreviewAction()).render(context);
-            } else if (action.equals("delete")) {
+            } else if (action.equals(DocumentAction.DELETE)) {
                 renderResult = (new DeleteAction()).render(context);
-            } else if (action.equals("download")) {
+            } else if (action.equals(DocumentAction.DOWNLOAD)) {
                 renderResult = (new DownloadAction()).render(context);
-            } else if (action.equals("downloadrev")) {
+            } else if (action.equals(DocumentAction.DOWNLOADREV)) {
                 renderResult = (new DownloadRevAction()).render(context);
-            } else if (action.equals("viewattachrev")) {
+            } else if (action.equals(DocumentAction.VIEWATTACHREV)) {
                 renderResult = (new ViewAttachRevAction()).render(context);
-            } else if (action.equals("dot")) {
+            } else if (action.equals(DocumentAction.valueOf("dot"))) {
                 renderResult = (new DotAction()).render(context);
-            } else if (action.equals("svg")) {
+            } else if (action.equals(DocumentAction.valueOf("svg"))) {
                 renderResult = (new SVGAction()).render(context);
-            } else if (action.equals("attach")) {
+            } else if (action.equals(DocumentAction.ATTACH)) {
                 renderResult = (new AttachAction()).render(context);
-            } else if (action.equals("login")) {
+            } else if (action.equals(DocumentAction.LOGIN)) {
                 renderResult = (new LoginAction()).render(context);
-            } else if (action.equals("loginsubmit")) {
+            } else if (action.equals(DocumentAction.LOGINSUBMIT)) {
                 renderResult = (new LoginSubmitAction()).render(context);
-            } else if (action.equals("loginerror")) {
+            } else if (action.equals(DocumentAction.LOGINERROR)) {
                 renderResult = (new LoginErrorAction()).render(context);
-            } else if (action.equals("register")) {
+            } else if (action.equals(DocumentAction.REGISTER)) {
                 renderResult = (new RegisterAction()).render(context);
-            } else if (action.equals("skin")) {
+            } else if (action.equals(DocumentAction.SKIN)) {
                 renderResult = (new SkinAction()).render(context);
-            } else if (action.equals("export")) {
+            } else if (action.equals(DocumentAction.EXPORT)) {
                 renderResult = (new ExportAction()).render(context);
-            } else if (action.equals("import")) {
+            } else if (action.equals(DocumentAction.IMPORT)) {
                 renderResult = (new ImportAction()).render(context);
-            } else if (action.equals("portletConfig")) {
+            } else if (action.equals(portletConfigAction)) {
                 renderResult = "portletConfig";
             } 
             if (renderResult != null) {
Index: src/main/java/com/xpn/xwiki/web/DeleteAttachmentAction.java
===================================================================
--- src/main/java/com/xpn/xwiki/web/DeleteAttachmentAction.java	(revision 3976)
+++ src/main/java/com/xpn/xwiki/web/DeleteAttachmentAction.java	(working copy)
@@ -21,6 +21,7 @@
 
 import com.xpn.xwiki.XWikiContext;
 import com.xpn.xwiki.XWikiException;
+import com.xpn.xwiki.api.DocumentAction;
 import com.xpn.xwiki.doc.XWikiAttachment;
 import com.xpn.xwiki.doc.XWikiDocument;
 
@@ -52,7 +53,7 @@
         doc.setAuthor(context.getUser());
         doc.deleteAttachment(attachment, context);
         // forward to attach page
-        String redirect = Utils.getRedirect("attach", context);
+        String redirect = Utils.getRedirect(DocumentAction.ATTACH, context);
         sendRedirect(response, redirect);
         return false;
     }
Index: src/main/java/com/xpn/xwiki/web/ObjectAddAction.java
===================================================================
--- src/main/java/com/xpn/xwiki/web/ObjectAddAction.java	(revision 3976)
+++ src/main/java/com/xpn/xwiki/web/ObjectAddAction.java	(working copy)
@@ -23,6 +23,7 @@
 import com.xpn.xwiki.XWiki;
 import com.xpn.xwiki.XWikiContext;
 import com.xpn.xwiki.XWikiException;
+import com.xpn.xwiki.api.DocumentAction;
 import com.xpn.xwiki.doc.XWikiDocument;
 import com.xpn.xwiki.objects.BaseObject;
 import com.xpn.xwiki.objects.classes.BaseClass;
@@ -68,7 +69,7 @@
         xwiki.saveDocument(doc, olddoc, context.getMessageTool().get("core.comment.addObject"), context);
 
         // forward to edit
-        String redirect = Utils.getRedirect("edit", context);
+        String redirect = Utils.getRedirect(DocumentAction.EDIT, context);
         sendRedirect(response, redirect);
         return false;
 	}
Index: src/main/java/com/xpn/xwiki/web/PreviewAction.java
===================================================================
--- src/main/java/com/xpn/xwiki/web/PreviewAction.java	(revision 3976)
+++ src/main/java/com/xpn/xwiki/web/PreviewAction.java	(working copy)
@@ -23,7 +23,6 @@
 import com.xpn.xwiki.XWiki;
 import com.xpn.xwiki.XWikiContext;
 import com.xpn.xwiki.XWikiException;
-import com.xpn.xwiki.api.Document;
 import com.xpn.xwiki.doc.XWikiDocument;
 import com.xpn.xwiki.plugin.captcha.CaptchaPluginApi;
 import org.apache.velocity.VelocityContext;
Index: src/main/java/com/xpn/xwiki/web/PropUpdateAction.java
===================================================================
--- src/main/java/com/xpn/xwiki/web/PropUpdateAction.java	(revision 3976)
+++ src/main/java/com/xpn/xwiki/web/PropUpdateAction.java	(working copy)
@@ -28,6 +28,7 @@
 import com.xpn.xwiki.XWiki;
 import com.xpn.xwiki.XWikiContext;
 import com.xpn.xwiki.XWikiException;
+import com.xpn.xwiki.api.DocumentAction;
 import com.xpn.xwiki.doc.XWikiDocument;
 import com.xpn.xwiki.objects.classes.BaseClass;
 import com.xpn.xwiki.objects.classes.PropertyClass;
@@ -107,7 +108,7 @@
             return true;
         }
         // forward to view
-        String redirect = Utils.getRedirect("view", context);
+        String redirect = Utils.getRedirect(DocumentAction.VIEW, context);
         sendRedirect(context.getResponse(), redirect);
         return false;
     }
Index: src/main/java/com/xpn/xwiki/web/CancelAction.java
===================================================================
--- src/main/java/com/xpn/xwiki/web/CancelAction.java	(revision 3976)
+++ src/main/java/com/xpn/xwiki/web/CancelAction.java	(working copy)
@@ -22,6 +22,7 @@
 
 import com.xpn.xwiki.XWikiContext;
 import com.xpn.xwiki.XWikiException;
+import com.xpn.xwiki.api.DocumentAction;
 import com.xpn.xwiki.doc.XWikiDocument;
 import com.xpn.xwiki.doc.XWikiLock;
 
@@ -63,7 +64,7 @@
 		// forward to view
 		String ajax = request.getParameter("ajax");
 		if (ajax == null || !ajax.equals("1")) {
-			String redirect = Utils.getRedirect("view", context);
+			String redirect = Utils.getRedirect(DocumentAction.VIEW, context);
 			sendRedirect(response, redirect);
 		}
 		return false;
Index: src/main/java/com/xpn/xwiki/web/LockAction.java
===================================================================
--- src/main/java/com/xpn/xwiki/web/LockAction.java	(revision 3976)
+++ src/main/java/com/xpn/xwiki/web/LockAction.java	(working copy)
@@ -3,6 +3,7 @@
 import com.xpn.xwiki.XWiki;
 import com.xpn.xwiki.XWikiContext;
 import com.xpn.xwiki.XWikiException;
+import com.xpn.xwiki.api.DocumentAction;
 import com.xpn.xwiki.doc.XWikiDocument;
 import com.xpn.xwiki.doc.XWikiLock;
 
@@ -43,7 +44,7 @@
         // forward to view
         String ajax = request.getParameter("ajax");
         if(ajax == null || !ajax.equals("1")){
-        	String redirect = Utils.getRedirect("view", context);
+        	String redirect = Utils.getRedirect(DocumentAction.VIEW, context);
         	sendRedirect(response, redirect);
         }
         return false;
Index: src/main/java/com/xpn/xwiki/user/impl/xwiki/XWikiRightServiceImpl.java
===================================================================
--- src/main/java/com/xpn/xwiki/user/impl/xwiki/XWikiRightServiceImpl.java	(revision 3976)
+++ src/main/java/com/xpn/xwiki/user/impl/xwiki/XWikiRightServiceImpl.java	(working copy)
@@ -23,6 +23,8 @@
 
 import com.xpn.xwiki.XWikiContext;
 import com.xpn.xwiki.XWikiException;
+import com.xpn.xwiki.api.AccessLevel;
+import com.xpn.xwiki.api.DocumentAction;
 import com.xpn.xwiki.doc.XWikiDocument;
 import com.xpn.xwiki.objects.BaseObject;
 import com.xpn.xwiki.user.api.XWikiGroupService;
@@ -39,10 +41,7 @@
 
 public class XWikiRightServiceImpl implements XWikiRightService {
     private static final Log log = LogFactory.getLog(XWikiRightServiceImpl.class);
-    private static Map actionMap;
-    private static List allLevels = Arrays.asList(
-        new String[] {"admin","view","edit","comment","delete","register","programming"});
-
+    
     protected void logAllow(String username, String page, String action, String info) {
         if (log.isDebugEnabled())
             log.debug("Access has been granted for (" + username + "," + page + "," + action + "): " + info);
@@ -58,56 +57,49 @@
             log.debug("Access has been denied for (" + name + "," + resourceKey + "," + accessLevel + ") at " + info, e);
     }
 
+    /**
+     * This function returns all the access levels as Strings the returned list is the union between 
+     * regular levels and global levels.
+     * @deprecated use {@link XWikiRightServiceImpl#listRegularLevels(XWikiContext)} and 
+     * {@link XWikiRightServiceImpl#listGlobalLevels(XWikiContext)}.
+     */
     public List listAllLevels(XWikiContext context) throws XWikiException {
-        List list = new ArrayList();
-        list.addAll(allLevels);
-        return list;
-    }
-
-    public String getRight(String action) {
-        if (actionMap == null) {
-            actionMap = new HashMap();
-            actionMap.put("login", "login");
-            actionMap.put("logout", "login");
-            actionMap.put("loginerror", "login");
-            actionMap.put("loginsubmit", "login");
-            actionMap.put("view", "view");
-            actionMap.put("viewrev", "view");
-            actionMap.put("downloadrev", "download");
-            actionMap.put("plain", "view");
-            actionMap.put("raw", "view");
-            actionMap.put("attach", "view");
-            actionMap.put("charting", "view");
-            actionMap.put("skin", "view");
-            actionMap.put("download", "view");
-            actionMap.put("dot", "view");
-            actionMap.put("svg", "view");
-            actionMap.put("pdf", "view");
-            actionMap.put("delete", "delete");
-            actionMap.put("reset", "delete");
-            actionMap.put("commentadd", "comment");
-            actionMap.put("register", "register");
-            actionMap.put("redirect", "view");
-            actionMap.put("admin", "admin");
-            actionMap.put("export", "view");
-            actionMap.put("import", "admin");
-            actionMap.put("unknown", "view");
+        List rAccessLevels = AccessLevel.listRegularAccessLevels();
+        List gAccessLevels = AccessLevel.listGlobalAccessLevels();
+        ArrayList allLevelsList = new ArrayList();
+        allLevelsList.addAll(rAccessLevels);
+        for(Iterator it = gAccessLevels.iterator(); it.hasNext();) {
+            AccessLevel currentLevel = (AccessLevel)it.next();
+            //find it
+            if (allLevelsList.contains(currentLevel)) {
+                continue;
+            } else {
+                allLevelsList.add(currentLevel);
+            }            
         }
-
-        String right = (String) actionMap.get(action);
-        if (right == null) {
-            return "edit";
-        } else
-            return right;
+        
+        ArrayList stringAccessLevels = new ArrayList();
+        for (Iterator it = allLevelsList.iterator(); it.hasNext();) {
+            stringAccessLevels.add(it.next().toString());
+        }
+        return stringAccessLevels;
     }
+    
+    public List listRegularLevels(XWikiContext context) throws XWikiException {
+        return AccessLevel.listRegularAccessLevels();
+    }
+    
+    public List listGlobalLevels(XWikiContext context) throws XWikiException {
+        return AccessLevel.listGlobalAccessLevels();
+    }
 
-    public boolean checkAccess(String action, XWikiDocument doc, XWikiContext context) throws XWikiException {
+    public boolean checkAccess(DocumentAction action, XWikiDocument doc, XWikiContext context) throws XWikiException {
         String username = null;
         XWikiUser user = null;
         boolean needsAuth = false;
-        String right = getRight(action);
+        AccessLevel right = action.getAccessLevel();
 
-        if (right.equals("login")) {
+        if (right.equals(AccessLevel.LOGIN)) {
             user = context.getWiki().checkAuth(context);
             if (user == null)
                 username = "XWiki.XWikiGuest";
@@ -116,11 +108,11 @@
 
             // Save the user
             context.setUser(username);
-            logAllow(username, doc.getFullName(), action, "login/logout pages");
+            logAllow(username, doc.getFullName(), action.toString(), "login/logout pages");
             return true;
         }
 
-        if (right.equals("delete")) {
+        if (right.equals(AccessLevel.DELETE)) {
             user = context.getWiki().checkAuth(context);
             String creator = doc.getCreator();
             if ((user != null) && (user.getUser() != null) && (creator != null)) {
@@ -128,7 +120,7 @@
                     return true;
                 }
             }
-            right = "admin";
+            right = AccessLevel.ADMIN;
         }
 
         // We do not need to authenticate twice
@@ -145,7 +137,7 @@
                 if ((user == null) && (needsAuth)) {
                     if (context.getRequest() != null)
                         context.getWiki().getAuthService().showLogin(context);
-                    logDeny("unauthentified", doc.getFullName(), action, "Authentication needed");
+                    logDeny("unauthentified", doc.getFullName(), action.toString(), "Authentication needed");
                     return false;
                 }
             } catch (XWikiException e) {
@@ -176,29 +168,29 @@
                 docname = doc.getFullName();
 
             if (context.getWiki().getRightService().hasAccessLevel(right, username, docname, context)) {
-                logAllow(username, docname, action, "access manager granted right");
+                logAllow(username, docname, action.toString(), "access manager granted right");
                 return true;
             }
         } catch (Exception e) {
 // This should not happen..
-            logDeny(username, (doc==null) ? "" : doc.getFullName(), action, "access manager exception " + e.getMessage());
+            logDeny(username, (doc==null) ? "" : doc.getFullName(), action.toString(), "access manager exception " + e.getMessage());
             e.printStackTrace();
             return false;
         }
 
         if (user == null) {
 // Denied Guest need to be authenticated
-            logDeny("unauthentified", (doc==null) ? "" : doc.getFullName(), action, "Guest has been denied - Redirecting to authentication");
+            logDeny("unauthentified", (doc==null) ? "" : doc.getFullName(), action.toString(), "Guest has been denied - Redirecting to authentication");
             if (context.getRequest() != null)
                 context.getWiki().getAuthService().showLogin(context);
             return false;
         } else {
-            logDeny(username, doc.getFullName(), action, "access manager denied right");
+            logDeny(username, doc.getFullName(), action.toString(), "access manager denied right");
             return false;
         }
     }
 
-    private boolean needsAuth(String right, XWikiContext context) {
+    private boolean needsAuth(AccessLevel right, XWikiContext context) {
         boolean needsAuth = false;
         try {
             needsAuth = context.getWiki().getXWikiPreference("authenticate_" + right, "", context).toLowerCase().equals("yes");
@@ -219,15 +211,24 @@
         return needsAuth;
     }
 
-    public boolean hasAccessLevel(String right, String username, String docname, XWikiContext context) throws XWikiException {
+    public boolean hasAccessLevel(AccessLevel right, String username, String docname, XWikiContext context) throws XWikiException {
         try {
             return hasAccessLevel(right, username, docname, true, context);
         } catch (XWikiException e) {
             return false;
         }
     }
+    
+    /**
+     * @see XWikiRightServiceImpl#hasAccessLevel(AccessLevel, String, String, XWikiContext) 
+     * @deprecated use {@link XWikiRightServiceImpl#hasAccessLevel(AccessLevel, String, String, XWikiContext)}
+     */
+    public boolean hasAccessLevel(String right, String username, String docname, XWikiContext context) throws XWikiException {
+        AccessLevel accessLevel = AccessLevel.valueOf(right);
+        return this.hasAccessLevel(accessLevel, username, docname, context);
+    }
 
-    public boolean checkRight(String name, XWikiDocument doc, String accessLevel,
+    public boolean checkRight(String name, XWikiDocument doc, AccessLevel accessLevel,
                               boolean user, boolean allow, boolean global, XWikiContext context) throws XWikiRightNotFoundException, XWikiException {
         String className = global ? "XWiki.XWikiGlobalRights" : "XWiki.XWikiRights";
         String fieldName = user ? "users" : "groups";
@@ -270,7 +271,7 @@
                         log.debug("Checking match: " + accessLevel + " in " + levels);
 
                     String[] levelsarray = StringUtils.split(levels, " ,|");
-                    if (ArrayUtils.contains(levelsarray, accessLevel)) {
+                    if (ArrayUtils.contains(levelsarray, accessLevel.toString())) {
                         if (log.isDebugEnabled())
                             log.debug("Found a right for " + allow);
                         found = true;
@@ -422,7 +423,7 @@
             throw new XWikiRightNotFoundException();
     }
 
-    public boolean hasAccessLevel(String accessLevel, String name, String resourceKey,
+    public boolean hasAccessLevel(AccessLevel accessLevel, String name, String resourceKey,
                                   boolean user, XWikiContext context) throws XWikiException {
         boolean deny = false;
         boolean allow = false;
@@ -434,11 +435,11 @@
 
         if (isReadOnly) {
 
-            if ("edit".equals(accessLevel) ||
-                    "delete".equals(accessLevel) ||
-                    "comment".equals(accessLevel) ||
-                    "register".equals(accessLevel)) {
-                logDeny(name, resourceKey, accessLevel, "server in read-only mode");
+            if (AccessLevel.EDIT.equals(accessLevel) ||
+                    AccessLevel.DELETE.equals(accessLevel) ||
+                    AccessLevel.COMMENT.equals(accessLevel) ||
+                    AccessLevel.REGISTER.equals(accessLevel)) {
+                logDeny(name, resourceKey, accessLevel.toString(), "server in read-only mode");
                 return false;
             }
         }
@@ -449,7 +450,7 @@
         }
 
         allow = isSuperAdminOrProgramming(name, resourceKey, accessLevel, user, context);
-        if ((allow==true)||(accessLevel.equals("programming"))) {
+        if ((allow==true)||(accessLevel.equals(AccessLevel.PROGRAMMING))) {
             return allow;
         }
 
@@ -458,7 +459,7 @@
             String wikiOwner = context.getWikiOwner();
             if (wikiOwner != null) {
                 if (wikiOwner.equals(name)) {
-                    logAllow(name, resourceKey, accessLevel, "admin level from wiki ownership");
+                    logAllow(name, resourceKey, accessLevel.toString(), "admin level from wiki ownership");
                     return true;
                 }
             }
@@ -466,26 +467,26 @@
             XWikiDocument xwikidoc = context.getWiki().getDocument("XWiki.XWikiPreferences", context);
 
             // Verify XWiki register right
-            if (accessLevel.equals("register")) {
+            if (accessLevel.equals(AccessLevel.REGISTER)) {
                 try {
-                    allow = checkRight(name, xwikidoc, "register", user, true, true, context);
+                    allow = checkRight(name, xwikidoc, AccessLevel.REGISTER, user, true, true, context);
                     if (allow) {
-                        logAllow(name, resourceKey, accessLevel, "register level");
+                        logAllow(name, resourceKey, accessLevel.toString(), "register level");
                         return true;
                     } else {
-                        logDeny(name, resourceKey, accessLevel, "register level");
+                        logDeny(name, resourceKey, accessLevel.toString(), "register level");
                         return false;
                     }
                 } catch (XWikiRightNotFoundException e) {
                 }
-                logDeny(name, resourceKey, accessLevel, "register level (no right found)");
+                logDeny(name, resourceKey, accessLevel.toString(), "register level (no right found)");
                 return false;
             }
 
             int maxRecursiveSpaceChecks = context.getWiki().getMaxRecursiveSpaceChecks(context);
             boolean isSuperUser = isSuperUser(accessLevel, name, resourceKey, user, xwikidoc, maxRecursiveSpaceChecks, context);
             if (isSuperUser) {
-                logAllow(name, resourceKey, accessLevel, "admin level");
+                logAllow(name, resourceKey, accessLevel.toString(), "admin level");
                 return true;
             }
 
@@ -498,7 +499,7 @@
                     deny = checkRight(name, currentdoc, accessLevel, user, false, false, context);
                     deny_found = true;
                     if (deny) {
-                        logDeny(name, resourceKey, accessLevel, "document level");
+                        logDeny(name, resourceKey, accessLevel.toString(), "document level");
                         return false;
                     }
                 } catch (XWikiRightNotFoundException e) {
@@ -510,7 +511,7 @@
                 allow = checkRight(name, currentdoc, accessLevel, user, true, false, context);
                 allow_found = true;
                 if (allow) {
-                    logAllow(name, resourceKey, accessLevel, "document level");
+                    logAllow(name, resourceKey, accessLevel.toString(), "document level");
                     return true;
                 }
             } catch (XWikiRightNotFoundException e) {
@@ -534,7 +535,7 @@
                             deny = checkRight(name, webdoc, accessLevel, user, false, true, context);
                             deny_found = true;
                             if (deny) {
-                                logDeny(name, resourceKey, accessLevel, "web level");
+                                logDeny(name, resourceKey, accessLevel.toString(), "web level");
                                 return false;
                             }
                         } catch (XWikiRightNotFoundException e) {
@@ -548,7 +549,7 @@
                             allow = checkRight(name, webdoc, accessLevel, user, true, true, context);
                             allow_found = true;
                             if (allow) {
-                                logAllow(name, resourceKey, accessLevel, "web level");
+                                logAllow(name, resourceKey, accessLevel.toString(), "web level");
                                 return true;
                             }
                         } catch (XWikiRightNotFoundException e) {
@@ -574,7 +575,7 @@
                     deny = checkRight(name, xwikidoc, accessLevel, user, false, true, context);
                     deny_found = true;
                     if (deny) {
-                        logDeny(name, resourceKey, accessLevel, "xwiki level");
+                        logDeny(name, resourceKey, accessLevel.toString(), "xwiki level");
                         return false;
                     }
                 } catch (XWikiRightNotFoundException e) {
@@ -588,7 +589,7 @@
                     allow = checkRight(name, xwikidoc, accessLevel, user, true, true, context);
                     allow_found = true;
                     if (allow) {
-                        logAllow(name, resourceKey, accessLevel, "xwiki level");
+                        logAllow(name, resourceKey, accessLevel.toString(), "xwiki level");
                         return true;
                     }
                 } catch (XWikiRightNotFoundException e) {
@@ -599,20 +600,20 @@
 // and that all users that were not denied
 // should be allowed.
             if (!allow_found) {
-                if (accessLevel.equals("register")) {
-                    logDeny(name, resourceKey, accessLevel, "global level (register right must be explicit)");
+                if (accessLevel.equals(AccessLevel.REGISTER)) {
+                    logDeny(name, resourceKey, accessLevel.toString(), "global level (register right must be explicit)");
                     return false;
                 } else {
-                    logAllow(name, resourceKey, accessLevel, "global level (no restricting right)");
+                    logAllow(name, resourceKey, accessLevel.toString(), "global level (no restricting right)");
                     return true;
                 }
             } else {
-                logDeny(name, resourceKey, accessLevel, "global level (restricting right was found)");
+                logDeny(name, resourceKey, accessLevel.toString(), "global level (restricting right was found)");
                 return false;
             }
 
         } catch (XWikiException e) {
-            logDeny(name, resourceKey, accessLevel, "global level (exception)", e);
+            logDeny(name, resourceKey, accessLevel.toString(), "global level (exception)", e);
             e.printStackTrace();
             return false;
         }
@@ -625,11 +626,11 @@
         return true;
     }
 
-    private boolean isSuperAdminOrProgramming(String name, String resourceKey, String accessLevel, boolean user, XWikiContext context) throws XWikiException {
+    private boolean isSuperAdminOrProgramming(String name, String resourceKey, AccessLevel accessLevel, boolean user, XWikiContext context) throws XWikiException {
         String database = context.getDatabase();
         boolean allow;
         if (name.equals("XWiki.superadmin") || name.endsWith(":XWiki.superadmin")) {
-            logAllow(name, resourceKey, accessLevel, "super admin level");
+            logAllow(name, resourceKey, accessLevel.toString(), "super admin level");
             return true;
         }
 
@@ -639,32 +640,32 @@
             XWikiDocument xwikimasterdoc = context.getWiki().getDocument("XWiki.XWikiPreferences", context);
 // Verify XWiki Master super user
             try {
-                allow = checkRight(name, xwikimasterdoc, "admin", true, true, true, context);
+                allow = checkRight(name, xwikimasterdoc, AccessLevel.ADMIN, true, true, true, context);
                 if (allow) {
-                    logAllow(name, resourceKey, accessLevel, "master admin level");
+                    logAllow(name, resourceKey, accessLevel.toString(), "master admin level");
                     return true;
                 }
             } catch (XWikiRightNotFoundException e) {
             }
 
 // Verify XWiki programming right
-            if (accessLevel.equals("programming")) {
+            if (accessLevel.equals(AccessLevel.PROGRAMMING)) {
                 // Programming right can only been given if user is from main wiki
                 if (!name.startsWith(context.getWiki().getDatabase() + ":"))
                     return false;
 
                 try {
-                    allow = checkRight(name, xwikimasterdoc, "programming", user, true, true, context);
+                    allow = checkRight(name, xwikimasterdoc, AccessLevel.PROGRAMMING, user, true, true, context);
                     if (allow) {
-                        logAllow(name, resourceKey, accessLevel, "programming level");
+                        logAllow(name, resourceKey, accessLevel.toString(), "programming level");
                         return true;
                     } else {
-                        logDeny(name, resourceKey, accessLevel, "programming level");
+                        logDeny(name, resourceKey, accessLevel.toString(), "programming level");
                         return false;
                     }
                 } catch (XWikiRightNotFoundException e) {
                 }
-                logDeny(name, resourceKey, accessLevel, "programming level (no right found)");
+                logDeny(name, resourceKey, accessLevel.toString(), "programming level (no right found)");
                 return false;
             }
         } finally {
@@ -675,14 +676,14 @@
         return false;
     }
 
-    private boolean isSuperUser(String accessLevel, String name, String resourceKey, boolean user, XWikiDocument xwikidoc, int maxRecursiveSpaceChecks, XWikiContext context) throws XWikiException {
+    private boolean isSuperUser(AccessLevel accessLevel, String name, String resourceKey, boolean user, XWikiDocument xwikidoc, int maxRecursiveSpaceChecks, XWikiContext context) throws XWikiException {
        boolean allow;
 
         // Verify XWiki super user
         try {
-            allow = checkRight(name, xwikidoc, "admin", user, true, true, context);
+            allow = checkRight(name, xwikidoc, AccessLevel.ADMIN, user, true, true, context);
             if (allow) {
-                logAllow(name, resourceKey, accessLevel, "admin level");
+                logAllow(name, resourceKey, accessLevel.toString(), "admin level");
                 return true;
             }
         } catch (XWikiRightNotFoundException e) {
@@ -700,9 +701,9 @@
             XWikiDocument webdoc = context.getWiki().getDocument(web, "WebPreferences", context);
             if (!webdoc.isNew()) {
                 try {
-                    allow = checkRight(name, webdoc, "admin", user, true, true, context);
+                    allow = checkRight(name, webdoc, AccessLevel.ADMIN, user, true, true, context);
                     if (allow) {
-                        logAllow(name, resourceKey, accessLevel, "web admin level");
+                        logAllow(name, resourceKey, accessLevel.toString(), "web admin level");
                         return true;
                     }
                 } catch (XWikiRightNotFoundException e) {
@@ -752,7 +753,7 @@
                     return false;
             }
 
-            return hasAccessLevel("programming", username, docname, context);
+            return hasAccessLevel(AccessLevel.PROGRAMMING, username, docname, context);
         } catch (Exception e) {
             e.printStackTrace();
             return false;
@@ -762,14 +763,14 @@
     public boolean hasAdminRights(XWikiContext context) {
         boolean hasAdmin = false;
         try {
-            hasAdmin = hasAccessLevel("admin", context.getUser(),
+            hasAdmin = hasAccessLevel(AccessLevel.ADMIN, context.getUser(),
                     "XWiki.XWikiPreferences", context);
         } catch (Exception e) {
             e.printStackTrace();
         }
         if (!hasAdmin) {
             try {
-                hasAdmin = hasAccessLevel("admin", context.getUser(),
+                hasAdmin = hasAccessLevel(AccessLevel.ADMIN, context.getUser(),
                         context.getDoc().getSpace() + ".WebPreferences", context);
             } catch (Exception e) {
                 e.printStackTrace();
Index: src/main/java/com/xpn/xwiki/user/api/XWikiRightService.java
===================================================================
--- src/main/java/com/xpn/xwiki/user/api/XWikiRightService.java	(revision 3976)
+++ src/main/java/com/xpn/xwiki/user/api/XWikiRightService.java	(working copy)
@@ -23,14 +23,21 @@
 
 import com.xpn.xwiki.XWikiContext;
 import com.xpn.xwiki.XWikiException;
+import com.xpn.xwiki.api.AccessLevel;
+import com.xpn.xwiki.api.DocumentAction;
 import com.xpn.xwiki.doc.XWikiDocument;
 
 import java.util.List;
 
 public interface XWikiRightService {
-    public boolean checkAccess(String action, XWikiDocument doc, XWikiContext context) throws XWikiException;
+    public boolean checkAccess(DocumentAction action, XWikiDocument doc, XWikiContext context) throws XWikiException;
 
-    public boolean hasAccessLevel(String right, String username, String docname, XWikiContext context) throws XWikiException;
+    public boolean hasAccessLevel(AccessLevel right, String username, String docname, XWikiContext context) throws XWikiException;
+    
+    /**
+     * @deprecated use {@link XWikiRightService#hasAccessLevel(AccessLevel, String, String, XWikiContext)} 
+     */
+    public boolean hasAccessLevel(String right, String username, String docname, XWikiContext context) throws XWikiException;    
 
     public boolean hasProgrammingRights(XWikiContext context);
 
@@ -38,5 +45,13 @@
 
     public boolean hasAdminRights(XWikiContext context);
 
+    /**
+     * @deprecated use {@link XWikiRightService#listRegularLevels(XWikiContext)} and 
+     * {@link XWikiRightService#listGlobalLevels(XWikiContext)} 
+     */
     public List listAllLevels(XWikiContext context) throws XWikiException;
+    
+    public List listRegularLevels(XWikiContext context) throws XWikiException;
+    
+    public List listGlobalLevels(XWikiContext context) throws XWikiException;
 }
