Merge branch 'master' into stable-5.4

* master:
  ReachabilityCheckers: @since 5.4
  Update Orbit to S20190521195709 for 2019-06 M3
  Tune max heap size for tests
  GPG: check that the key found is a signing key
  GPG: use key fingerprint suffix to compare id for signing key
  Recognize ReachabilityCheckerTestCase as helper
  UploadPack: restore inadvertently deleted line
  UploadPack: Use reachability checker to validate non-advertised wants
  Bazel: Simplify names of bouncy castle libraries
  Convert to lambda or member reference
  BitmappedReachabilityChecker: Reachability check using bitmaps
  BitmapCalculator: Get the reachability bitmap of a commit
  ReachabilityChecker: Default implementation with a RevWalk

Change-Id: I323c460853230abcffa94c4f34f15dbaff8c330c
diff --git a/WORKSPACE b/WORKSPACE
index 8ee3fec..7ddd554 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -215,21 +215,21 @@
 BOUNCYCASTLE_VER = "1.60"
 
 maven_jar(
-    name = "bcpg-jdk15on",
+    name = "bcpg",
     artifact = "org.bouncycastle:bcpg-jdk15on:" + BOUNCYCASTLE_VER,
     sha1 = "13c7a199c484127daad298996e95818478431a2c",
     src_sha1 = "edcd9e86d95e39b4da39bb295efd93bc4f56266e",
 )
 
 maven_jar(
-    name = "bcprov-jdk15on",
+    name = "bcprov",
     artifact = "org.bouncycastle:bcprov-jdk15on:" + BOUNCYCASTLE_VER,
     sha1 = "bd47ad3bd14b8e82595c7adaa143501e60842a84",
     src_sha1 = "7c57a4d13fe53d9abb967bba600dd0b293dafd6a",
 )
 
 maven_jar(
-    name = "bcpkix-jdk15on",
+    name = "bcpkix",
     artifact = "org.bouncycastle:bcpkix-jdk15on:" + BOUNCYCASTLE_VER,
     sha1 = "d0c46320fbc07be3a24eb13a56cee4e3d38e0c75",
     src_sha1 = "a25f041293f401af08efba63ff4bbdce98134a03",
diff --git a/lib/BUILD b/lib/BUILD
index 992f7bd..f41ad16 100644
--- a/lib/BUILD
+++ b/lib/BUILD
@@ -153,7 +153,7 @@
         "//org.eclipse.jgit:__pkg__",
         "//org.eclipse.jgit.test:__pkg__",
     ],
-    exports = ["@bcpg-jdk15on//jar"],
+    exports = ["@bcpg//jar"],
 )
 
 java_library(
@@ -162,7 +162,7 @@
         "//org.eclipse.jgit:__pkg__",
         "//org.eclipse.jgit.test:__pkg__",
     ],
-    exports = ["@bcprov-jdk15on//jar"],
+    exports = ["@bcprov//jar"],
 )
 
 java_library(
@@ -171,7 +171,7 @@
         "//org.eclipse.jgit:__pkg__",
         "//org.eclipse.jgit.test:__pkg__",
     ],
