code: @Override
      public final int read() throws IOException
      {
          assert cursor <= end;
          if (cursor >= end)
          {
              if (includeLevel.in == null)
              {
                  return -1;
              }
              int cp = (int)(cursor % size);
              long len = size-(cursor-waterMark);
              int il;
              if (len > size - cp)
              {
                  buffer1.position(cp);
                  buffer1.limit(size);
                  buffer2.position(0);
                  buffer2.limit((int)(len-(size-cp)));
                  if (!buffer1.hasRemaining() && !buffer2.hasRemaining())
                  {
                      throw new UnderflowException("Buffer size="+size+" too small for operation");
                  }
                  il = fill(includeLevel.in, array2);
              }
              else
              {
                  buffer1.position(cp);
                  buffer1.limit((int)(cp+len));
                  if (!buffer1.hasRemaining())
                  {
                      throw new UnderflowException("Buffer size="+size+" too small for operation");
                  }
                  il = fill(includeLevel.in, array1);
              }
              if (il == -1)
              {
                  if (includeStack != null)
                  {
                      while (!includeStack.isEmpty() && il == -1)
                      {
                          close(includeLevel.in);
                          includeLevel = includeStack.pop();
                          return read();
                      }
                  }
                  return -1;
              }
              if (il == 0)
              {
                  throw new IOException("No input! Use blocking mode?");
              }
              buffer1.clear();
              buffer2.clear();
              end+=il;
              if (end < 0)
              {
                  throw new IOException("end = "+end);
              }
          }
          int rc = get(cursor++);
          if (cursor < 0)
          {
              throw new IOException("cursor = "+cursor);
          }
          includeLevel.forward(rc);
          length++;
          if (length > size)
          {
              throw new IOException("input size "+length+" exceeds buffer size "+size);
          }
          if (checksum != null)
          {
              checksum.update(cursor-1, rc);
          }
          return rc;
      }
docs: Reads from ring buffer or from actual reader.
  @return
  @throws IOException