Merge "Add emoji icon and code as a groundwork"
diff --git a/java/res/layout/input_view.xml b/java/res/layout/input_view.xml
index 136e18c..1ffb8a3 100644
--- a/java/res/layout/input_view.xml
+++ b/java/res/layout/input_view.xml
@@ -30,34 +30,17 @@
         android:layout_width="match_parent"
         android:layout_height="0dp" />
 
-    <!-- On tablets, the suggestions strip is centered with horizontal paddings on both sides
-         because width of the landscape mode is too long for the suggestions strip. This
-         LinearLayout is required to hold the paddings. -->
-    <LinearLayout
-        android:id="@+id/suggestions_container"
-        android:orientation="horizontal"
+    <!-- To ensure that key preview popup is correctly placed when the current system locale is
+         one of RTL locales, layoutDirection="ltr" is needed in the SDK version 17+. -->
+    <com.android.inputmethod.latin.suggestions.SuggestionStripView
+        android:id="@+id/suggestion_strip_view"
+        android:layoutDirection="ltr"
         android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-    >
-        <View
-            android:layout_width="@dimen/suggestions_strip_padding"
-            android:layout_height="@dimen/suggestions_strip_height"
-            style="?attr/suggestionsStripBackgroundStyle" />
-        <!-- To ensure that key preview popup is correctly placed when the current system locale is
-             one of RTL locales, layoutDirection="ltr" is needed in the SDK version 17+. -->
-        <com.android.inputmethod.latin.suggestions.SuggestionStripView
-            android:id="@+id/suggestion_strip_view"
-            android:layoutDirection="ltr"
-            android:layout_weight="1.0"
-            android:layout_width="0dp"
-            android:layout_height="@dimen/suggestions_strip_height"
-            android:gravity="center_vertical"
-            style="?attr/suggestionStripViewStyle" />
-        <View
-            android:layout_width="@dimen/suggestions_strip_padding"
-            android:layout_height="@dimen/suggestions_strip_height"
-            style="?attr/suggestionsStripBackgroundStyle" />
-    </LinearLayout>
+        android:layout_height="@dimen/suggestions_strip_height"
+        android:gravity="center_vertical"
+        android:paddingRight="@dimen/suggestions_strip_padding"
+        android:paddingLeft="@dimen/suggestions_strip_padding"
+        style="?attr/suggestionStripViewStyle" />
 
     <!-- To ensure that key preview popup is correctly placed when the current system locale is
          one of RTL locales, layoutDirection="ltr" is needed in the SDK version 17+. -->
diff --git a/java/res/values/attrs.xml b/java/res/values/attrs.xml
index b8a84e3..eef9116 100644
--- a/java/res/values/attrs.xml
+++ b/java/res/values/attrs.xml
@@ -28,7 +28,6 @@
         <attr name="moreKeysKeyboardViewStyle" format="reference" />
         <attr name="moreKeysKeyboardPanelStyle" format="reference" />
         <!-- Suggestions strip style -->
-        <attr name="suggestionsStripBackgroundStyle" format="reference" />
         <attr name="suggestionStripViewStyle" format="reference" />
         <attr name="moreSuggestionsViewStyle" format="reference" />
         <attr name="suggestionBackgroundStyle" format="reference" />
diff --git a/java/res/values/styles.xml b/java/res/values/styles.xml
index 8b6c29e..37c6a95 100644
--- a/java/res/values/styles.xml
+++ b/java/res/values/styles.xml
@@ -145,13 +145,10 @@
     <style name="MoreKeysKeyboardPanelStyle">
         <item name="android:background">@drawable/keyboard_popup_panel_background</item>
     </style>
-    <style name="SuggestionsStripBackgroundStyle">
-        <item name="android:background">@drawable/keyboard_suggest_strip</item>
-    </style>
     <style
         name="SuggestionStripViewStyle"
-        parent="SuggestionsStripBackgroundStyle"
     >
