JAL-2674 Tidies
[jalview.git] / test / jalview / datamodel / HiddenColumnsTest.java
index 1aec1d3..192a822 100644 (file)
@@ -29,10 +29,9 @@ import jalview.analysis.AlignmentGenerator;
 import jalview.gui.JvOptionPane;
 import jalview.util.Comparison;
 
-import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.BitSet;
-import java.util.List;
+import java.util.Iterator;
 import java.util.Random;
 
 import org.testng.annotations.BeforeClass;
@@ -184,12 +183,14 @@ public class HiddenColumnsTest
   }
 
   @Test(groups = { "Functional" })
-  public void testGetVisibleContigs()
+  public void testVisibleContigsIterator()
   {
     HiddenColumns cs = new HiddenColumns();
 
-    int[] visible = cs.getVisibleContigs(3, 10);
-    assertEquals("[]", Arrays.toString(visible));
+    Iterator<int[]> visible = cs.getVisContigsIterator(3, 10);
+    int[] region = visible.next();
+    assertEquals("[3, 9]", Arrays.toString(region));
+    assertFalse(visible.hasNext());
 
     cs.hideColumns(3, 6);
     cs.hideColumns(8, 9);
@@ -198,24 +199,44 @@ public class HiddenColumnsTest
     // Test both ends visible region
 
     // start position is inclusive, end position exclusive
-    visible = cs.getVisibleContigs(1, 13);
-    assertEquals("[1, 2, 7, 7, 10, 11]", Arrays.toString(visible));
+    visible = cs.getVisContigsIterator(1, 13);
+    region = visible.next();
+    assertEquals("[1, 2]", Arrays.toString(region));
+    region = visible.next();
+    assertEquals("[7, 7]", Arrays.toString(region));
+    region = visible.next();
+    assertEquals("[10, 11]", Arrays.toString(region));
+    assertFalse(visible.hasNext());
 
     // Test start hidden, end visible
-    visible = cs.getVisibleContigs(4, 14);
-    assertEquals("[7, 7, 10, 11, 13, 13]", Arrays.toString(visible));
+    visible = cs.getVisContigsIterator(4, 14);
+    region = visible.next();
+    assertEquals("[7, 7]", Arrays.toString(region));
+    region = visible.next();
+    assertEquals("[10, 11]", Arrays.toString(region));
+    region = visible.next();
+    assertEquals("[13, 13]", Arrays.toString(region));
+    assertFalse(visible.hasNext());
 
     // Test start hidden, end hidden
-    visible = cs.getVisibleContigs(3, 10);
-    assertEquals("[7, 7]", Arrays.toString(visible));
+    visible = cs.getVisContigsIterator(3, 10);
+    region = visible.next();
+    assertEquals("[7, 7]", Arrays.toString(region));
+    assertFalse(visible.hasNext());
 
     // Test start visible, end hidden
-    visible = cs.getVisibleContigs(0, 13);
-    assertEquals("[0, 2, 7, 7, 10, 11]", Arrays.toString(visible));
+    visible = cs.getVisContigsIterator(0, 13);
+    region = visible.next();
+    assertEquals("[0, 2]", Arrays.toString(region));
+    region = visible.next();
+    assertEquals("[7, 7]", Arrays.toString(region));
+    region = visible.next();
+    assertEquals("[10, 11]", Arrays.toString(region));
+    assertFalse(visible.hasNext());
 
     // Test empty result
-    visible = cs.getVisibleContigs(4, 6);
-    assertEquals("[]", Arrays.toString(visible));
+    visible = cs.getVisContigsIterator(4, 6);
+    assertFalse(visible.hasNext());
   }
 
   @Test(groups = { "Functional" })
@@ -247,17 +268,48 @@ public class HiddenColumnsTest
     HiddenColumns cs = new HiddenColumns();
     cs.hideColumns(10, 11);
     cs.hideColumns(5, 7);
+    Iterator<int[]> regions = cs.iterator();
     assertEquals("[5, 7]",
-            Arrays.toString(cs.getHiddenColumnsCopy().get(0)));
+            Arrays.toString(regions.next()));
 
     HiddenColumns cs2 = new HiddenColumns(cs);
