ErrorProne: Enable and fix UnusedException check

Enable UnusedException at ERROR level which causes the build to fail
in many places with:

  [UnusedException] This catch block catches an symbol and re-throws
  another, but swallows the caught symbol rather than setting it as a
  cause. This can make debugging harder.

Fix it by setting the caught exception as cause on the subsequently
thrown exception.

Note: The grammatically incorrect error message is copy-pasted as-is
from the version of ErrorProne currently used in Bazel; it has been
fixed by [1] in the latest version.

[1] https://github.com/google/error-prone/commit/d57a39c

Change-Id: I11ed38243091fc12f64f1b2db404ba3f1d2e98b5
Signed-off-by: David Pursehouse <david.pursehouse@gmail.com>
Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
diff --git a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/GitFilter.java b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/GitFilter.java
index 9b17132..1769832 100644
--- a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/GitFilter.java
+++ b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/GitFilter.java
@@ -298,7 +298,8 @@ private static boolean getBoolean(FilterConfig cfg, String param)
 		try {
 			return StringUtils.toBoolean(n);
 		} catch (IllegalArgumentException err) {
-			throw new ServletException(MessageFormat.format(HttpServerText.get().invalidBoolean, param, n));
+			throw new ServletException(MessageFormat.format(
+					HttpServerText.get().invalidBoolean, param, n), err);
 		}
 	}
 
diff --git a/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/TestRepository.java b/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/TestRepository.java
index d68c5c8..a5b3b1f 100644
--- a/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/TestRepository.java
+++ b/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/TestRepository.java
@@ -973,7 +973,7 @@ private void writeFile(File p, byte[] bin) throws IOException,
 		try {
 			lck.write(bin);
 		} catch (IOException ioe) {
-			throw new ObjectWritingException("Can't write " + p);
+			throw new ObjectWritingException("Can't write " + p, ioe);
 		}
 		if (!lck.commit())
 			throw new ObjectWritingException("Can't write " + p);
diff --git a/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/LfsPointer.java b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/LfsPointer.java
index c4a51c7..55d2cfa 100644
--- a/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/LfsPointer.java
+++ b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/LfsPointer.java
@@ -18,7 +18,6 @@
 import java.io.OutputStream;
 import java.io.PrintStream;
 import java.io.UnsupportedEncodingException;
-import java.nio.charset.UnsupportedCharsetException;
 import java.util.Locale;
 
 import org.eclipse.jgit.annotations.Nullable;
@@ -110,7 +109,6 @@ public void encode(OutputStream out) {
 			ps.print(size + "\n"); //$NON-NLS-1$
 		} catch (UnsupportedEncodingException e) {
 			// should not happen, we are using a standard charset
-			throw new UnsupportedCharsetException(UTF_8.name());
 		}
 	}
 
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
index a2bcc35..9016e53 100644
--- 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
@@ -121,8 +121,11 @@ private static final AbbreviatedLongObjectId fromHexString(final byte[] bs,
 			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);
+		} catch (ArrayIndexOutOfBoundsException e) {
+			InvalidLongObjectIdException e1 = new InvalidLongObjectIdException(
+					bs, ptr, end - ptr);
+			e1.initCause(e);
+			throw e1;
 		}
 	}
 
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
index 000e9b2..15b3ca4 100644
--- 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
@@ -223,9 +223,11 @@ private static final LongObjectId fromHexString(byte[] bs, int p) {
 			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);
