code: package net.codebox.homoglyph;
  
  import java.io.*;
  import java.util.*;
  
  /**
   * Helper class providing methods that supply populated Homoglyph objects.
   *
   * @author Rob Dawson
   */
  public class HomoglyphBuilder {
      private static final String CHAR_CODES_FILE = "/char_codes.txt";
  
      /**
       * Parses the bundled char_codes.txt file, and uses it to construct a populated Homoglyph object.
       *
       * @return a Homoglyph object populated using the contents of the char_codes.txt file
       *
       * @throws MissingResourceException if the char_codes.txt file is missing
       * @throws IOException if the char_codes.txt exists but cannot be read
       */
      public static Homoglyph build() throws IOException {
          final InputStream is = HomoglyphBuilder.class.getResourceAsStream(CHAR_CODES_FILE);
          if (is == null){
              throw new MissingResourceException("Unable to read " + CHAR_CODES_FILE,
                      HomoglyphBuilder.class.getName(), CHAR_CODES_FILE);
          }
  
          return build(new InputStreamReader(is));
      }
  
      /**
       * Parses the specified file and uses it to construct a populated Homoglyph object.
       *
       * @param path the path to a file containing a list of homoglyphs (see the bundled char_codes.txt
       *             file for an example of the required format)
       *
       * @return a Homoglyph object populated using the contents of the specified file
       *
       * @throws IOException if the specified file cannot be read
       */
      public static Homoglyph build(final String path) throws IOException {
          return build(new FileReader(path));
      }
  
      /**
       * Consumes the supplied Reader and uses it to construct a populated Homoglyph object.
       *
       * @param reader a Reader object that provides access to homoglyph data (see the bundled
       *               char_codes.txt file for an example of the required format)
       *
       * @return a Homoglyph object populated using the data returned by the Reader object
       *
       * @throws IOException if the specified Reader cannot be read
       */
      public static Homoglyph build(final Reader reader) throws IOException {
          final List<Set<Integer>> homoglyphs = new ArrayList<>();
  
          try (final BufferedReader bufferedReader = new BufferedReader(reader)) {
              String line;
              while((line = bufferedReader.readLine()) != null){
                  line = line.trim();
                  if (line.startsWith("#") || line.length() == 0){
                      continue;
                  }
                  final Set<Integer> set = new HashSet<>();
                  for (String charCode : line.split(",")) {
                      try {
                          set.add(Integer.parseInt(charCode, 16));
                      } catch (NumberFormatException ex){
                          // ignore badly formatted lines
                      }
                  }
                  homoglyphs.add(set);
              }
          }
  
          return new Homoglyph(homoglyphs);
      }
  
  }
  