public static void Run()
        {
            // 0. Create the consumer session
            OAuthConsumerContext consumerContext = new OAuthConsumerContext
            {
                ConsumerKey = PartnerConsumerKey,
                ConsumerSecret = PartnerConsumerSecret,
                SignatureMethod = SignatureMethod.RsaSha1,
                UseHeaderForOAuthParameters = true,
                UserAgent = PartnerUserAgentString,
                Key = OAuthSigningCertificate.PrivateKey
            };

            OAuthSession consumerSession = new OAuthSession(
                consumerContext,
                Settings.Default.PartnerRequestTokenURI,
                Settings.Default.AuthoriseURI,
                Settings.Default.PartnerAccessTokenURI);

            // Replace the default ConsumerRequest factory with one that can create ConsumerRequest classes which use a client SSL certificate
            consumerSession.ConsumerRequestFactory = new DefaultConsumerRequestFactory(ClientSslCertificateFactory);


            // 1. Get a request token
            IToken requestToken;

            try
            {
                requestToken = consumerSession.GetRequestToken();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
                return;
            }

            Console.WriteLine("Request Token Key: {0}", requestToken.Token);
            Console.WriteLine("Request Token Secret: {0}", requestToken.TokenSecret);


            // 2. Get the user to log into Xero using the request token in the querystring
            //string authorisationUrl = Settings.Default.AuthoriseURI.AbsoluteUri + "?oauth_token=" + HttpUtility.UrlEncode(requestTokenKey);
            string authorisationUrl = consumerSession.GetUserAuthorizationUrlForToken(requestToken);
            Process.Start(authorisationUrl);

            // 3. Get the use to enter the authorisation code from Xero (4-7 digit number)
            Console.WriteLine("Please input the code you were given in Xero:");
            var verificationCode = Console.ReadLine();

            if (string.IsNullOrEmpty(verificationCode))
            {
                Console.WriteLine("You didn't type a verification code!");
                return;
            }

            verificationCode = verificationCode.Trim();


            // 4. Use the request token and verification code to get an access token
            AccessToken accessToken;

            try
            {
                accessToken = consumerSession.ExchangeRequestTokenForAccessToken(requestToken, verificationCode);
            }
            catch (OAuthException ex)
            {
                Console.WriteLine("An OAuthException was caught:");
                Console.WriteLine(ex.Report);
                return;
            }

            Console.WriteLine("Access Token Key: {0}", accessToken.Token);
            Console.WriteLine("Access Token Secret: {0}", accessToken.TokenSecret);


            // 5. Make a call to api-partner.network.xero.com to check that we can use the access token.
            IConsumerRequest getOrganisationRequest = consumerSession
                .Request()
                .ForMethod("GET")
                .ForUri(new Uri("https://api-partner.network.xero.com/api.xro/2.0/Organisation"))
                .SignWithToken(accessToken);

            string getOrganisationResponse = getOrganisationRequest.ToString();

            if (getOrganisationResponse != string.Empty)
            {
                XElement organisationXml = XElement.Parse(getOrganisationResponse);
                string organisationName = organisationXml.XPathSelectElement("//Organisation/Name").Value;
                Console.WriteLine(string.Format("You have been authorised against organisation: {0}", organisationName));
            }


            // 5.1 Refresh the access token using the session handle
            try
            {
                accessToken = consumerSession.RenewAccessToken(accessToken, accessToken.SessionHandle);

                Console.WriteLine("The access token has been refreshed");
                Console.WriteLine("New Access Token: " + accessToken.Token);
                Console.WriteLine("New Access Secret: " + accessToken.TokenSecret);
            }
            catch (Exception ex)
            {
                Console.WriteLine("The access token could not be refreshed:\r\n" + ex);
                return;
            }


            // 6. Make a PUT call to the API - add a dummy contact
            Console.WriteLine("Please enter the name of a new contact to add to Xero");
            string contactName = Console.ReadLine();

            if (string.IsNullOrEmpty(contactName))
            {
                return;
            }

            string putContactRequestBody = string.Format("<Contacts><Contact><Name>{0}</Name></Contact></Contacts>", contactName);
            string putContactResponse;

            IConsumerRequest putContactRequest = consumerSession
                .Request()
                .ForMethod("PUT")
                .ForUri(new Uri("https://api-partner.network.xero.com/api.xro/2.0/Contacts"))
                .WithFormParameters(new { xml = putContactRequestBody })
                .SignWithToken(accessToken);

            try
            {
                putContactResponse = putContactRequest.ToString();
            }
            catch (OAuthException ex)
            {
                Console.WriteLine("An OAuthException was caught:");
                Console.WriteLine(ex.Report);
                return;
            }
            catch (WebException ex)
            {
                putContactResponse = ex.Response.GetResponseStream().ReadToEnd();

                Console.WriteLine("A WebException was caught:");
                Console.WriteLine(putContactResponse);
                return;
            }

            if (putContactResponse != string.Empty)
            {
                var responseElement = XElement.Parse(putContactResponse);
                string statusCode = responseElement.XPathSelectElement("/Status").Value;

                if (statusCode == "OK")
                {
                    string contactId = responseElement.XPathSelectElement("/Contacts/Contact[1]/ContactID").Value;
                    Console.WriteLine(string.Format("The contact '{0}' was created with id: {1}", contactName, contactId));
                }
            }


            // 7. Try to update the contact that's just been created, but this time use a POST method
            string postContactRequestBody = string.Format("<Contacts><Contact><Name>{0}</Name><EmailAddress>{1}@nowhere.com</EmailAddress></Contact></Contacts>", contactName, contactName.ToLower().Replace(" ", "."));
            string postContactResponse;

            IConsumerRequest postContactRequest = consumerSession
                .Request()
                .ForMethod("POST")
                .ForUri(new Uri("https://api-partner.network.xero.com/api.xro/2.0/Contacts"))
                .WithFormParameters(new { xml = postContactRequestBody })
                .SignWithToken(accessToken);

            try
            {
                postContactResponse = postContactRequest.ToString();
            }
            catch (OAuthException ex)
            {
                Console.WriteLine("An OAuthException was caught:");
                Console.WriteLine(ex.Report);
                return;
            }
            catch (WebException ex)
            {
                putContactResponse = ex.Response.GetResponseStream().ReadToEnd();

                Console.WriteLine("A WebException was caught:");
                Console.WriteLine(putContactResponse);
                return;
            }

            if (postContactResponse != string.Empty)
            {
                var responseElement = XElement.Parse(postContactResponse);
                string statusCode = responseElement.XPathSelectElement("/Status").Value;

                if (statusCode == "OK")
                {
                    string emailAddress = responseElement.XPathSelectElement("/Contacts/Contact[1]/EmailAddress").Value;
                    Console.WriteLine(string.Format("The contact '{0}' was updated with email address: {1}", contactName, emailAddress));
                }
            }
        }