org.apache.flink.cep.pattern.conditions.RichAndCondition Java Examples

The following examples show how to use org.apache.flink.cep.pattern.conditions.RichAndCondition. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: Pattern.java    From Flink-CEPplus with Apache License 2.0 5 votes vote down vote up
/**
 * Applies a subtype constraint on the current pattern. This means that an event has
 * to be of the given subtype in order to be matched.
 *
 * @param subtypeClass Class of the subtype
 * @param <S> Type of the subtype
 * @return The same pattern with the new subtype constraint
 */
public <S extends F> Pattern<T, S> subtype(final Class<S> subtypeClass) {
	Preconditions.checkNotNull(subtypeClass, "The class cannot be null.");

	if (condition == null) {
		this.condition = new SubtypeCondition<F>(subtypeClass);
	} else {
		this.condition = new RichAndCondition<>(condition, new SubtypeCondition<F>(subtypeClass));
	}

	@SuppressWarnings("unchecked")
	Pattern<T, S> result = (Pattern<T, S>) this;

	return result;
}
 
Example #2
Source File: PatternTest.java    From flink with Apache License 2.0 5 votes vote down vote up
@Test
public void testRichCondition() {
	Pattern<Event, Event> pattern =
		Pattern.<Event>begin("start")
			.where(mock(IterativeCondition.class))
			.where(mock(IterativeCondition.class))
		.followedBy("end")
			.where(mock(IterativeCondition.class))
			.or(mock(IterativeCondition.class));
	assertTrue(pattern.getCondition() instanceof RichOrCondition);
	assertTrue(pattern.getPrevious().getCondition() instanceof RichAndCondition);
}
 
Example #3
Source File: NFACompiler.java    From flink with Apache License 2.0 5 votes vote down vote up
private void updateWithGreedyCondition(
	State<T> state,
	IterativeCondition<T> takeCondition) {
	for (StateTransition<T> stateTransition : state.getStateTransitions()) {
		stateTransition.setCondition(
			new RichAndCondition<>(stateTransition.getCondition(), new RichNotCondition<>(takeCondition)));
	}
}
 
Example #4
Source File: NFACompiler.java    From flink with Apache License 2.0 5 votes vote down vote up
/**
 * This method extends the given condition with stop(until) condition if necessary.
 * The until condition needs to be applied only if both of the given conditions are not null.
 *
 * @param condition the condition to extend
 * @param untilCondition the until condition to join with the given condition
 * @param isTakeCondition whether the {@code condition} is for {@code TAKE} edge
 * @return condition with AND applied or the original condition
 */
private IterativeCondition<T> extendWithUntilCondition(
		IterativeCondition<T> condition,
		IterativeCondition<T> untilCondition,
		boolean isTakeCondition) {
	if (untilCondition != null && condition != null) {
		return new RichAndCondition<>(new RichNotCondition<>(untilCondition), condition);
	} else if (untilCondition != null && isTakeCondition) {
		return new RichNotCondition<>(untilCondition);
	}

	return condition;
}
 
Example #5
Source File: Pattern.java    From flink with Apache License 2.0 5 votes vote down vote up
/**
 * Applies a subtype constraint on the current pattern. This means that an event has
 * to be of the given subtype in order to be matched.
 *
 * @param subtypeClass Class of the subtype
 * @param <S> Type of the subtype
 * @return The same pattern with the new subtype constraint
 */
public <S extends F> Pattern<T, S> subtype(final Class<S> subtypeClass) {
	Preconditions.checkNotNull(subtypeClass, "The class cannot be null.");

	if (condition == null) {
		this.condition = new SubtypeCondition<F>(subtypeClass);
	} else {
		this.condition = new RichAndCondition<>(condition, new SubtypeCondition<F>(subtypeClass));
	}

	@SuppressWarnings("unchecked")
	Pattern<T, S> result = (Pattern<T, S>) this;

	return result;
}
 
