protected virtual void FlattenSubQuery (
        SubQueryExpression subQueryExpression, FromClauseBase fromClause, QueryModel queryModel, int destinationIndex)
    {
      ArgumentUtility.CheckNotNull ("subQueryExpression", subQueryExpression);
      ArgumentUtility.CheckNotNull ("fromClause", fromClause);
      ArgumentUtility.CheckNotNull ("queryModel", queryModel);

      CheckFlattenable (subQueryExpression.QueryModel);

      var innerMainFromClause = subQueryExpression.QueryModel.MainFromClause;
      CopyFromClauseData (innerMainFromClause, fromClause);

      var innerSelectorMapping = new QuerySourceMapping();
      innerSelectorMapping.AddMapping (fromClause, subQueryExpression.QueryModel.SelectClause.Selector);
      queryModel.TransformExpressions (ex => ReferenceReplacingExpressionTreeVisitor.ReplaceClauseReferences (ex, innerSelectorMapping, false));

      InsertBodyClauses (subQueryExpression.QueryModel.BodyClauses, queryModel, destinationIndex);

      var innerBodyClauseMapping = new QuerySourceMapping();
      innerBodyClauseMapping.AddMapping (innerMainFromClause, new QuerySourceReferenceExpression (fromClause));
      queryModel.TransformExpressions (ex => ReferenceReplacingExpressionTreeVisitor.ReplaceClauseReferences (ex, innerBodyClauseMapping, false));
    }
    protected void CopyFromClauseData (FromClauseBase source, FromClauseBase destination)
    {
      ArgumentUtility.CheckNotNull ("source", source);
      ArgumentUtility.CheckNotNull ("destination", destination);

      destination.FromExpression = source.FromExpression;
      destination.ItemName = source.ItemName;
      destination.ItemType = source.ItemType;
    }