+        <item name="android:background">@drawable/keyboard_suggest_strip</item>
         <item name="suggestionStripOption">autoCorrectBold|validTypedWordBold</item>
         <item name="colorValidTypedWord">@color/highlight_color_default</item>
         <item name="colorTypedWord">@color/typed_word_color_default</item>
@@ -380,13 +377,10 @@
     <style name="MoreKeysKeyboardPanelStyle.IceCreamSandwich">
         <item name="android:background">@drawable/keyboard_popup_panel_background_holo</item>
     </style>
-    <style name="SuggestionsStripBackgroundStyle.IceCreamSandwich">
-        <item name="android:background">@drawable/keyboard_suggest_strip_holo</item>
-    </style>
     <style
         name="SuggestionStripViewStyle.IceCreamSandwich"
-        parent="SuggestionsStripBackgroundStyle.IceCreamSandwich"
     >
+        <item name="android:background">@drawable/keyboard_suggest_strip_holo</item>
         <item name="suggestionStripOption">autoCorrectBold|validTypedWordBold</item>
         <item name="colorValidTypedWord">@color/highlight_color_ics</item>
         <item name="colorTypedWord">@color/highlight_color_ics</item>
diff --git a/java/res/values/themes-basic-highcontrast.xml b/java/res/values/themes-basic-highcontrast.xml
index 48df0a1..e81d473 100644
--- a/java/res/values/themes-basic-highcontrast.xml
+++ b/java/res/values/themes-basic-highcontrast.xml
@@ -22,7 +22,6 @@
         <item name="moreKeysKeyboardStyle">@style/MoreKeysKeyboard</item>
         <item name="moreKeysKeyboardViewStyle">@style/MoreKeysKeyboardView</item>
         <item name="moreKeysKeyboardPanelStyle">@style/MoreKeysKeyboardPanelStyle</item>
-        <item name="suggestionsStripBackgroundStyle">@style/SuggestionsStripBackgroundStyle</item>
         <item name="suggestionStripViewStyle">@style/SuggestionStripViewStyle</item>
         <item name="moreSuggestionsViewStyle">@style/MoreSuggestionsViewStyle</item>
         <item name="suggestionBackgroundStyle">@style/SuggestionBackgroundStyle</item>
diff --git a/java/res/values/themes-basic.xml b/java/res/values/themes-basic.xml
index 88a0c5d..c44f0f6 100644
--- a/java/res/values/themes-basic.xml
+++ b/java/res/values/themes-basic.xml
@@ -22,7 +22,6 @@
         <item name="moreKeysKeyboardStyle">@style/MoreKeysKeyboard</item>
         <item name="moreKeysKeyboardViewStyle">@style/MoreKeysKeyboardView</item>
         <item name="moreKeysKeyboardPanelStyle">@style/MoreKeysKeyboardPanelStyle</item>
-        <item name="suggestionsStripBackgroundStyle">@style/SuggestionsStripBackgroundStyle</item>
         <item name="suggestionStripViewStyle">@style/SuggestionStripViewStyle</item>
         <item name="moreSuggestionsViewStyle">@style/MoreSuggestionsViewStyle</item>
         <item name="suggestionBackgroundStyle">@style/SuggestionBackgroundStyle</item>
diff --git a/java/res/values/themes-gingerbread.xml b/java/res/values/themes-gingerbread.xml
index 51f680a..129afdf 100644
--- a/java/res/values/themes-gingerbread.xml
+++ b/java/res/values/themes-gingerbread.xml
@@ -22,7 +22,6 @@
         <item name="moreKeysKeyboardStyle">@style/MoreKeysKeyboard.Gingerbread</item>
         <item name="moreKeysKeyboardViewStyle">@style/MoreKeysKeyboardView.Gingerbread</item>
         <item name="moreKeysKeyboardPanelStyle">@style/MoreKeysKeyboardPanelStyle</item>
