Index: /trunk/autoquest-core-usability-evaluation-test/src/main/java/de/ugoe/cs/autoquest/usability/CMDperformUsabilityEvaluationTest.java
===================================================================
--- /trunk/autoquest-core-usability-evaluation-test/src/main/java/de/ugoe/cs/autoquest/usability/CMDperformUsabilityEvaluationTest.java	(revision 1141)
+++ /trunk/autoquest-core-usability-evaluation-test/src/main/java/de/ugoe/cs/autoquest/usability/CMDperformUsabilityEvaluationTest.java	(revision 1141)
@@ -0,0 +1,110 @@
+//   Copyright 2012 Georg-August-Universität Göttingen, Germany
+//
+//   Licensed under the Apache License, Version 2.0 (the "License");
+//   you may not use this file except in compliance with the License.
+//   You may obtain a copy of the License at
+//
+//       http://www.apache.org/licenses/LICENSE-2.0
+//
+//   Unless required by applicable law or agreed to in writing, software
+//   distributed under the License is distributed on an "AS IS" BASIS,
+//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//   See the License for the specific language governing permissions and
+//   limitations under the License.
+
+package de.ugoe.cs.autoquest.usability;
+
+import static org.fest.assertions.api.Assertions.assertThat;
+
+import java.util.List;
+
+import org.junit.Test;
+
+import com.google.common.base.Optional;
+import com.google.common.collect.Lists;
+
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTree;
+import de.ugoe.cs.autoquest.usability.rules.UsabilityResult;
+import de.ugoe.cs.autoquest.usability.testutil.GenerateTaskTreeUtil;
+import de.ugoe.cs.util.console.GlobalDataContainer;
+
+/**
+ * <p>
+ * TODO comment
+ * </p>
+ * 
+ * @author Alexander Deicke
+ */
+public class CMDperformUsabilityEvaluationTest {
+
+    /**
+     * Test method for {@link de.ugoe.cs.autoquest.usability.CMDperformUsabilityEvaluation#run(java.util.List)}.
+     */
+    @Test(expected = IllegalArgumentException.class)
+    public void run_without_parameter_set() {
+        new CMDperformUsabilityEvaluation().run(Lists.newArrayList());
+    }
+    
+    /**
+     * Test method for {@link de.ugoe.cs.autoquest.usability.CMDperformUsabilityEvaluation#run(java.util.List)}.
+     */
+    public void run_without_evaluation_result_parameter_set_and_no_task_tree_in_data_container() {
+        List<?> parameters = Lists.newArrayList("taskTree");
+        new CMDperformUsabilityEvaluation().run((List<Object>) parameters);
+        assertThat(getUsabilityEvaluationResult("usabilityEvaluationResult").isPresent()).isFalse();
+    }
+
+    private Optional<UsabilityResult> getUsabilityEvaluationResult(String evaluationResultParameter) {
+        UsabilityResult result = (UsabilityResult) GlobalDataContainer.getInstance().getData(evaluationResultParameter);
+        return Optional.fromNullable(result);
+    }
+    
+    /**
+     * Test method for {@link de.ugoe.cs.autoquest.usability.CMDperformUsabilityEvaluation#run(java.util.List)}.
+     */
+    @Test
+    public void run_with_all_parameter_set_and_no_task_tree_in_data_container() {
+        List<?> parameters = Lists.newArrayList("taskTree", "evaluationResult");
+        new CMDperformUsabilityEvaluation().run((List<Object>) parameters);
+        assertThat(getUsabilityEvaluationResult("evaluationResult").isPresent()).isFalse();
+
+    }
+    
+    /**
+     * Test method for {@link de.ugoe.cs.autoquest.usability.CMDperformUsabilityEvaluation#run(java.util.List)}.
+     */
+    @Test
+    public void run_with_more_parameter_set_and_no_task_tree_in_data_container() {
+        List<?> parameters = Lists.newArrayList("taskTree", "evaluationResult", "dummyParameter");
+        new CMDperformUsabilityEvaluation().run((List<Object>) parameters);
+        assertThat(getUsabilityEvaluationResult("evaluationResult")).isNotNull();
+
+    }
+    
+    /**
+     * Test method for {@link de.ugoe.cs.autoquest.usability.CMDperformUsabilityEvaluation#run(java.util.List)}.
+     */
+    @Test
+    public void run_with_all_parameter_set_and_task_tree_in_data_container() {
+        String spec = "EventTask target1 {}";
+        storeInDataContainer(GenerateTaskTreeUtil.getTaskTreeFromSpec(spec));
+        List<?> parameters = Lists.newArrayList("taskTree", "evaluationResult");
+        new CMDperformUsabilityEvaluation().run((List<Object>) parameters);
+        assertThat(getUsabilityEvaluationResult("evaluationResult").isPresent()).isTrue();
+
+    }
+
+    private void storeInDataContainer(ITaskTree taskTree) {
+        GlobalDataContainer.getInstance().addData("taskTree", taskTree);
+    }
+    
+    /**
+     * Test method for {@link de.ugoe.cs.autoquest.usability.CMDperformUsabilityEvaluation#help()}.
+     */
+    @Test
+    public void print_help_text() {
+        String helpText = new CMDperformUsabilityEvaluation().help();
+        assertThat(helpText).isEqualToIgnoringCase("peformUsabilityEvaluation <taskTree> {evaluationResult}");
+    }
+
+}
Index: /trunk/autoquest-core-usability-evaluation-test/src/main/java/de/ugoe/cs/autoquest/usability/rules/metrics/AbstractUsabilityEvaluationTC.java
===================================================================
--- /trunk/autoquest-core-usability-evaluation-test/src/main/java/de/ugoe/cs/autoquest/usability/rules/metrics/AbstractUsabilityEvaluationTC.java	(revision 1141)
+++ /trunk/autoquest-core-usability-evaluation-test/src/main/java/de/ugoe/cs/autoquest/usability/rules/metrics/AbstractUsabilityEvaluationTC.java	(revision 1141)
@@ -0,0 +1,227 @@
+//   Copyright 2012 Georg-August-Universität Göttingen, Germany
+//
+//   Licensed under the Apache License, Version 2.0 (the "License");
+//   you may not use this file except in compliance with the License.
+//   You may obtain a copy of the License at
+//
+//       http://www.apache.org/licenses/LICENSE-2.0
+//
+//   Unless required by applicable law or agreed to in writing, software
+//   distributed under the License is distributed on an "AS IS" BASIS,
+//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//   See the License for the specific language governing permissions and
+//   limitations under the License.
+
+package de.ugoe.cs.autoquest.usability.rules.metrics;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import java.util.ArrayList;
+import java.util.logging.Level;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.junit.Before;
+
+import de.ugoe.cs.autoquest.eventcore.Event;
+import de.ugoe.cs.autoquest.eventcore.gui.TextInput;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.IEventTask;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.IIteration;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ISelection;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ISequence;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTree;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeBuilder;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeNode;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeNodeFactory;
+import de.ugoe.cs.autoquest.tasktrees.treeimpl.TaskTreeBuilder;
+import de.ugoe.cs.autoquest.tasktrees.treeimpl.TaskTreeNodeFactory;
+import de.ugoe.cs.autoquest.test.DummyGUIElement;
+import de.ugoe.cs.autoquest.test.DummyInteraction;
+import de.ugoe.cs.autoquest.test.DummyTextField;
+import de.ugoe.cs.autoquest.usability.UsabilityDefect;
+import de.ugoe.cs.autoquest.usability.UsabilityEvaluationResult;
+import de.ugoe.cs.util.console.TextConsole;
+
+/**
+ * TODO comment
+ * 
+ * @version $Revision: $ $Date: 18.07.2012$
+ * @author 2012, last modified by $Author: pharms$
+ */
+public class AbstractUsabilityEvaluationTC {
+
+    /** */
+    private ITaskTreeBuilder taskTreeBuilder = new TaskTreeBuilder();
+
+    /** */
+    private ITaskTreeNodeFactory taskTreeNodeFactory = new TaskTreeNodeFactory();
+
+    /**
+   *
+   */
+    @Before
+    public void setUp() {
+        new TextConsole(Level.FINEST);
+    }
+
+    /**
+   *
+   */
+    protected ITaskTree createTaskTree(String spec) {
+        Matcher matcher =
+            Pattern.compile("(\\s*(\\w+)\\s*(\\(((\\w*\\s*)*)\\))?\\s*(\\{))|(\\})").matcher(spec);
+
+        if (!matcher.find()) {
+            if (!matcher.hitEnd()) {
+                throw new IllegalArgumentException("could not parse task specification");
+            }
+        }
+
+        return taskTreeNodeFactory.createTaskTree(parseTask(matcher, new int[1]));
+    }
+
+    /**
+     * TODO: comment
+     * 
+     * @param expectedDefects
+     * @param evaluateUsability
+     */
+    protected void assertUsabilityEvaluationResult(UsabilityDefect[] expectedDefects,
+                                                   UsabilityEvaluationResult evaluationResult)
+    {
+        assertEquals(expectedDefects.length, evaluationResult.getAllDefects().size());
+
+        EXPECTED_DEFECT_ITERATION: for (UsabilityDefect expectedDefect : expectedDefects) {
+            for (UsabilityDefect defect : evaluationResult.getAllDefects()) {
+                if (expectedDefect.equals(defect)) {
+                    System.err.println(defect.getParameterizedDescription());
+                    continue EXPECTED_DEFECT_ITERATION;
+                }
+            }
+
+            for (UsabilityDefect defect : evaluationResult.getAllDefects()) {
+                System.err.println(defect);
+            }
+
+            fail("expected defect " + expectedDefect + " not found in evaluation result");
+        }
+    }
+
+    /**
+   * 
+   */
+    private ITaskTreeNode parseTask(Matcher tokenMatcher, int[] typeNumbers) {
+        String firstToken = tokenMatcher.group();
+
+        if ("}".equals(firstToken)) {
+            throw new IllegalArgumentException("found a closing bracket at an unexpected place");
+        }
+
+        ITaskTreeNode treeNode = instantiateTreeNode(tokenMatcher, typeNumbers);
+
+        if (!tokenMatcher.find()) {
+            throw new IllegalArgumentException("could not parse task specification");
+        }
+
+        firstToken = tokenMatcher.group();
+
+        if (!"}".equals(firstToken)) {
+            ITaskTreeNode child = null;
+
+            do {
+                child = parseTask(tokenMatcher, typeNumbers);
+
+                if (child != null) {
+                    addChild(treeNode, child);
+
+                    if (!tokenMatcher.find()) {
+                        throw new IllegalArgumentException("could not parse task specification");
+                    }
+
+                    firstToken = tokenMatcher.group();
+
+                    if ("}".equals(firstToken)) {
+                        break;
+                    }
+                }
+
+            }
+            while (child != null);
+
+        }
+
+        return treeNode;
+    }
+
+    /**
+     * TODO: comment
+     * 
+     * @param group
+     * @return
+     */
+    private ITaskTreeNode instantiateTreeNode(Matcher tokenMatcher, int[] typeNumbers) {
+        String type = tokenMatcher.group(2);
+        String additionalInfo = tokenMatcher.group(4);
+
+        if ("Interaction".equals(type)) {
+            return taskTreeNodeFactory.createNewEventTask(new DummyInteraction("dummy",
+                                                                               typeNumbers[0]++),
+                                                          new DummyGUIElement("dummy"));
+        }
+        else if ("Sequence".equals(type)) {
+            return taskTreeNodeFactory.createNewSequence();
+        }
+        else if ("Iteration".equals(type)) {
+            return taskTreeNodeFactory.createNewIteration();
+        }
+        else if ("Selection".equals(type)) {
+            return taskTreeNodeFactory.createNewSelection();
+        }
+        else if ("TextInput".equals(type)) {
+            if (additionalInfo == null) {
+                fail("no simulated text provided for text input interactin task");
+            }
+
+            TextInput textInput = new TextInput(additionalInfo, new ArrayList<Event>());
+
+            IEventTask task =
+                taskTreeNodeFactory.createNewEventTask(textInput,
+                                                       new DummyTextField(additionalInfo));
+
+            return task;
+        }
+        else {
+            fail("invalid type of task tree node: " + type);
+            return null;
+        }
+    }
+
+    /**
+     * TODO: comment
+     * 
+     * @param treeNode
+     * @param child
+     */
+    private void addChild(ITaskTreeNode parent, ITaskTreeNode child) {
+        if (parent instanceof ISequence) {
+            taskTreeBuilder.addChild((ISequence) parent, child);
+        }
+        else if (parent instanceof IIteration) {
+            if (parent.getChildren().size() <= 0) {
+                taskTreeBuilder.setChild((IIteration) parent, child);
+            }
+            else {
+                fail("can not add more than one child to an iteration");
+            }
+        }
+        else if (parent instanceof ISelection) {
+            taskTreeBuilder.addChild((ISelection) parent, child);
+        }
+        else {
+            fail("can not add children to parent task tree node of type " +
+                parent.getClass().getName());
+        }
+    }
+
+}
Index: /trunk/autoquest-core-usability-evaluation-test/src/main/java/de/ugoe/cs/autoquest/usability/rules/metrics/NoLetterOrDigitTextInputsEvaluatorTest.java
===================================================================
--- /trunk/autoquest-core-usability-evaluation-test/src/main/java/de/ugoe/cs/autoquest/usability/rules/metrics/NoLetterOrDigitTextInputsEvaluatorTest.java	(revision 1141)
+++ /trunk/autoquest-core-usability-evaluation-test/src/main/java/de/ugoe/cs/autoquest/usability/rules/metrics/NoLetterOrDigitTextInputsEvaluatorTest.java	(revision 1141)
@@ -0,0 +1,109 @@
+//   Copyright 2012 Georg-August-Universität Göttingen, Germany
+//
+//   Licensed under the Apache License, Version 2.0 (the "License");
+//   you may not use this file except in compliance with the License.
+//   You may obtain a copy of the License at
+//
+//       http://www.apache.org/licenses/LICENSE-2.0
+//
+//   Unless required by applicable law or agreed to in writing, software
+//   distributed under the License is distributed on an "AS IS" BASIS,
+//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//   See the License for the specific language governing permissions and
+//   limitations under the License.
+
+package de.ugoe.cs.autoquest.usability.rules.metrics;
+
+import static de.ugoe.cs.autoquest.usability.testutil.FestConditionUtil.absent;
+import static de.ugoe.cs.autoquest.usability.testutil.FestConditionUtil.highRecommendationSeverityLevel;
+import static de.ugoe.cs.autoquest.usability.testutil.FestConditionUtil.infoRecommendationSeverityLevel;
+import static de.ugoe.cs.autoquest.usability.testutil.FestConditionUtil.lowRecommendationSeverityLevel;
+import static de.ugoe.cs.autoquest.usability.testutil.FestConditionUtil.mediumRecommendationSeverityLevel;
+import static de.ugoe.cs.autoquest.usability.testutil.FestConditionUtil.present;
+import static org.fest.assertions.api.Assertions.assertThat;
+
+import org.junit.Test;
+
+import com.google.common.base.Optional;
+
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTree;
+import de.ugoe.cs.autoquest.usability.result.UsabilityDefect;
+import de.ugoe.cs.autoquest.usability.rules.metrics.NoLetterOrDigitRatioMetric;
+
+/**
+ * <p>
+ * TODO comment
+ * </p>
+ * 
+ * @author Alexander Deicke
+ */
+public class NoLetterOrDigitTextInputsEvaluatorTest extends AbstractUsabilityEvaluationTC {
+
+    @Test
+    public void should_return_no_recommendation() {
+        // Given
+        String spec = "Sequence {" + 
+                      "  TextInput () {}" + 
+                      "}";
+        ITaskTree taskTree = createTaskTree(spec);
+        // When
+        Optional<UsabilityDefect> recommendation = new NoLetterOrDigitRatioMetric(taskTree).check();
+        // Then
+        assertThat(recommendation).is(absent());
+    }
+
+    @Test
+    public void should_return_recommendation_with_info_severity_level() {
+        // Given
+        String spec =
+            "Sequence {" + 
+            "  TextInput (1234567890123456789012345678901234567890123456789_01234567890" + 
+                         "12345678901234567890123456789012345) {}" + 
+            "}";
+        ITaskTree taskTree = createTaskTree(spec);
+        // When
+        Optional<UsabilityDefect> recommendation = new NoLetterOrDigitRatioMetric(taskTree).check();
+        // Then
+        assertThat(recommendation).is(present()).has(infoRecommendationSeverityLevel());
+    }
+
+    @Test
+    public void should_return_recommendation_with_low_severity_level() {
+        // Given
+        String spec =
+            "Sequence {" + 
+            "  TextInput (123456789012345678901234567890_123456789012345) {}" + 
+            "}";
+        ITaskTree taskTree = createTaskTree(spec);
+        // When
+        Optional<UsabilityDefect> recommendation = new NoLetterOrDigitRatioMetric(taskTree).check();
+        // Then
+        assertThat(recommendation).is(present()).has(lowRecommendationSeverityLevel());
+    }
+
+    @Test
+    public void should_return_recommendation_with_medium_severity_level() {
+        // Given
+        String spec = "Sequence {" + 
+                      "  TextInput (12345_6789012345) {}" + 
+                      "}";
+        ITaskTree taskTree = createTaskTree(spec);
+        // When
+        Optional<UsabilityDefect> recommendation = new NoLetterOrDigitRatioMetric(taskTree).check();
+        // Then
+        assertThat(recommendation).is(present()).has(mediumRecommendationSeverityLevel());
+    }
+
+    @Test
+    public void should_return_recommendation_with_high_severity_level() {
+        // Given
+        String spec = "Sequence {" +
+                      "  TextInput (_a_b_c_) {}" +
+                      "}";
+        ITaskTree taskTree = createTaskTree(spec);
+        // When
+        Optional<UsabilityDefect> recommendation = new NoLetterOrDigitRatioMetric(taskTree).check();
+        // Then
+        assertThat(recommendation).is(present()).has(highRecommendationSeverityLevel());
+    }
+}
Index: /trunk/autoquest-core-usability-evaluation-test/src/main/java/de/ugoe/cs/autoquest/usability/rules/metrics/TextInputEntryRepetitionsEvaluatorTest.java
===================================================================
--- /trunk/autoquest-core-usability-evaluation-test/src/main/java/de/ugoe/cs/autoquest/usability/rules/metrics/TextInputEntryRepetitionsEvaluatorTest.java	(revision 1141)
+++ /trunk/autoquest-core-usability-evaluation-test/src/main/java/de/ugoe/cs/autoquest/usability/rules/metrics/TextInputEntryRepetitionsEvaluatorTest.java	(revision 1141)
@@ -0,0 +1,116 @@
+//   Copyright 2012 Georg-August-Universität Göttingen, Germany
+//
+//   Licensed under the Apache License, Version 2.0 (the "License");
+//   you may not use this file except in compliance with the License.
+//   You may obtain a copy of the License at
+//
+//       http://www.apache.org/licenses/LICENSE-2.0
+//
+//   Unless required by applicable law or agreed to in writing, software
+//   distributed under the License is distributed on an "AS IS" BASIS,
+//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//   See the License for the specific language governing permissions and
+//   limitations under the License.
+
+package de.ugoe.cs.autoquest.usability.rules.metrics;
+
+import static de.ugoe.cs.autoquest.usability.testutil.FestConditionUtil.absent;
+import static de.ugoe.cs.autoquest.usability.testutil.FestConditionUtil.highRecommendationSeverityLevel;
+import static de.ugoe.cs.autoquest.usability.testutil.FestConditionUtil.infoRecommendationSeverityLevel;
+import static de.ugoe.cs.autoquest.usability.testutil.FestConditionUtil.lowRecommendationSeverityLevel;
+import static de.ugoe.cs.autoquest.usability.testutil.FestConditionUtil.mediumRecommendationSeverityLevel;
+import static de.ugoe.cs.autoquest.usability.testutil.FestConditionUtil.present;
+import static org.fest.assertions.api.Assertions.assertThat;
+
+import org.junit.Test;
+
+import com.google.common.base.Optional;
+
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTree;
+import de.ugoe.cs.autoquest.usability.result.UsabilityDefect;
+import de.ugoe.cs.autoquest.usability.rules.metrics.TextInputEntryRepetitionsMetric;
+
+/**
+ * <p>
+ * TODO comment
+ * </p>
+ * 
+ * @author Alexander Deicke
+ */
+public class TextInputEntryRepetitionsEvaluatorTest extends AbstractUsabilityEvaluationTC {
+
+    @Test
+    public void should_return_no_recommendation() {
+        // Given
+        String spec = "Sequence {" + "  TextInput () {}" + "}";
+        ITaskTree taskTree = createTaskTree(spec);
+        // When
+        Optional<UsabilityDefect> recommendation = new TextInputEntryRepetitionsMetric(taskTree).check();
+        // Then
+        assertThat(recommendation).is(absent());
+    }
+
+    @Test
+    public void should_return_recommendation_with_info_severity_level() {
+        // Given
+        String spec =
+            "Sequence {" + "  TextInput (a b c) {}" + "  Sequence {" + "    TextInput (a) {}"
+                + "    TextInput (d) {}" + "    TextInput (e) {}" + "  }" + "}";
+        ITaskTree taskTree = createTaskTree(spec);
+        // When
+        Optional<UsabilityDefect> recommendation = new TextInputEntryRepetitionsMetric(taskTree).check();
+        // Then
+        assertThat(recommendation).is(present()).has(infoRecommendationSeverityLevel());
+    }
+
+    @Test
+    public void should_return_recommendation_with_low_severity_level() {
+        // Given
+        String spec =
+            "Sequence {" + "  TextInput (a b c) {}" + "  Sequence {" + "    TextInput (a) {}"
+                + "    TextInput (b) {}" + "    TextInput (c) {}" + "  }" + "}";
+        ITaskTree taskTree = createTaskTree(spec);
+        // When
+        Optional<UsabilityDefect> recommendation = new TextInputEntryRepetitionsMetric(taskTree).check();
+        // Then
+        assertThat(recommendation).is(present()).has(lowRecommendationSeverityLevel());
+    }
+
+    @Test
+    public void should_return_recommendation_with_medium_severity_level() {
+        // Given
+        String spec =
+            "Sequence {" + "  TextInput (a b c d e f g h i j k l m) {}" + "  Sequence {"
+                + "    TextInput (a) {}" + "    TextInput (b) {}" + "    TextInput (c) {}"
+                + "    TextInput (d) {}" + "  }" + "  Iteration {" + "    TextInput (e) {}" + "  }"
+                + "  TextInput (a) {}" + "  Selection {" + "    TextInput (b) {}"
+                + "    TextInput (c) {}" + "    TextInput (d) {}" + "    TextInput (e) {}" + "  }"
+                + "  Sequence {" + "    TextInput (a) {}" + "    Sequence {"
+                + "      TextInput (b) {}" + "      TextInput (c) {}" + "      TextInput (d) {}"
+                + "      TextInput (e) {}" + "    }" + "  }" + "  TextInput (f) {}" + "}";
+        ITaskTree taskTree = createTaskTree(spec);
+        // When
+        Optional<UsabilityDefect> recommendation = new TextInputEntryRepetitionsMetric(taskTree).check();
+        // Then
+        assertThat(recommendation).is(present()).has(mediumRecommendationSeverityLevel());
+    }
+
+    @Test
+    public void should_return_recommendation_with_high_severity_level() {
+        // Given
+        String spec =
+            "Sequence {" + "  TextInput (a b c) {}" + "  Sequence {" + "    TextInput (a) {}"
+                + "    TextInput (b) {}" + "    TextInput (c) {}" + "    TextInput (a) {}" + "  }"
+                + "  Iteration {" + "    TextInput (a) {}" + "  }" + "  TextInput (a) {}"
+                + "  Selection {" + "    TextInput (b c) {}" + "    TextInput (a) {}"
+                + "    TextInput (a c) {}" + "    TextInput (b a) {}" + "  }" + "  Sequence {"
+                + "    TextInput (b c) {}" + "    Sequence {" + "      TextInput (d a c) {}"
+                + "      TextInput (b b b a) {}" + "      TextInput (a a c c) {}"
+                + "      TextInput (b b a) {}" + "    }" + "  }" + "  TextInput (d) {}" + "}";
+        ITaskTree taskTree = createTaskTree(spec);
+        // When
+        Optional<UsabilityDefect> recommendation = new TextInputEntryRepetitionsMetric(taskTree).check();
+        // Then
+        assertThat(recommendation).is(present()).has(highRecommendationSeverityLevel());
+    }
+}
Index: /trunk/autoquest-core-usability-evaluation-test/src/main/java/de/ugoe/cs/autoquest/usability/rules/metrics/TextInputRatioEvaluatorTest.java
===================================================================
--- /trunk/autoquest-core-usability-evaluation-test/src/main/java/de/ugoe/cs/autoquest/usability/rules/metrics/TextInputRatioEvaluatorTest.java	(revision 1141)
+++ /trunk/autoquest-core-usability-evaluation-test/src/main/java/de/ugoe/cs/autoquest/usability/rules/metrics/TextInputRatioEvaluatorTest.java	(revision 1141)
@@ -0,0 +1,105 @@
+//   Copyright 2012 Georg-August-Universität Göttingen, Germany
+//
+//   Licensed under the Apache License, Version 2.0 (the "License");
+//   you may not use this file except in compliance with the License.
+//   You may obtain a copy of the License at
+//
+//       http://www.apache.org/licenses/LICENSE-2.0
+//
+//   Unless required by applicable law or agreed to in writing, software
+//   distributed under the License is distributed on an "AS IS" BASIS,
+//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//   See the License for the specific language governing permissions and
+//   limitations under the License.
+
+package de.ugoe.cs.autoquest.usability.rules.metrics;
+
+import static de.ugoe.cs.autoquest.usability.testutil.FestConditionUtil.absent;
+import static de.ugoe.cs.autoquest.usability.testutil.FestConditionUtil.highRecommendationSeverityLevel;
+import static de.ugoe.cs.autoquest.usability.testutil.FestConditionUtil.infoRecommendationSeverityLevel;
+import static de.ugoe.cs.autoquest.usability.testutil.FestConditionUtil.lowRecommendationSeverityLevel;
+import static de.ugoe.cs.autoquest.usability.testutil.FestConditionUtil.mediumRecommendationSeverityLevel;
+import static de.ugoe.cs.autoquest.usability.testutil.FestConditionUtil.present;
+import static org.fest.assertions.api.Assertions.assertThat;
+
+import org.junit.Test;
+
+import com.google.common.base.Optional;
+
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTree;
+import de.ugoe.cs.autoquest.usability.result.UsabilityDefect;
+import de.ugoe.cs.autoquest.usability.rules.metrics.TextInputRatioMetric;
+
+/**
+ * <p>
+ * TODO comment
+ * </p>
+ * 
+ * @author Alexander Deicke
+ */
+public class TextInputRatioEvaluatorTest extends AbstractUsabilityEvaluationTC {
+
+    @Test
+    public void should_return_no_recommendation() {
+        // Given
+        String spec =
+            "Sequence {" + "  Interaction {}" + "  TextInput (a) {}" + "  Interaction {}"
+                + "  Interaction {}" + "  TextInput (c) {}" + "  Interaction {}"
+                + "  Interaction {}" + "  Interaction {}" + "}";
+        ITaskTree taskTree = createTaskTree(spec);
+        // When
+        Optional<UsabilityDefect> recommendation = new TextInputRatioMetric(taskTree).check();
+        // Then
+        assertThat(recommendation).is(absent());
+    }
+
+    @Test
+    public void should_return_recommendation_with_info_severity_level() {
+        // Given
+        String spec =
+            "Sequence {" + "  Interaction {}" + "  TextInput (a) {}" + "  Interaction {}"
+                + "  Interaction {}" + "  TextInput (c) {}" + "}";
+        ITaskTree taskTree = createTaskTree(spec);
+        // When
+        Optional<UsabilityDefect> recommendation = new TextInputRatioMetric(taskTree).check();
+        // Then
+        assertThat(recommendation).is(present()).has(infoRecommendationSeverityLevel());
+    }
+
+    @Test
+    public void should_return_recommendation_with_low_severity_level() {
+        // Given
+        String spec =
+            "Sequence {" + "  Interaction {}" + "  TextInput (a) {}" + "  TextInput (b) {}"
+                + "  Interaction {}" + "  TextInput (c) {}" + "}";
+        ITaskTree taskTree = createTaskTree(spec);
+        // When
+        Optional<UsabilityDefect> recommendation = new TextInputRatioMetric(taskTree).check();
+        // Then
+        assertThat(recommendation).is(present()).has(lowRecommendationSeverityLevel());
+    }
+
+    @Test
+    public void should_return_recommendation_with_medium_severity_level() {
+        // Given
+        String spec =
+            "Sequence {" + "  TextInput (a) {}" + "  TextInput (b) {}" + "  Interaction {}"
+                + "  TextInput (c) {}" + "}";
+        ITaskTree taskTree = createTaskTree(spec);
+        // When
+        Optional<UsabilityDefect> recommendation = new TextInputRatioMetric(taskTree).check();
+        // Then
+        assertThat(recommendation).is(present()).has(mediumRecommendationSeverityLevel());
+    }
+
+    @Test
+    public void should_return_recommendation_with_high_severity_level() {
+        // Given
+        String spec = "TextInput (bla) {}";
+        ITaskTree taskTree = createTaskTree(spec);
+        // When
+        Optional<UsabilityDefect> recommendation = new TextInputRatioMetric(taskTree).check();
+        // Then
+        assertThat(recommendation).is(present()).has(highRecommendationSeverityLevel());
+    }
+}
Index: /trunk/autoquest-core-usability-evaluation-test/src/main/java/de/ugoe/cs/autoquest/usability/testutil/FestConditionUtil.java
===================================================================
--- /trunk/autoquest-core-usability-evaluation-test/src/main/java/de/ugoe/cs/autoquest/usability/testutil/FestConditionUtil.java	(revision 1140)
+++ /trunk/autoquest-core-usability-evaluation-test/src/main/java/de/ugoe/cs/autoquest/usability/testutil/FestConditionUtil.java	(revision 1141)
@@ -19,8 +19,7 @@
 import com.google.common.base.Optional;
 
