// Path: src/main/java/com/worksap/nlp/sudachi/WordId.java
// public class WordId {
//     private WordId() {
//     }
// 
//     /**
//      * Internal word ids can't be larger than this number
//      */
//     public static final int MAX_WORD_ID = 0x0fffffff;
// 
//     /**
//      * Dictionary ids can't be larger than this number
//      */
//     public static final int MAX_DIC_ID = 0xe;
// 
//     public static int makeUnchecked(int dic, int word) {
//         int dicPart = dic << 28;
//         return dicPart | word;
//     }
// 
//     /**
//      * Make combined WordId from dictionary and internal parts. This method does
//      * bound checking.
//      *
//      * @param dic
//      *            dictionary id. 0 is system, 1 and above are user.
//      * @param word
//      *            word id inside the dictionary.
//      * @return combined word id.
//      */
//     public static int make(int dic, int word) {
//         if (word > MAX_WORD_ID) {
//             throw new IndexOutOfBoundsException("wordId is too large: " + word);
//         }
//         if (dic > MAX_DIC_ID) {
//             throw new IndexOutOfBoundsException("dictionaryId is too large: " + dic);
//         }
//         return makeUnchecked(dic, word);
//     }
// 
//     /**
//      * Extract dictionary number from the combined word id
//      * 
//      * @param wordId
//      *            combined word id
//      * @return dictionary number
//      */
//     public static int dic(int wordId) {
//         return wordId >>> 28;
//     }
// 
//     /**
//      * Extract internal word id from the combined word id
//      * 
//      * @param wordId
//      *            combined word id
//      * @return internal word id
//      */
//     public static int word(int wordId) {
//         return wordId & MAX_WORD_ID;
//     }
// }
// 
// Path: src/main/java/com/worksap/nlp/sudachi/dictionary/Lexicon.java
// public interface Lexicon {
// 
//     Iterator<int[]> lookup(byte[] text, int offset);
// 
//     int getWordId(String headword, short posId, String readingForm);
// 
//     /**
//      * Returns the left-ID of the morpheme specified by the word ID.
//      *
//      * <p>
//      * when the word ID is out of range, the behavior is undefined.
//      *
//      * @param wordId
//      *            the word ID of the morpheme
//      * @return the left-ID of the morpheme
//      */
//     short getLeftId(int wordId);
// 
//     /**
//      * Returns the right-ID of the morpheme specified by the word ID.
//      *
//      * <p>
//      * when the word ID is out of range, the behavior is undefined.
//      *
//      * @param wordId
//      *            the word ID of the morpheme
//      * @return the right-ID of the morpheme.
//      */
//     short getRightId(int wordId);
// 
//     /**
//      * Returns the word occurrence cost of the morpheme specified by the word ID.
//      *
//      * <p>
//      * when the word ID is out of range, the behavior is undefined.
//      *
//      * @param wordId
//      *            the word ID of the morpheme
//      * @return the word occurrence cost
//      */
//     short getCost(int wordId);
// 
//     /**
//      * Returns the informations of the morpheme specified by the word ID.
//      *
//      * <p>
//      * when the word ID is out of range, the behavior is undefined.
//      *
//      * @param wordId
//      *            the word ID of the morpheme
//      * @return the informations of the morpheme
//      * @see WordInfo
//      */
//     WordInfo getWordInfo(int wordId);
// 
//     /**
//      * Returns the ID of the dictionary containing the morpheme specified by the
//      * word ID.
//      *
//      * If the morpheme is in the system dictionary, it returns {@code 0}.
//      *
//      * @param wordId
//      *            the word ID of the morpheme
//      * @return the dictionary ID
//      */
//     int getDictionaryId(int wordId);
// 
//     /**
//      * Returns the number of morphemes in the dictionary.
//      *
//      * @return the number of morphemes
//      */
//     int size();
// }


