public static Expression ReplaceTransparentIdentifiers(Expression expression)
        {
            Expression expressionBeforeRemove;
            Expression expressionAfterRemove = expression;

            // Run again and again until no replacements have been made.
            do
            {
                expressionBeforeRemove = expressionAfterRemove;
                expressionAfterRemove  = new TransparentIdentifierRemovingExpressionVisitor().Visit(expressionAfterRemove);
            } while (expressionAfterRemove != expressionBeforeRemove);

            return(expressionAfterRemove);
        }
			public static Expression FlattenGroupingKey(Expression expression)
			{
				var visitor = new GroupingKeyFlattener();
				expression = visitor.Visit(expression);
				if (visitor._flattened)
				{
					expression = TransparentIdentifierRemovingExpressionVisitor.ReplaceTransparentIdentifiers(expression);
					// When the grouping key is an array we have to unwrap it (e.g. group.Key[0] == variable)
					if (expression.NodeType == ExpressionType.ArrayIndex &&
					    expression is BinaryExpression binaryExpression &&
					    binaryExpression.Left is NewArrayExpression newArray &&
					    binaryExpression.Right is ConstantExpression indexExpression &&
					    indexExpression.Value is int index)
					{
						return newArray.Expressions[index];
					}
				}

				return expression;
			}
 public Expression Swap(Expression expression)
 {
     return(TransparentIdentifierRemovingExpressionVisitor.ReplaceTransparentIdentifiers(Visit(expression)));
 }