def build(self, message):
        """buffer all the streaming messages based on the
        message id. Reconstruct all fragments together.

        :param message:
            incoming message
        :return: next complete message or None if streaming
            is not done
        """
        context = None

        if message.message_type in [Types.CALL_REQ,
                                    Types.CALL_RES]:
            self.verify_message(message)

            context = self.build_context(message)
            # streaming message
            if message.flags == common.FlagsType.fragment:
                self.message_buffer[message.id] = context

            # find the incompleted stream
            num = 0
            for i, arg in enumerate(context.argstreams):
                if arg.state != StreamState.completed:
                    num = i
                    break

            self.close_argstream(context, num)
            return context

        elif message.message_type in [Types.CALL_REQ_CONTINUE,
                                      Types.CALL_RES_CONTINUE]:
            context = self.message_buffer.get(message.id)
            if context is None:
                # missing call msg before continue msg
                raise FatalProtocolError(
                    "missing call message after receiving continue message",
                    message.id,
                )

            # find the incompleted stream
            dst = 0
            for i, arg in enumerate(context.argstreams):
                if arg.state != StreamState.completed:
                    dst = i
                    break

            try:
                self.verify_message(message)
            except InvalidChecksumError as e:
                context.argstreams[dst].set_exception(e)
                raise

            src = 0
            while src < len(message.args):
                context.argstreams[dst].write(message.args[src])
                dst += 1
                src += 1

            if message.flags != FlagsType.fragment:
                # get last fragment. mark it as completed
                assert (len(context.argstreams) ==
                        CallContinueMessage.max_args_num)
                self.message_buffer.pop(message.id, None)
                context.flags = FlagsType.none

            self.close_argstream(context, dst - 1)
            return None
        elif message.message_type == Types.ERROR:
            context = self.message_buffer.pop(message.id, None)
            if context is None:
                log.info('Unconsumed error %s', message)
                return None
            else:
                error = TChannelError.from_code(
                    message.code,
                    description=message.description,
                    tracing=context.tracing,
                )

                context.set_exception(error)
                return error
        else:
            return message
buffer all the streaming messages based on the
        message id. Reconstruct all fragments together.

        :param message:
            incoming message
        :return: next complete message or None if streaming
            is not done