import com.worksap.nlp.sudachi.WordId;
import com.worksap.nlp.sudachi.dictionary.Lexicon;
import java.util.List;

        @Override
        public void validate(int wordId) {
            int word = WordId.word(wordId);
            if (word > prebuiltSize) {
                throw new IllegalArgumentException("WordId was larger than the number of dictionary entries");
            }
        }

        @Override
        public boolean isUser() {
            return false;
        }
    }

    public static class Chain implements WordIdResolver {
        private final WordIdResolver system;
        private final WordIdResolver user;

        public Chain(WordIdResolver system, WordIdResolver user) {
            this.system = system;
            this.user = user;
        }

        @Override
        public int lookup(String headword, short posId, String reading) {
            int wid = user.lookup(headword, posId, reading);
            if (wid == -1) {
                return system.lookup(headword, posId, reading);
            }
// Path: src/main/java/com/worksap/nlp/sudachi/WordId.java
// public class WordId {
//     private WordId() {
//     }
// 
//     /**
//      * Internal word ids can't be larger than this number
//      */
//     public static final int MAX_WORD_ID = 0x0fffffff;
// 
//     /**
//      * Dictionary ids can't be larger than this number
//      */
//     public static final int MAX_DIC_ID = 0xe;
// 
//     public static int makeUnchecked(int dic, int word) {
//         int dicPart = dic << 28;
//         return dicPart | word;
//     }
// 
//     /**
//      * Make combined WordId from dictionary and internal parts. This method does
//      * bound checking.
//      *
//      * @param dic
//      *            dictionary id. 0 is system, 1 and above are user.
//      * @param word
//      *            word id inside the dictionary.
//      * @return combined word id.
//      */
//     public static int make(int dic, int word) {
//         if (word > MAX_WORD_ID) {
//             throw new IndexOutOfBoundsException("wordId is too large: " + word);
//         }
//         if (dic > MAX_DIC_ID) {
//             throw new IndexOutOfBoundsException("dictionaryId is too large: " + dic);
//         }
//         return makeUnchecked(dic, word);
//     }
// 
//     /**
//      * Extract dictionary number from the combined word id
//      * 
//      * @param wordId
//      *            combined word id
//      * @return dictionary number
//      */
//     public static int dic(int wordId) {
//         return wordId >>> 28;
//     }
// 
//     /**
//      * Extract internal word id from the combined word id
//      * 
//      * @param wordId
//      *            combined word id
//      * @return internal word id
//      */
//     public static int word(int wordId) {
//         return wordId & MAX_WORD_ID;
//     }
// }
// 
// Path: src/main/java/com/worksap/nlp/sudachi/dictionary/Lexicon.java
// public interface Lexicon {
// 
//     Iterator<int[]> lookup(byte[] text, int offset);
// 
//     int getWordId(String headword, short posId, String readingForm);
// 
//     /**
//      * Returns the left-ID of the morpheme specified by the word ID.
//      *
//      * <p>
//      * when the word ID is out of range, the behavior is undefined.
//      *
//      * @param wordId
//      *            the word ID of the morpheme
//      * @return the left-ID of the morpheme
//      */
//     short getLeftId(int wordId);
// 
//     /**
//      * Returns the right-ID of the morpheme specified by the word ID.
//      *
//      * <p>
//      * when the word ID is out of range, the behavior is undefined.
//      *
//      * @param wordId
//      *            the word ID of the morpheme
//      * @return the right-ID of the morpheme.
//      */
//     short getRightId(int wordId);
// 
//     /**
//      * Returns the word occurrence cost of the morpheme specified by the word ID.
//      *
//      * <p>
//      * when the word ID is out of range, the behavior is undefined.
//      *
//      * @param wordId
//      *            the word ID of the morpheme
//      * @return the word occurrence cost
//      */
//     short getCost(int wordId);
// 
//     /**
//      * Returns the informations of the morpheme specified by the word ID.
//      *
//      * <p>
//      * when the word ID is out of range, the behavior is undefined.
//      *
//      * @param wordId
//      *            the word ID of the morpheme
//      * @return the informations of the morpheme
//      * @see WordInfo
//      */
//     WordInfo getWordInfo(int wordId);
// 
//     /**
//      * Returns the ID of the dictionary containing the morpheme specified by the
//      * word ID.
//      *
//      * If the morpheme is in the system dictionary, it returns {@code 0}.
//      *
//      * @param wordId
//      *            the word ID of the morpheme
//      * @return the dictionary ID
//      */
//     int getDictionaryId(int wordId);
// 
//     /**
//      * Returns the number of morphemes in the dictionary.
//      *
//      * @return the number of morphemes
//      */
//     int size();
// }


// Path: src/main/java/com/worksap/nlp/sudachi/dictionary/build/WordLookup.java
import com.worksap.nlp.sudachi.WordId;
import com.worksap.nlp.sudachi.dictionary.Lexicon;
import java.util.List;


        @Override
        public void validate(int wordId) {
            int word = WordId.word(wordId);
            if (word > prebuiltSize) {
                throw new IllegalArgumentException("WordId was larger than the number of dictionary entries");
            }
        }

        @Override
        public boolean isUser() {
            return false;
        }
    }

    public static class Chain implements WordIdResolver {
        private final WordIdResolver system;
        private final WordIdResolver user;

        public Chain(WordIdResolver system, WordIdResolver user) {
            this.system = system;
            this.user = user;
        }

        @Override
        public int lookup(String headword, short posId, String reading) {
            int wid = user.lookup(headword, posId, reading);
            if (wid == -1) {
                return system.lookup(headword, posId, reading);
            }
            return WordId.make(1, wid);