diff --git a/java/src/com/android/textclassifier/ActionsModelParamsSupplier.java b/java/src/com/android/textclassifier/ActionsModelParamsSupplier.java
index 8d122ad..a1bf109 100644
--- a/java/src/com/android/textclassifier/ActionsModelParamsSupplier.java
+++ b/java/src/com/android/textclassifier/ActionsModelParamsSupplier.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2018 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -11,202 +11,191 @@
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
  */
+
 package com.android.textclassifier;
 
-import android.content.ContentResolver;
 import android.content.Context;
 import android.database.ContentObserver;
 import android.provider.Settings;
-
 import androidx.annotation.GuardedBy;
-import androidx.annotation.Nullable;
-import androidx.annotation.VisibleForTesting;
-import androidx.core.util.Preconditions;
-
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Preconditions;
 import java.lang.ref.WeakReference;
 import java.util.Objects;
 import java.util.function.Supplier;
+import javax.annotation.Nullable;
 
 /** Parses the {@link Settings.Global#TEXT_CLASSIFIER_ACTION_MODEL_PARAMS} flag. */
+// TODO(tonymak): Re-enable this class.
 public final class ActionsModelParamsSupplier
-        implements Supplier<ActionsModelParamsSupplier.ActionsModelParams> {
-    private static final String TAG = "ActionsModelParamsSupplier";
+    implements Supplier<ActionsModelParamsSupplier.ActionsModelParams> {
+  private static final String TAG = "ActionsModelParams";
 
-    @VisibleForTesting static final String KEY_REQUIRED_MODEL_VERSION = "required_model_version";
-    @VisibleForTesting static final String KEY_REQUIRED_LOCALES = "required_locales";
+  @VisibleForTesting static final String KEY_REQUIRED_MODEL_VERSION = "required_model_version";
+  @VisibleForTesting static final String KEY_REQUIRED_LOCALES = "required_locales";
 
-    @VisibleForTesting
-    static final String KEY_SERIALIZED_PRECONDITIONS = "serialized_preconditions";
+  @VisibleForTesting static final String KEY_SERIALIZED_PRECONDITIONS = "serialized_preconditions";
 
-    private final Context mAppContext;
-    private final SettingsObserver mSettingsObserver;
+  private final Context appContext;
+  private final SettingsObserver settingsObserver;
 
-    private final Object mLock = new Object();
-    private final Runnable mOnChangedListener;
+  private final Object lock = new Object();
+  private final Runnable onChangedListener;
 
-    @Nullable
-    @GuardedBy("mLock")
-    private ActionsModelParams mActionsModelParams;
+  @Nullable
+  @GuardedBy("lock")
+  private ActionsModelParams actionsModelParams;
 
-    @GuardedBy("mLock")
-    private boolean mParsed = true;
+  @GuardedBy("lock")
+  private boolean parsed = true;
 
-    public ActionsModelParamsSupplier(Context context, @Nullable Runnable onChangedListener) {
-        mAppContext = Preconditions.checkNotNull(context).getApplicationContext();
-        mOnChangedListener = onChangedListener == null ? () -> {} : onChangedListener;
-        mSettingsObserver =
-                new SettingsObserver(
-                        mAppContext,
-                        () -> {
-                            synchronized (mLock) {
-                                TcLog.v(
-                                        TAG,
-                                        "Settings.Global.TEXT_CLASSIFIER_ACTION_MODEL_PARAMS is"
-                                                + " updated");
-                                mParsed = true;
-                                mOnChangedListener.run();
-                            }
-                        });
+  public ActionsModelParamsSupplier(Context context, @Nullable Runnable onChangedListener) {
+    appContext = Preconditions.checkNotNull(context).getApplicationContext();
+    this.onChangedListener = onChangedListener == null ? () -> {} : onChangedListener;
+    settingsObserver =
+        new SettingsObserver(
+            appContext,
+            () -> {
+              synchronized (lock) {
+                TcLog.v(TAG, "Settings.Global.TEXT_CLASSIFIER_ACTION_MODEL_PARAMS is updated");
+                parsed = true;
+                this.onChangedListener.run();
+              }
+            });
+  }
+
+  /**
+   * Returns the parsed actions params or {@link ActionsModelParams#INVALID} if the value is
+   * invalid.
+   */
+  @Override
+  public ActionsModelParams get() {
+    synchronized (lock) {
+      if (parsed) {
+        actionsModelParams = parse();
+        parsed = false;
+      }
+      return actionsModelParams;
+    }
+  }
+
+  private static ActionsModelParams parse() {
+    //        String settingStr = Settings.Global.getString(contentResolver,
+    //                Settings.Global.TEXT_CLASSIFIER_ACTION_MODEL_PARAMS);
+    //        if (TextUtils.isEmpty(settingStr)) {
+    //            return ActionsModelParams.INVALID;
+    //        }
+    //        try {
+    //            KeyValueListParser keyValueListParser = new KeyValueListParser(',');
+    //            keyValueListParser.setString(settingStr);
+    //            int version = keyValueListParser.getInt(KEY_REQUIRED_MODEL_VERSION, -1);
+    //            if (version == -1) {
+    //                TcLog.w(TAG, "ActionsModelParams.Parse, invalid model version");
+    //                return ActionsModelParams.INVALID;
+    //            }
+    //            String locales = keyValueListParser.getString(KEY_REQUIRED_LOCALES, null);
+    //            if (locales == null) {
+    //                TcLog.w(TAG, "ActionsModelParams.Parse, invalid locales");
+    //                return ActionsModelParams.INVALID;
+    //            }
+    //            String serializedPreconditionsStr =
+    //                    keyValueListParser.getString(KEY_SERIALIZED_PRECONDITIONS, null);
+    //            if (serializedPreconditionsStr == null) {
+    //                TcLog.w(TAG, "ActionsModelParams.Parse, invalid preconditions");
+    //                return ActionsModelParams.INVALID;
+    //            }
+    //            byte[] serializedPreconditions =
+    //                    Base64.decode(serializedPreconditionsStr, Base64.NO_WRAP);
+    //            return new ActionsModelParams(version, locales, serializedPreconditions);
+    //        } catch (Throwable t) {
+    //            TcLog.e(TAG, "Invalid TEXT_CLASSIFIER_ACTION_MODEL_PARAMS, ignore", t);
+    //        }
+    return ActionsModelParams.INVALID;
+  }
+
+  @Override
+  protected void finalize() throws Throwable {
+    try {
+      appContext.getContentResolver().unregisterContentObserver(settingsObserver);
+    } finally {
+      super.finalize();
+    }
+  }
+
+  /** Represents the parsed result. */
+  public static final class ActionsModelParams {
+
+    public static final ActionsModelParams INVALID = new ActionsModelParams(-1, "", new byte[0]);
+
+    /** The required model version to apply {@code serializedPreconditions}. */
+    private final int requiredModelVersion;
+
+    /** The required model locales to apply {@code serializedPreconditions}. */
+    private final String requiredModelLocales;
+
+    /**
+     * The serialized params that will be applied to the model file, if all requirements are met. Do
+     * not modify.
+     */
+    private final byte[] serializedPreconditions;
+
+    public ActionsModelParams(
+        int requiredModelVersion, String requiredModelLocales, byte[] serializedPreconditions) {
+      this.requiredModelVersion = requiredModelVersion;
+      this.requiredModelLocales = Preconditions.checkNotNull(requiredModelLocales);
+      this.serializedPreconditions = Preconditions.checkNotNull(serializedPreconditions);
     }
 
     /**
-     * Returns the parsed actions params or {@link ActionsModelParams#INVALID} if the value is
-     * invalid.
+     * Returns the serialized preconditions. Returns {@code null} if the model in use does not meet
+     * all the requirements listed in the {@code ActionsModelParams} or the params are invalid.
      */
-    @Override
-    public ActionsModelParams get() {
-        synchronized (mLock) {
-            if (mParsed) {
-                mActionsModelParams = parse(mAppContext.getContentResolver());
-                mParsed = false;
-            }
-            return mActionsModelParams;
-        }
+    @Nullable
+    public byte[] getSerializedPreconditions(ModelFileManager.ModelFile modelInUse) {
+      if (this == INVALID) {
+        return null;
+      }
+      if (modelInUse.getVersion() != requiredModelVersion) {
+        TcLog.w(
+            TAG,
+            String.format(
+                "Not applying mSerializedPreconditions, required version=%d, actual=%d",
+                requiredModelVersion, modelInUse.getVersion()));
+        return null;
+      }
+      if (!Objects.equals(modelInUse.getSupportedLocalesStr(), requiredModelLocales)) {
+        TcLog.w(
+            TAG,
+            String.format(
+                "Not applying mSerializedPreconditions, required locales=%s, actual=%s",
+                requiredModelLocales, modelInUse.getSupportedLocalesStr()));
+        return null;
+      }
+      return serializedPreconditions;
     }
+  }
 
-    private ActionsModelParams parse(ContentResolver contentResolver) {
-        //        String settingStr = Settings.Global.getString(contentResolver,
-        //                Settings.Global.TEXT_CLASSIFIER_ACTION_MODEL_PARAMS);
-        //        if (TextUtils.isEmpty(settingStr)) {
-        //            return ActionsModelParams.INVALID;
-        //        }
-        //        try {
-        //            KeyValueListParser keyValueListParser = new KeyValueListParser(',');
-        //            keyValueListParser.setString(settingStr);
-        //            int version = keyValueListParser.getInt(KEY_REQUIRED_MODEL_VERSION, -1);
-        //            if (version == -1) {
-        //                TcLog.w(TAG, "ActionsModelParams.Parse, invalid model version");
-        //                return ActionsModelParams.INVALID;
-        //            }
-        //            String locales = keyValueListParser.getString(KEY_REQUIRED_LOCALES, null);
-        //            if (locales == null) {
-        //                TcLog.w(TAG, "ActionsModelParams.Parse, invalid locales");
-        //                return ActionsModelParams.INVALID;
-        //            }
-        //            String serializedPreconditionsStr =
-        //                    keyValueListParser.getString(KEY_SERIALIZED_PRECONDITIONS, null);
-        //            if (serializedPreconditionsStr == null) {
-        //                TcLog.w(TAG, "ActionsModelParams.Parse, invalid preconditions");
-        //                return ActionsModelParams.INVALID;
-        //            }
-        //            byte[] serializedPreconditions =
-        //                    Base64.decode(serializedPreconditionsStr, Base64.NO_WRAP);
-        //            return new ActionsModelParams(version, locales, serializedPreconditions);
-        //        } catch (Throwable t) {
-        //            TcLog.e(TAG, "Invalid TEXT_CLASSIFIER_ACTION_MODEL_PARAMS, ignore", t);
-        //        }
-        return ActionsModelParams.INVALID;
+  private static final class SettingsObserver extends ContentObserver {
+
+    private final WeakReference<Runnable> onChangedListener;
+
+    SettingsObserver(Context appContext, Runnable listener) {
+      super(null);
+      onChangedListener = new WeakReference<>(listener);
+      //            appContext.getContentResolver().registerContentObserver(
+      //
+      // Settings.Global.getUriFor(Settings.Global.TEXT_CLASSIFIER_ACTION_MODEL_PARAMS),
+      //                    false /* notifyForDescendants */,
+      //                    this);
     }
 
     @Override
-    protected void finalize() throws Throwable {
-        try {
-            mAppContext.getContentResolver().unregisterContentObserver(mSettingsObserver);
-        } finally {
-            super.finalize();
-        }
+    public void onChange(boolean selfChange) {
+      if (onChangedListener.get() != null) {
+        onChangedListener.get().run();
+      }
     }
-
-    /** Represents the parsed result. */
-    public static final class ActionsModelParams {
-
-        public static final ActionsModelParams INVALID =
-                new ActionsModelParams(-1, "", new byte[0]);
-
-        /** The required model version to apply {@code mSerializedPreconditions}. */
-        private final int mRequiredModelVersion;
-
-        /** The required model locales to apply {@code mSerializedPreconditions}. */
-        private final String mRequiredModelLocales;
-
-        /**
-         * The serialized params that will be applied to the model file, if all requirements are
-         * met. Do not modify.
-         */
-        private final byte[] mSerializedPreconditions;
-
-        public ActionsModelParams(
-                int requiredModelVersion,
-                String requiredModelLocales,
-                byte[] serializedPreconditions) {
-            mRequiredModelVersion = requiredModelVersion;
-            mRequiredModelLocales = Preconditions.checkNotNull(requiredModelLocales);
-            mSerializedPreconditions = Preconditions.checkNotNull(serializedPreconditions);
-        }
-
-        /**
-         * Returns the serialized preconditions. Returns {@code null} if the the model in use does
-         * not meet all the requirements listed in the {@code ActionsModelParams} or the params are
-         * invalid.
-         */
-        @Nullable
-        public byte[] getSerializedPreconditions(ModelFileManager.ModelFile modelInUse) {
-            if (this == INVALID) {
-                return null;
-            }
-            if (modelInUse.getVersion() != mRequiredModelVersion) {
-                TcLog.w(
-                        TAG,
-                        String.format(
-                                "Not applying mSerializedPreconditions, required version=%d,"
-                                        + " actual=%d",
-                                mRequiredModelVersion, modelInUse.getVersion()));
-                return null;
-            }
-            if (!Objects.equals(modelInUse.getSupportedLocalesStr(), mRequiredModelLocales)) {
-                TcLog.w(
-                        TAG,
-                        String.format(
-                                "Not applying mSerializedPreconditions, required locales=%s,"
-                                        + " actual=%s",
-                                mRequiredModelLocales, modelInUse.getSupportedLocalesStr()));
-                return null;
-            }
-            return mSerializedPreconditions;
-        }
-    }
-
-    private static final class SettingsObserver extends ContentObserver {
-
-        private final WeakReference<Runnable> mOnChangedListener;
-
-        SettingsObserver(Context appContext, Runnable listener) {
-            super(null);
-            mOnChangedListener = new WeakReference<>(listener);
-            //            appContext.getContentResolver().registerContentObserver(
-            //
-            // Settings.Global.getUriFor(Settings.Global.TEXT_CLASSIFIER_ACTION_MODEL_PARAMS),
-            //                    false /* notifyForDescendants */,
-            //                    this);
-        }
-
-        @Override
-        public void onChange(boolean selfChange) {
-            if (mOnChangedListener.get() != null) {
-                mOnChangedListener.get().run();
-            }
-        }
-    }
+  }
 }
diff --git a/java/src/com/android/textclassifier/ActionsSuggestionsHelper.java b/java/src/com/android/textclassifier/ActionsSuggestionsHelper.java
index 41f0449..55ee402 100644
--- a/java/src/com/android/textclassifier/ActionsSuggestionsHelper.java
+++ b/java/src/com/android/textclassifier/ActionsSuggestionsHelper.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2018 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -11,7 +11,7 @@
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
  */
 
 package com.android.textclassifier;
@@ -26,17 +26,11 @@
 import android.util.Pair;
 import android.view.textclassifier.ConversationAction;
 import android.view.textclassifier.ConversationActions;
-
-import androidx.annotation.Nullable;
-import androidx.annotation.VisibleForTesting;
-
 import com.android.textclassifier.intent.LabeledIntent;
 import com.android.textclassifier.intent.TemplateIntentFactory;
 import com.android.textclassifier.logging.ResultIdUtils;
-
 import com.google.android.textclassifier.ActionsSuggestionsModel;
 import com.google.android.textclassifier.RemoteActionTemplate;
-
 import java.util.ArrayDeque;
 import java.util.ArrayList;
 import java.util.Deque;
@@ -46,182 +40,178 @@
 import java.util.Objects;
 import java.util.function.Function;
 import java.util.stream.Collectors;
+import javax.annotation.Nullable;
 
 /** Helper class for action suggestions. */
-@VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE)
-public final class ActionsSuggestionsHelper {
-    private static final String TAG = "ActionsSuggestions";
-    private static final int USER_LOCAL = 0;
-    private static final int FIRST_NON_LOCAL_USER = 1;
+final class ActionsSuggestionsHelper {
+  private static final String TAG = "ActionsSuggestions";
+  private static final int USER_LOCAL = 0;
+  private static final int FIRST_NON_LOCAL_USER = 1;
 
-    private ActionsSuggestionsHelper() {}
+  private ActionsSuggestionsHelper() {}
 
-    /**
-     * Converts the messages to a list of native messages object that the model can understand.
-     *
-     * <p>User id encoding - local user is represented as 0, Other users are numbered according to
-     * how far before they spoke last time in the conversation. For example, considering this
-     * conversation:
-     *
-     * <ul>
-     *   <li>User A: xxx
-     *   <li>Local user: yyy
-     *   <li>User B: zzz
-     * </ul>
-     *
-     * User A will be encoded as 2, user B will be encoded as 1 and local user will be encoded as 0.
-     */
-    public static ActionsSuggestionsModel.ConversationMessage[] toNativeMessages(
-            List<ConversationActions.Message> messages,
-            Function<CharSequence, List<String>> languageDetector) {
-        List<ConversationActions.Message> messagesWithText =
-                messages.stream()
-                        .filter(message -> !TextUtils.isEmpty(message.getText()))
-                        .collect(Collectors.toCollection(ArrayList::new));
-        if (messagesWithText.isEmpty()) {
-            return new ActionsSuggestionsModel.ConversationMessage[0];
-        }
-        Deque<ActionsSuggestionsModel.ConversationMessage> nativeMessages = new ArrayDeque<>();
-        PersonEncoder personEncoder = new PersonEncoder();
-        int size = messagesWithText.size();
-        for (int i = size - 1; i >= 0; i--) {
-            ConversationActions.Message message = messagesWithText.get(i);
-            long referenceTime =
-                    message.getReferenceTime() == null
-                            ? 0
-                            : message.getReferenceTime().toInstant().toEpochMilli();
-            String timeZone =
-                    message.getReferenceTime() == null
-                            ? null
-                            : message.getReferenceTime().getZone().getId();
-            nativeMessages.push(
-                    new ActionsSuggestionsModel.ConversationMessage(
-                            personEncoder.encode(message.getAuthor()),
-                            message.getText().toString(),
-                            referenceTime,
-                            timeZone,
-                            String.join(",", languageDetector.apply(message.getText()))));
-        }
-        return nativeMessages.toArray(
-                new ActionsSuggestionsModel.ConversationMessage[nativeMessages.size()]);
+  /**
+   * Converts the messages to a list of native messages object that the model can understand.
+   *
+   * <p>User id encoding - local user is represented as 0, Other users are numbered according to how
+   * far before they spoke last time in the conversation. For example, considering this
+   * conversation:
+   *
+   * <ul>
+   *   <li>User A: xxx
+   *   <li>Local user: yyy
+   *   <li>User B: zzz
+   * </ul>
+   *
+   * User A will be encoded as 2, user B will be encoded as 1 and local user will be encoded as 0.
+   */
+  public static ActionsSuggestionsModel.ConversationMessage[] toNativeMessages(
+      List<ConversationActions.Message> messages,
+      Function<CharSequence, List<String>> languageDetector) {
+    List<ConversationActions.Message> messagesWithText =
+        messages.stream()
+            .filter(message -> !TextUtils.isEmpty(message.getText()))
+            .collect(Collectors.toCollection(ArrayList::new));
+    if (messagesWithText.isEmpty()) {
+      return new ActionsSuggestionsModel.ConversationMessage[0];
     }
-
-    /** Returns the result id for logging. */
-    public static String createResultId(
-            Context context,
-            List<ConversationActions.Message> messages,
-            int modelVersion,
-            List<Locale> modelLocales) {
-        final int hash =
-                Objects.hash(
-                        messages.stream().mapToInt(ActionsSuggestionsHelper::hashMessage),
-                        context.getPackageName(),
-                        System.currentTimeMillis());
-        return ResultIdUtils.createId(modelVersion, modelLocales, hash);
+    Deque<ActionsSuggestionsModel.ConversationMessage> nativeMessages = new ArrayDeque<>();
+    PersonEncoder personEncoder = new PersonEncoder();
+    int size = messagesWithText.size();
+    for (int i = size - 1; i >= 0; i--) {
+      ConversationActions.Message message = messagesWithText.get(i);
+      long referenceTime =
+          message.getReferenceTime() == null
+              ? 0
+              : message.getReferenceTime().toInstant().toEpochMilli();
+      String timeZone =
+          message.getReferenceTime() == null ? null : message.getReferenceTime().getZone().getId();
+      nativeMessages.push(
+          new ActionsSuggestionsModel.ConversationMessage(
+              personEncoder.encode(message.getAuthor()),
+              message.getText().toString(),
+              referenceTime,
+              timeZone,
+              String.join(",", languageDetector.apply(message.getText()))));
     }
+    return nativeMessages.toArray(
+        new ActionsSuggestionsModel.ConversationMessage[nativeMessages.size()]);
+  }
 
-    /** Generated labeled intent from an action suggestion and return the resolved result. */
-    @Nullable
-    public static LabeledIntent.Result createLabeledIntentResult(
-            Context context,
-            TemplateIntentFactory templateIntentFactory,
-            ActionsSuggestionsModel.ActionSuggestion nativeSuggestion) {
-        RemoteActionTemplate[] remoteActionTemplates = nativeSuggestion.getRemoteActionTemplates();
-        if (remoteActionTemplates == null) {
-            TcLog.w(
-                    TAG,
-                    "createRemoteAction: Missing template for type "
-                            + nativeSuggestion.getActionType());
-            return null;
-        }
-        List<LabeledIntent> labeledIntents = templateIntentFactory.create(remoteActionTemplates);
-        if (labeledIntents.isEmpty()) {
-            return null;
-        }
-        // Given that we only support implicit intent here, we should expect there is just one
-        // intent for each action type.
-        LabeledIntent.TitleChooser titleChooser =
-                ActionsSuggestionsHelper.createTitleChooser(nativeSuggestion.getActionType());
-        return labeledIntents.get(0).resolve(context, titleChooser, null);
+  /** Returns the result id for logging. */
+  public static String createResultId(
+      Context context,
+      List<ConversationActions.Message> messages,
+      int modelVersion,
+      List<Locale> modelLocales) {
+    final int hash =
+        Objects.hash(
+            messages.stream().mapToInt(ActionsSuggestionsHelper::hashMessage),
+            context.getPackageName(),
+            System.currentTimeMillis());
+    return ResultIdUtils.createId(modelVersion, modelLocales, hash);
+  }
+
+  /** Generated labeled intent from an action suggestion and return the resolved result. */
+  @Nullable
+  public static LabeledIntent.Result createLabeledIntentResult(
+      Context context,
+      TemplateIntentFactory templateIntentFactory,
+      ActionsSuggestionsModel.ActionSuggestion nativeSuggestion) {
+    RemoteActionTemplate[] remoteActionTemplates = nativeSuggestion.getRemoteActionTemplates();
+    if (remoteActionTemplates == null) {
+      TcLog.w(
+          TAG, "createRemoteAction: Missing template for type " + nativeSuggestion.getActionType());
+      return null;
     }
-
-    /** Returns a {@link LabeledIntent.TitleChooser} for conversation actions use case. */
-    @Nullable
-    public static LabeledIntent.TitleChooser createTitleChooser(String actionType) {
-        if (ConversationAction.TYPE_OPEN_URL.equals(actionType)) {
-            return (labeledIntent, resolveInfo) -> {
-                if (resolveInfo.handleAllWebDataURI) {
-                    return labeledIntent.titleWithEntity;
-                }
-                if ("android".equals(resolveInfo.activityInfo.packageName)) {
-                    return labeledIntent.titleWithEntity;
-                }
-                return labeledIntent.titleWithoutEntity;
-            };
-        }
-        return null;
+    List<LabeledIntent> labeledIntents = templateIntentFactory.create(remoteActionTemplates);
+    if (labeledIntents.isEmpty()) {
+      return null;
     }
+    // Given that we only support implicit intent here, we should expect there is just one
+    // intent for each action type.
+    LabeledIntent.TitleChooser titleChooser =
+        ActionsSuggestionsHelper.createTitleChooser(nativeSuggestion.getActionType());
+    return labeledIntents.get(0).resolve(context, titleChooser, null);
+  }
 
-    /**
-     * Returns a list of {@link ConversationAction}s that have 0 duplicates. Two actions are
-     * duplicates if they may look the same to users. This function assumes every
-     * ConversationActions with a non-null RemoteAction also have a non-null intent in the extras.
-     */
-    public static List<ConversationAction> removeActionsWithDuplicates(
-            List<ConversationAction> conversationActions) {
-        // Ideally, we should compare title and icon here, but comparing icon is expensive and thus
-        // we use the component name of the target handler as the heuristic.
-        Map<Pair<String, String>, Integer> counter = new ArrayMap<>();
-        for (ConversationAction conversationAction : conversationActions) {
-            Pair<String, String> representation = getRepresentation(conversationAction);
-            if (representation == null) {
-                continue;
-            }
-            Integer existingCount = counter.getOrDefault(representation, 0);
-            counter.put(representation, existingCount + 1);
+  /** Returns a {@link LabeledIntent.TitleChooser} for conversation actions use case. */
+  @Nullable
+  public static LabeledIntent.TitleChooser createTitleChooser(String actionType) {
+    if (ConversationAction.TYPE_OPEN_URL.equals(actionType)) {
+      return (labeledIntent, resolveInfo) -> {
+        if (resolveInfo.handleAllWebDataURI) {
+          return labeledIntent.titleWithEntity;
         }
-        List<ConversationAction> result = new ArrayList<>();
-        for (ConversationAction conversationAction : conversationActions) {
-            Pair<String, String> representation = getRepresentation(conversationAction);
-            if (representation == null || counter.getOrDefault(representation, 0) == 1) {
-                result.add(conversationAction);
-            }
+        if ("android".equals(resolveInfo.activityInfo.packageName)) {
+          return labeledIntent.titleWithEntity;
         }
-        return result;
+        return labeledIntent.titleWithoutEntity;
+      };
     }
+    return null;
+  }
 
-    @Nullable
-    private static Pair<String, String> getRepresentation(ConversationAction conversationAction) {
-        RemoteAction remoteAction = conversationAction.getAction();
-        if (remoteAction == null) {
-            return null;
-        }
-        Intent actionIntent = ExtrasUtils.getActionIntent(conversationAction.getExtras());
-        ComponentName componentName = actionIntent.getComponent();
-        // Action without a component name will be considered as from the same app.
-        String packageName = componentName == null ? null : componentName.getPackageName();
-        return new Pair<>(conversationAction.getAction().getTitle().toString(), packageName);
+  /**
+   * Returns a list of {@link ConversationAction}s that have 0 duplicates. Two actions are
+   * duplicates if they may look the same to users. This function assumes every ConversationActions
+   * with a non-null RemoteAction also have a non-null intent in the extras.
+   */
+  public static List<ConversationAction> removeActionsWithDuplicates(
+      List<ConversationAction> conversationActions) {
+    // Ideally, we should compare title and icon here, but comparing icon is expensive and thus
+    // we use the component name of the target handler as the heuristic.
+    Map<Pair<String, String>, Integer> counter = new ArrayMap<>();
+    for (ConversationAction conversationAction : conversationActions) {
+      Pair<String, String> representation = getRepresentation(conversationAction);
+      if (representation == null) {
+        continue;
+      }
+      Integer existingCount = counter.getOrDefault(representation, 0);
+      counter.put(representation, existingCount + 1);
     }
-
-    private static final class PersonEncoder {
-        private final Map<Person, Integer> mMapping = new ArrayMap<>();
-        private int mNextUserId = FIRST_NON_LOCAL_USER;
-
-        private int encode(Person person) {
-            if (ConversationActions.Message.PERSON_USER_SELF.equals(person)) {
-                return USER_LOCAL;
-            }
-            Integer result = mMapping.get(person);
-            if (result == null) {
-                mMapping.put(person, mNextUserId);
-                result = mNextUserId;
-                mNextUserId++;
-            }
-            return result;
-        }
+    List<ConversationAction> result = new ArrayList<>();
+    for (ConversationAction conversationAction : conversationActions) {
+      Pair<String, String> representation = getRepresentation(conversationAction);
+      if (representation == null || counter.getOrDefault(representation, 0) == 1) {
+        result.add(conversationAction);
+      }
     }
+    return result;
+  }
 
-    private static int hashMessage(ConversationActions.Message message) {
-        return Objects.hash(message.getAuthor(), message.getText(), message.getReferenceTime());
+  @Nullable
+  private static Pair<String, String> getRepresentation(ConversationAction conversationAction) {
+    RemoteAction remoteAction = conversationAction.getAction();
+    if (remoteAction == null) {
+      return null;
     }
+    Intent actionIntent = ExtrasUtils.getActionIntent(conversationAction.getExtras());
+    ComponentName componentName = actionIntent.getComponent();
+    // Action without a component name will be considered as from the same app.
+    String packageName = componentName == null ? null : componentName.getPackageName();
+    return new Pair<>(conversationAction.getAction().getTitle().toString(), packageName);
+  }
+
+  private static final class PersonEncoder {
+    private final Map<Person, Integer> personToUserIdMap = new ArrayMap<>();
+    private int nextUserId = FIRST_NON_LOCAL_USER;
+
+    private int encode(Person person) {
+      if (ConversationActions.Message.PERSON_USER_SELF.equals(person)) {
+        return USER_LOCAL;
+      }
+      Integer result = personToUserIdMap.get(person);
+      if (result == null) {
+        personToUserIdMap.put(person, nextUserId);
+        result = nextUserId;
+        nextUserId++;
+      }
+      return result;
+    }
+  }
+
+  private static int hashMessage(ConversationActions.Message message) {
+    return Objects.hash(message.getAuthor(), message.getText(), message.getReferenceTime());
+  }
 }
diff --git a/java/src/com/android/textclassifier/DefaultTextClassifierService.java b/java/src/com/android/textclassifier/DefaultTextClassifierService.java
index e842247..32cba2f 100644
--- a/java/src/com/android/textclassifier/DefaultTextClassifierService.java
+++ b/java/src/com/android/textclassifier/DefaultTextClassifierService.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2018 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -11,7 +11,7 @@
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
  */
 
 package com.android.textclassifier;
@@ -26,160 +26,152 @@
 import android.view.textclassifier.TextLanguage;
 import android.view.textclassifier.TextLinks;
 import android.view.textclassifier.TextSelection;
-
 import com.android.textclassifier.utils.IndentingPrintWriter;
-
 import com.google.common.util.concurrent.FutureCallback;
 import com.google.common.util.concurrent.Futures;
 import com.google.common.util.concurrent.ListenableFuture;
 import com.google.common.util.concurrent.ListeningExecutorService;
 import com.google.common.util.concurrent.MoreExecutors;
 import com.google.common.util.concurrent.ThreadFactoryBuilder;
-
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 import java.util.concurrent.Callable;
 import java.util.concurrent.Executors;
 
+/** An implementation of a TextClassifierService. */
 public final class DefaultTextClassifierService extends TextClassifierService {
-    private static final String TAG = "default_tcs";
+  private static final String TAG = "default_tcs";
 
-    // TODO: Figure out do we need more concurrency.
-    private final ListeningExecutorService mNormPriorityExecutor =
-            MoreExecutors.listeningDecorator(
-                    Executors.newFixedThreadPool(
-                            /* nThreads= */ 2,
-                            new ThreadFactoryBuilder()
-                                    .setNameFormat("tcs-norm-prio-executor")
-                                    .setPriority(Thread.NORM_PRIORITY)
-                                    .build()));
+  // TODO: Figure out do we need more concurrency.
+  private final ListeningExecutorService normPriorityExecutor =
+      MoreExecutors.listeningDecorator(
+          Executors.newFixedThreadPool(
+              /* nThreads= */ 2,
+              new ThreadFactoryBuilder()
+                  .setNameFormat("tcs-norm-prio-executor")
+                  .setPriority(Thread.NORM_PRIORITY)
+                  .build()));
 
-    private final ListeningExecutorService mLowPriorityExecutor =
-            MoreExecutors.listeningDecorator(
-                    Executors.newSingleThreadExecutor(
-                            new ThreadFactoryBuilder()
-                                    .setNameFormat("tcs-low-prio-executor")
-                                    .setPriority(Thread.NORM_PRIORITY - 1)
-                                    .build()));
+  private final ListeningExecutorService lowPriorityExecutor =
+      MoreExecutors.listeningDecorator(
+          Executors.newSingleThreadExecutor(
+              new ThreadFactoryBuilder()
+                  .setNameFormat("tcs-low-prio-executor")
+                  .setPriority(Thread.NORM_PRIORITY - 1)
+                  .build()));
 
-    private TextClassifierImpl mTextClassifier;
+  private TextClassifierImpl textClassifier;
 
-    @Override
-    public void onCreate() {
-        super.onCreate();
-        mTextClassifier = new TextClassifierImpl(this, new TextClassificationConstants());
-    }
+  @Override
+  public void onCreate() {
+    super.onCreate();
+    textClassifier = new TextClassifierImpl(this, new TextClassificationConstants());
+  }
 
-    @Override
-    public void onSuggestSelection(
-            TextClassificationSessionId sessionId,
-            TextSelection.Request request,
-            CancellationSignal cancellationSignal,
-            Callback<TextSelection> callback) {
-        handleRequestAsync(
-                () -> mTextClassifier.suggestSelection(request), callback, cancellationSignal);
-    }
+  @Override
+  public void onSuggestSelection(
+      TextClassificationSessionId sessionId,
+      TextSelection.Request request,
+      CancellationSignal cancellationSignal,
+      Callback<TextSelection> callback) {
+    handleRequestAsync(
+        () -> textClassifier.suggestSelection(request), callback, cancellationSignal);
+  }
 
-    @Override
-    public void onClassifyText(
-            TextClassificationSessionId sessionId,
-            TextClassification.Request request,
-            CancellationSignal cancellationSignal,
-            Callback<TextClassification> callback) {
-        handleRequestAsync(
-                () -> mTextClassifier.classifyText(request), callback, cancellationSignal);
-    }
+  @Override
+  public void onClassifyText(
+      TextClassificationSessionId sessionId,
+      TextClassification.Request request,
+      CancellationSignal cancellationSignal,
+      Callback<TextClassification> callback) {
+    handleRequestAsync(() -> textClassifier.classifyText(request), callback, cancellationSignal);
+  }
 
-    @Override
-    public void onGenerateLinks(
-            TextClassificationSessionId sessionId,
-            TextLinks.Request request,
-            CancellationSignal cancellationSignal,
-            Callback<TextLinks> callback) {
-        handleRequestAsync(
-                () -> mTextClassifier.generateLinks(request), callback, cancellationSignal);
-    }
+  @Override
+  public void onGenerateLinks(
+      TextClassificationSessionId sessionId,
+      TextLinks.Request request,
+      CancellationSignal cancellationSignal,
+      Callback<TextLinks> callback) {
+    handleRequestAsync(() -> textClassifier.generateLinks(request), callback, cancellationSignal);
+  }
 
-    @Override
-    public void onSuggestConversationActions(
-            TextClassificationSessionId sessionId,
-            ConversationActions.Request request,
-            CancellationSignal cancellationSignal,
-            Callback<ConversationActions> callback) {
-        handleRequestAsync(
-                () -> mTextClassifier.suggestConversationActions(request),
-                callback,
-                cancellationSignal);
-    }
+  @Override
+  public void onSuggestConversationActions(
+      TextClassificationSessionId sessionId,
+      ConversationActions.Request request,
+      CancellationSignal cancellationSignal,
+      Callback<ConversationActions> callback) {
+    handleRequestAsync(
+        () -> textClassifier.suggestConversationActions(request), callback, cancellationSignal);
+  }
 
-    @Override
-    public void onDetectLanguage(
-            TextClassificationSessionId sessionId,
-            TextLanguage.Request request,
-            CancellationSignal cancellationSignal,
-            Callback<TextLanguage> callback) {
-        handleRequestAsync(
-                () -> mTextClassifier.detectLanguage(request), callback, cancellationSignal);
-    }
+  @Override
+  public void onDetectLanguage(
+      TextClassificationSessionId sessionId,
+      TextLanguage.Request request,
+      CancellationSignal cancellationSignal,
+      Callback<TextLanguage> callback) {
+    handleRequestAsync(() -> textClassifier.detectLanguage(request), callback, cancellationSignal);
+  }
 
-    @Override
-    public void onSelectionEvent(TextClassificationSessionId sessionId, SelectionEvent event) {
-        handleEvent(() -> mTextClassifier.onSelectionEvent(event));
-    }
+  @Override
+  public void onSelectionEvent(TextClassificationSessionId sessionId, SelectionEvent event) {
+    handleEvent(() -> textClassifier.onSelectionEvent(event));
+  }
 
-    @Override
-    public void onTextClassifierEvent(
-            TextClassificationSessionId sessionId, TextClassifierEvent event) {
-        handleEvent(() -> mTextClassifier.onTextClassifierEvent(sessionId, event));
-    }
+  @Override
+  public void onTextClassifierEvent(
+      TextClassificationSessionId sessionId, TextClassifierEvent event) {
+    handleEvent(() -> textClassifier.onTextClassifierEvent(sessionId, event));
+  }
 
-    @Override
-    protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
-        IndentingPrintWriter indentingPrintWriter = new IndentingPrintWriter(writer);
-        mTextClassifier.dump(indentingPrintWriter);
-        indentingPrintWriter.flush();
-    }
+  @Override
+  protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
+    IndentingPrintWriter indentingPrintWriter = new IndentingPrintWriter(writer);
+    textClassifier.dump(indentingPrintWriter);
+    indentingPrintWriter.flush();
+  }
 
-    private <T> void handleRequestAsync(
-            Callable<T> callable, Callback<T> callback, CancellationSignal cancellationSignal) {
-        ListenableFuture<T> result = mNormPriorityExecutor.submit(callable);
-        Futures.addCallback(
-                result,
-                new FutureCallback<T>() {
-                    @Override
-                    public void onSuccess(T result) {
-                        callback.onSuccess(result);
-                    }
+  private <T> void handleRequestAsync(
+      Callable<T> callable, Callback<T> callback, CancellationSignal cancellationSignal) {
+    ListenableFuture<T> result = normPriorityExecutor.submit(callable);
+    Futures.addCallback(
+        result,
+        new FutureCallback<T>() {
+          @Override
+          public void onSuccess(T result) {
+            callback.onSuccess(result);
+          }
 
-                    @Override
-                    public void onFailure(Throwable t) {
-                        TcLog.e(TAG, "onFailure: ", t);
-                        callback.onFailure(t.getMessage());
-                    }
-                },
-                MoreExecutors.directExecutor());
-        cancellationSignal.setOnCancelListener(
-                () -> result.cancel(/* mayInterruptIfRunning= */ true));
-    }
+          @Override
+          public void onFailure(Throwable t) {
+            TcLog.e(TAG, "onFailure: ", t);
+            callback.onFailure(t.getMessage());
+          }
+        },
+        MoreExecutors.directExecutor());
+    cancellationSignal.setOnCancelListener(() -> result.cancel(/* mayInterruptIfRunning= */ true));
+  }
 
-    private void handleEvent(Runnable runnable) {
-        ListenableFuture<Void> result =
-                mLowPriorityExecutor.submit(
-                        () -> {
-                            runnable.run();
-                            return null;
-                        });
-        Futures.addCallback(
-                result,
-                new FutureCallback<Void>() {
-                    @Override
-                    public void onSuccess(Void result) {}
+  private void handleEvent(Runnable runnable) {
+    ListenableFuture<Void> result =
+        lowPriorityExecutor.submit(
+            () -> {
+              runnable.run();
+              return null;
+            });
+    Futures.addCallback(
+        result,
+        new FutureCallback<Void>() {
+          @Override
+          public void onSuccess(Void result) {}
 
-                    @Override
-                    public void onFailure(Throwable t) {
-                        TcLog.e(TAG, "onFailure: ", t);
-                    }
-                },
-                MoreExecutors.directExecutor());
-    }
+          @Override
+          public void onFailure(Throwable t) {
+            TcLog.e(TAG, "onFailure: ", t);
+          }
+        },
+        MoreExecutors.directExecutor());
+  }
 }
diff --git a/java/src/com/android/textclassifier/Entity.java b/java/src/com/android/textclassifier/Entity.java
index 8a29923..6410a3e 100644
--- a/java/src/com/android/textclassifier/Entity.java
+++ b/java/src/com/android/textclassifier/Entity.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2018 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -17,62 +17,65 @@
 package com.android.textclassifier;
 
 import androidx.annotation.FloatRange;
-
 import com.google.common.base.Objects;
 import com.google.common.base.Preconditions;
 
 /** A representation of an identified entity with the confidence score */
 public final class Entity implements Comparable<Entity> {
 
-    private final String mEntityType;
-    private float mScore;
+  private final String entityType;
+  private final float score;
 
-    public Entity(String entityType, float score) {
-        mEntityType = Preconditions.checkNotNull(entityType);
-        mScore = score;
-    }
+  public Entity(String entityType, float score) {
+    this.entityType = Preconditions.checkNotNull(entityType);
+    this.score = score;
+  }
 
-    public String getEntityType() {
-        return mEntityType;
-    }
+  public String getEntityType() {
+    return entityType;
+  }
 
-    /**
-     * Returns the confidence score of the entity, which ranged from 0.0 (low confidence) to 1.0
-     * (high confidence).
-     */
-    @FloatRange(from = 0.0, to = 1.0)
-    public Float getScore() {
-        return mScore;
-    }
+  /**
+   * Returns the confidence score of the entity, which ranged from 0.0 (low confidence) to 1.0 (high
+   * confidence).
+   */
+  @FloatRange(from = 0.0, to = 1.0)
+  public Float getScore() {
+    return score;
+  }
 
-    @Override
-    public int hashCode() {
-        return Objects.hashCode(mEntityType, mScore);
-    }
+  @Override
+  public int hashCode() {
+    return Objects.hashCode(entityType, score);
+  }
 
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) return true;
-        if (o == null || getClass() != o.getClass()) return false;
-        Entity entity = (Entity) o;
-        return Float.compare(entity.mScore, mScore) == 0
-                && java.util.Objects.equals(mEntityType, entity.mEntityType);
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) {
+      return true;
     }
+    if (o == null || getClass() != o.getClass()) {
+      return false;
+    }
+    Entity entity = (Entity) o;
+    return Float.compare(entity.score, score) == 0
+        && java.util.Objects.equals(entityType, entity.entityType);
+  }
 
-    @Override
-    public String toString() {
-        return "Entity{" + mEntityType + ": " + mScore + "}";
-    }
+  @Override
+  public String toString() {
+    return "Entity{" + entityType + ": " + score + "}";
+  }
 
-    @Override
-    public int compareTo(Entity entity) {
-        // This method is implemented for sorting Entity. Sort the entities by the confidence score
-        // in descending order firstly. If the scores are the same, then sort them by the entity
-        // type in ascending order.
-        int result = Float.compare(entity.getScore(), mScore);
-        if (result == 0) {
-            return mEntityType.compareTo(entity.getEntityType());
-        }
-        return result;
+  @Override
+  public int compareTo(Entity entity) {
+    // This method is implemented for sorting Entity. Sort the entities by the confidence score
+    // in descending order firstly. If the scores are the same, then sort them by the entity
+    // type in ascending order.
+    int result = Float.compare(entity.getScore(), score);
+    if (result == 0) {
+      return entityType.compareTo(entity.getEntityType());
     }
+    return result;
+  }
 }
diff --git a/java/src/com/android/textclassifier/EntityConfidence.java b/java/src/com/android/textclassifier/EntityConfidence.java
index d3d26e4..ef8ff05 100644
--- a/java/src/com/android/textclassifier/EntityConfidence.java
+++ b/java/src/com/android/textclassifier/EntityConfidence.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 The Android Open Source Project
+ * Copyright (C) 2018 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -17,10 +17,8 @@
 package com.android.textclassifier;
 
 import androidx.annotation.FloatRange;
-import androidx.annotation.NonNull;
 import androidx.collection.ArrayMap;
-import androidx.core.util.Preconditions;
-
+import com.google.common.base.Preconditions;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
@@ -29,65 +27,64 @@
 /** Helper object for setting and getting entity scores for classified text. */
 final class EntityConfidence {
 
-    static final EntityConfidence EMPTY = new EntityConfidence(Collections.emptyMap());
+  static final EntityConfidence EMPTY = new EntityConfidence(Collections.emptyMap());
 
-    private final ArrayMap<String, Float> mEntityConfidence = new ArrayMap<>();
-    private final ArrayList<String> mSortedEntities = new ArrayList<>();
+  private final ArrayMap<String, Float> entityConfidence = new ArrayMap<>();
+  private final ArrayList<String> sortedEntities = new ArrayList<>();
 
-    /**
-     * Constructs an EntityConfidence from a map of entity to confidence.
-     *
-     * <p>Map entries that have 0 confidence are removed, and values greater than 1 are clamped to
-     * 1.
-     *
-     * @param source a map from entity to a confidence value in the range 0 (low confidence) to 1
-     *     (high confidence).
-     */
-    EntityConfidence(@NonNull Map<String, Float> source) {
-        Preconditions.checkNotNull(source);
+  /**
+   * Constructs an EntityConfidence from a map of entity to confidence.
+   *
+   * <p>Map entries that have 0 confidence are removed, and values greater than 1 are clamped to 1.
+   *
+   * @param source a map from entity to a confidence value in the range 0 (low confidence) to 1
+   *     (high confidence).
+   */
+  EntityConfidence(Map<String, Float> source) {
+    Preconditions.checkNotNull(source);
 
-        // Prune non-existent entities and clamp to 1.
-        mEntityConfidence.ensureCapacity(source.size());
-        for (Map.Entry<String, Float> it : source.entrySet()) {
-            if (it.getValue() <= 0) continue;
-            mEntityConfidence.put(it.getKey(), Math.min(1, it.getValue()));
-        }
-        resetSortedEntitiesFromMap();
+    // Prune non-existent entities and clamp to 1.
+    entityConfidence.ensureCapacity(source.size());
+    for (Map.Entry<String, Float> it : source.entrySet()) {
+      if (it.getValue() <= 0) {
+        continue;
+      }
+      entityConfidence.put(it.getKey(), Math.min(1, it.getValue()));
     }
+    resetSortedEntitiesFromMap();
+  }
 
-    /**
-     * Returns an immutable list of entities found in the classified text ordered from high
-     * confidence to low confidence.
-     */
-    @NonNull
-    public List<String> getEntities() {
-        return Collections.unmodifiableList(mSortedEntities);
-    }
+  /**
+   * Returns an immutable list of entities found in the classified text ordered from high confidence
+   * to low confidence.
+   */
+  public List<String> getEntities() {
+    return Collections.unmodifiableList(sortedEntities);
+  }
 
-    /**
-     * Returns the confidence score for the specified entity. The value ranges from 0 (low
-     * confidence) to 1 (high confidence). 0 indicates that the entity was not found for the
-     * classified text.
-     */
-    @FloatRange(from = 0.0, to = 1.0)
-    public float getConfidenceScore(String entity) {
-        return mEntityConfidence.getOrDefault(entity, 0f);
-    }
+  /**
+   * Returns the confidence score for the specified entity. The value ranges from 0 (low confidence)
+   * to 1 (high confidence). 0 indicates that the entity was not found for the classified text.
+   */
+  @FloatRange(from = 0.0, to = 1.0)
+  public float getConfidenceScore(String entity) {
+    return entityConfidence.getOrDefault(entity, 0f);
+  }
 
-    @Override
-    public String toString() {
-        return mEntityConfidence.toString();
-    }
+  @Override
+  public String toString() {
+    return entityConfidence.toString();
+  }
 
-    private void resetSortedEntitiesFromMap() {
-        mSortedEntities.clear();
-        mSortedEntities.ensureCapacity(mEntityConfidence.size());
-        mSortedEntities.addAll(mEntityConfidence.keySet());
-        mSortedEntities.sort(
-                (e1, e2) -> {
-                    float score1 = mEntityConfidence.get(e1);
-                    float score2 = mEntityConfidence.get(e2);
-                    return Float.compare(score2, score1);
-                });
-    }
+  private void resetSortedEntitiesFromMap() {
+    sortedEntities.clear();
+    sortedEntities.ensureCapacity(entityConfidence.size());
+    sortedEntities.addAll(entityConfidence.keySet());
+    sortedEntities.sort(
+        (e1, e2) -> {
+          float score1 = entityConfidence.get(e1);
+          float score2 = entityConfidence.get(e2);
+          return Float.compare(score2, score1);
+        });
+  }
 }
diff --git a/java/src/com/android/textclassifier/ExtrasUtils.java b/java/src/com/android/textclassifier/ExtrasUtils.java
index 8d18e19..2039d76 100644
--- a/java/src/com/android/textclassifier/ExtrasUtils.java
+++ b/java/src/com/android/textclassifier/ExtrasUtils.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2018 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -23,295 +23,287 @@
 import android.view.textclassifier.TextClassification;
 import android.view.textclassifier.TextClassifier;
 import android.view.textclassifier.TextLinks;
-
-import androidx.annotation.Nullable;
-import androidx.annotation.VisibleForTesting;
-
 import com.google.android.textclassifier.AnnotatorModel;
-
+import com.google.common.annotations.VisibleForTesting;
 import java.util.ArrayList;
 import java.util.List;
+import javax.annotation.Nullable;
 
 /** Utility class for inserting and retrieving data in TextClassifier request/response extras. */
 // TODO: Make this a TestApi for CTS testing.
 public final class ExtrasUtils {
 
-    // Keys for response objects.
-    private static final String SERIALIZED_ENTITIES_DATA = "serialized-entities-data";
-    private static final String ENTITIES_EXTRAS = "entities-extras";
-    private static final String ACTION_INTENT = "action-intent";
-    private static final String ACTIONS_INTENTS = "actions-intents";
-    private static final String FOREIGN_LANGUAGE = "foreign-language";
-    private static final String ENTITY_TYPE = "entity-type";
-    private static final String SCORE = "score";
-    private static final String MODEL_VERSION = "model-version";
-    private static final String MODEL_NAME = "model-name";
-    private static final String TEXT_LANGUAGES = "text-languages";
-    private static final String ENTITIES = "entities";
+  // Keys for response objects.
+  private static final String SERIALIZED_ENTITIES_DATA = "serialized-entities-data";
+  private static final String ENTITIES_EXTRAS = "entities-extras";
+  private static final String ACTION_INTENT = "action-intent";
+  private static final String ACTIONS_INTENTS = "actions-intents";
+  private static final String FOREIGN_LANGUAGE = "foreign-language";
+  private static final String ENTITY_TYPE = "entity-type";
+  private static final String SCORE = "score";
+  private static final String MODEL_VERSION = "model-version";
+  private static final String MODEL_NAME = "model-name";
+  private static final String TEXT_LANGUAGES = "text-languages";
+  private static final String ENTITIES = "entities";
 
-    // Keys for request objects.
-    private static final String IS_SERIALIZED_ENTITY_DATA_ENABLED =
-            "is-serialized-entity-data-enabled";
+  // Keys for request objects.
+  private static final String IS_SERIALIZED_ENTITY_DATA_ENABLED =
+      "is-serialized-entity-data-enabled";
 
-    private ExtrasUtils() {}
+  private ExtrasUtils() {}
 
-    /** Bundles and returns foreign language detection information for TextClassifier responses. */
-    static Bundle createForeignLanguageExtra(String language, float score, int modelVersion) {
-        final Bundle bundle = new Bundle();
-        bundle.putString(ENTITY_TYPE, language);
-        bundle.putFloat(SCORE, score);
-        bundle.putInt(MODEL_VERSION, modelVersion);
-        bundle.putString(MODEL_NAME, "langId_v" + modelVersion);
-        return bundle;
+  /** Bundles and returns foreign language detection information for TextClassifier responses. */
+  static Bundle createForeignLanguageExtra(String language, float score, int modelVersion) {
+    final Bundle bundle = new Bundle();
+    bundle.putString(ENTITY_TYPE, language);
+    bundle.putFloat(SCORE, score);
+    bundle.putInt(MODEL_VERSION, modelVersion);
+    bundle.putString(MODEL_NAME, "langId_v" + modelVersion);
+    return bundle;
+  }
+
+  /**
+   * Stores {@code extra} as foreign language information in TextClassifier response object's extras
+   * {@code container}.
+   *
+   * @see #getForeignLanguageExtra(TextClassification)
+   */
+  static void putForeignLanguageExtra(Bundle container, Bundle extra) {
+    container.putParcelable(FOREIGN_LANGUAGE, extra);
+  }
+
+  /**
+   * Returns foreign language detection information contained in the TextClassification object.
+   * responses.
+   *
+   * @see #putForeignLanguageExtra(Bundle, Bundle)
+   */
+  @Nullable
+  @VisibleForTesting
+  public static Bundle getForeignLanguageExtra(@Nullable TextClassification classification) {
+    if (classification == null) {
+      return null;
     }
+    return classification.getExtras().getBundle(FOREIGN_LANGUAGE);
+  }
 
-    /**
-     * Stores {@code extra} as foreign language information in TextClassifier response object's
-     * extras {@code container}.
-     *
-     * @see #getForeignLanguageExtra(TextClassification)
-     */
-    static void putForeignLanguageExtra(Bundle container, Bundle extra) {
-        container.putParcelable(FOREIGN_LANGUAGE, extra);
+  /** @see #getTopLanguage(Intent) */
+  static void putTopLanguageScores(Bundle container, EntityConfidence languageScores) {
+    final int maxSize = Math.min(3, languageScores.getEntities().size());
+    final String[] languages =
+        languageScores.getEntities().subList(0, maxSize).toArray(new String[0]);
+    final float[] scores = new float[languages.length];
+    for (int i = 0; i < languages.length; i++) {
+      scores[i] = languageScores.getConfidenceScore(languages[i]);
     }
+    container.putStringArray(ENTITY_TYPE, languages);
+    container.putFloatArray(SCORE, scores);
+  }
 
-    /**
-     * Returns foreign language detection information contained in the TextClassification object.
-     * responses.
-     *
-     * @see #putForeignLanguageExtra(Bundle, Bundle)
-     */
-    @Nullable
-    @VisibleForTesting
-    public static Bundle getForeignLanguageExtra(@Nullable TextClassification classification) {
-        if (classification == null) {
-            return null;
+  /** See {@link #putTopLanguageScores(Bundle, EntityConfidence)}. */
+  @Nullable
+  @VisibleForTesting
+  public static ULocale getTopLanguage(@Nullable Intent intent) {
+    if (intent == null) {
+      return null;
+    }
+    final Bundle tcBundle = intent.getBundleExtra(TextClassifier.EXTRA_FROM_TEXT_CLASSIFIER);
+    if (tcBundle == null) {
+      return null;
+    }
+    final Bundle textLanguagesExtra = tcBundle.getBundle(TEXT_LANGUAGES);
+    if (textLanguagesExtra == null) {
+      return null;
+    }
+    final String[] languages = textLanguagesExtra.getStringArray(ENTITY_TYPE);
+    final float[] scores = textLanguagesExtra.getFloatArray(SCORE);
+    if (languages == null
+        || scores == null
+        || languages.length == 0
+        || languages.length != scores.length) {
+      return null;
+    }
+    int highestScoringIndex = 0;
+    for (int i = 1; i < languages.length; i++) {
+      if (scores[highestScoringIndex] < scores[i]) {
+        highestScoringIndex = i;
+      }
+    }
+    return ULocale.forLanguageTag(languages[highestScoringIndex]);
+  }
+
+  public static void putTextLanguagesExtra(Bundle container, Bundle extra) {
+    container.putBundle(TEXT_LANGUAGES, extra);
+  }
+
+  /**
+   * Stores {@code actionsIntents} information in TextClassifier response object's extras {@code
+   * container}.
+   */
+  static void putActionsIntents(Bundle container, ArrayList<Intent> actionsIntents) {
+    container.putParcelableArrayList(ACTIONS_INTENTS, actionsIntents);
+  }
+
+  /**
+   * Stores {@code actionIntent} information in TextClassifier response object's extras {@code
+   * container}.
+   */
+  public static void putActionIntent(Bundle container, @Nullable Intent actionIntent) {
+    container.putParcelable(ACTION_INTENT, actionIntent);
+  }
+
+  /** Returns {@code actionIntent} information contained in a TextClassifier response object. */
+  @Nullable
+  public static Intent getActionIntent(Bundle container) {
+    return container.getParcelable(ACTION_INTENT);
+  }
+
+  /**
+   * Stores serialized entity data information in TextClassifier response object's extras {@code
+   * container}.
+   */
+  public static void putSerializedEntityData(
+      Bundle container, @Nullable byte[] serializedEntityData) {
+    container.putByteArray(SERIALIZED_ENTITIES_DATA, serializedEntityData);
+  }
+
+  /** Returns serialized entity data information contained in a TextClassifier response object. */
+  @Nullable
+  public static byte[] getSerializedEntityData(Bundle container) {
+    return container.getByteArray(SERIALIZED_ENTITIES_DATA);
+  }
+
+  /**
+   * Stores {@code entities} information in TextClassifier response object's extras {@code
+   * container}.
+   *
+   * @see {@link #getCopyText(Bundle)}
+   */
+  public static void putEntitiesExtras(Bundle container, @Nullable Bundle entitiesExtras) {
+    container.putParcelable(ENTITIES_EXTRAS, entitiesExtras);
+  }
+
+  /**
+   * Returns {@code entities} information contained in a TextClassifier response object.
+   *
+   * @see {@link #putEntitiesExtras(Bundle, Bundle)}
+   */
+  @Nullable
+  public static String getCopyText(Bundle container) {
+    Bundle entitiesExtras = container.getParcelable(ENTITIES_EXTRAS);
+    if (entitiesExtras == null) {
+      return null;
+    }
+    return entitiesExtras.getString("text");
+  }
+
+  /** Returns {@code actionIntents} information contained in the TextClassification object. */
+  @Nullable
+  public static ArrayList<Intent> getActionsIntents(@Nullable TextClassification classification) {
+    if (classification == null) {
+      return null;
+    }
+    return classification.getExtras().getParcelableArrayList(ACTIONS_INTENTS);
+  }
+
+  /**
+   * Returns the first action found in the {@code classification} object with an intent action
+   * string, {@code intentAction}.
+   */
+  @Nullable
+  @VisibleForTesting
+  public static RemoteAction findAction(
+      @Nullable TextClassification classification, @Nullable String intentAction) {
+    if (classification == null || intentAction == null) {
+      return null;
+    }
+    final ArrayList<Intent> actionIntents = getActionsIntents(classification);
+    if (actionIntents != null) {
+      final int size = actionIntents.size();
+      for (int i = 0; i < size; i++) {
+        final Intent intent = actionIntents.get(i);
+        if (intent != null && intentAction.equals(intent.getAction())) {
+          return classification.getActions().get(i);
         }
-        return classification.getExtras().getBundle(FOREIGN_LANGUAGE);
+      }
     }
+    return null;
+  }
 
-    /** @see #getTopLanguage(Intent) */
-    @VisibleForTesting
-    static void putTopLanguageScores(Bundle container, EntityConfidence languageScores) {
-        final int maxSize = Math.min(3, languageScores.getEntities().size());
-        final String[] languages =
-                languageScores.getEntities().subList(0, maxSize).toArray(new String[0]);
-        final float[] scores = new float[languages.length];
-        for (int i = 0; i < languages.length; i++) {
-            scores[i] = languageScores.getConfidenceScore(languages[i]);
-        }
-        container.putStringArray(ENTITY_TYPE, languages);
-        container.putFloatArray(SCORE, scores);
-    }
+  /** Returns the first "translate" action found in the {@code classification} object. */
+  @Nullable
+  @VisibleForTesting
+  public static RemoteAction findTranslateAction(@Nullable TextClassification classification) {
+    return findAction(classification, Intent.ACTION_TRANSLATE);
+  }
 
-    /** @see #putTopLanguageScores(Bundle, EntityConfidence) */
-    @Nullable
-    @VisibleForTesting
-    public static ULocale getTopLanguage(@Nullable Intent intent) {
-        if (intent == null) {
-            return null;
-        }
-        final Bundle tcBundle = intent.getBundleExtra(TextClassifier.EXTRA_FROM_TEXT_CLASSIFIER);
-        if (tcBundle == null) {
-            return null;
-        }
-        final Bundle textLanguagesExtra = tcBundle.getBundle(TEXT_LANGUAGES);
-        if (textLanguagesExtra == null) {
-            return null;
-        }
-        final String[] languages = textLanguagesExtra.getStringArray(ENTITY_TYPE);
-        final float[] scores = textLanguagesExtra.getFloatArray(SCORE);
-        if (languages == null
-                || scores == null
-                || languages.length == 0
-                || languages.length != scores.length) {
-            return null;
-        }
-        int highestScoringIndex = 0;
-        for (int i = 1; i < languages.length; i++) {
-            if (scores[highestScoringIndex] < scores[i]) {
-                highestScoringIndex = i;
-            }
-        }
-        return ULocale.forLanguageTag(languages[highestScoringIndex]);
+  /** Returns the entity type contained in the {@code extra}. */
+  @Nullable
+  @VisibleForTesting
+  public static String getEntityType(@Nullable Bundle extra) {
+    if (extra == null) {
+      return null;
     }
+    return extra.getString(ENTITY_TYPE);
+  }
 
-    public static void putTextLanguagesExtra(Bundle container, Bundle extra) {
-        container.putBundle(TEXT_LANGUAGES, extra);
+  /** Returns the score contained in the {@code extra}. */
+  @VisibleForTesting
+  public static float getScore(Bundle extra) {
+    final int defaultValue = -1;
+    if (extra == null) {
+      return defaultValue;
     }
+    return extra.getFloat(SCORE, defaultValue);
+  }
 
-    /**
-     * Stores {@code actionIntents} information in TextClassifier response object's extras {@code
-     * container}.
-     */
-    static void putActionsIntents(Bundle container, ArrayList<Intent> actionsIntents) {
-        container.putParcelableArrayList(ACTIONS_INTENTS, actionsIntents);
+  /** Returns the model name contained in the {@code extra}. */
+  @Nullable
+  public static String getModelName(@Nullable Bundle extra) {
+    if (extra == null) {
+      return null;
     }
+    return extra.getString(MODEL_NAME);
+  }
 
-    /**
-     * Stores {@code actionIntents} information in TextClassifier response object's extras {@code
-     * container}.
-     */
-    public static void putActionIntent(Bundle container, @Nullable Intent actionIntent) {
-        container.putParcelable(ACTION_INTENT, actionIntent);
+  /** Stores the entities from {@link AnnotatorModel.ClassificationResult} in {@code container}. */
+  public static void putEntities(
+      Bundle container, @Nullable AnnotatorModel.ClassificationResult[] classifications) {
+    if (classifications == null || classifications.length == 0) {
+      return;
     }
+    ArrayList<Bundle> entitiesBundle = new ArrayList<>();
+    for (AnnotatorModel.ClassificationResult classification : classifications) {
+      if (classification == null) {
+        continue;
+      }
+      Bundle entityBundle = new Bundle();
+      entityBundle.putString(ENTITY_TYPE, classification.getCollection());
+      entityBundle.putByteArray(SERIALIZED_ENTITIES_DATA, classification.getSerializedEntityData());
+      entitiesBundle.add(entityBundle);
+    }
+    if (!entitiesBundle.isEmpty()) {
+      container.putParcelableArrayList(ENTITIES, entitiesBundle);
+    }
+  }
 
-    /** Returns {@code actionIntent} information contained in a TextClassifier response object. */
-    @Nullable
-    public static Intent getActionIntent(Bundle container) {
-        return container.getParcelable(ACTION_INTENT);
-    }
+  /** Returns a list of entities contained in the {@code extra}. */
+  @Nullable
+  @VisibleForTesting
+  public static List<Bundle> getEntities(Bundle container) {
+    return container.getParcelableArrayList(ENTITIES);
+  }
 
-    /**
-     * Stores serialized entity data information in TextClassifier response object's extras {@code
-     * container}.
-     */
-    public static void putSerializedEntityData(
-            Bundle container, @Nullable byte[] serializedEntityData) {
-        container.putByteArray(SERIALIZED_ENTITIES_DATA, serializedEntityData);
-    }
+  /** Whether the annotator should populate serialized entity data into the result object. */
+  public static boolean isSerializedEntityDataEnabled(TextLinks.Request request) {
+    return request.getExtras().getBoolean(IS_SERIALIZED_ENTITY_DATA_ENABLED);
+  }
 
-    /** Returns serialized entity data information contained in a TextClassifier response object. */
-    @Nullable
-    public static byte[] getSerializedEntityData(Bundle container) {
-        return container.getByteArray(SERIALIZED_ENTITIES_DATA);
-    }
-
-    /**
-     * Stores {@code entities} information in TextClassifier response object's extras {@code
-     * container}.
-     *
-     * @see {@link #getCopyText(Bundle)}
-     */
-    public static void putEntitiesExtras(Bundle container, @Nullable Bundle entitiesExtras) {
-        container.putParcelable(ENTITIES_EXTRAS, entitiesExtras);
-    }
-
-    /**
-     * Returns {@code entities} information contained in a TextClassifier response object.
-     *
-     * @see {@link #putEntitiesExtras(Bundle, Bundle)}
-     */
-    @Nullable
-    public static String getCopyText(Bundle container) {
-        Bundle entitiesExtras = container.getParcelable(ENTITIES_EXTRAS);
-        if (entitiesExtras == null) {
-            return null;
-        }
-        return entitiesExtras.getString("text");
-    }
-
-    /** Returns {@code actionIntents} information contained in the TextClassification object. */
-    @Nullable
-    public static ArrayList<Intent> getActionsIntents(@Nullable TextClassification classification) {
-        if (classification == null) {
-            return null;
-        }
-        return classification.getExtras().getParcelableArrayList(ACTIONS_INTENTS);
-    }
-
-    /**
-     * Returns the first action found in the {@code classification} object with an intent action
-     * string, {@code intentAction}.
-     */
-    @Nullable
-    @VisibleForTesting
-    public static RemoteAction findAction(
-            @Nullable TextClassification classification, @Nullable String intentAction) {
-        if (classification == null || intentAction == null) {
-            return null;
-        }
-        final ArrayList<Intent> actionIntents = getActionsIntents(classification);
-        if (actionIntents != null) {
-            final int size = actionIntents.size();
-            for (int i = 0; i < size; i++) {
-                final Intent intent = actionIntents.get(i);
-                if (intent != null && intentAction.equals(intent.getAction())) {
-                    return classification.getActions().get(i);
-                }
-            }
-        }
-        return null;
-    }
-
-    /** Returns the first "translate" action found in the {@code classification} object. */
-    @Nullable
-    @VisibleForTesting
-    public static RemoteAction findTranslateAction(@Nullable TextClassification classification) {
-        return findAction(classification, Intent.ACTION_TRANSLATE);
-    }
-
-    /** Returns the entity type contained in the {@code extra}. */
-    @Nullable
-    @VisibleForTesting
-    public static String getEntityType(@Nullable Bundle extra) {
-        if (extra == null) {
-            return null;
-        }
-        return extra.getString(ENTITY_TYPE);
-    }
-
-    /** Returns the score contained in the {@code extra}. */
-    @VisibleForTesting
-    public static float getScore(Bundle extra) {
-        final int defaultValue = -1;
-        if (extra == null) {
-            return defaultValue;
-        }
-        return extra.getFloat(SCORE, defaultValue);
-    }
-
-    /** Returns the model name contained in the {@code extra}. */
-    @Nullable
-    public static String getModelName(@Nullable Bundle extra) {
-        if (extra == null) {
-            return null;
-        }
-        return extra.getString(MODEL_NAME);
-    }
-
-    /**
-     * Stores the entities from {@link AnnotatorModel.ClassificationResult} in {@code container}.
-     */
-    public static void putEntities(
-            Bundle container, @Nullable AnnotatorModel.ClassificationResult[] classifications) {
-        if (classifications == null || classifications.length == 0) {
-            return;
-        }
-        ArrayList<Bundle> entitiesBundle = new ArrayList<>();
-        for (AnnotatorModel.ClassificationResult classification : classifications) {
-            if (classification == null) {
-                continue;
-            }
-            Bundle entityBundle = new Bundle();
-            entityBundle.putString(ENTITY_TYPE, classification.getCollection());
-            entityBundle.putByteArray(
-                    SERIALIZED_ENTITIES_DATA, classification.getSerializedEntityData());
-            entitiesBundle.add(entityBundle);
-        }
-        if (!entitiesBundle.isEmpty()) {
-            container.putParcelableArrayList(ENTITIES, entitiesBundle);
-        }
-    }
-
-    /** Returns a list of entities contained in the {@code extra}. */
-    @Nullable
-    @VisibleForTesting
-    public static List<Bundle> getEntities(Bundle container) {
-        return container.getParcelableArrayList(ENTITIES);
-    }
-
-    /** Whether the annotator should populate serialized entity data into the result object. */
-    public static boolean isSerializedEntityDataEnabled(TextLinks.Request request) {
-        return request.getExtras().getBoolean(IS_SERIALIZED_ENTITY_DATA_ENABLED);
-    }
-
-    /**
-     * To indicate whether the annotator should populate serialized entity data in the result
-     * object.
-     */
-    @VisibleForTesting
-    public static void putIsSerializedEntityDataEnabled(Bundle bundle, boolean isEnabled) {
-        bundle.putBoolean(IS_SERIALIZED_ENTITY_DATA_ENABLED, isEnabled);
-    }
+  /**
+   * To indicate whether the annotator should populate serialized entity data in the result object.
+   */
+  @VisibleForTesting
+  public static void putIsSerializedEntityDataEnabled(Bundle bundle, boolean isEnabled) {
+    bundle.putBoolean(IS_SERIALIZED_ENTITY_DATA_ENABLED, isEnabled);
+  }
 }
diff --git a/java/src/com/android/textclassifier/ModelFileManager.java b/java/src/com/android/textclassifier/ModelFileManager.java
index 69ae40e..1d8bf3e 100644
--- a/java/src/com/android/textclassifier/ModelFileManager.java
+++ b/java/src/com/android/textclassifier/ModelFileManager.java
@@ -13,16 +13,14 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package com.android.textclassifier;
 
 import android.os.LocaleList;
 import android.os.ParcelFileDescriptor;
 import android.text.TextUtils;
-
-import androidx.annotation.Nullable;
-import androidx.annotation.VisibleForTesting;
-import androidx.core.util.Preconditions;
-
+import com.google.common.base.Preconditions;
+import com.google.common.base.Splitter;
 import java.io.File;
 import java.io.FileNotFoundException;
 import java.io.IOException;
@@ -36,263 +34,262 @@
 import java.util.function.Supplier;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
+import javax.annotation.Nullable;
 
 /** Manages model files that are listed by the model files supplier. */
-@VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE)
-public final class ModelFileManager {
-    private static final String TAG = "ModelFileManager";
+final class ModelFileManager {
+  private static final String TAG = "ModelFileManager";
 
-    private final Object mLock = new Object();
-    private final Supplier<List<ModelFile>> mModelFileSupplier;
+  private final Object lock = new Object();
+  private final Supplier<List<ModelFile>> modelFileSupplier;
 
-    private List<ModelFile> mModelFiles;
+  private List<ModelFile> modelFiles;
 
-    public ModelFileManager(Supplier<List<ModelFile>> modelFileSupplier) {
-        mModelFileSupplier = Preconditions.checkNotNull(modelFileSupplier);
+  public ModelFileManager(Supplier<List<ModelFile>> modelFileSupplier) {
+    this.modelFileSupplier = Preconditions.checkNotNull(modelFileSupplier);
+  }
+
+  /**
+   * Returns an unmodifiable list of model files listed by the given model files supplier.
+   *
+   * <p>The result is cached.
+   */
+  public List<ModelFile> listModelFiles() {
+    synchronized (lock) {
+      if (modelFiles == null) {
+        modelFiles = Collections.unmodifiableList(modelFileSupplier.get());
+      }
+      return modelFiles;
+    }
+  }
+
+  /**
+   * Returns the best model file for the given localelist, {@code null} if nothing is found.
+   *
+   * @param localeList the required locales, use {@code null} if there is no preference.
+   */
+  public ModelFile findBestModelFile(@Nullable LocaleList localeList) {
+    final String languages =
+        localeList == null || localeList.isEmpty()
+            ? LocaleList.getDefault().toLanguageTags()
+            : localeList.toLanguageTags();
+    final List<Locale.LanguageRange> languageRangeList = Locale.LanguageRange.parse(languages);
+
+    ModelFile bestModel = null;
+    for (ModelFile model : listModelFiles()) {
+      if (model.isAnyLanguageSupported(languageRangeList)) {
+        if (model.isPreferredTo(bestModel)) {
+          bestModel = model;
+        }
+      }
+    }
+    return bestModel;
+  }
+
+  /** Default implementation of the model file supplier. */
+  public static final class ModelFileSupplierImpl implements Supplier<List<ModelFile>> {
+    private final File updatedModelFile;
+    private final File factoryModelDir;
+    private final Pattern modelFilenamePattern;
+    private final Function<Integer, Integer> versionSupplier;
+    private final Function<Integer, String> supportedLocalesSupplier;
+
+    public ModelFileSupplierImpl(
+        File factoryModelDir,
+        String factoryModelFileNameRegex,
+        File updatedModelFile,
+        Function<Integer, Integer> versionSupplier,
+        Function<Integer, String> supportedLocalesSupplier) {
+      this.updatedModelFile = Preconditions.checkNotNull(updatedModelFile);
+      this.factoryModelDir = Preconditions.checkNotNull(factoryModelDir);
+      modelFilenamePattern = Pattern.compile(Preconditions.checkNotNull(factoryModelFileNameRegex));
+      this.versionSupplier = Preconditions.checkNotNull(versionSupplier);
+      this.supportedLocalesSupplier = Preconditions.checkNotNull(supportedLocalesSupplier);
     }
 
-    /**
-     * Returns an unmodifiable list of model files listed by the given model files supplier.
-     *
-     * <p>The result is cached.
-     */
-    public List<ModelFile> listModelFiles() {
-        synchronized (mLock) {
-            if (mModelFiles == null) {
-                mModelFiles = Collections.unmodifiableList(mModelFileSupplier.get());
-            }
-            return mModelFiles;
+    @Override
+    public List<ModelFile> get() {
+      final List<ModelFile> modelFiles = new ArrayList<>();
+      // The update model has the highest precedence.
+      if (updatedModelFile.exists()) {
+        final ModelFile updatedModel = createModelFile(updatedModelFile);
+        if (updatedModel != null) {
+          modelFiles.add(updatedModel);
         }
+      }
+      // Factory models should never have overlapping locales, so the order doesn't matter.
+      if (factoryModelDir.exists() && factoryModelDir.isDirectory()) {
+        final File[] files = factoryModelDir.listFiles();
+        for (File file : files) {
+          final Matcher matcher = modelFilenamePattern.matcher(file.getName());
+          if (matcher.matches() && file.isFile()) {
+            final ModelFile model = createModelFile(file);
+            if (model != null) {
+              modelFiles.add(model);
+            }
+          }
+        }
+      }
+      return modelFiles;
     }
 
-    /**
-     * Returns the best model file for the given localelist, {@code null} if nothing is found.
-     *
-     * @param localeList the required locales, use {@code null} if there is no preference.
-     */
-    public ModelFile findBestModelFile(@Nullable LocaleList localeList) {
-        final String languages =
-                localeList == null || localeList.isEmpty()
-                        ? LocaleList.getDefault().toLanguageTags()
-                        : localeList.toLanguageTags();
-        final List<Locale.LanguageRange> languageRangeList = Locale.LanguageRange.parse(languages);
-
-        ModelFile bestModel = null;
-        for (ModelFile model : listModelFiles()) {
-            if (model.isAnyLanguageSupported(languageRangeList)) {
-                if (model.isPreferredTo(bestModel)) {
-                    bestModel = model;
-                }
-            }
+    /** Returns null if the path did not point to a compatible model. */
+    @Nullable
+    private ModelFile createModelFile(File file) {
+      if (!file.exists()) {
+        return null;
+      }
+      ParcelFileDescriptor modelFd = null;
+      try {
+        modelFd = ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY);
+        if (modelFd == null) {
+          return null;
         }
-        return bestModel;
+        final int modelFdInt = modelFd.getFd();
+        final int version = versionSupplier.apply(modelFdInt);
+        final String supportedLocalesStr = supportedLocalesSupplier.apply(modelFdInt);
+        if (supportedLocalesStr.isEmpty()) {
+          TcLog.d(TAG, "Ignoring " + file.getAbsolutePath());
+          return null;
+        }
+        final List<Locale> supportedLocales = new ArrayList<>();
+        for (String langTag : Splitter.on(',').split(supportedLocalesStr)) {
+          supportedLocales.add(Locale.forLanguageTag(langTag));
+        }
+        return new ModelFile(
+            file,
+            version,
+            supportedLocales,
+            supportedLocalesStr,
+            ModelFile.LANGUAGE_INDEPENDENT.equals(supportedLocalesStr));
+      } catch (FileNotFoundException e) {
+        TcLog.e(TAG, "Failed to find " + file.getAbsolutePath(), e);
+        return null;
+      } finally {
+        maybeCloseAndLogError(modelFd);
+      }
     }
 
-    /** Default implementation of the model file supplier. */
-    public static final class ModelFileSupplierImpl implements Supplier<List<ModelFile>> {
-        private final File mUpdatedModelFile;
-        private final File mFactoryModelDir;
-        private final Pattern mModelFilenamePattern;
-        private final Function<Integer, Integer> mVersionSupplier;
-        private final Function<Integer, String> mSupportedLocalesSupplier;
+    /** Closes the ParcelFileDescriptor, if non-null, and logs any errors that occur. */
+    private static void maybeCloseAndLogError(@Nullable ParcelFileDescriptor fd) {
+      if (fd == null) {
+        return;
+      }
+      try {
+        fd.close();
+      } catch (IOException e) {
+        TcLog.e(TAG, "Error closing file.", e);
+      }
+    }
+  }
 
-        public ModelFileSupplierImpl(
-                File factoryModelDir,
-                String factoryModelFileNameRegex,
-                File updatedModelFile,
-                Function<Integer, Integer> versionSupplier,
-                Function<Integer, String> supportedLocalesSupplier) {
-            mUpdatedModelFile = Preconditions.checkNotNull(updatedModelFile);
-            mFactoryModelDir = Preconditions.checkNotNull(factoryModelDir);
-            mModelFilenamePattern =
-                    Pattern.compile(Preconditions.checkNotNull(factoryModelFileNameRegex));
-            mVersionSupplier = Preconditions.checkNotNull(versionSupplier);
-            mSupportedLocalesSupplier = Preconditions.checkNotNull(supportedLocalesSupplier);
-        }
+  /** Describes TextClassifier model files on disk. */
+  public static final class ModelFile {
+    public static final String LANGUAGE_INDEPENDENT = "*";
 
-        @Override
-        public List<ModelFile> get() {
-            final List<ModelFile> modelFiles = new ArrayList<>();
-            // The update model has the highest precedence.
-            if (mUpdatedModelFile.exists()) {
-                final ModelFile updatedModel = createModelFile(mUpdatedModelFile);
-                if (updatedModel != null) {
-                    modelFiles.add(updatedModel);
-                }
-            }
-            // Factory models should never have overlapping locales, so the order doesn't matter.
-            if (mFactoryModelDir.exists() && mFactoryModelDir.isDirectory()) {
-                final File[] files = mFactoryModelDir.listFiles();
-                for (File file : files) {
-                    final Matcher matcher = mModelFilenamePattern.matcher(file.getName());
-                    if (matcher.matches() && file.isFile()) {
-                        final ModelFile model = createModelFile(file);
-                        if (model != null) {
-                            modelFiles.add(model);
-                        }
-                    }
-                }
-            }
-            return modelFiles;
-        }
+    private final File file;
+    private final int version;
+    private final List<Locale> supportedLocales;
+    private final String supportedLocalesStr;
+    private final boolean languageIndependent;
 
-        /** Returns null if the path did not point to a compatible model. */
-        @Nullable
-        private ModelFile createModelFile(File file) {
-            if (!file.exists()) {
-                return null;
-            }
-            ParcelFileDescriptor modelFd = null;
-            try {
-                modelFd = ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY);
-                if (modelFd == null) {
-                    return null;
-                }
-                final int modelFdInt = modelFd.getFd();
-                final int version = mVersionSupplier.apply(modelFdInt);
-                final String supportedLocalesStr = mSupportedLocalesSupplier.apply(modelFdInt);
-                if (supportedLocalesStr.isEmpty()) {
-                    TcLog.d(TAG, "Ignoring " + file.getAbsolutePath());
-                    return null;
-                }
-                final List<Locale> supportedLocales = new ArrayList<>();
-                for (String langTag : supportedLocalesStr.split(",")) {
-                    supportedLocales.add(Locale.forLanguageTag(langTag));
-                }
-                return new ModelFile(
-                        file,
-                        version,
-                        supportedLocales,
-                        supportedLocalesStr,
-                        ModelFile.LANGUAGE_INDEPENDENT.equals(supportedLocalesStr));
-            } catch (FileNotFoundException e) {
-                TcLog.e(TAG, "Failed to find " + file.getAbsolutePath(), e);
-                return null;
-            } finally {
-                maybeCloseAndLogError(modelFd);
-            }
-        }
-
-        /** Closes the ParcelFileDescriptor, if non-null, and logs any errors that occur. */
-        private static void maybeCloseAndLogError(@Nullable ParcelFileDescriptor fd) {
-            if (fd == null) {
-                return;
-            }
-            try {
-                fd.close();
-            } catch (IOException e) {
-                TcLog.e(TAG, "Error closing file.", e);
-            }
-        }
+    public ModelFile(
+        File file,
+        int version,
+        List<Locale> supportedLocales,
+        String supportedLocalesStr,
+        boolean languageIndependent) {
+      this.file = Preconditions.checkNotNull(file);
+      this.version = version;
+      this.supportedLocales = Preconditions.checkNotNull(supportedLocales);
+      this.supportedLocalesStr = Preconditions.checkNotNull(supportedLocalesStr);
+      this.languageIndependent = languageIndependent;
     }
 
-    /** Describes TextClassifier model files on disk. */
-    public static final class ModelFile {
-        public static final String LANGUAGE_INDEPENDENT = "*";
-
-        private final File mFile;
-        private final int mVersion;
-        private final List<Locale> mSupportedLocales;
-        private final String mSupportedLocalesStr;
-        private final boolean mLanguageIndependent;
-
-        public ModelFile(
-                File file,
-                int version,
-                List<Locale> supportedLocales,
-                String supportedLocalesStr,
-                boolean languageIndependent) {
-            mFile = Preconditions.checkNotNull(file);
-            mVersion = version;
-            mSupportedLocales = Preconditions.checkNotNull(supportedLocales);
-            mSupportedLocalesStr = Preconditions.checkNotNull(supportedLocalesStr);
-            mLanguageIndependent = languageIndependent;
-        }
-
-        /** Returns the absolute path to the model file. */
-        public String getPath() {
-            return mFile.getAbsolutePath();
-        }
-
-        /** Returns a name to use for id generation, effectively the name of the model file. */
-        public String getName() {
-            return mFile.getName();
-        }
-
-        /** Returns the version tag in the model's metadata. */
-        public int getVersion() {
-            return mVersion;
-        }
-
-        /** Returns whether the language supports any language in the given ranges. */
-        public boolean isAnyLanguageSupported(List<Locale.LanguageRange> languageRanges) {
-            Preconditions.checkNotNull(languageRanges);
-            return mLanguageIndependent || Locale.lookup(languageRanges, mSupportedLocales) != null;
-        }
-
-        /** Returns an immutable lists of supported locales. */
-        public List<Locale> getSupportedLocales() {
-            return Collections.unmodifiableList(mSupportedLocales);
-        }
-
-        /** Returns the original supported locals string read from the model file. */
-        public String getSupportedLocalesStr() {
-            return mSupportedLocalesStr;
-        }
-
-        /** Returns if this model file is preferred to the given one. */
-        public boolean isPreferredTo(@Nullable ModelFile model) {
-            // A model is preferred to no model.
-            if (model == null) {
-                return true;
-            }
-
-            // A language-specific model is preferred to a language independent
-            // model.
-            if (!mLanguageIndependent && model.mLanguageIndependent) {
-                return true;
-            }
-            if (mLanguageIndependent && !model.mLanguageIndependent) {
-                return false;
-            }
-
-            // A higher-version model is preferred.
-            if (mVersion > model.getVersion()) {
-                return true;
-            }
-            return false;
-        }
-
-        @Override
-        public int hashCode() {
-            return Objects.hash(getPath());
-        }
-
-        @Override
-        public boolean equals(Object other) {
-            if (this == other) {
-                return true;
-            }
-            if (other instanceof ModelFile) {
-                final ModelFile otherModel = (ModelFile) other;
-                return TextUtils.equals(getPath(), otherModel.getPath());
-            }
-            return false;
-        }
-
-        @Override
-        public String toString() {
-            final StringJoiner localesJoiner = new StringJoiner(",");
-            for (Locale locale : mSupportedLocales) {
-                localesJoiner.add(locale.toLanguageTag());
-            }
-            return String.format(
-                    Locale.US,
-                    "ModelFile { path=%s name=%s version=%d locales=%s }",
-                    getPath(),
-                    getName(),
-                    mVersion,
-                    localesJoiner.toString());
-        }
+    /** Returns the absolute path to the model file. */
+    public String getPath() {
+      return file.getAbsolutePath();
     }
+
+    /** Returns a name to use for id generation, effectively the name of the model file. */
+    public String getName() {
+      return file.getName();
+    }
+
+    /** Returns the version tag in the model's metadata. */
+    public int getVersion() {
+      return version;
+    }
+
+    /** Returns whether the language supports any language in the given ranges. */
+    public boolean isAnyLanguageSupported(List<Locale.LanguageRange> languageRanges) {
+      Preconditions.checkNotNull(languageRanges);
+      return languageIndependent || Locale.lookup(languageRanges, supportedLocales) != null;
+    }
+
+    /** Returns an immutable lists of supported locales. */
+    public List<Locale> getSupportedLocales() {
+      return Collections.unmodifiableList(supportedLocales);
+    }
+
+    /** Returns the original supported locals string read from the model file. */
+    public String getSupportedLocalesStr() {
+      return supportedLocalesStr;
+    }
+
+    /** Returns if this model file is preferred to the given one. */
+    public boolean isPreferredTo(@Nullable ModelFile model) {
+      // A model is preferred to no model.
+      if (model == null) {
+        return true;
+      }
+
+      // A language-specific model is preferred to a language independent
+      // model.
+      if (!languageIndependent && model.languageIndependent) {
+        return true;
+      }
+      if (languageIndependent && !model.languageIndependent) {
+        return false;
+      }
+
+      // A higher-version model is preferred.
+      if (version > model.getVersion()) {
+        return true;
+      }
+      return false;
+    }
+
+    @Override
+    public int hashCode() {
+      return Objects.hash(getPath());
+    }
+
+    @Override
+    public boolean equals(Object other) {
+      if (this == other) {
+        return true;
+      }
+      if (other instanceof ModelFile) {
+        final ModelFile otherModel = (ModelFile) other;
+        return TextUtils.equals(getPath(), otherModel.getPath());
+      }
+      return false;
+    }
+
+    @Override
+    public String toString() {
+      final StringJoiner localesJoiner = new StringJoiner(",");
+      for (Locale locale : supportedLocales) {
+        localesJoiner.add(locale.toLanguageTag());
+      }
+      return String.format(
+          Locale.US,
+          "ModelFile { path=%s name=%s version=%d locales=%s }",
+          getPath(),
+          getName(),
+          version,
+          localesJoiner);
+    }
+  }
 }
diff --git a/java/src/com/android/textclassifier/StringUtils.java b/java/src/com/android/textclassifier/StringUtils.java
index d4968c8..a32d5e4 100644
--- a/java/src/com/android/textclassifier/StringUtils.java
+++ b/java/src/com/android/textclassifier/StringUtils.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2018 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -11,14 +11,13 @@
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
  */
 
 package com.android.textclassifier;
 
 import androidx.annotation.GuardedBy;
-import androidx.core.util.Preconditions;
-
+import com.google.common.base.Preconditions;
 import java.text.BreakIterator;
 
 /**
@@ -31,52 +30,54 @@
  * Intended to be used only for TextClassifier purposes.
  */
 public final class StringUtils {
-    private static final String TAG = "StringUtils";
+  private static final String TAG = "StringUtils";
 
-    @GuardedBy("WORD_ITERATOR")
-    private static final BreakIterator WORD_ITERATOR = BreakIterator.getWordInstance();
+  @GuardedBy("WORD_ITERATOR")
+  private static final BreakIterator WORD_ITERATOR = BreakIterator.getWordInstance();
 
-    /**
-     * Returns the substring of {@code text} that contains at least text from index {@code start}
-     * <i>(inclusive)</i> to index {@code end} <i><(exclusive)/i> with the goal of returning text
-     * that is at least {@code minimumLength}. If {@code text} is not long enough, this will return
-     * {@code text}. This method returns text at word boundaries.
-     *
-     * @param text the source text
-     * @param start the start index of text that must be included
-     * @param end the end index of text that must be included
-     * @param minimumLength minimum length of text to return if {@code text} is long enough
-     */
-    public static String getSubString(String text, int start, int end, int minimumLength) {
-        Preconditions.checkArgument(start >= 0);
-        Preconditions.checkArgument(end <= text.length());
-        Preconditions.checkArgument(start <= end);
+  /**
+   * Returns the substring of {@code text} that contains at least text from index {@code start}
+   * <i>(inclusive)</i> to index {@code end} <i><(exclusive)/i> with the goal of returning text that
+   * is at least {@code minimumLength}. If {@code text} is not long enough, this will return {@code
+   * text}. This method returns text at word boundaries.
+   *
+   * @param text the source text
+   * @param start the start index of text that must be included
+   * @param end the end index of text that must be included
+   * @param minimumLength minimum length of text to return if {@code text} is long enough
+   */
+  public static String getSubString(String text, int start, int end, int minimumLength) {
+    Preconditions.checkArgument(start >= 0);
+    Preconditions.checkArgument(end <= text.length());
+    Preconditions.checkArgument(start <= end);
 
-        if (text.length() < minimumLength) {
-            return text;
-        }
-
-        final int length = end - start;
-        if (length >= minimumLength) {
-            return text.substring(start, end);
-        }
-
-        final int offset = (minimumLength - length) / 2;
-        int iterStart = Math.max(0, Math.min(start - offset, text.length() - minimumLength));
-        int iterEnd = Math.min(text.length(), iterStart + minimumLength);
-
-        synchronized (WORD_ITERATOR) {
-            WORD_ITERATOR.setText(text);
-            iterStart =
-                    WORD_ITERATOR.isBoundary(iterStart)
-                            ? iterStart
-                            : Math.max(0, WORD_ITERATOR.preceding(iterStart));
-            iterEnd =
-                    WORD_ITERATOR.isBoundary(iterEnd)
-                            ? iterEnd
-                            : Math.max(iterEnd, WORD_ITERATOR.following(iterEnd));
-            WORD_ITERATOR.setText("");
-            return text.substring(iterStart, iterEnd);
-        }
+    if (text.length() < minimumLength) {
+      return text;
     }
+
+    final int length = end - start;
+    if (length >= minimumLength) {
+      return text.substring(start, end);
+    }
+
+    final int offset = (minimumLength - length) / 2;
+    int iterStart = Math.max(0, Math.min(start - offset, text.length() - minimumLength));
+    int iterEnd = Math.min(text.length(), iterStart + minimumLength);
+
+    synchronized (WORD_ITERATOR) {
+      WORD_ITERATOR.setText(text);
+      iterStart =
+          WORD_ITERATOR.isBoundary(iterStart)
+              ? iterStart
+              : Math.max(0, WORD_ITERATOR.preceding(iterStart));
+      iterEnd =
+          WORD_ITERATOR.isBoundary(iterEnd)
+              ? iterEnd
+              : Math.max(iterEnd, WORD_ITERATOR.following(iterEnd));
+      WORD_ITERATOR.setText("");
+      return text.substring(iterStart, iterEnd);
+    }
+  }
+
+  private StringUtils() {}
 }
diff --git a/java/src/com/android/textclassifier/TcLog.java b/java/src/com/android/textclassifier/TcLog.java
index 0c664ed..581d660 100644
--- a/java/src/com/android/textclassifier/TcLog.java
+++ b/java/src/com/android/textclassifier/TcLog.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 The Android Open Source Project
+ * Copyright (C) 2018 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -25,34 +25,34 @@
  * @hide
  */
 public final class TcLog {
-    private static final boolean USE_TC_TAG = true;
-    public static final String TAG = "androidtc";
+  private static final boolean USE_TC_TAG = true;
+  public static final String TAG = "androidtc";
 
-    /** true: Enables full logging. false: Limits logging to debug level. */
-    public static final boolean ENABLE_FULL_LOGGING =
-            android.util.Log.isLoggable(TAG, android.util.Log.VERBOSE);
+  /** true: Enables full logging. false: Limits logging to debug level. */
+  public static final boolean ENABLE_FULL_LOGGING =
+      android.util.Log.isLoggable(TAG, android.util.Log.VERBOSE);
 
-    private TcLog() {}
+  private TcLog() {}
 
-    public static void v(String tag, String msg) {
-        if (ENABLE_FULL_LOGGING) {
-            android.util.Log.v(getTag(tag), msg);
-        }
+  public static void v(String tag, String msg) {
+    if (ENABLE_FULL_LOGGING) {
+      android.util.Log.v(getTag(tag), msg);
     }
+  }
 
-    public static void d(String tag, String msg) {
-        android.util.Log.d(getTag(tag), msg);
-    }
+  public static void d(String tag, String msg) {
+    android.util.Log.d(getTag(tag), msg);
+  }
 
-    public static void w(String tag, String msg) {
-        android.util.Log.w(getTag(tag), msg);
-    }
+  public static void w(String tag, String msg) {
+    android.util.Log.w(getTag(tag), msg);
+  }
 
-    public static void e(String tag, String msg, Throwable tr) {
-        android.util.Log.e(getTag(tag), msg, tr);
-    }
+  public static void e(String tag, String msg, Throwable tr) {
+    android.util.Log.e(getTag(tag), msg, tr);
+  }
 
-    private static String getTag(String customTag) {
-        return USE_TC_TAG ? TAG : customTag;
-    }
+  private static String getTag(String customTag) {
+    return USE_TC_TAG ? TAG : customTag;
+  }
 }
diff --git a/java/src/com/android/textclassifier/TextClassificationConstants.java b/java/src/com/android/textclassifier/TextClassificationConstants.java
index f70c5ac..11b5179 100644
--- a/java/src/com/android/textclassifier/TextClassificationConstants.java
+++ b/java/src/com/android/textclassifier/TextClassificationConstants.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 The Android Open Source Project
+ * Copyright (C) 2018 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -19,14 +19,13 @@
 import android.provider.DeviceConfig;
 import android.view.textclassifier.ConversationAction;
 import android.view.textclassifier.TextClassifier;
-
-import androidx.annotation.Nullable;
-
 import com.android.textclassifier.utils.IndentingPrintWriter;
-
+import com.google.common.base.Splitter;
+import com.google.common.collect.ImmutableList;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
+import javax.annotation.Nullable;
 
 /**
  * TextClassifier specific settings.
@@ -43,318 +42,311 @@
  */
 // TODO: Rename to TextClassifierSettings.
 public final class TextClassificationConstants {
-    private static final String DELIMITER = ":";
+  private static final String DELIMITER = ":";
 
-    /** Whether the user language profile feature is enabled. */
-    private static final String USER_LANGUAGE_PROFILE_ENABLED = "user_language_profile_enabled";
-    /** Max length of text that suggestSelection can accept. */
-    private static final String SUGGEST_SELECTION_MAX_RANGE_LENGTH =
-            "suggest_selection_max_range_length";
-    /** Max length of text that classifyText can accept. */
-    private static final String CLASSIFY_TEXT_MAX_RANGE_LENGTH = "classify_text_max_range_length";
-    /** Max length of text that generateLinks can accept. */
-    private static final String GENERATE_LINKS_MAX_TEXT_LENGTH = "generate_links_max_text_length";
-    /** Sampling rate for generateLinks logging. */
-    private static final String GENERATE_LINKS_LOG_SAMPLE_RATE = "generate_links_log_sample_rate";
-    /**
-     * Extra count that is added to some languages, e.g. system languages, when deducing the
-     * frequent languages in {@link
-     * com.android.textclassifier.ulp.LanguageProfileAnalyzer#getFrequentLanguages(int)}.
-     */
-    private static final String FREQUENT_LANGUAGES_BOOTSTRAPPING_COUNT =
-            "frequent_languages_bootstrapping_count";
+  /** Whether the user language profile feature is enabled. */
+  private static final String USER_LANGUAGE_PROFILE_ENABLED = "user_language_profile_enabled";
+  /** Max length of text that suggestSelection can accept. */
+  private static final String SUGGEST_SELECTION_MAX_RANGE_LENGTH =
+      "suggest_selection_max_range_length";
+  /** Max length of text that classifyText can accept. */
+  private static final String CLASSIFY_TEXT_MAX_RANGE_LENGTH = "classify_text_max_range_length";
+  /** Max length of text that generateLinks can accept. */
+  private static final String GENERATE_LINKS_MAX_TEXT_LENGTH = "generate_links_max_text_length";
+  /** Sampling rate for generateLinks logging. */
+  private static final String GENERATE_LINKS_LOG_SAMPLE_RATE = "generate_links_log_sample_rate";
+  /**
+   * Extra count that is added to some languages, e.g. system languages, when deducing the frequent
+   * languages in {@link
+   * com.android.textclassifier.ulp.LanguageProfileAnalyzer#getFrequentLanguages(int)}.
+   */
+  private static final String FREQUENT_LANGUAGES_BOOTSTRAPPING_COUNT =
+      "frequent_languages_bootstrapping_count";
 
-    /**
-     * Default count for the language in the system settings while calculating {@code
-     * LanguageProfileAnalyzer.getRecognizedLanguages()}
-     */
-    private static final String LANGUAGE_PROFICIENCY_BOOTSTRAPPING_COUNT =
-            "language_proficiency_bootstrapping_count";
+  /**
+   * Default count for the language in the system settings while calculating {@code
+   * LanguageProfileAnalyzer.getRecognizedLanguages()}
+   */
+  private static final String LANGUAGE_PROFICIENCY_BOOTSTRAPPING_COUNT =
+      "language_proficiency_bootstrapping_count";
 
-    /**
-     * A colon(:) separated string that specifies the default entities types for generateLinks when
-     * hint is not given.
-     */
-    private static final String ENTITY_LIST_DEFAULT = "entity_list_default";
-    /**
-     * A colon(:) separated string that specifies the default entities types for generateLinks when
-     * the text is in a not editable UI widget.
-     */
-    private static final String ENTITY_LIST_NOT_EDITABLE = "entity_list_not_editable";
-    /**
-     * A colon(:) separated string that specifies the default entities types for generateLinks when
-     * the text is in an editable UI widget.
-     */
-    private static final String ENTITY_LIST_EDITABLE = "entity_list_editable";
-    /**
-     * A colon(:) separated string that specifies the default action types for
-     * suggestConversationActions when the suggestions are used in an app.
-     */
-    private static final String IN_APP_CONVERSATION_ACTION_TYPES_DEFAULT =
-            "in_app_conversation_action_types_default";
-    /**
-     * A colon(:) separated string that specifies the default action types for
-     * suggestConversationActions when the suggestions are used in a notification.
-     */
-    private static final String NOTIFICATION_CONVERSATION_ACTION_TYPES_DEFAULT =
-            "notification_conversation_action_types_default";
-    /** Threshold to accept a suggested language from LangID model. */
-    private static final String LANG_ID_THRESHOLD_OVERRIDE = "lang_id_threshold_override";
-    /** Whether to enable {@link com.android.textclassifier.intent.TemplateIntentFactory}. */
-    private static final String TEMPLATE_INTENT_FACTORY_ENABLED = "template_intent_factory_enabled";
-    /** Whether to enable "translate" action in classifyText. */
-    private static final String TRANSLATE_IN_CLASSIFICATION_ENABLED =
-            "translate_in_classification_enabled";
-    /**
-     * Whether to detect the languages of the text in request by using langId for the native model.
-     */
-    private static final String DETECT_LANGUAGES_FROM_TEXT_ENABLED =
-            "detect_languages_from_text_enabled";
-    /**
-     * A colon(:) separated string that specifies the configuration to use when including
-     * surrounding context text in language detection queries.
-     *
-     * <p>Format= minimumTextSize<int>:penalizeRatio<float>:textScoreRatio<float>
-     *
-     * <p>e.g. 20:1.0:0.4
-     *
-     * <p>Accept all text lengths with minimumTextSize=0
-     *
-     * <p>Reject all text less than minimumTextSize with penalizeRatio=0
-     *
-     * @see {@code TextClassifierImpl#detectLanguages(String, int, int)} for reference.
-     */
-    private static final String LANG_ID_CONTEXT_SETTINGS = "lang_id_context_settings";
-    /** Default threshold to translate the language of the context the user selects */
-    private static final String TRANSLATE_ACTION_THRESHOLD = "translate_action_threshold";
+  /**
+   * A colon(:) separated string that specifies the default entities types for generateLinks when
+   * hint is not given.
+   */
+  private static final String ENTITY_LIST_DEFAULT = "entity_list_default";
+  /**
+   * A colon(:) separated string that specifies the default entities types for generateLinks when
+   * the text is in a not editable UI widget.
+   */
+  private static final String ENTITY_LIST_NOT_EDITABLE = "entity_list_not_editable";
+  /**
+   * A colon(:) separated string that specifies the default entities types for generateLinks when
+   * the text is in an editable UI widget.
+   */
+  private static final String ENTITY_LIST_EDITABLE = "entity_list_editable";
+  /**
+   * A colon(:) separated string that specifies the default action types for
+   * suggestConversationActions when the suggestions are used in an app.
+   */
+  private static final String IN_APP_CONVERSATION_ACTION_TYPES_DEFAULT =
+      "in_app_conversation_action_types_default";
+  /**
+   * A colon(:) separated string that specifies the default action types for
+   * suggestConversationActions when the suggestions are used in a notification.
+   */
+  private static final String NOTIFICATION_CONVERSATION_ACTION_TYPES_DEFAULT =
+      "notification_conversation_action_types_default";
+  /** Threshold to accept a suggested language from LangID model. */
+  private static final String LANG_ID_THRESHOLD_OVERRIDE = "lang_id_threshold_override";
+  /** Whether to enable {@link com.android.textclassifier.intent.TemplateIntentFactory}. */
+  private static final String TEMPLATE_INTENT_FACTORY_ENABLED = "template_intent_factory_enabled";
+  /** Whether to enable "translate" action in classifyText. */
+  private static final String TRANSLATE_IN_CLASSIFICATION_ENABLED =
+      "translate_in_classification_enabled";
+  /**
+   * Whether to detect the languages of the text in request by using langId for the native model.
+   */
+  private static final String DETECT_LANGUAGES_FROM_TEXT_ENABLED =
+      "detect_languages_from_text_enabled";
+  /**
+   * A colon(:) separated string that specifies the configuration to use when including surrounding
+   * context text in language detection queries.
+   *
+   * <p>Format= minimumTextSize<int>:penalizeRatio<float>:textScoreRatio<float>
+   *
+   * <p>e.g. 20:1.0:0.4
+   *
+   * <p>Accept all text lengths with minimumTextSize=0
+   *
+   * <p>Reject all text less than minimumTextSize with penalizeRatio=0
+   *
+   * @see {@code TextClassifierImpl#detectLanguages(String, int, int)} for reference.
+   */
+  private static final String LANG_ID_CONTEXT_SETTINGS = "lang_id_context_settings";
+  /** Default threshold to translate the language of the context the user selects */
+  private static final String TRANSLATE_ACTION_THRESHOLD = "translate_action_threshold";
 
-    // Sync this with ConversationAction.TYPE_ADD_CONTACT;
-    public static final String TYPE_ADD_CONTACT = "add_contact";
-    // Sync this with ConversationAction.COPY;
-    public static final String TYPE_COPY = "copy";
+  // Sync this with ConversationAction.TYPE_ADD_CONTACT;
+  public static final String TYPE_ADD_CONTACT = "add_contact";
+  // Sync this with ConversationAction.COPY;
+  public static final String TYPE_COPY = "copy";
 
-    private static final int SUGGEST_SELECTION_MAX_RANGE_LENGTH_DEFAULT = 10 * 1000;
-    private static final int CLASSIFY_TEXT_MAX_RANGE_LENGTH_DEFAULT = 10 * 1000;
-    private static final int GENERATE_LINKS_MAX_TEXT_LENGTH_DEFAULT = 100 * 1000;
-    private static final int GENERATE_LINKS_LOG_SAMPLE_RATE_DEFAULT = 100;
-    private static final int FREQUENT_LANGUAGES_BOOTSTRAPPING_COUNT_DEFAULT = 100;
-    private static final int LANGUAGE_PROFICIENCY_BOOTSTRAPPING_COUNT_DEFAULT = 100;
+  private static final int SUGGEST_SELECTION_MAX_RANGE_LENGTH_DEFAULT = 10 * 1000;
+  private static final int CLASSIFY_TEXT_MAX_RANGE_LENGTH_DEFAULT = 10 * 1000;
+  private static final int GENERATE_LINKS_MAX_TEXT_LENGTH_DEFAULT = 100 * 1000;
+  private static final int GENERATE_LINKS_LOG_SAMPLE_RATE_DEFAULT = 100;
+  private static final int FREQUENT_LANGUAGES_BOOTSTRAPPING_COUNT_DEFAULT = 100;
+  private static final int LANGUAGE_PROFICIENCY_BOOTSTRAPPING_COUNT_DEFAULT = 100;
 
-    private static final List<String> ENTITY_LIST_DEFAULT_VALUE =
-            Arrays.asList(
-                    TextClassifier.TYPE_ADDRESS,
-                    TextClassifier.TYPE_EMAIL,
-                    TextClassifier.TYPE_PHONE,
-                    TextClassifier.TYPE_URL,
-                    TextClassifier.TYPE_DATE,
-                    TextClassifier.TYPE_DATE_TIME,
-                    TextClassifier.TYPE_FLIGHT_NUMBER);
-    private static final List<String> CONVERSATION_ACTIONS_TYPES_DEFAULT_VALUES =
-            Arrays.asList(
-                    ConversationAction.TYPE_TEXT_REPLY,
-                    ConversationAction.TYPE_CREATE_REMINDER,
-                    ConversationAction.TYPE_CALL_PHONE,
-                    ConversationAction.TYPE_OPEN_URL,
-                    ConversationAction.TYPE_SEND_EMAIL,
-                    ConversationAction.TYPE_SEND_SMS,
-                    ConversationAction.TYPE_TRACK_FLIGHT,
-                    ConversationAction.TYPE_VIEW_CALENDAR,
-                    ConversationAction.TYPE_VIEW_MAP,
-                    TYPE_ADD_CONTACT,
-                    TYPE_COPY);
-    /**
-     * < 0 : Not set. Use value from LangId model. 0 - 1: Override value in LangId model.
-     *
-     * @see EntityConfidence
-     */
-    private static final float LANG_ID_THRESHOLD_OVERRIDE_DEFAULT = -1f;
+  private static final ImmutableList<String> ENTITY_LIST_DEFAULT_VALUE =
+      ImmutableList.of(
+          TextClassifier.TYPE_ADDRESS,
+          TextClassifier.TYPE_EMAIL,
+          TextClassifier.TYPE_PHONE,
+          TextClassifier.TYPE_URL,
+          TextClassifier.TYPE_DATE,
+          TextClassifier.TYPE_DATE_TIME,
+          TextClassifier.TYPE_FLIGHT_NUMBER);
+  private static final ImmutableList<String> CONVERSATION_ACTIONS_TYPES_DEFAULT_VALUES =
+      ImmutableList.of(
+          ConversationAction.TYPE_TEXT_REPLY,
+          ConversationAction.TYPE_CREATE_REMINDER,
+          ConversationAction.TYPE_CALL_PHONE,
+          ConversationAction.TYPE_OPEN_URL,
+          ConversationAction.TYPE_SEND_EMAIL,
+          ConversationAction.TYPE_SEND_SMS,
+          ConversationAction.TYPE_TRACK_FLIGHT,
+          ConversationAction.TYPE_VIEW_CALENDAR,
+          ConversationAction.TYPE_VIEW_MAP,
+          TYPE_ADD_CONTACT,
+          TYPE_COPY);
+  /**
+   * < 0 : Not set. Use value from LangId model. 0 - 1: Override value in LangId model.
+   *
+   * @see EntityConfidence
+   */
+  private static final float LANG_ID_THRESHOLD_OVERRIDE_DEFAULT = -1f;
 
-    private static final float TRANSLATE_ACTION_THRESHOLD_DEFAULT = 0.5f;
+  private static final float TRANSLATE_ACTION_THRESHOLD_DEFAULT = 0.5f;
 
-    private static final boolean USER_LANGUAGE_PROFILE_ENABLED_DEFAULT = true;
-    private static final boolean TEMPLATE_INTENT_FACTORY_ENABLED_DEFAULT = true;
-    private static final boolean TRANSLATE_IN_CLASSIFICATION_ENABLED_DEFAULT = true;
-    private static final boolean DETECT_LANGUAGES_FROM_TEXT_ENABLED_DEFAULT = true;
-    private static final float[] LANG_ID_CONTEXT_SETTINGS_DEFAULT = new float[] {20f, 1.0f, 0.4f};
+  private static final boolean USER_LANGUAGE_PROFILE_ENABLED_DEFAULT = true;
+  private static final boolean TEMPLATE_INTENT_FACTORY_ENABLED_DEFAULT = true;
+  private static final boolean TRANSLATE_IN_CLASSIFICATION_ENABLED_DEFAULT = true;
+  private static final boolean DETECT_LANGUAGES_FROM_TEXT_ENABLED_DEFAULT = true;
+  private static final float[] LANG_ID_CONTEXT_SETTINGS_DEFAULT = new float[] {20f, 1.0f, 0.4f};
 
-    public int getSuggestSelectionMaxRangeLength() {
-        return DeviceConfig.getInt(
-                DeviceConfig.NAMESPACE_TEXTCLASSIFIER,
-                SUGGEST_SELECTION_MAX_RANGE_LENGTH,
-                SUGGEST_SELECTION_MAX_RANGE_LENGTH_DEFAULT);
+  public int getSuggestSelectionMaxRangeLength() {
+    return DeviceConfig.getInt(
+        DeviceConfig.NAMESPACE_TEXTCLASSIFIER,
+        SUGGEST_SELECTION_MAX_RANGE_LENGTH,
+        SUGGEST_SELECTION_MAX_RANGE_LENGTH_DEFAULT);
+  }
+
+  public int getClassifyTextMaxRangeLength() {
+    return DeviceConfig.getInt(
+        DeviceConfig.NAMESPACE_TEXTCLASSIFIER,
+        CLASSIFY_TEXT_MAX_RANGE_LENGTH,
+        CLASSIFY_TEXT_MAX_RANGE_LENGTH_DEFAULT);
+  }
+
+  public int getGenerateLinksMaxTextLength() {
+    return DeviceConfig.getInt(
+        DeviceConfig.NAMESPACE_TEXTCLASSIFIER,
+        GENERATE_LINKS_MAX_TEXT_LENGTH,
+        GENERATE_LINKS_MAX_TEXT_LENGTH_DEFAULT);
+  }
+
+  public int getGenerateLinksLogSampleRate() {
+    return DeviceConfig.getInt(
+        DeviceConfig.NAMESPACE_TEXTCLASSIFIER,
+        GENERATE_LINKS_LOG_SAMPLE_RATE,
+        GENERATE_LINKS_LOG_SAMPLE_RATE_DEFAULT);
+  }
+
+  public int getFrequentLanguagesBootstrappingCount() {
+    return DeviceConfig.getInt(
+        DeviceConfig.NAMESPACE_TEXTCLASSIFIER,
+        FREQUENT_LANGUAGES_BOOTSTRAPPING_COUNT,
+        FREQUENT_LANGUAGES_BOOTSTRAPPING_COUNT_DEFAULT);
+  }
+
+  public int getLanguageProficiencyBootstrappingCount() {
+    return DeviceConfig.getInt(
+        DeviceConfig.NAMESPACE_TEXTCLASSIFIER,
+        LANGUAGE_PROFICIENCY_BOOTSTRAPPING_COUNT,
+        LANGUAGE_PROFICIENCY_BOOTSTRAPPING_COUNT_DEFAULT);
+  }
+
+  public List<String> getEntityListDefault() {
+    return getDeviceConfigStringList(ENTITY_LIST_DEFAULT, ENTITY_LIST_DEFAULT_VALUE);
+  }
+
+  public List<String> getEntityListNotEditable() {
+    return getDeviceConfigStringList(ENTITY_LIST_NOT_EDITABLE, ENTITY_LIST_DEFAULT_VALUE);
+  }
+
+  public List<String> getEntityListEditable() {
+    return getDeviceConfigStringList(ENTITY_LIST_EDITABLE, ENTITY_LIST_DEFAULT_VALUE);
+  }
+
+  public List<String> getInAppConversationActionTypes() {
+    return getDeviceConfigStringList(
+        IN_APP_CONVERSATION_ACTION_TYPES_DEFAULT, CONVERSATION_ACTIONS_TYPES_DEFAULT_VALUES);
+  }
+
+  public List<String> getNotificationConversationActionTypes() {
+    return getDeviceConfigStringList(
+        NOTIFICATION_CONVERSATION_ACTION_TYPES_DEFAULT, CONVERSATION_ACTIONS_TYPES_DEFAULT_VALUES);
+  }
+
+  public float getLangIdThresholdOverride() {
+    return DeviceConfig.getFloat(
+        DeviceConfig.NAMESPACE_TEXTCLASSIFIER,
+        LANG_ID_THRESHOLD_OVERRIDE,
+        LANG_ID_THRESHOLD_OVERRIDE_DEFAULT);
+  }
+
+  public float getTranslateActionThreshold() {
+    return DeviceConfig.getFloat(
+        DeviceConfig.NAMESPACE_TEXTCLASSIFIER,
+        TRANSLATE_ACTION_THRESHOLD,
+        TRANSLATE_ACTION_THRESHOLD_DEFAULT);
+  }
+
+  public boolean isUserLanguageProfileEnabled() {
+    return DeviceConfig.getBoolean(
+        DeviceConfig.NAMESPACE_TEXTCLASSIFIER,
+        USER_LANGUAGE_PROFILE_ENABLED,
+        USER_LANGUAGE_PROFILE_ENABLED_DEFAULT);
+  }
+
+  public boolean isTemplateIntentFactoryEnabled() {
+    return DeviceConfig.getBoolean(
+        DeviceConfig.NAMESPACE_TEXTCLASSIFIER,
+        TEMPLATE_INTENT_FACTORY_ENABLED,
+        TEMPLATE_INTENT_FACTORY_ENABLED_DEFAULT);
+  }
+
+  public boolean isTranslateInClassificationEnabled() {
+    return DeviceConfig.getBoolean(
+        DeviceConfig.NAMESPACE_TEXTCLASSIFIER,
+        TRANSLATE_IN_CLASSIFICATION_ENABLED,
+        TRANSLATE_IN_CLASSIFICATION_ENABLED_DEFAULT);
+  }
+
+  public boolean isDetectLanguagesFromTextEnabled() {
+    return DeviceConfig.getBoolean(
+        DeviceConfig.NAMESPACE_TEXTCLASSIFIER,
+        DETECT_LANGUAGES_FROM_TEXT_ENABLED,
+        DETECT_LANGUAGES_FROM_TEXT_ENABLED_DEFAULT);
+  }
+
+  public float[] getLangIdContextSettings() {
+    return getDeviceConfigFloatArray(LANG_ID_CONTEXT_SETTINGS, LANG_ID_CONTEXT_SETTINGS_DEFAULT);
+  }
+
+  void dump(IndentingPrintWriter pw) {
+    pw.println("TextClassificationConstants:");
+    pw.increaseIndent();
+    pw.printPair("classify_text_max_range_length", getClassifyTextMaxRangeLength());
+    pw.printPair("detect_language_from_text_enabled", isDetectLanguagesFromTextEnabled());
+    pw.printPair("entity_list_default", getEntityListDefault());
+    pw.printPair("entity_list_editable", getEntityListEditable());
+    pw.printPair("entity_list_not_editable", getEntityListNotEditable());
+    pw.printPair("generate_links_log_sample_rate", getGenerateLinksLogSampleRate());
+    pw.printPair(
+        "frequent_languages_bootstrapping_count", getFrequentLanguagesBootstrappingCount());
+    pw.printPair("generate_links_max_text_length", getGenerateLinksMaxTextLength());
+    pw.printPair("in_app_conversation_action_types_default", getInAppConversationActionTypes());
+    pw.printPair("lang_id_context_settings", Arrays.toString(getLangIdContextSettings()));
+    pw.printPair("lang_id_threshold_override", getLangIdThresholdOverride());
+    pw.printPair("translate_action_threshold", getTranslateActionThreshold());
+    pw.printPair(
+        "notification_conversation_action_types_default", getNotificationConversationActionTypes());
+    pw.printPair("suggest_selection_max_range_length", getSuggestSelectionMaxRangeLength());
+    pw.printPair("user_language_profile_enabled", isUserLanguageProfileEnabled());
+    pw.printPair("template_intent_factory_enabled", isTemplateIntentFactoryEnabled());
+    pw.printPair("translate_in_classification_enabled", isTranslateInClassificationEnabled());
+    pw.printPair(
+        "language proficiency bootstrapping count", getLanguageProficiencyBootstrappingCount());
+    pw.decreaseIndent();
+  }
+
+  private static List<String> getDeviceConfigStringList(String key, List<String> defaultValue) {
+    return parse(
+        DeviceConfig.getString(DeviceConfig.NAMESPACE_TEXTCLASSIFIER, key, null), defaultValue);
+  }
+
+  private static float[] getDeviceConfigFloatArray(String key, float[] defaultValue) {
+    return parse(
+        DeviceConfig.getString(DeviceConfig.NAMESPACE_TEXTCLASSIFIER, key, null), defaultValue);
+  }
+
+  private static List<String> parse(@Nullable String listStr, List<String> defaultValue) {
+    if (listStr != null) {
+      return Collections.unmodifiableList(Arrays.asList(listStr.split(DELIMITER)));
     }
+    return defaultValue;
+  }
 
-    public int getClassifyTextMaxRangeLength() {
-        return DeviceConfig.getInt(
-                DeviceConfig.NAMESPACE_TEXTCLASSIFIER,
-                CLASSIFY_TEXT_MAX_RANGE_LENGTH,
-                CLASSIFY_TEXT_MAX_RANGE_LENGTH_DEFAULT);
-    }
-
-    public int getGenerateLinksMaxTextLength() {
-        return DeviceConfig.getInt(
-                DeviceConfig.NAMESPACE_TEXTCLASSIFIER,
-                GENERATE_LINKS_MAX_TEXT_LENGTH,
-                GENERATE_LINKS_MAX_TEXT_LENGTH_DEFAULT);
-    }
-
-    public int getGenerateLinksLogSampleRate() {
-        return DeviceConfig.getInt(
-                DeviceConfig.NAMESPACE_TEXTCLASSIFIER,
-                GENERATE_LINKS_LOG_SAMPLE_RATE,
-                GENERATE_LINKS_LOG_SAMPLE_RATE_DEFAULT);
-    }
-
-    public int getFrequentLanguagesBootstrappingCount() {
-        return DeviceConfig.getInt(
-                DeviceConfig.NAMESPACE_TEXTCLASSIFIER,
-                FREQUENT_LANGUAGES_BOOTSTRAPPING_COUNT,
-                FREQUENT_LANGUAGES_BOOTSTRAPPING_COUNT_DEFAULT);
-    }
-
-    public int getLanguageProficiencyBootstrappingCount() {
-        return DeviceConfig.getInt(
-                DeviceConfig.NAMESPACE_TEXTCLASSIFIER,
-                LANGUAGE_PROFICIENCY_BOOTSTRAPPING_COUNT,
-                LANGUAGE_PROFICIENCY_BOOTSTRAPPING_COUNT_DEFAULT);
-    }
-
-    public List<String> getEntityListDefault() {
-        return getDeviceConfigStringList(ENTITY_LIST_DEFAULT, ENTITY_LIST_DEFAULT_VALUE);
-    }
-
-    public List<String> getEntityListNotEditable() {
-        return getDeviceConfigStringList(ENTITY_LIST_NOT_EDITABLE, ENTITY_LIST_DEFAULT_VALUE);
-    }
-
-    public List<String> getEntityListEditable() {
-        return getDeviceConfigStringList(ENTITY_LIST_EDITABLE, ENTITY_LIST_DEFAULT_VALUE);
-    }
-
-    public List<String> getInAppConversationActionTypes() {
-        return getDeviceConfigStringList(
-                IN_APP_CONVERSATION_ACTION_TYPES_DEFAULT,
-                CONVERSATION_ACTIONS_TYPES_DEFAULT_VALUES);
-    }
-
-    public List<String> getNotificationConversationActionTypes() {
-        return getDeviceConfigStringList(
-                NOTIFICATION_CONVERSATION_ACTION_TYPES_DEFAULT,
-                CONVERSATION_ACTIONS_TYPES_DEFAULT_VALUES);
-    }
-
-    public float getLangIdThresholdOverride() {
-        return DeviceConfig.getFloat(
-                DeviceConfig.NAMESPACE_TEXTCLASSIFIER,
-                LANG_ID_THRESHOLD_OVERRIDE,
-                LANG_ID_THRESHOLD_OVERRIDE_DEFAULT);
-    }
-
-    public float getTranslateActionThreshold() {
-        return DeviceConfig.getFloat(
-                DeviceConfig.NAMESPACE_TEXTCLASSIFIER,
-                TRANSLATE_ACTION_THRESHOLD,
-                TRANSLATE_ACTION_THRESHOLD_DEFAULT);
-    }
-
-    public boolean isUserLanguageProfileEnabled() {
-        return DeviceConfig.getBoolean(
-                DeviceConfig.NAMESPACE_TEXTCLASSIFIER,
-                USER_LANGUAGE_PROFILE_ENABLED,
-                USER_LANGUAGE_PROFILE_ENABLED_DEFAULT);
-    }
-
-    public boolean isTemplateIntentFactoryEnabled() {
-        return DeviceConfig.getBoolean(
-                DeviceConfig.NAMESPACE_TEXTCLASSIFIER,
-                TEMPLATE_INTENT_FACTORY_ENABLED,
-                TEMPLATE_INTENT_FACTORY_ENABLED_DEFAULT);
-    }
-
-    public boolean isTranslateInClassificationEnabled() {
-        return DeviceConfig.getBoolean(
-                DeviceConfig.NAMESPACE_TEXTCLASSIFIER,
-                TRANSLATE_IN_CLASSIFICATION_ENABLED,
-                TRANSLATE_IN_CLASSIFICATION_ENABLED_DEFAULT);
-    }
-
-    public boolean isDetectLanguagesFromTextEnabled() {
-        return DeviceConfig.getBoolean(
-                DeviceConfig.NAMESPACE_TEXTCLASSIFIER,
-                DETECT_LANGUAGES_FROM_TEXT_ENABLED,
-                DETECT_LANGUAGES_FROM_TEXT_ENABLED_DEFAULT);
-    }
-
-    public float[] getLangIdContextSettings() {
-        return getDeviceConfigFloatArray(
-                LANG_ID_CONTEXT_SETTINGS, LANG_ID_CONTEXT_SETTINGS_DEFAULT);
-    }
-
-    void dump(IndentingPrintWriter pw) {
-        pw.println("TextClassificationConstants:");
-        pw.increaseIndent();
-        pw.printPair("classify_text_max_range_length", getClassifyTextMaxRangeLength());
-        pw.printPair("detect_language_from_text_enabled", isDetectLanguagesFromTextEnabled());
-        pw.printPair("entity_list_default", getEntityListDefault());
-        pw.printPair("entity_list_editable", getEntityListEditable());
-        pw.printPair("entity_list_not_editable", getEntityListNotEditable());
-        pw.printPair("generate_links_log_sample_rate", getGenerateLinksLogSampleRate());
-        pw.printPair(
-                "frequent_languages_bootstrapping_count", getFrequentLanguagesBootstrappingCount());
-        pw.printPair("generate_links_max_text_length", getGenerateLinksMaxTextLength());
-        pw.printPair("in_app_conversation_action_types_default", getInAppConversationActionTypes());
-        pw.printPair("lang_id_context_settings", Arrays.toString(getLangIdContextSettings()));
-        pw.printPair("lang_id_threshold_override", getLangIdThresholdOverride());
-        pw.printPair("translate_action_threshold", getTranslateActionThreshold());
-        pw.printPair(
-                "notification_conversation_action_types_default",
-                getNotificationConversationActionTypes());
-        pw.printPair("suggest_selection_max_range_length", getSuggestSelectionMaxRangeLength());
-        pw.printPair("user_language_profile_enabled", isUserLanguageProfileEnabled());
-        pw.printPair("template_intent_factory_enabled", isTemplateIntentFactoryEnabled());
-        pw.printPair("translate_in_classification_enabled", isTranslateInClassificationEnabled());
-        pw.printPair(
-                "language proficiency bootstrapping count",
-                getLanguageProficiencyBootstrappingCount());
-        pw.decreaseIndent();
-    }
-
-    private static List<String> getDeviceConfigStringList(String key, List<String> defaultValue) {
-        return parse(
-                DeviceConfig.getString(DeviceConfig.NAMESPACE_TEXTCLASSIFIER, key, null),
-                defaultValue);
-    }
-
-    private static float[] getDeviceConfigFloatArray(String key, float[] defaultValue) {
-        return parse(
-                DeviceConfig.getString(DeviceConfig.NAMESPACE_TEXTCLASSIFIER, key, null),
-                defaultValue);
-    }
-
-    private static List<String> parse(@Nullable String listStr, List<String> defaultValue) {
-        if (listStr != null) {
-            return Collections.unmodifiableList(Arrays.asList(listStr.split(DELIMITER)));
-        }
+  private static float[] parse(@Nullable String arrayStr, float[] defaultValue) {
+    if (arrayStr != null) {
+      final List<String> split = Splitter.onPattern(DELIMITER).splitToList(arrayStr);
+      if (split.size() != defaultValue.length) {
         return defaultValue;
-    }
-
-    private static float[] parse(@Nullable String arrayStr, float[] defaultValue) {
-        if (arrayStr != null) {
-            final String[] split = arrayStr.split(DELIMITER);
-            if (split.length != defaultValue.length) {
-                return defaultValue;
-            }
-            final float[] result = new float[split.length];
-            for (int i = 0; i < split.length; i++) {
-                try {
-                    result[i] = Float.parseFloat(split[i]);
-                } catch (NumberFormatException e) {
-                    return defaultValue;
-                }
-            }
-            return result;
-        } else {
-            return defaultValue;
+      }
+      final float[] result = new float[split.size()];
+      for (int i = 0; i < split.size(); i++) {
+        try {
+          result[i] = Float.parseFloat(split.get(i));
+        } catch (NumberFormatException e) {
+          return defaultValue;
         }
+      }
+      return result;
+    } else {
+      return defaultValue;
     }
+  }
 }
diff --git a/java/src/com/android/textclassifier/TextClassifierImpl.java b/java/src/com/android/textclassifier/TextClassifierImpl.java
index f385684..9babf30 100644
--- a/java/src/com/android/textclassifier/TextClassifierImpl.java
+++ b/java/src/com/android/textclassifier/TextClassifierImpl.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 The Android Open Source Project
+ * Copyright (C) 2018 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -37,15 +37,10 @@
 import android.view.textclassifier.TextLanguage;
 import android.view.textclassifier.TextLinks;
 import android.view.textclassifier.TextSelection;
-
 import androidx.annotation.GuardedBy;
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
 import androidx.annotation.WorkerThread;
 import androidx.collection.ArraySet;
 import androidx.core.util.Pair;
-import androidx.core.util.Preconditions;
-
 import com.android.textclassifier.ActionsModelParamsSupplier.ActionsModelParams;
 import com.android.textclassifier.intent.ClassificationIntentFactory;
 import com.android.textclassifier.intent.LabeledIntent;
@@ -59,17 +54,16 @@
 import com.android.textclassifier.ulp.LanguageProfileAnalyzer;
 import com.android.textclassifier.ulp.LanguageProfileUpdater;
 import com.android.textclassifier.utils.IndentingPrintWriter;
-
 import com.google.android.textclassifier.ActionsSuggestionsModel;
 import com.google.android.textclassifier.AnnotatorModel;
 import com.google.android.textclassifier.LangIdModel;
-import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.base.Preconditions;
 import com.google.common.util.concurrent.MoreExecutors;
-
 import java.io.File;
 import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.time.Instant;
+import java.time.ZoneId;
 import java.time.ZonedDateTime;
 import java.util.ArrayList;
 import java.util.Collection;
@@ -80,6 +74,7 @@
 import java.util.Set;
 import java.util.concurrent.Executors;
 import java.util.function.Supplier;
+import javax.annotation.Nullable;
 
 /**
  * Default implementation of the {@link TextClassifier} interface.
@@ -90,901 +85,872 @@
  */
 final class TextClassifierImpl {
 
-    private static final String TAG = "TextClassifierImpl";
+  private static final String TAG = "TextClassifierImpl";
 
-    private static final boolean DEBUG = false;
+  private static final File FACTORY_MODEL_DIR = new File("/etc/textclassifier/");
+  // Annotator
+  private static final String ANNOTATOR_FACTORY_MODEL_FILENAME_REGEX =
+      "textclassifier\\.(.*)\\.model";
+  private static final File ANNOTATOR_UPDATED_MODEL_FILE =
+      new File("/data/misc/textclassifier/textclassifier.model");
 
-    private static final File FACTORY_MODEL_DIR = new File("/etc/textclassifier/");
-    // Annotator
-    private static final String ANNOTATOR_FACTORY_MODEL_FILENAME_REGEX =
-            "textclassifier\\.(.*)\\.model";
-    private static final File ANNOTATOR_UPDATED_MODEL_FILE =
-            new File("/data/misc/textclassifier/textclassifier.model");
+  // LangID
+  private static final String LANG_ID_FACTORY_MODEL_FILENAME_REGEX = "lang_id.model";
+  private static final File UPDATED_LANG_ID_MODEL_FILE =
+      new File("/data/misc/textclassifier/lang_id.model");
 
-    // LangID
-    private static final String LANG_ID_FACTORY_MODEL_FILENAME_REGEX = "lang_id.model";
-    private static final File UPDATED_LANG_ID_MODEL_FILE =
-            new File("/data/misc/textclassifier/lang_id.model");
+  // Actions
+  private static final String ACTIONS_FACTORY_MODEL_FILENAME_REGEX =
+      "actions_suggestions\\.(.*)\\.model";
+  private static final File UPDATED_ACTIONS_MODEL =
+      new File("/data/misc/textclassifier/actions_suggestions.model");
 
-    // Actions
-    private static final String ACTIONS_FACTORY_MODEL_FILENAME_REGEX =
-            "actions_suggestions\\.(.*)\\.model";
-    private static final File UPDATED_ACTIONS_MODEL =
-            new File("/data/misc/textclassifier/actions_suggestions.model");
+  private final Context context;
+  private final TextClassifier fallback;
+  private final GenerateLinksLogger generateLinksLogger;
 
-    private final Context mContext;
-    private final TextClassifier mFallback;
-    private final GenerateLinksLogger mGenerateLinksLogger;
+  private final Object lock = new Object();
 
-    private final Object mLock = new Object();
+  @GuardedBy("lock")
+  private ModelFileManager.ModelFile annotatorModelInUse;
 
-    @GuardedBy("mLock")
-    private ModelFileManager.ModelFile mAnnotatorModelInUse;
+  @GuardedBy("lock")
+  private AnnotatorModel annotatorImpl;
 
-    @GuardedBy("mLock")
-    private AnnotatorModel mAnnotatorImpl;
+  @GuardedBy("lock")
+  private ModelFileManager.ModelFile langIdModelInUse;
 
-    @GuardedBy("mLock")
-    private ModelFileManager.ModelFile mLangIdModelInUse;
+  @GuardedBy("lock")
+  private LangIdModel langIdImpl;
 
-    @GuardedBy("mLock")
-    private LangIdModel mLangIdImpl;
+  @GuardedBy("lock")
+  private ModelFileManager.ModelFile actionModelInUse;
 
-    @GuardedBy("mLock")
-    private ModelFileManager.ModelFile mActionModelInUse;
+  @GuardedBy("lock")
+  private ActionsSuggestionsModel actionsImpl;
 
-    @GuardedBy("mLock")
-    private ActionsSuggestionsModel mActionsImpl;
+  private final TextClassifierEventLogger textClassifierEventLogger =
+      new TextClassifierEventLogger();
 
-    private final TextClassifierEventLogger mTextClassifierEventLogger =
-            new TextClassifierEventLogger();
+  private final TextClassificationConstants settings;
 
-    private final TextClassificationConstants mSettings;
+  private final ModelFileManager annotatorModelFileManager;
+  private final ModelFileManager langIdModelFileManager;
+  private final ModelFileManager actionsModelFileManager;
+  private final LanguageProfileUpdater languageProfileUpdater;
+  private final LanguageProfileAnalyzer languageProfileAnalyzer;
+  private final ClassificationIntentFactory classificationIntentFactory;
+  private final TemplateIntentFactory templateIntentFactory;
+  private final Supplier<ActionsModelParams> actionsModelParamsSupplier;
 
-    private final ModelFileManager mAnnotatorModelFileManager;
-    private final ModelFileManager mLangIdModelFileManager;
-    private final ModelFileManager mActionsModelFileManager;
-    private final LanguageProfileUpdater mLanguageProfileUpdater;
-    private final LanguageProfileAnalyzer mLanguageProfileAnalyzer;
-    private final ClassificationIntentFactory mClassificationIntentFactory;
-    private final TemplateIntentFactory mTemplateIntentFactory;
-    private final Supplier<ActionsModelParams> mActionsModelParamsSupplier;
+  TextClassifierImpl(
+      Context context, TextClassificationConstants settings, TextClassifier fallback) {
+    this.context = Preconditions.checkNotNull(context);
+    this.fallback = Preconditions.checkNotNull(fallback);
+    this.settings = Preconditions.checkNotNull(settings);
+    generateLinksLogger = new GenerateLinksLogger(this.settings.getGenerateLinksLogSampleRate());
+    annotatorModelFileManager =
+        new ModelFileManager(
+            new ModelFileManager.ModelFileSupplierImpl(
+                FACTORY_MODEL_DIR,
+                ANNOTATOR_FACTORY_MODEL_FILENAME_REGEX,
+                ANNOTATOR_UPDATED_MODEL_FILE,
+                AnnotatorModel::getVersion,
+                AnnotatorModel::getLocales));
+    langIdModelFileManager =
+        new ModelFileManager(
+            new ModelFileManager.ModelFileSupplierImpl(
+                FACTORY_MODEL_DIR,
+                LANG_ID_FACTORY_MODEL_FILENAME_REGEX,
+                UPDATED_LANG_ID_MODEL_FILE,
+                LangIdModel::getVersion,
+                fd -> ModelFileManager.ModelFile.LANGUAGE_INDEPENDENT));
+    actionsModelFileManager =
+        new ModelFileManager(
+            new ModelFileManager.ModelFileSupplierImpl(
+                FACTORY_MODEL_DIR,
+                ACTIONS_FACTORY_MODEL_FILENAME_REGEX,
+                UPDATED_ACTIONS_MODEL,
+                ActionsSuggestionsModel::getVersion,
+                ActionsSuggestionsModel::getLocales));
+    languageProfileUpdater =
+        new LanguageProfileUpdater(
+            this.context, MoreExecutors.listeningDecorator(Executors.newSingleThreadExecutor()));
+    languageProfileAnalyzer = LanguageProfileAnalyzer.create(context, this.settings);
 
-    TextClassifierImpl(
-            Context context, TextClassificationConstants settings, TextClassifier fallback) {
-        mContext = Preconditions.checkNotNull(context);
-        mFallback = Preconditions.checkNotNull(fallback);
-        mSettings = Preconditions.checkNotNull(settings);
-        mGenerateLinksLogger = new GenerateLinksLogger(mSettings.getGenerateLinksLogSampleRate());
-        mAnnotatorModelFileManager =
-                new ModelFileManager(
-                        new ModelFileManager.ModelFileSupplierImpl(
-                                FACTORY_MODEL_DIR,
-                                ANNOTATOR_FACTORY_MODEL_FILENAME_REGEX,
-                                ANNOTATOR_UPDATED_MODEL_FILE,
-                                AnnotatorModel::getVersion,
-                                AnnotatorModel::getLocales));
-        mLangIdModelFileManager =
-                new ModelFileManager(
-                        new ModelFileManager.ModelFileSupplierImpl(
-                                FACTORY_MODEL_DIR,
-                                LANG_ID_FACTORY_MODEL_FILENAME_REGEX,
-                                UPDATED_LANG_ID_MODEL_FILE,
-                                LangIdModel::getVersion,
-                                fd -> ModelFileManager.ModelFile.LANGUAGE_INDEPENDENT));
-        mActionsModelFileManager =
-                new ModelFileManager(
-                        new ModelFileManager.ModelFileSupplierImpl(
-                                FACTORY_MODEL_DIR,
-                                ACTIONS_FACTORY_MODEL_FILENAME_REGEX,
-                                UPDATED_ACTIONS_MODEL,
-                                ActionsSuggestionsModel::getVersion,
-                                ActionsSuggestionsModel::getLocales));
-        mLanguageProfileUpdater =
-                new LanguageProfileUpdater(
-                        mContext,
-                        MoreExecutors.listeningDecorator(Executors.newSingleThreadExecutor()));
-        mLanguageProfileAnalyzer = LanguageProfileAnalyzer.create(context, mSettings);
+    templateIntentFactory = new TemplateIntentFactory();
+    classificationIntentFactory =
+        this.settings.isTemplateIntentFactoryEnabled()
+            ? new TemplateClassificationIntentFactory(
+                templateIntentFactory, new LegacyClassificationIntentFactory())
+            : new LegacyClassificationIntentFactory();
+    actionsModelParamsSupplier =
+        new ActionsModelParamsSupplier(
+            this.context,
+            () -> {
+              synchronized (lock) {
+                // Clear actionsImpl here, so that we will create a new
+                // ActionsSuggestionsModel object with the new flag in the next
+                // request.
+                actionsImpl = null;
+                actionModelInUse = null;
+              }
+            });
+  }
 
-        mTemplateIntentFactory = new TemplateIntentFactory();
-        mClassificationIntentFactory =
-                mSettings.isTemplateIntentFactoryEnabled()
-                        ? new TemplateClassificationIntentFactory(
-                                mTemplateIntentFactory, new LegacyClassificationIntentFactory())
-                        : new LegacyClassificationIntentFactory();
-        mActionsModelParamsSupplier =
-                new ActionsModelParamsSupplier(
-                        mContext,
-                        () -> {
-                            synchronized (mLock) {
-                                // Clear mActionsImpl here, so that we will create a new
-                                // ActionsSuggestionsModel object with the new flag in the next
-                                // request.
-                                mActionsImpl = null;
-                                mActionModelInUse = null;
-                            }
-                        });
-    }
+  TextClassifierImpl(Context context, TextClassificationConstants settings) {
+    this(context, settings, TextClassifier.NO_OP);
+  }
 
-    TextClassifierImpl(Context context, TextClassificationConstants settings) {
-        this(context, settings, TextClassifier.NO_OP);
-    }
-
-    @WorkerThread
-    TextSelection suggestSelection(TextSelection.Request request) {
-        Preconditions.checkNotNull(request);
-        checkMainThread();
-        try {
-            final int rangeLength = request.getEndIndex() - request.getStartIndex();
-            final String string = request.getText().toString();
-            if (string.length() > 0
-                    && rangeLength <= mSettings.getSuggestSelectionMaxRangeLength()) {
-                final String localesString = concatenateLocales(request.getDefaultLocales());
-                final String detectLanguageTags =
-                        String.join(
-                                ",",
-                                detectLanguages(request.getText(), getLangIdThreshold())
-                                        .getEntities());
-                final ZonedDateTime refTime = ZonedDateTime.now();
-                final AnnotatorModel annotatorImpl = getAnnotatorImpl(request.getDefaultLocales());
-                final int[] startEnd =
-                        annotatorImpl.suggestSelection(
-                                string,
-                                request.getStartIndex(),
-                                request.getEndIndex(),
-                                new AnnotatorModel.SelectionOptions(
-                                        localesString, detectLanguageTags));
-                final int start = startEnd[0];
-                final int end = startEnd[1];
-                if (start < end
-                        && start >= 0
-                        && end <= string.length()
-                        && start <= request.getStartIndex()
-                        && end >= request.getEndIndex()) {
-                    final TextSelection.Builder tsBuilder = new TextSelection.Builder(start, end);
-                    final AnnotatorModel.ClassificationResult[] results =
-                            annotatorImpl.classifyText(
-                                    string,
-                                    start,
-                                    end,
-                                    new AnnotatorModel.ClassificationOptions(
-                                            refTime.toInstant().toEpochMilli(),
-                                            refTime.getZone().getId(),
-                                            localesString,
-                                            detectLanguageTags),
-                                    // Passing null here to suppress intent generation
-                                    // TODO: Use an explicit flag to suppress it.
-                                    /* appContext */ null,
-                                    /* deviceLocales */ null);
-                    final int size = results.length;
-                    for (int i = 0; i < size; i++) {
-                        tsBuilder.setEntityType(results[i].getCollection(), results[i].getScore());
-                    }
-                    return tsBuilder
-                            .setId(createId(string, request.getStartIndex(), request.getEndIndex()))
-                            .build();
-                } else {
-                    // We can not trust the result. Log the issue and ignore the result.
-                    TcLog.d(TAG, "Got bad indices for input text. Ignoring result.");
-                }
-            }
-        } catch (Throwable t) {
-            // Avoid throwing from this method. Log the error.
-            TcLog.e(
-                    TAG,
-                    "Error suggesting selection for text. No changes to selection suggested.",
-                    t);
+  @WorkerThread
+  TextSelection suggestSelection(TextSelection.Request request) {
+    Preconditions.checkNotNull(request);
+    checkMainThread();
+    try {
+      final int rangeLength = request.getEndIndex() - request.getStartIndex();
+      final String string = request.getText().toString();
+      if (string.length() > 0 && rangeLength <= settings.getSuggestSelectionMaxRangeLength()) {
+        final String localesString = concatenateLocales(request.getDefaultLocales());
+        final String detectLanguageTags =
+            String.join(
+                ",", detectLanguages(request.getText(), getLangIdThreshold()).getEntities());
+        final ZonedDateTime refTime = ZonedDateTime.now(ZoneId.systemDefault());
+        final AnnotatorModel annotatorImpl = getAnnotatorImpl(request.getDefaultLocales());
+        final int[] startEnd =
+            annotatorImpl.suggestSelection(
+                string,
+                request.getStartIndex(),
+                request.getEndIndex(),
+                new AnnotatorModel.SelectionOptions(localesString, detectLanguageTags));
+        final int start = startEnd[0];
+        final int end = startEnd[1];
+        if (start < end
+            && start >= 0
+            && end <= string.length()
+            && start <= request.getStartIndex()
+            && end >= request.getEndIndex()) {
+          final TextSelection.Builder tsBuilder = new TextSelection.Builder(start, end);
+          final AnnotatorModel.ClassificationResult[] results =
+              annotatorImpl.classifyText(
+                  string,
+                  start,
+                  end,
+                  new AnnotatorModel.ClassificationOptions(
+                      refTime.toInstant().toEpochMilli(),
+                      refTime.getZone().getId(),
+                      localesString,
+                      detectLanguageTags),
+                  // Passing null here to suppress intent generation
+                  // TODO: Use an explicit flag to suppress it.
+                  /* appContext */ null,
+                  /* deviceLocales */ null);
+          final int size = results.length;
+          for (int i = 0; i < size; i++) {
+            tsBuilder.setEntityType(results[i].getCollection(), results[i].getScore());
+          }
+          return tsBuilder
+              .setId(createId(string, request.getStartIndex(), request.getEndIndex()))
+              .build();
+        } else {
+          // We can not trust the result. Log the issue and ignore the result.
+          TcLog.d(TAG, "Got bad indices for input text. Ignoring result.");
         }
-        // Getting here means something went wrong, return a NO_OP result.
-        return mFallback.suggestSelection(request);
+      }
+    } catch (Throwable t) {
+      // Avoid throwing from this method. Log the error.
+      TcLog.e(TAG, "Error suggesting selection for text. No changes to selection suggested.", t);
     }
+    // Getting here means something went wrong, return a NO_OP result.
+    return fallback.suggestSelection(request);
+  }
 
-    @WorkerThread
-    TextClassification classifyText(TextClassification.Request request) {
-        Preconditions.checkNotNull(request);
-        checkMainThread();
-        try {
-            List<String> detectLanguageTags =
-                    detectLanguages(request.getText(), getLangIdThreshold()).getEntities();
-            if (mSettings.isUserLanguageProfileEnabled()) {
-                ListenableFuture<Void> ignoredResult =
-                        mLanguageProfileUpdater.updateFromClassifyTextAsync(detectLanguageTags);
-            }
-            final int rangeLength = request.getEndIndex() - request.getStartIndex();
-            final String string = request.getText().toString();
-            if (string.length() > 0 && rangeLength <= mSettings.getClassifyTextMaxRangeLength()) {
-                final String localesString = concatenateLocales(request.getDefaultLocales());
-                final ZonedDateTime refTime =
-                        request.getReferenceTime() != null
-                                ? request.getReferenceTime()
-                                : ZonedDateTime.now();
-                final AnnotatorModel.ClassificationResult[] results =
-                        getAnnotatorImpl(request.getDefaultLocales())
-                                .classifyText(
-                                        string,
-                                        request.getStartIndex(),
-                                        request.getEndIndex(),
-                                        new AnnotatorModel.ClassificationOptions(
-                                                refTime.toInstant().toEpochMilli(),
-                                                refTime.getZone().getId(),
-                                                localesString,
-                                                String.join(",", detectLanguageTags)),
-                                        mContext,
-                                        getResourceLocalesString());
-                if (results.length > 0) {
-                    return createClassificationResult(
-                            results,
-                            string,
-                            request.getStartIndex(),
-                            request.getEndIndex(),
-                            refTime.toInstant());
-                }
-            }
-        } catch (Throwable t) {
-            // Avoid throwing from this method. Log the error.
-            TcLog.e(TAG, "Error getting text classification info.", t);
+  @WorkerThread
+  TextClassification classifyText(TextClassification.Request request) {
+    Preconditions.checkNotNull(request);
+    checkMainThread();
+    try {
+      List<String> detectLanguageTags =
+          detectLanguages(request.getText(), getLangIdThreshold()).getEntities();
+      if (settings.isUserLanguageProfileEnabled()) {
+        languageProfileUpdater.updateFromClassifyTextAsync(detectLanguageTags);
+      }
+      final int rangeLength = request.getEndIndex() - request.getStartIndex();
+      final String string = request.getText().toString();
+      if (string.length() > 0 && rangeLength <= settings.getClassifyTextMaxRangeLength()) {
+        final String localesString = concatenateLocales(request.getDefaultLocales());
+        final ZonedDateTime refTime =
+            request.getReferenceTime() != null
+                ? request.getReferenceTime()
+                : ZonedDateTime.now(ZoneId.systemDefault());
+        final AnnotatorModel.ClassificationResult[] results =
+            getAnnotatorImpl(request.getDefaultLocales())
+                .classifyText(
+                    string,
+                    request.getStartIndex(),
+                    request.getEndIndex(),
+                    new AnnotatorModel.ClassificationOptions(
+                        refTime.toInstant().toEpochMilli(),
+                        refTime.getZone().getId(),
+                        localesString,
+                        String.join(",", detectLanguageTags)),
+                    context,
+                    getResourceLocalesString());
+        if (results.length > 0) {
+          return createClassificationResult(
+              results, string, request.getStartIndex(), request.getEndIndex(), refTime.toInstant());
         }
-        // Getting here means something went wrong, return a NO_OP result.
-        return mFallback.classifyText(request);
+      }
+    } catch (Throwable t) {
+      // Avoid throwing from this method. Log the error.
+      TcLog.e(TAG, "Error getting text classification info.", t);
     }
+    // Getting here means something went wrong, return a NO_OP result.
+    return fallback.classifyText(request);
+  }
 
-    @WorkerThread
-    TextLinks generateLinks(@NonNull TextLinks.Request request) {
-        Preconditions.checkNotNull(request);
-        Preconditions.checkArgumentInRange(
-                request.getText().length(), 0, getMaxGenerateLinksTextLength(), "text.length()");
-        checkMainThread();
+  @WorkerThread
+  TextLinks generateLinks(TextLinks.Request request) {
+    Preconditions.checkNotNull(request);
+    Preconditions.checkArgument(
+        request.getText().length() <= getMaxGenerateLinksTextLength(),
+        "text.length() cannot be greater than %s",
+        getMaxGenerateLinksTextLength());
+    checkMainThread();
 
-        final String textString = request.getText().toString();
-        final TextLinks.Builder builder = new TextLinks.Builder(textString);
+    final String textString = request.getText().toString();
+    final TextLinks.Builder builder = new TextLinks.Builder(textString);
 
-        try {
-            final long startTimeMs = System.currentTimeMillis();
-            final ZonedDateTime refTime = ZonedDateTime.now();
-            final Collection<String> entitiesToIdentify =
-                    request.getEntityConfig() != null
-                            ? request.getEntityConfig()
-                                    .resolveEntityListModifications(
-                                            getEntitiesForHints(
-                                                    request.getEntityConfig().getHints()))
-                            : mSettings.getEntityListDefault();
-            final String localesString = concatenateLocales(request.getDefaultLocales());
-            final String detectLanguageTags =
-                    String.join(
-                            ",",
-                            detectLanguages(request.getText(), getLangIdThreshold()).getEntities());
-            final AnnotatorModel annotatorImpl = getAnnotatorImpl(request.getDefaultLocales());
-            final boolean isSerializedEntityDataEnabled =
-                    ExtrasUtils.isSerializedEntityDataEnabled(request);
-            final AnnotatorModel.AnnotatedSpan[] annotations =
-                    annotatorImpl.annotate(
-                            textString,
-                            new AnnotatorModel.AnnotationOptions(
-                                    refTime.toInstant().toEpochMilli(),
-                                    refTime.getZone().getId(),
-                                    localesString,
-                                    detectLanguageTags,
-                                    entitiesToIdentify,
-                                    AnnotatorModel.AnnotationUsecase.SMART.getValue(),
-                                    isSerializedEntityDataEnabled));
-            for (AnnotatorModel.AnnotatedSpan span : annotations) {
-                final AnnotatorModel.ClassificationResult[] results = span.getClassification();
-                if (results.length == 0
-                        || !entitiesToIdentify.contains(results[0].getCollection())) {
-                    continue;
-                }
-                final Map<String, Float> entityScores = new ArrayMap<>();
-                for (int i = 0; i < results.length; i++) {
-                    entityScores.put(results[i].getCollection(), results[i].getScore());
-                }
-                Bundle extras = new Bundle();
-                if (isSerializedEntityDataEnabled) {
-                    ExtrasUtils.putEntities(extras, results);
-                }
-                builder.addLink(span.getStartIndex(), span.getEndIndex(), entityScores, extras);
-            }
-            final TextLinks links = builder.build();
-            final long endTimeMs = System.currentTimeMillis();
-            final String callingPackageName =
-                    request.getCallingPackageName() == null
-                            ? mContext.getPackageName() // local (in process) TC.
-                            : request.getCallingPackageName();
-            mGenerateLinksLogger.logGenerateLinks(
-                    request.getText(), links, callingPackageName, endTimeMs - startTimeMs);
-            return links;
-        } catch (Throwable t) {
-            // Avoid throwing from this method. Log the error.
-            TcLog.e(TAG, "Error getting links info.", t);
+    try {
+      final long startTimeMs = System.currentTimeMillis();
+      final ZonedDateTime refTime = ZonedDateTime.now(ZoneId.systemDefault());
+      final Collection<String> entitiesToIdentify =
+          request.getEntityConfig() != null
+              ? request
+                  .getEntityConfig()
+                  .resolveEntityListModifications(
+                      getEntitiesForHints(request.getEntityConfig().getHints()))
+              : settings.getEntityListDefault();
+      final String localesString = concatenateLocales(request.getDefaultLocales());
+      final String detectLanguageTags =
+          String.join(",", detectLanguages(request.getText(), getLangIdThreshold()).getEntities());
+      final AnnotatorModel annotatorImpl = getAnnotatorImpl(request.getDefaultLocales());
+      final boolean isSerializedEntityDataEnabled =
+          ExtrasUtils.isSerializedEntityDataEnabled(request);
+      final AnnotatorModel.AnnotatedSpan[] annotations =
+          annotatorImpl.annotate(
+              textString,
+              new AnnotatorModel.AnnotationOptions(
+                  refTime.toInstant().toEpochMilli(),
+                  refTime.getZone().getId(),
+                  localesString,
+                  detectLanguageTags,
+                  entitiesToIdentify,
+                  AnnotatorModel.AnnotationUsecase.SMART.getValue(),
+                  isSerializedEntityDataEnabled));
+      for (AnnotatorModel.AnnotatedSpan span : annotations) {
+        final AnnotatorModel.ClassificationResult[] results = span.getClassification();
+        if (results.length == 0 || !entitiesToIdentify.contains(results[0].getCollection())) {
+          continue;
         }
-        return mFallback.generateLinks(request);
-    }
-
-    int getMaxGenerateLinksTextLength() {
-        return mSettings.getGenerateLinksMaxTextLength();
-    }
-
-    private Collection<String> getEntitiesForHints(Collection<String> hints) {
-        final boolean editable = hints.contains(TextClassifier.HINT_TEXT_IS_EDITABLE);
-        final boolean notEditable = hints.contains(TextClassifier.HINT_TEXT_IS_NOT_EDITABLE);
-
-        // Use the default if there is no hint, or conflicting ones.
-        final boolean useDefault = editable == notEditable;
-        if (useDefault) {
-            return mSettings.getEntityListDefault();
-        } else if (editable) {
-            return mSettings.getEntityListEditable();
-        } else { // notEditable
-            return mSettings.getEntityListNotEditable();
-        }
-    }
-
-    void onSelectionEvent(SelectionEvent event) {
-        TextClassifierEvent textClassifierEvent =
-                SelectionEventConverter.toTextClassifierEvent(event);
-        if (textClassifierEvent == null) {
-            return;
-        }
-        onTextClassifierEvent(event.getSessionId(), textClassifierEvent);
-    }
-
-    void onTextClassifierEvent(
-            @Nullable TextClassificationSessionId sessionId, TextClassifierEvent event) {
-        mTextClassifierEventLogger.writeEvent(sessionId, event);
-        if (mSettings.isUserLanguageProfileEnabled()) {
-            mLanguageProfileAnalyzer.onTextClassifierEven(event);
-        }
-    }
-
-    TextLanguage detectLanguage(@NonNull TextLanguage.Request request) {
-        Preconditions.checkNotNull(request);
-        checkMainThread();
-        try {
-            final TextLanguage.Builder builder = new TextLanguage.Builder();
-            final LangIdModel.LanguageResult[] langResults =
-                    getLangIdImpl().detectLanguages(request.getText().toString());
-            for (int i = 0; i < langResults.length; i++) {
-                builder.putLocale(
-                        ULocale.forLanguageTag(langResults[i].getLanguage()),
-                        langResults[i].getScore());
-            }
-            return builder.build();
-        } catch (Throwable t) {
-            // Avoid throwing from this method. Log the error.
-            TcLog.e(TAG, "Error detecting text language.", t);
-        }
-        return mFallback.detectLanguage(request);
-    }
-
-    ConversationActions suggestConversationActions(ConversationActions.Request request) {
-        Preconditions.checkNotNull(request);
-        checkMainThread();
-        if (mSettings.isUserLanguageProfileEnabled()) {
-            // FIXME: Reuse the LangID result.
-            ListenableFuture<Void> ignoredResult =
-                    mLanguageProfileUpdater.updateFromConversationActionsAsync(
-                            request,
-                            text -> detectLanguages(text, getLangIdThreshold()).getEntities());
-        }
-        try {
-            ActionsSuggestionsModel actionsImpl = getActionsImpl();
-            if (actionsImpl == null) {
-                // Actions model is optional, fallback if it is not available.
-                return mFallback.suggestConversationActions(request);
-            }
-            ActionsSuggestionsModel.ConversationMessage[] nativeMessages =
-                    ActionsSuggestionsHelper.toNativeMessages(
-                            request.getConversation(),
-                            text -> detectLanguages(text, getLangIdThreshold()).getEntities());
-            if (nativeMessages.length == 0) {
-                return mFallback.suggestConversationActions(request);
-            }
-            ActionsSuggestionsModel.Conversation nativeConversation =
-                    new ActionsSuggestionsModel.Conversation(nativeMessages);
-
-            ActionsSuggestionsModel.ActionSuggestion[] nativeSuggestions =
-                    actionsImpl.suggestActionsWithIntents(
-                            nativeConversation,
-                            null,
-                            mContext,
-                            getResourceLocalesString(),
-                            getAnnotatorImpl(LocaleList.getDefault()));
-            return createConversationActionResult(request, nativeSuggestions);
-        } catch (Throwable t) {
-            // Avoid throwing from this method. Log the error.
-            TcLog.e(TAG, "Error suggesting conversation actions.", t);
-        }
-        return mFallback.suggestConversationActions(request);
-    }
-
-    /**
-     * Returns the {@link ConversationAction} result, with a non-null extras.
-     *
-     * <p>Whenever the RemoteAction is non-null, you can expect its corresponding intent with a
-     * non-null component name is in the extras.
-     */
-    private ConversationActions createConversationActionResult(
-            ConversationActions.Request request,
-            ActionsSuggestionsModel.ActionSuggestion[] nativeSuggestions) {
-        Collection<String> expectedTypes = resolveActionTypesFromRequest(request);
-        List<ConversationAction> conversationActions = new ArrayList<>();
-        for (ActionsSuggestionsModel.ActionSuggestion nativeSuggestion : nativeSuggestions) {
-            String actionType = nativeSuggestion.getActionType();
-            if (!expectedTypes.contains(actionType)) {
-                continue;
-            }
-            LabeledIntent.Result labeledIntentResult =
-                    ActionsSuggestionsHelper.createLabeledIntentResult(
-                            mContext, mTemplateIntentFactory, nativeSuggestion);
-            RemoteAction remoteAction = null;
-            Bundle extras = new Bundle();
-            if (labeledIntentResult != null) {
-                remoteAction = labeledIntentResult.remoteAction;
-                ExtrasUtils.putActionIntent(extras, labeledIntentResult.resolvedIntent);
-            }
-            ExtrasUtils.putSerializedEntityData(extras, nativeSuggestion.getSerializedEntityData());
-            ExtrasUtils.putEntitiesExtras(
-                    extras,
-                    TemplateIntentFactory.nameVariantsToBundle(nativeSuggestion.getEntityData()));
-            conversationActions.add(
-                    new ConversationAction.Builder(actionType)
-                            .setConfidenceScore(nativeSuggestion.getScore())
-                            .setTextReply(nativeSuggestion.getResponseText())
-                            .setAction(remoteAction)
-                            .setExtras(extras)
-                            .build());
-        }
-        conversationActions =
-                ActionsSuggestionsHelper.removeActionsWithDuplicates(conversationActions);
-        if (request.getMaxSuggestions() >= 0
-                && conversationActions.size() > request.getMaxSuggestions()) {
-            conversationActions = conversationActions.subList(0, request.getMaxSuggestions());
-        }
-        synchronized (mLock) {
-            String resultId =
-                    ActionsSuggestionsHelper.createResultId(
-                            mContext,
-                            request.getConversation(),
-                            mActionModelInUse.getVersion(),
-                            mActionModelInUse.getSupportedLocales());
-            return new ConversationActions(conversationActions, resultId);
-        }
-    }
-
-    private Collection<String> resolveActionTypesFromRequest(ConversationActions.Request request) {
-        List<String> defaultActionTypes =
-                request.getHints().contains(ConversationActions.Request.HINT_FOR_NOTIFICATION)
-                        ? mSettings.getNotificationConversationActionTypes()
-                        : mSettings.getInAppConversationActionTypes();
-        return request.getTypeConfig().resolveEntityListModifications(defaultActionTypes);
-    }
-
-    private AnnotatorModel getAnnotatorImpl(LocaleList localeList) throws FileNotFoundException {
-        synchronized (mLock) {
-            localeList = localeList == null ? LocaleList.getDefault() : localeList;
-            final ModelFileManager.ModelFile bestModel =
-                    mAnnotatorModelFileManager.findBestModelFile(localeList);
-            if (bestModel == null) {
-                throw new FileNotFoundException(
-                        "No annotator model for " + localeList.toLanguageTags());
-            }
-            if (mAnnotatorImpl == null || !Objects.equals(mAnnotatorModelInUse, bestModel)) {
-                TcLog.d(TAG, "Loading " + bestModel);
-                final ParcelFileDescriptor pfd =
-                        ParcelFileDescriptor.open(
-                                new File(bestModel.getPath()), ParcelFileDescriptor.MODE_READ_ONLY);
-                try {
-                    if (pfd != null) {
-                        // The current annotator model may be still used by another thread / model.
-                        // Do not call close() here, and let the GC to clean it up when no one else
-                        // is using it.
-                        mAnnotatorImpl = new AnnotatorModel(pfd.getFd());
-                        mAnnotatorModelInUse = bestModel;
-                    }
-                } finally {
-                    maybeCloseAndLogError(pfd);
-                }
-            }
-            return mAnnotatorImpl;
-        }
-    }
-
-    private LangIdModel getLangIdImpl() throws FileNotFoundException {
-        synchronized (mLock) {
-            final ModelFileManager.ModelFile bestModel =
-                    mLangIdModelFileManager.findBestModelFile(null);
-            if (bestModel == null) {
-                throw new FileNotFoundException("No LangID model is found");
-            }
-            if (mLangIdImpl == null || !Objects.equals(mLangIdModelInUse, bestModel)) {
-                TcLog.d(TAG, "Loading " + bestModel);
-                final ParcelFileDescriptor pfd =
-                        ParcelFileDescriptor.open(
-                                new File(bestModel.getPath()), ParcelFileDescriptor.MODE_READ_ONLY);
-                try {
-                    if (pfd != null) {
-                        mLangIdImpl = new LangIdModel(pfd.getFd());
-                        mLangIdModelInUse = bestModel;
-                    }
-                } finally {
-                    maybeCloseAndLogError(pfd);
-                }
-            }
-            return mLangIdImpl;
-        }
-    }
-
-    @Nullable
-    private ActionsSuggestionsModel getActionsImpl() throws FileNotFoundException {
-        synchronized (mLock) {
-            // TODO: Use LangID to determine the locale we should use here?
-            final ModelFileManager.ModelFile bestModel =
-                    mActionsModelFileManager.findBestModelFile(LocaleList.getDefault());
-            if (bestModel == null) {
-                return null;
-            }
-            if (mActionsImpl == null || !Objects.equals(mActionModelInUse, bestModel)) {
-                TcLog.d(TAG, "Loading " + bestModel);
-                final ParcelFileDescriptor pfd =
-                        ParcelFileDescriptor.open(
-                                new File(bestModel.getPath()), ParcelFileDescriptor.MODE_READ_ONLY);
-                try {
-                    if (pfd == null) {
-                        TcLog.d(TAG, "Failed to read the model file: " + bestModel.getPath());
-                        return null;
-                    }
-                    ActionsModelParams params = mActionsModelParamsSupplier.get();
-                    mActionsImpl =
-                            new ActionsSuggestionsModel(
-                                    pfd.getFd(), params.getSerializedPreconditions(bestModel));
-                    mActionModelInUse = bestModel;
-                } finally {
-                    maybeCloseAndLogError(pfd);
-                }
-            }
-            return mActionsImpl;
-        }
-    }
-
-    private String createId(String text, int start, int end) {
-        synchronized (mLock) {
-            return ResultIdUtils.createId(
-                    mContext,
-                    text,
-                    start,
-                    end,
-                    mAnnotatorModelInUse.getVersion(),
-                    mAnnotatorModelInUse.getSupportedLocales());
-        }
-    }
-
-    private static String concatenateLocales(@Nullable LocaleList locales) {
-        return (locales == null) ? "" : locales.toLanguageTags();
-    }
-
-    private TextClassification createClassificationResult(
-            AnnotatorModel.ClassificationResult[] classifications,
-            String text,
-            int start,
-            int end,
-            @Nullable Instant referenceTime) {
-        final String classifiedText = text.substring(start, end);
-        final TextClassification.Builder builder =
-                new TextClassification.Builder().setText(classifiedText);
-
-        final int typeCount = classifications.length;
-        AnnotatorModel.ClassificationResult highestScoringResult =
-                typeCount > 0 ? classifications[0] : null;
-        for (int i = 0; i < typeCount; i++) {
-            builder.setEntityType(
-                    classifications[i].getCollection(), classifications[i].getScore());
-            if (classifications[i].getScore() > highestScoringResult.getScore()) {
-                highestScoringResult = classifications[i];
-            }
-        }
-        final Pair<Bundle, Bundle> languagesBundles = generateLanguageBundles(text, start, end);
-        final Bundle textLanguagesBundle = languagesBundles.first;
-        final Bundle foreignLanguageBundle = languagesBundles.second;
-
-        boolean isPrimaryAction = true;
-        final List<LabeledIntent> labeledIntents =
-                mClassificationIntentFactory.create(
-                        mContext,
-                        classifiedText,
-                        foreignLanguageBundle != null,
-                        referenceTime,
-                        highestScoringResult);
-        final LabeledIntent.TitleChooser titleChooser =
-                (labeledIntent, resolveInfo) -> labeledIntent.titleWithoutEntity;
-
-        ArrayList<Intent> actionIntents = new ArrayList<>();
-        for (LabeledIntent labeledIntent : labeledIntents) {
-            final LabeledIntent.Result result =
-                    labeledIntent.resolve(mContext, titleChooser, textLanguagesBundle);
-            if (result == null) {
-                continue;
-            }
-
-            final Intent intent = result.resolvedIntent;
-            final RemoteAction action = result.remoteAction;
-            if (isPrimaryAction) {
-                // For O backwards compatibility, the first RemoteAction is also written to the
-                // legacy API fields.
-                builder.setIcon(action.getIcon().loadDrawable(mContext));
-                builder.setLabel(action.getTitle().toString());
-                builder.setIntent(intent);
-                builder.setOnClickListener(
-                        createIntentOnClickListener(
-                                createPendingIntent(mContext, intent, labeledIntent.requestCode)));
-                isPrimaryAction = false;
-            }
-            builder.addAction(action);
-            actionIntents.add(intent);
+        final Map<String, Float> entityScores = new ArrayMap<>();
+        for (int i = 0; i < results.length; i++) {
+          entityScores.put(results[i].getCollection(), results[i].getScore());
         }
         Bundle extras = new Bundle();
-        ExtrasUtils.putForeignLanguageExtra(extras, foreignLanguageBundle);
-        if (actionIntents.stream().anyMatch(Objects::nonNull)) {
-            ExtrasUtils.putActionsIntents(extras, actionIntents);
+        if (isSerializedEntityDataEnabled) {
+          ExtrasUtils.putEntities(extras, results);
         }
-        ExtrasUtils.putEntities(extras, classifications);
-        builder.setExtras(extras);
-        return builder.setId(createId(text, start, end)).build();
+        builder.addLink(span.getStartIndex(), span.getEndIndex(), entityScores, extras);
+      }
+      final TextLinks links = builder.build();
+      final long endTimeMs = System.currentTimeMillis();
+      final String callingPackageName =
+          request.getCallingPackageName() == null
+              ? context.getPackageName() // local (in process) TC.
+              : request.getCallingPackageName();
+      generateLinksLogger.logGenerateLinks(
+          request.getText(), links, callingPackageName, endTimeMs - startTimeMs);
+      return links;
+    } catch (Throwable t) {
+      // Avoid throwing from this method. Log the error.
+      TcLog.e(TAG, "Error getting links info.", t);
     }
+    return fallback.generateLinks(request);
+  }
 
-    private static OnClickListener createIntentOnClickListener(
-            @NonNull final PendingIntent intent) {
-        Preconditions.checkNotNull(intent);
-        return v -> {
-            try {
-                intent.send();
-            } catch (PendingIntent.CanceledException e) {
-                TcLog.e(TAG, "Error sending PendingIntent", e);
-            }
-        };
+  int getMaxGenerateLinksTextLength() {
+    return settings.getGenerateLinksMaxTextLength();
+  }
+
+  private Collection<String> getEntitiesForHints(Collection<String> hints) {
+    final boolean editable = hints.contains(TextClassifier.HINT_TEXT_IS_EDITABLE);
+    final boolean notEditable = hints.contains(TextClassifier.HINT_TEXT_IS_NOT_EDITABLE);
+
+    // Use the default if there is no hint, or conflicting ones.
+    final boolean useDefault = editable == notEditable;
+    if (useDefault) {
+      return settings.getEntityListDefault();
+    } else if (editable) {
+      return settings.getEntityListEditable();
+    } else { // notEditable
+      return settings.getEntityListNotEditable();
     }
+  }
 
-    /**
-     * Returns a bundle pair with language detection information for extras.
-     *
-     * <p>Pair.first = textLanguagesBundle - A bundle containing information about all detected
-     * languages in the text. May be null if language detection fails or is disabled. This is
-     * typically expected to be added to a textClassifier generated remote action intent. See {@link
-     * ExtrasUtils#putTextLanguagesExtra(Bundle, Bundle)}. See {@link
-     * ExtrasUtils#getTopLanguage(Intent)}.
-     *
-     * <p>Pair.second = foreignLanguageBundle - A bundle with the language and confidence score if
-     * the system finds the text to be in a foreign language. Otherwise is null. See {@link
-     * TextClassification.Builder#setForeignLanguageExtra(Bundle)}.
-     *
-     * @param context the context of the text to detect languages for
-     * @param start the start index of the text
-     * @param end the end index of the text
-     */
-    // TODO: Revisit this algorithm.
-    // TODO: Consider making this public API.
-    private Pair<Bundle, Bundle> generateLanguageBundles(String context, int start, int end) {
-        if (!mSettings.isTranslateInClassificationEnabled()) {
+  void onSelectionEvent(SelectionEvent event) {
+    TextClassifierEvent textClassifierEvent = SelectionEventConverter.toTextClassifierEvent(event);
+    if (textClassifierEvent == null) {
+      return;
+    }
+    onTextClassifierEvent(event.getSessionId(), textClassifierEvent);
+  }
+
+  void onTextClassifierEvent(
+      @Nullable TextClassificationSessionId sessionId, TextClassifierEvent event) {
+    textClassifierEventLogger.writeEvent(sessionId, event);
+    if (settings.isUserLanguageProfileEnabled()) {
+      languageProfileAnalyzer.onTextClassifierEven(event);
+    }
+  }
+
+  TextLanguage detectLanguage(TextLanguage.Request request) {
+    Preconditions.checkNotNull(request);
+    checkMainThread();
+    try {
+      final TextLanguage.Builder builder = new TextLanguage.Builder();
+      final LangIdModel.LanguageResult[] langResults =
+          getLangIdImpl().detectLanguages(request.getText().toString());
+      for (int i = 0; i < langResults.length; i++) {
+        builder.putLocale(
+            ULocale.forLanguageTag(langResults[i].getLanguage()), langResults[i].getScore());
+      }
+      return builder.build();
+    } catch (Throwable t) {
+      // Avoid throwing from this method. Log the error.
+      TcLog.e(TAG, "Error detecting text language.", t);
+    }
+    return fallback.detectLanguage(request);
+  }
+
+  ConversationActions suggestConversationActions(ConversationActions.Request request) {
+    Preconditions.checkNotNull(request);
+    checkMainThread();
+    if (settings.isUserLanguageProfileEnabled()) {
+      // TODO(tonymak): Reuse the LangID result.
+      languageProfileUpdater.updateFromConversationActionsAsync(
+          request, text -> detectLanguages(text, getLangIdThreshold()).getEntities());
+    }
+    try {
+      ActionsSuggestionsModel actionsImpl = getActionsImpl();
+      if (actionsImpl == null) {
+        // Actions model is optional, fallback if it is not available.
+        return fallback.suggestConversationActions(request);
+      }
+      ActionsSuggestionsModel.ConversationMessage[] nativeMessages =
+          ActionsSuggestionsHelper.toNativeMessages(
+              request.getConversation(),
+              text -> detectLanguages(text, getLangIdThreshold()).getEntities());
+      if (nativeMessages.length == 0) {
+        return fallback.suggestConversationActions(request);
+      }
+      ActionsSuggestionsModel.Conversation nativeConversation =
+          new ActionsSuggestionsModel.Conversation(nativeMessages);
+
+      ActionsSuggestionsModel.ActionSuggestion[] nativeSuggestions =
+          actionsImpl.suggestActionsWithIntents(
+              nativeConversation,
+              null,
+              context,
+              getResourceLocalesString(),
+              getAnnotatorImpl(LocaleList.getDefault()));
+      return createConversationActionResult(request, nativeSuggestions);
+    } catch (Throwable t) {
+      // Avoid throwing from this method. Log the error.
+      TcLog.e(TAG, "Error suggesting conversation actions.", t);
+    }
+    return fallback.suggestConversationActions(request);
+  }
+
+  /**
+   * Returns the {@link ConversationAction} result, with a non-null extras.
+   *
+   * <p>Whenever the RemoteAction is non-null, you can expect its corresponding intent with a
+   * non-null component name is in the extras.
+   */
+  private ConversationActions createConversationActionResult(
+      ConversationActions.Request request,
+      ActionsSuggestionsModel.ActionSuggestion[] nativeSuggestions) {
+    Collection<String> expectedTypes = resolveActionTypesFromRequest(request);
+    List<ConversationAction> conversationActions = new ArrayList<>();
+    for (ActionsSuggestionsModel.ActionSuggestion nativeSuggestion : nativeSuggestions) {
+      String actionType = nativeSuggestion.getActionType();
+      if (!expectedTypes.contains(actionType)) {
+        continue;
+      }
+      LabeledIntent.Result labeledIntentResult =
+          ActionsSuggestionsHelper.createLabeledIntentResult(
+              context, templateIntentFactory, nativeSuggestion);
+      RemoteAction remoteAction = null;
+      Bundle extras = new Bundle();
+      if (labeledIntentResult != null) {
+        remoteAction = labeledIntentResult.remoteAction;
+        ExtrasUtils.putActionIntent(extras, labeledIntentResult.resolvedIntent);
+      }
+      ExtrasUtils.putSerializedEntityData(extras, nativeSuggestion.getSerializedEntityData());
+      ExtrasUtils.putEntitiesExtras(
+          extras, TemplateIntentFactory.nameVariantsToBundle(nativeSuggestion.getEntityData()));
+      conversationActions.add(
+          new ConversationAction.Builder(actionType)
+              .setConfidenceScore(nativeSuggestion.getScore())
+              .setTextReply(nativeSuggestion.getResponseText())
+              .setAction(remoteAction)
+              .setExtras(extras)
+              .build());
+    }
+    conversationActions = ActionsSuggestionsHelper.removeActionsWithDuplicates(conversationActions);
+    if (request.getMaxSuggestions() >= 0
+        && conversationActions.size() > request.getMaxSuggestions()) {
+      conversationActions = conversationActions.subList(0, request.getMaxSuggestions());
+    }
+    synchronized (lock) {
+      String resultId =
+          ActionsSuggestionsHelper.createResultId(
+              context,
+              request.getConversation(),
+              actionModelInUse.getVersion(),
+              actionModelInUse.getSupportedLocales());
+      return new ConversationActions(conversationActions, resultId);
+    }
+  }
+
+  private Collection<String> resolveActionTypesFromRequest(ConversationActions.Request request) {
+    List<String> defaultActionTypes =
+        request.getHints().contains(ConversationActions.Request.HINT_FOR_NOTIFICATION)
+            ? settings.getNotificationConversationActionTypes()
+            : settings.getInAppConversationActionTypes();
+    return request.getTypeConfig().resolveEntityListModifications(defaultActionTypes);
+  }
+
+  private AnnotatorModel getAnnotatorImpl(LocaleList localeList) throws FileNotFoundException {
+    synchronized (lock) {
+      localeList = localeList == null ? LocaleList.getDefault() : localeList;
+      final ModelFileManager.ModelFile bestModel =
+          annotatorModelFileManager.findBestModelFile(localeList);
+      if (bestModel == null) {
+        throw new FileNotFoundException("No annotator model for " + localeList.toLanguageTags());
+      }
+      if (annotatorImpl == null || !Objects.equals(annotatorModelInUse, bestModel)) {
+        TcLog.d(TAG, "Loading " + bestModel);
+        final ParcelFileDescriptor pfd =
+            ParcelFileDescriptor.open(
+                new File(bestModel.getPath()), ParcelFileDescriptor.MODE_READ_ONLY);
+        try {
+          if (pfd != null) {
+            // The current annotator model may be still used by another thread / model.
+            // Do not call close() here, and let the GC to clean it up when no one else
+            // is using it.
+            annotatorImpl = new AnnotatorModel(pfd.getFd());
+            annotatorModelInUse = bestModel;
+          }
+        } finally {
+          maybeCloseAndLogError(pfd);
+        }
+      }
+      return annotatorImpl;
+    }
+  }
+
+  private LangIdModel getLangIdImpl() throws FileNotFoundException {
+    synchronized (lock) {
+      final ModelFileManager.ModelFile bestModel = langIdModelFileManager.findBestModelFile(null);
+      if (bestModel == null) {
+        throw new FileNotFoundException("No LangID model is found");
+      }
+      if (langIdImpl == null || !Objects.equals(langIdModelInUse, bestModel)) {
+        TcLog.d(TAG, "Loading " + bestModel);
+        final ParcelFileDescriptor pfd =
+            ParcelFileDescriptor.open(
+                new File(bestModel.getPath()), ParcelFileDescriptor.MODE_READ_ONLY);
+        try {
+          if (pfd != null) {
+            langIdImpl = new LangIdModel(pfd.getFd());
+            langIdModelInUse = bestModel;
+          }
+        } finally {
+          maybeCloseAndLogError(pfd);
+        }
+      }
+      return langIdImpl;
+    }
+  }
+
+  @Nullable
+  private ActionsSuggestionsModel getActionsImpl() throws FileNotFoundException {
+    synchronized (lock) {
+      // TODO: Use LangID to determine the locale we should use here?
+      final ModelFileManager.ModelFile bestModel =
+          actionsModelFileManager.findBestModelFile(LocaleList.getDefault());
+      if (bestModel == null) {
+        return null;
+      }
+      if (actionsImpl == null || !Objects.equals(actionModelInUse, bestModel)) {
+        TcLog.d(TAG, "Loading " + bestModel);
+        final ParcelFileDescriptor pfd =
+            ParcelFileDescriptor.open(
+                new File(bestModel.getPath()), ParcelFileDescriptor.MODE_READ_ONLY);
+        try {
+          if (pfd == null) {
+            TcLog.d(TAG, "Failed to read the model file: " + bestModel.getPath());
             return null;
+          }
+          ActionsModelParams params = actionsModelParamsSupplier.get();
+          actionsImpl =
+              new ActionsSuggestionsModel(
+                  pfd.getFd(), params.getSerializedPreconditions(bestModel));
+          actionModelInUse = bestModel;
+        } finally {
+          maybeCloseAndLogError(pfd);
         }
-        try {
-            final float threshold = getLangIdThreshold();
-            if (threshold < 0 || threshold > 1) {
-                TcLog.w(TAG, "[detectForeignLanguage] unexpected threshold is found: " + threshold);
-                return Pair.create(null, null);
-            }
+      }
+      return actionsImpl;
+    }
+  }
 
-            final EntityConfidence languageScores = detectLanguages(context, start, end);
-            if (languageScores.getEntities().isEmpty()) {
-                return Pair.create(null, null);
-            }
+  private String createId(String text, int start, int end) {
+    synchronized (lock) {
+      return ResultIdUtils.createId(
+          context,
+          text,
+          start,
+          end,
+          annotatorModelInUse.getVersion(),
+          annotatorModelInUse.getSupportedLocales());
+    }
+  }
 
-            final Bundle textLanguagesBundle = new Bundle();
-            ExtrasUtils.putTopLanguageScores(textLanguagesBundle, languageScores);
+  private static String concatenateLocales(@Nullable LocaleList locales) {
+    return (locales == null) ? "" : locales.toLanguageTags();
+  }
 
-            final String language = languageScores.getEntities().get(0);
-            final float score = languageScores.getConfidenceScore(language);
-            if (score < threshold) {
-                return Pair.create(textLanguagesBundle, null);
-            }
+  private TextClassification createClassificationResult(
+      AnnotatorModel.ClassificationResult[] classifications,
+      String text,
+      int start,
+      int end,
+      @Nullable Instant referenceTime) {
+    final String classifiedText = text.substring(start, end);
+    final TextClassification.Builder builder =
+        new TextClassification.Builder().setText(classifiedText);
 
-            TcLog.v(TAG, String.format(Locale.US, "Language detected: <%s:%.2f>", language, score));
-            if (mSettings.isUserLanguageProfileEnabled()) {
-                if (!mLanguageProfileAnalyzer.shouldShowTranslation(language)) {
-                    return Pair.create(textLanguagesBundle, null);
-                }
-            } else {
-                final Locale detected = new Locale(language);
-                final LocaleList deviceLocales = LocaleList.getDefault();
-                final int size = deviceLocales.size();
-                for (int i = 0; i < size; i++) {
-                    if (deviceLocales.get(i).getLanguage().equals(detected.getLanguage())) {
-                        return Pair.create(textLanguagesBundle, null);
-                    }
-                }
-            }
-            final Bundle foreignLanguageBundle =
-                    ExtrasUtils.createForeignLanguageExtra(
-                            language, score, getLangIdImpl().getVersion());
-            return Pair.create(textLanguagesBundle, foreignLanguageBundle);
-        } catch (Throwable t) {
-            TcLog.e(TAG, "Error generating language bundles.", t);
-        }
+    final int typeCount = classifications.length;
+    AnnotatorModel.ClassificationResult highestScoringResult =
+        typeCount > 0 ? classifications[0] : null;
+    for (int i = 0; i < typeCount; i++) {
+      builder.setEntityType(classifications[i].getCollection(), classifications[i].getScore());
+      if (classifications[i].getScore() > highestScoringResult.getScore()) {
+        highestScoringResult = classifications[i];
+      }
+    }
+    final Pair<Bundle, Bundle> languagesBundles = generateLanguageBundles(text, start, end);
+    final Bundle textLanguagesBundle = languagesBundles.first;
+    final Bundle foreignLanguageBundle = languagesBundles.second;
+
+    boolean isPrimaryAction = true;
+    final List<LabeledIntent> labeledIntents =
+        classificationIntentFactory.create(
+            context,
+            classifiedText,
+            foreignLanguageBundle != null,
+            referenceTime,
+            highestScoringResult);
+    final LabeledIntent.TitleChooser titleChooser =
+        (labeledIntent, resolveInfo) -> labeledIntent.titleWithoutEntity;
+
+    ArrayList<Intent> actionIntents = new ArrayList<>();
+    for (LabeledIntent labeledIntent : labeledIntents) {
+      final LabeledIntent.Result result =
+          labeledIntent.resolve(context, titleChooser, textLanguagesBundle);
+      if (result == null) {
+        continue;
+      }
+
+      final Intent intent = result.resolvedIntent;
+      final RemoteAction action = result.remoteAction;
+      if (isPrimaryAction) {
+        // For O backwards compatibility, the first RemoteAction is also written to the
+        // legacy API fields.
+        builder.setIcon(action.getIcon().loadDrawable(context));
+        builder.setLabel(action.getTitle().toString());
+        builder.setIntent(intent);
+        builder.setOnClickListener(
+            createIntentOnClickListener(
+                createPendingIntent(context, intent, labeledIntent.requestCode)));
+        isPrimaryAction = false;
+      }
+      builder.addAction(action);
+      actionIntents.add(intent);
+    }
+    Bundle extras = new Bundle();
+    ExtrasUtils.putForeignLanguageExtra(extras, foreignLanguageBundle);
+    if (actionIntents.stream().anyMatch(Objects::nonNull)) {
+      ExtrasUtils.putActionsIntents(extras, actionIntents);
+    }
+    ExtrasUtils.putEntities(extras, classifications);
+    builder.setExtras(extras);
+    return builder.setId(createId(text, start, end)).build();
+  }
+
+  private static OnClickListener createIntentOnClickListener(final PendingIntent intent) {
+    Preconditions.checkNotNull(intent);
+    return v -> {
+      try {
+        intent.send();
+      } catch (PendingIntent.CanceledException e) {
+        TcLog.e(TAG, "Error sending PendingIntent", e);
+      }
+    };
+  }
+
+  /**
+   * Returns a bundle pair with language detection information for extras.
+   *
+   * <p>Pair.first = textLanguagesBundle - A bundle containing information about all detected
+   * languages in the text. May be null if language detection fails or is disabled. This is
+   * typically expected to be added to a textClassifier generated remote action intent. See {@link
+   * ExtrasUtils#putTextLanguagesExtra(Bundle, Bundle)}. See {@link
+   * ExtrasUtils#getTopLanguage(Intent)}.
+   *
+   * <p>Pair.second = foreignLanguageBundle - A bundle with the language and confidence score if the
+   * system finds the text to be in a foreign language. Otherwise is null. See {@link
+   * TextClassification.Builder#setForeignLanguageExtra(Bundle)}.
+   *
+   * @param context the context of the text to detect languages for
+   * @param start the start index of the text
+   * @param end the end index of the text
+   */
+  // TODO: Revisit this algorithm.
+  // TODO: Consider making this public API.
+  private Pair<Bundle, Bundle> generateLanguageBundles(String context, int start, int end) {
+    if (!settings.isTranslateInClassificationEnabled()) {
+      return null;
+    }
+    try {
+      final float threshold = getLangIdThreshold();
+      if (threshold < 0 || threshold > 1) {
+        TcLog.w(TAG, "[detectForeignLanguage] unexpected threshold is found: " + threshold);
         return Pair.create(null, null);
+      }
+
+      final EntityConfidence languageScores = detectLanguages(context, start, end);
+      if (languageScores.getEntities().isEmpty()) {
+        return Pair.create(null, null);
+      }
+
+      final Bundle textLanguagesBundle = new Bundle();
+      ExtrasUtils.putTopLanguageScores(textLanguagesBundle, languageScores);
+
+      final String language = languageScores.getEntities().get(0);
+      final float score = languageScores.getConfidenceScore(language);
+      if (score < threshold) {
+        return Pair.create(textLanguagesBundle, null);
+      }
+
+      TcLog.v(TAG, String.format(Locale.US, "Language detected: <%s:%.2f>", language, score));
+      if (settings.isUserLanguageProfileEnabled()) {
+        if (!languageProfileAnalyzer.shouldShowTranslation(language)) {
+          return Pair.create(textLanguagesBundle, null);
+        }
+      } else {
+        final Locale detected = new Locale(language);
+        final LocaleList deviceLocales = LocaleList.getDefault();
+        final int size = deviceLocales.size();
+        for (int i = 0; i < size; i++) {
+          if (deviceLocales.get(i).getLanguage().equals(detected.getLanguage())) {
+            return Pair.create(textLanguagesBundle, null);
+          }
+        }
+      }
+      final Bundle foreignLanguageBundle =
+          ExtrasUtils.createForeignLanguageExtra(language, score, getLangIdImpl().getVersion());
+      return Pair.create(textLanguagesBundle, foreignLanguageBundle);
+    } catch (Throwable t) {
+      TcLog.e(TAG, "Error generating language bundles.", t);
+    }
+    return Pair.create(null, null);
+  }
+
+  /**
+   * Detect the language of a piece of text by taking surrounding text into consideration.
+   *
+   * @param text text providing context for the text for which its language is to be detected
+   * @param start the start index of the text to detect its language
+   * @param end the end index of the text to detect its language
+   */
+  // TODO: Revisit this algorithm.
+  private EntityConfidence detectLanguages(String text, int start, int end) {
+    Preconditions.checkArgument(start >= 0);
+    Preconditions.checkArgument(end <= text.length());
+    Preconditions.checkArgument(start <= end);
+
+    final float[] langIdContextSettings = settings.getLangIdContextSettings();
+    // The minimum size of text to prefer for detection.
+    final int minimumTextSize = (int) langIdContextSettings[0];
+    // For reducing the score when text is less than the preferred size.
+    final float penalizeRatio = langIdContextSettings[1];
+    // Original detection score to surrounding text detection score ratios.
+    final float subjectTextScoreRatio = langIdContextSettings[2];
+    final float moreTextScoreRatio = 1f - subjectTextScoreRatio;
+    TcLog.v(
+        TAG,
+        String.format(
+            Locale.US,
+            "LangIdContextSettings: "
+                + "minimumTextSize=%d, penalizeRatio=%.2f, "
+                + "subjectTextScoreRatio=%.2f, moreTextScoreRatio=%.2f",
+            minimumTextSize,
+            penalizeRatio,
+            subjectTextScoreRatio,
+            moreTextScoreRatio));
+
+    if (end - start < minimumTextSize && penalizeRatio <= 0) {
+      return EntityConfidence.EMPTY;
     }
 
-    /**
-     * Detect the language of a piece of text by taking surrounding text into consideration.
-     *
-     * @param text text providing context for the text for which its language is to be detected
-     * @param start the start index of the text to detect its language
-     * @param end the end index of the text to detect its language
-     */
-    // TODO: Revisit this algorithm.
-    private EntityConfidence detectLanguages(String text, int start, int end) {
-        Preconditions.checkArgument(start >= 0);
-        Preconditions.checkArgument(end <= text.length());
-        Preconditions.checkArgument(start <= end);
+    final String subject = text.substring(start, end);
+    final EntityConfidence scores = detectLanguages(subject, /* threshold= */ 0f);
 
-        final float[] langIdContextSettings = mSettings.getLangIdContextSettings();
-        // The minimum size of text to prefer for detection.
-        final int minimumTextSize = (int) langIdContextSettings[0];
-        // For reducing the score when text is less than the preferred size.
-        final float penalizeRatio = langIdContextSettings[1];
-        // Original detection score to surrounding text detection score ratios.
-        final float subjectTextScoreRatio = langIdContextSettings[2];
-        final float moreTextScoreRatio = 1f - subjectTextScoreRatio;
-        TcLog.v(
-                TAG,
-                String.format(
-                        Locale.US,
-                        "LangIdContextSettings: "
-                                + "minimumTextSize=%d, penalizeRatio=%.2f, "
-                                + "subjectTextScoreRatio=%.2f, moreTextScoreRatio=%.2f",
-                        minimumTextSize,
-                        penalizeRatio,
-                        subjectTextScoreRatio,
-                        moreTextScoreRatio));
-
-        if (end - start < minimumTextSize && penalizeRatio <= 0) {
-            return EntityConfidence.EMPTY;
-        }
-
-        final String subject = text.substring(start, end);
-        final EntityConfidence scores = detectLanguages(subject, /* threshold= */ 0f);
-
-        if (subject.length() >= minimumTextSize
-                || subject.length() == text.length()
-                || subjectTextScoreRatio * penalizeRatio >= 1) {
-            return scores;
-        }
-
-        final EntityConfidence moreTextScores;
-        if (moreTextScoreRatio >= 0) {
-            // Attempt to grow the detection text to be at least minimumTextSize long.
-            final String moreText = StringUtils.getSubString(text, start, end, minimumTextSize);
-            moreTextScores = detectLanguages(moreText, /* threshold= */ 0f);
-        } else {
-            moreTextScores = EntityConfidence.EMPTY;
-        }
-
-        // Combine the original detection scores with the those returned after including more text.
-        final Map<String, Float> newScores = new ArrayMap<>();
-        final Set<String> languages = new ArraySet<>();
-        languages.addAll(scores.getEntities());
-        languages.addAll(moreTextScores.getEntities());
-        for (String language : languages) {
-            final float score =
-                    (subjectTextScoreRatio * scores.getConfidenceScore(language)
-                                    + moreTextScoreRatio
-                                            * moreTextScores.getConfidenceScore(language))
-                            * penalizeRatio;
-            newScores.put(language, score);
-        }
-        return new EntityConfidence(newScores);
+    if (subject.length() >= minimumTextSize
+        || subject.length() == text.length()
+        || subjectTextScoreRatio * penalizeRatio >= 1) {
+      return scores;
     }
 
-    /**
-     * Detects languages for the specified text. Only returns languages with score that is higher
-     * than or equal to the specified threshold.
-     */
-    private EntityConfidence detectLanguages(CharSequence text, float threshold) {
-        final LangIdModel langId;
-        try {
-            langId = getLangIdImpl();
-        } catch (FileNotFoundException e) {
-            TcLog.e(TAG, "detectLanguages: Failed to call getLangIdImpl ", e);
-            return EntityConfidence.EMPTY;
-        }
-        final LangIdModel.LanguageResult[] langResults = langId.detectLanguages(text.toString());
-        final Map<String, Float> languagesMap = new ArrayMap<>();
-        for (LangIdModel.LanguageResult langResult : langResults) {
-            if (langResult.getScore() >= threshold) {
-                languagesMap.put(langResult.getLanguage(), langResult.getScore());
-            }
-        }
-        return new EntityConfidence(languagesMap);
+    final EntityConfidence moreTextScores;
+    if (moreTextScoreRatio >= 0) {
+      // Attempt to grow the detection text to be at least minimumTextSize long.
+      final String moreText = StringUtils.getSubString(text, start, end, minimumTextSize);
+      moreTextScores = detectLanguages(moreText, /* threshold= */ 0f);
+    } else {
+      moreTextScores = EntityConfidence.EMPTY;
     }
 
-    private float getLangIdThreshold() {
-        try {
-            return mSettings.getLangIdThresholdOverride() >= 0
-                    ? mSettings.getLangIdThresholdOverride()
-                    : getLangIdImpl().getLangIdThreshold();
-        } catch (FileNotFoundException e) {
-            final float defaultThreshold = 0.5f;
-            TcLog.v(TAG, "Using default foreign language threshold: " + defaultThreshold);
-            return defaultThreshold;
-        }
+    // Combine the original detection scores with the those returned after including more text.
+    final Map<String, Float> newScores = new ArrayMap<>();
+    final Set<String> languages = new ArraySet<>();
+    languages.addAll(scores.getEntities());
+    languages.addAll(moreTextScores.getEntities());
+    for (String language : languages) {
+      final float score =
+          (subjectTextScoreRatio * scores.getConfidenceScore(language)
+                  + moreTextScoreRatio * moreTextScores.getConfidenceScore(language))
+              * penalizeRatio;
+      newScores.put(language, score);
+    }
+    return new EntityConfidence(newScores);
+  }
+
+  /**
+   * Detects languages for the specified text. Only returns languages with score that is higher than
+   * or equal to the specified threshold.
+   */
+  private EntityConfidence detectLanguages(CharSequence text, float threshold) {
+    final LangIdModel langId;
+    try {
+      langId = getLangIdImpl();
+    } catch (FileNotFoundException e) {
+      TcLog.e(TAG, "detectLanguages: Failed to call getLangIdImpl ", e);
+      return EntityConfidence.EMPTY;
+    }
+    final LangIdModel.LanguageResult[] langResults = langId.detectLanguages(text.toString());
+    final Map<String, Float> languagesMap = new ArrayMap<>();
+    for (LangIdModel.LanguageResult langResult : langResults) {
+      if (langResult.getScore() >= threshold) {
+        languagesMap.put(langResult.getLanguage(), langResult.getScore());
+      }
+    }
+    return new EntityConfidence(languagesMap);
+  }
+
+  private float getLangIdThreshold() {
+    try {
+      return settings.getLangIdThresholdOverride() >= 0
+          ? settings.getLangIdThresholdOverride()
+          : getLangIdImpl().getLangIdThreshold();
+    } catch (FileNotFoundException e) {
+      final float defaultThreshold = 0.5f;
+      TcLog.v(TAG, "Using default foreign language threshold: " + defaultThreshold);
+      return defaultThreshold;
+    }
+  }
+
+  void dump(IndentingPrintWriter printWriter) {
+    synchronized (lock) {
+      printWriter.println("TextClassifierImpl:");
+      printWriter.increaseIndent();
+      printWriter.println("Annotator model file(s):");
+      printWriter.increaseIndent();
+      for (ModelFileManager.ModelFile modelFile : annotatorModelFileManager.listModelFiles()) {
+        printWriter.println(modelFile.toString());
+      }
+      printWriter.decreaseIndent();
+      printWriter.println("LangID model file(s):");
+      printWriter.increaseIndent();
+      for (ModelFileManager.ModelFile modelFile : langIdModelFileManager.listModelFiles()) {
+        printWriter.println(modelFile.toString());
+      }
+      printWriter.decreaseIndent();
+      printWriter.println("Actions model file(s):");
+      printWriter.increaseIndent();
+      for (ModelFileManager.ModelFile modelFile : actionsModelFileManager.listModelFiles()) {
+        printWriter.println(modelFile.toString());
+      }
+      printWriter.decreaseIndent();
+      printWriter.printPair("mFallback", fallback);
+      printWriter.decreaseIndent();
+      printWriter.println();
+      settings.dump(printWriter);
+      if (settings.isUserLanguageProfileEnabled()) {
+        printWriter.println();
+        languageProfileUpdater.dump(printWriter);
+        printWriter.println();
+        languageProfileAnalyzer.dump(printWriter);
+      }
+    }
+  }
+
+  /** Returns the locales string for the current resources configuration. */
+  private String getResourceLocalesString() {
+    try {
+      return context.getResources().getConfiguration().getLocales().toLanguageTags();
+    } catch (NullPointerException e) {
+
+      // NPE is unexpected. Erring on the side of caution.
+      return LocaleList.getDefault().toLanguageTags();
+    }
+  }
+
+  /** Closes the ParcelFileDescriptor, if non-null, and logs any errors that occur. */
+  private static void maybeCloseAndLogError(@Nullable ParcelFileDescriptor fd) {
+    if (fd == null) {
+      return;
     }
 
-    void dump(IndentingPrintWriter printWriter) {
-        synchronized (mLock) {
-            printWriter.println("TextClassifierImpl:");
-            printWriter.increaseIndent();
-            printWriter.println("Annotator model file(s):");
-            printWriter.increaseIndent();
-            for (ModelFileManager.ModelFile modelFile :
-                    mAnnotatorModelFileManager.listModelFiles()) {
-                printWriter.println(modelFile.toString());
-            }
-            printWriter.decreaseIndent();
-            printWriter.println("LangID model file(s):");
-            printWriter.increaseIndent();
-            for (ModelFileManager.ModelFile modelFile : mLangIdModelFileManager.listModelFiles()) {
-                printWriter.println(modelFile.toString());
-            }
-            printWriter.decreaseIndent();
-            printWriter.println("Actions model file(s):");
-            printWriter.increaseIndent();
-            for (ModelFileManager.ModelFile modelFile : mActionsModelFileManager.listModelFiles()) {
-                printWriter.println(modelFile.toString());
-            }
-            printWriter.decreaseIndent();
-            printWriter.printPair("mFallback", mFallback);
-            printWriter.decreaseIndent();
-            printWriter.println();
-            mSettings.dump(printWriter);
-            if (mSettings.isUserLanguageProfileEnabled()) {
-                printWriter.println();
-                mLanguageProfileUpdater.dump(printWriter);
-                printWriter.println();
-                mLanguageProfileAnalyzer.dump(printWriter);
-            }
-        }
+    try {
+      fd.close();
+    } catch (IOException e) {
+      TcLog.e(TAG, "Error closing file.", e);
     }
+  }
 
-    /** Returns the locales string for the current resources configuration. */
-    private String getResourceLocalesString() {
-        try {
-            return mContext.getResources().getConfiguration().getLocales().toLanguageTags();
-        } catch (NullPointerException e) {
-
-            // NPE is unexpected. Erring on the side of caution.
-            return LocaleList.getDefault().toLanguageTags();
-        }
+  private static void checkMainThread() {
+    if (Looper.myLooper() == Looper.getMainLooper()) {
+      TcLog.e(TAG, "TextClassifier called on main thread", new Exception());
     }
+  }
 
-    /** Closes the ParcelFileDescriptor, if non-null, and logs any errors that occur. */
-    private static void maybeCloseAndLogError(@Nullable ParcelFileDescriptor fd) {
-        if (fd == null) {
-            return;
-        }
-
-        try {
-            fd.close();
-        } catch (IOException e) {
-            TcLog.e(TAG, "Error closing file.", e);
-        }
-    }
-
-    private static void checkMainThread() {
-        if (Looper.myLooper() == Looper.getMainLooper()) {
-            TcLog.e(TAG, "TextClassifier called on main thread", new Exception());
-        }
-    }
-
-    private static PendingIntent createPendingIntent(
-            @NonNull final Context context, @NonNull final Intent intent, int requestCode) {
-        return PendingIntent.getActivity(
-                context, requestCode, intent, PendingIntent.FLAG_UPDATE_CURRENT);
-    }
+  private static PendingIntent createPendingIntent(
+      final Context context, final Intent intent, int requestCode) {
+    return PendingIntent.getActivity(
+        context, requestCode, intent, PendingIntent.FLAG_UPDATE_CURRENT);
+  }
 }
diff --git a/java/src/com/android/textclassifier/intent/ClassificationIntentFactory.java b/java/src/com/android/textclassifier/intent/ClassificationIntentFactory.java
index 180bc96..8704644 100644
--- a/java/src/com/android/textclassifier/intent/ClassificationIntentFactory.java
+++ b/java/src/com/android/textclassifier/intent/ClassificationIntentFactory.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2018 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -13,44 +13,41 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package com.android.textclassifier.intent;
 
 import android.content.Context;
 import android.content.Intent;
-
-import androidx.annotation.Nullable;
-
 import com.android.textclassifier.R;
-
 import com.google.android.textclassifier.AnnotatorModel;
-
 import java.time.Instant;
 import java.util.List;
+import javax.annotation.Nullable;
 
-/** @hide */
+/** Generates intents from classification results. */
 public interface ClassificationIntentFactory {
 
-    /** Return a list of LabeledIntent from the classification result. */
-    List<LabeledIntent> create(
-            Context context,
-            String text,
-            boolean foreignText,
-            @Nullable Instant referenceTime,
-            @Nullable AnnotatorModel.ClassificationResult classification);
+  /** Return a list of LabeledIntent from the classification result. */
+  List<LabeledIntent> create(
+      Context context,
+      String text,
+      boolean foreignText,
+      @Nullable Instant referenceTime,
+      @Nullable AnnotatorModel.ClassificationResult classification);
 
-    /** Inserts translate action to the list if it is a foreign text. */
-    static void insertTranslateAction(List<LabeledIntent> actions, Context context, String text) {
-        actions.add(
-                new LabeledIntent(
-                        context.getString(R.string.translate),
-                        /* titleWithEntity */ null,
-                        context.getString(R.string.translate_desc),
-                        /* descriptionWithAppName */ null,
-                        new Intent(Intent.ACTION_TRANSLATE)
-                                // TODO: Probably better to introduce a "translate" scheme instead
-                                // of
-                                // using EXTRA_TEXT.
-                                .putExtra(Intent.EXTRA_TEXT, text),
-                        text.hashCode()));
-    }
+  /** Inserts translate action to the list if it is a foreign text. */
+  static void insertTranslateAction(List<LabeledIntent> actions, Context context, String text) {
+    actions.add(
+        new LabeledIntent(
+            context.getString(R.string.translate),
+            /* titleWithEntity */ null,
+            context.getString(R.string.translate_desc),
+            /* descriptionWithAppName */ null,
+            new Intent(Intent.ACTION_TRANSLATE)
+                // TODO: Probably better to introduce a "translate" scheme instead
+                // of
+                // using EXTRA_TEXT.
+                .putExtra(Intent.EXTRA_TEXT, text),
+            text.hashCode()));
+  }
 }
diff --git a/java/src/com/android/textclassifier/intent/LabeledIntent.java b/java/src/com/android/textclassifier/intent/LabeledIntent.java
index e51aa82..e678291 100644
--- a/java/src/com/android/textclassifier/intent/LabeledIntent.java
+++ b/java/src/com/android/textclassifier/intent/LabeledIntent.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2018 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -13,6 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package com.android.textclassifier.intent;
 
 import android.app.PendingIntent;
@@ -26,195 +27,183 @@
 import android.os.Bundle;
 import android.text.TextUtils;
 import android.view.textclassifier.TextClassifier;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.annotation.VisibleForTesting;
-import androidx.core.util.Preconditions;
-
 import com.android.textclassifier.ExtrasUtils;
 import com.android.textclassifier.R;
 import com.android.textclassifier.TcLog;
+import com.google.common.base.Preconditions;
+import javax.annotation.Nullable;
 
 /**
  * Helper class to store the information from which RemoteActions are built.
  *
  * @hide
  */
-@VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE)
 public final class LabeledIntent {
-    private static final String TAG = "LabeledIntent";
-    public static final int DEFAULT_REQUEST_CODE = 0;
-    private static final TitleChooser DEFAULT_TITLE_CHOOSER =
-            (labeledIntent, resolveInfo) -> {
-                if (!TextUtils.isEmpty(labeledIntent.titleWithEntity)) {
-                    return labeledIntent.titleWithEntity;
-                }
-                return labeledIntent.titleWithoutEntity;
-            };
-
-    @Nullable public final String titleWithoutEntity;
-    @Nullable public final String titleWithEntity;
-    public final String description;
-    @Nullable public final String descriptionWithAppName;
-    // Do not update this intent.
-    public final Intent intent;
-    public final int requestCode;
-
-    /**
-     * Initializes a LabeledIntent.
-     *
-     * <p>NOTE: {@code requestCode} is required to not be {@link #DEFAULT_REQUEST_CODE} if
-     * distinguishing info (e.g. the classified text) is represented in intent extras only. In such
-     * circumstances, the request code should represent the distinguishing info (e.g. by generating
-     * a hashcode) so that the generated PendingIntent is (somewhat) unique. To be correct, the
-     * PendingIntent should be definitely unique but we try a best effort approach that avoids
-     * spamming the system with PendingIntents.
-     */
-    // TODO: Fix the issue mentioned above so the behaviour is correct.
-    public LabeledIntent(
-            @Nullable String titleWithoutEntity,
-            @Nullable String titleWithEntity,
-            String description,
-            @Nullable String descriptionWithAppName,
-            Intent intent,
-            int requestCode) {
-        if (TextUtils.isEmpty(titleWithEntity) && TextUtils.isEmpty(titleWithoutEntity)) {
-            throw new IllegalArgumentException(
-                    "titleWithEntity and titleWithoutEntity should not be both null");
+  private static final String TAG = "LabeledIntent";
+  public static final int DEFAULT_REQUEST_CODE = 0;
+  private static final TitleChooser DEFAULT_TITLE_CHOOSER =
+      (labeledIntent, resolveInfo) -> {
+        if (!TextUtils.isEmpty(labeledIntent.titleWithEntity)) {
+          return labeledIntent.titleWithEntity;
         }
-        this.titleWithoutEntity = titleWithoutEntity;
-        this.titleWithEntity = titleWithEntity;
-        this.description = Preconditions.checkNotNull(description);
-        this.descriptionWithAppName = descriptionWithAppName;
-        this.intent = Preconditions.checkNotNull(intent);
-        this.requestCode = requestCode;
-    }
+        return labeledIntent.titleWithoutEntity;
+      };
 
+  @Nullable public final String titleWithoutEntity;
+  @Nullable public final String titleWithEntity;
+  public final String description;
+  @Nullable public final String descriptionWithAppName;
+  // Do not update this intent.
+  public final Intent intent;
+  public final int requestCode;
+
+  /**
+   * Initializes a LabeledIntent.
+   *
+   * <p>NOTE: {@code requestCode} is required to not be {@link #DEFAULT_REQUEST_CODE} if
+   * distinguishing info (e.g. the classified text) is represented in intent extras only. In such
+   * circumstances, the request code should represent the distinguishing info (e.g. by generating a
+   * hashcode) so that the generated PendingIntent is (somewhat) unique. To be correct, the
+   * PendingIntent should be definitely unique but we try a best effort approach that avoids
+   * spamming the system with PendingIntents.
+   */
+  // TODO: Fix the issue mentioned above so the behaviour is correct.
+  public LabeledIntent(
+      @Nullable String titleWithoutEntity,
+      @Nullable String titleWithEntity,
+      String description,
+      @Nullable String descriptionWithAppName,
+      Intent intent,
+      int requestCode) {
+    if (TextUtils.isEmpty(titleWithEntity) && TextUtils.isEmpty(titleWithoutEntity)) {
+      throw new IllegalArgumentException(
+          "titleWithEntity and titleWithoutEntity should not be both null");
+    }
+    this.titleWithoutEntity = titleWithoutEntity;
+    this.titleWithEntity = titleWithEntity;
+    this.description = Preconditions.checkNotNull(description);
+    this.descriptionWithAppName = descriptionWithAppName;
+    this.intent = Preconditions.checkNotNull(intent);
+    this.requestCode = requestCode;
+  }
+
+  /**
+   * Return the resolved result.
+   *
+   * @param context the context to resolve the result's intent and action
+   * @param titleChooser for choosing an action title
+   * @param textLanguagesBundle containing language detection information
+   */
+  @Nullable
+  public Result resolve(
+      Context context, @Nullable TitleChooser titleChooser, @Nullable Bundle textLanguagesBundle) {
+    final PackageManager pm = context.getPackageManager();
+    final ResolveInfo resolveInfo = pm.resolveActivity(intent, 0);
+
+    if (resolveInfo == null || resolveInfo.activityInfo == null) {
+      TcLog.w(TAG, "resolveInfo or activityInfo is null");
+      return null;
+    }
+    final String packageName = resolveInfo.activityInfo.packageName;
+    final String className = resolveInfo.activityInfo.name;
+    if (packageName == null || className == null) {
+      TcLog.w(TAG, "packageName or className is null");
+      return null;
+    }
+    Intent resolvedIntent = new Intent(intent);
+    resolvedIntent.putExtra(
+        TextClassifier.EXTRA_FROM_TEXT_CLASSIFIER, getFromTextClassifierExtra(textLanguagesBundle));
+    boolean shouldShowIcon = false;
+    Icon icon = null;
+    if (!"android".equals(packageName)) {
+      // We only set the component name when the package name is not resolved to "android"
+      // to workaround a bug that explicit intent with component name == ResolverActivity
+      // can't be launched on keyguard.
+      resolvedIntent.setComponent(new ComponentName(packageName, className));
+      if (resolveInfo.activityInfo.getIconResource() != 0) {
+        icon = Icon.createWithResource(packageName, resolveInfo.activityInfo.getIconResource());
+        shouldShowIcon = true;
+      }
+    }
+    if (icon == null) {
+      // RemoteAction requires that there be an icon.
+      icon = Icon.createWithResource(context, R.drawable.app_icon);
+    }
+    final PendingIntent pendingIntent = createPendingIntent(context, resolvedIntent, requestCode);
+    titleChooser = titleChooser == null ? DEFAULT_TITLE_CHOOSER : titleChooser;
+    CharSequence title = titleChooser.chooseTitle(this, resolveInfo);
+    if (TextUtils.isEmpty(title)) {
+      TcLog.w(TAG, "Custom titleChooser return null, fallback to the default titleChooser");
+      title = DEFAULT_TITLE_CHOOSER.chooseTitle(this, resolveInfo);
+    }
+    final RemoteAction action =
+        new RemoteAction(icon, title, resolveDescription(resolveInfo, pm), pendingIntent);
+    action.setShouldShowIcon(shouldShowIcon);
+    return new Result(resolvedIntent, action);
+  }
+
+  private String resolveDescription(ResolveInfo resolveInfo, PackageManager packageManager) {
+    if (!TextUtils.isEmpty(descriptionWithAppName)) {
+      // Example string format of descriptionWithAppName: "Use %1$s to open map".
+      String applicationName = getApplicationName(resolveInfo, packageManager);
+      if (!TextUtils.isEmpty(applicationName)) {
+        return String.format(descriptionWithAppName, applicationName);
+      }
+    }
+    return description;
+  }
+
+  @Nullable
+  private String getApplicationName(ResolveInfo resolveInfo, PackageManager packageManager) {
+    if (resolveInfo.activityInfo == null) {
+      return null;
+    }
+    if ("android".equals(resolveInfo.activityInfo.packageName)) {
+      return null;
+    }
+    if (resolveInfo.activityInfo.applicationInfo == null) {
+      return null;
+    }
+    return (String) packageManager.getApplicationLabel(resolveInfo.activityInfo.applicationInfo);
+  }
+
+  private Bundle getFromTextClassifierExtra(@Nullable Bundle textLanguagesBundle) {
+    if (textLanguagesBundle != null) {
+      final Bundle bundle = new Bundle();
+      ExtrasUtils.putTextLanguagesExtra(bundle, textLanguagesBundle);
+      return bundle;
+    } else {
+      return Bundle.EMPTY;
+    }
+  }
+
+  private static PendingIntent createPendingIntent(
+      final Context context, final Intent intent, int requestCode) {
+    return PendingIntent.getActivity(
+        context, requestCode, intent, PendingIntent.FLAG_UPDATE_CURRENT);
+  }
+
+  /** Data class that holds the result. */
+  public static final class Result {
+    public final Intent resolvedIntent;
+    public final RemoteAction remoteAction;
+
+    public Result(Intent resolvedIntent, RemoteAction remoteAction) {
+      this.resolvedIntent = Preconditions.checkNotNull(resolvedIntent);
+      this.remoteAction = Preconditions.checkNotNull(remoteAction);
+    }
+  }
+
+  /**
+   * An object to choose a title from resolved info. If {@code null} is returned, {@link
+   * #titleWithEntity} will be used if it exists, {@link #titleWithoutEntity} otherwise.
+   */
+  public interface TitleChooser {
     /**
-     * Return the resolved result.
-     *
-     * @param context the context to resolve the result's intent and action
-     * @param titleChooser for choosing an action title
-     * @param textLanguagesBundle containing language detection information
+     * Picks a title from a {@link LabeledIntent} by looking into resolved info. {@code resolveInfo}
+     * is guaranteed to have a non-null {@code activityInfo}.
      */
     @Nullable
-    public Result resolve(
-            Context context,
-            @Nullable TitleChooser titleChooser,
-            @Nullable Bundle textLanguagesBundle) {
-        final PackageManager pm = context.getPackageManager();
-        final ResolveInfo resolveInfo = pm.resolveActivity(intent, 0);
-
-        if (resolveInfo == null || resolveInfo.activityInfo == null) {
-            TcLog.w(TAG, "resolveInfo or activityInfo is null");
-            return null;
-        }
-        final String packageName = resolveInfo.activityInfo.packageName;
-        final String className = resolveInfo.activityInfo.name;
-        if (packageName == null || className == null) {
-            TcLog.w(TAG, "packageName or className is null");
-            return null;
-        }
-        Intent resolvedIntent = new Intent(intent);
-        resolvedIntent.putExtra(
-                TextClassifier.EXTRA_FROM_TEXT_CLASSIFIER,
-                getFromTextClassifierExtra(textLanguagesBundle));
-        boolean shouldShowIcon = false;
-        Icon icon = null;
-        if (!"android".equals(packageName)) {
-            // We only set the component name when the package name is not resolved to "android"
-            // to workaround a bug that explicit intent with component name == ResolverActivity
-            // can't be launched on keyguard.
-            resolvedIntent.setComponent(new ComponentName(packageName, className));
-            if (resolveInfo.activityInfo.getIconResource() != 0) {
-                icon =
-                        Icon.createWithResource(
-                                packageName, resolveInfo.activityInfo.getIconResource());
-                shouldShowIcon = true;
-            }
-        }
-        if (icon == null) {
-            // RemoteAction requires that there be an icon.
-            icon = Icon.createWithResource(context, R.drawable.app_icon);
-        }
-        final PendingIntent pendingIntent =
-                createPendingIntent(context, resolvedIntent, requestCode);
-        titleChooser = titleChooser == null ? DEFAULT_TITLE_CHOOSER : titleChooser;
-        CharSequence title = titleChooser.chooseTitle(this, resolveInfo);
-        if (TextUtils.isEmpty(title)) {
-            TcLog.w(TAG, "Custom titleChooser return null, fallback to the default titleChooser");
-            title = DEFAULT_TITLE_CHOOSER.chooseTitle(this, resolveInfo);
-        }
-        final RemoteAction action =
-                new RemoteAction(icon, title, resolveDescription(resolveInfo, pm), pendingIntent);
-        action.setShouldShowIcon(shouldShowIcon);
-        return new Result(resolvedIntent, action);
-    }
-
-    private String resolveDescription(ResolveInfo resolveInfo, PackageManager packageManager) {
-        if (!TextUtils.isEmpty(descriptionWithAppName)) {
-            // Example string format of descriptionWithAppName: "Use %1$s to open map".
-            String applicationName = getApplicationName(resolveInfo, packageManager);
-            if (!TextUtils.isEmpty(applicationName)) {
-                return String.format(descriptionWithAppName, applicationName);
-            }
-        }
-        return description;
-    }
-
-    @Nullable
-    private String getApplicationName(ResolveInfo resolveInfo, PackageManager packageManager) {
-        if (resolveInfo.activityInfo == null) {
-            return null;
-        }
-        if ("android".equals(resolveInfo.activityInfo.packageName)) {
-            return null;
-        }
-        if (resolveInfo.activityInfo.applicationInfo == null) {
-            return null;
-        }
-        return (String)
-                packageManager.getApplicationLabel(resolveInfo.activityInfo.applicationInfo);
-    }
-
-    private Bundle getFromTextClassifierExtra(@Nullable Bundle textLanguagesBundle) {
-        if (textLanguagesBundle != null) {
-            final Bundle bundle = new Bundle();
-            ExtrasUtils.putTextLanguagesExtra(bundle, textLanguagesBundle);
-            return bundle;
-        } else {
-            return Bundle.EMPTY;
-        }
-    }
-
-    private static PendingIntent createPendingIntent(
-            @NonNull final Context context, @NonNull final Intent intent, int requestCode) {
-        return PendingIntent.getActivity(
-                context, requestCode, intent, PendingIntent.FLAG_UPDATE_CURRENT);
-    }
-
-    /** Data class that holds the result. */
-    public static final class Result {
-        public final Intent resolvedIntent;
-        public final RemoteAction remoteAction;
-
-        public Result(Intent resolvedIntent, RemoteAction remoteAction) {
-            this.resolvedIntent = Preconditions.checkNotNull(resolvedIntent);
-            this.remoteAction = Preconditions.checkNotNull(remoteAction);
-        }
-    }
-
-    /**
-     * An object to choose a title from resolved info. If {@code null} is returned, {@link
-     * #titleWithEntity} will be used if it exists, {@link #titleWithoutEntity} otherwise.
-     */
-    public interface TitleChooser {
-        /**
-         * Picks a title from a {@link LabeledIntent} by looking into resolved info. {@code
-         * resolveInfo} is guaranteed to have a non-null {@code activityInfo}.
-         */
-        @Nullable
-        CharSequence chooseTitle(LabeledIntent labeledIntent, ResolveInfo resolveInfo);
-    }
+    CharSequence chooseTitle(LabeledIntent labeledIntent, ResolveInfo resolveInfo);
+  }
 }
diff --git a/java/src/com/android/textclassifier/intent/LegacyClassificationIntentFactory.java b/java/src/com/android/textclassifier/intent/LegacyClassificationIntentFactory.java
index 4bac39a..c58df76 100644
--- a/java/src/com/android/textclassifier/intent/LegacyClassificationIntentFactory.java
+++ b/java/src/com/android/textclassifier/intent/LegacyClassificationIntentFactory.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2018 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -13,6 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package com.android.textclassifier.intent;
 
 import static java.time.temporal.ChronoUnit.MILLIS;
@@ -28,15 +29,9 @@
 import android.provider.CalendarContract;
 import android.provider.ContactsContract;
 import android.view.textclassifier.TextClassifier;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
 import com.android.textclassifier.R;
 import com.android.textclassifier.TcLog;
-
 import com.google.android.textclassifier.AnnotatorModel;
-
 import java.io.UnsupportedEncodingException;
 import java.net.URLEncoder;
 import java.time.Instant;
@@ -44,256 +39,239 @@
 import java.util.List;
 import java.util.Locale;
 import java.util.concurrent.TimeUnit;
+import javax.annotation.Nullable;
 
-/**
- * Creates intents based on the classification type.
- *
- * @hide
- */
+/** Creates intents based on the classification type. */
 // TODO: Consider to support {@code descriptionWithAppName}.
 public final class LegacyClassificationIntentFactory implements ClassificationIntentFactory {
 
-    private static final String TAG = "LegacyClassificationIntentFactory";
-    private static final long MIN_EVENT_FUTURE_MILLIS = TimeUnit.MINUTES.toMillis(5);
-    private static final long DEFAULT_EVENT_DURATION = TimeUnit.HOURS.toMillis(1);
+  private static final String TAG = "LegacyIntentFactory";
+  private static final long MIN_EVENT_FUTURE_MILLIS = TimeUnit.MINUTES.toMillis(5);
+  private static final long DEFAULT_EVENT_DURATION = TimeUnit.HOURS.toMillis(1);
 
-    // Sync with TextClassifier.TYPE_DICTIONARY.
-    private static final String TYPE_DICTIONARY = "dictionary";
+  // Sync with TextClassifier.TYPE_DICTIONARY.
+  private static final String TYPE_DICTIONARY = "dictionary";
 
-    @NonNull
-    @Override
-    public List<LabeledIntent> create(
-            Context context,
-            String text,
-            boolean foreignText,
-            @Nullable Instant referenceTime,
-            AnnotatorModel.ClassificationResult classification) {
-        final String type =
-                classification != null
-                        ? classification.getCollection().trim().toLowerCase(Locale.ENGLISH)
-                        : "";
-        text = text.trim();
-        final List<LabeledIntent> actions;
-        switch (type) {
-            case TextClassifier.TYPE_EMAIL:
-                actions = createForEmail(context, text);
-                break;
-            case TextClassifier.TYPE_PHONE:
-                actions = createForPhone(context, text);
-                break;
-            case TextClassifier.TYPE_ADDRESS:
-                actions = createForAddress(context, text);
-                break;
-            case TextClassifier.TYPE_URL:
-                actions = createForUrl(context, text);
-                break;
-            case TextClassifier.TYPE_DATE: // fall through
-            case TextClassifier.TYPE_DATE_TIME:
-                if (classification.getDatetimeResult() != null) {
-                    final Instant parsedTime =
-                            Instant.ofEpochMilli(classification.getDatetimeResult().getTimeMsUtc());
-                    actions = createForDatetime(context, type, referenceTime, parsedTime);
-                } else {
-                    actions = new ArrayList<>();
-                }
-                break;
-            case TextClassifier.TYPE_FLIGHT_NUMBER:
-                actions = createForFlight(context, text);
-                break;
-                //            case TextClassifier.TYPE_DICTIONARY:
-            case TYPE_DICTIONARY:
-                actions = createForDictionary(context, text);
-                break;
-            default:
-                actions = new ArrayList<>();
-                break;
+  @Override
+  public List<LabeledIntent> create(
+      Context context,
+      String text,
+      boolean foreignText,
+      @Nullable Instant referenceTime,
+      AnnotatorModel.ClassificationResult classification) {
+    final String type =
+        classification != null
+            ? classification.getCollection().trim().toLowerCase(Locale.ENGLISH)
+            : "";
+    text = text.trim();
+    final List<LabeledIntent> actions;
+    switch (type) {
+      case TextClassifier.TYPE_EMAIL:
+        actions = createForEmail(context, text);
+        break;
+      case TextClassifier.TYPE_PHONE:
+        actions = createForPhone(context, text);
+        break;
+      case TextClassifier.TYPE_ADDRESS:
+        actions = createForAddress(context, text);
+        break;
+      case TextClassifier.TYPE_URL:
+        actions = createForUrl(context, text);
+        break;
+      case TextClassifier.TYPE_DATE: // fall through
+      case TextClassifier.TYPE_DATE_TIME:
+        if (classification.getDatetimeResult() != null) {
+          final Instant parsedTime =
+              Instant.ofEpochMilli(classification.getDatetimeResult().getTimeMsUtc());
+          actions = createForDatetime(context, type, referenceTime, parsedTime);
+        } else {
+          actions = new ArrayList<>();
         }
-        if (foreignText) {
-            ClassificationIntentFactory.insertTranslateAction(actions, context, text);
-        }
-        return actions;
+        break;
+      case TextClassifier.TYPE_FLIGHT_NUMBER:
+        actions = createForFlight(context, text);
+        break;
+        //            case TextClassifier.TYPE_DICTIONARY:
+      case TYPE_DICTIONARY:
+        actions = createForDictionary(context, text);
+        break;
+      default:
+        actions = new ArrayList<>();
+        break;
     }
+    if (foreignText) {
+      ClassificationIntentFactory.insertTranslateAction(actions, context, text);
+    }
+    return actions;
+  }
 
-    @NonNull
-    private static List<LabeledIntent> createForEmail(Context context, String text) {
-        final List<LabeledIntent> actions = new ArrayList<>();
-        actions.add(
-                new LabeledIntent(
-                        context.getString(R.string.email),
-                        /* titleWithEntity */ null,
-                        context.getString(R.string.email_desc),
-                        /* descriptionWithAppName */ null,
-                        new Intent(Intent.ACTION_SENDTO)
-                                .setData(Uri.parse(String.format("mailto:%s", text))),
-                        LabeledIntent.DEFAULT_REQUEST_CODE));
-        actions.add(
-                new LabeledIntent(
-                        context.getString(R.string.add_contact),
-                        /* titleWithEntity */ null,
-                        context.getString(R.string.add_contact_desc),
-                        /* descriptionWithAppName */ null,
-                        new Intent(Intent.ACTION_INSERT_OR_EDIT)
-                                .setType(ContactsContract.Contacts.CONTENT_ITEM_TYPE)
-                                .putExtra(ContactsContract.Intents.Insert.EMAIL, text),
-                        text.hashCode()));
-        return actions;
-    }
+  private static List<LabeledIntent> createForEmail(Context context, String text) {
+    final List<LabeledIntent> actions = new ArrayList<>();
+    actions.add(
+        new LabeledIntent(
+            context.getString(R.string.email),
+            /* titleWithEntity */ null,
+            context.getString(R.string.email_desc),
+            /* descriptionWithAppName */ null,
+            new Intent(Intent.ACTION_SENDTO).setData(Uri.parse(String.format("mailto:%s", text))),
+            LabeledIntent.DEFAULT_REQUEST_CODE));
+    actions.add(
+        new LabeledIntent(
+            context.getString(R.string.add_contact),
+            /* titleWithEntity */ null,
+            context.getString(R.string.add_contact_desc),
+            /* descriptionWithAppName */ null,
+            new Intent(Intent.ACTION_INSERT_OR_EDIT)
+                .setType(ContactsContract.Contacts.CONTENT_ITEM_TYPE)
+                .putExtra(ContactsContract.Intents.Insert.EMAIL, text),
+            text.hashCode()));
+    return actions;
+  }
 
-    @NonNull
-    private static List<LabeledIntent> createForPhone(Context context, String text) {
-        final List<LabeledIntent> actions = new ArrayList<>();
-        final UserManager userManager = context.getSystemService(UserManager.class);
-        final Bundle userRestrictions =
-                userManager != null ? userManager.getUserRestrictions() : new Bundle();
-        if (!userRestrictions.getBoolean(UserManager.DISALLOW_OUTGOING_CALLS, false)) {
-            actions.add(
-                    new LabeledIntent(
-                            context.getString(R.string.dial),
-                            /* titleWithEntity */ null,
-                            context.getString(R.string.dial_desc),
-                            /* descriptionWithAppName */ null,
-                            new Intent(Intent.ACTION_DIAL)
-                                    .setData(Uri.parse(String.format("tel:%s", text))),
-                            LabeledIntent.DEFAULT_REQUEST_CODE));
-        }
-        actions.add(
-                new LabeledIntent(
-                        context.getString(R.string.add_contact),
-                        /* titleWithEntity */ null,
-                        context.getString(R.string.add_contact_desc),
-                        /* descriptionWithAppName */ null,
-                        new Intent(Intent.ACTION_INSERT_OR_EDIT)
-                                .setType(ContactsContract.Contacts.CONTENT_ITEM_TYPE)
-                                .putExtra(ContactsContract.Intents.Insert.PHONE, text),
-                        text.hashCode()));
-        if (!userRestrictions.getBoolean(UserManager.DISALLOW_SMS, false)) {
-            actions.add(
-                    new LabeledIntent(
-                            context.getString(R.string.sms),
-                            /* titleWithEntity */ null,
-                            context.getString(R.string.sms_desc),
-                            /* descriptionWithAppName */ null,
-                            new Intent(Intent.ACTION_SENDTO)
-                                    .setData(Uri.parse(String.format("smsto:%s", text))),
-                            LabeledIntent.DEFAULT_REQUEST_CODE));
-        }
-        return actions;
+  private static List<LabeledIntent> createForPhone(Context context, String text) {
+    final List<LabeledIntent> actions = new ArrayList<>();
+    final UserManager userManager = context.getSystemService(UserManager.class);
+    final Bundle userRestrictions =
+        userManager != null ? userManager.getUserRestrictions() : new Bundle();
+    if (!userRestrictions.getBoolean(UserManager.DISALLOW_OUTGOING_CALLS, false)) {
+      actions.add(
+          new LabeledIntent(
+              context.getString(R.string.dial),
+              /* titleWithEntity */ null,
+              context.getString(R.string.dial_desc),
+              /* descriptionWithAppName */ null,
+              new Intent(Intent.ACTION_DIAL).setData(Uri.parse(String.format("tel:%s", text))),
+              LabeledIntent.DEFAULT_REQUEST_CODE));
     }
+    actions.add(
+        new LabeledIntent(
+            context.getString(R.string.add_contact),
+            /* titleWithEntity */ null,
+            context.getString(R.string.add_contact_desc),
+            /* descriptionWithAppName */ null,
+            new Intent(Intent.ACTION_INSERT_OR_EDIT)
+                .setType(ContactsContract.Contacts.CONTENT_ITEM_TYPE)
+                .putExtra(ContactsContract.Intents.Insert.PHONE, text),
+            text.hashCode()));
+    if (!userRestrictions.getBoolean(UserManager.DISALLOW_SMS, false)) {
+      actions.add(
+          new LabeledIntent(
+              context.getString(R.string.sms),
+              /* titleWithEntity */ null,
+              context.getString(R.string.sms_desc),
+              /* descriptionWithAppName */ null,
+              new Intent(Intent.ACTION_SENDTO).setData(Uri.parse(String.format("smsto:%s", text))),
+              LabeledIntent.DEFAULT_REQUEST_CODE));
+    }
+    return actions;
+  }
 
-    @NonNull
-    private static List<LabeledIntent> createForAddress(Context context, String text) {
-        final List<LabeledIntent> actions = new ArrayList<>();
-        try {
-            final String encText = URLEncoder.encode(text, "UTF-8");
-            actions.add(
-                    new LabeledIntent(
-                            context.getString(R.string.map),
-                            /* titleWithEntity */ null,
-                            context.getString(R.string.map_desc),
-                            /* descriptionWithAppName */ null,
-                            new Intent(Intent.ACTION_VIEW)
-                                    .setData(Uri.parse(String.format("geo:0,0?q=%s", encText))),
-                            LabeledIntent.DEFAULT_REQUEST_CODE));
-        } catch (UnsupportedEncodingException e) {
-            TcLog.e(TAG, "Could not encode address", e);
-        }
-        return actions;
+  private static List<LabeledIntent> createForAddress(Context context, String text) {
+    final List<LabeledIntent> actions = new ArrayList<>();
+    try {
+      final String encText = URLEncoder.encode(text, "UTF-8");
+      actions.add(
+          new LabeledIntent(
+              context.getString(R.string.map),
+              /* titleWithEntity */ null,
+              context.getString(R.string.map_desc),
+              /* descriptionWithAppName */ null,
+              new Intent(Intent.ACTION_VIEW)
+                  .setData(Uri.parse(String.format("geo:0,0?q=%s", encText))),
+              LabeledIntent.DEFAULT_REQUEST_CODE));
+    } catch (UnsupportedEncodingException e) {
+      TcLog.e(TAG, "Could not encode address", e);
     }
+    return actions;
+  }
 
-    @NonNull
-    private static List<LabeledIntent> createForUrl(Context context, String text) {
-        if (Uri.parse(text).getScheme() == null) {
-            text = "http://" + text;
-        }
-        final List<LabeledIntent> actions = new ArrayList<>();
-        actions.add(
-                new LabeledIntent(
-                        context.getString(R.string.browse),
-                        /* titleWithEntity */ null,
-                        context.getString(R.string.browse_desc),
-                        /* descriptionWithAppName */ null,
-                        new Intent(Intent.ACTION_VIEW)
-                                .setDataAndNormalize(Uri.parse(text))
-                                .putExtra(Browser.EXTRA_APPLICATION_ID, context.getPackageName()),
-                        LabeledIntent.DEFAULT_REQUEST_CODE));
-        return actions;
+  private static List<LabeledIntent> createForUrl(Context context, String text) {
+    if (Uri.parse(text).getScheme() == null) {
+      text = "http://" + text;
     }
+    final List<LabeledIntent> actions = new ArrayList<>();
+    actions.add(
+        new LabeledIntent(
+            context.getString(R.string.browse),
+            /* titleWithEntity */ null,
+            context.getString(R.string.browse_desc),
+            /* descriptionWithAppName */ null,
+            new Intent(Intent.ACTION_VIEW)
+                .setDataAndNormalize(Uri.parse(text))
+                .putExtra(Browser.EXTRA_APPLICATION_ID, context.getPackageName()),
+            LabeledIntent.DEFAULT_REQUEST_CODE));
+    return actions;
+  }
 
-    @NonNull
-    private static List<LabeledIntent> createForDatetime(
-            Context context, String type, @Nullable Instant referenceTime, Instant parsedTime) {
-        if (referenceTime == null) {
-            // If no reference time was given, use now.
-            referenceTime = Instant.now();
-        }
-        List<LabeledIntent> actions = new ArrayList<>();
-        actions.add(createCalendarViewIntent(context, parsedTime));
-        final long millisUntilEvent = referenceTime.until(parsedTime, MILLIS);
-        if (millisUntilEvent > MIN_EVENT_FUTURE_MILLIS) {
-            actions.add(createCalendarCreateEventIntent(context, parsedTime, type));
-        }
-        return actions;
+  private static List<LabeledIntent> createForDatetime(
+      Context context, String type, @Nullable Instant referenceTime, Instant parsedTime) {
+    if (referenceTime == null) {
+      // If no reference time was given, use now.
+      referenceTime = Instant.now();
     }
+    List<LabeledIntent> actions = new ArrayList<>();
+    actions.add(createCalendarViewIntent(context, parsedTime));
+    final long millisUntilEvent = referenceTime.until(parsedTime, MILLIS);
+    if (millisUntilEvent > MIN_EVENT_FUTURE_MILLIS) {
+      actions.add(createCalendarCreateEventIntent(context, parsedTime, type));
+    }
+    return actions;
+  }
 
-    @NonNull
-    private static List<LabeledIntent> createForFlight(Context context, String text) {
-        final List<LabeledIntent> actions = new ArrayList<>();
-        actions.add(
-                new LabeledIntent(
-                        context.getString(R.string.view_flight),
-                        /* titleWithEntity */ null,
-                        context.getString(R.string.view_flight_desc),
-                        /* descriptionWithAppName */ null,
-                        new Intent(Intent.ACTION_WEB_SEARCH).putExtra(SearchManager.QUERY, text),
-                        text.hashCode()));
-        return actions;
-    }
+  private static List<LabeledIntent> createForFlight(Context context, String text) {
+    final List<LabeledIntent> actions = new ArrayList<>();
+    actions.add(
+        new LabeledIntent(
+            context.getString(R.string.view_flight),
+            /* titleWithEntity */ null,
+            context.getString(R.string.view_flight_desc),
+            /* descriptionWithAppName */ null,
+            new Intent(Intent.ACTION_WEB_SEARCH).putExtra(SearchManager.QUERY, text),
+            text.hashCode()));
+    return actions;
+  }
 
-    @NonNull
-    private static LabeledIntent createCalendarViewIntent(Context context, Instant parsedTime) {
-        Uri.Builder builder = CalendarContract.CONTENT_URI.buildUpon();
-        builder.appendPath("time");
-        ContentUris.appendId(builder, parsedTime.toEpochMilli());
-        return new LabeledIntent(
-                context.getString(R.string.view_calendar),
-                /* titleWithEntity */ null,
-                context.getString(R.string.view_calendar_desc),
-                /* descriptionWithAppName */ null,
-                new Intent(Intent.ACTION_VIEW).setData(builder.build()),
-                LabeledIntent.DEFAULT_REQUEST_CODE);
-    }
+  private static LabeledIntent createCalendarViewIntent(Context context, Instant parsedTime) {
+    Uri.Builder builder = CalendarContract.CONTENT_URI.buildUpon();
+    builder.appendPath("time");
+    ContentUris.appendId(builder, parsedTime.toEpochMilli());
+    return new LabeledIntent(
+        context.getString(R.string.view_calendar),
+        /* titleWithEntity */ null,
+        context.getString(R.string.view_calendar_desc),
+        /* descriptionWithAppName */ null,
+        new Intent(Intent.ACTION_VIEW).setData(builder.build()),
+        LabeledIntent.DEFAULT_REQUEST_CODE);
+  }
 
-    @NonNull
-    private static LabeledIntent createCalendarCreateEventIntent(
-            Context context, Instant parsedTime, String type) {
-        final boolean isAllDay = TextClassifier.TYPE_DATE.equals(type);
-        return new LabeledIntent(
-                context.getString(R.string.add_calendar_event),
-                /* titleWithEntity */ null,
-                context.getString(R.string.add_calendar_event_desc),
-                /* descriptionWithAppName */ null,
-                new Intent(Intent.ACTION_INSERT)
-                        .setData(CalendarContract.Events.CONTENT_URI)
-                        .putExtra(CalendarContract.EXTRA_EVENT_ALL_DAY, isAllDay)
-                        .putExtra(
-                                CalendarContract.EXTRA_EVENT_BEGIN_TIME, parsedTime.toEpochMilli())
-                        .putExtra(
-                                CalendarContract.EXTRA_EVENT_END_TIME,
-                                parsedTime.toEpochMilli() + DEFAULT_EVENT_DURATION),
-                parsedTime.hashCode());
-    }
+  private static LabeledIntent createCalendarCreateEventIntent(
+      Context context, Instant parsedTime, String type) {
+    final boolean isAllDay = TextClassifier.TYPE_DATE.equals(type);
+    return new LabeledIntent(
+        context.getString(R.string.add_calendar_event),
+        /* titleWithEntity */ null,
+        context.getString(R.string.add_calendar_event_desc),
+        /* descriptionWithAppName */ null,
+        new Intent(Intent.ACTION_INSERT)
+            .setData(CalendarContract.Events.CONTENT_URI)
+            .putExtra(CalendarContract.EXTRA_EVENT_ALL_DAY, isAllDay)
+            .putExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, parsedTime.toEpochMilli())
+            .putExtra(
+                CalendarContract.EXTRA_EVENT_END_TIME,
+                parsedTime.toEpochMilli() + DEFAULT_EVENT_DURATION),
+        parsedTime.hashCode());
+  }
 
-    @NonNull
-    private static List<LabeledIntent> createForDictionary(Context context, String text) {
-        final List<LabeledIntent> actions = new ArrayList<>();
-        actions.add(
-                new LabeledIntent(
-                        context.getString(R.string.define),
-                        /* titleWithEntity */ null,
-                        context.getString(R.string.define_desc),
-                        /* descriptionWithAppName */ null,
-                        new Intent(Intent.ACTION_DEFINE).putExtra(Intent.EXTRA_TEXT, text),
-                        text.hashCode()));
-        return actions;
-    }
+  private static List<LabeledIntent> createForDictionary(Context context, String text) {
+    final List<LabeledIntent> actions = new ArrayList<>();
+    actions.add(
+        new LabeledIntent(
+            context.getString(R.string.define),
+            /* titleWithEntity */ null,
+            context.getString(R.string.define_desc),
+            /* descriptionWithAppName */ null,
+            new Intent(Intent.ACTION_DEFINE).putExtra(Intent.EXTRA_TEXT, text),
+            text.hashCode()));
+    return actions;
+  }
 }
diff --git a/java/src/com/android/textclassifier/intent/TemplateClassificationIntentFactory.java b/java/src/com/android/textclassifier/intent/TemplateClassificationIntentFactory.java
index 53f5bf4..f5ef577 100644
--- a/java/src/com/android/textclassifier/intent/TemplateClassificationIntentFactory.java
+++ b/java/src/com/android/textclassifier/intent/TemplateClassificationIntentFactory.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2018 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -13,69 +13,60 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package com.android.textclassifier.intent;
 
 import android.content.Context;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.annotation.VisibleForTesting;
-import androidx.core.util.Preconditions;
-
 import com.android.textclassifier.TcLog;
-
 import com.google.android.textclassifier.AnnotatorModel;
 import com.google.android.textclassifier.RemoteActionTemplate;
-
+import com.google.common.base.Preconditions;
 import java.time.Instant;
 import java.util.Collections;
 import java.util.List;
+import javax.annotation.Nullable;
 
 /**
  * Creates intents based on {@link RemoteActionTemplate} objects for a ClassificationResult.
  *
  * @hide
  */
-@VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE)
 public final class TemplateClassificationIntentFactory implements ClassificationIntentFactory {
-    private static final String TAG = "TemplateClassificationIntentFactory";
-    private final TemplateIntentFactory mTemplateIntentFactory;
-    private final ClassificationIntentFactory mFallback;
+  private static final String TAG = "TemplateIntentFactory";
+  private final TemplateIntentFactory templateIntentFactory;
+  private final ClassificationIntentFactory fallback;
 
-    public TemplateClassificationIntentFactory(
-            TemplateIntentFactory templateIntentFactory, ClassificationIntentFactory fallback) {
-        mTemplateIntentFactory = Preconditions.checkNotNull(templateIntentFactory);
-        mFallback = Preconditions.checkNotNull(fallback);
-    }
+  public TemplateClassificationIntentFactory(
+      TemplateIntentFactory templateIntentFactory, ClassificationIntentFactory fallback) {
+    this.templateIntentFactory = Preconditions.checkNotNull(templateIntentFactory);
+    this.fallback = Preconditions.checkNotNull(fallback);
+  }
 
-    /**
-     * Returns a list of {@link LabeledIntent} that are constructed from the classification result.
-     */
-    @NonNull
-    @Override
-    public List<LabeledIntent> create(
-            Context context,
-            String text,
-            boolean foreignText,
-            @Nullable Instant referenceTime,
-            @Nullable AnnotatorModel.ClassificationResult classification) {
-        if (classification == null) {
-            return Collections.emptyList();
-        }
-        RemoteActionTemplate[] remoteActionTemplates = classification.getRemoteActionTemplates();
-        if (remoteActionTemplates == null) {
-            // RemoteActionTemplate is missing, fallback.
-            TcLog.w(
-                    TAG,
-                    "RemoteActionTemplate is missing, fallback to"
-                            + " LegacyClassificationIntentFactory.");
-            return mFallback.create(context, text, foreignText, referenceTime, classification);
-        }
-        final List<LabeledIntent> labeledIntents =
-                mTemplateIntentFactory.create(remoteActionTemplates);
-        if (foreignText) {
-            ClassificationIntentFactory.insertTranslateAction(labeledIntents, context, text.trim());
-        }
-        return labeledIntents;
+  /**
+   * Returns a list of {@link LabeledIntent} that are constructed from the classification result.
+   */
+  @Override
+  public List<LabeledIntent> create(
+      Context context,
+      String text,
+      boolean foreignText,
+      @Nullable Instant referenceTime,
+      @Nullable AnnotatorModel.ClassificationResult classification) {
+    if (classification == null) {
+      return Collections.emptyList();
     }
+    RemoteActionTemplate[] remoteActionTemplates = classification.getRemoteActionTemplates();
+    if (remoteActionTemplates == null) {
+      // RemoteActionTemplate is missing, fallback.
+      TcLog.w(
+          TAG,
+          "RemoteActionTemplate is missing, fallback to" + " LegacyClassificationIntentFactory.");
+      return fallback.create(context, text, foreignText, referenceTime, classification);
+    }
+    final List<LabeledIntent> labeledIntents = templateIntentFactory.create(remoteActionTemplates);
+    if (foreignText) {
+      ClassificationIntentFactory.insertTranslateAction(labeledIntents, context, text.trim());
+    }
+    return labeledIntents;
+  }
 }
diff --git a/java/src/com/android/textclassifier/intent/TemplateIntentFactory.java b/java/src/com/android/textclassifier/intent/TemplateIntentFactory.java
index 57f608a..718c988 100644
--- a/java/src/com/android/textclassifier/intent/TemplateIntentFactory.java
+++ b/java/src/com/android/textclassifier/intent/TemplateIntentFactory.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2018 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -13,144 +13,136 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package com.android.textclassifier.intent;
 
 import android.content.Intent;
 import android.net.Uri;
 import android.os.Bundle;
 import android.text.TextUtils;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.annotation.VisibleForTesting;
-
 import com.android.textclassifier.TcLog;
-
 import com.google.android.textclassifier.NamedVariant;
 import com.google.android.textclassifier.RemoteActionTemplate;
-
 import java.util.ArrayList;
 import java.util.List;
+import javax.annotation.Nullable;
 
 /**
  * Creates intents based on {@link RemoteActionTemplate} objects.
  *
  * @hide
  */
-@VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE)
 public final class TemplateIntentFactory {
-    private static final String TAG = "TemplateIntentFactory";
+  private static final String TAG = "TemplateIntentFactory";
 
-    /** Constructs and returns a list of {@link LabeledIntent} based on the given templates. */
-    @Nullable
-    public List<LabeledIntent> create(@NonNull RemoteActionTemplate[] remoteActionTemplates) {
-        if (remoteActionTemplates.length == 0) {
-            return new ArrayList<>();
-        }
-        final List<LabeledIntent> labeledIntents = new ArrayList<>();
-        for (RemoteActionTemplate remoteActionTemplate : remoteActionTemplates) {
-            if (!isValidTemplate(remoteActionTemplate)) {
-                TcLog.w(TAG, "Invalid RemoteActionTemplate skipped.");
-                continue;
-            }
-            labeledIntents.add(
-                    new LabeledIntent(
-                            remoteActionTemplate.titleWithoutEntity,
-                            remoteActionTemplate.titleWithEntity,
-                            remoteActionTemplate.description,
-                            remoteActionTemplate.descriptionWithAppName,
-                            createIntent(remoteActionTemplate),
-                            remoteActionTemplate.requestCode == null
-                                    ? LabeledIntent.DEFAULT_REQUEST_CODE
-                                    : remoteActionTemplate.requestCode));
-        }
-        return labeledIntents;
+  /** Constructs and returns a list of {@link LabeledIntent} based on the given templates. */
+  @Nullable
+  public List<LabeledIntent> create(RemoteActionTemplate[] remoteActionTemplates) {
+    if (remoteActionTemplates.length == 0) {
+      return new ArrayList<>();
     }
+    final List<LabeledIntent> labeledIntents = new ArrayList<>();
+    for (RemoteActionTemplate remoteActionTemplate : remoteActionTemplates) {
+      if (!isValidTemplate(remoteActionTemplate)) {
+        TcLog.w(TAG, "Invalid RemoteActionTemplate skipped.");
+        continue;
+      }
+      labeledIntents.add(
+          new LabeledIntent(
+              remoteActionTemplate.titleWithoutEntity,
+              remoteActionTemplate.titleWithEntity,
+              remoteActionTemplate.description,
+              remoteActionTemplate.descriptionWithAppName,
+              createIntent(remoteActionTemplate),
+              remoteActionTemplate.requestCode == null
+                  ? LabeledIntent.DEFAULT_REQUEST_CODE
+                  : remoteActionTemplate.requestCode));
+    }
+    return labeledIntents;
+  }
 
-    private static boolean isValidTemplate(@Nullable RemoteActionTemplate remoteActionTemplate) {
-        if (remoteActionTemplate == null) {
-            TcLog.w(TAG, "Invalid RemoteActionTemplate: is null");
-            return false;
-        }
-        if (TextUtils.isEmpty(remoteActionTemplate.titleWithEntity)
-                && TextUtils.isEmpty(remoteActionTemplate.titleWithoutEntity)) {
-            TcLog.w(TAG, "Invalid RemoteActionTemplate: title is null");
-            return false;
-        }
-        if (TextUtils.isEmpty(remoteActionTemplate.description)) {
-            TcLog.w(TAG, "Invalid RemoteActionTemplate: description is null");
-            return false;
-        }
-        if (!TextUtils.isEmpty(remoteActionTemplate.packageName)) {
-            TcLog.w(TAG, "Invalid RemoteActionTemplate: package name is set");
-            return false;
-        }
-        if (TextUtils.isEmpty(remoteActionTemplate.action)) {
-            TcLog.w(TAG, "Invalid RemoteActionTemplate: intent action not set");
-            return false;
-        }
-        return true;
+  private static boolean isValidTemplate(@Nullable RemoteActionTemplate remoteActionTemplate) {
+    if (remoteActionTemplate == null) {
+      TcLog.w(TAG, "Invalid RemoteActionTemplate: is null");
+      return false;
     }
+    if (TextUtils.isEmpty(remoteActionTemplate.titleWithEntity)
+        && TextUtils.isEmpty(remoteActionTemplate.titleWithoutEntity)) {
+      TcLog.w(TAG, "Invalid RemoteActionTemplate: title is null");
+      return false;
+    }
+    if (TextUtils.isEmpty(remoteActionTemplate.description)) {
+      TcLog.w(TAG, "Invalid RemoteActionTemplate: description is null");
+      return false;
+    }
+    if (!TextUtils.isEmpty(remoteActionTemplate.packageName)) {
+      TcLog.w(TAG, "Invalid RemoteActionTemplate: package name is set");
+      return false;
+    }
+    if (TextUtils.isEmpty(remoteActionTemplate.action)) {
+      TcLog.w(TAG, "Invalid RemoteActionTemplate: intent action not set");
+      return false;
+    }
+    return true;
+  }
 
-    private static Intent createIntent(RemoteActionTemplate remoteActionTemplate) {
-        final Intent intent = new Intent(remoteActionTemplate.action);
-        final Uri uri =
-                TextUtils.isEmpty(remoteActionTemplate.data)
-                        ? null
-                        : Uri.parse(remoteActionTemplate.data).normalizeScheme();
-        final String type =
-                TextUtils.isEmpty(remoteActionTemplate.type)
-                        ? null
-                        : Intent.normalizeMimeType(remoteActionTemplate.type);
-        intent.setDataAndType(uri, type);
-        intent.setFlags(remoteActionTemplate.flags == null ? 0 : remoteActionTemplate.flags);
-        if (remoteActionTemplate.category != null) {
-            for (String category : remoteActionTemplate.category) {
-                if (category != null) {
-                    intent.addCategory(category);
-                }
-            }
+  private static Intent createIntent(RemoteActionTemplate remoteActionTemplate) {
+    final Intent intent = new Intent(remoteActionTemplate.action);
+    final Uri uri =
+        TextUtils.isEmpty(remoteActionTemplate.data)
+            ? null
+            : Uri.parse(remoteActionTemplate.data).normalizeScheme();
+    final String type =
+        TextUtils.isEmpty(remoteActionTemplate.type)
+            ? null
+            : Intent.normalizeMimeType(remoteActionTemplate.type);
+    intent.setDataAndType(uri, type);
+    intent.setFlags(remoteActionTemplate.flags == null ? 0 : remoteActionTemplate.flags);
+    if (remoteActionTemplate.category != null) {
+      for (String category : remoteActionTemplate.category) {
+        if (category != null) {
+          intent.addCategory(category);
         }
-        intent.putExtras(nameVariantsToBundle(remoteActionTemplate.extras));
-        return intent;
+      }
     }
+    intent.putExtras(nameVariantsToBundle(remoteActionTemplate.extras));
+    return intent;
+  }
 
-    /** Converts an array of {@link NamedVariant} to a Bundle and returns it. */
-    public static Bundle nameVariantsToBundle(@Nullable NamedVariant[] namedVariants) {
-        if (namedVariants == null) {
-            return Bundle.EMPTY;
-        }
-        Bundle bundle = new Bundle();
-        for (NamedVariant namedVariant : namedVariants) {
-            if (namedVariant == null) {
-                continue;
-            }
-            switch (namedVariant.getType()) {
-                case NamedVariant.TYPE_INT:
-                    bundle.putInt(namedVariant.getName(), namedVariant.getInt());
-                    break;
-                case NamedVariant.TYPE_LONG:
-                    bundle.putLong(namedVariant.getName(), namedVariant.getLong());
-                    break;
-                case NamedVariant.TYPE_FLOAT:
-                    bundle.putFloat(namedVariant.getName(), namedVariant.getFloat());
-                    break;
-                case NamedVariant.TYPE_DOUBLE:
-                    bundle.putDouble(namedVariant.getName(), namedVariant.getDouble());
-                    break;
-                case NamedVariant.TYPE_BOOL:
-                    bundle.putBoolean(namedVariant.getName(), namedVariant.getBool());
-                    break;
-                case NamedVariant.TYPE_STRING:
-                    bundle.putString(namedVariant.getName(), namedVariant.getString());
-                    break;
-                default:
-                    TcLog.w(
-                            TAG,
-                            "Unsupported type found in nameVariantsToBundle : "
-                                    + namedVariant.getType());
-            }
-        }
-        return bundle;
+  /** Converts an array of {@link NamedVariant} to a Bundle and returns it. */
+  public static Bundle nameVariantsToBundle(@Nullable NamedVariant[] namedVariants) {
+    if (namedVariants == null) {
+      return Bundle.EMPTY;
     }
+    Bundle bundle = new Bundle();
+    for (NamedVariant namedVariant : namedVariants) {
+      if (namedVariant == null) {
+        continue;
+      }
+      switch (namedVariant.getType()) {
+        case NamedVariant.TYPE_INT:
+          bundle.putInt(namedVariant.getName(), namedVariant.getInt());
+          break;
+        case NamedVariant.TYPE_LONG:
+          bundle.putLong(namedVariant.getName(), namedVariant.getLong());
+          break;
+        case NamedVariant.TYPE_FLOAT:
+          bundle.putFloat(namedVariant.getName(), namedVariant.getFloat());
+          break;
+        case NamedVariant.TYPE_DOUBLE:
+          bundle.putDouble(namedVariant.getName(), namedVariant.getDouble());
+          break;
+        case NamedVariant.TYPE_BOOL:
+          bundle.putBoolean(namedVariant.getName(), namedVariant.getBool());
+          break;
+        case NamedVariant.TYPE_STRING:
+          bundle.putString(namedVariant.getName(), namedVariant.getString());
+          break;
+        default:
+          TcLog.w(
+              TAG, "Unsupported type found in nameVariantsToBundle : " + namedVariant.getType());
+      }
+    }
+    return bundle;
+  }
 }
diff --git a/java/src/com/android/textclassifier/logging/GenerateLinksLogger.java b/java/src/com/android/textclassifier/logging/GenerateLinksLogger.java
index d06104c..5da8e93 100644
--- a/java/src/com/android/textclassifier/logging/GenerateLinksLogger.java
+++ b/java/src/com/android/textclassifier/logging/GenerateLinksLogger.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 The Android Open Source Project
+ * Copyright (C) 2018 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -19,128 +19,126 @@
 import android.view.textclassifier.TextClassifier;
 import android.view.textclassifier.TextClassifierEvent;
 import android.view.textclassifier.TextLinks;
-
-import androidx.annotation.Nullable;
 import androidx.collection.ArrayMap;
-import androidx.core.util.Preconditions;
-
 import com.android.textclassifier.TcLog;
 import com.android.textclassifier.TextClassifierStatsLog;
-
+import com.google.common.base.Preconditions;
 import java.util.Locale;
 import java.util.Map;
 import java.util.Random;
 import java.util.UUID;
+import javax.annotation.Nullable;
 
 /** A helper for logging calls to generateLinks. */
 public final class GenerateLinksLogger {
 
-    private static final String LOG_TAG = "GenerateLinksLogger";
+  private static final String LOG_TAG = "GenerateLinksLogger";
 
-    private final Random mRng;
-    private final int mSampleRate;
+  private final Random rng;
+  private final int sampleRate;
 
-    /**
-     * @param sampleRate the rate at which log events are written. (e.g. 100 means there is a 0.01
-     *     chance that a call to logGenerateLinks results in an event being written). To write all
-     *     events, pass 1.
-     */
-    public GenerateLinksLogger(int sampleRate) {
-        mSampleRate = sampleRate;
-        mRng = new Random();
+  /**
+   * @param sampleRate the rate at which log events are written. (e.g. 100 means there is a 0.01
+   *     chance that a call to logGenerateLinks results in an event being written). To write all
+   *     events, pass 1.
+   */
+  public GenerateLinksLogger(int sampleRate) {
+    this.sampleRate = sampleRate;
+    rng = new Random();
+  }
+
+  /** Logs statistics about a call to generateLinks. */
+  public void logGenerateLinks(
+      CharSequence text, TextLinks links, String callingPackageName, long latencyMs) {
+    Preconditions.checkNotNull(text);
+    Preconditions.checkNotNull(links);
+    Preconditions.checkNotNull(callingPackageName);
+    if (!shouldLog()) {
+      return;
     }
 
-    /** Logs statistics about a call to generateLinks. */
-    public void logGenerateLinks(
-            CharSequence text, TextLinks links, String callingPackageName, long latencyMs) {
-        Preconditions.checkNotNull(text);
-        Preconditions.checkNotNull(links);
-        Preconditions.checkNotNull(callingPackageName);
-        if (!shouldLog()) {
-            return;
-        }
-
-        // Always populate the total stats, and per-entity stats for each entity type detected.
-        final LinkifyStats totalStats = new LinkifyStats();
-        final Map<String, LinkifyStats> perEntityTypeStats = new ArrayMap<>();
-        for (TextLinks.TextLink link : links.getLinks()) {
-            if (link.getEntityCount() == 0) continue;
-            final String entityType = link.getEntity(0);
-            if (entityType == null
-                    || TextClassifier.TYPE_OTHER.equals(entityType)
-                    || TextClassifier.TYPE_UNKNOWN.equals(entityType)) {
-                continue;
-            }
-            totalStats.countLink(link);
-            perEntityTypeStats.computeIfAbsent(entityType, k -> new LinkifyStats()).countLink(link);
-        }
-
-        final String callId = UUID.randomUUID().toString();
-        writeStats(callId, callingPackageName, null, totalStats, text, latencyMs);
-        for (Map.Entry<String, LinkifyStats> entry : perEntityTypeStats.entrySet()) {
-            writeStats(
-                    callId, callingPackageName, entry.getKey(), entry.getValue(), text, latencyMs);
-        }
+    // Always populate the total stats, and per-entity stats for each entity type detected.
+    final LinkifyStats totalStats = new LinkifyStats();
+    final Map<String, LinkifyStats> perEntityTypeStats = new ArrayMap<>();
+    for (TextLinks.TextLink link : links.getLinks()) {
+      if (link.getEntityCount() == 0) {
+        continue;
+      }
+      final String entityType = link.getEntity(0);
+      if (entityType == null
+          || TextClassifier.TYPE_OTHER.equals(entityType)
+          || TextClassifier.TYPE_UNKNOWN.equals(entityType)) {
+        continue;
+      }
+      totalStats.countLink(link);
+      perEntityTypeStats.computeIfAbsent(entityType, k -> new LinkifyStats()).countLink(link);
     }
 
-    /**
-     * Returns whether this particular event should be logged.
-     *
-     * <p>Sampling is used to reduce the amount of logging data generated.
-     */
-    private boolean shouldLog() {
-        if (mSampleRate <= 1) {
-            return true;
-        } else {
-            return mRng.nextInt(mSampleRate) == 0;
-        }
+    final String callId = UUID.randomUUID().toString();
+    writeStats(callId, callingPackageName, null, totalStats, text, latencyMs);
+    for (Map.Entry<String, LinkifyStats> entry : perEntityTypeStats.entrySet()) {
+      writeStats(callId, callingPackageName, entry.getKey(), entry.getValue(), text, latencyMs);
     }
+  }
 
-    /** Writes a log event for the given stats. */
-    private void writeStats(
-            String callId,
-            String callingPackageName,
-            @Nullable String entityType,
-            LinkifyStats stats,
-            CharSequence text,
-            long latencyMs) {
-        TextClassifierStatsLog.write(
-                TextClassifierStatsLog.TEXT_LINKIFY_EVENT,
-                callId,
-                TextClassifierEvent.TYPE_LINKS_GENERATED,
-                /*modelName=*/ null,
-                TextClassifierEventLogger.WidgetType.WIDGET_TYPE_UNKNOWN,
-                /*eventIndex=*/ 0,
-                entityType,
-                stats.mNumLinks,
-                stats.mNumLinksTextLength,
-                text.length(),
-                latencyMs,
-                callingPackageName);
-        if (TcLog.ENABLE_FULL_LOGGING) {
-            TcLog.v(
-                    LOG_TAG,
-                    String.format(
-                            Locale.US,
-                            "%s:%s %d links (%d/%d chars) %dms %s",
-                            callId,
-                            entityType,
-                            stats.mNumLinks,
-                            stats.mNumLinksTextLength,
-                            text.length(),
-                            latencyMs,
-                            callingPackageName));
-        }
+  /**
+   * Returns whether this particular event should be logged.
+   *
+   * <p>Sampling is used to reduce the amount of logging data generated.
+   */
+  private boolean shouldLog() {
+    if (sampleRate <= 1) {
+      return true;
+    } else {
+      return rng.nextInt(sampleRate) == 0;
     }
+  }
 
-    /** Helper class for storing per-entity type statistics. */
-    private static final class LinkifyStats {
-        int mNumLinks;
-        int mNumLinksTextLength;
-
-        void countLink(TextLinks.TextLink link) {
-            mNumLinks += 1;
-            mNumLinksTextLength += link.getEnd() - link.getStart();
-        }
+  /** Writes a log event for the given stats. */
+  private static void writeStats(
+      String callId,
+      String callingPackageName,
+      @Nullable String entityType,
+      LinkifyStats stats,
+      CharSequence text,
+      long latencyMs) {
+    TextClassifierStatsLog.write(
+        TextClassifierStatsLog.TEXT_LINKIFY_EVENT,
+        callId,
+        TextClassifierEvent.TYPE_LINKS_GENERATED,
+        /*modelName=*/ null,
+        TextClassifierEventLogger.WidgetType.WIDGET_TYPE_UNKNOWN,
+        /*eventIndex=*/ 0,
+        entityType,
+        stats.numLinks,
+        stats.numLinksTextLength,
+        text.length(),
+        latencyMs,
+        callingPackageName);
+    if (TcLog.ENABLE_FULL_LOGGING) {
+      TcLog.v(
+          LOG_TAG,
+          String.format(
+              Locale.US,
+              "%s:%s %d links (%d/%d chars) %dms %s",
+              callId,
+              entityType,
+              stats.numLinks,
+              stats.numLinksTextLength,
+              text.length(),
+              latencyMs,
+              callingPackageName));
     }
+  }
+
+  /** Helper class for storing per-entity type statistics. */
+  private static final class LinkifyStats {
+    int numLinks;
+    int numLinksTextLength;
+
+    void countLink(TextLinks.TextLink link) {
+      numLinks += 1;
+      numLinksTextLength += link.getEnd() - link.getStart();
+    }
+  }
 }
diff --git a/java/src/com/android/textclassifier/logging/ResultIdUtils.java b/java/src/com/android/textclassifier/logging/ResultIdUtils.java
index de21959..c0f8b2a 100644
--- a/java/src/com/android/textclassifier/logging/ResultIdUtils.java
+++ b/java/src/com/android/textclassifier/logging/ResultIdUtils.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2018 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -13,59 +13,59 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package com.android.textclassifier.logging;
 //
 
 import android.content.Context;
-
-import androidx.annotation.Nullable;
-import androidx.core.util.Preconditions;
-
+import com.google.common.base.Preconditions;
 import java.util.List;
 import java.util.Locale;
 import java.util.Objects;
 import java.util.StringJoiner;
+import javax.annotation.Nullable;
 
 /** Provide utils to generate and parse the result id. */
 public final class ResultIdUtils {
-    private static final String LOG_TAG = "ResultIdUtils";
-    private static final String CLASSIFIER_ID = "androidtc";
+  private static final String CLASSIFIER_ID = "androidtc";
 
-    /** Creates a string id that may be used to identify a TextClassifier result. */
-    public static String createId(
-            Context context,
-            String text,
-            int start,
-            int end,
-            int modelVersion,
-            List<Locale> modelLocales) {
-        Preconditions.checkNotNull(text);
-        Preconditions.checkNotNull(context);
-        Preconditions.checkNotNull(modelLocales);
-        final int hash = Objects.hash(text, start, end, context.getPackageName());
-        return createId(modelVersion, modelLocales, hash);
-    }
+  /** Creates a string id that may be used to identify a TextClassifier result. */
+  public static String createId(
+      Context context,
+      String text,
+      int start,
+      int end,
+      int modelVersion,
+      List<Locale> modelLocales) {
+    Preconditions.checkNotNull(text);
+    Preconditions.checkNotNull(context);
+    Preconditions.checkNotNull(modelLocales);
+    final int hash = Objects.hash(text, start, end, context.getPackageName());
+    return createId(modelVersion, modelLocales, hash);
+  }
 
-    /** Creates a string id that may be used to identify a TextClassifier result. */
-    public static String createId(int modelVersion, List<Locale> modelLocales, int hash) {
-        final StringJoiner localesJoiner = new StringJoiner(",");
-        for (Locale locale : modelLocales) {
-            localesJoiner.add(locale.toLanguageTag());
-        }
-        final String modelName =
-                String.format(Locale.US, "%s_v%d", localesJoiner.toString(), modelVersion);
-        return String.format(Locale.US, "%s|%s|%d", CLASSIFIER_ID, modelName, hash);
+  /** Creates a string id that may be used to identify a TextClassifier result. */
+  public static String createId(int modelVersion, List<Locale> modelLocales, int hash) {
+    final StringJoiner localesJoiner = new StringJoiner(",");
+    for (Locale locale : modelLocales) {
+      localesJoiner.add(locale.toLanguageTag());
     }
+    final String modelName =
+        String.format(Locale.US, "%s_v%d", localesJoiner.toString(), modelVersion);
+    return String.format(Locale.US, "%s|%s|%d", CLASSIFIER_ID, modelName, hash);
+  }
 
-    static String getModelName(@Nullable String signature) {
-        if (signature == null) {
-            return "";
-        }
-        final int start = signature.indexOf("|") + 1;
-        final int end = signature.indexOf("|", start);
-        if (start >= 1 && end >= start) {
-            return signature.substring(start, end);
-        }
-        return "";
+  static String getModelName(@Nullable String signature) {
+    if (signature == null) {
+      return "";
     }
+    final int start = signature.indexOf("|") + 1;
+    final int end = signature.indexOf("|", start);
+    if (start >= 1 && end >= start) {
+      return signature.substring(start, end);
+    }
+    return "";
+  }
+
+  private ResultIdUtils() {}
 }
diff --git a/java/src/com/android/textclassifier/logging/SelectionEventConverter.java b/java/src/com/android/textclassifier/logging/SelectionEventConverter.java
index 2d492a9..05fdf9f 100644
--- a/java/src/com/android/textclassifier/logging/SelectionEventConverter.java
+++ b/java/src/com/android/textclassifier/logging/SelectionEventConverter.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2018 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -19,84 +19,85 @@
 import android.view.textclassifier.SelectionEvent;
 import android.view.textclassifier.TextClassificationContext;
 import android.view.textclassifier.TextClassifierEvent;
-
-import androidx.annotation.Nullable;
+import javax.annotation.Nullable;
 
 /** Helper class to convert a {@link SelectionEvent} to a {@link TextClassifierEvent}. */
 public final class SelectionEventConverter {
 
-    /** Converts a {@link SelectionEvent} to a {@link TextClassifierEvent}. */
-    @Nullable
-    public static TextClassifierEvent toTextClassifierEvent(SelectionEvent selectionEvent) {
-        TextClassificationContext textClassificationContext = null;
-        if (selectionEvent.getPackageName() != null && selectionEvent.getWidgetType() != null) {
-            textClassificationContext =
-                    new TextClassificationContext.Builder(
-                                    selectionEvent.getPackageName(), selectionEvent.getWidgetType())
-                            .setWidgetVersion(selectionEvent.getWidgetVersion())
-                            .build();
-        }
-        if (selectionEvent.getInvocationMethod() == SelectionEvent.INVOCATION_LINK) {
-            return new TextClassifierEvent.TextLinkifyEvent.Builder(
-                            convertEventType(selectionEvent.getEventType()))
-                    .setEventContext(textClassificationContext)
-                    .setResultId(selectionEvent.getResultId())
-                    .setEventIndex(selectionEvent.getEventIndex())
-                    .setEntityTypes(selectionEvent.getEntityType())
-                    .build();
-        }
-        if (selectionEvent.getInvocationMethod() == SelectionEvent.INVOCATION_MANUAL) {
-            return new TextClassifierEvent.TextSelectionEvent.Builder(
-                            convertEventType(selectionEvent.getEventType()))
-                    .setEventContext(textClassificationContext)
-                    .setResultId(selectionEvent.getResultId())
-                    .setEventIndex(selectionEvent.getEventIndex())
-                    .setEntityTypes(selectionEvent.getEntityType())
-                    .setRelativeWordStartIndex(selectionEvent.getStart())
-                    .setRelativeWordEndIndex(selectionEvent.getEnd())
-                    .setRelativeSuggestedWordStartIndex(selectionEvent.getSmartStart())
-                    .setRelativeSuggestedWordEndIndex(selectionEvent.getSmartEnd())
-                    .build();
-        }
-        return null;
+  /** Converts a {@link SelectionEvent} to a {@link TextClassifierEvent}. */
+  @Nullable
+  public static TextClassifierEvent toTextClassifierEvent(SelectionEvent selectionEvent) {
+    TextClassificationContext textClassificationContext = null;
+    if (selectionEvent.getPackageName() != null && selectionEvent.getWidgetType() != null) {
+      textClassificationContext =
+          new TextClassificationContext.Builder(
+                  selectionEvent.getPackageName(), selectionEvent.getWidgetType())
+              .setWidgetVersion(selectionEvent.getWidgetVersion())
+              .build();
     }
+    if (selectionEvent.getInvocationMethod() == SelectionEvent.INVOCATION_LINK) {
+      return new TextClassifierEvent.TextLinkifyEvent.Builder(
+              convertEventType(selectionEvent.getEventType()))
+          .setEventContext(textClassificationContext)
+          .setResultId(selectionEvent.getResultId())
+          .setEventIndex(selectionEvent.getEventIndex())
+          .setEntityTypes(selectionEvent.getEntityType())
+          .build();
+    }
+    if (selectionEvent.getInvocationMethod() == SelectionEvent.INVOCATION_MANUAL) {
+      return new TextClassifierEvent.TextSelectionEvent.Builder(
+              convertEventType(selectionEvent.getEventType()))
+          .setEventContext(textClassificationContext)
+          .setResultId(selectionEvent.getResultId())
+          .setEventIndex(selectionEvent.getEventIndex())
+          .setEntityTypes(selectionEvent.getEntityType())
+          .setRelativeWordStartIndex(selectionEvent.getStart())
+          .setRelativeWordEndIndex(selectionEvent.getEnd())
+          .setRelativeSuggestedWordStartIndex(selectionEvent.getSmartStart())
+          .setRelativeSuggestedWordEndIndex(selectionEvent.getSmartEnd())
+          .build();
+    }
+    return null;
+  }
 
-    private static int convertEventType(int eventType) {
-        switch (eventType) {
-            case SelectionEvent.EVENT_SELECTION_STARTED:
-                return TextClassifierEvent.TYPE_SELECTION_STARTED;
-            case SelectionEvent.EVENT_SELECTION_MODIFIED:
-                return TextClassifierEvent.TYPE_SELECTION_MODIFIED;
-            case SelectionEvent.EVENT_SMART_SELECTION_SINGLE:
-                return SelectionEvent.EVENT_SMART_SELECTION_SINGLE;
-            case SelectionEvent.EVENT_SMART_SELECTION_MULTI:
-                return SelectionEvent.EVENT_SMART_SELECTION_MULTI;
-            case SelectionEvent.EVENT_AUTO_SELECTION:
-                return SelectionEvent.EVENT_AUTO_SELECTION;
-            case SelectionEvent.ACTION_OVERTYPE:
-                return TextClassifierEvent.TYPE_OVERTYPE;
-            case SelectionEvent.ACTION_COPY:
-                return TextClassifierEvent.TYPE_COPY_ACTION;
-            case SelectionEvent.ACTION_PASTE:
-                return TextClassifierEvent.TYPE_PASTE_ACTION;
-            case SelectionEvent.ACTION_CUT:
-                return TextClassifierEvent.TYPE_CUT_ACTION;
-            case SelectionEvent.ACTION_SHARE:
-                return TextClassifierEvent.TYPE_SHARE_ACTION;
-            case SelectionEvent.ACTION_SMART_SHARE:
-                return TextClassifierEvent.TYPE_SMART_ACTION;
-            case SelectionEvent.ACTION_DRAG:
-                return TextClassifierEvent.TYPE_SELECTION_DRAG;
-            case SelectionEvent.ACTION_ABANDON:
-                return TextClassifierEvent.TYPE_SELECTION_DESTROYED;
-            case SelectionEvent.ACTION_OTHER:
-                return TextClassifierEvent.TYPE_OTHER_ACTION;
-            case SelectionEvent.ACTION_SELECT_ALL:
-                return TextClassifierEvent.TYPE_SELECT_ALL;
-            case SelectionEvent.ACTION_RESET:
-                return TextClassifierEvent.TYPE_SELECTION_RESET;
-            default:
-                return 0;
-        }
+  private static int convertEventType(int eventType) {
+    switch (eventType) {
+      case SelectionEvent.EVENT_SELECTION_STARTED:
+        return TextClassifierEvent.TYPE_SELECTION_STARTED;
+      case SelectionEvent.EVENT_SELECTION_MODIFIED:
+        return TextClassifierEvent.TYPE_SELECTION_MODIFIED;
+      case SelectionEvent.EVENT_SMART_SELECTION_SINGLE:
+        return SelectionEvent.EVENT_SMART_SELECTION_SINGLE;
+      case SelectionEvent.EVENT_SMART_SELECTION_MULTI:
+        return SelectionEvent.EVENT_SMART_SELECTION_MULTI;
+      case SelectionEvent.EVENT_AUTO_SELECTION:
+        return SelectionEvent.EVENT_AUTO_SELECTION;
+      case SelectionEvent.ACTION_OVERTYPE:
+        return TextClassifierEvent.TYPE_OVERTYPE;
+      case SelectionEvent.ACTION_COPY:
+        return TextClassifierEvent.TYPE_COPY_ACTION;
+      case SelectionEvent.ACTION_PASTE:
+        return TextClassifierEvent.TYPE_PASTE_ACTION;
+      case SelectionEvent.ACTION_CUT:
+        return TextClassifierEvent.TYPE_CUT_ACTION;
+      case SelectionEvent.ACTION_SHARE:
+        return TextClassifierEvent.TYPE_SHARE_ACTION;
+      case SelectionEvent.ACTION_SMART_SHARE:
+        return TextClassifierEvent.TYPE_SMART_ACTION;
+      case SelectionEvent.ACTION_DRAG:
+        return TextClassifierEvent.TYPE_SELECTION_DRAG;
+      case SelectionEvent.ACTION_ABANDON:
+        return TextClassifierEvent.TYPE_SELECTION_DESTROYED;
+      case SelectionEvent.ACTION_OTHER:
+        return TextClassifierEvent.TYPE_OTHER_ACTION;
+      case SelectionEvent.ACTION_SELECT_ALL:
+        return TextClassifierEvent.TYPE_SELECT_ALL;
+      case SelectionEvent.ACTION_RESET:
+        return TextClassifierEvent.TYPE_SELECTION_RESET;
+      default:
+        return 0;
     }
+  }
+
+  private SelectionEventConverter() {}
 }
diff --git a/java/src/com/android/textclassifier/logging/TextClassifierEventLogger.java b/java/src/com/android/textclassifier/logging/TextClassifierEventLogger.java
index 29e38a1..a112fdf 100644
--- a/java/src/com/android/textclassifier/logging/TextClassifierEventLogger.java
+++ b/java/src/com/android/textclassifier/logging/TextClassifierEventLogger.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2018 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -13,203 +13,203 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package com.android.textclassifier.logging;
 
 import android.view.textclassifier.TextClassificationContext;
 import android.view.textclassifier.TextClassificationSessionId;
 import android.view.textclassifier.TextClassifier;
 import android.view.textclassifier.TextClassifierEvent;
-
-import androidx.annotation.Nullable;
-import androidx.core.util.Preconditions;
-
 import com.android.textclassifier.TcLog;
 import com.android.textclassifier.TextClassifierStatsLog;
+import com.google.common.base.Preconditions;
+import javax.annotation.Nullable;
 
 /** Logs {@link android.view.textclassifier.TextClassifierEvent}. */
 public final class TextClassifierEventLogger {
 
-    private static final String TAG = "TextClassifierEventLogger";
+  private static final String TAG = "TCEventLogger";
 
-    /** Emits a text classifier event to the logs. */
-    public void writeEvent(
-            @Nullable TextClassificationSessionId sessionId, TextClassifierEvent event) {
-        Preconditions.checkNotNull(event);
-        if (TcLog.ENABLE_FULL_LOGGING) {
-            TcLog.v(TAG, "TextClassifierEventLogger.writeEvent: event = [" + event + "]");
-        }
-        if (event instanceof TextClassifierEvent.TextSelectionEvent) {
-            logTextSelectionEvent(sessionId, (TextClassifierEvent.TextSelectionEvent) event);
-        } else if (event instanceof TextClassifierEvent.TextLinkifyEvent) {
-            logTextLinkifyEvent(sessionId, (TextClassifierEvent.TextLinkifyEvent) event);
-        } else if (event instanceof TextClassifierEvent.ConversationActionsEvent) {
-            logConversationActionsEvent(
-                    sessionId, (TextClassifierEvent.ConversationActionsEvent) event);
-        } else if (event instanceof TextClassifierEvent.LanguageDetectionEvent) {
-            logLanguageDetectionEvent(
-                    sessionId, (TextClassifierEvent.LanguageDetectionEvent) event);
-        } else {
-            TcLog.w(TAG, "Unexpected events, category=" + event.getEventCategory());
-        }
+  /** Emits a text classifier event to the logs. */
+  public void writeEvent(
+      @Nullable TextClassificationSessionId sessionId, TextClassifierEvent event) {
+    Preconditions.checkNotNull(event);
+    if (TcLog.ENABLE_FULL_LOGGING) {
+      TcLog.v(TAG, "TextClassifierEventLogger.writeEvent: event = [" + event + "]");
     }
-
-    private void logTextSelectionEvent(
-            @Nullable TextClassificationSessionId sessionId,
-            TextClassifierEvent.TextSelectionEvent event) {
-        TextClassifierStatsLog.write(
-                TextClassifierStatsLog.TEXT_SELECTION_EVENT,
-                sessionId == null ? null : sessionId.flattenToString(),
-                event.getEventType(),
-                getModelName(event),
-                getWidgetType(event),
-                event.getEventIndex(),
-                getItemAt(event.getEntityTypes(), /* index= */ 0),
-                event.getRelativeWordStartIndex(),
-                event.getRelativeWordEndIndex(),
-                event.getRelativeSuggestedWordStartIndex(),
-                event.getRelativeSuggestedWordEndIndex(),
-                getPackageName(event));
+    if (event instanceof TextClassifierEvent.TextSelectionEvent) {
+      logTextSelectionEvent(sessionId, (TextClassifierEvent.TextSelectionEvent) event);
+    } else if (event instanceof TextClassifierEvent.TextLinkifyEvent) {
+      logTextLinkifyEvent(sessionId, (TextClassifierEvent.TextLinkifyEvent) event);
+    } else if (event instanceof TextClassifierEvent.ConversationActionsEvent) {
+      logConversationActionsEvent(sessionId, (TextClassifierEvent.ConversationActionsEvent) event);
+    } else if (event instanceof TextClassifierEvent.LanguageDetectionEvent) {
+      logLanguageDetectionEvent(sessionId, (TextClassifierEvent.LanguageDetectionEvent) event);
+    } else {
+      TcLog.w(TAG, "Unexpected events, category=" + event.getEventCategory());
     }
+  }
 
-    private void logTextLinkifyEvent(
-            TextClassificationSessionId sessionId, TextClassifierEvent.TextLinkifyEvent event) {
-        TextClassifierStatsLog.write(
-                TextClassifierStatsLog.TEXT_LINKIFY_EVENT,
-                sessionId == null ? null : sessionId.flattenToString(),
-                event.getEventType(),
-                getModelName(event),
-                getWidgetType(event),
-                event.getEventIndex(),
-                getItemAt(event.getEntityTypes(), /* index= */ 0),
-                /*numOfLinks=*/ 0,
-                /*linkedTextLength=*/ 0,
-                /*textLength=*/ 0,
-                /*latencyInMillis=*/ 0L,
-                getPackageName(event));
+  private void logTextSelectionEvent(
+      @Nullable TextClassificationSessionId sessionId,
+      TextClassifierEvent.TextSelectionEvent event) {
+    TextClassifierStatsLog.write(
+        TextClassifierStatsLog.TEXT_SELECTION_EVENT,
+        sessionId == null ? null : sessionId.flattenToString(),
+        event.getEventType(),
+        getModelName(event),
+        getWidgetType(event),
+        event.getEventIndex(),
+        getItemAt(event.getEntityTypes(), /* index= */ 0),
+        event.getRelativeWordStartIndex(),
+        event.getRelativeWordEndIndex(),
+        event.getRelativeSuggestedWordStartIndex(),
+        event.getRelativeSuggestedWordEndIndex(),
+        getPackageName(event));
+  }
+
+  private void logTextLinkifyEvent(
+      TextClassificationSessionId sessionId, TextClassifierEvent.TextLinkifyEvent event) {
+    TextClassifierStatsLog.write(
+        TextClassifierStatsLog.TEXT_LINKIFY_EVENT,
+        sessionId == null ? null : sessionId.flattenToString(),
+        event.getEventType(),
+        getModelName(event),
+        getWidgetType(event),
+        event.getEventIndex(),
+        getItemAt(event.getEntityTypes(), /* index= */ 0),
+        /*numOfLinks=*/ 0,
+        /*linkedTextLength=*/ 0,
+        /*textLength=*/ 0,
+        /*latencyInMillis=*/ 0L,
+        getPackageName(event));
+  }
+
+  private void logConversationActionsEvent(
+      @Nullable TextClassificationSessionId sessionId,
+      TextClassifierEvent.ConversationActionsEvent event) {
+    TextClassifierStatsLog.write(
+        TextClassifierStatsLog.CONVERSATION_ACTIONS_EVENT,
+        sessionId == null
+            ? event.getResultId() // TODO: Update ExtServices to set the session id.
+            : sessionId.flattenToString(),
+        event.getEventType(),
+        getModelName(event),
+        getWidgetType(event),
+        getItemAt(event.getEntityTypes(), /* index= */ 0),
+        getItemAt(event.getEntityTypes(), /* index= */ 1),
+        getItemAt(event.getEntityTypes(), /* index= */ 2),
+        getFloatAt(event.getScores(), /* index= */ 0),
+        getPackageName(event));
+  }
+
+  private void logLanguageDetectionEvent(
+      @Nullable TextClassificationSessionId sessionId,
+      TextClassifierEvent.LanguageDetectionEvent event) {
+    TextClassifierStatsLog.write(
+        TextClassifierStatsLog.LANGUAGE_DETECTION_EVENT,
+        sessionId == null ? null : sessionId.flattenToString(),
+        event.getEventType(),
+        getModelName(event),
+        getWidgetType(event),
+        getItemAt(event.getEntityTypes(), /* index= */ 0),
+        getFloatAt(event.getScores(), /* index= */ 0),
+        getIntAt(event.getActionIndices(), /* index= */ 0),
+        getPackageName(event));
+  }
+
+  @Nullable
+  private static <T> T getItemAt(@Nullable T[] array, int index) {
+    if (array == null) {
+      return null;
     }
-
-    private void logConversationActionsEvent(
-            @Nullable TextClassificationSessionId sessionId,
-            TextClassifierEvent.ConversationActionsEvent event) {
-        TextClassifierStatsLog.write(
-                TextClassifierStatsLog.CONVERSATION_ACTIONS_EVENT,
-                sessionId == null
-                        ? event.getResultId() // TODO: Update ExtServices to set the session id.
-                        : sessionId.flattenToString(),
-                event.getEventType(),
-                getModelName(event),
-                getWidgetType(event),
-                getItemAt(event.getEntityTypes(), /* index= */ 0),
-                getItemAt(event.getEntityTypes(), /* index= */ 1),
-                getItemAt(event.getEntityTypes(), /* index= */ 2),
-                getFloatAt(event.getScores(), /* index= */ 0),
-                getPackageName(event));
+    if (index >= array.length) {
+      return null;
     }
+    return array[index];
+  }
 
-    private void logLanguageDetectionEvent(
-            @Nullable TextClassificationSessionId sessionId,
-            TextClassifierEvent.LanguageDetectionEvent event) {
-        TextClassifierStatsLog.write(
-                TextClassifierStatsLog.LANGUAGE_DETECTION_EVENT,
-                sessionId == null ? null : sessionId.flattenToString(),
-                event.getEventType(),
-                getModelName(event),
-                getWidgetType(event),
-                getItemAt(event.getEntityTypes(), /* index= */ 0),
-                getFloatAt(event.getScores(), /* index= */ 0),
-                getIntAt(event.getActionIndices(), /* index= */ 0),
-                getPackageName(event));
+  private static float getFloatAt(@Nullable float[] array, int index) {
+    if (array == null) {
+      return 0f;
     }
-
-    @Nullable
-    private static <T> T getItemAt(@Nullable T[] array, int index) {
-        if (array == null) {
-            return null;
-        }
-        if (index >= array.length) {
-            return null;
-        }
-        return array[index];
+    if (index >= array.length) {
+      return 0f;
     }
+    return array[index];
+  }
 
-    private static float getFloatAt(@Nullable float[] array, int index) {
-        if (array == null) {
-            return 0f;
-        }
-        if (index >= array.length) {
-            return 0f;
-        }
-        return array[index];
+  private static int getIntAt(@Nullable int[] array, int index) {
+    if (array == null) {
+      return 0;
     }
-
-    private static int getIntAt(@Nullable int[] array, int index) {
-        if (array == null) {
-            return 0;
-        }
-        if (index >= array.length) {
-            return 0;
-        }
-        return array[index];
+    if (index >= array.length) {
+      return 0;
     }
+    return array[index];
+  }
 
-    private static String getModelName(TextClassifierEvent event) {
-        if (event.getModelName() != null) {
-            return event.getModelName();
-        }
-        return ResultIdUtils.getModelName(event.getResultId());
+  private static String getModelName(TextClassifierEvent event) {
+    if (event.getModelName() != null) {
+      return event.getModelName();
     }
+    return ResultIdUtils.getModelName(event.getResultId());
+  }
 
-    @Nullable
-    private static String getPackageName(TextClassifierEvent event) {
-        TextClassificationContext eventContext = event.getEventContext();
-        if (eventContext == null) {
-            return null;
-        }
-        return eventContext.getPackageName();
+  @Nullable
+  private static String getPackageName(TextClassifierEvent event) {
+    TextClassificationContext eventContext = event.getEventContext();
+    if (eventContext == null) {
+      return null;
     }
+    return eventContext.getPackageName();
+  }
 
-    private static int getWidgetType(TextClassifierEvent event) {
-        TextClassificationContext eventContext = event.getEventContext();
-        if (eventContext == null) {
-            return WidgetType.WIDGET_TYPE_UNKNOWN;
-        }
-        switch (eventContext.getWidgetType()) {
-            case TextClassifier.WIDGET_TYPE_UNKNOWN:
-                return WidgetType.WIDGET_TYPE_UNKNOWN;
-            case TextClassifier.WIDGET_TYPE_TEXTVIEW:
-                return WidgetType.WIDGET_TYPE_TEXTVIEW;
-            case TextClassifier.WIDGET_TYPE_EDITTEXT:
-                return WidgetType.WIDGET_TYPE_EDITTEXT;
-            case TextClassifier.WIDGET_TYPE_UNSELECTABLE_TEXTVIEW:
-                return WidgetType.WIDGET_TYPE_UNSELECTABLE_TEXTVIEW;
-            case TextClassifier.WIDGET_TYPE_WEBVIEW:
-                return WidgetType.WIDGET_TYPE_WEBVIEW;
-            case TextClassifier.WIDGET_TYPE_EDIT_WEBVIEW:
-                return WidgetType.WIDGET_TYPE_EDIT_WEBVIEW;
-            case TextClassifier.WIDGET_TYPE_CUSTOM_TEXTVIEW:
-                return WidgetType.WIDGET_TYPE_CUSTOM_TEXTVIEW;
-            case TextClassifier.WIDGET_TYPE_CUSTOM_EDITTEXT:
-                return WidgetType.WIDGET_TYPE_CUSTOM_EDITTEXT;
-            case TextClassifier.WIDGET_TYPE_CUSTOM_UNSELECTABLE_TEXTVIEW:
-                return WidgetType.WIDGET_TYPE_CUSTOM_UNSELECTABLE_TEXTVIEW;
-            case TextClassifier.WIDGET_TYPE_NOTIFICATION:
-                return WidgetType.WIDGET_TYPE_NOTIFICATION;
-        }
+  private static int getWidgetType(TextClassifierEvent event) {
+    TextClassificationContext eventContext = event.getEventContext();
+    if (eventContext == null) {
+      return WidgetType.WIDGET_TYPE_UNKNOWN;
+    }
+    switch (eventContext.getWidgetType()) {
+      case TextClassifier.WIDGET_TYPE_UNKNOWN:
         return WidgetType.WIDGET_TYPE_UNKNOWN;
+      case TextClassifier.WIDGET_TYPE_TEXTVIEW:
+        return WidgetType.WIDGET_TYPE_TEXTVIEW;
+      case TextClassifier.WIDGET_TYPE_EDITTEXT:
+        return WidgetType.WIDGET_TYPE_EDITTEXT;
+      case TextClassifier.WIDGET_TYPE_UNSELECTABLE_TEXTVIEW:
+        return WidgetType.WIDGET_TYPE_UNSELECTABLE_TEXTVIEW;
+      case TextClassifier.WIDGET_TYPE_WEBVIEW:
+        return WidgetType.WIDGET_TYPE_WEBVIEW;
+      case TextClassifier.WIDGET_TYPE_EDIT_WEBVIEW:
+        return WidgetType.WIDGET_TYPE_EDIT_WEBVIEW;
+      case TextClassifier.WIDGET_TYPE_CUSTOM_TEXTVIEW:
+        return WidgetType.WIDGET_TYPE_CUSTOM_TEXTVIEW;
+      case TextClassifier.WIDGET_TYPE_CUSTOM_EDITTEXT:
+        return WidgetType.WIDGET_TYPE_CUSTOM_EDITTEXT;
+      case TextClassifier.WIDGET_TYPE_CUSTOM_UNSELECTABLE_TEXTVIEW:
+        return WidgetType.WIDGET_TYPE_CUSTOM_UNSELECTABLE_TEXTVIEW;
+      case TextClassifier.WIDGET_TYPE_NOTIFICATION:
+        return WidgetType.WIDGET_TYPE_NOTIFICATION;
+      default: // fall out
     }
+    return WidgetType.WIDGET_TYPE_UNKNOWN;
+  }
 
-    /** Widget type constants for logging. */
-    public interface WidgetType {
-        // Sync these constants with textclassifier_enums.proto.
-        int WIDGET_TYPE_UNKNOWN = 0;
-        int WIDGET_TYPE_TEXTVIEW = 1;
-        int WIDGET_TYPE_EDITTEXT = 2;
-        int WIDGET_TYPE_UNSELECTABLE_TEXTVIEW = 3;
-        int WIDGET_TYPE_WEBVIEW = 4;
-        int WIDGET_TYPE_EDIT_WEBVIEW = 5;
-        int WIDGET_TYPE_CUSTOM_TEXTVIEW = 6;
-        int WIDGET_TYPE_CUSTOM_EDITTEXT = 7;
-        int WIDGET_TYPE_CUSTOM_UNSELECTABLE_TEXTVIEW = 8;
-        int WIDGET_TYPE_NOTIFICATION = 9;
-    }
+  /** Widget type constants for logging. */
+  public static final class WidgetType {
+    // Sync these constants with textclassifier_enums.proto.
+    public static final int WIDGET_TYPE_UNKNOWN = 0;
+    public static final int WIDGET_TYPE_TEXTVIEW = 1;
+    public static final int WIDGET_TYPE_EDITTEXT = 2;
+    public static final int WIDGET_TYPE_UNSELECTABLE_TEXTVIEW = 3;
+    public static final int WIDGET_TYPE_WEBVIEW = 4;
+    public static final int WIDGET_TYPE_EDIT_WEBVIEW = 5;
+    public static final int WIDGET_TYPE_CUSTOM_TEXTVIEW = 6;
+    public static final int WIDGET_TYPE_CUSTOM_EDITTEXT = 7;
+    public static final int WIDGET_TYPE_CUSTOM_UNSELECTABLE_TEXTVIEW = 8;
+    public static final int WIDGET_TYPE_NOTIFICATION = 9;
+
+    private WidgetType() {}
+  }
 }
diff --git a/java/src/com/android/textclassifier/ulp/BasicLanguageProficiencyAnalyzer.java b/java/src/com/android/textclassifier/ulp/BasicLanguageProficiencyAnalyzer.java
index 64a9fe8..66db748 100644
--- a/java/src/com/android/textclassifier/ulp/BasicLanguageProficiencyAnalyzer.java
+++ b/java/src/com/android/textclassifier/ulp/BasicLanguageProficiencyAnalyzer.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2018 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -19,14 +19,11 @@
 import android.content.Context;
 import android.util.ArrayMap;
 import android.view.textclassifier.TextClassifierEvent;
-
 import com.android.textclassifier.TextClassificationConstants;
 import com.android.textclassifier.ulp.database.LanguageProfileDatabase;
 import com.android.textclassifier.ulp.database.LanguageSignalInfo;
-
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Preconditions;
-
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
@@ -42,77 +39,74 @@
  */
 final class BasicLanguageProficiencyAnalyzer implements LanguageProficiencyAnalyzer {
 
-    private static final long CAN_UNDERSTAND_RESULT_CACHE_EXPIRATION_TIME =
-            TimeUnit.HOURS.toMillis(6);
+  private static final long CAN_UNDERSTAND_RESULT_CACHE_EXPIRATION_TIME =
+      TimeUnit.HOURS.toMillis(6);
 
-    private final TextClassificationConstants mSettings;
-    private final LanguageProfileDatabase mDatabase;
-    private final SystemLanguagesProvider mSystemLanguagesProvider;
+  private final TextClassificationConstants settings;
+  private final LanguageProfileDatabase database;
+  private final SystemLanguagesProvider systemLanguagesProvider;
 
-    private Map<String, Float> mCanUnderstandResultCache;
-    private long mCanUnderstandResultCacheTime;
+  private Map<String, Float> canUnderstandResultCache;
+  private long canUnderstandResultCacheTime;
 
-    BasicLanguageProficiencyAnalyzer(
-            Context context,
-            TextClassificationConstants settings,
-            SystemLanguagesProvider systemLanguagesProvider) {
-        this(settings, LanguageProfileDatabase.getInstance(context), systemLanguagesProvider);
+  BasicLanguageProficiencyAnalyzer(
+      Context context,
+      TextClassificationConstants settings,
+      SystemLanguagesProvider systemLanguagesProvider) {
+    this(settings, LanguageProfileDatabase.getInstance(context), systemLanguagesProvider);
+  }
+
+  @VisibleForTesting
+  BasicLanguageProficiencyAnalyzer(
+      TextClassificationConstants settings,
+      LanguageProfileDatabase languageProfileDatabase,
+      SystemLanguagesProvider systemLanguagesProvider) {
+    this.settings = Preconditions.checkNotNull(settings);
+    database = Preconditions.checkNotNull(languageProfileDatabase);
+    this.systemLanguagesProvider = Preconditions.checkNotNull(systemLanguagesProvider);
+    canUnderstandResultCache = new ArrayMap<>();
+  }
+
+  @Override
+  public synchronized float canUnderstand(String languageTag) {
+    if (canUnderstandResultCache.isEmpty()
+        || (System.currentTimeMillis() - canUnderstandResultCacheTime)
+            >= CAN_UNDERSTAND_RESULT_CACHE_EXPIRATION_TIME) {
+      canUnderstandResultCache = createCanUnderstandResultCache();
+      canUnderstandResultCacheTime = System.currentTimeMillis();
     }
+    return canUnderstandResultCache.getOrDefault(languageTag, 0f);
+  }
 
-    @VisibleForTesting
-    BasicLanguageProficiencyAnalyzer(
-            TextClassificationConstants settings,
-            LanguageProfileDatabase languageProfileDatabase,
-            SystemLanguagesProvider systemLanguagesProvider) {
-        mSettings = Preconditions.checkNotNull(settings);
-        mDatabase = Preconditions.checkNotNull(languageProfileDatabase);
-        mSystemLanguagesProvider = Preconditions.checkNotNull(systemLanguagesProvider);
-        mCanUnderstandResultCache = new ArrayMap<>();
+  @Override
+  public void onTextClassifierEvent(TextClassifierEvent event) {}
+
+  @Override
+  public boolean shouldShowTranslation(String languageCode) {
+    return canUnderstand(languageCode) >= settings.getTranslateActionThreshold();
+  }
+
+  private Map<String, Float> createCanUnderstandResultCache() {
+    Map<String, Float> result = new ArrayMap<>();
+    List<String> systemLanguageTags = systemLanguagesProvider.getSystemLanguageTags();
+    List<LanguageSignalInfo> languageSignalInfos =
+        database.languageInfoDao().getBySource(LanguageSignalInfo.SUGGEST_CONVERSATION_ACTIONS);
+    // Applies system languages to bootstrap the model according to Zipf's Law.
+    // Zipf’s Law states that the ith most common language should be proportional to 1/i.
+    for (int i = 0; i < systemLanguageTags.size(); i++) {
+      String languageTag = systemLanguageTags.get(i);
+      result.put(
+          languageTag, settings.getLanguageProficiencyBootstrappingCount() / (float) (i + 1));
     }
-
-    @Override
-    public synchronized float canUnderstand(String languageTag) {
-        if (mCanUnderstandResultCache.isEmpty()
-                || (System.currentTimeMillis() - mCanUnderstandResultCacheTime)
-                        >= CAN_UNDERSTAND_RESULT_CACHE_EXPIRATION_TIME) {
-            mCanUnderstandResultCache = createCanUnderstandResultCache();
-            mCanUnderstandResultCacheTime = System.currentTimeMillis();
-        }
-        return mCanUnderstandResultCache.getOrDefault(languageTag, 0f);
+    // Adds message counts of different languages into the corresponding entry in the map
+    for (LanguageSignalInfo info : languageSignalInfos) {
+      String languageTag = info.getLanguageTag();
+      int count = info.getCount();
+      result.put(languageTag, result.getOrDefault(languageTag, 0f) + count);
     }
-
-    @Override
-    public void onTextClassifierEvent(TextClassifierEvent event) {}
-
-    @Override
-    public boolean shouldShowTranslation(String languageCode) {
-        return canUnderstand(languageCode) >= mSettings.getTranslateActionThreshold();
-    }
-
-    private Map<String, Float> createCanUnderstandResultCache() {
-        Map<String, Float> result = new ArrayMap<>();
-        List<String> systemLanguageTags = mSystemLanguagesProvider.getSystemLanguageTags();
-        List<LanguageSignalInfo> languageSignalInfos =
-                mDatabase
-                        .languageInfoDao()
-                        .getBySource(LanguageSignalInfo.SUGGEST_CONVERSATION_ACTIONS);
-        // Applies system languages to bootstrap the model according to Zipf's Law.
-        // Zipf’s Law states that the ith most common language should be proportional to 1/i.
-        for (int i = 0; i < systemLanguageTags.size(); i++) {
-            String languageTag = systemLanguageTags.get(i);
-            result.put(
-                    languageTag,
-                    mSettings.getLanguageProficiencyBootstrappingCount() / (float) (i + 1));
-        }
-        // Adds message counts of different languages into the corresponding entry in the map
-        for (LanguageSignalInfo info : languageSignalInfos) {
-            String languageTag = info.getLanguageTag();
-            int count = info.getCount();
-            result.put(languageTag, result.getOrDefault(languageTag, 0f) + count);
-        }
-        // Calculates confidence scores
-        float max = Collections.max(result.values());
-        result.forEach((languageTag, count) -> result.put(languageTag, count / max));
-        return result;
-    }
+    // Calculates confidence scores
+    float max = Collections.max(result.values());
+    result.forEach((languageTag, count) -> result.put(languageTag, count / max));
+    return result;
+  }
 }
diff --git a/java/src/com/android/textclassifier/ulp/KmeansLanguageProficiencyAnalyzer.java b/java/src/com/android/textclassifier/ulp/KmeansLanguageProficiencyAnalyzer.java
index e33e45b..28d97e4 100644
--- a/java/src/com/android/textclassifier/ulp/KmeansLanguageProficiencyAnalyzer.java
+++ b/java/src/com/android/textclassifier/ulp/KmeansLanguageProficiencyAnalyzer.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2018 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -18,17 +18,13 @@
 
 import android.content.Context;
 import android.view.textclassifier.TextClassifierEvent;
-
 import androidx.collection.ArrayMap;
-
 import com.android.textclassifier.TextClassificationConstants;
 import com.android.textclassifier.ulp.database.LanguageProfileDatabase;
 import com.android.textclassifier.ulp.database.LanguageSignalInfo;
 import com.android.textclassifier.ulp.kmeans.KMeans;
-
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Preconditions;
-
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
@@ -45,127 +41,126 @@
 // STOPSHIP: Review the entire ULP package before shipping it.
 final class KmeansLanguageProficiencyAnalyzer implements LanguageProficiencyAnalyzer {
 
-    private static final long CAN_UNDERSTAND_RESULT_CACHE_EXPIRATION_TIME =
-            TimeUnit.HOURS.toMillis(6);
+  private static final long CAN_UNDERSTAND_RESULT_CACHE_EXPIRATION_TIME =
+      TimeUnit.HOURS.toMillis(6);
 
-    private final TextClassificationConstants mSettings;
-    private final LanguageProfileDatabase mDatabase;
-    private final KMeans mKmeans;
-    private final SystemLanguagesProvider mSystemLanguagesProvider;
+  private final TextClassificationConstants settings;
+  private final LanguageProfileDatabase database;
+  private final KMeans kmeans;
+  private final SystemLanguagesProvider systemLanguagesProvider;
 
-    private Map<String, Float> mCanUnderstandResultCache;
-    private long mCanUnderstandResultCacheTime;
+  private Map<String, Float> canUnderstandResultCache;
+  private long canUnderstandResultCacheTime;
 
-    KmeansLanguageProficiencyAnalyzer(
-            Context context,
-            TextClassificationConstants settings,
-            SystemLanguagesProvider systemLanguagesProvider) {
-        this(settings, LanguageProfileDatabase.getInstance(context), systemLanguagesProvider);
+  KmeansLanguageProficiencyAnalyzer(
+      Context context,
+      TextClassificationConstants settings,
+      SystemLanguagesProvider systemLanguagesProvider) {
+    this(settings, LanguageProfileDatabase.getInstance(context), systemLanguagesProvider);
+  }
+
+  @VisibleForTesting
+  KmeansLanguageProficiencyAnalyzer(
+      TextClassificationConstants settings,
+      LanguageProfileDatabase languageProfileDatabase,
+      SystemLanguagesProvider systemLanguagesProvider) {
+    this.settings = Preconditions.checkNotNull(settings);
+    database = Preconditions.checkNotNull(languageProfileDatabase);
+    kmeans = new KMeans();
+    this.systemLanguagesProvider = Preconditions.checkNotNull(systemLanguagesProvider);
+    canUnderstandResultCache = new ArrayMap<>();
+  }
+
+  @Override
+  public synchronized float canUnderstand(String languageTag) {
+    if (canUnderstandResultCache.isEmpty()
+        || (System.currentTimeMillis() - canUnderstandResultCacheTime)
+            >= CAN_UNDERSTAND_RESULT_CACHE_EXPIRATION_TIME) {
+      canUnderstandResultCache = createCanUnderstandResultCache();
+      canUnderstandResultCacheTime = System.currentTimeMillis();
     }
+    return canUnderstandResultCache.getOrDefault(languageTag, 0f);
+  }
 
-    @VisibleForTesting
-    KmeansLanguageProficiencyAnalyzer(
-            TextClassificationConstants settings,
-            LanguageProfileDatabase languageProfileDatabase,
-            SystemLanguagesProvider systemLanguagesProvider) {
-        mSettings = Preconditions.checkNotNull(settings);
-        mDatabase = Preconditions.checkNotNull(languageProfileDatabase);
-        mKmeans = new KMeans();
-        mSystemLanguagesProvider = Preconditions.checkNotNull(systemLanguagesProvider);
-        mCanUnderstandResultCache = new ArrayMap<>();
+  private Map<String, Float> createCanUnderstandResultCache() {
+    Map<String, Float> result = new ArrayMap<>();
+    ArrayMap<String, Integer> languageCounts = new ArrayMap<>();
+    List<String> systemLanguageTags = systemLanguagesProvider.getSystemLanguageTags();
+    List<LanguageSignalInfo> languageSignalInfos =
+        database.languageInfoDao().getBySource(LanguageSignalInfo.SUGGEST_CONVERSATION_ACTIONS);
+    // Applies system languages to bootstrap the model according to Zipf's Law.
+    // Zipf’s Law states that the ith most common language should be proportional to 1/i.
+    for (int i = 0; i < systemLanguageTags.size(); i++) {
+      String languageTag = systemLanguageTags.get(i);
+      languageCounts.put(
+          languageTag, settings.getLanguageProficiencyBootstrappingCount() / (i + 1));
     }
-
-    @Override
-    public synchronized float canUnderstand(String languageTag) {
-        if (mCanUnderstandResultCache.isEmpty()
-                || (System.currentTimeMillis() - mCanUnderstandResultCacheTime)
-                        >= CAN_UNDERSTAND_RESULT_CACHE_EXPIRATION_TIME) {
-            mCanUnderstandResultCache = createCanUnderstandResultCache();
-            mCanUnderstandResultCacheTime = System.currentTimeMillis();
-        }
-        return mCanUnderstandResultCache.getOrDefault(languageTag, 0f);
+    // Adds message counts of different languages into the corresponding entry in the map
+    for (LanguageSignalInfo info : languageSignalInfos) {
+      String languageTag = info.getLanguageTag();
+      int count = info.getCount();
+      languageCounts.put(languageTag, languageCounts.getOrDefault(languageTag, 0) + count);
     }
-
-    private Map<String, Float> createCanUnderstandResultCache() {
-        Map<String, Float> result = new ArrayMap<>();
-        ArrayMap<String, Integer> languageCounts = new ArrayMap<>();
-        List<String> systemLanguageTags = mSystemLanguagesProvider.getSystemLanguageTags();
-        List<LanguageSignalInfo> languageSignalInfos =
-                mDatabase
-                        .languageInfoDao()
-                        .getBySource(LanguageSignalInfo.SUGGEST_CONVERSATION_ACTIONS);
-        // Applies system languages to bootstrap the model according to Zipf's Law.
-        // Zipf’s Law states that the ith most common language should be proportional to 1/i.
-        for (int i = 0; i < systemLanguageTags.size(); i++) {
-            String languageTag = systemLanguageTags.get(i);
-            languageCounts.put(
-                    languageTag, mSettings.getLanguageProficiencyBootstrappingCount() / (i + 1));
-        }
-        // Adds message counts of different languages into the corresponding entry in the map
-        for (LanguageSignalInfo info : languageSignalInfos) {
-            String languageTag = info.getLanguageTag();
-            int count = info.getCount();
-            languageCounts.put(languageTag, languageCounts.getOrDefault(languageTag, 0) + count);
-        }
-        // Calculates confidence scores
-        if (languageCounts.size() == 1) {
-            result.put(languageCounts.keyAt(0), 1f);
-            return result;
-        }
-        if (languageCounts.size() == 2) {
-            return evaluateTwoLanguageCounts(languageCounts);
-        }
-        // Applies K-Means to cluster data points
-        int size = languageCounts.size();
-        float[][] inputData = new float[size][1];
-        for (int i = 0; i < size; i++) {
-            inputData[i][0] = languageCounts.valueAt(i);
-        }
-        List<KMeans.Mean> means = mKmeans.predict(/* k= */ 2, inputData);
-        List<Integer> countsInMaxCluster = getCountsWithinFarthestCluster(means);
-        for (int i = 0; i < languageCounts.size(); i++) {
-            float score = countsInMaxCluster.contains(languageCounts.valueAt(i)) ? 1f : 0f;
-            result.put(languageCounts.keyAt(i), score);
-        }
-        return result;
+    // Calculates confidence scores
+    if (languageCounts.size() == 1) {
+      result.put(languageCounts.keyAt(0), 1f);
+      return result;
     }
-
-    @Override
-    public void onTextClassifierEvent(TextClassifierEvent event) {}
-
-    @Override
-    public boolean shouldShowTranslation(String languageCode) {
-        return canUnderstand(languageCode) >= mSettings.getTranslateActionThreshold();
+    if (languageCounts.size() == 2) {
+      return evaluateTwoLanguageCounts(languageCounts);
     }
-
-    private Map<String, Float> evaluateTwoLanguageCounts(ArrayMap<String, Integer> languageCounts) {
-        Map<String, Float> result = new ArrayMap<>();
-        int countOne = languageCounts.valueAt(0);
-        String languageTagOne = languageCounts.keyAt(0);
-        int countTwo = languageCounts.valueAt(1);
-        String languageTagTwo = languageCounts.keyAt(1);
-        if (countOne >= countTwo) {
-            result.put(languageTagOne, 1f);
-            result.put(languageTagTwo, countTwo / (float) countOne);
-        } else {
-            result.put(languageTagTwo, 1f);
-            result.put(languageTagOne, countOne / (float) countTwo);
-        }
-        return result;
+    // Applies K-Means to cluster data points
+    int size = languageCounts.size();
+    float[][] inputData = new float[size][1];
+    for (int i = 0; i < size; i++) {
+      inputData[i][0] = languageCounts.valueAt(i);
     }
-
-    private List<Integer> getCountsWithinFarthestCluster(List<KMeans.Mean> means) {
-        List<Integer> result = new ArrayList<>();
-        KMeans.Mean farthestMean = means.get(0);
-        for (int i = 1; i < means.size(); i++) {
-            KMeans.Mean curMean = means.get(i);
-            if (curMean.getCentroid()[0] > farthestMean.getCentroid()[0]) {
-                farthestMean = curMean;
-            }
-        }
-        for (float[] item : farthestMean.getItems()) {
-            result.add((int) item[0]);
-        }
-        return result;
+    List<KMeans.Mean> means = kmeans.predict(/* k= */ 2, inputData);
+    List<Integer> countsInMaxCluster = getCountsWithinFarthestCluster(means);
+    for (int i = 0; i < languageCounts.size(); i++) {
+      float score = countsInMaxCluster.contains(languageCounts.valueAt(i)) ? 1f : 0f;
+      result.put(languageCounts.keyAt(i), score);
     }
+    return result;
+  }
+
+  @Override
+  public void onTextClassifierEvent(TextClassifierEvent event) {}
+
+  @Override
+  public boolean shouldShowTranslation(String languageCode) {
+    return canUnderstand(languageCode) >= settings.getTranslateActionThreshold();
+  }
+
+  private static Map<String, Float> evaluateTwoLanguageCounts(
+      ArrayMap<String, Integer> languageCounts) {
+    Map<String, Float> result = new ArrayMap<>();
+    int countOne = languageCounts.valueAt(0);
+    String languageTagOne = languageCounts.keyAt(0);
+    int countTwo = languageCounts.valueAt(1);
+    String languageTagTwo = languageCounts.keyAt(1);
+    if (countOne >= countTwo) {
+      result.put(languageTagOne, 1f);
+      result.put(languageTagTwo, countTwo / (float) countOne);
+    } else {
+      result.put(languageTagTwo, 1f);
+      result.put(languageTagOne, countOne / (float) countTwo);
+    }
+    return result;
+  }
+
+  private static List<Integer> getCountsWithinFarthestCluster(List<KMeans.Mean> means) {
+    List<Integer> result = new ArrayList<>();
+    KMeans.Mean farthestMean = means.get(0);
+    for (int i = 1; i < means.size(); i++) {
+      KMeans.Mean curMean = means.get(i);
+      if (curMean.getCentroid()[0] > farthestMean.getCentroid()[0]) {
+        farthestMean = curMean;
+      }
+    }
+    for (float[] item : farthestMean.getItems()) {
+      result.add((int) item[0]);
+    }
+    return result;
+  }
 }
diff --git a/java/src/com/android/textclassifier/ulp/LanguageProficiencyAnalyzer.java b/java/src/com/android/textclassifier/ulp/LanguageProficiencyAnalyzer.java
index 89ea236..c9e8695 100644
--- a/java/src/com/android/textclassifier/ulp/LanguageProficiencyAnalyzer.java
+++ b/java/src/com/android/textclassifier/ulp/LanguageProficiencyAnalyzer.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2018 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -17,14 +17,13 @@
 package com.android.textclassifier.ulp;
 
 import android.view.textclassifier.TextClassifierEvent;
-
 import androidx.annotation.FloatRange;
 
 interface LanguageProficiencyAnalyzer {
-    @FloatRange(from = 0.0, to = 1.0)
-    float canUnderstand(String languageCode);
+  @FloatRange(from = 0.0, to = 1.0)
+  float canUnderstand(String languageCode);
 
-    void onTextClassifierEvent(TextClassifierEvent event);
+  void onTextClassifierEvent(TextClassifierEvent event);
 
-    boolean shouldShowTranslation(String languageCode);
+  boolean shouldShowTranslation(String languageCode);
 }
diff --git a/java/src/com/android/textclassifier/ulp/LanguageProficiencyEvaluator.java b/java/src/com/android/textclassifier/ulp/LanguageProficiencyEvaluator.java
index c8ed732..7c16418 100644
--- a/java/src/com/android/textclassifier/ulp/LanguageProficiencyEvaluator.java
+++ b/java/src/com/android/textclassifier/ulp/LanguageProficiencyEvaluator.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2018 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -18,106 +18,104 @@
 
 import androidx.collection.ArrayMap;
 import androidx.collection.ArraySet;
-import androidx.core.util.Preconditions;
-
+import com.google.common.base.Preconditions;
 import java.util.Set;
 
 final class LanguageProficiencyEvaluator {
-    private final SystemLanguagesProvider mSystemLanguagesProvider;
+  private final SystemLanguagesProvider systemLanguagesProvider;
 
-    LanguageProficiencyEvaluator(SystemLanguagesProvider systemLanguagesProvider) {
-        mSystemLanguagesProvider = Preconditions.checkNotNull(systemLanguagesProvider);
+  LanguageProficiencyEvaluator(SystemLanguagesProvider systemLanguagesProvider) {
+    this.systemLanguagesProvider = Preconditions.checkNotNull(systemLanguagesProvider);
+  }
+
+  EvaluationResult evaluate(LanguageProficiencyAnalyzer analyzer, Set<String> languagesToEvaluate) {
+    Set<String> systemLanguageTags =
+        new ArraySet<>(systemLanguagesProvider.getSystemLanguageTags());
+    ArrayMap<String, Boolean> actual = new ArrayMap<>();
+    // We assume user can only speak the languages that are set as system languages.
+    for (String languageToEvaluate : languagesToEvaluate) {
+      actual.put(languageToEvaluate, systemLanguageTags.contains(languageToEvaluate));
+    }
+    return evaluateWithActual(analyzer, actual);
+  }
+
+  private static EvaluationResult evaluateWithActual(
+      LanguageProficiencyAnalyzer analyzer, ArrayMap<String, Boolean> actual) {
+    ArrayMap<String, Boolean> predict = new ArrayMap<>();
+    for (int i = 0; i < actual.size(); i++) {
+      String languageTag = actual.keyAt(i);
+      predict.put(languageTag, analyzer.canUnderstand(languageTag) >= 0.5f);
+    }
+    return EvaluationResult.create(actual, predict);
+  }
+
+  static final class EvaluationResult {
+    final int truePositive;
+    final int trueNegative;
+    final int falsePositive;
+    final int falseNegative;
+
+    private EvaluationResult(
+        int truePositive, int trueNegative, int falsePositive, int falseNegative) {
+      this.truePositive = truePositive;
+      this.trueNegative = trueNegative;
+      this.falsePositive = falsePositive;
+      this.falseNegative = falseNegative;
     }
 
-    EvaluationResult evaluate(
-            LanguageProficiencyAnalyzer analyzer, Set<String> languagesToEvaluate) {
-        Set<String> systemLanguageTags =
-                new ArraySet<>(mSystemLanguagesProvider.getSystemLanguageTags());
-        ArrayMap<String, Boolean> actual = new ArrayMap<>();
-        // We assume user can only speak the languages that are set as system languages.
-        for (String languageToEvaluate : languagesToEvaluate) {
-            actual.put(languageToEvaluate, systemLanguageTags.contains(languageToEvaluate));
-        }
-        return evaluateWithActual(analyzer, actual);
+    float computePrecisionOfPositiveClass() {
+      float divisor = truePositive + falsePositive;
+      return divisor != 0 ? truePositive / divisor : 1f;
     }
 
-    private EvaluationResult evaluateWithActual(
-            LanguageProficiencyAnalyzer analyzer, ArrayMap<String, Boolean> actual) {
-        ArrayMap<String, Boolean> predict = new ArrayMap<>();
-        for (int i = 0; i < actual.size(); i++) {
-            String languageTag = actual.keyAt(i);
-            predict.put(languageTag, analyzer.canUnderstand(languageTag) >= 0.5f);
-        }
-        return EvaluationResult.create(actual, predict);
+    float computePrecisionOfNegativeClass() {
+      float divisor = trueNegative + falseNegative;
+      return divisor != 0 ? trueNegative / divisor : 1f;
     }
 
-    static final class EvaluationResult {
-        final int truePositive;
-        final int trueNegative;
-        final int falsePositive;
-        final int falseNegative;
-
-        private EvaluationResult(
-                int truePositive, int trueNegative, int falsePositive, int falseNegative) {
-            this.truePositive = truePositive;
-            this.trueNegative = trueNegative;
-            this.falsePositive = falsePositive;
-            this.falseNegative = falseNegative;
-        }
-
-        float computePrecisionOfPositiveClass() {
-            float divisor = truePositive + falsePositive;
-            return divisor != 0 ? truePositive / divisor : 1f;
-        }
-
-        float computePrecisionOfNegativeClass() {
-            float divisor = trueNegative + falseNegative;
-            return divisor != 0 ? trueNegative / divisor : 1f;
-        }
-
-        float computeRecallOfPositiveClass() {
-            float divisor = truePositive + falseNegative;
-            return divisor != 0 ? truePositive / divisor : 1f;
-        }
-
-        float computeRecallOfNegativeClass() {
-            float divisor = trueNegative + falsePositive;
-            return divisor != 0 ? trueNegative / divisor : 1f;
-        }
-
-        float computeF1ScoreOfPositiveClass() {
-            return 2 * truePositive / (float) (2 * truePositive + falsePositive + falseNegative);
-        }
-
-        float computeF1ScoreOfNegativeClass() {
-            return 2 * trueNegative / (float) (2 * trueNegative + falsePositive + falseNegative);
-        }
-
-        static EvaluationResult create(
-                ArrayMap<String, Boolean> actual, ArrayMap<String, Boolean> predict) {
-            int truePositive = 0;
-            int trueNegative = 0;
-            int falsePositive = 0;
-            int falseNegative = 0;
-            for (int i = 0; i < actual.size(); i++) {
-                String languageTag = actual.keyAt(i);
-                boolean actualLabel = actual.valueAt(i);
-                boolean predictLabel = predict.get(languageTag);
-                if (predictLabel) {
-                    if (actualLabel == predictLabel) {
-                        truePositive += 1;
-                    } else {
-                        falsePositive += 1;
-                    }
-                } else {
-                    if (actualLabel == predictLabel) {
-                        trueNegative += 1;
-                    } else {
-                        falseNegative += 1;
-                    }
-                }
-            }
-            return new EvaluationResult(truePositive, trueNegative, falsePositive, falseNegative);
-        }
+    float computeRecallOfPositiveClass() {
+      float divisor = truePositive + falseNegative;
+      return divisor != 0 ? truePositive / divisor : 1f;
     }
+
+    float computeRecallOfNegativeClass() {
+      float divisor = trueNegative + falsePositive;
+      return divisor != 0 ? trueNegative / divisor : 1f;
+    }
+
+    float computeF1ScoreOfPositiveClass() {
+      return 2 * truePositive / (float) (2 * truePositive + falsePositive + falseNegative);
+    }
+
+    float computeF1ScoreOfNegativeClass() {
+      return 2 * trueNegative / (float) (2 * trueNegative + falsePositive + falseNegative);
+    }
+
+    static EvaluationResult create(
+        ArrayMap<String, Boolean> actual, ArrayMap<String, Boolean> predict) {
+      int truePositive = 0;
+      int trueNegative = 0;
+      int falsePositive = 0;
+      int falseNegative = 0;
+      for (int i = 0; i < actual.size(); i++) {
+        String languageTag = actual.keyAt(i);
+        boolean actualLabel = actual.valueAt(i);
+        boolean predictLabel = predict.get(languageTag);
+        if (predictLabel) {
+          if (actualLabel == predictLabel) {
+            truePositive += 1;
+          } else {
+            falsePositive += 1;
+          }
+        } else {
+          if (actualLabel == predictLabel) {
+            trueNegative += 1;
+          } else {
+            falseNegative += 1;
+          }
+        }
+      }
+      return new EvaluationResult(truePositive, trueNegative, falsePositive, falseNegative);
+    }
+  }
 }
diff --git a/java/src/com/android/textclassifier/ulp/LanguageProfileAnalyzer.java b/java/src/com/android/textclassifier/ulp/LanguageProfileAnalyzer.java
index ac220f3..4c436dc 100644
--- a/java/src/com/android/textclassifier/ulp/LanguageProfileAnalyzer.java
+++ b/java/src/com/android/textclassifier/ulp/LanguageProfileAnalyzer.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2018 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -19,21 +19,17 @@
 import android.content.Context;
 import android.util.ArrayMap;
 import android.view.textclassifier.TextClassifierEvent;
-
 import androidx.annotation.FloatRange;
-import androidx.annotation.NonNull;
-
 import com.android.textclassifier.Entity;
 import com.android.textclassifier.TcLog;
 import com.android.textclassifier.TextClassificationConstants;
 import com.android.textclassifier.ulp.database.LanguageProfileDatabase;
 import com.android.textclassifier.ulp.database.LanguageSignalInfo;
 import com.android.textclassifier.utils.IndentingPrintWriter;
-
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableList;
 import com.google.common.util.concurrent.MoreExecutors;
-
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
@@ -51,188 +47,177 @@
  * blocking operations and should be called on the worker thread.
  */
 public class LanguageProfileAnalyzer {
-    private final Context mContext;
-    private final TextClassificationConstants mTextClassificationConstants;
-    private final LanguageProfileDatabase mLanguageProfileDatabase;
-    private final LanguageProficiencyAnalyzer mProficiencyAnalyzer;
-    private final LocationSignalProvider mLocationSignalProvider;
-    private final SystemLanguagesProvider mSystemLanguagesProvider;
+  private final Context context;
+  private final TextClassificationConstants textClassificationConstants;
+  private final LanguageProfileDatabase languageProfileDatabase;
+  private final LanguageProficiencyAnalyzer proficiencyAnalyzer;
+  private final LocationSignalProvider locationSignalProvider;
+  private final SystemLanguagesProvider systemLanguagesProvider;
 
-    @VisibleForTesting
-    LanguageProfileAnalyzer(
-            Context context,
-            TextClassificationConstants textClassificationConstants,
-            LanguageProfileDatabase database,
-            LanguageProficiencyAnalyzer languageProficiencyAnalyzer,
-            LocationSignalProvider locationSignalProvider,
-            SystemLanguagesProvider systemLanguagesProvider) {
-        mContext = context;
-        mTextClassificationConstants = textClassificationConstants;
-        mLanguageProfileDatabase = Preconditions.checkNotNull(database);
-        mProficiencyAnalyzer = Preconditions.checkNotNull(languageProficiencyAnalyzer);
-        mLocationSignalProvider = Preconditions.checkNotNull(locationSignalProvider);
-        mSystemLanguagesProvider = Preconditions.checkNotNull(systemLanguagesProvider);
+  @VisibleForTesting
+  LanguageProfileAnalyzer(
+      Context context,
+      TextClassificationConstants textClassificationConstants,
+      LanguageProfileDatabase database,
+      LanguageProficiencyAnalyzer languageProficiencyAnalyzer,
+      LocationSignalProvider locationSignalProvider,
+      SystemLanguagesProvider systemLanguagesProvider) {
+    this.context = context;
+    this.textClassificationConstants = textClassificationConstants;
+    languageProfileDatabase = Preconditions.checkNotNull(database);
+    proficiencyAnalyzer = Preconditions.checkNotNull(languageProficiencyAnalyzer);
+    this.locationSignalProvider = Preconditions.checkNotNull(locationSignalProvider);
+    this.systemLanguagesProvider = Preconditions.checkNotNull(systemLanguagesProvider);
+  }
+
+  /** Creates an instance of {@link LanguageProfileAnalyzer}. */
+  public static LanguageProfileAnalyzer create(
+      Context context, TextClassificationConstants textClassificationConstants) {
+    SystemLanguagesProvider systemLanguagesProvider = new SystemLanguagesProvider();
+    LocationSignalProvider locationSignalProvider = new LocationSignalProvider(context);
+    return new LanguageProfileAnalyzer(
+        context,
+        textClassificationConstants,
+        LanguageProfileDatabase.getInstance(context),
+        new ReinforcementLanguageProficiencyAnalyzer(context, systemLanguagesProvider),
+        locationSignalProvider,
+        systemLanguagesProvider);
+  }
+
+  /**
+   * Returns the confidence score for which the user understands the given language. The result is
+   * recalculated every constant time.
+   *
+   * <p>The score ranges from 0 to 1. 1 indicates the language is very familiar to the user and vice
+   * versa.
+   */
+  @FloatRange(from = 0.0, to = 1.0)
+  public float canUnderstand(String languageTag) {
+    return proficiencyAnalyzer.canUnderstand(languageTag);
+  }
+
+  /** Decides whether we should show translation for that language or no. */
+  public boolean shouldShowTranslation(String languageTag) {
+    return proficiencyAnalyzer.shouldShowTranslation(languageTag);
+  }
+
+  /** Performs actions defined for specific TextClassification events. */
+  public void onTextClassifierEven(TextClassifierEvent event) {
+    proficiencyAnalyzer.onTextClassifierEvent(event);
+  }
+
+  /**
+   * Returns a list of languages that appear in the specified source, the list is sorted by the
+   * frequency descendingly. The confidence score represents how frequent of the language is,
+   * compared to the most frequent language.
+   */
+  public List<Entity> getFrequentLanguages(@LanguageSignalInfo.Source int source) {
+    List<LanguageSignalInfo> languageSignalInfos =
+        languageProfileDatabase.languageInfoDao().getBySource(source);
+    int bootstrappingCount = textClassificationConstants.getFrequentLanguagesBootstrappingCount();
+    ArrayMap<String, Integer> languageCountMap = new ArrayMap<>();
+    systemLanguagesProvider
+        .getSystemLanguageTags()
+        .forEach(lang -> languageCountMap.put(lang, bootstrappingCount));
+    String languageTagFromLocation = locationSignalProvider.detectLanguageTag();
+    if (languageTagFromLocation != null) {
+      languageCountMap.put(
+          languageTagFromLocation,
+          languageCountMap.getOrDefault(languageTagFromLocation, 0) + bootstrappingCount);
     }
-
-    /** Creates an instance of {@link LanguageProfileAnalyzer}. */
-    public static LanguageProfileAnalyzer create(
-            Context context, TextClassificationConstants textClassificationConstants) {
-        SystemLanguagesProvider systemLanguagesProvider = new SystemLanguagesProvider();
-        LocationSignalProvider locationSignalProvider = new LocationSignalProvider(context);
-        return new LanguageProfileAnalyzer(
-                context,
-                textClassificationConstants,
-                LanguageProfileDatabase.getInstance(context),
-                new ReinforcementLanguageProficiencyAnalyzer(context, systemLanguagesProvider),
-                locationSignalProvider,
-                systemLanguagesProvider);
+    for (LanguageSignalInfo languageSignalInfo : languageSignalInfos) {
+      String lang = languageSignalInfo.getLanguageTag();
+      languageCountMap.put(
+          lang, languageSignalInfo.getCount() + languageCountMap.getOrDefault(lang, 0));
     }
-
-    /**
-     * Returns the confidence score for which the user understands the given language. The result is
-     * recalculated every constant time.
-     *
-     * <p>The score ranges from 0 to 1. 1 indicates the language is very familiar to the user and
-     * vice versa.
-     */
-    @FloatRange(from = 0.0, to = 1.0)
-    public float canUnderstand(String languageTag) {
-        return mProficiencyAnalyzer.canUnderstand(languageTag);
+    int max = Collections.max(languageCountMap.values());
+    if (max == 0) {
+      return ImmutableList.of();
     }
-
-    /** Decides whether we should show translation for that language or no. */
-    public boolean shouldShowTranslation(String languageTag) {
-        return mProficiencyAnalyzer.shouldShowTranslation(languageTag);
+    List<Entity> frequentLanguages = new ArrayList<>();
+    for (int i = 0; i < languageCountMap.size(); i++) {
+      String lang = languageCountMap.keyAt(i);
+      float score = languageCountMap.valueAt(i) / (float) max;
+      frequentLanguages.add(new Entity(lang, score));
     }
+    Collections.sort(frequentLanguages);
+    return ImmutableList.copyOf(frequentLanguages);
+  }
 
-    /** Performs actions defined for specific TextClassification events. */
-    public void onTextClassifierEven(TextClassifierEvent event) {
-        mProficiencyAnalyzer.onTextClassifierEvent(event);
+  /** Dumps the data on the screen when called. */
+  public void dump(IndentingPrintWriter printWriter) {
+    printWriter.println("LanguageProfileAnalyzer:");
+    printWriter.increaseIndent();
+    printWriter.printPair(
+        "System languages", String.join(",", systemLanguagesProvider.getSystemLanguageTags()));
+    printWriter.printPair(
+        "Language code deduced from location", locationSignalProvider.detectLanguageTag());
+
+    ExecutorService executorService =
+        MoreExecutors.listeningDecorator(Executors.newSingleThreadExecutor());
+    try {
+      executorService
+          .submit(
+              () -> {
+                printWriter.println("Languages that user has seen in selections:");
+                dumpFrequentLanguages(printWriter, LanguageSignalInfo.CLASSIFY_TEXT);
+
+                printWriter.println("Languages that user has seen in message notifications:");
+                dumpFrequentLanguages(printWriter, LanguageSignalInfo.SUGGEST_CONVERSATION_ACTIONS);
+
+                dumpEvaluationReport(printWriter);
+              })
+          .get();
+    } catch (ExecutionException | InterruptedException e) {
+      TcLog.e(TcLog.TAG, "Dumping interrupted: ", e);
     }
+    printWriter.decreaseIndent();
+  }
 
-    /**
-     * Returns a list of languages that appear in the specified source, the list is sorted by the
-     * frequency descendingly. The confidence score represents how frequent of the language is,
-     * compared to the most frequent language.
-     */
-    @NonNull
-    public List<Entity> getFrequentLanguages(@LanguageSignalInfo.Source int source) {
-        List<LanguageSignalInfo> languageSignalInfos =
-                mLanguageProfileDatabase.languageInfoDao().getBySource(source);
-        int bootstrappingCount =
-                mTextClassificationConstants.getFrequentLanguagesBootstrappingCount();
-        ArrayMap<String, Integer> languageCountMap = new ArrayMap<>();
-        mSystemLanguagesProvider
-                .getSystemLanguageTags()
-                .forEach(lang -> languageCountMap.put(lang, bootstrappingCount));
-        String languageTagFromLocation = mLocationSignalProvider.detectLanguageTag();
-        if (languageTagFromLocation != null) {
-            languageCountMap.put(
-                    languageTagFromLocation,
-                    languageCountMap.getOrDefault(languageTagFromLocation, 0) + bootstrappingCount);
-        }
-        for (LanguageSignalInfo languageSignalInfo : languageSignalInfos) {
-            String lang = languageSignalInfo.getLanguageTag();
-            languageCountMap.put(
-                    lang, languageSignalInfo.getCount() + languageCountMap.getOrDefault(lang, 0));
-        }
-        int max = Collections.max(languageCountMap.values());
-        if (max == 0) {
-            return Collections.emptyList();
-        }
-        List<Entity> frequentLanguages = new ArrayList<>();
-        for (int i = 0; i < languageCountMap.size(); i++) {
-            String lang = languageCountMap.keyAt(i);
-            float score = languageCountMap.valueAt(i) / (float) max;
-            frequentLanguages.add(new Entity(lang, score));
-        }
-        Collections.sort(frequentLanguages);
-        return frequentLanguages;
+  private void dumpEvaluationReport(IndentingPrintWriter printWriter) {
+    List<String> systemLanguageTags = systemLanguagesProvider.getSystemLanguageTags();
+    if (systemLanguageTags.size() <= 1) {
+      printWriter.println("Skipped evaluation as there are less than two system languages.");
+      return;
     }
-
-    /** Dumps the data on the screen when called. */
-    public void dump(IndentingPrintWriter printWriter) {
-        printWriter.println("LanguageProfileAnalyzer:");
-        printWriter.increaseIndent();
-        printWriter.printPair(
-                "System languages",
-                String.join(",", mSystemLanguagesProvider.getSystemLanguageTags()));
-        printWriter.printPair(
-                "Language code deduced from location", mLocationSignalProvider.detectLanguageTag());
-
-        ExecutorService executorService =
-                MoreExecutors.listeningDecorator(Executors.newSingleThreadExecutor());
-        try {
-            executorService
-                    .submit(
-                            () -> {
-                                printWriter.println("Languages that user has seen in selections:");
-                                dumpFrequentLanguages(
-                                        printWriter, LanguageSignalInfo.CLASSIFY_TEXT);
-
-                                printWriter.println(
-                                        "Languages that user has seen in message notifications:");
-                                dumpFrequentLanguages(
-                                        printWriter,
-                                        LanguageSignalInfo.SUGGEST_CONVERSATION_ACTIONS);
-
-                                dumpEvaluationReport(printWriter);
-                            })
-                    .get();
-        } catch (ExecutionException | InterruptedException e) {
-            TcLog.e(TcLog.TAG, "Dumping interrupted: ", e);
-        }
-        printWriter.decreaseIndent();
+    Set<String> languagesToEvaluate =
+        languageProfileDatabase.languageInfoDao().getAll().stream()
+            .map(LanguageSignalInfo::getLanguageTag)
+            .collect(Collectors.toSet());
+    languagesToEvaluate.addAll(systemLanguageTags);
+    LanguageProficiencyEvaluator evaluator =
+        new LanguageProficiencyEvaluator(systemLanguagesProvider);
+    LanguageProficiencyAnalyzer[] analyzers =
+        new LanguageProficiencyAnalyzer[] {
+          new BasicLanguageProficiencyAnalyzer(
+              context, textClassificationConstants, systemLanguagesProvider),
+          new KmeansLanguageProficiencyAnalyzer(
+              context, textClassificationConstants, systemLanguagesProvider),
+          proficiencyAnalyzer
+        };
+    for (LanguageProficiencyAnalyzer analyzer : analyzers) {
+      LanguageProficiencyEvaluator.EvaluationResult result =
+          evaluator.evaluate(analyzer, languagesToEvaluate);
+      printWriter.println("Evaluation result of " + analyzer.getClass().getSimpleName());
+      printWriter.increaseIndent();
+      printWriter.printPair(
+          "Precision of positive class", result.computePrecisionOfPositiveClass());
+      printWriter.printPair(
+          "Precision of negative class", result.computePrecisionOfNegativeClass());
+      printWriter.printPair("Recall of positive class", result.computeRecallOfPositiveClass());
+      printWriter.printPair("Recall of negative class", result.computeRecallOfNegativeClass());
+      printWriter.printPair("F1 score of positive class", result.computeF1ScoreOfPositiveClass());
+      printWriter.printPair("F1 score of negative class", result.computeF1ScoreOfNegativeClass());
+      printWriter.decreaseIndent();
     }
+  }
 
-    private void dumpEvaluationReport(IndentingPrintWriter printWriter) {
-        List<String> systemLanguageTags = mSystemLanguagesProvider.getSystemLanguageTags();
-        if (systemLanguageTags.size() <= 1) {
-            printWriter.println("Skipped evaluation as there are less than two system languages.");
-            return;
-        }
-        Set<String> languagesToEvaluate =
-                mLanguageProfileDatabase.languageInfoDao().getAll().stream()
-                        .map(LanguageSignalInfo::getLanguageTag)
-                        .collect(Collectors.toSet());
-        languagesToEvaluate.addAll(systemLanguageTags);
-        LanguageProficiencyEvaluator evaluator =
-                new LanguageProficiencyEvaluator(mSystemLanguagesProvider);
-        LanguageProficiencyAnalyzer[] analyzers =
-                new LanguageProficiencyAnalyzer[] {
-                    new BasicLanguageProficiencyAnalyzer(
-                            mContext, mTextClassificationConstants, mSystemLanguagesProvider),
-                    new KmeansLanguageProficiencyAnalyzer(
-                            mContext, mTextClassificationConstants, mSystemLanguagesProvider),
-                    mProficiencyAnalyzer
-                };
-        for (LanguageProficiencyAnalyzer analyzer : analyzers) {
-            LanguageProficiencyEvaluator.EvaluationResult result =
-                    evaluator.evaluate(analyzer, languagesToEvaluate);
-            printWriter.println("Evaluation result of " + analyzer.getClass().getSimpleName());
-            printWriter.increaseIndent();
-            printWriter.printPair(
-                    "Precision of positive class", result.computePrecisionOfPositiveClass());
-            printWriter.printPair(
-                    "Precision of negative class", result.computePrecisionOfNegativeClass());
-            printWriter.printPair(
-                    "Recall of positive class", result.computeRecallOfPositiveClass());
-            printWriter.printPair(
-                    "Recall of negative class", result.computeRecallOfNegativeClass());
-            printWriter.printPair(
-                    "F1 score of positive class", result.computeF1ScoreOfPositiveClass());
-            printWriter.printPair(
-                    "F1 score of negative class", result.computeF1ScoreOfNegativeClass());
-            printWriter.decreaseIndent();
-        }
+  private void dumpFrequentLanguages(
+      IndentingPrintWriter printWriter, @LanguageSignalInfo.Source int source) {
+    printWriter.increaseIndent();
+    for (Entity frequentLanguage : getFrequentLanguages(source)) {
+      printWriter.println(frequentLanguage.toString());
     }
-
-    private void dumpFrequentLanguages(
-            IndentingPrintWriter printWriter, @LanguageSignalInfo.Source int source) {
-        printWriter.increaseIndent();
-        for (Entity frequentLanguage : getFrequentLanguages(source)) {
-            printWriter.println(frequentLanguage.toString());
-        }
-        printWriter.decreaseIndent();
-    }
+    printWriter.decreaseIndent();
+  }
 }
diff --git a/java/src/com/android/textclassifier/ulp/LanguageProfileUpdater.java b/java/src/com/android/textclassifier/ulp/LanguageProfileUpdater.java
index 55ba729..56f878f 100644
--- a/java/src/com/android/textclassifier/ulp/LanguageProfileUpdater.java
+++ b/java/src/com/android/textclassifier/ulp/LanguageProfileUpdater.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2018 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -19,158 +19,154 @@
 import android.content.Context;
 import android.util.LruCache;
 import android.view.textclassifier.ConversationActions;
-
-import androidx.annotation.VisibleForTesting;
-
 import com.android.textclassifier.TcLog;
 import com.android.textclassifier.ulp.database.LanguageProfileDatabase;
 import com.android.textclassifier.ulp.database.LanguageSignalInfo;
 import com.android.textclassifier.utils.IndentingPrintWriter;
-
+import com.google.common.annotations.VisibleForTesting;
 import com.google.common.util.concurrent.FutureCallback;
 import com.google.common.util.concurrent.Futures;
 import com.google.common.util.concurrent.ListenableFuture;
 import com.google.common.util.concurrent.ListeningExecutorService;
 import com.google.common.util.concurrent.MoreExecutors;
-
+import com.google.errorprone.annotations.CanIgnoreReturnValue;
 import java.time.Instant;
-import java.time.OffsetDateTime;
 import java.util.List;
 import java.util.Map;
 import java.util.concurrent.Callable;
 import java.util.function.Function;
-
 import javax.annotation.Nullable;
 
 /** Class implementing functions which builds and updates user language profile. */
 public class LanguageProfileUpdater {
-    private static final String TAG = "LanguageProfileUpdater";
-    private static final int MAX_CACHE_SIZE = 20;
-    private static final String DEFAULT_NOTIFICATION_KEY = "DEFAULT_KEY";
+  private static final String TAG = "LanguageProfileUpdater";
+  private static final int MAX_CACHE_SIZE = 20;
+  private static final String DEFAULT_NOTIFICATION_KEY = "DEFAULT_KEY";
 
-    static final String NOTIFICATION_KEY = "notificationKey";
+  static final String NOTIFICATION_KEY = "notificationKey";
 
-    private final LanguageProfileDatabase mLanguageProfileDatabase;
-    private final ListeningExecutorService mExecutorService;
-    private final LruCache<String, Long> mUpdatedNotifications = new LruCache<>(MAX_CACHE_SIZE);
+  private final LanguageProfileDatabase languageProfileDatabase;
+  private final ListeningExecutorService executorService;
+  private final LruCache<String, Long> updatedNotifications = new LruCache<>(MAX_CACHE_SIZE);
 
-    public LanguageProfileUpdater(Context context, ListeningExecutorService executorService) {
-        mLanguageProfileDatabase = LanguageProfileDatabase.getInstance(context);
-        mExecutorService = executorService;
-    }
+  public LanguageProfileUpdater(Context context, ListeningExecutorService executorService) {
+    languageProfileDatabase = LanguageProfileDatabase.getInstance(context);
+    this.executorService = executorService;
+  }
 
-    @VisibleForTesting
-    LanguageProfileUpdater(
-            ListeningExecutorService executorService, LanguageProfileDatabase database) {
-        mLanguageProfileDatabase = database;
-        mExecutorService = executorService;
-    }
+  @VisibleForTesting
+  LanguageProfileUpdater(
+      ListeningExecutorService executorService, LanguageProfileDatabase database) {
+    languageProfileDatabase = database;
+    this.executorService = executorService;
+  }
 
-    /** Updates counts of languages found in suggestConversationActions. */
-    public ListenableFuture<Void> updateFromConversationActionsAsync(
-            ConversationActions.Request request,
-            Function<CharSequence, List<String>> languageDetector) {
-        return runAsync(
-                () -> {
-                    ConversationActions.Message msg = getMessageFromRequest(request);
-                    if (msg == null) {
-                        return null;
-                    }
-                    List<String> languageTags = languageDetector.apply(msg.getText().toString());
-                    String notificationKey =
-                            request.getExtras()
-                                    .getString(NOTIFICATION_KEY, DEFAULT_NOTIFICATION_KEY);
-                    Long messageReferenceTime = getMessageReferenceTime(msg);
-                    if (isNewMessage(notificationKey, messageReferenceTime)) {
-                        for (String tag : languageTags) {
-                            increaseSignalCountInDatabase(
-                                    tag, LanguageSignalInfo.SUGGEST_CONVERSATION_ACTIONS, 1);
-                        }
-                    }
-                    return null;
-                });
-    }
-
-    /** Updates counts of languages found in classifyText. */
-    public ListenableFuture<Void> updateFromClassifyTextAsync(List<String> detectedLanguageTags) {
-        return runAsync(
-                () -> {
-                    for (String languageTag : detectedLanguageTags) {
-                        increaseSignalCountInDatabase(
-                                languageTag, LanguageSignalInfo.CLASSIFY_TEXT, /* increment= */ 1);
-                    }
-                    return null;
-                });
-    }
-
-    /** Runs the specified callable asynchronously and prints the stack trace if it failed. */
-    private <T> ListenableFuture<T> runAsync(Callable<T> callable) {
-        ListenableFuture<T> future = mExecutorService.submit(callable);
-        Futures.addCallback(
-                future,
-                new FutureCallback<T>() {
-                    @Override
-                    public void onSuccess(T result) {}
-
-                    @Override
-                    public void onFailure(Throwable t) {
-                        TcLog.e(TAG, "runAsync", t);
-                    }
-                },
-                MoreExecutors.directExecutor());
-        return future;
-    }
-
-    private void increaseSignalCountInDatabase(
-            String languageTag, @LanguageSignalInfo.Source int sourceType, int increment) {
-        mLanguageProfileDatabase
-                .languageInfoDao()
-                .increaseSignalCount(languageTag, sourceType, increment);
-    }
-
-    @Nullable
-    private ConversationActions.Message getMessageFromRequest(ConversationActions.Request request) {
-        int size = request.getConversation().size();
-        if (size == 0) {
+  /** Updates counts of languages found in suggestConversationActions. */
+  @CanIgnoreReturnValue
+  public ListenableFuture<Void> updateFromConversationActionsAsync(
+      ConversationActions.Request request, Function<CharSequence, List<String>> languageDetector) {
+    return runAsync(
+        () -> {
+          ConversationActions.Message msg = getMessageFromRequest(request);
+          if (msg == null) {
             return null;
-        }
-        return request.getConversation().get(size - 1);
-    }
+          }
+          List<String> languageTags = languageDetector.apply(msg.getText().toString());
+          String notificationKey =
+              request.getExtras().getString(NOTIFICATION_KEY, DEFAULT_NOTIFICATION_KEY);
+          Long messageReferenceTime = getMessageReferenceTime(msg);
+          if (isNewMessage(notificationKey, messageReferenceTime)) {
+            for (String tag : languageTags) {
+              increaseSignalCountInDatabase(
+                  tag, LanguageSignalInfo.SUGGEST_CONVERSATION_ACTIONS, 1);
+            }
+          }
+          return null;
+        });
+  }
 
-    private boolean isNewMessage(String notificationKey, Long sendTime) {
-        Long oldTime = mUpdatedNotifications.get(notificationKey);
+  /** Updates counts of languages found in classifyText. */
+  @CanIgnoreReturnValue
+  public ListenableFuture<Void> updateFromClassifyTextAsync(List<String> detectedLanguageTags) {
+    return runAsync(
+        () -> {
+          for (String languageTag : detectedLanguageTags) {
+            increaseSignalCountInDatabase(
+                languageTag, LanguageSignalInfo.CLASSIFY_TEXT, /* increment= */ 1);
+          }
+          return null;
+        });
+  }
 
-        if (oldTime == null || sendTime > oldTime) {
-            mUpdatedNotifications.put(notificationKey, sendTime);
-            return true;
-        }
-        return false;
-    }
+  /** Runs the specified callable asynchronously and prints the stack trace if it failed. */
+  private <T> ListenableFuture<T> runAsync(Callable<T> callable) {
+    ListenableFuture<T> future = executorService.submit(callable);
+    Futures.addCallback(
+        future,
+        new FutureCallback<T>() {
+          @Override
+          public void onSuccess(T result) {}
 
-    private long getMessageReferenceTime(ConversationActions.Message msg) {
-        return msg.getReferenceTime() == null
-                ? OffsetDateTime.now().toInstant().toEpochMilli()
-                : msg.getReferenceTime().toInstant().toEpochMilli();
-    }
+          @Override
+          public void onFailure(Throwable t) {
+            TcLog.e(TAG, "runAsync", t);
+          }
+        },
+        MoreExecutors.directExecutor());
+    return future;
+  }
 
-    /** Dumps the data on the screen when called. */
-    public void dump(IndentingPrintWriter printWriter) {
-        printWriter.println("LanguageProfileUpdater:");
-        printWriter.increaseIndent();
-        printWriter.println("Cache for notifications status:");
-        printWriter.increaseIndent();
-        for (Map.Entry<String, Long> entry : mUpdatedNotifications.snapshot().entrySet()) {
-            long timestamp = entry.getValue();
-            printWriter.println(
-                    "Notification key: "
-                            + entry.getKey()
-                            + " time: "
-                            + timestamp
-                            + " ("
-                            + Instant.ofEpochMilli(timestamp).toString()
-                            + ")");
-        }
-        printWriter.decreaseIndent();
-        printWriter.decreaseIndent();
+  private void increaseSignalCountInDatabase(
+      String languageTag, @LanguageSignalInfo.Source int sourceType, int increment) {
+    languageProfileDatabase
+        .languageInfoDao()
+        .increaseSignalCount(languageTag, sourceType, increment);
+  }
+
+  @Nullable
+  private static ConversationActions.Message getMessageFromRequest(
+      ConversationActions.Request request) {
+    int size = request.getConversation().size();
+    if (size == 0) {
+      return null;
     }
+    return request.getConversation().get(size - 1);
+  }
+
+  private boolean isNewMessage(String notificationKey, Long sendTime) {
+    Long oldTime = updatedNotifications.get(notificationKey);
+
+    if (oldTime == null || sendTime > oldTime) {
+      updatedNotifications.put(notificationKey, sendTime);
+      return true;
+    }
+    return false;
+  }
+
+  private static long getMessageReferenceTime(ConversationActions.Message msg) {
+    return msg.getReferenceTime() == null
+        ? Instant.now().toEpochMilli()
+        : msg.getReferenceTime().toInstant().toEpochMilli();
+  }
+
+  /** Dumps the data on the screen when called. */
+  public void dump(IndentingPrintWriter printWriter) {
+    printWriter.println("LanguageProfileUpdater:");
+    printWriter.increaseIndent();
+    printWriter.println("Cache for notifications status:");
+    printWriter.increaseIndent();
+    for (Map.Entry<String, Long> entry : updatedNotifications.snapshot().entrySet()) {
+      long timestamp = entry.getValue();
+      printWriter.println(
+          "Notification key: "
+              + entry.getKey()
+              + " time: "
+              + timestamp
+              + " ("
+              + Instant.ofEpochMilli(timestamp).toString()
+              + ")");
+    }
+    printWriter.decreaseIndent();
+    printWriter.decreaseIndent();
+  }
 }
diff --git a/java/src/com/android/textclassifier/ulp/LocationSignalProvider.java b/java/src/com/android/textclassifier/ulp/LocationSignalProvider.java
index c3ad77a..8b678b9 100644
--- a/java/src/com/android/textclassifier/ulp/LocationSignalProvider.java
+++ b/java/src/com/android/textclassifier/ulp/LocationSignalProvider.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2018 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -23,103 +23,99 @@
 import android.location.Location;
 import android.location.LocationManager;
 import android.telephony.TelephonyManager;
-
-import androidx.annotation.Nullable;
-
 import com.android.textclassifier.TcLog;
-
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Preconditions;
-
 import java.io.IOException;
 import java.util.List;
 import java.util.concurrent.TimeUnit;
+import javax.annotation.Nullable;
 
 final class LocationSignalProvider {
-    private static final String TAG = "LocationSignalProvider";
+  private static final String TAG = "LocationSignalProvider";
 
-    private static final long EXPIRATION_TIME = TimeUnit.DAYS.toMillis(1);
-    private final LocationManager mLocationManager;
-    private final TelephonyManager mTelephonyManager;
-    private final Geocoder mGeocoder;
-    private final Object mLock = new Object();
+  private static final long EXPIRATION_TIME = TimeUnit.DAYS.toMillis(1);
+  private final LocationManager locationManager;
+  private final TelephonyManager telephonyManager;
+  private final Geocoder geocoder;
+  private final Object lock = new Object();
 
-    private String mCachedLanguageTag = null;
-    private long mLastModifiedTime;
+  private String cachedLanguageTag = null;
+  private long lastModifiedTime;
 
-    LocationSignalProvider(Context context) {
-        this(
-                context.getSystemService(LocationManager.class),
-                context.getSystemService(TelephonyManager.class),
-                new Geocoder(context));
+  LocationSignalProvider(Context context) {
+    this(
+        context.getSystemService(LocationManager.class),
+        context.getSystemService(TelephonyManager.class),
+        new Geocoder(context));
+  }
+
+  @VisibleForTesting
+  LocationSignalProvider(
+      LocationManager locationManager, TelephonyManager telephonyManager, Geocoder geocoder) {
+    this.locationManager = Preconditions.checkNotNull(locationManager);
+    this.telephonyManager = Preconditions.checkNotNull(telephonyManager);
+    this.geocoder = Preconditions.checkNotNull(geocoder);
+  }
+
+  /**
+   * Deduces the language by using user's current location as a signal and returns a BCP 47 language
+   * code.
+   */
+  @Nullable
+  String detectLanguageTag() {
+    synchronized (lock) {
+      if ((System.currentTimeMillis() - lastModifiedTime) < EXPIRATION_TIME) {
+        return cachedLanguageTag;
+      }
+      cachedLanguageTag = detectLanguageCodeInternal();
+      lastModifiedTime = System.currentTimeMillis();
+      return cachedLanguageTag;
     }
+  }
 
-    @VisibleForTesting
-    LocationSignalProvider(
-            LocationManager locationManager, TelephonyManager telephonyManager, Geocoder geocoder) {
-        mLocationManager = Preconditions.checkNotNull(locationManager);
-        mTelephonyManager = Preconditions.checkNotNull(telephonyManager);
-        mGeocoder = Preconditions.checkNotNull(geocoder);
+  @Nullable
+  private String detectLanguageCodeInternal() {
+    String currentCountryCode = detectCurrentCountryCode();
+    if (currentCountryCode == null) {
+      return null;
     }
+    return toLanguageTag(currentCountryCode);
+  }
 
-    /**
-     * Deduces the language by using user's current location as a signal and returns a BCP 47
-     * language code.
-     */
-    @Nullable
-    String detectLanguageTag() {
-        synchronized (mLock) {
-            if ((System.currentTimeMillis() - mLastModifiedTime) < EXPIRATION_TIME) {
-                return mCachedLanguageTag;
-            }
-            mCachedLanguageTag = detectLanguageCodeInternal();
-            mLastModifiedTime = System.currentTimeMillis();
-            return mCachedLanguageTag;
-        }
+  @Nullable
+  private String detectCurrentCountryCode() {
+    String networkCountryCode = telephonyManager.getNetworkCountryIso();
+    if (networkCountryCode != null) {
+      return networkCountryCode;
     }
+    return detectCurrentCountryFromLocationManager();
+  }
 
-    @Nullable
-    private String detectLanguageCodeInternal() {
-        String currentCountryCode = detectCurrentCountryCode();
-        if (currentCountryCode == null) {
-            return null;
-        }
-        return toLanguageTag(currentCountryCode);
+  @Nullable
+  private String detectCurrentCountryFromLocationManager() {
+    Location location = locationManager.getLastKnownLocation(LocationManager.PASSIVE_PROVIDER);
+    if (location == null) {
+      return null;
     }
+    try {
+      List<Address> addresses =
+          geocoder.getFromLocation(
+              location.getLatitude(), location.getLongitude(), /*maxResults=*/ 1);
+      if (addresses != null && !addresses.isEmpty()) {
+        return addresses.get(0).getCountryCode();
+      }
+    } catch (IOException e) {
+      TcLog.e(TAG, "Failed to call getFromLocation: ", e);
+      return null;
+    }
+    return null;
+  }
 
-    @Nullable
-    private String detectCurrentCountryCode() {
-        String networkCountryCode = mTelephonyManager.getNetworkCountryIso();
-        if (networkCountryCode != null) {
-            return networkCountryCode;
-        }
-        return detectCurrentCountryFromLocationManager();
-    }
-
-    @Nullable
-    private String detectCurrentCountryFromLocationManager() {
-        Location location = mLocationManager.getLastKnownLocation(LocationManager.PASSIVE_PROVIDER);
-        if (location == null) {
-            return null;
-        }
-        try {
-            List<Address> addresses =
-                    mGeocoder.getFromLocation(
-                            location.getLatitude(), location.getLongitude(), /*maxResults=*/ 1);
-            if (addresses != null && !addresses.isEmpty()) {
-                return addresses.get(0).getCountryCode();
-            }
-        } catch (IOException e) {
-            TcLog.e(TAG, "Failed to call getFromLocation: ", e);
-            return null;
-        }
-        return null;
-    }
-
-    @Nullable
-    private static String toLanguageTag(String countryTag) {
-        ULocale locale = new ULocale.Builder().setRegion(countryTag).build();
-        locale = ULocale.addLikelySubtags(locale);
-        return locale.getLanguage();
-    }
+  @Nullable
+  private static String toLanguageTag(String countryTag) {
+    ULocale locale = new ULocale.Builder().setRegion(countryTag).build();
+    locale = ULocale.addLikelySubtags(locale);
+    return locale.getLanguage();
+  }
 }
diff --git a/java/src/com/android/textclassifier/ulp/ReinforcementLanguageProficiencyAnalyzer.java b/java/src/com/android/textclassifier/ulp/ReinforcementLanguageProficiencyAnalyzer.java
index 851e81b..d23be60 100644
--- a/java/src/com/android/textclassifier/ulp/ReinforcementLanguageProficiencyAnalyzer.java
+++ b/java/src/com/android/textclassifier/ulp/ReinforcementLanguageProficiencyAnalyzer.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2018 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -19,12 +19,9 @@
 import android.content.Context;
 import android.content.SharedPreferences;
 import android.view.textclassifier.TextClassifierEvent;
-
 import com.android.textclassifier.TcLog;
-
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Preconditions;
-
 import org.json.JSONException;
 import org.json.JSONObject;
 
@@ -37,159 +34,159 @@
  * translation action in the future.
  */
 class ReinforcementLanguageProficiencyAnalyzer implements LanguageProficiencyAnalyzer {
-    private static final String TAG = "ReinforcementAnalyzer";
-    private static final String PREF_NAME = "ulp-reinforcement-analyzer";
-    private static final float SHOW_TRANSLATE_ACTION_THRESHOLD = 0.9f;
-    private static final int MIN_NUM_TRANSLATE_SHOWN_TO_BE_CONFIDENT = 30;
+  private static final String TAG = "ReinforcementAnalyzer";
+  private static final String PREF_NAME = "ulp-reinforcement-analyzer";
+  private static final float SHOW_TRANSLATE_ACTION_THRESHOLD = 0.9f;
+  private static final int MIN_NUM_TRANSLATE_SHOWN_TO_BE_CONFIDENT = 30;
 
-    private final SystemLanguagesProvider mSystemLanguagesProvider;
-    private final SharedPreferences mSharedPreferences;
+  private final SystemLanguagesProvider systemLanguagesProvider;
+  private final SharedPreferences sharedPreferences;
 
-    ReinforcementLanguageProficiencyAnalyzer(
-            Context context, SystemLanguagesProvider systemLanguagesProvider) {
-        Preconditions.checkNotNull(context);
-        mSystemLanguagesProvider = Preconditions.checkNotNull(systemLanguagesProvider);
-        mSharedPreferences = context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE);
+  ReinforcementLanguageProficiencyAnalyzer(
+      Context context, SystemLanguagesProvider systemLanguagesProvider) {
+    Preconditions.checkNotNull(context);
+    this.systemLanguagesProvider = Preconditions.checkNotNull(systemLanguagesProvider);
+    sharedPreferences = context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE);
+  }
+
+  @VisibleForTesting
+  ReinforcementLanguageProficiencyAnalyzer(
+      SystemLanguagesProvider systemLanguagesProvider, SharedPreferences sharedPreferences) {
+    this.systemLanguagesProvider = Preconditions.checkNotNull(systemLanguagesProvider);
+    this.sharedPreferences = Preconditions.checkNotNull(sharedPreferences);
+  }
+
+  @Override
+  public float canUnderstand(String languageTag) {
+    TranslationStatistics translationStatistics =
+        TranslationStatistics.loadFromSharedPreference(sharedPreferences, languageTag);
+    if (translationStatistics.getShownCount() < MIN_NUM_TRANSLATE_SHOWN_TO_BE_CONFIDENT) {
+      return systemLanguagesProvider.getSystemLanguageTags().contains(languageTag) ? 1f : 0f;
+    }
+    return translationStatistics.getScore();
+  }
+
+  @Override
+  public boolean shouldShowTranslation(String languageTag) {
+    TranslationStatistics translationStatistics =
+        TranslationStatistics.loadFromSharedPreference(sharedPreferences, languageTag);
+    if (translationStatistics.getShownCount() < MIN_NUM_TRANSLATE_SHOWN_TO_BE_CONFIDENT) {
+      // Show translate action until we have enough feedback.
+      return true;
+    }
+    return translationStatistics.getScore() <= SHOW_TRANSLATE_ACTION_THRESHOLD;
+  }
+
+  @Override
+  public void onTextClassifierEvent(TextClassifierEvent event) {
+    if (event.getEventCategory() == TextClassifierEvent.CATEGORY_LANGUAGE_DETECTION) {
+      if (event.getEventType() == TextClassifierEvent.TYPE_SMART_ACTION
+          || event.getEventType() == TextClassifierEvent.TYPE_ACTIONS_SHOWN) {
+        onTranslateEvent(event);
+      }
+    }
+  }
+
+  private void onTranslateEvent(TextClassifierEvent event) {
+    if (event.getEntityTypes().length == 0) {
+      return;
+    }
+    String languageTag = event.getEntityTypes()[0];
+    // We only count the case that we show translate action in the prime position.
+    if (event.getActionIndices().length == 0 || event.getActionIndices()[0] != 0) {
+      return;
+    }
+    TranslationStatistics translationStatistics =
+        TranslationStatistics.loadFromSharedPreference(sharedPreferences, languageTag);
+    if (event.getEventType() == TextClassifierEvent.TYPE_ACTIONS_SHOWN) {
+      translationStatistics.increaseShownCountByOne();
+    } else if (event.getEventType() == TextClassifierEvent.TYPE_SMART_ACTION) {
+      translationStatistics.increaseClickedCountByOne();
+    }
+    translationStatistics.save(sharedPreferences, languageTag);
+  }
+
+  private static final class TranslationStatistics {
+    private static final String SEEN_COUNT = "seen_count";
+    private static final String CLICK_COUNT = "click_count";
+
+    private int shownCount;
+    private int clickCount;
+
+    private TranslationStatistics() {
+      this(/* seenCount= */ 0, /* clickCount= */ 0);
     }
 
-    @VisibleForTesting
-    ReinforcementLanguageProficiencyAnalyzer(
-            SystemLanguagesProvider systemLanguagesProvider, SharedPreferences sharedPreferences) {
-        mSystemLanguagesProvider = Preconditions.checkNotNull(systemLanguagesProvider);
-        mSharedPreferences = Preconditions.checkNotNull(sharedPreferences);
+    private TranslationStatistics(int seenCount, int clickCount) {
+      shownCount = seenCount;
+      this.clickCount = clickCount;
+    }
+
+    static TranslationStatistics loadFromSharedPreference(
+        SharedPreferences sharedPreferences, String languageTag) {
+      String serializedString = sharedPreferences.getString(languageTag, null);
+      return TranslationStatistics.fromSerializedString(serializedString);
+    }
+
+    void save(SharedPreferences sharedPreferences, String languageTag) {
+      // TODO: Consider to store it in a database.
+      sharedPreferences.edit().putString(languageTag, serializeToString()).apply();
+    }
+
+    private String serializeToString() {
+      try {
+        JSONObject jsonObject = new JSONObject();
+        jsonObject.put(SEEN_COUNT, shownCount);
+        jsonObject.put(CLICK_COUNT, clickCount);
+        return jsonObject.toString();
+      } catch (JSONException ex) {
+        TcLog.e(TAG, "serializeToString: ", ex);
+      }
+      return "";
+    }
+
+    void increaseShownCountByOne() {
+      shownCount += 1;
+    }
+
+    void increaseClickedCountByOne() {
+      clickCount += 1;
+    }
+
+    float getScore() {
+      if (shownCount == 0) {
+        return 0f;
+      }
+      return clickCount / (float) shownCount;
+    }
+
+    int getShownCount() {
+      return shownCount;
+    }
+
+    static TranslationStatistics fromSerializedString(String str) {
+      if (str == null) {
+        return new TranslationStatistics();
+      }
+      try {
+        JSONObject jsonObject = new JSONObject(str);
+        int seenCount = jsonObject.getInt(SEEN_COUNT);
+        int clickCount = jsonObject.getInt(CLICK_COUNT);
+        return new TranslationStatistics(seenCount, clickCount);
+      } catch (JSONException ex) {
+        TcLog.e(TAG, "Failed to parse " + str, ex);
+      }
+      return new TranslationStatistics();
     }
 
     @Override
-    public float canUnderstand(String languageTag) {
-        TranslationStatistics translationStatistics =
-                TranslationStatistics.loadFromSharedPreference(mSharedPreferences, languageTag);
-        if (translationStatistics.getShownCount() < MIN_NUM_TRANSLATE_SHOWN_TO_BE_CONFIDENT) {
-            return mSystemLanguagesProvider.getSystemLanguageTags().contains(languageTag) ? 1f : 0f;
-        }
-        return translationStatistics.getScore();
+    public String toString() {
+      return "TranslationStatistics{"
+          + "mShownCount="
+          + shownCount
+          + ", mClickCount="
+          + clickCount
+          + '}';
     }
-
-    @Override
-    public boolean shouldShowTranslation(String languageTag) {
-        TranslationStatistics translationStatistics =
-                TranslationStatistics.loadFromSharedPreference(mSharedPreferences, languageTag);
-        if (translationStatistics.getShownCount() < MIN_NUM_TRANSLATE_SHOWN_TO_BE_CONFIDENT) {
-            // Show translate action until we have enough feedback.
-            return true;
-        }
-        return translationStatistics.getScore() <= SHOW_TRANSLATE_ACTION_THRESHOLD;
-    }
-
-    @Override
-    public void onTextClassifierEvent(TextClassifierEvent event) {
-        if (event.getEventCategory() == TextClassifierEvent.CATEGORY_LANGUAGE_DETECTION) {
-            if (event.getEventType() == TextClassifierEvent.TYPE_SMART_ACTION
-                    || event.getEventType() == TextClassifierEvent.TYPE_ACTIONS_SHOWN) {
-                onTranslateEvent(event);
-            }
-        }
-    }
-
-    private void onTranslateEvent(TextClassifierEvent event) {
-        if (event.getEntityTypes().length == 0) {
-            return;
-        }
-        String languageTag = event.getEntityTypes()[0];
-        // We only count the case that we show translate action in the prime position.
-        if (event.getActionIndices().length == 0 || event.getActionIndices()[0] != 0) {
-            return;
-        }
-        TranslationStatistics translationStatistics =
-                TranslationStatistics.loadFromSharedPreference(mSharedPreferences, languageTag);
-        if (event.getEventType() == TextClassifierEvent.TYPE_ACTIONS_SHOWN) {
-            translationStatistics.increaseShownCountByOne();
-        } else if (event.getEventType() == TextClassifierEvent.TYPE_SMART_ACTION) {
-            translationStatistics.increaseClickedCountByOne();
-        }
-        translationStatistics.save(mSharedPreferences, languageTag);
-    }
-
-    private static final class TranslationStatistics {
-        private static final String SEEN_COUNT = "seen_count";
-        private static final String CLICK_COUNT = "click_count";
-
-        private int mShownCount;
-        private int mClickCount;
-
-        private TranslationStatistics() {
-            this(/* seenCount= */ 0, /* clickCount= */ 0);
-        }
-
-        private TranslationStatistics(int seenCount, int clickCount) {
-            mShownCount = seenCount;
-            mClickCount = clickCount;
-        }
-
-        static TranslationStatistics loadFromSharedPreference(
-                SharedPreferences sharedPreferences, String languageTag) {
-            String serializedString = sharedPreferences.getString(languageTag, null);
-            return TranslationStatistics.fromSerializedString(serializedString);
-        }
-
-        void save(SharedPreferences sharedPreferences, String languageTag) {
-            // TODO: Consider to store it in a database.
-            sharedPreferences.edit().putString(languageTag, serializeToString()).apply();
-        }
-
-        private String serializeToString() {
-            try {
-                JSONObject jsonObject = new JSONObject();
-                jsonObject.put(SEEN_COUNT, mShownCount);
-                jsonObject.put(CLICK_COUNT, mClickCount);
-                return jsonObject.toString();
-            } catch (JSONException ex) {
-                TcLog.e(TAG, "serializeToString: ", ex);
-            }
-            return "";
-        }
-
-        void increaseShownCountByOne() {
-            mShownCount += 1;
-        }
-
-        void increaseClickedCountByOne() {
-            mClickCount += 1;
-        }
-
-        float getScore() {
-            if (mShownCount == 0) {
-                return 0f;
-            }
-            return mClickCount / (float) mShownCount;
-        }
-
-        int getShownCount() {
-            return mShownCount;
-        }
-
-        static TranslationStatistics fromSerializedString(String str) {
-            if (str == null) {
-                return new TranslationStatistics();
-            }
-            try {
-                JSONObject jsonObject = new JSONObject(str);
-                int seenCount = jsonObject.getInt(SEEN_COUNT);
-                int clickCount = jsonObject.getInt(CLICK_COUNT);
-                return new TranslationStatistics(seenCount, clickCount);
-            } catch (JSONException ex) {
-                TcLog.e(TAG, "Failed to parse " + str, ex);
-            }
-            return new TranslationStatistics();
-        }
-
-        @Override
-        public String toString() {
-            return "TranslationStatistics{"
-                    + "mShownCount="
-                    + mShownCount
-                    + ", mClickCount="
-                    + mClickCount
-                    + '}';
-        }
-    }
+  }
 }
diff --git a/java/src/com/android/textclassifier/ulp/SystemLanguagesProvider.java b/java/src/com/android/textclassifier/ulp/SystemLanguagesProvider.java
index e167566..eefa913 100644
--- a/java/src/com/android/textclassifier/ulp/SystemLanguagesProvider.java
+++ b/java/src/com/android/textclassifier/ulp/SystemLanguagesProvider.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2018 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -18,18 +18,17 @@
 
 import android.content.res.Resources;
 import android.os.LocaleList;
-
 import java.util.ArrayList;
 import java.util.List;
 
 final class SystemLanguagesProvider {
 
-    List<String> getSystemLanguageTags() {
-        LocaleList localeList = Resources.getSystem().getConfiguration().getLocales();
-        List<String> languageTags = new ArrayList<>();
-        for (int i = 0; i < localeList.size(); i++) {
-            languageTags.add(localeList.get(i).getLanguage());
-        }
-        return languageTags;
+  List<String> getSystemLanguageTags() {
+    LocaleList localeList = Resources.getSystem().getConfiguration().getLocales();
+    List<String> languageTags = new ArrayList<>();
+    for (int i = 0; i < localeList.size(); i++) {
+      languageTags.add(localeList.get(i).getLanguage());
     }
+    return languageTags;
+  }
 }
diff --git a/java/src/com/android/textclassifier/ulp/database/LanguageProfileDatabase.java b/java/src/com/android/textclassifier/ulp/database/LanguageProfileDatabase.java
index 2ae317e..2e213d5 100644
--- a/java/src/com/android/textclassifier/ulp/database/LanguageProfileDatabase.java
+++ b/java/src/com/android/textclassifier/ulp/database/LanguageProfileDatabase.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2018 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -17,7 +17,6 @@
 package com.android.textclassifier.ulp.database;
 
 import android.content.Context;
-
 import androidx.annotation.GuardedBy;
 import androidx.room.Database;
 import androidx.room.Room;
@@ -30,36 +29,36 @@
  * existing if there is one) and use it.
  */
 @Database(
-        entities = {LanguageSignalInfo.class},
-        version = 1,
-        exportSchema = false)
+    entities = {LanguageSignalInfo.class},
+    version = 1,
+    exportSchema = false)
 public abstract class LanguageProfileDatabase extends RoomDatabase {
-    private static final Object sLock = new Object();
+  private static final Object lock = new Object();
 
-    @GuardedBy("sLock")
-    private static LanguageProfileDatabase sINSTANCE;
+  @GuardedBy("lock")
+  private static LanguageProfileDatabase instance;
 
-    /**
-     * Returns {@link LanguageSignalInfoDao} object belonging to the {@link LanguageProfileDatabase}
-     * with which we can call database queries.
-     */
-    public abstract LanguageSignalInfoDao languageInfoDao();
+  /**
+   * Returns {@link LanguageSignalInfoDao} object belonging to the {@link LanguageProfileDatabase}
+   * with which we can call database queries.
+   */
+  public abstract LanguageSignalInfoDao languageInfoDao();
 
-    /**
-     * Create an instance of {@link LanguageProfileDatabase} for chosen context or existing one if
-     * it was already created.
-     */
-    public static LanguageProfileDatabase getInstance(final Context context) {
-        synchronized (sLock) {
-            if (sINSTANCE == null) {
-                sINSTANCE =
-                        Room.databaseBuilder(
-                                        context.getApplicationContext(),
-                                        LanguageProfileDatabase.class,
-                                        "language_profile")
-                                .build();
-            }
-            return sINSTANCE;
-        }
+  /**
+   * Create an instance of {@link LanguageProfileDatabase} for chosen context or existing one if it
+   * was already created.
+   */
+  public static LanguageProfileDatabase getInstance(final Context context) {
+    synchronized (lock) {
+      if (instance == null) {
+        instance =
+            Room.databaseBuilder(
+                    context.getApplicationContext(),
+                    LanguageProfileDatabase.class,
+                    "language_profile")
+                .build();
+      }
+      return instance;
     }
+  }
 }
diff --git a/java/src/com/android/textclassifier/ulp/database/LanguageSignalInfo.java b/java/src/com/android/textclassifier/ulp/database/LanguageSignalInfo.java
index b494e93..98f63ac 100644
--- a/java/src/com/android/textclassifier/ulp/database/LanguageSignalInfo.java
+++ b/java/src/com/android/textclassifier/ulp/database/LanguageSignalInfo.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2018 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -18,10 +18,9 @@
 
 import androidx.annotation.IntDef;
 import androidx.annotation.NonNull;
-import androidx.core.util.Preconditions;
 import androidx.room.ColumnInfo;
 import androidx.room.Entity;
-
+import com.google.common.base.Preconditions;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 
@@ -32,77 +31,78 @@
  * specified language.
  */
 @Entity(
-        tableName = "language_signal_infos",
-        primaryKeys = {"languageTag", "source"})
+    tableName = "language_signal_infos",
+    primaryKeys = {"languageTag", "source"})
 public final class LanguageSignalInfo {
 
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef({SUGGEST_CONVERSATION_ACTIONS, CLASSIFY_TEXT})
-    public @interface Source {}
+  /** The source of the signal */
+  @Retention(RetentionPolicy.SOURCE)
+  @IntDef({SUGGEST_CONVERSATION_ACTIONS, CLASSIFY_TEXT})
+  public @interface Source {}
 
-    public static final int SUGGEST_CONVERSATION_ACTIONS = 0;
-    public static final int CLASSIFY_TEXT = 1;
+  public static final int SUGGEST_CONVERSATION_ACTIONS = 0;
+  public static final int CLASSIFY_TEXT = 1;
 
-    @NonNull
-    @ColumnInfo(name = "languageTag")
-    private String mLanguageTag;
+  @NonNull
+  @ColumnInfo(name = "languageTag")
+  private final String languageTag;
 
-    @ColumnInfo(name = "source")
-    private int mSource;
+  @ColumnInfo(name = "source")
+  private final int source;
 
-    @ColumnInfo(name = "count")
-    private int mCount;
+  @ColumnInfo(name = "count")
+  private final int count;
 
-    public LanguageSignalInfo(String languageTag, @Source int source, int count) {
-        mLanguageTag = Preconditions.checkNotNull(languageTag);
-        mSource = source;
-        mCount = count;
+  public LanguageSignalInfo(String languageTag, @Source int source, int count) {
+    this.languageTag = Preconditions.checkNotNull(languageTag);
+    this.source = source;
+    this.count = count;
+  }
+
+  public String getLanguageTag() {
+    return languageTag;
+  }
+
+  @Source
+  public int getSource() {
+    return source;
+  }
+
+  public int getCount() {
+    return count;
+  }
+
+  @Override
+  public String toString() {
+    String src = "OTHER";
+    if (source == SUGGEST_CONVERSATION_ACTIONS) {
+      src = "SUGGEST_CONVERSATION_ACTIONS";
+    } else if (source == CLASSIFY_TEXT) {
+      src = "CLASSIFY_TEXT";
     }
 
-    public String getLanguageTag() {
-        return mLanguageTag;
-    }
+    return languageTag + "_" + src + ": " + count;
+  }
 
-    @Source
-    public int getSource() {
-        return mSource;
-    }
+  @Override
+  public int hashCode() {
+    int result = languageTag.hashCode();
+    result = 31 * result + Integer.hashCode(source);
+    result = 31 * result + Integer.hashCode(count);
+    return result;
+  }
 
-    public int getCount() {
-        return mCount;
+  @Override
+  public boolean equals(Object obj) {
+    if (this == obj) {
+      return true;
     }
-
-    @Override
-    public String toString() {
-        String src = "OTHER";
-        if (mSource == SUGGEST_CONVERSATION_ACTIONS) {
-            src = "SUGGEST_CONVERSATION_ACTIONS";
-        } else if (mSource == CLASSIFY_TEXT) {
-            src = "CLASSIFY_TEXT";
-        }
-
-        return mLanguageTag + "_" + src + ": " + mCount;
+    if (obj == null || obj.getClass() != getClass()) {
+      return false;
     }
-
-    @Override
-    public int hashCode() {
-        int result = mLanguageTag.hashCode();
-        result = 31 * result + Integer.hashCode(mSource);
-        result = 31 * result + Integer.hashCode(mCount);
-        return result;
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj == null || obj.getClass() != getClass()) {
-            return false;
-        }
-        LanguageSignalInfo info = (LanguageSignalInfo) obj;
-        return mLanguageTag.equals(info.getLanguageTag())
-                && mSource == info.getSource()
-                && mCount == info.getCount();
-    }
+    LanguageSignalInfo info = (LanguageSignalInfo) obj;
+    return languageTag.equals(info.getLanguageTag())
+        && source == info.getSource()
+        && count == info.getCount();
+  }
 }
diff --git a/java/src/com/android/textclassifier/ulp/database/LanguageSignalInfoDao.java b/java/src/com/android/textclassifier/ulp/database/LanguageSignalInfoDao.java
index adc1a59..ca792b2 100644
--- a/java/src/com/android/textclassifier/ulp/database/LanguageSignalInfoDao.java
+++ b/java/src/com/android/textclassifier/ulp/database/LanguageSignalInfoDao.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2018 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -20,9 +20,6 @@
 import androidx.room.Insert;
 import androidx.room.OnConflictStrategy;
 import androidx.room.Query;
-
-import com.google.common.annotations.VisibleForTesting;
-
 import java.util.List;
 
 /**
@@ -34,31 +31,30 @@
 @Dao
 public interface LanguageSignalInfoDao {
 
-    /**
-     * Inserts {@link LanguageSignalInfo} object into the Room database. If there was already entity
-     * with the same language local and source type replaces it with a passed one.
-     *
-     * @param languageSignalInfo object to insert into the database.
-     */
-    @Insert(onConflict = OnConflictStrategy.REPLACE)
-    @VisibleForTesting
-    void insertLanguageInfo(LanguageSignalInfo languageSignalInfo);
+  /**
+   * Inserts {@link LanguageSignalInfo} object into the Room database. If there was already entity
+   * with the same language local and source type replaces it with a passed one.
+   *
+   * @param languageSignalInfo object to insert into the database.
+   */
+  @Insert(onConflict = OnConflictStrategy.REPLACE)
+  void insertLanguageInfo(LanguageSignalInfo languageSignalInfo);
 
-    /** Returns all the {@link LanguageSignalInfo} objects which have source like {@code src}. */
-    @Query("SELECT * FROM language_signal_infos WHERE source = :src")
-    List<LanguageSignalInfo> getBySource(@LanguageSignalInfo.Source int src);
+  /** Returns all the {@link LanguageSignalInfo} objects which have source like {@code src}. */
+  @Query("SELECT * FROM language_signal_infos WHERE source = :src")
+  List<LanguageSignalInfo> getBySource(@LanguageSignalInfo.Source int src);
 
-    /** Returns all the {@link LanguageSignalInfo} objects stored in the database. */
-    @Query("SELECT * FROM language_signal_infos")
-    List<LanguageSignalInfo> getAll();
+  /** Returns all the {@link LanguageSignalInfo} objects stored in the database. */
+  @Query("SELECT * FROM language_signal_infos")
+  List<LanguageSignalInfo> getAll();
 
-    /**
-     * Increases the count of the specified signal by the specified increment or inserts a new entry
-     * if the signal is not in the database yet.
-     */
-    @Query(
-            "INSERT INTO language_signal_infos VALUES(:languageTag, :source, :increment)"
-                    + "  ON CONFLICT(languageTag, source) DO UPDATE SET count = count + :increment")
-    void increaseSignalCount(
-            String languageTag, @LanguageSignalInfo.Source int source, int increment);
+  /**
+   * Increases the count of the specified signal by the specified increment or inserts a new entry
+   * if the signal is not in the database yet.
+   */
+  @Query(
+      "INSERT INTO language_signal_infos VALUES(:languageTag, :source, :increment)"
+          + "  ON CONFLICT(languageTag, source) DO UPDATE SET count = count + :increment")
+  void increaseSignalCount(
+      String languageTag, @LanguageSignalInfo.Source int source, int increment);
 }
diff --git a/java/src/com/android/textclassifier/ulp/kmeans/KMeans.java b/java/src/com/android/textclassifier/ulp/kmeans/KMeans.java
index e77b05e..a01af54 100644
--- a/java/src/com/android/textclassifier/ulp/kmeans/KMeans.java
+++ b/java/src/com/android/textclassifier/ulp/kmeans/KMeans.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2018 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -17,11 +17,7 @@
 package com.android.textclassifier.ulp.kmeans;
 
 import android.util.Log;
-
-import androidx.annotation.NonNull;
-
 import com.google.common.annotations.VisibleForTesting;
-
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
@@ -29,226 +25,218 @@
 
 /** Simple K-Means implementation which found in android internal ml library */
 public class KMeans {
-    private static final boolean DEBUG = false;
-    private static final String TAG = "KMeans";
-    private final Random mRandomState;
-    private final int mMaxIterations;
-    private float mSqConvergenceEpsilon;
+  private static final boolean DEBUG = false;
+  private static final String TAG = "KMeans";
+  private final Random randomState;
+  private final int maxIterations;
+  private final float sqConvergenceEpsilon;
 
-    public KMeans() {
-        this(new Random());
+  public KMeans() {
+    this(new Random());
+  }
+
+  public KMeans(Random random) {
+    this(random, 30 /* maxIterations */, 0.005f /* convergenceEpsilon */);
+  }
+
+  public KMeans(Random random, int maxIterations, float convergenceEpsilon) {
+    randomState = random;
+    this.maxIterations = maxIterations;
+    sqConvergenceEpsilon = convergenceEpsilon * convergenceEpsilon;
+  }
+
+  /**
+   * Runs k-means on the input data (X) trying to find k means.
+   *
+   * <p>K-Means is known for getting stuck into local optima, so you might want to run it multiple
+   * time and argmax on {@link KMeans#score(List)}
+   *
+   * @param k The number of points to return.
+   * @param inputData Input data.
+   * @return An array of k Means, each representing a centroid and data points that belong to it.
+   */
+  public List<Mean> predict(final int k, final float[][] inputData) {
+    checkDataSetSanity(inputData);
+    int dimension = inputData[0].length;
+
+    final ArrayList<Mean> means = new ArrayList<>();
+    for (int i = 0; i < k; i++) {
+      Mean m = new Mean(dimension);
+      for (int j = 0; j < dimension; j++) {
+        m.centroid[j] = randomState.nextFloat();
+      }
+      means.add(m);
     }
 
-    public KMeans(Random random) {
-        this(random, 30 /* maxIterations */, 0.005f /* convergenceEpsilon */);
+    // Iterate until we converge or run out of iterations
+    boolean converged = false;
+    for (int i = 0; i < maxIterations; i++) {
+      converged = step(means, inputData);
+      if (converged) {
+        if (DEBUG) {
+          Log.d(TAG, "Converged at iteration: " + i);
+        }
+        break;
+      }
+    }
+    if (!converged && DEBUG) {
+      Log.d(TAG, "Did not converge");
     }
 
-    public KMeans(Random random, int maxIterations, float convergenceEpsilon) {
-        mRandomState = random;
-        mMaxIterations = maxIterations;
-        mSqConvergenceEpsilon = convergenceEpsilon * convergenceEpsilon;
+    return means;
+  }
+
+  /**
+   * Score calculates the inertia between means. This can be considered as an E step of an EM
+   * algorithm.
+   *
+   * @param means Means to use when calculating score.
+   * @return The score
+   */
+  public static double score(List<Mean> means) {
+    double score = 0;
+    final int meansSize = means.size();
+    for (int i = 0; i < meansSize; i++) {
+      Mean mean = means.get(i);
+      for (int j = 0; j < meansSize; j++) {
+        Mean compareTo = means.get(j);
+        if (mean == compareTo) {
+          continue;
+        }
+        double distance = Math.sqrt(sqDistance(mean.centroid, compareTo.centroid));
+        score += distance;
+      }
+    }
+    return score;
+  }
+
+  /** */
+  @VisibleForTesting
+  public void checkDataSetSanity(float[][] inputData) {
+    if (inputData == null) {
+      throw new IllegalArgumentException("Data set is null.");
+    } else if (inputData.length == 0) {
+      throw new IllegalArgumentException("Data set is empty.");
+    } else if (inputData[0] == null) {
+      throw new IllegalArgumentException("Bad data set format.");
     }
 
-    /**
-     * Runs k-means on the input data (X) trying to find k means.
-     *
-     * <p>K-Means is known for getting stuck into local optima, so you might want to run it multiple
-     * time and argmax on {@link KMeans#score(List)}
-     *
-     * @param k The number of points to return.
-     * @param inputData Input data.
-     * @return An array of k Means, each representing a centroid and data points that belong to it.
-     */
-    public List<Mean> predict(final int k, final float[][] inputData) {
-        checkDataSetSanity(inputData);
-        int dimension = inputData[0].length;
+    final int dimension = inputData[0].length;
+    final int length = inputData.length;
+    for (int i = 1; i < length; i++) {
+      if (inputData[i] == null || inputData[i].length != dimension) {
+        throw new IllegalArgumentException("Bad data set format.");
+      }
+    }
+  }
 
-        final ArrayList<Mean> means = new ArrayList<>();
-        for (int i = 0; i < k; i++) {
-            Mean m = new Mean(dimension);
-            for (int j = 0; j < dimension; j++) {
-                m.mCentroid[j] = mRandomState.nextFloat();
-            }
-            means.add(m);
-        }
+  /**
+   * K-Means iteration.
+   *
+   * @param means Current means
+   * @param inputData Input data
+   * @return True if data set converged
+   */
+  private boolean step(final ArrayList<Mean> means, final float[][] inputData) {
 
-        // Iterate until we converge or run out of iterations
-        boolean converged = false;
-        for (int i = 0; i < mMaxIterations; i++) {
-            converged = step(means, inputData);
-            if (converged) {
-                if (DEBUG) Log.d(TAG, "Converged at iteration: " + i);
-                break;
-            }
-        }
-        if (!converged && DEBUG) Log.d(TAG, "Did not converge");
-
-        return means;
+    // Clean up the previous state because we need to compute
+    // which point belongs to each mean again.
+    for (int i = means.size() - 1; i >= 0; i--) {
+      final Mean mean = means.get(i);
+      mean.closestItems.clear();
+    }
+    for (int i = inputData.length - 1; i >= 0; i--) {
+      final float[] current = inputData[i];
+      final Mean nearest = nearestMean(current, means);
+      nearest.closestItems.add(current);
     }
 
-    /**
-     * Score calculates the inertia between means. This can be considered as an E step of an EM
-     * algorithm.
-     *
-     * @param means Means to use when calculating score.
-     * @return The score
-     */
-    public static double score(@NonNull List<Mean> means) {
-        double score = 0;
-        final int meansSize = means.size();
-        for (int i = 0; i < meansSize; i++) {
-            Mean mean = means.get(i);
-            for (int j = 0; j < meansSize; j++) {
-                Mean compareTo = means.get(j);
-                if (mean == compareTo) {
-                    continue;
-                }
-                double distance = Math.sqrt(sqDistance(mean.mCentroid, compareTo.mCentroid));
-                score += distance;
-            }
+    boolean converged = true;
+    // Move each mean towards the nearest data set points
+    for (int i = means.size() - 1; i >= 0; i--) {
+      final Mean mean = means.get(i);
+      if (mean.closestItems.isEmpty()) {
+        continue;
+      }
+
+      // Compute the new mean centroid:
+      //   1. Sum all all points
+      //   2. Average them
+      final float[] oldCentroid = mean.centroid;
+      mean.centroid = new float[oldCentroid.length];
+      for (int j = 0; j < mean.closestItems.size(); j++) {
+        // Update each centroid component
+        for (int p = 0; p < mean.centroid.length; p++) {
+          mean.centroid[p] += mean.closestItems.get(j)[p];
         }
-        return score;
+      }
+      for (int j = 0; j < mean.centroid.length; j++) {
+        mean.centroid[j] /= mean.closestItems.size();
+      }
+
+      // We converged if the centroid didn't move for any of the means.
+      if (sqDistance(oldCentroid, mean.centroid) > sqConvergenceEpsilon) {
+        converged = false;
+      }
+    }
+    return converged;
+  }
+
+  /** */
+  @VisibleForTesting
+  public static Mean nearestMean(float[] point, List<Mean> means) {
+    Mean nearest = null;
+    float nearestDistance = Float.MAX_VALUE;
+
+    final int meanCount = means.size();
+    for (int i = 0; i < meanCount; i++) {
+      Mean next = means.get(i);
+      // We don't need the sqrt when comparing distances in euclidean space
+      // because they exist on both sides of the equation and cancel each other out.
+      float nextDistance = sqDistance(point, next.centroid);
+      if (nextDistance < nearestDistance) {
+        nearest = next;
+        nearestDistance = nextDistance;
+      }
+    }
+    return nearest;
+  }
+
+  /** */
+  @VisibleForTesting
+  public static float sqDistance(float[] a, float[] b) {
+    float dist = 0;
+    final int length = a.length;
+    for (int i = 0; i < length; i++) {
+      dist += (a[i] - b[i]) * (a[i] - b[i]);
+    }
+    return dist;
+  }
+
+  /** Definition of a mean, contains a centroid and points on its cluster. */
+  public static class Mean {
+    float[] centroid;
+    final ArrayList<float[]> closestItems = new ArrayList<>();
+
+    public Mean(int dimension) {
+      centroid = new float[dimension];
     }
 
-    /** @param inputData */
-    @VisibleForTesting
-    public void checkDataSetSanity(float[][] inputData) {
-        if (inputData == null) {
-            throw new IllegalArgumentException("Data set is null.");
-        } else if (inputData.length == 0) {
-            throw new IllegalArgumentException("Data set is empty.");
-        } else if (inputData[0] == null) {
-            throw new IllegalArgumentException("Bad data set format.");
-        }
-
-        final int dimension = inputData[0].length;
-        final int length = inputData.length;
-        for (int i = 1; i < length; i++) {
-            if (inputData[i] == null || inputData[i].length != dimension) {
-                throw new IllegalArgumentException("Bad data set format.");
-            }
-        }
+    public Mean(float... centroid) {
+      this.centroid = centroid;
     }
 
-    /**
-     * K-Means iteration.
-     *
-     * @param means Current means
-     * @param inputData Input data
-     * @return True if data set converged
-     */
-    private boolean step(final ArrayList<Mean> means, final float[][] inputData) {
-
-        // Clean up the previous state because we need to compute
-        // which point belongs to each mean again.
-        for (int i = means.size() - 1; i >= 0; i--) {
-            final Mean mean = means.get(i);
-            mean.mClosestItems.clear();
-        }
-        for (int i = inputData.length - 1; i >= 0; i--) {
-            final float[] current = inputData[i];
-            final Mean nearest = nearestMean(current, means);
-            nearest.mClosestItems.add(current);
-        }
-
-        boolean converged = true;
-        // Move each mean towards the nearest data set points
-        for (int i = means.size() - 1; i >= 0; i--) {
-            final Mean mean = means.get(i);
-            if (mean.mClosestItems.size() == 0) {
-                continue;
-            }
-
-            // Compute the new mean centroid:
-            //   1. Sum all all points
-            //   2. Average them
-            final float[] oldCentroid = mean.mCentroid;
-            mean.mCentroid = new float[oldCentroid.length];
-            for (int j = 0; j < mean.mClosestItems.size(); j++) {
-                // Update each centroid component
-                for (int p = 0; p < mean.mCentroid.length; p++) {
-                    mean.mCentroid[p] += mean.mClosestItems.get(j)[p];
-                }
-            }
-            for (int j = 0; j < mean.mCentroid.length; j++) {
-                mean.mCentroid[j] /= mean.mClosestItems.size();
-            }
-
-            // We converged if the centroid didn't move for any of the means.
-            if (sqDistance(oldCentroid, mean.mCentroid) > mSqConvergenceEpsilon) {
-                converged = false;
-            }
-        }
-        return converged;
+    public float[] getCentroid() {
+      return centroid;
     }
 
-    /**
-     * @param point
-     * @param means
-     * @return
-     */
-    @VisibleForTesting
-    public static Mean nearestMean(float[] point, List<Mean> means) {
-        Mean nearest = null;
-        float nearestDistance = Float.MAX_VALUE;
-
-        final int meanCount = means.size();
-        for (int i = 0; i < meanCount; i++) {
-            Mean next = means.get(i);
-            // We don't need the sqrt when comparing distances in euclidean space
-            // because they exist on both sides of the equation and cancel each other out.
-            float nextDistance = sqDistance(point, next.mCentroid);
-            if (nextDistance < nearestDistance) {
-                nearest = next;
-                nearestDistance = nextDistance;
-            }
-        }
-        return nearest;
+    public List<float[]> getItems() {
+      return closestItems;
     }
 
-    /**
-     * @param a
-     * @param b
-     * @return
-     */
-    @VisibleForTesting
-    public static float sqDistance(float[] a, float[] b) {
-        float dist = 0;
-        final int length = a.length;
-        for (int i = 0; i < length; i++) {
-            dist += (a[i] - b[i]) * (a[i] - b[i]);
-        }
-        return dist;
+    @Override
+    public String toString() {
+      return "Mean(centroid: " + Arrays.toString(centroid) + ", size: " + closestItems.size() + ")";
     }
-
-    /** Definition of a mean, contains a centroid and points on its cluster. */
-    public static class Mean {
-        float[] mCentroid;
-        final ArrayList<float[]> mClosestItems = new ArrayList<>();
-
-        public Mean(int dimension) {
-            mCentroid = new float[dimension];
-        }
-
-        public Mean(float... centroid) {
-            mCentroid = centroid;
-        }
-
-        public float[] getCentroid() {
-            return mCentroid;
-        }
-
-        public List<float[]> getItems() {
-            return mClosestItems;
-        }
-
-        @Override
-        public String toString() {
-            return "Mean(centroid: "
-                    + Arrays.toString(mCentroid)
-                    + ", size: "
-                    + mClosestItems.size()
-                    + ")";
-        }
-    }
+  }
 }
diff --git a/java/src/com/android/textclassifier/utils/IndentingPrintWriter.java b/java/src/com/android/textclassifier/utils/IndentingPrintWriter.java
index addc8e8..ea96633 100644
--- a/java/src/com/android/textclassifier/utils/IndentingPrintWriter.java
+++ b/java/src/com/android/textclassifier/utils/IndentingPrintWriter.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2018 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -11,13 +11,12 @@
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
  */
 
 package com.android.textclassifier.utils;
 
-import androidx.core.util.Preconditions;
-
+import com.google.common.base.Preconditions;
 import java.io.PrintWriter;
 
 /**
@@ -26,52 +25,52 @@
  * @see PrintWriter
  */
 public final class IndentingPrintWriter {
-    private static final String SINGLE_INDENT = "  ";
+  private static final String SINGLE_INDENT = "  ";
 
-    private final PrintWriter mWriter;
-    private StringBuilder mIndentBuilder = new StringBuilder();
-    private String mCurrentIndent = "";
+  private final PrintWriter writer;
+  private final StringBuilder indentBuilder = new StringBuilder();
+  private String currentIndent = "";
 
-    public IndentingPrintWriter(PrintWriter writer) {
-        mWriter = Preconditions.checkNotNull(writer);
-    }
+  public IndentingPrintWriter(PrintWriter writer) {
+    this.writer = Preconditions.checkNotNull(writer);
+  }
 
-    /** Prints a string. */
-    public IndentingPrintWriter println(String string) {
-        mWriter.print(mCurrentIndent);
-        mWriter.print(string);
-        mWriter.println();
-        return this;
-    }
+  /** Prints a string. */
+  public IndentingPrintWriter println(String string) {
+    writer.print(currentIndent);
+    writer.print(string);
+    writer.println();
+    return this;
+  }
 
-    /** Prints a empty line */
-    public IndentingPrintWriter println() {
-        mWriter.println();
-        return this;
-    }
+  /** Prints a empty line */
+  public IndentingPrintWriter println() {
+    writer.println();
+    return this;
+  }
 
-    /** Increases indents for subsequent texts. */
-    public IndentingPrintWriter increaseIndent() {
-        mIndentBuilder.append(SINGLE_INDENT);
-        mCurrentIndent = mIndentBuilder.toString();
-        return this;
-    }
+  /** Increases indents for subsequent texts. */
+  public IndentingPrintWriter increaseIndent() {
+    indentBuilder.append(SINGLE_INDENT);
+    currentIndent = indentBuilder.toString();
+    return this;
+  }
 
-    /** Decreases indents for subsequent texts. */
-    public IndentingPrintWriter decreaseIndent() {
-        mIndentBuilder.delete(0, SINGLE_INDENT.length());
-        mCurrentIndent = mIndentBuilder.toString();
-        return this;
-    }
+  /** Decreases indents for subsequent texts. */
+  public IndentingPrintWriter decreaseIndent() {
+    indentBuilder.delete(0, SINGLE_INDENT.length());
+    currentIndent = indentBuilder.toString();
+    return this;
+  }
 
-    /** Prints a key-valued pair. */
-    public IndentingPrintWriter printPair(String key, Object value) {
-        println(String.format("%s=%s", key, String.valueOf(value)));
-        return this;
-    }
+  /** Prints a key-valued pair. */
+  public IndentingPrintWriter printPair(String key, Object value) {
+    println(String.format("%s=%s", key, String.valueOf(value)));
+    return this;
+  }
 
-    /** Flushes the stream. */
-    public void flush() {
-        mWriter.flush();
-    }
+  /** Flushes the stream. */
+  public void flush() {
+    writer.flush();
+  }
 }
