protected boolean getRegionText(BaleRegion br, int off, int len, Segment text)
      throws BadLocationException {
    int soff = br.getStart();
    int eoff = br.getEnd();

    if (region_map != null) {
      validateRegions();
      RegionData rd = region_map.get(br);
      Segment rtext = new Segment();
      base_document.getText(soff, eoff - soff, rtext);
      return rd.getText(rtext, off, len, text);
    }

    int doff = off + soff;
    int dlen = len;

    boolean lastbad = false;
    if (br.includesEol()) {
      if (doff + dlen > eoff) dlen = eoff - off;
      base_document.getText(doff, len, text);
    } else {
      if (doff + dlen > eoff) dlen = eoff - off + 1;
      base_document.getText(doff, len, text);
      lastbad = (doff + len > eoff); // if last character might be bad
    }

    return lastbad;
  }
 IndentPosition(BaleRegion br, int off) throws BadLocationException {
   RegionData rd = region_map.get(br);
   validateRegions();
   int roff = rd.getRegionOffset(br, off);
   int voff = rd.getViewOffset(roff);
   local_offset = off - voff;
   base_position = base_document.createPosition(br.getStart() + roff);
 }
 private void fixupOffset(BaleRegion br, int off, boolean edit) {
   if (edit && region_map != null) {
     validateRegions();
     RegionData rd = region_map.get(br);
     rd.fixupOffset(br, off);
   }
   validateRegions();
 }
  protected int mapViewOffsetToRegion(BaleRegion br, int offset, boolean edit) {
    if (region_map != null) {
      fixupOffset(br, offset, edit);
      RegionData rd = region_map.get(br);
      return rd.getRegionOffset(br, offset);
    }

    return offset;
  }
  protected int mapRegionOffsetToView(BaleRegion br, int offset) {
    if (region_map != null) {
      validateRegions();
      RegionData rd = region_map.get(br);
      return rd.getViewOffset(offset);
    }

    return offset;
  }
  /** ***************************************************************************** */
  protected int getRegionLength(BaleRegion br) {
    int len = br.getEnd() - br.getStart();

    if (!br.includesEol()) len += 1;

    if (region_map != null) {
      validateRegions();
      RegionData rd = region_map.get(br);
      len += rd.getDeltaLength();
    }

    return len;
  }
  private void validateRegions() {
    if (region_map == null) return;

    synchronized (region_map) {
      if (regions_valid) return;

      Segment s = new Segment();

      region_map.clear();

      for (BaleRegion br : fragment_regions) {
        RegionData rd = new RegionData(indent_size);
        region_map.put(br, rd);
        int soff = br.getStart();
        int eoff = br.getEnd();
        if (eoff < soff) continue;
        try {
          base_document.getText(soff, eoff - soff, s);
        } catch (BadLocationException e) {
          BoardLog.logE("BALE", "Problem getting region indentation", e);
          continue;
        }
        int ln = s.length();

        LineData ld;
        boolean sol = true;
        for (int i = 0; i < ln; ++i) {
          char c = s.charAt(i);
          if (sol) {
            ld = computeLineData(i, s);
            rd.add(ld);
            sol = false;
          }
          if (c == '\n') sol = true;
        }
        if (!sol) {
          ld = computeLineData(ln, s);
          rd.add(ld);
          ++ln;
        }
      }

      regions_valid = true;
    }
  }