+		} catch (ArrayIndexOutOfBoundsException e) {
+			InvalidLongObjectIdException e1 = new InvalidLongObjectIdException(
+					bs, p, Constants.LONG_OBJECT_ID_STRING_LENGTH);
+			e1.initCause(e);
+			throw e1;
 		}
 	}
 
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
index 368f6af..012e4ae 100644
--- 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
@@ -213,9 +213,11 @@ private void fromHexString(byte[] bs, int 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);
+		} catch (ArrayIndexOutOfBoundsException e) {
+			InvalidLongObjectIdException e1 = new InvalidLongObjectIdException(
+					bs, p, Constants.LONG_OBJECT_ID_STRING_LENGTH);
+			e1.initCause(e);
+			throw e1;
 		}
 	}
 
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Checkout.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Checkout.java
index 455abcd..98724bf 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Checkout.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Checkout.java
@@ -100,7 +100,7 @@ protected void run() throws Exception {
 						.format(CLIText.get().pathspecDidNotMatch, name), e);
 			} catch (RefAlreadyExistsException e) {
 				throw die(MessageFormat
-						.format(CLIText.get().branchAlreadyExists, name));
+						.format(CLIText.get().branchAlreadyExists, name), e);
 			} catch (CheckoutConflictException e) {
 				StringBuilder builder = new StringBuilder();
 				builder.append(CLIText.get().checkoutConflict);
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Clone.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Clone.java
index 243e99f..8f80d6d 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Clone.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Clone.java
@@ -110,7 +110,7 @@ protected void run() throws Exception {
 				outw.println(CLIText.get().clonedEmptyRepository);
 		} catch (InvalidRemoteException e) {
 			throw die(MessageFormat.format(CLIText.get().doesNotExist,
-					sourceUri));
+					sourceUri), e);
 		} finally {
 			if (db != null)
 				db.close();
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/ReceivePack.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/ReceivePack.java
index cbb5d84..f570f7f 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/ReceivePack.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/ReceivePack.java
@@ -42,7 +42,7 @@ protected void run() {
 			db = key.open(true /* must exist */);
 		} catch (RepositoryNotFoundException notFound) {
 			throw die(MessageFormat.format(CLIText.get().notAGitRepository,
-					dstGitdir.getPath()));
+					dstGitdir.getPath()), notFound);
 		} catch (IOException e) {
 			throw die(e.getMessage(), e);
 		}
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Tag.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Tag.java
index 8c39886..b408b78 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Tag.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Tag.java
@@ -74,7 +74,7 @@ protected void run() {
 						command.call();
 					} catch (RefAlreadyExistsException e) {
 						throw die(MessageFormat.format(
-								CLIText.get().tagAlreadyExists, tagName));
+								CLIText.get().tagAlreadyExists, tagName), e);
 					}
 				}
 			} else {
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/UploadPack.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/UploadPack.java
index 69c8eb5..36103f2 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/UploadPack.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/UploadPack.java
@@ -50,7 +50,7 @@ protected void run() {
 			up.upload(ins, outs, errs);
 		} catch (RepositoryNotFoundException notFound) {
 			throw die(MessageFormat.format(CLIText.get().notAGitRepository,
-					srcGitdir.getPath()));
+					srcGitdir.getPath()), notFound);
 		} catch (IOException e) {
 			throw die(e.getMessage(), e);
 		}
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/RebuildCommitGraph.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/RebuildCommitGraph.java
index ddd48da..8d884c1 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/RebuildCommitGraph.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/RebuildCommitGraph.java
@@ -235,7 +235,9 @@ protected void writeFile(String name, byte[] content)
 				try {
 					lck.write(content);
 				} catch (IOException ioe) {
-					throw new ObjectWritingException(MessageFormat.format(CLIText.get().cantWrite, file));
+					throw new ObjectWritingException(
+							MessageFormat.format(CLIText.get().cantWrite, file),
+							ioe);
 				}
 				if (!lck.commit())
 					throw new ObjectWritingException(MessageFormat.format(CLIText.get().cantWrite, file));
@@ -266,7 +268,9 @@ private Map<String, Ref> computeNewRefs() throws IOException {
 						errw.println(MessageFormat.format(CLIText.get().skippingObject, type, name));
 						continue;
 					}