Example #6
Source File: Pattern.java    From flink with Apache License 2.0 5 votes vote down vote up
/**
 * Adds a condition that has to be satisfied by an event
 * in order to be considered a match. If another condition has already been
 * set, the new one is going to be combined with the previous with a
 * logical {@code AND}. In other case, this is going to be the only
 * condition.
 *
 * @param condition The condition as an {@link IterativeCondition}.
 * @return The pattern with the new condition is set.
 */
public Pattern<T, F> where(IterativeCondition<F> condition) {
	Preconditions.checkNotNull(condition, "The condition cannot be null.");

	ClosureCleaner.clean(condition, ExecutionConfig.ClosureCleanerLevel.RECURSIVE, true);
	if (this.condition == null) {
		this.condition = condition;
	} else {
		this.condition = new RichAndCondition<>(this.condition, condition);
	}
	return this;
}
 
Example #7
Source File: PatternTest.java    From flink with Apache License 2.0 5 votes vote down vote up
@Test
public void testRichCondition() {
	Pattern<Event, Event> pattern =
		Pattern.<Event>begin("start")
			.where(mock(IterativeCondition.class))
			.where(mock(IterativeCondition.class))
		.followedBy("end")
			.where(mock(IterativeCondition.class))
			.or(mock(IterativeCondition.class));
	assertTrue(pattern.getCondition() instanceof RichOrCondition);
	assertTrue(pattern.getPrevious().getCondition() instanceof RichAndCondition);
}
 
Example #8
Source File: NFACompiler.java    From flink with Apache License 2.0 5 votes vote down vote up
private void updateWithGreedyCondition(
	State<T> state,
	IterativeCondition<T> takeCondition) {
	for (StateTransition<T> stateTransition : state.getStateTransitions()) {
		stateTransition.setCondition(
			new RichAndCondition<>(stateTransition.getCondition(), new RichNotCondition<>(takeCondition)));
	}
}
 
Example #9
Source File: NFACompiler.java    From flink with Apache License 2.0 5 votes vote down vote up
/**
 * This method extends the given condition with stop(until) condition if necessary.
 * The until condition needs to be applied only if both of the given conditions are not null.
 *
 * @param condition the condition to extend
 * @param untilCondition the until condition to join with the given condition
 * @param isTakeCondition whether the {@code condition} is for {@code TAKE} edge
 * @return condition with AND applied or the original condition
 */
private IterativeCondition<T> extendWithUntilCondition(
		IterativeCondition<T> condition,
		IterativeCondition<T> untilCondition,
		boolean isTakeCondition) {
	if (untilCondition != null && condition != null) {
		return new RichAndCondition<>(new RichNotCondition<>(untilCondition), condition);
	} else if (untilCondition != null && isTakeCondition) {
		return new RichNotCondition<>(untilCondition);
	}

	return condition;
}
 
Example #10
Source File: Pattern.java    From flink with Apache License 2.0 5 votes vote down vote up
/**
 * Applies a subtype constraint on the current pattern. This means that an event has
 * to be of the given subtype in order to be matched.
 *
 * @param subtypeClass Class of the subtype
 * @param <S> Type of the subtype
 * @return The same pattern with the new subtype constraint
 */
public <S extends F> Pattern<T, S> subtype(final Class<S> subtypeClass) {
	Preconditions.checkNotNull(subtypeClass, "The class cannot be null.");

	if (condition == null) {
		this.condition = new SubtypeCondition<F>(subtypeClass);
	} else {
		this.condition = new RichAndCondition<>(condition, new SubtypeCondition<F>(subtypeClass));
	}

	@SuppressWarnings("unchecked")
	Pattern<T, S> result = (Pattern<T, S>) this;

	return result;
}
 
