gt:                 lastIterableEvent = results.getFirst()[0];
context: /**************************************************************************************
   * Copyright (C) 2008 EsperTech, Inc. All rights reserved.                            *
   * http://esper.codehaus.org                                                          *
   * http://www.espertech.com                                                           *
   * ---------------------------------------------------------------------------------- *
   * The software in this package is published under the terms of the GPL license       *
   * a copy of which has been included with this distribution in the license.txt file.  *
   **************************************************************************************/
  package com.espertech.esper.core;
  
  import com.espertech.esper.client.EventBean;
  import com.espertech.esper.client.StatementAwareUpdateListener;
  import com.espertech.esper.client.UpdateListener;
  import com.espertech.esper.collection.MultiKeyUntyped;
  import com.espertech.esper.collection.UniformPair;
  import com.espertech.esper.core.thread.OutboundUnitRunnable;
  import com.espertech.esper.core.thread.ThreadingOption;
  import com.espertech.esper.core.thread.ThreadingService;
  import com.espertech.esper.epl.expression.ExprEvaluator;
  import com.espertech.esper.epl.expression.ExprEvaluatorContext;
  import com.espertech.esper.epl.metric.MetricReportingPath;
  import com.espertech.esper.epl.metric.MetricReportingService;
  import com.espertech.esper.epl.metric.MetricReportingServiceSPI;
  import com.espertech.esper.epl.metric.StatementMetricHandle;
  import com.espertech.esper.event.EventBeanUtility;
  import com.espertech.esper.event.NaturalEventBean;
  import com.espertech.esper.util.AuditPath;
  import com.espertech.esper.util.ExecutionPathDebugLog;
  import com.espertech.esper.view.ViewSupport;
  import org.apache.commons.logging.Log;
  import org.apache.commons.logging.LogFactory;
  
  import java.util.*;
  
  /**
   * Implements tracking of statement listeners and subscribers for a given statement
   * such as to efficiently dispatch in situations where 0, 1 or more listeners
   * are attached and/or 0 or 1 subscriber (such as iteration-only statement).
   */
  public class StatementResultServiceImpl implements StatementResultService
  {
      private static Log log = LogFactory.getLog(StatementResultServiceImpl.class);
  
      private final String statementName;
      private final StatementLifecycleSvc statementLifecycleSvc;
      private final MetricReportingService metricReportingService;
      private final ThreadingService threadingService;
  
      // Part of the statement context
      private EPStatementSPI epStatement;
      private EPServiceProviderSPI epServiceProvider;
      private boolean isInsertInto;
      private boolean isPattern;
      private boolean isDistinct;
      private boolean isForClause;
      private StatementMetricHandle statementMetricHandle;
  
      private boolean forClauseDelivery= false;
      private ExprEvaluator[] groupDeliveryExpressions;
      private ExprEvaluatorContext exprEvaluatorContext;
  
      // For natural delivery derived out of select-clause expressions
      private Class[] selectClauseTypes;
      private String[] selectClauseColumnNames;
  
      // Listeners and subscribers and derived information
      private EPStatementListenerSet statementListenerSet;
      private boolean isMakeNatural;
      private boolean isMakeSynthetic;
      private ResultDeliveryStrategy statementResultNaturalStrategy;
  
      // For iteration over patterns
      private EventBean lastIterableEvent;
  
      private Set<StatementResultListener> statementOutputHooks;
  
      /**
       * Buffer for holding dispatchable events.
       */
      protected ThreadLocal<ArrayDeque<UniformPair<EventBean[]>>> lastResults = new ThreadLocal<ArrayDeque<UniformPair<EventBean[]>>>() {
          protected synchronized ArrayDeque<UniformPair<EventBean[]>> initialValue() {
              return new ArrayDeque<UniformPair<EventBean[]>>();
          }
      };
  
      /**
       * Ctor.
       * @param statementLifecycleSvc handles persistence for statements
       * @param metricReportingService for metrics reporting
       * @param threadingService for outbound threading
       */
      public StatementResultServiceImpl(String statementName,
                                        StatementLifecycleSvc statementLifecycleSvc,
                                        MetricReportingServiceSPI metricReportingService,
                                        ThreadingService threadingService)
      {
          log.debug(".ctor");
          this.statementName = statementName;
          this.statementLifecycleSvc = statementLifecycleSvc;
          this.metricReportingService = metricReportingService;
          if (metricReportingService != null) {
              this.statementOutputHooks = metricReportingService.getStatementOutputHooks();
          }
          else {
              this.statementOutputHooks = Collections.EMPTY_SET;
          }
          this.threadingService = threadingService;
      }
  
      public void setContext(EPStatementSPI epStatement, EPServiceProviderSPI epServiceProvider,
                             boolean isInsertInto,
                             boolean isPattern,
                             boolean isDistinct,
                             boolean isForClause,
                             StatementMetricHandle statementMetricHandle)
      {
          this.epStatement = epStatement;
          this.epServiceProvider = epServiceProvider;
          this.isInsertInto = isInsertInto;
          this.isPattern = isPattern;
          this.isDistinct = isDistinct;
          this.isForClause = isForClause;
          isMakeSynthetic = isInsertInto || isPattern || isDistinct || isForClause;
          this.statementMetricHandle = statementMetricHandle;
      }
  
      public void setSelectClause(Class[] selectClauseTypes, String[] selectClauseColumnNames,
                                  boolean forClauseDelivery, ExprEvaluator[] groupDeliveryExpressions, ExprEvaluatorContext exprEvaluatorContext)
      {
          if ((selectClauseTypes == null) || (selectClauseTypes.length == 0))
          {
              throw new IllegalArgumentException("Invalid null or zero-element list of select clause expression types");
          }
          if ((selectClauseColumnNames == null) || (selectClauseColumnNames.length == 0))
          {
              throw new IllegalArgumentException("Invalid null or zero-element list of select clause column names");
          }
          this.selectClauseTypes = selectClauseTypes;
          this.selectClauseColumnNames = selectClauseColumnNames;
          this.forClauseDelivery = forClauseDelivery;
          this.exprEvaluatorContext = exprEvaluatorContext;
          this.groupDeliveryExpressions = groupDeliveryExpressions;
      }
  
      public boolean isMakeSynthetic()
      {
          return isMakeSynthetic;
      }
  
      public boolean isMakeNatural()
      {
          return isMakeNatural;
      }
  
      public EventBean getLastIterableEvent()
      {
          return lastIterableEvent;
      }
  
      public void setUpdateListeners(EPStatementListenerSet statementListenerSet)
      {
          // indicate that listeners were updated for potential persistence of listener set, once the statement context is known
          if (epStatement != null)
          {
              this.statementLifecycleSvc.updatedListeners(epStatement, statementListenerSet);
          }
  
          this.statementListenerSet = statementListenerSet;
  
          isMakeNatural = statementListenerSet.getSubscriber() != null;
          isMakeSynthetic = !(statementListenerSet.getListeners().isEmpty() && statementListenerSet.getStmtAwareListeners().isEmpty())
                  || isPattern || isInsertInto || isDistinct | isForClause;
  
          if (statementListenerSet.getSubscriber() == null)
          {
              statementResultNaturalStrategy = null;
              isMakeNatural = false;
              return;
          }
  
          statementResultNaturalStrategy = ResultDeliveryStrategyFactory.create(statementName, statementListenerSet.getSubscriber(),
                  selectClauseTypes, selectClauseColumnNames);
          isMakeNatural = true;
      }
  
      // Called by OutputProcessView
      public void indicate(UniformPair<EventBean[]> results)
      {
          if (results != null)
          {
              if ((MetricReportingPath.isMetricsEnabled) && (statementMetricHandle.isEnabled()))
              {
                  int numIStream = (results.getFirst() != null) ? results.getFirst().length : 0;
                  int numRStream = (results.getSecond() != null) ? results.getSecond().length : 0;
                  this.metricReportingService.accountOutput(statementMetricHandle, numIStream, numRStream);
              }
  
              if ((results.getFirst() != null) && (results.getFirst().length != 0))
              {
                  lastResults.get().add(results);
  