(from s in ... select s).Take (1).Where (s != null)
This is because QueryParser.CreateClauseChain removes select clauses that are followed by other clauses without keeping their ResultModifications.
The solution would be to put all result modifications of the removed clauses into the ClauseGenerationContext and add their clones in ResultModificationExpressionNodeBase.GetSelectClauseForResultModification to the new select clause. The same must be done in QueryParser.GetOrCreateSelectClause.
Alternatively, change ResultModificationExpressionNodeBase.CreateClause to not create any Select clauses or ResultModifications, but instead add the nodes to the context. Then, after everything is done, the nodes could provide a CreateResultModification method to create all result modifications.
This will make it much easier to deal with user-defined expression types.
This will make manipulation of the clause chain easier because clauses and QueryModel don't need to be kept in sync.
GetExpressionTree is only used in error messages, and it causes lots of problems because it would have to be invalidated and recalculated every time the query model changes.
This removes the "readonly" aspect of previous clauses, but it seems much more natural than having to always specify a previous clause when generating a new object.
After COMMONS-1178, the CreateClause and CreateSelectClause, which were used to produce clause chains, don't fit very well. It would be better to unify the Apply concept already used for ResultModificationExpressionNodeBase to all nodes.