/**
   * Restore all the properties to their initial default. This may not change properties that are
   * currently active or that are read at initialization. These changes will take effect at the next
   * restart.
   */
  public static synchronized void resetDefaultProperties() {
    BoardSetup setup = BoardSetup.getSetup();

    setup.resetProperties();

    for (Map.Entry<String, BoardProperties> ent : loaded_properties.entrySet()) {
      String id = ent.getKey();
      if (id.equals("System")) continue;
      BoardProperties bp = ent.getValue();
      bp.clear();
      bp.loadProperties(id);
    }
  }
  /**
   * Return an input stream for a library file with the given name. If no such file/resource exists,
   * returns null.
   */
  public static InputStream getLibraryFile(String name) {
    // allow user version in ~/.bubbles

    String pname = name.replace("/", File.separator);

    File dir0 = new File(prop_base);
    if (dir0.exists()) {
      File f3 = new File(dir0, pname);
      if (f3.exists() && f3.canRead()) {
        try {
          return new FileInputStream(f3);
        } catch (IOException e) {
        }
      }
    }

    BoardProperties sp = getProperties("System");
    String dir = sp.getProperty(BOARD_PROP_INSTALL_DIR);

    URL url = BoardProperties.class.getClassLoader().getResource(BOARD_RESOURCE_CHECK);

    // use jar version if available
    if (url != null) {
      String nm = "lib/" + name;
      InputStream ins = BoardProperties.class.getClassLoader().getResourceAsStream(nm);
      if (ins != null) return ins;
      dir = sp.getProperty(BOARD_PROP_JAR_DIR);
    }

    // use whats in the lib directory
    File f1 = new File(dir);
    File f2 = new File(f1, "lib");
    File f3 = new File(f2, pname);

    try {
      return new FileInputStream(f3);
    } catch (IOException e) {
    }

    return null;
  }
  /** ***************************************************************************** */
  private void setupSpacing() {
    // get the tab_size from appropriate property
    BoardProperties bp = BoardProperties.getProperties("Bale");
    String v = bp.getProperty("indent.tabulation.size");
    if (v == null)
      v = BumpClient.getBump().getOption("org.eclipse.jdt.core.formatter.tabulation.size");
    if (v == null) v = bp.getProperty("Bale.tabsize");
    tab_size = 8;
    try {
      if (v != null) tab_size = Integer.parseInt(v);
    } catch (NumberFormatException e) {
    }

    region_map = null;
    regions_valid = true;
    indent_size = 0;
    indent_string = null;

    // determine minimum indent
    Segment s = new Segment();
    int minsp = -1;
    for (BaleRegion br : fragment_regions) {
      int soff = br.getStart();
      int eoff = br.getEnd();
      try {
        base_document.getText(soff, eoff - soff, s);
      } catch (BadLocationException e) {
        BoardLog.logE(
            "BALE",
            "Problem getting region text "
                + soff
                + " "
                + eoff
                + " "
                + s.length()
                + " "
                + base_document.getLength(),
            e);
        // should this be "throw e;"
        continue;
      }

      int ln = s.length();

      boolean sol = true;
      int ind = 0;
      for (int i = 0; i < ln && (minsp < 0 || minsp >= MIN_INDENT); ++i) {
        char c = s.charAt(i);
        if (sol) {
          switch (c) {
            case ' ':
              ind += 1;
              break;
            case '\t':
              ind = nextTabPosition(ind);
              break;
            case '\n':
              ind = 0;
              break;
            default:
              if (minsp < 0 || minsp > ind) minsp = ind;
              sol = false;
              break;
          }
        } else if (c == '\n') {
          sol = true;
          ind = 0;
        }
      }

      if (minsp >= 0 && minsp < MIN_INDENT) break;
    }

    if (minsp <= 0 || minsp < MIN_INDENT) return;

    indent_size = minsp;
    indent_string = "";
    for (int i = 0; i < minsp; ++i) indent_string += " ";

    region_map = new HashMap<BaleRegion, RegionData>();
    regions_valid = false;
    for (BaleRegion br : fragment_regions) {
      for (int i = getRegionLength(br) - 1; i >= 0; --i) {
        fixupOffset(br, i, true);
      }
    }
  }