// Path: src/main/java/preprocessor/ParsingPreprocessor.java
// static class GroupFactor extends RegexFactor<List<RegexToken>> {
// 		
// 		
// 	private int level;
// 	public int getLevel() {
// 		return level;
// 	}
// 
// 	public GroupFactor(List<RegexToken> factorContent, GroupType groupType) {
// 		super(factorContent);
// 		this.groupType = groupType;
// 	}
// 
// 	public GroupFactor(String processedContent, GroupType groupType, int level) {
// 		super(ParsingPreprocessor.tokenize(processedContent, level + 1));
// 		this.level = level;
// 		this.groupType = groupType;
// 	}
// 
// 	@Override
// 	public FactorType getFactorType() {
// 		return FactorType.GROUP;
// 	}
// 
// 	private GroupType groupType;
// 
// 	public GroupType getGroupType() {
// 		return groupType;
// 	}
// 		
// 	private String groupPrefix() {
// 		switch (groupType) {
// 		case NORMAL:
// 			return "";
// 		case NONCAPTURING:
// 			return "?:";
// 		case POSLOOKAHEAD:
// 			return "?=";
// 		case POSLOOKBEHIND:
// 			return "?<=";
// 		case NEGLOOKAHEAD:
// 			return "?!";
// 		case NEGLOOKBEHIND:
// 			return "?<!";
// 		default:
// 			throw new AssertionError("Unknown group type.");
// 		}
// 	}
// 		
// 	@Override
// 	public String toString() {
// 		String type = groupPrefix();
// 		return "Group( " + type + " " + factorContent + " )";
// 	}
// 
// 	public enum GroupType {
// 		NORMAL, NONCAPTURING, POSLOOKAHEAD, POSLOOKBEHIND, NEGLOOKAHEAD, NEGLOOKBEHIND
// 	}
// 
// 	@Override
// 	public String getRepresentation() {
// 		String type = groupPrefix();
// 		StringBuilder contentBuilder = new StringBuilder();
// 		for (RegexToken rt : factorContent) {
// 			contentBuilder.append(rt.getRepresentation());
// 		}
// 		return "(" + type + contentBuilder.toString() + ")";
// 	}
// 		
// 	@Override
// 	public boolean equals(Object o) {
// 		if (o == null) {
// 			return false;
// 		}
// 			
// 		if (o == this) {
// 			return true;
// 		}
// 			
// 		if (!(o instanceof GroupFactor)) {
// 			return false;
// 		}
// 			
// 		GroupFactor ro = (GroupFactor) o;
// 		return ro.factorContent.equals(factorContent);
// 	}
// 
// 	@Override
// 	public int hashCode() {
// 		return groupType.hashCode() * 13 + factorContent.hashCode();
// 	}
// }
// 
// Path: src/main/java/preprocessor/ParsingPreprocessor.java
// static abstract class RegexFactor<FactorContentType> implements RegexToken {
// 	public enum FactorType {
// 		CHARACTER_CLASS, SINGLE_CHARACTER, ESCAPED_CHARACTER, GROUP, WILD_CARD
// 	}
// 
// 	protected FactorContentType factorContent;
// 
// 	public FactorContentType getFactorContent() {
// 		return factorContent;
// 	}
// 
// 	public RegexFactor(FactorContentType factorContent) {
// 		this.factorContent = factorContent;
// 	}
// 
// 	@Override
// 	public TokenType getTokenType() {
// 		return TokenType.REGEX_FACTOR;
// 	}
// 
// 	public abstract FactorType getFactorType();
// 
// }
// 
// Path: src/main/java/preprocessor/ParsingPreprocessor.java
// public enum GroupType {
// 	NORMAL, NONCAPTURING, POSLOOKAHEAD, POSLOOKBEHIND, NEGLOOKAHEAD, NEGLOOKBEHIND
// }
// 
// Path: src/main/java/preprocessor/ParsingPreprocessor.java
// public enum FactorType {
// 	CHARACTER_CLASS, SINGLE_CHARACTER, ESCAPED_CHARACTER, GROUP, WILD_CARD
// }
// 
// Path: src/main/java/preprocessor/ParsingPreprocessor.java
// public enum TokenType {
// 	REGEX_FACTOR, REGEX_OPERATOR
// }
// 
// Path: src/main/java/preprocessor/ParsingPreprocessor.java
// static interface RegexToken {
// 
// 	public enum TokenType {
// 		REGEX_FACTOR, REGEX_OPERATOR
// 	}
// 
// 	public TokenType getTokenType();
// 		
// 	public String getRepresentation();
// 
// }


