CATCH_NEXTROW()
 {
     ActivityTimer t(totalCycles, timeActivities);
     if (abortSoon || eof)
         return NULL;
     RtlDynamicRowBuilder out(queryRowAllocator());
     size32_t sz = helper->clearAggregate(out);
     OwnedConstThorRow row = input->nextRow();
     if (row)
     {
         sz = helper->processFirst(out, row);
         // NB: if ungrouped existsAggregate, no need to look at rest of input
         if (!ungroupedExistsAggregate)
         {
             while (!abortSoon)
             {
                 row.setown(input->nextRow());
                 if (!row)
                     break;
                 sz = helper->processNext(out, row);
             }
         }
         if (!input->isGrouped())
             eof = true;
     }
     else
     {
         eof = true;
         if (input->isGrouped())
             return NULL;
     }
     dataLinkIncrement();
     return out.finalizeRowClear(sz);
 }
 void start()
 {
     ActivityTimer s(totalCycles, timeActivities);
     eof = false;
     input=inputs.item(0);
     startInput(input);
     ungroupedExistsAggregate = (container.getKind() == TAKexistsaggregate) && !input->isGrouped();
     dataLinkStart();
 }
 void doStart()
 {
     hadElement = false;
     inputStopped = false;
     input = inputs.item(0);
     startInput(input);
     if (input->isGrouped())
         ActPrintLog("Grouped mismatch");
 }