1495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert/* GENERATED SOURCE. DO NOT MODIFY. */
2495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert// © 2017 and later: Unicode, Inc. and others.
3495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert// License & terms of use: http://www.unicode.org/copyright.html#License
4495cb271e305cfb399d463f32210a371198f0abfFredrik Roubertpackage android.icu.impl.locale;
5495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert
6495cb271e305cfb399d463f32210a371198f0abfFredrik Roubertimport java.io.BufferedReader;
7495cb271e305cfb399d463f32210a371198f0abfFredrik Roubertimport java.io.File;
8495cb271e305cfb399d463f32210a371198f0abfFredrik Roubertimport java.io.InputStream;
9495cb271e305cfb399d463f32210a371198f0abfFredrik Roubertimport java.io.InputStreamReader;
10495cb271e305cfb399d463f32210a371198f0abfFredrik Roubertimport java.net.URL;
11495cb271e305cfb399d463f32210a371198f0abfFredrik Roubertimport java.nio.charset.Charset;
12495cb271e305cfb399d463f32210a371198f0abfFredrik Roubertimport java.util.Arrays;
13495cb271e305cfb399d463f32210a371198f0abfFredrik Roubertimport java.util.Collection;
14495cb271e305cfb399d463f32210a371198f0abfFredrik Roubertimport java.util.Collections;
15495cb271e305cfb399d463f32210a371198f0abfFredrik Roubertimport java.util.HashMap;
16495cb271e305cfb399d463f32210a371198f0abfFredrik Roubertimport java.util.HashSet;
17495cb271e305cfb399d463f32210a371198f0abfFredrik Roubertimport java.util.Iterator;
18495cb271e305cfb399d463f32210a371198f0abfFredrik Roubertimport java.util.LinkedHashMap;
19495cb271e305cfb399d463f32210a371198f0abfFredrik Roubertimport java.util.LinkedHashSet;
20495cb271e305cfb399d463f32210a371198f0abfFredrik Roubertimport java.util.List;
21495cb271e305cfb399d463f32210a371198f0abfFredrik Roubertimport java.util.Map;
22495cb271e305cfb399d463f32210a371198f0abfFredrik Roubertimport java.util.Map.Entry;
23495cb271e305cfb399d463f32210a371198f0abfFredrik Roubertimport java.util.Set;
24495cb271e305cfb399d463f32210a371198f0abfFredrik Roubertimport java.util.TreeMap;
25495cb271e305cfb399d463f32210a371198f0abfFredrik Roubertimport java.util.TreeSet;
26495cb271e305cfb399d463f32210a371198f0abfFredrik Roubertimport java.util.regex.Matcher;
27495cb271e305cfb399d463f32210a371198f0abfFredrik Roubertimport java.util.regex.Pattern;
28495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert
29495cb271e305cfb399d463f32210a371198f0abfFredrik Roubertimport android.icu.util.ICUException;
30495cb271e305cfb399d463f32210a371198f0abfFredrik Roubertimport android.icu.util.ICUUncheckedIOException;
31495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert
32495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert/**
33495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert * Stub class to make migration easier until we get either Guava or a higher level of Java.
34495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert * @hide Only a subset of ICU is exposed in Android
35495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert */
36495cb271e305cfb399d463f32210a371198f0abfFredrik Roubertpublic class XCldrStub {
37495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert
38495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert    public static class Multimap<K, V> {
39495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        private final Map<K,Set<V>> map;
40495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        private final Class<Set<V>> setClass;
41495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert
42495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        @SuppressWarnings("unchecked")
43495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        private Multimap(Map<K,Set<V>> map, Class<?> setClass) {
44495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert            this.map = map;
45495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert            this.setClass = (Class<Set<V>>) (setClass != null
46495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert                    ? setClass
47495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert                            : HashSet.class);
48495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        }
49495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        public Multimap<K, V> putAll(K key, V... values) {
50495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert            if (values.length != 0) {
51495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert                createSetIfMissing(key).addAll(Arrays.asList(values));
52495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert            }
53495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert            return this;
54495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        }
55495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        public void putAll(K key, Collection<V> values) {
56495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert            if (!values.isEmpty()) {
57495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert                createSetIfMissing(key).addAll(values);
58495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert            }
59495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        }
60495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        public void putAll(Collection<K> keys, V value) {
61495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert            for (K key : keys) {
62495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert                put(key, value);
63495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert            }
64495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        }
65495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        public void putAll(Multimap<K, V> source) {
66495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert            for (Entry<K, Set<V>> entry : source.map.entrySet()) {
67495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert                putAll(entry.getKey(), entry.getValue());
68495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert            }
69495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        }
70495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        public void put(K key, V value) {
71495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert            createSetIfMissing(key).add(value);
72495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        }
73495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        private Set<V> createSetIfMissing(K key) {
74495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert            Set<V> old = map.get(key);
75495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert            if (old == null) {
76495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert                map.put(key, old = getInstance());
77495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert            }
78495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert            return old;
79495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        }
80495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        private Set<V> getInstance() {
81495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert            try {
82495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert                return setClass.newInstance();
83495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert            } catch (Exception e) {
84495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert                throw new ICUException(e);
85495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert            }
86495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        }
87495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        public Set<V> get(K key) {
88495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert            Set<V> result = map.get(key);
89495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert            return result; //  == null ? Collections.<V>emptySet() : result;
90495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        }
91495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        public Set<K> keySet() {
92495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert            return map.keySet();
93495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        }
94495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        public Map<K, Set<V>> asMap() {
95495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert            return map;
96495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        }
97495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        public Set<V> values() {
98495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert            Collection<Set<V>> values = map.values();
99495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert            if (values.size() == 0) {
100495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert                return Collections.<V>emptySet();
101495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert            }
102495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert            Set<V> result = getInstance();
103495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert            for ( Set<V> valueSet : values) {
104495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert                result.addAll(valueSet);
105495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert            }
106495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert            return result;
107495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        }
108495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        public int size() {
109495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert            return map.size();
110495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        }
111495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        public Iterable<Entry<K, V>> entries() {
112495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert            return new MultimapIterator<K, V>(map);
113495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        }
114495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        @Override
115495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        public boolean equals(Object obj) {
116495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert            return this == obj ||
117495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert                    (obj != null
118495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert                    && obj.getClass() == this.getClass()
119495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert                    && map.equals(((Multimap<?,?>) obj).map));
120495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        }
121495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert
122495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        @Override
123495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        public int hashCode() {
124495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert            return map.hashCode();
125495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        }
126495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert    }
127495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert
128495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert    public static class Multimaps {
129495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        public static <K, V, R extends Multimap<K, V>> R invertFrom(Multimap<V, K> source, R target) {
130495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert            for (Entry<V, Set<K>> entry : source.asMap().entrySet()) {
131495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert                target.putAll(entry.getValue(), entry.getKey());
132495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert            }
133495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert            return target;
134495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        }
135495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        public static <K, V, R extends Multimap<K, V>> R invertFrom(Map<V, K> source, R target) {
136495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert            for (Entry<V, K> entry : source.entrySet()) {
137495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert                target.put(entry.getValue(), entry.getKey());
138495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert            }
139495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert            return target;
140495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        }
141495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        /**
142495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert         * Warning, not functionally the same as Guava; only for use in invertFrom.
143495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert         */
144495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        public static <K, V> Map<K,V> forMap(Map<K,V> map) {
145495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert            return map;
146495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        }
147495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert    }
148495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert
149495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert    private static class MultimapIterator<K,V> implements Iterator<Entry<K,V>>, Iterable<Entry<K,V>> {
150495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        private final Iterator<Entry<K, Set<V>>> it1;
151495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        private Iterator<V> it2 = null;
152495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        private final ReusableEntry<K,V> entry = new ReusableEntry<K,V>();
153495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert
154495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        private MultimapIterator(Map<K,Set<V>> map) {
155495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert            it1 = map.entrySet().iterator();
156495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        }
157495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        @Override
158495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        public boolean hasNext() {
159495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert            return it1.hasNext() || it2 != null && it2.hasNext();
160495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        }
161495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        @Override
162495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        public Entry<K, V> next() {
163495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert            if (it2 != null && it2.hasNext()) {
164495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert                entry.value = it2.next();
165495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert            } else {
166495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert                Entry<K, Set<V>> e = it1.next();
167495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert                entry.key = e.getKey();
168495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert                it2 = e.getValue().iterator();
169495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert            }
170495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert            return entry;
171495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        }
172495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        @Override
173495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        public Iterator<Entry<K, V>> iterator() {
174495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert            return this;
175495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        }
176495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        @Override
177495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        public void remove() {
178495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert            throw new UnsupportedOperationException();
179495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        }
180495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert    }
181495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert
182495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert    private static class ReusableEntry<K,V> implements Entry<K,V> {
183495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        K key;
184495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        V value;
185495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        @Override
186495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        public K getKey() {
187495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert            return key;
188495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        }
189495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        @Override
190495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        public V getValue() {
191495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert            return value;
192495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        }
193495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        @Override
194495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        public V setValue(V value) {
195495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert            throw new UnsupportedOperationException();
196495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        }
197495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert    }
198495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert
199495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert    public static class HashMultimap<K, V> extends Multimap<K, V> {
200495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        private HashMultimap() {
201495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert            super(new HashMap<K, Set<V>>(), HashSet.class);
202495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        }
203495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        public static <K, V> HashMultimap<K, V> create() {
204495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert            return new HashMultimap<K, V>();
205495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        }
206495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert    }
207495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert
208495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert    public static class TreeMultimap<K, V> extends Multimap<K, V> {
209495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        private TreeMultimap() {
210495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert            super(new TreeMap<K, Set<V>>(), TreeSet.class);
211495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        }
212495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        public static <K, V> TreeMultimap<K, V> create() {
213495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert            return new TreeMultimap<K, V>();
214495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        }
215495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert    }
216495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert
217495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert    public static class LinkedHashMultimap<K, V> extends Multimap<K, V> {
218495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        private LinkedHashMultimap() {
219495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert            super(new LinkedHashMap<K, Set<V>>(), LinkedHashSet.class);
220495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        }
221495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        public static <K, V> LinkedHashMultimap<K, V> create() {
222495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert            return new LinkedHashMultimap<K, V>();
223495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        }
224495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert    }
225495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert
226495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert
227495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert    //    public static class Counter<T> implements Iterable<T>{
228495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert    //        private Map<T,Long> data;
229495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert    //        @Override
230495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert    //        public Iterator<T> iterator() {
231495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert    //            return data.keySet().iterator();
232495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert    //        }
233495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert    //        public long get(T s) {
234495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert    //            Long result = data.get(s);
235495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert    //            return result != null ? result : 0L;
236495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert    //        }
237495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert    //        public void add(T item, int count) {
238495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert    //            Long result = data.get(item);
239495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert    //            data.put(item, result == null ? count : result + count);
240495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert    //        }
241495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert    //    }
242495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert
243495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert    public static <T> String join(T[] source, String separator) {
244495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        StringBuilder result = new StringBuilder();
245495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        for (int i = 0; i < source.length; ++i) {
246495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert            if (i != 0) result.append(separator);
247495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert            result.append(source[i]);
248495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        }
249495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        return result.toString();
250495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert    }
251495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert
252495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert    public static <T> String join(Iterable<T> source, String separator) {
253495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        StringBuilder result = new StringBuilder();
254495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        boolean first = true;
255495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        for (T item : source) {
256495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert            if (!first) result.append(separator);
257495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert            else first = false;
258495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert            result.append(item.toString());
259495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        }
260495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        return result.toString();
261495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert    }
262495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert
263495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert    public static class CollectionUtilities {
264495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        public static <T, U extends Iterable<T>> String join(U source, String separator) {
265495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert            return XCldrStub.join(source, separator);
266495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        }
267495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert    }
268495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert
269495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert    public static class Joiner {
270495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        private final String separator;
271495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        private Joiner(String separator) {
272495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert            this.separator = separator;
273495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        }
274495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        public static final Joiner on(String separator) {
275495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert            return new Joiner(separator);
276495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        }
277495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        public <T> String join(T[] source) {
278495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert            return XCldrStub.join(source, separator);
279495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        }
280495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        public <T> String join(Iterable<T> source) {
281495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert            return XCldrStub.join(source, separator);
282495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        }
283495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert    }
284495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert
285495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert    public static class Splitter {
286495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        Pattern pattern;
287495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        boolean trimResults = false;
288495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        public Splitter(char c) {
289495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert            this(Pattern.compile("\\Q" + c + "\\E"));
290495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        }
291495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        public Splitter(Pattern p) {
292495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert            pattern = p;
293495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        }
294495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        public static Splitter on(char c) {
295495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert            return new Splitter(c);
296495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        }
297495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        public static Splitter on(Pattern p) {
298495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert            return new Splitter(p);
299495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        }
300495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        public List<String> splitToList(String input) {
301495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert            String[] items = pattern.split(input);
302495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert            if (trimResults) {
303495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert                for (int i = 0; i < items.length; ++i) {
304495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert                    items[i] = items[i].trim();
305495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert                }
306495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert            }
307495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert            return Arrays.asList(items);
308495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        }
309495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        public Splitter trimResults() {
310495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert            trimResults = true;
311495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert            return this;
312495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        }
313495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        public Iterable<String> split(String input) {
314495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert            return splitToList(input);
315495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        }
316495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert    }
317495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert
318495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert    public static class ImmutableSet {
319495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        public static <T> Set<T> copyOf(Set<T> values) {
320495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert            return Collections.unmodifiableSet(new LinkedHashSet<T>(values)); // copy set for safety, preserve order
321495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        }
322495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert    }
323495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert    public static class ImmutableMap {
324495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        public static <K,V> Map<K,V> copyOf(Map<K,V> values) {
325495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert            return Collections.unmodifiableMap(new LinkedHashMap<K,V>(values)); // copy set for safety, preserve order
326495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        }
327495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert    }
328495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert    public static class ImmutableMultimap {
329495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        public static <K,V> Multimap<K,V> copyOf(Multimap<K,V> values) {
330495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert            LinkedHashMap<K, Set<V>> temp = new LinkedHashMap<K,Set<V>>(); // semi-deep copy, preserve order
331495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert            for (Entry<K, Set<V>> entry : values.asMap().entrySet()) {
332495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert                Set<V> value = entry.getValue();
333495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert                temp.put(entry.getKey(), value.size() == 1
334495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert                        ? Collections.singleton(value.iterator().next())
335495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert                                : Collections.unmodifiableSet(new LinkedHashSet<V>(value)));
336495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert            }
337495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert            return new Multimap<K,V>(Collections.unmodifiableMap(temp), null);
338495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        }
339495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert    }
340495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert
341495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert    public static class FileUtilities {
342495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        public static final Charset UTF8 = Charset.forName("utf-8");
343495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert
344495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        public static BufferedReader openFile(Class<?> class1, String file) {
345495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert            return openFile(class1, file, UTF8);
346495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        }
347495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert
348495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        public static BufferedReader openFile(Class<?> class1, String file, Charset charset) {
349495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert            // URL path = null;
350495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert            // String externalForm = null;
351495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert            try {
352495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert                final InputStream resourceAsStream = class1.getResourceAsStream(file);
353495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert                if (charset == null) {
354495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert                    charset = UTF8;
355495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert                }
356495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert                InputStreamReader reader = new InputStreamReader(resourceAsStream, charset);
357495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert                BufferedReader bufferedReader = new BufferedReader(reader, 1024 * 64);
358495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert                return bufferedReader;
359495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert            } catch (Exception e) {
360495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert                String className = class1 == null ? null : class1.getCanonicalName();
361495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert                String canonicalName = null;
362495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert                try {
363495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert                    String relativeFileName = getRelativeFileName(class1, "../util/");
364495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert                    canonicalName = new File(relativeFileName).getCanonicalPath();
365495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert                } catch (Exception e1) {
366495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert                    throw new ICUUncheckedIOException("Couldn't open file: " + file + "; relative to class: "
367495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert                            + className, e);
368495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert                }
369495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert                throw new ICUUncheckedIOException("Couldn't open file " + file + "; in path " + canonicalName + "; relative to class: "
370495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert                        + className, e);
371495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert            }
372495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        }
373495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        public static String getRelativeFileName(Class<?> class1, String filename) {
374495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert            URL resource = class1 == null ?
375495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert                    FileUtilities.class.getResource(filename) : class1.getResource(filename);
376495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert                    String resourceString = resource.toString();
377495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert                    if (resourceString.startsWith("file:")) {
378495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert                        return resourceString.substring(5);
379495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert                    } else if (resourceString.startsWith("jar:file:")) {
380495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert                        return resourceString.substring(9);
381495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert                    } else {
382495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert                        throw new ICUUncheckedIOException("File not found: " + resourceString);
383495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert                    }
384495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        }
385495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert    }
386495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert
387495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert    static public class RegexUtilities {
388495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        public static int findMismatch(Matcher m, CharSequence s) {
389495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert            int i;
390495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert            for (i = 1; i < s.length(); ++i) {
391495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert                boolean matches = m.reset(s.subSequence(0, i)).matches();
392495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert                if (!matches && !m.hitEnd()) {
393495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert                    break;
394495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert                }
395495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert            }
396495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert            return i - 1;
397495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        }
398495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        public static String showMismatch(Matcher m, CharSequence s) {
399495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert            int failPoint = findMismatch(m, s);
400495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert            String show = s.subSequence(0, failPoint) + "☹" + s.subSequence(failPoint, s.length());
401495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert            return show;
402495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        }
403495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert    }
404495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert
405495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert    public interface Predicate<T> {
406495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        /**
407495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert         * Evaluates this predicate on the given argument.
408495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert         *
409495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert         * @param t the input argument
410495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert         * @return {@code true} if the input argument matches the predicate,
411495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert         * otherwise {@code false}
412495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert         */
413495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert        boolean test(T t);
414495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert    }
415495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert}