Only handle last value change event for attached change screens

Bug: issue 1801
Change-Id: I2993a833d7547a234bdb6c36694f85913215b323
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ChangeScreen.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ChangeScreen.java
index 6819086..8689465 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ChangeScreen.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ChangeScreen.java
@@ -88,6 +88,7 @@
   private KeyCommandSet keysAction;
   private HandlerRegistration regNavigation;
   private HandlerRegistration regAction;
+  private HandlerRegistration regDetailCache;
 
   private Grid patchesGrid;
   private ListBox patchesList;
@@ -132,6 +133,10 @@
       regAction.removeHandler();
       regAction = null;
     }
+    if (regDetailCache != null) {
+      regDetailCache.removeHandler();
+      regDetailCache = null;
+    }
     super.onUnload();
   }
 
@@ -152,7 +157,7 @@
     ChangeCache cache = ChangeCache.get(changeId);
 
     detailCache = cache.getChangeDetailCache();
-    detailCache.addValueChangeHandler(this);
+    regDetailCache = detailCache.addValueChangeHandler(this);
 
     addStyleName(Gerrit.RESOURCES.css().changeScreen());
     addStyleName(Gerrit.RESOURCES.css().screenNoHeader());
@@ -263,7 +268,7 @@
 
   @Override
   public void onValueChange(final ValueChangeEvent<ChangeDetail> event) {
-    if (isAttached()) {
+    if (isAttached() && isLastValueChangeHandler()) {
       // Until this screen is fully migrated to the new API, these calls must
       // happen sequentially after the ChangeDetail lookup, because we can't
       // start an async get at the source of every call that might trigger a
@@ -295,6 +300,15 @@
     }
   }
 
+  // Find the last attached screen.
+  // When DialogBox is used (i. e. CommentedActionDialog) then the original
+  // ChangeScreen is still in attached state.
+  // Use here the fact, that the handlers (ChangeScreen) are sorted.
+  private boolean isLastValueChangeHandler() {
+    int count = detailCache.getHandlerCount();
+    return count > 0 && detailCache.getHandler(count - 1) == this;
+  }
+
   private void display(final ChangeDetail detail) {
     displayTitle(detail.getChange().getKey(), detail.getChange().getSubject());
     discardDiffBaseIfNotApplicable(detail.getChange().getId());
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/ui/ListenableValue.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/ui/ListenableValue.java
index 6dad875..d834eb2 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/ui/ListenableValue.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/ui/ListenableValue.java
@@ -45,4 +45,13 @@
       ValueChangeHandler<T> handler) {
     return manager.addHandler(ValueChangeEvent.getType(), handler);
   }
+
+  public int getHandlerCount() {
+    return manager.getHandlerCount(ValueChangeEvent.getType());
+  }
+
+  public ValueChangeHandler<?> getHandler(int index) {
+    return manager.getHandler(ValueChangeEvent.getType(), index);
+  }
+
 }