-					throw new MissingObjectException(id, type);
+					MissingObjectException mue1 = new MissingObjectException(id, type);
+					mue1.initCause(mue);
+					throw mue1;
 				}
 				refs.put(name, new ObjectIdRef.Unpeeled(Ref.Storage.PACKED,
 						name, id));
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/ShowPackDelta.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/ShowPackDelta.java
index 6f0aba3..49f7ada 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/ShowPackDelta.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/ShowPackDelta.java
@@ -57,7 +57,7 @@ protected void run() throws Exception {
 			if (BinaryDelta.getResultSize(delta) != size)
 				throw die("Object " + obj.name() + " is not a delta"); //$NON-NLS-1$ //$NON-NLS-2$
 		} catch (ArrayIndexOutOfBoundsException bad) {
-			throw die("Object " + obj.name() + " is not a delta"); //$NON-NLS-1$ //$NON-NLS-2$
+			throw die("Object " + obj.name() + " is not a delta", bad); //$NON-NLS-1$ //$NON-NLS-2$
 		}
 
 		outw.println(BinaryDelta.format(delta));
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/AbstractTreeIteratorHandler.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/AbstractTreeIteratorHandler.java
index 07a1bb8..d860472 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/AbstractTreeIteratorHandler.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/AbstractTreeIteratorHandler.java
@@ -101,8 +101,10 @@ public int parseArguments(Parameters params) throws CmdLineException {
 		try (ObjectReader curs = clp.getRepository().newObjectReader()) {
 			p.reset(curs, clp.getRevWalk().parseTree(id));
 		} catch (MissingObjectException | IncorrectObjectTypeException e) {
-			throw new CmdLineException(clp,
+			CmdLineException cle = new CmdLineException(clp,
 					CLIText.format(CLIText.get().notATree), name);
+			cle.initCause(e);
+			throw cle;
 		} catch (IOException e) {
 			throw new CmdLineException(clp,
 					CLIText.format(CLIText.get().cannotReadBecause), name,
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/RevCommitHandler.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/RevCommitHandler.java
index f521775..8b2bed36 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/RevCommitHandler.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/RevCommitHandler.java
@@ -98,8 +98,10 @@ private void addOne(String name, boolean interesting)
 		try {
 			c = clp.getRevWalk().parseCommit(id);
 		} catch (MissingObjectException | IncorrectObjectTypeException e) {
-			throw new CmdLineException(clp,
+			CmdLineException cle = new CmdLineException(clp,
 					CLIText.format(CLIText.get().notACommit), name);
+			cle.initCause(e);
+			throw cle;
 		} catch (IOException e) {
 			throw new CmdLineException(clp,
 					CLIText.format(CLIText.get().cannotReadBecause), name,
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/RevTreeHandler.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/RevTreeHandler.java
index fa96361..357886d 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/RevTreeHandler.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/RevTreeHandler.java
@@ -70,8 +70,10 @@ public int parseArguments(Parameters params) throws CmdLineException {
 		try {
 			c = clp.getRevWalk().parseTree(id);
 		} catch (MissingObjectException | IncorrectObjectTypeException e) {
-			throw new CmdLineException(clp,
+			CmdLineException cle = new CmdLineException(clp,
 					CLIText.format(CLIText.get().notATree), name);
+			cle.initCause(e);
+			throw cle;
 		} catch (IOException e) {
 			throw new CmdLineException(clp,
 					CLIText.format(CLIText.get().cannotReadBecause), name,
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/io/TimeoutOutputStreamTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/io/TimeoutOutputStreamTest.java
index 024f0f3..567880f 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/io/TimeoutOutputStreamTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/io/TimeoutOutputStreamTest.java
@@ -149,7 +149,9 @@ public void flush() throws IOException {
 					try {
 						Thread.sleep(1000);
 					} catch (InterruptedException e) {
-						throw new InterruptedIOException();
+						InterruptedIOException e1 = new InterruptedIOException();
+						e1.initCause(e);
+						throw e1;
 					}
 				}
 			}
@@ -202,7 +204,9 @@ public void close() throws IOException {
 					try {
 						Thread.sleep(1000);
 					} catch (InterruptedException e) {
-						throw new InterruptedIOException();
+						InterruptedIOException e1 = new InterruptedIOException();
+						e1.initCause(e);
+						throw e1;
 					}
 				}
 			}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/CloneCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/CloneCommand.java
index 5232223..eef7940 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/CloneCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/CloneCommand.java
@@ -160,7 +160,7 @@ public Git call() throws GitAPIException, InvalidRemoteException,
 			verifyDirectories(u);
 		} catch (URISyntaxException e) {
 			throw new InvalidRemoteException(
-					MessageFormat.format(JGitText.get().invalidURL, uri));
+					MessageFormat.format(JGitText.get().invalidURL, uri), e);
 		}
 		@SuppressWarnings("resource") // Closed by caller
 		Repository repository = init();
@@ -180,8 +180,9 @@ public Git call() throws GitAPIException, InvalidRemoteException,
 				repository.close();
 			}
 			cleanup();
-			throw new InvalidRemoteException(MessageFormat.format(
-					JGitText.get().invalidRemote, remote));
+			throw new InvalidRemoteException(
+					MessageFormat.format(JGitText.get().invalidRemote, remote),
+					e);
 		} catch (GitAPIException | RuntimeException e) {
 			if (repository != null) {
 				repository.close();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/FetchCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/FetchCommand.java
index a4b9bcf..033dd60 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/FetchCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/FetchCommand.java
@@ -223,7 +223,7 @@ public FetchResult call() throws GitAPIException, InvalidRemoteException,
 					e.getMessage(), e);
 		} catch (URISyntaxException e) {
 			throw new InvalidRemoteException(MessageFormat.format(
-					JGitText.get().invalidRemote, remote));
+					JGitText.get().invalidRemote, remote), e);
 		} catch (NotSupportedException e) {
 			throw new JGitInternalException(
 					JGitText.get().exceptionCaughtDuringExecutionOfFetchCommand,
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/LsRemoteCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/LsRemoteCommand.java
index 12517df..a4ca309 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/LsRemoteCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/LsRemoteCommand.java
@@ -180,7 +180,7 @@ private Map<String, Ref> execute() throws GitAPIException,
 			}
 		} catch (URISyntaxException e) {
 			throw new InvalidRemoteException(MessageFormat.format(
-					JGitText.get().invalidRemote, remote));
+					JGitText.get().invalidRemote, remote), e);
 		} catch (NotSupportedException e) {
 			throw new JGitInternalException(
 					JGitText.get().exceptionCaughtDuringExecutionOfLsRemoteCommand,
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/PushCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/PushCommand.java
index b9b15eb..aa5a634 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/PushCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/PushCommand.java
@@ -152,8 +152,9 @@ public Iterable<PushResult> call() throws GitAPIException,
 			}
 
 		} catch (URISyntaxException e) {
-			throw new InvalidRemoteException(MessageFormat.format(
-					JGitText.get().invalidRemote, remote));
+			throw new InvalidRemoteException(
+					MessageFormat.format(JGitText.get().invalidRemote, remote),
+					e);
 		} catch (TransportException e) {
 			throw new org.eclipse.jgit.api.errors.TransportException(
 					e.getMessage(), e);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/diff/SimilarityIndex.java b/org.eclipse.jgit/src/org/eclipse/jgit/diff/SimilarityIndex.java
index fcfae65..fb6e5df 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/diff/SimilarityIndex.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/diff/SimilarityIndex.java
@@ -350,6 +350,7 @@ private static int growAt(int idHashBits) {
 		return (1 << idHashBits) * (idHashBits - 3) / idHashBits;
 	}
 
+	@SuppressWarnings("UnusedException")
 	private void grow() throws TableFullException {
 		if (idHashBits == 30)
 			throw new TableFullException();
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 023efd8..6a2c389 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/ManifestParser.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/ManifestParser.java
@@ -139,7 +139,7 @@ public void read(InputStream inputStream) throws IOException {
 		try {
 			xr = XMLReaderFactory.createXMLReader();
 		} catch (SAXException e) {
-			throw new IOException(JGitText.get().noXMLParserAvailable);
+			throw new IOException(JGitText.get().noXMLParserAvailable, e);
 		}
 		xr.setContentHandler(this);
 		try {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoCommand.java
index 98f61d1..c039aaf 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoCommand.java
@@ -541,7 +541,7 @@ public RevCommit call() throws GitAPIException {
 				inputStream = new FileInputStream(manifestPath);
 			} catch (IOException e) {
 				throw new IllegalArgumentException(
-						JGitText.get().pathNotConfigured);
+						JGitText.get().pathNotConfigured, e);
 			}
 		}
 
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/fsck/FsckPackParser.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/fsck/FsckPackParser.java
index ad7aebc..3b94984 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/fsck/FsckPackParser.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/fsck/FsckPackParser.java
@@ -290,9 +290,12 @@ public void verifyIndex(PackIndex idx)
 							ErrorType.MISMATCH_CRC);
 				}
 			} catch (MissingObjectException e) {
-				throw new CorruptPackIndexException(MessageFormat
-						.format(JGitText.get().missingCRC, entry.getName()),
+				CorruptPackIndexException cpe = new CorruptPackIndexException(
+						MessageFormat.format(JGitText.get().missingCRC,
+								entry.getName()),
 						ErrorType.MISSING_CRC);
+				cpe.initCause(e);
+				throw cpe;
 			}
 		}
 
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsBlockCacheConfig.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsBlockCacheConfig.java
index bee2e01..6e7ad3e 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsBlockCacheConfig.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsBlockCacheConfig.java
@@ -236,7 +236,7 @@ public DfsBlockCacheConfig fromConfig(Config rc) {
 						JGitText.get().enumValueNotSupported3,
 						CONFIG_CORE_SECTION,
 						CONFIG_DFS_SECTION,
-						CONFIG_KEY_STREAM_RATIO, v));
+						CONFIG_KEY_STREAM_RATIO, v), e);
 			}
 		}
 		return this;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ObjectDirectory.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ObjectDirectory.java