Example #11
Source File: Pattern.java    From flink with Apache License 2.0 5 votes vote down vote up
/**
 * Adds a condition that has to be satisfied by an event
 * in order to be considered a match. If another condition has already been
 * set, the new one is going to be combined with the previous with a
 * logical {@code AND}. In other case, this is going to be the only
 * condition.
 *
 * @param condition The condition as an {@link IterativeCondition}.
 * @return The pattern with the new condition is set.
 */
public Pattern<T, F> where(IterativeCondition<F> condition) {
	Preconditions.checkNotNull(condition, "The condition cannot be null.");

	ClosureCleaner.clean(condition, ExecutionConfig.ClosureCleanerLevel.RECURSIVE, true);
	if (this.condition == null) {
		this.condition = condition;
	} else {
		this.condition = new RichAndCondition<>(this.condition, condition);
	}
	return this;
}
 
Example #12
Source File: PatternTest.java    From Flink-CEPplus with Apache License 2.0 5 votes vote down vote up
@Test
public void testRichCondition() {
	Pattern<Event, Event> pattern =
		Pattern.<Event>begin("start")
			.where(mock(IterativeCondition.class))
			.where(mock(IterativeCondition.class))
		.followedBy("end")
			.where(mock(IterativeCondition.class))
			.or(mock(IterativeCondition.class));
	assertTrue(pattern.getCondition() instanceof RichOrCondition);
	assertTrue(pattern.getPrevious().getCondition() instanceof RichAndCondition);
}
 
Example #13
Source File: NFACompiler.java    From Flink-CEPplus with Apache License 2.0 5 votes vote down vote up
private void updateWithGreedyCondition(
	State<T> state,
	IterativeCondition<T> takeCondition) {
	for (StateTransition<T> stateTransition : state.getStateTransitions()) {
		stateTransition.setCondition(
			new RichAndCondition<>(stateTransition.getCondition(), new RichNotCondition<>(takeCondition)));
	}
}
 
Example #14
Source File: NFACompiler.java    From Flink-CEPplus with Apache License 2.0 5 votes vote down vote up
/**
 * This method extends the given condition with stop(until) condition if necessary.
 * The until condition needs to be applied only if both of the given conditions are not null.
 *
 * @param condition the condition to extend
 * @param untilCondition the until condition to join with the given condition
 * @param isTakeCondition whether the {@code condition} is for {@code TAKE} edge
 * @return condition with AND applied or the original condition
 */
private IterativeCondition<T> extendWithUntilCondition(
		IterativeCondition<T> condition,
		IterativeCondition<T> untilCondition,
		boolean isTakeCondition) {
	if (untilCondition != null && condition != null) {
		return new RichAndCondition<>(new RichNotCondition<>(untilCondition), condition);
	} else if (untilCondition != null && isTakeCondition) {
		return new RichNotCondition<>(untilCondition);
	}

	return condition;
}
 
Example #15
Source File: Pattern.java    From Flink-CEPplus with Apache License 2.0 5 votes vote down vote up
/**
 * Adds a condition that has to be satisfied by an event
 * in order to be considered a match. If another condition has already been
 * set, the new one is going to be combined with the previous with a
 * logical {@code AND}. In other case, this is going to be the only
 * condition.
 *
 * @param condition The condition as an {@link IterativeCondition}.
 * @return The pattern with the new condition is set.
 */
public Pattern<T, F> where(IterativeCondition<F> condition) {
	Preconditions.checkNotNull(condition, "The condition cannot be null.");

	ClosureCleaner.clean(condition, ExecutionConfig.ClosureCleanerLevel.RECURSIVE, true);
	if (this.condition == null) {
		this.condition = condition;
	} else {
		this.condition = new RichAndCondition<>(this.condition, condition);
	}
	return this;
}
 