import java.util.List;
import preprocessor.ParsingPreprocessor.GroupFactor;
import preprocessor.ParsingPreprocessor.RegexFactor;
import preprocessor.ParsingPreprocessor.GroupFactor.GroupType;
import preprocessor.ParsingPreprocessor.RegexFactor.FactorType;
import preprocessor.ParsingPreprocessor.RegexToken.TokenType;
import preprocessor.ParsingPreprocessor.RegexToken;
package preprocessor;



public class NonpreciseLookaroundExpansion implements PreprocessorRule {

	@Override
	public String process(List<RegexToken> tokenStream) {
		StringBuilder regexBuilder = new StringBuilder();
		RegexToken tokens[] = new RegexToken[tokenStream.size()];
		tokens = tokenStream.toArray(tokens);
		int numTokens = tokens.length;
		int i = 0;
		while (i < numTokens) {

			if (tokens[i].getTokenType() == TokenType.REGEX_FACTOR) {
				RegexFactor<?> factorToken = (RegexFactor<?>) tokens[i];
				if (factorToken.getFactorType() == FactorType.GROUP) {
					GroupFactor groupFactor = (GroupFactor) factorToken;
// Path: src/main/java/preprocessor/ParsingPreprocessor.java
// static class GroupFactor extends RegexFactor<List<RegexToken>> {
// 		
// 		
// 	private int level;
// 	public int getLevel() {
// 		return level;
// 	}
// 
// 	public GroupFactor(List<RegexToken> factorContent, GroupType groupType) {
// 		super(factorContent);
// 		this.groupType = groupType;
// 	}
// 
// 	public GroupFactor(String processedContent, GroupType groupType, int level) {
// 		super(ParsingPreprocessor.tokenize(processedContent, level + 1));
// 		this.level = level;
// 		this.groupType = groupType;
// 	}
// 
// 	@Override
// 	public FactorType getFactorType() {
// 		return FactorType.GROUP;
// 	}
// 
// 	private GroupType groupType;
// 
// 	public GroupType getGroupType() {
// 		return groupType;
// 	}
// 		
// 	private String groupPrefix() {
// 		switch (groupType) {
// 		case NORMAL:
// 			return "";
// 		case NONCAPTURING:
// 			return "?:";
// 		case POSLOOKAHEAD:
// 			return "?=";
// 		case POSLOOKBEHIND:
// 			return "?<=";
// 		case NEGLOOKAHEAD:
// 			return "?!";
// 		case NEGLOOKBEHIND:
// 			return "?<!";
// 		default:
// 			throw new AssertionError("Unknown group type.");
// 		}
// 	}
// 		
// 	@Override
// 	public String toString() {
// 		String type = groupPrefix();
// 		return "Group( " + type + " " + factorContent + " )";
// 	}
// 
// 	public enum GroupType {
// 		NORMAL, NONCAPTURING, POSLOOKAHEAD, POSLOOKBEHIND, NEGLOOKAHEAD, NEGLOOKBEHIND
// 	}
// 
// 	@Override
// 	public String getRepresentation() {
// 		String type = groupPrefix();
// 		StringBuilder contentBuilder = new StringBuilder();
// 		for (RegexToken rt : factorContent) {
// 			contentBuilder.append(rt.getRepresentation());
// 		}
// 		return "(" + type + contentBuilder.toString() + ")";
// 	}
// 		
// 	@Override
// 	public boolean equals(Object o) {
// 		if (o == null) {
// 			return false;
// 		}
// 			
// 		if (o == this) {
// 			return true;
// 		}
// 			
// 		if (!(o instanceof GroupFactor)) {
// 			return false;
// 		}
// 			
// 		GroupFactor ro = (GroupFactor) o;
// 		return ro.factorContent.equals(factorContent);
// 	}
// 
// 	@Override
// 	public int hashCode() {
// 		return groupType.hashCode() * 13 + factorContent.hashCode();
// 	}
// }
// 
// Path: src/main/java/preprocessor/ParsingPreprocessor.java
// static abstract class RegexFactor<FactorContentType> implements RegexToken {
// 	public enum FactorType {
// 		CHARACTER_CLASS, SINGLE_CHARACTER, ESCAPED_CHARACTER, GROUP, WILD_CARD
// 	}
// 
// 	protected FactorContentType factorContent;
// 
// 	public FactorContentType getFactorContent() {
// 		return factorContent;
// 	}
// 
// 	public RegexFactor(FactorContentType factorContent) {
// 		this.factorContent = factorContent;
// 	}
// 
// 	@Override
// 	public TokenType getTokenType() {
// 		return TokenType.REGEX_FACTOR;
// 	}
// 
// 	public abstract FactorType getFactorType();
// 
// }
// 
// Path: src/main/java/preprocessor/ParsingPreprocessor.java
// public enum GroupType {
// 	NORMAL, NONCAPTURING, POSLOOKAHEAD, POSLOOKBEHIND, NEGLOOKAHEAD, NEGLOOKBEHIND
// }
// 
// Path: src/main/java/preprocessor/ParsingPreprocessor.java
// public enum FactorType {
// 	CHARACTER_CLASS, SINGLE_CHARACTER, ESCAPED_CHARACTER, GROUP, WILD_CARD
// }
// 
// Path: src/main/java/preprocessor/ParsingPreprocessor.java
// public enum TokenType {
// 	REGEX_FACTOR, REGEX_OPERATOR
// }
// 
// Path: src/main/java/preprocessor/ParsingPreprocessor.java
// static interface RegexToken {
// 
// 	public enum TokenType {
// 		REGEX_FACTOR, REGEX_OPERATOR
// 	}
// 
// 	public TokenType getTokenType();
// 		
// 	public String getRepresentation();
// 
// }


// Path: src/main/java/preprocessor/NonpreciseLookaroundExpansion.java
import java.util.List;
import preprocessor.ParsingPreprocessor.GroupFactor;
import preprocessor.ParsingPreprocessor.RegexFactor;
import preprocessor.ParsingPreprocessor.GroupFactor.GroupType;
import preprocessor.ParsingPreprocessor.RegexFactor.FactorType;
import preprocessor.ParsingPreprocessor.RegexToken.TokenType;
import preprocessor.ParsingPreprocessor.RegexToken;

package preprocessor;



public class NonpreciseLookaroundExpansion implements PreprocessorRule {

	@Override
	public String process(List<RegexToken> tokenStream) {
		StringBuilder regexBuilder = new StringBuilder();
		RegexToken tokens[] = new RegexToken[tokenStream.size()];
		tokens = tokenStream.toArray(tokens);
		int numTokens = tokens.length;
		int i = 0;
		while (i < numTokens) {

			if (tokens[i].getTokenType() == TokenType.REGEX_FACTOR) {
				RegexFactor<?> factorToken = (RegexFactor<?>) tokens[i];
				if (factorToken.getFactorType() == FactorType.GROUP) {
					GroupFactor groupFactor = (GroupFactor) factorToken;
					GroupType groupType = groupFactor.getGroupType();