}                             // getTableFromItems()

        public static List <FromItem> getTableFromItems(FromItem item)
        {
            List <FromItem> result = new List <FromItem>();

            if (item.getTable() != null)
            {
                result.Add(item);
            }
            else if (item.getSubQuery() != null)
            {
                FromItem[] sqItems = getTableFromItems(item.getSubQuery());
                for (int i = 0; i < sqItems.Length; i++)
                {
                    result.Add(sqItems[i]);
                }
            }
            else if (item.getJoin() != JoinType.None)
            {
                FromItem leftSide = item.getLeftSide();
                result.AddRange(getTableFromItems(leftSide));

                FromItem rightSide = item.getRightSide();
                result.AddRange(getTableFromItems(rightSide));
            }
            else
            {
                throw new InvalidOperationException("FromItem was neither of Table type, SubQuery type or Join type: " + item);
            }
            return(result);
        }     // getTableFromItems()
        private Column findColumnInAliasedTable(Column column, FromItem fromItem, String aliasPart, String columnPart)
        {
            if (column != null)
            {
                // ensure that if the column has already been found, return it
                return(column);
            }

            Table table = fromItem.getTable();

            if (table != null)
            {
                String alias = fromItem.getAlias();
                if (alias != null && alias.Equals(aliasPart))
                {
                    column = table.getColumnByName(columnPart);
                }
            }
            else
            {
                FromItem leftSide = fromItem.getLeftSide();
                column = findColumnInAliasedTable(column, leftSide, aliasPart, columnPart);
                FromItem rightSide = fromItem.getRightSide();
                column = findColumnInAliasedTable(column, rightSide, aliasPart, columnPart);
                if (column != null)
                {
                    Query subQuery = fromItem.getSubQuery();
                    if (subQuery != null)
                    {
                        List <FromItem> items = subQuery.getFromClause().getItems();
                        foreach (FromItem subQueryFromItem in items)
                        {
                            column = findColumnInAliasedTable(column, subQueryFromItem, aliasPart, columnPart);
                        }
                    }
                }
            }

            return(column);
        }
        } // executePrimaryKeyLookupQuery()

        protected DataSet materializeFromItem(FromItem fromItem, List <SelectItem> selectItems)
        {
            DataSet  dataSet;
            JoinType joinType = fromItem.getJoin();

            if (fromItem.getTable() != null)
            {
                // We need to materialize a single table
                Table             table = fromItem.getTable();
                List <SelectItem> selectItemsToMaterialize = new List <SelectItem>();

                foreach (SelectItem selectItem in selectItems)
                {
                    FromItem selectedFromItem = selectItem.getFromItem();
                    if (selectedFromItem != null)
                    {
                        if (selectedFromItem.equals(fromItem))
                        {
                            selectItemsToMaterialize.Add(selectItem.replaceFunction(null));
                        }
                    }
                    else
                    {
                        // the select item does not specify a specific
                        // from-item
                        Column selectedColumn = selectItem.getColumn();
                        if (selectedColumn != null)
                        {
                            // we assume that if the table matches, we will use the
                            // column
                            if (selectedColumn.getTable() != null && selectedColumn.getTable().Equals(table))
                            {
                                selectItemsToMaterialize.Add(selectItem.replaceFunction(null));
                            }
                        }
                    }
                }

                if (logger.isDebugEnabled())
                {
                    logger.debug("calling materializeTable(" + table.getName() + "," + selectItemsToMaterialize + ",1,-1");
                }

                // Dispatching to the concrete subclass of
                // QueryPostprocessDataContextStrategy
                dataSet = materializeTable(table, selectItemsToMaterialize, 1, -1);
            }
            else if (joinType != JoinType.None)
            {
                // We need to (recursively) materialize a joined FromItem
                if (fromItem.getLeftSide() == null || fromItem.getRightSide() == null)
                {
                    throw new ArgumentException("Joined FromItem requires both left and right side: " + fromItem);
                }
                DataSet[] fromItemDataSets = new DataSet[2];

                // materialize left side
                List <SelectItem> leftOn = NArrays.AsList(fromItem.getLeftOn());
                fromItemDataSets[0] = materializeFromItem(fromItem.getLeftSide(),
                                                          CollectionUtils.concat(true, selectItems, leftOn));

                // materialize right side
                List <SelectItem> rightOn = NArrays.AsList(fromItem.getRightOn());
                fromItemDataSets[1] = materializeFromItem(fromItem.getRightSide(),
                                                          CollectionUtils.concat(true, selectItems, rightOn));

                FilterItem[] onConditions = new FilterItem[leftOn.Count];
                for (int i = 0; i < onConditions.Length; i++)
                {
                    FilterItem whereItem = new FilterItem(leftOn[i], OperatorType.EQUALS_TO, rightOn[i]);
                    onConditions[i] = whereItem;
                }

                switch (joinType)
                {
                case JoinType.INNER:
                    dataSet = MetaModelHelper.getCarthesianProduct(fromItemDataSets, onConditions);
                    break;

                case JoinType.LEFT:
                    dataSet = MetaModelHelper.getLeftJoin(fromItemDataSets[0], fromItemDataSets[1], onConditions);
                    break;

                case JoinType.RIGHT:
                    dataSet = MetaModelHelper.getRightJoin(fromItemDataSets[0], fromItemDataSets[1], onConditions);
                    break;

                default:
                    throw new ArgumentException("FromItem type not supported: " + fromItem);
                }
            }
            else if (fromItem.getSubQuery() != null)
            {
                // We need to (recursively) materialize a subquery
                dataSet = executeQuery(fromItem.getSubQuery());
            }
            else
            {
                throw new ArgumentException("FromItem type not supported: " + fromItem);
            }
            if (dataSet == null)
            {
                throw new ArgumentException("FromItem was not succesfully materialized: " + fromItem);
            }
            return(dataSet);
        } // materializeFromItem()