Gets the tool object from the tool channel(s), and instantiates it using the tool parameters

        :param name: The name or stream id for the tool in the tool channel
        :param parameters: The parameters for the tool
        :param version: The string representation of the version
        :return: The instantiated tool object

def get_tool(self, name, parameters, version=None):
        """
        Gets the tool object from the tool channel(s), and instantiates it using the tool parameters

        :param name: The name or stream id for the tool in the tool channel
        :param parameters: The parameters for the tool
        :param version: The string representation of the version
        :return: The instantiated tool object
        """
        # TODO: use the version
        if version is not None:
            logging.warn("Tool versions not yet supported")

        tool_class = self.get_tool_class(name)

        # Check that the number of arguments is correct for this tool
        arg_spec = inspect.getargspec(tool_class.__init__)
        max_expected = len(arg_spec[0])
        if arg_spec.defaults:
            min_expected = max_expected - len(arg_spec.defaults)
        else:
            min_expected = max_expected
        num_parameters = len(parameters) if parameters is not None else 0
        if not (min_expected <= num_parameters + 1 <= max_expected):
            message = "Tool {} takes between {} and {} arguments ({} given)".format(
                tool_class.__name__, min_expected, max_expected, num_parameters + 1)
            raise ToolInitialisationError(message)

        # Instantiate tool
        try:
            tool = tool_class(**parameters) if parameters is not None else tool_class()
        except TypeError:
            raise ToolInitialisationError(name, parameters)

        if not tool:
            raise ToolNotFoundError(name, parameters)

        tool.name = name

        return tool