/// <inheritdoc/>
        protected override Provider VisitCalculate(CalculateProvider provider)
        {
            OnRecursionEntrance(provider);
            var source = VisitCompilable(provider.Source);

            OnRecursionExit(provider);
            var translated  = false;
            var descriptors = new List <CalculatedColumnDescriptor>(provider.CalculatedColumns.Length);

            foreach (var column in provider.CalculatedColumns)
            {
                var expression = translate(provider, column.Expression);
                if (expression != column.Expression)
                {
                    translated = true;
                }
                var ccd = new CalculatedColumnDescriptor(column.Name, column.Type, (Expression <Func <Tuple, object> >)expression);
                descriptors.Add(ccd);
            }
            if (!translated && source == provider.Source)
            {
                return(provider);
            }
            return(new CalculateProvider(source, descriptors.ToArray()));
        }
        protected override Provider VisitCalculate(CalculateProvider provider)
        {
            int sourceLength  = provider.Source.Header.Length;
            var usedColumns   = mappings[provider];
            var sourceMapping = Merge(
                mappings[provider].Where(i => i < sourceLength),
                provider.CalculatedColumns.SelectMany(c => mappingsGatherer.Gather(c.Expression))
                );

            mappings[provider.Source] = sourceMapping;
            var newSourceProvider = VisitCompilable(provider.Source);

            mappings[provider] = mappings[provider.Source];

            bool translated     = false;
            var  descriptors    = new List <CalculatedColumnDescriptor>(provider.CalculatedColumns.Length);
            var  currentMapping = mappings[provider];

            for (int calculatedColumnIndex = 0; calculatedColumnIndex < provider.CalculatedColumns.Length; calculatedColumnIndex++)
            {
                if (usedColumns.Contains(provider.CalculatedColumns[calculatedColumnIndex].Index))
                {
                    currentMapping.Add(provider.Source.Header.Length + calculatedColumnIndex);
                    var column     = provider.CalculatedColumns[calculatedColumnIndex];
                    var expression = TranslateLambda(provider, column.Expression);
                    if (expression != column.Expression)
                    {
                        translated = true;
                    }
                    var ccd = new CalculatedColumnDescriptor(column.Name, column.Type, (Expression <Func <Tuple, object> >)expression);
                    descriptors.Add(ccd);
                }
            }
            mappings[provider] = currentMapping;
            if (descriptors.Count == 0)
            {
                return(newSourceProvider);
            }
            if (!translated && newSourceProvider == provider.Source && descriptors.Count == provider.CalculatedColumns.Length)
            {
                return(provider);
            }
            return(new CalculateProvider(newSourceProvider, descriptors.ToArray()));
        }