/// <summary>
 /// Update a Contact using the simplified form. Only the following fields will be updated: 
 /// EmailAddress, FirstName, LastName, MiddleName, HomePhone, Addr1, Addr2, Addr3,
 /// City, StateCode, StateName, CountryCode, CountryName, PostalCode, SubPostalCode
 /// </summary>
 /// <param name="authenticationData">Authentication data (username, password and API Key)</param>
 /// <param name="contact">Contact to be updated</param>
 /// <exception cref="ArgumentNullException">Thrown if specified Contact is null</exception>
 /// <exception cref="ArgumentException">Thrown if Id or Email Address of specified Contact is null or empty</exception>        
 /// <exception cref="ConstantException">Thrown if communication error with Constant server occur 
 /// or other related with the response from server, if no Contact with specified Id exists 
 /// or if Contact cannot be updated (it belongs to the Do-Not-Mail list)
 /// or if ApiKey, Username or Password are null or empty</exception>        
 public static void UpdateContactSmallForm(AuthenticationData authenticationData, Contact contact)
 {
     UpdateContact(authenticationData, contact, false);
 }
        /// <summary>
        /// Create a New Contact
        /// </summary>        
        /// <param name="authenticationData">Authentication data (username, password and API Key)</param>
        /// <param name="contact">Contact to be created</param>        
        /// <remarks>The POST data presents only values for EmailAddress, FirstName, LastName, OptInSource and ContactLists elements</remarks>        
        /// <exception cref="ArgumentNullException">Thrown if specified Contact is null</exception>
        /// <exception cref="ArgumentException">Thrown if E-mail Address of specified Contact is null or empty</exception>
        /// <exception cref="ConstantException">Thrown if communication error with Constant server occur 
        /// or other related with the response from server or if specified Contact does not belongs to any list
        /// or if ApiKey, Username or Password are null or empty</exception>
        /// <returns>Newly created Contact</returns>
        public static Contact CreateNewContact(AuthenticationData authenticationData, Contact contact)
        {
            ValidateAuthenticationData(authenticationData);

            if (null == contact)
            {
                throw new ArgumentNullException("contact");
            }

            if (string.IsNullOrEmpty(contact.EmailAddress))
            {
                throw new ArgumentException("Contact E-mail Address cannot be null or empty", "contact");
            }

            if (null == contact.ContactLists
                || contact.ContactLists.Count == 0)
            {
                throw new ConstantException("Contact does not belongs to any contact list");
            }

            // get the Atom entry for specified Contact
            StringBuilder data = ContactComponent.CreateNewContact(contact, authenticationData.AccountContactListsUri);

            Stream stream = Stream.Null;
            try
            {
                // post the Atom entry at specified Uri and save the response stream
                stream = PostInformation(authenticationData, new Uri(authenticationData.AccountContactsUri),
                                         data.ToString());

                // return newly created Contact
                return ContactComponent.GetContactDetails(stream);
            }
            catch (Exception e)
            {
                throw new ConstantException(e.Message, e);
            }
            finally
            {
                // close the response stream
                stream.Close();
            }
        }
 /// <summary>
 /// Update a Contact using the full form. All Contact fields will be updated
 /// </summary>
 /// <param name="authenticationData">Authentication data (username, password and API Key)</param>
 /// <param name="contact">Contact to be updated</param>
 /// <exception cref="ArgumentNullException">Thrown if specified Contact is null</exception>
 /// <exception cref="ArgumentException">Thrown if Id or Email Address of specified Contact is null or empty</exception>        
 /// <exception cref="ConstantException">Thrown if communication error with Constant server occur 
 /// or other related with the response from server, if no Contact with specified Id exists 
 /// or if Contact cannot be updated (it belongs to the Do-Not-Mail list)
 /// or if ApiKey, Username or Password are null or empty</exception>        
 public static void UpdateContactFullForm(AuthenticationData authenticationData, Contact contact)
 {
     UpdateContact(authenticationData, contact, true);
 }
        /// <summary>
        /// Get Contact object with details from specified Xml data
        /// </summary>
        /// <param name="node">Xml data cursor model</param>
        /// <param name="resolver">Xml namespace resolver</param>
        /// <returns>Contact with details</returns>
        private static Contact GetContactDetail(XPathNavigator node, IXmlNamespaceResolver resolver)
        {
            Contact c = new Contact();
            c.Link = GetContactLink(node, resolver);

            const string xpathSelect = @"at:content/cc:Contact";

            XPathNodeIterator contactNodes = node.Select(xpathSelect, resolver);

            while (contactNodes.MoveNext())
            {
                XPathNavigator currentContactNode = contactNodes.Current;

                c.Id = GetContactId(currentContactNode);

                if (currentContactNode.HasChildren)
                {
                    currentContactNode.MoveToFirstChild();
                    do
                    {
                        switch (currentContactNode.Name)
                        {
                            case ContactXmlElementAddr1:
                                c.AddressLine1 = currentContactNode.Value;
                                break;
                            case ContactXmlElementAddr2:
                                c.AddressLine2 = currentContactNode.Value;
                                break;
                            case ContactXmlElementAddr3:
                                c.AddressLine3 = currentContactNode.Value;
                                break;
                            case ContactXmlElementCity:
                                c.City = currentContactNode.Value;
                                break;
                            case ContactXmlElementCompanyName:
                                c.CompanyName = currentContactNode.Value;
                                break;
                            case ContactXmlElementConfirmed:
                                c.Confirmed = currentContactNode.ValueAsBoolean;
                                break;
                            case ContactXmlElementCountryCode:
                                c.CountryCode = currentContactNode.Value;
                                break;
                            case ContactXmlElementCountryName:
                                c.CountryName = currentContactNode.Value;
                                break;
                            case ContactXmlElementCustomField1:
                                c.CustomField1 = currentContactNode.Value;
                                break;
                            case ContactXmlElementCustomField2:
                                c.CustomField2 = currentContactNode.Value;
                                break;
                            case ContactXmlElementCustomField3:
                                c.CustomField3 = currentContactNode.Value;
                                break;
                            case ContactXmlElementCustomField4:
                                c.CustomField4 = currentContactNode.Value;
                                break;
                            case ContactXmlElementCustomField5:
                                c.CustomField5 = currentContactNode.Value;
                                break;
                            case ContactXmlElementCustomField6:
                                c.CustomField6 = currentContactNode.Value;
                                break;
                            case ContactXmlElementCustomField7:
                                c.CustomField7 = currentContactNode.Value;
                                break;
                            case ContactXmlElementCustomField8:
                                c.CustomField8 = currentContactNode.Value;
                                break;
                            case ContactXmlElementCustomField9:
                                c.CustomField9 = currentContactNode.Value;
                                break;
                            case ContactXmlElementCustomField10:
                                c.CustomField10 = currentContactNode.Value;
                                break;
                            case ContactXmlElementCustomField11:
                                c.CustomField11 = currentContactNode.Value;
                                break;
                            case ContactXmlElementCustomField12:
                                c.CustomField12 = currentContactNode.Value;
                                break;
                            case ContactXmlElementCustomField13:
                                c.CustomField13 = currentContactNode.Value;
                                break;
                            case ContactXmlElementCustomField14:
                                c.CustomField14 = currentContactNode.Value;
                                break;
                            case ContactXmlElementCustomField15:
                                c.CustomField15 = currentContactNode.Value;
                                break;
                            case ContactXmlElementEmailAddresss:
                                c.EmailAddress = currentContactNode.Value;
                                break;
                            case ContactXmlElementEmailType:
                                c.EmailType = GetEmailType(currentContactNode.Value);
                                break;
                            case ContactXmlElementFirstName:
                                c.FirstName = currentContactNode.Value;
                                break;
                            case ContactXmlElementHomePhone:
                                c.HomePhone = currentContactNode.Value;
                                break;
                            case ContactXmlElementInsertTime:
                                c.InsertTime = currentContactNode.ValueAsDateTime;
                                break;
                            case ContactXmlElementJobTitle:
                                c.JobTitle = currentContactNode.Value;
                                break;
                            case ContactXmlElementLastName:
                                c.LastName = currentContactNode.Value;
                                break;
                            case ContactXmlElementLastUpdateTime:
                                c.LastUpdateTime = currentContactNode.ValueAsDateTime;
                                break;
                            case ContactXmlElementMiddleName:
                                c.MiddleName = currentContactNode.Value;
                                break;
                            case ContactXmlElementName:
                                c.Name = currentContactNode.Value;
                                break;
                            case ContactXmlElementNote:
                                c.Note = currentContactNode.Value;
                                break;
                            case ContactXmlElementPostalCode:
                                c.PostalCode = currentContactNode.Value;
                                break;
                            case ContactXmlElementStateCode:
                                c.StateCode = currentContactNode.Value;
                                break;
                            case ContactXmlElementStateName:
                                c.StateName = currentContactNode.Value;
                                break;
                            case ContactXmlElementStatus:
                                c.Status = GetContactStatus(currentContactNode.Value);
                                break;
                            case ContactXmlElementSubPostalCode:
                                c.SubPostalCode = currentContactNode.Value;
                                break;
                            case ContactXmlElementWorkPhone:
                                c.WorkPhone = currentContactNode.Value;
                                break;
                            case ContactXmlElementContactLists:
                                if (currentContactNode.HasChildren)
                                {
                                    // loop through all the Contact List
                                    XPathNavigator contactListsNode = currentContactNode.Clone();
                                    XPathNodeIterator lists = contactListsNode.Select("//cc:ContactList", resolver);
                                    while (lists.MoveNext())
                                    {
                                        // get current Contact List
                                        XPathNavigator list = lists.Current;

                                        ContactList contactList = new ContactList();
                                        // get the id of Contact List
                                        contactList.Id = GetContactListId(list);

                                        ContactOptInList optInList = new ContactOptInList();
                                        optInList.ContactList = contactList;

                                        if (list.HasChildren)
                                        {
                                            list.MoveToFirstChild();
                                            do
                                            {
                                                switch (list.Name)
                                                {
                                                    case ContactXmlElementOptInSource:
                                                        optInList.OptInSource = GetOptSource(list.Value);
                                                        break;
                                                    case ContactXmlElementOptInTime:
                                                        optInList.OptInTime = list.ValueAsDateTime;
                                                        break;
                                                }
                                            } while (list.MoveToNext());
                                        }

                                        // add the Contact List to current Contact
                                        c.ContactLists.Add(optInList);
                                    }
                                }
                                break;
                        }

                    } while (currentContactNode.MoveToNext());
                }

                break;
            }

            return c;
        }
        /// <summary>
        /// Update a Contact
        /// </summary>
        /// <param name="authenticationData">Authentication data (username, password and API Key)</param>
        /// <param name="contact">Contact to be updated</param>
        /// <param name="fullUpdate">True if all Contact fields will be update; False otherwise (only the following fields 
        /// will be updated: EmailAddress, FirstName, LastName, MiddleName, HomePhone, Addr1, Addr2, Addr3,
        /// City, StateCode, StateName, CountryCode, CountryName, PostalCode, SubPostalCode)</param>
        /// <exception cref="ArgumentNullException">Thrown if specified Contact is null</exception>
        /// <exception cref="ArgumentException">Thrown if Id or Email Address of specified Contact is null or empty</exception>        
        /// <exception cref="ConstantException">Thrown if communication error with Constant server occur 
        /// or other related with the response from server, if no Contact with specified Id exists 
        /// or if Contact cannot be updated (it belongs to the Do-Not-Mail list)
        /// or if ApiKey, Username or Password are null or empty</exception>        
        private static void UpdateContact(AuthenticationData authenticationData, Contact contact, bool fullUpdate)
        {
            ValidateAuthenticationData(authenticationData);

            if (null == contact)
            {
                throw new ArgumentNullException("contact");
            }

            if (string.IsNullOrEmpty(contact.Id))
            {
                throw new ArgumentException("Contact Id cannot be null or empty", "contact");
            }

            if (string.IsNullOrEmpty(contact.EmailAddress))
            {
                throw new ArgumentException("Contact Email Address cannot be null or empty", "contact");
            }

            // create the URI for specified Contact Id
            string completeUri = String.Format(CultureInfo.InvariantCulture, "{0}{1}",
                                               AuthenticationData.HostAddress, contact.Link);

            // get the Atom entry for specified Contact
            StringBuilder data = ContactComponent.UpdateContact(contact, authenticationData.ApiRootUri,
                                                                authenticationData.AccountContactListsUri, fullUpdate);

            try
            {
                // put the Atom entry at specified Uri
                PutInformation(authenticationData, new Uri(completeUri), data.ToString());
            }
            catch (Exception e)
            {
                if (string.Compare(e.Message, WebExceptionCode404Message) == 0)
                {
                    throw new ConstantException(String.Format(CultureInfo.InvariantCulture,
                                                              "Contact with Id '{0}' does not exist.", contact.Id));
                }
                if (string.Compare(e.Message, WebExceptionCode403Message) == 0)
                {
                    throw new ConstantException("Contact cannot be updated. It belongs to the Do-Not-Mail list.");
                }

                throw new ConstantException(e.Message, e);
            }
        }
        /// <summary>
        /// Create an Atom entry used to update a Contact.
        /// Only the following fields will be updated: EmailAddress, FirstName, LastName, MiddleName, HomePhone, Addr1, Addr2, Addr3,
        /// City, StateCode, StateName, CountryCode, CountryName, PostalCode, SubPostalCode
        /// </summary>
        /// <param name="contact">Contact to be updated</param>
        /// <param name="apiUri">Uri address of Account Owner Contact resource</param>
        /// <param name="accountContactListUri">Uri address of Account Owner Contact List resource</param>
        /// <returns>Atom entry used to update the Contact
        /// <example>
        ///     <entry xmlns="http://www.w3.org/2005/Atom">
        ///         <title type="text"> </title>
        ///         <updated>2008-07-23T14:21:06.407Z</updated>
        ///         <author></author>
        ///         <id>http://api.constantcontact.com/ws/customers/joesflowers/contacts/1454</id>
        ///         <summary type="text">Contact</summary>
        ///         <content type="application/vnd.ctct+xml">
        ///             <Contact xmlns="http://ws.constantcontact.com/ns/1.0/">
        ///                 <EmailAddress>[email protected]</EmailAddress>
        ///                 <FirstName>First</FirstName>
        ///                 <LastName>Last</LastName>
        ///                 <OptInSource>ACTION_BY_CUSTOMER</OptInSource>
        ///                 <ContactLists>
        ///                     <ContactList id="http://api.constantcontact.com/ws/customers/joesflowers/lists/1" />
        ///                 </ContactLists>
        ///             </Contact>
        ///         </content>
        ///     </entry>
        /// </example>
        /// </returns>
        private static StringBuilder CreateSmallUpdateAtomEntry(Contact contact, string apiUri, 
            string accountContactListUri)
        {
            // TBD!! - Change to use the contact.Link field
            string contactId = Regex.Replace(String.Format(CultureInfo.InvariantCulture,
                                                           "{0}{1}", apiUri, contact.Link),
                                             "https://", "http://");

            StringBuilder data = new StringBuilder();

            data.AppendFormat("<entry xmlns=\"{0}\">", AtomNamespace);
            data.Append("<title type=\"text\"></title>");
            data.Append("<updated>2008-07-23T14:21:06.407Z</updated>");
            data.Append("<author><name>Constant Contact</name></author>");
            data.AppendFormat("<id>{0}</id>", contactId);
            data.Append("<summary type=\"text\">Contact</summary>");
            data.Append("<content type=\"application/vnd.ctct+xml\">");
            data.AppendFormat("<Contact xmlns=\"{0}\" id=\"{1}\">", ConstantNamespace, contactId);
            data.AppendFormat("<EmailAddress>{0}</EmailAddress>", contact.EmailAddress);
            data.AppendFormat("<FirstName>{0}</FirstName>", contact.FirstName);
            data.AppendFormat("<LastName>{0}</LastName>", contact.LastName);
            data.AppendFormat("<MiddleName>{0}</MiddleName>", contact.MiddleName);

            // set the opt in source
            ContactOptSource optInSource = ContactOptSource.ActionByCustomer;
            if (contact.Status == ContactStatus.DoNotMail)
            {
                optInSource = ContactOptSource.ActionByContact;
            }
            data.AppendFormat("<OptInSource>{0}</OptInSource>", optSourceNames[optInSource]);
            data.AppendFormat("<HomePhone>{0}</HomePhone>", contact.HomePhone);
            data.AppendFormat("<Addr1>{0}</Addr1>", contact.AddressLine1);
            data.AppendFormat("<Addr2>{0}</Addr2>", contact.AddressLine2);
            data.AppendFormat("<Addr3>{0}</Addr3>", contact.AddressLine3);
            data.AppendFormat("<City>{0}</City>", contact.City);
            data.AppendFormat("<StateCode>{0}</StateCode>", contact.StateCode);
            data.AppendFormat("<StateName>{0}</StateName>", contact.StateName);
            data.AppendFormat("<CountryCode>{0}</CountryCode>", contact.CountryCode);
            data.AppendFormat("<CountryName>{0}</CountryName>", contact.CountryName);
            data.AppendFormat("<PostalCode>{0}</PostalCode>", contact.PostalCode);
            data.AppendFormat("<SubPostalCode>{0}</SubPostalCode>", contact.SubPostalCode);

            data.Append("<ContactLists>");
            if (contact.ContactLists != null)
            {
                foreach (ContactOptInList cList in contact.ContactLists)
                {
                    data.AppendFormat("<ContactList id=\"{0}/{1}\"/>",
                                      Regex.Replace(accountContactListUri, "https://", "http://"), cList.ContactList.Id);
                }
            }
            data.Append("</ContactLists>");

            data.Append("</Contact>");
            data.Append("</content>");
            data.Append("</entry>");

            return data;
        }
        /// <summary>
        /// Get Contact object from specified Xml data
        /// </summary>
        /// <param name="node">Xml data cursor model</param>
        /// <param name="resolver">Xml namespace resolver</param>
        /// <returns>Contact with details</returns>
        private static Contact GetContact(XPathNavigator node, IXmlNamespaceResolver resolver)
        {
            Contact c = new Contact();
            c.Link = GetContactLink(node, resolver);

            const string xpathSelect = @"at:content/cc:Contact";

            XPathNodeIterator contactNodes = node.Select(xpathSelect, resolver);

            while (contactNodes.MoveNext())
            {
                XPathNavigator currentContactNode = contactNodes.Current;

                c.Id = GetContactId(currentContactNode);

                if (currentContactNode.HasChildren)
                {
                    currentContactNode.MoveToFirstChild();
                    do
                    {
                        switch (currentContactNode.Name)
                        {
                            case ContactXmlElementName:
                                c.Name = currentContactNode.Value;
                                break;
                            case ContactXmlElementEmailAddresss:
                                c.EmailAddress = currentContactNode.Value;
                                break;
                            case ContactXmlElementEmailType:
                                c.EmailType = GetEmailType(currentContactNode.Value);
                                break;
                            case ContactXmlElementOptInSource:
                                c.OptInSource = GetOptSource(currentContactNode.Value);
                                break;
                            case ContactXmlElementOptInTime:
                                c.OptInTime = currentContactNode.ValueAsDateTime;
                                break;
                            case ContactXmlElementStatus:
                                c.Status = GetContactStatus(currentContactNode.Value);
                                break;
                            case ContactXmlElementConfirmed:
                                c.Confirmed = currentContactNode.ValueAsBoolean;
                                break;
                            case ContactXmlElementInsertTime:
                                c.InsertTime = currentContactNode.ValueAsDateTime;
                                break;
                            default:
                                //System.Diagnostics.Debugger.Break();
                                break;
                        }

                    } while (currentContactNode.MoveToNext());
                }

                break;
            }

            return c;
        }
        /// <summary>
        /// Create an Atom entry used to update a Contact
        /// </summary>
        /// <param name="contact">Contact to be updated</param>
        /// <param name="accountContactUri">Uri address of Account Owner Contact resource</param>
        /// <returns>Atom entry used to update the Contact
        /// <example>
        ///     <entry xmlns="http://www.w3.org/2005/Atom">
        ///         <title type="text"> </title>
        ///         <updated>2008-07-23T14:21:06.407Z</updated>
        ///         <author></author>
        ///         <id>http://api.constantcontact.com/ws/customers/joesflowers/contacts/1454</id>
        ///         <summary type="text">Contact</summary>
        ///         <content type="application/vnd.ctct+xml">
        ///             <Contact xmlns="http://ws.constantcontact.com/ns/1.0/">
        ///                 <OptInSource>ACTION_BY_CUSTOMER</OptInSource>
        ///                 <ContactLists>
        ///                 </ContactLists>
        ///             </Contact>
        ///         </content>
        ///     </entry>
        /// </example>
        /// </returns>
        private static StringBuilder CreateRemoveFromAllListsAtomEntry(Contact contact, string accountContactUri)
        {
            string contactId = Regex.Replace(String.Format(CultureInfo.InvariantCulture,
                                                           "{0}/{1}", accountContactUri, contact.Id),
                                             "https://", "http://");

            StringBuilder data = new StringBuilder();

            data.AppendFormat("<entry xmlns=\"{0}\">", AtomNamespace);
            data.Append("<title type=\"text\"></title>");
            data.Append("<updated>2008-07-23T14:21:06.407Z</updated>");
            data.Append("<author><name>Constant Contact</name></author>");
            data.AppendFormat("<id>{0}</id>", contactId);
            data.Append("<summary type=\"text\">Contact</summary>");
            data.Append("<content type=\"application/vnd.ctct+xml\">");
            data.AppendFormat("<Contact xmlns=\"{0}\" id=\"{1}\">", ConstantNamespace, contactId);
            data.AppendFormat("<EmailAddress>{0}</EmailAddress>", contact.EmailAddress);

            // set the opt in source
            data.AppendFormat("<OptInSource>{0}</OptInSource>", optSourceNames[ContactOptSource.ActionByCustomer]);

            data.Append("<ContactLists>");
            data.Append("</ContactLists>");

            data.Append("</Contact>");
            data.Append("</content>");
            data.Append("</entry>");

            return data;
        }
        /// <summary>
        /// Create an Atom entry used to update a Contact
        /// </summary>
        /// <param name="contact">Contact to be updated</param>
        /// <param name="accountContactUri">Uri address of Account Owner Contact resource</param>
        /// <param name="accountContactListUri">Uri address of Account Owner Contact List resource</param>
        /// <returns>Atom entry used to update the Contact
        /// <example>
        ///     <entry xmlns="http://www.w3.org/2005/Atom">
        ///         <title type="text"> </title>
        ///         <updated>2008-07-23T14:21:06.407Z</updated>
        ///         <author></author>
        ///         <id>http://api.constantcontact.com/ws/customers/joesflowers/contacts/1454</id>
        ///         <summary type="text">Contact</summary>
        ///         <content type="application/vnd.ctct+xml">
        ///             <Contact xmlns="http://ws.constantcontact.com/ns/1.0/">
        ///                 <EmailAddress>[email protected]</EmailAddress>
        ///                 <FirstName>First</FirstName>
        ///                 <LastName>Last</LastName>
        ///                 <OptInSource>ACTION_BY_CUSTOMER</OptInSource>
        ///                 <ContactLists>
        ///                     <ContactList id="http://api.constantcontact.com/ws/customers/joesflowers/lists/1" />
        ///                 </ContactLists>
        ///             </Contact>
        ///         </content>
        ///     </entry>
        /// </example>
        /// </returns>
        private static StringBuilder CreateFullUpdateAtomEntry(Contact contact, string accountContactUri,
            string accountContactListUri)
        {
            string contactId = Regex.Replace(String.Format(CultureInfo.InvariantCulture,
                                                           "{0}{1}", accountContactUri, contact.Link),
                                             "https://", "http://");

            StringBuilder data = new StringBuilder();

            data.AppendFormat("<entry xmlns=\"{0}\">", AtomNamespace);
            data.Append("<title type=\"text\"></title>");
            data.Append("<updated>2008-07-23T14:21:06.407Z</updated>");
            data.Append("<author><name>Constant Contact</name></author>");
            data.AppendFormat("<id>{0}</id>", contactId);
            data.Append("<summary type=\"text\">Contact</summary>");
            data.Append("<content type=\"application/vnd.ctct+xml\">");
            data.AppendFormat("<Contact xmlns=\"{0}\" id=\"{1}\">", ConstantNamespace, contactId);
            data.AppendFormat("<EmailAddress>{0}</EmailAddress>", contact.EmailAddress);
            data.AppendFormat("<FirstName>{0}</FirstName>", contact.FirstName);
            data.AppendFormat("<LastName>{0}</LastName>", contact.LastName);
            data.AppendFormat("<MiddleName>{0}</MiddleName>", contact.MiddleName);

            // set the opt in source
            ContactOptSource optInSource = ContactOptSource.ActionByCustomer;
            if (contact.Status == ContactStatus.DoNotMail)
            {
                optInSource = ContactOptSource.ActionByContact;
            }
            data.AppendFormat("<OptInSource>{0}</OptInSource>", optSourceNames[optInSource]);
            data.AppendFormat("<HomePhone>{0}</HomePhone>", contact.HomePhone);
            data.AppendFormat("<Addr1>{0}</Addr1>", contact.AddressLine1);
            data.AppendFormat("<Addr2>{0}</Addr2>", contact.AddressLine2);
            data.AppendFormat("<Addr3>{0}</Addr3>", contact.AddressLine3);
            data.AppendFormat("<City>{0}</City>", contact.City);
            data.AppendFormat("<StateCode>{0}</StateCode>", contact.StateCode);
            data.AppendFormat("<StateName>{0}</StateName>", contact.StateName);
            data.AppendFormat("<CountryCode>{0}</CountryCode>", contact.CountryCode);
            data.AppendFormat("<CountryName>{0}</CountryName>", contact.CountryName);
            data.AppendFormat("<PostalCode>{0}</PostalCode>", contact.PostalCode);
            data.AppendFormat("<SubPostalCode>{0}</SubPostalCode>", contact.SubPostalCode);

            data.AppendFormat("<EmailType>{0}</EmailType>",
                              contact.EmailType == ContactEmailType.Undefined
                                  ? ContactEmailTypeHtml
                                  : emailTypeNames[contact.EmailType]);
            data.AppendFormat("<WorkPhone>{0}</WorkPhone>", contact.WorkPhone);
            data.AppendFormat("<JobTitle>{0}</JobTitle>", contact.JobTitle);
            data.AppendFormat("<CompanyName>{0}</CompanyName>", contact.CompanyName);
            data.AppendFormat("<Note>{0}</Note>", contact.Note);
            data.AppendFormat("<CustomField1>{0}</CustomField1>", contact.CustomField1);
            data.AppendFormat("<CustomField2>{0}</CustomField2>", contact.CustomField2);
            data.AppendFormat("<CustomField3>{0}</CustomField3>", contact.CustomField3);
            data.AppendFormat("<CustomField4>{0}</CustomField4>", contact.CustomField4);
            data.AppendFormat("<CustomField5>{0}</CustomField5>", contact.CustomField5);
            data.AppendFormat("<CustomField6>{0}</CustomField6>", contact.CustomField6);
            data.AppendFormat("<CustomField7>{0}</CustomField7>", contact.CustomField7);
            data.AppendFormat("<CustomField8>{0}</CustomField8>", contact.CustomField8);
            data.AppendFormat("<CustomField9>{0}</CustomField9>", contact.CustomField9);
            data.AppendFormat("<CustomField10>{0}</CustomField10>", contact.CustomField10);
            data.AppendFormat("<CustomField11>{0}</CustomField11>", contact.CustomField11);
            data.AppendFormat("<CustomField12>{0}</CustomField12>", contact.CustomField12);
            data.AppendFormat("<CustomField13>{0}</CustomField13>", contact.CustomField13);
            data.AppendFormat("<CustomField14>{0}</CustomField14>", contact.CustomField14);
            data.AppendFormat("<CustomField15>{0}</CustomField15>", contact.CustomField15);

            data.Append("<ContactLists>");
            if (contact.ContactLists != null)
            {
                foreach (ContactOptInList cList in contact.ContactLists)
                {
                    data.AppendFormat("<ContactList id=\"{0}/{1}\"/>",
                                      Regex.Replace(accountContactListUri, "https://", "http://"), cList.ContactList.Id);

                }
            }
            data.Append("</ContactLists>");

            data.Append("</Contact>");
            data.Append("</content>");
            data.Append("</entry>");

            return data;
        }
 /// <summary>
 /// Get the Atom entry for the Contact to be updated
 /// </summary>
 /// <param name="contact">Contact to be updated</param>
 /// <param name="apiUri">Uri of the API</param>
 /// <param name="accountContactListUri">Uri address of Account Owner Contact List resource</param>        
 /// <param name="fullUpdate">True if all Contact fields will be update; False otherwise (only the following fields 
 /// will be updated: EmailAddress, FirstName, LastName, MiddleName, HomePhone, Addr1, Addr2, Addr3,
 /// City, StateCode, StateName, CountryCode, CountryName, PostalCode, SubPostalCode)</param>
 /// <returns>Atom entry for updating specified Contact</returns>
 public static StringBuilder UpdateContact(Contact contact, string apiUri,
     string accountContactListUri, bool fullUpdate)
 {
     return fullUpdate
                ? CreateFullUpdateAtomEntry(contact, apiUri, accountContactListUri)
                : CreateSmallUpdateAtomEntry(contact, apiUri, accountContactListUri);
 }
 /// <summary>
 /// Get the Atom entry for the Contact to be removed from all Contact Lists
 /// </summary>
 /// <param name="contact">Contact to be updated</param>
 /// <param name="accountContactUri">Uri address of Account Owner Contact resource</param>
 /// <returns>Atom entry for updating specified Contact</returns>
 public static StringBuilder RemoveContactFromAllLists(Contact contact, string accountContactUri)
 {
     return CreateRemoveFromAllListsAtomEntry(contact, accountContactUri);
 }
 /// <summary>
 /// Get the Atom entry for newly Contact to be send to Constant server
 /// </summary>
 /// <param name="contact">Contact to be created</param>
 /// <param name="accountContactListUri">Uri address of Account Owner Contact resource</param>
 /// <returns>Atom entry for creating specified Contact</returns>        
 public static StringBuilder CreateNewContact(Contact contact, string accountContactListUri)
 {
     return CreateAtomEntry(contact, accountContactListUri);
 }