changeset 628:6526d8adbc0f

Explicit HgRuntimeException to facilitate easy switch from runtime to checked exceptions
author Artem Tikhomirov <tikhomirov.artem@gmail.com>
date Wed, 22 May 2013 15:52:31 +0200
parents 5153eb73b18d
children 5f52074707b2
files cmdline/org/tmatesoft/hg/console/Bundle.java cmdline/org/tmatesoft/hg/console/ChangesetDumpHandler.java cmdline/org/tmatesoft/hg/console/Log.java cmdline/org/tmatesoft/hg/console/Main.java cmdline/org/tmatesoft/hg/console/Manifest.java src/org/tmatesoft/hg/core/ChangesetTransformer.java src/org/tmatesoft/hg/core/HgAnnotateCommand.java src/org/tmatesoft/hg/core/HgChangesetHandler.java src/org/tmatesoft/hg/core/HgChangesetTreeHandler.java src/org/tmatesoft/hg/core/HgCloneCommand.java src/org/tmatesoft/hg/core/HgCommitCommand.java src/org/tmatesoft/hg/core/HgFileRenameHandlerMixin.java src/org/tmatesoft/hg/core/HgFileRevision.java src/org/tmatesoft/hg/core/HgIOException.java src/org/tmatesoft/hg/core/HgIncomingCommand.java src/org/tmatesoft/hg/core/HgLogCommand.java src/org/tmatesoft/hg/core/HgManifestCommand.java src/org/tmatesoft/hg/core/HgManifestHandler.java src/org/tmatesoft/hg/core/HgOutgoingCommand.java src/org/tmatesoft/hg/core/HgStatus.java src/org/tmatesoft/hg/internal/BlameHelper.java src/org/tmatesoft/hg/internal/ChangelogHelper.java src/org/tmatesoft/hg/internal/ChangelogMonitor.java src/org/tmatesoft/hg/internal/CommitFacility.java src/org/tmatesoft/hg/internal/ConfigFile.java src/org/tmatesoft/hg/internal/CsetParamKeeper.java src/org/tmatesoft/hg/internal/DataSerializer.java src/org/tmatesoft/hg/internal/DirstateBuilder.java src/org/tmatesoft/hg/internal/FileAnnotation.java src/org/tmatesoft/hg/internal/FileHistory.java src/org/tmatesoft/hg/internal/FileRevisionHistoryChunk.java src/org/tmatesoft/hg/internal/Internals.java src/org/tmatesoft/hg/internal/LineReader.java src/org/tmatesoft/hg/internal/NewlineFilter.java src/org/tmatesoft/hg/internal/PhasesHelper.java src/org/tmatesoft/hg/internal/RepositoryComparator.java src/org/tmatesoft/hg/internal/RevisionDescendants.java src/org/tmatesoft/hg/internal/RevisionLookup.java src/org/tmatesoft/hg/internal/RevlogCompressor.java src/org/tmatesoft/hg/internal/RevlogStream.java src/org/tmatesoft/hg/internal/RevlogStreamWriter.java src/org/tmatesoft/hg/internal/WorkingCopyContent.java src/org/tmatesoft/hg/internal/WorkingDirFileWriter.java src/org/tmatesoft/hg/repo/HgBookmarks.java src/org/tmatesoft/hg/repo/HgBranches.java src/org/tmatesoft/hg/repo/HgBundle.java src/org/tmatesoft/hg/repo/HgChangelog.java src/org/tmatesoft/hg/repo/HgDataFile.java src/org/tmatesoft/hg/repo/HgInvalidControlFileException.java src/org/tmatesoft/hg/repo/HgInvalidFileException.java src/org/tmatesoft/hg/repo/HgLookup.java src/org/tmatesoft/hg/repo/HgManifest.java src/org/tmatesoft/hg/repo/HgMergeState.java src/org/tmatesoft/hg/repo/HgParentChildMap.java src/org/tmatesoft/hg/repo/HgRepository.java src/org/tmatesoft/hg/repo/HgRevisionMap.java src/org/tmatesoft/hg/repo/HgStatusCollector.java src/org/tmatesoft/hg/repo/HgTags.java src/org/tmatesoft/hg/repo/HgWorkingCopyStatusCollector.java src/org/tmatesoft/hg/repo/Revlog.java src/org/tmatesoft/hg/repo/ext/MqManager.java src/org/tmatesoft/hg/repo/ext/Rebase.java test/org/tmatesoft/hg/test/MapTagsToFileRevisions.java test/org/tmatesoft/hg/test/TestAuxUtilities.java test/org/tmatesoft/hg/test/TestBlame.java test/org/tmatesoft/hg/test/TestCommit.java test/org/tmatesoft/hg/test/TestFileFlags.java test/org/tmatesoft/hg/test/TestHistory.java test/org/tmatesoft/hg/test/TestPhases.java test/org/tmatesoft/hg/test/TestRevlog.java
diffstat 70 files changed, 655 insertions(+), 472 deletions(-) [+]
line wrap: on
line diff
--- a/cmdline/org/tmatesoft/hg/console/Bundle.java	Tue May 21 20:17:33 2013 +0200
+++ b/cmdline/org/tmatesoft/hg/console/Bundle.java	Wed May 22 15:52:31 2013 +0200
@@ -29,6 +29,7 @@
 import org.tmatesoft.hg.repo.HgBundle.GroupElement;
 import org.tmatesoft.hg.repo.HgBundle.Inspector;
 import org.tmatesoft.hg.repo.HgChangelog.RawChangeset;
+import org.tmatesoft.hg.repo.HgRuntimeException;
 
 
 /**
@@ -60,7 +61,7 @@
 		hgBundle.changes(hgRepo, new HgChangelog.Inspector() {
 			private final HgChangelog changelog = hgRepo.getChangelog();
 			
-			public void next(int revisionNumber, Nodeid nodeid, RawChangeset cset) {
+			public void next(int revisionNumber, Nodeid nodeid, RawChangeset cset) throws HgRuntimeException {
 				if (changelog.isKnown(nodeid)) {
 					System.out.print("+");
 				} else {
@@ -99,7 +100,7 @@
 
  */
 
