import collections
import operator
from abc import ABC, abstractmethod

import builtins

from collections import Iterator

import itertools

import functools

from iterable_collections import utils
from iterable_collections.strategy import MethodStrategy, StoreResultStrategy, ReturnInstanceStrategy, \
    PartialAtPositionIterableBindingStrategy, UnformattedArgumentFormattingStrategy, PreProcessingStrategy, \
    BaseExceptionErrorHandlingStrategy, StoreIterableStrategy, ReturnResultStrategy, PartialIterableBindingStrategy, \
    ConcatMethodStrategy, ConvertToDictErrorHandlingStrategy, DiffMethodStrategy, \
    ConvertToSetArgumentFormattingStrategy, ConvertDictItemsToSetArgumentFormattingStrategy, \
    ConvertToDictArgumentFormattingStrategy, ConvertToIterArgumentFormattingStrategy, \
    ConvertToListArgumentFormattingStrategy, SpreadTupleParameterArgumentFormattingStrategy, \
    RightPartialIterableBindingStrategy, GetItemErrorHandlingStrategy, FlattenMethodStrategy, IntersectMethodStrategy, \
    SetItemErrorHandlingStrategy, SortedAndGroupbyMethodStrategy, PartialInstanceBindingStrategy, ChunksMethodStrategy


class MethodStrategyFactoryInterface(ABC):
    @abstractmethod
    def create(self):
        raise NotImplementedError

    @abstractmethod
    def get_strategies(self):
        raise NotImplementedError


