def METHOD_NAME(self, f):
    """
    Updates the internal header buffer. Returns a frame that should replace
    the current one. May throw exceptions if this frame is invalid.
    """
    # Check if we're in the middle of a headers block. If we are, this
    # frame *must* be a CONTINUATION frame with the same stream ID as the
    # leading HEADERS or PUSH_PROMISE frame. Anything else is a
    # ProtocolError. If the frame *is* valid, append it to the header
    # buffer.
    if self._headers_buffer:
        stream_id = self._headers_buffer[0].stream_id
        valid_frame = (
            f is not None and
            isinstance(f, ContinuationFrame) and
            f.stream_id == stream_id
        )
        if not valid_frame:
            raise ProtocolError("Invalid frame during header block.")
        # Append the frame to the buffer.
        self._headers_buffer.append(f)
        if len(self._headers_buffer) > CONTINUATION_BACKLOG:
            raise ProtocolError("Too many continuation frames received.")
        # If this is the end of the header block, then we want to build a
        # mutant HEADERS frame that's massive. Use the original one we got,
        # then set END_HEADERS and set its data appopriately. If it's not
        # the end of the block, lose the current frame: we can't yield it.
        if 'END_HEADERS' in f.flags:
            f = self._headers_buffer[0]
            f.flags.add('END_HEADERS')
            f.data = b''.join(x.data for x in self._headers_buffer)
            self._headers_buffer = []
        else:
            f = None
    elif (isinstance(f, (HeadersFrame, PushPromiseFrame)) and
            'END_HEADERS' not in f.flags):
        # This is the start of a headers block! Save the frame off and then
        # act like we didn't receive one.
        self._headers_buffer.append(f)
        f = None
    return f