-import de.ugoe.cs.autoquest.usability.UsabilityEvaluationReport;
-import de.ugoe.cs.autoquest.usability.evaluation.result.UsabilityDefectSeverityLevel;
-import de.ugoe.cs.autoquest.usability.evaluation.result.UsabilityDefect;
-import de.ugoe.cs.autoquest.usability.evaluation.rule.set.UsabilityRuleset;
+import de.ugoe.cs.autoquest.usability.result.UsabilityDefect;
+import de.ugoe.cs.autoquest.usability.result.UsabilityDefectSeverityLevel;
+import de.ugoe.cs.autoquest.usability.rules.UsabilityResult;
 
 /**
@@ -37,43 +36,21 @@
     }
 
-    public static Condition<UsabilityEvaluationReport> noUsabilityGuidlineRecommendations() {
-        return new Condition<UsabilityEvaluationReport>() {
+    public static Condition<UsabilityResult> noUsabilityGuidlineRecommendations() {
+        return new Condition<UsabilityResult>() {
 
             @Override
-            public boolean matches(UsabilityEvaluationReport usabilityEvaluationReport) {
-                return usabilityEvaluationReport.evaluationResults().isEmpty();
+            public boolean matches(UsabilityResult usabilityResult) {
+                return !usabilityResult.hasDefects();
             }
         };
     }
 
-    public static Condition<UsabilityEvaluationReport> usabilityGuidlineRecommendations() {
-        return new Condition<UsabilityEvaluationReport>() {
+    public static Condition<UsabilityResult> usabilityGuidlineRecommendations() {
+        return new Condition<UsabilityResult>() {
 
             @Override
-            public boolean matches(UsabilityEvaluationReport usabilityEvaluationReport) {
-                return !usabilityEvaluationReport.evaluationResults().isEmpty();
+            public boolean matches(UsabilityResult usabilityResult) {
+                return usabilityResult.hasDefects();
             }
-        };
-    }
-
-    public static Condition<UsabilityRuleset> noUsabilityRules() {
-        return new Condition<UsabilityRuleset>() {
-
-            @Override
-            public boolean matches(UsabilityRuleset usabilityRuleset) {
-                return usabilityRuleset.evaluationRules().isEmpty();
-            }
-
-        };
-    }
-
-    public static Condition<UsabilityRuleset> usabilityRules() {
-        return new Condition<UsabilityRuleset>() {
-
-            @Override
-            public boolean matches(UsabilityRuleset usabilityRuleset) {
-                return !usabilityRuleset.evaluationRules().isEmpty();
-            }
-
         };
     }
Index: /trunk/autoquest-core-usability-evaluation-test/src/main/java/de/ugoe/cs/autoquest/usability/testutil/GenerateTaskTreeUtil.java
===================================================================
--- /trunk/autoquest-core-usability-evaluation-test/src/main/java/de/ugoe/cs/autoquest/usability/testutil/GenerateTaskTreeUtil.java	(revision 1140)
+++ /trunk/autoquest-core-usability-evaluation-test/src/main/java/de/ugoe/cs/autoquest/usability/testutil/GenerateTaskTreeUtil.java	(revision 1141)
@@ -24,7 +24,10 @@
 import de.ugoe.cs.autoquest.commands.usability.CMDgenerateTaskTree;
 import de.ugoe.cs.autoquest.plugin.jfc.commands.CMDparseJFC;
+import de.ugoe.cs.autoquest.tasktrees.TaskTreeInstantiator;
 import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTree;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeNode;
+import de.ugoe.cs.autoquest.tasktrees.treeimpl.TaskTreeBuilder;
+import de.ugoe.cs.autoquest.tasktrees.treeimpl.TaskTreeNodeFactory;
 import de.ugoe.cs.autoquest.test.CommandRunner;
-import de.ugoe.cs.util.console.Console;
 import de.ugoe.cs.util.console.GlobalDataContainer;
 import de.ugoe.cs.util.console.TextConsole;
@@ -42,7 +45,13 @@
 
     private static final String taskTreeName = "taskTree";
-
+    
+    public static ITaskTree getTaskTreeFromSpec(String spec) {
+        TaskTreeNodeFactory factory = new TaskTreeNodeFactory();
+        ITaskTreeNode taskTree = new TaskTreeInstantiator(new TaskTreeNodeFactory(), new TaskTreeBuilder()).instantiateTaskTree(spec);
+        return factory.createTaskTree(taskTree);
+    }
+    
     public static ITaskTree getTaskTreeFromFile(String filename) {
-        new TextConsole(Level.FINEST);
+        new TextConsole(Level.OFF);
         parseTraceFile(filename);
         condenseGuiModel();
@@ -55,5 +64,4 @@
 
     static private void parseTraceFile(String filetoparse) {
-        Console.println("parsing trace file");
         CommandRunner.runCommand(CMDparseJFC.class, ClassLoader.getSystemResource(filetoparse)
             .getFile(), seqName);
@@ -61,25 +69,20 @@
 
     private static void condenseGuiModel() {
-        Console.println("condensing GUI model");
         CommandRunner.runCommand(CMDcondenseGuiModel.class, seqName);
     }
 
     private static void sortKeyInteractions() {
-        Console.println("sorting key interactions");
         CommandRunner.runCommand(CMDsortKeyInteractions.class, seqName);
     }
 
     private static void correctKeyInteractionTargets() {
-        Console.println("correcting key interaction targets");
         CommandRunner.runCommand(CMDcorrectKeyInteractionTargets.class, seqName);
     }
 
     private static void detectTextInputEvents() {
-        Console.println("detecting text input events");
         CommandRunner.runCommand(CMDdetectTextInputEvents.class, seqName);
     }
 
     private static void condenseMouseClicks() {
-        Console.println("condensing mouse click events");
         CommandRunner.runCommand(CMDcondenseMouseClicks.class, seqName);
     }
