public StorageStatus OpenExperiment(long experimentId, long duration)
        {
            TicketIssuerDB ticketIssuer = new TicketIssuerDB();
            StorageStatus status = null;
            if (ticketIssuer.AuthenticateAgentHeader(agentAuthHeader))
            {
                Ticket essTicket = ticketIssuer.RetrieveTicket(opHeader.coupon, TicketTypes.ADMINISTER_EXPERIMENT);
                // Check for ESS use
                if (essTicket != null)
                {
                    XmlDocument payload = new XmlDocument();
                    payload.LoadXml(essTicket.payload);
                    string essURL = payload.GetElementsByTagName("essURL")[0].InnerText;

                    long sbExperimentId = Int64.Parse(payload.GetElementsByTagName("experimentID")[0].InnerText);
                    //
                    ExperimentSummary summary = InternalDataDB.SelectExperimentSummary(experimentId);
                    if (summary.HasEss)
                    {
                        // Retrieve the ESS Status info and update as needed
                        ProcessAgentInfo ess = ticketIssuer.GetProcessAgentInfo(summary.essGuid);
                        if (ess.retired)
                        {
                            throw new Exception("The ESS is retired");
                        }
                        ExperimentStorageProxy essProxy = new ExperimentStorageProxy();
                        essProxy.AgentAuthHeaderValue = new AgentAuthHeader();
                        essProxy.AgentAuthHeaderValue.coupon = ess.identOut;
                        essProxy.AgentAuthHeaderValue.agentGuid = ProcessAgentDB.ServiceGuid;
                        essProxy.Url = essURL;
                        status = essProxy.OpenExperiment(sbExperimentId, duration);
                    }

                    // Note: store and retrieve tickets are not cancelled.
                }
            }
            if (status != null)
            {
                DataStorageAPI.UpdateExperimentStatus(status);
            }
            return status;
        }
        public Coupon RequestExperimentAccess(long experimentID)
        {
            TicketIssuerDB ticketIssuer = new TicketIssuerDB();
            Coupon coupon = null;
            //first try to recreate session if using a html client
            //if ((Session == null) || (Session["UserID"] == null) || (Session["UserID"].ToString() == ""))

            if (ticketIssuer.AuthenticateIssuedCoupon(opHeader.coupon))
            {
                Ticket sessionTicket = ticketIssuer.RetrieveTicket(opHeader.coupon, TicketTypes.REDEEM_SESSION);
                if (sessionTicket != null)
                {

                    if (sessionTicket.IsExpired())
                    {
                        throw new AccessDeniedException("The ticket has expired.");
                    }

                    //Parse payload
                    XmlQueryDoc expDoc = new XmlQueryDoc(sessionTicket.payload);
                    // Get User & Group
                    int userID = -1;
                    int groupID = -1;
                    string group = expDoc.Query("RedeemSessionPayload/groupID");
                    string user = expDoc.Query("RedeemSessionPayload/userID");
                    if (group != null && group.Length > 0)
                    {
                        groupID = Convert.ToInt32(group);
                    }
                    if (user != null && user.Length > 0)
                    {
                        userID = Convert.ToInt32(user);
                    }

                    //Check Qualifiers on experiment
                    int status = wrapper.GetExperimentAuthorizationWrapper(experimentID, userID, groupID);
                    //if accessable by user create new TicketCollection
                }
            }
            return coupon;
        }
        public StorageStatus AgentCloseExperiment(Coupon coupon, long experimentId)
        {
            TicketIssuerDB ticketIssuer = new TicketIssuerDB();
            StorageStatus status = null;
            bool experimentClosed = false;

            if (dbTicketing.AuthenticateAgentHeader(agentAuthHeader))
            {
                if (coupon.issuerGuid == ProcessAgentDB.ServiceGuid)
                {

                    // Check for ESS use
                    Ticket essTicket = ticketIssuer.RetrieveTicket(coupon, TicketTypes.ADMINISTER_EXPERIMENT);
                    if (essTicket != null)
                    {
                        ProcessAgentInfo ess = ticketIssuer.GetProcessAgentInfo(essTicket.redeemerGuid);
                        if (ess != null)
                        {
                            if (ess.retired)
                            {
                                throw new Exception("The ProcessAgent is retired");
                            }
                            ExperimentStorageProxy essProxy = new ExperimentStorageProxy();
                            essProxy.AgentAuthHeaderValue = new AgentAuthHeader();
                            essProxy.AgentAuthHeaderValue.coupon = ess.identOut;
                            essProxy.AgentAuthHeaderValue.agentGuid = ProcessAgentDB.ServiceGuid;
                            essProxy.Url = ess.webServiceUrl;
                            status = essProxy.CloseExperiment(experimentId);
                            DataStorageAPI.UpdateExperimentStatus(status);
                        }
                        ticketIssuer.CancelIssuedTicket(coupon, essTicket);
                    }
                    else
                    {
                        // Close the local Experiment records
                        // Note: store and retrieve tickets are not cancelled.
                        experimentClosed = DataStorageAPI.CloseExperiment(experimentId, StorageStatus.CLOSED_USER);
                        status = DataStorageAPI.RetrieveExperimentStatus(experimentId);
                    }

                }
                else
                {
                    ProcessAgentInfo paInfo = ticketIssuer.GetProcessAgentInfo(coupon.issuerGuid);
                    if (paInfo != null)
                    {
                        if (paInfo.retired)
                        {
                            throw new Exception("The ProcessAgent is retired");
                        }
                        InteractiveSBProxy ticketProxy = new InteractiveSBProxy();
                        AgentAuthHeader authHeader = new AgentAuthHeader();
                        authHeader.coupon = paInfo.identOut;
                        authHeader.agentGuid = ProcessAgentDB.ServiceGuid;
                        ticketProxy.AgentAuthHeaderValue = authHeader;
                        ticketProxy.Url = paInfo.webServiceUrl;
                        status = ticketProxy.AgentCloseExperiment(coupon, experimentId);
                    }
                    else
                    {
                        throw new Exception("Unknown TicketIssuerDB in RedeemTicket Request");
                    }
                }

            }
            return status;
        }