}
  public int read(char[] buf, int offset, int count) throws IOException  {    // I declared channel being null meaning that the reader is closed.    if (!channel.isOpen())      throw new IOException("Reader was already closed.");    // I declared decoder being null meaning that there is no more data to read    // and convert.    if (decoder == null)      return -1;    // Stores the amount of character being read. It -1 so that if no conversion    // occured the caller will see this as an 'end of file'.    int sum = -1;    // Copies any characters which may be left from the last invocation into the    // destination array.    if (charBuffer.remaining() > 0)      {        sum = Math.min(count, charBuffer.remaining());        charBuffer.get(buf, offset, sum);        // Updates the control variables according to the latest copy operation.        offset += sum;        count -= sum;      }    // Copies the character which have not been put in the destination array to    // the beginning. If data is actually copied count will be 0. If no data is    // copied count is >0 and we can now convert some more characters.    charBuffer.compact();    int converted = 0;    boolean last = false;    while (count != 0)      {        // Tries to convert some bytes (Which will intentionally fail in the        // first place because we have not read any bytes yet.)        CoderResult result = decoder.decode(byteBuffer, charBuffer, last);        if (result.isMalformed() || result.isUnmappable())          {            // JDK throws exception when bytes are malformed for sure.            // FIXME: Unsure what happens when a character is simply            // unmappable.            result.throwException();          }        // Marks that we should end this loop regardless whether the caller        // wants more chars or not, when this was the last conversion.        if (last)          {            decoder = null;          }        else if (result.isUnderflow())          {            // We need more bytes to do the conversion.            // Copies the not yet converted bytes to the beginning making it            // being able to receive more bytes.            byteBuffer.compact();            // Reads in another bunch of bytes for being converted.            if (channel.read(byteBuffer) == -1)              {                // If there is no more data available in the channel we mark                // that state for the final character conversion run which is                // done in the next loop iteration.                last = true;              }            // Prepares the byteBuffer for the next character conversion run.            byteBuffer.flip();          }        // Prepares the charBuffer for being drained.        charBuffer.flip();        converted = Math.min(count, charBuffer.remaining());        charBuffer.get(buf, offset, converted);        // Copies characters which have not yet being copied into the char-Array        // to the beginning making it possible to read them later (If data is        // really copied here, then the caller has received enough characters so        // far.).        charBuffer.compact();        // Updates the control variables according to the latest copy operation.        offset += converted;        count -= converted;        // Updates the amount of transferred characters.        sum += converted;        if (decoder == null)          {            break;          }        // Now that more characters have been transfered we let the loop decide        // what to do next.      }    // Makes the charBuffer ready for reading on the next invocation.    charBuffer.flip();    return sum;  }