Example #16
Source File: NFACompiler.java    From flink with Apache License 2.0 4 votes vote down vote up
/**
 * Creates a simple single state. For an OPTIONAL state it also consists
 * of a similar state without the PROCEED edge, so that for each PROCEED transition branches
 * in computation state graph  can be created only once.
 *
 * @param ignoreCondition condition that should be applied to IGNORE transition
 * @param sinkState state that the state being converted should point to
 * @param proceedState state that the state being converted should proceed to
 * @param isOptional whether the state being converted is optional
 * @return the created state
 */
@SuppressWarnings("unchecked")
private State<T> createSingletonState(final State<T> sinkState,
	final State<T> proceedState,
	final IterativeCondition<T> takeCondition,
	final IterativeCondition<T> ignoreCondition,
	final boolean isOptional) {
	if (currentPattern instanceof GroupPattern) {
		return createGroupPatternState((GroupPattern) currentPattern, sinkState, proceedState, isOptional);
	}

	final State<T> singletonState = createState(currentPattern.getName(), State.StateType.Normal);
	// if event is accepted then all notPatterns previous to the optional states are no longer valid
	final State<T> sink = copyWithoutTransitiveNots(sinkState);
	singletonState.addTake(sink, takeCondition);

	// if no element accepted the previous nots are still valid.
	final IterativeCondition<T> proceedCondition = getTrueFunction();

	// for the first state of a group pattern, its PROCEED edge should point to the following state of
	// that group pattern and the edge will be added at the end of creating the NFA for that group pattern
	if (isOptional && !headOfGroup(currentPattern)) {
		if (currentPattern.getQuantifier().hasProperty(Quantifier.QuantifierProperty.GREEDY)) {
			final IterativeCondition<T> untilCondition =
				(IterativeCondition<T>) currentPattern.getUntilCondition();
			if (untilCondition != null) {
				singletonState.addProceed(
					originalStateMap.get(proceedState.getName()),
					new RichAndCondition<>(proceedCondition, untilCondition));
			}
			singletonState.addProceed(proceedState,
				untilCondition != null
					? new RichAndCondition<>(proceedCondition, new RichNotCondition<>(untilCondition))
					: proceedCondition);
		} else {
			singletonState.addProceed(proceedState, proceedCondition);
		}
	}

	if (ignoreCondition != null) {
		final State<T> ignoreState;
		if (isOptional) {
			ignoreState = createState(currentPattern.getName(), State.StateType.Normal);
			ignoreState.addTake(sink, takeCondition);
			ignoreState.addIgnore(ignoreCondition);
			addStopStates(ignoreState);
		} else {
			ignoreState = singletonState;
		}
		singletonState.addIgnore(ignoreState, ignoreCondition);
	}
	return singletonState;
}
 
Example #17
Source File: NFACompiler.java    From flink with Apache License 2.0 4 votes vote down vote up
/**
 * Creates the given state as a looping one. Looping state is one with TAKE edge to itself and
 * PROCEED edge to the sinkState. It also consists of a similar state without the PROCEED edge, so that
 * for each PROCEED transition branches in computation state graph  can be created only once.
 *
 * @param sinkState the state that the converted state should point to
 * @return the first state of the created complex state
 */
