class RangeBasedReaderWriterLock {

  public void acquireWriterLock(long start, long end, BufferPositionParser parser)
         throws InterruptedException, TimeoutException
  {
    long startOffset = parser.address(start);
    long endOffset = parser.address(end);

    boolean debug = LOG.isDebugEnabled();

    if (debug)
      LOG.debug("Acquiring writer lock from " + parser.toString(start) + " to " + parser.toString(end));

    mutex.lock();

    try
    {
        boolean timeout = false;
        while (!readerRanges.isEmpty() &&
                Range.contains(startOffset, endOffset, parser.address(readerRanges.peek()._id.start)))
        {
          if ( debug )
          {
        	  LOG.debug("Entering wait because reader(s) exist: Writer Range: ["
        			  + parser.toString(start) + "(Address:" +  parser.toString(startOffset) + ")-"
        			  + parser.toString(end) + "(Address:" + parser.toString(endOffset) +
        			  ")]. Nearest Reader Range :" + readerRanges.peek().toString(parser));
          }
          if (timeout)
          {
            LOG.error("timed out waiting for a write lock for [" + parser.toString(start) +
                      "," + parser.toString(end) + "); this: " + this );
            throw new TimeoutException();
          }

          for (LockToken token: readerRanges)
          {
            LOG.info(token.toString(parser));
          }
          writerWaiting = true;
          if (!writesPossible.await(MAX_LOCK_WAIT_MS, TimeUnit.MILLISECONDS))
            timeout = true;

          if ( debug )
            LOG.debug("Writer coming out of wait");
        }
      writerWaiting = false;
      writerIn = true;
      writerRange.start = start;
      writerRange.end = end;
    }
    finally
    {
      mutex.unlock();
    }

  }

  public  RangeBasedReaderWriterLock();

}