/**
   * Create a new pipelined parser from an existing one.
   *
   * @return A new pipelined parser that reads from the same input stream.
   */
  protected Object clone() {
    PipelinedMsgParser p = new PipelinedMsgParser();

    p.rawInputStream = this.rawInputStream;
    p.sipMessageListener = this.sipMessageListener;
    Thread mythread = new Thread(p);
    mythread.setName("PipelineThread");
    return p;
  }
  /**
   * This gets invoked when thread.start is called from the constructor. Implements a message loop -
   * reading the tcp connection and processing messages until we are done or the other end has
   * closed.
   */
  public void run() {
    String message;
    Pipeline hispipe = null;
    // Create a pipeline to connect to our message parser.
    hispipe =
        new Pipeline(myClientInputStream, stack.readTimeout, ((SIPTransactionStack) stack).timer);
    // Create a pipelined message parser to read and parse
    // messages that we write out to him.
    myParser = new PipelinedMsgParser(this, hispipe, this.stack.getMaxMessageSize());
    // Start running the parser thread.
    myParser.processInput();
    // bug fix by Emmanuel Proulx
    int bufferSize = 4096;
    this.tlsMessageProcessor.useCount++;
    this.isRunning = true;
    try {
      while (true) {
        try {
          byte[] msg = new byte[bufferSize];
          int nbytes = myClientInputStream.read(msg, 0, bufferSize);
          // no more bytes to read...
          if (nbytes == -1) {
            hispipe.write("\r\n\r\n".getBytes("UTF-8"));
            try {
              if (stack.maxConnections != -1) {
                synchronized (tlsMessageProcessor) {
                  tlsMessageProcessor.nConnections--;
                  tlsMessageProcessor.notify();
                }
              }
              hispipe.close();
              mySock.close();
            } catch (IOException ioex) {
            }
            return;
          }
          hispipe.write(msg, 0, nbytes);

        } catch (IOException ex) {
          // Terminate the message.
          try {
            hispipe.write("\r\n\r\n".getBytes("UTF-8"));
          } catch (Exception e) {
            // InternalErrorHandler.handleException(e);
          }

          try {
            if (LogWriter.needsLogging)
              stack.logWriter.logMessage("IOException  closing sock " + ex);
            try {
              if (stack.maxConnections != -1) {
                synchronized (tlsMessageProcessor) {
                  tlsMessageProcessor.nConnections--;
                  tlsMessageProcessor.notify();
                }
              }
              mySock.close();
              hispipe.close();
            } catch (IOException ioex) {
            }
          } catch (Exception ex1) {
            // Do nothing.
          }
          return;
        } catch (Exception ex) {
          InternalErrorHandler.handleException(ex);
        }
      }
    } finally {
      this.isRunning = false;
      this.tlsMessageProcessor.remove(this);
      this.tlsMessageProcessor.useCount--;
    }
  }