+    regions = cs2.iterator();
     assertTrue(cs2.hasHiddenColumns());
-    assertEquals(2, cs2.getHiddenColumnsCopy().size());
+    assertEquals(2, cs2.getNumberOfRegions());
     // hidden columns are held in column order
     assertEquals("[5, 7]",
-            Arrays.toString(cs2.getHiddenColumnsCopy().get(0)));
+            Arrays.toString(regions.next()));
     assertEquals("[10, 11]",
-            Arrays.toString(cs2.getHiddenColumnsCopy().get(1)));
+            Arrays.toString(regions.next()));
+  }
+
+  @Test(groups = "Functional")
+  public void testCopyConstructor2()
+  {
+    HiddenColumns cs = new HiddenColumns();
+    cs.hideColumns(10, 11);
+    cs.hideColumns(5, 7);
+
+    HiddenColumns cs2 = new HiddenColumns(cs, 3, 9, 1);
+    assertTrue(cs2.hasHiddenColumns());
+    Iterator<int[]> regions = cs2.iterator();
+
+    // only [5,7] returned, offset by 1
+    assertEquals("[4, 6]",
+            Arrays.toString(regions.next()));
+    assertEquals(3, cs2.getSize());
+
+    cs2 = new HiddenColumns(cs, 8, 15, 4);
+    regions = cs2.iterator();
+    assertTrue(cs2.hasHiddenColumns());
+
+    // only [10,11] returned, offset by 4
+    assertEquals("[6, 7]",
+            Arrays.toString(regions.next()));
+    assertEquals(2, cs2.getSize());
+
+    cs2 = new HiddenColumns(cs, 6, 10, 4);
+    assertFalse(cs2.hasHiddenColumns());
   }
 
   /**
@@ -521,80 +573,79 @@ public class HiddenColumnsTest
     ColumnSelection colsel = new ColumnSelection();
     HiddenColumns cs = al.getHiddenColumns();
     colsel.hideSelectedColumns(5, al.getHiddenColumns());
-    List<int[]> hidden = cs.getHiddenColumnsCopy();
-    assertEquals(1, hidden.size());
-    assertEquals("[5, 5]", Arrays.toString(hidden.get(0)));
+    Iterator<int[]> regions = cs.iterator();
+    assertEquals(1, cs.getNumberOfRegions());
+    assertEquals("[5, 5]", Arrays.toString(regions.next()));
 
     colsel.hideSelectedColumns(3, al.getHiddenColumns());
-    hidden = cs.getHiddenColumnsCopy();
-    assertEquals(2, hidden.size());
+    regions = cs.iterator();
+    assertEquals(2, cs.getNumberOfRegions());
     // two hidden ranges, in order:
-    assertEquals(hidden.size(), cs.getHiddenColumnsCopy().size());
-    assertEquals("[3, 3]", Arrays.toString(hidden.get(0)));
-    assertEquals("[5, 5]", Arrays.toString(hidden.get(1)));
+    assertEquals("[3, 3]", Arrays.toString(regions.next()));
+    assertEquals("[5, 5]", Arrays.toString(regions.next()));
 
     // hiding column 4 expands [3, 3] to [3, 4]
     // and merges to [5, 5] to make [3, 5]
     colsel.hideSelectedColumns(4, al.getHiddenColumns());
-    hidden = cs.getHiddenColumnsCopy();
-    assertEquals(1, hidden.size());
-    assertEquals("[3, 5]", Arrays.toString(hidden.get(0)));
+    regions = cs.iterator();
+    assertEquals(1, cs.getNumberOfRegions());
+    assertEquals("[3, 5]", Arrays.toString(regions.next()));
 
     // clear hidden columns (note they are added to selected)
     cs.revealAllHiddenColumns(colsel);
     // it is now actually null but getter returns an empty list
-    assertTrue(cs.getHiddenColumnsCopy().isEmpty());
+    assertEquals(0, cs.getNumberOfRegions());
 
     cs.hideColumns(3, 6);
-    hidden = cs.getHiddenColumnsCopy();
-    int[] firstHiddenRange = hidden.get(0);
+    regions = cs.iterator();
+    int[] firstHiddenRange = regions.next();
     assertEquals("[3, 6]", Arrays.toString(firstHiddenRange));
 
     // adding a subrange of already hidden should do nothing
     cs.hideColumns(4, 5);
-    hidden = cs.getHiddenColumnsCopy();
-    assertEquals(1, hidden.size());
+    regions = cs.iterator();
+    assertEquals(1, cs.getNumberOfRegions());
     assertEquals("[3, 6]",
-            Arrays.toString(cs.getHiddenColumnsCopy().get(0)));
+            Arrays.toString(regions.next()));
     cs.hideColumns(3, 5);
-    hidden = cs.getHiddenColumnsCopy();
-    assertEquals(1, hidden.size());
+    regions = cs.iterator();
+    assertEquals(1, cs.getNumberOfRegions());
     assertEquals("[3, 6]",
-            Arrays.toString(cs.getHiddenColumnsCopy().get(0)));
+            Arrays.toString(regions.next()));
     cs.hideColumns(4, 6);
-    hidden = cs.getHiddenColumnsCopy();
-    assertEquals(1, hidden.size());
+    regions = cs.iterator();
+    assertEquals(1, cs.getNumberOfRegions());
     assertEquals("[3, 6]",
-            Arrays.toString(cs.getHiddenColumnsCopy().get(0)));
+            Arrays.toString(regions.next()));
     cs.hideColumns(3, 6);
-    hidden = cs.getHiddenColumnsCopy();
-    assertEquals(1, hidden.size());
+    regions = cs.iterator();
+    assertEquals(1, cs.getNumberOfRegions());
     assertEquals("[3, 6]",
-            Arrays.toString(cs.getHiddenColumnsCopy().get(0)));
+            Arrays.toString(regions.next()));
 
     cs.revealAllHiddenColumns(colsel);
     cs.hideColumns(2, 4);
-    hidden = cs.getHiddenColumnsCopy();
-    assertEquals(1, hidden.size());
-    assertEquals("[2, 4]", Arrays.toString(hidden.get(0)));
+    regions = cs.iterator();
+    assertEquals(1, cs.getNumberOfRegions());
+    assertEquals("[2, 4]", Arrays.toString(regions.next()));
 
     // extend contiguous with 2 positions overlap
     cs.hideColumns(3, 5);
-    hidden = cs.getHiddenColumnsCopy();
-    assertEquals(1, hidden.size());
-    assertEquals("[2, 5]", Arrays.toString(hidden.get(0)));
+    regions = cs.iterator();
+    assertEquals(1, cs.getNumberOfRegions());
+    assertEquals("[2, 5]", Arrays.toString(regions.next()));
 
     // extend contiguous with 1 position overlap
     cs.hideColumns(5, 6);
-    hidden = cs.getHiddenColumnsCopy();
-    assertEquals(1, hidden.size());
-    assertEquals("[2, 6]", Arrays.toString(hidden.get(0)));
+    regions = cs.iterator();
+    assertEquals(1, cs.getNumberOfRegions());
+    assertEquals("[2, 6]", Arrays.toString(regions.next()));
 
     // extend contiguous with overlap both ends:
     cs.hideColumns(1, 7);
-    hidden = cs.getHiddenColumnsCopy();
-    assertEquals(1, hidden.size());
-    assertEquals("[1, 7]", Arrays.toString(hidden.get(0)));
+    regions = cs.iterator();
+    assertEquals(1, cs.getNumberOfRegions());
+    assertEquals("[1, 7]", Arrays.toString(regions.next()));
   }
 
   /**
@@ -681,15 +732,15 @@ public class HiddenColumnsTest
     HiddenColumns cs = new HiddenColumns();
     cs.hideColumns(49, 59);
     cs.hideColumns(69, 79);
-    List<int[]> hidden = cs.getHiddenColumnsCopy();
-    assertEquals(2, hidden.size());
-    assertEquals("[49, 59]", Arrays.toString(hidden.get(0)));
-    assertEquals("[69, 79]", Arrays.toString(hidden.get(1)));
+    Iterator<int[]> regions = cs.iterator();
+    assertEquals(2, cs.getNumberOfRegions());
+    assertEquals("[49, 59]", Arrays.toString(regions.next()));
+    assertEquals("[69, 79]", Arrays.toString(regions.next()));
 
     cs.hideColumns(48, 80);
-    hidden = cs.getHiddenColumnsCopy();
-    assertEquals(1, hidden.size());
-    assertEquals("[48, 80]", Arrays.toString(hidden.get(0)));
+    regions = cs.iterator();
+    assertEquals(1, cs.getNumberOfRegions());
+    assertEquals("[48, 80]", Arrays.toString(regions.next()));
 
     /*
      * another...joining hidden ranges
@@ -700,9 +751,9 @@ public class HiddenColumnsTest
     cs.hideColumns(50, 60);
     // hiding 21-49 should merge to one range
     cs.hideColumns(21, 49);
-    hidden = cs.getHiddenColumnsCopy();
-    assertEquals(1, hidden.size());
-    assertEquals("[10, 60]", Arrays.toString(hidden.get(0)));
+    regions = cs.iterator();
+    assertEquals(1, cs.getNumberOfRegions());
+    assertEquals("[10, 60]", Arrays.toString(regions.next()));
 
     /*
      * another...left overlap, subsumption, right overlap,
@@ -716,10 +767,10 @@ public class HiddenColumnsTest
     cs.hideColumns(60, 70);
 
     cs.hideColumns(15, 45);
-    hidden = cs.getHiddenColumnsCopy();
-    assertEquals(2, hidden.size());
-    assertEquals("[10, 50]", Arrays.toString(hidden.get(0)));
-    assertEquals("[60, 70]", Arrays.toString(hidden.get(1)));
+    regions = cs.iterator();
+    assertEquals(2, cs.getNumberOfRegions());
+    assertEquals("[10, 50]", Arrays.toString(regions.next()));
+    assertEquals("[60, 70]", Arrays.toString(regions.next()));
   }
 
   @Test(groups = { "Functional" })
@@ -733,23 +784,23 @@ public class HiddenColumnsTest
     one.set(1);
     cs = new HiddenColumns();
     cs.hideMarkedBits(one);
-    assertEquals(1, cs.getHiddenColumnsCopy().size());
+    assertEquals(1, cs.getNumberOfRegions());
 
     one.set(2);
     cs = new HiddenColumns();
     cs.hideMarkedBits(one);
-    assertEquals(1, cs.getHiddenColumnsCopy().size());
+    assertEquals(1, cs.getNumberOfRegions());
 
     one.set(3);
     cs = new HiddenColumns();
     cs.hideMarkedBits(one);
-    assertEquals(1, cs.getHiddenColumnsCopy().size());
+    assertEquals(1, cs.getNumberOfRegions());
 
     // split
     one.clear(2);
     cs = new HiddenColumns();
     cs.hideMarkedBits(one);
-    assertEquals(2, cs.getHiddenColumnsCopy().size());
+    assertEquals(2, cs.getNumberOfRegions());
 
     assertEquals(0, cs.adjustForHiddenColumns(0));
     assertEquals(2, cs.adjustForHiddenColumns(1));
@@ -760,7 +811,7 @@ public class HiddenColumnsTest
     cs = new HiddenColumns();
     cs.hideMarkedBits(one);
 
-    assertEquals(1, cs.getHiddenColumnsCopy().size());
+    assertEquals(1, cs.getNumberOfRegions());
 
     assertEquals(0, cs.adjustForHiddenColumns(0));
     assertEquals(1, cs.adjustForHiddenColumns(1));
@@ -791,25 +842,6 @@ public class HiddenColumnsTest
   }
 
   @Test(groups = { "Functional" })
-  public void testFindHiddenRegionPositions()
-  {
-    HiddenColumns hc = new HiddenColumns();
-
-    List<Integer> positions = hc.findHiddenRegionPositions();
-    assertTrue(positions.isEmpty());
-
-    hc.hideColumns(3, 7);
-    hc.hideColumns(10, 10);
-    hc.hideColumns(14, 15);
-
-    positions = hc.findHiddenRegionPositions();
-    assertEquals(3, positions.size());
-    assertEquals(3, positions.get(0).intValue());
-    assertEquals(5, positions.get(1).intValue());
-    assertEquals(8, positions.get(2).intValue());
-  }
-
-  @Test(groups = { "Functional" })
   public void testRegionsToString()
   {
     HiddenColumns hc = new HiddenColumns();
@@ -916,19 +948,22 @@ public class HiddenColumnsTest
             false);
 
     // confirm that original contigs are as expected
-    int[] oldcontigs = hidden.getVisibleContigs(0, 25);
-    int[] testcontigs = { 0, 14, 18, 24 };
-    assertTrue(Arrays.equals(oldcontigs, testcontigs));
+    Iterator<int[]> visible = hidden.getVisContigsIterator(0, 25);
+    int[] region = visible.next();
+    assertEquals("[0, 14]", Arrays.toString(region));
+    region = visible.next();
+    assertEquals("[18, 24]", Arrays.toString(region));
 
     // propagate insertions
     HiddenColumns result = HiddenColumns.propagateInsertions(profileseq, al,
             view);
 
     // confirm that the contigs have changed to account for the gaps
-    int[] newcontigs = result.getVisibleContigs(0, 25);
-    testcontigs[1] = 10;
-    testcontigs[2] = 14;
-    assertTrue(Arrays.equals(newcontigs, testcontigs));
+    visible = result.getVisContigsIterator(0, 25);
+    region = visible.next();
+    assertEquals("[0, 10]", Arrays.toString(region));
+    region = visible.next();
+    assertEquals("[14, 24]", Arrays.toString(region));
 
     // confirm the alignment has been changed so that the other sequences have
     // gaps inserted where the columns are hidden
@@ -971,19 +1006,24 @@ public class HiddenColumnsTest
             false);
 
     // confirm that original contigs are as expected
-    int[] oldcontigs = hidden.getVisibleContigs(0, 20);
-    int[] testcontigs = { 0, 6, 11, 19 };
-    assertTrue(Arrays.equals(oldcontigs, testcontigs));
+    Iterator<int[]> visible = hidden.getVisContigsIterator(0, 20);
+    int[] region = visible.next();
+    assertEquals("[0, 6]", Arrays.toString(region));
+    region = visible.next();
+    assertEquals("[11, 19]", Arrays.toString(region));
+    assertFalse(visible.hasNext());
 
     // propagate insertions
     HiddenColumns result = HiddenColumns.propagateInsertions(profileseq, al,
             view);
 
     // confirm that the contigs have changed to account for the gaps
-    int[] newcontigs = result.getVisibleContigs(0, 20);
-    testcontigs[1] = 4;
-    testcontigs[2] = 7;
-    assertTrue(Arrays.equals(newcontigs, testcontigs));
+    visible = result.getVisContigsIterator(0, 20);
+    region = visible.next();
+    assertEquals("[0, 4]", Arrays.toString(region));
+    region = visible.next();
+    assertEquals("[7, 19]", Arrays.toString(region));
+    assertFalse(visible.hasNext());
 
     // confirm the alignment has been changed so that the other sequences have
     // gaps inserted where the columns are hidden
@@ -1055,85 +1095,6 @@ public class HiddenColumnsTest
     assertEquals(4, h.adjustForHiddenColumns(2));
   }
 
-  /*@Test(groups = "Functional")
-  public void testCompensateForEdit()
-  {
-    HiddenColumns2 h = new HiddenColumns2();
-  
-    ColumnSelection sel = new ColumnSelection();
-    assertNull(h.compensateForEdit(10, 3, sel));
-  
-    h.hideColumns(3, 4);
-    List<int[]> result = h.compensateForEdit(10, 3, sel);
-    assertEquals(0, result.size());
-  
-    // edit partially overlapping hidden
-  
-    h = new HiddenColumns2();
-    h.hideColumns(15, 17);
-    result = h.compensateForEdit(10, 6, sel);
-    assertEquals(0, result.size());
-  
-    HiddenColumns2 h2 = new HiddenColumns2();
-    h2.hideColumns(9, 11);
-    assertTrue(h.equals(h2));
-  
-    // edit fully overlapping hidden
-  
-    h = new HiddenColumns2();
-    h.hideColumns(15, 17);
-    result = h.compensateForEdit(10, 8, sel);
-    assertEquals(result.get(0)[0], 15);
-    assertEquals(result.get(0)[1], 17);
-    assertFalse(h.hasHiddenColumns());
-  
-    // edit at start
-  
-    h = new HiddenColumns2();
-    h.hideColumns(0, 3);
-    result = h.compensateForEdit(0, 4, sel);
-    assertEquals(0, result.size());
-    assertEquals(sel.getSelected().size(), 4);
-    assertFalse(h.hasHiddenColumns());
-  }*/
-
-  /*@Test(groups = "Functional")
-  public void testCompensateForDelEdits()
-  {
-    HiddenColumns2 h = new HiddenColumns2();
-    HiddenColumns2 h2 = new HiddenColumns2();
-  
-    h.compensateForDelEdits(10, 3);
-    assertFalse(h.hasHiddenColumns());
-  
-    h = new HiddenColumns2();
-    h.hideColumns(3, 4);
-    h.compensateForDelEdits(10, 3);
-    h2.hideColumns(3, 4);
-    assertTrue(h.equals(h2));
-  
-    h = new HiddenColumns2();
-    h.hideColumns(15, 17);
-    h.compensateForDelEdits(10, 6);
-    h2 = new HiddenColumns2();
-    h2.hideColumns(9, 11);
-    assertTrue(h.equals(h2));
-  
-    h = new HiddenColumns2();
-    h.hideColumns(15, 17);
-    h.compensateForDelEdits(10, 8);
-    h2 = new HiddenColumns2();
-    h2.hideColumns(7, 9);
-    assertTrue(h.equals(h2));
-  
-    h = new HiddenColumns2();
-    h.hideColumns(0, 3);
-    h.compensateForDelEdits(0, 4);
-    h2 = new HiddenColumns2();
-    h2.hideColumns(0, 0);
-    assertTrue(h.equals(h2));
-  }*/
-
   @Test(groups = "Functional")
   public void testGetHiddenBoundaryLeft()
   {
@@ -1171,34 +1132,38 @@ public class HiddenColumnsTest
   }
 
   @Test(groups = "Functional")