index 857c173..1695870 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ObjectDirectory.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ObjectDirectory.java
@@ -769,7 +769,8 @@ Set<ObjectId> getShallowCommits() throws IOException {
 						shallowCommitsIds.add(ObjectId.fromString(line));
 					} catch (IllegalArgumentException ex) {
 						throw new IOException(MessageFormat
-								.format(JGitText.get().badShallowLine, line));
+								.format(JGitText.get().badShallowLine, line),
+								ex);
 					}
 				}
 			}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackFile.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackFile.java
index 0de818a..984c163 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackFile.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackFile.java
@@ -1071,7 +1071,7 @@ long getObjectSize(WindowCursor curs, long pos)
 		} catch (DataFormatException e) {
 			throw new CorruptObjectException(MessageFormat.format(
 					JGitText.get().objectAtHasBadZlibStream, Long.valueOf(pos),
-					getPackFile()));
+					getPackFile()), e);
 		}
 	}
 
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/RefDirectory.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/RefDirectory.java
index b636db6..fddd430 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/RefDirectory.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/RefDirectory.java
@@ -1035,7 +1035,10 @@ protected void writeFile(String name, byte[] content)
 					lck.waitForStatChange();
 				} catch (InterruptedException e) {
 					lck.unlock();
-					throw new ObjectWritingException(MessageFormat.format(JGitText.get().interruptedWriting, name));
+					throw new ObjectWritingException(
+							MessageFormat.format(
+									JGitText.get().interruptedWriting, name),
+							e);
 				}
 				if (!lck.commit())
 					throw new ObjectWritingException(MessageFormat.format(JGitText.get().unableToWrite, name));
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/UnpackedObject.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/UnpackedObject.java
index 743badb..bf47d2c 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/UnpackedObject.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/UnpackedObject.java
@@ -149,8 +149,10 @@ static ObjectLoader open(InputStream in, File path, AnyObjectId id,
 			}
 			return new LargeObject(type, size, path, id, wc.db);
 		} catch (ZipException badStream) {
-			throw new CorruptObjectException(id,
+			CorruptObjectException coe = new CorruptObjectException(id,
 					JGitText.get().corruptObjectBadStream);
+			coe.initCause(badStream);
+			throw coe;
 		}
 	}
 
@@ -192,8 +194,10 @@ static long getSize(InputStream in, AnyObjectId id, WindowCursor wc)
 			}
 			return size;
 		} catch (ZipException badStream) {
-			throw new CorruptObjectException(id,
+			CorruptObjectException coe = new CorruptObjectException(id,
 					JGitText.get().corruptObjectBadStream);
+			coe.initCause(badStream);
+			throw coe;
 		}
 	}
 
