diff --git a/native/jni/Android.mk b/native/jni/Android.mk
index 2c5401ba59ff109a0d4b979dcdca20949ff5630b..62ac0dae25e26f10da6579fa5e109b26178a7757 100644
--- a/native/jni/Android.mk
+++ b/native/jni/Android.mk
@@ -90,8 +90,6 @@ LATIN_IME_CORE_SRC_FILES := \
         dynamic_patricia_trie_writing_helper.cpp \
         dynamic_patricia_trie_writing_utils.cpp) \
     $(addprefix suggest/policyimpl/dictionary/structure/v4/, \
-        content/bigram_dict_content.cpp \
-        content/sparse_table_dict_content.cpp \
         ver4_dict_buffers.cpp \
         ver4_dict_constants.cpp \
         ver4_patricia_trie_node_reader.cpp \
@@ -99,6 +97,10 @@ LATIN_IME_CORE_SRC_FILES := \
         ver4_patricia_trie_policy.cpp \
         ver4_patricia_trie_reading_utils.cpp \
         ver4_patricia_trie_writing_helper.cpp) \
+    $(addprefix suggest/policyimpl/dictionary/structure/v4/content/, \
+        bigram_dict_content.cpp \
+        shortcut_dict_content.cpp \
+        sparse_table_dict_content.cpp) \
     $(addprefix suggest/policyimpl/dictionary/utils/, \
         buffer_with_extendable_buffer.cpp \
         byte_array_utils.cpp \
diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/shortcut_dict_content.cpp b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/shortcut_dict_content.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..f09bd4409e9b901da3b5fb336fcfe3d54bde62bb
--- /dev/null
+++ b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/shortcut_dict_content.cpp
@@ -0,0 +1,84 @@
+/*
+ * 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/structure/v4/content/shortcut_dict_content.h"
+
+#include "suggest/policyimpl/dictionary/utils/buffer_with_extendable_buffer.h"
+
+namespace latinime {
+
+void ShortcutDictContent::getShortcutEntryAndAdvancePosition(const int maxCodePointCount,
+        int *const outCodePoint, int *const outCodePointCount, int *const outShortcutFlags,
+        int *const shortcutEntryPos) const {
+    const BufferWithExtendableBuffer *const shortcutListBuffer = getContentBuffer();
+    if (outShortcutFlags) {
+        *outShortcutFlags = shortcutListBuffer->readUintAndAdvancePosition(
+                Ver4DictConstants::SHORTCUT_FLAGS_FIELD_SIZE, shortcutEntryPos);
+    }
+    if (outCodePoint && outCodePointCount) {
+        shortcutListBuffer->readCodePointsAndAdvancePosition(
+                maxCodePointCount, outCodePoint, outCodePointCount, shortcutEntryPos);
+    }
+}
+
+int ShortcutDictContent::getShortcutListHeadPos(const int terminalId) const {
+    const SparseTable *const addressLookupTable = getAddressLookupTable();
+    if (!addressLookupTable->contains(terminalId)) {
+        return NOT_A_DICT_POS;
+    }
+    return addressLookupTable->get(terminalId);
+}
+
+bool ShortcutDictContent::flushToFile(const char *const dictDirPath) const {
+    return flush(dictDirPath, Ver4DictConstants::SHORTCUT_LOOKUP_TABLE_FILE_EXTENSION,
+            Ver4DictConstants::SHORTCUT_CONTENT_TABLE_FILE_EXTENSION,
+            Ver4DictConstants::SHORTCUT_FILE_EXTENSION);
+}
+
+bool ShortcutDictContent::copyShortcutList(const int shortcutListPos,
+        const ShortcutDictContent *const sourceShortcutDictContent, const int toPos) {
+    bool hasNext = true;
+    int readingPos = shortcutListPos;
+    int writingPos = toPos;
+    int codePoints[MAX_WORD_LENGTH];
+    while (hasNext) {
+        int shortcutFlags = 0;
+        int codePointCount = 0;
+        sourceShortcutDictContent->getShortcutEntryAndAdvancePosition(MAX_WORD_LENGTH,
+                codePoints, &codePointCount, &shortcutFlags, &readingPos);
+        if (!writeShortcutEntryAndAdvancePosition(codePoints, codePointCount, shortcutFlags,
+                &writingPos)) {
+            return false;
+        }
+    }
+    return true;
+}
+
+bool ShortcutDictContent::writeShortcutEntryAndAdvancePosition(const int *const codePoint,
+        const int codePointCount, const int shortcutFlags, int *const shortcutEntryPos) {
+    BufferWithExtendableBuffer *const shortcutListBuffer = getWritableContentBuffer();
+    if (!shortcutListBuffer->writeUintAndAdvancePosition(shortcutFlags,
+            Ver4DictConstants::SHORTCUT_FLAGS_FIELD_SIZE, shortcutEntryPos)) {
+        return false;
+    }
+    if (!shortcutListBuffer->writeCodePointsAndAdvancePosition(codePoint, codePointCount,
+            true /* writesTerminator */, shortcutEntryPos)) {
+        return false;
+    }
+    return true;
+}
+
+} // namespace latinime
diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/shortcut_dict_content.h b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/shortcut_dict_content.h
index b11e233387f37e2df59207662ab7bec12e59c32c..71a8f6b31d761c84b6c4b4248b423e5bad20d4ea 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/shortcut_dict_content.h
+++ b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/shortcut_dict_content.h
@@ -19,6 +19,7 @@
 
 #include "defines.h"
 #include "suggest/policyimpl/dictionary/structure/v4/content/sparse_table_dict_content.h"