-  public void testGetHiddenColumnsCopy()
+  public void testIterator()
   {
     HiddenColumns h = new HiddenColumns();
-    ArrayList<int[]> result = h.getHiddenColumnsCopy();
-    assertTrue(result.isEmpty());
+    Iterator<int[]> result = h.iterator();
+    assertFalse(result.hasNext());
 
     h.hideColumns(5, 10);
-    result = h.getHiddenColumnsCopy();
-    assertEquals(1, result.size());
-    assertEquals(5, result.get(0)[0]);
-    assertEquals(10, result.get(0)[1]);
+    result = h.iterator();
+    int[] next = result.next();
+    assertEquals(5, next[0]);
+    assertEquals(10, next[1]);
+    assertFalse(result.hasNext());
 
     h.hideColumns(22, 23);
-    result = h.getHiddenColumnsCopy();
-    assertEquals(2, result.size());
-    assertEquals(5, result.get(0)[0]);
-    assertEquals(10, result.get(0)[1]);
-    assertEquals(22, result.get(1)[0]);
-    assertEquals(23, result.get(1)[1]);
+    result = h.iterator();
+    next = result.next();
+    assertEquals(5, next[0]);
+    assertEquals(10, next[1]);
+    next = result.next();
+    assertEquals(22, next[0]);
+    assertEquals(23, next[1]);
+    assertFalse(result.hasNext());
 
     // test for only one hidden region at start of alignment
     ColumnSelection sel = new ColumnSelection();
     h.revealAllHiddenColumns(sel);
     h.hideColumns(0, 1);
-    result = h.getHiddenColumnsCopy();
-    assertEquals(1, result.size());
-    assertEquals(0, result.get(0)[0]);
-    assertEquals(1, result.get(0)[1]);
+    result = h.iterator();
+    next = result.next();
+    assertEquals(0, next[0]);
+    assertEquals(1, next[1]);
+    assertFalse(result.hasNext());
   }
 
   @Test(groups = "Functional")