@SuppressWarnings("unchecked")
private State<T> createLooping(final State<T> sinkState) {
	if (currentPattern instanceof GroupPattern) {
		return createLoopingGroupPatternState((GroupPattern) currentPattern, sinkState);
	}
	final IterativeCondition<T> untilCondition = (IterativeCondition<T>) currentPattern.getUntilCondition();

	final IterativeCondition<T> ignoreCondition = extendWithUntilCondition(
		getInnerIgnoreCondition(currentPattern),
		untilCondition,
		false);
	final IterativeCondition<T> takeCondition = extendWithUntilCondition(
		getTakeCondition(currentPattern),
		untilCondition,
		true);

	IterativeCondition<T> proceedCondition = getTrueFunction();
	final State<T> loopingState = createState(currentPattern.getName(), State.StateType.Normal);

	if (currentPattern.getQuantifier().hasProperty(Quantifier.QuantifierProperty.GREEDY)) {
		if (untilCondition != null) {
			State<T> sinkStateCopy = copy(sinkState);
			loopingState.addProceed(sinkStateCopy, new RichAndCondition<>(proceedCondition, untilCondition));
			originalStateMap.put(sinkState.getName(), sinkStateCopy);
		}
		loopingState.addProceed(sinkState,
			untilCondition != null
				? new RichAndCondition<>(proceedCondition, new RichNotCondition<>(untilCondition))
				: proceedCondition);
		updateWithGreedyCondition(sinkState, getTakeCondition(currentPattern));
	} else {
		loopingState.addProceed(sinkState, proceedCondition);
	}
	loopingState.addTake(takeCondition);

	addStopStateToLooping(loopingState);

	if (ignoreCondition != null) {
		final State<T> ignoreState = createState(currentPattern.getName(), State.StateType.Normal);
		ignoreState.addTake(loopingState, takeCondition);
		ignoreState.addIgnore(ignoreCondition);
		loopingState.addIgnore(ignoreState, ignoreCondition);

		addStopStateToLooping(ignoreState);
	}
	return loopingState;
}
 
Example #18
Source File: NFACompiler.java    From flink with Apache License 2.0 4 votes vote down vote up
/**
 * Creates a simple single state. For an OPTIONAL state it also consists
 * of a similar state without the PROCEED edge, so that for each PROCEED transition branches
 * in computation state graph  can be created only once.
 *
 * @param ignoreCondition condition that should be applied to IGNORE transition
 * @param sinkState state that the state being converted should point to
 * @param proceedState state that the state being converted should proceed to
 * @param isOptional whether the state being converted is optional
 * @return the created state
 */
@SuppressWarnings("unchecked")
private State<T> createSingletonState(final State<T> sinkState,
	final State<T> proceedState,
	final IterativeCondition<T> takeCondition,
	final IterativeCondition<T> ignoreCondition,
	final boolean isOptional) {
	if (currentPattern instanceof GroupPattern) {
		return createGroupPatternState((GroupPattern) currentPattern, sinkState, proceedState, isOptional);
	}

	final State<T> singletonState = createState(currentPattern.getName(), State.StateType.Normal);
	// if event is accepted then all notPatterns previous to the optional states are no longer valid
	final State<T> sink = copyWithoutTransitiveNots(sinkState);
	singletonState.addTake(sink, takeCondition);

	// if no element accepted the previous nots are still valid.
	final IterativeCondition<T> proceedCondition = getTrueFunction();

	// for the first state of a group pattern, its PROCEED edge should point to the following state of
	// that group pattern and the edge will be added at the end of creating the NFA for that group pattern
	if (isOptional && !headOfGroup(currentPattern)) {
		if (currentPattern.getQuantifier().hasProperty(Quantifier.QuantifierProperty.GREEDY)) {
			final IterativeCondition<T> untilCondition =
				(IterativeCondition<T>) currentPattern.getUntilCondition();
			if (untilCondition != null) {
				singletonState.addProceed(
					originalStateMap.get(proceedState.getName()),
					new RichAndCondition<>(proceedCondition, untilCondition));
			}
			singletonState.addProceed(proceedState,
				untilCondition != null
					? new RichAndCondition<>(proceedCondition, new RichNotCondition<>(untilCondition))
					: proceedCondition);
		} else {
			singletonState.addProceed(proceedState, proceedCondition);
		}
	}

	if (ignoreCondition != null) {
		final State<T> ignoreState;
		if (isOptional) {
			ignoreState = createState(currentPattern.getName(), State.StateType.Normal);
			ignoreState.addTake(sink, takeCondition);
			ignoreState.addIgnore(ignoreCondition);
			addStopStates(ignoreState);
		} else {
			ignoreState = singletonState;
		}
		singletonState.addIgnore(ignoreState, ignoreCondition);
	}
	return singletonState;
}
 
