def record(self, state, new_state, action, reward, success,
               input_utterance=None, output_utterance=None,
               task_success=None, force_terminate=False, role='system',
               custom=None):
        """
        Records experience. Currently designed from a Reinforcement Learning
        perspective.

        :param state: the state from which action was taken
        :param new_state: the resulting state after action was taken
        :param action: the action taken from state
        :param reward: the reward received after taking action from state
        :param success: flag for success (usually for final states)
        :param input_utterance: utterance received by the agent
        :param output_utterance: utterance generated by the agent
        :param task_success: flag for task success (may be different than
                              success)
        :param force_terminate: forcefully end current episode and create new
        :param role: the agent's role
        :param custom: anything else we may want to save and is not captured in
                       the above structures
        :return: Nothing
        """

        self.cumulative_reward += reward

        # Check if a dialogue is starting or ending
        if self.current_dialogue is None:
            self.current_dialogue = []

        self.current_dialogue.append({
            'state': deepcopy(state),
            'new_state': deepcopy(new_state),
            'action': deepcopy(action),
            'reward': deepcopy(reward),
            'input_utterance':
                deepcopy(input_utterance) if input_utterance else '',
            'output_utterance':
                deepcopy(output_utterance) if output_utterance else '',
            'success': '',
            'task_success': '',
            'cumulative_reward': deepcopy(self.cumulative_reward),
            'role': role,
            'custom': deepcopy(custom) if custom else ''})

        if state.is_terminal() or force_terminate:
            if success is not None:
                self.current_dialogue[-1]['success'] = success
            if task_success is not None:
                self.current_dialogue[-1]['task_success'] = task_success
            else:
                print('Warning! DialogueEpisodeRecorder terminal state '
                      'without success signal.')

            # Check if maximum size has been reached
            if self.size and len(self.dialogues) >= self.size:
                self.dialogues = \
                    self.dialogues[(len(self.dialogues)-self.size + 1):]

            self.dialogues.append(self.current_dialogue)
            self.current_dialogue = []
            self.cumulative_reward = 0

        Records experience. Currently designed from a Reinforcement Learning
        perspective.

        :param state: the state from which action was taken
        :param new_state: the resulting state after action was taken
        :param action: the action taken from state
        :param reward: the reward received after taking action from state
        :param success: flag for success (usually for final states)
        :param input_utterance: utterance received by the agent
        :param output_utterance: utterance generated by the agent
        :param task_success: flag for task success (may be different than
                              success)
        :param force_terminate: forcefully end current episode and create new
        :param role: the agent's role
        :param custom: anything else we may want to save and is not captured in
                       the above structures
        :return: Nothing
        
plato/utilities/dialogue_episode_recorder.py