diff --git a/eraser-base/src/main/jastadd/DecisionTree.jrag b/eraser-base/src/main/jastadd/DecisionTree.jrag
index f50ca0562a920844e46a838c0f655f97bf804a01..22d94464f86fe8ab7876b4f870e4b32a5eb30521 100644
--- a/eraser-base/src/main/jastadd/DecisionTree.jrag
+++ b/eraser-base/src/main/jastadd/DecisionTree.jrag
@@ -3,21 +3,21 @@ aspect DecisionTree {
   // let DecisionTreeLeaf implement Leaf
   public class DecisionTreeLeaf implements Leaf { }
 
-  //--- classify ---
-  syn DecisionTreeLeaf DecisionTreeRoot.classify() {
-    return getRootRule().classify();
+  //--- internalClassify ---
+  syn DecisionTreeLeaf DecisionTreeRoot.internalClassify() {
+    return getRootRule().internalClassify();
   }
 
-  syn DecisionTreeLeaf DecisionTreeElement.classify();
+  syn DecisionTreeLeaf DecisionTreeElement.internalClassify();
 
-  syn DecisionTreeLeaf DecisionTreeRule.classify();
+  syn DecisionTreeLeaf DecisionTreeRule.internalClassify();
 
-  syn DecisionTreeLeaf ItemStateCheckRule.classify() {
+  syn DecisionTreeLeaf ItemStateCheckRule.internalClassify() {
     boolean chooseLeft = getItemStateCheck().holds();
-    return (chooseLeft ? getLeft() : getRight()).classify();
+    return (chooseLeft ? getLeft() : getRight()).internalClassify();
   }
 
-  syn DecisionTreeLeaf DecisionTreeLeaf.classify() = this;
+  syn DecisionTreeLeaf DecisionTreeLeaf.internalClassify() = this;
 
   //--- holds ---
   syn boolean ItemStateCheck.holds() = holdsFor(getItem());
@@ -47,19 +47,19 @@ aspect DecisionTree {
   }
 
   //--- computePreferences ---
-  syn List<ItemPreference> DecisionTreeLeaf.computePreferences() {
+  syn MachineLearningResult DecisionTreeLeaf.computePreferences() {
     // iterate over preference of this leaf, and all its parents and ancestors
-    List<ItemPreference> result = new ArrayList<>();
+    MachineLearningResult result = new MachineLearningResult();
     Set<Item> seenItems = new HashSet<>();
     List<DecisionTreeElement> ancestors = ancestors();
     for (ItemPreference pref : getPreferenceList()) {
-      result.add(pref);
+      result.addItemPreference(pref);
       seenItems.add(pref.getItem());
     }
     for (DecisionTreeElement ancestor : ancestors) {
       for (ItemPreference pref : ancestor.getPreferenceList()) {
         if (!seenItems.contains(pref.getItem())) {
-          result.add(pref);
+          result.addItemPreference(pref);
           seenItems.add(pref.getItem());
         }
       }
diff --git a/eraser-base/src/main/jastadd/Item.jrag b/eraser-base/src/main/jastadd/Item.jrag
index 0b370142cf57c377775294bb6c758dafa7db036f..97ebec744146ae2b884602bc183b75bb25df7905 100644
--- a/eraser-base/src/main/jastadd/Item.jrag
+++ b/eraser-base/src/main/jastadd/Item.jrag
@@ -401,7 +401,6 @@ aspect ItemHandling {
   //--- ItemPreference.apply ---
   public abstract void ItemPreference.apply();
   public void ItemPreferenceColor.apply() {
-    logger.debug("Apply color preference {} -> {}", getItem().getID(), getPreferredHSB());
     getItem().setStateFromColor(getPreferredHSB());
     getItem().freeze();
     for (Item controller : getItem().getControlledByList()) {
@@ -409,8 +408,8 @@ aspect ItemHandling {
     }
     getItem().unfreeze();
   }
+  //--- ItemPreference.apply ---
   public void ItemPreferenceDouble.apply() {
-    logger.debug("Apply double preference {} -> {}", getItem().getID(), getPreferredValue());
     getItem().setStateFromDouble(getPreferredValue());
     getItem().freeze();
     for (Item controller : getItem().getControlledByList()) {
@@ -419,6 +418,14 @@ aspect ItemHandling {
     getItem().unfreeze();
   }
 
+  //--- ItemPreference.describe ---
+  syn String ItemPreference.describe() = getItem().getID() + " -> " + getNewStateAsString();
+
+  //--- ItemPreference.getNewStateAsString ---
+  syn String ItemPreference.getNewStateAsString();
+  eq ItemPreferenceColor.getNewStateAsString() = getPreferredHSB().toString();
+  eq ItemPreferenceDouble.getNewStateAsString() = Double.toString(getPreferredValue());
+
 //  // override Item.init$Children from JastAdd's own ASTNode aspect
 //  refine ASTNode public void Item.init$Children() {
 //    refined();
diff --git a/eraser-base/src/main/jastadd/MachineLearning.jrag b/eraser-base/src/main/jastadd/MachineLearning.jrag
index c4e03ccbbf4d803b66ed38b092cbf1772932b2ee..d838c2cba4a6dde215cb9d3afd65f373cb5fc456 100644
--- a/eraser-base/src/main/jastadd/MachineLearning.jrag
+++ b/eraser-base/src/main/jastadd/MachineLearning.jrag
@@ -8,10 +8,10 @@ aspect MachineLearning {
   public interface Leaf {
     String getLabel();
     int getActivityIdentifier();
-    List<ItemPreference> computePreferences();
+    MachineLearningResult computePreferences();
   }
 
-  syn Leaf InternalMachineLearningModel.classify();
+  syn Leaf InternalMachineLearningModel.internalClassify();
 
   //--- currentActivityName ---
   syn String Root.currentActivityName() = JavaUtils.ifPresentOrElseReturn(
@@ -31,8 +31,8 @@ aspect MachineLearning {
     return (int) ((ItemPreferenceDouble) preferences.get(0)).getPreferredValue();
   }
 
-  //--- currentPreferences ---
-  syn List<ItemPreference> Root.currentPreferences() = getMachineLearningRoot().getPreferenceLearning().getDecoder().classify().getPreferences();
+//  //--- currentPreferences ---
+//  syn List<ItemPreference> Root.currentPreferences() = getMachineLearningRoot().getPreferenceLearning().getDecoder().classify().getItemPreferences();
 
   //--- canSetActivity ---
   syn boolean MachineLearningModel.canSetActivity() = false;
@@ -45,7 +45,7 @@ aspect MachineLearning {
   }
 
   //--- DummyMachineLearningModel.classify ---
-  eq DummyMachineLearningModel.classify() {
+  eq DummyMachineLearningModel.internalClassify() {
     if (logger.isInfoEnabled() && getItemList().size() > 0) {
       logger.info("Dummy classification of {}, values of connected items: {}",
           mlKind(),
@@ -167,6 +167,43 @@ aspect MachineLearning {
     return this.decoder;
   }
 
+  //--- classify ---
+  public MachineLearningResult MachineLearningModel.classify() {
+    MachineLearningResult result = getDecoder().classify();
+    setLastPreference(result);
+    return result;
+  }
+
+  //--- equals ---
+  public boolean MachineLearningResult.equals(Object other) {
+    if (!(other instanceof MachineLearningResult)) {
+      return false;
+    }
+    MachineLearningResult otherResult = (MachineLearningResult) other;
+    if (getNumItemPreference() != otherResult.getNumItemPreference()) {
+      return false;
+    }
+    for (int i = 0; i < getNumItemPreference(); i++) {
+      if (!getItemPreference(i).equals(otherResult.getItemPreference(i))) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  public abstract boolean ItemPreference.equals(Object other);
+  public boolean ItemPreferenceDouble.equals(Object other) {
+    if (!(other instanceof ItemPreferenceDouble)) {
+      return false;
+    }
+    return getItem() == ((ItemPreferenceDouble) other).getItem() && getPreferredValue() == ((ItemPreferenceDouble) other).getPreferredValue();
+  }
+  public boolean ItemPreferenceColor.equals(Object other) {
+    if (!(other instanceof ItemPreferenceColor)) {
+      return false;
+    }
+    return getItem() == ((ItemPreferenceColor) other).getItem() && getPreferredHSB() == ((ItemPreferenceColor) other).getPreferredHSB();
+  }
 }
 
 aspect ChangeEvents {
@@ -177,19 +214,30 @@ aspect ChangeEvents {
     RecognitionEvent result = new RecognitionEvent();
     result.initChangeEvent();
     for (Item relevantItem : modelOfRecognition.getRelevantItems()) {
-      result.addChangedItem(ChangedItem.newFromItem(relevantItem));
+      result.addRelevantItem(ChangedItem.newFrom(relevantItem));
+    }
+    for (ItemPreference preference : modelOfRecognition.getLastPreference().getItemPreferences()) {
+      result.addChangedItem(ChangedItem.newFrom(preference));
     }
     return result;
   }
 
-  //--- newFromItem ---
-  public static ChangedItem ChangedItem.newFromItem(Item source) {
+  //--- newFrom Item ---
+  public static ChangedItem ChangedItem.newFrom(Item source) {
     ChangedItem result = new ChangedItem();
     result.setItem(source);
     result.setNewStateAsString(source.getStateAsString());
     return result;
   }
 
+  //--- newFrom ItemPreference ---
+  public static ChangedItem ChangedItem.newFrom(ItemPreference update) {
+    ChangedItem result = new ChangedItem();
+    result.setItem(update.getItem());
+    result.setNewStateAsString(update.getNewStateAsString());
+    return result;
+  }
+
   //--- initChangeEvent ---
   protected void ChangeEvent.initChangeEvent() {
     this.setCreated(Instant.now());
diff --git a/eraser-base/src/main/jastadd/MachineLearning.relast b/eraser-base/src/main/jastadd/MachineLearning.relast
index 906d344b8f123fca5d617b174078dcfa56f7f4c8..c53ab3cc3394309afd18287d6c575497aa80933b 100644
--- a/eraser-base/src/main/jastadd/MachineLearning.relast
+++ b/eraser-base/src/main/jastadd/MachineLearning.relast
@@ -10,10 +10,11 @@ rel ChangedItem.Item -> Item ;
 
 RecognitionEvent : ChangeEvent ;
 rel RecognitionEvent.Activity -> Activity ;
+rel RecognitionEvent.RelevantItem* -> ChangedItem ;
 
 ManualChangeEvent : ChangeEvent ;
 
-abstract MachineLearningModel ::= ;
+abstract MachineLearningModel ::= LastPreference:MachineLearningResult ;
 rel MachineLearningModel.RelevantItem* <-> Item.RelevantInMachineLearningModel* ;
 rel MachineLearningModel.TargetItem* <-> Item.TargetInMachineLearningModel* ;
 
@@ -21,6 +22,8 @@ ExternalMachineLearningModel : MachineLearningModel ;
 
 abstract InternalMachineLearningModel : MachineLearningModel ::= <OutputApplication:DoubleDoubleFunction> ;
 
+MachineLearningResult ::= ItemPreference* ;
+
 abstract ItemPreference ::= ;
 rel ItemPreference.Item -> Item ;
 
diff --git a/eraser-base/src/main/jastadd/NeuralNetwork.jrag b/eraser-base/src/main/jastadd/NeuralNetwork.jrag
index 999031dd8ad2260fff1db1cdfa2ec69579a706a2..c9035025c77943cabf4f93fead3d9f56ecffea2b 100644
--- a/eraser-base/src/main/jastadd/NeuralNetwork.jrag
+++ b/eraser-base/src/main/jastadd/NeuralNetwork.jrag
@@ -18,17 +18,19 @@ aspect NeuralNetwork {
     public int getActivityIdentifier() {
       return (int) number;
     }
-    public List<ItemPreference> computePreferences() {
-      return Collections.singletonList(new ItemPreferenceDouble(affectedItem, number));
+    public MachineLearningResult computePreferences() {
+      MachineLearningResult result = new MachineLearningResult();
+      result.addItemPreference(new ItemPreferenceDouble(affectedItem, number));
+      return result;
     }
   }
 
-  //--- classify ---
-  syn DoubleNumber NeuralNetworkRoot.classify() {
-    return getOutputLayer().classify();
+  //--- internalClassify ---
+  syn DoubleNumber NeuralNetworkRoot.internalClassify() {
+    return getOutputLayer().internalClassify();
   }
 
-  syn DoubleNumber OutputLayer.classify() {
+  syn DoubleNumber OutputLayer.internalClassify() {
     double[] inputs = new double[getNumOutputNeuron()];
     for (int i = 0; i < getNumOutputNeuron(); ++i) {
       OutputNeuron n = getOutputNeuron(i);
diff --git a/eraser-base/src/main/java/de/tudresden/inf/st/eraser/jastadd/model/InternalMachineLearningHandler.java b/eraser-base/src/main/java/de/tudresden/inf/st/eraser/jastadd/model/InternalMachineLearningHandler.java
index 75d2a1d8cfc28c0293f1d55cc4e6714a6e37818a..a04db3e06454e47ecccb63b7231b0c11c13ea1d6 100644
--- a/eraser-base/src/main/java/de/tudresden/inf/st/eraser/jastadd/model/InternalMachineLearningHandler.java
+++ b/eraser-base/src/main/java/de/tudresden/inf/st/eraser/jastadd/model/InternalMachineLearningHandler.java
@@ -48,8 +48,7 @@ public class InternalMachineLearningHandler implements MachineLearningEncoder, M
 
   @Override
   public MachineLearningResult classify() {
-    List<ItemPreference> preferences = model.classify().computePreferences();
-    return new InternalMachineLearningResult(preferences);
+    return model.internalClassify().computePreferences();
   }
 
   @Override
diff --git a/eraser-base/src/main/java/de/tudresden/inf/st/eraser/jastadd/model/InternalMachineLearningResult.java b/eraser-base/src/main/java/de/tudresden/inf/st/eraser/jastadd/model/InternalMachineLearningResult.java
deleted file mode 100644
index 087020b383fee89ea839b2056e22072af799a9f3..0000000000000000000000000000000000000000
--- a/eraser-base/src/main/java/de/tudresden/inf/st/eraser/jastadd/model/InternalMachineLearningResult.java
+++ /dev/null
@@ -1,21 +0,0 @@
-package de.tudresden.inf.st.eraser.jastadd.model;
-
-import java.util.List;
-
-/**
- * Result of a classification returned by an internally held machine learning model.
- *
- * @author rschoene - Initial contribution
- */
-public class InternalMachineLearningResult implements MachineLearningResult {
-  private final List<ItemPreference> preferences;
-
-  InternalMachineLearningResult(List<ItemPreference> preferences) {
-    this.preferences = preferences;
-  }
-
-  @Override
-  public List<ItemPreference> getPreferences() {
-    return this.preferences;
-  }
-}
diff --git a/eraser-base/src/main/java/de/tudresden/inf/st/eraser/jastadd/model/MachineLearningResult.java b/eraser-base/src/main/java/de/tudresden/inf/st/eraser/jastadd/model/MachineLearningResult.java
deleted file mode 100644
index eebd16d3679c1531cb02d1ba1abd0c1610303668..0000000000000000000000000000000000000000
--- a/eraser-base/src/main/java/de/tudresden/inf/st/eraser/jastadd/model/MachineLearningResult.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package de.tudresden.inf.st.eraser.jastadd.model;
-
-import de.tudresden.inf.st.eraser.jastadd.model.ItemPreference;
-
-import java.util.List;
-
-/**
- * Representation of a classification result using a MachineLearningModel.
- *
- * @author rschoene - Initial contribution
- */
-@SuppressWarnings("unused")
-public interface MachineLearningResult {
-
-  // Object rawClass();
-
-  // double rawConfidence();
-
-  // can be used for both activity and preferences
-  /**
-   * Get the result as a list of item preferences, i.e., new states to be set for those items.
-   * @return the classification result as item preferences
-   */
-  List<ItemPreference> getPreferences();
-}
diff --git a/eraser-base/src/test/java/de/tudresden/inf/st/eraser/DecisionTreeTest.java b/eraser-base/src/test/java/de/tudresden/inf/st/eraser/DecisionTreeTest.java
index fa93e0691d782030d2e45c385f9327a57c9e1ae4..9ffee83b3a16695fd392efa6e123e7d9754a2fe1 100644
--- a/eraser-base/src/test/java/de/tudresden/inf/st/eraser/DecisionTreeTest.java
+++ b/eraser-base/src/test/java/de/tudresden/inf/st/eraser/DecisionTreeTest.java
@@ -25,17 +25,17 @@ public class DecisionTreeTest {
     dtroot.setRootRule(newRule(isLessThanFour, isFourOrGreater, "check item1", check));
 
     // current value is four, so return value should be "four or greater"
-    Leaf leaf = dtroot.classify();
+    Leaf leaf = dtroot.internalClassify();
     Assert.assertEquals(isFourOrGreater, leaf);
 
     // change value to 5, so return value should still be "four or greater"
     mai.item.setState(5);
-    leaf = dtroot.classify();
+    leaf = dtroot.internalClassify();
     Assert.assertEquals(isFourOrGreater, leaf);
 
     // change value to 2, so return value should now be "less than four"
     mai.item.setState(2);
-    leaf = dtroot.classify();
+    leaf = dtroot.internalClassify();
     Assert.assertEquals(isLessThanFour, leaf);
   }
 
@@ -64,17 +64,17 @@ public class DecisionTreeTest {
     dtroot.setRootRule(newRule(rule25, rule75, "50-item1", check50));
 
     // current value is 20, so return value should be "less than 25"
-    Leaf leaf = dtroot.classify();
+    Leaf leaf = dtroot.internalClassify();
     Assert.assertEquals(isLessThan25, leaf);
 
     // change value to 25, so return value should still be "25 or greater"
     mai.item.setState(25);
-    leaf = dtroot.classify();
+    leaf = dtroot.internalClassify();
     Assert.assertEquals(is25OrGreater, leaf);
 
     // change value to 100, so return value should now be "greater than 75"
     mai.item.setState(100);
-    leaf = dtroot.classify();
+    leaf = dtroot.internalClassify();
     Assert.assertEquals(is75OrGreater, leaf);
   }
 
@@ -139,7 +139,7 @@ public class DecisionTreeTest {
 
     for (TestResult result : testResults) {
       mai.item.setState(Math.round(result.value));
-      Leaf leaf = dtroot.classify();
+      Leaf leaf = dtroot.internalClassify();
       Assert.assertEquals(result.chooseLeft ? leaf : right, leaf);
     }
   }
diff --git a/eraser-base/src/test/java/de/tudresden/inf/st/eraser/NeuralNetworkTest.java b/eraser-base/src/test/java/de/tudresden/inf/st/eraser/NeuralNetworkTest.java
index 0eb593fd0fc6c3cb3401f315afe33d550e4b3658..d4549f59ed2e50d1c2e0db2d3e0b3dd5303e8ed0 100644
--- a/eraser-base/src/test/java/de/tudresden/inf/st/eraser/NeuralNetworkTest.java
+++ b/eraser-base/src/test/java/de/tudresden/inf/st/eraser/NeuralNetworkTest.java
@@ -50,17 +50,17 @@ public class NeuralNetworkTest {
     neuralNetworkRoot.setOutputLayer(outputLayer);
 
     // Current value is 1, so return value is 1 * 4 * 0.6 = 2.4, 1 * 4 * 0.4 = 1.6, both are less than 4. so 0.
-    Leaf leaf = neuralNetworkRoot.classify();
+    Leaf leaf = neuralNetworkRoot.internalClassify();
     assertLeafEqual(0, leaf);
 
     // Current value is 2, so return value is 2 * 4 * 0.6 = 4.8, 2 * 4 * 0.4 = 3.2, first is less than 4. so 1.
     mai.item.setState(2);
-    leaf = neuralNetworkRoot.classify();
+    leaf = neuralNetworkRoot.internalClassify();
     assertLeafEqual(1, leaf);
 
     // Current value is 5, so return value is 5 * 4 * 0.6 = 12, 5 * 4 * 0.4 = 8, both are greater than 4. so 3.
     mai.item.setState(5);
-    leaf = neuralNetworkRoot.classify();
+    leaf = neuralNetworkRoot.internalClassify();
     assertLeafEqual(3, leaf);
   }
 
diff --git a/feedbackloop.analyze/src/main/java/de/tudresden/inf/st/eraser/feedbackloop/analyze/AnalyzeImpl.java b/feedbackloop.analyze/src/main/java/de/tudresden/inf/st/eraser/feedbackloop/analyze/AnalyzeImpl.java
index 5e9f8cfb5476ae25219cebd704e17e2e2b78cb9d..b3d3a3d4b61c23cccd18a6939920a473a614d1f7 100644
--- a/feedbackloop.analyze/src/main/java/de/tudresden/inf/st/eraser/feedbackloop/analyze/AnalyzeImpl.java
+++ b/feedbackloop.analyze/src/main/java/de/tudresden/inf/st/eraser/feedbackloop/analyze/AnalyzeImpl.java
@@ -3,6 +3,8 @@ package de.tudresden.inf.st.eraser.feedbackloop.analyze;
 import de.tudresden.inf.st.eraser.feedbackloop.api.Analyze;
 import de.tudresden.inf.st.eraser.feedbackloop.api.Plan;
 import de.tudresden.inf.st.eraser.jastadd.model.Activity;
+import de.tudresden.inf.st.eraser.jastadd.model.ItemPreference;
+import de.tudresden.inf.st.eraser.jastadd.model.MachineLearningResult;
 import de.tudresden.inf.st.eraser.jastadd.model.Root;
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
@@ -17,10 +19,12 @@ public class AnalyzeImpl implements Analyze {
   private Root knowledgeBase;
   private Plan plan;
   private Activity mostRecentActivity;
+  private MachineLearningResult mostRecentPreferences;
   private Logger logger = LogManager.getLogger(AnalyzeImpl.class);
 
   public AnalyzeImpl() {
     this.mostRecentActivity = null;
+    this.mostRecentPreferences = null;
   }
 
   @Override
@@ -40,17 +44,32 @@ public class AnalyzeImpl implements Analyze {
 
   @Override
   public void analyzeLatestChanges() {
+    MachineLearningResult recognitionResult = knowledgeBase.getMachineLearningRoot().getActivityRecognition().getDecoder().classify();
+    recognitionResult.getItemPreferences().forEach(ItemPreference::apply);
     knowledgeBase.currentActivity().ifPresent(activity -> {
+      MachineLearningResult newMLResult = knowledgeBase.getMachineLearningRoot().getPreferenceLearning().classify();
+      // check if activity has changed
       if (!activity.equals(mostRecentActivity)) {
         // new! inform plan!
         logger.info("Found new activity '{}'", activity.getLabel());
-        mostRecentActivity = activity;
         try {
           informPlan(activity);
         } catch (Exception e) {
           logger.catching(e);
         }
+      } else {
+        // if no change, also check, if preferences have changed
+        if (!newMLResult.equals(mostRecentPreferences)) {
+          logger.info("Preferences have changed for same activity '{}'", activity.getLabel());
+          try {
+            informPlan(activity);
+          } catch (Exception e) {
+            logger.catching(e);
+          }
+        }
       }
+      mostRecentActivity = activity;
+      mostRecentPreferences = newMLResult;
     });
   }
 }
diff --git a/feedbackloop.api/src/main/java/de/tudresden/inf/st/eraser/feedbackloop/api/Execute.java b/feedbackloop.api/src/main/java/de/tudresden/inf/st/eraser/feedbackloop/api/Execute.java
index c7ecb57d535b832d59d76d9840813a6d8a72ca2d..0592bdcedb4980e4e66e357690c5312f1c92202e 100644
--- a/feedbackloop.api/src/main/java/de/tudresden/inf/st/eraser/feedbackloop/api/Execute.java
+++ b/feedbackloop.api/src/main/java/de/tudresden/inf/st/eraser/feedbackloop/api/Execute.java
@@ -22,7 +22,7 @@ public interface Execute {
   void setKnowledgeBase(Root knowledgeBase);
 
   /**
-   * <b>Deprecated</b>: Use {@link #updateItems(List)} instead.
+   * <b>Deprecated</b>: Use {@link #updateItems(Iterable)} instead.
    * @param brightnessAndRgbForItems Map, keys are item names, values are RGB and brightness values
    */
   @Deprecated
@@ -32,5 +32,5 @@ public interface Execute {
    * Updates items according to given preferences
    * @param preferences tuples containing item and its new HSB value
    */
-  void updateItems(List<ItemPreference> preferences);
+  void updateItems(Iterable<ItemPreference> preferences);
 }
diff --git a/feedbackloop.api/src/main/java/de/tudresden/inf/st/eraser/feedbackloop/api/Plan.java b/feedbackloop.api/src/main/java/de/tudresden/inf/st/eraser/feedbackloop/api/Plan.java
index 8c237d06d64684d6386e1bc8de5a73146d7a1485..eae690c1390b8f14dd776c9fb58d0e5343b692a6 100644
--- a/feedbackloop.api/src/main/java/de/tudresden/inf/st/eraser/feedbackloop/api/Plan.java
+++ b/feedbackloop.api/src/main/java/de/tudresden/inf/st/eraser/feedbackloop/api/Plan.java
@@ -21,7 +21,7 @@ public interface Plan {
 
   void planToMatchPreferences(Activity activity);
 
-  default void informExecute(List<ItemPreference> preferences) {
+  default void informExecute(Iterable<ItemPreference> preferences) {
     getExecute().updateItems(preferences);
   }
 }
diff --git a/feedbackloop.execute/src/main/java/de/tudresden/inf/st/eraser/feedbackloop/execute/ExecuteImpl.java b/feedbackloop.execute/src/main/java/de/tudresden/inf/st/eraser/feedbackloop/execute/ExecuteImpl.java
index 489956ca9807110328b740b77fe4412e0f00fda3..90baaff24e042423b4abf8b4958223bfe63f6086 100644
--- a/feedbackloop.execute/src/main/java/de/tudresden/inf/st/eraser/feedbackloop/execute/ExecuteImpl.java
+++ b/feedbackloop.execute/src/main/java/de/tudresden/inf/st/eraser/feedbackloop/execute/ExecuteImpl.java
@@ -54,7 +54,7 @@ public class ExecuteImpl implements Execute {
   }
 
   @Override
-  public void updateItems(List<ItemPreference> preferences) {
+  public void updateItems(Iterable<ItemPreference> preferences) {
     for (ItemPreference preference : preferences) {
       preference.apply();
     }
diff --git a/feedbackloop.learner/src/main/java/de/tudresden/inf/st/eraser/feedbackloop/learner/Main.java b/feedbackloop.learner/src/main/java/de/tudresden/inf/st/eraser/feedbackloop/learner/Main.java
index 0d4983c47112462224aa5595942aa23cf738ad8b..d1d56afaa351eecb9c7b79464a7c5ad25e648e71 100644
--- a/feedbackloop.learner/src/main/java/de/tudresden/inf/st/eraser/feedbackloop/learner/Main.java
+++ b/feedbackloop.learner/src/main/java/de/tudresden/inf/st/eraser/feedbackloop/learner/Main.java
@@ -226,7 +226,7 @@ public class Main {
 
 		List<String> output = new ArrayList<>();
 		Function<DoubleNumber, String> leafToString = classification -> Double.toString(classification.number);
-		Function<NeuralNetworkRoot, DoubleNumber> classify = NeuralNetworkRoot::classify;
+		Function<NeuralNetworkRoot, DoubleNumber> classify = NeuralNetworkRoot::internalClassify;
 		DoubleNumber classification = classify.apply(nn);
 		output.add(leafToString.apply(classification));
 		System.out.println(output);
diff --git a/feedbackloop.learner_backup/src/main/java/de/tudresden/inf/st/eraser/feedbackloop.learner_backup/MachineLearningImpl.java b/feedbackloop.learner_backup/src/main/java/de/tudresden/inf/st/eraser/feedbackloop.learner_backup/MachineLearningImpl.java
index f536026f95b47dab38c1acb695284bd31b5728ea..158ebd642bcddbe8c511a9e35714423c6cef1093 100644
--- a/feedbackloop.learner_backup/src/main/java/de/tudresden/inf/st/eraser/feedbackloop.learner_backup/MachineLearningImpl.java
+++ b/feedbackloop.learner_backup/src/main/java/de/tudresden/inf/st/eraser/feedbackloop.learner_backup/MachineLearningImpl.java
@@ -160,21 +160,27 @@ public class MachineLearningImpl implements MachineLearningDecoder, MachineLearn
 
   @Override
   public MachineLearningResult classify() {
+    MachineLearningResult result = new MachineLearningResult();
     switch (this.goal) {
       case GOAL_ACTIVITY_PHONE_AND_WATCH:
         String activityStringValue = activity_result;
+        if (activityStringValue == null) {
+          return result;
+        }
         Item activityItem = resolve(this.root.getSmartHomeEntityModel(), "activity");
         //activityItem.setStateFromString(activityStringValue);
         // FIXME how to translate activityStringValue to a number? or should activity item state better be a String?
-        for (int i=0; i< activites.length;i++){
-          if(activites[i].equals(activityStringValue)){
-            activityItem.setStateFromString(String.valueOf(i));
-            ItemPreference classifiedActivity = new ItemPreferenceDouble(activityItem,i);
-            return new MachineLearningResultImpl(classifiedActivity);
+        ItemPreference classifiedActivity = null;
+        for (Activity activity : this.root.getMachineLearningRoot().getActivityList()) {
+          if (activity.getLabel().equals(activityStringValue)) {
+            classifiedActivity = new ItemPreferenceDouble(activityItem, activity.getIdentifier());
           }
           logger.debug("Classify would return activity: {}", activityStringValue);
         }
-
+        if (classifiedActivity != null) {
+          result.addItemPreference(classifiedActivity);
+        }
+        return result;
       case GOAL_PREFERENCE_BRIGHTNESS_IRIS:
 //        String[] preference = {result[1], result[2]};
         // FIXME what is the meaning of result[1] and result[2]
@@ -185,11 +191,11 @@ public class MachineLearningImpl implements MachineLearningDecoder, MachineLearn
           color = Math.round(Float.valueOf(preference_result[0]));
           brightness = Math.round(Float.valueOf(preference_result[1]));
         }
-        ItemPreference classifiedPreference = new ItemPreferenceColor(iris1, TupleHSB.of(color, 100, brightness));
-        return new MachineLearningResultImpl(classifiedPreference);
+        result.addItemPreference(new ItemPreferenceColor(iris1, TupleHSB.of(color, 100, brightness)));
+        return result;
       default:
         logger.error("Unknown goal value ({}) set in classify", this.goal);
-        return new EmptyMachineLearningResult();
+        return result;
     }
   }
 
@@ -202,12 +208,4 @@ public class MachineLearningImpl implements MachineLearningDecoder, MachineLearn
     learner.preference_train(filenameOfCsv);
   }
 
-  class EmptyMachineLearningResult implements MachineLearningResult {
-
-    @Override
-    public List<ItemPreference> getPreferences() {
-      return Collections.emptyList();
-    }
-  }
-
 }
diff --git a/feedbackloop.learner_backup/src/main/java/de/tudresden/inf/st/eraser/feedbackloop.learner_backup/MachineLearningResultImpl.java b/feedbackloop.learner_backup/src/main/java/de/tudresden/inf/st/eraser/feedbackloop.learner_backup/MachineLearningResultImpl.java
deleted file mode 100644
index 61d483a566255d51ce424d23adb014df1eec8109..0000000000000000000000000000000000000000
--- a/feedbackloop.learner_backup/src/main/java/de/tudresden/inf/st/eraser/feedbackloop.learner_backup/MachineLearningResultImpl.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package de.tudresden.inf.st.eraser.feedbackloop.learner_backup;
-
-import de.tudresden.inf.st.eraser.jastadd.model.ItemPreference;
-import de.tudresden.inf.st.eraser.jastadd.model.MachineLearningResult;
-
-import java.util.Collections;
-import java.util.List;
-
-/**
- * TODO: Add description.
- *
- * @author rschoene - Initial contribution
- */
-public class MachineLearningResultImpl implements MachineLearningResult {
-
-  private final ItemPreference preference;
-
-  MachineLearningResultImpl(ItemPreference preference) {
-    this.preference = preference;
-  }
-
-  @Override
-  public List<ItemPreference> getPreferences() {
-    return Collections.singletonList(preference);
-  }
-}
diff --git a/feedbackloop.plan/src/main/java/de/tudresden/inf/st/eraser/feedbackloop/plan/PlanImpl.java b/feedbackloop.plan/src/main/java/de/tudresden/inf/st/eraser/feedbackloop/plan/PlanImpl.java
index e7f256b2928dfbbdd35e48b2dbf5b1797eee727d..4647c26ba6d54107c014e90cd34afdb8e733d1fb 100644
--- a/feedbackloop.plan/src/main/java/de/tudresden/inf/st/eraser/feedbackloop/plan/PlanImpl.java
+++ b/feedbackloop.plan/src/main/java/de/tudresden/inf/st/eraser/feedbackloop/plan/PlanImpl.java
@@ -37,14 +37,18 @@ public class PlanImpl implements Plan {
   @Override
   public void planToMatchPreferences(Activity activity) {
     logger.info("Plan got new activity [{}]: {}", activity.getIdentifier(), activity.getLabel());
-    List<ItemPreference> preferences = knowledgeBase.currentPreferences();
-    knowledgeBase.getMachineLearningRoot().addChangeEvent(createRecognitionEvent(activity));
-    informExecute(preferences);
+    MachineLearningResult mlResult = knowledgeBase.getMachineLearningRoot().getPreferenceLearning().getLastPreference();
+    knowledgeBase.getMachineLearningRoot().addChangeEvent(createRecognitionEvent(activity, mlResult.getItemPreferences()));
+    knowledgeBase.getMachineLearningRoot().getChangeEventList();
+    informExecute(mlResult.getItemPreferences());
   }
 
-  private ChangeEvent createRecognitionEvent(Activity activity) {
+  private ChangeEvent createRecognitionEvent(Activity activity, Iterable<ItemPreference> preferences) {
     RecognitionEvent result = RecognitionEvent.createRecognitionEvent(knowledgeBase.getMachineLearningRoot().getActivityRecognition());
     result.setActivity(activity);
+    for (ItemPreference preference : preferences) {
+      result.addChangedItem(ChangedItem.newFrom(preference));
+    }
     return result;
   }
 }
diff --git a/ml_test/src/main/java/de/tudresden/inf/st/eraser/ml_test/Main.java b/ml_test/src/main/java/de/tudresden/inf/st/eraser/ml_test/Main.java
index 75fd6d205d96cfe43bdd27176c21ac7e7155473a..535321b63883c8f37cb122b787a6ba3cb70b0fb7 100644
--- a/ml_test/src/main/java/de/tudresden/inf/st/eraser/ml_test/Main.java
+++ b/ml_test/src/main/java/de/tudresden/inf/st/eraser/ml_test/Main.java
@@ -158,7 +158,7 @@ public class Main {
       hiddenNeuron.connectTo(output, 1.0/pr.hiddenNeurons.length);
     }
 
-    classifyTimed(pr.nn, NeuralNetworkRoot::classify,
+    classifyTimed(pr.nn, NeuralNetworkRoot::internalClassify,
         classification -> Double.toString(classification.number));
   }
 
@@ -183,7 +183,7 @@ public class Main {
       }
     }
 
-    classifyTimed(pr.nn, NeuralNetworkRoot::classify,
+    classifyTimed(pr.nn, NeuralNetworkRoot::internalClassify,
         classification -> Double.toHexString(classification.number));
 
 //    long before = System.nanoTime();