Object used for encapsulating the login credentials
        /// <summary>
        /// Method used for making an http GET call
        /// </summary>
        /// <param name="credentialsDetails">An object that encapsulates the Constant Contact credentials</param>
        /// <param name="contactURI">The URL for the call</param>
        /// <param name="strRequest">The request string representation</param>
        /// <param name="strResponse">The response string representation</param>
        /// <returns>The string representation of the response</returns>
        public static string CallServiceGet(CredentialsDetails credentialsDetails, string contactURI,
            out string strRequest, out string strResponse)
        {
            var loginCredentials = new CredentialCache
                                       {
                                           {
                                               new Uri("https://api.constantcontact.com/ws/customers/" +
                                                       credentialsDetails.User),
                                               "Basic",
                                               new NetworkCredential(
                                               credentialsDetails.Key + "%" + credentialsDetails.User,
                                               credentialsDetails.Password)
                                               }
                                       };

            var request = WebRequest.Create(contactURI);

            request.Credentials = loginCredentials;

            var response = (HttpWebResponse) request.GetResponse();

            var reader = new StreamReader(response.GetResponseStream());

            var xmlResponse = reader.ReadToEnd();
            reader.Close();
            response.Close();

            strRequest = PrintRequestString(request, credentialsDetails, string.Empty);
            strResponse = xmlResponse;

            return xmlResponse;
        }
        /// <summary>
        /// Method used for trying to access the current user root document, if the credentials are fine then an xml response will be brought back
        /// else an exception will be thrown
        /// </summary>
        /// <param name="credentialsDetail">An object that encapsulates the Constant Contact credentials</param>
        /// <param name="strRequest">The request string representation</param>
        /// <param name="strResponse">The response string representation</param>
        public static void Authentification(CredentialsDetails credentialsDetail,
            out string strRequest, out string strResponse)
        {
            var contactURI = "https://api.constantcontact.com/ws/customers/" + credentialsDetail.User + "/";

            ApiCallComponent.CallServiceGet(credentialsDetail, contactURI, out strRequest, out strResponse);
        }
        /// <summary>
        /// Method used for adding a new contact list to Constant Contact
        /// </summary>
        /// <param name="credentialsDetail">An object that encapsulates the Constant Contact credentials</param>
        /// <param name="name">The name of the new contact list</param>
        /// <param name="strRequest">The request string representation</param>
        /// <param name="strResponse">The response string representation</param>
        /// <returns>A Contact List Detail object with the newly created contact lists</returns>
        public static ContactListDetails AddContactList(CredentialsDetails credentialsDetail, string name,
            out string strRequest, out string strResponse)
        {
            var returnValue = new ContactListDetails();

            var contactURI = "https://api.constantcontact.com/ws/customers/" + credentialsDetail.User + "/lists";

            var response = ApiCallComponent.CallServicePost(credentialsDetail, contactURI, CreateList(name),
                                                            out strRequest, out strResponse);

            var xdoc = XDocument.Parse(response);

            var result = from doc in xdoc.Descendants(W3Ns + "id")
                         select doc.Value;

            var id = result.FirstOrDefault();

            if (string.IsNullOrEmpty(id))
                throw new Exception();

            returnValue.Id = "https" + Regex.Split(id, "http")[1];
            returnValue.Name = name;

            return returnValue;
        }
        /// <summary>
        /// event triggered when the user tries to login 
        /// </summary>
        /// <param name="sender">the authentication control</param>
        /// <param name="e">e</param>
        private void LoginDoLogin(object sender, EventArgs e)
        {
            //do login action
            var user = ((Login) sender).UseName;
            var pass = ((Login) sender).Password;
            var key = ((Login) sender).Key;

            _credentialsDetails = new CredentialsDetails {Key = key, Password = pass, User = user};

            try
            {
                string strRequest;
                string strResponse;

                Cursor.Current = Cursors.WaitCursor;

                OperationsComponent.Authentification(_credentialsDetails, out strRequest, out strResponse);

                Cursor.Current = Cursors.Default;

                //print the request string
                richTextBoxRequest.Text = strRequest;

                //print the response string
                richTextBoxResponse.Text = strResponse;

                //clean up the loging control
                if (_login == null) return;
                _login.DoLogin -= LoginDoLogin;
                _login.Parent = null;
                _login = null;

                //show the contact list control
                _contactListControl = new ContactListControl
                                          {
                                              Dock = DockStyle.Fill,
                                              Parent = splitContainer.Panel1,
                                              FrmMain = this,
                                              CredentialsDetails = _credentialsDetails
                                          };
                _contactListControl.DoShowContactsInList += (ContactListControlDoShowContactsInList);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, Resources.MessageBoxTitle, MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

            Cursor.Current = Cursors.Default;
        }
        /// <summary>
        /// Creates the display string for the current http request
        /// </summary>
        /// <param name="request">The WebRequest object</param>
        /// <param name="credentialsDetails">An object that encapsulates the Constant Contact credentials</param>
        /// <param name="postData">The post data string representation</param>
        /// <returns>A string representation of the request for displaying</returns>
        private static string PrintRequestString(WebRequest request, CredentialsDetails credentialsDetails,
            string postData)
        {
            var returnValue = string.Format("URL: {0}", request.RequestUri);
            returnValue = string.Format("{0}{1}Method: {2}", returnValue, Environment.NewLine, request.Method);
            returnValue = string.Format("{0}{1}{2}", returnValue, Environment.NewLine,
                                        request.Headers.ToString().TrimEnd(new[] {'\n', '\r'}));
            if (!string.IsNullOrEmpty(postData))
            {
                returnValue = string.Format("{0}{1}Request Body: {2}", returnValue, Environment.NewLine, postData);
            }
            returnValue = string.Format("{0}{1}PreAuthenticate: {2}", returnValue, Environment.NewLine,
                                        request.PreAuthenticate);
            returnValue = string.Format("{0}{1}Username: {2}%{3}", returnValue, Environment.NewLine,
                                        credentialsDetails.Key, credentialsDetails.User);

            var fuscatedPassword = credentialsDetails.Password;
            for (var i = 0; i < fuscatedPassword.Length; i++)
            {
                fuscatedPassword = fuscatedPassword.Replace(fuscatedPassword.Substring(i, 1), "*");
            }

            returnValue = string.Format("{0}{1}Password: {2}", returnValue, Environment.NewLine, fuscatedPassword);

            return returnValue;
        }
        /// <summary>
        /// Method used for making an http PUT call
        /// </summary>
        /// <param name="credentialsDetails">An object that encapsulates the Constant Contact credentials</param>
        /// <param name="contactURI">The URL for the call</param>
        /// <param name="data">The put data string representation</param>
        /// <param name="strRequest">The request string representation</param>
        /// <param name="strResponse">The response string representation</param>
        /// <returns>The string representation of the response</returns>
        public static string CallServicePut(CredentialsDetails credentialsDetails, string contactURI,
            string data, out string strRequest, out string strResponse)
        {
            var loginCredentials = new CredentialCache
                                       {
                                           {
                                               new Uri("https://api.constantcontact.com/ws/customers/" +
                                                       credentialsDetails.User),
                                               "Basic",
                                               new NetworkCredential(
                                               credentialsDetails.Key + "%" + credentialsDetails.User,
                                               credentialsDetails.Password)
                                               }
                                       };

            var request = (HttpWebRequest)WebRequest.Create(contactURI);
            request.Method = "PUT";
            request.ContentType = "application/atom+xml";
            request.Credentials = loginCredentials;
            var xmlData = data;
            var byteArray = Encoding.UTF8.GetBytes(xmlData);

            request.ContentLength = byteArray.Length;
            var xmlResponse = string.Empty;
            var streamRequest = request.GetRequestStream();
            streamRequest.Write(byteArray, 0, byteArray.Length);
            streamRequest.Close();
            var response = (HttpWebResponse)request.GetResponse();

            var reader = new StreamReader(response.GetResponseStream());

            xmlResponse += reader.ReadToEnd();
            reader.Close();
            response.Close();

            strRequest = PrintRequestString(request, credentialsDetails, data);
            strResponse = xmlResponse;

            return xmlResponse;
        }
        /// <summary>
        /// Gets the contact list collection for the current user
        /// </summary>
        /// <param name="credentialsDetail">An object that encapsulates the Constant Contact credentials</param>
        /// <param name="strRequest">The request string representation</param>
        /// <param name="strResponse">The response string representation</param>
        /// <returns>The contact lists collection</returns>
        public static List<ContactListDetails> GetContactLists(CredentialsDetails credentialsDetail,
            out string strRequest, out string strResponse)
        {
            var contactURI = "https://api.constantcontact.com/ws/customers/" + credentialsDetail.User + "/lists";

            var xmlResponse = ApiCallComponent.CallServiceGet(credentialsDetail, contactURI, out strRequest,
                                                              out strResponse);

            var xdoc = XDocument.Parse(xmlResponse);

            if (xdoc.Root == null)
            {
                return null;
            }

            var lists = from f in xdoc.Root.Descendants(W3Ns + "entry")
                        let element = f.Element(W3Ns + "id")
                        where element != null
                        let xElement = element
                        where
                            xElement != null &&
                            (!xElement.Value.Contains("do-not-mail") & !xElement.Value.Contains("active") &
                             !xElement.Value.Contains("removed"))
                        let xElement1 = f.Element(W3Ns + "content")
                        where xElement1 != null
                        let element1 = xElement1.Element(ConstantContactNs + "ContactList")
                        where element1 != null
                        let xElement2 = element1.Element(ConstantContactNs + "Name")
                        where xElement2 != null
                        select new
                                   {
                                       id = element.Value,
                                       name = xElement2.Value
                                   };

            return
                lists.Select(
                    list => new ContactListDetails {Id = "https" + Regex.Split(list.id, "http")[1], Name = list.name}).
                    ToList();
        }
 /// <summary>
 /// Method used for deleting an existing contact list
 /// </summary>
 /// <param name="credentialsDetail">An object that encapsulates the Constant Contact credentials</param>
 /// <param name="listId">The id of the list to be deleted</param>
 /// <param name="strRequest">The request string representation</param>
 /// <param name="strResponse">The response string representation</param>
 public static void DeleteContactList(CredentialsDetails credentialsDetail, string listId, out string strRequest,
     out string strResponse)
 {
     ApiCallComponent.CallServiceDelete(credentialsDetail, listId, out strRequest, out strResponse);
 }
        /// <summary>
        /// Method used for updating an existing contact
        /// </summary>
        /// <param name="credentialsDetails">An object that encapsulates the Constant Contact credentials</param>
        /// <param name="contact">The contact url</param>
        /// <param name="strRequest">The request string representation</param>
        /// <param name="strResponse">The response string representation</param>
        public static void UpdateExistingContact(CredentialsDetails credentialsDetails, ContactDetails contact, out string strRequest, out string strResponse)
        {
            string req;
            string res;

            //Get the contact data
            var xmlContact = ApiCallComponent.CallServiceGet(credentialsDetails, contact.Id, out req, out res);

            //Update the contact data
            var xContact = XDocument.Parse(xmlContact);
            var contactNode = (from f in xContact.Descendants(W3Ns + "content")
                               let element = f.Element(ConstantContactNs + "Contact")
                               where element != null
                               select element).FirstOrDefault();

            if (contactNode != null)
            {
                contactNode.SetElementValue(ConstantContactNs + "FirstName", contact.FirstName);
                contactNode.SetElementValue(ConstantContactNs + "LastName", contact.LastName);
            }

            //Put the updated contact data
            ApiCallComponent.CallServicePut(credentialsDetails, contact.Id, xContact.Declaration.ToString() + xContact, out strRequest, out strResponse);
        }
        /// <summary>
        /// Get the contacts for a given list along with some contact details
        /// </summary>
        /// <param name="credentialsDetail">An object that encapsulates the Constant Contact credentials</param>
        /// <param name="listId">The id of the list for witch the contacts will be brought</param>
        /// <param name="strRequest">The request string representation</param>
        /// <param name="strResponse">The response string representation</param>
        /// <returns>A list of contact detail objects</returns>
        public static List<ContactDetails> GetContacts(CredentialsDetails credentialsDetail, string listId,
            out string strRequest, out string strResponse)
        {
            var contactCollection = new List<ContactDetails>();

            var xmlResponse = ApiCallComponent.CallServiceGet(credentialsDetail, listId + "/members", out strRequest,
                                                              out strResponse);

            var xdoc = XDocument.Parse(xmlResponse);

            if (xdoc.Root == null)
            {
                return null;
            }

            var contacts = from f in xdoc.Root.Descendants(W3Ns + "entry")
                           let element = f.Element(W3Ns + "id")
                           where element != null
                           select new
                                      {
                                          id = "https" + Regex.Split(element.Value, "http")[1]
                                      };

            foreach (var contact in contacts)
            {
                string req;
                string res;

                var xmlContact = ApiCallComponent.CallServiceGet(credentialsDetail, contact.id, out req, out res);

                var contactDetails = new ContactDetails();

                var xContact = XDocument.Parse(xmlContact);

                var c = (from f in xContact.Descendants(W3Ns + "content")
                         let element = f.Element(ConstantContactNs + "Contact")
                         where element != null
                         let element0 = element.Element(ConstantContactNs + "EmailAddress")
                         where element0 != null
                         let element1 = element.Element(ConstantContactNs + "FirstName")
                         where element1 != null
                         let element2 = element.Element(ConstantContactNs + "LastName")
                         where element2 != null
                         let element3 = element.Element(ConstantContactNs + "InsertTime")
                         where element3 != null
                         select new
                                    {
                                        email = element0.Value,
                                        firstName = element1.Value,
                                        lastName = element2.Value,
                                        updated = element3.Value
                                    }).ToList();

                var firstOrDefault = c.FirstOrDefault();
                if (firstOrDefault != null)
                {
                    contactDetails.Id = contact.id;
                    contactDetails.FirstName = firstOrDefault.firstName;
                    contactDetails.LastName = firstOrDefault.lastName;
                    contactDetails.CreateDate = string.Format("{0:MMM d, yyyy}", DateTime.Parse(firstOrDefault.updated));
                    contactDetails.Email = firstOrDefault.email;
                }

                contactCollection.Add(contactDetails);
            }

            return contactCollection;
        }
 public ContactControl(FrmMain frmMain, CredentialsDetails credentialsDetails)
 {
     FrmMain = frmMain;
     CredentialsDetails = credentialsDetails;
     InitializeComponent();
 }