gt:             for (final FieldNode group : this.groups) {
context: /*
   * Copyright (C) 2009 Leonardo Alves da Costa
   *
   * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public
   * License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any
   * later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
   * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
   * License for more details. You should have received a copy of the GNU General Public License along with this
   * program. If not, see <http://www.gnu.org/licenses/>.
   */
  package com.googlecode.paradox.parser.nodes;
  
  import com.googlecode.paradox.parser.ScannerPosition;
  import com.googlecode.paradox.planner.nodes.FieldNode;
  import com.googlecode.paradox.planner.sorting.OrderType;
  
  import java.util.ArrayList;
  import java.util.List;
  
  /**
   * Stores a select node.
   *
   * @version 1.4
   * @since 1.0
   */
  public final class SelectNode extends StatementNode {
  
      /**
       * The field list (SELECT).
       */
      private final List<SQLNode> fields = new ArrayList<>();
      /**
       * Group by values.
       */
      private final List<FieldNode> groups = new ArrayList<>();
      /**
       * Order by values.
       */
      private final List<FieldNode> order = new ArrayList<>();
      /**
       * Order type.
       */
      private final List<OrderType> orderTypes = new ArrayList<>();
      /**
       * The tables in from token.
       */
      private final List<TableNode> tables = new ArrayList<>();
      /**
       * The conditions list.
       */
      private AbstractConditionalNode condition;
      /**
       * If has a distinct token.
       */
      private boolean distinct;
      /**
       * Result set limit.
       */
      private Integer limit;
      /**
       * Result set offset.
       */
      private Integer offset;
  
      /**
       * Create a new instance.
       *
       * @param position the current Scanner position.
       */
      public SelectNode(final ScannerPosition position) {
          super("SELECT", position);
      }
  
      /**
       * Adds the field in the list.
       *
       * @param field the field to add.
       */
      public void addField(final SQLNode field) {
          this.fields.add(field);
      }
  
      /**
       * Adds the table in list.
       *
       * @param table the table to add
       */
      public void addTable(final TableNode table) {
          this.tables.add(table);
      }
  
      /**
       * Gets the condition list.
       *
       * @return the condition list.
       */
      public AbstractConditionalNode getCondition() {
          return this.condition;
      }
  
      /**
       * Sets the condition tree.
       *
       * @param condition the condition tree.
       */
      public void setCondition(final AbstractConditionalNode condition) {
          this.condition = condition;
      }
  
      /**
       * Gets the order by list.
       *
       * @return the order by list.
       */
      public List<FieldNode> getOrder() {
          return this.order;
      }
  
      /**
       * Gets the field list.
       *
       * @return the field list.
       */
      public List<SQLNode> getFields() {
          return this.fields;
      }
  
      /**
       * Gets the table list.
       *
       * @return the table list.
       */
      public List<TableNode> getTables() {
          return this.tables;
      }
  
      /**
       * Show this node SELECT.
       */
      @Override
      public String toString() {
          final StringBuilder builder = new StringBuilder();
          builder.append(this.getName());
          builder.append(' ');
  
          this.buildFields(builder);
          this.buildFrom(builder);
          this.buildWhere(builder);
          this.buildGroupBy(builder);
          this.buildOrderBy(builder);
          return builder.toString();
      }
  
      /**
       * Build the fields description.
       *
       * @param builder builder to append fields.
       */
      private void buildFields(final StringBuilder builder) {
          boolean first = true;
          for (final SQLNode field : this.fields) {
              if (first) {
                  first = false;
              } else {
                  builder.append(", ");
              }
              builder.append(field);
          }
      }
  
      /**
       * Build the FROM description.
       *
       * @param builder builder to append FROM tables.
       */
      private void buildFrom(final StringBuilder builder) {
          boolean first;
          if (!this.tables.isEmpty()) {
              builder.append(" FROM ");
              first = true;
              for (final TableNode table : this.tables) {
                  if (first) {
                      first = false;
                  } else {
                      builder.append(", ");
                  }
                  builder.append(table);
              }
          }
      }
  
      /**
       * Build the grouping fields.
       *
       * @param builder builder to GROUP BY fields.
       */
      private void buildGroupBy(final StringBuilder builder) {
          boolean first;
          if (!this.groups.isEmpty()) {
              builder.append(" GROUP BY ");
              first = true;
  