-    exports = ["@bcpkix-jdk15on//jar"],
+    exports = ["@bcpkix//jar"],
 )
 
 java_library(
diff --git a/org.eclipse.jgit.ant.test/pom.xml b/org.eclipse.jgit.ant.test/pom.xml
index cdf88e7..0ba52d4 100644
--- a/org.eclipse.jgit.ant.test/pom.xml
+++ b/org.eclipse.jgit.ant.test/pom.xml
@@ -105,7 +105,7 @@
       <plugin>
         <artifactId>maven-surefire-plugin</artifactId>
         <configuration>
-          <argLine>@{argLine} -Xmx256m -Dfile.encoding=UTF-8 -Djava.io.tmpdir=${project.build.directory}</argLine>
+          <argLine>@{argLine} -Xmx512m -Dfile.encoding=UTF-8 -Djava.io.tmpdir=${project.build.directory}</argLine>
         </configuration>
       </plugin>
     </plugins>
diff --git a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/glue/MetaServlet.java b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/glue/MetaServlet.java
index d8fa712..14b6506 100644
--- a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/glue/MetaServlet.java
+++ b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/glue/MetaServlet.java
@@ -47,7 +47,6 @@
 
 import java.io.IOException;
 
-import javax.servlet.FilterChain;
 import javax.servlet.ServletConfig;
 import javax.servlet.ServletContext;
 import javax.servlet.ServletException;
@@ -140,14 +139,10 @@ public void destroy() {
 	@Override
 	protected void service(HttpServletRequest req, HttpServletResponse res)
 			throws ServletException, IOException {
-		filter.doFilter(req, res, new FilterChain() {
-			@Override
-			public void doFilter(ServletRequest request,
-					ServletResponse response) throws IOException,
-					ServletException {
-				((HttpServletResponse) response).sendError(SC_NOT_FOUND);
-			}
-		});
+		filter.doFilter(req, res,
+				(ServletRequest request, ServletResponse response) -> {
+					((HttpServletResponse) response).sendError(SC_NOT_FOUND);
+				});
 	}
 
 	/**
diff --git a/org.eclipse.jgit.http.test/pom.xml b/org.eclipse.jgit.http.test/pom.xml
index 2426cb5..df8dc27 100644
--- a/org.eclipse.jgit.http.test/pom.xml
+++ b/org.eclipse.jgit.http.test/pom.xml
@@ -139,7 +139,7 @@
       <plugin>
         <artifactId>maven-surefire-plugin</artifactId>
         <configuration>
-          <argLine>@{argLine} -Djava.io.tmpdir=${project.build.directory}  -Xmx300m</argLine>
+          <argLine>@{argLine} -Djava.io.tmpdir=${project.build.directory}  -Xmx512m</argLine>
           <includes>
             <include>**/*Test.java</include>
             <include>**/*Tests.java</include>
diff --git a/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/AdvertiseErrorTest.java b/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/AdvertiseErrorTest.java
index 5a46967..ec9ced0 100644
--- a/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/AdvertiseErrorTest.java
+++ b/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/AdvertiseErrorTest.java
@@ -69,7 +69,6 @@
 import org.eclipse.jgit.transport.RemoteRefUpdate;
 import org.eclipse.jgit.transport.Transport;
 import org.eclipse.jgit.transport.URIish;
-import org.eclipse.jgit.transport.resolver.RepositoryResolver;
 import org.eclipse.jgit.transport.resolver.ServiceNotAuthorizedException;
 import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException;
 import org.junit.Before;
@@ -90,18 +89,13 @@ public void setUp() throws Exception {
 
 		ServletContextHandler app = server.addContext("/git");
 		GitServlet gs = new GitServlet();
-		gs.setRepositoryResolver(new RepositoryResolver<HttpServletRequest>() {
-			@Override
-			public Repository open(HttpServletRequest req, String name)
-					throws RepositoryNotFoundException,
-					ServiceNotEnabledException {
-				if (!name.equals(srcName))
-					throw new RepositoryNotFoundException(name);
-
-				final Repository db = src.getRepository();
-				db.incrementOpen();
-				return db;
+		gs.setRepositoryResolver((HttpServletRequest req, String name) -> {
+			if (!name.equals(srcName)) {
+				throw new RepositoryNotFoundException(name);
 			}
+			final Repository db = src.getRepository();
+			db.incrementOpen();
+			return db;
 		});
 		gs.setReceivePackFactory(new DefaultReceivePackFactory() {
 			@Override
diff --git a/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/GitServletResponseTests.java b/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/GitServletResponseTests.java
index 8dce98b..eb19365 100644
--- a/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/GitServletResponseTests.java
+++ b/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/GitServletResponseTests.java
@@ -75,7 +75,6 @@
 import org.eclipse.jgit.transport.RemoteRefUpdate;
 import org.eclipse.jgit.transport.Transport;
 import org.eclipse.jgit.transport.URIish;
-import org.eclipse.jgit.transport.resolver.RepositoryResolver;
 import org.eclipse.jgit.transport.resolver.ServiceNotAuthorizedException;
 import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException;
 import org.junit.Before;
@@ -117,18 +116,13 @@ public void setUp() throws Exception {
 
 		ServletContextHandler app = server.addContext("/git");
 		gs = new GitServlet();
-		gs.setRepositoryResolver(new RepositoryResolver<HttpServletRequest>() {
-			@Override
-			public Repository open(HttpServletRequest req, String name)
-					throws RepositoryNotFoundException,
-					ServiceNotEnabledException {
-				if (!name.equals(repoName))
-					throw new RepositoryNotFoundException(name);
-
-				final Repository db = srv.getRepository();
-				db.incrementOpen();
-				return db;
+		gs.setRepositoryResolver((HttpServletRequest req, String name) -> {
+			if (!name.equals(repoName)) {
+				throw new RepositoryNotFoundException(name);
 			}
+			final Repository db = srv.getRepository();
+			db.incrementOpen();
+			return db;
 		});
 		gs.setReceivePackFactory(new DefaultReceivePackFactory() {
 			@Override
@@ -179,12 +173,8 @@ public void testRuntimeExceptionInPreReceiveHook() throws Exception {
 
 		maxPackSize = 0;
 		postHook = null;
-		preHook = new PreReceiveHook() {
-			@Override
-			public void onPreReceive(ReceivePack rp,
-					Collection<ReceiveCommand> commands) {
-				throw new IllegalStateException();
-			}
+		preHook = (ReceivePack rp, Collection<ReceiveCommand> commands) -> {
+			throw new IllegalStateException();
 		};
 
 		try (Transport t = Transport.open(clientRepo, srvURI)) {
@@ -263,15 +253,11 @@ public void testUnpackErrorWithSubsequentExceptionInPostReceiveHook()
 		maxPackSize = 100;
 		// this PostReceiveHook when called after an unsuccesfull unpack will
 		// lead to an IllegalStateException
-		postHook = new PostReceiveHook() {
-			@Override
-			public void onPostReceive(ReceivePack rp,
-					Collection<ReceiveCommand> commands) {
-				// the maxPackSize setting caused that the packfile couldn't be
-				// saved to disk. Calling getPackSize() now will lead to a
-				// IllegalStateException.
-				rp.getPackSize();
-			}
+		postHook = (ReceivePack rp, Collection<ReceiveCommand> commands) -> {
+			// the maxPackSize setting caused that the packfile couldn't be
+			// saved to disk. Calling getPackSize() now will lead to a
+			// IllegalStateException.
+			rp.getPackSize();
 		};
 
 		try (Transport t = Transport.open(clientRepo, srvURI)) {
diff --git a/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/HookMessageTest.java b/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/HookMessageTest.java
index 5a5ff1a..49ff51a 100644
--- a/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/HookMessageTest.java
+++ b/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/HookMessageTest.java
@@ -70,14 +70,12 @@
 import org.eclipse.jgit.lib.StoredConfig;
 import org.eclipse.jgit.revwalk.RevBlob;
 import org.eclipse.jgit.revwalk.RevCommit;
-import org.eclipse.jgit.transport.PreReceiveHook;
 import org.eclipse.jgit.transport.PushResult;
 import org.eclipse.jgit.transport.ReceiveCommand;
 import org.eclipse.jgit.transport.ReceivePack;
 import org.eclipse.jgit.transport.RemoteRefUpdate;
 import org.eclipse.jgit.transport.Transport;
 import org.eclipse.jgit.transport.URIish;
-import org.eclipse.jgit.transport.resolver.RepositoryResolver;
 import org.eclipse.jgit.transport.resolver.ServiceNotAuthorizedException;
 import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException;
 import org.junit.Before;
@@ -98,18 +96,13 @@ public void setUp() throws Exception {
 
 		ServletContextHandler app = server.addContext("/git");
 		GitServlet gs = new GitServlet();
-		gs.setRepositoryResolver(new RepositoryResolver<HttpServletRequest>() {
-			@Override
-			public Repository open(HttpServletRequest req, String name)
-					throws RepositoryNotFoundException,
-					ServiceNotEnabledException {
-				if (!name.equals(srcName))
-					throw new RepositoryNotFoundException(name);
-
-				final Repository db = src.getRepository();
-				db.incrementOpen();
-				return db;
+		gs.setRepositoryResolver((HttpServletRequest req, String name) -> {
+			if (!name.equals(srcName)) {
+				throw new RepositoryNotFoundException(name);
 			}
+			final Repository db = src.getRepository();
+			db.incrementOpen();
+			return db;
 		});
 		gs.setReceivePackFactory(new DefaultReceivePackFactory() {
 			@Override
@@ -117,14 +110,11 @@ public ReceivePack create(HttpServletRequest req, Repository db)
 					throws ServiceNotEnabledException,
 					ServiceNotAuthorizedException {
 				ReceivePack recv = super.create(req, db);
-				recv.setPreReceiveHook(new PreReceiveHook() {
-					@Override
-					public void onPreReceive(ReceivePack rp,
-							Collection<ReceiveCommand> commands) {
-						rp.sendMessage("message line 1");
-						rp.sendError("no soup for you!");
-						rp.sendMessage("come back next year!");
-					}
+				recv.setPreReceiveHook((ReceivePack rp,
+						Collection<ReceiveCommand> commands) -> {
+					rp.sendMessage("message line 1");
+					rp.sendError("no soup for you!");
+					rp.sendMessage("come back next year!");
 				});
 				return recv;
 			}
diff --git a/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/HttpClientTests.java b/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/HttpClientTests.java
index 53626b1..1660f14 100644
--- a/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/HttpClientTests.java
+++ b/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/HttpClientTests.java
@@ -87,8 +87,6 @@
 import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider;
 import org.eclipse.jgit.transport.http.HttpConnection;
 import org.eclipse.jgit.transport.http.JDKHttpConnectionFactory;
-import org.eclipse.jgit.transport.resolver.RepositoryResolver;
-import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException;
 import org.junit.Before;
 import org.junit.Test;
 
@@ -141,18 +139,13 @@ private ServletContextHandler dumb(String path) {
 
 	private ServletContextHandler smart(String path) {
 		GitServlet gs = new GitServlet();
-		gs.setRepositoryResolver(new RepositoryResolver<HttpServletRequest>() {
-			@Override
-			public Repository open(HttpServletRequest req, String name)
-					throws RepositoryNotFoundException,
-					ServiceNotEnabledException {
-				final Repository db = remoteRepository.getRepository();
-				if (!name.equals(nameOf(db)))
-					throw new RepositoryNotFoundException(name);
-
-				db.incrementOpen();
-				return db;
+		gs.setRepositoryResolver((HttpServletRequest req, String name) -> {
+			final Repository db = remoteRepository.getRepository();
+			if (!name.equals(nameOf(db))) {
+				throw new RepositoryNotFoundException(name);
 			}
+			db.incrementOpen();
+			return db;
 		});
 
 		ServletContextHandler ctx = server.addContext(path);
diff --git a/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/MeasurePackSizeTest.java b/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/MeasurePackSizeTest.java
index 0415bcb..79df5a2 100644
--- a/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/MeasurePackSizeTest.java
+++ b/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/MeasurePackSizeTest.java
@@ -63,14 +63,12 @@
 import org.eclipse.jgit.lib.StoredConfig;
 import org.eclipse.jgit.revwalk.RevBlob;
 import org.eclipse.jgit.revwalk.RevCommit;
-import org.eclipse.jgit.transport.PostReceiveHook;
 import org.eclipse.jgit.transport.PushResult;
 import org.eclipse.jgit.transport.ReceiveCommand;
 import org.eclipse.jgit.transport.ReceivePack;
 import org.eclipse.jgit.transport.RemoteRefUpdate;
 import org.eclipse.jgit.transport.Transport;
 import org.eclipse.jgit.transport.URIish;
-import org.eclipse.jgit.transport.resolver.RepositoryResolver;
 import org.eclipse.jgit.transport.resolver.ServiceNotAuthorizedException;
 import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException;
 import org.junit.Before;
@@ -93,18 +91,13 @@ public void setUp() throws Exception {
 
 		ServletContextHandler app = server.addContext("/git");
 		GitServlet gs = new GitServlet();
-		gs.setRepositoryResolver(new RepositoryResolver<HttpServletRequest>() {
-			@Override
-			public Repository open(HttpServletRequest req, String name)
-					throws RepositoryNotFoundException,
-					ServiceNotEnabledException {
-				if (!name.equals(srcName))
-					throw new RepositoryNotFoundException(name);
-
-				final Repository db = src.getRepository();
-				db.incrementOpen();
-				return db;
+		gs.setRepositoryResolver((HttpServletRequest req, String name) -> {
+			if (!name.equals(srcName)) {
+				throw new RepositoryNotFoundException(name);
 			}
+			final Repository db = src.getRepository();
+			db.incrementOpen();
+			return db;
 		});
 		gs.setReceivePackFactory(new DefaultReceivePackFactory() {
 			@Override
@@ -112,13 +105,9 @@ public ReceivePack create(HttpServletRequest req, Repository db)
 					throws ServiceNotEnabledException,
 					ServiceNotAuthorizedException {
 				ReceivePack recv = super.create(req, db);
-				recv.setPostReceiveHook(new PostReceiveHook() {
-
-					@Override
-					public void onPostReceive(ReceivePack rp,
-							Collection<ReceiveCommand> commands) {
-						packSize = rp.getPackSize();
-					}
+				recv.setPostReceiveHook((ReceivePack rp,
+						Collection<ReceiveCommand> commands) -> {
+					packSize = rp.getPackSize();
 				});
 				return recv;
 			}
diff --git a/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/ProtocolErrorTest.java b/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/ProtocolErrorTest.java
index a1baae3..f0fac5a 100644
--- a/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/ProtocolErrorTest.java
+++ b/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/ProtocolErrorTest.java
@@ -71,8 +71,6 @@
 import org.eclipse.jgit.transport.PacketLineIn;
 import org.eclipse.jgit.transport.PacketLineOut;
 import org.eclipse.jgit.transport.URIish;
-import org.eclipse.jgit.transport.resolver.RepositoryResolver;
-import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException;
 import org.eclipse.jgit.util.NB;
 import org.junit.Before;
 import org.junit.Test;
@@ -94,18 +92,13 @@ public void setUp() throws Exception {
 
 		ServletContextHandler app = server.addContext("/git");
 		GitServlet gs = new GitServlet();
-		gs.setRepositoryResolver(new RepositoryResolver<HttpServletRequest>() {
-			@Override
-			public Repository open(HttpServletRequest req, String name)
-					throws RepositoryNotFoundException,
-					ServiceNotEnabledException {
-				if (!name.equals(srcName))
-					throw new RepositoryNotFoundException(name);
-
-				final Repository db = src.getRepository();
-				db.incrementOpen();
-				return db;
+		gs.setRepositoryResolver((HttpServletRequest req, String name) -> {
+			if (!name.equals(srcName)) {
+				throw new RepositoryNotFoundException(name);
 			}
+			final Repository db = src.getRepository();
+			db.incrementOpen();
+			return db;
 		});
 		app.addServlet(new ServletHolder(gs), "/*");
 
diff --git a/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/SmartClientSmartServerTest.java b/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/SmartClientSmartServerTest.java
index aad029c..54c1c03 100644
--- a/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/SmartClientSmartServerTest.java
+++ b/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/SmartClientSmartServerTest.java
@@ -124,9 +124,6 @@
 import org.eclipse.jgit.transport.http.HttpConnectionFactory;
 import org.eclipse.jgit.transport.http.JDKHttpConnectionFactory;
 import org.eclipse.jgit.transport.http.apache.HttpClientConnectionFactory;
-import org.eclipse.jgit.transport.resolver.ServiceNotAuthorizedException;
-import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException;
-import org.eclipse.jgit.transport.resolver.UploadPackFactory;
 import org.eclipse.jgit.util.FS;
 import org.eclipse.jgit.util.HttpSupport;
 import org.eclipse.jgit.util.SystemReader;
@@ -192,18 +189,13 @@ public void setUp() throws Exception {
 						ConfigConstants.CONFIG_KEY_LOGALLREFUPDATES, true);
 
 		GitServlet gs = new GitServlet();
-		gs.setUploadPackFactory(new UploadPackFactory<HttpServletRequest>() {
-			@Override
-			public UploadPack create(HttpServletRequest req, Repository db)
-					throws ServiceNotEnabledException,
-					ServiceNotAuthorizedException {
-				DefaultUploadPackFactory f = new DefaultUploadPackFactory();
-				UploadPack up = f.create(req, db);
-				if (advertiseRefsHook != null) {
-					up.setAdvertiseRefsHook(advertiseRefsHook);
-				}
-				return up;
+		gs.setUploadPackFactory((HttpServletRequest req, Repository db) -> {
+			DefaultUploadPackFactory f = new DefaultUploadPackFactory();
+			UploadPack up = f.create(req, db);
+			if (advertiseRefsHook != null) {
+				up.setAdvertiseRefsHook(advertiseRefsHook);
 			}
+			return up;
 		});
 
 		ServletContextHandler app = addNormalContext(gs, src, srcName);
diff --git a/org.eclipse.jgit.junit.http/src/org/eclipse/jgit/junit/http/SimpleHttpServer.java b/org.eclipse.jgit.junit.http/src/org/eclipse/jgit/junit/http/SimpleHttpServer.java
index 245b510..7c78330 100644
--- a/org.eclipse.jgit.junit.http/src/org/eclipse/jgit/junit/http/SimpleHttpServer.java
+++ b/org.eclipse.jgit.junit.http/src/org/eclipse/jgit/junit/http/SimpleHttpServer.java
@@ -54,8 +54,6 @@
 import org.eclipse.jgit.http.server.GitServlet;
 import org.eclipse.jgit.lib.Repository;
 import org.eclipse.jgit.transport.URIish;
-import org.eclipse.jgit.transport.resolver.RepositoryResolver;
-import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException;
 
 /**
  * Simple http server for testing http access to Git repositories.
@@ -136,17 +134,12 @@ public URIish getSecureUri() {
 
 	private ServletContextHandler smart(String path) {
 		GitServlet gs = new GitServlet();
-		gs.setRepositoryResolver(new RepositoryResolver<HttpServletRequest>() {
-			@Override
-			public Repository open(HttpServletRequest req, String name)
-					throws RepositoryNotFoundException,
-					ServiceNotEnabledException {
-				if (!name.equals(nameOf(db)))
-					throw new RepositoryNotFoundException(name);
-
-				db.incrementOpen();
-				return db;
+		gs.setRepositoryResolver((HttpServletRequest req, String name) -> {
+			if (!name.equals(nameOf(db))) {
+				throw new RepositoryNotFoundException(name);
 			}
+			db.incrementOpen();
+			return db;
 		});
 
 		ServletContextHandler ctx = server.addContext(path);
diff --git a/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/MockSystemReader.java b/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/MockSystemReader.java
index 8de386e..89f2530 100644
--- a/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/MockSystemReader.java
+++ b/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/MockSystemReader.java
@@ -171,22 +171,20 @@ public long getCurrentTime() {
 	/** {@inheritDoc} */
 	@Override
 	public MonotonicClock getClock() {
-		return new MonotonicClock() {
-			@Override
-			public ProposedTimestamp propose() {
-				long t = getCurrentTime();
-				return new ProposedTimestamp() {
-					@Override
-					public long read(TimeUnit unit) {
-						return unit.convert(t, TimeUnit.MILLISECONDS);
-					}
+		return () -> {
+			long t = getCurrentTime();
+			return new ProposedTimestamp() {
 
-					@Override
-					public void blockUntil(Duration maxWait) {
-						// Do not wait.
-					}
-				};
-			}
+				@Override
+				public long read(TimeUnit unit) {
+					return unit.convert(t, TimeUnit.MILLISECONDS);
+				}
+
+				@Override
+				public void blockUntil(Duration maxWait) {
+					// Do not wait.
+				}
+			};
 		};
 	}
 
diff --git a/org.eclipse.jgit.lfs.server.test/BUILD b/org.eclipse.jgit.lfs.server.test/BUILD
index 1341dd6..fb0d691 100644
--- a/org.eclipse.jgit.lfs.server.test/BUILD
+++ b/org.eclipse.jgit.lfs.server.test/BUILD
@@ -32,7 +32,7 @@
         exclude = TEST_BASE,
     ),
     jvm_flags = [
-        "-Xmx256m",
+        "-Xmx512m",
         "-Dfile.encoding=UTF-8",
     ],
     tags = ["lfs-server"],
diff --git a/org.eclipse.jgit.lfs.server.test/pom.xml b/org.eclipse.jgit.lfs.server.test/pom.xml
index 41ce510..ce1e280 100644
--- a/org.eclipse.jgit.lfs.server.test/pom.xml
+++ b/org.eclipse.jgit.lfs.server.test/pom.xml
@@ -137,7 +137,7 @@
       <plugin>
         <artifactId>maven-surefire-plugin</artifactId>
         <configuration>
-          <argLine>@{argLine} -Djava.io.tmpdir=${project.build.directory}  -Xmx300m</argLine>
+          <argLine>@{argLine} -Djava.io.tmpdir=${project.build.directory}  -Xmx512m</argLine>
         </configuration>
       </plugin>
     </plugins>
diff --git a/org.eclipse.jgit.lfs.server.test/tst/org/eclipse/jgit/lfs/server/fs/UploadTest.java b/org.eclipse.jgit.lfs.server.test/tst/org/eclipse/jgit/lfs/server/fs/UploadTest.java
index 09f8d0a..c6f9535 100644
--- a/org.eclipse.jgit.lfs.server.test/tst/org/eclipse/jgit/lfs/server/fs/UploadTest.java
+++ b/org.eclipse.jgit.lfs.server.test/tst/org/eclipse/jgit/lfs/server/fs/UploadTest.java
@@ -53,7 +53,6 @@
 import java.text.MessageFormat;
 import java.util.ArrayList;
 import java.util.List;
-import java.util.concurrent.Callable;
 import java.util.concurrent.CyclicBarrier;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
@@ -123,13 +122,10 @@ public void testParallelUploads() throws Exception {
 		ExecutorService e = Executors.newFixedThreadPool(count);
 		try {
 			for (Path p : paths) {
-				e.submit(new Callable<Void>() {
-					@Override
-					public Void call() throws Exception {
-						barrier.await();
-						putContent(p);
-						return null;
-					}
+				e.submit(() -> {
+					barrier.await();
+					putContent(p);
+					return null;
 				});
 			}
 		} finally {
diff --git a/org.eclipse.jgit.lfs.test/pom.xml b/org.eclipse.jgit.lfs.test/pom.xml
index 30b73f8..ef97708 100644
--- a/org.eclipse.jgit.lfs.test/pom.xml
+++ b/org.eclipse.jgit.lfs.test/pom.xml
@@ -111,7 +111,7 @@
       <plugin>
         <artifactId>maven-surefire-plugin</artifactId>
         <configuration>
-          <argLine>@{argLine} -Djava.io.tmpdir=${project.build.directory}  -Xmx300m</argLine>
+          <argLine>@{argLine} -Djava.io.tmpdir=${project.build.directory}  -Xmx512m</argLine>
         </configuration>
       </plugin>
     </plugins>
diff --git a/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/CleanFilter.java b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/CleanFilter.java
index 217e46f..80da802 100644
--- a/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/CleanFilter.java
+++ b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/CleanFilter.java
@@ -78,14 +78,7 @@ public class CleanFilter extends FilterCommand {
 	 * The factory is responsible for creating instances of
 	 * {@link org.eclipse.jgit.lfs.CleanFilter}
 	 */
-	public final static FilterCommandFactory FACTORY = new FilterCommandFactory() {
-
-		@Override
-		public FilterCommand create(Repository db, InputStream in,
-				OutputStream out) throws IOException {
-			return new CleanFilter(db, in, out);
-		}
-	};
+	public final static FilterCommandFactory FACTORY = CleanFilter::new;
 
 	/**
 	 * Registers this filter by calling
diff --git a/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/SmudgeFilter.java b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/SmudgeFilter.java
index 7bacf49..6b30da3 100644
--- a/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/SmudgeFilter.java
+++ b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/SmudgeFilter.java
@@ -92,13 +92,7 @@ public class SmudgeFilter extends FilterCommand {
 	 * The factory is responsible for creating instances of
 	 * {@link org.eclipse.jgit.lfs.SmudgeFilter}
 	 */
-	public final static FilterCommandFactory FACTORY = new FilterCommandFactory() {
-		@Override
-		public FilterCommand create(Repository db, InputStream in,
-				OutputStream out) throws IOException {
-			return new SmudgeFilter(db, in, out);
-		}
-	};
+	public final static FilterCommandFactory FACTORY = SmudgeFilter::new;
 
 	/**
 	 * Register this filter in JGit
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.10.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.10.target
index 80086da..440092a 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.10.target
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.10.target
@@ -1,6 +1,9 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?><?pde?><!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --><target name="jgit-4.10" sequenceNumber="1557148658">
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<?pde?>
+<!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl -->
+<target name="jgit-4.10" sequenceNumber="1558537043">
   <locations>
-    <location includeAllPlatforms="false" includeConfigurePhase="true" includeMode="slicer" includeSource="true" type="InstallableUnit">
+    <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
       <unit id="org.eclipse.jetty.client" version="9.4.14.v20181114"/>
       <unit id="org.eclipse.jetty.client.source" version="9.4.14.v20181114"/>
       <unit id="org.eclipse.jetty.continuation" version="9.4.14.v20181114"/>
@@ -19,17 +22,17 @@
       <unit id="org.eclipse.jetty.util.source" version="9.4.14.v20181114"/>
       <repository id="jetty-9.4.14" location="http://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.14.v20181114"/>
     </location>
-    <location includeAllPlatforms="false" includeConfigurePhase="true" includeMode="slicer" includeSource="true" type="InstallableUnit">
-      <unit id="org.apache.ant" version="1.10.5.v20180808-0324"/>
-      <unit id="org.apache.ant.source" version="1.10.5.v20180808-0324"/>
+    <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
+      <unit id="org.apache.ant" version="1.10.6.v20190516-0412"/>
+      <unit id="org.apache.ant.source" version="1.10.6.v20190516-0412"/>
       <unit id="org.apache.commons.codec" version="1.10.0.v20180409-1845"/>
       <unit id="org.apache.commons.codec.source" version="1.10.0.v20180409-1845"/>
       <unit id="org.apache.commons.compress" version="1.18.0.v20181121-2221"/>
       <unit id="org.apache.commons.compress.source" version="1.18.0.v20181121-2221"/>
       <unit id="org.apache.commons.logging" version="1.2.0.v20180409-1502"/>
       <unit id="org.apache.commons.logging.source" version="1.2.0.v20180409-1502"/>
-      <unit id="org.apache.httpcomponents.httpclient" version="4.5.6.v20190213-1430"/>
-      <unit id="org.apache.httpcomponents.httpclient.source" version="4.5.6.v20190213-1430"/>
+      <unit id="org.apache.httpcomponents.httpclient" version="4.5.6.v20190503-0009"/>
+      <unit id="org.apache.httpcomponents.httpclient.source" version="4.5.6.v20190503-0009"/>
       <unit id="org.apache.httpcomponents.httpcore" version="4.4.10.v20190123-2214"/>
       <unit id="org.apache.httpcomponents.httpcore.source" version="4.4.10.v20190123-2214"/>
       <unit id="org.apache.log4j" version="1.2.15.v201012070815"/>
@@ -79,11 +82,11 @@
       <unit id="org.apache.sshd.osgi.source" version="2.2.0.v20190425-2127"/>
       <unit id="org.apache.sshd.sftp" version="2.2.0.v20190425-2127"/>
       <unit id="org.apache.sshd.sftp.source" version="2.2.0.v20190425-2127"/>
-      <repository location="http://download.eclipse.org/tools/orbit/downloads/drops/S20190501151401/repository"/>
+      <repository location="http://download.eclipse.org/tools/orbit/downloads/drops/S20190521195709/repository"/>
     </location>
-    <location includeAllPlatforms="false" includeConfigurePhase="true" includeMode="slicer" includeSource="true" type="InstallableUnit">
+    <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
       <unit id="org.eclipse.osgi" version="0.0.0"/>
       <repository location="http://download.eclipse.org/releases/2018-12/"/>
     </location>
   </locations>
-</target>
\ No newline at end of file
+</target>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.10.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.10.tpd
index 6c0f9f8..5bfd814 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.10.tpd
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.10.tpd
@@ -1,7 +1,7 @@
 target "jgit-4.10" with source configurePhase
 
 include "projects/jetty-9.4.14.tpd"
-include "orbit/S20190501151401.tpd"
+include "orbit/S20190521195709.tpd"
 
 location "http://download.eclipse.org/releases/2018-12/" {
 	org.eclipse.osgi lazy
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.11.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.11.target
index ed4dc51..a3ad331 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.11.target
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.11.target
@@ -1,6 +1,9 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?><?pde?><!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --><target name="jgit-4.11" sequenceNumber="1557148673">
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<?pde?>
+<!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl -->
+<target name="jgit-4.11" sequenceNumber="1558539017">
   <locations>
-    <location includeAllPlatforms="false" includeConfigurePhase="true" includeMode="slicer" includeSource="true" type="InstallableUnit">
+    <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
       <unit id="org.eclipse.jetty.client" version="9.4.14.v20181114"/>
       <unit id="org.eclipse.jetty.client.source" version="9.4.14.v20181114"/>
       <unit id="org.eclipse.jetty.continuation" version="9.4.14.v20181114"/>
@@ -19,17 +22,17 @@
       <unit id="org.eclipse.jetty.util.source" version="9.4.14.v20181114"/>
       <repository id="jetty-9.4.14" location="http://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.14.v20181114"/>
     </location>
-    <location includeAllPlatforms="false" includeConfigurePhase="true" includeMode="slicer" includeSource="true" type="InstallableUnit">
-      <unit id="org.apache.ant" version="1.10.5.v20180808-0324"/>
-      <unit id="org.apache.ant.source" version="1.10.5.v20180808-0324"/>
+    <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
+      <unit id="org.apache.ant" version="1.10.6.v20190516-0412"/>
+      <unit id="org.apache.ant.source" version="1.10.6.v20190516-0412"/>
       <unit id="org.apache.commons.codec" version="1.10.0.v20180409-1845"/>
       <unit id="org.apache.commons.codec.source" version="1.10.0.v20180409-1845"/>
       <unit id="org.apache.commons.compress" version="1.18.0.v20181121-2221"/>
       <unit id="org.apache.commons.compress.source" version="1.18.0.v20181121-2221"/>
       <unit id="org.apache.commons.logging" version="1.2.0.v20180409-1502"/>
       <unit id="org.apache.commons.logging.source" version="1.2.0.v20180409-1502"/>
-      <unit id="org.apache.httpcomponents.httpclient" version="4.5.6.v20190213-1430"/>
-      <unit id="org.apache.httpcomponents.httpclient.source" version="4.5.6.v20190213-1430"/>
+      <unit id="org.apache.httpcomponents.httpclient" version="4.5.6.v20190503-0009"/>
+      <unit id="org.apache.httpcomponents.httpclient.source" version="4.5.6.v20190503-0009"/>
       <unit id="org.apache.httpcomponents.httpcore" version="4.4.10.v20190123-2214"/>
       <unit id="org.apache.httpcomponents.httpcore.source" version="4.4.10.v20190123-2214"/>
       <unit id="org.apache.log4j" version="1.2.15.v201012070815"/>
@@ -79,11 +82,11 @@
       <unit id="org.apache.sshd.osgi.source" version="2.2.0.v20190425-2127"/>
       <unit id="org.apache.sshd.sftp" version="2.2.0.v20190425-2127"/>
       <unit id="org.apache.sshd.sftp.source" version="2.2.0.v20190425-2127"/>
-      <repository location="http://download.eclipse.org/tools/orbit/downloads/drops/S20190501151401/repository"/>
+      <repository location="http://download.eclipse.org/tools/orbit/downloads/drops/S20190521195709/repository"/>
     </location>
-    <location includeAllPlatforms="false" includeConfigurePhase="true" includeMode="slicer" includeSource="true" type="InstallableUnit">
+    <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
       <unit id="org.eclipse.osgi" version="0.0.0"/>
       <repository location="http://download.eclipse.org/releases/2019-03/"/>
     </location>
   </locations>
-</target>
\ No newline at end of file
+</target>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.11.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.11.tpd
index 6d4be47..8b3b509 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.11.tpd
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.11.tpd
@@ -1,7 +1,7 @@
 target "jgit-4.11" with source configurePhase
 
 include "projects/jetty-9.4.14.tpd"
-include "orbit/S20190501151401.tpd"
+include "orbit/S20190521195709.tpd"
 
 location "http://download.eclipse.org/releases/2019-03/" {
 	org.eclipse.osgi lazy
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.12-staging.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.12-staging.target
index aa9d951..2ea7b79 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.12-staging.target
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.12-staging.target
@@ -1,6 +1,9 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?><?pde?><!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --><target name="jgit-4.12-staging" sequenceNumber="1557148680">
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<?pde?>
+<!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl -->
+<target name="jgit-4.12-staging" sequenceNumber="1558539043">
   <locations>
-    <location includeAllPlatforms="false" includeConfigurePhase="true" includeMode="slicer" includeSource="true" type="InstallableUnit">
+    <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
       <unit id="org.eclipse.jetty.client" version="9.4.14.v20181114"/>
       <unit id="org.eclipse.jetty.client.source" version="9.4.14.v20181114"/>
       <unit id="org.eclipse.jetty.continuation" version="9.4.14.v20181114"/>
@@ -19,17 +22,17 @@
       <unit id="org.eclipse.jetty.util.source" version="9.4.14.v20181114"/>
       <repository id="jetty-9.4.14" location="http://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.14.v20181114"/>
     </location>
-    <location includeAllPlatforms="false" includeConfigurePhase="true" includeMode="slicer" includeSource="true" type="InstallableUnit">
-      <unit id="org.apache.ant" version="1.10.5.v20180808-0324"/>
-      <unit id="org.apache.ant.source" version="1.10.5.v20180808-0324"/>
+    <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
+      <unit id="org.apache.ant" version="1.10.6.v20190516-0412"/>
+      <unit id="org.apache.ant.source" version="1.10.6.v20190516-0412"/>
       <unit id="org.apache.commons.codec" version="1.10.0.v20180409-1845"/>
       <unit id="org.apache.commons.codec.source" version="1.10.0.v20180409-1845"/>
       <unit id="org.apache.commons.compress" version="1.18.0.v20181121-2221"/>
       <unit id="org.apache.commons.compress.source" version="1.18.0.v20181121-2221"/>
       <unit id="org.apache.commons.logging" version="1.2.0.v20180409-1502"/>
       <unit id="org.apache.commons.logging.source" version="1.2.0.v20180409-1502"/>
-      <unit id="org.apache.httpcomponents.httpclient" version="4.5.6.v20190213-1430"/>
-      <unit id="org.apache.httpcomponents.httpclient.source" version="4.5.6.v20190213-1430"/>
+      <unit id="org.apache.httpcomponents.httpclient" version="4.5.6.v20190503-0009"/>
+      <unit id="org.apache.httpcomponents.httpclient.source" version="4.5.6.v20190503-0009"/>
       <unit id="org.apache.httpcomponents.httpcore" version="4.4.10.v20190123-2214"/>
       <unit id="org.apache.httpcomponents.httpcore.source" version="4.4.10.v20190123-2214"/>
       <unit id="org.apache.log4j" version="1.2.15.v201012070815"/>
@@ -79,11 +82,11 @@
       <unit id="org.apache.sshd.osgi.source" version="2.2.0.v20190425-2127"/>
       <unit id="org.apache.sshd.sftp" version="2.2.0.v20190425-2127"/>
       <unit id="org.apache.sshd.sftp.source" version="2.2.0.v20190425-2127"/>
-      <repository location="http://download.eclipse.org/tools/orbit/downloads/drops/S20190501151401/repository"/>
+      <repository location="http://download.eclipse.org/tools/orbit/downloads/drops/S20190521195709/repository"/>
     </location>
-    <location includeAllPlatforms="false" includeConfigurePhase="true" includeMode="slicer" includeSource="true" type="InstallableUnit">
+    <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
       <unit id="org.eclipse.osgi" version="0.0.0"/>
       <repository location="http://download.eclipse.org/staging/2019-06/"/>
     </location>
   </locations>
-</target>
\ No newline at end of file
+</target>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.12-staging.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.12-staging.tpd
index 69e6b01..f0cd304 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.12-staging.tpd
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.12-staging.tpd
@@ -1,7 +1,7 @@
 target "jgit-4.12-staging" with source configurePhase
 
 include "projects/jetty-9.4.14.tpd"
-include "orbit/S20190501151401.tpd"
+include "orbit/S20190521195709.tpd"
 
 location "http://download.eclipse.org/staging/2019-06/" {
 	org.eclipse.osgi lazy
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.6.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.6.target
index 2a4103b..64cf3e7 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.6.target
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.6.target
@@ -1,6 +1,9 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?><?pde?><!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --><target name="jgit-4.6" sequenceNumber="1557148684">
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<?pde?>
+<!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl -->
+<target name="jgit-4.6" sequenceNumber="1558539043">
   <locations>
-    <location includeAllPlatforms="false" includeConfigurePhase="true" includeMode="slicer" includeSource="true" type="InstallableUnit">
+    <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
       <unit id="org.eclipse.jetty.client" version="9.4.14.v20181114"/>
       <unit id="org.eclipse.jetty.client.source" version="9.4.14.v20181114"/>
       <unit id="org.eclipse.jetty.continuation" version="9.4.14.v20181114"/>
@@ -19,17 +22,17 @@
       <unit id="org.eclipse.jetty.util.source" version="9.4.14.v20181114"/>
       <repository id="jetty-9.4.14" location="http://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.14.v20181114"/>
     </location>
-    <location includeAllPlatforms="false" includeConfigurePhase="true" includeMode="slicer" includeSource="true" type="InstallableUnit">
-      <unit id="org.apache.ant" version="1.10.5.v20180808-0324"/>
-      <unit id="org.apache.ant.source" version="1.10.5.v20180808-0324"/>
+    <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
+      <unit id="org.apache.ant" version="1.10.6.v20190516-0412"/>
+      <unit id="org.apache.ant.source" version="1.10.6.v20190516-0412"/>
       <unit id="org.apache.commons.codec" version="1.10.0.v20180409-1845"/>
       <unit id="org.apache.commons.codec.source" version="1.10.0.v20180409-1845"/>
       <unit id="org.apache.commons.compress" version="1.18.0.v20181121-2221"/>
       <unit id="org.apache.commons.compress.source" version="1.18.0.v20181121-2221"/>
       <unit id="org.apache.commons.logging" version="1.2.0.v20180409-1502"/>
       <unit id="org.apache.commons.logging.source" version="1.2.0.v20180409-1502"/>
-      <unit id="org.apache.httpcomponents.httpclient" version="4.5.6.v20190213-1430"/>
-      <unit id="org.apache.httpcomponents.httpclient.source" version="4.5.6.v20190213-1430"/>
+      <unit id="org.apache.httpcomponents.httpclient" version="4.5.6.v20190503-0009"/>
+      <unit id="org.apache.httpcomponents.httpclient.source" version="4.5.6.v20190503-0009"/>
       <unit id="org.apache.httpcomponents.httpcore" version="4.4.10.v20190123-2214"/>
       <unit id="org.apache.httpcomponents.httpcore.source" version="4.4.10.v20190123-2214"/>
       <unit id="org.apache.log4j" version="1.2.15.v201012070815"/>
@@ -79,11 +82,11 @@
       <unit id="org.apache.sshd.osgi.source" version="2.2.0.v20190425-2127"/>
       <unit id="org.apache.sshd.sftp" version="2.2.0.v20190425-2127"/>
       <unit id="org.apache.sshd.sftp.source" version="2.2.0.v20190425-2127"/>
-      <repository location="http://download.eclipse.org/tools/orbit/downloads/drops/S20190501151401/repository"/>
+      <repository location="http://download.eclipse.org/tools/orbit/downloads/drops/S20190521195709/repository"/>
     </location>
-    <location includeAllPlatforms="false" includeConfigurePhase="true" includeMode="slicer" includeSource="true" type="InstallableUnit">
+    <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
       <unit id="org.eclipse.osgi" version="0.0.0"/>
       <repository location="http://download.eclipse.org/releases/neon/"/>
     </location>
   </locations>
-</target>
\ No newline at end of file
+</target>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.6.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.6.tpd
index 7a0a68d..8ae721f 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.6.tpd
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.6.tpd
@@ -1,7 +1,7 @@
 target "jgit-4.6" with source configurePhase
 
 include "projects/jetty-9.4.14.tpd"
-include "orbit/S20190501151401.tpd"
+include "orbit/S20190521195709.tpd"
 
 location "http://download.eclipse.org/releases/neon/" {
 	org.eclipse.osgi lazy
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.7.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.7.target
index 53c95ac..eb8c8e9 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.7.target
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.7.target
@@ -1,6 +1,9 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?><?pde?><!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --><target name="jgit-4.7" sequenceNumber="1557148689">
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<?pde?>
+<!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl -->
+<target name="jgit-4.7" sequenceNumber="1558539038">
   <locations>
-    <location includeAllPlatforms="false" includeConfigurePhase="true" includeMode="slicer" includeSource="true" type="InstallableUnit">
+    <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
       <unit id="org.eclipse.jetty.client" version="9.4.14.v20181114"/>
       <unit id="org.eclipse.jetty.client.source" version="9.4.14.v20181114"/>
       <unit id="org.eclipse.jetty.continuation" version="9.4.14.v20181114"/>
@@ -19,17 +22,17 @@
       <unit id="org.eclipse.jetty.util.source" version="9.4.14.v20181114"/>
       <repository id="jetty-9.4.14" location="http://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.14.v20181114"/>
     </location>
-    <location includeAllPlatforms="false" includeConfigurePhase="true" includeMode="slicer" includeSource="true" type="InstallableUnit">
-      <unit id="org.apache.ant" version="1.10.5.v20180808-0324"/>
-      <unit id="org.apache.ant.source" version="1.10.5.v20180808-0324"/>
+    <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
+      <unit id="org.apache.ant" version="1.10.6.v20190516-0412"/>
+      <unit id="org.apache.ant.source" version="1.10.6.v20190516-0412"/>
       <unit id="org.apache.commons.codec" version="1.10.0.v20180409-1845"/>
       <unit id="org.apache.commons.codec.source" version="1.10.0.v20180409-1845"/>
       <unit id="org.apache.commons.compress" version="1.18.0.v20181121-2221"/>
       <unit id="org.apache.commons.compress.source" version="1.18.0.v20181121-2221"/>
       <unit id="org.apache.commons.logging" version="1.2.0.v20180409-1502"/>
       <unit id="org.apache.commons.logging.source" version="1.2.0.v20180409-1502"/>
-      <unit id="org.apache.httpcomponents.httpclient" version="4.5.6.v20190213-1430"/>
-      <unit id="org.apache.httpcomponents.httpclient.source" version="4.5.6.v20190213-1430"/>
+      <unit id="org.apache.httpcomponents.httpclient" version="4.5.6.v20190503-0009"/>
+      <unit id="org.apache.httpcomponents.httpclient.source" version="4.5.6.v20190503-0009"/>
       <unit id="org.apache.httpcomponents.httpcore" version="4.4.10.v20190123-2214"/>
       <unit id="org.apache.httpcomponents.httpcore.source" version="4.4.10.v20190123-2214"/>
       <unit id="org.apache.log4j" version="1.2.15.v201012070815"/>
@@ -79,11 +82,11 @@
       <unit id="org.apache.sshd.osgi.source" version="2.2.0.v20190425-2127"/>
       <unit id="org.apache.sshd.sftp" version="2.2.0.v20190425-2127"/>
       <unit id="org.apache.sshd.sftp.source" version="2.2.0.v20190425-2127"/>
-      <repository location="http://download.eclipse.org/tools/orbit/downloads/drops/S20190501151401/repository"/>
+      <repository location="http://download.eclipse.org/tools/orbit/downloads/drops/S20190521195709/repository"/>
     </location>
-    <location includeAllPlatforms="false" includeConfigurePhase="true" includeMode="slicer" includeSource="true" type="InstallableUnit">
+    <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
       <unit id="org.eclipse.osgi" version="0.0.0"/>
       <repository location="http://download.eclipse.org/releases/oxygen/"/>
     </location>
   </locations>
-</target>
\ No newline at end of file
+</target>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.7.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.7.tpd
index d87e20b..430506a 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.7.tpd
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.7.tpd
@@ -1,7 +1,7 @@
 target "jgit-4.7" with source configurePhase
 
 include "projects/jetty-9.4.14.tpd"
-include "orbit/S20190501151401.tpd"
+include "orbit/S20190521195709.tpd"
 
 location "http://download.eclipse.org/releases/oxygen/" {
 	org.eclipse.osgi lazy
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.8.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.8.target
index 4caf1d9..9764a61 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.8.target
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.8.target
@@ -1,6 +1,9 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?><?pde?><!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --><target name="jgit-4.8" sequenceNumber="1557148692">
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<?pde?>
+<!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl -->
+<target name="jgit-4.8" sequenceNumber="1558539037">
   <locations>
-    <location includeAllPlatforms="false" includeConfigurePhase="true" includeMode="slicer" includeSource="true" type="InstallableUnit">
+    <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
       <unit id="org.eclipse.jetty.client" version="9.4.14.v20181114"/>
       <unit id="org.eclipse.jetty.client.source" version="9.4.14.v20181114"/>
       <unit id="org.eclipse.jetty.continuation" version="9.4.14.v20181114"/>
@@ -19,17 +22,17 @@
       <unit id="org.eclipse.jetty.util.source" version="9.4.14.v20181114"/>
       <repository id="jetty-9.4.14" location="http://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.14.v20181114"/>
     </location>
-    <location includeAllPlatforms="false" includeConfigurePhase="true" includeMode="slicer" includeSource="true" type="InstallableUnit">
-      <unit id="org.apache.ant" version="1.10.5.v20180808-0324"/>
-      <unit id="org.apache.ant.source" version="1.10.5.v20180808-0324"/>
+    <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
+      <unit id="org.apache.ant" version="1.10.6.v20190516-0412"/>
+      <unit id="org.apache.ant.source" version="1.10.6.v20190516-0412"/>
       <unit id="org.apache.commons.codec" version="1.10.0.v20180409-1845"/>
       <unit id="org.apache.commons.codec.source" version="1.10.0.v20180409-1845"/>
       <unit id="org.apache.commons.compress" version="1.18.0.v20181121-2221"/>
       <unit id="org.apache.commons.compress.source" version="1.18.0.v20181121-2221"/>
       <unit id="org.apache.commons.logging" version="1.2.0.v20180409-1502"/>
       <unit id="org.apache.commons.logging.source" version="1.2.0.v20180409-1502"/>
-      <unit id="org.apache.httpcomponents.httpclient" version="4.5.6.v20190213-1430"/>
-      <unit id="org.apache.httpcomponents.httpclient.source" version="4.5.6.v20190213-1430"/>
+      <unit id="org.apache.httpcomponents.httpclient" version="4.5.6.v20190503-0009"/>
+      <unit id="org.apache.httpcomponents.httpclient.source" version="4.5.6.v20190503-0009"/>
       <unit id="org.apache.httpcomponents.httpcore" version="4.4.10.v20190123-2214"/>
       <unit id="org.apache.httpcomponents.httpcore.source" version="4.4.10.v20190123-2214"/>
       <unit id="org.apache.log4j" version="1.2.15.v201012070815"/>
@@ -79,11 +82,11 @@
       <unit id="org.apache.sshd.osgi.source" version="2.2.0.v20190425-2127"/>
       <unit id="org.apache.sshd.sftp" version="2.2.0.v20190425-2127"/>
       <unit id="org.apache.sshd.sftp.source" version="2.2.0.v20190425-2127"/>
-      <repository location="http://download.eclipse.org/tools/orbit/downloads/drops/S20190501151401/repository"/>
+      <repository location="http://download.eclipse.org/tools/orbit/downloads/drops/S20190521195709/repository"/>
     </location>
-    <location includeAllPlatforms="false" includeConfigurePhase="true" includeMode="slicer" includeSource="true" type="InstallableUnit">
+    <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
       <unit id="org.eclipse.osgi" version="0.0.0"/>
       <repository location="http://download.eclipse.org/releases/photon/"/>
     </location>
   </locations>
-</target>
\ No newline at end of file
+</target>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.8.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.8.tpd
index e29d7cb..e18fc72 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.8.tpd
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.8.tpd
@@ -1,7 +1,7 @@
 target "jgit-4.8" with source configurePhase
 
 include "projects/jetty-9.4.14.tpd"
-include "orbit/S20190501151401.tpd"
+include "orbit/S20190521195709.tpd"
 
 location "http://download.eclipse.org/releases/photon/" {
 	org.eclipse.osgi lazy
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.9.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.9.target
index 8f3d593..331d141 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.9.target
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.9.target
@@ -1,6 +1,9 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?><?pde?><!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --><target name="jgit-4.9" sequenceNumber="1557148695">
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<?pde?>
+<!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl -->
+<target name="jgit-4.9" sequenceNumber="1558539042">
   <locations>
-    <location includeAllPlatforms="false" includeConfigurePhase="true" includeMode="slicer" includeSource="true" type="InstallableUnit">
+    <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
       <unit id="org.eclipse.jetty.client" version="9.4.14.v20181114"/>
       <unit id="org.eclipse.jetty.client.source" version="9.4.14.v20181114"/>
       <unit id="org.eclipse.jetty.continuation" version="9.4.14.v20181114"/>
@@ -19,17 +22,17 @@
       <unit id="org.eclipse.jetty.util.source" version="9.4.14.v20181114"/>
       <repository id="jetty-9.4.14" location="http://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.14.v20181114"/>
     </location>
-    <location includeAllPlatforms="false" includeConfigurePhase="true" includeMode="slicer" includeSource="true" type="InstallableUnit">
-      <unit id="org.apache.ant" version="1.10.5.v20180808-0324"/>
-      <unit id="org.apache.ant.source" version="1.10.5.v20180808-0324"/>
+    <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
+      <unit id="org.apache.ant" version="1.10.6.v20190516-0412"/>
+      <unit id="org.apache.ant.source" version="1.10.6.v20190516-0412"/>
       <unit id="org.apache.commons.codec" version="1.10.0.v20180409-1845"/>
       <unit id="org.apache.commons.codec.source" version="1.10.0.v20180409-1845"/>
       <unit id="org.apache.commons.compress" version="1.18.0.v20181121-2221"/>
       <unit id="org.apache.commons.compress.source" version="1.18.0.v20181121-2221"/>
       <unit id="org.apache.commons.logging" version="1.2.0.v20180409-1502"/>
       <unit id="org.apache.commons.logging.source" version="1.2.0.v20180409-1502"/>
-      <unit id="org.apache.httpcomponents.httpclient" version="4.5.6.v20190213-1430"/>
-      <unit id="org.apache.httpcomponents.httpclient.source" version="4.5.6.v20190213-1430"/>
+      <unit id="org.apache.httpcomponents.httpclient" version="4.5.6.v20190503-0009"/>
+      <unit id="org.apache.httpcomponents.httpclient.source" version="4.5.6.v20190503-0009"/>
       <unit id="org.apache.httpcomponents.httpcore" version="4.4.10.v20190123-2214"/>
       <unit id="org.apache.httpcomponents.httpcore.source" version="4.4.10.v20190123-2214"/>
       <unit id="org.apache.log4j" version="1.2.15.v201012070815"/>
@@ -79,11 +82,11 @@
       <unit id="org.apache.sshd.osgi.source" version="2.2.0.v20190425-2127"/>
       <unit id="org.apache.sshd.sftp" version="2.2.0.v20190425-2127"/>
       <unit id="org.apache.sshd.sftp.source" version="2.2.0.v20190425-2127"/>
-      <repository location="http://download.eclipse.org/tools/orbit/downloads/drops/S20190501151401/repository"/>
+      <repository location="http://download.eclipse.org/tools/orbit/downloads/drops/S20190521195709/repository"/>
     </location>
-    <location includeAllPlatforms="false" includeConfigurePhase="true" includeMode="slicer" includeSource="true" type="InstallableUnit">
+    <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
       <unit id="org.eclipse.osgi" version="0.0.0"/>
       <repository location="http://download.eclipse.org/releases/2018-09/"/>
     </location>
   </locations>
-</target>
\ No newline at end of file
+</target>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.9.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.9.tpd
index a36742e..6b71dff 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.9.tpd
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.9.tpd
@@ -1,7 +1,7 @@
 target "jgit-4.9" with source configurePhase
 
 include "projects/jetty-9.4.14.tpd"
-include "orbit/S20190501151401.tpd"
+include "orbit/S20190521195709.tpd"
 
 location "http://download.eclipse.org/releases/2018-09/" {
 	org.eclipse.osgi lazy
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/S20190501151401.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/S20190521195709.tpd
similarity index 90%
rename from org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/S20190501151401.tpd
rename to org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/S20190521195709.tpd
index 6cb4d12..d526ab4 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/S20190501151401.tpd
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/S20190521195709.tpd
@@ -1,17 +1,17 @@
-target "S20190501151401" with source configurePhase
+target "S20190521195709" with source configurePhase
 // see http://download.eclipse.org/tools/orbit/downloads/
 
-location "http://download.eclipse.org/tools/orbit/downloads/drops/S20190501151401/repository" {
-	org.apache.ant [1.10.5.v20180808-0324,1.10.5.v20180808-0324]
-	org.apache.ant.source [1.10.5.v20180808-0324,1.10.5.v20180808-0324]
+location "http://download.eclipse.org/tools/orbit/downloads/drops/S20190521195709/repository" {
+	org.apache.ant [1.10.6.v20190516-0412,1.10.6.v20190516-0412]
+	org.apache.ant.source [1.10.6.v20190516-0412,1.10.6.v20190516-0412]
 	org.apache.commons.codec [1.10.0.v20180409-1845,1.10.0.v20180409-1845]
 	org.apache.commons.codec.source [1.10.0.v20180409-1845,1.10.0.v20180409-1845]
 	org.apache.commons.compress [1.18.0.v20181121-2221,1.18.0.v20181121-2221]
 	org.apache.commons.compress.source [1.18.0.v20181121-2221,1.18.0.v20181121-2221]
 	org.apache.commons.logging [1.2.0.v20180409-1502,1.2.0.v20180409-1502]
 	org.apache.commons.logging.source [1.2.0.v20180409-1502,1.2.0.v20180409-1502]
-	org.apache.httpcomponents.httpclient [4.5.6.v20190213-1430,4.5.6.v20190213-1430]
-	org.apache.httpcomponents.httpclient.source [4.5.6.v20190213-1430,4.5.6.v20190213-1430]
+	org.apache.httpcomponents.httpclient [4.5.6.v20190503-0009,4.5.6.v20190503-0009]
+	org.apache.httpcomponents.httpclient.source [4.5.6.v20190503-0009,4.5.6.v20190503-0009]
 	org.apache.httpcomponents.httpcore [4.4.10.v20190123-2214,4.4.10.v20190123-2214]
 	org.apache.httpcomponents.httpcore.source [4.4.10.v20190123-2214,4.4.10.v20190123-2214]
 	org.apache.log4j [1.2.15.v201012070815,1.2.15.v201012070815]
diff --git a/org.eclipse.jgit.pgm.test/BUILD b/org.eclipse.jgit.pgm.test/BUILD
index 5bedf9a..f32fa12 100644
--- a/org.eclipse.jgit.pgm.test/BUILD
+++ b/org.eclipse.jgit.pgm.test/BUILD
@@ -7,7 +7,7 @@
     name = "pgm",
     srcs = glob(["tst/**/*.java"]),
     jvm_flags = [
-        "-Xmx256m",
+        "-Xmx512m",
         "-Dfile.encoding=UTF-8",
     ],
     tags = ["pgm"],
diff --git a/org.eclipse.jgit.pgm.test/pom.xml b/org.eclipse.jgit.pgm.test/pom.xml
index 326c28e..fcdebdc 100644
--- a/org.eclipse.jgit.pgm.test/pom.xml
+++ b/org.eclipse.jgit.pgm.test/pom.xml
@@ -109,7 +109,7 @@
       <plugin>
         <artifactId>maven-surefire-plugin</artifactId>
         <configuration>
-          <argLine>@{argLine} -Djava.io.tmpdir=${project.build.directory}</argLine>
+          <argLine>@{argLine} -Xmx512m -Djava.io.tmpdir=${project.build.directory}</argLine>
         </configuration>
       </plugin>
     </plugins>
diff --git a/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/ArchiveTest.java b/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/ArchiveTest.java
index 47eb156..e07fdd5 100644
--- a/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/ArchiveTest.java
+++ b/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/ArchiveTest.java
@@ -60,7 +60,6 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
-import java.util.concurrent.Callable;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 import java.util.concurrent.Future;
@@ -703,15 +702,12 @@ private void writeRaw(String filename, byte[] data)
 	private static Future<Object> writeAsync(OutputStream stream, byte[] data) {
 		ExecutorService executor = Executors.newSingleThreadExecutor();
 
-		return executor.submit(new Callable<Object>() {
-			@Override
-			public Object call() throws IOException {
-				try {
-					stream.write(data);
-					return null;
-				} finally {
-					stream.close();
-				}
+		return executor.submit(() -> {
+			try {
+				stream.write(data);
+				return null;
+			} finally {
+				stream.close();
 			}
 		});
 	}
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/CommandCatalog.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/CommandCatalog.java
index b98bf15..dab52f6 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/CommandCatalog.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/CommandCatalog.java
@@ -52,7 +52,6 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
-import java.util.Comparator;
 import java.util.Enumeration;
 import java.util.HashMap;
 import java.util.Map;
@@ -115,12 +114,8 @@ public static CommandRef get(String name) {
 
 	private static CommandRef[] toSortedArray(Collection<CommandRef> c) {
 		final CommandRef[] r = c.toArray(new CommandRef[0]);
-		Arrays.sort(r, new Comparator<CommandRef>() {
-			@Override
-			public int compare(CommandRef o1, CommandRef o2) {
-				return o1.getName().compareTo(o2.getName());
-			}
-		});
+		Arrays.sort(r, (CommandRef o1, CommandRef o2) -> o1.getName()
+				.compareTo(o2.getName()));
 		return r;
 	}
 
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Daemon.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Daemon.java
index 319b5e3..4382663 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Daemon.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Daemon.java
@@ -66,7 +66,6 @@
 import org.eclipse.jgit.transport.ReceivePack;
 import org.eclipse.jgit.transport.resolver.FileResolver;
 import org.eclipse.jgit.transport.resolver.ReceivePackFactory;
-import org.eclipse.jgit.transport.resolver.ServiceNotAuthorizedException;
 import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException;
 import org.eclipse.jgit.util.FS;
 import org.kohsuke.args4j.Argument;
@@ -188,22 +187,17 @@ private void startKetchLeader(org.eclipse.jgit.transport.Daemon daemon) {
 		final ReceivePackFactory<DaemonClient> factory;
 
 		factory = daemon.getReceivePackFactory();
-		daemon.setReceivePackFactory(new ReceivePackFactory<DaemonClient>() {
-			@Override
-			public ReceivePack create(DaemonClient req, Repository repo)
-					throws ServiceNotEnabledException,
-					ServiceNotAuthorizedException {
-				ReceivePack rp = factory.create(req, repo);
-				KetchLeader leader;
-				try {
-					leader = leaders.get(repo);
-				} catch (URISyntaxException err) {
-					throw new ServiceNotEnabledException(
-							KetchText.get().invalidFollowerUri, err);
-				}
-				rp.setPreReceiveHook(new KetchPreReceive(leader));
-				return rp;
+		daemon.setReceivePackFactory((DaemonClient req, Repository repo) -> {
+			ReceivePack rp = factory.create(req, repo);
+			KetchLeader leader;
+			try {
+				leader = leaders.get(repo);
+			} catch (URISyntaxException err) {
+				throw new ServiceNotEnabledException(
+						KetchText.get().invalidFollowerUri, err);
 			}
+			rp.setPreReceiveHook(new KetchPreReceive(leader));
+			return rp;
 		});
 	}
 }
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Glog.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Glog.java
index 2b5af5d..00bbfb7 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Glog.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Glog.java
@@ -47,7 +47,6 @@
 import java.awt.BorderLayout;
 import java.awt.FlowLayout;
 import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
 import java.awt.event.WindowAdapter;
 import java.awt.event.WindowEvent;
 import java.io.File;
@@ -87,11 +86,8 @@ public void windowClosing(WindowEvent e) {
 		final JPanel buttons = new JPanel(new FlowLayout());
 		final JButton repaint = new JButton();
 		repaint.setText(CLIText.get().repaint);
-		repaint.addActionListener(new ActionListener() {
-			@Override
-			public void actionPerformed(ActionEvent e) {
-				graphPane.repaint();
-			}
+		repaint.addActionListener((ActionEvent e) -> {
+			graphPane.repaint();
 		});
 		buttons.add(repaint);
 
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/LsRemote.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/LsRemote.java
index 1c2564d..708fcde 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/LsRemote.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/LsRemote.java
@@ -46,7 +46,6 @@
 package org.eclipse.jgit.pgm;
 
 import java.io.IOException;
-import java.util.Comparator;
 import java.util.TreeSet;
 
 import org.eclipse.jgit.api.Git;
@@ -76,13 +75,8 @@ class LsRemote extends TextBuiltin {
 	protected void run() {
 		LsRemoteCommand command = Git.lsRemoteRepository().setRemote(remote)
 				.setTimeout(timeout).setHeads(heads).setTags(tags);
-		TreeSet<Ref> refs = new TreeSet<>(new Comparator<Ref>() {
-
-			@Override
-			public int compare(Ref r1, Ref r2) {
-				return r1.getName().compareTo(r2.getName());
-			}
-		});
+		TreeSet<Ref> refs = new TreeSet<>(
+				(Ref r1, Ref r2) -> r1.getName().compareTo(r2.getName()));
 		try {
 			refs.addAll(command.call());
 			for (Ref r : refs) {
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/DiffAlgorithms.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/DiffAlgorithms.java
index 6165c0a..85a7444 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/DiffAlgorithms.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/DiffAlgorithms.java
@@ -52,7 +52,6 @@
 import java.lang.reflect.Field;
 import java.util.ArrayList;
 import java.util.Collections;
-import java.util.Comparator;
 import java.util.List;
 
 import org.eclipse.jgit.diff.DiffAlgorithm;
@@ -235,15 +234,12 @@ private void run(Repository repo) throws Exception {
 			}
 		}
 
-		Collections.sort(all, new Comparator<Test>() {
-			@Override
-			public int compare(Test a, Test b) {
-				int result = Long.signum(a.runningTimeNanos - b.runningTimeNanos);
-				if (result == 0) {
-					result = a.algorithm.name.compareTo(b.algorithm.name);
-				}
-				return result;
+		Collections.sort(all, (Test a, Test b) -> {
+			int result = Long.signum(a.runningTimeNanos - b.runningTimeNanos);
+			if (result == 0) {
+				result = a.algorithm.name.compareTo(b.algorithm.name);
 			}
+			return result;
 		});
 
 		File directory = repo.getDirectory();
diff --git a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/auth/BasicAuthentication.java b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/auth/BasicAuthentication.java
index a257a5e..6fa528d 100644
--- a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/auth/BasicAuthentication.java
+++ b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/auth/BasicAuthentication.java
@@ -145,18 +145,13 @@ public void process() throws Exception {
 	 */
 	protected void askCredentials() {
 		clearPassword();
-		PasswordAuthentication auth = AccessController
-				.doPrivileged(new PrivilegedAction<PasswordAuthentication>() {
-
-					@Override
-					public PasswordAuthentication run() {
-						return Authenticator.requestPasswordAuthentication(
-								proxy.getHostString(), proxy.getAddress(),
-								proxy.getPort(), SshConstants.SSH_SCHEME,
+		PasswordAuthentication auth = AccessController.doPrivileged(
+				(PrivilegedAction<PasswordAuthentication>) () -> Authenticator
+						.requestPasswordAuthentication(proxy.getHostString(),
+								proxy.getAddress(), proxy.getPort(),
+								SshConstants.SSH_SCHEME,
 								SshdText.get().proxyPasswordPrompt, "Basic", //$NON-NLS-1$
-								null, RequestorType.PROXY);
-					}
-				});
+								null, RequestorType.PROXY));
 		if (auth == null) {
 			user = ""; //$NON-NLS-1$
 			throw new CancellationException(
diff --git a/org.eclipse.jgit.test/BUILD b/org.eclipse.jgit.test/BUILD
index b9fb89c..be4fdbd 100644
--- a/org.eclipse.jgit.test/BUILD
+++ b/org.eclipse.jgit.test/BUILD
@@ -19,6 +19,7 @@
     "nls/MissingPropertyBundle.java",
     "nls/NoPropertiesBundle.java",
     "nls/NonTranslatedBundle.java",
+    "revwalk/ReachabilityCheckerTestCase.java",
     "revwalk/RevQueueTestCase.java",
     "revwalk/RevWalkTestCase.java",
     "transport/ObjectIdMatcher.java",
diff --git a/org.eclipse.jgit.test/pom.xml b/org.eclipse.jgit.test/pom.xml
index c0b8513..6248756 100644
--- a/org.eclipse.jgit.test/pom.xml
+++ b/org.eclipse.jgit.test/pom.xml
@@ -190,7 +190,7 @@
       <plugin>
         <artifactId>maven-surefire-plugin</artifactId>
         <configuration>
-          <argLine>@{argLine} -Xmx1024m -Dfile.encoding=UTF-8 -Djava.io.tmpdir=${project.build.directory}</argLine>
+          <argLine>@{argLine} -Xmx768m -Dfile.encoding=UTF-8 -Djava.io.tmpdir=${project.build.directory}</argLine>
           <includes>
             <include>**/*Test.java</include>
             <include>**/*Tests.java</include>
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/PullCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/PullCommandTest.java
index 9461c42..2fd3788 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/PullCommandTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/PullCommandTest.java
@@ -346,14 +346,11 @@ private enum TestPullMode {
 	@Test
 	/** global rebase config should be respected */
 	public void testPullWithRebasePreserve1Config() throws Exception {
-		Callable<PullResult> setup = new Callable<PullResult>() {
-			@Override
-			public PullResult call() throws Exception {
-				StoredConfig config = dbTarget.getConfig();
-				config.setString("pull", null, "rebase", "preserve");
-				config.save();
-				return target.pull().call();
-			}
+		Callable<PullResult> setup = () -> {
+			StoredConfig config = dbTarget.getConfig();
+			config.setString("pull", null, "rebase", "preserve");
+			config.save();
+			return target.pull().call();
 		};
 		doTestPullWithRebase(setup, TestPullMode.REBASE_PREASERVE);
 	}
@@ -361,15 +358,12 @@ public PullResult call() throws Exception {
 	@Test
 	/** the branch-local config should win over the global config */
 	public void testPullWithRebasePreserveConfig2() throws Exception {
-		Callable<PullResult> setup = new Callable<PullResult>() {
-			@Override
-			public PullResult call() throws Exception {
-				StoredConfig config = dbTarget.getConfig();
-				config.setString("pull", null, "rebase", "false");
-				config.setString("branch", "master", "rebase", "preserve");
-				config.save();
-				return target.pull().call();
-			}
+		Callable<PullResult> setup = () -> {
+			StoredConfig config = dbTarget.getConfig();
+			config.setString("pull", null, "rebase", "false");
+			config.setString("branch", "master", "rebase", "preserve");
+			config.save();
+			return target.pull().call();
 		};
 		doTestPullWithRebase(setup, TestPullMode.REBASE_PREASERVE);
 	}
@@ -377,14 +371,11 @@ public PullResult call() throws Exception {
 	@Test
 	/** the branch-local config should be respected */
 	public void testPullWithRebasePreserveConfig3() throws Exception {
-		Callable<PullResult> setup = new Callable<PullResult>() {
-			@Override
-			public PullResult call() throws Exception {
-				StoredConfig config = dbTarget.getConfig();
-				config.setString("branch", "master", "rebase", "preserve");
-				config.save();
-				return target.pull().call();
-			}
+		Callable<PullResult> setup = () -> {
+			StoredConfig config = dbTarget.getConfig();
+			config.setString("branch", "master", "rebase", "preserve");
+			config.save();
+			return target.pull().call();
 		};
 		doTestPullWithRebase(setup, TestPullMode.REBASE_PREASERVE);
 	}
@@ -392,14 +383,11 @@ public PullResult call() throws Exception {
 	@Test
 	/** global rebase config should be respected */
 	public void testPullWithRebaseConfig1() throws Exception {
-		Callable<PullResult> setup = new Callable<PullResult>() {
-			@Override
-			public PullResult call() throws Exception {
-				StoredConfig config = dbTarget.getConfig();
-				config.setString("pull", null, "rebase", "true");
-				config.save();
-				return target.pull().call();
-			}
+		Callable<PullResult> setup = () -> {
+			StoredConfig config = dbTarget.getConfig();
+			config.setString("pull", null, "rebase", "true");
+			config.save();
+			return target.pull().call();
 		};
 		doTestPullWithRebase(setup, TestPullMode.REBASE);
 	}
@@ -407,15 +395,12 @@ public PullResult call() throws Exception {
 	@Test
 	/** the branch-local config should win over the global config */
 	public void testPullWithRebaseConfig2() throws Exception {
-		Callable<PullResult> setup = new Callable<PullResult>() {
-			@Override
-			public PullResult call() throws Exception {
-				StoredConfig config = dbTarget.getConfig();
-				config.setString("pull", null, "rebase", "preserve");
-				config.setString("branch", "master", "rebase", "true");
-				config.save();
-				return target.pull().call();
-			}
+		Callable<PullResult> setup = () -> {
+			StoredConfig config = dbTarget.getConfig();
+			config.setString("pull", null, "rebase", "preserve");
+			config.setString("branch", "master", "rebase", "true");
+			config.save();
+			return target.pull().call();
 		};
 		doTestPullWithRebase(setup, TestPullMode.REBASE);
 	}
@@ -423,14 +408,11 @@ public PullResult call() throws Exception {
 	@Test
 	/** the branch-local config should be respected */
 	public void testPullWithRebaseConfig3() throws Exception {
-		Callable<PullResult> setup = new Callable<PullResult>() {
-			@Override
-			public PullResult call() throws Exception {
-				StoredConfig config = dbTarget.getConfig();
-				config.setString("branch", "master", "rebase", "true");
-				config.save();
-				return target.pull().call();
-			}
+		Callable<PullResult> setup = () -> {
+			StoredConfig config = dbTarget.getConfig();
+			config.setString("branch", "master", "rebase", "true");
+			config.save();
+			return target.pull().call();
 		};
 		doTestPullWithRebase(setup, TestPullMode.REBASE);
 	}
@@ -438,27 +420,19 @@ public PullResult call() throws Exception {
 	@Test
 	/** without config it should merge */
 	public void testPullWithoutConfig() throws Exception {
-		Callable<PullResult> setup = new Callable<PullResult>() {
-			@Override
-			public PullResult call() throws Exception {
-				return target.pull().call();
-			}
-		};
+		Callable<PullResult> setup = target.pull()::call;
 		doTestPullWithRebase(setup, TestPullMode.MERGE);
 	}
 
 	@Test
 	/** the branch local config should win over the global config */
 	public void testPullWithMergeConfig() throws Exception {
-		Callable<PullResult> setup = new Callable<PullResult>() {
-			@Override
-			public PullResult call() throws Exception {
-				StoredConfig config = dbTarget.getConfig();
-				config.setString("pull", null, "rebase", "true");
-				config.setString("branch", "master", "rebase", "false");
-				config.save();
-				return target.pull().call();
-			}
+		Callable<PullResult> setup = () -> {
+			StoredConfig config = dbTarget.getConfig();
+			config.setString("pull", null, "rebase", "true");
+			config.setString("branch", "master", "rebase", "false");
+			config.save();
+			return target.pull().call();
 		};
 		doTestPullWithRebase(setup, TestPullMode.MERGE);
 	}
@@ -466,14 +440,11 @@ public PullResult call() throws Exception {
 	@Test
 	/** the branch local config should win over the global config */
 	public void testPullWithMergeConfig2() throws Exception {
-		Callable<PullResult> setup = new Callable<PullResult>() {
-			@Override
-			public PullResult call() throws Exception {
-				StoredConfig config = dbTarget.getConfig();
-				config.setString("pull", null, "rebase", "false");
-				config.save();
-				return target.pull().call();
-			}
+		Callable<PullResult> setup = () -> {
+			StoredConfig config = dbTarget.getConfig();
+			config.setString("pull", null, "rebase", "false");
+			config.save();
+			return target.pull().call();
 		};
 		doTestPullWithRebase(setup, TestPullMode.MERGE);
 	}
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheBuilderTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheBuilderTest.java
index b284771..0c1131b 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheBuilderTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheBuilderTest.java
@@ -210,12 +210,8 @@ final class ReceivedEventMarkerException extends RuntimeException {
 		boolean receivedEvent = false;
 
 		DirCache dc = db.lockDirCache();
-		IndexChangedListener listener = new IndexChangedListener() {
-
-			@Override
-			public void onIndexChanged(IndexChangedEvent event) {
-				throw new ReceivedEventMarkerException();
-			}
+		IndexChangedListener listener = (IndexChangedEvent event) -> {
+			throw new ReceivedEventMarkerException();
 		};
 
 		ListenerList l = db.getListenerList();
@@ -238,12 +234,8 @@ public void onIndexChanged(IndexChangedEvent event) {
 		// do the same again, as this doesn't change index compared to first
 		// round we should get no event this time
 		dc = db.lockDirCache();
-		listener = new IndexChangedListener() {
-
-			@Override
-			public void onIndexChanged(IndexChangedEvent event) {
-				throw new ReceivedEventMarkerException();
-			}
+		listener = (IndexChangedEvent event) -> {
+			throw new ReceivedEventMarkerException();
 		};
 
 		l = db.getListenerList();
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/events/ConfigChangeEventTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/events/ConfigChangeEventTest.java
index 3624100..b6f312d 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/events/ConfigChangeEventTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/events/ConfigChangeEventTest.java
@@ -54,12 +54,9 @@ public class ConfigChangeEventTest extends RepositoryTestCase {
 	@Test
 	public void testFileRepository_ChangeEventsOnlyOnSave() throws Exception {
 		final ConfigChangedEvent[] events = new ConfigChangedEvent[1];
-		db.getListenerList().addConfigChangedListener(
-				new ConfigChangedListener() {
-					@Override
-					public void onConfigChanged(ConfigChangedEvent event) {
-						events[0] = event;
-					}
+		db.getListenerList()
+				.addConfigChangedListener((ConfigChangedEvent event) -> {
+					events[0] = event;
 				});
 		FileBasedConfig config = db.getConfig();
 		assertNull(events[0]);
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/GcConcurrentTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/GcConcurrentTest.java
index 05f7c65..9e7d41a 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/GcConcurrentTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/GcConcurrentTest.java
@@ -239,20 +239,15 @@ public void testInterruptGc() throws Exception {
 		SampleDataRepositoryTestCase.copyCGitTestPacks(repo);
 		ExecutorService executor = Executors.newSingleThreadExecutor();
 		final CountDownLatch latch = new CountDownLatch(1);
-		Future<Collection<PackFile>> result = executor
-				.submit(new Callable<Collection<PackFile>>() {
-
-					@Override
-					public Collection<PackFile> call() throws Exception {
-						long start = System.currentTimeMillis();
-						System.out.println("starting gc");
-						latch.countDown();
-						Collection<PackFile> r = gc.gc();
-						System.out.println("gc took "
-								+ (System.currentTimeMillis() - start) + " ms");
-						return r;
-					}
-				});
+		Future<Collection<PackFile>> result = executor.submit(() -> {
+			long start = System.currentTimeMillis();
+			System.out.println("starting gc");
+			latch.countDown();
+			Collection<PackFile> r = gc.gc();
+			System.out.println(
+					"gc took " + (System.currentTimeMillis() - start) + " ms");
+			return r;
+		});
 		try {
 			latch.await();
 			Thread.sleep(5);
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/GcPackRefsTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/GcPackRefsTest.java
index 9289e5a..1fa5aa0 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/GcPackRefsTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/GcPackRefsTest.java
@@ -155,38 +155,32 @@ public void whileRefUpdatedRefUpdateSucceeds()
 		final CyclicBarrier packRefsDone = new CyclicBarrier(2);
 		ExecutorService pool = Executors.newFixedThreadPool(2);
 		try {
-			Future<Result> result = pool.submit(new Callable<Result>() {
-
-				@Override
-				public Result call() throws Exception {
-					RefUpdate update = new RefDirectoryUpdate(
-							(RefDirectory) repo.getRefDatabase(),
-							repo.exactRef("refs/tags/t")) {
-						@Override
-						public boolean isForceUpdate() {
-							try {
-								refUpdateLockedRef.await();
-								packRefsDone.await();
-							} catch (InterruptedException | BrokenBarrierException e) {
-								Thread.currentThread().interrupt();
-							}
-							return super.isForceUpdate();
+			Future<Result> result = pool.submit(() -> {
+				RefUpdate update = new RefDirectoryUpdate(
+						(RefDirectory) repo.getRefDatabase(),
+						repo.exactRef("refs/tags/t")) {
+					@Override
+					public boolean isForceUpdate() {
+						try {
+							refUpdateLockedRef.await();
+							packRefsDone.await();
+						} catch (InterruptedException
+								| BrokenBarrierException e) {
+							Thread.currentThread().interrupt();
 						}
-					};
-					update.setForceUpdate(true);
-					update.setNewObjectId(b);
-					return update.update();
-				}
+						return super.isForceUpdate();
+					}
+				};
+				update.setForceUpdate(true);
+				update.setNewObjectId(b);
+				return update.update();
 			});
 
-			pool.submit(new Callable<Void>() {
-				@Override
-				public Void call() throws Exception {
-					refUpdateLockedRef.await();
-					gc.packRefs();
-					packRefsDone.await();
-					return null;
-				}
+			pool.submit(() -> {
+				refUpdateLockedRef.await();
+				gc.packRefs();
+				packRefsDone.await();
+				return null;
 			});
 
 			assertSame(result.get(), Result.FORCED);
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/ObjectDirectoryTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/ObjectDirectoryTest.java
index a3a302d..a9d0dc2 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/ObjectDirectoryTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/ObjectDirectoryTest.java
@@ -47,7 +47,6 @@
 import static org.junit.Assert.assertTrue;
 
 import java.io.File;
-import java.io.FilenameFilter;
 import java.io.IOException;
 import java.io.PrintWriter;
 import java.text.MessageFormat;
@@ -167,12 +166,8 @@ public void testScanningForPackfiles() throws Exception {
 			// Bug. To show the bug we sleep for more than 2500ms
 			Thread.sleep(2600);
 
-			File[] ret = packsFolder.listFiles(new FilenameFilter() {
-				@Override
-				public boolean accept(File dir, String name) {
-					return name.endsWith(".pack");
-				}
-			});
+			File[] ret = packsFolder.listFiles(
+					(File dir, String name) -> name.endsWith(".pack"));
 			assertTrue(ret != null && ret.length == 1);
 			Assume.assumeTrue(tmpFile.lastModified() == ret[0].lastModified());
 
@@ -220,12 +215,8 @@ public void testShallowFileCorrupt()
 
 	private Collection<Callable<ObjectId>> blobInsertersForTheSameFanOutDir(
 			final ObjectDirectory dir) {
-		Callable<ObjectId> callable = new Callable<ObjectId>() {
-			@Override
-			public ObjectId call() throws Exception {
-				return dir.newInserter().insert(Constants.OBJ_BLOB, new byte[0]);
-			}
-		};
+		Callable<ObjectId> callable = () -> dir.newInserter()
+				.insert(Constants.OBJ_BLOB, new byte[0]);
 		return Collections.nCopies(4, callable);
 	}
 
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackWriterTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackWriterTest.java
index ca44862..5d0a7e2 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackWriterTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackWriterTest.java
@@ -60,7 +60,6 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
-import java.util.Comparator;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
@@ -881,12 +880,8 @@ private void verifyObjectsOrder(ObjectId objectsOrder[]) {
 		for (MutableEntry me : pack) {
 			entries.add(me.cloneEntry());
 		}
-		Collections.sort(entries, new Comparator<PackIndex.MutableEntry>() {
-			@Override
-			public int compare(MutableEntry o1, MutableEntry o2) {
-				return Long.signum(o1.getOffset() - o2.getOffset());
-			}
-		});
+		Collections.sort(entries, (MutableEntry o1, MutableEntry o2) -> Long
+				.signum(o1.getOffset() - o2.getOffset()));
 
 		int i = 0;
 		for (MutableEntry me : entries) {
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/RefDirectoryTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/RefDirectoryTest.java
index 7b3684c..bd9572b 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/RefDirectoryTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/RefDirectoryTest.java
@@ -70,7 +70,6 @@
 import org.eclipse.jgit.errors.LockFailedException;
 import org.eclipse.jgit.events.ListenerHandle;
 import org.eclipse.jgit.events.RefsChangedEvent;
-import org.eclipse.jgit.events.RefsChangedListener;
 import org.eclipse.jgit.junit.LocalDiskRepositoryTestCase;
 import org.eclipse.jgit.junit.TestRepository;
 import org.eclipse.jgit.lib.AnyObjectId;
@@ -570,12 +569,8 @@ public void testGetRefs_LooseSorting_Bug_348834() throws IOException {
 		final int[] count = new int[1];
 
 		ListenerHandle listener = Repository.getGlobalListenerList()
-				.addRefsChangedListener(new RefsChangedListener() {
-
-					@Override
-					public void onRefsChanged(RefsChangedEvent event) {
-						count[0]++;
-					}
+				.addRefsChangedListener((RefsChangedEvent event) -> {
+					count[0]++;
 				});
 
 		refs = refdir.getRefs(RefDatabase.ALL);
@@ -1316,19 +1311,15 @@ public void testRefsChangedStackOverflow() throws Exception {
 		final AtomicReference<StackOverflowError> error = new AtomicReference<>();
 		final AtomicReference<IOException> exception = new AtomicReference<>();
 		final AtomicInteger changeCount = new AtomicInteger();
-		newRepo.getListenerList().addRefsChangedListener(
-				new RefsChangedListener() {
-
-					@Override
-					public void onRefsChanged(RefsChangedEvent event) {
-						try {
-							refDb.getRefsByPrefix("ref");
-							changeCount.incrementAndGet();
-						} catch (StackOverflowError soe) {
-							error.set(soe);
-						} catch (IOException ioe) {
-							exception.set(ioe);
-						}
+		newRepo.getListenerList()
+				.addRefsChangedListener((RefsChangedEvent event) -> {
+					try {
+						refDb.getRefsByPrefix("ref");
+						changeCount.incrementAndGet();
+					} catch (StackOverflowError soe) {
+						error.set(soe);
+					} catch (IOException ioe) {
+						exception.set(ioe);
 					}
 				});
 		refDb.getRefsByPrefix("ref");
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/reftree/RefTreeDatabaseTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/reftree/RefTreeDatabaseTest.java
index 8ef21e6..c3f5baa 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/reftree/RefTreeDatabaseTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/reftree/RefTreeDatabaseTest.java
@@ -633,35 +633,23 @@ private static ReceiveCommand command(AnyObjectId a, AnyObjectId b,
 
 	private void symref(String name, String dst)
 			throws IOException {
-		commit(new Function() {
-			@Override
-			public boolean apply(ObjectReader reader, RefTree tree)
-					throws IOException {
-				Ref old = tree.exactRef(reader, name);
-				Command n = new Command(
-					old,
-					new SymbolicRef(
-						name,
-						new ObjectIdRef.Unpeeled(Ref.Storage.NEW, dst, null)));
-				return tree.apply(Collections.singleton(n));
-			}
+		commit((ObjectReader reader, RefTree tree) -> {
+			Ref old = tree.exactRef(reader, name);
+			Command n = new Command(old, new SymbolicRef(name,
+					new ObjectIdRef.Unpeeled(Ref.Storage.NEW, dst, null)));
+			return tree.apply(Collections.singleton(n));
 		});
 	}
 
 	private void update(String name, ObjectId id)
 			throws IOException {
-		commit(new Function() {
-			@Override
-			public boolean apply(ObjectReader reader, RefTree tree)
-					throws IOException {
-				Ref old = tree.exactRef(reader, name);
-				Command n;
-				try (RevWalk rw = new RevWalk(repo)) {
-					n = new Command(old,
-							Command.toRef(rw, id, null, name, true));
-				}
-				return tree.apply(Collections.singleton(n));
+		commit((ObjectReader reader, RefTree tree) -> {
+			Ref old = tree.exactRef(reader, name);
+			Command n;
+			try (RevWalk rw = new RevWalk(repo)) {
+				n = new Command(old, Command.toRef(rw, id, null, name, true));
 			}
+			return tree.apply(Collections.singleton(n));
 		});
 	}
 
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ObjectCheckerTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ObjectCheckerTest.java
index 16ad70d..e7a5b28 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ObjectCheckerTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ObjectCheckerTest.java
@@ -1775,16 +1775,13 @@ private void assertSkipListRejects(String msg, int type, byte[] data) {
 	}
 
 	private static ObjectIdSet set(ObjectId... ids) {
-		return new ObjectIdSet() {
-			@Override
-			public boolean contains(AnyObjectId objectId) {
-				for (ObjectId id : ids) {
-					if (id.equals(objectId)) {
-						return true;
-					}
+		return (AnyObjectId objectId) -> {
+			for (ObjectId id : ids) {
+				if (id.equals(objectId)) {
+					return true;
 				}
-				return false;
 			}
+			return false;
 		};
 	}
 
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ThreadSafeProgressMonitorTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ThreadSafeProgressMonitorTest.java
index 545a188..6829822 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ThreadSafeProgressMonitorTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ThreadSafeProgressMonitorTest.java
@@ -61,29 +61,26 @@ public void testFailsMethodsOnBackgroundThread()
 		final MockProgressMonitor mock = new MockProgressMonitor();
 		final ThreadSafeProgressMonitor pm = new ThreadSafeProgressMonitor(mock);
 
-		runOnThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					pm.start(1);
-					fail("start did not fail on background thread");
-				} catch (IllegalStateException notMainThread) {
-					// Expected result
-				}
+		runOnThread(() -> {
+			try {
+				pm.start(1);
+				fail("start did not fail on background thread");
+			} catch (IllegalStateException notMainThread) {
+				// Expected result
+			}
 
-				try {
-					pm.beginTask("title", 1);
-					fail("beginTask did not fail on background thread");
-				} catch (IllegalStateException notMainThread) {
-					// Expected result
-				}
+			try {
+				pm.beginTask("title", 1);
+				fail("beginTask did not fail on background thread");
+			} catch (IllegalStateException notMainThread) {
+				// Expected result
+			}
 
-				try {
-					pm.endTask();
-					fail("endTask did not fail on background thread");
-				} catch (IllegalStateException notMainThread) {
-					// Expected result
-				}
+			try {
+				pm.endTask();
+				fail("endTask did not fail on background thread");
+			} catch (IllegalStateException notMainThread) {
+				// Expected result
 			}
 		});
 
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/BitmapCalculatorTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/BitmapCalculatorTest.java
new file mode 100644
index 0000000..3a78e1e
--- /dev/null
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/BitmapCalculatorTest.java
@@ -0,0 +1,139 @@
+package org.eclipse.jgit.revwalk;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import org.eclipse.jgit.internal.storage.file.FileRepository;
+import org.eclipse.jgit.internal.storage.file.GC;
+import org.eclipse.jgit.junit.LocalDiskRepositoryTestCase;
+import org.eclipse.jgit.junit.TestRepository;
+import org.eclipse.jgit.lib.BitmapIndex.BitmapBuilder;
+import org.eclipse.jgit.lib.NullProgressMonitor;
+import org.eclipse.jgit.lib.ProgressMonitor;
+import org.junit.Before;
+import org.junit.Test;
+
+public class BitmapCalculatorTest extends LocalDiskRepositoryTestCase {
+	TestRepository<FileRepository> repo;
+
+	/** {@inheritDoc} */
+	@Override
+	@Before
+	public void setUp() throws Exception {
+		super.setUp();
+		FileRepository db = createWorkRepository();
+		repo = new TestRepository<>(db);
+	}
+
+	@Test
+	public void addOnlyCommits() throws Exception {
+		RevBlob abBlob = repo.blob("a_b_content");
+		RevCommit root = repo.commit().add("a/b", abBlob).create();
+		repo.update("refs/heads/master", root);
+
+		// GC creates bitmap index with ALL objects
+		GC gc = new GC(repo.getRepository());
+		gc.setAuto(false);
+		gc.gc();
+
+		// These objects are not in the bitmap index.
+		RevBlob acBlob = repo.blob("a_c_content");
+		RevCommit head = repo.commit().parent(root).add("a/c", acBlob).create();
+		repo.update("refs/heads/master", head);
+
+		BitmapCalculator bitmapWalker = new BitmapCalculator(repo.getRevWalk());
+		BitmapBuilder bitmap = bitmapWalker
+				.getBitmap(head, NullProgressMonitor.INSTANCE);
+
+		assertTrue(bitmap.contains(root.getId()));
+		assertTrue(bitmap.contains(root.getTree().getId()));
+		assertTrue(bitmap.contains(abBlob.getId()));
+
+		// BitmapCalculator added only the commit, no other objects.
+		assertTrue(bitmap.contains(head.getId()));
+		assertFalse(bitmap.contains(head.getTree().getId()));
+		assertFalse(bitmap.contains(acBlob.getId()));
+	}
+
+	@Test
+	public void walkUntilBitmap() throws Exception {
+		RevCommit root = repo.commit().create();
+		repo.update("refs/heads/master", root);
+
+		// GC creates bitmap index with ALL objects
+		GC gc = new GC(repo.getRepository());
+		gc.setAuto(false);
+		gc.gc();
+
+		// These objects are not in the bitmap index.
+		RevCommit commit1 = repo.commit(root);
+		RevCommit commit2 = repo.commit(commit1);
+		repo.update("refs/heads/master", commit2);
+
+		CounterProgressMonitor monitor = new CounterProgressMonitor();
+		BitmapCalculator bitmapWalker = new BitmapCalculator(repo.getRevWalk());
+		BitmapBuilder bitmap = bitmapWalker.getBitmap(commit2, monitor);
+
+		assertTrue(bitmap.contains(root));
+		assertTrue(bitmap.contains(commit1));
+		assertTrue(bitmap.contains(commit2));
+		assertEquals(2, monitor.getUpdates());
+	}
+
+	@Test
+	public void noNeedToWalk() throws Exception {
+		RevCommit root = repo.commit().create();
+		RevCommit commit1 = repo.commit(root);
+		RevCommit commit2 = repo.commit(commit1);
+		repo.update("refs/heads/master", commit2);
+
+		// GC creates bitmap index with ALL objects
+		GC gc = new GC(repo.getRepository());
+		gc.setAuto(false);
+		gc.gc();
+
+		CounterProgressMonitor monitor = new CounterProgressMonitor();
+		BitmapCalculator bitmapWalker = new BitmapCalculator(repo.getRevWalk());
+		BitmapBuilder bitmap = bitmapWalker.getBitmap(commit2, monitor);
+
+		assertTrue(bitmap.contains(root));
+		assertTrue(bitmap.contains(commit1));
+		assertTrue(bitmap.contains(commit2));
+		assertEquals(0, monitor.getUpdates());
+	}
+
+	private static class CounterProgressMonitor implements ProgressMonitor {
+
+		private int counter;
+
+		@Override
+		public void start(int totalTasks) {
+			// Nothing to do in tests
+		}
+
+		@Override
+		public void beginTask(String title, int totalWork) {
+			// Nothing to to in tests
+		}
+
+		@Override
+		public void update(int completed) {
+			counter += 1;
+		}
+
+		@Override
+		public void endTask() {
+			// Nothing to do in tests
+		}
+
+		@Override
+		public boolean isCancelled() {
+			return false;
+		}
+
+		int getUpdates() {
+			return counter;
+		}
+	}
+}
\ No newline at end of file
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/BitmappedReachabilityCheckerTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/BitmappedReachabilityCheckerTest.java
new file mode 100644
index 0000000..5d3adf5
--- /dev/null
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/BitmappedReachabilityCheckerTest.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2019, Google LLC
+ * and other copyright owners as documented in the project's IP log.
+ *
+ * This program and the accompanying materials are made available
+ * under the terms of the Eclipse Distribution License v1.0 which
+ * accompanies this distribution, is reproduced below, and is
+ * available at http://www.eclipse.org/org/documents/edl-v10.php
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above
+ *   copyright notice, this list of conditions and the following
+ *   disclaimer in the documentation and/or other materials provided
+ *   with the distribution.
+ *
+ * - Neither the name of the Eclipse Foundation, Inc. nor the
+ *   names of its contributors may be used to endorse or promote
+ *   products derived from this software without specific prior
+ *   written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.eclipse.jgit.revwalk;
+
+import static org.junit.Assert.assertNotNull;
+
+import org.eclipse.jgit.internal.storage.file.FileRepository;
+import org.eclipse.jgit.internal.storage.file.GC;
+import org.eclipse.jgit.junit.TestRepository;
+
+public class BitmappedReachabilityCheckerTest
+		extends ReachabilityCheckerTestCase {
+
+	@Override
+	protected ReachabilityChecker getChecker(
+			TestRepository<FileRepository> repository) throws Exception {
+		// GC generates the bitmaps
+		GC gc = new GC(repo.getRepository());
+		gc.setAuto(false);
+		gc.gc();
+
+		// This is null when the test didn't create any branch
+		assertNotNull("Probably the test didn't define any ref",
+				repo.getRevWalk().getObjectReader().getBitmapIndex());
+
+		return new BitmappedReachabilityChecker(repository.getRevWalk());
+	}
+
+}
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/PedestrianReachabilityCheckerTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/PedestrianReachabilityCheckerTest.java
new file mode 100644
index 0000000..8d3e78c
--- /dev/null
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/PedestrianReachabilityCheckerTest.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2019, Google LLC.
+ * and other copyright owners as documented in the project's IP log.
+ *
+ * This program and the accompanying materials are made available
+ * under the terms of the Eclipse Distribution License v1.0 which
+ * accompanies this distribution, is reproduced below, and is
+ * available at http://www.eclipse.org/org/documents/edl-v10.php
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above
+ *   copyright notice, this list of conditions and the following
+ *   disclaimer in the documentation and/or other materials provided
+ *   with the distribution.
+ *
+ * - Neither the name of the Eclipse Foundation, Inc. nor the
+ *   names of its contributors may be used to endorse or promote
+ *   products derived from this software without specific prior
+ *   written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.eclipse.jgit.revwalk;
+
+import org.eclipse.jgit.internal.storage.file.FileRepository;
+import org.eclipse.jgit.junit.TestRepository;
+
+public class PedestrianReachabilityCheckerTest
+		extends ReachabilityCheckerTestCase {
+
+	@Override
+	protected ReachabilityChecker getChecker(
+			TestRepository<FileRepository> repository) {
+		return new PedestrianReachabilityChecker(true, repository.getRevWalk());
+	}
+
+}
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/ReachabilityCheckerTestCase.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/ReachabilityCheckerTestCase.java
new file mode 100644
index 0000000..dd73e35
--- /dev/null
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/ReachabilityCheckerTestCase.java
@@ -0,0 +1,168 @@
+/*
+ * Copyright (C) 2019, Google LLC.
+ * and other copyright owners as documented in the project's IP log.
+ *
+ * This program and the accompanying materials are made available
+ * under the terms of the Eclipse Distribution License v1.0 which
+ * accompanies this distribution, is reproduced below, and is
+ * available at http://www.eclipse.org/org/documents/edl-v10.php
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above
+ *   copyright notice, this list of conditions and the following
+ *   disclaimer in the documentation and/or other materials provided
+ *   with the distribution.
+ *
+ * - Neither the name of the Eclipse Foundation, Inc. nor the
+ *   names of its contributors may be used to endorse or promote
+ *   products derived from this software without specific prior
+ *   written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.eclipse.jgit.revwalk;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Arrays;
+import java.util.Optional;
+
+import org.eclipse.jgit.internal.storage.file.FileRepository;
+import org.eclipse.jgit.junit.LocalDiskRepositoryTestCase;
+import org.eclipse.jgit.junit.TestRepository;
+import org.junit.Before;
+import org.junit.Test;
+
+public abstract class ReachabilityCheckerTestCase
+		extends LocalDiskRepositoryTestCase {
+
+	protected abstract ReachabilityChecker getChecker(
+			TestRepository<FileRepository> repository) throws Exception;
+
+	TestRepository<FileRepository> repo;
+
+	/** {@inheritDoc} */
+	@Override
+	@Before
+	public void setUp() throws Exception {
+		super.setUp();
+		FileRepository db = createWorkRepository();
+		repo = new TestRepository<>(db);
+	}
+
+	@Test
+	public void reachable() throws Exception {
+		RevCommit a = repo.commit().create();
+		RevCommit b1 = repo.commit(a);
+		RevCommit b2 = repo.commit(b1);
+		RevCommit c1 = repo.commit(a);
+		RevCommit c2 = repo.commit(c1);
+		repo.update("refs/heads/checker", b2);
+
+		ReachabilityChecker checker = getChecker(repo);
+
+		assertReachable("reachable from one tip",
+				checker.areAllReachable(Arrays.asList(a), Arrays.asList(c2)));
+		assertReachable("reachable from another tip",
+				checker.areAllReachable(Arrays.asList(a), Arrays.asList(b2)));
+		assertReachable("reachable from itself",
+				checker.areAllReachable(Arrays.asList(a), Arrays.asList(b2)));
+	}
+
+	@Test
+	public void reachable_merge() throws Exception {
+		RevCommit a = repo.commit().create();
+		RevCommit b1 = repo.commit(a);
+		RevCommit b2 = repo.commit(b1);
+		RevCommit c1 = repo.commit(a);
+		RevCommit c2 = repo.commit(c1);
+		RevCommit merge = repo.commit(c2, b2);
+		repo.update("refs/heads/checker", merge);
+
+		ReachabilityChecker checker = getChecker(repo);
+
+		assertReachable("reachable through one branch",
+				checker.areAllReachable(Arrays.asList(b1),
+						Arrays.asList(merge)));
+		assertReachable("reachable through another branch",
+				checker.areAllReachable(Arrays.asList(c1),
+						Arrays.asList(merge)));
+		assertReachable("reachable, before the branching",
+				checker.areAllReachable(Arrays.asList(a),
+						Arrays.asList(merge)));
+	}
+
+	@Test
+	public void unreachable_isLaterCommit() throws Exception {
+		RevCommit a = repo.commit().create();
+		RevCommit b1 = repo.commit(a);
+		RevCommit b2 = repo.commit(b1);
+		repo.update("refs/heads/checker", b2);
+
+		ReachabilityChecker checker = getChecker(repo);
+
+		assertUnreachable("unreachable from the future",
+				checker.areAllReachable(Arrays.asList(b2), Arrays.asList(b1)));
+	}
+
+	@Test
+	public void unreachable_differentBranch() throws Exception {
+		RevCommit a = repo.commit().create();
+		RevCommit b1 = repo.commit(a);
+		RevCommit b2 = repo.commit(b1);
+		RevCommit c1 = repo.commit(a);
+		repo.update("refs/heads/checker", b2);
+
+		ReachabilityChecker checker = getChecker(repo);
+
+		assertUnreachable("unreachable from different branch",
+				checker.areAllReachable(Arrays.asList(c1), Arrays.asList(b2)));
+	}
+
+	@Test
+	public void reachable_longChain() throws Exception {
+		RevCommit root = repo.commit().create();
+		RevCommit head = root;
+		for (int i = 0; i < 10000; i++) {
+			head = repo.commit(head);
+		}
+		repo.update("refs/heads/master", head);
+
+		ReachabilityChecker checker = getChecker(repo);
+
+		assertReachable("reachable with long chain in the middle", checker
+				.areAllReachable(Arrays.asList(root), Arrays.asList(head)));
+	}
+
+	private static void assertReachable(String msg,
+			Optional<RevCommit> result) {
+		assertFalse(msg, result.isPresent());
+	}
+
+	private static void assertUnreachable(String msg,
+			Optional<RevCommit> result) {
+		assertTrue(msg, result.isPresent());
+	}
+
+}
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/PushConnectionTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/PushConnectionTest.java
index cea432e..89d02d7 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/PushConnectionTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/PushConnectionTest.java
@@ -67,9 +67,6 @@
 import org.eclipse.jgit.lib.ObjectInserter;
 import org.eclipse.jgit.lib.RefUpdate;
 import org.eclipse.jgit.lib.Repository;
-import org.eclipse.jgit.transport.resolver.ReceivePackFactory;
-import org.eclipse.jgit.transport.resolver.ServiceNotAuthorizedException;
-import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
@@ -91,27 +88,16 @@ public void setUp() throws Exception {
 		server = newRepo("server");
 		client = newRepo("client");
 		processedRefs = new ArrayList<>();
-		testProtocol = new TestProtocol<>(
-				null,
-				new ReceivePackFactory<Object>() {
-					@Override
-					public ReceivePack create(Object req, Repository db)
-							throws ServiceNotEnabledException,
-							ServiceNotAuthorizedException {
-						ReceivePack rp = new ReceivePack(db);
-						rp.setPreReceiveHook(
-								new PreReceiveHook() {
-									@Override
-									public void onPreReceive(ReceivePack receivePack,
-											Collection<ReceiveCommand> cmds) {
-										for (ReceiveCommand cmd : cmds) {
-											processedRefs.add(cmd.getRefName());
-										}
-									}
-								});
-						return rp;
-					}
-				});
+		testProtocol = new TestProtocol<>(null, (Object req, Repository db) -> {
+			ReceivePack rp = new ReceivePack(db);
+			rp.setPreReceiveHook((ReceivePack receivePack,
+					Collection<ReceiveCommand> cmds) -> {
+				for (ReceiveCommand cmd : cmds) {
+					processedRefs.add(cmd.getRefName());
+				}
+			});
+			return rp;
+		});
 		uri = testProtocol.register(ctx, server);
 
 		try (ObjectInserter ins = server.newObjectInserter()) {
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/PushOptionsTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/PushOptionsTest.java
index f26201d..fd1c3bf 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/PushOptionsTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/PushOptionsTest.java
@@ -69,9 +69,6 @@
 import org.eclipse.jgit.lib.Repository;
 import org.eclipse.jgit.lib.StoredConfig;
 import org.eclipse.jgit.revwalk.RevCommit;
-import org.eclipse.jgit.transport.resolver.ReceivePackFactory;
-import org.eclipse.jgit.transport.resolver.ServiceNotAuthorizedException;
-import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
@@ -95,16 +92,11 @@ public void setUp() throws Exception {
 		client = newRepo("client");
 
 		testProtocol = new TestProtocol<>(null,
-				new ReceivePackFactory<Object>() {
-					@Override
-					public ReceivePack create(Object req, Repository git)
-							throws ServiceNotEnabledException,
-							ServiceNotAuthorizedException {
-						receivePack = new ReceivePack(git);
-						receivePack.setAllowPushOptions(true);
-						receivePack.setAtomic(true);
-						return receivePack;
-					}
+				(Object req, Repository git) -> {
+					receivePack = new ReceivePack(git);
+					receivePack.setAllowPushOptions(true);
+					receivePack.setAtomic(true);
+					return receivePack;
 				});
 
 		uri = testProtocol.register(ctx, server);
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/TestProtocolTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/TestProtocolTest.java
index 1c4d0cf..f4c55aa 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/TestProtocolTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/TestProtocolTest.java
@@ -92,11 +92,8 @@ private static class DefaultUpload implements UploadPackFactory<User> {
 		@Override
 		public UploadPack create(User req, Repository db) {
 			UploadPack up = new UploadPack(db);
-			up.setPostUploadHook(new PostUploadHook() {
-				@Override
-				public void onPostUpload(PackStatistics stats) {
-					havesCount = stats.getHaves();
-				}
+			up.setPostUploadHook((PackStatistics stats) -> {
+				havesCount = stats.getHaves();
 			});
 			return up;
 		}
@@ -217,16 +214,12 @@ public void testUploadPackFactory() throws Exception {
 		ObjectId master = remote.branch("master").commit().create();
 
 		final AtomicInteger rejected = new AtomicInteger();
-		TestProtocol<User> proto = registerProto(new UploadPackFactory<User>() {
-			@Override
-			public UploadPack create(User req, Repository db)
-					throws ServiceNotAuthorizedException {
-				if (!"user2".equals(req.name)) {
-					rejected.incrementAndGet();
-					throw new ServiceNotAuthorizedException();
-				}
-				return new UploadPack(db);
+		TestProtocol<User> proto = registerProto((User req, Repository db) -> {
+			if (!"user2".equals(req.name)) {
+				rejected.incrementAndGet();
+				throw new ServiceNotAuthorizedException();
 			}
+			return new UploadPack(db);
 		}, new DefaultReceive());
 
 		// Same repository, different users.
@@ -262,16 +255,12 @@ public void testReceivePackFactory() throws Exception {
 
 		final AtomicInteger rejected = new AtomicInteger();
 		TestProtocol<User> proto = registerProto(new DefaultUpload(),
-				new ReceivePackFactory<User>() {
-					@Override
-					public ReceivePack create(User req, Repository db)
-							throws ServiceNotAuthorizedException {
-						if (!"user2".equals(req.name)) {
-							rejected.incrementAndGet();
-							throw new ServiceNotAuthorizedException();
-						}
-						return new ReceivePack(db);
+				(User req, Repository db) -> {
+					if (!"user2".equals(req.name)) {
+						rejected.incrementAndGet();
+						throw new ServiceNotAuthorizedException();
 					}
+					return new ReceivePack(db);
 				});
 
 		// Same repository, different users.
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/UploadPackTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/UploadPackTest.java
index 9fd7483..9ffcbcc 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/UploadPackTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/UploadPackTest.java
@@ -47,9 +47,6 @@
 import org.eclipse.jgit.revwalk.RevTree;
 import org.eclipse.jgit.storage.pack.PackStatistics;
 import org.eclipse.jgit.transport.UploadPack.RequestPolicy;
-import org.eclipse.jgit.transport.resolver.ServiceNotAuthorizedException;
-import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException;
-import org.eclipse.jgit.transport.resolver.UploadPackFactory;
 import org.eclipse.jgit.util.io.NullOutputStream;
 import org.hamcrest.Matchers;
 import org.junit.After;
@@ -102,17 +99,11 @@ private void generateBitmaps(InMemoryRepository repo) throws Exception {
 	}
 
 	private static TestProtocol<Object> generateReachableCommitUploadPackProtocol() {
-		return new TestProtocol<>(
-				new UploadPackFactory<Object>() {
-					@Override
-					public UploadPack create(Object req, Repository db)
-							throws ServiceNotEnabledException,
-							ServiceNotAuthorizedException {
-						UploadPack up = new UploadPack(db);
-						up.setRequestPolicy(RequestPolicy.REACHABLE_COMMIT);
-						return up;
-					}
-				}, null);
+		return new TestProtocol<>((Object req, Repository db) -> {
+			UploadPack up = new UploadPack(db);
+			up.setRequestPolicy(RequestPolicy.REACHABLE_COMMIT);
+			return up;
+		}, null);
 	}
 
 	@Test
@@ -122,20 +113,14 @@ public void testFetchParentOfShallowCommit() throws Exception {
 		RevCommit tip = remote.commit().message("2").parent(commit1).create();
 		remote.update("master", tip);
 
-		testProtocol = new TestProtocol<>(
-				new UploadPackFactory<Object>() {
-					@Override
-					public UploadPack create(Object req, Repository db)
-							throws ServiceNotEnabledException,
-							ServiceNotAuthorizedException {
-						UploadPack up = new UploadPack(db);
-						up.setRequestPolicy(RequestPolicy.REACHABLE_COMMIT);
-						// assume client has a shallow commit
-						up.getRevWalk().assumeShallow(
-								Collections.singleton(commit1.getId()));
-						return up;
-					}
-				}, null);
+		testProtocol = new TestProtocol<>((Object req, Repository db) -> {
+			UploadPack up = new UploadPack(db);
+			up.setRequestPolicy(RequestPolicy.REACHABLE_COMMIT);
+			// assume client has a shallow commit
+			up.getRevWalk()
+					.assumeShallow(Collections.singleton(commit1.getId()));
+			return up;
+		}, null);
 		uri = testProtocol.register(ctx, server);
 
 		assertFalse(client.getObjectDatabase().has(commit0.toObjectId()));
@@ -222,14 +207,9 @@ public void testFetchWithBlobNoneFilter() throws Exception {
 			server2.getConfig().setBoolean("uploadpack", null, "allowfilter",
 					true);
 
-			testProtocol = new TestProtocol<>(new UploadPackFactory<Object>() {
-				@Override
-				public UploadPack create(Object req, Repository db)
-						throws ServiceNotEnabledException,
-						ServiceNotAuthorizedException {
-					UploadPack up = new UploadPack(db);
-					return up;
-				}
+			testProtocol = new TestProtocol<>((Object req, Repository db) -> {
+				UploadPack up = new UploadPack(db);
+				return up;
 			}, null);
 			uri = testProtocol.register(ctx, server2);
 
@@ -260,14 +240,9 @@ public void testFetchExplicitBlobWithFilter() throws Exception {
 			server2.getConfig().setBoolean("uploadpack", null, "allowfilter",
 					true);
 
-			testProtocol = new TestProtocol<>(new UploadPackFactory<Object>() {
-				@Override
-				public UploadPack create(Object req, Repository db)
-						throws ServiceNotEnabledException,
-						ServiceNotAuthorizedException {
-					UploadPack up = new UploadPack(db);
-					return up;
-				}
+			testProtocol = new TestProtocol<>((Object req, Repository db) -> {
+				UploadPack up = new UploadPack(db);
+				return up;
 			}, null);
 			uri = testProtocol.register(ctx, server2);
 
@@ -297,14 +272,9 @@ public void testFetchWithBlobLimitFilter() throws Exception {
 			server2.getConfig().setBoolean("uploadpack", null, "allowfilter",
 					true);
 
-			testProtocol = new TestProtocol<>(new UploadPackFactory<Object>() {
-				@Override
-				public UploadPack create(Object req, Repository db)
-						throws ServiceNotEnabledException,
-						ServiceNotAuthorizedException {
-					UploadPack up = new UploadPack(db);
-					return up;
-				}
+			testProtocol = new TestProtocol<>((Object req, Repository db) -> {
+				UploadPack up = new UploadPack(db);
+				return up;
 			}, null);
 			uri = testProtocol.register(ctx, server2);
 
@@ -340,14 +310,9 @@ public void testFetchExplicitBlobWithFilterAndBitmaps() throws Exception {
 			new DfsGarbageCollector(server2).pack(null);
 			server2.scanForRepoChanges();
 
-			testProtocol = new TestProtocol<>(new UploadPackFactory<Object>() {
-				@Override
-				public UploadPack create(Object req, Repository db)
-						throws ServiceNotEnabledException,
-						ServiceNotAuthorizedException {
-					UploadPack up = new UploadPack(db);
-					return up;
-				}
+			testProtocol = new TestProtocol<>((Object req, Repository db) -> {
+				UploadPack up = new UploadPack(db);
+				return up;
 			}, null);
 			uri = testProtocol.register(ctx, server2);
 
@@ -380,14 +345,9 @@ public void testFetchWithBlobLimitFilterAndBitmaps() throws Exception {
 			new DfsGarbageCollector(server2).pack(null);
 			server2.scanForRepoChanges();
 
-			testProtocol = new TestProtocol<>(new UploadPackFactory<Object>() {
-				@Override
-				public UploadPack create(Object req, Repository db)
-						throws ServiceNotEnabledException,
-						ServiceNotAuthorizedException {
-					UploadPack up = new UploadPack(db);
-					return up;
-				}
+			testProtocol = new TestProtocol<>((Object req, Repository db) -> {
+				UploadPack up = new UploadPack(db);
+				return up;
 			}, null);
 			uri = testProtocol.register(ctx, server2);
 
@@ -416,14 +376,9 @@ public void testFetchWithNonSupportingServer() throws Exception {
 			server2.getConfig().setBoolean("uploadpack", null, "allowfilter",
 					false);
 
-			testProtocol = new TestProtocol<>(new UploadPackFactory<Object>() {
-				@Override
-				public UploadPack create(Object req, Repository db)
-						throws ServiceNotEnabledException,
-						ServiceNotAuthorizedException {
-					UploadPack up = new UploadPack(db);
-					return up;
-				}
+			testProtocol = new TestProtocol<>((Object req, Repository db) -> {
+				UploadPack up = new UploadPack(db);
+				return up;
 			}, null);
 			uri = testProtocol.register(ctx, server2);
 
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/FileTreeIteratorTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/FileTreeIteratorTest.java
index 6f61912..0303ea2 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/FileTreeIteratorTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/FileTreeIteratorTest.java
@@ -582,26 +582,23 @@ public void idOffset() throws Exception {
 		}
 	}
 
-	private final FileTreeIterator.FileModeStrategy NO_GITLINKS_STRATEGY =
-			new FileTreeIterator.FileModeStrategy() {
-				@Override
-				public FileMode getMode(File f, FS.Attributes attributes) {
-					if (attributes.isSymbolicLink()) {
-						return FileMode.SYMLINK;
-					} else if (attributes.isDirectory()) {
-						// NOTE: in the production DefaultFileModeStrategy, there is
-						// a check here for a subdirectory called '.git', and if it
-						// exists, we create a GITLINK instead of recursing into the
-						// tree.  In this custom strategy, we ignore nested git dirs
-						// and treat all directories the same.
-						return FileMode.TREE;
-					} else if (attributes.isExecutable()) {
-						return FileMode.EXECUTABLE_FILE;
-					} else {
-						return FileMode.REGULAR_FILE;
-					}
-				}
-			};
+	private final FileTreeIterator.FileModeStrategy NO_GITLINKS_STRATEGY = (
+			File f, FS.Attributes attributes) -> {
+		if (attributes.isSymbolicLink()) {
+			return FileMode.SYMLINK;
+		} else if (attributes.isDirectory()) {
+			// NOTE: in the production DefaultFileModeStrategy, there is
+			// a check here for a subdirectory called '.git', and if it
+			// exists, we create a GITLINK instead of recursing into the
+			// tree. In this custom strategy, we ignore nested git dirs
+			// and treat all directories the same.
+			return FileMode.TREE;
+		} else if (attributes.isExecutable()) {
+			return FileMode.EXECUTABLE_FILE;
+		} else {
+			return FileMode.REGULAR_FILE;
+		}
+	};
 
 	private Repository createNestedRepo() throws IOException {
 		File gitdir = createUniqueTestGitDir(false);
diff --git a/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties b/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties
index 9d221c9..fc2a26f 100644
--- a/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties
+++ b/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties
@@ -330,6 +330,7 @@
 gpgNoKeyInLegacySecring=no matching secret key found in legacy secring.gpg for key or user id: {0}
 gpgNoPublicKeyFound=Unable to find a public-key with key or user id: {0}
 gpgNoSecretKeyForPublicKey=unable to find associated secret key for public key: {0}
+gpgNotASigningKey=Secret key ({0}) is not suitable for signing
 gpgKeyInfo=GPG Key (fingerprint {0})
 gpgSigningCancelled=Signing was cancelled
 headRequiredToStash=HEAD required to stash local changes
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/DescribeCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/DescribeCommand.java
index 831865a..9ebcf9f 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/DescribeCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/DescribeCommand.java
@@ -402,12 +402,8 @@ String describe(ObjectId tip) throws IOException {
 			if (candidates.isEmpty())
 				return null;
 
-			Candidate best = Collections.min(candidates, new Comparator<Candidate>() {
-				@Override
-				public int compare(Candidate o1, Candidate o2) {
-					return o1.depth - o2.depth;
-				}
-			});
+			Candidate best = Collections.min(candidates,
+					(Candidate o1, Candidate o2) -> o1.depth - o2.depth);
 
 			return best.describe(target);
 		} catch (IOException e) {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/ListBranchCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/ListBranchCommand.java
index 29a51a0..e0eafc7 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/ListBranchCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/ListBranchCommand.java
@@ -53,7 +53,6 @@
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
-import java.util.Comparator;
 import java.util.List;
 
 import org.eclipse.jgit.api.errors.GitAPIException;
@@ -134,12 +133,8 @@ public List<Ref> call() throws GitAPIException {
 			throw new JGitInternalException(e.getMessage(), e);
 		}
 
-		Collections.sort(resultRefs, new Comparator<Ref>() {
-			@Override
-			public int compare(Ref o1, Ref o2) {
-				return o1.getName().compareTo(o2.getName());
-			}
-		});
+		Collections.sort(resultRefs,
+				(Ref o1, Ref o2) -> o1.getName().compareTo(o2.getName()));
 		setCallable(false);
 		return resultRefs;
 	}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/ListTagCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/ListTagCommand.java
index 01c1991..c894d05 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/ListTagCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/ListTagCommand.java
@@ -45,7 +45,6 @@
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Collections;
-import java.util.Comparator;
 import java.util.List;
 
 import org.eclipse.jgit.api.errors.GitAPIException;
@@ -87,12 +86,8 @@ public List<Ref> call() throws GitAPIException {
 		} catch (IOException e) {
 			throw new JGitInternalException(e.getMessage(), e);
 		}
-		Collections.sort(tags, new Comparator<Ref>() {
-			@Override
-			public int compare(Ref o1, Ref o2) {
-				return o1.getName().compareTo(o2.getName());
-			}
-		});
+		Collections.sort(tags,
+				(Ref o1, Ref o2) -> o1.getName().compareTo(o2.getName()));
 		setCallable(false);
 		return tags;
 	}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCache.java b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCache.java
index 667634f..eeab03d 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCache.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCache.java
@@ -111,14 +111,12 @@ public class DirCache {
 
 	private static final byte[] NO_CHECKSUM = {};
 
-	static final Comparator<DirCacheEntry> ENT_CMP = new Comparator<DirCacheEntry>() {
-		@Override
-		public int compare(DirCacheEntry o1, DirCacheEntry o2) {
-			final int cr = cmp(o1, o2);
-			if (cr != 0)
-				return cr;
-			return o1.getStage() - o2.getStage();
-		}
+	static final Comparator<DirCacheEntry> ENT_CMP = (DirCacheEntry o1,
+			DirCacheEntry o2) -> {
+		final int cr = cmp(o1, o2);
+		if (cr != 0)
+			return cr;
+		return o1.getStage() - o2.getStage();
 	};
 
 	static int cmp(DirCacheEntry a, DirCacheEntry b) {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheEditor.java b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheEditor.java
index 74ba97f..5b8e11f 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheEditor.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheEditor.java
@@ -75,13 +75,11 @@
  * @see DirCacheBuilder
  */
 public class DirCacheEditor extends BaseDirCacheEditor {
-	private static final Comparator<PathEdit> EDIT_CMP = new Comparator<PathEdit>() {
-		@Override
-		public int compare(PathEdit o1, PathEdit o2) {
-			final byte[] a = o1.path;
-			final byte[] b = o2.path;
-			return cmp(a, a.length, b, b.length);
-		}
+	private static final Comparator<PathEdit> EDIT_CMP = (PathEdit o1,
+			PathEdit o2) -> {
+		final byte[] a = o1.path;
+		final byte[] b = o2.path;
+		return cmp(a, a.length, b, b.length);
 	};
 
 	private final List<PathEdit> edits;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheTree.java b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheTree.java
index 11a3474..80e1084 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheTree.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheTree.java
@@ -81,25 +81,26 @@ public class DirCacheTree {
 
 	private static final DirCacheTree[] NO_CHILDREN = {};
 
-	private static final Comparator<DirCacheTree> TREE_CMP = new Comparator<DirCacheTree>() {
-		@Override
-		public int compare(DirCacheTree o1, DirCacheTree o2) {
-			final byte[] a = o1.encodedName;
-			final byte[] b = o2.encodedName;
-			final int aLen = a.length;
-			final int bLen = b.length;
-			int cPos;
-			for (cPos = 0; cPos < aLen && cPos < bLen; cPos++) {
-				final int cmp = (a[cPos] & 0xff) - (b[cPos] & 0xff);
-				if (cmp != 0)
-					return cmp;
+	private static final Comparator<DirCacheTree> TREE_CMP = (DirCacheTree o1,
+			DirCacheTree o2) -> {
+		final byte[] a = o1.encodedName;
+		final byte[] b = o2.encodedName;
+		final int aLen = a.length;
+		final int bLen = b.length;
+		int cPos;
+		for (cPos = 0; cPos < aLen && cPos < bLen; cPos++) {
+			final int cmp = (a[cPos] & 0xff) - (b[cPos] & 0xff);
+			if (cmp != 0) {
+				return cmp;
 			}
-			if (aLen == bLen)
-				return 0;
-			if (aLen < bLen)
-				return '/' - (b[cPos] & 0xff);
-			return (a[cPos] & 0xff) - '/';
 		}
+		if (aLen == bLen) {
+			return 0;
+		}
+		if (aLen < bLen) {
+			return '/' - (b[cPos] & 0xff);
+		}
+		return (a[cPos] & 0xff) - '/';
 	};
 
 	/** Tree this tree resides in; null if we are the root. */
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java
index 018b643..ca0024d 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java
@@ -391,6 +391,7 @@ public static JGitText get() {
 	/***/ public String gpgNoKeyInLegacySecring;
 	/***/ public String gpgNoPublicKeyFound;
 	/***/ public String gpgNoSecretKeyForPublicKey;
+	/***/ public String gpgNotASigningKey;
 	/***/ public String gpgKeyInfo;
 	/***/ public String gpgSigningCancelled;
 	/***/ public String headRequiredToStash;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/ketch/KetchLeader.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/ketch/KetchLeader.java
index fa32b26..c0364ac 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/ketch/KetchLeader.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/ketch/KetchLeader.java
@@ -385,12 +385,7 @@ private void initialize() throws IOException {
 
 	private void scheduleLeader() {
 		idle = false;
-		system.getExecutor().execute(new Runnable() {
-			@Override
-			public void run() {
-				runLeader();
-			}
-		});
+		system.getExecutor().execute(this::runLeader);
 	}
 
 	private void runLeader() {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/ketch/LocalReplica.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/ketch/LocalReplica.java
index 6f1f5c5..cd0ded5 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/ketch/LocalReplica.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/ketch/LocalReplica.java
@@ -123,21 +123,18 @@ void initialize(Repository repo) throws IOException {
 	/** {@inheritDoc} */
 	@Override
 	protected void startPush(ReplicaPushRequest req) {
-		getSystem().getExecutor().execute(new Runnable() {
-			@Override
-			public void run() {
-				MonotonicClock clk = getSystem().getClock();
-				try (Repository git = getLeader().openRepository();
-						ProposedTimestamp ts = clk.propose()) {
-					try {
-						update(git, req, ts);
-						req.done(git);
-					} catch (Throwable err) {
-						req.setException(git, err);
-					}
-				} catch (IOException err) {
-					req.setException(null, err);
+		getSystem().getExecutor().execute(() -> {
+			MonotonicClock clk = getSystem().getClock();
+			try (Repository git = getLeader().openRepository();
+					ProposedTimestamp ts = clk.propose()) {
+				try {
+					update(git, req, ts);
+					req.done(git);
+				} catch (Throwable err) {
+					req.setException(git, err);
 				}
+			} catch (IOException err) {
+				req.setException(null, err);
 			}
 		});
 	}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/ketch/RemoteGitReplica.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/ketch/RemoteGitReplica.java
index b61274e..3c9b187 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/ketch/RemoteGitReplica.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/ketch/RemoteGitReplica.java
@@ -139,19 +139,16 @@ protected String describeForLog() {
 	/** {@inheritDoc} */
 	@Override
 	protected void startPush(ReplicaPushRequest req) {
-		getSystem().getExecutor().execute(new Runnable() {
-			@Override
-			public void run() {
-				try (Repository git = getLeader().openRepository()) {
-					try {
-						push(git, req);
-						req.done(git);
-					} catch (Throwable err) {
-						req.setException(git, err);
-					}
-				} catch (IOException err) {
-					req.setException(null, err);
+		getSystem().getExecutor().execute(() -> {
+			try (Repository git = getLeader().openRepository()) {
+				try {
+					push(git, req);
+					req.done(git);
+				} catch (Throwable err) {
+					req.setException(git, err);
 				}
+			} catch (IOException err) {
+				req.setException(null, err);
 			}
 		});
 	}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackCompactor.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackCompactor.java
index 127ee6b..6f3f2bd 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackCompactor.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackCompactor.java
@@ -469,12 +469,8 @@ private List<ObjectIdWithOffset> toInclude(DfsPackFile src, DfsReader ctx)
 					continue SCAN;
 			want.add(new ObjectIdWithOffset(id, ent.getOffset()));
 		}
-		Collections.sort(want, new Comparator<ObjectIdWithOffset>() {
-			@Override
-			public int compare(ObjectIdWithOffset a, ObjectIdWithOffset b) {
-				return Long.signum(a.offset - b.offset);
-			}
-		});
+		Collections.sort(want, (ObjectIdWithOffset a,
+				ObjectIdWithOffset b) -> Long.signum(a.offset - b.offset));
 		return want;
 	}
 
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsReader.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsReader.java
index 1a5553d..c75b88f 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsReader.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsReader.java
@@ -287,14 +287,12 @@ public Set<ObjectId> getShallowCommits() {
 		return Collections.emptySet();
 	}
 
-	private static final Comparator<FoundObject<?>> FOUND_OBJECT_SORT = new Comparator<FoundObject<?>>() {
-		@Override
-		public int compare(FoundObject<?> a, FoundObject<?> b) {
-			int cmp = a.packIndex - b.packIndex;
-			if (cmp == 0)
-				cmp = Long.signum(a.offset - b.offset);
-			return cmp;
-		}
+	private static final Comparator<FoundObject<?>> FOUND_OBJECT_SORT = (
+			FoundObject<?> a, FoundObject<?> b) -> {
+		int cmp = a.packIndex - b.packIndex;
+		if (cmp == 0)
+			cmp = Long.signum(a.offset - b.offset);
+		return cmp;
 	};
 
 	private static class FoundObject<T extends ObjectId> {
@@ -565,12 +563,9 @@ public DfsObjectToPack newObjectToPack(AnyObjectId objectId, int type) {
 		return new DfsObjectToPack(objectId, type);
 	}
 
-	private static final Comparator<DfsObjectToPack> OFFSET_SORT = new Comparator<DfsObjectToPack>() {
-		@Override
-		public int compare(DfsObjectToPack a, DfsObjectToPack b) {
-			return Long.signum(a.getOffset() - b.getOffset());
-		}
-	};
+	private static final Comparator<DfsObjectToPack> OFFSET_SORT = (
+			DfsObjectToPack a,
+			DfsObjectToPack b) -> Long.signum(a.getOffset() - b.getOffset());
 
 	@Override
 	public void selectObjectRepresentation(PackWriter packer,
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileRepository.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileRepository.java
index 5ced686..d82d29e 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileRepository.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileRepository.java
@@ -62,8 +62,6 @@
 import org.eclipse.jgit.attributes.AttributesNode;
 import org.eclipse.jgit.attributes.AttributesNodeProvider;
 import org.eclipse.jgit.errors.ConfigInvalidException;
-import org.eclipse.jgit.events.ConfigChangedEvent;
-import org.eclipse.jgit.events.ConfigChangedListener;
 import org.eclipse.jgit.events.IndexChangedEvent;
 import org.eclipse.jgit.internal.JGitText;
 import org.eclipse.jgit.internal.storage.file.ObjectDirectory.AlternateHandle;
@@ -206,12 +204,7 @@ public boolean isOutdated() {
 		loadUserConfig();
 		loadRepoConfig();
 
-		repoConfig.addChangeListener(new ConfigChangedListener() {
-			@Override
-			public void onConfigChanged(ConfigChangedEvent event) {
-				fireEvent(event);
-			}
-		});
+		repoConfig.addChangeListener(this::fireEvent);
 
 		final long repositoryFormatVersion = getConfig().getLong(
 				ConfigConstants.CONFIG_CORE_SECTION, null,
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/LockFile.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/LockFile.java
index f0ee22d..a4fc1a2 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/LockFile.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/LockFile.java
@@ -116,12 +116,8 @@ static File getLockFile(File file) {
 	}
 
 	/** Filter to skip over active lock files when listing a directory. */
-	static final FilenameFilter FILTER = new FilenameFilter() {
-		@Override
-		public boolean accept(File dir, String name) {
-			return !name.endsWith(LOCK_SUFFIX);
-		}
-	};
+	static final FilenameFilter FILTER = (File dir,
+			String name) -> !name.endsWith(LOCK_SUFFIX);
 
 	private final File ref;
 
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackBitmapIndexBuilder.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackBitmapIndexBuilder.java
index eff7958..9941ff3 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackBitmapIndexBuilder.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackBitmapIndexBuilder.java
@@ -45,7 +45,6 @@
 
 import java.text.MessageFormat;
 import java.util.Collections;
-import java.util.Comparator;
 import java.util.Iterator;
 import java.util.List;
 import java.util.NoSuchElementException;
@@ -133,12 +132,8 @@ private static void sortByOffsetAndIndex(BlockList<PositionEntry> byOffset,
 		for (int i = 0; i < entries.size(); i++) {
 			positionEntries.add(new PositionEntry(entries.get(i), i));
 		}
-		Collections.sort(entries, new Comparator<ObjectToPack>() {
-			@Override
-			public int compare(ObjectToPack a, ObjectToPack b) {
-				return Long.signum(a.getOffset() - b.getOffset());
-			}
-		});
+		Collections.sort(entries, (ObjectToPack a, ObjectToPack b) -> Long
+				.signum(a.getOffset() - b.getOffset()));
 		for (int i = 0; i < entries.size(); i++) {
 			PositionEntry e = positionEntries.get(entries.get(i));
 			e.offsetPosition = i;
@@ -310,57 +305,55 @@ public int getObjectCount() {
 	public Iterable<StoredEntry> getCompressedBitmaps() {
 		// Add order is from oldest to newest. The reverse add order is the
 		// output order.
-		return new Iterable<StoredEntry>() {
+		return () -> new Iterator<StoredEntry>() {
+
+			private int index = byAddOrder.size() - 1;
+
 			@Override
-			public Iterator<StoredEntry> iterator() {
-				return new Iterator<StoredEntry>() {
-					private int index = byAddOrder.size() - 1;
+			public boolean hasNext() {
+				return index >= 0;
+			}
 
-					@Override
-					public boolean hasNext() {
-						return index >= 0;
+			@Override
+			public StoredEntry next() {
+				if (!hasNext()) {
+					throw new NoSuchElementException();
+				}
+				StoredBitmap item = byAddOrder.get(index);
+				int bestXorOffset = 0;
+				EWAHCompressedBitmap bestBitmap = item.getBitmap();
+
+				// Attempt to compress the bitmap with an XOR of the
+				// previously written entries.
+				for (int i = 1; i <= MAX_XOR_OFFSET_SEARCH; i++) {
+					int curr = i + index;
+					if (curr >= byAddOrder.size()) {
+						break;
 					}
 
-					@Override
-					public StoredEntry next() {
-						if (!hasNext())
-							throw new NoSuchElementException();
-						StoredBitmap item = byAddOrder.get(index);
-						int bestXorOffset = 0;
-						EWAHCompressedBitmap bestBitmap = item.getBitmap();
+					StoredBitmap other = byAddOrder.get(curr);
+					EWAHCompressedBitmap bitmap = other.getBitmap()
+							.xor(item.getBitmap());
 
-						// Attempt to compress the bitmap with an XOR of the
-						// previously written entries.
-						for (int i = 1; i <= MAX_XOR_OFFSET_SEARCH; i++) {
-							int curr = i + index;
-							if (curr >= byAddOrder.size())
-								break;
-
-							StoredBitmap other = byAddOrder.get(curr);
-							EWAHCompressedBitmap bitmap = other.getBitmap()
-									.xor(item.getBitmap());
-
-							if (bitmap.sizeInBytes()
-									< bestBitmap.sizeInBytes()) {
-								bestBitmap = bitmap;
-								bestXorOffset = i;
-							}
-						}
-						index--;
-
-						PositionEntry entry = positionEntries.get(item);
-						if (entry == null)
-							throw new IllegalStateException();
-						bestBitmap.trim();
-						return new StoredEntry(entry.namePosition, bestBitmap,
-								bestXorOffset, item.getFlags());
+					if (bitmap.sizeInBytes() < bestBitmap.sizeInBytes()) {
+						bestBitmap = bitmap;
+						bestXorOffset = i;
 					}
+				}
+				index--;
 
-					@Override
-					public void remove() {
-						throw new UnsupportedOperationException();
-					}
-				};
+				PositionEntry entry = positionEntries.get(item);
+				if (entry == null) {
+					throw new IllegalStateException();
+				}
+				bestBitmap.trim();
+				return new StoredEntry(entry.namePosition, bestBitmap,
+						bestXorOffset, item.getFlags());
+			}
+
+			@Override
+			public void remove() {
+				throw new UnsupportedOperationException();
 			}
 		};
 	}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackFile.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackFile.java
index d834b1a..c1aac23 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackFile.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackFile.java
@@ -101,12 +101,8 @@
  */
 public class PackFile implements Iterable<PackIndex.MutableEntry> {
 	/** Sorts PackFiles to be most recently created to least recently created. */
-	public static final Comparator<PackFile> SORT = new Comparator<PackFile>() {
-		@Override
-		public int compare(PackFile a, PackFile b) {
-			return b.packLastModified - a.packLastModified;
-		}
-	};
+	public static final Comparator<PackFile> SORT = (PackFile a,
+			PackFile b) -> b.packLastModified - a.packLastModified;
 
 	private final File packFile;
 
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/DeltaTask.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/DeltaTask.java
index 0347644..a211d16 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/DeltaTask.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/DeltaTask.java
@@ -46,7 +46,6 @@
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Collections;
-import java.util.Comparator;
 import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
@@ -212,12 +211,8 @@ private ArrayList<WeightedPath> computeTopPaths() {
 			}
 
 			// Sort by starting index to identify gaps later.
-			Collections.sort(topPaths, new Comparator<WeightedPath>() {
-				@Override
-				public int compare(WeightedPath a, WeightedPath b) {
-					return a.slice.beginIndex - b.slice.beginIndex;
-				}
-			});
+			Collections.sort(topPaths, (WeightedPath a,
+					WeightedPath b) -> a.slice.beginIndex - b.slice.beginIndex);
 
 			bytesPerUnit = 1;
 			while (MAX_METER <= (totalWeight / bytesPerUnit)) {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackWriter.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackWriter.java
index b6e6a6c..2f7e1a6 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackWriter.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackWriter.java
@@ -62,7 +62,6 @@
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
-import java.util.Comparator;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
@@ -1418,32 +1417,33 @@ private void searchForDeltas(ProgressMonitor monitor)
 		// applies "Linus' Law" which states that newer files tend to be the
 		// bigger ones, because source files grow and hardly ever shrink.
 		//
-		Arrays.sort(list, 0, cnt, new Comparator<ObjectToPack>() {
-			@Override
-			public int compare(ObjectToPack a, ObjectToPack b) {
-				int cmp = (a.isDoNotDelta() ? 1 : 0)
-						- (b.isDoNotDelta() ? 1 : 0);
-				if (cmp != 0)
-					return cmp;
-
-				cmp = a.getType() - b.getType();
-				if (cmp != 0)
-					return cmp;
-
-				cmp = (a.getPathHash() >>> 1) - (b.getPathHash() >>> 1);
-				if (cmp != 0)
-					return cmp;
-
-				cmp = (a.getPathHash() & 1) - (b.getPathHash() & 1);
-				if (cmp != 0)
-					return cmp;
-
-				cmp = (a.isEdge() ? 0 : 1) - (b.isEdge() ? 0 : 1);
-				if (cmp != 0)
-					return cmp;
-
-				return b.getWeight() - a.getWeight();
+		Arrays.sort(list, 0, cnt, (ObjectToPack a, ObjectToPack b) -> {
+			int cmp = (a.isDoNotDelta() ? 1 : 0) - (b.isDoNotDelta() ? 1 : 0);
+			if (cmp != 0) {
+				return cmp;
 			}
+
+			cmp = a.getType() - b.getType();
+			if (cmp != 0) {
+				return cmp;
+			}
+
+			cmp = (a.getPathHash() >>> 1) - (b.getPathHash() >>> 1);
+			if (cmp != 0) {
+				return cmp;
+			}
+
+			cmp = (a.getPathHash() & 1) - (b.getPathHash() & 1);
+			if (cmp != 0) {
+				return cmp;
+			}
+
+			cmp = (a.isEdge() ? 0 : 1) - (b.isEdge() ? 0 : 1);
+			if (cmp != 0) {
+				return cmp;
+			}
+
+			return b.getWeight() - a.getWeight();
 		});
 
 		// Above we stored the objects we cannot delta onto the end.
@@ -1564,14 +1564,11 @@ private void parallelDeltaSearch(ProgressMonitor monitor,
 			// asynchronous execution.  Wrap everything and hope it
 			// can schedule these for us.
 			for (DeltaTask task : taskBlock.tasks) {
-				executor.execute(new Runnable() {
-					@Override
-					public void run() {
-						try {
-							task.call();
-						} catch (Throwable failure) {
-							errors.add(failure);
-						}
+				executor.execute(() -> {
+					try {
+						task.call();
+					} catch (Throwable failure) {
+						errors.add(failure);
 					}
 				});
 			}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackWriterBitmapPreparer.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackWriterBitmapPreparer.java
index 99db749..d3b5e12 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackWriterBitmapPreparer.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackWriterBitmapPreparer.java
@@ -91,12 +91,9 @@ class PackWriterBitmapPreparer {
 
 	private static final int DAY_IN_SECONDS = 24 * 60 * 60;
 
-	private static final Comparator<RevCommit> ORDER_BY_REVERSE_TIMESTAMP = new Comparator<RevCommit>() {
-		@Override
-		public int compare(RevCommit a, RevCommit b) {
-			return Integer.signum(b.getCommitTime() - a.getCommitTime());
-		}
-	};
+	private static final Comparator<RevCommit> ORDER_BY_REVERSE_TIMESTAMP = (
+			RevCommit a, RevCommit b) -> Integer
+					.signum(b.getCommitTime() - a.getCommitTime());
 
 	private final ObjectReader reader;
 	private final ProgressMonitor pm;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/IndexDiff.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/IndexDiff.java
index f37c310..42d1330 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/IndexDiff.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/IndexDiff.java
@@ -352,12 +352,7 @@ public interface WorkingTreeIteratorFactory {
 		public WorkingTreeIterator getWorkingTreeIterator(Repository repo);
 	}
 
-	private WorkingTreeIteratorFactory wTreeIt = new WorkingTreeIteratorFactory() {
-		@Override
-		public WorkingTreeIterator getWorkingTreeIterator(Repository repo) {
-			return new FileTreeIterator(repo);
-		}
-	};
+	private WorkingTreeIteratorFactory wTreeIt = FileTreeIterator::new;
 
 	/**
 	 * Allows higher layers to set the factory for WorkingTreeIterators.
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/Repository.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/Repository.java
index b242f98..aac63e9 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/Repository.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/Repository.java
@@ -1277,11 +1277,8 @@ public DirCache lockDirCache() throws NoWorkTreeException,
 			CorruptObjectException, IOException {
 		// we want DirCache to inform us so that we can inform registered
 		// listeners about index changes
-		IndexChangedListener l = new IndexChangedListener() {
-			@Override
-			public void onIndexChanged(IndexChangedEvent event) {
-				notifyIndexChanged(true);
-			}
+		IndexChangedListener l = (IndexChangedEvent event) -> {
+			notifyIndexChanged(true);
 		};
 		return DirCache.lock(this, l);
 	}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/RepositoryCache.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/RepositoryCache.java
index 400342b1..27befba 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/RepositoryCache.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/RepositoryCache.java
@@ -255,14 +255,11 @@ private void configureEviction(
 			if (delay == RepositoryCacheConfig.NO_CLEANUP) {
 				return;
 			}
-			cleanupTask = scheduler.scheduleWithFixedDelay(new Runnable() {
-				@Override
-				public void run() {
-					try {
-						cache.clearAllExpired();
-					} catch (Throwable e) {
-						LOG.error(e.getMessage(), e);
-					}
+			cleanupTask = scheduler.scheduleWithFixedDelay(() -> {
+				try {
+					cache.clearAllExpired();
+				} catch (Throwable e) {
+					LOG.error(e.getMessage(), e);
 				}
 			}, delay, delay, TimeUnit.MILLISECONDS);
 		}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/internal/BouncyCastleGpgKeyLocator.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/internal/BouncyCastleGpgKeyLocator.java
index c942cf4..df9615f 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/internal/BouncyCastleGpgKeyLocator.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/internal/BouncyCastleGpgKeyLocator.java
@@ -181,10 +181,11 @@ private boolean containsSigningKey(String userId) {
 
 	private PGPPublicKey findPublicKeyByKeyId(KeyBlob keyBlob)
 			throws IOException {
+		String keyId = signingKey.toLowerCase(Locale.ROOT);
 		for (KeyInformation keyInfo : keyBlob.getKeyInformation()) {
-			if (signingKey.toLowerCase(Locale.ROOT)
-					.equals(Hex.toHexString(keyInfo.getKeyID())
-							.toLowerCase(Locale.ROOT))) {
+			String fingerprint = Hex.toHexString(keyInfo.getFingerprint())
+					.toLowerCase(Locale.ROOT);
+			if (fingerprint.endsWith(keyId)) {
 				return getFirstPublicKey(keyBlob);
 			}
 		}
@@ -260,6 +261,10 @@ public BouncyCastleGpgKey findSecretKey()
 					USER_PGP_LEGACY_SECRING_FILE);
 
 			if (secretKey != null) {
+				if (!secretKey.isSigningKey()) {
+					throw new PGPException(MessageFormat.format(
+							JGitText.get().gpgNotASigningKey, signingKey));
+				}
 				return new BouncyCastleGpgKey(secretKey, USER_PGP_LEGACY_SECRING_FILE);
 			}
 
@@ -293,6 +298,10 @@ private BouncyCastleGpgKey findSecretKeyForKeyBoxPublicKey(
 				PGPSecretKey secretKey = attemptParseSecretKey(keyFile,
 						calculatorProvider, passphraseProvider, publicKey);
 				if (secretKey != null) {
+					if (!secretKey.isSigningKey()) {
+						throw new PGPException(MessageFormat.format(
+								JGitText.get().gpgNotASigningKey, signingKey));
+					}
 					return new BouncyCastleGpgKey(secretKey, userKeyboxPath);
 				}
 			}
@@ -334,6 +343,7 @@ private PGPSecretKey findSecretKeyInLegacySecring(String signingkey,
 					PGPUtil.getDecoderStream(new BufferedInputStream(in)),
 					new JcaKeyFingerprintCalculator());
 
+			String keyId = signingkey.toLowerCase(Locale.ROOT);
 			Iterator<PGPSecretKeyRing> keyrings = pgpSec.getKeyRings();
 			while (keyrings.hasNext()) {
 				PGPSecretKeyRing keyRing = keyrings.next();
@@ -344,8 +354,7 @@ private PGPSecretKey findSecretKeyInLegacySecring(String signingkey,
 					String fingerprint = Hex
 							.toHexString(key.getPublicKey().getFingerprint())
 							.toLowerCase(Locale.ROOT);
-					if (fingerprint
-							.endsWith(signingkey.toLowerCase(Locale.ROOT))) {
+					if (fingerprint.endsWith(keyId)) {
 						return key;
 					}
 					// try user id
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/BitmapCalculator.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/BitmapCalculator.java
new file mode 100644
index 0000000..e1d5d4a
--- /dev/null
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/BitmapCalculator.java
@@ -0,0 +1,93 @@
+package org.eclipse.jgit.revwalk;
+
+import static java.util.Objects.requireNonNull;
+
+import java.io.IOException;
+
+import org.eclipse.jgit.errors.IncorrectObjectTypeException;
+import org.eclipse.jgit.errors.MissingObjectException;
+import org.eclipse.jgit.internal.revwalk.AddToBitmapFilter;
+import org.eclipse.jgit.lib.BitmapIndex;
+import org.eclipse.jgit.lib.BitmapIndex.Bitmap;
+import org.eclipse.jgit.lib.BitmapIndex.BitmapBuilder;
+import org.eclipse.jgit.lib.ProgressMonitor;
+
+/**
+ * Calculate the bitmap indicating what other commits are reachable from certain
+ * commit.
+ * <p>
+ * This bitmap refers only to commits. For a bitmap with ALL objects reachable
+ * from certain object, see {@code BitmapWalker}.
+ */
+class BitmapCalculator {
+
+	private final RevWalk walk;
+	private final BitmapIndex bitmapIndex;
+
+	BitmapCalculator(RevWalk walk) throws IOException {
+		this.walk = walk;
+		this.bitmapIndex = requireNonNull(
+				walk.getObjectReader().getBitmapIndex());
+	}
+
+	/**
+	 * Get the reachability bitmap from certain commit to other commits.
+	 * <p>
+	 * This will return a precalculated bitmap if available or walk building one
+	 * until finding a precalculated bitmap (and returning the union).
+	 * <p>
+	 * Beware that the returned bitmap it is guaranteed to include ONLY the
+	 * commits reachable from the initial commit. It COULD include other objects
+	 * (because precalculated bitmaps have them) but caller shouldn't count on
+	 * that. See {@link BitmapWalker} for a full reachability bitmap.
+	 *
+	 * @param start
+	 *            the commit. Use {@code walk.parseCommit(objectId)} to get this
+	 *            object from the id.
+	 * @param pm
+	 *            progress monitor. Updated by one per commit browsed in the
+	 *            graph
+	 * @return the bitmap of reachable commits (and maybe some extra objects)
+	 *         for the commit
+	 * @throws MissingObjectException
+	 *             the supplied id doesn't exist
+	 * @throws IncorrectObjectTypeException
+	 *             the supplied id doens't refer to a commit or a tag
+	 * @throws IOException
+	 */
+	BitmapBuilder getBitmap(RevCommit start, ProgressMonitor pm)
+			throws MissingObjectException,
+			IncorrectObjectTypeException, IOException {
+		Bitmap precalculatedBitmap = bitmapIndex.getBitmap(start);
+		if (precalculatedBitmap != null) {
+			return asBitmapBuilder(precalculatedBitmap);
+		}
+
+		walk.reset();
+		walk.sort(RevSort.TOPO);
+		walk.markStart(start);
+		// Unbounded walk. If the repo has bitmaps, it should bump into one at
+		// some point.
+
+		BitmapBuilder bitmapResult = bitmapIndex.newBitmapBuilder();
+		walk.setRevFilter(new AddToBitmapFilter(bitmapResult));
+		while (walk.next() != null) {
+			// Iterate through all of the commits. The BitmapRevFilter does
+			// the work.
+			//
+			// filter.include returns true for commits that do not have
+			// a bitmap in bitmapIndex and are not reachable from a
+			// bitmap in bitmapIndex encountered earlier in the walk.
+			// Thus the number of commits returned by next() measures how
+			// much history was traversed without being able to make use
+			// of bitmaps.
+			pm.update(1);
+		}
+
+		return bitmapResult;
+	}
+
+	private BitmapBuilder asBitmapBuilder(Bitmap bitmap) {
+		return bitmapIndex.newBitmapBuilder().or(bitmap);
+	}
+}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/BitmappedReachabilityChecker.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/BitmappedReachabilityChecker.java
new file mode 100644
index 0000000..ab45343
--- /dev/null
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/BitmappedReachabilityChecker.java
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2019, Google LLC
+ * and other copyright owners as documented in the project's IP log.
+ *
+ * This program and the accompanying materials are made available
+ * under the terms of the Eclipse Distribution License v1.0 which
+ * accompanies this distribution, is reproduced below, and is
+ * available at http://www.eclipse.org/org/documents/edl-v10.php
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above
+ *   copyright notice, this list of conditions and the following
+ *   disclaimer in the documentation and/or other materials provided
+ *   with the distribution.
+ *
+ * - Neither the name of the Eclipse Foundation, Inc. nor the
+ *   names of its contributors may be used to endorse or promote
+ *   products derived from this software without specific prior
+ *   written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.eclipse.jgit.revwalk;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Optional;
+
+import org.eclipse.jgit.errors.IncorrectObjectTypeException;
+import org.eclipse.jgit.errors.MissingObjectException;
+import org.eclipse.jgit.lib.BitmapIndex.BitmapBuilder;
+import org.eclipse.jgit.lib.NullProgressMonitor;
+
+/**
+ * Checks the reachability using bitmaps.
+ *
+ * @since 5.4
+ */
+public class BitmappedReachabilityChecker implements ReachabilityChecker {
+
+	private final RevWalk walk;
+
+	/**
+	 * @param walk
+	 *            walk on the repository to get or create the bitmaps for the
+	 *            commits. It must have bitmaps.
+	 * @throws AssertionError
+	 *             runtime exception if walk is over a repository without
+	 *             bitmaps
+	 * @throws IOException
+	 *             if the index or the object reader cannot be opened.
+	 */
+	public BitmappedReachabilityChecker(RevWalk walk)
+			throws IOException {
+		this.walk = walk;
+		if (walk.getObjectReader().getBitmapIndex() == null) {
+			throw new AssertionError(
+					"Trying to use bitmapped reachability check " //$NON-NLS-1$
+							+ "on a repository without bitmaps"); //$NON-NLS-1$
+		}
+	}
+
+	/**
+	 * Check all targets are reachable from the starters.
+	 * <p>
+	 * In this implementation, it is recommended to put the most popular
+	 * starters (e.g. refs/heads tips) at the beginning of the collection
+	 */
+	@Override
+	public Optional<RevCommit> areAllReachable(Collection<RevCommit> targets,
+			Collection<RevCommit> starters) throws MissingObjectException,
+			IncorrectObjectTypeException, IOException {
+		BitmapCalculator calculator = new BitmapCalculator(walk);
+
+		/**
+		 * Iterate over starters bitmaps and remove targets as they become
+		 * reachable.
+		 *
+		 * Building the total starters bitmap has the same cost (iterating over
+		 * all starters adding the bitmaps) and this gives us the chance to
+		 * shorcut the loop.
+		 *
+		 * This is based on the assuption that most of the starters will have
+		 * the reachability bitmap precalculated. If many require a walk, the
+		 * walk.reset() could start to take too much time.
+		 */
+		List<RevCommit> remainingTargets = new ArrayList<>(targets);
+		for (RevCommit starter : starters) {
+			BitmapBuilder starterBitmap = calculator.getBitmap(starter,
+					NullProgressMonitor.INSTANCE);
+			remainingTargets.removeIf(starterBitmap::contains);
+			if (remainingTargets.isEmpty()) {
+				return Optional.empty();
+			}
+		}
+
+		return Optional.of(remainingTargets.get(0));
+	}
+
+}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/PedestrianReachabilityChecker.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/PedestrianReachabilityChecker.java
new file mode 100644
index 0000000..4012a45
--- /dev/null
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/PedestrianReachabilityChecker.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2019, Google LLC.
+ * and other copyright owners as documented in the project's IP log.
+ *
+ * This program and the accompanying materials are made available
+ * under the terms of the Eclipse Distribution License v1.0 which
+ * accompanies this distribution, is reproduced below, and is
+ * available at http://www.eclipse.org/org/documents/edl-v10.php
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above
+ *   copyright notice, this list of conditions and the following
+ *   disclaimer in the documentation and/or other materials provided
+ *   with the distribution.
+ *
+ * - Neither the name of the Eclipse Foundation, Inc. nor the
+ *   names of its contributors may be used to endorse or promote
+ *   products derived from this software without specific prior
+ *   written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.eclipse.jgit.revwalk;
+
+import java.io.IOException;
+import java.util.Collection;
+import java.util.Optional;
+
+import org.eclipse.jgit.errors.IncorrectObjectTypeException;
+import org.eclipse.jgit.errors.MissingObjectException;
+
+/**
+ * Checks the reachability walking the graph from the starters towards the
+ * target.
+ *
+ * @since 5.4
+ */
+public class PedestrianReachabilityChecker implements ReachabilityChecker {
+
+	private final boolean topoSort;
+
+	private final RevWalk walk;
+
+	/**
+	 * New instance of the reachability checker using a existing walk.
+	 *
+	 * @param topoSort
+	 *            walk commits in topological order
+	 * @param walk
+	 *            RevWalk instance to reuse. Caller retains ownership.
+	 */
+	public PedestrianReachabilityChecker(boolean topoSort,
+			RevWalk walk) {
+		this.topoSort = topoSort;
+		this.walk = walk;
+	}
+
+	@Override
+	public Optional<RevCommit> areAllReachable(Collection<RevCommit> targets,
+			Collection<RevCommit> starters)
+					throws MissingObjectException, IncorrectObjectTypeException,
+					IOException {
+		walk.reset();
+		if (topoSort) {
+			walk.sort(RevSort.TOPO);
+		}
+
+		for (RevCommit target: targets) {
+			walk.markStart(target);
+		}
+
+		for (RevCommit starter : starters) {
+			walk.markUninteresting(starter);
+		}
+
+		return Optional.ofNullable(walk.next());
+	}
+}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/ReachabilityChecker.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/ReachabilityChecker.java
new file mode 100644
index 0000000..2ed06d1
--- /dev/null
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/ReachabilityChecker.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2019, Google LLC.
+ * and other copyright owners as documented in the project's IP log.
+ *
+ * This program and the accompanying materials are made available
+ * under the terms of the Eclipse Distribution License v1.0 which
+ * accompanies this distribution, is reproduced below, and is
+ * available at http://www.eclipse.org/org/documents/edl-v10.php
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above
+ *   copyright notice, this list of conditions and the following
+ *   disclaimer in the documentation and/or other materials provided
+ *   with the distribution.
+ *
+ * - Neither the name of the Eclipse Foundation, Inc. nor the
+ *   names of its contributors may be used to endorse or promote
+ *   products derived from this software without specific prior
+ *   written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.eclipse.jgit.revwalk;
+
+import java.io.IOException;
+import java.util.Collection;
+import java.util.Optional;
+
+import org.eclipse.jgit.errors.IncorrectObjectTypeException;
+import org.eclipse.jgit.errors.MissingObjectException;
+
+/**
+ * Check if a commit is reachable from a collection of starting commits.
+ * <p>
+ * Note that this checks the reachability of commits (and tags). Trees, blobs or
+ * any other object will cause IncorrectObjectTypeException exceptions.
+ *
+ * @since 5.4
+ */
+public interface ReachabilityChecker {
+
+	/**
+	 * Check if all targets are reachable from the {@code starter} commits.
+	 * <p>
+	 * Caller should parse the objectIds (preferably with
+	 * {@code walk.parseCommit()} and handle missing/incorrect type objects
+	 * before calling this method.
+	 *
+	 * @param targets
+	 *            commits to reach.
+	 * @param starters
+	 *            known starting points.
+	 * @return An unreachable target if at least one of the targets is
+	 *         unreachable. An empty optional if all targets are reachable from
+	 *         the starters.
+	 *
+	 * @throws MissingObjectException
+	 *             if any of the incoming objects doesn't exist in the
+	 *             repository.
+	 * @throws IncorrectObjectTypeException
+	 *             if any of the incoming objects is not a commit or a tag.
+	 * @throws IOException
+	 *             if any of the underlying indexes or readers can not be
+	 *             opened.
+	 */
+	Optional<RevCommit> areAllReachable(Collection<RevCommit> targets,
+			Collection<RevCommit> starters)
+			throws MissingObjectException, IncorrectObjectTypeException,
+			IOException;
+}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/Daemon.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/Daemon.java
index 7289ce7..2b27df2 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/Daemon.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/Daemon.java
@@ -115,36 +115,26 @@ public Daemon(InetSocketAddress addr) {
 
 		repositoryResolver = (RepositoryResolver<DaemonClient>) RepositoryResolver.NONE;
 
-		uploadPackFactory = new UploadPackFactory<DaemonClient>() {
-			@Override
-			public UploadPack create(DaemonClient req, Repository db)
-					throws ServiceNotEnabledException,
-					ServiceNotAuthorizedException {
-				UploadPack up = new UploadPack(db);
-				up.setTimeout(getTimeout());
-				up.setPackConfig(getPackConfig());
-				return up;
-			}
+		uploadPackFactory = (DaemonClient req, Repository db) -> {
+			UploadPack up = new UploadPack(db);
+			up.setTimeout(getTimeout());
+			up.setPackConfig(getPackConfig());
+			return up;
 		};
 
-		receivePackFactory = new ReceivePackFactory<DaemonClient>() {
-			@Override
-			public ReceivePack create(DaemonClient req, Repository db)
-					throws ServiceNotEnabledException,
-					ServiceNotAuthorizedException {
-				ReceivePack rp = new ReceivePack(db);
+		receivePackFactory = (DaemonClient req, Repository db) -> {
+			ReceivePack rp = new ReceivePack(db);
 
-				InetAddress peer = req.getRemoteAddress();
-				String host = peer.getCanonicalHostName();
-				if (host == null)
-					host = peer.getHostAddress();
-				String name = "anonymous"; //$NON-NLS-1$
-				String email = name + "@" + host; //$NON-NLS-1$
-				rp.setRefLogIdent(new PersonIdent(name, email));
-				rp.setTimeout(getTimeout());
+			InetAddress peer = req.getRemoteAddress();
+			String host = peer.getCanonicalHostName();
+			if (host == null)
+				host = peer.getHostAddress();
+			String name = "anonymous"; //$NON-NLS-1$
+			String email = name + "@" + host; //$NON-NLS-1$
+			rp.setRefLogIdent(new PersonIdent(name, email));
+			rp.setTimeout(getTimeout());
 
-				return rp;
-			}
+			return rp;
 		};
 
 		services = new DaemonService[] {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PostReceiveHook.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PostReceiveHook.java
index ba5d2f3..28a146d 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PostReceiveHook.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PostReceiveHook.java
@@ -63,12 +63,9 @@
  */
 public interface PostReceiveHook {
 	/** A simple no-op hook. */
-	PostReceiveHook NULL = new PostReceiveHook() {
-		@Override
-		public void onPostReceive(final ReceivePack rp,
-				final Collection<ReceiveCommand> commands) {
-			// Do nothing.
-		}
+	PostReceiveHook NULL = (final ReceivePack rp,
+			final Collection<ReceiveCommand> commands) -> {
+		// Do nothing.
 	};
 
 	/**
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PostUploadHook.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PostUploadHook.java
index 3aa3b12..251bfe2 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PostUploadHook.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PostUploadHook.java
@@ -57,11 +57,8 @@
  */
 public interface PostUploadHook {
 	/** A simple no-op hook. */
-	PostUploadHook NULL = new PostUploadHook() {
-		@Override
-		public void onPostUpload(PackStatistics stats) {
-			// Do nothing.
-		}
+	PostUploadHook NULL = (PackStatistics stats) -> {
+		// Do nothing.
 	};
 
 	/**
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PreReceiveHook.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PreReceiveHook.java
index 30845d3..b91756b 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PreReceiveHook.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PreReceiveHook.java
@@ -79,12 +79,9 @@
  */
 public interface PreReceiveHook {
 	/** A simple no-op hook. */
-	PreReceiveHook NULL = new PreReceiveHook() {
-		@Override
-		public void onPreReceive(final ReceivePack rp,
-				final Collection<ReceiveCommand> commands) {
-			// Do nothing.
-		}
+	PreReceiveHook NULL = (final ReceivePack rp,
+			final Collection<ReceiveCommand> commands) -> {
+		// Do nothing.
 	};
 
 	/**
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PushCertificateStore.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PushCertificateStore.java
index aeca635..14afc44 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PushCertificateStore.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PushCertificateStore.java
@@ -57,7 +57,6 @@
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
-import java.util.Comparator;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
@@ -193,81 +192,78 @@ public PushCertificate get(String refName) throws IOException {
 	 *         close resources.
 	 */
 	public Iterable<PushCertificate> getAll(String refName) {
-		return new Iterable<PushCertificate>() {
-			@Override
-			public Iterator<PushCertificate> iterator() {
-				return new Iterator<PushCertificate>() {
-					private final String path = pathName(refName);
-					private PushCertificate next;
+		return () -> new Iterator<PushCertificate>() {
+			private final String path = pathName(refName);
 
-					private RevWalk rw;
-					{
+			private PushCertificate next;
+
+			private RevWalk rw;
+			{
+				try {
+					if (reader == null) {
+						load();
+					}
+					if (commit != null) {
+						rw = new RevWalk(reader);
+						rw.setTreeFilter(AndTreeFilter.create(
+								PathFilterGroup.create(Collections
+										.singleton(PathFilter.create(path))),
+								TreeFilter.ANY_DIFF));
+						rw.setRewriteParents(false);
+						rw.markStart(rw.parseCommit(commit));
+					} else {
+						rw = null;
+					}
+				} catch (IOException e) {
+					throw new RuntimeException(e);
+				}
+			}
+
+			@Override
+			public boolean hasNext() {
+				try {
+					if (next == null) {
+						if (rw == null) {
+							return false;
+						}
 						try {
-							if (reader == null) {
-								load();
-							}
-							if (commit != null) {
-								rw = new RevWalk(reader);
-								rw.setTreeFilter(AndTreeFilter.create(
-										PathFilterGroup.create(
-											Collections.singleton(PathFilter.create(path))),
-										TreeFilter.ANY_DIFF));
-								rw.setRewriteParents(false);
-								rw.markStart(rw.parseCommit(commit));
+							RevCommit c = rw.next();
+							if (c != null) {
+								try (TreeWalk tw = TreeWalk.forPath(
+										rw.getObjectReader(), path,
+										c.getTree())) {
+									next = read(tw);
+								}
 							} else {
-								rw = null;
+								next = null;
 							}
 						} catch (IOException e) {
 							throw new RuntimeException(e);
 						}
 					}
-
-					@Override
-					public boolean hasNext() {
-						try {
-							if (next == null) {
-								if (rw == null) {
-									return false;
-								}
-								try {
-									RevCommit c = rw.next();
-									if (c != null) {
-										try (TreeWalk tw = TreeWalk.forPath(
-												rw.getObjectReader(), path, c.getTree())) {
-											next = read(tw);
-										}
-									} else {
-										next = null;
-									}
-								} catch (IOException e) {
-									throw new RuntimeException(e);
-								}
-							}
-							return next != null;
-						} finally {
-							if (next == null && rw != null) {
-								rw.close();
-								rw = null;
-							}
-						}
+					return next != null;
+				} finally {
+					if (next == null && rw != null) {
+						rw.close();
+						rw = null;
 					}
+				}
+			}
 
-					@Override
-					public PushCertificate next() {
-						hasNext();
-						PushCertificate n = next;
-						if (n == null) {
-							throw new NoSuchElementException();
-						}
-						next = null;
-						return n;
-					}
+			@Override
+			public PushCertificate next() {
+				hasNext();
+				PushCertificate n = next;
+				if (n == null) {
+					throw new NoSuchElementException();
+				}
+				next = null;
+				return n;
+			}
 
-					@Override
-					public void remove() {
-						throw new UnsupportedOperationException();
-					}
-				};
+			@Override
+			public void remove() {
+				throw new UnsupportedOperationException();
 			}
 		};
 	}
@@ -442,13 +438,8 @@ private ObjectId write() throws IOException {
 	}
 
 	private static void sortPending(List<PendingCert> pending) {
-		Collections.sort(pending, new Comparator<PendingCert>() {
-			@Override
-			public int compare(PendingCert a, PendingCert b) {
-				return Long.signum(
-						a.ident.getWhen().getTime() - b.ident.getWhen().getTime());
-			}
-		});
+		Collections.sort(pending, (PendingCert a, PendingCert b) -> Long.signum(
+				a.ident.getWhen().getTime() - b.ident.getWhen().getTime()));
 	}
 
 	private DirCache newDirCache() throws IOException {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/RefFilter.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/RefFilter.java
index d6d6198..d19c652 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/RefFilter.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/RefFilter.java
@@ -61,12 +61,7 @@ public interface RefFilter {
 	/**
 	 * The default filter, allows all refs to be shown.
 	 */
-	RefFilter DEFAULT = new RefFilter() {
-		@Override
-		public Map<String, Ref> filter (Map<String, Ref> refs) {
-			return refs;
-		}
-	};
+	RefFilter DEFAULT = (Map<String, Ref> refs) -> refs;
 
 	/**
 	 * Filters a {@code Map} of refs before it is advertised to the client.
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/SshSessionFactory.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/SshSessionFactory.java
index 005a0c2..fdb19df 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/SshSessionFactory.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/SshSessionFactory.java
@@ -100,13 +100,9 @@ public static void setInstance(SshSessionFactory newFactory) {
 	 * @since 5.2
 	 */
 	public static String getLocalUserName() {
-		return AccessController.doPrivileged(new PrivilegedAction<String>() {
-			@Override
-			public String run() {
-				return SystemReader.getInstance()
-						.getProperty(Constants.OS_USER_NAME_KEY);
-			}
-		});
+		return AccessController
+				.doPrivileged((PrivilegedAction<String>) () -> SystemReader
+						.getInstance().getProperty(Constants.OS_USER_NAME_KEY));
 	}
 
 	/**
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportLocal.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportLocal.java
index fbb2c44..f2a2b0a 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportLocal.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportLocal.java
@@ -188,12 +188,8 @@ public FetchConnection openFetch() throws TransportException {
 				&& !"git upload-pack".equals(up)) //$NON-NLS-1$
 			return new ForkLocalFetchConnection();
 
-		UploadPackFactory<Void> upf = new UploadPackFactory<Void>() {
-			@Override
-			public UploadPack create(Void req, Repository db) {
-				return createUploadPack(db);
-			}
-		};
+		UploadPackFactory<Void> upf = (Void req,
+				Repository db) -> createUploadPack(db);
 		return new InternalFetchConnection<>(this, upf, null, openRepo());
 	}
 
@@ -205,12 +201,8 @@ public PushConnection openPush() throws TransportException {
 				&& !"git receive-pack".equals(rp)) //$NON-NLS-1$
 			return new ForkLocalPushConnection();
 
-		ReceivePackFactory<Void> rpf = new ReceivePackFactory<Void>() {
-			@Override
-			public ReceivePack create(Void req, Repository db) {
-				return createReceivePack(db);
-			}
-		};
+		ReceivePackFactory<Void> rpf = (Void req,
+				Repository db) -> createReceivePack(db);
 		return new InternalPushConnection<>(this, rpf, null, openRepo());
 	}
 
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java
index 27090f4..3ed9886 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java
@@ -44,12 +44,11 @@
 package org.eclipse.jgit.transport;
 
 import static java.util.Collections.unmodifiableMap;
-import static org.eclipse.jgit.util.RefMap.toRefMap;
 import static org.eclipse.jgit.lib.Constants.R_TAGS;
 import static org.eclipse.jgit.transport.GitProtocolConstants.CAPABILITY_REF_IN_WANT;
+import static org.eclipse.jgit.transport.GitProtocolConstants.CAPABILITY_SERVER_OPTION;
 import static org.eclipse.jgit.transport.GitProtocolConstants.COMMAND_FETCH;
 import static org.eclipse.jgit.transport.GitProtocolConstants.COMMAND_LS_REFS;
-import static org.eclipse.jgit.transport.GitProtocolConstants.CAPABILITY_SERVER_OPTION;
 import static org.eclipse.jgit.transport.GitProtocolConstants.OPTION_AGENT;
 import static org.eclipse.jgit.transport.GitProtocolConstants.OPTION_ALLOW_REACHABLE_SHA1_IN_WANT;
 import static org.eclipse.jgit.transport.GitProtocolConstants.OPTION_ALLOW_TIP_SHA1_IN_WANT;
@@ -65,6 +64,7 @@
 import static org.eclipse.jgit.transport.GitProtocolConstants.OPTION_SIDE_BAND;
 import static org.eclipse.jgit.transport.GitProtocolConstants.OPTION_SIDE_BAND_64K;
 import static org.eclipse.jgit.transport.GitProtocolConstants.OPTION_THIN_PACK;
+import static org.eclipse.jgit.util.RefMap.toRefMap;
 
 import java.io.ByteArrayOutputStream;
 import java.io.EOFException;
@@ -80,8 +80,10 @@
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
+import java.util.Optional;
 import java.util.Set;
 import java.util.TreeMap;
+import java.util.stream.Collectors;
 
 import org.eclipse.jgit.annotations.NonNull;
 import org.eclipse.jgit.annotations.Nullable;
@@ -104,8 +106,11 @@
 import org.eclipse.jgit.lib.Repository;
 import org.eclipse.jgit.revwalk.AsyncRevObjectQueue;
 import org.eclipse.jgit.revwalk.BitmapWalker;
+import org.eclipse.jgit.revwalk.BitmappedReachabilityChecker;
 import org.eclipse.jgit.revwalk.DepthWalk;
 import org.eclipse.jgit.revwalk.ObjectWalk;
+import org.eclipse.jgit.revwalk.PedestrianReachabilityChecker;
+import org.eclipse.jgit.revwalk.ReachabilityChecker;
 import org.eclipse.jgit.revwalk.RevCommit;
 import org.eclipse.jgit.revwalk.RevFlag;
 import org.eclipse.jgit.revwalk.RevFlagSet;
@@ -1867,59 +1872,89 @@ private static void checkNotAdvertisedWantsUsingBitmap(ObjectReader reader,
 
 	private static void checkNotAdvertisedWants(UploadPack up,
 			List<ObjectId> notAdvertisedWants, Set<ObjectId> reachableFrom)
-			throws MissingObjectException, IncorrectObjectTypeException, IOException {
-		// Walk the requested commits back to the provided set of commits. If any
-		// commit exists, a branch was deleted or rewound and the repository owner
-		// no longer exports that requested item. If the requested commit is merged
-		// into an advertised branch it will be marked UNINTERESTING and no commits
-		// return.
+			throws IOException {
 
 		ObjectReader reader = up.getRevWalk().getObjectReader();
 		try (RevWalk walk = new RevWalk(reader)) {
 			walk.setRetainBody(false);
-			AsyncRevObjectQueue q = walk.parseAny(notAdvertisedWants, true);
-			try {
-				RevObject obj;
-				while ((obj = q.next()) != null) {
-					if (!(obj instanceof RevCommit)) {
-						// If unadvertized non-commits are requested, use
-						// bitmaps. If there are no bitmaps, instead of
-						// incurring the expense of a manual walk, reject
-						// the request.
-						BitmapIndex bitmapIndex = reader.getBitmapIndex();
-						if (bitmapIndex != null) {
-							checkNotAdvertisedWantsUsingBitmap(
-									reader,
-									bitmapIndex,
-									notAdvertisedWants,
-									reachableFrom);
-							return;
-						}
-						throw new WantNotValidException(obj);
-					}
-					walk.markStart((RevCommit) obj);
+			// Missing "wants" throw exception here
+			List<RevObject> wantsAsObjs = objectIdsToRevObjects(walk,
+					notAdvertisedWants);
+			List<RevCommit> wantsAsCommits = wantsAsObjs.stream()
+					.filter(obj -> obj instanceof RevCommit)
+					.map(obj -> (RevCommit) obj)
+					.collect(Collectors.toList());
+			boolean allWantsAreCommits = wantsAsObjs.size() == wantsAsCommits
+					.size();
+			boolean repoHasBitmaps = reader.getBitmapIndex() != null;
+
+			if (!allWantsAreCommits) {
+				if (!repoHasBitmaps) {
+					// If unadvertized non-commits are requested, use
+					// bitmaps. If there are no bitmaps, instead of
+					// incurring the expense of a manual walk, reject
+					// the request.
+					RevObject nonCommit = wantsAsObjs
+							.stream()
+							.filter(obj -> !(obj instanceof RevCommit))
+							.limit(1)
+							.collect(Collectors.toList()).get(0);
+					throw new WantNotValidException(nonCommit);
+
 				}
-			} catch (MissingObjectException notFound) {
-				throw new WantNotValidException(notFound.getObjectId(),
-						notFound);
-			} finally {
-				q.release();
-			}
-			for (ObjectId id : reachableFrom) {
-				try {
-					walk.markUninteresting(walk.parseCommit(id));
-				} catch (IncorrectObjectTypeException notCommit) {
-					continue;
-				}
+				checkNotAdvertisedWantsUsingBitmap(reader,
+						reader.getBitmapIndex(), notAdvertisedWants,
+						reachableFrom);
+				return;
 			}
 
-			RevCommit bad = walk.next();
-			if (bad != null) {
-				throw new WantNotValidException(bad);
+			// All wants are commits, we can use ReachabilityChecker
+			ReachabilityChecker reachabilityChecker = repoHasBitmaps
+					? new BitmappedReachabilityChecker(walk)
+					: new PedestrianReachabilityChecker(true, walk);
+
+			List<RevCommit> starters = objectIdsToRevCommits(walk,
+					reachableFrom);
+			Optional<RevCommit> unreachable = reachabilityChecker
+					.areAllReachable(wantsAsCommits, starters);
+			if (unreachable.isPresent()) {
+				throw new WantNotValidException(unreachable.get());
 			}
+
+		} catch (MissingObjectException notFound) {
+			throw new WantNotValidException(notFound.getObjectId(), notFound);
 		}
 	}
 
+	// Resolve the ObjectIds into RevObjects. Any missing object raises an
+	// exception
+	private static List<RevObject> objectIdsToRevObjects(RevWalk walk,
+			Iterable<ObjectId> objectIds)
+			throws MissingObjectException, IOException {
+		List<RevObject> result = new ArrayList<>();
+		for (ObjectId objectId : objectIds) {
+			result.add(walk.parseAny(objectId));
+		}
+		return result;
+	}
+
+	// Get commits from object ids. If the id is not a commit, ignore it. If the
+	// id doesn't exist, report the missing object in a exception.
+	private static List<RevCommit> objectIdsToRevCommits(RevWalk walk,
+			Iterable<ObjectId> objectIds)
+			throws MissingObjectException, IOException {
+		List<RevCommit> result = new ArrayList<>();
+		for (ObjectId objectId : objectIds) {
+			try {
+				result.add(walk.parseCommit(objectId));
+			} catch (IncorrectObjectTypeException e) {
+				continue;
+			}
+		}
+		return result;
+	}
+
+
 	private void addCommonBase(RevObject o) {
 		if (!o.has(COMMON)) {
 			o.add(COMMON);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/resolver/ReceivePackFactory.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/resolver/ReceivePackFactory.java
index b850d1e..5d36e58 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/resolver/ReceivePackFactory.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/resolver/ReceivePackFactory.java
@@ -57,12 +57,8 @@ public interface ReceivePackFactory<C> {
 	/**
 	 * A factory disabling the ReceivePack service for all repositories
 	 */
-	ReceivePackFactory<?> DISABLED = new ReceivePackFactory<Object>() {
-		@Override
-		public ReceivePack create(Object req, Repository db)
-				throws ServiceNotEnabledException {
-			throw new ServiceNotEnabledException();
-		}
+	ReceivePackFactory<?> DISABLED = (Object req, Repository db) -> {
+		throw new ServiceNotEnabledException();
 	};
 
 	/**
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/resolver/RepositoryResolver.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/resolver/RepositoryResolver.java
index 4816f21..dd24b7a 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/resolver/RepositoryResolver.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/resolver/RepositoryResolver.java
@@ -57,12 +57,8 @@ public interface RepositoryResolver<C> {
 	/**
 	 * Resolver configured to open nothing.
 	 */
-	RepositoryResolver<?> NONE = new RepositoryResolver<Object>() {
-		@Override
-		public Repository open(Object req, String name)
-				throws RepositoryNotFoundException {
-			throw new RepositoryNotFoundException(name);
-		}
+	RepositoryResolver<?> NONE = (Object req, String name) -> {
+		throw new RepositoryNotFoundException(name);
 	};
 
 	/**
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/resolver/UploadPackFactory.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/resolver/UploadPackFactory.java
index bb43b13..b8673f5 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/resolver/UploadPackFactory.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/resolver/UploadPackFactory.java
@@ -57,12 +57,8 @@ public interface UploadPackFactory<C> {
 	/**
 	 * A factory disabling the UploadPack service for all repositories.
 	 */
-	UploadPackFactory<?> DISABLED = new UploadPackFactory<Object>() {
-		@Override
-		public UploadPack create(Object req, Repository db)
-				throws ServiceNotEnabledException {
-			throw new ServiceNotEnabledException();
-		}
+	UploadPackFactory<?> DISABLED = (Object req, Repository db) -> {
+		throw new ServiceNotEnabledException();
 	};
 
 	/**
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/WorkingTreeIterator.java b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/WorkingTreeIterator.java
index b768acd..c0c2487 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/WorkingTreeIterator.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/WorkingTreeIterator.java
@@ -774,14 +774,10 @@ public AttributesNode getEntryAttributesNode() throws IOException {
 		return attributesNode;
 	}
 
-	private static final Comparator<Entry> ENTRY_CMP = new Comparator<Entry>() {
-		@Override
-		public int compare(Entry a, Entry b) {
-			return Paths.compare(
-					a.encodedName, 0, a.encodedNameLen, a.getMode().getBits(),
-					b.encodedName, 0, b.encodedNameLen, b.getMode().getBits());
-		}
-	};
+	private static final Comparator<Entry> ENTRY_CMP = (Entry a,
+			Entry b) -> Paths.compare(a.encodedName, 0, a.encodedNameLen,
+					a.getMode().getBits(), b.encodedName, 0, b.encodedNameLen,
+					b.getMode().getBits());
 
 	/**
 	 * Constructor helper.
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java
index 536e4f1..5368502 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java
@@ -463,13 +463,9 @@ public BasicFileAttributes fileAttributes(File file) throws IOException {
 	 * @return the user's home directory; null if the user does not have one.
 	 */
 	protected File userHomeImpl() {
-		final String home = AccessController
-				.doPrivileged(new PrivilegedAction<String>() {
-					@Override
-					public String run() {
-						return System.getProperty("user.home"); //$NON-NLS-1$
-					}
-				});
+		final String home = AccessController.doPrivileged(
+				(PrivilegedAction<String>) () -> System.getProperty("user.home") //$NON-NLS-1$
+		);
 		if (home == null || home.length() == 0)
 			return null;
 		return new File(home).getAbsoluteFile();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_Win32_Cygwin.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_Win32_Cygwin.java
index e5c8d9d..9a163e8 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_Win32_Cygwin.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_Win32_Cygwin.java
@@ -80,12 +80,9 @@ public class FS_Win32_Cygwin extends FS_Win32 {
 	 */
 	public static boolean isCygwin() {
 		final String path = AccessController
-				.doPrivileged(new PrivilegedAction<String>() {
-					@Override
-					public String run() {
-						return System.getProperty("java.library.path"); //$NON-NLS-1$
-					}
-				});
+				.doPrivileged((PrivilegedAction<String>) () -> System
+						.getProperty("java.library.path") //$NON-NLS-1$
+				);
 		if (path == null)
 			return false;
 		File found = FS.searchPath(path, "cygpath.exe"); //$NON-NLS-1$
@@ -141,13 +138,9 @@ public File resolve(File dir, String pn) {
 	/** {@inheritDoc} */
 	@Override
 	protected File userHomeImpl() {
-		final String home = AccessController
-				.doPrivileged(new PrivilegedAction<String>() {
-					@Override
-					public String run() {
-						return System.getenv("HOME"); //$NON-NLS-1$
-					}
-				});
+		final String home = AccessController.doPrivileged(
+				(PrivilegedAction<String>) () -> System.getenv("HOME") //$NON-NLS-1$
+		);
 		if (home == null || home.length() == 0)
 			return super.userHomeImpl();
 		return resolve(new File("."), home); //$NON-NLS-1$
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/SystemReader.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/SystemReader.java
index 953c976..5feacff 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/SystemReader.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/SystemReader.java
@@ -368,12 +368,9 @@ public boolean isMacOS() {
 	}
 
 	private String getOsName() {
-		return AccessController.doPrivileged(new PrivilegedAction<String>() {
-			@Override
-			public String run() {
-				return getProperty("os.name"); //$NON-NLS-1$
-			}
-		});
+		return AccessController.doPrivileged(
+				(PrivilegedAction<String>) () -> getProperty("os.name") //$NON-NLS-1$
+		);
 	}
 
 	/**
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/io/IsolatedOutputStream.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/io/IsolatedOutputStream.java
index 8ea8723..18de705 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/io/IsolatedOutputStream.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/io/IsolatedOutputStream.java
@@ -102,12 +102,9 @@ public void write(int ch) throws IOException {
 	public void write(byte[] buf, int pos, int cnt)
 			throws IOException {
 		checkClosed();
-		execute(new Callable<Void>() {
-			@Override
-			public Void call() throws IOException {
-				dst.write(buf, pos, cnt);
-				return null;
-			}
+		execute(() -> {
+			dst.write(buf, pos, cnt);
+			return null;
 		});
 	}
 
@@ -115,12 +112,9 @@ public Void call() throws IOException {
 	@Override
 	public void flush() throws IOException {
 		checkClosed();
-		execute(new Callable<Void>() {
-			@Override
-			public Void call() throws IOException {
-				dst.flush();
-				return null;
-			}
+		execute(() -> {
+			dst.flush();
+			return null;
 		});
 	}
 
@@ -159,12 +153,9 @@ private boolean tryCleanClose() {
 	}
 
 	private void cleanClose() throws IOException {
-		execute(new Callable<Void>() {
-			@Override
-			public Void call() throws IOException {
-				dst.close();
-				return null;
-			}
+		execute(() -> {
+			dst.close();
+			return null;
 		});
 	}
 
@@ -178,12 +169,9 @@ private void dirtyClose() throws IOException {
 
 		Future<Void> close;
 		try {
-			close = copier.submit(new Callable<Void>() {
-				@Override
-				public Void call() throws IOException {
-					dst.close();
-					return null;
-				}
+			close = copier.submit(() -> {
+				dst.close();
+				return null;
 			});
 		} catch (RejectedExecutionException e) {
 			throw new IOException(e);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/io/ThrowingPrintWriter.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/io/ThrowingPrintWriter.java
index caabcef..9431aaf 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/io/ThrowingPrintWriter.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/io/ThrowingPrintWriter.java
@@ -68,12 +68,10 @@ public class ThrowingPrintWriter extends Writer {
 	 */
 	public ThrowingPrintWriter(Writer out) {
 		this.out = out;
-		LF = AccessController.doPrivileged(new PrivilegedAction<String>() {
-			@Override
-			public String run() {
-				return SystemReader.getInstance().getProperty("line.separator"); //$NON-NLS-1$
-			}
-		});
+		LF = AccessController
+				.doPrivileged((PrivilegedAction<String>) () -> SystemReader
+						.getInstance().getProperty("line.separator") //$NON-NLS-1$
+				);
 	}
 
 	/** {@inheritDoc} */