protected override KeyValuePair <Expression, List <KeyValuePair <int, MutatorConfiguration> > > BuildRawMutators <TValue>(Expression <Func <TData, TValue> > path)
        {
            var node = tree.Traverse(path.Body, create: false);

            if (node == null)
            {
                return(default(KeyValuePair <Expression, List <KeyValuePair <int, MutatorConfiguration> > >));
            }
            IEnumerable <MutatorConfiguration> mutators;
            var alienArray = node.NodeType.IsArray ? node.GetAlienArray() : null;

            if (alienArray == null)
            {
                mutators = node.GetMutators();
            }
            else
            {
                var setSourceArrayConfiguration = SetSourceArrayConfiguration.Create(Expression.Lambda(alienArray, alienArray.ExtractParameters()));
                mutators = node.GetMutators().Concat(new[] { setSourceArrayConfiguration });
            }

            return(new KeyValuePair <Expression, List <KeyValuePair <int, MutatorConfiguration> > >(node.Path, mutators.Select(mutator => new KeyValuePair <int, MutatorConfiguration>(priority, mutator)).ToList()));
        }
        protected List <MutatorConfiguration> Canonize(IEnumerable <KeyValuePair <int, MutatorConfiguration> > mutators)
        {
            // todo ich: kill, as soon as scripts are fixed
            // todo ich: handle validation priorities
            if (mutators == null)
            {
                return(null);
            }
            var hideIfConfigurations           = new List <HideIfConfiguration>();
            var disableIfConfigurations        = new List <DisableIfConfiguration>();
            var staticAggregatorConfigurations = new Dictionary <string, List <ConditionalAggregatorConfiguration> >();
            //var validatorConfigurations = new List<KeyValuePair<int, ValidatorConfiguration>>();
            SetSourceArrayConfiguration setSourceArrayConfiguration = null;
            var otherConfigurations = new List <MutatorConfiguration>();

            foreach (var mutator in mutators)
            {
                if (mutator.Value is HideIfConfiguration)
                {
                    hideIfConfigurations.Add((HideIfConfiguration)mutator.Value);
                }
                else if (mutator.Value is DisableIfConfiguration)
                {
                    disableIfConfigurations.Add((DisableIfConfiguration)mutator.Value);
                }
//                else if(mutator.Value is ValidatorConfiguration)
//                    validatorConfigurations.Add(new KeyValuePair<int, ValidatorConfiguration>(mutator.Key, (ValidatorConfiguration)mutator.Value));
                else if (mutator.Value is SetSourceArrayConfiguration)
                {
                    var currentSetSourceArrayConfiguration = (SetSourceArrayConfiguration)mutator.Value;
                    if (setSourceArrayConfiguration == null)
                    {
                        setSourceArrayConfiguration = currentSetSourceArrayConfiguration;
                    }
                    else if (!ExpressionEquivalenceChecker.Equivalent(setSourceArrayConfiguration.SourceArray, currentSetSourceArrayConfiguration.SourceArray, false, true))
                    {
                        throw new InvalidOperationException("An attempt to set array from different sources: '" + setSourceArrayConfiguration.SourceArray + "' and '" + currentSetSourceArrayConfiguration.SourceArray + "'");
                    }
                }
                else if (mutator.Value is ConditionalAggregatorConfiguration)
                {
                    var staticAggregator = (ConditionalAggregatorConfiguration)mutator.Value;
                    List <ConditionalAggregatorConfiguration> staticAggregators;
                    if (!staticAggregatorConfigurations.TryGetValue(staticAggregator.Name, out staticAggregators))
                    {
                        staticAggregatorConfigurations.Add(staticAggregator.Name, staticAggregators = new List <ConditionalAggregatorConfiguration>());
                    }
                    staticAggregators.Add(staticAggregator);
                }
                else
                {
                    otherConfigurations.Add(mutator.Value);
                }
            }

            if (hideIfConfigurations.Count == 1)
            {
                otherConfigurations.Add(hideIfConfigurations.Single());
            }
            else if (hideIfConfigurations.Count > 1)
            {
                var condition = hideIfConfigurations[0].Condition;
                var type      = hideIfConfigurations[0].Type;
                for (var i = 1; i < hideIfConfigurations.Count; ++i)
                {
                    condition = condition.OrElse(hideIfConfigurations[i].Condition);
                }
                otherConfigurations.Add(new HideIfConfiguration(type, condition));
            }

            if (disableIfConfigurations.Count == 1)
            {
                otherConfigurations.Add(disableIfConfigurations.Single());
            }
            else if (disableIfConfigurations.Count > 1)
            {
                var condition = disableIfConfigurations[0].Condition;
                var type      = disableIfConfigurations[0].Type;
                for (var i = 1; i < disableIfConfigurations.Count; ++i)
                {
                    condition = condition.OrElse(disableIfConfigurations[i].Condition);
                }
                otherConfigurations.Add(new DisableIfConfiguration(type, condition));
            }

            foreach (var item in staticAggregatorConfigurations)
            {
                var staticAggregators = item.Value;
                if (staticAggregators.Count == 1)
                {
                    otherConfigurations.Add(staticAggregators.Single());
                }
                else
                {
                    var condition = staticAggregators[0].Condition;
                    var type      = staticAggregators[0].Type;
                    for (var i = 1; i < staticAggregators.Count; ++i)
                    {
                        condition = condition.OrElse(staticAggregators[i].Condition);
                    }
                    otherConfigurations.Add(new ConditionalAggregatorConfiguration(type, condition, item.Key));
                }
            }

            if (setSourceArrayConfiguration != null)
            {
                otherConfigurations.Add(setSourceArrayConfiguration);
            }
            return(otherConfigurations);
        }