@Test
  public void testEncodeDecodeSequence() throws Exception {
    final ASN1Writer writer = getWriter();

    writer.writeStartSequence();

    writer.writeBoolean(true);
    writer.writeBoolean(false);
    writer.writeInteger(0);
    writer.writeInteger(10L);
    writer.writeNull();
    writer.writeOctetString("test value");
    writer.writeOctetString("skip value");

    writer.writeStartSequence();
    writer.writeOctetString("nested sequence");
    writer.writeEndSequence();

    writer.writeStartSet();
    writer.writeOctetString("nested set");
    writer.writeEndSet();

    writer.writeEndSequence();

    final ASN1Reader reader = getReader(getEncodedBytes());
    assertEquals(reader.peekType(), ASN1.UNIVERSAL_SEQUENCE_TYPE);
    assertEquals(reader.peekLength(), 71);

    assertTrue(reader.hasNextElement());
    reader.readStartSequence();
    assertTrue(reader.hasNextElement());

    assertEquals(true, reader.readBoolean());
    assertEquals(false, reader.readBoolean());
    assertEquals(0, reader.readInteger());
    assertEquals(10, reader.readInteger());
    reader.readNull();
    assertEquals("test value", reader.readOctetStringAsString());
    reader.skipElement();

    assertEquals(reader.peekLength(), 17);
    assertEquals(reader.peekType(), ASN1.UNIVERSAL_SEQUENCE_TYPE);
    reader.readStartSequence();
    assertEquals("nested sequence", reader.readOctetStringAsString());
    reader.readEndSequence();

    assertEquals(reader.peekLength(), 12);
    assertEquals(reader.peekType(), ASN1.UNIVERSAL_SET_TYPE);
    reader.readStartSequence();
    assertEquals("nested set", reader.readOctetStringAsString());
    reader.readEndSequence();

    assertFalse(reader.hasNextElement());
    reader.readEndSequence();
    assertFalse(reader.elementAvailable());
  }
  /**
   * Reads an LDAP message from the associated input stream.
   *
   * @return The LDAP message read from the associated input stream, or <CODE>null</CODE> if the end
   *     of the stream has been reached.
   * @throws IOException If a problem occurs while attempting to read from the input stream.
   * @throws ASN1Exception If a problem occurs while attempting to decode the data read as an ASN.1
   *     sequence.
   * @throws LDAPException If a problem occurs while attempting to decode the LDAP message.
   */
  public LDAPMessage readMessage() throws IOException, ASN1Exception, LDAPException {
    debugInputStream.setRecordingEnabled(debugEnabled());

    if (!asn1Reader.hasNextElement()) {
      // EOF was reached...
      return null;
    }

    LDAPMessage message = org.opends.server.protocols.ldap.LDAPReader.readMessage(asn1Reader);

    if (debugInputStream.isRecordingEnabled()) {
      ByteString bytesRead = debugInputStream.getRecordedBytes();
      debugInputStream.clearRecordedBytes();

      StringBuilder builder = new StringBuilder();
      builder.append("bytes read from wire(len=");
      builder.append(bytesRead.length());
      builder.append("):");
      builder.append(ServerConstants.EOL);
      bytesRead.toHexPlusAscii(builder, 4);

      TRACER.debugProtocolElement(DebugLogLevel.VERBOSE, builder.toString());
      TRACER.debugProtocolElement(DebugLogLevel.VERBOSE, message.toString());
    }

    return message;
  }