AlignedString implements Iterable<AlignedString.DataSegment> { public ImmutableInterval inverseResolve(final ImmutableInterval i) { if (_underlying == null) { return i; } int start = -1; AbstractDataSegment seg = _first; for (; seg != null; seg = seg.getNext()) { if (seg.isAnchor()) { continue; } final Interval ulpos = resolve(new ImmutableInterval(seg.getStart(), seg.getEnd())); final int ulend = ulpos.getEnd(); if (ulend <= i.getStart()) { continue; } final int ulstart = ulpos.getStart(); if ((ulstart <= i.getStart()) && (i.getStart() < ulend)) { start = seg.getStart() + (i.getStart() - ulstart); break; } if (ulstart >= i.getEnd()) { seg = seg.getNext(); } break; } if (start == -1) { if (seg != null) { start = seg.getStart(); } else { start = _last.getPosition(); } } int end = -1; ObliqueSegment last = null; for (; seg != null; seg = seg.getNext()) { if (seg instanceof ObliqueSegment) { final ObliqueSegment oseg = (ObliqueSegment) seg; final int ulend = oseg._end.getPosition(); if (ulend <= i.getEnd()) { last = oseg; continue; } final int ulstart = oseg._start.getPosition(); if ((ulstart <= i.getEnd()) && (i.getEnd() < ulend)) { end = seg.getStart() + (i.getEnd() - ulstart); break; } break; } } if (end == -1) { if (last != null) { end = last.getEnd(); } else { end = start; } } return new ImmutableInterval(start, end); } private  AlignedString();  AlignedString(final String base);  AlignedString(final AlignedString underlying); void fireChange(); Interval resolve(final Interval i); ImmutableInterval inverseResolve(final ImmutableInterval i); AbstractDataSegment getSegmentAt(final int position); AbstractDataSegment getFirst(); AbstractDataSegment getLast(); @Override Iterator<DataSegment> iterator(); int length(); String get(); void updateCaches(); String get(final int start, final int end); void insert(final int pos, final String s); void delete(final int start, final int end); void replace(final int start, final int end, final String d); Anchor getAnchor(final int pos); Collection<Anchor> getAnchors(); Collection<DataSegment> getSegments(); String dataSegmentsToString(); @Override String toString();  }
@Test public void testInverseResolve() { bottom = new AlignedString("111XX222XXXXX3333XX44XXXX5555XXXX"); bottom.insert(7, "ZZ"); assertEquals("111XX22ZZ2XXXXX3333XX44XXXX5555XXXX", bottom.get()); top = new AlignedString(bottom); top.delete(31, 35); assertEquals("111XX22ZZ2XXXXX3333XX44XXXX5555", top.get()); top.delete(23, 27); assertEquals("111XX22ZZ2XXXXX3333XX445555", top.get()); top.delete(19, 21); assertEquals("111XX22ZZ2XXXXX3333445555", top.get()); top.delete(10, 15); assertEquals("111XX22ZZ23333445555", top.get()); top.delete(3, 5); assertEquals("11122ZZ23333445555", top.get()); top.insert(16, "YYY"); assertEquals("11122ZZ233334455YYY55", top.get()); final ImmutableInterval uli = new ImmutableInterval(22, 30); System.out.println("ULI : " + bottom.get(uli.getStart(), uli.getEnd())); final ImmutableInterval adi = top.inverseResolve(uli); System.out.println("ADI : " + top.get(adi.getStart(), adi.getEnd())); assertEquals(new ImmutableInterval(13, 20), adi); assertEquals("455YYY5", top.get(adi.getStart(), adi.getEnd())); assertEquals("4XXXX555", bottom.get(uli.getStart(), uli.getEnd())); }