# Path: ronin/utils/strings.py
# def stringify(value):
#     """
#     Casts the value to a Unicode string. If the value is a function, calls it using
#     :func:`ronin.contexts.current_context` as its only argument, and recurses until a
#     non-FunctionType value is returned.
#     
#     None values are preserved, whether None is directly sent to this function or is the return
#     value of function argument.
#     
#     This function is the heart of Rōnin's deferred value capability, as it allows lambdas to be
#     passed around instead of strings.
#     
#     :param value: value or None
#     :type value: str|FunctionType
#     :returns: stringified value or None
#     :rtype: str
#     """
#     
#     if value is None:
#         return None
#     elif hasattr(value, '__call__'):
#         with current_context() as ctx:
#             value = value(ctx)
#         return stringify(value)
#     else:
#         try:
#             return to_str(value)
#         except UnicodeDecodeError:
#             return str(value).decode(_ENCODING)
# 
# def join_later(values, separator=' '):
#     """
#     Creates a lambda that calls :func:`stringify_list` and joins the results on ``separator``.
#     
#     :param values: values
#     :type values: []
#     :param separator: separator
#     :type separator: str|FunctionType
#     :returns: lambda returning the joined string
#     :rtype: FunctionType
#     """
#     
#     return lambda _: stringify(separator).join(stringify_list(values))
# 
# Path: ronin/utils/collections.py
# class StrictList(list):
#     """
#     A list that raises :class:`~exceptions.TypeError` exceptions when objects of the wrong type are
#     inserted.
#     
#     :param items: initial list
#     :type items: list
#     :param value_type: type(s) required for list values
#     :type value_type: :obj:`type` or :obj:`str` or (:obj:`type` or :obj:`str`)
#     :param wrapper_function: calls this optional function on all values before added to the list
#     :type wrapper_function: ~types.FunctionType
#     :param unwrapper_function: calls this optional function on all values when retrieved from the
#      list
#     :type unwrapper_function: ~types.FunctionType
#     """
# 
#     def __init__(self, items=None, value_type=None, wrapper_function=None, unwrapper_function=None):
#         super(StrictList, self).__init__()
#         if isinstance(items, StrictList):
#             self.value_type = items.value_type
#             self.wrapper_function = items.wrapper_function
#             self.unwrapper_function = items.unwrapper_function
#         self.value_type = _convert_type(value_type)
#         self.wrapper_function = wrapper_function
#         self.unwrapper_function = unwrapper_function
#         if items:
#             for item in items:
#                 self.append(item)
# 
#     def _wrap(self, value):
#         if (self.value_type is not None) and (not isinstance(value, self.value_type)):
#             raise TypeError('value must be a "{}": {!r}'.format(type_name(self.value_type), value))
#         if self.wrapper_function is not None:
#             value = self.wrapper_function(value)
#         return value
# 
#     def _unwrap(self, value):
#         if self.unwrapper_function is not None:
#             value = self.unwrapper_function(value)
#         return value
# 
#     def __getitem__(self, index):
#         value = super(StrictList, self).__getitem__(index)
#         value = self._unwrap(value)
#         return value
# 
#     def __setitem__(self, index, value):
#         value = self._wrap(value)
#         return super(StrictList, self).__setitem__(index, value)
# 
#     def __iadd__(self, values):
#         values = [self._wrap(v) for v in values]
#         return super(StrictList, self).__iadd__(values)
# 
#     def append(self, value):
#         value = self._wrap(value)
#         return super(StrictList, self).append(value)
# 
#     def extend(self, values):
#         values = [self._wrap(v) for v in values]
#         return super(StrictList, self).extend(values)
# 
#     def insert(self, index, value):
#         value = self._wrap(value)
#         return super(StrictList, self).insert(index, value)


from .utils.strings import stringify, join_later
from .utils.collections import StrictList
from io import StringIO
        for hook in self.hooks:
            hook(self)
        f.write(stringify(self.command))
    
    def command_as_str(self, argument_filter=None):
        f = StringIO()
        try:
            self.write_command(f, argument_filter)
            v = f.getvalue()
        finally:
            f.close()
        return v

    def add_input(self, value):
        pass


class ExecutorWithArguments(Executor):
    """
    Base class for executors with arguments.
    """

    def __init__(self):
        super(ExecutorWithArguments, self).__init__()
        self._arguments = []

    def write_command(self, f, argument_filter=None):
        super(ExecutorWithArguments, self).write_command(f, argument_filter)
        arguments = []
        for append, to_filter, argument in self._arguments:

