Index: trunk/quest-core-coverage/.classpath
===================================================================
--- trunk/quest-core-coverage/.classpath	(revision 518)
+++ trunk/quest-core-coverage/.classpath	(revision 518)
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" output="target/classes" path="src/main/java">
+		<attributes>
+			<attribute name="optional" value="true"/>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="output" path="target/classes"/>
+</classpath>
Index: trunk/quest-core-coverage/.project
===================================================================
--- trunk/quest-core-coverage/.project	(revision 518)
+++ trunk/quest-core-coverage/.project	(revision 518)
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>quest-core-coverage</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.m2e.core.maven2Builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.m2e.core.maven2Nature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
Index: trunk/quest-core-coverage/.settings/org.eclipse.jdt.core.prefs
===================================================================
--- trunk/quest-core-coverage/.settings/org.eclipse.jdt.core.prefs	(revision 518)
+++ trunk/quest-core-coverage/.settings/org.eclipse.jdt.core.prefs	(revision 518)
@@ -0,0 +1,5 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
+org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+org.eclipse.jdt.core.compiler.source=1.6
Index: trunk/quest-core-coverage/.settings/org.eclipse.m2e.core.prefs
===================================================================
--- trunk/quest-core-coverage/.settings/org.eclipse.m2e.core.prefs	(revision 518)
+++ trunk/quest-core-coverage/.settings/org.eclipse.m2e.core.prefs	(revision 518)
@@ -0,0 +1,4 @@
+activeProfiles=
+eclipse.preferences.version=1
+resolveWorkspaceProjects=true
+version=1
Index: trunk/quest-core-coverage/pom.xml
===================================================================
--- trunk/quest-core-coverage/pom.xml	(revision 518)
+++ trunk/quest-core-coverage/pom.xml	(revision 518)
@@ -0,0 +1,34 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>de.ugoe.cs.quest</groupId>
+  <artifactId>quest-core-coverage</artifactId>
+  <version>0.0.1-SNAPSHOT</version>
+  <name>quest-core-coverage</name>
+  <scm>
+		<url>https://quest.informatik.uni-goettingen.de/svn/quest/trunk/quest-core-coverage</url>
+	</scm>
+  	<dependencies>
+		<dependency>
+			<groupId>de.ugoe.cs.quest</groupId>
+			<artifactId>quest-core-events</artifactId>
+			<version>0.0.1-SNAPSHOT</version>
+		</dependency>
+		<dependency>
+			<groupId>de.ugoe.cs.quest</groupId>
+			<artifactId>quest-core-usageprofiles</artifactId>
+			<version>0.0.1-SNAPSHOT</version>
+		</dependency>
+	</dependencies>
+	<build>
+		<plugins>
+			<plugin>
+				<artifactId>maven-compiler-plugin</artifactId>
+				<version>2.3.2</version>
+				<configuration>
+					<source>1.6</source>
+					<target>1.6</target>
+				</configuration>
+			</plugin>
+		</plugins>
+	</build>
+</project>
Index: trunk/quest-core-coverage/src/main/java/de/ugoe/cs/quest/coverage/CoverageCalculatorObserved.java
===================================================================
--- trunk/quest-core-coverage/src/main/java/de/ugoe/cs/quest/coverage/CoverageCalculatorObserved.java	(revision 518)
+++ trunk/quest-core-coverage/src/main/java/de/ugoe/cs/quest/coverage/CoverageCalculatorObserved.java	(revision 518)
@@ -0,0 +1,272 @@
+package de.ugoe.cs.quest.coverage;
+
+import java.security.InvalidParameterException;
+import java.util.Collection;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+
+import de.ugoe.cs.quest.eventcore.Event;
+import de.ugoe.cs.quest.usageprofiles.IStochasticProcess;
+
+/**
+ * <p>
+ * This class calculates various types of sequence coverage in relation to a
+ * collection of observed sequences.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class CoverageCalculatorObserved {
+
+	/**
+	 * <p>
+	 * Sequences for which the coverage is calculated.
+	 * </p>
+	 */
+	private final Collection<List<? extends Event<?>>> sequences;
+
+	/**
+	 * <p>
+	 * Observed sequences that are baseline for the coverage calculation.
+	 * </p>
+	 */
+	private final Collection<List<? extends Event<?>>> observedSequences;
+
+	/**
+	 * <p>
+	 * Length of the subsequences in relation to which the covarage is
+	 * calculated.
+	 * </p>
+	 */
+	private final int length;
+
+	/**
+	 * <p>
+	 * All subsequences of {@link #length} of {@link #sequences}.
+	 * </p>
+	 */
+	private Collection<List<? extends Event<?>>> subSeqsGenerated = null;
+
+	/**
+	 * <p>
+	 * All subsequences of {@link #length} of {@link #observedSequences}.
+	 * </p>
+	 */
+	private Collection<List<? extends Event<?>>> subSeqsObserved = null;
+
+	/**
+	 * <p>
+	 * Constructor. Creates a new CoverageCalculatorObserved for given
+	 * collections of observed sequences and generated sequences.
+	 * </p>
+	 * 
+	 * @param observedSequences
+	 *            observed sequences in relation to which the coverage is
+	 *            calculated; must not be null
+	 * @param sequences
+	 *            sequences for which the coverage is calculated; must not be
+	 *            null
+	 * @param length
+	 *            length of the subsequences for which the coverage is analyzed;
+	 *            must be >0
+	 * @throws InvalidParameterException
+	 *             thrown if observedSequences or sequences is null or length
+	 *             less than or equal to 0
+	 */
+	public CoverageCalculatorObserved(
+			Collection<List<? extends Event<?>>> observedSequences,
+			Collection<List<? extends Event<?>>> sequences, int length) {
+		if (observedSequences == null) {
+			throw new InvalidParameterException(
+					"observed sequences must not be null");
+		}
+		if (sequences == null) {
+			throw new InvalidParameterException("sequences must not be null");
+		}
+		if (length <= 0) {
+			throw new InvalidParameterException(
+					"length must be >0; actual value: " + length);
+		}
+		this.observedSequences = observedSequences;
+		this.sequences = sequences;
+		this.length = length;
+	}
+
+	/**
+	 * <p>
+	 * Calculates the percentage of subsequences of length k that occur, with
+	 * reference to those that were observed.
+	 * </p>
+	 * 
+	 * @return coverage percentage
+	 */
+	public double getCoverageObserved() {
+		createSubSeqs();
+		Collection<List<? extends Event<?>>> subSeqsObservedCopy = new LinkedHashSet<List<? extends Event<?>>>(
+				subSeqsObserved);
+		subSeqsObservedCopy.retainAll(subSeqsGenerated);
+		return ((double) subSeqsObservedCopy.size()) / subSeqsObserved.size();
+	}
+
+	/**
+	 * <p>
+	 * Calculates the weight of subsequences of length k that occur, with
+	 * reference to those that were observed.
+	 * </p>
+	 * 
+	 * @param process
+	 *            stochastic process in reference to which the weight is
+	 *            calculated
+	 * @return coverage percentage
+	 */
+
+	public double getCoverageObservedWeigth(IStochasticProcess process) {
+		createSubSeqs();
+		Map<List<? extends Event<?>>, Double> weightMap = SequenceTools
+				.generateWeights(process, subSeqsObserved);
+
+		Collection<List<? extends Event<?>>> subSeqsObservedCopy = new LinkedHashSet<List<? extends Event<?>>>(
+				subSeqsObserved);
+		subSeqsObservedCopy.retainAll(subSeqsGenerated);
+		double weight = 0.0d;
+		for (List<? extends Event<?>> subSeq : subSeqsObservedCopy) {
+			weight += weightMap.get(subSeq);
+		}
+		return weight;
+	}
+
+	/**
+	 * <p>
+	 * Calculates the percentage of generated subsequences of length k that
+	 * occur and have not been observed, with reference to all generated
+	 * subsequences.
+	 * </p>
+	 * 
+	 * @return coverage percentage
+	 */
+	public double getNewPercentage() {
+		createSubSeqs();
+		Collection<List<? extends Event<?>>> subSeqsGeneratedCopy = new LinkedHashSet<List<? extends Event<?>>>(
+				subSeqsGenerated);
+		subSeqsGeneratedCopy.removeAll(subSeqsObserved);
+		return ((double) subSeqsGeneratedCopy.size()) / subSeqsGenerated.size();
+	}
+
+	/**
+	 * <p>
+	 * Calculates the percentage of generated subsequences of length k that
+	 * occur and have not been observed, with references to all possible new
+	 * subsequences.
+	 * </p>
+	 * 
+	 * @param process
+	 *            stochastic process which is used to determine which
+	 *            subsequences are possible
+	 * @return coverage percentage
+	 * @throws InvalidParameterException
+	 *             thrown if process is null
+	 */
+	public double getCoveragePossibleNew(IStochasticProcess process) {
+		if (process == null) {
+			throw new InvalidParameterException("process must not be null");
+		}
+		createSubSeqs();
+		Collection<List<? extends Event<?>>> subSeqsGeneratedCopy = new LinkedHashSet<List<? extends Event<?>>>(
+				subSeqsGenerated);
+		Collection<List<? extends Event<?>>> subSeqsPossible = process
+				.generateSequences(length);
+		subSeqsGeneratedCopy.removeAll(subSeqsObserved);
+		subSeqsPossible.removeAll(subSeqsObserved);
+		int possibleSize = subSeqsPossible.size();
+		subSeqsPossible.retainAll(subSeqsGeneratedCopy);
+		return ((double) subSeqsPossible.size()) / possibleSize;
+	}
+
+	/**
+	 * <p>
+	 * Calculates the weight of generated subsequences of length k that occur
+	 * and have not been observed, with references to all possible new
+	 * subsequences.
+	 * </p>
+	 * 
+	 * @param process
+	 *            stochastic process which is used to determine the weights and
+	 *            which subsequences are possible
+	 * @return coverage percentage
+	 * @throws InvalidParameterException
+	 *             thrown if process is null
+	 */
+	public double getCoveragePossibleNewWeight(IStochasticProcess process) {
+		if (process == null) {
+			throw new InvalidParameterException("process must not be null");
+		}
+		createSubSeqs();
+		Collection<List<? extends Event<?>>> subSeqsGeneratedCopy = new LinkedHashSet<List<? extends Event<?>>>(
+				subSeqsGenerated);
+		Collection<List<? extends Event<?>>> subSeqsPossible = process
+				.generateSequences(length);
+		subSeqsGeneratedCopy.removeAll(subSeqsObserved);
+		subSeqsPossible.removeAll(subSeqsObserved);
+		Map<List<? extends Event<?>>, Double> weightMap = SequenceTools
+				.generateWeights(process, subSeqsPossible);
+		double weight = 0.0d;
+		for (List<? extends Event<?>> subSeq : subSeqsGeneratedCopy) {
+			Double currentWeight = weightMap.get(subSeq);
+			if( currentWeight!=null ) {
+				weight += currentWeight;
+			}
+		}
+		return weight;
+	}
+
+	/**
+	 * <p>
+	 * Returns the number of covered subsequences of length k.
+	 * </p>
+	 * 
+	 * @return number of covered subsequences
+	 */
+	public int getNumObserved() {
+		createSubSeqs();
+		return subSeqsObserved.size();
+	}
+
+	/**
+	 * <p>
+	 * Returns the number of covered subsequences of length k.
+	 * </p>
+	 * 
+	 * @return number of covered subsequences
+	 */
+	public int getNumCovered() {
+		createSubSeqs();
+		return subSeqsGenerated.size();
+	}
+
+	public int getNumNew() {
+		createSubSeqs();
+		Collection<List<? extends Event<?>>> subSeqsGeneratedCopy = new LinkedHashSet<List<? extends Event<?>>>(
+				subSeqsGenerated);
+		subSeqsGeneratedCopy.removeAll(subSeqsObserved);
+		return subSeqsGeneratedCopy.size();
+	}
+
+	/**
+	 * <p>
+	 * Helper function that calcuates the subsequences of length k that have
+	 * been observed and generated.
+	 * </p>
+	 */
+	private void createSubSeqs() {
+		if (subSeqsObserved == null) {
+			subSeqsObserved = SequenceTools.containedSubSequences(
+					observedSequences, length);
+		}
+		if (subSeqsGenerated == null) {
+			subSeqsGenerated = SequenceTools.containedSubSequences(sequences,
+					length);
+		}
+	}
+}
Index: trunk/quest-core-coverage/src/main/java/de/ugoe/cs/quest/coverage/CoverageCalculatorProcess.java
===================================================================
--- trunk/quest-core-coverage/src/main/java/de/ugoe/cs/quest/coverage/CoverageCalculatorProcess.java	(revision 518)
+++ trunk/quest-core-coverage/src/main/java/de/ugoe/cs/quest/coverage/CoverageCalculatorProcess.java	(revision 518)
@@ -0,0 +1,218 @@
+package de.ugoe.cs.quest.coverage;
+
+import java.security.InvalidParameterException;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+import de.ugoe.cs.quest.eventcore.Event;
+import de.ugoe.cs.quest.usageprofiles.IStochasticProcess;
+
+/**
+ * <p>
+ * This class calculates various types of sequence coverage in relation to a
+ * stochastic process.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class CoverageCalculatorProcess {
+
+	/**
+	 * <p>
+	 * Stochastic process that is the foundation for probabilistic coverages and
+	 * coverages with reference to all possible sequences.
+	 * </p>
+	 */
+	private final IStochasticProcess process;
+
+	/**
+	 * <p>
+	 * Sequences for which the coverage is calculated.
+	 * </p>
+	 */
+	private Collection<List<? extends Event<?>>> sequences;
+
+	/**
+	 * <p>
+	 * Length of the subsequences in relation to which the coverage is
+	 * calculated.
+	 * </p>
+	 */
+	private final int length;
+
+	/**
+	 * <p>
+	 * All subsequences of {@link #length} of {@link #sequences}.
+	 * </p>
+	 */
+	private Collection<List<? extends Event<?>>> containedSubSeqs = null;
+
+	/**
+	 * <p>
+	 * All subsequences of {@link #length} that can be generated by
+	 * {@link #process}.
+	 * </p>
+	 */
+	private Collection<List<? extends Event<?>>> allPossibleSubSeqs = null;
+
+	/**
+	 * <p>
+	 * The probabilities of all subsequences of {@link #length} according to
+	 * {@link #process}.
+	 * </p>
+	 */
+	private Map<List<? extends Event<?>>, Double> subSeqWeights = null;
+
+	/**
+	 * <p>
+	 * Constructor. Creates a new CoverageCalculatorProcess for a given
+	 * stochastic process and generated sequences.
+	 * </p>
+	 * 
+	 * @param process
+	 *            stochastic process used for coverage calculations; must not be
+	 *            null
+	 * @param sequences
+	 *            sequences for which the coverage is calculated; must not be
+	 *            null
+	 * @param length
+	 *            length of the subsequences for which the coverage is analyzed;
+	 *            must be >0
+	 * @throws InvalidParameterException
+	 *             thrown if process or sequences is null or length less than or equal to 0
+	 */
+	public CoverageCalculatorProcess(IStochasticProcess process,
+			Collection<List<? extends Event<?>>> sequences, int length) {
+		if (process == null) {
+			throw new InvalidParameterException("process must not be null");
+		}
+		if (sequences == null) {
+			throw new InvalidParameterException("sequences must not be null");
+		}
+		if (length <= 0) {
+			throw new InvalidParameterException(
+					"length must be >0; actual value: " + length);
+		}
+		this.process = process;
+		this.sequences = sequences;
+		this.length = length;
+	}
+
+	/**
+	 * <p>
+	 * Calculates the percentage of subsequences of length k that occur,
+	 * including those that cannot be generated by {@link #process}.
+	 * </p>
+	 * 
+	 * @return coverage percentage
+	 */
+	public double getCoverageAllNoWeight() {
+		if (containedSubSeqs == null) {
+			containedSubSeqs = SequenceTools.containedSubSequences(sequences,
+					length);
+		}
+		return ((double) containedSubSeqs.size())
+				/ SequenceTools.numSequences(process, length);
+	}
+
+	/**
+	 * <p>
+	 * Calculates the percentage of subsequences of length k that occur and can
+	 * generated by {@link #process}.
+	 * </p>
+	 * 
+	 * @return coverage percentage
+	 */
+	public double getCoveragePossibleNoWeight() {
+		if (containedSubSeqs == null) {
+			containedSubSeqs = SequenceTools.containedSubSequences(sequences,
+					length);
+		}
+		if (allPossibleSubSeqs == null) {
+			allPossibleSubSeqs = process.generateSequences(length);
+		}
+		return ((double) containedSubSeqs.size()) / allPossibleSubSeqs.size();
+	}
+
+	/**
+	 * <p>
+	 * Calculates the weight of the subsequences that occur with relation to
+	 * {@link #process}, i.e., the mass of the subsequence probability covered
+	 * by the subsequences.
+	 * </p>
+	 * 
+	 * @return coverage weight
+	 */
+	public double getCoveragePossibleWeight() {
+		if (containedSubSeqs == null) {
+			containedSubSeqs = SequenceTools.containedSubSequences(sequences,
+					length);
+		}
+		if (allPossibleSubSeqs == null) {
+			allPossibleSubSeqs = process.generateSequences(length);
+		}
+		if (subSeqWeights == null) {
+			subSeqWeights = SequenceTools.generateWeights(process,
+					allPossibleSubSeqs);
+		}
+		double weight = 0.0;
+		for (List<? extends Event<?>> subSeq : containedSubSeqs) {
+			Double curWeight = subSeqWeights.get(subSeq);
+			if( curWeight!=null ) {
+				weight += curWeight;
+			}
+		}
+		return weight;
+	}
+
+	/**
+	 * <p>
+	 * Returns the number of covered subsequences of length k.
+	 * </p>
+	 * 
+	 * @return number of covered subsequences
+	 */
+	public int getNumCovered() {
+		if (containedSubSeqs == null) {
+			containedSubSeqs = SequenceTools.containedSubSequences(sequences,
+					length);
+		}
+		return containedSubSeqs.size();
+	}
+
+	/**
+	 * <p>
+	 * Returns the number of possible subsequences of length k according to the
+	 * stochastic process.
+	 * </p>
+	 * 
+	 * @return number of possible subsequences
+	 */
+	public int getNumPossible() {
+		if (allPossibleSubSeqs == null) {
+			allPossibleSubSeqs = process.generateSequences(length);
+		}
+		return allPossibleSubSeqs.size();
+	}
+
+	/**
+	 * <p>
+	 * Sets a new collection of sequences for which the coverage is analyzed.
+	 * </p>
+	 * 
+	 * @param newSequences
+	 *            new collection of sequences
+	 * @throws InvalidParameterException
+	 *             thrown is newSequences is null
+	 */
+	public void setSequences(Collection<List<? extends Event<?>>> newSequences) {
+		if (newSequences == null) {
+			throw new InvalidParameterException("sequences must not be null");
+		}
+		this.sequences = newSequences;
+		containedSubSeqs = null;
+	}
+
+}
Index: trunk/quest-core-coverage/src/main/java/de/ugoe/cs/quest/coverage/SequenceTools.java
===================================================================
--- trunk/quest-core-coverage/src/main/java/de/ugoe/cs/quest/coverage/SequenceTools.java	(revision 518)
+++ trunk/quest-core-coverage/src/main/java/de/ugoe/cs/quest/coverage/SequenceTools.java	(revision 518)
@@ -0,0 +1,147 @@
+package de.ugoe.cs.quest.coverage;
+
+import java.security.InvalidParameterException;
+import java.util.Collection;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import de.ugoe.cs.quest.eventcore.Event;
+import de.ugoe.cs.quest.usageprofiles.IStochasticProcess;
+
+/**
+ * <p>
+ * This class gathers some helper functions to work with sequences.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class SequenceTools {
+	
+	/**
+	 * <p>
+	 * Private constructor to prevent initializing of the class.
+	 * </p>
+	 */
+	private SequenceTools() {
+		
+	}
+
+	/**
+	 * <p>
+	 * Calculates the weights for all sequences passed to this function as
+	 * defined by the stochastic process and stores them in a {@link Map}. The
+	 * weights are normalized, i.e., the sum of all weights contained in this
+	 * map is 1.
+	 * </p>
+	 * 
+	 * @param process
+	 *            process used for weight calculation
+	 * @param sequences
+	 *            sequences for which the weights are calculated
+	 * @return {@link Map} of weights
+	 */
+	public static Map<List<? extends Event<?>>, Double> generateWeights(
+			IStochasticProcess process,
+			Collection<List<? extends Event<?>>> sequences) {
+		Map<List<? extends Event<?>>, Double> subSeqWeights = new LinkedHashMap<List<? extends Event<?>>, Double>();
+		if (sequences != null && !sequences.isEmpty()) {
+			if (process != null) {
+				double sum = 0.0;
+				for (List<? extends Event<?>> sequence : sequences) {
+					double prob = process.getProbability(sequence);
+					subSeqWeights.put(sequence, prob);
+					sum += prob;
+				}
+				if (sum < 1.0) {
+					for (Map.Entry<List<? extends Event<?>>, Double> entry : subSeqWeights
+							.entrySet()) {
+						entry.setValue(entry.getValue() / sum);
+					}
+				}
+			} else {
+				for( List<? extends Event<?>> sequence : sequences ) {
+					subSeqWeights.put(sequence, 0.0d);
+				}
+			}
+		}
+		return subSeqWeights;
+	}
+
+	/**
+	 * <p>
+	 * Calculates the number of all existing sequences of a given length,
+	 * regardless whether they are possible or not.
+	 * </p>
+	 * 
+	 * @param process
+	 *            stochastic process whose symbols are the basis for this
+	 *            calculation
+	 * @param length
+	 *            lenght of the sequences
+	 * @return numStates^length
+	 * @throws InvalidParameterException
+	 *             thrown if length less or equal to 0
+	 */
+	public static long numSequences(IStochasticProcess process, int length) {
+		if (length <= 0) {
+			throw new InvalidParameterException(
+					"length must be a positive integer");
+		}
+		long result = 0;
+		if (process != null) {
+			result = (long) Math.pow(process.getNumSymbols(), length);
+		}
+		return result;
+	}
+
+	/**
+	 * <p>
+	 * Creates a {@link Set} of all subsequences of a given length that are
+	 * contained in a sequence collection.
+	 * </p>
+	 * 
+	 * @param sequences
+	 *            sequences from which the subsequences are extracted
+	 * @param length
+	 *            length of the subsequences
+	 * @return {@link Set} of all subsequences
+	 * @throws InvalidParameterException
+	 *             thrown if length less or equal to 0
+	 */
+	public static Set<List<? extends Event<?>>> containedSubSequences(
+			Collection<List<? extends Event<?>>> sequences, int length) {
+		if (length <= 0) {
+			throw new InvalidParameterException(
+					"length must be a positive integer");
+		}
+		Set<List<? extends Event<?>>> containedSubSeqs = new LinkedHashSet<List<? extends Event<?>>>();
+		if (sequences != null) {
+			for (List<? extends Event<?>> sequence : sequences) {
+				List<Event<?>> subSeq = new LinkedList<Event<?>>();
+				boolean minLengthReached = false;
+				for (Event<?> event : sequence) {
+					subSeq.add(event);
+					if (!minLengthReached) {
+						if (subSeq.size() == length) {
+							minLengthReached = true;
+						}
+					} else {
+						subSeq.remove(0);
+					}
+					if (minLengthReached) {
+						if (!containedSubSeqs.contains(subSeq)) {
+							containedSubSeqs.add(new LinkedList<Event<?>>(
+									subSeq));
+						}
+					}
+				}
+			}
+		}
+		return containedSubSeqs;
+	}
+}
