+ return null;// (diff<0) ? (intv[1]-1) : (intv[0]+1);
+ }
+
+ /**
+ * find series of intervals mapping from start-end in the From map.
+ *
+ * @param start
+ * position in to map
+ * @param end
+ * position in to map
+ * @return series of ranges in from map
+ */
+ public int[] locateInFrom(int start, int end)
+ {
+ // inefficient implementation
+ int fromStart[] = shiftTo(start);
+ int fromEnd[] = shiftTo(end); // needs to be inclusive of end of symbol
+ // position
+ if (fromStart == null || fromEnd == null)
+ return null;
+ int iv[] = getIntervals(fromShifts, fromStart, fromEnd, fromRatio);
+ return iv;
+ }
+
+ /**
+ * find series of intervals mapping from start-end in the to map.
+ *
+ * @param start
+ * position in from map
+ * @param end
+ * position in from map
+ * @return series of ranges in to map
+ */
+ public int[] locateInTo(int start, int end)
+ {
+ // inefficient implementation
+ int toStart[] = shiftFrom(start);
+ int toEnd[] = shiftFrom(end);
+ if (toStart == null || toEnd == null)
+ return null;
+ int iv[] = getIntervals(toShifts, toStart, toEnd, toRatio);
+ return iv;
+ }
+
+ /**
+ * like shift - except returns the intervals in the given vector of shifts
+ * which were spanned in traversing fromStart to fromEnd
+ *
+ * @param fromShifts2
+ * @param fromStart
+ * @param fromEnd
+ * @param fromRatio2
+ * @return series of from,to intervals from from first position of starting
+ * region to final position of ending region inclusive
+ */
+ private int[] getIntervals(Vector fromShifts2, int[] fromStart,
+ int[] fromEnd, int fromRatio2)
+ {
+ int startpos, endpos;
+ startpos = fromStart[0]; // first position in fromStart
+ endpos = fromEnd[0]; // last position in fromEnd
+ int endindx = (fromRatio2 - 1); // additional positions to get to last
+ // position from endpos
+ int intv = 0, intvSize = fromShifts2.size();
+ int iv[], i = 0, fs = -1, fe_s = -1, fe = -1; // containing intervals
+ // search intervals to locate ones containing startpos and count endindx
+ // positions on from endpos
+ while (intv < intvSize && (fs == -1 || fe == -1))
+ {
+ iv = (int[]) fromShifts2.elementAt(intv++);
+ if (fe_s > -1)
+ {
+ endpos = iv[0]; // start counting from beginning of interval
+ endindx--; // inclusive of endpos
+ }
+ if (iv[0] <= iv[1])
+ {
+ if (fs == -1 && startpos >= iv[0] && startpos <= iv[1])
+ {
+ fs = i;
+ }
+ if (endpos >= iv[0] && endpos <= iv[1])
+ {
+ if (fe_s == -1)
+ {
+ fe_s = i;
+ }
+ if (fe_s != -1)
+ {
+ if (endpos + endindx <= iv[1])
+ {
+ fe = i;
+ endpos = endpos + endindx; // end of end token is within this
+ // interval
+ }
+ else
+ {
+ endindx -= iv[1] - endpos; // skip all this interval too
+ }
+ }
+ }
+ }
+ else
+ {
+ if (fs == -1 && startpos <= iv[0] && startpos >= iv[1])
+ {
+ fs = i;
+ }
+ if (endpos <= iv[0] && endpos >= iv[1])
+ {
+ if (fe_s == -1)
+ {
+ fe_s = i;
+ }
+ if (fe_s != -1)
+ {
+ if (endpos - endindx >= iv[1])
+ {
+ fe = i;
+ endpos = endpos - endindx; // end of end token is within this
+ // interval
+ }
+ else
+ {
+ endindx -= endpos - iv[1]; // skip all this interval too
+ }
+ }
+ }
+ }
+ i++;
+ }
+ if (fs == fe && fe == -1)
+ return null;
+ Vector ranges = new Vector();
+ if (fs <= fe)
+ {
+ intv = fs;
+ i = fs;
+ // truncate initial interval
+ iv = (int[]) fromShifts2.elementAt(intv++);
+ iv = new int[]
+ { iv[0], iv[1] };// clone
+ if (i == fs)
+ iv[0] = startpos;
+ while (i != fe)
+ {
+ ranges.addElement(iv); // add initial range
+ iv = (int[]) fromShifts2.elementAt(intv++); // get next interval
+ iv = new int[]
+ { iv[0], iv[1] };// clone
+ i++;
+ }
+ if (i == fe)
+ iv[1] = endpos;
+ ranges.addElement(iv); // add only - or final range
+ }
+ else
+ {
+ // walk from end of interval.
+ i = fromShifts2.size() - 1;
+ while (i > fs)
+ {
+ i--;
+ }
+ iv = (int[]) fromShifts2.elementAt(i);
+ iv = new int[]
+ { iv[1], iv[0] };// reverse and clone
+ // truncate initial interval
+ if (i == fs)
+ {
+ iv[0] = startpos;
+ }
+ while (--i != fe)
+ { // fix apparent logic bug when fe==-1
+ ranges.addElement(iv); // add (truncated) reversed interval
+ iv = (int[]) fromShifts2.elementAt(i);
+ iv = new int[]
+ { iv[1], iv[0] }; // reverse and clone
+ }
+ if (i == fe)
+ {
+ // interval is already reversed
+ iv[1] = endpos;
+ }
+ ranges.addElement(iv); // add only - or final range
+ }
+ // create array of start end intervals.
+ int[] range = null;
+ if (ranges != null && ranges.size() > 0)
+ {
+ range = new int[ranges.size() * 2];
+ intv = 0;
+ intvSize = ranges.size();
+ i = 0;
+ while (intv < intvSize)
+ {
+ iv = (int[]) ranges.elementAt(intv);
+ range[i++] = iv[0];
+ range[i++] = iv[1];
+ ranges.setElementAt(null, intv++); // remove
+ }
+ }
+ return range;
+ }
+
+ /**
+ * get the 'initial' position of mpos in To
+ *
+ * @param mpos
+ * position in from
+ * @return position of first word in to reference frame
+ */
+ public int getToPosition(int mpos)
+ {
+ int[] mp = shiftTo(mpos);
+ if (mp != null)
+ {
+ return mp[0];
+ }
+ return mpos;