private void addSimilarNames(String namePiece, Collection<String> tokens) {
      String[] names = null;
      boolean memcacheLookupFailed = false;

      // if we read similar names from a file, look up there first
      if (similarNames != null) {
         names = similarNames.get(namePiece);
      }
      else {
         // try the cache if we have one
         if (memcachedClient != null) {
            names = (String[]) memcachedClient.get(memcacheKeyPrefix+namePiece);
            if (names == null) {
               memcacheLookupFailed = true;
            }
         }

         // try the database
         if (names == null) {
            names = readSimilarNamesFromDb(namePiece);
         }
      }

      // if all else fails, get similar names from soundex code map
      if (names == null) {
         try {
            names = codeMap.get(coder.encode(namePiece));
         } catch (EncoderException e) {
            logger.warning("Error encoding: "+namePiece);
         }
         if (names == null) {
            names = new String[0];
         }
      }

      if (memcacheLookupFailed) {
         memcachedClient.set(memcacheKeyPrefix+namePiece, memcacheExpiration, names);
      }

      Collections.addAll(tokens, names);
   }