diff --git a/twidere.component.common/src/main/java/org/mariotaku/twidere/TwidereConstants.java b/twidere.component.common/src/main/java/org/mariotaku/twidere/TwidereConstants.java index 892e69d51..4182d4001 100644 --- a/twidere.component.common/src/main/java/org/mariotaku/twidere/TwidereConstants.java +++ b/twidere.component.common/src/main/java/org/mariotaku/twidere/TwidereConstants.java @@ -19,6 +19,8 @@ package org.mariotaku.twidere; +import android.content.ContentResolver; + import org.mariotaku.twidere.constant.IntentConstants; import org.mariotaku.twidere.constant.SharedPreferenceConstants; @@ -30,7 +32,6 @@ import org.mariotaku.twidere.constant.SharedPreferenceConstants; public interface TwidereConstants extends SharedPreferenceConstants, IntentConstants { String TWIDERE_APP_NAME = "Twidere"; - String TWIDERE_PACKAGE_NAME = "org.mariotaku.twidere"; String TWIDERE_PROJECT_URL = "https://github.com/mariotaku/twidere"; String TWIDERE_PROJECT_EMAIL = "twidere.project@gmail.com"; @@ -57,10 +58,9 @@ public interface TwidereConstants extends SharedPreferenceConstants, IntentConst String SCHEME_HTTP = "http"; String SCHEME_HTTPS = "https"; - String SCHEME_CONTENT = "content"; + String SCHEME_CONTENT = ContentResolver.SCHEME_CONTENT; String SCHEME_TWIDERE = "twidere"; String SCHEME_DATA = "data"; - String SCHEME_FILE = "file"; String PROTOCOL_HTTP = SCHEME_HTTP + "://"; String PROTOCOL_HTTPS = SCHEME_HTTPS + "://"; @@ -71,9 +71,6 @@ public interface TwidereConstants extends SharedPreferenceConstants, IntentConst String AUTHORITY_TWIDERE_CACHE = "twidere.cache"; String AUTHORITY_USER = "user"; - String AUTHORITY_HOME = "home"; - String AUTHORITY_MENTIONS = "mentions"; - String AUTHORITY_DIRECT_MESSAGES = "direct_messages"; String AUTHORITY_USERS = "users"; String AUTHORITY_USER_TIMELINE = "user_timeline"; String AUTHORITY_USER_MEDIA_TIMELINE = "user_media_timeline"; @@ -228,12 +225,6 @@ public interface TwidereConstants extends SharedPreferenceConstants, IntentConst String TASK_TAG_GET_TRENDS = "get_trends"; String TASK_TAG_STORE_TRENDS = "store_trends"; - String SERVICE_COMMAND_REFRESH_ALL = "refresh_all"; - String SERVICE_COMMAND_GET_HOME_TIMELINE = "get_home_timeline"; - String SERVICE_COMMAND_GET_MENTIONS = "get_mentions"; - String SERVICE_COMMAND_GET_SENT_DIRECT_MESSAGES = "get_sent_direct_messages"; - String SERVICE_COMMAND_GET_RECEIVED_DIRECT_MESSAGES = "get_received_direct_messages"; - String METADATA_KEY_EXTENSION = "org.mariotaku.twidere.extension"; String METADATA_KEY_EXTENSION_PERMISSIONS = "org.mariotaku.twidere.extension.permissions"; String METADATA_KEY_EXTENSION_SETTINGS = "org.mariotaku.twidere.extension.settings"; @@ -251,19 +242,6 @@ public interface TwidereConstants extends SharedPreferenceConstants, IntentConst String PERMISSION_ACCOUNTS = "accounts"; String PERMISSION_PREFERENCES = "preferences"; - String TAB_TYPE_HOME_TIMELINE = "home_timeline"; - String TAB_TYPE_NOTIFICATIONS_TIMELINE = "notifications_timeline"; - String TAB_TYPE_TRENDS_SUGGESTIONS = "trends_suggestions"; - String TAB_TYPE_DIRECT_MESSAGES = "direct_messages"; - String TAB_TYPE_FAVORITES = "favorites"; - String TAB_TYPE_USER_TIMELINE = "user_timeline"; - String TAB_TYPE_SEARCH_STATUSES = "search_statuses"; - String TAB_TYPE_LIST_TIMELINE = "list_timeline"; - String TAB_TYPE_ACTIVITIES_ABOUT_ME = "activities_about_me"; - String TAB_TYPE_ACTIVITIES_BY_FRIENDS = "activities_by_friends"; - String TAB_TYPE_RETWEETS_OF_ME = "retweets_of_me"; - - int TAB_CODE_HOME_TIMELINE = 1; int TAB_CODE_NOTIFICATIONS_TIMELINE = 2; int TAB_CODE_DIRECT_MESSAGES = 4; diff --git a/twidere.component.common/src/main/java/org/mariotaku/twidere/api/twitter/auth/OAuthToken.java b/twidere.component.common/src/main/java/org/mariotaku/twidere/api/twitter/auth/OAuthToken.java index f5a2d6b08..de768c697 100644 --- a/twidere.component.common/src/main/java/org/mariotaku/twidere/api/twitter/auth/OAuthToken.java +++ b/twidere.component.common/src/main/java/org/mariotaku/twidere/api/twitter/auth/OAuthToken.java @@ -30,7 +30,6 @@ import org.mariotaku.twidere.api.twitter.TwitterException; import java.io.ByteArrayOutputStream; import java.io.IOException; -import java.lang.reflect.Type; import java.nio.charset.Charset; import java.text.ParseException; diff --git a/twidere.component.common/src/main/java/org/mariotaku/twidere/api/twitter/model/CreateCardData.java b/twidere.component.common/src/main/java/org/mariotaku/twidere/api/twitter/model/CreateCardData.java index f214ceb19..d008dcad0 100644 --- a/twidere.component.common/src/main/java/org/mariotaku/twidere/api/twitter/model/CreateCardData.java +++ b/twidere.component.common/src/main/java/org/mariotaku/twidere/api/twitter/model/CreateCardData.java @@ -19,12 +19,6 @@ package org.mariotaku.twidere.api.twitter.model; -import com.bluelinelabs.logansquare.LoganSquare; - -import java.io.IOException; -import java.util.LinkedHashMap; -import java.util.Map; - /** * Example *
diff --git a/twidere.component.common/src/main/java/org/mariotaku/twidere/api/twitter/model/GeoQuery.java b/twidere.component.common/src/main/java/org/mariotaku/twidere/api/twitter/model/GeoQuery.java
index 3c28150e3..16d11fb2a 100644
--- a/twidere.component.common/src/main/java/org/mariotaku/twidere/api/twitter/model/GeoQuery.java
+++ b/twidere.component.common/src/main/java/org/mariotaku/twidere/api/twitter/model/GeoQuery.java
@@ -39,7 +39,7 @@ public final class GeoQuery implements ValueMap {
     /**
      * Creates a GeoQuery with the specified location
      *
-     * @param location
+     * @param location Query location
      */
     public GeoQuery(final GeoLocation location) {
         this.location = location;
diff --git a/twidere.component.common/src/main/java/org/mariotaku/twidere/api/twitter/model/MediaEntity.java b/twidere.component.common/src/main/java/org/mariotaku/twidere/api/twitter/model/MediaEntity.java
index 3d29f0ede..2ae979af6 100644
--- a/twidere.component.common/src/main/java/org/mariotaku/twidere/api/twitter/model/MediaEntity.java
+++ b/twidere.component.common/src/main/java/org/mariotaku/twidere/api/twitter/model/MediaEntity.java
@@ -22,8 +22,6 @@ package org.mariotaku.twidere.api.twitter.model;
 import com.bluelinelabs.logansquare.annotation.JsonField;
 import com.bluelinelabs.logansquare.annotation.JsonObject;
 
-import org.mariotaku.twidere.api.gnusocial.model.Attachment;
-
 import java.util.Arrays;
 import java.util.HashMap;
 import java.util.Map;
diff --git a/twidere.component.common/src/main/java/org/mariotaku/twidere/api/twitter/model/TimeZone.java b/twidere.component.common/src/main/java/org/mariotaku/twidere/api/twitter/model/TimeZone.java
index b4ba5d25d..72682deb6 100644
--- a/twidere.component.common/src/main/java/org/mariotaku/twidere/api/twitter/model/TimeZone.java
+++ b/twidere.component.common/src/main/java/org/mariotaku/twidere/api/twitter/model/TimeZone.java
@@ -22,8 +22,6 @@ package org.mariotaku.twidere.api.twitter.model;
 import com.bluelinelabs.logansquare.annotation.JsonField;
 import com.bluelinelabs.logansquare.annotation.JsonObject;
 
-import org.mariotaku.twidere.api.twitter.model.TimeZone;
-
 /**
  * Created by mariotaku on 15/5/13.
  */
diff --git a/twidere.component.common/src/main/java/org/mariotaku/twidere/api/twitter/model/Warning.java b/twidere.component.common/src/main/java/org/mariotaku/twidere/api/twitter/model/Warning.java
index dc64ffc65..1f9ad90e8 100644
--- a/twidere.component.common/src/main/java/org/mariotaku/twidere/api/twitter/model/Warning.java
+++ b/twidere.component.common/src/main/java/org/mariotaku/twidere/api/twitter/model/Warning.java
@@ -21,8 +21,6 @@ package org.mariotaku.twidere.api.twitter.model;
 
 import com.bluelinelabs.logansquare.annotation.JsonObject;
 
-import org.mariotaku.twidere.api.twitter.model.Warning;
-
 /**
  * Created by mariotaku on 15/5/26.
  */
diff --git a/twidere.component.common/src/main/java/org/mariotaku/twidere/model/ParcelableAccount.java b/twidere.component.common/src/main/java/org/mariotaku/twidere/model/ParcelableAccount.java
index 2d4a3db53..a0d83f361 100644
--- a/twidere.component.common/src/main/java/org/mariotaku/twidere/model/ParcelableAccount.java
+++ b/twidere.component.common/src/main/java/org/mariotaku/twidere/model/ParcelableAccount.java
@@ -199,13 +199,17 @@ public class ParcelableAccount implements Parcelable {
 
     public static ParcelableCredentials getCredentials(final Context context, final long accountId) {
         if (context == null) return null;
-        try (Cursor cur = ContentResolverUtils.query(context.getContentResolver(), Accounts.CONTENT_URI,
-                Accounts.COLUMNS, Accounts.ACCOUNT_ID + " = " + accountId, null, null)) {
-            if (cur != null && cur.moveToFirst()) {
+        Cursor cur = ContentResolverUtils.query(context.getContentResolver(), Accounts.CONTENT_URI,
+                Accounts.COLUMNS, Accounts.ACCOUNT_ID + " = " + accountId, null, null);
+        if (cur == null) return null;
+        try {
+            if (cur.moveToFirst()) {
                 return ParcelableCredentialsCursorIndices.fromCursor(cur);
             }
-            return null;
+        } finally {
+            cur.close();
         }
+        return null;
     }
 
     public static List getCredentialsList(final Context context, final boolean activatedOnly) {
diff --git a/twidere.component.common/src/main/java/org/mariotaku/twidere/model/ParcelableStatus.java b/twidere.component.common/src/main/java/org/mariotaku/twidere/model/ParcelableStatus.java
index e6f2bb544..b09ec3d41 100644
--- a/twidere.component.common/src/main/java/org/mariotaku/twidere/model/ParcelableStatus.java
+++ b/twidere.component.common/src/main/java/org/mariotaku/twidere/model/ParcelableStatus.java
@@ -44,7 +44,6 @@ import org.mariotaku.twidere.util.HtmlEscapeHelper;
 import org.mariotaku.twidere.util.TwitterContentUtils;
 
 import java.io.IOException;
-import java.util.Arrays;
 import java.util.Comparator;
 import java.util.Date;
 
diff --git a/twidere.component.common/src/main/java/org/mariotaku/twidere/model/ParcelableUserList.java b/twidere.component.common/src/main/java/org/mariotaku/twidere/model/ParcelableUserList.java
index d5f2a4439..d8dfedbfe 100644
--- a/twidere.component.common/src/main/java/org/mariotaku/twidere/model/ParcelableUserList.java
+++ b/twidere.component.common/src/main/java/org/mariotaku/twidere/model/ParcelableUserList.java
@@ -108,7 +108,7 @@ public class ParcelableUserList implements Parcelable, Comparable grabLinks(final String html) {
-        final Vector result = new Vector();
+        final Vector result = new Vector<>();
         final Matcher matcherTag = patternTag.matcher(html);
         while (matcherTag.find()) {
             final String href = matcherTag.group(1); // href
diff --git a/twidere.component.common/src/main/java/org/mariotaku/twidere/util/ParseUtils.java b/twidere.component.common/src/main/java/org/mariotaku/twidere/util/ParseUtils.java
index 4bf20acaf..c6cda19a2 100644
--- a/twidere.component.common/src/main/java/org/mariotaku/twidere/util/ParseUtils.java
+++ b/twidere.component.common/src/main/java/org/mariotaku/twidere/util/ParseUtils.java
@@ -32,10 +32,6 @@ import org.mariotaku.twidere.constant.IntentConstants;
 
 import java.io.IOException;
 import java.io.StringWriter;
-import java.net.MalformedURLException;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.net.URL;
 import java.util.Iterator;
 import java.util.Locale;
 import java.util.Set;
diff --git a/twidere.component.common/src/main/java/org/mariotaku/twidere/util/TwidereArrayUtils.java b/twidere.component.common/src/main/java/org/mariotaku/twidere/util/TwidereArrayUtils.java
index 9320ee065..728327495 100644
--- a/twidere.component.common/src/main/java/org/mariotaku/twidere/util/TwidereArrayUtils.java
+++ b/twidere.component.common/src/main/java/org/mariotaku/twidere/util/TwidereArrayUtils.java
@@ -46,8 +46,8 @@ public final class TwidereArrayUtils {
         if (array1 == null || array2 == null) return array1 == array2;
         if (array1.length != array2.length) return false;
         final int length = array1.length;
-        for (int i = 0; i < length; i++) {
-            if (!ArrayUtils.contains(array2, array1[i])) return false;
+        for (long anArray1 : array1) {
+            if (!ArrayUtils.contains(array2, anArray1)) return false;
         }
         return true;
     }
@@ -55,9 +55,8 @@ public final class TwidereArrayUtils {
     public static boolean contentMatch(final Object[] array1, final Object[] array2) {
         if (array1 == null || array2 == null) return array1 == array2;
         if (array1.length != array2.length) return false;
-        final int length = array1.length;
-        for (int i = 0; i < length; i++) {
-            if (!ArrayUtils.contains(array2, array1[i])) return false;
+        for (Object item : array1) {
+            if (!ArrayUtils.contains(array2, item)) return false;
         }
         return true;
     }
@@ -75,11 +74,11 @@ public final class TwidereArrayUtils {
 
     public static long[] intersection(final long[] array1, final long[] array2) {
         if (array1 == null || array2 == null) return new long[0];
-        final List list1 = new ArrayList();
+        final List list1 = new ArrayList<>();
         for (final long item : array1) {
             list1.add(item);
         }
-        final List list2 = new ArrayList();
+        final List list2 = new ArrayList<>();
         for (final long item : array2) {
             list2.add(item);
         }
diff --git a/twidere.component.common/src/main/java/org/mariotaku/twidere/util/media/preview/provider/TwitterPicProvider.java b/twidere.component.common/src/main/java/org/mariotaku/twidere/util/media/preview/provider/TwitterPicProvider.java
index 82811c10a..92ab04da3 100644
--- a/twidere.component.common/src/main/java/org/mariotaku/twidere/util/media/preview/provider/TwitterPicProvider.java
+++ b/twidere.component.common/src/main/java/org/mariotaku/twidere/util/media/preview/provider/TwitterPicProvider.java
@@ -8,7 +8,6 @@ import org.mariotaku.restfu.http.RestHttpClient;
 import org.mariotaku.twidere.model.ParcelableMedia;
 import org.mariotaku.twidere.util.media.preview.PreviewMediaExtractor;
 
-import java.util.List;
 import java.util.Locale;
 
 /**
diff --git a/twidere.component.nyan/src/main/java/org/mariotaku/twidere/nyan/NyanDrawingHelper.java b/twidere.component.nyan/src/main/java/org/mariotaku/twidere/nyan/NyanDrawingHelper.java
index 69fd360cc..a3582079b 100644
--- a/twidere.component.nyan/src/main/java/org/mariotaku/twidere/nyan/NyanDrawingHelper.java
+++ b/twidere.component.nyan/src/main/java/org/mariotaku/twidere/nyan/NyanDrawingHelper.java
@@ -294,7 +294,7 @@ public class NyanDrawingHelper {
 
         private final Paint mPaint;
 
-        private final ArrayList mStars = new ArrayList();
+        private final ArrayList mStars = new ArrayList<>();
 
         private final Random mRandom = new Random();
 
diff --git a/twidere/src/main/java/org/mariotaku/twidere/Constants.java b/twidere/src/main/java/org/mariotaku/twidere/Constants.java
index 180f9110e..d18fe2136 100644
--- a/twidere/src/main/java/org/mariotaku/twidere/Constants.java
+++ b/twidere/src/main/java/org/mariotaku/twidere/Constants.java
@@ -105,5 +105,4 @@ public interface Constants extends TwidereConstants {
     @Preference(type = STRING, exportable = false)
     String KEY_DEVICE_SERIAL = "device_serial";
 
-    String READ_POSITION_TAG_ACTIVITIES_ABOUT_ME = "activities_about_me";
 }
diff --git a/twidere/src/main/java/org/mariotaku/twidere/activity/ImageCropperActivity.java b/twidere/src/main/java/org/mariotaku/twidere/activity/ImageCropperActivity.java
index dbae37a6f..53d5f9206 100644
--- a/twidere/src/main/java/org/mariotaku/twidere/activity/ImageCropperActivity.java
+++ b/twidere/src/main/java/org/mariotaku/twidere/activity/ImageCropperActivity.java
@@ -23,9 +23,7 @@ import android.content.res.Resources;
 import android.os.Build;
 import android.os.Bundle;
 import android.support.annotation.NonNull;
-import android.support.v4.view.MarginLayoutParamsCompat;
 import android.support.v4.view.ViewCompat;
-import android.support.v4.view.WindowCompat;
 import android.view.View;
 import android.view.WindowManager;
 
diff --git a/twidere/src/main/java/org/mariotaku/twidere/activity/NyanActivity.java b/twidere/src/main/java/org/mariotaku/twidere/activity/NyanActivity.java
index 5afc78b32..d7a6133b9 100644
--- a/twidere/src/main/java/org/mariotaku/twidere/activity/NyanActivity.java
+++ b/twidere/src/main/java/org/mariotaku/twidere/activity/NyanActivity.java
@@ -38,7 +38,6 @@ import org.mariotaku.twidere.R;
 import org.mariotaku.twidere.nyan.NyanDaydreamService;
 import org.mariotaku.twidere.nyan.NyanSurfaceHelper;
 import org.mariotaku.twidere.nyan.NyanWallpaperService;
-import org.mariotaku.twidere.util.DebugModeUtils;
 
 public class NyanActivity extends Activity implements Constants, OnLongClickListener, OnSharedPreferenceChangeListener {
 
diff --git a/twidere/src/main/java/org/mariotaku/twidere/activity/SettingsWizardActivity.java b/twidere/src/main/java/org/mariotaku/twidere/activity/SettingsWizardActivity.java
index 0f45fc1db..79d50bb6d 100644
--- a/twidere/src/main/java/org/mariotaku/twidere/activity/SettingsWizardActivity.java
+++ b/twidere/src/main/java/org/mariotaku/twidere/activity/SettingsWizardActivity.java
@@ -50,6 +50,7 @@ import org.mariotaku.twidere.R;
 import org.mariotaku.twidere.activity.support.DataImportActivity;
 import org.mariotaku.twidere.activity.support.HomeActivity;
 import org.mariotaku.twidere.adapter.TabsAdapter;
+import org.mariotaku.twidere.annotation.CustomTabType;
 import org.mariotaku.twidere.fragment.BaseDialogFragment;
 import org.mariotaku.twidere.fragment.BaseFragment;
 import org.mariotaku.twidere.fragment.BasePreferenceFragment;
@@ -536,9 +537,9 @@ public class SettingsWizardActivity extends Activity implements Constants {
 
         private static final String FRAGMENT_TAG = "initial_settings_dialog";
 
-        private static final String[] DEFAULT_TAB_TYPES = {TAB_TYPE_HOME_TIMELINE,
-                TAB_TYPE_NOTIFICATIONS_TIMELINE, TAB_TYPE_TRENDS_SUGGESTIONS,
-                TAB_TYPE_DIRECT_MESSAGES};
+        private static final String[] DEFAULT_TAB_TYPES = {CustomTabType.HOME_TIMELINE,
+                CustomTabType.NOTIFICATIONS_TIMELINE, CustomTabType.TRENDS_SUGGESTIONS,
+                CustomTabType.DIRECT_MESSAGES};
 
         private final SettingsWizardActivity mActivity;
 
diff --git a/twidere/src/main/java/org/mariotaku/twidere/activity/support/BrowserSignInActivity.java b/twidere/src/main/java/org/mariotaku/twidere/activity/support/BrowserSignInActivity.java
index 03d3af41b..4ab7431ef 100644
--- a/twidere/src/main/java/org/mariotaku/twidere/activity/support/BrowserSignInActivity.java
+++ b/twidere/src/main/java/org/mariotaku/twidere/activity/support/BrowserSignInActivity.java
@@ -41,7 +41,6 @@ import android.webkit.WebViewClient;
 import android.widget.Toast;
 
 import org.attoparser.AttoParseException;
-import org.mariotaku.restfu.Pair;
 import org.mariotaku.restfu.http.Authorization;
 import org.mariotaku.twidere.R;
 import org.mariotaku.twidere.api.twitter.TwitterOAuth;
diff --git a/twidere/src/main/java/org/mariotaku/twidere/activity/support/HomeActivity.java b/twidere/src/main/java/org/mariotaku/twidere/activity/support/HomeActivity.java
index 89fa45f3d..16b47baaa 100644
--- a/twidere/src/main/java/org/mariotaku/twidere/activity/support/HomeActivity.java
+++ b/twidere/src/main/java/org/mariotaku/twidere/activity/support/HomeActivity.java
@@ -45,6 +45,7 @@ import android.support.v4.view.ViewPager.OnPageChangeListener;
 import android.support.v4.widget.DrawerLayout;
 import android.support.v4.widget.DrawerLayoutAccessor;
 import android.support.v7.widget.Toolbar;
+import android.util.SparseIntArray;
 import android.view.Gravity;
 import android.view.KeyEvent;
 import android.view.MenuItem;
@@ -71,6 +72,7 @@ import org.mariotaku.twidere.activity.SettingsActivity;
 import org.mariotaku.twidere.activity.SettingsWizardActivity;
 import org.mariotaku.twidere.activity.UsageStatisticsActivity;
 import org.mariotaku.twidere.adapter.support.SupportTabsAdapter;
+import org.mariotaku.twidere.annotation.CustomTabType;
 import org.mariotaku.twidere.fragment.CustomTabsFragment;
 import org.mariotaku.twidere.fragment.iface.RefreshScrollTopInterface;
 import org.mariotaku.twidere.fragment.iface.SupportFragmentCallback;
@@ -107,10 +109,7 @@ import org.mariotaku.twidere.view.TintedStatusFrameLayout;
 import org.mariotaku.twidere.view.iface.IHomeActionButton;
 
 import java.util.Collections;
-import java.util.HashMap;
 import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
 
 import static org.mariotaku.twidere.util.CompareUtils.classEquals;
 import static org.mariotaku.twidere.util.Utils.cleanDatabasesByItemLimit;
@@ -723,8 +722,6 @@ public class HomeActivity extends BaseAppCompatActivity implements OnClickListen
                 }
             }
         }
-        if (initialTab != -1 && mViewPager != null) {
-        }
         final Intent extraIntent = intent.getParcelableExtra(EXTRA_EXTRA_INTENT);
         if (extraIntent != null && firstCreate) {
             extraIntent.setExtrasClassLoader(getClassLoader());
@@ -924,13 +921,14 @@ public class HomeActivity extends BaseAppCompatActivity implements OnClickListen
         }
     }
 
-    private static class UpdateUnreadCountTask extends AsyncTask> {
+    private static class UpdateUnreadCountTask extends AsyncTask {
         private final Context mContext;
         private final ReadStateManager mReadStateManager;
         private final TabPagerIndicator mIndicator;
         private final List mTabs;
 
-        UpdateUnreadCountTask(final Context context, final ReadStateManager manager, final TabPagerIndicator indicator, final List tabs) {
+        UpdateUnreadCountTask(final Context context, final ReadStateManager manager,
+                              final TabPagerIndicator indicator, final List tabs) {
             mContext = context;
             mReadStateManager = manager;
             mIndicator = indicator;
@@ -938,25 +936,30 @@ public class HomeActivity extends BaseAppCompatActivity implements OnClickListen
         }
 
         @Override
-        protected Map doInBackground(final Object... params) {
-            final Map result = new HashMap<>();
+        protected SparseIntArray doInBackground(final Object... params) {
+            final SparseIntArray result = new SparseIntArray();
             for (SupportTabSpec spec : mTabs) {
+                if (spec.type == null) continue;
                 switch (spec.type) {
-                    case TAB_TYPE_HOME_TIMELINE: {
+                    case CustomTabType.HOME_TIMELINE: {
                         final long[] accountIds = Utils.getAccountIds(spec.args);
-                        final String tagWithAccounts = Utils.getReadPositionTagWithAccounts(mContext, true, spec.tag, accountIds);
+                        final String tagWithAccounts = Utils.getReadPositionTagWithAccounts(mContext,
+                                true, spec.tag, accountIds);
                         final long position = mReadStateManager.getPosition(tagWithAccounts);
-                        result.put(spec, DataStoreUtils.getStatusesCount(mContext, Statuses.CONTENT_URI, position, accountIds));
+                        result.put(spec.position, DataStoreUtils.getStatusesCount(mContext,
+                                Statuses.CONTENT_URI, position, accountIds));
                         break;
                     }
-                    case TAB_TYPE_ACTIVITIES_ABOUT_ME: {
+                    case CustomTabType.NOTIFICATIONS_TIMELINE: {
                         final long[] accountIds = Utils.getAccountIds(spec.args);
-                        final String tagWithAccounts = Utils.getReadPositionTagWithAccounts(mContext, true, spec.tag, accountIds);
+                        final String tagWithAccounts = Utils.getReadPositionTagWithAccounts(mContext,
+                                true, spec.tag, accountIds);
                         final long position = mReadStateManager.getPosition(tagWithAccounts);
-                        result.put(spec, DataStoreUtils.getActivitiesCount(mContext, Activities.AboutMe.CONTENT_URI, position, accountIds));
+                        result.put(spec.position, DataStoreUtils.getActivitiesCount(mContext,
+                                Activities.AboutMe.CONTENT_URI, position, accountIds));
                         break;
                     }
-                    case TAB_TYPE_DIRECT_MESSAGES: {
+                    case CustomTabType.DIRECT_MESSAGES: {
                         break;
                     }
                 }
@@ -965,11 +968,10 @@ public class HomeActivity extends BaseAppCompatActivity implements OnClickListen
         }
 
         @Override
-        protected void onPostExecute(final Map result) {
+        protected void onPostExecute(final SparseIntArray result) {
             mIndicator.clearBadge();
-            for (Entry entry : result.entrySet()) {
-                final SupportTabSpec key = entry.getKey();
-                mIndicator.setBadge(key.position, entry.getValue());
+            for (int i = 0, j = result.size(); i < j; i++) {
+                mIndicator.setBadge(result.keyAt(i), result.valueAt(i));
             }
         }
 
diff --git a/twidere/src/main/java/org/mariotaku/twidere/activity/support/RequestPermissionsActivity.java b/twidere/src/main/java/org/mariotaku/twidere/activity/support/RequestPermissionsActivity.java
index 7568c6d95..1c35ee482 100644
--- a/twidere/src/main/java/org/mariotaku/twidere/activity/support/RequestPermissionsActivity.java
+++ b/twidere/src/main/java/org/mariotaku/twidere/activity/support/RequestPermissionsActivity.java
@@ -23,7 +23,6 @@ import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.os.Bundle;
-import android.text.Html;
 import android.view.View;
 import android.view.View.OnClickListener;
 import android.view.Window;
diff --git a/twidere/src/main/java/org/mariotaku/twidere/activity/support/ThemedAppCompatActivity.java b/twidere/src/main/java/org/mariotaku/twidere/activity/support/ThemedAppCompatActivity.java
index f0bcfdc94..f7f9accd5 100644
--- a/twidere/src/main/java/org/mariotaku/twidere/activity/support/ThemedAppCompatActivity.java
+++ b/twidere/src/main/java/org/mariotaku/twidere/activity/support/ThemedAppCompatActivity.java
@@ -32,7 +32,6 @@ import org.mariotaku.twidere.BuildConfig;
 import org.mariotaku.twidere.Constants;
 import org.mariotaku.twidere.activity.iface.IAppCompatActivity;
 import org.mariotaku.twidere.activity.iface.IThemedActivity;
-import org.mariotaku.twidere.util.DebugModeUtils;
 import org.mariotaku.twidere.util.StrictModeUtils;
 import org.mariotaku.twidere.util.ThemeUtils;
 import org.mariotaku.twidere.util.Utils;
diff --git a/twidere/src/main/java/org/mariotaku/twidere/activity/support/ThemedFragmentActivity.java b/twidere/src/main/java/org/mariotaku/twidere/activity/support/ThemedFragmentActivity.java
index 6914fbaa0..fd021c166 100644
--- a/twidere/src/main/java/org/mariotaku/twidere/activity/support/ThemedFragmentActivity.java
+++ b/twidere/src/main/java/org/mariotaku/twidere/activity/support/ThemedFragmentActivity.java
@@ -36,7 +36,6 @@ import org.mariotaku.twidere.Constants;
 import org.mariotaku.twidere.activity.iface.IThemedActivity;
 import org.mariotaku.twidere.util.ActivityTracker;
 import org.mariotaku.twidere.util.AsyncTwitterWrapper;
-import org.mariotaku.twidere.util.DebugModeUtils;
 import org.mariotaku.twidere.util.KeyboardShortcutsHandler;
 import org.mariotaku.twidere.util.KeyboardShortcutsHandler.KeyboardShortcutCallback;
 import org.mariotaku.twidere.util.MediaLoaderWrapper;
diff --git a/twidere/src/main/java/org/mariotaku/twidere/adapter/AbsUserListsAdapter.java b/twidere/src/main/java/org/mariotaku/twidere/adapter/AbsUserListsAdapter.java
index cf001d36d..a241aac5e 100644
--- a/twidere/src/main/java/org/mariotaku/twidere/adapter/AbsUserListsAdapter.java
+++ b/twidere/src/main/java/org/mariotaku/twidere/adapter/AbsUserListsAdapter.java
@@ -20,7 +20,6 @@
 package org.mariotaku.twidere.adapter;
 
 import android.content.Context;
-import android.support.annotation.NonNull;
 import android.support.v7.widget.CardView;
 import android.support.v7.widget.RecyclerView.ViewHolder;
 import android.view.LayoutInflater;
@@ -30,10 +29,7 @@ import android.view.ViewGroup;
 import org.mariotaku.twidere.Constants;
 import org.mariotaku.twidere.R;
 import org.mariotaku.twidere.adapter.iface.IUserListsAdapter;
-import org.mariotaku.twidere.util.AsyncTwitterWrapper;
-import org.mariotaku.twidere.util.MediaLoaderWrapper;
 import org.mariotaku.twidere.util.ThemeUtils;
-import org.mariotaku.twidere.util.UserColorNameManager;
 import org.mariotaku.twidere.util.Utils;
 import org.mariotaku.twidere.view.holder.LoadIndicatorViewHolder;
 import org.mariotaku.twidere.view.holder.UserListViewHolder;
diff --git a/twidere/src/main/java/org/mariotaku/twidere/adapter/MessageEntriesAdapter.java b/twidere/src/main/java/org/mariotaku/twidere/adapter/MessageEntriesAdapter.java
index 892861903..86d09c071 100644
--- a/twidere/src/main/java/org/mariotaku/twidere/adapter/MessageEntriesAdapter.java
+++ b/twidere/src/main/java/org/mariotaku/twidere/adapter/MessageEntriesAdapter.java
@@ -32,6 +32,7 @@ import android.view.ViewGroup;
 import org.mariotaku.twidere.Constants;
 import org.mariotaku.twidere.R;
 import org.mariotaku.twidere.adapter.iface.IContentCardAdapter;
+import org.mariotaku.twidere.annotation.CustomTabType;
 import org.mariotaku.twidere.model.StringLongPair;
 import org.mariotaku.twidere.provider.TwidereDataStore.DirectMessages.ConversationEntries;
 import org.mariotaku.twidere.util.ReadStateManager.OnReadStateChangeListener;
@@ -182,7 +183,7 @@ public class MessageEntriesAdapter extends LoadMoreSupportAdapter im
     }
 
     public void updateReadState() {
-        mPositionPairs = mReadStateManager.getPositionPairs(TAB_TYPE_DIRECT_MESSAGES);
+        mPositionPairs = mReadStateManager.getPositionPairs(CustomTabType.DIRECT_MESSAGES);
         notifyDataSetChanged();
     }
 
diff --git a/twidere/src/main/java/org/mariotaku/twidere/adapter/iface/IStatusesAdapter.java b/twidere/src/main/java/org/mariotaku/twidere/adapter/iface/IStatusesAdapter.java
index 28069eff7..b0a293aec 100644
--- a/twidere/src/main/java/org/mariotaku/twidere/adapter/iface/IStatusesAdapter.java
+++ b/twidere/src/main/java/org/mariotaku/twidere/adapter/iface/IStatusesAdapter.java
@@ -7,7 +7,6 @@ import org.mariotaku.twidere.model.ParcelableMedia;
 import org.mariotaku.twidere.model.ParcelableStatus;
 import org.mariotaku.twidere.util.MediaLoadingHandler;
 import org.mariotaku.twidere.util.TwidereLinkify;
-import org.mariotaku.twidere.view.CardMediaContainer;
 import org.mariotaku.twidere.view.CardMediaContainer.PreviewStyle;
 import org.mariotaku.twidere.view.holder.GapViewHolder;
 import org.mariotaku.twidere.view.holder.iface.IStatusViewHolder;
diff --git a/twidere/src/main/java/org/mariotaku/twidere/annotation/CustomTabType.java b/twidere/src/main/java/org/mariotaku/twidere/annotation/CustomTabType.java
new file mode 100644
index 000000000..4e2cd0bea
--- /dev/null
+++ b/twidere/src/main/java/org/mariotaku/twidere/annotation/CustomTabType.java
@@ -0,0 +1,31 @@
+package org.mariotaku.twidere.annotation;
+
+import android.support.annotation.StringDef;
+
+/**
+ * Created by mariotaku on 16/1/28.
+ */
+@StringDef({
+        CustomTabType.HOME_TIMELINE,
+        CustomTabType.NOTIFICATIONS_TIMELINE,
+        CustomTabType.TRENDS_SUGGESTIONS,
+        CustomTabType.DIRECT_MESSAGES,
+        CustomTabType.FAVORITES,
+        CustomTabType.USER_TIMELINE,
+        CustomTabType.SEARCH_STATUSES,
+        CustomTabType.LIST_TIMELINE,
+        CustomTabType.ACTIVITIES_BY_FRIENDS,
+        CustomTabType.RETWEETS_OF_ME,
+})
+public @interface CustomTabType {
+    String HOME_TIMELINE = "home_timeline";
+    String NOTIFICATIONS_TIMELINE = "notifications_timeline";
+    String TRENDS_SUGGESTIONS = "trends_suggestions";
+    String DIRECT_MESSAGES = "direct_messages";
+    String FAVORITES = "favorites";
+    String USER_TIMELINE = "user_timeline";
+    String SEARCH_STATUSES = "search_statuses";
+    String LIST_TIMELINE = "list_timeline";
+    String ACTIVITIES_BY_FRIENDS = "activities_by_friends";
+    String RETWEETS_OF_ME = "retweets_of_me";
+}
diff --git a/twidere/src/main/java/org/mariotaku/twidere/annotation/NotificationType.java b/twidere/src/main/java/org/mariotaku/twidere/annotation/NotificationType.java
new file mode 100644
index 000000000..ee852cafe
--- /dev/null
+++ b/twidere/src/main/java/org/mariotaku/twidere/annotation/NotificationType.java
@@ -0,0 +1,20 @@
+package org.mariotaku.twidere.annotation;
+
+import android.support.annotation.StringDef;
+
+/**
+ * Created by mariotaku on 16/1/28.
+ */
+@StringDef({
+        NotificationType.INTERACTIONS,
+        NotificationType.HOME_TIMELINE,
+        NotificationType.DIRECT_MESSAGES
+})
+public @interface NotificationType {
+    @NotificationType
+    String INTERACTIONS = "interactions";
+    @NotificationType
+    String HOME_TIMELINE = "home_timeline";
+    @NotificationType
+    String DIRECT_MESSAGES = "direct_messages";
+}
diff --git a/twidere/src/main/java/org/mariotaku/twidere/annotation/ReadPositionTag.java b/twidere/src/main/java/org/mariotaku/twidere/annotation/ReadPositionTag.java
new file mode 100644
index 000000000..476c1519c
--- /dev/null
+++ b/twidere/src/main/java/org/mariotaku/twidere/annotation/ReadPositionTag.java
@@ -0,0 +1,17 @@
+package org.mariotaku.twidere.annotation;
+
+import android.support.annotation.StringDef;
+
+/**
+ * Created by mariotaku on 16/1/28.
+ */
+@StringDef({
+        ReadPositionTag.ACTIVITIES_ABOUT_ME,
+        ReadPositionTag.HOME_TIMELINE,
+        ReadPositionTag.DIRECT_MESSAGES,
+})
+public @interface ReadPositionTag {
+    String HOME_TIMELINE = "home_timeline";
+    String ACTIVITIES_ABOUT_ME = "activities_about_me";
+    String DIRECT_MESSAGES = "direct_messages";
+}
diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/BaseFiltersFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/BaseFiltersFragment.java
index ba4cf3904..a511d73dc 100644
--- a/twidere/src/main/java/org/mariotaku/twidere/fragment/BaseFiltersFragment.java
+++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/BaseFiltersFragment.java
@@ -19,8 +19,6 @@
 
 package org.mariotaku.twidere.fragment;
 
-import android.app.AlertDialog;
-import android.app.AlertDialog.Builder;
 import android.app.Dialog;
 import android.content.BroadcastReceiver;
 import android.content.ContentResolver;
@@ -39,6 +37,9 @@ import android.support.v4.app.FragmentActivity;
 import android.support.v4.app.LoaderManager;
 import android.support.v4.content.CursorLoader;
 import android.support.v4.content.Loader;
+import android.support.v4.widget.SimpleCursorAdapter;
+import android.support.v7.app.AlertDialog;
+import android.text.TextUtils;
 import android.util.SparseBooleanArray;
 import android.view.ActionMode;
 import android.view.LayoutInflater;
@@ -50,7 +51,6 @@ import android.view.ViewGroup;
 import android.widget.AbsListView.MultiChoiceModeListener;
 import android.widget.AutoCompleteTextView;
 import android.widget.ListView;
-import android.widget.SimpleCursorAdapter;
 import android.widget.TextView;
 
 import org.mariotaku.sqliteqb.library.Columns.Column;
@@ -256,19 +256,18 @@ public abstract class BaseFiltersFragment extends AbsContentListViewFragment extends AbsContentListRecycler
         adapter.setData(data);
     }
 
+    @ReadPositionTag
+    @Nullable
     protected String getReadPositionTag() {
         return null;
     }
diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/AbsStatusesFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/AbsStatusesFragment.java
index 9baa224e4..6022a7dba 100644
--- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/AbsStatusesFragment.java
+++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/AbsStatusesFragment.java
@@ -47,6 +47,7 @@ import com.squareup.otto.Subscribe;
 import org.mariotaku.twidere.R;
 import org.mariotaku.twidere.adapter.AbsStatusesAdapter;
 import org.mariotaku.twidere.adapter.iface.IStatusesAdapter.StatusAdapterListener;
+import org.mariotaku.twidere.annotation.ReadPositionTag;
 import org.mariotaku.twidere.loader.iface.IExtendedLoader;
 import org.mariotaku.twidere.model.ParcelableMedia;
 import org.mariotaku.twidere.model.ParcelableStatus;
@@ -509,6 +510,8 @@ public abstract class AbsStatusesFragment extends AbsContentListRecyclerVi
         adapter.setData(data);
     }
 
+    @ReadPositionTag
+    @Nullable
     protected String getReadPositionTag() {
         return null;
     }
diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/AbsUserListsFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/AbsUserListsFragment.java
index 04f8283a2..7cad168ad 100644
--- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/AbsUserListsFragment.java
+++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/AbsUserListsFragment.java
@@ -70,8 +70,6 @@ abstract class AbsUserListsFragment extends AbsContentListRecyclerViewFrag
     @Override
     public void onActivityCreated(@Nullable Bundle savedInstanceState) {
         super.onActivityCreated(savedInstanceState);
-
-        final FragmentActivity activity = getActivity();
         final AbsUserListsAdapter adapter = getAdapter();
         final RecyclerView recyclerView = getRecyclerView();
         final LinearLayoutManager layoutManager = getLayoutManager();
diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/AbsUsersFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/AbsUsersFragment.java
index 3670668b5..1222024d7 100644
--- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/AbsUsersFragment.java
+++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/AbsUsersFragment.java
@@ -69,8 +69,6 @@ abstract class AbsUsersFragment extends AbsContentListRecyclerViewFragment
     @Override
     public void onActivityCreated(@Nullable Bundle savedInstanceState) {
         super.onActivityCreated(savedInstanceState);
-
-        final FragmentActivity activity = getActivity();
         final AbsUsersAdapter adapter = getAdapter();
         final RecyclerView recyclerView = getRecyclerView();
         final LinearLayoutManager layoutManager = getLayoutManager();
diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/AccountsDashboardFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/AccountsDashboardFragment.java
index c2504123f..4ddf59932 100644
--- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/AccountsDashboardFragment.java
+++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/AccountsDashboardFragment.java
@@ -414,7 +414,6 @@ public class AccountsDashboardFragment extends BaseSupportFragment implements Lo
         final View view = getView();
         assert view != null;
         final Context context = view.getContext();
-        final TwidereApplication application = TwidereApplication.getInstance(context);
         mListView.setItemsCanFocus(true);
         mAdapter = new MergeAdapter();
         final LayoutInflater inflater = getLayoutInflater(savedInstanceState);
diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/ActivitiesAboutMeFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/ActivitiesAboutMeFragment.java
index 1aadd808d..29718d637 100644
--- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/ActivitiesAboutMeFragment.java
+++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/ActivitiesAboutMeFragment.java
@@ -23,8 +23,10 @@ import android.content.Context;
 import android.net.Uri;
 import android.os.Bundle;
 import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
 
 import org.mariotaku.twidere.adapter.ParcelableActivitiesAdapter;
+import org.mariotaku.twidere.annotation.ReadPositionTag;
 import org.mariotaku.twidere.provider.TwidereDataStore.Activities;
 
 import edu.tsinghua.hotmobi.model.TimelineType;
@@ -78,9 +80,11 @@ public class ActivitiesAboutMeFragment extends CursorActivitiesFragment {
         return adapter;
     }
 
+    @Nullable
     @Override
+    @ReadPositionTag
     protected String getReadPositionTag() {
-        return READ_POSITION_TAG_ACTIVITIES_ABOUT_ME;
+        return ReadPositionTag.ACTIVITIES_ABOUT_ME;
     }
 
     @Override
diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/AddUserListMemberDialogFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/AddUserListMemberDialogFragment.java
deleted file mode 100644
index 83a4e1527..000000000
--- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/AddUserListMemberDialogFragment.java
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * 				Twidere - Twitter client for Android
- * 
- *  Copyright (C) 2012-2014 Mariotaku Lee 
- * 
- *  This program is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- * 
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- * 
- *  You should have received a copy of the GNU General Public License
- *  along with this program.  If not, see .
- */
-
-package org.mariotaku.twidere.fragment.support;
-
-import android.support.v7.app.AlertDialog;
-import android.app.Dialog;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.os.Bundle;
-import android.support.annotation.NonNull;
-import android.support.v4.app.FragmentManager;
-import android.text.InputFilter;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.widget.AutoCompleteTextView;
-
-import org.mariotaku.twidere.R;
-import org.mariotaku.twidere.adapter.ComposeAutoCompleteAdapter;
-import org.mariotaku.twidere.util.AsyncTwitterWrapper;
-import org.mariotaku.twidere.util.ParseUtils;
-import org.mariotaku.twidere.util.ThemeUtils;
-
-public class AddUserListMemberDialogFragment extends BaseSupportDialogFragment implements
-        DialogInterface.OnClickListener {
-
-    public static final String FRAGMENT_TAG = "add_user_list_member";
-    private AutoCompleteTextView mEditText;
-    private ComposeAutoCompleteAdapter mUserAutoCompleteAdapter;
-
-    @Override
-    public void onClick(final DialogInterface dialog, final int which) {
-        final Bundle args = getArguments();
-        if (args == null || !args.containsKey(EXTRA_ACCOUNT_ID) || !args.containsKey(EXTRA_LIST_ID) || !args.containsKey(EXTRA_USERS))
-            return;
-        switch (which) {
-            case DialogInterface.BUTTON_POSITIVE: {
-                final String mText = ParseUtils.parseString(mEditText.getText());
-                final AsyncTwitterWrapper twitter = mTwitterWrapper;
-                if (mText == null || mText.length() <= 0 || twitter == null) return;
-                twitter.addUserListMembersAsync(args.getLong(EXTRA_ACCOUNT_ID), args.getLong(EXTRA_LIST_ID));
-                break;
-            }
-        }
-    }
-
-    @NonNull
-    @Override
-    public Dialog onCreateDialog(final Bundle savedInstanceState) {
-        final Context wrapped = ThemeUtils.getDialogThemedContext(getActivity());
-        final AlertDialog.Builder builder = new AlertDialog.Builder(wrapped);
-        final View view = LayoutInflater.from(wrapped).inflate(R.layout.dialog_auto_complete_textview, null);
-        builder.setView(view);
-        mEditText = (AutoCompleteTextView) view.findViewById(R.id.edit_text);
-        if (savedInstanceState != null) {
-            mEditText.setText(savedInstanceState.getCharSequence(EXTRA_TEXT));
-        }
-        mUserAutoCompleteAdapter = new ComposeAutoCompleteAdapter(wrapped);
-        final Bundle args = getArguments();
-        mUserAutoCompleteAdapter.setAccountId(args.getLong(EXTRA_ACCOUNT_ID));
-        mEditText.setAdapter(mUserAutoCompleteAdapter);
-        mEditText.setThreshold(1);
-        mEditText.setFilters(new InputFilter[]{new InputFilter.LengthFilter(20)});
-        builder.setTitle(R.string.screen_name);
-        builder.setPositiveButton(android.R.string.ok, this);
-        builder.setNegativeButton(android.R.string.cancel, this);
-        return builder.create();
-    }
-
-    @Override
-    public void onSaveInstanceState(final Bundle outState) {
-        outState.putCharSequence(EXTRA_TEXT, mEditText.getText());
-        super.onSaveInstanceState(outState);
-    }
-
-    public static AddUserListMemberDialogFragment show(final FragmentManager fm, final long accountId, final long listId) {
-        final Bundle args = new Bundle();
-        args.putLong(EXTRA_ACCOUNT_ID, accountId);
-        args.putLong(EXTRA_LIST_ID, listId);
-        final AddUserListMemberDialogFragment f = new AddUserListMemberDialogFragment();
-        f.setArguments(args);
-        f.show(fm, FRAGMENT_TAG);
-        return f;
-    }
-
-}
diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/CreateUserListDialogFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/CreateUserListDialogFragment.java
index 1423f0b66..bb4ea291b 100644
--- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/CreateUserListDialogFragment.java
+++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/CreateUserListDialogFragment.java
@@ -20,13 +20,11 @@
 package org.mariotaku.twidere.fragment.support;
 
 import android.app.Dialog;
-import android.content.Context;
 import android.content.DialogInterface;
 import android.os.Bundle;
 import android.support.annotation.NonNull;
 import android.support.v7.app.AlertDialog;
-import android.view.LayoutInflater;
-import android.view.View;
+import android.text.TextUtils;
 import android.widget.CheckBox;
 
 import com.rengwuxian.materialedittext.MaterialEditText;
@@ -34,27 +32,24 @@ import com.rengwuxian.materialedittext.MaterialEditText;
 import org.mariotaku.twidere.R;
 import org.mariotaku.twidere.text.validator.UserListNameValidator;
 import org.mariotaku.twidere.util.ParseUtils;
-import org.mariotaku.twidere.util.ThemeUtils;
 
 public class CreateUserListDialogFragment extends BaseSupportDialogFragment implements DialogInterface.OnClickListener {
 
-    private MaterialEditText mEditName, mEditDescription;
-    private CheckBox mPublicCheckBox;
-    private String mName, mDescription;
-    private long mAccountId;
-    private long mListId;
-    private boolean mIsPublic = true;
-
     @Override
     public void onClick(final DialogInterface dialog, final int which) {
-        if (mAccountId <= 0) return;
         switch (which) {
             case DialogInterface.BUTTON_POSITIVE: {
-                mName = ParseUtils.parseString(mEditName.getText());
-                mDescription = ParseUtils.parseString(mEditDescription.getText());
-                mIsPublic = mPublicCheckBox.isChecked();
-                if (mName == null || mName.length() <= 0) return;
-                mTwitterWrapper.createUserListAsync(mAccountId, mName, mIsPublic, mDescription);
+                final AlertDialog alertDialog = (AlertDialog) dialog;
+                final Bundle args = getArguments();
+                final long accountId = args.getLong(EXTRA_ACCOUNT_ID, -1);
+                final MaterialEditText mEditName = (MaterialEditText) alertDialog.findViewById(R.id.name);
+                final MaterialEditText mEditDescription = (MaterialEditText) alertDialog.findViewById(R.id.description);
+                final CheckBox mPublicCheckBox = (CheckBox) alertDialog.findViewById(R.id.is_public);
+                final String name = ParseUtils.parseString(mEditName.getText());
+                final String description = ParseUtils.parseString(mEditDescription.getText());
+                final boolean isPublic = mPublicCheckBox.isChecked();
+                if (TextUtils.isEmpty(name)) return;
+                mTwitterWrapper.createUserListAsync(accountId, name, isPublic, description);
                 break;
             }
         }
@@ -64,37 +59,24 @@ public class CreateUserListDialogFragment extends BaseSupportDialogFragment impl
     @NonNull
     @Override
     public Dialog onCreateDialog(final Bundle savedInstanceState) {
-        final Bundle bundle = savedInstanceState == null ? getArguments() : savedInstanceState;
-        mAccountId = bundle != null ? bundle.getLong(EXTRA_ACCOUNT_ID, -1) : -1;
-        final Context wrapped = ThemeUtils.getDialogThemedContext(getActivity());
-        final AlertDialog.Builder builder = new AlertDialog.Builder(wrapped);
-        final View view = LayoutInflater.from(wrapped).inflate(R.layout.dialog_user_list_detail_editor, null);
-        builder.setView(view);
-        mEditName = (MaterialEditText) view.findViewById(R.id.name);
-        mEditName.addValidator(new UserListNameValidator(getString(R.string.invalid_list_name)));
-        mEditDescription = (MaterialEditText) view.findViewById(R.id.description);
-        mPublicCheckBox = (CheckBox) view.findViewById(R.id.is_public);
-        if (mName != null) {
-            mEditName.setText(mName);
-        }
-        if (mDescription != null) {
-            mEditDescription.setText(mDescription);
-        }
-        mPublicCheckBox.setChecked(mIsPublic);
+        final AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
+        builder.setView(R.layout.dialog_user_list_detail_editor);
+
         builder.setTitle(R.string.new_user_list);
         builder.setPositiveButton(android.R.string.ok, this);
         builder.setNegativeButton(android.R.string.cancel, this);
-        return builder.create();
-    }
-
-    @Override
-    public void onSaveInstanceState(final Bundle outState) {
-        outState.putLong(EXTRA_ACCOUNT_ID, mAccountId);
-        outState.putLong(EXTRA_LIST_ID, mListId);
-        outState.putString(EXTRA_LIST_NAME, mName);
-        outState.putString(EXTRA_DESCRIPTION, mDescription);
-        outState.putBoolean(EXTRA_IS_PUBLIC, mIsPublic);
-        super.onSaveInstanceState(outState);
+        final AlertDialog dialog = builder.create();
+        dialog.setOnShowListener(new DialogInterface.OnShowListener() {
+            @Override
+            public void onShow(DialogInterface dialog) {
+                final AlertDialog alertDialog = (AlertDialog) dialog;
+                MaterialEditText editName = (MaterialEditText) alertDialog.findViewById(R.id.name);
+                MaterialEditText editDescription = (MaterialEditText) alertDialog.findViewById(R.id.description);
+                CheckBox publicCheckBox = (CheckBox) alertDialog.findViewById(R.id.is_public);
+                editName.addValidator(new UserListNameValidator(getString(R.string.invalid_list_name)));
+            }
+        });
+        return dialog;
     }
 
 }
diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/DraftsFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/DraftsFragment.java
index ec43f1d6b..9e409bb43 100644
--- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/DraftsFragment.java
+++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/DraftsFragment.java
@@ -27,7 +27,6 @@ import android.content.Context;
 import android.content.DialogInterface;
 import android.content.DialogInterface.OnClickListener;
 import android.content.Intent;
-import android.content.SharedPreferences;
 import android.database.Cursor;
 import android.net.Uri;
 import android.os.AsyncTask;
diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/HomeTimelineFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/HomeTimelineFragment.java
index 330025156..efc40d3b7 100644
--- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/HomeTimelineFragment.java
+++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/HomeTimelineFragment.java
@@ -23,6 +23,7 @@ import android.net.Uri;
 import android.support.annotation.NonNull;
 import android.support.v4.app.FragmentActivity;
 
+import org.mariotaku.twidere.annotation.ReadPositionTag;
 import org.mariotaku.twidere.provider.TwidereDataStore.Statuses;
 import org.mariotaku.twidere.util.AsyncTwitterWrapper;
 
@@ -89,8 +90,9 @@ public class HomeTimelineFragment extends CursorStatusesFragment {
     }
 
     @Override
+    @ReadPositionTag
     protected String getReadPositionTag() {
-        return TAB_TYPE_HOME_TIMELINE;
+        return ReadPositionTag.HOME_TIMELINE;
     }
 
 }
diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/MessagesConversationFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/MessagesConversationFragment.java
index a16b8569a..1ebd1b50a 100644
--- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/MessagesConversationFragment.java
+++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/MessagesConversationFragment.java
@@ -81,6 +81,7 @@ import org.mariotaku.twidere.adapter.AccountsSpinnerAdapter;
 import org.mariotaku.twidere.adapter.MessageConversationAdapter;
 import org.mariotaku.twidere.adapter.SimpleParcelableUsersAdapter;
 import org.mariotaku.twidere.adapter.iface.IBaseCardAdapter.MenuButtonClickListener;
+import org.mariotaku.twidere.annotation.CustomTabType;
 import org.mariotaku.twidere.loader.support.UserSearchLoader;
 import org.mariotaku.twidere.model.ParcelableAccount;
 import org.mariotaku.twidere.model.ParcelableCredentials;
@@ -857,6 +858,7 @@ public class MessagesConversationFragment extends BaseSupportFragment implements
                         CachedUsers.BASIC_COLUMNS, selection != null ? selection.getSQL() : null,
                         selectionArgs, orderBy.getSQL());
                 final ParcelableUserCursorIndices i = new ParcelableUserCursorIndices(c);
+                assert c != null;
                 c.moveToFirst();
                 while (!c.isAfterLast()) {
                     cachedList.add(i.newObject(c));
@@ -929,7 +931,7 @@ public class MessagesConversationFragment extends BaseSupportFragment implements
             if (cursor.moveToFirst()) {
                 final int messageIdIdx = cursor.getColumnIndex(ConversationEntries.MESSAGE_ID);
                 final String key = mAccount.account_id + "-" + mRecipient.id;
-                mReadStateManager.setPosition(TAB_TYPE_DIRECT_MESSAGES, key, cursor.getLong(messageIdIdx), false);
+                mReadStateManager.setPosition(CustomTabType.DIRECT_MESSAGES, key, cursor.getLong(messageIdIdx), false);
             }
             cursor.close();
         }
diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/PhishingLinkWarningDialogFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/PhishingLinkWarningDialogFragment.java
index 47b8538e9..2fa8062a6 100644
--- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/PhishingLinkWarningDialogFragment.java
+++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/PhishingLinkWarningDialogFragment.java
@@ -19,50 +19,45 @@
 
 package org.mariotaku.twidere.fragment.support;
 
-import android.support.v7.app.AlertDialog;
 import android.app.Dialog;
-import android.content.Context;
 import android.content.DialogInterface;
 import android.content.DialogInterface.OnClickListener;
 import android.content.Intent;
 import android.net.Uri;
 import android.os.Bundle;
 import android.support.annotation.NonNull;
-import android.view.LayoutInflater;
+import android.support.v7.app.AlertDialog;
 
 import org.mariotaku.twidere.R;
-import org.mariotaku.twidere.util.ThemeUtils;
 
 public class PhishingLinkWarningDialogFragment extends BaseSupportDialogFragment implements OnClickListener {
 
-	@Override
-	public void onClick(final DialogInterface dialog, final int which) {
-		switch (which) {
-			case DialogInterface.BUTTON_POSITIVE: {
-				final Bundle args = getArguments();
-				if (args == null) return;
-				final Uri uri = args.getParcelable(EXTRA_URI);
-				if (uri == null) return;
-				final Intent intent = new Intent(Intent.ACTION_VIEW);
-				intent.setData(uri);
-				startActivity(intent);
-				break;
-			}
-		}
-
-	}
-
-	@NonNull
     @Override
-	public Dialog onCreateDialog(final Bundle savedInstanceState) {
-		final Context wrapped = ThemeUtils.getDialogThemedContext(getActivity());
-		final AlertDialog.Builder builder = new AlertDialog.Builder(wrapped);
-		final LayoutInflater inflater = LayoutInflater.from(wrapped);
-		builder.setTitle(android.R.string.dialog_alert_title);
-		builder.setView(inflater.inflate(R.layout.dialog_phishing_link_warning, null));
-		builder.setPositiveButton(android.R.string.ok, this);
-		builder.setNegativeButton(android.R.string.cancel, null);
-		return builder.create();
-	}
+    public void onClick(final DialogInterface dialog, final int which) {
+        switch (which) {
+            case DialogInterface.BUTTON_POSITIVE: {
+                final Bundle args = getArguments();
+                if (args == null) return;
+                final Uri uri = args.getParcelable(EXTRA_URI);
+                if (uri == null) return;
+                final Intent intent = new Intent(Intent.ACTION_VIEW);
+                intent.setData(uri);
+                startActivity(intent);
+                break;
+            }
+        }
+
+    }
+
+    @NonNull
+    @Override
+    public Dialog onCreateDialog(final Bundle savedInstanceState) {
+        final AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
+        builder.setTitle(android.R.string.dialog_alert_title);
+        builder.setView(R.layout.dialog_phishing_link_warning);
+        builder.setPositiveButton(android.R.string.ok, this);
+        builder.setNegativeButton(android.R.string.cancel, null);
+        return builder.create();
+    }
 
 }
diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/SetUserNicknameDialogFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/SetUserNicknameDialogFragment.java
index f589bfc44..1b065ac4c 100644
--- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/SetUserNicknameDialogFragment.java
+++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/SetUserNicknameDialogFragment.java
@@ -35,7 +35,6 @@ import android.widget.FrameLayout;
 import org.mariotaku.twidere.R;
 import org.mariotaku.twidere.util.ParseUtils;
 import org.mariotaku.twidere.util.ThemeUtils;
-import org.mariotaku.twidere.util.UserColorNameManager;
 
 public class SetUserNicknameDialogFragment extends BaseSupportDialogFragment implements OnClickListener {
 
diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/SupportMessageDialogFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/SupportMessageDialogFragment.java
index 8b6fad890..6a234aa9d 100644
--- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/SupportMessageDialogFragment.java
+++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/SupportMessageDialogFragment.java
@@ -23,7 +23,6 @@ import android.app.AlertDialog;
 import android.app.Dialog;
 import android.os.Bundle;
 import android.support.annotation.NonNull;
-import android.support.v4.app.DialogFragment;
 import android.support.v4.app.FragmentActivity;
 
 /**
diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/TrendsSuggestionsFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/TrendsSuggestionsFragment.java
index 97ae417ba..bcb1f6b01 100644
--- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/TrendsSuggestionsFragment.java
+++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/TrendsSuggestionsFragment.java
@@ -20,7 +20,6 @@
 package org.mariotaku.twidere.fragment.support;
 
 import android.content.Context;
-import android.content.SharedPreferences;
 import android.database.Cursor;
 import android.net.Uri;
 import android.os.Bundle;
@@ -39,8 +38,8 @@ import org.mariotaku.twidere.provider.TwidereDataStore.CachedTrends;
 import org.mariotaku.twidere.util.AsyncTwitterWrapper;
 import org.mariotaku.twidere.util.message.TaskStateChangedEvent;
 
-import static org.mariotaku.twidere.util.Utils.getDefaultAccountId;
 import static org.mariotaku.twidere.util.DataStoreUtils.getTableNameByUri;
+import static org.mariotaku.twidere.util.Utils.getDefaultAccountId;
 import static org.mariotaku.twidere.util.Utils.openTweetSearch;
 
 public class TrendsSuggestionsFragment extends AbsContentListViewFragment
diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/UserFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/UserFragment.java
index 5775d950c..c99bb6b54 100644
--- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/UserFragment.java
+++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/UserFragment.java
@@ -414,6 +414,7 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
             return;
         }
         final SupportTabSpec spec = mPagerAdapter.getTab(mViewPager.getCurrentItem());
+        assert spec.type != null;
         switch (spec.type) {
             case TAB_TYPE_STATUSES: {
                 actionBar.setSubtitle(getResources().getQuantityString(R.plurals.N_statuses,
@@ -1637,7 +1638,7 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
 
         @TargetApi(Build.VERSION_CODES.LOLLIPOP)
         @Override
-        public void getOutline(Outline outline) {
+        public void getOutline(@NonNull Outline outline) {
             mColorDrawable.getOutline(outline);
             outline.setAlpha(mFactor * mOutlineAlphaFactor * 0.99f);
         }
diff --git a/twidere/src/main/java/org/mariotaku/twidere/graphic/ActionBarColorDrawable.java b/twidere/src/main/java/org/mariotaku/twidere/graphic/ActionBarColorDrawable.java
index f2b04317e..0a11957de 100644
--- a/twidere/src/main/java/org/mariotaku/twidere/graphic/ActionBarColorDrawable.java
+++ b/twidere/src/main/java/org/mariotaku/twidere/graphic/ActionBarColorDrawable.java
@@ -23,6 +23,7 @@ import android.annotation.TargetApi;
 import android.graphics.Outline;
 import android.graphics.Rect;
 import android.os.Build;
+import android.support.annotation.NonNull;
 
 /**
  * Created by mariotaku on 14/12/8.
@@ -38,7 +39,7 @@ public class ActionBarColorDrawable extends ActionBarColorDrawableBase {
 
     @TargetApi(Build.VERSION_CODES.LOLLIPOP)
     @Override
-    public void getOutline(Outline outline) {
+    public void getOutline(@NonNull Outline outline) {
         if (!isOutlineEnabled()) return;
         final Rect bounds = getBounds();
         // Very very dirty hack to make outline shadow in action bar not visible beneath status bar
diff --git a/twidere/src/main/java/org/mariotaku/twidere/loader/support/CursorSupportUsersLoader.java b/twidere/src/main/java/org/mariotaku/twidere/loader/support/CursorSupportUsersLoader.java
index 41d4a936e..f411727d8 100644
--- a/twidere/src/main/java/org/mariotaku/twidere/loader/support/CursorSupportUsersLoader.java
+++ b/twidere/src/main/java/org/mariotaku/twidere/loader/support/CursorSupportUsersLoader.java
@@ -42,6 +42,7 @@ public abstract class CursorSupportUsersLoader extends BaseCursorSupportUsersLoa
     protected abstract PageableResponseList getCursoredUsers(@NonNull Twitter twitter, Paging paging)
             throws TwitterException;
 
+    @NonNull
     @Override
     protected final List getUsers(@NonNull final Twitter twitter) throws TwitterException {
         final Paging paging = new Paging();
diff --git a/twidere/src/main/java/org/mariotaku/twidere/loader/support/IDsUsersLoader.java b/twidere/src/main/java/org/mariotaku/twidere/loader/support/IDsUsersLoader.java
index 80ddb654c..7c84db3eb 100644
--- a/twidere/src/main/java/org/mariotaku/twidere/loader/support/IDsUsersLoader.java
+++ b/twidere/src/main/java/org/mariotaku/twidere/loader/support/IDsUsersLoader.java
@@ -39,6 +39,7 @@ public abstract class IDsUsersLoader extends BaseCursorSupportUsersLoader {
         super(context, accountId, cursor, data, fromUser);
     }
 
+    @NonNull
     @Override
     public List getUsers(@NonNull final Twitter twitter) throws TwitterException {
         final Paging paging = new Paging();
@@ -47,11 +48,11 @@ public abstract class IDsUsersLoader extends BaseCursorSupportUsersLoader {
             paging.setCursor(getCursor());
         }
         final IDs ids = getIDs(twitter, paging);
-        if (ids == null) return null;
         setCursorIds(ids);
         return twitter.lookupUsers(ids.getIDs());
     }
 
+    @NonNull
     protected abstract IDs getIDs(@NonNull Twitter twitter, Paging paging) throws TwitterException;
 
 }
diff --git a/twidere/src/main/java/org/mariotaku/twidere/loader/support/IncomingFriendshipsLoader.java b/twidere/src/main/java/org/mariotaku/twidere/loader/support/IncomingFriendshipsLoader.java
index 0162df5e7..8633f0155 100644
--- a/twidere/src/main/java/org/mariotaku/twidere/loader/support/IncomingFriendshipsLoader.java
+++ b/twidere/src/main/java/org/mariotaku/twidere/loader/support/IncomingFriendshipsLoader.java
@@ -37,6 +37,7 @@ public class IncomingFriendshipsLoader extends IDsUsersLoader {
         super(context, accountId, maxId, data, fromUser);
     }
 
+    @NonNull
     @Override
     protected IDs getIDs(@NonNull final Twitter twitter, final Paging paging) throws TwitterException {
         return twitter.getIncomingFriendships(paging);
diff --git a/twidere/src/main/java/org/mariotaku/twidere/loader/support/StatusFavoritersLoader.java b/twidere/src/main/java/org/mariotaku/twidere/loader/support/StatusFavoritersLoader.java
index 514528d08..52c4770b5 100644
--- a/twidere/src/main/java/org/mariotaku/twidere/loader/support/StatusFavoritersLoader.java
+++ b/twidere/src/main/java/org/mariotaku/twidere/loader/support/StatusFavoritersLoader.java
@@ -41,6 +41,7 @@ public class StatusFavoritersLoader extends IDsUsersLoader {
         mStatusId = statusId;
     }
 
+    @NonNull
     @Override
     protected IDs getIDs(@NonNull final Twitter twitter, final Paging paging) throws TwitterException {
         return twitter.getStatusActivitySummary(mStatusId).getFavoriters();
diff --git a/twidere/src/main/java/org/mariotaku/twidere/loader/support/StatusRetweetersLoader.java b/twidere/src/main/java/org/mariotaku/twidere/loader/support/StatusRetweetersLoader.java
index 65f453241..89c45bc49 100644
--- a/twidere/src/main/java/org/mariotaku/twidere/loader/support/StatusRetweetersLoader.java
+++ b/twidere/src/main/java/org/mariotaku/twidere/loader/support/StatusRetweetersLoader.java
@@ -40,6 +40,7 @@ public class StatusRetweetersLoader extends IDsUsersLoader {
         mStatusId = statusId;
     }
 
+    @NonNull
     @Override
     protected IDs getIDs(@NonNull final Twitter twitter, final Paging paging) throws TwitterException {
         return twitter.getRetweetersIDs(mStatusId, paging);
diff --git a/twidere/src/main/java/org/mariotaku/twidere/loader/support/TwitterAPIStatusesLoader.java b/twidere/src/main/java/org/mariotaku/twidere/loader/support/TwitterAPIStatusesLoader.java
index e1fc6fc97..006a9a010 100644
--- a/twidere/src/main/java/org/mariotaku/twidere/loader/support/TwitterAPIStatusesLoader.java
+++ b/twidere/src/main/java/org/mariotaku/twidere/loader/support/TwitterAPIStatusesLoader.java
@@ -101,7 +101,6 @@ public abstract class TwitterAPIStatusesLoader extends ParcelableStatusesLoader
         final Twitter twitter = getTwitter();
         if (twitter == null) return null;
         final List statuses;
-        final boolean truncated;
         final Context context = getContext();
         final SharedPreferences prefs = context.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
         final int loadItemLimit = prefs.getInt(KEY_LOAD_ITEM_LIMIT, DEFAULT_LOAD_ITEM_LIMIT);
diff --git a/twidere/src/main/java/org/mariotaku/twidere/loader/support/TwitterAPIUsersLoader.java b/twidere/src/main/java/org/mariotaku/twidere/loader/support/TwitterAPIUsersLoader.java
index c1274a82c..39507b922 100644
--- a/twidere/src/main/java/org/mariotaku/twidere/loader/support/TwitterAPIUsersLoader.java
+++ b/twidere/src/main/java/org/mariotaku/twidere/loader/support/TwitterAPIUsersLoader.java
@@ -49,7 +49,6 @@ public abstract class TwitterAPIUsersLoader extends ParcelableUsersLoader {
         final List users;
         try {
             users = getUsers(twitter);
-            if (users == null) return data;
         } catch (final TwitterException e) {
             Log.w(LOGTAG, e);
             return data;
@@ -66,5 +65,6 @@ public abstract class TwitterAPIUsersLoader extends ParcelableUsersLoader {
         return data;
     }
 
+    @NonNull
     protected abstract List getUsers(@NonNull Twitter twitter) throws TwitterException;
 }
diff --git a/twidere/src/main/java/org/mariotaku/twidere/loader/support/UserSearchLoader.java b/twidere/src/main/java/org/mariotaku/twidere/loader/support/UserSearchLoader.java
index 7cffad0ca..aaede560f 100644
--- a/twidere/src/main/java/org/mariotaku/twidere/loader/support/UserSearchLoader.java
+++ b/twidere/src/main/java/org/mariotaku/twidere/loader/support/UserSearchLoader.java
@@ -50,9 +50,9 @@ public class UserSearchLoader extends TwitterAPIUsersLoader {
         return mQuery;
     }
 
+    @NonNull
     @Override
     public List getUsers(@NonNull final Twitter twitter) throws TwitterException {
-        if (twitter == null) return null;
         final Paging paging = new Paging();
         paging.page(mPage);
         return twitter.searchUsers(mQuery, paging);
diff --git a/twidere/src/main/java/org/mariotaku/twidere/model/SupportTabSpec.java b/twidere/src/main/java/org/mariotaku/twidere/model/SupportTabSpec.java
index f3470ccf1..05d8b135c 100644
--- a/twidere/src/main/java/org/mariotaku/twidere/model/SupportTabSpec.java
+++ b/twidere/src/main/java/org/mariotaku/twidere/model/SupportTabSpec.java
@@ -21,9 +21,12 @@ package org.mariotaku.twidere.model;
 
 import android.os.Bundle;
 import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
 import android.support.v4.app.Fragment;
 
+import org.apache.commons.lang3.builder.ToStringBuilder;
 import org.mariotaku.twidere.TwidereConstants;
+import org.mariotaku.twidere.annotation.CustomTabType;
 
 import static org.mariotaku.twidere.util.CompareUtils.bundleEquals;
 import static org.mariotaku.twidere.util.CompareUtils.classEquals;
@@ -33,6 +36,8 @@ public class SupportTabSpec implements Comparable, TwidereConsta
 
     public CharSequence name;
     public final Object icon;
+    @CustomTabType
+    @Nullable
     public final String type;
     public final Class cls;
     public final Bundle args;
@@ -44,8 +49,9 @@ public class SupportTabSpec implements Comparable, TwidereConsta
         this(name, icon, null, cls, args, position, tag);
     }
 
-    public SupportTabSpec(final String name, final Object icon, final String type, final Class cls,
-                          final Bundle args, final int position, final String tag) {
+    public SupportTabSpec(final String name, final Object icon, @CustomTabType @Nullable final String type,
+                          final Class cls, final Bundle args, final int position,
+                          final String tag) {
         if (cls == null) throw new IllegalArgumentException("Fragment cannot be null!");
         if (name == null && icon == null)
             throw new IllegalArgumentException("You must specify a name or icon for this tab!");
@@ -73,15 +79,15 @@ public class SupportTabSpec implements Comparable, TwidereConsta
 
     @Override
     public String toString() {
-        return "SupportTabSpec{" +
-                "name='" + name + '\'' +
-                ", icon=" + icon +
-                ", type='" + type + '\'' +
-                ", cls=" + cls +
-                ", args=" + args +
-                ", position=" + position +
-                ", tag='" + tag + '\'' +
-                '}';
+        return new ToStringBuilder(this)
+                .append("name", name)
+                .append("icon", icon)
+                .append("type", type)
+                .append("cls", cls)
+                .append("args", args)
+                .append("position", position)
+                .append("tag", tag)
+                .toString();
     }
 
 }
diff --git a/twidere/src/main/java/org/mariotaku/twidere/model/util/ParcelableStatusUtils.java b/twidere/src/main/java/org/mariotaku/twidere/model/util/ParcelableStatusUtils.java
index c143fd91c..5248a4556 100644
--- a/twidere/src/main/java/org/mariotaku/twidere/model/util/ParcelableStatusUtils.java
+++ b/twidere/src/main/java/org/mariotaku/twidere/model/util/ParcelableStatusUtils.java
@@ -2,7 +2,6 @@ package org.mariotaku.twidere.model.util;
 
 import android.support.annotation.NonNull;
 
-import org.mariotaku.twidere.api.twitter.model.Status;
 import org.mariotaku.twidere.model.ParcelableStatus;
 
 /**
diff --git a/twidere/src/main/java/org/mariotaku/twidere/preference/AutoFixSwitchPreference.java b/twidere/src/main/java/org/mariotaku/twidere/preference/AutoFixSwitchPreference.java
index 79f234c4d..a933c4023 100644
--- a/twidere/src/main/java/org/mariotaku/twidere/preference/AutoFixSwitchPreference.java
+++ b/twidere/src/main/java/org/mariotaku/twidere/preference/AutoFixSwitchPreference.java
@@ -22,7 +22,6 @@ package org.mariotaku.twidere.preference;
 import android.content.Context;
 import android.content.SharedPreferences;
 import android.util.AttributeSet;
-import android.view.View;
 
 import org.jraf.android.backport.switchwidget.SwitchPreference;
 
diff --git a/twidere/src/main/java/org/mariotaku/twidere/preference/TranslationDestinationPreference.java b/twidere/src/main/java/org/mariotaku/twidere/preference/TranslationDestinationPreference.java
index 7c370a792..4b23fd9b9 100644
--- a/twidere/src/main/java/org/mariotaku/twidere/preference/TranslationDestinationPreference.java
+++ b/twidere/src/main/java/org/mariotaku/twidere/preference/TranslationDestinationPreference.java
@@ -51,8 +51,6 @@ import org.mariotaku.twidere.api.twitter.Twitter;
 import org.mariotaku.twidere.api.twitter.TwitterException;
 import org.mariotaku.twidere.api.twitter.model.Language;
 
-import static org.mariotaku.twidere.util.TwitterAPIFactory.getDefaultTwitterInstance;
-
 public class TranslationDestinationPreference extends Preference implements Constants, OnClickListener {
 
     private SharedPreferences mPreferences;
diff --git a/twidere/src/main/java/org/mariotaku/twidere/provider/TwidereDataProvider.java b/twidere/src/main/java/org/mariotaku/twidere/provider/TwidereDataProvider.java
index c12943a86..635853af1 100644
--- a/twidere/src/main/java/org/mariotaku/twidere/provider/TwidereDataProvider.java
+++ b/twidere/src/main/java/org/mariotaku/twidere/provider/TwidereDataProvider.java
@@ -75,6 +75,9 @@ import org.mariotaku.twidere.BuildConfig;
 import org.mariotaku.twidere.Constants;
 import org.mariotaku.twidere.R;
 import org.mariotaku.twidere.activity.support.HomeActivity;
+import org.mariotaku.twidere.annotation.CustomTabType;
+import org.mariotaku.twidere.annotation.NotificationType;
+import org.mariotaku.twidere.annotation.ReadPositionTag;
 import org.mariotaku.twidere.app.TwidereApplication;
 import org.mariotaku.twidere.model.AccountPreferences;
 import org.mariotaku.twidere.model.ActivityTitleSummaryMessage;
@@ -184,14 +187,14 @@ public final class TwidereDataProvider extends ContentProvider implements Consta
 
     };
 
-    private static PendingIntent getMarkReadDeleteIntent(Context context, String type, long accountId,
-                                                         long position, boolean extraUserFollowing) {
+    private static PendingIntent getMarkReadDeleteIntent(Context context, @NotificationType String type,
+                                                         long accountId, long position, boolean extraUserFollowing) {
         return getMarkReadDeleteIntent(context, type, accountId, position, -1, -1, extraUserFollowing);
     }
 
-    private static PendingIntent getMarkReadDeleteIntent(Context context, String type, long accountId,
-                                                         long position, long extraId, long extraUserId,
-                                                         boolean extraUserFollowing) {
+    private static PendingIntent getMarkReadDeleteIntent(Context context, @NotificationType String type,
+                                                         long accountId, long position, long extraId,
+                                                         long extraUserId, boolean extraUserFollowing) {
         // Setup delete intent
         final Intent intent = new Intent(context, NotificationReceiver.class);
         intent.setAction(BROADCAST_NOTIFICATION_DELETED);
@@ -211,17 +214,18 @@ public final class TwidereDataProvider extends ContentProvider implements Consta
         return PendingIntent.getBroadcast(context, 0, intent, 0);
     }
 
-    private static PendingIntent getMarkReadDeleteIntent(Context context, String type, long accountId, StringLongPair[] positions) {
+    private static PendingIntent getMarkReadDeleteIntent(Context context, @NotificationType String notificationType,
+                                                         long accountId, StringLongPair[] positions) {
         // Setup delete intent
         final Intent intent = new Intent(context, NotificationReceiver.class);
         final Uri.Builder linkBuilder = new Uri.Builder();
         linkBuilder.scheme(SCHEME_TWIDERE);
         linkBuilder.authority(AUTHORITY_NOTIFICATIONS);
-        linkBuilder.appendPath(type);
+        linkBuilder.appendPath(notificationType);
         linkBuilder.appendQueryParameter(QUERY_PARAM_ACCOUNT_ID, String.valueOf(accountId));
         linkBuilder.appendQueryParameter(QUERY_PARAM_READ_POSITIONS, StringLongPair.toString(positions));
         linkBuilder.appendQueryParameter(QUERY_PARAM_TIMESTAMP, String.valueOf(System.currentTimeMillis()));
-        linkBuilder.appendQueryParameter(QUERY_PARAM_NOTIFICATION_TYPE, type);
+        linkBuilder.appendQueryParameter(QUERY_PARAM_NOTIFICATION_TYPE, notificationType);
         intent.setData(linkBuilder.build());
         return PendingIntent.getBroadcast(context, 0, intent, 0);
     }
@@ -586,18 +590,23 @@ public final class TwidereDataProvider extends ContentProvider implements Consta
     public ParcelFileDescriptor openFile(@NonNull final Uri uri, @NonNull final String mode) throws FileNotFoundException {
         final int table_id = DataStoreUtils.getTableId(uri);
         final String table = DataStoreUtils.getTableNameById(table_id);
-        final int mode_code;
-        if ("r".equals(mode)) {
-            mode_code = ParcelFileDescriptor.MODE_READ_ONLY;
-        } else if ("rw".equals(mode)) {
-            mode_code = ParcelFileDescriptor.MODE_READ_WRITE;
-        } else if ("rwt".equals(mode)) {
-            mode_code = ParcelFileDescriptor.MODE_READ_WRITE | ParcelFileDescriptor.MODE_TRUNCATE;
-        } else
-            throw new IllegalArgumentException();
-        if (mode_code == ParcelFileDescriptor.MODE_READ_ONLY) {
+        final int modeCode;
+        switch (mode) {
+            case "r":
+                modeCode = ParcelFileDescriptor.MODE_READ_ONLY;
+                break;
+            case "rw":
+                modeCode = ParcelFileDescriptor.MODE_READ_WRITE;
+                break;
+            case "rwt":
+                modeCode = ParcelFileDescriptor.MODE_READ_WRITE | ParcelFileDescriptor.MODE_TRUNCATE;
+                break;
+            default:
+                throw new IllegalArgumentException();
+        }
+        if (modeCode == ParcelFileDescriptor.MODE_READ_ONLY) {
             checkReadPermission(table_id, table, null);
-        } else if ((mode_code & ParcelFileDescriptor.MODE_READ_WRITE) != 0) {
+        } else if ((modeCode & ParcelFileDescriptor.MODE_READ_WRITE) != 0) {
             checkReadPermission(table_id, table, null);
             checkWritePermission(table_id, table);
         }
@@ -1181,7 +1190,7 @@ public final class TwidereDataProvider extends ContentProvider implements Consta
                         DataStoreUtils.getAccountIds(context));
                 for (final AccountPreferences pref : prefs) {
                     if (!pref.isHomeTimelineNotificationEnabled()) continue;
-                    showTimelineNotification(pref, getPositionTag(TAB_TYPE_HOME_TIMELINE, pref.getAccountId()));
+                    showTimelineNotification(pref, getPositionTag(CustomTabType.HOME_TIMELINE, pref.getAccountId()));
                 }
                 notifyUnreadCountChanged(NOTIFICATION_ID_HOME_TIMELINE);
                 break;
@@ -1192,7 +1201,7 @@ public final class TwidereDataProvider extends ContentProvider implements Consta
                 final boolean combined = mPreferences.getBoolean(KEY_COMBINED_NOTIFICATIONS);
                 for (final AccountPreferences pref : prefs) {
                     if (!pref.isInteractionsNotificationEnabled()) continue;
-                    showInteractionsNotification(pref, getPositionTag(READ_POSITION_TAG_ACTIVITIES_ABOUT_ME,
+                    showInteractionsNotification(pref, getPositionTag(ReadPositionTag.ACTIVITIES_ABOUT_ME,
                             pref.getAccountId()), combined);
                 }
                 notifyUnreadCountChanged(NOTIFICATION_ID_INTERACTIONS_TIMELINE);
@@ -1203,7 +1212,7 @@ public final class TwidereDataProvider extends ContentProvider implements Consta
                         DataStoreUtils.getAccountIds(context));
                 for (final AccountPreferences pref : prefs) {
                     if (!pref.isDirectMessagesNotificationEnabled()) continue;
-                    final StringLongPair[] pairs = mReadStateManager.getPositionPairs(TAB_TYPE_DIRECT_MESSAGES);
+                    final StringLongPair[] pairs = mReadStateManager.getPositionPairs(CustomTabType.DIRECT_MESSAGES);
                     showMessagesNotification(pref, pairs, valuesArray);
                 }
                 notifyUnreadCountChanged(NOTIFICATION_ID_DIRECT_MESSAGES);
@@ -1276,9 +1285,10 @@ public final class TwidereDataProvider extends ContentProvider implements Consta
             builder.setContentTitle(notificationTitle);
             builder.setContentText(notificationContent);
             builder.setCategory(NotificationCompat.CATEGORY_SOCIAL);
-            builder.setContentIntent(getContentIntent(context, AUTHORITY_HOME, accountId));
-            builder.setDeleteIntent(getMarkReadDeleteIntent(context, AUTHORITY_HOME, accountId,
-                    statusId, false));
+            builder.setContentIntent(getContentIntent(context, CustomTabType.HOME_TIMELINE,
+                    NotificationType.HOME_TIMELINE, accountId));
+            builder.setDeleteIntent(getMarkReadDeleteIntent(context, NotificationType.HOME_TIMELINE,
+                    accountId, statusId, false));
             builder.setNumber(statusesCount);
             builder.setCategory(NotificationCompat.CATEGORY_SOCIAL);
             applyNotificationPreferences(builder, pref, pref.getHomeTimelineNotificationType());
@@ -1310,7 +1320,7 @@ public final class TwidereDataProvider extends ContentProvider implements Consta
             final int count = c.getCount();
             if (count == 0) return;
             c.moveToFirst();
-            builder.setSmallIcon(R.drawable.ic_stat_mention);
+            builder.setSmallIcon(R.drawable.ic_stat_notification);
             builder.setNumber(count);
             builder.setCategory(NotificationCompat.CATEGORY_SOCIAL);
             applyNotificationPreferences(builder, pref, pref.getHomeTimelineNotificationType());
@@ -1354,11 +1364,11 @@ public final class TwidereDataProvider extends ContentProvider implements Consta
                 }
                 c.moveToNext();
             }
-            builder.setContentIntent(getContentIntent(context, AUTHORITY_ACTIVITIES_ABOUT_ME,
-                    accountId));
+            builder.setContentIntent(getContentIntent(context, CustomTabType.NOTIFICATIONS_TIMELINE,
+                    NotificationType.INTERACTIONS, accountId));
             if (timestamp != -1) {
-                builder.setDeleteIntent(getMarkReadDeleteIntent(context, AUTHORITY_ACTIVITIES_ABOUT_ME,
-                        accountId, timestamp, false));
+                builder.setDeleteIntent(getMarkReadDeleteIntent(context,
+                        NotificationType.INTERACTIONS, accountId, timestamp, false));
             }
         } finally {
             c.close();
@@ -1367,7 +1377,9 @@ public final class TwidereDataProvider extends ContentProvider implements Consta
         mNotificationManager.notify("interactions", notificationId, builder.build());
     }
 
-    private PendingIntent getContentIntent(Context context, String type, long accountId) {
+    private PendingIntent getContentIntent(final Context context, @CustomTabType final String type,
+                                           @NotificationType final String notificationType,
+                                           final long accountId) {
         // Setup click intent
         final Intent homeIntent = new Intent(context, HomeActivity.class);
         final Uri.Builder homeLinkBuilder = new Uri.Builder();
@@ -1381,8 +1393,10 @@ public final class TwidereDataProvider extends ContentProvider implements Consta
         return PendingIntent.getActivity(context, 0, homeIntent, 0);
     }
 
-    private PendingIntent getStatusContentIntent(Context context, String type, long accountId,
-                                                 long statusId, long userId, boolean userFollowing) {
+    private PendingIntent getStatusContentIntent(final Context context, @CustomTabType final String type,
+                                                 @NotificationType final String notificationType,
+                                                 long accountId, long statusId,
+                                                 long userId, boolean userFollowing) {
         // Setup click intent
         final Intent homeIntent = new Intent(Intent.ACTION_VIEW);
         homeIntent.setPackage(BuildConfig.APPLICATION_ID);
@@ -1543,8 +1557,10 @@ public final class TwidereDataProvider extends ContentProvider implements Consta
             builder.setContentTitle(notificationTitle);
             builder.setContentText(notificationContent);
             builder.setCategory(NotificationCompat.CATEGORY_MESSAGE);
-            builder.setContentIntent(getContentIntent(context, AUTHORITY_DIRECT_MESSAGES, accountId));
-            builder.setDeleteIntent(getMarkReadDeleteIntent(context, AUTHORITY_DIRECT_MESSAGES, accountId, positions));
+            builder.setContentIntent(getContentIntent(context, CustomTabType.DIRECT_MESSAGES,
+                    NotificationType.DIRECT_MESSAGES, accountId));
+            builder.setDeleteIntent(getMarkReadDeleteIntent(context,
+                    NotificationType.DIRECT_MESSAGES, accountId, positions));
             builder.setNumber(messagesCount);
             builder.setWhen(when);
             builder.setStyle(style);
diff --git a/twidere/src/main/java/org/mariotaku/twidere/receiver/NotificationReceiver.java b/twidere/src/main/java/org/mariotaku/twidere/receiver/NotificationReceiver.java
index 77528cd87..4eb40d21b 100644
--- a/twidere/src/main/java/org/mariotaku/twidere/receiver/NotificationReceiver.java
+++ b/twidere/src/main/java/org/mariotaku/twidere/receiver/NotificationReceiver.java
@@ -23,12 +23,16 @@ import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
 import android.net.Uri;
-import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
 import android.text.TextUtils;
 
 import org.apache.commons.lang3.math.NumberUtils;
 import org.mariotaku.twidere.Constants;
+import org.mariotaku.twidere.annotation.CustomTabType;
+import org.mariotaku.twidere.annotation.NotificationType;
+import org.mariotaku.twidere.annotation.ReadPositionTag;
 import org.mariotaku.twidere.model.StringLongPair;
+import org.mariotaku.twidere.util.CustomTabUtils;
 import org.mariotaku.twidere.util.ReadStateManager;
 import org.mariotaku.twidere.util.UriExtraUtils;
 import org.mariotaku.twidere.util.Utils;
@@ -50,20 +54,23 @@ public class NotificationReceiver extends BroadcastReceiver implements Constants
                 final Uri uri = intent.getData();
                 if (uri == null) return;
                 DependencyHolder holder = DependencyHolder.get(context);
-                final String type = uri.getQueryParameter(QUERY_PARAM_NOTIFICATION_TYPE);
+                @NotificationType
+                final String notificationType = uri.getQueryParameter(QUERY_PARAM_NOTIFICATION_TYPE);
                 final long accountId = NumberUtils.toLong(uri.getQueryParameter(QUERY_PARAM_ACCOUNT_ID), -1);
                 final long itemId = NumberUtils.toLong(UriExtraUtils.getExtra(uri, "item_id"), -1);
                 final long itemUserId = NumberUtils.toLong(UriExtraUtils.getExtra(uri, "item_user_id"), -1);
                 final boolean itemUserFollowing = Boolean.parseBoolean(UriExtraUtils.getExtra(uri, "item_user_following"));
                 final long timestamp = NumberUtils.toLong(uri.getQueryParameter(QUERY_PARAM_TIMESTAMP), -1);
-                if (AUTHORITY_MENTIONS.equals(type) && accountId != -1 && itemId != -1 && timestamp != -1) {
+                if (CustomTabType.NOTIFICATIONS_TIMELINE.equals(CustomTabUtils.getTabTypeAlias(notificationType))
+                        && accountId != -1 && itemId != -1 && timestamp != -1) {
                     final HotMobiLogger logger = holder.getHotMobiLogger();
-                    logger.log(accountId, NotificationEvent.deleted(context, timestamp, type, accountId,
+                    logger.log(accountId, NotificationEvent.deleted(context, timestamp, notificationType, accountId,
                             itemId, itemUserId, itemUserFollowing));
                 }
                 final ReadStateManager manager = holder.getReadStateManager();
                 final String paramReadPosition, paramReadPositions;
-                final String tag = getPositionTag(type);
+                @ReadPositionTag
+                final String tag = getPositionTag(notificationType);
                 if (tag != null && !TextUtils.isEmpty(paramReadPosition = uri.getQueryParameter(QUERY_PARAM_READ_POSITION))) {
                     final long def = -1;
                     manager.setPosition(Utils.getReadPositionTagWithAccounts(tag, accountId),
@@ -83,17 +90,17 @@ public class NotificationReceiver extends BroadcastReceiver implements Constants
         }
     }
 
-    private static String getPositionTag(@NonNull String type) {
+    @ReadPositionTag
+    @Nullable
+    private static String getPositionTag(@Nullable @NotificationType String type) {
+        if (type == null) return null;
         switch (type) {
-            case AUTHORITY_HOME: {
-                return TAB_TYPE_HOME_TIMELINE;
-            }
-            case AUTHORITY_ACTIVITIES_ABOUT_ME:
-            case AUTHORITY_MENTIONS: {
-                return TAB_TYPE_NOTIFICATIONS_TIMELINE;
-            }
-            case AUTHORITY_DIRECT_MESSAGES: {
-                return TAB_TYPE_DIRECT_MESSAGES;
+            case NotificationType.HOME_TIMELINE:
+                return ReadPositionTag.HOME_TIMELINE;
+            case NotificationType.INTERACTIONS:
+                return ReadPositionTag.ACTIVITIES_ABOUT_ME;
+            case NotificationType.DIRECT_MESSAGES: {
+                return ReadPositionTag.DIRECT_MESSAGES;
             }
         }
         return null;
diff --git a/twidere/src/main/java/org/mariotaku/twidere/receiver/PowerStateReceiver.java b/twidere/src/main/java/org/mariotaku/twidere/receiver/PowerStateReceiver.java
index 2042e0bf3..c76704a9f 100644
--- a/twidere/src/main/java/org/mariotaku/twidere/receiver/PowerStateReceiver.java
+++ b/twidere/src/main/java/org/mariotaku/twidere/receiver/PowerStateReceiver.java
@@ -22,7 +22,6 @@ package org.mariotaku.twidere.receiver;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
-import android.widget.Toast;
 
 import edu.tsinghua.hotmobi.HotMobiLogger;
 
diff --git a/twidere/src/main/java/org/mariotaku/twidere/service/BackgroundOperationService.java b/twidere/src/main/java/org/mariotaku/twidere/service/BackgroundOperationService.java
index 2cb953de7..0ae4d680e 100644
--- a/twidere/src/main/java/org/mariotaku/twidere/service/BackgroundOperationService.java
+++ b/twidere/src/main/java/org/mariotaku/twidere/service/BackgroundOperationService.java
@@ -95,7 +95,6 @@ import java.io.File;
 import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.InputStream;
-import java.io.RandomAccessFile;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
diff --git a/twidere/src/main/java/org/mariotaku/twidere/util/AsyncTwitterWrapper.java b/twidere/src/main/java/org/mariotaku/twidere/util/AsyncTwitterWrapper.java
index 8dfaa172d..e04ce94cf 100644
--- a/twidere/src/main/java/org/mariotaku/twidere/util/AsyncTwitterWrapper.java
+++ b/twidere/src/main/java/org/mariotaku/twidere/util/AsyncTwitterWrapper.java
@@ -40,6 +40,7 @@ import org.apache.commons.lang3.ArrayUtils;
 import org.mariotaku.sqliteqb.library.Expression;
 import org.mariotaku.twidere.BuildConfig;
 import org.mariotaku.twidere.R;
+import org.mariotaku.twidere.annotation.ReadPositionTag;
 import org.mariotaku.twidere.api.twitter.Twitter;
 import org.mariotaku.twidere.api.twitter.TwitterException;
 import org.mariotaku.twidere.api.twitter.http.HttpResponseCode;
@@ -531,7 +532,7 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
             protected void getReadPosition(long accountId, Twitter twitter) {
                 try {
                     CursorTimestampResponse response = twitter.getActivitiesAboutMeUnread(true);
-                    final String tag = Utils.getReadPositionTagWithAccounts(READ_POSITION_TAG_ACTIVITIES_ABOUT_ME, accountIds);
+                    final String tag = Utils.getReadPositionTagWithAccounts(ReadPositionTag.ACTIVITIES_ABOUT_ME, accountIds);
                     mReadStateManager.setPosition(tag, response.getCursor(), false);
                 } catch (TwitterException e) {
                     // Ignore
diff --git a/twidere/src/main/java/org/mariotaku/twidere/util/CustomTabUtils.java b/twidere/src/main/java/org/mariotaku/twidere/util/CustomTabUtils.java
index cc00f1bc6..ae9eb60ce 100644
--- a/twidere/src/main/java/org/mariotaku/twidere/util/CustomTabUtils.java
+++ b/twidere/src/main/java/org/mariotaku/twidere/util/CustomTabUtils.java
@@ -36,6 +36,8 @@ import android.text.TextUtils;
 
 import org.mariotaku.twidere.Constants;
 import org.mariotaku.twidere.R;
+import org.mariotaku.twidere.annotation.CustomTabType;
+import org.mariotaku.twidere.annotation.ReadPositionTag;
 import org.mariotaku.twidere.fragment.support.ActivitiesAboutMeFragment;
 import org.mariotaku.twidere.fragment.support.ActivitiesByFriendsFragment;
 import org.mariotaku.twidere.fragment.support.DirectMessagesFragment;
@@ -66,42 +68,42 @@ public class CustomTabUtils implements Constants {
     private static final HashMap CUSTOM_TABS_ICON_NAME_MAP = new HashMap<>();
 
     static {
-        CUSTOM_TABS_CONFIGURATION_MAP.put(TAB_TYPE_HOME_TIMELINE, new CustomTabConfiguration(
+        CUSTOM_TABS_CONFIGURATION_MAP.put(CustomTabType.HOME_TIMELINE, new CustomTabConfiguration(
                 HomeTimelineFragment.class, R.string.home, R.drawable.ic_action_home,
                 CustomTabConfiguration.ACCOUNT_OPTIONAL, CustomTabConfiguration.FIELD_TYPE_NONE, 0, false));
 
-        CUSTOM_TABS_CONFIGURATION_MAP.put(TAB_TYPE_NOTIFICATIONS_TIMELINE, new CustomTabConfiguration(
+        CUSTOM_TABS_CONFIGURATION_MAP.put(CustomTabType.NOTIFICATIONS_TIMELINE, new CustomTabConfiguration(
                 ActivitiesAboutMeFragment.class, R.string.notifications, R.drawable.ic_action_notification,
                 CustomTabConfiguration.ACCOUNT_OPTIONAL, CustomTabConfiguration.FIELD_TYPE_NONE, 1, false,
                 ExtraConfiguration.newBoolean(EXTRA_MY_FOLLOWING_ONLY, R.string.following_only, false)));
 
-        CUSTOM_TABS_CONFIGURATION_MAP.put(TAB_TYPE_DIRECT_MESSAGES, new CustomTabConfiguration(
+        CUSTOM_TABS_CONFIGURATION_MAP.put(CustomTabType.DIRECT_MESSAGES, new CustomTabConfiguration(
                 DirectMessagesFragment.class, R.string.direct_messages, R.drawable.ic_action_message,
                 CustomTabConfiguration.ACCOUNT_OPTIONAL, CustomTabConfiguration.FIELD_TYPE_NONE, 2, false));
 
-        CUSTOM_TABS_CONFIGURATION_MAP.put(TAB_TYPE_TRENDS_SUGGESTIONS, new CustomTabConfiguration(
+        CUSTOM_TABS_CONFIGURATION_MAP.put(CustomTabType.TRENDS_SUGGESTIONS, new CustomTabConfiguration(
                 TrendsSuggestionsFragment.class, R.string.trends, R.drawable.ic_action_hashtag,
                 CustomTabConfiguration.ACCOUNT_NONE, CustomTabConfiguration.FIELD_TYPE_NONE, 3, true));
-        CUSTOM_TABS_CONFIGURATION_MAP.put(TAB_TYPE_FAVORITES, new CustomTabConfiguration(UserFavoritesFragment.class,
+        CUSTOM_TABS_CONFIGURATION_MAP.put(CustomTabType.FAVORITES, new CustomTabConfiguration(UserFavoritesFragment.class,
                 R.string.likes, R.drawable.ic_action_heart, CustomTabConfiguration.ACCOUNT_REQUIRED,
                 CustomTabConfiguration.FIELD_TYPE_USER, 4));
-        CUSTOM_TABS_CONFIGURATION_MAP.put(TAB_TYPE_USER_TIMELINE, new CustomTabConfiguration(
+        CUSTOM_TABS_CONFIGURATION_MAP.put(CustomTabType.USER_TIMELINE, new CustomTabConfiguration(
                 UserTimelineFragment.class, R.string.users_statuses, R.drawable.ic_action_quote,
                 CustomTabConfiguration.ACCOUNT_REQUIRED, CustomTabConfiguration.FIELD_TYPE_USER, 5));
-        CUSTOM_TABS_CONFIGURATION_MAP.put(TAB_TYPE_SEARCH_STATUSES, new CustomTabConfiguration(
+        CUSTOM_TABS_CONFIGURATION_MAP.put(CustomTabType.SEARCH_STATUSES, new CustomTabConfiguration(
                 StatusesSearchFragment.class, R.string.search_statuses, R.drawable.ic_action_search,
                 CustomTabConfiguration.ACCOUNT_REQUIRED, CustomTabConfiguration.FIELD_TYPE_TEXT, R.string.query,
                 EXTRA_QUERY, 6));
 
-        CUSTOM_TABS_CONFIGURATION_MAP.put(TAB_TYPE_LIST_TIMELINE, new CustomTabConfiguration(
+        CUSTOM_TABS_CONFIGURATION_MAP.put(CustomTabType.LIST_TIMELINE, new CustomTabConfiguration(
                 UserListTimelineFragment.class, R.string.list_timeline, R.drawable.ic_action_list,
                 CustomTabConfiguration.ACCOUNT_REQUIRED, CustomTabConfiguration.FIELD_TYPE_USER_LIST, 7));
 
-        CUSTOM_TABS_CONFIGURATION_MAP.put(TAB_TYPE_ACTIVITIES_BY_FRIENDS, new CustomTabConfiguration(
+        CUSTOM_TABS_CONFIGURATION_MAP.put(CustomTabType.ACTIVITIES_BY_FRIENDS, new CustomTabConfiguration(
                 ActivitiesByFriendsFragment.class, R.string.activities_by_friends,
                 R.drawable.ic_action_accounts, CustomTabConfiguration.ACCOUNT_REQUIRED,
                 CustomTabConfiguration.FIELD_TYPE_NONE, 9));
-        CUSTOM_TABS_CONFIGURATION_MAP.put(TAB_TYPE_RETWEETS_OF_ME, new CustomTabConfiguration(
+        CUSTOM_TABS_CONFIGURATION_MAP.put(CustomTabType.RETWEETS_OF_ME, new CustomTabConfiguration(
                 RetweetsOfMeFragment.class, R.string.retweets_of_me, R.drawable.ic_action_retweet,
                 CustomTabConfiguration.ACCOUNT_REQUIRED, CustomTabConfiguration.FIELD_TYPE_NONE, 10));
 
@@ -154,18 +156,22 @@ public class CustomTabUtils implements Constants {
                 .getColumnIndex(Tabs.TYPE), idxArguments = cur.getColumnIndex(Tabs.ARGUMENTS), idxExtras = cur
                 .getColumnIndex(Tabs.EXTRAS), idxPosition = cur.getColumnIndex(Tabs.POSITION);
         while (!cur.isAfterLast()) {
-            final String type = cur.getString(idxType);
+            @CustomTabType
+            final String type = getTabTypeAlias(cur.getString(idxType));
             final int position = cur.getInt(idxPosition);
             final String iconType = cur.getString(idxIcon);
             final String name = cur.getString(idxName);
             final Bundle args = ParseUtils.jsonToBundle(cur.getString(idxArguments));
+            @ReadPositionTag
             final String tag = getTagByType(type);
             args.putInt(EXTRA_TAB_POSITION, position);
             args.putBundle(EXTRA_EXTRAS, ParseUtils.jsonToBundle(cur.getString(idxExtras)));
             final CustomTabConfiguration conf = getTabConfiguration(type);
             final Class cls = conf != null ? conf.getFragmentClass() : InvalidTabFragment.class;
-            tabs.add(new SupportTabSpec(TextUtils.isEmpty(name) ? getTabTypeName(context, type) : name,
-                    getTabIconObject(iconType), type, cls, args, position, tag));
+            final String tabTypeName = getTabTypeName(context, type);
+            final Object tabIconObject = getTabIconObject(iconType);
+            tabs.add(new SupportTabSpec(TextUtils.isEmpty(name) ? tabTypeName : name, tabIconObject,
+                    type, cls, args, position, tag));
             cur.moveToNext();
         }
         cur.close();
@@ -174,13 +180,16 @@ public class CustomTabUtils implements Constants {
     }
 
     @Nullable
-    private static String getTagByType(@NonNull String tabType) {
+    @ReadPositionTag
+    private static String getTagByType(@NonNull @CustomTabType String tabType) {
         switch (getTabTypeAlias(tabType)) {
-            case TAB_TYPE_HOME_TIMELINE:
-            case TAB_TYPE_NOTIFICATIONS_TIMELINE:
-            case TAB_TYPE_ACTIVITIES_ABOUT_ME:
-            case TAB_TYPE_DIRECT_MESSAGES:
-                return tabType;
+            case CustomTabType.HOME_TIMELINE:
+                return ReadPositionTag.HOME_TIMELINE;
+            case "activities_about_me":
+            case CustomTabType.NOTIFICATIONS_TIMELINE:
+                return ReadPositionTag.ACTIVITIES_ABOUT_ME;
+            case CustomTabType.DIRECT_MESSAGES:
+                return ReadPositionTag.DIRECT_MESSAGES;
         }
         return null;
     }
@@ -194,12 +203,13 @@ public class CustomTabUtils implements Constants {
         return CUSTOM_TABS_CONFIGURATION_MAP.get(getTabTypeAlias(tabType));
     }
 
+    @CustomTabType
     public static String getTabTypeAlias(String key) {
         if (key == null) return null;
         switch (key) {
             case "mentions_timeline":
             case "activities_about_me":
-                return TAB_TYPE_NOTIFICATIONS_TIMELINE;
+                return CustomTabType.NOTIFICATIONS_TIMELINE;
         }
         return key;
     }
diff --git a/twidere/src/main/java/org/mariotaku/twidere/util/ReadStateManager.java b/twidere/src/main/java/org/mariotaku/twidere/util/ReadStateManager.java
index af5743d92..b7d03628b 100644
--- a/twidere/src/main/java/org/mariotaku/twidere/util/ReadStateManager.java
+++ b/twidere/src/main/java/org/mariotaku/twidere/util/ReadStateManager.java
@@ -27,6 +27,8 @@ import android.support.annotation.Nullable;
 import android.text.TextUtils;
 
 import org.mariotaku.twidere.Constants;
+import org.mariotaku.twidere.annotation.NotificationType;
+import org.mariotaku.twidere.annotation.ReadPositionTag;
 import org.mariotaku.twidere.model.StringLongPair;
 import org.mariotaku.twidere.util.collection.CompactHashSet;
 
@@ -144,14 +146,14 @@ public class ReadStateManager implements Constants {
         return true;
     }
 
-    public boolean setPosition(final String key, final long id) {
-        return setPosition(key, id, false);
+    public boolean setPosition(final String key, final long position) {
+        return setPosition(key, position, false);
     }
 
-    public boolean setPosition(final String key, final long id, boolean acceptOlder) {
-        if (TextUtils.isEmpty(key) || !acceptOlder && getPosition(key) >= id) return false;
+    public boolean setPosition(final String key, final long position, boolean acceptOlder) {
+        if (TextUtils.isEmpty(key) || !acceptOlder && getPosition(key) >= position) return false;
         final SharedPreferences.Editor editor = mPreferences.edit();
-        editor.putLong(key, id);
+        editor.putLong(key, position);
         editor.apply();
         return true;
     }
@@ -160,4 +162,16 @@ public class ReadStateManager implements Constants {
         void onReadStateChanged();
     }
 
+    @Nullable
+    @ReadPositionTag
+    public static String getReadPositionTagForNotificationType(@NotificationType String notificationType) {
+        if (notificationType == null) return null;
+        switch (notificationType) {
+            case NotificationType.INTERACTIONS: {
+                return ReadPositionTag.ACTIVITIES_ABOUT_ME;
+            }
+        }
+        return null;
+    }
+
 }
diff --git a/twidere/src/main/java/org/mariotaku/twidere/util/ThemedLayoutInflaterFactory.java b/twidere/src/main/java/org/mariotaku/twidere/util/ThemedLayoutInflaterFactory.java
index 12c15b496..45161783a 100644
--- a/twidere/src/main/java/org/mariotaku/twidere/util/ThemedLayoutInflaterFactory.java
+++ b/twidere/src/main/java/org/mariotaku/twidere/util/ThemedLayoutInflaterFactory.java
@@ -171,7 +171,6 @@ public class ThemedLayoutInflaterFactory implements LayoutInflaterFactory {
         } else {
             // View context is derived from ActionBar and it's light theme, so we use contrast color
             final int actionBarColor = activity.getCurrentThemeColor();
-            final int actionBarTheme = ThemeUtils.getActionBarThemeResource(activity.getThemeResourceId(), actionBarColor);
             accentColor = ThemeUtils.getColorFromAttribute(viewContext, android.R.attr.colorForeground, 0);
             noTintColor = ThemeUtils.getColorFromAttribute(viewContext, android.R.attr.colorBackground, 0);
             backgroundTintColor = accentColor;
diff --git a/twidere/src/main/java/org/mariotaku/twidere/util/Utils.java b/twidere/src/main/java/org/mariotaku/twidere/util/Utils.java
index 6aa1789db..84dd9d3ce 100644
--- a/twidere/src/main/java/org/mariotaku/twidere/util/Utils.java
+++ b/twidere/src/main/java/org/mariotaku/twidere/util/Utils.java
@@ -133,6 +133,8 @@ import org.mariotaku.twidere.activity.support.ColorPickerDialogActivity;
 import org.mariotaku.twidere.activity.support.MediaViewerActivity;
 import org.mariotaku.twidere.adapter.iface.IBaseAdapter;
 import org.mariotaku.twidere.adapter.iface.IBaseCardAdapter;
+import org.mariotaku.twidere.annotation.CustomTabType;
+import org.mariotaku.twidere.annotation.ReadPositionTag;
 import org.mariotaku.twidere.api.twitter.Twitter;
 import org.mariotaku.twidere.api.twitter.TwitterException;
 import org.mariotaku.twidere.api.twitter.model.DirectMessage;
@@ -288,10 +290,9 @@ public final class Utils implements Constants {
         LINK_HANDLER_URI_MATCHER.addURI(AUTHORITY_FILTERS, null, LINK_ID_FILTERS);
         LINK_HANDLER_URI_MATCHER.addURI(AUTHORITY_PROFILE_EDITOR, null, LINK_ID_PROFILE_EDITOR);
 
-        HOME_TABS_URI_MATCHER.addURI(AUTHORITY_HOME, null, TAB_CODE_HOME_TIMELINE);
-        HOME_TABS_URI_MATCHER.addURI(AUTHORITY_MENTIONS, null, TAB_CODE_NOTIFICATIONS_TIMELINE);
-        HOME_TABS_URI_MATCHER.addURI(AUTHORITY_ACTIVITIES_ABOUT_ME, null, TAB_CODE_NOTIFICATIONS_TIMELINE);
-        HOME_TABS_URI_MATCHER.addURI(AUTHORITY_DIRECT_MESSAGES, null, TAB_CODE_DIRECT_MESSAGES);
+        HOME_TABS_URI_MATCHER.addURI(CustomTabType.HOME_TIMELINE, null, TAB_CODE_HOME_TIMELINE);
+        HOME_TABS_URI_MATCHER.addURI(CustomTabType.NOTIFICATIONS_TIMELINE, null, TAB_CODE_NOTIFICATIONS_TIMELINE);
+        HOME_TABS_URI_MATCHER.addURI(CustomTabType.DIRECT_MESSAGES, null, TAB_CODE_DIRECT_MESSAGES);
     }
 
 
@@ -921,7 +922,7 @@ public final class Utils implements Constants {
     }
 
 
-    public static String getReadPositionTagWithAccounts(String tag, Bundle args) {
+    public static String getReadPositionTagWithAccounts(@ReadPositionTag String tag, Bundle args) {
         final long[] accountIds = getAccountIds(args);
         return getReadPositionTagWithAccounts(tag, accountIds);
     }
@@ -938,7 +939,10 @@ public final class Utils implements Constants {
         return accountIds;
     }
 
-    public static String getReadPositionTagWithAccounts(String tag, long... accountIds) {
+    @Nullable
+    public static String getReadPositionTagWithAccounts(@Nullable @ReadPositionTag final String tag,
+                                                        final long... accountIds) {
+        if (tag == null) return null;
         if (accountIds == null || accountIds.length == 0 || (accountIds.length == 1 && accountIds[0] < 0))
             return tag;
         final long[] accountIdsClone = accountIds.clone();
@@ -946,7 +950,11 @@ public final class Utils implements Constants {
         return tag + "_" + TwidereArrayUtils.toString(accountIdsClone, '_', false);
     }
 
-    public static String getReadPositionTagWithAccounts(Context context, boolean activatedIfMissing, String tag, long... accountIds) {
+    @Nullable
+    public static String getReadPositionTagWithAccounts(Context context, boolean activatedIfMissing,
+                                                        @Nullable @ReadPositionTag String tag,
+                                                        long... accountIds) {
+        if (tag == null) return null;
         if (accountIds == null || accountIds.length == 0 || (accountIds.length == 1 && accountIds[0] < 0)) {
             final long[] activatedIds = DataStoreUtils.getActivatedAccountIds(context);
             Arrays.sort(activatedIds);
@@ -1811,13 +1819,13 @@ public final class Utils implements Constants {
     public static String getTabType(final int code) {
         switch (code) {
             case TAB_CODE_HOME_TIMELINE: {
-                return TAB_TYPE_HOME_TIMELINE;
+                return CustomTabType.HOME_TIMELINE;
             }
             case TAB_CODE_NOTIFICATIONS_TIMELINE: {
-                return TAB_TYPE_NOTIFICATIONS_TIMELINE;
+                return CustomTabType.NOTIFICATIONS_TIMELINE;
             }
             case TAB_CODE_DIRECT_MESSAGES: {
-                return TAB_TYPE_DIRECT_MESSAGES;
+                return CustomTabType.DIRECT_MESSAGES;
             }
         }
         return null;
diff --git a/twidere/src/main/java/org/mariotaku/twidere/view/HeaderDrawerLayout.java b/twidere/src/main/java/org/mariotaku/twidere/view/HeaderDrawerLayout.java
index 786318a05..d83930864 100644
--- a/twidere/src/main/java/org/mariotaku/twidere/view/HeaderDrawerLayout.java
+++ b/twidere/src/main/java/org/mariotaku/twidere/view/HeaderDrawerLayout.java
@@ -194,6 +194,7 @@ public class HeaderDrawerLayout extends ViewGroup {
 
     @Override
     protected void onFinishInflate() {
+        super.onFinishInflate();
         if (getChildCount() != 1) {
             throw new IllegalArgumentException("Add subview by XML is not allowed.");
         }
diff --git a/twidere/src/main/java/org/mariotaku/twidere/view/NameView.java b/twidere/src/main/java/org/mariotaku/twidere/view/NameView.java
index 9389bbcd3..b4c58ed2a 100644
--- a/twidere/src/main/java/org/mariotaku/twidere/view/NameView.java
+++ b/twidere/src/main/java/org/mariotaku/twidere/view/NameView.java
@@ -42,6 +42,7 @@ import org.mariotaku.twidere.view.themed.ThemedTextView;
 public class NameView extends ThemedTextView {
 
     private boolean mNameFirst;
+    private boolean mTwoLine;
 
     private String mName, mScreenName;
 
@@ -59,11 +60,16 @@ public class NameView extends ThemedTextView {
 
     public NameView(final Context context, final AttributeSet attrs, final int defStyleAttr) {
         super(context, attrs, defStyleAttr);
-        setSingleLine(true);
         setEllipsize(TextUtils.TruncateAt.END);
         final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.NameView, defStyleAttr, 0);
         setPrimaryTextColor(a.getColor(R.styleable.NameView_nv_primaryTextColor, 0));
         setSecondaryTextColor(a.getColor(R.styleable.NameView_nv_secondaryTextColor, 0));
+        if (mTwoLine = a.getBoolean(R.styleable.NameView_nv_twoLine, false)) {
+            setSingleLine(false);
+            setMaxLines(2);
+        } else {
+            setSingleLine(true);
+        }
         mPrimaryTextStyle = new StyleSpan(a.getInt(R.styleable.NameView_nv_primaryTextStyle, 0));
         mSecondaryTextStyle = new StyleSpan(a.getInt(R.styleable.NameView_nv_secondaryTextStyle, 0));
         a.recycle();
@@ -115,7 +121,7 @@ public class NameView extends ThemedTextView {
             sb.setSpan(mPrimaryTextStyle, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
             sb.setSpan(mPrimaryTextSize, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
         }
-        sb.append(" ");
+        sb.append(mTwoLine ? "\n" : "");
         if (secondaryText != null) {
             int start = sb.length();
             if (formatter != null && !isInEditMode()) {
diff --git a/twidere/src/main/java/org/mariotaku/twidere/view/ProfileBannerSpace.java b/twidere/src/main/java/org/mariotaku/twidere/view/ProfileBannerSpace.java
index 388eb8688..131ef5483 100644
--- a/twidere/src/main/java/org/mariotaku/twidere/view/ProfileBannerSpace.java
+++ b/twidere/src/main/java/org/mariotaku/twidere/view/ProfileBannerSpace.java
@@ -1,5 +1,6 @@
 package org.mariotaku.twidere.view;
 
+import android.annotation.SuppressLint;
 import android.content.Context;
 import android.graphics.Canvas;
 import android.graphics.Rect;
@@ -43,6 +44,7 @@ public class ProfileBannerSpace extends View {
      *
      * @param canvas an unused parameter.
      */
+    @SuppressLint("MissingSuperCall")
     @Override
     public void draw(@NonNull final Canvas canvas) {
     }
diff --git a/twidere/src/main/java/org/mariotaku/twidere/view/holder/UserViewHolder.java b/twidere/src/main/java/org/mariotaku/twidere/view/holder/UserViewHolder.java
index f060b84d1..459eb7f8d 100644
--- a/twidere/src/main/java/org/mariotaku/twidere/view/holder/UserViewHolder.java
+++ b/twidere/src/main/java/org/mariotaku/twidere/view/holder/UserViewHolder.java
@@ -33,7 +33,7 @@ import org.mariotaku.twidere.adapter.iface.IUsersAdapter;
 import org.mariotaku.twidere.model.ParcelableUser;
 import org.mariotaku.twidere.util.MediaLoaderWrapper;
 import org.mariotaku.twidere.util.UserColorNameManager;
-import org.mariotaku.twidere.view.ShapedImageView;
+import org.mariotaku.twidere.view.NameView;
 import org.mariotaku.twidere.view.iface.IColorLabelView;
 
 import java.util.Locale;
@@ -48,7 +48,8 @@ public class UserViewHolder extends ViewHolder implements OnClickListener, OnLon
     private final IColorLabelView itemContent;
     private final ImageView profileImageView;
     private final ImageView profileTypeView;
-    private final TextView nameView, screenNameView, descriptionView, locationView, urlView,
+    private final NameView nameView;
+    private final TextView descriptionView, locationView, urlView,
             statusesCountView, followersCountView, friendsCountView;
 
     private UserClickListener userClickListener;
@@ -59,8 +60,7 @@ public class UserViewHolder extends ViewHolder implements OnClickListener, OnLon
         itemContent = (IColorLabelView) itemView.findViewById(R.id.item_content);
         profileImageView = (ImageView) itemView.findViewById(R.id.profile_image);
         profileTypeView = (ImageView) itemView.findViewById(R.id.profile_type);
-        nameView = (TextView) itemView.findViewById(R.id.name);
-        screenNameView = (TextView) itemView.findViewById(R.id.screen_name);
+        nameView = (NameView) itemView.findViewById(R.id.name);
         descriptionView = (TextView) itemView.findViewById(R.id.description);
         locationView = (TextView) itemView.findViewById(R.id.location);
         urlView = (TextView) itemView.findViewById(R.id.url);
@@ -83,8 +83,8 @@ public class UserViewHolder extends ViewHolder implements OnClickListener, OnLon
         } else {
             profileTypeView.setImageDrawable(null);
         }
-        nameView.setText(manager.getUserNickname(user.id, user.name, false));
-        screenNameView.setText("@" + user.screen_name);
+        nameView.setName(manager.getUserNickname(user.id, user.name, false));
+        nameView.setScreenName("@" + user.screen_name);
         descriptionView.setVisibility(TextUtils.isEmpty(user.description_unescaped) ? View.GONE : View.VISIBLE);
         descriptionView.setText(user.description_unescaped);
         locationView.setVisibility(TextUtils.isEmpty(user.location) ? View.GONE : View.VISIBLE);
@@ -141,7 +141,6 @@ public class UserViewHolder extends ViewHolder implements OnClickListener, OnLon
     public void setTextSize(final float textSize) {
         descriptionView.setTextSize(textSize);
         nameView.setTextSize(textSize);
-        screenNameView.setTextSize(textSize * 0.75f);
         locationView.setTextSize(textSize);
         urlView.setTextSize(textSize);
         statusesCountView.setTextSize(textSize);
diff --git a/twidere/src/main/java/org/oshkimaadziig/george/androidutils/SpanFormatter.java b/twidere/src/main/java/org/oshkimaadziig/george/androidutils/SpanFormatter.java
index 6bd08caa8..07318b49c 100644
--- a/twidere/src/main/java/org/oshkimaadziig/george/androidutils/SpanFormatter.java
+++ b/twidere/src/main/java/org/oshkimaadziig/george/androidutils/SpanFormatter.java
@@ -33,6 +33,7 @@ import java.util.regex.Pattern;
  *
  * @author George T. Steel
  */
+@SuppressWarnings("IfCanBeSwitch")
 public class SpanFormatter {
     public static final Pattern FORMAT_SEQUENCE = Pattern.compile("%([0-9]+\\$|
             
diff --git a/twidere/src/main/res/layout/card_item_status_common.xml b/twidere/src/main/res/layout/card_item_status_common.xml
index 037623aef..a411ce9ce 100644
--- a/twidere/src/main/res/layout/card_item_status_common.xml
+++ b/twidere/src/main/res/layout/card_item_status_common.xml
@@ -198,7 +198,7 @@
             android:id="@+id/quote_indicator"
             android:layout_width="@dimen/element_spacing_small"
             android:layout_height="wrap_content"
-            android:layout_alignBottom="@+id/quoted_text"
+            android:layout_alignBottom="@+id/media_preview"
             android:layout_alignTop="@+id/quoted_name"
             android:layout_marginLeft="@dimen/element_spacing_normal"
             android:layout_marginStart="@dimen/element_spacing_normal"
diff --git a/twidere/src/main/res/layout/card_item_user.xml b/twidere/src/main/res/layout/card_item_user.xml
index 3317bb2af..adb6384f9 100644
--- a/twidere/src/main/res/layout/card_item_user.xml
+++ b/twidere/src/main/res/layout/card_item_user.xml
@@ -17,10 +17,11 @@
   ~  along with this program.  If not, see .
   -->
 
-
+                android:scaleType="fitCenter"
+                tools:src="@mipmap/ic_launcher"/>
 
             
+                tools:ignore="ContentDescription"/>
 
-            
+                android:paddingStart="8dp"/>
 
-                
-
-                
-            
         
 
         
+            android:textColor="?android:attr/textColorSecondary"
+            tools:text="@string/sample_status_text"/>
 
         
+            android:textAppearance="?android:attr/textAppearanceSmall"
+            tools:text="Earth"/>
 
         
+            android:textAppearance="?android:attr/textAppearanceSmall"
+            tools:text="https://github.com/TwidereProject"/>
 
         
+                android:textAppearance="?android:attr/textAppearanceSmall"
+                tools:text="255"/>
 
             
+                android:textAppearance="?android:attr/textAppearanceSmall"
+                tools:text="255"/>
 
             
+                android:textAppearance="?android:attr/textAppearanceSmall"
+                tools:text="255"/>
         
 
     
diff --git a/twidere/src/main/res/layout/card_item_user_compact.xml b/twidere/src/main/res/layout/card_item_user_compact.xml
index 37e9896ae..ef66848e1 100644
--- a/twidere/src/main/res/layout/card_item_user_compact.xml
+++ b/twidere/src/main/res/layout/card_item_user_compact.xml
@@ -17,9 +17,11 @@
   ~  along with this program.  If not, see .
   -->
 
-
+            android:contentDescription="@string/profile_image"
+            tools:src="@mipmap/ic_launcher"/>
 
         
+            tools:ignore="ContentDescription"/>
 
-        
+            android:layout_toRightOf="@id/profile_image"
+            app:nv_primaryTextColor="?android:attr/textColorPrimary"
+            app:nv_primaryTextStyle="bold"/>
 
-            
-
-                
-
-                
-            
-        
 
         
+            android:textColor="?android:attr/textColorSecondary"
+            tools:text="@string/sample_status_text"/>
 
         
+            android:textAppearance="?android:attr/textAppearanceSmall"
+            tools:text="Earth"/>
 
         
+            android:textAppearance="?android:attr/textAppearanceSmall"
+            tools:text="https://github.com/TwidereProject"/>
 
         
@@ -161,7 +141,8 @@
                 android:drawablePadding="@dimen/element_spacing_small"
                 android:drawableStart="@drawable/ic_indicator_twitter"
                 android:singleLine="true"
-                android:textAppearance="?android:attr/textAppearanceSmall" />
+                android:textAppearance="?android:attr/textAppearanceSmall"
+                tools:text="255"/>
 
             
+                android:textAppearance="?android:attr/textAppearanceSmall"
+                tools:text="255"/>
 
             
+                android:textAppearance="?android:attr/textAppearanceSmall"
+                tools:text="255"/>
         
     
 
diff --git a/twidere/src/main/res/layout/popup_account_selector.xml b/twidere/src/main/res/layout/popup_account_selector.xml
deleted file mode 100644
index 8cc76fdf6..000000000
--- a/twidere/src/main/res/layout/popup_account_selector.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-
-
-
-
\ No newline at end of file
diff --git a/twidere/src/main/res/menu/action_direct_message.xml b/twidere/src/main/res/menu/action_direct_message.xml
index 8ee65c065..80b91b8e7 100644
--- a/twidere/src/main/res/menu/action_direct_message.xml
+++ b/twidere/src/main/res/menu/action_direct_message.xml
@@ -6,18 +6,8 @@
         android:icon="@drawable/ic_action_copy"
         android:title="@android:string/copy"/>
     
-        
-            
-            
-        
-    
+        android:title="@string/delete"/>
 
 
\ No newline at end of file
diff --git a/twidere/src/main/res/menu/action_status_text_selection.xml b/twidere/src/main/res/menu/action_status_text_selection.xml
index 17bb5ff38..3f3008ce5 100644
--- a/twidere/src/main/res/menu/action_status_text_selection.xml
+++ b/twidere/src/main/res/menu/action_status_text_selection.xml
@@ -5,7 +5,7 @@
     
 
 
\ No newline at end of file
diff --git a/twidere/src/main/res/values/attrs.xml b/twidere/src/main/res/values/attrs.xml
index 0a0df8c84..7aa0e6d6b 100644
--- a/twidere/src/main/res/values/attrs.xml
+++ b/twidere/src/main/res/values/attrs.xml
@@ -55,6 +55,7 @@
     
         
         
+        
         
         
     
diff --git a/twidere/src/main/svg/drawable/ic_stat_notification-mdpi.svg b/twidere/src/main/svg/drawable/ic_stat_notification-mdpi.svg
new file mode 100644
index 000000000..7424601b3
--- /dev/null
+++ b/twidere/src/main/svg/drawable/ic_stat_notification-mdpi.svg
@@ -0,0 +1,12 @@
+
+
+    
+    Artboard
+    Created with Sketch.
+    
+    
+        
+            
+        
+    
+
\ No newline at end of file