@@ -1346,12 +1311,109 @@ public class HiddenColumnsTest
     ColumnSelection sel = new ColumnSelection();
     h.revealAllHiddenColumns(sel);
     h.hideColumns(0, 30);
-    result = h.subtractVisibleColumns(31, 13);
-    assertEquals(-18, result);
-
     result = h.subtractVisibleColumns(31, 0);
     assertEquals(-31, result);
+  }
 
+  @Test(groups = "Functional")
+  public void testBoundedIterator()
+  {
+    HiddenColumns h = new HiddenColumns();
+    Iterator<int[]> it = h.getBoundedIterator(0, 10);
+
+    // no hidden columns = nothing to iterate over
+    assertFalse(it.hasNext());
+
+    // [start,end] contains all hidden columns
+    // all regions are returned
+    h.hideColumns(3, 10);
+    h.hideColumns(14, 16);
+    it = h.getBoundedIterator(0, 20);
+    assertTrue(it.hasNext());
+    int[] next = it.next();
+    assertEquals(3, next[0]);
+    assertEquals(10, next[1]);
+    next = it.next();
+    assertEquals(14, next[0]);
+    assertEquals(16, next[1]);
+    assertFalse(it.hasNext());
+
+    // [start,end] overlaps a region
+    // 1 region returned
+    it = h.getBoundedIterator(5, 7);
+    assertTrue(it.hasNext());
+    next = it.next();
+    assertEquals(3, next[0]);
+    assertEquals(10, next[1]);
+    assertFalse(it.hasNext());
+
+    // [start,end] fully contains 1 region and start of last
+    // - 2 regions returned
+    it = h.getBoundedIterator(3, 15);
+    assertTrue(it.hasNext());
+    next = it.next();
+    assertEquals(3, next[0]);
+    assertEquals(10, next[1]);
+    next = it.next();
+    assertEquals(14, next[0]);
+    assertEquals(16, next[1]);
+    assertFalse(it.hasNext());
+
+    // [start,end] contains end of first region and whole of last region
+    // - 2 regions returned
+    it = h.getBoundedIterator(4, 20);
+    assertTrue(it.hasNext());
+    next = it.next();
+    assertEquals(3, next[0]);
+    assertEquals(10, next[1]);
+    next = it.next();
+    assertEquals(14, next[0]);
+    assertEquals(16, next[1]);
+    assertFalse(it.hasNext());
   }
 