# Path: ronin/utils/strings.py
# def stringify(value):
#     """
#     Casts the value to a Unicode string. If the value is a function, calls it using
#     :func:`ronin.contexts.current_context` as its only argument, and recurses until a
#     non-FunctionType value is returned.
#     
#     None values are preserved, whether None is directly sent to this function or is the return
#     value of function argument.
#     
#     This function is the heart of Rōnin's deferred value capability, as it allows lambdas to be
#     passed around instead of strings.
#     
#     :param value: value or None
#     :type value: str|FunctionType
#     :returns: stringified value or None
#     :rtype: str
#     """
#     
#     if value is None:
#         return None
#     elif hasattr(value, '__call__'):
#         with current_context() as ctx:
#             value = value(ctx)
#         return stringify(value)
#     else:
#         try:
#             return to_str(value)
#         except UnicodeDecodeError:
#             return str(value).decode(_ENCODING)
# 
# def join_later(values, separator=' '):
#     """
#     Creates a lambda that calls :func:`stringify_list` and joins the results on ``separator``.
#     
#     :param values: values
#     :type values: []
#     :param separator: separator
#     :type separator: str|FunctionType
#     :returns: lambda returning the joined string
#     :rtype: FunctionType
#     """
#     
#     return lambda _: stringify(separator).join(stringify_list(values))
# 
# Path: ronin/utils/collections.py
# class StrictList(list):
#     """
#     A list that raises :class:`~exceptions.TypeError` exceptions when objects of the wrong type are
#     inserted.
#     
#     :param items: initial list
#     :type items: list
#     :param value_type: type(s) required for list values
#     :type value_type: :obj:`type` or :obj:`str` or (:obj:`type` or :obj:`str`)
#     :param wrapper_function: calls this optional function on all values before added to the list
#     :type wrapper_function: ~types.FunctionType
#     :param unwrapper_function: calls this optional function on all values when retrieved from the
#      list
#     :type unwrapper_function: ~types.FunctionType
#     """
# 
#     def __init__(self, items=None, value_type=None, wrapper_function=None, unwrapper_function=None):
#         super(StrictList, self).__init__()
#         if isinstance(items, StrictList):
#             self.value_type = items.value_type
#             self.wrapper_function = items.wrapper_function
#             self.unwrapper_function = items.unwrapper_function
#         self.value_type = _convert_type(value_type)
#         self.wrapper_function = wrapper_function
#         self.unwrapper_function = unwrapper_function
#         if items:
#             for item in items:
#                 self.append(item)
# 
#     def _wrap(self, value):
#         if (self.value_type is not None) and (not isinstance(value, self.value_type)):
#             raise TypeError('value must be a "{}": {!r}'.format(type_name(self.value_type), value))
#         if self.wrapper_function is not None:
#             value = self.wrapper_function(value)
#         return value
# 
#     def _unwrap(self, value):
#         if self.unwrapper_function is not None:
#             value = self.unwrapper_function(value)
#         return value
# 
#     def __getitem__(self, index):
#         value = super(StrictList, self).__getitem__(index)
#         value = self._unwrap(value)
#         return value
# 
#     def __setitem__(self, index, value):
#         value = self._wrap(value)
#         return super(StrictList, self).__setitem__(index, value)
# 
#     def __iadd__(self, values):
#         values = [self._wrap(v) for v in values]
#         return super(StrictList, self).__iadd__(values)
# 
#     def append(self, value):
#         value = self._wrap(value)
#         return super(StrictList, self).append(value)
# 
#     def extend(self, values):
#         values = [self._wrap(v) for v in values]
#         return super(StrictList, self).extend(values)
# 
#     def insert(self, index, value):
#         value = self._wrap(value)
#         return super(StrictList, self).insert(index, value)


# Path: ronin/executors.py
from .utils.strings import stringify, join_later
from .utils.collections import StrictList
from io import StringIO

        for hook in self.hooks:
            hook(self)
        f.write(stringify(self.command))
    
    def command_as_str(self, argument_filter=None):
        f = StringIO()
        try:
            self.write_command(f, argument_filter)
            v = f.getvalue()
        finally:
            f.close()
        return v

    def add_input(self, value):
        pass


class ExecutorWithArguments(Executor):
    """
    Base class for executors with arguments.
    """

    def __init__(self):
        super(ExecutorWithArguments, self).__init__()
        self._arguments = []

    def write_command(self, f, argument_filter=None):
        super(ExecutorWithArguments, self).write_command(f, argument_filter)
        arguments = []
        for append, to_filter, argument in self._arguments:

            argument = stringify(argument)