+ private int[] countToPos(Vector intVals, int pos)
+ {
+ int count = 0, diff = 0, iv = 0, ivSize = intVals.size(), intv[] =
+ { 0, 0 };
+ while (iv < ivSize)
+ {
+ intv = (int[]) intVals.elementAt(iv++);
+ diff = intv[1] - intv[0];
+ if (diff >= 0)
+ {
+ if (pos <= count + 1 + diff)
+ {
+ return new int[]
+ { pos - count - 1 + intv[0], +1 };
+ }
+ else
+ {
+ count += 1 + diff;
+ }
+ }
+ else
+ {
+ if (pos <= count + 1 - diff)
+ {
+ return new int[]
+ { intv[0] - (pos - count - 1), -1 };
+ }
+ else
+ {
+ count += 1 - diff;
+ }
+ }
+ }
+ 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;
+ }
+
+ /**
+ * get range of positions in To frame for the mpos word in From
+ *
+ * @param mpos
+ * position in From
+ * @return null or int[] first position in To for mpos, last position in to
+ * for Mpos
+ */
+ public int[] getToWord(int mpos)
+ {
+ int[] mp = shiftTo(mpos);
+ if (mp != null)
+ {
+ return new int[]
+ { mp[0], mp[0] + mp[2] * (getFromRatio() - 1) };
+ }
+ return null;
+ }
+
+ /**
+ * get From position in the associated reference frame for position pos in the
+ * associated sequence.
+ *
+ * @param pos
+ * @return
+ */
+ public int getMappedPosition(int pos)
+ {
+ int[] mp = shiftFrom(pos);
+ if (mp != null)
+ {
+ return mp[0];
+ }
+ return pos;
+ }
+
+ public int[] getMappedWord(int pos)
+ {
+ int[] mp = shiftFrom(pos);
+ if (mp != null)
+ {
+ return new int[]
+ { mp[0], mp[0] + mp[2] * (getToRatio() - 1) };
+ }
+ return null;
+ }
+
+ /**
+ * test routine. not incremental.
+ *
+ * @param ml
+ * @param fromS
+ * @param fromE
+ */
+ public static void testMap(MapList ml, int fromS, int fromE)
+ {
+ for (int from = 1; from <= 25; from++)
+ {
+ int[] too = ml.shiftFrom(from);
+ System.out.print("ShiftFrom(" + from + ")==");
+ if (too == null)
+ {
+ System.out.print("NaN\n");
+ }
+ else
+ {
+ System.out.print(too[0] + " % " + too[1] + " (" + too[2] + ")");
+ System.out.print("\t+--+\t");
+ int[] toofrom = ml.shiftTo(too[0]);
+ if (toofrom != null)
+ {
+ if (toofrom[0] != from)
+ {
+ System.err.println("Mapping not reflexive:" + from + " "
+ + too[0] + "->" + toofrom[0]);