Example #19
Source File: NFACompiler.java    From flink with Apache License 2.0 4 votes vote down vote up
/**
 * Creates the given state as a looping one. Looping state is one with TAKE edge to itself and
 * PROCEED edge to the sinkState. It also consists of a similar state without the PROCEED edge, so that
 * for each PROCEED transition branches in computation state graph  can be created only once.
 *
 * @param sinkState the state that the converted state should point to
 * @return the first state of the created complex state
 */
@SuppressWarnings("unchecked")
private State<T> createLooping(final State<T> sinkState) {
	if (currentPattern instanceof GroupPattern) {
		return createLoopingGroupPatternState((GroupPattern) currentPattern, sinkState);
	}
	final IterativeCondition<T> untilCondition = (IterativeCondition<T>) currentPattern.getUntilCondition();

	final IterativeCondition<T> ignoreCondition = extendWithUntilCondition(
		getInnerIgnoreCondition(currentPattern),
		untilCondition,
		false);
	final IterativeCondition<T> takeCondition = extendWithUntilCondition(
		getTakeCondition(currentPattern),
		untilCondition,
		true);

	IterativeCondition<T> proceedCondition = getTrueFunction();
	final State<T> loopingState = createState(currentPattern.getName(), State.StateType.Normal);

	if (currentPattern.getQuantifier().hasProperty(Quantifier.QuantifierProperty.GREEDY)) {
		if (untilCondition != null) {
			State<T> sinkStateCopy = copy(sinkState);
			loopingState.addProceed(sinkStateCopy, new RichAndCondition<>(proceedCondition, untilCondition));
			originalStateMap.put(sinkState.getName(), sinkStateCopy);
		}
		loopingState.addProceed(sinkState,
			untilCondition != null
				? new RichAndCondition<>(proceedCondition, new RichNotCondition<>(untilCondition))
				: proceedCondition);
		updateWithGreedyCondition(sinkState, getTakeCondition(currentPattern));
	} else {
		loopingState.addProceed(sinkState, proceedCondition);
	}
	loopingState.addTake(takeCondition);

	addStopStateToLooping(loopingState);

	if (ignoreCondition != null) {
		final State<T> ignoreState = createState(currentPattern.getName(), State.StateType.Normal);
		ignoreState.addTake(loopingState, takeCondition);
		ignoreState.addIgnore(ignoreCondition);
		loopingState.addIgnore(ignoreState, ignoreCondition);

		addStopStateToLooping(ignoreState);
	}
	return loopingState;
}
 
Example #20
Source File: NFACompiler.java    From Flink-CEPplus with Apache License 2.0 4 votes vote down vote up
/**
 * Creates the given state as a looping one. Looping state is one with TAKE edge to itself and
 * PROCEED edge to the sinkState. It also consists of a similar state without the PROCEED edge, so that
 * for each PROCEED transition branches in computation state graph  can be created only once.
 *
 * @param sinkState the state that the converted state should point to
 * @return the first state of the created complex state
 */
