protected void closure_(ATNConfig config,
							ATNConfigSet configs,
							Set<ATNConfig> closureBusy,
							boolean collectPredicates,
							boolean fullCtx,
							int depth,
							boolean treatEofAsEpsilon)
	{
		ATNState p = config.state;
		// optimization
		if ( !p.onlyHasEpsilonTransitions() ) {
            configs.add(config, mergeCache);
			// make sure to not return here, because EOF transitions can act as
			// both epsilon transitions and non-epsilon transitions.
//            if ( debug ) System.out.println("added config "+configs);
        }

		for (int i=0; i<p.getNumberOfTransitions(); i++) {
			if ( i==0 && canDropLoopEntryEdgeInLeftRecursiveRule(config) ) continue;

			Transition t = p.transition(i);
			boolean continueCollecting =
				!(t instanceof ActionTransition) && collectPredicates;
			ATNConfig c = getEpsilonTarget(config, t, continueCollecting,
										   depth == 0, fullCtx, treatEofAsEpsilon);
			if ( c!=null ) {
				int newDepth = depth;
				if ( config.state instanceof RuleStopState) {
					assert !fullCtx;
					// target fell off end of rule; mark resulting c as having dipped into outer context
					// We can't get here if incoming config was rule stop and we had context
					// track how far we dip into outer context.  Might
					// come in handy and we avoid evaluating context dependent
					// preds if this is > 0.

					if (_dfa != null && _dfa.isPrecedenceDfa()) {
						int outermostPrecedenceReturn = ((EpsilonTransition)t).outermostPrecedenceReturn();
						if (outermostPrecedenceReturn == _dfa.atnStartState.ruleIndex) {
							c.setPrecedenceFilterSuppressed(true);
						}
					}

					c.reachesIntoOuterContext++;

					if (!closureBusy.add(c)) {
						// avoid infinite recursion for right-recursive rules
						continue;
					}

					configs.dipsIntoOuterContext = true; // TODO: can remove? only care when we add to set per middle of this method
					assert newDepth > Integer.MIN_VALUE;
					newDepth--;
					if ( debug ) System.out.println("dips into outer ctx: "+c);
				}
				else {
					if (!t.isEpsilon() && !closureBusy.add(c)) {
						// avoid infinite recursion for EOF* and EOF+
						continue;
					}

					if (t instanceof RuleTransition) {
						// latch when newDepth goes negative - once we step out of the entry context we can't return
						if (newDepth >= 0) {
							newDepth++;
						}
					}
				}

				closureCheckingStopState(c, configs, closureBusy, continueCollecting,
										 fullCtx, newDepth, treatEofAsEpsilon);
			}
		}
	}
Do the actual work of walking epsilon edges
runtime/Java/src/org/antlr/v4/runtime/atn/ParserATNSimulator.java