diff --git a/java/Android.bp b/java/Android.bp
index f457e9e..f6cc0ed 100644
--- a/java/Android.bp
+++ b/java/Android.bp
@@ -47,7 +47,8 @@
         "androidx.annotation_annotation",
         "guava",
         "androidx.room_room-runtime",
-        "textclassifier-statsd"
+        "textclassifier-statsd",
+        "error_prone_annotations",
     ],
     sdk_version: "system_current",
     min_sdk_version: "28",
diff --git a/java/AndroidManifest.xml b/java/AndroidManifest.xml
index d4be7c7..98308db 100644
--- a/java/AndroidManifest.xml
+++ b/java/AndroidManifest.xml
@@ -25,14 +25,15 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
           package="com.android.textclassifier"
           android:versionCode="1"
-          android:versionName="R-initial">
+          android:versionName="1.0.0">
 
-    <uses-sdk android:minSdkVersion="28" android:targetSdkVersion="28"/>
+    <uses-sdk android:minSdkVersion="29" android:targetSdkVersion="29"/>
 
-    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
+    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
 
     <application android:label="@string/app_name"
-                 android:icon="@drawable/app_icon">
+                 android:icon="@drawable/app_icon"
+                 android:extractNativeLibs="false">
         <service
             android:exported="true"
             android:name=".DefaultTextClassifierService"
diff --git a/java/checkstyle.sh b/java/checkstyle.sh
deleted file mode 100755
index 39443d5..0000000
--- a/java/checkstyle.sh
+++ /dev/null
@@ -1,2 +0,0 @@
-cd ${ANDROID_BUILD_TOP}/vendor/google_experimental
-${ANDROID_BUILD_TOP}/prebuilts/checkstyle/checkstyle.py
\ No newline at end of file
diff --git a/java/google-java-format.sh b/java/google-java-format.sh
deleted file mode 100755
index 867cf9c..0000000
--- a/java/google-java-format.sh
+++ /dev/null
@@ -1,3 +0,0 @@
-find src -name "*.java" -exec google-java-format -r -a {} \;
-find tests/unittests/src -name "*.java" -exec google-java-format -r -a {} \;
-find tests/robotests/src -name "*.java" -exec google-java-format -r -a {} \;
\ No newline at end of file
diff --git a/java/res/values/strings.xml b/java/res/values/strings.xml
index 60d1859..f8e410a 100644
--- a/java/res/values/strings.xml
+++ b/java/res/values/strings.xml
@@ -1,5 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+      <!-- Label for this app [CHAR LIMIT=30] -->
     <string name="app_name">Text classifier</string>
     <!-- Label for item in the text selection menu to trigger an Email app. Should be a verb. [CHAR LIMIT=30] -->
     <string name="email">Email</string>
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();
+  }
 }
diff --git a/java/tests/unittests/Android.bp b/java/tests/instrumentation/Android.bp
similarity index 89%
rename from java/tests/unittests/Android.bp
rename to java/tests/instrumentation/Android.bp
index ab3f713..c742c8d 100644
--- a/java/tests/unittests/Android.bp
+++ b/java/tests/instrumentation/Android.bp
@@ -22,12 +22,15 @@
     srcs: [
         "src/**/*.java",
     ],
