private Models.Result MapToResult(Entities.Result result)
 {
     return(new Models.Result
     {
         Year = result.Year,
         Grade = result.Grade.ToString().ToUpper()
     });
 }
        public IHttpActionResult SaveSelectedAnswer(int questionId,
                                                    int optionId)
        {
            var question = QuestionRepository.GetQuestionById(questionId);

            if (question == null)
            {
                return(NotFound());
            }
            else if (question.Status == false)
            {
                return(StatusCode(HttpStatusCode.Forbidden));
            }

            var option = QuestionRepository.GetOptionById(optionId, questionId);

            Entities.Result result = new Entities.Result();
            result.question       = question;
            result.responseOption = option;

            QuestionRepository.SaveAnswer(result);

            return(Created("AnswerSaved", Mapper.Map <Models.Result>(result)));
        }
        /// <summary>
        /// Asynchronously receive list of messages from inbound queue
        /// </summary>
        /// <param name="offset">zero-based 1st message to receive (latest message comes first)</param>
        /// <param name="limit">Max number of messages to retrieve</param>
        /// <param name="userData">User data (piggyback)</param>
        /// <param name="ct">Cancelation token</param>
        /// <param name="callback">callback method to invoke upon completion. Will be invoked also after cancelation</param>
        public void GetMessageListAsync(int offset, int limit, Object userData, CancellationToken ct, Action<Entities.Result<List<Entities.InboundMessageHeader>>> callback)
        {
            Entities.Result<List<Entities.InboundMessageHeader>> result = new Entities.Result<List<Entities.InboundMessageHeader>>();
            result.Status.userData = userData;

            HttpRequestMessage requestMessage = new HttpRequestMessage(HttpMethod.Get,String.Format( "/api/messages/inbound/meta?offset={0}&limit={1}",offset,limit));

            sendAsync(requestMessage, result.Status, ct, (response) =>
            {
                if (!result.Status.IsCancelled && response != null && response.StatusCode == System.Net.HttpStatusCode.OK)
                {
                    // populate messageList
                    result.responsePayload = getMessageListFromContent(response);
                }
                if (callback != null)
                    callback(result);
            });

        }
        /// <summary>
        /// Asynchronously Retrieve a message by Uri
        /// </summary>
        /// <param name="messageID">the message ID</param>
        /// <param name="userData">User data (piggyback)</param>
        /// <param name="ct">Cancelation token</param>
        /// <param name="callback">callback method to invoke upon completion. Will be invoked also after cancelation</param>
        public void RetrieveMessageAsync(string messageID, Object userData, CancellationToken ct, Action<Entities.Result<Entities.Message,Entities.MessageHeaderBase>> callback)
        {
            if (callback == null) return;

            Entities.Result<Entities.Message,Entities.MessageHeaderBase> result = new Entities.Result<Entities.Message,Entities.MessageHeaderBase>();
            result.Status.userData = userData;

            HttpRequestMessage requestMessage = new HttpRequestMessage(HttpMethod.Get, "/api/messages/inbound/content/" + messageID);
            requestMessage.Headers.Accept.Clear();
            requestMessage.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/xml"));

            sendAsync(requestMessage, result.Status, ct, (response) =>
            {
                if (result.Status.IsSuccess)
                {
                    // populate message and header
                    result.responsePayload = getMessageFromResponse(response);
                    result.responsePayload2 = getMessageHeaderFromHeader(response);
                }
                callback(result);
            });

        }
        /// <summary>
        /// Asynchronously relay an HTTP message using saved card details
        /// </summary>
        /// <param name="rr">Relay request object</param>
        /// <param name="userData">User data (piggyback)</param>
        /// <param name="ct">Cancelation token</param>
        /// <param name="callback">callback method to invoke upon completion. Will be invoked also after cancelation</param>
        public void RelayRequestUsingSavedCardAsync(Entities.SavedRelayRequest rr, Object userData, CancellationToken ct, Action<Entities.Result<HttpResponseMessage>> callback)
        {
            var baseUri = String.Format("{0}/relay?sessionToken={1}&cardToken={2}&targetUri={3}&httpMethod={4}&timeout={5}",
                    PAYCARDS_URL_PATH, 
                    Uri.EscapeUriString(rr.sessionToken),
                    Uri.EscapeUriString(rr.cardUri.ToString()),
                    Uri.EscapeUriString(rr.targetUri.ToString()),
                    Uri.EscapeUriString(rr.httpMethod),
                    Uri.EscapeUriString(((int)rr.timeout.TotalSeconds).ToString())
                );

            var requestMessage = new HttpRequestMessage(HttpMethod.Post, baseUri)
            {
                Content = rr.content
            };

            requestMessage.Headers.Authorization = rr.authorizationHeaderValue; // override pciBooking authentication

            var result = new Entities.Result<HttpResponseMessage>();
            result.Status.userData = userData;

            sendAsync(requestMessage, result.Status, ct, (response) =>
            {
                if (result.Status.IsSuccess)
                {
                    result.responsePayload = response;
                }
                if (callback != null)
                    callback(result);
            });
        }
        /// <summary>
        /// Asynchronously clear a temporary card and optionally save it for future use
        /// </summary>
        /// <param name="cardToken">Card token</param>
        /// <param name="save">True to save</param>
        /// <param name="CreatorReference">An optional value to be used for retrieving card meta data in the future</param>
        /// <param name="userData">User data (piggyback)</param>
        /// <param name="ct">Cancelation token</param>
        /// <param name="callback">callback method to invoke upon completion. Will be invoked also after cancelation</param>
        public void ClearTemporaryBankCardAsync(String cardToken, bool save, String CreatorReference, Object userData, CancellationToken ct, Action<Entities.Result<Uri>> callback)
        {
            var baseUri = String.Format(
                "{0}/clear?token={1}&save={2}&ref={3}",
                    PAYCARDS_URL_PATH,  Uri.EscapeUriString(cardToken),  save,  Uri.EscapeUriString(CreatorReference)); ;

            var requestMessage = new HttpRequestMessage(HttpMethod.Post, baseUri);

            var result = new Entities.Result<Uri>();
            result.Status.userData = userData;

            sendAsync(requestMessage, result.Status, ct, (response) =>
            {
                if (result.Status.IsSuccess)
                {
                    result.responsePayload = response.Headers.Location;
                }
                if (callback != null)
                    callback(result);
            });
        }
        /// <summary>
        /// Asynchronously obtain a temporary session token
        /// </summary>
        /// <param name="userData">User data (piggyback)</param>
        /// <param name="ct">Cancelation token</param>
        /// <param name="callback">callback method to invoke upon completion. Will be invoked also after cancelation</param>
        public void ObtainTempSessionTokenAsync(Object userData, CancellationToken ct, Action<Entities.Result<String>> callback)
        {
            var baseUri = String.Format("{0}/tempsession", PAYCARDS_URL_PATH);

            var requestMessage = new HttpRequestMessage(HttpMethod.Post, baseUri);

            var result = new Entities.Result<String>();
            result.Status.userData = userData;

            sendAsync(requestMessage, result.Status, ct, (response) =>
            {
                if (result.Status.IsSuccess)
                {
                    result.responsePayload = BaseRestfulClient.getObjectFromResponse<String>(response);
                }
                if (callback != null)
                    callback(result);
            });
        }
        /// <summary>
        /// Asynchronously disassociate a payment Info object from a merchant
        /// </summary>
        /// <param name="token">Token representing the payment info</param>
        /// <param name="merchantId">Merchant Id (pciBooking user Id of the hotel)</param>
        /// <param name="userData">User data (piggyback)</param>
        /// <param name="ct">Cancelation token</param>
        /// <param name="callback">callback method to invoke upon completion. Will be invoked also after cancelation</param>
        public void DisAssociateCardAsync(string token, string merchantId, Object userData, CancellationToken ct, Action<Entities.Result<Uri>> callback)
        {
            var baseUri = string.Format(
                "{0}/{1}/{2}/?op=Remove",
                PAYCARDS_URL_PATH,  Uri.EscapeDataString(token), Uri.EscapeDataString(merchantId));

            HttpRequestMessage requestMessage = new HttpRequestMessage(HttpMethod.Post, baseUri);

            Entities.Result<Uri> result = new Entities.Result<Uri>();
            result.Status.userData = userData;

            sendAsync(requestMessage, result.Status, ct, (response) =>
            {
                if (result.Status.IsSuccess)
                {
                    result.responsePayload = response.Headers.Location;
                }
                if (callback != null)
                    callback(result);
            });
        }
        /// <summary>
        /// Asynchronously Retrieve a payment Info object by Uri
        /// </summary>
        /// <param name="BankCardDetailsUri">the Uri to the payment Info resource</param>
        /// <param name="userData">User data (piggyback)</param>
        /// <param name="ct">Cancelation token</param>
        /// <param name="callback">callback method to invoke upon completion. Will be invoked also after cancelation</param>
        public void RetrieveBankCardDetailsAsync(string BankCardDetailsUri, Object userData, CancellationToken ct, Action<Entities.Result<Entities.BankCardDetails>> callback)
        {
            if (callback == null) return;

            Entities.Result<Entities.BankCardDetails> result = new Entities.Result<Entities.BankCardDetails>(); // { userData = userData };
            result.Status.userData = userData;

            HttpRequestMessage requestMessage = new HttpRequestMessage(HttpMethod.Get, BankCardDetailsUri);

           if (client.DefaultRequestHeaders.AcceptEncoding.Contains(new StringWithQualityHeaderValue("gzip")))
           {
               client.DefaultRequestHeaders.AcceptEncoding.Remove(new StringWithQualityHeaderValue("gzip"));
           }

            sendAsync(requestMessage, result.Status, ct, (response) =>
            {
                if (!result.Status.IsCancelled && response != null && response.StatusCode == System.Net.HttpStatusCode.OK)
                {
                    // populate result

                    Entities.BankCardDetails bcd = BaseRestfulClient.getObjectFromResponse<Entities.BankCardDetails>(response);
                    result.responsePayload = bcd;

                    //
                    //result.responsePayload = new Entities.BankCardDetails();
                    //result.responsePayload.LoadBinary(response.Content.ReadAsStreamAsync().Result);
                    //

                }
                callback(result);
            });
        }
        /// <summary>
        /// Asynchronously retrieve list of bank card items by creator reference
        /// </summary>
        /// <param name="creatorReference">the reference string provided by the creator</param>
        /// <param name="userData">User data (piggyback)</param>
        /// <param name="ct">Cancelation token</param>
        /// <param name="callback">callback method to invoke upon completion. Will be invoked also after cancelation</param>
        public void GetBankCardListAsync(String creatorReference, Object userData, CancellationToken ct, Action<Entities.Result<List<Entities.BankCardMeta>>> callback)
        {
            string uri = String.Format("{0}/meta?ref={1}", PAYCARDS_URL_PATH, System.Uri.EscapeDataString(creatorReference));
            var result = new Entities.Result<List<Entities.BankCardMeta>>();
            result.Status.userData = userData;

            HttpRequestMessage requestMessage = new HttpRequestMessage(HttpMethod.Get, uri);

            sendAsync(requestMessage, result.Status, ct, (response) =>
            {
                if (result.Status.IsSuccess)
                {
                    // populate list of Payment info
                    result.responsePayload = Helpers.Http.getObjectFromContent<List<Entities.BankCardMeta>>(response);
                }
                if (callback != null)
                    callback(result);
            });
        }
        /// <summary>
        /// Asynchronously Put a payment Info object with possible association to a merchant
        /// </summary>
        /// <param name="cardDetailsContent">HTTP Contennt already containing the payment Info object</param>
        /// <param name="creatorReference">On optional value to be used by the sender for future reference</param>
        /// <param name="saveCVV">Whether to save the Security code with the card</param>
        /// <param name="merchantId">Optional value allowing access to the given merchant Id (pciBooking user Id of the hotel)</param>
        /// <param name="storeMode">Where to store the card data</param>
        /// <param name="userData">User data (piggyback)</param>
        /// <param name="ct">Cancelation token</param>
        /// <param name="callback">callback method to invoke upon completion. Will be invoked also after cancelation</param>
        /// <remarks>Only bank cards are supported</remarks>
        private void PutCardDetailsAsync
        (HttpContent cardDetailsContent, string creatorReference, bool saveCVV, string merchantId, StoreMode storeMode, 
                Object userData, CancellationToken ct, Action<Entities.Result<Uri>> callback)
        {
            var baseUri = string.Format(
                "{0}?ref={1}&merchant={2}&storeMode={3}&saveCVV={4}",
                PAYCARDS_URL_PATH, 
                Uri.EscapeDataString(creatorReference),
                Uri.EscapeDataString(merchantId),
                Uri.EscapeDataString(storeMode.ToString()),
                Uri.EscapeDataString(saveCVV.ToString())
                );

            HttpRequestMessage requestMessage = new HttpRequestMessage(HttpMethod.Post, baseUri);
            requestMessage.Content = cardDetailsContent;

            Entities.Result<Uri> result = new Entities.Result<Uri>();
            result.Status.userData = userData;

            sendAsync(requestMessage, result.Status, ct, (response) =>
            {
                if (result.Status.IsSuccess)
                {
                    result.responsePayload = response.Headers.Location;
                }
                if (callback != null)
                    callback(result);
            });
        }
        /// <summary>
        /// Common method for async receiving messages
        /// </summary>
        /// <param name="urlSuffix">the url suffix (after base url) to be used</param>
        /// <param name="userData">User data (piggyback)</param>
        /// <param name="ct">Cancelation token</param>
        /// <param name="callback">callback method to invoke upon completion. Will be invoked also after cancelation</param>
        private void CommonGetMessageListAsync(string urlSuffix, Object userData, CancellationToken ct, Action<Entities.Result<List<Entities.MessageHeaderStatus>>> callback)
        {
            Entities.Result<List<Entities.MessageHeaderStatus>> result = new Entities.Result<List<Entities.MessageHeaderStatus>>() ;
            result.Status.userData = userData ;

            HttpRequestMessage requestMessage = new HttpRequestMessage(HttpMethod.Get, urlSuffix);

            sendAsync(requestMessage, result.Status, ct, (response) =>
            {
                if (result.Status.IsSuccess)
                {
                    // populate messageList
                    result.responsePayload = Helpers.Http.getObjectFromContent<List<Entities.MessageHeaderStatus>>(response);      // getMessageListFromContent(response);
                }
                if (callback != null)
                    callback(result);
            });

        }
        /// <summary>
        /// async receiving messages by message IDs
        /// </summary>
        /// <param name="messageIds">list of messageIds</param>
        /// <param name="userData">User data (piggyback)</param>
        /// <param name="ct">Cancelation token</param>
        /// <param name="callback">callback method to invoke upon completion. Will be invoked also after cancelation</param>
        public void GetMessageListAsync(IEnumerable<String> messageIds, Object userData, CancellationToken ct, Action<Entities.Result<List<Entities.MessageHeaderStatus>>> callback)
        {
            if (callback == null || messageIds==null || !messageIds.Any()) return;

            if (messageIds.Contains<string>(String.Empty))
            {
                Entities.Result<List<Entities.MessageHeaderStatus>> r = new Entities.Result<List<Entities.MessageHeaderStatus>>();
                r.Status.IsFaulted = true;
                r.Status.userData = userData;
                r.Status.message = "Empty messageId";
                callback(r);
                return;
            }

            // add destination header
            string url = "/api/messages/outbound/meta/" + String.Join(",", messageIds);
            CommonGetMessageListAsync(url, userData, ct, callback);
        }
        /// <summary>
        /// Common method for sending a message
        /// </summary>
        /// <param name="content">Request content</param>
        /// <param name="destinationList">list of destinations</param>
        /// <param name="senderReference">Sender Reference</param>
        /// <param name="userData">User data (piggyback)</param>
        /// <param name="ct">Cancelation token</param>
        /// <param name="callback">callback method to invoke upon completion. Will be invoked also after cancelation</param>
        private void SendMessageAsync(HttpContent content, IEnumerable<Entities.EnvelopeDestination> destinationList, string senderReference, Object userData, CancellationToken ct, Action<Entities.Result<Uri, List<Entities.Destination>>> callback)
        {
            HttpRequestMessage requestMessage = new HttpRequestMessage(HttpMethod.Post, "/api/messages/outbound");

            requestMessage.Content = content;

            // add destination header
            string destinationsCsv = String.Join(",", destinationList.Select((dest) =>
            {
                return dest.ToHeaderFormat();
            }).ToArray());
            requestMessage.Headers.Add(Helpers.Constants.HEADER_DESTINATION, destinationsCsv);

            // add sender reference header
            if (!string.IsNullOrWhiteSpace(senderReference))
                requestMessage.Headers.Add(Helpers.Constants.HEADER_SENDER_REFERENCE, senderReference);

            Entities.Result<Uri, List<Entities.Destination>> result = new Entities.Result<Uri, List<Entities.Destination>>();
            result.Status.userData = userData;

            sendAsync(requestMessage, result.Status, ct, (response) =>
            {
                if (result.Status.IsSuccess)
                {
                    result.responsePayload = response.Headers.Location;
                    result.responsePayload2 = getDestinationsFromHeader(response);
                }
                if (callback != null)
                    callback(result);
            });
        }
        /// <summary>
        /// Asynchronously Delete a payment Info object
        /// </summary>
        /// <param name="token">Token representing the payment info</param>
        /// <param name="userData">User data (piggyback)</param>
        /// <param name="ct">Cancelation token</param>
        /// <param name="callback">callback method to invoke upon completion. Will be invoked also after cancelation</param>
        public void DeletePaymentInfoAsync(string token, Object userData, CancellationToken ct, Action<Entities.Result<Uri>> callback)
        {
            var baseUri = string.Format(
                "/api/payments/bankcard/{0}?op=Delete",
                Uri.EscapeDataString(token));

            HttpRequestMessage requestMessage = new HttpRequestMessage(HttpMethod.Post, baseUri);

            Entities.Result<Uri> result = new Entities.Result<Uri>();
            result.Status.userData = userData;

            sendAsync(requestMessage, result.Status, ct, (response) =>
            {
                if (result.Status.IsSuccess)
                {
                    result.responsePayload = response.Headers.Location;
                }
                if (callback != null)
                    callback(result);
            });
        }
        /// <summary>
        /// Asynchronously Put a payment Info object with possible association to a merchant
        /// </summary>
        /// <param name="paymentInfoContent">HTTP Contennt already containing the payment Info object</param>
        /// <param name="creatorReference">On optional value to be used by the sender for future reference</param>
        /// <param name="merchantId">Optional value allowing access to the given merchant Id (pciBooking user Id of the hotel)</param>
        /// <param name="userData">User data (piggyback)</param>
        /// <param name="ct">Cancelation token</param>
        /// <param name="callback">callback method to invoke upon completion. Will be invoked also after cancelation</param>
        /// <remarks>Only bank cards are supported</remarks>
        private void PutPaymentInfoAsync(HttpContent paymentInfoContent, string creatorReference, string merchantId, Object userData, CancellationToken ct, Action<Entities.Result<Uri>> callback)
        {
            var baseUri = string.Format(
                "/api/payments/bankcard?ref={0}&merchant={1}",
                Uri.EscapeDataString(creatorReference),
                Uri.EscapeDataString(merchantId));

            HttpRequestMessage requestMessage = new HttpRequestMessage(HttpMethod.Post, baseUri);
            requestMessage.Content = paymentInfoContent;

            Entities.Result<Uri> result = new Entities.Result<Uri>();
            result.Status.userData = userData;

            sendAsync(requestMessage, result.Status, ct, (response) =>
            {
                if (result.Status.IsSuccess)
                {
                    result.responsePayload = response.Headers.Location;
                }
                if (callback != null)
                    callback(result);
            });
        }