public static HashMap<String, String> requestTokenToAccessToken(String oauthToken, String oauthVerifier) throws TwitterException {

		String _numberUsedOnce = generateNumberUsedOnce();
		String _timeStamp= currentTimeInSeconds();

		String oauthSignature = null;

		// signature parameters
		HashMap<String, String> signatureParameters = new HashMap<String, String>();
		signatureParameters.put(OAH_CONSUMER_KEY, TwitterCredentials.TWITTER_LOGIN_CONSUMER_KEY);
		signatureParameters.put(OAH_NONCE, _numberUsedOnce);
		signatureParameters.put(OAH_TIMESTAMP, _timeStamp);
		// include token in signature parameters too
		signatureParameters.put(OAH_TOKEN, oauthToken);
		// include body parameter in the signature Parameters too
		signatureParameters.put(OAH_VERIFIER, oauthVerifier);

		// generate the signature
		try {
			// signing secret not known at this point
			oauthSignature = generateOauthSignature(signatureParameters, TWITTER_ACCESS_TOKEN_ENDPOINT,
					TwitterCredentials.TWITTER_LOGIN_CONSUMER_SECRET, null, METHOD_POST);
		} catch (Exception e) {
			throw new TwitterException(e);
		}

		// authorisation header parameters, excludes verifier parameter
		HashMap<String, String> authorisationParameters = new HashMap<String, String>();
		authorisationParameters.put(OAH_CONSUMER_KEY, TwitterCredentials.TWITTER_SERVICES_CONSUMER_KEY);
		authorisationParameters.put(OAH_NONCE, _numberUsedOnce);
		authorisationParameters.put(OAH_TIMESTAMP, _timeStamp);
		// include access token
		authorisationParameters.put(OAH_TOKEN, oauthToken);
		// exclude verifier, actually sent in the body
		String authHeader = generateOauthHeader(authorisationParameters, oauthSignature);
		
		// generate the request parameters and body
		HashMap<String, String> bodyParameters = new HashMap<String, String>();
		bodyParameters.put(OAH_VERIFIER, oauthVerifier);
		String requestBody = assembleRequestBody(bodyParameters);

		// make the HTTP request
		String responseBody = makeHttpRequest(TWITTER_ENDPOINT_HOST, TWITTER_ACCESS_TOKEN_ENDPOINT_PATH,
				authHeader, requestBody, METHOD_POST);
		logger.info(responseBody);

		// encode key/value pairs in a results map
		HashMap<String, String> result = new HashMap<String, String>();

		// parse the response
		StringTokenizer responseBodyTokenizer = new StringTokenizer(responseBody, AMPERSAND);
		// returns oauth_token, oauth_token_secret, user_id, and screen_name
		String keyValue = null;
		if (responseBodyTokenizer.countTokens() == 4) {
			while (responseBodyTokenizer.hasMoreTokens()) {
				keyValue = responseBodyTokenizer.nextToken();
				// split key and value
				StringTokenizer keyValueTokenizer = new StringTokenizer(keyValue, EQUALS);
				if (keyValueTokenizer.countTokens() == 2) {
					String key = keyValueTokenizer.nextToken();
					String value = keyValueTokenizer.nextToken();
					result.put(key, value);
				} else {
					logger.error(responseBody);
					throw new TwitterException("Response body has unexpected format");
				}
			}
		} else {
			logger.error(responseBody);
			throw new TwitterException("Response body has unexpected format");
		}

		// check the correct values present
		if (result.containsKey(OAH_TOKEN) && result.containsKey(OAH_TOKEN_SECRET) && result.containsKey(TWITTER_USER_ID)
				&& result.containsKey(TWITTER_SCREEN_NAME)) {
			return result;
		} else {
			logger.error(responseBody);
			throw new TwitterException("Response body missing expected values");
		}
	}