@@ -205,8 +209,10 @@ static void checkValidEndOfStream(InputStream in, Inflater inf,
 			try {
 				r = inf.inflate(buf);
 			} catch (DataFormatException e) {
-				throw new CorruptObjectException(id,
+				CorruptObjectException coe = new CorruptObjectException(id,
 						JGitText.get().corruptObjectBadStream);
+				coe.initCause(e);
+				throw coe;
 			}
 			if (r != 0)
 				throw new CorruptObjectException(id,
@@ -277,8 +283,10 @@ public int read(byte[] b, int off, int cnt) throws IOException {
 						remaining -= r;
 					return r;
 				} catch (ZipException badStream) {
-					throw new CorruptObjectException(id,
+					CorruptObjectException coe = new CorruptObjectException(id,
 							JGitText.get().corruptObjectBadStream);
+					coe.initCause(badStream);
+					throw coe;
 				}
 			}
 
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackWriter.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackWriter.java
index 33ffe07..9a6ec76 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackWriter.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackWriter.java
@@ -1579,8 +1579,8 @@ private void parallelDeltaSearch(ProgressMonitor monitor,
 						if (pool.awaitTermination(60, TimeUnit.SECONDS))
 							break;
 					} catch (InterruptedException e) {
-						throw new IOException(
-								JGitText.get().packingCancelledDuringObjectsWriting);
+						throw new IOException(JGitText
+								.get().packingCancelledDuringObjectsWriting, e);
 					}
 				}
 			}
@@ -1604,7 +1604,8 @@ private void parallelDeltaSearch(ProgressMonitor monitor,
 				// Cross our fingers and just break out anyway.
 				//
 				throw new IOException(
-						JGitText.get().packingCancelledDuringObjectsWriting);
+						JGitText.get().packingCancelledDuringObjectsWriting,
+						ie);
 			}
 		}
 
@@ -1645,7 +1646,7 @@ private static void runTasks(ExecutorService pool,
 			for (Future<?> f : futures)
 				f.cancel(true);
 			throw new IOException(
-					JGitText.get().packingCancelledDuringObjectsWriting);
+					JGitText.get().packingCancelledDuringObjectsWriting, ie);
 		}
 	}
 
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/submodule/SubmoduleValidator.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/submodule/SubmoduleValidator.java
index 20066be..d0e2441 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/submodule/SubmoduleValidator.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/submodule/SubmoduleValidator.java
@@ -165,9 +165,10 @@ public static void assertValidGitModulesFile(String gitModulesContents)
 				}
 			}
 		} catch (ConfigInvalidException e) {
-			throw new SubmoduleValidationException(
-					JGitText.get().invalidGitModules,
-					GITMODULES_PARSE);
+			SubmoduleValidationException sve = new SubmoduleValidationException(
+					JGitText.get().invalidGitModules, GITMODULES_PARSE);
+			sve.initCause(e);
+			throw sve;
 		}
 	}
 }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/AbbreviatedObjectId.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/AbbreviatedObjectId.java
index a5e4d78..dc5e5cc 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/AbbreviatedObjectId.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/AbbreviatedObjectId.java
@@ -114,8 +114,11 @@ private static final AbbreviatedObjectId fromHexString(final byte[] bs,
 			final int d = hexUInt32(bs, ptr + 24, end);
 			final int e = hexUInt32(bs, ptr + 32, end);
 			return new AbbreviatedObjectId(end - ptr, a, b, c, d, e);
-		} catch (ArrayIndexOutOfBoundsException e1) {
-			throw new InvalidObjectIdException(bs, ptr, end - ptr);
+		} catch (ArrayIndexOutOfBoundsException e) {
+			InvalidObjectIdException e1 = new InvalidObjectIdException(bs, ptr,
+					end - ptr);
+			e1.initCause(e);
+			throw e1;
 		}
 	}
 
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/Constants.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/Constants.java
index d502274..ffc742d 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/Constants.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/Constants.java
@@ -601,7 +601,10 @@ public static int decodeTypeString(final AnyObjectId id,
 				throw new CorruptObjectException(id, JGitText.get().corruptObjectInvalidType);
 			}
 		} catch (ArrayIndexOutOfBoundsException bad) {
-			throw new CorruptObjectException(id, JGitText.get().corruptObjectInvalidType);
+			CorruptObjectException coe = new CorruptObjectException(id,
+					JGitText.get().corruptObjectInvalidType);
+			coe.initCause(bad);
+			throw coe;
 		}
 	}
 
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/DefaultTypedConfigGetter.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/DefaultTypedConfigGetter.java
index abc9b21..cc0b995 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/DefaultTypedConfigGetter.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/DefaultTypedConfigGetter.java
@@ -46,7 +46,7 @@ public boolean getBoolean(Config config, String section, String subsection,
 			return StringUtils.toBoolean(n);
 		} catch (IllegalArgumentException err) {
 			throw new IllegalArgumentException(MessageFormat.format(
-					JGitText.get().invalidBooleanValue, section, name, n));
+					JGitText.get().invalidBooleanValue, section, name, n), err);
 		}
 	}
 
@@ -152,7 +152,8 @@ public long getLong(Config config, String section, String subsection,
 			return mul * Long.parseLong(n);
 		} catch (NumberFormatException nfe) {
 			throw new IllegalArgumentException(MessageFormat.format(
-					JGitText.get().invalidIntegerValue, section, name, str));
+					JGitText.get().invalidIntegerValue, section, name, str),
+					nfe);
 		}
 	}
 
