public SuddenJumpingTouchEventHandler(Context context, ProcessMotionEvent view) {
   mView = view;
   mNeedsSuddenJumpingHack =
       Boolean.parseBoolean(
           Utils.getDeviceOverrideValue(
               context.getResources(), R.array.sudden_jumping_touch_event_device_list, "false"));
 }
 public DictAndProximity createDictAndProximity(final Locale locale) {
   final ProximityInfo proximityInfo = ProximityInfo.createSpellCheckerProximityInfo();
   final Resources resources = getResources();
   final int fallbackResourceId = Utils.getMainDictionaryResourceId(resources);
   final DictionaryCollection dictionaryCollection =
       DictionaryFactory.createDictionaryFromManager(
           this, locale, fallbackResourceId, USE_FULL_EDIT_DISTANCE_FLAG_ARRAY);
   final String localeStr = locale.toString();
   Dictionary userDictionary = mUserDictionaries.get(localeStr);
   if (null == userDictionary) {
     userDictionary = new SynchronouslyLoadedUserDictionary(this, localeStr, true);
     mUserDictionaries.put(localeStr, userDictionary);
   }
   dictionaryCollection.addDictionary(userDictionary);
   Dictionary whitelistDictionary = mWhitelistDictionaries.get(localeStr);
   if (null == whitelistDictionary) {
     whitelistDictionary = new WhitelistDictionary(this, locale);
     mWhitelistDictionaries.put(localeStr, whitelistDictionary);
   }
   dictionaryCollection.addDictionary(whitelistDictionary);
   if (null == mContactsDictionary) {
     mContactsDictionary = new SynchronouslyLoadedContactsDictionary(this);
   }
   // TODO: add a setting to use or not contacts when checking spelling
   dictionaryCollection.addDictionary(mContactsDictionary);
   return new DictAndProximity(dictionaryCollection, proximityInfo);
 }
    @Override
    public synchronized boolean addWord(
        char[] word, int wordOffset, int wordLength, int score, int dicTypeId, DataType dataType) {
      final int positionIndex = ArraysCompatUtils.binarySearch(mScores, 0, mLength, score);
      // binarySearch returns the index if the element exists, and -<insertion index> - 1
      // if it doesn't. See documentation for binarySearch.
      final int insertIndex = positionIndex >= 0 ? positionIndex : -positionIndex - 1;

      if (insertIndex == 0 && mLength >= mMaxLength) {
        // In the future, we may want to keep track of the best suggestion score even if
        // we are asked for 0 suggestions. In this case, we can use the following
        // (tested) code to keep it:
        // If the maxLength is 0 (should never be less, but if it is, it's treated as 0)
        // then we need to keep track of the best suggestion in mBestScore and
        // mBestSuggestion. This is so that we know whether the best suggestion makes
        // the score cutoff, since we need to know that to return a meaningful
        // looksLikeTypo.
        // if (0 >= mMaxLength) {
        //     if (score > mBestScore) {
        //         mBestScore = score;
        //         mBestSuggestion = new String(word, wordOffset, wordLength);
        //     }
        // }
        return true;
      }
      if (insertIndex >= mMaxLength) {
        // We found a suggestion, but its score is too weak to be kept considering
        // the suggestion limit.
        return true;
      }

      // Compute the normalized score and skip this word if it's normalized score does not
      // make the threshold.
      final String wordString = new String(word, wordOffset, wordLength);
      final double normalizedScore = Utils.calcNormalizedScore(mOriginalText, wordString, score);
      if (normalizedScore < mSuggestionThreshold) {
        if (DBG) Log.i(TAG, wordString + " does not make the score threshold");
        return true;
      }

      if (mLength < mMaxLength) {
        final int copyLen = mLength - insertIndex;
        ++mLength;
        System.arraycopy(mScores, insertIndex, mScores, insertIndex + 1, copyLen);
        mSuggestions.add(insertIndex, wordString);
      } else {
        System.arraycopy(mScores, 1, mScores, 0, insertIndex);
        mSuggestions.add(insertIndex, wordString);
        mSuggestions.remove(0);
      }
      mScores[insertIndex] = score;

      return true;
    }
    public Result getResults(final int capitalizeType, final Locale locale) {
      final String[] gatheredSuggestions;
      final boolean hasLikelySuggestions;
      if (0 == mLength) {
        // Either we found no suggestions, or we found some BUT the max length was 0.
        // If we found some mBestSuggestion will not be null. If it is null, then
        // we found none, regardless of the max length.
        if (null == mBestSuggestion) {
          gatheredSuggestions = null;
          hasLikelySuggestions = false;
        } else {
          gatheredSuggestions = EMPTY_STRING_ARRAY;
          final double normalizedScore =
              Utils.calcNormalizedScore(mOriginalText, mBestSuggestion, mBestScore);
          hasLikelySuggestions = (normalizedScore > mLikelyThreshold);
        }
      } else {
        if (DBG) {
          if (mLength != mSuggestions.size()) {
            Log.e(TAG, "Suggestion size is not the same as stored mLength");
          }
          for (int i = mLength - 1; i >= 0; --i) {
            Log.i(TAG, "" + mScores[i] + " " + mSuggestions.get(i));
          }
        }
        Collections.reverse(mSuggestions);
        Utils.removeDupes(mSuggestions);
        if (CAPITALIZE_ALL == capitalizeType) {
          for (int i = 0; i < mSuggestions.size(); ++i) {
            // get(i) returns a CharSequence which is actually a String so .toString()
            // should return the same object.
            mSuggestions.set(i, mSuggestions.get(i).toString().toUpperCase(locale));
          }
        } else if (CAPITALIZE_FIRST == capitalizeType) {
          for (int i = 0; i < mSuggestions.size(); ++i) {
            // Likewise
            mSuggestions.set(i, Utils.toTitleCase(mSuggestions.get(i).toString(), locale));
          }
        }
        // This returns a String[], while toArray() returns an Object[] which cannot be cast
        // into a String[].
        gatheredSuggestions = mSuggestions.toArray(EMPTY_STRING_ARRAY);

        final int bestScore = mScores[mLength - 1];
        final CharSequence bestSuggestion = mSuggestions.get(0);
        final double normalizedScore =
            Utils.calcNormalizedScore(mOriginalText, bestSuggestion, bestScore);
        hasLikelySuggestions = (normalizedScore > mLikelyThreshold);
        if (DBG) {
          Log.i(TAG, "Best suggestion : " + bestSuggestion + ", score " + bestScore);
          Log.i(
              TAG,
              "Normalized score = "
                  + normalizedScore
                  + " (threshold "
                  + mLikelyThreshold
                  + ") => hasLikelySuggestions = "
                  + hasLikelySuggestions);
        }
      }
      return new Result(gatheredSuggestions, hasLikelySuggestions);
    }