class DefaultMethodStrategyFactory(MethodStrategyFactoryInterface):
    def create(self):
        return {s.name: s for s in self.get_strategies()}

    def get_strategies(self):
        return (
            MethodStrategy(
                'all',
                builtins.all,
                StoreIterableStrategy(),
                ReturnResultStrategy(),
                PartialIterableBindingStrategy(),
                UnformattedArgumentFormattingStrategy(),
                PreProcessingStrategy(),
                BaseExceptionErrorHandlingStrategy()
            ),
            MethodStrategy(
                'any',
                builtins.any,
                StoreIterableStrategy(),
                ReturnResultStrategy(),
                PartialIterableBindingStrategy(),
                UnformattedArgumentFormattingStrategy(),
                PreProcessingStrategy(),
                BaseExceptionErrorHandlingStrategy()
            ),
            ChunksMethodStrategy(
                'chunks',
                StoreResultStrategy(),
                ReturnInstanceStrategy(),
                PartialInstanceBindingStrategy(),
                UnformattedArgumentFormattingStrategy(),
                PreProcessingStrategy(),
                BaseExceptionErrorHandlingStrategy()
            ),
            ChunksMethodStrategy(
                'chunks_dict',
                StoreResultStrategy(),
                ReturnInstanceStrategy(),
                PartialIterableBindingStrategy(),
                UnformattedArgumentFormattingStrategy(),
                PreProcessingStrategy((
                    {'name': 'items', 'args': (), 'kwargs': {}},
                    {'name': 'list_', 'args': (), 'kwargs': {}}
                )),
                BaseExceptionErrorHandlingStrategy()
            ),
            ChunksMethodStrategy(
                'chunks_iter',
                StoreResultStrategy(),
                ReturnInstanceStrategy(),
                PartialIterableBindingStrategy(),
                UnformattedArgumentFormattingStrategy(),
                PreProcessingStrategy((
                    {'name': 'list_', 'args': (), 'kwargs': {}},
                )),
                BaseExceptionErrorHandlingStrategy()
            ),
            ChunksMethodStrategy(
                'chunks_seq',
                StoreResultStrategy(),
                ReturnInstanceStrategy(),
                PartialIterableBindingStrategy(),
                UnformattedArgumentFormattingStrategy(),
                PreProcessingStrategy((
                    {'name': 'list_', 'args': (), 'kwargs': {}},
                )),
                BaseExceptionErrorHandlingStrategy()
            ),
            ConcatMethodStrategy(
                'concat',
                StoreResultStrategy(),
                ReturnInstanceStrategy(),
                PartialInstanceBindingStrategy(),
                UnformattedArgumentFormattingStrategy(),
                PreProcessingStrategy(),
                BaseExceptionErrorHandlingStrategy()
            ),
            ConcatMethodStrategy(
                'concat_dict',
                StoreResultStrategy(),
                ReturnInstanceStrategy(),
                PartialIterableBindingStrategy(),
                ConvertToDictArgumentFormattingStrategy(
                    ConvertToDictErrorHandlingStrategy()
                ),
                PreProcessingStrategy((
                    {'name': 'dict', 'args': (), 'kwargs': {'store': True}},
                )),
                BaseExceptionErrorHandlingStrategy()
            ),
            ConcatMethodStrategy(
                'concat_iter',
                StoreResultStrategy(),
                ReturnInstanceStrategy(),
                PartialIterableBindingStrategy(),
                ConvertToIterArgumentFormattingStrategy(),
                PreProcessingStrategy((
                    {'name': 'iter', 'args': (), 'kwargs': {'store': True}},
                )),
                BaseExceptionErrorHandlingStrategy()
            ),
            ConcatMethodStrategy(
                'concat_seq',
                StoreResultStrategy(),
                ReturnInstanceStrategy(),
                PartialIterableBindingStrategy(),
                ConvertToListArgumentFormattingStrategy(),
                PreProcessingStrategy((
                    {'name': 'list', 'args': (), 'kwargs': {'store': True}},
                )),
                BaseExceptionErrorHandlingStrategy()
            ),
            MethodStrategy(
                'contains',
                operator.contains,
                StoreIterableStrategy(),
                ReturnResultStrategy(),
                PartialIterableBindingStrategy(),
                UnformattedArgumentFormattingStrategy(),
                PreProcessingStrategy(),
                BaseExceptionErrorHandlingStrategy()
            ),
            MethodStrategy(
                'dict',
                builtins.dict,
                StoreIterableStrategy(),
                ReturnResultStrategy(),
                PartialIterableBindingStrategy(),
                UnformattedArgumentFormattingStrategy(),
                PreProcessingStrategy(),
                ConvertToDictErrorHandlingStrategy()
            ),
            MethodStrategy(
                'dict_',
                builtins.dict,
                StoreResultStrategy(),
                ReturnInstanceStrategy(),
                PartialIterableBindingStrategy(),
                UnformattedArgumentFormattingStrategy(),
                PreProcessingStrategy(),
                ConvertToDictErrorHandlingStrategy()
            ),
            DiffMethodStrategy(
                'diff',
                StoreResultStrategy(),
                ReturnInstanceStrategy(),
                PartialInstanceBindingStrategy(),
                UnformattedArgumentFormattingStrategy(),
                PreProcessingStrategy(),
                BaseExceptionErrorHandlingStrategy()
            ),
            MethodStrategy(
                'diff_dict',
                operator.sub,
                StoreResultStrategy(),
                ReturnInstanceStrategy(),
                PartialIterableBindingStrategy(),
                ConvertDictItemsToSetArgumentFormattingStrategy(
                    ConvertToDictArgumentFormattingStrategy(
                        ConvertToDictErrorHandlingStrategy()
                    )
                ),
                PreProcessingStrategy((
                    {'name': 'items', 'args': (), 'kwargs': {}},
                    {'name': 'set', 'args': (), 'kwargs': {'store': True}}
                )),
                ConvertToDictErrorHandlingStrategy()
            ),
            MethodStrategy(
                'diff_iter',
                operator.sub,
                StoreResultStrategy(),
                ReturnInstanceStrategy(),
                PartialIterableBindingStrategy(),
                ConvertToSetArgumentFormattingStrategy(),
                PreProcessingStrategy((
                    {'name': 'set', 'args': (), 'kwargs': {'store': True}},
                )),
                BaseExceptionErrorHandlingStrategy()
            ),
            MethodStrategy(
                'diff_seq',
                operator.sub,
                StoreResultStrategy(),
                ReturnInstanceStrategy(),
                PartialIterableBindingStrategy(),
                ConvertToSetArgumentFormattingStrategy(),
                PreProcessingStrategy((
                    {'name': 'set', 'args': (), 'kwargs': {'store': True}},
                )),
                BaseExceptionErrorHandlingStrategy()
            ),
            MethodStrategy(
                'emap',
                builtins.map,
                StoreResultStrategy(),
                ReturnInstanceStrategy(),
                PartialAtPositionIterableBindingStrategy(position=1),
                SpreadTupleParameterArgumentFormattingStrategy(),
                PreProcessingStrategy((
                    {'name': 'enumerate', 'args': (), 'kwargs': {}},
                )),
                BaseExceptionErrorHandlingStrategy()
            ),
            MethodStrategy(
                'enumerate',
                builtins.enumerate,
                StoreResultStrategy(),
                ReturnInstanceStrategy(),
                PartialIterableBindingStrategy(),
                UnformattedArgumentFormattingStrategy(),
                PreProcessingStrategy(),
                BaseExceptionErrorHandlingStrategy()
            ),
            MethodStrategy(
                'empty',
                lambda x: not x if not isinstance(x, Iterator) else not any(True for _ in x),
                StoreIterableStrategy(),
                ReturnResultStrategy(),
                PartialIterableBindingStrategy(),
                UnformattedArgumentFormattingStrategy(),
                PreProcessingStrategy(),
                BaseExceptionErrorHandlingStrategy()
            ),
            MethodStrategy(
                'filter',
                builtins.filter,
                StoreResultStrategy(),
                ReturnInstanceStrategy(),
                RightPartialIterableBindingStrategy(),
                UnformattedArgumentFormattingStrategy(),
                PreProcessingStrategy(),
                BaseExceptionErrorHandlingStrategy()
            ),
            MethodStrategy(
                'filter_items',
                builtins.filter,
                StoreResultStrategy(),
                ReturnInstanceStrategy(),
                RightPartialIterableBindingStrategy(),
                SpreadTupleParameterArgumentFormattingStrategy(),
                PreProcessingStrategy((
                    {'name': 'items', 'args': (), 'kwargs': {}},
                )),
                BaseExceptionErrorHandlingStrategy()
            ),
            MethodStrategy(
                'filter_nt_items',
                builtins.filter,
                StoreResultStrategy(),
                ReturnInstanceStrategy(),
                RightPartialIterableBindingStrategy(),
                UnformattedArgumentFormattingStrategy(),
                PreProcessingStrategy((
                    {'name': 'nt_items', 'args': (), 'kwargs': {}},
                )),
                BaseExceptionErrorHandlingStrategy()
            ),
            MethodStrategy(
                'first',
                operator.itemgetter(0),
                StoreIterableStrategy(),
                ReturnResultStrategy(),
                PartialIterableBindingStrategy(),
                UnformattedArgumentFormattingStrategy(),
                PreProcessingStrategy(),
                GetItemErrorHandlingStrategy()
            ),
            MethodStrategy(
                'first_item',
                operator.itemgetter(0),
                StoreIterableStrategy(),
                ReturnResultStrategy(),
                PartialIterableBindingStrategy(),
                UnformattedArgumentFormattingStrategy(),
                PreProcessingStrategy((
                    {'name': 'items', 'args': (), 'kwargs': {}},
                    {'name': 'tuple', 'args': (), 'kwargs': {'store': True}}
                )),
                GetItemErrorHandlingStrategy()
            ),
            MethodStrategy(
                'first_nt_item',
                operator.itemgetter(0),
                StoreIterableStrategy(),
                ReturnResultStrategy(),
                PartialIterableBindingStrategy(),
                UnformattedArgumentFormattingStrategy(),
                PreProcessingStrategy((
                    {'name': 'nt_items', 'args': (), 'kwargs': {}},
                )),
                GetItemErrorHandlingStrategy()
            ),
            FlattenMethodStrategy(
                'flatten',
                StoreResultStrategy(),
                ReturnInstanceStrategy(),
                PartialIterableBindingStrategy(),
                UnformattedArgumentFormattingStrategy(),
                PreProcessingStrategy((
                    {'name': 'list', 'args': (), 'kwargs': {'store': True}},
                )),
                BaseExceptionErrorHandlingStrategy()
            ),
            MethodStrategy(
                'getitem',
                operator.getitem,
                StoreIterableStrategy(),
                ReturnResultStrategy(),
                PartialIterableBindingStrategy(),
                UnformattedArgumentFormattingStrategy(),
                PreProcessingStrategy(),
                GetItemErrorHandlingStrategy()
            ),
            MethodStrategy(
                'groupby',
                itertools.groupby,
                StoreResultStrategy(),
                ReturnInstanceStrategy(),
                PartialIterableBindingStrategy(),
                UnformattedArgumentFormattingStrategy(),
                PreProcessingStrategy(),
                BaseExceptionErrorHandlingStrategy()
            ),
            IntersectMethodStrategy(
                'intersect',
                StoreResultStrategy(),
                ReturnInstanceStrategy(),
                PartialInstanceBindingStrategy(),
                UnformattedArgumentFormattingStrategy(),
                PreProcessingStrategy(),
                BaseExceptionErrorHandlingStrategy()
            ),
            MethodStrategy(
                'intersect_dict',
                operator.and_,
                StoreResultStrategy(),
                ReturnInstanceStrategy(),
                PartialIterableBindingStrategy(),
                ConvertDictItemsToSetArgumentFormattingStrategy(
                    ConvertToDictArgumentFormattingStrategy(
                        ConvertToDictErrorHandlingStrategy()
                    )
                ),
                PreProcessingStrategy((
                    {'name': 'items', 'args': (), 'kwargs': {}},
                    {'name': 'set', 'args': (), 'kwargs': {'store': True}}
                )),
                BaseExceptionErrorHandlingStrategy()
            ),
            MethodStrategy(
                'intersect_iter',
                operator.and_,
                StoreResultStrategy(),
                ReturnInstanceStrategy(),
                PartialIterableBindingStrategy(),
                ConvertToSetArgumentFormattingStrategy(),
                PreProcessingStrategy((
                    {'name': 'set', 'args': (), 'kwargs': {'store': True}},
                )),
                BaseExceptionErrorHandlingStrategy()
            ),
            MethodStrategy(
                'intersect_seq',
                operator.and_,
                StoreResultStrategy(),
                ReturnInstanceStrategy(),
                PartialIterableBindingStrategy(),
                ConvertToSetArgumentFormattingStrategy(),
                PreProcessingStrategy((
                    {'name': 'set', 'args': (), 'kwargs': {'store': True}},
                )),
                BaseExceptionErrorHandlingStrategy()
            ),
            MethodStrategy(
                'islice',
                itertools.islice,
                StoreResultStrategy(),
                ReturnInstanceStrategy(),
                PartialIterableBindingStrategy(),
                UnformattedArgumentFormattingStrategy(),
                PreProcessingStrategy(),
                BaseExceptionErrorHandlingStrategy()
            ),
            MethodStrategy(
                'items',
                dict.items,
                StoreResultStrategy(),
                ReturnInstanceStrategy(),
                PartialIterableBindingStrategy(),
                UnformattedArgumentFormattingStrategy(),
                PreProcessingStrategy((
                    {'name': 'dict', 'args': (), 'kwargs': {'store': True}},
                )),
                BaseExceptionErrorHandlingStrategy()
            ),
            MethodStrategy(
                'iter',
                builtins.iter,
                StoreIterableStrategy(),
                ReturnResultStrategy(),
                PartialIterableBindingStrategy(),
                UnformattedArgumentFormattingStrategy(),
                PreProcessingStrategy(),
                BaseExceptionErrorHandlingStrategy()
            ),
            MethodStrategy(
                'iter_',
                builtins.iter,
                StoreResultStrategy(),
                ReturnInstanceStrategy(),
                PartialIterableBindingStrategy(),
                UnformattedArgumentFormattingStrategy(),
                PreProcessingStrategy(),
                BaseExceptionErrorHandlingStrategy()
            ),
            MethodStrategy(
                'join',
                str.join,
                StoreIterableStrategy(),
                ReturnResultStrategy(),
                RightPartialIterableBindingStrategy(),
                UnformattedArgumentFormattingStrategy(),
                PreProcessingStrategy(),
                BaseExceptionErrorHandlingStrategy()
            ),
            MethodStrategy(
                'last',
                operator.itemgetter(-1),
                StoreIterableStrategy(),
                ReturnResultStrategy(),
                PartialIterableBindingStrategy(),
                UnformattedArgumentFormattingStrategy(),
                PreProcessingStrategy(),
                BaseExceptionErrorHandlingStrategy()
            ),
            MethodStrategy(
                'last_item',
                operator.itemgetter(-1),
                StoreIterableStrategy(),
                ReturnResultStrategy(),
                PartialIterableBindingStrategy(),
                UnformattedArgumentFormattingStrategy(),
                PreProcessingStrategy((
                    {'name': 'items', 'args': (), 'kwargs': {}},
                    {'name': 'list_', 'args': (), 'kwargs': {}},
                )),
                BaseExceptionErrorHandlingStrategy()
            ),
            MethodStrategy(
                'last_nt_item',
                operator.itemgetter(-1),
                StoreIterableStrategy(),
                ReturnResultStrategy(),
                PartialIterableBindingStrategy(),
                UnformattedArgumentFormattingStrategy(),
                PreProcessingStrategy((
                    {'name': 'nt_items', 'args': (), 'kwargs': {}},
                )),
                BaseExceptionErrorHandlingStrategy()
            ),
            MethodStrategy(
                'len',
                builtins.len,
                StoreIterableStrategy(),
                ReturnResultStrategy(),
                PartialIterableBindingStrategy(),
                UnformattedArgumentFormattingStrategy(),
                PreProcessingStrategy(),
                BaseExceptionErrorHandlingStrategy()
            ),
            MethodStrategy(
                'list',
                builtins.list,
                StoreIterableStrategy(),
                ReturnResultStrategy(),
                PartialIterableBindingStrategy(),
                UnformattedArgumentFormattingStrategy(),
                PreProcessingStrategy(),
                BaseExceptionErrorHandlingStrategy()
            ),
            MethodStrategy(
                'list_',
                builtins.list,
                StoreResultStrategy(),
                ReturnInstanceStrategy(),
                PartialIterableBindingStrategy(),
                UnformattedArgumentFormattingStrategy(),
                PreProcessingStrategy(),
                BaseExceptionErrorHandlingStrategy()
            ),
            MethodStrategy(
                'map',
                builtins.map,
                StoreResultStrategy(),
                ReturnInstanceStrategy(),
                PartialAtPositionIterableBindingStrategy(position=1),
                UnformattedArgumentFormattingStrategy(),
                PreProcessingStrategy(),
                BaseExceptionErrorHandlingStrategy()
            ),
            MethodStrategy(
                'map_items',
                builtins.map,
                StoreResultStrategy(),
                ReturnInstanceStrategy(),
                PartialAtPositionIterableBindingStrategy(position=1),
                SpreadTupleParameterArgumentFormattingStrategy(),
                PreProcessingStrategy((
                    {'name': 'items', 'args': (), 'kwargs': {}},
                )),
                BaseExceptionErrorHandlingStrategy()
            ),
            MethodStrategy(
                'map_nt_items',
                builtins.map,
                StoreResultStrategy(),
                ReturnInstanceStrategy(),
                PartialAtPositionIterableBindingStrategy(position=1),
                UnformattedArgumentFormattingStrategy(),
                PreProcessingStrategy((
                    {'name': 'nt_items', 'args': (), 'kwargs': {}},
                )),
                BaseExceptionErrorHandlingStrategy()
            ),
            MethodStrategy(
                'max',
                builtins.max,
                StoreIterableStrategy(),
                ReturnResultStrategy(),
                PartialIterableBindingStrategy(),
                UnformattedArgumentFormattingStrategy(),
                PreProcessingStrategy(),
                BaseExceptionErrorHandlingStrategy()
            ),
            MethodStrategy(
                'min',
                builtins.min,
                StoreIterableStrategy(),
                ReturnResultStrategy(),
                PartialIterableBindingStrategy(),
                UnformattedArgumentFormattingStrategy(),
                PreProcessingStrategy(),
                BaseExceptionErrorHandlingStrategy()
            ),
            MethodStrategy(
                'next',
                builtins.next,
                StoreIterableStrategy(),
                ReturnResultStrategy(),
                PartialIterableBindingStrategy(),
                UnformattedArgumentFormattingStrategy(),
                PreProcessingStrategy((
                    {'name': 'iter_', 'args': (), 'kwargs': {}},
                )),
                BaseExceptionErrorHandlingStrategy()
            ),
            MethodStrategy(
                'nt_items',
                utils.make_nt_items,
                StoreResultStrategy(),
                ReturnInstanceStrategy(),
                PartialIterableBindingStrategy(),
                UnformattedArgumentFormattingStrategy(),
                PreProcessingStrategy((
                    {'name': 'items', 'args': (), 'kwargs': {}},
                )),
                BaseExceptionErrorHandlingStrategy()
            ),
            MethodStrategy(
                'ordered_dict',
                collections.OrderedDict,
                StoreIterableStrategy(),
                ReturnResultStrategy(),
                PartialIterableBindingStrategy(),
                UnformattedArgumentFormattingStrategy(),
                PreProcessingStrategy(),
                ConvertToDictErrorHandlingStrategy()
            ),
            MethodStrategy(
                'ordered_dict_',
                collections.OrderedDict,
                StoreResultStrategy(),
                ReturnInstanceStrategy(),
                PartialIterableBindingStrategy(),
                UnformattedArgumentFormattingStrategy(),
                PreProcessingStrategy(),
                ConvertToDictErrorHandlingStrategy()
            ),
            MethodStrategy(
                'pop',
                list.pop,
                StoreIterableStrategy(),
                ReturnResultStrategy(),
                PartialIterableBindingStrategy(),
                UnformattedArgumentFormattingStrategy(),
                PreProcessingStrategy((
                    {'name': 'list', 'args': (), 'kwargs': {'store': True}},
                )),
                BaseExceptionErrorHandlingStrategy()
            ),
            MethodStrategy(
                'reduce',
                functools.reduce,
                StoreIterableStrategy(),
                ReturnResultStrategy(),
                PartialAtPositionIterableBindingStrategy(position=1),
                UnformattedArgumentFormattingStrategy(),
                PreProcessingStrategy(),
                BaseExceptionErrorHandlingStrategy()
            ),
            MethodStrategy(
                'reduce_items',
                functools.reduce,
                StoreIterableStrategy(),
                ReturnResultStrategy(),
                PartialAtPositionIterableBindingStrategy(position=1),
                SpreadTupleParameterArgumentFormattingStrategy(callable_position=1),
                PreProcessingStrategy((
                    {'name': 'items', 'args': (), 'kwargs': {}},
                )),
                BaseExceptionErrorHandlingStrategy()
            ),
            MethodStrategy(
                'reduce_nt_items',
                functools.reduce,
                StoreIterableStrategy(),
                ReturnResultStrategy(),
                PartialAtPositionIterableBindingStrategy(position=1),
                UnformattedArgumentFormattingStrategy(),
                PreProcessingStrategy((
                    {'name': 'nt_items', 'args': (), 'kwargs': {}},
                )),
                BaseExceptionErrorHandlingStrategy()
            ),
            MethodStrategy(
                'reversed',
                builtins.reversed,
                StoreResultStrategy(),
                ReturnInstanceStrategy(),
                PartialIterableBindingStrategy(),
                UnformattedArgumentFormattingStrategy(),
                PreProcessingStrategy((
                    {'name': 'list', 'args': (), 'kwargs': {'store': True}},
                )),
                BaseExceptionErrorHandlingStrategy()
            ),
            MethodStrategy(
                'set',
                builtins.set,
                StoreIterableStrategy(),
                ReturnResultStrategy(),
                PartialIterableBindingStrategy(),
                UnformattedArgumentFormattingStrategy(),
                PreProcessingStrategy(),
                BaseExceptionErrorHandlingStrategy()
            ),
            MethodStrategy(
                'set_',
                builtins.set,
                StoreResultStrategy(),
                ReturnInstanceStrategy(),
                PartialIterableBindingStrategy(),
                UnformattedArgumentFormattingStrategy(),
                PreProcessingStrategy(),
                BaseExceptionErrorHandlingStrategy()
            ),
            MethodStrategy(
                'setitem',
                operator.setitem,
                StoreIterableStrategy(),
                ReturnInstanceStrategy(),
                PartialIterableBindingStrategy(),
                UnformattedArgumentFormattingStrategy(),
                PreProcessingStrategy(),
                SetItemErrorHandlingStrategy()
            ),
            MethodStrategy(
                'slice',
                lambda d, x, y=None: operator.getitem(d, slice(x, y)),
                StoreResultStrategy(),
                ReturnInstanceStrategy(),
                PartialIterableBindingStrategy(),
                UnformattedArgumentFormattingStrategy(),
                PreProcessingStrategy((
                    {'name': 'list', 'args': (), 'kwargs': {'store': True}},
                )),
                BaseExceptionErrorHandlingStrategy()
            ),
            MethodStrategy(
                'sorted',
                builtins.sorted,
                StoreResultStrategy(),
                ReturnInstanceStrategy(),
                PartialIterableBindingStrategy(),
                UnformattedArgumentFormattingStrategy(),
                PreProcessingStrategy(),
                BaseExceptionErrorHandlingStrategy()
            ),
            SortedAndGroupbyMethodStrategy(
                'sorted_and_groupby',
                StoreIterableStrategy(),
                ReturnInstanceStrategy(),
                PartialInstanceBindingStrategy(),
                UnformattedArgumentFormattingStrategy(),
                PreProcessingStrategy(),
                BaseExceptionErrorHandlingStrategy()
            ),
            MethodStrategy(
                'tuple',
                builtins.tuple,
                StoreIterableStrategy(),
                ReturnResultStrategy(),
                PartialIterableBindingStrategy(),
                UnformattedArgumentFormattingStrategy(),
                PreProcessingStrategy(),
                BaseExceptionErrorHandlingStrategy()
            ),
            MethodStrategy(
                'tuple_',
                builtins.tuple,
                StoreResultStrategy(),
                ReturnInstanceStrategy(),
                PartialIterableBindingStrategy(),
                UnformattedArgumentFormattingStrategy(),
                PreProcessingStrategy(),
                BaseExceptionErrorHandlingStrategy()
            ),
            MethodStrategy(
                'unique',
                builtins.set,
                StoreResultStrategy(),
                ReturnInstanceStrategy(),
                PartialIterableBindingStrategy(),
                UnformattedArgumentFormattingStrategy(),
                PreProcessingStrategy(),
                BaseExceptionErrorHandlingStrategy()
            ),
            MethodStrategy(
                'zip',
                builtins.zip,
                StoreResultStrategy(),
                ReturnInstanceStrategy(),
                PartialIterableBindingStrategy(),
                UnformattedArgumentFormattingStrategy(),
                PreProcessingStrategy(),
                BaseExceptionErrorHandlingStrategy()
            )
        )