/** {@inheritDoc} */
  @Override
  public void logout(final AuthCallbacks.LogoutListener logoutListener) {
    SoomlaUtils.LogDebug(TAG, "logout");

    KeyValueStorage.deleteKeyValue(getTwitterStorageKey(TWITTER_OAUTH_TOKEN));
    KeyValueStorage.deleteKeyValue(getTwitterStorageKey(TWITTER_OAUTH_SECRET));

    mainRequestToken = null;

    twitter.setOAuthAccessToken(null);
    twitter.shutdown();

    logoutListener.success();
  }
  /** {@inheritDoc} */
  @Override
  public void updateStory(
      String message,
      String name,
      String caption,
      String description,
      String link,
      String picture,
      final SocialCallbacks.SocialActionListener socialActionListener) {
    if (!isInitialized) {
      return;
    }

    SoomlaUtils.LogDebug(TAG, "updateStory");

    RefProvider = getProvider();
    RefSocialActionListener = socialActionListener;

    preformingAction = ACTION_PUBLISH_STORY;

    try {
      twitter.updateStatus(message + " " + link);
    } catch (Exception e) {
      failListener(ACTION_PUBLISH_STORY, e.getMessage());
    }
  }
  /** {@inheritDoc} */
  @Override
  public boolean isLoggedIn() {
    SoomlaUtils.LogDebug(TAG, "isLoggedIn");

    try {
      return isInitialized && (twitter.getOAuthAccessToken() != null);
    } catch (Exception e) {
      return false;
    }
  }
  private UserProfile createUserProfile(User user, boolean withExtraFields) {
    String fullName = user.getName();
    String firstName = "";
    String lastName = "";

    if (!TextUtils.isEmpty(fullName)) {
      String[] splitName = fullName.split(" ");
      if (splitName.length > 0) {
        firstName = splitName[0];
        if (splitName.length > 1) {
          lastName = splitName[1];
        }
      }
    }
    Map<String, Object> extraDict = Collections.<String, Object>emptyMap();
    if (withExtraFields) {
      extraDict = new HashMap<String, Object>();
      // TwitterException will throws when Twitter service or network is unavailable, or the user
      // has not authorized
      try {
        extraDict.put("access_token", twitter.getOAuthAccessToken().getToken());
      } catch (TwitterException twitterExc) {
        SoomlaUtils.LogError(TAG, twitterExc.getErrorMessage());
      }
    }
    // Twitter does not supply email access: https://dev.twitter.com/faq#26
    UserProfile result =
        new UserProfile(
            RefProvider,
            String.valueOf(user.getId()),
            user.getScreenName(),
            "",
            firstName,
            lastName,
            extraDict);

    // No gender information on Twitter:
    // https://twittercommunity.com/t/how-to-find-male-female-accounts-in-following-list/7367
    result.setGender("");

    // No birthday on Twitter:
    // https://twittercommunity.com/t/how-can-i-get-email-of-user-if-i-use-api/7019/16
    result.setBirthday("");

    result.setLanguage(user.getLang());
    result.setLocation(user.getLocation());
    result.setAvatarLink(user.getBiggerProfileImageURL());

    return result;
  }
  /** {@inheritDoc} */
  @Override
  public void login(
      final Activity parentActivity, final AuthCallbacks.LoginListener loginListener) {
    if (!isInitialized) {
      SoomlaUtils.LogError(
          TAG, "Consumer key and secret were not defined, please provide them in initialization");
      return;
    }

    SoomlaUtils.LogDebug(TAG, "login");
    WeakRefParentActivity = new WeakReference<Activity>(parentActivity);

    RefProvider = getProvider();
    RefLoginListener = loginListener;

    preformingAction = ACTION_LOGIN;

    mainRequestToken = null;
    twitter.setOAuthAccessToken(null);

    // Try logging in using store credentials
    String oauthToken = KeyValueStorage.getValue(getTwitterStorageKey(TWITTER_OAUTH_TOKEN));
    String oauthTokenSecret = KeyValueStorage.getValue(getTwitterStorageKey(TWITTER_OAUTH_SECRET));
    if (!TextUtils.isEmpty(oauthToken) && !TextUtils.isEmpty(oauthTokenSecret)) {
      twitter.setOAuthAccessToken(new AccessToken(oauthToken, oauthTokenSecret));
      twitterScreenName = KeyValueStorage.getValue(getTwitterStorageKey(TWITTER_SCREEN_NAME));

      loginListener.success(RefProvider);

      clearListener(ACTION_LOGIN);
    } else {
      // If no stored credentials start login process by requesting
      // a request token
      twitter.getOAuthRequestTokenAsync(oauthCallbackURL);
    }
  }
  /** {@inheritDoc} */
  @Override
  public void getUserProfile(final AuthCallbacks.UserProfileListener userProfileListener) {
    if (!isInitialized) {
      return;
    }

    SoomlaUtils.LogDebug(TAG, "getUserProfile");

    RefProvider = getProvider();
    RefUserProfileListener = userProfileListener;

    preformingAction = ACTION_GET_USER_PROFILE;

    try {
      twitter.showUser(twitterScreenName);
    } catch (Exception e) {
      failListener(ACTION_GET_USER_PROFILE, e.getMessage());
    }
  }
    private void completeVerify(Uri uri) {
      SoomlaUtils.LogDebug(TAG, "Verification complete");
      /** Handle OAuth Callback */
      if (uri != null && uri.toString().startsWith(oauthCallbackURL)) {
        String verifier = uri.getQueryParameter(OAUTH_VERIFIER);
        if (!TextUtils.isEmpty(verifier)) {
          twitter.getOAuthAccessTokenAsync(mainRequestToken, verifier);
        } else {
          // Without a verifier an Access Token cannot be received
          // happens when a user clicks "cancel"
          cancelLogin();
        }
      }

      webView.hide();
      finish();

      mFinishedVerifying = true;
    }
  /** {@inheritDoc} */
  @Override
  public void updateStatus(
      String status, final SocialCallbacks.SocialActionListener socialActionListener) {
    if (!isInitialized) {
      return;
    }

    SoomlaUtils.LogDebug(TAG, "updateStatus");

    RefProvider = getProvider();
    RefSocialActionListener = socialActionListener;

    preformingAction = ACTION_PUBLISH_STATUS;

    try {
      twitter.updateStatus(status);
    } catch (Exception e) {
      failListener(ACTION_PUBLISH_STATUS, e.getMessage());
    }
  }
  /** {@inheritDoc} */
  @Override
  public void configure(Map<String, String> providerParams) {
    autoLogin = false;

    if (providerParams != null) {
      twitterConsumerKey = providerParams.get("consumerKey");
      twitterConsumerSecret = providerParams.get("consumerSecret");

      // extract autoLogin
      String autoLoginStr = providerParams.get("autoLogin");
      autoLogin = autoLoginStr != null && Boolean.parseBoolean(autoLoginStr);
    }

    SoomlaUtils.LogDebug(
        TAG,
        String.format(
            "ConsumerKey:%s ConsumerSecret:%s", twitterConsumerKey, twitterConsumerSecret));

    if (TextUtils.isEmpty(twitterConsumerKey) || TextUtils.isEmpty(twitterConsumerSecret)) {
      SoomlaUtils.LogError(
          TAG,
          "You must provide the Consumer Key and Secret in the SoomlaProfile initialization parameters");
      isInitialized = false;
    } else {
      isInitialized = true;
    }

    oauthCallbackURL = "oauth://soomla_twitter" + twitterConsumerKey;

    ConfigurationBuilder configurationBuilder = new ConfigurationBuilder();
    configurationBuilder.setOAuthConsumerKey(twitterConsumerKey);
    configurationBuilder.setOAuthConsumerSecret(twitterConsumerSecret);
    Configuration configuration = configurationBuilder.build();
    twitter = new AsyncTwitterFactory(configuration).getInstance();

    if (!actionsListenerAdded) {
      SoomlaUtils.LogWarning(TAG, "added action listener");
      twitter.addListener(actionsListener);
      actionsListenerAdded = true;
    }
  }
  /** {@inheritDoc} */
  @Override
  public void getContacts(
      boolean fromStart, final SocialCallbacks.ContactsListener contactsListener) {
    if (!isInitialized) {
      return;
    }

    SoomlaUtils.LogDebug(TAG, "getContacts");

    RefProvider = getProvider();
    RefContactsListener = contactsListener;

    preformingAction = ACTION_GET_USER_PROFILE;

    try {
      twitter.getFriendsList(twitterScreenName, fromStart ? -1 : this.lastContactCursor);
      this.lastContactCursor = -1;
    } catch (Exception e) {
      failListener(ACTION_GET_USER_PROFILE, e.getMessage());
    }
  }
        /**
         * Called when OAuth authentication has been finalized and an Access Token and Access Token
         * Secret have been provided
         *
         * @param accessToken The access token to use to do REST calls
         */
        @Override
        public void gotOAuthAccessToken(AccessToken accessToken) {
          SoomlaUtils.LogDebug(TAG, "login/onComplete");

          twitter.setOAuthAccessToken(accessToken);

          // Keep in storage for logging in without web-authentication
          KeyValueStorage.setValue(
              getTwitterStorageKey(TWITTER_OAUTH_TOKEN), accessToken.getToken());
          KeyValueStorage.setValue(
              getTwitterStorageKey(TWITTER_OAUTH_SECRET), accessToken.getTokenSecret());

          // Keep screen name since Twitter4J does not have it when
          // logging in using authenticated tokens
          KeyValueStorage.setValue(
              getTwitterStorageKey(TWITTER_SCREEN_NAME), accessToken.getScreenName());

          twitterScreenName = accessToken.getScreenName();

          RefLoginListener.success(RefProvider);

          clearListener(ACTION_LOGIN);
        }
  /** {@inheritDoc} */
  @Override
  public void uploadImage(
      String message,
      String filePath,
      final SocialCallbacks.SocialActionListener socialActionListener) {
    if (!isInitialized) {
      return;
    }

    SoomlaUtils.LogDebug(TAG, "uploadImage");

    RefProvider = getProvider();
    RefSocialActionListener = socialActionListener;

    preformingAction = ACTION_UPLOAD_IMAGE;

    try {
      StatusUpdate updateImage = new StatusUpdate(message);
      updateImage.media(new File(filePath));
      twitter.updateStatus(updateImage);
    } catch (Exception e) {
      failListener(ACTION_UPLOAD_IMAGE, e.getMessage());
    }
  }
  /** {@inheritDoc} */
  @Override
  public void getFeed(Boolean fromStart, final SocialCallbacks.FeedListener feedListener) {
    if (!isInitialized) {
      return;
    }

    SoomlaUtils.LogDebug(TAG, "getFeed");

    RefProvider = getProvider();
    RefFeedListener = feedListener;

    preformingAction = ACTION_GET_FEED;

    try {
      if (fromStart) {
        this.lastFeedCursor = 1;
      }

      Paging paging = new Paging(this.lastFeedCursor, PAGE_SIZE);
      twitter.getUserTimeline(paging);
    } catch (Exception e) {
      failListener(ACTION_GET_FEED, e.getMessage());
    }
  }