parent != Language.treebank.baseNPLabel() && mods.hasNext();
!Language.treebank.isBaseNP(parent) && mods.hasNext();
  protected void collectModifierStats(HeadTreeNode tree,				      Subcat subcat,				      int gapIdx,				      boolean side) {    Symbol parent = tree.label();    Symbol head = tree.headChild().label();    Word headWord = tree.headWord();    Iterator mods = (side == Constants.LEFT ?		     tree.preMods().iterator() : tree.postMods().iterator());    ModifierEvent prevModEvent = null;    SexpList prevModList = newStartList(numPrevMods);    Sexp prevMod = prevModList.first();    WordList prevWordList = newStartWordList(numPrevWords);    Word prevWord = prevWordList.getWord(0);    Subcat dynamicSubcat = (Subcat)subcat.copy();    // if there's a gap to generate, add as requirement to end of subcat list    if (gapIdx != -1)      dynamicSubcat.add(gapAugmentation);    boolean verbIntervening = false;    // collect modifier generation events    boolean prevModHadVerb = false;    // the next two booleans only necessary for (currently) unused method of    // determining modifier adjacency, which is that no *words* appear between    // head and currently-generated left- or right-edge frontier word of    // currently-generated modifier subtree    boolean wordsIntervening = false;    boolean headAlreadyHasMods =      (side == Constants.LEFT ?       tree.headChild().leftIdx() < tree.headWordIdx() :       tree.headChild().rightIdx() > tree.headWordIdx() + 1);    Symbol prevRealModifier = null;    Word prevPunc = null, prevConj = null;    for (int modIdx = 0; mods.hasNext(); modIdx++) {      HeadTreeNode currMod = (HeadTreeNode)mods.next();      Symbol modifier = currMod.label();      Shifter.shift(prevModEvent, prevModList, prevMod, modifier);      Shifter.shift(prevModEvent, prevWordList, prevWord, currMod.headWord());      boolean isConj = Language.treebank.isConjunction(modifier);      boolean isConjPConj =	isConj && side == Constants.RIGHT &&	parent != Language.treebank.baseNPLabel() && mods.hasNext();      if (isConjPConj && prevConj != null)	System.err.println(className +			   ": warning: more than one conjunction in a row: " +			   tree.toSexp());      boolean headAdjacent = prevRealModifier == null;      verbIntervening |= prevModHadVerb;      wordsIntervening = (modIdx > 0 ? true : headAlreadyHasMods);      Subcat canonicalDynamicSubcat =	dynamicSubcat.getCanonical(false, canonicalSubcatMap);      ModifierEvent modEvent = new ModifierEvent(currMod.headWord(),						 headWord,						 modifier,						 new SexpList(prevModList),						 prevWordList.copy(),						 parent,						 head,						 canonicalDynamicSubcat,						 prevPunc,						 prevConj,						 isConjPConj,						 verbIntervening,						 headAdjacent,						 side);      addModifierEvent(modEvent);      if (outputCollins)	outputCollins(modEvent);      if (modIdx == gapIdx) {	Symbol direction = (side == Constants.LEFT ?			    GapEvent.toLeft : GapEvent.toRight);	GapEvent gapEvent = new GapEvent(direction, headWord, parent, head);	addGapEvent(gapEvent);	if (dynamicSubcat.size() == 0)	  System.err.println(className + ": error: gap detected in " +			     tree + " but subcat list is empty!");	if (dynamicSubcat.contains(gapAugmentation)) {	  dynamicSubcat = (Subcat)dynamicSubcat.copy();	  dynamicSubcat.remove(gapAugmentation);	}	else {	  System.err.println(className + ": warning: gap detected in " +			     "modifier " + tree.label() + " but not present " +			     "in subcat list");	}      }      prevModEvent = modEvent;      if (dynamicSubcat.contains(modifier)) {	dynamicSubcat = (Subcat)dynamicSubcat.copy();	dynamicSubcat.remove(modifier);      }      prevModHadVerb = currMod.containsVerb();      prevWord = currMod.headWord();      prevMod = modifier;      if (Language.treebank.isPunctuation(modifier))	prevPunc = currMod.headWord();      else if (isConjPConj)	prevConj = currMod.headWord();      else {	prevRealModifier = modifier;	prevPunc = null;	prevConj = null;      }    }    if (!dynamicSubcat.empty())      System.err.println(className + ": warning: dynamic subcat not empty: " +			 dynamicSubcat);    Subcat emptySubcat = dynamicSubcat.getCanonical(false, canonicalSubcatMap);    // transition to stop symbol    verbIntervening |= prevModHadVerb;    // need to shift in final mod and modWord    Shifter.shift(prevModEvent, prevModList, prevMod, stopSym);    Shifter.shift(prevModEvent, prevWordList, prevWord, stopWord);    ModifierEvent modEvent = new ModifierEvent(stopWord,					       headWord,					       stopSym,					       prevModList,					       prevWordList,					       parent,					       head,					       emptySubcat,					       null,					       null,					       false,					       verbIntervening,					       prevRealModifier == null,					       side);    addModifierEvent(modEvent);    if (outputCollins)      outputCollins(modEvent);  }