Merge changes Iaa8658bd,Ifdae88ec into stable-2.4

* changes:
  Fix deadlock on destroy of CommandFactoryProvider.
  Use AtomicBoolean for "logged" in CommandFactoryProvider.
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/git/MergeOp.java b/gerrit-server/src/main/java/com/google/gerrit/server/git/MergeOp.java
index f862ff0..4773680 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/git/MergeOp.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/git/MergeOp.java
@@ -37,7 +37,6 @@
 import com.google.gerrit.server.IdentifiedUser;
 import com.google.gerrit.server.account.AccountCache;
 import com.google.gerrit.server.config.CanonicalWebUrl;
-import com.google.gerrit.server.mail.EmailException;
 import com.google.gerrit.server.mail.MergeFailSender;
 import com.google.gerrit.server.mail.MergedSender;
 import com.google.gerrit.server.patch.PatchSetInfoFactory;
@@ -1047,7 +1046,7 @@
     }
   }
 
-  private boolean isMergeable(Change c) throws OrmException {
+  private boolean isMergeable(Change c) {
     final CodeReviewCommit commit = commits.get(c.getId());
     final CommitMergeStatus s = commit != null ? commit.statusCode : null;
     boolean isMergeable = false;
@@ -1061,7 +1060,7 @@
     return isMergeable;
   }
 
-  private void updateChangeStatus() throws MergeException {
+  private void updateChangeStatus() {
     List<CodeReviewCommit> merged = new ArrayList<CodeReviewCommit>();
 
     for (final Change c : submitted) {
@@ -1127,7 +1126,7 @@
         GitRepositoryManager.REFS_NOTES_REVIEW);
   }
 
-  private void updateSubscriptions() throws MergeException {
+  private void updateSubscriptions() {
     if (mergeTip != null && (branchTip == null || branchTip != mergeTip)) {
       SubmoduleOp subOp =
           subOpFactory.create(destBranch, mergeTip, rw, repo, destProject,
@@ -1410,7 +1409,7 @@
           } finally {
             reviewDb.close();
           }
-        } catch (OrmException e) {
+        } catch (Exception e) {
           log.error("Cannot send email for submitted patch set " + c.getId(), e);
           return;
         }
@@ -1422,7 +1421,7 @@
           }
           cm.setPatchSet(patchSet);
           cm.send();
-        } catch (EmailException e) {
+        } catch (Exception e) {
           log.error("Cannot send email for submitted patch set " + c.getId(), e);
         }
       }
@@ -1493,7 +1492,7 @@
           } finally {
             reviewDb.close();
           }
-        } catch (OrmException e) {
+        } catch (Exception e) {
           log.error("Cannot send email notifications about merge failure", e);
           return;
         }
@@ -1506,7 +1505,7 @@
           cm.setPatchSet(patchSet);
           cm.setChangeMessage(msg);
           cm.send();
-        } catch (EmailException e) {
+        } catch (Exception e) {
           log.error("Cannot send email notifications about merge failure", e);
         }
       }
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/git/ReceiveCommits.java b/gerrit-server/src/main/java/com/google/gerrit/server/git/ReceiveCommits.java
index b8d133e..04224d9 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/git/ReceiveCommits.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/git/ReceiveCommits.java
@@ -44,7 +44,6 @@
 import com.google.gerrit.server.config.TrackingFooters;
 import com.google.gerrit.server.git.MultiProgressMonitor.Task;
 import com.google.gerrit.server.mail.CreateChangeSender;
-import com.google.gerrit.server.mail.EmailException;
 import com.google.gerrit.server.mail.MergedSender;
 import com.google.gerrit.server.mail.ReplacePatchSetSender;
 import com.google.gerrit.server.patch.PatchSetInfoFactory;
@@ -1122,7 +1121,7 @@
           cm.addReviewers(reviewers);
           cm.addExtraCC(cc);
           cm.send();
-        } catch (EmailException e) {
+        } catch (Exception e) {
           log.error("Cannot send email for new change " + change.getId(), e);
         }
       }
@@ -1473,7 +1472,7 @@
           cm.addReviewers(oldReviewers);
           cm.addExtraCC(oldCC);
           cm.send();
-        } catch (EmailException e) {
+        } catch (Exception e) {
           log.error("Cannot send email for new patch set " + ps.getId(), e);
         }
       }
