public override byte[] Handle(string path, Stream request, OSHttpRequest httpRequest, OSHttpResponse httpResponse)
        {
            HttpRequestInfo requestInfo = OpenAuthHelper.GetRequestInfo(httpRequest);

            try
            {
                UserAuthorizationRequest oauthRequest = CableBeachServerState.OAuthServiceProvider.ReadAuthorizationRequest(requestInfo);

                if (oauthRequest != null && oauthRequest.ExtraData != null)
                {
                    IServiceProviderRequestToken requestToken = CableBeachServerState.OAuthTokenManager.GetRequestToken(oauthRequest.RequestToken);
                    if (requestToken.Callback != null)
                        oauthRequest.Callback = requestToken.Callback;

                    if (oauthRequest.Callback != null)
                    {
                        string capNameList;
                        if (oauthRequest.ExtraData.TryGetValue("cb_capabilities", out capNameList))
                        {
                            // Store the OAuth request state in a temporary dictionary to reference later
                            string[] capNames = capNameList.Split(',');
                            OAuthRequest thisRequest = new OAuthRequest(null, oauthRequest, capNames);
                            CableBeachServerState.OAuthCurrentRequests.AddOrUpdate(oauthRequest.RequestToken, thisRequest,
                                TimeSpan.FromMinutes(CableBeachServerState.OAUTH_OPENID_LOGIN_TIMEOUT_MINUTES));

                            HttpCookie cookie = (httpRequest.Cookies != null) ? httpRequest.Cookies["cb_auth"] : null;
                            AuthCookie authCookie;
                            if (cookie != null && CableBeachServerState.AuthCookies.TryGetValue(cookie.Value, out authCookie))
                            {
                                CableBeachServerState.Log.Debug("[CABLE BEACH SERVER]: Found auth cookie for " + authCookie.Identity);
                                thisRequest.Identity = authCookie.Identity;

                                // Return either a permission grant request page or a successful OAuth authorization response
                                return CableBeachServerState.MakeCheckPermissionsResponse(httpRequest, httpResponse, thisRequest);
                            }

                            #region Start OpenID Auth

                            try
                            {
                                // Redirect the user to do an OpenID login through our trusted identity provider
                                Identifier identifier;
                                Identifier.TryParse(CableBeachServerState.OpenIDProviderUrl.ToString(), out identifier);
                                Realm realm = new Realm(CableBeachServerState.ServiceUrl);

                                IAuthenticationRequest authRequest = CableBeachServerState.OpenIDRelyingParty.CreateRequest(
                                    identifier, realm, new Uri(CableBeachServerState.ServiceUrl, "/oauth/openid_callback"));
                                authRequest.AddCallbackArguments("oauth_request_token", oauthRequest.RequestToken);
                                return OpenAuthHelper.MakeOpenAuthResponse(httpResponse, authRequest.RedirectingResponse);
                            }
                            catch (Exception ex)
                            {
                                CableBeachServerState.Log.Error("[CABLE BEACH SERVER]: OpenID authentication failed: " + ex.Message, ex);
                                httpResponse.StatusCode = (int)HttpStatusCode.InternalServerError;
                                return Encoding.UTF8.GetBytes("OpenID authentication failed: " + ex.Message);
                            }

                            #endregion Start OpenID Auth
                        }
                        else
                        {
                            // No capabilities were requested
                            CableBeachServerState.Log.Error("[CABLE BEACH SERVER]: Got an OAuth request with no capabilities being requested");
                            httpResponse.StatusCode = (int)HttpStatusCode.BadRequest;
                            return Encoding.UTF8.GetBytes("Unknown capabilities");
                        }
                    }
                    else
                    {
                        // No callback was given
                        CableBeachServerState.Log.Error("[CABLE BEACH SERVER]: Got an OAuth request with no callback");
                        httpResponse.StatusCode = (int)HttpStatusCode.BadRequest;
                        return Encoding.UTF8.GetBytes("Missing or invalid OAuth callback");
                    }
                }
                else
                {
                    CableBeachServerState.Log.Error("[CABLE BEACH SERVER]: authorize_token called with missing or invalid OAuth request");
                    httpResponse.StatusCode = (int)HttpStatusCode.BadRequest;
                    return Encoding.UTF8.GetBytes("Missing or invalid OAuth request");
                }
            }
            catch (Exception ex)
            {
                CableBeachServerState.Log.Error("[CABLE BEACH SERVER]: authorize_token called with invalid data");
                httpResponse.StatusCode = (int)HttpStatusCode.BadRequest;
                return Encoding.UTF8.GetBytes("Failed to handle OAuth request: " + ex.Message);
            }
        }
        public static UserAuthorizationResponse MakeOAuthSuccessResponse(string requestToken, OAuthRequest oauthRequest)
        {
            // Mark the request token as authorized
            CableBeachServerState.OAuthTokenManager.AuthorizeRequestToken(requestToken);

            // Create an authorization response (including a verification code)
            UserAuthorizationResponse oauthResponse = CableBeachServerState.OAuthServiceProvider.PrepareAuthorizationResponse(oauthRequest.Request);

            // Update the verification code for this request to the newly created verification code
            try { CableBeachServerState.OAuthTokenManager.GetRequestToken(requestToken).VerificationCode = oauthResponse.VerificationCode; }
            catch (KeyNotFoundException)
            {
                CableBeachServerState.Log.Warn("[CABLE BEACH SERVER]: Did not recognize request token \"" + requestToken +
                    "\", failed to update verification code");
            }

            return oauthResponse;
        }
        public static byte[] BuildPermissionGrantTemplate(OAuthRequest oauthRequest)
        {
            string output = null;
            Dictionary<string, object> variables = new Dictionary<string, object>();
            variables["identity"] = oauthRequest.Identity;
            variables["callback"] = oauthRequest.Request.Callback;
            variables["request_token"] = oauthRequest.Request.RequestToken;
            variables["consumer"] = oauthRequest.Request.Callback.Authority;

            try { output = WebTemplates.Render(PermissionGrantTemplateFile, variables); }
            catch (Exception) { }
            if (output == null)
            {
                Log.Error("[CABLE BEACH SERVER]: Failed to render template " + PermissionGrantTemplateFile);
                output = "Failed to render template " + PermissionGrantTemplateFile;
            }

            return Encoding.UTF8.GetBytes(output);
        }
        public static byte[] MakeCheckPermissionsResponse(OSHttpRequest httpRequest, OSHttpResponse httpResponse, OAuthRequest oauthRequest)
        {
            // Return an auth cookie to the client and check if the current consumer has already been granted permissions
            bool permissionGranted = SetAuthCookie(httpRequest, httpResponse, oauthRequest.Identity, oauthRequest.Request.Callback.Authority);

            if (permissionGranted)
            {
                UserAuthorizationResponse oauthResponse = MakeOAuthSuccessResponse(oauthRequest.Request.RequestToken, oauthRequest);
                Log.Info("[CABLE BEACH SERVER]: OAuth confirmation was cached, redirecting to " + oauthRequest.Request.Callback);
                return OpenAuthHelper.MakeOpenAuthResponse(httpResponse, OAuthServiceProvider.Channel.PrepareResponse(oauthResponse));
            }
            else
            {
                // Ask the user if they want to grant capabilities to the requesting world
                return BuildPermissionGrantTemplate(oauthRequest);
            }
        }