code: public static int expectHCOLONStreamFriendly(final Buffer buffer) throws SipParseException {
          try {
              int consumed = consumeWS(buffer);
              if (buffer.hasReadableBytes()) {
                  expect(buffer, COLON);
              } else {
                  // normally the expect(buffer, COLON) would have thrown
                  // an IndexOutOfBoundsException but let's signal that as
                  // -1
                  return -1;
              }
              ++consumed;
              consumed += consumeSWSAfterHColon(buffer);
              return consumed;
          } catch (final IOException e) {
              throw new SipParseException(buffer.getReaderIndex(), UNABLE_TO_READ_FROM_STREAM, e);
          }
      }
docs: A problem with stream based protocols is that you don't have everything
  available right away so e.g. when expecting HCOLON you may consume white spaces
  but then you run out of bytes because you haven't received them yet
  so therefore the expect(buffer, COLON) will blow up for the wrong reasons.
  It may very well be that the next byte on the wire is indeed a ':' and as
  such you should rather signal that you didn't have enough bytes to do your
  job. This one does that.
  
  Note, still some issues with this one though. Let's say the header
  we are trying to parse is "X-Hello :    whatever" and we have
  only received "X-Hello :" so far. So first off we consume "X-Hello"
  then call this method, which will consume " :" but ideally we also
  want to consume the white space after the colon. I.e., when we
  go off and consume the value of this header we will end up with
  white space which normally should have been consumed by this method.
  
  Hence, whenever dealing with streams you will run into this issue
  and will have to keep extra state around to solve it. See the
  {@link SipMessageStreamBuilder} for how it is dealing with this.
  
  @param buffer
  @return
  @throws SipParseException