+#include "suggest/policyimpl/dictionary/structure/v4/content/terminal_position_lookup_table.h"
 #include "suggest/policyimpl/dictionary/structure/v4/ver4_dict_constants.h"
 
 namespace latinime {
@@ -39,35 +40,21 @@ class ShortcutDictContent : public SparseTableDictContent {
 
     void getShortcutEntryAndAdvancePosition(const int maxCodePointCount,
             int *const outCodePoint, int *const outCodePointCount, int *const outShortcutFlags,
-            int *const shortcutEntryPos) const {
-        const BufferWithExtendableBuffer *const shortcutListBuffer = getContentBuffer();
-        if (outShortcutFlags) {
-            *outShortcutFlags = shortcutListBuffer->readUintAndAdvancePosition(
-                    Ver4DictConstants::SHORTCUT_FLAGS_FIELD_SIZE, shortcutEntryPos);
-        }
-        if (outCodePoint && outCodePointCount) {
-            shortcutListBuffer->readCodePointsAndAdvancePosition(
-                    maxCodePointCount, outCodePoint, outCodePointCount, shortcutEntryPos);
-        }
-    }
+            int *const shortcutEntryPos) const;
 
    // Returns head position of shortcut list for a PtNode specified by terminalId.
-   int getShortcutListHeadPos(const int terminalId) const {
-        const SparseTable *const addressLookupTable = getAddressLookupTable();
-        if (!addressLookupTable->contains(terminalId)) {
-            return NOT_A_DICT_POS;
-        }
-        return addressLookupTable->get(terminalId);
-    }
+   int getShortcutListHeadPos(const int terminalId) const;
 
-   bool flushToFile(const char *const dictDirPath) const {
-       return flush(dictDirPath, Ver4DictConstants::SHORTCUT_LOOKUP_TABLE_FILE_EXTENSION,
-               Ver4DictConstants::SHORTCUT_CONTENT_TABLE_FILE_EXTENSION,
-               Ver4DictConstants::SHORTCUT_FILE_EXTENSION);
-   }
+   bool flushToFile(const char *const dictDirPath) const;
 
  private:
     DISALLOW_COPY_AND_ASSIGN(ShortcutDictContent);
+
+    bool copyShortcutList(const int shortcutListPos,
+            const ShortcutDictContent *const sourceShortcutDictContent, const int toPos);
+
+    bool writeShortcutEntryAndAdvancePosition(const int *const codePoint,
+            const int codePointCount, const int shortcutFlags, int *const shortcutEntryPos);
 };
 } // namespace latinime
 #endif /* LATINIME_SHORTCUT_DICT_CONTENT_H */