Merges results to form arguments to run(). There are two cases for each result:
         - dictionary: dictionaries get merged and passed as keyword arguments
         - list: lists get concatenated to positional arguments
         - Arguments: kwargs gets merged and args gets appended
         - else: concatenated and passed as postitional arguments
        Args:
            inputs: the inputs whose results to merge
            arguments: an optional existing Arguments object to merge into

def merge_results(inputs, arguments=None):
        """
        Merges results to form arguments to run(). There are two cases for each result:
         - dictionary: dictionaries get merged and passed as keyword arguments
         - list: lists get concatenated to positional arguments
         - Arguments: kwargs gets merged and args gets appended
         - else: concatenated and passed as postitional arguments
        Args:
            inputs: the inputs whose results to merge
            arguments: an optional existing Arguments object to merge into
        """
        if arguments is None:
            arguments = Arguments()

        args = arguments.args
        kwargs = arguments.kwargs

        for i in inputs:
            # without a mapping we handle two cases
            # when the result is a dict merge it with a global dict
            if isinstance(i.result, dict):
                # but do not override
                kwargs.update({k: v for k, v in i.result.items() if k not in kwargs})
            elif isinstance(i.result, list):
                args.extend(i.result)
            elif isinstance(i.result, Arguments):
                args.extend(i.result.args)
                kwargs.update({k: v for k, v in i.result.kwargs.items() if k not in kwargs})
            # otherwise use it as a positional argument
            else:
                args.append(i.result)

        return arguments