package innovimax.mixthem.operation;

import innovimax.mixthem.MixException;
import innovimax.mixthem.arguments.ParamValue;
import innovimax.mixthem.arguments.RuleParam;
import innovimax.mixthem.arguments.TokenType;
import innovimax.mixthem.io.InputResource;
import innovimax.mixthem.io.Token;

import java.io.IOException;
import java.io.OutputStream;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
* <p>Abstract class for all token operation.</p>
* @see ITokenOperation
* @author Innovimax
* @version 1.0
*/
public abstract class AbstractTokenOperation extends AbstractOperation implements ITokenOperation {
	
	/**
	* Constructor
	* @param selection The file index selection (maybe empty)
	* @param tokenType The input tokenization type
 	* @param params The list of parameters (maybe empty)
	* @see innovimax.mixthem.arguments.RuleParam
	* @see innovimax.mixthem.arguments.ParamValue
	*/
	public AbstractTokenOperation(final Set<Integer> selection, final TokenType tokenType, final Map<RuleParam, ParamValue> params) {
		super(selection, tokenType, params);
	}

	@Override
	public void processFiles(final List<InputResource> inputs, final OutputStream output) throws MixException, IOException {
		//TODO
    	}
	
	@Override
	public boolean mixable(final List<Token> tokenRange) {
		//TODO
		return false;
	}

}

@@ -280,21 +280,237 @@
 them.io.
+I
 Token
+Range;%0Aimport innovimax.mixthem.io.ISerialize;%0Aimport innovimax.mixthem.io.Token;%0Aimport innovimax.mixthem.io.TokenRangeReader;%0Aimport innovimax.mixthem.io.TokenSerializer;%0Aimport innovimax.mixthem.utils.StreamUtils
 ;%0A%0Aimpor
@@ -627,16 +627,51 @@
 til.Set;
+%0Aimport java.util.stream.IntStream;
 %0A%0A/**%0A* 
@@ -1472,114 +1472,1152 @@
 %7B%0A%09%09
-//TODO%0A    %09%7D%0A%09%0A%09@Override%0A%09public boolean mixable(final List%3CToken%3E tokenRange) %7B%0A%09%09//TODO%0A%09%09return false
+final ITokenRange reader = new TokenRangeReader(inputs, this.selection, this.tokenType);%0A%09%09final ISerialize writer = new TokenSerializer(output, this.tokenType);%0A%09%09final TokenResult result = new TokenResult(inputs.size());%09%09%0A%09%09while (reader.hasMoreTokens()) %7B%0A%09%09%09// read next token range depends on last result indicators%0A%09%09%09final List%3CToken%3E tokenRange = reader.nextTokenRange(result.getReadingRange());%0A%09%09%09// set range preserved lines from last result%0A%09%09%09IntStream.range(0, tokenRange.size())%0A%09%09%09%09.filter(index -%3E !result.getReadingRange().get(index).booleanValue())%0A%09%09%09%09.forEach(index -%3E tokenRange.set(index, result.getRangeToken(index)));%0A%09%09%09result.reset();%0A%09%09%09if (mixable(tokenRange)) %7B%0A%09%09%09%09// process mixing%0A%09%09%09%09process(tokenRange, result);%0A%09%09%09%09// write mixing result if has one%0A%09%09%09%09if (result.hasResult()) %7B%0A%09%09%09%09%09result.getResult()%0A%09%09%09%09%09%09.forEach(StreamUtils.consume(token -%3E writer.writeToken(token)));%0A%09%09%09%09%7D%09%09%09%0A%09%09%09%7D%09%09%09%0A%09%09%7D%0A%09%09reader.close();%0A%09%09writer.close();%0A    %09%7D%0A%09%0A%09@Override%0A%09public boolean mixable(final List%3CToken%3E tokenRange) %7B%0A%09%09return IntStream.range(0, tokenRange.size())%0A%09%09%09.allMatch(index -%3E tokenRange.get(index) != null)
 ;%0A%09%7D

Implement abstract token operation