@Override
   public boolean forward(SliceByteArray input, SliceByteArray output)
   {
      if ((!SliceByteArray.isValid(input)) || (!SliceByteArray.isValid(output)))
         return false;

      if (input.array == output.array)
         return false;
      
      final int blockSize = input.length;

      if (output.length - output.index < getMaxEncodedLength(blockSize))
         return false;
      
      final int savedOIdx = output.index;
      int log = 1;

      while (1<<log <= blockSize)
         log++; 
               
      // Estimate header size based on block size
      final int headerSizeBytes1 = (1+log+7) >> 3;
      output.index += headerSizeBytes1;
      output.length -= headerSizeBytes1;
     
      // Apply forward transform
      if (this.bwt.forward(input, output) == false)
         return false;

      int primaryIndex = this.bwt.getPrimaryIndex();
      int pIndexSizeBits = 6;

      while ((1<<pIndexSizeBits) <= primaryIndex)
         pIndexSizeBits++;          

      // Compute block size based on primary index
      final int headerSizeBytes2 = (2+pIndexSizeBits+7) >>> 3;

      if (headerSizeBytes2 != headerSizeBytes1)
      {
         // Adjust space for header
         System.arraycopy(output.array, savedOIdx+headerSizeBytes1, 
            output.array, savedOIdx+headerSizeBytes2, blockSize);

         output.index = output.index - headerSizeBytes1 + headerSizeBytes2;
      }
      
      // Write block header (mode + primary index). See top of file for format 
      int shift = (headerSizeBytes2 - 1) << 3;
      int blockMode = (pIndexSizeBits + 1) >>> 3;
      blockMode = (blockMode << 6) | ((primaryIndex >>> shift) & 0x3F);
      output.array[savedOIdx] = (byte) blockMode;

      for (int i=1; i<headerSizeBytes2; i++)
      {
         shift -= 8;
         output.array[savedOIdx+i] = (byte) (primaryIndex >> shift);
      }
      
      return true;
   }