-        <item name="suggestionsStripBackgroundStyle">@style/SuggestionsStripBackgroundStyle</item>
         <item name="suggestionStripViewStyle">@style/SuggestionStripViewStyle</item>
         <item name="moreSuggestionsViewStyle">@style/MoreSuggestionsViewStyle</item>
         <item name="suggestionBackgroundStyle">@style/SuggestionBackgroundStyle</item>
diff --git a/java/res/values/themes-ics.xml b/java/res/values/themes-ics.xml
index d9c59a1..1264831 100644
--- a/java/res/values/themes-ics.xml
+++ b/java/res/values/themes-ics.xml
@@ -22,7 +22,6 @@
         <item name="moreKeysKeyboardStyle">@style/MoreKeysKeyboard.IceCreamSandwich</item>
         <item name="moreKeysKeyboardViewStyle">@style/MoreKeysKeyboardView.IceCreamSandwich</item>
         <item name="moreKeysKeyboardPanelStyle">@style/MoreKeysKeyboardPanelStyle.IceCreamSandwich</item>
-        <item name="suggestionsStripBackgroundStyle">@style/SuggestionsStripBackgroundStyle.IceCreamSandwich</item>
         <item name="suggestionStripViewStyle">@style/SuggestionStripViewStyle.IceCreamSandwich</item>
         <item name="moreSuggestionsViewStyle">@style/MoreSuggestionsViewStyle.IceCreamSandwich</item>
         <item name="suggestionBackgroundStyle">@style/SuggestionBackgroundStyle.IceCreamSandwich</item>
diff --git a/java/res/values/themes-stone-bold.xml b/java/res/values/themes-stone-bold.xml
index 6ace9d6..196f3ef 100644
--- a/java/res/values/themes-stone-bold.xml
+++ b/java/res/values/themes-stone-bold.xml
@@ -22,7 +22,6 @@
         <item name="moreKeysKeyboardStyle">@style/MoreKeysKeyboard.Stone</item>
         <item name="moreKeysKeyboardViewStyle">@style/MoreKeysKeyboardView.Stone</item>
         <item name="moreKeysKeyboardPanelStyle">@style/MoreKeysKeyboardPanelStyle</item>
-        <item name="suggestionsStripBackgroundStyle">@style/SuggestionsStripBackgroundStyle</item>
         <item name="suggestionStripViewStyle">@style/SuggestionStripViewStyle</item>
         <item name="moreSuggestionsViewStyle">@style/MoreSuggestionsViewStyle</item>
         <item name="suggestionBackgroundStyle">@style/SuggestionBackgroundStyle</item>
diff --git a/java/res/values/themes-stone.xml b/java/res/values/themes-stone.xml
index 3c3826b..d0d35c2 100644
--- a/java/res/values/themes-stone.xml
+++ b/java/res/values/themes-stone.xml
@@ -22,7 +22,6 @@
         <item name="moreKeysKeyboardStyle">@style/MoreKeysKeyboard.Stone</item>
         <item name="moreKeysKeyboardViewStyle">@style/MoreKeysKeyboardView.Stone</item>
         <item name="moreKeysKeyboardPanelStyle">@style/MoreKeysKeyboardPanelStyle</item>
-        <item name="suggestionsStripBackgroundStyle">@style/SuggestionsStripBackgroundStyle</item>
         <item name="suggestionStripViewStyle">@style/SuggestionStripViewStyle</item>
         <item name="moreSuggestionsViewStyle">@style/MoreSuggestionsViewStyle</item>
         <item name="suggestionBackgroundStyle">@style/SuggestionBackgroundStyle</item>
