gt:     runTest(new CollectorContext() {
context: /*
   *  This file is part of the Jikes RVM project (http://jikesrvm.org).
   *
   *  This file is licensed to You under the Eclipse Public License (EPL);
   *  You may not use this file except in compliance with the License. You
   *  may obtain a copy of the License at
   *
   *      http://www.opensource.org/licenses/eclipse-1.0.php
   *
   *  See the COPYRIGHT.txt file distributed with this work for information
   *  regarding copyright ownership.
   */
  package org.mmtk.utility.deque;
  
  import org.junit.BeforeClass;
  import org.junit.Test;
  import org.junit.Assert;
  import org.mmtk.harness.Harness;
  import org.mmtk.harness.lang.Env;
  import org.mmtk.harness.scheduler.Schedulable;
  import org.mmtk.harness.scheduler.Scheduler;
  import org.mmtk.plan.CollectorContext;
  import org.mmtk.plan.Plan;
  import org.vmmagic.unboxed.Address;
  import org.vmmagic.unboxed.ObjectReference;
  
  /**
   * Junit unit-tests for ObjectReferenceDeque.
   */
  public class ObjectReferenceDequeTest {
  
    @BeforeClass
    public static void setUpBeforeClass() throws Exception {
      /*
       * Setting options here can be handy for running in Eclipse.  Otherwise
       * allow the harness to pick up the defaults so we can set them using
       * properties from ant.
       */
      Harness.init("collectors=0"
  //        ,"scheduler=JAVA"
  //        ,"scheduler=DETERMINISTIC"
  
  //        ,"schedulerPolicy=FIXED"
  //        ,"yieldInterval=1"
  
  //        ,"schedulerPolicy=RANDOM"
  //        ,"randomPolicyLength=20"
  //        ,"randomPolicyMin=1"
  //        ,"randomPolicyMax=2"
  //        ,"randomPolicySeed=1"
  //        ,"policyStats=true"
          );
  
      /* The deques rely on being run during GC. */
      Plan.setGCStatus(Plan.GC_PROPER);
    }
  
    /**
     * Helper method to create object references
     * @param val
     * @return
     */
    private static ObjectReference o(int val) {
      return Address.fromIntSignExtend(val).toObjectReference();
    }
  
    /**
     * Run a test, ie a list of threads, all run in GC context.
     * @param items
     */
    private void runTest(final CollectorContext... items) {
      for (CollectorContext item : items) {
        Scheduler.scheduleCollector(item);
      }
      Scheduler.scheduleGcThreads();
    }
  
    @Test
    public void testPushPop() {
      runTest(new CollectorContext() {
        @Override
        public void run() {
          SharedDeque shared = new SharedDeque("shared",Plan.metaDataSpace,1);
          ObjectReferenceDeque deque = new ObjectReferenceDeque("deque",shared);
  
          shared.prepareNonBlocking();
          deque.push(o(1));
          Assert.assertEquals(deque.pop(),o(1));
          Assert.assertTrue(deque.isEmpty());
        }
      });
    }
  
    @Test
    public void testInsertPop() {
      runTest(new CollectorContext() {
        @Override
        public void run() {
          SharedDeque shared = new SharedDeque("shared",Plan.metaDataSpace,1);
          ObjectReferenceDeque deque = new ObjectReferenceDeque("deque",shared);
  
          shared.prepareNonBlocking();
          deque.insert(o(1));
          Assert.assertEquals(deque.pop(),o(1));
          Assert.assertTrue(deque.isEmpty());
        }
      });
    }
  
    @Test
    public void testPushPop2() {
      runTest(new CollectorContext() {
        @Override
        public void run() {
          SharedDeque shared = new SharedDeque("shared",Plan.metaDataSpace,1);
          ObjectReferenceDeque deque = new ObjectReferenceDeque("deque",shared);
  
          shared.prepareNonBlocking();
          deque.push(o(1));
          deque.push(o(2));
          Assert.assertEquals(deque.pop(),o(2));
          Assert.assertEquals(deque.pop(),o(1));
          Assert.assertTrue(deque.isEmpty());
        }
      });
    }
  
    @Test
    public void testInsertPop2() {
      runTest(new CollectorContext() {
        @Override
        public void run() {
          SharedDeque shared = new SharedDeque("shared",Plan.metaDataSpace,1);
          ObjectReferenceDeque deque = new ObjectReferenceDeque("deque",shared);
  
          shared.prepareNonBlocking();
          deque.insert(o(1));
          deque.insert(o(2));
          Assert.assertEquals(deque.pop(),o(1));
          Assert.assertEquals(deque.pop(),o(2));
          Assert.assertTrue(deque.isEmpty());
        }
      });
    }
  
    @Test
    public void testPushFlushPop() {
      runTest(new CollectorContext() {
        @Override
        public void run() {
          SharedDeque shared = new SharedDeque("shared",Plan.metaDataSpace,1);
          ObjectReferenceDeque deque = new ObjectReferenceDeque("deque",shared);
  
          shared.prepareNonBlocking();
          deque.push(o(1));
          deque.flushLocal();
          Assert.assertEquals(deque.pop(),o(1));
          Assert.assertTrue(deque.isEmpty());
        }
      });
    }
  
    @Test
    public void testPushFlushPop2() {
      runTest(new CollectorContext() {
        @Override
        public void run() {
          SharedDeque shared = new SharedDeque("shared",Plan.metaDataSpace,1);
          ObjectReferenceDeque deque = new ObjectReferenceDeque("deque",shared);
  
          shared.prepareNonBlocking();
          deque.push(o(1));
          deque.push(o(2));
          deque.flushLocal();
          Assert.assertEquals(deque.pop(),o(2));
          Assert.assertEquals(deque.pop(),o(1));
          Assert.assertTrue(deque.isEmpty());
        }
      });
    }
  
    @Test
    public void test2Heads() {
      runTest(new CollectorContext() {
        @Override
        public void run() {
          SharedDeque shared = new SharedDeque("shared",Plan.metaDataSpace,1);
          ObjectReferenceDeque deque1 = new ObjectReferenceDeque("deque1",shared);
          ObjectReferenceDeque deque2 = new ObjectReferenceDeque("deque2",shared);
  
          shared.prepareNonBlocking();
          deque1.push(o(101));
          deque1.push(o(102));
          deque2.push(o(201));
          deque2.push(o(202));
          deque1.flushLocal();
          deque2.flushLocal();
          Assert.assertEquals(deque1.pop(),o(202));
          Assert.assertEquals(deque1.pop(),o(201));
          Assert.assertEquals(deque1.pop(),o(102));
          Assert.assertEquals(deque1.pop(),o(101));
          Assert.assertTrue(deque1.isEmpty());
          Assert.assertTrue(deque2.isEmpty());
        }
      });
    }
  
    @Test
    public void testnHeads() {
      final int NDEQUES = 4;
      final int ENTRIES = 1500; // Page and a half
  