public int write(byte[] abData, int nOffset, int nLength) {
        LOG.log(Level.FINE, ">TCircularBuffer.write(): called; nLength: {0}", nLength);
        dumpInternalState();
        synchronized (this) {
            LOG.log(Level.FINE, "entered synchronized block.");
            if (!m_bBlockingWrite) {
                nLength = Math.min(availableWrite(), nLength);
            }
            int nRemainingBytes = nLength;
            while (nRemainingBytes > 0) {
                while (availableWrite() == 0) {
                    try {
                        wait();
                    } catch (InterruptedException e) {
                        LOG.log(Level.FINE, e.getMessage());
                    }
                }
                int nAvailable = Math.min(availableWrite(), nRemainingBytes);
                while (nAvailable > 0) {
                    int nToWrite = Math.min(nAvailable, m_nSize - getWritePos());
                    //TDebug.out("src buf size= " + abData.length + ", offset = " + nOffset + ", dst buf size=" + m_abData.length + " write pos=" + getWritePos() + " len=" + nToWrite);
                    System.arraycopy(abData, nOffset, m_abData, getWritePos(), nToWrite);
                    m_lWritePos += nToWrite;
                    nOffset += nToWrite;
                    nAvailable -= nToWrite;
                    nRemainingBytes -= nToWrite;
                }
                notifyAll();
            }
            LOG.log(Level.FINE, "After write:");
            dumpInternalState();
            LOG.log(Level.FINE, "< completed. Wrote {0} bytes", nLength);
            return nLength;
        }
    }