+    // TODO: Re-enable the ulp tests.
+    exclude_srcs: ["src/**/ulp/*.java"],
 
     static_libs: [
+        "androidx.test.ext.junit",
         "androidx.test.rules",
         "androidx.test.espresso.core",
         "androidx.test.ext.truth",
-        "mockito-target-inline",
+        "mockito-target-minus-junit4",
         "ub-uiautomator",
         "testng",
         "compatibility-device-util-axt",
diff --git a/java/tests/instrumentation/AndroidManifest.xml b/java/tests/instrumentation/AndroidManifest.xml
new file mode 100644
index 0000000..5de247c
--- /dev/null
+++ b/java/tests/instrumentation/AndroidManifest.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.textclassifier.tests">
+
+  <uses-sdk android:minSdkVersion="28"/>
+
+  <application>
+    <uses-library android:name="android.test.runner"/>
+  </application>
+
+  <instrumentation
+      android:name="androidx.test.runner.AndroidJUnitRunner"
+      android:targetPackage="com.android.textclassifier.tests"/>
+</manifest>
diff --git a/java/tests/instrumentation/src/com/android/textclassifier/ActionsModelParamsSupplierTest.java b/java/tests/instrumentation/src/com/android/textclassifier/ActionsModelParamsSupplierTest.java
new file mode 100644
index 0000000..6a9d08a
--- /dev/null
+++ b/java/tests/instrumentation/src/com/android/textclassifier/ActionsModelParamsSupplierTest.java
@@ -0,0 +1,90 @@
+/*
+ * 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.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * 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.
+ */
+
+package com.android.textclassifier;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+import java.io.File;
+import java.util.Collections;
+import java.util.Locale;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class ActionsModelParamsSupplierTest {
+
+  @Test
+  public void getSerializedPreconditions_validActionsModelParams() {
+    ModelFileManager.ModelFile modelFile =
+        new ModelFileManager.ModelFile(
+            new File("/model/file"),
+            200 /* version */,
+            Collections.singletonList(Locale.forLanguageTag("en")),
+            "en",
+            false);
+    byte[] serializedPreconditions = new byte[] {0x12, 0x24, 0x36};
+    ActionsModelParamsSupplier.ActionsModelParams params =
+        new ActionsModelParamsSupplier.ActionsModelParams(
+            200 /* version */, "en", serializedPreconditions);
+
+    byte[] actual = params.getSerializedPreconditions(modelFile);
+
+    assertThat(actual).isEqualTo(serializedPreconditions);
+  }
+
+  @Test
+  public void getSerializedPreconditions_invalidVersion() {
+    ModelFileManager.ModelFile modelFile =
+        new ModelFileManager.ModelFile(
+            new File("/model/file"),
+            201 /* version */,
+            Collections.singletonList(Locale.forLanguageTag("en")),
+            "en",
+            false);
+    byte[] serializedPreconditions = new byte[] {0x12, 0x24, 0x36};
+    ActionsModelParamsSupplier.ActionsModelParams params =
+        new ActionsModelParamsSupplier.ActionsModelParams(
+            200 /* version */, "en", serializedPreconditions);
+
+    byte[] actual = params.getSerializedPreconditions(modelFile);
+
+    assertThat(actual).isNull();
+  }
+
+  @Test
+  public void getSerializedPreconditions_invalidLocales() {
+    final String languageTag = "zh";
+    ModelFileManager.ModelFile modelFile =
+        new ModelFileManager.ModelFile(
+            new File("/model/file"),
+            200 /* version */,
+            Collections.singletonList(Locale.forLanguageTag(languageTag)),
+            languageTag,
+            false);
+    byte[] serializedPreconditions = new byte[] {0x12, 0x24, 0x36};
+    ActionsModelParamsSupplier.ActionsModelParams params =
+        new ActionsModelParamsSupplier.ActionsModelParams(
+            200 /* version */, "en", serializedPreconditions);
+
+    byte[] actual = params.getSerializedPreconditions(modelFile);
+
+    assertThat(actual).isNull();
+  }
+}
diff --git a/java/tests/instrumentation/src/com/android/textclassifier/ActionsSuggestionsHelperTest.java b/java/tests/instrumentation/src/com/android/textclassifier/ActionsSuggestionsHelperTest.java
new file mode 100644
index 0000000..b48d361
--- /dev/null
+++ b/java/tests/instrumentation/src/com/android/textclassifier/ActionsSuggestionsHelperTest.java
@@ -0,0 +1,305 @@
+/*
+ * 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.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * 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.
+ */
+
+package com.android.textclassifier;
+
+import static android.view.textclassifier.ConversationActions.Message.PERSON_USER_OTHERS;
+import static android.view.textclassifier.ConversationActions.Message.PERSON_USER_SELF;
+import static com.google.common.truth.Truth.assertThat;
+
+import android.app.PendingIntent;
+import android.app.Person;
+import android.app.RemoteAction;
+import android.content.ComponentName;
+import android.content.Intent;
+import android.graphics.drawable.Icon;
+import android.net.Uri;
+import android.os.Bundle;
+import android.view.textclassifier.ConversationAction;
+import android.view.textclassifier.ConversationActions;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+import com.android.textclassifier.intent.LabeledIntent;
+import com.android.textclassifier.intent.TemplateIntentFactory;
+import com.google.android.textclassifier.ActionsSuggestionsModel;
+import com.google.android.textclassifier.RemoteActionTemplate;
+import com.google.common.collect.ImmutableList;
+import java.time.Instant;
+import java.time.ZoneId;
+import java.time.ZonedDateTime;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Locale;
+import java.util.function.Function;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class ActionsSuggestionsHelperTest {
+  private static final String LOCALE_TAG = Locale.US.toLanguageTag();
+  private static final Function<CharSequence, List<String>> LANGUAGE_DETECTOR =
+      charSequence -> Collections.singletonList(LOCALE_TAG);
+
+  @Test
+  public void testToNativeMessages_emptyInput() {
+    ActionsSuggestionsModel.ConversationMessage[] conversationMessages =
+        ActionsSuggestionsHelper.toNativeMessages(ImmutableList.of(), LANGUAGE_DETECTOR);
+
+    assertThat(conversationMessages).isEmpty();
+  }
+
+  @Test
+  public void testToNativeMessages_noTextMessages() {
+    ConversationActions.Message messageWithoutText =
+        new ConversationActions.Message.Builder(PERSON_USER_OTHERS).build();
+
+    ActionsSuggestionsModel.ConversationMessage[] conversationMessages =
+        ActionsSuggestionsHelper.toNativeMessages(
+            ImmutableList.of(messageWithoutText), LANGUAGE_DETECTOR);
+
+    assertThat(conversationMessages).isEmpty();
+  }
+
+  @Test
+  public void testToNativeMessages_userIdEncoding() {
+    Person userA = new Person.Builder().setName("userA").build();
+    Person userB = new Person.Builder().setName("userB").build();
+
+    ConversationActions.Message firstMessage =
+        new ConversationActions.Message.Builder(userB).setText("first").build();
+    ConversationActions.Message secondMessage =
+        new ConversationActions.Message.Builder(userA).setText("second").build();
+    ConversationActions.Message thirdMessage =
+        new ConversationActions.Message.Builder(PERSON_USER_SELF).setText("third").build();
+    ConversationActions.Message fourthMessage =
+        new ConversationActions.Message.Builder(userA).setText("fourth").build();
+
+    ActionsSuggestionsModel.ConversationMessage[] conversationMessages =
+        ActionsSuggestionsHelper.toNativeMessages(
+            Arrays.asList(firstMessage, secondMessage, thirdMessage, fourthMessage),
+            LANGUAGE_DETECTOR);
+
+    assertThat(conversationMessages).hasLength(4);
+    assertNativeMessage(conversationMessages[0], firstMessage.getText(), 2, 0);
+    assertNativeMessage(conversationMessages[1], secondMessage.getText(), 1, 0);
+    assertNativeMessage(conversationMessages[2], thirdMessage.getText(), 0, 0);
+    assertNativeMessage(conversationMessages[3], fourthMessage.getText(), 1, 0);
+  }
+
+  @Test
+  public void testToNativeMessages_referenceTime() {
+    ConversationActions.Message firstMessage =
+        new ConversationActions.Message.Builder(PERSON_USER_OTHERS)
+            .setText("first")
+            .setReferenceTime(createZonedDateTimeFromMsUtc(1000))
+            .build();
+    ConversationActions.Message secondMessage =
+        new ConversationActions.Message.Builder(PERSON_USER_OTHERS).setText("second").build();
+    ConversationActions.Message thirdMessage =
+        new ConversationActions.Message.Builder(PERSON_USER_OTHERS)
+            .setText("third")
+            .setReferenceTime(createZonedDateTimeFromMsUtc(2000))
+            .build();
+
+    ActionsSuggestionsModel.ConversationMessage[] conversationMessages =
+        ActionsSuggestionsHelper.toNativeMessages(
+            Arrays.asList(firstMessage, secondMessage, thirdMessage), LANGUAGE_DETECTOR);
+
+    assertThat(conversationMessages).hasLength(3);
+    assertNativeMessage(conversationMessages[0], firstMessage.getText(), 1, 1000);
+    assertNativeMessage(conversationMessages[1], secondMessage.getText(), 1, 0);
+    assertNativeMessage(conversationMessages[2], thirdMessage.getText(), 1, 2000);
+  }
+
+  @Test
+  public void testDeduplicateActions() {
+    Bundle phoneExtras = new Bundle();
+    Intent phoneIntent = new Intent();
+    phoneIntent.setComponent(new ComponentName("phone", "intent"));
+    ExtrasUtils.putActionIntent(phoneExtras, phoneIntent);
+
+    Bundle anotherPhoneExtras = new Bundle();
+    Intent anotherPhoneIntent = new Intent();
+    anotherPhoneIntent.setComponent(new ComponentName("phone", "another.intent"));
+    ExtrasUtils.putActionIntent(anotherPhoneExtras, anotherPhoneIntent);
+
+    Bundle urlExtras = new Bundle();
+    Intent urlIntent = new Intent();
+    urlIntent.setComponent(new ComponentName("url", "intent"));
+    ExtrasUtils.putActionIntent(urlExtras, urlIntent);
+
+    PendingIntent pendingIntent =
+        PendingIntent.getActivity(ApplicationProvider.getApplicationContext(), 0, phoneIntent, 0);
+    Icon icon = Icon.createWithData(new byte[0], 0, 0);
+    ConversationAction action =
+        new ConversationAction.Builder(ConversationAction.TYPE_CALL_PHONE)
+            .setAction(new RemoteAction(icon, "label", "1", pendingIntent))
+            .setExtras(phoneExtras)
+            .build();
+    ConversationAction actionWithSameLabel =
+        new ConversationAction.Builder(ConversationAction.TYPE_CALL_PHONE)
+            .setAction(new RemoteAction(icon, "label", "2", pendingIntent))
+            .setExtras(phoneExtras)
+            .build();
+    ConversationAction actionWithSamePackageButDifferentClass =
+        new ConversationAction.Builder(ConversationAction.TYPE_CALL_PHONE)
+            .setAction(new RemoteAction(icon, "label", "3", pendingIntent))
+            .setExtras(anotherPhoneExtras)
+            .build();
+    ConversationAction actionWithDifferentLabel =
+        new ConversationAction.Builder(ConversationAction.TYPE_CALL_PHONE)
+            .setAction(new RemoteAction(icon, "another_label", "4", pendingIntent))
+            .setExtras(phoneExtras)
+            .build();
+    ConversationAction actionWithDifferentPackage =
+        new ConversationAction.Builder(ConversationAction.TYPE_OPEN_URL)
+            .setAction(new RemoteAction(icon, "label", "5", pendingIntent))
+            .setExtras(urlExtras)
+            .build();
+    ConversationAction actionWithoutRemoteAction =
+        new ConversationAction.Builder(ConversationAction.TYPE_CREATE_REMINDER).build();
+
+    List<ConversationAction> conversationActions =
+        ActionsSuggestionsHelper.removeActionsWithDuplicates(
+            Arrays.asList(
+                action,
+                actionWithSameLabel,
+                actionWithSamePackageButDifferentClass,
+                actionWithDifferentLabel,
+                actionWithDifferentPackage,
+                actionWithoutRemoteAction));
+
+    assertThat(conversationActions).hasSize(3);
+    assertThat(conversationActions.get(0).getAction().getContentDescription().toString())
+        .isEqualTo("4");
+    assertThat(conversationActions.get(1).getAction().getContentDescription().toString())
+        .isEqualTo("5");
+    assertThat(conversationActions.get(2).getAction()).isNull();
+  }
+
+  @Test
+  public void testDeduplicateActions_nullComponent() {
+    Bundle phoneExtras = new Bundle();
+    Intent phoneIntent = new Intent(Intent.ACTION_DIAL);
+    ExtrasUtils.putActionIntent(phoneExtras, phoneIntent);
+    PendingIntent pendingIntent =
+        PendingIntent.getActivity(ApplicationProvider.getApplicationContext(), 0, phoneIntent, 0);
+    Icon icon = Icon.createWithData(new byte[0], 0, 0);
+    ConversationAction action =
+        new ConversationAction.Builder(ConversationAction.TYPE_CALL_PHONE)
+            .setAction(new RemoteAction(icon, "label", "1", pendingIntent))
+            .setExtras(phoneExtras)
+            .build();
+    ConversationAction actionWithSameLabel =
+        new ConversationAction.Builder(ConversationAction.TYPE_CALL_PHONE)
+            .setAction(new RemoteAction(icon, "label", "2", pendingIntent))
+            .setExtras(phoneExtras)
+            .build();
+
+    List<ConversationAction> conversationActions =
+        ActionsSuggestionsHelper.removeActionsWithDuplicates(
+            Arrays.asList(action, actionWithSameLabel));
+
+    assertThat(conversationActions).isEmpty();
+  }
+
+  public void createLabeledIntentResult_null() {
+    ActionsSuggestionsModel.ActionSuggestion nativeSuggestion =
+        new ActionsSuggestionsModel.ActionSuggestion(
+            "text", ConversationAction.TYPE_OPEN_URL, 1.0f, null, null, null);
+
+    LabeledIntent.Result labeledIntentResult =
+        ActionsSuggestionsHelper.createLabeledIntentResult(
+            ApplicationProvider.getApplicationContext(),
+            new TemplateIntentFactory(),
+            nativeSuggestion);
+
+    assertThat(labeledIntentResult).isNull();
+  }
+
+  @Test
+  public void createLabeledIntentResult_emptyList() {
+    ActionsSuggestionsModel.ActionSuggestion nativeSuggestion =
+        new ActionsSuggestionsModel.ActionSuggestion(
+            "text",
+            ConversationAction.TYPE_OPEN_URL,
+            1.0f,
+            null,
+            null,
+            new RemoteActionTemplate[0]);
+
+    LabeledIntent.Result labeledIntentResult =
+        ActionsSuggestionsHelper.createLabeledIntentResult(
+            ApplicationProvider.getApplicationContext(),
+            new TemplateIntentFactory(),
+            nativeSuggestion);
+
+    assertThat(labeledIntentResult).isNull();
+  }
+
+  @Test
+  public void createLabeledIntentResult() {
+    ActionsSuggestionsModel.ActionSuggestion nativeSuggestion =
+        new ActionsSuggestionsModel.ActionSuggestion(
+            "text",
+            ConversationAction.TYPE_OPEN_URL,
+            1.0f,
+            null,
+            null,
+            new RemoteActionTemplate[] {
+              new RemoteActionTemplate(
+                  "title",
+                  null,
+                  "description",
+                  null,
+                  Intent.ACTION_VIEW,
+                  Uri.parse("http://www.android.com").toString(),
+                  null,
+                  0,
+                  null,
+                  null,
+                  null,
+                  0)
+            });
+
+    LabeledIntent.Result labeledIntentResult =
+        ActionsSuggestionsHelper.createLabeledIntentResult(
+            ApplicationProvider.getApplicationContext(),
+            new TemplateIntentFactory(),
+            nativeSuggestion);
+
+    assertThat(labeledIntentResult.remoteAction.getTitle().toString()).isEqualTo("title");
+    assertThat(labeledIntentResult.resolvedIntent.getAction()).isEqualTo(Intent.ACTION_VIEW);
+  }
+
+  private static ZonedDateTime createZonedDateTimeFromMsUtc(long msUtc) {
+    return ZonedDateTime.ofInstant(Instant.ofEpochMilli(msUtc), ZoneId.of("UTC"));
+  }
+
+  private static void assertNativeMessage(
+      ActionsSuggestionsModel.ConversationMessage nativeMessage,
+      CharSequence text,
+      int userId,
+      long referenceTimeInMsUtc) {
+    assertThat(nativeMessage.getText()).isEqualTo(text.toString());
+    assertThat(nativeMessage.getUserId()).isEqualTo(userId);
+    assertThat(nativeMessage.getDetectedTextLanguageTags()).isEqualTo(LOCALE_TAG);
+    assertThat(nativeMessage.getReferenceTimeMsUtc()).isEqualTo(referenceTimeInMsUtc);
+  }
+}
diff --git a/java/tests/instrumentation/src/com/android/textclassifier/FakeContextBuilder.java b/java/tests/instrumentation/src/com/android/textclassifier/FakeContextBuilder.java
new file mode 100644
index 0000000..17b6e0a
--- /dev/null
+++ b/java/tests/instrumentation/src/com/android/textclassifier/FakeContextBuilder.java
@@ -0,0 +1,137 @@
+/*
+ * 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.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * 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.
+ */
+
+package com.android.textclassifier;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.ContextWrapper;
+import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import androidx.test.core.app.ApplicationProvider;
+import com.google.common.base.Preconditions;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+import javax.annotation.Nullable;
+import org.mockito.stubbing.Answer;
+
+/** A builder used to build a fake context for testing. */
+public final class FakeContextBuilder {
+
+  /** A component name that can be used for tests. */
+  public static final ComponentName DEFAULT_COMPONENT = new ComponentName("pkg", "cls");
+
+  private final PackageManager packageManager;
+  private final ContextWrapper context;
+  private final Map<String, ComponentName> components = new HashMap<>();
+  private final Map<String, CharSequence> appLabels = new HashMap<>();
+  @Nullable private ComponentName allIntentComponent;
+
+  public FakeContextBuilder() {
+    packageManager = mock(PackageManager.class);
+    when(packageManager.resolveActivity(any(Intent.class), anyInt())).thenReturn(null);
+    context =
+        new ContextWrapper(ApplicationProvider.getApplicationContext()) {
+          @Override
+          public PackageManager getPackageManager() {
+            return packageManager;
+          }
+        };
+  }
+
+  /**
+   * Sets the component name of an activity to handle the specified intent action.
+   *
+   * <p><strong>NOTE: </strong>By default, no component is set to handle any intent.
+   */
+  public FakeContextBuilder setIntentComponent(
+      String intentAction, @Nullable ComponentName component) {
+    Preconditions.checkNotNull(intentAction);
+    components.put(intentAction, component);
+    return this;
+  }
+
+  /** Sets the app label res for a specified package. */
+  public FakeContextBuilder setAppLabel(String packageName, @Nullable CharSequence appLabel) {
+    Preconditions.checkNotNull(packageName);
+    appLabels.put(packageName, appLabel);
+    return this;
+  }
+
+  /**
+   * Sets the component name of an activity to handle all intents.
+   *
+   * <p><strong>NOTE: </strong>By default, no component is set to handle any intent.
+   */
+  public FakeContextBuilder setAllIntentComponent(@Nullable ComponentName component) {
+    allIntentComponent = component;
+    return this;
+  }
+
+  /** Builds and returns a fake context. */
+  public Context build() {
+    when(packageManager.resolveActivity(any(Intent.class), anyInt()))
+        .thenAnswer(
+            (Answer<ResolveInfo>)
+                invocation -> {
+                  final String action = ((Intent) invocation.getArgument(0)).getAction();
+                  final ComponentName component =
+                      components.containsKey(action) ? components.get(action) : allIntentComponent;
+                  return getResolveInfo(component);
+                });
+    when(packageManager.getApplicationLabel(any(ApplicationInfo.class)))
+        .thenAnswer(
+            (Answer<CharSequence>)
+                invocation -> {
+                  ApplicationInfo applicationInfo = invocation.getArgument(0);
+                  return appLabels.get(applicationInfo.packageName);
+                });
+    return context;
+  }
+
+  /** Returns a component name with random package and class names. */
+  public static ComponentName newComponent() {
+    return new ComponentName(UUID.randomUUID().toString(), UUID.randomUUID().toString());
+  }
+
+  private static ResolveInfo getResolveInfo(ComponentName component) {
+    final ResolveInfo info;
+    if (component == null) {
+      info = null;
+    } else {
+      // NOTE: If something breaks in TextClassifier because we expect more fields to be set
+      // in here, just add them.
+      info = new ResolveInfo();
+      info.activityInfo = new ActivityInfo();
+      info.activityInfo.packageName = component.getPackageName();
+      info.activityInfo.name = component.getClassName();
+      info.activityInfo.exported = true;
+      info.activityInfo.applicationInfo = new ApplicationInfo();
+      info.activityInfo.applicationInfo.packageName = component.getPackageName();
+      info.activityInfo.applicationInfo.icon = 0;
+    }
+    return info;
+  }
+}
diff --git a/java/tests/instrumentation/src/com/android/textclassifier/ModelFileManagerTest.java b/java/tests/instrumentation/src/com/android/textclassifier/ModelFileManagerTest.java
new file mode 100644
index 0000000..ab4fde4
--- /dev/null
+++ b/java/tests/instrumentation/src/com/android/textclassifier/ModelFileManagerTest.java
@@ -0,0 +1,353 @@
+/*
+ * 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.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * 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.
+ */
+
+package com.android.textclassifier;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Mockito.when;
+
+import android.os.LocaleList;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+import com.google.common.collect.ImmutableList;
+import java.io.File;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Locale;
+import java.util.function.Supplier;
+import java.util.stream.Collectors;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class ModelFileManagerTest {
+  private static final Locale DEFAULT_LOCALE = Locale.forLanguageTag("en-US");
+  @Mock private Supplier<List<ModelFileManager.ModelFile>> modelFileSupplier;
+  private ModelFileManager.ModelFileSupplierImpl modelFileSupplierImpl;
+  private ModelFileManager modelFileManager;
+  private File rootTestDir;
+  private File factoryModelDir;
+  private File updatedModelFile;
+
+  @Before
+  public void setup() {
+    MockitoAnnotations.initMocks(this);
+    modelFileManager = new ModelFileManager(modelFileSupplier);
+    rootTestDir = ApplicationProvider.getApplicationContext().getCacheDir();
+    factoryModelDir = new File(rootTestDir, "factory");
+    updatedModelFile = new File(rootTestDir, "updated.model");
+
+    modelFileSupplierImpl =
+        new ModelFileManager.ModelFileSupplierImpl(
+            factoryModelDir,
+            "test\\d.model",
+            updatedModelFile,
+            fd -> 1,
+            fd -> ModelFileManager.ModelFile.LANGUAGE_INDEPENDENT);
+
+    rootTestDir.mkdirs();
+    factoryModelDir.mkdirs();
+
+    Locale.setDefault(DEFAULT_LOCALE);
+  }
+
+  @After
+  public void removeTestDir() {
+    recursiveDelete(rootTestDir);
+  }
+
+  @Test
+  public void get() {
+    ModelFileManager.ModelFile modelFile =
+        new ModelFileManager.ModelFile(new File("/path/a"), 1, ImmutableList.of(), "", true);
+    when(modelFileSupplier.get()).thenReturn(ImmutableList.of(modelFile));
+
+    List<ModelFileManager.ModelFile> modelFiles = modelFileManager.listModelFiles();
+
+    assertThat(modelFiles).hasSize(1);
+    assertThat(modelFiles.get(0)).isEqualTo(modelFile);
+  }
+
+  @Test
+  public void findBestModel_versionCode() {
+    ModelFileManager.ModelFile olderModelFile =
+        new ModelFileManager.ModelFile(new File("/path/a"), 1, ImmutableList.of(), "", true);
+
+    ModelFileManager.ModelFile newerModelFile =
+        new ModelFileManager.ModelFile(new File("/path/b"), 2, ImmutableList.of(), "", true);
+    when(modelFileSupplier.get()).thenReturn(Arrays.asList(olderModelFile, newerModelFile));
+
+    ModelFileManager.ModelFile bestModelFile =
+        modelFileManager.findBestModelFile(LocaleList.getEmptyLocaleList());
+
+    assertThat(bestModelFile).isEqualTo(newerModelFile);
+  }
+
+  @Test
+  public void findBestModel_languageDependentModelIsPreferred() {
+    Locale locale = Locale.forLanguageTag("ja");
+    ModelFileManager.ModelFile languageIndependentModelFile =
+        new ModelFileManager.ModelFile(new File("/path/a"), 1, ImmutableList.of(), "", true);
+
+    ModelFileManager.ModelFile languageDependentModelFile =
+        new ModelFileManager.ModelFile(
+            new File("/path/b"),
+            1,
+            Collections.singletonList(locale),
+            locale.toLanguageTag(),
+            false);
+    when(modelFileSupplier.get())
+        .thenReturn(Arrays.asList(languageIndependentModelFile, languageDependentModelFile));
+
+    ModelFileManager.ModelFile bestModelFile =
+        modelFileManager.findBestModelFile(LocaleList.forLanguageTags(locale.toLanguageTag()));
+    assertThat(bestModelFile).isEqualTo(languageDependentModelFile);
+  }
+
+  @Test
+  public void findBestModel_noMatchedLanguageModel() {
+    Locale locale = Locale.forLanguageTag("ja");
+    ModelFileManager.ModelFile languageIndependentModelFile =
+        new ModelFileManager.ModelFile(new File("/path/a"), 1, Collections.emptyList(), "", true);
+
+    ModelFileManager.ModelFile languageDependentModelFile =
+        new ModelFileManager.ModelFile(
+            new File("/path/b"),
+            1,
+            Collections.singletonList(locale),
+            locale.toLanguageTag(),
+            false);
+
+    when(modelFileSupplier.get())
+        .thenReturn(Arrays.asList(languageIndependentModelFile, languageDependentModelFile));
+
+    ModelFileManager.ModelFile bestModelFile =
+        modelFileManager.findBestModelFile(LocaleList.forLanguageTags("zh-hk"));
+    assertThat(bestModelFile).isEqualTo(languageIndependentModelFile);
+  }
+
+  @Test
+  public void findBestModel_noMatchedLanguageModel_defaultLocaleModelExists() {
+    ModelFileManager.ModelFile languageIndependentModelFile =
+        new ModelFileManager.ModelFile(new File("/path/a"), 1, ImmutableList.of(), "", true);
+
+    ModelFileManager.ModelFile languageDependentModelFile =
+        new ModelFileManager.ModelFile(
+            new File("/path/b"),
+            1,
+            Collections.singletonList(DEFAULT_LOCALE),
+            DEFAULT_LOCALE.toLanguageTag(),
+            false);
+
+    when(modelFileSupplier.get())
+        .thenReturn(Arrays.asList(languageIndependentModelFile, languageDependentModelFile));
+
+    ModelFileManager.ModelFile bestModelFile =
+        modelFileManager.findBestModelFile(LocaleList.forLanguageTags("zh-hk"));
+    assertThat(bestModelFile).isEqualTo(languageIndependentModelFile);
+  }
+
+  @Test
+  public void findBestModel_languageIsMoreImportantThanVersion() {
+    ModelFileManager.ModelFile matchButOlderModel =
+        new ModelFileManager.ModelFile(
+            new File("/path/a"),
+            1,
+            Collections.singletonList(Locale.forLanguageTag("fr")),
+            "fr",
+            false);
+
+    ModelFileManager.ModelFile mismatchButNewerModel =
+        new ModelFileManager.ModelFile(
+            new File("/path/b"),
+            2,
+            Collections.singletonList(Locale.forLanguageTag("ja")),
+            "ja",
+            false);
+
+    when(modelFileSupplier.get())
+        .thenReturn(Arrays.asList(matchButOlderModel, mismatchButNewerModel));
+
+    ModelFileManager.ModelFile bestModelFile =
+        modelFileManager.findBestModelFile(LocaleList.forLanguageTags("fr"));
+    assertThat(bestModelFile).isEqualTo(matchButOlderModel);
+  }
+
+  @Test
+  public void findBestModel_languageIsMoreImportantThanVersion_bestModelComesFirst() {
+    ModelFileManager.ModelFile matchLocaleModel =
+        new ModelFileManager.ModelFile(
+            new File("/path/b"),
+            1,
+            Collections.singletonList(Locale.forLanguageTag("ja")),
+            "ja",
+            false);
+
+    ModelFileManager.ModelFile languageIndependentModel =
+        new ModelFileManager.ModelFile(new File("/path/a"), 2, ImmutableList.of(), "", true);
+    when(modelFileSupplier.get())
+        .thenReturn(Arrays.asList(matchLocaleModel, languageIndependentModel));
+
+    ModelFileManager.ModelFile bestModelFile =
+        modelFileManager.findBestModelFile(LocaleList.forLanguageTags("ja"));
+
+    assertThat(bestModelFile).isEqualTo(matchLocaleModel);
+  }
+
+  @Test
+  public void modelFileEquals() {
+    ModelFileManager.ModelFile modelA =
+        new ModelFileManager.ModelFile(
+            new File("/path/a"),
+            1,
+            Collections.singletonList(Locale.forLanguageTag("ja")),
+            "ja",
+            false);
+
+    ModelFileManager.ModelFile modelB =
+        new ModelFileManager.ModelFile(
+            new File("/path/a"),
+            1,
+            Collections.singletonList(Locale.forLanguageTag("ja")),
+            "ja",
+            false);
+
+    assertThat(modelA).isEqualTo(modelB);
+  }
+
+  @Test
+  public void modelFile_different() {
+    ModelFileManager.ModelFile modelA =
+        new ModelFileManager.ModelFile(
+            new File("/path/a"),
+            1,
+            Collections.singletonList(Locale.forLanguageTag("ja")),
+            "ja",
+            false);
+
+    ModelFileManager.ModelFile modelB =
+        new ModelFileManager.ModelFile(
+            new File("/path/b"),
+            1,
+            Collections.singletonList(Locale.forLanguageTag("ja")),
+            "ja",
+            false);
+
+    assertThat(modelA).isNotEqualTo(modelB);
+  }
+
+  @Test
+  public void modelFile_getPath() {
+    ModelFileManager.ModelFile modelA =
+        new ModelFileManager.ModelFile(
+            new File("/path/a"),
+            1,
+            Collections.singletonList(Locale.forLanguageTag("ja")),
+            "ja",
+            false);
+
+    assertThat(modelA.getPath()).isEqualTo("/path/a");
+  }
+
+  @Test
+  public void modelFile_getName() {
+    ModelFileManager.ModelFile modelA =
+        new ModelFileManager.ModelFile(
+            new File("/path/a"),
+            1,
+            Collections.singletonList(Locale.forLanguageTag("ja")),
+            "ja",
+            false);
+
+    assertThat(modelA.getName()).isEqualTo("a");
+  }
+
+  @Test
+  public void modelFile_isPreferredTo_languageDependentIsBetter() {
+    ModelFileManager.ModelFile modelA =
+        new ModelFileManager.ModelFile(
+            new File("/path/a"),
+            1,
+            Collections.singletonList(Locale.forLanguageTag("ja")),
+            "ja",
+            false);
+
+    ModelFileManager.ModelFile modelB =
+        new ModelFileManager.ModelFile(new File("/path/b"), 2, ImmutableList.of(), "", true);
+
+    assertThat(modelA.isPreferredTo(modelB)).isTrue();
+  }
+
+  @Test
+  public void modelFile_isPreferredTo_version() {
+    ModelFileManager.ModelFile modelA =
+        new ModelFileManager.ModelFile(
+            new File("/path/a"),
+            2,
+            Collections.singletonList(Locale.forLanguageTag("ja")),
+            "ja",
+            false);
+
+    ModelFileManager.ModelFile modelB =
+        new ModelFileManager.ModelFile(new File("/path/b"), 1, Collections.emptyList(), "", false);
+
+    assertThat(modelA.isPreferredTo(modelB)).isTrue();
+  }
+
+  @Test
+  public void testFileSupplierImpl_updatedFileOnly() throws IOException {
+    updatedModelFile.createNewFile();
+    File model1 = new File(factoryModelDir, "test1.model");
+    model1.createNewFile();
+    File model2 = new File(factoryModelDir, "test2.model");
+    model2.createNewFile();
+    new File(factoryModelDir, "not_match_regex.model").createNewFile();
+
+    List<ModelFileManager.ModelFile> modelFiles = modelFileSupplierImpl.get();
+    List<String> modelFilePaths =
+        modelFiles.stream().map(modelFile -> modelFile.getPath()).collect(Collectors.toList());
+
+    assertThat(modelFiles).hasSize(3);
+    assertThat(modelFilePaths)
+        .containsExactly(
+            updatedModelFile.getAbsolutePath(), model1.getAbsolutePath(), model2.getAbsolutePath());
+  }
+
+  @Test
+  public void testFileSupplierImpl_empty() {
+    factoryModelDir.delete();
+    List<ModelFileManager.ModelFile> modelFiles = modelFileSupplierImpl.get();
+
+    assertThat(modelFiles).hasSize(0);
+  }
+
+  private static void recursiveDelete(File f) {
+    if (f.isDirectory()) {
+      for (File innerFile : f.listFiles()) {
+        recursiveDelete(innerFile);
+      }
+    }
+    f.delete();
+  }
+}
diff --git a/java/tests/instrumentation/src/com/android/textclassifier/StringUtilsTest.java b/java/tests/instrumentation/src/com/android/textclassifier/StringUtilsTest.java
new file mode 100644
index 0000000..7511e45
--- /dev/null
+++ b/java/tests/instrumentation/src/com/android/textclassifier/StringUtilsTest.java
@@ -0,0 +1,90 @@
+/*
+ * 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.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * 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.
+ */
+
+package com.android.textclassifier;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.testng.Assert.assertThrows;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class StringUtilsTest {
+
+  @Test
+  public void testGetSubString() {
+    final String text = "Yakuza call themselves 任侠団体";
+    int start;
+    int end;
+    int minimumLength;
+
+    // End index at end of text.
+    start = text.indexOf("任侠団体");
+    end = text.length();
+    minimumLength = 20;
+    assertThat(StringUtils.getSubString(text, start, end, minimumLength))
+        .isEqualTo("call themselves 任侠団体");
+
+    // Start index at beginning of text.
+    start = 0;
+    end = "Yakuza".length();
+    minimumLength = 15;
+    assertThat(StringUtils.getSubString(text, start, end, minimumLength))
+        .isEqualTo("Yakuza call themselves");
+
+    // Text in the middle
+    start = text.indexOf("all");
+    end = start + 1;
+    minimumLength = 10;
+    assertThat(StringUtils.getSubString(text, start, end, minimumLength))
+        .isEqualTo("Yakuza call themselves");
+
+    // Selection >= minimumLength.
+    start = text.indexOf("themselves");
+    end = start + "themselves".length();
+    minimumLength = end - start;
+    assertThat(StringUtils.getSubString(text, start, end, minimumLength)).isEqualTo("themselves");
+
+    // text.length < minimumLength.
+    minimumLength = text.length() + 1;
+    assertThat(StringUtils.getSubString(text, start, end, minimumLength)).isEqualTo(text);
+  }
+
+  @Test
+  public void testGetSubString_invalidParams() {
+    final String text = "The Yoruba regard Olodumare as the principal agent of creation";
+    final int length = text.length();
+    final int minimumLength = 10;
+
+    // Null text
+    assertThrows(
+        NullPointerException.class, () -> StringUtils.getSubString(null, 0, 1, minimumLength));
+    // start > end
+    assertThrows(
+        IllegalArgumentException.class, () -> StringUtils.getSubString(text, 6, 5, minimumLength));
+    // start < 0
+    assertThrows(
+        IllegalArgumentException.class, () -> StringUtils.getSubString(text, -1, 5, minimumLength));
+    // end > text.length
+    assertThrows(
+        IllegalArgumentException.class,
+        () -> StringUtils.getSubString(text, 6, length + 1, minimumLength));
+  }
+}
diff --git a/java/tests/instrumentation/src/com/android/textclassifier/TextClassificationConstantsTest.java b/java/tests/instrumentation/src/com/android/textclassifier/TextClassificationConstantsTest.java
new file mode 100644
index 0000000..6ec2d2c
--- /dev/null
+++ b/java/tests/instrumentation/src/com/android/textclassifier/TextClassificationConstantsTest.java
@@ -0,0 +1,104 @@
+/*
+ * 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.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * 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.
+ */
+
+package com.android.textclassifier;
+
+import static com.google.common.truth.Truth.assertWithMessage;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class TextClassificationConstantsTest {
+
+  private static final float EPSILON = 0.0001f;
+
+  @Test
+  public void testLoadFromString_defaultValues() {
+    final TextClassificationConstants constants = new TextClassificationConstants();
+
+    assertWithMessage("suggest_selection_max_range_length")
+        .that(constants.getSuggestSelectionMaxRangeLength())
+        .isEqualTo(10 * 1000);
+    assertWithMessage("classify_text_max_range_length")
+        .that(constants.getClassifyTextMaxRangeLength())
+        .isEqualTo(10 * 1000);
+    assertWithMessage("generate_links_max_text_length")
+        .that(constants.getGenerateLinksMaxTextLength())
+        .isEqualTo(100 * 1000);
+    //        assertWithMessage("generate_links_log_sample_rate")
+    //                .that(constants.getGenerateLinksLogSampleRate()).isEqualTo(100);
+    assertWithMessage("entity_list_default")
+        .that(constants.getEntityListDefault())
+        .containsExactly("address", "email", "url", "phone", "date", "datetime", "flight");
+    assertWithMessage("entity_list_not_editable")
+        .that(constants.getEntityListNotEditable())
+        .containsExactly("address", "email", "url", "phone", "date", "datetime", "flight");
+    assertWithMessage("entity_list_editable")
+        .that(constants.getEntityListEditable())
+        .containsExactly("address", "email", "url", "phone", "date", "datetime", "flight");
+    assertWithMessage("in_app_conversation_action_types_default")
+        .that(constants.getInAppConversationActionTypes())
+        .containsExactly(
+            "text_reply",
+            "create_reminder",
+            "call_phone",
+            "open_url",
+            "send_email",
+            "send_sms",
+            "track_flight",
+            "view_calendar",
+            "view_map",
+            "add_contact",
+            "copy");
+    assertWithMessage("notification_conversation_action_types_default")
+        .that(constants.getNotificationConversationActionTypes())
+        .containsExactly(
+            "text_reply",
+            "create_reminder",
+            "call_phone",
+            "open_url",
+            "send_email",
+            "send_sms",
+            "track_flight",
+            "view_calendar",
+            "view_map",
+            "add_contact",
+            "copy");
+    assertWithMessage("lang_id_threshold_override")
+        .that(constants.getLangIdThresholdOverride())
+        .isWithin(EPSILON)
+        .of(-1f);
+    Assert.assertArrayEquals(
+        "lang_id_context_settings",
+        constants.getLangIdContextSettings(),
+        new float[] {20, 1, 0.4f},
+        EPSILON);
+    assertWithMessage("detect_language_from_text_enabled")
+        .that(constants.isDetectLanguagesFromTextEnabled())
+        .isTrue();
+    assertWithMessage("template_intent_factory_enabled")
+        .that(constants.isTemplateIntentFactoryEnabled())
+        .isTrue();
+    assertWithMessage("translate_in_classification_enabled")
+        .that(constants.isTranslateInClassificationEnabled())
+        .isTrue();
+  }
+}
diff --git a/java/tests/instrumentation/src/com/android/textclassifier/TextClassifierImplTest.java b/java/tests/instrumentation/src/com/android/textclassifier/TextClassifierImplTest.java
new file mode 100644
index 0000000..2ebfa6b
--- /dev/null
+++ b/java/tests/instrumentation/src/com/android/textclassifier/TextClassifierImplTest.java
@@ -0,0 +1,653 @@
+/*
+ * 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.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * 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.
+ */
+
+package com.android.textclassifier;
+
+import static org.hamcrest.CoreMatchers.not;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+import static org.testng.Assert.assertThrows;
+
+import android.app.RemoteAction;
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.LocaleList;
+import android.text.Spannable;
+import android.text.SpannableString;
+import android.view.textclassifier.ConversationAction;
+import android.view.textclassifier.ConversationActions;
+import android.view.textclassifier.TextClassification;
+import android.view.textclassifier.TextClassifier;
+import android.view.textclassifier.TextLanguage;
+import android.view.textclassifier.TextLinks;
+import android.view.textclassifier.TextSelection;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+import com.google.common.collect.ImmutableList;
+import com.google.common.truth.Truth;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import org.hamcrest.BaseMatcher;
+import org.hamcrest.Description;
+import org.hamcrest.Matcher;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Testing {@link TextClassifierImplTest} APIs on local and system textclassifier.
+ *
+ * <p>Tests are skipped if such a textclassifier does not exist.
+ */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class TextClassifierImplTest {
+
+  // TODO: Implement TextClassifierService testing.
+  private static final String TYPE_COPY = "copy";
+  private static final LocaleList LOCALES = LocaleList.forLanguageTags("en-US");
+  private static final String NO_TYPE = null;
+
+  private TextClassifierImpl classifier;
+
+  @Before
+  public void setup() {
+    Context context = ApplicationProvider.getApplicationContext();
+    classifier = new TextClassifierImpl(context, new TextClassificationConstants());
+  }
+
+  @Test
+  public void testSuggestSelection() {
+    String text = "Contact me at droid@android.com";
+    String selected = "droid";
+    String suggested = "droid@android.com";
+    int startIndex = text.indexOf(selected);
+    int endIndex = startIndex + selected.length();
+    int smartStartIndex = text.indexOf(suggested);
+    int smartEndIndex = smartStartIndex + suggested.length();
+    TextSelection.Request request =
+        new TextSelection.Request.Builder(text, startIndex, endIndex)
+            .setDefaultLocales(LOCALES)
+            .build();
+
+    TextSelection selection = classifier.suggestSelection(request);
+    assertThat(
+        selection, isTextSelection(smartStartIndex, smartEndIndex, TextClassifier.TYPE_EMAIL));
+  }
+
+  @Test
+  public void testSuggestSelection_url() {
+    String text = "Visit http://www.android.com for more information";
+    String selected = "http";
+    String suggested = "http://www.android.com";
+    int startIndex = text.indexOf(selected);
+    int endIndex = startIndex + selected.length();
+    int smartStartIndex = text.indexOf(suggested);
+    int smartEndIndex = smartStartIndex + suggested.length();
+    TextSelection.Request request =
+        new TextSelection.Request.Builder(text, startIndex, endIndex)
+            .setDefaultLocales(LOCALES)
+            .build();
+
+    TextSelection selection = classifier.suggestSelection(request);
+    assertThat(selection, isTextSelection(smartStartIndex, smartEndIndex, TextClassifier.TYPE_URL));
+  }
+
+  @Test
+  public void testSmartSelection_withEmoji() {
+    String text = "\uD83D\uDE02 Hello.";
+    String selected = "Hello";
+    int startIndex = text.indexOf(selected);
+    int endIndex = startIndex + selected.length();
+    TextSelection.Request request =
+        new TextSelection.Request.Builder(text, startIndex, endIndex)
+            .setDefaultLocales(LOCALES)
+            .build();
+
+    TextSelection selection = classifier.suggestSelection(request);
+    assertThat(selection, isTextSelection(startIndex, endIndex, NO_TYPE));
+  }
+
+  @Test
+  public void testClassifyText() {
+    String text = "Contact me at droid@android.com";
+    String classifiedText = "droid@android.com";
+    int startIndex = text.indexOf(classifiedText);
+    int endIndex = startIndex + classifiedText.length();
+    TextClassification.Request request =
+        new TextClassification.Request.Builder(text, startIndex, endIndex)
+            .setDefaultLocales(LOCALES)
+            .build();
+
+    TextClassification classification = classifier.classifyText(request);
+    assertThat(classification, isTextClassification(classifiedText, TextClassifier.TYPE_EMAIL));
+  }
+
+  @Test
+  public void testClassifyText_url() {
+    String text = "Visit www.android.com for more information";
+    String classifiedText = "www.android.com";
+    int startIndex = text.indexOf(classifiedText);
+    int endIndex = startIndex + classifiedText.length();
+    TextClassification.Request request =
+        new TextClassification.Request.Builder(text, startIndex, endIndex)
+            .setDefaultLocales(LOCALES)
+            .build();
+
+    TextClassification classification = classifier.classifyText(request);
+    assertThat(classification, isTextClassification(classifiedText, TextClassifier.TYPE_URL));
+    assertThat(classification, containsIntentWithAction(Intent.ACTION_VIEW));
+  }
+
+  @Test
+  public void testClassifyText_address() {
+    String text = "Brandschenkestrasse 110, Zürich, Switzerland";
+    TextClassification.Request request =
+        new TextClassification.Request.Builder(text, 0, text.length())
+            .setDefaultLocales(LOCALES)
+            .build();
+
+    TextClassification classification = classifier.classifyText(request);
+    assertThat(classification, isTextClassification(text, TextClassifier.TYPE_ADDRESS));
+  }
+
+  @Test
+  public void testClassifyText_url_inCaps() {
+    String text = "Visit HTTP://ANDROID.COM for more information";
+    String classifiedText = "HTTP://ANDROID.COM";
+    int startIndex = text.indexOf(classifiedText);
+    int endIndex = startIndex + classifiedText.length();
+    TextClassification.Request request =
+        new TextClassification.Request.Builder(text, startIndex, endIndex)
+            .setDefaultLocales(LOCALES)
+            .build();
+
+    TextClassification classification = classifier.classifyText(request);
+    assertThat(classification, isTextClassification(classifiedText, TextClassifier.TYPE_URL));
+    assertThat(classification, containsIntentWithAction(Intent.ACTION_VIEW));
+  }
+
+  @Test
+  public void testClassifyText_date() {
+    String text = "Let's meet on January 9, 2018.";
+    String classifiedText = "January 9, 2018";
+    int startIndex = text.indexOf(classifiedText);
+    int endIndex = startIndex + classifiedText.length();
+    TextClassification.Request request =
+        new TextClassification.Request.Builder(text, startIndex, endIndex)
+            .setDefaultLocales(LOCALES)
+            .build();
+
+    TextClassification classification = classifier.classifyText(request);
+    assertThat(classification, isTextClassification(classifiedText, TextClassifier.TYPE_DATE));
+    Bundle extras = classification.getExtras();
+    List<Bundle> entities = ExtrasUtils.getEntities(extras);
+    Truth.assertThat(entities).hasSize(1);
+    Bundle entity = entities.get(0);
+    Truth.assertThat(ExtrasUtils.getEntityType(entity)).isEqualTo(TextClassifier.TYPE_DATE);
+  }
+
+  @Test
+  public void testClassifyText_datetime() {
+    String text = "Let's meet 2018/01/01 10:30:20.";
+    String classifiedText = "2018/01/01 10:30:20";
+    int startIndex = text.indexOf(classifiedText);
+    int endIndex = startIndex + classifiedText.length();
+    TextClassification.Request request =
+        new TextClassification.Request.Builder(text, startIndex, endIndex)
+            .setDefaultLocales(LOCALES)
+            .build();
+
+    TextClassification classification = classifier.classifyText(request);
+    assertThat(classification, isTextClassification(classifiedText, TextClassifier.TYPE_DATE_TIME));
+  }
+
+  @Test
+  public void testClassifyText_foreignText() {
+    LocaleList originalLocales = LocaleList.getDefault();
+    LocaleList.setDefault(LocaleList.forLanguageTags("en"));
+    String japaneseText = "これは日本語のテキストです";
+
+    Context context =
+        new FakeContextBuilder()
+            .setIntentComponent(Intent.ACTION_TRANSLATE, FakeContextBuilder.DEFAULT_COMPONENT)
+            .build();
+    TextClassifierImpl textClassifier =
+        new TextClassifierImpl(context, new TextClassificationConstants());
+    TextClassification.Request request =
+        new TextClassification.Request.Builder(japaneseText, 0, japaneseText.length())
+            .setDefaultLocales(LOCALES)
+            .build();
+
+    TextClassification classification = textClassifier.classifyText(request);
+    RemoteAction translateAction = classification.getActions().get(0);
+    assertEquals(1, classification.getActions().size());
+    assertEquals(
+        context.getString(com.android.textclassifier.R.string.translate),
+        translateAction.getTitle().toString());
+
+    assertEquals(translateAction, ExtrasUtils.findTranslateAction(classification));
+    Intent intent = ExtrasUtils.getActionsIntents(classification).get(0);
+    assertEquals(Intent.ACTION_TRANSLATE, intent.getAction());
+    Bundle foreignLanguageInfo = ExtrasUtils.getForeignLanguageExtra(classification);
+    assertEquals("ja", ExtrasUtils.getEntityType(foreignLanguageInfo));
+    assertTrue(ExtrasUtils.getScore(foreignLanguageInfo) >= 0);
+    assertTrue(ExtrasUtils.getScore(foreignLanguageInfo) <= 1);
+    assertTrue(intent.hasExtra(TextClassifier.EXTRA_FROM_TEXT_CLASSIFIER));
+    assertEquals("ja", ExtrasUtils.getTopLanguage(intent).getLanguage());
+
+    LocaleList.setDefault(originalLocales);
+  }
+
+  @Test
+  public void testGenerateLinks_phone() {
+    String text = "The number is +12122537077. See you tonight!";
+    TextLinks.Request request = new TextLinks.Request.Builder(text).build();
+    assertThat(
+        classifier.generateLinks(request),
+        isTextLinksContaining(text, "+12122537077", TextClassifier.TYPE_PHONE));
+  }
+
+  @Test
+  public void testGenerateLinks_exclude() {
+    String text = "You want apple@banana.com. See you tonight!";
+    List<String> hints = ImmutableList.of();
+    List<String> included = ImmutableList.of();
+    List<String> excluded = Arrays.asList(TextClassifier.TYPE_EMAIL);
+    TextLinks.Request request =
+        new TextLinks.Request.Builder(text)
+            .setEntityConfig(TextClassifier.EntityConfig.create(hints, included, excluded))
+            .setDefaultLocales(LOCALES)
+            .build();
+    assertThat(
+        classifier.generateLinks(request),
+        not(isTextLinksContaining(text, "apple@banana.com", TextClassifier.TYPE_EMAIL)));
+  }
+
+  @Test
+  public void testGenerateLinks_explicit_address() {
+    String text = "The address is 1600 Amphitheater Parkway, Mountain View, CA. See you!";
+    List<String> explicit = Arrays.asList(TextClassifier.TYPE_ADDRESS);
+    TextLinks.Request request =
+        new TextLinks.Request.Builder(text)
+            .setEntityConfig(TextClassifier.EntityConfig.createWithExplicitEntityList(explicit))
+            .setDefaultLocales(LOCALES)
+            .build();
+    assertThat(
+        classifier.generateLinks(request),
+        isTextLinksContaining(
+            text, "1600 Amphitheater Parkway, Mountain View, CA", TextClassifier.TYPE_ADDRESS));
+  }
+
+  @Test
+  public void testGenerateLinks_exclude_override() {
+    String text = "You want apple@banana.com. See you tonight!";
+    List<String> hints = ImmutableList.of();
+    List<String> included = Arrays.asList(TextClassifier.TYPE_EMAIL);
+    List<String> excluded = Arrays.asList(TextClassifier.TYPE_EMAIL);
+    TextLinks.Request request =
+        new TextLinks.Request.Builder(text)
+            .setEntityConfig(TextClassifier.EntityConfig.create(hints, included, excluded))
+            .setDefaultLocales(LOCALES)
+            .build();
+    assertThat(
+        classifier.generateLinks(request),
+        not(isTextLinksContaining(text, "apple@banana.com", TextClassifier.TYPE_EMAIL)));
+  }
+
+  @Test
+  public void testGenerateLinks_maxLength() {
+    char[] manySpaces = new char[classifier.getMaxGenerateLinksTextLength()];
+    Arrays.fill(manySpaces, ' ');
+    TextLinks.Request request = new TextLinks.Request.Builder(new String(manySpaces)).build();
+    TextLinks links = classifier.generateLinks(request);
+    assertTrue(links.getLinks().isEmpty());
+  }
+
+  @Test
+  public void testApplyLinks_unsupportedCharacter() {
+    Spannable url = new SpannableString("\u202Emoc.diordna.com");
+    TextLinks.Request request = new TextLinks.Request.Builder(url).build();
+    assertEquals(
+        TextLinks.STATUS_UNSUPPORTED_CHARACTER,
+        classifier.generateLinks(request).apply(url, 0, null));
+  }
+
+  @Test
+  public void testGenerateLinks_tooLong() {
+    char[] manySpaces = new char[classifier.getMaxGenerateLinksTextLength() + 1];
+    Arrays.fill(manySpaces, ' ');
+    TextLinks.Request request = new TextLinks.Request.Builder(new String(manySpaces)).build();
+    assertThrows(IllegalArgumentException.class, () -> classifier.generateLinks(request));
+  }
+
+  @Test
+  public void testGenerateLinks_entityData() {
+    String text = "The number is +12122537077.";
+    Bundle extras = new Bundle();
+    ExtrasUtils.putIsSerializedEntityDataEnabled(extras, true);
+    TextLinks.Request request = new TextLinks.Request.Builder(text).setExtras(extras).build();
+
+    TextLinks textLinks = classifier.generateLinks(request);
+
+    Truth.assertThat(textLinks.getLinks()).hasSize(1);
+    TextLinks.TextLink textLink = textLinks.getLinks().iterator().next();
+    List<Bundle> entities = ExtrasUtils.getEntities(textLink.getExtras());
+    Truth.assertThat(entities).hasSize(1);
+    Bundle entity = entities.get(0);
+    Truth.assertThat(ExtrasUtils.getEntityType(entity)).isEqualTo(TextClassifier.TYPE_PHONE);
+  }
+
+  @Test
+  public void testGenerateLinks_entityData_disabled() {
+    String text = "The number is +12122537077.";
+    TextLinks.Request request = new TextLinks.Request.Builder(text).build();
+
+    TextLinks textLinks = classifier.generateLinks(request);
+
+    Truth.assertThat(textLinks.getLinks()).hasSize(1);
+    TextLinks.TextLink textLink = textLinks.getLinks().iterator().next();
+    List<Bundle> entities = ExtrasUtils.getEntities(textLink.getExtras());
+    Truth.assertThat(entities).isNull();
+  }
+
+  @Test
+  public void testDetectLanguage() {
+    String text = "This is English text";
+    TextLanguage.Request request = new TextLanguage.Request.Builder(text).build();
+    TextLanguage textLanguage = classifier.detectLanguage(request);
+    assertThat(textLanguage, isTextLanguage("en"));
+  }
+
+  @Test
+  public void testDetectLanguage_japanese() {
+    String text = "これは日本語のテキストです";
+    TextLanguage.Request request = new TextLanguage.Request.Builder(text).build();
+    TextLanguage textLanguage = classifier.detectLanguage(request);
+    assertThat(textLanguage, isTextLanguage("ja"));
+  }
+
+  @Ignore // Doesn't work without a language-based model.
+  @Test
+  public void testSuggestConversationActions_textReplyOnly_maxOne() {
+    ConversationActions.Message message =
+        new ConversationActions.Message.Builder(ConversationActions.Message.PERSON_USER_OTHERS)
+            .setText("Where are you?")
+            .build();
+    TextClassifier.EntityConfig typeConfig =
+        new TextClassifier.EntityConfig.Builder()
+            .includeTypesFromTextClassifier(false)
+            .setIncludedTypes(Collections.singletonList(ConversationAction.TYPE_TEXT_REPLY))
+            .build();
+    ConversationActions.Request request =
+        new ConversationActions.Request.Builder(Collections.singletonList(message))
+            .setMaxSuggestions(1)
+            .setTypeConfig(typeConfig)
+            .build();
+
+    ConversationActions conversationActions = classifier.suggestConversationActions(request);
+    Truth.assertThat(conversationActions.getConversationActions()).hasSize(1);
+    ConversationAction conversationAction = conversationActions.getConversationActions().get(0);
+    Truth.assertThat(conversationAction.getType()).isEqualTo(ConversationAction.TYPE_TEXT_REPLY);
+    Truth.assertThat(conversationAction.getTextReply()).isNotNull();
+  }
+
+  @Ignore // Doesn't work without a language-based model.
+  @Test
+  public void testSuggestConversationActions_textReplyOnly_noMax() {
+    ConversationActions.Message message =
+        new ConversationActions.Message.Builder(ConversationActions.Message.PERSON_USER_OTHERS)
+            .setText("Where are you?")
+            .build();
+    TextClassifier.EntityConfig typeConfig =
+        new TextClassifier.EntityConfig.Builder()
+            .includeTypesFromTextClassifier(false)
+            .setIncludedTypes(Collections.singletonList(ConversationAction.TYPE_TEXT_REPLY))
+            .build();
+    ConversationActions.Request request =
+        new ConversationActions.Request.Builder(Collections.singletonList(message))
+            .setTypeConfig(typeConfig)
+            .build();
+
+    ConversationActions conversationActions = classifier.suggestConversationActions(request);
+    assertTrue(conversationActions.getConversationActions().size() > 1);
+    for (ConversationAction conversationAction : conversationActions.getConversationActions()) {
+      assertThat(conversationAction, isConversationAction(ConversationAction.TYPE_TEXT_REPLY));
+    }
+  }
+
+  @Test
+  public void testSuggestConversationActions_openUrl() {
+    ConversationActions.Message message =
+        new ConversationActions.Message.Builder(ConversationActions.Message.PERSON_USER_OTHERS)
+            .setText("Check this out: https://www.android.com")
+            .build();
+    TextClassifier.EntityConfig typeConfig =
+        new TextClassifier.EntityConfig.Builder()
+            .includeTypesFromTextClassifier(false)
+            .setIncludedTypes(Collections.singletonList(ConversationAction.TYPE_OPEN_URL))
+            .build();
+    ConversationActions.Request request =
+        new ConversationActions.Request.Builder(Collections.singletonList(message))
+            .setMaxSuggestions(1)
+            .setTypeConfig(typeConfig)
+            .build();
+
+    ConversationActions conversationActions = classifier.suggestConversationActions(request);
+    Truth.assertThat(conversationActions.getConversationActions()).hasSize(1);
+    ConversationAction conversationAction = conversationActions.getConversationActions().get(0);
+    Truth.assertThat(conversationAction.getType()).isEqualTo(ConversationAction.TYPE_OPEN_URL);
+    Intent actionIntent = ExtrasUtils.getActionIntent(conversationAction.getExtras());
+    Truth.assertThat(actionIntent.getAction()).isEqualTo(Intent.ACTION_VIEW);
+    Truth.assertThat(actionIntent.getData()).isEqualTo(Uri.parse("https://www.android.com"));
+  }
+
+  @Ignore // Doesn't work without a language-based model.
+  @Test
+  public void testSuggestConversationActions_copy() {
+    ConversationActions.Message message =
+        new ConversationActions.Message.Builder(ConversationActions.Message.PERSON_USER_OTHERS)
+            .setText("Authentication code: 12345")
+            .build();
+    TextClassifier.EntityConfig typeConfig =
+        new TextClassifier.EntityConfig.Builder()
+            .includeTypesFromTextClassifier(false)
+            .setIncludedTypes(Collections.singletonList(TYPE_COPY))
+            .build();
+    ConversationActions.Request request =
+        new ConversationActions.Request.Builder(Collections.singletonList(message))
+            .setMaxSuggestions(1)
+            .setTypeConfig(typeConfig)
+            .build();
+
+    ConversationActions conversationActions = classifier.suggestConversationActions(request);
+    Truth.assertThat(conversationActions.getConversationActions()).hasSize(1);
+    ConversationAction conversationAction = conversationActions.getConversationActions().get(0);
+    Truth.assertThat(conversationAction.getType()).isEqualTo(TYPE_COPY);
+    Truth.assertThat(conversationAction.getTextReply()).isAnyOf(null, "");
+    Truth.assertThat(conversationAction.getAction()).isNull();
+    String code = ExtrasUtils.getCopyText(conversationAction.getExtras());
+    Truth.assertThat(code).isEqualTo("12345");
+    Truth.assertThat(ExtrasUtils.getSerializedEntityData(conversationAction.getExtras()))
+        .isNotEmpty();
+  }
+
+  @Test
+  public void testSuggetsConversationActions_deduplicate() {
+    ConversationActions.Message message =
+        new ConversationActions.Message.Builder(ConversationActions.Message.PERSON_USER_OTHERS)
+            .setText("a@android.com b@android.com")
+            .build();
+    ConversationActions.Request request =
+        new ConversationActions.Request.Builder(Collections.singletonList(message))
+            .setMaxSuggestions(3)
+            .build();
+
+    ConversationActions conversationActions = classifier.suggestConversationActions(request);
+
+    Truth.assertThat(conversationActions.getConversationActions()).isEmpty();
+  }
+
+  private static Matcher<TextSelection> isTextSelection(
+      final int startIndex, final int endIndex, final String type) {
+    return new BaseMatcher<TextSelection>() {
+      @Override
+      public boolean matches(Object o) {
+        if (o instanceof TextSelection) {
+          TextSelection selection = (TextSelection) o;
+          return startIndex == selection.getSelectionStartIndex()
+              && endIndex == selection.getSelectionEndIndex()
+              && typeMatches(selection, type);
+        }
+        return false;
+      }
+
+      private boolean typeMatches(TextSelection selection, String type) {
+        return type == null
+            || (selection.getEntityCount() > 0
+                && type.trim().equalsIgnoreCase(selection.getEntity(0)));
+      }
+
+      @Override
+      public void describeTo(Description description) {
+        description.appendValue(String.format("%d, %d, %s", startIndex, endIndex, type));
+      }
+    };
+  }
+
+  private static Matcher<TextLinks> isTextLinksContaining(
+      final String text, final String substring, final String type) {
+    return new BaseMatcher<TextLinks>() {
+
+      @Override
+      public void describeTo(Description description) {
+        description
+            .appendText("text=")
+            .appendValue(text)
+            .appendText(", substring=")
+            .appendValue(substring)
+            .appendText(", type=")
+            .appendValue(type);
+      }
+
+      @Override
+      public boolean matches(Object o) {
+        if (o instanceof TextLinks) {
+          for (TextLinks.TextLink link : ((TextLinks) o).getLinks()) {
+            if (text.subSequence(link.getStart(), link.getEnd()).toString().equals(substring)) {
+              return type.equals(link.getEntity(0));
+            }
+          }
+        }
+        return false;
+      }
+    };
+  }
+
+  private static Matcher<TextClassification> isTextClassification(
+      final String text, final String type) {
+    return new BaseMatcher<TextClassification>() {
+      @Override
+      public boolean matches(Object o) {
+        if (o instanceof TextClassification) {
+          TextClassification result = (TextClassification) o;
+          return text.equals(result.getText())
+              && result.getEntityCount() > 0
+              && type.equals(result.getEntity(0));
+        }
+        return false;
+      }
+
+      @Override
+      public void describeTo(Description description) {
+        description.appendText("text=").appendValue(text).appendText(", type=").appendValue(type);
+      }
+    };
+  }
+
+  private static Matcher<TextClassification> containsIntentWithAction(final String action) {
+    return new BaseMatcher<TextClassification>() {
+      @Override
+      public boolean matches(Object o) {
+        if (o instanceof TextClassification) {
+          TextClassification result = (TextClassification) o;
+          return ExtrasUtils.findAction(result, action) != null;
+        }
+        return false;
+      }
+
+      @Override
+      public void describeTo(Description description) {
+        description.appendText("intent action=").appendValue(action);
+      }
+    };
+  }
+
+  private static Matcher<TextLanguage> isTextLanguage(final String languageTag) {
+    return new BaseMatcher<TextLanguage>() {
+      @Override
+      public boolean matches(Object o) {
+        if (o instanceof TextLanguage) {
+          TextLanguage result = (TextLanguage) o;
+          return result.getLocaleHypothesisCount() > 0
+              && languageTag.equals(result.getLocale(0).toLanguageTag());
+        }
+        return false;
+      }
+
+      @Override
+      public void describeTo(Description description) {
+        description.appendText("locale=").appendValue(languageTag);
+      }
+    };
+  }
+
+  private static Matcher<ConversationAction> isConversationAction(String actionType) {
+    return new BaseMatcher<ConversationAction>() {
+      @Override
+      public boolean matches(Object o) {
+        if (!(o instanceof ConversationAction)) {
+          return false;
+        }
+        ConversationAction conversationAction = (ConversationAction) o;
+        if (!actionType.equals(conversationAction.getType())) {
+          return false;
+        }
+        if (ConversationAction.TYPE_TEXT_REPLY.equals(actionType)) {
+          if (conversationAction.getTextReply() == null) {
+            return false;
+          }
+        }
+        if (conversationAction.getConfidenceScore() < 0
+            || conversationAction.getConfidenceScore() > 1) {
+          return false;
+        }
+        return true;
+      }
+
+      @Override
+      public void describeTo(Description description) {
+        description.appendText("actionType=").appendValue(actionType);
+      }
+    };
+  }
+}
diff --git a/java/tests/instrumentation/src/com/android/textclassifier/intent/LabeledIntentTest.java b/java/tests/instrumentation/src/com/android/textclassifier/intent/LabeledIntentTest.java
new file mode 100644
index 0000000..3840823
--- /dev/null
+++ b/java/tests/instrumentation/src/com/android/textclassifier/intent/LabeledIntentTest.java
@@ -0,0 +1,166 @@
+/*
+ * 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.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * 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.
+ */
+
+package com.android.textclassifier.intent;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.testng.Assert.assertThrows;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Bundle;
+import android.view.textclassifier.TextClassifier;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+import com.android.textclassifier.FakeContextBuilder;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public final class LabeledIntentTest {
+  private static final String TITLE_WITHOUT_ENTITY = "Map";
+  private static final String TITLE_WITH_ENTITY = "Map NW14D1";
+  private static final String DESCRIPTION = "Check the map";
+  private static final String DESCRIPTION_WITH_APP_NAME = "Use %1$s to open map";
+  private static final Intent INTENT =
+      new Intent(Intent.ACTION_VIEW).setDataAndNormalize(Uri.parse("http://www.android.com"));
+  private static final int REQUEST_CODE = 42;
+  private static final Bundle TEXT_LANGUAGES_BUNDLE = Bundle.EMPTY;
+  private static final String APP_LABEL = "fake";
+
+  private Context context;
+
+  @Before
+  public void setup() {
+    final ComponentName component = FakeContextBuilder.DEFAULT_COMPONENT;
+    context =
+        new FakeContextBuilder()
+            .setIntentComponent(Intent.ACTION_VIEW, component)
+            .setAppLabel(component.getPackageName(), APP_LABEL)
+            .build();
+  }
+
+  @Test
+  public void resolve_preferTitleWithEntity() {
+    LabeledIntent labeledIntent =
+        new LabeledIntent(
+            TITLE_WITHOUT_ENTITY, TITLE_WITH_ENTITY, DESCRIPTION, null, INTENT, REQUEST_CODE);
+
+    LabeledIntent.Result result =
+        labeledIntent.resolve(context, /*titleChooser*/ null, TEXT_LANGUAGES_BUNDLE);
+
+    assertThat(result).isNotNull();
+    assertThat(result.remoteAction.getTitle().toString()).isEqualTo(TITLE_WITH_ENTITY);
+    assertThat(result.remoteAction.getContentDescription().toString()).isEqualTo(DESCRIPTION);
+    Intent intent = result.resolvedIntent;
+    assertThat(intent.getAction()).isEqualTo(intent.getAction());
+    assertThat(intent.getComponent()).isNotNull();
+    assertThat(intent.hasExtra(TextClassifier.EXTRA_FROM_TEXT_CLASSIFIER)).isTrue();
+  }
+
+  @Test
+  public void resolve_useAvailableTitle() {
+    LabeledIntent labeledIntent =
+        new LabeledIntent(TITLE_WITHOUT_ENTITY, null, DESCRIPTION, null, INTENT, REQUEST_CODE);
+
+    LabeledIntent.Result result =
+        labeledIntent.resolve(context, /*titleChooser*/ null, TEXT_LANGUAGES_BUNDLE);
+
+    assertThat(result).isNotNull();
+    assertThat(result.remoteAction.getTitle().toString()).isEqualTo(TITLE_WITHOUT_ENTITY);
+    assertThat(result.remoteAction.getContentDescription().toString()).isEqualTo(DESCRIPTION);
+    Intent intent = result.resolvedIntent;
+    assertThat(intent.getAction()).isEqualTo(intent.getAction());
+    assertThat(intent.getComponent()).isNotNull();
+  }
+
+  @Test
+  public void resolve_titleChooser() {
+    LabeledIntent labeledIntent =
+        new LabeledIntent(TITLE_WITHOUT_ENTITY, null, DESCRIPTION, null, INTENT, REQUEST_CODE);
+
+    LabeledIntent.Result result =
+        labeledIntent.resolve(
+            context, (labeledIntent1, resolveInfo) -> "chooser", TEXT_LANGUAGES_BUNDLE);
+
+    assertThat(result).isNotNull();
+    assertThat(result.remoteAction.getTitle().toString()).isEqualTo("chooser");
+    assertThat(result.remoteAction.getContentDescription().toString()).isEqualTo(DESCRIPTION);
+    Intent intent = result.resolvedIntent;
+    assertThat(intent.getAction()).isEqualTo(intent.getAction());
+    assertThat(intent.getComponent()).isNotNull();
+  }
+
+  @Test
+  public void resolve_titleChooserReturnsNull() {
+    LabeledIntent labeledIntent =
+        new LabeledIntent(TITLE_WITHOUT_ENTITY, null, DESCRIPTION, null, INTENT, REQUEST_CODE);
+
+    LabeledIntent.Result result =
+        labeledIntent.resolve(
+            context, (labeledIntent1, resolveInfo) -> null, TEXT_LANGUAGES_BUNDLE);
+
+    assertThat(result).isNotNull();
+    assertThat(result.remoteAction.getTitle().toString()).isEqualTo(TITLE_WITHOUT_ENTITY);
+    assertThat(result.remoteAction.getContentDescription().toString()).isEqualTo(DESCRIPTION);
+    Intent intent = result.resolvedIntent;
+    assertThat(intent.getAction()).isEqualTo(intent.getAction());
+    assertThat(intent.getComponent()).isNotNull();
+  }
+
+  @Test
+  public void resolve_missingTitle() {
+    assertThrows(
+        IllegalArgumentException.class,
+        () -> new LabeledIntent(null, null, DESCRIPTION, null, INTENT, REQUEST_CODE));
+  }
+
+  @Test
+  public void resolve_noIntentHandler() {
+    // See setup(). context can only resolve Intent.ACTION_VIEW.
+    Intent unresolvableIntent = new Intent(Intent.ACTION_TRANSLATE);
+    LabeledIntent labeledIntent =
+        new LabeledIntent(
+            TITLE_WITHOUT_ENTITY, null, DESCRIPTION, null, unresolvableIntent, REQUEST_CODE);
+
+    LabeledIntent.Result result = labeledIntent.resolve(context, null, null);
+
+    assertThat(result).isNull();
+  }
+
+  @Test
+  public void resolve_descriptionWithAppName() {
+    LabeledIntent labeledIntent =
+        new LabeledIntent(
+            TITLE_WITHOUT_ENTITY,
+            TITLE_WITH_ENTITY,
+            DESCRIPTION,
+            DESCRIPTION_WITH_APP_NAME,
+            INTENT,
+            REQUEST_CODE);
+
+    LabeledIntent.Result result =
+        labeledIntent.resolve(context, /*titleChooser*/ null, TEXT_LANGUAGES_BUNDLE);
+
+    assertThat(result).isNotNull();
+    assertThat(result.remoteAction.getContentDescription().toString())
+        .isEqualTo("Use fake to open map");
+  }
+}
diff --git a/java/tests/instrumentation/src/com/android/textclassifier/intent/LegacyIntentClassificationFactoryTest.java b/java/tests/instrumentation/src/com/android/textclassifier/intent/LegacyIntentClassificationFactoryTest.java
new file mode 100644
index 0000000..389c98e
--- /dev/null
+++ b/java/tests/instrumentation/src/com/android/textclassifier/intent/LegacyIntentClassificationFactoryTest.java
@@ -0,0 +1,120 @@
+/*
+ * 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.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * 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.
+ */
+
+package com.android.textclassifier.intent;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.Intent;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+import com.google.android.textclassifier.AnnotatorModel;
+import java.util.List;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class LegacyIntentClassificationFactoryTest {
+
+  private static final String TEXT = "text";
+  private static final String TYPE_DICTIONARY = "dictionary";
+
+  private LegacyClassificationIntentFactory legacyIntentClassificationFactory;
+
+  @Before
+  public void setup() {
+    legacyIntentClassificationFactory = new LegacyClassificationIntentFactory();
+  }
+
+  @Test
+  public void create_typeDictionary() {
+    AnnotatorModel.ClassificationResult classificationResult =
+        new AnnotatorModel.ClassificationResult(
+            TYPE_DICTIONARY,
+            1.0f,
+            null,
+            null,
+            null,
+            null,
+            null,
+            null,
+            null,
+            null,
+            null,
+            null,
+            null,
+            null,
+            null,
+            null,
+            0L,
+            0L,
+            0d);
+
+    List<LabeledIntent> intents =
+        legacyIntentClassificationFactory.create(
+            ApplicationProvider.getApplicationContext(),
+            TEXT,
+            /* foreignText */ false,
+            null,
+            classificationResult);
+
+    assertThat(intents).hasSize(1);
+    LabeledIntent labeledIntent = intents.get(0);
+    Intent intent = labeledIntent.intent;
+    assertThat(intent.getAction()).isEqualTo(Intent.ACTION_DEFINE);
+    assertThat(intent.getStringExtra(Intent.EXTRA_TEXT)).isEqualTo(TEXT);
+  }
+
+  @Test
+  public void create_translateAndDictionary() {
+    AnnotatorModel.ClassificationResult classificationResult =
+        new AnnotatorModel.ClassificationResult(
+            TYPE_DICTIONARY,
+            1.0f,
+            null,
+            null,
+            null,
+            null,
+            null,
+            null,
+            null,
+            null,
+            null,
+            null,
+            null,
+            null,
+            null,
+            null,
+            0L,
+            0L,
+            0d);
+
+    List<LabeledIntent> intents =
+        legacyIntentClassificationFactory.create(
+            ApplicationProvider.getApplicationContext(),
+            TEXT,
+            /* foreignText */ true,
+            null,
+            classificationResult);
+
+    assertThat(intents).hasSize(2);
+    assertThat(intents.get(0).intent.getAction()).isEqualTo(Intent.ACTION_DEFINE);
+    assertThat(intents.get(1).intent.getAction()).isEqualTo(Intent.ACTION_TRANSLATE);
+  }
+}
diff --git a/java/tests/instrumentation/src/com/android/textclassifier/intent/TemplateClassificationIntentFactoryTest.java b/java/tests/instrumentation/src/com/android/textclassifier/intent/TemplateClassificationIntentFactoryTest.java
new file mode 100644
index 0000000..42176bd
--- /dev/null
+++ b/java/tests/instrumentation/src/com/android/textclassifier/intent/TemplateClassificationIntentFactoryTest.java
@@ -0,0 +1,240 @@
+/*
+ * 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.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * 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.
+ */
+
+package com.android.textclassifier.intent;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.ArgumentMatchers.same;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+
+import android.content.Context;
+import android.content.Intent;
+import android.view.textclassifier.TextClassifier;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+import com.google.android.textclassifier.AnnotatorModel;
+import com.google.android.textclassifier.RemoteActionTemplate;
+import java.util.List;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class TemplateClassificationIntentFactoryTest {
+
+  private static final String TEXT = "text";
+  private static final String TITLE_WITHOUT_ENTITY = "Map";
+  private static final String DESCRIPTION = "Opens in Maps";
+  private static final String DESCRIPTION_WITH_APP_NAME = "Use %1$s to open Map";
+  private static final String ACTION = Intent.ACTION_VIEW;
+
+  @Mock private ClassificationIntentFactory fallback;
+  private TemplateClassificationIntentFactory templateClassificationIntentFactory;
+
+  @Before
+  public void setup() {
+    MockitoAnnotations.initMocks(this);
+    templateClassificationIntentFactory =
+        new TemplateClassificationIntentFactory(new TemplateIntentFactory(), fallback);
+  }
+
+  @Test
+  public void create_foreignText() {
+    AnnotatorModel.ClassificationResult classificationResult =
+        new AnnotatorModel.ClassificationResult(
+            TextClassifier.TYPE_ADDRESS,
+            1.0f,
+            null,
+            null,
+            null,
+            null,
+            null,
+            null,
+            null,
+            null,
+            null,
+            null,
+            null,
+            null,
+            null,
+            createRemoteActionTemplates(),
+            0L,
+            0L,
+            0d);
+
+    List<LabeledIntent> intents =
+        templateClassificationIntentFactory.create(
+            ApplicationProvider.getApplicationContext(),
+            TEXT,
+            /* foreignText */ true,
+            null,
+            classificationResult);
+
+    assertThat(intents).hasSize(2);
+    LabeledIntent labeledIntent = intents.get(0);
+    assertThat(labeledIntent.titleWithoutEntity).isEqualTo(TITLE_WITHOUT_ENTITY);
+    Intent intent = labeledIntent.intent;
+    assertThat(intent.getAction()).isEqualTo(ACTION);
+
+    labeledIntent = intents.get(1);
+    intent = labeledIntent.intent;
+    assertThat(intent.getAction()).isEqualTo(Intent.ACTION_TRANSLATE);
+  }
+
+  @Test
+  public void create_notForeignText() {
+    AnnotatorModel.ClassificationResult classificationResult =
+        new AnnotatorModel.ClassificationResult(
+            TextClassifier.TYPE_ADDRESS,
+            1.0f,
+            null,
+            null,
+            null,
+            null,
+            null,
+            null,
+            null,
+            null,
+            null,
+            null,
+            null,
+            null,
+            null,
+            createRemoteActionTemplates(),
+            0L,
+            0L,
+            0d);
+
+    List<LabeledIntent> intents =
+        templateClassificationIntentFactory.create(
+            ApplicationProvider.getApplicationContext(),
+            TEXT,
+            /* foreignText */ false,
+            null,
+            classificationResult);
+
+    assertThat(intents).hasSize(1);
+    LabeledIntent labeledIntent = intents.get(0);
+    assertThat(labeledIntent.titleWithoutEntity).isEqualTo(TITLE_WITHOUT_ENTITY);
+    Intent intent = labeledIntent.intent;
+    assertThat(intent.getAction()).isEqualTo(ACTION);
+  }
+
+  @Test
+  public void create_nullTemplate() {
+    AnnotatorModel.ClassificationResult classificationResult =
+        new AnnotatorModel.ClassificationResult(
+            TextClassifier.TYPE_ADDRESS,
+            1.0f,
+            null,
+            null,
+            null,
+            null,
+            null,
+            null,
+            null,
+            null,
+            null,
+            null,
+            null,
+            null,
+            null,
+            null,
+            0L,
+            0L,
+            0d);
+
+    templateClassificationIntentFactory.create(
+        ApplicationProvider.getApplicationContext(),
+        TEXT,
+        /* foreignText */ false,
+        null,
+        classificationResult);
+
+    verify(fallback)
+        .create(
+            same(ApplicationProvider.getApplicationContext()),
+            eq(TEXT),
+            eq(false),
+            eq(null),
+            same(classificationResult));
+  }
+
+  @Test
+  public void create_emptyResult() {
+    AnnotatorModel.ClassificationResult classificationResult =
+        new AnnotatorModel.ClassificationResult(
+            TextClassifier.TYPE_ADDRESS,
+            1.0f,
+            null,
+            null,
+            null,
+            null,
+            null,
+            null,
+            null,
+            null,
+            null,
+            null,
+            null,
+            null,
+            null,
+            new RemoteActionTemplate[0],
+            0L,
+            0L,
+            0d);
+
+    templateClassificationIntentFactory.create(
+        ApplicationProvider.getApplicationContext(),
+        TEXT,
+        /* foreignText */ false,
+        null,
+        classificationResult);
+
+    verify(fallback, never())
+        .create(
+            any(Context.class),
+            eq(TEXT),
+            eq(false),
+            eq(null),
+            any(AnnotatorModel.ClassificationResult.class));
+  }
+
+  private static RemoteActionTemplate[] createRemoteActionTemplates() {
+    return new RemoteActionTemplate[] {
+      new RemoteActionTemplate(
+          TITLE_WITHOUT_ENTITY,
+          null,
+          DESCRIPTION,
+          DESCRIPTION_WITH_APP_NAME,
+          ACTION,
+          null,
+          null,
+          null,
+          null,
+          null,
+          null,
+          null)
+    };
+  }
+}
diff --git a/java/tests/instrumentation/src/com/android/textclassifier/intent/TemplateIntentFactoryTest.java b/java/tests/instrumentation/src/com/android/textclassifier/intent/TemplateIntentFactoryTest.java
new file mode 100644
index 0000000..ee45f18
--- /dev/null
+++ b/java/tests/instrumentation/src/com/android/textclassifier/intent/TemplateIntentFactoryTest.java
@@ -0,0 +1,265 @@
+/*
+ * 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.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * 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.
+ */
+
+package com.android.textclassifier.intent;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.Intent;
+import android.net.Uri;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+import com.google.android.textclassifier.NamedVariant;
+import com.google.android.textclassifier.RemoteActionTemplate;
+import java.util.List;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.MockitoAnnotations;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class TemplateIntentFactoryTest {
+
+  private static final String TITLE_WITHOUT_ENTITY = "Map";
+  private static final String TITLE_WITH_ENTITY = "Map NW14D1";
+  private static final String DESCRIPTION = "Check the map";
+  private static final String DESCRIPTION_WITH_APP_NAME = "Use %1$s to open map";
+  private static final String ACTION = Intent.ACTION_VIEW;
+  private static final String DATA = Uri.parse("http://www.android.com").toString();
+  private static final String TYPE = "text/html";
+  private static final Integer FLAG = Intent.FLAG_ACTIVITY_NEW_TASK;
+  private static final String[] CATEGORY =
+      new String[] {Intent.CATEGORY_DEFAULT, Intent.CATEGORY_APP_BROWSER};
+  private static final String PACKAGE_NAME = "pkg.name";
+  private static final String KEY_ONE = "key1";
+  private static final String VALUE_ONE = "value1";
+  private static final String KEY_TWO = "key2";
+  private static final int VALUE_TWO = 42;
+
+  private static final NamedVariant[] NAMED_VARIANTS =
+      new NamedVariant[] {
+        new NamedVariant(KEY_ONE, VALUE_ONE), new NamedVariant(KEY_TWO, VALUE_TWO)
+      };
+  private static final Integer REQUEST_CODE = 10;
+
+  private TemplateIntentFactory templateIntentFactory;
+
+  @Before
+  public void setup() {
+    MockitoAnnotations.initMocks(this);
+    templateIntentFactory = new TemplateIntentFactory();
+  }
+
+  @Test
+  public void create_full() {
+    RemoteActionTemplate remoteActionTemplate =
+        new RemoteActionTemplate(
+            TITLE_WITHOUT_ENTITY,
+            TITLE_WITH_ENTITY,
+            DESCRIPTION,
+            DESCRIPTION_WITH_APP_NAME,
+            ACTION,
+            DATA,
+            TYPE,
+            FLAG,
+            CATEGORY,
+            /* packageName */ null,
+            NAMED_VARIANTS,
+            REQUEST_CODE);
+
+    List<LabeledIntent> intents =
+        templateIntentFactory.create(new RemoteActionTemplate[] {remoteActionTemplate});
+
+    assertThat(intents).hasSize(1);
+    LabeledIntent labeledIntent = intents.get(0);
+    assertThat(labeledIntent.titleWithoutEntity).isEqualTo(TITLE_WITHOUT_ENTITY);
+    assertThat(labeledIntent.titleWithEntity).isEqualTo(TITLE_WITH_ENTITY);
+    assertThat(labeledIntent.description).isEqualTo(DESCRIPTION);
+    assertThat(labeledIntent.descriptionWithAppName).isEqualTo(DESCRIPTION_WITH_APP_NAME);
+    assertThat(labeledIntent.requestCode).isEqualTo(REQUEST_CODE);
+    Intent intent = labeledIntent.intent;
+    assertThat(intent.getAction()).isEqualTo(ACTION);
+    assertThat(intent.getData().toString()).isEqualTo(DATA);
+    assertThat(intent.getType()).isEqualTo(TYPE);
+    assertThat(intent.getFlags()).isEqualTo(FLAG);
+    assertThat(intent.getCategories()).containsExactly((Object[]) CATEGORY);
+    assertThat(intent.getPackage()).isNull();
+    assertThat(intent.getStringExtra(KEY_ONE)).isEqualTo(VALUE_ONE);
+    assertThat(intent.getIntExtra(KEY_TWO, 0)).isEqualTo(VALUE_TWO);
+  }
+
+  @Test
+  public void normalizesScheme() {
+    RemoteActionTemplate remoteActionTemplate =
+        new RemoteActionTemplate(
+            TITLE_WITHOUT_ENTITY,
+            TITLE_WITH_ENTITY,
+            DESCRIPTION,
+            DESCRIPTION_WITH_APP_NAME,
+            ACTION,
+            "HTTp://www.android.com",
+            TYPE,
+            FLAG,
+            CATEGORY,
+            /* packageName */ null,
+            NAMED_VARIANTS,
+            REQUEST_CODE);
+
+    List<LabeledIntent> intents =
+        templateIntentFactory.create(new RemoteActionTemplate[] {remoteActionTemplate});
+
+    String data = intents.get(0).intent.getData().toString();
+    assertThat(data).isEqualTo("http://www.android.com");
+  }
+
+  @Test
+  public void create_minimal() {
+    RemoteActionTemplate remoteActionTemplate =
+        new RemoteActionTemplate(
+            TITLE_WITHOUT_ENTITY,
+            null,
+            DESCRIPTION,
+            null,
+            ACTION,
+            null,
+            null,
+            null,
+            null,
+            null,
+            null,
+            null);
+
+    List<LabeledIntent> intents =
+        templateIntentFactory.create(new RemoteActionTemplate[] {remoteActionTemplate});
+
+    assertThat(intents).hasSize(1);
+    LabeledIntent labeledIntent = intents.get(0);
+    assertThat(labeledIntent.titleWithoutEntity).isEqualTo(TITLE_WITHOUT_ENTITY);
+    assertThat(labeledIntent.titleWithEntity).isNull();
+    assertThat(labeledIntent.description).isEqualTo(DESCRIPTION);
+    assertThat(labeledIntent.requestCode).isEqualTo(LabeledIntent.DEFAULT_REQUEST_CODE);
+    Intent intent = labeledIntent.intent;
+    assertThat(intent.getAction()).isEqualTo(ACTION);
+    assertThat(intent.getData()).isNull();
+    assertThat(intent.getType()).isNull();
+    assertThat(intent.getFlags()).isEqualTo(0);
+    assertThat(intent.getCategories()).isNull();
+    assertThat(intent.getPackage()).isNull();
+  }
+
+  @Test
+  public void invalidTemplate_nullTemplate() {
+    RemoteActionTemplate remoteActionTemplate = null;
+
+    List<LabeledIntent> intents =
+        templateIntentFactory.create(new RemoteActionTemplate[] {remoteActionTemplate});
+
+    assertThat(intents).isEmpty();
+  }
+
+  @Test
+  public void invalidTemplate_nonEmptyPackageName() {
+    RemoteActionTemplate remoteActionTemplate =
+        new RemoteActionTemplate(
+            TITLE_WITHOUT_ENTITY,
+            TITLE_WITH_ENTITY,
+            DESCRIPTION,
+            DESCRIPTION_WITH_APP_NAME,
+            ACTION,
+            DATA,
+            TYPE,
+            FLAG,
+            CATEGORY,
+            PACKAGE_NAME,
+            NAMED_VARIANTS,
+            REQUEST_CODE);
+
+    List<LabeledIntent> intents =
+        templateIntentFactory.create(new RemoteActionTemplate[] {remoteActionTemplate});
+
+    assertThat(intents).isEmpty();
+  }
+
+  @Test
+  public void invalidTemplate_emptyTitle() {
+    RemoteActionTemplate remoteActionTemplate =
+        new RemoteActionTemplate(
+            null,
+            null,
+            DESCRIPTION,
+            DESCRIPTION_WITH_APP_NAME,
+            ACTION,
+            null,
+            null,
+            null,
+            null,
+            null,
+            null,
+            null);
+
+    List<LabeledIntent> intents =
+        templateIntentFactory.create(new RemoteActionTemplate[] {remoteActionTemplate});
+
+    assertThat(intents).isEmpty();
+  }
+
+  @Test
+  public void invalidTemplate_emptyDescription() {
+    RemoteActionTemplate remoteActionTemplate =
+        new RemoteActionTemplate(
+            TITLE_WITHOUT_ENTITY,
+            TITLE_WITH_ENTITY,
+            null,
+            null,
+            ACTION,
+            null,
+            null,
+            null,
+            null,
+            null,
+            null,
+            null);
+
+    List<LabeledIntent> intents =
+        templateIntentFactory.create(new RemoteActionTemplate[] {remoteActionTemplate});
+
+    assertThat(intents).isEmpty();
+  }
+
+  @Test
+  public void invalidTemplate_emptyIntentAction() {
+    RemoteActionTemplate remoteActionTemplate =
+        new RemoteActionTemplate(
+            TITLE_WITHOUT_ENTITY,
+            TITLE_WITH_ENTITY,
+            DESCRIPTION,
+            DESCRIPTION_WITH_APP_NAME,
+            null,
+            null,
+            null,
+            null,
+            null,
+            null,
+            null,
+            null);
+
+    List<LabeledIntent> intents =
+        templateIntentFactory.create(new RemoteActionTemplate[] {remoteActionTemplate});
+
+    assertThat(intents).isEmpty();
+  }
+}
diff --git a/java/tests/instrumentation/src/com/android/textclassifier/logging/ResultIdUtilsTest.java b/java/tests/instrumentation/src/com/android/textclassifier/logging/ResultIdUtilsTest.java
new file mode 100644
index 0000000..571a97b
--- /dev/null
+++ b/java/tests/instrumentation/src/com/android/textclassifier/logging/ResultIdUtilsTest.java
@@ -0,0 +1,56 @@
+/*
+ * 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.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * 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.
+ */
+
+package com.android.textclassifier.logging;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+import java.util.Collections;
+import java.util.Locale;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class ResultIdUtilsTest {
+  private static final int MODEL_VERSION = 703;
+  private static final int HASH = 12345;
+
+  @Test
+  public void createId_customHash() {
+    String resultId =
+        ResultIdUtils.createId(MODEL_VERSION, Collections.singletonList(Locale.ENGLISH), HASH);
+
+    assertThat(resultId).isEqualTo("androidtc|en_v703|12345");
+  }
+
+  @Test
+  public void createId_selection() {
+    String resultId =
+        ResultIdUtils.createId(
+            ApplicationProvider.getApplicationContext(),
+            "text",
+            1,
+            2,
+            MODEL_VERSION,
+            Collections.singletonList(Locale.ENGLISH));
+
+    assertThat(resultId).matches("androidtc\\|en_v703\\|-?\\d+");
+  }
+}
diff --git a/java/tests/instrumentation/src/com/android/textclassifier/logging/SelectionEventConverterTest.java b/java/tests/instrumentation/src/com/android/textclassifier/logging/SelectionEventConverterTest.java
new file mode 100644
index 0000000..1c4a356
--- /dev/null
+++ b/java/tests/instrumentation/src/com/android/textclassifier/logging/SelectionEventConverterTest.java
@@ -0,0 +1,191 @@
+/*
+ * 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.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * 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.
+ */
+
+package com.android.textclassifier.logging;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.view.textclassifier.SelectionEvent;
+import android.view.textclassifier.TextClassification;
+import android.view.textclassifier.TextClassificationContext;
+import android.view.textclassifier.TextClassificationManager;
+import android.view.textclassifier.TextClassifier;
+import android.view.textclassifier.TextClassifierEvent;
+import android.view.textclassifier.TextSelection;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+import java.util.ArrayDeque;
+import java.util.Collections;
+import java.util.Deque;
+import java.util.Locale;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class SelectionEventConverterTest {
+  private static final String PKG_NAME = "com.pkg";
+  private static final String WIDGET_TYPE = TextClassifier.WIDGET_TYPE_EDITTEXT;
+  private static final int START = 2;
+  private static final int SMART_START = 1;
+  private static final int SMART_END = 3;
+  private TestTextClassifier testTextClassifier;
+  private TextClassifier session;
+
+  @Before
+  public void setup() {
+    TextClassificationManager textClassificationManager =
+        ApplicationProvider.getApplicationContext()
+            .getSystemService(TextClassificationManager.class);
+    testTextClassifier = new TestTextClassifier();
+    textClassificationManager.setTextClassifier(testTextClassifier);
+    session = textClassificationManager.createTextClassificationSession(createEventContext());
+  }
+
+  @Test
+  public void convert_started() {
+    session.onSelectionEvent(
+        SelectionEvent.createSelectionStartedEvent(SelectionEvent.INVOCATION_MANUAL, START));
+
+    SelectionEvent interceptedEvent = testTextClassifier.popLastSelectionEvent();
+    TextClassifierEvent textClassifierEvent =
+        SelectionEventConverter.toTextClassifierEvent(interceptedEvent);
+
+    assertEventContext(textClassifierEvent.getEventContext());
+    assertThat(textClassifierEvent.getEventIndex()).isEqualTo(0);
+    assertThat(textClassifierEvent.getEventType())
+        .isEqualTo(TextClassifierEvent.TYPE_SELECTION_STARTED);
+  }
+
+  @Test
+  public void convert_smartSelection() {
+    session.onSelectionEvent(
+        SelectionEvent.createSelectionStartedEvent(SelectionEvent.INVOCATION_MANUAL, START));
+    String resultId =
+        ResultIdUtils.createId(702, Collections.singletonList(Locale.ENGLISH), /*hash=*/ 12345);
+    session.onSelectionEvent(
+        SelectionEvent.createSelectionActionEvent(
+            SMART_START,
+            SMART_END,
+            SelectionEvent.ACTION_SMART_SHARE,
+            new TextClassification.Builder()
+                .setEntityType(TextClassifier.TYPE_ADDRESS, 1.0f)
+                .setId(resultId)
+                .build()));
+
+    SelectionEvent interceptedEvent = testTextClassifier.popLastSelectionEvent();
+    TextClassifierEvent.TextSelectionEvent textSelectionEvent =
+        (TextClassifierEvent.TextSelectionEvent)
+            SelectionEventConverter.toTextClassifierEvent(interceptedEvent);
+
+    assertEventContext(textSelectionEvent.getEventContext());
+    assertThat(textSelectionEvent.getRelativeWordStartIndex()).isEqualTo(-1);
+    assertThat(textSelectionEvent.getRelativeWordEndIndex()).isEqualTo(1);
+    assertThat(textSelectionEvent.getEventType()).isEqualTo(TextClassifierEvent.TYPE_SMART_ACTION);
+    assertThat(textSelectionEvent.getEventIndex()).isEqualTo(1);
+    assertThat(textSelectionEvent.getEntityTypes())
+        .asList()
+        .containsExactly(TextClassifier.TYPE_ADDRESS);
+    assertThat(textSelectionEvent.getResultId()).isEqualTo(resultId);
+  }
+
+  @Test
+  public void convert_smartShare() {
+    session.onSelectionEvent(
+        SelectionEvent.createSelectionStartedEvent(SelectionEvent.INVOCATION_MANUAL, START));
+    String resultId =
+        ResultIdUtils.createId(702, Collections.singletonList(Locale.ENGLISH), /*hash=*/ 12345);
+    session.onSelectionEvent(
+        SelectionEvent.createSelectionModifiedEvent(
+            SMART_START,
+            SMART_END,
+            new TextSelection.Builder(SMART_START, SMART_END)
+                .setEntityType(TextClassifier.TYPE_ADDRESS, 1.0f)
+                .setId(resultId)
+                .build()));
+
+    SelectionEvent interceptedEvent = testTextClassifier.popLastSelectionEvent();
+    TextClassifierEvent.TextSelectionEvent textSelectionEvent =
+        (TextClassifierEvent.TextSelectionEvent)
+            SelectionEventConverter.toTextClassifierEvent(interceptedEvent);
+
+    assertEventContext(textSelectionEvent.getEventContext());
+    assertThat(textSelectionEvent.getRelativeSuggestedWordStartIndex()).isEqualTo(-1);
+    assertThat(textSelectionEvent.getRelativeSuggestedWordEndIndex()).isEqualTo(1);
+    assertThat(textSelectionEvent.getEventType())
+        .isEqualTo(TextClassifierEvent.TYPE_SMART_SELECTION_MULTI);
+    assertThat(textSelectionEvent.getEventIndex()).isEqualTo(1);
+    assertThat(textSelectionEvent.getEntityTypes())
+        .asList()
+        .containsExactly(TextClassifier.TYPE_ADDRESS);
+    assertThat(textSelectionEvent.getResultId()).isEqualTo(resultId);
+  }
+
+  @Test
+  public void convert_smartLinkify() {
+    session.onSelectionEvent(
+        SelectionEvent.createSelectionStartedEvent(SelectionEvent.INVOCATION_LINK, START));
+    String resultId =
+        ResultIdUtils.createId(702, Collections.singletonList(Locale.ENGLISH), /*hash=*/ 12345);
+    session.onSelectionEvent(
+        SelectionEvent.createSelectionModifiedEvent(
+            SMART_START,
+            SMART_END,
+            new TextSelection.Builder(SMART_START, SMART_END)
+                .setEntityType(TextClassifier.TYPE_ADDRESS, 1.0f)
+                .setId(resultId)
+                .build()));
+
+    SelectionEvent interceptedEvent = testTextClassifier.popLastSelectionEvent();
+    TextClassifierEvent.TextLinkifyEvent textLinkifyEvent =
+        (TextClassifierEvent.TextLinkifyEvent)
+            SelectionEventConverter.toTextClassifierEvent(interceptedEvent);
+
+    assertEventContext(textLinkifyEvent.getEventContext());
+    assertThat(textLinkifyEvent.getEventType())
+        .isEqualTo(TextClassifierEvent.TYPE_SMART_SELECTION_MULTI);
+    assertThat(textLinkifyEvent.getEventIndex()).isEqualTo(1);
+    assertThat(textLinkifyEvent.getEntityTypes())
+        .asList()
+        .containsExactly(TextClassifier.TYPE_ADDRESS);
+    assertThat(textLinkifyEvent.getResultId()).isEqualTo(resultId);
+  }
+
+  private static TextClassificationContext createEventContext() {
+    return new TextClassificationContext.Builder(PKG_NAME, TextClassifier.WIDGET_TYPE_EDITTEXT)
+        .build();
+  }
+
+  private static void assertEventContext(TextClassificationContext eventContext) {
+    assertThat(eventContext.getPackageName()).isEqualTo(PKG_NAME);
+    assertThat(eventContext.getWidgetType()).isEqualTo(WIDGET_TYPE);
+  }
+
+  private static class TestTextClassifier implements TextClassifier {
+    private final Deque<SelectionEvent> selectionEvents = new ArrayDeque<>();
+
+    @Override
+    public void onSelectionEvent(SelectionEvent event) {
+      selectionEvents.push(event);
+    }
+
+    SelectionEvent popLastSelectionEvent() {
+      return selectionEvents.pop();
+    }
+  }
+}
diff --git a/java/tests/instrumentation/src/com/android/textclassifier/subjects/EntitySubject.java b/java/tests/instrumentation/src/com/android/textclassifier/subjects/EntitySubject.java
new file mode 100644
index 0000000..6d01a64
--- /dev/null
+++ b/java/tests/instrumentation/src/com/android/textclassifier/subjects/EntitySubject.java
@@ -0,0 +1,51 @@
+/*
+ * 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.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * 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.
+ */
+
+package com.android.textclassifier.subjects;
+
+import static com.google.common.truth.Truth.assertAbout;
+
+import com.android.textclassifier.Entity;
+import com.google.common.truth.FailureMetadata;
+import com.google.common.truth.MathUtil;
+import com.google.common.truth.Subject;
+import javax.annotation.Nullable;
+
+/** Test helper for checking {@link com.android.textclassifier.Entity} results. */
+public final class EntitySubject extends Subject<EntitySubject, Entity> {
+
+  private static final float TOLERANCE = 0.0001f;
+
+  private final Entity entity;
+
+  public static EntitySubject assertThat(@Nullable Entity entity) {
+    return assertAbout(EntitySubject::new).that(entity);
+  }
+
+  private EntitySubject(FailureMetadata failureMetadata, @Nullable Entity entity) {
+    super(failureMetadata, entity);
+    this.entity = entity;
+  }
+
+  public void isMatchWithinTolerance(@Nullable Entity entity) {
+    if (!entity.getEntityType().equals(this.entity.getEntityType())) {
+      failWithActual("expected to have type", entity.getEntityType());
+    }
+    if (!MathUtil.equalWithinTolerance(entity.getScore(), this.entity.getScore(), TOLERANCE)) {
+      failWithActual("expected to have confidence score", entity.getScore());
+    }
+  }
+}
diff --git a/java/tests/instrumentation/src/com/android/textclassifier/ulp/BasicLanguageProficiencyAnalyzerTest.java b/java/tests/instrumentation/src/com/android/textclassifier/ulp/BasicLanguageProficiencyAnalyzerTest.java
new file mode 100644
index 0000000..91d5e3e
--- /dev/null
+++ b/java/tests/instrumentation/src/com/android/textclassifier/ulp/BasicLanguageProficiencyAnalyzerTest.java
@@ -0,0 +1,98 @@
+/*
+ * 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.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * 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.
+ */
+
+package com.android.textclassifier.ulp;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import androidx.room.Room;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+import com.android.textclassifier.TextClassificationConstants;
+import com.android.textclassifier.ulp.database.LanguageProfileDatabase;
+import com.android.textclassifier.ulp.database.LanguageSignalInfo;
+import java.util.Arrays;
+import java.util.Locale;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+/** Testing {@link BasicLanguageProficiencyAnalyzer} in an in-memory database. */
+public class BasicLanguageProficiencyAnalyzerTest {
+
+  private static final String PRIMARY_SYSTEM_LANGUAGE = Locale.CHINESE.toLanguageTag();
+  private static final String SECONDARY_SYSTEM_LANGUAGE = Locale.ENGLISH.toLanguageTag();
+  private static final String NON_SYSTEM_LANGUAGE = Locale.JAPANESE.toLanguageTag();
+
+  private LanguageProfileDatabase mDatabase;
+  private BasicLanguageProficiencyAnalyzer mProficiencyAnalyzer;
+  @Mock private SystemLanguagesProvider mSystemLanguagesProvider;
+
+  @Before
+  public void setup() {
+    MockitoAnnotations.initMocks(this);
+
+    Context context = ApplicationProvider.getApplicationContext();
+    TextClassificationConstants textClassificationConstants =
+        mock(TextClassificationConstants.class);
+    mDatabase = Room.inMemoryDatabaseBuilder(context, LanguageProfileDatabase.class).build();
+    mProficiencyAnalyzer =
+        new BasicLanguageProficiencyAnalyzer(
+            textClassificationConstants, mDatabase, mSystemLanguagesProvider);
+    when(mSystemLanguagesProvider.getSystemLanguageTags())
+        .thenReturn(Arrays.asList(PRIMARY_SYSTEM_LANGUAGE, SECONDARY_SYSTEM_LANGUAGE));
+    when(textClassificationConstants.getLanguageProficiencyBootstrappingCount()).thenReturn(100);
+  }
+
+  @After
+  public void close() {
+    mDatabase.close();
+  }
+
+  @Test
+  public void canUnderstand_emptyDatabase() {
+    assertThat(mProficiencyAnalyzer.canUnderstand(PRIMARY_SYSTEM_LANGUAGE)).isEqualTo(1f);
+    assertThat(mProficiencyAnalyzer.canUnderstand(SECONDARY_SYSTEM_LANGUAGE)).isEqualTo(0.5f);
+    assertThat(mProficiencyAnalyzer.canUnderstand(NON_SYSTEM_LANGUAGE)).isEqualTo(0f);
+  }
+
+  @Test
+  public void canUnderstand_validRequest() {
+    mDatabase
+        .languageInfoDao()
+        .insertLanguageInfo(
+            new LanguageSignalInfo(
+                PRIMARY_SYSTEM_LANGUAGE, LanguageSignalInfo.SUGGEST_CONVERSATION_ACTIONS, 100));
+    mDatabase
+        .languageInfoDao()
+        .insertLanguageInfo(
+            new LanguageSignalInfo(
+                SECONDARY_SYSTEM_LANGUAGE, LanguageSignalInfo.SUGGEST_CONVERSATION_ACTIONS, 30));
+
+    assertThat(mProficiencyAnalyzer.canUnderstand(PRIMARY_SYSTEM_LANGUAGE)).isEqualTo(1f);
+    assertThat(mProficiencyAnalyzer.canUnderstand(SECONDARY_SYSTEM_LANGUAGE)).isEqualTo(0.4f);
+    assertThat(mProficiencyAnalyzer.canUnderstand(NON_SYSTEM_LANGUAGE)).isEqualTo(0f);
+  }
+}
diff --git a/java/tests/instrumentation/src/com/android/textclassifier/ulp/KmeansLanguageProficiencyAnalyzerTest.java b/java/tests/instrumentation/src/com/android/textclassifier/ulp/KmeansLanguageProficiencyAnalyzerTest.java
new file mode 100644
index 0000000..d554cae
--- /dev/null
+++ b/java/tests/instrumentation/src/com/android/textclassifier/ulp/KmeansLanguageProficiencyAnalyzerTest.java
@@ -0,0 +1,137 @@
+/*
+ * 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.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * 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.
+ */
+
+package com.android.textclassifier.ulp;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import androidx.room.Room;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+import com.android.textclassifier.TextClassificationConstants;
+import com.android.textclassifier.ulp.database.LanguageProfileDatabase;
+import com.android.textclassifier.ulp.database.LanguageSignalInfo;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Locale;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+/** Testing {@link KmeansLanguageProficiencyAnalyzer} in an in-memory database. */
+public class KmeansLanguageProficiencyAnalyzerTest {
+
+  private static final String PRIMARY_SYSTEM_LANGUAGE = Locale.CHINESE.toLanguageTag();
+  private static final String SECONDARY_SYSTEM_LANGUAGE = Locale.ENGLISH.toLanguageTag();
+  private static final String NORMAL_LANGUAGE = Locale.JAPANESE.toLanguageTag();
+
+  private LanguageProfileDatabase mDatabase;
+  private KmeansLanguageProficiencyAnalyzer mProficiencyAnalyzer;
+  @Mock private SystemLanguagesProvider mSystemLanguagesProvider;
+
+  @Before
+  public void setup() {
+    MockitoAnnotations.initMocks(this);
+
+    Context context = ApplicationProvider.getApplicationContext();
+    TextClassificationConstants textClassificationConstants =
+        mock(TextClassificationConstants.class);
+    mDatabase = Room.inMemoryDatabaseBuilder(context, LanguageProfileDatabase.class).build();
+    mProficiencyAnalyzer =
+        new KmeansLanguageProficiencyAnalyzer(
+            textClassificationConstants, mDatabase, mSystemLanguagesProvider);
+    when(mSystemLanguagesProvider.getSystemLanguageTags())
+        .thenReturn(Arrays.asList(PRIMARY_SYSTEM_LANGUAGE, SECONDARY_SYSTEM_LANGUAGE));
+    when(textClassificationConstants.getLanguageProficiencyBootstrappingCount()).thenReturn(100);
+  }
+
+  @After
+  public void close() {
+    mDatabase.close();
+  }
+
+  @Test
+  public void canUnderstand_emptyDatabase() {
+    assertThat(mProficiencyAnalyzer.canUnderstand(PRIMARY_SYSTEM_LANGUAGE)).isEqualTo(1f);
+    assertThat(mProficiencyAnalyzer.canUnderstand(SECONDARY_SYSTEM_LANGUAGE)).isEqualTo(0.5f);
+    assertThat(mProficiencyAnalyzer.canUnderstand(NORMAL_LANGUAGE)).isEqualTo(0f);
+  }
+
+  @Test
+  public void canUnderstand_oneLanguage() {
+    when(mSystemLanguagesProvider.getSystemLanguageTags())
+        .thenReturn(Collections.singletonList(PRIMARY_SYSTEM_LANGUAGE));
+    mDatabase
+        .languageInfoDao()
+        .insertLanguageInfo(
+            new LanguageSignalInfo(
+                PRIMARY_SYSTEM_LANGUAGE, LanguageSignalInfo.SUGGEST_CONVERSATION_ACTIONS, 1));
+
+    assertThat(mProficiencyAnalyzer.canUnderstand(PRIMARY_SYSTEM_LANGUAGE)).isEqualTo(1f);
+    assertThat(mProficiencyAnalyzer.canUnderstand(SECONDARY_SYSTEM_LANGUAGE)).isEqualTo(0f);
+    assertThat(mProficiencyAnalyzer.canUnderstand(NORMAL_LANGUAGE)).isEqualTo(0f);
+  }
+
+  @Test
+  public void canUnderstand_twoLanguages() {
+    mDatabase
+        .languageInfoDao()
+        .insertLanguageInfo(
+            new LanguageSignalInfo(
+                PRIMARY_SYSTEM_LANGUAGE, LanguageSignalInfo.SUGGEST_CONVERSATION_ACTIONS, 100));
+    mDatabase
+        .languageInfoDao()
+        .insertLanguageInfo(
+            new LanguageSignalInfo(
+                SECONDARY_SYSTEM_LANGUAGE, LanguageSignalInfo.SUGGEST_CONVERSATION_ACTIONS, 50));
+
+    assertThat(mProficiencyAnalyzer.canUnderstand(PRIMARY_SYSTEM_LANGUAGE)).isEqualTo(1f);
+    assertThat(mProficiencyAnalyzer.canUnderstand(SECONDARY_SYSTEM_LANGUAGE)).isEqualTo(0.5f);
+    assertThat(mProficiencyAnalyzer.canUnderstand(NORMAL_LANGUAGE)).isEqualTo(0f);
+  }
+
+  @Test
+  public void canUnderstand_threeLanguages() {
+    mDatabase
+        .languageInfoDao()
+        .insertLanguageInfo(
+            new LanguageSignalInfo(
+                PRIMARY_SYSTEM_LANGUAGE, LanguageSignalInfo.SUGGEST_CONVERSATION_ACTIONS, 100));
+    mDatabase
+        .languageInfoDao()
+        .insertLanguageInfo(
+            new LanguageSignalInfo(
+                SECONDARY_SYSTEM_LANGUAGE, LanguageSignalInfo.SUGGEST_CONVERSATION_ACTIONS, 75));
+    mDatabase
+        .languageInfoDao()
+        .insertLanguageInfo(
+            new LanguageSignalInfo(
+                NORMAL_LANGUAGE, LanguageSignalInfo.SUGGEST_CONVERSATION_ACTIONS, 2));
+
+    assertThat(mProficiencyAnalyzer.canUnderstand(PRIMARY_SYSTEM_LANGUAGE)).isEqualTo(1f);
+    assertThat(mProficiencyAnalyzer.canUnderstand(SECONDARY_SYSTEM_LANGUAGE)).isEqualTo(1f);
+    assertThat(mProficiencyAnalyzer.canUnderstand(NORMAL_LANGUAGE)).isEqualTo(0f);
+  }
+}
diff --git a/java/tests/instrumentation/src/com/android/textclassifier/ulp/LanguageProficiencyEvaluatorTest.java b/java/tests/instrumentation/src/com/android/textclassifier/ulp/LanguageProficiencyEvaluatorTest.java
new file mode 100644
index 0000000..74ec27c
--- /dev/null
+++ b/java/tests/instrumentation/src/com/android/textclassifier/ulp/LanguageProficiencyEvaluatorTest.java
@@ -0,0 +1,160 @@
+/*
+ * 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.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * 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.
+ */
+
+package com.android.textclassifier.ulp;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Mockito.when;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+import com.google.common.collect.ImmutableSet;
+import java.util.Arrays;
+import java.util.Set;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+import org.mockito.stubbing.Answer;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class LanguageProficiencyEvaluatorTest {
+  private static final float EPSILON = 0.01f;
+  private LanguageProficiencyEvaluator mLanguageProficiencyEvaluator;
+
+  @Mock private SystemLanguagesProvider mSystemLanguagesProvider;
+
+  private static final String SYSTEM_LANGUAGE_EN = "en";
+  private static final String SYSTEM_LANGUAGE_ZH = "zh";
+  private static final String NORMAL_LANGUAGE_JP = "jp";
+  private static final String NORMAL_LANGUAGE_FR = "fr";
+  private static final String NORMAL_LANGUAGE_PL = "pl";
+  private static final Set<String> EVALUATION_LANGUAGES =
+      ImmutableSet.of(
+          SYSTEM_LANGUAGE_EN,
+          SYSTEM_LANGUAGE_ZH,
+          NORMAL_LANGUAGE_JP,
+          NORMAL_LANGUAGE_FR,
+          NORMAL_LANGUAGE_PL);
+
+  @Mock private LanguageProficiencyAnalyzer mLanguageProficiencyAnalyzer;
+
+  @Before
+  public void setUp() {
+    MockitoAnnotations.initMocks(this);
+    when(mSystemLanguagesProvider.getSystemLanguageTags())
+        .thenReturn(Arrays.asList(SYSTEM_LANGUAGE_EN, SYSTEM_LANGUAGE_ZH));
+    mLanguageProficiencyEvaluator = new LanguageProficiencyEvaluator(mSystemLanguagesProvider);
+  }
+
+  @Test
+  public void evaluate_allCorrect() {
+    when(mLanguageProficiencyAnalyzer.canUnderstand(Mockito.anyString()))
+        .thenAnswer(
+            (Answer<Float>)
+                invocation -> {
+                  String languageTag = invocation.getArgument(0);
+                  if (languageTag.equals(SYSTEM_LANGUAGE_EN)
+                      || languageTag.equals(SYSTEM_LANGUAGE_ZH)) {
+                    return 1f;
+                  }
+                  return 0f;
+                });
+
+    LanguageProficiencyEvaluator.EvaluationResult evaluationResult =
+        mLanguageProficiencyEvaluator.evaluate(mLanguageProficiencyAnalyzer, EVALUATION_LANGUAGES);
+
+    assertThat(evaluationResult.truePositive).isEqualTo(2);
+    assertThat(evaluationResult.trueNegative).isEqualTo(3);
+    assertThat(evaluationResult.falsePositive).isEqualTo(0);
+    assertThat(evaluationResult.falseNegative).isEqualTo(0);
+    assertThat(evaluationResult.computePrecisionOfPositiveClass()).isWithin(EPSILON).of(1f);
+    assertThat(evaluationResult.computePrecisionOfNegativeClass()).isWithin(EPSILON).of(1f);
+    assertThat(evaluationResult.computeRecallOfPositiveClass()).isWithin(EPSILON).of(1f);
+    assertThat(evaluationResult.computeRecallOfNegativeClass()).isWithin(EPSILON).of(1f);
+    assertThat(evaluationResult.computeF1ScoreOfPositiveClass()).isWithin(EPSILON).of(1f);
+    assertThat(evaluationResult.computeF1ScoreOfNegativeClass()).isWithin(EPSILON).of(1f);
+  }
+
+  @Test
+  public void evaluate_allWrong() {
+    when(mLanguageProficiencyAnalyzer.canUnderstand(Mockito.anyString()))
+        .thenAnswer(
+            (Answer<Float>)
+                invocation -> {
+                  String languageTag = invocation.getArgument(0);
+                  if (languageTag.equals(SYSTEM_LANGUAGE_EN)
+                      || languageTag.equals(SYSTEM_LANGUAGE_ZH)) {
+                    return 0f;
+                  }
+                  return 1f;
+                });
+
+    LanguageProficiencyEvaluator.EvaluationResult evaluationResult =
+        mLanguageProficiencyEvaluator.evaluate(mLanguageProficiencyAnalyzer, EVALUATION_LANGUAGES);
+
+    assertThat(evaluationResult.truePositive).isEqualTo(0);
+    assertThat(evaluationResult.trueNegative).isEqualTo(0);
+    assertThat(evaluationResult.falsePositive).isEqualTo(3);
+    assertThat(evaluationResult.falseNegative).isEqualTo(2);
+    assertThat(evaluationResult.computePrecisionOfPositiveClass()).isWithin(EPSILON).of(0f);
+    assertThat(evaluationResult.computePrecisionOfNegativeClass()).isWithin(EPSILON).of(0f);
+    assertThat(evaluationResult.computeRecallOfPositiveClass()).isWithin(EPSILON).of(0f);
+    assertThat(evaluationResult.computeRecallOfNegativeClass()).isWithin(EPSILON).of(0f);
+    assertThat(evaluationResult.computeF1ScoreOfPositiveClass()).isWithin(EPSILON).of(0f);
+    assertThat(evaluationResult.computeF1ScoreOfNegativeClass()).isWithin(EPSILON).of(0f);
+  }
+
+  @Test
+  public void evaluate_mixed() {
+    when(mLanguageProficiencyAnalyzer.canUnderstand(Mockito.anyString()))
+        .thenAnswer(
+            (Answer<Float>)
+                invocation -> {
+                  String languageTag = invocation.getArgument(0);
+                  switch (languageTag) {
+                    case SYSTEM_LANGUAGE_EN:
+                      return 1f;
+                    case SYSTEM_LANGUAGE_ZH:
+                      return 0f;
+                    case NORMAL_LANGUAGE_FR:
+                      return 0f;
+                    case NORMAL_LANGUAGE_JP:
+                      return 0f;
+                    case NORMAL_LANGUAGE_PL:
+                      return 1f;
+                  }
+                  throw new IllegalArgumentException("unexpected language: " + languageTag);
+                });
+
+    LanguageProficiencyEvaluator.EvaluationResult evaluationResult =
+        mLanguageProficiencyEvaluator.evaluate(mLanguageProficiencyAnalyzer, EVALUATION_LANGUAGES);
+
+    assertThat(evaluationResult.truePositive).isEqualTo(1);
+    assertThat(evaluationResult.trueNegative).isEqualTo(2);
+    assertThat(evaluationResult.falsePositive).isEqualTo(1);
+    assertThat(evaluationResult.falseNegative).isEqualTo(1);
+    assertThat(evaluationResult.computePrecisionOfPositiveClass()).isWithin(EPSILON).of(0.5f);
+    assertThat(evaluationResult.computePrecisionOfNegativeClass()).isWithin(EPSILON).of(0.66f);
+    assertThat(evaluationResult.computeRecallOfPositiveClass()).isWithin(EPSILON).of(0.5f);
+    assertThat(evaluationResult.computeRecallOfNegativeClass()).isWithin(EPSILON).of(0.66f);
+    assertThat(evaluationResult.computeF1ScoreOfPositiveClass()).isWithin(EPSILON).of(0.5f);
+    assertThat(evaluationResult.computeF1ScoreOfNegativeClass()).isWithin(EPSILON).of(0.66f);
+  }
+}
diff --git a/java/tests/instrumentation/src/com/android/textclassifier/ulp/LanguageProfileAnalyzerTest.java b/java/tests/instrumentation/src/com/android/textclassifier/ulp/LanguageProfileAnalyzerTest.java
new file mode 100644
index 0000000..46153db
--- /dev/null
+++ b/java/tests/instrumentation/src/com/android/textclassifier/ulp/LanguageProfileAnalyzerTest.java
@@ -0,0 +1,141 @@
+/*
+ * 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.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * 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.
+ */
+
+package com.android.textclassifier.ulp;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import androidx.room.Room;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+import com.android.textclassifier.Entity;
+import com.android.textclassifier.TextClassificationConstants;
+import com.android.textclassifier.subjects.EntitySubject;
+import com.android.textclassifier.ulp.database.LanguageProfileDatabase;
+import com.android.textclassifier.ulp.database.LanguageSignalInfo;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+/** Testing {@link LanguageProfileAnalyzer} in an inMemoryDatabase. */
+public class LanguageProfileAnalyzerTest {
+
+  private static final String SYSTEM_LANGUAGE_CODE = "en";
+  private static final String LOCATION_LANGUAGE_CODE = "jp";
+  private static final String NORMAL_LANGUAGE_CODE = "pl";
+
+  private LanguageProfileDatabase mDatabase;
+  private LanguageProfileAnalyzer mLanguageProfileAnalyzer;
+  @Mock private LocationSignalProvider mLocationSignalProvider;
+  @Mock private SystemLanguagesProvider mSystemLanguagesProvider;
+  @Mock private LanguageProficiencyAnalyzer mLanguageProficiencyAnalyzer;
+
+  @Before
+  public void setup() {
+    MockitoAnnotations.initMocks(this);
+
+    Context mContext = ApplicationProvider.getApplicationContext();
+    mDatabase = Room.inMemoryDatabaseBuilder(mContext, LanguageProfileDatabase.class).build();
+    when(mLocationSignalProvider.detectLanguageTag()).thenReturn(LOCATION_LANGUAGE_CODE);
+    when(mSystemLanguagesProvider.getSystemLanguageTags())
+        .thenReturn(Collections.singletonList(SYSTEM_LANGUAGE_CODE));
+    when(mLanguageProficiencyAnalyzer.canUnderstand(anyString())).thenReturn(1.0f);
+    TextClassificationConstants customTextClassificationConstants =
+        mock(TextClassificationConstants.class);
+    when(customTextClassificationConstants.getFrequentLanguagesBootstrappingCount())
+        .thenReturn(100);
+    mLanguageProfileAnalyzer =
+        new LanguageProfileAnalyzer(
+            mContext,
+            customTextClassificationConstants,
+            mDatabase,
+            mLanguageProficiencyAnalyzer,
+            mLocationSignalProvider,
+            mSystemLanguagesProvider);
+  }
+
+  @After
+  public void close() {
+    mDatabase.close();
+  }
+
+  @Test
+  public void getFrequentLanguages_emptyDatabase() {
+    List<Entity> frequentLanguages =
+        mLanguageProfileAnalyzer.getFrequentLanguages(LanguageSignalInfo.CLASSIFY_TEXT);
+
+    assertThat(frequentLanguages).hasSize(2);
+    EntitySubject.assertThat(frequentLanguages.get(0))
+        .isMatchWithinTolerance(new Entity(SYSTEM_LANGUAGE_CODE, 1.0f));
+    EntitySubject.assertThat(frequentLanguages.get(1))
+        .isMatchWithinTolerance(new Entity(LOCATION_LANGUAGE_CODE, 1.0f));
+  }
+
+  @Test
+  public void getFrequentLanguages_mixedSignal() {
+    insertSignal(NORMAL_LANGUAGE_CODE, LanguageSignalInfo.CLASSIFY_TEXT, 50);
+    insertSignal(SYSTEM_LANGUAGE_CODE, LanguageSignalInfo.CLASSIFY_TEXT, 100);
+    // Unrelated signals.
+    insertSignal(NORMAL_LANGUAGE_CODE, LanguageSignalInfo.SUGGEST_CONVERSATION_ACTIONS, 100);
+    insertSignal(SYSTEM_LANGUAGE_CODE, LanguageSignalInfo.SUGGEST_CONVERSATION_ACTIONS, 100);
+    insertSignal(LOCATION_LANGUAGE_CODE, LanguageSignalInfo.SUGGEST_CONVERSATION_ACTIONS, 100);
+
+    List<Entity> frequentLanguages =
+        mLanguageProfileAnalyzer.getFrequentLanguages(LanguageSignalInfo.CLASSIFY_TEXT);
+
+    assertThat(frequentLanguages).hasSize(3);
+    EntitySubject.assertThat(frequentLanguages.get(0))
+        .isMatchWithinTolerance(new Entity(SYSTEM_LANGUAGE_CODE, 1.0f));
+    EntitySubject.assertThat(frequentLanguages.get(1))
+        .isMatchWithinTolerance(new Entity(LOCATION_LANGUAGE_CODE, 0.5f));
+    EntitySubject.assertThat(frequentLanguages.get(2))
+        .isMatchWithinTolerance(new Entity(NORMAL_LANGUAGE_CODE, 0.25f));
+  }
+
+  @Test
+  public void getFrequentLanguages_bothSystemLanguageAndLocationLanguage() {
+    when(mLocationSignalProvider.detectLanguageTag()).thenReturn("en");
+    when(mSystemLanguagesProvider.getSystemLanguageTags()).thenReturn(Arrays.asList("en", "jp"));
+
+    List<Entity> frequentLanguages =
+        mLanguageProfileAnalyzer.getFrequentLanguages(LanguageSignalInfo.CLASSIFY_TEXT);
+
+    assertThat(frequentLanguages).hasSize(2);
+    EntitySubject.assertThat(frequentLanguages.get(0))
+        .isMatchWithinTolerance(new Entity("en", 1.0f));
+    EntitySubject.assertThat(frequentLanguages.get(1))
+        .isMatchWithinTolerance(new Entity("jp", 0.5f));
+  }
+
+  private void insertSignal(String languageTag, @LanguageSignalInfo.Source int source, int count) {
+    mDatabase
+        .languageInfoDao()
+        .insertLanguageInfo(new LanguageSignalInfo(languageTag, source, count));
+  }
+}
diff --git a/java/tests/instrumentation/src/com/android/textclassifier/ulp/LanguageProfileUpdaterTest.java b/java/tests/instrumentation/src/com/android/textclassifier/ulp/LanguageProfileUpdaterTest.java
new file mode 100644
index 0000000..02958b6
--- /dev/null
+++ b/java/tests/instrumentation/src/com/android/textclassifier/ulp/LanguageProfileUpdaterTest.java
@@ -0,0 +1,213 @@
+/*
+ * 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.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * 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.
+ */
+
+package com.android.textclassifier.ulp;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.app.Person;
+import android.content.Context;
+import android.os.Bundle;
+import android.view.textclassifier.ConversationActions;
+import android.view.textclassifier.TextClassification;
+import androidx.room.Room;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+import com.android.textclassifier.ulp.database.LanguageProfileDatabase;
+import com.android.textclassifier.ulp.database.LanguageSignalInfo;
+import com.google.common.collect.ImmutableList;
+import com.google.common.util.concurrent.ListeningExecutorService;
+import com.google.common.util.concurrent.MoreExecutors;
+import java.time.ZoneId;
+import java.time.ZonedDateTime;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Locale;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Executors;
+import java.util.function.Function;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+/** Testing {@link LanguageProfileUpdater} in an in-memory database. */
+public class LanguageProfileUpdaterTest {
+
+  private static final String NOTIFICATION_KEY = "test_notification";
+  private static final String LOCALE_TAG_US = Locale.US.toLanguageTag();
+  private static final String LOCALE_TAG_CHINA = Locale.CHINA.toLanguageTag();
+  private static final String TEXT_ONE = "hello world";
+  private static final String TEXT_TWO = "你好!";
+  private static final Function<CharSequence, List<String>> LANGUAGE_DETECTOR_US =
+      charSequence -> ImmutableList.of(LOCALE_TAG_US);
+  private static final Function<CharSequence, List<String>> LANGUAGE_DETECTOR_CHINA =
+      charSequence -> ImmutableList.of(LOCALE_TAG_CHINA);
+  private static final Person PERSON = new Person.Builder().build();
+  private static final ZonedDateTime TIME_ONE =
+      ZonedDateTime.of(2019, 7, 21, 12, 12, 12, 12, ZoneId.systemDefault());
+  private static final ZonedDateTime TIME_TWO =
+      ZonedDateTime.of(2019, 7, 21, 12, 20, 20, 12, ZoneId.systemDefault());
+  private static final ConversationActions.Message MSG_ONE =
+      new ConversationActions.Message.Builder(PERSON)
+          .setReferenceTime(TIME_ONE)
+          .setText(TEXT_ONE)
+          .setExtras(new Bundle())
+          .build();
+  private static final ConversationActions.Message MSG_TWO =
+      new ConversationActions.Message.Builder(PERSON)
+          .setReferenceTime(TIME_TWO)
+          .setText("where are you?")
+          .setExtras(new Bundle())
+          .build();
+  private static final ConversationActions.Message MSG_THREE =
+      new ConversationActions.Message.Builder(PERSON)
+          .setReferenceTime(TIME_TWO)
+          .setText(TEXT_TWO)
+          .setExtras(new Bundle())
+          .build();
+  private static final ConversationActions.Request CONVERSATION_ACTION_REQUEST_ONE =
+      new ConversationActions.Request.Builder(Arrays.asList(MSG_ONE)).build();
+  private static final ConversationActions.Request CONVERSATION_ACTION_REQUEST_TWO =
+      new ConversationActions.Request.Builder(Arrays.asList(MSG_TWO)).build();
+  private static final TextClassification.Request TEXT_CLASSIFICATION_REQUEST_ONE =
+      new TextClassification.Request.Builder(TEXT_ONE, 0, 2).build();
+  private static final LanguageSignalInfo US_INFO_ONE_FOR_CONVERSATION_ACTION_ONE =
+      new LanguageSignalInfo(LOCALE_TAG_US, LanguageSignalInfo.SUGGEST_CONVERSATION_ACTIONS, 1);
+  private static final LanguageSignalInfo US_INFO_ONE_FOR_CONVERSATION_ACTION_TWO =
+      new LanguageSignalInfo(LOCALE_TAG_US, LanguageSignalInfo.SUGGEST_CONVERSATION_ACTIONS, 2);
+  private static final LanguageSignalInfo US_INFO_ONE_FOR_CLASSIFY_TEXT =
+      new LanguageSignalInfo(LOCALE_TAG_US, LanguageSignalInfo.CLASSIFY_TEXT, 1);
+
+  private LanguageProfileUpdater mLanguageProfileUpdater;
+  private LanguageProfileDatabase mDatabase;
+
+  @Before
+  public void setup() {
+    Context mContext = ApplicationProvider.getApplicationContext();
+    ListeningExecutorService mExecutorService =
+        MoreExecutors.listeningDecorator(Executors.newSingleThreadExecutor());
+    mDatabase = Room.inMemoryDatabaseBuilder(mContext, LanguageProfileDatabase.class).build();
+    mLanguageProfileUpdater = new LanguageProfileUpdater(mExecutorService, mDatabase);
+  }
+
+  @After
+  public void close() {
+    mDatabase.close();
+  }
+
+  @Test
+  public void updateFromConversationActionsAsync_oneMessage()
+      throws ExecutionException, InterruptedException {
+    mLanguageProfileUpdater
+        .updateFromConversationActionsAsync(CONVERSATION_ACTION_REQUEST_ONE, LANGUAGE_DETECTOR_US)
+        .get();
+    List<LanguageSignalInfo> infos = mDatabase.languageInfoDao().getAll();
+
+    assertThat(infos).hasSize(1);
+    LanguageSignalInfo info = infos.get(0);
+    assertThat(info).isEqualTo(US_INFO_ONE_FOR_CONVERSATION_ACTION_ONE);
+  }
+
+  /** Notification keys for these two messages are DEFAULT_NOTIFICATION_KEY */
+  @Test
+  public void updateFromConversationActionsAsync_twoMessagesInSameNotificationWithSameLanguage()
+      throws ExecutionException, InterruptedException {
+    mLanguageProfileUpdater
+        .updateFromConversationActionsAsync(CONVERSATION_ACTION_REQUEST_ONE, LANGUAGE_DETECTOR_US)
+        .get();
+    mLanguageProfileUpdater
+        .updateFromConversationActionsAsync(CONVERSATION_ACTION_REQUEST_TWO, LANGUAGE_DETECTOR_US)
+        .get();
+    List<LanguageSignalInfo> infos = mDatabase.languageInfoDao().getAll();
+
+    assertThat(infos).hasSize(1);
+    LanguageSignalInfo info = infos.get(0);
+    assertThat(info).isEqualTo(US_INFO_ONE_FOR_CONVERSATION_ACTION_TWO);
+  }
+
+  @Test
+  public void updateFromConversationActionsAsync_twoMessagesInDifferentNotifications()
+      throws ExecutionException, InterruptedException {
+    mLanguageProfileUpdater
+        .updateFromConversationActionsAsync(CONVERSATION_ACTION_REQUEST_ONE, LANGUAGE_DETECTOR_US)
+        .get();
+    Bundle extra = new Bundle();
+    extra.putString(LanguageProfileUpdater.NOTIFICATION_KEY, NOTIFICATION_KEY);
+    ConversationActions.Request newRequest =
+        new ConversationActions.Request.Builder(Arrays.asList(MSG_TWO)).setExtras(extra).build();
+    mLanguageProfileUpdater
+        .updateFromConversationActionsAsync(newRequest, LANGUAGE_DETECTOR_US)
+        .get();
+    List<LanguageSignalInfo> infos = mDatabase.languageInfoDao().getAll();
+
+    assertThat(infos).hasSize(1);
+    LanguageSignalInfo info = infos.get(0);
+    assertThat(info).isEqualTo(US_INFO_ONE_FOR_CONVERSATION_ACTION_TWO);
+  }
+
+  @Test
+  public void updateFromConversationActionsAsync_twoMessagesInDifferentLanguage()
+      throws ExecutionException, InterruptedException {
+    mLanguageProfileUpdater
+        .updateFromConversationActionsAsync(CONVERSATION_ACTION_REQUEST_ONE, LANGUAGE_DETECTOR_US)
+        .get();
+    ConversationActions.Request newRequest =
+        new ConversationActions.Request.Builder(Arrays.asList(MSG_THREE)).build();
+    mLanguageProfileUpdater
+        .updateFromConversationActionsAsync(newRequest, LANGUAGE_DETECTOR_CHINA)
+        .get();
+    List<LanguageSignalInfo> infos = mDatabase.languageInfoDao().getAll();
+
+    assertThat(infos).hasSize(2);
+    LanguageSignalInfo infoOne = infos.get(0);
+    LanguageSignalInfo infoTwo = infos.get(1);
+    assertThat(infoOne).isEqualTo(US_INFO_ONE_FOR_CONVERSATION_ACTION_ONE);
+    assertThat(infoTwo)
+        .isEqualTo(
+            new LanguageSignalInfo(
+                LOCALE_TAG_CHINA, LanguageSignalInfo.SUGGEST_CONVERSATION_ACTIONS, 1));
+  }
+
+  @Test
+  public void updateFromClassifyTextAsync_classifyText()
+      throws ExecutionException, InterruptedException {
+    mLanguageProfileUpdater.updateFromClassifyTextAsync(ImmutableList.of(LOCALE_TAG_US)).get();
+    List<LanguageSignalInfo> infos = mDatabase.languageInfoDao().getAll();
+
+    assertThat(infos).hasSize(1);
+    LanguageSignalInfo info = infos.get(0);
+    assertThat(info).isEqualTo(US_INFO_ONE_FOR_CLASSIFY_TEXT);
+  }
+
+  @Test
+  public void updateFromClassifyTextAsync_classifyTextTwice()
+      throws ExecutionException, InterruptedException {
+    mLanguageProfileUpdater.updateFromClassifyTextAsync(ImmutableList.of(LOCALE_TAG_US)).get();
+    mLanguageProfileUpdater.updateFromClassifyTextAsync(ImmutableList.of(LOCALE_TAG_CHINA)).get();
+
+    List<LanguageSignalInfo> infos = mDatabase.languageInfoDao().getAll();
+    assertThat(infos).hasSize(2);
+    LanguageSignalInfo infoOne = infos.get(0);
+    LanguageSignalInfo infoTwo = infos.get(1);
+    assertThat(infoOne).isEqualTo(US_INFO_ONE_FOR_CLASSIFY_TEXT);
+    assertThat(infoTwo)
+        .isEqualTo(new LanguageSignalInfo(LOCALE_TAG_CHINA, LanguageSignalInfo.CLASSIFY_TEXT, 1));
+  }
+}
diff --git a/java/tests/instrumentation/src/com/android/textclassifier/ulp/LocationSignalProviderTest.java b/java/tests/instrumentation/src/com/android/textclassifier/ulp/LocationSignalProviderTest.java
new file mode 100644
index 0000000..6ceacab
--- /dev/null
+++ b/java/tests/instrumentation/src/com/android/textclassifier/ulp/LocationSignalProviderTest.java
@@ -0,0 +1,74 @@
+/*
+ * 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.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * 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.
+ */
+
+package com.android.textclassifier.ulp;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Mockito.when;
+
+import android.location.Address;
+import android.location.Geocoder;
+import android.location.Location;
+import android.location.LocationManager;
+import android.telephony.TelephonyManager;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+import java.io.IOException;
+import java.util.Collections;
+import java.util.Locale;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class LocationSignalProviderTest {
+  @Mock private LocationManager mLocationManager;
+  @Mock private TelephonyManager mTelephonyManager;
+  @Mock private LocationSignalProvider mLocationSignalProvider;
+  @Mock private Geocoder mGeocoder;
+
+  @Before
+  public void setup() {
+    MockitoAnnotations.initMocks(this);
+    mLocationSignalProvider =
+        new LocationSignalProvider(mLocationManager, mTelephonyManager, mGeocoder);
+  }
+
+  @Test
+  public void detectLanguageTag_useTelephony() {
+    when(mTelephonyManager.getNetworkCountryIso()).thenReturn(Locale.UK.getCountry());
+
+    assertThat(mLocationSignalProvider.detectLanguageTag()).isEqualTo("en");
+  }
+
+  @Test
+  public void detectLanguageTag_useLocation() throws IOException {
+    when(mTelephonyManager.getNetworkCountryIso()).thenReturn(null);
+    Location location = new Location(LocationManager.PASSIVE_PROVIDER);
+    when(mLocationManager.getLastKnownLocation(LocationManager.PASSIVE_PROVIDER))
+        .thenReturn(location);
+    Address address = new Address(Locale.FRANCE);
+    address.setCountryCode(Locale.FRANCE.getCountry());
+    when(mGeocoder.getFromLocation(Mockito.anyDouble(), Mockito.anyDouble(), Mockito.anyInt()))
+        .thenReturn(Collections.singletonList(address));
+
+    assertThat(mLocationSignalProvider.detectLanguageTag()).isEqualTo("fr");
+  }
+}
diff --git a/java/tests/instrumentation/src/com/android/textclassifier/ulp/ReinforcementLanguageProficiencyAnalyzerTest.java b/java/tests/instrumentation/src/com/android/textclassifier/ulp/ReinforcementLanguageProficiencyAnalyzerTest.java
new file mode 100644
index 0000000..dda6600
--- /dev/null
+++ b/java/tests/instrumentation/src/com/android/textclassifier/ulp/ReinforcementLanguageProficiencyAnalyzerTest.java
@@ -0,0 +1,115 @@
+/*
+ * 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.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * 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.
+ */
+
+package com.android.textclassifier.ulp;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.view.textclassifier.TextClassifierEvent;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+import java.util.Arrays;
+import java.util.Locale;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+/** Testing {@link ReinforcementLanguageProficiencyAnalyzer} using Mockito. */
+public class ReinforcementLanguageProficiencyAnalyzerTest {
+
+  private static final String PRIMARY_SYSTEM_LANGUAGE = Locale.CHINESE.toLanguageTag();
+  private static final String SECONDARY_SYSTEM_LANGUAGE = Locale.ENGLISH.toLanguageTag();
+  private static final String NON_SYSTEM_LANGUAGE = Locale.JAPANESE.toLanguageTag();
+  private ReinforcementLanguageProficiencyAnalyzer mProficiencyAnalyzer;
+  @Mock private SystemLanguagesProvider mSystemLanguagesProvider;
+  private SharedPreferences mSharedPreferences;
+
+  @Before
+  public void setup() {
+    MockitoAnnotations.initMocks(this);
+    Context context = ApplicationProvider.getApplicationContext();
+    mSharedPreferences = context.getSharedPreferences("test-preferences", Context.MODE_PRIVATE);
+    when(mSystemLanguagesProvider.getSystemLanguageTags())
+        .thenReturn(Arrays.asList(PRIMARY_SYSTEM_LANGUAGE, SECONDARY_SYSTEM_LANGUAGE));
+    mProficiencyAnalyzer =
+        new ReinforcementLanguageProficiencyAnalyzer(mSystemLanguagesProvider, mSharedPreferences);
+  }
+
+  @After
+  public void teardown() {
+    mSharedPreferences.edit().clear().apply();
+  }
+
+  @Test
+  public void canUnderstand_defaultValue() {
+    assertThat(mProficiencyAnalyzer.canUnderstand(PRIMARY_SYSTEM_LANGUAGE)).isEqualTo(1.0f);
+    assertThat(mProficiencyAnalyzer.canUnderstand(SECONDARY_SYSTEM_LANGUAGE)).isEqualTo(1.0f);
+    assertThat(mProficiencyAnalyzer.canUnderstand(NON_SYSTEM_LANGUAGE)).isEqualTo(0f);
+  }
+
+  @Test
+  public void canUnderstand_enoughFeedback() {
+    sendEvent(TextClassifierEvent.TYPE_ACTIONS_SHOWN, PRIMARY_SYSTEM_LANGUAGE, /* times= */ 50);
+    sendEvent(TextClassifierEvent.TYPE_SMART_ACTION, PRIMARY_SYSTEM_LANGUAGE, /* times= */ 40);
+
+    assertThat(mProficiencyAnalyzer.canUnderstand(PRIMARY_SYSTEM_LANGUAGE)).isEqualTo(0.8f);
+  }
+
+  @Test
+  public void shouldShowTranslation_defaultValue() {
+    assertThat(mProficiencyAnalyzer.shouldShowTranslation(PRIMARY_SYSTEM_LANGUAGE)).isEqualTo(true);
+    assertThat(mProficiencyAnalyzer.shouldShowTranslation(SECONDARY_SYSTEM_LANGUAGE))
+        .isEqualTo(true);
+    assertThat(mProficiencyAnalyzer.shouldShowTranslation(NON_SYSTEM_LANGUAGE)).isEqualTo(true);
+  }
+
+  @Test
+  public void shouldShowTranslation_enoughFeedback_true() {
+    sendEvent(TextClassifierEvent.TYPE_ACTIONS_SHOWN, PRIMARY_SYSTEM_LANGUAGE, /* times= */ 1000);
+    sendEvent(TextClassifierEvent.TYPE_SMART_ACTION, PRIMARY_SYSTEM_LANGUAGE, /* times= */ 200);
+
+    assertThat(mProficiencyAnalyzer.shouldShowTranslation(PRIMARY_SYSTEM_LANGUAGE)).isEqualTo(true);
+  }
+
+  @Test
+  public void shouldShowTranslation_enoughFeedback_false() {
+    sendEvent(TextClassifierEvent.TYPE_ACTIONS_SHOWN, PRIMARY_SYSTEM_LANGUAGE, /* times= */ 1000);
+    sendEvent(TextClassifierEvent.TYPE_SMART_ACTION, PRIMARY_SYSTEM_LANGUAGE, /* times= */ 1000);
+
+    assertThat(mProficiencyAnalyzer.shouldShowTranslation(PRIMARY_SYSTEM_LANGUAGE))
+        .isEqualTo(false);
+  }
+
+  private void sendEvent(int type, String languageTag, int times) {
+    TextClassifierEvent.LanguageDetectionEvent event =
+        new TextClassifierEvent.LanguageDetectionEvent.Builder(type)
+            .setEntityTypes(languageTag)
+            .setActionIndices(0)
+            .build();
+    for (int i = 0; i < times; i++) {
+      mProficiencyAnalyzer.onTextClassifierEvent(event);
+    }
+  }
+}
diff --git a/java/tests/instrumentation/src/com/android/textclassifier/ulp/SystemLanguagesProviderTest.java b/java/tests/instrumentation/src/com/android/textclassifier/ulp/SystemLanguagesProviderTest.java
new file mode 100644
index 0000000..45e8608
--- /dev/null
+++ b/java/tests/instrumentation/src/com/android/textclassifier/ulp/SystemLanguagesProviderTest.java
@@ -0,0 +1,60 @@
+/*
+ * 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.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * 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.
+ */
+
+package com.android.textclassifier.ulp;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.res.Resources;
+import android.os.LocaleList;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+import java.util.List;
+import java.util.Locale;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class SystemLanguagesProviderTest {
+  private SystemLanguagesProvider mSystemLanguagesProvider;
+
+  @Before
+  public void setup() {
+    mSystemLanguagesProvider = new SystemLanguagesProvider();
+  }
+
+  @Test
+  public void getSystemLanguageTags_singleLanguages() {
+    Resources.getSystem().getConfiguration().setLocales(new LocaleList(Locale.FRANCE));
+
+    List<String> systemLanguageTags = mSystemLanguagesProvider.getSystemLanguageTags();
+
+    assertThat(systemLanguageTags).containsExactly("fr");
+  }
+
+  @Test
+  public void getSystemLanguageTags_multipleLanguages() {
+    Resources.getSystem()
+        .getConfiguration()
+        .setLocales(new LocaleList(Locale.FRANCE, Locale.ENGLISH));
+
+    List<String> systemLanguageTags = mSystemLanguagesProvider.getSystemLanguageTags();
+
+    assertThat(systemLanguageTags).containsExactly("fr", "en");
+  }
+}
diff --git a/java/tests/unittests/AndroidManifest.xml b/java/tests/unittests/AndroidManifest.xml
deleted file mode 100644
index 7864815..0000000
--- a/java/tests/unittests/AndroidManifest.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2019 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.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ 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
-  -->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="com.android.textclassifier.tests">
-    <uses-permission android:name="android.permission.WRITE_DEVICE_CONFIG" />
-    <application android:debuggable="true">
-        <uses-library android:name="android.test.runner"/>
-    </application>
-
-    <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
-                     android:targetPackage="com.android.textclassifier.tests"
-                     android:label="Tests for TextClassifierService"/>
-
-</manifest>
\ No newline at end of file
diff --git a/java/tests/unittests/AndroidTest.xml b/java/tests/unittests/AndroidTest.xml
deleted file mode 100644
index d55e8c5..0000000
--- a/java/tests/unittests/AndroidTest.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2019 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.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ 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
-  -->
-<configuration description="Runs Tests for TextClassifierServiceTest.">
-    <target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup">
-        <option name="test-file-name" value="TextClassifierServiceTest.apk"/>
-    </target_preparer>
-    <!--<option name="test-suite-tag" value="apct"/>-->
-    <option name="test-tag" value="TextClassifierServiceTest"/>
-    <test class="com.android.tradefed.testtype.AndroidJUnitTest">
-        <option name="package" value="com.android.textclassifier.tests"/>
-        <option name="runner" value="androidx.test.runner.AndroidJUnitRunner"/>
-    </test>
-</configuration>
\ No newline at end of file
diff --git a/java/tests/unittests/src/com/android/textclassifier/ActionsModelParamsSupplierTest.java b/java/tests/unittests/src/com/android/textclassifier/ActionsModelParamsSupplierTest.java
deleted file mode 100644
index a8ae8aa..0000000
--- a/java/tests/unittests/src/com/android/textclassifier/ActionsModelParamsSupplierTest.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright (C) 2019 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.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * 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
- */
-package com.android.textclassifier;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.io.File;
-import java.util.Collections;
-import java.util.Locale;
-
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public class ActionsModelParamsSupplierTest {
-
-    @Test
-    public void getSerializedPreconditions_validActionsModelParams() {
-        ModelFileManager.ModelFile modelFile =
-                new ModelFileManager.ModelFile(
-                        new File("/model/file"),
-                        200 /* version */,
-                        Collections.singletonList(Locale.forLanguageTag("en")),
-                        "en",
-                        false);
-        byte[] serializedPreconditions = new byte[] {0x12, 0x24, 0x36};
-        ActionsModelParamsSupplier.ActionsModelParams params =
-                new ActionsModelParamsSupplier.ActionsModelParams(
-                        200 /* version */, "en", serializedPreconditions);
-
-        byte[] actual = params.getSerializedPreconditions(modelFile);
-
-        assertThat(actual).isEqualTo(serializedPreconditions);
-    }
-
-    @Test
-    public void getSerializedPreconditions_invalidVersion() {
-        ModelFileManager.ModelFile modelFile =
-                new ModelFileManager.ModelFile(
-                        new File("/model/file"),
-                        201 /* version */,
-                        Collections.singletonList(Locale.forLanguageTag("en")),
-                        "en",
-                        false);
-        byte[] serializedPreconditions = new byte[] {0x12, 0x24, 0x36};
-        ActionsModelParamsSupplier.ActionsModelParams params =
-                new ActionsModelParamsSupplier.ActionsModelParams(
-                        200 /* version */, "en", serializedPreconditions);
-
-        byte[] actual = params.getSerializedPreconditions(modelFile);
-
-        assertThat(actual).isNull();
-    }
-
-    @Test
-    public void getSerializedPreconditions_invalidLocales() {
-        final String LANGUAGE_TAG = "zh";
-        ModelFileManager.ModelFile modelFile =
-                new ModelFileManager.ModelFile(
-                        new File("/model/file"),
-                        200 /* version */,
-                        Collections.singletonList(Locale.forLanguageTag(LANGUAGE_TAG)),
-                        LANGUAGE_TAG,
-                        false);
-        byte[] serializedPreconditions = new byte[] {0x12, 0x24, 0x36};
-        ActionsModelParamsSupplier.ActionsModelParams params =
-                new ActionsModelParamsSupplier.ActionsModelParams(
-                        200 /* version */, "en", serializedPreconditions);
-
-        byte[] actual = params.getSerializedPreconditions(modelFile);
-
-        assertThat(actual).isNull();
-    }
-}
diff --git a/java/tests/unittests/src/com/android/textclassifier/ActionsSuggestionsHelperTest.java b/java/tests/unittests/src/com/android/textclassifier/ActionsSuggestionsHelperTest.java
deleted file mode 100644
index c25fce8..0000000
--- a/java/tests/unittests/src/com/android/textclassifier/ActionsSuggestionsHelperTest.java
+++ /dev/null
@@ -1,314 +0,0 @@
-/*
- * Copyright (C) 2019 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.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * 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
- */
-
-package com.android.textclassifier;
-
-import static android.view.textclassifier.ConversationActions.Message.PERSON_USER_OTHERS;
-import static android.view.textclassifier.ConversationActions.Message.PERSON_USER_SELF;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.app.PendingIntent;
-import android.app.Person;
-import android.app.RemoteAction;
-import android.content.ComponentName;
-import android.content.Intent;
-import android.graphics.drawable.Icon;
-import android.net.Uri;
-import android.os.Bundle;
-import android.view.textclassifier.ConversationAction;
-import android.view.textclassifier.ConversationActions;
-
-import androidx.test.InstrumentationRegistry;
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import com.android.textclassifier.intent.LabeledIntent;
-import com.android.textclassifier.intent.TemplateIntentFactory;
-
-import com.google.android.textclassifier.ActionsSuggestionsModel;
-import com.google.android.textclassifier.RemoteActionTemplate;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.time.Instant;
-import java.time.ZoneId;
-import java.time.ZonedDateTime;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-import java.util.Locale;
-import java.util.function.Function;
-
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public class ActionsSuggestionsHelperTest {
-    private static final String LOCALE_TAG = Locale.US.toLanguageTag();
-    private static final Function<CharSequence, List<String>> LANGUAGE_DETECTOR =
-            charSequence -> Collections.singletonList(LOCALE_TAG);
-
-    @Test
-    public void testToNativeMessages_emptyInput() {
-        ActionsSuggestionsModel.ConversationMessage[] conversationMessages =
-                ActionsSuggestionsHelper.toNativeMessages(
-                        Collections.emptyList(), LANGUAGE_DETECTOR);
-
-        assertThat(conversationMessages).isEmpty();
-    }
-
-    @Test
-    public void testToNativeMessages_noTextMessages() {
-        ConversationActions.Message messageWithoutText =
-                new ConversationActions.Message.Builder(PERSON_USER_OTHERS).build();
-
-        ActionsSuggestionsModel.ConversationMessage[] conversationMessages =
-                ActionsSuggestionsHelper.toNativeMessages(
-                        Collections.singletonList(messageWithoutText), LANGUAGE_DETECTOR);
-
-        assertThat(conversationMessages).isEmpty();
-    }
-
-    @Test
-    public void testToNativeMessages_userIdEncoding() {
-        Person userA = new Person.Builder().setName("userA").build();
-        Person userB = new Person.Builder().setName("userB").build();
-
-        ConversationActions.Message firstMessage =
-                new ConversationActions.Message.Builder(userB).setText("first").build();
-        ConversationActions.Message secondMessage =
-                new ConversationActions.Message.Builder(userA).setText("second").build();
-        ConversationActions.Message thirdMessage =
-                new ConversationActions.Message.Builder(PERSON_USER_SELF).setText("third").build();
-        ConversationActions.Message fourthMessage =
-                new ConversationActions.Message.Builder(userA).setText("fourth").build();
-
-        ActionsSuggestionsModel.ConversationMessage[] conversationMessages =
-                ActionsSuggestionsHelper.toNativeMessages(
-                        Arrays.asList(firstMessage, secondMessage, thirdMessage, fourthMessage),
-                        LANGUAGE_DETECTOR);
-
-        assertThat(conversationMessages).hasLength(4);
-        assertNativeMessage(conversationMessages[0], firstMessage.getText(), 2, 0);
-        assertNativeMessage(conversationMessages[1], secondMessage.getText(), 1, 0);
-        assertNativeMessage(conversationMessages[2], thirdMessage.getText(), 0, 0);
-        assertNativeMessage(conversationMessages[3], fourthMessage.getText(), 1, 0);
-    }
-
-    @Test
-    public void testToNativeMessages_referenceTime() {
-        ConversationActions.Message firstMessage =
-                new ConversationActions.Message.Builder(PERSON_USER_OTHERS)
-                        .setText("first")
-                        .setReferenceTime(createZonedDateTimeFromMsUtc(1000))
-                        .build();
-        ConversationActions.Message secondMessage =
-                new ConversationActions.Message.Builder(PERSON_USER_OTHERS)
-                        .setText("second")
-                        .build();
-        ConversationActions.Message thirdMessage =
-                new ConversationActions.Message.Builder(PERSON_USER_OTHERS)
-                        .setText("third")
-                        .setReferenceTime(createZonedDateTimeFromMsUtc(2000))
-                        .build();
-
-        ActionsSuggestionsModel.ConversationMessage[] conversationMessages =
-                ActionsSuggestionsHelper.toNativeMessages(
-                        Arrays.asList(firstMessage, secondMessage, thirdMessage),
-                        LANGUAGE_DETECTOR);
-
-        assertThat(conversationMessages).hasLength(3);
-        assertNativeMessage(conversationMessages[0], firstMessage.getText(), 1, 1000);
-        assertNativeMessage(conversationMessages[1], secondMessage.getText(), 1, 0);
-        assertNativeMessage(conversationMessages[2], thirdMessage.getText(), 1, 2000);
-    }
-
-    @Test
-    public void testDeduplicateActions() {
-        Bundle phoneExtras = new Bundle();
-        Intent phoneIntent = new Intent();
-        phoneIntent.setComponent(new ComponentName("phone", "intent"));
-        ExtrasUtils.putActionIntent(phoneExtras, phoneIntent);
-
-        Bundle anotherPhoneExtras = new Bundle();
-        Intent anotherPhoneIntent = new Intent();
-        anotherPhoneIntent.setComponent(new ComponentName("phone", "another.intent"));
-        ExtrasUtils.putActionIntent(anotherPhoneExtras, anotherPhoneIntent);
-
-        Bundle urlExtras = new Bundle();
-        Intent urlIntent = new Intent();
-        urlIntent.setComponent(new ComponentName("url", "intent"));
-        ExtrasUtils.putActionIntent(urlExtras, urlIntent);
-
-        PendingIntent pendingIntent =
-                PendingIntent.getActivity(
-                        InstrumentationRegistry.getTargetContext(), 0, phoneIntent, 0);
-        Icon icon = Icon.createWithData(new byte[0], 0, 0);
-        ConversationAction action =
-                new ConversationAction.Builder(ConversationAction.TYPE_CALL_PHONE)
-                        .setAction(new RemoteAction(icon, "label", "1", pendingIntent))
-                        .setExtras(phoneExtras)
-                        .build();
-        ConversationAction actionWithSameLabel =
-                new ConversationAction.Builder(ConversationAction.TYPE_CALL_PHONE)
-                        .setAction(new RemoteAction(icon, "label", "2", pendingIntent))
-                        .setExtras(phoneExtras)
-                        .build();
-        ConversationAction actionWithSamePackageButDifferentClass =
-                new ConversationAction.Builder(ConversationAction.TYPE_CALL_PHONE)
-                        .setAction(new RemoteAction(icon, "label", "3", pendingIntent))
-                        .setExtras(anotherPhoneExtras)
-                        .build();
-        ConversationAction actionWithDifferentLabel =
-                new ConversationAction.Builder(ConversationAction.TYPE_CALL_PHONE)
-                        .setAction(new RemoteAction(icon, "another_label", "4", pendingIntent))
-                        .setExtras(phoneExtras)
-                        .build();
-        ConversationAction actionWithDifferentPackage =
-                new ConversationAction.Builder(ConversationAction.TYPE_OPEN_URL)
-                        .setAction(new RemoteAction(icon, "label", "5", pendingIntent))
-                        .setExtras(urlExtras)
-                        .build();
-        ConversationAction actionWithoutRemoteAction =
-                new ConversationAction.Builder(ConversationAction.TYPE_CREATE_REMINDER).build();
-
-        List<ConversationAction> conversationActions =
-                ActionsSuggestionsHelper.removeActionsWithDuplicates(
-                        Arrays.asList(
-                                action,
-                                actionWithSameLabel,
-                                actionWithSamePackageButDifferentClass,
-                                actionWithDifferentLabel,
-                                actionWithDifferentPackage,
-                                actionWithoutRemoteAction));
-
-        assertThat(conversationActions).hasSize(3);
-        assertThat(conversationActions.get(0).getAction().getContentDescription()).isEqualTo("4");
-        assertThat(conversationActions.get(1).getAction().getContentDescription()).isEqualTo("5");
-        assertThat(conversationActions.get(2).getAction()).isNull();
-    }
-
-    @Test
-    public void testDeduplicateActions_nullComponent() {
-        Bundle phoneExtras = new Bundle();
-        Intent phoneIntent = new Intent(Intent.ACTION_DIAL);
-        ExtrasUtils.putActionIntent(phoneExtras, phoneIntent);
-        PendingIntent pendingIntent =
-                PendingIntent.getActivity(
-                        InstrumentationRegistry.getTargetContext(), 0, phoneIntent, 0);
-        Icon icon = Icon.createWithData(new byte[0], 0, 0);
-        ConversationAction action =
-                new ConversationAction.Builder(ConversationAction.TYPE_CALL_PHONE)
-                        .setAction(new RemoteAction(icon, "label", "1", pendingIntent))
-                        .setExtras(phoneExtras)
-                        .build();
-        ConversationAction actionWithSameLabel =
-                new ConversationAction.Builder(ConversationAction.TYPE_CALL_PHONE)
-                        .setAction(new RemoteAction(icon, "label", "2", pendingIntent))
-                        .setExtras(phoneExtras)
-                        .build();
-
-        List<ConversationAction> conversationActions =
-                ActionsSuggestionsHelper.removeActionsWithDuplicates(
-                        Arrays.asList(action, actionWithSameLabel));
-
-        assertThat(conversationActions).isEmpty();
-    }
-
-    public void createLabeledIntentResult_null() {
-        ActionsSuggestionsModel.ActionSuggestion nativeSuggestion =
-                new ActionsSuggestionsModel.ActionSuggestion(
-                        "text", ConversationAction.TYPE_OPEN_URL, 1.0f, null, null, null);
-
-        LabeledIntent.Result labeledIntentResult =
-                ActionsSuggestionsHelper.createLabeledIntentResult(
-                        InstrumentationRegistry.getTargetContext(),
-                        new TemplateIntentFactory(),
-                        nativeSuggestion);
-
-        assertThat(labeledIntentResult).isNull();
-    }
-
-    @Test
-    public void createLabeledIntentResult_emptyList() {
-        ActionsSuggestionsModel.ActionSuggestion nativeSuggestion =
-                new ActionsSuggestionsModel.ActionSuggestion(
-                        "text",
-                        ConversationAction.TYPE_OPEN_URL,
-                        1.0f,
-                        null,
-                        null,
-                        new RemoteActionTemplate[0]);
-
-        LabeledIntent.Result labeledIntentResult =
-                ActionsSuggestionsHelper.createLabeledIntentResult(
-                        InstrumentationRegistry.getTargetContext(),
-                        new TemplateIntentFactory(),
-                        nativeSuggestion);
-
-        assertThat(labeledIntentResult).isNull();
-    }
-
-    @Test
-    public void createLabeledIntentResult() {
-        ActionsSuggestionsModel.ActionSuggestion nativeSuggestion =
-                new ActionsSuggestionsModel.ActionSuggestion(
-                        "text",
-                        ConversationAction.TYPE_OPEN_URL,
-                        1.0f,
-                        null,
-                        null,
-                        new RemoteActionTemplate[] {
-                            new RemoteActionTemplate(
-                                    "title",
-                                    null,
-                                    "description",
-                                    null,
-                                    Intent.ACTION_VIEW,
-                                    Uri.parse("http://www.android.com").toString(),
-                                    null,
-                                    0,
-                                    null,
-                                    null,
-                                    null,
-                                    0)
-                        });
-
-        LabeledIntent.Result labeledIntentResult =
-                ActionsSuggestionsHelper.createLabeledIntentResult(
-                        InstrumentationRegistry.getTargetContext(),
-                        new TemplateIntentFactory(),
-                        nativeSuggestion);
-
-        assertThat(labeledIntentResult.remoteAction.getTitle()).isEqualTo("title");
-        assertThat(labeledIntentResult.resolvedIntent.getAction()).isEqualTo(Intent.ACTION_VIEW);
-    }
-
-    private ZonedDateTime createZonedDateTimeFromMsUtc(long msUtc) {
-        return ZonedDateTime.ofInstant(Instant.ofEpochMilli(msUtc), ZoneId.of("UTC"));
-    }
-
-    private static void assertNativeMessage(
-            ActionsSuggestionsModel.ConversationMessage nativeMessage,
-            CharSequence text,
-            int userId,
-            long referenceTimeInMsUtc) {
-        assertThat(nativeMessage.getText()).isEqualTo(text.toString());
-        assertThat(nativeMessage.getUserId()).isEqualTo(userId);
-        assertThat(nativeMessage.getDetectedTextLanguageTags()).isEqualTo(LOCALE_TAG);
-        assertThat(nativeMessage.getReferenceTimeMsUtc()).isEqualTo(referenceTimeInMsUtc);
-    }
-}
diff --git a/java/tests/unittests/src/com/android/textclassifier/FakeContextBuilder.java b/java/tests/unittests/src/com/android/textclassifier/FakeContextBuilder.java
deleted file mode 100644
index 451229a..0000000
--- a/java/tests/unittests/src/com/android/textclassifier/FakeContextBuilder.java
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * Copyright (C) 2019 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.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * 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
- */
-
-package com.android.textclassifier;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-import android.annotation.Nullable;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.ContextWrapper;
-import android.content.Intent;
-import android.content.pm.ActivityInfo;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-
-import androidx.test.InstrumentationRegistry;
-
-import com.google.common.base.Preconditions;
-
-import org.mockito.stubbing.Answer;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.UUID;
-
-/** A builder used to build a fake context for testing. */
-public final class FakeContextBuilder {
-
-    /** A component name that can be used for tests. */
-    public static final ComponentName DEFAULT_COMPONENT = new ComponentName("pkg", "cls");
-
-    private final PackageManager mPackageManager;
-    private final ContextWrapper mContext;
-    private final Map<String, ComponentName> mComponents = new HashMap<>();
-    private final Map<String, CharSequence> mAppLabels = new HashMap<>();
-    private @Nullable ComponentName mAllIntentComponent;
-
-    public FakeContextBuilder() {
-        mPackageManager = mock(PackageManager.class);
-        when(mPackageManager.resolveActivity(any(Intent.class), anyInt())).thenReturn(null);
-        mContext =
-                new ContextWrapper(InstrumentationRegistry.getTargetContext()) {
-                    @Override
-                    public PackageManager getPackageManager() {
-                        return mPackageManager;
-                    }
-                };
-    }
-
-    /**
-     * Sets the component name of an activity to handle the specified intent action.
-     *
-     * <p><strong>NOTE: </strong>By default, no component is set to handle any intent.
-     */
-    public FakeContextBuilder setIntentComponent(
-            String intentAction, @Nullable ComponentName component) {
-        Preconditions.checkNotNull(intentAction);
-        mComponents.put(intentAction, component);
-        return this;
-    }
-
-    /** Sets the app label res for a specified package. */
-    public FakeContextBuilder setAppLabel(String packageName, @Nullable CharSequence appLabel) {
-        Preconditions.checkNotNull(packageName);
-        mAppLabels.put(packageName, appLabel);
-        return this;
-    }
-
-    /**
-     * Sets the component name of an activity to handle all intents.
-     *
-     * <p><strong>NOTE: </strong>By default, no component is set to handle any intent.
-     */
-    public FakeContextBuilder setAllIntentComponent(@Nullable ComponentName component) {
-        mAllIntentComponent = component;
-        return this;
-    }
-
-    /** Builds and returns a fake context. */
-    public Context build() {
-        when(mPackageManager.resolveActivity(any(Intent.class), anyInt()))
-                .thenAnswer(
-                        (Answer<ResolveInfo>)
-                                invocation -> {
-                                    final String action =
-                                            ((Intent) invocation.getArgument(0)).getAction();
-                                    final ComponentName component =
-                                            mComponents.containsKey(action)
-                                                    ? mComponents.get(action)
-                                                    : mAllIntentComponent;
-                                    return getResolveInfo(component);
-                                });
-        when(mPackageManager.getApplicationLabel(any(ApplicationInfo.class)))
-                .thenAnswer(
-                        (Answer<CharSequence>)
-                                invocation -> {
-                                    ApplicationInfo applicationInfo = invocation.getArgument(0);
-                                    return mAppLabels.get(applicationInfo.packageName);
-                                });
-        return mContext;
-    }
-
-    /** Returns a component name with random package and class names. */
-    public static ComponentName newComponent() {
-        return new ComponentName(UUID.randomUUID().toString(), UUID.randomUUID().toString());
-    }
-
-    private static ResolveInfo getResolveInfo(ComponentName component) {
-        final ResolveInfo info;
-        if (component == null) {
-            info = null;
-        } else {
-            // NOTE: If something breaks in TextClassifier because we expect more fields to be set
-            // in here, just add them.
-            info = new ResolveInfo();
-            info.activityInfo = new ActivityInfo();
-            info.activityInfo.packageName = component.getPackageName();
-            info.activityInfo.name = component.getClassName();
-            info.activityInfo.exported = true;
-            info.activityInfo.applicationInfo = new ApplicationInfo();
-            info.activityInfo.applicationInfo.packageName = component.getPackageName();
-            info.activityInfo.applicationInfo.icon = 0;
-        }
-        return info;
-    }
-}
diff --git a/java/tests/unittests/src/com/android/textclassifier/ModelFileManagerTest.java b/java/tests/unittests/src/com/android/textclassifier/ModelFileManagerTest.java
deleted file mode 100644
index c2626ff..0000000
--- a/java/tests/unittests/src/com/android/textclassifier/ModelFileManagerTest.java
+++ /dev/null
@@ -1,373 +0,0 @@
-/*
- * Copyright (C) 2019 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.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * 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
- */
-
-package com.android.textclassifier;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.Mockito.when;
-
-import android.os.LocaleList;
-
-import androidx.test.InstrumentationRegistry;
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-import java.util.Locale;
-import java.util.function.Supplier;
-import java.util.stream.Collectors;
-
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public class ModelFileManagerTest {
-    private static final Locale DEFAULT_LOCALE = Locale.forLanguageTag("en-US");
-    @Mock private Supplier<List<ModelFileManager.ModelFile>> mModelFileSupplier;
-    private ModelFileManager.ModelFileSupplierImpl mModelFileSupplierImpl;
-    private ModelFileManager mModelFileManager;
-    private File mRootTestDir;
-    private File mFactoryModelDir;
-    private File mUpdatedModelFile;
-
-    @Before
-    public void setup() {
-        MockitoAnnotations.initMocks(this);
-        mModelFileManager = new ModelFileManager(mModelFileSupplier);
-        mRootTestDir = InstrumentationRegistry.getTargetContext().getCacheDir();
-        mFactoryModelDir = new File(mRootTestDir, "factory");
-        mUpdatedModelFile = new File(mRootTestDir, "updated.model");
-
-        mModelFileSupplierImpl =
-                new ModelFileManager.ModelFileSupplierImpl(
-                        mFactoryModelDir,
-                        "test\\d.model",
-                        mUpdatedModelFile,
-                        fd -> 1,
-                        fd -> ModelFileManager.ModelFile.LANGUAGE_INDEPENDENT);
-
-        mRootTestDir.mkdirs();
-        mFactoryModelDir.mkdirs();
-
-        Locale.setDefault(DEFAULT_LOCALE);
-    }
-
-    @After
-    public void removeTestDir() {
-        recursiveDelete(mRootTestDir);
-    }
-
-    @Test
-    public void get() {
-        ModelFileManager.ModelFile modelFile =
-                new ModelFileManager.ModelFile(
-                        new File("/path/a"), 1, Collections.emptyList(), "", true);
-        when(mModelFileSupplier.get()).thenReturn(Collections.singletonList(modelFile));
-
-        List<ModelFileManager.ModelFile> modelFiles = mModelFileManager.listModelFiles();
-
-        assertThat(modelFiles).hasSize(1);
-        assertThat(modelFiles.get(0)).isEqualTo(modelFile);
-    }
-
-    @Test
-    public void findBestModel_versionCode() {
-        ModelFileManager.ModelFile olderModelFile =
-                new ModelFileManager.ModelFile(
-                        new File("/path/a"), 1, Collections.emptyList(), "", true);
-
-        ModelFileManager.ModelFile newerModelFile =
-                new ModelFileManager.ModelFile(
-                        new File("/path/b"), 2, Collections.emptyList(), "", true);
-        when(mModelFileSupplier.get()).thenReturn(Arrays.asList(olderModelFile, newerModelFile));
-
-        ModelFileManager.ModelFile bestModelFile =
-                mModelFileManager.findBestModelFile(LocaleList.getEmptyLocaleList());
-
-        assertThat(bestModelFile).isEqualTo(newerModelFile);
-    }
-
-    @Test
-    public void findBestModel_languageDependentModelIsPreferred() {
-        Locale locale = Locale.forLanguageTag("ja");
-        ModelFileManager.ModelFile languageIndependentModelFile =
-                new ModelFileManager.ModelFile(
-                        new File("/path/a"), 1, Collections.emptyList(), "", true);
-
-        ModelFileManager.ModelFile languageDependentModelFile =
-                new ModelFileManager.ModelFile(
-                        new File("/path/b"),
-                        1,
-                        Collections.singletonList(locale),
-                        locale.toLanguageTag(),
-                        false);
-        when(mModelFileSupplier.get())
-                .thenReturn(
-                        Arrays.asList(languageIndependentModelFile, languageDependentModelFile));
-
-        ModelFileManager.ModelFile bestModelFile =
-                mModelFileManager.findBestModelFile(
-                        LocaleList.forLanguageTags(locale.toLanguageTag()));
-        assertThat(bestModelFile).isEqualTo(languageDependentModelFile);
-    }
-
-    @Test
-    public void findBestModel_noMatchedLanguageModel() {
-        Locale locale = Locale.forLanguageTag("ja");
-        ModelFileManager.ModelFile languageIndependentModelFile =
-                new ModelFileManager.ModelFile(
-                        new File("/path/a"), 1, Collections.emptyList(), "", true);
-
-        ModelFileManager.ModelFile languageDependentModelFile =
-                new ModelFileManager.ModelFile(
-                        new File("/path/b"),
-                        1,
-                        Collections.singletonList(locale),
-                        locale.toLanguageTag(),
-                        false);
-
-        when(mModelFileSupplier.get())
-                .thenReturn(
-                        Arrays.asList(languageIndependentModelFile, languageDependentModelFile));
-
-        ModelFileManager.ModelFile bestModelFile =
-                mModelFileManager.findBestModelFile(LocaleList.forLanguageTags("zh-hk"));
-        assertThat(bestModelFile).isEqualTo(languageIndependentModelFile);
-    }
-
-    @Test
-    public void findBestModel_noMatchedLanguageModel_defaultLocaleModelExists() {
-        ModelFileManager.ModelFile languageIndependentModelFile =
-                new ModelFileManager.ModelFile(
-                        new File("/path/a"), 1, Collections.emptyList(), "", true);
-
-        ModelFileManager.ModelFile languageDependentModelFile =
-                new ModelFileManager.ModelFile(
-                        new File("/path/b"),
-                        1,
-                        Collections.singletonList(DEFAULT_LOCALE),
-                        DEFAULT_LOCALE.toLanguageTag(),
-                        false);
-
-        when(mModelFileSupplier.get())
-                .thenReturn(
-                        Arrays.asList(languageIndependentModelFile, languageDependentModelFile));
-
-        ModelFileManager.ModelFile bestModelFile =
-                mModelFileManager.findBestModelFile(LocaleList.forLanguageTags("zh-hk"));
-        assertThat(bestModelFile).isEqualTo(languageIndependentModelFile);
-    }
-
-    @Test
-    public void findBestModel_languageIsMoreImportantThanVersion() {
-        ModelFileManager.ModelFile matchButOlderModel =
-                new ModelFileManager.ModelFile(
-                        new File("/path/a"),
-                        1,
-                        Collections.singletonList(Locale.forLanguageTag("fr")),
-                        "fr",
-                        false);
-
-        ModelFileManager.ModelFile mismatchButNewerModel =
-                new ModelFileManager.ModelFile(
-                        new File("/path/b"),
-                        2,
-                        Collections.singletonList(Locale.forLanguageTag("ja")),
-                        "ja",
-                        false);
-
-        when(mModelFileSupplier.get())
-                .thenReturn(Arrays.asList(matchButOlderModel, mismatchButNewerModel));
-
-        ModelFileManager.ModelFile bestModelFile =
-                mModelFileManager.findBestModelFile(LocaleList.forLanguageTags("fr"));
-        assertThat(bestModelFile).isEqualTo(matchButOlderModel);
-    }
-
-    @Test
-    public void findBestModel_languageIsMoreImportantThanVersion_bestModelComesFirst() {
-        ModelFileManager.ModelFile matchLocaleModel =
-                new ModelFileManager.ModelFile(
-                        new File("/path/b"),
-                        1,
-                        Collections.singletonList(Locale.forLanguageTag("ja")),
-                        "ja",
-                        false);
-
-        ModelFileManager.ModelFile languageIndependentModel =
-                new ModelFileManager.ModelFile(
-                        new File("/path/a"), 2, Collections.emptyList(), "", true);
-        when(mModelFileSupplier.get())
-                .thenReturn(Arrays.asList(matchLocaleModel, languageIndependentModel));
-
-        ModelFileManager.ModelFile bestModelFile =
-                mModelFileManager.findBestModelFile(LocaleList.forLanguageTags("ja"));
-
-        assertThat(bestModelFile).isEqualTo(matchLocaleModel);
-    }
-
-    @Test
-    public void modelFileEquals() {
-        ModelFileManager.ModelFile modelA =
-                new ModelFileManager.ModelFile(
-                        new File("/path/a"),
-                        1,
-                        Collections.singletonList(Locale.forLanguageTag("ja")),
-                        "ja",
-                        false);
-
-        ModelFileManager.ModelFile modelB =
-                new ModelFileManager.ModelFile(
-                        new File("/path/a"),
-                        1,
-                        Collections.singletonList(Locale.forLanguageTag("ja")),
-                        "ja",
-                        false);
-
-        assertThat(modelA).isEqualTo(modelB);
-    }
-
-    @Test
-    public void modelFile_different() {
-        ModelFileManager.ModelFile modelA =
-                new ModelFileManager.ModelFile(
-                        new File("/path/a"),
-                        1,
-                        Collections.singletonList(Locale.forLanguageTag("ja")),
-                        "ja",
-                        false);
-
-        ModelFileManager.ModelFile modelB =
-                new ModelFileManager.ModelFile(
-                        new File("/path/b"),
-                        1,
-                        Collections.singletonList(Locale.forLanguageTag("ja")),
-                        "ja",
-                        false);
-
-        assertThat(modelA).isNotEqualTo(modelB);
-    }
-
-    @Test
-    public void modelFile_getPath() {
-        ModelFileManager.ModelFile modelA =
-                new ModelFileManager.ModelFile(
-                        new File("/path/a"),
-                        1,
-                        Collections.singletonList(Locale.forLanguageTag("ja")),
-                        "ja",
-                        false);
-
-        assertThat(modelA.getPath()).isEqualTo("/path/a");
-    }
-
-    @Test
-    public void modelFile_getName() {
-        ModelFileManager.ModelFile modelA =
-                new ModelFileManager.ModelFile(
-                        new File("/path/a"),
-                        1,
-                        Collections.singletonList(Locale.forLanguageTag("ja")),
-                        "ja",
-                        false);
-
-        assertThat(modelA.getName()).isEqualTo("a");
-    }
-
-    @Test
-    public void modelFile_isPreferredTo_languageDependentIsBetter() {
-        ModelFileManager.ModelFile modelA =
-                new ModelFileManager.ModelFile(
-                        new File("/path/a"),
-                        1,
-                        Collections.singletonList(Locale.forLanguageTag("ja")),
-                        "ja",
-                        false);
-
-        ModelFileManager.ModelFile modelB =
-                new ModelFileManager.ModelFile(
-                        new File("/path/b"), 2, Collections.emptyList(), "", true);
-
-        assertThat(modelA.isPreferredTo(modelB)).isTrue();
-    }
-
-    @Test
-    public void modelFile_isPreferredTo_version() {
-        ModelFileManager.ModelFile modelA =
-                new ModelFileManager.ModelFile(
-                        new File("/path/a"),
-                        2,
-                        Collections.singletonList(Locale.forLanguageTag("ja")),
-                        "ja",
-                        false);
-
-        ModelFileManager.ModelFile modelB =
-                new ModelFileManager.ModelFile(
-                        new File("/path/b"), 1, Collections.emptyList(), "", false);
-
-        assertThat(modelA.isPreferredTo(modelB)).isTrue();
-    }
-
-    @Test
-    public void testFileSupplierImpl_updatedFileOnly() throws IOException {
-        mUpdatedModelFile.createNewFile();
-        File model1 = new File(mFactoryModelDir, "test1.model");
-        model1.createNewFile();
-        File model2 = new File(mFactoryModelDir, "test2.model");
-        model2.createNewFile();
-        new File(mFactoryModelDir, "not_match_regex.model").createNewFile();
-
-        List<ModelFileManager.ModelFile> modelFiles = mModelFileSupplierImpl.get();
-        List<String> modelFilePaths =
-                modelFiles.stream()
-                        .map(modelFile -> modelFile.getPath())
-                        .collect(Collectors.toList());
-
-        assertThat(modelFiles).hasSize(3);
-        assertThat(modelFilePaths)
-                .containsExactly(
-                        mUpdatedModelFile.getAbsolutePath(),
-                        model1.getAbsolutePath(),
-                        model2.getAbsolutePath());
-    }
-
-    @Test
-    public void testFileSupplierImpl_empty() {
-        mFactoryModelDir.delete();
-        List<ModelFileManager.ModelFile> modelFiles = mModelFileSupplierImpl.get();
-
-        assertThat(modelFiles).hasSize(0);
-    }
-
-    private static void recursiveDelete(File f) {
-        if (f.isDirectory()) {
-            for (File innerFile : f.listFiles()) {
-                recursiveDelete(innerFile);
-            }
-        }
-        f.delete();
-    }
-}
diff --git a/java/tests/unittests/src/com/android/textclassifier/StringUtilsTest.java b/java/tests/unittests/src/com/android/textclassifier/StringUtilsTest.java
deleted file mode 100644
index c3fc717..0000000
--- a/java/tests/unittests/src/com/android/textclassifier/StringUtilsTest.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (C) 2019 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.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * 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
- */
-
-package com.android.textclassifier;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.testng.Assert.assertThrows;
-
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public class StringUtilsTest {
-
-    @Test
-    public void testGetSubString() {
-        final String text = "Yakuza call themselves 任侠団体";
-        int start;
-        int end;
-        int minimumLength;
-
-        // End index at end of text.
-        start = text.indexOf("任侠団体");
-        end = text.length();
-        minimumLength = 20;
-        assertThat(StringUtils.getSubString(text, start, end, minimumLength))
-                .isEqualTo("call themselves 任侠団体");
-
-        // Start index at beginning of text.
-        start = 0;
-        end = "Yakuza".length();
-        minimumLength = 15;
-        assertThat(StringUtils.getSubString(text, start, end, minimumLength))
-                .isEqualTo("Yakuza call themselves");
-
-        // Text in the middle
-        start = text.indexOf("all");
-        end = start + 1;
-        minimumLength = 10;
-        assertThat(StringUtils.getSubString(text, start, end, minimumLength))
-                .isEqualTo("Yakuza call themselves");
-
-        // Selection >= minimumLength.
-        start = text.indexOf("themselves");
-        end = start + "themselves".length();
-        minimumLength = end - start;
-        assertThat(StringUtils.getSubString(text, start, end, minimumLength))
-                .isEqualTo("themselves");
-
-        // text.length < minimumLength.
-        minimumLength = text.length() + 1;
-        assertThat(StringUtils.getSubString(text, start, end, minimumLength)).isEqualTo(text);
-    }
-
-    @Test
-    public void testGetSubString_invalidParams() {
-        final String text = "The Yoruba regard Olodumare as the principal agent of creation";
-        final int length = text.length();
-        final int minimumLength = 10;
-
-        // Null text
-        assertThrows(() -> StringUtils.getSubString(null, 0, 1, minimumLength));
-        // start > end
-        assertThrows(() -> StringUtils.getSubString(text, 6, 5, minimumLength));
-        // start < 0
-        assertThrows(() -> StringUtils.getSubString(text, -1, 5, minimumLength));
-        // end > text.length
-        assertThrows(() -> StringUtils.getSubString(text, 6, length + 1, minimumLength));
-    }
-}
diff --git a/java/tests/unittests/src/com/android/textclassifier/TextClassificationConstantsTest.java b/java/tests/unittests/src/com/android/textclassifier/TextClassificationConstantsTest.java
deleted file mode 100644
index b7c9246..0000000
--- a/java/tests/unittests/src/com/android/textclassifier/TextClassificationConstantsTest.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright (C) 2019 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.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * 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
- */
-
-package com.android.textclassifier;
-
-import static com.google.common.truth.Truth.assertWithMessage;
-
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.Assert;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public class TextClassificationConstantsTest {
-
-    private static final float EPSILON = 0.0001f;
-
-    @Test
-    public void testLoadFromString_defaultValues() {
-        final TextClassificationConstants constants = new TextClassificationConstants();
-
-        assertWithMessage("suggest_selection_max_range_length")
-                .that(constants.getSuggestSelectionMaxRangeLength())
-                .isEqualTo(10 * 1000);
-        assertWithMessage("classify_text_max_range_length")
-                .that(constants.getClassifyTextMaxRangeLength())
-                .isEqualTo(10 * 1000);
-        assertWithMessage("generate_links_max_text_length")
-                .that(constants.getGenerateLinksMaxTextLength())
-                .isEqualTo(100 * 1000);
-        //        assertWithMessage("generate_links_log_sample_rate")
-        //                .that(constants.getGenerateLinksLogSampleRate()).isEqualTo(100);
-        assertWithMessage("entity_list_default")
-                .that(constants.getEntityListDefault())
-                .containsExactly("address", "email", "url", "phone", "date", "datetime", "flight");
-        assertWithMessage("entity_list_not_editable")
-                .that(constants.getEntityListNotEditable())
-                .containsExactly("address", "email", "url", "phone", "date", "datetime", "flight");
-        assertWithMessage("entity_list_editable")
-                .that(constants.getEntityListEditable())
-                .containsExactly("address", "email", "url", "phone", "date", "datetime", "flight");
-        assertWithMessage("in_app_conversation_action_types_default")
-                .that(constants.getInAppConversationActionTypes())
-                .containsExactly(
-                        "text_reply",
-                        "create_reminder",
-                        "call_phone",
-                        "open_url",
-                        "send_email",
-                        "send_sms",
-                        "track_flight",
-                        "view_calendar",
-                        "view_map",
-                        "add_contact",
-                        "copy");
-        assertWithMessage("notification_conversation_action_types_default")
-                .that(constants.getNotificationConversationActionTypes())
-                .containsExactly(
-                        "text_reply",
-                        "create_reminder",
-                        "call_phone",
-                        "open_url",
-                        "send_email",
-                        "send_sms",
-                        "track_flight",
-                        "view_calendar",
-                        "view_map",
-                        "add_contact",
-                        "copy");
-        assertWithMessage("lang_id_threshold_override")
-                .that(constants.getLangIdThresholdOverride())
-                .isWithin(EPSILON)
-                .of(-1f);
-        Assert.assertArrayEquals(
-                "lang_id_context_settings",
-                constants.getLangIdContextSettings(),
-                new float[] {20, 1, 0.4f},
-                EPSILON);
-        assertWithMessage("detect_language_from_text_enabled")
-                .that(constants.isDetectLanguagesFromTextEnabled())
-                .isTrue();
-        assertWithMessage("template_intent_factory_enabled")
-                .that(constants.isTemplateIntentFactoryEnabled())
-                .isTrue();
-        assertWithMessage("translate_in_classification_enabled")
-                .that(constants.isTranslateInClassificationEnabled())
-                .isTrue();
-    }
-}
diff --git a/java/tests/unittests/src/com/android/textclassifier/TextClassifierImplTest.java b/java/tests/unittests/src/com/android/textclassifier/TextClassifierImplTest.java
deleted file mode 100644
index 6faba34..0000000
--- a/java/tests/unittests/src/com/android/textclassifier/TextClassifierImplTest.java
+++ /dev/null
@@ -1,681 +0,0 @@
-/*
- * Copyright (C) 2019 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.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * 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
- */
-
-package com.android.textclassifier;
-
-import static org.hamcrest.CoreMatchers.not;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.assertTrue;
-
-import android.app.RemoteAction;
-import android.content.Context;
-import android.content.Intent;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.LocaleList;
-import android.text.Spannable;
-import android.text.SpannableString;
-import android.view.textclassifier.ConversationAction;
-import android.view.textclassifier.ConversationActions;
-import android.view.textclassifier.TextClassification;
-import android.view.textclassifier.TextClassifier;
-import android.view.textclassifier.TextLanguage;
-import android.view.textclassifier.TextLinks;
-import android.view.textclassifier.TextSelection;
-
-import androidx.test.InstrumentationRegistry;
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import com.google.common.truth.Truth;
-
-import org.hamcrest.BaseMatcher;
-import org.hamcrest.Description;
-import org.hamcrest.Matcher;
-import org.junit.Before;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * Testing {@link TextClassifierImplTest} APIs on local and system textclassifier.
- *
- * <p>Tests are skipped if such a textclassifier does not exist.
- */
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public class TextClassifierImplTest {
-
-    // TODO: Implement TextClassifierService testing.
-
-    private static final LocaleList LOCALES = LocaleList.forLanguageTags("en-US");
-    private static final String NO_TYPE = null;
-
-    private Context mContext;
-    private TextClassifierImpl mClassifier;
-
-    @Before
-    public void setup() {
-        mContext = InstrumentationRegistry.getTargetContext();
-        mClassifier = new TextClassifierImpl(mContext, new TextClassificationConstants());
-    }
-
-    @Test
-    public void testSuggestSelection() {
-        String text = "Contact me at droid@android.com";
-        String selected = "droid";
-        String suggested = "droid@android.com";
-        int startIndex = text.indexOf(selected);
-        int endIndex = startIndex + selected.length();
-        int smartStartIndex = text.indexOf(suggested);
-        int smartEndIndex = smartStartIndex + suggested.length();
-        TextSelection.Request request =
-                new TextSelection.Request.Builder(text, startIndex, endIndex)
-                        .setDefaultLocales(LOCALES)
-                        .build();
-
-        TextSelection selection = mClassifier.suggestSelection(request);
-        assertThat(
-                selection,
-                isTextSelection(smartStartIndex, smartEndIndex, TextClassifier.TYPE_EMAIL));
-    }
-
-    @Test
-    public void testSuggestSelection_url() {
-        String text = "Visit http://www.android.com for more information";
-        String selected = "http";
-        String suggested = "http://www.android.com";
-        int startIndex = text.indexOf(selected);
-        int endIndex = startIndex + selected.length();
-        int smartStartIndex = text.indexOf(suggested);
-        int smartEndIndex = smartStartIndex + suggested.length();
-        TextSelection.Request request =
-                new TextSelection.Request.Builder(text, startIndex, endIndex)
-                        .setDefaultLocales(LOCALES)
-                        .build();
-
-        TextSelection selection = mClassifier.suggestSelection(request);
-        assertThat(
-                selection,
-                isTextSelection(smartStartIndex, smartEndIndex, TextClassifier.TYPE_URL));
-    }
-
-    @Test
-    public void testSmartSelection_withEmoji() {
-        String text = "\uD83D\uDE02 Hello.";
-        String selected = "Hello";
-        int startIndex = text.indexOf(selected);
-        int endIndex = startIndex + selected.length();
-        TextSelection.Request request =
-                new TextSelection.Request.Builder(text, startIndex, endIndex)
-                        .setDefaultLocales(LOCALES)
-                        .build();
-
-        TextSelection selection = mClassifier.suggestSelection(request);
-        assertThat(selection, isTextSelection(startIndex, endIndex, NO_TYPE));
-    }
-
-    @Test
-    public void testClassifyText() {
-        String text = "Contact me at droid@android.com";
-        String classifiedText = "droid@android.com";
-        int startIndex = text.indexOf(classifiedText);
-        int endIndex = startIndex + classifiedText.length();
-        TextClassification.Request request =
-                new TextClassification.Request.Builder(text, startIndex, endIndex)
-                        .setDefaultLocales(LOCALES)
-                        .build();
-
-        TextClassification classification = mClassifier.classifyText(request);
-        assertThat(classification, isTextClassification(classifiedText, TextClassifier.TYPE_EMAIL));
-    }
-
-    @Test
-    public void testClassifyText_url() {
-        String text = "Visit www.android.com for more information";
-        String classifiedText = "www.android.com";
-        int startIndex = text.indexOf(classifiedText);
-        int endIndex = startIndex + classifiedText.length();
-        TextClassification.Request request =
-                new TextClassification.Request.Builder(text, startIndex, endIndex)
-                        .setDefaultLocales(LOCALES)
-                        .build();
-
-        TextClassification classification = mClassifier.classifyText(request);
-        assertThat(classification, isTextClassification(classifiedText, TextClassifier.TYPE_URL));
-        assertThat(classification, containsIntentWithAction(Intent.ACTION_VIEW));
-    }
-
-    @Test
-    public void testClassifyText_address() {
-        String text = "Brandschenkestrasse 110, Zürich, Switzerland";
-        TextClassification.Request request =
-                new TextClassification.Request.Builder(text, 0, text.length())
-                        .setDefaultLocales(LOCALES)
-                        .build();
-
-        TextClassification classification = mClassifier.classifyText(request);
-        assertThat(classification, isTextClassification(text, TextClassifier.TYPE_ADDRESS));
-    }
-
-    @Test
-    public void testClassifyText_url_inCaps() {
-        String text = "Visit HTTP://ANDROID.COM for more information";
-        String classifiedText = "HTTP://ANDROID.COM";
-        int startIndex = text.indexOf(classifiedText);
-        int endIndex = startIndex + classifiedText.length();
-        TextClassification.Request request =
-                new TextClassification.Request.Builder(text, startIndex, endIndex)
-                        .setDefaultLocales(LOCALES)
-                        .build();
-
-        TextClassification classification = mClassifier.classifyText(request);
-        assertThat(classification, isTextClassification(classifiedText, TextClassifier.TYPE_URL));
-        assertThat(classification, containsIntentWithAction(Intent.ACTION_VIEW));
-    }
-
-    @Test
-    public void testClassifyText_date() {
-        String text = "Let's meet on January 9, 2018.";
-        String classifiedText = "January 9, 2018";
-        int startIndex = text.indexOf(classifiedText);
-        int endIndex = startIndex + classifiedText.length();
-        TextClassification.Request request =
-                new TextClassification.Request.Builder(text, startIndex, endIndex)
-                        .setDefaultLocales(LOCALES)
-                        .build();
-
-        TextClassification classification = mClassifier.classifyText(request);
-        assertThat(classification, isTextClassification(classifiedText, TextClassifier.TYPE_DATE));
-        Bundle extras = classification.getExtras();
-        List<Bundle> entities = ExtrasUtils.getEntities(extras);
-        Truth.assertThat(entities).hasSize(1);
-        Bundle entity = entities.get(0);
-        Truth.assertThat(ExtrasUtils.getEntityType(entity)).isEqualTo(TextClassifier.TYPE_DATE);
-    }
-
-    @Test
-    public void testClassifyText_datetime() {
-        String text = "Let's meet 2018/01/01 10:30:20.";
-        String classifiedText = "2018/01/01 10:30:20";
-        int startIndex = text.indexOf(classifiedText);
-        int endIndex = startIndex + classifiedText.length();
-        TextClassification.Request request =
-                new TextClassification.Request.Builder(text, startIndex, endIndex)
-                        .setDefaultLocales(LOCALES)
-                        .build();
-
-        TextClassification classification = mClassifier.classifyText(request);
-        assertThat(
-                classification,
-                isTextClassification(classifiedText, TextClassifier.TYPE_DATE_TIME));
-    }
-
-    @Test
-    public void testClassifyText_foreignText() {
-        LocaleList originalLocales = LocaleList.getDefault();
-        LocaleList.setDefault(LocaleList.forLanguageTags("en"));
-        String japaneseText = "これは日本語のテキストです";
-
-        Context context =
-                new FakeContextBuilder()
-                        .setIntentComponent(
-                                Intent.ACTION_TRANSLATE, FakeContextBuilder.DEFAULT_COMPONENT)
-                        .build();
-        TextClassifierImpl textClassifier =
-                new TextClassifierImpl(context, new TextClassificationConstants());
-        TextClassification.Request request =
-                new TextClassification.Request.Builder(japaneseText, 0, japaneseText.length())
-                        .setDefaultLocales(LOCALES)
-                        .build();
-
-        TextClassification classification = textClassifier.classifyText(request);
-        RemoteAction translateAction = classification.getActions().get(0);
-        assertEquals(1, classification.getActions().size());
-        assertEquals(
-                context.getString(com.android.textclassifier.R.string.translate),
-                translateAction.getTitle());
-
-        assertEquals(translateAction, ExtrasUtils.findTranslateAction(classification));
-        Intent intent = ExtrasUtils.getActionsIntents(classification).get(0);
-        assertEquals(Intent.ACTION_TRANSLATE, intent.getAction());
-        Bundle foreignLanguageInfo = ExtrasUtils.getForeignLanguageExtra(classification);
-        assertEquals("ja", ExtrasUtils.getEntityType(foreignLanguageInfo));
-        assertTrue(ExtrasUtils.getScore(foreignLanguageInfo) >= 0);
-        assertTrue(ExtrasUtils.getScore(foreignLanguageInfo) <= 1);
-        assertTrue(intent.hasExtra(TextClassifier.EXTRA_FROM_TEXT_CLASSIFIER));
-        assertEquals("ja", ExtrasUtils.getTopLanguage(intent).getLanguage());
-
-        LocaleList.setDefault(originalLocales);
-    }
-
-    @Test
-    public void testGenerateLinks_phone() {
-        String text = "The number is +12122537077. See you tonight!";
-        TextLinks.Request request = new TextLinks.Request.Builder(text).build();
-        assertThat(
-                mClassifier.generateLinks(request),
-                isTextLinksContaining(text, "+12122537077", TextClassifier.TYPE_PHONE));
-    }
-
-    @Test
-    public void testGenerateLinks_exclude() {
-        String text = "You want apple@banana.com. See you tonight!";
-        List<String> hints = Collections.EMPTY_LIST;
-        List<String> included = Collections.EMPTY_LIST;
-        List<String> excluded = Arrays.asList(TextClassifier.TYPE_EMAIL);
-        TextLinks.Request request =
-                new TextLinks.Request.Builder(text)
-                        .setEntityConfig(
-                                TextClassifier.EntityConfig.create(hints, included, excluded))
-                        .setDefaultLocales(LOCALES)
-                        .build();
-        assertThat(
-                mClassifier.generateLinks(request),
-                not(isTextLinksContaining(text, "apple@banana.com", TextClassifier.TYPE_EMAIL)));
-    }
-
-    @Test
-    public void testGenerateLinks_explicit_address() {
-        String text = "The address is 1600 Amphitheater Parkway, Mountain View, CA. See you!";
-        List<String> explicit = Arrays.asList(TextClassifier.TYPE_ADDRESS);
-        TextLinks.Request request =
-                new TextLinks.Request.Builder(text)
-                        .setEntityConfig(
-                                TextClassifier.EntityConfig.createWithExplicitEntityList(explicit))
-                        .setDefaultLocales(LOCALES)
-                        .build();
-        assertThat(
-                mClassifier.generateLinks(request),
-                isTextLinksContaining(
-                        text,
-                        "1600 Amphitheater Parkway, Mountain View, CA",
-                        TextClassifier.TYPE_ADDRESS));
-    }
-
-    @Test
-    public void testGenerateLinks_exclude_override() {
-        String text = "You want apple@banana.com. See you tonight!";
-        List<String> hints = Collections.EMPTY_LIST;
-        List<String> included = Arrays.asList(TextClassifier.TYPE_EMAIL);
-        List<String> excluded = Arrays.asList(TextClassifier.TYPE_EMAIL);
-        TextLinks.Request request =
-                new TextLinks.Request.Builder(text)
-                        .setEntityConfig(
-                                TextClassifier.EntityConfig.create(hints, included, excluded))
-                        .setDefaultLocales(LOCALES)
-                        .build();
-        assertThat(
-                mClassifier.generateLinks(request),
-                not(isTextLinksContaining(text, "apple@banana.com", TextClassifier.TYPE_EMAIL)));
-    }
-
-    @Test
-    public void testGenerateLinks_maxLength() {
-        char[] manySpaces = new char[mClassifier.getMaxGenerateLinksTextLength()];
-        Arrays.fill(manySpaces, ' ');
-        TextLinks.Request request = new TextLinks.Request.Builder(new String(manySpaces)).build();
-        TextLinks links = mClassifier.generateLinks(request);
-        assertTrue(links.getLinks().isEmpty());
-    }
-
-    @Test
-    public void testApplyLinks_unsupportedCharacter() {
-        Spannable url = new SpannableString("\u202Emoc.diordna.com");
-        TextLinks.Request request = new TextLinks.Request.Builder(url).build();
-        assertEquals(
-                TextLinks.STATUS_UNSUPPORTED_CHARACTER,
-                mClassifier.generateLinks(request).apply(url, 0, null));
-    }
-
-    @Test(expected = IllegalArgumentException.class)
-    public void testGenerateLinks_tooLong() {
-        char[] manySpaces = new char[mClassifier.getMaxGenerateLinksTextLength() + 1];
-        Arrays.fill(manySpaces, ' ');
-        TextLinks.Request request = new TextLinks.Request.Builder(new String(manySpaces)).build();
-        mClassifier.generateLinks(request);
-    }
-
-    @Test
-    public void testGenerateLinks_entityData() {
-        String text = "The number is +12122537077.";
-        Bundle extras = new Bundle();
-        ExtrasUtils.putIsSerializedEntityDataEnabled(extras, true);
-        TextLinks.Request request = new TextLinks.Request.Builder(text).setExtras(extras).build();
-
-        TextLinks textLinks = mClassifier.generateLinks(request);
-
-        Truth.assertThat(textLinks.getLinks()).hasSize(1);
-        TextLinks.TextLink textLink = textLinks.getLinks().iterator().next();
-        List<Bundle> entities = ExtrasUtils.getEntities(textLink.getExtras());
-        Truth.assertThat(entities).hasSize(1);
-        Bundle entity = entities.get(0);
-        Truth.assertThat(ExtrasUtils.getEntityType(entity)).isEqualTo(TextClassifier.TYPE_PHONE);
-    }
-
-    @Test
-    public void testGenerateLinks_entityData_disabled() {
-        String text = "The number is +12122537077.";
-        TextLinks.Request request = new TextLinks.Request.Builder(text).build();
-
-        TextLinks textLinks = mClassifier.generateLinks(request);
-
-        Truth.assertThat(textLinks.getLinks()).hasSize(1);
-        TextLinks.TextLink textLink = textLinks.getLinks().iterator().next();
-        List<Bundle> entities = ExtrasUtils.getEntities(textLink.getExtras());
-        Truth.assertThat(entities).isNull();
-    }
-
-    @Test
-    public void testDetectLanguage() {
-        String text = "This is English text";
-        TextLanguage.Request request = new TextLanguage.Request.Builder(text).build();
-        TextLanguage textLanguage = mClassifier.detectLanguage(request);
-        assertThat(textLanguage, isTextLanguage("en"));
-    }
-
-    @Test
-    public void testDetectLanguage_japanese() {
-        String text = "これは日本語のテキストです";
-        TextLanguage.Request request = new TextLanguage.Request.Builder(text).build();
-        TextLanguage textLanguage = mClassifier.detectLanguage(request);
-        assertThat(textLanguage, isTextLanguage("ja"));
-    }
-
-    @Ignore // Doesn't work without a language-based model.
-    @Test
-    public void testSuggestConversationActions_textReplyOnly_maxOne() {
-        ConversationActions.Message message =
-                new ConversationActions.Message.Builder(
-                                ConversationActions.Message.PERSON_USER_OTHERS)
-                        .setText("Where are you?")
-                        .build();
-        TextClassifier.EntityConfig typeConfig =
-                new TextClassifier.EntityConfig.Builder()
-                        .includeTypesFromTextClassifier(false)
-                        .setIncludedTypes(
-                                Collections.singletonList(ConversationAction.TYPE_TEXT_REPLY))
-                        .build();
-        ConversationActions.Request request =
-                new ConversationActions.Request.Builder(Collections.singletonList(message))
-                        .setMaxSuggestions(1)
-                        .setTypeConfig(typeConfig)
-                        .build();
-
-        ConversationActions conversationActions = mClassifier.suggestConversationActions(request);
-        Truth.assertThat(conversationActions.getConversationActions()).hasSize(1);
-        ConversationAction conversationAction = conversationActions.getConversationActions().get(0);
-        Truth.assertThat(conversationAction.getType())
-                .isEqualTo(ConversationAction.TYPE_TEXT_REPLY);
-        Truth.assertThat(conversationAction.getTextReply()).isNotNull();
-    }
-
-    @Ignore // Doesn't work without a language-based model.
-    @Test
-    public void testSuggestConversationActions_textReplyOnly_noMax() {
-        ConversationActions.Message message =
-                new ConversationActions.Message.Builder(
-                                ConversationActions.Message.PERSON_USER_OTHERS)
-                        .setText("Where are you?")
-                        .build();
-        TextClassifier.EntityConfig typeConfig =
-                new TextClassifier.EntityConfig.Builder()
-                        .includeTypesFromTextClassifier(false)
-                        .setIncludedTypes(
-                                Collections.singletonList(ConversationAction.TYPE_TEXT_REPLY))
-                        .build();
-        ConversationActions.Request request =
-                new ConversationActions.Request.Builder(Collections.singletonList(message))
-                        .setTypeConfig(typeConfig)
-                        .build();
-
-        ConversationActions conversationActions = mClassifier.suggestConversationActions(request);
-        assertTrue(conversationActions.getConversationActions().size() > 1);
-        for (ConversationAction conversationAction : conversationActions.getConversationActions()) {
-            assertThat(
-                    conversationAction, isConversationAction(ConversationAction.TYPE_TEXT_REPLY));
-        }
-    }
-
-    @Test
-    public void testSuggestConversationActions_openUrl() {
-        ConversationActions.Message message =
-                new ConversationActions.Message.Builder(
-                                ConversationActions.Message.PERSON_USER_OTHERS)
-                        .setText("Check this out: https://www.android.com")
-                        .build();
-        TextClassifier.EntityConfig typeConfig =
-                new TextClassifier.EntityConfig.Builder()
-                        .includeTypesFromTextClassifier(false)
-                        .setIncludedTypes(
-                                Collections.singletonList(ConversationAction.TYPE_OPEN_URL))
-                        .build();
-        ConversationActions.Request request =
-                new ConversationActions.Request.Builder(Collections.singletonList(message))
-                        .setMaxSuggestions(1)
-                        .setTypeConfig(typeConfig)
-                        .build();
-
-        ConversationActions conversationActions = mClassifier.suggestConversationActions(request);
-        Truth.assertThat(conversationActions.getConversationActions()).hasSize(1);
-        ConversationAction conversationAction = conversationActions.getConversationActions().get(0);
-        Truth.assertThat(conversationAction.getType()).isEqualTo(ConversationAction.TYPE_OPEN_URL);
-        Intent actionIntent = ExtrasUtils.getActionIntent(conversationAction.getExtras());
-        Truth.assertThat(actionIntent.getAction()).isEqualTo(Intent.ACTION_VIEW);
-        Truth.assertThat(actionIntent.getData()).isEqualTo(Uri.parse("https://www.android.com"));
-    }
-
-    @Ignore // Doesn't work without a language-based model.
-    @Test
-    public void testSuggestConversationActions_copy() {
-        ConversationActions.Message message =
-                new ConversationActions.Message.Builder(
-                                ConversationActions.Message.PERSON_USER_OTHERS)
-                        .setText("Authentication code: 12345")
-                        .build();
-        TextClassifier.EntityConfig typeConfig =
-                new TextClassifier.EntityConfig.Builder()
-                        .includeTypesFromTextClassifier(false)
-                        .setIncludedTypes(Collections.singletonList(ConversationAction.TYPE_COPY))
-                        .build();
-        ConversationActions.Request request =
-                new ConversationActions.Request.Builder(Collections.singletonList(message))
-                        .setMaxSuggestions(1)
-                        .setTypeConfig(typeConfig)
-                        .build();
-
-        ConversationActions conversationActions = mClassifier.suggestConversationActions(request);
-        Truth.assertThat(conversationActions.getConversationActions()).hasSize(1);
-        ConversationAction conversationAction = conversationActions.getConversationActions().get(0);
-        Truth.assertThat(conversationAction.getType()).isEqualTo(ConversationAction.TYPE_COPY);
-        Truth.assertThat(conversationAction.getTextReply()).isAnyOf(null, "");
-        Truth.assertThat(conversationAction.getAction()).isNull();
-        String code = ExtrasUtils.getCopyText(conversationAction.getExtras());
-        Truth.assertThat(code).isEqualTo("12345");
-        Truth.assertThat(ExtrasUtils.getSerializedEntityData(conversationAction.getExtras()))
-                .isNotEmpty();
-    }
-
-    @Test
-    public void testSuggetsConversationActions_deduplicate() {
-        ConversationActions.Message message =
-                new ConversationActions.Message.Builder(
-                                ConversationActions.Message.PERSON_USER_OTHERS)
-                        .setText("a@android.com b@android.com")
-                        .build();
-        ConversationActions.Request request =
-                new ConversationActions.Request.Builder(Collections.singletonList(message))
-                        .setMaxSuggestions(3)
-                        .build();
-
-        ConversationActions conversationActions = mClassifier.suggestConversationActions(request);
-
-        Truth.assertThat(conversationActions.getConversationActions()).isEmpty();
-    }
-
-    private static Matcher<TextSelection> isTextSelection(
-            final int startIndex, final int endIndex, final String type) {
-        return new BaseMatcher<TextSelection>() {
-            @Override
-            public boolean matches(Object o) {
-                if (o instanceof TextSelection) {
-                    TextSelection selection = (TextSelection) o;
-                    return startIndex == selection.getSelectionStartIndex()
-                            && endIndex == selection.getSelectionEndIndex()
-                            && typeMatches(selection, type);
-                }
-                return false;
-            }
-
-            private boolean typeMatches(TextSelection selection, String type) {
-                return type == null
-                        || (selection.getEntityCount() > 0
-                                && type.trim().equalsIgnoreCase(selection.getEntity(0)));
-            }
-
-            @Override
-            public void describeTo(Description description) {
-                description.appendValue(String.format("%d, %d, %s", startIndex, endIndex, type));
-            }
-        };
-    }
-
-    private static Matcher<TextLinks> isTextLinksContaining(
-            final String text, final String substring, final String type) {
-        return new BaseMatcher<TextLinks>() {
-
-            @Override
-            public void describeTo(Description description) {
-                description
-                        .appendText("text=")
-                        .appendValue(text)
-                        .appendText(", substring=")
-                        .appendValue(substring)
-                        .appendText(", type=")
-                        .appendValue(type);
-            }
-
-            @Override
-            public boolean matches(Object o) {
-                if (o instanceof TextLinks) {
-                    for (TextLinks.TextLink link : ((TextLinks) o).getLinks()) {
-                        if (text.subSequence(link.getStart(), link.getEnd()).equals(substring)) {
-                            return type.equals(link.getEntity(0));
-                        }
-                    }
-                }
-                return false;
-            }
-        };
-    }
-
-    private static Matcher<TextClassification> isTextClassification(
-            final String text, final String type) {
-        return new BaseMatcher<TextClassification>() {
-            @Override
-            public boolean matches(Object o) {
-                if (o instanceof TextClassification) {
-                    TextClassification result = (TextClassification) o;
-                    return text.equals(result.getText())
-                            && result.getEntityCount() > 0
-                            && type.equals(result.getEntity(0));
-                }
-                return false;
-            }
-
-            @Override
-            public void describeTo(Description description) {
-                description
-                        .appendText("text=")
-                        .appendValue(text)
-                        .appendText(", type=")
-                        .appendValue(type);
-            }
-        };
-    }
-
-    private static Matcher<TextClassification> containsIntentWithAction(final String action) {
-        return new BaseMatcher<TextClassification>() {
-            @Override
-            public boolean matches(Object o) {
-                if (o instanceof TextClassification) {
-                    TextClassification result = (TextClassification) o;
-                    return ExtrasUtils.findAction(result, action) != null;
-                }
-                return false;
-            }
-
-            @Override
-            public void describeTo(Description description) {
-                description.appendText("intent action=").appendValue(action);
-            }
-        };
-    }
-
-    private static Matcher<TextLanguage> isTextLanguage(final String languageTag) {
-        return new BaseMatcher<TextLanguage>() {
-            @Override
-            public boolean matches(Object o) {
-                if (o instanceof TextLanguage) {
-                    TextLanguage result = (TextLanguage) o;
-                    return result.getLocaleHypothesisCount() > 0
-                            && languageTag.equals(result.getLocale(0).toLanguageTag());
-                }
-                return false;
-            }
-
-            @Override
-            public void describeTo(Description description) {
-                description.appendText("locale=").appendValue(languageTag);
-            }
-        };
-    }
-
-    private static Matcher<ConversationAction> isConversationAction(String actionType) {
-        return new BaseMatcher<ConversationAction>() {
-            @Override
-            public boolean matches(Object o) {
-                if (!(o instanceof ConversationAction)) {
-                    return false;
-                }
-                ConversationAction conversationAction = (ConversationAction) o;
-                if (!actionType.equals(conversationAction.getType())) {
-                    return false;
-                }
-                if (ConversationAction.TYPE_TEXT_REPLY.equals(actionType)) {
-                    if (conversationAction.getTextReply() == null) {
-                        return false;
-                    }
-                }
-                if (conversationAction.getConfidenceScore() < 0
-                        || conversationAction.getConfidenceScore() > 1) {
-                    return false;
-                }
-                return true;
-            }
-
-            @Override
-            public void describeTo(Description description) {
-                description.appendText("actionType=").appendValue(actionType);
-            }
-        };
-    }
-}
diff --git a/java/tests/unittests/src/com/android/textclassifier/intent/LabeledIntentTest.java b/java/tests/unittests/src/com/android/textclassifier/intent/LabeledIntentTest.java
deleted file mode 100644
index 98ece06..0000000
--- a/java/tests/unittests/src/com/android/textclassifier/intent/LabeledIntentTest.java
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
- * Copyright (C) 2019 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.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * 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.
- */
-
-package com.android.textclassifier.intent;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.testng.Assert.assertThrows;
-
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.net.Uri;
-import android.os.Bundle;
-import android.view.textclassifier.TextClassifier;
-
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import com.android.textclassifier.FakeContextBuilder;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public final class LabeledIntentTest {
-    private static final String TITLE_WITHOUT_ENTITY = "Map";
-    private static final String TITLE_WITH_ENTITY = "Map NW14D1";
-    private static final String DESCRIPTION = "Check the map";
-    private static final String DESCRIPTION_WITH_APP_NAME = "Use %1$s to open map";
-    private static final Intent INTENT =
-            new Intent(Intent.ACTION_VIEW).setDataAndNormalize(Uri.parse("http://www.android.com"));
-    private static final int REQUEST_CODE = 42;
-    private static final Bundle TEXT_LANGUAGES_BUNDLE = Bundle.EMPTY;
-    private static final String APP_LABEL = "fake";
-
-    private Context mContext;
-
-    @Before
-    public void setup() {
-        final ComponentName component = FakeContextBuilder.DEFAULT_COMPONENT;
-        mContext =
-                new FakeContextBuilder()
-                        .setIntentComponent(Intent.ACTION_VIEW, component)
-                        .setAppLabel(component.getPackageName(), APP_LABEL)
-                        .build();
-    }
-
-    @Test
-    public void resolve_preferTitleWithEntity() {
-        LabeledIntent labeledIntent =
-                new LabeledIntent(
-                        TITLE_WITHOUT_ENTITY,
-                        TITLE_WITH_ENTITY,
-                        DESCRIPTION,
-                        null,
-                        INTENT,
-                        REQUEST_CODE);
-
-        LabeledIntent.Result result =
-                labeledIntent.resolve(mContext, /*titleChooser*/ null, TEXT_LANGUAGES_BUNDLE);
-
-        assertThat(result).isNotNull();
-        assertThat(result.remoteAction.getTitle()).isEqualTo(TITLE_WITH_ENTITY);
-        assertThat(result.remoteAction.getContentDescription()).isEqualTo(DESCRIPTION);
-        Intent intent = result.resolvedIntent;
-        assertThat(intent.getAction()).isEqualTo(intent.getAction());
-        assertThat(intent.getComponent()).isNotNull();
-        assertThat(intent.hasExtra(TextClassifier.EXTRA_FROM_TEXT_CLASSIFIER)).isTrue();
-    }
-
-    @Test
-    public void resolve_useAvailableTitle() {
-        LabeledIntent labeledIntent =
-                new LabeledIntent(
-                        TITLE_WITHOUT_ENTITY, null, DESCRIPTION, null, INTENT, REQUEST_CODE);
-
-        LabeledIntent.Result result =
-                labeledIntent.resolve(mContext, /*titleChooser*/ null, TEXT_LANGUAGES_BUNDLE);
-
-        assertThat(result).isNotNull();
-        assertThat(result.remoteAction.getTitle()).isEqualTo(TITLE_WITHOUT_ENTITY);
-        assertThat(result.remoteAction.getContentDescription()).isEqualTo(DESCRIPTION);
-        Intent intent = result.resolvedIntent;
-        assertThat(intent.getAction()).isEqualTo(intent.getAction());
-        assertThat(intent.getComponent()).isNotNull();
-    }
-
-    @Test
-    public void resolve_titleChooser() {
-        LabeledIntent labeledIntent =
-                new LabeledIntent(
-                        TITLE_WITHOUT_ENTITY, null, DESCRIPTION, null, INTENT, REQUEST_CODE);
-
-        LabeledIntent.Result result =
-                labeledIntent.resolve(
-                        mContext,
-                        (labeledIntent1, resolveInfo) -> "chooser",
-                        TEXT_LANGUAGES_BUNDLE);
-
-        assertThat(result).isNotNull();
-        assertThat(result.remoteAction.getTitle()).isEqualTo("chooser");
-        assertThat(result.remoteAction.getContentDescription()).isEqualTo(DESCRIPTION);
-        Intent intent = result.resolvedIntent;
-        assertThat(intent.getAction()).isEqualTo(intent.getAction());
-        assertThat(intent.getComponent()).isNotNull();
-    }
-
-    @Test
-    public void resolve_titleChooserReturnsNull() {
-        LabeledIntent labeledIntent =
-                new LabeledIntent(
-                        TITLE_WITHOUT_ENTITY, null, DESCRIPTION, null, INTENT, REQUEST_CODE);
-
-        LabeledIntent.Result result =
-                labeledIntent.resolve(
-                        mContext, (labeledIntent1, resolveInfo) -> null, TEXT_LANGUAGES_BUNDLE);
-
-        assertThat(result).isNotNull();
-        assertThat(result.remoteAction.getTitle()).isEqualTo(TITLE_WITHOUT_ENTITY);
-        assertThat(result.remoteAction.getContentDescription()).isEqualTo(DESCRIPTION);
-        Intent intent = result.resolvedIntent;
-        assertThat(intent.getAction()).isEqualTo(intent.getAction());
-        assertThat(intent.getComponent()).isNotNull();
-    }
-
-    @Test
-    public void resolve_missingTitle() {
-        assertThrows(
-                IllegalArgumentException.class,
-                () -> new LabeledIntent(null, null, DESCRIPTION, null, INTENT, REQUEST_CODE));
-    }
-
-    @Test
-    public void resolve_noIntentHandler() {
-        // See setup(). mContext can only resolve Intent.ACTION_VIEW.
-        Intent unresolvableIntent = new Intent(Intent.ACTION_TRANSLATE);
-        LabeledIntent labeledIntent =
-                new LabeledIntent(
-                        TITLE_WITHOUT_ENTITY,
-                        null,
-                        DESCRIPTION,
-                        null,
-                        unresolvableIntent,
-                        REQUEST_CODE);
-
-        LabeledIntent.Result result = labeledIntent.resolve(mContext, null, null);
-
-        assertThat(result).isNull();
-    }
-
-    @Test
-    public void resolve_descriptionWithAppName() {
-        LabeledIntent labeledIntent =
-                new LabeledIntent(
-                        TITLE_WITHOUT_ENTITY,
-                        TITLE_WITH_ENTITY,
-                        DESCRIPTION,
-                        DESCRIPTION_WITH_APP_NAME,
-                        INTENT,
-                        REQUEST_CODE);
-
-        LabeledIntent.Result result =
-                labeledIntent.resolve(mContext, /*titleChooser*/ null, TEXT_LANGUAGES_BUNDLE);
-
-        assertThat(result).isNotNull();
-        assertThat(result.remoteAction.getContentDescription()).isEqualTo("Use fake to open map");
-    }
-}
diff --git a/java/tests/unittests/src/com/android/textclassifier/intent/LegacyIntentClassificationFactoryTest.java b/java/tests/unittests/src/com/android/textclassifier/intent/LegacyIntentClassificationFactoryTest.java
deleted file mode 100644
index 6ae9e5a..0000000
--- a/java/tests/unittests/src/com/android/textclassifier/intent/LegacyIntentClassificationFactoryTest.java
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Copyright (C) 2019 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.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * 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
- */
-
-package com.android.textclassifier.intent;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.content.Intent;
-import android.view.textclassifier.TextClassifier;
-
-import androidx.test.InstrumentationRegistry;
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import com.google.android.textclassifier.AnnotatorModel;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.List;
-
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public class LegacyIntentClassificationFactoryTest {
-
-    private static final String TEXT = "text";
-
-    private LegacyClassificationIntentFactory mLegacyIntentClassificationFactory;
-
-    @Before
-    public void setup() {
-        mLegacyIntentClassificationFactory = new LegacyClassificationIntentFactory();
-    }
-
-    @Test
-    public void create_typeDictionary() {
-        AnnotatorModel.ClassificationResult classificationResult =
-                new AnnotatorModel.ClassificationResult(
-                        TextClassifier.TYPE_DICTIONARY,
-                        1.0f,
-                        null,
-                        null,
-                        null,
-                        null,
-                        null,
-                        null,
-                        null,
-                        null,
-                        null,
-                        null,
-                        null,
-                        null,
-                        null,
-                        null,
-                        0L,
-                        0L,
-                        0d);
-
-        List<LabeledIntent> intents =
-                mLegacyIntentClassificationFactory.create(
-                        InstrumentationRegistry.getTargetContext(),
-                        TEXT,
-                        /* foreignText */ false,
-                        null,
-                        classificationResult);
-
-        assertThat(intents).hasSize(1);
-        LabeledIntent labeledIntent = intents.get(0);
-        Intent intent = labeledIntent.intent;
-        assertThat(intent.getAction()).isEqualTo(Intent.ACTION_DEFINE);
-        assertThat(intent.getStringExtra(Intent.EXTRA_TEXT)).isEqualTo(TEXT);
-    }
-
-    @Test
-    public void create_translateAndDictionary() {
-        AnnotatorModel.ClassificationResult classificationResult =
-                new AnnotatorModel.ClassificationResult(
-                        TextClassifier.TYPE_DICTIONARY,
-                        1.0f,
-                        null,
-                        null,
-                        null,
-                        null,
-                        null,
-                        null,
-                        null,
-                        null,
-                        null,
-                        null,
-                        null,
-                        null,
-                        null,
-                        null,
-                        0L,
-                        0L,
-                        0d);
-
-        List<LabeledIntent> intents =
-                mLegacyIntentClassificationFactory.create(
-                        InstrumentationRegistry.getTargetContext(),
-                        TEXT,
-                        /* foreignText */ true,
-                        null,
-                        classificationResult);
-
-        assertThat(intents).hasSize(2);
-        assertThat(intents.get(0).intent.getAction()).isEqualTo(Intent.ACTION_DEFINE);
-        assertThat(intents.get(1).intent.getAction()).isEqualTo(Intent.ACTION_TRANSLATE);
-    }
-}
diff --git a/java/tests/unittests/src/com/android/textclassifier/intent/TemplateClassificationIntentFactoryTest.java b/java/tests/unittests/src/com/android/textclassifier/intent/TemplateClassificationIntentFactoryTest.java
deleted file mode 100644
index 32840d0..0000000
--- a/java/tests/unittests/src/com/android/textclassifier/intent/TemplateClassificationIntentFactoryTest.java
+++ /dev/null
@@ -1,245 +0,0 @@
-/*
- * Copyright (C) 2019 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.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * 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
- */
-
-package com.android.textclassifier.intent;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.ArgumentMatchers.same;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-
-import android.content.Context;
-import android.content.Intent;
-import android.view.textclassifier.TextClassifier;
-
-import androidx.test.InstrumentationRegistry;
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import com.google.android.textclassifier.AnnotatorModel;
-import com.google.android.textclassifier.RemoteActionTemplate;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import java.util.List;
-
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public class TemplateClassificationIntentFactoryTest {
-
-    private static final String TEXT = "text";
-    private static final String TITLE_WITHOUT_ENTITY = "Map";
-    private static final String DESCRIPTION = "Opens in Maps";
-    private static final String DESCRIPTION_WITH_APP_NAME = "Use %1$s to open Map";
-    private static final String ACTION = Intent.ACTION_VIEW;
-
-    @Mock private ClassificationIntentFactory mFallback;
-    private TemplateClassificationIntentFactory mTemplateClassificationIntentFactory;
-
-    @Before
-    public void setup() {
-        MockitoAnnotations.initMocks(this);
-        mTemplateClassificationIntentFactory =
-                new TemplateClassificationIntentFactory(new TemplateIntentFactory(), mFallback);
-    }
-
-    @Test
-    public void create_foreignText() {
-        AnnotatorModel.ClassificationResult classificationResult =
-                new AnnotatorModel.ClassificationResult(
-                        TextClassifier.TYPE_ADDRESS,
-                        1.0f,
-                        null,
-                        null,
-                        null,
-                        null,
-                        null,
-                        null,
-                        null,
-                        null,
-                        null,
-                        null,
-                        null,
-                        null,
-                        null,
-                        createRemoteActionTemplates(),
-                        0L,
-                        0L,
-                        0d);
-
-        List<LabeledIntent> intents =
-                mTemplateClassificationIntentFactory.create(
-                        InstrumentationRegistry.getTargetContext(),
-                        TEXT,
-                        /* foreignText */ true,
-                        null,
-                        classificationResult);
-
-        assertThat(intents).hasSize(2);
-        LabeledIntent labeledIntent = intents.get(0);
-        assertThat(labeledIntent.titleWithoutEntity).isEqualTo(TITLE_WITHOUT_ENTITY);
-        Intent intent = labeledIntent.intent;
-        assertThat(intent.getAction()).isEqualTo(ACTION);
-
-        labeledIntent = intents.get(1);
-        intent = labeledIntent.intent;
-        assertThat(intent.getAction()).isEqualTo(Intent.ACTION_TRANSLATE);
-    }
-
-    @Test
-    public void create_notForeignText() {
-        AnnotatorModel.ClassificationResult classificationResult =
-                new AnnotatorModel.ClassificationResult(
-                        TextClassifier.TYPE_ADDRESS,
-                        1.0f,
-                        null,
-                        null,
-                        null,
-                        null,
-                        null,
-                        null,
-                        null,
-                        null,
-                        null,
-                        null,
-                        null,
-                        null,
-                        null,
-                        createRemoteActionTemplates(),
-                        0L,
-                        0L,
-                        0d);
-
-        List<LabeledIntent> intents =
-                mTemplateClassificationIntentFactory.create(
-                        InstrumentationRegistry.getContext(),
-                        TEXT,
-                        /* foreignText */ false,
-                        null,
-                        classificationResult);
-
-        assertThat(intents).hasSize(1);
-        LabeledIntent labeledIntent = intents.get(0);
-        assertThat(labeledIntent.titleWithoutEntity).isEqualTo(TITLE_WITHOUT_ENTITY);
-        Intent intent = labeledIntent.intent;
-        assertThat(intent.getAction()).isEqualTo(ACTION);
-    }
-
-    @Test
-    public void create_nullTemplate() {
-        AnnotatorModel.ClassificationResult classificationResult =
-                new AnnotatorModel.ClassificationResult(
-                        TextClassifier.TYPE_ADDRESS,
-                        1.0f,
-                        null,
-                        null,
-                        null,
-                        null,
-                        null,
-                        null,
-                        null,
-                        null,
-                        null,
-                        null,
-                        null,
-                        null,
-                        null,
-                        null,
-                        0L,
-                        0L,
-                        0d);
-
-        mTemplateClassificationIntentFactory.create(
-                InstrumentationRegistry.getContext(),
-                TEXT,
-                /* foreignText */ false,
-                null,
-                classificationResult);
-
-        verify(mFallback)
-                .create(
-                        same(InstrumentationRegistry.getContext()),
-                        eq(TEXT),
-                        eq(false),
-                        eq(null),
-                        same(classificationResult));
-    }
-
-    @Test
-    public void create_emptyResult() {
-        AnnotatorModel.ClassificationResult classificationResult =
-                new AnnotatorModel.ClassificationResult(
-                        TextClassifier.TYPE_ADDRESS,
-                        1.0f,
-                        null,
-                        null,
-                        null,
-                        null,
-                        null,
-                        null,
-                        null,
-                        null,
-                        null,
-                        null,
-                        null,
-                        null,
-                        null,
-                        new RemoteActionTemplate[0],
-                        0L,
-                        0L,
-                        0d);
-
-        mTemplateClassificationIntentFactory.create(
-                InstrumentationRegistry.getContext(),
-                TEXT,
-                /* foreignText */ false,
-                null,
-                classificationResult);
-
-        verify(mFallback, never())
-                .create(
-                        any(Context.class),
-                        eq(TEXT),
-                        eq(false),
-                        eq(null),
-                        any(AnnotatorModel.ClassificationResult.class));
-    }
-
-    private static RemoteActionTemplate[] createRemoteActionTemplates() {
-        return new RemoteActionTemplate[] {
-            new RemoteActionTemplate(
-                    TITLE_WITHOUT_ENTITY,
-                    null,
-                    DESCRIPTION,
-                    DESCRIPTION_WITH_APP_NAME,
-                    ACTION,
-                    null,
-                    null,
-                    null,
-                    null,
-                    null,
-                    null,
-                    null)
-        };
-    }
-}
diff --git a/java/tests/unittests/src/com/android/textclassifier/intent/TemplateIntentFactoryTest.java b/java/tests/unittests/src/com/android/textclassifier/intent/TemplateIntentFactoryTest.java
deleted file mode 100644
index ed12784..0000000
--- a/java/tests/unittests/src/com/android/textclassifier/intent/TemplateIntentFactoryTest.java
+++ /dev/null
@@ -1,269 +0,0 @@
-/*
- * Copyright (C) 2019 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.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * 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
- */
-package com.android.textclassifier.intent;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.content.Intent;
-import android.net.Uri;
-
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import com.google.android.textclassifier.NamedVariant;
-import com.google.android.textclassifier.RemoteActionTemplate;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.MockitoAnnotations;
-
-import java.util.List;
-
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public class TemplateIntentFactoryTest {
-
-    private static final String TEXT = "text";
-    private static final String TITLE_WITHOUT_ENTITY = "Map";
-    private static final String TITLE_WITH_ENTITY = "Map NW14D1";
-    private static final String DESCRIPTION = "Check the map";
-    private static final String DESCRIPTION_WITH_APP_NAME = "Use %1$s to open map";
-    private static final String ACTION = Intent.ACTION_VIEW;
-    private static final String DATA = Uri.parse("http://www.android.com").toString();
-    private static final String TYPE = "text/html";
-    private static final Integer FLAG = Intent.FLAG_ACTIVITY_NEW_TASK;
-    private static final String[] CATEGORY =
-            new String[] {Intent.CATEGORY_DEFAULT, Intent.CATEGORY_APP_BROWSER};
-    private static final String PACKAGE_NAME = "pkg.name";
-    private static final String KEY_ONE = "key1";
-    private static final String VALUE_ONE = "value1";
-    private static final String KEY_TWO = "key2";
-    private static final int VALUE_TWO = 42;
-
-    private static final NamedVariant[] NAMED_VARIANTS =
-            new NamedVariant[] {
-                new NamedVariant(KEY_ONE, VALUE_ONE), new NamedVariant(KEY_TWO, VALUE_TWO)
-            };
-    private static final Integer REQUEST_CODE = 10;
-
-    private TemplateIntentFactory mTemplateIntentFactory;
-
-    @Before
-    public void setup() {
-        MockitoAnnotations.initMocks(this);
-        mTemplateIntentFactory = new TemplateIntentFactory();
-    }
-
-    @Test
-    public void create_full() {
-        RemoteActionTemplate remoteActionTemplate =
-                new RemoteActionTemplate(
-                        TITLE_WITHOUT_ENTITY,
-                        TITLE_WITH_ENTITY,
-                        DESCRIPTION,
-                        DESCRIPTION_WITH_APP_NAME,
-                        ACTION,
-                        DATA,
-                        TYPE,
-                        FLAG,
-                        CATEGORY,
-                        /* packageName */ null,
-                        NAMED_VARIANTS,
-                        REQUEST_CODE);
-
-        List<LabeledIntent> intents =
-                mTemplateIntentFactory.create(new RemoteActionTemplate[] {remoteActionTemplate});
-
-        assertThat(intents).hasSize(1);
-        LabeledIntent labeledIntent = intents.get(0);
-        assertThat(labeledIntent.titleWithoutEntity).isEqualTo(TITLE_WITHOUT_ENTITY);
-        assertThat(labeledIntent.titleWithEntity).isEqualTo(TITLE_WITH_ENTITY);
-        assertThat(labeledIntent.description).isEqualTo(DESCRIPTION);
-        assertThat(labeledIntent.descriptionWithAppName).isEqualTo(DESCRIPTION_WITH_APP_NAME);
-        assertThat(labeledIntent.requestCode).isEqualTo(REQUEST_CODE);
-        Intent intent = labeledIntent.intent;
-        assertThat(intent.getAction()).isEqualTo(ACTION);
-        assertThat(intent.getData().toString()).isEqualTo(DATA);
-        assertThat(intent.getType()).isEqualTo(TYPE);
-        assertThat(intent.getFlags()).isEqualTo(FLAG);
-        assertThat(intent.getCategories()).containsExactly((Object[]) CATEGORY);
-        assertThat(intent.getPackage()).isNull();
-        assertThat(intent.getStringExtra(KEY_ONE)).isEqualTo(VALUE_ONE);
-        assertThat(intent.getIntExtra(KEY_TWO, 0)).isEqualTo(VALUE_TWO);
-    }
-
-    @Test
-    public void normalizesScheme() {
-        RemoteActionTemplate remoteActionTemplate =
-                new RemoteActionTemplate(
-                        TITLE_WITHOUT_ENTITY,
-                        TITLE_WITH_ENTITY,
-                        DESCRIPTION,
-                        DESCRIPTION_WITH_APP_NAME,
-                        ACTION,
-                        "HTTp://www.android.com",
-                        TYPE,
-                        FLAG,
-                        CATEGORY,
-                        /* packageName */ null,
-                        NAMED_VARIANTS,
-                        REQUEST_CODE);
-
-        List<LabeledIntent> intents =
-                mTemplateIntentFactory.create(new RemoteActionTemplate[] {remoteActionTemplate});
-
-        String data = intents.get(0).intent.getData().toString();
-        assertThat(data).isEqualTo("http://www.android.com");
-    }
-
-    @Test
-    public void create_minimal() {
-        RemoteActionTemplate remoteActionTemplate =
-                new RemoteActionTemplate(
-                        TITLE_WITHOUT_ENTITY,
-                        null,
-                        DESCRIPTION,
-                        null,
-                        ACTION,
-                        null,
-                        null,
-                        null,
-                        null,
-                        null,
-                        null,
-                        null);
-
-        List<LabeledIntent> intents =
-                mTemplateIntentFactory.create(new RemoteActionTemplate[] {remoteActionTemplate});
-
-        assertThat(intents).hasSize(1);
-        LabeledIntent labeledIntent = intents.get(0);
-        assertThat(labeledIntent.titleWithoutEntity).isEqualTo(TITLE_WITHOUT_ENTITY);
-        assertThat(labeledIntent.titleWithEntity).isNull();
-        assertThat(labeledIntent.description).isEqualTo(DESCRIPTION);
-        assertThat(labeledIntent.requestCode).isEqualTo(LabeledIntent.DEFAULT_REQUEST_CODE);
-        Intent intent = labeledIntent.intent;
-        assertThat(intent.getAction()).isEqualTo(ACTION);
-        assertThat(intent.getData()).isNull();
-        assertThat(intent.getType()).isNull();
-        assertThat(intent.getFlags()).isEqualTo(0);
-        assertThat(intent.getCategories()).isNull();
-        assertThat(intent.getPackage()).isNull();
-    }
-
-    @Test
-    public void invalidTemplate_nullTemplate() {
-        RemoteActionTemplate remoteActionTemplate = null;
-
-        List<LabeledIntent> intents =
-                mTemplateIntentFactory.create(new RemoteActionTemplate[] {remoteActionTemplate});
-
-        assertThat(intents).isEmpty();
-    }
-
-    @Test
-    public void invalidTemplate_nonEmptyPackageName() {
-        RemoteActionTemplate remoteActionTemplate =
-                new RemoteActionTemplate(
-                        TITLE_WITHOUT_ENTITY,
-                        TITLE_WITH_ENTITY,
-                        DESCRIPTION,
-                        DESCRIPTION_WITH_APP_NAME,
-                        ACTION,
-                        DATA,
-                        TYPE,
-                        FLAG,
-                        CATEGORY,
-                        PACKAGE_NAME,
-                        NAMED_VARIANTS,
-                        REQUEST_CODE);
-
-        List<LabeledIntent> intents =
-                mTemplateIntentFactory.create(new RemoteActionTemplate[] {remoteActionTemplate});
-
-        assertThat(intents).isEmpty();
-    }
-
-    @Test
-    public void invalidTemplate_emptyTitle() {
-        RemoteActionTemplate remoteActionTemplate =
-                new RemoteActionTemplate(
-                        null,
-                        null,
-                        DESCRIPTION,
-                        DESCRIPTION_WITH_APP_NAME,
-                        ACTION,
-                        null,
-                        null,
-                        null,
-                        null,
-                        null,
-                        null,
-                        null);
-
-        List<LabeledIntent> intents =
-                mTemplateIntentFactory.create(new RemoteActionTemplate[] {remoteActionTemplate});
-
-        assertThat(intents).isEmpty();
-    }
-
-    @Test
-    public void invalidTemplate_emptyDescription() {
-        RemoteActionTemplate remoteActionTemplate =
-                new RemoteActionTemplate(
-                        TITLE_WITHOUT_ENTITY,
-                        TITLE_WITH_ENTITY,
-                        null,
-                        null,
-                        ACTION,
-                        null,
-                        null,
-                        null,
-                        null,
-                        null,
-                        null,
-                        null);
-
-        List<LabeledIntent> intents =
-                mTemplateIntentFactory.create(new RemoteActionTemplate[] {remoteActionTemplate});
-
-        assertThat(intents).isEmpty();
-    }
-
-    @Test
-    public void invalidTemplate_emptyIntentAction() {
-        RemoteActionTemplate remoteActionTemplate =
-                new RemoteActionTemplate(
-                        TITLE_WITHOUT_ENTITY,
-                        TITLE_WITH_ENTITY,
-                        DESCRIPTION,
-                        DESCRIPTION_WITH_APP_NAME,
-                        null,
-                        null,
-                        null,
-                        null,
-                        null,
-                        null,
-                        null,
-                        null);
-
-        List<LabeledIntent> intents =
-                mTemplateIntentFactory.create(new RemoteActionTemplate[] {remoteActionTemplate});
-
-        assertThat(intents).isEmpty();
-    }
-}
diff --git a/java/tests/unittests/src/com/android/textclassifier/logging/ResultIdUtilsTest.java b/java/tests/unittests/src/com/android/textclassifier/logging/ResultIdUtilsTest.java
deleted file mode 100644
index 3ec07bc..0000000
--- a/java/tests/unittests/src/com/android/textclassifier/logging/ResultIdUtilsTest.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2019 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.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * 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.
- */
-
-package com.android.textclassifier.logging;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import androidx.test.core.app.ApplicationProvider;
-import androidx.test.filters.SmallTest;
-
-import org.junit.Test;
-
-import java.util.Collections;
-import java.util.Locale;
-
-@SmallTest
-public class ResultIdUtilsTest {
-    private static final int MODEL_VERSION = 703;
-    private static final int HASH = 12345;
-
-    @Test
-    public void createId_customHash() {
-        String resultId =
-                ResultIdUtils.createId(
-                        MODEL_VERSION, Collections.singletonList(Locale.ENGLISH), HASH);
-
-        assertThat(resultId).isEqualTo("androidtc|en_v703|12345");
-    }
-
-    @Test
-    public void createId_selection() {
-        String resultId =
-                ResultIdUtils.createId(
-                        ApplicationProvider.getApplicationContext(),
-                        "text",
-                        1,
-                        2,
-                        MODEL_VERSION,
-                        Collections.singletonList(Locale.ENGLISH));
-
-        assertThat(resultId).matches("androidtc\\|en_v703\\|-?\\d+");
-    }
-}
diff --git a/java/tests/unittests/src/com/android/textclassifier/logging/SelectionEventConverterTest.java b/java/tests/unittests/src/com/android/textclassifier/logging/SelectionEventConverterTest.java
deleted file mode 100644
index 2760145..0000000
--- a/java/tests/unittests/src/com/android/textclassifier/logging/SelectionEventConverterTest.java
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- * Copyright (C) 2019 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.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * 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.
- */
-
-package com.android.textclassifier.logging;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.view.textclassifier.SelectionEvent;
-import android.view.textclassifier.TextClassification;
-import android.view.textclassifier.TextClassificationContext;
-import android.view.textclassifier.TextClassificationManager;
-import android.view.textclassifier.TextClassifier;
-import android.view.textclassifier.TextClassifierEvent;
-import android.view.textclassifier.TextSelection;
-
-import androidx.test.core.app.ApplicationProvider;
-import androidx.test.filters.SmallTest;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import java.util.ArrayDeque;
-import java.util.Collections;
-import java.util.Deque;
-import java.util.Locale;
-
-@SmallTest
-public class SelectionEventConverterTest {
-    private static final String TEXT = "Some text here and there";
-    private static final String PKG_NAME = "com.pkg";
-    private static final String WIDGET_TYPE = TextClassifier.WIDGET_TYPE_EDITTEXT;
-    private static final int START = 2;
-    private static final int SMART_START = 1;
-    private static final int SMART_END = 3;
-    private TestTextClassifier mTestTextClassifier;
-    private TextClassifier mSession;
-
-    @Before
-    public void setup() {
-        TextClassificationManager textClassificationManager =
-                ApplicationProvider.getApplicationContext()
-                        .getSystemService(TextClassificationManager.class);
-        mTestTextClassifier = new TestTextClassifier();
-        textClassificationManager.setTextClassifier(mTestTextClassifier);
-        mSession = textClassificationManager.createTextClassificationSession(createEventContext());
-    }
-
-    @Test
-    public void convert_started() {
-        mSession.onSelectionEvent(
-                SelectionEvent.createSelectionStartedEvent(
-                        SelectionEvent.INVOCATION_MANUAL, START));
-
-        SelectionEvent interceptedEvent = mTestTextClassifier.popLastSelectionEvent();
-        TextClassifierEvent textClassifierEvent =
-                SelectionEventConverter.toTextClassifierEvent(interceptedEvent);
-
-        assertEventContext(textClassifierEvent.getEventContext());
-        assertThat(textClassifierEvent.getEventIndex()).isEqualTo(0);
-        assertThat(textClassifierEvent.getEventType())
-                .isEqualTo(TextClassifierEvent.TYPE_SELECTION_STARTED);
-    }
-
-    @Test
-    public void convert_smartSelection() {
-        mSession.onSelectionEvent(
-                SelectionEvent.createSelectionStartedEvent(
-                        SelectionEvent.INVOCATION_MANUAL, START));
-        String resultId =
-                ResultIdUtils.createId(
-                        702, Collections.singletonList(Locale.ENGLISH), /*hash=*/ 12345);
-        mSession.onSelectionEvent(
-                SelectionEvent.createSelectionActionEvent(
-                        SMART_START,
-                        SMART_END,
-                        SelectionEvent.ACTION_SMART_SHARE,
-                        new TextClassification.Builder()
-                                .setEntityType(TextClassifier.TYPE_ADDRESS, 1.0f)
-                                .setId(resultId)
-                                .build()));
-
-        SelectionEvent interceptedEvent = mTestTextClassifier.popLastSelectionEvent();
-        TextClassifierEvent.TextSelectionEvent textSelectionEvent =
-                (TextClassifierEvent.TextSelectionEvent)
-                        SelectionEventConverter.toTextClassifierEvent(interceptedEvent);
-
-        assertEventContext(textSelectionEvent.getEventContext());
-        assertThat(textSelectionEvent.getRelativeWordStartIndex()).isEqualTo(-1);
-        assertThat(textSelectionEvent.getRelativeWordEndIndex()).isEqualTo(1);
-        assertThat(textSelectionEvent.getEventType())
-                .isEqualTo(TextClassifierEvent.TYPE_SMART_ACTION);
-        assertThat(textSelectionEvent.getEventIndex()).isEqualTo(1);
-        assertThat(textSelectionEvent.getEntityTypes())
-                .asList()
-                .containsExactly(TextClassifier.TYPE_ADDRESS);
-        assertThat(textSelectionEvent.getResultId()).isEqualTo(resultId);
-    }
-
-    @Test
-    public void convert_smartShare() {
-        mSession.onSelectionEvent(
-                SelectionEvent.createSelectionStartedEvent(
-                        SelectionEvent.INVOCATION_MANUAL, START));
-        String resultId =
-                ResultIdUtils.createId(
-                        702, Collections.singletonList(Locale.ENGLISH), /*hash=*/ 12345);
-        mSession.onSelectionEvent(
-                SelectionEvent.createSelectionModifiedEvent(
-                        SMART_START,
-                        SMART_END,
-                        new TextSelection.Builder(SMART_START, SMART_END)
-                                .setEntityType(TextClassifier.TYPE_ADDRESS, 1.0f)
-                                .setId(resultId)
-                                .build()));
-
-        SelectionEvent interceptedEvent = mTestTextClassifier.popLastSelectionEvent();
-        TextClassifierEvent.TextSelectionEvent textSelectionEvent =
-                (TextClassifierEvent.TextSelectionEvent)
-                        SelectionEventConverter.toTextClassifierEvent(interceptedEvent);
-
-        assertEventContext(textSelectionEvent.getEventContext());
-        assertThat(textSelectionEvent.getRelativeSuggestedWordStartIndex()).isEqualTo(-1);
-        assertThat(textSelectionEvent.getRelativeSuggestedWordEndIndex()).isEqualTo(1);
-        assertThat(textSelectionEvent.getEventType())
-                .isEqualTo(TextClassifierEvent.TYPE_SMART_SELECTION_MULTI);
-        assertThat(textSelectionEvent.getEventIndex()).isEqualTo(1);
-        assertThat(textSelectionEvent.getEntityTypes())
-                .asList()
-                .containsExactly(TextClassifier.TYPE_ADDRESS);
-        assertThat(textSelectionEvent.getResultId()).isEqualTo(resultId);
-    }
-
-    @Test
-    public void convert_smartLinkify() {
-        mSession.onSelectionEvent(
-                SelectionEvent.createSelectionStartedEvent(SelectionEvent.INVOCATION_LINK, START));
-        String resultId =
-                ResultIdUtils.createId(
-                        702, Collections.singletonList(Locale.ENGLISH), /*hash=*/ 12345);
-        mSession.onSelectionEvent(
-                SelectionEvent.createSelectionModifiedEvent(
-                        SMART_START,
-                        SMART_END,
-                        new TextSelection.Builder(SMART_START, SMART_END)
-                                .setEntityType(TextClassifier.TYPE_ADDRESS, 1.0f)
-                                .setId(resultId)
-                                .build()));
-
-        SelectionEvent interceptedEvent = mTestTextClassifier.popLastSelectionEvent();
-        TextClassifierEvent.TextLinkifyEvent textLinkifyEvent =
-                (TextClassifierEvent.TextLinkifyEvent)
-                        SelectionEventConverter.toTextClassifierEvent(interceptedEvent);
-
-        assertEventContext(textLinkifyEvent.getEventContext());
-        assertThat(textLinkifyEvent.getEventType())
-                .isEqualTo(TextClassifierEvent.TYPE_SMART_SELECTION_MULTI);
-        assertThat(textLinkifyEvent.getEventIndex()).isEqualTo(1);
-        assertThat(textLinkifyEvent.getEntityTypes())
-                .asList()
-                .containsExactly(TextClassifier.TYPE_ADDRESS);
-        assertThat(textLinkifyEvent.getResultId()).isEqualTo(resultId);
-    }
-
-    private static TextClassificationContext createEventContext() {
-        return new TextClassificationContext.Builder(PKG_NAME, TextClassifier.WIDGET_TYPE_EDITTEXT)
-                .build();
-    }
-
-    private static void assertEventContext(TextClassificationContext eventContext) {
-        assertThat(eventContext.getPackageName()).isEqualTo(PKG_NAME);
-        assertThat(eventContext.getWidgetType()).isEqualTo(WIDGET_TYPE);
-    }
-
-    private static class TestTextClassifier implements TextClassifier {
-        private Deque<SelectionEvent> mSelectionEvents = new ArrayDeque<>();
-
-        @Override
-        public void onSelectionEvent(SelectionEvent event) {
-            mSelectionEvents.push(event);
-        }
-
-        SelectionEvent popLastSelectionEvent() {
-            return mSelectionEvents.pop();
-        }
-    }
-}
diff --git a/java/tests/unittests/src/com/android/textclassifier/subjects/EntitySubject.java b/java/tests/unittests/src/com/android/textclassifier/subjects/EntitySubject.java
deleted file mode 100644
index 17a339f..0000000
--- a/java/tests/unittests/src/com/android/textclassifier/subjects/EntitySubject.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2019 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.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * 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.
- */
-
-package com.android.textclassifier.subjects;
-
-import static com.google.common.truth.Truth.assertAbout;
-
-import com.android.textclassifier.Entity;
-
-import com.google.common.truth.FailureMetadata;
-import com.google.common.truth.MathUtil;
-import com.google.common.truth.Subject;
-
-import javax.annotation.Nullable;
-
-/** Test helper for checking {@link com.android.textclassifier.Entity} results. */
-public final class EntitySubject extends Subject<EntitySubject, Entity> {
-
-    private static final float TOLERANCE = 0.0001f;
-    private Entity mEntity;
-
-    public static EntitySubject assertThat(@Nullable Entity entity) {
-        return assertAbout(EntitySubject::new).that(entity);
-    }
-
-    private EntitySubject(FailureMetadata failureMetadata, @Nullable Entity entity) {
-        super(failureMetadata, entity);
-        mEntity = entity;
-    }
-
-    public void isMatchWithinTolerance(@Nullable Entity entity) {
-        if (!entity.getEntityType().equals(mEntity.getEntityType())) {
-            failWithActual("expected to have type", entity.getEntityType());
-        }
-        if (!MathUtil.equalWithinTolerance(entity.getScore(), mEntity.getScore(), TOLERANCE)) {
-            failWithActual("expected to have confidence score", entity.getScore());
-        }
-    }
-}
diff --git a/java/tests/unittests/src/com/android/textclassifier/ulp/BasicLanguageProficiencyAnalyzerTest.java b/java/tests/unittests/src/com/android/textclassifier/ulp/BasicLanguageProficiencyAnalyzerTest.java
deleted file mode 100644
index 571abbd..0000000
--- a/java/tests/unittests/src/com/android/textclassifier/ulp/BasicLanguageProficiencyAnalyzerTest.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright (C) 2019 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.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * 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.
- */
-
-package com.android.textclassifier.ulp;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-import android.content.Context;
-
-import androidx.room.Room;
-import androidx.test.core.app.ApplicationProvider;
-import androidx.test.filters.SmallTest;
-
-import com.android.textclassifier.TextClassificationConstants;
-import com.android.textclassifier.ulp.database.LanguageProfileDatabase;
-import com.android.textclassifier.ulp.database.LanguageSignalInfo;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import java.util.Arrays;
-import java.util.Locale;
-
-/** Testing {@link BasicLanguageProficiencyAnalyzer} in an in-memory database. */
-@SmallTest
-public class BasicLanguageProficiencyAnalyzerTest {
-
-    private static final String PRIMARY_SYSTEM_LANGUAGE = Locale.CHINESE.toLanguageTag();
-    private static final String SECONDARY_SYSTEM_LANGUAGE = Locale.ENGLISH.toLanguageTag();
-    private static final String NON_SYSTEM_LANGUAGE = Locale.JAPANESE.toLanguageTag();
-
-    private LanguageProfileDatabase mDatabase;
-    private BasicLanguageProficiencyAnalyzer mProficiencyAnalyzer;
-    @Mock private SystemLanguagesProvider mSystemLanguagesProvider;
-
-    @Before
-    public void setup() {
-        MockitoAnnotations.initMocks(this);
-
-        Context context = ApplicationProvider.getApplicationContext();
-        TextClassificationConstants textClassificationConstants =
-                mock(TextClassificationConstants.class);
-        mDatabase = Room.inMemoryDatabaseBuilder(context, LanguageProfileDatabase.class).build();
-        mProficiencyAnalyzer =
-                new BasicLanguageProficiencyAnalyzer(
-                        textClassificationConstants, mDatabase, mSystemLanguagesProvider);
-        when(mSystemLanguagesProvider.getSystemLanguageTags())
-                .thenReturn(Arrays.asList(PRIMARY_SYSTEM_LANGUAGE, SECONDARY_SYSTEM_LANGUAGE));
-        when(textClassificationConstants.getLanguageProficiencyBootstrappingCount())
-                .thenReturn(100);
-    }
-
-    @After
-    public void close() {
-        mDatabase.close();
-    }
-
-    @Test
-    public void canUnderstand_emptyDatabase() {
-        assertThat(mProficiencyAnalyzer.canUnderstand(PRIMARY_SYSTEM_LANGUAGE)).isEqualTo(1f);
-        assertThat(mProficiencyAnalyzer.canUnderstand(SECONDARY_SYSTEM_LANGUAGE)).isEqualTo(0.5f);
-        assertThat(mProficiencyAnalyzer.canUnderstand(NON_SYSTEM_LANGUAGE)).isEqualTo(0f);
-    }
-
-    @Test
-    public void canUnderstand_validRequest() {
-        mDatabase
-                .languageInfoDao()
-                .insertLanguageInfo(
-                        new LanguageSignalInfo(
-                                PRIMARY_SYSTEM_LANGUAGE,
-                                LanguageSignalInfo.SUGGEST_CONVERSATION_ACTIONS,
-                                100));
-        mDatabase
-                .languageInfoDao()
-                .insertLanguageInfo(
-                        new LanguageSignalInfo(
-                                SECONDARY_SYSTEM_LANGUAGE,
-                                LanguageSignalInfo.SUGGEST_CONVERSATION_ACTIONS,
-                                30));
-
-        assertThat(mProficiencyAnalyzer.canUnderstand(PRIMARY_SYSTEM_LANGUAGE)).isEqualTo(1f);
-        assertThat(mProficiencyAnalyzer.canUnderstand(SECONDARY_SYSTEM_LANGUAGE)).isEqualTo(0.4f);
-        assertThat(mProficiencyAnalyzer.canUnderstand(NON_SYSTEM_LANGUAGE)).isEqualTo(0f);
-    }
-}
diff --git a/java/tests/unittests/src/com/android/textclassifier/ulp/KmeansLanguageProficiencyAnalyzerTest.java b/java/tests/unittests/src/com/android/textclassifier/ulp/KmeansLanguageProficiencyAnalyzerTest.java
deleted file mode 100644
index cb3fc02..0000000
--- a/java/tests/unittests/src/com/android/textclassifier/ulp/KmeansLanguageProficiencyAnalyzerTest.java
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * Copyright (C) 2019 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.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * 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.
- */
-
-package com.android.textclassifier.ulp;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-import android.content.Context;
-
-import androidx.room.Room;
-import androidx.test.core.app.ApplicationProvider;
-import androidx.test.filters.SmallTest;
-
-import com.android.textclassifier.TextClassificationConstants;
-import com.android.textclassifier.ulp.database.LanguageProfileDatabase;
-import com.android.textclassifier.ulp.database.LanguageSignalInfo;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Locale;
-
-/** Testing {@link KmeansLanguageProficiencyAnalyzer} in an in-memory database. */
-@SmallTest
-public class KmeansLanguageProficiencyAnalyzerTest {
-
-    private static final String PRIMARY_SYSTEM_LANGUAGE = Locale.CHINESE.toLanguageTag();
-    private static final String SECONDARY_SYSTEM_LANGUAGE = Locale.ENGLISH.toLanguageTag();
-    private static final String NORMAL_LANGUAGE = Locale.JAPANESE.toLanguageTag();
-
-    private LanguageProfileDatabase mDatabase;
-    private KmeansLanguageProficiencyAnalyzer mProficiencyAnalyzer;
-    @Mock private SystemLanguagesProvider mSystemLanguagesProvider;
-
-    @Before
-    public void setup() {
-        MockitoAnnotations.initMocks(this);
-
-        Context context = ApplicationProvider.getApplicationContext();
-        TextClassificationConstants textClassificationConstants =
-                mock(TextClassificationConstants.class);
-        mDatabase = Room.inMemoryDatabaseBuilder(context, LanguageProfileDatabase.class).build();
-        mProficiencyAnalyzer =
-                new KmeansLanguageProficiencyAnalyzer(
-                        textClassificationConstants, mDatabase, mSystemLanguagesProvider);
-        when(mSystemLanguagesProvider.getSystemLanguageTags())
-                .thenReturn(Arrays.asList(PRIMARY_SYSTEM_LANGUAGE, SECONDARY_SYSTEM_LANGUAGE));
-        when(textClassificationConstants.getLanguageProficiencyBootstrappingCount())
-                .thenReturn(100);
-    }
-
-    @After
-    public void close() {
-        mDatabase.close();
-    }
-
-    @Test
-    public void canUnderstand_emptyDatabase() {
-        assertThat(mProficiencyAnalyzer.canUnderstand(PRIMARY_SYSTEM_LANGUAGE)).isEqualTo(1f);
-        assertThat(mProficiencyAnalyzer.canUnderstand(SECONDARY_SYSTEM_LANGUAGE)).isEqualTo(0.5f);
-        assertThat(mProficiencyAnalyzer.canUnderstand(NORMAL_LANGUAGE)).isEqualTo(0f);
-    }
-
-    @Test
-    public void canUnderstand_oneLanguage() {
-        when(mSystemLanguagesProvider.getSystemLanguageTags())
-                .thenReturn(Collections.singletonList(PRIMARY_SYSTEM_LANGUAGE));
-        mDatabase
-                .languageInfoDao()
-                .insertLanguageInfo(
-                        new LanguageSignalInfo(
-                                PRIMARY_SYSTEM_LANGUAGE,
-                                LanguageSignalInfo.SUGGEST_CONVERSATION_ACTIONS,
-                                1));
-
-        assertThat(mProficiencyAnalyzer.canUnderstand(PRIMARY_SYSTEM_LANGUAGE)).isEqualTo(1f);
-        assertThat(mProficiencyAnalyzer.canUnderstand(SECONDARY_SYSTEM_LANGUAGE)).isEqualTo(0f);
-        assertThat(mProficiencyAnalyzer.canUnderstand(NORMAL_LANGUAGE)).isEqualTo(0f);
-    }
-
-    @Test
-    public void canUnderstand_twoLanguages() {
-        mDatabase
-                .languageInfoDao()
-                .insertLanguageInfo(
-                        new LanguageSignalInfo(
-                                PRIMARY_SYSTEM_LANGUAGE,
-                                LanguageSignalInfo.SUGGEST_CONVERSATION_ACTIONS,
-                                100));
-        mDatabase
-                .languageInfoDao()
-                .insertLanguageInfo(
-                        new LanguageSignalInfo(
-                                SECONDARY_SYSTEM_LANGUAGE,
-                                LanguageSignalInfo.SUGGEST_CONVERSATION_ACTIONS,
-                                50));
-
-        assertThat(mProficiencyAnalyzer.canUnderstand(PRIMARY_SYSTEM_LANGUAGE)).isEqualTo(1f);
-        assertThat(mProficiencyAnalyzer.canUnderstand(SECONDARY_SYSTEM_LANGUAGE)).isEqualTo(0.5f);
-        assertThat(mProficiencyAnalyzer.canUnderstand(NORMAL_LANGUAGE)).isEqualTo(0f);
-    }
-
-    @Test
-    public void canUnderstand_threeLanguages() {
-        mDatabase
-                .languageInfoDao()
-                .insertLanguageInfo(
-                        new LanguageSignalInfo(
-                                PRIMARY_SYSTEM_LANGUAGE,
-                                LanguageSignalInfo.SUGGEST_CONVERSATION_ACTIONS,
-                                100));
-        mDatabase
-                .languageInfoDao()
-                .insertLanguageInfo(
-                        new LanguageSignalInfo(
-                                SECONDARY_SYSTEM_LANGUAGE,
-                                LanguageSignalInfo.SUGGEST_CONVERSATION_ACTIONS,
-                                75));
-        mDatabase
-                .languageInfoDao()
-                .insertLanguageInfo(
-                        new LanguageSignalInfo(
-                                NORMAL_LANGUAGE,
-                                LanguageSignalInfo.SUGGEST_CONVERSATION_ACTIONS,
-                                2));
-
-        assertThat(mProficiencyAnalyzer.canUnderstand(PRIMARY_SYSTEM_LANGUAGE)).isEqualTo(1f);
-        assertThat(mProficiencyAnalyzer.canUnderstand(SECONDARY_SYSTEM_LANGUAGE)).isEqualTo(1f);
-        assertThat(mProficiencyAnalyzer.canUnderstand(NORMAL_LANGUAGE)).isEqualTo(0f);
-    }
-}
diff --git a/java/tests/unittests/src/com/android/textclassifier/ulp/LanguageProficiencyEvaluatorTest.java b/java/tests/unittests/src/com/android/textclassifier/ulp/LanguageProficiencyEvaluatorTest.java
deleted file mode 100644
index 387cb61..0000000
--- a/java/tests/unittests/src/com/android/textclassifier/ulp/LanguageProficiencyEvaluatorTest.java
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * Copyright (C) 2019 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.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * 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.
- */
-
-package com.android.textclassifier.ulp;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.Mockito.when;
-
-import androidx.test.filters.SmallTest;
-
-import com.google.android.collect.Sets;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mock;
-import org.mockito.Mockito;
-import org.mockito.MockitoAnnotations;
-import org.mockito.stubbing.Answer;
-
-import java.util.Arrays;
-import java.util.Set;
-
-@SmallTest
-public class LanguageProficiencyEvaluatorTest {
-    private static final float EPSILON = 0.01f;
-    private LanguageProficiencyEvaluator mLanguageProficiencyEvaluator;
-
-    @Mock private SystemLanguagesProvider mSystemLanguagesProvider;
-
-    private static final String SYSTEM_LANGUAGE_EN = "en";
-    private static final String SYSTEM_LANGUAGE_ZH = "zh";
-    private static final String NORMAL_LANGUAGE_JP = "jp";
-    private static final String NORMAL_LANGUAGE_FR = "fr";
-    private static final String NORMAL_LANGUAGE_PL = "pl";
-    private static final Set<String> EVALUATION_LANGUAGES =
-            Sets.newArraySet(
-                    SYSTEM_LANGUAGE_EN,
-                    SYSTEM_LANGUAGE_ZH,
-                    NORMAL_LANGUAGE_JP,
-                    NORMAL_LANGUAGE_FR,
-                    NORMAL_LANGUAGE_PL);
-
-    @Mock private LanguageProficiencyAnalyzer mLanguageProficiencyAnalyzer;
-
-    @Before
-    public void setUp() {
-        MockitoAnnotations.initMocks(this);
-        when(mSystemLanguagesProvider.getSystemLanguageTags())
-                .thenReturn(Arrays.asList(SYSTEM_LANGUAGE_EN, SYSTEM_LANGUAGE_ZH));
-        mLanguageProficiencyEvaluator = new LanguageProficiencyEvaluator(mSystemLanguagesProvider);
-    }
-
-    @Test
-    public void evaluate_allCorrect() {
-        when(mLanguageProficiencyAnalyzer.canUnderstand(Mockito.anyString()))
-                .thenAnswer(
-                        (Answer<Float>)
-                                invocation -> {
-                                    String languageTag = invocation.getArgument(0);
-                                    if (languageTag.equals(SYSTEM_LANGUAGE_EN)
-                                            || languageTag.equals(SYSTEM_LANGUAGE_ZH)) {
-                                        return 1f;
-                                    }
-                                    return 0f;
-                                });
-
-        LanguageProficiencyEvaluator.EvaluationResult evaluationResult =
-                mLanguageProficiencyEvaluator.evaluate(
-                        mLanguageProficiencyAnalyzer, EVALUATION_LANGUAGES);
-
-        assertThat(evaluationResult.truePositive).isEqualTo(2);
-        assertThat(evaluationResult.trueNegative).isEqualTo(3);
-        assertThat(evaluationResult.falsePositive).isEqualTo(0);
-        assertThat(evaluationResult.falseNegative).isEqualTo(0);
-        assertThat(evaluationResult.computePrecisionOfPositiveClass()).isWithin(EPSILON).of(1f);
-        assertThat(evaluationResult.computePrecisionOfNegativeClass()).isWithin(EPSILON).of(1f);
-        assertThat(evaluationResult.computeRecallOfPositiveClass()).isWithin(EPSILON).of(1f);
-        assertThat(evaluationResult.computeRecallOfNegativeClass()).isWithin(EPSILON).of(1f);
-        assertThat(evaluationResult.computeF1ScoreOfPositiveClass()).isWithin(EPSILON).of(1f);
-        assertThat(evaluationResult.computeF1ScoreOfNegativeClass()).isWithin(EPSILON).of(1f);
-    }
-
-    @Test
-    public void evaluate_allWrong() {
-        when(mLanguageProficiencyAnalyzer.canUnderstand(Mockito.anyString()))
-                .thenAnswer(
-                        (Answer<Float>)
-                                invocation -> {
-                                    String languageTag = invocation.getArgument(0);
-                                    if (languageTag.equals(SYSTEM_LANGUAGE_EN)
-                                            || languageTag.equals(SYSTEM_LANGUAGE_ZH)) {
-                                        return 0f;
-                                    }
-                                    return 1f;
-                                });
-
-        LanguageProficiencyEvaluator.EvaluationResult evaluationResult =
-                mLanguageProficiencyEvaluator.evaluate(
-                        mLanguageProficiencyAnalyzer, EVALUATION_LANGUAGES);
-
-        assertThat(evaluationResult.truePositive).isEqualTo(0);
-        assertThat(evaluationResult.trueNegative).isEqualTo(0);
-        assertThat(evaluationResult.falsePositive).isEqualTo(3);
-        assertThat(evaluationResult.falseNegative).isEqualTo(2);
-        assertThat(evaluationResult.computePrecisionOfPositiveClass()).isWithin(EPSILON).of(0f);
-        assertThat(evaluationResult.computePrecisionOfNegativeClass()).isWithin(EPSILON).of(0f);
-        assertThat(evaluationResult.computeRecallOfPositiveClass()).isWithin(EPSILON).of(0f);
-        assertThat(evaluationResult.computeRecallOfNegativeClass()).isWithin(EPSILON).of(0f);
-        assertThat(evaluationResult.computeF1ScoreOfPositiveClass()).isWithin(EPSILON).of(0f);
-        assertThat(evaluationResult.computeF1ScoreOfNegativeClass()).isWithin(EPSILON).of(0f);
-    }
-
-    @Test
-    public void evaluate_mixed() {
-        when(mLanguageProficiencyAnalyzer.canUnderstand(Mockito.anyString()))
-                .thenAnswer(
-                        (Answer<Float>)
-                                invocation -> {
-                                    String languageTag = invocation.getArgument(0);
-                                    switch (languageTag) {
-                                        case SYSTEM_LANGUAGE_EN:
-                                            return 1f;
-                                        case SYSTEM_LANGUAGE_ZH:
-                                            return 0f;
-                                        case NORMAL_LANGUAGE_FR:
-                                            return 0f;
-                                        case NORMAL_LANGUAGE_JP:
-                                            return 0f;
-                                        case NORMAL_LANGUAGE_PL:
-                                            return 1f;
-                                    }
-                                    throw new IllegalArgumentException(
-                                            "unexpected language: " + languageTag);
-                                });
-
-        LanguageProficiencyEvaluator.EvaluationResult evaluationResult =
-                mLanguageProficiencyEvaluator.evaluate(
-                        mLanguageProficiencyAnalyzer, EVALUATION_LANGUAGES);
-
-        assertThat(evaluationResult.truePositive).isEqualTo(1);
-        assertThat(evaluationResult.trueNegative).isEqualTo(2);
-        assertThat(evaluationResult.falsePositive).isEqualTo(1);
-        assertThat(evaluationResult.falseNegative).isEqualTo(1);
-        assertThat(evaluationResult.computePrecisionOfPositiveClass()).isWithin(EPSILON).of(0.5f);
-        assertThat(evaluationResult.computePrecisionOfNegativeClass()).isWithin(EPSILON).of(0.66f);
-        assertThat(evaluationResult.computeRecallOfPositiveClass()).isWithin(EPSILON).of(0.5f);
-        assertThat(evaluationResult.computeRecallOfNegativeClass()).isWithin(EPSILON).of(0.66f);
-        assertThat(evaluationResult.computeF1ScoreOfPositiveClass()).isWithin(EPSILON).of(0.5f);
-        assertThat(evaluationResult.computeF1ScoreOfNegativeClass()).isWithin(EPSILON).of(0.66f);
-    }
-}
diff --git a/java/tests/unittests/src/com/android/textclassifier/ulp/LanguageProfileAnalyzerTest.java b/java/tests/unittests/src/com/android/textclassifier/ulp/LanguageProfileAnalyzerTest.java
deleted file mode 100644
index 8b21a9f..0000000
--- a/java/tests/unittests/src/com/android/textclassifier/ulp/LanguageProfileAnalyzerTest.java
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * Copyright (C) 2019 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.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * 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.
- */
-
-package com.android.textclassifier.ulp;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-import android.content.Context;
-
-import androidx.room.Room;
-import androidx.test.core.app.ApplicationProvider;
-import androidx.test.filters.SmallTest;
-
-import com.android.textclassifier.Entity;
-import com.android.textclassifier.TextClassificationConstants;
-import com.android.textclassifier.subjects.EntitySubject;
-import com.android.textclassifier.ulp.database.LanguageProfileDatabase;
-import com.android.textclassifier.ulp.database.LanguageSignalInfo;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-
-/** Testing {@link LanguageProfileAnalyzer} in an inMemoryDatabase. */
-@SmallTest
-public class LanguageProfileAnalyzerTest {
-
-    private static final String SYSTEM_LANGUAGE_CODE = "en";
-    private static final String LOCATION_LANGUAGE_CODE = "jp";
-    private static final String NORMAL_LANGUAGE_CODE = "pl";
-
-    private LanguageProfileDatabase mDatabase;
-    private LanguageProfileAnalyzer mLanguageProfileAnalyzer;
-    @Mock private LocationSignalProvider mLocationSignalProvider;
-    @Mock private SystemLanguagesProvider mSystemLanguagesProvider;
-    @Mock private LanguageProficiencyAnalyzer mLanguageProficiencyAnalyzer;
-
-    @Before
-    public void setup() {
-        MockitoAnnotations.initMocks(this);
-
-        Context mContext = ApplicationProvider.getApplicationContext();
-        mDatabase = Room.inMemoryDatabaseBuilder(mContext, LanguageProfileDatabase.class).build();
-        when(mLocationSignalProvider.detectLanguageTag()).thenReturn(LOCATION_LANGUAGE_CODE);
-        when(mSystemLanguagesProvider.getSystemLanguageTags())
-                .thenReturn(Collections.singletonList(SYSTEM_LANGUAGE_CODE));
-        when(mLanguageProficiencyAnalyzer.canUnderstand(anyString())).thenReturn(1.0f);
-        TextClassificationConstants customTextClassificationConstants =
-                mock(TextClassificationConstants.class);
-        when(customTextClassificationConstants.getFrequentLanguagesBootstrappingCount())
-                .thenReturn(100);
-        mLanguageProfileAnalyzer =
-                new LanguageProfileAnalyzer(
-                        mContext,
-                        customTextClassificationConstants,
-                        mDatabase,
-                        mLanguageProficiencyAnalyzer,
-                        mLocationSignalProvider,
-                        mSystemLanguagesProvider);
-    }
-
-    @After
-    public void close() {
-        mDatabase.close();
-    }
-
-    @Test
-    public void getFrequentLanguages_emptyDatabase() {
-        List<Entity> frequentLanguages =
-                mLanguageProfileAnalyzer.getFrequentLanguages(LanguageSignalInfo.CLASSIFY_TEXT);
-
-        assertThat(frequentLanguages).hasSize(2);
-        EntitySubject.assertThat(frequentLanguages.get(0))
-                .isMatchWithinTolerance(new Entity(SYSTEM_LANGUAGE_CODE, 1.0f));
-        EntitySubject.assertThat(frequentLanguages.get(1))
-                .isMatchWithinTolerance(new Entity(LOCATION_LANGUAGE_CODE, 1.0f));
-    }
-
-    @Test
-    public void getFrequentLanguages_mixedSignal() {
-        insertSignal(NORMAL_LANGUAGE_CODE, LanguageSignalInfo.CLASSIFY_TEXT, 50);
-        insertSignal(SYSTEM_LANGUAGE_CODE, LanguageSignalInfo.CLASSIFY_TEXT, 100);
-        // Unrelated signals.
-        insertSignal(NORMAL_LANGUAGE_CODE, LanguageSignalInfo.SUGGEST_CONVERSATION_ACTIONS, 100);
-        insertSignal(SYSTEM_LANGUAGE_CODE, LanguageSignalInfo.SUGGEST_CONVERSATION_ACTIONS, 100);
-        insertSignal(LOCATION_LANGUAGE_CODE, LanguageSignalInfo.SUGGEST_CONVERSATION_ACTIONS, 100);
-
-        List<Entity> frequentLanguages =
-                mLanguageProfileAnalyzer.getFrequentLanguages(LanguageSignalInfo.CLASSIFY_TEXT);
-
-        assertThat(frequentLanguages).hasSize(3);
-        EntitySubject.assertThat(frequentLanguages.get(0))
-                .isMatchWithinTolerance(new Entity(SYSTEM_LANGUAGE_CODE, 1.0f));
-        EntitySubject.assertThat(frequentLanguages.get(1))
-                .isMatchWithinTolerance(new Entity(LOCATION_LANGUAGE_CODE, 0.5f));
-        EntitySubject.assertThat(frequentLanguages.get(2))
-                .isMatchWithinTolerance(new Entity(NORMAL_LANGUAGE_CODE, 0.25f));
-    }
-
-    @Test
-    public void getFrequentLanguages_bothSystemLanguageAndLocationLanguage() {
-        when(mLocationSignalProvider.detectLanguageTag()).thenReturn("en");
-        when(mSystemLanguagesProvider.getSystemLanguageTags())
-                .thenReturn(Arrays.asList("en", "jp"));
-
-        List<Entity> frequentLanguages =
-                mLanguageProfileAnalyzer.getFrequentLanguages(LanguageSignalInfo.CLASSIFY_TEXT);
-
-        assertThat(frequentLanguages).hasSize(2);
-        EntitySubject.assertThat(frequentLanguages.get(0))
-                .isMatchWithinTolerance(new Entity("en", 1.0f));
-        EntitySubject.assertThat(frequentLanguages.get(1))
-                .isMatchWithinTolerance(new Entity("jp", 0.5f));
-    }
-
-    private void insertSignal(
-            String languageTag, @LanguageSignalInfo.Source int source, int count) {
-        mDatabase
-                .languageInfoDao()
-                .insertLanguageInfo(new LanguageSignalInfo(languageTag, source, count));
-    }
-}
diff --git a/java/tests/unittests/src/com/android/textclassifier/ulp/LanguageProfileUpdaterTest.java b/java/tests/unittests/src/com/android/textclassifier/ulp/LanguageProfileUpdaterTest.java
deleted file mode 100644
index b90704a..0000000
--- a/java/tests/unittests/src/com/android/textclassifier/ulp/LanguageProfileUpdaterTest.java
+++ /dev/null
@@ -1,230 +0,0 @@
-/*
- * Copyright (C) 2019 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.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * 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.
- */
-
-package com.android.textclassifier.ulp;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.app.Person;
-import android.content.Context;
-import android.os.Bundle;
-import android.view.textclassifier.ConversationActions;
-import android.view.textclassifier.TextClassification;
-
-import androidx.room.Room;
-import androidx.test.core.app.ApplicationProvider;
-import androidx.test.filters.SmallTest;
-
-import com.android.textclassifier.ulp.database.LanguageProfileDatabase;
-import com.android.textclassifier.ulp.database.LanguageSignalInfo;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.util.concurrent.ListeningExecutorService;
-import com.google.common.util.concurrent.MoreExecutors;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-import java.time.ZoneId;
-import java.time.ZonedDateTime;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Locale;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.Executors;
-import java.util.function.Function;
-
-/** Testing {@link LanguageProfileUpdater} in an in-memory database. */
-@SmallTest
-public class LanguageProfileUpdaterTest {
-
-    private static final String NOTIFICATION_KEY = "test_notification";
-    private static final String LOCALE_TAG_US = Locale.US.toLanguageTag();
-    private static final String LOCALE_TAG_CHINA = Locale.CHINA.toLanguageTag();
-    private static final String TEXT_ONE = "hello world";
-    private static final String TEXT_TWO = "你好!";
-    private static final Function<CharSequence, List<String>> LANGUAGE_DETECTOR_US =
-            charSequence -> ImmutableList.of(LOCALE_TAG_US);
-    private static final Function<CharSequence, List<String>> LANGUAGE_DETECTOR_CHINA =
-            charSequence -> ImmutableList.of(LOCALE_TAG_CHINA);
-    private static final Person PERSON = new Person.Builder().build();
-    private static final ZonedDateTime TIME_ONE =
-            ZonedDateTime.of(2019, 7, 21, 12, 12, 12, 12, ZoneId.systemDefault());
-    private static final ZonedDateTime TIME_TWO =
-            ZonedDateTime.of(2019, 7, 21, 12, 20, 20, 12, ZoneId.systemDefault());
-    private static final ConversationActions.Message MSG_ONE =
-            new ConversationActions.Message.Builder(PERSON)
-                    .setReferenceTime(TIME_ONE)
-                    .setText(TEXT_ONE)
-                    .setExtras(new Bundle())
-                    .build();
-    private static final ConversationActions.Message MSG_TWO =
-            new ConversationActions.Message.Builder(PERSON)
-                    .setReferenceTime(TIME_TWO)
-                    .setText("where are you?")
-                    .setExtras(new Bundle())
-                    .build();
-    private static final ConversationActions.Message MSG_THREE =
-            new ConversationActions.Message.Builder(PERSON)
-                    .setReferenceTime(TIME_TWO)
-                    .setText(TEXT_TWO)
-                    .setExtras(new Bundle())
-                    .build();
-    private static final ConversationActions.Request CONVERSATION_ACTION_REQUEST_ONE =
-            new ConversationActions.Request.Builder(Arrays.asList(MSG_ONE)).build();
-    private static final ConversationActions.Request CONVERSATION_ACTION_REQUEST_TWO =
-            new ConversationActions.Request.Builder(Arrays.asList(MSG_TWO)).build();
-    private static final TextClassification.Request TEXT_CLASSIFICATION_REQUEST_ONE =
-            new TextClassification.Request.Builder(TEXT_ONE, 0, 2).build();
-    private static final LanguageSignalInfo US_INFO_ONE_FOR_CONVERSATION_ACTION_ONE =
-            new LanguageSignalInfo(
-                    LOCALE_TAG_US, LanguageSignalInfo.SUGGEST_CONVERSATION_ACTIONS, 1);
-    private static final LanguageSignalInfo US_INFO_ONE_FOR_CONVERSATION_ACTION_TWO =
-            new LanguageSignalInfo(
-                    LOCALE_TAG_US, LanguageSignalInfo.SUGGEST_CONVERSATION_ACTIONS, 2);
-    private static final LanguageSignalInfo US_INFO_ONE_FOR_CLASSIFY_TEXT =
-            new LanguageSignalInfo(LOCALE_TAG_US, LanguageSignalInfo.CLASSIFY_TEXT, 1);
-
-    private LanguageProfileUpdater mLanguageProfileUpdater;
-    private LanguageProfileDatabase mDatabase;
-
-    @Before
-    public void setup() {
-        Context mContext = ApplicationProvider.getApplicationContext();
-        ListeningExecutorService mExecutorService =
-                MoreExecutors.listeningDecorator(Executors.newSingleThreadExecutor());
-        mDatabase = Room.inMemoryDatabaseBuilder(mContext, LanguageProfileDatabase.class).build();
-        mLanguageProfileUpdater = new LanguageProfileUpdater(mExecutorService, mDatabase);
-    }
-
-    @After
-    public void close() {
-        mDatabase.close();
-    }
-
-    @Test
-    public void updateFromConversationActionsAsync_oneMessage()
-            throws ExecutionException, InterruptedException {
-        mLanguageProfileUpdater
-                .updateFromConversationActionsAsync(
-                        CONVERSATION_ACTION_REQUEST_ONE, LANGUAGE_DETECTOR_US)
-                .get();
-        List<LanguageSignalInfo> infos = mDatabase.languageInfoDao().getAll();
-
-        assertThat(infos).hasSize(1);
-        LanguageSignalInfo info = infos.get(0);
-        assertThat(info).isEqualTo(US_INFO_ONE_FOR_CONVERSATION_ACTION_ONE);
-    }
-
-    /** Notification keys for these two messages are DEFAULT_NOTIFICATION_KEY */
-    @Test
-    public void updateFromConversationActionsAsync_twoMessagesInSameNotificationWithSameLanguage()
-            throws ExecutionException, InterruptedException {
-        mLanguageProfileUpdater
-                .updateFromConversationActionsAsync(
-                        CONVERSATION_ACTION_REQUEST_ONE, LANGUAGE_DETECTOR_US)
-                .get();
-        mLanguageProfileUpdater
-                .updateFromConversationActionsAsync(
-                        CONVERSATION_ACTION_REQUEST_TWO, LANGUAGE_DETECTOR_US)
-                .get();
-        List<LanguageSignalInfo> infos = mDatabase.languageInfoDao().getAll();
-
-        assertThat(infos).hasSize(1);
-        LanguageSignalInfo info = infos.get(0);
-        assertThat(info).isEqualTo(US_INFO_ONE_FOR_CONVERSATION_ACTION_TWO);
-    }
-
-    @Test
-    public void updateFromConversationActionsAsync_twoMessagesInDifferentNotifications()
-            throws ExecutionException, InterruptedException {
-        mLanguageProfileUpdater
-                .updateFromConversationActionsAsync(
-                        CONVERSATION_ACTION_REQUEST_ONE, LANGUAGE_DETECTOR_US)
-                .get();
-        Bundle extra = new Bundle();
-        extra.putString(LanguageProfileUpdater.NOTIFICATION_KEY, NOTIFICATION_KEY);
-        ConversationActions.Request newRequest =
-                new ConversationActions.Request.Builder(Arrays.asList(MSG_TWO))
-                        .setExtras(extra)
-                        .build();
-        mLanguageProfileUpdater
-                .updateFromConversationActionsAsync(newRequest, LANGUAGE_DETECTOR_US)
-                .get();
-        List<LanguageSignalInfo> infos = mDatabase.languageInfoDao().getAll();
-
-        assertThat(infos).hasSize(1);
-        LanguageSignalInfo info = infos.get(0);
-        assertThat(info).isEqualTo(US_INFO_ONE_FOR_CONVERSATION_ACTION_TWO);
-    }
-
-    @Test
-    public void updateFromConversationActionsAsync_twoMessagesInDifferentLanguage()
-            throws ExecutionException, InterruptedException {
-        mLanguageProfileUpdater
-                .updateFromConversationActionsAsync(
-                        CONVERSATION_ACTION_REQUEST_ONE, LANGUAGE_DETECTOR_US)
-                .get();
-        ConversationActions.Request newRequest =
-                new ConversationActions.Request.Builder(Arrays.asList(MSG_THREE)).build();
-        mLanguageProfileUpdater
-                .updateFromConversationActionsAsync(newRequest, LANGUAGE_DETECTOR_CHINA)
-                .get();
-        List<LanguageSignalInfo> infos = mDatabase.languageInfoDao().getAll();
-
-        assertThat(infos).hasSize(2);
-        LanguageSignalInfo infoOne = infos.get(0);
-        LanguageSignalInfo infoTwo = infos.get(1);
-        assertThat(infoOne).isEqualTo(US_INFO_ONE_FOR_CONVERSATION_ACTION_ONE);
-        assertThat(infoTwo)
-                .isEqualTo(
-                        new LanguageSignalInfo(
-                                LOCALE_TAG_CHINA,
-                                LanguageSignalInfo.SUGGEST_CONVERSATION_ACTIONS,
-                                1));
-    }
-
-    @Test
-    public void updateFromClassifyTextAsync_classifyText()
-            throws ExecutionException, InterruptedException {
-        mLanguageProfileUpdater.updateFromClassifyTextAsync(ImmutableList.of(LOCALE_TAG_US)).get();
-        List<LanguageSignalInfo> infos = mDatabase.languageInfoDao().getAll();
-
-        assertThat(infos).hasSize(1);
-        LanguageSignalInfo info = infos.get(0);
-        assertThat(info).isEqualTo(US_INFO_ONE_FOR_CLASSIFY_TEXT);
-    }
-
-    @Test
-    public void updateFromClassifyTextAsync_classifyTextTwice()
-            throws ExecutionException, InterruptedException {
-        mLanguageProfileUpdater.updateFromClassifyTextAsync(ImmutableList.of(LOCALE_TAG_US)).get();
-        mLanguageProfileUpdater
-                .updateFromClassifyTextAsync(ImmutableList.of(LOCALE_TAG_CHINA))
-                .get();
-
-        List<LanguageSignalInfo> infos = mDatabase.languageInfoDao().getAll();
-        assertThat(infos).hasSize(2);
-        LanguageSignalInfo infoOne = infos.get(0);
-        LanguageSignalInfo infoTwo = infos.get(1);
-        assertThat(infoOne).isEqualTo(US_INFO_ONE_FOR_CLASSIFY_TEXT);
-        assertThat(infoTwo)
-                .isEqualTo(
-                        new LanguageSignalInfo(
-                                LOCALE_TAG_CHINA, LanguageSignalInfo.CLASSIFY_TEXT, 1));
-    }
-}
diff --git a/java/tests/unittests/src/com/android/textclassifier/ulp/LocationSignalProviderTest.java b/java/tests/unittests/src/com/android/textclassifier/ulp/LocationSignalProviderTest.java
deleted file mode 100644
index 0979344..0000000
--- a/java/tests/unittests/src/com/android/textclassifier/ulp/LocationSignalProviderTest.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (C) 2019 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.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * 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.
- */
-
-package com.android.textclassifier.ulp;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.Mockito.when;
-
-import android.location.Address;
-import android.location.Geocoder;
-import android.location.Location;
-import android.location.LocationManager;
-import android.telephony.TelephonyManager;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mock;
-import org.mockito.Mockito;
-import org.mockito.MockitoAnnotations;
-
-import java.io.IOException;
-import java.util.Collections;
-import java.util.Locale;
-
-@SmallTest
-public class LocationSignalProviderTest {
-    @Mock private LocationManager mLocationManager;
-    @Mock private TelephonyManager mTelephonyManager;
-    @Mock private LocationSignalProvider mLocationSignalProvider;
-    @Mock private Geocoder mGeocoder;
-
-    @Before
-    public void setup() {
-        MockitoAnnotations.initMocks(this);
-        mLocationSignalProvider =
-                new LocationSignalProvider(mLocationManager, mTelephonyManager, mGeocoder);
-    }
-
-    @Test
-    public void detectLanguageTag_useTelephony() {
-        when(mTelephonyManager.getNetworkCountryIso()).thenReturn(Locale.UK.getCountry());
-
-        assertThat(mLocationSignalProvider.detectLanguageTag()).isEqualTo("en");
-    }
-
-    @Test
-    public void detectLanguageTag_useLocation() throws IOException {
-        when(mTelephonyManager.getNetworkCountryIso()).thenReturn(null);
-        Location location = new Location(LocationManager.PASSIVE_PROVIDER);
-        when(mLocationManager.getLastKnownLocation(LocationManager.PASSIVE_PROVIDER))
-                .thenReturn(location);
-        Address address = new Address(Locale.FRANCE);
-        address.setCountryCode(Locale.FRANCE.getCountry());
-        when(mGeocoder.getFromLocation(Mockito.anyDouble(), Mockito.anyDouble(), Mockito.anyInt()))
-                .thenReturn(Collections.singletonList(address));
-
-        assertThat(mLocationSignalProvider.detectLanguageTag()).isEqualTo("fr");
-    }
-}
diff --git a/java/tests/unittests/src/com/android/textclassifier/ulp/ReinforcementLanguageProficiencyAnalyzerTest.java b/java/tests/unittests/src/com/android/textclassifier/ulp/ReinforcementLanguageProficiencyAnalyzerTest.java
deleted file mode 100644
index 8e43e99..0000000
--- a/java/tests/unittests/src/com/android/textclassifier/ulp/ReinforcementLanguageProficiencyAnalyzerTest.java
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright (C) 2019 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.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * 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.
- */
-
-package com.android.textclassifier.ulp;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.Mockito.when;
-
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.view.textclassifier.TextClassifierEvent;
-
-import androidx.test.core.app.ApplicationProvider;
-import androidx.test.filters.SmallTest;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import java.util.Arrays;
-import java.util.Locale;
-
-/** Testing {@link ReinforcementLanguageProficiencyAnalyzer} using Mockito. */
-@SmallTest
-public class ReinforcementLanguageProficiencyAnalyzerTest {
-
-    private static final String PRIMARY_SYSTEM_LANGUAGE = Locale.CHINESE.toLanguageTag();
-    private static final String SECONDARY_SYSTEM_LANGUAGE = Locale.ENGLISH.toLanguageTag();
-    private static final String NON_SYSTEM_LANGUAGE = Locale.JAPANESE.toLanguageTag();
-    private ReinforcementLanguageProficiencyAnalyzer mProficiencyAnalyzer;
-    @Mock private SystemLanguagesProvider mSystemLanguagesProvider;
-    private SharedPreferences mSharedPreferences;
-
-    @Before
-    public void setup() {
-        MockitoAnnotations.initMocks(this);
-        Context context = ApplicationProvider.getApplicationContext();
-        mSharedPreferences = context.getSharedPreferences("test-preferences", Context.MODE_PRIVATE);
-        when(mSystemLanguagesProvider.getSystemLanguageTags())
-                .thenReturn(Arrays.asList(PRIMARY_SYSTEM_LANGUAGE, SECONDARY_SYSTEM_LANGUAGE));
-        mProficiencyAnalyzer =
-                new ReinforcementLanguageProficiencyAnalyzer(
-                        mSystemLanguagesProvider, mSharedPreferences);
-    }
-
-    @After
-    public void teardown() {
-        mSharedPreferences.edit().clear().apply();
-    }
-
-    @Test
-    public void canUnderstand_defaultValue() {
-        assertThat(mProficiencyAnalyzer.canUnderstand(PRIMARY_SYSTEM_LANGUAGE)).isEqualTo(1.0f);
-        assertThat(mProficiencyAnalyzer.canUnderstand(SECONDARY_SYSTEM_LANGUAGE)).isEqualTo(1.0f);
-        assertThat(mProficiencyAnalyzer.canUnderstand(NON_SYSTEM_LANGUAGE)).isEqualTo(0f);
-    }
-
-    @Test
-    public void canUnderstand_enoughFeedback() {
-        sendEvent(TextClassifierEvent.TYPE_ACTIONS_SHOWN, PRIMARY_SYSTEM_LANGUAGE, /* times= */ 50);
-        sendEvent(TextClassifierEvent.TYPE_SMART_ACTION, PRIMARY_SYSTEM_LANGUAGE, /* times= */ 40);
-
-        assertThat(mProficiencyAnalyzer.canUnderstand(PRIMARY_SYSTEM_LANGUAGE)).isEqualTo(0.8f);
-    }
-
-    @Test
-    public void shouldShowTranslation_defaultValue() {
-        assertThat(mProficiencyAnalyzer.shouldShowTranslation(PRIMARY_SYSTEM_LANGUAGE))
-                .isEqualTo(true);
-        assertThat(mProficiencyAnalyzer.shouldShowTranslation(SECONDARY_SYSTEM_LANGUAGE))
-                .isEqualTo(true);
-        assertThat(mProficiencyAnalyzer.shouldShowTranslation(NON_SYSTEM_LANGUAGE)).isEqualTo(true);
-    }
-
-    @Test
-    public void shouldShowTranslation_enoughFeedback_true() {
-        sendEvent(
-                TextClassifierEvent.TYPE_ACTIONS_SHOWN, PRIMARY_SYSTEM_LANGUAGE, /* times= */ 1000);
-        sendEvent(TextClassifierEvent.TYPE_SMART_ACTION, PRIMARY_SYSTEM_LANGUAGE, /* times= */ 200);
-
-        assertThat(mProficiencyAnalyzer.shouldShowTranslation(PRIMARY_SYSTEM_LANGUAGE))
-                .isEqualTo(true);
-    }
-
-    @Test
-    public void shouldShowTranslation_enoughFeedback_false() {
-        sendEvent(
-                TextClassifierEvent.TYPE_ACTIONS_SHOWN, PRIMARY_SYSTEM_LANGUAGE, /* times= */ 1000);
-        sendEvent(
-                TextClassifierEvent.TYPE_SMART_ACTION, PRIMARY_SYSTEM_LANGUAGE, /* times= */ 1000);
-
-        assertThat(mProficiencyAnalyzer.shouldShowTranslation(PRIMARY_SYSTEM_LANGUAGE))
-                .isEqualTo(false);
-    }
-
-    private void sendEvent(int type, String languageTag, int times) {
-        TextClassifierEvent.LanguageDetectionEvent event =
-                new TextClassifierEvent.LanguageDetectionEvent.Builder(type)
-                        .setEntityTypes(languageTag)
-                        .setActionIndices(0)
-                        .build();
-        for (int i = 0; i < times; i++) {
-            mProficiencyAnalyzer.onTextClassifierEvent(event);
-        }
-    }
-}
diff --git a/java/tests/unittests/src/com/android/textclassifier/ulp/SystemLanguagesProviderTest.java b/java/tests/unittests/src/com/android/textclassifier/ulp/SystemLanguagesProviderTest.java
deleted file mode 100644
index 8117bdd..0000000
--- a/java/tests/unittests/src/com/android/textclassifier/ulp/SystemLanguagesProviderTest.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2019 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.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * 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.
- */
-
-package com.android.textclassifier.ulp;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.content.res.Resources;
-import android.os.LocaleList;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import java.util.List;
-import java.util.Locale;
-
-@SmallTest
-public class SystemLanguagesProviderTest {
-    private SystemLanguagesProvider mSystemLanguagesProvider;
-
-    @Before
-    public void setup() {
-        mSystemLanguagesProvider = new SystemLanguagesProvider();
-    }
-
-    @Test
-    public void getSystemLanguageTags_singleLanguages() {
-        Resources.getSystem().getConfiguration().setLocales(new LocaleList(Locale.FRANCE));
-
-        List<String> systemLanguageTags = mSystemLanguagesProvider.getSystemLanguageTags();
-
-        assertThat(systemLanguageTags).containsExactly("fr");
-    }
-
-    @Test
-    public void getSystemLanguageTags_multipleLanguages() {
-        Resources.getSystem()
-                .getConfiguration()
-                .setLocales(new LocaleList(Locale.FRANCE, Locale.ENGLISH));
-
-        List<String> systemLanguageTags = mSystemLanguagesProvider.getSystemLanguageTags();
-
-        assertThat(systemLanguageTags).containsExactly("fr", "en");
-    }
-}