@SuppressWarnings("unchecked")
private State<T> createLooping(final State<T> sinkState) {
	if (currentPattern instanceof GroupPattern) {
		return createLoopingGroupPatternState((GroupPattern) currentPattern, sinkState);
	}
	final IterativeCondition<T> untilCondition = (IterativeCondition<T>) currentPattern.getUntilCondition();

	final IterativeCondition<T> ignoreCondition = extendWithUntilCondition(
		getInnerIgnoreCondition(currentPattern),
		untilCondition,
		false);
	final IterativeCondition<T> takeCondition = extendWithUntilCondition(
		getTakeCondition(currentPattern),
		untilCondition,
		true);

	IterativeCondition<T> proceedCondition = getTrueFunction();
	final State<T> loopingState = createState(currentPattern.getName(), State.StateType.Normal);

	if (currentPattern.getQuantifier().hasProperty(Quantifier.QuantifierProperty.GREEDY)) {
		if (untilCondition != null) {
			State<T> sinkStateCopy = copy(sinkState);
			loopingState.addProceed(sinkStateCopy, new RichAndCondition<>(proceedCondition, untilCondition));
			originalStateMap.put(sinkState.getName(), sinkStateCopy);
		}
		loopingState.addProceed(sinkState,
			untilCondition != null
				? new RichAndCondition<>(proceedCondition, new RichNotCondition<>(untilCondition))
				: proceedCondition);
		updateWithGreedyCondition(sinkState, getTakeCondition(currentPattern));
	} else {
		loopingState.addProceed(sinkState, proceedCondition);
	}
	loopingState.addTake(takeCondition);

	addStopStateToLooping(loopingState);

	if (ignoreCondition != null) {
		final State<T> ignoreState = createState(currentPattern.getName(), State.StateType.Normal);
		ignoreState.addTake(loopingState, takeCondition);
		ignoreState.addIgnore(ignoreCondition);
		loopingState.addIgnore(ignoreState, ignoreCondition);

		addStopStateToLooping(ignoreState);
	}
	return loopingState;
}
 
Example #21
Source File: NFACompiler.java    From Flink-CEPplus with Apache License 2.0 4 votes vote down vote up
/**
 * Creates a simple single state. For an OPTIONAL state it also consists
 * of a similar state without the PROCEED edge, so that for each PROCEED transition branches
 * in computation state graph  can be created only once.
 *
 * @param ignoreCondition condition that should be applied to IGNORE transition
 * @param sinkState state that the state being converted should point to
 * @param proceedState state that the state being converted should proceed to
 * @param isOptional whether the state being converted is optional
 * @return the created state
 */
@SuppressWarnings("unchecked")
private State<T> createSingletonState(final State<T> sinkState,
	final State<T> proceedState,
	final IterativeCondition<T> takeCondition,
	final IterativeCondition<T> ignoreCondition,
	final boolean isOptional) {
	if (currentPattern instanceof GroupPattern) {
		return createGroupPatternState((GroupPattern) currentPattern, sinkState, proceedState, isOptional);
	}

	final State<T> singletonState = createState(currentPattern.getName(), State.StateType.Normal);
	// if event is accepted then all notPatterns previous to the optional states are no longer valid
	final State<T> sink = copyWithoutTransitiveNots(sinkState);
	singletonState.addTake(sink, takeCondition);

	// if no element accepted the previous nots are still valid.
	final IterativeCondition<T> proceedCondition = getTrueFunction();

	// for the first state of a group pattern, its PROCEED edge should point to the following state of
	// that group pattern and the edge will be added at the end of creating the NFA for that group pattern
	if (isOptional && !headOfGroup(currentPattern)) {
		if (currentPattern.getQuantifier().hasProperty(Quantifier.QuantifierProperty.GREEDY)) {
			final IterativeCondition<T> untilCondition =
				(IterativeCondition<T>) currentPattern.getUntilCondition();
			if (untilCondition != null) {
				singletonState.addProceed(
					originalStateMap.get(proceedState.getName()),
					new RichAndCondition<>(proceedCondition, untilCondition));
			}
			singletonState.addProceed(proceedState,
				untilCondition != null
					? new RichAndCondition<>(proceedCondition, new RichNotCondition<>(untilCondition))
					: proceedCondition);
		} else {
			singletonState.addProceed(proceedState, proceedCondition);
		}
	}

	if (ignoreCondition != null) {
		final State<T> ignoreState;
		if (isOptional) {
			ignoreState = createState(currentPattern.getName(), State.StateType.Normal);
			ignoreState.addTake(sink, takeCondition);
			ignoreState.addIgnore(ignoreCondition);
			addStopStates(ignoreState);
		} else {
			ignoreState = singletonState;
		}
		singletonState.addIgnore(ignoreState, ignoreCondition);
	}
	return singletonState;
}