private int encryptBlock(
        byte[] in,
        int inOff,
        byte[] out,
        int outOff)
        throws DataLengthException, IllegalStateException
    {
        if ((inOff + blockSize) > in.length)
        {
            throw new DataLengthException("input buffer too short");
        }

        if ((outOff + blockSize) > out.length)
        {
            throw new DataLengthException("output buffer too short");
        }
        
        if (count > blockSize)
        {
            FR[blockSize - 2] = out[outOff] = encryptByte(in[inOff], blockSize - 2);
            FR[blockSize - 1] = out[outOff + 1] = encryptByte(in[inOff + 1], blockSize - 1);

            cipher.processBlock(FR, 0, FRE, 0);

            for (int n = 2; n < blockSize; n++) 
            {
                FR[n - 2] = out[outOff + n] = encryptByte(in[inOff + n], n - 2);
            }
        }
        else if (count == 0)
        {
            cipher.processBlock(FR, 0, FRE, 0);

            for (int n = 0; n < blockSize; n++) 
            {
                FR[n] = out[outOff + n] = encryptByte(in[inOff + n], n);
            }
            
            count += blockSize;
        }
        else if (count == blockSize)
        {
            cipher.processBlock(FR, 0, FRE, 0);

            out[outOff] = encryptByte(in[inOff], 0);
            out[outOff + 1] = encryptByte(in[inOff + 1], 1);

            //
            // do reset
            //
            System.arraycopy(FR, 2, FR, 0, blockSize - 2);
            System.arraycopy(out, outOff, FR, blockSize - 2, 2);

            cipher.processBlock(FR, 0, FRE, 0);

            for (int n = 2; n < blockSize; n++) 
            {
                FR[n - 2] = out[outOff + n] = encryptByte(in[inOff + n], n - 2);
            }

            count += blockSize;
        }
        
        return blockSize;
    }