1069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project/*
2069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Copyright 2001-2004 The Apache Software Foundation.
3069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project *
4069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
5069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * you may not use this file except in compliance with the License.
6069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * You may obtain a copy of the License at
7069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project *
8069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
9069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project *
10069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
12069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * See the License for the specific language governing permissions and
14069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * limitations under the License.
15069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */
16069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
17069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectpackage org.apache.commons.codec.language;
18069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
19069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport org.apache.commons.codec.EncoderException;
20069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport org.apache.commons.codec.StringEncoder;
21069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
22069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project/**
23069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Encodes a string into a double metaphone value.
24069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * This Implementation is based on the algorithm by <CITE>Lawrence Philips</CITE>.
25069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <ul>
26069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <li>Original Article: <a
27069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * href="http://www.cuj.com/documents/s=8038/cuj0006philips/">
28069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * http://www.cuj.com/documents/s=8038/cuj0006philips/</a></li>
29069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <li>Original Source Code: <a href="ftp://ftp.cuj.com/pub/2000/1806/philips.zip">
30069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * ftp://ftp.cuj.com/pub/2000/1806/philips.zip</a></li>
31069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * </ul>
32069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project *
33069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @author Apache Software Foundation
34069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @version $Id: DoubleMetaphone.java,v 1.24 2004/06/05 18:32:04 ggregory Exp $
35d42abb2fd917184764daf22f5f299e848b8701d7Narayan Kamath *
36d42abb2fd917184764daf22f5f299e848b8701d7Narayan Kamath * @deprecated Please use {@link java.net.URL#openConnection} instead.
37d42abb2fd917184764daf22f5f299e848b8701d7Narayan Kamath *     Please visit <a href="http://android-developers.blogspot.com/2011/09/androids-http-clients.html">this webpage</a>
38d42abb2fd917184764daf22f5f299e848b8701d7Narayan Kamath *     for further details.
39069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */
40d42abb2fd917184764daf22f5f299e848b8701d7Narayan Kamath@Deprecated
41069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectpublic class DoubleMetaphone implements StringEncoder {
42069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
43069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    /**
44069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * "Vowels" to test for
45069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     */
46069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    private static final String VOWELS = "AEIOUY";
47069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
48069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    /**
49069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * Prefixes when present which are not pronounced
50069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     */
51069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    private static final String[] SILENT_START =
52069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    { "GN", "KN", "PN", "WR", "PS" };
53069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    private static final String[] L_R_N_M_B_H_F_V_W_SPACE =
54069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    { "L", "R", "N", "M", "B", "H", "F", "V", "W", " " };
55069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    private static final String[] ES_EP_EB_EL_EY_IB_IL_IN_IE_EI_ER =
56069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    { "ES", "EP", "EB", "EL", "EY", "IB", "IL", "IN", "IE", "EI", "ER" };
57069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    private static final String[] L_T_K_S_N_M_B_Z =
58069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    { "L", "T", "K", "S", "N", "M", "B", "Z" };
59069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
60069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    /**
61069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * Maximum length of an encoding, default is 4
62069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     */
63069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    protected int maxCodeLen = 4;
64069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
65069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    /**
66069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * Creates an instance of this DoubleMetaphone encoder
67069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     */
68069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    public DoubleMetaphone() {
69069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        super();
70069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    }
71069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
72069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    /**
73069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * Encode a value with Double Metaphone
74069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     *
75069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * @param value String to encode
76069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * @return an encoded string
77069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     */
78069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    public String doubleMetaphone(String value) {
79069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        return doubleMetaphone(value, false);
80069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    }
81069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
82069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    /**
83069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * Encode a value with Double Metaphone, optionally using the alternate
84069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * encoding.
85069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     *
86069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * @param value String to encode
87069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * @param alternate use alternate encode
88069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * @return an encoded string
89069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     */
90069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    public String doubleMetaphone(String value, boolean alternate) {
91069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        value = cleanInput(value);
92069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        if (value == null) {
93069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            return null;
94069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
95069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
96069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        boolean slavoGermanic = isSlavoGermanic(value);
97069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        int index = isSilentStart(value) ? 1 : 0;
98069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
99069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        DoubleMetaphoneResult result = new DoubleMetaphoneResult(this.getMaxCodeLen());
100069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
101069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        while (!result.isComplete() && index <= value.length() - 1) {
102069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            switch (value.charAt(index)) {
103069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            case 'A':
104069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            case 'E':
105069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            case 'I':
106069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            case 'O':
107069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            case 'U':
108069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            case 'Y':
109069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                index = handleAEIOUY(value, result, index);
110069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                break;
111069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            case 'B':
112069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                result.append('P');
113069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                index = charAt(value, index + 1) == 'B' ? index + 2 : index + 1;
114069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                break;
115069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            case '\u00C7':
116069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                // A C with a Cedilla
117069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                result.append('S');
118069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                index++;
119069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                break;
120069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            case 'C':
121069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                index = handleC(value, result, index);
122069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                break;
123069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            case 'D':
124069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                index = handleD(value, result, index);
125069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                break;
126069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            case 'F':
127069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                result.append('F');
128069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                index = charAt(value, index + 1) == 'F' ? index + 2 : index + 1;
129069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                break;
130069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            case 'G':
131069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                index = handleG(value, result, index, slavoGermanic);
132069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                break;
133069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            case 'H':
134069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                index = handleH(value, result, index);
135069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                break;
136069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            case 'J':
137069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                index = handleJ(value, result, index, slavoGermanic);
138069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                break;
139069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            case 'K':
140069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                result.append('K');
141069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                index = charAt(value, index + 1) == 'K' ? index + 2 : index + 1;
142069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                break;
143069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            case 'L':
144069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                index = handleL(value, result, index);
145069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                break;
146069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            case 'M':
147069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                result.append('M');
148069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                index = conditionM0(value, index) ? index + 2 : index + 1;
149069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                break;
150069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            case 'N':
151069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                result.append('N');
152069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                index = charAt(value, index + 1) == 'N' ? index + 2 : index + 1;
153069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                break;
154069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            case '\u00D1':
155069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                // N with a tilde (spanish ene)
156069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                result.append('N');
157069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                index++;
158069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                break;
159069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            case 'P':
160069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                index = handleP(value, result, index);
161069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                break;
162069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            case 'Q':
163069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                result.append('K');
164069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                index = charAt(value, index + 1) == 'Q' ? index + 2 : index + 1;
165069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                break;
166069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            case 'R':
167069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                index = handleR(value, result, index, slavoGermanic);
168069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                break;
169069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            case 'S':
170069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                index = handleS(value, result, index, slavoGermanic);
171069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                break;
172069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            case 'T':
173069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                index = handleT(value, result, index);
174069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                break;
175069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            case 'V':
176069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                result.append('F');
177069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                index = charAt(value, index + 1) == 'V' ? index + 2 : index + 1;
178069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                break;
179069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            case 'W':
180069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                index = handleW(value, result, index);
181069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                break;
182069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            case 'X':
183069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                index = handleX(value, result, index);
184069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                break;
185069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            case 'Z':
186069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                index = handleZ(value, result, index, slavoGermanic);
187069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                break;
188069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            default:
189069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                index++;
190069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                break;
191069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            }
192069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
193069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
194069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        return alternate ? result.getAlternate() : result.getPrimary();
195069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    }
196069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
197069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    /**
198069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * Encode the value using DoubleMetaphone.  It will only work if
199069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * <code>obj</code> is a <code>String</code> (like <code>Metaphone</code>).
200069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     *
201069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * @param obj Object to encode (should be of type String)
202069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * @return An encoded Object (will be of type String)
203069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * @throws EncoderException encode parameter is not of type String
204069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     */
205069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    public Object encode(Object obj) throws EncoderException {
206069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        if (!(obj instanceof String)) {
207069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            throw new EncoderException("DoubleMetaphone encode parameter is not of type String");
208069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
209069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        return doubleMetaphone((String) obj);
210069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    }
211069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
212069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    /**
213069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * Encode the value using DoubleMetaphone.
214069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     *
215069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * @param value String to encode
216069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * @return An encoded String
217069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     */
218069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    public String encode(String value) {
219069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        return doubleMetaphone(value);
220069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    }
221069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
222069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    /**
223069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * Check if the Double Metaphone values of two <code>String</code> values
224069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * are equal.
225069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     *
226069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * @param value1 The left-hand side of the encoded {@link String#equals(Object)}.
227069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * @param value2 The right-hand side of the encoded {@link String#equals(Object)}.
228069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * @return <code>true</code> if the encoded <code>String</code>s are equal;
229069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     *          <code>false</code> otherwise.
230069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * @see #isDoubleMetaphoneEqual(String,String,boolean)
231069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     */
232069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    public boolean isDoubleMetaphoneEqual(String value1, String value2) {
233069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        return isDoubleMetaphoneEqual(value1, value2, false);
234069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    }
235069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
236069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    /**
237069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * Check if the Double Metaphone values of two <code>String</code> values
238069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * are equal, optionally using the alternate value.
239069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     *
240069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * @param value1 The left-hand side of the encoded {@link String#equals(Object)}.
241069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * @param value2 The right-hand side of the encoded {@link String#equals(Object)}.
242069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * @param alternate use the alternate value if <code>true</code>.
243069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * @return <code>true</code> if the encoded <code>String</code>s are equal;
244069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     *          <code>false</code> otherwise.
245069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     */
246069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    public boolean isDoubleMetaphoneEqual(String value1,
247069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                                          String value2,
248069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                                          boolean alternate) {
249069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        return doubleMetaphone(value1, alternate).equals(doubleMetaphone
250069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                                                         (value2, alternate));
251069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    }
252069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
253069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    /**
254069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * Returns the maxCodeLen.
255069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * @return int
256069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     */
257069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    public int getMaxCodeLen() {
258069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        return this.maxCodeLen;
259069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    }
260069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
261069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    /**
262069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * Sets the maxCodeLen.
263069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * @param maxCodeLen The maxCodeLen to set
264069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     */
265069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    public void setMaxCodeLen(int maxCodeLen) {
266069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        this.maxCodeLen = maxCodeLen;
267069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    }
268069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
269069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    //-- BEGIN HANDLERS --//
270069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
271069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    /**
272069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * Handles 'A', 'E', 'I', 'O', 'U', and 'Y' cases
273069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     */
274069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    private int handleAEIOUY(String value, DoubleMetaphoneResult result, int
275069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                             index) {
276069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        if (index == 0) {
277069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            result.append('A');
278069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
279069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        return index + 1;
280069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    }
281069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
282069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    /**
283069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * Handles 'C' cases
284069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     */
285069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    private int handleC(String value,
286069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                        DoubleMetaphoneResult result,
287069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                        int index) {
288069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        if (conditionC0(value, index)) {  // very confusing, moved out
289069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            result.append('K');
290069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            index += 2;
291069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        } else if (index == 0 && contains(value, index, 6, "CAESAR")) {
292069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            result.append('S');
293069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            index += 2;
294069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        } else if (contains(value, index, 2, "CH")) {
295069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            index = handleCH(value, result, index);
296069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        } else if (contains(value, index, 2, "CZ") &&
297069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                   !contains(value, index - 2, 4, "WICZ")) {
298069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            //-- "Czerny" --//
299069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            result.append('S', 'X');
300069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            index += 2;
301069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        } else if (contains(value, index + 1, 3, "CIA")) {
302069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            //-- "focaccia" --//
303069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            result.append('X');
304069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            index += 3;
305069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        } else if (contains(value, index, 2, "CC") &&
306069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                   !(index == 1 && charAt(value, 0) == 'M')) {
307069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            //-- double "cc" but not "McClelland" --//
308069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            return handleCC(value, result, index);
309069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        } else if (contains(value, index, 2, "CK", "CG", "CQ")) {
310069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            result.append('K');
311069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            index += 2;
312069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        } else if (contains(value, index, 2, "CI", "CE", "CY")) {
313069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            //-- Italian vs. English --//
314069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            if (contains(value, index, 3, "CIO", "CIE", "CIA")) {
315069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                result.append('S', 'X');
316069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            } else {
317069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                result.append('S');
318069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            }
319069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            index += 2;
320069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        } else {
321069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            result.append('K');
322069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            if (contains(value, index + 1, 2, " C", " Q", " G")) {
323069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                //-- Mac Caffrey, Mac Gregor --//
324069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                index += 3;
325069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            } else if (contains(value, index + 1, 1, "C", "K", "Q") &&
326069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                       !contains(value, index + 1, 2, "CE", "CI")) {
327069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                index += 2;
328069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            } else {
329069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                index++;
330069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            }
331069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
332069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
333069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        return index;
334069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    }
335069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
336069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    /**
337069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * Handles 'CC' cases
338069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     */
339069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    private int handleCC(String value,
340069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                         DoubleMetaphoneResult result,
341069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                         int index) {
342069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        if (contains(value, index + 2, 1, "I", "E", "H") &&
343069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            !contains(value, index + 2, 2, "HU")) {
344069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            //-- "bellocchio" but not "bacchus" --//
345069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            if ((index == 1 && charAt(value, index - 1) == 'A') ||
346069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                contains(value, index - 1, 5, "UCCEE", "UCCES")) {
347069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                //-- "accident", "accede", "succeed" --//
348069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                result.append("KS");
349069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            } else {
350069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                //-- "bacci", "bertucci", other Italian --//
351069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                result.append('X');
352069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            }
353069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            index += 3;
354069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        } else {    // Pierce's rule
355069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            result.append('K');
356069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            index += 2;
357069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
358069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
359069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        return index;
360069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    }
361069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
362069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    /**
363069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * Handles 'CH' cases
364069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     */
365069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    private int handleCH(String value,
366069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                         DoubleMetaphoneResult result,
367069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                         int index) {
368069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        if (index > 0 && contains(value, index, 4, "CHAE")) {   // Michael
369069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            result.append('K', 'X');
370069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            return index + 2;
371069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        } else if (conditionCH0(value, index)) {
372069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            //-- Greek roots ("chemistry", "chorus", etc.) --//
373069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            result.append('K');
374069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            return index + 2;
375069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        } else if (conditionCH1(value, index)) {
376069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            //-- Germanic, Greek, or otherwise 'ch' for 'kh' sound --//
377069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            result.append('K');
378069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            return index + 2;
379069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        } else {
380069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            if (index > 0) {
381069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                if (contains(value, 0, 2, "MC")) {
382069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                    result.append('K');
383069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                } else {
384069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                    result.append('X', 'K');
385069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                }
386069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            } else {
387069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                result.append('X');
388069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            }
389069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            return index + 2;
390069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
391069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    }
392069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
393069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    /**
394069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * Handles 'D' cases
395069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     */
396069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    private int handleD(String value,
397069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                        DoubleMetaphoneResult result,
398069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                        int index) {
399069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        if (contains(value, index, 2, "DG")) {
400069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            //-- "Edge" --//
401069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            if (contains(value, index + 2, 1, "I", "E", "Y")) {
402069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                result.append('J');
403069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                index += 3;
404069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                //-- "Edgar" --//
405069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            } else {
406069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                result.append("TK");
407069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                index += 2;
408069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            }
409069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        } else if (contains(value, index, 2, "DT", "DD")) {
410069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            result.append('T');
411069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            index += 2;
412069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        } else {
413069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            result.append('T');
414069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            index++;
415069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
416069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        return index;
417069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    }
418069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
419069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    /**
420069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * Handles 'G' cases
421069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     */
422069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    private int handleG(String value,
423069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                        DoubleMetaphoneResult result,
424069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                        int index,
425069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                        boolean slavoGermanic) {
426069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        if (charAt(value, index + 1) == 'H') {
427069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            index = handleGH(value, result, index);
428069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        } else if (charAt(value, index + 1) == 'N') {
429069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            if (index == 1 && isVowel(charAt(value, 0)) && !slavoGermanic) {
430069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                result.append("KN", "N");
431069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            } else if (!contains(value, index + 2, 2, "EY") &&
432069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                       charAt(value, index + 1) != 'Y' && !slavoGermanic) {
433069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                result.append("N", "KN");
434069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            } else {
435069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                result.append("KN");
436069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            }
437069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            index = index + 2;
438069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        } else if (contains(value, index + 1, 2, "LI") && !slavoGermanic) {
439069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            result.append("KL", "L");
440069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            index += 2;
441069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        } else if (index == 0 && (charAt(value, index + 1) == 'Y' || contains(value, index + 1, 2, ES_EP_EB_EL_EY_IB_IL_IN_IE_EI_ER))) {
442069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            //-- -ges-, -gep-, -gel-, -gie- at beginning --//
443069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            result.append('K', 'J');
444069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            index += 2;
445069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        } else if ((contains(value, index + 1, 2, "ER") ||
446069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                    charAt(value, index + 1) == 'Y') &&
447069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                   !contains(value, 0, 6, "DANGER", "RANGER", "MANGER") &&
448069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                   !contains(value, index - 1, 1, "E", "I") &&
449069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                   !contains(value, index - 1, 3, "RGY", "OGY")) {
450069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            //-- -ger-, -gy- --//
451069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            result.append('K', 'J');
452069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            index += 2;
453069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        } else if (contains(value, index + 1, 1, "E", "I", "Y") ||
454069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                   contains(value, index - 1, 4, "AGGI", "OGGI")) {
455069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            //-- Italian "biaggi" --//
456069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            if ((contains(value, 0 ,4, "VAN ", "VON ") || contains(value, 0, 3, "SCH")) || contains(value, index + 1, 2, "ET")) {
457069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                //-- obvious germanic --//
458069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                result.append('K');
459069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            } else if (contains(value, index + 1, 4, "IER")) {
460069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                result.append('J');
461069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            } else {
462069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                result.append('J', 'K');
463069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            }
464069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            index += 2;
465069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        } else if (charAt(value, index + 1) == 'G') {
466069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            index += 2;
467069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            result.append('K');
468069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        } else {
469069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            index++;
470069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            result.append('K');
471069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
472069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        return index;
473069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    }
474069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
475069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    /**
476069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * Handles 'GH' cases
477069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     */
478069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    private int handleGH(String value,
479069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                         DoubleMetaphoneResult result,
480069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                         int index) {
481069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        if (index > 0 && !isVowel(charAt(value, index - 1))) {
482069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            result.append('K');
483069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            index += 2;
484069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        } else if (index == 0) {
485069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            if (charAt(value, index + 2) == 'I') {
486069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                result.append('J');
487069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            } else {
488069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                result.append('K');
489069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            }
490069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            index += 2;
491069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        } else if ((index > 1 && contains(value, index - 2, 1, "B", "H", "D")) ||
492069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                   (index > 2 && contains(value, index - 3, 1, "B", "H", "D")) ||
493069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                   (index > 3 && contains(value, index - 4, 1, "B", "H"))) {
494069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            //-- Parker's rule (with some further refinements) - "hugh"
495069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            index += 2;
496069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        } else {
497069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            if (index > 2 && charAt(value, index - 1) == 'U' &&
498069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                contains(value, index - 3, 1, "C", "G", "L", "R", "T")) {
499069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                //-- "laugh", "McLaughlin", "cough", "gough", "rough", "tough"
500069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                result.append('F');
501069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            } else if (index > 0 && charAt(value, index - 1) != 'I') {
502069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                result.append('K');
503069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            }
504069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            index += 2;
505069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
506069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        return index;
507069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    }
508069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
509069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    /**
510069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * Handles 'H' cases
511069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     */
512069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    private int handleH(String value,
513069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                        DoubleMetaphoneResult result,
514069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                        int index) {
515069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        //-- only keep if first & before vowel or between 2 vowels --//
516069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        if ((index == 0 || isVowel(charAt(value, index - 1))) &&
517069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            isVowel(charAt(value, index + 1))) {
518069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            result.append('H');
519069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            index += 2;
520069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            //-- also takes car of "HH" --//
521069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        } else {
522069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            index++;
523069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
524069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        return index;
525069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    }
526069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
527069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    /**
528069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * Handles 'J' cases
529069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     */
530069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    private int handleJ(String value, DoubleMetaphoneResult result, int index,
531069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                        boolean slavoGermanic) {
532069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        if (contains(value, index, 4, "JOSE") || contains(value, 0, 4, "SAN ")) {
533069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                //-- obvious Spanish, "Jose", "San Jacinto" --//
534069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                if ((index == 0 && (charAt(value, index + 4) == ' ') ||
535069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                     value.length() == 4) || contains(value, 0, 4, "SAN ")) {
536069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                    result.append('H');
537069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                } else {
538069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                    result.append('J', 'H');
539069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                }
540069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                index++;
541069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            } else {
542069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                if (index == 0 && !contains(value, index, 4, "JOSE")) {
543069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                    result.append('J', 'A');
544069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                } else if (isVowel(charAt(value, index - 1)) && !slavoGermanic &&
545069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                              (charAt(value, index + 1) == 'A' || charAt(value, index + 1) == 'O')) {
546069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                    result.append('J', 'H');
547069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                } else if (index == value.length() - 1) {
548069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                    result.append('J', ' ');
549069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                } else if (!contains(value, index + 1, 1, L_T_K_S_N_M_B_Z) && !contains(value, index - 1, 1, "S", "K", "L")) {
550069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                    result.append('J');
551069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                }
552069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
553069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                if (charAt(value, index + 1) == 'J') {
554069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                    index += 2;
555069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                } else {
556069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                    index++;
557069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                }
558069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            }
559069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        return index;
560069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    }
561069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
562069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    /**
563069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * Handles 'L' cases
564069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     */
565069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    private int handleL(String value,
566069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                        DoubleMetaphoneResult result,
567069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                        int index) {
568069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        result.append('L');
569069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        if (charAt(value, index + 1) == 'L') {
570069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            if (conditionL0(value, index)) {
571069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                result.appendAlternate(' ');
572069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            }
573069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            index += 2;
574069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        } else {
575069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            index++;
576069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
577069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        return index;
578069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    }
579069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
580069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    /**
581069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * Handles 'P' cases
582069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     */
583069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    private int handleP(String value,
584069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                        DoubleMetaphoneResult result,
585069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                        int index) {
586069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        if (charAt(value, index + 1) == 'H') {
587069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            result.append('F');
588069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            index += 2;
589069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        } else {
590069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            result.append('P');
591069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            index = contains(value, index + 1, 1, "P", "B") ? index + 2 : index + 1;
592069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
593069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        return index;
594069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    }
595069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
596069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    /**
597069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * Handles 'R' cases
598069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     */
599069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    private int handleR(String value,
600069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                        DoubleMetaphoneResult result,
601069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                        int index,
602069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                        boolean slavoGermanic) {
603069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        if (index == value.length() - 1 && !slavoGermanic &&
604069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            contains(value, index - 2, 2, "IE") &&
605069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            !contains(value, index - 4, 2, "ME", "MA")) {
606069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            result.appendAlternate('R');
607069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        } else {
608069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            result.append('R');
609069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
610069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        return charAt(value, index + 1) == 'R' ? index + 2 : index + 1;
611069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    }
612069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
613069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    /**
614069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * Handles 'S' cases
615069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     */
616069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    private int handleS(String value,
617069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                        DoubleMetaphoneResult result,
618069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                        int index,
619069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                        boolean slavoGermanic) {
620069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        if (contains(value, index - 1, 3, "ISL", "YSL")) {
621069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            //-- special cases "island", "isle", "carlisle", "carlysle" --//
622069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            index++;
623069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        } else if (index == 0 && contains(value, index, 5, "SUGAR")) {
624069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            //-- special case "sugar-" --//
625069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            result.append('X', 'S');
626069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            index++;
627069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        } else if (contains(value, index, 2, "SH")) {
628069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            if (contains(value, index + 1, 4,
629069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                         "HEIM", "HOEK", "HOLM", "HOLZ")) {
630069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                //-- germanic --//
631069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                result.append('S');
632069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            } else {
633069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                result.append('X');
634069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            }
635069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            index += 2;
636069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        } else if (contains(value, index, 3, "SIO", "SIA") || contains(value, index, 4, "SIAN")) {
637069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            //-- Italian and Armenian --//
638069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            if (slavoGermanic) {
639069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                result.append('S');
640069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            } else {
641069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                result.append('S', 'X');
642069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            }
643069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            index += 3;
644069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        } else if ((index == 0 && contains(value, index + 1, 1, "M", "N", "L", "W")) || contains(value, index + 1, 1, "Z")) {
645069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            //-- german & anglicisations, e.g. "smith" match "schmidt" //
646069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            // "snider" match "schneider" --//
647069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            //-- also, -sz- in slavic language altho in hungarian it //
648069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            //   is pronounced "s" --//
649069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            result.append('S', 'X');
650069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            index = contains(value, index + 1, 1, "Z") ? index + 2 : index + 1;
651069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        } else if (contains(value, index, 2, "SC")) {
652069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            index = handleSC(value, result, index);
653069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        } else {
654069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            if (index == value.length() - 1 && contains(value, index - 2,
655069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                                                        2, "AI", "OI")){
656069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                //-- french e.g. "resnais", "artois" --//
657069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                result.appendAlternate('S');
658069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            } else {
659069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                result.append('S');
660069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            }
661069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            index = contains(value, index + 1, 1, "S", "Z") ? index + 2 : index + 1;
662069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
663069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        return index;
664069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    }
665069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
666069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    /**
667069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * Handles 'SC' cases
668069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     */
669069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    private int handleSC(String value,
670069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                         DoubleMetaphoneResult result,
671069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                         int index) {
672069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        if (charAt(value, index + 2) == 'H') {
673069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            //-- Schlesinger's rule --//
674069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            if (contains(value, index + 3,
675069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                         2, "OO", "ER", "EN", "UY", "ED", "EM")) {
676069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                //-- Dutch origin, e.g. "school", "schooner" --//
677069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                if (contains(value, index + 3, 2, "ER", "EN")) {
678069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                    //-- "schermerhorn", "schenker" --//
679069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                    result.append("X", "SK");
680069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                } else {
681069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                    result.append("SK");
682069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                }
683069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            } else {
684069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                if (index == 0 && !isVowel(charAt(value, 3)) && charAt(value, 3) != 'W') {
685069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                    result.append('X', 'S');
686069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                } else {
687069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                    result.append('X');
688069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                }
689069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            }
690069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        } else if (contains(value, index + 2, 1, "I", "E", "Y")) {
691069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            result.append('S');
692069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        } else {
693069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            result.append("SK");
694069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
695069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        return index + 3;
696069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    }
697069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
698069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    /**
699069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * Handles 'T' cases
700069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     */
701069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    private int handleT(String value,
702069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                        DoubleMetaphoneResult result,
703069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                        int index) {
704069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        if (contains(value, index, 4, "TION")) {
705069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            result.append('X');
706069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            index += 3;
707069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        } else if (contains(value, index, 3, "TIA", "TCH")) {
708069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            result.append('X');
709069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            index += 3;
710069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        } else if (contains(value, index, 2, "TH") || contains(value, index,
711069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                                                               3, "TTH")) {
712069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            if (contains(value, index + 2, 2, "OM", "AM") ||
713069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                //-- special case "thomas", "thames" or germanic --//
714069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                contains(value, 0, 4, "VAN ", "VON ") ||
715069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                contains(value, 0, 3, "SCH")) {
716069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                result.append('T');
717069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            } else {
718069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                result.append('0', 'T');
719069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            }
720069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            index += 2;
721069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        } else {
722069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            result.append('T');
723069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            index = contains(value, index + 1, 1, "T", "D") ? index + 2 : index + 1;
724069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
725069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        return index;
726069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    }
727069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
728069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    /**
729069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * Handles 'W' cases
730069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     */
731069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    private int handleW(String value,
732069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                        DoubleMetaphoneResult result,
733069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                        int index) {
734069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        if (contains(value, index, 2, "WR")) {
735069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            //-- can also be in middle of word --//
736069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            result.append('R');
737069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            index += 2;
738069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        } else {
739069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            if (index == 0 && (isVowel(charAt(value, index + 1)) ||
740069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                               contains(value, index, 2, "WH"))) {
741069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                if (isVowel(charAt(value, index + 1))) {
742069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                    //-- Wasserman should match Vasserman --//
743069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                    result.append('A', 'F');
744069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                } else {
745069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                    //-- need Uomo to match Womo --//
746069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                    result.append('A');
747069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                }
748069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                index++;
749069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            } else if ((index == value.length() - 1 && isVowel(charAt(value, index - 1))) ||
750069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                       contains(value, index - 1,
751069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                                5, "EWSKI", "EWSKY", "OWSKI", "OWSKY") ||
752069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                       contains(value, 0, 3, "SCH")) {
753069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                //-- Arnow should match Arnoff --//
754069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                result.appendAlternate('F');
755069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                index++;
756069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            } else if (contains(value, index, 4, "WICZ", "WITZ")) {
757069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                //-- Polish e.g. "filipowicz" --//
758069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                result.append("TS", "FX");
759069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                index += 4;
760069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            } else {
761069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                index++;
762069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            }
763069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
764069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        return index;
765069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    }
766069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
767069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    /**
768069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * Handles 'X' cases
769069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     */
770069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    private int handleX(String value,
771069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                        DoubleMetaphoneResult result,
772069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                        int index) {
773069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        if (index == 0) {
774069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            result.append('S');
775069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            index++;
776069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        } else {
777069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            if (!((index == value.length() - 1) &&
778069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                  (contains(value, index - 3, 3, "IAU", "EAU") ||
779069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                   contains(value, index - 2, 2, "AU", "OU")))) {
780069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                //-- French e.g. breaux --//
781069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                result.append("KS");
782069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            }
783069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            index = contains(value, index + 1, 1, "C", "X") ? index + 2 : index + 1;
784069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
785069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        return index;
786069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    }
787069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
788069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    /**
789069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * Handles 'Z' cases
790069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     */
791069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    private int handleZ(String value, DoubleMetaphoneResult result, int index,
792069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                        boolean slavoGermanic) {
793069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        if (charAt(value, index + 1) == 'H') {
794069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            //-- Chinese pinyin e.g. "zhao" or Angelina "Zhang" --//
795069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            result.append('J');
796069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            index += 2;
797069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        } else {
798069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            if (contains(value, index + 1, 2, "ZO", "ZI", "ZA") || (slavoGermanic && (index > 0 && charAt(value, index - 1) != 'T'))) {
799069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                result.append("S", "TS");
800069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            } else {
801069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                result.append('S');
802069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            }
803069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            index = charAt(value, index + 1) == 'Z' ? index + 2 : index + 1;
804069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
805069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        return index;
806069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    }
807069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
808069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    //-- BEGIN CONDITIONS --//
809069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
810069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    /**
811069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * Complex condition 0 for 'C'
812069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     */
813069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    private boolean conditionC0(String value, int index) {
814069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        if (contains(value, index, 4, "CHIA")) {
815069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            return true;
816069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        } else if (index <= 1) {
817069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            return false;
818069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        } else if (isVowel(charAt(value, index - 2))) {
819069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            return false;
820069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        } else if (!contains(value, index - 1, 3, "ACH")) {
821069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            return false;
822069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        } else {
823069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            char c = charAt(value, index + 2);
824069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            return (c != 'I' && c != 'E')
825069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                    || contains(value, index - 2, 6, "BACHER", "MACHER");
826069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
827069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    }
828069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
829069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    /**
830069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * Complex condition 0 for 'CH'
831069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     */
832069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    private boolean conditionCH0(String value, int index) {
833069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        if (index != 0) {
834069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            return false;
835069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        } else if (!contains(value, index + 1, 5, "HARAC", "HARIS") &&
836069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                   !contains(value, index + 1, 3, "HOR", "HYM", "HIA", "HEM")) {
837069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            return false;
838069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        } else if (contains(value, 0, 5, "CHORE")) {
839069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            return false;
840069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        } else {
841069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            return true;
842069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
843069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    }
844069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
845069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    /**
846069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * Complex condition 1 for 'CH'
847069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     */
848069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    private boolean conditionCH1(String value, int index) {
849069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        return ((contains(value, 0, 4, "VAN ", "VON ") || contains(value, 0,
850069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                                                                   3, "SCH")) ||
851069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                contains(value, index - 2, 6, "ORCHES", "ARCHIT", "ORCHID") ||
852069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                contains(value, index + 2, 1, "T", "S") ||
853069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                ((contains(value, index - 1, 1, "A", "O", "U", "E") || index == 0) &&
854069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                 (contains(value, index + 2, 1, L_R_N_M_B_H_F_V_W_SPACE) || index + 1 == value.length() - 1)));
855069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    }
856069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
857069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    /**
858069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * Complex condition 0 for 'L'
859069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     */
860069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    private boolean conditionL0(String value, int index) {
861069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        if (index == value.length() - 3 &&
862069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            contains(value, index - 1, 4, "ILLO", "ILLA", "ALLE")) {
863069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            return true;
864069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        } else if ((contains(value, index - 1, 2, "AS", "OS") ||
865069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                    contains(value, value.length() - 1, 1, "A", "O")) &&
866069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                   contains(value, index - 1, 4, "ALLE")) {
867069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            return true;
868069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        } else {
869069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            return false;
870069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
871069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    }
872069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
873069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    /**
874069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * Complex condition 0 for 'M'
875069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     */
876069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    private boolean conditionM0(String value, int index) {
877069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        if (charAt(value, index + 1) == 'M') {
878069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            return true;
879069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
880069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        return contains(value, index - 1, 3, "UMB")
881069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                && ((index + 1) == value.length() - 1 || contains(value,
882069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                        index + 2, 2, "ER"));
883069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    }
884069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
885069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    //-- BEGIN HELPER FUNCTIONS --//
886069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
887069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    /**
888069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * Determines whether or not a value is of slavo-germanic orgin. A value is
889069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * of slavo-germanic origin if it contians any of 'W', 'K', 'CZ', or 'WITZ'.
890069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     */
891069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    private boolean isSlavoGermanic(String value) {
892069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        return value.indexOf('W') > -1 || value.indexOf('K') > -1 ||
893069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            value.indexOf("CZ") > -1 || value.indexOf("WITZ") > -1;
894069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    }
895069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
896069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    /**
897069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * Determines whether or not a character is a vowel or not
898069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     */
899069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    private boolean isVowel(char ch) {
900069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        return VOWELS.indexOf(ch) != -1;
901069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    }
902069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
903069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    /**
904069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * Determines whether or not the value starts with a silent letter.  It will
905069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * return <code>true</code> if the value starts with any of 'GN', 'KN',
906069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * 'PN', 'WR' or 'PS'.
907069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     */
908069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    private boolean isSilentStart(String value) {
909069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        boolean result = false;
910069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        for (int i = 0; i < SILENT_START.length; i++) {
911069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            if (value.startsWith(SILENT_START[i])) {
912069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                result = true;
913069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                break;
914069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            }
915069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
916069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        return result;
917069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    }
918069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
919069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    /**
920069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * Cleans the input
921069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     */
922069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    private String cleanInput(String input) {
923069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        if (input == null) {
924069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            return null;
925069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
926069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        input = input.trim();
927069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        if (input.length() == 0) {
928069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            return null;
929069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
930069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        return input.toUpperCase();
931069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    }
932069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
933069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    /**
934069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * Gets the character at index <code>index</code> if available, otherwise
935069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * it returns <code>Character.MIN_VALUE</code> so that there is some sort
936069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * of a default
937069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     */
938069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    protected char charAt(String value, int index) {
939069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        if (index < 0 || index >= value.length()) {
940069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            return Character.MIN_VALUE;
941069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
942069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        return value.charAt(index);
943069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    }
944069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
945069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    /**
946069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * Shortcut method with 1 criteria
947069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     */
948069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    private static boolean contains(String value, int start, int length,
949069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                                    String criteria) {
950069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        return contains(value, start, length,
951069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                        new String[] { criteria });
952069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    }
953069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
954069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    /**
955069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * Shortcut method with 2 criteria
956069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     */
957069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    private static boolean contains(String value, int start, int length,
958069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                                    String criteria1, String criteria2) {
959069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        return contains(value, start, length,
960069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                        new String[] { criteria1, criteria2 });
961069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    }
962069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
963069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    /**
964069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * Shortcut method with 3 criteria
965069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     */
966069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    private static boolean contains(String value, int start, int length,
967069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                                    String criteria1, String criteria2,
968069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                                    String criteria3) {
969069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        return contains(value, start, length,
970069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                        new String[] { criteria1, criteria2, criteria3 });
971069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    }
972069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
973069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    /**
974069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * Shortcut method with 4 criteria
975069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     */
976069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    private static boolean contains(String value, int start, int length,
977069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                                    String criteria1, String criteria2,
978069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                                    String criteria3, String criteria4) {
979069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        return contains(value, start, length,
980069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                        new String[] { criteria1, criteria2, criteria3,
981069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                                       criteria4 });
982069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    }
983069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
984069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    /**
985069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * Shortcut method with 5 criteria
986069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     */
987069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    private static boolean contains(String value, int start, int length,
988069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                                    String criteria1, String criteria2,
989069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                                    String criteria3, String criteria4,
990069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                                    String criteria5) {
991069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        return contains(value, start, length,
992069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                        new String[] { criteria1, criteria2, criteria3,
993069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                                       criteria4, criteria5 });
994069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    }
995069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
996069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    /**
997069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * Shortcut method with 6 criteria
998069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     */
999069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    private static boolean contains(String value, int start, int length,
1000069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                                    String criteria1, String criteria2,
1001069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                                    String criteria3, String criteria4,
1002069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                                    String criteria5, String criteria6) {
1003069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        return contains(value, start, length,
1004069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                        new String[] { criteria1, criteria2, criteria3,
1005069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                                       criteria4, criteria5, criteria6 });
1006069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    }
1007069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
1008069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    /**
1009069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * Determines whether <code>value</code> contains any of the criteria
1010069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     starting
1011069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * at index <code>start</code> and matching up to length <code>length</code>
1012069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     */
1013069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    protected static boolean contains(String value, int start, int length,
1014069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                                      String[] criteria) {
1015069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        boolean result = false;
1016069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        if (start >= 0 && start + length <= value.length()) {
1017069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            String target = value.substring(start, start + length);
1018069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
1019069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            for (int i = 0; i < criteria.length; i++) {
1020069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                if (target.equals(criteria[i])) {
1021069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                    result = true;
1022069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                    break;
1023069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                }
1024069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            }
1025069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
1026069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        return result;
1027069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    }
1028069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
1029069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    //-- BEGIN INNER CLASSES --//
1030069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
1031069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    /**
1032069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * Inner class for storing results, since there is the optional alternate
1033069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * encoding.
1034069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     */
1035069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    public class DoubleMetaphoneResult {
1036069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
1037069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        private StringBuffer primary = new StringBuffer(getMaxCodeLen());
1038069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        private StringBuffer alternate = new StringBuffer(getMaxCodeLen());
1039069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        private int maxLength;
1040069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
1041069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        public DoubleMetaphoneResult(int maxLength) {
1042069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            this.maxLength = maxLength;
1043069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
1044069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
1045069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        public void append(char value) {
1046069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            appendPrimary(value);
1047069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            appendAlternate(value);
1048069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
1049069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
1050069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        public void append(char primary, char alternate) {
1051069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            appendPrimary(primary);
1052069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            appendAlternate(alternate);
1053069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
1054069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
1055069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        public void appendPrimary(char value) {
1056069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            if (this.primary.length() < this.maxLength) {
1057069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                this.primary.append(value);
1058069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            }
1059069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
1060069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
1061069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        public void appendAlternate(char value) {
1062069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            if (this.alternate.length() < this.maxLength) {
1063069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                this.alternate.append(value);
1064069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            }
1065069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
1066069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
1067069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        public void append(String value) {
1068069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            appendPrimary(value);
1069069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            appendAlternate(value);
1070069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
1071069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
1072069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        public void append(String primary, String alternate) {
1073069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            appendPrimary(primary);
1074069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            appendAlternate(alternate);
1075069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
1076069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
1077069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        public void appendPrimary(String value) {
1078069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            int addChars = this.maxLength - this.primary.length();
1079069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            if (value.length() <= addChars) {
1080069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                this.primary.append(value);
1081069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            } else {
1082069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                this.primary.append(value.substring(0, addChars));
1083069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            }
1084069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
1085069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
1086069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        public void appendAlternate(String value) {
1087069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            int addChars = this.maxLength - this.alternate.length();
1088069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            if (value.length() <= addChars) {
1089069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                this.alternate.append(value);
1090069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            } else {
1091069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                this.alternate.append(value.substring(0, addChars));
1092069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            }
1093069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
1094069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
1095069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        public String getPrimary() {
1096069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            return this.primary.toString();
1097069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
1098069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
1099069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        public String getAlternate() {
1100069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            return this.alternate.toString();
1101069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
1102069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
1103069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        public boolean isComplete() {
1104069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            return this.primary.length() >= this.maxLength &&
1105069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                this.alternate.length() >= this.maxLength;
1106069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
1107069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    }
1108069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project}
1109