Index: autoquest-core-usability-evaluation/.classpath
===================================================================
--- autoquest-core-usability-evaluation/.classpath	(revision 1030)
+++ autoquest-core-usability-evaluation/.classpath	(revision 1030)
@@ -0,0 +1,42 @@
+<?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 excluding="**" kind="src" output="target/classes" path="src/main/resources">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="src" output="target/test-classes" path="src/test/java">
+		<attributes>
+			<attribute name="optional" value="true"/>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry excluding="**" kind="src" output="target/test-classes" path="src/test/resources">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry including="**/*.java" kind="src" output="target/classes" path="target/generated-sources/xjc">
+		<attributes>
+			<attribute name="optional" value="true"/>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER">
+		<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: autoquest-core-usability-evaluation/.project
===================================================================
--- autoquest-core-usability-evaluation/.project	(revision 1030)
+++ autoquest-core-usability-evaluation/.project	(revision 1030)
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>autoquest-core-usability-evaluation</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.jdt.core.javanature</nature>
+		<nature>org.eclipse.m2e.core.maven2Nature</nature>
+	</natures>
+</projectDescription>
Index: autoquest-core-usability-evaluation/.settings/org.eclipse.jdt.core.prefs
===================================================================
--- autoquest-core-usability-evaluation/.settings/org.eclipse.jdt.core.prefs	(revision 1030)
+++ autoquest-core-usability-evaluation/.settings/org.eclipse.jdt.core.prefs	(revision 1030)
@@ -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: autoquest-core-usability-evaluation/.settings/org.eclipse.m2e.core.prefs
===================================================================
--- autoquest-core-usability-evaluation/.settings/org.eclipse.m2e.core.prefs	(revision 1030)
+++ autoquest-core-usability-evaluation/.settings/org.eclipse.m2e.core.prefs	(revision 1030)
@@ -0,0 +1,4 @@
+activeProfiles=
+eclipse.preferences.version=1
+resolveWorkspaceProjects=true
+version=1
Index: autoquest-core-usability-evaluation/pom.xml
===================================================================
--- autoquest-core-usability-evaluation/pom.xml	(revision 1030)
+++ autoquest-core-usability-evaluation/pom.xml	(revision 1030)
@@ -0,0 +1,87 @@
+<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>
+	<artifactId>autoquest-core-usability-evaluation</artifactId>
+
+	<parent>
+		<groupId>de.ugoe.cs.autoquest</groupId>
+		<artifactId>autoquest</artifactId>
+		<version>0.0.1-SNAPSHOT</version>
+	</parent>
+
+	<licenses>
+		<license>
+			<name>The Apache Software License, Version 2.0</name>
+			<url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
+		</license>
+	</licenses>
+
+	<scm>
+		<url>${autoquest-scm-trunk-dir}/autoquest-core-usability-evaluation</url>
+	</scm>
+
+	<dependencies>
+
+		<dependency>
+			<groupId>de.ugoe.cs.autoquest</groupId>
+			<artifactId>autoquest-core-tasktrees</artifactId>
+			<version>${project.parent.version}</version>
+		</dependency>
+		<dependency>
+			<groupId>de.ugoe.cs.autoquest</groupId>
+			<artifactId>autoquest-plugin-jfc</artifactId>
+			<version>0.0.1-SNAPSHOT</version>
+		</dependency>
+		<dependency>
+			<groupId>de.ugoe.cs.autoquest</groupId>
+			<artifactId>autoquest-plugin-html</artifactId>
+			<version>0.0.1-SNAPSHOT</version>
+		</dependency>
+
+		<dependency>
+			<groupId>com.google.guava</groupId>
+			<artifactId>guava</artifactId>
+			<version>14.0-rc1</version>
+		</dependency>
+		<dependency>
+			<groupId>com.google.code.findbugs</groupId>
+			<artifactId>jsr305</artifactId>
+			<version>2.0.1</version>
+		</dependency>
+		<dependency>
+			<groupId>com.github.peichhorn</groupId>
+			<artifactId>lombok-pg</artifactId>
+			<version>0.11.3</version>
+		</dependency>
+		<dependency>
+			<groupId>com.github.peichhorn</groupId>
+			<artifactId>lombok-pg</artifactId>
+			<version>0.11.3</version>
+			<classifier>runtime</classifier>
+			<scope>runtime</scope>
+		</dependency>
+	</dependencies>
+
+	<build>
+
+		<plugins>
+			<plugin>
+				<groupId>org.jvnet.jaxb2.maven2</groupId>
+				<artifactId>maven-jaxb2-plugin</artifactId>
+				<version>0.8.2</version>
+				<configuration>
+					<generatePackage>de.ugoe.cs.autoquest.usability</generatePackage>
+				</configuration>
+				<executions>
+					<execution>
+						<goals>
+							<goal>generate</goal>
+						</goals>
+					</execution>
+				</executions>
+			</plugin>
+		</plugins>
+
+	</build>
+
+</project>
Index: autoquest-core-usability-evaluation/src/main/java/de/ugoe/cs/autoquest/usability/UsabilityEvaluationFacade.java
===================================================================
--- autoquest-core-usability-evaluation/src/main/java/de/ugoe/cs/autoquest/usability/UsabilityEvaluationFacade.java	(revision 1030)
+++ autoquest-core-usability-evaluation/src/main/java/de/ugoe/cs/autoquest/usability/UsabilityEvaluationFacade.java	(revision 1030)
@@ -0,0 +1,50 @@
+package de.ugoe.cs.autoquest.usability;
+
+import java.util.EnumSet;
+import java.util.List;
+
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Lists;
+
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTree;
+import de.ugoe.cs.autoquest.usability.evaluation.result.UsabilityDefect;
+import de.ugoe.cs.autoquest.usability.evaluation.rule.set.UsabilityRule;
+import de.ugoe.cs.autoquest.usability.evaluation.rule.set.UsabilityRuleset;
+
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+public class UsabilityEvaluationFacade {
+
+    public static ExecuteUsabilityEvaluationStep applyUsabilityRuleset(UsabilityRuleset usabilityRuleset) {
+	Preconditions.checkNotNull(usabilityRuleset);
+        return new ExecuteUsabilityEvaluationStep(usabilityRuleset);
+    }
+
+    protected static class ExecuteUsabilityEvaluationStep {
+	
+	private UsabilityRuleset usabilityRuleset;
+
+	public ExecuteUsabilityEvaluationStep(UsabilityRuleset usabilityRuleset) {
+	    this.usabilityRuleset = usabilityRuleset;
+	}
+
+	public UsabilityEvaluationReport evaluateUsabilityOf(ITaskTree taskTree) {
+	    Preconditions.checkNotNull(taskTree);
+	    EnumSet<? extends UsabilityRule> rulesetForUsabilityEvaluation = usabilityRuleset.getRulesetForUsabilityEvaluation();
+	    List<UsabilityDefect> evaluationResults = 
+		    Lists.newArrayListWithCapacity(rulesetForUsabilityEvaluation.size());
+	    for(UsabilityRule usabilityRule : rulesetForUsabilityEvaluation) {
+		Optional<UsabilityDefect> ruleEvaluationResult = usabilityRule.evaluate(taskTree);
+		if(ruleEvaluationResult.isPresent()) {
+		    evaluationResults.add(ruleEvaluationResult.get());
+		}
+	    }
+	    return UsabilityEvaluationReport.from(evaluationResults);
+	}
+	
+    }
+
+}
Index: autoquest-core-usability-evaluation/src/main/java/de/ugoe/cs/autoquest/usability/UsabilityEvaluationReport.java
===================================================================
--- autoquest-core-usability-evaluation/src/main/java/de/ugoe/cs/autoquest/usability/UsabilityEvaluationReport.java	(revision 1030)
+++ autoquest-core-usability-evaluation/src/main/java/de/ugoe/cs/autoquest/usability/UsabilityEvaluationReport.java	(revision 1030)
@@ -0,0 +1,26 @@
+package de.ugoe.cs.autoquest.usability;
+
+import java.util.List;
+
+import lombok.AccessLevel;
+import lombok.AllArgsConstructor;
+
+import com.google.common.base.Preconditions;
+
+import de.ugoe.cs.autoquest.usability.evaluation.result.UsabilityDefect;
+
+@AllArgsConstructor(access = AccessLevel.PRIVATE)
+public class UsabilityEvaluationReport {
+    
+    private List<UsabilityDefect> evaluationResults;
+    
+    public static UsabilityEvaluationReport from(List<UsabilityDefect> evaluationResults) {
+	Preconditions.checkNotNull(evaluationResults);
+	return new UsabilityEvaluationReport(evaluationResults);
+    }
+    
+    public List<UsabilityDefect> evaluationResults() {
+        return this.evaluationResults;
+    }
+    
+}
Index: autoquest-core-usability-evaluation/src/main/java/de/ugoe/cs/autoquest/usability/evaluation/result/UsabilityDefect.java
===================================================================
--- autoquest-core-usability-evaluation/src/main/java/de/ugoe/cs/autoquest/usability/evaluation/result/UsabilityDefect.java	(revision 1030)
+++ autoquest-core-usability-evaluation/src/main/java/de/ugoe/cs/autoquest/usability/evaluation/result/UsabilityDefect.java	(revision 1030)
@@ -0,0 +1,72 @@
+
+package de.ugoe.cs.autoquest.usability.evaluation.result;
+
+import java.util.Map;
+
+import lombok.Getter;
+import de.ugoe.cs.autoquest.usability.DefectDescription;
+import de.ugoe.cs.autoquest.usability.ParameterFragment;
+
+public class UsabilityDefect {
+
+    @Getter
+    private UsabilityDefectSeverityLevel severityLevel;
+
+    private DefectDescription defectDescription;
+
+    private Map<String, String> descriptionParametersValues;
+
+    public UsabilityDefect(UsabilityDefectSeverityLevel severityLevel,
+                                           DefectDescription recommendationDescription,
+                                           Map<String, String> descriptionParametersValues) {
+        this.severityLevel = severityLevel;
+        this.defectDescription = recommendationDescription;
+        this.descriptionParametersValues = descriptionParametersValues;
+    }
+
+    public String defectDescription() {
+        StringBuffer result = new StringBuffer();
+
+        for (Object fragment : defectDescription.getTextFragmentOrParameterFragment()) {
+            if (result.length() > 0) {
+                result.append(" ");
+            }
+
+            if (fragment instanceof ParameterFragment) {
+                String value = null;
+                if (descriptionParametersValues != null) {
+                    value =
+                        descriptionParametersValues.get(((ParameterFragment) fragment)
+                            .getParameterName());
+                }
+
+                if (value != null) {
+                    result.append(value);
+                }
+                else {
+                    throw new IllegalArgumentException("required parameter \"" +
+                        ((ParameterFragment) fragment).getParameterName() +
+                        "\" for usability defect description not provided");
+                }
+            }
+            else {
+                result.append(getFragmentString(fragment));
+            }
+        }
+
+        return result.toString();
+    }
+
+    private String getFragmentString(Object fragment) {
+        String fragmentStr = fragment.toString().trim();
+
+        fragmentStr = fragmentStr.replaceAll("\n", " ");
+
+        while (fragmentStr.indexOf("  ") > -1) {
+            fragmentStr = fragmentStr.replaceAll("  ", " ");
+        }
+
+        return fragmentStr;
+    }
+
+}
Index: autoquest-core-usability-evaluation/src/main/java/de/ugoe/cs/autoquest/usability/evaluation/result/UsabilityDefectDescriptionResolver.java
===================================================================
--- autoquest-core-usability-evaluation/src/main/java/de/ugoe/cs/autoquest/usability/evaluation/result/UsabilityDefectDescriptionResolver.java	(revision 1030)
+++ autoquest-core-usability-evaluation/src/main/java/de/ugoe/cs/autoquest/usability/evaluation/result/UsabilityDefectDescriptionResolver.java	(revision 1030)
@@ -0,0 +1,10 @@
+package de.ugoe.cs.autoquest.usability.evaluation.result;
+
+import de.ugoe.cs.autoquest.usability.DefectDescription;
+import de.ugoe.cs.autoquest.usability.evaluation.rule.set.UsabilityRule;
+
+public interface UsabilityDefectDescriptionResolver {
+
+    public DefectDescription descriptionFor(UsabilityRule usabilityRule);
+
+}
Index: autoquest-core-usability-evaluation/src/main/java/de/ugoe/cs/autoquest/usability/evaluation/result/UsabilityDefectFactory.java
===================================================================
--- autoquest-core-usability-evaluation/src/main/java/de/ugoe/cs/autoquest/usability/evaluation/result/UsabilityDefectFactory.java	(revision 1030)
+++ autoquest-core-usability-evaluation/src/main/java/de/ugoe/cs/autoquest/usability/evaluation/result/UsabilityDefectFactory.java	(revision 1030)
@@ -0,0 +1,25 @@
+
+package de.ugoe.cs.autoquest.usability.evaluation.result;
+
+import java.util.Map;
+
+import de.ugoe.cs.autoquest.usability.DefectDescription;
+import de.ugoe.cs.autoquest.usability.evaluation.rule.set.UsabilityRule;
+import lombok.AllArgsConstructor;
+
+@AllArgsConstructor
+public class UsabilityDefectFactory {
+
+    private final UsabilityDefectDescriptionResolver usabilityDefectDescriptionResolver;
+
+    public UsabilityDefect createUsabilityGuidlineRecommendation(UsabilityDefectSeverityLevel recommendationSeverityLevel,
+                                                                 UsabilityRule usabilityRule,
+                                                                 Map<String, String> recommendationMessageParameteValues) {
+        DefectDescription guidlineDescription =
+            usabilityDefectDescriptionResolver.descriptionFor(usabilityRule);
+        return new UsabilityDefect(recommendationSeverityLevel, guidlineDescription,
+                                   recommendationMessageParameteValues);
+
+    }
+
+}
Index: autoquest-core-usability-evaluation/src/main/java/de/ugoe/cs/autoquest/usability/evaluation/result/UsabilityDefectSeverityLevel.java
===================================================================
--- autoquest-core-usability-evaluation/src/main/java/de/ugoe/cs/autoquest/usability/evaluation/result/UsabilityDefectSeverityLevel.java	(revision 1030)
+++ autoquest-core-usability-evaluation/src/main/java/de/ugoe/cs/autoquest/usability/evaluation/result/UsabilityDefectSeverityLevel.java	(revision 1030)
@@ -0,0 +1,7 @@
+package de.ugoe.cs.autoquest.usability.evaluation.result;
+
+public enum UsabilityDefectSeverityLevel {
+
+    INFO, LOW, MEDIUM, HIGH;
+    
+}
Index: autoquest-core-usability-evaluation/src/main/java/de/ugoe/cs/autoquest/usability/evaluation/result/UsabilityDefectXmlDescriptionResolver.java
===================================================================
--- autoquest-core-usability-evaluation/src/main/java/de/ugoe/cs/autoquest/usability/evaluation/result/UsabilityDefectXmlDescriptionResolver.java	(revision 1030)
+++ autoquest-core-usability-evaluation/src/main/java/de/ugoe/cs/autoquest/usability/evaluation/result/UsabilityDefectXmlDescriptionResolver.java	(revision 1030)
@@ -0,0 +1,79 @@
+package de.ugoe.cs.autoquest.usability.evaluation.result;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBElement;
+import javax.xml.bind.Unmarshaller;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Predicate;
+import com.google.common.collect.Iterables;
+
+import de.ugoe.cs.autoquest.usability.DefectDescription;
+import de.ugoe.cs.autoquest.usability.DefectDescriptions;
+import de.ugoe.cs.autoquest.usability.evaluation.rule.set.UsabilityRule;
+
+public class UsabilityDefectXmlDescriptionResolver implements UsabilityDefectDescriptionResolver {
+    
+    private static final String DEFAULT_MESSAGES_FILE = "defectDescriptions_en.xml";
+    
+    private static final UsabilityDefectXmlDescriptionResolver instance = new UsabilityDefectXmlDescriptionResolver();
+    
+    private DefectDescriptions defectDescriptions;
+    
+    private UsabilityDefectXmlDescriptionResolver() {
+        loadDescriptions();
+    }
+    
+    @SuppressWarnings("unchecked")
+    private void loadDescriptions() {
+        InputStream inputStream =
+                ClassLoader.getSystemResourceAsStream(DEFAULT_MESSAGES_FILE);
+        try {
+            String packageName = DefectDescriptions.class.getPackage().getName();
+            JAXBContext jaxbContext = JAXBContext.newInstance(packageName);
+            Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
+
+            defectDescriptions =
+                ((JAXBElement<DefectDescriptions>) unmarshaller.unmarshal(inputStream))
+                    .getValue();
+        }
+        catch (Exception e) {
+            throw new RuntimeException
+                ("error while initializing usability defect descriptions", e);
+        }
+        finally {
+            if (inputStream != null) {
+                try {
+                    inputStream.close();
+                }
+                catch (IOException e) {
+                    // ignore
+                }
+            }
+        }
+    }
+    
+    public static UsabilityDefectXmlDescriptionResolver instance() {
+        return instance;
+    }
+
+    @Override
+    public DefectDescription descriptionFor(final UsabilityRule usabilityRule) {
+        Optional<DefectDescription> guidlineDescription = Iterables.tryFind(defectDescriptions.getDefectDescription(), new Predicate<DefectDescription>() {
+            
+            public boolean apply(DefectDescription defectDescription) {
+                return usabilityRule.ruleIdentifier().equals(defectDescription.getDefectId());
+            }
+            
+        });
+        if(!guidlineDescription.isPresent())
+            throw new RuntimeException
+            ("error while initializing usability defect descriptions. No " +
+                    "description text available for description " + usabilityRule.ruleIdentifier());
+        return guidlineDescription.get();
+    }
+
+}
Index: autoquest-core-usability-evaluation/src/main/java/de/ugoe/cs/autoquest/usability/evaluation/rule/evaluator/NoLetterOrDigitTextInputsEvaluator.java
===================================================================
--- autoquest-core-usability-evaluation/src/main/java/de/ugoe/cs/autoquest/usability/evaluation/rule/evaluator/NoLetterOrDigitTextInputsEvaluator.java	(revision 1030)
+++ autoquest-core-usability-evaluation/src/main/java/de/ugoe/cs/autoquest/usability/evaluation/rule/evaluator/NoLetterOrDigitTextInputsEvaluator.java	(revision 1030)
@@ -0,0 +1,71 @@
+package de.ugoe.cs.autoquest.usability.evaluation.rule.evaluator;
+
+import static de.ugoe.cs.autoquest.usability.tasktree.filter.EventTypeFilter.TEXT_INPUT;
+import static de.ugoe.cs.autoquest.usability.util.TextInputUtil.aggregateEnteredTextFromTextInputs;
+import static de.ugoe.cs.autoquest.usability.util.TextInputUtil.characterIsLetterOrDigitPredicate;
+
+import com.google.common.base.CharMatcher;
+import com.google.common.base.Optional;
+import com.google.common.collect.Multiset;
+
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTree;
+import de.ugoe.cs.autoquest.usability.evaluation.result.UsabilityDefectSeverityLevel;
+import de.ugoe.cs.autoquest.usability.evaluation.rule.set.UsabilityRule;
+import de.ugoe.cs.autoquest.usability.tasktree.filter.FilterStatistic;
+import de.ugoe.cs.autoquest.usability.tasktree.filter.IterativeDFSFilterStrategy;
+import de.ugoe.cs.autoquest.usability.tasktree.filter.TaskTreeFilter;
+
+public class NoLetterOrDigitTextInputsEvaluator extends RuleEvaluator {
+
+    public NoLetterOrDigitTextInputsEvaluator(UsabilityRule evaluatedUsabilityRule, ITaskTree taskTree) {
+        super(evaluatedUsabilityRule, taskTree);
+    }
+
+    @Override
+    protected FilterStatistic nodesUnderEvaluation(ITaskTree taskTree) {
+        Optional<FilterStatistic> cachedNodes = loadFromCache(TEXT_INPUT);
+        return cachedNodes.isPresent() ? cachedNodes.get() : cacheAndReturnNodes(taskTree, TEXT_INPUT);
+    }
+    
+    @Override
+    protected FilterStatistic extractNodesFromTaskTree(ITaskTree taskTree) {
+        return new TaskTreeFilter(new IterativeDFSFilterStrategy())
+            .filterByEventType(TEXT_INPUT).from(taskTree);
+    }
+
+    @Override
+    protected float calculateEvaluationMetric() {
+        Multiset<String> enteredTextFragments = aggregateEnteredTextFromTextInputs(this.filteredNodes.nodesMatchedFilter());
+        int allCharactersCount = 0;
+        int noLetterOrDigitCount = 0;
+        for(String textFragment : enteredTextFragments.elementSet()) {
+            int occurencesOfTextFragment = enteredTextFragments.count(textFragment);
+            allCharactersCount += CharMatcher.ANY.countIn(textFragment) * occurencesOfTextFragment;
+            noLetterOrDigitCount += CharMatcher.forPredicate(characterIsLetterOrDigitPredicate()).countIn(textFragment) * occurencesOfTextFragment;
+        }
+        return allCharactersCount != 0 ? (float) noLetterOrDigitCount / (float) allCharactersCount : 0;
+    }
+
+    @Override
+    protected Optional<UsabilityDefectSeverityLevel> determineSeverityLevel(float evaluationMetric) {
+        Optional<UsabilityDefectSeverityLevel> recommendationSeverityLevel = Optional.absent();
+        if (evaluationMetric > 0.1) // every 10th sign
+        {
+            recommendationSeverityLevel = Optional.of(UsabilityDefectSeverityLevel.HIGH);
+        }
+        else if (evaluationMetric > 0.05) // every 20th sign
+        {
+            recommendationSeverityLevel = Optional.of(UsabilityDefectSeverityLevel.MEDIUM);
+        }
+        else if (evaluationMetric > 0.02) // every 50th sign
+        {
+            recommendationSeverityLevel = Optional.of(UsabilityDefectSeverityLevel.LOW);
+        }
+        else if (evaluationMetric > 0.01) // every 100th sign
+        {
+            recommendationSeverityLevel = Optional.of(UsabilityDefectSeverityLevel.INFO);
+        }
+        return recommendationSeverityLevel;
+    }
+ 
+}
Index: autoquest-core-usability-evaluation/src/main/java/de/ugoe/cs/autoquest/usability/evaluation/rule/evaluator/RuleEvaluator.java
===================================================================
--- autoquest-core-usability-evaluation/src/main/java/de/ugoe/cs/autoquest/usability/evaluation/rule/evaluator/RuleEvaluator.java	(revision 1030)
+++ autoquest-core-usability-evaluation/src/main/java/de/ugoe/cs/autoquest/usability/evaluation/rule/evaluator/RuleEvaluator.java	(revision 1030)
@@ -0,0 +1,70 @@
+
+package de.ugoe.cs.autoquest.usability.evaluation.rule.evaluator;
+
+import java.util.Map;
+
+import com.google.common.base.Optional;
+import com.google.common.collect.Maps;
+
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTree;
+import de.ugoe.cs.autoquest.usability.evaluation.result.UsabilityDefect;
+import de.ugoe.cs.autoquest.usability.evaluation.result.UsabilityDefectFactory;
+import de.ugoe.cs.autoquest.usability.evaluation.result.UsabilityDefectSeverityLevel;
+import de.ugoe.cs.autoquest.usability.evaluation.result.UsabilityDefectXmlDescriptionResolver;
+import de.ugoe.cs.autoquest.usability.evaluation.rule.set.UsabilityRule;
+import de.ugoe.cs.autoquest.usability.tasktree.filter.FilterStatistic;
+import de.ugoe.cs.autoquest.usability.tasktree.filter.FilterStatisticCache;
+import de.ugoe.cs.autoquest.usability.tasktree.filter.TaskTreeNodeFilter;
+
+public abstract class RuleEvaluator {
+
+    protected final UsabilityRule evaluatedUsabilityRule;
+
+    protected final FilterStatistic filteredNodes;
+
+    protected Map<String, String> defectDescriptionMessageParameterValues = Maps.newHashMap();
+
+    public RuleEvaluator(UsabilityRule evaluatedUsabilityRule, ITaskTree taskTree) {
+        this.evaluatedUsabilityRule = evaluatedUsabilityRule;
+        this.filteredNodes = nodesUnderEvaluation(taskTree);
+    }
+
+    protected abstract FilterStatistic nodesUnderEvaluation(ITaskTree taskTree);
+
+    @SuppressWarnings("rawtypes")
+    protected Optional<FilterStatistic> loadFromCache(TaskTreeNodeFilter nodeFilter) {
+        return FilterStatisticCache.instance().getFilterStatistic(nodeFilter);
+    }
+
+    @SuppressWarnings("rawtypes")
+    protected FilterStatistic cacheAndReturnNodes(ITaskTree taskTree, TaskTreeNodeFilter nodeFilter) {
+        FilterStatistic textInputEvents = extractNodesFromTaskTree(taskTree);
+        FilterStatisticCache.instance().addFilterStatistic(nodeFilter, textInputEvents);
+        return textInputEvents;
+    }
+
+    protected abstract FilterStatistic extractNodesFromTaskTree(ITaskTree taskTree);
+
+    public Optional<UsabilityDefect> evaluationResult() {
+        Optional<UsabilityDefect> ruleEvaluationResult = Optional.absent();
+        float evaluationMetric = calculateEvaluationMetric();
+        Optional<UsabilityDefectSeverityLevel> severityLevel =
+            determineSeverityLevel(evaluationMetric);
+        if (severityLevel.isPresent()) {
+            ruleEvaluationResult =
+                Optional.of(createRuleEvaluationResult(severityLevel.get()));
+        }
+        return ruleEvaluationResult;
+    }
+
+    protected abstract float calculateEvaluationMetric();
+
+    protected abstract Optional<UsabilityDefectSeverityLevel> determineSeverityLevel(float evaluationMetric);
+
+    public UsabilityDefect createRuleEvaluationResult(UsabilityDefectSeverityLevel severityLevelOfDefect) {
+        return new UsabilityDefectFactory(UsabilityDefectXmlDescriptionResolver.instance())
+            .createUsabilityGuidlineRecommendation(severityLevelOfDefect,
+                                                   evaluatedUsabilityRule,
+                                                   defectDescriptionMessageParameterValues);
+    }
+}
Index: autoquest-core-usability-evaluation/src/main/java/de/ugoe/cs/autoquest/usability/evaluation/rule/evaluator/TextInputEntryRepetitionsEvaluator.java
===================================================================
--- autoquest-core-usability-evaluation/src/main/java/de/ugoe/cs/autoquest/usability/evaluation/rule/evaluator/TextInputEntryRepetitionsEvaluator.java	(revision 1030)
+++ autoquest-core-usability-evaluation/src/main/java/de/ugoe/cs/autoquest/usability/evaluation/rule/evaluator/TextInputEntryRepetitionsEvaluator.java	(revision 1030)
@@ -0,0 +1,76 @@
+package de.ugoe.cs.autoquest.usability.evaluation.rule.evaluator;
+
+import static de.ugoe.cs.autoquest.usability.tasktree.filter.EventTypeFilter.TEXT_INPUT;
+import static de.ugoe.cs.autoquest.usability.util.TextInputUtil.aggregateEnteredTextFromTextInputs;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Predicate;
+import com.google.common.collect.Multiset;
+import com.google.common.collect.Multisets;
+
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTree;
+import de.ugoe.cs.autoquest.usability.evaluation.result.UsabilityDefectSeverityLevel;
+import de.ugoe.cs.autoquest.usability.evaluation.rule.set.UsabilityRule;
+import de.ugoe.cs.autoquest.usability.tasktree.filter.FilterStatistic;
+import de.ugoe.cs.autoquest.usability.tasktree.filter.IterativeDFSFilterStrategy;
+import de.ugoe.cs.autoquest.usability.tasktree.filter.TaskTreeFilter;
+
+public class TextInputEntryRepetitionsEvaluator extends RuleEvaluator {
+
+    public TextInputEntryRepetitionsEvaluator(UsabilityRule evaluatedUsabilityRule, ITaskTree taskTree) {
+        super(evaluatedUsabilityRule, taskTree);
+    }
+
+    @Override
+    protected FilterStatistic nodesUnderEvaluation(ITaskTree taskTree) {
+        Optional<FilterStatistic> cachedNodes = loadFromCache(TEXT_INPUT);
+        return cachedNodes.isPresent() ? cachedNodes.get() : cacheAndReturnNodes(taskTree, TEXT_INPUT);
+    }
+    
+    @Override
+    protected FilterStatistic extractNodesFromTaskTree(ITaskTree taskTree) {
+        return new TaskTreeFilter(new IterativeDFSFilterStrategy())
+            .filterByEventType(TEXT_INPUT).from(taskTree);
+    }
+
+    @Override
+    protected float calculateEvaluationMetric() {
+        Multiset<String> enteredTextFragments = aggregateEnteredTextFromTextInputs(this.filteredNodes.nodesMatchedFilter());
+        Multiset<String> orderedTextFragmentsWithMultipleOccurences = onlyTextFragmentsWithMultipleOccurences(enteredTextFragments);
+        if(orderedTextFragmentsWithMultipleOccurences.isEmpty()) return 0;
+        String wordWithHighestRepetitionInTextFragments = orderedTextFragmentsWithMultipleOccurences.iterator().next();
+        int numberOfRepeatedWords = orderedTextFragmentsWithMultipleOccurences.entrySet().size();
+        int maxRepetitions = orderedTextFragmentsWithMultipleOccurences.count(wordWithHighestRepetitionInTextFragments);
+        return Math.max(numberOfRepeatedWords, maxRepetitions);
+    }
+    
+    private Multiset<String> onlyTextFragmentsWithMultipleOccurences(final Multiset<String> allTextInputs) {
+        return Multisets.copyHighestCountFirst(Multisets.filter(allTextInputs, new Predicate<String>() {
+            
+            @Override
+            public boolean apply(String word) {
+                return allTextInputs.count(word) > 1;
+            }
+            
+        }));
+    }
+
+    @Override
+    protected Optional<UsabilityDefectSeverityLevel> determineSeverityLevel(float evaluationMetric) {
+        Optional<UsabilityDefectSeverityLevel> recommendationSeverityLevel = Optional.absent();
+        if (evaluationMetric > 10) {
+            recommendationSeverityLevel = Optional.of(UsabilityDefectSeverityLevel.HIGH);
+        }
+        else if (evaluationMetric > 4) {
+            recommendationSeverityLevel = Optional.of(UsabilityDefectSeverityLevel.MEDIUM);
+        }
+        else if (evaluationMetric > 2) {
+            recommendationSeverityLevel = Optional.of(UsabilityDefectSeverityLevel.LOW);
+        }
+        else if (evaluationMetric > 1) {
+            recommendationSeverityLevel = Optional.of(UsabilityDefectSeverityLevel.INFO);
+        }
+        return recommendationSeverityLevel;
+    }
+    
+}
Index: autoquest-core-usability-evaluation/src/main/java/de/ugoe/cs/autoquest/usability/evaluation/rule/evaluator/TextInputRatioEvaluator.java
===================================================================
--- autoquest-core-usability-evaluation/src/main/java/de/ugoe/cs/autoquest/usability/evaluation/rule/evaluator/TextInputRatioEvaluator.java	(revision 1030)
+++ autoquest-core-usability-evaluation/src/main/java/de/ugoe/cs/autoquest/usability/evaluation/rule/evaluator/TextInputRatioEvaluator.java	(revision 1030)
@@ -0,0 +1,71 @@
+package de.ugoe.cs.autoquest.usability.evaluation.rule.evaluator;
+
+import static de.ugoe.cs.autoquest.usability.tasktree.filter.EventTypeFilter.TEXT_INPUT;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Predicate;
+import com.google.common.collect.Iterables;
+
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTree;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeNode;
+import de.ugoe.cs.autoquest.usability.evaluation.result.UsabilityDefectSeverityLevel;
+import de.ugoe.cs.autoquest.usability.evaluation.rule.set.UsabilityRule;
+import de.ugoe.cs.autoquest.usability.tasktree.filter.FilterStatistic;
+import de.ugoe.cs.autoquest.usability.tasktree.filter.IterativeDFSFilterStrategy;
+import de.ugoe.cs.autoquest.usability.tasktree.filter.TaskTreeFilter;
+
+public class TextInputRatioEvaluator extends RuleEvaluator {
+
+    public TextInputRatioEvaluator(UsabilityRule evaluatedUsabilityRule, ITaskTree taskTree) {
+        super(evaluatedUsabilityRule, taskTree);
+    }
+
+    @Override
+    protected FilterStatistic nodesUnderEvaluation(ITaskTree taskTree) {
+        Optional<FilterStatistic> cachedNodes = loadFromCache(TEXT_INPUT);
+        return cachedNodes.isPresent() ? cachedNodes.get() : cacheAndReturnNodes(taskTree, TEXT_INPUT);
+    }
+
+    @Override
+    protected FilterStatistic extractNodesFromTaskTree(ITaskTree taskTree) {
+        return new TaskTreeFilter(new IterativeDFSFilterStrategy()).filterByEventType(TEXT_INPUT).from(taskTree);
+    }
+
+    @Override
+    protected float calculateEvaluationMetric() {
+        float textInputEvents = this.filteredNodes.nrOfNodesMatchedFilter();
+        float nonTextInputEvents = nrOfEventNodesNotMatchedFilter();
+        return textInputEvents / (textInputEvents + nonTextInputEvents);
+    }
+    
+    private int nrOfEventNodesNotMatchedFilter() {
+        return Iterables.size(
+            Iterables.filter(this.filteredNodes.nodesNotMatchedFilter(), new Predicate<ITaskTreeNode>() {
+            
+                @Override
+                public boolean apply(ITaskTreeNode node) {
+                    return  (node.getChildren() == null) || (node.getChildren().size() == 0);
+                }
+            })
+        );
+    }
+
+    @Override
+    protected Optional<UsabilityDefectSeverityLevel> determineSeverityLevel(float evaluationMetric) {
+        Optional<UsabilityDefectSeverityLevel> recommendationSeverityLevel = Optional.absent();
+        if (evaluationMetric > 0.9) {
+            recommendationSeverityLevel = Optional.of(UsabilityDefectSeverityLevel.HIGH);
+        }
+        else if (evaluationMetric > 0.7) {
+            recommendationSeverityLevel = Optional.of(UsabilityDefectSeverityLevel.MEDIUM);
+        }
+        else if (evaluationMetric > 0.5) {
+            recommendationSeverityLevel = Optional.of(UsabilityDefectSeverityLevel.LOW);
+        }
+        else if (evaluationMetric > 0.3) {
+            recommendationSeverityLevel = Optional.of(UsabilityDefectSeverityLevel.INFO);
+        }
+        return recommendationSeverityLevel;
+    }
+
+}
Index: autoquest-core-usability-evaluation/src/main/java/de/ugoe/cs/autoquest/usability/evaluation/rule/set/EmptyUsabilityRuleset.java
===================================================================
--- autoquest-core-usability-evaluation/src/main/java/de/ugoe/cs/autoquest/usability/evaluation/rule/set/EmptyUsabilityRuleset.java	(revision 1030)
+++ autoquest-core-usability-evaluation/src/main/java/de/ugoe/cs/autoquest/usability/evaluation/rule/set/EmptyUsabilityRuleset.java	(revision 1030)
@@ -0,0 +1,37 @@
+package de.ugoe.cs.autoquest.usability.evaluation.rule.set;
+
+import java.util.EnumSet;
+
+import org.apache.commons.lang.StringUtils;
+
+import com.google.common.base.Optional;
+
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTree;
+import de.ugoe.cs.autoquest.usability.evaluation.result.UsabilityDefect;
+
+public class EmptyUsabilityRuleset implements UsabilityRuleset {
+    
+    private enum EmptyUsabilityRule implements UsabilityRule {
+	;
+
+        @Override
+        public Optional<UsabilityDefect> evaluate(ITaskTree taskTree) {
+            return Optional.absent();
+        }
+
+        @Override
+        public String ruleIdentifier() {
+            return StringUtils.EMPTY;
+        }
+
+    }
+    
+    private final EnumSet<EmptyUsabilityRule> EMPTY_USABILITY_RULESET = 
+	    EnumSet.noneOf(EmptyUsabilityRule.class);
+
+    @Override
+    public EnumSet<? extends UsabilityRule> getRulesetForUsabilityEvaluation() {
+	return EMPTY_USABILITY_RULESET;
+    }
+
+}
Index: autoquest-core-usability-evaluation/src/main/java/de/ugoe/cs/autoquest/usability/evaluation/rule/set/MouseInteractionUsabilityRuleset.java
===================================================================
--- autoquest-core-usability-evaluation/src/main/java/de/ugoe/cs/autoquest/usability/evaluation/rule/set/MouseInteractionUsabilityRuleset.java	(revision 1030)
+++ autoquest-core-usability-evaluation/src/main/java/de/ugoe/cs/autoquest/usability/evaluation/rule/set/MouseInteractionUsabilityRuleset.java	(revision 1030)
@@ -0,0 +1,41 @@
+package de.ugoe.cs.autoquest.usability.evaluation.rule.set;
+
+import java.util.EnumSet;
+
+import com.google.common.base.Optional;
+
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTree;
+import de.ugoe.cs.autoquest.usability.evaluation.result.UsabilityDefect;
+
+public class MouseInteractionUsabilityRuleset implements UsabilityRuleset {
+
+    private enum MouseInteractionUsabilityRule implements UsabilityRule {
+        
+        MOUSE_INTERACTION {
+
+            @Override
+            public Optional<UsabilityDefect> evaluate(ITaskTree taskTree) {
+                // TODO Auto-generated method stub
+                System.out.println("TODO: implement MouseInteractionUsabilityRule.evaluate ");
+                return null;
+            }
+
+            @Override
+            public String ruleIdentifier() {
+                return this.name();
+            }
+            
+        };
+
+        public abstract Optional<UsabilityDefect> evaluate(ITaskTree taskTree);
+    }
+    
+    private final EnumSet<MouseInteractionUsabilityRule> MOUSE_INTERACTION_USABILITY_RULESET = EnumSet
+            .allOf(MouseInteractionUsabilityRule.class);
+    
+    @Override
+    public EnumSet<? extends UsabilityRule> getRulesetForUsabilityEvaluation() {
+        return MOUSE_INTERACTION_USABILITY_RULESET;
+    }
+
+}
Index: autoquest-core-usability-evaluation/src/main/java/de/ugoe/cs/autoquest/usability/evaluation/rule/set/RulesetFactory.java
===================================================================
--- autoquest-core-usability-evaluation/src/main/java/de/ugoe/cs/autoquest/usability/evaluation/rule/set/RulesetFactory.java	(revision 1030)
+++ autoquest-core-usability-evaluation/src/main/java/de/ugoe/cs/autoquest/usability/evaluation/rule/set/RulesetFactory.java	(revision 1030)
@@ -0,0 +1,20 @@
+package de.ugoe.cs.autoquest.usability.evaluation.rule.set;
+
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+public class RulesetFactory {
+    
+    public static EmptyUsabilityRuleset emptyUsabilityRuleset() {
+	return new EmptyUsabilityRuleset();
+    }
+    
+    public static TextInputUsabiliyRuleset textInputUsabiliyRuleset() {
+	return new TextInputUsabiliyRuleset();
+    }
+    
+    public static MouseInteractionUsabilityRuleset mouseInteractionUsabiliyRuleset() {
+        return new MouseInteractionUsabilityRuleset();
+    }
+}
Index: autoquest-core-usability-evaluation/src/main/java/de/ugoe/cs/autoquest/usability/evaluation/rule/set/TextInputUsabiliyRuleset.java
===================================================================
--- autoquest-core-usability-evaluation/src/main/java/de/ugoe/cs/autoquest/usability/evaluation/rule/set/TextInputUsabiliyRuleset.java	(revision 1030)
+++ autoquest-core-usability-evaluation/src/main/java/de/ugoe/cs/autoquest/usability/evaluation/rule/set/TextInputUsabiliyRuleset.java	(revision 1030)
@@ -0,0 +1,73 @@
+
+package de.ugoe.cs.autoquest.usability.evaluation.rule.set;
+
+import java.util.EnumSet;
+
+import com.google.common.base.Optional;
+
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTree;
+import de.ugoe.cs.autoquest.usability.evaluation.result.UsabilityDefect;
+import de.ugoe.cs.autoquest.usability.evaluation.rule.evaluator.NoLetterOrDigitTextInputsEvaluator;
+import de.ugoe.cs.autoquest.usability.evaluation.rule.evaluator.TextInputEntryRepetitionsEvaluator;
+import de.ugoe.cs.autoquest.usability.evaluation.rule.evaluator.TextInputRatioEvaluator;
+
+public class TextInputUsabiliyRuleset implements UsabilityRuleset {
+
+    private enum TextInputUsabilityRule implements UsabilityRule {
+
+        TEXT_FIELD_INPUT_RATIO {
+            
+            @Override
+            public Optional<UsabilityDefect> evaluate(ITaskTree taskTree) {
+                return new TextInputRatioEvaluator(this, taskTree).evaluationResult();
+            }
+
+            @Override
+            public String ruleIdentifier() {
+                return this.name();
+            }
+
+        },
+
+        TEXT_FIELD_INPUT_REPETITIONS {
+
+            @Override
+            public Optional<UsabilityDefect> evaluate(ITaskTree taskTree) {
+                return new TextInputEntryRepetitionsEvaluator(this, taskTree).evaluationResult();
+            }
+
+            @Override
+            public String ruleIdentifier() {
+                return this.name();
+            }
+
+        },
+
+        TEXT_FIELD_NO_LETTER_OR_DIGIT_RATIO {
+
+            @Override
+            public Optional<UsabilityDefect> evaluate(ITaskTree taskTree) {
+                return new NoLetterOrDigitTextInputsEvaluator(this, taskTree).evaluationResult();
+            }
+
+            @Override
+            public String ruleIdentifier() {
+                return this.name();
+            }
+
+
+        };
+        
+        public abstract Optional<UsabilityDefect> evaluate(ITaskTree taskTree);
+
+    }
+
+    private final EnumSet<TextInputUsabilityRule> TEXT_INPUT_USABILITY_RULESET = EnumSet
+        .allOf(TextInputUsabilityRule.class);
+
+    @Override
+    public EnumSet<? extends UsabilityRule> getRulesetForUsabilityEvaluation() {
+        return TEXT_INPUT_USABILITY_RULESET;
+    }
+
+}
Index: autoquest-core-usability-evaluation/src/main/java/de/ugoe/cs/autoquest/usability/evaluation/rule/set/UsabilityRule.java
===================================================================
--- autoquest-core-usability-evaluation/src/main/java/de/ugoe/cs/autoquest/usability/evaluation/rule/set/UsabilityRule.java	(revision 1030)
+++ autoquest-core-usability-evaluation/src/main/java/de/ugoe/cs/autoquest/usability/evaluation/rule/set/UsabilityRule.java	(revision 1030)
@@ -0,0 +1,14 @@
+package de.ugoe.cs.autoquest.usability.evaluation.rule.set;
+
+import com.google.common.base.Optional;
+
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTree;
+import de.ugoe.cs.autoquest.usability.evaluation.result.UsabilityDefect;
+
+public interface UsabilityRule {
+    
+    public String ruleIdentifier();
+    
+    public Optional<UsabilityDefect> evaluate(ITaskTree taskTree);
+
+}
Index: autoquest-core-usability-evaluation/src/main/java/de/ugoe/cs/autoquest/usability/evaluation/rule/set/UsabilityRuleset.java
===================================================================
--- autoquest-core-usability-evaluation/src/main/java/de/ugoe/cs/autoquest/usability/evaluation/rule/set/UsabilityRuleset.java	(revision 1030)
+++ autoquest-core-usability-evaluation/src/main/java/de/ugoe/cs/autoquest/usability/evaluation/rule/set/UsabilityRuleset.java	(revision 1030)
@@ -0,0 +1,10 @@
+package de.ugoe.cs.autoquest.usability.evaluation.rule.set;
+
+import java.util.EnumSet;
+
+
+public interface UsabilityRuleset {
+
+    public EnumSet<? extends UsabilityRule> getRulesetForUsabilityEvaluation();
+    
+}
Index: autoquest-core-usability-evaluation/src/main/java/de/ugoe/cs/autoquest/usability/tasktree/filter/EventTargetFilter.java
===================================================================
--- autoquest-core-usability-evaluation/src/main/java/de/ugoe/cs/autoquest/usability/tasktree/filter/EventTargetFilter.java	(revision 1030)
+++ autoquest-core-usability-evaluation/src/main/java/de/ugoe/cs/autoquest/usability/tasktree/filter/EventTargetFilter.java	(revision 1030)
@@ -0,0 +1,50 @@
+package de.ugoe.cs.autoquest.usability.tasktree.filter;
+
+import com.google.common.base.Function;
+import com.google.common.base.Predicate;
+import com.google.common.base.Predicates;
+
+import de.ugoe.cs.autoquest.eventcore.IEventTarget;
+import de.ugoe.cs.autoquest.eventcore.guimodel.ITextArea;
+import de.ugoe.cs.autoquest.eventcore.guimodel.ITextField;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.IEventTask;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeNode;
+
+public enum EventTargetFilter implements TaskTreeNodeFilter<IEventTarget> {
+
+    TEXT_FIELD(ITextField.class),
+    
+    TEXT_AREA(ITextArea.class);
+    
+    private Class<? extends IEventTarget> eventTargetClazz;
+    
+    private EventTargetFilter(Class<? extends IEventTarget> eventTargetClazz) {
+        this.eventTargetClazz = eventTargetClazz;
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public Class<IEventTarget> clazz() {
+        return (Class<IEventTarget>) eventTargetClazz;
+    }
+
+    @SuppressWarnings("rawtypes")
+    @Override
+    public Predicate filterPredicate() {
+        Predicate<Object> instanceOfIEventTaskPredicate = Predicates.instanceOf(IEventTask.class);
+        Predicate<ITaskTreeNode> nodeHoldsInstanceOfFilterArgument =
+            Predicates.compose(Predicates.instanceOf(eventTargetClazz), nodeExtractionFunction());
+        return Predicates.and(instanceOfIEventTaskPredicate, nodeHoldsInstanceOfFilterArgument);
+    }
+    
+    private Function<ITaskTreeNode, IEventTarget> nodeExtractionFunction() {
+        return new Function<ITaskTreeNode, IEventTarget>() {
+            
+            @Override
+            public IEventTarget apply(ITaskTreeNode treeNode) {
+                return ((IEventTask) treeNode).getEventTarget();
+            }
+        };
+    }
+    
+}
Index: autoquest-core-usability-evaluation/src/main/java/de/ugoe/cs/autoquest/usability/tasktree/filter/EventTypeFilter.java
===================================================================
--- autoquest-core-usability-evaluation/src/main/java/de/ugoe/cs/autoquest/usability/tasktree/filter/EventTypeFilter.java	(revision 1030)
+++ autoquest-core-usability-evaluation/src/main/java/de/ugoe/cs/autoquest/usability/tasktree/filter/EventTypeFilter.java	(revision 1030)
@@ -0,0 +1,52 @@
+package de.ugoe.cs.autoquest.usability.tasktree.filter;
+
+import com.google.common.base.Function;
+import com.google.common.base.Predicate;
+import com.google.common.base.Predicates;
+
+import de.ugoe.cs.autoquest.eventcore.IEventType;
+import de.ugoe.cs.autoquest.eventcore.gui.MouseButtonInteraction;
+import de.ugoe.cs.autoquest.eventcore.gui.MouseInteraction;
+import de.ugoe.cs.autoquest.eventcore.gui.TextInput;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.IEventTask;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeNode;
+
+public enum EventTypeFilter implements TaskTreeNodeFilter<IEventType> {
+    
+    TEXT_INPUT(TextInput.class),
+    
+    MOUSE_INTERACTION(MouseInteraction.class),
+    
+    MOUSE_BUTTON_INTERACTION(MouseButtonInteraction.class);
+    
+    private Class<? extends IEventType> eventTypeClazz;
+    
+    private EventTypeFilter(Class<? extends IEventType> eventTypeClazz) {
+        this.eventTypeClazz = eventTypeClazz;
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public Class<IEventType> clazz() {
+        return (Class<IEventType>) eventTypeClazz;
+    }
+    
+    @SuppressWarnings("rawtypes")
+    @Override
+    public Predicate filterPredicate() {
+        Predicate<Object> instanceOfIEventTaskPredicate = Predicates.instanceOf(IEventTask.class);
+        Predicate<ITaskTreeNode> nodeHoldsInstanceOfFilterArgument =
+            Predicates.compose(Predicates.instanceOf(eventTypeClazz), nodeExtractionFunction());
+        return Predicates.and(instanceOfIEventTaskPredicate, nodeHoldsInstanceOfFilterArgument);
+    }
+    
+    private Function<ITaskTreeNode, IEventType> nodeExtractionFunction() {
+        return new Function<ITaskTreeNode, IEventType>() {
+            
+            @Override
+            public IEventType apply(ITaskTreeNode treeNode) {
+                return ((IEventTask) treeNode).getEventType();
+            }
+        };
+    }
+    }
Index: autoquest-core-usability-evaluation/src/main/java/de/ugoe/cs/autoquest/usability/tasktree/filter/FilterStatistic.java
===================================================================
--- autoquest-core-usability-evaluation/src/main/java/de/ugoe/cs/autoquest/usability/tasktree/filter/FilterStatistic.java	(revision 1030)
+++ autoquest-core-usability-evaluation/src/main/java/de/ugoe/cs/autoquest/usability/tasktree/filter/FilterStatistic.java	(revision 1030)
@@ -0,0 +1,49 @@
+package de.ugoe.cs.autoquest.usability.tasktree.filter;
+
+import java.util.List;
+
+import com.google.common.base.Predicate;
+import com.google.common.collect.Lists;
+
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeNode;
+
+public class FilterStatistic {
+    
+    @SuppressWarnings("rawtypes")
+    private final Predicate filterPredicate;
+
+    private List<ITaskTreeNode> filteredNodes = Lists.newArrayList();
+    
+    private List<ITaskTreeNode> nodesNotMatchedFilter = Lists.newArrayList();
+    
+    @SuppressWarnings("rawtypes")
+    public FilterStatistic(Predicate filterPredicate) {
+        this.filterPredicate = filterPredicate;
+    }
+    
+    @SuppressWarnings("unchecked")
+    public void addNode(ITaskTreeNode node) {
+        if (filterPredicate.apply(node)) {
+            filteredNodes.add(node);
+        } else {
+            nodesNotMatchedFilter.add(node);
+        }
+    }
+    
+    public List<ITaskTreeNode> nodesMatchedFilter() {
+        return this.filteredNodes;
+    }
+    
+    public int nrOfNodesMatchedFilter() {
+        return this.filteredNodes.size();
+    }
+    
+    public List<ITaskTreeNode> nodesNotMatchedFilter() {
+        return this.nodesNotMatchedFilter;
+    }
+    
+    public int nrOfNodesNotMatchedFilter() {
+        return this.nodesNotMatchedFilter.size();
+    }
+    
+}
Index: autoquest-core-usability-evaluation/src/main/java/de/ugoe/cs/autoquest/usability/tasktree/filter/FilterStatisticCache.java
===================================================================
--- autoquest-core-usability-evaluation/src/main/java/de/ugoe/cs/autoquest/usability/tasktree/filter/FilterStatisticCache.java	(revision 1030)
+++ autoquest-core-usability-evaluation/src/main/java/de/ugoe/cs/autoquest/usability/tasktree/filter/FilterStatisticCache.java	(revision 1030)
@@ -0,0 +1,38 @@
+package de.ugoe.cs.autoquest.usability.tasktree.filter;
+
+import java.util.concurrent.TimeUnit;
+
+import com.google.common.base.Optional;
+import com.google.common.cache.Cache;
+import com.google.common.cache.CacheBuilder;
+
+public class FilterStatisticCache {
+
+    private static final FilterStatisticCache instance = new FilterStatisticCache();
+    
+    @SuppressWarnings("rawtypes")
+    private Cache<TaskTreeNodeFilter, FilterStatistic> cache;
+    
+    private FilterStatisticCache() {
+        this.cache = CacheBuilder.newBuilder().expireAfterWrite(10, TimeUnit.MINUTES).build();
+    }
+    
+    public static FilterStatisticCache instance() {
+        return instance;
+    }
+    
+    @SuppressWarnings("rawtypes")
+    public void addFilterStatistic(TaskTreeNodeFilter nodeFilter, FilterStatistic filterStatistic) {
+        this.cache.put(nodeFilter, filterStatistic);
+    }
+    
+    @SuppressWarnings("rawtypes")
+    public Optional<FilterStatistic> getFilterStatistic(TaskTreeNodeFilter nodeFilter) {
+        return Optional.fromNullable(this.cache.getIfPresent(nodeFilter));
+    }
+    
+    public void clear() {
+        this.cache.invalidateAll();
+    }
+    
+}
Index: autoquest-core-usability-evaluation/src/main/java/de/ugoe/cs/autoquest/usability/tasktree/filter/IterativeDFSFilterStrategy.java
===================================================================
--- autoquest-core-usability-evaluation/src/main/java/de/ugoe/cs/autoquest/usability/tasktree/filter/IterativeDFSFilterStrategy.java	(revision 1030)
+++ autoquest-core-usability-evaluation/src/main/java/de/ugoe/cs/autoquest/usability/tasktree/filter/IterativeDFSFilterStrategy.java	(revision 1030)
@@ -0,0 +1,59 @@
+package de.ugoe.cs.autoquest.usability.tasktree.filter;
+
+import java.util.Stack;
+
+import com.google.common.base.Predicate;
+
+import de.ugoe.cs.autoquest.eventcore.IEventTarget;
+import de.ugoe.cs.autoquest.eventcore.IEventType;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTree;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeNode;
+
+public class IterativeDFSFilterStrategy implements TaskTreeFilterStrategy {
+    
+    private FilterStatistic filterStatistic;
+    
+    @SuppressWarnings("unchecked")
+    @Override
+    public FilterStatistic filter(ITaskTree taskTree, EventTargetFilter eventTarget) {
+        Predicate<IEventTarget> filterPredicate = eventTarget.filterPredicate();
+        this.filterStatistic = new FilterStatistic(filterPredicate);
+        traverse(taskTree);
+        return this.filterStatistic;
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public FilterStatistic filter(ITaskTree taskTree, EventTypeFilter eventType) {
+        Predicate<IEventType> filterPredicate = eventType.filterPredicate();
+        this.filterStatistic = new FilterStatistic(filterPredicate);
+        traverse(taskTree);
+        return this.filterStatistic;
+    }
+    
+    private void traverse(ITaskTree taskTree) {
+        Stack<ITaskTreeNode> unvisitedNodes = new Stack<ITaskTreeNode>();
+        unvisitedNodes.push(taskTree.getRoot());
+        while(stillUnvisitedNodes(unvisitedNodes)) {
+            ITaskTreeNode node = unvisitedNodes.pop();
+            processCurrentNode(node);
+            processChildrenOfCurrentNode(unvisitedNodes, node);
+        }
+    }
+
+    private boolean stillUnvisitedNodes(Stack<ITaskTreeNode> unvisitedNodes) {
+        return !unvisitedNodes.isEmpty();
+    }
+
+    private void processCurrentNode(ITaskTreeNode node) {
+        this.filterStatistic.addNode(node);
+    }
+    
+    private void processChildrenOfCurrentNode(Stack<ITaskTreeNode> unvisitedNodes,
+                                              ITaskTreeNode node) {
+        for(ITaskTreeNode child : node.getChildren()) {
+            unvisitedNodes.push(child);
+        }
+    }
+
+}
Index: autoquest-core-usability-evaluation/src/main/java/de/ugoe/cs/autoquest/usability/tasktree/filter/TaskTreeFilter.java
===================================================================
--- autoquest-core-usability-evaluation/src/main/java/de/ugoe/cs/autoquest/usability/tasktree/filter/TaskTreeFilter.java	(revision 1030)
+++ autoquest-core-usability-evaluation/src/main/java/de/ugoe/cs/autoquest/usability/tasktree/filter/TaskTreeFilter.java	(revision 1030)
@@ -0,0 +1,52 @@
+
+package de.ugoe.cs.autoquest.usability.tasktree.filter;
+
+import com.google.common.base.Preconditions;
+
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTree;
+
+public class TaskTreeFilter {
+    
+    private final TaskTreeFilterStrategy taskTreeFilterStrategy;
+    
+    public TaskTreeFilter(TaskTreeFilterStrategy treeTraversalStrategy) {
+        Preconditions.checkNotNull(treeTraversalStrategy);
+        this.taskTreeFilterStrategy = treeTraversalStrategy;
+    }
+
+    public FilterEventTargetStep filterByEventTarget(EventTargetFilter eventTarget) {
+        return new FilterEventTargetStep(eventTarget);
+    }
+
+    public FilterEventTypeStep filterByEventType(EventTypeFilter eventType) {
+        return new FilterEventTypeStep(eventType);
+    }
+
+    public class FilterEventTargetStep {
+
+        private final EventTargetFilter eventTarget;
+
+        public FilterEventTargetStep(EventTargetFilter eventTarget) {
+            this.eventTarget = eventTarget;
+        }
+
+        public FilterStatistic from(ITaskTree taskTree) {
+            return taskTreeFilterStrategy.filter(taskTree, eventTarget);
+        }
+
+    }
+
+    public class FilterEventTypeStep {
+
+        private final EventTypeFilter eventType;
+
+        public FilterEventTypeStep(EventTypeFilter eventType) {
+            this.eventType = eventType;
+        }
+
+        public FilterStatistic from(ITaskTree taskTree) {
+            return taskTreeFilterStrategy.filter(taskTree, eventType);
+        }
+
+    }
+}
Index: autoquest-core-usability-evaluation/src/main/java/de/ugoe/cs/autoquest/usability/tasktree/filter/TaskTreeFilterStrategy.java
===================================================================
--- autoquest-core-usability-evaluation/src/main/java/de/ugoe/cs/autoquest/usability/tasktree/filter/TaskTreeFilterStrategy.java	(revision 1030)
+++ autoquest-core-usability-evaluation/src/main/java/de/ugoe/cs/autoquest/usability/tasktree/filter/TaskTreeFilterStrategy.java	(revision 1030)
@@ -0,0 +1,11 @@
+package de.ugoe.cs.autoquest.usability.tasktree.filter;
+
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTree;
+
+public interface TaskTreeFilterStrategy {
+
+    public FilterStatistic filter(ITaskTree taskTree, EventTargetFilter eventTarget);
+
+    public FilterStatistic filter(ITaskTree taskTree, EventTypeFilter eventType);
+  
+}
Index: autoquest-core-usability-evaluation/src/main/java/de/ugoe/cs/autoquest/usability/tasktree/filter/TaskTreeNodeFilter.java
===================================================================
--- autoquest-core-usability-evaluation/src/main/java/de/ugoe/cs/autoquest/usability/tasktree/filter/TaskTreeNodeFilter.java	(revision 1030)
+++ autoquest-core-usability-evaluation/src/main/java/de/ugoe/cs/autoquest/usability/tasktree/filter/TaskTreeNodeFilter.java	(revision 1030)
@@ -0,0 +1,12 @@
+package de.ugoe.cs.autoquest.usability.tasktree.filter;
+
+import com.google.common.base.Predicate;
+
+public interface TaskTreeNodeFilter<T> {
+
+    public Class<T> clazz();
+    
+    @SuppressWarnings("rawtypes")
+    public Predicate filterPredicate();
+    
+}
Index: autoquest-core-usability-evaluation/src/main/java/de/ugoe/cs/autoquest/usability/util/TextInputUtil.java
===================================================================
--- autoquest-core-usability-evaluation/src/main/java/de/ugoe/cs/autoquest/usability/util/TextInputUtil.java	(revision 1030)
+++ autoquest-core-usability-evaluation/src/main/java/de/ugoe/cs/autoquest/usability/util/TextInputUtil.java	(revision 1030)
@@ -0,0 +1,58 @@
+package de.ugoe.cs.autoquest.usability.util;
+
+import java.util.List;
+
+import com.google.common.base.CharMatcher;
+import com.google.common.base.Predicate;
+import com.google.common.base.Splitter;
+import com.google.common.collect.HashMultiset;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Multiset;
+
+import de.ugoe.cs.autoquest.eventcore.gui.TextInput;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.IEventTask;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeNode;
+
+public class TextInputUtil {
+    
+    public static Multiset<String> aggregateEnteredTextFromTextInputs(List<ITaskTreeNode> nodesWithTextInputEvents) {
+        List<Iterable<String>> allTextInputs = Lists.newArrayList();
+        for(ITaskTreeNode nodeWithTextInput : nodesWithTextInputEvents) {
+            TextInput textInput = (TextInput) ((IEventTask) nodeWithTextInput).getEventType();
+            allTextInputs.add(splitTextIntoWordsAnsSigns(textInput.getEnteredText()));
+        }
+        return HashMultiset.create(Iterables.concat(allTextInputs));
+    }
+    
+    public static Iterable<String> splitTextIntoWordsAnsSigns(String enteredText) {
+        CharMatcher onlyWords = CharMatcher.WHITESPACE.or(CharMatcher.forPredicate(characterIsJavaIdentifierPartPredicate()));
+        CharMatcher onlySigns = CharMatcher.WHITESPACE.or(CharMatcher.forPredicate(characterIsJavaIdentifierPartPredicate()).negate());
+        Iterable<String> words = Splitter.on(onlyWords).omitEmptyStrings().trimResults().split(enteredText);
+        Iterable<String> signs = Splitter.on(onlySigns).omitEmptyStrings().trimResults().split(enteredText);
+        return Iterables.concat(words, signs);
+    }
+    
+    public static Predicate<Character> characterIsJavaIdentifierPartPredicate() {
+        return new Predicate<Character>() {
+            
+            @Override
+            public boolean apply(Character character) {
+               return  !Character.isJavaIdentifierPart(character);
+            }
+            
+        };
+    }
+    
+    public static Predicate<Character> characterIsLetterOrDigitPredicate() {
+        return new Predicate<Character>() {
+            
+            @Override
+            public boolean apply(Character character) {
+                return !Character.isLetterOrDigit(character);
+            }
+            
+        };
+    }
+
+}
Index: autoquest-core-usability-evaluation/src/main/resources/defectDescriptions.xsd
===================================================================
--- autoquest-core-usability-evaluation/src/main/resources/defectDescriptions.xsd	(revision 1030)
+++ autoquest-core-usability-evaluation/src/main/resources/defectDescriptions.xsd	(revision 1030)
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsd:schema
+  targetNamespace="http://quest"
+  xmlns:tns="http://quest"
+  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+  xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
+  jxb:version="2.0"
+  elementFormDefault="qualified">
+  
+  <xsd:element name="defectDescriptions" type="tns:DefectDescriptions" />
+
+  <xsd:complexType name="DefectDescriptions">
+    <xsd:sequence>
+      <xsd:element name="defectDescription" type="tns:DefectDescription" maxOccurs="unbounded" />
+    </xsd:sequence>
+  </xsd:complexType>
+
+  <xsd:complexType name="DefectDescription">
+    <xsd:choice maxOccurs="unbounded">
+      <xsd:element name="textFragment" type="tns:SimpleFragment" />
+      <xsd:element name="parameterFragment" type="tns:ParameterFragment" />
+    </xsd:choice>
+    <xsd:attribute name="defectId" type="xsd:string" use="required" />
+  </xsd:complexType>
+
+  <xsd:simpleType name="SimpleFragment">
+    <xsd:restriction base="xsd:string"/>
+  </xsd:simpleType>
+
+  <xsd:complexType name="ParameterFragment">
+    <xsd:attribute name="parameterName" use="required" type="xsd:string" />
+  </xsd:complexType>
+
+</xsd:schema>
Index: autoquest-core-usability-evaluation/src/main/resources/defectDescriptions_en.xml
===================================================================
--- autoquest-core-usability-evaluation/src/main/resources/defectDescriptions_en.xml	(revision 1030)
+++ autoquest-core-usability-evaluation/src/main/resources/defectDescriptions_en.xml	(revision 1030)
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<defectDescriptions
+  xmlns="http://quest"
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://quest defectDescriptions.xsd">
+  
+  <defectDescription defectId="TEXT_FIELD_INPUT_RATIO">
+    <textFragment>
+      The ratio of interactions that enter text into text fields is relatively high in comparison
+      with the other user interactions (
+    </textFragment>
+    <parameterFragment parameterName="textInputRatio" />
+    <textFragment>
+      ). This should be reduced. As an example, entering data can also be done using check boxes
+      or combo boxes in the case predefined values must be entered.
+    </textFragment>
+  </defectDescription>
+  
+  <defectDescription defectId="TEXT_FIELD_INPUT_REPETITIONS">
+    <textFragment>
+      Several interactions that enter text into text fields repeat tokens such as words or
+      specific signs (
+    </textFragment>
+    <parameterFragment parameterName="textRepetitionRatio" />
+    <textFragment>
+      ). This is an indicator that the same data must be entered several times. This could be
+      better supported by using e.g. automatic filling of input fields, provision of combo
+      boxes or lists prefilled with data that was already entered previously. 
+    </textFragment>
+  </defectDescription>
+  
+  <defectDescription defectId="TEXT_FIELD_NO_LETTER_OR_DIGIT_RATIO">
+    <textFragment>
+      Much of the text entered into text fields contains signs other than letters or digits (
+    </textFragment>
+    <parameterFragment parameterName="noLetterOrDigitRatio" />
+    <textFragment>
+      ). This is an indicator that the entered data has to follow a specific syntax. This should
+      be supported by syntax checking, auto completion or even providing the text fields in a way
+      that does not require the entering of special signs as they are already included at the right
+      positions.
+    </textFragment>
+  </defectDescription>
+</defectDescriptions>
