ModelListener sets text from suggestion or userText
diff --git a/bundles/org.eclipse.rap.addons.dropdown.viewer/src/org/eclipse/rap/addons/dropdown/viewer/internal/resources/DataBinding.js b/bundles/org.eclipse.rap.addons.dropdown.viewer/src/org/eclipse/rap/addons/dropdown/viewer/internal/resources/DataBinding.js
index 9f8fa93..1f06178 100644
--- a/bundles/org.eclipse.rap.addons.dropdown.viewer/src/org/eclipse/rap/addons/dropdown/viewer/internal/resources/DataBinding.js
+++ b/bundles/org.eclipse.rap.addons.dropdown.viewer/src/org/eclipse/rap/addons/dropdown/viewer/internal/resources/DataBinding.js
@@ -9,6 +9,8 @@
  *    EclipseSource - initial API and implementation
  ******************************************************************************/
 
+ //@ sourceURL=DataBinding.js
+
 ///////////////////
 // Event Delegation
 
@@ -31,10 +33,10 @@
 function handleDropDownEvent( model, event ) {
   switch( event.type ) {
     case SWT.Selection:
-      onDropDownSelection( model, event.widget.getSelectionIndex() );
+      onDropDownSelection( model, event );
     break;
     case SWT.DefaultSelection:
-      onDropDownDefaultSelection( model );
+      onDropDownDefaultSelection( model, event );
     break;
   }
 }
@@ -43,12 +45,25 @@
   var userAction = getUserAction( event );
   switch( event.type ) {
     case SWT.Modify:
-      onTextModify( model, event.widget.getText(), userAction );
+      onTextModify( model, event, userAction );
     break;
   }
   setUserAction( event );
 }
 
+function handleModelEvent( model, type, event ) {
+  var textWidget = rap.getObject( model.get( "textWidgetId" ) );
+  var dropDown = rap.getObject( model.get( "dropDownWidgetId" ) );
+  switch( event.property ) {
+    case "text":
+      onModelChangeText( textWidget, model, event );
+    break;
+    case "results":
+      onModelChangeResults( dropDown, model, event );
+    break;
+  }
+}
+
 function setUserAction( event ) {
   if( event.type === SWT.Verify ) {
     // See Bug 404896 - [ClientScripting] Verify event keyCode is always zero when replacing txt
@@ -63,34 +78,23 @@
   return action;
 }
 
-function handleModelEvent( model, type, event ) {
-  var textWidget = rap.getObject( model.get( "textWidgetId" ) );
-  var dropDown = rap.getObject( model.get( "dropDownWidgetId" ) );
-  switch( event.property ) {
-    case "suggestion":
-      onModelChangeSuggestion( textWidget, model, event );
-    break;
-    case "results":
-      onModelChangeResults( dropDown, model, event );
-    break;
-  }
-}
-
 /////////////////
 // Event Handling
 
-function onTextModify( model, text, userAction ) {
+function onTextModify( model, event, userAction ) {
+  var text = event.widget.getText();
+  model.set( "text", text, { "source" : "Text" } );
   if( userAction ) {
     model.set( "userText", text );
   }
 }
 
-function onDropDownSelection( model, selectionIndex ) {
-  model.set( "resultSelection", selectionIndex );
+function onDropDownSelection( model, event ) {
+  model.set( "resultSelection", event.index, { "source" : "DropDown" } );
 }
 
-function onDropDownDefaultSelection( model ) {
-  model.notify( "accept" );
+function onDropDownDefaultSelection( model, event ) {
+  model.notify( "accept", { "source" : "DropDown" }  );
 }
 
 function onModelChangeResults( dropDown, model, event ) {
@@ -99,11 +103,9 @@
   dropDown.setItems( results.items );
 }
 
-function onModelChangeSuggestion( textWidget, model, event ) {
-  var text = model.get( "suggestion" );
-  if( text == null ) {
-    text = model.get( "userText" );
+function onModelChangeText( textWidget, model, event ) {
+  if( event.source !== "Text" ) {
+    textWidget.setText( model.get( "text" ) );
   }
-  textWidget.setText( text );
 }
 
diff --git a/bundles/org.eclipse.rap.addons.dropdown.viewer/src/org/eclipse/rap/addons/dropdown/viewer/internal/resources/ModelListener.js b/bundles/org.eclipse.rap.addons.dropdown.viewer/src/org/eclipse/rap/addons/dropdown/viewer/internal/resources/ModelListener.js
index bf1436a..4745081 100644
--- a/bundles/org.eclipse.rap.addons.dropdown.viewer/src/org/eclipse/rap/addons/dropdown/viewer/internal/resources/ModelListener.js
+++ b/bundles/org.eclipse.rap.addons.dropdown.viewer/src/org/eclipse/rap/addons/dropdown/viewer/internal/resources/ModelListener.js
@@ -9,6 +9,8 @@
  *    EclipseSource - initial API and implementation
  ******************************************************************************/
 
+//@ sourceURL=ModelListener.js
+
 ///////////////////
 // Event Delegation
 
@@ -20,6 +22,9 @@
       case "userText":
         onChangeUserText.apply( model, [ event ] );
       break;
+      case "suggestion":
+        onChangeSuggestion.apply( model, [ event ] );
+      break;
       case "resultSelection":
         onChangeResultSelection.apply( model, [ event ] );
       break;
@@ -55,6 +60,11 @@
   this.set( "suggestion", text );
 }
 
+function onChangeSuggestion( options ) {
+  var text = options.value != null ? options.value : this.get( "userText" );
+  this.set( "text", text );
+}
+
 function onAcceptSuggestion( options ) {
   var indicies = this.get( "results" ).indicies;
   var index = this.get( "resultSelection" );
diff --git a/tests/org.eclipse.rap.addons.dropdown.test/jasmine/jasmine/specs/ModelListenerSpec.js b/tests/org.eclipse.rap.addons.dropdown.test/jasmine/jasmine/specs/ModelListenerSpec.js
index 2e35f21..025167a 100644
--- a/tests/org.eclipse.rap.addons.dropdown.test/jasmine/jasmine/specs/ModelListenerSpec.js
+++ b/tests/org.eclipse.rap.addons.dropdown.test/jasmine/jasmine/specs/ModelListenerSpec.js
@@ -177,6 +177,27 @@
 
     } );
 
+    describe( "change:suggestion", function() {
+
+      it( "sets text to suggestion", function() {
+        model.addListener( "change:suggestion", createClientListener( "ModelListener" ) );
+
+        model.set( "suggestion", "foo" );
+
+        expect( model.get( "text" ) ).toEqual( "foo" );
+      } );
+
+      it( "resets text to userText", function() {
+        model.addListener( "change:suggestion", createClientListener( "ModelListener" ) );
+        model.set( "userText", "bar" );
+
+        model.set( "suggestion", null );
+
+        expect( model.get( "text" ) ).toEqual( "bar" );
+      } );
+
+    } );
+
     describe( "change:results", function() {
 
       it( "does nothing without autocomplete", function() {