code: @Override
      public synchronized Collection<MatchInfo> find(CharSequence text, int start, EnumSet<NameType> nameTypes) {
          if (text == null || text.length() == 0 || start < 0 || start >= text.length()) {
              throw new IllegalArgumentException("bad input text or range");
          }
          NameSearchHandler handler = new NameSearchHandler(nameTypes);
          Collection<MatchInfo> matches;
  
          // First try of lookup.
          matches = doFind(handler, text, start);
          if (matches != null) {
              return matches;
          }
  
          // All names are not yet loaded into the trie.
          // We may have loaded names for formatting several time zones,
          // and might be parsing one of those.
          // Populate the parsing trie from all of the already-loaded names.
          addAllNamesIntoTrie();
  
          // Second try of lookup.
          matches = doFind(handler, text, start);
          if (matches != null) {
              return matches;
          }
  
          // There are still some names we haven't loaded into the trie yet.
          // Load everything now.
          internalLoadAllDisplayNames();
  
          // Set default time zone location names
          // for time zones without explicit display names.
          // TODO: Should this logic be moved into internalLoadAllDisplayNames?
          Set<String> tzIDs = TimeZone.getAvailableIDs(SystemTimeZoneType.CANONICAL, null, null);
          for (String tzID : tzIDs) {
              if (!_tzNamesMap.containsKey(tzID)) {
                  ZNames.createTimeZoneAndPutInCache(_tzNamesMap, null, tzID);
              }
          }
          addAllNamesIntoTrie();
          _namesTrieFullyLoaded = true;
  
          // Third try: we must return this one.
          return doFind(handler, text, start);
      }
docs: /* (non-Javadoc)
  @see android.icu.text.TimeZoneNames#find(java.lang.CharSequence, int, java.util.Set)