+  @Test(groups = "Functional")
+  public void testBoundedStartIterator()
+  {
+    HiddenColumns h = new HiddenColumns();
+    Iterator<Integer> it = h.getBoundedStartIterator(0, 10);
+
+    // no hidden columns = nothing to iterate over
+    assertFalse(it.hasNext());
+
+    // [start,end] contains all hidden columns
+    // all regions are returned
+    h.hideColumns(3, 10);
+    h.hideColumns(14, 16);
+    it = h.getBoundedStartIterator(0, 20);
+    assertTrue(it.hasNext());
+    int next = it.next();
+    assertEquals(3, next);
+    next = it.next();
+    assertEquals(6, next);
+    assertFalse(it.hasNext());
+
+    // [start,end] does not contain a start of a region
+    // no regions to iterate over
+    it = h.getBoundedStartIterator(4, 5);
+    assertFalse(it.hasNext());
+
+    // [start,end] fully contains 1 region and start of last
+    // - 2 regions returned
+    it = h.getBoundedStartIterator(3, 7);
+    assertTrue(it.hasNext());
+    next = it.next();
+    assertEquals(3, next);
+    next = it.next();
+    assertEquals(6, next);
+    assertFalse(it.hasNext());
+
+    // [start,end] contains whole of last region
+    // - 1 region returned
+    it = h.getBoundedStartIterator(4, 20);
+    assertTrue(it.hasNext());
+    next = it.next();
+    assertEquals(6, next);
+    assertFalse(it.hasNext());
+  }
 }