@@ -2012,7 +2011,7 @@
             cm.setFrom(currentUser.getAccountId());
             cm.setPatchSet(result.patchSet, result.info);
             cm.send();
-          } catch (EmailException e) {
+          } catch (Exception e) {
             final PatchSet.Id psi = result.patchSet.getId();
             log.error("Cannot send email for submitted patch set " + psi, e);
           }
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/patch/PatchList.java b/gerrit-server/src/main/java/com/google/gerrit/server/patch/PatchList.java
index aab8e39..93d7bf7 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/patch/PatchList.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/patch/PatchList.java
@@ -142,8 +142,12 @@
   }
 
   private int search(final String fileName) {
+    if (Patch.COMMIT_MSG.equals(fileName)) {
+      return 0;
+    }
+
     int high = patches.length;
-    int low = 0;
+    int low = 1;
     while (low < high) {
       final int mid = (low + high) >>> 1;
       final int cmp = patches[mid].getNewName().compareTo(fileName);
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/patch/PublishComments.java b/gerrit-server/src/main/java/com/google/gerrit/server/patch/PublishComments.java
index 17c690f..fdabcaa 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/patch/PublishComments.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/patch/PublishComments.java
@@ -30,7 +30,6 @@
 import com.google.gerrit.server.IdentifiedUser;
 import com.google.gerrit.server.git.WorkQueue;
 import com.google.gerrit.server.mail.CommentSender;
-import com.google.gerrit.server.mail.EmailException;
 import com.google.gerrit.server.project.ChangeControl;
 import com.google.gerrit.server.project.InvalidChangeOperationException;
 import com.google.gerrit.server.project.NoSuchChangeException;
@@ -332,7 +331,7 @@
         } catch (PatchSetInfoNotAvailableException e) {
           log.error("Cannot read PatchSetInfo of " + patchSetId, e);
           return;
-        } catch (OrmException e) {
+        } catch (Exception e) {
           log.error("Cannot email comments for " + patchSetId, e);
           return;
         }
@@ -344,7 +343,7 @@
           cm.setChangeMessage(message);
           cm.setPatchLineComments(drafts);
           cm.send();
-        } catch (EmailException e) {
+        } catch (Exception e) {
           log.error("Cannot email comments for " + patchSetId, e);
         }
       }
diff --git a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/SshScope.java b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/SshScope.java
index f923d80..92609b5 100644
--- a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/SshScope.java
+++ b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/SshScope.java
@@ -39,7 +39,7 @@
     volatile long started;
     volatile long finished;
 
-    Context(final SshSession s, final String c) {
+    private Context(final SshSession s, final String c, final long at) {
       cleanup = new RequestCleanup();
       session = s;
       commandLine = c;
@@ -47,25 +47,17 @@
       map = new HashMap<Key<?>, Object>();
       map.put(RC_KEY, cleanup);
 
-      final long now = System.currentTimeMillis();
-      created = now;
-      started = now;
-      finished = now;
+      created = started = finished = at;
     }
 
     private Context(Context p, SshSession s, String c) {
-      cleanup = new RequestCleanup();
-      session = s;
-      commandLine = c;
-
-      map = new HashMap<Key<?>, Object>();
-      map.put(RC_KEY, cleanup);
-
-      created = p.created;
+      this(s, c, p.created);
       started = p.started;
       finished = p.finished;
+    }
 
-      p.cleanup.add(cleanup);
+    Context(final SshSession s, final String c) {
+      this(s, c, System.currentTimeMillis());
     }
 
     String getCommandLine() {
@@ -87,7 +79,9 @@
     }
 
     synchronized Context subContext(SshSession newSession, String newCommandLine) {
-      return new Context(this, newSession, newCommandLine);
+      Context ctx = new Context(this, newSession, newCommandLine);
+      cleanup.add(ctx.cleanup);
+      return ctx;
     }
   }
 
@@ -112,7 +106,9 @@
 
     @Override
     protected Context continuingContext(Context ctx) {
-      return ctx.subContext(ctx.getSession(), ctx.getCommandLine());
+      // The cleanup is not chained, since the RequestScopePropagator executors
+      // the Context's cleanup when finished executing.
+      return new Context(ctx, ctx.getSession(), ctx.getCommandLine());
     }
   }