Merge "Allow deletion of HEAD ref if the repository is bare."
diff --git a/.buckconfig b/.buckconfig
index b2e07ac..8d2572b 100644
--- a/.buckconfig
+++ b/.buckconfig
@@ -1,3 +1,12 @@
+[alias]
+  all = //:all
+  jgit = //org.eclipse.jgit:jgit
+  jgit-archive = //org.eclipse.jgit.archive:jgit-archive
+  jgit_bin = //:jgit_bin
+  jgit-lfs = //org.eclipse.jgit.lfs:jgit-lfs
+  jgit-lfs-server = //org.eclipse.jgit.lfs.server:jgit-lfs-server
+  jgit-servlet = //org.eclipse.jgit.http.server:jgit-servlet
+
 [buildfile]
   includes = //tools/default.defs
 
diff --git a/.buckversion b/.buckversion
index 9daac2c..561a769 100644
--- a/.buckversion
+++ b/.buckversion
@@ -1 +1 @@
-1b03b4313b91b634bd604fc3487a05f877e59dee
+ca8d6cbac373a690f543c5159eec0116e76187a9
diff --git a/.mailmap b/.mailmap
index 8701b19..8f11a1c 100644
--- a/.mailmap
+++ b/.mailmap
@@ -1,5 +1,6 @@
-Shawn Pearce <spearce@spearce.org>	Shawn O. Pearce <sop@google.com>
-Shawn Pearce <spearce@spearce.org>	Shawn Pearce <sop@google.com>
-Shawn Pearce <spearce@spearce.org>	Shawn O. Pearce <spearce@spearce.org>
-Saša Živkov <sasa.zivkov@sap.com>	Sasa Zivkov <sasa.zivkov@sap.com>
-Saša Živkov <sasa.zivkov@sap.com>	Saša Živkov <zivkov@gmail.com>
+Roberto Tyley <roberto.tyley@guardian.co.uk> roberto <roberto.tyley@guardian.co.uk>
+Saša Živkov <sasa.zivkov@sap.com>            Sasa Zivkov <sasa.zivkov@sap.com>
+Saša Živkov <sasa.zivkov@sap.com>            Saša Živkov <zivkov@gmail.com>
+Shawn Pearce <spearce@spearce.org>           Shawn O. Pearce <sop@google.com>
+Shawn Pearce <spearce@spearce.org>           Shawn Pearce <sop@google.com>
+Shawn Pearce <spearce@spearce.org>           Shawn O. Pearce <spearce@spearce.org>
diff --git a/BUCK b/BUCK
index f19b7bd..4578e17 100644
--- a/BUCK
+++ b/BUCK
@@ -1,45 +1,18 @@
-java_library(
-  name = 'jgit',
-  exported_deps = ['//org.eclipse.jgit:jgit'],
-  visibility = ['PUBLIC'],
+DEPS = [
+  '//org.eclipse.jgit:jgit',
+  '//org.eclipse.jgit.archive:jgit-archive',
+  '//org.eclipse.jgit.http.server:jgit-servlet',
+  '//org.eclipse.jgit.lfs:jgit-lfs',
+  '//org.eclipse.jgit.lfs.server:jgit-lfs-server',
+  '//org.eclipse.jgit.pgm:jgit',
+]
+
+zip_file(
+  name = 'all',
+  srcs = DEPS,
 )
 
-genrule(
-  name = 'jgit_src',
-  cmd = 'ln -s $(location //org.eclipse.jgit:jgit_src) $OUT',
-  out = 'jgit_src.zip',
-  visibility = ['PUBLIC'],
-)
-
-java_library(
-  name = 'jgit-servlet',
-  exported_deps = [
-    ':jgit',
-    '//org.eclipse.jgit.http.server:jgit-servlet'
-  ],
-  visibility = ['PUBLIC'],
-)
-
-java_library(
-  name = 'jgit-archive',
-  exported_deps = [
-    ':jgit',
-    '//org.eclipse.jgit.archive:jgit-archive'
-  ],
-  visibility = ['PUBLIC'],
-)
-
-java_library(
-  name = 'junit',
-  exported_deps = [
-    ':jgit',
-    '//org.eclipse.jgit.junit:junit'
-  ],
-  visibility = ['PUBLIC'],
-)
-
-genrule(
+sh_binary(
   name = 'jgit_bin',
-  cmd = 'ln -s $(location //org.eclipse.jgit.pgm:jgit) $OUT',
-  out = 'jgit_bin',
+  main = '//org.eclipse.jgit.pgm:jgit',
 )
diff --git a/lib/BUCK b/lib/BUCK
index 524612b..2421b40 100644
--- a/lib/BUCK
+++ b/lib/BUCK
@@ -123,3 +123,12 @@
   artifact = 'hamcrest-core',
   version = '1.3',
 )
+
+maven_jar(
+  name = 'gson',
+  bin_sha1 = 'a60a5e993c98c864010053cb901b7eab25306568',
+  src_sha1 = 'a6dc5db8a12928e583bd3f23e72d3ab611ecd58f',
+  group = 'com.google.code.gson',
+  artifact = 'gson',
+  version = '2.2.4',
+)
diff --git a/org.eclipse.jgit.http.apache/BUCK b/org.eclipse.jgit.http.apache/BUCK
index f48f33a..3b7a823 100644
--- a/org.eclipse.jgit.http.apache/BUCK
+++ b/org.eclipse.jgit.http.apache/BUCK
@@ -4,7 +4,6 @@
   resources = glob(['resources/**']),
   deps = [
     '//org.eclipse.jgit:jgit',
-    '//lib:commons-logging',
     '//lib:httpcomponents',
     '//lib:httpcore',
   ],
diff --git a/org.eclipse.jgit.http.apache/META-INF/MANIFEST.MF b/org.eclipse.jgit.http.apache/META-INF/MANIFEST.MF
index 9871622..2616526 100644
--- a/org.eclipse.jgit.http.apache/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.http.apache/META-INF/MANIFEST.MF
@@ -7,8 +7,7 @@
 Bundle-Localization: plugin
 Bundle-Vendor: %Provider-Name
 Bundle-ActivationPolicy: lazy
-Import-Package: org.apache.commons.logging;version="[1.1.1,2.0.0)",
- org.apache.http;version="[4.1.0,5.0.0)",
+Import-Package: org.apache.http;version="[4.1.0,5.0.0)",
  org.apache.http.client;version="[4.1.0,5.0.0)",
  org.apache.http.client.methods;version="[4.1.0,5.0.0)",
  org.apache.http.client.params;version="[4.1.0,5.0.0)",
diff --git a/org.eclipse.jgit.http.apache/src/org/eclipse/jgit/transport/http/apache/HttpClientConnection.java b/org.eclipse.jgit.http.apache/src/org/eclipse/jgit/transport/http/apache/HttpClientConnection.java
index de81bf8..a0eeef8 100644
--- a/org.eclipse.jgit.http.apache/src/org/eclipse/jgit/transport/http/apache/HttpClientConnection.java
+++ b/org.eclipse.jgit.http.apache/src/org/eclipse/jgit/transport/http/apache/HttpClientConnection.java
@@ -42,6 +42,11 @@
  */
 package org.eclipse.jgit.transport.http.apache;
 
+import static org.eclipse.jgit.util.HttpSupport.METHOD_GET;
+import static org.eclipse.jgit.util.HttpSupport.METHOD_HEAD;
+import static org.eclipse.jgit.util.HttpSupport.METHOD_POST;
+import static org.eclipse.jgit.util.HttpSupport.METHOD_PUT;
+
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
@@ -76,6 +81,7 @@
 import org.apache.http.client.ClientProtocolException;
 import org.apache.http.client.HttpClient;
 import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpHead;
 import org.apache.http.client.methods.HttpPost;
 import org.apache.http.client.methods.HttpPut;
 import org.apache.http.client.methods.HttpUriRequest;
@@ -250,13 +256,15 @@ public void setRequestProperty(String name, String value) {
 
 	public void setRequestMethod(String method) throws ProtocolException {
 		this.method = method;
-		if ("GET".equalsIgnoreCase(method)) //$NON-NLS-1$
+		if (METHOD_GET.equalsIgnoreCase(method)) {
 			req = new HttpGet(url.toString());
-		else if ("PUT".equalsIgnoreCase(method)) //$NON-NLS-1$
+		} else if (METHOD_HEAD.equalsIgnoreCase(method)) {
+			req = new HttpHead(url.toString());
+		} else if (METHOD_PUT.equalsIgnoreCase(method)) {
 			req = new HttpPut(url.toString());
-		else if ("POST".equalsIgnoreCase(method)) //$NON-NLS-1$
+		} else if (METHOD_POST.equalsIgnoreCase(method)) {
 			req = new HttpPost(url.toString());
-		else {
+		} else {
 			this.method = null;
 			throw new UnsupportedOperationException();
 		}
diff --git a/org.eclipse.jgit.http.test/BUCK b/org.eclipse.jgit.http.test/BUCK
index d2ced7a..d65cdad 100644
--- a/org.eclipse.jgit.http.test/BUCK
+++ b/org.eclipse.jgit.http.test/BUCK
@@ -23,6 +23,7 @@
       '//lib/jetty:servlet',
       '//lib/jetty:security',
       '//lib/jetty:util',
+      '//lib:commons-logging',
     ],
     source_under_test = ['//org.eclipse.jgit.http.server:jgit-servlet'],
   )
diff --git a/org.eclipse.jgit.junit.http/src/org/eclipse/jgit/junit/http/AppServer.java b/org.eclipse.jgit.junit.http/src/org/eclipse/jgit/junit/http/AppServer.java
index ce04bdf..c36c297 100644
--- a/org.eclipse.jgit.junit.http/src/org/eclipse/jgit/junit/http/AppServer.java
+++ b/org.eclipse.jgit.junit.http/src/org/eclipse/jgit/junit/http/AppServer.java
@@ -104,6 +104,15 @@ public class AppServer {
 	private final TestRequestLog log;
 
 	public AppServer() {
+		this(0);
+	}
+
+	/**
+	 * @param port
+	 *            the http port number
+	 * @since 4.2
+	 */
+	public AppServer(int port) {
 		server = new Server();
 
 		HttpConfiguration http_config = new HttpConfiguration();
@@ -113,7 +122,7 @@ public AppServer() {
 
 		connector = new ServerConnector(server,
 				new HttpConnectionFactory(http_config));
-		connector.setPort(0);
+		connector.setPort(port);
 		try {
 			final InetAddress me = InetAddress.getByName("localhost");
 			connector.setHost(me.getHostAddress());
diff --git a/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/RepositoryTestCase.java b/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/RepositoryTestCase.java
index c649eb9..0db71f7 100644
--- a/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/RepositoryTestCase.java
+++ b/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/RepositoryTestCase.java
@@ -401,8 +401,7 @@ protected File writeTrashFiles(boolean ensureDistinctTimestamps,
 	 * @return the created commit
 	 */
 	protected RevCommit commitFile(String filename, String contents, String branch) {
-		try {
-			Git git = new Git(db);
+		try (Git git = new Git(db)) {
 			Repository repo = git.getRepository();
 			String originalBranch = repo.getFullBranch();
 			boolean empty = repo.resolve(Constants.HEAD) == null;
@@ -443,8 +442,10 @@ protected DirCacheEntry createEntry(final String path, final FileMode mode,
 			final int stage, final String content) {
 		final DirCacheEntry entry = new DirCacheEntry(path, stage);
 		entry.setFileMode(mode);
-		entry.setObjectId(new ObjectInserter.Formatter().idFor(
-				Constants.OBJ_BLOB, Constants.encode(content)));
+		try (ObjectInserter.Formatter formatter = new ObjectInserter.Formatter()) {
+			entry.setObjectId(formatter.idFor(
+					Constants.OBJ_BLOB, Constants.encode(content)));
+		}
 		return entry;
 	}
 
diff --git a/org.eclipse.jgit.lfs.server.test/.classpath b/org.eclipse.jgit.lfs.server.test/.classpath
new file mode 100644
index 0000000..2fdcc94
--- /dev/null
+++ b/org.eclipse.jgit.lfs.server.test/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="src" path="tst"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/org.eclipse.jgit.lfs.server.test/.gitignore b/org.eclipse.jgit.lfs.server.test/.gitignore
new file mode 100644
index 0000000..4dc0091
--- /dev/null
+++ b/org.eclipse.jgit.lfs.server.test/.gitignore
@@ -0,0 +1,2 @@
+/target
+/bin
diff --git a/org.eclipse.jgit.lfs.server.test/.project b/org.eclipse.jgit.lfs.server.test/.project
new file mode 100644
index 0000000..e3a4748
--- /dev/null
+++ b/org.eclipse.jgit.lfs.server.test/.project
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.jgit.lfs.server.test</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ManifestBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.SchemaBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.api.tools.apiAnalysisBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.PluginNature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>org.eclipse.pde.api.tools.apiAnalysisNature</nature>
+	</natures>
+</projectDescription>
diff --git a/org.eclipse.jgit.lfs.server.test/.settings/org.eclipse.core.resources.prefs b/org.eclipse.jgit.lfs.server.test/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 0000000..4824b80
--- /dev/null
+++ b/org.eclipse.jgit.lfs.server.test/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1

+encoding/<project>=UTF-8

diff --git a/org.eclipse.jgit.lfs.server.test/.settings/org.eclipse.core.runtime.prefs b/org.eclipse.jgit.lfs.server.test/.settings/org.eclipse.core.runtime.prefs
new file mode 100644
index 0000000..5a0ad22
--- /dev/null
+++ b/org.eclipse.jgit.lfs.server.test/.settings/org.eclipse.core.runtime.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+line.separator=\n
diff --git a/org.eclipse.jgit.lfs.server.test/.settings/org.eclipse.jdt.core.prefs b/org.eclipse.jgit.lfs.server.test/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..dcc0d3a
--- /dev/null
+++ b/org.eclipse.jgit.lfs.server.test/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,398 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.annotation.inheritNullAnnotations=disabled
+org.eclipse.jdt.core.compiler.annotation.missingNonNullByDefaultAnnotation=ignore
+org.eclipse.jdt.core.compiler.annotation.nonnull=org.eclipse.jdt.annotation.NonNull
+org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=org.eclipse.jdt.annotation.NonNullByDefault
+org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nullable
+org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.7
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.doc.comment.support=enabled
+org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.autoboxing=warning
+org.eclipse.jdt.core.compiler.problem.comparingIdentical=error
+org.eclipse.jdt.core.compiler.problem.deadCode=error
+org.eclipse.jdt.core.compiler.problem.deprecation=warning
+org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
+org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
+org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
+org.eclipse.jdt.core.compiler.problem.emptyStatement=warning
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=ignore
+org.eclipse.jdt.core.compiler.problem.fallthroughCase=warning
+org.eclipse.jdt.core.compiler.problem.fatalOptionalError=disabled
+org.eclipse.jdt.core.compiler.problem.fieldHiding=warning
+org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
+org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=error
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=error
+org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=error
+org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=enabled
+org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
+org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=warning
+org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=error
+org.eclipse.jdt.core.compiler.problem.invalidJavadoc=error
+org.eclipse.jdt.core.compiler.problem.invalidJavadocTags=enabled
+org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsDeprecatedRef=enabled
+org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsNotVisibleRef=enabled
+org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsVisibility=private
+org.eclipse.jdt.core.compiler.problem.localVariableHiding=warning
+org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=error
+org.eclipse.jdt.core.compiler.problem.missingDefaultCase=ignore
+org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore
+org.eclipse.jdt.core.compiler.problem.missingEnumCaseDespiteDefault=disabled
+org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=error
+org.eclipse.jdt.core.compiler.problem.missingJavadocComments=ignore
+org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsVisibility=protected
+org.eclipse.jdt.core.compiler.problem.missingJavadocTagDescription=return_tag
+org.eclipse.jdt.core.compiler.problem.missingJavadocTags=error
+org.eclipse.jdt.core.compiler.problem.missingJavadocTagsMethodTypeParameters=disabled
+org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility=private
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled
+org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
+org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore
+org.eclipse.jdt.core.compiler.problem.noEffectAssignment=error
+org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=error
+org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore
+org.eclipse.jdt.core.compiler.problem.nonnullParameterAnnotationDropped=warning
+org.eclipse.jdt.core.compiler.problem.nullAnnotationInferenceConflict=error
+org.eclipse.jdt.core.compiler.problem.nullReference=error
+org.eclipse.jdt.core.compiler.problem.nullSpecViolation=error
+org.eclipse.jdt.core.compiler.problem.nullUncheckedConversion=warning
+org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
+org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=error
+org.eclipse.jdt.core.compiler.problem.potentialNullReference=warning
+org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable=ignore
+org.eclipse.jdt.core.compiler.problem.rawTypeReference=ignore
+org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning
+org.eclipse.jdt.core.compiler.problem.redundantNullCheck=warning
+org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore
+org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=error
+org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore
+org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore
+org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
+org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=error
+org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled
+org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
+org.eclipse.jdt.core.compiler.problem.syntacticNullAnalysisForFields=disabled
+org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
+org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
+org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=enabled
+org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
+org.eclipse.jdt.core.compiler.problem.unclosedCloseable=warning
+org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=warning
+org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
+org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=error
+org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=error
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.unusedImport=error
+org.eclipse.jdt.core.compiler.problem.unusedLabel=error
+org.eclipse.jdt.core.compiler.problem.unusedLocal=error
+org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=warning
+org.eclipse.jdt.core.compiler.problem.unusedParameter=warning
+org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
+org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=error
+org.eclipse.jdt.core.compiler.problem.unusedTypeParameter=ignore
+org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=error
+org.eclipse.jdt.core.compiler.source=1.7
+org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_assignment=0
+org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_compact_if=16
+org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80
+org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0
+org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16
+org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0
+org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16
+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80
+org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16
+org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=16
+org.eclipse.jdt.core.formatter.blank_lines_after_imports=1
+org.eclipse.jdt.core.formatter.blank_lines_after_package=1
+org.eclipse.jdt.core.formatter.blank_lines_before_field=1
+org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0
+org.eclipse.jdt.core.formatter.blank_lines_before_imports=1
+org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1
+org.eclipse.jdt.core.formatter.blank_lines_before_method=1
+org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1
+org.eclipse.jdt.core.formatter.blank_lines_before_package=0
+org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1
+org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1
+org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines=false
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false
+org.eclipse.jdt.core.formatter.comment.format_block_comments=true
+org.eclipse.jdt.core.formatter.comment.format_comments=true
+org.eclipse.jdt.core.formatter.comment.format_header=false
+org.eclipse.jdt.core.formatter.comment.format_html=true
+org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true
+org.eclipse.jdt.core.formatter.comment.format_line_comments=true
+org.eclipse.jdt.core.formatter.comment.format_source_code=true
+org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true
+org.eclipse.jdt.core.formatter.comment.indent_root_tags=true
+org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert
+org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert
+org.eclipse.jdt.core.formatter.comment.line_length=80
+org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true
+org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true
+org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=false
+org.eclipse.jdt.core.formatter.compact_else_if=true
+org.eclipse.jdt.core.formatter.continuation_indentation=2
+org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2
+org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off
+org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on
+org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false
+org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true
+org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true
+org.eclipse.jdt.core.formatter.indent_empty_lines=false
+org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true
+org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true
+org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true
+org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false
+org.eclipse.jdt.core.formatter.indentation.size=4
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_member=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert
+org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert
+org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert
+org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert
+org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert
+org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert
+org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.join_lines_in_comments=true
+org.eclipse.jdt.core.formatter.join_wrapped_lines=true
+org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false
+org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false
+org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false
+org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false
+org.eclipse.jdt.core.formatter.lineSplit=80
+org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false
+org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false
+org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0
+org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1
+org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true
+org.eclipse.jdt.core.formatter.tabulation.char=tab
+org.eclipse.jdt.core.formatter.tabulation.size=4
+org.eclipse.jdt.core.formatter.use_on_off_tags=true
+org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false
+org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true
+org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true
+org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true
diff --git a/org.eclipse.jgit.lfs.server.test/.settings/org.eclipse.jdt.ui.prefs b/org.eclipse.jgit.lfs.server.test/.settings/org.eclipse.jdt.ui.prefs
new file mode 100644
index 0000000..c336cce
--- /dev/null
+++ b/org.eclipse.jgit.lfs.server.test/.settings/org.eclipse.jdt.ui.prefs
@@ -0,0 +1,61 @@
+eclipse.preferences.version=1
+editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
+formatter_profile=_JGit Format
+formatter_settings_version=12
+org.eclipse.jdt.ui.ignorelowercasenames=true
+org.eclipse.jdt.ui.importorder=java;javax;org;com;
+org.eclipse.jdt.ui.ondemandthreshold=99
+org.eclipse.jdt.ui.staticondemandthreshold=99
+org.eclipse.jdt.ui.text.custom_code_templates=<?xml version\="1.0" encoding\="UTF-8"?><templates/>
+sp_cleanup.add_default_serial_version_id=true
+sp_cleanup.add_generated_serial_version_id=false
+sp_cleanup.add_missing_annotations=false
+sp_cleanup.add_missing_deprecated_annotations=true
+sp_cleanup.add_missing_methods=false
+sp_cleanup.add_missing_nls_tags=false
+sp_cleanup.add_missing_override_annotations=true
+sp_cleanup.add_missing_override_annotations_interface_methods=false
+sp_cleanup.add_serial_version_id=false
+sp_cleanup.always_use_blocks=true
+sp_cleanup.always_use_parentheses_in_expressions=false
+sp_cleanup.always_use_this_for_non_static_field_access=false
+sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.correct_indentation=false
+sp_cleanup.format_source_code=true
+sp_cleanup.format_source_code_changes_only=true
+sp_cleanup.make_local_variable_final=false
+sp_cleanup.make_parameters_final=false
+sp_cleanup.make_private_fields_final=true
+sp_cleanup.make_type_abstract_if_missing_method=false
+sp_cleanup.make_variable_declarations_final=false
+sp_cleanup.never_use_blocks=false
+sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.organize_imports=false
+sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
+sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
+sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
+sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
+sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_trailing_whitespaces=true
+sp_cleanup.remove_trailing_whitespaces_all=true
+sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_casts=false
+sp_cleanup.remove_unnecessary_nls_tags=false
+sp_cleanup.remove_unused_imports=false
+sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_private_fields=true
+sp_cleanup.remove_unused_private_members=false
+sp_cleanup.remove_unused_private_methods=true
+sp_cleanup.remove_unused_private_types=true
+sp_cleanup.sort_members=false
+sp_cleanup.sort_members_all=false
+sp_cleanup.use_blocks=false
+sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_this_for_non_static_field_access=false
+sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
+sp_cleanup.use_this_for_non_static_method_access=false
+sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
diff --git a/org.eclipse.jgit.lfs.server.test/.settings/org.eclipse.mylyn.tasks.ui.prefs b/org.eclipse.jgit.lfs.server.test/.settings/org.eclipse.mylyn.tasks.ui.prefs
new file mode 100644
index 0000000..3dec4d9
--- /dev/null
+++ b/org.eclipse.jgit.lfs.server.test/.settings/org.eclipse.mylyn.tasks.ui.prefs
@@ -0,0 +1,3 @@
+eclipse.preferences.version=1
+project.repository.kind=bugzilla
+project.repository.url=https\://bugs.eclipse.org/bugs
diff --git a/org.eclipse.jgit.lfs.server.test/.settings/org.eclipse.mylyn.team.ui.prefs b/org.eclipse.jgit.lfs.server.test/.settings/org.eclipse.mylyn.team.ui.prefs
new file mode 100644
index 0000000..ce7a0f0
--- /dev/null
+++ b/org.eclipse.jgit.lfs.server.test/.settings/org.eclipse.mylyn.team.ui.prefs
@@ -0,0 +1,2 @@
+commit.comment.template=${task.description} \n\nBug\: ${task.key}
+eclipse.preferences.version=1
diff --git a/org.eclipse.jgit.lfs.server.test/.settings/org.eclipse.pde.api.tools.prefs b/org.eclipse.jgit.lfs.server.test/.settings/org.eclipse.pde.api.tools.prefs
new file mode 100644
index 0000000..d585687
--- /dev/null
+++ b/org.eclipse.jgit.lfs.server.test/.settings/org.eclipse.pde.api.tools.prefs
@@ -0,0 +1,93 @@
+ANNOTATION_ELEMENT_TYPE_ADDED_METHOD_WITHOUT_DEFAULT_VALUE=Error
+ANNOTATION_ELEMENT_TYPE_CHANGED_TYPE_CONVERSION=Error
+ANNOTATION_ELEMENT_TYPE_REMOVED_FIELD=Error
+ANNOTATION_ELEMENT_TYPE_REMOVED_METHOD=Error
+ANNOTATION_ELEMENT_TYPE_REMOVED_TYPE_MEMBER=Error
+API_COMPONENT_ELEMENT_TYPE_REMOVED_API_TYPE=Error
+API_COMPONENT_ELEMENT_TYPE_REMOVED_REEXPORTED_API_TYPE=Error
+API_COMPONENT_ELEMENT_TYPE_REMOVED_REEXPORTED_TYPE=Error
+API_COMPONENT_ELEMENT_TYPE_REMOVED_TYPE=Error
+CLASS_ELEMENT_TYPE_ADDED_METHOD=Error
+CLASS_ELEMENT_TYPE_ADDED_RESTRICTIONS=Error
+CLASS_ELEMENT_TYPE_ADDED_TYPE_PARAMETER=Error
+CLASS_ELEMENT_TYPE_CHANGED_CONTRACTED_SUPERINTERFACES_SET=Error
+CLASS_ELEMENT_TYPE_CHANGED_DECREASE_ACCESS=Error
+CLASS_ELEMENT_TYPE_CHANGED_NON_ABSTRACT_TO_ABSTRACT=Error
+CLASS_ELEMENT_TYPE_CHANGED_NON_FINAL_TO_FINAL=Error
+CLASS_ELEMENT_TYPE_CHANGED_TYPE_CONVERSION=Error
+CLASS_ELEMENT_TYPE_REMOVED_CONSTRUCTOR=Error
+CLASS_ELEMENT_TYPE_REMOVED_FIELD=Error
+CLASS_ELEMENT_TYPE_REMOVED_METHOD=Error
+CLASS_ELEMENT_TYPE_REMOVED_SUPERCLASS=Error
+CLASS_ELEMENT_TYPE_REMOVED_TYPE_MEMBER=Error
+CLASS_ELEMENT_TYPE_REMOVED_TYPE_PARAMETER=Error
+CONSTRUCTOR_ELEMENT_TYPE_ADDED_TYPE_PARAMETER=Error
+CONSTRUCTOR_ELEMENT_TYPE_CHANGED_DECREASE_ACCESS=Error
+CONSTRUCTOR_ELEMENT_TYPE_CHANGED_VARARGS_TO_ARRAY=Error
+CONSTRUCTOR_ELEMENT_TYPE_REMOVED_TYPE_PARAMETER=Error
+ENUM_ELEMENT_TYPE_CHANGED_CONTRACTED_SUPERINTERFACES_SET=Error
+ENUM_ELEMENT_TYPE_CHANGED_TYPE_CONVERSION=Error
+ENUM_ELEMENT_TYPE_REMOVED_ENUM_CONSTANT=Error
+ENUM_ELEMENT_TYPE_REMOVED_FIELD=Error
+ENUM_ELEMENT_TYPE_REMOVED_METHOD=Error
+ENUM_ELEMENT_TYPE_REMOVED_TYPE_MEMBER=Error
+FIELD_ELEMENT_TYPE_ADDED_VALUE=Error
+FIELD_ELEMENT_TYPE_CHANGED_DECREASE_ACCESS=Error
+FIELD_ELEMENT_TYPE_CHANGED_FINAL_TO_NON_FINAL_STATIC_CONSTANT=Error
+FIELD_ELEMENT_TYPE_CHANGED_NON_FINAL_TO_FINAL=Error
+FIELD_ELEMENT_TYPE_CHANGED_NON_STATIC_TO_STATIC=Error
+FIELD_ELEMENT_TYPE_CHANGED_STATIC_TO_NON_STATIC=Error
+FIELD_ELEMENT_TYPE_CHANGED_TYPE=Error
+FIELD_ELEMENT_TYPE_CHANGED_VALUE=Error
+FIELD_ELEMENT_TYPE_REMOVED_TYPE_ARGUMENT=Error
+FIELD_ELEMENT_TYPE_REMOVED_VALUE=Error
+ILLEGAL_EXTEND=Warning
+ILLEGAL_IMPLEMENT=Warning
+ILLEGAL_INSTANTIATE=Warning
+ILLEGAL_OVERRIDE=Warning
+ILLEGAL_REFERENCE=Warning
+INTERFACE_ELEMENT_TYPE_ADDED_FIELD=Error
+INTERFACE_ELEMENT_TYPE_ADDED_METHOD=Error
+INTERFACE_ELEMENT_TYPE_ADDED_RESTRICTIONS=Error
+INTERFACE_ELEMENT_TYPE_ADDED_SUPER_INTERFACE_WITH_METHODS=Error
+INTERFACE_ELEMENT_TYPE_ADDED_TYPE_PARAMETER=Error
+INTERFACE_ELEMENT_TYPE_CHANGED_CONTRACTED_SUPERINTERFACES_SET=Error
+INTERFACE_ELEMENT_TYPE_CHANGED_TYPE_CONVERSION=Error
+INTERFACE_ELEMENT_TYPE_REMOVED_FIELD=Error
+INTERFACE_ELEMENT_TYPE_REMOVED_METHOD=Error
+INTERFACE_ELEMENT_TYPE_REMOVED_TYPE_MEMBER=Error
+INTERFACE_ELEMENT_TYPE_REMOVED_TYPE_PARAMETER=Error
+INVALID_JAVADOC_TAG=Ignore
+INVALID_REFERENCE_IN_SYSTEM_LIBRARIES=Error
+LEAK_EXTEND=Warning
+LEAK_FIELD_DECL=Warning
+LEAK_IMPLEMENT=Warning
+LEAK_METHOD_PARAM=Warning
+LEAK_METHOD_RETURN_TYPE=Warning
+METHOD_ELEMENT_TYPE_ADDED_RESTRICTIONS=Error
+METHOD_ELEMENT_TYPE_ADDED_TYPE_PARAMETER=Error
+METHOD_ELEMENT_TYPE_CHANGED_DECREASE_ACCESS=Error
+METHOD_ELEMENT_TYPE_CHANGED_NON_ABSTRACT_TO_ABSTRACT=Error
+METHOD_ELEMENT_TYPE_CHANGED_NON_FINAL_TO_FINAL=Error
+METHOD_ELEMENT_TYPE_CHANGED_NON_STATIC_TO_STATIC=Error
+METHOD_ELEMENT_TYPE_CHANGED_STATIC_TO_NON_STATIC=Error
+METHOD_ELEMENT_TYPE_CHANGED_VARARGS_TO_ARRAY=Error
+METHOD_ELEMENT_TYPE_REMOVED_ANNOTATION_DEFAULT_VALUE=Error
+METHOD_ELEMENT_TYPE_REMOVED_TYPE_PARAMETER=Error
+TYPE_PARAMETER_ELEMENT_TYPE_ADDED_CLASS_BOUND=Error
+TYPE_PARAMETER_ELEMENT_TYPE_ADDED_INTERFACE_BOUND=Error
+TYPE_PARAMETER_ELEMENT_TYPE_CHANGED_CLASS_BOUND=Error
+TYPE_PARAMETER_ELEMENT_TYPE_CHANGED_INTERFACE_BOUND=Error
+TYPE_PARAMETER_ELEMENT_TYPE_REMOVED_CLASS_BOUND=Error
+TYPE_PARAMETER_ELEMENT_TYPE_REMOVED_INTERFACE_BOUND=Error
+UNUSED_PROBLEM_FILTERS=Warning
+automatically_removed_unused_problem_filters=false
+eclipse.preferences.version=1
+incompatible_api_component_version=Error
+incompatible_api_component_version_include_major_without_breaking_change=Disabled
+incompatible_api_component_version_include_minor_without_api_change=Disabled
+invalid_since_tag_version=Error
+malformed_since_tag=Error
+missing_since_tag=Error
+report_api_breakage_when_major_version_incremented=Disabled
+report_resolution_errors_api_component=Warning
diff --git a/org.eclipse.jgit.lfs.server.test/.settings/org.eclipse.pde.core.prefs b/org.eclipse.jgit.lfs.server.test/.settings/org.eclipse.pde.core.prefs
new file mode 100644
index 0000000..923c37f
--- /dev/null
+++ b/org.eclipse.jgit.lfs.server.test/.settings/org.eclipse.pde.core.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+resolve.requirebundle=false
diff --git a/org.eclipse.jgit.lfs.server.test/BUCK b/org.eclipse.jgit.lfs.server.test/BUCK
new file mode 100644
index 0000000..9d6e72f
--- /dev/null
+++ b/org.eclipse.jgit.lfs.server.test/BUCK
@@ -0,0 +1,35 @@
+TEST_BASE = ['tst/org/eclipse/jgit/lfs/server/fs/LfsServerTest.java']
+TESTS = glob(['tst/**/*.java'],
+    excludes = TEST_BASE
+)
+
+for t in TESTS:
+  n = t[len('tst/'):len(t)-len('.java')].replace('/', '.')
+  java_test(
+    name = n,
+    labels = ['lfs-server'],
+    srcs = [t] + TEST_BASE,
+    deps = [
+      '//org.eclipse.jgit.lfs.test:helpers',
+      '//org.eclipse.jgit:jgit',
+      '//org.eclipse.jgit.junit:junit',
+      '//org.eclipse.jgit.junit.http:junit-http',
+      '//org.eclipse.jgit.lfs:jgit-lfs',
+      '//org.eclipse.jgit.lfs.server:jgit-lfs-server',
+      '//lib:hamcrest-core',
+      '//lib:hamcrest-library',
+      '//lib:httpcore',
+      '//lib:httpcomponents',
+      '//lib:junit',
+      '//lib/jetty:http',
+      '//lib/jetty:io',
+      '//lib/jetty:server',
+      '//lib/jetty:servlet',
+      '//lib/jetty:security',
+      '//lib/jetty:util',
+      '//lib:servlet-api',
+      '//lib:commons-logging',
+    ],
+    source_under_test = ['//org.eclipse.jgit.lfs.server:jgit-lfs-server'],
+    vm_args = ['-Xmx256m', '-Dfile.encoding=UTF-8'],
+  )
diff --git a/org.eclipse.jgit.lfs.server.test/META-INF/MANIFEST.MF b/org.eclipse.jgit.lfs.server.test/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..d263c3a
--- /dev/null
+++ b/org.eclipse.jgit.lfs.server.test/META-INF/MANIFEST.MF
@@ -0,0 +1,38 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: %plugin_name
+Bundle-SymbolicName: org.eclipse.jgit.lfs.server.test
+Bundle-Version: 4.3.0.qualifier
+Bundle-Vendor: %provider_name
+Bundle-Localization: plugin
+Bundle-RequiredExecutionEnvironment: JavaSE-1.7
+Import-Package: javax.servlet;version="[3.1.0,4.0.0)",
+ javax.servlet.http;version="[3.1.0,4.0.0)",
+ org.apache.http;version="[4.3.0,5.0.0)",
+ org.apache.http.client;version="[4.3.0,5.0.0)",
+ org.apache.http.client.methods;version="[4.3.0,5.0.0)",
+ org.apache.http.entity;version="[4.3.0,5.0.0)",
+ org.apache.http.impl.client;version="[4.3.0,5.0.0)",
+ org.eclipse.jetty.continuation;version="[9.0.0,10.0.0)",
+ org.eclipse.jetty.http;version="[9.0.0,10.0.0)",
+ org.eclipse.jetty.io;version="[9.0.0,10.0.0)",
+ org.eclipse.jetty.security;version="[9.0.0,10.0.0)",
+ org.eclipse.jetty.security.authentication;version="[9.0.0,10.0.0)",
+ org.eclipse.jetty.server;version="[9.0.0,10.0.0)",
+ org.eclipse.jetty.server.handler;version="[9.0.0,10.0.0)",
+ org.eclipse.jetty.server.nio;version="[9.0.0,10.0.0)",
+ org.eclipse.jetty.servlet;version="[9.0.0,10.0.0)",
+ org.eclipse.jetty.util;version="[9.0.0,10.0.0)",
+ org.eclipse.jetty.util.component;version="[9.0.0,10.0.0)",
+ org.eclipse.jetty.util.log;version="[9.0.0,10.0.0)",
+ org.eclipse.jetty.util.security;version="[9.0.0,10.0.0)",
+ org.eclipse.jetty.util.thread;version="[9.0.0,10.0.0)",
+ org.eclipse.jgit.junit.http;version="[4.3.0,4.4.0)",
+ org.eclipse.jgit.lfs.lib;version="[4.3.0,4.4.0)",
+ org.eclipse.jgit.lfs.server.fs;version="[4.3.0,4.4.0)",
+ org.eclipse.jgit.lfs.test;version="[4.3.0,4.4.0)",
+ org.eclipse.jgit.util;version="[4.3.0,4.4.0)",
+ org.hamcrest.core;version="[1.1.0,2.0.0)",
+ org.junit;version="[4.0.0,5.0.0)",
+ org.junit.runner;version="[4.0.0,5.0.0)",
+ org.junit.runners;version="[4.0.0,5.0.0)"
diff --git a/org.eclipse.jgit.lfs.server.test/build.properties b/org.eclipse.jgit.lfs.server.test/build.properties
new file mode 100644
index 0000000..9ffa0ca
--- /dev/null
+++ b/org.eclipse.jgit.lfs.server.test/build.properties
@@ -0,0 +1,5 @@
+source.. = tst/
+output.. = bin/
+bin.includes = META-INF/,\
+               .,\
+               plugin.properties
diff --git a/org.eclipse.jgit.lfs.server.test/plugin.properties b/org.eclipse.jgit.lfs.server.test/plugin.properties
new file mode 100644
index 0000000..4a8e642
--- /dev/null
+++ b/org.eclipse.jgit.lfs.server.test/plugin.properties
@@ -0,0 +1,2 @@
+plugin_name=JGit LFS Server Tests
+provider_name=Eclipse JGit
diff --git a/org.eclipse.jgit.lfs.server.test/pom.xml b/org.eclipse.jgit.lfs.server.test/pom.xml
new file mode 100644
index 0000000..15461aa
--- /dev/null
+++ b/org.eclipse.jgit.lfs.server.test/pom.xml
@@ -0,0 +1,146 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+   Copyright (C) 2015 Matthias Sohn <matthias.sohn@sap.com>
+   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.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>org.eclipse.jgit</groupId>
+    <artifactId>org.eclipse.jgit-parent</artifactId>
+    <version>4.3.0-SNAPSHOT</version>
+  </parent>
+
+  <artifactId>org.eclipse.jgit.lfs.server.test</artifactId>
+  <name>JGit - LFS Server Tests</name>
+
+  <description>
+    Tests for the LFS server.
+  </description>
+
+  <dependencies>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <scope>test</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>org.eclipse.jgit</groupId>
+      <artifactId>org.eclipse.jgit</artifactId>
+      <version>${project.version}</version>
+      <scope>test</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>org.eclipse.jgit</groupId>
+      <artifactId>org.eclipse.jgit.lfs.server</artifactId>
+      <version>${project.version}</version>
+      <scope>test</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>org.eclipse.jgit</groupId>
+      <artifactId>org.eclipse.jgit.lfs.test</artifactId>
+      <version>${project.version}</version>
+      <scope>test</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>org.eclipse.jgit</groupId>
+      <artifactId>org.eclipse.jgit.junit.http</artifactId>
+      <version>${project.version}</version>
+      <scope>test</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>org.eclipse.jgit</groupId>
+      <artifactId>org.eclipse.jgit.junit</artifactId>
+      <version>${project.version}</version>
+      <scope>test</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>org.eclipse.jetty</groupId>
+      <artifactId>jetty-servlet</artifactId>
+      <scope>test</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>org.apache.httpcomponents</groupId>
+      <artifactId>httpclient</artifactId>
+      <version>4.3.6</version>
+    </dependency>
+  </dependencies>
+
+  <build>
+    <testSourceDirectory>tst/</testSourceDirectory>
+
+    <testResources>
+      <testResource>
+        <directory>tst-rsrc/</directory>
+      </testResource>
+    </testResources>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-jar-plugin</artifactId>
+        <executions>
+          <execution>
+            <goals>
+              <goal>test-jar</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <artifactId>maven-surefire-plugin</artifactId>
+        <configuration>
+          <argLine>-Djava.io.tmpdir=${project.build.directory}  -Xmx300m</argLine>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+</project>
diff --git a/org.eclipse.jgit.lfs.server.test/tst/org/eclipse/jgit/lfs/server/fs/DownloadTest.java b/org.eclipse.jgit.lfs.server.test/tst/org/eclipse/jgit/lfs/server/fs/DownloadTest.java
new file mode 100644
index 0000000..6c4f3cb
--- /dev/null
+++ b/org.eclipse.jgit.lfs.server.test/tst/org/eclipse/jgit/lfs/server/fs/DownloadTest.java
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2015, Matthias Sohn <matthias.sohnk@sap.com>
+ * 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.lfs.server.fs;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import java.io.IOException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.text.MessageFormat;
+
+import org.apache.http.client.ClientProtocolException;
+import org.eclipse.jgit.lfs.lib.AnyLongObjectId;
+import org.eclipse.jgit.lfs.test.LongObjectIdTestUtils;
+import org.eclipse.jgit.util.FileUtils;
+import org.junit.Test;
+
+public class DownloadTest extends LfsServerTest {
+
+	@Test
+	public void testDownload() throws Exception {
+		String TEXT = "test";
+		AnyLongObjectId id = putContent(TEXT);
+		Path f = Paths.get(getTempDirectory().toString(), "download");
+		long len = getContent(id, f);
+		assertEquals(TEXT.length(), len);
+		FileUtils.delete(f.toFile(), FileUtils.RETRY);
+	}
+
+	@Test
+	public void testDownloadInvalidPathInfo()
+			throws ClientProtocolException, IOException {
+		String TEXT = "test";
+		AnyLongObjectId id = putContent(TEXT);
+		Path f = Paths.get(getTempDirectory().toString(), "download");
+		try {
+			getContent(id.name().substring(0, 60), f);
+			fail("expected RuntimeException");
+		} catch (RuntimeException e) {
+			assertEquals("Status: 400 Bad Request",
+					e.getMessage());
+		}
+	}
+
+	@Test
+	public void testDownloadInvalidId()
+			throws ClientProtocolException, IOException {
+		String TEXT = "test";
+		AnyLongObjectId id = putContent(TEXT);
+		Path f = Paths.get(getTempDirectory().toString(), "download");
+		try {
+			getContent(id.name().replace('f', 'z'), f);
+			fail("expected RuntimeException");
+		} catch (RuntimeException e) {
+			assertEquals("Status: 400 Bad Request",
+					e.getMessage());
+		}
+	}
+
+	@Test
+	public void testDownloadNotFound()
+			throws ClientProtocolException, IOException {
+		String TEXT = "test";
+		AnyLongObjectId id = LongObjectIdTestUtils.hash(TEXT);
+		Path f = Paths.get(getTempDirectory().toString(), "download");
+		try {
+			getContent(id, f);
+			fail("expected RuntimeException");
+		} catch (RuntimeException e) {
+			assertEquals("Status: 404 Not Found",
+					e.getMessage());
+		}
+	}
+
+	@SuppressWarnings("boxing")
+	@Test
+	public void testLargeFileDownload() throws Exception {
+		Path f = Paths.get(getTempDirectory().toString(), "largeRandomFile");
+		long expectedLen = createPseudoRandomContentFile(f, 5 * MiB);
+		AnyLongObjectId id = putContent(f);
+		Path f2 = Paths.get(getTempDirectory().toString(), "download");
+		long start = System.nanoTime();
+		long len = getContent(id, f2);
+		System.out.println(
+				MessageFormat.format("dowloaded 10 MiB random data in {0}ms",
+						(System.nanoTime() - start) / 1e6));
+		assertEquals(expectedLen, len);
+		FileUtils.delete(f.toFile(), FileUtils.RETRY);
+
+	}
+}
diff --git a/org.eclipse.jgit.lfs.server.test/tst/org/eclipse/jgit/lfs/server/fs/LfsServerTest.java b/org.eclipse.jgit.lfs.server.test/tst/org/eclipse/jgit/lfs/server/fs/LfsServerTest.java
new file mode 100644
index 0000000..8c266d4
--- /dev/null
+++ b/org.eclipse.jgit.lfs.server.test/tst/org/eclipse/jgit/lfs/server/fs/LfsServerTest.java
@@ -0,0 +1,252 @@
+/*
+ * Copyright (C) 2015, Matthias Sohn <matthias.sohnk@sap.com>
+ * 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.lfs.server.fs;
+
+import static org.junit.Assert.assertEquals;
+
+import java.io.BufferedInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.ByteBuffer;
+import java.nio.channels.Channels;
+import java.nio.channels.FileChannel;
+import java.nio.channels.ReadableByteChannel;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.StandardOpenOption;
+import java.security.DigestInputStream;
+import java.security.SecureRandom;
+
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpResponse;
+import org.apache.http.StatusLine;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPut;
+import org.apache.http.entity.ContentType;
+import org.apache.http.entity.InputStreamEntity;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClientBuilder;
+import org.eclipse.jetty.servlet.ServletContextHandler;
+import org.eclipse.jetty.servlet.ServletHolder;
+import org.eclipse.jgit.junit.http.AppServer;
+import org.eclipse.jgit.lfs.lib.AnyLongObjectId;
+import org.eclipse.jgit.lfs.lib.Constants;
+import org.eclipse.jgit.lfs.lib.LongObjectId;
+import org.eclipse.jgit.lfs.test.LongObjectIdTestUtils;
+import org.eclipse.jgit.util.FileUtils;
+import org.junit.After;
+import org.junit.Before;
+
+@SuppressWarnings("restriction")
+public abstract class LfsServerTest {
+
+	private static final long timeout = /* 10 sec */ 10 * 1000;
+
+	protected static final int MiB = 1024 * 1024;
+
+	/** In-memory application server; subclass must start. */
+	protected AppServer server;
+
+	private Path tmp;
+
+	private Path dir;
+
+	protected FileLfsRepository repository;
+
+	protected FileLfsServlet servlet;
+
+	public LfsServerTest() {
+		super();
+	}
+
+	public Path getTempDirectory() {
+		return tmp;
+	}
+
+	public Path getDir() {
+		return dir;
+	}
+
+	@Before
+	public void setup() throws Exception {
+		tmp = Files.createTempDirectory("jgit_test_");
+		server = new AppServer();
+		ServletContextHandler app = server.addContext("/lfs");
+		dir = Paths.get(tmp.toString(), "lfs");
+		this.repository = new FileLfsRepository(null, dir);
+		servlet = new FileLfsServlet(repository, timeout);
+		app.addServlet(new ServletHolder(servlet), "/objects/*");
+		server.setUp();
+	}
+
+	@After
+	public void tearDown() throws Exception {
+		server.tearDown();
+		FileUtils.delete(tmp.toFile(), FileUtils.RECURSIVE | FileUtils.RETRY);
+	}
+
+	protected AnyLongObjectId putContent(String s)
+			throws IOException, ClientProtocolException {
+		AnyLongObjectId id = LongObjectIdTestUtils.hash(s);
+		return putContent(id, s);
+	}
+
+	protected AnyLongObjectId putContent(AnyLongObjectId id, String s)
+			throws ClientProtocolException, IOException {
+		try (CloseableHttpClient client = HttpClientBuilder.create().build()) {
+			HttpEntity entity = new StringEntity(s,
+					ContentType.APPLICATION_OCTET_STREAM);
+			String hexId = id.name();
+			HttpPut request = new HttpPut(
+					server.getURI() + "/lfs/objects/" + hexId);
+			request.setEntity(entity);
+			try (CloseableHttpResponse response = client.execute(request)) {
+				StatusLine statusLine = response.getStatusLine();
+				int status = statusLine.getStatusCode();
+				if (status >= 400) {
+					throw new RuntimeException("Status: " + status + ". "
+							+ statusLine.getReasonPhrase());
+				}
+			}
+			return id;
+		}
+	}
+
+	protected LongObjectId putContent(Path f)
+			throws FileNotFoundException, IOException {
+		try (CloseableHttpClient client = HttpClientBuilder.create().build()) {
+			LongObjectId id1, id2;
+			String hexId1, hexId2;
+			try (DigestInputStream in = new DigestInputStream(
+					new BufferedInputStream(Files.newInputStream(f)),
+					Constants.newMessageDigest())) {
+				InputStreamEntity entity = new InputStreamEntity(in,
+						Files.size(f), ContentType.APPLICATION_OCTET_STREAM);
+				id1 = LongObjectIdTestUtils.hash(f);
+				hexId1 = id1.name();
+				HttpPut request = new HttpPut(
+						server.getURI() + "/lfs/objects/" + hexId1);
+				request.setEntity(entity);
+				HttpResponse response = client.execute(request);
+				checkResponseStatus(response);
+				id2 = LongObjectId.fromRaw(in.getMessageDigest().digest());
+				hexId2 = id2.name();
+				assertEquals(hexId1, hexId2);
+			}
+			return id1;
+		}
+	}
+
+	private void checkResponseStatus(HttpResponse response) {
+		StatusLine statusLine = response.getStatusLine();
+		int status = statusLine.getStatusCode();
+		if (statusLine.getStatusCode() >= 400) {
+			throw new RuntimeException("Status: " + status + " "
+					+ statusLine.getReasonPhrase());
+		}
+		assertEquals(200, status);
+	}
+
+	protected long getContent(AnyLongObjectId id, Path f) throws IOException {
+		String hexId = id.name();
+		return getContent(hexId, f);
+	}
+
+	protected long getContent(String hexId, Path f) throws IOException {
+		try (CloseableHttpClient client = HttpClientBuilder.create().build()) {
+			HttpGet request = new HttpGet(
+					server.getURI() + "/lfs/objects/" + hexId);
+			HttpResponse response = client.execute(request);
+			checkResponseStatus(response);
+			HttpEntity entity = response.getEntity();
+			long pos = 0;
+			try (InputStream in = entity.getContent();
+					ReadableByteChannel inChannel = Channels.newChannel(in);
+					FileChannel outChannel = FileChannel.open(f,
+							StandardOpenOption.CREATE_NEW,
+							StandardOpenOption.WRITE)) {
+				long transferred;
+				do {
+					transferred = outChannel.transferFrom(inChannel, pos, MiB);
+					pos += transferred;
+				} while (transferred > 0);
+			}
+			return pos;
+		}
+	}
+
+	/**
+	 * Creates a file with random content, repeatedly writing a random string of
+	 * 4k length to the file until the file has at least the specified length.
+	 *
+	 * @param f
+	 *            file to fill
+	 * @param size
+	 *            size of the file to generate
+	 * @return length of the generated file in bytes
+	 * @throws IOException
+	 */
+	protected long createPseudoRandomContentFile(Path f, long size)
+			throws IOException {
+		SecureRandom rnd = new SecureRandom();
+		byte[] buf = new byte[4096];
+		rnd.nextBytes(buf);
+		ByteBuffer bytebuf = ByteBuffer.wrap(buf);
+		try (FileChannel outChannel = FileChannel.open(f,
+				StandardOpenOption.CREATE_NEW, StandardOpenOption.WRITE)) {
+			long len = 0;
+			do {
+				len += outChannel.write(bytebuf);
+				if (bytebuf.position() == 4096) {
+					bytebuf.rewind();
+				}
+			} while (len < size);
+		}
+		return Files.size(f);
+	}
+}
\ No newline at end of file
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
new file mode 100644
index 0000000..35bf09b
--- /dev/null
+++ b/org.eclipse.jgit.lfs.server.test/tst/org/eclipse/jgit/lfs/server/fs/UploadTest.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2015, Matthias Sohn <matthias.sohnk@sap.com>
+ * 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.lfs.server.fs;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.text.MessageFormat;
+
+import org.eclipse.jgit.lfs.lib.AnyLongObjectId;
+import org.eclipse.jgit.lfs.lib.LongObjectId;
+import org.eclipse.jgit.lfs.test.LongObjectIdTestUtils;
+import org.junit.Test;
+
+public class UploadTest extends LfsServerTest {
+
+	@Test
+	public void testUpload() throws Exception {
+		String TEXT = "test";
+		AnyLongObjectId id = putContent(TEXT);
+		assertTrue("expect object " + id.name() + " to exist",
+				repository.getSize(id) >= 0);
+		assertEquals("expected object length " + TEXT.length(), TEXT.length(),
+				repository.getSize(id));
+	}
+
+	@Test
+	public void testCorruptUpload() throws Exception {
+		String TEXT = "test";
+		AnyLongObjectId id = LongObjectIdTestUtils.hash("wrongHash");
+		try {
+			putContent(id, TEXT);
+			fail("expected RuntimeException(\"Status 400\")");
+		} catch (RuntimeException e) {
+			assertEquals("Status: 400. Bad Request", e.getMessage());
+		}
+		assertFalse("expect object " + id.name() + " not to exist",
+				repository.getSize(id) >= 0);
+	}
+
+	@SuppressWarnings("boxing")
+	@Test
+	public void testLargeFileUpload() throws Exception {
+		Path f = Paths.get(getTempDirectory().toString(), "largeRandomFile");
+		createPseudoRandomContentFile(f, 5 * MiB);
+		long start = System.nanoTime();
+		LongObjectId id = putContent(f);
+		System.out.println(
+				MessageFormat.format("uploaded 10 MiB random data in {0}ms",
+						(System.nanoTime() - start) / 1e6));
+		assertTrue("expect object " + id.name() + " to exist",
+				repository.getSize(id) >= 0);
+		assertEquals("expected object length " + Files.size(f), Files.size(f),
+				repository.getSize(id));
+	}
+}
diff --git a/org.eclipse.jgit.lfs.server/.classpath b/org.eclipse.jgit.lfs.server/.classpath
new file mode 100644
index 0000000..04a2be7
--- /dev/null
+++ b/org.eclipse.jgit.lfs.server/.classpath
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="src" path="resources"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/org.eclipse.jgit.lfs.server/.fbprefs b/org.eclipse.jgit.lfs.server/.fbprefs
new file mode 100644
index 0000000..81a0767
--- /dev/null
+++ b/org.eclipse.jgit.lfs.server/.fbprefs
@@ -0,0 +1,125 @@
+#FindBugs User Preferences
+#Mon May 04 16:24:13 PDT 2009
+detectorAppendingToAnObjectOutputStream=AppendingToAnObjectOutputStream|true
+detectorBadAppletConstructor=BadAppletConstructor|false
+detectorBadResultSetAccess=BadResultSetAccess|true
+detectorBadSyntaxForRegularExpression=BadSyntaxForRegularExpression|true
+detectorBadUseOfReturnValue=BadUseOfReturnValue|true
+detectorBadlyOverriddenAdapter=BadlyOverriddenAdapter|true
+detectorBooleanReturnNull=BooleanReturnNull|true
+detectorCallToUnsupportedMethod=CallToUnsupportedMethod|true
+detectorCheckImmutableAnnotation=CheckImmutableAnnotation|true
+detectorCheckTypeQualifiers=CheckTypeQualifiers|true
+detectorCloneIdiom=CloneIdiom|false
+detectorComparatorIdiom=ComparatorIdiom|true
+detectorConfusedInheritance=ConfusedInheritance|true
+detectorConfusionBetweenInheritedAndOuterMethod=ConfusionBetweenInheritedAndOuterMethod|true
+detectorCrossSiteScripting=CrossSiteScripting|true
+detectorDoInsideDoPrivileged=DoInsideDoPrivileged|true
+detectorDontCatchIllegalMonitorStateException=DontCatchIllegalMonitorStateException|true
+detectorDontUseEnum=DontUseEnum|true
+detectorDroppedException=DroppedException|true
+detectorDumbMethodInvocations=DumbMethodInvocations|true
+detectorDumbMethods=DumbMethods|true
+detectorDuplicateBranches=DuplicateBranches|true
+detectorEmptyZipFileEntry=EmptyZipFileEntry|true
+detectorEqualsOperandShouldHaveClassCompatibleWithThis=EqualsOperandShouldHaveClassCompatibleWithThis|true
+detectorFinalizerNullsFields=FinalizerNullsFields|true
+detectorFindBadCast2=FindBadCast2|true
+detectorFindBadForLoop=FindBadForLoop|true
+detectorFindCircularDependencies=FindCircularDependencies|false
+detectorFindDeadLocalStores=FindDeadLocalStores|true
+detectorFindDoubleCheck=FindDoubleCheck|true
+detectorFindEmptySynchronizedBlock=FindEmptySynchronizedBlock|true
+detectorFindFieldSelfAssignment=FindFieldSelfAssignment|true
+detectorFindFinalizeInvocations=FindFinalizeInvocations|true
+detectorFindFloatEquality=FindFloatEquality|true
+detectorFindHEmismatch=FindHEmismatch|true
+detectorFindInconsistentSync2=FindInconsistentSync2|true
+detectorFindJSR166LockMonitorenter=FindJSR166LockMonitorenter|true
+detectorFindLocalSelfAssignment2=FindLocalSelfAssignment2|true
+detectorFindMaskedFields=FindMaskedFields|true
+detectorFindMismatchedWaitOrNotify=FindMismatchedWaitOrNotify|true
+detectorFindNakedNotify=FindNakedNotify|true
+detectorFindNonSerializableStoreIntoSession=FindNonSerializableStoreIntoSession|true
+detectorFindNonSerializableValuePassedToWriteObject=FindNonSerializableValuePassedToWriteObject|true
+detectorFindNonShortCircuit=FindNonShortCircuit|true
+detectorFindNullDeref=FindNullDeref|true
+detectorFindNullDerefsInvolvingNonShortCircuitEvaluation=FindNullDerefsInvolvingNonShortCircuitEvaluation|true
+detectorFindOpenStream=FindOpenStream|true
+detectorFindPuzzlers=FindPuzzlers|true
+detectorFindRefComparison=FindRefComparison|true
+detectorFindReturnRef=FindReturnRef|true
+detectorFindRunInvocations=FindRunInvocations|true
+detectorFindSelfComparison=FindSelfComparison|true
+detectorFindSelfComparison2=FindSelfComparison2|true
+detectorFindSleepWithLockHeld=FindSleepWithLockHeld|true
+detectorFindSpinLoop=FindSpinLoop|true
+detectorFindSqlInjection=FindSqlInjection|true
+detectorFindTwoLockWait=FindTwoLockWait|true
+detectorFindUncalledPrivateMethods=FindUncalledPrivateMethods|true
+detectorFindUnconditionalWait=FindUnconditionalWait|true
+detectorFindUninitializedGet=FindUninitializedGet|true
+detectorFindUnrelatedTypesInGenericContainer=FindUnrelatedTypesInGenericContainer|true
+detectorFindUnreleasedLock=FindUnreleasedLock|true
+detectorFindUnsatisfiedObligation=FindUnsatisfiedObligation|true
+detectorFindUnsyncGet=FindUnsyncGet|true
+detectorFindUselessControlFlow=FindUselessControlFlow|true
+detectorFormatStringChecker=FormatStringChecker|true
+detectorHugeSharedStringConstants=HugeSharedStringConstants|true
+detectorIDivResultCastToDouble=IDivResultCastToDouble|true
+detectorIncompatMask=IncompatMask|true
+detectorInconsistentAnnotations=InconsistentAnnotations|true
+detectorInefficientMemberAccess=InefficientMemberAccess|false
+detectorInefficientToArray=InefficientToArray|true
+detectorInfiniteLoop=InfiniteLoop|true
+detectorInfiniteRecursiveLoop=InfiniteRecursiveLoop|true
+detectorInfiniteRecursiveLoop2=InfiniteRecursiveLoop2|false
+detectorInheritanceUnsafeGetResource=InheritanceUnsafeGetResource|true
+detectorInitializationChain=InitializationChain|true
+detectorInstantiateStaticClass=InstantiateStaticClass|true
+detectorInvalidJUnitTest=InvalidJUnitTest|true
+detectorIteratorIdioms=IteratorIdioms|true
+detectorLazyInit=LazyInit|true
+detectorLoadOfKnownNullValue=LoadOfKnownNullValue|true
+detectorMethodReturnCheck=MethodReturnCheck|true
+detectorMultithreadedInstanceAccess=MultithreadedInstanceAccess|true
+detectorMutableLock=MutableLock|true
+detectorMutableStaticFields=MutableStaticFields|true
+detectorNaming=Naming|true
+detectorNumberConstructor=NumberConstructor|true
+detectorOverridingEqualsNotSymmetrical=OverridingEqualsNotSymmetrical|true
+detectorPreferZeroLengthArrays=PreferZeroLengthArrays|true
+detectorPublicSemaphores=PublicSemaphores|false
+detectorQuestionableBooleanAssignment=QuestionableBooleanAssignment|true
+detectorReadReturnShouldBeChecked=ReadReturnShouldBeChecked|true
+detectorRedundantInterfaces=RedundantInterfaces|true
+detectorRepeatedConditionals=RepeatedConditionals|true
+detectorRuntimeExceptionCapture=RuntimeExceptionCapture|true
+detectorSerializableIdiom=SerializableIdiom|true
+detectorStartInConstructor=StartInConstructor|true
+detectorStaticCalendarDetector=StaticCalendarDetector|true
+detectorStringConcatenation=StringConcatenation|true
+detectorSuperfluousInstanceOf=SuperfluousInstanceOf|true
+detectorSuspiciousThreadInterrupted=SuspiciousThreadInterrupted|true
+detectorSwitchFallthrough=SwitchFallthrough|true
+detectorSynchronizeAndNullCheckField=SynchronizeAndNullCheckField|true
+detectorSynchronizeOnClassLiteralNotGetClass=SynchronizeOnClassLiteralNotGetClass|true
+detectorSynchronizingOnContentsOfFieldToProtectField=SynchronizingOnContentsOfFieldToProtectField|true
+detectorURLProblems=URLProblems|true
+detectorUncallableMethodOfAnonymousClass=UncallableMethodOfAnonymousClass|true
+detectorUnnecessaryMath=UnnecessaryMath|true
+detectorUnreadFields=UnreadFields|true
+detectorUseObjectEquals=UseObjectEquals|false
+detectorUselessSubclassMethod=UselessSubclassMethod|false
+detectorVarArgsProblems=VarArgsProblems|true
+detectorVolatileUsage=VolatileUsage|true
+detectorWaitInLoop=WaitInLoop|true
+detectorWrongMapIterator=WrongMapIterator|true
+detectorXMLFactoryBypass=XMLFactoryBypass|true
+detector_threshold=2
+effort=default
+excludefilter0=findBugs/FindBugsExcludeFilter.xml
+filter_settings=Medium|BAD_PRACTICE,CORRECTNESS,MT_CORRECTNESS,PERFORMANCE,STYLE|false
+filter_settings_neg=MALICIOUS_CODE,NOISE,I18N,SECURITY,EXPERIMENTAL|
+run_at_full_build=true
diff --git a/org.eclipse.jgit.lfs.server/.gitignore b/org.eclipse.jgit.lfs.server/.gitignore
new file mode 100644
index 0000000..934e0e0
--- /dev/null
+++ b/org.eclipse.jgit.lfs.server/.gitignore
@@ -0,0 +1,2 @@
+/bin
+/target
diff --git a/org.eclipse.jgit.lfs.server/.project b/org.eclipse.jgit.lfs.server/.project
new file mode 100644
index 0000000..8379fea
--- /dev/null
+++ b/org.eclipse.jgit.lfs.server/.project
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.jgit.lfs.server</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ManifestBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.SchemaBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.api.tools.apiAnalysisBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>org.eclipse.pde.PluginNature</nature>
+		<nature>org.eclipse.pde.api.tools.apiAnalysisNature</nature>
+	</natures>
+</projectDescription>
diff --git a/org.eclipse.jgit.lfs.server/.settings/org.eclipse.core.resources.prefs b/org.eclipse.jgit.lfs.server/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 0000000..99f26c0
--- /dev/null
+++ b/org.eclipse.jgit.lfs.server/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+encoding/<project>=UTF-8
diff --git a/org.eclipse.jgit.lfs.server/.settings/org.eclipse.core.runtime.prefs b/org.eclipse.jgit.lfs.server/.settings/org.eclipse.core.runtime.prefs
new file mode 100644
index 0000000..5a0ad22
--- /dev/null
+++ b/org.eclipse.jgit.lfs.server/.settings/org.eclipse.core.runtime.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+line.separator=\n
diff --git a/org.eclipse.jgit.lfs.server/.settings/org.eclipse.jdt.core.prefs b/org.eclipse.jgit.lfs.server/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..ff39d16
--- /dev/null
+++ b/org.eclipse.jgit.lfs.server/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,398 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.annotation.inheritNullAnnotations=disabled
+org.eclipse.jdt.core.compiler.annotation.missingNonNullByDefaultAnnotation=ignore
+org.eclipse.jdt.core.compiler.annotation.nonnull=org.eclipse.jdt.annotation.NonNull
+org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=org.eclipse.jdt.annotation.NonNullByDefault
+org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nullable
+org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.7
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.doc.comment.support=enabled
+org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.autoboxing=warning
+org.eclipse.jdt.core.compiler.problem.comparingIdentical=error
+org.eclipse.jdt.core.compiler.problem.deadCode=error
+org.eclipse.jdt.core.compiler.problem.deprecation=warning
+org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
+org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
+org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
+org.eclipse.jdt.core.compiler.problem.emptyStatement=warning
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=ignore
+org.eclipse.jdt.core.compiler.problem.fallthroughCase=warning
+org.eclipse.jdt.core.compiler.problem.fatalOptionalError=disabled
+org.eclipse.jdt.core.compiler.problem.fieldHiding=warning
+org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
+org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=error
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=error
+org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=error
+org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=enabled
+org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
+org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=warning
+org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=error
+org.eclipse.jdt.core.compiler.problem.invalidJavadoc=error
+org.eclipse.jdt.core.compiler.problem.invalidJavadocTags=enabled
+org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsDeprecatedRef=enabled
+org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsNotVisibleRef=enabled
+org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsVisibility=private
+org.eclipse.jdt.core.compiler.problem.localVariableHiding=warning
+org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=error
+org.eclipse.jdt.core.compiler.problem.missingDefaultCase=ignore
+org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore
+org.eclipse.jdt.core.compiler.problem.missingEnumCaseDespiteDefault=disabled
+org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=error
+org.eclipse.jdt.core.compiler.problem.missingJavadocComments=error
+org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsVisibility=protected
+org.eclipse.jdt.core.compiler.problem.missingJavadocTagDescription=return_tag
+org.eclipse.jdt.core.compiler.problem.missingJavadocTags=error
+org.eclipse.jdt.core.compiler.problem.missingJavadocTagsMethodTypeParameters=disabled
+org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility=private
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled
+org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
+org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore
+org.eclipse.jdt.core.compiler.problem.noEffectAssignment=error
+org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=error
+org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=warning
+org.eclipse.jdt.core.compiler.problem.nonnullParameterAnnotationDropped=warning
+org.eclipse.jdt.core.compiler.problem.nullAnnotationInferenceConflict=error
+org.eclipse.jdt.core.compiler.problem.nullReference=error
+org.eclipse.jdt.core.compiler.problem.nullSpecViolation=error
+org.eclipse.jdt.core.compiler.problem.nullUncheckedConversion=warning
+org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
+org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=error
+org.eclipse.jdt.core.compiler.problem.potentialNullReference=warning
+org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable=ignore
+org.eclipse.jdt.core.compiler.problem.rawTypeReference=ignore
+org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning
+org.eclipse.jdt.core.compiler.problem.redundantNullCheck=warning
+org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore
+org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=error
+org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore
+org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore
+org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
+org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=error
+org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled
+org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
+org.eclipse.jdt.core.compiler.problem.syntacticNullAnalysisForFields=disabled
+org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
+org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
+org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=enabled
+org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
+org.eclipse.jdt.core.compiler.problem.unclosedCloseable=warning
+org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=warning
+org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
+org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=error
+org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=warning
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.unusedImport=error
+org.eclipse.jdt.core.compiler.problem.unusedLabel=error
+org.eclipse.jdt.core.compiler.problem.unusedLocal=error
+org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=warning
+org.eclipse.jdt.core.compiler.problem.unusedParameter=warning
+org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
+org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=error
+org.eclipse.jdt.core.compiler.problem.unusedTypeParameter=ignore
+org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=error
+org.eclipse.jdt.core.compiler.source=1.7
+org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_assignment=0
+org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_compact_if=16
+org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80
+org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0
+org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16
+org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0
+org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16
+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80
+org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16
+org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=16
+org.eclipse.jdt.core.formatter.blank_lines_after_imports=1
+org.eclipse.jdt.core.formatter.blank_lines_after_package=1
+org.eclipse.jdt.core.formatter.blank_lines_before_field=1
+org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0
+org.eclipse.jdt.core.formatter.blank_lines_before_imports=1
+org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1
+org.eclipse.jdt.core.formatter.blank_lines_before_method=1
+org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1
+org.eclipse.jdt.core.formatter.blank_lines_before_package=0
+org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1
+org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1
+org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines=false
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false
+org.eclipse.jdt.core.formatter.comment.format_block_comments=true
+org.eclipse.jdt.core.formatter.comment.format_comments=true
+org.eclipse.jdt.core.formatter.comment.format_header=false
+org.eclipse.jdt.core.formatter.comment.format_html=true
+org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true
+org.eclipse.jdt.core.formatter.comment.format_line_comments=true
+org.eclipse.jdt.core.formatter.comment.format_source_code=true
+org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true
+org.eclipse.jdt.core.formatter.comment.indent_root_tags=true
+org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert
+org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert
+org.eclipse.jdt.core.formatter.comment.line_length=80
+org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true
+org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true
+org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=false
+org.eclipse.jdt.core.formatter.compact_else_if=true
+org.eclipse.jdt.core.formatter.continuation_indentation=2
+org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2
+org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off
+org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on
+org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false
+org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true
+org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true
+org.eclipse.jdt.core.formatter.indent_empty_lines=false
+org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true
+org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true
+org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true
+org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false
+org.eclipse.jdt.core.formatter.indentation.size=4
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_member=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert
+org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert
+org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert
+org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert
+org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert
+org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert
+org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.join_lines_in_comments=true
+org.eclipse.jdt.core.formatter.join_wrapped_lines=true
+org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false
+org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false
+org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false
+org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false
+org.eclipse.jdt.core.formatter.lineSplit=80
+org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false
+org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false
+org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0
+org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1
+org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true
+org.eclipse.jdt.core.formatter.tabulation.char=tab
+org.eclipse.jdt.core.formatter.tabulation.size=4
+org.eclipse.jdt.core.formatter.use_on_off_tags=true
+org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false
+org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true
+org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true
+org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true
diff --git a/org.eclipse.jgit.lfs.server/.settings/org.eclipse.jdt.ui.prefs b/org.eclipse.jgit.lfs.server/.settings/org.eclipse.jdt.ui.prefs
new file mode 100644
index 0000000..c336cce
--- /dev/null
+++ b/org.eclipse.jgit.lfs.server/.settings/org.eclipse.jdt.ui.prefs
@@ -0,0 +1,61 @@
+eclipse.preferences.version=1
+editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
+formatter_profile=_JGit Format
+formatter_settings_version=12
+org.eclipse.jdt.ui.ignorelowercasenames=true
+org.eclipse.jdt.ui.importorder=java;javax;org;com;
+org.eclipse.jdt.ui.ondemandthreshold=99
+org.eclipse.jdt.ui.staticondemandthreshold=99
+org.eclipse.jdt.ui.text.custom_code_templates=<?xml version\="1.0" encoding\="UTF-8"?><templates/>
+sp_cleanup.add_default_serial_version_id=true
+sp_cleanup.add_generated_serial_version_id=false
+sp_cleanup.add_missing_annotations=false
+sp_cleanup.add_missing_deprecated_annotations=true
+sp_cleanup.add_missing_methods=false
+sp_cleanup.add_missing_nls_tags=false
+sp_cleanup.add_missing_override_annotations=true
+sp_cleanup.add_missing_override_annotations_interface_methods=false
+sp_cleanup.add_serial_version_id=false
+sp_cleanup.always_use_blocks=true
+sp_cleanup.always_use_parentheses_in_expressions=false
+sp_cleanup.always_use_this_for_non_static_field_access=false
+sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.correct_indentation=false
+sp_cleanup.format_source_code=true
+sp_cleanup.format_source_code_changes_only=true
+sp_cleanup.make_local_variable_final=false
+sp_cleanup.make_parameters_final=false
+sp_cleanup.make_private_fields_final=true
+sp_cleanup.make_type_abstract_if_missing_method=false
+sp_cleanup.make_variable_declarations_final=false
+sp_cleanup.never_use_blocks=false
+sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.organize_imports=false
+sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
+sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
+sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
+sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
+sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_trailing_whitespaces=true
+sp_cleanup.remove_trailing_whitespaces_all=true
+sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_casts=false
+sp_cleanup.remove_unnecessary_nls_tags=false
+sp_cleanup.remove_unused_imports=false
+sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_private_fields=true
+sp_cleanup.remove_unused_private_members=false
+sp_cleanup.remove_unused_private_methods=true
+sp_cleanup.remove_unused_private_types=true
+sp_cleanup.sort_members=false
+sp_cleanup.sort_members_all=false
+sp_cleanup.use_blocks=false
+sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_this_for_non_static_field_access=false
+sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
+sp_cleanup.use_this_for_non_static_method_access=false
+sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
diff --git a/org.eclipse.jgit.lfs.server/.settings/org.eclipse.mylyn.tasks.ui.prefs b/org.eclipse.jgit.lfs.server/.settings/org.eclipse.mylyn.tasks.ui.prefs
new file mode 100644
index 0000000..3dec4d9
--- /dev/null
+++ b/org.eclipse.jgit.lfs.server/.settings/org.eclipse.mylyn.tasks.ui.prefs
@@ -0,0 +1,3 @@
+eclipse.preferences.version=1
+project.repository.kind=bugzilla
+project.repository.url=https\://bugs.eclipse.org/bugs
diff --git a/org.eclipse.jgit.lfs.server/.settings/org.eclipse.mylyn.team.ui.prefs b/org.eclipse.jgit.lfs.server/.settings/org.eclipse.mylyn.team.ui.prefs
new file mode 100644
index 0000000..ce7a0f0
--- /dev/null
+++ b/org.eclipse.jgit.lfs.server/.settings/org.eclipse.mylyn.team.ui.prefs
@@ -0,0 +1,2 @@
+commit.comment.template=${task.description} \n\nBug\: ${task.key}
+eclipse.preferences.version=1
diff --git a/org.eclipse.jgit.lfs.server/.settings/org.eclipse.pde.api.tools.prefs b/org.eclipse.jgit.lfs.server/.settings/org.eclipse.pde.api.tools.prefs
new file mode 100644
index 0000000..3294d4f
--- /dev/null
+++ b/org.eclipse.jgit.lfs.server/.settings/org.eclipse.pde.api.tools.prefs
@@ -0,0 +1,98 @@
+ANNOTATION_ELEMENT_TYPE_ADDED_METHOD_WITHOUT_DEFAULT_VALUE=Error
+ANNOTATION_ELEMENT_TYPE_CHANGED_TYPE_CONVERSION=Error
+ANNOTATION_ELEMENT_TYPE_REMOVED_FIELD=Error
+ANNOTATION_ELEMENT_TYPE_REMOVED_METHOD=Error
+ANNOTATION_ELEMENT_TYPE_REMOVED_TYPE_MEMBER=Error
+API_COMPONENT_ELEMENT_TYPE_REMOVED_API_TYPE=Error
+API_COMPONENT_ELEMENT_TYPE_REMOVED_REEXPORTED_API_TYPE=Error
+API_COMPONENT_ELEMENT_TYPE_REMOVED_REEXPORTED_TYPE=Error
+API_COMPONENT_ELEMENT_TYPE_REMOVED_TYPE=Error
+API_USE_SCAN_FIELD_SEVERITY=Error
+API_USE_SCAN_METHOD_SEVERITY=Error
+API_USE_SCAN_TYPE_SEVERITY=Error
+CLASS_ELEMENT_TYPE_ADDED_METHOD=Error
+CLASS_ELEMENT_TYPE_ADDED_RESTRICTIONS=Error
+CLASS_ELEMENT_TYPE_ADDED_TYPE_PARAMETER=Error
+CLASS_ELEMENT_TYPE_CHANGED_CONTRACTED_SUPERINTERFACES_SET=Error
+CLASS_ELEMENT_TYPE_CHANGED_DECREASE_ACCESS=Error
+CLASS_ELEMENT_TYPE_CHANGED_NON_ABSTRACT_TO_ABSTRACT=Error
+CLASS_ELEMENT_TYPE_CHANGED_NON_FINAL_TO_FINAL=Error
+CLASS_ELEMENT_TYPE_CHANGED_TYPE_CONVERSION=Error
+CLASS_ELEMENT_TYPE_REMOVED_CONSTRUCTOR=Error
+CLASS_ELEMENT_TYPE_REMOVED_FIELD=Error
+CLASS_ELEMENT_TYPE_REMOVED_METHOD=Error
+CLASS_ELEMENT_TYPE_REMOVED_SUPERCLASS=Error
+CLASS_ELEMENT_TYPE_REMOVED_TYPE_MEMBER=Error
+CLASS_ELEMENT_TYPE_REMOVED_TYPE_PARAMETER=Error
+CONSTRUCTOR_ELEMENT_TYPE_ADDED_TYPE_PARAMETER=Error
+CONSTRUCTOR_ELEMENT_TYPE_CHANGED_DECREASE_ACCESS=Error
+CONSTRUCTOR_ELEMENT_TYPE_CHANGED_VARARGS_TO_ARRAY=Error
+CONSTRUCTOR_ELEMENT_TYPE_REMOVED_TYPE_PARAMETER=Error
+ENUM_ELEMENT_TYPE_CHANGED_CONTRACTED_SUPERINTERFACES_SET=Error
+ENUM_ELEMENT_TYPE_CHANGED_TYPE_CONVERSION=Error
+ENUM_ELEMENT_TYPE_REMOVED_ENUM_CONSTANT=Error
+ENUM_ELEMENT_TYPE_REMOVED_FIELD=Error
+ENUM_ELEMENT_TYPE_REMOVED_METHOD=Error
+ENUM_ELEMENT_TYPE_REMOVED_TYPE_MEMBER=Error
+FIELD_ELEMENT_TYPE_ADDED_VALUE=Error
+FIELD_ELEMENT_TYPE_CHANGED_DECREASE_ACCESS=Error
+FIELD_ELEMENT_TYPE_CHANGED_FINAL_TO_NON_FINAL_STATIC_CONSTANT=Error
+FIELD_ELEMENT_TYPE_CHANGED_NON_FINAL_TO_FINAL=Error
+FIELD_ELEMENT_TYPE_CHANGED_NON_STATIC_TO_STATIC=Error
+FIELD_ELEMENT_TYPE_CHANGED_STATIC_TO_NON_STATIC=Error
+FIELD_ELEMENT_TYPE_CHANGED_TYPE=Error
+FIELD_ELEMENT_TYPE_CHANGED_VALUE=Error
+FIELD_ELEMENT_TYPE_REMOVED_TYPE_ARGUMENT=Error
+FIELD_ELEMENT_TYPE_REMOVED_VALUE=Error
+ILLEGAL_EXTEND=Warning
+ILLEGAL_IMPLEMENT=Warning
+ILLEGAL_INSTANTIATE=Warning
+ILLEGAL_OVERRIDE=Warning
+ILLEGAL_REFERENCE=Warning
+INTERFACE_ELEMENT_TYPE_ADDED_FIELD=Error
+INTERFACE_ELEMENT_TYPE_ADDED_METHOD=Error
+INTERFACE_ELEMENT_TYPE_ADDED_RESTRICTIONS=Error
+INTERFACE_ELEMENT_TYPE_ADDED_SUPER_INTERFACE_WITH_METHODS=Error
+INTERFACE_ELEMENT_TYPE_ADDED_TYPE_PARAMETER=Error
+INTERFACE_ELEMENT_TYPE_CHANGED_CONTRACTED_SUPERINTERFACES_SET=Error
+INTERFACE_ELEMENT_TYPE_CHANGED_TYPE_CONVERSION=Error
+INTERFACE_ELEMENT_TYPE_REMOVED_FIELD=Error
+INTERFACE_ELEMENT_TYPE_REMOVED_METHOD=Error
+INTERFACE_ELEMENT_TYPE_REMOVED_TYPE_MEMBER=Error
+INTERFACE_ELEMENT_TYPE_REMOVED_TYPE_PARAMETER=Error
+INVALID_ANNOTATION=Ignore
+INVALID_JAVADOC_TAG=Ignore
+INVALID_REFERENCE_IN_SYSTEM_LIBRARIES=Error
+LEAK_EXTEND=Warning
+LEAK_FIELD_DECL=Warning
+LEAK_IMPLEMENT=Warning
+LEAK_METHOD_PARAM=Warning
+LEAK_METHOD_RETURN_TYPE=Warning
+METHOD_ELEMENT_TYPE_ADDED_RESTRICTIONS=Error
+METHOD_ELEMENT_TYPE_ADDED_TYPE_PARAMETER=Error
+METHOD_ELEMENT_TYPE_CHANGED_DECREASE_ACCESS=Error
+METHOD_ELEMENT_TYPE_CHANGED_NON_ABSTRACT_TO_ABSTRACT=Error
+METHOD_ELEMENT_TYPE_CHANGED_NON_FINAL_TO_FINAL=Error
+METHOD_ELEMENT_TYPE_CHANGED_NON_STATIC_TO_STATIC=Error
+METHOD_ELEMENT_TYPE_CHANGED_STATIC_TO_NON_STATIC=Error
+METHOD_ELEMENT_TYPE_CHANGED_VARARGS_TO_ARRAY=Error
+METHOD_ELEMENT_TYPE_REMOVED_ANNOTATION_DEFAULT_VALUE=Error
+METHOD_ELEMENT_TYPE_REMOVED_TYPE_PARAMETER=Error
+MISSING_EE_DESCRIPTIONS=Error
+TYPE_PARAMETER_ELEMENT_TYPE_ADDED_CLASS_BOUND=Error
+TYPE_PARAMETER_ELEMENT_TYPE_ADDED_INTERFACE_BOUND=Error
+TYPE_PARAMETER_ELEMENT_TYPE_CHANGED_CLASS_BOUND=Error
+TYPE_PARAMETER_ELEMENT_TYPE_CHANGED_INTERFACE_BOUND=Error
+TYPE_PARAMETER_ELEMENT_TYPE_REMOVED_CLASS_BOUND=Error
+TYPE_PARAMETER_ELEMENT_TYPE_REMOVED_INTERFACE_BOUND=Error
+UNUSED_PROBLEM_FILTERS=Warning
+automatically_removed_unused_problem_filters=false
+eclipse.preferences.version=1
+incompatible_api_component_version=Error
+incompatible_api_component_version_include_major_without_breaking_change=Disabled
+incompatible_api_component_version_include_minor_without_api_change=Disabled
+invalid_since_tag_version=Error
+malformed_since_tag=Error
+missing_since_tag=Error
+report_api_breakage_when_major_version_incremented=Disabled
+report_resolution_errors_api_component=Warning
diff --git a/org.eclipse.jgit.lfs.server/.settings/org.eclipse.pde.core.prefs b/org.eclipse.jgit.lfs.server/.settings/org.eclipse.pde.core.prefs
new file mode 100644
index 0000000..923c37f
--- /dev/null
+++ b/org.eclipse.jgit.lfs.server/.settings/org.eclipse.pde.core.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+resolve.requirebundle=false
diff --git a/org.eclipse.jgit.lfs.server/BUCK b/org.eclipse.jgit.lfs.server/BUCK
new file mode 100644
index 0000000..6b40b7c
--- /dev/null
+++ b/org.eclipse.jgit.lfs.server/BUCK
@@ -0,0 +1,22 @@
+SRCS = glob(['src/**'])
+RESOURCES = glob(['resources/**'])
+
+java_library(
+  name = 'jgit-lfs-server',
+  srcs = SRCS,
+  resources = RESOURCES,
+  deps = [
+    '//org.eclipse.jgit.http.apache:http-apache',
+    '//org.eclipse.jgit:jgit',
+    '//org.eclipse.jgit.lfs:jgit-lfs',
+    '//lib:gson',
+    '//lib:httpcore',
+    '//lib:servlet-api'
+  ],
+  visibility = ['PUBLIC'],
+)
+
+java_sources(
+  name = 'jgit-lfs-server_src',
+  srcs = SRCS + RESOURCES,
+)
diff --git a/org.eclipse.jgit.lfs.server/META-INF/MANIFEST.MF b/org.eclipse.jgit.lfs.server/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..b0ff740
--- /dev/null
+++ b/org.eclipse.jgit.lfs.server/META-INF/MANIFEST.MF
@@ -0,0 +1,28 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: %plugin_name
+Bundle-SymbolicName: org.eclipse.jgit.lfs.server
+Bundle-Version: 4.3.0.qualifier
+Bundle-Localization: plugin
+Bundle-Vendor: %provider_name
+Export-Package: org.eclipse.jgit.lfs.server;version="4.3.0";
+  uses:="javax.servlet.http,
+   org.eclipse.jgit.lfs.lib",
+ org.eclipse.jgit.lfs.server.fs;version="4.3.0";
+  uses:="javax.servlet,
+   javax.servlet.http,
+   org.eclipse.jgit.lfs.server,
+   org.eclipse.jgit.lfs.lib",
+ org.eclipse.jgit.lfs.server.internal;version="4.3.0";x-internal:=true
+Bundle-RequiredExecutionEnvironment: JavaSE-1.7
+Import-Package: com.google.gson;version="[2.2.4,3.0.0)",
+ javax.servlet;version="[3.1.0,4.0.0)",
+ javax.servlet.annotation;version="[3.1.0,4.0.0)",
+ javax.servlet.http;version="[3.1.0,4.0.0)",
+ org.apache.http;version="[4.3.0,5.0.0)",
+ org.eclipse.jgit.annotations;version="[4.3.0,4.4.0)",
+ org.eclipse.jgit.internal.storage.file;version="[4.3.0,4.4.0)",
+ org.eclipse.jgit.lfs.errors;version="[4.3.0,4.4.0)",
+ org.eclipse.jgit.lfs.lib;version="[4.3.0,4.4.0)",
+ org.eclipse.jgit.nls;version="[4.3.0,4.4.0)",
+ org.eclipse.jgit.util;version="[4.3.0,4.4.0)"
diff --git a/org.eclipse.jgit.lfs.server/about.html b/org.eclipse.jgit.lfs.server/about.html
new file mode 100644
index 0000000..01a2671
--- /dev/null
+++ b/org.eclipse.jgit.lfs.server/about.html
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
+<title>Eclipse Distribution License - Version 1.0</title>
+<style type="text/css">
+  body {
+    size: 8.5in 11.0in;
+    margin: 0.25in 0.5in 0.25in 0.5in;
+    tab-interval: 0.5in;
+    }
+  p {  	
+    margin-left: auto;
+    margin-top:  0.5em;
+    margin-bottom: 0.5em;
+    }
+  p.list {
+  	margin-left: 0.5in;
+    margin-top:  0.05em;
+    margin-bottom: 0.05em;
+    }
+  </style>
+
+</head>
+
+<body lang="EN-US">
+
+<p><b>Eclipse Distribution License - v 1.0</b></p>
+
+<p>Copyright (c) 2007, Eclipse Foundation, Inc. and its licensors. </p>
+
+<p>All rights reserved.</p>
+<p>Redistribution and use in source and binary forms, with or without modification, 
+	are permitted provided that the following conditions are met:
+<ul><li>Redistributions of source code must retain the above copyright notice, 
+	this list of conditions and the following disclaimer. </li>
+<li>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. </li>
+<li>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. </li></ul>
+</p>
+<p>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.</p>
+
+</body>
+
+</html>
diff --git a/org.eclipse.jgit.lfs.server/build.properties b/org.eclipse.jgit.lfs.server/build.properties
new file mode 100644
index 0000000..8148271
--- /dev/null
+++ b/org.eclipse.jgit.lfs.server/build.properties
@@ -0,0 +1,7 @@
+source.. = src/,\
+           resources/
+output.. = bin/
+bin.includes = META-INF/,\
+               .,\
+               plugin.properties,\
+               about.html
diff --git a/org.eclipse.jgit.lfs.server/plugin.properties b/org.eclipse.jgit.lfs.server/plugin.properties
new file mode 100644
index 0000000..59f0139
--- /dev/null
+++ b/org.eclipse.jgit.lfs.server/plugin.properties
@@ -0,0 +1,2 @@
+plugin_name=JGit Large File Storage Server
+provider_name=Eclipse JGit
diff --git a/org.eclipse.jgit.lfs.server/pom.xml b/org.eclipse.jgit.lfs.server/pom.xml
new file mode 100644
index 0000000..8cfdf3b
--- /dev/null
+++ b/org.eclipse.jgit.lfs.server/pom.xml
@@ -0,0 +1,158 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+   Copyright (C) 2015, Matthias Sohn <matthias.sohn@sap.com>
+   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.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>org.eclipse.jgit</groupId>
+    <artifactId>org.eclipse.jgit-parent</artifactId>
+    <version>4.3.0-SNAPSHOT</version>
+  </parent>
+
+  <artifactId>org.eclipse.jgit.lfs.server</artifactId>
+  <name>JGit - Large File Storage Server</name>
+
+  <description>
+    JGit Large File Storage Server implementation.
+  </description>
+
+  <properties>
+    <translate-qualifier/>
+  </properties>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.eclipse.jgit</groupId>
+      <artifactId>org.eclipse.jgit</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+
+    <dependency>
+      <groupId>org.eclipse.jgit</groupId>
+      <artifactId>org.eclipse.jgit.lfs</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+
+    <dependency>
+      <groupId>javax.servlet</groupId>
+      <artifactId>javax.servlet-api</artifactId>
+      <scope>provided</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>com.google.code.gson</groupId>
+      <artifactId>gson</artifactId>
+    </dependency>
+  </dependencies>
+
+  <build>
+    <sourceDirectory>src/</sourceDirectory>
+
+    <resources>
+      <resource>
+        <directory>.</directory>
+        <includes>
+          <include>plugin.properties</include>
+          <include>about.html</include>
+        </includes>
+      </resource>
+      <resource>
+        <directory>resources/</directory>
+      </resource>
+    </resources>
+
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-source-plugin</artifactId>
+        <inherited>true</inherited>
+        <executions>
+          <execution>
+            <id>attach-sources</id>
+            <phase>process-classes</phase>
+            <goals>
+              <goal>jar</goal>
+            </goals>
+            <configuration>
+              <archive>
+                <manifestFile>${source-bundle-manifest}</manifestFile>
+              </archive>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+
+      <plugin>
+        <artifactId>maven-jar-plugin</artifactId>
+        <configuration>
+          <archive>
+            <manifestFile>${bundle-manifest}</manifestFile>
+          </archive>
+        </configuration>
+      </plugin>
+
+      <plugin>
+        <groupId>org.codehaus.mojo</groupId>
+        <artifactId>clirr-maven-plugin</artifactId>
+      </plugin>
+    </plugins>
+  </build>
+
+  <reporting>
+    <plugins>
+      <plugin>
+        <groupId>org.codehaus.mojo</groupId>
+        <artifactId>clirr-maven-plugin</artifactId>
+        <version>${clirr-version}</version>
+        <configuration>
+          <comparisonVersion>${jgit-last-release-version}</comparisonVersion>
+          <minSeverity>info</minSeverity>
+        </configuration>
+      </plugin>
+    </plugins>
+  </reporting>
+</project>
diff --git a/org.eclipse.jgit.lfs.server/resources/org/eclipse/jgit/lfs/server/internal/LfsServerText.properties b/org.eclipse.jgit.lfs.server/resources/org/eclipse/jgit/lfs/server/internal/LfsServerText.properties
new file mode 100644
index 0000000..752a774
--- /dev/null
+++ b/org.eclipse.jgit.lfs.server/resources/org/eclipse/jgit/lfs/server/internal/LfsServerText.properties
@@ -0,0 +1,4 @@
+corruptLongObject=The content hash ''{0}'' of the long object ''{1}'' doesn''t match its id, the corrupt object will be deleted.
+invalidPathInfo=Invalid pathInfo ''{0}'' does not match ''/'{'SHA-256'}'''
+objectNotFound=Object ''{0}'' not found
+unsupportedOperation=Operation ''{0}'' is not supported
diff --git a/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/LargeFileRepository.java b/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/LargeFileRepository.java
new file mode 100644
index 0000000..3bdf8d0
--- /dev/null
+++ b/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/LargeFileRepository.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2015, Matthias Sohn <matthias.sohn@sap.com>
+ * 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.lfs.server;
+
+import java.io.IOException;
+
+import org.eclipse.jgit.annotations.Nullable;
+import org.eclipse.jgit.lfs.lib.AnyLongObjectId;
+
+/**
+ * Abstraction of a repository for storing large objects
+ *
+ * @since 4.3
+ */
+public interface LargeFileRepository {
+
+	/**
+	 * @param id
+	 *            id of the object to download
+	 * @return Action for downloading the object
+	 */
+	public Response.Action getDownloadAction(AnyLongObjectId id);
+
+	/**
+	 * @param id
+	 *            id of the object to upload
+	 * @param size
+	 *            size of the object to be uploaded
+	 * @return Action for uploading the object
+	 */
+	public Response.Action getUploadAction(AnyLongObjectId id, long size);
+
+	/**
+	 * @param id
+	 *            id of the object to be verified
+	 * @return Action for verifying the object, or {@code null} if the server
+	 *         doesn't support or require verification
+	 */
+	public @Nullable Response.Action getVerifyAction(AnyLongObjectId id);
+
+	/**
+	 * @param id
+	 *            id of the object
+	 * @return length of the object content in bytes, -1 if the object doesn't
+	 *         exist
+	 * @throws IOException
+	 */
+	public long getSize(AnyLongObjectId id) throws IOException;
+}
diff --git a/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/LfsObject.java b/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/LfsObject.java
new file mode 100644
index 0000000..30ba22e
--- /dev/null
+++ b/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/LfsObject.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2015, Sasa Zivkov <sasa.zivkov@sap.com>
+ * 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.lfs.server;
+
+class LfsObject {
+	String oid;
+	long size;
+}
diff --git a/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/LfsProtocolServlet.java b/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/LfsProtocolServlet.java
new file mode 100644
index 0000000..394137c
--- /dev/null
+++ b/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/LfsProtocolServlet.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2015, Sasa Zivkov <sasa.zivkov@sap.com>
+ * 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.lfs.server;
+
+import static java.nio.charset.StandardCharsets.UTF_8;
+import static javax.servlet.http.HttpServletResponse.SC_OK;
+import static javax.servlet.http.HttpServletResponse.SC_SERVICE_UNAVAILABLE;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.io.Reader;
+import java.io.Writer;
+import java.util.List;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import com.google.gson.FieldNamingPolicy;
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+
+/**
+ * LFS protocol handler implementing the LFS batch API [1]
+ *
+ * [1] https://github.com/github/git-lfs/blob/master/docs/api/http-v1-batch.md
+ *
+ * @since 4.3
+ */
+public abstract class LfsProtocolServlet extends HttpServlet {
+
+	private static final long serialVersionUID = 1L;
+
+	private static final String CONTENTTYPE_VND_GIT_LFS_JSON = "application/vnd.git-lfs+json"; //$NON-NLS-1$
+
+	private Gson gson = createGson();
+
+	/**
+	 * Get the large file repository
+	 *
+	 * @return the large file repository storing large files
+	 */
+	protected abstract LargeFileRepository getLargeFileRepository();
+
+	@Override
+	protected void doPost(HttpServletRequest req, HttpServletResponse res)
+			throws ServletException, IOException {
+		res.setStatus(SC_OK);
+		res.setContentType(CONTENTTYPE_VND_GIT_LFS_JSON);
+
+		Writer w = new BufferedWriter(
+				new OutputStreamWriter(res.getOutputStream(), UTF_8));
+
+		Reader r = new BufferedReader(new InputStreamReader(req.getInputStream(), UTF_8));
+		LfsRequest request = gson.fromJson(r, LfsRequest.class);
+
+		LargeFileRepository repo = getLargeFileRepository();
+		if (repo == null) {
+			res.setStatus(SC_SERVICE_UNAVAILABLE);
+			return;
+		}
+
+		TransferHandler handler = TransferHandler
+				.forOperation(request.operation, repo, request.objects);
+		gson.toJson(handler.process(), w);
+		w.flush();
+	}
+
+	private static class LfsRequest {
+		String operation;
+
+		List<LfsObject> objects;
+	}
+
+	private static Gson createGson() {
+		GsonBuilder gb = new GsonBuilder()
+				.setFieldNamingPolicy(
+						FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
+				.setPrettyPrinting().disableHtmlEscaping();
+		return gb.create();
+	}
+}
diff --git a/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/Response.java b/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/Response.java
new file mode 100644
index 0000000..dc972e0
--- /dev/null
+++ b/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/Response.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2015, Sasa Zivkov <sasa.zivkov@sap.com>
+ * 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.lfs.server;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * POJOs for Gson serialization/deserialization
+ *
+ * See
+ * {@link <a href="https://github.com/github/git-lfs/tree/master/docs/api">LFS
+ * API specification</a>}
+ *
+ * @since 4.3
+ */
+public interface Response {
+	/** Describes an action the client can execute on a single object */
+	class Action {
+		public String href;
+		public Map<String, String> header;
+	}
+
+	/** Describes an error to be returned by the LFS batch API */
+	class Error {
+		public int code;
+		public String message;
+	}
+
+	/** Describes the actions the LFS server offers for a single object */
+	class ObjectInfo {
+		public String oid;
+		public long size;
+		public Map<String, Action> actions;
+		public Error error;
+	}
+
+	/** Describes the body of a LFS batch API response */
+	class Body {
+		public List<ObjectInfo> objects;
+	}
+}
diff --git a/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/TransferHandler.java b/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/TransferHandler.java
new file mode 100644
index 0000000..bf5b61c
--- /dev/null
+++ b/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/TransferHandler.java
@@ -0,0 +1,168 @@
+/*
+ * Copyright (C) 2015, Sasa Zivkov <sasa.zivkov@sap.com>
+ * 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.lfs.server;
+
+import static javax.servlet.http.HttpServletResponse.SC_NOT_FOUND;
+
+import java.io.IOException;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+import org.eclipse.jgit.lfs.lib.LongObjectId;
+import org.eclipse.jgit.lfs.server.Response.Action;
+import org.eclipse.jgit.lfs.server.Response.Body;
+import org.eclipse.jgit.lfs.server.internal.LfsServerText;
+
+abstract class TransferHandler {
+
+	private static final String DOWNLOAD = "download"; //$NON-NLS-1$
+	private static final String UPLOAD = "upload"; //$NON-NLS-1$
+	private static final String VERIFY = "verify"; //$NON-NLS-1$
+
+	static TransferHandler forOperation(String operation,
+			LargeFileRepository repository, List<LfsObject> objects) {
+		switch (operation) {
+		case TransferHandler.UPLOAD:
+			return new Upload(repository, objects);
+		case TransferHandler.DOWNLOAD:
+			return new Download(repository, objects);
+		case TransferHandler.VERIFY:
+		default:
+			throw new UnsupportedOperationException(MessageFormat.format(
+					LfsServerText.get().unsupportedOperation, operation));
+		}
+	}
+
+	private static class Upload extends TransferHandler {
+		Upload(LargeFileRepository repository,
+				List<LfsObject> objects) {
+			super(repository, objects);
+		}
+
+		@Override
+		Body process() throws IOException {
+			Response.Body body = new Response.Body();
+			if (objects.size() > 0) {
+				body.objects = new ArrayList<>();
+				for (LfsObject o : objects) {
+					addObjectInfo(body, o);
+				}
+			}
+			return body;
+		}
+
+		private void addObjectInfo(Response.Body body, LfsObject o)
+				throws IOException {
+			Response.ObjectInfo info = new Response.ObjectInfo();
+			body.objects.add(info);
+			info.oid = o.oid;
+			info.size = o.size;
+
+			LongObjectId oid = LongObjectId.fromString(o.oid);
+			if (repository.getSize(oid) == -1) {
+				info.actions = new HashMap<>();
+				info.actions.put(UPLOAD,
+						repository.getUploadAction(oid, o.size));
+				Action verify = repository.getVerifyAction(oid);
+				if (verify != null) {
+					info.actions.put(VERIFY, verify);
+				}
+			}
+		}
+	}
+
+	private static class Download extends TransferHandler {
+		Download(LargeFileRepository repository,
+				List<LfsObject> objects) {
+			super(repository, objects);
+		}
+
+		@Override
+		Body process() throws IOException {
+			Response.Body body = new Response.Body();
+			if (objects.size() > 0) {
+				body.objects = new ArrayList<>();
+				for (LfsObject o : objects) {
+					addObjectInfo(body, o);
+				}
+			}
+			return body;
+		}
+
+		private void addObjectInfo(Response.Body body, LfsObject o)
+				throws IOException {
+			Response.ObjectInfo info = new Response.ObjectInfo();
+			body.objects.add(info);
+			info.oid = o.oid;
+			info.size = o.size;
+
+			LongObjectId oid = LongObjectId.fromString(o.oid);
+			if (repository.getSize(oid) >= 0) {
+				info.actions = new HashMap<>();
+				info.actions.put(DOWNLOAD,
+						repository.getDownloadAction(oid));
+			} else {
+				info.error = new Response.Error();
+				info.error.code = SC_NOT_FOUND;
+				info.error.message = MessageFormat.format(
+						LfsServerText.get().objectNotFound,
+						oid.getName());
+			}
+		}
+	}
+
+	final LargeFileRepository repository;
+
+	final List<LfsObject> objects;
+
+	TransferHandler(LargeFileRepository repository,
+			List<LfsObject> objects) {
+		this.repository = repository;
+		this.objects = objects;
+	}
+
+	abstract Response.Body process() throws IOException;
+}
\ No newline at end of file
diff --git a/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/fs/AtomicObjectOutputStream.java b/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/fs/AtomicObjectOutputStream.java
new file mode 100644
index 0000000..ecc7c1f
--- /dev/null
+++ b/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/fs/AtomicObjectOutputStream.java
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2015, Matthias Sohn <matthias.sohn@sap.com>
+ * 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.lfs.server.fs;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.nio.file.Path;
+import java.security.DigestOutputStream;
+import java.text.MessageFormat;
+
+import org.eclipse.jgit.internal.storage.file.LockFile;
+import org.eclipse.jgit.lfs.errors.CorruptLongObjectException;
+import org.eclipse.jgit.lfs.lib.AnyLongObjectId;
+import org.eclipse.jgit.lfs.lib.Constants;
+import org.eclipse.jgit.lfs.lib.LongObjectId;
+import org.eclipse.jgit.lfs.server.internal.LfsServerText;
+
+/**
+ * Output stream writing content to a {@link LockFile} which is committed on
+ * close(). The stream checks if the hash of the stream content matches the
+ * id.
+ */
+class AtomicObjectOutputStream extends OutputStream {
+
+	private LockFile locked;
+
+	private DigestOutputStream out;
+
+	private boolean aborted;
+
+	private AnyLongObjectId id;
+
+	AtomicObjectOutputStream(Path path, AnyLongObjectId id)
+			throws IOException {
+		locked = new LockFile(path.toFile());
+		locked.lock();
+		this.id = id;
+		out = new DigestOutputStream(locked.getOutputStream(),
+				Constants.newMessageDigest());
+	}
+
+	@Override
+	public void write(int b) throws IOException {
+		out.write(b);
+	}
+
+	@Override
+	public void write(byte[] b) throws IOException {
+		out.write(b);
+	}
+
+	@Override
+	public void write(byte[] b, int off, int len) throws IOException {
+		out.write(b, off, len);
+	}
+
+	@Override
+	public void close() throws IOException {
+		out.close();
+		if (!aborted) {
+			verifyHash();
+			locked.commit();
+		}
+	}
+
+	private void verifyHash() {
+		AnyLongObjectId contentHash = LongObjectId
+				.fromRaw(out.getMessageDigest().digest());
+		if (!contentHash.equals(id)) {
+			abort();
+			throw new CorruptLongObjectException(id, contentHash,
+					MessageFormat.format(LfsServerText.get().corruptLongObject,
+							contentHash, id));
+		}
+	}
+
+	void abort() {
+		locked.unlock();
+		aborted = true;
+	}
+}
\ No newline at end of file
diff --git a/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/fs/FileLfsRepository.java b/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/fs/FileLfsRepository.java
new file mode 100644
index 0000000..12da271
--- /dev/null
+++ b/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/fs/FileLfsRepository.java
@@ -0,0 +1,185 @@
+/*
+ * Copyright (C) 2015, Matthias Sohn <matthias.sohn@sap.com>
+ * 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.lfs.server.fs;
+
+import static org.eclipse.jgit.util.HttpSupport.HDR_AUTHORIZATION;
+
+import java.io.IOException;
+import java.nio.channels.Channels;
+import java.nio.channels.FileChannel;
+import java.nio.channels.ReadableByteChannel;
+import java.nio.channels.WritableByteChannel;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.StandardOpenOption;
+import java.util.Collections;
+
+import org.eclipse.jgit.annotations.Nullable;
+import org.eclipse.jgit.lfs.lib.AnyLongObjectId;
+import org.eclipse.jgit.lfs.lib.Constants;
+import org.eclipse.jgit.lfs.server.LargeFileRepository;
+import org.eclipse.jgit.lfs.server.Response;
+import org.eclipse.jgit.lfs.server.Response.Action;
+
+/**
+ * Repository storing large objects in the file system
+ *
+ * @since 4.3
+ */
+public class FileLfsRepository implements LargeFileRepository {
+
+	private final String url;
+	private final Path dir;
+	private AtomicObjectOutputStream out;
+
+	/**
+	 * @param url
+	 *            external URL of this repository
+	 * @param dir
+	 *            storage directory
+	 * @throws IOException
+	 */
+	public FileLfsRepository(String url, Path dir) throws IOException {
+		this.url = url;
+		this.dir = dir;
+		Files.createDirectories(dir);
+	}
+
+	@Override
+	public Response.Action getDownloadAction(AnyLongObjectId id) {
+		return getAction(id);
+	}
+
+	@Override
+	public Action getUploadAction(AnyLongObjectId id, long size) {
+		return getAction(id);
+	}
+
+	@Override
+	public @Nullable Action getVerifyAction(AnyLongObjectId id) {
+		return null;
+	}
+
+	@Override
+	public long getSize(AnyLongObjectId id) throws IOException {
+		Path p = getPath(id);
+		if (Files.exists(p)) {
+			return Files.size(p);
+		} else {
+			return -1;
+		}
+	}
+
+	/**
+	 * Get the storage directory
+	 *
+	 * @return the path of the storage directory
+	 */
+	public Path getDir() {
+		return dir;
+	}
+
+	/**
+	 * Get the path where the given object is stored
+	 *
+	 * @param id
+	 *            id of a large object
+	 * @return path the object's storage path
+	 */
+	protected Path getPath(AnyLongObjectId id) {
+		StringBuilder s = new StringBuilder(
+				Constants.LONG_OBJECT_ID_STRING_LENGTH + 6);
+		s.append(toHexCharArray(id.getFirstByte())).append('/');
+		s.append(toHexCharArray(id.getSecondByte())).append('/');
+		s.append(id.name());
+		return dir.resolve(s.toString());
+	}
+
+	private Response.Action getAction(AnyLongObjectId id) {
+		Response.Action a = new Response.Action();
+		a.href = url + id.getName();
+		a.header = Collections.singletonMap(HDR_AUTHORIZATION, "not:required"); //$NON-NLS-1$
+		return a;
+	}
+
+	ReadableByteChannel getReadChannel(AnyLongObjectId id)
+			throws IOException {
+		return FileChannel.open(getPath(id), StandardOpenOption.READ);
+	}
+
+	WritableByteChannel getWriteChannel(AnyLongObjectId id)
+			throws IOException {
+		Path path = getPath(id);
+		Files.createDirectories(path.getParent());
+		out = new AtomicObjectOutputStream(path, id);
+		return Channels.newChannel(out);
+	}
+
+	/**
+	 * Abort the output stream
+	 */
+	void abortWrite() {
+		if (out != null) {
+			out.abort();
+		}
+	}
+
+	private static char[] toHexCharArray(int b) {
+		final char[] dst = new char[2];
+		formatHexChar(dst, 0, b);
+		return dst;
+	}
+
+	private static final char[] hexchar = { '0', '1', '2', '3', '4', '5', '6',
+			'7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
+
+	private static void formatHexChar(final char[] dst, final int p, int b) {
+		int o = p + 1;
+		while (o >= p && b != 0) {
+			dst[o--] = hexchar[b & 0xf];
+			b >>>= 4;
+		}
+		while (o >= p)
+			dst[o--] = '0';
+	}
+}
diff --git a/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/fs/FileLfsServlet.java b/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/fs/FileLfsServlet.java
new file mode 100644
index 0000000..8864af8
--- /dev/null
+++ b/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/fs/FileLfsServlet.java
@@ -0,0 +1,167 @@
+/*
+ * Copyright (C) 2015, Matthias Sohn <matthias.sohn@sap.com>
+ * 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.lfs.server.fs;
+
+import java.io.IOException;
+import java.text.MessageFormat;
+
+import javax.servlet.AsyncContext;
+import javax.servlet.ServletException;
+import javax.servlet.annotation.WebServlet;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.http.HttpStatus;
+import org.eclipse.jgit.lfs.errors.InvalidLongObjectIdException;
+import org.eclipse.jgit.lfs.lib.AnyLongObjectId;
+import org.eclipse.jgit.lfs.lib.Constants;
+import org.eclipse.jgit.lfs.lib.LongObjectId;
+import org.eclipse.jgit.lfs.server.internal.LfsServerText;
+
+/**
+ * Servlet supporting upload and download of large objects as defined by the
+ * GitHub Large File Storage extension API extending git to allow separate
+ * storage of large files
+ * (https://github.com/github/git-lfs/tree/master/docs/api).
+ *
+ * @since 4.3
+ */
+@WebServlet(asyncSupported = true)
+public class FileLfsServlet extends HttpServlet {
+
+	private static final long serialVersionUID = 1L;
+
+	private final FileLfsRepository repository;
+
+	private final long timeout;
+
+	/**
+	 * @param repository
+	 *            the repository storing the large objects
+	 * @param timeout
+	 *            timeout for object upload / download in milliseconds
+	 */
+	public FileLfsServlet(FileLfsRepository repository, long timeout) {
+		this.repository = repository;
+		this.timeout = timeout;
+	}
+
+	/**
+	 * Handles object downloads
+	 *
+	 * @param req
+	 *            servlet request
+	 * @param rsp
+	 *            servlet response
+	 * @throws ServletException
+	 *             if a servlet-specific error occurs
+	 * @throws IOException
+	 *             if an I/O error occurs
+	 */
+	@Override
+	protected void doGet(HttpServletRequest req,
+			HttpServletResponse rsp) throws ServletException, IOException {
+		AnyLongObjectId obj = getObjectToTransfer(req, rsp);
+		if (obj != null) {
+			if (repository.getSize(obj) == -1) {
+				sendError(rsp, HttpStatus.SC_NOT_FOUND, MessageFormat
+						.format(LfsServerText.get().objectNotFound, obj));
+				return;
+			}
+			AsyncContext context = req.startAsync();
+			context.setTimeout(timeout);
+			rsp.getOutputStream()
+					.setWriteListener(new ObjectDownloadListener(repository,
+							context, rsp, obj));
+		}
+	}
+
+	private AnyLongObjectId getObjectToTransfer(HttpServletRequest req,
+			HttpServletResponse rsp) throws IOException {
+		String info = req.getPathInfo();
+		if (info.length() != 1 + Constants.LONG_OBJECT_ID_STRING_LENGTH) {
+			sendError(rsp, HttpStatus.SC_BAD_REQUEST, MessageFormat
+					.format(LfsServerText.get().invalidPathInfo, info));
+			return null;
+		}
+		try {
+			return LongObjectId.fromString(info.substring(1, 65));
+		} catch (InvalidLongObjectIdException e) {
+			sendError(rsp, HttpStatus.SC_BAD_REQUEST, e.getMessage());
+			return null;
+		}
+	}
+
+	/**
+	 * Handle object uploads
+	 *
+	 * @param req
+	 *            servlet request
+	 * @param rsp
+	 *            servlet response
+	 * @throws ServletException
+	 *             if a servlet-specific error occurs
+	 * @throws IOException
+	 *             if an I/O error occurs
+	 */
+	@Override
+	protected void doPut(HttpServletRequest req,
+			HttpServletResponse rsp) throws ServletException, IOException {
+		AnyLongObjectId id = getObjectToTransfer(req, rsp);
+		if (id != null) {
+			AsyncContext context = req.startAsync();
+			context.setTimeout(timeout);
+			req.getInputStream().setReadListener(new ObjectUploadListener(
+					repository, context, req, rsp, id));
+		}
+	}
+
+	static void sendError(HttpServletResponse rsp, int status, String message)
+			throws IOException {
+		rsp.setStatus(status);
+		// TODO return message in response body in json format as specified in
+		// https://github.com/github/git-lfs/blob/master/docs/api/http-v1-batch.md
+		rsp.flushBuffer();
+	}
+}
diff --git a/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/fs/ObjectDownloadListener.java b/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/fs/ObjectDownloadListener.java
new file mode 100644
index 0000000..bfdea4f
--- /dev/null
+++ b/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/fs/ObjectDownloadListener.java
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2015, Matthias Sohn <matthias.sohnk@sap.com>
+ * 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.lfs.server.fs;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.channels.Channels;
+import java.nio.channels.ReadableByteChannel;
+import java.nio.channels.WritableByteChannel;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.servlet.AsyncContext;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.WriteListener;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.http.HttpStatus;
+import org.eclipse.jgit.lfs.lib.AnyLongObjectId;
+import org.eclipse.jgit.lfs.lib.Constants;
+import org.eclipse.jgit.util.HttpSupport;
+
+/**
+ * Handle asynchronous large object download
+ */
+class ObjectDownloadListener implements WriteListener {
+
+	private static Logger LOG = Logger
+			.getLogger(ObjectDownloadListener.class.getName());
+
+	private final AsyncContext context;
+
+	private final HttpServletResponse response;
+
+	private final ServletOutputStream out;
+
+	private final ReadableByteChannel in;
+
+	private final WritableByteChannel outChannel;
+
+	private final ByteBuffer buffer = ByteBuffer.allocateDirect(8192);
+
+	/**
+	 * @param repository
+	 *            the repository storing large objects
+	 * @param context
+	 *            the servlet asynchronous context
+	 * @param response
+	 *            the servlet response
+	 * @param id
+	 *            id of the object to be downloaded
+	 * @throws IOException
+	 */
+	public ObjectDownloadListener(FileLfsRepository repository,
+			AsyncContext context, HttpServletResponse response,
+			AnyLongObjectId id) throws IOException {
+		this.context = context;
+		this.response = response;
+		this.in = repository.getReadChannel(id);
+		this.out = response.getOutputStream();
+		this.outChannel = Channels.newChannel(out);
+
+		response.addHeader(HttpSupport.HDR_CONTENT_LENGTH,
+				String.valueOf(repository.getSize(id)));
+		response.setContentType(Constants.HDR_APPLICATION_OCTET_STREAM);
+	}
+
+	/**
+	 * Write file content
+	 *
+	 * @throws IOException
+	 */
+	@Override
+	public void onWritePossible() throws IOException {
+		while (out.isReady()) {
+			if (in.read(buffer) != -1) {
+				buffer.flip();
+				outChannel.write(buffer);
+				buffer.compact();
+			} else {
+				in.close();
+				buffer.flip();
+				while (out.isReady()) {
+					if (buffer.hasRemaining()) {
+						outChannel.write(buffer);
+					} else {
+						context.complete();
+					}
+				}
+			}
+		}
+	}
+
+	/**
+	 * Handle errors
+	 *
+	 * @param e
+	 *            the cause
+	 */
+	@Override
+	public void onError(Throwable e) {
+		try {
+			FileLfsServlet.sendError(response,
+					HttpStatus.SC_INTERNAL_SERVER_ERROR, e.getMessage());
+			context.complete();
+			in.close();
+		} catch (IOException ex) {
+			LOG.log(Level.SEVERE, ex.getMessage(), ex);
+		}
+	}
+}
diff --git a/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/fs/ObjectUploadListener.java b/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/fs/ObjectUploadListener.java
new file mode 100644
index 0000000..05970ad
--- /dev/null
+++ b/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/fs/ObjectUploadListener.java
@@ -0,0 +1,176 @@
+/*
+ * Copyright (C) 2015, Matthias Sohn <matthias.sohnk@sap.com>
+ * 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.lfs.server.fs;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.channels.Channels;
+import java.nio.channels.ReadableByteChannel;
+import java.nio.channels.WritableByteChannel;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.servlet.AsyncContext;
+import javax.servlet.ReadListener;
+import javax.servlet.ServletInputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.http.HttpStatus;
+import org.eclipse.jgit.lfs.errors.CorruptLongObjectException;
+import org.eclipse.jgit.lfs.lib.AnyLongObjectId;
+import org.eclipse.jgit.lfs.lib.Constants;
+
+/**
+ * Handle asynchronous object upload
+ */
+class ObjectUploadListener implements ReadListener {
+
+	private static Logger LOG = Logger
+			.getLogger(ObjectUploadListener.class.getName());
+
+	private final AsyncContext context;
+
+	private final HttpServletResponse response;
+
+	private FileLfsRepository repository;
+
+	private final ServletInputStream in;
+
+	private final ReadableByteChannel inChannel;
+
+	private WritableByteChannel out;
+
+	private final ByteBuffer buffer = ByteBuffer.allocateDirect(8192);
+
+	/**
+	 * @param repository
+	 *            the repository storing large objects
+	 * @param context
+	 * @param request
+	 * @param response
+	 * @param id
+	 * @throws FileNotFoundException
+	 * @throws IOException
+	 */
+	public ObjectUploadListener(FileLfsRepository repository,
+			AsyncContext context, HttpServletRequest request,
+			HttpServletResponse response, AnyLongObjectId id)
+					throws FileNotFoundException, IOException {
+		this.repository = repository;
+		this.context = context;
+		this.response = response;
+		this.in = request.getInputStream();
+		this.inChannel = Channels.newChannel(in);
+		this.out = repository.getWriteChannel(id);
+		response.setContentType(Constants.CONTENT_TYPE_GIT_LFS_JSON);
+	}
+
+	/**
+	 * Writes all the received data to the output channel
+	 *
+	 * @throws IOException
+	 */
+	@Override
+	public void onDataAvailable() throws IOException {
+		while (in.isReady()) {
+			if (inChannel.read(buffer) > 0) {
+				buffer.flip();
+				out.write(buffer);
+				buffer.compact();
+			} else {
+				buffer.flip();
+				while (buffer.hasRemaining()) {
+					out.write(buffer);
+				}
+				close();
+				return;
+			}
+		}
+	}
+
+	/**
+	 * @throws IOException
+	 */
+	@Override
+	public void onAllDataRead() throws IOException {
+		close();
+	}
+
+	protected void close() throws IOException {
+		try {
+			inChannel.close();
+			out.close();
+			// TODO check if status 200 is ok for PUT request, HTTP foresees 204
+			// for successful PUT without response body
+			response.setStatus(HttpServletResponse.SC_OK);
+		} finally {
+			context.complete();
+		}
+	}
+
+	/**
+	 * @param e
+	 *            the exception that caused the problem
+	 */
+	@Override
+	public void onError(Throwable e) {
+		try {
+			repository.abortWrite();
+			inChannel.close();
+			out.close();
+			int status;
+			if (e instanceof CorruptLongObjectException) {
+				status = HttpStatus.SC_BAD_REQUEST;
+				LOG.log(Level.WARNING, e.getMessage(), e);
+			} else {
+				status = HttpStatus.SC_INTERNAL_SERVER_ERROR;
+				LOG.log(Level.SEVERE, e.getMessage(), e);
+			}
+			FileLfsServlet.sendError(response, status, e.getMessage());
+		} catch (IOException ex) {
+			LOG.log(Level.SEVERE, ex.getMessage(), ex);
+		}
+	}
+}
\ No newline at end of file
diff --git a/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/internal/LfsServerText.java b/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/internal/LfsServerText.java
new file mode 100644
index 0000000..4e1c4c6
--- /dev/null
+++ b/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/internal/LfsServerText.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2015, Matthias Sohn <matthias.sohn@sap.com>
+ * 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.lfs.server.internal;
+
+import org.eclipse.jgit.nls.NLS;
+import org.eclipse.jgit.nls.TranslationBundle;
+
+/**
+ * Translation bundle for JGit LFS server
+ */
+public class LfsServerText extends TranslationBundle {
+
+	/**
+	 * @return an instance of this translation bundle
+	 */
+	public static LfsServerText get() {
+		return NLS.getBundleFor(LfsServerText.class);
+	}
+
+	// @formatter:off
+	/***/ public String corruptLongObject;
+	/***/ public String invalidPathInfo;
+	/***/ public String objectNotFound;
+	/***/ public String unsupportedOperation;
+}
diff --git a/org.eclipse.jgit.lfs.test/.classpath b/org.eclipse.jgit.lfs.test/.classpath
new file mode 100644
index 0000000..efc781d
--- /dev/null
+++ b/org.eclipse.jgit.lfs.test/.classpath
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="src" path="tst"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/org.eclipse.jgit.lfs.test/.gitignore b/org.eclipse.jgit.lfs.test/.gitignore
new file mode 100644
index 0000000..4dc0091
--- /dev/null
+++ b/org.eclipse.jgit.lfs.test/.gitignore
@@ -0,0 +1,2 @@
+/target
+/bin
diff --git a/org.eclipse.jgit.lfs.test/.project b/org.eclipse.jgit.lfs.test/.project
new file mode 100644
index 0000000..c5dddb0
--- /dev/null
+++ b/org.eclipse.jgit.lfs.test/.project
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.jgit.lfs.test</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ManifestBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.SchemaBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.api.tools.apiAnalysisBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.PluginNature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>org.eclipse.pde.api.tools.apiAnalysisNature</nature>
+	</natures>
+</projectDescription>
diff --git a/org.eclipse.jgit.lfs.test/.settings/org.eclipse.core.resources.prefs b/org.eclipse.jgit.lfs.test/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 0000000..4824b80
--- /dev/null
+++ b/org.eclipse.jgit.lfs.test/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1

+encoding/<project>=UTF-8

diff --git a/org.eclipse.jgit.lfs.test/.settings/org.eclipse.core.runtime.prefs b/org.eclipse.jgit.lfs.test/.settings/org.eclipse.core.runtime.prefs
new file mode 100644
index 0000000..5a0ad22
--- /dev/null
+++ b/org.eclipse.jgit.lfs.test/.settings/org.eclipse.core.runtime.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+line.separator=\n
diff --git a/org.eclipse.jgit.lfs.test/.settings/org.eclipse.jdt.core.prefs b/org.eclipse.jgit.lfs.test/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..dcc0d3a
--- /dev/null
+++ b/org.eclipse.jgit.lfs.test/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,398 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.annotation.inheritNullAnnotations=disabled
+org.eclipse.jdt.core.compiler.annotation.missingNonNullByDefaultAnnotation=ignore
+org.eclipse.jdt.core.compiler.annotation.nonnull=org.eclipse.jdt.annotation.NonNull
+org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=org.eclipse.jdt.annotation.NonNullByDefault
+org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nullable
+org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.7
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.doc.comment.support=enabled
+org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.autoboxing=warning
+org.eclipse.jdt.core.compiler.problem.comparingIdentical=error
+org.eclipse.jdt.core.compiler.problem.deadCode=error
+org.eclipse.jdt.core.compiler.problem.deprecation=warning
+org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
+org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
+org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
+org.eclipse.jdt.core.compiler.problem.emptyStatement=warning
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=ignore
+org.eclipse.jdt.core.compiler.problem.fallthroughCase=warning
+org.eclipse.jdt.core.compiler.problem.fatalOptionalError=disabled
+org.eclipse.jdt.core.compiler.problem.fieldHiding=warning
+org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
+org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=error
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=error
+org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=error
+org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=enabled
+org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
+org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=warning
+org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=error
+org.eclipse.jdt.core.compiler.problem.invalidJavadoc=error
+org.eclipse.jdt.core.compiler.problem.invalidJavadocTags=enabled
+org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsDeprecatedRef=enabled
+org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsNotVisibleRef=enabled
+org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsVisibility=private
+org.eclipse.jdt.core.compiler.problem.localVariableHiding=warning
+org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=error
+org.eclipse.jdt.core.compiler.problem.missingDefaultCase=ignore
+org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore
+org.eclipse.jdt.core.compiler.problem.missingEnumCaseDespiteDefault=disabled
+org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=error
+org.eclipse.jdt.core.compiler.problem.missingJavadocComments=ignore
+org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsVisibility=protected
+org.eclipse.jdt.core.compiler.problem.missingJavadocTagDescription=return_tag
+org.eclipse.jdt.core.compiler.problem.missingJavadocTags=error
+org.eclipse.jdt.core.compiler.problem.missingJavadocTagsMethodTypeParameters=disabled
+org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility=private
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled
+org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
+org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore
+org.eclipse.jdt.core.compiler.problem.noEffectAssignment=error
+org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=error
+org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore
+org.eclipse.jdt.core.compiler.problem.nonnullParameterAnnotationDropped=warning
+org.eclipse.jdt.core.compiler.problem.nullAnnotationInferenceConflict=error
+org.eclipse.jdt.core.compiler.problem.nullReference=error
+org.eclipse.jdt.core.compiler.problem.nullSpecViolation=error
+org.eclipse.jdt.core.compiler.problem.nullUncheckedConversion=warning
+org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
+org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=error
+org.eclipse.jdt.core.compiler.problem.potentialNullReference=warning
+org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable=ignore
+org.eclipse.jdt.core.compiler.problem.rawTypeReference=ignore
+org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning
+org.eclipse.jdt.core.compiler.problem.redundantNullCheck=warning
+org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore
+org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=error
+org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore
+org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore
+org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
+org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=error
+org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled
+org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
+org.eclipse.jdt.core.compiler.problem.syntacticNullAnalysisForFields=disabled
+org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
+org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
+org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=enabled
+org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
+org.eclipse.jdt.core.compiler.problem.unclosedCloseable=warning
+org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=warning
+org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
+org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=error
+org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=error
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.unusedImport=error
+org.eclipse.jdt.core.compiler.problem.unusedLabel=error
+org.eclipse.jdt.core.compiler.problem.unusedLocal=error
+org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=warning
+org.eclipse.jdt.core.compiler.problem.unusedParameter=warning
+org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
+org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=error
+org.eclipse.jdt.core.compiler.problem.unusedTypeParameter=ignore
+org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=error
+org.eclipse.jdt.core.compiler.source=1.7
+org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_assignment=0
+org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_compact_if=16
+org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80
+org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0
+org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16
+org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0
+org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16
+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80
+org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16
+org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=16
+org.eclipse.jdt.core.formatter.blank_lines_after_imports=1
+org.eclipse.jdt.core.formatter.blank_lines_after_package=1
+org.eclipse.jdt.core.formatter.blank_lines_before_field=1
+org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0
+org.eclipse.jdt.core.formatter.blank_lines_before_imports=1
+org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1
+org.eclipse.jdt.core.formatter.blank_lines_before_method=1
+org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1
+org.eclipse.jdt.core.formatter.blank_lines_before_package=0
+org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1
+org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1
+org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines=false
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false
+org.eclipse.jdt.core.formatter.comment.format_block_comments=true
+org.eclipse.jdt.core.formatter.comment.format_comments=true
+org.eclipse.jdt.core.formatter.comment.format_header=false
+org.eclipse.jdt.core.formatter.comment.format_html=true
+org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true
+org.eclipse.jdt.core.formatter.comment.format_line_comments=true
+org.eclipse.jdt.core.formatter.comment.format_source_code=true
+org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true
+org.eclipse.jdt.core.formatter.comment.indent_root_tags=true
+org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert
+org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert
+org.eclipse.jdt.core.formatter.comment.line_length=80
+org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true
+org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true
+org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=false
+org.eclipse.jdt.core.formatter.compact_else_if=true
+org.eclipse.jdt.core.formatter.continuation_indentation=2
+org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2
+org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off
+org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on
+org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false
+org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true
+org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true
+org.eclipse.jdt.core.formatter.indent_empty_lines=false
+org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true
+org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true
+org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true
+org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false
+org.eclipse.jdt.core.formatter.indentation.size=4
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_member=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert
+org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert
+org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert
+org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert
+org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert
+org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert
+org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.join_lines_in_comments=true
+org.eclipse.jdt.core.formatter.join_wrapped_lines=true
+org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false
+org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false
+org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false
+org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false
+org.eclipse.jdt.core.formatter.lineSplit=80
+org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false
+org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false
+org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0
+org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1
+org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true
+org.eclipse.jdt.core.formatter.tabulation.char=tab
+org.eclipse.jdt.core.formatter.tabulation.size=4
+org.eclipse.jdt.core.formatter.use_on_off_tags=true
+org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false
+org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true
+org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true
+org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true
diff --git a/org.eclipse.jgit.lfs.test/.settings/org.eclipse.jdt.ui.prefs b/org.eclipse.jgit.lfs.test/.settings/org.eclipse.jdt.ui.prefs
new file mode 100644
index 0000000..c336cce
--- /dev/null
+++ b/org.eclipse.jgit.lfs.test/.settings/org.eclipse.jdt.ui.prefs
@@ -0,0 +1,61 @@
+eclipse.preferences.version=1
+editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
+formatter_profile=_JGit Format
+formatter_settings_version=12
+org.eclipse.jdt.ui.ignorelowercasenames=true
+org.eclipse.jdt.ui.importorder=java;javax;org;com;
+org.eclipse.jdt.ui.ondemandthreshold=99
+org.eclipse.jdt.ui.staticondemandthreshold=99
+org.eclipse.jdt.ui.text.custom_code_templates=<?xml version\="1.0" encoding\="UTF-8"?><templates/>
+sp_cleanup.add_default_serial_version_id=true
+sp_cleanup.add_generated_serial_version_id=false
+sp_cleanup.add_missing_annotations=false
+sp_cleanup.add_missing_deprecated_annotations=true
+sp_cleanup.add_missing_methods=false
+sp_cleanup.add_missing_nls_tags=false
+sp_cleanup.add_missing_override_annotations=true
+sp_cleanup.add_missing_override_annotations_interface_methods=false
+sp_cleanup.add_serial_version_id=false
+sp_cleanup.always_use_blocks=true
+sp_cleanup.always_use_parentheses_in_expressions=false
+sp_cleanup.always_use_this_for_non_static_field_access=false
+sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.correct_indentation=false
+sp_cleanup.format_source_code=true
+sp_cleanup.format_source_code_changes_only=true
+sp_cleanup.make_local_variable_final=false
+sp_cleanup.make_parameters_final=false
+sp_cleanup.make_private_fields_final=true
+sp_cleanup.make_type_abstract_if_missing_method=false
+sp_cleanup.make_variable_declarations_final=false
+sp_cleanup.never_use_blocks=false
+sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.organize_imports=false
+sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
+sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
+sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
+sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
+sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_trailing_whitespaces=true
+sp_cleanup.remove_trailing_whitespaces_all=true
+sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_casts=false
+sp_cleanup.remove_unnecessary_nls_tags=false
+sp_cleanup.remove_unused_imports=false
+sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_private_fields=true
+sp_cleanup.remove_unused_private_members=false
+sp_cleanup.remove_unused_private_methods=true
+sp_cleanup.remove_unused_private_types=true
+sp_cleanup.sort_members=false
+sp_cleanup.sort_members_all=false
+sp_cleanup.use_blocks=false
+sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_this_for_non_static_field_access=false
+sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
+sp_cleanup.use_this_for_non_static_method_access=false
+sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
diff --git a/org.eclipse.jgit.lfs.test/.settings/org.eclipse.mylyn.tasks.ui.prefs b/org.eclipse.jgit.lfs.test/.settings/org.eclipse.mylyn.tasks.ui.prefs
new file mode 100644
index 0000000..3dec4d9
--- /dev/null
+++ b/org.eclipse.jgit.lfs.test/.settings/org.eclipse.mylyn.tasks.ui.prefs
@@ -0,0 +1,3 @@
+eclipse.preferences.version=1
+project.repository.kind=bugzilla
+project.repository.url=https\://bugs.eclipse.org/bugs
diff --git a/org.eclipse.jgit.lfs.test/.settings/org.eclipse.mylyn.team.ui.prefs b/org.eclipse.jgit.lfs.test/.settings/org.eclipse.mylyn.team.ui.prefs
new file mode 100644
index 0000000..ce7a0f0
--- /dev/null
+++ b/org.eclipse.jgit.lfs.test/.settings/org.eclipse.mylyn.team.ui.prefs
@@ -0,0 +1,2 @@
+commit.comment.template=${task.description} \n\nBug\: ${task.key}
+eclipse.preferences.version=1
diff --git a/org.eclipse.jgit.lfs.test/.settings/org.eclipse.pde.api.tools.prefs b/org.eclipse.jgit.lfs.test/.settings/org.eclipse.pde.api.tools.prefs
new file mode 100644
index 0000000..d585687
--- /dev/null
+++ b/org.eclipse.jgit.lfs.test/.settings/org.eclipse.pde.api.tools.prefs
@@ -0,0 +1,93 @@
+ANNOTATION_ELEMENT_TYPE_ADDED_METHOD_WITHOUT_DEFAULT_VALUE=Error
+ANNOTATION_ELEMENT_TYPE_CHANGED_TYPE_CONVERSION=Error
+ANNOTATION_ELEMENT_TYPE_REMOVED_FIELD=Error
+ANNOTATION_ELEMENT_TYPE_REMOVED_METHOD=Error
+ANNOTATION_ELEMENT_TYPE_REMOVED_TYPE_MEMBER=Error
+API_COMPONENT_ELEMENT_TYPE_REMOVED_API_TYPE=Error
+API_COMPONENT_ELEMENT_TYPE_REMOVED_REEXPORTED_API_TYPE=Error
+API_COMPONENT_ELEMENT_TYPE_REMOVED_REEXPORTED_TYPE=Error
+API_COMPONENT_ELEMENT_TYPE_REMOVED_TYPE=Error
+CLASS_ELEMENT_TYPE_ADDED_METHOD=Error
+CLASS_ELEMENT_TYPE_ADDED_RESTRICTIONS=Error
+CLASS_ELEMENT_TYPE_ADDED_TYPE_PARAMETER=Error
+CLASS_ELEMENT_TYPE_CHANGED_CONTRACTED_SUPERINTERFACES_SET=Error
+CLASS_ELEMENT_TYPE_CHANGED_DECREASE_ACCESS=Error
+CLASS_ELEMENT_TYPE_CHANGED_NON_ABSTRACT_TO_ABSTRACT=Error
+CLASS_ELEMENT_TYPE_CHANGED_NON_FINAL_TO_FINAL=Error
+CLASS_ELEMENT_TYPE_CHANGED_TYPE_CONVERSION=Error
+CLASS_ELEMENT_TYPE_REMOVED_CONSTRUCTOR=Error
+CLASS_ELEMENT_TYPE_REMOVED_FIELD=Error
+CLASS_ELEMENT_TYPE_REMOVED_METHOD=Error
+CLASS_ELEMENT_TYPE_REMOVED_SUPERCLASS=Error
+CLASS_ELEMENT_TYPE_REMOVED_TYPE_MEMBER=Error
+CLASS_ELEMENT_TYPE_REMOVED_TYPE_PARAMETER=Error
+CONSTRUCTOR_ELEMENT_TYPE_ADDED_TYPE_PARAMETER=Error
+CONSTRUCTOR_ELEMENT_TYPE_CHANGED_DECREASE_ACCESS=Error
+CONSTRUCTOR_ELEMENT_TYPE_CHANGED_VARARGS_TO_ARRAY=Error
+CONSTRUCTOR_ELEMENT_TYPE_REMOVED_TYPE_PARAMETER=Error
+ENUM_ELEMENT_TYPE_CHANGED_CONTRACTED_SUPERINTERFACES_SET=Error
+ENUM_ELEMENT_TYPE_CHANGED_TYPE_CONVERSION=Error
+ENUM_ELEMENT_TYPE_REMOVED_ENUM_CONSTANT=Error
+ENUM_ELEMENT_TYPE_REMOVED_FIELD=Error
+ENUM_ELEMENT_TYPE_REMOVED_METHOD=Error
+ENUM_ELEMENT_TYPE_REMOVED_TYPE_MEMBER=Error
+FIELD_ELEMENT_TYPE_ADDED_VALUE=Error
+FIELD_ELEMENT_TYPE_CHANGED_DECREASE_ACCESS=Error
+FIELD_ELEMENT_TYPE_CHANGED_FINAL_TO_NON_FINAL_STATIC_CONSTANT=Error
+FIELD_ELEMENT_TYPE_CHANGED_NON_FINAL_TO_FINAL=Error
+FIELD_ELEMENT_TYPE_CHANGED_NON_STATIC_TO_STATIC=Error
+FIELD_ELEMENT_TYPE_CHANGED_STATIC_TO_NON_STATIC=Error
+FIELD_ELEMENT_TYPE_CHANGED_TYPE=Error
+FIELD_ELEMENT_TYPE_CHANGED_VALUE=Error
+FIELD_ELEMENT_TYPE_REMOVED_TYPE_ARGUMENT=Error
+FIELD_ELEMENT_TYPE_REMOVED_VALUE=Error
+ILLEGAL_EXTEND=Warning
+ILLEGAL_IMPLEMENT=Warning
+ILLEGAL_INSTANTIATE=Warning
+ILLEGAL_OVERRIDE=Warning
+ILLEGAL_REFERENCE=Warning
+INTERFACE_ELEMENT_TYPE_ADDED_FIELD=Error
+INTERFACE_ELEMENT_TYPE_ADDED_METHOD=Error
+INTERFACE_ELEMENT_TYPE_ADDED_RESTRICTIONS=Error
+INTERFACE_ELEMENT_TYPE_ADDED_SUPER_INTERFACE_WITH_METHODS=Error
+INTERFACE_ELEMENT_TYPE_ADDED_TYPE_PARAMETER=Error
+INTERFACE_ELEMENT_TYPE_CHANGED_CONTRACTED_SUPERINTERFACES_SET=Error
+INTERFACE_ELEMENT_TYPE_CHANGED_TYPE_CONVERSION=Error
+INTERFACE_ELEMENT_TYPE_REMOVED_FIELD=Error
+INTERFACE_ELEMENT_TYPE_REMOVED_METHOD=Error
+INTERFACE_ELEMENT_TYPE_REMOVED_TYPE_MEMBER=Error
+INTERFACE_ELEMENT_TYPE_REMOVED_TYPE_PARAMETER=Error
+INVALID_JAVADOC_TAG=Ignore
+INVALID_REFERENCE_IN_SYSTEM_LIBRARIES=Error
+LEAK_EXTEND=Warning
+LEAK_FIELD_DECL=Warning
+LEAK_IMPLEMENT=Warning
+LEAK_METHOD_PARAM=Warning
+LEAK_METHOD_RETURN_TYPE=Warning
+METHOD_ELEMENT_TYPE_ADDED_RESTRICTIONS=Error
+METHOD_ELEMENT_TYPE_ADDED_TYPE_PARAMETER=Error
+METHOD_ELEMENT_TYPE_CHANGED_DECREASE_ACCESS=Error
+METHOD_ELEMENT_TYPE_CHANGED_NON_ABSTRACT_TO_ABSTRACT=Error
+METHOD_ELEMENT_TYPE_CHANGED_NON_FINAL_TO_FINAL=Error
+METHOD_ELEMENT_TYPE_CHANGED_NON_STATIC_TO_STATIC=Error
+METHOD_ELEMENT_TYPE_CHANGED_STATIC_TO_NON_STATIC=Error
+METHOD_ELEMENT_TYPE_CHANGED_VARARGS_TO_ARRAY=Error
+METHOD_ELEMENT_TYPE_REMOVED_ANNOTATION_DEFAULT_VALUE=Error
+METHOD_ELEMENT_TYPE_REMOVED_TYPE_PARAMETER=Error
+TYPE_PARAMETER_ELEMENT_TYPE_ADDED_CLASS_BOUND=Error
+TYPE_PARAMETER_ELEMENT_TYPE_ADDED_INTERFACE_BOUND=Error
+TYPE_PARAMETER_ELEMENT_TYPE_CHANGED_CLASS_BOUND=Error
+TYPE_PARAMETER_ELEMENT_TYPE_CHANGED_INTERFACE_BOUND=Error
+TYPE_PARAMETER_ELEMENT_TYPE_REMOVED_CLASS_BOUND=Error
+TYPE_PARAMETER_ELEMENT_TYPE_REMOVED_INTERFACE_BOUND=Error
+UNUSED_PROBLEM_FILTERS=Warning
+automatically_removed_unused_problem_filters=false
+eclipse.preferences.version=1
+incompatible_api_component_version=Error
+incompatible_api_component_version_include_major_without_breaking_change=Disabled
+incompatible_api_component_version_include_minor_without_api_change=Disabled
+invalid_since_tag_version=Error
+malformed_since_tag=Error
+missing_since_tag=Error
+report_api_breakage_when_major_version_incremented=Disabled
+report_resolution_errors_api_component=Warning
diff --git a/org.eclipse.jgit.lfs.test/.settings/org.eclipse.pde.core.prefs b/org.eclipse.jgit.lfs.test/.settings/org.eclipse.pde.core.prefs
new file mode 100644
index 0000000..923c37f
--- /dev/null
+++ b/org.eclipse.jgit.lfs.test/.settings/org.eclipse.pde.core.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+resolve.requirebundle=false
diff --git a/org.eclipse.jgit.lfs.test/BUCK b/org.eclipse.jgit.lfs.test/BUCK
new file mode 100644
index 0000000..d0fb96f
--- /dev/null
+++ b/org.eclipse.jgit.lfs.test/BUCK
@@ -0,0 +1,31 @@
+TESTS = glob(['tst/**/*.java'])
+
+for t in TESTS:
+  n = t[len('tst/'):len(t)-len('.java')].replace('/', '.')
+  java_test(
+    name = n,
+    labels = ['lfs'],
+    srcs = [t],
+    deps = [
+      ':helpers',
+      '//org.eclipse.jgit.junit:junit',
+      '//org.eclipse.jgit.lfs:jgit-lfs',
+      '//org.eclipse.jgit:jgit',
+      '//lib:hamcrest-core',
+      '//lib:hamcrest-library',
+      '//lib:junit',
+    ],
+    source_under_test = ['//org.eclipse.jgit.lfs:jgit-lfs'],
+  )
+
+java_library(
+  name = 'helpers',
+  srcs = glob(['src/**/*.java']),
+  deps = [
+    '//org.eclipse.jgit:jgit',
+    '//org.eclipse.jgit.lfs:jgit-lfs',
+    '//org.eclipse.jgit.junit:junit',
+    '//lib:junit',
+  ],
+  visibility = ['PUBLIC']
+)
diff --git a/org.eclipse.jgit.lfs.test/META-INF/MANIFEST.MF b/org.eclipse.jgit.lfs.test/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..61456f1
--- /dev/null
+++ b/org.eclipse.jgit.lfs.test/META-INF/MANIFEST.MF
@@ -0,0 +1,20 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: %plugin_name
+Bundle-SymbolicName: org.eclipse.jgit.lfs.test
+Bundle-Version: 4.3.0.qualifier
+Bundle-Vendor: %provider_name
+Bundle-Localization: plugin
+Bundle-RequiredExecutionEnvironment: JavaSE-1.7
+Import-Package: org.eclipse.jgit.junit;version="[4.3.0,4.4.0)",
+ org.eclipse.jgit.lfs.errors;version="[4.3.0,4.4.0)",
+ org.eclipse.jgit.lfs.lib;version="[4.3.0,4.4.0)",
+ org.eclipse.jgit.lib;version="[4.3.0,4.4.0)",
+ org.eclipse.jgit.util;version="[4.3.0,4.4.0)",
+ org.hamcrest.core;version="[1.1.0,2.0.0)",
+ org.junit;version="[4.0.0,5.0.0)",
+ org.junit.runner;version="[4.0.0,5.0.0)",
+ org.junit.runners;version="[4.0.0,5.0.0)"
+Export-Package: org.eclipse.jgit.lfs.lib;version="4.3.0";x-internal:=true,
+ org.eclipse.jgit.lfs.test;version="4.3.0";x-friends:="org.eclipse.jgit.lfs.server.test"
+
diff --git a/org.eclipse.jgit.lfs.test/build.properties b/org.eclipse.jgit.lfs.test/build.properties
new file mode 100644
index 0000000..47ae091
--- /dev/null
+++ b/org.eclipse.jgit.lfs.test/build.properties
@@ -0,0 +1,5 @@
+source.. = tst/, src/
+output.. = bin/
+bin.includes = META-INF/,\
+               .,\
+               plugin.properties
diff --git a/org.eclipse.jgit.lfs.test/plugin.properties b/org.eclipse.jgit.lfs.test/plugin.properties
new file mode 100644
index 0000000..f900780
--- /dev/null
+++ b/org.eclipse.jgit.lfs.test/plugin.properties
@@ -0,0 +1,2 @@
+plugin_name=JGit LFS Tests
+provider_name=Eclipse JGit
diff --git a/org.eclipse.jgit.lfs.test/pom.xml b/org.eclipse.jgit.lfs.test/pom.xml
new file mode 100644
index 0000000..ae72a80
--- /dev/null
+++ b/org.eclipse.jgit.lfs.test/pom.xml
@@ -0,0 +1,119 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+   Copyright (C) 2015 Matthias Sohn <matthias.sohn@sap.com>
+   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.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>org.eclipse.jgit</groupId>
+    <artifactId>org.eclipse.jgit-parent</artifactId>
+    <version>4.3.0-SNAPSHOT</version>
+  </parent>
+
+  <artifactId>org.eclipse.jgit.lfs.test</artifactId>
+  <name>JGit - Large File Storage Tests</name>
+
+  <description>
+    Tests for the Large File Extension (LFS).
+  </description>
+
+  <dependencies>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <scope>test</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>org.eclipse.jgit</groupId>
+      <artifactId>org.eclipse.jgit</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+
+    <dependency>
+      <groupId>org.eclipse.jgit</groupId>
+      <artifactId>org.eclipse.jgit.lfs</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+
+    <dependency>
+      <groupId>org.eclipse.jgit</groupId>
+      <artifactId>org.eclipse.jgit.junit</artifactId>
+      <version>${project.version}</version>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+
+  <build>
+    <testSourceDirectory>tst/</testSourceDirectory>
+    <sourceDirectory>src/</sourceDirectory>
+
+    <testResources>
+      <testResource>
+        <directory>tst-rsrc/</directory>
+      </testResource>
+    </testResources>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-jar-plugin</artifactId>
+        <executions>
+          <execution>
+            <goals>
+              <goal>test-jar</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <artifactId>maven-surefire-plugin</artifactId>
+        <configuration>
+          <argLine>-Djava.io.tmpdir=${project.build.directory}  -Xmx300m</argLine>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+</project>
diff --git a/org.eclipse.jgit.lfs.test/src/org/eclipse/jgit/lfs/test/LongObjectIdTestUtils.java b/org.eclipse.jgit.lfs.test/src/org/eclipse/jgit/lfs/test/LongObjectIdTestUtils.java
new file mode 100644
index 0000000..6c6400f
--- /dev/null
+++ b/org.eclipse.jgit.lfs.test/src/org/eclipse/jgit/lfs/test/LongObjectIdTestUtils.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2015, Matthias Sohn <matthias.sohn@sap.com>
+ * 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.lfs.test;
+
+import java.io.BufferedInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.security.MessageDigest;
+
+import org.eclipse.jgit.lfs.lib.Constants;
+import org.eclipse.jgit.lfs.lib.LongObjectId;
+
+public class LongObjectIdTestUtils {
+
+	/**
+	 * Create id as hash of the given string.
+	 *
+	 * @param s
+	 *            the string to hash
+	 * @return id calculated by hashing string
+	 */
+	public static LongObjectId hash(String s) {
+		MessageDigest md = Constants.newMessageDigest();
+		md.update(s.getBytes(StandardCharsets.UTF_8));
+		return LongObjectId.fromRaw(md.digest());
+	}
+
+	/**
+	 * Create id as hash of a file content
+	 *
+	 * @param file
+	 *            the file to hash
+	 * @return id calculated by hashing file content
+	 * @throws FileNotFoundException
+	 *             if file doesn't exist
+	 * @throws IOException
+	 */
+	public static LongObjectId hash(Path file)
+			throws FileNotFoundException, IOException {
+		MessageDigest md = Constants.newMessageDigest();
+		try (InputStream is = new BufferedInputStream(
+				Files.newInputStream(file))) {
+			final byte[] buffer = new byte[4096];
+			for (int read = 0; (read = is.read(buffer)) != -1;) {
+				md.update(buffer, 0, read);
+			}
+		}
+		return LongObjectId.fromRaw(md.digest());
+	}
+}
diff --git a/org.eclipse.jgit.lfs.test/tst/org/eclipse/jgit/lfs/lib/AbbreviatedLongObjectIdTest.java b/org.eclipse.jgit.lfs.test/tst/org/eclipse/jgit/lfs/lib/AbbreviatedLongObjectIdTest.java
new file mode 100644
index 0000000..8938a78
--- /dev/null
+++ b/org.eclipse.jgit.lfs.test/tst/org/eclipse/jgit/lfs/lib/AbbreviatedLongObjectIdTest.java
@@ -0,0 +1,596 @@
+/*
+ * Copyright (C) 2015, Matthias Sohn <matthias.sohn@sap.com>
+ * 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.lfs.lib;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import org.eclipse.jgit.lfs.test.LongObjectIdTestUtils;
+import org.junit.Test;
+
+/*
+ * Ported to SHA-256 from org.eclipse.jgit.lib.AbbreviatedObjectIdTest
+ */
+public class AbbreviatedLongObjectIdTest {
+	@Test
+	public void testEmpty_FromByteArray() {
+		final AbbreviatedLongObjectId i;
+		i = AbbreviatedLongObjectId.fromString(new byte[] {}, 0, 0);
+		assertNotNull(i);
+		assertEquals(0, i.length());
+		assertFalse(i.isComplete());
+		assertEquals("", i.name());
+	}
+
+	@Test
+	public void testEmpty_FromString() {
+		final AbbreviatedLongObjectId i = AbbreviatedLongObjectId
+				.fromString("");
+		assertNotNull(i);
+		assertEquals(0, i.length());
+		assertFalse(i.isComplete());
+		assertEquals("", i.name());
+	}
+
+	@Test
+	public void testFull_FromByteArray() {
+		final String s = "27e15b72937fc8f558da24ac3d50ec20302a4cf21e33b87ae8e4ce90e89c4b10";
+		final byte[] b = org.eclipse.jgit.lib.Constants.encodeASCII(s);
+		final AbbreviatedLongObjectId i = AbbreviatedLongObjectId.fromString(b,
+				0, b.length);
+		assertNotNull(i);
+		assertEquals(s.length(), i.length());
+		assertTrue(i.isComplete());
+		assertEquals(s, i.name());
+
+		final LongObjectId f = i.toLongObjectId();
+		assertNotNull(f);
+		assertEquals(LongObjectId.fromString(s), f);
+		assertEquals(f.hashCode(), i.hashCode());
+	}
+
+	@Test
+	public void testFull_FromString() {
+		final String s = "27e15b72937fc8f558da24ac3d50ec20302a4cf21e33b87ae8e4ce90e89c4b10";
+		final AbbreviatedLongObjectId i = AbbreviatedLongObjectId.fromString(s);
+		assertNotNull(i);
+		assertEquals(s.length(), i.length());
+		assertTrue(i.isComplete());
+		assertEquals(s, i.name());
+
+		final LongObjectId f = i.toLongObjectId();
+		assertNotNull(f);
+		assertEquals(LongObjectId.fromString(s), f);
+		assertEquals(f.hashCode(), i.hashCode());
+	}
+
+	@Test
+	public void test1_FromString() {
+		final String s = "2";
+		final AbbreviatedLongObjectId i = AbbreviatedLongObjectId.fromString(s);
+		assertNotNull(i);
+		assertEquals(s.length(), i.length());
+		assertFalse(i.isComplete());
+		assertEquals(s, i.name());
+		assertNull(i.toLongObjectId());
+	}
+
+	@Test
+	public void test2_FromString() {
+		final String s = "27";
+		final AbbreviatedLongObjectId i = AbbreviatedLongObjectId.fromString(s);
+		assertNotNull(i);
+		assertEquals(s.length(), i.length());
+		assertFalse(i.isComplete());
+		assertEquals(s, i.name());
+		assertNull(i.toLongObjectId());
+	}
+
+	@Test
+	public void test3_FromString() {
+		final String s = "27e";
+		final AbbreviatedLongObjectId i = AbbreviatedLongObjectId.fromString(s);
+		assertNotNull(i);
+		assertEquals(s.length(), i.length());
+		assertFalse(i.isComplete());
+		assertEquals(s, i.name());
+		assertNull(i.toLongObjectId());
+	}
+
+	@Test
+	public void test4_FromString() {
+		final String s = "27e1";
+		final AbbreviatedLongObjectId i = AbbreviatedLongObjectId.fromString(s);
+		assertNotNull(i);
+		assertEquals(s.length(), i.length());
+		assertFalse(i.isComplete());
+		assertEquals(s, i.name());
+		assertNull(i.toLongObjectId());
+	}
+
+	@Test
+	public void test5_FromString() {
+		final String s = "27e15";
+		final AbbreviatedLongObjectId i = AbbreviatedLongObjectId.fromString(s);
+		assertNotNull(i);
+		assertEquals(s.length(), i.length());
+		assertFalse(i.isComplete());
+		assertEquals(s, i.name());
+		assertNull(i.toLongObjectId());
+	}
+
+	@Test
+	public void test6_FromString() {
+		final String s = "27e15b";
+		final AbbreviatedLongObjectId i = AbbreviatedLongObjectId.fromString(s);
+		assertNotNull(i);
+		assertEquals(s.length(), i.length());
+		assertFalse(i.isComplete());
+		assertEquals(s, i.name());
+		assertNull(i.toLongObjectId());
+	}
+
+	@Test
+	public void test7_FromString() {
+		final String s = "27e15b7";
+		final AbbreviatedLongObjectId i = AbbreviatedLongObjectId.fromString(s);
+		assertNotNull(i);
+		assertEquals(s.length(), i.length());
+		assertFalse(i.isComplete());
+		assertEquals(s, i.name());
+		assertNull(i.toLongObjectId());
+	}
+
+	@Test
+	public void test8_FromString() {
+		final String s = "27e15b72";
+		final AbbreviatedLongObjectId i = AbbreviatedLongObjectId.fromString(s);
+		assertNotNull(i);
+		assertEquals(s.length(), i.length());
+		assertFalse(i.isComplete());
+		assertEquals(s, i.name());
+		assertNull(i.toLongObjectId());
+	}
+
+	@Test
+	public void test9_FromString() {
+		final String s = "27e15b729";
+		final AbbreviatedLongObjectId i = AbbreviatedLongObjectId.fromString(s);
+		assertNotNull(i);
+		assertEquals(s.length(), i.length());
+		assertFalse(i.isComplete());
+		assertEquals(s, i.name());
+		assertNull(i.toLongObjectId());
+	}
+
+	@Test
+	public void test15_FromString() {
+		final String s = "27e15b72937fc8f";
+		final AbbreviatedLongObjectId i = AbbreviatedLongObjectId.fromString(s);
+		assertNotNull(i);
+		assertEquals(s.length(), i.length());
+		assertFalse(i.isComplete());
+		assertEquals(s, i.name());
+		assertNull(i.toLongObjectId());
+	}
+
+	@Test
+	public void test16_FromString() {
+		final String s = "27e15b72937fc8f5";
+		final AbbreviatedLongObjectId i = AbbreviatedLongObjectId.fromString(s);
+		assertNotNull(i);
+		assertEquals(s.length(), i.length());
+		assertFalse(i.isComplete());
+		assertEquals(s, i.name());
+		assertNull(i.toLongObjectId());
+	}
+
+	@Test
+	public void test17_FromString() {
+		final String s = "27e15b72937fc8f55";
+		final AbbreviatedLongObjectId i = AbbreviatedLongObjectId.fromString(s);
+		assertNotNull(i);
+		assertEquals(s.length(), i.length());
+		assertFalse(i.isComplete());
+		assertEquals(s, i.name());
+		assertNull(i.toLongObjectId());
+	}
+
+	@Test
+	public void test33_FromString() {
+		final String s = "27e15b72937fc8f558da24ac3d50ec203";
+		final AbbreviatedLongObjectId i = AbbreviatedLongObjectId.fromString(s);
+		assertNotNull(i);
+		assertEquals(s.length(), i.length());
+		assertFalse(i.isComplete());
+		assertEquals(s, i.name());
+		assertNull(i.toLongObjectId());
+	}
+
+	@Test
+	public void testEquals_Short() {
+		final String s = "27e15b72";
+		final AbbreviatedLongObjectId a = AbbreviatedLongObjectId.fromString(s);
+		final AbbreviatedLongObjectId b = AbbreviatedLongObjectId.fromString(s);
+		assertNotSame(a, b);
+		assertTrue(a.hashCode() == b.hashCode());
+		assertEquals(b, a);
+		assertEquals(a, b);
+	}
+
+	@Test
+	public void testEquals_Full() {
+		final String s = "27e15b72937fc8f558da24ac3d50ec20302a4cf21e33b87ae8e4ce90e89c4b10";
+		final AbbreviatedLongObjectId a = AbbreviatedLongObjectId.fromString(s);
+		final AbbreviatedLongObjectId b = AbbreviatedLongObjectId.fromString(s);
+		assertNotSame(a, b);
+		assertTrue(a.hashCode() == b.hashCode());
+		assertEquals(b, a);
+		assertEquals(a, b);
+	}
+
+	@Test
+	public void testNotEquals_SameLength() {
+		final String sa = "27e15b72";
+		final String sb = "27e15b7f";
+		final AbbreviatedLongObjectId a = AbbreviatedLongObjectId
+				.fromString(sa);
+		final AbbreviatedLongObjectId b = AbbreviatedLongObjectId
+				.fromString(sb);
+		assertFalse(a.equals(b));
+		assertFalse(b.equals(a));
+	}
+
+	@Test
+	public void testNotEquals_DiffLength() {
+		final String sa = "27e15b72abcd";
+		final String sb = "27e15b72";
+		final AbbreviatedLongObjectId a = AbbreviatedLongObjectId
+				.fromString(sa);
+		final AbbreviatedLongObjectId b = AbbreviatedLongObjectId
+				.fromString(sb);
+		assertFalse(a.equals(b));
+		assertFalse(b.equals(a));
+	}
+
+	@Test
+	public void testPrefixCompare_Full() {
+		final String s1 = "27e15b72937fc8f558da24ac3d50ec20302a4cf21e33b87ae8e4ce90e89c4b10";
+		final AbbreviatedLongObjectId a = AbbreviatedLongObjectId
+				.fromString(s1);
+		final LongObjectId i1 = LongObjectId.fromString(s1);
+		assertEquals(0, a.prefixCompare(i1));
+		assertTrue(i1.startsWith(a));
+
+		final String s2 = "27e15b72937fc8f558da24ac3d50ec20302a4cf21e33b87ae8e4ce90e89c4b11";
+		final LongObjectId i2 = LongObjectId.fromString(s2);
+		assertTrue(a.prefixCompare(i2) < 0);
+		assertFalse(i2.startsWith(a));
+
+		final String s3 = "27e15b72937fc8f558da24ac3d50ec20302a4cf21e33b87ae8e4ce90e89c4b0f";
+		final LongObjectId i3 = LongObjectId.fromString(s3);
+		assertTrue(a.prefixCompare(i3) > 0);
+		assertFalse(i3.startsWith(a));
+	}
+
+	@Test
+	public void testPrefixCompare_1() {
+		final String sa = "2";
+		final AbbreviatedLongObjectId a = AbbreviatedLongObjectId
+				.fromString(sa);
+
+		final String s1 = "27e15b72937fc8f558da24ac3d50ec20302a4cf21e33b87ae8e4ce90e89c4b10";
+		final LongObjectId i1 = LongObjectId.fromString(s1);
+		assertEquals(0, a.prefixCompare(i1));
+		assertTrue(i1.startsWith(a));
+
+		final String s2 = "37e15b72937fc8f558da24ac3d50ec20302a4cf21e33b87ae8e4ce90e89c4b10";
+		final LongObjectId i2 = LongObjectId.fromString(s2);
+		assertTrue(a.prefixCompare(i2) < 0);
+		assertFalse(i2.startsWith(a));
+
+		final String s3 = "17e15b72937fc8f558da24ac3d50ec20302a4cf21e33b87ae8e4ce90e89c4b10";
+		final LongObjectId i3 = LongObjectId.fromString(s3);
+		assertTrue(a.prefixCompare(i3) > 0);
+		assertFalse(i3.startsWith(a));
+	}
+
+	@Test
+	public void testPrefixCompare_15() {
+		final String sa = "27e15b72937fc8f";
+		final AbbreviatedLongObjectId a = AbbreviatedLongObjectId
+				.fromString(sa);
+
+		final String s1 = "27e15b72937fc8f558da24ac3d50ec20302a4cf21e33b87ae8e4ce90e89c4b10";
+		final LongObjectId i1 = LongObjectId.fromString(s1);
+		assertEquals(0, a.prefixCompare(i1));
+		assertTrue(i1.startsWith(a));
+
+		final String s2 = "27e15b72937fc90558da24ac3d50ec20302a4cf21e33b87ae8e4ce90e89c4b10";
+		final LongObjectId i2 = LongObjectId.fromString(s2);
+		assertTrue(a.prefixCompare(i2) < 0);
+		assertFalse(i2.startsWith(a));
+
+		final String s3 = "27e15b72937fc8e558da24ac3d50ec20302a4cf21e33b87ae8e4ce90e89c4b10";
+		final LongObjectId i3 = LongObjectId.fromString(s3);
+		assertTrue(a.prefixCompare(i3) > 0);
+		assertFalse(i3.startsWith(a));
+	}
+
+	@Test
+	public void testPrefixCompare_16() {
+		final String sa = "27e15b72937fc8f5";
+		final AbbreviatedLongObjectId a = AbbreviatedLongObjectId
+				.fromString(sa);
+
+		final String s1 = "27e15b72937fc8f558da24ac3d50ec20302a4cf21e33b87ae8e4ce90e89c4b10";
+		final LongObjectId i1 = LongObjectId.fromString(s1);
+		assertEquals(0, a.prefixCompare(i1));
+		assertTrue(i1.startsWith(a));
+
+		final String s2 = "27e15b72937fc8f658da24ac3d50ec20302a4cf21e33b87ae8e4ce90e89c4b10";
+		final LongObjectId i2 = LongObjectId.fromString(s2);
+		assertTrue(a.prefixCompare(i2) < 0);
+		assertFalse(i2.startsWith(a));
+
+		final String s3 = "27e15b72937fc8f458da24ac3d50ec20302a4cf21e33b87ae8e4ce90e89c4b10";
+		final LongObjectId i3 = LongObjectId.fromString(s3);
+		assertTrue(a.prefixCompare(i3) > 0);
+		assertFalse(i3.startsWith(a));
+	}
+
+	@Test
+	public void testPrefixCompare_17() {
+		final String sa = "27e15b72937fc8f55";
+		final AbbreviatedLongObjectId a = AbbreviatedLongObjectId
+				.fromString(sa);
+
+		final String s1 = "27e15b72937fc8f558da24ac3d50ec20302a4cf21e33b87ae8e4ce90e89c4b10";
+		final LongObjectId i1 = LongObjectId.fromString(s1);
+		assertEquals(0, a.prefixCompare(i1));
+		assertTrue(i1.startsWith(a));
+
+		final String s2 = "27e15b72937fc8f568da24ac3d50ec20302a4cf21e33b87ae8e4ce90e89c4b10";
+		final LongObjectId i2 = LongObjectId.fromString(s2);
+		assertTrue(a.prefixCompare(i2) < 0);
+		assertFalse(i2.startsWith(a));
+
+		final String s3 = "27e15b72937fc8f548da24ac3d50ec20302a4cf21e33b87ae8e4ce90e89c4b10";
+		final LongObjectId i3 = LongObjectId.fromString(s3);
+		assertTrue(a.prefixCompare(i3) > 0);
+		assertFalse(i3.startsWith(a));
+	}
+
+	@Test
+	public void testPrefixCompare_33() {
+		final String sa = "27e15b72937fc8f558da24ac3d50ec203";
+		final AbbreviatedLongObjectId a = AbbreviatedLongObjectId
+				.fromString(sa);
+
+		final String s1 = "27e15b72937fc8f558da24ac3d50ec20302a4cf21e33b87ae8e4ce90e89c4b10";
+		final LongObjectId i1 = LongObjectId.fromString(s1);
+		assertEquals(0, a.prefixCompare(i1));
+		assertTrue(i1.startsWith(a));
+
+		final String s2 = "27e15b72937fc8f558da24ac3d50ec20402a4cf21e33b87ae8e4ce90e89c4b10";
+		final LongObjectId i2 = LongObjectId.fromString(s2);
+		assertTrue(a.prefixCompare(i2) < 0);
+		assertFalse(i2.startsWith(a));
+
+		final String s3 = "27e15b72937fc8f558da24ac3d50ec20202a4cf21e33b87ae8e4ce90e89c4b10";
+		final LongObjectId i3 = LongObjectId.fromString(s3);
+		assertTrue(a.prefixCompare(i3) > 0);
+		assertFalse(i3.startsWith(a));
+	}
+
+	@Test
+	public void testIsId() {
+		// These are all too short.
+		assertFalse(AbbreviatedLongObjectId.isId(""));
+		assertFalse(AbbreviatedLongObjectId.isId("a"));
+
+		// These are too long.
+		assertFalse(AbbreviatedLongObjectId.isId(LongObjectId
+				.fromString(
+						"27e15b72937fc8f558da24ac3d50ec20302a4cf21e33b87ae8e4ce90e89c4b10")
+				.name() + "0"));
+		assertFalse(AbbreviatedLongObjectId.isId(LongObjectId
+				.fromString(
+						"27e15b72937fc8f558da24ac3d50ec20302a4cf21e33b87ae8e4ce90e89c4b10")
+				.name() + "c0ffee"));
+
+		// These contain non-hex characters.
+		assertFalse(AbbreviatedLongObjectId.isId("01notahexstring"));
+
+		// These should all work.
+		assertTrue(AbbreviatedLongObjectId.isId("ab"));
+		assertTrue(AbbreviatedLongObjectId.isId("abc"));
+		assertTrue(AbbreviatedLongObjectId.isId("abcd"));
+		assertTrue(AbbreviatedLongObjectId.isId("abcd0"));
+		assertTrue(AbbreviatedLongObjectId.isId("abcd09"));
+		assertTrue(AbbreviatedLongObjectId.isId(LongObjectId
+				.fromString(
+						"27e15b72937fc8f558da24ac3d50ec20302a4cf21e33b87ae8e4ce90e89c4b10")
+				.name()));
+	}
+
+	@Test
+	public void testAbbreviate() {
+		AnyLongObjectId id = LongObjectIdTestUtils.hash("test");
+		assertEquals(
+				"abbreviated id should match the id it was abbreviated from", 0,
+				id.abbreviate(10).prefixCompare(id));
+	}
+
+	@Test
+	public void testFromStringByteWrongLength() {
+		byte[] buf = new byte[65];
+		try {
+			AbbreviatedLongObjectId.fromString(buf, 0, 65);
+			fail("expected IllegalArgumentException for too long AbbreviatedLongObjectId");
+		} catch (IllegalArgumentException e) {
+			// expected
+		}
+	}
+
+	@Test
+	public void testFromStringWrongLength() {
+		AnyLongObjectId id = LongObjectIdTestUtils.hash("test");
+		try {
+			AbbreviatedLongObjectId.fromString(id.name() + "c0ffee");
+			fail("expected IllegalArgumentException for too long AbbreviatedLongObjectId");
+		} catch (IllegalArgumentException e) {
+			// expected
+		}
+	}
+
+	@Test
+	public void testFromLongObjectId() {
+		AnyLongObjectId id = LongObjectIdTestUtils.hash("test");
+		assertEquals(0,
+				AbbreviatedLongObjectId.fromLongObjectId(id).prefixCompare(id));
+	}
+
+	@Test
+	public void testPrefixCompareByte() {
+		AnyLongObjectId id = LongObjectId.fromString(
+				"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef");
+		byte[] buf = new byte[32];
+		id.copyRawTo(buf, 0);
+
+		AbbreviatedLongObjectId a = id.abbreviate(62);
+		assertEquals(0, a.prefixCompare(buf, 0));
+
+		a = LongObjectId
+				.fromString(
+						"0023456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef")
+				.abbreviate(16);
+		assertEquals(-1, a.prefixCompare(buf, 0));
+		a = LongObjectId
+				.fromString(
+						"0123456789abcdef0023456789abcdef0123456789abcdef0123456789abcdef")
+				.abbreviate(32);
+		assertEquals(-1, a.prefixCompare(buf, 0));
+		a = LongObjectId
+				.fromString(
+						"0123456789abcdef0123456789abcdef0023456789abcdef0123456789abcdef")
+				.abbreviate(48);
+		assertEquals(-1, a.prefixCompare(buf, 0));
+		a = LongObjectId
+				.fromString(
+						"0123456789abcdef0123456789abcdef0123456789abcdef0023456789abcdef")
+				.abbreviate(64);
+		assertEquals(-1, a.prefixCompare(buf, 0));
+
+		a = LongObjectId
+				.fromString(
+						"1123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef")
+				.abbreviate(16);
+		assertEquals(1, a.prefixCompare(buf, 0));
+		a = LongObjectId
+				.fromString(
+						"0123456789abcdef1123456789abcdef0123456789abcdef0123456789abcdef")
+				.abbreviate(32);
+		assertEquals(1, a.prefixCompare(buf, 0));
+		a = LongObjectId
+				.fromString(
+						"0123456789abcdef0123456789abcdef1123456789abcdef0123456789abcdef")
+				.abbreviate(48);
+		assertEquals(1, a.prefixCompare(buf, 0));
+		a = LongObjectId
+				.fromString(
+						"0123456789abcdef0123456789abcdef0123456789abcdef1123456789abcdef")
+				.abbreviate(64);
+		assertEquals(1, a.prefixCompare(buf, 0));
+	}
+
+	@Test
+	public void testPrefixCompareLong() {
+		AnyLongObjectId id = new LongObjectId(1L, 2L, 3L, 4L);
+		long[] buf = new long[4];
+		id.copyRawTo(buf, 0);
+
+		AbbreviatedLongObjectId a = id.abbreviate(62);
+		assertEquals(0, a.prefixCompare(buf, 0));
+
+		a = new LongObjectId(0L, 2L, 3L, 4L).abbreviate(16);
+		assertEquals(-1, a.prefixCompare(buf, 0));
+		a = new LongObjectId(1L, 1L, 3L, 4L).abbreviate(32);
+		assertEquals(-1, a.prefixCompare(buf, 0));
+		a = new LongObjectId(1L, 2L, 2L, 4L).abbreviate(48);
+		assertEquals(-1, a.prefixCompare(buf, 0));
+		a = new LongObjectId(1L, 2L, 3L, 3L).abbreviate(64);
+		assertEquals(-1, a.prefixCompare(buf, 0));
+
+		a = new LongObjectId(2L, 2L, 3L, 4L).abbreviate(16);
+		assertEquals(1, a.prefixCompare(buf, 0));
+		a = new LongObjectId(1L, 3L, 3L, 4L).abbreviate(32);
+		assertEquals(1, a.prefixCompare(buf, 0));
+		a = new LongObjectId(1L, 2L, 4L, 4L).abbreviate(48);
+		assertEquals(1, a.prefixCompare(buf, 0));
+		a = new LongObjectId(1L, 2L, 3L, 5L).abbreviate(64);
+		assertEquals(1, a.prefixCompare(buf, 0));
+	}
+
+	@Test
+	public void testGetFirstByte() {
+		AnyLongObjectId id = LongObjectId.fromString(
+				"f423456789abcdef0123456789abcdef0123456789abcdef1123456789abcdef");
+		AbbreviatedLongObjectId a = id.abbreviate(10);
+		assertEquals(0xf4, a.getFirstByte());
+		assertEquals(id.getFirstByte(), a.getFirstByte());
+	}
+
+	@Test
+	public void testNotEquals() {
+		AbbreviatedLongObjectId a = new LongObjectId(1L, 2L, 3L, 4L)
+				.abbreviate(10);
+		assertFalse(a.equals("different"));
+	}
+}
diff --git a/org.eclipse.jgit.lfs.test/tst/org/eclipse/jgit/lfs/lib/LongObjectIdTest.java b/org.eclipse.jgit.lfs.test/tst/org/eclipse/jgit/lfs/lib/LongObjectIdTest.java
new file mode 100644
index 0000000..435a2a3
--- /dev/null
+++ b/org.eclipse.jgit.lfs.test/tst/org/eclipse/jgit/lfs/lib/LongObjectIdTest.java
@@ -0,0 +1,427 @@
+/*
+ * Copyright (C) 2015, Matthias Sohn <matthias.sohn@sap.com>
+ * 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.lfs.lib;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.nio.ByteBuffer;
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+
+import org.eclipse.jgit.junit.JGitTestUtil;
+import org.eclipse.jgit.lfs.errors.InvalidLongObjectIdException;
+import org.eclipse.jgit.lfs.test.LongObjectIdTestUtils;
+import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.util.FileUtils;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+/*
+ * Ported to SHA-256 from org.eclipse.jgit.lib.ObjectIdTest
+ */
+public class LongObjectIdTest {
+	private static Path tmp;
+
+	@BeforeClass
+	public static void setup() throws IOException {
+		tmp = Files.createTempDirectory("jgit_test_");
+	}
+
+	@AfterClass
+	public static void tearDown() throws IOException {
+		FileUtils.delete(tmp.toFile(), FileUtils.RECURSIVE | FileUtils.RETRY);
+	}
+
+	@Test
+	public void test001_toString() {
+		final String x = "8367b0edc81df80e6b42eb1b71f783111224e058cb3da37894d065d2deb7ab0a";
+		final LongObjectId oid = LongObjectId.fromString(x);
+		assertEquals(x, oid.name());
+	}
+
+	@Test
+	public void test002_toString() {
+		final String x = "140ce71d628cceb78e3709940ba52a651a0c4a9c1400f2e15e998a1a43887edf";
+		final LongObjectId oid = LongObjectId.fromString(x);
+		assertEquals(x, oid.name());
+	}
+
+	@Test
+	public void test003_equals() {
+		final String x = "8367b0edc81df80e6b42eb1b71f783111224e058cb3da37894d065d2deb7ab0a";
+		final LongObjectId a = LongObjectId.fromString(x);
+		final LongObjectId b = LongObjectId.fromString(x);
+		assertEquals(a.hashCode(), b.hashCode());
+		assertEquals("a and b should be equal", b, a);
+	}
+
+	@Test
+	public void test004_isId() {
+		assertTrue("valid id", LongObjectId.isId(
+				"8367b0edc81df80e6b42eb1b71f783111224e058cb3da37894d065d2deb7ab0a"));
+	}
+
+	@Test
+	public void test005_notIsId() {
+		assertFalse("bob is not an id", LongObjectId.isId("bob"));
+	}
+
+	@Test
+	public void test006_notIsId() {
+		assertFalse("63 digits is not an id", LongObjectId.isId(
+				"8367b0edc81df80e6b42eb1b71f783111224e058cb3da37894d065d2deb7ab0"));
+	}
+
+	@Test
+	public void test007_isId() {
+		assertTrue("uppercase is accepted", LongObjectId.isId(
+				"8367b0edc81df80e6b42eb1b71f783111224e058cb3da37894d065d2dEb7ab0A"));
+	}
+
+	@Test
+	public void test008_notIsId() {
+		assertFalse("g is not a valid hex digit", LongObjectId.isId(
+				"g367b0edc81df80e6b42eb1b71f783111224e058cb3da37894d065d2deb7ab0a"));
+	}
+
+	@Test
+	public void test009_toString() {
+		final String x = "140ce71d628cceb78e3709940ba52a651a0c4a9c1400f2e15e998a1a43887edf";
+		final LongObjectId oid = LongObjectId.fromString(x);
+		assertEquals(x, LongObjectId.toString(oid));
+	}
+
+	@Test
+	public void test010_toString() {
+		final String x = "0000000000000000000000000000000000000000000000000000000000000000";
+		assertEquals(x, LongObjectId.toString(null));
+	}
+
+	@Test
+	public void test011_toString() {
+		final String x = "0123456789ABCDEFabcdef01234567890123456789ABCDEFabcdef0123456789";
+		final LongObjectId oid = LongObjectId.fromString(x);
+		assertEquals(x.toLowerCase(), oid.name());
+	}
+
+	@Test
+	public void testGetByte() {
+		byte[] raw = new byte[32];
+		for (int i = 0; i < 32; i++)
+			raw[i] = (byte) (0xa0 + i);
+		LongObjectId id = LongObjectId.fromRaw(raw);
+
+		assertEquals(raw[0] & 0xff, id.getFirstByte());
+		assertEquals(raw[0] & 0xff, id.getByte(0));
+		assertEquals(raw[1] & 0xff, id.getByte(1));
+		assertEquals(raw[1] & 0xff, id.getSecondByte());
+
+		for (int i = 2; i < 32; i++) {
+			assertEquals("index " + i, raw[i] & 0xff, id.getByte(i));
+		}
+		try {
+			id.getByte(32);
+			fail("LongObjectId has 32 byte only");
+		} catch (ArrayIndexOutOfBoundsException e) {
+			// expected
+		}
+	}
+
+	@Test
+	public void testSetByte() {
+		byte[] exp = new byte[32];
+		for (int i = 0; i < 32; i++) {
+			exp[i] = (byte) (0xa0 + i);
+		}
+
+		MutableLongObjectId id = new MutableLongObjectId();
+		id.fromRaw(exp);
+		assertEquals(LongObjectId.fromRaw(exp).name(), id.name());
+
+		id.setByte(0, 0x10);
+		assertEquals(0x10, id.getByte(0));
+		exp[0] = 0x10;
+		assertEquals(LongObjectId.fromRaw(exp).name(), id.name());
+
+		for (int p = 1; p < 32; p++) {
+			id.setByte(p, 0x10 + p);
+			assertEquals(0x10 + p, id.getByte(p));
+			exp[p] = (byte) (0x10 + p);
+			assertEquals(LongObjectId.fromRaw(exp).name(), id.name());
+		}
+
+		for (int p = 0; p < 32; p++) {
+			id.setByte(p, 0x80 + p);
+			assertEquals(0x80 + p, id.getByte(p));
+			exp[p] = (byte) (0x80 + p);
+			assertEquals(LongObjectId.fromRaw(exp).name(), id.name());
+		}
+	}
+
+	@Test
+	public void testZeroId() {
+		AnyLongObjectId zero = new LongObjectId(0L, 0L, 0L, 0L);
+		assertEquals(zero, LongObjectId.zeroId());
+		assertEquals(
+				"0000000000000000000000000000000000000000000000000000000000000000",
+				LongObjectId.zeroId().name());
+	}
+
+	@Test
+	public void testEquals() {
+		AnyLongObjectId id1 = LongObjectIdTestUtils.hash("test");
+		assertTrue("id should equal itself", id1.equals(id1));
+		AnyLongObjectId id2 = new LongObjectId(id1);
+		assertEquals("objects should be equals", id1, id2);
+
+		id2 = LongObjectIdTestUtils.hash("other");
+		assertNotEquals("objects should be not equal", id1, id2);
+	}
+
+	@Test
+	public void testCopyRawBytes() {
+		AnyLongObjectId id1 = LongObjectIdTestUtils.hash("test");
+		AnyLongObjectId id2 = new LongObjectId(id1);
+
+		byte[] buf = new byte[64];
+		id1.copyRawTo(buf, 0);
+		id2.copyRawTo(buf, 32);
+		assertTrue("objects should be equals",
+				LongObjectId.equals(buf, 0, buf, 32));
+	}
+
+	@Test
+	public void testCopyRawLongs() {
+		long[] a = new long[4];
+		a[0] = 1L;
+		a[1] = 2L;
+		a[2] = 3L;
+		a[3] = 4L;
+		AnyLongObjectId id1 = new LongObjectId(a[0], a[1], a[2], a[3]);
+		AnyLongObjectId id2 = LongObjectId.fromRaw(a);
+		assertEquals("objects should be equals", id1, id2);
+	}
+
+	@Test
+	public void testCopyFromStringInvalid() {
+		AnyLongObjectId id1 = LongObjectIdTestUtils.hash("test");
+		try {
+			LongObjectId.fromString(id1.name() + "01234");
+			fail("expected InvalidLongObjectIdException");
+		} catch (InvalidLongObjectIdException e) {
+			assertEquals("Invalid id: " + id1.name() + "01234",
+					e.getMessage());
+		}
+	}
+
+	@Test
+	public void testCopyFromStringByte() {
+		AnyLongObjectId id1 = LongObjectIdTestUtils.hash("test");
+		byte[] buf = new byte[64];
+		Charset cs = StandardCharsets.US_ASCII;
+		cs.encode(id1.name()).get(buf);
+		AnyLongObjectId id2 = LongObjectId.fromString(buf, 0);
+		assertEquals("objects should be equals", id1, id2);
+	}
+
+	@Test
+	public void testHashFile() throws IOException {
+		AnyLongObjectId id1 = LongObjectIdTestUtils.hash("test");
+		Path f = tmp.resolve("test");
+		JGitTestUtil.write(f.toFile(), "test");
+		AnyLongObjectId id2 = LongObjectIdTestUtils.hash(f);
+		assertEquals("objects should be equals", id1, id2);
+	}
+
+	@Test
+	public void testCompareTo() {
+		AnyLongObjectId id1 = LongObjectId.fromString(
+				"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef");
+		assertEquals(0, id1.compareTo(LongObjectId.fromString(
+				"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef")));
+		assertEquals(0, id1.compareTo(id1));
+
+		assertEquals(-1, id1.compareTo(LongObjectId.fromString(
+				"1123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef")));
+		assertEquals(-1, id1.compareTo(LongObjectId.fromString(
+				"0123456789abcdef1123456789abcdef0123456789abcdef0123456789abcdef")));
+		assertEquals(-1, id1.compareTo(LongObjectId.fromString(
+				"0123456789abcdef0123456789abcdef1123456789abcdef0123456789abcdef")));
+		assertEquals(-1, id1.compareTo(LongObjectId.fromString(
+				"0123456789abcdef0123456789abcdef0123456789abcdef1123456789abcdef")));
+
+		assertEquals(1, id1.compareTo(LongObjectId.fromString(
+				"0023456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef")));
+		assertEquals(1, id1.compareTo(LongObjectId.fromString(
+				"0123456789abcdef0023456789abcdef0123456789abcdef0123456789abcdef")));
+		assertEquals(1, id1.compareTo(LongObjectId.fromString(
+				"0123456789abcdef0123456789abcdef0023456789abcdef0123456789abcdef")));
+		assertEquals(1, id1.compareTo(LongObjectId.fromString(
+				"0123456789abcdef0123456789abcdef0123456789abcdef0023456789abcdef")));
+	}
+
+	@Test
+	public void testCompareToByte() {
+		AnyLongObjectId id1 = LongObjectId.fromString(
+				"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef");
+		byte[] buf = new byte[32];
+		id1.copyRawTo(buf, 0);
+		assertEquals(0, id1.compareTo(buf, 0));
+
+		LongObjectId
+				.fromString(
+						"1123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef")
+				.copyRawTo(buf, 0);
+		assertEquals(-1, id1.compareTo(buf, 0));
+
+		LongObjectId
+				.fromString(
+						"0023456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef")
+				.copyRawTo(buf, 0);
+		assertEquals(1, id1.compareTo(buf, 0));
+	}
+
+	@Test
+	public void testCompareToLong() {
+		AnyLongObjectId id1 = new LongObjectId(1L, 2L, 3L, 4L);
+		long[] buf = new long[4];
+		id1.copyRawTo(buf, 0);
+		assertEquals(0, id1.compareTo(buf, 0));
+
+		new LongObjectId(2L, 2L, 3L, 4L).copyRawTo(buf, 0);
+		assertEquals(-1, id1.compareTo(buf, 0));
+
+		new LongObjectId(0L, 2L, 3L, 4L).copyRawTo(buf, 0);
+		assertEquals(1, id1.compareTo(buf, 0));
+	}
+
+	@Test
+	public void testCopyToByte() {
+		AnyLongObjectId id1 = LongObjectIdTestUtils.hash("test");
+		byte[] buf = new byte[64];
+		id1.copyTo(buf, 0);
+		assertEquals(id1, LongObjectId.fromString(buf, 0));
+	}
+
+	@Test
+	public void testCopyRawToByteBuffer() {
+		AnyLongObjectId id1 = LongObjectIdTestUtils.hash("test");
+		ByteBuffer buf = ByteBuffer.allocate(32);
+		id1.copyRawTo(buf);
+		assertEquals(id1, LongObjectId.fromRaw(buf.array(), 0));
+	}
+
+	@Test
+	public void testCopyToByteBuffer() {
+		AnyLongObjectId id1 = LongObjectIdTestUtils.hash("test");
+		ByteBuffer buf = ByteBuffer.allocate(64);
+		id1.copyTo(buf);
+		assertEquals(id1, LongObjectId.fromString(buf.array(), 0));
+	}
+
+	@Test
+	public void testCopyRawToOutputStream() throws IOException {
+		AnyLongObjectId id1 = LongObjectIdTestUtils.hash("test");
+		ByteArrayOutputStream os = new ByteArrayOutputStream(32);
+		id1.copyRawTo(os);
+		assertEquals(id1, LongObjectId.fromRaw(os.toByteArray(), 0));
+	}
+
+	@Test
+	public void testCopyToOutputStream() throws IOException {
+		AnyLongObjectId id1 = LongObjectIdTestUtils.hash("test");
+		ByteArrayOutputStream os = new ByteArrayOutputStream(64);
+		id1.copyTo(os);
+		assertEquals(id1, LongObjectId.fromString(os.toByteArray(), 0));
+	}
+
+	@Test
+	public void testCopyToWriter() throws IOException {
+		AnyLongObjectId id1 = LongObjectIdTestUtils.hash("test");
+		ByteArrayOutputStream os = new ByteArrayOutputStream(64);
+		OutputStreamWriter w = new OutputStreamWriter(os, Constants.CHARSET);
+		id1.copyTo(w);
+		w.close();
+		assertEquals(id1, LongObjectId.fromString(os.toByteArray(), 0));
+	}
+
+	@Test
+	public void testCopyToWriterWithBuf() throws IOException {
+		AnyLongObjectId id1 = LongObjectIdTestUtils.hash("test");
+		ByteArrayOutputStream os = new ByteArrayOutputStream(64);
+		OutputStreamWriter w = new OutputStreamWriter(os, Constants.CHARSET);
+		char[] buf = new char[64];
+		id1.copyTo(buf, w);
+		w.close();
+		assertEquals(id1, LongObjectId.fromString(os.toByteArray(), 0));
+	}
+
+	@Test
+	public void testCopyToStringBuilder() {
+		AnyLongObjectId id1 = LongObjectIdTestUtils.hash("test");
+		StringBuilder sb = new StringBuilder();
+		char[] buf = new char[64];
+		id1.copyTo(buf, sb);
+		assertEquals(id1, LongObjectId.fromString(sb.toString()));
+	}
+
+	@Test
+	public void testCopy() {
+		AnyLongObjectId id1 = LongObjectIdTestUtils.hash("test");
+		assertEquals(id1.copy(), id1);
+		MutableLongObjectId id2 = new MutableLongObjectId();
+		id2.fromObjectId(id1);
+		assertEquals(id1, id2.copy());
+	}
+}
diff --git a/org.eclipse.jgit.lfs.test/tst/org/eclipse/jgit/lfs/lib/MutableLongObjectIdTest.java b/org.eclipse.jgit.lfs.test/tst/org/eclipse/jgit/lfs/lib/MutableLongObjectIdTest.java
new file mode 100644
index 0000000..9bdc3ab
--- /dev/null
+++ b/org.eclipse.jgit.lfs.test/tst/org/eclipse/jgit/lfs/lib/MutableLongObjectIdTest.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2015, Matthias Sohn <matthias.sohn@sap.com>
+ * 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.lfs.lib;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+
+/*
+ * Ported to SHA-256 from org.eclipse.jgit.lib.MutableObjectIdTest
+ */
+public class MutableLongObjectIdTest {
+
+	@Test
+	public void testFromRawLong() {
+		MutableLongObjectId m = new MutableLongObjectId();
+		m.fromRaw(new long[] { 1L, 2L, 3L, 4L });
+		assertEquals(new LongObjectId(1L, 2L, 3L, 4L), m);
+	}
+
+	@Test
+	public void testFromString() {
+		AnyLongObjectId id = new LongObjectId(1L, 2L, 3L, 4L);
+		MutableLongObjectId m = new MutableLongObjectId();
+		m.fromString(id.name());
+		assertEquals(id, m);
+	}
+
+	@Test
+	public void testFromStringByte() {
+		AnyLongObjectId id = new LongObjectId(1L, 2L, 3L, 4L);
+		MutableLongObjectId m = new MutableLongObjectId();
+		byte[] buf = new byte[64];
+		id.copyTo(buf, 0);
+		m.fromString(buf, 0);
+		assertEquals(id, m);
+	}
+
+	@Test
+	public void testCopy() {
+		MutableLongObjectId m = new MutableLongObjectId();
+		m.fromRaw(new long[] { 1L, 2L, 3L, 4L });
+		assertEquals(m, new MutableLongObjectId(m));
+	}
+
+	@Test
+	public void testToObjectId() {
+		MutableLongObjectId m = new MutableLongObjectId();
+		m.fromRaw(new long[] { 1L, 2L, 3L, 4L });
+		assertEquals(m, m.toObjectId());
+	}
+}
diff --git a/org.eclipse.jgit.lfs/.classpath b/org.eclipse.jgit.lfs/.classpath
new file mode 100644
index 0000000..04a2be7
--- /dev/null
+++ b/org.eclipse.jgit.lfs/.classpath
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="src" path="resources"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/org.eclipse.jgit.lfs/.fbprefs b/org.eclipse.jgit.lfs/.fbprefs
new file mode 100644
index 0000000..81a0767
--- /dev/null
+++ b/org.eclipse.jgit.lfs/.fbprefs
@@ -0,0 +1,125 @@
+#FindBugs User Preferences
+#Mon May 04 16:24:13 PDT 2009
+detectorAppendingToAnObjectOutputStream=AppendingToAnObjectOutputStream|true
+detectorBadAppletConstructor=BadAppletConstructor|false
+detectorBadResultSetAccess=BadResultSetAccess|true
+detectorBadSyntaxForRegularExpression=BadSyntaxForRegularExpression|true
+detectorBadUseOfReturnValue=BadUseOfReturnValue|true
+detectorBadlyOverriddenAdapter=BadlyOverriddenAdapter|true
+detectorBooleanReturnNull=BooleanReturnNull|true
+detectorCallToUnsupportedMethod=CallToUnsupportedMethod|true
+detectorCheckImmutableAnnotation=CheckImmutableAnnotation|true
+detectorCheckTypeQualifiers=CheckTypeQualifiers|true
+detectorCloneIdiom=CloneIdiom|false
+detectorComparatorIdiom=ComparatorIdiom|true
+detectorConfusedInheritance=ConfusedInheritance|true
+detectorConfusionBetweenInheritedAndOuterMethod=ConfusionBetweenInheritedAndOuterMethod|true
+detectorCrossSiteScripting=CrossSiteScripting|true
+detectorDoInsideDoPrivileged=DoInsideDoPrivileged|true
+detectorDontCatchIllegalMonitorStateException=DontCatchIllegalMonitorStateException|true
+detectorDontUseEnum=DontUseEnum|true
+detectorDroppedException=DroppedException|true
+detectorDumbMethodInvocations=DumbMethodInvocations|true
+detectorDumbMethods=DumbMethods|true
+detectorDuplicateBranches=DuplicateBranches|true
+detectorEmptyZipFileEntry=EmptyZipFileEntry|true
+detectorEqualsOperandShouldHaveClassCompatibleWithThis=EqualsOperandShouldHaveClassCompatibleWithThis|true
+detectorFinalizerNullsFields=FinalizerNullsFields|true
+detectorFindBadCast2=FindBadCast2|true
+detectorFindBadForLoop=FindBadForLoop|true
+detectorFindCircularDependencies=FindCircularDependencies|false
+detectorFindDeadLocalStores=FindDeadLocalStores|true
+detectorFindDoubleCheck=FindDoubleCheck|true
+detectorFindEmptySynchronizedBlock=FindEmptySynchronizedBlock|true
+detectorFindFieldSelfAssignment=FindFieldSelfAssignment|true
+detectorFindFinalizeInvocations=FindFinalizeInvocations|true
+detectorFindFloatEquality=FindFloatEquality|true
+detectorFindHEmismatch=FindHEmismatch|true
+detectorFindInconsistentSync2=FindInconsistentSync2|true
+detectorFindJSR166LockMonitorenter=FindJSR166LockMonitorenter|true
+detectorFindLocalSelfAssignment2=FindLocalSelfAssignment2|true
+detectorFindMaskedFields=FindMaskedFields|true
+detectorFindMismatchedWaitOrNotify=FindMismatchedWaitOrNotify|true
+detectorFindNakedNotify=FindNakedNotify|true
+detectorFindNonSerializableStoreIntoSession=FindNonSerializableStoreIntoSession|true
+detectorFindNonSerializableValuePassedToWriteObject=FindNonSerializableValuePassedToWriteObject|true
+detectorFindNonShortCircuit=FindNonShortCircuit|true
+detectorFindNullDeref=FindNullDeref|true
+detectorFindNullDerefsInvolvingNonShortCircuitEvaluation=FindNullDerefsInvolvingNonShortCircuitEvaluation|true
+detectorFindOpenStream=FindOpenStream|true
+detectorFindPuzzlers=FindPuzzlers|true
+detectorFindRefComparison=FindRefComparison|true
+detectorFindReturnRef=FindReturnRef|true
+detectorFindRunInvocations=FindRunInvocations|true
+detectorFindSelfComparison=FindSelfComparison|true
+detectorFindSelfComparison2=FindSelfComparison2|true
+detectorFindSleepWithLockHeld=FindSleepWithLockHeld|true
+detectorFindSpinLoop=FindSpinLoop|true
+detectorFindSqlInjection=FindSqlInjection|true
+detectorFindTwoLockWait=FindTwoLockWait|true
+detectorFindUncalledPrivateMethods=FindUncalledPrivateMethods|true
+detectorFindUnconditionalWait=FindUnconditionalWait|true
+detectorFindUninitializedGet=FindUninitializedGet|true
+detectorFindUnrelatedTypesInGenericContainer=FindUnrelatedTypesInGenericContainer|true
+detectorFindUnreleasedLock=FindUnreleasedLock|true
+detectorFindUnsatisfiedObligation=FindUnsatisfiedObligation|true
+detectorFindUnsyncGet=FindUnsyncGet|true
+detectorFindUselessControlFlow=FindUselessControlFlow|true
+detectorFormatStringChecker=FormatStringChecker|true
+detectorHugeSharedStringConstants=HugeSharedStringConstants|true
+detectorIDivResultCastToDouble=IDivResultCastToDouble|true
+detectorIncompatMask=IncompatMask|true
+detectorInconsistentAnnotations=InconsistentAnnotations|true
+detectorInefficientMemberAccess=InefficientMemberAccess|false
+detectorInefficientToArray=InefficientToArray|true
+detectorInfiniteLoop=InfiniteLoop|true
+detectorInfiniteRecursiveLoop=InfiniteRecursiveLoop|true
+detectorInfiniteRecursiveLoop2=InfiniteRecursiveLoop2|false
+detectorInheritanceUnsafeGetResource=InheritanceUnsafeGetResource|true
+detectorInitializationChain=InitializationChain|true
+detectorInstantiateStaticClass=InstantiateStaticClass|true
+detectorInvalidJUnitTest=InvalidJUnitTest|true
+detectorIteratorIdioms=IteratorIdioms|true
+detectorLazyInit=LazyInit|true
+detectorLoadOfKnownNullValue=LoadOfKnownNullValue|true
+detectorMethodReturnCheck=MethodReturnCheck|true
+detectorMultithreadedInstanceAccess=MultithreadedInstanceAccess|true
+detectorMutableLock=MutableLock|true
+detectorMutableStaticFields=MutableStaticFields|true
+detectorNaming=Naming|true
+detectorNumberConstructor=NumberConstructor|true
+detectorOverridingEqualsNotSymmetrical=OverridingEqualsNotSymmetrical|true
+detectorPreferZeroLengthArrays=PreferZeroLengthArrays|true
+detectorPublicSemaphores=PublicSemaphores|false
+detectorQuestionableBooleanAssignment=QuestionableBooleanAssignment|true
+detectorReadReturnShouldBeChecked=ReadReturnShouldBeChecked|true
+detectorRedundantInterfaces=RedundantInterfaces|true
+detectorRepeatedConditionals=RepeatedConditionals|true
+detectorRuntimeExceptionCapture=RuntimeExceptionCapture|true
+detectorSerializableIdiom=SerializableIdiom|true
+detectorStartInConstructor=StartInConstructor|true
+detectorStaticCalendarDetector=StaticCalendarDetector|true
+detectorStringConcatenation=StringConcatenation|true
+detectorSuperfluousInstanceOf=SuperfluousInstanceOf|true
+detectorSuspiciousThreadInterrupted=SuspiciousThreadInterrupted|true
+detectorSwitchFallthrough=SwitchFallthrough|true
+detectorSynchronizeAndNullCheckField=SynchronizeAndNullCheckField|true
+detectorSynchronizeOnClassLiteralNotGetClass=SynchronizeOnClassLiteralNotGetClass|true
+detectorSynchronizingOnContentsOfFieldToProtectField=SynchronizingOnContentsOfFieldToProtectField|true
+detectorURLProblems=URLProblems|true
+detectorUncallableMethodOfAnonymousClass=UncallableMethodOfAnonymousClass|true
+detectorUnnecessaryMath=UnnecessaryMath|true
+detectorUnreadFields=UnreadFields|true
+detectorUseObjectEquals=UseObjectEquals|false
+detectorUselessSubclassMethod=UselessSubclassMethod|false
+detectorVarArgsProblems=VarArgsProblems|true
+detectorVolatileUsage=VolatileUsage|true
+detectorWaitInLoop=WaitInLoop|true
+detectorWrongMapIterator=WrongMapIterator|true
+detectorXMLFactoryBypass=XMLFactoryBypass|true
+detector_threshold=2
+effort=default
+excludefilter0=findBugs/FindBugsExcludeFilter.xml
+filter_settings=Medium|BAD_PRACTICE,CORRECTNESS,MT_CORRECTNESS,PERFORMANCE,STYLE|false
+filter_settings_neg=MALICIOUS_CODE,NOISE,I18N,SECURITY,EXPERIMENTAL|
+run_at_full_build=true
diff --git a/org.eclipse.jgit.lfs/.gitignore b/org.eclipse.jgit.lfs/.gitignore
new file mode 100644
index 0000000..934e0e0
--- /dev/null
+++ b/org.eclipse.jgit.lfs/.gitignore
@@ -0,0 +1,2 @@
+/bin
+/target
diff --git a/org.eclipse.jgit.lfs/.project b/org.eclipse.jgit.lfs/.project
new file mode 100644
index 0000000..d9beec1
--- /dev/null
+++ b/org.eclipse.jgit.lfs/.project
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.jgit.lfs</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ManifestBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.SchemaBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.api.tools.apiAnalysisBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>org.eclipse.pde.PluginNature</nature>
+		<nature>org.eclipse.pde.api.tools.apiAnalysisNature</nature>
+	</natures>
+</projectDescription>
diff --git a/org.eclipse.jgit.lfs/.settings/org.eclipse.core.resources.prefs b/org.eclipse.jgit.lfs/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 0000000..99f26c0
--- /dev/null
+++ b/org.eclipse.jgit.lfs/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+encoding/<project>=UTF-8
diff --git a/org.eclipse.jgit.lfs/.settings/org.eclipse.core.runtime.prefs b/org.eclipse.jgit.lfs/.settings/org.eclipse.core.runtime.prefs
new file mode 100644
index 0000000..5a0ad22
--- /dev/null
+++ b/org.eclipse.jgit.lfs/.settings/org.eclipse.core.runtime.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+line.separator=\n
diff --git a/org.eclipse.jgit.lfs/.settings/org.eclipse.jdt.core.prefs b/org.eclipse.jgit.lfs/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..ff39d16
--- /dev/null
+++ b/org.eclipse.jgit.lfs/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,398 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.annotation.inheritNullAnnotations=disabled
+org.eclipse.jdt.core.compiler.annotation.missingNonNullByDefaultAnnotation=ignore
+org.eclipse.jdt.core.compiler.annotation.nonnull=org.eclipse.jdt.annotation.NonNull
+org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=org.eclipse.jdt.annotation.NonNullByDefault
+org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nullable
+org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.7
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.doc.comment.support=enabled
+org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.autoboxing=warning
+org.eclipse.jdt.core.compiler.problem.comparingIdentical=error
+org.eclipse.jdt.core.compiler.problem.deadCode=error
+org.eclipse.jdt.core.compiler.problem.deprecation=warning
+org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
+org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
+org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
+org.eclipse.jdt.core.compiler.problem.emptyStatement=warning
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=ignore
+org.eclipse.jdt.core.compiler.problem.fallthroughCase=warning
+org.eclipse.jdt.core.compiler.problem.fatalOptionalError=disabled
+org.eclipse.jdt.core.compiler.problem.fieldHiding=warning
+org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
+org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=error
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=error
+org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=error
+org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=enabled
+org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
+org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=warning
+org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=error
+org.eclipse.jdt.core.compiler.problem.invalidJavadoc=error
+org.eclipse.jdt.core.compiler.problem.invalidJavadocTags=enabled
+org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsDeprecatedRef=enabled
+org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsNotVisibleRef=enabled
+org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsVisibility=private
+org.eclipse.jdt.core.compiler.problem.localVariableHiding=warning
+org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=error
+org.eclipse.jdt.core.compiler.problem.missingDefaultCase=ignore
+org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore
+org.eclipse.jdt.core.compiler.problem.missingEnumCaseDespiteDefault=disabled
+org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=error
+org.eclipse.jdt.core.compiler.problem.missingJavadocComments=error
+org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsVisibility=protected
+org.eclipse.jdt.core.compiler.problem.missingJavadocTagDescription=return_tag
+org.eclipse.jdt.core.compiler.problem.missingJavadocTags=error
+org.eclipse.jdt.core.compiler.problem.missingJavadocTagsMethodTypeParameters=disabled
+org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility=private
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled
+org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
+org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore
+org.eclipse.jdt.core.compiler.problem.noEffectAssignment=error
+org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=error
+org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=warning
+org.eclipse.jdt.core.compiler.problem.nonnullParameterAnnotationDropped=warning
+org.eclipse.jdt.core.compiler.problem.nullAnnotationInferenceConflict=error
+org.eclipse.jdt.core.compiler.problem.nullReference=error
+org.eclipse.jdt.core.compiler.problem.nullSpecViolation=error
+org.eclipse.jdt.core.compiler.problem.nullUncheckedConversion=warning
+org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
+org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=error
+org.eclipse.jdt.core.compiler.problem.potentialNullReference=warning
+org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable=ignore
+org.eclipse.jdt.core.compiler.problem.rawTypeReference=ignore
+org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning
+org.eclipse.jdt.core.compiler.problem.redundantNullCheck=warning
+org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore
+org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=error
+org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore
+org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore
+org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
+org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=error
+org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled
+org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
+org.eclipse.jdt.core.compiler.problem.syntacticNullAnalysisForFields=disabled
+org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
+org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
+org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=enabled
+org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
+org.eclipse.jdt.core.compiler.problem.unclosedCloseable=warning
+org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=warning
+org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
+org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=error
+org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=warning
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.unusedImport=error
+org.eclipse.jdt.core.compiler.problem.unusedLabel=error
+org.eclipse.jdt.core.compiler.problem.unusedLocal=error
+org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=warning
+org.eclipse.jdt.core.compiler.problem.unusedParameter=warning
+org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
+org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=error
+org.eclipse.jdt.core.compiler.problem.unusedTypeParameter=ignore
+org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=error
+org.eclipse.jdt.core.compiler.source=1.7
+org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_assignment=0
+org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_compact_if=16
+org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80
+org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0
+org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16
+org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0
+org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16
+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80
+org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16
+org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=16
+org.eclipse.jdt.core.formatter.blank_lines_after_imports=1
+org.eclipse.jdt.core.formatter.blank_lines_after_package=1
+org.eclipse.jdt.core.formatter.blank_lines_before_field=1
+org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0
+org.eclipse.jdt.core.formatter.blank_lines_before_imports=1
+org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1
+org.eclipse.jdt.core.formatter.blank_lines_before_method=1
+org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1
+org.eclipse.jdt.core.formatter.blank_lines_before_package=0
+org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1
+org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1
+org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines=false
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false
+org.eclipse.jdt.core.formatter.comment.format_block_comments=true
+org.eclipse.jdt.core.formatter.comment.format_comments=true
+org.eclipse.jdt.core.formatter.comment.format_header=false
+org.eclipse.jdt.core.formatter.comment.format_html=true
+org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true
+org.eclipse.jdt.core.formatter.comment.format_line_comments=true
+org.eclipse.jdt.core.formatter.comment.format_source_code=true
+org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true
+org.eclipse.jdt.core.formatter.comment.indent_root_tags=true
+org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert
+org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert
+org.eclipse.jdt.core.formatter.comment.line_length=80
+org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true
+org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true
+org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=false
+org.eclipse.jdt.core.formatter.compact_else_if=true
+org.eclipse.jdt.core.formatter.continuation_indentation=2
+org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2
+org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off
+org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on
+org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false
+org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true
+org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true
+org.eclipse.jdt.core.formatter.indent_empty_lines=false
+org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true
+org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true
+org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true
+org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false
+org.eclipse.jdt.core.formatter.indentation.size=4
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_member=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert
+org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert
+org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert
+org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert
+org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert
+org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert
+org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.join_lines_in_comments=true
+org.eclipse.jdt.core.formatter.join_wrapped_lines=true
+org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false
+org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false
+org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false
+org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false
+org.eclipse.jdt.core.formatter.lineSplit=80
+org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false
+org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false
+org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0
+org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1
+org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true
+org.eclipse.jdt.core.formatter.tabulation.char=tab
+org.eclipse.jdt.core.formatter.tabulation.size=4
+org.eclipse.jdt.core.formatter.use_on_off_tags=true
+org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false
+org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true
+org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true
+org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true
diff --git a/org.eclipse.jgit.lfs/.settings/org.eclipse.jdt.ui.prefs b/org.eclipse.jgit.lfs/.settings/org.eclipse.jdt.ui.prefs
new file mode 100644
index 0000000..c336cce
--- /dev/null
+++ b/org.eclipse.jgit.lfs/.settings/org.eclipse.jdt.ui.prefs
@@ -0,0 +1,61 @@
+eclipse.preferences.version=1
+editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
+formatter_profile=_JGit Format
+formatter_settings_version=12
+org.eclipse.jdt.ui.ignorelowercasenames=true
+org.eclipse.jdt.ui.importorder=java;javax;org;com;
+org.eclipse.jdt.ui.ondemandthreshold=99
+org.eclipse.jdt.ui.staticondemandthreshold=99
+org.eclipse.jdt.ui.text.custom_code_templates=<?xml version\="1.0" encoding\="UTF-8"?><templates/>
+sp_cleanup.add_default_serial_version_id=true
+sp_cleanup.add_generated_serial_version_id=false
+sp_cleanup.add_missing_annotations=false
+sp_cleanup.add_missing_deprecated_annotations=true
+sp_cleanup.add_missing_methods=false
+sp_cleanup.add_missing_nls_tags=false
+sp_cleanup.add_missing_override_annotations=true
+sp_cleanup.add_missing_override_annotations_interface_methods=false
+sp_cleanup.add_serial_version_id=false
+sp_cleanup.always_use_blocks=true
+sp_cleanup.always_use_parentheses_in_expressions=false
+sp_cleanup.always_use_this_for_non_static_field_access=false
+sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.correct_indentation=false
+sp_cleanup.format_source_code=true
+sp_cleanup.format_source_code_changes_only=true
+sp_cleanup.make_local_variable_final=false
+sp_cleanup.make_parameters_final=false
+sp_cleanup.make_private_fields_final=true
+sp_cleanup.make_type_abstract_if_missing_method=false
+sp_cleanup.make_variable_declarations_final=false
+sp_cleanup.never_use_blocks=false
+sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.organize_imports=false
+sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
+sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
+sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
+sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
+sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_trailing_whitespaces=true
+sp_cleanup.remove_trailing_whitespaces_all=true
+sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_casts=false
+sp_cleanup.remove_unnecessary_nls_tags=false
+sp_cleanup.remove_unused_imports=false
+sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_private_fields=true
+sp_cleanup.remove_unused_private_members=false
+sp_cleanup.remove_unused_private_methods=true
+sp_cleanup.remove_unused_private_types=true
+sp_cleanup.sort_members=false
+sp_cleanup.sort_members_all=false
+sp_cleanup.use_blocks=false
+sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_this_for_non_static_field_access=false
+sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
+sp_cleanup.use_this_for_non_static_method_access=false
+sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
diff --git a/org.eclipse.jgit.lfs/.settings/org.eclipse.mylyn.tasks.ui.prefs b/org.eclipse.jgit.lfs/.settings/org.eclipse.mylyn.tasks.ui.prefs
new file mode 100644
index 0000000..3dec4d9
--- /dev/null
+++ b/org.eclipse.jgit.lfs/.settings/org.eclipse.mylyn.tasks.ui.prefs
@@ -0,0 +1,3 @@
+eclipse.preferences.version=1
+project.repository.kind=bugzilla
+project.repository.url=https\://bugs.eclipse.org/bugs
diff --git a/org.eclipse.jgit.lfs/.settings/org.eclipse.mylyn.team.ui.prefs b/org.eclipse.jgit.lfs/.settings/org.eclipse.mylyn.team.ui.prefs
new file mode 100644
index 0000000..ce7a0f0
--- /dev/null
+++ b/org.eclipse.jgit.lfs/.settings/org.eclipse.mylyn.team.ui.prefs
@@ -0,0 +1,2 @@
+commit.comment.template=${task.description} \n\nBug\: ${task.key}
+eclipse.preferences.version=1
diff --git a/org.eclipse.jgit.lfs/.settings/org.eclipse.pde.api.tools.prefs b/org.eclipse.jgit.lfs/.settings/org.eclipse.pde.api.tools.prefs
new file mode 100644
index 0000000..3294d4f
--- /dev/null
+++ b/org.eclipse.jgit.lfs/.settings/org.eclipse.pde.api.tools.prefs
@@ -0,0 +1,98 @@
+ANNOTATION_ELEMENT_TYPE_ADDED_METHOD_WITHOUT_DEFAULT_VALUE=Error
+ANNOTATION_ELEMENT_TYPE_CHANGED_TYPE_CONVERSION=Error
+ANNOTATION_ELEMENT_TYPE_REMOVED_FIELD=Error
+ANNOTATION_ELEMENT_TYPE_REMOVED_METHOD=Error
+ANNOTATION_ELEMENT_TYPE_REMOVED_TYPE_MEMBER=Error
+API_COMPONENT_ELEMENT_TYPE_REMOVED_API_TYPE=Error
+API_COMPONENT_ELEMENT_TYPE_REMOVED_REEXPORTED_API_TYPE=Error
+API_COMPONENT_ELEMENT_TYPE_REMOVED_REEXPORTED_TYPE=Error
+API_COMPONENT_ELEMENT_TYPE_REMOVED_TYPE=Error
+API_USE_SCAN_FIELD_SEVERITY=Error
+API_USE_SCAN_METHOD_SEVERITY=Error
+API_USE_SCAN_TYPE_SEVERITY=Error
+CLASS_ELEMENT_TYPE_ADDED_METHOD=Error
+CLASS_ELEMENT_TYPE_ADDED_RESTRICTIONS=Error
+CLASS_ELEMENT_TYPE_ADDED_TYPE_PARAMETER=Error
+CLASS_ELEMENT_TYPE_CHANGED_CONTRACTED_SUPERINTERFACES_SET=Error
+CLASS_ELEMENT_TYPE_CHANGED_DECREASE_ACCESS=Error
+CLASS_ELEMENT_TYPE_CHANGED_NON_ABSTRACT_TO_ABSTRACT=Error
+CLASS_ELEMENT_TYPE_CHANGED_NON_FINAL_TO_FINAL=Error
+CLASS_ELEMENT_TYPE_CHANGED_TYPE_CONVERSION=Error
+CLASS_ELEMENT_TYPE_REMOVED_CONSTRUCTOR=Error
+CLASS_ELEMENT_TYPE_REMOVED_FIELD=Error
+CLASS_ELEMENT_TYPE_REMOVED_METHOD=Error
+CLASS_ELEMENT_TYPE_REMOVED_SUPERCLASS=Error
+CLASS_ELEMENT_TYPE_REMOVED_TYPE_MEMBER=Error
+CLASS_ELEMENT_TYPE_REMOVED_TYPE_PARAMETER=Error
+CONSTRUCTOR_ELEMENT_TYPE_ADDED_TYPE_PARAMETER=Error
+CONSTRUCTOR_ELEMENT_TYPE_CHANGED_DECREASE_ACCESS=Error
+CONSTRUCTOR_ELEMENT_TYPE_CHANGED_VARARGS_TO_ARRAY=Error
+CONSTRUCTOR_ELEMENT_TYPE_REMOVED_TYPE_PARAMETER=Error
+ENUM_ELEMENT_TYPE_CHANGED_CONTRACTED_SUPERINTERFACES_SET=Error
+ENUM_ELEMENT_TYPE_CHANGED_TYPE_CONVERSION=Error
+ENUM_ELEMENT_TYPE_REMOVED_ENUM_CONSTANT=Error
+ENUM_ELEMENT_TYPE_REMOVED_FIELD=Error
+ENUM_ELEMENT_TYPE_REMOVED_METHOD=Error
+ENUM_ELEMENT_TYPE_REMOVED_TYPE_MEMBER=Error
+FIELD_ELEMENT_TYPE_ADDED_VALUE=Error
+FIELD_ELEMENT_TYPE_CHANGED_DECREASE_ACCESS=Error
+FIELD_ELEMENT_TYPE_CHANGED_FINAL_TO_NON_FINAL_STATIC_CONSTANT=Error
+FIELD_ELEMENT_TYPE_CHANGED_NON_FINAL_TO_FINAL=Error
+FIELD_ELEMENT_TYPE_CHANGED_NON_STATIC_TO_STATIC=Error
+FIELD_ELEMENT_TYPE_CHANGED_STATIC_TO_NON_STATIC=Error
+FIELD_ELEMENT_TYPE_CHANGED_TYPE=Error
+FIELD_ELEMENT_TYPE_CHANGED_VALUE=Error
+FIELD_ELEMENT_TYPE_REMOVED_TYPE_ARGUMENT=Error
+FIELD_ELEMENT_TYPE_REMOVED_VALUE=Error
+ILLEGAL_EXTEND=Warning
+ILLEGAL_IMPLEMENT=Warning
+ILLEGAL_INSTANTIATE=Warning
+ILLEGAL_OVERRIDE=Warning
+ILLEGAL_REFERENCE=Warning
+INTERFACE_ELEMENT_TYPE_ADDED_FIELD=Error
+INTERFACE_ELEMENT_TYPE_ADDED_METHOD=Error
+INTERFACE_ELEMENT_TYPE_ADDED_RESTRICTIONS=Error
+INTERFACE_ELEMENT_TYPE_ADDED_SUPER_INTERFACE_WITH_METHODS=Error
+INTERFACE_ELEMENT_TYPE_ADDED_TYPE_PARAMETER=Error
+INTERFACE_ELEMENT_TYPE_CHANGED_CONTRACTED_SUPERINTERFACES_SET=Error
+INTERFACE_ELEMENT_TYPE_CHANGED_TYPE_CONVERSION=Error
+INTERFACE_ELEMENT_TYPE_REMOVED_FIELD=Error
+INTERFACE_ELEMENT_TYPE_REMOVED_METHOD=Error
+INTERFACE_ELEMENT_TYPE_REMOVED_TYPE_MEMBER=Error
+INTERFACE_ELEMENT_TYPE_REMOVED_TYPE_PARAMETER=Error
+INVALID_ANNOTATION=Ignore
+INVALID_JAVADOC_TAG=Ignore
+INVALID_REFERENCE_IN_SYSTEM_LIBRARIES=Error
+LEAK_EXTEND=Warning
+LEAK_FIELD_DECL=Warning
+LEAK_IMPLEMENT=Warning
+LEAK_METHOD_PARAM=Warning
+LEAK_METHOD_RETURN_TYPE=Warning
+METHOD_ELEMENT_TYPE_ADDED_RESTRICTIONS=Error
+METHOD_ELEMENT_TYPE_ADDED_TYPE_PARAMETER=Error
+METHOD_ELEMENT_TYPE_CHANGED_DECREASE_ACCESS=Error
+METHOD_ELEMENT_TYPE_CHANGED_NON_ABSTRACT_TO_ABSTRACT=Error
+METHOD_ELEMENT_TYPE_CHANGED_NON_FINAL_TO_FINAL=Error
+METHOD_ELEMENT_TYPE_CHANGED_NON_STATIC_TO_STATIC=Error
+METHOD_ELEMENT_TYPE_CHANGED_STATIC_TO_NON_STATIC=Error
+METHOD_ELEMENT_TYPE_CHANGED_VARARGS_TO_ARRAY=Error
+METHOD_ELEMENT_TYPE_REMOVED_ANNOTATION_DEFAULT_VALUE=Error
+METHOD_ELEMENT_TYPE_REMOVED_TYPE_PARAMETER=Error
+MISSING_EE_DESCRIPTIONS=Error
+TYPE_PARAMETER_ELEMENT_TYPE_ADDED_CLASS_BOUND=Error
+TYPE_PARAMETER_ELEMENT_TYPE_ADDED_INTERFACE_BOUND=Error
+TYPE_PARAMETER_ELEMENT_TYPE_CHANGED_CLASS_BOUND=Error
+TYPE_PARAMETER_ELEMENT_TYPE_CHANGED_INTERFACE_BOUND=Error
+TYPE_PARAMETER_ELEMENT_TYPE_REMOVED_CLASS_BOUND=Error
+TYPE_PARAMETER_ELEMENT_TYPE_REMOVED_INTERFACE_BOUND=Error
+UNUSED_PROBLEM_FILTERS=Warning
+automatically_removed_unused_problem_filters=false
+eclipse.preferences.version=1
+incompatible_api_component_version=Error
+incompatible_api_component_version_include_major_without_breaking_change=Disabled
+incompatible_api_component_version_include_minor_without_api_change=Disabled
+invalid_since_tag_version=Error
+malformed_since_tag=Error
+missing_since_tag=Error
+report_api_breakage_when_major_version_incremented=Disabled
+report_resolution_errors_api_component=Warning
diff --git a/org.eclipse.jgit.lfs/.settings/org.eclipse.pde.core.prefs b/org.eclipse.jgit.lfs/.settings/org.eclipse.pde.core.prefs
new file mode 100644
index 0000000..923c37f
--- /dev/null
+++ b/org.eclipse.jgit.lfs/.settings/org.eclipse.pde.core.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+resolve.requirebundle=false
diff --git a/org.eclipse.jgit.lfs/BUCK b/org.eclipse.jgit.lfs/BUCK
new file mode 100644
index 0000000..ddb3a10
--- /dev/null
+++ b/org.eclipse.jgit.lfs/BUCK
@@ -0,0 +1,17 @@
+SRCS = glob(['src/**'])
+RESOURCES = glob(['resources/**'])
+
+java_library(
+  name = 'jgit-lfs',
+  srcs = SRCS,
+  resources = RESOURCES,
+  deps = [
+    '//org.eclipse.jgit:jgit'
+  ],
+  visibility = ['PUBLIC'],
+)
+
+java_sources(
+  name = 'jgit-lfs_src',
+  srcs = SRCS + RESOURCES,
+)
diff --git a/org.eclipse.jgit.lfs/META-INF/MANIFEST.MF b/org.eclipse.jgit.lfs/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..9a1fd7b
--- /dev/null
+++ b/org.eclipse.jgit.lfs/META-INF/MANIFEST.MF
@@ -0,0 +1,15 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: %plugin_name
+Bundle-SymbolicName: org.eclipse.jgit.lfs
+Bundle-Version: 4.3.0.qualifier
+Bundle-Localization: plugin
+Bundle-Vendor: %provider_name
+Export-Package: org.eclipse.jgit.lfs.errors;version="4.3.0",
+ org.eclipse.jgit.lfs.internal;version="4.3.0";x-friends:="org.eclipse.jgit.lfs.test",
+ org.eclipse.jgit.lfs.lib;version="4.3.0"
+Bundle-RequiredExecutionEnvironment: JavaSE-1.7
+Import-Package: org.eclipse.jgit.internal.storage.file;version="[4.3.0,4.4.0)",
+ org.eclipse.jgit.lib;version="[4.3.0,4.4.0)",
+ org.eclipse.jgit.nls;version="[4.3.0,4.4.0)",
+ org.eclipse.jgit.util;version="[4.3.0,4.4.0)"
diff --git a/org.eclipse.jgit.lfs/about.html b/org.eclipse.jgit.lfs/about.html
new file mode 100644
index 0000000..721e62d
--- /dev/null
+++ b/org.eclipse.jgit.lfs/about.html
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
+<title>Eclipse Distribution License - Version 1.0</title>
+<style type="text/css">
+  body {
+    size: 8.5in 11.0in;
+    margin: 0.25in 0.5in 0.25in 0.5in;
+    tab-interval: 0.5in;
+    }
+  p {
+    margin-left: auto;
+    margin-top:  0.5em;
+    margin-bottom: 0.5em;
+    }
+  p.list {
+  	margin-left: 0.5in;
+    margin-top:  0.05em;
+    margin-bottom: 0.05em;
+    }
+  </style>
+
+</head>
+
+<body lang="EN-US">
+
+<p><b>Eclipse Distribution License - v 1.0</b></p>
+
+<p>Copyright (c) 2007, Eclipse Foundation, Inc. and its licensors. </p>
+
+<p>All rights reserved.</p>
+<p>Redistribution and use in source and binary forms, with or without modification,
+	are permitted provided that the following conditions are met:
+<ul><li>Redistributions of source code must retain the above copyright notice,
+	this list of conditions and the following disclaimer. </li>
+<li>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. </li>
+<li>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. </li></ul>
+</p>
+<p>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.</p>
+
+</body>
+
+</html>
diff --git a/org.eclipse.jgit.lfs/build.properties b/org.eclipse.jgit.lfs/build.properties
new file mode 100644
index 0000000..8148271
--- /dev/null
+++ b/org.eclipse.jgit.lfs/build.properties
@@ -0,0 +1,7 @@
+source.. = src/,\
+           resources/
+output.. = bin/
+bin.includes = META-INF/,\
+               .,\
+               plugin.properties,\
+               about.html
diff --git a/org.eclipse.jgit.lfs/plugin.properties b/org.eclipse.jgit.lfs/plugin.properties
new file mode 100644
index 0000000..7c22ddb
--- /dev/null
+++ b/org.eclipse.jgit.lfs/plugin.properties
@@ -0,0 +1,2 @@
+plugin_name=JGit Large File Storage
+provider_name=Eclipse JGit
diff --git a/org.eclipse.jgit.lfs/pom.xml b/org.eclipse.jgit.lfs/pom.xml
new file mode 100644
index 0000000..bfee4ca
--- /dev/null
+++ b/org.eclipse.jgit.lfs/pom.xml
@@ -0,0 +1,140 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+   Copyright (C) 2015, Matthias Sohn <matthias.sohn@sap.com>
+   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.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>org.eclipse.jgit</groupId>
+    <artifactId>org.eclipse.jgit-parent</artifactId>
+    <version>4.3.0-SNAPSHOT</version>
+  </parent>
+
+  <artifactId>org.eclipse.jgit.lfs</artifactId>
+  <name>JGit - Large File Storage</name>
+
+  <description>
+    JGit Large File Storage (LFS) implementation.
+  </description>
+
+  <properties>
+    <translate-qualifier/>
+  </properties>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.eclipse.jgit</groupId>
+      <artifactId>org.eclipse.jgit</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+  </dependencies>
+  <build>
+    <sourceDirectory>src/</sourceDirectory>
+
+    <resources>
+      <resource>
+        <directory>.</directory>
+        <includes>
+          <include>plugin.properties</include>
+          <include>about.html</include>
+        </includes>
+      </resource>
+      <resource>
+        <directory>resources/</directory>
+      </resource>
+    </resources>
+
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-source-plugin</artifactId>
+        <inherited>true</inherited>
+        <executions>
+          <execution>
+            <id>attach-sources</id>
+            <phase>process-classes</phase>
+            <goals>
+              <goal>jar</goal>
+            </goals>
+            <configuration>
+              <archive>
+                <manifestFile>${source-bundle-manifest}</manifestFile>
+              </archive>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+
+      <plugin>
+        <artifactId>maven-jar-plugin</artifactId>
+        <configuration>
+          <archive>
+            <manifestFile>${bundle-manifest}</manifestFile>
+          </archive>
+        </configuration>
+      </plugin>
+
+      <plugin>
+        <groupId>org.codehaus.mojo</groupId>
+        <artifactId>clirr-maven-plugin</artifactId>
+      </plugin>
+    </plugins>
+  </build>
+
+  <reporting>
+    <plugins>
+      <plugin>
+        <groupId>org.codehaus.mojo</groupId>
+        <artifactId>clirr-maven-plugin</artifactId>
+        <version>${clirr-version}</version>
+        <configuration>
+          <comparisonVersion>${jgit-last-release-version}</comparisonVersion>
+          <minSeverity>info</minSeverity>
+        </configuration>
+      </plugin>
+    </plugins>
+  </reporting>
+</project>
diff --git a/org.eclipse.jgit.lfs/resources/org/eclipse/jgit/lfs/internal/LfsText.properties b/org.eclipse.jgit.lfs/resources/org/eclipse/jgit/lfs/internal/LfsText.properties
new file mode 100644
index 0000000..700e2d5
--- /dev/null
+++ b/org.eclipse.jgit.lfs/resources/org/eclipse/jgit/lfs/internal/LfsText.properties
@@ -0,0 +1,4 @@
+incorrectLONG_OBJECT_ID_LENGTH=Incorrect LONG_OBJECT_ID_LENGTH.
+invalidLongId=Invalid id: {0}
+invalidLongIdLength=Invalid id length {0}; should be {1}
+requiredHashFunctionNotAvailable=Required hash function {0} not available.
\ No newline at end of file
diff --git a/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/errors/CorruptLongObjectException.java b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/errors/CorruptLongObjectException.java
new file mode 100644
index 0000000..fea148b
--- /dev/null
+++ b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/errors/CorruptLongObjectException.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2015, Matthias Sohn <matthias.sohn@sap.com>
+ * 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.lfs.errors;
+
+import org.eclipse.jgit.lfs.lib.AnyLongObjectId;
+
+/**
+ * Thrown when an object id is given that doesn't match the hash of the object's
+ * content
+ *
+ * @since 4.3
+ */
+public class CorruptLongObjectException extends IllegalArgumentException {
+
+	private static final long serialVersionUID = 1L;
+
+	private final AnyLongObjectId id;
+
+	private final AnyLongObjectId contentHash;
+
+	/**
+	 * Corrupt long object detected.
+	 *
+	 * @param id
+	 *            id of the long object
+	 * @param contentHash
+	 *            hash of the long object's content
+	 *
+	 * @param message
+	 */
+	public CorruptLongObjectException(AnyLongObjectId id,
+			AnyLongObjectId contentHash,
+			String message) {
+		super(message);
+		this.id = id;
+		this.contentHash = contentHash;
+	}
+
+	/**
+	 * @return the id of the object, i.e. the expected hash of the object's
+	 *         content
+	 */
+	public AnyLongObjectId getId() {
+		return id;
+	}
+
+	/**
+	 * @return the actual hash of the object's content which doesn't match the
+	 *         object's id when this exception is thrown which signals that the
+	 *         object has been corrupted
+	 */
+	public AnyLongObjectId getContentHash() {
+		return contentHash;
+	}
+}
diff --git a/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/errors/InvalidLongObjectIdException.java b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/errors/InvalidLongObjectIdException.java
new file mode 100644
index 0000000..1f6e2d1
--- /dev/null
+++ b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/errors/InvalidLongObjectIdException.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2009, Jonas Fonseca <fonseca@diku.dk>
+ * Copyright (C) 2007, Robin Rosenberg <robin.rosenberg@dewire.com>
+ * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
+ * 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.lfs.errors;
+
+import java.io.UnsupportedEncodingException;
+import java.text.MessageFormat;
+
+import org.eclipse.jgit.lfs.internal.LfsText;
+
+/**
+ * Thrown when an invalid long object id is passed in as an argument.
+ *
+ * @since 4.3
+ */
+public class InvalidLongObjectIdException extends IllegalArgumentException {
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * Create exception with bytes of the invalid object id.
+	 *
+	 * @param bytes containing the invalid id.
+	 * @param offset in the byte array where the error occurred.
+	 * @param length of the sequence of invalid bytes.
+	 */
+	public InvalidLongObjectIdException(byte[] bytes, int offset, int length) {
+		super(MessageFormat.format(LfsText.get().invalidLongId,
+				asAscii(bytes, offset, length)));
+	}
+
+	/**
+	 * @param idString
+	 *            String containing the invalid id
+	 */
+	public InvalidLongObjectIdException(String idString) {
+		super(MessageFormat.format(LfsText.get().invalidLongId, idString));
+	}
+
+	private static String asAscii(byte[] bytes, int offset, int length) {
+		try {
+			return ": " + new String(bytes, offset, length, "US-ASCII"); //$NON-NLS-1$ //$NON-NLS-2$
+		} catch (UnsupportedEncodingException e2) {
+			return ""; //$NON-NLS-1$
+		} catch (StringIndexOutOfBoundsException e2) {
+			return ""; //$NON-NLS-1$
+		}
+	}
+}
diff --git a/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/internal/LfsText.java b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/internal/LfsText.java
new file mode 100644
index 0000000..eaffcc9
--- /dev/null
+++ b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/internal/LfsText.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2015, Matthias Sohn <matthias.sohn@sap.com>
+ * 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.lfs.internal;
+
+import org.eclipse.jgit.nls.NLS;
+import org.eclipse.jgit.nls.TranslationBundle;
+
+/**
+ * Translation bundle for JGit LFS server
+ */
+public class LfsText extends TranslationBundle {
+
+	/**
+	 * @return an instance of this translation bundle
+	 */
+	public static LfsText get() {
+		return NLS.getBundleFor(LfsText.class);
+	}
+
+	// @formatter:off
+	/***/ public String incorrectLONG_OBJECT_ID_LENGTH;
+	/***/ public String invalidLongId;
+	/***/ public String invalidLongIdLength;
+	/***/ public String requiredHashFunctionNotAvailable;
+}
diff --git a/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/lib/AbbreviatedLongObjectId.java b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/lib/AbbreviatedLongObjectId.java
new file mode 100644
index 0000000..e9eb0e3
--- /dev/null
+++ b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/lib/AbbreviatedLongObjectId.java
@@ -0,0 +1,375 @@
+/*
+ * Copyright (C) 2015, Matthias Sohn <matthias.sohn@sap.com>
+ * 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.lfs.lib;
+
+import java.io.Serializable;
+import java.text.MessageFormat;
+
+import org.eclipse.jgit.lfs.errors.InvalidLongObjectIdException;
+import org.eclipse.jgit.lfs.internal.LfsText;
+import org.eclipse.jgit.lib.AbbreviatedObjectId;
+import org.eclipse.jgit.lib.AnyObjectId;
+import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.util.NB;
+import org.eclipse.jgit.util.RawParseUtils;
+
+/**
+ * A prefix abbreviation of an {@link LongObjectId}.
+ * <p>
+ * Enable abbreviating SHA-256 strings used by Git LFS, using sufficient leading
+ * digits from the LongObjectId name to still be unique within the repository
+ * the string was generated from. These ids are likely to be unique for a useful
+ * period of time, especially if they contain at least 6-10 hex digits.
+ * <p>
+ * This class converts the hex string into a binary form, to make it more
+ * efficient for matching against an object.
+ *
+ * Ported to SHA-256 from {@link AbbreviatedObjectId}
+ *
+ * @since 4.3
+ */
+public final class AbbreviatedLongObjectId implements Serializable {
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * Test a string of characters to verify it is a hex format.
+	 * <p>
+	 * If true the string can be parsed with {@link #fromString(String)}.
+	 *
+	 * @param id
+	 *            the string to test.
+	 * @return true if the string can converted into an AbbreviatedObjectId.
+	 */
+	public static final boolean isId(final String id) {
+		if (id.length() < 2
+				|| Constants.LONG_OBJECT_ID_STRING_LENGTH < id.length())
+			return false;
+		try {
+			for (int i = 0; i < id.length(); i++)
+				RawParseUtils.parseHexInt4((byte) id.charAt(i));
+			return true;
+		} catch (ArrayIndexOutOfBoundsException e) {
+			return false;
+		}
+	}
+
+	/**
+	 * Convert an AbbreviatedObjectId from hex characters (US-ASCII).
+	 *
+	 * @param buf
+	 *            the US-ASCII buffer to read from.
+	 * @param offset
+	 *            position to read the first character from.
+	 * @param end
+	 *            one past the last position to read (<code>end-offset</code> is
+	 *            the length of the string).
+	 * @return the converted object id.
+	 */
+	public static final AbbreviatedLongObjectId fromString(final byte[] buf,
+			final int offset, final int end) {
+		if (end - offset > Constants.LONG_OBJECT_ID_STRING_LENGTH)
+			throw new IllegalArgumentException(MessageFormat.format(
+							LfsText.get().invalidLongIdLength,
+					Integer.valueOf(end - offset),
+					Integer.valueOf(Constants.LONG_OBJECT_ID_STRING_LENGTH)));
+		return fromHexString(buf, offset, end);
+	}
+
+	/**
+	 * Convert an AbbreviatedObjectId from an {@link AnyObjectId}.
+	 * <p>
+	 * This method copies over all bits of the Id, and is therefore complete
+	 * (see {@link #isComplete()}).
+	 *
+	 * @param id
+	 *            the {@link ObjectId} to convert from.
+	 * @return the converted object id.
+	 */
+	public static final AbbreviatedLongObjectId fromLongObjectId(
+			AnyLongObjectId id) {
+		return new AbbreviatedLongObjectId(
+				Constants.LONG_OBJECT_ID_STRING_LENGTH, id.w1, id.w2, id.w3,
+				id.w4);
+	}
+
+	/**
+	 * Convert an AbbreviatedLongObjectId from hex characters.
+	 *
+	 * @param str
+	 *            the string to read from. Must be &lt;= 64 characters.
+	 * @return the converted object id.
+	 */
+	public static final AbbreviatedLongObjectId fromString(final String str) {
+		if (str.length() > Constants.LONG_OBJECT_ID_STRING_LENGTH)
+			throw new IllegalArgumentException(
+					MessageFormat.format(LfsText.get().invalidLongId, str));
+		final byte[] b = org.eclipse.jgit.lib.Constants.encodeASCII(str);
+		return fromHexString(b, 0, b.length);
+	}
+
+	private static final AbbreviatedLongObjectId fromHexString(final byte[] bs,
+			int ptr, final int end) {
+		try {
+			final long a = hexUInt64(bs, ptr, end);
+			final long b = hexUInt64(bs, ptr + 16, end);
+			final long c = hexUInt64(bs, ptr + 32, end);
+			final long d = hexUInt64(bs, ptr + 48, end);
+			return new AbbreviatedLongObjectId(end - ptr, a, b, c, d);
+		} catch (ArrayIndexOutOfBoundsException e1) {
+			throw new InvalidLongObjectIdException(bs, ptr, end - ptr);
+		}
+	}
+
+	private static final long hexUInt64(final byte[] bs, int p, final int end) {
+		if (16 <= end - p)
+			return RawParseUtils.parseHexInt64(bs, p);
+
+		long r = 0;
+		int n = 0;
+		while (n < 16 && p < end) {
+			r <<= 4;
+			r |= RawParseUtils.parseHexInt4(bs[p++]);
+			n++;
+		}
+		return r << (16 - n) * 4;
+	}
+
+	static long mask(final int nibbles, final long word, final long v) {
+		final long b = (word - 1) * 16;
+		if (b + 16 <= nibbles) {
+			// We have all of the bits required for this word.
+			//
+			return v;
+		}
+
+		if (nibbles <= b) {
+			// We have none of the bits required for this word.
+			//
+			return 0;
+		}
+
+		final long s = 64 - (nibbles - b) * 4;
+		return (v >>> s) << s;
+	}
+
+	/** Number of half-bytes used by this id. */
+	final int nibbles;
+
+	final long w1;
+
+	final long w2;
+
+	final long w3;
+
+	final long w4;
+
+	AbbreviatedLongObjectId(final int n, final long new_1, final long new_2,
+			final long new_3, final long new_4) {
+		nibbles = n;
+		w1 = new_1;
+		w2 = new_2;
+		w3 = new_3;
+		w4 = new_4;
+	}
+
+	/** @return number of hex digits appearing in this id */
+	public int length() {
+		return nibbles;
+	}
+
+	/** @return true if this ObjectId is actually a complete id. */
+	public boolean isComplete() {
+		return length() == Constants.LONG_OBJECT_ID_STRING_LENGTH;
+	}
+
+	/** @return a complete ObjectId; null if {@link #isComplete()} is false */
+	public LongObjectId toLongObjectId() {
+		return isComplete() ? new LongObjectId(w1, w2, w3, w4) : null;
+	}
+
+	/**
+	 * Compares this abbreviation to a full object id.
+	 *
+	 * @param other
+	 *            the other object id.
+	 * @return &lt;0 if this abbreviation names an object that is less than
+	 *         <code>other</code>; 0 if this abbreviation exactly matches the
+	 *         first {@link #length()} digits of <code>other.name()</code>;
+	 *         &gt;0 if this abbreviation names an object that is after
+	 *         <code>other</code>.
+	 */
+	public final int prefixCompare(final AnyLongObjectId other) {
+		int cmp;
+
+		cmp = NB.compareUInt64(w1, mask(1, other.w1));
+		if (cmp != 0)
+			return cmp;
+
+		cmp = NB.compareUInt64(w2, mask(2, other.w2));
+		if (cmp != 0)
+			return cmp;
+
+		cmp = NB.compareUInt64(w3, mask(3, other.w3));
+		if (cmp != 0)
+			return cmp;
+
+		return NB.compareUInt64(w4, mask(4, other.w4));
+	}
+
+	/**
+	 * Compare this abbreviation to a network-byte-order LongObjectId.
+	 *
+	 * @param bs
+	 *            array containing the other LongObjectId in network byte order.
+	 * @param p
+	 *            position within {@code bs} to start the compare at. At least
+	 *            32 bytes, starting at this position are required.
+	 * @return &lt;0 if this abbreviation names an object that is less than
+	 *         <code>other</code>; 0 if this abbreviation exactly matches the
+	 *         first {@link #length()} digits of <code>other.name()</code>;
+	 *         &gt;0 if this abbreviation names an object that is after
+	 *         <code>other</code>.
+	 */
+	public final int prefixCompare(final byte[] bs, final int p) {
+		int cmp;
+
+		cmp = NB.compareUInt64(w1, mask(1, NB.decodeInt64(bs, p)));
+		if (cmp != 0)
+			return cmp;
+
+		cmp = NB.compareUInt64(w2, mask(2, NB.decodeInt64(bs, p + 8)));
+		if (cmp != 0)
+			return cmp;
+
+		cmp = NB.compareUInt64(w3, mask(3, NB.decodeInt64(bs, p + 16)));
+		if (cmp != 0)
+			return cmp;
+
+		return NB.compareUInt64(w4, mask(4, NB.decodeInt64(bs, p + 24)));
+	}
+
+	/**
+	 * Compare this abbreviation to a network-byte-order LongObjectId.
+	 *
+	 * @param bs
+	 *            array containing the other LongObjectId in network byte order.
+	 * @param p
+	 *            position within {@code bs} to start the compare at. At least 4
+	 *            longs, starting at this position are required.
+	 * @return &lt;0 if this abbreviation names an object that is less than
+	 *         <code>other</code>; 0 if this abbreviation exactly matches the
+	 *         first {@link #length()} digits of <code>other.name()</code>;
+	 *         &gt;0 if this abbreviation names an object that is after
+	 *         <code>other</code>.
+	 */
+	public final int prefixCompare(final long[] bs, final int p) {
+		int cmp;
+
+		cmp = NB.compareUInt64(w1, mask(1, bs[p]));
+		if (cmp != 0)
+			return cmp;
+
+		cmp = NB.compareUInt64(w2, mask(2, bs[p + 1]));
+		if (cmp != 0)
+			return cmp;
+
+		cmp = NB.compareUInt64(w3, mask(3, bs[p + 2]));
+		if (cmp != 0)
+			return cmp;
+
+		return NB.compareUInt64(w4, mask(4, bs[p + 3]));
+	}
+
+	/** @return value for a fan-out style map, only valid of length &gt;= 2. */
+	public final int getFirstByte() {
+		return (int) (w1 >>> 56);
+	}
+
+	private long mask(final long word, final long v) {
+		return mask(nibbles, word, v);
+	}
+
+	@Override
+	public int hashCode() {
+		return (int) (w1 >> 32);
+	}
+
+	@Override
+	public boolean equals(final Object o) {
+		if (o instanceof AbbreviatedLongObjectId) {
+			final AbbreviatedLongObjectId b = (AbbreviatedLongObjectId) o;
+			return nibbles == b.nibbles && w1 == b.w1 && w2 == b.w2
+					&& w3 == b.w3 && w4 == b.w4;
+		}
+		return false;
+	}
+
+	/**
+	 * @return string form of the abbreviation, in lower case hexadecimal.
+	 */
+	public final String name() {
+		final char[] b = new char[Constants.LONG_OBJECT_ID_STRING_LENGTH];
+
+		AnyLongObjectId.formatHexChar(b, 0, w1);
+		if (nibbles <= 16)
+			return new String(b, 0, nibbles);
+
+		AnyLongObjectId.formatHexChar(b, 16, w2);
+		if (nibbles <= 32)
+			return new String(b, 0, nibbles);
+
+		AnyLongObjectId.formatHexChar(b, 32, w3);
+		if (nibbles <= 48)
+			return new String(b, 0, nibbles);
+
+		AnyLongObjectId.formatHexChar(b, 48, w4);
+		return new String(b, 0, nibbles);
+	}
+
+	@SuppressWarnings("nls")
+	@Override
+	public String toString() {
+		return "AbbreviatedLongObjectId[" + name() + "]"; //$NON-NLS-1$
+	}
+}
diff --git a/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/lib/AnyLongObjectId.java b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/lib/AnyLongObjectId.java
new file mode 100644
index 0000000..1f0df88
--- /dev/null
+++ b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/lib/AnyLongObjectId.java
@@ -0,0 +1,555 @@
+/*
+ * Copyright (C) 2015, Matthias Sohn <matthias.sohn@sap.com>
+ * 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.lfs.lib;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.Writer;
+import java.nio.ByteBuffer;
+
+import org.eclipse.jgit.lib.AnyObjectId;
+import org.eclipse.jgit.lib.ObjectReader;
+import org.eclipse.jgit.util.NB;
+
+/**
+ * A (possibly mutable) SHA-256 abstraction.
+ * <p>
+ * If this is an instance of {@link MutableLongObjectId} the concept of equality
+ * with this instance can alter at any time, if this instance is modified to
+ * represent a different object name.
+ *
+ * Ported to SHA-256 from {@link AnyObjectId}
+ *
+ * @since 4.3
+ */
+public abstract class AnyLongObjectId implements Comparable<AnyLongObjectId> {
+
+	/**
+	 * Compare two object identifier byte sequences for equality.
+	 *
+	 * @param firstObjectId
+	 *            the first identifier to compare. Must not be null.
+	 * @param secondObjectId
+	 *            the second identifier to compare. Must not be null.
+	 * @return true if the two identifiers are the same.
+	 */
+	public static boolean equals(final AnyLongObjectId firstObjectId,
+			final AnyLongObjectId secondObjectId) {
+		if (firstObjectId == secondObjectId)
+			return true;
+
+		// We test word 2 first as odds are someone already used our
+		// word 1 as a hash code, and applying that came up with these
+		// two instances we are comparing for equality. Therefore the
+		// first two words are very likely to be identical. We want to
+		// break away from collisions as quickly as possible.
+		//
+		return firstObjectId.w2 == secondObjectId.w2
+				&& firstObjectId.w3 == secondObjectId.w3
+				&& firstObjectId.w4 == secondObjectId.w4
+				&& firstObjectId.w1 == secondObjectId.w1;
+	}
+
+	long w1;
+
+	long w2;
+
+	long w3;
+
+	long w4;
+
+	/**
+	 * Get the first 8 bits of the LongObjectId.
+	 *
+	 * This is a faster version of {@code getByte(0)}.
+	 *
+	 * @return a discriminator usable for a fan-out style map. Returned values
+	 *         are unsigned and thus are in the range [0,255] rather than the
+	 *         signed byte range of [-128, 127].
+	 */
+	public final int getFirstByte() {
+		return (int) (w1 >>> 56);
+	}
+
+	/**
+	 * Get the second 8 bits of the LongObjectId.
+	 *
+	 * @return a discriminator usable for a fan-out style map. Returned values
+	 *         are unsigned and thus are in the range [0,255] rather than the
+	 *         signed byte range of [-128, 127].
+	 */
+	public final int getSecondByte() {
+		return (int) ((w1 >>> 48) & 0xff);
+	}
+
+	/**
+	 * Get any byte from the LongObjectId.
+	 *
+	 * Callers hard-coding {@code getByte(0)} should instead use the much faster
+	 * special case variant {@link #getFirstByte()}.
+	 *
+	 * @param index
+	 *            index of the byte to obtain from the raw form of the
+	 *            LongObjectId. Must be in range [0,
+	 *            {@link Constants#LONG_OBJECT_ID_LENGTH}).
+	 * @return the value of the requested byte at {@code index}. Returned values
+	 *         are unsigned and thus are in the range [0,255] rather than the
+	 *         signed byte range of [-128, 127].
+	 * @throws ArrayIndexOutOfBoundsException
+	 *             {@code index} is less than 0, equal to
+	 *             {@link Constants#LONG_OBJECT_ID_LENGTH}, or greater than
+	 *             {@link Constants#LONG_OBJECT_ID_LENGTH}.
+	 */
+	public final int getByte(int index) {
+		long w;
+		switch (index >> 3) {
+		case 0:
+			w = w1;
+			break;
+		case 1:
+			w = w2;
+			break;
+		case 2:
+			w = w3;
+			break;
+		case 3:
+			w = w4;
+			break;
+		default:
+			throw new ArrayIndexOutOfBoundsException(index);
+		}
+
+		return (int) ((w >>> (8 * (15 - (index & 15)))) & 0xff);
+	}
+
+	/**
+	 * Compare this LongObjectId to another and obtain a sort ordering.
+	 *
+	 * @param other
+	 *            the other id to compare to. Must not be null.
+	 * @return &lt; 0 if this id comes before other; 0 if this id is equal to
+	 *         other; &gt; 0 if this id comes after other.
+	 */
+	public final int compareTo(final AnyLongObjectId other) {
+		if (this == other)
+			return 0;
+
+		int cmp;
+
+		cmp = NB.compareUInt64(w1, other.w1);
+		if (cmp != 0)
+			return cmp;
+
+		cmp = NB.compareUInt64(w2, other.w2);
+		if (cmp != 0)
+			return cmp;
+
+		cmp = NB.compareUInt64(w3, other.w3);
+		if (cmp != 0)
+			return cmp;
+
+		return NB.compareUInt64(w4, other.w4);
+	}
+
+	/**
+	 * Compare this LongObjectId to a network-byte-order LongObjectId.
+	 *
+	 * @param bs
+	 *            array containing the other LongObjectId in network byte order.
+	 * @param p
+	 *            position within {@code bs} to start the compare at. At least
+	 *            32 bytes, starting at this position are required.
+	 * @return a negative integer, zero, or a positive integer as this object is
+	 *         less than, equal to, or greater than the specified object.
+	 */
+	public final int compareTo(final byte[] bs, final int p) {
+		int cmp;
+
+		cmp = NB.compareUInt64(w1, NB.decodeInt64(bs, p));
+		if (cmp != 0)
+			return cmp;
+
+		cmp = NB.compareUInt64(w2, NB.decodeInt64(bs, p + 8));
+		if (cmp != 0)
+			return cmp;
+
+		cmp = NB.compareUInt64(w3, NB.decodeInt64(bs, p + 16));
+		if (cmp != 0)
+			return cmp;
+
+		return NB.compareUInt64(w4, NB.decodeInt64(bs, p + 24));
+	}
+
+	/**
+	 * Compare this LongObjectId to a network-byte-order LongObjectId.
+	 *
+	 * @param bs
+	 *            array containing the other LongObjectId in network byte order.
+	 * @param p
+	 *            position within {@code bs} to start the compare at. At least 4
+	 *            longs, starting at this position are required.
+	 * @return a negative integer, zero, or a positive integer as this object is
+	 *         less than, equal to, or greater than the specified object.
+	 */
+	public final int compareTo(final long[] bs, final int p) {
+		int cmp;
+
+		cmp = NB.compareUInt64(w1, bs[p]);
+		if (cmp != 0)
+			return cmp;
+
+		cmp = NB.compareUInt64(w2, bs[p + 1]);
+		if (cmp != 0)
+			return cmp;
+
+		cmp = NB.compareUInt64(w3, bs[p + 2]);
+		if (cmp != 0)
+			return cmp;
+
+		return NB.compareUInt64(w4, bs[p + 3]);
+	}
+
+	/**
+	 * Tests if this LongObjectId starts with the given abbreviation.
+	 *
+	 * @param abbr
+	 *            the abbreviation.
+	 * @return true if this LongObjectId begins with the abbreviation; else
+	 *         false.
+	 */
+	public boolean startsWith(final AbbreviatedLongObjectId abbr) {
+		return abbr.prefixCompare(this) == 0;
+	}
+
+	public final int hashCode() {
+		return (int) (w1 >> 32);
+	}
+
+	/**
+	 * Determine if this LongObjectId has exactly the same value as another.
+	 *
+	 * @param other
+	 *            the other id to compare to. May be null.
+	 * @return true only if both LongObjectIds have identical bits.
+	 */
+	public final boolean equals(final AnyLongObjectId other) {
+		return other != null ? equals(this, other) : false;
+	}
+
+	public final boolean equals(final Object o) {
+		if (o instanceof AnyLongObjectId)
+			return equals((AnyLongObjectId) o);
+		else
+			return false;
+	}
+
+	/**
+	 * Copy this LongObjectId to an output writer in raw binary.
+	 *
+	 * @param w
+	 *            the buffer to copy to. Must be in big endian order.
+	 */
+	public void copyRawTo(final ByteBuffer w) {
+		w.putLong(w1);
+		w.putLong(w2);
+		w.putLong(w3);
+		w.putLong(w4);
+	}
+
+	/**
+	 * Copy this LongObjectId to a byte array.
+	 *
+	 * @param b
+	 *            the buffer to copy to.
+	 * @param o
+	 *            the offset within b to write at.
+	 */
+	public void copyRawTo(final byte[] b, final int o) {
+		NB.encodeInt64(b, o, w1);
+		NB.encodeInt64(b, o + 8, w2);
+		NB.encodeInt64(b, o + 16, w3);
+		NB.encodeInt64(b, o + 24, w4);
+	}
+
+	/**
+	 * Copy this LongObjectId to an long array.
+	 *
+	 * @param b
+	 *            the buffer to copy to.
+	 * @param o
+	 *            the offset within b to write at.
+	 */
+	public void copyRawTo(final long[] b, final int o) {
+		b[o] = w1;
+		b[o + 1] = w2;
+		b[o + 2] = w3;
+		b[o + 3] = w4;
+	}
+
+	/**
+	 * Copy this LongObjectId to an output writer in raw binary.
+	 *
+	 * @param w
+	 *            the stream to write to.
+	 * @throws IOException
+	 *             the stream writing failed.
+	 */
+	public void copyRawTo(final OutputStream w) throws IOException {
+		writeRawLong(w, w1);
+		writeRawLong(w, w2);
+		writeRawLong(w, w3);
+		writeRawLong(w, w4);
+	}
+
+	private static void writeRawLong(final OutputStream w, long v)
+			throws IOException {
+		w.write((int) (v >>> 56));
+		w.write((int) (v >>> 48));
+		w.write((int) (v >>> 40));
+		w.write((int) (v >>> 32));
+		w.write((int) (v >>> 24));
+		w.write((int) (v >>> 16));
+		w.write((int) (v >>> 8));
+		w.write((int) v);
+	}
+
+	/**
+	 * Copy this LongObjectId to an output writer in hex format.
+	 *
+	 * @param w
+	 *            the stream to copy to.
+	 * @throws IOException
+	 *             the stream writing failed.
+	 */
+	public void copyTo(final OutputStream w) throws IOException {
+		w.write(toHexByteArray());
+	}
+
+	/**
+	 * Copy this LongObjectId to a byte array in hex format.
+	 *
+	 * @param b
+	 *            the buffer to copy to.
+	 * @param o
+	 *            the offset within b to write at.
+	 */
+	public void copyTo(byte[] b, int o) {
+		formatHexByte(b, o + 0, w1);
+		formatHexByte(b, o + 16, w2);
+		formatHexByte(b, o + 32, w3);
+		formatHexByte(b, o + 48, w4);
+	}
+
+	/**
+	 * Copy this LongObjectId to a ByteBuffer in hex format.
+	 *
+	 * @param b
+	 *            the buffer to copy to.
+	 */
+	public void copyTo(ByteBuffer b) {
+		b.put(toHexByteArray());
+	}
+
+	private byte[] toHexByteArray() {
+		final byte[] dst = new byte[Constants.LONG_OBJECT_ID_STRING_LENGTH];
+		formatHexByte(dst, 0, w1);
+		formatHexByte(dst, 16, w2);
+		formatHexByte(dst, 32, w3);
+		formatHexByte(dst, 48, w4);
+		return dst;
+	}
+
+	private static final byte[] hexbyte = { '0', '1', '2', '3', '4', '5', '6',
+			'7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
+
+	private static void formatHexByte(final byte[] dst, final int p, long w) {
+		int o = p + 15;
+		while (o >= p && w != 0) {
+			dst[o--] = hexbyte[(int) (w & 0xf)];
+			w >>>= 4;
+		}
+		while (o >= p)
+			dst[o--] = '0';
+	}
+
+	/**
+	 * Copy this LongObjectId to an output writer in hex format.
+	 *
+	 * @param w
+	 *            the stream to copy to.
+	 * @throws IOException
+	 *             the stream writing failed.
+	 */
+	public void copyTo(final Writer w) throws IOException {
+		w.write(toHexCharArray());
+	}
+
+	/**
+	 * Copy this LongObjectId to an output writer in hex format.
+	 *
+	 * @param tmp
+	 *            temporary char array to buffer construct into before writing.
+	 *            Must be at least large enough to hold 2 digits for each byte
+	 *            of object id (64 characters or larger).
+	 * @param w
+	 *            the stream to copy to.
+	 * @throws IOException
+	 *             the stream writing failed.
+	 */
+	public void copyTo(final char[] tmp, final Writer w) throws IOException {
+		toHexCharArray(tmp);
+		w.write(tmp, 0, Constants.LONG_OBJECT_ID_STRING_LENGTH);
+	}
+
+	/**
+	 * Copy this LongObjectId to a StringBuilder in hex format.
+	 *
+	 * @param tmp
+	 *            temporary char array to buffer construct into before writing.
+	 *            Must be at least large enough to hold 2 digits for each byte
+	 *            of object id (64 characters or larger).
+	 * @param w
+	 *            the string to append onto.
+	 */
+	public void copyTo(final char[] tmp, final StringBuilder w) {
+		toHexCharArray(tmp);
+		w.append(tmp, 0, Constants.LONG_OBJECT_ID_STRING_LENGTH);
+	}
+
+	char[] toHexCharArray() {
+		final char[] dst = new char[Constants.LONG_OBJECT_ID_STRING_LENGTH];
+		toHexCharArray(dst);
+		return dst;
+	}
+
+	private void toHexCharArray(final char[] dst) {
+		formatHexChar(dst, 0, w1);
+		formatHexChar(dst, 16, w2);
+		formatHexChar(dst, 32, w3);
+		formatHexChar(dst, 48, w4);
+	}
+
+	private static final char[] hexchar = { '0', '1', '2', '3', '4', '5', '6',
+			'7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
+
+	static void formatHexChar(final char[] dst, final int p, long w) {
+		int o = p + 15;
+		while (o >= p && w != 0) {
+			dst[o--] = hexchar[(int) (w & 0xf)];
+			w >>>= 4;
+		}
+		while (o >= p)
+			dst[o--] = '0';
+	}
+
+	@SuppressWarnings("nls")
+	@Override
+	public String toString() {
+		return "AnyLongObjectId[" + name() + "]";
+	}
+
+	/**
+	 * @return string form of the SHA-256, in lower case hexadecimal.
+	 */
+	public final String name() {
+		return new String(toHexCharArray());
+	}
+
+	/**
+	 * @return string form of the SHA-256, in lower case hexadecimal.
+	 */
+	public final String getName() {
+		return name();
+	}
+
+	/**
+	 * Return an abbreviation (prefix) of this object SHA-256.
+	 * <p>
+	 * This implementation does not guarantee uniqueness. Callers should instead
+	 * use {@link ObjectReader#abbreviate(AnyObjectId, int)} to obtain a unique
+	 * abbreviation within the scope of a particular object database.
+	 *
+	 * @param len
+	 *            length of the abbreviated string.
+	 * @return SHA-256 abbreviation.
+	 */
+	public AbbreviatedLongObjectId abbreviate(final int len) {
+		final long a = AbbreviatedLongObjectId.mask(len, 1, w1);
+		final long b = AbbreviatedLongObjectId.mask(len, 2, w2);
+		final long c = AbbreviatedLongObjectId.mask(len, 3, w3);
+		final long d = AbbreviatedLongObjectId.mask(len, 4, w4);
+		return new AbbreviatedLongObjectId(len, a, b, c, d);
+	}
+
+	/**
+	 * Obtain an immutable copy of this current object.
+	 * <p>
+	 * Only returns <code>this</code> if this instance is an unsubclassed
+	 * instance of {@link LongObjectId}; otherwise a new instance is returned
+	 * holding the same value.
+	 * <p>
+	 * This method is useful to shed any additional memory that may be tied to
+	 * the subclass, yet retain the unique identity of the object id for future
+	 * lookups within maps and repositories.
+	 *
+	 * @return an immutable copy, using the smallest memory footprint possible.
+	 */
+	public final LongObjectId copy() {
+		if (getClass() == LongObjectId.class)
+			return (LongObjectId) this;
+		return new LongObjectId(this);
+	}
+
+	/**
+	 * Obtain an immutable copy of this current object.
+	 * <p>
+	 * See {@link #copy()} if <code>this</code> is a possibly subclassed (but
+	 * immutable) identity and the application needs a lightweight identity
+	 * <i>only</i> reference.
+	 *
+	 * @return an immutable copy. May be <code>this</code> if this is already an
+	 *         immutable instance.
+	 */
+	public abstract LongObjectId toObjectId();
+}
diff --git a/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/lib/Constants.java b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/lib/Constants.java
new file mode 100644
index 0000000..3cadbf7
--- /dev/null
+++ b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/lib/Constants.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2015, Matthias Sohn <matthias.sohn@sap.com>
+ * 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.lfs.lib;
+
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.text.MessageFormat;
+
+import org.eclipse.jgit.lfs.internal.LfsText;
+
+/**
+ * Misc. constants used throughout JGit LFS extension.
+ *
+ * @since 4.3
+ **/
+@SuppressWarnings("nls")
+public final class Constants {
+	/** Hash function used natively by Git LFS extension for large objects. */
+	private static final String LONG_HASH_FUNCTION = "SHA-256";
+
+	/**
+	 * A Git LFS large object hash is 256 bits, i.e. 32 bytes.
+	 * <p>
+	 * Changing this assumption is not going to be as easy as changing this
+	 * declaration.
+	 */
+	public static final int LONG_OBJECT_ID_LENGTH = 32;
+
+	/**
+	 * A Git LFS large object can be expressed as a 64 character string of
+	 * hexadecimal digits.
+	 *
+	 * @see #LONG_OBJECT_ID_LENGTH
+	 */
+	public static final int LONG_OBJECT_ID_STRING_LENGTH = LONG_OBJECT_ID_LENGTH
+			* 2;
+
+	/**
+	 * Create a new digest function for objects.
+	 *
+	 * @return a new digest object.
+	 * @throws RuntimeException
+	 *             this Java virtual machine does not support the required hash
+	 *             function. Very unlikely given that JGit uses a hash function
+	 *             that is in the Java reference specification.
+	 */
+	public static MessageDigest newMessageDigest() {
+		try {
+			return MessageDigest.getInstance(LONG_HASH_FUNCTION);
+		} catch (NoSuchAlgorithmException nsae) {
+			throw new RuntimeException(MessageFormat.format(
+					LfsText.get().requiredHashFunctionNotAvailable,
+					LONG_HASH_FUNCTION), nsae);
+		}
+	}
+
+	static {
+		if (LONG_OBJECT_ID_LENGTH != newMessageDigest().getDigestLength())
+			throw new LinkageError(
+					LfsText.get().incorrectLONG_OBJECT_ID_LENGTH);
+	}
+
+	/**
+	 * Content type used by LFS REST API as defined in
+	 * {@link "https://github.com/github/git-lfs/blob/master/docs/api/http-v1-batch.md"}
+	 */
+	public static String CONTENT_TYPE_GIT_LFS_JSON = "application/vnd.git-lfs+json";
+
+	/**
+	 * "arbitrary binary data" as defined in RFC 2046
+	 * {@link "https://www.ietf.org/rfc/rfc2046.txt"}
+	 */
+	public static String HDR_APPLICATION_OCTET_STREAM = "application/octet-stream";
+}
\ No newline at end of file
diff --git a/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/lib/LongObjectId.java b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/lib/LongObjectId.java
new file mode 100644
index 0000000..c4a4e43
--- /dev/null
+++ b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/lib/LongObjectId.java
@@ -0,0 +1,309 @@
+/*
+ * Copyright (C) 2015, Matthias Sohn <matthias.sohn@sap.com>
+ * 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.lfs.lib;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+
+import org.eclipse.jgit.lfs.errors.InvalidLongObjectIdException;
+import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.util.NB;
+import org.eclipse.jgit.util.RawParseUtils;
+
+/**
+ * A SHA-256 abstraction.
+ *
+ * Ported to SHA-256 from {@link ObjectId}
+ *
+ * @since 4.3
+ */
+public class LongObjectId extends AnyLongObjectId implements Serializable {
+	private static final long serialVersionUID = 1L;
+
+	private static final LongObjectId ZEROID;
+
+	private static final String ZEROID_STR;
+
+	static {
+		ZEROID = new LongObjectId(0L, 0L, 0L, 0L);
+		ZEROID_STR = ZEROID.name();
+	}
+
+	/**
+	 * Get the special all-zero LongObjectId.
+	 *
+	 * @return the all-zero LongObjectId, often used to stand-in for no object.
+	 */
+	public static final LongObjectId zeroId() {
+		return ZEROID;
+	}
+
+	/**
+	 * Test a string of characters to verify that it can be interpreted as
+	 * LongObjectId.
+	 * <p>
+	 * If true the string can be parsed with {@link #fromString(String)}.
+	 *
+	 * @param id
+	 *            the string to test.
+	 * @return true if the string can converted into an LongObjectId.
+	 */
+	public static final boolean isId(final String id) {
+		if (id.length() != Constants.LONG_OBJECT_ID_STRING_LENGTH)
+			return false;
+		try {
+			for (int i = 0; i < Constants.LONG_OBJECT_ID_STRING_LENGTH; i++) {
+				RawParseUtils.parseHexInt4((byte) id.charAt(i));
+			}
+			return true;
+		} catch (ArrayIndexOutOfBoundsException e) {
+			return false;
+		}
+	}
+
+	/**
+	 * Convert a LongObjectId into a hex string representation.
+	 *
+	 * @param i
+	 *            the id to convert. May be null.
+	 * @return the hex string conversion of this id's content.
+	 */
+	public static final String toString(final LongObjectId i) {
+		return i != null ? i.name() : ZEROID_STR;
+	}
+
+	/**
+	 * Compare two object identifier byte sequences for equality.
+	 *
+	 * @param firstBuffer
+	 *            the first buffer to compare against. Must have at least 32
+	 *            bytes from position fi through the end of the buffer.
+	 * @param fi
+	 *            first offset within firstBuffer to begin testing.
+	 * @param secondBuffer
+	 *            the second buffer to compare against. Must have at least 32
+	 *            bytes from position si through the end of the buffer.
+	 * @param si
+	 *            first offset within secondBuffer to begin testing.
+	 * @return true if the two identifiers are the same.
+	 */
+	public static boolean equals(final byte[] firstBuffer, final int fi,
+			final byte[] secondBuffer, final int si) {
+		return firstBuffer[fi] == secondBuffer[si]
+				&& firstBuffer[fi + 1] == secondBuffer[si + 1]
+				&& firstBuffer[fi + 2] == secondBuffer[si + 2]
+				&& firstBuffer[fi + 3] == secondBuffer[si + 3]
+				&& firstBuffer[fi + 4] == secondBuffer[si + 4]
+				&& firstBuffer[fi + 5] == secondBuffer[si + 5]
+				&& firstBuffer[fi + 6] == secondBuffer[si + 6]
+				&& firstBuffer[fi + 7] == secondBuffer[si + 7]
+				&& firstBuffer[fi + 8] == secondBuffer[si + 8]
+				&& firstBuffer[fi + 9] == secondBuffer[si + 9]
+				&& firstBuffer[fi + 10] == secondBuffer[si + 10]
+				&& firstBuffer[fi + 11] == secondBuffer[si + 11]
+				&& firstBuffer[fi + 12] == secondBuffer[si + 12]
+				&& firstBuffer[fi + 13] == secondBuffer[si + 13]
+				&& firstBuffer[fi + 14] == secondBuffer[si + 14]
+				&& firstBuffer[fi + 15] == secondBuffer[si + 15]
+				&& firstBuffer[fi + 16] == secondBuffer[si + 16]
+				&& firstBuffer[fi + 17] == secondBuffer[si + 17]
+				&& firstBuffer[fi + 18] == secondBuffer[si + 18]
+				&& firstBuffer[fi + 19] == secondBuffer[si + 19]
+				&& firstBuffer[fi + 20] == secondBuffer[si + 20]
+				&& firstBuffer[fi + 21] == secondBuffer[si + 21]
+				&& firstBuffer[fi + 22] == secondBuffer[si + 22]
+				&& firstBuffer[fi + 23] == secondBuffer[si + 23]
+				&& firstBuffer[fi + 24] == secondBuffer[si + 24]
+				&& firstBuffer[fi + 25] == secondBuffer[si + 25]
+				&& firstBuffer[fi + 26] == secondBuffer[si + 26]
+				&& firstBuffer[fi + 27] == secondBuffer[si + 27]
+				&& firstBuffer[fi + 28] == secondBuffer[si + 28]
+				&& firstBuffer[fi + 29] == secondBuffer[si + 29]
+				&& firstBuffer[fi + 30] == secondBuffer[si + 30]
+				&& firstBuffer[fi + 31] == secondBuffer[si + 31];
+	}
+
+	/**
+	 * Convert a LongObjectId from raw binary representation.
+	 *
+	 * @param bs
+	 *            the raw byte buffer to read from. At least 32 bytes must be
+	 *            available within this byte array.
+	 * @return the converted object id.
+	 */
+	public static final LongObjectId fromRaw(final byte[] bs) {
+		return fromRaw(bs, 0);
+	}
+
+	/**
+	 * Convert a LongObjectId from raw binary representation.
+	 *
+	 * @param bs
+	 *            the raw byte buffer to read from. At least 32 bytes after p
+	 *            must be available within this byte array.
+	 * @param p
+	 *            position to read the first byte of data from.
+	 * @return the converted object id.
+	 */
+	public static final LongObjectId fromRaw(final byte[] bs, final int p) {
+		final long a = NB.decodeInt64(bs, p);
+		final long b = NB.decodeInt64(bs, p + 8);
+		final long c = NB.decodeInt64(bs, p + 16);
+		final long d = NB.decodeInt64(bs, p + 24);
+		return new LongObjectId(a, b, c, d);
+	}
+
+	/**
+	 * Convert a LongObjectId from raw binary representation.
+	 *
+	 * @param is
+	 *            the raw long buffer to read from. At least 4 longs must be
+	 *            available within this long array.
+	 * @return the converted object id.
+	 */
+	public static final LongObjectId fromRaw(final long[] is) {
+		return fromRaw(is, 0);
+	}
+
+	/**
+	 * Convert a LongObjectId from raw binary representation.
+	 *
+	 * @param is
+	 *            the raw long buffer to read from. At least 4 longs after p
+	 *            must be available within this long array.
+	 * @param p
+	 *            position to read the first long of data from.
+	 * @return the converted object id.
+	 */
+	public static final LongObjectId fromRaw(final long[] is, final int p) {
+		return new LongObjectId(is[p], is[p + 1], is[p + 2], is[p + 3]);
+	}
+
+	/**
+	 * Convert a LongObjectId from hex characters (US-ASCII).
+	 *
+	 * @param buf
+	 *            the US-ASCII buffer to read from. At least 64 bytes after
+	 *            offset must be available within this byte array.
+	 * @param offset
+	 *            position to read the first character from.
+	 * @return the converted object id.
+	 */
+	public static final LongObjectId fromString(final byte[] buf, final int offset) {
+		return fromHexString(buf, offset);
+	}
+
+	/**
+	 * Convert a LongObjectId from hex characters.
+	 *
+	 * @param str
+	 *            the string to read from. Must be 64 characters long.
+	 * @return the converted object id.
+	 */
+	public static LongObjectId fromString(final String str) {
+		if (str.length() != Constants.LONG_OBJECT_ID_STRING_LENGTH)
+			throw new InvalidLongObjectIdException(str);
+		return fromHexString(org.eclipse.jgit.lib.Constants.encodeASCII(str),
+				0);
+	}
+
+	private static final LongObjectId fromHexString(final byte[] bs, int p) {
+		try {
+			final long a = RawParseUtils.parseHexInt64(bs, p);
+			final long b = RawParseUtils.parseHexInt64(bs, p + 16);
+			final long c = RawParseUtils.parseHexInt64(bs, p + 32);
+			final long d = RawParseUtils.parseHexInt64(bs, p + 48);
+			return new LongObjectId(a, b, c, d);
+		} catch (ArrayIndexOutOfBoundsException e1) {
+			throw new InvalidLongObjectIdException(bs, p,
+					Constants.LONG_OBJECT_ID_STRING_LENGTH);
+		}
+	}
+
+	LongObjectId(final long new_1, final long new_2, final long new_3,
+			final long new_4) {
+		w1 = new_1;
+		w2 = new_2;
+		w3 = new_3;
+		w4 = new_4;
+	}
+
+	/**
+	 * Initialize this instance by copying another existing LongObjectId.
+	 * <p>
+	 * This constructor is mostly useful for subclasses which want to extend a
+	 * LongObjectId with more properties, but initialize from an existing
+	 * LongObjectId instance acquired by other means.
+	 *
+	 * @param src
+	 *            another already parsed LongObjectId to copy the value out of.
+	 */
+	protected LongObjectId(final AnyLongObjectId src) {
+		w1 = src.w1;
+		w2 = src.w2;
+		w3 = src.w3;
+		w4 = src.w4;
+	}
+
+	@Override
+	public LongObjectId toObjectId() {
+		return this;
+	}
+
+	private void writeObject(ObjectOutputStream os) throws IOException {
+		os.writeLong(w1);
+		os.writeLong(w2);
+		os.writeLong(w3);
+		os.writeLong(w4);
+	}
+
+	private void readObject(ObjectInputStream ois) throws IOException {
+		w1 = ois.readLong();
+		w2 = ois.readLong();
+		w3 = ois.readLong();
+		w4 = ois.readLong();
+	}
+}
diff --git a/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/lib/MutableLongObjectId.java b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/lib/MutableLongObjectId.java
new file mode 100644
index 0000000..130e94e
--- /dev/null
+++ b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/lib/MutableLongObjectId.java
@@ -0,0 +1,256 @@
+/*
+ * Copyright (C) 2015, Matthias Sohn <matthias.sohn@sap.com>
+ * 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.lfs.lib;
+
+import java.text.MessageFormat;
+
+import org.eclipse.jgit.lfs.errors.InvalidLongObjectIdException;
+import org.eclipse.jgit.lfs.internal.LfsText;
+import org.eclipse.jgit.lib.MutableObjectId;
+import org.eclipse.jgit.util.NB;
+import org.eclipse.jgit.util.RawParseUtils;
+
+/**
+ * A mutable SHA-256 abstraction.
+ *
+ * Ported to SHA-256 from {@link MutableObjectId}
+ *
+ * @since 4.3
+ */
+public class MutableLongObjectId extends AnyLongObjectId {
+	/**
+	 * Empty constructor. Initialize object with default (zeros) value.
+	 */
+	public MutableLongObjectId() {
+		super();
+	}
+
+	/**
+	 * Copying constructor.
+	 *
+	 * @param src
+	 *            original entry, to copy id from
+	 */
+	MutableLongObjectId(MutableLongObjectId src) {
+		fromObjectId(src);
+	}
+
+	/**
+	 * Set any byte in the id.
+	 *
+	 * @param index
+	 *            index of the byte to set in the raw form of the ObjectId. Must
+	 *            be in range [0, {@link Constants#LONG_OBJECT_ID_LENGTH}).
+	 * @param value
+	 *            the value of the specified byte at {@code index}. Values are
+	 *            unsigned and thus are in the range [0,255] rather than the
+	 *            signed byte range of [-128, 127].
+	 * @throws ArrayIndexOutOfBoundsException
+	 *             {@code index} is less than 0, equal to
+	 *             {@link Constants#LONG_OBJECT_ID_LENGTH}, or greater than
+	 *             {@link Constants#LONG_OBJECT_ID_LENGTH}.
+	 */
+	public void setByte(int index, int value) {
+		switch (index >> 3) {
+		case 0:
+			w1 = set(w1, index & 7, value);
+			break;
+		case 1:
+			w2 = set(w2, index & 7, value);
+			break;
+		case 2:
+			w3 = set(w3, index & 7, value);
+			break;
+		case 3:
+			w4 = set(w4, index & 7, value);
+			break;
+		default:
+			throw new ArrayIndexOutOfBoundsException(index);
+		}
+	}
+
+	private static long set(long w, int index, long value) {
+		value &= 0xff;
+
+		switch (index) {
+		case 0:
+			return (w & 0x00ffffffffffffffL) | (value << 56);
+		case 1:
+			return (w & 0xff00ffffffffffffL) | (value << 48);
+		case 2:
+			return (w & 0xffff00ffffffffffL) | (value << 40);
+		case 3:
+			return (w & 0xffffff00ffffffffL) | (value << 32);
+		case 4:
+			return (w & 0xffffffff00ffffffL) | (value << 24);
+		case 5:
+			return (w & 0xffffffffff00ffffL) | (value << 16);
+		case 6:
+			return (w & 0xffffffffffff00ffL) | (value << 8);
+		case 7:
+			return (w & 0xffffffffffffff00L) | value;
+		default:
+			throw new ArrayIndexOutOfBoundsException();
+		}
+	}
+
+	/** Make this id match {@link LongObjectId#zeroId()}. */
+	public void clear() {
+		w1 = 0;
+		w2 = 0;
+		w3 = 0;
+		w4 = 0;
+	}
+
+	/**
+	 * Copy an LongObjectId into this mutable buffer.
+	 *
+	 * @param src
+	 *            the source id to copy from.
+	 */
+	public void fromObjectId(AnyLongObjectId src) {
+		this.w1 = src.w1;
+		this.w2 = src.w2;
+		this.w3 = src.w3;
+		this.w4 = src.w4;
+	}
+
+	/**
+	 * Convert an LongObjectId from raw binary representation.
+	 *
+	 * @param bs
+	 *            the raw byte buffer to read from. At least 32 bytes must be
+	 *            available within this byte array.
+	 */
+	public void fromRaw(final byte[] bs) {
+		fromRaw(bs, 0);
+	}
+
+	/**
+	 * Convert an LongObjectId from raw binary representation.
+	 *
+	 * @param bs
+	 *            the raw byte buffer to read from. At least 32 bytes after p
+	 *            must be available within this byte array.
+	 * @param p
+	 *            position to read the first byte of data from.
+	 */
+	public void fromRaw(final byte[] bs, final int p) {
+		w1 = NB.decodeInt64(bs, p);
+		w2 = NB.decodeInt64(bs, p + 8);
+		w3 = NB.decodeInt64(bs, p + 16);
+		w4 = NB.decodeInt64(bs, p + 24);
+	}
+
+	/**
+	 * Convert an LongObjectId from binary representation expressed in integers.
+	 *
+	 * @param longs
+	 *            the raw long buffer to read from. At least 4 longs must be
+	 *            available within this longs array.
+	 */
+	public void fromRaw(final long[] longs) {
+		fromRaw(longs, 0);
+	}
+
+	/**
+	 * Convert an LongObjectId from binary representation expressed in longs.
+	 *
+	 * @param longs
+	 *            the raw int buffer to read from. At least 4 longs after p must
+	 *            be available within this longs array.
+	 * @param p
+	 *            position to read the first integer of data from.
+	 *
+	 */
+	public void fromRaw(final long[] longs, final int p) {
+		w1 = longs[p];
+		w2 = longs[p + 1];
+		w3 = longs[p + 2];
+		w4 = longs[p + 3];
+	}
+
+	/**
+	 * Convert an LongObjectId from hex characters (US-ASCII).
+	 *
+	 * @param buf
+	 *            the US-ASCII buffer to read from. At least 32 bytes after
+	 *            offset must be available within this byte array.
+	 * @param offset
+	 *            position to read the first character from.
+	 */
+	public void fromString(final byte[] buf, final int offset) {
+		fromHexString(buf, offset);
+	}
+
+	/**
+	 * Convert an LongObjectId from hex characters.
+	 *
+	 * @param str
+	 *            the string to read from. Must be 64 characters long.
+	 */
+	public void fromString(final String str) {
+		if (str.length() != Constants.LONG_OBJECT_ID_STRING_LENGTH)
+			throw new IllegalArgumentException(
+					MessageFormat.format(LfsText.get().invalidLongId, str));
+		fromHexString(org.eclipse.jgit.lib.Constants.encodeASCII(str), 0);
+	}
+
+	private void fromHexString(final byte[] bs, int p) {
+		try {
+			w1 = RawParseUtils.parseHexInt64(bs, p);
+			w2 = RawParseUtils.parseHexInt64(bs, p + 16);
+			w3 = RawParseUtils.parseHexInt64(bs, p + 32);
+			w4 = RawParseUtils.parseHexInt64(bs, p + 48);
+		} catch (ArrayIndexOutOfBoundsException e1) {
+			throw new InvalidLongObjectIdException(bs, p,
+					Constants.LONG_OBJECT_ID_STRING_LENGTH);
+		}
+	}
+
+	@Override
+	public LongObjectId toObjectId() {
+		return new LongObjectId(this);
+	}
+}
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.lfs.feature/.gitignore b/org.eclipse.jgit.packaging/org.eclipse.jgit.lfs.feature/.gitignore
new file mode 100644
index 0000000..2f7896d
--- /dev/null
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.lfs.feature/.gitignore
@@ -0,0 +1 @@
+target/
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.lfs.feature/.project b/org.eclipse.jgit.packaging/org.eclipse.jgit.lfs.feature/.project
new file mode 100644
index 0000000..c2061b9
--- /dev/null
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.lfs.feature/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.jgit.lfs.feature</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.pde.FeatureBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.FeatureNature</nature>
+	</natures>
+</projectDescription>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.lfs.feature/.settings/org.eclipse.core.resources.prefs b/org.eclipse.jgit.packaging/org.eclipse.jgit.lfs.feature/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 0000000..14bdc2c
--- /dev/null
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.lfs.feature/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,3 @@
+#Fri Jun 18 23:33:45 CEST 2010
+eclipse.preferences.version=1
+encoding/<project>=UTF-8
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.lfs.feature/.settings/org.eclipse.core.runtime.prefs b/org.eclipse.jgit.packaging/org.eclipse.jgit.lfs.feature/.settings/org.eclipse.core.runtime.prefs
new file mode 100644
index 0000000..898252b
--- /dev/null
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.lfs.feature/.settings/org.eclipse.core.runtime.prefs
@@ -0,0 +1,3 @@
+#Fri Jun 18 23:33:45 CEST 2010
+eclipse.preferences.version=1
+line.separator=\n
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.lfs.feature/.settings/org.eclipse.mylyn.tasks.ui.prefs b/org.eclipse.jgit.packaging/org.eclipse.jgit.lfs.feature/.settings/org.eclipse.mylyn.tasks.ui.prefs
new file mode 100644
index 0000000..823c0f5
--- /dev/null
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.lfs.feature/.settings/org.eclipse.mylyn.tasks.ui.prefs
@@ -0,0 +1,4 @@
+#Tue Jul 19 20:11:28 CEST 2011
+eclipse.preferences.version=1
+project.repository.kind=bugzilla
+project.repository.url=https\://bugs.eclipse.org/bugs
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.lfs.feature/.settings/org.eclipse.mylyn.team.ui.prefs b/org.eclipse.jgit.packaging/org.eclipse.jgit.lfs.feature/.settings/org.eclipse.mylyn.team.ui.prefs
new file mode 100644
index 0000000..0cba949
--- /dev/null
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.lfs.feature/.settings/org.eclipse.mylyn.team.ui.prefs
@@ -0,0 +1,3 @@
+#Tue Jul 19 20:11:28 CEST 2011
+commit.comment.template=${task.description} \n\nBug\: ${task.key}
+eclipse.preferences.version=1
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.lfs.feature/build.properties b/org.eclipse.jgit.packaging/org.eclipse.jgit.lfs.feature/build.properties
new file mode 100644
index 0000000..b4a8dde
--- /dev/null
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.lfs.feature/build.properties
@@ -0,0 +1,4 @@
+bin.includes = feature.xml,\
+               edl-v10.html,\
+               feature.properties,\
+               license.html
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.lfs.feature/edl-v10.html b/org.eclipse.jgit.packaging/org.eclipse.jgit.lfs.feature/edl-v10.html
new file mode 100644
index 0000000..1826b47
--- /dev/null
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.lfs.feature/edl-v10.html
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
+<title>Eclipse Distribution License - Version 1.0</title>
+<style type="text/css">
+  body {
+    size: 8.5in 11.0in;
+    margin: 0.25in 0.5in 0.25in 0.5in;
+    tab-interval: 0.5in;
+    }
+  p {
+    margin-left: auto;
+    margin-top:  0.5em;
+    margin-bottom: 0.5em;
+    }
+  p.list {
+    margin-left: 0.5in;
+    margin-top:  0.05em;
+    margin-bottom: 0.05em;
+    }
+  </style>
+
+</head>
+
+<body lang="EN-US">
+
+<p><b>Eclipse Distribution License - v 1.0</b></p>
+
+<p>Copyright (c) 2007, Eclipse Foundation, Inc. and its licensors. </p>
+
+<p>All rights reserved.</p>
+<p>Redistribution and use in source and binary forms, with or without modification,
+    are permitted provided that the following conditions are met:
+<ul><li>Redistributions of source code must retain the above copyright notice,
+    this list of conditions and the following disclaimer.</li>
+<li>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.</li>
+<li>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.</li></ul>
+</p>
+<p>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.</p>
+
+</body>
+
+</html>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.lfs.feature/feature.properties b/org.eclipse.jgit.packaging/org.eclipse.jgit.lfs.feature/feature.properties
new file mode 100644
index 0000000..c5bffa8
--- /dev/null
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.lfs.feature/feature.properties
@@ -0,0 +1,159 @@
+###############################################################################
+# Copyright (c) 20015 Matthias Sohn <matthias.sohn@sap.com> and others.
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+###############################################################################
+
+featureName=Java implementation of Git - optional LFS support
+providerName=Eclipse JGit
+
+updateSiteName=Eclipse JGit Update Site
+
+# description property - text of the "Feature Description"
+description=\
+Optional LFS support.\n
+################ end of description property ##################################
+
+# "copyright" property - text of the "Feature Update Copyright"
+copyright=\
+Copyright (c) 2015, Matthias Sohn et.al.\n\
+All rights reserved. This program and the accompanying materials\n\
+are made available under the terms of the Eclipse Distribution License v1.0\n\
+which accompanies this distribution, and is available at\n\
+http://www.eclipse.org/org/documents/edl-v10.html\n
+################ end of copyright property ####################################
+
+# "licenseURL" property - URL of the "Feature License"
+# do not translate value - just change to point to a locale-specific HTML page
+licenseURL=license.html
+
+# "license" property - text of the "Feature Update License"
+# should be plain text version of license agreement pointed to be "licenseURL"
+license=\
+Eclipse Foundation Software User Agreement\n\
+April 9, 2014\n\
+\n\
+Usage Of Content\n\
+\n\
+THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION AND/OR\n\
+OTHER MATERIALS FOR OPEN SOURCE PROJECTS (COLLECTIVELY "CONTENT").\n\
+USE OF THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS\n\
+AGREEMENT AND/OR THE TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR\n\
+NOTICES INDICATED OR REFERENCED BELOW.  BY USING THE CONTENT, YOU\n\
+AGREE THAT YOUR USE OF THE CONTENT IS GOVERNED BY THIS AGREEMENT\n\
+AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS\n\
+OR NOTICES INDICATED OR REFERENCED BELOW.  IF YOU DO NOT AGREE TO THE\n\
+TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND CONDITIONS\n\
+OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED\n\
+BELOW, THEN YOU MAY NOT USE THE CONTENT.\n\
+\n\
+Applicable Licenses\n\
+\n\
+Unless otherwise indicated, all Content made available by the\n\
+Eclipse Foundation is provided to you under the terms and conditions of\n\
+the Eclipse Public License Version 1.0 ("EPL"). A copy of the EPL is\n\
+provided with this Content and is also available at http://www.eclipse.org/legal/epl-v10.html.\n\
+For purposes of the EPL, "Program" will mean the Content.\n\
+\n\
+Content includes, but is not limited to, source code, object code,\n\
+documentation and other files maintained in the Eclipse Foundation source code\n\
+repository ("Repository") in software modules ("Modules") and made available\n\
+as downloadable archives ("Downloads").\n\
+\n\
+       - Content may be structured and packaged into modules to facilitate delivering,\n\
+         extending, and upgrading the Content. Typical modules may include plug-ins ("Plug-ins"),\n\
+         plug-in fragments ("Fragments"), and features ("Features").\n\
+       - Each Plug-in or Fragment may be packaged as a sub-directory or JAR (Java(TM) ARchive)\n\
+         in a directory named "plugins".\n\
+       - A Feature is a bundle of one or more Plug-ins and/or Fragments and associated material.\n\
+         Each Feature may be packaged as a sub-directory in a directory named "features".\n\
+         Within a Feature, files named "feature.xml" may contain a list of the names and version\n\
+         numbers of the Plug-ins and/or Fragments associated with that Feature.\n\
+       - Features may also include other Features ("Included Features"). Within a Feature, files\n\
+         named "feature.xml" may contain a list of the names and version numbers of Included Features.\n\
+\n\
+The terms and conditions governing Plug-ins and Fragments should be\n\
+contained in files named "about.html" ("Abouts"). The terms and\n\
+conditions governing Features and Included Features should be contained\n\
+in files named "license.html" ("Feature Licenses"). Abouts and Feature\n\
+Licenses may be located in any directory of a Download or Module\n\
+including, but not limited to the following locations:\n\
+\n\
+       - The top-level (root) directory\n\
+       - Plug-in and Fragment directories\n\
+       - Inside Plug-ins and Fragments packaged as JARs\n\
+       - Sub-directories of the directory named "src" of certain Plug-ins\n\
+       - Feature directories\n\
+\n\
+Note: if a Feature made available by the Eclipse Foundation is installed using the\n\
+Provisioning Technology (as defined below), you must agree to a license ("Feature \n\
+Update License") during the installation process. If the Feature contains\n\
+Included Features, the Feature Update License should either provide you\n\
+with the terms and conditions governing the Included Features or inform\n\
+you where you can locate them. Feature Update Licenses may be found in\n\
+the "license" property of files named "feature.properties" found within a Feature.\n\
+Such Abouts, Feature Licenses, and Feature Update Licenses contain the\n\
+terms and conditions (or references to such terms and conditions) that\n\
+govern your use of the associated Content in that directory.\n\
+\n\
+THE ABOUTS, FEATURE LICENSES, AND FEATURE UPDATE LICENSES MAY REFER\n\
+TO THE EPL OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS.\n\
+SOME OF THESE OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):\n\
+\n\
+       - Eclipse Distribution License Version 1.0 (available at http://www.eclipse.org/licenses/edl-v1.0.html)\n\
+       - Common Public License Version 1.0 (available at http://www.eclipse.org/legal/cpl-v10.html)\n\
+       - Apache Software License 1.1 (available at http://www.apache.org/licenses/LICENSE)\n\
+       - Apache Software License 2.0 (available at http://www.apache.org/licenses/LICENSE-2.0)\n\
+       - Mozilla Public License Version 1.1 (available at http://www.mozilla.org/MPL/MPL-1.1.html)\n\
+\n\
+IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR\n\
+TO USE OF THE CONTENT. If no About, Feature License, or Feature Update License\n\
+is provided, please contact the Eclipse Foundation to determine what terms and conditions\n\
+govern that particular Content.\n\
+\n\
+\n\Use of Provisioning Technology\n\
+\n\
+The Eclipse Foundation makes available provisioning software, examples of which include,\n\
+but are not limited to, p2 and the Eclipse Update Manager ("Provisioning Technology") for\n\
+the purpose of allowing users to install software, documentation, information and/or\n\
+other materials (collectively "Installable Software"). This capability is provided with\n\
+the intent of allowing such users to install, extend and update Eclipse-based products.\n\
+Information about packaging Installable Software is available at\n\
+http://eclipse.org/equinox/p2/repository_packaging.html ("Specification").\n\
+\n\
+You may use Provisioning Technology to allow other parties to install Installable Software.\n\
+You shall be responsible for enabling the applicable license agreements relating to the\n\
+Installable Software to be presented to, and accepted by, the users of the Provisioning Technology\n\
+in accordance with the Specification. By using Provisioning Technology in such a manner and\n\
+making it available in accordance with the Specification, you further acknowledge your\n\
+agreement to, and the acquisition of all necessary rights to permit the following:\n\
+\n\
+       1. A series of actions may occur ("Provisioning Process") in which a user may execute\n\
+          the Provisioning Technology on a machine ("Target Machine") with the intent of installing,\n\
+          extending or updating the functionality of an Eclipse-based product.\n\
+       2. During the Provisioning Process, the Provisioning Technology may cause third party\n\
+          Installable Software or a portion thereof to be accessed and copied to the Target Machine.\n\
+       3. Pursuant to the Specification, you will provide to the user the terms and conditions that\n\
+          govern the use of the Installable Software ("Installable Software Agreement") and such\n\
+          Installable Software Agreement shall be accessed from the Target Machine in accordance\n\
+          with the Specification. Such Installable Software Agreement must inform the user of the\n\
+          terms and conditions that govern the Installable Software and must solicit acceptance by\n\
+          the end user in the manner prescribed in such Installable Software Agreement. Upon such\n\
+          indication of agreement by the user, the provisioning Technology will complete installation\n\
+          of the Installable Software.\n\
+\n\
+Cryptography\n\
+\n\
+Content may contain encryption software. The country in which you are\n\
+currently may have restrictions on the import, possession, and use,\n\
+and/or re-export to another country, of encryption software. BEFORE\n\
+using any encryption software, please check the country's laws,\n\
+regulations and policies concerning the import, possession, or use, and\n\
+re-export of encryption software, to see if this is permitted.\n\
+\n\
+Java and all Java-based trademarks are trademarks of Oracle Corporation in the United States, other countries, or both.\n
+########### end of license property ##########################################
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.lfs.feature/feature.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.lfs.feature/feature.xml
new file mode 100644
index 0000000..bb52857
--- /dev/null
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.lfs.feature/feature.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<feature
+      id="org.eclipse.jgit.lfs"
+      label="%featureName"
+      version="4.3.0.qualifier"
+      provider-name="%providerName">
+
+   <description url="http://www.eclipse.org/jgit/">
+      %description
+   </description>
+
+   <copyright>
+      %copyright
+   </copyright>
+
+   <license url="%licenseURL">
+      %license
+   </license>
+
+   <url>
+      <update label="%updateSiteName" url="http://download.eclipse.org/egit/updates"/>
+      <discovery label="%updateSiteName" url="http://download.eclipse.org/egit/updates"/>
+   </url>
+
+   <requires>
+      <import plugin="org.eclipse.jgit"/>
+   </requires>
+
+   <plugin
+         id="org.eclipse.jgit.lfs"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         unpack="false"/>
+
+   <plugin
+         id="org.eclipse.jgit.lfs.server"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         unpack="false"/>
+
+   <plugin
+         id="com.google.gson"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         unpack="false"/>
+
+</feature>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.lfs.feature/license.html b/org.eclipse.jgit.packaging/org.eclipse.jgit.lfs.feature/license.html
new file mode 100644
index 0000000..95ad95e
--- /dev/null
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.lfs.feature/license.html
@@ -0,0 +1,106 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<!-- saved from url=(0044)http://www.eclipse.org/legal/epl/notice.html -->
+<html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+
+<title>Eclipse Foundation Software User Agreement</title>
+</head>
+
+<body lang="EN-US">
+<h2>Eclipse Foundation Software User Agreement</h2>
+<p>April 9, 2014</p>
+
+<h3>Usage Of Content</h3>
+
+<p>THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION AND/OR OTHER MATERIALS FOR OPEN SOURCE PROJECTS
+   (COLLECTIVELY "CONTENT").  USE OF THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS AGREEMENT AND/OR THE TERMS AND
+   CONDITIONS OF LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW.  BY USING THE CONTENT, YOU AGREE THAT YOUR USE
+   OF THE CONTENT IS GOVERNED BY THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS OR
+   NOTICES INDICATED OR REFERENCED BELOW.  IF YOU DO NOT AGREE TO THE TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND
+   CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU MAY NOT USE THE CONTENT.</p>
+
+<h3>Applicable Licenses</h3>
+
+<p>Unless otherwise indicated, all Content made available by the Eclipse Foundation is provided to you under the terms and conditions of the Eclipse Public License Version 1.0
+   ("EPL").  A copy of the EPL is provided with this Content and is also available at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
+   For purposes of the EPL, "Program" will mean the Content.</p>
+
+<p>Content includes, but is not limited to, source code, object code, documentation and other files maintained in the Eclipse Foundation source code
+   repository ("Repository") in software modules ("Modules") and made available as downloadable archives ("Downloads").</p>
+
+<ul>
+       <li>Content may be structured and packaged into modules to facilitate delivering, extending, and upgrading the Content.  Typical modules may include plug-ins ("Plug-ins"), plug-in fragments ("Fragments"), and features ("Features").</li>
+       <li>Each Plug-in or Fragment may be packaged as a sub-directory or JAR (Java™ ARchive) in a directory named "plugins".</li>
+       <li>A Feature is a bundle of one or more Plug-ins and/or Fragments and associated material.  Each Feature may be packaged as a sub-directory in a directory named "features".  Within a Feature, files named "feature.xml" may contain a list of the names and version numbers of the Plug-ins
+      and/or Fragments associated with that Feature.</li>
+       <li>Features may also include other Features ("Included Features"). Within a Feature, files named "feature.xml" may contain a list of the names and version numbers of Included Features.</li>
+</ul>
+
+<p>The terms and conditions governing Plug-ins and Fragments should be contained in files named "about.html" ("Abouts"). The terms and conditions governing Features and
+Included Features should be contained in files named "license.html" ("Feature Licenses").  Abouts and Feature Licenses may be located in any directory of a Download or Module
+including, but not limited to the following locations:</p>
+
+<ul>
+       <li>The top-level (root) directory</li>
+       <li>Plug-in and Fragment directories</li>
+       <li>Inside Plug-ins and Fragments packaged as JARs</li>
+       <li>Sub-directories of the directory named "src" of certain Plug-ins</li>
+       <li>Feature directories</li>
+</ul>
+
+<p>Note: if a Feature made available by the Eclipse Foundation is installed using the Provisioning Technology (as defined below), you must agree to a license ("Feature Update License") during the
+installation process.  If the Feature contains Included Features, the Feature Update License should either provide you with the terms and conditions governing the Included Features or
+inform you where you can locate them.  Feature Update Licenses may be found in the "license" property of files named "feature.properties" found within a Feature.
+Such Abouts, Feature Licenses, and Feature Update Licenses contain the terms and conditions (or references to such terms and conditions) that govern your use of the associated Content in
+that directory.</p>
+
+<p>THE ABOUTS, FEATURE LICENSES, AND FEATURE UPDATE LICENSES MAY REFER TO THE EPL OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS.  SOME OF THESE
+OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):</p>
+
+<ul>
+       <li>Eclipse Distribution License Version 1.0 (available at <a href="http://www.eclipse.org/licenses/edl-v10.html">http://www.eclipse.org/licenses/edl-v1.0.html</a>)</li>
+       <li>Common Public License Version 1.0 (available at <a href="http://www.eclipse.org/legal/cpl-v10.html">http://www.eclipse.org/legal/cpl-v10.html</a>)</li>
+       <li>Apache Software License 1.1 (available at <a href="http://www.apache.org/licenses/LICENSE">http://www.apache.org/licenses/LICENSE</a>)</li>
+       <li>Apache Software License 2.0 (available at <a href="http://www.apache.org/licenses/LICENSE-2.0">http://www.apache.org/licenses/LICENSE-2.0</a>)</li>
+       <li>Mozilla Public License Version 1.1 (available at <a href="http://www.mozilla.org/MPL/MPL-1.1.html">http://www.mozilla.org/MPL/MPL-1.1.html</a>)</li>
+</ul>
+
+<p>IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR TO USE OF THE CONTENT.  If no About, Feature License, or Feature Update License is provided, please
+contact the Eclipse Foundation to determine what terms and conditions govern that particular Content.</p>
+
+
+<h3>Use of Provisioning Technology</h3>
+
+<p>The Eclipse Foundation makes available provisioning software, examples of which include, but are not limited to, p2 and the Eclipse
+   Update Manager ("Provisioning Technology") for the purpose of allowing users to install software, documentation, information and/or
+   other materials (collectively "Installable Software"). This capability is provided with the intent of allowing such users to
+   install, extend and update Eclipse-based products. Information about packaging Installable Software is available at <a href="http://eclipse.org/equinox/p2/repository_packaging.html">http://eclipse.org/equinox/p2/repository_packaging.html</a>
+   ("Specification").</p>
+
+<p>You may use Provisioning Technology to allow other parties to install Installable Software. You shall be responsible for enabling the
+   applicable license agreements relating to the Installable Software to be presented to, and accepted by, the users of the Provisioning Technology
+   in accordance with the Specification. By using Provisioning Technology in such a manner and making it available in accordance with the
+   Specification, you further acknowledge your agreement to, and the acquisition of all necessary rights to permit the following:</p>
+
+<ol>
+       <li>A series of actions may occur ("Provisioning Process") in which a user may execute the Provisioning Technology
+       on a machine ("Target Machine") with the intent of installing, extending or updating the functionality of an Eclipse-based
+       product.</li>
+       <li>During the Provisioning Process, the Provisioning Technology may cause third party Installable Software or a portion thereof to be
+       accessed and copied to the Target Machine.</li>
+       <li>Pursuant to the Specification, you will provide to the user the terms and conditions that govern the use of the Installable
+       Software ("Installable Software Agreement") and such Installable Software Agreement shall be accessed from the Target
+       Machine in accordance with the Specification. Such Installable Software Agreement must inform the user of the terms and conditions that govern
+       the Installable Software and must solicit acceptance by the end user in the manner prescribed in such Installable Software Agreement. Upon such
+       indication of agreement by the user, the provisioning Technology will complete installation of the Installable Software.</li>
+</ol>
+
+<h3>Cryptography</h3>
+
+<p>Content may contain encryption software. The country in which you are currently may have restrictions on the import, possession, and use, and/or re-export to
+   another country, of encryption software. BEFORE using any encryption software, please check the country's laws, regulations and policies concerning the import,
+   possession, or use, and re-export of encryption software, to see if this is permitted.</p>
+
+<p><small>Java and all Java-based trademarks are trademarks of Oracle Corporation in the United States, other countries, or both.</small></p>
+
+
+</body></html>
\ No newline at end of file
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.lfs.feature/pom.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.lfs.feature/pom.xml
new file mode 100644
index 0000000..9d35816
--- /dev/null
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.lfs.feature/pom.xml
@@ -0,0 +1,82 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+   Copyright (C) 2015, Matthias Sohn <matthias.sohn@sap.com>
+   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.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>org.eclipse.jgit</groupId>
+    <artifactId>jgit.tycho.parent</artifactId>
+    <version>4.3.0-SNAPSHOT</version>
+  </parent>
+
+  <groupId>org.eclipse.jgit.feature</groupId>
+  <artifactId>org.eclipse.jgit.lfs</artifactId>
+  <packaging>eclipse-feature</packaging>
+
+  <name>JGit - Optional LFS support</name>
+  <dependencies>
+
+    <dependency>
+      <groupId>org.eclipse.jgit</groupId>
+      <artifactId>org.eclipse.jgit</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+
+    <dependency>
+      <groupId>org.eclipse.jgit</groupId>
+      <artifactId>org.eclipse.jgit.lfs</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+
+    <dependency>
+      <groupId>org.eclipse.jgit</groupId>
+      <artifactId>org.eclipse.jgit.lfs.server</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+  </dependencies>
+
+</project>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.feature/feature.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.feature/feature.xml
index 03c9fed..ae30f08 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.feature/feature.xml
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.feature/feature.xml
@@ -26,8 +26,13 @@
          id="org.eclipse.jgit"
          version="0.0.0"/>
 
+   <includes
+         id="org.eclipse.jgit.lfs"
+         version="0.0.0"/>
+
    <requires>
       <import feature="org.eclipse.jgit" version="4.3.0" match="equivalent"/>
+      <import feature="org.eclipse.jgit.lfs" version="4.3.0" match="equivalent"/>
    </requires>
 
    <plugin
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.repository/category.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.repository/category.xml
index 2186ad9..c2bfc92 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.repository/category.xml
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.repository/category.xml
@@ -21,6 +21,12 @@
    <feature url="features/org.eclipse.jgit.http.apache_0.0.0.qualifier.jar" id="org.eclipse.jgit.http.apache" version="0.0.0" patch="true">
       <category name="JGit"/>
    </feature>
+   <feature url="features/org.eclipse.jgit.lfs_0.0.0.qualifier.jar" id="org.eclipse.jgit.lfs" version="0.0.0">
+      <category name="JGit"/>
+   </feature>
+   <feature url="features/org.eclipse.jgit.lfs_0.0.0.qualifier.jar" id="org.eclipse.jgit.lfs" version="0.0.0">
+      <category name="JGit"/>
+   </feature>
    <category-def name="JGit" label="JGit">
       <description>
          JGit
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.repository/pom.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.repository/pom.xml
index 6e5fd09..9d842ef 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.repository/pom.xml
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.repository/pom.xml
@@ -70,6 +70,16 @@
 	  <version>${project.version}</version>
 	</dependency>
     <dependency>
+	  <groupId>org.eclipse.jgit</groupId>
+	  <artifactId>org.eclipse.jgit.lfs</artifactId>
+	  <version>${project.version}</version>
+	</dependency>
+    <dependency>
+      <groupId>org.eclipse.jgit</groupId>
+      <artifactId>org.eclipse.jgit.lfs.server</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
       <groupId>org.eclipse.jgit</groupId>
       <artifactId>org.eclipse.jgit.pgm</artifactId>
       <version>${project.version}</version>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.3.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.3.target
index e8670e7..19edf51 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.3.target
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.3.target
@@ -45,6 +45,7 @@
       <unit id="org.objenesis.source" version="1.0.0.v201105211943"/>
       <unit id="org.mockito" version="1.8.4.v201303031500"/>
       <unit id="org.mockito.source" version="1.8.4.v201303031500"/>
+      <unit id="com.google.gson" version="2.2.4.v201311231704"/>
       <unit id="com.jcraft.jsch" version="0.1.51.v201410302000"/>
       <unit id="com.jcraft.jsch.source" version="0.1.51.v201410302000"/>
       <unit id="org.junit" version="4.11.0.v201303080030"/>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.4.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.4.target
index 0b85d75..3451b42 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.4.target
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.4.target
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <?pde?>
 <!-- generated with https://github.com/mbarbero/fr.obeo.releng.targetplatform -->
-<target name="jgit-4.4" sequenceNumber="1440024079">
+<target name="jgit-4.4" sequenceNumber="1444167820">
   <locations>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
       <unit id="org.eclipse.jetty.client" version="9.2.13.v20150730"/>
@@ -45,6 +45,7 @@
       <unit id="org.objenesis.source" version="1.0.0.v201105211943"/>
       <unit id="org.mockito" version="1.8.4.v201303031500"/>
       <unit id="org.mockito.source" version="1.8.4.v201303031500"/>
+      <unit id="com.google.gson" version="2.2.4.v201311231704"/>
       <unit id="com.jcraft.jsch" version="0.1.51.v201410302000"/>
       <unit id="com.jcraft.jsch.source" version="0.1.51.v201410302000"/>
       <unit id="org.junit" version="4.11.0.v201303080030"/>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.5.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.5.target
index 2067482..ce71222 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.5.target
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.5.target
@@ -45,6 +45,7 @@
       <unit id="org.objenesis.source" version="1.0.0.v201505121915"/>
       <unit id="org.mockito" version="1.8.4.v201303031500"/>
       <unit id="org.mockito.source" version="1.8.4.v201303031500"/>
+      <unit id="com.google.gson" version="2.2.4.v201311231704"/>
       <unit id="com.jcraft.jsch" version="0.1.53.v201508180515"/>
       <unit id="com.jcraft.jsch.source" version="0.1.53.v201508180515"/>
       <unit id="org.junit" version="4.11.0.v201303080030"/>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/R20150124073747-Luna-SR2.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/R20150124073747-Luna-SR2.tpd
index 38c9297..d9e072f 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/R20150124073747-Luna-SR2.tpd
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/R20150124073747-Luna-SR2.tpd
@@ -24,6 +24,7 @@
 	org.objenesis.source [1.0.0.v201105211943,1.0.0.v201105211943]
 	org.mockito [1.8.4.v201303031500,1.8.4.v201303031500]
 	org.mockito.source [1.8.4.v201303031500,1.8.4.v201303031500]
+	com.google.gson [2.2.4.v201311231704,2.2.4.v201311231704]
 	com.jcraft.jsch [0.1.51.v201410302000,0.1.51.v201410302000]
 	com.jcraft.jsch.source [0.1.51.v201410302000,0.1.51.v201410302000]
 	org.junit [4.11.0.v201303080030,4.11.0.v201303080030]
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/R20150821153341-Mars.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/R20150821153341-Mars.tpd
index cb63807..5cacd71 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/R20150821153341-Mars.tpd
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/R20150821153341-Mars.tpd
@@ -24,6 +24,7 @@
 	org.objenesis.source [1.0.0.v201505121915,1.0.0.v201505121915]
 	org.mockito [1.8.4.v201303031500,1.8.4.v201303031500]
 	org.mockito.source [1.8.4.v201303031500,1.8.4.v201303031500]
+	com.google.gson [2.2.4.v201311231704,2.2.4.v201311231704]
 	com.jcraft.jsch [0.1.53.v201508180515,0.1.53.v201508180515]
 	com.jcraft.jsch.source [0.1.53.v201508180515,0.1.53.v201508180515]
 	org.junit [4.11.0.v201303080030,4.11.0.v201303080030]
diff --git a/org.eclipse.jgit.packaging/pom.xml b/org.eclipse.jgit.packaging/pom.xml
index 7f44df8..68efc46 100644
--- a/org.eclipse.jgit.packaging/pom.xml
+++ b/org.eclipse.jgit.packaging/pom.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!--
-   Copyright (C) 2009, 2013, Matthias Sohn <matthias.sohn@sap.com>
+   Copyright (C) 2009, 2015, Matthias Sohn <matthias.sohn@sap.com>
    and other copyright owners as documented in the project's IP log.
 
    This program and the accompanying materials are made available
@@ -78,6 +78,7 @@
     <module>org.eclipse.jgit.target</module>
     <module>org.eclipse.jgit.feature</module>
     <module>org.eclipse.jgit.http.apache.feature</module>
+    <module>org.eclipse.jgit.lfs.feature</module>
     <module>org.eclipse.jgit.pgm.feature</module>
     <module>org.eclipse.jgit.source.feature</module>
     <module>org.eclipse.jgit.pgm.source.feature</module>
diff --git a/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/ReflogTest.java b/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/ReflogTest.java
index ce80832..7330ee9 100644
--- a/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/ReflogTest.java
+++ b/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/ReflogTest.java
@@ -57,24 +57,27 @@ public void testClean() throws Exception {
 
 	@Test
 	public void testSingleCommit() throws Exception {
-		new Git(db).commit().setMessage("initial commit").call();
+		try (Git git = new Git(db)) {
+			git.commit().setMessage("initial commit").call();
 
-		assertEquals("6fd41be HEAD@{0}: commit (initial): initial commit",
-				execute("git reflog")[0]);
+			assertEquals("6fd41be HEAD@{0}: commit (initial): initial commit",
+					execute("git reflog")[0]);
+		}
 	}
 
 	@Test
 	public void testBranch() throws Exception {
-		Git git = new Git(db);
-		git.commit().setMessage("first commit").call();
-		git.checkout().setCreateBranch(true).setName("side").call();
-		writeTrashFile("file", "side content");
-		git.add().addFilepattern("file").call();
-		git.commit().setMessage("side commit").call();
+		try (Git git = new Git(db)) {
+			git.commit().setMessage("first commit").call();
+			git.checkout().setCreateBranch(true).setName("side").call();
+			writeTrashFile("file", "side content");
+			git.add().addFilepattern("file").call();
+			git.commit().setMessage("side commit").call();
 
-		assertArrayEquals(new String[] {
-				"38890c7 side@{0}: commit: side commit",
-				"d216986 side@{1}: branch: Created from commit first commit",
-				"" }, execute("git reflog refs/heads/side"));
+			assertArrayEquals(new String[] {
+					"38890c7 side@{0}: commit: side commit",
+					"d216986 side@{1}: branch: Created from commit first commit",
+					"" }, execute("git reflog refs/heads/side"));
+		}
 	}
 }
\ No newline at end of file
diff --git a/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/RepoTest.java b/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/RepoTest.java
index 0eee771..ba62383 100644
--- a/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/RepoTest.java
+++ b/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/RepoTest.java
@@ -74,28 +74,32 @@ public void setUp() throws Exception {
 		super.setUp();
 
 		defaultDb = createWorkRepository();
-		Git git = new Git(defaultDb);
-		JGitTestUtil.writeTrashFile(defaultDb, "hello.txt", "world");
-		git.add().addFilepattern("hello.txt").call();
-		git.commit().setMessage("Initial commit").call();
+		try (Git git = new Git(defaultDb)) {
+			JGitTestUtil.writeTrashFile(defaultDb, "hello.txt", "world");
+			git.add().addFilepattern("hello.txt").call();
+			git.commit().setMessage("Initial commit").call();
+		}
 
 		notDefaultDb = createWorkRepository();
-		git = new Git(notDefaultDb);
-		JGitTestUtil.writeTrashFile(notDefaultDb, "world.txt", "hello");
-		git.add().addFilepattern("world.txt").call();
-		git.commit().setMessage("Initial commit").call();
+		try (Git git = new Git(notDefaultDb)) {
+			JGitTestUtil.writeTrashFile(notDefaultDb, "world.txt", "hello");
+			git.add().addFilepattern("world.txt").call();
+			git.commit().setMessage("Initial commit").call();
+		}
 
 		groupADb = createWorkRepository();
-		git = new Git(groupADb);
-		JGitTestUtil.writeTrashFile(groupADb, "a.txt", "world");
-		git.add().addFilepattern("a.txt").call();
-		git.commit().setMessage("Initial commit").call();
+		try (Git git = new Git(groupADb)) {
+			JGitTestUtil.writeTrashFile(groupADb, "a.txt", "world");
+			git.add().addFilepattern("a.txt").call();
+			git.commit().setMessage("Initial commit").call();
+		}
 
 		groupBDb = createWorkRepository();
-		git = new Git(groupBDb);
-		JGitTestUtil.writeTrashFile(groupBDb, "b.txt", "world");
-		git.add().addFilepattern("b.txt").call();
-		git.commit().setMessage("Initial commit").call();
+		try (Git git = new Git(groupBDb)) {
+			JGitTestUtil.writeTrashFile(groupBDb, "b.txt", "world");
+			git.add().addFilepattern("b.txt").call();
+			git.commit().setMessage("Initial commit").call();
+		}
 
 		resolveRelativeUris();
 	}
diff --git a/org.eclipse.jgit.pgm/BUCK b/org.eclipse.jgit.pgm/BUCK
index edcf2fc..47711b5 100644
--- a/org.eclipse.jgit.pgm/BUCK
+++ b/org.eclipse.jgit.pgm/BUCK
@@ -9,8 +9,18 @@
     '//org.eclipse.jgit:jgit',
     '//org.eclipse.jgit.archive:jgit-archive',
     '//org.eclipse.jgit.http.apache:http-apache',
+    '//org.eclipse.jgit.lfs.server:jgit-lfs-server',
     '//org.eclipse.jgit.ui:ui',
     '//lib:args4j',
+    '//lib:httpcomponents',
+    '//lib:httpcore',
+    '//lib/jetty:http',
+    '//lib/jetty:io',
+    '//lib/jetty:server',
+    '//lib/jetty:servlet',
+    '//lib/jetty:security',
+    '//lib/jetty:util',
+    '//lib:servlet-api'
   ],
   visibility = ['PUBLIC'],
 )
diff --git a/org.eclipse.jgit.pgm/META-INF/MANIFEST.MF b/org.eclipse.jgit.pgm/META-INF/MANIFEST.MF
index bf1fc5d..b654fc9 100644
--- a/org.eclipse.jgit.pgm/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.pgm/META-INF/MANIFEST.MF
@@ -7,9 +7,25 @@
 Bundle-ActivationPolicy: lazy
 Bundle-Localization: plugin
 Bundle-RequiredExecutionEnvironment: JavaSE-1.7
-Import-Package: org.apache.commons.compress.archivers;version="[1.3,2.0)",
+Import-Package: javax.servlet;version="[3.1.0,4.0.0)",
+ javax.servlet.http;version="[3.1.0,4.0.0)",
+ org.apache.commons.compress.archivers;version="[1.3,2.0)",
  org.apache.commons.compress.archivers.tar;version="[1.3,2.0)",
  org.apache.commons.compress.archivers.zip;version="[1.3,2.0)",
+ org.eclipse.jetty.continuation;version="[9.0.0,10.0.0)",
+ org.eclipse.jetty.http;version="[9.0.0,10.0.0)",
+ org.eclipse.jetty.io;version="[9.0.0,10.0.0)",
+ org.eclipse.jetty.security;version="[9.0.0,10.0.0)",
+ org.eclipse.jetty.security.authentication;version="[9.0.0,10.0.0)",
+ org.eclipse.jetty.server;version="[9.0.0,10.0.0)",
+ org.eclipse.jetty.server.handler;version="[9.0.0,10.0.0)",
+ org.eclipse.jetty.server.nio;version="[9.0.0,10.0.0)",
+ org.eclipse.jetty.servlet;version="[9.0.0,10.0.0)",
+ org.eclipse.jetty.util;version="[9.0.0,10.0.0)",
+ org.eclipse.jetty.util.component;version="[9.0.0,10.0.0)",
+ org.eclipse.jetty.util.log;version="[9.0.0,10.0.0)",
+ org.eclipse.jetty.util.security;version="[9.0.0,10.0.0)",
+ org.eclipse.jetty.util.thread;version="[9.0.0,10.0.0)",
  org.eclipse.jgit.api;version="[4.3.0,4.4.0)",
  org.eclipse.jgit.api.errors;version="[4.3.0,4.4.0)",
  org.eclipse.jgit.archive;version="[4.3.0,4.4.0)",
@@ -23,8 +39,11 @@
  org.eclipse.jgit.internal.storage.file;version="[4.3.0,4.4.0)",
  org.eclipse.jgit.internal.storage.pack;version="[4.3.0,4.4.0)",
  org.eclipse.jgit.internal.storage.reftree;version="[4.3.0,4.4.0)",
+ org.eclipse.jgit.lfs.lib;version="[4.3.0,4.4.0)",
+ org.eclipse.jgit.lfs.server;version="[4.3.0,4.4.0)",
+ org.eclipse.jgit.lfs.server.fs;version="[4.3.0,4.4.0)",
  org.eclipse.jgit.lib;version="[4.3.0,4.4.0)",
- org.eclipse.jgit.merge;version="4.3.0",
+ org.eclipse.jgit.merge;version="[4.3.0,4.4.0)",
  org.eclipse.jgit.nls;version="[4.3.0,4.4.0)",
  org.eclipse.jgit.notes;version="[4.3.0,4.4.0)",
  org.eclipse.jgit.revplot;version="[4.3.0,4.4.0)",
diff --git a/org.eclipse.jgit.pgm/META-INF/services/org.eclipse.jgit.pgm.TextBuiltin b/org.eclipse.jgit.pgm/META-INF/services/org.eclipse.jgit.pgm.TextBuiltin
index 6aa2004..c159f7d 100644
--- a/org.eclipse.jgit.pgm/META-INF/services/org.eclipse.jgit.pgm.TextBuiltin
+++ b/org.eclipse.jgit.pgm/META-INF/services/org.eclipse.jgit.pgm.TextBuiltin
@@ -38,6 +38,7 @@
 org.eclipse.jgit.pgm.Version
 
 org.eclipse.jgit.pgm.debug.DiffAlgorithms
+org.eclipse.jgit.pgm.debug.LfsStore
 org.eclipse.jgit.pgm.debug.MakeCacheTree
 org.eclipse.jgit.pgm.debug.ReadDirCache
 org.eclipse.jgit.pgm.debug.RebuildCommitGraph
diff --git a/org.eclipse.jgit.pgm/pom.xml b/org.eclipse.jgit.pgm/pom.xml
index 0531e44..8d0bcf9 100644
--- a/org.eclipse.jgit.pgm/pom.xml
+++ b/org.eclipse.jgit.pgm/pom.xml
@@ -122,6 +122,34 @@
       <artifactId>log4j</artifactId>
       <version>${log4j-version}</version>
     </dependency>
+
+    <dependency>
+      <groupId>org.eclipse.jetty</groupId>
+      <artifactId>jetty-servlet</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>org.eclipse.jgit</groupId>
+      <artifactId>org.eclipse.jgit.junit.http</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+
+    <dependency>
+      <groupId>org.eclipse.jgit</groupId>
+      <artifactId>org.eclipse.jgit.lfs</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+
+    <dependency>
+      <groupId>org.eclipse.jgit</groupId>
+      <artifactId>org.eclipse.jgit.lfs.server</artifactId>
+      <version>${project.version}</version>
+    </dependency>
   </dependencies>
 
   <build>
diff --git a/org.eclipse.jgit.pgm/resources/org/eclipse/jgit/pgm/internal/CLIText.properties b/org.eclipse.jgit.pgm/resources/org/eclipse/jgit/pgm/internal/CLIText.properties
index b4b1261..544e234 100644
--- a/org.eclipse.jgit.pgm/resources/org/eclipse/jgit/pgm/internal/CLIText.properties
+++ b/org.eclipse.jgit.pgm/resources/org/eclipse/jgit/pgm/internal/CLIText.properties
@@ -125,6 +125,7 @@
 metaVar_revision=REVISION
 metaVar_seconds=SECONDS
 metaVar_service=SERVICE
+metaVar_lfsStorage=STORAGE
 metaVar_treeish=tree-ish
 metaVar_uriish=uri-ish
 metaVar_url=URL
@@ -218,6 +219,10 @@
 usage_Gc=Cleanup unnecessary files and optimize the local repository
 usage_Glog=View commit history as a graph
 usage_IndexPack=Build pack index file for an existing packed archive
+usage_LFSDirectory=Directory to store large objects
+usage_LFSPort=Server http port
+usage_LFSRunStore=fs: store lfs objects in file system
+usage_LFSStoreUrl=URL of the LFS store
 usage_LongFormat=Always output the long format
 usage_LsRemote=List references in a remote repository
 usage_lsRemoteHeads=Show only refs starting with refs/heads
@@ -347,6 +352,7 @@
 usage_resetHard=Resets the index and working tree
 usage_resetSoft=Resets without touching the index file nor the working tree
 usage_resetMixed=Resets the index but not the working tree
+usage_runLfsStore=Run LFS Store in a given directory
 usage_setTheGitRepositoryToOperateOn=set the git repository to operate on
 usage_show=display one commit
 usage_showRefNamesMatchingCommits=Show ref names matching commits
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Branch.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Branch.java
index 045f357..bf6ee3a 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Branch.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Branch.java
@@ -310,24 +310,24 @@ private void delete(List<String> branches, boolean force)
 			throws IOException {
 		String current = db.getBranch();
 		ObjectId head = db.resolve(Constants.HEAD);
-		for (String branch : branches) {
-			if (branch.equals(current)) {
-				throw die(MessageFormat.format(CLIText.get().cannotDeleteTheBranchWhichYouAreCurrentlyOn, branch));
+		for (String b : branches) {
+			if (b.equals(current)) {
+				throw die(MessageFormat.format(CLIText.get().cannotDeleteTheBranchWhichYouAreCurrentlyOn, b));
 			}
 			RefUpdate update = db.updateRef((remote ? Constants.R_REMOTES
 					: Constants.R_HEADS)
-					+ branch);
+					+ b);
 			update.setNewObjectId(head);
 			update.setForceUpdate(force || remote);
 			Result result = update.delete();
 			if (result == Result.REJECTED) {
-				throw die(MessageFormat.format(CLIText.get().branchIsNotAnAncestorOfYourCurrentHEAD, branch));
+				throw die(MessageFormat.format(CLIText.get().branchIsNotAnAncestorOfYourCurrentHEAD, b));
 			} else if (result == Result.NEW)
-				throw die(MessageFormat.format(CLIText.get().branchNotFound, branch));
+				throw die(MessageFormat.format(CLIText.get().branchNotFound, b));
 			if (remote)
-				outw.println(MessageFormat.format(CLIText.get().deletedRemoteBranch, branch));
+				outw.println(MessageFormat.format(CLIText.get().deletedRemoteBranch, b));
 			else if (verbose)
-				outw.println(MessageFormat.format(CLIText.get().deletedBranch, branch));
+				outw.println(MessageFormat.format(CLIText.get().deletedBranch, b));
 		}
 	}
 }
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/LfsStore.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/LfsStore.java
new file mode 100644
index 0000000..18398f6
--- /dev/null
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/LfsStore.java
@@ -0,0 +1,249 @@
+/*
+ * Copyright (C) 2015, Sasa Zivkov <sasa.zivkov@sap.com>
+ * 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.pgm.debug;
+
+import java.net.InetAddress;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.UnknownHostException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+import org.eclipse.jetty.server.Connector;
+import org.eclipse.jetty.server.HttpConfiguration;
+import org.eclipse.jetty.server.HttpConnectionFactory;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.server.ServerConnector;
+import org.eclipse.jetty.server.handler.ContextHandlerCollection;
+import org.eclipse.jetty.servlet.ServletContextHandler;
+import org.eclipse.jetty.servlet.ServletHolder;
+import org.eclipse.jgit.lfs.server.LargeFileRepository;
+import org.eclipse.jgit.lfs.server.LfsProtocolServlet;
+import org.eclipse.jgit.lfs.server.fs.FileLfsServlet;
+import org.eclipse.jgit.lfs.server.fs.FileLfsRepository;
+import org.eclipse.jgit.pgm.Command;
+import org.eclipse.jgit.pgm.TextBuiltin;
+import org.kohsuke.args4j.Argument;
+import org.kohsuke.args4j.Option;
+
+@Command(common = true, usage = "usage_runLfsStore")
+class LfsStore extends TextBuiltin {
+
+	/**
+	 * Tiny web application server for testing
+	 */
+	class AppServer {
+
+		private final Server server;
+
+		private final ServerConnector connector;
+
+		private final ContextHandlerCollection contexts;
+
+		private URI uri;
+
+		AppServer(int port) {
+			server = new Server();
+
+			HttpConfiguration http_config = new HttpConfiguration();
+			http_config.setOutputBufferSize(32768);
+
+			connector = new ServerConnector(server,
+					new HttpConnectionFactory(http_config));
+			connector.setPort(port);
+			try {
+				String host = InetAddress.getByName("localhost") //$NON-NLS-1$
+						.getHostAddress();
+				connector.setHost(host);
+				if (host.contains(":") && !host.startsWith("[")) //$NON-NLS-1$ //$NON-NLS-2$
+					host = "[" + host + "]"; //$NON-NLS-1$//$NON-NLS-2$
+				uri = new URI("http://" + host + ":" + port); //$NON-NLS-1$ //$NON-NLS-2$
+			} catch (UnknownHostException e) {
+				throw new RuntimeException("Cannot find localhost", e); //$NON-NLS-1$
+			} catch (URISyntaxException e) {
+				throw new RuntimeException("Unexpected URI error on " + uri, e); //$NON-NLS-1$
+			}
+
+			contexts = new ContextHandlerCollection();
+			server.setHandler(contexts);
+			server.setConnectors(new Connector[] { connector });
+		}
+
+		/**
+		 * Create a new servlet context within the server.
+		 * <p>
+		 * This method should be invoked before the server is started, once for
+		 * each context the caller wants to register.
+		 *
+		 * @param path
+		 *            path of the context; use "/" for the root context if
+		 *            binding to the root is desired.
+		 * @return the context to add servlets into.
+		 */
+		ServletContextHandler addContext(String path) {
+			assertNotRunning();
+			if ("".equals(path)) //$NON-NLS-1$
+				path = "/"; //$NON-NLS-1$
+
+			ServletContextHandler ctx = new ServletContextHandler();
+			ctx.setContextPath(path);
+			contexts.addHandler(ctx);
+
+			return ctx;
+		}
+
+		void start() throws Exception {
+			server.start();
+		}
+
+		void stop() throws Exception {
+			server.stop();
+		}
+
+		URI getURI() {
+			return uri;
+		}
+
+		private void assertNotRunning() {
+			if (server.isRunning()) {
+				throw new IllegalStateException("server is running"); //$NON-NLS-1$
+			}
+		}
+	}
+
+	private static enum StoreType {
+		FS;
+	}
+
+	private static final String OBJECTS = "objects/"; //$NON-NLS-1$
+
+	private static final String STORE_PATH = "/" + OBJECTS + "*"; //$NON-NLS-1$//$NON-NLS-2$
+
+	private static final String PROTOCOL_PATH = "/lfs/objects/batch"; //$NON-NLS-1$
+
+	@Option(name = "--port", aliases = {"-p" }, metaVar = "metaVar_port",
+			usage = "usage_LFSPort")
+	int port;
+
+	@Option(name = "--store", metaVar = "metaVar_lfsStorage", usage = "usage_LFSRunStore")
+	StoreType storeType;
+
+	@Option(name = "--store-url", aliases = {"-u" }, metaVar = "metaVar_url",
+			usage = "usage_LFSStoreUrl")
+	String storeUrl;
+
+	@Argument(required = false, metaVar = "metaVar_directory", usage = "usage_LFSDirectory")
+	String directory;
+
+	String protocolUrl;
+
+	String accessKey;
+
+	String secretKey;
+
+	@Override
+	protected boolean requiresRepository() {
+		return false;
+	}
+
+	protected void run() throws Exception {
+		AppServer server = new AppServer(port);
+		URI baseURI = server.getURI();
+		ServletContextHandler app = server.addContext("/"); //$NON-NLS-1$
+
+		final LargeFileRepository repository;
+		switch (storeType) {
+		case FS:
+			Path dir = Paths.get(directory);
+			FileLfsRepository fsRepo = new FileLfsRepository(
+					getStoreUrl(baseURI), dir);
+			FileLfsServlet content = new FileLfsServlet(fsRepo, 30000);
+			app.addServlet(new ServletHolder(content), STORE_PATH);
+			repository = fsRepo;
+			break;
+
+		default:
+			throw new IllegalArgumentException(
+					"Unknown store type: " + storeType); //$NON-NLS-1$
+		}
+
+		LfsProtocolServlet protocol = new LfsProtocolServlet() {
+
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			protected LargeFileRepository getLargeFileRepository() {
+				return repository;
+			}
+
+		};
+		app.addServlet(new ServletHolder(protocol), PROTOCOL_PATH);
+
+		server.start();
+
+		outw.println("LFS protocol URL: " + getProtocolUrl(baseURI)); //$NON-NLS-1$
+		if (storeType == StoreType.FS) {
+			outw.println("LFS objects located in: " + directory); //$NON-NLS-1$
+			outw.println("LFS store URL: " + getStoreUrl(baseURI)); //$NON-NLS-1$
+		}
+	}
+
+	private String getStoreUrl(URI baseURI) {
+		if (storeUrl == null) {
+			if (storeType == StoreType.FS) {
+				storeUrl = baseURI + "/" + OBJECTS; //$NON-NLS-1$
+			} else {
+				die("Local store not running and no --store-url specified"); //$NON-NLS-1$
+			}
+		}
+		return storeUrl;
+	}
+
+	private String getProtocolUrl(URI baseURI) {
+		if (protocolUrl == null) {
+			protocolUrl = baseURI + PROTOCOL_PATH;
+		}
+		return protocolUrl;
+	}
+}
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/TextHashFunctions.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/TextHashFunctions.java
index 062f4e7..28d92ae 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/TextHashFunctions.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/TextHashFunctions.java
@@ -286,25 +286,25 @@ protected void run() throws Exception {
 			else
 				rb.findGitDir(dir);
 
-			Repository db = rb.build();
+			Repository repo = rb.build();
 			try {
-				run(db);
+				run(repo);
 			} finally {
-				db.close();
+				repo.close();
 			}
 		}
 	}
 
-	private void run(Repository db) throws Exception {
+	private void run(Repository repo) throws Exception {
 		List<Function> all = init();
 
 		long fileCnt = 0;
 		long lineCnt = 0;
-		try (ObjectReader or = db.newObjectReader();
+		try (ObjectReader or = repo.newObjectReader();
 			RevWalk rw = new RevWalk(or);
 			TreeWalk tw = new TreeWalk(or)) {
 			final MutableObjectId id = new MutableObjectId();
-			tw.reset(rw.parseTree(db.resolve(Constants.HEAD)));
+			tw.reset(rw.parseTree(repo.resolve(Constants.HEAD)));
 			tw.setRecursive(true);
 
 			while (tw.next()) {
@@ -341,7 +341,7 @@ private void run(Repository db) throws Exception {
 			}
 		}
 
-		File directory = db.getDirectory();
+		File directory = repo.getDirectory();
 		if (directory != null) {
 			String name = directory.getName();
 			File parent = directory.getParentFile();
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/ApplyCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/ApplyCommandTest.java
index ad3ff60..d842046 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/ApplyCommandTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/ApplyCommandTest.java
@@ -69,23 +69,24 @@ private ApplyResult init(final String name) throws Exception {
 
 	private ApplyResult init(final String name, final boolean preExists,
 			final boolean postExists) throws Exception {
-		Git git = new Git(db);
+		try (Git git = new Git(db)) {
+			if (preExists) {
+				a = new RawText(readFile(name + "_PreImage"));
+				write(new File(db.getDirectory().getParent(), name),
+						a.getString(0, a.size(), false));
 
-		if (preExists) {
-			a = new RawText(readFile(name + "_PreImage"));
-			write(new File(db.getDirectory().getParent(), name),
-					a.getString(0, a.size(), false));
+				git.add().addFilepattern(name).call();
+				git.commit().setMessage("PreImage").call();
+			}
 
-			git.add().addFilepattern(name).call();
-			git.commit().setMessage("PreImage").call();
+			if (postExists) {
+				b = new RawText(readFile(name + "_PostImage"));
+			}
+
+			return git
+					.apply()
+					.setPatch(getTestResource(name + ".patch")).call();
 		}
-
-		if (postExists)
-			b = new RawText(readFile(name + "_PostImage"));
-
-		return git
-				.apply()
-				.setPatch(getTestResource(name + ".patch")).call();
 	}
 
 	@Test
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CommitCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CommitCommandTest.java
index b39a68a..9d87f0c 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CommitCommandTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CommitCommandTest.java
@@ -186,297 +186,302 @@ public boolean isCaseSensitive() {
 
 	@Test
 	public void commitNewSubmodule() throws Exception {
-		Git git = new Git(db);
-		writeTrashFile("file.txt", "content");
-		git.add().addFilepattern("file.txt").call();
-		RevCommit commit = git.commit().setMessage("create file").call();
+		try (Git git = new Git(db)) {
+			writeTrashFile("file.txt", "content");
+			git.add().addFilepattern("file.txt").call();
+			RevCommit commit = git.commit().setMessage("create file").call();
 
-		SubmoduleAddCommand command = new SubmoduleAddCommand(db);
-		String path = "sub";
-		command.setPath(path);
-		String uri = db.getDirectory().toURI().toString();
-		command.setURI(uri);
-		Repository repo = command.call();
-		assertNotNull(repo);
-		addRepoToClose(repo);
+			SubmoduleAddCommand command = new SubmoduleAddCommand(db);
+			String path = "sub";
+			command.setPath(path);
+			String uri = db.getDirectory().toURI().toString();
+			command.setURI(uri);
+			Repository repo = command.call();
+			assertNotNull(repo);
+			addRepoToClose(repo);
 
-		SubmoduleWalk generator = SubmoduleWalk.forIndex(db);
-		assertTrue(generator.next());
-		assertEquals(path, generator.getPath());
-		assertEquals(commit, generator.getObjectId());
-		assertEquals(uri, generator.getModulesUrl());
-		assertEquals(path, generator.getModulesPath());
-		assertEquals(uri, generator.getConfigUrl());
-		Repository subModRepo = generator.getRepository();
-		assertNotNull(subModRepo);
-		subModRepo.close();
-		assertEquals(commit, repo.resolve(Constants.HEAD));
+			SubmoduleWalk generator = SubmoduleWalk.forIndex(db);
+			assertTrue(generator.next());
+			assertEquals(path, generator.getPath());
+			assertEquals(commit, generator.getObjectId());
+			assertEquals(uri, generator.getModulesUrl());
+			assertEquals(path, generator.getModulesPath());
+			assertEquals(uri, generator.getConfigUrl());
+			Repository subModRepo = generator.getRepository();
+			assertNotNull(subModRepo);
+			subModRepo.close();
+			assertEquals(commit, repo.resolve(Constants.HEAD));
 
-		RevCommit submoduleCommit = git.commit().setMessage("submodule add")
-				.setOnly(path).call();
-		assertNotNull(submoduleCommit);
-		TreeWalk walk = new TreeWalk(db);
-		walk.addTree(commit.getTree());
-		walk.addTree(submoduleCommit.getTree());
-		walk.setFilter(TreeFilter.ANY_DIFF);
-		List<DiffEntry> diffs = DiffEntry.scan(walk);
-		assertEquals(1, diffs.size());
-		DiffEntry subDiff = diffs.get(0);
-		assertEquals(FileMode.MISSING, subDiff.getOldMode());
-		assertEquals(FileMode.GITLINK, subDiff.getNewMode());
-		assertEquals(ObjectId.zeroId(), subDiff.getOldId().toObjectId());
-		assertEquals(commit, subDiff.getNewId().toObjectId());
-		assertEquals(path, subDiff.getNewPath());
+			RevCommit submoduleCommit = git.commit().setMessage("submodule add")
+					.setOnly(path).call();
+			assertNotNull(submoduleCommit);
+			try (TreeWalk walk = new TreeWalk(db)) {
+				walk.addTree(commit.getTree());
+				walk.addTree(submoduleCommit.getTree());
+				walk.setFilter(TreeFilter.ANY_DIFF);
+				List<DiffEntry> diffs = DiffEntry.scan(walk);
+				assertEquals(1, diffs.size());
+				DiffEntry subDiff = diffs.get(0);
+				assertEquals(FileMode.MISSING, subDiff.getOldMode());
+				assertEquals(FileMode.GITLINK, subDiff.getNewMode());
+				assertEquals(ObjectId.zeroId(), subDiff.getOldId().toObjectId());
+				assertEquals(commit, subDiff.getNewId().toObjectId());
+				assertEquals(path, subDiff.getNewPath());
+			}
+		}
 	}
 
 	@Test
 	public void commitSubmoduleUpdate() throws Exception {
-		Git git = new Git(db);
-		writeTrashFile("file.txt", "content");
-		git.add().addFilepattern("file.txt").call();
-		RevCommit commit = git.commit().setMessage("create file").call();
-		writeTrashFile("file.txt", "content2");
-		git.add().addFilepattern("file.txt").call();
-		RevCommit commit2 = git.commit().setMessage("edit file").call();
+		try (Git git = new Git(db)) {
+			writeTrashFile("file.txt", "content");
+			git.add().addFilepattern("file.txt").call();
+			RevCommit commit = git.commit().setMessage("create file").call();
+			writeTrashFile("file.txt", "content2");
+			git.add().addFilepattern("file.txt").call();
+			RevCommit commit2 = git.commit().setMessage("edit file").call();
 
-		SubmoduleAddCommand command = new SubmoduleAddCommand(db);
-		String path = "sub";
-		command.setPath(path);
-		String uri = db.getDirectory().toURI().toString();
-		command.setURI(uri);
-		Repository repo = command.call();
-		assertNotNull(repo);
-		addRepoToClose(repo);
+			SubmoduleAddCommand command = new SubmoduleAddCommand(db);
+			String path = "sub";
+			command.setPath(path);
+			String uri = db.getDirectory().toURI().toString();
+			command.setURI(uri);
+			Repository repo = command.call();
+			assertNotNull(repo);
+			addRepoToClose(repo);
 
-		SubmoduleWalk generator = SubmoduleWalk.forIndex(db);
-		assertTrue(generator.next());
-		assertEquals(path, generator.getPath());
-		assertEquals(commit2, generator.getObjectId());
-		assertEquals(uri, generator.getModulesUrl());
-		assertEquals(path, generator.getModulesPath());
-		assertEquals(uri, generator.getConfigUrl());
-		Repository subModRepo = generator.getRepository();
-		assertNotNull(subModRepo);
-		subModRepo.close();
-		assertEquals(commit2, repo.resolve(Constants.HEAD));
+			SubmoduleWalk generator = SubmoduleWalk.forIndex(db);
+			assertTrue(generator.next());
+			assertEquals(path, generator.getPath());
+			assertEquals(commit2, generator.getObjectId());
+			assertEquals(uri, generator.getModulesUrl());
+			assertEquals(path, generator.getModulesPath());
+			assertEquals(uri, generator.getConfigUrl());
+			Repository subModRepo = generator.getRepository();
+			assertNotNull(subModRepo);
+			subModRepo.close();
+			assertEquals(commit2, repo.resolve(Constants.HEAD));
 
-		RevCommit submoduleAddCommit = git.commit().setMessage("submodule add")
-				.setOnly(path).call();
-		assertNotNull(submoduleAddCommit);
+			RevCommit submoduleAddCommit = git.commit().setMessage("submodule add")
+					.setOnly(path).call();
+			assertNotNull(submoduleAddCommit);
 
-		RefUpdate update = repo.updateRef(Constants.HEAD);
-		update.setNewObjectId(commit);
-		assertEquals(Result.FORCED, update.forceUpdate());
+			RefUpdate update = repo.updateRef(Constants.HEAD);
+			update.setNewObjectId(commit);
+			assertEquals(Result.FORCED, update.forceUpdate());
 
-		RevCommit submoduleEditCommit = git.commit()
-				.setMessage("submodule add").setOnly(path).call();
-		assertNotNull(submoduleEditCommit);
-		TreeWalk walk = new TreeWalk(db);
-		walk.addTree(submoduleAddCommit.getTree());
-		walk.addTree(submoduleEditCommit.getTree());
-		walk.setFilter(TreeFilter.ANY_DIFF);
-		List<DiffEntry> diffs = DiffEntry.scan(walk);
-		assertEquals(1, diffs.size());
-		DiffEntry subDiff = diffs.get(0);
-		assertEquals(FileMode.GITLINK, subDiff.getOldMode());
-		assertEquals(FileMode.GITLINK, subDiff.getNewMode());
-		assertEquals(commit2, subDiff.getOldId().toObjectId());
-		assertEquals(commit, subDiff.getNewId().toObjectId());
-		assertEquals(path, subDiff.getNewPath());
-		assertEquals(path, subDiff.getOldPath());
+			RevCommit submoduleEditCommit = git.commit()
+					.setMessage("submodule add").setOnly(path).call();
+			assertNotNull(submoduleEditCommit);
+			try (TreeWalk walk = new TreeWalk(db)) {
+				walk.addTree(submoduleAddCommit.getTree());
+				walk.addTree(submoduleEditCommit.getTree());
+				walk.setFilter(TreeFilter.ANY_DIFF);
+				List<DiffEntry> diffs = DiffEntry.scan(walk);
+				assertEquals(1, diffs.size());
+				DiffEntry subDiff = diffs.get(0);
+				assertEquals(FileMode.GITLINK, subDiff.getOldMode());
+				assertEquals(FileMode.GITLINK, subDiff.getNewMode());
+				assertEquals(commit2, subDiff.getOldId().toObjectId());
+				assertEquals(commit, subDiff.getNewId().toObjectId());
+				assertEquals(path, subDiff.getNewPath());
+				assertEquals(path, subDiff.getOldPath());
+			}
+		}
 	}
 
 	@Test
 	public void commitUpdatesSmudgedEntries() throws Exception {
-		Git git = new Git(db);
+		try (Git git = new Git(db)) {
+			File file1 = writeTrashFile("file1.txt", "content1");
+			assertTrue(file1.setLastModified(file1.lastModified() - 5000));
+			File file2 = writeTrashFile("file2.txt", "content2");
+			assertTrue(file2.setLastModified(file2.lastModified() - 5000));
+			File file3 = writeTrashFile("file3.txt", "content3");
+			assertTrue(file3.setLastModified(file3.lastModified() - 5000));
 
-		File file1 = writeTrashFile("file1.txt", "content1");
-		assertTrue(file1.setLastModified(file1.lastModified() - 5000));
-		File file2 = writeTrashFile("file2.txt", "content2");
-		assertTrue(file2.setLastModified(file2.lastModified() - 5000));
-		File file3 = writeTrashFile("file3.txt", "content3");
-		assertTrue(file3.setLastModified(file3.lastModified() - 5000));
+			assertNotNull(git.add().addFilepattern("file1.txt")
+					.addFilepattern("file2.txt").addFilepattern("file3.txt").call());
+			RevCommit commit = git.commit().setMessage("add files").call();
+			assertNotNull(commit);
 
-		assertNotNull(git.add().addFilepattern("file1.txt")
-				.addFilepattern("file2.txt").addFilepattern("file3.txt").call());
-		RevCommit commit = git.commit().setMessage("add files").call();
-		assertNotNull(commit);
+			DirCache cache = DirCache.read(db.getIndexFile(), db.getFS());
+			int file1Size = cache.getEntry("file1.txt").getLength();
+			int file2Size = cache.getEntry("file2.txt").getLength();
+			int file3Size = cache.getEntry("file3.txt").getLength();
+			ObjectId file2Id = cache.getEntry("file2.txt").getObjectId();
+			ObjectId file3Id = cache.getEntry("file3.txt").getObjectId();
+			assertTrue(file1Size > 0);
+			assertTrue(file2Size > 0);
+			assertTrue(file3Size > 0);
 
-		DirCache cache = DirCache.read(db.getIndexFile(), db.getFS());
-		int file1Size = cache.getEntry("file1.txt").getLength();
-		int file2Size = cache.getEntry("file2.txt").getLength();
-		int file3Size = cache.getEntry("file3.txt").getLength();
-		ObjectId file2Id = cache.getEntry("file2.txt").getObjectId();
-		ObjectId file3Id = cache.getEntry("file3.txt").getObjectId();
-		assertTrue(file1Size > 0);
-		assertTrue(file2Size > 0);
-		assertTrue(file3Size > 0);
+			// Smudge entries
+			cache = DirCache.lock(db.getIndexFile(), db.getFS());
+			cache.getEntry("file1.txt").setLength(0);
+			cache.getEntry("file2.txt").setLength(0);
+			cache.getEntry("file3.txt").setLength(0);
+			cache.write();
+			assertTrue(cache.commit());
 
-		// Smudge entries
-		cache = DirCache.lock(db.getIndexFile(), db.getFS());
-		cache.getEntry("file1.txt").setLength(0);
-		cache.getEntry("file2.txt").setLength(0);
-		cache.getEntry("file3.txt").setLength(0);
-		cache.write();
-		assertTrue(cache.commit());
+			// Verify entries smudged
+			cache = DirCache.read(db.getIndexFile(), db.getFS());
+			assertEquals(0, cache.getEntry("file1.txt").getLength());
+			assertEquals(0, cache.getEntry("file2.txt").getLength());
+			assertEquals(0, cache.getEntry("file3.txt").getLength());
 
-		// Verify entries smudged
-		cache = DirCache.read(db.getIndexFile(), db.getFS());
-		assertEquals(0, cache.getEntry("file1.txt").getLength());
-		assertEquals(0, cache.getEntry("file2.txt").getLength());
-		assertEquals(0, cache.getEntry("file3.txt").getLength());
+			long indexTime = db.getIndexFile().lastModified();
+			db.getIndexFile().setLastModified(indexTime - 5000);
 
-		long indexTime = db.getIndexFile().lastModified();
-		db.getIndexFile().setLastModified(indexTime - 5000);
+			write(file1, "content4");
+			assertTrue(file1.setLastModified(file1.lastModified() + 2500));
+			assertNotNull(git.commit().setMessage("edit file").setOnly("file1.txt")
+					.call());
 
-		write(file1, "content4");
-		assertTrue(file1.setLastModified(file1.lastModified() + 2500));
-		assertNotNull(git.commit().setMessage("edit file").setOnly("file1.txt")
-				.call());
-
-		cache = db.readDirCache();
-		assertEquals(file1Size, cache.getEntry("file1.txt").getLength());
-		assertEquals(file2Size, cache.getEntry("file2.txt").getLength());
-		assertEquals(file3Size, cache.getEntry("file3.txt").getLength());
-		assertEquals(file2Id, cache.getEntry("file2.txt").getObjectId());
-		assertEquals(file3Id, cache.getEntry("file3.txt").getObjectId());
+			cache = db.readDirCache();
+			assertEquals(file1Size, cache.getEntry("file1.txt").getLength());
+			assertEquals(file2Size, cache.getEntry("file2.txt").getLength());
+			assertEquals(file3Size, cache.getEntry("file3.txt").getLength());
+			assertEquals(file2Id, cache.getEntry("file2.txt").getObjectId());
+			assertEquals(file3Id, cache.getEntry("file3.txt").getObjectId());
+		}
 	}
 
 	@Test
 	public void commitIgnoresSmudgedEntryWithDifferentId() throws Exception {
-		Git git = new Git(db);
+		try (Git git = new Git(db)) {
+			File file1 = writeTrashFile("file1.txt", "content1");
+			assertTrue(file1.setLastModified(file1.lastModified() - 5000));
+			File file2 = writeTrashFile("file2.txt", "content2");
+			assertTrue(file2.setLastModified(file2.lastModified() - 5000));
 
-		File file1 = writeTrashFile("file1.txt", "content1");
-		assertTrue(file1.setLastModified(file1.lastModified() - 5000));
-		File file2 = writeTrashFile("file2.txt", "content2");
-		assertTrue(file2.setLastModified(file2.lastModified() - 5000));
+			assertNotNull(git.add().addFilepattern("file1.txt")
+					.addFilepattern("file2.txt").call());
+			RevCommit commit = git.commit().setMessage("add files").call();
+			assertNotNull(commit);
 
-		assertNotNull(git.add().addFilepattern("file1.txt")
-				.addFilepattern("file2.txt").call());
-		RevCommit commit = git.commit().setMessage("add files").call();
-		assertNotNull(commit);
+			DirCache cache = DirCache.read(db.getIndexFile(), db.getFS());
+			int file1Size = cache.getEntry("file1.txt").getLength();
+			int file2Size = cache.getEntry("file2.txt").getLength();
+			assertTrue(file1Size > 0);
+			assertTrue(file2Size > 0);
 
-		DirCache cache = DirCache.read(db.getIndexFile(), db.getFS());
-		int file1Size = cache.getEntry("file1.txt").getLength();
-		int file2Size = cache.getEntry("file2.txt").getLength();
-		assertTrue(file1Size > 0);
-		assertTrue(file2Size > 0);
+			writeTrashFile("file2.txt", "content3");
+			assertNotNull(git.add().addFilepattern("file2.txt").call());
+			writeTrashFile("file2.txt", "content4");
 
-		writeTrashFile("file2.txt", "content3");
-		assertNotNull(git.add().addFilepattern("file2.txt").call());
-		writeTrashFile("file2.txt", "content4");
+			// Smudge entries
+			cache = DirCache.lock(db.getIndexFile(), db.getFS());
+			cache.getEntry("file1.txt").setLength(0);
+			cache.getEntry("file2.txt").setLength(0);
+			cache.write();
+			assertTrue(cache.commit());
 
-		// Smudge entries
-		cache = DirCache.lock(db.getIndexFile(), db.getFS());
-		cache.getEntry("file1.txt").setLength(0);
-		cache.getEntry("file2.txt").setLength(0);
-		cache.write();
-		assertTrue(cache.commit());
+			// Verify entries smudged
+			cache = db.readDirCache();
+			assertEquals(0, cache.getEntry("file1.txt").getLength());
+			assertEquals(0, cache.getEntry("file2.txt").getLength());
 
-		// Verify entries smudged
-		cache = db.readDirCache();
-		assertEquals(0, cache.getEntry("file1.txt").getLength());
-		assertEquals(0, cache.getEntry("file2.txt").getLength());
+			long indexTime = db.getIndexFile().lastModified();
+			db.getIndexFile().setLastModified(indexTime - 5000);
 
-		long indexTime = db.getIndexFile().lastModified();
-		db.getIndexFile().setLastModified(indexTime - 5000);
+			write(file1, "content5");
+			assertTrue(file1.setLastModified(file1.lastModified() + 1000));
 
-		write(file1, "content5");
-		assertTrue(file1.setLastModified(file1.lastModified() + 1000));
+			assertNotNull(git.commit().setMessage("edit file").setOnly("file1.txt")
+					.call());
 
-		assertNotNull(git.commit().setMessage("edit file").setOnly("file1.txt")
-				.call());
-
-		cache = db.readDirCache();
-		assertEquals(file1Size, cache.getEntry("file1.txt").getLength());
-		assertEquals(0, cache.getEntry("file2.txt").getLength());
+			cache = db.readDirCache();
+			assertEquals(file1Size, cache.getEntry("file1.txt").getLength());
+			assertEquals(0, cache.getEntry("file2.txt").getLength());
+		}
 	}
 
 	@Test
 	public void commitAfterSquashMerge() throws Exception {
-		Git git = new Git(db);
+		try (Git git = new Git(db)) {
+			writeTrashFile("file1", "file1");
+			git.add().addFilepattern("file1").call();
+			RevCommit first = git.commit().setMessage("initial commit").call();
 
-		writeTrashFile("file1", "file1");
-		git.add().addFilepattern("file1").call();
-		RevCommit first = git.commit().setMessage("initial commit").call();
+			assertTrue(new File(db.getWorkTree(), "file1").exists());
+			createBranch(first, "refs/heads/branch1");
+			checkoutBranch("refs/heads/branch1");
 
-		assertTrue(new File(db.getWorkTree(), "file1").exists());
-		createBranch(first, "refs/heads/branch1");
-		checkoutBranch("refs/heads/branch1");
+			writeTrashFile("file2", "file2");
+			git.add().addFilepattern("file2").call();
+			git.commit().setMessage("second commit").call();
+			assertTrue(new File(db.getWorkTree(), "file2").exists());
 
-		writeTrashFile("file2", "file2");
-		git.add().addFilepattern("file2").call();
-		git.commit().setMessage("second commit").call();
-		assertTrue(new File(db.getWorkTree(), "file2").exists());
+			checkoutBranch("refs/heads/master");
 
-		checkoutBranch("refs/heads/master");
+			MergeResult result = git.merge()
+					.include(db.exactRef("refs/heads/branch1"))
+					.setSquash(true)
+					.call();
 
-		MergeResult result = git.merge()
-				.include(db.exactRef("refs/heads/branch1"))
-				.setSquash(true)
-				.call();
+			assertTrue(new File(db.getWorkTree(), "file1").exists());
+			assertTrue(new File(db.getWorkTree(), "file2").exists());
+			assertEquals(MergeResult.MergeStatus.FAST_FORWARD_SQUASHED,
+					result.getMergeStatus());
 
-		assertTrue(new File(db.getWorkTree(), "file1").exists());
-		assertTrue(new File(db.getWorkTree(), "file2").exists());
-		assertEquals(MergeResult.MergeStatus.FAST_FORWARD_SQUASHED,
-				result.getMergeStatus());
+			// comment not set, should be inferred from SQUASH_MSG
+			RevCommit squashedCommit = git.commit().call();
 
-		// comment not set, should be inferred from SQUASH_MSG
-		RevCommit squashedCommit = git.commit().call();
-
-		assertEquals(1, squashedCommit.getParentCount());
-		assertNull(db.readSquashCommitMsg());
-		assertEquals("commit: Squashed commit of the following:", db
-				.getReflogReader(Constants.HEAD).getLastEntry().getComment());
-		assertEquals("commit: Squashed commit of the following:", db
-				.getReflogReader(db.getBranch()).getLastEntry().getComment());
+			assertEquals(1, squashedCommit.getParentCount());
+			assertNull(db.readSquashCommitMsg());
+			assertEquals("commit: Squashed commit of the following:", db
+					.getReflogReader(Constants.HEAD).getLastEntry().getComment());
+			assertEquals("commit: Squashed commit of the following:", db
+					.getReflogReader(db.getBranch()).getLastEntry().getComment());
+		}
 	}
 
 	@Test(expected = WrongRepositoryStateException.class)
 	public void commitAmendOnInitialShouldFail() throws Exception {
-		Git git = new Git(db);
-		git.commit().setAmend(true).setMessage("initial commit").call();
+		try (Git git = new Git(db)) {
+			git.commit().setAmend(true).setMessage("initial commit").call();
+		}
 	}
 
 	@Test
 	public void commitAmendWithoutAuthorShouldSetOriginalAuthorAndAuthorTime()
 			throws Exception {
-		Git git = new Git(db);
+		try (Git git = new Git(db)) {
+			writeTrashFile("file1", "file1");
+			git.add().addFilepattern("file1").call();
 
-		writeTrashFile("file1", "file1");
-		git.add().addFilepattern("file1").call();
+			final String authorName = "First Author";
+			final String authorEmail = "author@example.org";
+			final Date authorDate = new Date(1349621117000L);
+			PersonIdent firstAuthor = new PersonIdent(authorName, authorEmail,
+					authorDate, TimeZone.getTimeZone("UTC"));
+			git.commit().setMessage("initial commit").setAuthor(firstAuthor).call();
 
-		final String authorName = "First Author";
-		final String authorEmail = "author@example.org";
-		final Date authorDate = new Date(1349621117000L);
-		PersonIdent firstAuthor = new PersonIdent(authorName, authorEmail,
-				authorDate, TimeZone.getTimeZone("UTC"));
-		git.commit().setMessage("initial commit").setAuthor(firstAuthor).call();
+			RevCommit amended = git.commit().setAmend(true)
+					.setMessage("amend commit").call();
 
-		RevCommit amended = git.commit().setAmend(true)
-				.setMessage("amend commit").call();
-
-		PersonIdent amendedAuthor = amended.getAuthorIdent();
-		assertEquals(authorName, amendedAuthor.getName());
-		assertEquals(authorEmail, amendedAuthor.getEmailAddress());
-		assertEquals(authorDate.getTime(), amendedAuthor.getWhen().getTime());
+			PersonIdent amendedAuthor = amended.getAuthorIdent();
+			assertEquals(authorName, amendedAuthor.getName());
+			assertEquals(authorEmail, amendedAuthor.getEmailAddress());
+			assertEquals(authorDate.getTime(), amendedAuthor.getWhen().getTime());
+		}
 	}
 
 	@Test
 	public void commitAmendWithAuthorShouldUseIt() throws Exception {
-		Git git = new Git(db);
+		try (Git git = new Git(db)) {
+			writeTrashFile("file1", "file1");
+			git.add().addFilepattern("file1").call();
+			git.commit().setMessage("initial commit").call();
 
-		writeTrashFile("file1", "file1");
-		git.add().addFilepattern("file1").call();
-		git.commit().setMessage("initial commit").call();
+			RevCommit amended = git.commit().setAmend(true)
+					.setAuthor("New Author", "newauthor@example.org")
+					.setMessage("amend commit").call();
 
-		RevCommit amended = git.commit().setAmend(true)
-				.setAuthor("New Author", "newauthor@example.org")
-				.setMessage("amend commit").call();
-
-		PersonIdent amendedAuthor = amended.getAuthorIdent();
-		assertEquals("New Author", amendedAuthor.getName());
-		assertEquals("newauthor@example.org", amendedAuthor.getEmailAddress());
+			PersonIdent amendedAuthor = amended.getAuthorIdent();
+			assertEquals("New Author", amendedAuthor.getName());
+			assertEquals("newauthor@example.org", amendedAuthor.getEmailAddress());
+		}
 	}
 
 	@Test
@@ -532,18 +537,19 @@ public void commitOnlyShouldCommitUnmergedPathAndNotAffectOthers()
 				+ "[unmerged2, mode:100644, stage:3]",
 				indexState(0));
 
-		Git git = new Git(db);
-		RevCommit commit = git.commit().setOnly("unmerged1")
-				.setMessage("Only one file").call();
+		try (Git git = new Git(db)) {
+			RevCommit commit = git.commit().setOnly("unmerged1")
+					.setMessage("Only one file").call();
 
-		assertEquals("[other, mode:100644]" + "[unmerged1, mode:100644]"
-				+ "[unmerged2, mode:100644, stage:1]"
-				+ "[unmerged2, mode:100644, stage:2]"
-				+ "[unmerged2, mode:100644, stage:3]",
-				indexState(0));
+			assertEquals("[other, mode:100644]" + "[unmerged1, mode:100644]"
+					+ "[unmerged2, mode:100644, stage:1]"
+					+ "[unmerged2, mode:100644, stage:2]"
+					+ "[unmerged2, mode:100644, stage:3]",
+					indexState(0));
 
-		try (TreeWalk walk = TreeWalk.forPath(db, "unmerged1", commit.getTree())) {
-			assertEquals(FileMode.REGULAR_FILE, walk.getFileMode(0));
+			try (TreeWalk walk = TreeWalk.forPath(db, "unmerged1", commit.getTree())) {
+				assertEquals(FileMode.REGULAR_FILE, walk.getFileMode(0));
+			}
 		}
 	}
 
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/DiffCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/DiffCommandTest.java
index 4ad01cf..4f5b50d 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/DiffCommandTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/DiffCommandTest.java
@@ -70,32 +70,33 @@ public void testDiffModified() throws Exception {
 		File folder = new File(db.getWorkTree(), "folder");
 		folder.mkdir();
 		write(new File(folder, "folder.txt"), "folder");
-		Git git = new Git(db);
-		git.add().addFilepattern(".").call();
-		git.commit().setMessage("Initial commit").call();
-		write(new File(folder, "folder.txt"), "folder change");
+		try (Git git = new Git(db)) {
+			git.add().addFilepattern(".").call();
+			git.commit().setMessage("Initial commit").call();
+			write(new File(folder, "folder.txt"), "folder change");
 
-		OutputStream out = new ByteArrayOutputStream();
-		List<DiffEntry> entries = git.diff().setOutputStream(out).call();
-		assertEquals(1, entries.size());
-		assertEquals(ChangeType.MODIFY, entries.get(0)
-				.getChangeType());
-		assertEquals("folder/folder.txt", entries.get(0)
-				.getOldPath());
-		assertEquals("folder/folder.txt", entries.get(0)
-				.getNewPath());
+			OutputStream out = new ByteArrayOutputStream();
+			List<DiffEntry> entries = git.diff().setOutputStream(out).call();
+			assertEquals(1, entries.size());
+			assertEquals(ChangeType.MODIFY, entries.get(0)
+					.getChangeType());
+			assertEquals("folder/folder.txt", entries.get(0)
+					.getOldPath());
+			assertEquals("folder/folder.txt", entries.get(0)
+					.getNewPath());
 
-		String actual = out.toString();
-		String expected = "diff --git a/folder/folder.txt b/folder/folder.txt\n"
-				+ "index 0119635..95c4c65 100644\n"
-				+ "--- a/folder/folder.txt\n"
-				+ "+++ b/folder/folder.txt\n"
-				+ "@@ -1 +1 @@\n"
-				+ "-folder\n"
-				+ "\\ No newline at end of file\n"
-				+ "+folder change\n"
-				+ "\\ No newline at end of file\n";
-		assertEquals(expected.toString(), actual);
+			String actual = out.toString();
+			String expected = "diff --git a/folder/folder.txt b/folder/folder.txt\n"
+					+ "index 0119635..95c4c65 100644\n"
+					+ "--- a/folder/folder.txt\n"
+					+ "+++ b/folder/folder.txt\n"
+					+ "@@ -1 +1 @@\n"
+					+ "-folder\n"
+					+ "\\ No newline at end of file\n"
+					+ "+folder change\n"
+					+ "\\ No newline at end of file\n";
+			assertEquals(expected.toString(), actual);
+		}
 	}
 
 	@Test
@@ -103,33 +104,34 @@ public void testDiffCached() throws Exception {
 		write(new File(db.getWorkTree(), "test.txt"), "test");
 		File folder = new File(db.getWorkTree(), "folder");
 		folder.mkdir();
-		Git git = new Git(db);
-		git.add().addFilepattern(".").call();
-		git.commit().setMessage("Initial commit").call();
-		write(new File(folder, "folder.txt"), "folder");
-		git.add().addFilepattern(".").call();
+		try (Git git = new Git(db)) {
+			git.add().addFilepattern(".").call();
+			git.commit().setMessage("Initial commit").call();
+			write(new File(folder, "folder.txt"), "folder");
+			git.add().addFilepattern(".").call();
 
-		OutputStream out = new ByteArrayOutputStream();
-		List<DiffEntry> entries = git.diff().setOutputStream(out)
-				.setCached(true).call();
-		assertEquals(1, entries.size());
-		assertEquals(ChangeType.ADD, entries.get(0)
-				.getChangeType());
-		assertEquals("/dev/null", entries.get(0)
-				.getOldPath());
-		assertEquals("folder/folder.txt", entries.get(0)
-				.getNewPath());
+			OutputStream out = new ByteArrayOutputStream();
+			List<DiffEntry> entries = git.diff().setOutputStream(out)
+					.setCached(true).call();
+			assertEquals(1, entries.size());
+			assertEquals(ChangeType.ADD, entries.get(0)
+					.getChangeType());
+			assertEquals("/dev/null", entries.get(0)
+					.getOldPath());
+			assertEquals("folder/folder.txt", entries.get(0)
+					.getNewPath());
 
-		String actual = out.toString();
-		String expected = "diff --git a/folder/folder.txt b/folder/folder.txt\n"
-				+ "new file mode 100644\n"
-				+ "index 0000000..0119635\n"
-				+ "--- /dev/null\n"
-				+ "+++ b/folder/folder.txt\n"
-				+ "@@ -0,0 +1 @@\n"
-				+ "+folder\n"
-				+ "\\ No newline at end of file\n";
-		assertEquals(expected.toString(), actual);
+			String actual = out.toString();
+			String expected = "diff --git a/folder/folder.txt b/folder/folder.txt\n"
+					+ "new file mode 100644\n"
+					+ "index 0000000..0119635\n"
+					+ "--- /dev/null\n"
+					+ "+++ b/folder/folder.txt\n"
+					+ "@@ -0,0 +1 @@\n"
+					+ "+folder\n"
+					+ "\\ No newline at end of file\n";
+			assertEquals(expected.toString(), actual);
+		}
 	}
 
 	@Test
@@ -138,107 +140,109 @@ public void testDiffTwoCommits() throws Exception {
 		File folder = new File(db.getWorkTree(), "folder");
 		folder.mkdir();
 		write(new File(folder, "folder.txt"), "folder");
-		Git git = new Git(db);
-		git.add().addFilepattern(".").call();
-		git.commit().setMessage("Initial commit").call();
-		write(new File(folder, "folder.txt"), "folder change");
-		git.add().addFilepattern(".").call();
-		git.commit().setMessage("second commit").call();
-		write(new File(folder, "folder.txt"), "second folder change");
-		git.add().addFilepattern(".").call();
-		git.commit().setMessage("third commit").call();
+		try (Git git = new Git(db)) {
+			git.add().addFilepattern(".").call();
+			git.commit().setMessage("Initial commit").call();
+			write(new File(folder, "folder.txt"), "folder change");
+			git.add().addFilepattern(".").call();
+			git.commit().setMessage("second commit").call();
+			write(new File(folder, "folder.txt"), "second folder change");
+			git.add().addFilepattern(".").call();
+			git.commit().setMessage("third commit").call();
 
-		// bad filter
-		DiffCommand diff = git.diff().setShowNameAndStatusOnly(true)
-				.setPathFilter(PathFilter.create("test.txt"))
-				.setOldTree(getTreeIterator("HEAD^^"))
-				.setNewTree(getTreeIterator("HEAD^"));
-		List<DiffEntry> entries = diff.call();
-		assertEquals(0, entries.size());
+			// bad filter
+			DiffCommand diff = git.diff().setShowNameAndStatusOnly(true)
+					.setPathFilter(PathFilter.create("test.txt"))
+					.setOldTree(getTreeIterator("HEAD^^"))
+					.setNewTree(getTreeIterator("HEAD^"));
+			List<DiffEntry> entries = diff.call();
+			assertEquals(0, entries.size());
 
-		// no filter, two commits
-		OutputStream out = new ByteArrayOutputStream();
-		diff = git.diff().setOutputStream(out)
-				.setOldTree(getTreeIterator("HEAD^^"))
-				.setNewTree(getTreeIterator("HEAD^"));
-		entries = diff.call();
-		assertEquals(1, entries.size());
-		assertEquals(ChangeType.MODIFY, entries.get(0).getChangeType());
-		assertEquals("folder/folder.txt", entries.get(0).getOldPath());
-		assertEquals("folder/folder.txt", entries.get(0).getNewPath());
+			// no filter, two commits
+			OutputStream out = new ByteArrayOutputStream();
+			diff = git.diff().setOutputStream(out)
+					.setOldTree(getTreeIterator("HEAD^^"))
+					.setNewTree(getTreeIterator("HEAD^"));
+			entries = diff.call();
+			assertEquals(1, entries.size());
+			assertEquals(ChangeType.MODIFY, entries.get(0).getChangeType());
+			assertEquals("folder/folder.txt", entries.get(0).getOldPath());
+			assertEquals("folder/folder.txt", entries.get(0).getNewPath());
 
-		String actual = out.toString();
-		String expected = "diff --git a/folder/folder.txt b/folder/folder.txt\n"
-				+ "index 0119635..95c4c65 100644\n"
-				+ "--- a/folder/folder.txt\n"
-				+ "+++ b/folder/folder.txt\n"
-				+ "@@ -1 +1 @@\n"
-				+ "-folder\n"
-				+ "\\ No newline at end of file\n"
-				+ "+folder change\n"
-				+ "\\ No newline at end of file\n";
-		assertEquals(expected.toString(), actual);
+			String actual = out.toString();
+			String expected = "diff --git a/folder/folder.txt b/folder/folder.txt\n"
+					+ "index 0119635..95c4c65 100644\n"
+					+ "--- a/folder/folder.txt\n"
+					+ "+++ b/folder/folder.txt\n"
+					+ "@@ -1 +1 @@\n"
+					+ "-folder\n"
+					+ "\\ No newline at end of file\n"
+					+ "+folder change\n"
+					+ "\\ No newline at end of file\n";
+			assertEquals(expected.toString(), actual);
+		}
 	}
 
 	@Test
 	public void testDiffWithPrefixes() throws Exception {
 		write(new File(db.getWorkTree(), "test.txt"), "test");
-		Git git = new Git(db);
-		git.add().addFilepattern(".").call();
-		git.commit().setMessage("Initial commit").call();
-		write(new File(db.getWorkTree(), "test.txt"), "test change");
+		try (Git git = new Git(db)) {
+			git.add().addFilepattern(".").call();
+			git.commit().setMessage("Initial commit").call();
+			write(new File(db.getWorkTree(), "test.txt"), "test change");
 
-		OutputStream out = new ByteArrayOutputStream();
-		git.diff().setOutputStream(out).setSourcePrefix("old/")
-				.setDestinationPrefix("new/")
-				.call();
+			OutputStream out = new ByteArrayOutputStream();
+			git.diff().setOutputStream(out).setSourcePrefix("old/")
+					.setDestinationPrefix("new/").call();
 
-		String actual = out.toString();
-		String expected = "diff --git old/test.txt new/test.txt\n"
-				+ "index 30d74d2..4dba797 100644\n" + "--- old/test.txt\n"
-				+ "+++ new/test.txt\n" + "@@ -1 +1 @@\n" + "-test\n"
-				+ "\\ No newline at end of file\n" + "+test change\n"
-				+ "\\ No newline at end of file\n";
-		assertEquals(expected.toString(), actual);
+			String actual = out.toString();
+			String expected = "diff --git old/test.txt new/test.txt\n"
+					+ "index 30d74d2..4dba797 100644\n" + "--- old/test.txt\n"
+					+ "+++ new/test.txt\n" + "@@ -1 +1 @@\n" + "-test\n"
+					+ "\\ No newline at end of file\n" + "+test change\n"
+					+ "\\ No newline at end of file\n";
+			assertEquals(expected.toString(), actual);
+		}
 	}
 
 	@Test
 	public void testDiffWithNegativeLineCount() throws Exception {
 		write(new File(db.getWorkTree(), "test.txt"),
 				"0\n1\n2\n3\n4\n5\n6\n7\n8\n9");
-		Git git = new Git(db);
-		git.add().addFilepattern(".").call();
-		git.commit().setMessage("Initial commit").call();
-		write(new File(db.getWorkTree(), "test.txt"),
-				"0\n1\n2\n3\n4a\n5\n6\n7\n8\n9");
+		try (Git git = new Git(db)) {
+			git.add().addFilepattern(".").call();
+			git.commit().setMessage("Initial commit").call();
+			write(new File(db.getWorkTree(), "test.txt"),
+					"0\n1\n2\n3\n4a\n5\n6\n7\n8\n9");
 
-		OutputStream out = new ByteArrayOutputStream();
-		git.diff().setOutputStream(out).setContextLines(1)
-				.call();
+			OutputStream out = new ByteArrayOutputStream();
+			git.diff().setOutputStream(out).setContextLines(1).call();
 
-		String actual = out.toString();
-		String expected = "diff --git a/test.txt b/test.txt\n"
-				+ "index f55b5c9..c5ec8fd 100644\n" + "--- a/test.txt\n"
-				+ "+++ b/test.txt\n" + "@@ -4,3 +4,3 @@\n" + " 3\n" + "-4\n"
-				+ "+4a\n" + " 5\n";
-		assertEquals(expected.toString(), actual);
+			String actual = out.toString();
+			String expected = "diff --git a/test.txt b/test.txt\n"
+					+ "index f55b5c9..c5ec8fd 100644\n" + "--- a/test.txt\n"
+					+ "+++ b/test.txt\n" + "@@ -4,3 +4,3 @@\n" + " 3\n" + "-4\n"
+					+ "+4a\n" + " 5\n";
+			assertEquals(expected.toString(), actual);
+		}
 	}
 
 	@Test
 	public void testNoOutputStreamSet() throws Exception {
 		File file = writeTrashFile("test.txt", "a");
 		assertTrue(file.setLastModified(file.lastModified() - 5000));
-		Git git = new Git(db);
-		git.add().addFilepattern(".").call();
-		write(file, "b");
+		try (Git git = new Git(db)) {
+			git.add().addFilepattern(".").call();
+			write(file, "b");
 
-		List<DiffEntry> diffs = git.diff().call();
-		assertNotNull(diffs);
-		assertEquals(1, diffs.size());
-		DiffEntry diff = diffs.get(0);
-		assertEquals(ChangeType.MODIFY, diff.getChangeType());
-		assertEquals("test.txt", diff.getOldPath());
-		assertEquals("test.txt", diff.getNewPath());
+			List<DiffEntry> diffs = git.diff().call();
+			assertNotNull(diffs);
+			assertEquals(1, diffs.size());
+			DiffEntry diff = diffs.get(0);
+			assertEquals(ChangeType.MODIFY, diff.getChangeType());
+			assertEquals("test.txt", diff.getOldPath());
+			assertEquals("test.txt", diff.getNewPath());
+		}
 	}
 
 	private AbstractTreeIterator getTreeIterator(String name)
@@ -247,8 +251,9 @@ private AbstractTreeIterator getTreeIterator(String name)
 		if (id == null)
 			throw new IllegalArgumentException(name);
 		final CanonicalTreeParser p = new CanonicalTreeParser();
-		try (ObjectReader or = db.newObjectReader()) {
-			p.reset(or, new RevWalk(db).parseTree(id));
+		try (ObjectReader or = db.newObjectReader();
+				RevWalk rw = new RevWalk(db)) {
+			p.reset(or, rw.parseTree(id));
 			return p;
 		}
 	}
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 57888e7..ff7066e 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
@@ -140,11 +140,12 @@ public void testPullMerge() throws Exception {
 		ObjectId[] mergedCommits = mergeResult.getMergedCommits();
 		assertEquals(targetCommit.getId(), mergedCommits[0]);
 		assertEquals(sourceCommit.getId(), mergedCommits[1]);
-		RevCommit mergeCommit = new RevWalk(dbTarget).parseCommit(mergeResult
-				.getNewHead());
-		String message = "Merge branch 'master' of "
-				+ db.getWorkTree().getAbsolutePath();
-		assertEquals(message, mergeCommit.getShortMessage());
+		try (RevWalk rw = new RevWalk(dbTarget)) {
+			RevCommit mergeCommit = rw.parseCommit(mergeResult.getNewHead());
+			String message = "Merge branch 'master' of "
+					+ db.getWorkTree().getAbsolutePath();
+			assertEquals(message, mergeCommit.getShortMessage());
+		}
 	}
 
 	@Test
@@ -259,11 +260,12 @@ public void testPullMergeProgrammaticConfiguration() throws Exception {
 		ObjectId[] mergedCommits = mergeResult.getMergedCommits();
 		assertEquals(targetCommit.getId(), mergedCommits[0]);
 		assertEquals(sourceCommit.getId(), mergedCommits[1]);
-		RevCommit mergeCommit = new RevWalk(dbTarget).parseCommit(mergeResult
-				.getNewHead());
-		String message = "Merge branch 'other' of "
-				+ db.getWorkTree().getAbsolutePath();
-		assertEquals(message, mergeCommit.getShortMessage());
+		try (RevWalk rw = new RevWalk(dbTarget)) {
+			RevCommit mergeCommit = rw.parseCommit(mergeResult.getNewHead());
+			String message = "Merge branch 'other' of "
+					+ db.getWorkTree().getAbsolutePath();
+			assertEquals(message, mergeCommit.getShortMessage());
+		}
 	}
 
 	@Test
@@ -293,11 +295,12 @@ public void testPullMergeProgrammaticConfigurationImpliedTargetBranch()
 		ObjectId[] mergedCommits = mergeResult.getMergedCommits();
 		assertEquals(targetCommit.getId(), mergedCommits[0]);
 		assertEquals(sourceCommit.getId(), mergedCommits[1]);
-		RevCommit mergeCommit = new RevWalk(dbTarget).parseCommit(mergeResult
-				.getNewHead());
-		String message = "Merge branch 'other' of "
-				+ db.getWorkTree().getAbsolutePath() + " into other";
-		assertEquals(message, mergeCommit.getShortMessage());
+		try (RevWalk rw = new RevWalk(dbTarget)) {
+			RevCommit mergeCommit = rw.parseCommit(mergeResult.getNewHead());
+			String message = "Merge branch 'other' of "
+					+ db.getWorkTree().getAbsolutePath() + " into other";
+			assertEquals(message, mergeCommit.getShortMessage());
+		}
 	}
 
 	private enum TestPullMode {
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/PullCommandWithRebaseTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/PullCommandWithRebaseTest.java
index 9ad845b..b405f6a 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/PullCommandWithRebaseTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/PullCommandWithRebaseTest.java
@@ -273,26 +273,27 @@ public void testPullFastForwardWithLocalCommitAndRebaseFlagSet() throws Exceptio
 
 		// Get the HEAD and HEAD~1 commits
 		Repository targetRepo = target.getRepository();
-		RevWalk revWalk = new RevWalk(targetRepo);
-		ObjectId headId = targetRepo.resolve(Constants.HEAD);
-		RevCommit root = revWalk.parseCommit(headId);
-		revWalk.markStart(root);
-		// HEAD
-		RevCommit head = revWalk.next();
-		// HEAD~1
-		RevCommit beforeHead = revWalk.next();
+		try (RevWalk revWalk = new RevWalk(targetRepo)) {
+			ObjectId headId = targetRepo.resolve(Constants.HEAD);
+			RevCommit root = revWalk.parseCommit(headId);
+			revWalk.markStart(root);
+			// HEAD
+			RevCommit head = revWalk.next();
+			// HEAD~1
+			RevCommit beforeHead = revWalk.next();
 
-		// verify the commit message on the HEAD commit
-		assertEquals(TARGET_COMMIT_MESSAGE, head.getFullMessage());
-		// verify the commit just before HEAD
-		assertEquals(SOURCE_COMMIT_MESSAGE, beforeHead.getFullMessage());
+			// verify the commit message on the HEAD commit
+			assertEquals(TARGET_COMMIT_MESSAGE, head.getFullMessage());
+			// verify the commit just before HEAD
+			assertEquals(SOURCE_COMMIT_MESSAGE, beforeHead.getFullMessage());
 
-		// verify file states
-		assertFileContentsEqual(sourceFile, SOURCE_FILE_CONTENTS);
-		assertFileContentsEqual(newFile, NEW_FILE_CONTENTS);
-		// verify repository state
-		assertEquals(RepositoryState.SAFE, target
-			.getRepository().getRepositoryState());
+			// verify file states
+			assertFileContentsEqual(sourceFile, SOURCE_FILE_CONTENTS);
+			assertFileContentsEqual(newFile, NEW_FILE_CONTENTS);
+			// verify repository state
+			assertEquals(RepositoryState.SAFE, target
+				.getRepository().getRepositoryState());
+		}
 	}
 
 	@Override
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/PushCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/PushCommandTest.java
index 1fcfef9..2a32540 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/PushCommandTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/PushCommandTest.java
@@ -90,26 +90,27 @@ public void testPush() throws JGitInternalException, IOException,
 		remoteConfig.update(config);
 		config.save();
 
-		Git git1 = new Git(db);
-		// create some refs via commits and tag
-		RevCommit commit = git1.commit().setMessage("initial commit").call();
-		Ref tagRef = git1.tag().setName("tag").call();
+		try (Git git1 = new Git(db)) {
+			// create some refs via commits and tag
+			RevCommit commit = git1.commit().setMessage("initial commit").call();
+			Ref tagRef = git1.tag().setName("tag").call();
 
-		try {
-			db2.resolve(commit.getId().getName() + "^{commit}");
-			fail("id shouldn't exist yet");
-		} catch (MissingObjectException e) {
-			// we should get here
+			try {
+				db2.resolve(commit.getId().getName() + "^{commit}");
+				fail("id shouldn't exist yet");
+			} catch (MissingObjectException e) {
+				// we should get here
+			}
+
+			RefSpec spec = new RefSpec("refs/heads/master:refs/heads/x");
+			git1.push().setRemote("test").setRefSpecs(spec)
+					.call();
+
+			assertEquals(commit.getId(),
+					db2.resolve(commit.getId().getName() + "^{commit}"));
+			assertEquals(tagRef.getObjectId(),
+					db2.resolve(tagRef.getObjectId().getName()));
 		}
-
-		RefSpec spec = new RefSpec("refs/heads/master:refs/heads/x");
-		git1.push().setRemote("test").setRefSpecs(spec)
-				.call();
-
-		assertEquals(commit.getId(),
-				db2.resolve(commit.getId().getName() + "^{commit}"));
-		assertEquals(tagRef.getObjectId(),
-				db2.resolve(tagRef.getObjectId().getName()));
 	}
 
 	@Test
@@ -132,15 +133,16 @@ public void testPrePushHook() throws JGitInternalException, IOException,
 				+ hookOutput.toPath() + "\"\ncat - >>\"" + hookOutput.toPath()
 				+ "\"\nexit 0");
 
-		Git git1 = new Git(db);
-		// create some refs via commits and tag
-		RevCommit commit = git1.commit().setMessage("initial commit").call();
+		try (Git git1 = new Git(db)) {
+			// create some refs via commits and tag
+			RevCommit commit = git1.commit().setMessage("initial commit").call();
 
-		RefSpec spec = new RefSpec("refs/heads/master:refs/heads/x");
-		git1.push().setRemote("test").setRefSpecs(spec).call();
-		assertEquals("1:test, 2:" + uri + ", 3:\n" + "refs/heads/master "
-				+ commit.getName() + " refs/heads/x "
-				+ ObjectId.zeroId().name(), read(hookOutput));
+			RefSpec spec = new RefSpec("refs/heads/master:refs/heads/x");
+			git1.push().setRemote("test").setRefSpecs(spec).call();
+			assertEquals("1:test, 2:" + uri + ", 3:\n" + "refs/heads/master "
+					+ commit.getName() + " refs/heads/x "
+					+ ObjectId.zeroId().name(), read(hookOutput));
+		}
 	}
 
 	private File writeHookFile(final String name, final String data)
@@ -160,45 +162,45 @@ public void testTrackingUpdate() throws Exception {
 		String branch = "refs/heads/master";
 		String trackingBranch = "refs/remotes/" + remote + "/master";
 
-		Git git = new Git(db);
+		try (Git git = new Git(db)) {
+			RevCommit commit1 = git.commit().setMessage("Initial commit")
+					.call();
 
-		RevCommit commit1 = git.commit().setMessage("Initial commit")
-				.call();
+			RefUpdate branchRefUpdate = db.updateRef(branch);
+			branchRefUpdate.setNewObjectId(commit1.getId());
+			branchRefUpdate.update();
 
-		RefUpdate branchRefUpdate = db.updateRef(branch);
-		branchRefUpdate.setNewObjectId(commit1.getId());
-		branchRefUpdate.update();
+			RefUpdate trackingBranchRefUpdate = db.updateRef(trackingBranch);
+			trackingBranchRefUpdate.setNewObjectId(commit1.getId());
+			trackingBranchRefUpdate.update();
 
-		RefUpdate trackingBranchRefUpdate = db.updateRef(trackingBranch);
-		trackingBranchRefUpdate.setNewObjectId(commit1.getId());
-		trackingBranchRefUpdate.update();
-
-		final StoredConfig config = db.getConfig();
-		RemoteConfig remoteConfig = new RemoteConfig(config, remote);
-		URIish uri = new URIish(db2.getDirectory().toURI().toURL());
-		remoteConfig.addURI(uri);
-		remoteConfig.addFetchRefSpec(new RefSpec("+refs/heads/*:refs/remotes/"
-				+ remote + "/*"));
-		remoteConfig.update(config);
-		config.save();
+			final StoredConfig config = db.getConfig();
+			RemoteConfig remoteConfig = new RemoteConfig(config, remote);
+			URIish uri = new URIish(db2.getDirectory().toURI().toURL());
+			remoteConfig.addURI(uri);
+			remoteConfig.addFetchRefSpec(new RefSpec("+refs/heads/*:refs/remotes/"
+					+ remote + "/*"));
+			remoteConfig.update(config);
+			config.save();
 
 
-		RevCommit commit2 = git.commit().setMessage("Commit to push").call();
+			RevCommit commit2 = git.commit().setMessage("Commit to push").call();
 
-		RefSpec spec = new RefSpec(branch + ":" + branch);
-		Iterable<PushResult> resultIterable = git.push().setRemote(remote)
-				.setRefSpecs(spec).call();
+			RefSpec spec = new RefSpec(branch + ":" + branch);
+			Iterable<PushResult> resultIterable = git.push().setRemote(remote)
+					.setRefSpecs(spec).call();
 
-		PushResult result = resultIterable.iterator().next();
-		TrackingRefUpdate trackingRefUpdate = result
-				.getTrackingRefUpdate(trackingBranch);
+			PushResult result = resultIterable.iterator().next();
+			TrackingRefUpdate trackingRefUpdate = result
+					.getTrackingRefUpdate(trackingBranch);
 
-		assertNotNull(trackingRefUpdate);
-		assertEquals(trackingBranch, trackingRefUpdate.getLocalName());
-		assertEquals(branch, trackingRefUpdate.getRemoteName());
-		assertEquals(commit2.getId(), trackingRefUpdate.getNewObjectId());
-		assertEquals(commit2.getId(), db.resolve(trackingBranch));
-		assertEquals(commit2.getId(), db2.resolve(branch));
+			assertNotNull(trackingRefUpdate);
+			assertEquals(trackingBranch, trackingRefUpdate.getLocalName());
+			assertEquals(branch, trackingRefUpdate.getRemoteName());
+			assertEquals(commit2.getId(), trackingRefUpdate.getNewObjectId());
+			assertEquals(commit2.getId(), db.resolve(trackingBranch));
+			assertEquals(commit2.getId(), db2.resolve(branch));
+		}
 	}
 
 	/**
@@ -208,40 +210,38 @@ public void testTrackingUpdate() throws Exception {
 	 */
 	@Test
 	public void testPushRefUpdate() throws Exception {
-		Git git = new Git(db);
-		Git git2 = new Git(createBareRepository());
+		try (Git git = new Git(db);
+				Git git2 = new Git(createBareRepository())) {
+			final StoredConfig config = git.getRepository().getConfig();
+			RemoteConfig remoteConfig = new RemoteConfig(config, "test");
+			URIish uri = new URIish(git2.getRepository().getDirectory().toURI()
+					.toURL());
+			remoteConfig.addURI(uri);
+			remoteConfig.addPushRefSpec(new RefSpec("+refs/heads/*:refs/heads/*"));
+			remoteConfig.update(config);
+			config.save();
 
-		final StoredConfig config = git.getRepository().getConfig();
-		RemoteConfig remoteConfig = new RemoteConfig(config, "test");
-		URIish uri = new URIish(git2.getRepository().getDirectory().toURI()
-				.toURL());
-		remoteConfig.addURI(uri);
-		remoteConfig.addPushRefSpec(new RefSpec("+refs/heads/*:refs/heads/*"));
-		remoteConfig.update(config);
-		config.save();
+			writeTrashFile("f", "content of f");
+			git.add().addFilepattern("f").call();
+			RevCommit commit = git.commit().setMessage("adding f").call();
 
-		writeTrashFile("f", "content of f");
-		git.add().addFilepattern("f").call();
-		RevCommit commit = git.commit().setMessage("adding f").call();
-
-		assertEquals(null, git2.getRepository().resolve("refs/heads/master"));
-		git.push().setRemote("test").call();
-		assertEquals(commit.getId(),
-				git2.getRepository().resolve("refs/heads/master"));
-
-		git.branchCreate().setName("refs/heads/test").call();
-		git.checkout().setName("refs/heads/test").call();
-
-
-		for (int i = 0; i < 6; i++) {
-			writeTrashFile("f" + i, "content of f" + i);
-			git.add().addFilepattern("f" + i).call();
-			commit = git.commit().setMessage("adding f" + i).call();
+			assertEquals(null, git2.getRepository().resolve("refs/heads/master"));
 			git.push().setRemote("test").call();
-			git2.getRepository().getAllRefs();
-			assertEquals("failed to update on attempt " + i, commit.getId(),
-					git2.getRepository().resolve("refs/heads/test"));
+			assertEquals(commit.getId(),
+					git2.getRepository().resolve("refs/heads/master"));
 
+			git.branchCreate().setName("refs/heads/test").call();
+			git.checkout().setName("refs/heads/test").call();
+
+			for (int i = 0; i < 6; i++) {
+				writeTrashFile("f" + i, "content of f" + i);
+				git.add().addFilepattern("f" + i).call();
+				commit = git.commit().setMessage("adding f" + i).call();
+				git.push().setRemote("test").call();
+				git2.getRepository().getAllRefs();
+				assertEquals("failed to update on attempt " + i, commit.getId(),
+						git2.getRepository().resolve("refs/heads/test"));
+			}
 		}
 	}
 
@@ -252,28 +252,26 @@ public void testPushRefUpdate() throws Exception {
 	 */
 	@Test
 	public void testPushWithRefSpecFromConfig() throws Exception {
-		Git git = new Git(db);
-		Git git2 = new Git(createBareRepository());
+		try (Git git = new Git(db);
+				Git git2 = new Git(createBareRepository())) {
+			final StoredConfig config = git.getRepository().getConfig();
+			RemoteConfig remoteConfig = new RemoteConfig(config, "test");
+			URIish uri = new URIish(git2.getRepository().getDirectory().toURI()
+					.toURL());
+			remoteConfig.addURI(uri);
+			remoteConfig.addPushRefSpec(new RefSpec("HEAD:refs/heads/newbranch"));
+			remoteConfig.update(config);
+			config.save();
 
-		final StoredConfig config = git.getRepository().getConfig();
-		RemoteConfig remoteConfig = new RemoteConfig(config, "test");
-		URIish uri = new URIish(git2.getRepository().getDirectory().toURI()
-				.toURL());
-		remoteConfig.addURI(uri);
-		remoteConfig.addPushRefSpec(new RefSpec("HEAD:refs/heads/newbranch"));
-		remoteConfig.update(config);
-		config.save();
+			writeTrashFile("f", "content of f");
+			git.add().addFilepattern("f").call();
+			RevCommit commit = git.commit().setMessage("adding f").call();
 
-		writeTrashFile("f", "content of f");
-		git.add().addFilepattern("f").call();
-		RevCommit commit = git.commit().setMessage("adding f").call();
-
-		assertEquals(null, git2.getRepository().resolve("refs/heads/master"));
-		git.push().setRemote("test").call();
-		assertEquals(commit.getId(),
-				git2.getRepository().resolve("refs/heads/newbranch"));
-
-
+			assertEquals(null, git2.getRepository().resolve("refs/heads/master"));
+			git.push().setRemote("test").call();
+			assertEquals(commit.getId(),
+					git2.getRepository().resolve("refs/heads/newbranch"));
+		}
 	}
 
 	/**
@@ -283,38 +281,37 @@ public void testPushWithRefSpecFromConfig() throws Exception {
 	 */
 	@Test
 	public void testPushWithoutPushRefSpec() throws Exception {
-		Git git = new Git(db);
-		Git git2 = new Git(createBareRepository());
+		try (Git git = new Git(db);
+				Git git2 = new Git(createBareRepository())) {
+			final StoredConfig config = git.getRepository().getConfig();
+			RemoteConfig remoteConfig = new RemoteConfig(config, "test");
+			URIish uri = new URIish(git2.getRepository().getDirectory().toURI()
+					.toURL());
+			remoteConfig.addURI(uri);
+			remoteConfig.addFetchRefSpec(new RefSpec(
+					"+refs/heads/*:refs/remotes/origin/*"));
+			remoteConfig.update(config);
+			config.save();
 
-		final StoredConfig config = git.getRepository().getConfig();
-		RemoteConfig remoteConfig = new RemoteConfig(config, "test");
-		URIish uri = new URIish(git2.getRepository().getDirectory().toURI()
-				.toURL());
-		remoteConfig.addURI(uri);
-		remoteConfig.addFetchRefSpec(new RefSpec(
-				"+refs/heads/*:refs/remotes/origin/*"));
-		remoteConfig.update(config);
-		config.save();
+			writeTrashFile("f", "content of f");
+			git.add().addFilepattern("f").call();
+			RevCommit commit = git.commit().setMessage("adding f").call();
 
-		writeTrashFile("f", "content of f");
-		git.add().addFilepattern("f").call();
-		RevCommit commit = git.commit().setMessage("adding f").call();
+			git.checkout().setName("not-pushed").setCreateBranch(true).call();
+			git.checkout().setName("branchtopush").setCreateBranch(true).call();
 
-		git.checkout().setName("not-pushed").setCreateBranch(true).call();
-		git.checkout().setName("branchtopush").setCreateBranch(true).call();
-
-		assertEquals(null,
-				git2.getRepository().resolve("refs/heads/branchtopush"));
-		assertEquals(null, git2.getRepository()
-				.resolve("refs/heads/not-pushed"));
-		assertEquals(null, git2.getRepository().resolve("refs/heads/master"));
-		git.push().setRemote("test").call();
-		assertEquals(commit.getId(),
-				git2.getRepository().resolve("refs/heads/branchtopush"));
-		assertEquals(null, git2.getRepository()
-				.resolve("refs/heads/not-pushed"));
-		assertEquals(null, git2.getRepository().resolve("refs/heads/master"));
-
+			assertEquals(null,
+					git2.getRepository().resolve("refs/heads/branchtopush"));
+			assertEquals(null, git2.getRepository()
+					.resolve("refs/heads/not-pushed"));
+			assertEquals(null, git2.getRepository().resolve("refs/heads/master"));
+			git.push().setRemote("test").call();
+			assertEquals(commit.getId(),
+					git2.getRepository().resolve("refs/heads/branchtopush"));
+			assertEquals(null, git2.getRepository()
+					.resolve("refs/heads/not-pushed"));
+			assertEquals(null, git2.getRepository().resolve("refs/heads/master"));
+		}
 	}
 
 	/**
@@ -335,51 +332,51 @@ public void testPushAfterGC() throws Exception {
 		remoteConfig.update(config);
 		config.save();
 
-		Git git1 = new Git(db);
-		Git git2 = new Git(db2);
+		try (Git git1 = new Git(db);
+				Git git2 = new Git(db2)) {
+			// push master (with a new commit) to the remote
+			git1.commit().setMessage("initial commit").call();
 
-		// push master (with a new commit) to the remote
-		git1.commit().setMessage("initial commit").call();
-
-		RefSpec spec = new RefSpec("refs/heads/*:refs/heads/*");
-		git1.push().setRemote("test").setRefSpecs(spec).call();
-
-		// create an unrelated ref and a commit on our remote
-		git2.branchCreate().setName("refs/heads/other").call();
-		git2.checkout().setName("refs/heads/other").call();
-
-		writeTrashFile("a", "content of a");
-		git2.add().addFilepattern("a").call();
-		RevCommit commit2 = git2.commit().setMessage("adding a").call();
-
-		// run a gc to ensure we have a bitmap index
-		Properties res = git1.gc().setExpire(null).call();
-		assertEquals(7, res.size());
-
-		// create another commit so we have something else to push
-		writeTrashFile("b", "content of b");
-		git1.add().addFilepattern("b").call();
-		RevCommit commit3 = git1.commit().setMessage("adding b").call();
-
-		try {
-			// Re-run the push.  Failure may happen here.
+			RefSpec spec = new RefSpec("refs/heads/*:refs/heads/*");
 			git1.push().setRemote("test").setRefSpecs(spec).call();
-		} catch (TransportException e) {
-			assertTrue("should be caused by a MissingObjectException", e
-					.getCause().getCause() instanceof MissingObjectException);
-			fail("caught MissingObjectException for a change we don't have");
-		}
 
-		// Remote will have both a and b.  Master will have only b
-		try {
-			db.resolve(commit2.getId().getName() + "^{commit}");
-			fail("id shouldn't exist locally");
-		} catch (MissingObjectException e) {
-			// we should get here
+			// create an unrelated ref and a commit on our remote
+			git2.branchCreate().setName("refs/heads/other").call();
+			git2.checkout().setName("refs/heads/other").call();
+
+			writeTrashFile("a", "content of a");
+			git2.add().addFilepattern("a").call();
+			RevCommit commit2 = git2.commit().setMessage("adding a").call();
+
+			// run a gc to ensure we have a bitmap index
+			Properties res = git1.gc().setExpire(null).call();
+			assertEquals(7, res.size());
+
+			// create another commit so we have something else to push
+			writeTrashFile("b", "content of b");
+			git1.add().addFilepattern("b").call();
+			RevCommit commit3 = git1.commit().setMessage("adding b").call();
+
+			try {
+				// Re-run the push.  Failure may happen here.
+				git1.push().setRemote("test").setRefSpecs(spec).call();
+			} catch (TransportException e) {
+				assertTrue("should be caused by a MissingObjectException", e
+						.getCause().getCause() instanceof MissingObjectException);
+				fail("caught MissingObjectException for a change we don't have");
+			}
+
+			// Remote will have both a and b.  Master will have only b
+			try {
+				db.resolve(commit2.getId().getName() + "^{commit}");
+				fail("id shouldn't exist locally");
+			} catch (MissingObjectException e) {
+				// we should get here
+			}
+			assertEquals(commit2.getId(),
+					db2.resolve(commit2.getId().getName() + "^{commit}"));
+			assertEquals(commit3.getId(),
+					db2.resolve(commit3.getId().getName() + "^{commit}"));
 		}
-		assertEquals(commit2.getId(),
-				db2.resolve(commit2.getId().getName() + "^{commit}"));
-		assertEquals(commit3.getId(),
-				db2.resolve(commit3.getId().getName() + "^{commit}"));
 	}
 }
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/RebaseCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/RebaseCommandTest.java
index 8b0ed5f..24cb522 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/RebaseCommandTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/RebaseCommandTest.java
@@ -288,13 +288,14 @@ public void testRebaseShouldIgnoreMergeCommits()
 		RebaseResult res = git.rebase().setUpstream("refs/heads/master").call();
 		assertEquals(Status.OK, res.getStatus());
 
-		RevWalk rw = new RevWalk(db);
-		rw.markStart(rw.parseCommit(db.resolve("refs/heads/topic")));
-		assertDerivedFrom(rw.next(), e);
-		assertDerivedFrom(rw.next(), d);
-		assertDerivedFrom(rw.next(), c);
-		assertEquals(b, rw.next());
-		assertEquals(a, rw.next());
+		try (RevWalk rw = new RevWalk(db)) {
+			rw.markStart(rw.parseCommit(db.resolve("refs/heads/topic")));
+			assertDerivedFrom(rw.next(), e);
+			assertDerivedFrom(rw.next(), d);
+			assertDerivedFrom(rw.next(), c);
+			assertEquals(b, rw.next());
+			assertEquals(a, rw.next());
+		}
 
 		List<ReflogEntry> headLog = db.getReflogReader(Constants.HEAD)
 				.getReverseEntries();
@@ -354,8 +355,6 @@ public void testRebasePreservingMerges2() throws Exception {
 	 */
 	private void doTestRebasePreservingMerges(boolean testConflict)
 			throws Exception {
-		RevWalk rw = new RevWalk(db);
-
 		// create file1 on master
 		writeTrashFile(FILE1, FILE1);
 		git.add().addFilepattern(FILE1).call();
@@ -409,7 +408,9 @@ private void doTestRebasePreservingMerges(boolean testConflict)
 			f = git.commit().setMessage("commit f").call();
 		} else {
 			assertEquals(MergeStatus.MERGED, result.getMergeStatus());
-			f = rw.parseCommit(result.getNewHead());
+			try (RevWalk rw = new RevWalk(db)) {
+				f = rw.parseCommit(result.getNewHead());
+			}
 		}
 
 		RebaseResult res = git.rebase().setUpstream("refs/heads/master")
@@ -453,23 +454,25 @@ private void doTestRebasePreservingMerges(boolean testConflict)
 		assertEquals("file2", read("file2"));
 		assertEquals("more change", read("file3"));
 
-		rw.markStart(rw.parseCommit(db.resolve("refs/heads/topic")));
-		RevCommit newF = rw.next();
-		assertDerivedFrom(newF, f);
-		assertEquals(2, newF.getParentCount());
-		RevCommit newD = rw.next();
-		assertDerivedFrom(newD, d);
-		if (testConflict)
-			assertEquals("d new", readFile("conflict", newD));
-		RevCommit newE = rw.next();
-		assertDerivedFrom(newE, e);
-		if (testConflict)
-			assertEquals("e new", readFile("conflict", newE));
-		assertEquals(newD, newF.getParent(0));
-		assertEquals(newE, newF.getParent(1));
-		assertDerivedFrom(rw.next(), c);
-		assertEquals(b, rw.next());
-		assertEquals(a, rw.next());
+		try (RevWalk rw = new RevWalk(db)) {
+			rw.markStart(rw.parseCommit(db.resolve("refs/heads/topic")));
+			RevCommit newF = rw.next();
+			assertDerivedFrom(newF, f);
+			assertEquals(2, newF.getParentCount());
+			RevCommit newD = rw.next();
+			assertDerivedFrom(newD, d);
+			if (testConflict)
+				assertEquals("d new", readFile("conflict", newD));
+			RevCommit newE = rw.next();
+			assertDerivedFrom(newE, e);
+			if (testConflict)
+				assertEquals("e new", readFile("conflict", newE));
+			assertEquals(newD, newF.getParent(0));
+			assertEquals(newE, newF.getParent(1));
+			assertDerivedFrom(rw.next(), c);
+			assertEquals(b, rw.next());
+			assertEquals(a, rw.next());
+		}
 	}
 
 	private String readFile(String path, RevCommit commit) throws IOException {
@@ -517,88 +520,89 @@ public void testRebasePreservingMergesWithUnrelatedSide2() throws Exception {
 	 */
 	private void doTestRebasePreservingMergesWithUnrelatedSide(
 			boolean testConflict) throws Exception {
-		RevWalk rw = new RevWalk(db);
-		rw.sort(RevSort.TOPO);
+		try (RevWalk rw = new RevWalk(db)) {
+			rw.sort(RevSort.TOPO);
 
-		writeTrashFile(FILE1, FILE1);
-		git.add().addFilepattern(FILE1).call();
-		RevCommit a = git.commit().setMessage("commit a").call();
+			writeTrashFile(FILE1, FILE1);
+			git.add().addFilepattern(FILE1).call();
+			RevCommit a = git.commit().setMessage("commit a").call();
 
-		writeTrashFile("file2", "blah");
-		git.add().addFilepattern("file2").call();
-		RevCommit b = git.commit().setMessage("commit b").call();
+			writeTrashFile("file2", "blah");
+			git.add().addFilepattern("file2").call();
+			RevCommit b = git.commit().setMessage("commit b").call();
 
-		// create a topic branch
-		createBranch(b, "refs/heads/topic");
-		checkoutBranch("refs/heads/topic");
+			// create a topic branch
+			createBranch(b, "refs/heads/topic");
+			checkoutBranch("refs/heads/topic");
 
-		writeTrashFile("file3", "more changess");
-		writeTrashFile(FILE1, "preparing conflict");
-		git.add().addFilepattern("file3").addFilepattern(FILE1).call();
-		RevCommit c = git.commit().setMessage("commit c").call();
+			writeTrashFile("file3", "more changess");
+			writeTrashFile(FILE1, "preparing conflict");
+			git.add().addFilepattern("file3").addFilepattern(FILE1).call();
+			RevCommit c = git.commit().setMessage("commit c").call();
 
-		createBranch(a, "refs/heads/side");
-		checkoutBranch("refs/heads/side");
-		writeTrashFile("conflict", "e");
-		writeTrashFile(FILE1, FILE1 + "\n" + "line 2");
-		git.add().addFilepattern(".").call();
-		RevCommit e = git.commit().setMessage("commit e").call();
-
-		// switch back to topic and merge in side, creating d
-		checkoutBranch("refs/heads/topic");
-		MergeResult result = git.merge().include(e)
-				.setStrategy(MergeStrategy.RESOLVE).call();
-
-		assertEquals(MergeStatus.CONFLICTING, result.getMergeStatus());
-		assertEquals(result.getConflicts().keySet(),
-				Collections.singleton(FILE1));
-		writeTrashFile(FILE1, "merge resolution");
-		git.add().addFilepattern(FILE1).call();
-		RevCommit d = git.commit().setMessage("commit d").call();
-
-		RevCommit f = commitFile("file2", "new content two", "topic");
-
-		checkoutBranch("refs/heads/master");
-		writeTrashFile("fileg", "fileg");
-		if (testConflict)
-			writeTrashFile("conflict", "g");
-		git.add().addFilepattern(".").call();
-		RevCommit g = git.commit().setMessage("commit g").call();
-
-		checkoutBranch("refs/heads/topic");
-		RebaseResult res = git.rebase().setUpstream("refs/heads/master")
-				.setPreserveMerges(true).call();
-		if (testConflict) {
-			assertEquals(Status.STOPPED, res.getStatus());
-			assertEquals(Collections.singleton("conflict"), git.status().call()
-					.getConflicting());
-			// resolve
+			createBranch(a, "refs/heads/side");
+			checkoutBranch("refs/heads/side");
 			writeTrashFile("conflict", "e");
-			git.add().addFilepattern("conflict").call();
-			res = git.rebase().setOperation(Operation.CONTINUE).call();
+			writeTrashFile(FILE1, FILE1 + "\n" + "line 2");
+			git.add().addFilepattern(".").call();
+			RevCommit e = git.commit().setMessage("commit e").call();
+
+			// switch back to topic and merge in side, creating d
+			checkoutBranch("refs/heads/topic");
+			MergeResult result = git.merge().include(e)
+					.setStrategy(MergeStrategy.RESOLVE).call();
+
+			assertEquals(MergeStatus.CONFLICTING, result.getMergeStatus());
+			assertEquals(result.getConflicts().keySet(),
+					Collections.singleton(FILE1));
+			writeTrashFile(FILE1, "merge resolution");
+			git.add().addFilepattern(FILE1).call();
+			RevCommit d = git.commit().setMessage("commit d").call();
+
+			RevCommit f = commitFile("file2", "new content two", "topic");
+
+			checkoutBranch("refs/heads/master");
+			writeTrashFile("fileg", "fileg");
+			if (testConflict)
+				writeTrashFile("conflict", "g");
+			git.add().addFilepattern(".").call();
+			RevCommit g = git.commit().setMessage("commit g").call();
+
+			checkoutBranch("refs/heads/topic");
+			RebaseResult res = git.rebase().setUpstream("refs/heads/master")
+					.setPreserveMerges(true).call();
+			if (testConflict) {
+				assertEquals(Status.STOPPED, res.getStatus());
+				assertEquals(Collections.singleton("conflict"), git.status().call()
+						.getConflicting());
+				// resolve
+				writeTrashFile("conflict", "e");
+				git.add().addFilepattern("conflict").call();
+				res = git.rebase().setOperation(Operation.CONTINUE).call();
+			}
+			assertEquals(Status.OK, res.getStatus());
+
+			assertEquals("merge resolution", read(FILE1));
+			assertEquals("new content two", read("file2"));
+			assertEquals("more changess", read("file3"));
+			assertEquals("fileg", read("fileg"));
+
+			rw.markStart(rw.parseCommit(db.resolve("refs/heads/topic")));
+			RevCommit newF = rw.next();
+			assertDerivedFrom(newF, f);
+			RevCommit newD = rw.next();
+			assertDerivedFrom(newD, d);
+			assertEquals(2, newD.getParentCount());
+			RevCommit newC = rw.next();
+			assertDerivedFrom(newC, c);
+			RevCommit newE = rw.next();
+			assertEquals(e, newE);
+			assertEquals(newC, newD.getParent(0));
+			assertEquals(e, newD.getParent(1));
+			assertEquals(g, rw.next());
+			assertEquals(b, rw.next());
+			assertEquals(a, rw.next());
 		}
-		assertEquals(Status.OK, res.getStatus());
-
-		assertEquals("merge resolution", read(FILE1));
-		assertEquals("new content two", read("file2"));
-		assertEquals("more changess", read("file3"));
-		assertEquals("fileg", read("fileg"));
-
-		rw.markStart(rw.parseCommit(db.resolve("refs/heads/topic")));
-		RevCommit newF = rw.next();
-		assertDerivedFrom(newF, f);
-		RevCommit newD = rw.next();
-		assertDerivedFrom(newD, d);
-		assertEquals(2, newD.getParentCount());
-		RevCommit newC = rw.next();
-		assertDerivedFrom(newC, c);
-		RevCommit newE = rw.next();
-		assertEquals(e, newE);
-		assertEquals(newC, newD.getParent(0));
-		assertEquals(e, newD.getParent(1));
-		assertEquals(g, rw.next());
-		assertEquals(b, rw.next());
-		assertEquals(a, rw.next());
 	}
 
 	@Test
@@ -687,8 +691,10 @@ public void testConflictFreeWithSingleFile() throws Exception {
 		checkFile(theFile, "1master\n2\n3\ntopic\n");
 		// our old branch should be checked out again
 		assertEquals("refs/heads/topic", db.getFullBranch());
-		assertEquals(lastMasterChange, new RevWalk(db).parseCommit(
-				db.resolve(Constants.HEAD)).getParent(0));
+		try (RevWalk rw = new RevWalk(db)) {
+			assertEquals(lastMasterChange, rw.parseCommit(
+					db.resolve(Constants.HEAD)).getParent(0));
+		}
 		assertEquals(origHead, db.readOrigHead());
 		List<ReflogEntry> headLog = db.getReflogReader(Constants.HEAD)
 				.getReverseEntries();
@@ -737,8 +743,10 @@ public void testDetachedHead() throws Exception {
 		RebaseResult res = git.rebase().setUpstream("refs/heads/master").call();
 		assertEquals(Status.OK, res.getStatus());
 		checkFile(theFile, "1master\n2\n3\ntopic\n");
-		assertEquals(lastMasterChange, new RevWalk(db).parseCommit(
-				db.resolve(Constants.HEAD)).getParent(0));
+		try (RevWalk rw = new RevWalk(db)) {
+			assertEquals(lastMasterChange, rw.parseCommit(
+					db.resolve(Constants.HEAD)).getParent(0));
+		}
 
 		List<ReflogEntry> headLog = db.getReflogReader(Constants.HEAD)
 				.getReverseEntries();
@@ -785,8 +793,10 @@ public void testFilesAddedFromTwoBranches() throws Exception {
 
 		// our old branch should be checked out again
 		assertEquals("refs/heads/file3", db.getFullBranch());
-		assertEquals(addFile2, new RevWalk(db).parseCommit(
-				db.resolve(Constants.HEAD)).getParent(0));
+		try (RevWalk rw = new RevWalk(db)) {
+			assertEquals(addFile2, rw.parseCommit(
+					db.resolve(Constants.HEAD)).getParent(0));
+		}
 
 		checkoutBranch("refs/heads/file2");
 		assertTrue(new File(db.getWorkTree(), FILE1).exists());
@@ -846,9 +856,10 @@ public void testStopOnConflict() throws Exception {
 		assertEquals(res.getStatus(), Status.ABORTED);
 		assertEquals("refs/heads/topic", db.getFullBranch());
 		checkFile(FILE1, "1topic", "2", "3", "topic4");
-		RevWalk rw = new RevWalk(db);
-		assertEquals(lastTopicCommit, rw
-				.parseCommit(db.resolve(Constants.HEAD)));
+		try (RevWalk rw = new RevWalk(db)) {
+			assertEquals(lastTopicCommit,
+					rw.parseCommit(db.resolve(Constants.HEAD)));
+		}
 		assertEquals(RepositoryState.SAFE, db.getRepositoryState());
 
 		// rebase- dir in .git must be deleted
@@ -909,9 +920,10 @@ public void testStopOnConflictAndAbortWithDetachedHEAD() throws Exception {
 		assertEquals(res.getStatus(), Status.ABORTED);
 		assertEquals(lastTopicCommit.getName(), db.getFullBranch());
 		checkFile(FILE1, "1topic", "2", "3", "topic4");
-		RevWalk rw = new RevWalk(db);
-		assertEquals(lastTopicCommit,
-				rw.parseCommit(db.resolve(Constants.HEAD)));
+		try (RevWalk rw = new RevWalk(db)) {
+			assertEquals(lastTopicCommit,
+					rw.parseCommit(db.resolve(Constants.HEAD)));
+		}
 		assertEquals(RepositoryState.SAFE, db.getRepositoryState());
 
 		// rebase- dir in .git must be deleted
@@ -966,11 +978,12 @@ public void testStopOnConflictAndContinue() throws Exception {
 		assertEquals(RepositoryState.SAFE, db.getRepositoryState());
 
 		ObjectId headId = db.resolve(Constants.HEAD);
-		RevWalk rw = new RevWalk(db);
-		RevCommit rc = rw.parseCommit(headId);
-		RevCommit parent = rw.parseCommit(rc.getParent(0));
-		assertEquals("change file1 in topic\n\nThis is conflicting", parent
-				.getFullMessage());
+		try (RevWalk rw = new RevWalk(db)) {
+			RevCommit rc = rw.parseCommit(headId);
+			RevCommit parent = rw.parseCommit(rc.getParent(0));
+			assertEquals("change file1 in topic\n\nThis is conflicting", parent
+					.getFullMessage());
+		}
 	}
 
 	@Test
@@ -1017,9 +1030,10 @@ public void testStopOnConflictAndContinueWithNoDeltaToMaster()
 		git.rebase().setOperation(Operation.SKIP).call();
 
 		ObjectId headId = db.resolve(Constants.HEAD);
-		RevWalk rw = new RevWalk(db);
-		RevCommit rc = rw.parseCommit(headId);
-		assertEquals("change file1 in master", rc.getFullMessage());
+		try (RevWalk rw = new RevWalk(db)) {
+			RevCommit rc = rw.parseCommit(headId);
+			assertEquals("change file1 in master", rc.getFullMessage());
+		}
 	}
 
 	@Test
@@ -1308,10 +1322,11 @@ public void testStopOnConflictCommitAndContinue() throws Exception {
 		git.rebase().setOperation(Operation.SKIP).call();
 
 		ObjectId headId = db.resolve(Constants.HEAD);
-		RevWalk rw = new RevWalk(db);
-		RevCommit rc = rw.parseCommit(headId);
-		RevCommit parent = rw.parseCommit(rc.getParent(0));
-		assertEquals("A different commit message", parent.getFullMessage());
+		try (RevWalk rw = new RevWalk(db)) {
+			RevCommit rc = rw.parseCommit(headId);
+			RevCommit parent = rw.parseCommit(rc.getParent(0));
+			assertEquals("A different commit message", parent.getFullMessage());
+		}
 	}
 
 	private RevCommit writeFileAndCommit(String fileName, String commitMessage,
@@ -1420,9 +1435,10 @@ public void testStopOnConflictFileCreationAndDeletion() throws Exception {
 		res = git.rebase().setOperation(Operation.ABORT).call();
 		assertEquals(res.getStatus(), Status.ABORTED);
 		assertEquals("refs/heads/topic", db.getFullBranch());
-		RevWalk rw = new RevWalk(db);
-		assertEquals(conflicting, rw.parseCommit(db.resolve(Constants.HEAD)));
-		assertEquals(RepositoryState.SAFE, db.getRepositoryState());
+		try (RevWalk rw = new RevWalk(db)) {
+			assertEquals(conflicting, rw.parseCommit(db.resolve(Constants.HEAD)));
+			assertEquals(RepositoryState.SAFE, db.getRepositoryState());
+		}
 
 		// rebase- dir in .git must be deleted
 		assertFalse(new File(db.getDirectory(), "rebase-merge").exists());
@@ -2286,14 +2302,15 @@ public String modifyCommitMessage(String commit) {
 		assertEquals(RebaseResult.Status.OK, res2.getStatus());
 
 		ObjectId headId = db.resolve(Constants.HEAD);
-		RevWalk rw = new RevWalk(db);
-		RevCommit rc = rw.parseCommit(headId);
+		try (RevWalk rw = new RevWalk(db)) {
+			RevCommit rc = rw.parseCommit(headId);
 
-		ObjectId head1Id = db.resolve(Constants.HEAD + "~1");
-		RevCommit rc1 = rw.parseCommit(head1Id);
+			ObjectId head1Id = db.resolve(Constants.HEAD + "~1");
+			RevCommit rc1 = rw.parseCommit(head1Id);
 
-		assertEquals(rc.getFullMessage(), c4.getFullMessage());
-		assertEquals(rc1.getFullMessage(), c2.getFullMessage());
+			assertEquals(rc.getFullMessage(), c4.getFullMessage());
+			assertEquals(rc1.getFullMessage(), c2.getFullMessage());
+		}
 	}
 
 	@Test
@@ -2643,15 +2660,16 @@ public String modifyCommitMessage(String commit) {
 					}
 				}).call();
 
-		RevWalk walk = new RevWalk(db);
-		ObjectId headId = db.resolve(Constants.HEAD);
-		RevCommit headCommit = walk.parseCommit(headId);
-		assertEquals(headCommit.getFullMessage(),
-				"update file2 on master\nnew line");
+		try (RevWalk walk = new RevWalk(db)) {
+			ObjectId headId = db.resolve(Constants.HEAD);
+			RevCommit headCommit = walk.parseCommit(headId);
+			assertEquals(headCommit.getFullMessage(),
+					"update file2 on master\nnew line");
 
-		ObjectId head2Id = db.resolve(Constants.HEAD + "^1");
-		RevCommit head1Commit = walk.parseCommit(head2Id);
-		assertEquals("changed", head1Commit.getFullMessage());
+			ObjectId head2Id = db.resolve(Constants.HEAD + "^1");
+			RevCommit head1Commit = walk.parseCommit(head2Id);
+			assertEquals("changed", head1Commit.getFullMessage());
+		}
 	}
 
 	@Test
@@ -2722,17 +2740,18 @@ public String modifyCommitMessage(String commit) {
 					}
 				}).call();
 
-		RevWalk walk = new RevWalk(db);
-		ObjectId headId = db.resolve(Constants.HEAD);
-		RevCommit headCommit = walk.parseCommit(headId);
-		assertEquals(headCommit.getFullMessage(),
-				"update file2 on master\nnew line");
+		try (RevWalk walk = new RevWalk(db)) {
+			ObjectId headId = db.resolve(Constants.HEAD);
+			RevCommit headCommit = walk.parseCommit(headId);
+			assertEquals(headCommit.getFullMessage(),
+					"update file2 on master\nnew line");
 
-		ObjectId head2Id = db.resolve(Constants.HEAD + "^1");
-		RevCommit head1Commit = walk.parseCommit(head2Id);
-		assertEquals(
-				"Add file1\nnew line\nAdd file2\nnew line\nupdated file1 on master\nnew line",
-				head1Commit.getFullMessage());
+			ObjectId head2Id = db.resolve(Constants.HEAD + "^1");
+			RevCommit head1Commit = walk.parseCommit(head2Id);
+			assertEquals(
+					"Add file1\nnew line\nAdd file2\nnew line\nupdated file1 on master\nnew line",
+					head1Commit.getFullMessage());
+		}
 	}
 
 	@Test
@@ -2804,15 +2823,16 @@ public String modifyCommitMessage(String commit) {
 					}
 				}).call();
 
-		RevWalk walk = new RevWalk(db);
-		ObjectId headId = db.resolve(Constants.HEAD);
-		RevCommit headCommit = walk.parseCommit(headId);
-		assertEquals(headCommit.getFullMessage(),
-				"update file2 on master\nnew line");
+		try (RevWalk walk = new RevWalk(db)) {
+			ObjectId headId = db.resolve(Constants.HEAD);
+			RevCommit headCommit = walk.parseCommit(headId);
+			assertEquals(headCommit.getFullMessage(),
+					"update file2 on master\nnew line");
 
-		ObjectId head2Id = db.resolve(Constants.HEAD + "^1");
-		RevCommit head1Commit = walk.parseCommit(head2Id);
-		assertEquals("changed", head1Commit.getFullMessage());
+			ObjectId head2Id = db.resolve(Constants.HEAD + "^1");
+			RevCommit head1Commit = walk.parseCommit(head2Id);
+			assertEquals("changed", head1Commit.getFullMessage());
+		}
 	}
 
 	@Test
@@ -2855,16 +2875,17 @@ public String modifyCommitMessage(String commit) {
 					}
 				}).call();
 
-		RevWalk walk = new RevWalk(db);
-		ObjectId headId = db.resolve(Constants.HEAD);
-		RevCommit headCommit = walk.parseCommit(headId);
-		assertEquals("update file2 on master\nnew line",
-				headCommit.getFullMessage());
+		try (RevWalk walk = new RevWalk(db)) {
+			ObjectId headId = db.resolve(Constants.HEAD);
+			RevCommit headCommit = walk.parseCommit(headId);
+			assertEquals("update file2 on master\nnew line",
+					headCommit.getFullMessage());
 
-		ObjectId head1Id = db.resolve(Constants.HEAD + "^1");
-		RevCommit head1Commit = walk.parseCommit(head1Id);
-		assertEquals("Add file2\nnew line",
-				head1Commit.getFullMessage());
+			ObjectId head1Id = db.resolve(Constants.HEAD + "^1");
+			RevCommit head1Commit = walk.parseCommit(head1Id);
+			assertEquals("Add file2\nnew line",
+					head1Commit.getFullMessage());
+		}
 	}
 
 	@Test
@@ -2903,11 +2924,12 @@ public String modifyCommitMessage(String commit) {
 					}
 				}).call();
 
-		RevWalk walk = new RevWalk(db);
-		ObjectId headId = db.resolve(Constants.HEAD);
-		RevCommit headCommit = walk.parseCommit(headId);
-		assertEquals("Add file2",
-				headCommit.getFullMessage());
+		try (RevWalk walk = new RevWalk(db)) {
+			ObjectId headId = db.resolve(Constants.HEAD);
+			RevCommit headCommit = walk.parseCommit(headId);
+			assertEquals("Add file2",
+					headCommit.getFullMessage());
+		}
 	}
 
 	@Test(expected = InvalidRebaseStepException.class)
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/ResetCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/ResetCommandTest.java
index 66f25e8..40d8458 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/ResetCommandTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/ResetCommandTest.java
@@ -463,24 +463,24 @@ public void testHardResetOnTag() throws Exception {
 
 	@Test
 	public void testHardResetAfterSquashMerge() throws Exception {
-		Git g = new Git(db);
+		git = new Git(db);
 
 		writeTrashFile("file1", "file1");
-		g.add().addFilepattern("file1").call();
-		RevCommit first = g.commit().setMessage("initial commit").call();
+		git.add().addFilepattern("file1").call();
+		RevCommit first = git.commit().setMessage("initial commit").call();
 
 		assertTrue(new File(db.getWorkTree(), "file1").exists());
 		createBranch(first, "refs/heads/branch1");
 		checkoutBranch("refs/heads/branch1");
 
 		writeTrashFile("file2", "file2");
-		g.add().addFilepattern("file2").call();
-		g.commit().setMessage("second commit").call();
+		git.add().addFilepattern("file2").call();
+		git.commit().setMessage("second commit").call();
 		assertTrue(new File(db.getWorkTree(), "file2").exists());
 
 		checkoutBranch("refs/heads/master");
 
-		MergeResult result = g.merge()
+		MergeResult result = git.merge()
 				.include(db.exactRef("refs/heads/branch1"))
 				.setSquash(true)
 				.call();
@@ -489,7 +489,7 @@ public void testHardResetAfterSquashMerge() throws Exception {
 				result.getMergeStatus());
 		assertNotNull(db.readSquashCommitMsg());
 
-		assertSameAsHead(g.reset().setMode(ResetType.HARD)
+		assertSameAsHead(git.reset().setMode(ResetType.HARD)
 				.setRef(first.getName()).call());
 
 		assertNull(db.readSquashCommitMsg());
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/RevertCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/RevertCommandTest.java
index 060168c..ea63104 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/RevertCommandTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/RevertCommandTest.java
@@ -74,303 +74,309 @@ public class RevertCommandTest extends RepositoryTestCase {
 	@Test
 	public void testRevert() throws IOException, JGitInternalException,
 			GitAPIException {
-		Git git = new Git(db);
+		try (Git git = new Git(db)) {
+			writeTrashFile("a", "first line\nsec. line\nthird line\n");
+			git.add().addFilepattern("a").call();
+			git.commit().setMessage("create a").call();
 
-		writeTrashFile("a", "first line\nsec. line\nthird line\n");
-		git.add().addFilepattern("a").call();
-		git.commit().setMessage("create a").call();
+			writeTrashFile("b", "content\n");
+			git.add().addFilepattern("b").call();
+			git.commit().setMessage("create b").call();
 
-		writeTrashFile("b", "content\n");
-		git.add().addFilepattern("b").call();
-		git.commit().setMessage("create b").call();
+			writeTrashFile("a", "first line\nsec. line\nthird line\nfourth line\n");
+			git.add().addFilepattern("a").call();
+			git.commit().setMessage("enlarged a").call();
 
-		writeTrashFile("a", "first line\nsec. line\nthird line\nfourth line\n");
-		git.add().addFilepattern("a").call();
-		git.commit().setMessage("enlarged a").call();
+			writeTrashFile("a",
+					"first line\nsecond line\nthird line\nfourth line\n");
+			git.add().addFilepattern("a").call();
+			RevCommit fixingA = git.commit().setMessage("fixed a").call();
 
-		writeTrashFile("a",
-				"first line\nsecond line\nthird line\nfourth line\n");
-		git.add().addFilepattern("a").call();
-		RevCommit fixingA = git.commit().setMessage("fixed a").call();
+			writeTrashFile("b", "first line\n");
+			git.add().addFilepattern("b").call();
+			git.commit().setMessage("fixed b").call();
 
-		writeTrashFile("b", "first line\n");
-		git.add().addFilepattern("b").call();
-		git.commit().setMessage("fixed b").call();
+			git.revert().include(fixingA).call();
 
-		git.revert().include(fixingA).call();
+			assertEquals(RepositoryState.SAFE, db.getRepositoryState());
 
-		assertEquals(RepositoryState.SAFE, db.getRepositoryState());
+			assertTrue(new File(db.getWorkTree(), "b").exists());
+			checkFile(new File(db.getWorkTree(), "a"),
+					"first line\nsec. line\nthird line\nfourth line\n");
+			Iterator<RevCommit> history = git.log().call().iterator();
+			RevCommit revertCommit = history.next();
+			String expectedMessage = "Revert \"fixed a\"\n\n"
+					+ "This reverts commit " + fixingA.getId().getName() + ".\n";
+			assertEquals(expectedMessage, revertCommit.getFullMessage());
+			assertEquals("fixed b", history.next().getFullMessage());
+			assertEquals("fixed a", history.next().getFullMessage());
+			assertEquals("enlarged a", history.next().getFullMessage());
+			assertEquals("create b", history.next().getFullMessage());
+			assertEquals("create a", history.next().getFullMessage());
+			assertFalse(history.hasNext());
 
-		assertTrue(new File(db.getWorkTree(), "b").exists());
-		checkFile(new File(db.getWorkTree(), "a"),
-				"first line\nsec. line\nthird line\nfourth line\n");
-		Iterator<RevCommit> history = git.log().call().iterator();
-		RevCommit revertCommit = history.next();
-		String expectedMessage = "Revert \"fixed a\"\n\n"
-				+ "This reverts commit " + fixingA.getId().getName() + ".\n";
-		assertEquals(expectedMessage, revertCommit.getFullMessage());
-		assertEquals("fixed b", history.next().getFullMessage());
-		assertEquals("fixed a", history.next().getFullMessage());
-		assertEquals("enlarged a", history.next().getFullMessage());
-		assertEquals("create b", history.next().getFullMessage());
-		assertEquals("create a", history.next().getFullMessage());
-		assertFalse(history.hasNext());
-
-		ReflogReader reader = db.getReflogReader(Constants.HEAD);
-		assertTrue(reader.getLastEntry().getComment()
-				.startsWith("revert: Revert \""));
-		reader = db.getReflogReader(db.getBranch());
-		assertTrue(reader.getLastEntry().getComment()
-				.startsWith("revert: Revert \""));
+			ReflogReader reader = db.getReflogReader(Constants.HEAD);
+			assertTrue(reader.getLastEntry().getComment()
+					.startsWith("revert: Revert \""));
+			reader = db.getReflogReader(db.getBranch());
+			assertTrue(reader.getLastEntry().getComment()
+					.startsWith("revert: Revert \""));
+		}
 
 	}
 
 	@Test
 	public void testRevertMultiple() throws IOException, JGitInternalException,
 			GitAPIException {
-		Git git = new Git(db);
+		try (Git git = new Git(db)) {
+			writeTrashFile("a", "first\n");
+			git.add().addFilepattern("a").call();
+			git.commit().setMessage("add first").call();
 
-		writeTrashFile("a", "first\n");
-		git.add().addFilepattern("a").call();
-		git.commit().setMessage("add first").call();
+			writeTrashFile("a", "first\nsecond\n");
+			git.add().addFilepattern("a").call();
+			RevCommit secondCommit = git.commit().setMessage("add second").call();
 
-		writeTrashFile("a", "first\nsecond\n");
-		git.add().addFilepattern("a").call();
-		RevCommit secondCommit = git.commit().setMessage("add second").call();
+			writeTrashFile("a", "first\nsecond\nthird\n");
+			git.add().addFilepattern("a").call();
+			RevCommit thirdCommit = git.commit().setMessage("add third").call();
 
-		writeTrashFile("a", "first\nsecond\nthird\n");
-		git.add().addFilepattern("a").call();
-		RevCommit thirdCommit = git.commit().setMessage("add third").call();
+			git.revert().include(thirdCommit).include(secondCommit).call();
 
-		git.revert().include(thirdCommit).include(secondCommit).call();
+			assertEquals(RepositoryState.SAFE, db.getRepositoryState());
 
-		assertEquals(RepositoryState.SAFE, db.getRepositoryState());
+			checkFile(new File(db.getWorkTree(), "a"), "first\n");
+			Iterator<RevCommit> history = git.log().call().iterator();
+			RevCommit revertCommit = history.next();
+			String expectedMessage = "Revert \"add second\"\n\n"
+					+ "This reverts commit "
+					+ secondCommit.getId().getName() + ".\n";
+			assertEquals(expectedMessage, revertCommit.getFullMessage());
+			revertCommit = history.next();
+			expectedMessage = "Revert \"add third\"\n\n"
+					+ "This reverts commit " + thirdCommit.getId().getName()
+					+ ".\n";
+			assertEquals(expectedMessage, revertCommit.getFullMessage());
+			assertEquals("add third", history.next().getFullMessage());
+			assertEquals("add second", history.next().getFullMessage());
+			assertEquals("add first", history.next().getFullMessage());
+			assertFalse(history.hasNext());
 
-		checkFile(new File(db.getWorkTree(), "a"), "first\n");
-		Iterator<RevCommit> history = git.log().call().iterator();
-		RevCommit revertCommit = history.next();
-		String expectedMessage = "Revert \"add second\"\n\n"
-				+ "This reverts commit "
-				+ secondCommit.getId().getName() + ".\n";
-		assertEquals(expectedMessage, revertCommit.getFullMessage());
-		revertCommit = history.next();
-		expectedMessage = "Revert \"add third\"\n\n"
-				+ "This reverts commit " + thirdCommit.getId().getName()
-				+ ".\n";
-		assertEquals(expectedMessage, revertCommit.getFullMessage());
-		assertEquals("add third", history.next().getFullMessage());
-		assertEquals("add second", history.next().getFullMessage());
-		assertEquals("add first", history.next().getFullMessage());
-		assertFalse(history.hasNext());
-
-		ReflogReader reader = db.getReflogReader(Constants.HEAD);
-		assertTrue(reader.getLastEntry().getComment()
-				.startsWith("revert: Revert \""));
-		reader = db.getReflogReader(db.getBranch());
-		assertTrue(reader.getLastEntry().getComment()
-				.startsWith("revert: Revert \""));
+			ReflogReader reader = db.getReflogReader(Constants.HEAD);
+			assertTrue(reader.getLastEntry().getComment()
+					.startsWith("revert: Revert \""));
+			reader = db.getReflogReader(db.getBranch());
+			assertTrue(reader.getLastEntry().getComment()
+					.startsWith("revert: Revert \""));
+		}
 
 	}
 
 	@Test
 	public void testRevertMultipleWithFail() throws IOException,
 			JGitInternalException, GitAPIException {
-		Git git = new Git(db);
+		try (Git git = new Git(db)) {
+			writeTrashFile("a", "first\n");
+			git.add().addFilepattern("a").call();
+			git.commit().setMessage("add first").call();
 
-		writeTrashFile("a", "first\n");
-		git.add().addFilepattern("a").call();
-		git.commit().setMessage("add first").call();
+			writeTrashFile("a", "first\nsecond\n");
+			git.add().addFilepattern("a").call();
+			RevCommit secondCommit = git.commit().setMessage("add second").call();
 
-		writeTrashFile("a", "first\nsecond\n");
-		git.add().addFilepattern("a").call();
-		RevCommit secondCommit = git.commit().setMessage("add second").call();
+			writeTrashFile("a", "first\nsecond\nthird\n");
+			git.add().addFilepattern("a").call();
+			git.commit().setMessage("add third").call();
 
-		writeTrashFile("a", "first\nsecond\nthird\n");
-		git.add().addFilepattern("a").call();
-		git.commit().setMessage("add third").call();
+			writeTrashFile("a", "first\nsecond\nthird\nfourth\n");
+			git.add().addFilepattern("a").call();
+			RevCommit fourthCommit = git.commit().setMessage("add fourth").call();
 
-		writeTrashFile("a", "first\nsecond\nthird\nfourth\n");
-		git.add().addFilepattern("a").call();
-		RevCommit fourthCommit = git.commit().setMessage("add fourth").call();
+			git.revert().include(fourthCommit).include(secondCommit).call();
 
-		git.revert().include(fourthCommit).include(secondCommit).call();
+			// not SAFE because it failed
+			assertEquals(RepositoryState.REVERTING, db.getRepositoryState());
 
-		// not SAFE because it failed
-		assertEquals(RepositoryState.REVERTING, db.getRepositoryState());
+			checkFile(new File(db.getWorkTree(), "a"), "first\n"
+					+ "<<<<<<< master\n" + "second\n" + "third\n" + "=======\n"
+					+ ">>>>>>> " + secondCommit.getId().abbreviate(7).name()
+					+ " add second\n");
+			Iterator<RevCommit> history = git.log().call().iterator();
+			RevCommit revertCommit = history.next();
+			String expectedMessage = "Revert \"add fourth\"\n\n"
+					+ "This reverts commit " + fourthCommit.getId().getName()
+					+ ".\n";
+			assertEquals(expectedMessage, revertCommit.getFullMessage());
+			assertEquals("add fourth", history.next().getFullMessage());
+			assertEquals("add third", history.next().getFullMessage());
+			assertEquals("add second", history.next().getFullMessage());
+			assertEquals("add first", history.next().getFullMessage());
+			assertFalse(history.hasNext());
 
-		checkFile(new File(db.getWorkTree(), "a"), "first\n"
-				+ "<<<<<<< master\n" + "second\n" + "third\n" + "=======\n"
-				+ ">>>>>>> " + secondCommit.getId().abbreviate(7).name()
-				+ " add second\n");
-		Iterator<RevCommit> history = git.log().call().iterator();
-		RevCommit revertCommit = history.next();
-		String expectedMessage = "Revert \"add fourth\"\n\n"
-				+ "This reverts commit " + fourthCommit.getId().getName()
-				+ ".\n";
-		assertEquals(expectedMessage, revertCommit.getFullMessage());
-		assertEquals("add fourth", history.next().getFullMessage());
-		assertEquals("add third", history.next().getFullMessage());
-		assertEquals("add second", history.next().getFullMessage());
-		assertEquals("add first", history.next().getFullMessage());
-		assertFalse(history.hasNext());
-
-		ReflogReader reader = db.getReflogReader(Constants.HEAD);
-		assertTrue(reader.getLastEntry().getComment()
-				.startsWith("revert: Revert \""));
-		reader = db.getReflogReader(db.getBranch());
-		assertTrue(reader.getLastEntry().getComment()
-				.startsWith("revert: Revert \""));
+			ReflogReader reader = db.getReflogReader(Constants.HEAD);
+			assertTrue(reader.getLastEntry().getComment()
+					.startsWith("revert: Revert \""));
+			reader = db.getReflogReader(db.getBranch());
+			assertTrue(reader.getLastEntry().getComment()
+					.startsWith("revert: Revert \""));
+		}
 
 	}
 
 	@Test
 	public void testRevertDirtyIndex() throws Exception {
-		Git git = new Git(db);
-		RevCommit sideCommit = prepareRevert(git);
+		try (Git git = new Git(db)) {
+			RevCommit sideCommit = prepareRevert(git);
 
-		// modify and add file a
-		writeTrashFile("a", "a(modified)");
-		git.add().addFilepattern("a").call();
-		// do not commit
+			// modify and add file a
+			writeTrashFile("a", "a(modified)");
+			git.add().addFilepattern("a").call();
+			// do not commit
 
-		doRevertAndCheckResult(git, sideCommit,
-				MergeFailureReason.DIRTY_INDEX);
+			doRevertAndCheckResult(git, sideCommit,
+					MergeFailureReason.DIRTY_INDEX);
+		}
 }
 
 	@Test
 	public void testRevertDirtyWorktree() throws Exception {
-		Git git = new Git(db);
-		RevCommit sideCommit = prepareRevert(git);
+		try (Git git = new Git(db)) {
+			RevCommit sideCommit = prepareRevert(git);
 
-		// modify file a
-		writeTrashFile("a", "a(modified)");
-		// do not add and commit
+			// modify file a
+			writeTrashFile("a", "a(modified)");
+			// do not add and commit
 
-		doRevertAndCheckResult(git, sideCommit,
-				MergeFailureReason.DIRTY_WORKTREE);
+			doRevertAndCheckResult(git, sideCommit,
+					MergeFailureReason.DIRTY_WORKTREE);
+		}
 	}
 
 	@Test
 	public void testRevertConflictResolution() throws Exception {
-		Git git = new Git(db);
-		RevCommit sideCommit = prepareRevert(git);
+		try (Git git = new Git(db)) {
+			RevCommit sideCommit = prepareRevert(git);
 
-		RevertCommand revert = git.revert();
-		RevCommit newHead = revert.include(sideCommit.getId()).call();
-		assertNull(newHead);
-		MergeResult result = revert.getFailingResult();
-		assertEquals(MergeStatus.CONFLICTING, result.getMergeStatus());
-		assertTrue(new File(db.getDirectory(), Constants.MERGE_MSG).exists());
-		assertEquals("Revert \"" + sideCommit.getShortMessage()
-				+ "\"\n\nThis reverts commit " + sideCommit.getId().getName()
-				+ ".\n\nConflicts:\n\ta\n",
-				db.readMergeCommitMsg());
-		assertTrue(new File(db.getDirectory(), Constants.REVERT_HEAD)
-				.exists());
-		assertEquals(sideCommit.getId(), db.readRevertHead());
-		assertEquals(RepositoryState.REVERTING, db.getRepositoryState());
+			RevertCommand revert = git.revert();
+			RevCommit newHead = revert.include(sideCommit.getId()).call();
+			assertNull(newHead);
+			MergeResult result = revert.getFailingResult();
+			assertEquals(MergeStatus.CONFLICTING, result.getMergeStatus());
+			assertTrue(new File(db.getDirectory(), Constants.MERGE_MSG).exists());
+			assertEquals("Revert \"" + sideCommit.getShortMessage()
+					+ "\"\n\nThis reverts commit " + sideCommit.getId().getName()
+					+ ".\n\nConflicts:\n\ta\n",
+					db.readMergeCommitMsg());
+			assertTrue(new File(db.getDirectory(), Constants.REVERT_HEAD)
+					.exists());
+			assertEquals(sideCommit.getId(), db.readRevertHead());
+			assertEquals(RepositoryState.REVERTING, db.getRepositoryState());
 
-		// Resolve
-		writeTrashFile("a", "a");
-		git.add().addFilepattern("a").call();
+			// Resolve
+			writeTrashFile("a", "a");
+			git.add().addFilepattern("a").call();
 
-		assertEquals(RepositoryState.REVERTING_RESOLVED,
-				db.getRepositoryState());
+			assertEquals(RepositoryState.REVERTING_RESOLVED,
+					db.getRepositoryState());
 
-		git.commit().setOnly("a").setMessage("resolve").call();
+			git.commit().setOnly("a").setMessage("resolve").call();
 
-		assertEquals(RepositoryState.SAFE, db.getRepositoryState());
+			assertEquals(RepositoryState.SAFE, db.getRepositoryState());
+		}
 	}
 
 	@Test
 	public void testRevertkConflictReset() throws Exception {
-		Git git = new Git(db);
+		try (Git git = new Git(db)) {
+			RevCommit sideCommit = prepareRevert(git);
 
-		RevCommit sideCommit = prepareRevert(git);
+			RevertCommand revert = git.revert();
+			RevCommit newHead = revert.include(sideCommit.getId()).call();
+			assertNull(newHead);
+			MergeResult result = revert.getFailingResult();
 
-		RevertCommand revert = git.revert();
-		RevCommit newHead = revert.include(sideCommit.getId()).call();
-		assertNull(newHead);
-		MergeResult result = revert.getFailingResult();
+			assertEquals(MergeStatus.CONFLICTING, result.getMergeStatus());
+			assertEquals(RepositoryState.REVERTING, db.getRepositoryState());
+			assertTrue(new File(db.getDirectory(), Constants.REVERT_HEAD)
+					.exists());
 
-		assertEquals(MergeStatus.CONFLICTING, result.getMergeStatus());
-		assertEquals(RepositoryState.REVERTING, db.getRepositoryState());
-		assertTrue(new File(db.getDirectory(), Constants.REVERT_HEAD)
-				.exists());
+			git.reset().setMode(ResetType.MIXED).setRef("HEAD").call();
 
-		git.reset().setMode(ResetType.MIXED).setRef("HEAD").call();
-
-		assertEquals(RepositoryState.SAFE, db.getRepositoryState());
-		assertFalse(new File(db.getDirectory(), Constants.REVERT_HEAD)
-				.exists());
+			assertEquals(RepositoryState.SAFE, db.getRepositoryState());
+			assertFalse(new File(db.getDirectory(), Constants.REVERT_HEAD)
+					.exists());
+		}
 	}
 
 	@Test
 	public void testRevertOverExecutableChangeOnNonExectuableFileSystem()
 			throws Exception {
-		Git git = new Git(db);
-		File file = writeTrashFile("test.txt", "a");
-		assertNotNull(git.add().addFilepattern("test.txt").call());
-		assertNotNull(git.commit().setMessage("commit1").call());
+		try (Git git = new Git(db)) {
+			File file = writeTrashFile("test.txt", "a");
+			assertNotNull(git.add().addFilepattern("test.txt").call());
+			assertNotNull(git.commit().setMessage("commit1").call());
 
-		assertNotNull(git.checkout().setCreateBranch(true).setName("a").call());
+			assertNotNull(git.checkout().setCreateBranch(true).setName("a").call());
 
-		writeTrashFile("test.txt", "b");
-		assertNotNull(git.add().addFilepattern("test.txt").call());
-		RevCommit commit2 = git.commit().setMessage("commit2").call();
-		assertNotNull(commit2);
+			writeTrashFile("test.txt", "b");
+			assertNotNull(git.add().addFilepattern("test.txt").call());
+			RevCommit commit2 = git.commit().setMessage("commit2").call();
+			assertNotNull(commit2);
 
-		assertNotNull(git.checkout().setName(Constants.MASTER).call());
+			assertNotNull(git.checkout().setName(Constants.MASTER).call());
 
-		DirCache cache = db.lockDirCache();
-		cache.getEntry("test.txt").setFileMode(FileMode.EXECUTABLE_FILE);
-		cache.write();
-		assertTrue(cache.commit());
-		cache.unlock();
+			DirCache cache = db.lockDirCache();
+			cache.getEntry("test.txt").setFileMode(FileMode.EXECUTABLE_FILE);
+			cache.write();
+			assertTrue(cache.commit());
+			cache.unlock();
 
-		assertNotNull(git.commit().setMessage("commit3").call());
+			assertNotNull(git.commit().setMessage("commit3").call());
 
-		db.getFS().setExecute(file, false);
-		git.getRepository()
-				.getConfig()
-				.setBoolean(ConfigConstants.CONFIG_CORE_SECTION, null,
-						ConfigConstants.CONFIG_KEY_FILEMODE, false);
+			db.getFS().setExecute(file, false);
+			git.getRepository()
+					.getConfig()
+					.setBoolean(ConfigConstants.CONFIG_CORE_SECTION, null,
+							ConfigConstants.CONFIG_KEY_FILEMODE, false);
 
-		RevertCommand revert = git.revert();
-		RevCommit newHead = revert.include(commit2).call();
-		assertNotNull(newHead);
+			RevertCommand revert = git.revert();
+			RevCommit newHead = revert.include(commit2).call();
+			assertNotNull(newHead);
+		}
 	}
 
 	@Test
 	public void testRevertConflictMarkers() throws Exception {
-		Git git = new Git(db);
-		RevCommit sideCommit = prepareRevert(git);
+		try (Git git = new Git(db)) {
+			RevCommit sideCommit = prepareRevert(git);
 
-		RevertCommand revert = git.revert();
-		RevCommit newHead = revert.include(sideCommit.getId())
-				.call();
-		assertNull(newHead);
-		MergeResult result = revert.getFailingResult();
-		assertEquals(MergeStatus.CONFLICTING, result.getMergeStatus());
+			RevertCommand revert = git.revert();
+			RevCommit newHead = revert.include(sideCommit.getId())
+					.call();
+			assertNull(newHead);
+			MergeResult result = revert.getFailingResult();
+			assertEquals(MergeStatus.CONFLICTING, result.getMergeStatus());
 
-		String expected = "<<<<<<< master\na(latest)\n=======\na\n>>>>>>> ca96c31 second master\n";
-		checkFile(new File(db.getWorkTree(), "a"), expected);
+			String expected = "<<<<<<< master\na(latest)\n=======\na\n>>>>>>> ca96c31 second master\n";
+			checkFile(new File(db.getWorkTree(), "a"), expected);
+		}
 	}
 
 	@Test
 	public void testRevertOurCommitName() throws Exception {
-		Git git = new Git(db);
-		RevCommit sideCommit = prepareRevert(git);
+		try (Git git = new Git(db)) {
+			RevCommit sideCommit = prepareRevert(git);
 
-		RevertCommand revert = git.revert();
-		RevCommit newHead = revert.include(sideCommit.getId())
-				.setOurCommitName("custom name").call();
-		assertNull(newHead);
-		MergeResult result = revert.getFailingResult();
-		assertEquals(MergeStatus.CONFLICTING, result.getMergeStatus());
+			RevertCommand revert = git.revert();
+			RevCommit newHead = revert.include(sideCommit.getId())
+					.setOurCommitName("custom name").call();
+			assertNull(newHead);
+			MergeResult result = revert.getFailingResult();
+			assertEquals(MergeStatus.CONFLICTING, result.getMergeStatus());
 
-		String expected = "<<<<<<< custom name\na(latest)\n=======\na\n>>>>>>> ca96c31 second master\n";
-		checkFile(new File(db.getWorkTree(), "a"), expected);
+			String expected = "<<<<<<< custom name\na(latest)\n=======\na\n>>>>>>> ca96c31 second master\n";
+			checkFile(new File(db.getWorkTree(), "a"), expected);
+		}
 	}
 
 	private RevCommit prepareRevert(final Git git) throws Exception {
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/StatusCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/StatusCommandTest.java
index c70604e..f3ac65c 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/StatusCommandTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/StatusCommandTest.java
@@ -61,109 +61,111 @@ public class StatusCommandTest extends RepositoryTestCase {
 	@Test
 	public void testEmptyStatus() throws NoWorkTreeException,
 			GitAPIException {
-		Git git = new Git(db);
-
-		Status stat = git.status().call();
-		assertEquals(0, stat.getAdded().size());
-		assertEquals(0, stat.getChanged().size());
-		assertEquals(0, stat.getMissing().size());
-		assertEquals(0, stat.getModified().size());
-		assertEquals(0, stat.getRemoved().size());
-		assertEquals(0, stat.getUntracked().size());
+		try (Git git = new Git(db)) {
+			Status stat = git.status().call();
+			assertEquals(0, stat.getAdded().size());
+			assertEquals(0, stat.getChanged().size());
+			assertEquals(0, stat.getMissing().size());
+			assertEquals(0, stat.getModified().size());
+			assertEquals(0, stat.getRemoved().size());
+			assertEquals(0, stat.getUntracked().size());
+		}
 	}
 
 	@Test
 	public void testDifferentStates() throws IOException,
 			NoFilepatternException, GitAPIException {
-		Git git = new Git(db);
-		writeTrashFile("a", "content of a");
-		writeTrashFile("b", "content of b");
-		writeTrashFile("c", "content of c");
-		git.add().addFilepattern("a").addFilepattern("b").call();
-		Status stat = git.status().call();
-		assertEquals(Sets.of("a", "b"), stat.getAdded());
-		assertEquals(0, stat.getChanged().size());
-		assertEquals(0, stat.getMissing().size());
-		assertEquals(0, stat.getModified().size());
-		assertEquals(0, stat.getRemoved().size());
-		assertEquals(Sets.of("c"), stat.getUntracked());
-		git.commit().setMessage("initial").call();
+		try (Git git = new Git(db)) {
+			writeTrashFile("a", "content of a");
+			writeTrashFile("b", "content of b");
+			writeTrashFile("c", "content of c");
+			git.add().addFilepattern("a").addFilepattern("b").call();
+			Status stat = git.status().call();
+			assertEquals(Sets.of("a", "b"), stat.getAdded());
+			assertEquals(0, stat.getChanged().size());
+			assertEquals(0, stat.getMissing().size());
+			assertEquals(0, stat.getModified().size());
+			assertEquals(0, stat.getRemoved().size());
+			assertEquals(Sets.of("c"), stat.getUntracked());
+			git.commit().setMessage("initial").call();
 
-		writeTrashFile("a", "modified content of a");
-		writeTrashFile("b", "modified content of b");
-		writeTrashFile("d", "content of d");
-		git.add().addFilepattern("a").addFilepattern("d").call();
-		writeTrashFile("a", "again modified content of a");
-		stat = git.status().call();
-		assertEquals(Sets.of("d"), stat.getAdded());
-		assertEquals(Sets.of("a"), stat.getChanged());
-		assertEquals(0, stat.getMissing().size());
-		assertEquals(Sets.of("b", "a"), stat.getModified());
-		assertEquals(0, stat.getRemoved().size());
-		assertEquals(Sets.of("c"), stat.getUntracked());
-		git.add().addFilepattern(".").call();
-		git.commit().setMessage("second").call();
+			writeTrashFile("a", "modified content of a");
+			writeTrashFile("b", "modified content of b");
+			writeTrashFile("d", "content of d");
+			git.add().addFilepattern("a").addFilepattern("d").call();
+			writeTrashFile("a", "again modified content of a");
+			stat = git.status().call();
+			assertEquals(Sets.of("d"), stat.getAdded());
+			assertEquals(Sets.of("a"), stat.getChanged());
+			assertEquals(0, stat.getMissing().size());
+			assertEquals(Sets.of("b", "a"), stat.getModified());
+			assertEquals(0, stat.getRemoved().size());
+			assertEquals(Sets.of("c"), stat.getUntracked());
+			git.add().addFilepattern(".").call();
+			git.commit().setMessage("second").call();
 
-		stat = git.status().call();
-		assertEquals(0, stat.getAdded().size());
-		assertEquals(0, stat.getChanged().size());
-		assertEquals(0, stat.getMissing().size());
-		assertEquals(0, stat.getModified().size());
-		assertEquals(0, stat.getRemoved().size());
-		assertEquals(0, stat.getUntracked().size());
+			stat = git.status().call();
+			assertEquals(0, stat.getAdded().size());
+			assertEquals(0, stat.getChanged().size());
+			assertEquals(0, stat.getMissing().size());
+			assertEquals(0, stat.getModified().size());
+			assertEquals(0, stat.getRemoved().size());
+			assertEquals(0, stat.getUntracked().size());
 
-		deleteTrashFile("a");
-		assertFalse(new File(git.getRepository().getWorkTree(), "a").exists());
-		git.add().addFilepattern("a").setUpdate(true).call();
-		writeTrashFile("a", "recreated content of a");
-		stat = git.status().call();
-		assertEquals(0, stat.getAdded().size());
-		assertEquals(0, stat.getChanged().size());
-		assertEquals(0, stat.getMissing().size());
-		assertEquals(0, stat.getModified().size());
-		assertEquals(Sets.of("a"), stat.getRemoved());
-		assertEquals(Sets.of("a"), stat.getUntracked());
-		git.commit().setMessage("t").call();
+			deleteTrashFile("a");
+			assertFalse(new File(git.getRepository().getWorkTree(), "a").exists());
+			git.add().addFilepattern("a").setUpdate(true).call();
+			writeTrashFile("a", "recreated content of a");
+			stat = git.status().call();
+			assertEquals(0, stat.getAdded().size());
+			assertEquals(0, stat.getChanged().size());
+			assertEquals(0, stat.getMissing().size());
+			assertEquals(0, stat.getModified().size());
+			assertEquals(Sets.of("a"), stat.getRemoved());
+			assertEquals(Sets.of("a"), stat.getUntracked());
+			git.commit().setMessage("t").call();
 
-		writeTrashFile("sub/a", "sub-file");
-		stat = git.status().call();
-		assertEquals(1, stat.getUntrackedFolders().size());
-		assertTrue(stat.getUntrackedFolders().contains("sub"));
+			writeTrashFile("sub/a", "sub-file");
+			stat = git.status().call();
+			assertEquals(1, stat.getUntrackedFolders().size());
+			assertTrue(stat.getUntrackedFolders().contains("sub"));
+		}
 	}
 
 	@Test
 	public void testDifferentStatesWithPaths() throws IOException,
 			NoFilepatternException, GitAPIException {
-		Git git = new Git(db);
-		writeTrashFile("a", "content of a");
-		writeTrashFile("D/b", "content of b");
-		writeTrashFile("D/c", "content of c");
-		writeTrashFile("D/D/d", "content of d");
-		git.add().addFilepattern(".").call();
+		try (Git git = new Git(db)) {
+			writeTrashFile("a", "content of a");
+			writeTrashFile("D/b", "content of b");
+			writeTrashFile("D/c", "content of c");
+			writeTrashFile("D/D/d", "content of d");
+			git.add().addFilepattern(".").call();
 
-		writeTrashFile("a", "new content of a");
-		writeTrashFile("D/b", "new content of b");
-		writeTrashFile("D/D/d", "new content of d");
+			writeTrashFile("a", "new content of a");
+			writeTrashFile("D/b", "new content of b");
+			writeTrashFile("D/D/d", "new content of d");
 
 
-		// filter on an not existing path
-		Status stat = git.status().addPath("x").call();
-		assertEquals(0, stat.getModified().size());
+			// filter on an not existing path
+			Status stat = git.status().addPath("x").call();
+			assertEquals(0, stat.getModified().size());
 
-		// filter on an existing file
-		stat = git.status().addPath("a").call();
-		assertEquals(Sets.of("a"), stat.getModified());
+			// filter on an existing file
+			stat = git.status().addPath("a").call();
+			assertEquals(Sets.of("a"), stat.getModified());
 
-		// filter on an existing folder
-		stat = git.status().addPath("D").call();
-		assertEquals(Sets.of("D/b", "D/D/d"), stat.getModified());
+			// filter on an existing folder
+			stat = git.status().addPath("D").call();
+			assertEquals(Sets.of("D/b", "D/D/d"), stat.getModified());
 
-		// filter on an existing folder and file
-		stat = git.status().addPath("D/D").addPath("a").call();
-		assertEquals(Sets.of("a", "D/D/d"), stat.getModified());
+			// filter on an existing folder and file
+			stat = git.status().addPath("D/D").addPath("a").call();
+			assertEquals(Sets.of("a", "D/D/d"), stat.getModified());
 
-		// do not filter at all
-		stat = git.status().call();
-		assertEquals(Sets.of("a", "D/b", "D/D/d"), stat.getModified());
+			// do not filter at all
+			stat = git.status().call();
+			assertEquals(Sets.of("a", "D/b", "D/D/d"), stat.getModified());
+		}
 	}
 }
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/blame/BlameGeneratorTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/blame/BlameGeneratorTest.java
index 42909f0..fa9848b 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/blame/BlameGeneratorTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/blame/BlameGeneratorTest.java
@@ -58,141 +58,142 @@
 public class BlameGeneratorTest extends RepositoryTestCase {
 	@Test
 	public void testBoundLineDelete() throws Exception {
-		Git git = new Git(db);
+		try (Git git = new Git(db)) {
+			String[] content1 = new String[] { "first", "second" };
+			writeTrashFile("file.txt", join(content1));
+			git.add().addFilepattern("file.txt").call();
+			RevCommit c1 = git.commit().setMessage("create file").call();
 
-		String[] content1 = new String[] { "first", "second" };
-		writeTrashFile("file.txt", join(content1));
-		git.add().addFilepattern("file.txt").call();
-		RevCommit c1 = git.commit().setMessage("create file").call();
+			String[] content2 = new String[] { "third", "first", "second" };
+			writeTrashFile("file.txt", join(content2));
+			git.add().addFilepattern("file.txt").call();
+			RevCommit c2 = git.commit().setMessage("create file").call();
 
-		String[] content2 = new String[] { "third", "first", "second" };
-		writeTrashFile("file.txt", join(content2));
-		git.add().addFilepattern("file.txt").call();
-		RevCommit c2 = git.commit().setMessage("create file").call();
+			try (BlameGenerator generator = new BlameGenerator(db, "file.txt")) {
+				generator.push(null, db.resolve(Constants.HEAD));
+				assertEquals(3, generator.getResultContents().size());
 
-		try (BlameGenerator generator = new BlameGenerator(db, "file.txt")) {
-			generator.push(null, db.resolve(Constants.HEAD));
-			assertEquals(3, generator.getResultContents().size());
+				assertTrue(generator.next());
+				assertEquals(c2, generator.getSourceCommit());
+				assertEquals(1, generator.getRegionLength());
+				assertEquals(0, generator.getResultStart());
+				assertEquals(1, generator.getResultEnd());
+				assertEquals(0, generator.getSourceStart());
+				assertEquals(1, generator.getSourceEnd());
+				assertEquals("file.txt", generator.getSourcePath());
 
-			assertTrue(generator.next());
-			assertEquals(c2, generator.getSourceCommit());
-			assertEquals(1, generator.getRegionLength());
-			assertEquals(0, generator.getResultStart());
-			assertEquals(1, generator.getResultEnd());
-			assertEquals(0, generator.getSourceStart());
-			assertEquals(1, generator.getSourceEnd());
-			assertEquals("file.txt", generator.getSourcePath());
+				assertTrue(generator.next());
+				assertEquals(c1, generator.getSourceCommit());
+				assertEquals(2, generator.getRegionLength());
+				assertEquals(1, generator.getResultStart());
+				assertEquals(3, generator.getResultEnd());
+				assertEquals(0, generator.getSourceStart());
+				assertEquals(2, generator.getSourceEnd());
+				assertEquals("file.txt", generator.getSourcePath());
 
-			assertTrue(generator.next());
-			assertEquals(c1, generator.getSourceCommit());
-			assertEquals(2, generator.getRegionLength());
-			assertEquals(1, generator.getResultStart());
-			assertEquals(3, generator.getResultEnd());
-			assertEquals(0, generator.getSourceStart());
-			assertEquals(2, generator.getSourceEnd());
-			assertEquals("file.txt", generator.getSourcePath());
-
-			assertFalse(generator.next());
+				assertFalse(generator.next());
+			}
 		}
 	}
 
 	@Test
 	public void testRenamedBoundLineDelete() throws Exception {
-		Git git = new Git(db);
-		final String FILENAME_1 = "subdir/file1.txt";
-		final String FILENAME_2 = "subdir/file2.txt";
+		try (Git git = new Git(db)) {
+			final String FILENAME_1 = "subdir/file1.txt";
+			final String FILENAME_2 = "subdir/file2.txt";
 
-		String[] content1 = new String[] { "first", "second" };
-		writeTrashFile(FILENAME_1, join(content1));
-		git.add().addFilepattern(FILENAME_1).call();
-		RevCommit c1 = git.commit().setMessage("create file1").call();
+			String[] content1 = new String[] { "first", "second" };
+			writeTrashFile(FILENAME_1, join(content1));
+			git.add().addFilepattern(FILENAME_1).call();
+			RevCommit c1 = git.commit().setMessage("create file1").call();
 
-		// rename it
-		writeTrashFile(FILENAME_2, join(content1));
-		git.add().addFilepattern(FILENAME_2).call();
-		deleteTrashFile(FILENAME_1);
-		git.rm().addFilepattern(FILENAME_1).call();
-		git.commit().setMessage("rename file1.txt to file2.txt").call();
+			// rename it
+			writeTrashFile(FILENAME_2, join(content1));
+			git.add().addFilepattern(FILENAME_2).call();
+			deleteTrashFile(FILENAME_1);
+			git.rm().addFilepattern(FILENAME_1).call();
+			git.commit().setMessage("rename file1.txt to file2.txt").call();
 
-		// and change the new file
-		String[] content2 = new String[] { "third", "first", "second" };
-		writeTrashFile(FILENAME_2, join(content2));
-		git.add().addFilepattern(FILENAME_2).call();
-		RevCommit c2 = git.commit().setMessage("change file2").call();
+			// and change the new file
+			String[] content2 = new String[] { "third", "first", "second" };
+			writeTrashFile(FILENAME_2, join(content2));
+			git.add().addFilepattern(FILENAME_2).call();
+			RevCommit c2 = git.commit().setMessage("change file2").call();
 
-		try (BlameGenerator generator = new BlameGenerator(db, FILENAME_2)) {
-			generator.push(null, db.resolve(Constants.HEAD));
-			assertEquals(3, generator.getResultContents().size());
+			try (BlameGenerator generator = new BlameGenerator(db, FILENAME_2)) {
+				generator.push(null, db.resolve(Constants.HEAD));
+				assertEquals(3, generator.getResultContents().size());
 
-			assertTrue(generator.next());
-			assertEquals(c2, generator.getSourceCommit());
-			assertEquals(1, generator.getRegionLength());
-			assertEquals(0, generator.getResultStart());
-			assertEquals(1, generator.getResultEnd());
-			assertEquals(0, generator.getSourceStart());
-			assertEquals(1, generator.getSourceEnd());
-			assertEquals(FILENAME_2, generator.getSourcePath());
+				assertTrue(generator.next());
+				assertEquals(c2, generator.getSourceCommit());
+				assertEquals(1, generator.getRegionLength());
+				assertEquals(0, generator.getResultStart());
+				assertEquals(1, generator.getResultEnd());
+				assertEquals(0, generator.getSourceStart());
+				assertEquals(1, generator.getSourceEnd());
+				assertEquals(FILENAME_2, generator.getSourcePath());
 
-			assertTrue(generator.next());
-			assertEquals(c1, generator.getSourceCommit());
-			assertEquals(2, generator.getRegionLength());
-			assertEquals(1, generator.getResultStart());
-			assertEquals(3, generator.getResultEnd());
-			assertEquals(0, generator.getSourceStart());
-			assertEquals(2, generator.getSourceEnd());
-			assertEquals(FILENAME_1, generator.getSourcePath());
+				assertTrue(generator.next());
+				assertEquals(c1, generator.getSourceCommit());
+				assertEquals(2, generator.getRegionLength());
+				assertEquals(1, generator.getResultStart());
+				assertEquals(3, generator.getResultEnd());
+				assertEquals(0, generator.getSourceStart());
+				assertEquals(2, generator.getSourceEnd());
+				assertEquals(FILENAME_1, generator.getSourcePath());
 
-			assertFalse(generator.next());
-		}
+				assertFalse(generator.next());
+			}
 
-		// and test again with other BlameGenerator API:
-		try (BlameGenerator generator = new BlameGenerator(db, FILENAME_2)) {
-			generator.push(null, db.resolve(Constants.HEAD));
-			BlameResult result = generator.computeBlameResult();
+			// and test again with other BlameGenerator API:
+			try (BlameGenerator generator = new BlameGenerator(db, FILENAME_2)) {
+				generator.push(null, db.resolve(Constants.HEAD));
+				BlameResult result = generator.computeBlameResult();
 
-			assertEquals(3, result.getResultContents().size());
+				assertEquals(3, result.getResultContents().size());
 
-			assertEquals(c2, result.getSourceCommit(0));
-			assertEquals(FILENAME_2, result.getSourcePath(0));
+				assertEquals(c2, result.getSourceCommit(0));
+				assertEquals(FILENAME_2, result.getSourcePath(0));
 
-			assertEquals(c1, result.getSourceCommit(1));
-			assertEquals(FILENAME_1, result.getSourcePath(1));
+				assertEquals(c1, result.getSourceCommit(1));
+				assertEquals(FILENAME_1, result.getSourcePath(1));
 
-			assertEquals(c1, result.getSourceCommit(2));
-			assertEquals(FILENAME_1, result.getSourcePath(2));
+				assertEquals(c1, result.getSourceCommit(2));
+				assertEquals(FILENAME_1, result.getSourcePath(2));
+			}
 		}
 	}
 
 	@Test
 	public void testLinesAllDeletedShortenedWalk() throws Exception {
-		Git git = new Git(db);
+		try (Git git = new Git(db)) {
+			String[] content1 = new String[] { "first", "second", "third" };
 
-		String[] content1 = new String[] { "first", "second", "third" };
+			writeTrashFile("file.txt", join(content1));
+			git.add().addFilepattern("file.txt").call();
+			git.commit().setMessage("create file").call();
 
-		writeTrashFile("file.txt", join(content1));
-		git.add().addFilepattern("file.txt").call();
-		git.commit().setMessage("create file").call();
+			String[] content2 = new String[] { "" };
 
-		String[] content2 = new String[] { "" };
+			writeTrashFile("file.txt", join(content2));
+			git.add().addFilepattern("file.txt").call();
+			git.commit().setMessage("create file").call();
 
-		writeTrashFile("file.txt", join(content2));
-		git.add().addFilepattern("file.txt").call();
-		git.commit().setMessage("create file").call();
+			writeTrashFile("file.txt", join(content1));
+			git.add().addFilepattern("file.txt").call();
+			RevCommit c3 = git.commit().setMessage("create file").call();
 
-		writeTrashFile("file.txt", join(content1));
-		git.add().addFilepattern("file.txt").call();
-		RevCommit c3 = git.commit().setMessage("create file").call();
+			try (BlameGenerator generator = new BlameGenerator(db, "file.txt")) {
+				generator.push(null, db.resolve(Constants.HEAD));
+				assertEquals(3, generator.getResultContents().size());
 
-		try (BlameGenerator generator = new BlameGenerator(db, "file.txt")) {
-			generator.push(null, db.resolve(Constants.HEAD));
-			assertEquals(3, generator.getResultContents().size());
+				assertTrue(generator.next());
+				assertEquals(c3, generator.getSourceCommit());
+				assertEquals(0, generator.getResultStart());
+				assertEquals(3, generator.getResultEnd());
 
-			assertTrue(generator.next());
-			assertEquals(c3, generator.getSourceCommit());
-			assertEquals(0, generator.getResultStart());
-			assertEquals(3, generator.getResultEnd());
-
-			assertFalse(generator.next());
+				assertFalse(generator.next());
+			}
 		}
 	}
 
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/attributes/AttributesHandlerTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/attributes/AttributesHandlerTest.java
new file mode 100644
index 0000000..ca456b3
--- /dev/null
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/attributes/AttributesHandlerTest.java
@@ -0,0 +1,339 @@
+/*
+ * 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.attributes;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+
+import org.eclipse.jgit.junit.RepositoryTestCase;
+import org.eclipse.jgit.lib.ConfigConstants;
+import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.lib.FileMode;
+import org.eclipse.jgit.storage.file.FileBasedConfig;
+import org.eclipse.jgit.treewalk.FileTreeIterator;
+import org.eclipse.jgit.treewalk.TreeWalk;
+import org.junit.Test;
+
+/**
+ * Tests {@link AttributesHandler}
+ */
+public class AttributesHandlerTest extends RepositoryTestCase {
+	private static final FileMode D = FileMode.TREE;
+
+	private static final FileMode F = FileMode.REGULAR_FILE;
+
+	private TreeWalk walk;
+
+	@Test
+	public void testExpandNonMacro1() throws Exception {
+		setupRepo(null, null, null, "*.txt text");
+
+		walk = beginWalk();
+		assertIteration(D, "sub");
+		assertIteration(F, "sub/.gitattributes");
+		assertIteration(F, "sub/a.txt", attrs("text"));
+		endWalk();
+	}
+
+	@Test
+	public void testExpandNonMacro2() throws Exception {
+		setupRepo(null, null, null, "*.txt -text");
+
+		walk = beginWalk();
+		assertIteration(D, "sub");
+		assertIteration(F, "sub/.gitattributes");
+		assertIteration(F, "sub/a.txt", attrs("-text"));
+		endWalk();
+	}
+
+	@Test
+	public void testExpandNonMacro3() throws Exception {
+		setupRepo(null, null, null, "*.txt !text");
+
+		walk = beginWalk();
+		assertIteration(D, "sub");
+		assertIteration(F, "sub/.gitattributes");
+		assertIteration(F, "sub/a.txt", attrs(""));
+		endWalk();
+	}
+
+	@Test
+	public void testExpandNonMacro4() throws Exception {
+		setupRepo(null, null, null, "*.txt text=auto");
+
+		walk = beginWalk();
+		assertIteration(D, "sub");
+		assertIteration(F, "sub/.gitattributes");
+		assertIteration(F, "sub/a.txt", attrs("text=auto"));
+		endWalk();
+	}
+
+	@Test
+	public void testExpandBuiltInMacro1() throws Exception {
+		setupRepo(null, null, null, "*.txt binary");
+
+		walk = beginWalk();
+		assertIteration(D, "sub");
+		assertIteration(F, "sub/.gitattributes");
+		assertIteration(F, "sub/a.txt", attrs("binary -diff -merge -text"));
+		endWalk();
+	}
+
+	@Test
+	public void testExpandBuiltInMacro2() throws Exception {
+		setupRepo(null, null, null, "*.txt -binary");
+
+		walk = beginWalk();
+		assertIteration(D, "sub");
+		assertIteration(F, "sub/.gitattributes");
+		assertIteration(F, "sub/a.txt", attrs("-binary diff merge text"));
+		endWalk();
+	}
+
+	@Test
+	public void testExpandBuiltInMacro3() throws Exception {
+		setupRepo(null, null, null, "*.txt !binary");
+
+		walk = beginWalk();
+		assertIteration(D, "sub");
+		assertIteration(F, "sub/.gitattributes");
+		assertIteration(F, "sub/a.txt", attrs(""));
+		endWalk();
+	}
+
+	@Test
+	public void testCustomGlobalMacro1() throws Exception {
+		setupRepo(
+				"[attr]foo a -b !c d=e", null, null, "*.txt foo");
+
+		walk = beginWalk();
+		assertIteration(D, "sub");
+		assertIteration(F, "sub/.gitattributes");
+		assertIteration(F, "sub/a.txt", attrs("foo a -b d=e"));
+		endWalk();
+	}
+
+	@Test
+	public void testCustomGlobalMacro2() throws Exception {
+		setupRepo("[attr]foo a -b !c d=e", null, null, "*.txt -foo");
+
+		walk = beginWalk();
+		assertIteration(D, "sub");
+		assertIteration(F, "sub/.gitattributes");
+		assertIteration(F, "sub/a.txt", attrs("-foo -a b d=e"));
+		endWalk();
+	}
+
+	@Test
+	public void testCustomGlobalMacro3() throws Exception {
+		setupRepo("[attr]foo a -b !c d=e", null, null, "*.txt !foo");
+
+		walk = beginWalk();
+		assertIteration(D, "sub");
+		assertIteration(F, "sub/.gitattributes");
+		assertIteration(F, "sub/a.txt", attrs(""));
+		endWalk();
+	}
+
+	@Test
+	public void testCustomGlobalMacro4() throws Exception {
+		setupRepo("[attr]foo a -b !c d=e", null, null, "*.txt foo=bar");
+
+		walk = beginWalk();
+		assertIteration(D, "sub");
+		assertIteration(F, "sub/.gitattributes");
+		assertIteration(F, "sub/a.txt", attrs("foo=bar a -b d=bar"));
+		endWalk();
+	}
+
+	@Test
+	public void testInfoOverridesGlobal() throws Exception {
+		setupRepo("[attr]foo bar1",
+				"[attr]foo bar2", null, "*.txt foo");
+
+		walk = beginWalk();
+		assertIteration(D, "sub");
+		assertIteration(F, "sub/.gitattributes");
+		assertIteration(F, "sub/a.txt", attrs("foo bar2"));
+		endWalk();
+	}
+
+	@Test
+	public void testWorkDirRootOverridesGlobal() throws Exception {
+		setupRepo("[attr]foo bar1",
+				null,
+				"[attr]foo bar3", "*.txt foo");
+
+		walk = beginWalk();
+		assertIteration(F, ".gitattributes");
+		assertIteration(D, "sub");
+		assertIteration(F, "sub/.gitattributes");
+		assertIteration(F, "sub/a.txt", attrs("foo bar3"));
+		endWalk();
+	}
+
+	@Test
+	public void testInfoOverridesWorkDirRoot() throws Exception {
+		setupRepo("[attr]foo bar1",
+				"[attr]foo bar2", "[attr]foo bar3", "*.txt foo");
+
+		walk = beginWalk();
+		assertIteration(F, ".gitattributes");
+		assertIteration(D, "sub");
+		assertIteration(F, "sub/.gitattributes");
+		assertIteration(F, "sub/a.txt", attrs("foo bar2"));
+		endWalk();
+	}
+
+	@Test
+	public void testRecursiveMacro() throws Exception {
+		setupRepo(
+				"[attr]foo x bar -foo",
+				null, null, "*.txt foo");
+
+		walk = beginWalk();
+		assertIteration(D, "sub");
+		assertIteration(F, "sub/.gitattributes");
+		assertIteration(F, "sub/a.txt", attrs("foo x bar"));
+		endWalk();
+	}
+
+	@Test
+	public void testCyclicMacros() throws Exception {
+		setupRepo(
+				"[attr]foo x -bar\n[attr]bar y -foo", null, null, "*.txt foo");
+
+		walk = beginWalk();
+		assertIteration(D, "sub");
+		assertIteration(F, "sub/.gitattributes");
+		assertIteration(F, "sub/a.txt", attrs("foo x -bar -y"));
+		endWalk();
+	}
+
+	private static Collection<Attribute> attrs(String s) {
+		return new AttributesRule("*", s).getAttributes();
+	}
+
+	private void assertIteration(FileMode type, String pathName)
+			throws IOException {
+		assertIteration(type, pathName, Collections.<Attribute> emptyList());
+	}
+
+	private void assertIteration(FileMode type, String pathName,
+			Collection<Attribute> expectedAttrs) throws IOException {
+		assertTrue("walk has entry", walk.next());
+		assertEquals(pathName, walk.getPathString());
+		assertEquals(type, walk.getFileMode(0));
+
+		if (expectedAttrs != null) {
+			assertEquals(new ArrayList<>(expectedAttrs),
+					new ArrayList<>(walk.getAttributes().getAll()));
+		}
+
+		if (D.equals(type))
+			walk.enterSubtree();
+	}
+
+	/**
+	 * @param globalAttributesContent
+	 * @param infoAttributesContent
+	 * @param rootAttributesContent
+	 * @param subDirAttributesContent
+	 * @throws Exception
+	 *             Setup a repo with .gitattributes files and a test file
+	 *             sub/a.txt
+	 */
+	private void setupRepo(
+			String globalAttributesContent,
+			String infoAttributesContent, String rootAttributesContent, String subDirAttributesContent)
+					throws Exception {
+		FileBasedConfig config = db.getConfig();
+		if (globalAttributesContent != null) {
+			File f = new File(db.getDirectory(), "global/attributes");
+			write(f, globalAttributesContent);
+			config.setString(ConfigConstants.CONFIG_CORE_SECTION, null,
+					ConfigConstants.CONFIG_KEY_ATTRIBUTESFILE,
+					f.getAbsolutePath());
+
+		}
+		if (infoAttributesContent != null) {
+			File f = new File(db.getDirectory(), Constants.INFO_ATTRIBUTES);
+			write(f, infoAttributesContent);
+		}
+		config.save();
+
+		if (rootAttributesContent != null) {
+			writeAttributesFile(Constants.DOT_GIT_ATTRIBUTES,
+					rootAttributesContent);
+		}
+
+		if (subDirAttributesContent != null) {
+			writeAttributesFile("sub/" + Constants.DOT_GIT_ATTRIBUTES,
+					subDirAttributesContent);
+		}
+
+		writeTrashFile("sub/a.txt", "a");
+	}
+
+	private void writeAttributesFile(String name, String... rules)
+			throws IOException {
+		StringBuilder data = new StringBuilder();
+		for (String line : rules)
+			data.append(line + "\n");
+		writeTrashFile(name, data.toString());
+	}
+
+	private TreeWalk beginWalk() {
+		TreeWalk newWalk = new TreeWalk(db);
+		newWalk.addTree(new FileTreeIterator(db));
+		return newWalk;
+	}
+
+	private void endWalk() throws IOException {
+		assertFalse("Not all files tested", walk.next());
+	}
+}
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/attributes/AttributesMatcherTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/attributes/AttributesMatcherTest.java
index 9f82b8a..e8dd952 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/attributes/AttributesMatcherTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/attributes/AttributesMatcherTest.java
@@ -293,28 +293,28 @@ public void testNameOnlyMatches() {
 	public void testGetters() {
 		AttributesRule r = new AttributesRule("/pattern/", "");
 		assertFalse(r.isNameOnly());
-		assertTrue(r.dirOnly());
+		assertTrue(r.isDirOnly());
 		assertNotNull(r.getAttributes());
 		assertTrue(r.getAttributes().isEmpty());
 		assertEquals(r.getPattern(), "/pattern");
 
 		r = new AttributesRule("/patter?/", "");
 		assertFalse(r.isNameOnly());
-		assertTrue(r.dirOnly());
+		assertTrue(r.isDirOnly());
 		assertNotNull(r.getAttributes());
 		assertTrue(r.getAttributes().isEmpty());
 		assertEquals(r.getPattern(), "/patter?");
 
 		r = new AttributesRule("patt*", "");
 		assertTrue(r.isNameOnly());
-		assertFalse(r.dirOnly());
+		assertFalse(r.isDirOnly());
 		assertNotNull(r.getAttributes());
 		assertTrue(r.getAttributes().isEmpty());
 		assertEquals(r.getPattern(), "patt*");
 
 		r = new AttributesRule("pattern", "attribute1");
 		assertTrue(r.isNameOnly());
-		assertFalse(r.dirOnly());
+		assertFalse(r.isDirOnly());
 		assertNotNull(r.getAttributes());
 		assertFalse(r.getAttributes().isEmpty());
 		assertEquals(r.getAttributes().size(), 1);
@@ -322,28 +322,28 @@ public void testGetters() {
 
 		r = new AttributesRule("pattern", "attribute1 -attribute2");
 		assertTrue(r.isNameOnly());
-		assertFalse(r.dirOnly());
+		assertFalse(r.isDirOnly());
 		assertNotNull(r.getAttributes());
 		assertEquals(r.getAttributes().size(), 2);
 		assertEquals(r.getPattern(), "pattern");
 
 		r = new AttributesRule("pattern", "attribute1 \t-attribute2 \t");
 		assertTrue(r.isNameOnly());
-		assertFalse(r.dirOnly());
+		assertFalse(r.isDirOnly());
 		assertNotNull(r.getAttributes());
 		assertEquals(r.getAttributes().size(), 2);
 		assertEquals(r.getPattern(), "pattern");
 
 		r = new AttributesRule("pattern", "attribute1\t-attribute2\t");
 		assertTrue(r.isNameOnly());
-		assertFalse(r.dirOnly());
+		assertFalse(r.isDirOnly());
 		assertNotNull(r.getAttributes());
 		assertEquals(r.getAttributes().size(), 2);
 		assertEquals(r.getPattern(), "pattern");
 
 		r = new AttributesRule("pattern", "attribute1\t -attribute2\t ");
 		assertTrue(r.isNameOnly());
-		assertFalse(r.dirOnly());
+		assertFalse(r.isDirOnly());
 		assertNotNull(r.getAttributes());
 		assertEquals(r.getAttributes().size(), 2);
 		assertEquals(r.getPattern(), "pattern");
@@ -351,7 +351,7 @@ public void testGetters() {
 		r = new AttributesRule("pattern",
 				"attribute1 -attribute2  attribute3=value ");
 		assertTrue(r.isNameOnly());
-		assertFalse(r.dirOnly());
+		assertFalse(r.isDirOnly());
 		assertNotNull(r.getAttributes());
 		assertEquals(r.getAttributes().size(), 3);
 		assertEquals(r.getPattern(), "pattern");
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/attributes/AttributesNodeDirCacheIteratorTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/attributes/AttributesNodeDirCacheIteratorTest.java
index 0e595e6..7421e90 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/attributes/AttributesNodeDirCacheIteratorTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/attributes/AttributesNodeDirCacheIteratorTest.java
@@ -251,14 +251,17 @@ private void assertIteration(FileMode type, String pathName,
 	}
 
 	private void assertAttributesNode(String pathName,
-			AttributesNode attributesNode, List<Attribute> nodeAttrs) {
+			AttributesNode attributesNode, List<Attribute> nodeAttrs)
+					throws IOException {
 		if (attributesNode == null)
 			assertTrue(nodeAttrs == null || nodeAttrs.isEmpty());
 		else {
 
 			Attributes entryAttributes = new Attributes();
-			attributesNode.getAttributes(pathName,
-					false, entryAttributes);
+			new AttributesHandler(walk).mergeAttributes(attributesNode,
+					pathName,
+					false,
+					entryAttributes);
 
 			if (nodeAttrs != null && !nodeAttrs.isEmpty()) {
 				for (Attribute attribute : nodeAttrs) {
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/attributes/AttributesNodeTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/attributes/AttributesNodeTest.java
index d478a7c..ec2370e 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/attributes/AttributesNodeTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/attributes/AttributesNodeTest.java
@@ -50,6 +50,9 @@
 import java.io.IOException;
 import java.io.InputStream;
 
+import org.eclipse.jgit.internal.storage.dfs.DfsRepositoryDescription;
+import org.eclipse.jgit.internal.storage.dfs.InMemoryRepository;
+import org.eclipse.jgit.treewalk.TreeWalk;
 import org.junit.After;
 import org.junit.Test;
 
@@ -57,6 +60,8 @@
  * Test {@link AttributesNode}
  */
 public class AttributesNodeTest {
+	private static final TreeWalk DUMMY_WALK = new TreeWalk(
+			new InMemoryRepository(new DfsRepositoryDescription("FooBar")));
 
 	private static final Attribute A_SET_ATTR = new Attribute("A", SET);
 
@@ -162,9 +167,10 @@ public void testTabSeparator() throws IOException {
 	}
 
 	private void assertAttribute(String path, AttributesNode node,
-			Attributes attrs) {
+			Attributes attrs) throws IOException {
 		Attributes attributes = new Attributes();
-		node.getAttributes(path, false, attributes);
+		new AttributesHandler(DUMMY_WALK).mergeAttributes(node, path, false,
+				attributes);
 		assertEquals(attrs, attributes);
 	}
 
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/attributes/AttributesNodeWorkingTreeIteratorTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/attributes/AttributesNodeWorkingTreeIteratorTest.java
index 4215ba2..b159cca 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/attributes/AttributesNodeWorkingTreeIteratorTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/attributes/AttributesNodeWorkingTreeIteratorTest.java
@@ -219,14 +219,16 @@ private void assertIteration(FileMode type, String pathName,
 	}
 
 	private void assertAttributesNode(String pathName,
-			AttributesNode attributesNode, List<Attribute> nodeAttrs) {
+			AttributesNode attributesNode, List<Attribute> nodeAttrs)
+					throws IOException {
 		if (attributesNode == null)
 			assertTrue(nodeAttrs == null || nodeAttrs.isEmpty());
 		else {
 
 			Attributes entryAttributes = new Attributes();
-			attributesNode.getAttributes(pathName,
-					false, entryAttributes);
+			new AttributesHandler(walk).mergeAttributes(attributesNode,
+					pathName, false,
+					entryAttributes);
 
 			if (nodeAttrs != null && !nodeAttrs.isEmpty()) {
 				for (Attribute attribute : nodeAttrs) {
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/diff/DiffEntryTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/diff/DiffEntryTest.java
index 5694e83..443c956 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/diff/DiffEntryTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/diff/DiffEntryTest.java
@@ -77,260 +77,268 @@ public class DiffEntryTest extends RepositoryTestCase {
 	public void shouldListAddedFileInInitialCommit() throws Exception {
 		// given
 		writeTrashFile("a.txt", "content");
-		Git git = new Git(db);
-		git.add().addFilepattern("a.txt").call();
-		RevCommit c = git.commit().setMessage("initial commit").call();
+		try (Git git = new Git(db);
+				TreeWalk walk = new TreeWalk(db)) {
+			git.add().addFilepattern("a.txt").call();
+			RevCommit c = git.commit().setMessage("initial commit").call();
 
-		// when
-		TreeWalk walk = new TreeWalk(db);
-		walk.addTree(new EmptyTreeIterator());
-		walk.addTree(c.getTree());
-		List<DiffEntry> result = DiffEntry.scan(walk);
+			// when
+			walk.addTree(new EmptyTreeIterator());
+			walk.addTree(c.getTree());
+			List<DiffEntry> result = DiffEntry.scan(walk);
 
-		// then
-		assertThat(result, notNullValue());
-		assertThat(Integer.valueOf(result.size()), is(Integer.valueOf(1)));
+			// then
+			assertThat(result, notNullValue());
+			assertThat(Integer.valueOf(result.size()), is(Integer.valueOf(1)));
 
-		DiffEntry entry = result.get(0);
-		assertThat(entry.getChangeType(), is(ChangeType.ADD));
-		assertThat(entry.getNewPath(), is("a.txt"));
-		assertThat(entry.getOldPath(), is(DEV_NULL));
+			DiffEntry entry = result.get(0);
+			assertThat(entry.getChangeType(), is(ChangeType.ADD));
+			assertThat(entry.getNewPath(), is("a.txt"));
+			assertThat(entry.getOldPath(), is(DEV_NULL));
+		}
 	}
 
 	@Test
 	public void shouldListAddedFileBetweenTwoCommits() throws Exception {
 		// given
-		Git git = new Git(db);
-		RevCommit c1 = git.commit().setMessage("initial commit").call();
-		writeTrashFile("a.txt", "content");
-		git.add().addFilepattern("a.txt").call();
-		RevCommit c2 = git.commit().setMessage("second commit").call();
+		try (Git git = new Git(db);
+				TreeWalk walk = new TreeWalk(db)) {
+			RevCommit c1 = git.commit().setMessage("initial commit").call();
+			writeTrashFile("a.txt", "content");
+			git.add().addFilepattern("a.txt").call();
+			RevCommit c2 = git.commit().setMessage("second commit").call();
 
-		// when
-		TreeWalk walk = new TreeWalk(db);
-		walk.addTree(c1.getTree());
-		walk.addTree(c2.getTree());
-		List<DiffEntry> result = DiffEntry.scan(walk);
+			// when
+			walk.addTree(c1.getTree());
+			walk.addTree(c2.getTree());
+			List<DiffEntry> result = DiffEntry.scan(walk);
 
-		// then
-		assertThat(result, notNullValue());
-		assertThat(Integer.valueOf(result.size()), is(Integer.valueOf(1)));
+			// then
+			assertThat(result, notNullValue());
+			assertThat(Integer.valueOf(result.size()), is(Integer.valueOf(1)));
 
-		DiffEntry entry = result.get(0);
-		assertThat(entry.getChangeType(), is(ChangeType.ADD));
-		assertThat(entry.getNewPath(), is("a.txt"));
-		assertThat(entry.getOldPath(), is(DEV_NULL));
+			DiffEntry entry = result.get(0);
+			assertThat(entry.getChangeType(), is(ChangeType.ADD));
+			assertThat(entry.getNewPath(), is("a.txt"));
+			assertThat(entry.getOldPath(), is(DEV_NULL));
+		}
 	}
 
 	@Test
 	public void shouldListModificationBetweenTwoCommits() throws Exception {
 		// given
-		Git git = new Git(db);
-		File file = writeTrashFile("a.txt", "content");
-		git.add().addFilepattern("a.txt").call();
-		RevCommit c1 = git.commit().setMessage("initial commit").call();
-		write(file, "new content");
-		RevCommit c2 = git.commit().setAll(true).setMessage("second commit")
-				.call();
+		try (Git git = new Git(db);
+				TreeWalk walk = new TreeWalk(db)) {
+			File file = writeTrashFile("a.txt", "content");
+			git.add().addFilepattern("a.txt").call();
+			RevCommit c1 = git.commit().setMessage("initial commit").call();
+			write(file, "new content");
+			RevCommit c2 = git.commit().setAll(true).setMessage("second commit")
+					.call();
 
-		// when
-		TreeWalk walk = new TreeWalk(db);
-		walk.addTree(c1.getTree());
-		walk.addTree(c2.getTree());
-		List<DiffEntry> result = DiffEntry.scan(walk);
+			// when
+			walk.addTree(c1.getTree());
+			walk.addTree(c2.getTree());
+			List<DiffEntry> result = DiffEntry.scan(walk);
 
-		// then
-		assertThat(result, notNullValue());
-		assertThat(Integer.valueOf(result.size()), is(Integer.valueOf(1)));
+			// then
+			assertThat(result, notNullValue());
+			assertThat(Integer.valueOf(result.size()), is(Integer.valueOf(1)));
 
-		DiffEntry entry = result.get(0);
-		assertThat(entry.getChangeType(), is(ChangeType.MODIFY));
-		assertThat(entry.getNewPath(), is("a.txt"));
+			DiffEntry entry = result.get(0);
+			assertThat(entry.getChangeType(), is(ChangeType.MODIFY));
+			assertThat(entry.getNewPath(), is("a.txt"));
+		}
 	}
 
 	@Test
 	public void shouldListDeletionBetweenTwoCommits() throws Exception {
 		// given
-		Git git = new Git(db);
-		File file = writeTrashFile("a.txt", "content");
-		git.add().addFilepattern("a.txt").call();
-		RevCommit c1 = git.commit().setMessage("initial commit").call();
-		delete(file);
-		RevCommit c2 = git.commit().setAll(true).setMessage("delete a.txt")
-				.call();
+		try (Git git = new Git(db);
+				TreeWalk walk = new TreeWalk(db)) {
+			File file = writeTrashFile("a.txt", "content");
+			git.add().addFilepattern("a.txt").call();
+			RevCommit c1 = git.commit().setMessage("initial commit").call();
+			delete(file);
+			RevCommit c2 = git.commit().setAll(true).setMessage("delete a.txt")
+					.call();
 
-		// when
-		TreeWalk walk = new TreeWalk(db);
-		walk.addTree(c1.getTree());
-		walk.addTree(c2.getTree());
-		List<DiffEntry> result = DiffEntry.scan(walk);
+			// when
+			walk.addTree(c1.getTree());
+			walk.addTree(c2.getTree());
+			List<DiffEntry> result = DiffEntry.scan(walk);
 
-		// then
-		assertThat(result, notNullValue());
-		assertThat(Integer.valueOf(result.size()), is(Integer.valueOf(1)));
+			// then
+			assertThat(result, notNullValue());
+			assertThat(Integer.valueOf(result.size()), is(Integer.valueOf(1)));
 
-		DiffEntry entry = result.get(0);
-		assertThat(entry.getOldPath(), is("a.txt"));
-		assertThat(entry.getNewPath(), is(DEV_NULL));
-		assertThat(entry.getChangeType(), is(ChangeType.DELETE));
+			DiffEntry entry = result.get(0);
+			assertThat(entry.getOldPath(), is("a.txt"));
+			assertThat(entry.getNewPath(), is(DEV_NULL));
+			assertThat(entry.getChangeType(), is(ChangeType.DELETE));
+		}
 	}
 
 	@Test
 	public void shouldListModificationInDirWithoutModifiedTrees()
 			throws Exception {
 		// given
-		Git git = new Git(db);
-		File tree = new File(new File(db.getWorkTree(), "a"), "b");
-		FileUtils.mkdirs(tree);
-		File file = new File(tree, "c.txt");
-		FileUtils.createNewFile(file);
-		write(file, "content");
-		git.add().addFilepattern("a").call();
-		RevCommit c1 = git.commit().setMessage("initial commit").call();
-		write(file, "new line");
-		RevCommit c2 = git.commit().setAll(true).setMessage("second commit")
-				.call();
+		try (Git git = new Git(db);
+				TreeWalk walk = new TreeWalk(db)) {
+			File tree = new File(new File(db.getWorkTree(), "a"), "b");
+			FileUtils.mkdirs(tree);
+			File file = new File(tree, "c.txt");
+			FileUtils.createNewFile(file);
+			write(file, "content");
+			git.add().addFilepattern("a").call();
+			RevCommit c1 = git.commit().setMessage("initial commit").call();
+			write(file, "new line");
+			RevCommit c2 = git.commit().setAll(true).setMessage("second commit")
+					.call();
 
-		// when
-		TreeWalk walk = new TreeWalk(db);
-		walk.addTree(c1.getTree());
-		walk.addTree(c2.getTree());
-		walk.setRecursive(true);
-		List<DiffEntry> result = DiffEntry.scan(walk);
+			// when
+			walk.addTree(c1.getTree());
+			walk.addTree(c2.getTree());
+			walk.setRecursive(true);
+			List<DiffEntry> result = DiffEntry.scan(walk);
 
-		// then
-		assertThat(result, notNullValue());
-		assertThat(Integer.valueOf(result.size()), is(Integer.valueOf(1)));
+			// then
+			assertThat(result, notNullValue());
+			assertThat(Integer.valueOf(result.size()), is(Integer.valueOf(1)));
 
-		DiffEntry entry = result.get(0);
-		assertThat(entry.getChangeType(), is(ChangeType.MODIFY));
-		assertThat(entry.getNewPath(), is("a/b/c.txt"));
+			DiffEntry entry = result.get(0);
+			assertThat(entry.getChangeType(), is(ChangeType.MODIFY));
+			assertThat(entry.getNewPath(), is("a/b/c.txt"));
+		}
 	}
 
 	@Test
 	public void shouldListModificationInDirWithModifiedTrees() throws Exception {
 		// given
-		Git git = new Git(db);
-		File tree = new File(new File(db.getWorkTree(), "a"), "b");
-		FileUtils.mkdirs(tree);
-		File file = new File(tree, "c.txt");
-		FileUtils.createNewFile(file);
-		write(file, "content");
-		git.add().addFilepattern("a").call();
-		RevCommit c1 = git.commit().setMessage("initial commit").call();
-		write(file, "new line");
-		RevCommit c2 = git.commit().setAll(true).setMessage("second commit")
-				.call();
+		try (Git git = new Git(db);
+				TreeWalk walk = new TreeWalk(db)) {
+			File tree = new File(new File(db.getWorkTree(), "a"), "b");
+			FileUtils.mkdirs(tree);
+			File file = new File(tree, "c.txt");
+			FileUtils.createNewFile(file);
+			write(file, "content");
+			git.add().addFilepattern("a").call();
+			RevCommit c1 = git.commit().setMessage("initial commit").call();
+			write(file, "new line");
+			RevCommit c2 = git.commit().setAll(true).setMessage("second commit")
+					.call();
 
-		// when
-		TreeWalk walk = new TreeWalk(db);
-		walk.addTree(c1.getTree());
-		walk.addTree(c2.getTree());
-		List<DiffEntry> result = DiffEntry.scan(walk, true);
+			// when
+			walk.addTree(c1.getTree());
+			walk.addTree(c2.getTree());
+			List<DiffEntry> result = DiffEntry.scan(walk, true);
 
-		// then
-		assertThat(result, notNullValue());
-		assertThat(Integer.valueOf(result.size()), is(Integer.valueOf(3)));
+			// then
+			assertThat(result, notNullValue());
+			assertThat(Integer.valueOf(result.size()), is(Integer.valueOf(3)));
 
-		DiffEntry entry = result.get(0);
-		assertThat(entry.getChangeType(), is(ChangeType.MODIFY));
-		assertThat(entry.getNewPath(), is("a"));
+			DiffEntry entry = result.get(0);
+			assertThat(entry.getChangeType(), is(ChangeType.MODIFY));
+			assertThat(entry.getNewPath(), is("a"));
 
-		entry = result.get(1);
-		assertThat(entry.getChangeType(), is(ChangeType.MODIFY));
-		assertThat(entry.getNewPath(), is("a/b"));
+			entry = result.get(1);
+			assertThat(entry.getChangeType(), is(ChangeType.MODIFY));
+			assertThat(entry.getNewPath(), is("a/b"));
 
-		entry = result.get(2);
-		assertThat(entry.getChangeType(), is(ChangeType.MODIFY));
-		assertThat(entry.getNewPath(), is("a/b/c.txt"));
+			entry = result.get(2);
+			assertThat(entry.getChangeType(), is(ChangeType.MODIFY));
+			assertThat(entry.getNewPath(), is("a/b/c.txt"));
+		}
 	}
 
 	@Test
 	public void shouldListChangesInWorkingTree() throws Exception {
 		// given
 		writeTrashFile("a.txt", "content");
-		Git git = new Git(db);
-		git.add().addFilepattern("a.txt").call();
-		RevCommit c = git.commit().setMessage("initial commit").call();
-		writeTrashFile("b.txt", "new line");
+		try (Git git = new Git(db);
+				TreeWalk walk = new TreeWalk(db)) {
+			git.add().addFilepattern("a.txt").call();
+			RevCommit c = git.commit().setMessage("initial commit").call();
+			writeTrashFile("b.txt", "new line");
 
-		// when
-		TreeWalk walk = new TreeWalk(db);
-		walk.addTree(c.getTree());
-		walk.addTree(new FileTreeIterator(db));
-		List<DiffEntry> result = DiffEntry.scan(walk, true);
+			// when
+			walk.addTree(c.getTree());
+			walk.addTree(new FileTreeIterator(db));
+			List<DiffEntry> result = DiffEntry.scan(walk, true);
 
-		// then
-		assertThat(Integer.valueOf(result.size()), is(Integer.valueOf(1)));
-		DiffEntry entry = result.get(0);
+			// then
+			assertThat(Integer.valueOf(result.size()), is(Integer.valueOf(1)));
+			DiffEntry entry = result.get(0);
 
-		assertThat(entry.getChangeType(), is(ChangeType.ADD));
-		assertThat(entry.getNewPath(), is("b.txt"));
+			assertThat(entry.getChangeType(), is(ChangeType.ADD));
+			assertThat(entry.getNewPath(), is("b.txt"));
+		}
 	}
 
 	@Test
 	public void shouldMarkEntriesWhenGivenMarkTreeFilter() throws Exception {
 		// given
-		Git git = new Git(db);
-		RevCommit c1 = git.commit().setMessage("initial commit").call();
-		FileUtils.mkdir(new File(db.getWorkTree(), "b"));
-		writeTrashFile("a.txt", "a");
-		writeTrashFile("b/1.txt", "b1");
-		writeTrashFile("b/2.txt", "b2");
-		writeTrashFile("c.txt", "c");
-		git.add().addFilepattern("a.txt").addFilepattern("b")
-				.addFilepattern("c.txt").call();
-		RevCommit c2 = git.commit().setMessage("second commit").call();
-		TreeFilter filterA = PathFilterGroup.createFromStrings("a.txt");
-		TreeFilter filterB = PathFilterGroup.createFromStrings("b");
-		TreeFilter filterB2 = PathFilterGroup.createFromStrings("b/2.txt");
+		try (Git git = new Git(db);
+				TreeWalk walk = new TreeWalk(db)) {
+			RevCommit c1 = git.commit().setMessage("initial commit").call();
+			FileUtils.mkdir(new File(db.getWorkTree(), "b"));
+			writeTrashFile("a.txt", "a");
+			writeTrashFile("b/1.txt", "b1");
+			writeTrashFile("b/2.txt", "b2");
+			writeTrashFile("c.txt", "c");
+			git.add().addFilepattern("a.txt").addFilepattern("b")
+					.addFilepattern("c.txt").call();
+			RevCommit c2 = git.commit().setMessage("second commit").call();
+			TreeFilter filterA = PathFilterGroup.createFromStrings("a.txt");
+			TreeFilter filterB = PathFilterGroup.createFromStrings("b");
+			TreeFilter filterB2 = PathFilterGroup.createFromStrings("b/2.txt");
 
-		// when
-		TreeWalk walk = new TreeWalk(db);
-		walk.addTree(c1.getTree());
-		walk.addTree(c2.getTree());
-		List<DiffEntry> result = DiffEntry.scan(walk, true, new TreeFilter[] {
-				filterA, filterB, filterB2 });
+			// when
+			walk.addTree(c1.getTree());
+			walk.addTree(c2.getTree());
+			List<DiffEntry> result = DiffEntry.scan(walk, true, new TreeFilter[] {
+					filterA, filterB, filterB2 });
 
-		// then
-		assertThat(result, notNullValue());
-		assertEquals(5, result.size());
+			// then
+			assertThat(result, notNullValue());
+			assertEquals(5, result.size());
 
-		DiffEntry entryA = result.get(0);
-		DiffEntry entryB = result.get(1);
-		DiffEntry entryB1 = result.get(2);
-		DiffEntry entryB2 = result.get(3);
-		DiffEntry entryC = result.get(4);
+			DiffEntry entryA = result.get(0);
+			DiffEntry entryB = result.get(1);
+			DiffEntry entryB1 = result.get(2);
+			DiffEntry entryB2 = result.get(3);
+			DiffEntry entryC = result.get(4);
 
-		assertThat(entryA.getNewPath(), is("a.txt"));
-		assertTrue(entryA.isMarked(0));
-		assertFalse(entryA.isMarked(1));
-		assertFalse(entryA.isMarked(2));
-		assertEquals(1, entryA.getTreeFilterMarks());
+			assertThat(entryA.getNewPath(), is("a.txt"));
+			assertTrue(entryA.isMarked(0));
+			assertFalse(entryA.isMarked(1));
+			assertFalse(entryA.isMarked(2));
+			assertEquals(1, entryA.getTreeFilterMarks());
 
-		assertThat(entryB.getNewPath(), is("b"));
-		assertFalse(entryB.isMarked(0));
-		assertTrue(entryB.isMarked(1));
-		assertTrue(entryB.isMarked(2));
-		assertEquals(6, entryB.getTreeFilterMarks());
+			assertThat(entryB.getNewPath(), is("b"));
+			assertFalse(entryB.isMarked(0));
+			assertTrue(entryB.isMarked(1));
+			assertTrue(entryB.isMarked(2));
+			assertEquals(6, entryB.getTreeFilterMarks());
 
-		assertThat(entryB1.getNewPath(), is("b/1.txt"));
-		assertFalse(entryB1.isMarked(0));
-		assertTrue(entryB1.isMarked(1));
-		assertFalse(entryB1.isMarked(2));
-		assertEquals(2, entryB1.getTreeFilterMarks());
+			assertThat(entryB1.getNewPath(), is("b/1.txt"));
+			assertFalse(entryB1.isMarked(0));
+			assertTrue(entryB1.isMarked(1));
+			assertFalse(entryB1.isMarked(2));
+			assertEquals(2, entryB1.getTreeFilterMarks());
 
-		assertThat(entryB2.getNewPath(), is("b/2.txt"));
-		assertFalse(entryB2.isMarked(0));
-		assertTrue(entryB2.isMarked(1));
-		assertTrue(entryB2.isMarked(2));
-		assertEquals(6, entryB2.getTreeFilterMarks());
+			assertThat(entryB2.getNewPath(), is("b/2.txt"));
+			assertFalse(entryB2.isMarked(0));
+			assertTrue(entryB2.isMarked(1));
+			assertTrue(entryB2.isMarked(2));
+			assertEquals(6, entryB2.getTreeFilterMarks());
 
-		assertThat(entryC.getNewPath(), is("c.txt"));
-		assertFalse(entryC.isMarked(0));
-		assertFalse(entryC.isMarked(1));
-		assertFalse(entryC.isMarked(2));
-		assertEquals(0, entryC.getTreeFilterMarks());
+			assertThat(entryC.getNewPath(), is("c.txt"));
+			assertFalse(entryC.isMarked(0));
+			assertFalse(entryC.isMarked(1));
+			assertFalse(entryC.isMarked(2));
+			assertEquals(0, entryC.getTreeFilterMarks());
+		}
 	}
 
 	@Test(expected = IllegalArgumentException.class)
@@ -339,9 +347,10 @@ public void shouldThrowIAEWhenTreeWalkHasLessThanTwoTrees()
 		// given - we don't need anything here
 
 		// when
-		TreeWalk walk = new TreeWalk(db);
-		walk.addTree(new EmptyTreeIterator());
-		DiffEntry.scan(walk);
+		try (TreeWalk walk = new TreeWalk(db)) {
+			walk.addTree(new EmptyTreeIterator());
+			DiffEntry.scan(walk);
+		}
 	}
 
 	@Test(expected = IllegalArgumentException.class)
@@ -350,11 +359,12 @@ public void shouldThrowIAEWhenTreeWalkHasMoreThanTwoTrees()
 		// given - we don't need anything here
 
 		// when
-		TreeWalk walk = new TreeWalk(db);
-		walk.addTree(new EmptyTreeIterator());
-		walk.addTree(new EmptyTreeIterator());
-		walk.addTree(new EmptyTreeIterator());
-		DiffEntry.scan(walk);
+		try (TreeWalk walk = new TreeWalk(db)) {
+			walk.addTree(new EmptyTreeIterator());
+			walk.addTree(new EmptyTreeIterator());
+			walk.addTree(new EmptyTreeIterator());
+			DiffEntry.scan(walk);
+		}
 	}
 
 	@Test(expected = IllegalArgumentException.class)
@@ -363,46 +373,47 @@ public void shouldThrowIAEWhenScanShouldIncludeTreesAndWalkIsRecursive()
 		// given - we don't need anything here
 
 		// when
-		TreeWalk walk = new TreeWalk(db);
-		walk.addTree(new EmptyTreeIterator());
-		walk.addTree(new EmptyTreeIterator());
-		walk.setRecursive(true);
-		DiffEntry.scan(walk, true);
+		try (TreeWalk walk = new TreeWalk(db)) {
+			walk.addTree(new EmptyTreeIterator());
+			walk.addTree(new EmptyTreeIterator());
+			walk.setRecursive(true);
+			DiffEntry.scan(walk, true);
+		}
 	}
 
 	@Test
 	public void shouldReportFileModeChange() throws Exception {
 		writeTrashFile("a.txt", "content");
-		Git git = new Git(db);
-		git.add().addFilepattern("a.txt").call();
-		RevCommit c1 = git.commit().setMessage("initial commit").call();
-		DirCache cache = db.lockDirCache();
-		DirCacheEditor editor = cache.editor();
-		final TreeWalk walk = new TreeWalk(db);
-		walk.addTree(c1.getTree());
-		walk.setRecursive(true);
-		assertTrue(walk.next());
+		try (Git git = new Git(db);
+				TreeWalk walk = new TreeWalk(db)) {
+			git.add().addFilepattern("a.txt").call();
+			RevCommit c1 = git.commit().setMessage("initial commit").call();
+			DirCache cache = db.lockDirCache();
+			DirCacheEditor editor = cache.editor();
+			walk.addTree(c1.getTree());
+			walk.setRecursive(true);
+			assertTrue(walk.next());
 
-		editor.add(new PathEdit("a.txt") {
-
-			public void apply(DirCacheEntry ent) {
-				ent.setFileMode(FileMode.EXECUTABLE_FILE);
-				ent.setObjectId(walk.getObjectId(0));
-			}
-		});
-		assertTrue(editor.commit());
-		RevCommit c2 = git.commit().setMessage("second commit").call();
-		walk.reset();
-		walk.addTree(c1.getTree());
-		walk.addTree(c2.getTree());
-		List<DiffEntry> diffs = DiffEntry.scan(walk, false);
-		assertEquals(1, diffs.size());
-		DiffEntry diff = diffs.get(0);
-		assertEquals(ChangeType.MODIFY,diff.getChangeType());
-		assertEquals(diff.getOldId(), diff.getNewId());
-		assertEquals("a.txt", diff.getOldPath());
-		assertEquals(diff.getOldPath(), diff.getNewPath());
-		assertEquals(FileMode.EXECUTABLE_FILE, diff.getNewMode());
-		assertEquals(FileMode.REGULAR_FILE, diff.getOldMode());
+			editor.add(new PathEdit("a.txt") {
+				public void apply(DirCacheEntry ent) {
+					ent.setFileMode(FileMode.EXECUTABLE_FILE);
+					ent.setObjectId(walk.getObjectId(0));
+				}
+			});
+			assertTrue(editor.commit());
+			RevCommit c2 = git.commit().setMessage("second commit").call();
+			walk.reset();
+			walk.addTree(c1.getTree());
+			walk.addTree(c2.getTree());
+			List<DiffEntry> diffs = DiffEntry.scan(walk, false);
+			assertEquals(1, diffs.size());
+			DiffEntry diff = diffs.get(0);
+			assertEquals(ChangeType.MODIFY,diff.getChangeType());
+			assertEquals(diff.getOldId(), diff.getNewId());
+			assertEquals("a.txt", diff.getOldPath());
+			assertEquals(diff.getOldPath(), diff.getNewPath());
+			assertEquals(FileMode.EXECUTABLE_FILE, diff.getNewMode());
+			assertEquals(FileMode.REGULAR_FILE, diff.getOldMode());
+		}
 	}
 }
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/diff/DiffFormatterTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/diff/DiffFormatterTest.java
index 81a4c6a..638a163 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/diff/DiffFormatterTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/diff/DiffFormatterTest.java
@@ -260,6 +260,68 @@ public void testCreateFileHeader_GitLink() throws Exception {
 	}
 
 	@Test
+	public void testCreateFileHeader_AddGitLink() throws Exception {
+		ObjectId adId = blob("a\nd\n");
+		DiffEntry ent = DiffEntry.add("FOO", adId);
+		ent.newMode = FileMode.GITLINK;
+		FileHeader fh = df.toFileHeader(ent);
+
+		String diffHeader = "diff --git a/FOO b/FOO\n" //
+				+ "new file mode " + GITLINK + "\n"
+				+ "index "
+				+ ObjectId.zeroId().abbreviate(8).name()
+				+ ".."
+				+ adId.abbreviate(8).name() + "\n" //
+				+ "--- /dev/null\n"//
+				+ "+++ b/FOO\n";
+		assertEquals(diffHeader, RawParseUtils.decode(fh.getBuffer()));
+
+		assertEquals(1, fh.getHunks().size());
+		HunkHeader hh = fh.getHunks().get(0);
+
+		EditList el = hh.toEditList();
+		assertEquals(1, el.size());
+
+		Edit e = el.get(0);
+		assertEquals(0, e.getBeginA());
+		assertEquals(0, e.getEndA());
+		assertEquals(0, e.getBeginB());
+		assertEquals(1, e.getEndB());
+		assertEquals(Edit.Type.INSERT, e.getType());
+	}
+
+	@Test
+	public void testCreateFileHeader_DeleteGitLink() throws Exception {
+		ObjectId adId = blob("a\nd\n");
+		DiffEntry ent = DiffEntry.delete("FOO", adId);
+		ent.oldMode = FileMode.GITLINK;
+		FileHeader fh = df.toFileHeader(ent);
+
+		String diffHeader = "diff --git a/FOO b/FOO\n" //
+				+ "deleted file mode " + GITLINK + "\n"
+				+ "index "
+				+ adId.abbreviate(8).name()
+				+ ".."
+				+ ObjectId.zeroId().abbreviate(8).name() + "\n" //
+				+ "--- a/FOO\n"//
+				+ "+++ /dev/null\n";
+		assertEquals(diffHeader, RawParseUtils.decode(fh.getBuffer()));
+
+		assertEquals(1, fh.getHunks().size());
+		HunkHeader hh = fh.getHunks().get(0);
+
+		EditList el = hh.toEditList();
+		assertEquals(1, el.size());
+
+		Edit e = el.get(0);
+		assertEquals(0, e.getBeginA());
+		assertEquals(1, e.getEndA());
+		assertEquals(0, e.getBeginB());
+		assertEquals(0, e.getEndB());
+		assertEquals(Edit.Type.DELETE, e.getType());
+	}
+
+	@Test
 	public void testCreateFileHeaderWithoutIndexLine() throws Exception {
 		DiffEntry m = DiffEntry.modify(PATH_A);
 		m.oldMode = FileMode.REGULAR_FILE;
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/diff/PatchIdDiffFormatterTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/diff/PatchIdDiffFormatterTest.java
index ce283ae..024aaa3 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/diff/PatchIdDiffFormatterTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/diff/PatchIdDiffFormatterTest.java
@@ -61,21 +61,22 @@ public void testDiff() throws Exception {
 		File folder = new File(db.getDirectory().getParent(), "folder");
 		folder.mkdir();
 		write(new File(folder, "folder.txt"), "folder");
-		Git git = new Git(db);
-		git.add().addFilepattern(".").call();
-		git.commit().setMessage("Initial commit").call();
-		write(new File(folder, "folder.txt"), "folder change");
+		try (Git git = new Git(db);
+				PatchIdDiffFormatter df = new PatchIdDiffFormatter()) {
+			git.add().addFilepattern(".").call();
+			git.commit().setMessage("Initial commit").call();
+			write(new File(folder, "folder.txt"), "folder change");
 
-		PatchIdDiffFormatter df = new PatchIdDiffFormatter();
-		df.setRepository(db);
-		df.setPathFilter(PathFilter.create("folder"));
-		DirCacheIterator oldTree = new DirCacheIterator(db.readDirCache());
-		FileTreeIterator newTree = new FileTreeIterator(db);
-		df.format(oldTree, newTree);
-		df.flush();
+			df.setRepository(db);
+			df.setPathFilter(PathFilter.create("folder"));
+			DirCacheIterator oldTree = new DirCacheIterator(db.readDirCache());
+			FileTreeIterator newTree = new FileTreeIterator(db);
+			df.format(oldTree, newTree);
+			df.flush();
 
-		assertEquals("1ff64e0f9333e9b81967c3e8d7a81362b14d5441", df
-				.getCalulatedPatchId().name());
+			assertEquals("1ff64e0f9333e9b81967c3e8d7a81362b14d5441", df
+					.getCalulatedPatchId().name());
+		}
 	}
 
 	@Test
@@ -84,37 +85,40 @@ public void testSameDiff() throws Exception {
 		File folder = new File(db.getDirectory().getParent(), "folder");
 		folder.mkdir();
 		write(new File(folder, "folder.txt"), "\n\n\n\nfolder");
-		Git git = new Git(db);
-		git.add().addFilepattern(".").call();
-		git.commit().setMessage("Initial commit").call();
-		write(new File(folder, "folder.txt"), "\n\n\n\nfolder change");
+		try (Git git = new Git(db)) {
+			git.add().addFilepattern(".").call();
+			git.commit().setMessage("Initial commit").call();
+			write(new File(folder, "folder.txt"), "\n\n\n\nfolder change");
 
-		PatchIdDiffFormatter df = new PatchIdDiffFormatter();
-		df.setRepository(db);
-		df.setPathFilter(PathFilter.create("folder"));
-		DirCacheIterator oldTree = new DirCacheIterator(db.readDirCache());
-		FileTreeIterator newTree = new FileTreeIterator(db);
-		df.format(oldTree, newTree);
-		df.flush();
+			try (PatchIdDiffFormatter df = new PatchIdDiffFormatter()) {
+				df.setRepository(db);
+				df.setPathFilter(PathFilter.create("folder"));
+				DirCacheIterator oldTree = new DirCacheIterator(db.readDirCache());
+				FileTreeIterator newTree = new FileTreeIterator(db);
+				df.format(oldTree, newTree);
+				df.flush();
 
-		assertEquals("08fca5ac531383eb1da8bf6b6f7cf44411281407", df
-				.getCalulatedPatchId().name());
+				assertEquals("08fca5ac531383eb1da8bf6b6f7cf44411281407", df
+						.getCalulatedPatchId().name());
+			}
 
-		write(new File(folder, "folder.txt"), "a\n\n\n\nfolder");
-		git.add().addFilepattern(".").call();
-		git.commit().setMessage("Initial commit").call();
-		write(new File(folder, "folder.txt"), "a\n\n\n\nfolder change");
+			write(new File(folder, "folder.txt"), "a\n\n\n\nfolder");
+			git.add().addFilepattern(".").call();
+			git.commit().setMessage("Initial commit").call();
+			write(new File(folder, "folder.txt"), "a\n\n\n\nfolder change");
 
-		df = new PatchIdDiffFormatter();
-		df.setRepository(db);
-		df.setPathFilter(PathFilter.create("folder"));
-		oldTree = new DirCacheIterator(db.readDirCache());
-		newTree = new FileTreeIterator(db);
-		df.format(oldTree, newTree);
-		df.flush();
+			try (PatchIdDiffFormatter df = new PatchIdDiffFormatter()) {
+				df.setRepository(db);
+				df.setPathFilter(PathFilter.create("folder"));
+				DirCacheIterator oldTree = new DirCacheIterator(db.readDirCache());
+				FileTreeIterator newTree = new FileTreeIterator(db);
+				df.format(oldTree, newTree);
+				df.flush();
 
-		assertEquals("08fca5ac531383eb1da8bf6b6f7cf44411281407", df
-				.getCalulatedPatchId().name());
+				assertEquals("08fca5ac531383eb1da8bf6b6f7cf44411281407", df
+						.getCalulatedPatchId().name());
+			}
+		}
 	}
 
 }
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/gitrepo/RepoCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/gitrepo/RepoCommandTest.java
index 524d0b8..2cec34b 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/gitrepo/RepoCommandTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/gitrepo/RepoCommandTest.java
@@ -82,38 +82,42 @@ public void setUp() throws Exception {
 		super.setUp();
 
 		defaultDb = createWorkRepository();
-		Git git = new Git(defaultDb);
-		JGitTestUtil.writeTrashFile(defaultDb, "hello.txt", "branch world");
-		git.add().addFilepattern("hello.txt").call();
-		oldCommitId = git.commit().setMessage("Initial commit").call().getId();
-		git.checkout().setName(BRANCH).setCreateBranch(true).call();
-		git.checkout().setName("master").call();
-		git.tag().setName(TAG).call();
-		JGitTestUtil.writeTrashFile(defaultDb, "hello.txt", "master world");
-		git.add().addFilepattern("hello.txt").call();
-		git.commit().setMessage("Second commit").call();
-		addRepoToClose(defaultDb);
+		try (Git git = new Git(defaultDb)) {
+			JGitTestUtil.writeTrashFile(defaultDb, "hello.txt", "branch world");
+			git.add().addFilepattern("hello.txt").call();
+			oldCommitId = git.commit().setMessage("Initial commit").call().getId();
+			git.checkout().setName(BRANCH).setCreateBranch(true).call();
+			git.checkout().setName("master").call();
+			git.tag().setName(TAG).call();
+			JGitTestUtil.writeTrashFile(defaultDb, "hello.txt", "master world");
+			git.add().addFilepattern("hello.txt").call();
+			git.commit().setMessage("Second commit").call();
+			addRepoToClose(defaultDb);
+		}
 
 		notDefaultDb = createWorkRepository();
-		git = new Git(notDefaultDb);
-		JGitTestUtil.writeTrashFile(notDefaultDb, "world.txt", "hello");
-		git.add().addFilepattern("world.txt").call();
-		git.commit().setMessage("Initial commit").call();
-		addRepoToClose(notDefaultDb);
+		try (Git git = new Git(notDefaultDb)) {
+			JGitTestUtil.writeTrashFile(notDefaultDb, "world.txt", "hello");
+			git.add().addFilepattern("world.txt").call();
+			git.commit().setMessage("Initial commit").call();
+			addRepoToClose(notDefaultDb);
+		}
 
 		groupADb = createWorkRepository();
-		git = new Git(groupADb);
-		JGitTestUtil.writeTrashFile(groupADb, "a.txt", "world");
-		git.add().addFilepattern("a.txt").call();
-		git.commit().setMessage("Initial commit").call();
-		addRepoToClose(groupADb);
+		try (Git git = new Git(groupADb)) {
+			JGitTestUtil.writeTrashFile(groupADb, "a.txt", "world");
+			git.add().addFilepattern("a.txt").call();
+			git.commit().setMessage("Initial commit").call();
+			addRepoToClose(groupADb);
+		}
 
 		groupBDb = createWorkRepository();
-		git = new Git(groupBDb);
-		JGitTestUtil.writeTrashFile(groupBDb, "b.txt", "world");
-		git.add().addFilepattern("b.txt").call();
-		git.commit().setMessage("Initial commit").call();
-		addRepoToClose(groupBDb);
+		try (Git git = new Git(groupBDb)) {
+			JGitTestUtil.writeTrashFile(groupBDb, "b.txt", "world");
+			git.add().addFilepattern("b.txt").call();
+			git.commit().setMessage("Initial commit").call();
+			addRepoToClose(groupBDb);
+		}
 
 		resolveRelativeUris();
 	}
@@ -747,6 +751,59 @@ public void testRecordRemoteBranch() throws Exception {
 		}
 	}
 
+	@Test
+	public void testRemoteRevision() throws Exception {
+		StringBuilder xmlContent = new StringBuilder();
+		xmlContent.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
+			.append("<manifest>")
+			.append("<remote name=\"remote1\" fetch=\".\" />")
+			.append("<remote name=\"remote2\" fetch=\".\" revision=\"")
+			.append(BRANCH)
+			.append("\" />")
+			.append("<default remote=\"remote1\" revision=\"master\" />")
+			.append("<project path=\"foo\" remote=\"remote2\" name=\"")
+			.append(defaultUri)
+			.append("\" />")
+			.append("</manifest>");
+		writeTrashFile("manifest.xml", xmlContent.toString());
+		RepoCommand command = new RepoCommand(db);
+		command.setPath(db.getWorkTree().getAbsolutePath() + "/manifest.xml")
+			.setURI(rootUri)
+			.call();
+		File hello = new File(db.getWorkTree(), "foo/hello.txt");
+		BufferedReader reader = new BufferedReader(new FileReader(hello));
+		String content = reader.readLine();
+		reader.close();
+		assertEquals("submodule content should be as expected",
+				"branch world", content);
+	}
+
+	@Test
+	public void testDefaultRemoteRevision() throws Exception {
+		StringBuilder xmlContent = new StringBuilder();
+		xmlContent.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
+			.append("<manifest>")
+			.append("<remote name=\"remote1\" fetch=\".\" revision=\"")
+			.append(BRANCH)
+			.append("\" />")
+			.append("<default remote=\"remote1\" />")
+			.append("<project path=\"foo\" name=\"")
+			.append(defaultUri)
+			.append("\" />")
+			.append("</manifest>");
+		writeTrashFile("manifest.xml", xmlContent.toString());
+		RepoCommand command = new RepoCommand(db);
+		command.setPath(db.getWorkTree().getAbsolutePath() + "/manifest.xml")
+			.setURI(rootUri)
+			.call();
+		File hello = new File(db.getWorkTree(), "foo/hello.txt");
+		BufferedReader reader = new BufferedReader(new FileReader(hello));
+		String content = reader.readLine();
+		reader.close();
+		assertEquals("submodule content should be as expected",
+				"branch world", content);
+	}
+
 	private void resolveRelativeUris() {
 		// Find the longest common prefix ends with "/" as rootUri.
 		defaultUri = defaultDb.getDirectory().toURI().toString();
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 3226f42..923f283 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
@@ -62,18 +62,18 @@ public void testConcurrentInsertionOfBlobsToTheSameNewFanOutDirectory()
 			throws Exception {
 		ExecutorService e = Executors.newCachedThreadPool();
 		for (int i=0; i < 100; ++i) {
-			ObjectDirectory db = createBareRepository().getObjectDatabase();
-			for (Future f : e.invokeAll(blobInsertersForTheSameFanOutDir(db))) {
+			ObjectDirectory dir = createBareRepository().getObjectDatabase();
+			for (Future f : e.invokeAll(blobInsertersForTheSameFanOutDir(dir))) {
 				f.get();
 			}
 		}
 	}
 
 	private Collection<Callable<ObjectId>> blobInsertersForTheSameFanOutDir(
-			final ObjectDirectory db) {
+			final ObjectDirectory dir) {
 		Callable<ObjectId> callable = new Callable<ObjectId>() {
 			public ObjectId call() throws Exception {
-				return db.newInserter().insert(Constants.OBJ_BLOB, new byte[0]);
+				return 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/PackFileTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackFileTest.java
index cb80768..ba07d68 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackFileTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackFileTest.java
@@ -191,119 +191,122 @@ public void testWhole_LargeObject() throws Exception {
 
 	@Test
 	public void testDelta_SmallObjectChain() throws Exception {
-		ObjectInserter.Formatter fmt = new ObjectInserter.Formatter();
-		byte[] data0 = new byte[512];
-		Arrays.fill(data0, (byte) 0xf3);
-		ObjectId id0 = fmt.idFor(Constants.OBJ_BLOB, data0);
+		try (ObjectInserter.Formatter fmt = new ObjectInserter.Formatter()) {
+			byte[] data0 = new byte[512];
+			Arrays.fill(data0, (byte) 0xf3);
+			ObjectId id0 = fmt.idFor(Constants.OBJ_BLOB, data0);
 
-		TemporaryBuffer.Heap pack = new TemporaryBuffer.Heap(64 * 1024);
-		packHeader(pack, 4);
-		objectHeader(pack, Constants.OBJ_BLOB, data0.length);
-		deflate(pack, data0);
+			TemporaryBuffer.Heap pack = new TemporaryBuffer.Heap(64 * 1024);
+			packHeader(pack, 4);
+			objectHeader(pack, Constants.OBJ_BLOB, data0.length);
+			deflate(pack, data0);
 
-		byte[] data1 = clone(0x01, data0);
-		byte[] delta1 = delta(data0, data1);
-		ObjectId id1 = fmt.idFor(Constants.OBJ_BLOB, data1);
-		objectHeader(pack, Constants.OBJ_REF_DELTA, delta1.length);
-		id0.copyRawTo(pack);
-		deflate(pack, delta1);
+			byte[] data1 = clone(0x01, data0);
+			byte[] delta1 = delta(data0, data1);
+			ObjectId id1 = fmt.idFor(Constants.OBJ_BLOB, data1);
+			objectHeader(pack, Constants.OBJ_REF_DELTA, delta1.length);
+			id0.copyRawTo(pack);
+			deflate(pack, delta1);
 
-		byte[] data2 = clone(0x02, data1);
-		byte[] delta2 = delta(data1, data2);
-		ObjectId id2 = fmt.idFor(Constants.OBJ_BLOB, data2);
-		objectHeader(pack, Constants.OBJ_REF_DELTA, delta2.length);
-		id1.copyRawTo(pack);
-		deflate(pack, delta2);
+			byte[] data2 = clone(0x02, data1);
+			byte[] delta2 = delta(data1, data2);
+			ObjectId id2 = fmt.idFor(Constants.OBJ_BLOB, data2);
+			objectHeader(pack, Constants.OBJ_REF_DELTA, delta2.length);
+			id1.copyRawTo(pack);
+			deflate(pack, delta2);
 
-		byte[] data3 = clone(0x03, data2);
-		byte[] delta3 = delta(data2, data3);
-		ObjectId id3 = fmt.idFor(Constants.OBJ_BLOB, data3);
-		objectHeader(pack, Constants.OBJ_REF_DELTA, delta3.length);
-		id2.copyRawTo(pack);
-		deflate(pack, delta3);
+			byte[] data3 = clone(0x03, data2);
+			byte[] delta3 = delta(data2, data3);
+			ObjectId id3 = fmt.idFor(Constants.OBJ_BLOB, data3);
+			objectHeader(pack, Constants.OBJ_REF_DELTA, delta3.length);
+			id2.copyRawTo(pack);
+			deflate(pack, delta3);
 
-		digest(pack);
-		PackParser ip = index(pack.toByteArray());
-		ip.setAllowThin(true);
-		ip.parse(NullProgressMonitor.INSTANCE);
+			digest(pack);
+			PackParser ip = index(pack.toByteArray());
+			ip.setAllowThin(true);
+			ip.parse(NullProgressMonitor.INSTANCE);
 
-		assertTrue("has blob", wc.has(id3));
+			assertTrue("has blob", wc.has(id3));
 
-		ObjectLoader ol = wc.open(id3);
-		assertNotNull("created loader", ol);
-		assertEquals(Constants.OBJ_BLOB, ol.getType());
-		assertEquals(data3.length, ol.getSize());
-		assertFalse("is large", ol.isLarge());
-		assertNotNull(ol.getCachedBytes());
-		assertArrayEquals(data3, ol.getCachedBytes());
+			ObjectLoader ol = wc.open(id3);
+			assertNotNull("created loader", ol);
+			assertEquals(Constants.OBJ_BLOB, ol.getType());
+			assertEquals(data3.length, ol.getSize());
+			assertFalse("is large", ol.isLarge());
+			assertNotNull(ol.getCachedBytes());
+			assertArrayEquals(data3, ol.getCachedBytes());
 
-		ObjectStream in = ol.openStream();
-		assertNotNull("have stream", in);
-		assertEquals(Constants.OBJ_BLOB, in.getType());
-		assertEquals(data3.length, in.getSize());
-		byte[] act = new byte[data3.length];
-		IO.readFully(in, act, 0, data3.length);
-		assertTrue("same content", Arrays.equals(act, data3));
-		assertEquals("stream at EOF", -1, in.read());
-		in.close();
+			ObjectStream in = ol.openStream();
+			assertNotNull("have stream", in);
+			assertEquals(Constants.OBJ_BLOB, in.getType());
+			assertEquals(data3.length, in.getSize());
+			byte[] act = new byte[data3.length];
+			IO.readFully(in, act, 0, data3.length);
+			assertTrue("same content", Arrays.equals(act, data3));
+			assertEquals("stream at EOF", -1, in.read());
+			in.close();
+		}
 	}
 
 	@Test
 	public void testDelta_FailsOver2GiB() throws Exception {
-		ObjectInserter.Formatter fmt = new ObjectInserter.Formatter();
-		byte[] base = new byte[] { 'a' };
-		ObjectId idA = fmt.idFor(Constants.OBJ_BLOB, base);
-		ObjectId idB = fmt.idFor(Constants.OBJ_BLOB, new byte[] { 'b' });
+		try (ObjectInserter.Formatter fmt = new ObjectInserter.Formatter()) {
+			byte[] base = new byte[] { 'a' };
+			ObjectId idA = fmt.idFor(Constants.OBJ_BLOB, base);
+			ObjectId idB = fmt.idFor(Constants.OBJ_BLOB, new byte[] { 'b' });
 
-		PackedObjectInfo a = new PackedObjectInfo(idA);
-		PackedObjectInfo b = new PackedObjectInfo(idB);
+			PackedObjectInfo a = new PackedObjectInfo(idA);
+			PackedObjectInfo b = new PackedObjectInfo(idB);
 
-		TemporaryBuffer.Heap pack = new TemporaryBuffer.Heap(64 * 1024);
-		packHeader(pack, 2);
-		a.setOffset(pack.length());
-		objectHeader(pack, Constants.OBJ_BLOB, base.length);
-		deflate(pack, base);
+			TemporaryBuffer.Heap pack = new TemporaryBuffer.Heap(64 * 1024);
+			packHeader(pack, 2);
+			a.setOffset(pack.length());
+			objectHeader(pack, Constants.OBJ_BLOB, base.length);
+			deflate(pack, base);
 
-		ByteArrayOutputStream tmp = new ByteArrayOutputStream();
-		DeltaEncoder de = new DeltaEncoder(tmp, base.length, 3L << 30);
-		de.copy(0, 1);
-		byte[] delta = tmp.toByteArray();
-		b.setOffset(pack.length());
-		objectHeader(pack, Constants.OBJ_REF_DELTA, delta.length);
-		idA.copyRawTo(pack);
-		deflate(pack, delta);
-		byte[] footer = digest(pack);
+			ByteArrayOutputStream tmp = new ByteArrayOutputStream();
+			DeltaEncoder de = new DeltaEncoder(tmp, base.length, 3L << 30);
+			de.copy(0, 1);
+			byte[] delta = tmp.toByteArray();
+			b.setOffset(pack.length());
+			objectHeader(pack, Constants.OBJ_REF_DELTA, delta.length);
+			idA.copyRawTo(pack);
+			deflate(pack, delta);
+			byte[] footer = digest(pack);
 
-		File dir = new File(repo.getObjectDatabase().getDirectory(), "pack");
-		File packName = new File(dir, idA.name() + ".pack");
-		File idxName = new File(dir, idA.name() + ".idx");
+			File dir = new File(repo.getObjectDatabase().getDirectory(),
+					"pack");
+			File packName = new File(dir, idA.name() + ".pack");
+			File idxName = new File(dir, idA.name() + ".idx");
 
-		FileOutputStream f = new FileOutputStream(packName);
-		try {
-			f.write(pack.toByteArray());
-		} finally {
-			f.close();
-		}
+			FileOutputStream f = new FileOutputStream(packName);
+			try {
+				f.write(pack.toByteArray());
+			} finally {
+				f.close();
+			}
 
-		f = new FileOutputStream(idxName);
-		try {
-			List<PackedObjectInfo> list = new ArrayList<PackedObjectInfo>();
-			list.add(a);
-			list.add(b);
-			Collections.sort(list);
-			new PackIndexWriterV1(f).write(list, footer);
-		} finally {
-			f.close();
-		}
+			f = new FileOutputStream(idxName);
+			try {
+				List<PackedObjectInfo> list = new ArrayList<PackedObjectInfo>();
+				list.add(a);
+				list.add(b);
+				Collections.sort(list);
+				new PackIndexWriterV1(f).write(list, footer);
+			} finally {
+				f.close();
+			}
 
-		PackFile packFile = new PackFile(packName, PackExt.INDEX.getBit());
-		try {
-			packFile.get(wc, b);
-			fail("expected LargeObjectException.ExceedsByteArrayLimit");
-		} catch (LargeObjectException.ExceedsByteArrayLimit bad) {
-			assertNull(bad.getObjectId());
-		} finally {
-			packFile.close();
+			PackFile packFile = new PackFile(packName, PackExt.INDEX.getBit());
+			try {
+				packFile.get(wc, b);
+				fail("expected LargeObjectException.ExceedsByteArrayLimit");
+			} catch (LargeObjectException.ExceedsByteArrayLimit bad) {
+				assertNull(bad.getObjectId());
+			} finally {
+				packFile.close();
+			}
 		}
 	}
 
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 01d6ee6..63a3072 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
@@ -342,12 +342,13 @@ public void testWritePack3() throws MissingObjectException, IOException {
 				ObjectId.fromString("902d5476fa249b7abc9d84c611577a81381f0327"),
 				ObjectId.fromString("5b6e7c66c276e7610d4a73c70ec1a1f7c1003259"),
 				ObjectId.fromString("6ff87c4664981e4397625791c8ea3bbb5f2279a3") };
-		final RevWalk parser = new RevWalk(db);
-		final RevObject forcedOrderRevs[] = new RevObject[forcedOrder.length];
-		for (int i = 0; i < forcedOrder.length; i++)
-			forcedOrderRevs[i] = parser.parseAny(forcedOrder[i]);
+		try (final RevWalk parser = new RevWalk(db)) {
+			final RevObject forcedOrderRevs[] = new RevObject[forcedOrder.length];
+			for (int i = 0; i < forcedOrder.length; i++)
+				forcedOrderRevs[i] = parser.parseAny(forcedOrder[i]);
 
-		createVerifyOpenPack(Arrays.asList(forcedOrderRevs));
+			createVerifyOpenPack(Arrays.asList(forcedOrderRevs));
+		}
 
 		assertEquals(forcedOrder.length, writer.getObjectCount());
 		verifyObjectsOrder(forcedOrder);
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 52e181b..ef5dfcd 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
@@ -1444,8 +1444,8 @@ public void start(int totalTasks) {
 			// empty
 		}
 
-		public void beginTask(String title, int totalWork) {
-			this.totalWork = totalWork;
+		public void beginTask(String title, int total) {
+			this.totalWork = total;
 			lastWork = 0;
 		}
 
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/T0003_BasicTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/T0003_BasicTest.java
index f4d655f..b6ad22b 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/T0003_BasicTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/T0003_BasicTest.java
@@ -84,7 +84,6 @@
 import org.eclipse.jgit.util.FileUtils;
 import org.junit.Test;
 
-@SuppressWarnings("deprecation")
 public class T0003_BasicTest extends SampleDataRepositoryTestCase {
 
 	@Test
@@ -355,14 +354,14 @@ public void test006_ReadUglyConfig() throws IOException,
 
 	@Test
 	public void test007_Open() throws IOException {
-		final FileRepository db2 = new FileRepository(db.getDirectory());
-		assertEquals(db.getDirectory(), db2.getDirectory());
-		assertEquals(db.getObjectDatabase().getDirectory(), db2
-				.getObjectDatabase().getDirectory());
-		assertNotSame(db.getConfig(), db2.getConfig());
+		try (final FileRepository db2 = new FileRepository(db.getDirectory())) {
+			assertEquals(db.getDirectory(), db2.getDirectory());
+			assertEquals(db.getObjectDatabase().getDirectory(), db2
+					.getObjectDatabase().getDirectory());
+			assertNotSame(db.getConfig(), db2.getConfig());
+		}
 	}
 
-	@SuppressWarnings("unused")
 	@Test
 	public void test008_FailOnWrongVersion() throws IOException {
 		final File cfg = new File(db.getDirectory(), Constants.CONFIG);
@@ -371,8 +370,7 @@ public void test008_FailOnWrongVersion() throws IOException {
 				+ badvers + "\n";
 		write(cfg, configStr);
 
-		try {
-			new FileRepository(db.getDirectory());
+		try (FileRepository unused = new FileRepository(db.getDirectory())) {
 			fail("incorrectly opened a bad repository");
 		} catch (IllegalArgumentException ioe) {
 			assertNotNull(ioe.getMessage());
@@ -534,9 +532,10 @@ public void test024_createCommitNonAscii() throws IOException {
 	public void test025_computeSha1NoStore() throws IOException {
 		byte[] data = "test025 some data, more than 16 bytes to get good coverage"
 				.getBytes("ISO-8859-1");
-		final ObjectId id = new ObjectInserter.Formatter().idFor(
-				Constants.OBJ_BLOB, data);
-		assertEquals("4f561df5ecf0dfbd53a0dc0f37262fef075d9dde", id.name());
+		try (ObjectInserter.Formatter formatter = new ObjectInserter.Formatter()) {
+			final ObjectId id = formatter.idFor(Constants.OBJ_BLOB, data);
+			assertEquals("4f561df5ecf0dfbd53a0dc0f37262fef075d9dde", id.name());
+		}
 	}
 
 	@Test
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/DirCacheCheckoutTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/DirCacheCheckoutTest.java
index 92901f8..c1b882a 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/DirCacheCheckoutTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/DirCacheCheckoutTest.java
@@ -140,52 +140,53 @@ private static HashMap<String, String> mkmap(String... args) {
 	@Test
 	public void testResetHard() throws IOException, NoFilepatternException,
 			GitAPIException {
-		Git git = new Git(db);
-		writeTrashFile("f", "f()");
-		writeTrashFile("D/g", "g()");
-		git.add().addFilepattern(".").call();
-		git.commit().setMessage("inital").call();
-		assertIndex(mkmap("f", "f()", "D/g", "g()"));
+		try (Git git = new Git(db)) {
+			writeTrashFile("f", "f()");
+			writeTrashFile("D/g", "g()");
+			git.add().addFilepattern(".").call();
+			git.commit().setMessage("inital").call();
+			assertIndex(mkmap("f", "f()", "D/g", "g()"));
 
-		git.branchCreate().setName("topic").call();
+			git.branchCreate().setName("topic").call();
 
-		writeTrashFile("f", "f()\nmaster");
-		writeTrashFile("D/g", "g()\ng2()");
-		writeTrashFile("E/h", "h()");
-		git.add().addFilepattern(".").call();
-		RevCommit master = git.commit().setMessage("master-1").call();
-		assertIndex(mkmap("f", "f()\nmaster", "D/g", "g()\ng2()", "E/h", "h()"));
+			writeTrashFile("f", "f()\nmaster");
+			writeTrashFile("D/g", "g()\ng2()");
+			writeTrashFile("E/h", "h()");
+			git.add().addFilepattern(".").call();
+			RevCommit master = git.commit().setMessage("master-1").call();
+			assertIndex(mkmap("f", "f()\nmaster", "D/g", "g()\ng2()", "E/h", "h()"));
 
-		checkoutBranch("refs/heads/topic");
-		assertIndex(mkmap("f", "f()", "D/g", "g()"));
+			checkoutBranch("refs/heads/topic");
+			assertIndex(mkmap("f", "f()", "D/g", "g()"));
 
-		writeTrashFile("f", "f()\nside");
-		assertTrue(new File(db.getWorkTree(), "D/g").delete());
-		writeTrashFile("G/i", "i()");
-		git.add().addFilepattern(".").call();
-		git.add().addFilepattern(".").setUpdate(true).call();
-		RevCommit topic = git.commit().setMessage("topic-1").call();
-		assertIndex(mkmap("f", "f()\nside", "G/i", "i()"));
+			writeTrashFile("f", "f()\nside");
+			assertTrue(new File(db.getWorkTree(), "D/g").delete());
+			writeTrashFile("G/i", "i()");
+			git.add().addFilepattern(".").call();
+			git.add().addFilepattern(".").setUpdate(true).call();
+			RevCommit topic = git.commit().setMessage("topic-1").call();
+			assertIndex(mkmap("f", "f()\nside", "G/i", "i()"));
 
-		writeTrashFile("untracked", "untracked");
+			writeTrashFile("untracked", "untracked");
 
-		resetHard(master);
-		assertIndex(mkmap("f", "f()\nmaster", "D/g", "g()\ng2()", "E/h", "h()"));
-		resetHard(topic);
-		assertIndex(mkmap("f", "f()\nside", "G/i", "i()"));
-		assertWorkDir(mkmap("f", "f()\nside", "G/i", "i()", "untracked",
-				"untracked"));
+			resetHard(master);
+			assertIndex(mkmap("f", "f()\nmaster", "D/g", "g()\ng2()", "E/h", "h()"));
+			resetHard(topic);
+			assertIndex(mkmap("f", "f()\nside", "G/i", "i()"));
+			assertWorkDir(mkmap("f", "f()\nside", "G/i", "i()", "untracked",
+					"untracked"));
 
-		assertEquals(MergeStatus.CONFLICTING, git.merge().include(master)
-				.call().getMergeStatus());
-		assertEquals(
-				"[D/g, mode:100644, stage:1][D/g, mode:100644, stage:3][E/h, mode:100644][G/i, mode:100644][f, mode:100644, stage:1][f, mode:100644, stage:2][f, mode:100644, stage:3]",
-				indexState(0));
+			assertEquals(MergeStatus.CONFLICTING, git.merge().include(master)
+					.call().getMergeStatus());
+			assertEquals(
+					"[D/g, mode:100644, stage:1][D/g, mode:100644, stage:3][E/h, mode:100644][G/i, mode:100644][f, mode:100644, stage:1][f, mode:100644, stage:2][f, mode:100644, stage:3]",
+					indexState(0));
 
-		resetHard(master);
-		assertIndex(mkmap("f", "f()\nmaster", "D/g", "g()\ng2()", "E/h", "h()"));
-		assertWorkDir(mkmap("f", "f()\nmaster", "D/g", "g()\ng2()", "E/h",
-				"h()", "untracked", "untracked"));
+			resetHard(master);
+			assertIndex(mkmap("f", "f()\nmaster", "D/g", "g()\ng2()", "E/h", "h()"));
+			assertWorkDir(mkmap("f", "f()\nmaster", "D/g", "g()\ng2()", "E/h",
+					"h()", "untracked", "untracked"));
+		}
 	}
 
 	/**
@@ -200,21 +201,22 @@ public void testResetHard() throws IOException, NoFilepatternException,
 	@Test
 	public void testResetHardFromIndexEntryWithoutFileToTreeWithoutFile()
 			throws Exception {
-		Git git = new Git(db);
-		writeTrashFile("x", "x");
-		git.add().addFilepattern("x").call();
-		RevCommit id1 = git.commit().setMessage("c1").call();
+		try (Git git = new Git(db)) {
+			writeTrashFile("x", "x");
+			git.add().addFilepattern("x").call();
+			RevCommit id1 = git.commit().setMessage("c1").call();
 
-		writeTrashFile("f/g", "f/g");
-		git.rm().addFilepattern("x").call();
-		git.add().addFilepattern("f/g").call();
-		git.commit().setMessage("c2").call();
-		deleteTrashFile("f/g");
-		deleteTrashFile("f");
+			writeTrashFile("f/g", "f/g");
+			git.rm().addFilepattern("x").call();
+			git.add().addFilepattern("f/g").call();
+			git.commit().setMessage("c2").call();
+			deleteTrashFile("f/g");
+			deleteTrashFile("f");
 
-		// The actual test
-		git.reset().setMode(ResetType.HARD).setRef(id1.getName()).call();
-		assertIndex(mkmap("x", "x"));
+			// The actual test
+			git.reset().setMode(ResetType.HARD).setRef(id1.getName()).call();
+			assertIndex(mkmap("x", "x"));
+		}
 	}
 
 	/**
@@ -224,14 +226,14 @@ public void testResetHardFromIndexEntryWithoutFileToTreeWithoutFile()
 	 */
 	@Test
 	public void testInitialCheckout() throws Exception {
-		Git git = new Git(db);
-
-		TestRepository<Repository> db_t = new TestRepository<Repository>(db);
-		BranchBuilder master = db_t.branch("master");
-		master.commit().add("f", "1").message("m0").create();
-		assertFalse(new File(db.getWorkTree(), "f").exists());
-		git.checkout().setName("master").call();
-		assertTrue(new File(db.getWorkTree(), "f").exists());
+		try (Git git = new Git(db)) {
+			TestRepository<Repository> db_t = new TestRepository<Repository>(db);
+			BranchBuilder master = db_t.branch("master");
+			master.commit().add("f", "1").message("m0").create();
+			assertFalse(new File(db.getWorkTree(), "f").exists());
+			git.checkout().setName("master").call();
+			assertTrue(new File(db.getWorkTree(), "f").exists());
+		}
 	}
 
 	private DirCacheCheckout resetHard(RevCommit commit)
@@ -1612,46 +1614,47 @@ public void testFileModeChangeAndContentChangeNoConflict() throws Exception {
 	public void assertWorkDir(Map<String, String> i)
 			throws CorruptObjectException,
 			IOException {
-		TreeWalk walk = new TreeWalk(db);
-		walk.setRecursive(false);
-		walk.addTree(new FileTreeIterator(db));
-		String expectedValue;
-		String path;
-		int nrFiles = 0;
-		FileTreeIterator ft;
-		while (walk.next()) {
-			ft = walk.getTree(0, FileTreeIterator.class);
-			path = ft.getEntryPathString();
-			expectedValue = i.get(path);
-			File file = new File(db.getWorkTree(), path);
-			assertTrue(file.exists());
-			if (file.isFile()) {
-				assertNotNull("found unexpected file for path " + path
-						+ " in workdir", expectedValue);
-				FileInputStream is = new FileInputStream(file);
-				byte[] buffer = new byte[(int) file.length()];
-				int offset = 0;
-				int numRead = 0;
-				while (offset < buffer.length
-						&& (numRead = is.read(buffer, offset, buffer.length
-								- offset)) >= 0) {
-					offset += numRead;
-				}
-				is.close();
-				assertArrayEquals("unexpected content for path " + path
-						+ " in workDir. ", buffer, i.get(path).getBytes());
-				nrFiles++;
-			} else if (file.isDirectory()) {
-				if (file.list().length == 0) {
-					assertEquals("found unexpected empty folder for path "
-							+ path + " in workDir. ", "/", i.get(path));
+		try (TreeWalk walk = new TreeWalk(db)) {
+			walk.setRecursive(false);
+			walk.addTree(new FileTreeIterator(db));
+			String expectedValue;
+			String path;
+			int nrFiles = 0;
+			FileTreeIterator ft;
+			while (walk.next()) {
+				ft = walk.getTree(0, FileTreeIterator.class);
+				path = ft.getEntryPathString();
+				expectedValue = i.get(path);
+				File file = new File(db.getWorkTree(), path);
+				assertTrue(file.exists());
+				if (file.isFile()) {
+					assertNotNull("found unexpected file for path " + path
+							+ " in workdir", expectedValue);
+					FileInputStream is = new FileInputStream(file);
+					byte[] buffer = new byte[(int) file.length()];
+					int offset = 0;
+					int numRead = 0;
+					while (offset < buffer.length
+							&& (numRead = is.read(buffer, offset, buffer.length
+									- offset)) >= 0) {
+						offset += numRead;
+					}
+					is.close();
+					assertArrayEquals("unexpected content for path " + path
+							+ " in workDir. ", buffer, i.get(path).getBytes());
 					nrFiles++;
+				} else if (file.isDirectory()) {
+					if (file.list().length == 0) {
+						assertEquals("found unexpected empty folder for path "
+								+ path + " in workDir. ", "/", i.get(path));
+						nrFiles++;
+					}
+				}
+				if (walk.isSubtree()) {
+					walk.enterSubtree();
 				}
 			}
-			if (walk.isSubtree()) {
-				walk.enterSubtree();
-			}
+			assertEquals("WorkDir has not the right size.", i.size(), nrFiles);
 		}
-		assertEquals("WorkDir has not the right size.", i.size(), nrFiles);
 	}
 }
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/IndexDiffTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/IndexDiffTest.java
index 7fcee3d..18c9596 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/IndexDiffTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/IndexDiffTest.java
@@ -77,7 +77,6 @@
 import org.eclipse.jgit.util.IO;
 import org.junit.Test;
 
-@SuppressWarnings("deprecation")
 public class IndexDiffTest extends RepositoryTestCase {
 
 	static PathEdit add(final Repository db, final File workdir,
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/RacyGitTests.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/RacyGitTests.java
index 99d6801..aa46d1a 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/RacyGitTests.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/RacyGitTests.java
@@ -82,38 +82,42 @@ public void testIterator() throws IllegalStateException, IOException,
 		}
 		FileTreeIteratorWithTimeControl fileIt = new FileTreeIteratorWithTimeControl(
 				db, modTimes);
-		NameConflictTreeWalk tw = new NameConflictTreeWalk(db);
-		tw.addTree(fileIt);
-		tw.setRecursive(true);
-		FileTreeIterator t;
-		long t0 = 0;
-		for (int i = 0; i < 10; i++) {
-			assertTrue(tw.next());
-			t = tw.getTree(0, FileTreeIterator.class);
-			if (i == 0)
-				t0 = t.getEntryLastModified();
-			else
-				assertEquals(t0, t.getEntryLastModified());
-		}
-		long t1 = 0;
-		for (int i = 0; i < 10; i++) {
-			assertTrue(tw.next());
-			t = tw.getTree(0, FileTreeIterator.class);
-			if (i == 0) {
-				t1 = t.getEntryLastModified();
-				assertTrue(t1 > t0);
-			} else
-				assertEquals(t1, t.getEntryLastModified());
-		}
-		long t2 = 0;
-		for (int i = 0; i < 10; i++) {
-			assertTrue(tw.next());
-			t = tw.getTree(0, FileTreeIterator.class);
-			if (i == 0) {
-				t2 = t.getEntryLastModified();
-				assertTrue(t2 > t1);
-			} else
-				assertEquals(t2, t.getEntryLastModified());
+		try (NameConflictTreeWalk tw = new NameConflictTreeWalk(db)) {
+			tw.addTree(fileIt);
+			tw.setRecursive(true);
+			FileTreeIterator t;
+			long t0 = 0;
+			for (int i = 0; i < 10; i++) {
+				assertTrue(tw.next());
+				t = tw.getTree(0, FileTreeIterator.class);
+				if (i == 0) {
+					t0 = t.getEntryLastModified();
+				} else {
+					assertEquals(t0, t.getEntryLastModified());
+				}
+			}
+			long t1 = 0;
+			for (int i = 0; i < 10; i++) {
+				assertTrue(tw.next());
+				t = tw.getTree(0, FileTreeIterator.class);
+				if (i == 0) {
+					t1 = t.getEntryLastModified();
+					assertTrue(t1 > t0);
+				} else {
+					assertEquals(t1, t.getEntryLastModified());
+				}
+			}
+			long t2 = 0;
+			for (int i = 0; i < 10; i++) {
+				assertTrue(tw.next());
+				t = tw.getTree(0, FileTreeIterator.class);
+				if (i == 0) {
+					t2 = t.getEntryLastModified();
+					assertTrue(t2 > t1);
+				} else {
+					assertEquals(t2, t.getEntryLastModified());
+				}
+			}
 		}
 	}
 
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ReflogConfigTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ReflogConfigTest.java
index 7b6d7d4..df1a52d 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ReflogConfigTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ReflogConfigTest.java
@@ -70,8 +70,7 @@ public void testlogAllRefUpdates() throws Exception {
 
 		// do one commit and check that reflog size is 0: no reflogs should be
 		// written
-		commit("A Commit\n", new PersonIdent(author, commitTime, tz),
-				new PersonIdent(committer, commitTime, tz));
+		commit("A Commit\n", commitTime, tz);
 		commitTime += 60 * 1000;
 		assertTrue(
 				"Reflog for HEAD still contain no entry",
@@ -83,8 +82,7 @@ public void testlogAllRefUpdates() throws Exception {
 		assertTrue(cfg.get(CoreConfig.KEY).isLogAllRefUpdates());
 
 		// do one commit and check that reflog size is increased to 1
-		commit("A Commit\n", new PersonIdent(author, commitTime, tz),
-				new PersonIdent(committer, commitTime, tz));
+		commit("A Commit\n", commitTime, tz);
 		commitTime += 60 * 1000;
 		assertTrue(
 				"Reflog for HEAD should contain one entry",
@@ -96,18 +94,17 @@ public void testlogAllRefUpdates() throws Exception {
 		assertFalse(cfg.get(CoreConfig.KEY).isLogAllRefUpdates());
 
 		// do one commit and check that reflog size is 2
-		commit("A Commit\n", new PersonIdent(author, commitTime, tz),
-				new PersonIdent(committer, commitTime, tz));
+		commit("A Commit\n", commitTime, tz);
 		assertTrue(
 				"Reflog for HEAD should contain two entries",
 				db.getReflogReader(Constants.HEAD).getReverseEntries().size() == 2);
 	}
 
-	private void commit(String commitMsg, PersonIdent author,
-			PersonIdent committer) throws IOException {
+	private void commit(String commitMsg, long commitTime, int tz)
+			throws IOException {
 		final CommitBuilder commit = new CommitBuilder();
-		commit.setAuthor(author);
-		commit.setCommitter(committer);
+		commit.setAuthor(new PersonIdent(author, commitTime, tz));
+		commit.setCommitter(new PersonIdent(committer, commitTime, tz));
 		commit.setMessage(commitMsg);
 		ObjectId id;
 		try (ObjectInserter inserter = db.newObjectInserter()) {
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ReflogResolveTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ReflogResolveTest.java
index 75d74fc..7db9f60 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ReflogResolveTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ReflogResolveTest.java
@@ -60,117 +60,123 @@ public class ReflogResolveTest extends RepositoryTestCase {
 
 	@Test
 	public void resolveMasterCommits() throws Exception {
-		Git git = new Git(db);
-		writeTrashFile("file.txt", "content");
-		git.add().addFilepattern("file.txt").call();
-		RevCommit c1 = git.commit().setMessage("create file").call();
-		writeTrashFile("file.txt", "content2");
-		git.add().addFilepattern("file.txt").call();
-		RevCommit c2 = git.commit().setMessage("edit file").call();
+		try (Git git = new Git(db)) {
+			writeTrashFile("file.txt", "content");
+			git.add().addFilepattern("file.txt").call();
+			RevCommit c1 = git.commit().setMessage("create file").call();
+			writeTrashFile("file.txt", "content2");
+			git.add().addFilepattern("file.txt").call();
+			RevCommit c2 = git.commit().setMessage("edit file").call();
 
-		assertEquals(c2, db.resolve("master@{0}"));
-		assertEquals(c1, db.resolve("master@{1}"));
+			assertEquals(c2, db.resolve("master@{0}"));
+			assertEquals(c1, db.resolve("master@{1}"));
+		}
 	}
 
 	@Test
 	public void resolveUnnamedCurrentBranchCommits() throws Exception {
-		Git git = new Git(db);
-		writeTrashFile("file.txt", "content");
-		git.add().addFilepattern("file.txt").call();
-		RevCommit c1 = git.commit().setMessage("create file").call();
-		writeTrashFile("file.txt", "content2");
-		git.add().addFilepattern("file.txt").call();
-		RevCommit c2 = git.commit().setMessage("edit file").call();
+		try (Git git = new Git(db)) {
+			writeTrashFile("file.txt", "content");
+			git.add().addFilepattern("file.txt").call();
+			RevCommit c1 = git.commit().setMessage("create file").call();
+			writeTrashFile("file.txt", "content2");
+			git.add().addFilepattern("file.txt").call();
+			RevCommit c2 = git.commit().setMessage("edit file").call();
 
-		assertEquals(c2, db.resolve("master@{0}"));
-		assertEquals(c1, db.resolve("master@{1}"));
+			assertEquals(c2, db.resolve("master@{0}"));
+			assertEquals(c1, db.resolve("master@{1}"));
 
-		git.checkout().setCreateBranch(true).setName("newbranch")
-				.setStartPoint(c1).call();
+			git.checkout().setCreateBranch(true).setName("newbranch")
+					.setStartPoint(c1).call();
 
-		// same as current branch, e.g. master
-		assertEquals(c1, db.resolve("@{0}"));
-		try {
+			// same as current branch, e.g. master
+			assertEquals(c1, db.resolve("@{0}"));
+			try {
+				assertEquals(c1, db.resolve("@{1}"));
+				fail(); // Looking at wrong ref, e.g HEAD
+			} catch (RevisionSyntaxException e) {
+				assertNotNull(e);
+			}
+
+			// detached head, read HEAD reflog
+			git.checkout().setName(c2.getName()).call();
+			assertEquals(c2, db.resolve("@{0}"));
 			assertEquals(c1, db.resolve("@{1}"));
-			fail(); // Looking at wrong ref, e.g HEAD
-		} catch (RevisionSyntaxException e) {
-			assertNotNull(e);
+			assertEquals(c2, db.resolve("@{2}"));
 		}
-
-		// detached head, read HEAD reflog
-		git.checkout().setName(c2.getName()).call();
-		assertEquals(c2, db.resolve("@{0}"));
-		assertEquals(c1, db.resolve("@{1}"));
-		assertEquals(c2, db.resolve("@{2}"));
 	}
 
 	@Test
 	public void resolveReflogParent() throws Exception {
-		Git git = new Git(db);
-		writeTrashFile("file.txt", "content");
-		git.add().addFilepattern("file.txt").call();
-		RevCommit c1 = git.commit().setMessage("create file").call();
-		writeTrashFile("file.txt", "content2");
-		git.add().addFilepattern("file.txt").call();
-		git.commit().setMessage("edit file").call();
+		try (Git git = new Git(db)) {
+			writeTrashFile("file.txt", "content");
+			git.add().addFilepattern("file.txt").call();
+			RevCommit c1 = git.commit().setMessage("create file").call();
+			writeTrashFile("file.txt", "content2");
+			git.add().addFilepattern("file.txt").call();
+			git.commit().setMessage("edit file").call();
 
-		assertEquals(c1, db.resolve("master@{0}~1"));
+			assertEquals(c1, db.resolve("master@{0}~1"));
+		}
 	}
 
 	@Test
 	public void resolveNonExistingBranch() throws Exception {
-		Git git = new Git(db);
-		writeTrashFile("file.txt", "content");
-		git.add().addFilepattern("file.txt").call();
-		git.commit().setMessage("create file").call();
-		assertNull(db.resolve("notabranch@{7}"));
+		try (Git git = new Git(db)) {
+			writeTrashFile("file.txt", "content");
+			git.add().addFilepattern("file.txt").call();
+			git.commit().setMessage("create file").call();
+			assertNull(db.resolve("notabranch@{7}"));
+		}
 	}
 
 	@Test
 	public void resolvePreviousBranch() throws Exception {
-		Git git = new Git(db);
-		writeTrashFile("file.txt", "content");
-		git.add().addFilepattern("file.txt").call();
-		RevCommit c1 = git.commit().setMessage("create file").call();
-		writeTrashFile("file.txt", "content2");
-		git.add().addFilepattern("file.txt").call();
-		RevCommit c2 = git.commit().setMessage("edit file").call();
+		try (Git git = new Git(db)) {
+			writeTrashFile("file.txt", "content");
+			git.add().addFilepattern("file.txt").call();
+			RevCommit c1 = git.commit().setMessage("create file").call();
+			writeTrashFile("file.txt", "content2");
+			git.add().addFilepattern("file.txt").call();
+			RevCommit c2 = git.commit().setMessage("edit file").call();
 
-		git.checkout().setCreateBranch(true).setName("newbranch")
-				.setStartPoint(c1).call();
+			git.checkout().setCreateBranch(true).setName("newbranch")
+					.setStartPoint(c1).call();
 
-		git.checkout().setName(c1.getName()).call();
+			git.checkout().setName(c1.getName()).call();
 
-		git.checkout().setName("master").call();
+			git.checkout().setName("master").call();
 
-		assertEquals(c1.getName(), db.simplify("@{-1}"));
-		assertEquals("newbranch", db.simplify("@{-2}"));
-		assertEquals("master", db.simplify("@{-3}"));
+			assertEquals(c1.getName(), db.simplify("@{-1}"));
+			assertEquals("newbranch", db.simplify("@{-2}"));
+			assertEquals("master", db.simplify("@{-3}"));
 
-		// chained expression
-		try {
-			// Cannot refer to reflog of detached head
-			db.resolve("@{-1}@{0}");
-			fail();
-		} catch (RevisionSyntaxException e) {
-			// good
+			// chained expression
+			try {
+				// Cannot refer to reflog of detached head
+				db.resolve("@{-1}@{0}");
+				fail();
+			} catch (RevisionSyntaxException e) {
+				// good
+			}
+			assertEquals(c1.getName(), db.resolve("@{-2}@{0}").getName());
+
+			assertEquals(c2.getName(), db.resolve("@{-3}@{0}").getName());
 		}
-		assertEquals(c1.getName(), db.resolve("@{-2}@{0}").getName());
-
-		assertEquals(c2.getName(), db.resolve("@{-3}@{0}").getName());
 	}
 
 	@Test
 	public void resolveDate() throws Exception {
-		Git git = new Git(db);
-		writeTrashFile("file.txt", "content");
-		git.add().addFilepattern("file.txt").call();
-		git.commit().setMessage("create file").call();
-		try {
-			db.resolve("master@{yesterday}");
-			fail("Exception not thrown");
-		} catch (RevisionSyntaxException e) {
-			assertNotNull(e);
+		try (Git git = new Git(db)) {
+			writeTrashFile("file.txt", "content");
+			git.add().addFilepattern("file.txt").call();
+			git.commit().setMessage("create file").call();
+			try {
+				db.resolve("master@{yesterday}");
+				fail("Exception not thrown");
+			} catch (RevisionSyntaxException e) {
+				assertNotNull(e);
+			}
 		}
 	}
 }
\ No newline at end of file
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/RepositoryResolveTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/RepositoryResolveTest.java
index c9ea286..1d2a4e9 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/RepositoryResolveTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/RepositoryResolveTest.java
@@ -267,35 +267,37 @@ public void testParseLookupPath() throws IOException {
 
 	@Test
 	public void resolveExprSimple() throws Exception {
-		Git git = new Git(db);
-		writeTrashFile("file.txt", "content");
-		git.add().addFilepattern("file.txt").call();
-		git.commit().setMessage("create file").call();
-		assertEquals("master", db.simplify("master"));
-		assertEquals("refs/heads/master", db.simplify("refs/heads/master"));
-		assertEquals("HEAD", db.simplify("HEAD"));
+		try (Git git = new Git(db)) {
+			writeTrashFile("file.txt", "content");
+			git.add().addFilepattern("file.txt").call();
+			git.commit().setMessage("create file").call();
+			assertEquals("master", db.simplify("master"));
+			assertEquals("refs/heads/master", db.simplify("refs/heads/master"));
+			assertEquals("HEAD", db.simplify("HEAD"));
+		}
 	}
 
 	@Test
 	public void resolveUpstream() throws Exception {
-		Git git = new Git(db);
-		writeTrashFile("file.txt", "content");
-		git.add().addFilepattern("file.txt").call();
-		RevCommit c1 = git.commit().setMessage("create file").call();
-		writeTrashFile("file2.txt", "content");
-		RefUpdate updateRemoteRef = db.updateRef("refs/remotes/origin/main");
-		updateRemoteRef.setNewObjectId(c1);
-		updateRemoteRef.update();
-		db.getConfig().setString("branch", "master", "remote", "origin");
-		db.getConfig()
-				.setString("branch", "master", "merge", "refs/heads/main");
-		db.getConfig().setString("remote", "origin", "url",
-				"git://example.com/here");
-		db.getConfig().setString("remote", "origin", "fetch",
-				"+refs/heads/*:refs/remotes/origin/*");
-		git.add().addFilepattern("file2.txt").call();
-		git.commit().setMessage("create file").call();
-		assertEquals("refs/remotes/origin/main", db.simplify("@{upstream}"));
+		try (Git git = new Git(db)) {
+			writeTrashFile("file.txt", "content");
+			git.add().addFilepattern("file.txt").call();
+			RevCommit c1 = git.commit().setMessage("create file").call();
+			writeTrashFile("file2.txt", "content");
+			RefUpdate updateRemoteRef = db.updateRef("refs/remotes/origin/main");
+			updateRemoteRef.setNewObjectId(c1);
+			updateRemoteRef.update();
+			db.getConfig().setString("branch", "master", "remote", "origin");
+			db.getConfig()
+					.setString("branch", "master", "merge", "refs/heads/main");
+			db.getConfig().setString("remote", "origin", "url",
+					"git://example.com/here");
+			db.getConfig().setString("remote", "origin", "fetch",
+					"+refs/heads/*:refs/remotes/origin/*");
+			git.add().addFilepattern("file2.txt").call();
+			git.commit().setMessage("create file").call();
+			assertEquals("refs/remotes/origin/main", db.simplify("@{upstream}"));
+		}
 	}
 
 	@Test
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/RecursiveMergerTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/RecursiveMergerTest.java
index 7ef6448..0e7109c 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/RecursiveMergerTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/RecursiveMergerTest.java
@@ -872,32 +872,31 @@ private boolean validateStates(IndexState indexState,
 
 	private String contentAsString(Repository r, ObjectId treeId, String path)
 			throws MissingObjectException, IOException {
-		TreeWalk tw = new TreeWalk(r);
-		tw.addTree(treeId);
-		tw.setFilter(PathFilter.create(path));
-		tw.setRecursive(true);
-		if (!tw.next())
-			return null;
-		AnyObjectId blobId = tw.getObjectId(0);
+		AnyObjectId blobId;
+		try (TreeWalk tw = new TreeWalk(r)) {
+			tw.addTree(treeId);
+			tw.setFilter(PathFilter.create(path));
+			tw.setRecursive(true);
+			if (!tw.next()) {
+				return null;
+			}
+			blobId = tw.getObjectId(0);
+		}
 
 		StringBuilder result = new StringBuilder();
-		BufferedReader br = null;
 		ObjectReader or = r.newObjectReader();
-		try {
-			br = new BufferedReader(new InputStreamReader(or.open(blobId)
-					.openStream()));
+		try (BufferedReader br = new BufferedReader(
+				new InputStreamReader(or.open(blobId).openStream()))) {
 			String line;
 			boolean first = true;
 			while ((line = br.readLine()) != null) {
-				if (!first)
+				if (!first) {
 					result.append('\n');
+				}
 				result.append(line);
 				first = false;
 			}
 			return result.toString();
-		} finally {
-			if (br != null)
-				br.close();
 		}
 	}
 }
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/ResolveMergerTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/ResolveMergerTest.java
index 674619f..55bb93a 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/ResolveMergerTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/ResolveMergerTest.java
@@ -88,35 +88,36 @@ public void failingDeleteOfDirectoryWithUntrackedContent(
 		file = new File(folder1, "file2.txt");
 		write(file, "folder1--file2.txt");
 
-		Git git = new Git(db);
-		git.add().addFilepattern(folder1.getName()).call();
-		RevCommit base = git.commit().setMessage("adding folder").call();
+		try (Git git = new Git(db)) {
+			git.add().addFilepattern(folder1.getName()).call();
+			RevCommit base = git.commit().setMessage("adding folder").call();
 
-		recursiveDelete(folder1);
-		git.rm().addFilepattern("folder1/file1.txt")
-				.addFilepattern("folder1/file2.txt").call();
-		RevCommit other = git.commit()
-				.setMessage("removing folders on 'other'").call();
+			recursiveDelete(folder1);
+			git.rm().addFilepattern("folder1/file1.txt")
+					.addFilepattern("folder1/file2.txt").call();
+			RevCommit other = git.commit()
+					.setMessage("removing folders on 'other'").call();
 
-		git.checkout().setName(base.name()).call();
+			git.checkout().setName(base.name()).call();
 
-		file = new File(db.getWorkTree(), "unrelated.txt");
-		write(file, "unrelated");
+			file = new File(db.getWorkTree(), "unrelated.txt");
+			write(file, "unrelated");
 
-		git.add().addFilepattern("unrelated.txt").call();
-		RevCommit head = git.commit().setMessage("Adding another file").call();
+			git.add().addFilepattern("unrelated.txt").call();
+			RevCommit head = git.commit().setMessage("Adding another file").call();
 
-		// Untracked file to cause failing path for delete() of folder1
-		// but that's ok.
-		file = new File(folder1, "file3.txt");
-		write(file, "folder1--file3.txt");
+			// Untracked file to cause failing path for delete() of folder1
+			// but that's ok.
+			file = new File(folder1, "file3.txt");
+			write(file, "folder1--file3.txt");
 
-		ResolveMerger merger = (ResolveMerger) strategy.newMerger(db, false);
-		merger.setCommitNames(new String[] { "BASE", "HEAD", "other" });
-		merger.setWorkingTreeIterator(new FileTreeIterator(db));
-		boolean ok = merger.merge(head.getId(), other.getId());
-		assertTrue(ok);
-		assertTrue(file.exists());
+			ResolveMerger merger = (ResolveMerger) strategy.newMerger(db, false);
+			merger.setCommitNames(new String[] { "BASE", "HEAD", "other" });
+			merger.setWorkingTreeIterator(new FileTreeIterator(db));
+			boolean ok = merger.merge(head.getId(), other.getId());
+			assertTrue(ok);
+			assertTrue(file.exists());
+		}
 	}
 
 	/**
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/SquashMessageFormatterTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/SquashMessageFormatterTest.java
index cddbbd5..7a2586d 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/SquashMessageFormatterTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/SquashMessageFormatterTest.java
@@ -73,17 +73,18 @@ public void setUp() throws Exception {
 
 	@Test
 	public void testCommit() throws Exception {
-		Git git = new Git(db);
-		revCommit = git.commit().setMessage("squash_me").call();
+		try (Git git = new Git(db)) {
+			revCommit = git.commit().setMessage("squash_me").call();
 
-		Ref master = db.exactRef("refs/heads/master");
-		String message = msgFormatter.format(Arrays.asList(revCommit), master);
-		assertEquals(
-				"Squashed commit of the following:\n\ncommit "
-						+ revCommit.getName() + "\nAuthor: "
-						+ revCommit.getAuthorIdent().getName() + " <"
-						+ revCommit.getAuthorIdent().getEmailAddress()
-						+ ">\nDate:   " + dateFormatter.formatDate(author)
-						+ "\n\n\tsquash_me\n", message);
+			Ref master = db.exactRef("refs/heads/master");
+			String message = msgFormatter.format(Arrays.asList(revCommit), master);
+			assertEquals(
+					"Squashed commit of the following:\n\ncommit "
+							+ revCommit.getName() + "\nAuthor: "
+							+ revCommit.getAuthorIdent().getName() + " <"
+							+ revCommit.getAuthorIdent().getEmailAddress()
+							+ ">\nDate:   " + dateFormatter.formatDate(author)
+							+ "\n\n\tsquash_me\n", message);
+		}
 	}
 }
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/notes/NoteMapTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/notes/NoteMapTest.java
index 4539a01..47b08a7 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/notes/NoteMapTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/notes/NoteMapTest.java
@@ -403,10 +403,12 @@ public void testLeafSplitsWhenFull() throws Exception {
 		}
 
 		RevCommit n = commitNoteMap(map);
-		TreeWalk tw = new TreeWalk(reader);
-		tw.reset(n.getTree());
-		while (tw.next())
-			assertFalse("no fan-out subtree", tw.isSubtree());
+		try (TreeWalk tw = new TreeWalk(reader)) {
+			tw.reset(n.getTree());
+			while (tw.next()) {
+				assertFalse("no fan-out subtree", tw.isSubtree());
+			}
+		}
 
 		for (int i = 254; i < 256; i++) {
 			idBuf.setByte(Constants.OBJECT_ID_LENGTH - 1, i);
@@ -418,13 +420,15 @@ public void testLeafSplitsWhenFull() throws Exception {
 
 		// The 00 bucket is fully split.
 		String path = fanout(38, idBuf.name());
-		tw = TreeWalk.forPath(reader, path, n.getTree());
-		assertNotNull("has " + path, tw);
+		try (TreeWalk tw = TreeWalk.forPath(reader, path, n.getTree())) {
+			assertNotNull("has " + path, tw);
+		}
 
 		// The other bucket is not.
 		path = fanout(2, data1.name());
-		tw = TreeWalk.forPath(reader, path, n.getTree());
-		assertNotNull("has " + path, tw);
+		try (TreeWalk tw = TreeWalk.forPath(reader, path, n.getTree())) {
+			assertNotNull("has " + path, tw);
+		}
 	}
 
 	@Test
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/ObjectWalkTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/ObjectWalkTest.java
index 9c9edc1..e5ad313 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/ObjectWalkTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/ObjectWalkTest.java
@@ -53,7 +53,6 @@
 import org.eclipse.jgit.lib.TreeFormatter;
 import org.junit.Test;
 
-@SuppressWarnings("deprecation")
 public class ObjectWalkTest extends RevWalkTestCase {
 	protected ObjectWalk objw;
 
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevCommitListTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevCommitListTest.java
index 5ec6eb3..4d75322 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevCommitListTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevCommitListTest.java
@@ -57,14 +57,15 @@ public class RevCommitListTest extends RepositoryTestCase {
 	private RevCommitList<RevCommit> list;
 
 	public void setup(int count) throws Exception {
-		Git git = new Git(db);
-		for (int i = 0; i < count; i++)
-			git.commit().setCommitter(committer).setAuthor(author)
-					.setMessage("commit " + i).call();
-		list = new RevCommitList<RevCommit>();
-		RevWalk w = new RevWalk(db);
-		w.markStart(w.lookupCommit(db.resolve(Constants.HEAD)));
-		list.source(w);
+		try (Git git = new Git(db);
+				RevWalk w = new RevWalk(db);) {
+			for (int i = 0; i < count; i++)
+				git.commit().setCommitter(committer).setAuthor(author)
+						.setMessage("commit " + i).call();
+			list = new RevCommitList<RevCommit>();
+			w.markStart(w.lookupCommit(db.resolve(Constants.HEAD)));
+			list.source(w);
+		}
 	}
 
 	@Test
@@ -107,17 +108,18 @@ public void testFillToHighMarkMulitpleBlocks() throws Exception {
 	public void testFillToCommit() throws Exception {
 		setup(3);
 
-		RevWalk w = new RevWalk(db);
-		w.markStart(w.lookupCommit(db.resolve(Constants.HEAD)));
+		try (RevWalk w = new RevWalk(db)) {
+			w.markStart(w.lookupCommit(db.resolve(Constants.HEAD)));
 
-		w.next();
-		RevCommit c = w.next();
-		assertNotNull("should have found 2. commit", c);
+			w.next();
+			RevCommit c = w.next();
+			assertNotNull("should have found 2. commit", c);
 
-		list.fillTo(c, 5);
-		assertEquals(2, list.size());
-		assertEquals("commit 1", list.get(1).getFullMessage());
-		assertNull(list.get(3));
+			list.fillTo(c, 5);
+			assertEquals(2, list.size());
+			assertEquals("commit 1", list.get(1).getFullMessage());
+			assertNull(list.get(3));
+		}
 	}
 
 	@Test
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevCommitParseTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevCommitParseTest.java
index 885c1b5..1a15842 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevCommitParseTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevCommitParseTest.java
@@ -452,9 +452,10 @@ public void testParse_GitStyleMessage() throws Exception {
 	@Test
 	public void testParse_PublicParseMethod()
 			throws UnsupportedEncodingException {
-		ObjectInserter.Formatter fmt = new ObjectInserter.Formatter();
 		CommitBuilder src = new CommitBuilder();
-		src.setTreeId(fmt.idFor(Constants.OBJ_TREE, new byte[] {}));
+		try (ObjectInserter.Formatter fmt = new ObjectInserter.Formatter()) {
+			src.setTreeId(fmt.idFor(Constants.OBJ_TREE, new byte[] {}));
+		}
 		src.setAuthor(author);
 		src.setCommitter(committer);
 		src.setMessage("Test commit\n\nThis is a test.\n");
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevObjectTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevObjectTest.java
index a768bef..95e7ca6 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevObjectTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevObjectTest.java
@@ -73,9 +73,12 @@ public void testEquals() throws Exception {
 		assertTrue(a1.equals((Object) a1));
 		assertFalse(a1.equals(""));
 
-		final RevWalk rw2 = new RevWalk(db);
-		final RevCommit a2 = rw2.parseCommit(a1);
-		final RevCommit b2 = rw2.parseCommit(b1);
+		final RevCommit a2;
+		final RevCommit b2;
+		try (final RevWalk rw2 = new RevWalk(db)) {
+			a2 = rw2.parseCommit(a1);
+			b2 = rw2.parseCommit(b1);
+		}
 		assertNotSame(a1, a2);
 		assertNotSame(b1, b2);
 
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevTagParseTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevTagParseTest.java
index 82505ca..f97043b 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevTagParseTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevTagParseTest.java
@@ -463,10 +463,11 @@ public void testParse_GitStyleMessage() throws Exception {
 
 	@Test
 	public void testParse_PublicParseMethod() throws CorruptObjectException {
-		ObjectInserter.Formatter fmt = new ObjectInserter.Formatter();
 		TagBuilder src = new TagBuilder();
-		src.setObjectId(fmt.idFor(Constants.OBJ_TREE, new byte[] {}),
-				Constants.OBJ_TREE);
+		try (ObjectInserter.Formatter fmt = new ObjectInserter.Formatter()) {
+			src.setObjectId(fmt.idFor(Constants.OBJ_TREE, new byte[] {}),
+					Constants.OBJ_TREE);
+		}
 		src.setTagger(committer);
 		src.setTag("a.test");
 		src.setMessage("Test tag\n\nThis is a test.\n");
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/submodule/SubmoduleAddTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/submodule/SubmoduleAddTest.java
index b13c4cd..a131e5e 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/submodule/SubmoduleAddTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/submodule/SubmoduleAddTest.java
@@ -119,36 +119,37 @@ public void commandWithEmptyUri() throws GitAPIException {
 
 	@Test
 	public void addSubmodule() throws Exception {
-		Git git = new Git(db);
-		writeTrashFile("file.txt", "content");
-		git.add().addFilepattern("file.txt").call();
-		RevCommit commit = git.commit().setMessage("create file").call();
+		try (Git git = new Git(db)) {
+			writeTrashFile("file.txt", "content");
+			git.add().addFilepattern("file.txt").call();
+			RevCommit commit = git.commit().setMessage("create file").call();
 
-		SubmoduleAddCommand command = new SubmoduleAddCommand(db);
-		String path = "sub";
-		command.setPath(path);
-		String uri = db.getDirectory().toURI().toString();
-		command.setURI(uri);
-		Repository repo = command.call();
-		assertNotNull(repo);
-		ObjectId subCommit = repo.resolve(Constants.HEAD);
-		repo.close();
+			SubmoduleAddCommand command = new SubmoduleAddCommand(db);
+			String path = "sub";
+			command.setPath(path);
+			String uri = db.getDirectory().toURI().toString();
+			command.setURI(uri);
+			Repository repo = command.call();
+			assertNotNull(repo);
+			ObjectId subCommit = repo.resolve(Constants.HEAD);
+			repo.close();
 
-		SubmoduleWalk generator = SubmoduleWalk.forIndex(db);
-		assertTrue(generator.next());
-		assertEquals(path, generator.getPath());
-		assertEquals(commit, generator.getObjectId());
-		assertEquals(uri, generator.getModulesUrl());
-		assertEquals(path, generator.getModulesPath());
-		assertEquals(uri, generator.getConfigUrl());
-		Repository subModRepo = generator.getRepository();
-		assertNotNull(subModRepo);
-		assertEquals(subCommit, commit);
-		subModRepo.close();
+			SubmoduleWalk generator = SubmoduleWalk.forIndex(db);
+			assertTrue(generator.next());
+			assertEquals(path, generator.getPath());
+			assertEquals(commit, generator.getObjectId());
+			assertEquals(uri, generator.getModulesUrl());
+			assertEquals(path, generator.getModulesPath());
+			assertEquals(uri, generator.getConfigUrl());
+			Repository subModRepo = generator.getRepository();
+			assertNotNull(subModRepo);
+			assertEquals(subCommit, commit);
+			subModRepo.close();
 
-		Status status = Git.wrap(db).status().call();
-		assertTrue(status.getAdded().contains(Constants.DOT_GIT_MODULES));
-		assertTrue(status.getAdded().contains(path));
+			Status status = Git.wrap(db).status().call();
+			assertTrue(status.getAdded().contains(Constants.DOT_GIT_MODULES));
+			assertTrue(status.getAdded().contains(path));
+		}
 	}
 
 	@Test
@@ -182,45 +183,47 @@ public void apply(DirCacheEntry ent) {
 
 	@Test
 	public void addSubmoduleWithRelativeUri() throws Exception {
-		Git git = new Git(db);
-		writeTrashFile("file.txt", "content");
-		git.add().addFilepattern("file.txt").call();
-		RevCommit commit = git.commit().setMessage("create file").call();
+		try (Git git = new Git(db)) {
+			writeTrashFile("file.txt", "content");
+			git.add().addFilepattern("file.txt").call();
+			RevCommit commit = git.commit().setMessage("create file").call();
 
-		SubmoduleAddCommand command = new SubmoduleAddCommand(db);
-		String path = "sub";
-		String uri = "./.git";
-		command.setPath(path);
-		command.setURI(uri);
-		Repository repo = command.call();
-		assertNotNull(repo);
-		addRepoToClose(repo);
+			SubmoduleAddCommand command = new SubmoduleAddCommand(db);
+			String path = "sub";
+			String uri = "./.git";
+			command.setPath(path);
+			command.setURI(uri);
+			Repository repo = command.call();
+			assertNotNull(repo);
+			addRepoToClose(repo);
 
-		SubmoduleWalk generator = SubmoduleWalk.forIndex(db);
-		assertTrue(generator.next());
-		assertEquals(path, generator.getPath());
-		assertEquals(commit, generator.getObjectId());
-		assertEquals(uri, generator.getModulesUrl());
-		assertEquals(path, generator.getModulesPath());
-		String fullUri = db.getDirectory().getAbsolutePath();
-		if (File.separatorChar == '\\')
-			fullUri = fullUri.replace('\\', '/');
-		assertEquals(fullUri, generator.getConfigUrl());
-		Repository subModRepo = generator.getRepository();
-		assertNotNull(subModRepo);
-		assertEquals(
-				fullUri,
-				subModRepo
-						.getConfig()
-						.getString(ConfigConstants.CONFIG_REMOTE_SECTION,
-								Constants.DEFAULT_REMOTE_NAME,
-								ConfigConstants.CONFIG_KEY_URL));
-		subModRepo.close();
-		assertEquals(commit, repo.resolve(Constants.HEAD));
+			SubmoduleWalk generator = SubmoduleWalk.forIndex(db);
+			assertTrue(generator.next());
+			assertEquals(path, generator.getPath());
+			assertEquals(commit, generator.getObjectId());
+			assertEquals(uri, generator.getModulesUrl());
+			assertEquals(path, generator.getModulesPath());
+			String fullUri = db.getDirectory().getAbsolutePath();
+			if (File.separatorChar == '\\') {
+				fullUri = fullUri.replace('\\', '/');
+			}
+			assertEquals(fullUri, generator.getConfigUrl());
+			Repository subModRepo = generator.getRepository();
+			assertNotNull(subModRepo);
+			assertEquals(
+					fullUri,
+					subModRepo
+							.getConfig()
+							.getString(ConfigConstants.CONFIG_REMOTE_SECTION,
+									Constants.DEFAULT_REMOTE_NAME,
+									ConfigConstants.CONFIG_KEY_URL));
+			subModRepo.close();
+			assertEquals(commit, repo.resolve(Constants.HEAD));
 
-		Status status = Git.wrap(db).status().call();
-		assertTrue(status.getAdded().contains(Constants.DOT_GIT_MODULES));
-		assertTrue(status.getAdded().contains(path));
+			Status status = Git.wrap(db).status().call();
+			assertTrue(status.getAdded().contains(Constants.DOT_GIT_MODULES));
+			assertTrue(status.getAdded().contains(path));
+		}
 	}
 
 	@Test
@@ -237,31 +240,32 @@ public void addSubmoduleWithExistingSubmoduleDefined() throws Exception {
 				path1, ConfigConstants.CONFIG_KEY_URL, url1);
 		modulesConfig.save();
 
-		Git git = new Git(db);
-		writeTrashFile("file.txt", "content");
-		git.add().addFilepattern("file.txt").call();
-		assertNotNull(git.commit().setMessage("create file").call());
+		try (Git git = new Git(db)) {
+			writeTrashFile("file.txt", "content");
+			git.add().addFilepattern("file.txt").call();
+			assertNotNull(git.commit().setMessage("create file").call());
 
-		SubmoduleAddCommand command = new SubmoduleAddCommand(db);
-		command.setPath(path2);
-		String url2 = db.getDirectory().toURI().toString();
-		command.setURI(url2);
-		Repository r = command.call();
-		assertNotNull(r);
-		addRepoToClose(r);
+			SubmoduleAddCommand command = new SubmoduleAddCommand(db);
+			command.setPath(path2);
+			String url2 = db.getDirectory().toURI().toString();
+			command.setURI(url2);
+			Repository r = command.call();
+			assertNotNull(r);
+			addRepoToClose(r);
 
-		modulesConfig.load();
-		assertEquals(path1, modulesConfig.getString(
-				ConfigConstants.CONFIG_SUBMODULE_SECTION, path1,
-				ConfigConstants.CONFIG_KEY_PATH));
-		assertEquals(url1, modulesConfig.getString(
-				ConfigConstants.CONFIG_SUBMODULE_SECTION, path1,
-				ConfigConstants.CONFIG_KEY_URL));
-		assertEquals(path2, modulesConfig.getString(
-				ConfigConstants.CONFIG_SUBMODULE_SECTION, path2,
-				ConfigConstants.CONFIG_KEY_PATH));
-		assertEquals(url2, modulesConfig.getString(
-				ConfigConstants.CONFIG_SUBMODULE_SECTION, path2,
-				ConfigConstants.CONFIG_KEY_URL));
+			modulesConfig.load();
+			assertEquals(path1, modulesConfig.getString(
+					ConfigConstants.CONFIG_SUBMODULE_SECTION, path1,
+					ConfigConstants.CONFIG_KEY_PATH));
+			assertEquals(url1, modulesConfig.getString(
+					ConfigConstants.CONFIG_SUBMODULE_SECTION, path1,
+					ConfigConstants.CONFIG_KEY_URL));
+			assertEquals(path2, modulesConfig.getString(
+					ConfigConstants.CONFIG_SUBMODULE_SECTION, path2,
+					ConfigConstants.CONFIG_KEY_PATH));
+			assertEquals(url2, modulesConfig.getString(
+					ConfigConstants.CONFIG_SUBMODULE_SECTION, path2,
+					ConfigConstants.CONFIG_KEY_URL));
+		}
 	}
 }
\ No newline at end of file
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/symlinks/SymlinksTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/symlinks/SymlinksTest.java
index 3ddc3de..274fa53 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/symlinks/SymlinksTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/symlinks/SymlinksTest.java
@@ -75,26 +75,27 @@ public void beforeMethod() {
 	 */
 	@Test
 	public void fileModeTestFileThenSymlink() throws Exception {
-		Git git = new Git(db);
-		writeTrashFile("a", "Hello world a");
-		writeTrashFile("b", "Hello world b");
-		git.add().addFilepattern(".").call();
-		git.commit().setMessage("add files a & b").call();
-		Ref branch_1 = git.branchCreate().setName("branch_1").call();
-		git.rm().addFilepattern("a").call();
-		FileUtils.createSymLink(new File(db.getWorkTree(), "a"), "b");
-		git.add().addFilepattern("a").call();
-		git.commit().setMessage("add symlink a").call();
+		try (Git git = new Git(db)) {
+			writeTrashFile("a", "Hello world a");
+			writeTrashFile("b", "Hello world b");
+			git.add().addFilepattern(".").call();
+			git.commit().setMessage("add files a & b").call();
+			Ref branch_1 = git.branchCreate().setName("branch_1").call();
+			git.rm().addFilepattern("a").call();
+			FileUtils.createSymLink(new File(db.getWorkTree(), "a"), "b");
+			git.add().addFilepattern("a").call();
+			git.commit().setMessage("add symlink a").call();
 
-		FileEntry entry = new FileTreeIterator.FileEntry(new File(
-				db.getWorkTree(), "a"), db.getFS());
-		assertEquals(FileMode.SYMLINK, entry.getMode());
+			FileEntry entry = new FileTreeIterator.FileEntry(new File(
+					db.getWorkTree(), "a"), db.getFS());
+			assertEquals(FileMode.SYMLINK, entry.getMode());
 
-		git.checkout().setName(branch_1.getName()).call();
+			git.checkout().setName(branch_1.getName()).call();
 
-		entry = new FileTreeIterator.FileEntry(new File(db.getWorkTree(), "a"),
-				db.getFS());
-		assertEquals(FileMode.REGULAR_FILE, entry.getMode());
+			entry = new FileTreeIterator.FileEntry(new File(db.getWorkTree(), "a"),
+					db.getFS());
+			assertEquals(FileMode.REGULAR_FILE, entry.getMode());
+		}
 	}
 
 	/**
@@ -108,26 +109,27 @@ public void fileModeTestFileThenSymlink() throws Exception {
 	 */
 	@Test
 	public void fileModeTestSymlinkThenFile() throws Exception {
-		Git git = new Git(db);
-		writeTrashFile("b", "Hello world b");
-		FileUtils.createSymLink(new File(db.getWorkTree(), "a"), "b");
-		git.add().addFilepattern(".").call();
-		git.commit().setMessage("add file b & symlink a").call();
-		Ref branch_1 = git.branchCreate().setName("branch_1").call();
-		git.rm().addFilepattern("a").call();
-		writeTrashFile("a", "Hello world a");
-		git.add().addFilepattern("a").call();
-		git.commit().setMessage("add file a").call();
+		try (Git git = new Git(db)) {
+			writeTrashFile("b", "Hello world b");
+			FileUtils.createSymLink(new File(db.getWorkTree(), "a"), "b");
+			git.add().addFilepattern(".").call();
+			git.commit().setMessage("add file b & symlink a").call();
+			Ref branch_1 = git.branchCreate().setName("branch_1").call();
+			git.rm().addFilepattern("a").call();
+			writeTrashFile("a", "Hello world a");
+			git.add().addFilepattern("a").call();
+			git.commit().setMessage("add file a").call();
 
-		FileEntry entry = new FileTreeIterator.FileEntry(new File(
-				db.getWorkTree(), "a"), db.getFS());
-		assertEquals(FileMode.REGULAR_FILE, entry.getMode());
+			FileEntry entry = new FileTreeIterator.FileEntry(new File(
+					db.getWorkTree(), "a"), db.getFS());
+			assertEquals(FileMode.REGULAR_FILE, entry.getMode());
 
-		git.checkout().setName(branch_1.getName()).call();
+			git.checkout().setName(branch_1.getName()).call();
 
-		entry = new FileTreeIterator.FileEntry(new File(db.getWorkTree(), "a"),
-				db.getFS());
-		assertEquals(FileMode.SYMLINK, entry.getMode());
+			entry = new FileTreeIterator.FileEntry(new File(db.getWorkTree(), "a"),
+					db.getFS());
+			assertEquals(FileMode.SYMLINK, entry.getMode());
+		}
 	}
 
 	/**
@@ -141,27 +143,28 @@ public void fileModeTestSymlinkThenFile() throws Exception {
 	 */
 	@Test
 	public void fileModeTestFolderThenSymlink() throws Exception {
-		Git git = new Git(db);
-		FileUtils.mkdirs(new File(db.getWorkTree(), "a"));
-		writeTrashFile("a/b", "Hello world b");
-		writeTrashFile("c", "Hello world c");
-		git.add().addFilepattern(".").call();
-		git.commit().setMessage("add folder a").call();
-		Ref branch_1 = git.branchCreate().setName("branch_1").call();
-		git.rm().addFilepattern("a").call();
-		FileUtils.createSymLink(new File(db.getWorkTree(), "a"), "c");
-		git.add().addFilepattern("a").call();
-		git.commit().setMessage("add symlink a").call();
+		try (Git git = new Git(db)) {
+			FileUtils.mkdirs(new File(db.getWorkTree(), "a"));
+			writeTrashFile("a/b", "Hello world b");
+			writeTrashFile("c", "Hello world c");
+			git.add().addFilepattern(".").call();
+			git.commit().setMessage("add folder a").call();
+			Ref branch_1 = git.branchCreate().setName("branch_1").call();
+			git.rm().addFilepattern("a").call();
+			FileUtils.createSymLink(new File(db.getWorkTree(), "a"), "c");
+			git.add().addFilepattern("a").call();
+			git.commit().setMessage("add symlink a").call();
 
-		FileEntry entry = new FileTreeIterator.FileEntry(new File(
-				db.getWorkTree(), "a"), db.getFS());
-		assertEquals(FileMode.SYMLINK, entry.getMode());
+			FileEntry entry = new FileTreeIterator.FileEntry(new File(
+					db.getWorkTree(), "a"), db.getFS());
+			assertEquals(FileMode.SYMLINK, entry.getMode());
 
-		git.checkout().setName(branch_1.getName()).call();
+			git.checkout().setName(branch_1.getName()).call();
 
-		entry = new FileTreeIterator.FileEntry(new File(db.getWorkTree(), "a"),
-				db.getFS());
-		assertEquals(FileMode.TREE, entry.getMode());
+			entry = new FileTreeIterator.FileEntry(new File(db.getWorkTree(), "a"),
+					db.getFS());
+			assertEquals(FileMode.TREE, entry.getMode());
+		}
 	}
 
 	/**
@@ -175,27 +178,28 @@ public void fileModeTestFolderThenSymlink() throws Exception {
 	 */
 	@Test
 	public void fileModeTestSymlinkThenFolder() throws Exception {
-		Git git = new Git(db);
-		writeTrashFile("c", "Hello world c");
-		FileUtils.createSymLink(new File(db.getWorkTree(), "a"), "c");
-		git.add().addFilepattern(".").call();
-		git.commit().setMessage("add symlink a").call();
-		Ref branch_1 = git.branchCreate().setName("branch_1").call();
-		git.rm().addFilepattern("a").call();
-		FileUtils.mkdirs(new File(db.getWorkTree(), "a"));
-		writeTrashFile("a/b", "Hello world b");
-		git.add().addFilepattern("a").call();
-		git.commit().setMessage("add folder a").call();
+		try (Git git = new Git(db)) {
+			writeTrashFile("c", "Hello world c");
+			FileUtils.createSymLink(new File(db.getWorkTree(), "a"), "c");
+			git.add().addFilepattern(".").call();
+			git.commit().setMessage("add symlink a").call();
+			Ref branch_1 = git.branchCreate().setName("branch_1").call();
+			git.rm().addFilepattern("a").call();
+			FileUtils.mkdirs(new File(db.getWorkTree(), "a"));
+			writeTrashFile("a/b", "Hello world b");
+			git.add().addFilepattern("a").call();
+			git.commit().setMessage("add folder a").call();
 
-		FileEntry entry = new FileTreeIterator.FileEntry(new File(
-				db.getWorkTree(), "a"), db.getFS());
-		assertEquals(FileMode.TREE, entry.getMode());
+			FileEntry entry = new FileTreeIterator.FileEntry(new File(
+					db.getWorkTree(), "a"), db.getFS());
+			assertEquals(FileMode.TREE, entry.getMode());
 
-		git.checkout().setName(branch_1.getName()).call();
+			git.checkout().setName(branch_1.getName()).call();
 
-		entry = new FileTreeIterator.FileEntry(new File(db.getWorkTree(), "a"),
-				db.getFS());
-		assertEquals(FileMode.SYMLINK, entry.getMode());
+			entry = new FileTreeIterator.FileEntry(new File(db.getWorkTree(), "a"),
+					db.getFS());
+			assertEquals(FileMode.SYMLINK, entry.getMode());
+		}
 	}
 
 	/**
@@ -209,24 +213,25 @@ public void fileModeTestSymlinkThenFolder() throws Exception {
 	 */
 	@Test
 	public void fileModeTestMissingThenSymlink() throws Exception {
-		Git git = new Git(db);
-		writeTrashFile("b", "Hello world b");
-		git.add().addFilepattern(".").call();
-		RevCommit commit1 = git.commit().setMessage("add file b").call();
-		Ref branch_1 = git.branchCreate().setName("branch_1").call();
-		FileUtils.createSymLink(new File(db.getWorkTree(), "a"), "b");
-		git.add().addFilepattern("a").call();
-		RevCommit commit2 = git.commit().setMessage("add symlink a").call();
+		try (Git git = new Git(db);
+				TreeWalk tw = new TreeWalk(db);) {
+			writeTrashFile("b", "Hello world b");
+			git.add().addFilepattern(".").call();
+			RevCommit commit1 = git.commit().setMessage("add file b").call();
+			Ref branch_1 = git.branchCreate().setName("branch_1").call();
+			FileUtils.createSymLink(new File(db.getWorkTree(), "a"), "b");
+			git.add().addFilepattern("a").call();
+			RevCommit commit2 = git.commit().setMessage("add symlink a").call();
 
-		git.checkout().setName(branch_1.getName()).call();
+			git.checkout().setName(branch_1.getName()).call();
 
-		TreeWalk tw = new TreeWalk(db);
-		tw.addTree(commit1.getTree());
-		tw.addTree(commit2.getTree());
-		List<DiffEntry> scan = DiffEntry.scan(tw);
-		assertEquals(1, scan.size());
-		assertEquals(FileMode.SYMLINK, scan.get(0).getNewMode());
-		assertEquals(FileMode.MISSING, scan.get(0).getOldMode());
+			tw.addTree(commit1.getTree());
+			tw.addTree(commit2.getTree());
+			List<DiffEntry> scan = DiffEntry.scan(tw);
+			assertEquals(1, scan.size());
+			assertEquals(FileMode.SYMLINK, scan.get(0).getNewMode());
+			assertEquals(FileMode.MISSING, scan.get(0).getOldMode());
+		}
 	}
 
 	/**
@@ -240,97 +245,101 @@ public void fileModeTestMissingThenSymlink() throws Exception {
 	 */
 	@Test
 	public void fileModeTestSymlinkThenMissing() throws Exception {
-		Git git = new Git(db);
-		writeTrashFile("b", "Hello world b");
-		FileUtils.createSymLink(new File(db.getWorkTree(), "a"), "b");
-		git.add().addFilepattern(".").call();
-		RevCommit commit1 = git.commit().setMessage("add file b & symlink a")
-				.call();
-		Ref branch_1 = git.branchCreate().setName("branch_1").call();
-		git.rm().addFilepattern("a").call();
-		RevCommit commit2 = git.commit().setMessage("delete symlink a").call();
+		try (Git git = new Git(db);
+				TreeWalk tw = new TreeWalk(db);) {
+			writeTrashFile("b", "Hello world b");
+			FileUtils.createSymLink(new File(db.getWorkTree(), "a"), "b");
+			git.add().addFilepattern(".").call();
+			RevCommit commit1 = git.commit().setMessage("add file b & symlink a")
+					.call();
+			Ref branch_1 = git.branchCreate().setName("branch_1").call();
+			git.rm().addFilepattern("a").call();
+			RevCommit commit2 = git.commit().setMessage("delete symlink a").call();
 
-		git.checkout().setName(branch_1.getName()).call();
+			git.checkout().setName(branch_1.getName()).call();
 
-		TreeWalk tw = new TreeWalk(db);
-		tw.addTree(commit1.getTree());
-		tw.addTree(commit2.getTree());
-		List<DiffEntry> scan = DiffEntry.scan(tw);
-		assertEquals(1, scan.size());
-		assertEquals(FileMode.MISSING, scan.get(0).getNewMode());
-		assertEquals(FileMode.SYMLINK, scan.get(0).getOldMode());
+			tw.addTree(commit1.getTree());
+			tw.addTree(commit2.getTree());
+			List<DiffEntry> scan = DiffEntry.scan(tw);
+			assertEquals(1, scan.size());
+			assertEquals(FileMode.MISSING, scan.get(0).getNewMode());
+			assertEquals(FileMode.SYMLINK, scan.get(0).getOldMode());
+		}
 	}
 
 	@Test
 	public void createSymlinkAfterTarget() throws Exception {
-		Git git = new Git(db);
-		writeTrashFile("a", "start");
-		git.add().addFilepattern("a").call();
-		RevCommit base = git.commit().setMessage("init").call();
-		writeTrashFile("target", "someData");
-		FileUtils.createSymLink(new File(db.getWorkTree(), "link"), "target");
-		git.add().addFilepattern("target").addFilepattern("link").call();
-		git.commit().setMessage("add target").call();
-		assertEquals(4, db.getWorkTree().list().length); // self-check
-		git.checkout().setName(base.name()).call();
-		assertEquals(2, db.getWorkTree().list().length); // self-check
-		git.checkout().setName("master").call();
-		assertEquals(4, db.getWorkTree().list().length);
-		String data = read(new File(db.getWorkTree(), "target"));
-		assertEquals(8, new File(db.getWorkTree(), "target").length());
-		assertEquals("someData", data);
-		data = read(new File(db.getWorkTree(), "link"));
-		assertEquals("target",
-				FileUtils.readSymLink(new File(db.getWorkTree(), "link")));
-		assertEquals("someData", data);
+		try (Git git = new Git(db)) {
+			writeTrashFile("a", "start");
+			git.add().addFilepattern("a").call();
+			RevCommit base = git.commit().setMessage("init").call();
+			writeTrashFile("target", "someData");
+			FileUtils.createSymLink(new File(db.getWorkTree(), "link"), "target");
+			git.add().addFilepattern("target").addFilepattern("link").call();
+			git.commit().setMessage("add target").call();
+			assertEquals(4, db.getWorkTree().list().length); // self-check
+			git.checkout().setName(base.name()).call();
+			assertEquals(2, db.getWorkTree().list().length); // self-check
+			git.checkout().setName("master").call();
+			assertEquals(4, db.getWorkTree().list().length);
+			String data = read(new File(db.getWorkTree(), "target"));
+			assertEquals(8, new File(db.getWorkTree(), "target").length());
+			assertEquals("someData", data);
+			data = read(new File(db.getWorkTree(), "link"));
+			assertEquals("target",
+					FileUtils.readSymLink(new File(db.getWorkTree(), "link")));
+			assertEquals("someData", data);
+		}
 	}
 
 	@Test
 	public void createFileSymlinkBeforeTarget() throws Exception {
-		Git git = new Git(db);
-		writeTrashFile("a", "start");
-		git.add().addFilepattern("a").call();
-		RevCommit base = git.commit().setMessage("init").call();
-		writeTrashFile("target", "someData");
-		FileUtils.createSymLink(new File(db.getWorkTree(), "tlink"), "target");
-		git.add().addFilepattern("target").addFilepattern("tlink").call();
-		git.commit().setMessage("add target").call();
-		assertEquals(4, db.getWorkTree().list().length); // self-check
-		git.checkout().setName(base.name()).call();
-		assertEquals(2, db.getWorkTree().list().length); // self-check
-		git.checkout().setName("master").call();
-		assertEquals(4, db.getWorkTree().list().length);
-		String data = read(new File(db.getWorkTree(), "target"));
-		assertEquals(8, new File(db.getWorkTree(), "target").length());
-		assertEquals("someData", data);
-		data = read(new File(db.getWorkTree(), "tlink"));
-		assertEquals("target",
-				FileUtils.readSymLink(new File(db.getWorkTree(), "tlink")));
-		assertEquals("someData", data);
+		try (Git git = new Git(db)) {
+			writeTrashFile("a", "start");
+			git.add().addFilepattern("a").call();
+			RevCommit base = git.commit().setMessage("init").call();
+			writeTrashFile("target", "someData");
+			FileUtils.createSymLink(new File(db.getWorkTree(), "tlink"), "target");
+			git.add().addFilepattern("target").addFilepattern("tlink").call();
+			git.commit().setMessage("add target").call();
+			assertEquals(4, db.getWorkTree().list().length); // self-check
+			git.checkout().setName(base.name()).call();
+			assertEquals(2, db.getWorkTree().list().length); // self-check
+			git.checkout().setName("master").call();
+			assertEquals(4, db.getWorkTree().list().length);
+			String data = read(new File(db.getWorkTree(), "target"));
+			assertEquals(8, new File(db.getWorkTree(), "target").length());
+			assertEquals("someData", data);
+			data = read(new File(db.getWorkTree(), "tlink"));
+			assertEquals("target",
+					FileUtils.readSymLink(new File(db.getWorkTree(), "tlink")));
+			assertEquals("someData", data);
+		}
 	}
 
 	@Test
 	public void createDirSymlinkBeforeTarget() throws Exception {
-		Git git = new Git(db);
-		writeTrashFile("a", "start");
-		git.add().addFilepattern("a").call();
-		RevCommit base = git.commit().setMessage("init").call();
-		FileUtils.createSymLink(new File(db.getWorkTree(), "link"), "target");
-		FileUtils.mkdir(new File(db.getWorkTree(), "target"));
-		writeTrashFile("target/file", "someData");
-		git.add().addFilepattern("target").addFilepattern("link").call();
-		git.commit().setMessage("add target").call();
-		assertEquals(4, db.getWorkTree().list().length); // self-check
-		git.checkout().setName(base.name()).call();
-		assertEquals(2, db.getWorkTree().list().length); // self-check
-		git.checkout().setName("master").call();
-		assertEquals(4, db.getWorkTree().list().length);
-		String data = read(new File(db.getWorkTree(), "target/file"));
-		assertEquals(8, new File(db.getWorkTree(), "target/file").length());
-		assertEquals("someData", data);
-		data = read(new File(db.getWorkTree(), "link/file"));
-		assertEquals("target",
-				FileUtils.readSymLink(new File(db.getWorkTree(), "link")));
-		assertEquals("someData", data);
+		try (Git git = new Git(db)) {
+			writeTrashFile("a", "start");
+			git.add().addFilepattern("a").call();
+			RevCommit base = git.commit().setMessage("init").call();
+			FileUtils.createSymLink(new File(db.getWorkTree(), "link"), "target");
+			FileUtils.mkdir(new File(db.getWorkTree(), "target"));
+			writeTrashFile("target/file", "someData");
+			git.add().addFilepattern("target").addFilepattern("link").call();
+			git.commit().setMessage("add target").call();
+			assertEquals(4, db.getWorkTree().list().length); // self-check
+			git.checkout().setName(base.name()).call();
+			assertEquals(2, db.getWorkTree().list().length); // self-check
+			git.checkout().setName("master").call();
+			assertEquals(4, db.getWorkTree().list().length);
+			String data = read(new File(db.getWorkTree(), "target/file"));
+			assertEquals(8, new File(db.getWorkTree(), "target/file").length());
+			assertEquals("someData", data);
+			data = read(new File(db.getWorkTree(), "link/file"));
+			assertEquals("target",
+					FileUtils.readSymLink(new File(db.getWorkTree(), "link")));
+			assertEquals("someData", data);
+		}
 	}
 }
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 767e13d..df17a3e 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
@@ -255,10 +255,11 @@ public void testComputeFileObjectId() throws Exception {
 	@Test
 	public void testDirCacheMatchingId() throws Exception {
 		File f = writeTrashFile("file", "content");
-		Git git = new Git(db);
-		writeTrashFile("file", "content");
-		fsTick(f);
-		git.add().addFilepattern("file").call();
+		try (Git git = new Git(db)) {
+			writeTrashFile("file", "content");
+			fsTick(f);
+			git.add().addFilepattern("file").call();
+		}
 		DirCacheEntry dce = db.readDirCache().getEntry("file");
 		TreeWalk tw = new TreeWalk(db);
 		FileTreeIterator fti = new FileTreeIterator(trash, db.getFS(), db
@@ -282,11 +283,12 @@ public void testDirCacheMatchingId() throws Exception {
 	@Test
 	public void testIsModifiedSymlinkAsFile() throws Exception {
 		writeTrashFile("symlink", "content");
-		Git git = new Git(db);
-		db.getConfig().setString(ConfigConstants.CONFIG_CORE_SECTION, null,
-				ConfigConstants.CONFIG_KEY_SYMLINKS, "false");
-		git.add().addFilepattern("symlink").call();
-		git.commit().setMessage("commit").call();
+		try (Git git = new Git(db)) {
+			db.getConfig().setString(ConfigConstants.CONFIG_CORE_SECTION, null,
+					ConfigConstants.CONFIG_KEY_SYMLINKS, "false");
+			git.add().addFilepattern("symlink").call();
+			git.commit().setMessage("commit").call();
+		}
 
 		// Modify previously committed DirCacheEntry and write it back to disk
 		DirCacheEntry dce = db.readDirCache().getEntry("symlink");
@@ -305,20 +307,21 @@ public void testIsModifiedSymlinkAsFile() throws Exception {
 	@Test
 	public void testIsModifiedFileSmudged() throws Exception {
 		File f = writeTrashFile("file", "content");
-		Git git = new Git(db);
-		// The idea of this test is to check the smudged handling
-		// Hopefully fsTick will make sure our entry gets smudged
-		fsTick(f);
-		writeTrashFile("file", "content");
-		long lastModified = f.lastModified();
-		git.add().addFilepattern("file").call();
-		writeTrashFile("file", "conten2");
-		f.setLastModified(lastModified);
-		// We cannot trust this to go fast enough on
-		// a system with less than one-second lastModified
-		// resolution, so we force the index to have the
-		// same timestamp as the file we look at.
-		db.getIndexFile().setLastModified(lastModified);
+		try (Git git = new Git(db)) {
+			// The idea of this test is to check the smudged handling
+			// Hopefully fsTick will make sure our entry gets smudged
+			fsTick(f);
+			writeTrashFile("file", "content");
+			long lastModified = f.lastModified();
+			git.add().addFilepattern("file").call();
+			writeTrashFile("file", "conten2");
+			f.setLastModified(lastModified);
+			// We cannot trust this to go fast enough on
+			// a system with less than one-second lastModified
+			// resolution, so we force the index to have the
+			// same timestamp as the file we look at.
+			db.getIndexFile().setLastModified(lastModified);
+		}
 		DirCacheEntry dce = db.readDirCache().getEntry("file");
 		FileTreeIterator fti = new FileTreeIterator(trash, db.getFS(), db
 				.getConfig().get(WorkingTreeOptions.KEY));
@@ -334,198 +337,204 @@ public void testIsModifiedFileSmudged() throws Exception {
 
 	@Test
 	public void submoduleHeadMatchesIndex() throws Exception {
-		Git git = new Git(db);
-		writeTrashFile("file.txt", "content");
-		git.add().addFilepattern("file.txt").call();
-		final RevCommit id = git.commit().setMessage("create file").call();
-		final String path = "sub";
-		DirCache cache = db.lockDirCache();
-		DirCacheEditor editor = cache.editor();
-		editor.add(new PathEdit(path) {
+		try (Git git = new Git(db);
+				TreeWalk walk = new TreeWalk(db)) {
+			writeTrashFile("file.txt", "content");
+			git.add().addFilepattern("file.txt").call();
+			final RevCommit id = git.commit().setMessage("create file").call();
+			final String path = "sub";
+			DirCache cache = db.lockDirCache();
+			DirCacheEditor editor = cache.editor();
+			editor.add(new PathEdit(path) {
+	
+				public void apply(DirCacheEntry ent) {
+					ent.setFileMode(FileMode.GITLINK);
+					ent.setObjectId(id);
+				}
+			});
+			editor.commit();
 
-			public void apply(DirCacheEntry ent) {
-				ent.setFileMode(FileMode.GITLINK);
-				ent.setObjectId(id);
-			}
-		});
-		editor.commit();
+			Git.cloneRepository().setURI(db.getDirectory().toURI().toString())
+					.setDirectory(new File(db.getWorkTree(), path)).call()
+					.getRepository().close();
 
-		Git.cloneRepository().setURI(db.getDirectory().toURI().toString())
-				.setDirectory(new File(db.getWorkTree(), path)).call()
-				.getRepository().close();
-
-		TreeWalk walk = new TreeWalk(db);
-		DirCacheIterator indexIter = new DirCacheIterator(db.readDirCache());
-		FileTreeIterator workTreeIter = new FileTreeIterator(db);
-		walk.addTree(indexIter);
-		walk.addTree(workTreeIter);
-		walk.setFilter(PathFilter.create(path));
-
-		assertTrue(walk.next());
-		assertTrue(indexIter.idEqual(workTreeIter));
+			DirCacheIterator indexIter = new DirCacheIterator(db.readDirCache());
+			FileTreeIterator workTreeIter = new FileTreeIterator(db);
+			walk.addTree(indexIter);
+			walk.addTree(workTreeIter);
+			walk.setFilter(PathFilter.create(path));
+	
+			assertTrue(walk.next());
+			assertTrue(indexIter.idEqual(workTreeIter));
+		}
 	}
 
 	@Test
 	public void submoduleWithNoGitDirectory() throws Exception {
-		Git git = new Git(db);
-		writeTrashFile("file.txt", "content");
-		git.add().addFilepattern("file.txt").call();
-		final RevCommit id = git.commit().setMessage("create file").call();
-		final String path = "sub";
-		DirCache cache = db.lockDirCache();
-		DirCacheEditor editor = cache.editor();
-		editor.add(new PathEdit(path) {
+		try (Git git = new Git(db);
+				TreeWalk walk = new TreeWalk(db)) {
+			writeTrashFile("file.txt", "content");
+			git.add().addFilepattern("file.txt").call();
+			final RevCommit id = git.commit().setMessage("create file").call();
+			final String path = "sub";
+			DirCache cache = db.lockDirCache();
+			DirCacheEditor editor = cache.editor();
+			editor.add(new PathEdit(path) {
 
-			public void apply(DirCacheEntry ent) {
-				ent.setFileMode(FileMode.GITLINK);
-				ent.setObjectId(id);
-			}
-		});
-		editor.commit();
+				public void apply(DirCacheEntry ent) {
+					ent.setFileMode(FileMode.GITLINK);
+					ent.setObjectId(id);
+				}
+			});
+			editor.commit();
 
-		File submoduleRoot = new File(db.getWorkTree(), path);
-		assertTrue(submoduleRoot.mkdir());
-		assertTrue(new File(submoduleRoot, Constants.DOT_GIT).mkdir());
+			File submoduleRoot = new File(db.getWorkTree(), path);
+			assertTrue(submoduleRoot.mkdir());
+			assertTrue(new File(submoduleRoot, Constants.DOT_GIT).mkdir());
 
-		TreeWalk walk = new TreeWalk(db);
-		DirCacheIterator indexIter = new DirCacheIterator(db.readDirCache());
-		FileTreeIterator workTreeIter = new FileTreeIterator(db);
-		walk.addTree(indexIter);
-		walk.addTree(workTreeIter);
-		walk.setFilter(PathFilter.create(path));
+			DirCacheIterator indexIter = new DirCacheIterator(db.readDirCache());
+			FileTreeIterator workTreeIter = new FileTreeIterator(db);
+			walk.addTree(indexIter);
+			walk.addTree(workTreeIter);
+			walk.setFilter(PathFilter.create(path));
 
-		assertTrue(walk.next());
-		assertFalse(indexIter.idEqual(workTreeIter));
-		assertEquals(ObjectId.zeroId(), workTreeIter.getEntryObjectId());
+			assertTrue(walk.next());
+			assertFalse(indexIter.idEqual(workTreeIter));
+			assertEquals(ObjectId.zeroId(), workTreeIter.getEntryObjectId());
+		}
 	}
 
 	@Test
 	public void submoduleWithNoHead() throws Exception {
-		Git git = new Git(db);
-		writeTrashFile("file.txt", "content");
-		git.add().addFilepattern("file.txt").call();
-		final RevCommit id = git.commit().setMessage("create file").call();
-		final String path = "sub";
-		DirCache cache = db.lockDirCache();
-		DirCacheEditor editor = cache.editor();
-		editor.add(new PathEdit(path) {
+		try (Git git = new Git(db);
+				TreeWalk walk = new TreeWalk(db)) {
+			writeTrashFile("file.txt", "content");
+			git.add().addFilepattern("file.txt").call();
+			final RevCommit id = git.commit().setMessage("create file").call();
+			final String path = "sub";
+			DirCache cache = db.lockDirCache();
+			DirCacheEditor editor = cache.editor();
+			editor.add(new PathEdit(path) {
 
-			public void apply(DirCacheEntry ent) {
-				ent.setFileMode(FileMode.GITLINK);
-				ent.setObjectId(id);
-			}
-		});
-		editor.commit();
+				public void apply(DirCacheEntry ent) {
+					ent.setFileMode(FileMode.GITLINK);
+					ent.setObjectId(id);
+				}
+			});
+			editor.commit();
 
-		assertNotNull(Git.init().setDirectory(new File(db.getWorkTree(), path))
-				.call().getRepository());
+			assertNotNull(Git.init().setDirectory(new File(db.getWorkTree(), path))
+					.call().getRepository());
 
-		TreeWalk walk = new TreeWalk(db);
-		DirCacheIterator indexIter = new DirCacheIterator(db.readDirCache());
-		FileTreeIterator workTreeIter = new FileTreeIterator(db);
-		walk.addTree(indexIter);
-		walk.addTree(workTreeIter);
-		walk.setFilter(PathFilter.create(path));
+			DirCacheIterator indexIter = new DirCacheIterator(db.readDirCache());
+			FileTreeIterator workTreeIter = new FileTreeIterator(db);
+			walk.addTree(indexIter);
+			walk.addTree(workTreeIter);
+			walk.setFilter(PathFilter.create(path));
 
-		assertTrue(walk.next());
-		assertFalse(indexIter.idEqual(workTreeIter));
-		assertEquals(ObjectId.zeroId(), workTreeIter.getEntryObjectId());
+			assertTrue(walk.next());
+			assertFalse(indexIter.idEqual(workTreeIter));
+			assertEquals(ObjectId.zeroId(), workTreeIter.getEntryObjectId());
+		}
 	}
 
 	@Test
 	public void submoduleDirectoryIterator() throws Exception {
-		Git git = new Git(db);
-		writeTrashFile("file.txt", "content");
-		git.add().addFilepattern("file.txt").call();
-		final RevCommit id = git.commit().setMessage("create file").call();
-		final String path = "sub";
-		DirCache cache = db.lockDirCache();
-		DirCacheEditor editor = cache.editor();
-		editor.add(new PathEdit(path) {
+		try (Git git = new Git(db);
+				TreeWalk walk = new TreeWalk(db)) {
+			writeTrashFile("file.txt", "content");
+			git.add().addFilepattern("file.txt").call();
+			final RevCommit id = git.commit().setMessage("create file").call();
+			final String path = "sub";
+			DirCache cache = db.lockDirCache();
+			DirCacheEditor editor = cache.editor();
+			editor.add(new PathEdit(path) {
 
-			public void apply(DirCacheEntry ent) {
-				ent.setFileMode(FileMode.GITLINK);
-				ent.setObjectId(id);
-			}
-		});
-		editor.commit();
+				public void apply(DirCacheEntry ent) {
+					ent.setFileMode(FileMode.GITLINK);
+					ent.setObjectId(id);
+				}
+			});
+			editor.commit();
 
-		Git.cloneRepository().setURI(db.getDirectory().toURI().toString())
-				.setDirectory(new File(db.getWorkTree(), path)).call()
-				.getRepository().close();
+			Git.cloneRepository().setURI(db.getDirectory().toURI().toString())
+					.setDirectory(new File(db.getWorkTree(), path)).call()
+					.getRepository().close();
 
-		TreeWalk walk = new TreeWalk(db);
-		DirCacheIterator indexIter = new DirCacheIterator(db.readDirCache());
-		FileTreeIterator workTreeIter = new FileTreeIterator(db.getWorkTree(),
-				db.getFS(), db.getConfig().get(WorkingTreeOptions.KEY));
-		walk.addTree(indexIter);
-		walk.addTree(workTreeIter);
-		walk.setFilter(PathFilter.create(path));
+			DirCacheIterator indexIter = new DirCacheIterator(db.readDirCache());
+			FileTreeIterator workTreeIter = new FileTreeIterator(db.getWorkTree(),
+					db.getFS(), db.getConfig().get(WorkingTreeOptions.KEY));
+			walk.addTree(indexIter);
+			walk.addTree(workTreeIter);
+			walk.setFilter(PathFilter.create(path));
 
-		assertTrue(walk.next());
-		assertTrue(indexIter.idEqual(workTreeIter));
+			assertTrue(walk.next());
+			assertTrue(indexIter.idEqual(workTreeIter));
+		}
 	}
 
 	@Test
 	public void submoduleNestedWithHeadMatchingIndex() throws Exception {
-		Git git = new Git(db);
-		writeTrashFile("file.txt", "content");
-		git.add().addFilepattern("file.txt").call();
-		final RevCommit id = git.commit().setMessage("create file").call();
-		final String path = "sub/dir1/dir2";
-		DirCache cache = db.lockDirCache();
-		DirCacheEditor editor = cache.editor();
-		editor.add(new PathEdit(path) {
+		try (Git git = new Git(db);
+				TreeWalk walk = new TreeWalk(db)) {
+			writeTrashFile("file.txt", "content");
+			git.add().addFilepattern("file.txt").call();
+			final RevCommit id = git.commit().setMessage("create file").call();
+			final String path = "sub/dir1/dir2";
+			DirCache cache = db.lockDirCache();
+			DirCacheEditor editor = cache.editor();
+			editor.add(new PathEdit(path) {
 
-			public void apply(DirCacheEntry ent) {
-				ent.setFileMode(FileMode.GITLINK);
-				ent.setObjectId(id);
-			}
-		});
-		editor.commit();
+				public void apply(DirCacheEntry ent) {
+					ent.setFileMode(FileMode.GITLINK);
+					ent.setObjectId(id);
+				}
+			});
+			editor.commit();
 
-		Git.cloneRepository().setURI(db.getDirectory().toURI().toString())
-				.setDirectory(new File(db.getWorkTree(), path)).call()
-				.getRepository().close();
+			Git.cloneRepository().setURI(db.getDirectory().toURI().toString())
+					.setDirectory(new File(db.getWorkTree(), path)).call()
+					.getRepository().close();
 
-		TreeWalk walk = new TreeWalk(db);
-		DirCacheIterator indexIter = new DirCacheIterator(db.readDirCache());
-		FileTreeIterator workTreeIter = new FileTreeIterator(db);
-		walk.addTree(indexIter);
-		walk.addTree(workTreeIter);
-		walk.setFilter(PathFilter.create(path));
+			DirCacheIterator indexIter = new DirCacheIterator(db.readDirCache());
+			FileTreeIterator workTreeIter = new FileTreeIterator(db);
+			walk.addTree(indexIter);
+			walk.addTree(workTreeIter);
+			walk.setFilter(PathFilter.create(path));
 
-		assertTrue(walk.next());
-		assertTrue(indexIter.idEqual(workTreeIter));
+			assertTrue(walk.next());
+			assertTrue(indexIter.idEqual(workTreeIter));
+		}
 	}
 
 	@Test
 	public void idOffset() throws Exception {
-		Git git = new Git(db);
-		writeTrashFile("fileAinfsonly", "A");
-		File fileBinindex = writeTrashFile("fileBinindex", "B");
-		fsTick(fileBinindex);
-		git.add().addFilepattern("fileBinindex").call();
-		writeTrashFile("fileCinfsonly", "C");
-		TreeWalk tw = new TreeWalk(db);
-		DirCacheIterator indexIter = new DirCacheIterator(db.readDirCache());
-		FileTreeIterator workTreeIter = new FileTreeIterator(db);
-		tw.addTree(indexIter);
-		tw.addTree(workTreeIter);
-		workTreeIter.setDirCacheIterator(tw, 0);
-		assertEntry("d46c305e85b630558ee19cc47e73d2e5c8c64cdc", "a,", tw);
-		assertEntry("58ee403f98538ec02409538b3f80adf610accdec", "a,b", tw);
-		assertEntry("0000000000000000000000000000000000000000", "a", tw);
-		assertEntry("b8d30ff397626f0f1d3538d66067edf865e201d6", "a0b", tw);
-		// The reason for adding this test. Check that the id is correct for
-		// mixed
-		assertEntry("8c7e5a667f1b771847fe88c01c3de34413a1b220",
-				"fileAinfsonly", tw);
-		assertEntry("7371f47a6f8bd23a8fa1a8b2a9479cdd76380e54", "fileBinindex",
-				tw);
-		assertEntry("96d80cd6c4e7158dbebd0849f4fb7ce513e5828c",
-				"fileCinfsonly", tw);
-		assertFalse(tw.next());
+		try (Git git = new Git(db);
+				TreeWalk tw = new TreeWalk(db)) {
+			writeTrashFile("fileAinfsonly", "A");
+			File fileBinindex = writeTrashFile("fileBinindex", "B");
+			fsTick(fileBinindex);
+			git.add().addFilepattern("fileBinindex").call();
+			writeTrashFile("fileCinfsonly", "C");
+			DirCacheIterator indexIter = new DirCacheIterator(db.readDirCache());
+			FileTreeIterator workTreeIter = new FileTreeIterator(db);
+			tw.addTree(indexIter);
+			tw.addTree(workTreeIter);
+			workTreeIter.setDirCacheIterator(tw, 0);
+			assertEntry("d46c305e85b630558ee19cc47e73d2e5c8c64cdc", "a,", tw);
+			assertEntry("58ee403f98538ec02409538b3f80adf610accdec", "a,b", tw);
+			assertEntry("0000000000000000000000000000000000000000", "a", tw);
+			assertEntry("b8d30ff397626f0f1d3538d66067edf865e201d6", "a0b", tw);
+			// The reason for adding this test. Check that the id is correct for
+			// mixed
+			assertEntry("8c7e5a667f1b771847fe88c01c3de34413a1b220",
+					"fileAinfsonly", tw);
+			assertEntry("7371f47a6f8bd23a8fa1a8b2a9479cdd76380e54", "fileBinindex",
+					tw);
+			assertEntry("96d80cd6c4e7158dbebd0849f4fb7ce513e5828c",
+					"fileCinfsonly", tw);
+			assertFalse(tw.next());
+		}
 	}
 
 	private static void assertEntry(String sha1string, String path, TreeWalk tw)
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/PostOrderTreeWalkTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/PostOrderTreeWalkTest.java
index acbbb39..6ad47c2 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/PostOrderTreeWalkTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/PostOrderTreeWalkTest.java
@@ -60,124 +60,124 @@
 public class PostOrderTreeWalkTest extends RepositoryTestCase {
 	@Test
 	public void testInitialize_NoPostOrder() throws Exception {
-		final TreeWalk tw = new TreeWalk(db);
-		assertFalse(tw.isPostOrderTraversal());
+		try (final TreeWalk tw = new TreeWalk(db)) {
+			assertFalse(tw.isPostOrderTraversal());
+		}
 	}
 
 	@Test
 	public void testInitialize_TogglePostOrder() throws Exception {
-		final TreeWalk tw = new TreeWalk(db);
-		assertFalse(tw.isPostOrderTraversal());
-		tw.setPostOrderTraversal(true);
-		assertTrue(tw.isPostOrderTraversal());
-		tw.setPostOrderTraversal(false);
-		assertFalse(tw.isPostOrderTraversal());
+		try (final TreeWalk tw = new TreeWalk(db)) {
+			assertFalse(tw.isPostOrderTraversal());
+			tw.setPostOrderTraversal(true);
+			assertTrue(tw.isPostOrderTraversal());
+			tw.setPostOrderTraversal(false);
+			assertFalse(tw.isPostOrderTraversal());
+		}
 	}
 
 	@Test
 	public void testResetDoesNotAffectPostOrder() throws Exception {
-		final TreeWalk tw = new TreeWalk(db);
-		tw.setPostOrderTraversal(true);
-		assertTrue(tw.isPostOrderTraversal());
-		tw.reset();
-		assertTrue(tw.isPostOrderTraversal());
+		try (final TreeWalk tw = new TreeWalk(db)) {
+			tw.setPostOrderTraversal(true);
+			assertTrue(tw.isPostOrderTraversal());
+			tw.reset();
+			assertTrue(tw.isPostOrderTraversal());
 
-		tw.setPostOrderTraversal(false);
-		assertFalse(tw.isPostOrderTraversal());
-		tw.reset();
-		assertFalse(tw.isPostOrderTraversal());
+			tw.setPostOrderTraversal(false);
+			assertFalse(tw.isPostOrderTraversal());
+			tw.reset();
+			assertFalse(tw.isPostOrderTraversal());
+		}
 	}
 
 	@Test
 	public void testNoPostOrder() throws Exception {
 		final DirCache tree = db.readDirCache();
-		{
-			final DirCacheBuilder b = tree.builder();
+		final DirCacheBuilder b = tree.builder();
 
-			b.add(makeFile("a"));
-			b.add(makeFile("b/c"));
-			b.add(makeFile("b/d"));
-			b.add(makeFile("q"));
+		b.add(makeFile("a"));
+		b.add(makeFile("b/c"));
+		b.add(makeFile("b/d"));
+		b.add(makeFile("q"));
 
-			b.finish();
-			assertEquals(4, tree.getEntryCount());
+		b.finish();
+		assertEquals(4, tree.getEntryCount());
+
+		try (final TreeWalk tw = new TreeWalk(db)) {
+			tw.setPostOrderTraversal(false);
+			tw.addTree(new DirCacheIterator(tree));
+
+			assertModes("a", REGULAR_FILE, tw);
+			assertModes("b", TREE, tw);
+			assertTrue(tw.isSubtree());
+			assertFalse(tw.isPostChildren());
+			tw.enterSubtree();
+			assertModes("b/c", REGULAR_FILE, tw);
+			assertModes("b/d", REGULAR_FILE, tw);
+			assertModes("q", REGULAR_FILE, tw);
 		}
-
-		final TreeWalk tw = new TreeWalk(db);
-		tw.setPostOrderTraversal(false);
-		tw.addTree(new DirCacheIterator(tree));
-
-		assertModes("a", REGULAR_FILE, tw);
-		assertModes("b", TREE, tw);
-		assertTrue(tw.isSubtree());
-		assertFalse(tw.isPostChildren());
-		tw.enterSubtree();
-		assertModes("b/c", REGULAR_FILE, tw);
-		assertModes("b/d", REGULAR_FILE, tw);
-		assertModes("q", REGULAR_FILE, tw);
 	}
 
 	@Test
 	public void testWithPostOrder_EnterSubtree() throws Exception {
 		final DirCache tree = db.readDirCache();
-		{
-			final DirCacheBuilder b = tree.builder();
+		final DirCacheBuilder b = tree.builder();
 
-			b.add(makeFile("a"));
-			b.add(makeFile("b/c"));
-			b.add(makeFile("b/d"));
-			b.add(makeFile("q"));
+		b.add(makeFile("a"));
+		b.add(makeFile("b/c"));
+		b.add(makeFile("b/d"));
+		b.add(makeFile("q"));
 
-			b.finish();
-			assertEquals(4, tree.getEntryCount());
+		b.finish();
+		assertEquals(4, tree.getEntryCount());
+
+		try (final TreeWalk tw = new TreeWalk(db)) {
+			tw.setPostOrderTraversal(true);
+			tw.addTree(new DirCacheIterator(tree));
+
+			assertModes("a", REGULAR_FILE, tw);
+
+			assertModes("b", TREE, tw);
+			assertTrue(tw.isSubtree());
+			assertFalse(tw.isPostChildren());
+			tw.enterSubtree();
+			assertModes("b/c", REGULAR_FILE, tw);
+			assertModes("b/d", REGULAR_FILE, tw);
+
+			assertModes("b", TREE, tw);
+			assertTrue(tw.isSubtree());
+			assertTrue(tw.isPostChildren());
+
+			assertModes("q", REGULAR_FILE, tw);
 		}
-
-		final TreeWalk tw = new TreeWalk(db);
-		tw.setPostOrderTraversal(true);
-		tw.addTree(new DirCacheIterator(tree));
-
-		assertModes("a", REGULAR_FILE, tw);
-
-		assertModes("b", TREE, tw);
-		assertTrue(tw.isSubtree());
-		assertFalse(tw.isPostChildren());
-		tw.enterSubtree();
-		assertModes("b/c", REGULAR_FILE, tw);
-		assertModes("b/d", REGULAR_FILE, tw);
-
-		assertModes("b", TREE, tw);
-		assertTrue(tw.isSubtree());
-		assertTrue(tw.isPostChildren());
-
-		assertModes("q", REGULAR_FILE, tw);
 	}
 
 	@Test
 	public void testWithPostOrder_NoEnterSubtree() throws Exception {
 		final DirCache tree = db.readDirCache();
-		{
-			final DirCacheBuilder b = tree.builder();
+		final DirCacheBuilder b = tree.builder();
 
-			b.add(makeFile("a"));
-			b.add(makeFile("b/c"));
-			b.add(makeFile("b/d"));
-			b.add(makeFile("q"));
+		b.add(makeFile("a"));
+		b.add(makeFile("b/c"));
+		b.add(makeFile("b/d"));
+		b.add(makeFile("q"));
 
-			b.finish();
-			assertEquals(4, tree.getEntryCount());
+		b.finish();
+		assertEquals(4, tree.getEntryCount());
+
+		try (final TreeWalk tw = new TreeWalk(db)) {
+			tw.setPostOrderTraversal(true);
+			tw.addTree(new DirCacheIterator(tree));
+
+			assertModes("a", REGULAR_FILE, tw);
+
+			assertModes("b", TREE, tw);
+			assertTrue(tw.isSubtree());
+			assertFalse(tw.isPostChildren());
+
+			assertModes("q", REGULAR_FILE, tw);
 		}
-
-		final TreeWalk tw = new TreeWalk(db);
-		tw.setPostOrderTraversal(true);
-		tw.addTree(new DirCacheIterator(tree));
-
-		assertModes("a", REGULAR_FILE, tw);
-
-		assertModes("b", TREE, tw);
-		assertTrue(tw.isSubtree());
-		assertFalse(tw.isPostChildren());
-
-		assertModes("q", REGULAR_FILE, tw);
 	}
 
 	private DirCacheEntry makeFile(final String path) throws Exception {
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/TreeWalkJava7Test.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/TreeWalkJava7Test.java
index 1328b38..ba8f194 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/TreeWalkJava7Test.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/TreeWalkJava7Test.java
@@ -60,13 +60,14 @@ public void testSymlinkToDirNotRecursingViaSymlink() throws Exception {
 		assertTrue(fs.supportsSymlinks());
 		writeTrashFile("target/data", "targetdata");
 		fs.createSymLink(new File(trash, "link"), "target");
-		TreeWalk tw = new TreeWalk(db);
-		tw.setRecursive(true);
-		tw.addTree(new FileTreeIterator(db));
-		assertTrue(tw.next());
-		assertEquals("link", tw.getPathString());
-		assertTrue(tw.next());
-		assertEquals("target/data", tw.getPathString());
-		assertFalse(tw.next());
+		try (TreeWalk tw = new TreeWalk(db)) {
+			tw.setRecursive(true);
+			tw.addTree(new FileTreeIterator(db));
+			assertTrue(tw.next());
+			assertEquals("link", tw.getPathString());
+			assertTrue(tw.next());
+			assertEquals("target/data", tw.getPathString());
+			assertFalse(tw.next());
+		}
 	}
 }
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/filter/PathSuffixFilterTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/filter/PathSuffixFilterTest.java
index d871c5e..3885c41 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/filter/PathSuffixFilterTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/filter/PathSuffixFilterTest.java
@@ -113,15 +113,16 @@ private List<String> getMatchingPaths(String suffixFilter,
 
 	private List<String> getMatchingPaths(String suffixFilter,
 			final ObjectId treeId, boolean recursiveWalk) throws IOException {
-		final TreeWalk tw = new TreeWalk(db);
-		tw.setFilter(PathSuffixFilter.create(suffixFilter));
-		tw.setRecursive(recursiveWalk);
-		tw.addTree(treeId);
+		try (final TreeWalk tw = new TreeWalk(db)) {
+			tw.setFilter(PathSuffixFilter.create(suffixFilter));
+			tw.setRecursive(recursiveWalk);
+			tw.addTree(treeId);
 
-		List<String> paths = new ArrayList<String>();
-		while (tw.next())
-			paths.add(tw.getPathString());
-		return paths;
+			List<String> paths = new ArrayList<String>();
+			while (tw.next())
+				paths.add(tw.getPathString());
+			return paths;
+		}
 	}
 
 }
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/filter/TreeFilterTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/filter/TreeFilterTest.java
index 09007e7..c3423b6 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/filter/TreeFilterTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/filter/TreeFilterTest.java
@@ -55,9 +55,10 @@
 public class TreeFilterTest extends RepositoryTestCase {
 	@Test
 	public void testALL_IncludesAnything() throws Exception {
-		final TreeWalk tw = new TreeWalk(db);
-		tw.addTree(new EmptyTreeIterator());
-		assertTrue(TreeFilter.ALL.include(tw));
+		try (final TreeWalk tw = new TreeWalk(db)) {
+			tw.addTree(new EmptyTreeIterator());
+			assertTrue(TreeFilter.ALL.include(tw));
+		}
 	}
 
 	@Test
@@ -72,16 +73,18 @@ public void testALL_IdentityClone() throws Exception {
 
 	@Test
 	public void testNotALL_IncludesNothing() throws Exception {
-		final TreeWalk tw = new TreeWalk(db);
-		tw.addTree(new EmptyTreeIterator());
-		assertFalse(TreeFilter.ALL.negate().include(tw));
+		try (final TreeWalk tw = new TreeWalk(db)) {
+			tw.addTree(new EmptyTreeIterator());
+			assertFalse(TreeFilter.ALL.negate().include(tw));
+		}
 	}
 
 	@Test
 	public void testANY_DIFF_IncludesSingleTreeCase() throws Exception {
-		final TreeWalk tw = new TreeWalk(db);
-		tw.addTree(new EmptyTreeIterator());
-		assertTrue(TreeFilter.ANY_DIFF.include(tw));
+		try (final TreeWalk tw = new TreeWalk(db)) {
+			tw.addTree(new EmptyTreeIterator());
+			assertTrue(TreeFilter.ANY_DIFF.include(tw));
+		}
 	}
 
 	@Test
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/NBTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/NBTest.java
index 06cb11b..7e11a61 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/NBTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/NBTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008, Google Inc.
+ * Copyright (C) 2008, 2015 Google Inc.
  * and other copyright owners as documented in the project's IP log.
  *
  * This program and the accompanying materials are made available
@@ -61,6 +61,17 @@ public void testCompareUInt32() {
 	}
 
 	@Test
+	public void testCompareUInt64() {
+		assertTrue(NB.compareUInt64(0, 0) == 0);
+		assertTrue(NB.compareUInt64(1, 0) > 0);
+		assertTrue(NB.compareUInt64(0, 1) < 0);
+		assertTrue(NB.compareUInt64(-1, 0) > 0);
+		assertTrue(NB.compareUInt64(0, -1) < 0);
+		assertTrue(NB.compareUInt64(-1, 1) > 0);
+		assertTrue(NB.compareUInt64(1, -1) < 0);
+	}
+
+	@Test
 	public void testDecodeUInt16() {
 		assertEquals(0, NB.decodeUInt16(b(0, 0), 0));
 		assertEquals(0, NB.decodeUInt16(padb(3, 0, 0), 3));
diff --git a/org.eclipse.jgit/.settings/.api_filters b/org.eclipse.jgit/.settings/.api_filters
index 36041f8..a5000dd 100644
--- a/org.eclipse.jgit/.settings/.api_filters
+++ b/org.eclipse.jgit/.settings/.api_filters
@@ -1,115 +1,18 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <component id="org.eclipse.jgit" version="2">
-    <resource path="META-INF/MANIFEST.MF" type="org.eclipse.jgit.lib.FileTreeEntry">
-        <filter id="305324134">
-            <message_arguments>
-                <message_argument value="org.eclipse.jgit.lib.FileTreeEntry"/>
-                <message_argument value="org.eclipse.jgit_4.2.0"/>
-            </message_arguments>
-        </filter>
-    </resource>
-    <resource path="META-INF/MANIFEST.MF" type="org.eclipse.jgit.lib.GitlinkTreeEntry">
-        <filter id="305324134">
-            <message_arguments>
-                <message_argument value="org.eclipse.jgit.lib.GitlinkTreeEntry"/>
-                <message_argument value="org.eclipse.jgit_4.2.0"/>
-            </message_arguments>
-        </filter>
-    </resource>
-    <resource path="META-INF/MANIFEST.MF" type="org.eclipse.jgit.lib.SymlinkTreeEntry">
-        <filter id="305324134">
-            <message_arguments>
-                <message_argument value="org.eclipse.jgit.lib.SymlinkTreeEntry"/>
-                <message_argument value="org.eclipse.jgit_4.2.0"/>
-            </message_arguments>
-        </filter>
-    </resource>
-    <resource path="META-INF/MANIFEST.MF" type="org.eclipse.jgit.lib.Tree">
-        <filter id="305324134">
-            <message_arguments>
-                <message_argument value="org.eclipse.jgit.lib.Tree"/>
-                <message_argument value="org.eclipse.jgit_4.2.0"/>
-            </message_arguments>
-        </filter>
-    </resource>
-    <resource path="META-INF/MANIFEST.MF" type="org.eclipse.jgit.lib.TreeEntry">
-        <filter id="305324134">
-            <message_arguments>
-                <message_argument value="org.eclipse.jgit.lib.TreeEntry"/>
-                <message_argument value="org.eclipse.jgit_4.2.0"/>
-            </message_arguments>
-        </filter>
-    </resource>
     <resource path="src/org/eclipse/jgit/attributes/AttributesNode.java" type="org.eclipse.jgit.attributes.AttributesNode">
-        <filter comment="attributes weren't really usable in earlier versions" id="338792546">
+        <filter comment="moved to new AttributesManager" id="338792546">
             <message_arguments>
                 <message_argument value="org.eclipse.jgit.attributes.AttributesNode"/>
-                <message_argument value="getAttributes(String, boolean, Map&lt;String,Attribute&gt;)"/>
+                <message_argument value="getAttributes(String, boolean, Attributes)"/>
             </message_arguments>
         </filter>
     </resource>
-    <resource path="src/org/eclipse/jgit/lib/BitmapIndex.java" type="org.eclipse.jgit.lib.BitmapIndex$BitmapBuilder">
-        <filter comment="interface is implemented by extenders but not clients of the API" id="403804204">
+    <resource path="src/org/eclipse/jgit/attributes/AttributesRule.java" type="org.eclipse.jgit.attributes.AttributesRule">
+        <filter comment="used only in tests: bean naming" id="338792546">
             <message_arguments>
-                <message_argument value="org.eclipse.jgit.lib.BitmapIndex.BitmapBuilder"/>
-                <message_argument value="addObject(AnyObjectId, int)"/>
-            </message_arguments>
-        </filter>
-        <filter comment="interface is implemented by extenders but not clients of the API" id="403804204">
-            <message_arguments>
-                <message_argument value="org.eclipse.jgit.lib.BitmapIndex.BitmapBuilder"/>
-                <message_argument value="getBitmapIndex()"/>
-            </message_arguments>
-        </filter>
-    </resource>
-    <resource path="src/org/eclipse/jgit/lib/Repository.java" type="org.eclipse.jgit.lib.Repository">
-        <filter comment="Only implementors of Repository are affected. That should be allowed" id="336695337">
-            <message_arguments>
-                <message_argument value="org.eclipse.jgit.lib.Repository"/>
-                <message_argument value="createAttributesNodeProvider()"/>
-            </message_arguments>
-        </filter>
-    </resource>
-    <resource path="src/org/eclipse/jgit/transport/PushCertificate.java" type="org.eclipse.jgit.transport.PushCertificate">
-        <filter comment="PushCertificate wasn't really usable in 4.0" id="338722907">
-            <message_arguments>
-                <message_argument value="org.eclipse.jgit.transport.PushCertificate"/>
-                <message_argument value="PushCertificate()"/>
-            </message_arguments>
-        </filter>
-        <filter comment="PushCertificate wasn't really usable in 4.0" id="338792546">
-            <message_arguments>
-                <message_argument value="org.eclipse.jgit.transport.PushCertificate"/>
-                <message_argument value="getCommandList()"/>
-            </message_arguments>
-        </filter>
-    </resource>
-    <resource path="src/org/eclipse/jgit/transport/PushCertificateParser.java" type="org.eclipse.jgit.transport.PushCertificateParser">
-        <filter comment="PushCertificates haven't been really usable in 4.0" id="338849923">
-            <message_arguments>
-                <message_argument value="org.eclipse.jgit.transport.PushCertificateParser"/>
-            </message_arguments>
-        </filter>
-    </resource>
-    <resource path="src/org/eclipse/jgit/treewalk/WorkingTreeIterator.java" type="org.eclipse.jgit.treewalk.WorkingTreeIterator">
-        <filter comment="attributes weren't really usable in earlier versions" id="338792546">
-            <message_arguments>
-                <message_argument value="org.eclipse.jgit.treewalk.WorkingTreeIterator"/>
-                <message_argument value="getGlobalAttributesNode()"/>
-            </message_arguments>
-        </filter>
-        <filter comment="attributes weren't really usable in earlier versions" id="338792546">
-            <message_arguments>
-                <message_argument value="org.eclipse.jgit.treewalk.WorkingTreeIterator"/>
-                <message_argument value="getInfoAttributesNode()"/>
-            </message_arguments>
-        </filter>
-    </resource>
-    <resource path="src/org/eclipse/jgit/util/FileUtils.java" type="org.eclipse.jgit.util.FileUtils">
-        <filter id="338792546">
-            <message_arguments>
-                <message_argument value="org.eclipse.jgit.util.FileUtils"/>
-                <message_argument value="createSymLink(File, String)"/>
+                <message_argument value="org.eclipse.jgit.attributes.AttributesRule"/>
+                <message_argument value="dirOnly()"/>
             </message_arguments>
         </filter>
     </resource>
diff --git a/org.eclipse.jgit/META-INF/MANIFEST.MF b/org.eclipse.jgit/META-INF/MANIFEST.MF
index f263a5c..3e155a7 100644
--- a/org.eclipse.jgit/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit/META-INF/MANIFEST.MF
@@ -66,8 +66,9 @@
    org.eclipse.jgit.junit,
    org.eclipse.jgit.junit.http,
    org.eclipse.jgit.http.server,
-   org.eclipse.jgit.pgm.test,
-   org.eclipse.jgit.pgm",
+   org.eclipse.jgit.lfs.server,
+   org.eclipse.jgit.pgm,
+   org.eclipse.jgit.pgm.test",
  org.eclipse.jgit.internal.storage.pack;version="4.3.0";x-friends:="org.eclipse.jgit.junit,org.eclipse.jgit.test,org.eclipse.jgit.pgm",
  org.eclipse.jgit.internal.storage.reftree;version="4.3.0";x-friends:="org.eclipse.jgit.junit,org.eclipse.jgit.test,org.eclipse.jgit.pgm",
  org.eclipse.jgit.lib;version="4.3.0";
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/CommitCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/CommitCommand.java
index b5057ad..0abb8ba 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/CommitCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/CommitCommand.java
@@ -312,7 +312,7 @@ public RevCommit call() throws GitAPIException, NoHeadException,
 		}
 	}
 
-	private void insertChangeId(ObjectId treeId) throws IOException {
+	private void insertChangeId(ObjectId treeId) {
 		ObjectId firstParentId = null;
 		if (!parents.isEmpty())
 			firstParentId = parents.get(0);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/attributes/AttributesHandler.java b/org.eclipse.jgit/src/org/eclipse/jgit/attributes/AttributesHandler.java
new file mode 100644
index 0000000..19e4afd
--- /dev/null
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/attributes/AttributesHandler.java
@@ -0,0 +1,434 @@
+/*
+ * Copyright (C) 2015, Ivan Motsch <ivan.motsch@bsiag.com>
+ *
+ * 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.attributes;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Map;
+
+import org.eclipse.jgit.annotations.Nullable;
+import org.eclipse.jgit.attributes.Attribute.State;
+import org.eclipse.jgit.dircache.DirCacheIterator;
+import org.eclipse.jgit.lib.FileMode;
+import org.eclipse.jgit.treewalk.AbstractTreeIterator;
+import org.eclipse.jgit.treewalk.CanonicalTreeParser;
+import org.eclipse.jgit.treewalk.TreeWalk;
+import org.eclipse.jgit.treewalk.WorkingTreeIterator;
+import org.eclipse.jgit.treewalk.TreeWalk.OperationType;
+
+/**
+ * The attributes handler knows how to retrieve, parse and merge attributes from
+ * the various gitattributes files. Furthermore it collects and expands macro
+ * expressions. The method {@link #getAttributes()} yields the ready processed
+ * attributes for the current path represented by the {@link TreeWalk}
+ * <p>
+ * The implementation is based on the specifications in
+ * http://git-scm.com/docs/gitattributes
+ *
+ * @since 4.3
+ */
+public class AttributesHandler {
+	private static final String MACRO_PREFIX = "[attr]"; //$NON-NLS-1$
+
+	private static final String BINARY_RULE_KEY = "binary"; //$NON-NLS-1$
+
+	/**
+	 * This is the default <b>binary</b> rule that is present in any git folder
+	 * <code>[attr]binary -diff -merge -text</code>
+	 */
+	private static final List<Attribute> BINARY_RULE_ATTRIBUTES = new AttributesRule(
+			MACRO_PREFIX + BINARY_RULE_KEY, "-diff -merge -text") //$NON-NLS-1$
+					.getAttributes();
+
+	private final TreeWalk treeWalk;
+
+	private final AttributesNode globalNode;
+
+	private final AttributesNode infoNode;
+
+	private final Map<String, List<Attribute>> expansions = new HashMap<>();
+
+	/**
+	 * Create an {@link AttributesHandler} with default rules as well as merged
+	 * rules from global, info and worktree root attributes
+	 *
+	 * @param treeWalk
+	 * @throws IOException
+	 */
+	public AttributesHandler(TreeWalk treeWalk) throws IOException {
+		this.treeWalk = treeWalk;
+		AttributesNodeProvider attributesNodeProvider =treeWalk.getAttributesNodeProvider();
+		this.globalNode = attributesNodeProvider != null
+				? attributesNodeProvider.getGlobalAttributesNode() : null;
+		this.infoNode = attributesNodeProvider != null
+				? attributesNodeProvider.getInfoAttributesNode() : null;
+
+		AttributesNode rootNode = attributesNode(treeWalk,
+				rootOf(
+						treeWalk.getTree(WorkingTreeIterator.class)),
+				rootOf(
+						treeWalk.getTree(DirCacheIterator.class)),
+				rootOf(treeWalk
+						.getTree(CanonicalTreeParser.class)));
+
+		expansions.put(BINARY_RULE_KEY, BINARY_RULE_ATTRIBUTES);
+		for (AttributesNode node : new AttributesNode[] { globalNode, rootNode,
+				infoNode }) {
+			if (node == null) {
+				continue;
+			}
+			for (AttributesRule rule : node.getRules()) {
+				if (rule.getPattern().startsWith(MACRO_PREFIX)) {
+					expansions.put(rule.getPattern()
+							.substring(MACRO_PREFIX.length()).trim(),
+							rule.getAttributes());
+				}
+			}
+		}
+	}
+
+	/**
+	 * see {@link TreeWalk#getAttributes()}
+	 *
+	 * @return the {@link Attributes} for the current path represented by the
+	 *         {@link TreeWalk}
+	 * @throws IOException
+	 */
+	public Attributes getAttributes() throws IOException {
+		String entryPath = treeWalk.getPathString();
+		boolean isDirectory = (treeWalk.getFileMode() == FileMode.TREE);
+		Attributes attributes = new Attributes();
+
+		// Gets the info attributes
+		mergeInfoAttributes(entryPath, isDirectory, attributes);
+
+		// Gets the attributes located on the current entry path
+		mergePerDirectoryEntryAttributes(entryPath, isDirectory,
+				treeWalk.getTree(WorkingTreeIterator.class),
+				treeWalk.getTree(DirCacheIterator.class),
+				treeWalk.getTree(CanonicalTreeParser.class),
+				attributes);
+
+		// Gets the attributes located in the global attribute file
+		mergeGlobalAttributes(entryPath, isDirectory, attributes);
+
+		// now after all attributes are collected - in the correct hierarchy
+		// order - remove all unspecified entries (the ! marker)
+		for (Attribute a : attributes.getAll()) {
+			if (a.getState() == State.UNSPECIFIED)
+				attributes.remove(a.getKey());
+		}
+
+		return attributes;
+	}
+
+	/**
+	 * Merges the matching GLOBAL attributes for an entry path.
+	 *
+	 * @param entryPath
+	 *            the path to test. The path must be relative to this attribute
+	 *            node's own repository path, and in repository path format
+	 *            (uses '/' and not '\').
+	 * @param isDirectory
+	 *            true if the target item is a directory.
+	 * @param result
+	 *            that will hold the attributes matching this entry path. This
+	 *            method will NOT override any existing entry in attributes.
+	 */
+	private void mergeGlobalAttributes(String entryPath, boolean isDirectory,
+			Attributes result) {
+		mergeAttributes(globalNode, entryPath, isDirectory, result);
+	}
+
+	/**
+	 * Merges the matching INFO attributes for an entry path.
+	 *
+	 * @param entryPath
+	 *            the path to test. The path must be relative to this attribute
+	 *            node's own repository path, and in repository path format
+	 *            (uses '/' and not '\').
+	 * @param isDirectory
+	 *            true if the target item is a directory.
+	 * @param result
+	 *            that will hold the attributes matching this entry path. This
+	 *            method will NOT override any existing entry in attributes.
+	 */
+	private void mergeInfoAttributes(String entryPath, boolean isDirectory,
+			Attributes result) {
+		mergeAttributes(infoNode, entryPath, isDirectory, result);
+	}
+
+	/**
+	 * Merges the matching working directory attributes for an entry path.
+	 *
+	 * @param entryPath
+	 *            the path to test. The path must be relative to this attribute
+	 *            node's own repository path, and in repository path format
+	 *            (uses '/' and not '\').
+	 * @param isDirectory
+	 *            true if the target item is a directory.
+	 * @param workingTreeIterator
+	 * @param dirCacheIterator
+	 * @param otherTree
+	 * @param result
+	 *            that will hold the attributes matching this entry path. This
+	 *            method will NOT override any existing entry in attributes.
+	 * @throws IOException
+	 */
+	private void mergePerDirectoryEntryAttributes(String entryPath,
+			boolean isDirectory,
+			@Nullable WorkingTreeIterator workingTreeIterator,
+			@Nullable DirCacheIterator dirCacheIterator,
+			@Nullable CanonicalTreeParser otherTree, Attributes result)
+					throws IOException {
+		// Prevents infinite recurrence
+		if (workingTreeIterator != null || dirCacheIterator != null
+				|| otherTree != null) {
+			AttributesNode attributesNode = attributesNode(
+					treeWalk, workingTreeIterator, dirCacheIterator, otherTree);
+			if (attributesNode != null) {
+				mergeAttributes(attributesNode, entryPath, isDirectory, result);
+			}
+			mergePerDirectoryEntryAttributes(entryPath, isDirectory,
+					parentOf(workingTreeIterator), parentOf(dirCacheIterator),
+					parentOf(otherTree), result);
+		}
+	}
+
+	/**
+	 * Merges the matching node attributes for an entry path.
+	 *
+	 * @param node
+	 *            the node to scan for matches to entryPath
+	 * @param entryPath
+	 *            the path to test. The path must be relative to this attribute
+	 *            node's own repository path, and in repository path format
+	 *            (uses '/' and not '\').
+	 * @param isDirectory
+	 *            true if the target item is a directory.
+	 * @param result
+	 *            that will hold the attributes matching this entry path. This
+	 *            method will NOT override any existing entry in attributes.
+	 */
+	protected void mergeAttributes(@Nullable AttributesNode node,
+			String entryPath,
+			boolean isDirectory, Attributes result) {
+		if (node == null)
+			return;
+		List<AttributesRule> rules = node.getRules();
+		// Parse rules in the reverse order that they were read since the last
+		// entry should be used
+		ListIterator<AttributesRule> ruleIterator = rules
+				.listIterator(rules.size());
+		while (ruleIterator.hasPrevious()) {
+			AttributesRule rule = ruleIterator.previous();
+			if (rule.isMatch(entryPath, isDirectory)) {
+				ListIterator<Attribute> attributeIte = rule.getAttributes()
+						.listIterator(rule.getAttributes().size());
+				// Parses the attributes in the reverse order that they were
+				// read since the last entry should be used
+				while (attributeIte.hasPrevious()) {
+					expandMacro(attributeIte.previous(), result);
+				}
+			}
+		}
+	}
+
+	/**
+	 * @param attr
+	 * @param result
+	 *            contains the (recursive) expanded and merged macro attributes
+	 *            including the attribute iself
+	 */
+	protected void expandMacro(Attribute attr, Attributes result) {
+		// loop detection = exists check
+		if (result.containsKey(attr.getKey()))
+			return;
+
+		// also add macro to result set, same does native git
+		result.put(attr);
+
+		List<Attribute> expansion = expansions.get(attr.getKey());
+		if (expansion == null) {
+			return;
+		}
+		switch (attr.getState()) {
+		case UNSET: {
+			for (Attribute e : expansion) {
+				switch (e.getState()) {
+				case SET:
+					expandMacro(new Attribute(e.getKey(), State.UNSET), result);
+					break;
+				case UNSET:
+					expandMacro(new Attribute(e.getKey(), State.SET), result);
+					break;
+				case UNSPECIFIED:
+					expandMacro(new Attribute(e.getKey(), State.UNSPECIFIED),
+							result);
+					break;
+				case CUSTOM:
+				default:
+					expandMacro(e, result);
+				}
+			}
+			break;
+		}
+		case CUSTOM: {
+			for (Attribute e : expansion) {
+				switch (e.getState()) {
+				case SET:
+				case UNSET:
+				case UNSPECIFIED:
+					expandMacro(e, result);
+					break;
+				case CUSTOM:
+				default:
+					expandMacro(new Attribute(e.getKey(), attr.getValue()),
+							result);
+				}
+			}
+			break;
+		}
+		case UNSPECIFIED: {
+			for (Attribute e : expansion) {
+				expandMacro(new Attribute(e.getKey(), State.UNSPECIFIED),
+						result);
+			}
+			break;
+		}
+		case SET:
+		default:
+			for (Attribute e : expansion) {
+				expandMacro(e, result);
+			}
+			break;
+		}
+	}
+
+	/**
+	 * Get the {@link AttributesNode} for the current entry.
+	 * <p>
+	 * This method implements the fallback mechanism between the index and the
+	 * working tree depending on the operation type
+	 * </p>
+	 *
+	 * @param treeWalk
+	 * @param workingTreeIterator
+	 * @param dirCacheIterator
+	 * @param otherTree
+	 * @return a {@link AttributesNode} of the current entry,
+	 *         {@link NullPointerException} otherwise.
+	 * @throws IOException
+	 *             It raises an {@link IOException} if a problem appears while
+	 *             parsing one on the attributes file.
+	 */
+	private static AttributesNode attributesNode(TreeWalk treeWalk,
+			@Nullable WorkingTreeIterator workingTreeIterator,
+			@Nullable DirCacheIterator dirCacheIterator,
+			@Nullable CanonicalTreeParser otherTree) throws IOException {
+		AttributesNode attributesNode = null;
+		switch (treeWalk.getOperationType()) {
+		case CHECKIN_OP:
+			if (workingTreeIterator != null) {
+				attributesNode = workingTreeIterator.getEntryAttributesNode();
+			}
+			if (attributesNode == null && dirCacheIterator != null) {
+				attributesNode = dirCacheIterator
+						.getEntryAttributesNode(treeWalk.getObjectReader());
+			}
+			if (attributesNode == null && otherTree != null) {
+				attributesNode = otherTree
+						.getEntryAttributesNode(treeWalk.getObjectReader());
+			}
+			break;
+		case CHECKOUT_OP:
+			if (otherTree != null) {
+				attributesNode = otherTree
+						.getEntryAttributesNode(treeWalk.getObjectReader());
+			}
+			if (attributesNode == null && dirCacheIterator != null) {
+				attributesNode = dirCacheIterator
+						.getEntryAttributesNode(treeWalk.getObjectReader());
+			}
+			if (attributesNode == null && workingTreeIterator != null) {
+				attributesNode = workingTreeIterator.getEntryAttributesNode();
+			}
+			break;
+		default:
+			throw new IllegalStateException(
+					"The only supported operation types are:" //$NON-NLS-1$
+							+ OperationType.CHECKIN_OP + "," //$NON-NLS-1$
+							+ OperationType.CHECKOUT_OP);
+		}
+
+		return attributesNode;
+	}
+
+	private static <T extends AbstractTreeIterator> T parentOf(@Nullable T node) {
+		if(node==null) return null;
+		@SuppressWarnings("unchecked")
+		Class<T> type = (Class<T>) node.getClass();
+		AbstractTreeIterator parent = node.parent;
+		if (type.isInstance(parent)) {
+			return type.cast(parent);
+		}
+		return null;
+	}
+
+	private static <T extends AbstractTreeIterator> T rootOf(
+			@Nullable T node) {
+		if(node==null) return null;
+		AbstractTreeIterator t=node;
+		while (t!= null && t.parent != null) {
+			t= t.parent;
+		}
+		@SuppressWarnings("unchecked")
+		Class<T> type = (Class<T>) node.getClass();
+		if (type.isInstance(t)) {
+			return type.cast(t);
+		}
+		return null;
+	}
+
+}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/attributes/AttributesNode.java b/org.eclipse.jgit/src/org/eclipse/jgit/attributes/AttributesNode.java
index 5c0aba2..7196502 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/attributes/AttributesNode.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/attributes/AttributesNode.java
@@ -49,7 +49,6 @@
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
-import java.util.ListIterator;
 
 import org.eclipse.jgit.lib.Constants;
 
@@ -122,40 +121,4 @@ public List<AttributesRule> getRules() {
 		return Collections.unmodifiableList(rules);
 	}
 
-	/**
-	 * Returns the matching attributes for an entry path.
-	 *
-	 * @param entryPath
-	 *            the path to test. The path must be relative to this attribute
-	 *            node's own repository path, and in repository path format
-	 *            (uses '/' and not '\').
-	 * @param isDirectory
-	 *            true if the target item is a directory.
-	 * @param attributes
-	 *            Map that will hold the attributes matching this entry path. If
-	 *            it is not empty, this method will NOT override any existing
-	 *            entry.
-	 * @since 4.2
-	 */
-	public void getAttributes(String entryPath,
-			boolean isDirectory, Attributes attributes) {
-		// Parse rules in the reverse order that they were read since the last
-		// entry should be used
-		ListIterator<AttributesRule> ruleIterator = rules.listIterator(rules
-				.size());
-		while (ruleIterator.hasPrevious()) {
-			AttributesRule rule = ruleIterator.previous();
-			if (rule.isMatch(entryPath, isDirectory)) {
-				ListIterator<Attribute> attributeIte = rule.getAttributes()
-						.listIterator(rule.getAttributes().size());
-				// Parses the attributes in the reverse order that they were
-				// read since the last entry should be used
-				while (attributeIte.hasPrevious()) {
-					Attribute attr = attributeIte.previous();
-					if (!attributes.containsKey(attr.getKey()))
-						attributes.put(attr);
-				}
-			}
-		}
-	}
 }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/attributes/AttributesRule.java b/org.eclipse.jgit/src/org/eclipse/jgit/attributes/AttributesRule.java
index 35d18c4..0532250 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/attributes/AttributesRule.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/attributes/AttributesRule.java
@@ -109,10 +109,11 @@ private static List<Attribute> parseAttributes(String attributesLine) {
 	private final String pattern;
 	private final List<Attribute> attributes;
 
-	private boolean nameOnly;
-	private boolean dirOnly;
+	private final boolean nameOnly;
 
-	private IMatcher matcher;
+	private final boolean dirOnly;
+
+	private final IMatcher matcher;
 
 	/**
 	 * Create a new attribute rule with the given pattern. Assumes that the
@@ -128,38 +129,43 @@ private static List<Attribute> parseAttributes(String attributesLine) {
 	 */
 	public AttributesRule(String pattern, String attributes) {
 		this.attributes = parseAttributes(attributes);
-		nameOnly = false;
-		dirOnly = false;
 
 		if (pattern.endsWith("/")) { //$NON-NLS-1$
 			pattern = pattern.substring(0, pattern.length() - 1);
 			dirOnly = true;
+		} else {
+			dirOnly = false;
 		}
 
-		boolean hasSlash = pattern.contains("/"); //$NON-NLS-1$
+		int slashIndex = pattern.indexOf('/');
 
-		if (!hasSlash)
+		if (slashIndex < 0) {
 			nameOnly = true;
-		else if (!pattern.startsWith("/")) { //$NON-NLS-1$
+		} else if (slashIndex == 0) {
+			nameOnly = false;
+		} else {
+			nameOnly = false;
 			// Contains "/" but does not start with one
 			// Adding / to the start should not interfere with matching
 			pattern = "/" + pattern; //$NON-NLS-1$
 		}
 
+		IMatcher candidateMatcher = NO_MATCH;
 		try {
-			matcher = PathMatcher.createPathMatcher(pattern,
+			candidateMatcher = PathMatcher.createPathMatcher(pattern,
 					Character.valueOf(FastIgnoreRule.PATH_SEPARATOR), dirOnly);
 		} catch (InvalidPatternException e) {
-			matcher = NO_MATCH;
+			// ignore: invalid patterns are silently ignored
 		}
-
+		this.matcher = candidateMatcher;
 		this.pattern = pattern;
 	}
 
 	/**
 	 * @return True if the pattern should match directories only
+	 * @since 4.3
 	 */
-	public boolean dirOnly() {
+	public boolean isDirOnly() {
 		return dirOnly;
 	}
 
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/diff/DiffFormatter.java b/org.eclipse.jgit/src/org/eclipse/jgit/diff/DiffFormatter.java
index 4c0ed38..fc701f3 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/diff/DiffFormatter.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/diff/DiffFormatter.java
@@ -666,6 +666,9 @@ public void format(DiffEntry ent) throws IOException {
 	}
 
 	private static byte[] writeGitLinkText(AbbreviatedObjectId id) {
+		if (id.toObjectId().equals(ObjectId.zeroId())) {
+			return EMPTY;
+		}
 		return encodeASCII("Subproject commit " + id.name() //$NON-NLS-1$
 				+ "\n"); //$NON-NLS-1$
 	}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/ManifestParser.java b/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/ManifestParser.java
index 7eb9550..796b422 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/ManifestParser.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/ManifestParser.java
@@ -80,7 +80,7 @@ public class ManifestParser extends DefaultHandler {
 	private final String baseUrl;
 	private final String defaultBranch;
 	private final Repository rootRepo;
-	private final Map<String, String> remotes;
+	private final Map<String, Remote> remotes;
 	private final Set<String> plusGroups;
 	private final Set<String> minusGroups;
 	private final List<RepoProject> projects;
@@ -146,7 +146,7 @@ public ManifestParser(IncludedFileReader includedReader, String filename,
 			}
 		}
 
-		remotes = new HashMap<String, String>();
+		remotes = new HashMap<String, Remote>();
 		projects = new ArrayList<RepoProject>();
 		filteredProjects = new ArrayList<RepoProject>();
 	}
@@ -195,14 +195,14 @@ public void startElement(
 		} else if ("remote".equals(qName)) { //$NON-NLS-1$
 			String alias = attributes.getValue("alias"); //$NON-NLS-1$
 			String fetch = attributes.getValue("fetch"); //$NON-NLS-1$
-			remotes.put(attributes.getValue("name"), fetch); //$NON-NLS-1$
+			String revision = attributes.getValue("revision"); //$NON-NLS-1$
+			Remote remote = new Remote(fetch, revision);
+			remotes.put(attributes.getValue("name"), remote); //$NON-NLS-1$
 			if (alias != null)
-				remotes.put(alias, fetch);
+				remotes.put(alias, remote);
 		} else if ("default".equals(qName)) { //$NON-NLS-1$
 			defaultRemote = attributes.getValue("remote"); //$NON-NLS-1$
 			defaultRevision = attributes.getValue("revision"); //$NON-NLS-1$
-			if (defaultRevision == null)
-				defaultRevision = defaultBranch;
 		} else if ("copyfile".equals(qName)) { //$NON-NLS-1$
 			if (currentProject == null)
 				throw new SAXException(RepoText.get().invalidManifest);
@@ -268,8 +268,18 @@ public void endDocument() throws SAXException {
 		} catch (URISyntaxException e) {
 			throw new SAXException(e);
 		}
+		if (defaultRevision == null && defaultRemote != null) {
+			Remote remote = remotes.get(defaultRemote);
+			if (remote != null) {
+				defaultRevision = remote.revision;
+			}
+			if (defaultRevision == null) {
+				defaultRevision = defaultBranch;
+			}
+		}
 		for (RepoProject proj : projects) {
 			String remote = proj.getRemote();
+			String revision = defaultRevision;
 			if (remote == null) {
 				if (defaultRemote == null) {
 					if (filename != null)
@@ -281,16 +291,22 @@ public void endDocument() throws SAXException {
 								RepoText.get().errorNoDefault);
 				}
 				remote = defaultRemote;
+			} else {
+				Remote r = remotes.get(remote);
+				if (r != null && r.revision != null) {
+					revision = r.revision;
+				}
 			}
 			String remoteUrl = remoteUrls.get(remote);
 			if (remoteUrl == null) {
-				remoteUrl = baseUri.resolve(remotes.get(remote)).toString();
+				remoteUrl =
+						baseUri.resolve(remotes.get(remote).fetch).toString();
 				if (!remoteUrl.endsWith("/")) //$NON-NLS-1$
 					remoteUrl = remoteUrl + "/"; //$NON-NLS-1$
 				remoteUrls.put(remote, remoteUrl);
 			}
 			proj.setUrl(remoteUrl + proj.getName())
-					.setDefaultRevision(defaultRevision);
+					.setDefaultRevision(revision);
 		}
 
 		filteredProjects.addAll(projects);
@@ -389,4 +405,14 @@ private boolean isNestedCopyfile(CopyFile copyfile) {
 		}
 		return false;
 	}
+
+	private static class Remote {
+		final String fetch;
+		final String revision;
+
+		Remote(String fetch, String revision) {
+			this.fetch = fetch;
+			this.revision = revision;
+		}
+	}
 }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoProject.java b/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoProject.java
index 915066d..f6d1209 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoProject.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoProject.java
@@ -252,10 +252,10 @@ public void addCopyFile(CopyFile copyfile) {
 	/**
 	 * Add a bunch of copyfile configurations.
 	 *
-	 * @param copyfiles
+	 * @param copyFiles
 	 */
-	public void addCopyFiles(Collection<CopyFile> copyfiles) {
-		this.copyfiles.addAll(copyfiles);
+	public void addCopyFiles(Collection<CopyFile> copyFiles) {
+		this.copyfiles.addAll(copyFiles);
 	}
 
 	/**
@@ -288,13 +288,13 @@ public boolean isAncestorOf(RepoProject that) {
 	/**
 	 * Check if this sub repo is an ancestor of the given path.
 	 *
-	 * @param path
+	 * @param thatPath
 	 *            path to be checked to see if it is within this repository
 	 * @return true if this sub repo is an ancestor of the given path.
 	 * @since 4.2
 	 */
-	public boolean isAncestorOf(String path) {
-		return path.startsWith(getPathWithSlash());
+	public boolean isAncestorOf(String thatPath) {
+		return thatPath.startsWith(getPathWithSlash());
 	}
 
 	@Override
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/ChainingCredentialsProvider.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/ChainingCredentialsProvider.java
index 3941d3c..739ddcc 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/ChainingCredentialsProvider.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/ChainingCredentialsProvider.java
@@ -70,8 +70,6 @@ public class ChainingCredentialsProvider extends CredentialsProvider {
 	public ChainingCredentialsProvider(CredentialsProvider... providers) {
 		this.credentialProviders = new ArrayList<CredentialsProvider>(
 				Arrays.asList(providers));
-		for (CredentialsProvider p : providers)
-			credentialProviders.add(p);
 	}
 
 	/**
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportHttp.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportHttp.java
index 5948278..414e879 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportHttp.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportHttp.java
@@ -67,9 +67,6 @@
 import java.net.Proxy;
 import java.net.ProxySelector;
 import java.net.URL;
-import java.security.KeyManagementException;
-import java.security.NoSuchAlgorithmException;
-import java.security.cert.X509Certificate;
 import java.text.MessageFormat;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -83,11 +80,6 @@
 import java.util.zip.GZIPInputStream;
 import java.util.zip.GZIPOutputStream;
 
-import javax.net.ssl.HostnameVerifier;
-import javax.net.ssl.SSLSession;
-import javax.net.ssl.TrustManager;
-import javax.net.ssl.X509TrustManager;
-
 import org.eclipse.jgit.errors.NoRemoteRepositoryException;
 import org.eclipse.jgit.errors.NotSupportedException;
 import org.eclipse.jgit.errors.PackProtocolException;
@@ -538,7 +530,7 @@ protected HttpConnection httpOpen(String method, URL u)
 		HttpConnection conn = connectionFactory.create(u, proxy);
 
 		if (!http.sslVerify && "https".equals(u.getProtocol())) { //$NON-NLS-1$
-			disableSslVerify(conn);
+			HttpSupport.disableSslVerify(conn);
 		}
 
 		conn.setRequestMethod(method);
@@ -562,19 +554,6 @@ protected HttpConnection httpOpen(String method, URL u)
 		return conn;
 	}
 
-	private void disableSslVerify(HttpConnection conn)
-			throws IOException {
-		final TrustManager[] trustAllCerts = new TrustManager[] { new DummyX509TrustManager() };
-		try {
-			conn.configure(null, trustAllCerts, null);
-			conn.setHostnameVerifier(new DummyHostnameVerifier());
-		} catch (KeyManagementException e) {
-			throw new IOException(e.getMessage());
-		} catch (NoSuchAlgorithmException e) {
-			throw new IOException(e.getMessage());
-		}
-	}
-
 	final InputStream openInputStream(HttpConnection conn)
 			throws IOException {
 		InputStream input = conn.getInputStream();
@@ -1002,25 +981,4 @@ void execute() throws IOException {
 			in.add(openInputStream(conn));
 		}
 	}
-
-	private static class DummyX509TrustManager implements X509TrustManager {
-		public X509Certificate[] getAcceptedIssuers() {
-			return null;
-		}
-
-		public void checkClientTrusted(X509Certificate[] certs, String authType) {
-			// no check
-		}
-
-		public void checkServerTrusted(X509Certificate[] certs, String authType) {
-			// no check
-		}
-	}
-
-	private static class DummyHostnameVerifier implements HostnameVerifier {
-		public boolean verify(String hostname, SSLSession session) {
-			// always accept
-			return true;
-		}
-	}
 }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/AbstractTreeIterator.java b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/AbstractTreeIterator.java
index 5813635..dc835e4 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/AbstractTreeIterator.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/AbstractTreeIterator.java
@@ -50,6 +50,7 @@
 import java.nio.CharBuffer;
 
 import org.eclipse.jgit.attributes.AttributesNode;
+import org.eclipse.jgit.attributes.AttributesHandler;
 import org.eclipse.jgit.dircache.DirCacheCheckout;
 import org.eclipse.jgit.errors.CorruptObjectException;
 import org.eclipse.jgit.errors.IncorrectObjectTypeException;
@@ -88,8 +89,14 @@ public abstract class AbstractTreeIterator {
 	/** A dummy object id buffer that matches the zero ObjectId. */
 	protected static final byte[] zeroid = new byte[Constants.OBJECT_ID_LENGTH];
 
-	/** Iterator for the parent tree; null if we are the root iterator. */
-	final AbstractTreeIterator parent;
+	/**
+	 * Iterator for the parent tree; null if we are the root iterator.
+	 * <p>
+	 * Used by {@link TreeWalk} and {@link AttributesHandler}
+	 *
+	 * @since 4.3
+	 */
+	public final AbstractTreeIterator parent;
 
 	/** The iterator this current entry is path equal to. */
 	AbstractTreeIterator matches;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/TreeWalk.java b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/TreeWalk.java
index 5cd713d..4775e96 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/TreeWalk.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/TreeWalk.java
@@ -49,15 +49,13 @@
 import java.util.Map;
 import java.util.Set;
 
-import org.eclipse.jgit.annotations.Nullable;
 import org.eclipse.jgit.api.errors.JGitInternalException;
 import org.eclipse.jgit.attributes.Attribute;
-import org.eclipse.jgit.attributes.Attribute.State;
 import org.eclipse.jgit.attributes.Attributes;
-import org.eclipse.jgit.attributes.AttributesNode;
 import org.eclipse.jgit.attributes.AttributesNodeProvider;
 import org.eclipse.jgit.attributes.AttributesProvider;
 import org.eclipse.jgit.dircache.DirCacheBuildIterator;
+import org.eclipse.jgit.attributes.AttributesHandler;
 import org.eclipse.jgit.dircache.DirCacheIterator;
 import org.eclipse.jgit.errors.CorruptObjectException;
 import org.eclipse.jgit.errors.IncorrectObjectTypeException;
@@ -270,6 +268,9 @@ public static TreeWalk forPath(final Repository db, final String path,
 	/** Cached attribute for the current entry */
 	private Attributes attrs = null;
 
+	/** Cached attributes handler */
+	private AttributesHandler attributesHandler;
+
 	private Config config;
 
 	/**
@@ -310,6 +311,14 @@ public ObjectReader getObjectReader() {
 	}
 
 	/**
+	 * @return the {@link OperationType}
+	 * @since 4.3
+	 */
+	public OperationType getOperationType() {
+		return operationType;
+	}
+
+	/**
 	 * Release any resources used by this walker's reader.
 	 * <p>
 	 * A walker that has been released can be used again, but may need to be
@@ -435,9 +444,83 @@ public void setAttributesNodeProvider(AttributesNodeProvider provider) {
 		attributesNodeProvider = provider;
 	}
 
+	/**
+	 * @return the {@link AttributesNodeProvider} for this {@link TreeWalk}.
+	 * @since 4.3
+	 */
+	public AttributesNodeProvider getAttributesNodeProvider() {
+		return attributesNodeProvider;
+	}
+
+	/**
+	 * Retrieve the git attributes for the current entry.
+	 *
+	 * <h4>Git attribute computation</h4>
+	 *
+	 * <ul>
+	 * <li>Get the attributes matching the current path entry from the info file
+	 * (see {@link AttributesNodeProvider#getInfoAttributesNode()}).</li>
+	 * <li>Completes the list of attributes using the .gitattributes files
+	 * located on the current path (the further the directory that contains
+	 * .gitattributes is from the path in question, the lower its precedence).
+	 * For a checkin operation, it will look first on the working tree (if any).
+	 * If there is no attributes file, it will fallback on the index. For a
+	 * checkout operation, it will first use the index entry and then fallback
+	 * on the working tree if none.</li>
+	 * <li>In the end, completes the list of matching attributes using the
+	 * global attribute file define in the configuration (see
+	 * {@link AttributesNodeProvider#getGlobalAttributesNode()})</li>
+	 *
+	 * </ul>
+	 *
+	 *
+	 * <h4>Iterator constraints</h4>
+	 *
+	 * <p>
+	 * In order to have a correct list of attributes for the current entry, this
+	 * {@link TreeWalk} requires to have at least one
+	 * {@link AttributesNodeProvider} and a {@link DirCacheIterator} set up. An
+	 * {@link AttributesNodeProvider} is used to retrieve the attributes from
+	 * the info attributes file and the global attributes file. The
+	 * {@link DirCacheIterator} is used to retrieve the .gitattributes files
+	 * stored in the index. A {@link WorkingTreeIterator} can also be provided
+	 * to access the local version of the .gitattributes files. If none is
+	 * provided it will fallback on the {@link DirCacheIterator}.
+	 * </p>
+	 *
+	 * @return a {@link Set} of {@link Attribute}s that match the current entry.
+	 * @since 4.2
+	 */
+	public Attributes getAttributes() {
+		if (attrs != null)
+			return attrs;
+
+		if (attributesNodeProvider == null) {
+			// The work tree should have a AttributesNodeProvider to be able to
+			// retrieve the info and global attributes node
+			throw new IllegalStateException(
+					"The tree walk should have one AttributesNodeProvider set in order to compute the git attributes."); //$NON-NLS-1$
+		}
+
+		try {
+			// Lazy create the attributesHandler on the first access of
+			// attributes. This requires the info, global and root
+			// attributes nodes
+			if (attributesHandler == null) {
+				attributesHandler = new AttributesHandler(this);
+			}
+			attrs = attributesHandler.getAttributes();
+			return attrs;
+		} catch (IOException e) {
+			throw new JGitInternalException("Error while parsing attributes", //$NON-NLS-1$
+					e);
+		}
+	}
+
 	/** Reset this walker so new tree iterators can be added to it. */
 	public void reset() {
 		attrs = null;
+		attributesHandler = null;
 		trees = NO_TREES;
 		advance = false;
 		depth = 0;
@@ -740,6 +823,16 @@ public FileMode getFileMode(final int nth) {
 	}
 
 	/**
+	 * Obtain the {@link FileMode} for the current entry on the currentHead tree
+	 *
+	 * @return mode for the current entry of the currentHead tree.
+	 * @since 4.3
+	 */
+	public FileMode getFileMode() {
+		return FileMode.fromBits(currentHead.mode);
+	}
+
+	/**
 	 * Obtain the ObjectId for the current entry.
 	 * <p>
 	 * Using this method to compare ObjectId values between trees of this walker
@@ -1109,156 +1202,13 @@ static String pathOf(final byte[] buf, int pos, int end) {
 	}
 
 	/**
-	 * Retrieve the git attributes for the current entry.
-	 *
-	 * <h4>Git attribute computation</h4>
-	 *
-	 * <ul>
-	 * <li>Get the attributes matching the current path entry from the info file
-	 * (see {@link AttributesNodeProvider#getInfoAttributesNode()}).</li>
-	 * <li>Completes the list of attributes using the .gitattributes files
-	 * located on the current path (the further the directory that contains
-	 * .gitattributes is from the path in question, the lower its precedence).
-	 * For a checkin operation, it will look first on the working tree (if any).
-	 * If there is no attributes file, it will fallback on the index. For a
-	 * checkout operation, it will first use the index entry and then fallback
-	 * on the working tree if none.</li>
-	 * <li>In the end, completes the list of matching attributes using the
-	 * global attribute file define in the configuration (see
-	 * {@link AttributesNodeProvider#getGlobalAttributesNode()})</li>
-	 *
-	 * </ul>
-	 *
-	 *
-	 * <h4>Iterator constraints</h4>
-	 *
-	 * <p>
-	 * In order to have a correct list of attributes for the current entry, this
-	 * {@link TreeWalk} requires to have at least one
-	 * {@link AttributesNodeProvider} and a {@link DirCacheIterator} set up. An
-	 * {@link AttributesNodeProvider} is used to retrieve the attributes from
-	 * the info attributes file and the global attributes file. The
-	 * {@link DirCacheIterator} is used to retrieve the .gitattributes files
-	 * stored in the index. A {@link WorkingTreeIterator} can also be provided
-	 * to access the local version of the .gitattributes files. If none is
-	 * provided it will fallback on the {@link DirCacheIterator}.
-	 * </p>
-	 *
-	 * @return a {@link Set} of {@link Attribute}s that match the current entry.
-	 * @since 4.2
+	 * @param type
+	 *            of the tree to be queried
+	 * @return the tree of that type or null if none is present
+	 * @since 4.3
 	 */
-	public Attributes getAttributes() {
-		if (attrs != null)
-			return attrs;
-
-		if (attributesNodeProvider == null) {
-			// The work tree should have a AttributesNodeProvider to be able to
-			// retrieve the info and global attributes node
-			throw new IllegalStateException(
-					"The tree walk should have one AttributesNodeProvider set in order to compute the git attributes."); //$NON-NLS-1$
-		}
-
-		WorkingTreeIterator workingTreeIterator = getTree(WorkingTreeIterator.class);
-		DirCacheIterator dirCacheIterator = getTree(DirCacheIterator.class);
-		CanonicalTreeParser other = getTree(CanonicalTreeParser.class);
-
-		if (workingTreeIterator == null && dirCacheIterator == null
-				&& other == null) {
-			// Can not retrieve the attributes without at least one of the above
-			// iterators.
-			return new Attributes();
-		}
-
-		String path = currentHead.getEntryPathString();
-		final boolean isDir = FileMode.TREE.equals(currentHead.mode);
-		Attributes attributes = new Attributes();
-		try {
-			// Gets the global attributes node
-			AttributesNode globalNodeAttr = attributesNodeProvider
-					.getGlobalAttributesNode();
-			// Gets the info attributes node
-			AttributesNode infoNodeAttr = attributesNodeProvider
-					.getInfoAttributesNode();
-
-			// Gets the info attributes
-			if (infoNodeAttr != null) {
-				infoNodeAttr.getAttributes(path, isDir, attributes);
-			}
-
-			// Gets the attributes located on the current entry path
-			getPerDirectoryEntryAttributes(path, isDir, operationType,
-					workingTreeIterator, dirCacheIterator, other, attributes);
-
-			// Gets the attributes located in the global attribute file
-			if (globalNodeAttr != null) {
-				globalNodeAttr.getAttributes(path, isDir, attributes);
-			}
-		} catch (IOException e) {
-			throw new JGitInternalException("Error while parsing attributes", e); //$NON-NLS-1$
-		}
-		// now after all attributes are collected - in the correct hierarchy
-		// order - remove all unspecified entries (the ! marker)
-		for (Attribute a : attributes.getAll()) {
-			if (a.getState() == State.UNSPECIFIED)
-				attributes.remove(a.getKey());
-		}
-		return attributes;
-	}
-
-	/**
-	 * Get the attributes located on the current entry path.
-	 *
-	 * @param path
-	 *            current entry path
-	 * @param isDir
-	 *            holds true if the current entry is a directory
-	 * @param opType
-	 *            type of operation
-	 * @param workingTreeIterator
-	 *            a {@link WorkingTreeIterator} matching the current entry
-	 * @param dirCacheIterator
-	 *            a {@link DirCacheIterator} matching the current entry
-	 * @param other
-	 *            a {@link CanonicalTreeParser} matching the current entry
-	 * @param attributes
-	 *            Non null map holding the existing attributes. This map will be
-	 *            augmented with new entry. None entry will be overrided.
-	 * @throws IOException
-	 *             It raises an {@link IOException} if a problem appears while
-	 *             parsing one on the attributes file.
-	 */
-	private void getPerDirectoryEntryAttributes(String path, boolean isDir,
-			OperationType opType, WorkingTreeIterator workingTreeIterator,
-			DirCacheIterator dirCacheIterator, CanonicalTreeParser other,
-			Attributes attributes)
-			throws IOException {
-		// Prevents infinite recurrence
-		if (workingTreeIterator != null || dirCacheIterator != null
-				|| other != null) {
-			AttributesNode currentAttributesNode = getCurrentAttributesNode(
-					opType, workingTreeIterator, dirCacheIterator, other);
-			if (currentAttributesNode != null) {
-				currentAttributesNode.getAttributes(path, isDir, attributes);
-			}
-			getPerDirectoryEntryAttributes(path, isDir, opType,
-					getParent(workingTreeIterator, WorkingTreeIterator.class),
-					getParent(dirCacheIterator, DirCacheIterator.class),
-					getParent(other, CanonicalTreeParser.class), attributes);
-		}
-	}
-
-	private static <T extends AbstractTreeIterator> T getParent(T current,
+	public <T extends AbstractTreeIterator> T getTree(
 			Class<T> type) {
-		if (current != null) {
-			AbstractTreeIterator parent = current.parent;
-			if (type.isInstance(parent)) {
-				return type.cast(parent);
-			}
-		}
-		return null;
-	}
-
-	private <T extends AbstractTreeIterator> T getTree(Class<T> type) {
 		for (int i = 0; i < trees.length; i++) {
 			AbstractTreeIterator tree = trees[i];
 			if (type.isInstance(tree)) {
@@ -1269,76 +1219,6 @@ private <T extends AbstractTreeIterator> T getTree(Class<T> type) {
 	}
 
 	/**
-	 * Get the {@link AttributesNode} for the current entry.
-	 * <p>
-	 * This method implements the fallback mechanism between the index and the
-	 * working tree depending on the operation type
-	 * </p>
-	 *
-	 * @param opType
-	 * @param workingTreeIterator
-	 * @param dirCacheIterator
-	 * @param other
-	 * @return a {@link AttributesNode} of the current entry,
-	 *         {@link NullPointerException} otherwise.
-	 * @throws IOException
-	 *             It raises an {@link IOException} if a problem appears while
-	 *             parsing one on the attributes file.
-	 */
-	private AttributesNode getCurrentAttributesNode(OperationType opType,
-			@Nullable WorkingTreeIterator workingTreeIterator,
-			@Nullable DirCacheIterator dirCacheIterator,
-			@Nullable CanonicalTreeParser other)
-					throws IOException {
-		AttributesNode attributesNode = null;
-		switch (opType) {
-		case CHECKIN_OP:
-			if (workingTreeIterator != null) {
-				attributesNode = workingTreeIterator.getEntryAttributesNode();
-			}
-			if (attributesNode == null && dirCacheIterator != null) {
-				attributesNode = getAttributesNode(dirCacheIterator
-						.getEntryAttributesNode(getObjectReader()),
-						attributesNode);
-			}
-			if (attributesNode == null && other != null) {
-				attributesNode = getAttributesNode(
-						other.getEntryAttributesNode(getObjectReader()),
-						attributesNode);
-			}
-			break;
-		case CHECKOUT_OP:
-			if (other != null) {
-				attributesNode = other
-						.getEntryAttributesNode(getObjectReader());
-			}
-			if (dirCacheIterator != null) {
-				attributesNode = getAttributesNode(dirCacheIterator
-						.getEntryAttributesNode(getObjectReader()),
-						attributesNode);
-			}
-			if (attributesNode == null && workingTreeIterator != null) {
-				attributesNode = getAttributesNode(
-						workingTreeIterator.getEntryAttributesNode(),
-						attributesNode);
-			}
-			break;
-		default:
-			throw new IllegalStateException(
-					"The only supported operation types are:" //$NON-NLS-1$
-							+ OperationType.CHECKIN_OP + "," //$NON-NLS-1$
-							+ OperationType.CHECKOUT_OP);
-		}
-
-		return attributesNode;
-	}
-
-	private static AttributesNode getAttributesNode(AttributesNode value,
-			AttributesNode defaultValue) {
-		return (value == null) ? defaultValue : value;
-	}
-
-	/**
 	 * Inspect config and attributes to return a filtercommand applicable for
 	 * the current path
 	 *
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/HttpSupport.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/HttpSupport.java
index 8b4ad0a..6a43c0f 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/HttpSupport.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/HttpSupport.java
@@ -52,8 +52,16 @@
 import java.net.URISyntaxException;
 import java.net.URL;
 import java.net.URLEncoder;
+import java.security.KeyManagementException;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.X509Certificate;
 import java.text.MessageFormat;
 
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.SSLSession;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.X509TrustManager;
+
 import org.eclipse.jgit.internal.JGitText;
 import org.eclipse.jgit.transport.http.HttpConnection;
 
@@ -62,6 +70,14 @@ public class HttpSupport {
 	/** The {@code GET} HTTP method. */
 	public static final String METHOD_GET = "GET"; //$NON-NLS-1$
 
+	/** The {@code HEAD} HTTP method.
+	 * @since 4.3 */
+	public static final String METHOD_HEAD = "HEAD"; //$NON-NLS-1$
+
+	/** The {@code POST} HTTP method.
+	 * @since 4.3 */
+	public static final String METHOD_PUT = "PUT"; //$NON-NLS-1$
+
 	/** The {@code POST} HTTP method. */
 	public static final String METHOD_POST = "POST"; //$NON-NLS-1$
 
@@ -234,6 +250,50 @@ public static Proxy proxyFor(final ProxySelector proxySelector, final URL u)
 		}
 	}
 
+	/**
+	 * Disable SSL and hostname verification for given HTTP connection
+	 *
+	 * @param conn
+	 * @throws IOException
+	 * @since 4.3
+	 */
+	public static void disableSslVerify(HttpConnection conn)
+			throws IOException {
+		final TrustManager[] trustAllCerts = new TrustManager[] {
+				new DummyX509TrustManager() };
+		try {
+			conn.configure(null, trustAllCerts, null);
+			conn.setHostnameVerifier(new DummyHostnameVerifier());
+		} catch (KeyManagementException e) {
+			throw new IOException(e.getMessage());
+		} catch (NoSuchAlgorithmException e) {
+			throw new IOException(e.getMessage());
+		}
+	}
+
+	private static class DummyX509TrustManager implements X509TrustManager {
+		public X509Certificate[] getAcceptedIssuers() {
+			return null;
+		}
+
+		public void checkClientTrusted(X509Certificate[] certs,
+				String authType) {
+			// no check
+		}
+
+		public void checkServerTrusted(X509Certificate[] certs,
+				String authType) {
+			// no check
+		}
+	}
+
+	private static class DummyHostnameVerifier implements HostnameVerifier {
+		public boolean verify(String hostname, SSLSession session) {
+			// always accept
+			return true;
+		}
+	}
+
 	private HttpSupport() {
 		// Utility class only.
 	}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/NB.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/NB.java
index 85c1648..8536f1d 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/NB.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/NB.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
+ * Copyright (C) 2008, 2015 Shawn O. Pearce <spearce@spearce.org>
  * and other copyright owners as documented in the project's IP log.
  *
  * This program and the accompanying materials are made available
@@ -66,6 +66,37 @@ public static int compareUInt32(final int a, final int b) {
 	}
 
 	/**
+	 * Compare a 64 bit unsigned integer stored in a 64 bit signed integer.
+	 * <p>
+	 * This function performs an unsigned compare operation, even though Java
+	 * does not natively support unsigned integer values. Negative numbers are
+	 * treated as larger than positive ones.
+	 *
+	 * @param a
+	 *            the first value to compare.
+	 * @param b
+	 *            the second value to compare.
+	 * @return &lt; 0 if a &lt; b; 0 if a == b; &gt; 0 if a &gt; b.
+	 * @since 4.3
+	 */
+	public static int compareUInt64(final long a, final long b) {
+		long cmp = (a >>> 1) - (b >>> 1);
+		if (cmp > 0) {
+			return 1;
+		} else if (cmp < 0) {
+			return -1;
+		}
+		cmp = ((a & 1) - (b & 1));
+		if (cmp > 0) {
+			return 1;
+		} else if (cmp < 0) {
+			return -1;
+		} else {
+			return 0;
+		}
+	}
+
+	/**
 	 * Convert sequence of 2 bytes (network byte order) into unsigned value.
 	 *
 	 * @param intbuf
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/RawParseUtils.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/RawParseUtils.java
index f2955f7..86777b9 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/RawParseUtils.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/RawParseUtils.java
@@ -366,6 +366,72 @@ public static final int parseHexInt32(final byte[] bs, final int p) {
 	}
 
 	/**
+	 * Parse 16 character base 16 (hex) formatted string to unsigned long.
+	 * <p>
+	 * The number is read in network byte order, that is, most significant
+	 * nibble first.
+	 *
+	 * @param bs
+	 *            buffer to parse digits from; positions {@code [p, p+16)} will
+	 *            be parsed.
+	 * @param p
+	 *            first position within the buffer to parse.
+	 * @return the integer value.
+	 * @throws ArrayIndexOutOfBoundsException
+	 *             if the string is not hex formatted.
+	 * @since 4.3
+	 */
+	public static final long parseHexInt64(final byte[] bs, final int p) {
+		long r = digits16[bs[p]] << 4;
+
+		r |= digits16[bs[p + 1]];
+		r <<= 4;
+
+		r |= digits16[bs[p + 2]];
+		r <<= 4;
+
+		r |= digits16[bs[p + 3]];
+		r <<= 4;
+
+		r |= digits16[bs[p + 4]];
+		r <<= 4;
+
+		r |= digits16[bs[p + 5]];
+		r <<= 4;
+
+		r |= digits16[bs[p + 6]];
+		r <<= 4;
+
+		r |= digits16[bs[p + 7]];
+		r <<= 4;
+
+		r |= digits16[bs[p + 8]];
+		r <<= 4;
+
+		r |= digits16[bs[p + 9]];
+		r <<= 4;
+
+		r |= digits16[bs[p + 10]];
+		r <<= 4;
+
+		r |= digits16[bs[p + 11]];
+		r <<= 4;
+
+		r |= digits16[bs[p + 12]];
+		r <<= 4;
+
+		r |= digits16[bs[p + 13]];
+		r <<= 4;
+
+		r |= digits16[bs[p + 14]];
+
+		final int last = digits16[bs[p + 15]];
+		if (r < 0 || last < 0)
+			throw new ArrayIndexOutOfBoundsException();
+		return (r << 4) | last;
+	}
+
+	/**
 	 * Parse a single hex digit to its numeric value (0-15).
 	 *
 	 * @param digit
diff --git a/pom.xml b/pom.xml
index 0dda8cf..6bb30fe 100644
--- a/pom.xml
+++ b/pom.xml
@@ -208,6 +208,7 @@
     <log4j-version>1.2.15</log4j-version>
     <maven-javadoc-plugin-version>2.10.1</maven-javadoc-plugin-version>
     <tycho-extras-version>0.23.0</tycho-extras-version>
+    <gson-version>2.2.4</gson-version>
 
     <!-- Properties to enable jacoco code coverage analysis -->
     <sonar.core.codeCoveragePlugin>jacoco</sonar.core.codeCoveragePlugin>
@@ -632,6 +633,12 @@
           </exclusion>
         </exclusions>
       </dependency>
+
+      <dependency>
+        <groupId>com.google.code.gson</groupId>
+        <artifactId>gson</artifactId>
+        <version>${gson-version}</version>
+      </dependency>
     </dependencies>
   </dependencyManagement>
 
@@ -767,6 +774,8 @@
     <module>org.eclipse.jgit.http.apache</module>
     <module>org.eclipse.jgit.http.server</module>
     <module>org.eclipse.jgit.pgm</module>
+    <module>org.eclipse.jgit.lfs</module>
+    <module>org.eclipse.jgit.lfs.server</module>
     <module>org.eclipse.jgit.junit</module>
     <module>org.eclipse.jgit.junit.http</module>
 
@@ -774,6 +783,8 @@
     <module>org.eclipse.jgit.ant.test</module>
     <module>org.eclipse.jgit.http.test</module>
     <module>org.eclipse.jgit.pgm.test</module>
+    <module>org.eclipse.jgit.lfs.test</module>
+    <module>org.eclipse.jgit.lfs.server.test</module>
   </modules>
 
 </project>