/// <summary>
        /// Initializes a new instance of the <see cref="PermutationProcessor"/> class.
        /// </summary>
        /// <param name="values">All objects, every element - one permutation item</param>
        /// <param name="fun">To break -&gt; return true</param>
        public PermutationProcessor(IEnumerable values, Func <IEnumerable <object>, bool> fun)
        {
            IEnumerable <object> reverseList = values.Cast <object>().Reverse();

            object[] generatedParams = new object[reverseList.Count()];

            IPermutationNode firstNode = new PermutationProcessorFinalNode(fun, generatedParams);

            int resultIndex = reverseList.Count() - 1;

            foreach (object val in values.Cast <object>().Reverse())
            {
                if (typeof(IEnumerable).IsAssignableFrom(val.GetType()))
                {
                    firstNode = new PermutationProcessorNode((IEnumerable)val, resultIndex, firstNode, generatedParams);
                }
                else
                {
                    firstNode = new PermutationProcessorOneElementNode(val, resultIndex, firstNode, generatedParams);
                }

                resultIndex--;
            }

            this.root = firstNode;
        }
            internal PermutationProcessorNode(IEnumerable values, int resultIndex, IPermutationNode next, object[] generatedParams)
            {
                if (values == null)
                {
                    throw new ArgumentNullException(nameof(values));
                }

                if (next == null)
                {
                    throw new ArgumentNullException(nameof(next));
                }

                if (generatedParams == null)
                {
                    throw new ArgumentNullException(nameof(generatedParams));
                }

                if (resultIndex < 0)
                {
                    throw new ArgumentOutOfRangeException(nameof(resultIndex));
                }

                this.values          = values;
                this.next            = next;
                this.resultIndex     = resultIndex;
                this.generatedParams = generatedParams;
            }
            internal PermutationProcessorOneElementNode(object value, int resultIndex, IPermutationNode next, object[] generatedParams)
            {
                if (next == null)
                {
                    throw new ArgumentNullException(nameof(next));
                }

                if (generatedParams == null)
                {
                    throw new ArgumentNullException(nameof(generatedParams));
                }

                if (resultIndex < 0)
                {
                    throw new ArgumentOutOfRangeException(nameof(resultIndex));
                }

                this.next = next;
                generatedParams[resultIndex] = value;
            }
        /// <summary>
        /// Processors constructor
        /// </summary>
        /// <param name="values">All objects, every element - one permutation item</param>
        /// <param name="fun">To break -> return true</param>
        public PermutationProcessor(IEnumerable values, Func<IEnumerable<object>, bool> fun) {
            IEnumerable<object> reverseList = values.Cast<object>().Reverse();

            object[] generatedParams = new object[reverseList.Count()];

            IPermutationNode firstNode = new PermutationProcessorFinalNode(fun, generatedParams);

            int resultIndex = reverseList.Count() - 1;

            foreach (object val in values.Cast<object>().Reverse()) {
                if (val.GetType().IsArray || (val.GetType().IsGenericType && val.GetType().ReflectedType == typeof(Enumerable))) {
                    firstNode = new PermutationProcessorNode((IEnumerable)val, resultIndex, firstNode, generatedParams);
                }
                else {
                    firstNode = new PermutationProcessorOneElementNode(val, resultIndex, firstNode, generatedParams);
                }

                resultIndex--;
            }

            this.root = firstNode;
        }
 internal PermutationProcessorNode(IEnumerable values, int resultIndex, IPermutationNode next, object[] generatedParams) {
     this.values = values;
     this.next = next;
     this.resultIndex = resultIndex;
     this.generatedParams = generatedParams;
 }
 internal PermutationProcessorOneElementNode(object value, int resultIndex, IPermutationNode next, object[] generatedParams) {
     this.next = next;
     generatedParams[resultIndex] = value;
 }