+ * A local iterator which reverse iterates over hidden column regions in a
+ * range. Intended for use ONLY within the HiddenColumns class, because it
+ * works directly with the hiddenColumns collection without locking (callers
+ * should lock hiddenColumns).
+ */
+ private class ReverseRegionsIterator implements Iterator<int[]>
+ {
+ // start position to iterate to
+ private int start;
+
+ // end position to iterate from
+ private int end;
+
+ // current index in hiddenColumns
+ private int currentPosition = 0;
+
+ // current column in hiddenColumns
+ private int[] nextRegion = null;
+
+ // Constructor with bounds
+ ReverseRegionsIterator(int lowerBound, int upperBound)
+ {
+ init(lowerBound, upperBound);
+ }
+
+ // Unbounded constructor
+ ReverseRegionsIterator()
+ {
+ if (hiddenColumns != null)
+ {
+ // iterator over full hiddenColumns collection
+ int last = hiddenColumns.get(hiddenColumns.size() - 1)[1];
+ init(0, last);
+ }
+ else
+ {
+ // empty iterator
+ init(0, 0);
+ }
+ }
+
+ /**
+ * Construct an iterator over hiddenColums bounded at
+ * [lowerBound,upperBound]
+ *
+ * @param lowerBound
+ * lower bound to iterate to
+ * @param upperBound
+ * upper bound to iterate from
+ */
+ private void init(int lowerBound, int upperBound)
+ {
+ start = lowerBound;
+ end = upperBound;
+
+ if (hiddenColumns != null)
+ {
+ // iterate until a region overlaps with [start,end]
+ currentPosition = hiddenColumns.size() - 1;
+ while (currentPosition >= 0
+ && hiddenColumns.get(currentPosition)[1] > end)
+ {
+ currentPosition--;
+ }
+ if (currentPosition >= 0)
+ {
+ nextRegion = hiddenColumns.get(currentPosition);
+ }
+ }
+ }
+
+ @Override
+ public boolean hasNext()
+ {
+ return (hiddenColumns != null) && (nextRegion != null)
+ && (nextRegion[1] >= start);
+ }
+
+ @Override
+ public int[] next()
+ {
+ int[] region = nextRegion;
+ currentPosition--;
+ if (currentPosition >= 0)
+ {
+ nextRegion = hiddenColumns.get(currentPosition);
+ }
+ else
+ {
+ nextRegion = null;
+ }
+ return region;
+ }
+
+ }
+
+ /**