bool TryRemoveTransparentIdentifier(QueryExpression query, QueryFromClause fromClause, QueryExpression innerQuery)
        {
            if (!IsTransparentIdentifier(fromClause.Identifier))
            {
                return(false);
            }
            Match match = selectTransparentIdentifierPattern.Match(innerQuery.Clauses.Last());

            if (!match.Success)
            {
                return(false);
            }
            QuerySelectClause       selectClause = (QuerySelectClause)innerQuery.Clauses.Last();
            NamedArgumentExpression nae1         = match.Get <NamedArgumentExpression>("nae1").Single();
            NamedArgumentExpression nae2         = match.Get <NamedArgumentExpression>("nae2").Single();

            if (nae1.Identifier != ((IdentifierExpression)nae1.Expression).Identifier)
            {
                return(false);
            }
            IdentifierExpression nae2IdentExpr = nae2.Expression as IdentifierExpression;

            if (nae2IdentExpr != null && nae2.Identifier == nae2IdentExpr.Identifier)
            {
                // from * in (from x in ... select new { x = x, y = y }) ...
                // =>
                // from x in ... ...
                fromClause.Remove();
                selectClause.Remove();
                // Move clauses from innerQuery to query
                QueryClause insertionPos = null;
                foreach (var clause in innerQuery.Clauses)
                {
                    query.Clauses.InsertAfter(insertionPos, insertionPos = clause.Detach());
                }
            }
            else
            {
                // from * in (from x in ... select new { x = x, y = expr }) ...
                // =>
                // from x in ... let y = expr ...
                fromClause.Remove();
                selectClause.Remove();
                // Move clauses from innerQuery to query
                QueryClause insertionPos = null;
                foreach (var clause in innerQuery.Clauses)
                {
                    query.Clauses.InsertAfter(insertionPos, insertionPos = clause.Detach());
                }
                query.Clauses.InsertAfter(insertionPos, new QueryLetClause {
                    Identifier = nae2.Identifier, Expression = nae2.Expression.Detach()
                });
            }
            return(true);
        }
        bool TryRemoveTransparentIdentifier(QueryExpression query, QueryFromClause fromClause, QueryExpression innerQuery, Dictionary <string, object> letClauses)
        {
            if (!IsTransparentIdentifier(fromClause.Identifier))
            {
                return(false);
            }
            QuerySelectClause selectClause = innerQuery.Clauses.Last() as QuerySelectClause;
            Match             match        = selectTransparentIdentifierPattern.Match(selectClause);

            if (!match.Success)
            {
                return(false);
            }

            // from * in (from x in ... select new { members of anonymous type }) ...
            // =>
            // from x in ... { let x = ... } ...
            fromClause.Remove();
            selectClause.Remove();
            // Move clauses from innerQuery to query
            QueryClause insertionPos = null;

            foreach (var clause in innerQuery.Clauses)
            {
                query.Clauses.InsertAfter(insertionPos, insertionPos = clause.Detach());
            }

            foreach (var expr in match.Get <Expression>("expr"))
            {
                switch (expr)
                {
                case IdentifierExpression identifier:
                    // nothing to add
                    continue;

                case NamedExpression namedExpression:
                    if (namedExpression.Expression is IdentifierExpression identifierExpression && namedExpression.Name == identifierExpression.Identifier)
                    {
                        letClauses[namedExpression.Name] = identifierExpression.Annotation <ILVariableResolveResult>();
                        continue;
                    }
                    QueryLetClause letClause = new QueryLetClause {
                        Identifier = namedExpression.Name, Expression = namedExpression.Expression.Detach()
                    };
                    var annotation = new LetIdentifierAnnotation();
                    letClause.AddAnnotation(annotation);
                    letClauses[namedExpression.Name] = annotation;
                    query.Clauses.InsertAfter(insertionPos, letClause);
                    break;
                }
            }
            return(true);
        }
            bool TryRemoveTransparentIdentifier(QueryExpression query, QueryFromClause fromClause, QueryExpression innerQuery)
            {
                if (!IsTransparentIdentifier(fromClause.Identifier))
                {
                    return(false);
                }
                Match match = selectTransparentIdentifierPattern.Match(innerQuery.Clauses.Last());

                if (!match.Success)
                {
                    return(false);
                }
                QuerySelectClause selectClause = (QuerySelectClause)innerQuery.Clauses.Last();
                NamedExpression   nae1         = match.Get <NamedExpression>("nae1").SingleOrDefault();
                NamedExpression   nae2         = match.Get <NamedExpression>("nae2").SingleOrDefault();

                if (nae1 != null && nae1.Name != ((IdentifierExpression)nae1.Expression).Identifier)
                {
                    return(false);
                }
                Expression           nae2Expr      = match.Get <Expression>("nae2Expr").Single();
                IdentifierExpression nae2IdentExpr = nae2Expr as IdentifierExpression;

                if (nae2IdentExpr != null && (nae2 == null || nae2.Name == nae2IdentExpr.Identifier))
                {
                    // from * in (from x in ... select new { x = x, y = y }) ...
                    // =>
                    // from x in ... ...
                    fromClause.Remove();
                    selectClause.Remove();
                    // Move clauses from innerQuery to query
                    QueryClause insertionPos = null;
                    foreach (var clause in innerQuery.Clauses)
                    {
                        query.Clauses.InsertAfter(insertionPos, insertionPos = Detach(clause));
                    }
                }
                else
                {
                    // from * in (from x in ... select new { x = x, y = expr }) ...
                    // =>
                    // from x in ... let y = expr ...
                    fromClause.Remove();
                    selectClause.Remove();
                    // Move clauses from innerQuery to query
                    QueryClause insertionPos = null;
                    foreach (var clause in innerQuery.Clauses)
                    {
                        query.Clauses.InsertAfter(insertionPos, insertionPos = Detach(clause));
                    }
                    string ident;
                    if (nae2 != null)
                    {
                        ident = nae2.Name;
                    }
                    else if (nae2Expr is MemberReferenceExpression)
                    {
                        ident = ((MemberReferenceExpression)nae2Expr).MemberName;
                    }
                    else
                    {
                        throw new InvalidOperationException("Could not infer name from initializer in AnonymousTypeCreateExpression");
                    }
                    query.Clauses.InsertAfter(insertionPos, new QueryLetClause {
                        Identifier = ident, Expression = Detach(nae2Expr)
                    });
                }
                return(true);
            }