Index: src/main/java/com/xpn/xwiki/user/impl/xwiki/MyFormAuthenticator.java
===================================================================
--- src/main/java/com/xpn/xwiki/user/impl/xwiki/MyFormAuthenticator.java	(revision 17850)
+++ src/main/java/com/xpn/xwiki/user/impl/xwiki/MyFormAuthenticator.java	(working copy)
@@ -32,12 +32,12 @@
 import org.apache.commons.logging.LogFactory;
 import org.securityfilter.authenticator.Authenticator;
 import org.securityfilter.authenticator.FormAuthenticator;
+import org.securityfilter.filter.SecurityFilter;
 import org.securityfilter.filter.SecurityRequestWrapper;
 import org.securityfilter.filter.URLPatternMatcher;
 
 import com.xpn.xwiki.XWikiContext;
 import com.xpn.xwiki.XWikiException;
-import com.xpn.xwiki.web.SavedRequestRestorerFilter;
 
 public class MyFormAuthenticator extends FormAuthenticator implements Authenticator, XWikiAuthenticator
 {
@@ -63,26 +63,6 @@
         }
     }
 
-    /**
-     * {@inheritDoc}
-     * 
-     * @see org.securityfilter.authenticator.Authenticator#showLogin(HttpServletRequest, HttpServletResponse)
-     */
-    @Override
-    public void showLogin(HttpServletRequest request, HttpServletResponse response) throws IOException
-    {
-        String savedRequestId = request.getParameter(SavedRequestRestorerFilter.SAVED_REQUESTS_IDENTIFIER);
-        if (StringUtils.isEmpty(savedRequestId)) {
-            // Save this request
-            savedRequestId = SavedRequestRestorerFilter.saveRequest(request);
-        }
-
-        // Redirect to login page
-        response.sendRedirect(response.encodeRedirectURL(request.getContextPath() + this.loginPage + "?"
-            + SavedRequestRestorerFilter.SAVED_REQUESTS_IDENTIFIER + "=" + savedRequestId));
-        return;
-    }
-
     @Override
     public boolean processLogin(SecurityRequestWrapper request, HttpServletResponse response) throws Exception
     {
@@ -229,11 +209,11 @@
     private String getContinueToURL(HttpServletRequest request)
     {
         String savedURL = request.getParameter("xredirect");
-        if (StringUtils.isEmpty(savedURL)) {
-            savedURL = SavedRequestRestorerFilter.getOriginalUrl(request);
+        if ((savedURL == null) || (savedURL.trim().equals(""))) {
+            savedURL = SecurityFilter.getContinueToURL(request);
         }
 
-        if (!StringUtils.isEmpty(savedURL)) {
+        if (savedURL != null) {
             return savedURL;
         }
         return request.getContextPath() + this.defaultPage;
Index: src/main/java/com/xpn/xwiki/user/impl/xwiki/XWikiAuthServiceImpl.java
===================================================================
--- src/main/java/com/xpn/xwiki/user/impl/xwiki/XWikiAuthServiceImpl.java	(revision 17850)
+++ src/main/java/com/xpn/xwiki/user/impl/xwiki/XWikiAuthServiceImpl.java	(working copy)
@@ -27,13 +27,17 @@
 
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
 
 import org.apache.commons.lang.StringUtils;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.hibernate.Query;
 import org.hibernate.Session;
+import org.securityfilter.authenticator.FormAuthenticator;
 import org.securityfilter.config.SecurityConfig;
+import org.securityfilter.filter.SavedRequest;
+import org.securityfilter.filter.SecurityFilter;
 import org.securityfilter.filter.SecurityRequestWrapper;
 import org.securityfilter.realm.SimplePrincipal;
 
@@ -45,6 +49,7 @@
 import com.xpn.xwiki.plugin.ldap.LDAPPlugin;
 import com.xpn.xwiki.user.api.XWikiAuthService;
 import com.xpn.xwiki.user.api.XWikiUser;
+import com.xpn.xwiki.util.Util;
 
 public class XWikiAuthServiceImpl extends AbstractXWikiAuthService
 {
@@ -160,9 +165,9 @@
 
                 MyFilterConfig fconfig = new MyFilterConfig();
                 if (xwiki.Param("xwiki.authentication.loginsubmitpage") != null) {
-                    fconfig.setInitParameter("loginSubmitPattern", xwiki.Param("xwiki.authentication.loginsubmitpage"));
+                    fconfig.setInitParameter(FormAuthenticator.LOGIN_SUBMIT_PATTERN_KEY, xwiki.Param("xwiki.authentication.loginsubmitpage"));
                 } else {
-                    fconfig.setInitParameter("loginSubmitPattern", "/loginsubmit/XWiki/XWikiLogin");
+                    fconfig.setInitParameter(FormAuthenticator.LOGIN_SUBMIT_PATTERN_KEY, "/loginsubmit/XWiki/XWikiLogin");
                 }
 
                 this.authenticator.init(fconfig, sconfig);
@@ -192,9 +197,12 @@
         if (request == null) {
             return null;
         }
+        
+        // get saved request, if any (returns null if not applicable)
+        SavedRequest savedRequest = getSavedRequest(request);
 
         XWikiAuthenticator auth = getAuthenticator(context);
-        SecurityRequestWrapper wrappedRequest = new SecurityRequestWrapper(request, null, null, auth.getAuthMethod());
+        SecurityRequestWrapper wrappedRequest = new SecurityRequestWrapper(request, savedRequest, null, auth.getAuthMethod());
 
         try {
             if (auth.processLogin(wrappedRequest, response, context)) {
@@ -303,6 +311,7 @@
         }
 
         XWikiAuthenticator auth = getAuthenticator(context);
+        
         SecurityRequestWrapper wrappedRequest = new SecurityRequestWrapper(request, null, null, auth.getAuthMethod());
         try {
             if (!auth.processLogin(username, password, rememberme, wrappedRequest, response, context)) {
@@ -569,6 +578,74 @@
         if (contextPath.endsWith("/") && !contextPath.startsWith("/")) {
             contextPath = "/" + StringUtils.chop(contextPath);
         }
-        return StringUtils.removeStart(context.getURLFactory().getURL(url, context), contextPath);
+        return StringUtils.removeStart(context.getURLFactory().getURL(url, context), Util.escapeURL(contextPath));
+    }
+    
+    /**
+     * If this request matches the one we saved, return the SavedRequest and remove it from the session.
+     *
+     * @param request the current request
+     * @return usually null, but when the request matches the posted URL that initiated the login sequence a
+     * SavedRequest object is returned.
+     */
+    protected SavedRequest getSavedRequest(HttpServletRequest request) {
+        HttpSession session = request.getSession();
+        String savedURL = (String) session.getAttribute(SecurityFilter.SAVED_REQUEST_URL);
+        if (savedURL != null && savedURL.equals(getSaveableURL(request))) {
+            // this is a request for the request that caused the login,
+            // get the SavedRequest from the session
+            SavedRequest saved = (SavedRequest) session.getAttribute(SecurityFilter.SAVED_REQUEST);
+            // remove the saved request info from the session
+            session.removeAttribute(SecurityFilter.SAVED_REQUEST_URL);
+            session.removeAttribute(SecurityFilter.SAVED_REQUEST);
+            // and return the SavedRequest
+            return saved;
+        } else {
+            return null;
+        }
     }
+    
+    /**
+     * Return a URL suitable for saving or matching against a saved URL.<p>
+     *
+     * This is the whole URL, plus the query string.
+     *
+     * @param request the request to construct a saveable URL for
+     */
+   private static String getSaveableURL(HttpServletRequest request) {
+        StringBuffer saveableURL = null;
+        try {
+           saveableURL = request.getRequestURL();
+        } catch (NoSuchMethodError e) {
+            return null;
+        }
+        // fix the protocol
+        fixProtocol(saveableURL, request);
+        // add the query string, if any
+        String queryString = request.getQueryString();
+        if (queryString != null) {
+           saveableURL.append("?" + queryString);
+        }
+        return saveableURL.toString();
+     }
+
+   /**
+    * Fix the protocol portion of an absolute url. Often, the protocol will be http: even for https: requests.
+    *
+    * todo: needs testing to make sure this is proper in all circumstances
+    *
+    * @param url
+    * @param request
+    */
+   private static void fixProtocol(StringBuffer url, HttpServletRequest request) {
+      // fix protocol, if needed (since HTTP is the same regardless of whether it runs on TCP or on SSL/TCP)
+      if (
+         request.getProtocol().equals("HTTP/1.1")
+         && request.isSecure()
+         && url.toString().startsWith("http://")
+      ) {
+         url.replace(0, 4, "https");
+      }
+   }
+
 }