diff --git a/java/src/com/android/inputmethod/latin/InputView.java b/java/src/com/android/inputmethod/latin/InputView.java
index 5359c81..1cf17c8 100644
--- a/java/src/com/android/inputmethod/latin/InputView.java
+++ b/java/src/com/android/inputmethod/latin/InputView.java
@@ -24,7 +24,7 @@
 import android.widget.LinearLayout;
 
 public final class InputView extends LinearLayout {
-    private View mSuggestionStripContainer;
+    private View mSuggestionStripView;
     private View mKeyboardView;
     private int mKeyboardTopPadding;
 
@@ -43,13 +43,13 @@
 
     @Override
     protected void onFinishInflate() {
-        mSuggestionStripContainer = findViewById(R.id.suggestions_container);
+        mSuggestionStripView = findViewById(R.id.suggestion_strip_view);
         mKeyboardView = findViewById(R.id.keyboard_view);
     }
 
     @Override
     public boolean dispatchTouchEvent(MotionEvent me) {
-        if (mSuggestionStripContainer.getVisibility() == VISIBLE
+        if (mSuggestionStripView.getVisibility() == VISIBLE
                 && mKeyboardView.getVisibility() == VISIBLE
                 && forwardTouchEvent(me)) {
             return true;
@@ -97,7 +97,7 @@
         }
 
         final Rect receivingRect = mEventReceivingRect;
-        mSuggestionStripContainer.getGlobalVisibleRect(receivingRect);
+        mSuggestionStripView.getGlobalVisibleRect(receivingRect);
         final int translatedX = x - receivingRect.left;
         final int translatedY;
         if (y < forwardingLimitY) {
@@ -107,7 +107,7 @@
             translatedY = y - receivingRect.top;
         }
         me.setLocation(translatedX, translatedY);
-        mSuggestionStripContainer.dispatchTouchEvent(me);
+        mSuggestionStripView.dispatchTouchEvent(me);
         return true;
     }
 }
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index 0ba1bd4..d970bca 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -152,7 +152,6 @@
 
     private View mExtractArea;
     private View mKeyPreviewBackingView;
-    private View mSuggestionsContainer;
     private SuggestionStripView mSuggestionStripView;
     // Never null
     private SuggestedWords mSuggestedWords = SuggestedWords.EMPTY;
@@ -667,7 +666,6 @@
         mExtractArea = getWindow().getWindow().getDecorView()
                 .findViewById(android.R.id.extractArea);
         mKeyPreviewBackingView = view.findViewById(R.id.key_preview_backing);
-        mSuggestionsContainer = view.findViewById(R.id.suggestions_container);
         mSuggestionStripView = (SuggestionStripView)view.findViewById(R.id.suggestion_strip_view);
         if (mSuggestionStripView != null)
             mSuggestionStripView.setListener(this, view);
@@ -1111,17 +1109,17 @@
     private void setSuggestionStripShownInternal(final boolean shown,
             final boolean needsInputViewShown) {
         // TODO: Modify this if we support suggestions with hard keyboard
-        if (onEvaluateInputViewShown() && mSuggestionsContainer != null) {
+        if (onEvaluateInputViewShown() && mSuggestionStripView != null) {
             final MainKeyboardView mainKeyboardView = mKeyboardSwitcher.getMainKeyboardView();
             final boolean inputViewShown = (mainKeyboardView != null)
                     ? mainKeyboardView.isShown() : false;
             final boolean shouldShowSuggestions = shown
                     && (needsInputViewShown ? inputViewShown : true);
             if (isFullscreenMode()) {
-                mSuggestionsContainer.setVisibility(
+                mSuggestionStripView.setVisibility(
                         shouldShowSuggestions ? View.VISIBLE : View.GONE);
             } else {
-                mSuggestionsContainer.setVisibility(
+                mSuggestionStripView.setVisibility(
                         shouldShowSuggestions ? View.VISIBLE : View.INVISIBLE);
             }
         }
@@ -1142,7 +1140,7 @@
             return 0;
         }
         final int keyboardHeight = mainKeyboardView.getHeight();
-        final int suggestionsHeight = mSuggestionsContainer.getHeight();
+        final int suggestionsHeight = mSuggestionStripView.getHeight();
         final int displayHeight = getResources().getDisplayMetrics().heightPixels;
         final Rect rect = new Rect();
         mKeyPreviewBackingView.getWindowVisibleDisplayFrame(rect);
@@ -1160,7 +1158,7 @@
     public void onComputeInsets(final InputMethodService.Insets outInsets) {
         super.onComputeInsets(outInsets);
         final MainKeyboardView mainKeyboardView = mKeyboardSwitcher.getMainKeyboardView();
-        if (mainKeyboardView == null || mSuggestionsContainer == null) {
+        if (mainKeyboardView == null || mSuggestionStripView == null) {
             return;
         }
         final int adjustedBackingHeight = getAdjustedBackingViewHeight();
@@ -1170,13 +1168,13 @@
         // be considered.
         // See {@link android.inputmethodservice.InputMethodService#onComputeInsets}.
         final int extractHeight = isFullscreenMode() ? mExtractArea.getHeight() : 0;
-        final int suggestionsHeight = (mSuggestionsContainer.getVisibility() == View.GONE) ? 0
-                : mSuggestionsContainer.getHeight();
+        final int suggestionsHeight = (mSuggestionStripView.getVisibility() == View.GONE) ? 0
+                : mSuggestionStripView.getHeight();
         final int extraHeight = extractHeight + backingHeight + suggestionsHeight;
         int visibleTopY = extraHeight;
         // Need to set touchable region only if input view is being shown
         if (mainKeyboardView.isShown()) {
-            if (mSuggestionsContainer.getVisibility() == View.VISIBLE) {
+            if (mSuggestionStripView.getVisibility() == View.VISIBLE) {
                 visibleTopY -= suggestionsHeight;
             }
             final int touchY = mainKeyboardView.isShowingMoreKeysPanel() ? 0 : visibleTopY;
diff --git a/native/jni/Android.mk b/native/jni/Android.mk
index acd230f..e14cf5a 100644
--- a/native/jni/Android.mk
+++ b/native/jni/Android.mk
@@ -71,7 +71,9 @@
     suggest/core/policy/weighting.cpp \
     suggest/core/session/dic_traverse_session.cpp \
     $(addprefix suggest/policyimpl/dictionary/, \
+        dynamic_patricia_trie_node_reader.cpp \
         dynamic_patricia_trie_policy.cpp \
+        dynamic_patricia_trie_reading_utils.cpp \
         patricia_trie_policy.cpp \
         patricia_trie_reading_utils.cpp) \
     suggest/policyimpl/gesture/gesture_suggest_policy_factory.cpp \
diff --git a/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_node_reader.cpp b/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_node_reader.cpp
new file mode 100644
index 0000000..20cda91
--- /dev/null
+++ b/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_node_reader.cpp
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2013, 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.
+ */
+
+#include "suggest/policyimpl/dictionary/dynamic_patricia_trie_node_reader.h"
+
+#include "suggest/core/dictionary/binary_dictionary_info.h"
+#include "suggest/core/dictionary/binary_dictionary_terminal_attributes_reading_utils.h"
+#include "suggest/policyimpl/dictionary/dynamic_patricia_trie_reading_utils.h"
+
+namespace latinime {
+
+void DynamicPatriciaTrieNodeReader::fetchNodeInfoFromBufferAndProcessMovedNode(const int nodePos,
+        const int maxCodePointCount, int *const outCodePoints) {
+    const uint8_t *const dictRoot = mBinaryDictionaryInfo->getDictRoot();
+    int pos = nodePos;
+    mFlags = PatriciaTrieReadingUtils::getFlagsAndAdvancePosition(dictRoot, &pos);
+    mParentPos = DynamicPatriciaTrieReadingUtils::getParentPosAndAdvancePosition(dictRoot, &pos);
+    if (outCodePoints != 0) {
+        mCodePointCount = PatriciaTrieReadingUtils::getCharsAndAdvancePosition(
+                dictRoot, mFlags, maxCodePointCount, outCodePoints, &pos);
+    } else {
+        mCodePointCount = PatriciaTrieReadingUtils::skipCharacters(
+                dictRoot, mFlags, MAX_WORD_LENGTH, &pos);
+    }
+    if (isTerminal()) {
+        mProbability = PatriciaTrieReadingUtils::readProbabilityAndAdvancePosition(dictRoot, &pos);
+    } else {
+        mProbability = NOT_A_PROBABILITY;
+    }
+    if (hasChildren()) {
+        mChildrenPos = DynamicPatriciaTrieReadingUtils::readChildrenPositionAndAdvancePosition(
+                dictRoot, mFlags, &pos);
+    } else {
+        mChildrenPos = NOT_A_DICT_POS;
+    }
+    if (PatriciaTrieReadingUtils::hasShortcutTargets(mFlags)) {
+        mShortcutPos = pos;
+        BinaryDictionaryTerminalAttributesReadingUtils::skipShortcuts(mBinaryDictionaryInfo, &pos);
+    } else {
+        mShortcutPos = NOT_A_DICT_POS;
+    }
+    if (PatriciaTrieReadingUtils::hasBigrams(mFlags)) {
+        mBigramPos = pos;
+        BinaryDictionaryTerminalAttributesReadingUtils::skipExistingBigrams(
+                mBinaryDictionaryInfo, &pos);
+    } else {
+        mBigramPos = NOT_A_DICT_POS;
+    }
+    // Update siblingPos if needed.
+    if (mSiblingPos == NOT_A_VALID_WORD_POS) {
+        // Sibling position is the tail position of current node.
+        mSiblingPos = pos;
+    }
+    // Read destination node if the read node is a moved node.
+    if (DynamicPatriciaTrieReadingUtils::isMoved(mFlags)) {
+        // The destination position is stored at the same place as the parent position.
+        fetchNodeInfoFromBufferAndProcessMovedNode(mParentPos, maxCodePointCount, outCodePoints);
+    }
+}
+
+}
diff --git a/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_node_reader.h b/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_node_reader.h
new file mode 100644
index 0000000..b668aab
--- /dev/null
+++ b/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_node_reader.h
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2013, 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.
+ */
+
+#ifndef LATINIME_DYNAMIC_PATRICIA_TRIE_NODE_READER_H
+#define LATINIME_DYNAMIC_PATRICIA_TRIE_NODE_READER_H
+
+#include "defines.h"
+#include "suggest/policyimpl/dictionary/dynamic_patricia_trie_reading_utils.h"
+#include "suggest/policyimpl/dictionary/patricia_trie_reading_utils.h"
+
+namespace latinime {
+
+class BinaryDictionaryInfo;
+
+/*
+ * This class is used for helping to read nodes of dynamic patricia trie. This class handles moved
+ * node and reads node attributes.
+ */
+class DynamicPatriciaTrieNodeReader {
+ public:
+    explicit DynamicPatriciaTrieNodeReader(const BinaryDictionaryInfo *const binaryDictionaryInfo)
+            : mBinaryDictionaryInfo(binaryDictionaryInfo), mNodePos(NOT_A_VALID_WORD_POS),
+              mFlags(0), mParentPos(NOT_A_DICT_POS), mCodePointCount(0),
+              mProbability(NOT_A_PROBABILITY), mChildrenPos(NOT_A_DICT_POS),
+              mShortcutPos(NOT_A_DICT_POS), mBigramPos(NOT_A_DICT_POS),
+              mSiblingPos(NOT_A_VALID_WORD_POS) {}
+
+    ~DynamicPatriciaTrieNodeReader() {}
+
+    // Reads node information from dictionary buffer and updates members with the information.
+    AK_FORCE_INLINE void fetchNodeInfoFromBuffer(const int nodePos) {
+        fetchNodeInfoFromBufferAndGetNodeCodePoints(mNodePos , 0 /* maxCodePointCount */,
+                0 /* outCodePoints */);
+    }
+
+    AK_FORCE_INLINE void fetchNodeInfoFromBufferAndGetNodeCodePoints(const int nodePos,
+            const int maxCodePointCount, int *const outCodePoints) {
+        mNodePos = nodePos;
+        mSiblingPos = NOT_A_VALID_WORD_POS;
+        fetchNodeInfoFromBufferAndProcessMovedNode(mNodePos, maxCodePointCount, outCodePoints);
+    }
+
+    AK_FORCE_INLINE int getNodePos() const {
+        return mNodePos;
+    }
+
+    // Flags
+    AK_FORCE_INLINE bool isDeleted() const {
+        return DynamicPatriciaTrieReadingUtils::isDeleted(mFlags);
+    }
+
+    AK_FORCE_INLINE bool hasChildren() const {
+        return PatriciaTrieReadingUtils::hasChildrenInFlags(mFlags);
+    }
+
+    AK_FORCE_INLINE bool isTerminal() const {
+        return PatriciaTrieReadingUtils::isTerminal(mFlags);
+    }
+
+    AK_FORCE_INLINE bool isBlacklisted() const {
+        return PatriciaTrieReadingUtils::isBlacklisted(mFlags);
+    }
+
+    AK_FORCE_INLINE bool isNotAWord() const {
+        return PatriciaTrieReadingUtils::isNotAWord(mFlags);
+    }
+
+    // Parent node position
+    AK_FORCE_INLINE int getParentPos() const {
+        return mParentPos;
+    }
+
+    // Number of code points
+    AK_FORCE_INLINE uint8_t getCodePointCount() const {
+        return mCodePointCount;
+    }
+
+    // Probability
+    AK_FORCE_INLINE int getProbability() const {
+        return mProbability;
+    }
+
+    // Children node group position
+    AK_FORCE_INLINE int getChildrenPos() const {
+        return mChildrenPos;
+    }
+
+    // Shortcutlist position
+    AK_FORCE_INLINE int getShortcutPos() const {
+        return mShortcutPos;
+    }
+
+    // Bigrams position
+    AK_FORCE_INLINE int getBigramsPos() const {
+        return mBigramPos;
+    }
+
+    // Sibling node position
+    AK_FORCE_INLINE int getSiblingNodePos() const {
+        return mSiblingPos;
+    }
+
+ private:
+    DISALLOW_COPY_AND_ASSIGN(DynamicPatriciaTrieNodeReader);
+
+    const BinaryDictionaryInfo *const mBinaryDictionaryInfo;
+    int mNodePos;
+    DynamicPatriciaTrieReadingUtils::NodeFlags mFlags;
+    int mParentPos;
+    uint8_t mCodePointCount;
+    int mProbability;
+    int mChildrenPos;
+    int mShortcutPos;
+    int mBigramPos;
+    int mSiblingPos;
+
+    void fetchNodeInfoFromBufferAndProcessMovedNode(const int nodePos, const int maxCodePointCount,
+            int *const outCodePoints);
+};
+} // namespace latinime
+#endif /* LATINIME_DYNAMIC_PATRICIA_TRIE_NODE_READER_H */
diff --git a/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_policy.cpp b/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_policy.cpp
index c7314ec..17cbdde 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_policy.cpp
+++ b/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_policy.cpp
@@ -20,6 +20,9 @@
 #include "suggest/core/dicnode/dic_node.h"
 #include "suggest/core/dicnode/dic_node_vector.h"
 #include "suggest/core/dictionary/binary_dictionary_info.h"
+#include "suggest/policyimpl/dictionary/dynamic_patricia_trie_node_reader.h"
+#include "suggest/policyimpl/dictionary/dynamic_patricia_trie_reading_utils.h"
+#include "suggest/policyimpl/dictionary/patricia_trie_reading_utils.h"
 
 namespace latinime {
 
@@ -28,7 +31,31 @@
 void DynamicPatriciaTriePolicy::createAndGetAllChildNodes(const DicNode *const dicNode,
         const BinaryDictionaryInfo *const binaryDictionaryInfo,
         const NodeFilter *const nodeFilter, DicNodeVector *const childDicNodes) const {
-    // TODO: Implement.
+    if (!dicNode->hasChildren()) {
+        return;
+    }
+    DynamicPatriciaTrieNodeReader nodeReader(binaryDictionaryInfo);
+    int mergedNodeCodePoints[MAX_WORD_LENGTH];
+    int nextPos = dicNode->getChildrenPos();
+    do {
+        const int childCount = PatriciaTrieReadingUtils::getGroupCountAndAdvancePosition(
+                binaryDictionaryInfo->getDictRoot(), &nextPos);
+        for (int i = 0; i < childCount; i++) {
+            nodeReader.fetchNodeInfoFromBufferAndGetNodeCodePoints(nextPos, MAX_WORD_LENGTH,
+                    mergedNodeCodePoints);
+            if (!nodeReader.isDeleted() && !nodeFilter->isFilteredOut(mergedNodeCodePoints[0])) {
+                // Push child note when the node is not deleted and not filtered out.
+                childDicNodes->pushLeavingChild(dicNode, nodeReader.getNodePos(),
+                        nodeReader.getChildrenPos(), nodeReader.getProbability(),
+                        nodeReader.isTerminal(), nodeReader.hasChildren(),
+                        nodeReader.isBlacklisted() || nodeReader.isNotAWord(),
+                        nodeReader.getCodePointCount(), mergedNodeCodePoints);
+            }
+            nextPos = nodeReader.getSiblingNodePos();
+        }
+        nextPos = DynamicPatriciaTrieReadingUtils::getForwardLinkPosition(
+                binaryDictionaryInfo->getDictRoot(), nextPos);
+    } while(DynamicPatriciaTrieReadingUtils::isValidForwardLinkPosition(nextPos));
 }
 
 int DynamicPatriciaTriePolicy::getCodePointsAndProbabilityAndReturnCodePointCount(
@@ -48,22 +75,34 @@
 
 int DynamicPatriciaTriePolicy::getUnigramProbability(
         const BinaryDictionaryInfo *const binaryDictionaryInfo, const int nodePos) const {
-    // TODO: Implement.
-    return NOT_A_PROBABILITY;
+    DynamicPatriciaTrieNodeReader nodeReader(binaryDictionaryInfo);
+    nodeReader.fetchNodeInfoFromBuffer(nodePos);
+    if (nodeReader.isDeleted() || nodeReader.isBlacklisted() || nodeReader.isNotAWord()) {
+        return NOT_A_PROBABILITY;
+    }
+    return nodeReader.getProbability();
 }
 
 int DynamicPatriciaTriePolicy::getShortcutPositionOfNode(
         const BinaryDictionaryInfo *const binaryDictionaryInfo,
         const int nodePos) const {
-    // TODO: Implement.
-    return NOT_A_DICT_POS;
+    DynamicPatriciaTrieNodeReader nodeReader(binaryDictionaryInfo);
+    nodeReader.fetchNodeInfoFromBuffer(nodePos);
+    if (nodeReader.isDeleted()) {
+        return NOT_A_DICT_POS;
+    }
+    return nodeReader.getShortcutPos();
 }
 
 int DynamicPatriciaTriePolicy::getBigramsPositionOfNode(
         const BinaryDictionaryInfo *const binaryDictionaryInfo,
         const int nodePos) const {
-    // TODO: Implement.
-    return NOT_A_DICT_POS;
+    DynamicPatriciaTrieNodeReader nodeReader(binaryDictionaryInfo);
+    nodeReader.fetchNodeInfoFromBuffer(nodePos);
+    if (nodeReader.isDeleted()) {
+        return NOT_A_DICT_POS;
+    }
+    return nodeReader.getBigramsPos();
 }
 
 } // namespace latinime