-	public static void dump(HgBundle hgBundle) throws HgException {
+	public static void dump(HgBundle hgBundle) throws HgException, HgRuntimeException {
 		Dump dump = new Dump();
 		hgBundle.inspectAll(dump);
 		System.out.println("Total files:" + dump.names.size());
--- a/cmdline/org/tmatesoft/hg/console/ChangesetDumpHandler.java	Tue May 21 20:17:33 2013 +0200
+++ b/cmdline/org/tmatesoft/hg/console/ChangesetDumpHandler.java	Wed May 22 15:52:31 2013 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012 TMate Software Ltd
+ * Copyright (c) 2011-2013 TMate Software Ltd
  *  
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -26,6 +26,7 @@
 import org.tmatesoft.hg.core.HgFileRevision;
 import org.tmatesoft.hg.core.Nodeid;
 import org.tmatesoft.hg.repo.HgRepository;
+import org.tmatesoft.hg.repo.HgRuntimeException;
 import org.tmatesoft.hg.util.Path;
 
 /**
@@ -43,7 +44,7 @@
 	private final HgRepository repo;
 	private final int tip;
 
-	public ChangesetDumpHandler(HgRepository hgRepo) {
+	public ChangesetDumpHandler(HgRepository hgRepo) throws HgRuntimeException {
 		repo = hgRepo;
 		tip = hgRepo.getChangelog().getLastRevision();
 	}
@@ -63,7 +64,7 @@
 		return this;
 	}
 
-	public void cset(HgChangeset changeset) {
+	public void cset(HgChangeset changeset) throws HgRuntimeException {
 		try {
 			final String s = print(changeset);
 			if (reverseOrder) {
@@ -89,7 +90,7 @@
 		l.clear();
 	}
 
-	private String print(HgChangeset cset) throws HgException {
+	private String print(HgChangeset cset) throws HgException, HgRuntimeException {
 		StringBuilder sb = new StringBuilder();
 		Formatter f = new Formatter(sb);
 		final Nodeid csetNodeid = cset.getNodeid();
--- a/cmdline/org/tmatesoft/hg/console/Log.java	Tue May 21 20:17:33 2013 +0200
+++ b/cmdline/org/tmatesoft/hg/console/Log.java	Wed May 22 15:52:31 2013 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2012 TMate Software Ltd
+ * Copyright (c) 2010-2013 TMate Software Ltd
  *  
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -26,6 +26,7 @@
 import org.tmatesoft.hg.core.HgLogCommand;
 import org.tmatesoft.hg.repo.HgDataFile;
 import org.tmatesoft.hg.repo.HgRepository;
+import org.tmatesoft.hg.repo.HgRuntimeException;
 import org.tmatesoft.hg.util.CancelSupport;
 import org.tmatesoft.hg.util.ProgressSupport;
 
@@ -124,7 +125,7 @@
 	private static final class Dump extends ChangesetDumpHandler implements HgChangesetHandler.WithCopyHistory {
 		private final RenameDumpHandler renameHandlerDelegate;
 
-		public Dump(HgRepository hgRepo) {
+		public Dump(HgRepository hgRepo) throws HgRuntimeException {
 			super(hgRepo);
 			renameHandlerDelegate = new RenameDumpHandler();
 		}
--- a/cmdline/org/tmatesoft/hg/console/Main.java	Tue May 21 20:17:33 2013 +0200
+++ b/cmdline/org/tmatesoft/hg/console/Main.java	Wed May 22 15:52:31 2013 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012 TMate Software Ltd
+ * Copyright (c) 2011-2013 TMate Software Ltd
  *  
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -57,6 +57,7 @@
 import org.tmatesoft.hg.repo.HgDirstate.Record;
 import org.tmatesoft.hg.repo.HgIgnore;
 import org.tmatesoft.hg.repo.HgInternals;
+import org.tmatesoft.hg.repo.HgInvalidControlFileException;
 import org.tmatesoft.hg.repo.HgManifest;
 import org.tmatesoft.hg.repo.HgManifest.Flags;
 import org.tmatesoft.hg.repo.HgMergeState;
@@ -219,7 +220,7 @@
 		cmd.file("a2.txt", true, false);
 		final int[] count = new int[] { 0 };
 		class MyHandler implements HgChangesetTreeHandler, Adaptable {
-			public void treeElement(HgChangesetTreeHandler.TreeElement entry) {
+			public void treeElement(HgChangesetTreeHandler.TreeElement entry) throws HgRuntimeException {
 				StringBuilder sb = new StringBuilder();
 				HashSet<Nodeid> test = new HashSet<Nodeid>(entry.childRevisions());
 				for (HgChangeset cc : entry.children()) {
@@ -519,7 +520,7 @@
 		System.out.println(bac.toArray().length);
 	}
 	
-	private void dumpIgnored() {
+	private void dumpIgnored() throws HgInvalidControlFileException {
 		String[] toCheck = new String[] {"design.txt", "src/com/tmate/hgkit/ll/Changelog.java", "src/Extras.java", "bin/com/tmate/hgkit/ll/Changelog.class"};
 		HgIgnore ignore = hgRepo.getIgnore();
 		for (int i = 0; i < toCheck.length; i++) {
@@ -609,7 +610,7 @@
 			public void dir(Path p) {
 				System.out.println(p);
 			}
-			public void file(HgFileRevision fileRevision) {
+			public void file(HgFileRevision fileRevision) throws HgRuntimeException {
 				System.out.print(fileRevision.getRevision());;
 				System.out.print("   ");
 				System.out.printf("%s %s", fileRevision.getParents().first().shortNotation(), fileRevision.getParents().second().shortNotation());
@@ -672,7 +673,7 @@
 	}
 
 
-	private void testStatusInternals() throws HgException {
+	private void testStatusInternals() throws HgException, HgRuntimeException {
 		HgDataFile n = hgRepo.getFileNode(Path.create("design.txt"));
 		for (String s : new String[] {"011dfd44417c72bd9e54cf89b82828f661b700ed", "e5529faa06d53e06a816e56d218115b42782f1ba", "c18e7111f1fc89a80a00f6a39d51288289a382fc"}) {
 			// expected: 359, 2123, 3079
--- a/cmdline/org/tmatesoft/hg/console/Manifest.java	Tue May 21 20:17:33 2013 +0200
+++ b/cmdline/org/tmatesoft/hg/console/Manifest.java	Wed May 22 15:52:31 2013 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2012 TMate Software Ltd
+ * Copyright (c) 2010-2013 TMate Software Ltd
  *  
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -27,6 +27,7 @@
 import org.tmatesoft.hg.repo.HgInvalidRevisionException;
 import org.tmatesoft.hg.repo.HgManifest;
 import org.tmatesoft.hg.repo.HgRepository;
+import org.tmatesoft.hg.repo.HgRuntimeException;
 import org.tmatesoft.hg.util.Path;
 
 
@@ -52,7 +53,7 @@
 			}
 			public void dir(Path p) {
 			}
-			public void file(HgFileRevision fileRevision) {
+			public void file(HgFileRevision fileRevision) throws HgRuntimeException {
 				try {
 					if (debug) {
 						System.out.print(fileRevision.getRevision());;
--- a/src/org/tmatesoft/hg/core/ChangesetTransformer.java	Tue May 21 20:17:33 2013 +0200
+++ b/src/org/tmatesoft/hg/core/ChangesetTransformer.java	Wed May 22 15:52:31 2013 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012 TMate Software Ltd
+ * Copyright (c) 2011-2013 TMate Software Ltd
  *  
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -24,6 +24,7 @@
 import org.tmatesoft.hg.repo.HgChangelog;
 import org.tmatesoft.hg.repo.HgChangelog.RawChangeset;
 import org.tmatesoft.hg.repo.HgRepository;
+import org.tmatesoft.hg.repo.HgRuntimeException;
 import org.tmatesoft.hg.repo.HgStatusCollector;
 import org.tmatesoft.hg.repo.HgParentChildMap;
 import org.tmatesoft.hg.util.Adaptable;
@@ -63,7 +64,7 @@
 		lifecycleBridge = new LifecycleBridge(ps, cs);
 	}
 	
-	public void next(int revisionNumber, Nodeid nodeid, RawChangeset cset) {
+	public void next(int revisionNumber, Nodeid nodeid, RawChangeset cset) throws HgRuntimeException {
 		if (branches != null && !branches.contains(cset.branch())) {
 			return;
 		}
--- a/src/org/tmatesoft/hg/core/HgAnnotateCommand.java	Tue May 21 20:17:33 2013 +0200
+++ b/src/org/tmatesoft/hg/core/HgAnnotateCommand.java	Wed May 22 15:52:31 2013 +0200
@@ -28,6 +28,7 @@
 import org.tmatesoft.hg.repo.HgBlameInspector.BlockData;
 import org.tmatesoft.hg.repo.HgDataFile;
 import org.tmatesoft.hg.repo.HgRepository;
+import org.tmatesoft.hg.repo.HgRuntimeException;
 import org.tmatesoft.hg.util.CancelSupport;
 import org.tmatesoft.hg.util.CancelledException;
 import org.tmatesoft.hg.util.Path;
@@ -107,27 +108,31 @@
 		final CancelSupport cancellation = getCancelSupport(inspector, true);
 		cancellation.checkCancelled();
 		progress.start(2);
-		HgDataFile df = repo.getFileNode(file);
-		if (!df.exists()) {
-			return;
+		try {
+			HgDataFile df = repo.getFileNode(file);
+			if (!df.exists()) {
+				return;
+			}
+			final int changesetStart = followRename ? 0 : df.getChangesetRevisionIndex(0);
+			Collector c = new Collector(cancellation);
+			FileAnnotation fa = new FileAnnotation(c);
+			df.annotate(changesetStart, annotateRevision.get(), fa, HgIterateDirection.NewToOld);
+			progress.worked(1);
+			c.throwIfCancelled();
+			cancellation.checkCancelled();
+			ProgressSupport.Sub subProgress = new ProgressSupport.Sub(progress, 1);
+			subProgress.start(c.lineRevisions.length);
+			LineImpl li = new LineImpl();
+			for (int i = 0; i < c.lineRevisions.length; i++) {
+				li.init(i+1, c.lineRevisions[i], c.line(i));
+				inspector.next(li);
+				subProgress.worked(1);
+				cancellation.checkCancelled();
+			}
+			subProgress.done();
+		} catch (HgRuntimeException ex) {
+			throw new HgLibraryFailureException(ex);
 		}
-		final int changesetStart = followRename ? 0 : df.getChangesetRevisionIndex(0);
-		Collector c = new Collector(cancellation);
-		FileAnnotation fa = new FileAnnotation(c);
-		df.annotate(changesetStart, annotateRevision.get(), fa, HgIterateDirection.NewToOld);
-		progress.worked(1);
-		c.throwIfCancelled();
-		cancellation.checkCancelled();
-		ProgressSupport.Sub subProgress = new ProgressSupport.Sub(progress, 1);
-		subProgress.start(c.lineRevisions.length);
-		LineImpl li = new LineImpl();
-		for (int i = 0; i < c.lineRevisions.length; i++) {
-			li.init(i+1, c.lineRevisions[i], c.line(i));
-			inspector.next(li);
-			subProgress.worked(1);
-			cancellation.checkCancelled();
-		}
-		subProgress.done();
 		progress.done();
 	}
 	
--- a/src/org/tmatesoft/hg/core/HgChangesetHandler.java	Tue May 21 20:17:33 2013 +0200
+++ b/src/org/tmatesoft/hg/core/HgChangesetHandler.java	Wed May 22 15:52:31 2013 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012 TMate Software Ltd
+ * Copyright (c) 2011-2013 TMate Software Ltd
  *  
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -17,6 +17,7 @@
 package org.tmatesoft.hg.core;
 
 import org.tmatesoft.hg.internal.Callback;
+import org.tmatesoft.hg.repo.HgRuntimeException;
 import org.tmatesoft.hg.util.Adaptable;
 import org.tmatesoft.hg.util.Path;
 
@@ -32,8 +33,9 @@
 	/**
 	 * @param changeset descriptor of a change, not necessarily a distinct instance each time, {@link HgChangeset#clone() clone()} if need a copy.
 	 * @throws HgCallbackTargetException wrapper for any exception user code may produce 
+	 * @throws HgRuntimeException propagates library issues. <em>Runtime exception</em>
 	 */
-	void cset(HgChangeset changeset) throws HgCallbackTargetException;
+	void cset(HgChangeset changeset) throws HgCallbackTargetException, HgRuntimeException;
 
 
 	/**
--- a/src/org/tmatesoft/hg/core/HgChangesetTreeHandler.java	Tue May 21 20:17:33 2013 +0200
+++ b/src/org/tmatesoft/hg/core/HgChangesetTreeHandler.java	Wed May 22 15:52:31 2013 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012 TMate Software Ltd
+ * Copyright (c) 2011-2013 TMate Software Ltd
  *  
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -20,6 +20,7 @@
 
 import org.tmatesoft.hg.internal.Callback;
 import org.tmatesoft.hg.repo.HgDataFile;
+import org.tmatesoft.hg.repo.HgRuntimeException;
 import org.tmatesoft.hg.util.Pair;
 
 /**
@@ -36,16 +37,18 @@
 	 * @param entry access to various pieces of information about current tree node. Instances might be 
 	 * reused across calls and shall not be kept by client's code
 	 * @throws HgCallbackTargetException wrapper for any exception user code may produce 
+	 * @throws HgRuntimeException propagates library issues. <em>Runtime exception</em>
 	 */
-	public void treeElement(HgChangesetTreeHandler.TreeElement entry) throws HgCallbackTargetException;
+	public void treeElement(HgChangesetTreeHandler.TreeElement entry) throws HgCallbackTargetException, HgRuntimeException;
 
 	interface TreeElement {
 		/**
 		 * Revision of the revlog being iterated. For example, when walking file history, return value represents file revisions.
 		 * 
 		 * @return revision of the revlog being iterated.
+		 * @throws HgRuntimeException subclass thereof to indicate issues with the library. <em>Runtime exception</em>
 		 */
-		public Nodeid fileRevision();
+		public Nodeid fileRevision() throws HgRuntimeException;
 		
 		/**
 		 * File node, provided revlog being iterated is a {@link HgDataFile}; {@link #fileRevision()} 
@@ -55,19 +58,22 @@
 		 * file name for particular revision in the history.
 		 * 
 		 * @return instance of the file being walked, or <code>null</code> if it's not a file but other revlog.
+		 * @throws HgRuntimeException subclass thereof to indicate issues with the library. <em>Runtime exception</em>
 		 */
-		public HgDataFile file();
+		public HgDataFile file() throws HgRuntimeException;
 
 		/**
 		 * @return changeset associated with the current file revision
+		 * @throws HgRuntimeException subclass thereof to indicate issues with the library. <em>Runtime exception</em>
 		 */
-		public HgChangeset changeset();
+		public HgChangeset changeset() throws HgRuntimeException;
 
 		/**
 		 * Lightweight alternative to {@link #changeset()}, identifies changeset in which current file node has been modified 
 		 * @return changeset {@link Nodeid revision} 
+		 * @throws HgRuntimeException subclass thereof to indicate issues with the library. <em>Runtime exception</em>
 		 */
-		public Nodeid changesetRevision();
+		public Nodeid changesetRevision() throws HgRuntimeException;
 
 		/**
 		 * Identifies parent changes, changesets where file/revlog in question was modified prior to change being visited.
@@ -91,25 +97,29 @@
 		 * then this {@link #parents()} call would return pair with single element only, pointing to <code>D</code>
 		 * 
 		 * @return changesets that correspond to parents of the current file node, either pair element may be <code>null</code>.
+		 * @throws HgRuntimeException subclass thereof to indicate issues with the library. <em>Runtime exception</em>
 		 */
-		public Pair<HgChangeset, HgChangeset> parents();
+		public Pair<HgChangeset, HgChangeset> parents() throws HgRuntimeException;
 		
 		/**
 		 * Lightweight alternative to {@link #parents()}, give {@link Nodeid nodeids} only
 		 * @return two values, neither is <code>null</code>, use {@link Nodeid#isNull()} to identify parent not set
+		 * @throws HgRuntimeException subclass thereof to indicate issues with the library. <em>Runtime exception</em>
 		 */
-		public Pair<Nodeid, Nodeid> parentRevisions();
+		public Pair<Nodeid, Nodeid> parentRevisions() throws HgRuntimeException;
 
 		/**
 		 * Changes that originate from the given change and bear it as their parent. 
 		 * @return collection (possibly empty) of immediate children of the change
+		 * @throws HgRuntimeException subclass thereof to indicate issues with the library. <em>Runtime exception</em>
 		 */
-		public Collection<HgChangeset> children();
+		public Collection<HgChangeset> children() throws HgRuntimeException;
 
 		/**
 		 * Lightweight alternative to {@link #children()}.
 		 * @return never <code>null</code>
+		 * @throws HgRuntimeException subclass thereof to indicate issues with the library. <em>Runtime exception</em>
 		 */
-		public Collection<Nodeid> childRevisions();
+		public Collection<Nodeid> childRevisions() throws HgRuntimeException;
 	}
 }
\ No newline at end of file
--- a/src/org/tmatesoft/hg/core/HgCloneCommand.java	Tue May 21 20:17:33 2013 +0200
+++ b/src/org/tmatesoft/hg/core/HgCloneCommand.java	Wed May 22 15:52:31 2013 +0200
@@ -90,7 +90,6 @@
 	 * @throws HgRepositoryNotFoundException
 	 * @throws HgException
 	 * @throws CancelledException
-	 * @throws HgRuntimeException subclass thereof to indicate issues with the library. <em>Runtime exception</em>
 	 */
 	public HgRepository execute() throws HgException, CancelledException {
 		if (destination == null) {
@@ -114,23 +113,27 @@
 		// if cloning remote repo, which can stream and no revision is specified -
 		// can use 'stream_out' wireproto
 		//
-		// pull all changes from the very beginning
-		// XXX consult getContext() if by any chance has a bundle ready, if not, then read and register
-		HgBundle completeChanges = srcRepo.getChanges(Collections.singletonList(NULL));
-		cancel.checkCancelled();
-		WriteDownMate mate = new WriteDownMate(srcRepo.getSessionContext(), destination, progress, cancel);
 		try {
-			// instantiate new repo in the destdir
-			mate.initEmptyRepository();
-			// pull changes
-			completeChanges.inspectAll(mate);
-			mate.checkFailure();
-			mate.complete();
-		} catch (IOException ex) {
-			throw new HgInvalidFileException(getClass().getName(), ex);
-		} finally {
-			completeChanges.unlink();
-			progress.done();
+			// pull all changes from the very beginning
+			// XXX consult getContext() if by any chance has a bundle ready, if not, then read and register
+			HgBundle completeChanges = srcRepo.getChanges(Collections.singletonList(NULL));
+			cancel.checkCancelled();
+			WriteDownMate mate = new WriteDownMate(srcRepo.getSessionContext(), destination, progress, cancel);
+			try {
+				// instantiate new repo in the destdir
+				mate.initEmptyRepository();
+				// pull changes
+				completeChanges.inspectAll(mate);
+				mate.checkFailure();
+				mate.complete();
+			} catch (IOException ex) {
+				throw new HgInvalidFileException(getClass().getName(), ex);
+			} finally {
+				completeChanges.unlink();
+				progress.done();
+			}
+		} catch (HgRuntimeException ex) {
+			throw new HgLibraryFailureException(ex);
 		}
 		return new HgLookup().detect(destination);
 	}
@@ -190,7 +193,7 @@
 			fncacheFile.write();
 		}
 
-		public void changelogStart() {
+		public void changelogStart() throws HgInvalidControlFileException {
 			try {
 				revlogHeader.offset(0).baseRevision(-1);
 				revisionSequence.clear();
@@ -202,7 +205,7 @@
 			stopIfCancelled();
 		}
 
-		public void changelogEnd() {
+		public void changelogEnd() throws HgInvalidControlFileException {
 			try {
 				clearPreviousContent();
 				collectChangelogIndexes = false;
@@ -214,7 +217,7 @@
 			stopIfCancelled();
 		}
 
-		public void manifestStart() {
+		public void manifestStart() throws HgInvalidControlFileException {
 			try {
 				revlogHeader.offset(0).baseRevision(-1);
 				revisionSequence.clear();
@@ -225,7 +228,7 @@
 			stopIfCancelled();
 		}
 
-		public void manifestEnd() {
+		public void manifestEnd() throws HgInvalidControlFileException {
 			try {
 				clearPreviousContent();
 				closeIndexFile();
@@ -236,7 +239,7 @@
 			stopIfCancelled();
 		}
 		
-		public void fileStart(String name) {
+		public void fileStart(String name) throws HgInvalidControlFileException {
 			try {
 				revlogHeader.offset(0).baseRevision(-1);
 				revisionSequence.clear();
@@ -250,7 +253,7 @@
 			stopIfCancelled();
 		}
 
-		public void fileEnd(String name) {
+		public void fileEnd(String name) throws HgInvalidControlFileException {
 			try {
 				fncacheFile.addIndex(pathFactory.path(name)); 
 				clearPreviousContent();
@@ -277,7 +280,7 @@
 			currentFile = null;
 		}
 
-		private int knownRevision(Nodeid p) {
+		private int knownRevision(Nodeid p) throws HgInvalidControlFileException {
 			if (p.isNull()) {
 				return -1;
 			} else {
@@ -291,7 +294,7 @@
 			throw new HgInvalidControlFileException(m, null, new File(hgDir, filename)).setRevision(p);
 		}
 		
-		public boolean element(GroupElement ge) {
+		public boolean element(GroupElement ge) throws HgRuntimeException {
 			try {
 				assert indexFile != null;
 				boolean writeComplete = false;
--- a/src/org/tmatesoft/hg/core/HgCommitCommand.java	Tue May 21 20:17:33 2013 +0200
+++ b/src/org/tmatesoft/hg/core/HgCommitCommand.java	Wed May 22 15:52:31 2013 +0200
@@ -30,6 +30,7 @@
 import org.tmatesoft.hg.repo.HgChangelog;
 import org.tmatesoft.hg.repo.HgDataFile;
 import org.tmatesoft.hg.repo.HgInternals;
+import org.tmatesoft.hg.repo.HgInvalidControlFileException;
 import org.tmatesoft.hg.repo.HgRepository;
 import org.tmatesoft.hg.repo.HgRuntimeException;
 import org.tmatesoft.hg.repo.HgStatusCollector.Record;
@@ -74,12 +75,17 @@
 	 * Tell if changes in the working directory constitute merge commit. May be invoked prior to (and independently from) {@link #execute()}
 	 * 
 	 * @return <code>true</code> if working directory changes are result of a merge
-	 * @throws HgException subclass thereof to indicate specific issue with the repository
+	 * @throws HgLibraryFailureException to indicate unexpected issue with the repository
+	 * @throws HgException subclass thereof to indicate other specific issue with repository state
 	 */
 	public boolean isMergeCommit() throws HgException {
-		int[] parents = new int[2];
-		detectParentFromDirstate(parents);
-		return parents[0] != NO_REVISION && parents[1] != NO_REVISION; 
+		try {
+			int[] parents = new int[2];
+			detectParentFromDirstate(parents);
+			return parents[0] != NO_REVISION && parents[1] != NO_REVISION;
+		} catch (HgRuntimeException ex) {
+			throw new HgLibraryFailureException(ex);
+		}
 	}
 
 	/**
@@ -152,7 +158,7 @@
 		return newRevision;
 	}
 
-	private String detectBranch() {
+	private String detectBranch() throws HgInvalidControlFileException {
 		return repo.getWorkingCopyBranchName();
 	}
 	
@@ -164,7 +170,7 @@
 		return new HgInternals(repo).getNextCommitUsername();
 	}
 
-	private void detectParentFromDirstate(int[] parents) {
+	private void detectParentFromDirstate(int[] parents) throws HgRuntimeException {
 		Pair<Nodeid, Nodeid> pn = repo.getWorkingCopyParents();
 		HgChangelog clog = repo.getChangelog();
 		parents[0] = pn.first().isNull() ? NO_REVISION : clog.getRevisionIndex(pn.first());
--- a/src/org/tmatesoft/hg/core/HgFileRenameHandlerMixin.java	Tue May 21 20:17:33 2013 +0200
+++ b/src/org/tmatesoft/hg/core/HgFileRenameHandlerMixin.java	Wed May 22 15:52:31 2013 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 TMate Software Ltd
+ * Copyright (c) 2012-2013 TMate Software Ltd
  *  
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -16,6 +16,7 @@
  */
 package org.tmatesoft.hg.core;
 
+import org.tmatesoft.hg.repo.HgRuntimeException;
 import org.tmatesoft.hg.util.Adaptable;
 
 /**
@@ -34,6 +35,7 @@
 
 	/**
 	 * @throws HgCallbackTargetException wrapper object for any exception user code may produce 
+	 * @throws HgRuntimeException propagates library issues. <em>Runtime exception</em>
 	 */
-	void copy(HgFileRevision from, HgFileRevision to) throws HgCallbackTargetException;
+	void copy(HgFileRevision from, HgFileRevision to) throws HgCallbackTargetException, HgRuntimeException;
 }
--- a/src/org/tmatesoft/hg/core/HgFileRevision.java	Tue May 21 20:17:33 2013 +0200
+++ b/src/org/tmatesoft/hg/core/HgFileRevision.java	Wed May 22 15:52:31 2013 +0200
@@ -107,7 +107,11 @@
 		return flags;
 	}
 
-	public boolean wasCopied() throws HgException {
+	/**
+	 * @return <code>true</code> if this file revision was created as a result of a copy/rename
+	 * @throws HgRuntimeException subclass thereof to indicate issues with the library. <em>Runtime exception</em>
+	 */
+	public boolean wasCopied() throws HgRuntimeException {
 		if (isCopy == null) {
 			checkCopy();
 		}
@@ -115,8 +119,9 @@
 	}
 	/**
 	 * @return <code>null</code> if {@link #wasCopied()} is <code>false</code>, name of the copy source otherwise.
+	 * @throws HgRuntimeException subclass thereof to indicate issues with the library. <em>Runtime exception</em>
 	 */
-	public Path getOriginIfCopy() throws HgException {
+	public Path getOriginIfCopy() throws HgRuntimeException {
 		if (wasCopied()) {
 			return origin;
 		}
@@ -145,7 +150,13 @@
 		return parents;
 	}
 
-	public void putContentTo(ByteChannel sink) throws HgException, CancelledException {
+	/**
+	 * Pipe content of this file revision into the sink
+	 * @param sink accepts file revision content
+	 * @throws HgRuntimeException subclass thereof to indicate issues with the library. <em>Runtime exception</em>
+	 * @throws CancelledException if execution of the operation was cancelled
+	 */
+	public void putContentTo(ByteChannel sink) throws HgRuntimeException, CancelledException {
 		HgDataFile fn = repo.getFileNode(path);
 		int revisionIndex = fn.getRevisionIndex(revision);
 		fn.contentWithFilters(revisionIndex, sink);
@@ -156,7 +167,7 @@
 		return String.format("HgFileRevision(%s, %s)", getPath().toString(), revision.shortNotation());
 	}
 
-	private void checkCopy() throws HgException {
+	private void checkCopy() throws HgRuntimeException {
 		HgDataFile fn = repo.getFileNode(path);
 		if (fn.isCopy()) {
 			if (fn.getRevision(0).equals(revision)) {
--- a/src/org/tmatesoft/hg/core/HgIOException.java	Tue May 21 20:17:33 2013 +0200
+++ b/src/org/tmatesoft/hg/core/HgIOException.java	Wed May 22 15:52:31 2013 +0200
@@ -40,7 +40,7 @@
 	 * @param cause root cause for the error, likely {@link IOException} or its subclass, but not necessarily, and may be omitted. 
 	 * @param troubleFile file we tried to deal with, never <code>null</code>
 	 */
-	public HgIOException(String message, Exception cause, File troubleFile) {
+	public HgIOException(String message, Throwable cause, File troubleFile) {
 		super(message, cause);
 		file = troubleFile;
 	}
--- a/src/org/tmatesoft/hg/core/HgIncomingCommand.java	Tue May 21 20:17:33 2013 +0200
+++ b/src/org/tmatesoft/hg/core/HgIncomingCommand.java	Wed May 22 15:52:31 2013 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012 TMate Software Ltd
+ * Copyright (c) 2011-2013 TMate Software Ltd
  *  
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -31,12 +31,11 @@
 import org.tmatesoft.hg.repo.HgBundle;
 import org.tmatesoft.hg.repo.HgChangelog;
 import org.tmatesoft.hg.repo.HgChangelog.RawChangeset;
-import org.tmatesoft.hg.repo.HgInvalidControlFileException;
 import org.tmatesoft.hg.repo.HgInvalidStateException;
+import org.tmatesoft.hg.repo.HgParentChildMap;
 import org.tmatesoft.hg.repo.HgRemoteRepository;
 import org.tmatesoft.hg.repo.HgRepository;
 import org.tmatesoft.hg.repo.HgRuntimeException;
-import org.tmatesoft.hg.repo.HgParentChildMap;
 import org.tmatesoft.hg.util.CancelledException;
 import org.tmatesoft.hg.util.ProgressSupport;
 
@@ -138,10 +137,10 @@
 		if (handler == null) {
 			throw new IllegalArgumentException("Delegate can't be null");
 		}
-		final List<Nodeid> common = getCommon();
-		HgBundle changegroup = remoteRepo.getChanges(common);
 		final ProgressSupport ps = getProgressSupport(handler);
 		try {
+			final List<Nodeid> common = getCommon();
+			HgBundle changegroup = remoteRepo.getChanges(common);
 			final ChangesetTransformer transformer = new ChangesetTransformer(localRepo, handler, getParentHelper(), ps, getCancelSupport(handler, true));
 			transformer.limitBranches(branches);
 			changegroup.changes(localRepo, new HgChangelog.Inspector() {
@@ -154,7 +153,7 @@
 					localIndex = localRepo.getChangelog().getRevisionCount();
 				}
 				
-				public void next(int revisionNumber, Nodeid nodeid, RawChangeset cset) {
+				public void next(int revisionNumber, Nodeid nodeid, RawChangeset cset) throws HgRuntimeException {
 					if (parentHelper.knownNode(nodeid)) {
 						if (!common.contains(nodeid)) {
 							throw new HgInvalidStateException("Bundle shall not report known nodes other than roots we've supplied");
@@ -172,7 +171,7 @@
 		}
 	}
 
-	private RepositoryComparator getComparator() throws HgInvalidControlFileException, CancelledException {
+	private RepositoryComparator getComparator() throws CancelledException, HgRuntimeException {
 		if (remoteRepo == null) {
 			throw new IllegalArgumentException("Shall specify remote repository to compare against", null);
 		}
@@ -183,7 +182,7 @@
 		return comparator;
 	}
 	
-	private HgParentChildMap<HgChangelog> getParentHelper() throws HgInvalidControlFileException {
+	private HgParentChildMap<HgChangelog> getParentHelper() throws HgRuntimeException {
 		if (parentHelper == null) {
 			parentHelper = new HgParentChildMap<HgChangelog>(localRepo.getChangelog());
 			parentHelper.init();
@@ -191,14 +190,14 @@
 		return parentHelper;
 	}
 	
-	private List<BranchChain> getMissingBranches() throws HgRemoteConnectionException, HgInvalidControlFileException, CancelledException {
+	private List<BranchChain> getMissingBranches() throws HgRemoteConnectionException, CancelledException, HgRuntimeException {
 		if (missingBranches == null) {
 			missingBranches = getComparator().calculateMissingBranches();
 		}
 		return missingBranches;
 	}
 
-	private List<Nodeid> getCommon() throws HgRemoteConnectionException, HgInvalidControlFileException, CancelledException {
+	private List<Nodeid> getCommon() throws HgRemoteConnectionException, CancelledException, HgRuntimeException {
 //		return getComparator(context).getCommon();
 		final LinkedHashSet<Nodeid> common = new LinkedHashSet<Nodeid>();
 		// XXX common can be obtained from repoCompare, but at the moment it would almost duplicate work of calculateMissingBranches
--- a/src/org/tmatesoft/hg/core/HgLogCommand.java	Tue May 21 20:17:33 2013 +0200
+++ b/src/org/tmatesoft/hg/core/HgLogCommand.java	Wed May 22 15:52:31 2013 +0200
@@ -45,7 +45,6 @@
 import org.tmatesoft.hg.repo.HgChangelog;
 import org.tmatesoft.hg.repo.HgChangelog.RawChangeset;
 import org.tmatesoft.hg.repo.HgDataFile;
-import org.tmatesoft.hg.repo.HgInvalidControlFileException;
 import org.tmatesoft.hg.repo.HgInvalidStateException;
 import org.tmatesoft.hg.repo.HgParentChildMap;
 import org.tmatesoft.hg.repo.HgRepository;
@@ -297,20 +296,20 @@
 		if (csetTransform != null) {
 			throw new ConcurrentModificationException();
 		}
-		if (repo.getChangelog().getRevisionCount() == 0) {
-			return;
-		}
-		final int lastCset = endRev == TIP ? repo.getChangelog().getLastRevision() : endRev;
-		// XXX pretty much like HgInternals.checkRevlogRange
-		if (lastCset < 0 || lastCset > repo.getChangelog().getLastRevision()) {
-			throw new HgBadArgumentException(String.format("Bad value %d for end revision", lastCset), null);
-		}
-		if (startRev < 0 || startRev > lastCset) {
-			throw new HgBadArgumentException(String.format("Bad value %d for start revision for range [%1$d..%d]", startRev, lastCset), null);
-		}
 		final ProgressSupport progressHelper = getProgressSupport(handler);
-		final int BATCH_SIZE = 100;
 		try {
+			if (repo.getChangelog().getRevisionCount() == 0) {
+				return;
+			}
+			final int lastCset = endRev == TIP ? repo.getChangelog().getLastRevision() : endRev;
+			// XXX pretty much like HgInternals.checkRevlogRange
+			if (lastCset < 0 || lastCset > repo.getChangelog().getLastRevision()) {
+				throw new HgBadArgumentException(String.format("Bad value %d for end revision", lastCset), null);
+			}
+			if (startRev < 0 || startRev > lastCset) {
+				throw new HgBadArgumentException(String.format("Bad value %d for start revision for range [%1$d..%d]", startRev, lastCset), null);
+			}
+			final int BATCH_SIZE = 100;
 			count = 0;
 			HgParentChildMap<HgChangelog> pw = getParentHelper(file == null); // leave it uninitialized unless we iterate whole repo
 			// ChangesetTransfrom creates a blank PathPool, and #file(String, boolean) above 
@@ -517,44 +516,48 @@
 		final CancelSupport cancelHelper = getCancelSupport(handler, true);
 		final HgFileRenameHandlerMixin renameHandler = Adaptable.Factory.getAdapter(handler, HgFileRenameHandlerMixin.class, null);
 
-		
-		// XXX rename. dispatcher is not a proper name (most of the job done - managing history chunk interconnection)
-		final HandlerDispatcher dispatcher = new HandlerDispatcher() {
-
-			@Override
-			protected void once(HistoryNode n) throws HgCallbackTargetException, CancelledException {
-				handler.treeElement(ei.init(n, currentFileNode));
-				cancelHelper.checkCancelled();
-			}
-		};
+		try {
 
-		// renamed files in the queue are placed with respect to #iterateDirection
-		// i.e. if we iterate from new to old, recent filenames come first
-		FileRenameQueueBuilder frqBuilder = new FileRenameQueueBuilder();
-		List<Pair<HgDataFile, Nodeid>> fileRenamesQueue = frqBuilder.buildFileRenamesQueue();
-		// XXX perhaps, makes sense to look at selected file's revision when followAncestry is true
-		// to ensure file we attempt to trace is in the WC's parent. Native hg aborts if not.
-		progressHelper.start(4 * fileRenamesQueue.size());
-		for (int namesIndex = 0, renamesQueueSize = fileRenamesQueue.size(); namesIndex < renamesQueueSize; namesIndex++) {
- 
-			final Pair<HgDataFile, Nodeid> renameInfo = fileRenamesQueue.get(namesIndex);
-			dispatcher.prepare(progressHelper, renameInfo);
-			cancelHelper.checkCancelled();
-			if (namesIndex > 0) {
-				dispatcher.connectWithLastJunctionPoint(renameInfo, fileRenamesQueue.get(namesIndex - 1));
-			}
-			if (namesIndex + 1 < renamesQueueSize) {
-				// there's at least one more name we are going to look at
-				dispatcher.updateJunctionPoint(renameInfo, fileRenamesQueue.get(namesIndex+1), renameHandler != null);
-			} else {
-				dispatcher.clearJunctionPoint();
-			}
-			dispatcher.dispatchAllChanges();
-			if (renameHandler != null && namesIndex + 1 < renamesQueueSize) {
-				dispatcher.reportRenames(renameHandler);
-			}
-		} // for fileRenamesQueue;
-		frqBuilder.reportRenameIfNotInQueue(fileRenamesQueue, renameHandler);
+			// XXX rename. dispatcher is not a proper name (most of the job done - managing history chunk interconnection)
+			final HandlerDispatcher dispatcher = new HandlerDispatcher() {
+	
+				@Override
+				protected void once(HistoryNode n) throws HgCallbackTargetException, CancelledException, HgRuntimeException {
+					handler.treeElement(ei.init(n, currentFileNode));
+					cancelHelper.checkCancelled();
+				}
+			};
+	
+			// renamed files in the queue are placed with respect to #iterateDirection
+			// i.e. if we iterate from new to old, recent filenames come first
+			FileRenameQueueBuilder frqBuilder = new FileRenameQueueBuilder();
+			List<Pair<HgDataFile, Nodeid>> fileRenamesQueue = frqBuilder.buildFileRenamesQueue();
+			// XXX perhaps, makes sense to look at selected file's revision when followAncestry is true
+			// to ensure file we attempt to trace is in the WC's parent. Native hg aborts if not.
+			progressHelper.start(4 * fileRenamesQueue.size());
+			for (int namesIndex = 0, renamesQueueSize = fileRenamesQueue.size(); namesIndex < renamesQueueSize; namesIndex++) {
+	 
+				final Pair<HgDataFile, Nodeid> renameInfo = fileRenamesQueue.get(namesIndex);
+				dispatcher.prepare(progressHelper, renameInfo);
+				cancelHelper.checkCancelled();
+				if (namesIndex > 0) {
+					dispatcher.connectWithLastJunctionPoint(renameInfo, fileRenamesQueue.get(namesIndex - 1));
+				}
+				if (namesIndex + 1 < renamesQueueSize) {
+					// there's at least one more name we are going to look at
+					dispatcher.updateJunctionPoint(renameInfo, fileRenamesQueue.get(namesIndex+1), renameHandler != null);
+				} else {
+					dispatcher.clearJunctionPoint();
+				}
+				dispatcher.dispatchAllChanges();
+				if (renameHandler != null && namesIndex + 1 < renamesQueueSize) {
+					dispatcher.reportRenames(renameHandler);
+				}
+			} // for fileRenamesQueue;
+			frqBuilder.reportRenameIfNotInQueue(fileRenamesQueue, renameHandler);
+		} catch (HgRuntimeException ex) {
+			throw new HgLibraryFailureException(ex);
+		}
 		progressHelper.done();
 	}
 	
@@ -578,8 +581,9 @@
 		 * and possibly reuse this functionality
 		 * 
 		 * @return list of file renames, ordered with respect to {@link #iterateDirection}
+		 * @throws HgRuntimeException 
 		 */
-		public List<Pair<HgDataFile, Nodeid>> buildFileRenamesQueue() throws HgPathNotFoundException {
+		public List<Pair<HgDataFile, Nodeid>> buildFileRenamesQueue() throws HgPathNotFoundException, HgRuntimeException {
 			LinkedList<Pair<HgDataFile, Nodeid>> rv = new LinkedList<Pair<HgDataFile, Nodeid>>();
 			Nodeid startRev = null;
 			HgDataFile fileNode = repo.getFileNode(file);
@@ -613,11 +617,11 @@
 			return rv;
 		}
 		
-		public boolean hasOrigin(Pair<HgDataFile, Nodeid> p) {
+		public boolean hasOrigin(Pair<HgDataFile, Nodeid> p) throws HgRuntimeException {
 			return p.first().isCopy();
 		}
 
-		public Pair<HgDataFile, Nodeid> origin(Pair<HgDataFile, Nodeid> p) {
+		public Pair<HgDataFile, Nodeid> origin(Pair<HgDataFile, Nodeid> p) throws HgRuntimeException {
 			HgDataFile fileNode = p.first();
 			assert fileNode.isCopy();
 			Path fp = fileNode.getCopySourceName();
@@ -633,7 +637,7 @@
 		 * @param queue value from {@link #buildFileRenamesQueue()}
 		 * @param renameHandler may be <code>null</code>
 		 */
-		public void reportRenameIfNotInQueue(List<Pair<HgDataFile, Nodeid>> queue, HgFileRenameHandlerMixin renameHandler) throws HgCallbackTargetException {
+		public void reportRenameIfNotInQueue(List<Pair<HgDataFile, Nodeid>> queue, HgFileRenameHandlerMixin renameHandler) throws HgCallbackTargetException, HgRuntimeException {
 			if (renameHandler != null && !followRenames) {
 				// If followRenames is true, all the historical names were in the queue and are processed already.
 				// Hence, shall process origin explicitly only when renameHandler is present but followRenames is not requested.
@@ -677,12 +681,12 @@
 			completeHistory[revisionNumber] = new HistoryNode(commitRevisions[revisionNumber], revision, p1, p2);
 		}
 		
-		HistoryNode one(HgDataFile fileNode, Nodeid fileRevision) throws HgInvalidControlFileException {
+		HistoryNode one(HgDataFile fileNode, Nodeid fileRevision) throws HgRuntimeException {
 			int fileRevIndexToVisit = fileNode.getRevisionIndex(fileRevision);
 			return one(fileNode, fileRevIndexToVisit);
 		}
 
-		HistoryNode one(HgDataFile fileNode, int fileRevIndexToVisit) throws HgInvalidControlFileException {
+		HistoryNode one(HgDataFile fileNode, int fileRevIndexToVisit) throws HgRuntimeException {
 			resultHistory = null;
 			if (fileRevIndexToVisit == HgRepository.TIP) {
 				fileRevIndexToVisit = fileNode.getLastRevision();
@@ -708,7 +712,7 @@
 		 * @return list of history elements, from oldest to newest. In case {@link #followAncestry} is <code>true</code>, the list
 		 * is modifiable (to further augment with last/first elements of renamed file histories)
 		 */
-		List<HistoryNode> go(HgDataFile fileNode, Nodeid fileLastRevisionToVisit) throws HgInvalidControlFileException {
+		List<HistoryNode> go(HgDataFile fileNode, Nodeid fileLastRevisionToVisit) throws HgRuntimeException {
 			resultHistory = null;
 			int fileLastRevIndexToVisit = fileLastRevisionToVisit == null ? fileNode.getLastRevision() : fileNode.getRevisionIndex(fileLastRevisionToVisit);
 			completeHistory = new HistoryNode[fileLastRevIndexToVisit+1];
@@ -805,7 +809,7 @@
 		private HgFileRevision copiedFrom, copiedTo; 
 
 		// parentProgress shall be initialized with 4 XXX refactor all this stuff with parentProgress 
-		public void prepare(ProgressSupport parentProgress, Pair<HgDataFile, Nodeid> renameInfo) {
+		public void prepare(ProgressSupport parentProgress, Pair<HgDataFile, Nodeid> renameInfo) throws HgRuntimeException {
 			// if we don't followAncestry, take complete history
 			// XXX treeBuildInspector knows followAncestry, perhaps the logic 
 			// whether to take specific revision or the last one shall be there?
@@ -834,7 +838,7 @@
 			switchTo(renameInfo.first());
 		}
 		
-		public void updateJunctionPoint(Pair<HgDataFile, Nodeid> curRename, Pair<HgDataFile, Nodeid> nextRename, boolean needCopyFromTo) {
+		public void updateJunctionPoint(Pair<HgDataFile, Nodeid> curRename, Pair<HgDataFile, Nodeid> nextRename, boolean needCopyFromTo) throws HgRuntimeException {
 			copiedFrom = copiedTo = null;
 			//
 			// A (old) renamed to B(new).  A(0..k..n) -> B(0..m). If followAncestry, k == n
@@ -876,7 +880,7 @@
 			}
 		}
 		
-		public void reportRenames(HgFileRenameHandlerMixin renameHandler) throws HgCallbackTargetException {
+		public void reportRenames(HgFileRenameHandlerMixin renameHandler) throws HgCallbackTargetException, HgRuntimeException {
 			if (renameHandler != null) { // shall report renames
 				assert copiedFrom != null;
 				assert copiedTo != null;
@@ -931,9 +935,9 @@
 			throw new HgInvalidStateException(String.format("For change history (cset[%d..%d]) could not find node for file change %s", csetStart, csetEnd, fileRevision.shortNotation()));
 		}
 
-		protected abstract void once(HistoryNode n) throws HgCallbackTargetException, CancelledException;
+		protected abstract void once(HistoryNode n) throws HgCallbackTargetException, CancelledException, HgRuntimeException;
 		
-		public void dispatchAllChanges() throws HgCallbackTargetException, CancelledException {
+		public void dispatchAllChanges() throws HgCallbackTargetException, CancelledException, HgRuntimeException {
 			// XXX shall sort changeHistory according to changeset numbers?
 			Iterator<HistoryNode> it;
 			if (iterateDirection == HgIterateDirection.OldToNew) {
@@ -983,7 +987,7 @@
 			}
 		}
 
-		public void next(int revisionNumber, Nodeid nodeid, RawChangeset cset) {
+		public void next(int revisionNumber, Nodeid nodeid, RawChangeset cset) throws HgRuntimeException {
 			if (limit > 0 && count >= limit) {
 				return;
 			}
@@ -1022,7 +1026,7 @@
 		}
 	}
 
-	private HgParentChildMap<HgChangelog> getParentHelper(boolean create) throws HgInvalidControlFileException {
+	private HgParentChildMap<HgChangelog> getParentHelper(boolean create) throws HgRuntimeException {
 		if (parentHelper == null && create) {
 			parentHelper = new HgParentChildMap<HgChangelog>(repo.getChangelog());
 			parentHelper.init();
@@ -1120,11 +1124,11 @@
 			return fileNode;
 		}
 
-		public HgChangeset changeset() {
+		public HgChangeset changeset() throws HgRuntimeException {
 			return get(historyNode.changeset)[0];
 		}
 
-		public Pair<HgChangeset, HgChangeset> parents() {
+		public Pair<HgChangeset, HgChangeset> parents() throws HgRuntimeException {
 			if (parents != null) {
 				return parents;
 			}
@@ -1144,7 +1148,7 @@
 			return parents = new Pair<HgChangeset, HgChangeset>(r[0], r[1]);
 		}
 
-		public Collection<HgChangeset> children() {
+		public Collection<HgChangeset> children() throws HgRuntimeException {
 			if (children != null) {
 				return children;
 			}
@@ -1165,7 +1169,7 @@
 			cachedChangesets.put(cs.getRevisionIndex(), cs);
 		}
 		
-		private HgChangeset[] get(int... changelogRevisionIndex) {
+		private HgChangeset[] get(int... changelogRevisionIndex) throws HgRuntimeException {
 			HgChangeset[] rv = new HgChangeset[changelogRevisionIndex.length];
 			IntVector misses = new IntVector(changelogRevisionIndex.length, -1);
 			for (int i = 0; i < changelogRevisionIndex.length; i++) {
@@ -1187,8 +1191,7 @@
 				for (int changeset2read : changesets2read) {
 					HgChangeset cs = cachedChangesets.get(changeset2read);
 					if (cs == null) {
-						HgInvalidStateException t = new HgInvalidStateException(String.format("Can't get changeset for revision %d", changeset2read));
-						throw t.setRevisionIndex(changeset2read);
+						throw new HgInvalidStateException(String.format("Can't get changeset for revision %d", changeset2read));
 					}
 					// HgChangelog.range may reorder changesets according to their order in the changelog
 					// thus need to find original index
@@ -1221,14 +1224,14 @@
 			populate(cs.clone());
 		}
 
-		public Nodeid changesetRevision() {
+		public Nodeid changesetRevision() throws HgRuntimeException {
 			if (changesetRevision == null) {
 				changesetRevision = getRevision(historyNode.changeset);
 			}
 			return changesetRevision;
 		}
 
-		public Pair<Nodeid, Nodeid> parentRevisions() {
+		public Pair<Nodeid, Nodeid> parentRevisions() throws HgRuntimeException {
 			if (parentRevisions == null) {
 				HistoryNode p;
 				final Nodeid p1, p2;
@@ -1247,7 +1250,7 @@
 			return parentRevisions;
 		}
 
-		public Collection<Nodeid> childRevisions() {
+		public Collection<Nodeid> childRevisions() throws HgRuntimeException {
 			if (childRevisions != null) {
 				return childRevisions;
 			}
@@ -1264,7 +1267,7 @@
 		}
 		
 		// reading nodeid involves reading index only, guess, can afford not to optimize multiple reads
-		private Nodeid getRevision(int changelogRevisionNumber) {
+		private Nodeid getRevision(int changelogRevisionNumber) throws HgRuntimeException {
 			// TODO post-1.0 pipe through pool
 			HgChangeset cs = cachedChangesets.get(changelogRevisionNumber);
 			if (cs != null) {
--- a/src/org/tmatesoft/hg/core/HgManifestCommand.java	Tue May 21 20:17:33 2013 +0200
+++ b/src/org/tmatesoft/hg/core/HgManifestCommand.java	Wed May 22 15:52:31 2013 +0200
@@ -190,7 +190,7 @@
 			}
 		}
 	
-		public boolean begin(int manifestRevision, Nodeid nid, int changelogRevision) {
+		public boolean begin(int manifestRevision, Nodeid nid, int changelogRevision) throws HgRuntimeException {
 			if (needDirs && manifestContent == null) {
 				manifestContent = new LinkedList<HgFileRevision>();
 			}
@@ -206,7 +206,7 @@
 				return false;
 			}
 		}
-		public boolean end(int revision) {
+		public boolean end(int revision) throws HgRuntimeException {
 			try {
 				if (needDirs) {
 					LinkedHashMap<Path, LinkedList<HgFileRevision>> breakDown = new LinkedHashMap<Path, LinkedList<HgFileRevision>>();
@@ -243,7 +243,7 @@
 			}
 		}
 		
-		public boolean next(Nodeid nid, Path fname, Flags flags) {
+		public boolean next(Nodeid nid, Path fname, Flags flags) throws HgRuntimeException {
 			if (matcher != null && !matcher.accept(fname)) {
 				return true;
 			}
--- a/src/org/tmatesoft/hg/core/HgManifestHandler.java	Tue May 21 20:17:33 2013 +0200
+++ b/src/org/tmatesoft/hg/core/HgManifestHandler.java	Wed May 22 15:52:31 2013 +0200
@@ -17,6 +17,7 @@
 package org.tmatesoft.hg.core;
 
 import org.tmatesoft.hg.internal.Callback;
+import org.tmatesoft.hg.repo.HgRuntimeException;
 import org.tmatesoft.hg.util.Path;
 
 /**
@@ -33,8 +34,9 @@
 	 * 
 	 * @param manifestRevision unique identifier of the manifest revision
 	 * @throws HgCallbackTargetException wrapper for any exception user code may produce
+	 * @throws HgRuntimeException propagates library issues. <em>Runtime exception</em>
 	 */
-	void begin(Nodeid manifestRevision) throws HgCallbackTargetException;
+	void begin(Nodeid manifestRevision) throws HgCallbackTargetException, HgRuntimeException;
 
 	/**
 	 * If walker is configured to spit out directories, indicates files from specified directories are about to be reported.
@@ -42,16 +44,18 @@
 	 * 
 	 * @param path directory known in the manifest
 	 * @throws HgCallbackTargetException wrapper for any exception user code may produce
+	 * @throws HgRuntimeException propagates library issues. <em>Runtime exception</em>
 	 */
-	void dir(Path path) throws HgCallbackTargetException; 
+	void dir(Path path) throws HgCallbackTargetException, HgRuntimeException; 
 
 	/**
 	 * Reports a file revision entry in the manifest
 	 * 
 	 * @param fileRevision description of the file revision
 	 * @throws HgCallbackTargetException wrapper for any exception user code may produce
+	 * @throws HgRuntimeException propagates library issues. <em>Runtime exception</em>
 	 */
-	void file(HgFileRevision fileRevision) throws HgCallbackTargetException;
+	void file(HgFileRevision fileRevision) throws HgCallbackTargetException, HgRuntimeException;
 
 	/**
 	 * Indicates all files from the manifest revision have been reported.
@@ -59,6 +63,7 @@
 	 * 
 	 * @param manifestRevision unique identifier of the manifest revision 
 	 * @throws HgCallbackTargetException wrapper for any exception user code may produce
+	 * @throws HgRuntimeException propagates library issues. <em>Runtime exception</em>
 	 */
-	void end(Nodeid manifestRevision) throws HgCallbackTargetException;
+	void end(Nodeid manifestRevision) throws HgCallbackTargetException, HgRuntimeException;
 }
\ No newline at end of file
--- a/src/org/tmatesoft/hg/core/HgOutgoingCommand.java	Tue May 21 20:17:33 2013 +0200
+++ b/src/org/tmatesoft/hg/core/HgOutgoingCommand.java	Wed May 22 15:52:31 2013 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012 TMate Software Ltd
+ * Copyright (c) 2011-2013 TMate Software Ltd
  *  
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -23,11 +23,10 @@
 import org.tmatesoft.hg.internal.Internals;
 import org.tmatesoft.hg.internal.RepositoryComparator;
 import org.tmatesoft.hg.repo.HgChangelog;
-import org.tmatesoft.hg.repo.HgInvalidControlFileException;
+import org.tmatesoft.hg.repo.HgParentChildMap;
 import org.tmatesoft.hg.repo.HgRemoteRepository;
 import org.tmatesoft.hg.repo.HgRepository;
 import org.tmatesoft.hg.repo.HgRuntimeException;
-import org.tmatesoft.hg.repo.HgParentChildMap;
 import org.tmatesoft.hg.util.CancelSupport;
 import org.tmatesoft.hg.util.CancelledException;
 import org.tmatesoft.hg.util.ProgressSupport;
@@ -141,7 +140,7 @@
 		}
 	}
 
-	private RepositoryComparator getComparator(ProgressSupport ps, CancelSupport cs) throws HgRemoteConnectionException, HgInvalidControlFileException, CancelledException {
+	private RepositoryComparator getComparator(ProgressSupport ps, CancelSupport cs) throws HgRemoteConnectionException, CancelledException, HgRuntimeException {
 		if (remoteRepo == null) {
 			throw new IllegalArgumentException("Shall specify remote repository to compare against");
 		}
@@ -152,7 +151,7 @@
 		return comparator;
 	}
 	
-	private HgParentChildMap<HgChangelog> getParentHelper() throws HgInvalidControlFileException {
+	private HgParentChildMap<HgChangelog> getParentHelper() throws HgRuntimeException {
 		if (parentHelper == null) {
 			parentHelper = new HgParentChildMap<HgChangelog>(localRepo.getChangelog());
 			parentHelper.init();
--- a/src/org/tmatesoft/hg/core/HgStatus.java	Tue May 21 20:17:33 2013 +0200
+++ b/src/org/tmatesoft/hg/core/HgStatus.java	Wed May 22 15:52:31 2013 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012 TMate Software Ltd
+ * Copyright (c) 2011-2013 TMate Software Ltd
  *  
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -21,6 +21,7 @@
 
 import org.tmatesoft.hg.internal.ChangelogHelper;
 import org.tmatesoft.hg.repo.HgChangelog.RawChangeset;
+import org.tmatesoft.hg.repo.HgRuntimeException;
 import org.tmatesoft.hg.util.Path;
 
 /**
@@ -70,8 +71,9 @@
 
 	/**
 	 * @return <code>null</code> if author for the change can't be deduced (e.g. for clean files it's senseless)
+	 * @throws HgRuntimeException subclass thereof to indicate issues with the library. <em>Runtime exception</em>
 	 */
-	public String getModificationAuthor() {
+	public String getModificationAuthor() throws HgRuntimeException {
 		RawChangeset cset = logHelper.findLatestChangeWith(path);
 		if (cset == null) {
 			if (kind == Kind.Modified || kind == Kind.Added || kind == Kind.Removed /*&& RightBoundary is TIP*/) {
@@ -84,15 +86,20 @@
 		return null;
 	}
 
-	public Date getModificationDate() {
+	/**
+	 * @return date when the file was last modified, never <code>null</code>. Either date of changeset the file was modified at
+	 * or timestamp of local file, if present
+	 * @throws HgRuntimeException subclass thereof to indicate issues with the library. <em>Runtime exception</em>
+	 */
+	public Date getModificationDate() throws HgRuntimeException {
 		RawChangeset cset = logHelper.findLatestChangeWith(path);
 		if (cset == null) {
 			File localFile = new File(logHelper.getRepo().getWorkingDir(), path.toString());
 			if (localFile.canRead()) {
 				return new Date(localFile.lastModified());
 			}
-			// TODO post-1.0 find out what to do in this case, perhaps, throw an exception?
-			// perhaps check dirstate and/or local file for tstamp
+			// TODO post-1.1 find out what to do in this case, perhaps, throw an exception?
+			// perhaps check dirstate and for timestamp
 			return new Date(); // what's correct? 
 		} else {
 			return cset.date();
--- a/src/org/tmatesoft/hg/internal/BlameHelper.java	Tue May 21 20:17:33 2013 +0200
+++ b/src/org/tmatesoft/hg/internal/BlameHelper.java	Wed May 22 15:52:31 2013 +0200
@@ -34,6 +34,7 @@
 import org.tmatesoft.hg.repo.HgBlameInspector;
 import org.tmatesoft.hg.repo.HgDataFile;
 import org.tmatesoft.hg.repo.HgInvalidStateException;
+import org.tmatesoft.hg.repo.HgRuntimeException;
 import org.tmatesoft.hg.util.Adaptable;
 import org.tmatesoft.hg.util.CancelledException;
 import org.tmatesoft.hg.util.Pair;
@@ -62,7 +63,7 @@
 	 * <p>NOTE, clogRevIndexEnd has to list name of the supplied file in the corresponding manifest,
 	 * as it's not possible to trace rename history otherwise.
 	 */
-	public FileHistory prepare(HgDataFile df, int clogRevIndexStart, int clogRevIndexEnd) {
+	public FileHistory prepare(HgDataFile df, int clogRevIndexStart, int clogRevIndexEnd) throws HgRuntimeException {
 		assert clogRevIndexStart <= clogRevIndexEnd;
 		FileHistory fileHistory = new FileHistory(df, clogRevIndexStart, clogRevIndexEnd);
 		fileHistory.build();
@@ -84,7 +85,7 @@
 	}
 	
 	// NO_REVISION is not allowed as any argument
-	public void diff(int fileRevIndex1, int clogRevIndex1, int fileRevIndex2, int clogRevIndex2) throws HgCallbackTargetException {
+	public void diff(int fileRevIndex1, int clogRevIndex1, int fileRevIndex2, int clogRevIndex2) throws HgCallbackTargetException, HgRuntimeException {
 		HgDataFile targetFile = linesCache.getFile(clogRevIndex2);
 		LineSequence c1 = linesCache.lines(clogRevIndex1, fileRevIndex1);
 		LineSequence c2 = linesCache.lines(clogRevIndex2, fileRevIndex2);
@@ -95,7 +96,7 @@
 		bbi.checkErrors();
 	}
 
-	public void annotateChange(int fileRevIndex, int csetRevIndex, int[] fileParentRevs, int[] fileParentClogRevs) throws HgCallbackTargetException {
+	public void annotateChange(int fileRevIndex, int csetRevIndex, int[] fileParentRevs, int[] fileParentClogRevs) throws HgCallbackTargetException, HgRuntimeException {
 		HgDataFile targetFile = linesCache.getFile(csetRevIndex);
 		final LineSequence fileRevLines = linesCache.lines(csetRevIndex, fileRevIndex);
 		if (fileParentClogRevs[0] != NO_REVISION && fileParentClogRevs[1] != NO_REVISION) {
@@ -176,7 +177,7 @@
 			throw new HgInvalidStateException(String.format("Got %d file-changelog mappings, but no luck for revision %d.", files.size(), clogRevIndex));
 		}
 
-		public LineSequence lines(int clogRevIndex, int fileRevIndex) {
+		public LineSequence lines(int clogRevIndex, int fileRevIndex) throws HgRuntimeException {
 			Pair<Integer, LineSequence> cached = checkCache(clogRevIndex);
 			if (cached != null) {
 				return cached.second();
--- a/src/org/tmatesoft/hg/internal/ChangelogHelper.java	Tue May 21 20:17:33 2013 +0200
+++ b/src/org/tmatesoft/hg/internal/ChangelogHelper.java	Wed May 22 15:52:31 2013 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011 TMate Software Ltd
+ * Copyright (c) 2011-2013 TMate Software Ltd
  *  
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -19,8 +19,8 @@
 import org.tmatesoft.hg.repo.HgChangelog.RawChangeset;
 import org.tmatesoft.hg.repo.HgDataFile;
 import org.tmatesoft.hg.repo.HgInternals;
-import org.tmatesoft.hg.repo.HgInvalidControlFileException;
 import org.tmatesoft.hg.repo.HgRepository;
+import org.tmatesoft.hg.repo.HgRuntimeException;
 import org.tmatesoft.hg.util.Path;
 
 /**
@@ -56,7 +56,7 @@
 	 * @param file
 	 * @return changeset where specified file is mentioned among affected files, or <code>null</code> if none found up to leftBoundary
 	 */
-	public RawChangeset findLatestChangeWith(Path file) throws HgInvalidControlFileException {
+	public RawChangeset findLatestChangeWith(Path file) throws HgRuntimeException {
 		HgDataFile df = repo.getFileNode(file);
 		if (!df.exists()) {
 			return null;
--- a/src/org/tmatesoft/hg/internal/ChangelogMonitor.java	Tue May 21 20:17:33 2013 +0200
+++ b/src/org/tmatesoft/hg/internal/ChangelogMonitor.java	Wed May 22 15:52:31 2013 +0200
@@ -19,6 +19,7 @@
 import org.tmatesoft.hg.core.Nodeid;
 import org.tmatesoft.hg.core.SessionContext;
 import org.tmatesoft.hg.repo.HgRepository;
+import org.tmatesoft.hg.repo.HgRuntimeException;
 
 /**
  * Track changes to a repository based on recent changelog revision.
@@ -38,13 +39,13 @@
 	}
 	
 	// memorize the state of the repository's changelog
-	public void touch() {
+	public void touch() throws HgRuntimeException {
 		changelogRevCount = repo.getChangelog().getRevisionCount();
 		changelogLastRev = safeGetRevision(changelogRevCount-1);
 	}
 	
 	// if present state doesn't match the one we remember
-	public boolean isChanged() {
+	public boolean isChanged() throws HgRuntimeException {
 		int rc = repo.getChangelog().getRevisionCount();
 		if (rc != changelogRevCount) {
 			return true;
@@ -54,7 +55,7 @@
 	}
 	
 	// handles empty repository case
-	private Nodeid safeGetRevision(int revIndex) {
+	private Nodeid safeGetRevision(int revIndex) throws HgRuntimeException {
 		if (revIndex >= 0) {
 			return repo.getChangelog().getRevision(revIndex);
 		}
--- a/src/org/tmatesoft/hg/internal/CommitFacility.java	Tue May 21 20:17:33 2013 +0200
+++ b/src/org/tmatesoft/hg/internal/CommitFacility.java	Wed May 22 15:52:31 2013 +0200
@@ -40,6 +40,7 @@
 import org.tmatesoft.hg.internal.DataSerializer.DataSource;
 import org.tmatesoft.hg.repo.HgChangelog;
 import org.tmatesoft.hg.repo.HgDataFile;
+import org.tmatesoft.hg.repo.HgRuntimeException;
 import org.tmatesoft.hg.util.Pair;
 import org.tmatesoft.hg.util.Path;
 
@@ -97,7 +98,7 @@
 	
 	// this method doesn't roll transaction back in case of failure, caller's responsibility
 	// this method expects repository to be locked, if needed
-	public Nodeid commit(String message, Transaction transaction) throws HgIOException, HgRepositoryLockException {
+	public Nodeid commit(String message, Transaction transaction) throws HgIOException, HgRepositoryLockException, HgRuntimeException {
 		final HgChangelog clog = repo.getRepo().getChangelog();
 		final int clogRevisionIndex = clog.getRevisionCount();
 		ManifestRevision c1Manifest = new ManifestRevision(null, null);
--- a/src/org/tmatesoft/hg/internal/ConfigFile.java	Tue May 21 20:17:33 2013 +0200
+++ b/src/org/tmatesoft/hg/internal/ConfigFile.java	Wed May 22 15:52:31 2013 +0200
@@ -31,8 +31,8 @@
 import java.util.List;
 import java.util.Map;
 
+import org.tmatesoft.hg.core.HgIOException;
 import org.tmatesoft.hg.core.SessionContext;
-import org.tmatesoft.hg.repo.HgInvalidFileException;
 import org.tmatesoft.hg.util.LogFacility;
 
 /**
@@ -50,7 +50,7 @@
 		sessionContext = ctx;
 	}
 
-	public void addLocation(File path) throws HgInvalidFileException {
+	public void addLocation(File path) throws HgIOException {
 		read(path);
 	}
 	
@@ -125,7 +125,7 @@
 		}
 	}
 	
-	private void read(File f) throws HgInvalidFileException {
+	private void read(File f) throws HgIOException {
 		if (f == null || !f.canRead()) {
 			return;
 		}
@@ -227,7 +227,7 @@
 			return true;
 		}
 		
-		public void go(File f, ConfigFile cfg) throws HgInvalidFileException {
+		public void go(File f, ConfigFile cfg) throws HgIOException {
 			contextFile = f;
 			LineReader lr = new LineReader(f, cfg.sessionContext.getLog());
 			lr.ignoreLineComments("#");
@@ -250,7 +250,7 @@
 					LogFacility lf = cfg.sessionContext.getLog();
 					lf.dump(ConfigFile.class, LogFacility.Severity.Debug, "Can't read file to  include: %s", f);
 				}
-			} catch (HgInvalidFileException ex) {
+			} catch (HgIOException ex) {
 				LogFacility lf = cfg.sessionContext.getLog();
 				lf.dump(ConfigFile.class, LogFacility.Severity.Warn, "Can't include %s (%s)", f, includeValue);
 			}
--- a/src/org/tmatesoft/hg/internal/CsetParamKeeper.java	Tue May 21 20:17:33 2013 +0200
+++ b/src/org/tmatesoft/hg/internal/CsetParamKeeper.java	Wed May 22 15:52:31 2013 +0200
@@ -23,6 +23,7 @@
 import org.tmatesoft.hg.core.Nodeid;
 import org.tmatesoft.hg.repo.HgInvalidRevisionException;
 import org.tmatesoft.hg.repo.HgRepository;
+import org.tmatesoft.hg.repo.HgRuntimeException;
 
 /**
  * Common code to keep changelog revision and to perform boundary check.
@@ -43,19 +44,25 @@
 			set(repo.getChangelog().getRevisionIndex(changeset));
 		} catch (HgInvalidRevisionException ex) {
 			throw new HgBadArgumentException("Can't find revision", ex).setRevision(changeset);
+		} catch (HgRuntimeException ex) {
+			throw new HgBadArgumentException(String.format("Can't initialize with revision %s", changeset.shortNotation()), ex);
 		}
 		return this;
 	}
 	
 	public CsetParamKeeper set(int changelogRevIndex) throws HgBadArgumentException {
-		int lastCsetIndex = repo.getChangelog().getLastRevision();
-		if (changelogRevIndex == HgRepository.TIP) {
-			changelogRevIndex = lastCsetIndex;
+		try {
+			int lastCsetIndex = repo.getChangelog().getLastRevision();
+			if (changelogRevIndex == HgRepository.TIP) {
+				changelogRevIndex = lastCsetIndex;
+			}
+			if (changelogRevIndex < 0 || changelogRevIndex > lastCsetIndex) {
+				throw new HgBadArgumentException(String.format("Bad revision index %d, value from [0..%d] expected", changelogRevIndex, lastCsetIndex), null).setRevisionIndex(changelogRevIndex);
+			}
+			doSet(changelogRevIndex);
+		} catch (HgRuntimeException ex) {
+			throw new HgBadArgumentException(String.format("Can't initialize with revision index %d", changelogRevIndex), ex);
 		}
-		if (changelogRevIndex < 0 || changelogRevIndex > lastCsetIndex) {
-			throw new HgBadArgumentException(String.format("Bad revision index %d, value from [0..%d] expected", changelogRevIndex, lastCsetIndex), null).setRevisionIndex(changelogRevIndex);
-		}
-		doSet(changelogRevIndex);
 		return this;
 	}
 	
@@ -74,7 +81,7 @@
 	 * @param defaultRevisionIndex value to return when no revision was set, may be {@link HgRepository#TIP} which gets translated to real index if used
 	 * @return changelog revision index if set, or defaultRevisionIndex value otherwise
 	 */
-	public int get(int defaultRevisionIndex) {
+	public int get(int defaultRevisionIndex) throws HgRuntimeException {
 		// XXX perhaps, shall translate other predefined constants (like WORKING COPY) here, too (e.g. for HgRevertCommand)
 		if (changelogRevisionIndex != BAD_REVISION || changelogRevisionIndex != TIP) {
 			return changelogRevisionIndex;
--- a/src/org/tmatesoft/hg/internal/DataSerializer.java	Tue May 21 20:17:33 2013 +0200
+++ b/src/org/tmatesoft/hg/internal/DataSerializer.java	Wed May 22 15:52:31 2013 +0200
@@ -19,6 +19,7 @@
 import java.io.ByteArrayOutputStream;
 
 import org.tmatesoft.hg.core.HgIOException;
+import org.tmatesoft.hg.repo.HgRuntimeException;
 
 /**
  * Serialization friend of {@link DataAccess}
@@ -78,13 +79,13 @@
 		 * Invoked once for a single write operation, 
 		 * although the source itself may get serialized several times
 		 */
-		public void serialize(DataSerializer out) throws HgIOException;
+		public void serialize(DataSerializer out) throws HgIOException, HgRuntimeException;
 
 		/**
 		 * Hint of data length it would like to writes
 		 * @return -1 if can't answer
 		 */
-		public int serializeLength();
+		public int serializeLength() throws HgRuntimeException;
 	}
 	
 	public static class ByteArrayDataSource implements DataSource {
--- a/src/org/tmatesoft/hg/internal/DirstateBuilder.java	Tue May 21 20:17:33 2013 +0200
+++ b/src/org/tmatesoft/hg/internal/DirstateBuilder.java	Wed May 22 15:52:31 2013 +0200
@@ -33,6 +33,7 @@
 import org.tmatesoft.hg.repo.HgDirstate;
 import org.tmatesoft.hg.repo.HgDirstate.EntryKind;
 import org.tmatesoft.hg.repo.HgDirstate.Record;
+import org.tmatesoft.hg.repo.HgInvalidControlFileException;
 import org.tmatesoft.hg.repo.HgInvalidStateException;
 import org.tmatesoft.hg.repo.HgManifest.Flags;
 import org.tmatesoft.hg.util.Path;
@@ -164,7 +165,7 @@
 		}
 	}
 	
-	public void fillFrom(DirstateReader dirstate) {
+	public void fillFrom(DirstateReader dirstate) throws HgInvalidControlFileException {
 		// TODO preserve order, if reasonable and possible 
 		dirstate.readInto(new HgDirstate.Inspector() {
 			
--- a/src/org/tmatesoft/hg/internal/FileAnnotation.java	Tue May 21 20:17:33 2013 +0200
+++ b/src/org/tmatesoft/hg/internal/FileAnnotation.java	Wed May 22 15:52:31 2013 +0200
@@ -23,6 +23,7 @@
 import org.tmatesoft.hg.repo.HgBlameInspector.RevisionDescriptor;
 import org.tmatesoft.hg.repo.HgDataFile;
 import org.tmatesoft.hg.repo.HgInvalidStateException;
+import org.tmatesoft.hg.repo.HgRuntimeException;
 
 /**
  * Produce output like 'hg annotate' does
@@ -48,7 +49,7 @@
 	/**
 	 * Annotate file revision, line by line.
 	 */
-	public static void annotate(HgDataFile df, int changelogRevisionIndex, LineInspector insp) throws HgCallbackTargetException {
+	public static void annotate(HgDataFile df, int changelogRevisionIndex, LineInspector insp) throws HgCallbackTargetException, HgRuntimeException {
 		if (!df.exists()) {
 			return;
 		}
--- a/src/org/tmatesoft/hg/internal/FileHistory.java	Tue May 21 20:17:33 2013 +0200
+++ b/src/org/tmatesoft/hg/internal/FileHistory.java	Wed May 22 15:52:31 2013 +0200
@@ -25,6 +25,7 @@
 import org.tmatesoft.hg.core.Nodeid;
 import org.tmatesoft.hg.repo.HgDataFile;
 import org.tmatesoft.hg.repo.HgRepository;
+import org.tmatesoft.hg.repo.HgRuntimeException;
 
 /**
  * History of a file, with copy/renames, and corresponding revision information.
@@ -56,7 +57,7 @@
 		return csetTo;
 	}
 
-	public void build() {
+	public void build() throws HgRuntimeException {
 		assert fileCompleteHistory.isEmpty();
 		HgDataFile currentFile = df;
 		final int changelogRevIndexEnd = csetTo;
--- a/src/org/tmatesoft/hg/internal/FileRevisionHistoryChunk.java	Tue May 21 20:17:33 2013 +0200
+++ b/src/org/tmatesoft/hg/internal/FileRevisionHistoryChunk.java	Wed May 22 15:52:31 2013 +0200
@@ -28,6 +28,7 @@
 import org.tmatesoft.hg.core.Nodeid;
 import org.tmatesoft.hg.repo.HgDataFile;
 import org.tmatesoft.hg.repo.HgRepository;
+import org.tmatesoft.hg.repo.HgRuntimeException;
 
 /**
  * Piece of file history, identified by path, limited to file revisions from range [chop..init] of changesets, 
@@ -73,7 +74,7 @@
 		return csetRangeEnd;
 	}
 	
-	public void init(int changelogRevisionIndex) {
+	public void init(int changelogRevisionIndex) throws HgRuntimeException {
 		csetRangeEnd = changelogRevisionIndex;
 		// XXX df.indexWalk(0, fileRevIndex, ) might be more effective
 		Nodeid fileRev = df.getRepo().getManifest().getFileRevision(changelogRevisionIndex, df.getPath());
--- a/src/org/tmatesoft/hg/internal/Internals.java	Tue May 21 20:17:33 2013 +0200
+++ b/src/org/tmatesoft/hg/internal/Internals.java	Wed May 22 15:52:31 2013 +0200
@@ -19,7 +19,6 @@
 import static org.tmatesoft.hg.util.LogFacility.Severity.Error;
 
 import java.io.File;
-import java.io.IOException;
 import java.nio.charset.Charset;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -29,6 +28,7 @@
 import java.util.List;
 import java.util.StringTokenizer;
 
+import org.tmatesoft.hg.core.HgIOException;
 import org.tmatesoft.hg.core.SessionContext;
 import org.tmatesoft.hg.repo.HgDataFile;
 import org.tmatesoft.hg.repo.HgInternals;
@@ -337,10 +337,9 @@
 	
 	/**
 	 * User-specific configuration, from system-wide and user home locations, without any repository-specific data.
-	 * 
 	 * @see http://www.selenic.com/mercurial/hgrc.5.html
 	 */
-	public static ConfigFile readConfiguration(SessionContext sessionCtx) throws IOException {
+	public static ConfigFile readConfiguration(SessionContext sessionCtx) throws HgIOException {
 		ConfigFile configFile = new ConfigFile(sessionCtx);
 		File hgInstallRoot = findHgInstallRoot(sessionCtx); // may be null
 		//
@@ -386,7 +385,7 @@
 	 * Repository-specific configuration
 	 * @see http://www.selenic.com/mercurial/hgrc.5.html
 	 */
-	public ConfigFile readConfiguration() throws IOException {
+	public ConfigFile readConfiguration() throws HgIOException {
 		ConfigFile configFile = readConfiguration(repo.getSessionContext());
 		// last one, overrides anything else
 		// <repo>/.hg/hgrc
--- a/src/org/tmatesoft/hg/internal/LineReader.java	Tue May 21 20:17:33 2013 +0200
+++ b/src/org/tmatesoft/hg/internal/LineReader.java	Wed May 22 15:52:31 2013 +0200
@@ -26,7 +26,7 @@
 import java.nio.charset.Charset;
 import java.util.Collection;
 
-import org.tmatesoft.hg.repo.HgInvalidFileException;
+import org.tmatesoft.hg.core.HgIOException;
 import org.tmatesoft.hg.util.LogFacility;
 
 /**
@@ -95,7 +95,7 @@
 			return this;
 		}
 
-		public <T> void read(LineConsumer<T> consumer, T paramObj) throws HgInvalidFileException {
+		public <T> void read(LineConsumer<T> consumer, T paramObj) throws HgIOException {
 			BufferedReader statusFileReader = null;
 			try {
 //				consumer.begin(file, paramObj);
@@ -120,7 +120,7 @@
 					}
 				}
 			} catch (IOException ex) {
-				throw new HgInvalidFileException(ex.getMessage(), ex, file);
+				throw new HgIOException(ex.getMessage(), ex, file);
 			} finally {
 				new FileUtils(log).closeQuietly(statusFileReader);
 //				try {
--- a/src/org/tmatesoft/hg/internal/NewlineFilter.java	Tue May 21 20:17:33 2013 +0200
+++ b/src/org/tmatesoft/hg/internal/NewlineFilter.java	Wed May 22 15:52:31 2013 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012 TMate Software Ltd
+ * Copyright (c) 2011-2013 TMate Software Ltd
  *  
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -28,7 +28,7 @@
 import java.util.ArrayList;
 import java.util.Map;
 
-import org.tmatesoft.hg.repo.HgInvalidFileException;
+import org.tmatesoft.hg.core.HgIOException;
 import org.tmatesoft.hg.repo.HgInvalidStateException;
 import org.tmatesoft.hg.repo.HgRepository;
 import org.tmatesoft.hg.util.Adaptable;
@@ -314,7 +314,7 @@
 			ConfigFile hgeol = new ConfigFile(hgRepo.getSessionContext());
 			try {
 				hgeol.addLocation(cfgFile);
-			} catch (HgInvalidFileException ex) {
+			} catch (HgIOException ex) {
 				hgRepo.getSessionContext().getLog().dump(getClass(), Warn, ex, null);
 			}
 			nativeRepoFormat = hgeol.getSection("repository").get("native");
--- a/src/org/tmatesoft/hg/internal/PhasesHelper.java	Tue May 21 20:17:33 2013 +0200
+++ b/src/org/tmatesoft/hg/internal/PhasesHelper.java	Wed May 22 15:52:31 2013 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 TMate Software Ltd
+ * Copyright (c) 2012-2013 TMate Software Ltd
  *  
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -37,6 +37,7 @@
 import org.tmatesoft.hg.repo.HgParentChildMap;
 import org.tmatesoft.hg.repo.HgPhase;
 import org.tmatesoft.hg.repo.HgRepository;
+import org.tmatesoft.hg.repo.HgRuntimeException;
 
 /**
  * Support to deal with Mercurial phases feature (as of Mercurial version 2.1)
@@ -69,7 +70,7 @@
 		return repo.getRepo();
 	}
 
-	public boolean isCapableOfPhases() throws HgInvalidControlFileException {
+	public boolean isCapableOfPhases() throws HgRuntimeException {
 		if (null == repoSupporsPhases) {
 			repoSupporsPhases = readRoots();
 		}
@@ -77,13 +78,26 @@
 	}
 
 
-	public HgPhase getPhase(HgChangeset cset) throws HgInvalidControlFileException {
+	/**
+	 * @param cset revision to query
+	 * @return phase of the changeset, never <code>null</code>
+	 * @throws HgInvalidControlFileException if failed to access revlog index/data entry. <em>Runtime exception</em>
+	 * @throws HgRuntimeException subclass thereof to indicate other issues with the library. <em>Runtime exception</em>
+	 */
+	public HgPhase getPhase(HgChangeset cset) throws HgRuntimeException {
 		final Nodeid csetRev = cset.getNodeid();
 		final int csetRevIndex = cset.getRevisionIndex();
 		return getPhase(csetRevIndex, csetRev);
 	}
 
-	public HgPhase getPhase(final int csetRevIndex, Nodeid csetRev) throws HgInvalidControlFileException {
+	/**
+	 * @param csetRevIndex revision index to query
+	 * @param csetRev revision nodeid, optional 
+	 * @return phase of the changeset, never <code>null</code>
+	 * @throws HgInvalidControlFileException if failed to access revlog index/data entry. <em>Runtime exception</em>
+	 * @throws HgRuntimeException subclass thereof to indicate other issues with the library. <em>Runtime exception</em>
+	 */
+	public HgPhase getPhase(final int csetRevIndex, Nodeid csetRev) throws HgRuntimeException {
 		if (!isCapableOfPhases()) {
 			return HgPhase.Undefined;
 		}
@@ -119,8 +133,8 @@
 
 	}
 
-	private Boolean readRoots() throws HgInvalidControlFileException {
-		File phaseroots = repo.getFileFromStoreDir("phaseroots");
+	private Boolean readRoots() throws HgRuntimeException {
+		File phaseroots = repo.getFileFromStoreDir("phaseroots"); // TODO into HgRepositoryFiles
 		BufferedReader br = null;
 		try {
 			if (!phaseroots.exists()) {
@@ -177,7 +191,7 @@
 	}
 
 
-	private RevisionDescendants[] getPhaseDescendants(HgPhase phase) throws HgInvalidControlFileException {
+	private RevisionDescendants[] getPhaseDescendants(HgPhase phase) throws HgRuntimeException {
 		int ordinal = phase.ordinal();
 		if (phaseDescendants[ordinal] == null) {
 			phaseDescendants[ordinal] = buildPhaseDescendants(phase);
@@ -185,7 +199,7 @@
 		return phaseDescendants[ordinal];
 	}
 
-	private RevisionDescendants[] buildPhaseDescendants(HgPhase phase) throws HgInvalidControlFileException {
+	private RevisionDescendants[] buildPhaseDescendants(HgPhase phase) throws HgRuntimeException {
 		int[] roots = toIndexes(getPhaseRoots(phase));
 		RevisionDescendants[] rv = new RevisionDescendants[roots.length];
 		for (int i = 0; i < roots.length; i++) {
@@ -195,7 +209,7 @@
 		return rv;
 	}
 	
-	private int[] toIndexes(List<Nodeid> roots) throws HgInvalidControlFileException {
+	private int[] toIndexes(List<Nodeid> roots) throws HgRuntimeException {
 		int[] rv = new int[roots.size()];
 		for (int i = 0; i < rv.length; i++) {
 			rv[i] = getRepo().getChangelog().getRevisionIndex(roots.get(i));
--- a/src/org/tmatesoft/hg/internal/RepositoryComparator.java	Tue May 21 20:17:33 2013 +0200
+++ b/src/org/tmatesoft/hg/internal/RepositoryComparator.java	Wed May 22 15:52:31 2013 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012 TMate Software Ltd
+ * Copyright (c) 2011-2013 TMate Software Ltd
  *  
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -33,12 +33,12 @@
 import org.tmatesoft.hg.core.HgRemoteConnectionException;
 import org.tmatesoft.hg.core.Nodeid;
 import org.tmatesoft.hg.repo.HgChangelog;
-import org.tmatesoft.hg.repo.HgInvalidControlFileException;
 import org.tmatesoft.hg.repo.HgInvalidStateException;
+import org.tmatesoft.hg.repo.HgParentChildMap;
 import org.tmatesoft.hg.repo.HgRemoteRepository;
 import org.tmatesoft.hg.repo.HgRemoteRepository.Range;
 import org.tmatesoft.hg.repo.HgRemoteRepository.RemoteBranch;
-import org.tmatesoft.hg.repo.HgParentChildMap;
+import org.tmatesoft.hg.repo.HgRuntimeException;
 import org.tmatesoft.hg.util.CancelSupport;
 import org.tmatesoft.hg.util.CancelledException;
 import org.tmatesoft.hg.util.ProgressSupport;
@@ -93,7 +93,7 @@
 	 * only its revision number. 
 	 * @param inspector delegate to analyze changesets, shall not be <code>null</code>
 	 */
-	public void visitLocalOnlyRevisions(HgChangelog.Inspector inspector) throws HgInvalidControlFileException {
+	public void visitLocalOnlyRevisions(HgChangelog.Inspector inspector) throws HgRuntimeException {
 		if (inspector == null) {
 			throw new IllegalArgumentException();
 		}
--- a/src/org/tmatesoft/hg/internal/RevisionDescendants.java	Tue May 21 20:17:33 2013 +0200
+++ b/src/org/tmatesoft/hg/internal/RevisionDescendants.java	Wed May 22 15:52:31 2013 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 TMate Software Ltd
+ * Copyright (c) 2012-2013 TMate Software Ltd
  *  
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -20,9 +20,9 @@
 
 import org.tmatesoft.hg.core.Nodeid;
 import org.tmatesoft.hg.repo.HgChangelog;
-import org.tmatesoft.hg.repo.HgInvalidControlFileException;
 import org.tmatesoft.hg.repo.HgInvalidStateException;
 import org.tmatesoft.hg.repo.HgRepository;
+import org.tmatesoft.hg.repo.HgRuntimeException;
 
 /**
  * Represent indicators which revisions are descendants of the supplied root revision
@@ -39,7 +39,7 @@
 	private final BitSet descendants;
 
 	// in fact, may be refactored to deal not only with changelog, but any revlog (not sure what would be the usecase, though)
-	public RevisionDescendants(HgRepository hgRepo, int revisionIndex) {
+	public RevisionDescendants(HgRepository hgRepo, int revisionIndex) throws HgRuntimeException {
 		repo = hgRepo;
 		rootRevIndex = revisionIndex;
 		// even if tip moves, we still answer correctly for those isCandidate()
@@ -51,7 +51,7 @@
 		descendants = new BitSet(tipRevIndex - rootRevIndex + 1);
 	}
 	
-	public void build() throws HgInvalidControlFileException {
+	public void build() throws HgRuntimeException {
 		final BitSet result = descendants;
 		result.set(0);
 		if (rootRevIndex == tipRevIndex) {
--- a/src/org/tmatesoft/hg/internal/RevisionLookup.java	Tue May 21 20:17:33 2013 +0200
+++ b/src/org/tmatesoft/hg/internal/RevisionLookup.java	Wed May 22 15:52:31 2013 +0200
@@ -21,7 +21,10 @@
 import java.util.Arrays;
 
 import org.tmatesoft.hg.core.Nodeid;
+import org.tmatesoft.hg.repo.HgInvalidControlFileException;
+import org.tmatesoft.hg.repo.HgInvalidRevisionException;
 import org.tmatesoft.hg.repo.HgRevisionMap;
+import org.tmatesoft.hg.repo.HgRuntimeException;
 
 /**
  * Lite alternative to {@link HgRevisionMap}, to speed up nodeid to index conversion without consuming too much memory.
@@ -42,7 +45,7 @@
 		content = stream;
 	}
 	
-	public static RevisionLookup createFor(RevlogStream stream) {
+	public static RevisionLookup createFor(RevlogStream stream) throws HgRuntimeException {
 		RevisionLookup rv = new RevisionLookup(stream);
 		int revCount = stream.revisionCount();
 		rv.prepare(revCount);
@@ -62,7 +65,7 @@
 	public void next(int index, Nodeid nodeid) {
 		nodeidHashes[index] = nodeid.hashCode();
 	}
-	public int findIndex(Nodeid nodeid) {
+	public int findIndex(Nodeid nodeid) throws HgInvalidControlFileException, HgInvalidRevisionException {
 		final int hash = nodeid.hashCode();
 		for (int i = 0; i < nodeidHashes.length; i++) {
 			if (nodeidHashes[i] == hash) {
--- a/src/org/tmatesoft/hg/internal/RevlogCompressor.java	Tue May 21 20:17:33 2013 +0200
+++ b/src/org/tmatesoft/hg/internal/RevlogCompressor.java	Wed May 22 15:52:31 2013 +0200
@@ -20,6 +20,7 @@
 
 import org.tmatesoft.hg.core.HgIOException;
 import org.tmatesoft.hg.core.SessionContext;
+import org.tmatesoft.hg.repo.HgRuntimeException;
 import org.tmatesoft.hg.util.LogFacility.Severity;
 
 /**
@@ -44,7 +45,7 @@
 	}
 	
 	// out stream is not closed!
-	public int writeCompressedData(DataSerializer out) throws HgIOException {
+	public int writeCompressedData(DataSerializer out) throws HgIOException, HgRuntimeException {
 		zip.reset();
 		DeflaterDataSerializer dds = new DeflaterDataSerializer(out, zip, sourceData.serializeLength());
 		sourceData.serialize(dds);
@@ -52,7 +53,7 @@
 		return zip.getTotalOut();
 	}
 
-	public int getCompressedLength() {
+	public int getCompressedLength() throws HgRuntimeException {
 		if (compressedLen != -1) {
 			return compressedLen;
 		}
--- a/src/org/tmatesoft/hg/internal/RevlogStream.java	Tue May 21 20:17:33 2013 +0200
+++ b/src/org/tmatesoft/hg/internal/RevlogStream.java	Wed May 22 15:52:31 2013 +0200
@@ -36,6 +36,7 @@
 import org.tmatesoft.hg.repo.HgInvalidRevisionException;
 import org.tmatesoft.hg.repo.HgInvalidStateException;
 import org.tmatesoft.hg.repo.HgRepository;
+import org.tmatesoft.hg.repo.HgRuntimeException;
 import org.tmatesoft.hg.util.Adaptable;
 
 
@@ -150,12 +151,12 @@
 		return inline ? indexFile.getPath() : getDataFile().getPath();
 	}
 
-	public boolean isInlineData() {
+	public boolean isInlineData() throws HgInvalidControlFileException {
 		initOutline();
 		return inline;
 	}
 	
-	public int revisionCount() {
+	public int revisionCount() throws HgInvalidControlFileException {
 		initOutline();
 		return baseRevisions.length;
 	}
@@ -271,7 +272,7 @@
 	 * @return value suitable for the corresponding field in the new revision's header, not physical offset in the file 
 	 * (which is different in case of inline revlogs)
 	 */
-	public long newEntryOffset() {
+	public long newEntryOffset() throws HgInvalidControlFileException {
 		if (revisionCount() == 0) {
 			return 0;
 		}
@@ -291,9 +292,12 @@
 		}
 	}
 
-	// should be possible to use TIP, ALL, or -1, -2, -n notation of Hg
-	// ? boolean needsNodeid
-	public void iterate(int start, int end, boolean needData, Inspector inspector) throws HgInvalidRevisionException, HgInvalidControlFileException {
+	/**
+	 * should be possible to use TIP, ALL, or -1, -2, -n notation of Hg
+	 * ? boolean needsNodeid
+	 * @throws HgRuntimeException subclass thereof to indicate issues with the library. <em>Runtime exception</em>
+	 */
+	public void iterate(int start, int end, boolean needData, Inspector inspector) throws HgRuntimeException {
 		initOutline();
 		final int indexSize = revisionCount();
 		if (indexSize == 0) {
@@ -326,8 +330,9 @@
 	 * @param sortedRevisions revisions to walk, in ascending order.
 	 * @param needData whether inspector needs access to header only
 	 * @param inspector callback to process entries
+	 * @throws HgRuntimeException subclass thereof to indicate issues with the library. <em>Runtime exception</em>
 	 */
-	public void iterate(int[] sortedRevisions, boolean needData, Inspector inspector) throws HgInvalidRevisionException, HgInvalidControlFileException /*REVISIT - too general exception*/ {
+	public void iterate(int[] sortedRevisions, boolean needData, Inspector inspector) throws HgRuntimeException {
 		final int indexSize = revisionCount();
 		if (indexSize == 0 || sortedRevisions.length == 0) {
 			return;
@@ -442,7 +447,7 @@
 		return inline ? indexRecordOffset[revisionIndex] : revisionIndex * REVLOGV1_RECORD_SIZE;
 	}
 	
-	private int checkRevisionIndex(int revisionIndex) throws HgInvalidRevisionException {
+	private int checkRevisionIndex(int revisionIndex) throws HgInvalidControlFileException, HgInvalidRevisionException {
 		final int last = revisionCount() - 1;
 		if (revisionIndex == TIP) {
 			revisionIndex = last;
@@ -722,7 +727,7 @@
 		}
 
 		// may be invoked few times per instance life
-		public boolean range(int start, int end) throws IOException {
+		public boolean range(int start, int end) throws IOException, HgRuntimeException {
 			int i;
 			// it (i.e. replace with i >= start)
 			if (needData && (i = getBaseRevision(start)) < start) {
@@ -850,7 +855,7 @@
 		 * @param data access to revision content of actualLen size, or <code>null</code> if no data has been requested with 
 		 *        {@link RevlogStream#iterate(int[], boolean, Inspector)}
 		 */
-		void next(int revisionIndex, int actualLen, int baseRevision, int linkRevision, int parent1Revision, int parent2Revision, byte[/*20*/] nodeid, DataAccess data);
+		void next(int revisionIndex, int actualLen, int baseRevision, int linkRevision, int parent1Revision, int parent2Revision, byte[/*20*/] nodeid, DataAccess data) throws HgRuntimeException;
 	}
 
 	public interface Observer {
--- a/src/org/tmatesoft/hg/internal/RevlogStreamWriter.java	Tue May 21 20:17:33 2013 +0200
+++ b/src/org/tmatesoft/hg/internal/RevlogStreamWriter.java	Wed May 22 15:52:31 2013 +0200
@@ -29,7 +29,9 @@
 import org.tmatesoft.hg.internal.DataSerializer.ByteArrayDataSource;
 import org.tmatesoft.hg.internal.DataSerializer.DataSource;
 import org.tmatesoft.hg.repo.HgInvalidControlFileException;
+import org.tmatesoft.hg.repo.HgInvalidRevisionException;
 import org.tmatesoft.hg.repo.HgInvalidStateException;
+import org.tmatesoft.hg.repo.HgRuntimeException;
 
 /**
  * 
@@ -61,8 +63,9 @@
 	
 	/**
 	 * @return nodeid of added revision
+	 * @throws HgRuntimeException 
 	 */
-	public Nodeid addRevision(DataSource content, int linkRevision, int p1, int p2) throws HgIOException {
+	public Nodeid addRevision(DataSource content, int linkRevision, int p1, int p2) throws HgIOException, HgRuntimeException {
 		lastEntryRevision = Nodeid.NULL;
 		int revCount = revlogStream.revisionCount();
 		lastEntryIndex = revCount == 0 ? NO_REVISION : revCount - 1;
@@ -138,13 +141,13 @@
 		return lastEntryRevision;
 	}
 	
-	private byte[] toByteArray(DataSource content) throws HgIOException {
+	private byte[] toByteArray(DataSource content) throws HgIOException, HgRuntimeException {
 		ByteArrayDataSerializer ba = new ByteArrayDataSerializer();
 		content.serialize(ba);
 		return ba.toByteArray();
 	}
 
-	private Nodeid revision(int revisionIndex) {
+	private Nodeid revision(int revisionIndex) throws HgInvalidControlFileException, HgInvalidRevisionException {
 		if (revisionIndex == NO_REVISION) {
 			return Nodeid.NULL;
 		}
@@ -156,7 +159,7 @@
 		return n;
 	}
 	
-	private void populateLastEntry() throws HgInvalidControlFileException {
+	private void populateLastEntry() throws HgRuntimeException {
 		if (lastEntryContent != null) {
 			return;
 		}
--- a/src/org/tmatesoft/hg/internal/WorkingCopyContent.java	Tue May 21 20:17:33 2013 +0200
+++ b/src/org/tmatesoft/hg/internal/WorkingCopyContent.java	Wed May 22 15:52:31 2013 +0200
@@ -26,6 +26,7 @@
 import org.tmatesoft.hg.repo.HgInvalidFileException;
 import org.tmatesoft.hg.repo.HgInvalidStateException;
 import org.tmatesoft.hg.repo.HgRepository;
+import org.tmatesoft.hg.repo.HgRuntimeException;
 import org.tmatesoft.hg.util.ByteChannel;
 import org.tmatesoft.hg.util.CancelledException;
 
@@ -47,7 +48,7 @@
 		}
 	}
 
-	public void serialize(final DataSerializer out) throws HgIOException {
+	public void serialize(final DataSerializer out) throws HgIOException, HgRuntimeException {
 		final HgIOException failure[] = new HgIOException[1];
 		try {
 			// TODO #workingCopy API is very limiting, CancelledException is inconvenient, 
@@ -80,7 +81,7 @@
 		}
 	}
 
-	public int serializeLength() {
+	public int serializeLength() throws HgRuntimeException {
 		return file.getLength(HgRepository.WORKING_COPY);
 	}
 }
\ No newline at end of file
--- a/src/org/tmatesoft/hg/internal/WorkingDirFileWriter.java	Tue May 21 20:17:33 2013 +0200
+++ b/src/org/tmatesoft/hg/internal/WorkingDirFileWriter.java	Wed May 22 15:52:31 2013 +0200
@@ -26,6 +26,7 @@
 
 import org.tmatesoft.hg.repo.HgDataFile;
 import org.tmatesoft.hg.repo.HgManifest;
+import org.tmatesoft.hg.repo.HgRuntimeException;
 import org.tmatesoft.hg.util.ByteChannel;
 import org.tmatesoft.hg.util.CancelledException;
 import org.tmatesoft.hg.util.LogFacility.Severity;
@@ -62,8 +63,9 @@
 	/**
 	 * Writes content of specified file revision into local filesystem, or create a symlink according to flags. 
 	 * Executable bit is set if specified and filesystem supports it. 
+	 * @throws HgRuntimeException 
 	 */
-	public void processFile(HgDataFile df, int fileRevIndex, HgManifest.Flags flags) throws IOException {
+	public void processFile(HgDataFile df, int fileRevIndex, HgManifest.Flags flags) throws IOException, HgRuntimeException {
 		try {
 			prepare(df.getPath());
 			if (flags != HgManifest.Flags.Link) {
--- a/src/org/tmatesoft/hg/repo/HgBookmarks.java	Tue May 21 20:17:33 2013 +0200
+++ b/src/org/tmatesoft/hg/repo/HgBookmarks.java	Wed May 22 15:52:31 2013 +0200
@@ -52,66 +52,78 @@
 		repo = internals;
 	}
 	
-	/*package-local*/ void read() throws HgInvalidControlFileException {
+	/*package-local*/ void read() throws HgRuntimeException {
 		readBookmarks();
 		readActiveBookmark();
 	}
 	
-	private void readBookmarks() throws HgInvalidControlFileException {
+	private void readBookmarks() throws HgRuntimeException {
 		final LogFacility log = repo.getLog();
 		File all = repo.getRepositoryFile(HgRepositoryFiles.Bookmarks);
-		LinkedHashMap<String, Nodeid> bm = new LinkedHashMap<String, Nodeid>();
-		if (all.canRead() && all.isFile()) {
-			LineReader lr1 = new LineReader(all, log);
-			ArrayList<String> c = new ArrayList<String>();
-			lr1.read(new LineReader.SimpleLineCollector(), c);
-			for (String s : c) {
-				int x = s.indexOf(' ');
-				try {
-					if (x > 0) {
-						Nodeid nid = Nodeid.fromAscii(s.substring(0, x));
-						String name = new String(s.substring(x+1));
-						if (repo.getRepo().getChangelog().isKnown(nid)) {
-							// copy name part not to drag complete line
-							bm.put(name, nid);
+		try {
+			LinkedHashMap<String, Nodeid> bm = new LinkedHashMap<String, Nodeid>();
+			if (all.canRead() && all.isFile()) {
+				LineReader lr1 = new LineReader(all, log);
+				ArrayList<String> c = new ArrayList<String>();
+				lr1.read(new LineReader.SimpleLineCollector(), c);
+				for (String s : c) {
+					int x = s.indexOf(' ');
+					try {
+						if (x > 0) {
+							Nodeid nid = Nodeid.fromAscii(s.substring(0, x));
+							String name = new String(s.substring(x+1));
+							if (repo.getRepo().getChangelog().isKnown(nid)) {
+								// copy name part not to drag complete line
+								bm.put(name, nid);
+							} else {
+								log.dump(getClass(), LogFacility.Severity.Info, "Bookmark %s points to non-existent revision %s, ignored.", name, nid);
+							}
 						} else {
-							log.dump(getClass(), LogFacility.Severity.Info, "Bookmark %s points to non-existent revision %s, ignored.", name, nid);
+							log.dump(getClass(), LogFacility.Severity.Warn, "Can't parse bookmark entry: %s", s);
 						}
-					} else {
-						log.dump(getClass(), LogFacility.Severity.Warn, "Can't parse bookmark entry: %s", s);
+					} catch (IllegalArgumentException ex) {
+						log.dump(getClass(), LogFacility.Severity.Warn, ex, String.format("Can't parse bookmark entry: %s", s));
 					}
-				} catch (IllegalArgumentException ex) {
-					log.dump(getClass(), LogFacility.Severity.Warn, ex, String.format("Can't parse bookmark entry: %s", s));
 				}
+				bookmarks = bm;
+			} else {
+				bookmarks = Collections.emptyMap();
 			}
-			bookmarks = bm;
-		} else {
-			bookmarks = Collections.emptyMap();
+			if (bmFileTracker == null) {
+				bmFileTracker = new FileChangeMonitor(all);
+			}
+			bmFileTracker.touch(this);
+		} catch (HgInvalidControlFileException ex) {
+			// do not translate HgInvalidControlFileException into another HgInvalidControlFileException
+			// but only HgInvalidFileException
+			throw ex;
+		} catch (HgIOException ex) {
+			throw new HgInvalidControlFileException(ex, true);
 		}
-		if (bmFileTracker == null) {
-			bmFileTracker = new FileChangeMonitor(all);
-		}
-		bmFileTracker.touch(this);
 	}
-		
+
 	private void readActiveBookmark() throws HgInvalidControlFileException { 
 		activeBookmark = null;
 		File active = repo.getRepositoryFile(HgRepositoryFiles.BookmarksCurrent);
-		if (active.canRead() && active.isFile()) {
-			LineReader lr2 = new LineReader(active, repo.getLog());
-			ArrayList<String> c = new ArrayList<String>(2);
-			lr2.read(new LineReader.SimpleLineCollector(), c);
-			if (c.size() > 0) {
-				activeBookmark = c.get(0);
+		try {
+			if (active.canRead() && active.isFile()) {
+				LineReader lr2 = new LineReader(active, repo.getLog());
+				ArrayList<String> c = new ArrayList<String>(2);
+				lr2.read(new LineReader.SimpleLineCollector(), c);
+				if (c.size() > 0) {
+					activeBookmark = c.get(0);
+				}
 			}
+			if (activeTracker == null) {
+				activeTracker = new FileChangeMonitor(active);
+			}
+			activeTracker.touch(this);
+		} catch (HgIOException ex) {
+			throw new HgInvalidControlFileException(ex, true);
 		}
-		if (activeTracker == null) {
-			activeTracker = new FileChangeMonitor(active);
-		}
-		activeTracker.touch(this);
 	}
 	
-	/*package-local*/void reloadIfChanged() throws HgInvalidControlFileException {
+	/*package-local*/void reloadIfChanged() throws HgRuntimeException {
 		assert activeTracker != null;
 		assert bmFileTracker != null;
 		if (bmFileTracker.changed(this)) {
--- a/src/org/tmatesoft/hg/repo/HgBranches.java	Tue May 21 20:17:33 2013 +0200
+++ b/src/org/tmatesoft/hg/repo/HgBranches.java	Wed May 22 15:52:31 2013 +0200
@@ -40,6 +40,7 @@
 import org.tmatesoft.hg.core.Nodeid;
 import org.tmatesoft.hg.internal.ChangelogMonitor;
 import org.tmatesoft.hg.internal.Experimental;
+import org.tmatesoft.hg.internal.FileUtils;
 import org.tmatesoft.hg.internal.Internals;
 import org.tmatesoft.hg.repo.HgChangelog.RawChangeset;
 import org.tmatesoft.hg.util.ProgressSupport;
@@ -68,7 +69,7 @@
 		if (!branchheadsCache.canRead()) {
 			return lastInCache;
 		}
-		BufferedReader br = null;
+		BufferedReader br = null; // TODO replace with LineReader
 		final Pattern spacePattern = Pattern.compile(" ");
 		try {
 			final LinkedHashMap<String, List<Nodeid>> branchHeads = new LinkedHashMap<String, List<Nodeid>>();
@@ -111,26 +112,17 @@
 		} catch (NumberFormatException ex) {
 			repo.getSessionContext().getLog().dump(getClass(), Warn, ex, null);
 			// FALL THROUGH
-		} catch (HgInvalidControlFileException ex) {
-			// shall not happen, thus log as error
-			repo.getSessionContext().getLog().dump(getClass(), Error, ex, null);
-			// FALL THROUGH
-		} catch (HgInvalidRevisionException ex) {
+		} catch (HgRuntimeException ex) {
+			// if happens, log error and pretend there's no cache
 			repo.getSessionContext().getLog().dump(getClass(), Error, ex, null);
 			// FALL THROUGH
 		} finally {
-			if (br != null) {
-				try {
-					br.close();
-				} catch (IOException ex) {
-					repo.getSessionContext().getLog().dump(getClass(), Warn, ex, null); // ignore
-				}
-			}
+			new FileUtils(repo.getSessionContext().getLog()).closeQuietly(br);
 		}
 		return -1; // deliberately not lastInCache, to avoid anything but -1 when 1st line was read and there's error is in lines 2..end
 	}
 
-	void collect(final ProgressSupport ps) throws HgInvalidControlFileException {
+	void collect(final ProgressSupport ps) throws HgRuntimeException {
 		branches.clear();
 		final HgRepository repo = internalRepo.getRepo();
 		ps.start(1 + repo.getChangelog().getRevisionCount() * 2);
@@ -286,7 +278,7 @@
 		return internalRepo.getFileFromRepoDir("cache/branchheads");
 	}
 	
-	/*package-local*/ void reloadIfChanged(ProgressSupport ps) throws HgInvalidControlFileException {
+	/*package-local*/ void reloadIfChanged(ProgressSupport ps) throws HgRuntimeException {
 		if (repoChangeTracker.isChanged()) {
 			collect(ps);
 		}
@@ -313,7 +305,7 @@
 			this(branchName, Nodeid.NULL, branchHeads);
 		}
 		
-		void validate(HgChangelog clog, HgRevisionMap<HgChangelog> rmap) throws HgInvalidControlFileException {
+		void validate(HgChangelog clog, HgRevisionMap<HgChangelog> rmap) throws HgRuntimeException {
 			int[] localCset = new int[heads.size()];
 			int i = 0;
 			for (Nodeid h : heads) {
--- a/src/org/tmatesoft/hg/repo/HgBundle.java	Tue May 21 20:17:33 2013 +0200
+++ b/src/org/tmatesoft/hg/repo/HgBundle.java	Wed May 22 15:52:31 2013 +0200
@@ -143,7 +143,7 @@
 
 To recreate 30bd..e5, one have to take content of 9429..e0, not its p1 f1db..5e
  */
-			public boolean element(GroupElement ge) {
+			public boolean element(GroupElement ge) throws HgRuntimeException {
 				emptyChangelog = false;
 				HgChangelog changelog = hgRepo.getChangelog();
 				try {
@@ -194,24 +194,24 @@
 	// callback to minimize amount of Strings and Nodeids instantiated
 	@Callback
 	public interface Inspector {
-		void changelogStart();
-
-		void changelogEnd();
+		void changelogStart() throws HgRuntimeException;
 
-		void manifestStart();
+		void changelogEnd() throws HgRuntimeException;
 
-		void manifestEnd();
+		void manifestStart() throws HgRuntimeException;
 
-		void fileStart(String name);
+		void manifestEnd() throws HgRuntimeException;
 
-		void fileEnd(String name);
+		void fileStart(String name) throws HgRuntimeException;
+
+		void fileEnd(String name) throws HgRuntimeException;
 
 		/**
 		 * XXX desperately need exceptions here
 		 * @param element data element, instance might be reused, don't keep a reference to it or its raw data
 		 * @return <code>true</code> to continue
 		 */
-		boolean element(GroupElement element);
+		boolean element(GroupElement element) throws HgRuntimeException;
 	}
 
 	/**
@@ -355,7 +355,7 @@
 		flowControl = null;
 	}
 
-	private void internalInspectChangelog(DataAccess da, Inspector inspector) throws IOException {
+	private void internalInspectChangelog(DataAccess da, Inspector inspector) throws IOException, HgRuntimeException {
 		if (da.isEmpty()) {
 			return;
 		}
@@ -370,7 +370,7 @@
 		inspector.changelogEnd();
 	}
 
-	private void internalInspectManifest(DataAccess da, Inspector inspector) throws IOException {
+	private void internalInspectManifest(DataAccess da, Inspector inspector) throws IOException, HgRuntimeException {
 		if (da.isEmpty()) {
 			return;
 		}
@@ -385,7 +385,7 @@
 		inspector.manifestEnd();
 	}
 
-	private void internalInspectFiles(DataAccess da, Inspector inspector) throws IOException {
+	private void internalInspectFiles(DataAccess da, Inspector inspector) throws IOException, HgRuntimeException {
 		while (!da.isEmpty()) {
 			int fnameLen = da.readInt();
 			if (fnameLen <= 4) {
@@ -406,7 +406,7 @@
 		}
 	}
 
-	private static void readGroup(DataAccess da, Inspector inspector) throws IOException {
+	private static void readGroup(DataAccess da, Inspector inspector) throws IOException, HgRuntimeException {
 		int len = da.readInt();
 		boolean good2go = true;
 		Nodeid prevNodeid = Nodeid.NULL;
--- a/src/org/tmatesoft/hg/repo/HgChangelog.java	Tue May 21 20:17:33 2013 +0200
+++ b/src/org/tmatesoft/hg/repo/HgChangelog.java	Wed May 22 15:52:31 2013 +0200
@@ -53,18 +53,40 @@
 		super(hgRepo, content, true);
 	}
 
-	public void all(final HgChangelog.Inspector inspector) throws HgInvalidRevisionException, HgInvalidControlFileException {
+	/**
+	 * Iterate over whole changelog
+	 * @param inspector callback to process entries
+	 * @throws HgInvalidControlFileException if failed to access revlog index/data entry. <em>Runtime exception</em>
+	 * @throws HgRuntimeException subclass thereof to indicate other issues with the library. <em>Runtime exception</em>
+	 */
+	public void all(final HgChangelog.Inspector inspector) throws HgRuntimeException {
 		range(0, getLastRevision(), inspector);
 	}
 
-	public void range(int start, int end, final HgChangelog.Inspector inspector) throws HgInvalidRevisionException, HgInvalidControlFileException {
+	/**
+	 * Iterate over changelog part
+	 * @param start first changelog entry to process
+	 * @param end last changelog entry to process
+	 * @param inspector callback to process entries
+	 * @throws HgInvalidRevisionException if any supplied revision doesn't identify revision from this revlog. <em>Runtime exception</em>
+	 * @throws HgInvalidControlFileException if failed to access revlog index/data entry. <em>Runtime exception</em>
+	 * @throws HgRuntimeException subclass thereof to indicate other issues with the library. <em>Runtime exception</em>
+	 */
+	public void range(int start, int end, final HgChangelog.Inspector inspector) throws HgRuntimeException {
 		if (inspector == null) {
 			throw new IllegalArgumentException();
 		}
 		content.iterate(start, end, true, new RawCsetParser(inspector));
 	}
 
-	public List<RawChangeset> range(int start, int end) throws HgInvalidRevisionException, HgInvalidControlFileException {
+	/**
+	 * @see #range(int, int, Inspector)
+	 * @return changeset entry objects, never <code>null</code>
+	 * @throws HgInvalidRevisionException if any supplied revision doesn't identify revision from this revlog. <em>Runtime exception</em>
+	 * @throws HgInvalidControlFileException if failed to access revlog index/data entry. <em>Runtime exception</em>
+	 * @throws HgRuntimeException subclass thereof to indicate other issues with the library. <em>Runtime exception</em>
+	 */
+	public List<RawChangeset> range(int start, int end) throws HgRuntimeException {
 		final RawCsetCollector c = new RawCsetCollector(end - start + 1);
 		range(start, end, c);
 		return c.result;
@@ -75,8 +97,11 @@
 	 * changesets strictly in the order they are in the changelog.
 	 * @param inspector callback to get changesets
 	 * @param revisions revisions to read, unrestricted ordering.
+	 * @throws HgInvalidRevisionException if any supplied revision doesn't identify revision from this revlog <em>Runtime exception</em>
+	 * @throws HgInvalidControlFileException if failed to access revlog index/data entry. <em>Runtime exception</em>
+	 * @throws HgRuntimeException subclass thereof to indicate other issues with the library. <em>Runtime exception</em>
 	 */
-	public void range(final HgChangelog.Inspector inspector, final int... revisions) throws HgInvalidRevisionException, HgInvalidControlFileException {
+	public void range(final HgChangelog.Inspector inspector, final int... revisions) throws HgRuntimeException {
 		Arrays.sort(revisions);
 		rangeInternal(inspector, revisions);
 	}
@@ -84,7 +109,7 @@
 	/**
 	 * Friends-only version of {@link #range(Inspector, int...)}, when callers know array is sorted
 	 */
-	/*package-local*/ void rangeInternal(HgChangelog.Inspector inspector, int[] sortedRevisions) throws HgInvalidRevisionException, HgInvalidControlFileException {
+	/*package-local*/ void rangeInternal(HgChangelog.Inspector inspector, int[] sortedRevisions) throws HgRuntimeException {
 		if (sortedRevisions == null || sortedRevisions.length == 0) {
 			return;
 		}
@@ -95,10 +120,12 @@
 	}
 
 	/**
-	 * @throws HgInvalidRevisionException if supplied nodeid doesn't identify any revision from this revlog  
-	 * @throws HgInvalidControlFileException if access to revlog index/data entry failed
+	 * Get changeset entry object
+	 * @throws HgInvalidRevisionException if supplied nodeid doesn't identify any revision from this revlog. <em>Runtime exception</em>
+	 * @throws HgInvalidControlFileException if failed to access revlog index/data entry. <em>Runtime exception</em>
+	 * @throws HgRuntimeException subclass thereof to indicate other issues with the library. <em>Runtime exception</em>
 	 */
-	public RawChangeset changeset(Nodeid nid)  throws HgInvalidControlFileException, HgInvalidRevisionException {
+	public RawChangeset changeset(Nodeid nid)  throws HgRuntimeException {
 		int x = getRevisionIndex(nid);
 		return range(x, x).get(0);
 	}
@@ -113,7 +140,7 @@
 		 * @param nodeid revision being inspected
 		 * @param cset changeset raw data
 		 */
-		void next(int revisionIndex, Nodeid nodeid, RawChangeset cset);
+		void next(int revisionIndex, Nodeid nodeid, RawChangeset cset) throws HgRuntimeException;
 	}
 
 	/**
@@ -396,7 +423,7 @@
 			}
 		}
 
-		public void next(int revisionNumber, int actualLen, int baseRevision, int linkRevision, int parent1Revision, int parent2Revision, byte[] nodeid, DataAccess da) {
+		public void next(int revisionNumber, int actualLen, int baseRevision, int linkRevision, int parent1Revision, int parent2Revision, byte[] nodeid, DataAccess da) throws HgRuntimeException {
 			try {
 				byte[] data = da.byteArray();
 				cset.init(data, 0, data.length, usersPool);
--- a/src/org/tmatesoft/hg/repo/HgDataFile.java	Tue May 21 20:17:33 2013 +0200
+++ b/src/org/tmatesoft/hg/repo/HgDataFile.java	Wed May 22 15:52:31 2013 +0200
@@ -194,8 +194,10 @@
 	
 	/**
 	 * @return file revision as recorded in repository manifest for dirstate parent, or <code>null</code> if no file revision can be found 
+	 * @throws HgInvalidControlFileException if failed to access revlog index/data entry. <em>Runtime exception</em>
+	 * @throws HgRuntimeException subclass thereof to indicate other issues with the library. <em>Runtime exception</em>
 	 */
-	private Nodeid getWorkingCopyRevision() throws HgInvalidControlFileException {
+	private Nodeid getWorkingCopyRevision() throws HgRuntimeException {
 		final Pair<Nodeid, Nodeid> wcParents = getRepo().getWorkingCopyParents();
 		Nodeid p = wcParents.first().isNull() ? wcParents.second() : wcParents.first();
 		final HgChangelog clog = getRepo().getChangelog();
@@ -217,7 +219,7 @@
 				csetRevIndex = clog.getLastRevision();
 			} else {
 				// bad luck, need to search honestly
-				csetRevIndex = getRepo().getChangelog().getRevisionIndex(p);
+				csetRevIndex = clog.getRevisionIndex(p);
 			}
 		}
 		Nodeid fileRev = getRepo().getManifest().getFileRevision(csetRevIndex, getPath());
@@ -428,7 +430,7 @@
 	/**
 	 * mimic 'hg diff -r clogRevIndex1 -r clogRevIndex2'
 	 */
-	public void diff(int clogRevIndex1, int clogRevIndex2, HgBlameInspector insp) throws HgCallbackTargetException {
+	public void diff(int clogRevIndex1, int clogRevIndex2, HgBlameInspector insp) throws HgRuntimeException, HgCallbackTargetException {
 		int fileRevIndex1 = fileRevIndex(this, clogRevIndex1);
 		int fileRevIndex2 = fileRevIndex(this, clogRevIndex2);
 		BlameHelper bh = new BlameHelper(insp);
@@ -439,14 +441,14 @@
 	/**
 	 * Walk file history up/down to revision at given changeset and report changes for each revision
 	 */
-	public void annotate(int changelogRevisionIndex, HgBlameInspector insp, HgIterateDirection iterateOrder) throws HgCallbackTargetException {
+	public void annotate(int changelogRevisionIndex, HgBlameInspector insp, HgIterateDirection iterateOrder) throws HgRuntimeException, HgCallbackTargetException {
 		annotate(0, changelogRevisionIndex, insp, iterateOrder);
 	}
 
 	/**
 	 * Walk file history range and report changes for each revision
 	 */
-	public void annotate(int changelogRevIndexStart, int changelogRevIndexEnd, HgBlameInspector insp, HgIterateDirection iterateOrder) throws HgCallbackTargetException {
+	public void annotate(int changelogRevIndexStart, int changelogRevIndexEnd, HgBlameInspector insp, HgIterateDirection iterateOrder) throws HgRuntimeException, HgCallbackTargetException {
 		if (wrongRevisionIndex(changelogRevIndexStart) || wrongRevisionIndex(changelogRevIndexEnd)) {
 			throw new IllegalArgumentException();
 		}
@@ -483,7 +485,7 @@
 	 * Unlike {@link #annotate(HgDataFile, int, Inspector, HgIterateDirection)}, doesn't
 	 * walk file history, looks at the specified revision only. Handles both parents (if merge revision).
 	 */
-	public void annotateSingleRevision(int changelogRevisionIndex, HgBlameInspector insp) throws HgCallbackTargetException {
+	public void annotateSingleRevision(int changelogRevisionIndex, HgBlameInspector insp) throws HgRuntimeException, HgCallbackTargetException {
 		// TODO detect if file is text/binary (e.g. looking for chars < ' ' and not \t\r\n\f
 		int fileRevIndex = fileRevIndex(this, changelogRevisionIndex);
 		int[] fileRevParents = new int[2];
@@ -509,7 +511,7 @@
 		return sb.toString();
 	}
 	
-	private void checkAndRecordMetadata(int localRev) throws HgInvalidControlFileException {
+	private void checkAndRecordMetadata(int localRev) throws HgRuntimeException {
 		if (metadata == null) {
 			metadata = new Metadata(getRepo());
 		}
@@ -519,7 +521,7 @@
 	}
 	
 
-	private static int fileRevIndex(HgDataFile df, int csetRevIndex) {
+	private static int fileRevIndex(HgDataFile df, int csetRevIndex) throws HgRuntimeException {
 		Nodeid fileRev = df.getRepo().getManifest().getFileRevision(csetRevIndex, df.getPath());
 		return df.getRevisionIndex(fileRev);
 	}
@@ -539,7 +541,7 @@
 			setCancelSupport(CancelSupport.Factory.get(chain));
 		}
 
-		public void next(int revisionNumber, int actualLen, int baseRevision, int linkRevision, int parent1Revision, int parent2Revision, byte[] nodeid, DataAccess data) {
+		public void next(int revisionNumber, int actualLen, int baseRevision, int linkRevision, int parent1Revision, int parent2Revision, byte[] nodeid, DataAccess data) throws HgRuntimeException {
 			try {
 				if (metadata.tryRead(revisionNumber, data)) {
 					// da is in prepared state (i.e. we consumed all bytes up to metadata end).
--- a/src/org/tmatesoft/hg/repo/HgInvalidControlFileException.java	Tue May 21 20:17:33 2013 +0200
+++ b/src/org/tmatesoft/hg/repo/HgInvalidControlFileException.java	Wed May 22 15:52:31 2013 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012 TMate Software Ltd
+ * Copyright (c) 2011-2013 TMate Software Ltd
  *  
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -18,6 +18,7 @@
 
 import java.io.File;
 
+import org.tmatesoft.hg.core.HgIOException;
 import org.tmatesoft.hg.core.Nodeid;
 import org.tmatesoft.hg.util.Path;
 
@@ -35,6 +36,13 @@
 	public HgInvalidControlFileException(String message, Throwable th, File file) {
 		super(message, th, file);
 	}
+	
+	public HgInvalidControlFileException(HgIOException ex, boolean replaceStackTrace) {
+		super(ex.getMessage(), ex.getCause(), ex.getFile());
+		if (replaceStackTrace) {
+			setStackTrace(ex.getStackTrace());
+		}
+	}
 
 	@Override
 	public HgInvalidControlFileException setFile(File file) {
--- a/src/org/tmatesoft/hg/repo/HgInvalidFileException.java	Tue May 21 20:17:33 2013 +0200
+++ b/src/org/tmatesoft/hg/repo/HgInvalidFileException.java	Wed May 22 15:52:31 2013 +0200
@@ -19,6 +19,8 @@
 import java.io.File;
 import java.io.IOException;
 
+import org.tmatesoft.hg.util.Path;
+
 /**
  * Thrown when there are troubles working with local file. Most likely (but not necessarily) wraps IOException. Might be 
  * perceived as specialized IOException with optional File and other repository information.
@@ -59,6 +61,12 @@
 		details.setFile(file);
 		return this;
 	}
+	
+	@Override
+	public HgInvalidFileException setFileName(Path name) {
+		super.setFileName(name);
+		return this;
+	}
 
 	/**
 	 * @return file object that causes troubles, or <code>null</code> if specific file is unknown
--- a/src/org/tmatesoft/hg/repo/HgLookup.java	Tue May 21 20:17:33 2013 +0200
+++ b/src/org/tmatesoft/hg/repo/HgLookup.java	Wed May 22 15:52:31 2013 +0200
@@ -23,6 +23,7 @@
 import java.net.URL;
 
 import org.tmatesoft.hg.core.HgBadArgumentException;
+import org.tmatesoft.hg.core.HgIOException;
 import org.tmatesoft.hg.core.HgRepositoryNotFoundException;
 import org.tmatesoft.hg.core.SessionContext;
 import org.tmatesoft.hg.internal.BasicSessionContext;
@@ -80,13 +81,19 @@
 		if (repository == null) {
 			throw new HgRepositoryNotFoundException(String.format("Can't locate .hg/ directory of Mercurial repository in %s nor in parent dirs", location)).setLocation(location.getPath());
 		}
-		String repoPath = repository.getParentFile().getAbsolutePath();
-		HgRepository rv = new HgRepository(getSessionContext(), repoPath, repository);
-		int requiresFlags = rv.getImplHelper().getRequiresFlags();
-		if ((requiresFlags & RequiresFile.REVLOGV1) == 0) {
-			throw new HgRepositoryNotFoundException(String.format("%s: repository version is not supported (Mercurial <0.9?)", repoPath)).setLocation(location.getPath());
+		try {
+			String repoPath = repository.getParentFile().getAbsolutePath();
+			HgRepository rv = new HgRepository(getSessionContext(), repoPath, repository);
+			int requiresFlags = rv.getImplHelper().getRequiresFlags();
+			if ((requiresFlags & RequiresFile.REVLOGV1) == 0) {
+				throw new HgRepositoryNotFoundException(String.format("%s: repository version is not supported (Mercurial <0.9?)", repoPath)).setLocation(location.getPath());
+			}
+			return rv;
+		} catch (HgRuntimeException ex) {
+			HgRepositoryNotFoundException e = new HgRepositoryNotFoundException("Failed to initialize Hg4J library").setLocation(location.getPath());
+			e.initCause(ex);
+			throw e;
 		}
-		return rv;
 	}
 	
 	public HgBundle loadBundle(File location) throws HgRepositoryNotFoundException {
@@ -152,7 +159,7 @@
 			globalCfg = new ConfigFile(getSessionContext());
 			try {
 				globalCfg.addLocation(new File(System.getProperty("user.home"), ".hgrc"));
-			} catch (HgInvalidFileException ex) {
+			} catch (HgIOException ex) {
 				// XXX perhaps, makes sense to let caller/client know that we've failed to read global config? 
 				getSessionContext().getLog().dump(getClass(), Warn, ex, null);
 			}
--- a/src/org/tmatesoft/hg/repo/HgManifest.java	Tue May 21 20:17:33 2013 +0200
+++ b/src/org/tmatesoft/hg/repo/HgManifest.java	Wed May 22 15:52:31 2013 +0200
@@ -237,7 +237,9 @@
 	 * 
 	 * @param inspector manifest revision visitor, can't be <code>null</code>
 	 * @param revisionIndexes local indexes of changesets to visit, non-<code>null</code>
-	 * @throws HgRuntimeException subclass thereof to indicate issues with the library. <em>Runtime exception</em>
+	 * @throws HgInvalidRevisionException if method argument specifies non-existent revision index. <em>Runtime exception</em>
+	 * @throws HgInvalidControlFileException if failed to access revlog index/data entry. <em>Runtime exception</em>
+	 * @throws HgRuntimeException subclass thereof to indicate other issues with the library. <em>Runtime exception</em>
 	 * @throws InvalidArgumentException if supplied arguments are <code>null</code>s
 	 */
 	public void walk(final Inspector inspector, int... revisionIndexes) throws HgRuntimeException, IllegalArgumentException {
@@ -253,10 +255,11 @@
 	 * Tells manifest revision number that corresponds to the given changeset. May return {@link HgRepository#BAD_REVISION} 
 	 * if changeset has no associated manifest (cset records NULL nodeid for manifest).
 	 * @return manifest revision index, non-negative, or {@link HgRepository#BAD_REVISION}.
-	 * @throws HgInvalidRevisionException if method argument specifies non-existent revision index
-	 * @throws HgInvalidControlFileException if access to revlog index/data entry failed
+	 * @throws HgInvalidRevisionException if method argument specifies non-existent revision index. <em>Runtime exception</em>
+	 * @throws HgInvalidControlFileException if failed to access revlog index/data entry. <em>Runtime exception</em>
+	 * @throws HgRuntimeException subclass thereof to indicate other issues with the library. <em>Runtime exception</em>
 	 */
-	/*package-local*/ int fromChangelog(int changesetRevisionIndex) throws HgInvalidRevisionException, HgInvalidControlFileException {
+	/*package-local*/ int fromChangelog(int changesetRevisionIndex) throws HgRuntimeException {
 		if (HgInternals.wrongRevisionIndex(changesetRevisionIndex)) {
 			throw new HgInvalidRevisionException(changesetRevisionIndex);
 		}
@@ -296,9 +299,11 @@
 	 * @param changelogRevisionIndex local changeset index 
 	 * @param file path to file in question
 	 * @return file revision or <code>null</code> if manifest at specified revision doesn't list such file
-	 * @throws HgRuntimeException subclass thereof to indicate issues with the library. <em>Runtime exception</em>
+	 * @throws HgInvalidRevisionException if supplied revision doesn't identify revision from this revlog. <em>Runtime exception</em>
+	 * @throws HgInvalidControlFileException if failed to access revlog index/data entry. <em>Runtime exception</em>
+	 * @throws HgRuntimeException subclass thereof to indicate other issues with the library. <em>Runtime exception</em>
 	 */
-	public Nodeid getFileRevision(int changelogRevisionIndex, final Path file) throws HgInvalidRevisionException, HgInvalidControlFileException {
+	public Nodeid getFileRevision(int changelogRevisionIndex, final Path file) throws HgRuntimeException {
 		// there's no need for HgDataFile to own this method, or get a delegate
 		// as most of HgDataFile API is using file revision indexes, and there's easy step from file revision index to
 		// both file revision and changeset revision index. But there's no easy way to go from changesetRevisionIndex to
@@ -330,7 +335,9 @@
 	 * @param file path of interest
 	 * @param inspector callback to receive details about selected file
 	 * @param changelogRevisionIndexes changeset indexes to visit
-	 * @throws HgRuntimeException subclass thereof to indicate issues with the library. <em>Runtime exception</em>
+	 * @throws HgInvalidRevisionException if supplied revision doesn't identify revision from this revlog. <em>Runtime exception</em>
+	 * @throws HgInvalidControlFileException if failed to access revlog index/data entry. <em>Runtime exception</em>
+	 * @throws HgRuntimeException subclass thereof to indicate other issues with the library. <em>Runtime exception</em>
 	 */
 	public void walkFileRevisions(Path file, Inspector inspector, int... changelogRevisionIndexes) throws HgRuntimeException {
 		if (file == null || inspector == null || changelogRevisionIndexes == null) {
@@ -349,9 +356,11 @@
 	 * @param changesetRevIndex changeset revision index
 	 * @param file path to look up
 	 * @return one of predefined enum values, or <code>null</code> if file was not known in the specified revision
-	 * @throws HgRuntimeException subclass thereof to indicate issues with the library. <em>Runtime exception</em>
+	 * @throws HgInvalidRevisionException if supplied revision doesn't identify revision from this revlog. <em>Runtime exception</em>
+	 * @throws HgInvalidControlFileException if failed to access revlog index/data entry. <em>Runtime exception</em>
+	 * @throws HgRuntimeException subclass thereof to indicate other issues with the library. <em>Runtime exception</em>
 	 */
-	public Flags getFileFlags(int changesetRevIndex, Path file) throws HgInvalidRevisionException, HgInvalidControlFileException {
+	public Flags getFileFlags(int changesetRevIndex, Path file) throws HgRuntimeException {
 		int manifestRevIdx = fromChangelog(changesetRevIndex);
 		IntMap<Flags> resMap = new IntMap<Flags>(2);
 		FileLookupInspector parser = new FileLookupInspector(encodingHelper, file, null, resMap);
@@ -374,11 +383,11 @@
 	/**
 	 * @param changelogRevisionIndexes non-null
 	 * @param inspector may be null if reporting of missing manifests is not needed
-	 * @throws HgInvalidRevisionException if arguments specify non-existent revision index
-	 * @throws IllegalArgumentException if any index argument is not a revision index
-	 * @throws HgInvalidControlFileException if access to revlog index/data entry failed
+	 * @throws HgInvalidRevisionException if supplied revision doesn't identify revision from this revlog. <em>Runtime exception</em>
+	 * @throws HgInvalidControlFileException if failed to access revlog index/data entry. <em>Runtime exception</em>
+	 * @throws HgRuntimeException subclass thereof to indicate other issues with the library. <em>Runtime exception</em>
 	 */
-	private int[] toManifestRevisionIndexes(int[] changelogRevisionIndexes, Inspector inspector) throws HgInvalidRevisionException, HgInvalidControlFileException {
+	private int[] toManifestRevisionIndexes(int[] changelogRevisionIndexes, Inspector inspector) throws HgRuntimeException {
 		int[] manifestRevs = new int[changelogRevisionIndexes.length];
 		boolean needsSort = false;
 		int j = 0;
@@ -421,8 +430,9 @@
 		 * @param manifestRevision revision of the manifest we're about to iterate through
 		 * @param changelogRevisionIndex local revision index of changelog this manifest points to 
 		 * @return <code>true</code> to continue iteration, <code>false</code> to stop
+		 * @throws HgRuntimeException propagates library issues. <em>Runtime exception</em>
 		 */
-		boolean begin(int manifestRevisionIndex, Nodeid manifestRevision, int changelogRevisionIndex);
+		boolean begin(int manifestRevisionIndex, Nodeid manifestRevision, int changelogRevisionIndex) throws HgRuntimeException;
 
 		
 		/**
@@ -432,16 +442,18 @@
 		 * @param fname file name
 		 * @param flags one of {@link HgManifest.Flags} constants, not <code>null</code>
 		 * @return <code>true</code> to continue iteration, <code>false</code> to stop
+		 * @throws HgRuntimeException propagates library issues. <em>Runtime exception</em>
 		 */
-		boolean next(Nodeid nid, Path fname, Flags flags);
+		boolean next(Nodeid nid, Path fname, Flags flags) throws HgRuntimeException;
 
 		/**
 		 * Denotes leaving specific manifest revision, after all entries were reported using {@link #next(Nodeid, Path, Flags)}
 		 *   
 		 * @param manifestRevisionIndex indicates manifest revision, corresponds to opening {@link #begin(int, Nodeid, int)}
 		 * @return <code>true</code> to continue iteration, <code>false</code> to stop
+		 * @throws HgRuntimeException propagates library issues. <em>Runtime exception</em>
 		 */
-		boolean end(int manifestRevisionIndex);
+		boolean end(int manifestRevisionIndex) throws HgRuntimeException;
 	}
 	
 	/**
@@ -531,7 +543,7 @@
 			progressHelper = ProgressSupport.Factory.get(delegate);
 		}
 		
-		public void next(int revisionNumber, int actualLen, int baseRevision, int linkRevision, int parent1Revision, int parent2Revision, byte[] nodeid, DataAccess da) {
+		public void next(int revisionNumber, int actualLen, int baseRevision, int linkRevision, int parent1Revision, int parent2Revision, byte[] nodeid, DataAccess da) throws HgRuntimeException {
 			try {
 				if (!inspector.begin(revisionNumber, new Nodeid(nodeid, true), linkRevision)) {
 					iterateControl.stop();
@@ -623,7 +635,7 @@
 		private int[] changelog2manifest;
 		RevisionLookup manifestNodeids;
 
-		private RevisionMapper(boolean useOwnRevisionLookup) {
+		private RevisionMapper(boolean useOwnRevisionLookup) throws HgRuntimeException {
 			changelogRevisionCount = HgManifest.this.getRepo().getChangelog().getRevisionCount();
 			if (useOwnRevisionLookup) {
 				manifestNodeids = new RevisionLookup(HgManifest.this.content);
@@ -691,7 +703,7 @@
 			// #finish, as the manifest read operation is not complete at the moment.
 		}
 		
-		public void fixReusedManifests() {
+		public void fixReusedManifests() throws HgRuntimeException {
 			if (changelog2manifest == null) {
 				// direct, 1-1 mapping of changeset indexes to manifest
 				return;
@@ -768,15 +780,15 @@
 			csetIndex2Flags = null;
 		}
 		
-		void walk(int manifestRevIndex, RevlogStream content) {
+		void walk(int manifestRevIndex, RevlogStream content) throws HgRuntimeException {
 			content.iterate(manifestRevIndex, manifestRevIndex, true, this); 
 		}
 
-		void walk(int[] manifestRevIndexes, RevlogStream content) {
+		void walk(int[] manifestRevIndexes, RevlogStream content) throws HgRuntimeException {
 			content.iterate(manifestRevIndexes, true, this);
 		}
 		
-		public void next(int revisionNumber, int actualLen, int baseRevision, int linkRevision, int parent1Revision, int parent2Revision, byte[] nodeid, DataAccess data) {
+		public void next(int revisionNumber, int actualLen, int baseRevision, int linkRevision, int parent1Revision, int parent2Revision, byte[] nodeid, DataAccess data) throws HgRuntimeException {
 			ByteVector byteVector = new ByteVector(256, 128); // allocate for long paths right away
 			try {
 				byte b;
--- a/src/org/tmatesoft/hg/repo/HgMergeState.java	Tue May 21 20:17:33 2013 +0200
+++ b/src/org/tmatesoft/hg/repo/HgMergeState.java	Wed May 22 15:52:31 2013 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012 TMate Software Ltd
+ * Copyright (c) 2011-2013 TMate Software Ltd
  *  
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -185,9 +185,7 @@
 	 * @return <code>true</code> when recorded merge state doesn't seem to correspond to present working copy
 	 */
 	public boolean isStale() {
-		if (wcp1 == null) {
-			refresh();
-		}
+		assert wcp1 != null;
 		return !stateParent.isNull() /*there's merge state*/ && !wcp1.equals(stateParent) /*and it doesn't match*/; 
 	}
 
@@ -198,9 +196,7 @@
 	 * @return first parent of the working copy, never <code>null</code>
 	 */
 	public Nodeid getFirstParent() {
-		if (wcp1 == null) {
-			refresh();
-		}
+		assert wcp1 != null;
 		return wcp1;
 	}
 	
@@ -208,9 +204,7 @@
 	 * @return second parent of the working copy, never <code>null</code>
 	 */
 	public Nodeid getSecondParent() {
-		if (wcp2 == null) {
-			refresh();
-		}
+		assert wcp2 != null;
 		return wcp2;
 	}
 	
@@ -218,9 +212,7 @@
 	 * @return revision of the merge state or {@link Nodeid#NULL} if there's no merge state
 	 */
 	public Nodeid getStateParent() {
-		if (stateParent == null) {
-			refresh();
-		}
+		assert stateParent != null;
 		return stateParent;
 	}
 
--- a/src/org/tmatesoft/hg/repo/HgParentChildMap.java	Tue May 21 20:17:33 2013 +0200
+++ b/src/org/tmatesoft/hg/repo/HgParentChildMap.java	Wed May 22 15:52:31 2013 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012 TMate Software Ltd
+ * Copyright (c) 2011-2013 TMate Software Ltd
  *  
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -88,7 +88,12 @@
 		}
 	}
 	
-	public void init() throws HgInvalidControlFileException {
+	/**
+	 * Prepare the map 
+	 * @throws HgInvalidControlFileException if failed to access revlog index/data entry. <em>Runtime exception</em>
+	 * @throws HgRuntimeException subclass thereof to indicate other issues with the library. <em>Runtime exception</em>
+	 */
+	public void init() throws HgRuntimeException {
 		final int revisionCount = revlog.getRevisionCount();
 		firstParent = new Nodeid[revisionCount];
 		// TODO [post 1.0] Branches/merges are less frequent, and most of secondParent would be -1/null, hence 
--- a/src/org/tmatesoft/hg/repo/HgRepository.java	Tue May 21 20:17:33 2013 +0200
+++ b/src/org/tmatesoft/hg/repo/HgRepository.java	Wed May 22 15:52:31 2013 +0200
@@ -27,6 +27,7 @@
 import java.util.Collections;
 import java.util.List;
 
+import org.tmatesoft.hg.core.HgIOException;
 import org.tmatesoft.hg.core.Nodeid;
 import org.tmatesoft.hg.core.SessionContext;
 import org.tmatesoft.hg.internal.ConfigFile;
@@ -195,7 +196,7 @@
 	 * 
 	 * @throws HgRuntimeException subclass thereof to indicate issues with the library. <em>Runtime exception</em>
 	 */
-	public HgTags getTags() throws HgInvalidControlFileException {
+	public HgTags getTags() throws HgRuntimeException {
 		if (tags == null) {
 			tags = new HgTags(impl);
 			tags.read();
@@ -212,7 +213,7 @@
 	 * @return branch manager instance, never <code>null</code>
 	 * @throws HgRuntimeException subclass thereof to indicate issues with the library. <em>Runtime exception</em>
 	 */
-	public HgBranches getBranches() throws HgInvalidControlFileException {
+	public HgBranches getBranches() throws HgRuntimeException {
 		final ProgressSupport ps = ProgressSupport.Factory.get(null);
 		if (branches == null) {
 			branches = new HgBranches(impl);
@@ -226,10 +227,12 @@
 	/**
 	 * Access state of the recent merge
 	 * @return merge state facility, never <code>null</code> 
+	 * @throws HgRuntimeException subclass thereof to indicate issues with the library. <em>Runtime exception</em>
 	 */
-	public HgMergeState getMergeState() {
+	public HgMergeState getMergeState() throws HgRuntimeException {
 		if (mergeState == null) {
 			mergeState = new HgMergeState(impl);
+			mergeState.refresh();
 		}
 		return mergeState;
 	}
@@ -305,7 +308,7 @@
 			try {
 				ConfigFile configFile = impl.readConfiguration();
 				repoConfig = new HgRepoConfig(configFile);
-			} catch (IOException ex) {
+			} catch (HgIOException ex) {
 				String m = "Errors while reading user configuration file";
 				getSessionContext().getLog().dump(getClass(), Warn, ex, m);
 				return new HgRepoConfig(new ConfigFile(getSessionContext())); // empty config, do not cache, allow to try once again
@@ -424,7 +427,7 @@
 	 * @return facility to manage bookmarks, never <code>null</code>
 	 * @throws HgRuntimeException subclass thereof to indicate issues with the library. <em>Runtime exception</em>
 	 */
-	public HgBookmarks getBookmarks() throws HgInvalidControlFileException {
+	public HgBookmarks getBookmarks() throws HgRuntimeException {
 		if (bookmarks == null) {
 			bookmarks = new HgBookmarks(impl);
 			bookmarks.read();
--- a/src/org/tmatesoft/hg/repo/HgRevisionMap.java	Tue May 21 20:17:33 2013 +0200
+++ b/src/org/tmatesoft/hg/repo/HgRevisionMap.java	Wed May 22 15:52:31 2013 +0200
@@ -85,7 +85,7 @@
 	/**
 	 * @return <code>this</code> for convenience.
 	 */
-	public HgRevisionMap<T> init(/*XXX Pool<Nodeid> to reuse nodeids, if possible. */) throws HgInvalidControlFileException{
+	public HgRevisionMap<T> init(/*XXX Pool<Nodeid> to reuse nodeids, if possible. */) throws HgRuntimeException {
 		// XXX HgRepository.register((RepoChangeListener) this); // listen to changes in repo, re-init if needed?
 		final int revisionCount = revlog.getRevisionCount();
 		sequential = new Nodeid[revisionCount];
--- a/src/org/tmatesoft/hg/repo/HgStatusCollector.java	Tue May 21 20:17:33 2013 +0200
+++ b/src/org/tmatesoft/hg/repo/HgStatusCollector.java	Wed May 22 15:52:31 2013 +0200
@@ -73,7 +73,7 @@
 		return repo;
 	}
 	
-	private ManifestRevision get(int rev) throws HgInvalidControlFileException {
+	private ManifestRevision get(int rev) throws HgRuntimeException {
 		ManifestRevision i = cache.get(rev);
 		if (i == null) {
 			if (rev == NO_REVISION) {
@@ -98,7 +98,7 @@
 		}
 	}
 	
-	private void initCacheRange(int minRev, int maxRev) throws HgInvalidControlFileException {
+	private void initCacheRange(int minRev, int maxRev) throws HgRuntimeException {
 		ensureCacheSize();
 		// In fact, walk(minRev, maxRev) doesn't imply
 		// there would be maxRev-minRev+1 revisions visited. For example,
@@ -159,7 +159,7 @@
 	 * @return
 	 * @throws HgInvalidControlFileException
 	 */
-	/*package-local*/ ManifestRevision raw(int rev) throws HgInvalidControlFileException {
+	/*package-local*/ ManifestRevision raw(int rev) throws HgRuntimeException {
 		return get(rev);
 	}
 	/*package-local*/ Convertor<Path> getPathPool() {
@@ -344,9 +344,11 @@
 	 * @param rev1 <em>from</em> changeset index 
 	 * @param rev2 <em>to</em> changeset index
 	 * @return information object that describes change between the revisions
-	 * @throws HgRuntimeException subclass thereof to indicate issues with the library. <em>Runtime exception</em>
+	 * @throws HgInvalidRevisionException if any supplied revision doesn't identify changeset revision. <em>Runtime exception</em>
+	 * @throws HgInvalidControlFileException if failed to access revlog index/data entry. <em>Runtime exception</em>
+	 * @throws HgRuntimeException subclass thereof to indicate other issues with the library. <em>Runtime exception</em>
 	 */
-	public Record status(int rev1, int rev2) throws HgInvalidRevisionException, HgInvalidControlFileException {
+	public Record status(int rev1, int rev2) throws HgRuntimeException {
 		Record rv = new Record();
 		try {
 			walk(rev1, rev2, rv);
@@ -359,7 +361,7 @@
 		return rv;
 	}
 	
-	/*package-local*/static Path getOriginIfCopy(HgRepository hgRepo, Path fname, Collection<Path> originals, int originalChangelogRevision) throws HgInvalidFileException {
+	/*package-local*/static Path getOriginIfCopy(HgRepository hgRepo, Path fname, Collection<Path> originals, int originalChangelogRevision) throws HgRuntimeException {
 		HgDataFile df = hgRepo.getFileNode(fname);
 		if (!df.exists()) {
 			String msg = String.format("Didn't find file '%s' in the repo. Perhaps, bad storage name conversion?", fname);
@@ -417,7 +419,7 @@
 			statusHelper = self;
 		}
 		
-		public Nodeid nodeidBeforeChange(Path fname) throws HgInvalidControlFileException {
+		public Nodeid nodeidBeforeChange(Path fname) throws HgRuntimeException {
 			if (statusHelper == null || startRev == BAD_REVISION) {
 				return null;
 			}
@@ -426,7 +428,7 @@
 			}
 			return statusHelper.raw(startRev).nodeid(fname);
 		}
-		public Nodeid nodeidAfterChange(Path fname) throws HgInvalidControlFileException {
+		public Nodeid nodeidAfterChange(Path fname) throws HgRuntimeException {
 			if (statusHelper == null || endRev == BAD_REVISION) {
 				return null;
 			}
--- a/src/org/tmatesoft/hg/repo/HgTags.java	Tue May 21 20:17:33 2013 +0200
+++ b/src/org/tmatesoft/hg/repo/HgTags.java	Wed May 22 15:52:31 2013 +0200
@@ -74,13 +74,13 @@
 		localFromName  = new TreeMap<String, List<Nodeid>>();
 	}
 	
-	/*package-local*/ void read() throws HgInvalidControlFileException {
+	/*package-local*/ void read() throws HgRuntimeException {
 		readTagsFromHistory();
 		readGlobal();
 		readLocal();
 	}
 	
-	private void readTagsFromHistory() throws HgInvalidControlFileException {
+	private void readTagsFromHistory() throws HgRuntimeException {
 		HgDataFile hgTags = repo.getRepo().getFileNode(HgTags.getPath());
 		if (hgTags.exists()) {
 			for (int i = 0; i <= hgTags.getLastRevision(); i++) { // TODO post-1.0 in fact, would be handy to have walk(start,end) 
@@ -280,7 +280,7 @@
 	}
 
 	// can be called only after instance has been initialized (#read() invoked) 
-	/*package-local*/void reloadIfChanged() throws HgInvalidControlFileException {
+	/*package-local*/void reloadIfChanged() throws HgRuntimeException {
 		assert repoChangeMonitor != null;
 		assert localTagsFileMonitor != null;
 		assert globalTagsFileMonitor != null;
@@ -312,7 +312,13 @@
 			return localFromName.containsKey(name);
 		}
 
-		public String branch() throws HgInvalidControlFileException {
+		/**
+		 * @return name of the branch this tag belongs to, never <code>null</code>
+		 * @throws HgInvalidRevisionException if revision of the tag is not a valid changeset revision. <em>Runtime exception</em>
+		 * @throws HgInvalidControlFileException if failed to access revlog index/data entry. <em>Runtime exception</em>
+		 * @throws HgRuntimeException subclass thereof to indicate other issues with the library. <em>Runtime exception</em>
+		 */
+		public String branch() throws HgRuntimeException {
 			if (branch == null) {
 				int x = repo.getRepo().getChangelog().getRevisionIndex(revision());
 				branch = repo.getRepo().getChangelog().range(x, x).get(0).branch();
--- a/src/org/tmatesoft/hg/repo/HgWorkingCopyStatusCollector.java	Tue May 21 20:17:33 2013 +0200
+++ b/src/org/tmatesoft/hg/repo/HgWorkingCopyStatusCollector.java	Wed May 22 15:52:31 2013 +0200
@@ -34,6 +34,7 @@
 import org.tmatesoft.hg.core.Nodeid;
 import org.tmatesoft.hg.core.SessionContext;
 import org.tmatesoft.hg.internal.ByteArrayChannel;
+import org.tmatesoft.hg.internal.FileUtils;
 import org.tmatesoft.hg.internal.FilterByteChannel;
 import org.tmatesoft.hg.internal.Internals;
 import org.tmatesoft.hg.internal.ManifestRevision;
@@ -130,7 +131,7 @@
 		return dirstate;
 	}
 	
-	private ManifestRevision getManifest(int changelogLocalRev) throws HgInvalidControlFileException {
+	private ManifestRevision getManifest(int changelogLocalRev) throws HgRuntimeException {
 		assert changelogLocalRev >= 0;
 		ManifestRevision mr;
 		if (baseRevisionCollector != null) {
@@ -142,7 +143,7 @@
 		return mr;
 	}
 
-	private void initDirstateParentManifest() throws HgInvalidControlFileException {
+	private void initDirstateParentManifest() throws HgRuntimeException {
 		Nodeid dirstateParent = getDirstateImpl().parents().first();
 		if (dirstateParent.isNull()) {
 			dirstateParentManifest = baseRevisionCollector != null ? baseRevisionCollector.raw(NO_REVISION) : HgStatusCollector.createEmptyManifestRevision();
@@ -407,7 +408,7 @@
 	}
 	
 	// XXX refactor checkLocalStatus methods in more OO way
-	private void checkLocalStatusAgainstBaseRevision(Set<Path> baseRevNames, ManifestRevision collect, int baseRevision, Path fname, FileInfo f, HgStatusInspector inspector) {
+	private void checkLocalStatusAgainstBaseRevision(Set<Path> baseRevNames, ManifestRevision collect, int baseRevision, Path fname, FileInfo f, HgStatusInspector inspector) throws HgRuntimeException {
 		// fname is in the dirstate, either Normal, Added, Removed or Merged
 		Nodeid nid1 = collect.nodeid(fname);
 		HgManifest.Flags flags = collect.flags(fname);
@@ -501,7 +502,7 @@
 		// The question is whether original Hg treats this case (same content, different parents and hence nodeids) as 'modified' or 'clean'
 	}
 
-	private boolean areTheSame(FileInfo f, HgDataFile dataFile, Nodeid revision) throws HgInvalidFileException {
+	private boolean areTheSame(FileInfo f, HgDataFile dataFile, Nodeid revision) throws HgRuntimeException {
 		// XXX consider adding HgDataDile.compare(File/byte[]/whatever) operation to optimize comparison
 		ByteArrayChannel bac = new ByteArrayChannel();
 		try {
@@ -588,13 +589,7 @@
 		} catch (IOException ex) {
 			throw new HgInvalidFileException("File comparison failed", ex).setFileName(p);
 		} finally {
-			if (is != null) {
-				try {
-					is.close();
-				} catch (IOException ex) {
-					repo.getSessionContext().getLog().dump(getClass(), Info, ex, null);
-				}
-			}
+			new FileUtils(repo.getSessionContext().getLog()).closeQuietly(is);
 		}
 	}
 
--- a/src/org/tmatesoft/hg/repo/Revlog.java	Tue May 21 20:17:33 2013 +0200
+++ b/src/org/tmatesoft/hg/repo/Revlog.java	Wed May 22 15:52:31 2013 +0200
@@ -94,7 +94,8 @@
 
 	/**
 	 * @return total number of revisions kept in this revlog
-	 * @throws HgRuntimeException subclass thereof to indicate issues with the library. <em>Runtime exception</em>
+	 * @throws HgInvalidControlFileException if failed to access revlog index/data entry. <em>Runtime exception</em>
+	 * @throws HgRuntimeException subclass thereof to indicate other issues with the library. <em>Runtime exception</em>
 	 */
 	public final int getRevisionCount() throws HgRuntimeException {
 		return content.revisionCount();
@@ -102,7 +103,8 @@
 	
 	/**
 	 * @return index of last known revision, a.k.a. {@link HgRepository#TIP}, or {@link HgRepository#NO_REVISION} if revlog is empty
-	 * @throws HgRuntimeException subclass thereof to indicate issues with the library. <em>Runtime exception</em>
+	 * @throws HgInvalidControlFileException if failed to access revlog index/data entry. <em>Runtime exception</em>
+	 * @throws HgRuntimeException subclass thereof to indicate other issues with the library. <em>Runtime exception</em>
 	 */
 	public final int getLastRevision() throws HgRuntimeException {
 		// although old code gives correct result when revlog is empty (NO_REVISION deliberately == -1), 
@@ -117,7 +119,9 @@
 	 * @param revisionIndex index of the entry in this revlog, may be {@link HgRepository#TIP}
 	 * @return revision nodeid of the entry
 	 * 
-	 * @throws HgRuntimeException subclass thereof to indicate issues with the library. <em>Runtime exception</em>
+	 * @throws HgInvalidRevisionException if any supplied revision doesn't identify revision from this revlog. <em>Runtime exception</em>
+	 * @throws HgInvalidControlFileException if failed to access revlog index/data entry. <em>Runtime exception</em>
+	 * @throws HgRuntimeException subclass thereof to indicate other issues with the library. <em>Runtime exception</em>
 	 */
 	public final Nodeid getRevision(int revisionIndex) throws HgRuntimeException {
 		// XXX cache nodeids? Rather, if context.getCache(this).getRevisionMap(create == false) != null, use it
@@ -130,7 +134,9 @@
 	 * <li>ordering of the revisions in the return list is unspecified, it's likely won't match that of the method argument
 	 * <li>supplied array get modified (sorted)</ul>
 	 * @return list of mapped revisions in no particular order
-	 * @throws HgRuntimeException subclass thereof to indicate issues with the library. <em>Runtime exception</em>
+	 * @throws HgInvalidRevisionException if any supplied revision doesn't identify revision from this revlog. <em>Runtime exception</em>
+	 * @throws HgInvalidControlFileException if failed to access revlog index/data entry. <em>Runtime exception</em>
+	 * @throws HgRuntimeException subclass thereof to indicate other issues with the library. <em>Runtime exception</em>
 	 */
 	public final List<Nodeid> getRevisions(int... revisions) throws HgRuntimeException {
 		ArrayList<Nodeid> rv = new ArrayList<Nodeid>(revisions.length);
@@ -139,7 +145,7 @@
 		return rv;
 	}
 	
-	/*package-local*/ void getRevisionsInternal(final List<Nodeid> retVal, int[] sortedRevs) throws HgInvalidRevisionException, HgInvalidControlFileException {
+	/*package-local*/ void getRevisionsInternal(final List<Nodeid> retVal, int[] sortedRevs) throws HgRuntimeException {
 		// once I have getRevisionMap and may find out whether it is avalable from cache,
 		// may use it, perhaps only for small number of revisions
 		content.iterate(sortedRevs, false, new RevlogStream.Inspector() {
@@ -159,7 +165,9 @@
 	 * 
 	 * @param nid revision to look up 
 	 * @return revision local index in this revlog
-	 * @throws HgRuntimeException subclass thereof to indicate issues with the library. <em>Runtime exception</em>
+	 * @throws HgInvalidRevisionException if revision was not found in this revlog. <em>Runtime exception</em>
+	 * @throws HgInvalidControlFileException if failed to access revlog index/data entry. <em>Runtime exception</em>
+	 * @throws HgRuntimeException subclass thereof to indicate other issues with the library. <em>Runtime exception</em>
 	 */
 	public final int getRevisionIndex(Nodeid nid) throws HgRuntimeException {
 		final int revision = doFindWithCache(nid);
@@ -172,7 +180,7 @@
 		return revision;
 	}
 	
-	private int doFindWithCache(Nodeid nid) {
+	private int doFindWithCache(Nodeid nid) throws HgRuntimeException {
 		if (useRevisionLookup) {
 			if (revisionLookup == null || content.shallDropDerivedCaches()) {
 				content.detach(revisionLookupCleaner);
@@ -199,7 +207,8 @@
 	 * 
 	 * @param nodeid
 	 * @return <code>true</code> if revision is part of this revlog
-	 * @throws HgRuntimeException subclass thereof to indicate issues with the library. <em>Runtime exception</em>
+	 * @throws HgInvalidControlFileException if failed to access revlog index/data entry. <em>Runtime exception</em>
+	 * @throws HgRuntimeException subclass thereof to indicate other issues with the library. <em>Runtime exception</em>
 	 */
 	public final boolean isKnown(Nodeid nodeid) throws HgRuntimeException {
 		final int rn = doFindWithCache(nodeid);
@@ -219,13 +228,14 @@
 	 * @param nodeid revision to retrieve
 	 * @param sink data destination
 	 * 
-	 * @throws HgInvalidRevisionException if supplied argument doesn't represent revision index in this revlog
-	 * @throws HgInvalidControlFileException if access to revlog index/data entry failed
+	 * @see #rawContent(int, ByteChannel)
+	 * 
 	 * @throws CancelledException if content retrieval operation was cancelled
-	 * 
-	 * @see #rawContent(int, ByteChannel)
+	 * @throws HgInvalidRevisionException if supplied argument doesn't represent revision index in this revlog. <em>Runtime exception</em>
+	 * @throws HgInvalidControlFileException if failed to access revlog index/data entry. <em>Runtime exception</em>
+	 * @throws HgRuntimeException subclass thereof to indicate other issues with the library. <em>Runtime exception</em>
 	 */
-	protected void rawContent(Nodeid nodeid, ByteChannel sink) throws HgInvalidControlFileException, CancelledException, HgInvalidRevisionException {
+	protected void rawContent(Nodeid nodeid, ByteChannel sink) throws CancelledException, HgRuntimeException {
 		rawContent(getRevisionIndex(nodeid), sink);
 	}
 	
@@ -235,11 +245,12 @@
 	 * @param revisionIndex index of this revlog change (not a changelog revision index), non-negative. From predefined constants, only {@link HgRepository#TIP} makes sense.
 	 * @param sink data destination
 	 * 
-	 * @throws HgInvalidRevisionException if supplied argument doesn't represent revision index in this revlog
-	 * @throws HgInvalidControlFileException if access to revlog index/data entry failed
 	 * @throws CancelledException if content retrieval operation was cancelled
+	 * @throws HgInvalidRevisionException if supplied argument doesn't represent revision index in this revlog. <em>Runtime exception</em>
+	 * @throws HgInvalidControlFileException if failed to access revlog index/data entry. <em>Runtime exception</em>
+	 * @throws HgRuntimeException subclass thereof to indicate other issues with the library. <em>Runtime exception</em>
 	 */
-	protected void rawContent(int revisionIndex, ByteChannel sink) throws HgInvalidControlFileException, CancelledException, HgInvalidRevisionException {
+	protected void rawContent(int revisionIndex, ByteChannel sink) throws CancelledException, HgRuntimeException {
 		if (sink == null) {
 			throw new IllegalArgumentException();
 		}
@@ -348,7 +359,7 @@
 		content.iterate(_start, end, false, new RevlogStream.Inspector() {
 			private int i = 0;
 			
-			public void next(int revisionIndex, int actualLen, int baseRevIndex, int linkRevIndex, int parent1RevIndex, int parent2RevIndex, byte[] nodeid, DataAccess data) {
+			public void next(int revisionIndex, int actualLen, int baseRevIndex, int linkRevIndex, int parent1RevIndex, int parent2RevIndex, byte[] nodeid, DataAccess data) throws HgRuntimeException {
 				Nodeid nid = Nodeid.fromBinary(nodeid, 0);
 				if (revisionInsp != null) {
 					revisionInsp.next(revisionIndex, nid, linkRevIndex);
@@ -417,16 +428,16 @@
 
 	@Experimental
 	public interface RevisionInspector extends Inspector {
-		void next(int revisionIndex, Nodeid revision, int linkedRevisionIndex);
+		void next(int revisionIndex, Nodeid revision, int linkedRevisionIndex) throws HgRuntimeException;
 	}
 
 	@Experimental
 	public interface ParentInspector extends Inspector {
 		// XXX document whether parentX is -1 or a constant (BAD_REVISION? or dedicated?)
-		void next(int revisionIndex, Nodeid revision, int parent1, int parent2, Nodeid nidParent1, Nodeid nidParent2);
+		void next(int revisionIndex, Nodeid revision, int parent1, int parent2, Nodeid nidParent1, Nodeid nidParent2) throws HgRuntimeException;
 	}
 	
-	protected HgParentChildMap<? extends Revlog> getParentWalker() {
+	protected HgParentChildMap<? extends Revlog> getParentWalker() throws HgRuntimeException {
 		HgParentChildMap<Revlog> pw = new HgParentChildMap<Revlog>(this);
 		pw.init();
 		return pw;
--- a/src/org/tmatesoft/hg/repo/ext/MqManager.java	Tue May 21 20:17:33 2013 +0200
+++ b/src/org/tmatesoft/hg/repo/ext/MqManager.java	Wed May 22 15:52:31 2013 +0200
@@ -27,11 +27,11 @@
 import java.util.List;
 import java.util.Map;
 
+import org.tmatesoft.hg.core.HgIOException;
 import org.tmatesoft.hg.core.Nodeid;
 import org.tmatesoft.hg.internal.Internals;
 import org.tmatesoft.hg.internal.LineReader;
 import org.tmatesoft.hg.repo.HgInvalidControlFileException;
-import org.tmatesoft.hg.repo.HgInvalidFileException;
 import org.tmatesoft.hg.util.LogFacility;
 import org.tmatesoft.hg.util.Path;
 
@@ -136,10 +136,8 @@
 					allKnown.add(pr);
 				}
 			}
-		} catch (HgInvalidFileException ex) {
-			HgInvalidControlFileException th = new HgInvalidControlFileException(ex.getMessage(), ex.getCause(), ex.getFile());
-			th.setStackTrace(ex.getStackTrace());
-			throw th;
+		} catch (HgIOException ex) {
+			throw new HgInvalidControlFileException(ex, true);
 		}
 		return this;
 	}
--- a/src/org/tmatesoft/hg/repo/ext/Rebase.java	Tue May 21 20:17:33 2013 +0200
+++ b/src/org/tmatesoft/hg/repo/ext/Rebase.java	Wed May 22 15:52:31 2013 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 TMate Software Ltd
+ * Copyright (c) 2012-2013 TMate Software Ltd
  *  
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -28,7 +28,6 @@
 import org.tmatesoft.hg.core.Nodeid;
 import org.tmatesoft.hg.internal.Internals;
 import org.tmatesoft.hg.internal.LineReader;
-import org.tmatesoft.hg.repo.HgInvalidFileException;
 import org.tmatesoft.hg.repo.HgInvalidStateException;
 
 /**
@@ -94,8 +93,6 @@
 			throw new HgIOException("Bad format of rebase state file", f);
 		} catch (HgBadNodeidFormatException ex) {
 			throw new HgIOException("Bad format of rebase state file", ex, f);
-		} catch (HgInvalidFileException ex) {
-			throw new HgIOException("Bad format of rebase state file", ex, f);
 		}
 		return this;
 	}
--- a/test/org/tmatesoft/hg/test/MapTagsToFileRevisions.java	Tue May 21 20:17:33 2013 +0200
+++ b/test/org/tmatesoft/hg/test/MapTagsToFileRevisions.java	Wed May 22 15:52:31 2013 +0200
@@ -26,6 +26,7 @@
 import org.tmatesoft.hg.repo.HgManifest;
 import org.tmatesoft.hg.repo.HgManifest.Flags;
 import org.tmatesoft.hg.repo.HgRepository;
+import org.tmatesoft.hg.repo.HgRuntimeException;
 import org.tmatesoft.hg.repo.HgTags;
 import org.tmatesoft.hg.repo.HgTags.TagInfo;
 import org.tmatesoft.hg.repo.HgRevisionMap;
@@ -160,7 +161,7 @@
 			final Map<Nodeid, Nodeid> changesetToNodeid_3 = new HashMap<Nodeid, Nodeid>();
 			fileNode.indexWalk(0, TIP, new HgDataFile.RevisionInspector() {
 	
-				public void next(int fileRevisionIndex, Nodeid revision, int linkedRevisionIndex) {
+				public void next(int fileRevisionIndex, Nodeid revision, int linkedRevisionIndex) throws HgRuntimeException {
 					changesetToNodeid_3.put(clog.getRevision(linkedRevisionIndex), revision);
 				}
 			});
@@ -273,7 +274,7 @@
 		return tagLocalRevs;
 	}
 
-	public void collectTagsPerFile() throws HgException, CancelledException {
+	public void collectTagsPerFile() throws HgException, CancelledException, HgRuntimeException {
 		final long start = System.currentTimeMillis();
 		final HgRepository repository = new HgLookup().detect(new File("/home/artem/hg/cpython"));
 		final HgTags tags = repository.getTags();
@@ -301,7 +302,7 @@
 		
 	// Approach 1. Build map with all files, their revisions and corresponding tags
 	//
-	private void collectTagsPerFile_Approach_1(final HgRevisionMap<HgChangelog> clogrmap, final int[] tagLocalRevs, final TagInfo[] allTags, Path targetPath) throws HgException {
+	private void collectTagsPerFile_Approach_1(final HgRevisionMap<HgChangelog> clogrmap, final int[] tagLocalRevs, final TagInfo[] allTags, Path targetPath) throws HgException, IllegalArgumentException, HgRuntimeException {
 		HgRepository repository = clogrmap.getRepo();
 		final long start = System.currentTimeMillis();
 		// file2rev2tag value is array of revisions, always of allTags.length. Revision index in the array
@@ -373,7 +374,7 @@
 		}
 	}
 	
-	private void collectTagsPerFile_Approach_2(HgRepository repository, final int[] tagLocalRevs, final IntMap<List<TagInfo>> tagRevIndex2TagInfo, Path targetPath) throws HgException {
+	private void collectTagsPerFile_Approach_2(HgRepository repository, final int[] tagLocalRevs, final IntMap<List<TagInfo>> tagRevIndex2TagInfo, Path targetPath) throws HgException, HgRuntimeException {
 		//
 		// Approach 2. No all-file map. Collect file revisions recorded at the time of tagging,
 		// then for each file revision check if it is among those above, and if yes, take corresponding tags
@@ -457,7 +458,7 @@
 		}
 	}
 	
-	public static void main2(String[] args) throws HgCallbackTargetException, HgException, CancelledException {
+	public static void main2(String[] args) throws HgCallbackTargetException, HgException, CancelledException, HgRuntimeException {
 		final HgRepository repository = new HgLookup().detect(new File("/temp/hg/cpython"));
 		final Path targetPath = Path.create("README");
 		final HgTags tags = repository.getTags();
--- a/test/org/tmatesoft/hg/test/TestAuxUtilities.java	Tue May 21 20:17:33 2013 +0200
+++ b/test/org/tmatesoft/hg/test/TestAuxUtilities.java	Wed May 22 15:52:31 2013 +0200
@@ -41,6 +41,7 @@
 import org.tmatesoft.hg.repo.HgManifest;
 import org.tmatesoft.hg.repo.HgManifest.Flags;
 import org.tmatesoft.hg.repo.HgRepository;
+import org.tmatesoft.hg.repo.HgRuntimeException;
 import org.tmatesoft.hg.util.Adaptable;
 import org.tmatesoft.hg.util.ByteChannel;
 import org.tmatesoft.hg.util.CancelSupport;
@@ -285,7 +286,7 @@
 		fileNode.indexWalk(0, TIP, new HgDataFile.RevisionInspector() {
 			int i = 0;
 
-			public void next(int localRevision, Nodeid revision, int linkedRevision) {
+			public void next(int localRevision, Nodeid revision, int linkedRevision) throws HgRuntimeException {
 				assertEquals(i++, localRevision);
 				assertEquals(fileNode.getChangesetRevisionIndex(localRevision), linkedRevision);
 				assertEquals(fileNode.getRevision(localRevision), revision);
--- a/test/org/tmatesoft/hg/test/TestBlame.java	Tue May 21 20:17:33 2013 +0200
+++ b/test/org/tmatesoft/hg/test/TestBlame.java	Wed May 22 15:52:31 2013 +0200
@@ -277,7 +277,7 @@
 			//
 			String[] apiResult = splitLines(bos.toString());
 			String[] expected = splitLines(gp.result());
-			Assert.assertArrayEquals(expected, apiResult);
+			Assert.assertArrayEquals("diff -r " + cs + " - r 8", expected, apiResult);
 			gp.reset();
 		}
 	}
--- a/test/org/tmatesoft/hg/test/TestCommit.java	Tue May 21 20:17:33 2013 +0200
+++ b/test/org/tmatesoft/hg/test/TestCommit.java	Wed May 22 15:52:31 2013 +0200
@@ -37,9 +37,8 @@
 import org.tmatesoft.hg.internal.ByteArrayChannel;
 import org.tmatesoft.hg.internal.COWTransaction;
 import org.tmatesoft.hg.internal.CommitFacility;
+import org.tmatesoft.hg.internal.DataSerializer.ByteArrayDataSource;
 import org.tmatesoft.hg.internal.DirstateReader;
-import org.tmatesoft.hg.internal.DataSerializer.ByteArrayDataSource;
-import org.tmatesoft.hg.internal.FileChangeMonitor;
 import org.tmatesoft.hg.internal.FileContentSupplier;
 import org.tmatesoft.hg.internal.Internals;
 import org.tmatesoft.hg.internal.Transaction;
--- a/test/org/tmatesoft/hg/test/TestFileFlags.java	Tue May 21 20:17:33 2013 +0200
+++ b/test/org/tmatesoft/hg/test/TestFileFlags.java	Wed May 22 15:52:31 2013 +0200
@@ -30,6 +30,7 @@
 import org.tmatesoft.hg.repo.HgDataFile;
 import org.tmatesoft.hg.repo.HgManifest.Flags;
 import org.tmatesoft.hg.repo.HgRepository;
+import org.tmatesoft.hg.repo.HgRuntimeException;
 import org.tmatesoft.hg.util.FileInfo;
 import org.tmatesoft.hg.util.FileWalker;
 import org.tmatesoft.hg.util.Path;
@@ -52,7 +53,7 @@
 	private HgRepository repo;
 	
 	@Test
-	public void testFlagsInManifest() {
+	public void testFlagsInManifest() throws HgRuntimeException {
 		HgDataFile link = repo.getFileNode("file-link");
 		HgDataFile exec = repo.getFileNode("file-exec");
 		HgDataFile file = repo.getFileNode("regular-file");
--- a/test/org/tmatesoft/hg/test/TestHistory.java	Tue May 21 20:17:33 2013 +0200
+++ b/test/org/tmatesoft/hg/test/TestHistory.java	Wed May 22 15:52:31 2013 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012 TMate Software Ltd
+ * Copyright (c) 2011-2013 TMate Software Ltd
  *  
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -45,6 +45,7 @@
 import org.tmatesoft.hg.internal.AdapterPlug;
 import org.tmatesoft.hg.repo.HgLookup;
 import org.tmatesoft.hg.repo.HgRepository;
+import org.tmatesoft.hg.repo.HgRuntimeException;
 import org.tmatesoft.hg.test.LogOutputParser.Record;
 import org.tmatesoft.hg.util.Adaptable;
 import org.tmatesoft.hg.util.CancelSupport;
@@ -626,7 +627,7 @@
 		}
 		
 
-		public void treeElement(TreeElement entry) throws HgCallbackTargetException {
+		public void treeElement(TreeElement entry) throws HgCallbackTargetException, HgRuntimeException {
 			// check consistency
 			Nodeid cset = entry.changeset().getNodeid();
 			errorCollector.assertEquals(entry.changesetRevision(), cset);
--- a/test/org/tmatesoft/hg/test/TestPhases.java	Tue May 21 20:17:33 2013 +0200
+++ b/test/org/tmatesoft/hg/test/TestPhases.java	Wed May 22 15:52:31 2013 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 TMate Software Ltd
+ * Copyright (c) 2012-2013 TMate Software Ltd
  *  
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -30,6 +30,7 @@
 import org.tmatesoft.hg.repo.HgParentChildMap;
 import org.tmatesoft.hg.repo.HgPhase;
 import org.tmatesoft.hg.repo.HgRepository;
+import org.tmatesoft.hg.repo.HgRuntimeException;
 
 /**
  * {hg4j.tests.repos}/test-phases/
@@ -67,7 +68,7 @@
 		System.out.printf("With ParentWalker(simulates log command for whole repo): %,d μs (pw init: %,d ns)\n", (end - start1)/1000, start2 - start1);
 	}
 
-	private HgPhase[] initAndCheck(PhasesHelper ph, HgPhase[] expected) {
+	private HgPhase[] initAndCheck(PhasesHelper ph, HgPhase[] expected) throws HgRuntimeException {
 		HgChangelog clog = ph.getRepo().getChangelog();
 		HgPhase[] result = new HgPhase[clog.getRevisionCount()];
 		for (int i = 0, l = clog.getLastRevision(); i <= l; i++) {
--- a/test/org/tmatesoft/hg/test/TestRevlog.java	Tue May 21 20:17:33 2013 +0200
+++ b/test/org/tmatesoft/hg/test/TestRevlog.java	Wed May 22 15:52:31 2013 +0200
@@ -33,6 +33,7 @@
 import org.tmatesoft.hg.repo.HgManifest;
 import org.tmatesoft.hg.repo.HgManifest.Flags;
 import org.tmatesoft.hg.repo.HgRepository;
+import org.tmatesoft.hg.repo.HgRuntimeException;
 import org.tmatesoft.hg.util.Path;
 
 /**
@@ -187,7 +188,7 @@
 		return patch1;
 	}
 	
-	private byte[] getRevisionTrueContent(File repoLoc, final int manifestRev, int clogRev) throws HgRepositoryNotFoundException {
+	private byte[] getRevisionTrueContent(File repoLoc, final int manifestRev, int clogRev) throws HgRepositoryNotFoundException, IllegalArgumentException, HgRuntimeException {
 		HgRepository hgRepo = new HgLookup().detect(repoLoc);
 		final ByteArrayOutputStream out = new ByteArrayOutputStream(1024 * 1000);
 		hgRepo.getManifest().walk(clogRev, clogRev, new HgManifest.Inspector() {