private boolean makeAvailable(int required) throws IOException {
    if (avail >= required)
      return true;
    if (buf == null)
      buf = new byte[required > INIT_BUF_SIZE ? required : INIT_BUF_SIZE];
    else if (required > buf.length - start) {
      if (buf.length >= required) {
	// move the available bytes
	for (int i = 0; i < avail; i++)
	  buf[i] = buf[i + start];
	start = 0;
      }
      else {
	// reallocate
	int newBufSize = buf.length * 2;
	newBufSize = required > newBufSize ? required : newBufSize;
	byte[] newBuf = new byte[newBufSize];
	System.arraycopy(buf, start, newBuf, 0, avail);
	buf = newBuf;
      }
    }
    do {
      int nRead = in.read(buf, start + avail, buf.length - start - avail);
      if (nRead == -1)
	return false;
      avail += nRead;
    } while (avail < required);
    return true;
  }