@@ -239,7 +240,10 @@ public long getTimeUnit(Config config, String section, String subsection,
 			return wantUnit.convert(Long.parseLong(digits) * inputMul,
 					inputUnit);
 		} catch (NumberFormatException nfe) {
-			throw notTimeUnit(section, subsection, unitName, valueString);
+			IllegalArgumentException iae = notTimeUnit(section, subsection,
+					unitName, valueString);
+			iae.initCause(nfe);
+			throw iae;
 		}
 	}
 
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/MutableObjectId.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/MutableObjectId.java
index 86b306d..4a712ba 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/MutableObjectId.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/MutableObjectId.java
@@ -234,9 +234,11 @@ private void fromHexString(byte[] bs, int p) {
 			w3 = RawParseUtils.parseHexInt32(bs, p + 16);
 			w4 = RawParseUtils.parseHexInt32(bs, p + 24);
 			w5 = RawParseUtils.parseHexInt32(bs, p + 32);
-		} catch (ArrayIndexOutOfBoundsException e1) {
-			throw new InvalidObjectIdException(bs, p,
+		} catch (ArrayIndexOutOfBoundsException e) {
+			InvalidObjectIdException e1 = new InvalidObjectIdException(bs, p,
 					Constants.OBJECT_ID_STRING_LENGTH);
+			e1.initCause(e);
+			throw e1;
 		}
 	}
 
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectId.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectId.java
index 11c0aef..269049f 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectId.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectId.java
@@ -213,9 +213,11 @@ private static final ObjectId fromHexString(byte[] bs, int p) {
 			final int d = RawParseUtils.parseHexInt32(bs, p + 24);
 			final int e = RawParseUtils.parseHexInt32(bs, p + 32);
 			return new ObjectId(a, b, c, d, e);
-		} catch (ArrayIndexOutOfBoundsException e1) {
-			throw new InvalidObjectIdException(bs, p,
+		} catch (ArrayIndexOutOfBoundsException e) {
+			InvalidObjectIdException e1 = new InvalidObjectIdException(bs, p,
 					Constants.OBJECT_ID_STRING_LENGTH);
+			e1.initCause(e);
+			throw e1;
 		}
 	}
 
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/Repository.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/Repository.java
index 503e218..a7a832c 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/Repository.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/Repository.java
@@ -550,9 +550,11 @@ private Object resolve(RevWalk rw, String revstr)
 						try {
 							pnum = Integer.parseInt(parentnum);
 						} catch (NumberFormatException e) {
-							throw new RevisionSyntaxException(
+							RevisionSyntaxException rse = new RevisionSyntaxException(
 									JGitText.get().invalidCommitParentNumber,
 									revstr);
+							rse.initCause(e);
+							throw rse;
 						}
 						if (pnum != 0) {
 							RevCommit commit = (RevCommit) rev;
@@ -647,8 +649,10 @@ private Object resolve(RevWalk rw, String revstr)
 					try {
 						dist = Integer.parseInt(distnum);
 					} catch (NumberFormatException e) {
-						throw new RevisionSyntaxException(
+						RevisionSyntaxException rse = new RevisionSyntaxException(
 								JGitText.get().invalidAncestryLength, revstr);
+						rse.initCause(e);
+						throw rse;
 					}
 				} else
 					dist = 1;
@@ -707,7 +711,10 @@ private Object resolve(RevWalk rw, String revstr)
 							remoteConfig = new RemoteConfig(getConfig(),
 									"origin"); //$NON-NLS-1$
 						} catch (URISyntaxException e) {
-							throw new RevisionSyntaxException(revstr);
+							RevisionSyntaxException rse = new RevisionSyntaxException(
+									revstr);
+							rse.initCause(e);
+							throw rse;
 						}
 						String remoteBranchName = getConfig()
 								.getString(
@@ -874,8 +881,11 @@ private RevCommit resolveReflog(RevWalk rw, Ref ref, String time)
 		try {
 			number = Integer.parseInt(time);
 		} catch (NumberFormatException nfe) {
-			throw new RevisionSyntaxException(MessageFormat.format(
-					JGitText.get().invalidReflogRevision, time));
+			RevisionSyntaxException rse = new RevisionSyntaxException(
+					MessageFormat.format(JGitText.get().invalidReflogRevision,
+							time));
+			rse.initCause(nfe);
+			throw rse;
 		}
 		assert number >= 0;
 		ReflogReader reader = getReflogReader(ref.getName());
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/AmazonS3.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/AmazonS3.java
index a177c29..1e7f3b1 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/AmazonS3.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/AmazonS3.java
@@ -655,7 +655,8 @@ void list() throws IOException {
 					try {
 						xr = XMLReaderFactory.createXMLReader();
 					} catch (SAXException e) {
-						throw new IOException(JGitText.get().noXMLParserAvailable);
+						throw new IOException(
+								JGitText.get().noXMLParserAvailable, e);
 					}
 					xr.setContentHandler(this);
 					try (InputStream in = c.getInputStream()) {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackConnection.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackConnection.java
index 8604244..1417fae 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackConnection.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackConnection.java
@@ -203,7 +203,9 @@ private void readAdvertisedRefsImpl() throws IOException {
 			try {
 				id  = ObjectId.fromString(line.substring(0, 40));
 			} catch (InvalidObjectIdException e) {
-				throw invalidRefAdvertisementLine(line);
+				PackProtocolException ppe = invalidRefAdvertisementLine(line);
+				ppe.initCause(e);
+				throw ppe;
 			}
 			if (name.equals(".have")) { //$NON-NLS-1$
 				additionalHaves.add(id);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PacketLineIn.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PacketLineIn.java
index 93800d5..c992bb1 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PacketLineIn.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PacketLineIn.java
@@ -286,7 +286,7 @@ int readLength() throws IOException {
 		try {
 			len = RawParseUtils.parseHexInt16(lineBuffer, 0);
 		} catch (ArrayIndexOutOfBoundsException err) {
-			throw invalidHeader();
+			throw invalidHeader(err);
 		}
 
 		if (len == 0) {
@@ -320,6 +320,12 @@ private IOException invalidHeader() {
 				+ (char) lineBuffer[2] + (char) lineBuffer[3]));
 	}
 
+	private IOException invalidHeader(Throwable cause) {
+		IOException ioe = invalidHeader();
+		ioe.initCause(cause);
+		return ioe;
+	}
+
 	/**
 	 * IOException thrown by read when the configured input limit is exceeded.
 	 *
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceivePack.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceivePack.java
index 24cd8f3..e505e17 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceivePack.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceivePack.java
@@ -2110,7 +2110,7 @@ public void receive(final InputStream input, final OutputStream output,
 		} catch (InputOverLimitIOException e) {
 			String msg = JGitText.get().tooManyCommands;
 			fatalError(msg);
-			throw new PackProtocolException(msg);
+			throw new PackProtocolException(msg, e);
 		} finally {
 			try {
 				close();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TestProtocol.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TestProtocol.java
index 13b891f..c6ecb3a 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TestProtocol.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TestProtocol.java
@@ -140,7 +140,7 @@ public synchronized URIish register(C req, Repository remote) {
 			int n = handles.size();
 			uri = new URIish(SCHEME + "://test/conn" + n); //$NON-NLS-1$
 		} catch (URISyntaxException e) {
-			throw new IllegalStateException();
+			throw new IllegalStateException(e);
 		}
 		handles.put(uri, new Handle(req, remote));
 		return uri;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportBundleFile.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportBundleFile.java
index 155c115..04ebddb 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportBundleFile.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportBundleFile.java
@@ -113,7 +113,10 @@ public FetchConnection openFetch() throws NotSupportedException,
 		try {
 			src = new FileInputStream(bundle);
 		} catch (FileNotFoundException err) {
-			throw new TransportException(uri, JGitText.get().notFound);
+			TransportException te = new TransportException(uri,
+					JGitText.get().notFound);
+			te.initCause(err);
+			throw te;
 		}
 		return new BundleFetchConnection(this, src);
 	}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportLocal.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportLocal.java
index be17b44..403f98d 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportLocal.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportLocal.java
@@ -143,7 +143,10 @@ private Repository openRepo() throws TransportException {
 					.setFS(local != null ? local.getFS() : FS.DETECTED)
 					.setGitDir(remoteGitDir).build();
 		} catch (IOException err) {
-			throw new TransportException(uri, JGitText.get().notAGitDirectory);
+			TransportException te = new TransportException(uri,
+					JGitText.get().notAGitDirectory);
+			te.initCause(err);
+			throw te;
 		}
 	}
 
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/URIish.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/URIish.java
index 6ebb668..858d1f7 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/URIish.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/URIish.java
@@ -266,7 +266,10 @@ private static String unescape(String s) throws URISyntaxException {
 				try {
 					val = parseHexByte(c1, c2);
 				} catch (ArrayIndexOutOfBoundsException e) {
-					throw new URISyntaxException(s, JGitText.get().cannotParseGitURIish);
+					URISyntaxException use = new URISyntaxException(s,
+							JGitText.get().cannotParseGitURIish);
+					use.initCause(e);
+					throw use;
 				}
 				os[j++] = (byte) val;
 				i += 2;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/WalkEncryption.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/WalkEncryption.java
index 1880c8b..df9f11e 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/WalkEncryption.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/WalkEncryption.java
@@ -282,9 +282,12 @@ interface Vals {
 		String REGEX_TRANS = "(.+)/(.+)/(.+)"; //$NON-NLS-1$
 	}
 
-	static GeneralSecurityException securityError(String message) {
-		return new GeneralSecurityException(
+	static GeneralSecurityException securityError(String message,
+			Throwable cause) {
+		GeneralSecurityException e = new GeneralSecurityException(
 				MessageFormat.format(JGitText.get().encryptionError, message));
+		e.initCause(cause);
+		return e;
 	}
 
 	/**
@@ -332,21 +335,21 @@ static abstract class SymmetricEncryption extends WalkEncryption
 			try {
 				size = Integer.parseInt(keySize);
 			} catch (Exception e) {
-				throw securityError(X_KEY_SIZE + EMPTY + keySize);
+				throw securityError(X_KEY_SIZE + EMPTY + keySize, e);
 			}
 
 			final int iter;
 			try {
 				iter = Integer.parseInt(keyIter);
 			} catch (Exception e) {
-				throw securityError(X_KEY_ITER + EMPTY + keyIter);
+				throw securityError(X_KEY_ITER + EMPTY + keyIter, e);
 			}
 
 			final byte[] salt;
 			try {
 				salt = Hex.decode(keySalt.replaceAll(REGEX_WS, EMPTY));
 			} catch (Exception e) {
-				throw securityError(X_KEY_SALT + EMPTY + keySalt);
+				throw securityError(X_KEY_SALT + EMPTY + keySalt, e);
 			}
 
 			KeySpec keySpec = new PBEKeySpec(pass.toCharArray(), salt, iter, size);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/WorkingTreeIterator.java b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/WorkingTreeIterator.java
index 02ca86b..2c3f3e2 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/WorkingTreeIterator.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/WorkingTreeIterator.java
@@ -1159,7 +1159,7 @@ void encodeName(CharsetEncoder enc) {
 			} catch (CharacterCodingException e) {
 				// This should so never happen.
 				throw new RuntimeException(MessageFormat.format(
-						JGitText.get().unencodeableFile, getName()));
+						JGitText.get().unencodeableFile, getName()), e);
 			}
 
 			encodedNameLen = b.limit();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/FileUtils.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/FileUtils.java
index fa99087..4831fbb 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/FileUtils.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/FileUtils.java
@@ -300,7 +300,8 @@ public static void rename(final File src, final File dst,
 			} catch (InterruptedException e) {
 				throw new IOException(
 						MessageFormat.format(JGitText.get().renameFileFailed,
-								src.getAbsolutePath(), dst.getAbsolutePath()));
+								src.getAbsolutePath(), dst.getAbsolutePath()),
+						e);
 			}
 		}
 		throw new IOException(
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/io/TimeoutInputStream.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/io/TimeoutInputStream.java
index 1356136..1947b3b 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/io/TimeoutInputStream.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/io/TimeoutInputStream.java
@@ -70,7 +70,7 @@ public int read() throws IOException {
 			beginRead();
 			return super.read();
 		} catch (InterruptedIOException e) {
-			throw readTimedOut();
+			throw readTimedOut(e);
 		} finally {
 			endRead();
 		}
@@ -89,7 +89,7 @@ public int read(byte[] buf, int off, int cnt) throws IOException {
 			beginRead();
 			return super.read(buf, off, cnt);
 		} catch (InterruptedIOException e) {
-			throw readTimedOut();
+			throw readTimedOut(e);
 		} finally {
 			endRead();
 		}
@@ -102,7 +102,7 @@ public long skip(long cnt) throws IOException {
 			beginRead();
 			return super.skip(cnt);
 		} catch (InterruptedIOException e) {
-			throw readTimedOut();
+			throw readTimedOut(e);
 		} finally {
 			endRead();
 		}
@@ -116,8 +116,11 @@ private void endRead() {
 		myTimer.end();
 	}
 
-	private InterruptedIOException readTimedOut() {
-		return new InterruptedIOException(MessageFormat.format(
-				JGitText.get().readTimedOut, Integer.valueOf(timeout)));
+	private InterruptedIOException readTimedOut(InterruptedIOException e) {
+		InterruptedIOException interrupted = new InterruptedIOException(
+				MessageFormat.format(JGitText.get().readTimedOut,
+						Integer.valueOf(timeout)));
+		interrupted.initCause(e);
+		return interrupted;
 	}
 }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/io/TimeoutOutputStream.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/io/TimeoutOutputStream.java
index 7532c42..3fbf6ff 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/io/TimeoutOutputStream.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/io/TimeoutOutputStream.java
@@ -72,7 +72,7 @@ public void write(int b) throws IOException {
 			beginWrite();
 			dst.write(b);
 		} catch (InterruptedIOException e) {
-			throw writeTimedOut();
+			throw writeTimedOut(e);
 		} finally {
 			endWrite();
 		}
@@ -91,7 +91,7 @@ public void write(byte[] buf, int off, int len) throws IOException {
 			beginWrite();
 			dst.write(buf, off, len);
 		} catch (InterruptedIOException e) {
-			throw writeTimedOut();
+			throw writeTimedOut(e);
 		} finally {
 			endWrite();
 		}
@@ -104,7 +104,7 @@ public void flush() throws IOException {
 			beginWrite();
 			dst.flush();
 		} catch (InterruptedIOException e) {
-			throw writeTimedOut();
+			throw writeTimedOut(e);
 		} finally {
 			endWrite();
 		}
@@ -117,7 +117,7 @@ public void close() throws IOException {
 			beginWrite();
 			dst.close();
 		} catch (InterruptedIOException e) {
-			throw writeTimedOut();
+			throw writeTimedOut(e);
 		} finally {
 			endWrite();
 		}
@@ -131,8 +131,11 @@ private void endWrite() {
 		myTimer.end();
 	}
 
-	private InterruptedIOException writeTimedOut() {
-		return new InterruptedIOException(MessageFormat.format(
-				JGitText.get().writeTimedOut, Integer.valueOf(timeout)));
+	private InterruptedIOException writeTimedOut(InterruptedIOException cause) {
+		InterruptedIOException e = new InterruptedIOException(
+				MessageFormat.format(JGitText.get().writeTimedOut,
+						Integer.valueOf(timeout)));
+		e.initCause(cause);
+		return e;
 	}
 }
diff --git a/tools/BUILD b/tools/BUILD
index d668377..2b20874 100644
--- a/tools/BUILD
+++ b/tools/BUILD
@@ -78,6 +78,7 @@
         "-Xep:TypeParameterShadowing:ERROR",
         "-Xep:TypeParameterUnusedInFormals:WARN",
         "-Xep:URLEqualsHashCode:ERROR",
+        "-Xep:UnusedException:ERROR",
         "-Xep:UnsynchronizedOverridesSynchronized:ERROR",
         "-Xep:WaitNotInLoop:ERROR",
     ],