<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array"/>
  <modified type="array">
    <modified>
      <diff>@@ -1,4 +1,4 @@
-Netbeans Git Module
-===================
-
-Please see README.markdown.
+Netbeans Git Module
+===================
+
+Please see README.markdown.</diff>
      <filename>README</filename>
    </modified>
    <modified>
      <diff>@@ -1,17 +1,17 @@
-&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
-&lt;!-- You may freely edit this file. See harness/README in the NetBeans platform --&gt;
-&lt;!-- for some information on what you could do (e.g. targets to override). --&gt;
-&lt;!-- If you delete this file and reopen the project it will be recreated. --&gt;
-&lt;project name=&quot;org.nbgit&quot; default=&quot;netbeans&quot; basedir=&quot;.&quot;&gt;
-    &lt;description&gt;Builds, tests, and runs the project org.nbgit.&lt;/description&gt;
-    &lt;import file=&quot;nbproject/build-impl.xml&quot;/&gt;
-    &lt;target name=&quot;netbeans-extra&quot; depends=&quot;init&quot;&gt;
-        &lt;mkdir dir=&quot;${cluster}/modules/ext&quot;/&gt;
-        &lt;copy todir=&quot;${cluster}/modules/ext&quot;&gt;
-            &lt;fileset dir=&quot;release/modules/ext&quot;&gt;
-                &lt;include name=&quot;com-jcraft-jsch.jar&quot;/&gt;
-                &lt;include name=&quot;org-spearce-jgit.jar&quot;/&gt;
-            &lt;/fileset&gt;
-        &lt;/copy&gt;
-    &lt;/target&gt;
-&lt;/project&gt;
+&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
+&lt;!-- You may freely edit this file. See harness/README in the NetBeans platform --&gt;
+&lt;!-- for some information on what you could do (e.g. targets to override). --&gt;
+&lt;!-- If you delete this file and reopen the project it will be recreated. --&gt;
+&lt;project name=&quot;org.nbgit&quot; default=&quot;netbeans&quot; basedir=&quot;.&quot;&gt;
+    &lt;description&gt;Builds, tests, and runs the project org.nbgit.&lt;/description&gt;
+    &lt;import file=&quot;nbproject/build-impl.xml&quot;/&gt;
+    &lt;target name=&quot;netbeans-extra&quot; depends=&quot;init&quot;&gt;
+        &lt;mkdir dir=&quot;${cluster}/modules/ext&quot;/&gt;
+        &lt;copy todir=&quot;${cluster}/modules/ext&quot;&gt;
+            &lt;fileset dir=&quot;release/modules/ext&quot;&gt;
+                &lt;include name=&quot;com-jcraft-jsch.jar&quot;/&gt;
+                &lt;include name=&quot;org-spearce-jgit.jar&quot;/&gt;
+            &lt;/fileset&gt;
+        &lt;/copy&gt;
+    &lt;/target&gt;
+&lt;/project&gt;</diff>
      <filename>build.xml</filename>
    </modified>
    <modified>
      <diff>@@ -1,90 +1,90 @@
-&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.01 Transitional//EN&quot;&gt;
-&lt;html&gt;
-	&lt;head&gt;
-		&lt;title&gt;About Git&lt;/title&gt;
-		&lt;link rel=&quot;stylesheet&quot; href=&quot;nbdocs:/org/netbeans/modules/usersguide/ide.css&quot; type=&quot;text/css&quot;&gt;
-		&lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=UTF-8&quot;&gt;
-	&lt;/head&gt;
-	&lt;body&gt;
-		&lt;h1&gt;About Git&lt;/h1&gt;
-		&lt;p&gt;
-			Git is an open source version control system designed to
-			scale from small to very large projects in terms of speed and
-			efficiency. Git falls in the category of distributed source
-			code management tools which means that a Git repository
-			is a full-fledged copy with complete history and full
-			revision tracking capabilities, not dependent on network
-			access or a central server. Still, Git stays extremely
-			fast and space efficient.
-		&lt;/p&gt;
-		
-		&lt;h3&gt;About NbGit&lt;/h3&gt;
-		&lt;p&gt;
-			NbGit is a Netbeans plugin that adds support for working
-			with the Git version control system. It uses the JGit
-			library to interact with the Git repository.
-		&lt;/p&gt;
-		
-		&lt;h3&gt;Licensing&lt;/h3&gt;
-		&lt;p&gt;
-			The code of the module itself is dual licensed under the
-			the Common Development and Distribution License(&quot;CDDL&quot;)
-			and the GNU General Public License Version 2 only (&quot;GPL&quot;)
-			with the &quot;Classpath&quot; exception. The module and the
-			installable Netbeans module (the &quot;.nbm&quot; file) is distributed
-			with &lt;a href=&quot;nbdocs:/org/nbgit/docs/credits.html&quot;&gt;
-			several third-party components&lt;/a&gt; (.jar files, icons,
-			etc.) which have different licensing than the NbGit code.
-		&lt;/p&gt;
-		
-		&lt;h3&gt;Status&lt;/h3&gt;
-		&lt;p&gt;
-			This module is still under development and thus
-			may randomly crash, eat all your memory, etc. Be sure to check
-			&lt;a href=&quot;nbdocs:/org/nbgit/docs/news.html&quot;&gt;the release
-			notes&lt;/a&gt; and &lt;a href=&quot;nbdocs:/org/nbgit/docs/issues.html&quot;&gt;
-			the known issues&lt;/a&gt; before installing and upgrading.
-		&lt;/p&gt;
-		
-		&lt;h3&gt;More About Git&lt;/h3&gt;
-		&lt;p&gt;
-			For more information about Git and this plugin visit
-			the following sites:
-		&lt;/p&gt;
-		&lt;ul&gt;
-			&lt;li&gt;NbGit Project Page:&lt;br/&gt;
-				&lt;object classid=&quot;java:org.netbeans.modules.javahelp.BrowserDisplayer&quot;&gt;
-					&lt;param name=&quot;content&quot; value=&quot;http://nbgit.googlecode.com/&quot;&gt;
-					&lt;param name=&quot;text&quot; value=&quot;&lt;html&gt;&lt;u&gt;http://nbgit.googlecode.com/&lt;/u&gt;&lt;/html&gt;&quot;&gt;
-					&lt;param name=&quot;textFontSize&quot; value=&quot;medium&quot;&gt;
-					&lt;param name=&quot;textColor&quot; value=&quot;blue&quot;&gt;
-				&lt;/object&gt;
-			&lt;/li&gt;
-			&lt;li&gt;NbGit GitWeb Page:&lt;br/&gt;
-				&lt;object classid=&quot;java:org.netbeans.modules.javahelp.BrowserDisplayer&quot;&gt;
-					&lt;param name=&quot;content&quot; value=&quot;http://repo.or.cz/w/nbgit.git&quot;&gt;
-					&lt;param name=&quot;text&quot; value=&quot;&lt;html&gt;&lt;u&gt;http://repo.or.cz/w/nbgit.git&lt;/u&gt;&lt;/html&gt;&quot;&gt;
-					&lt;param name=&quot;textFontSize&quot; value=&quot;medium&quot;&gt;
-					&lt;param name=&quot;textColor&quot; value=&quot;blue&quot;&gt;
-				&lt;/object&gt;
-			&lt;/li&gt;
-			&lt;li&gt;Git Homepage:&lt;br/&gt;
-				&lt;object classid=&quot;java:org.netbeans.modules.javahelp.BrowserDisplayer&quot;&gt;
-					&lt;param name=&quot;content&quot; value=&quot;http://www.git-scm.org/&quot;&gt;
-					&lt;param name=&quot;text&quot; value=&quot;&lt;html&gt;&lt;u&gt;http://git-scm.org/&lt;/u&gt;&lt;/html&gt;&quot;&gt;
-					&lt;param name=&quot;textFontSize&quot; value=&quot;medium&quot;&gt;
-					&lt;param name=&quot;textColor&quot; value=&quot;blue&quot;&gt;
-				&lt;/object&gt;
-			&lt;/li&gt;
-			&lt;li&gt;Git Wiki:&lt;br/&gt;
-				&lt;object classid=&quot;java:org.netbeans.modules.javahelp.BrowserDisplayer&quot;&gt;
-					&lt;param name=&quot;content&quot; value=&quot;http://www.git-scm.org/gitwiki/&quot;&gt;
-					&lt;param name=&quot;text&quot; value=&quot;&lt;html&gt;&lt;u&gt;http://git-scm.org/gitwiki/&lt;/u&gt;&lt;/html&gt;&quot;&gt;
-					&lt;param name=&quot;textFontSize&quot; value=&quot;medium&quot;&gt;
-					&lt;param name=&quot;textColor&quot; value=&quot;blue&quot;&gt;
-				&lt;/object&gt;
-			&lt;/li&gt;
-		&lt;/ul&gt;
-		
-	&lt;/body&gt;
-&lt;/html&gt;
\ No newline at end of file
+&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.01 Transitional//EN&quot;&gt;
+&lt;html&gt;
+ &lt;head&gt;
+  &lt;title&gt;About Git&lt;/title&gt;
+  &lt;link rel=&quot;stylesheet&quot; href=&quot;nbdocs:/org/netbeans/modules/usersguide/ide.css&quot; type=&quot;text/css&quot;&gt;
+  &lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=UTF-8&quot;&gt;
+ &lt;/head&gt;
+ &lt;body&gt;
+  &lt;h1&gt;About Git&lt;/h1&gt;
+  &lt;p&gt;
+   Git is an open source version control system designed to
+   scale from small to very large projects in terms of speed and
+   efficiency. Git falls in the category of distributed source
+   code management tools which means that a Git repository
+   is a full-fledged copy with complete history and full
+   revision tracking capabilities, not dependent on network
+   access or a central server. Still, Git stays extremely
+   fast and space efficient.
+  &lt;/p&gt;
+
+  &lt;h3&gt;About NbGit&lt;/h3&gt;
+  &lt;p&gt;
+   NbGit is a Netbeans plugin that adds support for working
+   with the Git version control system. It uses the JGit
+   library to interact with the Git repository.
+  &lt;/p&gt;
+
+  &lt;h3&gt;Licensing&lt;/h3&gt;
+  &lt;p&gt;
+   The code of the module itself is dual licensed under the
+   the Common Development and Distribution License(&quot;CDDL&quot;)
+   and the GNU General Public License Version 2 only (&quot;GPL&quot;)
+   with the &quot;Classpath&quot; exception. The module and the
+   installable Netbeans module (the &quot;.nbm&quot; file) is distributed
+   with &lt;a href=&quot;nbdocs:/org/nbgit/docs/credits.html&quot;&gt;
+   several third-party components&lt;/a&gt; (.jar files, icons,
+   etc.) which have different licensing than the NbGit code.
+  &lt;/p&gt;
+
+  &lt;h3&gt;Status&lt;/h3&gt;
+  &lt;p&gt;
+   This module is still under development and thus
+   may randomly crash, eat all your memory, etc. Be sure to check
+   &lt;a href=&quot;nbdocs:/org/nbgit/docs/news.html&quot;&gt;the release
+   notes&lt;/a&gt; and &lt;a href=&quot;nbdocs:/org/nbgit/docs/issues.html&quot;&gt;
+   the known issues&lt;/a&gt; before installing and upgrading.
+  &lt;/p&gt;
+
+  &lt;h3&gt;More About Git&lt;/h3&gt;
+  &lt;p&gt;
+   For more information about Git and this plugin visit
+   the following sites:
+  &lt;/p&gt;
+  &lt;ul&gt;
+   &lt;li&gt;NbGit Project Page:&lt;br/&gt;
+    &lt;object classid=&quot;java:org.netbeans.modules.javahelp.BrowserDisplayer&quot;&gt;
+     &lt;param name=&quot;content&quot; value=&quot;http://nbgit.googlecode.com/&quot;&gt;
+     &lt;param name=&quot;text&quot; value=&quot;&lt;html&gt;&lt;u&gt;http://nbgit.googlecode.com/&lt;/u&gt;&lt;/html&gt;&quot;&gt;
+     &lt;param name=&quot;textFontSize&quot; value=&quot;medium&quot;&gt;
+     &lt;param name=&quot;textColor&quot; value=&quot;blue&quot;&gt;
+    &lt;/object&gt;
+   &lt;/li&gt;
+   &lt;li&gt;NbGit GitWeb Page:&lt;br/&gt;
+    &lt;object classid=&quot;java:org.netbeans.modules.javahelp.BrowserDisplayer&quot;&gt;
+     &lt;param name=&quot;content&quot; value=&quot;http://repo.or.cz/w/nbgit.git&quot;&gt;
+     &lt;param name=&quot;text&quot; value=&quot;&lt;html&gt;&lt;u&gt;http://repo.or.cz/w/nbgit.git&lt;/u&gt;&lt;/html&gt;&quot;&gt;
+     &lt;param name=&quot;textFontSize&quot; value=&quot;medium&quot;&gt;
+     &lt;param name=&quot;textColor&quot; value=&quot;blue&quot;&gt;
+    &lt;/object&gt;
+   &lt;/li&gt;
+   &lt;li&gt;Git Homepage:&lt;br/&gt;
+    &lt;object classid=&quot;java:org.netbeans.modules.javahelp.BrowserDisplayer&quot;&gt;
+     &lt;param name=&quot;content&quot; value=&quot;http://www.git-scm.org/&quot;&gt;
+     &lt;param name=&quot;text&quot; value=&quot;&lt;html&gt;&lt;u&gt;http://git-scm.org/&lt;/u&gt;&lt;/html&gt;&quot;&gt;
+     &lt;param name=&quot;textFontSize&quot; value=&quot;medium&quot;&gt;
+     &lt;param name=&quot;textColor&quot; value=&quot;blue&quot;&gt;
+    &lt;/object&gt;
+   &lt;/li&gt;
+   &lt;li&gt;Git Wiki:&lt;br/&gt;
+    &lt;object classid=&quot;java:org.netbeans.modules.javahelp.BrowserDisplayer&quot;&gt;
+     &lt;param name=&quot;content&quot; value=&quot;http://www.git-scm.org/gitwiki/&quot;&gt;
+     &lt;param name=&quot;text&quot; value=&quot;&lt;html&gt;&lt;u&gt;http://git-scm.org/gitwiki/&lt;/u&gt;&lt;/html&gt;&quot;&gt;
+     &lt;param name=&quot;textFontSize&quot; value=&quot;medium&quot;&gt;
+     &lt;param name=&quot;textColor&quot; value=&quot;blue&quot;&gt;
+    &lt;/object&gt;
+   &lt;/li&gt;
+  &lt;/ul&gt;
+
+ &lt;/body&gt;
+&lt;/html&gt;</diff>
      <filename>javahelp/org/nbgit/docs/about.html</filename>
    </modified>
    <modified>
      <diff>@@ -1,125 +1,125 @@
-&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.01 Transitional//EN&quot; &quot;http://www.w3.org/TR/html4/loose.dtd&quot;&gt;
-&lt;html&gt;
-	&lt;head&gt;
-		&lt;title&gt;Credits and Legal Notices&lt;/title&gt;
-		&lt;link rel=&quot;stylesheet&quot; href=&quot;nbdocs://org.netbeans.modules.usersguide/org/netbeans/modules/usersguide/ide.css&quot; type=&quot;text/css&quot;&gt;
-	&lt;/head&gt;
-	&lt;body&gt;
-		&lt;h1&gt;Credits and Legal Notices&lt;/h1&gt;
-		&lt;p&gt;
-			Below credits are given to third-party components that
-			the NbGit module uses. Here you will also find information
-			about their individual terms of licensing.
-		&lt;/p&gt;
-		
-		&lt;h3&gt;The Mercurial and NbGit plugins&lt;/h3&gt;
-		&lt;p&gt;
-			Most of the core plugin code in NbGit is based on code
-			from NbGit (a git CLI-based Netbeans plugin), which in
-			terms borrows its code from the Mercurial and Subversion
-			plugins.
-		&lt;/p&gt;
-		&lt;p&gt;
-			The Mercurial and Subversion code is dual licensed under
-			the Common Development and Distribution License(&quot;CDDL&quot;)
-			and the GNU General Public License Version 2 only (&quot;GPL&quot;)
-			with the &quot;Classpath&quot; exception. NbGit is licensed under
-			the GNU General Public License Version 2 only (&quot;GPL&quot;)
-			with the &quot;Classpath&quot; exception.
-		&lt;/p&gt;
-		&lt;ul&gt;
-			&lt;li&gt;
-				The license can be view at:&lt;br/&gt;
-				&lt;object classid=&quot;java:org.netbeans.modules.javahelp.BrowserDisplayer&quot;&gt;
-					&lt;param name=&quot;content&quot; value=&quot;http://www.netbeans.org/cddl-gplv2.html&quot;/&gt;
-					&lt;param name=&quot;text&quot; value=&quot;&lt;html&gt;&lt;u&gt;http://www.netbeans.org/cddl-gplv2.html&lt;/u&gt;&lt;/html&gt;&quot;/&gt;
-					&lt;param name=&quot;textFontSize&quot; value=&quot;medium&quot;&gt;
-					&lt;param name=&quot;textColor&quot; value=&quot;blue&quot;/&gt;
-				&lt;/object&gt;
-			&lt;/li&gt;
-		&lt;/ul&gt;
-
-		&lt;h3&gt;JGit / EGit&lt;/h3&gt;
-		&lt;p&gt;
-			JGit is a pure Java implementation of Git. The library
-			is what makes it possible for NbGit to be a truely
-			cross platform, easy-to-install Netbeans plugin. NbGit's
-			sibling project EGit, an Eclipse plugin, along with the
-			JGit example programs has served as an excellent source
-			of inspiration for working with JGit.
-		&lt;/p&gt;
-		&lt;p&gt;
-			JGit is distributed under a BSD-style license.
-			The license is available in the source repository as
-			&lt;code&gt;release/modules/ext/org-spearce-jgit.LICENSE.txt&lt;/code&gt;.
-			EGit is distributed under the Eclipse Public License v1.0.
-		&lt;/p&gt;
-		&lt;ul&gt;
-			&lt;li&gt;
-				More info about JGit/EGit can be found at:&lt;br/&gt;
-				&lt;object classid=&quot;java:org.netbeans.modules.javahelp.BrowserDisplayer&quot;&gt;
-					&lt;param name=&quot;content&quot; value=&quot;http://code.google.com/p/egit/&quot;/&gt;
-					&lt;param name=&quot;text&quot; value=&quot;&lt;html&gt;&lt;u&gt;http://code.google.com/p/egit/&lt;/u&gt;&lt;/html&gt;&quot;/&gt;
-					&lt;param name=&quot;textFontSize&quot; value=&quot;medium&quot;&gt;
-					&lt;param name=&quot;textColor&quot; value=&quot;blue&quot;/&gt;
-				&lt;/object&gt;
-			&lt;/li&gt;
-			&lt;li&gt;
-				The specific license for JGit can be found at:&lt;br/&gt;
-				&lt;object classid=&quot;java:org.netbeans.modules.javahelp.BrowserDisplayer&quot;&gt;
-					&lt;param name=&quot;content&quot; value=&quot;http://repo.or.cz/w/egit.git?a=blob;f=org.spearce.jgit/LICENSE;hb=HEAD&quot;/&gt;
-					&lt;param name=&quot;text&quot; value=&quot;&lt;html&gt;&lt;u&gt;http://repo.or.cz/w/egit.git?a=blob;f=org.spearce.jgit/LICENSE;hb=HEAD&lt;/u&gt;&lt;/html&gt;&quot;/&gt;
-					&lt;param name=&quot;textFontSize&quot; value=&quot;medium&quot;&gt;
-					&lt;param name=&quot;textColor&quot; value=&quot;blue&quot;/&gt;
-				&lt;/object&gt;				
-			&lt;/li&gt;
-		&lt;/ul&gt;
-		
-		&lt;h3&gt;JSch&lt;/h3&gt;
-		&lt;p&gt;
-			The SSH transport support in JGit uses JSch. To easy
-			installation the version distributed with the JGit/EGit
-			project is included in this project. However, Netbeans
-			seem to include its own JSch jar file so it might be
-			possible to remove this dependency in the future.
-		&lt;/p&gt;
-		&lt;p&gt;
-			JSch is distributed under a BSD-style license.
-			The license is available in the source repository as
-			&lt;code&gt;release/modules/ext/com-jcraft-jsch.LICENSE.txt&lt;/code&gt;.
-		&lt;/p&gt;
-		
-		&lt;h3&gt;Git Icon&lt;/h3&gt;
-		&lt;p&gt;
-			The Git icon used for &quot;branding&quot; the status and history
-			tabs is made by Henrik Nyh.
-		&lt;/p&gt;
-		&lt;p&gt;
-			Regarding license, the blog post that announced this
-			alternative logo for Git states that anyone is 
-			&quot;Free to modify and redistribute with due credit,
-			and obviously free to use&quot;.
-		&lt;/p&gt;
-		&lt;ul&gt;
-			&lt;li&gt;
-				The blog post can be found at:&lt;br/&gt;
-				&lt;object classid=&quot;java:org.netbeans.modules.javahelp.BrowserDisplayer&quot;&gt;
-					&lt;param name=&quot;content&quot; value=&quot;http://henrik.nyh.se/2007/06/alternative-git-logo-and-favicon&quot;&gt;
-					&lt;param name=&quot;text&quot; value=&quot;&lt;html&gt;&lt;u&gt;http://henrik.nyh.se/2007/06/alternative-git-logo-and-favicon&lt;/u&gt;&lt;/html&gt;&quot;&gt;
-					&lt;param name=&quot;textFontSize&quot; value=&quot;medium&quot;&gt;
-					&lt;param name=&quot;textColor&quot; value=&quot;blue&quot;&gt;
-				&lt;/object&gt;
-			&lt;/li&gt;
-			&lt;li&gt;
-				Other versions can be found at:&lt;br/&gt;
-				&lt;object classid=&quot;java:org.netbeans.modules.javahelp.BrowserDisplayer&quot;&gt;
-					&lt;param name=&quot;content&quot; value=&quot;http://git.or.cz/gitwiki/GitRelatedLogos&quot;&gt;
-					&lt;param name=&quot;text&quot; value=&quot;&lt;html&gt;&lt;u&gt;http://git.or.cz/gitwiki/GitRelatedLogos&lt;/u&gt;&lt;/html&gt;&quot;&gt;
-					&lt;param name=&quot;textFontSize&quot; value=&quot;medium&quot;&gt;
-					&lt;param name=&quot;textColor&quot; value=&quot;blue&quot;&gt;
-				&lt;/object&gt;
-			&lt;/li&gt;
-		&lt;/ul&gt;
-		
-	&lt;/body&gt;
-&lt;/html&gt;
\ No newline at end of file
+&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.01 Transitional//EN&quot; &quot;http://www.w3.org/TR/html4/loose.dtd&quot;&gt;
+&lt;html&gt;
+ &lt;head&gt;
+  &lt;title&gt;Credits and Legal Notices&lt;/title&gt;
+  &lt;link rel=&quot;stylesheet&quot; href=&quot;nbdocs://org.netbeans.modules.usersguide/org/netbeans/modules/usersguide/ide.css&quot; type=&quot;text/css&quot;&gt;
+ &lt;/head&gt;
+ &lt;body&gt;
+  &lt;h1&gt;Credits and Legal Notices&lt;/h1&gt;
+  &lt;p&gt;
+   Below credits are given to third-party components that
+   the NbGit module uses. Here you will also find information
+   about their individual terms of licensing.
+  &lt;/p&gt;
+
+  &lt;h3&gt;The Mercurial and NbGit plugins&lt;/h3&gt;
+  &lt;p&gt;
+   Most of the core plugin code in NbGit is based on code
+   from NbGit (a git CLI-based Netbeans plugin), which in
+   terms borrows its code from the Mercurial and Subversion
+   plugins.
+  &lt;/p&gt;
+  &lt;p&gt;
+   The Mercurial and Subversion code is dual licensed under
+   the Common Development and Distribution License(&quot;CDDL&quot;)
+   and the GNU General Public License Version 2 only (&quot;GPL&quot;)
+   with the &quot;Classpath&quot; exception. NbGit is licensed under
+   the GNU General Public License Version 2 only (&quot;GPL&quot;)
+   with the &quot;Classpath&quot; exception.
+  &lt;/p&gt;
+  &lt;ul&gt;
+   &lt;li&gt;
+    The license can be view at:&lt;br/&gt;
+    &lt;object classid=&quot;java:org.netbeans.modules.javahelp.BrowserDisplayer&quot;&gt;
+     &lt;param name=&quot;content&quot; value=&quot;http://www.netbeans.org/cddl-gplv2.html&quot;/&gt;
+     &lt;param name=&quot;text&quot; value=&quot;&lt;html&gt;&lt;u&gt;http://www.netbeans.org/cddl-gplv2.html&lt;/u&gt;&lt;/html&gt;&quot;/&gt;
+     &lt;param name=&quot;textFontSize&quot; value=&quot;medium&quot;&gt;
+     &lt;param name=&quot;textColor&quot; value=&quot;blue&quot;/&gt;
+    &lt;/object&gt;
+   &lt;/li&gt;
+  &lt;/ul&gt;
+
+  &lt;h3&gt;JGit / EGit&lt;/h3&gt;
+  &lt;p&gt;
+   JGit is a pure Java implementation of Git. The library
+   is what makes it possible for NbGit to be a truely
+   cross platform, easy-to-install Netbeans plugin. NbGit's
+   sibling project EGit, an Eclipse plugin, along with the
+   JGit example programs has served as an excellent source
+   of inspiration for working with JGit.
+  &lt;/p&gt;
+  &lt;p&gt;
+   JGit is distributed under a BSD-style license.
+   The license is available in the source repository as
+   &lt;code&gt;release/modules/ext/org-spearce-jgit.LICENSE.txt&lt;/code&gt;.
+   EGit is distributed under the Eclipse Public License v1.0.
+  &lt;/p&gt;
+  &lt;ul&gt;
+   &lt;li&gt;
+    More info about JGit/EGit can be found at:&lt;br/&gt;
+    &lt;object classid=&quot;java:org.netbeans.modules.javahelp.BrowserDisplayer&quot;&gt;
+     &lt;param name=&quot;content&quot; value=&quot;http://code.google.com/p/egit/&quot;/&gt;
+     &lt;param name=&quot;text&quot; value=&quot;&lt;html&gt;&lt;u&gt;http://code.google.com/p/egit/&lt;/u&gt;&lt;/html&gt;&quot;/&gt;
+     &lt;param name=&quot;textFontSize&quot; value=&quot;medium&quot;&gt;
+     &lt;param name=&quot;textColor&quot; value=&quot;blue&quot;/&gt;
+    &lt;/object&gt;
+   &lt;/li&gt;
+   &lt;li&gt;
+    The specific license for JGit can be found at:&lt;br/&gt;
+    &lt;object classid=&quot;java:org.netbeans.modules.javahelp.BrowserDisplayer&quot;&gt;
+     &lt;param name=&quot;content&quot; value=&quot;http://repo.or.cz/w/egit.git?a=blob;f=org.spearce.jgit/LICENSE;hb=HEAD&quot;/&gt;
+     &lt;param name=&quot;text&quot; value=&quot;&lt;html&gt;&lt;u&gt;http://repo.or.cz/w/egit.git?a=blob;f=org.spearce.jgit/LICENSE;hb=HEAD&lt;/u&gt;&lt;/html&gt;&quot;/&gt;
+     &lt;param name=&quot;textFontSize&quot; value=&quot;medium&quot;&gt;
+     &lt;param name=&quot;textColor&quot; value=&quot;blue&quot;/&gt;
+    &lt;/object&gt;
+   &lt;/li&gt;
+  &lt;/ul&gt;
+
+  &lt;h3&gt;JSch&lt;/h3&gt;
+  &lt;p&gt;
+   The SSH transport support in JGit uses JSch. To easy
+   installation the version distributed with the JGit/EGit
+   project is included in this project. However, Netbeans
+   seem to include its own JSch jar file so it might be
+   possible to remove this dependency in the future.
+  &lt;/p&gt;
+  &lt;p&gt;
+   JSch is distributed under a BSD-style license.
+   The license is available in the source repository as
+   &lt;code&gt;release/modules/ext/com-jcraft-jsch.LICENSE.txt&lt;/code&gt;.
+  &lt;/p&gt;
+
+  &lt;h3&gt;Git Icon&lt;/h3&gt;
+  &lt;p&gt;
+   The Git icon used for &quot;branding&quot; the status and history
+   tabs is made by Henrik Nyh.
+  &lt;/p&gt;
+  &lt;p&gt;
+   Regarding license, the blog post that announced this
+   alternative logo for Git states that anyone is
+   &quot;Free to modify and redistribute with due credit,
+   and obviously free to use&quot;.
+  &lt;/p&gt;
+  &lt;ul&gt;
+   &lt;li&gt;
+    The blog post can be found at:&lt;br/&gt;
+    &lt;object classid=&quot;java:org.netbeans.modules.javahelp.BrowserDisplayer&quot;&gt;
+     &lt;param name=&quot;content&quot; value=&quot;http://henrik.nyh.se/2007/06/alternative-git-logo-and-favicon&quot;&gt;
+     &lt;param name=&quot;text&quot; value=&quot;&lt;html&gt;&lt;u&gt;http://henrik.nyh.se/2007/06/alternative-git-logo-and-favicon&lt;/u&gt;&lt;/html&gt;&quot;&gt;
+     &lt;param name=&quot;textFontSize&quot; value=&quot;medium&quot;&gt;
+     &lt;param name=&quot;textColor&quot; value=&quot;blue&quot;&gt;
+    &lt;/object&gt;
+   &lt;/li&gt;
+   &lt;li&gt;
+    Other versions can be found at:&lt;br/&gt;
+    &lt;object classid=&quot;java:org.netbeans.modules.javahelp.BrowserDisplayer&quot;&gt;
+     &lt;param name=&quot;content&quot; value=&quot;http://git.or.cz/gitwiki/GitRelatedLogos&quot;&gt;
+     &lt;param name=&quot;text&quot; value=&quot;&lt;html&gt;&lt;u&gt;http://git.or.cz/gitwiki/GitRelatedLogos&lt;/u&gt;&lt;/html&gt;&quot;&gt;
+     &lt;param name=&quot;textFontSize&quot; value=&quot;medium&quot;&gt;
+     &lt;param name=&quot;textColor&quot; value=&quot;blue&quot;&gt;
+    &lt;/object&gt;
+   &lt;/li&gt;
+  &lt;/ul&gt;
+
+ &lt;/body&gt;
+&lt;/html&gt;</diff>
      <filename>javahelp/org/nbgit/docs/credits.html</filename>
    </modified>
    <modified>
      <diff>@@ -1,28 +1,28 @@
 &lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
 &lt;!DOCTYPE helpset PUBLIC &quot;-//Sun Microsystems Inc.//DTD JavaHelp HelpSet Version 2.0//EN&quot; &quot;http://java.sun.com/products/javahelp/helpset_2_0.dtd&quot;&gt;
 &lt;helpset version=&quot;2.0&quot;&gt;
-	&lt;title&gt;Git Help&lt;/title&gt;
-	&lt;maps&gt;
-		&lt;homeID&gt;org.nbgit.docs.about&lt;/homeID&gt;
-		&lt;mapref location=&quot;map.xml&quot;/&gt;
-	&lt;/maps&gt;
-	&lt;view mergetype=&quot;javax.help.AppendMerge&quot;&gt;
-		&lt;name&gt;TOC&lt;/name&gt;
-		&lt;label&gt;Table of Contents&lt;/label&gt;
-		&lt;type&gt;javax.help.TOCView&lt;/type&gt;
-		&lt;data&gt;toc.xml&lt;/data&gt;
-	&lt;/view&gt;
-	&lt;view mergetype=&quot;javax.help.AppendMerge&quot;&gt;
-		&lt;name&gt;Index&lt;/name&gt;
-		&lt;label&gt;Index&lt;/label&gt;
-		&lt;type&gt;javax.help.IndexView&lt;/type&gt;
-		&lt;data&gt;index.xml&lt;/data&gt;
-	&lt;/view&gt;
-	&lt;view&gt;
-		&lt;name&gt;Search&lt;/name&gt;
-		&lt;label&gt;Search&lt;/label&gt;
-		&lt;type&gt;javax.help.SearchView&lt;/type&gt;
-		&lt;data engine=&quot;com.sun.java.help.search.DefaultSearchEngine&quot;&gt;JavaHelpSearch
-		&lt;/data&gt;
-	&lt;/view&gt;
+ &lt;title&gt;Git Help&lt;/title&gt;
+ &lt;maps&gt;
+  &lt;homeID&gt;org.nbgit.docs.about&lt;/homeID&gt;
+  &lt;mapref location=&quot;map.xml&quot;/&gt;
+ &lt;/maps&gt;
+ &lt;view mergetype=&quot;javax.help.AppendMerge&quot;&gt;
+  &lt;name&gt;TOC&lt;/name&gt;
+  &lt;label&gt;Table of Contents&lt;/label&gt;
+  &lt;type&gt;javax.help.TOCView&lt;/type&gt;
+  &lt;data&gt;toc.xml&lt;/data&gt;
+ &lt;/view&gt;
+ &lt;view mergetype=&quot;javax.help.AppendMerge&quot;&gt;
+  &lt;name&gt;Index&lt;/name&gt;
+  &lt;label&gt;Index&lt;/label&gt;
+  &lt;type&gt;javax.help.IndexView&lt;/type&gt;
+  &lt;data&gt;index.xml&lt;/data&gt;
+ &lt;/view&gt;
+ &lt;view&gt;
+  &lt;name&gt;Search&lt;/name&gt;
+  &lt;label&gt;Search&lt;/label&gt;
+  &lt;type&gt;javax.help.SearchView&lt;/type&gt;
+  &lt;data engine=&quot;com.sun.java.help.search.DefaultSearchEngine&quot;&gt;JavaHelpSearch
+  &lt;/data&gt;
+ &lt;/view&gt;
 &lt;/helpset&gt;</diff>
      <filename>javahelp/org/nbgit/docs/helpset.xml</filename>
    </modified>
    <modified>
      <diff>@@ -1,9 +1,9 @@
 &lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
 &lt;!DOCTYPE index PUBLIC &quot;-//Sun Microsystems Inc.//DTD JavaHelp Index Version 2.0//EN&quot; &quot;http://java.sun.com/products/javahelp/index_2_0.dtd&quot;&gt;
 &lt;index version=&quot;2.0&quot;&gt;
-	&lt;indexitem text=&quot;About Git&quot; target=&quot;org.nbgit.docs.about&quot;/&gt;
-	&lt;indexitem text=&quot;Release notes&quot; target=&quot;org.nbgit.docs.news&quot;/&gt;
-	&lt;indexitem text=&quot;Issues&quot; target=&quot;org.nbgit.docs.issues&quot;/&gt;
-	&lt;indexitem text=&quot;Bug reporting&quot; target=&quot;org.nbgit.docs.issues&quot;/&gt;
-	&lt;indexitem text=&quot;Credits&quot; target=&quot;org.nbgit.docs.credits&quot;/&gt;
+ &lt;indexitem text=&quot;About Git&quot; target=&quot;org.nbgit.docs.about&quot;/&gt;
+ &lt;indexitem text=&quot;Release notes&quot; target=&quot;org.nbgit.docs.news&quot;/&gt;
+ &lt;indexitem text=&quot;Issues&quot; target=&quot;org.nbgit.docs.issues&quot;/&gt;
+ &lt;indexitem text=&quot;Bug reporting&quot; target=&quot;org.nbgit.docs.issues&quot;/&gt;
+ &lt;indexitem text=&quot;Credits&quot; target=&quot;org.nbgit.docs.credits&quot;/&gt;
 &lt;/index&gt;</diff>
      <filename>javahelp/org/nbgit/docs/index.xml</filename>
    </modified>
    <modified>
      <diff>@@ -1,49 +1,49 @@
-&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.01 Transitional//EN&quot;&gt;
-&lt;html&gt;
-	&lt;head&gt;
-		&lt;title&gt;Issues and Bug Reporting&lt;/title&gt;
-		&lt;link rel=&quot;stylesheet&quot; href=&quot;nbdocs:/org/netbeans/modules/usersguide/ide.css&quot; type=&quot;text/css&quot;&gt;
-		&lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=UTF-8&quot;&gt;
-	&lt;/head&gt;
-	&lt;body&gt;
-		&lt;h1&gt;Issues and Bug Reporting&lt;/h1&gt;
-		&lt;p&gt;
-			The module is far from complete. Below some of the known
-			problems are listed along with how to report bugs.
-		&lt;/p&gt;
-		
-		&lt;h3&gt;Known Issues&lt;/h3&gt;
-		&lt;p&gt;
-			Known issues that are deemed worthy is listed here. Others
-			can be found in the issue tracker.
-		&lt;/p&gt;
-		&lt;ul&gt;
-			&lt;li&gt;The status information is not always updated correctly.&lt;/li&gt;
-			&lt;li&gt;When listing the status for a project, files in build/
-			is visible.&lt;/li&gt;
-		&lt;/ul&gt;
-		
-		&lt;h3&gt;Bug Reporting&lt;/h3&gt;
-		&lt;p&gt;
-			Did you find a bug? Got an idea for a must-have feature?
-		&lt;/p&gt;
-		&lt;ul&gt;
-			&lt;li&gt;Report an issue:&lt;br/&gt;
-				&lt;object classid=&quot;java:org.netbeans.modules.javahelp.BrowserDisplayer&quot;&gt;
-					&lt;param name=&quot;content&quot; value=&quot;http://code.google.com/p/nbgit/issues/entry&quot;&gt;
-					&lt;param name=&quot;text&quot; value=&quot;&lt;html&gt;&lt;u&gt;http://code.google.com/p/nbgit/issues/entry&lt;/u&gt;&lt;/html&gt;&quot;&gt;
-					&lt;param name=&quot;textFontSize&quot; value=&quot;medium&quot;&gt;
-					&lt;param name=&quot;textColor&quot; value=&quot;blue&quot;&gt;
-				&lt;/object&gt;
-			&lt;/li&gt;
-			&lt;li&gt;View all issues in the issue tracker:&lt;br/&gt;
-				&lt;object classid=&quot;java:org.netbeans.modules.javahelp.BrowserDisplayer&quot;&gt;
-					&lt;param name=&quot;content&quot; value=&quot;http://code.google.com/p/nbgit/issues/&quot;&gt;
-					&lt;param name=&quot;text&quot; value=&quot;&lt;html&gt;&lt;u&gt;http://code.google.com/p/nbgit/issues/&lt;/u&gt;&lt;/html&gt;&quot;&gt;
-					&lt;param name=&quot;textFontSize&quot; value=&quot;medium&quot;&gt;
-					&lt;param name=&quot;textColor&quot; value=&quot;blue&quot;&gt;
-				&lt;/object&gt;
-			&lt;/li&gt;
-		&lt;/ul&gt;
-	&lt;/body&gt;
-&lt;/html&gt;
+&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.01 Transitional//EN&quot;&gt;
+&lt;html&gt;
+ &lt;head&gt;
+  &lt;title&gt;Issues and Bug Reporting&lt;/title&gt;
+  &lt;link rel=&quot;stylesheet&quot; href=&quot;nbdocs:/org/netbeans/modules/usersguide/ide.css&quot; type=&quot;text/css&quot;&gt;
+  &lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=UTF-8&quot;&gt;
+ &lt;/head&gt;
+ &lt;body&gt;
+  &lt;h1&gt;Issues and Bug Reporting&lt;/h1&gt;
+  &lt;p&gt;
+   The module is far from complete. Below some of the known
+   problems are listed along with how to report bugs.
+  &lt;/p&gt;
+
+  &lt;h3&gt;Known Issues&lt;/h3&gt;
+  &lt;p&gt;
+   Known issues that are deemed worthy is listed here. Others
+   can be found in the issue tracker.
+  &lt;/p&gt;
+  &lt;ul&gt;
+   &lt;li&gt;The status information is not always updated correctly.&lt;/li&gt;
+   &lt;li&gt;When listing the status for a project, files in build/
+   is visible.&lt;/li&gt;
+  &lt;/ul&gt;
+
+  &lt;h3&gt;Bug Reporting&lt;/h3&gt;
+  &lt;p&gt;
+   Did you find a bug? Got an idea for a must-have feature?
+  &lt;/p&gt;
+  &lt;ul&gt;
+   &lt;li&gt;Report an issue:&lt;br/&gt;
+    &lt;object classid=&quot;java:org.netbeans.modules.javahelp.BrowserDisplayer&quot;&gt;
+     &lt;param name=&quot;content&quot; value=&quot;http://code.google.com/p/nbgit/issues/entry&quot;&gt;
+     &lt;param name=&quot;text&quot; value=&quot;&lt;html&gt;&lt;u&gt;http://code.google.com/p/nbgit/issues/entry&lt;/u&gt;&lt;/html&gt;&quot;&gt;
+     &lt;param name=&quot;textFontSize&quot; value=&quot;medium&quot;&gt;
+     &lt;param name=&quot;textColor&quot; value=&quot;blue&quot;&gt;
+    &lt;/object&gt;
+   &lt;/li&gt;
+   &lt;li&gt;View all issues in the issue tracker:&lt;br/&gt;
+    &lt;object classid=&quot;java:org.netbeans.modules.javahelp.BrowserDisplayer&quot;&gt;
+     &lt;param name=&quot;content&quot; value=&quot;http://code.google.com/p/nbgit/issues/&quot;&gt;
+     &lt;param name=&quot;text&quot; value=&quot;&lt;html&gt;&lt;u&gt;http://code.google.com/p/nbgit/issues/&lt;/u&gt;&lt;/html&gt;&quot;&gt;
+     &lt;param name=&quot;textFontSize&quot; value=&quot;medium&quot;&gt;
+     &lt;param name=&quot;textColor&quot; value=&quot;blue&quot;&gt;
+    &lt;/object&gt;
+   &lt;/li&gt;
+  &lt;/ul&gt;
+ &lt;/body&gt;
+&lt;/html&gt;</diff>
      <filename>javahelp/org/nbgit/docs/issues.html</filename>
    </modified>
    <modified>
      <diff>@@ -1,8 +1,8 @@
 &lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
 &lt;!DOCTYPE map PUBLIC &quot;-//Sun Microsystems Inc.//DTD JavaHelp Map Version 2.0//EN&quot; &quot;http://java.sun.com/products/javahelp/map_2_0.dtd&quot;&gt;
 &lt;map version=&quot;2.0&quot;&gt;
-	&lt;mapID target=&quot;org.nbgit.docs.about&quot; url=&quot;about.html&quot;/&gt;
-	&lt;mapID target=&quot;org.nbgit.docs.credits&quot; url=&quot;credits.html&quot;/&gt;
-	&lt;mapID target=&quot;org.nbgit.docs.news&quot; url=&quot;news.html&quot;/&gt;
-	&lt;mapID target=&quot;org.nbgit.docs.issues&quot; url=&quot;issues.html&quot;/&gt;
+ &lt;mapID target=&quot;org.nbgit.docs.about&quot; url=&quot;about.html&quot;/&gt;
+ &lt;mapID target=&quot;org.nbgit.docs.credits&quot; url=&quot;credits.html&quot;/&gt;
+ &lt;mapID target=&quot;org.nbgit.docs.news&quot; url=&quot;news.html&quot;/&gt;
+ &lt;mapID target=&quot;org.nbgit.docs.issues&quot; url=&quot;issues.html&quot;/&gt;
 &lt;/map&gt;</diff>
      <filename>javahelp/org/nbgit/docs/map.xml</filename>
    </modified>
    <modified>
      <diff>@@ -1,26 +1,26 @@
-&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.01 Transitional//EN&quot;&gt;
-&lt;html&gt;
-	&lt;head&gt;
-		&lt;title&gt;Release Notes&lt;/title&gt;
-		&lt;link rel=&quot;stylesheet&quot; href=&quot;nbdocs:/org/netbeans/modules/usersguide/ide.css&quot; type=&quot;text/css&quot;&gt;
-		&lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=UTF-8&quot;&gt;
-	&lt;/head&gt;
-	&lt;body&gt;
-		&lt;h1&gt;Release Notes&lt;/h1&gt;
-		&lt;p&gt;
-			News about features and issues that have been resolved.	
-		&lt;/p&gt;
-		
-		&lt;h3&gt;NbGit v0.1&lt;/h3&gt;
-		&lt;p&gt;New features:&lt;/p&gt;
-		&lt;ul&gt;
-			&lt;li&gt;init: create a new git repository.&lt;/li&gt;
-			&lt;li&gt;status: list the status of changed files.&lt;/li&gt;
-			&lt;li&gt;diff: view changes to files (side-by-side).&lt;/li&gt;
-			&lt;li&gt;commit: commit a selected range of files.&lt;/li&gt;
-			&lt;li&gt;update: revert individual file changes.&lt;/li&gt;
-			&lt;li&gt;properties: change project and repository specific
-			options (i.e. user.name and user.email).&lt;/li&gt;
-		&lt;/ul&gt;
-	&lt;/body&gt;
-&lt;/html&gt;
+&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.01 Transitional//EN&quot;&gt;
+&lt;html&gt;
+ &lt;head&gt;
+  &lt;title&gt;Release Notes&lt;/title&gt;
+  &lt;link rel=&quot;stylesheet&quot; href=&quot;nbdocs:/org/netbeans/modules/usersguide/ide.css&quot; type=&quot;text/css&quot;&gt;
+  &lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=UTF-8&quot;&gt;
+ &lt;/head&gt;
+ &lt;body&gt;
+  &lt;h1&gt;Release Notes&lt;/h1&gt;
+  &lt;p&gt;
+   News about features and issues that have been resolved.
+  &lt;/p&gt;
+
+  &lt;h3&gt;NbGit v0.1&lt;/h3&gt;
+  &lt;p&gt;New features:&lt;/p&gt;
+  &lt;ul&gt;
+   &lt;li&gt;init: create a new git repository.&lt;/li&gt;
+   &lt;li&gt;status: list the status of changed files.&lt;/li&gt;
+   &lt;li&gt;diff: view changes to files (side-by-side).&lt;/li&gt;
+   &lt;li&gt;commit: commit a selected range of files.&lt;/li&gt;
+   &lt;li&gt;update: revert individual file changes.&lt;/li&gt;
+   &lt;li&gt;properties: change project and repository specific
+   options (i.e. user.name and user.email).&lt;/li&gt;
+  &lt;/ul&gt;
+ &lt;/body&gt;
+&lt;/html&gt;</diff>
      <filename>javahelp/org/nbgit/docs/news.html</filename>
    </modified>
    <modified>
      <diff>@@ -1,10 +1,10 @@
-&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
-&lt;!DOCTYPE toc PUBLIC &quot;-//Sun Microsystems Inc.//DTD JavaHelp TOC Version 2.0//EN&quot; &quot;http://java.sun.com/products/javahelp/toc_2_0.dtd&quot;&gt;
-&lt;toc version=&quot;2.0&quot;&gt;
-	&lt;tocitem text=&quot;Git&quot;&gt;
-		&lt;tocitem text=&quot;About Git&quot; target=&quot;org.nbgit.docs.about&quot;/&gt;
-		&lt;tocitem text=&quot;Release Notes&quot; target=&quot;org.nbgit.docs.news&quot;/&gt;
-		&lt;tocitem text=&quot;Issues and Bug Reporting&quot; target=&quot;org.nbgit.docs.issues&quot;/&gt;
-		&lt;tocitem text=&quot;Credits and Legal Notes&quot; target=&quot;org.nbgit.docs.credits&quot;/&gt;
-	&lt;/tocitem&gt;
-&lt;/toc&gt;
+&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
+&lt;!DOCTYPE toc PUBLIC &quot;-//Sun Microsystems Inc.//DTD JavaHelp TOC Version 2.0//EN&quot; &quot;http://java.sun.com/products/javahelp/toc_2_0.dtd&quot;&gt;
+&lt;toc version=&quot;2.0&quot;&gt;
+ &lt;tocitem text=&quot;Git&quot;&gt;
+  &lt;tocitem text=&quot;About Git&quot; target=&quot;org.nbgit.docs.about&quot;/&gt;
+  &lt;tocitem text=&quot;Release Notes&quot; target=&quot;org.nbgit.docs.news&quot;/&gt;
+  &lt;tocitem text=&quot;Issues and Bug Reporting&quot; target=&quot;org.nbgit.docs.issues&quot;/&gt;
+  &lt;tocitem text=&quot;Credits and Legal Notes&quot; target=&quot;org.nbgit.docs.credits&quot;/&gt;
+ &lt;/tocitem&gt;
+&lt;/toc&gt;</diff>
      <filename>javahelp/org/nbgit/docs/toc.xml</filename>
    </modified>
    <modified>
      <diff>@@ -1,8 +1,8 @@
-JSch 0.0.* was released under the GNU LGPL license.  Later, we have switched 
-over to a BSD-style license. 
+JSch 0.0.* was released under the GNU LGPL license.  Later, we have switched
+over to a BSD-style license.
 
 ------------------------------------------------------------------------------
-Copyright (c) 2002,2003,2004,2005,2006,2007,2008 Atsuhiko Yamanaka, JCraft,Inc. 
+Copyright (c) 2002,2003,2004,2005,2006,2007,2008 Atsuhiko Yamanaka, JCraft,Inc.
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
@@ -11,8 +11,8 @@ modification, are permitted provided that the following conditions are met:
   1. Redistributions of source code must retain the above copyright notice,
      this list of conditions and the following disclaimer.
 
-  2. Redistributions in binary form must reproduce the above copyright 
-     notice, this list of conditions and the following disclaimer in 
+  2. Redistributions in binary form must reproduce the above copyright
+     notice, this list of conditions and the following disclaimer in
      the documentation and/or other materials provided with the distribution.
 
   3. The names of the authors may not be used to endorse or promote products</diff>
      <filename>release/modules/ext/com-jcraft-jsch.LICENSE.txt</filename>
    </modified>
    <modified>
      <diff>@@ -74,13 +74,13 @@ class DiskMapTurboProvider implements TurboProvider {
 
     private static final int STATUS_VALUABLE = StatusInfo.STATUS_MANAGED &amp; ~StatusInfo.STATUS_VERSIONED_UPTODATE;
     private static final String CACHE_DIRECTORY = &quot;gitcache&quot;; // NOI18N
-    
+
     private File cacheStore;
     private int                             storeSerial;
 
     private int                             cachedStoreSerial = -1;
     private Map&lt;File, StatusInfo&gt; cachedValues;
-    
+
     DiskMapTurboProvider() {
         initCacheStore();
     }</diff>
      <filename>src/org/nbgit/DiskMapTurboProvider.java</filename>
    </modified>
    <modified>
      <diff>@@ -61,240 +61,240 @@ import org.spearce.jgit.lib.Repository;
 
 /**
  * Main entry point for Git functionality, use getInstance() to get the Git object.
- * 
+ *
  * @author alexbcoles
  * @author Maros Sandor
  */
 public class Git {
 
-	public static final String GIT_OUTPUT_TAB_TITLE = org.openide.util.NbBundle.getMessage(Git.class, &quot;CTL_Git_DisplayName&quot;); // NOI18N
+    public static final String GIT_OUTPUT_TAB_TITLE = org.openide.util.NbBundle.getMessage(Git.class, &quot;CTL_Git_DisplayName&quot;); // NOI18N
 
-	public static final String PROP_ANNOTATIONS_CHANGED = &quot;annotationsChanged&quot;; // NOI18N
-	public static final String PROP_VERSIONED_FILES_CHANGED = &quot;versionedFilesChanged&quot;; // NOI18N
-	public static final String PROP_CHANGESET_CHANGED = &quot;changesetChanged&quot;; // NOI18N
-	public static final Logger LOG = Logger.getLogger(&quot;org.nbgit&quot;); // NOI18N
-	private static final int STATUS_DIFFABLE =
-		StatusInfo.STATUS_VERSIONED_UPTODATE |
-		StatusInfo.STATUS_VERSIONED_MODIFIEDLOCALLY |
-		StatusInfo.STATUS_VERSIONED_MODIFIEDINREPOSITORY |
-		StatusInfo.STATUS_VERSIONED_CONFLICT |
-		StatusInfo.STATUS_VERSIONED_MERGE |
-		StatusInfo.STATUS_VERSIONED_REMOVEDINREPOSITORY |
-		StatusInfo.STATUS_VERSIONED_MODIFIEDINREPOSITORY |
-		StatusInfo.STATUS_VERSIONED_MODIFIEDINREPOSITORY;
-	private final PropertyChangeSupport support = new PropertyChangeSupport(this);
-	private final StatusCache statusCache = new StatusCache(this);
-	private HashMap&lt;String, RequestProcessor&gt; processorsToUrl;
-	private final Map&lt;File, Repository&gt; repos = new HashMap&lt;File, Repository&gt;();
-	private static Git instance;
+    public static final String PROP_ANNOTATIONS_CHANGED = &quot;annotationsChanged&quot;; // NOI18N
+    public static final String PROP_VERSIONED_FILES_CHANGED = &quot;versionedFilesChanged&quot;; // NOI18N
+    public static final String PROP_CHANGESET_CHANGED = &quot;changesetChanged&quot;; // NOI18N
+    public static final Logger LOG = Logger.getLogger(&quot;org.nbgit&quot;); // NOI18N
+    private static final int STATUS_DIFFABLE =
+        StatusInfo.STATUS_VERSIONED_UPTODATE |
+        StatusInfo.STATUS_VERSIONED_MODIFIEDLOCALLY |
+        StatusInfo.STATUS_VERSIONED_MODIFIEDINREPOSITORY |
+        StatusInfo.STATUS_VERSIONED_CONFLICT |
+        StatusInfo.STATUS_VERSIONED_MERGE |
+        StatusInfo.STATUS_VERSIONED_REMOVEDINREPOSITORY |
+        StatusInfo.STATUS_VERSIONED_MODIFIEDINREPOSITORY |
+        StatusInfo.STATUS_VERSIONED_MODIFIEDINREPOSITORY;
+    private final PropertyChangeSupport support = new PropertyChangeSupport(this);
+    private final StatusCache statusCache = new StatusCache(this);
+    private HashMap&lt;String, RequestProcessor&gt; processorsToUrl;
+    private final Map&lt;File, Repository&gt; repos = new HashMap&lt;File, Repository&gt;();
+    private static Git instance;
 
-	private Git()
-	{
-	}
+    private Git()
+    {
+    }
 
-	public static synchronized Git getInstance()
-	{
-		if (instance == null)
-			instance = new Git();
-		return instance;
-	}
+    public static synchronized Git getInstance()
+    {
+        if (instance == null)
+            instance = new Git();
+        return instance;
+    }
 
-	public Repository getRepository(File root)
-	{
-		Repository repo = repos.get(root);
+    public Repository getRepository(File root)
+    {
+        Repository repo = repos.get(root);
 
-		if (repo == null) {
-			final File gitDir = new File(root, GitRepository.GIT_DIR);
-			try {
-				repo = new Repository(gitDir);
-				repos.put(root, repo);
-			} catch (IOException ex) {
-			}
-		}
+        if (repo == null) {
+            final File gitDir = new File(root, GitRepository.GIT_DIR);
+            try {
+                repo = new Repository(gitDir);
+                repos.put(root, repo);
+            } catch (IOException ex) {
+            }
+        }
 
-		return repo;
-	}
+        return repo;
+    }
 
-	/**
-	 * Gets the Status Cache for the Git repository.
-	 * 
-	 * @return StatusCache for the repository
-	 */
-	public StatusCache getStatusCache()
-	{
-		return statusCache;
-	}
+    /**
+     * Gets the Status Cache for the Git repository.
+     *
+     * @return StatusCache for the repository
+     */
+    public StatusCache getStatusCache()
+    {
+        return statusCache;
+    }
 
-	/**
-	 * Tests the &lt;tt&gt;.git&lt;/tt&gt; directory itself.
-	 * 
-	 * @param file
-	 * @return
-	 */
-	public boolean isAdministrative(File file)
-	{
-		String name = file.getName();
-		return isAdministrative(name) &amp;&amp; file.isDirectory();
-	}
+    /**
+     * Tests the &lt;tt&gt;.git&lt;/tt&gt; directory itself.
+     *
+     * @param file
+     * @return
+     */
+    public boolean isAdministrative(File file)
+    {
+        String name = file.getName();
+        return isAdministrative(name) &amp;&amp; file.isDirectory();
+    }
 
-	public boolean isAdministrative(String fileName)
-	{
-		return fileName.equals(&quot;.git&quot;); // NOI18N
-	}
+    public boolean isAdministrative(String fileName)
+    {
+        return fileName.equals(&quot;.git&quot;); // NOI18N
+    }
 
-	/**
-	 * Tests whether a file or directory should receive the STATUS_NOTVERSIONED_NOTMANAGED status. 
-	 * All files and folders that have a parent with CVS/Repository file are considered versioned.
-	 * 
-	 * @param file a file or directory
-	 * @return false if the file should receive the STATUS_NOTVERSIONED_NOTMANAGED status, true otherwise
-	 */
-	public boolean isManaged(File file)
-	{
-		return VersioningSupport.getOwner(file) instanceof GitVCS &amp;&amp; !GitUtils.isPartOfGitMetadata(file);
-	}
+    /**
+     * Tests whether a file or directory should receive the STATUS_NOTVERSIONED_NOTMANAGED status.
+     * All files and folders that have a parent with CVS/Repository file are considered versioned.
+     *
+     * @param file a file or directory
+     * @return false if the file should receive the STATUS_NOTVERSIONED_NOTMANAGED status, true otherwise
+     */
+    public boolean isManaged(File file)
+    {
+        return VersioningSupport.getOwner(file) instanceof GitVCS &amp;&amp; !GitUtils.isPartOfGitMetadata(file);
+    }
 
-	public File getTopmostManagedParent(File file)
-	{
-		if (GitUtils.isPartOfGitMetadata(file))
-			for (; file != null; file = file.getParentFile()) {
-				if (isAdministrative(file)) {
-					file = file.getParentFile();
-					break;
-				}
-			}
-		File topmost = null;
-		for (; file != null; file = file.getParentFile()) {
-			if (org.netbeans.modules.versioning.util.Utils.isScanForbidden(file))
-				break;
-			if (new File(file, &quot;.git&quot;).canWrite()) { // NOI18N
-				topmost = file;
-				break;
-			}
-		}
-		return topmost;
-	}
+    public File getTopmostManagedParent(File file)
+    {
+        if (GitUtils.isPartOfGitMetadata(file))
+            for (; file != null; file = file.getParentFile()) {
+                if (isAdministrative(file)) {
+                    file = file.getParentFile();
+                    break;
+                }
+            }
+        File topmost = null;
+        for (; file != null; file = file.getParentFile()) {
+            if (org.netbeans.modules.versioning.util.Utils.isScanForbidden(file))
+                break;
+            if (new File(file, &quot;.git&quot;).canWrite()) { // NOI18N
+                topmost = file;
+                break;
+            }
+        }
+        return topmost;
+    }
 
-	/**
-	 * Uses content analysis to return the mime type for files.
-	 *
-	 * @param file file to examine
-	 * @return String mime type of the file (or best guess)
-	 */
-	public String getMimeType(File file)
-	{
-		FileObject fo = FileUtil.toFileObject(file);
-		String foMime;
-		if (fo == null)
-			foMime = &quot;content/unknown&quot;;
-		else {
-			foMime = fo.getMIMEType();
-			if (&quot;content/unknown&quot;.equals(foMime)) // NOI18N
-				foMime = &quot;text/plain&quot;;
-		}
-		if ((statusCache.getStatus(file).getStatus() &amp; StatusInfo.STATUS_VERSIONED) == 0)
-			return GitUtils.isFileContentBinary(file) ? &quot;application/octet-stream&quot; : foMime;
-		else
-			return foMime;
-	}
+    /**
+     * Uses content analysis to return the mime type for files.
+     *
+     * @param file file to examine
+     * @return String mime type of the file (or best guess)
+     */
+    public String getMimeType(File file)
+    {
+        FileObject fo = FileUtil.toFileObject(file);
+        String foMime;
+        if (fo == null)
+            foMime = &quot;content/unknown&quot;;
+        else {
+            foMime = fo.getMIMEType();
+            if (&quot;content/unknown&quot;.equals(foMime)) // NOI18N
+                foMime = &quot;text/plain&quot;;
+        }
+        if ((statusCache.getStatus(file).getStatus() &amp; StatusInfo.STATUS_VERSIONED) == 0)
+            return GitUtils.isFileContentBinary(file) ? &quot;application/octet-stream&quot; : foMime;
+        else
+            return foMime;
+    }
 
-	public void versionedFilesChanged()
-	{
-		support.firePropertyChange(PROP_VERSIONED_FILES_CHANGED, null, null);
-	}
+    public void versionedFilesChanged()
+    {
+        support.firePropertyChange(PROP_VERSIONED_FILES_CHANGED, null, null);
+    }
 
-	public void refreshAllAnnotations()
-	{
-		support.firePropertyChange(PROP_ANNOTATIONS_CHANGED, null, null);
-	}
+    public void refreshAllAnnotations()
+    {
+        support.firePropertyChange(PROP_ANNOTATIONS_CHANGED, null, null);
+    }
 
-	public void changesetChanged(File repository)
-	{
-		support.firePropertyChange(PROP_CHANGESET_CHANGED, repository, null);
-	}
+    public void changesetChanged(File repository)
+    {
+        support.firePropertyChange(PROP_CHANGESET_CHANGED, repository, null);
+    }
 
-	public void addPropertyChangeListener(PropertyChangeListener listener)
-	{
-		support.addPropertyChangeListener(listener);
-	}
+    public void addPropertyChangeListener(PropertyChangeListener listener)
+    {
+        support.addPropertyChangeListener(listener);
+    }
 
-	public void removePropertyChangeListener(PropertyChangeListener listener)
-	{
-		support.removePropertyChangeListener(listener);
-	}
+    public void removePropertyChangeListener(PropertyChangeListener listener)
+    {
+        support.removePropertyChangeListener(listener);
+    }
 
-	public void getOriginalFile(File workingCopy, File originalFile)
-	{
-		StatusInfo info = statusCache.getStatus(workingCopy);
-		LOG.log(Level.FINE, &quot;getOriginalFile: {0} {1}&quot;, new Object[]{workingCopy, info}); // NOI18N
-		if ((info.getStatus() &amp; STATUS_DIFFABLE) == 0)
-			return;
+    public void getOriginalFile(File workingCopy, File originalFile)
+    {
+        StatusInfo info = statusCache.getStatus(workingCopy);
+        LOG.log(Level.FINE, &quot;getOriginalFile: {0} {1}&quot;, new Object[]{workingCopy, info}); // NOI18N
+        if ((info.getStatus() &amp; STATUS_DIFFABLE) == 0)
+            return;
 
-		// We can get status returned as UptoDate instead of LocallyNew
-		// because refreshing of status after creation has been scheduled
-		// but may not have happened yet.
-		try {
-			File original = GitUtils.getFileRevision(workingCopy, GitRepository.REVISION_BASE);
-			if (original == null)
-				return;
-			org.netbeans.modules.versioning.util.Utils.copyStreamsCloseAll(new FileOutputStream(originalFile), new FileInputStream(original));
-			original.delete();
-		} catch (IOException e) {
-			Logger.getLogger(Git.class.getName()).log(Level.INFO, &quot;Unable to get original file&quot;, e); // NOI18N
-		}
+        // We can get status returned as UptoDate instead of LocallyNew
+        // because refreshing of status after creation has been scheduled
+        // but may not have happened yet.
+        try {
+            File original = GitUtils.getFileRevision(workingCopy, GitRepository.REVISION_BASE);
+            if (original == null)
+                return;
+            org.netbeans.modules.versioning.util.Utils.copyStreamsCloseAll(new FileOutputStream(originalFile), new FileInputStream(original));
+            original.delete();
+        } catch (IOException e) {
+            Logger.getLogger(Git.class.getName()).log(Level.INFO, &quot;Unable to get original file&quot;, e); // NOI18N
+        }
 
-	}
+    }
 
-	/**
-	 * Serializes all Git requests (moves them out of AWT).
-	 */
-	public RequestProcessor getRequestProcessor()
-	{
-		return getRequestProcessor((String) null);
-	}
+    /**
+     * Serializes all Git requests (moves them out of AWT).
+     */
+    public RequestProcessor getRequestProcessor()
+    {
+        return getRequestProcessor((String) null);
+    }
 
-	/**
-	 * Serializes all Git requests (moves them out of AWT).
-	 */
-	public RequestProcessor getRequestProcessor(File file)
-	{
-		return getRequestProcessor(file.getAbsolutePath());
-	}
+    /**
+     * Serializes all Git requests (moves them out of AWT).
+     */
+    public RequestProcessor getRequestProcessor(File file)
+    {
+        return getRequestProcessor(file.getAbsolutePath());
+    }
 
-	public RequestProcessor getRequestProcessor(String url)
-	{
-		if (processorsToUrl == null)
-			processorsToUrl = new HashMap&lt;String, RequestProcessor&gt;();
+    public RequestProcessor getRequestProcessor(String url)
+    {
+        if (processorsToUrl == null)
+            processorsToUrl = new HashMap&lt;String, RequestProcessor&gt;();
 
-		String key;
-		if (url != null)
-			key = url;
-		else
-			key = &quot;ANY_URL&quot;;
+        String key;
+        if (url != null)
+            key = url;
+        else
+            key = &quot;ANY_URL&quot;;
 
-		RequestProcessor rp = processorsToUrl.get(key);
-		if (rp == null) {
-			rp = new RequestProcessor(&quot;Git - &quot; + key, 1, true); // NOI18N
-			processorsToUrl.put(key, rp);
-		}
-		return rp;
-	}
+        RequestProcessor rp = processorsToUrl.get(key);
+        if (rp == null) {
+            rp = new RequestProcessor(&quot;Git - &quot; + key, 1, true); // NOI18N
+            processorsToUrl.put(key, rp);
+        }
+        return rp;
+    }
 
-	public void clearRequestProcessor(String url)
-	{
-		if (processorsToUrl != null &amp; url != null)
-			processorsToUrl.remove(url);
-	}
+    public void clearRequestProcessor(String url)
+    {
+        if (processorsToUrl != null &amp; url != null)
+            processorsToUrl.remove(url);
+    }
 
-	/**
-	 *
-	 * @param repositoryRoot String of Git repository so that logger writes to correct output tab. Can be null
-	 * in which case the logger will not print anything
-	 * @return OutputLogger logger to write to
-	 */
-	public OutputLogger getLogger(String repositoryRoot)
-	{
-		return OutputLogger.getLogger(repositoryRoot);
-	}
+    /**
+     *
+     * @param repositoryRoot String of Git repository so that logger writes to correct output tab. Can be null
+     * in which case the logger will not print anything
+     * @return OutputLogger logger to write to
+     */
+    public OutputLogger getLogger(String repositoryRoot)
+    {
+        return OutputLogger.getLogger(repositoryRoot);
+    }
 
 }
\ No newline at end of file</diff>
      <filename>src/org/nbgit/Git.java</filename>
    </modified>
    <modified>
      <diff>@@ -75,7 +75,7 @@ import org.openide.util.RequestProcessor;
 import org.openide.util.Utilities;
 
 /**
- * Responsible for coloring file labels and file icons in the IDE and providing 
+ * Responsible for coloring file labels and file icons in the IDE and providing
  * IDE with menu items.
  *
  * @author Maros Sandor
@@ -83,351 +83,351 @@ import org.openide.util.Utilities;
  */
 public class GitAnnotator extends VCSAnnotator {
 
-	private static final int INITIAL_ACTION_ARRAY_LENGTH = 25;
-	private static final int STATUS_BADGEABLE =
-		StatusInfo.STATUS_VERSIONED_UPTODATE |
-		StatusInfo.STATUS_NOTVERSIONED_NEWLOCALLY |
-		StatusInfo.STATUS_VERSIONED_MODIFIEDLOCALLY;
-	public static String ANNOTATION_REVISION = &quot;revision&quot;; // NOI18N
-	public static String ANNOTATION_STATUS = &quot;status&quot;; // NOI18N
-	public static String ANNOTATION_FOLDER = &quot;folder&quot;; // NOI18N
-	public static String[] LABELS = new String[]{ANNOTATION_REVISION, ANNOTATION_STATUS, ANNOTATION_FOLDER};
-	private StatusCache cache;
-	private File folderToScan;
-	private ConcurrentLinkedQueue&lt;File&gt; dirsToScan = new ConcurrentLinkedQueue&lt;File&gt;();
-	private RequestProcessor.Task scanTask;
-	private static final RequestProcessor rp = new RequestProcessor(&quot;GitAnnotateScan&quot;, 1, true); // NOI18N
-	private final HtmlFormatter format;
-
-	public GitAnnotator()
-	{
-		format = HtmlFormatter.getInstance();
-		cache = Git.getInstance().getStatusCache();
-		scanTask = rp.create(new ScanTask());
-	}
-
-	@Override
-	public String annotateName(String name, VCSContext context)
-	{
-		int includeStatus = StatusInfo.STATUS_VERSIONED_UPTODATE | StatusInfo.STATUS_LOCAL_CHANGE | StatusInfo.STATUS_NOTVERSIONED_EXCLUDED;
-
-		StatusInfo mostImportantInfo = null;
-		File mostImportantFile = null;
-		boolean folderAnnotation = false;
-
-		for (final File file : context.getRootFiles()) {
-			StatusInfo info = cache.getCachedStatus(file, true);
-			if (info == null) {
-				File parentFile = file.getParentFile();
-				Git.LOG.log(Level.FINE, &quot;null cached status for: {0} {1} {2}&quot;, new Object[]{file, folderToScan, parentFile});
-				folderToScan = parentFile;
-				reScheduleScan(1000);
-				info = new StatusInfo(StatusInfo.STATUS_VERSIONED_UPTODATE, false);
-			}
-			int status = info.getStatus();
-			if ((status &amp; includeStatus) == 0)
-				continue;
-
-			if (isMoreImportant(info, mostImportantInfo)) {
-				mostImportantInfo = info;
-				mostImportantFile = file;
-				folderAnnotation = file.isDirectory();
-			}
-		}
-
-		if (folderAnnotation == false &amp;&amp; context.getRootFiles().size() &gt; 1)
-			folderAnnotation = !Utils.shareCommonDataObject(context.getRootFiles().toArray(new File[context.getRootFiles().size()]));
-
-		if (mostImportantInfo == null)
-			return null;
-		if (folderAnnotation)
-			return format.annotateFolderNameHtml(name, mostImportantInfo, mostImportantFile);
-		return format.annotateNameHtml(name, mostImportantInfo, mostImportantFile);
-	}
-
-	@Override
-	public Image annotateIcon(Image icon, VCSContext context)
-	{
-		boolean folderAnnotation = false;
-		for (File file : context.getRootFiles()) {
-			if (file.isDirectory()) {
-				folderAnnotation = true;
-				break;
-			}
-		}
-
-		if (folderAnnotation == false &amp;&amp; context.getRootFiles().size() &gt; 1)
-			folderAnnotation = !Utils.shareCommonDataObject(context.getRootFiles().toArray(new File[context.getRootFiles().size()]));
-
-		if (folderAnnotation == false)
-			return null;
-
-		boolean isVersioned = false;
-		for (Iterator i = context.getRootFiles().iterator(); i.hasNext();) {
-			File file = (File) i.next();
-			// There is an assumption here that annotateName was already 
-			// called and StatusCache.getStatus was scheduled if
-			// StatusCache.getCachedStatus returned null.
-			StatusInfo info = cache.getCachedStatus(file, true);
-			if ((info != null &amp;&amp; (info.getStatus() &amp; STATUS_BADGEABLE) != 0)) {
-				isVersioned = true;
-				break;
-			}
-		}
-		if (!isVersioned)
-			return null;
-
-		boolean allExcluded = true;
-		boolean modified = false;
-
-		Map&lt;File, StatusInfo&gt; map = cache.getAllModifiedFiles();
-		Map&lt;File, StatusInfo&gt; modifiedFiles = new HashMap&lt;File, StatusInfo&gt;();
-		for (Iterator i = map.keySet().iterator(); i.hasNext();) {
-			File file = (File) i.next();
-			StatusInfo info = map.get(file);
-			if ((info.getStatus() &amp; StatusInfo.STATUS_LOCAL_CHANGE) != 0)
-				modifiedFiles.put(file, info);
-		}
-
-		for (Iterator i = context.getRootFiles().iterator(); i.hasNext();) {
-			File file = (File) i.next();
-			if (VersioningSupport.isFlat(file))
-				for (Iterator j = modifiedFiles.keySet().iterator(); j.hasNext();) {
-					File mf = (File) j.next();
-					if (mf.getParentFile().equals(file)) {
-						StatusInfo info = modifiedFiles.get(mf);
-						if (info.isDirectory())
-							continue;
-						int status = info.getStatus();
-						if (status == StatusInfo.STATUS_VERSIONED_CONFLICT) {
-							Image badge = Utilities.loadImage(&quot;org/nbgit/resources/icons/conflicts-badge.png&quot;, true);  // NOI18N
-							return Utilities.mergeImages(icon, badge, 16, 9);
-						}
-						modified = true;
-						allExcluded &amp;= isExcludedFromCommit(mf.getAbsolutePath());
-					}
-				}
-			else
-				for (Iterator j = modifiedFiles.keySet().iterator(); j.hasNext();) {
-					File mf = (File) j.next();
-					if (Utils.isAncestorOrEqual(file, mf)) {
-						StatusInfo info = modifiedFiles.get(mf);
-						int status = info.getStatus();
-						if ((status == StatusInfo.STATUS_NOTVERSIONED_NEWLOCALLY || status == StatusInfo.STATUS_VERSIONED_ADDEDLOCALLY) &amp;&amp; file.equals(mf))
-							continue;
-						if (status == StatusInfo.STATUS_VERSIONED_CONFLICT) {
-							Image badge = Utilities.loadImage(&quot;org/nbgit/resources/icons/conflicts-badge.png&quot;, true); // NOI18N
-							return Utilities.mergeImages(icon, badge, 16, 9);
-						}
-						modified = true;
-						allExcluded &amp;= isExcludedFromCommit(mf.getAbsolutePath());
-					}
-				}
-		}
-
-		if (modified &amp;&amp; !allExcluded) {
-			Image badge = Utilities.loadImage(&quot;org/nbgit/resources/icons/modified-badge.png&quot;, true); // NOI18N
-			return Utilities.mergeImages(icon, badge, 16, 9);
-		} else
-			return null;
-	}
-
-	@Override
-	public Action[] getActions(VCSContext ctx, VCSAnnotator.ActionDestination destination)
-	{
-		// TODO: get resource strings for all actions:
-		ResourceBundle loc = NbBundle.getBundle(GitAnnotator.class);
-		Node[] nodes = ctx.getElements().lookupAll(Node.class).toArray(new Node[0]);
-		File[] files = ctx.getRootFiles().toArray(new File[ctx.getRootFiles().size()]);
-		File root = GitUtils.getRootFile(ctx);
-		boolean noneVersioned = root == null;
-		boolean onlyFolders = onlyFolders(files);
-		boolean onlyProjects = onlyProjects(nodes);
-
-		List&lt;Action&gt; actions = new ArrayList&lt;Action&gt;(INITIAL_ACTION_ARRAY_LENGTH);
-		if (destination == VCSAnnotator.ActionDestination.MainMenu) {
-			actions.add(new InitAction(loc.getString(&quot;CTL_MenuItem_Create&quot;), ctx)); // NOI18N
-			actions.add(null);
-			actions.add(new StatusAction(loc.getString(&quot;CTL_PopupMenuItem_Status&quot;), ctx)); // NOI18N
-			actions.add(new DiffAction(loc.getString(&quot;CTL_PopupMenuItem_Diff&quot;), ctx)); // NOI18N
-			actions.add(new UpdateAction(loc.getString(&quot;CTL_PopupMenuItem_Update&quot;), ctx)); // NOI18N
-			actions.add(new CommitAction(loc.getString(&quot;CTL_PopupMenuItem_Commit&quot;), ctx)); // NOI18N
-			actions.add(null);
-			/*
-			actions.add(new ExportDiffAction(loc.getString(&quot;CTL_PopupMenuItem_ExportDiff&quot;), ctx)); // NOI18N
-			actions.add(new ApplyDiffAction(loc.getString(&quot;CTL_PopupMenuItem_ImportDiff&quot;), ctx)); // NOI18N
-			actions.add(null);
-			if (root != null) {
-			actions.add(new CloneAction(NbBundle.getMessage(GitAnnotator.class, &quot;CTL_PopupMenuItem_CloneLocal&quot;,  // NOI18N
-			root.getName()), ctx));
-			}
-			actions.add(new CloneExternalAction(loc.getString(&quot;CTL_PopupMenuItem_CloneOther&quot;), ctx));     // NOI18N        
-			actions.add(null);
-			actions.add(new FetchAction(NbBundle.getMessage(GitAnnotator.class, &quot;CTL_PopupMenuItem_FetchLocal&quot;), ctx)); // NOI18N
-			actions.add(new PushAction(NbBundle.getMessage(GitAnnotator.class, &quot;CTL_PopupMenuItem_PushLocal&quot;), ctx)); // NOI18N
-			actions.add(new PushOtherAction(loc.getString(&quot;CTL_PopupMenuItem_PushOther&quot;), ctx)); // NOI18N
-			actions.add(new PullAction(NbBundle.getMessage(GitAnnotator.class, &quot;CTL_PopupMenuItem_PullLocal&quot;), ctx)); // NOI18N
-			actions.add(new PullOtherAction(loc.getString(&quot;CTL_PopupMenuItem_PullOther&quot;), ctx)); // NOI18N
-			actions.add(new MergeAction(NbBundle.getMessage(GitAnnotator.class, &quot;CTL_PopupMenuItem_Merge&quot;), ctx)); // NOI18N
-			actions.add(null);
-			AnnotateAction tempA = new AnnotateAction(loc.getString(&quot;CTL_PopupMenuItem_ShowAnnotations&quot;), ctx); // NOI18N
-			if (tempA.visible(nodes))
-			tempA = new AnnotateAction(loc.getString(&quot;CTL_PopupMenuItem_HideAnnotations&quot;), ctx);
-			actions.add(tempA);
-			 */
-			actions.add(new LogAction(loc.getString(&quot;CTL_PopupMenuItem_Log&quot;), ctx)); // NOI18N
-		/*
-			actions.add(new IncomingAction(NbBundle.getMessage(GitAnnotator.class, &quot;CTL_PopupMenuItem_ShowIncoming&quot;), ctx)); // NOI18N
-			actions.add(new OutAction(NbBundle.getMessage(GitAnnotator.class, &quot;CTL_PopupMenuItem_ShowOut&quot;), ctx)); // NOI18N
-			actions.add(new ViewAction(loc.getString(&quot;CTL_PopupMenuItem_View&quot;), ctx)); // NOI18N
-			 */
-			actions.add(null);
-			actions.add(new RevertModificationsAction(NbBundle.getMessage(GitAnnotator.class, &quot;CTL_PopupMenuItem_Revert&quot;), ctx)); // NOI18N
-		/*
-			actions.add(new StashAction(NbBundle.getMessage(GitAnnotator.class, &quot;CTL_PopupMenuItem_Stash&quot;), ctx));
-			actions.add(new StripAction(NbBundle.getMessage(GitAnnotator.class, &quot;CTL_PopupMenuItem_Strip&quot;), ctx)); // NOI18N
-			actions.add(new BackoutAction(NbBundle.getMessage(GitAnnotator.class, &quot;CTL_PopupMenuItem_Backout&quot;), ctx)); // NOI18N
-			actions.add(new RollbackAction(NbBundle.getMessage(GitAnnotator.class, &quot;CTL_PopupMenuItem_Rollback&quot;), ctx)); // NOI18N
-			 * */
-			actions.add(new ResolveConflictsAction(NbBundle.getMessage(GitAnnotator.class, &quot;CTL_PopupMenuItem_Resolve&quot;), ctx)); // NOI18N
-		/*
-			if (!onlyProjects &amp;&amp; !onlyFolders) {
-			IgnoreAction tempIA = new IgnoreAction(loc.getString(&quot;CTL_PopupMenuItem_Ignore&quot;), ctx); // NOI18N
-			actions.add(tempIA);
-			}
-			 * */
-			actions.add(null);
-			actions.add(new PropertiesAction(loc.getString(&quot;CTL_PopupMenuItem_Properties&quot;), ctx)); // NOI18N
-		} else if (noneVersioned)
-			actions.add(new InitAction(loc.getString(&quot;CTL_PopupMenuItem_Create&quot;), ctx));
-		else {
-			actions.add(new StatusAction(loc.getString(&quot;CTL_PopupMenuItem_Status&quot;), ctx)); // NOI18N
-			actions.add(new DiffAction(loc.getString(&quot;CTL_PopupMenuItem_Diff&quot;), ctx)); // NOI18N
-			actions.add(new UpdateAction(loc.getString(&quot;CTL_PopupMenuItem_Update&quot;), ctx)); // NOI18N
-			actions.add(new CommitAction(loc.getString(&quot;CTL_PopupMenuItem_Commit&quot;), ctx)); // NOI18N
-			actions.add(null);
-			/*
-			if (root != null)
-			actions.add(new CloneAction(NbBundle.getMessage(GitAnnotator.class, &quot;CTL_PopupMenuItem_CloneLocal&quot;, // NOI18N
-			root.getName()), ctx));
-			
-			actions.add(null);
-			actions.add(new FetchAction(NbBundle.getMessage(GitAnnotator.class,
-			&quot;CTL_PopupMenuItem_FetchLocal&quot;), ctx)); // NOI18N
-			actions.add(new PushAction(NbBundle.getMessage(GitAnnotator.class,
-			&quot;CTL_PopupMenuItem_PushLocal&quot;), ctx)); // NOI18N
-			actions.add(new PullAction(NbBundle.getMessage(GitAnnotator.class,
-			&quot;CTL_PopupMenuItem_PullLocal&quot;), ctx)); // NOI18N
-			actions.add(new MergeAction(NbBundle.getMessage(GitAnnotator.class,
-			&quot;CTL_PopupMenuItem_Merge&quot;), ctx)); // NOI18N
-			actions.add(null);
-			if (!onlyFolders) {
-			AnnotateAction tempA = new AnnotateAction(loc.getString(&quot;CTL_PopupMenuItem_ShowAnnotations&quot;), ctx);  // NOI18N
-			if (tempA.visible(nodes))
-			tempA = new AnnotateAction(loc.getString(&quot;CTL_PopupMenuItem_HideAnnotations&quot;), ctx);
-			actions.add(tempA);
-			}
-			 */
-			actions.add(new LogAction(loc.getString(&quot;CTL_PopupMenuItem_Log&quot;), ctx)); // NOI18N
-		/*
-			actions.add(new IncomingAction(NbBundle.getMessage(GitAnnotator.class, &quot;CTL_PopupMenuItem_ShowIncoming&quot;), ctx)); // NOI18N
-			actions.add(new OutAction(NbBundle.getMessage(GitAnnotator.class, &quot;CTL_PopupMenuItem_ShowOut&quot;), ctx)); // NOI18N
-			actions.add(new ViewAction(loc.getString(&quot;CTL_PopupMenuItem_View&quot;), ctx)); // NOI18N
-			 */
-			actions.add(null);
-			actions.add(new RevertModificationsAction(NbBundle.getMessage(GitAnnotator.class,
-				&quot;CTL_PopupMenuItem_Revert&quot;), ctx)); // NOI18N
-		/*
-			actions.add(new StripAction(NbBundle.getMessage(GitAnnotator.class, &quot;CTL_PopupMenuItem_Strip&quot;), ctx)); // NOI18N
-			actions.add(new BackoutAction(NbBundle.getMessage(GitAnnotator.class, &quot;CTL_PopupMenuItem_Backout&quot;), ctx)); // NOI18N
-			actions.add(new RollbackAction(NbBundle.getMessage(GitAnnotator.class, &quot;CTL_PopupMenuItem_Rollback&quot;), ctx)); // NOI18N
-			 * */
-			actions.add(new ResolveConflictsAction(NbBundle.getMessage(GitAnnotator.class,
-				&quot;CTL_PopupMenuItem_Resolve&quot;), ctx)); // NOI18N
-			if (!onlyProjects &amp;&amp; !onlyFolders)
-				actions.add(new ConflictResolvedAction(NbBundle.getMessage(GitAnnotator.class,
-					&quot;CTL_PopupMenuItem_MarkResolved&quot;), ctx));
-		/*
-			if (!onlyProjects &amp;&amp; !onlyFolders) {
-			IgnoreAction tempIA = new IgnoreAction(loc.getString(&quot;CTL_PopupMenuItem_Ignore&quot;), ctx); // NOI18N
-			actions.add(tempIA);
-			}
-			 * */
-			actions.add(null);
-			actions.add(new PropertiesAction(loc.getString(&quot;CTL_PopupMenuItem_Properties&quot;), ctx)); // NOI18N
-		}
-
-		return actions.toArray(new Action[actions.size()]);
-	}
-
-	private boolean isMoreImportant(StatusInfo a, StatusInfo b)
-	{
-		if (b == null)
-			return true;
-		if (a == null)
-			return false;
-		return GitUtils.getComparableStatus(a.getStatus()) &lt; GitUtils.getComparableStatus(b.getStatus());
-	}
-
-	private boolean isExcludedFromCommit(String absolutePath)
-	{
-		return false;
-	}
-
-	private boolean isNothingVersioned(File[] files)
-	{
-		for (File file : files) {
-			if ((cache.getStatus(file).getStatus() &amp; StatusInfo.STATUS_MANAGED) != 0)
-				return false;
-		}
-		return true;
-	}
-
-	private static boolean onlyProjects(Node[] nodes)
-	{
-		if (nodes == null)
-			return false;
-		for (Node node : nodes) {
-			if (node.getLookup().lookup(Project.class) == null)
-				return false;
-		}
-		return true;
-	}
-
-	private boolean onlyFolders(File[] files)
-	{
-		for (int i = 0; i &lt; files.length; i++) {
-			if (files[i].isFile())
-				return false;
-			if (!files[i].exists() &amp;&amp; !cache.getStatus(files[i]).isDirectory())
-				return false;
-		}
-		return true;
-	}
-
-	private void reScheduleScan(int delayMillis)
-	{
-		File dirToScan = dirsToScan.peek();
-		if (!folderToScan.equals(dirToScan))
-			if (!dirsToScan.offer(folderToScan))
-				Git.LOG.log(Level.FINE, &quot;reScheduleScan failed to add to dirsToScan queue: {0} &quot;, folderToScan);
-		scanTask.schedule(delayMillis);
-	}
-
-	private class ScanTask implements Runnable {
-
-		public void run()
-		{
-			Thread.interrupted();
-			File dirToScan = dirsToScan.poll();
-			if (dirToScan != null) {
-				cache.getScannedFiles(dirToScan, null);
-				dirToScan = dirsToScan.peek();
-				if (dirToScan != null)
-					scanTask.schedule(1000);
-			}
-		}
-
-	}
+    private static final int INITIAL_ACTION_ARRAY_LENGTH = 25;
+    private static final int STATUS_BADGEABLE =
+        StatusInfo.STATUS_VERSIONED_UPTODATE |
+        StatusInfo.STATUS_NOTVERSIONED_NEWLOCALLY |
+        StatusInfo.STATUS_VERSIONED_MODIFIEDLOCALLY;
+    public static String ANNOTATION_REVISION = &quot;revision&quot;; // NOI18N
+    public static String ANNOTATION_STATUS = &quot;status&quot;; // NOI18N
+    public static String ANNOTATION_FOLDER = &quot;folder&quot;; // NOI18N
+    public static String[] LABELS = new String[]{ANNOTATION_REVISION, ANNOTATION_STATUS, ANNOTATION_FOLDER};
+    private StatusCache cache;
+    private File folderToScan;
+    private ConcurrentLinkedQueue&lt;File&gt; dirsToScan = new ConcurrentLinkedQueue&lt;File&gt;();
+    private RequestProcessor.Task scanTask;
+    private static final RequestProcessor rp = new RequestProcessor(&quot;GitAnnotateScan&quot;, 1, true); // NOI18N
+    private final HtmlFormatter format;
+
+    public GitAnnotator()
+    {
+        format = HtmlFormatter.getInstance();
+        cache = Git.getInstance().getStatusCache();
+        scanTask = rp.create(new ScanTask());
+    }
+
+    @Override
+    public String annotateName(String name, VCSContext context)
+    {
+        int includeStatus = StatusInfo.STATUS_VERSIONED_UPTODATE | StatusInfo.STATUS_LOCAL_CHANGE | StatusInfo.STATUS_NOTVERSIONED_EXCLUDED;
+
+        StatusInfo mostImportantInfo = null;
+        File mostImportantFile = null;
+        boolean folderAnnotation = false;
+
+        for (final File file : context.getRootFiles()) {
+            StatusInfo info = cache.getCachedStatus(file, true);
+            if (info == null) {
+                File parentFile = file.getParentFile();
+                Git.LOG.log(Level.FINE, &quot;null cached status for: {0} {1} {2}&quot;, new Object[]{file, folderToScan, parentFile});
+                folderToScan = parentFile;
+                reScheduleScan(1000);
+                info = new StatusInfo(StatusInfo.STATUS_VERSIONED_UPTODATE, false);
+            }
+            int status = info.getStatus();
+            if ((status &amp; includeStatus) == 0)
+                continue;
+
+            if (isMoreImportant(info, mostImportantInfo)) {
+                mostImportantInfo = info;
+                mostImportantFile = file;
+                folderAnnotation = file.isDirectory();
+            }
+        }
+
+        if (folderAnnotation == false &amp;&amp; context.getRootFiles().size() &gt; 1)
+            folderAnnotation = !Utils.shareCommonDataObject(context.getRootFiles().toArray(new File[context.getRootFiles().size()]));
+
+        if (mostImportantInfo == null)
+            return null;
+        if (folderAnnotation)
+            return format.annotateFolderNameHtml(name, mostImportantInfo, mostImportantFile);
+        return format.annotateNameHtml(name, mostImportantInfo, mostImportantFile);
+    }
+
+    @Override
+    public Image annotateIcon(Image icon, VCSContext context)
+    {
+        boolean folderAnnotation = false;
+        for (File file : context.getRootFiles()) {
+            if (file.isDirectory()) {
+                folderAnnotation = true;
+                break;
+            }
+        }
+
+        if (folderAnnotation == false &amp;&amp; context.getRootFiles().size() &gt; 1)
+            folderAnnotation = !Utils.shareCommonDataObject(context.getRootFiles().toArray(new File[context.getRootFiles().size()]));
+
+        if (folderAnnotation == false)
+            return null;
+
+        boolean isVersioned = false;
+        for (Iterator i = context.getRootFiles().iterator(); i.hasNext();) {
+            File file = (File) i.next();
+            // There is an assumption here that annotateName was already
+            // called and StatusCache.getStatus was scheduled if
+            // StatusCache.getCachedStatus returned null.
+            StatusInfo info = cache.getCachedStatus(file, true);
+            if ((info != null &amp;&amp; (info.getStatus() &amp; STATUS_BADGEABLE) != 0)) {
+                isVersioned = true;
+                break;
+            }
+        }
+        if (!isVersioned)
+            return null;
+
+        boolean allExcluded = true;
+        boolean modified = false;
+
+        Map&lt;File, StatusInfo&gt; map = cache.getAllModifiedFiles();
+        Map&lt;File, StatusInfo&gt; modifiedFiles = new HashMap&lt;File, StatusInfo&gt;();
+        for (Iterator i = map.keySet().iterator(); i.hasNext();) {
+            File file = (File) i.next();
+            StatusInfo info = map.get(file);
+            if ((info.getStatus() &amp; StatusInfo.STATUS_LOCAL_CHANGE) != 0)
+                modifiedFiles.put(file, info);
+        }
+
+        for (Iterator i = context.getRootFiles().iterator(); i.hasNext();) {
+            File file = (File) i.next();
+            if (VersioningSupport.isFlat(file))
+                for (Iterator j = modifiedFiles.keySet().iterator(); j.hasNext();) {
+                    File mf = (File) j.next();
+                    if (mf.getParentFile().equals(file)) {
+                        StatusInfo info = modifiedFiles.get(mf);
+                        if (info.isDirectory())
+                            continue;
+                        int status = info.getStatus();
+                        if (status == StatusInfo.STATUS_VERSIONED_CONFLICT) {
+                            Image badge = Utilities.loadImage(&quot;org/nbgit/resources/icons/conflicts-badge.png&quot;, true);  // NOI18N
+                            return Utilities.mergeImages(icon, badge, 16, 9);
+                        }
+                        modified = true;
+                        allExcluded &amp;= isExcludedFromCommit(mf.getAbsolutePath());
+                    }
+                }
+            else
+                for (Iterator j = modifiedFiles.keySet().iterator(); j.hasNext();) {
+                    File mf = (File) j.next();
+                    if (Utils.isAncestorOrEqual(file, mf)) {
+                        StatusInfo info = modifiedFiles.get(mf);
+                        int status = info.getStatus();
+                        if ((status == StatusInfo.STATUS_NOTVERSIONED_NEWLOCALLY || status == StatusInfo.STATUS_VERSIONED_ADDEDLOCALLY) &amp;&amp; file.equals(mf))
+                            continue;
+                        if (status == StatusInfo.STATUS_VERSIONED_CONFLICT) {
+                            Image badge = Utilities.loadImage(&quot;org/nbgit/resources/icons/conflicts-badge.png&quot;, true); // NOI18N
+                            return Utilities.mergeImages(icon, badge, 16, 9);
+                        }
+                        modified = true;
+                        allExcluded &amp;= isExcludedFromCommit(mf.getAbsolutePath());
+                    }
+                }
+        }
+
+        if (modified &amp;&amp; !allExcluded) {
+            Image badge = Utilities.loadImage(&quot;org/nbgit/resources/icons/modified-badge.png&quot;, true); // NOI18N
+            return Utilities.mergeImages(icon, badge, 16, 9);
+        } else
+            return null;
+    }
+
+    @Override
+    public Action[] getActions(VCSContext ctx, VCSAnnotator.ActionDestination destination)
+    {
+        // TODO: get resource strings for all actions:
+        ResourceBundle loc = NbBundle.getBundle(GitAnnotator.class);
+        Node[] nodes = ctx.getElements().lookupAll(Node.class).toArray(new Node[0]);
+        File[] files = ctx.getRootFiles().toArray(new File[ctx.getRootFiles().size()]);
+        File root = GitUtils.getRootFile(ctx);
+        boolean noneVersioned = root == null;
+        boolean onlyFolders = onlyFolders(files);
+        boolean onlyProjects = onlyProjects(nodes);
+
+        List&lt;Action&gt; actions = new ArrayList&lt;Action&gt;(INITIAL_ACTION_ARRAY_LENGTH);
+        if (destination == VCSAnnotator.ActionDestination.MainMenu) {
+            actions.add(new InitAction(loc.getString(&quot;CTL_MenuItem_Create&quot;), ctx)); // NOI18N
+            actions.add(null);
+            actions.add(new StatusAction(loc.getString(&quot;CTL_PopupMenuItem_Status&quot;), ctx)); // NOI18N
+            actions.add(new DiffAction(loc.getString(&quot;CTL_PopupMenuItem_Diff&quot;), ctx)); // NOI18N
+            actions.add(new UpdateAction(loc.getString(&quot;CTL_PopupMenuItem_Update&quot;), ctx)); // NOI18N
+            actions.add(new CommitAction(loc.getString(&quot;CTL_PopupMenuItem_Commit&quot;), ctx)); // NOI18N
+            actions.add(null);
+            /*
+            actions.add(new ExportDiffAction(loc.getString(&quot;CTL_PopupMenuItem_ExportDiff&quot;), ctx)); // NOI18N
+            actions.add(new ApplyDiffAction(loc.getString(&quot;CTL_PopupMenuItem_ImportDiff&quot;), ctx)); // NOI18N
+            actions.add(null);
+            if (root != null) {
+            actions.add(new CloneAction(NbBundle.getMessage(GitAnnotator.class, &quot;CTL_PopupMenuItem_CloneLocal&quot;,  // NOI18N
+            root.getName()), ctx));
+            }
+            actions.add(new CloneExternalAction(loc.getString(&quot;CTL_PopupMenuItem_CloneOther&quot;), ctx));     // NOI18N
+            actions.add(null);
+            actions.add(new FetchAction(NbBundle.getMessage(GitAnnotator.class, &quot;CTL_PopupMenuItem_FetchLocal&quot;), ctx)); // NOI18N
+            actions.add(new PushAction(NbBundle.getMessage(GitAnnotator.class, &quot;CTL_PopupMenuItem_PushLocal&quot;), ctx)); // NOI18N
+            actions.add(new PushOtherAction(loc.getString(&quot;CTL_PopupMenuItem_PushOther&quot;), ctx)); // NOI18N
+            actions.add(new PullAction(NbBundle.getMessage(GitAnnotator.class, &quot;CTL_PopupMenuItem_PullLocal&quot;), ctx)); // NOI18N
+            actions.add(new PullOtherAction(loc.getString(&quot;CTL_PopupMenuItem_PullOther&quot;), ctx)); // NOI18N
+            actions.add(new MergeAction(NbBundle.getMessage(GitAnnotator.class, &quot;CTL_PopupMenuItem_Merge&quot;), ctx)); // NOI18N
+            actions.add(null);
+            AnnotateAction tempA = new AnnotateAction(loc.getString(&quot;CTL_PopupMenuItem_ShowAnnotations&quot;), ctx); // NOI18N
+            if (tempA.visible(nodes))
+            tempA = new AnnotateAction(loc.getString(&quot;CTL_PopupMenuItem_HideAnnotations&quot;), ctx);
+            actions.add(tempA);
+             */
+            actions.add(new LogAction(loc.getString(&quot;CTL_PopupMenuItem_Log&quot;), ctx)); // NOI18N
+        /*
+            actions.add(new IncomingAction(NbBundle.getMessage(GitAnnotator.class, &quot;CTL_PopupMenuItem_ShowIncoming&quot;), ctx)); // NOI18N
+            actions.add(new OutAction(NbBundle.getMessage(GitAnnotator.class, &quot;CTL_PopupMenuItem_ShowOut&quot;), ctx)); // NOI18N
+            actions.add(new ViewAction(loc.getString(&quot;CTL_PopupMenuItem_View&quot;), ctx)); // NOI18N
+             */
+            actions.add(null);
+            actions.add(new RevertModificationsAction(NbBundle.getMessage(GitAnnotator.class, &quot;CTL_PopupMenuItem_Revert&quot;), ctx)); // NOI18N
+        /*
+            actions.add(new StashAction(NbBundle.getMessage(GitAnnotator.class, &quot;CTL_PopupMenuItem_Stash&quot;), ctx));
+            actions.add(new StripAction(NbBundle.getMessage(GitAnnotator.class, &quot;CTL_PopupMenuItem_Strip&quot;), ctx)); // NOI18N
+            actions.add(new BackoutAction(NbBundle.getMessage(GitAnnotator.class, &quot;CTL_PopupMenuItem_Backout&quot;), ctx)); // NOI18N
+            actions.add(new RollbackAction(NbBundle.getMessage(GitAnnotator.class, &quot;CTL_PopupMenuItem_Rollback&quot;), ctx)); // NOI18N
+             * */
+            actions.add(new ResolveConflictsAction(NbBundle.getMessage(GitAnnotator.class, &quot;CTL_PopupMenuItem_Resolve&quot;), ctx)); // NOI18N
+        /*
+            if (!onlyProjects &amp;&amp; !onlyFolders) {
+            IgnoreAction tempIA = new IgnoreAction(loc.getString(&quot;CTL_PopupMenuItem_Ignore&quot;), ctx); // NOI18N
+            actions.add(tempIA);
+            }
+             * */
+            actions.add(null);
+            actions.add(new PropertiesAction(loc.getString(&quot;CTL_PopupMenuItem_Properties&quot;), ctx)); // NOI18N
+        } else if (noneVersioned)
+            actions.add(new InitAction(loc.getString(&quot;CTL_PopupMenuItem_Create&quot;), ctx));
+        else {
+            actions.add(new StatusAction(loc.getString(&quot;CTL_PopupMenuItem_Status&quot;), ctx)); // NOI18N
+            actions.add(new DiffAction(loc.getString(&quot;CTL_PopupMenuItem_Diff&quot;), ctx)); // NOI18N
+            actions.add(new UpdateAction(loc.getString(&quot;CTL_PopupMenuItem_Update&quot;), ctx)); // NOI18N
+            actions.add(new CommitAction(loc.getString(&quot;CTL_PopupMenuItem_Commit&quot;), ctx)); // NOI18N
+            actions.add(null);
+            /*
+            if (root != null)
+            actions.add(new CloneAction(NbBundle.getMessage(GitAnnotator.class, &quot;CTL_PopupMenuItem_CloneLocal&quot;, // NOI18N
+            root.getName()), ctx));
+
+            actions.add(null);
+            actions.add(new FetchAction(NbBundle.getMessage(GitAnnotator.class,
+            &quot;CTL_PopupMenuItem_FetchLocal&quot;), ctx)); // NOI18N
+            actions.add(new PushAction(NbBundle.getMessage(GitAnnotator.class,
+            &quot;CTL_PopupMenuItem_PushLocal&quot;), ctx)); // NOI18N
+            actions.add(new PullAction(NbBundle.getMessage(GitAnnotator.class,
+            &quot;CTL_PopupMenuItem_PullLocal&quot;), ctx)); // NOI18N
+            actions.add(new MergeAction(NbBundle.getMessage(GitAnnotator.class,
+            &quot;CTL_PopupMenuItem_Merge&quot;), ctx)); // NOI18N
+            actions.add(null);
+            if (!onlyFolders) {
+            AnnotateAction tempA = new AnnotateAction(loc.getString(&quot;CTL_PopupMenuItem_ShowAnnotations&quot;), ctx);  // NOI18N
+            if (tempA.visible(nodes))
+            tempA = new AnnotateAction(loc.getString(&quot;CTL_PopupMenuItem_HideAnnotations&quot;), ctx);
+            actions.add(tempA);
+            }
+             */
+            actions.add(new LogAction(loc.getString(&quot;CTL_PopupMenuItem_Log&quot;), ctx)); // NOI18N
+        /*
+            actions.add(new IncomingAction(NbBundle.getMessage(GitAnnotator.class, &quot;CTL_PopupMenuItem_ShowIncoming&quot;), ctx)); // NOI18N
+            actions.add(new OutAction(NbBundle.getMessage(GitAnnotator.class, &quot;CTL_PopupMenuItem_ShowOut&quot;), ctx)); // NOI18N
+            actions.add(new ViewAction(loc.getString(&quot;CTL_PopupMenuItem_View&quot;), ctx)); // NOI18N
+             */
+            actions.add(null);
+            actions.add(new RevertModificationsAction(NbBundle.getMessage(GitAnnotator.class,
+                &quot;CTL_PopupMenuItem_Revert&quot;), ctx)); // NOI18N
+        /*
+            actions.add(new StripAction(NbBundle.getMessage(GitAnnotator.class, &quot;CTL_PopupMenuItem_Strip&quot;), ctx)); // NOI18N
+            actions.add(new BackoutAction(NbBundle.getMessage(GitAnnotator.class, &quot;CTL_PopupMenuItem_Backout&quot;), ctx)); // NOI18N
+            actions.add(new RollbackAction(NbBundle.getMessage(GitAnnotator.class, &quot;CTL_PopupMenuItem_Rollback&quot;), ctx)); // NOI18N
+             * */
+            actions.add(new ResolveConflictsAction(NbBundle.getMessage(GitAnnotator.class,
+                &quot;CTL_PopupMenuItem_Resolve&quot;), ctx)); // NOI18N
+            if (!onlyProjects &amp;&amp; !onlyFolders)
+                actions.add(new ConflictResolvedAction(NbBundle.getMessage(GitAnnotator.class,
+                    &quot;CTL_PopupMenuItem_MarkResolved&quot;), ctx));
+        /*
+            if (!onlyProjects &amp;&amp; !onlyFolders) {
+            IgnoreAction tempIA = new IgnoreAction(loc.getString(&quot;CTL_PopupMenuItem_Ignore&quot;), ctx); // NOI18N
+            actions.add(tempIA);
+            }
+             * */
+            actions.add(null);
+            actions.add(new PropertiesAction(loc.getString(&quot;CTL_PopupMenuItem_Properties&quot;), ctx)); // NOI18N
+        }
+
+        return actions.toArray(new Action[actions.size()]);
+    }
+
+    private boolean isMoreImportant(StatusInfo a, StatusInfo b)
+    {
+        if (b == null)
+            return true;
+        if (a == null)
+            return false;
+        return GitUtils.getComparableStatus(a.getStatus()) &lt; GitUtils.getComparableStatus(b.getStatus());
+    }
+
+    private boolean isExcludedFromCommit(String absolutePath)
+    {
+        return false;
+    }
+
+    private boolean isNothingVersioned(File[] files)
+    {
+        for (File file : files) {
+            if ((cache.getStatus(file).getStatus() &amp; StatusInfo.STATUS_MANAGED) != 0)
+                return false;
+        }
+        return true;
+    }
+
+    private static boolean onlyProjects(Node[] nodes)
+    {
+        if (nodes == null)
+            return false;
+        for (Node node : nodes) {
+            if (node.getLookup().lookup(Project.class) == null)
+                return false;
+        }
+        return true;
+    }
+
+    private boolean onlyFolders(File[] files)
+    {
+        for (int i = 0; i &lt; files.length; i++) {
+            if (files[i].isFile())
+                return false;
+            if (!files[i].exists() &amp;&amp; !cache.getStatus(files[i]).isDirectory())
+                return false;
+        }
+        return true;
+    }
+
+    private void reScheduleScan(int delayMillis)
+    {
+        File dirToScan = dirsToScan.peek();
+        if (!folderToScan.equals(dirToScan))
+            if (!dirsToScan.offer(folderToScan))
+                Git.LOG.log(Level.FINE, &quot;reScheduleScan failed to add to dirsToScan queue: {0} &quot;, folderToScan);
+        scanTask.schedule(delayMillis);
+    }
+
+    private class ScanTask implements Runnable {
+
+        public void run()
+        {
+            Thread.interrupted();
+            File dirToScan = dirsToScan.poll();
+            if (dirToScan != null) {
+                cache.getScannedFiles(dirToScan, null);
+                dirToScan = dirsToScan.peek();
+                if (dirToScan != null)
+                    scanTask.schedule(1000);
+            }
+        }
+
+    }
 
 }</diff>
      <filename>src/org/nbgit/GitAnnotator.java</filename>
    </modified>
    <modified>
      <diff>@@ -58,381 +58,381 @@ import org.openide.util.RequestProcessor;
 
 /**
  * Listens on file system changes and reacts appropriately, mainly refreshing affected files' status.
- * 
+ *
  * @author Maros Sandor
  */
 public class GitInterceptor extends VCSInterceptor {
 
-	private final StatusCache cache;
-	private ConcurrentHashMap&lt;File, File&gt; dirsToDelete = new ConcurrentHashMap&lt;File, File&gt;();
-	private ConcurrentLinkedQueue&lt;File&gt; filesToRefresh = new ConcurrentLinkedQueue&lt;File&gt;();
-	private RequestProcessor.Task refreshTask;
-	private static final RequestProcessor refresh = new RequestProcessor(&quot;GitRefresh&quot;, 1, true);
-
-	public GitInterceptor()
-	{
-		cache = Git.getInstance().getStatusCache();
-		refreshTask = refresh.create(new RefreshTask());
-	}
-
-	@Override
-	public boolean beforeDelete(File file)
-	{
-		if (file == null)
-			return true;
-		if (GitUtils.isPartOfGitMetadata(file))
-			return false;
-
-		// We track the deletion of top level directories
-		if (file.isDirectory()) {
-			for (File dir : dirsToDelete.keySet()) {
-				if (file.equals(dir.getParentFile()))
-					dirsToDelete.remove(dir);
-			}
-			if (GitIgnore.isSharable(file))
-				dirsToDelete.put(file, file);
-		}
-		return true;
-	}
-
-	@Override
-	public void doDelete(File file) throws IOException
-	{
-	}
-
-	@Override
-	public void afterDelete(final File file)
-	{
-		Utils.post(new Runnable() {
-
-			public void run()
-			{
-				fileDeletedImpl(file);
-			}
-
-		});
-	}
-
-	private void fileDeletedImpl(final File file)
-	{
-		if (file == null || !file.exists())
-			return;
-
-		Git git = Git.getInstance();
-		final File root = git.getTopmostManagedParent(file);
-		RequestProcessor rp = null;
-		if (root != null)
-			rp = git.getRequestProcessor(root.getAbsolutePath());
-
-		if (file.isDirectory()) {
-			file.delete();
-			if (!dirsToDelete.remove(file, file))
-				return;
-			if (root == null)
-				return;
-			GitProgressSupport support = new GitProgressSupport() {
-
-				public void perform()
-				{
-					GitCommand.doRemove(root, file, this.getLogger());
-					// We need to cache the status of all deleted files
-					Map&lt;File, StatusInfo&gt; interestingFiles = GitCommand.getInterestingStatus(root, file);
-					if (!interestingFiles.isEmpty()) {
-						Collection&lt;File&gt; files = interestingFiles.keySet();
-
-						Map&lt;File, Map&lt;File, StatusInfo&gt;&gt; interestingDirs =
-							GitUtils.getInterestingDirs(interestingFiles, files);
-
-						for (File tmpFile : files) {
-							if (this.isCanceled())
-								return;
-							StatusInfo fi = interestingFiles.get(tmpFile);
-
-							cache.refreshFileStatus(tmpFile, fi,
-								interestingDirs.get(tmpFile.isDirectory() ? tmpFile : tmpFile.getParentFile()), true);
-						}
-					}
-				}
-
-			};
-
-			support.start(rp, root.getAbsolutePath(),
-				org.openide.util.NbBundle.getMessage(GitInterceptor.class, &quot;MSG_Remove_Progress&quot;)); // NOI18N
-		} else {
-			// If we are deleting a parent directory of this file
-			// skip the call to git remove as we will do it for the directory
-			file.delete();
-			if (root == null)
-				return;
-			for (File dir : dirsToDelete.keySet()) {
-				File tmpFile = file.getParentFile();
-				while (tmpFile != null) {
-					if (tmpFile.equals(dir))
-						return;
-					tmpFile = tmpFile.getParentFile();
-				}
-			}
-			GitProgressSupport support = new GitProgressSupport() {
-
-				public void perform()
-				{
-					GitCommand.doRemove(root, file, this.getLogger());
-					cache.refresh(file, StatusCache.REPOSITORY_STATUS_UNKNOWN);
-				}
-
-			};
-			support.start(rp, root.getAbsolutePath(),
-				org.openide.util.NbBundle.getMessage(GitInterceptor.class, &quot;MSG_Remove_Progress&quot;)); // NOI18N
-		}
-	}
-
-	@Override
-	public boolean beforeMove(File from, File to)
-	{
-		if (from == null || to == null || to.exists())
-			return true;
-
-		Git git = Git.getInstance();
-		if (git.isManaged(from))
-			return git.isManaged(to);
-		return super.beforeMove(from, to);
-	}
-
-	@Override
-	public void doMove(final File from, final File to) throws IOException
-	{
-		if (from == null || to == null || to.exists())
-			return;
-
-		if (SwingUtilities.isEventDispatchThread()) {
-
-			Git.LOG.log(Level.INFO, &quot;Warning: launching external process in AWT&quot;, new Exception().fillInStackTrace()); // NOI18N
-			final Throwable innerT[] = new Throwable[1];
-			Runnable outOfAwt = new Runnable() {
-
-				public void run()
-				{
-					try {
-						gitMoveImplementation(from, to);
-					} catch (Throwable t) {
-						innerT[0] = t;
-					}
-				}
-
-			};
-
-			Git.getInstance().getRequestProcessor().post(outOfAwt).waitFinished();
-			if (innerT[0] != null)
-				if (innerT[0] instanceof IOException)
-					throw (IOException) innerT[0];
-				else if (innerT[0] instanceof RuntimeException)
-					throw (RuntimeException) innerT[0];
-				else if (innerT[0] instanceof Error)
-					throw (Error) innerT[0];
-				else
-					throw new IllegalStateException(&quot;Unexpected exception class: &quot; + innerT[0]);
-
-		// end of hack
-
-		} else
-			gitMoveImplementation(from, to);
-	}
-
-	private void gitMoveImplementation(final File srcFile, final File dstFile) throws IOException
-	{
-		final Git git = Git.getInstance();
-		final File root = git.getTopmostManagedParent(srcFile);
-		if (root == null)
-			return;
-
-		RequestProcessor rp = git.getRequestProcessor(root.getAbsolutePath());
-
-		Git.LOG.log(Level.FINE, &quot;gitMoveImplementation(): File: {0} {1}&quot;, new Object[]{srcFile, dstFile}); // NOI18N
-
-		srcFile.renameTo(dstFile);
-		Runnable moveImpl = new Runnable() {
-
-			public void run()
-			{
-				OutputLogger logger = OutputLogger.getLogger(root.getAbsolutePath());
-				try {
-					if (dstFile.isDirectory()) {
-						GitCommand.doRenameAfter(root, srcFile, dstFile, logger);
-						return;
-					}
-					int status = GitCommand.getSingleStatus(root, srcFile).getStatus();
-					Git.LOG.log(Level.FINE, &quot;gitMoveImplementation(): Status: {0} {1}&quot;, new Object[]{srcFile, status}); // NOI18N
-					if (status == StatusInfo.STATUS_NOTVERSIONED_NEWLOCALLY ||
-						status == StatusInfo.STATUS_NOTVERSIONED_EXCLUDED) {
-					} else if (status == StatusInfo.STATUS_VERSIONED_ADDEDLOCALLY) {
-						GitCommand.doRemove(root, srcFile, logger);
-						GitCommand.doAdd(root, dstFile, logger);
-					} else
-						GitCommand.doRenameAfter(root, srcFile, dstFile, logger);
-				} catch (Exception e) {
-					Git.LOG.log(Level.FINE, &quot;Git failed to rename: File: {0} {1}&quot;, new Object[]{srcFile.getAbsolutePath(), dstFile.getAbsolutePath()}); // NOI18N
-				} finally {
-					logger.closeLog();
-				}
-			}
-
-		};
-
-		rp.post(moveImpl);
-	}
-
-	@Override
-	public void afterMove(final File from, final File to)
-	{
-		Utils.post(new Runnable() {
-
-			public void run()
-			{
-				fileMovedImpl(from, to);
-			}
-
-		});
-	}
-
-	private void fileMovedImpl(final File from, final File to)
-	{
-		if (from == null || to == null || !to.exists())
-			return;
-		if (to.isDirectory())
-			return;
-		Git git = Git.getInstance();
-		final File root = git.getTopmostManagedParent(from);
-		if (root == null)
-			return;
-
-		RequestProcessor rp = git.getRequestProcessor(root.getAbsolutePath());
-
-		GitProgressSupport supportCreate = new GitProgressSupport() {
-
-			public void perform()
-			{
-				cache.refresh(from, StatusCache.REPOSITORY_STATUS_UNKNOWN);
-				cache.refresh(to, StatusCache.REPOSITORY_STATUS_UNKNOWN);
-			}
-
-		};
-
-		supportCreate.start(rp, root.getAbsolutePath(),
-			org.openide.util.NbBundle.getMessage(GitInterceptor.class, &quot;MSG_Move_Progress&quot;)); // NOI18N
-	}
-
-	@Override
-	public boolean beforeCreate(File file, boolean isDirectory)
-	{
-		return super.beforeCreate(file, isDirectory);
-	}
-
-	@Override
-	public void doCreate(File file, boolean isDirectory) throws IOException
-	{
-		super.doCreate(file, isDirectory);
-	}
-
-	@Override
-	public void afterCreate(final File file)
-	{
-		Utils.post(new Runnable() {
-
-			public void run()
-			{
-				fileCreatedImpl(file);
-			}
-
-		});
-	}
-
-	private void fileCreatedImpl(final File file)
-	{
-		if (file.isDirectory())
-			return;
-		Git git = Git.getInstance();
-		final File root = git.getTopmostManagedParent(file);
-		if (root == null)
-			return;
-
-		RequestProcessor rp = git.getRequestProcessor(root.getAbsolutePath());
-
-		GitProgressSupport supportCreate = new GitProgressSupport() {
-
-			public void perform()
-			{
-				reScheduleRefresh(file);
-			}
-
-		};
-
-		supportCreate.start(rp, root.getAbsolutePath(),
-			org.openide.util.NbBundle.getMessage(GitInterceptor.class, &quot;MSG_Create_Progress&quot;)); // NOI18N
-	}
-
-	@Override
-	public void afterChange(final File file)
-	{
-		Utils.post(new Runnable() {
-
-			public void run()
-			{
-				fileChangedImpl(file);
-			}
-
-		});
-	}
-
-	private void fileChangedImpl(final File file)
-	{
-		if (file.isDirectory())
-			return;
-		Git git = Git.getInstance();
-		final File root = git.getTopmostManagedParent(file);
-		if (root == null)
-			return;
-
-		RequestProcessor rp = git.getRequestProcessor(root.getAbsolutePath());
-
-		GitProgressSupport supportCreate = new GitProgressSupport() {
-
-			public void perform()
-			{
-				Git.LOG.log(Level.FINE, &quot;fileChangedImpl(): File: {0}&quot;, file); // NOI18N
-				reScheduleRefresh(file);
-			}
-
-		};
-
-		supportCreate.start(rp, root.getAbsolutePath(),
-			org.openide.util.NbBundle.getMessage(GitInterceptor.class, &quot;MSG_Change_Progress&quot;)); // NOI18N
-	}
-
-	private void reScheduleRefresh(File fileToRefresh)
-	{
-		// There is no point in refreshing the cache for ignored files.
-		if (GitIgnore.isIgnored(fileToRefresh, false))
-			return;
-		if (!filesToRefresh.contains(fileToRefresh))
-			if (!filesToRefresh.offer(fileToRefresh))
-				Git.LOG.log(Level.FINE, &quot;reScheduleRefresh failed to add to filesToRefresh queue {0}&quot;, fileToRefresh);
-		refreshTask.schedule(1000);
-	}
-
-	private class RefreshTask implements Runnable {
-
-		public void run()
-		{
-			Thread.interrupted();
-			File fileToRefresh = filesToRefresh.poll();
-			if (fileToRefresh != null) {
-				cache.refresh(fileToRefresh, StatusCache.REPOSITORY_STATUS_UNKNOWN);
-				fileToRefresh = filesToRefresh.peek();
-				if (fileToRefresh != null)
-					refreshTask.schedule(0);
-			}
-		}
-
-	}
+    private final StatusCache cache;
+    private ConcurrentHashMap&lt;File, File&gt; dirsToDelete = new ConcurrentHashMap&lt;File, File&gt;();
+    private ConcurrentLinkedQueue&lt;File&gt; filesToRefresh = new ConcurrentLinkedQueue&lt;File&gt;();
+    private RequestProcessor.Task refreshTask;
+    private static final RequestProcessor refresh = new RequestProcessor(&quot;GitRefresh&quot;, 1, true);
+
+    public GitInterceptor()
+    {
+        cache = Git.getInstance().getStatusCache();
+        refreshTask = refresh.create(new RefreshTask());
+    }
+
+    @Override
+    public boolean beforeDelete(File file)
+    {
+        if (file == null)
+            return true;
+        if (GitUtils.isPartOfGitMetadata(file))
+            return false;
+
+        // We track the deletion of top level directories
+        if (file.isDirectory()) {
+            for (File dir : dirsToDelete.keySet()) {
+                if (file.equals(dir.getParentFile()))
+                    dirsToDelete.remove(dir);
+            }
+            if (GitIgnore.isSharable(file))
+                dirsToDelete.put(file, file);
+        }
+        return true;
+    }
+
+    @Override
+    public void doDelete(File file) throws IOException
+    {
+    }
+
+    @Override
+    public void afterDelete(final File file)
+    {
+        Utils.post(new Runnable() {
+
+            public void run()
+            {
+                fileDeletedImpl(file);
+            }
+
+        });
+    }
+
+    private void fileDeletedImpl(final File file)
+    {
+        if (file == null || !file.exists())
+            return;
+
+        Git git = Git.getInstance();
+        final File root = git.getTopmostManagedParent(file);
+        RequestProcessor rp = null;
+        if (root != null)
+            rp = git.getRequestProcessor(root.getAbsolutePath());
+
+        if (file.isDirectory()) {
+            file.delete();
+            if (!dirsToDelete.remove(file, file))
+                return;
+            if (root == null)
+                return;
+            GitProgressSupport support = new GitProgressSupport() {
+
+                public void perform()
+                {
+                    GitCommand.doRemove(root, file, this.getLogger());
+                    // We need to cache the status of all deleted files
+                    Map&lt;File, StatusInfo&gt; interestingFiles = GitCommand.getInterestingStatus(root, file);
+                    if (!interestingFiles.isEmpty()) {
+                        Collection&lt;File&gt; files = interestingFiles.keySet();
+
+                        Map&lt;File, Map&lt;File, StatusInfo&gt;&gt; interestingDirs =
+                            GitUtils.getInterestingDirs(interestingFiles, files);
+
+                        for (File tmpFile : files) {
+                            if (this.isCanceled())
+                                return;
+                            StatusInfo fi = interestingFiles.get(tmpFile);
+
+                            cache.refreshFileStatus(tmpFile, fi,
+                                interestingDirs.get(tmpFile.isDirectory() ? tmpFile : tmpFile.getParentFile()), true);
+                        }
+                    }
+                }
+
+            };
+
+            support.start(rp, root.getAbsolutePath(),
+                org.openide.util.NbBundle.getMessage(GitInterceptor.class, &quot;MSG_Remove_Progress&quot;)); // NOI18N
+        } else {
+            // If we are deleting a parent directory of this file
+            // skip the call to git remove as we will do it for the directory
+            file.delete();
+            if (root == null)
+                return;
+            for (File dir : dirsToDelete.keySet()) {
+                File tmpFile = file.getParentFile();
+                while (tmpFile != null) {
+                    if (tmpFile.equals(dir))
+                        return;
+                    tmpFile = tmpFile.getParentFile();
+                }
+            }
+            GitProgressSupport support = new GitProgressSupport() {
+
+                public void perform()
+                {
+                    GitCommand.doRemove(root, file, this.getLogger());
+                    cache.refresh(file, StatusCache.REPOSITORY_STATUS_UNKNOWN);
+                }
+
+            };
+            support.start(rp, root.getAbsolutePath(),
+                org.openide.util.NbBundle.getMessage(GitInterceptor.class, &quot;MSG_Remove_Progress&quot;)); // NOI18N
+        }
+    }
+
+    @Override
+    public boolean beforeMove(File from, File to)
+    {
+        if (from == null || to == null || to.exists())
+            return true;
+
+        Git git = Git.getInstance();
+        if (git.isManaged(from))
+            return git.isManaged(to);
+        return super.beforeMove(from, to);
+    }
+
+    @Override
+    public void doMove(final File from, final File to) throws IOException
+    {
+        if (from == null || to == null || to.exists())
+            return;
+
+        if (SwingUtilities.isEventDispatchThread()) {
+
+            Git.LOG.log(Level.INFO, &quot;Warning: launching external process in AWT&quot;, new Exception().fillInStackTrace()); // NOI18N
+            final Throwable innerT[] = new Throwable[1];
+            Runnable outOfAwt = new Runnable() {
+
+                public void run()
+                {
+                    try {
+                        gitMoveImplementation(from, to);
+                    } catch (Throwable t) {
+                        innerT[0] = t;
+                    }
+                }
+
+            };
+
+            Git.getInstance().getRequestProcessor().post(outOfAwt).waitFinished();
+            if (innerT[0] != null)
+                if (innerT[0] instanceof IOException)
+                    throw (IOException) innerT[0];
+                else if (innerT[0] instanceof RuntimeException)
+                    throw (RuntimeException) innerT[0];
+                else if (innerT[0] instanceof Error)
+                    throw (Error) innerT[0];
+                else
+                    throw new IllegalStateException(&quot;Unexpected exception class: &quot; + innerT[0]);
+
+        // end of hack
+
+        } else
+            gitMoveImplementation(from, to);
+    }
+
+    private void gitMoveImplementation(final File srcFile, final File dstFile) throws IOException
+    {
+        final Git git = Git.getInstance();
+        final File root = git.getTopmostManagedParent(srcFile);
+        if (root == null)
+            return;
+
+        RequestProcessor rp = git.getRequestProcessor(root.getAbsolutePath());
+
+        Git.LOG.log(Level.FINE, &quot;gitMoveImplementation(): File: {0} {1}&quot;, new Object[]{srcFile, dstFile}); // NOI18N
+
+        srcFile.renameTo(dstFile);
+        Runnable moveImpl = new Runnable() {
+
+            public void run()
+            {
+                OutputLogger logger = OutputLogger.getLogger(root.getAbsolutePath());
+                try {
+                    if (dstFile.isDirectory()) {
+                        GitCommand.doRenameAfter(root, srcFile, dstFile, logger);
+                        return;
+                    }
+                    int status = GitCommand.getSingleStatus(root, srcFile).getStatus();
+                    Git.LOG.log(Level.FINE, &quot;gitMoveImplementation(): Status: {0} {1}&quot;, new Object[]{srcFile, status}); // NOI18N
+                    if (status == StatusInfo.STATUS_NOTVERSIONED_NEWLOCALLY ||
+                        status == StatusInfo.STATUS_NOTVERSIONED_EXCLUDED) {
+                    } else if (status == StatusInfo.STATUS_VERSIONED_ADDEDLOCALLY) {
+                        GitCommand.doRemove(root, srcFile, logger);
+                        GitCommand.doAdd(root, dstFile, logger);
+                    } else
+                        GitCommand.doRenameAfter(root, srcFile, dstFile, logger);
+                } catch (Exception e) {
+                    Git.LOG.log(Level.FINE, &quot;Git failed to rename: File: {0} {1}&quot;, new Object[]{srcFile.getAbsolutePath(), dstFile.getAbsolutePath()}); // NOI18N
+                } finally {
+                    logger.closeLog();
+                }
+            }
+
+        };
+
+        rp.post(moveImpl);
+    }
+
+    @Override
+    public void afterMove(final File from, final File to)
+    {
+        Utils.post(new Runnable() {
+
+            public void run()
+            {
+                fileMovedImpl(from, to);
+            }
+
+        });
+    }
+
+    private void fileMovedImpl(final File from, final File to)
+    {
+        if (from == null || to == null || !to.exists())
+            return;
+        if (to.isDirectory())
+            return;
+        Git git = Git.getInstance();
+        final File root = git.getTopmostManagedParent(from);
+        if (root == null)
+            return;
+
+        RequestProcessor rp = git.getRequestProcessor(root.getAbsolutePath());
+
+        GitProgressSupport supportCreate = new GitProgressSupport() {
+
+            public void perform()
+            {
+                cache.refresh(from, StatusCache.REPOSITORY_STATUS_UNKNOWN);
+                cache.refresh(to, StatusCache.REPOSITORY_STATUS_UNKNOWN);
+            }
+
+        };
+
+        supportCreate.start(rp, root.getAbsolutePath(),
+            org.openide.util.NbBundle.getMessage(GitInterceptor.class, &quot;MSG_Move_Progress&quot;)); // NOI18N
+    }
+
+    @Override
+    public boolean beforeCreate(File file, boolean isDirectory)
+    {
+        return super.beforeCreate(file, isDirectory);
+    }
+
+    @Override
+    public void doCreate(File file, boolean isDirectory) throws IOException
+    {
+        super.doCreate(file, isDirectory);
+    }
+
+    @Override
+    public void afterCreate(final File file)
+    {
+        Utils.post(new Runnable() {
+
+            public void run()
+            {
+                fileCreatedImpl(file);
+            }
+
+        });
+    }
+
+    private void fileCreatedImpl(final File file)
+    {
+        if (file.isDirectory())
+            return;
+        Git git = Git.getInstance();
+        final File root = git.getTopmostManagedParent(file);
+        if (root == null)
+            return;
+
+        RequestProcessor rp = git.getRequestProcessor(root.getAbsolutePath());
+
+        GitProgressSupport supportCreate = new GitProgressSupport() {
+
+            public void perform()
+            {
+                reScheduleRefresh(file);
+            }
+
+        };
+
+        supportCreate.start(rp, root.getAbsolutePath(),
+            org.openide.util.NbBundle.getMessage(GitInterceptor.class, &quot;MSG_Create_Progress&quot;)); // NOI18N
+    }
+
+    @Override
+    public void afterChange(final File file)
+    {
+        Utils.post(new Runnable() {
+
+            public void run()
+            {
+                fileChangedImpl(file);
+            }
+
+        });
+    }
+
+    private void fileChangedImpl(final File file)
+    {
+        if (file.isDirectory())
+            return;
+        Git git = Git.getInstance();
+        final File root = git.getTopmostManagedParent(file);
+        if (root == null)
+            return;
+
+        RequestProcessor rp = git.getRequestProcessor(root.getAbsolutePath());
+
+        GitProgressSupport supportCreate = new GitProgressSupport() {
+
+            public void perform()
+            {
+                Git.LOG.log(Level.FINE, &quot;fileChangedImpl(): File: {0}&quot;, file); // NOI18N
+                reScheduleRefresh(file);
+            }
+
+        };
+
+        supportCreate.start(rp, root.getAbsolutePath(),
+            org.openide.util.NbBundle.getMessage(GitInterceptor.class, &quot;MSG_Change_Progress&quot;)); // NOI18N
+    }
+
+    private void reScheduleRefresh(File fileToRefresh)
+    {
+        // There is no point in refreshing the cache for ignored files.
+        if (GitIgnore.isIgnored(fileToRefresh, false))
+            return;
+        if (!filesToRefresh.contains(fileToRefresh))
+            if (!filesToRefresh.offer(fileToRefresh))
+                Git.LOG.log(Level.FINE, &quot;reScheduleRefresh failed to add to filesToRefresh queue {0}&quot;, fileToRefresh);
+        refreshTask.schedule(1000);
+    }
+
+    private class RefreshTask implements Runnable {
+
+        public void run()
+        {
+            Thread.interrupted();
+            File fileToRefresh = filesToRefresh.poll();
+            if (fileToRefresh != null) {
+                cache.refresh(fileToRefresh, StatusCache.REPOSITORY_STATUS_UNKNOWN);
+                fileToRefresh = filesToRefresh.peek();
+                if (fileToRefresh != null)
+                    refreshTask.schedule(0);
+            }
+        }
+
+    }
 
 }
\ No newline at end of file</diff>
      <filename>src/org/nbgit/GitInterceptor.java</filename>
    </modified>
    <modified>
      <diff>@@ -58,499 +58,499 @@ import org.spearce.jgit.lib.RepositoryConfig;
 
 /**
  * Stores Git module configuration.
- * 
+ *
  * @author alexbcoles
  */
 public class GitModuleConfig {
 
-	public static final String PROP_IGNORED_FILEPATTERNS = &quot;ignoredFilePatterns&quot;;                        // NOI18N
-	public static final String PROP_COMMIT_EXCLUSIONS = &quot;commitExclusions&quot;;                           // NOI18N
-	public static final String PROP_DEFAULT_VALUES = &quot;defaultValues&quot;;                              // NOI18N
-	public static final String PROP_RUN_VERSION = &quot;runVersion&quot;;                                 // NOI18N
-	public static final String KEY_EXECUTABLE_BINARY = &quot;gitExecBinary&quot;;                              // NOI18N
-	public static final String KEY_EXPORT_FILENAME = &quot;gitExportFilename&quot;;                          // NOI18N
-	public static final String KEY_EXPORT_FOLDER = &quot;gitExportFolder&quot;;                          // NOI18N
-	public static final String KEY_IMPORT_FOLDER = &quot;gitImportFolder&quot;;                          // NOI18N
-	public static final String KEY_ANNOTATION_FORMAT = &quot;annotationFormat&quot;;                           // NOI18N
-	public static final String SAVE_PASSWORD = &quot;savePassword&quot;;                               // NOI18N
-	public static final String KEY_BACKUP_ON_REVERTMODS = &quot;backupOnRevert&quot;;                               // NOI18N
-	public static final String KEY_SHOW_HITORY_MERGES = &quot;showHistoryMerges&quot;;                               // NOI18N
-	private static final String RECENT_URL = &quot;repository.recentURL&quot;;                                        // NOI18N
-	private static final String SHOW_CLONE_COMPLETED = &quot;cloneCompleted.showCloneCompleted&quot;;        // NOI18N  
-	private static final String SET_MAIN_PROJECT = &quot;cloneCompleted.setMainProject&quot;;        // NOI18N  
-	private static final String URL_EXP = &quot;annotator.urlExp&quot;;                                               // NOI18N
-	private static final String ANNOTATION_EXP = &quot;annotator.annotationExp&quot;;                                 // NOI18N
-	public static final String TEXT_ANNOTATIONS_FORMAT_DEFAULT = &quot;{DEFAULT}&quot;;                               // NOI18N           
-	private static final String DEFAULT_EXPORT_FILENAME = &quot;%b_%r_%h&quot;;                                  // NOI18N
-	private static final String WINDOWS_USER_APPDATA = getAPPDATA();
-	private static final String WINDOWS_CONFIG_DIR = WINDOWS_USER_APPDATA + &quot;\\Git&quot;;                                      // NOI18N
-	private static final String WINDOWS_GLOBAL_CONFIG_DIR = getGlobalAPPDATA() + &quot;\\Git&quot;;                                 // NOI18N
-	private static final GitModuleConfig INSTANCE = new GitModuleConfig();
-	private static String userEmail;
-	private static String userName;
-	
-
-	static {
-		final RepositoryConfig config = RepositoryConfig.openUserConfig();
-		userEmail = config.getString(&quot;user&quot;, null, &quot;email&quot;);
-		userName = config.getString(&quot;user&quot;, null, &quot;name&quot;);
-
-		if (userName == null || userName.length() == 0) {
-			userName = System.getProperty(&quot;user.name&quot;); // NOI18N
-		}
-
-		if (userEmail == null || userEmail.length() == 0) {
-			userEmail = &quot;&quot;;
-			// nothing
-			// TODO: does NetBeans provide this with product registration?
-			// if not, then get this information in setup wizard.
-		}
-
-	/* FIXME:
-	 * Load user config to get email + name.
-	 * If not found, load global config.
-	 *
-	final RepositoryConfig sysConf = new RepositoryConfig(null, getGlobalConfigPath());
-	 */
-
-	}
-
-	public static GitModuleConfig getDefault()
-	{
-		return INSTANCE;
-	}
-
-	private Set&lt;String&gt; exclusions;
-	// properties ~~~~~~~~~~~~~~~~~~~~~~~~~
-	public Preferences getPreferences()
-	{
-		return NbPreferences.forModule(GitModuleConfig.class);
-	}
-
-	public boolean getShowCloneCompleted()
-	{
-		return getPreferences().getBoolean(SHOW_CLONE_COMPLETED, true);
-	}
-
-	public boolean getSetMainProject()
-	{
-		return getPreferences().getBoolean(SET_MAIN_PROJECT, true);
-	}
-
-	public Pattern[] getIgnoredFilePatterns()
-	{
-		return getDefaultFilePatterns();
-	}
-
-	public boolean isExcludedFromCommit(String path)
-	{
-		return getCommitExclusions().contains(path);
-	}
-
-	/**
-	 * @param paths collection of paths, of File.getAbsolutePath()
-	 */
-	public void addExclusionPaths(Collection&lt;String&gt; paths)
-	{
-		Set&lt;String&gt; exclusions = getCommitExclusions();
-		if (exclusions.addAll(paths))
-			Utils.put(getPreferences(), PROP_COMMIT_EXCLUSIONS, new ArrayList&lt;String&gt;(exclusions));
-	}
-
-	/**
-	 * @param paths collection of paths, File.getAbsolutePath()
-	 */
-	public void removeExclusionPaths(Collection&lt;String&gt; paths)
-	{
-		Set&lt;String&gt; exclusions = getCommitExclusions();
-		if (exclusions.removeAll(paths))
-			Utils.put(getPreferences(), PROP_COMMIT_EXCLUSIONS, new ArrayList&lt;String&gt;(exclusions));
-	}
-
-	public String getExecutableBinaryPath()
-	{
-		return getPreferences().get(KEY_EXECUTABLE_BINARY, &quot;&quot;); // NOI18N
-	}
-
-	public boolean getBackupOnRevertModifications()
-	{
-		return getPreferences().getBoolean(KEY_BACKUP_ON_REVERTMODS, true);
-	}
-
-	public void setBackupOnRevertModifications(boolean bBackup)
-	{
-		getPreferences().putBoolean(KEY_BACKUP_ON_REVERTMODS, bBackup);
-	}
-
-	public boolean getShowHistoryMerges()
-	{
-		return getPreferences().getBoolean(KEY_SHOW_HITORY_MERGES, true);
-	}
-
-	public void setShowHistoryMerges(boolean bShowMerges)
-	{
-		getPreferences().putBoolean(KEY_SHOW_HITORY_MERGES, bShowMerges);
-	}
-
-	public void setExecutableBinaryPath(String path)
-	{
-		getPreferences().put(KEY_EXECUTABLE_BINARY, path);
-	}
-
-	public String getExportFolder()
-	{
-		return getPreferences().get(KEY_EXPORT_FOLDER, System.getProperty(&quot;user.home&quot;)); // NOI18N
-	}
-
-	public void setExportFolder(String path)
-	{
-		getPreferences().put(KEY_EXPORT_FOLDER, path);
-	}
-
-	public String getImportFolder()
-	{
-		return getPreferences().get(KEY_IMPORT_FOLDER, System.getProperty(&quot;user.home&quot;)); // NOI18N
-	}
-
-	public void setImportFolder(String path)
-	{
-		getPreferences().put(KEY_IMPORT_FOLDER, path);
-	}
-
-	public String getExportFilename()
-	{
-		String str = getPreferences().get(KEY_EXPORT_FILENAME, &quot;&quot;); // NOI18N
-		if (str.trim().length() == 0)
-			str = DEFAULT_EXPORT_FILENAME;
-		return str;
-	}
-
-	public void setExportFilename(String path)
-	{
-		getPreferences().put(KEY_EXPORT_FILENAME, path);
-	}
-
-	/**
-	 * This method returns the email address specified in $HOME/.gitconfig
-	 * or a default email address if none is found.
-	 */
-	public String getEmail()
-	{
-		return userEmail;
-	}
-
-	/**
-	 * This method returns the username specified in $HOME/.gitconfig
-	 * or a default username if none is found.
-	 */
-	public String getUserName()
-	{
-		return userName;
-	}
-
-	public void setEmail(String email)
-	{
-		userEmail = email;
-	}
-
-	public void setUserName(String name)
-	{
-		userName = name;
-	}
-
-	public Boolean isEmailValid(String email)
-	{
-		if (email.equals(email))
-			return true;
-		if (email.length() == 0)
-			return false; // cannot be blank
-		return true;//GitMail.isEmailValid(email);
-	}
-
-	public Boolean isUserNameValid(String name)
-	{
-		if (name.equals(userName))
-			return true;
-		if (name.length() == 0)
-			return true;
-		return true;
-	}
-
-	public Properties getProperties(File file)
-	{
-		Properties props = new Properties();
-		Repository repo = Git.getInstance().getRepository(file);
-		RepositoryConfig config = repo != null
-			? repo.getConfig()
-			: RepositoryConfig.openUserConfig();
-
-		String email = null;
-		if (config != null)
-			email = config.getString(&quot;user&quot;, null, &quot;email&quot;);
-		if (email == null || email.length() == 0)
-			email = getEmail();
-		props.setProperty(&quot;user.email&quot;, email);
-
-		String name = null;
-		if (config != null)
-			name = config.getString(&quot;user&quot;, null, &quot;name&quot;);
-		if (name == null || name.length() == 0)
-			name = getUserName();
-		props.setProperty(&quot;user.name&quot;, name); // NOI18N
-
-		return props;
-	}
-
-	public String getAnnotationFormat()
-	{
-		return getPreferences().get(KEY_ANNOTATION_FORMAT, getDefaultAnnotationFormat());
-	}
-
-	public String getDefaultAnnotationFormat()
-	{
-		return &quot;[{&quot; + GitAnnotator.ANNOTATION_STATUS + &quot;} {&quot; + GitAnnotator.ANNOTATION_FOLDER + &quot;}]&quot;; // NOI18N
-	}
-
-	public void setAnnotationFormat(String annotationFormat)
-	{
-		getPreferences().put(KEY_ANNOTATION_FORMAT, annotationFormat);
-	}
-
-	public boolean getSavePassword()
-	{
-		return getPreferences().getBoolean(SAVE_PASSWORD, true);
-	}
-
-	public void setSavePassword(boolean bl)
-	{
-		getPreferences().putBoolean(SAVE_PASSWORD, bl);
-	}
-
-	public void setShowCloneCompleted(boolean bl)
-	{
-		getPreferences().putBoolean(SHOW_CLONE_COMPLETED, bl);
-	}
-
-	public void setSetMainProject(boolean bl)
-	{
-		getPreferences().putBoolean(SET_MAIN_PROJECT, bl);
-	}
-
-	/*
-	public RepositoryConnection getRepositoryConnection(String url)
-	{
-	List&lt;RepositoryConnection&gt; rcs = getRecentUrls();
-	for (Iterator&lt;RepositoryConnection&gt; it = rcs.iterator(); it.hasNext();) {
-	RepositoryConnection rc = it.next();
-	if (url.equals(rc.getUrl()))
-	return rc;
-	}
-	return null;
-	}
-	 */
-
-	/*
-	public void insertRecentUrl(RepositoryConnection rc)
-	{
-	Preferences prefs = getPreferences();
-	
-	List&lt;String&gt; urlValues = Utils.getStringList(prefs, RECENT_URL);
-	for (Iterator&lt;String&gt; it = urlValues.iterator(); it.hasNext();) {
-	String rcOldString = it.next();
-	RepositoryConnection rcOld = RepositoryConnection.parse(rcOldString);
-	if (rcOld.equals(rc))
-	Utils.removeFromArray(prefs, RECENT_URL, rcOldString);
-	}
-	Utils.insert(prefs, RECENT_URL, RepositoryConnection.getString(rc), -1);
-	}
-	
-	public void setRecentUrls(List&lt;RepositoryConnection&gt; recentUrls)
-	{
-	List&lt;String&gt; urls = new ArrayList&lt;String&gt;(recentUrls.size());
-	
-	int idx = 0;
-	for (Iterator&lt;RepositoryConnection&gt; it = recentUrls.iterator(); it.hasNext();) {
-	idx++;
-	RepositoryConnection rc = it.next();
-	urls.add(RepositoryConnection.getString(rc));
-	}
-	Preferences prefs = getPreferences();
-	Utils.put(prefs, RECENT_URL, urls);
-	}
-	
-	public List&lt;RepositoryConnection&gt; getRecentUrls()
-	{
-	Preferences prefs = getPreferences();
-	List&lt;String&gt; urls = Utils.getStringList(prefs, RECENT_URL);
-	List&lt;RepositoryConnection&gt; ret = new ArrayList&lt;RepositoryConnection&gt;(urls.size());
-	for (Iterator&lt;String&gt; it = urls.iterator(); it.hasNext();) {
-	RepositoryConnection rc = RepositoryConnection.parse(it.next());
-	ret.add(rc);
-	}
-	return ret;
-	}
-	 */
-	//public void setAnnotationExpresions(List&lt;AnnotationExpression&gt; exps) {
-	//    List&lt;String&gt; urlExp = new ArrayList&lt;String&gt;(exps.size());
-	//    List&lt;String&gt; annotationExp = new ArrayList&lt;String&gt;(exps.size());        
-	//    int idx = 0;
-	//    for (Iterator&lt;AnnotationExpression&gt; it = exps.iterator(); it.hasNext();) {
-	//        idx++;
-	//        AnnotationExpression exp = it.next();            
-	//        urlExp.add(exp.getUrlExp());
-	//        annotationExp.add(exp.getAnnotationExp());            
-	//    }
-
-	//    Preferences prefs = getPreferences();
-	//    Utils.put(prefs, URL_EXP, urlExp);        
-	//    Utils.put(prefs, ANNOTATION_EXP, annotationExp);                
-	//}
-
-	//public List&lt;AnnotationExpression&gt; getAnnotationExpresions() {
-	//    Preferences prefs = getPreferences();
-	//    List&lt;String&gt; urlExp = Utils.getStringList(prefs, URL_EXP);
-	//    List&lt;String&gt; annotationExp = Utils.getStringList(prefs, ANNOTATION_EXP);        
-	//    List&lt;AnnotationExpression&gt; ret = new ArrayList&lt;AnnotationExpression&gt;(urlExp.size());                
-	//    for (int i = 0; i &lt; urlExp.size(); i++) {                                        
-	//        ret.add(new AnnotationExpression(urlExp.get(i), annotationExp.get(i)));
-	//    }
-	//    if(ret.size() &lt; 1) {
-	//        ret = getDefaultAnnotationExpresions();
-	//    }
-	//    return ret;
-	//}
-
-	//public List&lt;AnnotationExpression&gt; getDefaultAnnotationExpresions() {
-	//    List&lt;AnnotationExpression&gt; ret = new ArrayList&lt;AnnotationExpression&gt;(1);
-	//    ret.add(new AnnotationExpression(&quot;.*/(branches|tags)/(.+?)/.*&quot;, &quot;\\2&quot;));     // NOI18N 
-	//    return ret;
-	//}
-	// TODO: persist state
-	private TableSorter importTableSorter;
-	private TableSorter commitTableSorter;
-
-	public TableSorter getImportTableSorter()
-	{
-		return importTableSorter;
-	}
-
-	public void setImportTableSorter(TableSorter sorter)
-	{
-		importTableSorter = sorter;
-	}
-
-	public TableSorter getCommitTableSorter()
-	{
-		return commitTableSorter;
-	}
-
-	public void setCommitTableSorter(TableSorter sorter)
-	{
-		commitTableSorter = sorter;
-	}
-	// private methods ~~~~~~~~~~~~~~~~~~
-	private synchronized Set&lt;String&gt; getCommitExclusions()
-	{
-		if (exclusions == null)
-			exclusions = new HashSet&lt;String&gt;(Utils.getStringList(getPreferences(), PROP_COMMIT_EXCLUSIONS));
-		return exclusions;
-	}
-
-	private static Pattern[] getDefaultFilePatterns()
-	{
-		return new Pattern[]{
-				Pattern.compile(&quot;cvslog\\..*&quot;), // NOI18N
-				Pattern.compile(&quot;\\.make\\.state&quot;), // NOI18N
-				Pattern.compile(&quot;\\.nse_depinfo&quot;), // NOI18N
-				Pattern.compile(&quot;.*~&quot;), // NOI18N
-				Pattern.compile(&quot;#.*&quot;), // NOI18N
-				Pattern.compile(&quot;\\.#.*&quot;), // NOI18N
-				Pattern.compile(&quot;,.*&quot;), // NOI18N
-				Pattern.compile(&quot;_\\$.*&quot;), // NOI18N
-				Pattern.compile(&quot;.*\\$&quot;), // NOI18N
-				Pattern.compile(&quot;.*\\.old&quot;), // NOI18N
-				Pattern.compile(&quot;.*\\.bak&quot;), // NOI18N
-				Pattern.compile(&quot;.*\\.BAK&quot;), // NOI18N
-				Pattern.compile(&quot;.*\\.orig&quot;), // NOI18N
-				Pattern.compile(&quot;.*\\.rej&quot;), // NOI18N
-				Pattern.compile(&quot;.*\\.del-.*&quot;), // NOI18N
-				Pattern.compile(&quot;.*\\.a&quot;), // NOI18N
-				Pattern.compile(&quot;.*\\.olb&quot;), // NOI18N
-				Pattern.compile(&quot;.*\\.o&quot;), // NOI18N
-				Pattern.compile(&quot;.*\\.obj&quot;), // NOI18N
-				Pattern.compile(&quot;.*\\.so&quot;), // NOI18N
-				Pattern.compile(&quot;.*\\.exe&quot;), // NOI18N
-				Pattern.compile(&quot;.*\\.Z&quot;), // NOI18N
-				Pattern.compile(&quot;.*\\.elc&quot;), // NOI18N
-				Pattern.compile(&quot;.*\\.ln&quot;), // NOI18N
-			};
-	}
-
-	/**
-	 * Return the path for the systemwide command lines configuration directory
-	 */
-	private static String getGlobalConfigPath()
-	{
-		if (Utilities.isUnix())
-			return &quot;/etc/gitconfig&quot;;
-		else if (Utilities.isWindows())
-			return WINDOWS_GLOBAL_CONFIG_DIR;
-		return &quot;&quot;;                                  // NOI18N
-	}
-
-	/**
-	 * Returns the value for the %APPDATA% env variable on Windows
-	 */
-	private static String getAPPDATA()
-	{
-		String appdata = &quot;&quot;; // NOI18N
-		if (Utilities.isWindows())
-			appdata = System.getenv(&quot;APPDATA&quot;);
-		return appdata != null ? appdata : &quot;&quot;; // NOI18N
-	}
-
-	/**
-	 * Returns the value for the %ALLUSERSPROFILE% + the last folder segment
-	 * from %APPDATA% env variables on Windows
-	 */
-	private static String getGlobalAPPDATA()
-	{
-		if (Utilities.isWindows()) {
-			String globalProfile = System.getenv(&quot;ALLUSERSPROFILE&quot;);                                // NOI18N
-			if (globalProfile == null || globalProfile.trim().equals(&quot;&quot;))                          // NOI18N
-				globalProfile = &quot;&quot;;
-			String appdataPath = WINDOWS_USER_APPDATA;
-			if (appdataPath == null || appdataPath.equals(&quot;&quot;))                                     // NOI18N
-				return &quot;&quot;;
-			String appdata = &quot;&quot;;                                                                    // NOI18N
-			int idx = appdataPath.lastIndexOf(&quot;\\&quot;);                                                // NOI18N
-			if (idx &gt; -1) {
-				appdata = appdataPath.substring(idx + 1);
-				if (appdata.trim().equals(&quot;&quot;)) {                                                     // NOI18N
-					int previdx = appdataPath.lastIndexOf(&quot;\\&quot;, idx);                               // NOI18N
-					if (idx &gt; -1)
-						appdata = appdataPath.substring(previdx + 1, idx);
-				}
-			} else
-				return &quot;&quot;;
-			return globalProfile + &quot;/&quot; + appdata;                                                   // NOI18N
-		}
-		return &quot;&quot;;                                                                                  // NOI18N
-	}
-
-	/**
-	 * Returns the path for the user-specific git configuration.
-	 *
-	 * @return the path
-	 */
-	public static String getUserConfigPath()
-	{
-		if (Utilities.isUnix()) {
-			String path = System.getProperty(&quot;user.home&quot;);     // NOI18N
-			return path + &quot;/.&quot;;                                 // NOI18N
-		} else if (Utilities.isWindows())
-			return WINDOWS_CONFIG_DIR + &quot;/&quot;;
-		return &quot;&quot;;                                              // NOI18N
-	}
+    public static final String PROP_IGNORED_FILEPATTERNS = &quot;ignoredFilePatterns&quot;;                        // NOI18N
+    public static final String PROP_COMMIT_EXCLUSIONS = &quot;commitExclusions&quot;;                           // NOI18N
+    public static final String PROP_DEFAULT_VALUES = &quot;defaultValues&quot;;                              // NOI18N
+    public static final String PROP_RUN_VERSION = &quot;runVersion&quot;;                                 // NOI18N
+    public static final String KEY_EXECUTABLE_BINARY = &quot;gitExecBinary&quot;;                              // NOI18N
+    public static final String KEY_EXPORT_FILENAME = &quot;gitExportFilename&quot;;                          // NOI18N
+    public static final String KEY_EXPORT_FOLDER = &quot;gitExportFolder&quot;;                          // NOI18N
+    public static final String KEY_IMPORT_FOLDER = &quot;gitImportFolder&quot;;                          // NOI18N
+    public static final String KEY_ANNOTATION_FORMAT = &quot;annotationFormat&quot;;                           // NOI18N
+    public static final String SAVE_PASSWORD = &quot;savePassword&quot;;                               // NOI18N
+    public static final String KEY_BACKUP_ON_REVERTMODS = &quot;backupOnRevert&quot;;                               // NOI18N
+    public static final String KEY_SHOW_HITORY_MERGES = &quot;showHistoryMerges&quot;;                               // NOI18N
+    private static final String RECENT_URL = &quot;repository.recentURL&quot;;                                        // NOI18N
+    private static final String SHOW_CLONE_COMPLETED = &quot;cloneCompleted.showCloneCompleted&quot;;        // NOI18N
+    private static final String SET_MAIN_PROJECT = &quot;cloneCompleted.setMainProject&quot;;        // NOI18N
+    private static final String URL_EXP = &quot;annotator.urlExp&quot;;                                               // NOI18N
+    private static final String ANNOTATION_EXP = &quot;annotator.annotationExp&quot;;                                 // NOI18N
+    public static final String TEXT_ANNOTATIONS_FORMAT_DEFAULT = &quot;{DEFAULT}&quot;;                               // NOI18N
+    private static final String DEFAULT_EXPORT_FILENAME = &quot;%b_%r_%h&quot;;                                  // NOI18N
+    private static final String WINDOWS_USER_APPDATA = getAPPDATA();
+    private static final String WINDOWS_CONFIG_DIR = WINDOWS_USER_APPDATA + &quot;\\Git&quot;;                                      // NOI18N
+    private static final String WINDOWS_GLOBAL_CONFIG_DIR = getGlobalAPPDATA() + &quot;\\Git&quot;;                                 // NOI18N
+    private static final GitModuleConfig INSTANCE = new GitModuleConfig();
+    private static String userEmail;
+    private static String userName;
+
+
+    static {
+        final RepositoryConfig config = RepositoryConfig.openUserConfig();
+        userEmail = config.getString(&quot;user&quot;, null, &quot;email&quot;);
+        userName = config.getString(&quot;user&quot;, null, &quot;name&quot;);
+
+        if (userName == null || userName.length() == 0) {
+            userName = System.getProperty(&quot;user.name&quot;); // NOI18N
+        }
+
+        if (userEmail == null || userEmail.length() == 0) {
+            userEmail = &quot;&quot;;
+            // nothing
+            // TODO: does NetBeans provide this with product registration?
+            // if not, then get this information in setup wizard.
+        }
+
+    /* FIXME:
+     * Load user config to get email + name.
+     * If not found, load global config.
+     *
+    final RepositoryConfig sysConf = new RepositoryConfig(null, getGlobalConfigPath());
+     */
+
+    }
+
+    public static GitModuleConfig getDefault()
+    {
+        return INSTANCE;
+    }
+
+    private Set&lt;String&gt; exclusions;
+    // properties ~~~~~~~~~~~~~~~~~~~~~~~~~
+    public Preferences getPreferences()
+    {
+        return NbPreferences.forModule(GitModuleConfig.class);
+    }
+
+    public boolean getShowCloneCompleted()
+    {
+        return getPreferences().getBoolean(SHOW_CLONE_COMPLETED, true);
+    }
+
+    public boolean getSetMainProject()
+    {
+        return getPreferences().getBoolean(SET_MAIN_PROJECT, true);
+    }
+
+    public Pattern[] getIgnoredFilePatterns()
+    {
+        return getDefaultFilePatterns();
+    }
+
+    public boolean isExcludedFromCommit(String path)
+    {
+        return getCommitExclusions().contains(path);
+    }
+
+    /**
+     * @param paths collection of paths, of File.getAbsolutePath()
+     */
+    public void addExclusionPaths(Collection&lt;String&gt; paths)
+    {
+        Set&lt;String&gt; exclusions = getCommitExclusions();
+        if (exclusions.addAll(paths))
+            Utils.put(getPreferences(), PROP_COMMIT_EXCLUSIONS, new ArrayList&lt;String&gt;(exclusions));
+    }
+
+    /**
+     * @param paths collection of paths, File.getAbsolutePath()
+     */
+    public void removeExclusionPaths(Collection&lt;String&gt; paths)
+    {
+        Set&lt;String&gt; exclusions = getCommitExclusions();
+        if (exclusions.removeAll(paths))
+            Utils.put(getPreferences(), PROP_COMMIT_EXCLUSIONS, new ArrayList&lt;String&gt;(exclusions));
+    }
+
+    public String getExecutableBinaryPath()
+    {
+        return getPreferences().get(KEY_EXECUTABLE_BINARY, &quot;&quot;); // NOI18N
+    }
+
+    public boolean getBackupOnRevertModifications()
+    {
+        return getPreferences().getBoolean(KEY_BACKUP_ON_REVERTMODS, true);
+    }
+
+    public void setBackupOnRevertModifications(boolean bBackup)
+    {
+        getPreferences().putBoolean(KEY_BACKUP_ON_REVERTMODS, bBackup);
+    }
+
+    public boolean getShowHistoryMerges()
+    {
+        return getPreferences().getBoolean(KEY_SHOW_HITORY_MERGES, true);
+    }
+
+    public void setShowHistoryMerges(boolean bShowMerges)
+    {
+        getPreferences().putBoolean(KEY_SHOW_HITORY_MERGES, bShowMerges);
+    }
+
+    public void setExecutableBinaryPath(String path)
+    {
+        getPreferences().put(KEY_EXECUTABLE_BINARY, path);
+    }
+
+    public String getExportFolder()
+    {
+        return getPreferences().get(KEY_EXPORT_FOLDER, System.getProperty(&quot;user.home&quot;)); // NOI18N
+    }
+
+    public void setExportFolder(String path)
+    {
+        getPreferences().put(KEY_EXPORT_FOLDER, path);
+    }
+
+    public String getImportFolder()
+    {
+        return getPreferences().get(KEY_IMPORT_FOLDER, System.getProperty(&quot;user.home&quot;)); // NOI18N
+    }
+
+    public void setImportFolder(String path)
+    {
+        getPreferences().put(KEY_IMPORT_FOLDER, path);
+    }
+
+    public String getExportFilename()
+    {
+        String str = getPreferences().get(KEY_EXPORT_FILENAME, &quot;&quot;); // NOI18N
+        if (str.trim().length() == 0)
+            str = DEFAULT_EXPORT_FILENAME;
+        return str;
+    }
+
+    public void setExportFilename(String path)
+    {
+        getPreferences().put(KEY_EXPORT_FILENAME, path);
+    }
+
+    /**
+     * This method returns the email address specified in $HOME/.gitconfig
+     * or a default email address if none is found.
+     */
+    public String getEmail()
+    {
+        return userEmail;
+    }
+
+    /**
+     * This method returns the username specified in $HOME/.gitconfig
+     * or a default username if none is found.
+     */
+    public String getUserName()
+    {
+        return userName;
+    }
+
+    public void setEmail(String email)
+    {
+        userEmail = email;
+    }
+
+    public void setUserName(String name)
+    {
+        userName = name;
+    }
+
+    public Boolean isEmailValid(String email)
+    {
+        if (email.equals(email))
+            return true;
+        if (email.length() == 0)
+            return false; // cannot be blank
+        return true;//GitMail.isEmailValid(email);
+    }
+
+    public Boolean isUserNameValid(String name)
+    {
+        if (name.equals(userName))
+            return true;
+        if (name.length() == 0)
+            return true;
+        return true;
+    }
+
+    public Properties getProperties(File file)
+    {
+        Properties props = new Properties();
+        Repository repo = Git.getInstance().getRepository(file);
+        RepositoryConfig config = repo != null
+            ? repo.getConfig()
+            : RepositoryConfig.openUserConfig();
+
+        String email = null;
+        if (config != null)
+            email = config.getString(&quot;user&quot;, null, &quot;email&quot;);
+        if (email == null || email.length() == 0)
+            email = getEmail();
+        props.setProperty(&quot;user.email&quot;, email);
+
+        String name = null;
+        if (config != null)
+            name = config.getString(&quot;user&quot;, null, &quot;name&quot;);
+        if (name == null || name.length() == 0)
+            name = getUserName();
+        props.setProperty(&quot;user.name&quot;, name); // NOI18N
+
+        return props;
+    }
+
+    public String getAnnotationFormat()
+    {
+        return getPreferences().get(KEY_ANNOTATION_FORMAT, getDefaultAnnotationFormat());
+    }
+
+    public String getDefaultAnnotationFormat()
+    {
+        return &quot;[{&quot; + GitAnnotator.ANNOTATION_STATUS + &quot;} {&quot; + GitAnnotator.ANNOTATION_FOLDER + &quot;}]&quot;; // NOI18N
+    }
+
+    public void setAnnotationFormat(String annotationFormat)
+    {
+        getPreferences().put(KEY_ANNOTATION_FORMAT, annotationFormat);
+    }
+
+    public boolean getSavePassword()
+    {
+        return getPreferences().getBoolean(SAVE_PASSWORD, true);
+    }
+
+    public void setSavePassword(boolean bl)
+    {
+        getPreferences().putBoolean(SAVE_PASSWORD, bl);
+    }
+
+    public void setShowCloneCompleted(boolean bl)
+    {
+        getPreferences().putBoolean(SHOW_CLONE_COMPLETED, bl);
+    }
+
+    public void setSetMainProject(boolean bl)
+    {
+        getPreferences().putBoolean(SET_MAIN_PROJECT, bl);
+    }
+
+    /*
+    public RepositoryConnection getRepositoryConnection(String url)
+    {
+    List&lt;RepositoryConnection&gt; rcs = getRecentUrls();
+    for (Iterator&lt;RepositoryConnection&gt; it = rcs.iterator(); it.hasNext();) {
+    RepositoryConnection rc = it.next();
+    if (url.equals(rc.getUrl()))
+    return rc;
+    }
+    return null;
+    }
+     */
+
+    /*
+    public void insertRecentUrl(RepositoryConnection rc)
+    {
+    Preferences prefs = getPreferences();
+
+    List&lt;String&gt; urlValues = Utils.getStringList(prefs, RECENT_URL);
+    for (Iterator&lt;String&gt; it = urlValues.iterator(); it.hasNext();) {
+    String rcOldString = it.next();
+    RepositoryConnection rcOld = RepositoryConnection.parse(rcOldString);
+    if (rcOld.equals(rc))
+    Utils.removeFromArray(prefs, RECENT_URL, rcOldString);
+    }
+    Utils.insert(prefs, RECENT_URL, RepositoryConnection.getString(rc), -1);
+    }
+
+    public void setRecentUrls(List&lt;RepositoryConnection&gt; recentUrls)
+    {
+    List&lt;String&gt; urls = new ArrayList&lt;String&gt;(recentUrls.size());
+
+    int idx = 0;
+    for (Iterator&lt;RepositoryConnection&gt; it = recentUrls.iterator(); it.hasNext();) {
+    idx++;
+    RepositoryConnection rc = it.next();
+    urls.add(RepositoryConnection.getString(rc));
+    }
+    Preferences prefs = getPreferences();
+    Utils.put(prefs, RECENT_URL, urls);
+    }
+
+    public List&lt;RepositoryConnection&gt; getRecentUrls()
+    {
+    Preferences prefs = getPreferences();
+    List&lt;String&gt; urls = Utils.getStringList(prefs, RECENT_URL);
+    List&lt;RepositoryConnection&gt; ret = new ArrayList&lt;RepositoryConnection&gt;(urls.size());
+    for (Iterator&lt;String&gt; it = urls.iterator(); it.hasNext();) {
+    RepositoryConnection rc = RepositoryConnection.parse(it.next());
+    ret.add(rc);
+    }
+    return ret;
+    }
+     */
+    //public void setAnnotationExpresions(List&lt;AnnotationExpression&gt; exps) {
+    //    List&lt;String&gt; urlExp = new ArrayList&lt;String&gt;(exps.size());
+    //    List&lt;String&gt; annotationExp = new ArrayList&lt;String&gt;(exps.size());
+    //    int idx = 0;
+    //    for (Iterator&lt;AnnotationExpression&gt; it = exps.iterator(); it.hasNext();) {
+    //        idx++;
+    //        AnnotationExpression exp = it.next();
+    //        urlExp.add(exp.getUrlExp());
+    //        annotationExp.add(exp.getAnnotationExp());
+    //    }
+
+    //    Preferences prefs = getPreferences();
+    //    Utils.put(prefs, URL_EXP, urlExp);
+    //    Utils.put(prefs, ANNOTATION_EXP, annotationExp);
+    //}
+
+    //public List&lt;AnnotationExpression&gt; getAnnotationExpresions() {
+    //    Preferences prefs = getPreferences();
+    //    List&lt;String&gt; urlExp = Utils.getStringList(prefs, URL_EXP);
+    //    List&lt;String&gt; annotationExp = Utils.getStringList(prefs, ANNOTATION_EXP);
+    //    List&lt;AnnotationExpression&gt; ret = new ArrayList&lt;AnnotationExpression&gt;(urlExp.size());
+    //    for (int i = 0; i &lt; urlExp.size(); i++) {
+    //        ret.add(new AnnotationExpression(urlExp.get(i), annotationExp.get(i)));
+    //    }
+    //    if(ret.size() &lt; 1) {
+    //        ret = getDefaultAnnotationExpresions();
+    //    }
+    //    return ret;
+    //}
+
+    //public List&lt;AnnotationExpression&gt; getDefaultAnnotationExpresions() {
+    //    List&lt;AnnotationExpression&gt; ret = new ArrayList&lt;AnnotationExpression&gt;(1);
+    //    ret.add(new AnnotationExpression(&quot;.*/(branches|tags)/(.+?)/.*&quot;, &quot;\\2&quot;));     // NOI18N
+    //    return ret;
+    //}
+    // TODO: persist state
+    private TableSorter importTableSorter;
+    private TableSorter commitTableSorter;
+
+    public TableSorter getImportTableSorter()
+    {
+        return importTableSorter;
+    }
+
+    public void setImportTableSorter(TableSorter sorter)
+    {
+        importTableSorter = sorter;
+    }
+
+    public TableSorter getCommitTableSorter()
+    {
+        return commitTableSorter;
+    }
+
+    public void setCommitTableSorter(TableSorter sorter)
+    {
+        commitTableSorter = sorter;
+    }
+    // private methods ~~~~~~~~~~~~~~~~~~
+    private synchronized Set&lt;String&gt; getCommitExclusions()
+    {
+        if (exclusions == null)
+            exclusions = new HashSet&lt;String&gt;(Utils.getStringList(getPreferences(), PROP_COMMIT_EXCLUSIONS));
+        return exclusions;
+    }
+
+    private static Pattern[] getDefaultFilePatterns()
+    {
+        return new Pattern[]{
+                Pattern.compile(&quot;cvslog\\..*&quot;), // NOI18N
+                Pattern.compile(&quot;\\.make\\.state&quot;), // NOI18N
+                Pattern.compile(&quot;\\.nse_depinfo&quot;), // NOI18N
+                Pattern.compile(&quot;.*~&quot;), // NOI18N
+                Pattern.compile(&quot;#.*&quot;), // NOI18N
+                Pattern.compile(&quot;\\.#.*&quot;), // NOI18N
+                Pattern.compile(&quot;,.*&quot;), // NOI18N
+                Pattern.compile(&quot;_\\$.*&quot;), // NOI18N
+                Pattern.compile(&quot;.*\\$&quot;), // NOI18N
+                Pattern.compile(&quot;.*\\.old&quot;), // NOI18N
+                Pattern.compile(&quot;.*\\.bak&quot;), // NOI18N
+                Pattern.compile(&quot;.*\\.BAK&quot;), // NOI18N
+                Pattern.compile(&quot;.*\\.orig&quot;), // NOI18N
+                Pattern.compile(&quot;.*\\.rej&quot;), // NOI18N
+                Pattern.compile(&quot;.*\\.del-.*&quot;), // NOI18N
+                Pattern.compile(&quot;.*\\.a&quot;), // NOI18N
+                Pattern.compile(&quot;.*\\.olb&quot;), // NOI18N
+                Pattern.compile(&quot;.*\\.o&quot;), // NOI18N
+                Pattern.compile(&quot;.*\\.obj&quot;), // NOI18N
+                Pattern.compile(&quot;.*\\.so&quot;), // NOI18N
+                Pattern.compile(&quot;.*\\.exe&quot;), // NOI18N
+                Pattern.compile(&quot;.*\\.Z&quot;), // NOI18N
+                Pattern.compile(&quot;.*\\.elc&quot;), // NOI18N
+                Pattern.compile(&quot;.*\\.ln&quot;), // NOI18N
+            };
+    }
+
+    /**
+     * Return the path for the systemwide command lines configuration directory
+     */
+    private static String getGlobalConfigPath()
+    {
+        if (Utilities.isUnix())
+            return &quot;/etc/gitconfig&quot;;
+        else if (Utilities.isWindows())
+            return WINDOWS_GLOBAL_CONFIG_DIR;
+        return &quot;&quot;;                                  // NOI18N
+    }
+
+    /**
+     * Returns the value for the %APPDATA% env variable on Windows
+     */
+    private static String getAPPDATA()
+    {
+        String appdata = &quot;&quot;; // NOI18N
+        if (Utilities.isWindows())
+            appdata = System.getenv(&quot;APPDATA&quot;);
+        return appdata != null ? appdata : &quot;&quot;; // NOI18N
+    }
+
+    /**
+     * Returns the value for the %ALLUSERSPROFILE% + the last folder segment
+     * from %APPDATA% env variables on Windows
+     */
+    private static String getGlobalAPPDATA()
+    {
+        if (Utilities.isWindows()) {
+            String globalProfile = System.getenv(&quot;ALLUSERSPROFILE&quot;);                                // NOI18N
+            if (globalProfile == null || globalProfile.trim().equals(&quot;&quot;))                          // NOI18N
+                globalProfile = &quot;&quot;;
+            String appdataPath = WINDOWS_USER_APPDATA;
+            if (appdataPath == null || appdataPath.equals(&quot;&quot;))                                     // NOI18N
+                return &quot;&quot;;
+            String appdata = &quot;&quot;;                                                                    // NOI18N
+            int idx = appdataPath.lastIndexOf(&quot;\\&quot;);                                                // NOI18N
+            if (idx &gt; -1) {
+                appdata = appdataPath.substring(idx + 1);
+                if (appdata.trim().equals(&quot;&quot;)) {                                                     // NOI18N
+                    int previdx = appdataPath.lastIndexOf(&quot;\\&quot;, idx);                               // NOI18N
+                    if (idx &gt; -1)
+                        appdata = appdataPath.substring(previdx + 1, idx);
+                }
+            } else
+                return &quot;&quot;;
+            return globalProfile + &quot;/&quot; + appdata;                                                   // NOI18N
+        }
+        return &quot;&quot;;                                                                                  // NOI18N
+    }
+
+    /**
+     * Returns the path for the user-specific git configuration.
+     *
+     * @return the path
+     */
+    public static String getUserConfigPath()
+    {
+        if (Utilities.isUnix()) {
+            String path = System.getProperty(&quot;user.home&quot;);     // NOI18N
+            return path + &quot;/.&quot;;                                 // NOI18N
+        } else if (Utilities.isWindows())
+            return WINDOWS_CONFIG_DIR + &quot;/&quot;;
+        return &quot;&quot;;                                              // NOI18N
+    }
 
 }
\ No newline at end of file</diff>
      <filename>src/org/nbgit/GitModuleConfig.java</filename>
    </modified>
    <modified>
      <diff>@@ -56,134 +56,134 @@ import org.openide.util.TaskListener;
  */
 public abstract class GitProgressSupport implements Runnable, Cancellable {
 
-	private Cancellable delegate;
-	private volatile boolean canceled;
-	private ProgressHandle progressHandle = null;
-	private String displayName = &quot;&quot;; // NOI18N
-	private String originalDisplayName = &quot;&quot;; // NOI18N
-	private OutputLogger logger;
-	private String repositoryRoot;
-	private RequestProcessor.Task task;
-
-	public RequestProcessor.Task start(RequestProcessor rp, String repositoryRoot, String displayName)
-	{
-		setDisplayName(displayName);
-		this.repositoryRoot = repositoryRoot;
-		startProgress();
-		setProgressQueued();
-		task = rp.post(this);
-		task.addTaskListener(new TaskListener() {
-
-			public void taskFinished(org.openide.util.Task task)
-			{
-				delegate = null;
-			}
-
-		});
-		return task;
-	}
-
-	public void setRepositoryRoot(String repositoryRoot)
-	{
-		this.repositoryRoot = repositoryRoot;
-		logger = null;
-	}
-
-	public void run()
-	{
-		setProgress();
-		performIntern();
-	}
-
-	protected void performIntern()
-	{
-		try {
-			Git.LOG.log(Level.FINE, &quot;Start - {0}&quot;, displayName); // NOI18N
-
-			if (!canceled)
-				perform();
-			Git.LOG.log(Level.FINE, &quot;End - {0}&quot;, displayName); // NOI18N
-
-		} finally {
-			finnishProgress();
-			if (logger != null)
-				logger.closeLog();
-		}
-	}
-
-	protected abstract void perform();
-
-	public synchronized boolean isCanceled()
-	{
-		return canceled;
-	}
-
-	public synchronized boolean cancel()
-	{
-		if (canceled)
-			return false;
-		if (task != null)
-			task.cancel();
-		if (delegate != null)
-			delegate.cancel();
-		Git.getInstance().clearRequestProcessor(repositoryRoot);
-		getProgressHandle().finish();
-		canceled = true;
-		return true;
-	}
-
-	void setCancellableDelegate(Cancellable cancellable)
-	{
-		this.delegate = cancellable;
-	}
-
-	public void setDisplayName(String displayName)
-	{
-		if (originalDisplayName.equals(&quot;&quot;)) // NOI18N
-			originalDisplayName = displayName;
-		this.displayName = displayName;
-		setProgress();
-	}
-
-	private void setProgressQueued()
-	{
-		if (progressHandle != null)
-			progressHandle.progress(NbBundle.getMessage(GitProgressSupport.class, &quot;LBL_Queued&quot;, displayName));
-	}
-
-	private void setProgress()
-	{
-		if (progressHandle != null)
-			progressHandle.progress(displayName);
-	}
-
-	protected String getDisplayName()
-	{
-		return displayName;
-	}
-
-	protected ProgressHandle getProgressHandle()
-	{
-		if (progressHandle == null)
-			progressHandle = ProgressHandleFactory.createHandle(displayName, this);
-		return progressHandle;
-	}
-
-	protected void startProgress()
-	{
-		getProgressHandle().start();
-	}
-
-	protected void finnishProgress()
-	{
-		getProgressHandle().finish();
-	}
-
-	public OutputLogger getLogger()
-	{
-		if (logger == null)
-			logger = Git.getInstance().getLogger(repositoryRoot);
-		return logger;
-	}
+    private Cancellable delegate;
+    private volatile boolean canceled;
+    private ProgressHandle progressHandle = null;
+    private String displayName = &quot;&quot;; // NOI18N
+    private String originalDisplayName = &quot;&quot;; // NOI18N
+    private OutputLogger logger;
+    private String repositoryRoot;
+    private RequestProcessor.Task task;
+
+    public RequestProcessor.Task start(RequestProcessor rp, String repositoryRoot, String displayName)
+    {
+        setDisplayName(displayName);
+        this.repositoryRoot = repositoryRoot;
+        startProgress();
+        setProgressQueued();
+        task = rp.post(this);
+        task.addTaskListener(new TaskListener() {
+
+            public void taskFinished(org.openide.util.Task task)
+            {
+                delegate = null;
+            }
+
+        });
+        return task;
+    }
+
+    public void setRepositoryRoot(String repositoryRoot)
+    {
+        this.repositoryRoot = repositoryRoot;
+        logger = null;
+    }
+
+    public void run()
+    {
+        setProgress();
+        performIntern();
+    }
+
+    protected void performIntern()
+    {
+        try {
+            Git.LOG.log(Level.FINE, &quot;Start - {0}&quot;, displayName); // NOI18N
+
+            if (!canceled)
+                perform();
+            Git.LOG.log(Level.FINE, &quot;End - {0}&quot;, displayName); // NOI18N
+
+        } finally {
+            finnishProgress();
+            if (logger != null)
+                logger.closeLog();
+        }
+    }
+
+    protected abstract void perform();
+
+    public synchronized boolean isCanceled()
+    {
+        return canceled;
+    }
+
+    public synchronized boolean cancel()
+    {
+        if (canceled)
+            return false;
+        if (task != null)
+            task.cancel();
+        if (delegate != null)
+            delegate.cancel();
+        Git.getInstance().clearRequestProcessor(repositoryRoot);
+        getProgressHandle().finish();
+        canceled = true;
+        return true;
+    }
+
+    void setCancellableDelegate(Cancellable cancellable)
+    {
+        this.delegate = cancellable;
+    }
+
+    public void setDisplayName(String displayName)
+    {
+        if (originalDisplayName.equals(&quot;&quot;)) // NOI18N
+            originalDisplayName = displayName;
+        this.displayName = displayName;
+        setProgress();
+    }
+
+    private void setProgressQueued()
+    {
+        if (progressHandle != null)
+            progressHandle.progress(NbBundle.getMessage(GitProgressSupport.class, &quot;LBL_Queued&quot;, displayName));
+    }
+
+    private void setProgress()
+    {
+        if (progressHandle != null)
+            progressHandle.progress(displayName);
+    }
+
+    protected String getDisplayName()
+    {
+        return displayName;
+    }
+
+    protected ProgressHandle getProgressHandle()
+    {
+        if (progressHandle == null)
+            progressHandle = ProgressHandleFactory.createHandle(displayName, this);
+        return progressHandle;
+    }
+
+    protected void startProgress()
+    {
+        getProgressHandle().start();
+    }
+
+    protected void finnishProgress()
+    {
+        getProgressHandle().finish();
+    }
+
+    public OutputLogger getLogger()
+    {
+        if (logger == null)
+            logger = Git.getInstance().getLogger(repositoryRoot);
+        return logger;
+    }
 
 }
\ No newline at end of file</diff>
      <filename>src/org/nbgit/GitProgressSupport.java</filename>
    </modified>
    <modified>
      <diff>@@ -1,8 +1,8 @@
 package org.nbgit;
 
 public interface GitRepository {
-	public static final String REVISION_BASE = &quot;BASE&quot;; // NOI18N
-	public static final String REVISION_CURRENT = &quot;LOCAL&quot;; // NOI18N
-	public static final String REVISION_HEAD = &quot;HEAD&quot;; // NOI18N
-	public static final String GIT_DIR = &quot;.git&quot;; // NOI18N
+    public static final String REVISION_BASE = &quot;BASE&quot;; // NOI18N
+    public static final String REVISION_CURRENT = &quot;LOCAL&quot;; // NOI18N
+    public static final String REVISION_HEAD = &quot;HEAD&quot;; // NOI18N
+    public static final String GIT_DIR = &quot;.git&quot;; // NOI18N
 }</diff>
      <filename>src/org/nbgit/GitRepository.java</filename>
    </modified>
    <modified>
      <diff>@@ -56,80 +56,80 @@ import org.openide.util.NbBundle;
  */
 public class GitVCS extends VersioningSystem implements PropertyChangeListener, CollocationQueryImplementation {
 
-	final private GitInterceptor gitInterceptor = new GitInterceptor();
-	final private GitAnnotator gitAnnotator = new GitAnnotator();
+    final private GitInterceptor gitInterceptor = new GitInterceptor();
+    final private GitAnnotator gitAnnotator = new GitAnnotator();
 
-	public GitVCS()
-	{
-		putProperty(PROP_DISPLAY_NAME, NbBundle.getMessage(GitVCS.class, &quot;CTL_Git_DisplayName&quot;)); // NOI18N
-		putProperty(PROP_MENU_LABEL, NbBundle.getMessage(GitVCS.class, &quot;CTL_Git_MainMenu&quot;)); // NOI18N
+    public GitVCS()
+    {
+        putProperty(PROP_DISPLAY_NAME, NbBundle.getMessage(GitVCS.class, &quot;CTL_Git_DisplayName&quot;)); // NOI18N
+        putProperty(PROP_MENU_LABEL, NbBundle.getMessage(GitVCS.class, &quot;CTL_Git_MainMenu&quot;)); // NOI18N
 
-		Git.getInstance().addPropertyChangeListener(this);
-		Git.getInstance().getStatusCache().addPropertyChangeListener(this);
-	}
+        Git.getInstance().addPropertyChangeListener(this);
+        Git.getInstance().getStatusCache().addPropertyChangeListener(this);
+    }
 
-	public boolean areCollocated(File a, File b)
-	{
-		File fra = getTopmostManagedAncestor(a);
-		File frb = getTopmostManagedAncestor(b);
+    public boolean areCollocated(File a, File b)
+    {
+        File fra = getTopmostManagedAncestor(a);
+        File frb = getTopmostManagedAncestor(b);
 
-		return fra != null &amp;&amp; fra.equals(frb);
-	}
+        return fra != null &amp;&amp; fra.equals(frb);
+    }
 
-	public File findRoot(File file)
-	{
-		return getTopmostManagedAncestor(file);
-	}
+    public File findRoot(File file)
+    {
+        return getTopmostManagedAncestor(file);
+    }
 
-	/**
-	 * Tests whether the file is managed by this versioning system. If it is, 
-	 * the method should return the topmost 
-	 * ancestor of the file that is still versioned.
-	 *  
-	 * @param file a file
-	 * @return File the file itself or one of its ancestors or null if the 
-	 *  supplied file is NOT managed by this versioning system
-	 */
-	@Override
-	public File getTopmostManagedAncestor(File file)
-	{
-		return Git.getInstance().getTopmostManagedParent(file);
-	}
+    /**
+     * Tests whether the file is managed by this versioning system. If it is,
+     * the method should return the topmost
+     * ancestor of the file that is still versioned.
+     *
+     * @param file a file
+     * @return File the file itself or one of its ancestors or null if the
+     *  supplied file is NOT managed by this versioning system
+     */
+    @Override
+    public File getTopmostManagedAncestor(File file)
+    {
+        return Git.getInstance().getTopmostManagedParent(file);
+    }
 
-	/**
-	 * Coloring label, modifying icons, providing action on file
-	 */
-	@Override
-	public VCSAnnotator getVCSAnnotator()
-	{
-		return gitAnnotator;
-	}
+    /**
+     * Coloring label, modifying icons, providing action on file
+     */
+    @Override
+    public VCSAnnotator getVCSAnnotator()
+    {
+        return gitAnnotator;
+    }
 
-	/**
-	 * Handle file system events such as delete, create, remove etc.
-	 */
-	@Override
-	public VCSInterceptor getVCSInterceptor()
-	{
-		return gitInterceptor;
-	}
+    /**
+     * Handle file system events such as delete, create, remove etc.
+     */
+    @Override
+    public VCSInterceptor getVCSInterceptor()
+    {
+        return gitInterceptor;
+    }
 
-	@Override
-	public void getOriginalFile(File workingCopy, File originalFile)
-	{
-		Git.getInstance().getOriginalFile(workingCopy, originalFile);
-	}
+    @Override
+    public void getOriginalFile(File workingCopy, File originalFile)
+    {
+        Git.getInstance().getOriginalFile(workingCopy, originalFile);
+    }
 
-	@SuppressWarnings(&quot;unchecked&quot;) // Property Change event.getNewValue returning Object
-	public void propertyChange(PropertyChangeEvent event)
-	{
-		if (event.getPropertyName().equals(StatusCache.PROP_FILE_STATUS_CHANGED)) {
-			StatusCache.ChangedEvent changedEvent = (StatusCache.ChangedEvent) event.getNewValue();
-			fireStatusChanged(changedEvent.getFile());
-		} else if (event.getPropertyName().equals(Git.PROP_ANNOTATIONS_CHANGED))
-			fireAnnotationsChanged((Set&lt;File&gt;) event.getNewValue());
-		else if (event.getPropertyName().equals(Git.PROP_VERSIONED_FILES_CHANGED))
-			fireVersionedFilesChanged();
-	}
+    @SuppressWarnings(&quot;unchecked&quot;) // Property Change event.getNewValue returning Object
+    public void propertyChange(PropertyChangeEvent event)
+    {
+        if (event.getPropertyName().equals(StatusCache.PROP_FILE_STATUS_CHANGED)) {
+            StatusCache.ChangedEvent changedEvent = (StatusCache.ChangedEvent) event.getNewValue();
+            fireStatusChanged(changedEvent.getFile());
+        } else if (event.getPropertyName().equals(Git.PROP_ANNOTATIONS_CHANGED))
+            fireAnnotationsChanged((Set&lt;File&gt;) event.getNewValue());
+        else if (event.getPropertyName().equals(Git.PROP_VERSIONED_FILES_CHANGED))
+            fireVersionedFilesChanged();
+    }
 
 }
\ No newline at end of file</diff>
      <filename>src/org/nbgit/GitVCS.java</filename>
    </modified>
    <modified>
      <diff>@@ -59,256 +59,256 @@ import org.openide.windows.OutputWriter;
  */
 public class OutputLogger {
 
-	private InputOutput log;
-	private String repositoryRootString;
-	private static final RequestProcessor rp = new RequestProcessor(&quot;GitOutput&quot;, 1);
-	public static final int MAX_LINES_TO_PRINT = 500;
-	private static final String MSG_TOO_MANY_LINES = &quot;The number of output lines is greater than 500; see message log for complete output&quot;;
-
-	public static OutputLogger getLogger(String repositoryRoot)
-	{
-		if (repositoryRoot != null)
-			return new OutputLogger(repositoryRoot);
-		else
-			return new NullLogger();
-	}
-
-	private OutputLogger(String repositoryRoot)
-	{
-		repositoryRootString = repositoryRoot;
-		log = IOProvider.getDefault().getIO(repositoryRootString, false);
-	}
-
-	private OutputLogger()
-	{
-	}
-
-	public void closeLog()
-	{
-		rp.post(new Runnable() {
-
-			public void run()
-			{
-				log.getOut().flush();
-				log.getOut().close();
-				log.getErr().flush();
-				log.getErr().close();
-			}
-
-		});
-	}
-
-	public void flushLog()
-	{
-		rp.post(new Runnable() {
-
-			public void run()
-			{
-				log.getOut().flush();
-				log.getErr().flush();
-			}
-
-		});
-	}
-
-	/**
-	 * Print contents of list to OutputLogger's tab
-	 *
-	 * @param list to print out
-	 *
-	 */
-	public void output(final List&lt;String&gt; list)
-	{
-		if (list.isEmpty())
-			return;
-
-		rp.post(new Runnable() {
-
-			public void run()
-			{
-				log.select();
-				OutputWriter out = log.getOut();
-
-				int lines = list.size();
-				if (lines &gt; MAX_LINES_TO_PRINT) {
-					out.println(list.get(1));
-					out.println(list.get(2));
-					out.println(list.get(3));
-					out.println(&quot;...&quot;);
-					out.println(list.get(list.size() - 1));
-					out.println(MSG_TOO_MANY_LINES);
-					for (String s : list) {
-						Git.LOG.log(Level.WARNING, s);
-					}
-				} else
-					for (String s : list) {
-						out.println(s);
-					}
-				out.flush();
-			}
-
-		});
-	}
-
-	/**
-	 * Print msg to OutputLogger's tab
-	 *
-	 * @param String msg to print out
-	 *
-	 */
-	public void output(final String msg)
-	{
-		if (msg == null)
-			return;
-
-		rp.post(new Runnable() {
-
-			public void run()
-			{
-				log.select();
-
-				log.getOut().println(msg);
-				log.getOut().flush();
-			}
-
-		});
-	}
-
-	/**
-	 * Print msg to OutputLogger's tab in Red
-	 *
-	 * @param String msg to print out
-	 *
-	 */
-	public void outputInRed(final String msg)
-	{
-		if (msg == null)
-			return;
-
-		rp.post(new Runnable() {
-
-			public void run()
-			{
-				log.select();
-				log.getErr().println(msg);
-				log.getErr().flush();
-			}
-
-		});
-	}
-
-	/**
-	 * Print URL to OutputLogger's tab as an active Hyperlink
-	 *
-	 * @param String sURL to print out
-	 *
-	 */
-	public void outputLink(final String sURL)
-	{
-		if (sURL == null)
-			return;
-
-		rp.post(new Runnable() {
-
-			public void run()
-			{
-				log.select();
-				try {
-					OutputWriter out = log.getOut();
-
-					OutputListener listener = new OutputListener() {
-
-						public void outputLineAction(OutputEvent ev)
-						{
-							try {
-								HtmlBrowser.URLDisplayer.getDefault().showURL(new URL(sURL));
-							} catch (IOException ex) {
-								// Ignore
-							}
-						}
-
-						public void outputLineSelected(OutputEvent ev)
-						{
-						}
-
-						public void outputLineCleared(OutputEvent ev)
-						{
-						}
-
-					};
-					out.println(sURL, listener, true);
-					out.flush();
-				} catch (IOException ex) {
-					// Ignore
-				}
-			}
-
-		});
-	}
-
-	/**
-	 * Select and Clear OutputLogger's tab
-	 *
-	 * @param list to print out
-	 *
-	 */
-	public void clearOutput()
-	{
-		rp.post(new Runnable() {
-
-			public void run()
-			{
-				log.select();
-				OutputWriter out = log.getOut();
-
-				try {
-					out.reset();
-				} catch (IOException ex) {
-					// Ignore Exception
-				}
-				out.flush();
-			}
-
-		});
-	}
-
-	private static class NullLogger extends OutputLogger {
-
-		@Override
-		public void closeLog()
-		{
-		}
-
-		@Override
-		public void flushLog()
-		{
-		}
-
-		@Override
-		public void output(List&lt;String&gt; list)
-		{
-		}
-
-		@Override
-		public void output(String msg)
-		{
-		}
-
-		@Override
-		public void outputInRed(String msg)
-		{
-		}
-
-		@Override
-		public void outputLink(final String sURL)
-		{
-		}
-
-		@Override
-		public void clearOutput()
-		{
-		}
-
-	}
+    private InputOutput log;
+    private String repositoryRootString;
+    private static final RequestProcessor rp = new RequestProcessor(&quot;GitOutput&quot;, 1);
+    public static final int MAX_LINES_TO_PRINT = 500;
+    private static final String MSG_TOO_MANY_LINES = &quot;The number of output lines is greater than 500; see message log for complete output&quot;;
+
+    public static OutputLogger getLogger(String repositoryRoot)
+    {
+        if (repositoryRoot != null)
+            return new OutputLogger(repositoryRoot);
+        else
+            return new NullLogger();
+    }
+
+    private OutputLogger(String repositoryRoot)
+    {
+        repositoryRootString = repositoryRoot;
+        log = IOProvider.getDefault().getIO(repositoryRootString, false);
+    }
+
+    private OutputLogger()
+    {
+    }
+
+    public void closeLog()
+    {
+        rp.post(new Runnable() {
+
+            public void run()
+            {
+                log.getOut().flush();
+                log.getOut().close();
+                log.getErr().flush();
+                log.getErr().close();
+            }
+
+        });
+    }
+
+    public void flushLog()
+    {
+        rp.post(new Runnable() {
+
+            public void run()
+            {
+                log.getOut().flush();
+                log.getErr().flush();
+            }
+
+        });
+    }
+
+    /**
+     * Print contents of list to OutputLogger's tab
+     *
+     * @param list to print out
+     *
+     */
+    public void output(final List&lt;String&gt; list)
+    {
+        if (list.isEmpty())
+            return;
+
+        rp.post(new Runnable() {
+
+            public void run()
+            {
+                log.select();
+                OutputWriter out = log.getOut();
+
+                int lines = list.size();
+                if (lines &gt; MAX_LINES_TO_PRINT) {
+                    out.println(list.get(1));
+                    out.println(list.get(2));
+                    out.println(list.get(3));
+                    out.println(&quot;...&quot;);
+                    out.println(list.get(list.size() - 1));
+                    out.println(MSG_TOO_MANY_LINES);
+                    for (String s : list) {
+                        Git.LOG.log(Level.WARNING, s);
+                    }
+                } else
+                    for (String s : list) {
+                        out.println(s);
+                    }
+                out.flush();
+            }
+
+        });
+    }
+
+    /**
+     * Print msg to OutputLogger's tab
+     *
+     * @param String msg to print out
+     *
+     */
+    public void output(final String msg)
+    {
+        if (msg == null)
+            return;
+
+        rp.post(new Runnable() {
+
+            public void run()
+            {
+                log.select();
+
+                log.getOut().println(msg);
+                log.getOut().flush();
+            }
+
+        });
+    }
+
+    /**
+     * Print msg to OutputLogger's tab in Red
+     *
+     * @param String msg to print out
+     *
+     */
+    public void outputInRed(final String msg)
+    {
+        if (msg == null)
+            return;
+
+        rp.post(new Runnable() {
+
+            public void run()
+            {
+                log.select();
+                log.getErr().println(msg);
+                log.getErr().flush();
+            }
+
+        });
+    }
+
+    /**
+     * Print URL to OutputLogger's tab as an active Hyperlink
+     *
+     * @param String sURL to print out
+     *
+     */
+    public void outputLink(final String sURL)
+    {
+        if (sURL == null)
+            return;
+
+        rp.post(new Runnable() {
+
+            public void run()
+            {
+                log.select();
+                try {
+                    OutputWriter out = log.getOut();
+
+                    OutputListener listener = new OutputListener() {
+
+                        public void outputLineAction(OutputEvent ev)
+                        {
+                            try {
+                                HtmlBrowser.URLDisplayer.getDefault().showURL(new URL(sURL));
+                            } catch (IOException ex) {
+                                // Ignore
+                            }
+                        }
+
+                        public void outputLineSelected(OutputEvent ev)
+                        {
+                        }
+
+                        public void outputLineCleared(OutputEvent ev)
+                        {
+                        }
+
+                    };
+                    out.println(sURL, listener, true);
+                    out.flush();
+                } catch (IOException ex) {
+                    // Ignore
+                }
+            }
+
+        });
+    }
+
+    /**
+     * Select and Clear OutputLogger's tab
+     *
+     * @param list to print out
+     *
+     */
+    public void clearOutput()
+    {
+        rp.post(new Runnable() {
+
+            public void run()
+            {
+                log.select();
+                OutputWriter out = log.getOut();
+
+                try {
+                    out.reset();
+                } catch (IOException ex) {
+                    // Ignore Exception
+                }
+                out.flush();
+            }
+
+        });
+    }
+
+    private static class NullLogger extends OutputLogger {
+
+        @Override
+        public void closeLog()
+        {
+        }
+
+        @Override
+        public void flushLog()
+        {
+        }
+
+        @Override
+        public void output(List&lt;String&gt; list)
+        {
+        }
+
+        @Override
+        public void output(String msg)
+        {
+        }
+
+        @Override
+        public void outputInRed(String msg)
+        {
+        }
+
+        @Override
+        public void outputLink(final String sURL)
+        {
+        }
+
+        @Override
+        public void clearOutput()
+        {
+        }
+
+    }
 
 }
\ No newline at end of file</diff>
      <filename>src/org/nbgit/OutputLogger.java</filename>
    </modified>
    <modified>
      <diff>@@ -71,733 +71,733 @@ import org.openide.filesystems.FileUtil;
  */
 public class StatusCache {
 
-	/**
-	 * Indicates that status of a file changed and listeners SHOULD check new status
-	 * values if they are interested in this file.
-	 * The New value is a ChangedEvent object (old StatusInfo object may be null)
-	 */
-	public static final String PROP_FILE_STATUS_CHANGED = &quot;status.changed&quot;; // NOI18N
-	/**
-	 * A special map saying that no file inside the folder is managed.
-	 */
-	private static final Map&lt;File, StatusInfo&gt; NOT_MANAGED_MAP = new NotManagedMap();
-	public static final File REPOSITORY_STATUS_UNKNOWN = null;	// Constant File objects that can be safely reused
-	// Files that have a revision number cannot share StatusInfo objects
-	private static final StatusInfo FILE_STATUS_EXCLUDED = new StatusInfo(StatusInfo.STATUS_NOTVERSIONED_EXCLUDED, false);
-	private static final StatusInfo FILE_STATUS_EXCLUDED_DIRECTORY = new StatusInfo(StatusInfo.STATUS_NOTVERSIONED_EXCLUDED, true);
-	private static final StatusInfo FILE_STATUS_UPTODATE_DIRECTORY = new StatusInfo(StatusInfo.STATUS_VERSIONED_UPTODATE, true);
-	private static final StatusInfo FILE_STATUS_NOTMANAGED = new StatusInfo(StatusInfo.STATUS_NOTVERSIONED_NOTMANAGED, false);
-	private static final StatusInfo FILE_STATUS_NOTMANAGED_DIRECTORY = new StatusInfo(StatusInfo.STATUS_NOTVERSIONED_NOTMANAGED, true);
-	private static final StatusInfo FILE_STATUS_UNKNOWN = new StatusInfo(StatusInfo.STATUS_UNKNOWN, false);
-	private static final StatusInfo FILE_STATUS_NEWLOCALLY = new StatusInfo(StatusInfo.STATUS_NOTVERSIONED_NEWLOCALLY, false);
-	private static final StatusInfo FILE_STATUS_CONFLICT = new StatusInfo(StatusInfo.STATUS_VERSIONED_CONFLICT, false);
-	private static final StatusInfo FILE_STATUS_REMOVEDLOCALLY = new StatusInfo(StatusInfo.STATUS_VERSIONED_REMOVEDLOCALLY, false);
-	private PropertyChangeSupport listenerSupport = new PropertyChangeSupport(this);
-	/**
-	 * Caches status of files in memory and on disk
-	 */
-	private final Turbo turbo;
-	private final String FILE_STATUS_MAP = DiskMapTurboProvider.ATTR_STATUS_MAP;
-	private DiskMapTurboProvider cacheProvider;
-	private Git git;
-	private Set&lt;FileSystem&gt; filesystemsToRefresh;
-
-	StatusCache(Git git)
-	{
-		this.git = git;
-		cacheProvider = new DiskMapTurboProvider();
-		turbo = Turbo.createCustom(new CustomProviders() {
-
-			private final Set providers = Collections.singleton(cacheProvider);
-
-			public Iterator providers()
-			{
-				return providers.iterator();
-			}
-
-		}, 200, 5000);
-	}
-
-	// --- Public interface -------------------------------------------------
-	/**
-	 * Lists &lt;b&gt;modified files&lt;/b&gt; and all folders that are known to be inside
-	 * this folder. There are locally modified files present
-	 * plus any files that exist in the folder in the remote repository.
-	 *
-	 * @param dir folder to list
-	 * @return
-	 */
-	public File[] listFiles(File dir)
-	{
-		Set&lt;File&gt; files = getScannedFiles(dir, null).keySet();
-		return files.toArray(new File[files.size()]);
-	}
-
-	/**
-	 * Lists &lt;b&gt;interesting files&lt;/b&gt; that are known to be inside given folders.
-	 * These are locally and remotely modified and ignored files.
-	 *
-	 * &lt;p&gt;This method returns both folders and files.
-	 *
-	 * @param context context to examine
-	 * @param includeStatus limit returned files to those having one of supplied statuses
-	 * @return File [] array of interesting files
-	 */
-	public File[] listFiles(VCSContext context, int includeStatus)
-	{
-		Set&lt;File&gt; set = new HashSet&lt;File&gt;();
-		Map allFiles = cacheProvider.getAllModifiedValues();
-		if (allFiles == null) {
-			Git.LOG.log(Level.FINE, &quot;StatusCache: listFiles(): allFiles == null&quot;); // NOI18N
-			return new File[0];
-		}
-
-		for (Iterator i = allFiles.keySet().iterator(); i.hasNext();) {
-			File file = (File) i.next();
-			StatusInfo info = (StatusInfo) allFiles.get(file);
-			if ((info.getStatus() &amp; includeStatus) == 0)
-				continue;
-			Set&lt;File&gt; roots = context.getRootFiles();
-			for (File root : roots) {
-				if (VersioningSupport.isFlat(root)) {
-					if (file.equals(root) || file.getParentFile().equals(root)) {
-						set.add(file);
-						break;
-					}
-				} else if (Utils.isAncestorOrEqual(root, file)) {
-					set.add(file);
-					break;
-				}
-			}
-		}
-		if (context.getExclusions().size() &gt; 0)
-			for (Iterator i = context.getExclusions().iterator(); i.hasNext();) {
-				File excluded = (File) i.next();
-				for (Iterator j = set.iterator(); j.hasNext();) {
-					File file = (File) j.next();
-					if (Utils.isAncestorOrEqual(excluded, file))
-						j.remove();
-				}
-			}
-		return set.toArray(new File[set.size()]);
-	}
-
-	/**
-	 * Lists &lt;b&gt;interesting files&lt;/b&gt; that are known to be inside given folders.
-	 * These are locally and remotely modified and ignored files.
-	 *
-	 * &lt;p&gt;Comparing to CVS this method returns both folders and files.
-	 *
-	 * @param roots context to examine
-	 * @param includeStatus limit returned files to those having one of supplied statuses
-	 * @return File [] array of interesting files
-	 */
-	public File[] listFiles(File[] roots, int includeStatus)
-	{
-		Set&lt;File&gt; set = new HashSet&lt;File&gt;();
-		Map&lt;File, StatusInfo&gt; allFiles = cacheProvider.getAllModifiedValues();
-
-		for (File file : allFiles.keySet()) {
-			StatusInfo info = allFiles.get(file);
-			if ((info.getStatus() &amp; includeStatus) == 0)
-				continue;
-			for (int j = 0; j &lt; roots.length; j++) {
-				File root = roots[j];
-				if (VersioningSupport.isFlat(root)) {
-					if (file.getParentFile().equals(root)) {
-						set.add(file);
-						break;
-					}
-				} else if (Utils.isAncestorOrEqual(root, file)) {
-					set.add(file);
-					break;
-				}
-			}
-		}
-		return set.toArray(new File[set.size()]);
-	}
-
-	/**
-	 * Check if this context has at least one file with the passed in status
-	 *
-	 * @param context context to examine
-	 * @param includeStatus file status to check for
-	 * @return boolean true if this context contains at least one file with the includeStatus, false otherwise
-	 */
-	public boolean containsFileOfStatus(VCSContext context, int includeStatus)
-	{
-		Map&lt;File, StatusInfo&gt; allFiles = cacheProvider.getAllModifiedValues();
-		if (allFiles == null) {
-			Git.LOG.log(Level.FINE, &quot;containsFileOfStatus(): allFiles == null&quot;); // NOI18N
-			return false;
-		}
-
-		Set&lt;File&gt; roots = context.getRootFiles();
-		Set&lt;File&gt; exclusions = context.getExclusions();
-		Set&lt;File&gt; setAllFiles = allFiles.keySet();
-		boolean bExclusions = exclusions != null &amp;&amp; exclusions.size() &gt; 0;
-		boolean bContainsFile = false;
-
-		for (File file : setAllFiles) {
-			StatusInfo info = allFiles.get(file);
-			if ((info.getStatus() &amp; includeStatus) == 0)
-				continue;
-			for (File root : roots) {
-				if (VersioningSupport.isFlat(root)) {
-					if (file.equals(root) || file.getParentFile().equals(root)) {
-						bContainsFile = true;
-						break;
-					}
-				} else if (Utils.isAncestorOrEqual(root, file)) {
-					bContainsFile = true;
-					break;
-				}
-			}
-			// Check it is not an excluded file
-			if (bContainsFile &amp;&amp; bExclusions) {
-				for (File excluded : exclusions) {
-					if (!Utils.isAncestorOrEqual(excluded, file))
-						return true;
-				}
-			} else if (bContainsFile)
-				return true;
-		}
-		return false;
-	}
-
-	/**
-	 * Determines the versioning status of a file. This method accesses disk and may block for a long period of time.
-	 *
-	 * @param file file to get status for
-	 * @return StatusInfo structure containing the file status
-	 * @see StatusInfo
-	 */
-	public StatusInfo getStatus(File file)
-	{
-		if (file.isDirectory() &amp;&amp; excludeFile(file))
-			return StatusCache.FILE_STATUS_EXCLUDED_DIRECTORY;
-		File dir = file.getParentFile();
-		if (dir == null)
-			return StatusCache.FILE_STATUS_NOTMANAGED;
-		Map files = getScannedFiles(dir, null);
-		if (files == StatusCache.NOT_MANAGED_MAP)
-			return StatusCache.FILE_STATUS_NOTMANAGED;
-		StatusInfo fi = (StatusInfo) files.get(file);
-		if (fi != null)
-			return fi;
-		if (!exists(file))
-			return StatusCache.FILE_STATUS_UNKNOWN;
-		if (file.isDirectory())
-			return refresh(file, REPOSITORY_STATUS_UNKNOWN);
-		else
-			return new StatusInfo(StatusInfo.STATUS_VERSIONED_UPTODATE, false);
-	}
-
-	/**
-	 * Looks up cached file status.
-	 *
-	 * @param file file to check
-	 * @return give file's status or null if the file's status is not in cache
-	 */
-	@SuppressWarnings(&quot;unchecked&quot;) // Need to change turbo module to remove warning at source
-	StatusInfo getCachedStatus( File file, boolean bCheckSharability)
-	{
-		File parent = file.getParentFile();
-		if (parent == null)
-			return StatusCache.FILE_STATUS_NOTMANAGED_DIRECTORY;
-
-		Map&lt;File, StatusInfo&gt; files = (Map&lt;File, StatusInfo&gt;) turbo.readEntry(parent, FILE_STATUS_MAP);
-		StatusInfo fi = files != null ? files.get(file) : null;
-		if (fi != null)
-			return fi;
-
-		if (file.isDirectory())
-			if (excludeFile(file))
-				return StatusCache.FILE_STATUS_EXCLUDED_DIRECTORY;
-			else
-				return StatusCache.FILE_STATUS_UPTODATE_DIRECTORY;
-
-		return fi;
-	}
-
-	private StatusInfo refresh(File file, File repoStat, boolean forceChangeEvent)
-	{
-		Git.LOG.log(Level.FINE, &quot;refresh(): {0}&quot;, file); // NOI18N
-		File dir = file.getParentFile();
-		if (dir == null)
-			return StatusCache.FILE_STATUS_NOTMANAGED;
-
-		Map&lt;File, StatusInfo&gt; files = getScannedFiles(dir, null); // Has side effect of updating the cache
-		if (files == StatusCache.NOT_MANAGED_MAP &amp;&amp; repoStat == StatusCache.REPOSITORY_STATUS_UNKNOWN)
-			return StatusCache.FILE_STATUS_NOTMANAGED;
-		StatusInfo current = files.get(file);
-
-		StatusInfo fi = createFileInformation(file, true);
-
-		if (StatusInfo.equivalent(fi, current)) {
-			if (forceChangeEvent)
-				fireFileStatusChanged(file, current, fi);
-			return fi;
-		}
-
-		// do not include uptodate files into cache, missing directories must be included
-		if (current == null &amp;&amp; !fi.isDirectory() &amp;&amp; fi.getStatus() == StatusInfo.STATUS_VERSIONED_UPTODATE) {
-			if (forceChangeEvent)
-				fireFileStatusChanged(file, current, fi);
-			return fi;
-		}
-
-		file = FileUtil.normalizeFile(file);
-		dir = FileUtil.normalizeFile(dir);
-		Map&lt;File, StatusInfo&gt; newFiles = new HashMap&lt;File, StatusInfo&gt;(files);
-		if (fi.getStatus() == StatusInfo.STATUS_UNKNOWN) {
-			newFiles.remove(file);
-			turbo.writeEntry(file, FILE_STATUS_MAP, null);  // remove mapping in case of directories
-		} else if (fi.getStatus() == StatusInfo.STATUS_VERSIONED_UPTODATE &amp;&amp; file.isFile())
-			newFiles.remove(file);
-		else
-			newFiles.put(file, fi);
-		assert newFiles.containsKey(dir) == false;
-		turbo.writeEntry(dir, FILE_STATUS_MAP, newFiles.size() == 0 ? null : newFiles);
-
-		if (file.isDirectory() &amp;&amp; needRecursiveRefresh(fi, current)) {
-			File[] content = listFiles(file); // Has side effect of updating the cache
-			for (int i = 0; i &lt; content.length; i++) {
-				refresh(content[i], StatusCache.REPOSITORY_STATUS_UNKNOWN);
-			}
-		}
-		fireFileStatusChanged(file, current, fi);
-		return fi;
-	}
-
-	private StatusInfo createFileInformation(File file, Boolean callStatus)
-	{
-		Git.LOG.log(Level.FINE, &quot;createFileInformation(): {0} {1}&quot;, new Object[]{file, callStatus}); // NOI18N
-		if (file == null)
-			return FILE_STATUS_UNKNOWN;
-		if (git.isAdministrative(file))
-			return FILE_STATUS_EXCLUDED_DIRECTORY; // Excluded
-
-		File rootManagedFolder = git.getTopmostManagedParent(file);
-		if (rootManagedFolder == null)
-			return FILE_STATUS_UNKNOWN; // Avoiding returning NOT_MANAGED dir or file
-
-		if (file.isDirectory())
-			if (GitIgnore.isIgnored(file))
-				return FILE_STATUS_EXCLUDED_DIRECTORY;
-			else
-				return FILE_STATUS_UPTODATE_DIRECTORY;
-
-		if (callStatus == false) {
-			if (GitIgnore.isIgnored(file))
-				return FILE_STATUS_EXCLUDED;
-			return null;
-		}
-
-		return GitCommand.getSingleStatus(rootManagedFolder, file);
-	}
-
-	/**
-	 * Refreshes the status of the file given the repository status. Repository status is filled
-	 * in when this method is called while processing server output.
-	 *
-	 * &lt;p&gt;Note: it's not necessary if you use Subversion.getClient(), it
-	 * updates the cache automatically using onNotify(). It's not
-	 * fully reliable for removed files.
-	 *
-	 * @param file
-	 * @param repositoryStatus
-	 */
-	public StatusInfo refresh(File file, File repositoryStatus)
-	{
-		return refresh(file, repositoryStatus, false);
-	}
-
-	@SuppressWarnings(&quot;unchecked&quot;) // Need to change turbo module to remove warning at source
-	public Map&lt;File, StatusInfo&gt; getScannedFiles(File dir, Map&lt;File, StatusInfo&gt; interestingFiles)
-	{
-		Map&lt;File, StatusInfo&gt; files;
-
-		files = (Map&lt;File, StatusInfo&gt;) turbo.readEntry(dir, FILE_STATUS_MAP);
-		if (files != null)
-			return files;
-
-		if (!dir.exists() &amp;&amp; interestingFiles == null)
-			return StatusCache.NOT_MANAGED_MAP;
-
-		dir = FileUtil.normalizeFile(dir);
-		files = scanFolder(dir, interestingFiles);
-		assert files.containsKey(dir) == false;
-		turbo.writeEntry(dir, FILE_STATUS_MAP, files);
-		if (interestingFiles == null)
-			for (Iterator i = files.keySet().iterator(); i.hasNext();) {
-				File file = (File) i.next();
-				StatusInfo info = files.get(file);
-				if ((info.getStatus() &amp; (StatusInfo.STATUS_LOCAL_CHANGE | StatusInfo.STATUS_NOTVERSIONED_EXCLUDED)) != 0)
-					fireFileStatusChanged(file, null, info);
-			}
-		return files;
-	}
-
-	public void refreshFileStatus(File file, StatusInfo fi, Map&lt;File, StatusInfo&gt; interestingFiles)
-	{
-		refreshFileStatus(file, fi, interestingFiles, false);
-	}
-
-	public void refreshFileStatus(File file, StatusInfo fi, Map&lt;File, StatusInfo&gt; interestingFiles, boolean alwaysFireEvent)
-	{
-		if (file == null || fi == null)
-			return;
-		File dir = file.getParentFile();
-		if (dir == null)
-			return;
-
-		Map&lt;File, StatusInfo&gt; files = getScannedFiles(dir, interestingFiles);
-
-		if (files == null || files == StatusCache.NOT_MANAGED_MAP)
-			return;
-		StatusInfo current = files.get(file);
-		if (StatusInfo.equivalent(fi, current))
-			if (StatusInfo.equivalent(FILE_STATUS_NEWLOCALLY, fi))
-				if (GitIgnore.isIgnored(file)) {
-					Git.LOG.log(Level.FINE, &quot;refreshFileStatus() file: {0} was LocallyNew but is NotSharable&quot;, file.getAbsolutePath()); // NOI18N
-					fi = FILE_STATUS_EXCLUDED;
-				} else
-					return;
-			else if (!StatusInfo.equivalent(FILE_STATUS_REMOVEDLOCALLY, fi))
-				return;
-		if (StatusInfo.equivalent(FILE_STATUS_NEWLOCALLY, fi))
-			if (StatusInfo.equivalent(FILE_STATUS_EXCLUDED, current)) {
-				Git.LOG.log(Level.FINE, &quot;refreshFileStatus() file: {0} was LocallyNew but is Excluded&quot;, file.getAbsolutePath()); // NOI18N
-				return;
-			} else if (current == null)
-				if (GitIgnore.isIgnored(file)) {
-					Git.LOG.log(Level.FINE, &quot;refreshFileStatus() file: {0} was LocallyNew but current is null and is not NotSharable&quot;, file.getAbsolutePath()); // NOI18N
-					fi = FILE_STATUS_EXCLUDED;
-				}
-		file = FileUtil.normalizeFile(file);
-		dir = FileUtil.normalizeFile(dir);
-		Map&lt;File, StatusInfo&gt; newFiles = new HashMap&lt;File, StatusInfo&gt;(files);
-		if (fi.getStatus() == StatusInfo.STATUS_UNKNOWN) {
-			newFiles.remove(file);
-			turbo.writeEntry(file, FILE_STATUS_MAP, null);  // remove mapping in case of directories
-		} else if (fi.getStatus() == StatusInfo.STATUS_VERSIONED_UPTODATE &amp;&amp; file.isFile())
-			newFiles.remove(file);
-		else
-			newFiles.put(file, fi);
-		assert files.containsKey(dir) == false;
-		turbo.writeEntry(dir, FILE_STATUS_MAP, newFiles);
-
-		if (interestingFiles == null)
-			fireFileStatusChanged(file, current, fi);
-		else if (alwaysFireEvent)
-			fireFileStatusChanged(file, null, fi);
-
-		return;
-	}
-
-	private boolean needRecursiveRefresh(StatusInfo fi, StatusInfo current)
-	{
-		if (fi.getStatus() == StatusInfo.STATUS_NOTVERSIONED_EXCLUDED ||
-			current != null &amp;&amp; current.getStatus() == StatusInfo.STATUS_NOTVERSIONED_EXCLUDED)
-			return true;
-		if (fi.getStatus() == StatusInfo.STATUS_NOTVERSIONED_NOTMANAGED ||
-			current != null &amp;&amp; current.getStatus() == StatusInfo.STATUS_NOTVERSIONED_NOTMANAGED)
-			return true;
-		return false;
-	}
-
-	/**
-	 * Refreshes information about a given file or directory ONLY if its status is already cached. The
-	 * only exception are non-existing files (new-in-repository) whose statuses are cached in all cases.
-	 *
-	 * @param file
-	 * @param repositoryStatus
-	 */
-	public void refreshCached(File file, File repositoryStatus)
-	{
-		refresh(file, repositoryStatus);
-	}
-
-	/**
-	 * Refreshes status of the specfied file or all files inside the 
-	 * specified directory. 
-	 *
-	 * @param file
-	 */
-	public void refreshCached(File root)
-	{
-		if (!root.isDirectory()) {
-			refresh(root, StatusCache.REPOSITORY_STATUS_UNKNOWN);
-			return;
-		}
-
-		File repository = git.getTopmostManagedParent(root);
-		if (repository == null)
-			return;
-		File roots[] = new File[1];
-		roots[0] = root;
-		File[] files = listFiles(roots, ~0);
-		if (files.length == 0)
-			return;
-		Map&lt;File, StatusInfo&gt; allFiles;
-		try {
-			allFiles = GitCommand.getAllStatus(repository, root);
-			for (int i = 0; i &lt; files.length; i++) {
-				File file = files[i];
-				StatusInfo fi = allFiles.get(file);
-				if (fi == null)
-					// We have a file in the cache which seems to have disappeared
-					refresh(file, StatusCache.REPOSITORY_STATUS_UNKNOWN);
-				else
-					refreshFileStatus(file, fi, null);
-			}
-		} catch (IOException ex) {
-			Git.LOG.log(Level.FINE, &quot;refreshCached() file: {0} {1} { 2} &quot;, new Object[]{repository.getAbsolutePath(), root.getAbsolutePath(), ex.toString()}); // NOI18N
-		}
-	}
-
-	/**
-	 * Refreshes status of all files inside given context. 
-	 *
-	 * @param ctx context to refresh
-	 */
-	public void refreshCached(VCSContext ctx)
-	{
-		for (File root : ctx.getRootFiles()) {
-			refreshCached(root);
-		}
-	}
-
-	public void addToCache(Set&lt;File&gt; files)
-	{
-		StatusInfo fi = new StatusInfo(StatusInfo.STATUS_NOTVERSIONED_NEWLOCALLY, null, false);
-		HashMap&lt;File, Map&lt;File, StatusInfo&gt;&gt; dirMap = new HashMap&lt;File, Map&lt;File, StatusInfo&gt;&gt;(files.size());
-
-		for (File file : files) {
-			File parent = file.getParentFile();
-			file = FileUtil.normalizeFile(file);
-			parent = FileUtil.normalizeFile(parent);
-			Map&lt;File, StatusInfo&gt; currentDirMap = dirMap.get(parent);
-			if (currentDirMap == null) {
-				// 20 is a guess at number of files in a directory
-				currentDirMap = new HashMap&lt;File, StatusInfo&gt;(20);
-				dirMap.put(parent, currentDirMap);
-			}
-			currentDirMap.put(file, fi);
-		}
-		for (File dir : dirMap.keySet()) {
-			dir = FileUtil.normalizeFile(dir);
-			Map&lt;File, StatusInfo&gt; currentDirMap = dirMap.get(dir);
-			turbo.writeEntry(dir, FILE_STATUS_MAP, currentDirMap);
-		}
-	}
-	// --- Package private contract ------------------------------------------
-	Map&lt;File, StatusInfo&gt; getAllModifiedFiles()
-	{
-		return cacheProvider.getAllModifiedValues();
-	}
-
-	/**
-	 * Refreshes given directory and all subdirectories.
-	 *
-	 * @param dir directory to refresh
-	 */
-	void directoryContentChanged(File dir)
-	{
-		Map originalFiles = (Map) turbo.readEntry(dir, FILE_STATUS_MAP);
-		if (originalFiles != null)
-			for (Iterator i = originalFiles.keySet().iterator(); i.hasNext();) {
-				File file = (File) i.next();
-				refresh(file, StatusCache.REPOSITORY_STATUS_UNKNOWN);
-			}
-	}
-
-	// --- Private methods ---------------------------------------------------
-	private boolean isNotManagedByDefault(File dir)
-	{
-		return !dir.exists();
-	}
-
-	/**
-	 * Scans all files in the given folder, computes and stores their CVS status.
-	 *
-	 * @param dir directory to scan
-	 * @return Map map to be included in the status cache (File =&gt; StatusInfo)
-	 */
-	private Map&lt;File, StatusInfo&gt; scanFolder(File dir, Map&lt;File, StatusInfo&gt; interestingFiles)
-	{
-		File[] files = dir.listFiles();
-		if (files == null)
-			if (interestingFiles == null)
-				files = new File[0];
-			else
-				files = interestingFiles.keySet().toArray(new File[interestingFiles.keySet().size()]);
-		Map&lt;File, StatusInfo&gt; folderFiles = new HashMap&lt;File, StatusInfo&gt;(files.length);
-
-		Git.LOG.log(Level.FINE, &quot;scanFolder(): {0}&quot;, dir); // NOI18N
-		if (git.isAdministrative(dir)) {
-			folderFiles.put(dir, FILE_STATUS_EXCLUDED_DIRECTORY); // Excluded dir
-			return folderFiles;
-		}
-
-		File rootManagedFolder = git.getTopmostManagedParent(dir);
-		if (rootManagedFolder == null) {
-			// Only interested in looking for Git managed dirs
-			for (File file : files) {
-				if (file.isDirectory() &amp;&amp; git.getTopmostManagedParent(file) != null)
-					if (excludeFile(file)) {
-						Git.LOG.log(Level.FINE, &quot;scanFolder NotMng Ignored Dir {0}: exclude SubDir: {1}&quot;, // NOI18N
-							new Object[]{dir.getAbsolutePath(), file.getName()});
-						folderFiles.put(file, FILE_STATUS_EXCLUDED_DIRECTORY); // Excluded dir
-					} else {
-						Git.LOG.log(Level.FINE, &quot;scanFolder NotMng Dir {0}: up to date Dir: {1}&quot;, // NOI18N
-							new Object[]{dir.getAbsolutePath(), file.getName()});
-						folderFiles.put(file, FILE_STATUS_UPTODATE_DIRECTORY);
-					}
-			// Do NOT put any unmanaged dir's (FILE_STATUS_NOTMANAGED_DIRECTORY) or 
-			// files (FILE_STATUS_NOTMANAGED) into the folderFiles
-			}
-			return folderFiles;
-		}
-
-		boolean bInIgnoredDir = GitIgnore.isIgnored(dir);
-		if (bInIgnoredDir) {
-			for (File file : files) {
-				if (GitUtils.isPartOfGitMetadata(file))
-					continue;
-
-				if (file.isDirectory()) {
-					folderFiles.put(file, FILE_STATUS_EXCLUDED_DIRECTORY); // Excluded dir
-					Git.LOG.log(Level.FINE, &quot;scanFolder Mng Ignored Dir {0}: exclude SubDir: {1}&quot;, // NOI18N
-						new Object[]{dir.getAbsolutePath(), file.getName()});
-				} else {
-					Git.LOG.log(Level.FINE, &quot;scanFolder Mng Ignored Dir {0}: exclude File: {1}&quot;, // NOI18N
-						new Object[]{dir.getAbsolutePath(), file.getName()});
-					folderFiles.put(file, FILE_STATUS_EXCLUDED);
-				}
-			}
-			return folderFiles;
-		}
-
-		if (interestingFiles == null)
-			interestingFiles = GitCommand.getInterestingStatus(rootManagedFolder, dir);
-
-		if (interestingFiles == null)
-			return folderFiles;
-
-		for (File file : files) {
-			if (GitUtils.isPartOfGitMetadata(file))
-				continue;
-
-			if (file.isDirectory())
-				if (excludeFile(file)) {
-					Git.LOG.log(Level.FINE, &quot;scanFolder Mng Dir {0}: exclude Dir: {1}&quot;, // NOI18N
-						new Object[]{dir.getAbsolutePath(), file.getName()});
-					folderFiles.put(file, FILE_STATUS_EXCLUDED_DIRECTORY); // Excluded dir
-				} else {
-					Git.LOG.log(Level.FINE, &quot;scanFolder Mng Dir {0}: up to date Dir: {1}&quot;, // NOI18N
-						new Object[]{dir.getAbsolutePath(), file.getName()});
-					folderFiles.put(file, FILE_STATUS_UPTODATE_DIRECTORY);
-				}
-			else {
-				StatusInfo fi = interestingFiles.get(file);
-				if (fi == null)
-					// We have removed -i from GitCommand.getInterestingFiles
-					// so we might have a file we should be ignoring
-					fi = createFileInformation(file, false);
-				if (fi != null &amp;&amp; fi.getStatus() != StatusInfo.STATUS_VERSIONED_UPTODATE)
-					folderFiles.put(file, fi);
-			}
-		}
-		return folderFiles;
-	}
-
-	private boolean exists(File file)
-	{
-		if (!file.exists())
-			return false;
-		return file.getAbsolutePath().equals(FileUtil.normalizeFile(file).getAbsolutePath());
-	}
-
-	public synchronized void addPropertyChangeListener(PropertyChangeListener listener)
-	{
-		listenerSupport.addPropertyChangeListener(listener);
-	}
-
-	public void removePropertyChangeListener(PropertyChangeListener listener)
-	{
-		listenerSupport.removePropertyChangeListener(listener);
-	}
-
-	private void fireFileStatusChanged(File file, StatusInfo oldInfo, StatusInfo newInfo)
-	{
-		listenerSupport.firePropertyChange(PROP_FILE_STATUS_CHANGED, null, new ChangedEvent(file, oldInfo, newInfo));
-	}
-
-	public void refreshDirtyFileSystems()
-	{
-		Set&lt;FileSystem&gt; filesystems = getFilesystemsToRefresh();
-		FileSystem[] fstoRefresh = new FileSystem[filesystems.size()];
-		synchronized (filesystems) {
-			fstoRefresh = filesystems.toArray(new FileSystem[filesystems.size()]);
-			filesystems.clear();
-		}
-		for (int i = 0; i &lt; fstoRefresh.length; i++) {
-			// don't call refresh() in synchronized (filesystems). It may lead to a deadlock.
-			fstoRefresh[i].refresh(true);
-		}
-	}
-
-	private Set&lt;FileSystem&gt; getFilesystemsToRefresh()
-	{
-		if (filesystemsToRefresh == null)
-			filesystemsToRefresh = new HashSet&lt;FileSystem&gt;();
-		return filesystemsToRefresh;
-	}
-
-	private boolean excludeFile(File file)
-	{
-		return git.isAdministrative(file) || GitIgnore.isIgnored(file);
-	}
-
-	private static final class NotManagedMap extends AbstractMap&lt;File, StatusInfo&gt; {
-
-		public Set&lt;Entry&lt;File, StatusInfo&gt;&gt; entrySet()
-		{
-			return Collections.emptySet();
-		}
-
-	}
-
-	public static class ChangedEvent {
-
-		private File file;
-		private StatusInfo oldInfo;
-		private StatusInfo newInfo;
-
-		public ChangedEvent(File file, StatusInfo oldInfo, StatusInfo newInfo)
-		{
-			this.file = file;
-			this.oldInfo = oldInfo;
-			this.newInfo = newInfo;
-		}
-
-		public File getFile()
-		{
-			return file;
-		}
-
-		public StatusInfo getOldInfo()
-		{
-			return oldInfo;
-		}
-
-		public StatusInfo getNewInfo()
-		{
-			return newInfo;
-		}
-
-	}
+    /**
+     * Indicates that status of a file changed and listeners SHOULD check new status
+     * values if they are interested in this file.
+     * The New value is a ChangedEvent object (old StatusInfo object may be null)
+     */
+    public static final String PROP_FILE_STATUS_CHANGED = &quot;status.changed&quot;; // NOI18N
+    /**
+     * A special map saying that no file inside the folder is managed.
+     */
+    private static final Map&lt;File, StatusInfo&gt; NOT_MANAGED_MAP = new NotManagedMap();
+    public static final File REPOSITORY_STATUS_UNKNOWN = null;  // Constant File objects that can be safely reused
+    // Files that have a revision number cannot share StatusInfo objects
+    private static final StatusInfo FILE_STATUS_EXCLUDED = new StatusInfo(StatusInfo.STATUS_NOTVERSIONED_EXCLUDED, false);
+    private static final StatusInfo FILE_STATUS_EXCLUDED_DIRECTORY = new StatusInfo(StatusInfo.STATUS_NOTVERSIONED_EXCLUDED, true);
+    private static final StatusInfo FILE_STATUS_UPTODATE_DIRECTORY = new StatusInfo(StatusInfo.STATUS_VERSIONED_UPTODATE, true);
+    private static final StatusInfo FILE_STATUS_NOTMANAGED = new StatusInfo(StatusInfo.STATUS_NOTVERSIONED_NOTMANAGED, false);
+    private static final StatusInfo FILE_STATUS_NOTMANAGED_DIRECTORY = new StatusInfo(StatusInfo.STATUS_NOTVERSIONED_NOTMANAGED, true);
+    private static final StatusInfo FILE_STATUS_UNKNOWN = new StatusInfo(StatusInfo.STATUS_UNKNOWN, false);
+    private static final StatusInfo FILE_STATUS_NEWLOCALLY = new StatusInfo(StatusInfo.STATUS_NOTVERSIONED_NEWLOCALLY, false);
+    private static final StatusInfo FILE_STATUS_CONFLICT = new StatusInfo(StatusInfo.STATUS_VERSIONED_CONFLICT, false);
+    private static final StatusInfo FILE_STATUS_REMOVEDLOCALLY = new StatusInfo(StatusInfo.STATUS_VERSIONED_REMOVEDLOCALLY, false);
+    private PropertyChangeSupport listenerSupport = new PropertyChangeSupport(this);
+    /**
+     * Caches status of files in memory and on disk
+     */
+    private final Turbo turbo;
+    private final String FILE_STATUS_MAP = DiskMapTurboProvider.ATTR_STATUS_MAP;
+    private DiskMapTurboProvider cacheProvider;
+    private Git git;
+    private Set&lt;FileSystem&gt; filesystemsToRefresh;
+
+    StatusCache(Git git)
+    {
+        this.git = git;
+        cacheProvider = new DiskMapTurboProvider();
+        turbo = Turbo.createCustom(new CustomProviders() {
+
+            private final Set providers = Collections.singleton(cacheProvider);
+
+            public Iterator providers()
+            {
+                return providers.iterator();
+            }
+
+        }, 200, 5000);
+    }
+
+    // --- Public interface -------------------------------------------------
+    /**
+     * Lists &lt;b&gt;modified files&lt;/b&gt; and all folders that are known to be inside
+     * this folder. There are locally modified files present
+     * plus any files that exist in the folder in the remote repository.
+     *
+     * @param dir folder to list
+     * @return
+     */
+    public File[] listFiles(File dir)
+    {
+        Set&lt;File&gt; files = getScannedFiles(dir, null).keySet();
+        return files.toArray(new File[files.size()]);
+    }
+
+    /**
+     * Lists &lt;b&gt;interesting files&lt;/b&gt; that are known to be inside given folders.
+     * These are locally and remotely modified and ignored files.
+     *
+     * &lt;p&gt;This method returns both folders and files.
+     *
+     * @param context context to examine
+     * @param includeStatus limit returned files to those having one of supplied statuses
+     * @return File [] array of interesting files
+     */
+    public File[] listFiles(VCSContext context, int includeStatus)
+    {
+        Set&lt;File&gt; set = new HashSet&lt;File&gt;();
+        Map allFiles = cacheProvider.getAllModifiedValues();
+        if (allFiles == null) {
+            Git.LOG.log(Level.FINE, &quot;StatusCache: listFiles(): allFiles == null&quot;); // NOI18N
+            return new File[0];
+        }
+
+        for (Iterator i = allFiles.keySet().iterator(); i.hasNext();) {
+            File file = (File) i.next();
+            StatusInfo info = (StatusInfo) allFiles.get(file);
+            if ((info.getStatus() &amp; includeStatus) == 0)
+                continue;
+            Set&lt;File&gt; roots = context.getRootFiles();
+            for (File root : roots) {
+                if (VersioningSupport.isFlat(root)) {
+                    if (file.equals(root) || file.getParentFile().equals(root)) {
+                        set.add(file);
+                        break;
+                    }
+                } else if (Utils.isAncestorOrEqual(root, file)) {
+                    set.add(file);
+                    break;
+                }
+            }
+        }
+        if (context.getExclusions().size() &gt; 0)
+            for (Iterator i = context.getExclusions().iterator(); i.hasNext();) {
+                File excluded = (File) i.next();
+                for (Iterator j = set.iterator(); j.hasNext();) {
+                    File file = (File) j.next();
+                    if (Utils.isAncestorOrEqual(excluded, file))
+                        j.remove();
+                }
+            }
+        return set.toArray(new File[set.size()]);
+    }
+
+    /**
+     * Lists &lt;b&gt;interesting files&lt;/b&gt; that are known to be inside given folders.
+     * These are locally and remotely modified and ignored files.
+     *
+     * &lt;p&gt;Comparing to CVS this method returns both folders and files.
+     *
+     * @param roots context to examine
+     * @param includeStatus limit returned files to those having one of supplied statuses
+     * @return File [] array of interesting files
+     */
+    public File[] listFiles(File[] roots, int includeStatus)
+    {
+        Set&lt;File&gt; set = new HashSet&lt;File&gt;();
+        Map&lt;File, StatusInfo&gt; allFiles = cacheProvider.getAllModifiedValues();
+
+        for (File file : allFiles.keySet()) {
+            StatusInfo info = allFiles.get(file);
+            if ((info.getStatus() &amp; includeStatus) == 0)
+                continue;
+            for (int j = 0; j &lt; roots.length; j++) {
+                File root = roots[j];
+                if (VersioningSupport.isFlat(root)) {
+                    if (file.getParentFile().equals(root)) {
+                        set.add(file);
+                        break;
+                    }
+                } else if (Utils.isAncestorOrEqual(root, file)) {
+                    set.add(file);
+                    break;
+                }
+            }
+        }
+        return set.toArray(new File[set.size()]);
+    }
+
+    /**
+     * Check if this context has at least one file with the passed in status
+     *
+     * @param context context to examine
+     * @param includeStatus file status to check for
+     * @return boolean true if this context contains at least one file with the includeStatus, false otherwise
+     */
+    public boolean containsFileOfStatus(VCSContext context, int includeStatus)
+    {
+        Map&lt;File, StatusInfo&gt; allFiles = cacheProvider.getAllModifiedValues();
+        if (allFiles == null) {
+            Git.LOG.log(Level.FINE, &quot;containsFileOfStatus(): allFiles == null&quot;); // NOI18N
+            return false;
+        }
+
+        Set&lt;File&gt; roots = context.getRootFiles();
+        Set&lt;File&gt; exclusions = context.getExclusions();
+        Set&lt;File&gt; setAllFiles = allFiles.keySet();
+        boolean bExclusions = exclusions != null &amp;&amp; exclusions.size() &gt; 0;
+        boolean bContainsFile = false;
+
+        for (File file : setAllFiles) {
+            StatusInfo info = allFiles.get(file);
+            if ((info.getStatus() &amp; includeStatus) == 0)
+                continue;
+            for (File root : roots) {
+                if (VersioningSupport.isFlat(root)) {
+                    if (file.equals(root) || file.getParentFile().equals(root)) {
+                        bContainsFile = true;
+                        break;
+                    }
+                } else if (Utils.isAncestorOrEqual(root, file)) {
+                    bContainsFile = true;
+                    break;
+                }
+            }
+            // Check it is not an excluded file
+            if (bContainsFile &amp;&amp; bExclusions) {
+                for (File excluded : exclusions) {
+                    if (!Utils.isAncestorOrEqual(excluded, file))
+                        return true;
+                }
+            } else if (bContainsFile)
+                return true;
+        }
+        return false;
+    }
+
+    /**
+     * Determines the versioning status of a file. This method accesses disk and may block for a long period of time.
+     *
+     * @param file file to get status for
+     * @return StatusInfo structure containing the file status
+     * @see StatusInfo
+     */
+    public StatusInfo getStatus(File file)
+    {
+        if (file.isDirectory() &amp;&amp; excludeFile(file))
+            return StatusCache.FILE_STATUS_EXCLUDED_DIRECTORY;
+        File dir = file.getParentFile();
+        if (dir == null)
+            return StatusCache.FILE_STATUS_NOTMANAGED;
+        Map files = getScannedFiles(dir, null);
+        if (files == StatusCache.NOT_MANAGED_MAP)
+            return StatusCache.FILE_STATUS_NOTMANAGED;
+        StatusInfo fi = (StatusInfo) files.get(file);
+        if (fi != null)
+            return fi;
+        if (!exists(file))
+            return StatusCache.FILE_STATUS_UNKNOWN;
+        if (file.isDirectory())
+            return refresh(file, REPOSITORY_STATUS_UNKNOWN);
+        else
+            return new StatusInfo(StatusInfo.STATUS_VERSIONED_UPTODATE, false);
+    }
+
+    /**
+     * Looks up cached file status.
+     *
+     * @param file file to check
+     * @return give file's status or null if the file's status is not in cache
+     */
+    @SuppressWarnings(&quot;unchecked&quot;) // Need to change turbo module to remove warning at source
+    StatusInfo getCachedStatus( File file, boolean bCheckSharability)
+    {
+        File parent = file.getParentFile();
+        if (parent == null)
+            return StatusCache.FILE_STATUS_NOTMANAGED_DIRECTORY;
+
+        Map&lt;File, StatusInfo&gt; files = (Map&lt;File, StatusInfo&gt;) turbo.readEntry(parent, FILE_STATUS_MAP);
+        StatusInfo fi = files != null ? files.get(file) : null;
+        if (fi != null)
+            return fi;
+
+        if (file.isDirectory())
+            if (excludeFile(file))
+                return StatusCache.FILE_STATUS_EXCLUDED_DIRECTORY;
+            else
+                return StatusCache.FILE_STATUS_UPTODATE_DIRECTORY;
+
+        return fi;
+    }
+
+    private StatusInfo refresh(File file, File repoStat, boolean forceChangeEvent)
+    {
+        Git.LOG.log(Level.FINE, &quot;refresh(): {0}&quot;, file); // NOI18N
+        File dir = file.getParentFile();
+        if (dir == null)
+            return StatusCache.FILE_STATUS_NOTMANAGED;
+
+        Map&lt;File, StatusInfo&gt; files = getScannedFiles(dir, null); // Has side effect of updating the cache
+        if (files == StatusCache.NOT_MANAGED_MAP &amp;&amp; repoStat == StatusCache.REPOSITORY_STATUS_UNKNOWN)
+            return StatusCache.FILE_STATUS_NOTMANAGED;
+        StatusInfo current = files.get(file);
+
+        StatusInfo fi = createFileInformation(file, true);
+
+        if (StatusInfo.equivalent(fi, current)) {
+            if (forceChangeEvent)
+                fireFileStatusChanged(file, current, fi);
+            return fi;
+        }
+
+        // do not include uptodate files into cache, missing directories must be included
+        if (current == null &amp;&amp; !fi.isDirectory() &amp;&amp; fi.getStatus() == StatusInfo.STATUS_VERSIONED_UPTODATE) {
+            if (forceChangeEvent)
+                fireFileStatusChanged(file, current, fi);
+            return fi;
+        }
+
+        file = FileUtil.normalizeFile(file);
+        dir = FileUtil.normalizeFile(dir);
+        Map&lt;File, StatusInfo&gt; newFiles = new HashMap&lt;File, StatusInfo&gt;(files);
+        if (fi.getStatus() == StatusInfo.STATUS_UNKNOWN) {
+            newFiles.remove(file);
+            turbo.writeEntry(file, FILE_STATUS_MAP, null);  // remove mapping in case of directories
+        } else if (fi.getStatus() == StatusInfo.STATUS_VERSIONED_UPTODATE &amp;&amp; file.isFile())
+            newFiles.remove(file);
+        else
+            newFiles.put(file, fi);
+        assert newFiles.containsKey(dir) == false;
+        turbo.writeEntry(dir, FILE_STATUS_MAP, newFiles.size() == 0 ? null : newFiles);
+
+        if (file.isDirectory() &amp;&amp; needRecursiveRefresh(fi, current)) {
+            File[] content = listFiles(file); // Has side effect of updating the cache
+            for (int i = 0; i &lt; content.length; i++) {
+                refresh(content[i], StatusCache.REPOSITORY_STATUS_UNKNOWN);
+            }
+        }
+        fireFileStatusChanged(file, current, fi);
+        return fi;
+    }
+
+    private StatusInfo createFileInformation(File file, Boolean callStatus)
+    {
+        Git.LOG.log(Level.FINE, &quot;createFileInformation(): {0} {1}&quot;, new Object[]{file, callStatus}); // NOI18N
+        if (file == null)
+            return FILE_STATUS_UNKNOWN;
+        if (git.isAdministrative(file))
+            return FILE_STATUS_EXCLUDED_DIRECTORY; // Excluded
+
+        File rootManagedFolder = git.getTopmostManagedParent(file);
+        if (rootManagedFolder == null)
+            return FILE_STATUS_UNKNOWN; // Avoiding returning NOT_MANAGED dir or file
+
+        if (file.isDirectory())
+            if (GitIgnore.isIgnored(file))
+                return FILE_STATUS_EXCLUDED_DIRECTORY;
+            else
+                return FILE_STATUS_UPTODATE_DIRECTORY;
+
+        if (callStatus == false) {
+            if (GitIgnore.isIgnored(file))
+                return FILE_STATUS_EXCLUDED;
+            return null;
+        }
+
+        return GitCommand.getSingleStatus(rootManagedFolder, file);
+    }
+
+    /**
+     * Refreshes the status of the file given the repository status. Repository status is filled
+     * in when this method is called while processing server output.
+     *
+     * &lt;p&gt;Note: it's not necessary if you use Subversion.getClient(), it
+     * updates the cache automatically using onNotify(). It's not
+     * fully reliable for removed files.
+     *
+     * @param file
+     * @param repositoryStatus
+     */
+    public StatusInfo refresh(File file, File repositoryStatus)
+    {
+        return refresh(file, repositoryStatus, false);
+    }
+
+    @SuppressWarnings(&quot;unchecked&quot;) // Need to change turbo module to remove warning at source
+    public Map&lt;File, StatusInfo&gt; getScannedFiles(File dir, Map&lt;File, StatusInfo&gt; interestingFiles)
+    {
+        Map&lt;File, StatusInfo&gt; files;
+
+        files = (Map&lt;File, StatusInfo&gt;) turbo.readEntry(dir, FILE_STATUS_MAP);
+        if (files != null)
+            return files;
+
+        if (!dir.exists() &amp;&amp; interestingFiles == null)
+            return StatusCache.NOT_MANAGED_MAP;
+
+        dir = FileUtil.normalizeFile(dir);
+        files = scanFolder(dir, interestingFiles);
+        assert files.containsKey(dir) == false;
+        turbo.writeEntry(dir, FILE_STATUS_MAP, files);
+        if (interestingFiles == null)
+            for (Iterator i = files.keySet().iterator(); i.hasNext();) {
+                File file = (File) i.next();
+                StatusInfo info = files.get(file);
+                if ((info.getStatus() &amp; (StatusInfo.STATUS_LOCAL_CHANGE | StatusInfo.STATUS_NOTVERSIONED_EXCLUDED)) != 0)
+                    fireFileStatusChanged(file, null, info);
+            }
+        return files;
+    }
+
+    public void refreshFileStatus(File file, StatusInfo fi, Map&lt;File, StatusInfo&gt; interestingFiles)
+    {
+        refreshFileStatus(file, fi, interestingFiles, false);
+    }
+
+    public void refreshFileStatus(File file, StatusInfo fi, Map&lt;File, StatusInfo&gt; interestingFiles, boolean alwaysFireEvent)
+    {
+        if (file == null || fi == null)
+            return;
+        File dir = file.getParentFile();
+        if (dir == null)
+            return;
+
+        Map&lt;File, StatusInfo&gt; files = getScannedFiles(dir, interestingFiles);
+
+        if (files == null || files == StatusCache.NOT_MANAGED_MAP)
+            return;
+        StatusInfo current = files.get(file);
+        if (StatusInfo.equivalent(fi, current))
+            if (StatusInfo.equivalent(FILE_STATUS_NEWLOCALLY, fi))
+                if (GitIgnore.isIgnored(file)) {
+                    Git.LOG.log(Level.FINE, &quot;refreshFileStatus() file: {0} was LocallyNew but is NotSharable&quot;, file.getAbsolutePath()); // NOI18N
+                    fi = FILE_STATUS_EXCLUDED;
+                } else
+                    return;
+            else if (!StatusInfo.equivalent(FILE_STATUS_REMOVEDLOCALLY, fi))
+                return;
+        if (StatusInfo.equivalent(FILE_STATUS_NEWLOCALLY, fi))
+            if (StatusInfo.equivalent(FILE_STATUS_EXCLUDED, current)) {
+                Git.LOG.log(Level.FINE, &quot;refreshFileStatus() file: {0} was LocallyNew but is Excluded&quot;, file.getAbsolutePath()); // NOI18N
+                return;
+            } else if (current == null)
+                if (GitIgnore.isIgnored(file)) {
+                    Git.LOG.log(Level.FINE, &quot;refreshFileStatus() file: {0} was LocallyNew but current is null and is not NotSharable&quot;, file.getAbsolutePath()); // NOI18N
+                    fi = FILE_STATUS_EXCLUDED;
+                }
+        file = FileUtil.normalizeFile(file);
+        dir = FileUtil.normalizeFile(dir);
+        Map&lt;File, StatusInfo&gt; newFiles = new HashMap&lt;File, StatusInfo&gt;(files);
+        if (fi.getStatus() == StatusInfo.STATUS_UNKNOWN) {
+            newFiles.remove(file);
+            turbo.writeEntry(file, FILE_STATUS_MAP, null);  // remove mapping in case of directories
+        } else if (fi.getStatus() == StatusInfo.STATUS_VERSIONED_UPTODATE &amp;&amp; file.isFile())
+            newFiles.remove(file);
+        else
+            newFiles.put(file, fi);
+        assert files.containsKey(dir) == false;
+        turbo.writeEntry(dir, FILE_STATUS_MAP, newFiles);
+
+        if (interestingFiles == null)
+            fireFileStatusChanged(file, current, fi);
+        else if (alwaysFireEvent)
+            fireFileStatusChanged(file, null, fi);
+
+        return;
+    }
+
+    private boolean needRecursiveRefresh(StatusInfo fi, StatusInfo current)
+    {
+        if (fi.getStatus() == StatusInfo.STATUS_NOTVERSIONED_EXCLUDED ||
+            current != null &amp;&amp; current.getStatus() == StatusInfo.STATUS_NOTVERSIONED_EXCLUDED)
+            return true;
+        if (fi.getStatus() == StatusInfo.STATUS_NOTVERSIONED_NOTMANAGED ||
+            current != null &amp;&amp; current.getStatus() == StatusInfo.STATUS_NOTVERSIONED_NOTMANAGED)
+            return true;
+        return false;
+    }
+
+    /**
+     * Refreshes information about a given file or directory ONLY if its status is already cached. The
+     * only exception are non-existing files (new-in-repository) whose statuses are cached in all cases.
+     *
+     * @param file
+     * @param repositoryStatus
+     */
+    public void refreshCached(File file, File repositoryStatus)
+    {
+        refresh(file, repositoryStatus);
+    }
+
+    /**
+     * Refreshes status of the specfied file or all files inside the
+     * specified directory.
+     *
+     * @param file
+     */
+    public void refreshCached(File root)
+    {
+        if (!root.isDirectory()) {
+            refresh(root, StatusCache.REPOSITORY_STATUS_UNKNOWN);
+            return;
+        }
+
+        File repository = git.getTopmostManagedParent(root);
+        if (repository == null)
+            return;
+        File roots[] = new File[1];
+        roots[0] = root;
+        File[] files = listFiles(roots, ~0);
+        if (files.length == 0)
+            return;
+        Map&lt;File, StatusInfo&gt; allFiles;
+        try {
+            allFiles = GitCommand.getAllStatus(repository, root);
+            for (int i = 0; i &lt; files.length; i++) {
+                File file = files[i];
+                StatusInfo fi = allFiles.get(file);
+                if (fi == null)
+                    // We have a file in the cache which seems to have disappeared
+                    refresh(file, StatusCache.REPOSITORY_STATUS_UNKNOWN);
+                else
+                    refreshFileStatus(file, fi, null);
+            }
+        } catch (IOException ex) {
+            Git.LOG.log(Level.FINE, &quot;refreshCached() file: {0} {1} { 2} &quot;, new Object[]{repository.getAbsolutePath(), root.getAbsolutePath(), ex.toString()}); // NOI18N
+        }
+    }
+
+    /**
+     * Refreshes status of all files inside given context.
+     *
+     * @param ctx context to refresh
+     */
+    public void refreshCached(VCSContext ctx)
+    {
+        for (File root : ctx.getRootFiles()) {
+            refreshCached(root);
+        }
+    }
+
+    public void addToCache(Set&lt;File&gt; files)
+    {
+        StatusInfo fi = new StatusInfo(StatusInfo.STATUS_NOTVERSIONED_NEWLOCALLY, null, false);
+        HashMap&lt;File, Map&lt;File, StatusInfo&gt;&gt; dirMap = new HashMap&lt;File, Map&lt;File, StatusInfo&gt;&gt;(files.size());
+
+        for (File file : files) {
+            File parent = file.getParentFile();
+            file = FileUtil.normalizeFile(file);
+            parent = FileUtil.normalizeFile(parent);
+            Map&lt;File, StatusInfo&gt; currentDirMap = dirMap.get(parent);
+            if (currentDirMap == null) {
+                // 20 is a guess at number of files in a directory
+                currentDirMap = new HashMap&lt;File, StatusInfo&gt;(20);
+                dirMap.put(parent, currentDirMap);
+            }
+            currentDirMap.put(file, fi);
+        }
+        for (File dir : dirMap.keySet()) {
+            dir = FileUtil.normalizeFile(dir);
+            Map&lt;File, StatusInfo&gt; currentDirMap = dirMap.get(dir);
+            turbo.writeEntry(dir, FILE_STATUS_MAP, currentDirMap);
+        }
+    }
+    // --- Package private contract ------------------------------------------
+    Map&lt;File, StatusInfo&gt; getAllModifiedFiles()
+    {
+        return cacheProvider.getAllModifiedValues();
+    }
+
+    /**
+     * Refreshes given directory and all subdirectories.
+     *
+     * @param dir directory to refresh
+     */
+    void directoryContentChanged(File dir)
+    {
+        Map originalFiles = (Map) turbo.readEntry(dir, FILE_STATUS_MAP);
+        if (originalFiles != null)
+            for (Iterator i = originalFiles.keySet().iterator(); i.hasNext();) {
+                File file = (File) i.next();
+                refresh(file, StatusCache.REPOSITORY_STATUS_UNKNOWN);
+            }
+    }
+
+    // --- Private methods ---------------------------------------------------
+    private boolean isNotManagedByDefault(File dir)
+    {
+        return !dir.exists();
+    }
+
+    /**
+     * Scans all files in the given folder, computes and stores their CVS status.
+     *
+     * @param dir directory to scan
+     * @return Map map to be included in the status cache (File =&gt; StatusInfo)
+     */
+    private Map&lt;File, StatusInfo&gt; scanFolder(File dir, Map&lt;File, StatusInfo&gt; interestingFiles)
+    {
+        File[] files = dir.listFiles();
+        if (files == null)
+            if (interestingFiles == null)
+                files = new File[0];
+            else
+                files = interestingFiles.keySet().toArray(new File[interestingFiles.keySet().size()]);
+        Map&lt;File, StatusInfo&gt; folderFiles = new HashMap&lt;File, StatusInfo&gt;(files.length);
+
+        Git.LOG.log(Level.FINE, &quot;scanFolder(): {0}&quot;, dir); // NOI18N
+        if (git.isAdministrative(dir)) {
+            folderFiles.put(dir, FILE_STATUS_EXCLUDED_DIRECTORY); // Excluded dir
+            return folderFiles;
+        }
+
+        File rootManagedFolder = git.getTopmostManagedParent(dir);
+        if (rootManagedFolder == null) {
+            // Only interested in looking for Git managed dirs
+            for (File file : files) {
+                if (file.isDirectory() &amp;&amp; git.getTopmostManagedParent(file) != null)
+                    if (excludeFile(file)) {
+                        Git.LOG.log(Level.FINE, &quot;scanFolder NotMng Ignored Dir {0}: exclude SubDir: {1}&quot;, // NOI18N
+                            new Object[]{dir.getAbsolutePath(), file.getName()});
+                        folderFiles.put(file, FILE_STATUS_EXCLUDED_DIRECTORY); // Excluded dir
+                    } else {
+                        Git.LOG.log(Level.FINE, &quot;scanFolder NotMng Dir {0}: up to date Dir: {1}&quot;, // NOI18N
+                            new Object[]{dir.getAbsolutePath(), file.getName()});
+                        folderFiles.put(file, FILE_STATUS_UPTODATE_DIRECTORY);
+                    }
+            // Do NOT put any unmanaged dir's (FILE_STATUS_NOTMANAGED_DIRECTORY) or
+            // files (FILE_STATUS_NOTMANAGED) into the folderFiles
+            }
+            return folderFiles;
+        }
+
+        boolean bInIgnoredDir = GitIgnore.isIgnored(dir);
+        if (bInIgnoredDir) {
+            for (File file : files) {
+                if (GitUtils.isPartOfGitMetadata(file))
+                    continue;
+
+                if (file.isDirectory()) {
+                    folderFiles.put(file, FILE_STATUS_EXCLUDED_DIRECTORY); // Excluded dir
+                    Git.LOG.log(Level.FINE, &quot;scanFolder Mng Ignored Dir {0}: exclude SubDir: {1}&quot;, // NOI18N
+                        new Object[]{dir.getAbsolutePath(), file.getName()});
+                } else {
+                    Git.LOG.log(Level.FINE, &quot;scanFolder Mng Ignored Dir {0}: exclude File: {1}&quot;, // NOI18N
+                        new Object[]{dir.getAbsolutePath(), file.getName()});
+                    folderFiles.put(file, FILE_STATUS_EXCLUDED);
+                }
+            }
+            return folderFiles;
+        }
+
+        if (interestingFiles == null)
+            interestingFiles = GitCommand.getInterestingStatus(rootManagedFolder, dir);
+
+        if (interestingFiles == null)
+            return folderFiles;
+
+        for (File file : files) {
+            if (GitUtils.isPartOfGitMetadata(file))
+                continue;
+
+            if (file.isDirectory())
+                if (excludeFile(file)) {
+                    Git.LOG.log(Level.FINE, &quot;scanFolder Mng Dir {0}: exclude Dir: {1}&quot;, // NOI18N
+                        new Object[]{dir.getAbsolutePath(), file.getName()});
+                    folderFiles.put(file, FILE_STATUS_EXCLUDED_DIRECTORY); // Excluded dir
+                } else {
+                    Git.LOG.log(Level.FINE, &quot;scanFolder Mng Dir {0}: up to date Dir: {1}&quot;, // NOI18N
+                        new Object[]{dir.getAbsolutePath(), file.getName()});
+                    folderFiles.put(file, FILE_STATUS_UPTODATE_DIRECTORY);
+                }
+            else {
+                StatusInfo fi = interestingFiles.get(file);
+                if (fi == null)
+                    // We have removed -i from GitCommand.getInterestingFiles
+                    // so we might have a file we should be ignoring
+                    fi = createFileInformation(file, false);
+                if (fi != null &amp;&amp; fi.getStatus() != StatusInfo.STATUS_VERSIONED_UPTODATE)
+                    folderFiles.put(file, fi);
+            }
+        }
+        return folderFiles;
+    }
+
+    private boolean exists(File file)
+    {
+        if (!file.exists())
+            return false;
+        return file.getAbsolutePath().equals(FileUtil.normalizeFile(file).getAbsolutePath());
+    }
+
+    public synchronized void addPropertyChangeListener(PropertyChangeListener listener)
+    {
+        listenerSupport.addPropertyChangeListener(listener);
+    }
+
+    public void removePropertyChangeListener(PropertyChangeListener listener)
+    {
+        listenerSupport.removePropertyChangeListener(listener);
+    }
+
+    private void fireFileStatusChanged(File file, StatusInfo oldInfo, StatusInfo newInfo)
+    {
+        listenerSupport.firePropertyChange(PROP_FILE_STATUS_CHANGED, null, new ChangedEvent(file, oldInfo, newInfo));
+    }
+
+    public void refreshDirtyFileSystems()
+    {
+        Set&lt;FileSystem&gt; filesystems = getFilesystemsToRefresh();
+        FileSystem[] fstoRefresh = new FileSystem[filesystems.size()];
+        synchronized (filesystems) {
+            fstoRefresh = filesystems.toArray(new FileSystem[filesystems.size()]);
+            filesystems.clear();
+        }
+        for (int i = 0; i &lt; fstoRefresh.length; i++) {
+            // don't call refresh() in synchronized (filesystems). It may lead to a deadlock.
+            fstoRefresh[i].refresh(true);
+        }
+    }
+
+    private Set&lt;FileSystem&gt; getFilesystemsToRefresh()
+    {
+        if (filesystemsToRefresh == null)
+            filesystemsToRefresh = new HashSet&lt;FileSystem&gt;();
+        return filesystemsToRefresh;
+    }
+
+    private boolean excludeFile(File file)
+    {
+        return git.isAdministrative(file) || GitIgnore.isIgnored(file);
+    }
+
+    private static final class NotManagedMap extends AbstractMap&lt;File, StatusInfo&gt; {
+
+        public Set&lt;Entry&lt;File, StatusInfo&gt;&gt; entrySet()
+        {
+            return Collections.emptySet();
+        }
+
+    }
+
+    public static class ChangedEvent {
+
+        private File file;
+        private StatusInfo oldInfo;
+        private StatusInfo newInfo;
+
+        public ChangedEvent(File file, StatusInfo oldInfo, StatusInfo newInfo)
+        {
+            this.file = file;
+            this.oldInfo = oldInfo;
+            this.newInfo = newInfo;
+        }
+
+        public File getFile()
+        {
+            return file;
+        }
+
+        public StatusInfo getOldInfo()
+        {
+            return oldInfo;
+        }
+
+        public StatusInfo getNewInfo()
+        {
+            return newInfo;
+        }
+
+    }
 
 }</diff>
      <filename>src/org/nbgit/StatusCache.java</filename>
    </modified>
    <modified>
      <diff>@@ -53,323 +53,323 @@ import org.openide.util.NbBundle;
  */
 public class StatusInfo implements Serializable {
 
-	private static final long serialVersionUID = 1L;
-	/**
-	 * There is nothing known about the file, it may not even exist.
-	 */
-	public static final int STATUS_UNKNOWN = 0;
-	/**
-	 * The file is not managed by the module, i.e. the user does not wish it to be under control of this
-	 * versioning system module. All files except files under versioned roots have this status.
-	 */
-	public static final int STATUS_NOTVERSIONED_NOTMANAGED = 1;
-	/**
-	 * The file exists locally but is NOT under version control because it should not be (i.e. is has
-	 * the Ignore property set or resides under an excluded folder). The file itself IS under a versioned root.
-	 */
-	public static final int STATUS_NOTVERSIONED_EXCLUDED = 2;
-	/**
-	 * The file exists locally but is NOT under version control, mostly because it has not been added
-	 * to the repository yet.
-	 */
-	public static final int STATUS_NOTVERSIONED_NEWLOCALLY = 4;
-	/**
-	 * The file is under version control and is in sync with repository.
-	 */
-	public static final int STATUS_VERSIONED_UPTODATE = 8;
-	/**
-	 * The file is modified locally and was not yet modified in repository.
-	 */
-	public static final int STATUS_VERSIONED_MODIFIEDLOCALLY = 16;
-	/**
-	 * The file was not modified locally but an updated version exists in repository.
-	 */
-	public static final int STATUS_VERSIONED_MODIFIEDINREPOSITORY = 32;
-	/**
-	 * Merging during update resulted in merge conflict. Conflicts in the local copy must be resolved before
-	 * the file can be commited.  
-	 */
-	public static final int STATUS_VERSIONED_CONFLICT = 64;
-	/**
-	 * The file was modified both locally and remotely and these changes may or may not result in
-	 * merge conflict. 
-	 */
-	public static final int STATUS_VERSIONED_MERGE = 128;
-	/**
-	 * The file does NOT exist locally and exists in repository, it has beed removed locally, waits
-	 * for commit.
-	 */
-	public static final int STATUS_VERSIONED_REMOVEDLOCALLY = 256;
-	/**
-	 * The file does NOT exist locally but exists in repository and has not yet been downloaded. 
-	 */
-	public static final int STATUS_VERSIONED_NEWINREPOSITORY = 512;
-	/**
-	 * The file has been removed from repository. 
-	 */
-	public static final int STATUS_VERSIONED_REMOVEDINREPOSITORY = 1024;
-	/**
-	 * The file does NOT exist locally and exists in repository, it has beed removed locally.
-	 */
-	public static final int STATUS_VERSIONED_DELETEDLOCALLY = 2048;
-	/**
-	 * The file exists locally and has beed scheduled for addition to repository. This status represents
-	 * state after the 'add' command.
-	 */
-	public static final int STATUS_VERSIONED_ADDEDLOCALLY = 4096;
-	public static final int STATUS_VERSIONED_COPIEDLOCALLY = 8192;
-	public static final int STATUS_ALL = ~0;
-	/**
-	 * All statuses except &lt;tt&gt;STATUS_NOTVERSIONED_NOTMANAGED&lt;/tt&gt;
-	 *
-	 * &lt;p&gt;Note: it covers ignored files.
-	 */
-	public static final int STATUS_MANAGED = StatusInfo.STATUS_ALL &amp; ~StatusInfo.STATUS_NOTVERSIONED_NOTMANAGED;
-	public static final int STATUS_VERSIONED = StatusInfo.STATUS_VERSIONED_UPTODATE |
-		StatusInfo.STATUS_VERSIONED_MODIFIEDLOCALLY |
-		StatusInfo.STATUS_VERSIONED_MODIFIEDINREPOSITORY |
-		StatusInfo.STATUS_VERSIONED_CONFLICT |
-		StatusInfo.STATUS_VERSIONED_MERGE |
-		StatusInfo.STATUS_VERSIONED_REMOVEDLOCALLY |
-		StatusInfo.STATUS_VERSIONED_REMOVEDINREPOSITORY |
-		StatusInfo.STATUS_VERSIONED_DELETEDLOCALLY |
-		StatusInfo.STATUS_VERSIONED_ADDEDLOCALLY |
-		StatusInfo.STATUS_VERSIONED_COPIEDLOCALLY;
-	public static final int STATUS_IN_REPOSITORY = StatusInfo.STATUS_VERSIONED_UPTODATE |
-		StatusInfo.STATUS_VERSIONED_MODIFIEDLOCALLY |
-		StatusInfo.STATUS_VERSIONED_MODIFIEDINREPOSITORY |
-		StatusInfo.STATUS_VERSIONED_CONFLICT |
-		StatusInfo.STATUS_VERSIONED_MERGE |
-		StatusInfo.STATUS_VERSIONED_REMOVEDLOCALLY |
-		StatusInfo.STATUS_VERSIONED_NEWINREPOSITORY |
-		StatusInfo.STATUS_VERSIONED_REMOVEDINREPOSITORY |
-		StatusInfo.STATUS_VERSIONED_DELETEDLOCALLY;
-	public static final int STATUS_LOCAL_CHANGE =
-		StatusInfo.STATUS_NOTVERSIONED_NEWLOCALLY |
-		StatusInfo.STATUS_VERSIONED_ADDEDLOCALLY |
-		StatusInfo.STATUS_VERSIONED_COPIEDLOCALLY |
-		StatusInfo.STATUS_VERSIONED_CONFLICT |
-		StatusInfo.STATUS_VERSIONED_DELETEDLOCALLY |
-		StatusInfo.STATUS_VERSIONED_MERGE |
-		StatusInfo.STATUS_VERSIONED_REMOVEDLOCALLY |
-		StatusInfo.STATUS_VERSIONED_MODIFIEDLOCALLY;
-	/**
-	 * Modified, in conflict, scheduled for removal or addition;
-	 * or deleted but with existing entry record.
-	 */
-	public static final int STATUS_REVERTIBLE_CHANGE =
-		StatusInfo.STATUS_VERSIONED_ADDEDLOCALLY |
-		StatusInfo.STATUS_VERSIONED_COPIEDLOCALLY |
-		StatusInfo.STATUS_VERSIONED_CONFLICT |
-		StatusInfo.STATUS_VERSIONED_MERGE |
-		StatusInfo.STATUS_VERSIONED_REMOVEDLOCALLY |
-		StatusInfo.STATUS_VERSIONED_DELETEDLOCALLY |
-		StatusInfo.STATUS_VERSIONED_MODIFIEDLOCALLY;
-	public static final int STATUS_REMOTE_CHANGE =
-		StatusInfo.STATUS_VERSIONED_MERGE |
-		StatusInfo.STATUS_VERSIONED_MODIFIEDINREPOSITORY |
-		StatusInfo.STATUS_VERSIONED_NEWINREPOSITORY |
-		StatusInfo.STATUS_VERSIONED_REMOVEDINREPOSITORY;
-	/**
-	 * Status constant.
-	 */
-	private final int status;
-	/**
-	 * More detailed information about a file, you may disregard the field if not needed.
-	 */
-	private transient File entry;
-	/**
-	 * Directory indicator, mainly because of files that may have been deleted so file.isDirectory() won't work.
-	 */
-	private final boolean isDirectory;
+    private static final long serialVersionUID = 1L;
+    /**
+     * There is nothing known about the file, it may not even exist.
+     */
+    public static final int STATUS_UNKNOWN = 0;
+    /**
+     * The file is not managed by the module, i.e. the user does not wish it to be under control of this
+     * versioning system module. All files except files under versioned roots have this status.
+     */
+    public static final int STATUS_NOTVERSIONED_NOTMANAGED = 1;
+    /**
+     * The file exists locally but is NOT under version control because it should not be (i.e. is has
+     * the Ignore property set or resides under an excluded folder). The file itself IS under a versioned root.
+     */
+    public static final int STATUS_NOTVERSIONED_EXCLUDED = 2;
+    /**
+     * The file exists locally but is NOT under version control, mostly because it has not been added
+     * to the repository yet.
+     */
+    public static final int STATUS_NOTVERSIONED_NEWLOCALLY = 4;
+    /**
+     * The file is under version control and is in sync with repository.
+     */
+    public static final int STATUS_VERSIONED_UPTODATE = 8;
+    /**
+     * The file is modified locally and was not yet modified in repository.
+     */
+    public static final int STATUS_VERSIONED_MODIFIEDLOCALLY = 16;
+    /**
+     * The file was not modified locally but an updated version exists in repository.
+     */
+    public static final int STATUS_VERSIONED_MODIFIEDINREPOSITORY = 32;
+    /**
+     * Merging during update resulted in merge conflict. Conflicts in the local copy must be resolved before
+     * the file can be commited.
+     */
+    public static final int STATUS_VERSIONED_CONFLICT = 64;
+    /**
+     * The file was modified both locally and remotely and these changes may or may not result in
+     * merge conflict.
+     */
+    public static final int STATUS_VERSIONED_MERGE = 128;
+    /**
+     * The file does NOT exist locally and exists in repository, it has beed removed locally, waits
+     * for commit.
+     */
+    public static final int STATUS_VERSIONED_REMOVEDLOCALLY = 256;
+    /**
+     * The file does NOT exist locally but exists in repository and has not yet been downloaded.
+     */
+    public static final int STATUS_VERSIONED_NEWINREPOSITORY = 512;
+    /**
+     * The file has been removed from repository.
+     */
+    public static final int STATUS_VERSIONED_REMOVEDINREPOSITORY = 1024;
+    /**
+     * The file does NOT exist locally and exists in repository, it has beed removed locally.
+     */
+    public static final int STATUS_VERSIONED_DELETEDLOCALLY = 2048;
+    /**
+     * The file exists locally and has beed scheduled for addition to repository. This status represents
+     * state after the 'add' command.
+     */
+    public static final int STATUS_VERSIONED_ADDEDLOCALLY = 4096;
+    public static final int STATUS_VERSIONED_COPIEDLOCALLY = 8192;
+    public static final int STATUS_ALL = ~0;
+    /**
+     * All statuses except &lt;tt&gt;STATUS_NOTVERSIONED_NOTMANAGED&lt;/tt&gt;
+     *
+     * &lt;p&gt;Note: it covers ignored files.
+     */
+    public static final int STATUS_MANAGED = StatusInfo.STATUS_ALL &amp; ~StatusInfo.STATUS_NOTVERSIONED_NOTMANAGED;
+    public static final int STATUS_VERSIONED = StatusInfo.STATUS_VERSIONED_UPTODATE |
+        StatusInfo.STATUS_VERSIONED_MODIFIEDLOCALLY |
+        StatusInfo.STATUS_VERSIONED_MODIFIEDINREPOSITORY |
+        StatusInfo.STATUS_VERSIONED_CONFLICT |
+        StatusInfo.STATUS_VERSIONED_MERGE |
+        StatusInfo.STATUS_VERSIONED_REMOVEDLOCALLY |
+        StatusInfo.STATUS_VERSIONED_REMOVEDINREPOSITORY |
+        StatusInfo.STATUS_VERSIONED_DELETEDLOCALLY |
+        StatusInfo.STATUS_VERSIONED_ADDEDLOCALLY |
+        StatusInfo.STATUS_VERSIONED_COPIEDLOCALLY;
+    public static final int STATUS_IN_REPOSITORY = StatusInfo.STATUS_VERSIONED_UPTODATE |
+        StatusInfo.STATUS_VERSIONED_MODIFIEDLOCALLY |
+        StatusInfo.STATUS_VERSIONED_MODIFIEDINREPOSITORY |
+        StatusInfo.STATUS_VERSIONED_CONFLICT |
+        StatusInfo.STATUS_VERSIONED_MERGE |
+        StatusInfo.STATUS_VERSIONED_REMOVEDLOCALLY |
+        StatusInfo.STATUS_VERSIONED_NEWINREPOSITORY |
+        StatusInfo.STATUS_VERSIONED_REMOVEDINREPOSITORY |
+        StatusInfo.STATUS_VERSIONED_DELETEDLOCALLY;
+    public static final int STATUS_LOCAL_CHANGE =
+        StatusInfo.STATUS_NOTVERSIONED_NEWLOCALLY |
+        StatusInfo.STATUS_VERSIONED_ADDEDLOCALLY |
+        StatusInfo.STATUS_VERSIONED_COPIEDLOCALLY |
+        StatusInfo.STATUS_VERSIONED_CONFLICT |
+        StatusInfo.STATUS_VERSIONED_DELETEDLOCALLY |
+        StatusInfo.STATUS_VERSIONED_MERGE |
+        StatusInfo.STATUS_VERSIONED_REMOVEDLOCALLY |
+        StatusInfo.STATUS_VERSIONED_MODIFIEDLOCALLY;
+    /**
+     * Modified, in conflict, scheduled for removal or addition;
+     * or deleted but with existing entry record.
+     */
+    public static final int STATUS_REVERTIBLE_CHANGE =
+        StatusInfo.STATUS_VERSIONED_ADDEDLOCALLY |
+        StatusInfo.STATUS_VERSIONED_COPIEDLOCALLY |
+        StatusInfo.STATUS_VERSIONED_CONFLICT |
+        StatusInfo.STATUS_VERSIONED_MERGE |
+        StatusInfo.STATUS_VERSIONED_REMOVEDLOCALLY |
+        StatusInfo.STATUS_VERSIONED_DELETEDLOCALLY |
+        StatusInfo.STATUS_VERSIONED_MODIFIEDLOCALLY;
+    public static final int STATUS_REMOTE_CHANGE =
+        StatusInfo.STATUS_VERSIONED_MERGE |
+        StatusInfo.STATUS_VERSIONED_MODIFIEDINREPOSITORY |
+        StatusInfo.STATUS_VERSIONED_NEWINREPOSITORY |
+        StatusInfo.STATUS_VERSIONED_REMOVEDINREPOSITORY;
+    /**
+     * Status constant.
+     */
+    private final int status;
+    /**
+     * More detailed information about a file, you may disregard the field if not needed.
+     */
+    private transient File entry;
+    /**
+     * Directory indicator, mainly because of files that may have been deleted so file.isDirectory() won't work.
+     */
+    private final boolean isDirectory;
 
-	/**
-	 * For deserialization purposes only.
-	 */
-	public StatusInfo()
-	{
-		status = 0;
-		isDirectory = false;
-	}
+    /**
+     * For deserialization purposes only.
+     */
+    public StatusInfo()
+    {
+        status = 0;
+        isDirectory = false;
+    }
 
-	public StatusInfo(int status, File entry, boolean isDirectory)
-	{
-		this.status = status;
-		this.entry = entry;
-		this.isDirectory = isDirectory;
-	}
+    public StatusInfo(int status, File entry, boolean isDirectory)
+    {
+        this.status = status;
+        this.entry = entry;
+        this.isDirectory = isDirectory;
+    }
 
-	StatusInfo(int status, boolean isDirectory)
-	{
-		this(status, null, isDirectory);
-	}
+    StatusInfo(int status, boolean isDirectory)
+    {
+        this(status, null, isDirectory);
+    }
 
-	/**
-	 * Retrieves the status constant representing status of the file.
-	 * 
-	 * @return one of status constants
-	 */
-	public int getStatus()
-	{
-		return status;
-	}
+    /**
+     * Retrieves the status constant representing status of the file.
+     *
+     * @return one of status constants
+     */
+    public int getStatus()
+    {
+        return status;
+    }
 
-	public boolean isDirectory()
-	{
-		return isDirectory;
-	}
+    public boolean isDirectory()
+    {
+        return isDirectory;
+    }
 
-	/**
-	 * Retrieves file's Status.
-	 *
-	 * @param file file this information belongs to or null if you do not want the entry to be read from disk 
-	 * in case it is not loaded yet
-	 * @return Status parsed entry form the .svn/entries file or null if the file does not exist,
-	 * is not versioned or its entry is invalid
-	 */
-	public File getStatus(File file)
-	{
-		if (entry == null &amp;&amp; file != null)
-			readEntry(file);
-		return entry;
-	}
+    /**
+     * Retrieves file's Status.
+     *
+     * @param file file this information belongs to or null if you do not want the entry to be read from disk
+     * in case it is not loaded yet
+     * @return Status parsed entry form the .svn/entries file or null if the file does not exist,
+     * is not versioned or its entry is invalid
+     */
+    public File getStatus(File file)
+    {
+        if (entry == null &amp;&amp; file != null)
+            readEntry(file);
+        return entry;
+    }
 
-	private void readEntry(File file)
-	{
-		// Fetches File info from .svn directory:
-		// entry = Subversion.getInstance().getClient(true).getSingleStatus(file);
-		entry = null;       // TODO: read your detailed information about the file here, or disregard the entry field
-	}
+    private void readEntry(File file)
+    {
+        // Fetches File info from .svn directory:
+        // entry = Subversion.getInstance().getClient(true).getSingleStatus(file);
+        entry = null;       // TODO: read your detailed information about the file here, or disregard the entry field
+    }
 
-	/**
-	 * Returns localized text representation of status.
-	 * 
-	 * @return status name, for multistatuses prefers local
-	 * status name.
-	 */
-	public String getStatusText()
-	{
-		return getStatusText(~0);
-	}
+    /**
+     * Returns localized text representation of status.
+     *
+     * @return status name, for multistatuses prefers local
+     * status name.
+     */
+    public String getStatusText()
+    {
+        return getStatusText(~0);
+    }
 
-	/**
-	 * Returns localized text representation of status.
-	 *
-	 * @param displayStatuses statuses bitmask
-	 *
-	 * @return status name, for multistatuses prefers local
-	 * status name, for masked &lt;tt&gt;&quot;&quot;&lt;/tt&gt;. // NOI18N
-	 */
-	public String getStatusText(int displayStatuses)
-	{
-		int stat = this.status &amp; displayStatuses;
-		ResourceBundle loc = NbBundle.getBundle(StatusInfo.class);
-		if (stat == StatusInfo.STATUS_UNKNOWN)
-			return loc.getString(&quot;CTL_FileInfoStatus_Unknown&quot;);
-		else if (StatusInfo.match(stat, StatusInfo.STATUS_NOTVERSIONED_EXCLUDED))
-			return loc.getString(&quot;CTL_FileInfoStatus_Excluded&quot;);
-		else if (StatusInfo.match(stat, StatusInfo.STATUS_NOTVERSIONED_NEWLOCALLY))
-			return loc.getString(&quot;CTL_FileInfoStatus_NewLocally&quot;);
-		else if (StatusInfo.match(stat, StatusInfo.STATUS_VERSIONED_ADDEDLOCALLY))
-			/* FIXME
-			if (entry != null &amp;&amp; entry.isCopied())
-			return loc.getString(&quot;CTL_FileInfoStatus_AddedLocallyCopied&quot;);
-			 */
-			return loc.getString(&quot;CTL_FileInfoStatus_AddedLocally&quot;); // NOI18N
-		else if (StatusInfo.match(stat, StatusInfo.STATUS_VERSIONED_COPIEDLOCALLY))
-			return loc.getString(&quot;CTL_FileInfoStatus_AddedLocallyCopied&quot;);
-		else if (StatusInfo.match(stat, StatusInfo.STATUS_VERSIONED_UPTODATE))
-			return loc.getString(&quot;CTL_FileInfoStatus_UpToDate&quot;);
-		else if (StatusInfo.match(stat, StatusInfo.STATUS_VERSIONED_CONFLICT))
-			return loc.getString(&quot;CTL_FileInfoStatus_Conflict&quot;);
-		else if (StatusInfo.match(stat, StatusInfo.STATUS_VERSIONED_MERGE))
-			return loc.getString(&quot;CTL_FileInfoStatus_Merge&quot;);
-		else if (StatusInfo.match(stat, StatusInfo.STATUS_VERSIONED_DELETEDLOCALLY))
-			return loc.getString(&quot;CTL_FileInfoStatus_DeletedLocally&quot;);
-		else if (StatusInfo.match(stat, StatusInfo.STATUS_VERSIONED_REMOVEDLOCALLY))
-			return loc.getString(&quot;CTL_FileInfoStatus_RemovedLocally&quot;);
-		else if (StatusInfo.match(stat, StatusInfo.STATUS_VERSIONED_MODIFIEDLOCALLY))
-			return loc.getString(&quot;CTL_FileInfoStatus_ModifiedLocally&quot;);
-		else if (StatusInfo.match(stat, StatusInfo.STATUS_VERSIONED_NEWINREPOSITORY))
-			return loc.getString(&quot;CTL_FileInfoStatus_NewInRepository&quot;);
-		else if (StatusInfo.match(stat, StatusInfo.STATUS_VERSIONED_MODIFIEDINREPOSITORY))
-			return loc.getString(&quot;CTL_FileInfoStatus_ModifiedInRepository&quot;);
-		else if (StatusInfo.match(stat, StatusInfo.STATUS_VERSIONED_REMOVEDINREPOSITORY))
-			return loc.getString(&quot;CTL_FileInfoStatus_RemovedInRepository&quot;);
-		else
-			return &quot;&quot;;
-	}
+    /**
+     * Returns localized text representation of status.
+     *
+     * @param displayStatuses statuses bitmask
+     *
+     * @return status name, for multistatuses prefers local
+     * status name, for masked &lt;tt&gt;&quot;&quot;&lt;/tt&gt;. // NOI18N
+     */
+    public String getStatusText(int displayStatuses)
+    {
+        int stat = this.status &amp; displayStatuses;
+        ResourceBundle loc = NbBundle.getBundle(StatusInfo.class);
+        if (stat == StatusInfo.STATUS_UNKNOWN)
+            return loc.getString(&quot;CTL_FileInfoStatus_Unknown&quot;);
+        else if (StatusInfo.match(stat, StatusInfo.STATUS_NOTVERSIONED_EXCLUDED))
+            return loc.getString(&quot;CTL_FileInfoStatus_Excluded&quot;);
+        else if (StatusInfo.match(stat, StatusInfo.STATUS_NOTVERSIONED_NEWLOCALLY))
+            return loc.getString(&quot;CTL_FileInfoStatus_NewLocally&quot;);
+        else if (StatusInfo.match(stat, StatusInfo.STATUS_VERSIONED_ADDEDLOCALLY))
+            /* FIXME
+            if (entry != null &amp;&amp; entry.isCopied())
+            return loc.getString(&quot;CTL_FileInfoStatus_AddedLocallyCopied&quot;);
+             */
+            return loc.getString(&quot;CTL_FileInfoStatus_AddedLocally&quot;); // NOI18N
+        else if (StatusInfo.match(stat, StatusInfo.STATUS_VERSIONED_COPIEDLOCALLY))
+            return loc.getString(&quot;CTL_FileInfoStatus_AddedLocallyCopied&quot;);
+        else if (StatusInfo.match(stat, StatusInfo.STATUS_VERSIONED_UPTODATE))
+            return loc.getString(&quot;CTL_FileInfoStatus_UpToDate&quot;);
+        else if (StatusInfo.match(stat, StatusInfo.STATUS_VERSIONED_CONFLICT))
+            return loc.getString(&quot;CTL_FileInfoStatus_Conflict&quot;);
+        else if (StatusInfo.match(stat, StatusInfo.STATUS_VERSIONED_MERGE))
+            return loc.getString(&quot;CTL_FileInfoStatus_Merge&quot;);
+        else if (StatusInfo.match(stat, StatusInfo.STATUS_VERSIONED_DELETEDLOCALLY))
+            return loc.getString(&quot;CTL_FileInfoStatus_DeletedLocally&quot;);
+        else if (StatusInfo.match(stat, StatusInfo.STATUS_VERSIONED_REMOVEDLOCALLY))
+            return loc.getString(&quot;CTL_FileInfoStatus_RemovedLocally&quot;);
+        else if (StatusInfo.match(stat, StatusInfo.STATUS_VERSIONED_MODIFIEDLOCALLY))
+            return loc.getString(&quot;CTL_FileInfoStatus_ModifiedLocally&quot;);
+        else if (StatusInfo.match(stat, StatusInfo.STATUS_VERSIONED_NEWINREPOSITORY))
+            return loc.getString(&quot;CTL_FileInfoStatus_NewInRepository&quot;);
+        else if (StatusInfo.match(stat, StatusInfo.STATUS_VERSIONED_MODIFIEDINREPOSITORY))
+            return loc.getString(&quot;CTL_FileInfoStatus_ModifiedInRepository&quot;);
+        else if (StatusInfo.match(stat, StatusInfo.STATUS_VERSIONED_REMOVEDINREPOSITORY))
+            return loc.getString(&quot;CTL_FileInfoStatus_RemovedInRepository&quot;);
+        else
+            return &quot;&quot;;
+    }
 
-	/**
-	 * @return short status name for local changes, for remote
-	 * changes returns &lt;tt&gt;&quot;&quot;&lt;/tt&gt; // NOI18N
-	 */
-	public String getShortStatusText()
-	{
-		ResourceBundle loc = NbBundle.getBundle(StatusInfo.class);
-		if (StatusInfo.match(status, StatusInfo.STATUS_NOTVERSIONED_EXCLUDED))
-			return loc.getString(&quot;CTL_FileInfoStatus_Excluded_Short&quot;);
-		else if (StatusInfo.match(status, StatusInfo.STATUS_NOTVERSIONED_NEWLOCALLY))
-			return loc.getString(&quot;CTL_FileInfoStatus_NewLocally_Short&quot;);
-		else if (StatusInfo.match(status, StatusInfo.STATUS_VERSIONED_ADDEDLOCALLY)) /* {
-			if (entry != null &amp;&amp; entry.isCopied())
-			return loc.getString(&quot;CTL_FileInfoStatus_AddedLocallyCopied_Short&quot;);
-			 */
+    /**
+     * @return short status name for local changes, for remote
+     * changes returns &lt;tt&gt;&quot;&quot;&lt;/tt&gt; // NOI18N
+     */
+    public String getShortStatusText()
+    {
+        ResourceBundle loc = NbBundle.getBundle(StatusInfo.class);
+        if (StatusInfo.match(status, StatusInfo.STATUS_NOTVERSIONED_EXCLUDED))
+            return loc.getString(&quot;CTL_FileInfoStatus_Excluded_Short&quot;);
+        else if (StatusInfo.match(status, StatusInfo.STATUS_NOTVERSIONED_NEWLOCALLY))
+            return loc.getString(&quot;CTL_FileInfoStatus_NewLocally_Short&quot;);
+        else if (StatusInfo.match(status, StatusInfo.STATUS_VERSIONED_ADDEDLOCALLY)) /* {
+            if (entry != null &amp;&amp; entry.isCopied())
+            return loc.getString(&quot;CTL_FileInfoStatus_AddedLocallyCopied_Short&quot;);
+             */
 
-			return loc.getString(&quot;CTL_FileInfoStatus_AddedLocally_Short&quot;); // NOI18N
-		else if (StatusInfo.match(status, StatusInfo.STATUS_VERSIONED_COPIEDLOCALLY))
-			return loc.getString(&quot;CTL_FileInfoStatus_AddedLocallyCopied_Short&quot;);
-		else if (status == StatusInfo.STATUS_VERSIONED_REMOVEDLOCALLY)
-			return loc.getString(&quot;CTL_FileInfoStatus_RemovedLocally_Short&quot;);
-		else if (status == StatusInfo.STATUS_VERSIONED_DELETEDLOCALLY)
-			return loc.getString(&quot;CTL_FileInfoStatus_DeletedLocally_Short&quot;);
-		else if (StatusInfo.match(status, StatusInfo.STATUS_VERSIONED_MODIFIEDLOCALLY))
-			return loc.getString(&quot;CTL_FileInfoStatus_ModifiedLocally_Short&quot;);
-		else if (StatusInfo.match(status, StatusInfo.STATUS_VERSIONED_CONFLICT))
-			return loc.getString(&quot;CTL_FileInfoStatus_Conflict_Short&quot;);
-		else
-			return &quot;&quot;;
-	}
+            return loc.getString(&quot;CTL_FileInfoStatus_AddedLocally_Short&quot;); // NOI18N
+        else if (StatusInfo.match(status, StatusInfo.STATUS_VERSIONED_COPIEDLOCALLY))
+            return loc.getString(&quot;CTL_FileInfoStatus_AddedLocallyCopied_Short&quot;);
+        else if (status == StatusInfo.STATUS_VERSIONED_REMOVEDLOCALLY)
+            return loc.getString(&quot;CTL_FileInfoStatus_RemovedLocally_Short&quot;);
+        else if (status == StatusInfo.STATUS_VERSIONED_DELETEDLOCALLY)
+            return loc.getString(&quot;CTL_FileInfoStatus_DeletedLocally_Short&quot;);
+        else if (StatusInfo.match(status, StatusInfo.STATUS_VERSIONED_MODIFIEDLOCALLY))
+            return loc.getString(&quot;CTL_FileInfoStatus_ModifiedLocally_Short&quot;);
+        else if (StatusInfo.match(status, StatusInfo.STATUS_VERSIONED_CONFLICT))
+            return loc.getString(&quot;CTL_FileInfoStatus_Conflict_Short&quot;);
+        else
+            return &quot;&quot;;
+    }
 
-	private static boolean match(int status, int mask)
-	{
-		return (status &amp; mask) != 0;
-	}
+    private static boolean match(int status, int mask)
+    {
+        return (status &amp; mask) != 0;
+    }
 
-	/**
-	 * Two StatusInfo objects are equivalent if their status contants are equal AND they both reperesent a file (or
-	 * both represent a directory) AND Entries they cache, if they can be compared, are equal.
-	 *
-	 * @param other object to compare to
-	 * @return true if status constants of both object are equal, false otherwise
-	 */
-	public static boolean equivalent(StatusInfo main, StatusInfo other)
-	{
-		if (other == null || main.getStatus() != other.getStatus() || main.isDirectory() != other.isDirectory())
-			return false;
+    /**
+     * Two StatusInfo objects are equivalent if their status contants are equal AND they both reperesent a file (or
+     * both represent a directory) AND Entries they cache, if they can be compared, are equal.
+     *
+     * @param other object to compare to
+     * @return true if status constants of both object are equal, false otherwise
+     */
+    public static boolean equivalent(StatusInfo main, StatusInfo other)
+    {
+        if (other == null || main.getStatus() != other.getStatus() || main.isDirectory() != other.isDirectory())
+            return false;
 
-		File e1 = main.getStatus(null);
-		File e2 = other.getStatus(null);
-		return e1 == e2 || e1 == null || e2 == null || equal(e1, e2);
-	}
+        File e1 = main.getStatus(null);
+        File e2 = other.getStatus(null);
+        return e1 == e2 || e1 == null || e2 == null || equal(e1, e2);
+    }
 
-	/**
-	 * Replacement for missing Entry.equals(). It is implemented as a separate method to maintain compatibility.
-	 *
-	 * @param e1 first entry to compare
-	 * @param e2 second Entry to compare
-	 * @return true if supplied entries contain equivalent information
-	 */
-	private static boolean equal(File e1, File e2)
-	{
-		// TODO: use your own logic here
-		return true;
-	}
+    /**
+     * Replacement for missing Entry.equals(). It is implemented as a separate method to maintain compatibility.
+     *
+     * @param e1 first entry to compare
+     * @param e2 second Entry to compare
+     * @return true if supplied entries contain equivalent information
+     */
+    private static boolean equal(File e1, File e2)
+    {
+        // TODO: use your own logic here
+        return true;
+    }
 
-	@Override
-	public String toString()
-	{
-		return &quot;Text: &quot; + status + &quot; &quot; + getStatusText(status); // NOI18N
-	}
+    @Override
+    public String toString()
+    {
+        return &quot;Text: &quot; + status + &quot; &quot; + getStatusText(status); // NOI18N
+    }
 
 }</diff>
      <filename>src/org/nbgit/StatusInfo.java</filename>
    </modified>
    <modified>
      <diff>@@ -47,19 +47,19 @@ import org.openide.util.NbBundle;
 
 public final class GitAdvancedOption extends AdvancedOption {
 
-	public String getDisplayName()
-	{
-		return NbBundle.getMessage(GitAdvancedOption.class, &quot;AdvancedOption_DisplayName_Git&quot;); // NOI18N
-	}
+    public String getDisplayName()
+    {
+        return NbBundle.getMessage(GitAdvancedOption.class, &quot;AdvancedOption_DisplayName_Git&quot;); // NOI18N
+    }
 
-	public String getTooltip()
-	{
-		return NbBundle.getMessage(GitAdvancedOption.class, &quot;AdvancedOption_Tooltip_Git&quot;); // NOI18N
-	}
+    public String getTooltip()
+    {
+        return NbBundle.getMessage(GitAdvancedOption.class, &quot;AdvancedOption_Tooltip_Git&quot;); // NOI18N
+    }
 
-	public OptionsPanelController create()
-	{
-		return new GitOptionsPanelController();
-	}
+    public OptionsPanelController create()
+    {
+        return new GitOptionsPanelController();
+    }
 
 }
\ No newline at end of file</diff>
      <filename>src/org/nbgit/options/GitAdvancedOption.java</filename>
    </modified>
    <modified>
      <diff>@@ -67,243 +67,243 @@ import org.openide.util.RequestProcessor;
 
 public class GitExtProperties implements ActionListener, DocumentListener {
 
-	private PropertiesPanel panel;
-	private File root;
-	private PropertiesTable propTable;
-	private GitProgressSupport support;
-	private File loadedValueFile;
-	private Font fontTextArea;
-
-	/** Creates a new instance of GitExtProperties */
-	public GitExtProperties(PropertiesPanel panel, PropertiesTable propTable, File root)
-	{
-		this.panel = panel;
-		this.propTable = propTable;
-		this.root = root;
-		panel.getTxtAreaValue().getDocument().addDocumentListener(this);
-		((JTextField) panel.getComboName().getEditor().getEditorComponent()).getDocument().addDocumentListener(this);
-		propTable.getTable().addMouseListener(new TableMouseListener());
-		panel.getBtnAdd().addActionListener(this);
-		panel.getBtnRemove().addActionListener(this);
-		panel.getComboName().setEditable(true);
-		panel.getBtnAdd().setEnabled(false);
-		initPropertyNameCbx();
-		refreshProperties();
-	}
-
-	public PropertiesPanel getPropertiesPanel()
-	{
-		return panel;
-	}
-
-	public void setPropertiesPanel(PropertiesPanel panel)
-	{
-		this.panel = panel;
-	}
-
-	public File getRoot()
-	{
-		return root;
-	}
-
-	public void setRoot(File root)
-	{
-		this.root = root;
-	}
-
-	public void actionPerformed(ActionEvent event)
-	{
-		Object source = event.getSource();
-
-		if (source.equals(panel.getBtnAdd()))
-			addProperty();
-
-		if (source.equals(panel.getBtnRemove()))
-			removeProperties();
-
-	}
-
-	protected void initPropertyNameCbx()
-	{
-		List&lt;String&gt; lstName = new ArrayList&lt;String&gt;(8);
-
-		ComboBoxModel comboModel = new DefaultComboBoxModel(new Vector&lt;String&gt;(lstName));
-		panel.getComboName().setModel(comboModel);
-		panel.getComboName().getEditor().setItem(&quot;&quot;); // NOI18N
-	}
-
-	protected String getPropertyValue()
-	{
-		return panel.getTxtAreaValue().getText();
-	}
-
-	protected String getPropertyName()
-	{
-		Object selectedItem = panel.getComboName().getSelectedObjects()[0];
-		if (selectedItem != null)
-			return panel.getComboName().getEditor().getItem().toString().trim();
-		else
-			return selectedItem.toString().trim();
-	}
-
-	protected void refreshProperties()
-	{
-		RequestProcessor rp = Git.getInstance().getRequestProcessor();
-		try {
-			support = new GitProgressSupport() {
-
-				protected void perform()
-				{
-					/*
-					Properties props = GitModuleConfig.getDefault().getProperties(root, &quot;extensions&quot;); // NOI18N
-					GitPropertiesNode[] gitProps = new GitPropertiesNode[props.size()];
-					int i = 0;
-
-					for (Enumeration e = props.propertyNames(); e.hasMoreElements();) {
-						String name = (String) e.nextElement();
-						String tmp = props.getProperty(name);
-						String value = tmp != null ? tmp : &quot;&quot;; // NOI18N
-						gitProps[i] = new GitPropertiesNode(name, value);
-						i++;
-					}
-					propTable.setNodes(gitProps);
-					 */
-				}
-
-			};
-			support.start(rp, null, org.openide.util.NbBundle.getMessage(GitExtProperties.class, &quot;LBL_Properties_Progress&quot;)); // NOI18N
-		} finally {
-			support = null;
-		}
-	}
-
-	private boolean addProperty(String name, String value)
-	{
-		GitPropertiesNode[] gitPropertiesNode = propTable.getNodes();
-		for (int i = 0; i &lt; gitPropertiesNode.length; i++) {
-			String gitPropertyName = gitPropertiesNode[propTable.getModelIndex(i)].getName();
-			if (gitPropertyName.equals(name)) {
-				gitPropertiesNode[propTable.getModelIndex(i)].setValue(value);
-				propTable.setNodes(gitPropertiesNode);
-				return true;
-			}
-		}
-		GitPropertiesNode[] gitProps = new GitPropertiesNode[gitPropertiesNode.length + 1];
-		for (int i = 0; i &lt; gitPropertiesNode.length; i++) {
-			gitProps[i] = gitPropertiesNode[i];
-		}
-		gitProps[gitPropertiesNode.length] = new GitPropertiesNode(name, value);
-		propTable.setNodes(gitProps);
-		return true;
-	}
-
-	public void addProperty()
-	{
-		if (addProperty(getPropertyName(), getPropertyValue())) {
-			panel.getComboName().getEditor().setItem(&quot;&quot;); // NOI18N
-			panel.getTxtAreaValue().setText(&quot;&quot;); // NOI18N
-		}
-	}
-
-	public void setProperties()
-	{
-		RequestProcessor rp = Git.getInstance().getRequestProcessor();
-		try {
-			support = new GitProgressSupport() {
-
-				protected void perform()
-				{
-					/*
-					GitModuleConfig.getDefault().clearProperties(root, &quot;extensions&quot;); // NOI18N
-					GitPropertiesNode[] gitPropertiesNodes = propTable.getNodes();
-					for (int i = 0; i &lt; gitPropertiesNodes.length; i++) {
-						String gitPropertyName = gitPropertiesNodes[propTable.getModelIndex(i)].getName();
-						String gitPropertyValue = gitPropertiesNodes[propTable.getModelIndex(i)].getValue();
-						GitModuleConfig.getDefault().setProperty(root, &quot;extensions&quot;, gitPropertyName, gitPropertyValue, true); // NOI18N
-					}
-					 */
-				}
-
-			};
-			support.start(rp, null, org.openide.util.NbBundle.getMessage(GitExtProperties.class, &quot;LBL_Properties_Progress&quot;)); // NOI18N
-		} finally {
-			support = null;
-		}
-	}
-
-	public void removeProperties()
-	{
-		final int[] rows = propTable.getSelectedItems();
-		// No rows selected
-		if (rows.length == 0)
-			return;
-		GitPropertiesNode[] gitPropertiesNodes = propTable.getNodes();
-		GitPropertiesNode[] gitProps = new GitPropertiesNode[gitPropertiesNodes.length - rows.length];
-		int j = 0;
-		int k = 0;
-		for (int i = 0; i &lt; gitPropertiesNodes.length; i++) {
-			if (i != rows[j])
-				gitProps[k++] = gitPropertiesNodes[i];
-			else
-				if (j &lt; rows.length - 1)
-					j++;
-		}
-		propTable.setNodes(gitProps);
-	}
-
-	public void insertUpdate(DocumentEvent event)
-	{
-		validateUserInput(event);
-	}
-
-	public void removeUpdate(DocumentEvent event)
-	{
-		validateUserInput(event);
-	}
-
-	public void changedUpdate(DocumentEvent event)
-	{
-		validateUserInput(event);
-	}
-
-	private void validateUserInput(DocumentEvent event)
-	{
-
-		Document doc = event.getDocument();
-		String name = panel.getComboName().getEditor().getItem().toString().trim();
-		String value = panel.getTxtAreaValue().getText().trim();
-
-		if (name.length() == 0 || name.indexOf(&quot; &quot;) &gt; 0) // NOI18N
-			panel.getBtnAdd().setEnabled(false);
-		else
-			panel.getBtnAdd().setEnabled(true);
-	}
-
-	public class TableMouseListener extends MouseAdapter {
-
-		@Override
-		public void mouseClicked(MouseEvent event)
-		{
-			//super.mouseClicked(arg0);
-			if (event.getClickCount() == 2) {
-				int[] rows = propTable.getSelectedItems();
-				GitPropertiesNode[] gitPropertiesNodes = propTable.getNodes();
-				if (gitPropertiesNodes == null)
-					return;
-				final String gitPropertyName = gitPropertiesNodes[propTable.getModelIndex(rows[0])].getName();
-				final String gitPropertyValue = gitPropertiesNodes[propTable.getModelIndex(rows[0])].getValue();
-				EventQueue.invokeLater(new Runnable() {
-
-					public void run()
-					{
-						panel.getComboName().getEditor().setItem(gitPropertyName);
-						panel.getTxtAreaValue().setText(gitPropertyValue);
-					}
-
-				});
-			}
-		}
-
-	}
+    private PropertiesPanel panel;
+    private File root;
+    private PropertiesTable propTable;
+    private GitProgressSupport support;
+    private File loadedValueFile;
+    private Font fontTextArea;
+
+    /** Creates a new instance of GitExtProperties */
+    public GitExtProperties(PropertiesPanel panel, PropertiesTable propTable, File root)
+    {
+        this.panel = panel;
+        this.propTable = propTable;
+        this.root = root;
+        panel.getTxtAreaValue().getDocument().addDocumentListener(this);
+        ((JTextField) panel.getComboName().getEditor().getEditorComponent()).getDocument().addDocumentListener(this);
+        propTable.getTable().addMouseListener(new TableMouseListener());
+        panel.getBtnAdd().addActionListener(this);
+        panel.getBtnRemove().addActionListener(this);
+        panel.getComboName().setEditable(true);
+        panel.getBtnAdd().setEnabled(false);
+        initPropertyNameCbx();
+        refreshProperties();
+    }
+
+    public PropertiesPanel getPropertiesPanel()
+    {
+        return panel;
+    }
+
+    public void setPropertiesPanel(PropertiesPanel panel)
+    {
+        this.panel = panel;
+    }
+
+    public File getRoot()
+    {
+        return root;
+    }
+
+    public void setRoot(File root)
+    {
+        this.root = root;
+    }
+
+    public void actionPerformed(ActionEvent event)
+    {
+        Object source = event.getSource();
+
+        if (source.equals(panel.getBtnAdd()))
+            addProperty();
+
+        if (source.equals(panel.getBtnRemove()))
+            removeProperties();
+
+    }
+
+    protected void initPropertyNameCbx()
+    {
+        List&lt;String&gt; lstName = new ArrayList&lt;String&gt;(8);
+
+        ComboBoxModel comboModel = new DefaultComboBoxModel(new Vector&lt;String&gt;(lstName));
+        panel.getComboName().setModel(comboModel);
+        panel.getComboName().getEditor().setItem(&quot;&quot;); // NOI18N
+    }
+
+    protected String getPropertyValue()
+    {
+        return panel.getTxtAreaValue().getText();
+    }
+
+    protected String getPropertyName()
+    {
+        Object selectedItem = panel.getComboName().getSelectedObjects()[0];
+        if (selectedItem != null)
+            return panel.getComboName().getEditor().getItem().toString().trim();
+        else
+            return selectedItem.toString().trim();
+    }
+
+    protected void refreshProperties()
+    {
+        RequestProcessor rp = Git.getInstance().getRequestProcessor();
+        try {
+            support = new GitProgressSupport() {
+
+                protected void perform()
+                {
+                    /*
+                    Properties props = GitModuleConfig.getDefault().getProperties(root, &quot;extensions&quot;); // NOI18N
+                    GitPropertiesNode[] gitProps = new GitPropertiesNode[props.size()];
+                    int i = 0;
+
+                    for (Enumeration e = props.propertyNames(); e.hasMoreElements();) {
+                        String name = (String) e.nextElement();
+                        String tmp = props.getProperty(name);
+                        String value = tmp != null ? tmp : &quot;&quot;; // NOI18N
+                        gitProps[i] = new GitPropertiesNode(name, value);
+                        i++;
+                    }
+                    propTable.setNodes(gitProps);
+                     */
+                }
+
+            };
+            support.start(rp, null, org.openide.util.NbBundle.getMessage(GitExtProperties.class, &quot;LBL_Properties_Progress&quot;)); // NOI18N
+        } finally {
+            support = null;
+        }
+    }
+
+    private boolean addProperty(String name, String value)
+    {
+        GitPropertiesNode[] gitPropertiesNode = propTable.getNodes();
+        for (int i = 0; i &lt; gitPropertiesNode.length; i++) {
+            String gitPropertyName = gitPropertiesNode[propTable.getModelIndex(i)].getName();
+            if (gitPropertyName.equals(name)) {
+                gitPropertiesNode[propTable.getModelIndex(i)].setValue(value);
+                propTable.setNodes(gitPropertiesNode);
+                return true;
+            }
+        }
+        GitPropertiesNode[] gitProps = new GitPropertiesNode[gitPropertiesNode.length + 1];
+        for (int i = 0; i &lt; gitPropertiesNode.length; i++) {
+            gitProps[i] = gitPropertiesNode[i];
+        }
+        gitProps[gitPropertiesNode.length] = new GitPropertiesNode(name, value);
+        propTable.setNodes(gitProps);
+        return true;
+    }
+
+    public void addProperty()
+    {
+        if (addProperty(getPropertyName(), getPropertyValue())) {
+            panel.getComboName().getEditor().setItem(&quot;&quot;); // NOI18N
+            panel.getTxtAreaValue().setText(&quot;&quot;); // NOI18N
+        }
+    }
+
+    public void setProperties()
+    {
+        RequestProcessor rp = Git.getInstance().getRequestProcessor();
+        try {
+            support = new GitProgressSupport() {
+
+                protected void perform()
+                {
+                    /*
+                    GitModuleConfig.getDefault().clearProperties(root, &quot;extensions&quot;); // NOI18N
+                    GitPropertiesNode[] gitPropertiesNodes = propTable.getNodes();
+                    for (int i = 0; i &lt; gitPropertiesNodes.length; i++) {
+                        String gitPropertyName = gitPropertiesNodes[propTable.getModelIndex(i)].getName();
+                        String gitPropertyValue = gitPropertiesNodes[propTable.getModelIndex(i)].getValue();
+                        GitModuleConfig.getDefault().setProperty(root, &quot;extensions&quot;, gitPropertyName, gitPropertyValue, true); // NOI18N
+                    }
+                     */
+                }
+
+            };
+            support.start(rp, null, org.openide.util.NbBundle.getMessage(GitExtProperties.class, &quot;LBL_Properties_Progress&quot;)); // NOI18N
+        } finally {
+            support = null;
+        }
+    }
+
+    public void removeProperties()
+    {
+        final int[] rows = propTable.getSelectedItems();
+        // No rows selected
+        if (rows.length == 0)
+            return;
+        GitPropertiesNode[] gitPropertiesNodes = propTable.getNodes();
+        GitPropertiesNode[] gitProps = new GitPropertiesNode[gitPropertiesNodes.length - rows.length];
+        int j = 0;
+        int k = 0;
+        for (int i = 0; i &lt; gitPropertiesNodes.length; i++) {
+            if (i != rows[j])
+                gitProps[k++] = gitPropertiesNodes[i];
+            else
+                if (j &lt; rows.length - 1)
+                    j++;
+        }
+        propTable.setNodes(gitProps);
+    }
+
+    public void insertUpdate(DocumentEvent event)
+    {
+        validateUserInput(event);
+    }
+
+    public void removeUpdate(DocumentEvent event)
+    {
+        validateUserInput(event);
+    }
+
+    public void changedUpdate(DocumentEvent event)
+    {
+        validateUserInput(event);
+    }
+
+    private void validateUserInput(DocumentEvent event)
+    {
+
+        Document doc = event.getDocument();
+        String name = panel.getComboName().getEditor().getItem().toString().trim();
+        String value = panel.getTxtAreaValue().getText().trim();
+
+        if (name.length() == 0 || name.indexOf(&quot; &quot;) &gt; 0) // NOI18N
+            panel.getBtnAdd().setEnabled(false);
+        else
+            panel.getBtnAdd().setEnabled(true);
+    }
+
+    public class TableMouseListener extends MouseAdapter {
+
+        @Override
+        public void mouseClicked(MouseEvent event)
+        {
+            //super.mouseClicked(arg0);
+            if (event.getClickCount() == 2) {
+                int[] rows = propTable.getSelectedItems();
+                GitPropertiesNode[] gitPropertiesNodes = propTable.getNodes();
+                if (gitPropertiesNodes == null)
+                    return;
+                final String gitPropertyName = gitPropertiesNodes[propTable.getModelIndex(rows[0])].getName();
+                final String gitPropertyValue = gitPropertiesNodes[propTable.getModelIndex(rows[0])].getValue();
+                EventQueue.invokeLater(new Runnable() {
+
+                    public void run()
+                    {
+                        panel.getComboName().getEditor().setItem(gitPropertyName);
+                        panel.getTxtAreaValue().setText(gitPropertyValue);
+                    }
+
+                });
+            }
+        }
+
+    }
 
 }
\ No newline at end of file</diff>
      <filename>src/org/nbgit/options/GitExtProperties.java</filename>
    </modified>
    <modified>
      <diff>@@ -72,260 +72,260 @@ import org.openide.util.NbBundle;
 
 final class GitOptionsPanelController extends OptionsPanelController implements ActionListener {
 
-	private GitPanel panel;
-	private final PropertyChangeSupport pcs = new PropertyChangeSupport(this);
-	private boolean changed;
-
-	public GitOptionsPanelController()
-	{
-		panel = new GitPanel(this);
-		panel.exportFilenameBrowseButton.addActionListener(this);
-
-		String tooltip = NbBundle.getMessage(GitPanel.class, &quot;GitPanel.annotationTextField.toolTipText&quot;, GitAnnotator.LABELS); // NOI18N
-
-		panel.annotationTextField.setToolTipText(tooltip);
-		panel.addButton.addActionListener(this);
-	}
-
-	public void update()
-	{
-		getPanel().load();
-		changed = false;
-	}
-
-	public void applyChanges()
-	{
-		if (!validateFields())
-			return;
-
-		getPanel().store();
-		// {folder} variable setting
-		HtmlFormatter.getInstance().refresh();
-		Git.getInstance().refreshAllAnnotations();
-
-		changed = false;
-	}
-
-	public void cancel()
-	{
-		// need not do anything special, if no changes have been persisted yet
-	}
-
-	public boolean isValid()
-	{
-		return getPanel().valid();
-	}
-
-	public boolean isChanged()
-	{
-		return changed;
-	}
-
-	public HelpCtx getHelpCtx()
-	{
-		return new HelpCtx(GitOptionsPanelController.class);
-	}
-
-	public JComponent getComponent(Lookup masterLookup)
-	{
-		return getPanel();
-	}
-
-	public void addPropertyChangeListener(PropertyChangeListener l)
-	{
-		pcs.addPropertyChangeListener(l);
-	}
-
-	public void removePropertyChangeListener(PropertyChangeListener l)
-	{
-		pcs.removePropertyChangeListener(l);
-	}
-
-	public void actionPerformed(ActionEvent evt)
-	{
-		if (evt.getSource() == panel.exportFilenameBrowseButton)
-			onExportFilenameBrowseClick();
-		else if (evt.getSource() == panel.addButton)
-			onAddClick();
-	}
-
-	private File getExportFile()
-	{
-		String execPath = panel.exportFilenameTextField.getText();
-		return FileUtil.normalizeFile(new File(execPath));
-	}
-
-	private Boolean validateFields()
-	{
-		String username = panel.emailTextField.getText();
-		if (!GitModuleConfig.getDefault().isUserNameValid(username)) {
-			JOptionPane.showMessageDialog(null,
-				NbBundle.getMessage(GitPanel.class, &quot;MSG_WARN_USER_NAME_TEXT&quot;), // NOI18N
-				NbBundle.getMessage(GitPanel.class, &quot;MSG_WARN_FIELD_TITLE&quot;), // NOI18N
-				JOptionPane.WARNING_MESSAGE);
-			return false;
-		}
-		return true;
-	}
-
-	private void onExportFilenameBrowseClick()
-	{
-		File oldFile = getExportFile();
-		JFileChooser fileChooser = new AccessibleJFileChooser(NbBundle.getMessage(GitOptionsPanelController.class, &quot;ACSD_ExportBrowseFolder&quot;), oldFile);   // NOI18N
-		fileChooser.setDialogTitle(NbBundle.getMessage(GitOptionsPanelController.class, &quot;ExportBrowse_title&quot;));                                            // NOI18N
-		fileChooser.setMultiSelectionEnabled(false);
-		FileFilter[] old = fileChooser.getChoosableFileFilters();
-		for (int i = 0; i &lt; old.length; i++) {
-			FileFilter fileFilter = old[i];
-			fileChooser.removeChoosableFileFilter(fileFilter);
-		}
-		fileChooser.showDialog(panel, NbBundle.getMessage(GitOptionsPanelController.class, &quot;OK_Button&quot;));                                            // NOI18N
-		File f = fileChooser.getSelectedFile();
-		if (f != null)
-			panel.exportFilenameTextField.setText(f.getAbsolutePath());
-	}
-
-	private GitPanel getPanel()
-	{
-		if (panel == null)
-			panel = new GitPanel(this);
-		return panel;
-	}
-
-	void changed()
-	{
-		if (!changed) {
-			changed = true;
-			pcs.firePropertyChange(OptionsPanelController.PROP_CHANGED, false, true);
-		}
-		pcs.firePropertyChange(OptionsPanelController.PROP_VALID, null, null);
-	}
-
-	private class LabelVariable {
-
-		private String description;
-		private String variable;
-
-		public LabelVariable(String variable, String description)
-		{
-			this.description = description;
-			this.variable = variable;
-		}
-
-		@Override
-		public String toString()
-		{
-			return description;
-		}
-
-		public String getDescription()
-		{
-			return description;
-		}
-
-		public String getVariable()
-		{
-			return variable;
-		}
-
-	}
-
-	private void onAddClick()
-	{
-		LabelsPanel labelsPanel = new LabelsPanel();
-		List&lt;LabelVariable&gt; variables = new ArrayList&lt;LabelVariable&gt;(GitAnnotator.LABELS.length);
-		for (int i = 0; i &lt; GitAnnotator.LABELS.length; i++) {
-			LabelVariable variable = new LabelVariable(
-				GitAnnotator.LABELS[i],
-				&quot;{&quot; + GitAnnotator.LABELS[i] + &quot;} - &quot; + NbBundle.getMessage(GitPanel.class, &quot;GitPanel.label.&quot; + GitAnnotator.LABELS[i]) // NOI18N
-				);
-			variables.add(variable);
-		}
-		labelsPanel.labelsList.setListData(variables.toArray(new LabelVariable[variables.size()]));
-
-		String title = NbBundle.getMessage(GitPanel.class, &quot;GitPanel.labelVariables.title&quot;); // NOI18N
-		String acsd = NbBundle.getMessage(GitPanel.class, &quot;GitPanel.labelVariables.acsd&quot;); // NOI18N
-
-		DialogDescriptor dialogDescriptor = new DialogDescriptor(labelsPanel, title);
-		dialogDescriptor.setModal(true);
-		dialogDescriptor.setValid(true);
-
-		final Dialog dialog = DialogDisplayer.getDefault().createDialog(dialogDescriptor);
-		dialog.getAccessibleContext().setAccessibleDescription(acsd);
-
-		labelsPanel.labelsList.addMouseListener(new MouseAdapter() {
-
-			@Override
-			public void mouseClicked(MouseEvent e)
-			{
-				if (e.getClickCount() == 2)
-					dialog.setVisible(false);
-			}
-
-		});
-
-		dialog.setVisible(true);
-
-		if (DialogDescriptor.OK_OPTION.equals(dialogDescriptor.getValue())) {
-
-			Object[] selection = labelsPanel.labelsList.getSelectedValues();
-
-			String variable = &quot;&quot;; // NOI18N
-			for (int i = 0; i &lt; selection.length; i++) {
-				variable += &quot;{&quot; + ((LabelVariable) selection[i]).getVariable() + &quot;}&quot;; // NOI18N
-			}
-
-			String annotation = panel.annotationTextField.getText();
-
-			int pos = panel.annotationTextField.getCaretPosition();
-			if (pos &lt; 0)
-				pos = annotation.length();
-
-			StringBuffer sb = new StringBuffer(annotation.length() + variable.length());
-			sb.append(annotation.substring(0, pos));
-			sb.append(variable);
-			if (pos &lt; annotation.length())
-				sb.append(annotation.substring(pos, annotation.length()));
-			panel.annotationTextField.setText(sb.toString());
-			panel.annotationTextField.requestFocus();
-			panel.annotationTextField.setCaretPosition(pos + variable.length());
-		}
-	}
-
-	private void onManageClick()
-	{
-		final PropertiesPanel panel = new PropertiesPanel();
-
-		final PropertiesTable propTable;
-
-		propTable = new PropertiesTable(panel.labelForTable, PropertiesTable.PROPERTIES_COLUMNS, new String[]{PropertiesTableModel.COLUMN_NAME_VALUE});
-
-		panel.setPropertiesTable(propTable);
-
-		JComponent component = propTable.getComponent();
-
-		panel.propsPanel.setLayout(new BorderLayout());
-
-		panel.propsPanel.add(component, BorderLayout.CENTER);
-
-		GitExtProperties gitProperties = new GitExtProperties(panel, propTable, null);
-
-		DialogDescriptor dd = new DialogDescriptor(panel, NbBundle.getMessage(GitOptionsPanelController.class, &quot;CTL_PropertiesDialog_Title&quot;, null), true, null); // NOI18N
-		final JButton okButton = new JButton(NbBundle.getMessage(GitOptionsPanelController.class, &quot;CTL_Properties_Action_OK&quot;)); // NOI18N
-		okButton.getAccessibleContext().setAccessibleDescription(NbBundle.getMessage(GitOptionsPanelController.class, &quot;CTL_Properties_Action_OK&quot;)); // NOI18N
-		final JButton cancelButton = new JButton(NbBundle.getMessage(GitOptionsPanelController.class, &quot;CTL_Properties_Action_Cancel&quot;)); // NOI18N
-		cancelButton.getAccessibleContext().setAccessibleDescription(NbBundle.getMessage(GitOptionsPanelController.class, &quot;CTL_Properties_Action_Cancel&quot;)); // NOI18N
-		dd.setOptions(new Object[]{okButton, cancelButton}); // NOI18N
-		dd.setHelpCtx(new HelpCtx(GitOptionsPanelController.class));
-		panel.putClientProperty(&quot;contentTitle&quot;, null);  // NOI18N
-		panel.putClientProperty(&quot;DialogDescriptor&quot;, dd); // NOI18N
-		Dialog dialog = DialogDisplayer.getDefault().createDialog(dd);
-		dialog.getAccessibleContext().setAccessibleDescription(NbBundle.getMessage(GitOptionsPanelController.class, &quot;CTL_PropertiesDialog_Title&quot;)); // NOI18N
+    private GitPanel panel;
+    private final PropertyChangeSupport pcs = new PropertyChangeSupport(this);
+    private boolean changed;
+
+    public GitOptionsPanelController()
+    {
+        panel = new GitPanel(this);
+        panel.exportFilenameBrowseButton.addActionListener(this);
+
+        String tooltip = NbBundle.getMessage(GitPanel.class, &quot;GitPanel.annotationTextField.toolTipText&quot;, GitAnnotator.LABELS); // NOI18N
+
+        panel.annotationTextField.setToolTipText(tooltip);
+        panel.addButton.addActionListener(this);
+    }
+
+    public void update()
+    {
+        getPanel().load();
+        changed = false;
+    }
+
+    public void applyChanges()
+    {
+        if (!validateFields())
+            return;
+
+        getPanel().store();
+        // {folder} variable setting
+        HtmlFormatter.getInstance().refresh();
+        Git.getInstance().refreshAllAnnotations();
+
+        changed = false;
+    }
+
+    public void cancel()
+    {
+        // need not do anything special, if no changes have been persisted yet
+    }
+
+    public boolean isValid()
+    {
+        return getPanel().valid();
+    }
+
+    public boolean isChanged()
+    {
+        return changed;
+    }
+
+    public HelpCtx getHelpCtx()
+    {
+        return new HelpCtx(GitOptionsPanelController.class);
+    }
+
+    public JComponent getComponent(Lookup masterLookup)
+    {
+        return getPanel();
+    }
+
+    public void addPropertyChangeListener(PropertyChangeListener l)
+    {
+        pcs.addPropertyChangeListener(l);
+    }
+
+    public void removePropertyChangeListener(PropertyChangeListener l)
+    {
+        pcs.removePropertyChangeListener(l);
+    }
+
+    public void actionPerformed(ActionEvent evt)
+    {
+        if (evt.getSource() == panel.exportFilenameBrowseButton)
+            onExportFilenameBrowseClick();
+        else if (evt.getSource() == panel.addButton)
+            onAddClick();
+    }
+
+    private File getExportFile()
+    {
+        String execPath = panel.exportFilenameTextField.getText();
+        return FileUtil.normalizeFile(new File(execPath));
+    }
+
+    private Boolean validateFields()
+    {
+        String username = panel.emailTextField.getText();
+        if (!GitModuleConfig.getDefault().isUserNameValid(username)) {
+            JOptionPane.showMessageDialog(null,
+                NbBundle.getMessage(GitPanel.class, &quot;MSG_WARN_USER_NAME_TEXT&quot;), // NOI18N
+                NbBundle.getMessage(GitPanel.class, &quot;MSG_WARN_FIELD_TITLE&quot;), // NOI18N
+                JOptionPane.WARNING_MESSAGE);
+            return false;
+        }
+        return true;
+    }
+
+    private void onExportFilenameBrowseClick()
+    {
+        File oldFile = getExportFile();
+        JFileChooser fileChooser = new AccessibleJFileChooser(NbBundle.getMessage(GitOptionsPanelController.class, &quot;ACSD_ExportBrowseFolder&quot;), oldFile);   // NOI18N
+        fileChooser.setDialogTitle(NbBundle.getMessage(GitOptionsPanelController.class, &quot;ExportBrowse_title&quot;));                                            // NOI18N
+        fileChooser.setMultiSelectionEnabled(false);
+        FileFilter[] old = fileChooser.getChoosableFileFilters();
+        for (int i = 0; i &lt; old.length; i++) {
+            FileFilter fileFilter = old[i];
+            fileChooser.removeChoosableFileFilter(fileFilter);
+        }
+        fileChooser.showDialog(panel, NbBundle.getMessage(GitOptionsPanelController.class, &quot;OK_Button&quot;));                                            // NOI18N
+        File f = fileChooser.getSelectedFile();
+        if (f != null)
+            panel.exportFilenameTextField.setText(f.getAbsolutePath());
+    }
+
+    private GitPanel getPanel()
+    {
+        if (panel == null)
+            panel = new GitPanel(this);
+        return panel;
+    }
+
+    void changed()
+    {
+        if (!changed) {
+            changed = true;
+            pcs.firePropertyChange(OptionsPanelController.PROP_CHANGED, false, true);
+        }
+        pcs.firePropertyChange(OptionsPanelController.PROP_VALID, null, null);
+    }
+
+    private class LabelVariable {
+
+        private String description;
+        private String variable;
+
+        public LabelVariable(String variable, String description)
+        {
+            this.description = description;
+            this.variable = variable;
+        }
+
+        @Override
+        public String toString()
+        {
+            return description;
+        }
+
+        public String getDescription()
+        {
+            return description;
+        }
+
+        public String getVariable()
+        {
+            return variable;
+        }
+
+    }
+
+    private void onAddClick()
+    {
+        LabelsPanel labelsPanel = new LabelsPanel();
+        List&lt;LabelVariable&gt; variables = new ArrayList&lt;LabelVariable&gt;(GitAnnotator.LABELS.length);
+        for (int i = 0; i &lt; GitAnnotator.LABELS.length; i++) {
+            LabelVariable variable = new LabelVariable(
+                GitAnnotator.LABELS[i],
+                &quot;{&quot; + GitAnnotator.LABELS[i] + &quot;} - &quot; + NbBundle.getMessage(GitPanel.class, &quot;GitPanel.label.&quot; + GitAnnotator.LABELS[i]) // NOI18N
+                );
+            variables.add(variable);
+        }
+        labelsPanel.labelsList.setListData(variables.toArray(new LabelVariable[variables.size()]));
+
+        String title = NbBundle.getMessage(GitPanel.class, &quot;GitPanel.labelVariables.title&quot;); // NOI18N
+        String acsd = NbBundle.getMessage(GitPanel.class, &quot;GitPanel.labelVariables.acsd&quot;); // NOI18N
+
+        DialogDescriptor dialogDescriptor = new DialogDescriptor(labelsPanel, title);
+        dialogDescriptor.setModal(true);
+        dialogDescriptor.setValid(true);
+
+        final Dialog dialog = DialogDisplayer.getDefault().createDialog(dialogDescriptor);
+        dialog.getAccessibleContext().setAccessibleDescription(acsd);
+
+        labelsPanel.labelsList.addMouseListener(new MouseAdapter() {
+
+            @Override
+            public void mouseClicked(MouseEvent e)
+            {
+                if (e.getClickCount() == 2)
+                    dialog.setVisible(false);
+            }
+
+        });
+
+        dialog.setVisible(true);
+
+        if (DialogDescriptor.OK_OPTION.equals(dialogDescriptor.getValue())) {
+
+            Object[] selection = labelsPanel.labelsList.getSelectedValues();
+
+            String variable = &quot;&quot;; // NOI18N
+            for (int i = 0; i &lt; selection.length; i++) {
+                variable += &quot;{&quot; + ((LabelVariable) selection[i]).getVariable() + &quot;}&quot;; // NOI18N
+            }
+
+            String annotation = panel.annotationTextField.getText();
+
+            int pos = panel.annotationTextField.getCaretPosition();
+            if (pos &lt; 0)
+                pos = annotation.length();
+
+            StringBuffer sb = new StringBuffer(annotation.length() + variable.length());
+            sb.append(annotation.substring(0, pos));
+            sb.append(variable);
+            if (pos &lt; annotation.length())
+                sb.append(annotation.substring(pos, annotation.length()));
+            panel.annotationTextField.setText(sb.toString());
+            panel.annotationTextField.requestFocus();
+            panel.annotationTextField.setCaretPosition(pos + variable.length());
+        }
+    }
+
+    private void onManageClick()
+    {
+        final PropertiesPanel panel = new PropertiesPanel();
+
+        final PropertiesTable propTable;
+
+        propTable = new PropertiesTable(panel.labelForTable, PropertiesTable.PROPERTIES_COLUMNS, new String[]{PropertiesTableModel.COLUMN_NAME_VALUE});
+
+        panel.setPropertiesTable(propTable);
+
+        JComponent component = propTable.getComponent();
+
+        panel.propsPanel.setLayout(new BorderLayout());
+
+        panel.propsPanel.add(component, BorderLayout.CENTER);
+
+        GitExtProperties gitProperties = new GitExtProperties(panel, propTable, null);
+
+        DialogDescriptor dd = new DialogDescriptor(panel, NbBundle.getMessage(GitOptionsPanelController.class, &quot;CTL_PropertiesDialog_Title&quot;, null), true, null); // NOI18N
+        final JButton okButton = new JButton(NbBundle.getMessage(GitOptionsPanelController.class, &quot;CTL_Properties_Action_OK&quot;)); // NOI18N
+        okButton.getAccessibleContext().setAccessibleDescription(NbBundle.getMessage(GitOptionsPanelController.class, &quot;CTL_Properties_Action_OK&quot;)); // NOI18N
+        final JButton cancelButton = new JButton(NbBundle.getMessage(GitOptionsPanelController.class, &quot;CTL_Properties_Action_Cancel&quot;)); // NOI18N
+        cancelButton.getAccessibleContext().setAccessibleDescription(NbBundle.getMessage(GitOptionsPanelController.class, &quot;CTL_Properties_Action_Cancel&quot;)); // NOI18N
+        dd.setOptions(new Object[]{okButton, cancelButton}); // NOI18N
+        dd.setHelpCtx(new HelpCtx(GitOptionsPanelController.class));
+        panel.putClientProperty(&quot;contentTitle&quot;, null);  // NOI18N
+        panel.putClientProperty(&quot;DialogDescriptor&quot;, dd); // NOI18N
+        Dialog dialog = DialogDisplayer.getDefault().createDialog(dd);
+        dialog.getAccessibleContext().setAccessibleDescription(NbBundle.getMessage(GitOptionsPanelController.class, &quot;CTL_PropertiesDialog_Title&quot;)); // NOI18N
 
-		dialog.pack();
-		dialog.setVisible(true);
-		if (dd.getValue() == okButton)
-			gitProperties.setProperties();
-	}
+        dialog.pack();
+        dialog.setVisible(true);
+        if (dd.getValue() == okButton)
+            gitProperties.setProperties();
+    }
 
 }
\ No newline at end of file</diff>
      <filename>src/org/nbgit/options/GitOptionsPanelController.java</filename>
    </modified>
    <modified>
      <diff>@@ -50,52 +50,52 @@ import org.nbgit.util.HtmlFormatter;
 
 final class GitPanel extends javax.swing.JPanel {
 
-	private final GitOptionsPanelController controller;
-	private final DocumentListener listener;
-
-	GitPanel(GitOptionsPanelController controller)
-	{
-		this.controller = controller;
-		this.listener = new DocumentListener() {
-
-			public void insertUpdate(DocumentEvent e)
-			{
-				nameChange();
-			}
-
-			public void removeUpdate(DocumentEvent e)
-			{
-				nameChange();
-			}
-
-			public void changedUpdate(DocumentEvent e)
-			{
-				nameChange();
-			}
-
-		};
-		initComponents();
-	}
-
-	@Override
-	public void addNotify()
-	{
-		super.addNotify();
-		emailTextField.getDocument().addDocumentListener(listener);
-	}
-
-	@Override
-	public void removeNotify()
-	{
-		emailTextField.getDocument().removeDocumentListener(listener);
-		super.removeNotify();
-	}
-
-	/** This method is called from within the constructor to
-	 * initialize the form.
-	 * WARNING: Do NOT modify this code. The content of this method is
-	 * always regenerated by the Form Editor.
-	 */
+    private final GitOptionsPanelController controller;
+    private final DocumentListener listener;
+
+    GitPanel(GitOptionsPanelController controller)
+    {
+        this.controller = controller;
+        this.listener = new DocumentListener() {
+
+            public void insertUpdate(DocumentEvent e)
+            {
+                nameChange();
+            }
+
+            public void removeUpdate(DocumentEvent e)
+            {
+                nameChange();
+            }
+
+            public void changedUpdate(DocumentEvent e)
+            {
+                nameChange();
+            }
+
+        };
+        initComponents();
+    }
+
+    @Override
+    public void addNotify()
+    {
+        super.addNotify();
+        emailTextField.getDocument().addDocumentListener(listener);
+    }
+
+    @Override
+    public void removeNotify()
+    {
+        emailTextField.getDocument().removeDocumentListener(listener);
+        super.removeNotify();
+    }
+
+    /** This method is called from within the constructor to
+     * initialize the form.
+     * WARNING: Do NOT modify this code. The content of this method is
+     * always regenerated by the Form Editor.
+     */
     // &lt;editor-fold defaultstate=&quot;collapsed&quot; desc=&quot;Generated Code&quot;&gt;//GEN-BEGIN:initComponents
     private void initComponents() {
 
@@ -300,60 +300,60 @@ private void annotationTextFieldActionPerformed(java.awt.event.ActionEvent evt)
 // TODO add your handling code here:
 }//GEN-LAST:event_annotationTextFieldActionPerformed
 
-	private void nameChange()
-	{
-		controller.changed();
-	}
-
-	void load()
-	{
-		// TODO read settings and initialize GUI
-		// Example:
-		// someCheckBox.setSelected(Preferences.userNodeForPackage(GitPanel.class).getBoolean(&quot;someFlag&quot;, false)); // NOI18N
-		// or for org.openide.util with API spec. version &gt;= 7.4:
-		// someCheckBox.setSelected(NbPreferences.forModule(GitPanel.class).getBoolean(&quot;someFlag&quot;, false)); // NOI18N
-		// or:
-		// someTextField.setText(SomeSystemOption.getDefault().getSomeStringProperty());
-		emailTextField.setText(GitModuleConfig.getDefault().getEmail());
-		userNameTextField.setText(GitModuleConfig.getDefault().getUserName());
-		exportFilenameTextField.setText(GitModuleConfig.getDefault().getExportFilename());
-		annotationTextField.setText(GitModuleConfig.getDefault().getAnnotationFormat());
-		backupOnRevertModifications.setSelected(GitModuleConfig.getDefault().getBackupOnRevertModifications());
-	}
-
-	void store()
-	{
-		// TODO store modified settings
-		// Example:
-		// Preferences.userNodeForPackage(GitPanel.class).putBoolean(&quot;someFlag&quot;, someCheckBox.isSelected()); // NOI18N
-		// or for org.openide.util with API spec. version &gt;= 7.4:
-		// NbPreferences.forModule(GitPanel.class).putBoolean(&quot;someFlag&quot;, someCheckBox.isSelected()); // NOI18N
-		// or:
-		// SomeSystemOption.getDefault().setSomeStringProperty(someTextField.getText());
-		GitModuleConfig.getDefault().setEmail(emailTextField.getText());
-		GitModuleConfig.getDefault().setUserName(userNameTextField.getText());
-		GitModuleConfig.getDefault().setExportFilename(exportFilenameTextField.getText());
-		GitModuleConfig.getDefault().setAnnotationFormat(annotationTextField.getText());
-		GitModuleConfig.getDefault().setBackupOnRevertModifications(backupOnRevertModifications.isSelected());
-		if (HtmlFormatter.isRevisionInAnnotationFormat(annotationTextField.getText()))
-			GitUtils.warningDialog(GitPanel.class,
-				&quot;MSG_STATUS_LABEL_WITH_REVSION_TITLE&quot;, &quot;MSG_STATUS_LABEL_WITH_REVSION_MSG&quot;);
-	}
-
-	boolean valid()
-	{
-		// TODO check whether form is consistent and complete
-		//return true;
-		String name = userNameTextField.getText();
-		String email = emailTextField.getText();
-		Boolean valid;
-
-		valid = GitModuleConfig.getDefault().isUserNameValid(name);
-		if (!valid)
-			return false;
-		valid = GitModuleConfig.getDefault().isEmailValid(email);
-		return valid;
-	}
+    private void nameChange()
+    {
+        controller.changed();
+    }
+
+    void load()
+    {
+        // TODO read settings and initialize GUI
+        // Example:
+        // someCheckBox.setSelected(Preferences.userNodeForPackage(GitPanel.class).getBoolean(&quot;someFlag&quot;, false)); // NOI18N
+        // or for org.openide.util with API spec. version &gt;= 7.4:
+        // someCheckBox.setSelected(NbPreferences.forModule(GitPanel.class).getBoolean(&quot;someFlag&quot;, false)); // NOI18N
+        // or:
+        // someTextField.setText(SomeSystemOption.getDefault().getSomeStringProperty());
+        emailTextField.setText(GitModuleConfig.getDefault().getEmail());
+        userNameTextField.setText(GitModuleConfig.getDefault().getUserName());
+        exportFilenameTextField.setText(GitModuleConfig.getDefault().getExportFilename());
+        annotationTextField.setText(GitModuleConfig.getDefault().getAnnotationFormat());
+        backupOnRevertModifications.setSelected(GitModuleConfig.getDefault().getBackupOnRevertModifications());
+    }
+
+    void store()
+    {
+        // TODO store modified settings
+        // Example:
+        // Preferences.userNodeForPackage(GitPanel.class).putBoolean(&quot;someFlag&quot;, someCheckBox.isSelected()); // NOI18N
+        // or for org.openide.util with API spec. version &gt;= 7.4:
+        // NbPreferences.forModule(GitPanel.class).putBoolean(&quot;someFlag&quot;, someCheckBox.isSelected()); // NOI18N
+        // or:
+        // SomeSystemOption.getDefault().setSomeStringProperty(someTextField.getText());
+        GitModuleConfig.getDefault().setEmail(emailTextField.getText());
+        GitModuleConfig.getDefault().setUserName(userNameTextField.getText());
+        GitModuleConfig.getDefault().setExportFilename(exportFilenameTextField.getText());
+        GitModuleConfig.getDefault().setAnnotationFormat(annotationTextField.getText());
+        GitModuleConfig.getDefault().setBackupOnRevertModifications(backupOnRevertModifications.isSelected());
+        if (HtmlFormatter.isRevisionInAnnotationFormat(annotationTextField.getText()))
+            GitUtils.warningDialog(GitPanel.class,
+                &quot;MSG_STATUS_LABEL_WITH_REVSION_TITLE&quot;, &quot;MSG_STATUS_LABEL_WITH_REVSION_MSG&quot;);
+    }
+
+    boolean valid()
+    {
+        // TODO check whether form is consistent and complete
+        //return true;
+        String name = userNameTextField.getText();
+        String email = emailTextField.getText();
+        Boolean valid;
+
+        valid = GitModuleConfig.getDefault().isUserNameValid(name);
+        if (!valid)
+            return false;
+        valid = GitModuleConfig.getDefault().isEmailValid(email);
+        return valid;
+    }
 
     // Variables declaration - do not modify//GEN-BEGIN:variables
     final javax.swing.JButton addButton = new javax.swing.JButton();</diff>
      <filename>src/org/nbgit/options/GitPanel.java</filename>
    </modified>
    <modified>
      <diff>@@ -54,7 +54,7 @@ public class LabelsPanel extends javax.swing.JPanel {
 
 
     }
-    
+
     /** This method is called from within the constructor to
      * initialize the form.
      * WARNING: Do NOT modify this code. The content of this method is
@@ -83,11 +83,11 @@ public class LabelsPanel extends javax.swing.JPanel {
             .add(jScrollPane1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 110, Short.MAX_VALUE)
         );
     }// &lt;/editor-fold&gt;//GEN-END:initComponents
-    
-    
+
+
     // Variables declaration - do not modify//GEN-BEGIN:variables
     private javax.swing.JScrollPane jScrollPane1;
     final javax.swing.JList labelsList = new javax.swing.JList();
     // End of variables declaration//GEN-END:variables
-    
+
 }
\ No newline at end of file</diff>
      <filename>src/org/nbgit/options/LabelsPanel.java</filename>
    </modified>
    <modified>
      <diff>@@ -57,12 +57,12 @@ public class PropertiesPanel extends javax.swing.JPanel implements PreferenceCha
     private static final Object EVENT_SETTINGS_CHANGED = new Object();
     private PropertiesTable propertiesTable;
     private ListenersSupport listenerSupport = new ListenersSupport(this);
-    
+
     /** Creates new form PropertiesPanel */
     public PropertiesPanel() {
         initComponents();
     }
-    
+
     public javax.swing.JTextArea getTxtAreaValue() {
         return txtAreaValue;
     }
@@ -82,11 +82,11 @@ public class PropertiesPanel extends javax.swing.JPanel implements PreferenceCha
     public void setPropertiesTable(PropertiesTable propertiesTable){
         this.propertiesTable = propertiesTable;
     }
-    
+
     @Override
     public void addNotify() {
         super.addNotify();
-        GitModuleConfig.getDefault().getPreferences().addPreferenceChangeListener(this);        
+        GitModuleConfig.getDefault().getPreferences().addPreferenceChangeListener(this);
         propertiesTable.getTableModel().addTableModelListener(this);
         listenerSupport.fireVersioningEvent(EVENT_SETTINGS_CHANGED);
         txtAreaValue.selectAll();
@@ -98,7 +98,7 @@ public class PropertiesPanel extends javax.swing.JPanel implements PreferenceCha
         GitModuleConfig.getDefault().getPreferences().removePreferenceChangeListener(this);
         super.removeNotify();
     }
-    
+
     public void preferenceChange(PreferenceChangeEvent evt) {
         if (evt.getKey().startsWith(GitModuleConfig.PROP_COMMIT_EXCLUSIONS)) {
             propertiesTable.dataChanged();
@@ -109,7 +109,7 @@ public class PropertiesPanel extends javax.swing.JPanel implements PreferenceCha
     public void tableChanged(TableModelEvent e) {
         listenerSupport.fireVersioningEvent(EVENT_SETTINGS_CHANGED);
     }
-    
+
     /** This method is called from within the constructor to
      * initialize the form.
      * WARNING: Do NOT modify this code. The content of this method is
@@ -205,8 +205,8 @@ public class PropertiesPanel extends javax.swing.JPanel implements PreferenceCha
         btnRemove.getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getMessage(PropertiesPanel.class, &quot;ACSD_btnRemove&quot;)); // NOI18N
         btnAdd.getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getMessage(PropertiesPanel.class, &quot;ACSD_btnAdd&quot;)); // NOI18N
     }// &lt;/editor-fold&gt;//GEN-END:initComponents
-    
-    
+
+
     // Variables declaration - do not modify//GEN-BEGIN:variables
     final javax.swing.JButton btnAdd = new javax.swing.JButton();
     final javax.swing.JButton btnRemove = new javax.swing.JButton();
@@ -218,6 +218,6 @@ public class PropertiesPanel extends javax.swing.JPanel implements PreferenceCha
     public javax.swing.JPanel propsPanel;
     final javax.swing.JTextArea txtAreaValue = new javax.swing.JTextArea();
     // End of variables declaration//GEN-END:variables
-    
+
 }
 </diff>
      <filename>src/org/nbgit/options/PropertiesPanel.java</filename>
    </modified>
    <modified>
      <diff>@@ -65,165 +65,165 @@ import org.openide.util.NbBundle;
  */
 public class PropertiesTable implements AncestorListener, TableModelListener {
 
-	static public final String[] PROPERTIES_COLUMNS = new String[]{PropertiesTableModel.COLUMN_NAME_NAME, PropertiesTableModel.COLUMN_NAME_VALUE};
-	private PropertiesTableModel tableModel;
-	private JTable table;
-	private TableSorter sorter;
-	private JComponent component;
-	private String[] columns;
-	private String[] sortByColumns;
-
-	/** Creates a new instance of PropertiesTable */
-	public PropertiesTable(JLabel label, String[] columns, String[] sortByColumns)
-	{
-		init(label, columns, null);
-		this.sortByColumns = sortByColumns;
-		setSortingStatus();
-	}
-
-	public PropertiesTable(JLabel label, String[] columns, TableSorter sorter)
-	{
-		init(label, columns, sorter);
-	}
-
-	private void init(JLabel label, String[] columns, TableSorter sorter)
-	{
-		tableModel = new PropertiesTableModel(columns);
-		tableModel.addTableModelListener(this);
-		if (sorter == null)
-			sorter = new TableSorter(tableModel);
-		this.sorter = sorter;
-		table = new JTable(this.sorter);
-		table.getTableHeader().setReorderingAllowed(false);
-		table.setDefaultRenderer(String.class, new PropertiesTableCellRenderer());
-		//table.setDefaultEditor(CommitOptions.class, new CommitOptionsCellEditor());
-		table.getTableHeader().setReorderingAllowed(true);
-		this.sorter.setTableHeader(table.getTableHeader());
-		table.setRowHeight(table.getRowHeight());
-		table.addAncestorListener(this);
-		component = new JScrollPane(table, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
-		component.setPreferredSize(new Dimension(340, 150));
-		table.getAccessibleContext().setAccessibleDescription(NbBundle.getMessage(PropertiesTable.class, &quot;ACSD_PropertiesTable&quot;)); // NOI18N        
-		label.setLabelFor(table);
-		setColumns(columns);
-	}
-
-	public void setColumns(String[] clmns)
-	{
-		if (Arrays.equals(columns, clmns))
-			return;
-		columns = clmns;
-		tableModel.setColumns(clmns);
-		setDefaultColumnSize();
-	}
-
-	public JTable getTable()
-	{
-		return table;
-	}
-
-	private void setDefaultColumnSize()
-	{
-		int width = table.getWidth();
-		TableColumnModel columnModel = table.getColumnModel();
-		if (columns == null || columnModel == null)
-			return;
-		if (columnModel.getColumnCount() != columns.length)
-			return;
-		for (int i = 0; i &lt; columns.length; i++) {
-			String col = columns[i];
-			sorter.setColumnComparator(i, null);
-			if (col.equals(PropertiesTableModel.COLUMN_NAME_NAME))
-				columnModel.getColumn(i).setPreferredWidth(width * 20 / 100);
-			else if (col.equals(PropertiesTableModel.COLUMN_NAME_VALUE))
-				columnModel.getColumn(i).setPreferredWidth(width * 40 / 100);
-		}
-	}
-
-	private void setSortingStatus()
-	{
-		for (int i = 0; i &lt; sortByColumns.length; i++) {
-			String sortByColumn = sortByColumns[i];
-			for (int j = 0; j &lt; columns.length; j++) {
-				String column = columns[j];
-				if (column.equals(sortByColumn)) {
-					sorter.setSortingStatus(j, column.equals(sortByColumn) ? TableSorter.ASCENDING : TableSorter.NOT_SORTED);
-					break;
-				}
-			}
-		}
-	}
-
-	TableModel getTableModel()
-	{
-		return tableModel;
-	}
-
-	void dataChanged()
-	{
-		int idx = table.getSelectedRow();
-		tableModel.fireTableDataChanged();
-		if (idx != -1)
-			table.getSelectionModel().addSelectionInterval(idx, idx);
-	}
-
-	public int getModelIndex(int viewIndex)
-	{
-		return sorter.modelIndex(viewIndex);
-	}
-
-	public int[] getSelectedItems()
-	{
-		return table.getSelectedRows();
-	}
-
-	public GitPropertiesNode[] getNodes()
-	{
-		return tableModel.getNodes();
-	}
-
-	public void setNodes(GitPropertiesNode[] nodes)
-	{
-		tableModel.setNodes(nodes);
-	}
-
-	public JComponent getComponent()
-	{
-		return component;
-	}
-
-	public void ancestorAdded(AncestorEvent arg0)
-	{
-		setDefaultColumnSize();
-	}
-
-	public void ancestorRemoved(AncestorEvent arg0)
-	{
-	}
-
-	public void ancestorMoved(AncestorEvent arg0)
-	{
-	}
-
-	public void tableChanged(TableModelEvent event)
-	{
-		table.repaint();
-	}
-
-	public class PropertiesTableCellRenderer extends DefaultTableCellRenderer {
-
-		@Override
-		public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int rowIndex, int columnIndex)
-		{
-			Component renderer = super.getTableCellRendererComponent(table, value, hasFocus, hasFocus, rowIndex, columnIndex);
-			if (renderer instanceof JComponent) {
-				String strValue = tableModel.getNode(sorter.modelIndex(rowIndex)).getValue();
-				((JComponent) renderer).setToolTipText(strValue);
-			}
-			setToolTipText(value.toString());
-			return renderer;
-		}
-
-	}
+    static public final String[] PROPERTIES_COLUMNS = new String[]{PropertiesTableModel.COLUMN_NAME_NAME, PropertiesTableModel.COLUMN_NAME_VALUE};
+    private PropertiesTableModel tableModel;
+    private JTable table;
+    private TableSorter sorter;
+    private JComponent component;
+    private String[] columns;
+    private String[] sortByColumns;
+
+    /** Creates a new instance of PropertiesTable */
+    public PropertiesTable(JLabel label, String[] columns, String[] sortByColumns)
+    {
+        init(label, columns, null);
+        this.sortByColumns = sortByColumns;
+        setSortingStatus();
+    }
+
+    public PropertiesTable(JLabel label, String[] columns, TableSorter sorter)
+    {
+        init(label, columns, sorter);
+    }
+
+    private void init(JLabel label, String[] columns, TableSorter sorter)
+    {
+        tableModel = new PropertiesTableModel(columns);
+        tableModel.addTableModelListener(this);
+        if (sorter == null)
+            sorter = new TableSorter(tableModel);
+        this.sorter = sorter;
+        table = new JTable(this.sorter);
+        table.getTableHeader().setReorderingAllowed(false);
+        table.setDefaultRenderer(String.class, new PropertiesTableCellRenderer());
+        //table.setDefaultEditor(CommitOptions.class, new CommitOptionsCellEditor());
+        table.getTableHeader().setReorderingAllowed(true);
+        this.sorter.setTableHeader(table.getTableHeader());
+        table.setRowHeight(table.getRowHeight());
+        table.addAncestorListener(this);
+        component = new JScrollPane(table, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
+        component.setPreferredSize(new Dimension(340, 150));
+        table.getAccessibleContext().setAccessibleDescription(NbBundle.getMessage(PropertiesTable.class, &quot;ACSD_PropertiesTable&quot;)); // NOI18N
+        label.setLabelFor(table);
+        setColumns(columns);
+    }
+
+    public void setColumns(String[] clmns)
+    {
+        if (Arrays.equals(columns, clmns))
+            return;
+        columns = clmns;
+        tableModel.setColumns(clmns);
+        setDefaultColumnSize();
+    }
+
+    public JTable getTable()
+    {
+        return table;
+    }
+
+    private void setDefaultColumnSize()
+    {
+        int width = table.getWidth();
+        TableColumnModel columnModel = table.getColumnModel();
+        if (columns == null || columnModel == null)
+            return;
+        if (columnModel.getColumnCount() != columns.length)
+            return;
+        for (int i = 0; i &lt; columns.length; i++) {
+            String col = columns[i];
+            sorter.setColumnComparator(i, null);
+            if (col.equals(PropertiesTableModel.COLUMN_NAME_NAME))
+                columnModel.getColumn(i).setPreferredWidth(width * 20 / 100);
+            else if (col.equals(PropertiesTableModel.COLUMN_NAME_VALUE))
+                columnModel.getColumn(i).setPreferredWidth(width * 40 / 100);
+        }
+    }
+
+    private void setSortingStatus()
+    {
+        for (int i = 0; i &lt; sortByColumns.length; i++) {
+            String sortByColumn = sortByColumns[i];
+            for (int j = 0; j &lt; columns.length; j++) {
+                String column = columns[j];
+                if (column.equals(sortByColumn)) {
+                    sorter.setSortingStatus(j, column.equals(sortByColumn) ? TableSorter.ASCENDING : TableSorter.NOT_SORTED);
+                    break;
+                }
+            }
+        }
+    }
+
+    TableModel getTableModel()
+    {
+        return tableModel;
+    }
+
+    void dataChanged()
+    {
+        int idx = table.getSelectedRow();
+        tableModel.fireTableDataChanged();
+        if (idx != -1)
+            table.getSelectionModel().addSelectionInterval(idx, idx);
+    }
+
+    public int getModelIndex(int viewIndex)
+    {
+        return sorter.modelIndex(viewIndex);
+    }
+
+    public int[] getSelectedItems()
+    {
+        return table.getSelectedRows();
+    }
+
+    public GitPropertiesNode[] getNodes()
+    {
+        return tableModel.getNodes();
+    }
+
+    public void setNodes(GitPropertiesNode[] nodes)
+    {
+        tableModel.setNodes(nodes);
+    }
+
+    public JComponent getComponent()
+    {
+        return component;
+    }
+
+    public void ancestorAdded(AncestorEvent arg0)
+    {
+        setDefaultColumnSize();
+    }
+
+    public void ancestorRemoved(AncestorEvent arg0)
+    {
+    }
+
+    public void ancestorMoved(AncestorEvent arg0)
+    {
+    }
+
+    public void tableChanged(TableModelEvent event)
+    {
+        table.repaint();
+    }
+
+    public class PropertiesTableCellRenderer extends DefaultTableCellRenderer {
+
+        @Override
+        public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int rowIndex, int columnIndex)
+        {
+            Component renderer = super.getTableCellRendererComponent(table, value, hasFocus, hasFocus, rowIndex, columnIndex);
+            if (renderer instanceof JComponent) {
+                String strValue = tableModel.getNode(sorter.modelIndex(rowIndex)).getValue();
+                ((JComponent) renderer).setToolTipText(strValue);
+            }
+            setToolTipText(value.toString());
+            return renderer;
+        }
+
+    }
 
 }
\ No newline at end of file</diff>
      <filename>src/org/nbgit/options/PropertiesTable.java</filename>
    </modified>
    <modified>
      <diff>@@ -54,21 +54,21 @@ import org.openide.util.NbBundle;
  * @author Peter Pis
  */
 public class PropertiesTableModel extends AbstractTableModel {
-    
+
     public static final String COLUMN_NAME_NAME = &quot;name&quot;; // NOI18N
     public static final String COLUMN_NAME_VALUE = &quot;value&quot;; // NOI18N
-    
+
     private GitPropertiesNode[] nodes;
     private String[] columns;
-    
-    private static final Map&lt;String, String[]&gt; columnLabels = new HashMap&lt;String, String[]&gt;(2); 
-    
+
+    private static final Map&lt;String, String[]&gt; columnLabels = new HashMap&lt;String, String[]&gt;(2);
+
     {
-        ResourceBundle loc = NbBundle.getBundle(PropertiesTableModel.class);    
+        ResourceBundle loc = NbBundle.getBundle(PropertiesTableModel.class);
         columnLabels.put(COLUMN_NAME_NAME, new String[] {loc.getString(&quot;CTL_PropertiesTable_Column_Name&quot;), loc.getString(&quot;CTL_PropertiesTable_Column_Name&quot;)}); // NOI18N
         columnLabels.put(COLUMN_NAME_VALUE, new String[] {loc.getString(&quot;CTL_PropertiesTable_Column_Value&quot;), loc.getString(&quot;CTL_PropertiesTable_Column_Value&quot;)}); // NOI18N
     }
-    
+
     /** Creates a new instance of PropertiesTableModel */
     public PropertiesTableModel(String[] clms) {
         if (Arrays.equals(columns, clms))
@@ -76,25 +76,25 @@ public class PropertiesTableModel extends AbstractTableModel {
         setColumns(clms);
         setNodes(new GitPropertiesNode[0]);
     }
-    
+
     public void setColumns(String[] clms) {
         this.columns = clms;
         fireTableStructureChanged();
     }
-    
+
     public void setNodes(GitPropertiesNode[] nodes) {
         this.nodes = nodes;
         fireTableDataChanged();
     }
-    
+
     public GitPropertiesNode[] getNodes() {
         return nodes;
     }
-    
+
     public GitPropertiesNode getNode(int row) {
         return nodes[row];
     }
-    
+
     public int getRowCount() {
         return nodes.length;
     }
@@ -103,7 +103,7 @@ public class PropertiesTableModel extends AbstractTableModel {
     public String getColumnName(int column) {
         return columnLabels.get(columns[column])[0];
     }
-    
+
     public int getColumnCount() {
         return columns.length;
     }
@@ -118,5 +118,5 @@ public class PropertiesTableModel extends AbstractTableModel {
         throw new IllegalArgumentException(&quot;The column index is out of index: &quot; + columnIndex); // NOI18N
     }
 
-    
+
 }
\ No newline at end of file</diff>
      <filename>src/org/nbgit/options/PropertiesTableModel.java</filename>
    </modified>
    <modified>
      <diff>@@ -50,4 +50,4 @@ made subject to such option by the copyright holder.
       severity=&quot;ok&quot;
       custom_sidebar_color=&quot;0x5890BE&quot;
       browseable=&quot;true&quot;
-/&gt;
\ No newline at end of file
+/&gt;</diff>
      <filename>src/org/nbgit/resources/annotation.xml</filename>
    </modified>
    <modified>
      <diff>@@ -50,7 +50,7 @@ made subject to such option by the copyright holder.
             &lt;/file&gt;
         &lt;/folder&gt;
     &lt;/folder&gt;
-    
+
     &lt;folder name=&quot;Menu&quot;&gt;
         &lt;folder name=&quot;Window&quot;&gt;
             &lt;folder name=&quot;Versioning&quot;&gt;
@@ -69,11 +69,11 @@ made subject to such option by the copyright holder.
             &lt;/file&gt;
         &lt;/folder&gt;
     &lt;/folder&gt;
-    
+
     &lt;folder name=&quot;Windows2&quot;&gt;
         &lt;folder name=&quot;Components&quot;&gt;
             &lt;file name=&quot;gitversioning.settings&quot; url=&quot;settings.xml&quot;/&gt;
-        &lt;/folder&gt;        
+        &lt;/folder&gt;
         &lt;folder name=&quot;Modes&quot;&gt;
             &lt;folder name=&quot;output&quot;&gt;
                 &lt;file name=&quot;gitversioning.wstcref&quot; url=&quot;wstcref.xml&quot;&gt;
@@ -82,15 +82,15 @@ made subject to such option by the copyright holder.
             &lt;/folder&gt;
         &lt;/folder&gt;
     &lt;/folder&gt;
-    
+
     &lt;folder name=&quot;Editors&quot;&gt;
-	    &lt;!--
+     &lt;!--
         &lt;folder name=&quot;SideBar&quot;&gt;
             &lt;file name=&quot;org-nbgit-ui-annotate-AnnotationBarManager.instance&quot;&gt;
                 &lt;attr name=&quot;position&quot; intvalue=&quot;2100&quot;/&gt;
             &lt;/file&gt;
         &lt;/folder&gt;
-	--&gt;
+ --&gt;
             &lt;!-- place in between line numbers sidebar and folding sidebar #57544 --&gt;
         &lt;folder name=&quot;AnnotationTypes&quot;&gt;
             &lt;file name=&quot;org-nbgit-Annotation.xml&quot; url=&quot;annotation.xml&quot;/&gt;
@@ -107,7 +107,7 @@ made subject to such option by the copyright holder.
             &lt;attr name=&quot;instanceClass&quot; stringvalue=&quot;org.nbgit.options.GitAdvancedOption&quot;/&gt;
         &lt;/file&gt;
     &lt;/folder&gt;
-    
+
     &lt;!--
        &lt;folder name=&quot;OptionsDialog&quot;&gt;
         &lt;folder name=&quot;Actions&quot;&gt;
@@ -145,7 +145,7 @@ made subject to such option by the copyright holder.
                 &lt;file name=&quot;ConflictResolvedAction.shadow&quot;&gt;
                     &lt;attr name=&quot;originalFile&quot; stringvalue=&quot;Actions/Subversion/org-netbeans-modules-subversion-ui-commit-ConflictResolvedAction.instance&quot;/&gt;
                 &lt;/file&gt;
-            
+
                 &lt;file name=&quot;CreateCopyAction.shadow&quot;&gt;
                     &lt;attr name=&quot;originalFile&quot; stringvalue=&quot;Actions/Subversion/org-netbeans-modules-subversion-ui-copy-CreateCopyAction.instance&quot;/&gt;
                 &lt;/file&gt;
@@ -171,8 +171,8 @@ made subject to such option by the copyright holder.
                     &lt;attr name=&quot;originalFile&quot; stringvalue=&quot;Actions/Subversion/org-netbeans-modules-subversion-ui-ignore-IgnoreAction.instance&quot;/&gt;
                 &lt;/file&gt;
                 &lt;file name=&quot;SvnPropertiesAction.shadow&quot;&gt;
-                    &lt;attr name=&quot;originalFile&quot; stringvalue=&quot;Actions/Subversion/org-netbeans-modules-subversion-ui-properties-SvnPropertiesAction.instance&quot;/&gt;                    
-                &lt;/file&gt;                 
+                    &lt;attr name=&quot;originalFile&quot; stringvalue=&quot;Actions/Subversion/org-netbeans-modules-subversion-ui-properties-SvnPropertiesAction.instance&quot;/&gt;
+                &lt;/file&gt;
             &lt;/folder&gt;
         &lt;/folder&gt;
     &lt;/folder&gt;</diff>
      <filename>src/org/nbgit/resources/layer.xml</filename>
    </modified>
    <modified>
      <diff>@@ -46,4 +46,4 @@ made subject to such option by the copyright holder.
     &lt;instanceof class=&quot;org.openide.windows.TopComponent&quot;/&gt;
     &lt;instanceof class=&quot;org.nbgit.ui.status.GitVersioningTopComponent&quot;/&gt;
     &lt;instance class=&quot;org.nbgit.ui.status.GitVersioningTopComponent&quot; method=&quot;getDefault&quot;/&gt;
-&lt;/settings&gt;
\ No newline at end of file
+&lt;/settings&gt;</diff>
      <filename>src/org/nbgit/resources/settings.xml</filename>
    </modified>
    <modified>
      <diff>@@ -49,4 +49,4 @@ made subject to such option by the copyright holder.
     &lt;module name=&quot;org.nbgit/1&quot;/&gt;
     &lt;tc-id id=&quot;gitversioning&quot; /&gt;
     &lt;state opened=&quot;false&quot; /&gt;
-&lt;/tc-ref&gt;
\ No newline at end of file
+&lt;/tc-ref&gt;</diff>
      <filename>src/org/nbgit/resources/wstcref.xml</filename>
    </modified>
    <modified>
      <diff>@@ -50,39 +50,39 @@ import org.openide.LifecycleManager;
 
 /**
  * Base for all context-sensitive Git actions.
- * 
+ *
  * @author Padraig O'Briain
  */
 public abstract class ContextAction extends AbstractAction {
-	
-	protected final VCSContext context;
 
-	public ContextAction(String name, VCSContext context)
-	{
-		this.context = context;
-		putValue(Action.NAME, name);
-	}
-	
-	@Override
-	public boolean isEnabled()
-	{
-		return GitUtils.getRootFile(context) != null;
-	}
+    protected final VCSContext context;
+
+    public ContextAction(String name, VCSContext context)
+    {
+        this.context = context;
+        putValue(Action.NAME, name);
+    }
+
+    @Override
+    public boolean isEnabled()
+    {
+        return GitUtils.getRootFile(context) != null;
+    }
 
-	/**
-	 * Synchronizes memory modificatios with disk and calls
-	 * {@link  #performContextAction}.
-	 */
-	public void actionPerformed(final ActionEvent event)
-	{
-		// TODO try to save files in invocation context only
-		// list somehow modified file in the context and save
-		// just them.
-		// The same (global save) logic is in CVS, no complaint
-		LifecycleManager.getDefault().saveAll();
-		performAction(event);
-	}
+    /**
+     * Synchronizes memory modificatios with disk and calls
+     * {@link  #performContextAction}.
+     */
+    public void actionPerformed(final ActionEvent event)
+    {
+        // TODO try to save files in invocation context only
+        // list somehow modified file in the context and save
+        // just them.
+        // The same (global save) logic is in CVS, no complaint
+        LifecycleManager.getDefault().saveAll();
+        performAction(event);
+    }
 
-	protected abstract void performAction(ActionEvent event);
+    protected abstract void performAction(ActionEvent event);
 
 }</diff>
      <filename>src/org/nbgit/ui/ContextAction.java</filename>
    </modified>
    <modified>
      <diff>@@ -56,55 +56,55 @@ import org.openide.filesystems.FileUtil;
  */
 public class GitFileNode {
 
-	private final File file;
+    private final File file;
 
-	public GitFileNode(File file)
-	{
-		this.file = file;
-	}
+    public GitFileNode(File file)
+    {
+        this.file = file;
+    }
 
-	public String getName()
-	{
-		return file.getName();
-	}
+    public String getName()
+    {
+        return file.getName();
+    }
 
-	public StatusInfo getInformation()
-	{
-		return Git.getInstance().getStatusCache().getStatus(file);
-	}
+    public StatusInfo getInformation()
+    {
+        return Git.getInstance().getStatusCache().getStatus(file);
+    }
 
-	public File getFile()
-	{
-		return file;
-	}
+    public File getFile()
+    {
+        return file;
+    }
 
-	@Override
-	public boolean equals(Object o)
-	{
-		if (this == o)
-			return true;
-		return o instanceof GitFileNode &amp;&amp; file.equals(((GitFileNode) o).file);
-	}
+    @Override
+    public boolean equals(Object o)
+    {
+        if (this == o)
+            return true;
+        return o instanceof GitFileNode &amp;&amp; file.equals(((GitFileNode) o).file);
+    }
 
-	@Override
-	public int hashCode()
-	{
-		return file.hashCode();
-	}
+    @Override
+    public int hashCode()
+    {
+        return file.hashCode();
+    }
 
-	public FileObject getFileObject()
-	{
-		return FileUtil.toFileObject(file);
-	}
+    public FileObject getFileObject()
+    {
+        return FileUtil.toFileObject(file);
+    }
 
-	public Object[] getLookupObjects()
-	{
-		List&lt;Object&gt; list = new ArrayList&lt;Object&gt;(2);
-		list.add(file);
-		FileObject fo = getFileObject();
-		if (fo != null)
-			list.add(fo);
-		return list.toArray(new Object[list.size()]);
-	}
+    public Object[] getLookupObjects()
+    {
+        List&lt;Object&gt; list = new ArrayList&lt;Object&gt;(2);
+        list.add(file);
+        FileObject fo = getFileObject();
+        if (fo != null)
+            list.add(fo);
+        return list.toArray(new Object[list.size()]);
+    }
 
 }
\ No newline at end of file</diff>
      <filename>src/org/nbgit/ui/GitFileNode.java</filename>
    </modified>
    <modified>
      <diff>@@ -84,326 +84,326 @@ import org.openide.util.RequestProcessor;
 /**
  * Commit action for Git:
  * git commit - commit the specified files or all outstanding changes
- * 
+ *
  * @author John Rice
  */
 public class CommitAction extends ContextAction {
 
-	static final String RECENT_COMMIT_MESSAGES = &quot;recentCommitMessage&quot;; // NOI18N
-
-	public CommitAction(String name, VCSContext context)
-	{
-		super(name, context);
-	}
-
-	@Override
-	public boolean isEnabled()
-	{
-		StatusCache cache = Git.getInstance().getStatusCache();
-		return cache.containsFileOfStatus(context, StatusInfo.STATUS_LOCAL_CHANGE);
-	}
-
-	public void performAction(ActionEvent e)
-	{
-		final File root = GitUtils.getRootFile(context);
-		if (root == null) {
-			OutputLogger logger = OutputLogger.getLogger(Git.GIT_OUTPUT_TAB_TITLE);
-			logger.outputInRed(NbBundle.getMessage(CommitAction.class, &quot;MSG_COMMIT_TITLE&quot;)); // NOI18N
-			logger.outputInRed(NbBundle.getMessage(CommitAction.class, &quot;MSG_COMMIT_TITLE_SEP&quot;)); // NOI18N
-			logger.outputInRed(
-				NbBundle.getMessage(CommitAction.class, &quot;MSG_COMMIT_NOT_SUPPORTED_INVIEW_INFO&quot;)); // NOI18N
-			logger.output(&quot;&quot;); // NOI18N
-			logger.closeLog();
-			JOptionPane.showMessageDialog(null,
-				NbBundle.getMessage(CommitAction.class, &quot;MSG_COMMIT_NOT_SUPPORTED_INVIEW&quot;),// NOI18N
-				NbBundle.getMessage(CommitAction.class, &quot;MSG_COMMIT_NOT_SUPPORTED_INVIEW_TITLE&quot;),// NOI18N
-				JOptionPane.INFORMATION_MESSAGE);
-			return;
-		}
-		String contentTitle = Utils.getContextDisplayName(context);
-
-		commit(contentTitle, context);
-	}
-
-	public static void commit(String contentTitle, final VCSContext ctx)
-	{
-		StatusCache cache = Git.getInstance().getStatusCache();
-		File[] roots = ctx.getRootFiles().toArray(new File[ctx.getRootFiles().size()]);
-		if (roots == null || roots.length == 0)
-			return;
-
-		final File repository = GitUtils.getRootFile(ctx);
-		if (repository == null)
-			return;
-		String projName = GitProjectUtils.getProjectName(repository);
-		if (projName == null) {
-			File projFile = GitUtils.getProjectFile(ctx);
-			projName = GitProjectUtils.getProjectName(projFile);
-		}
-		final String prjName = projName;
-
-		File[][] split = Utils.splitFlatOthers(roots);
-		List&lt;File&gt; fileList = new ArrayList&lt;File&gt;();
-		for (int c = 0; c &lt; split.length; c++) {
-			roots = split[c];
-			boolean recursive = c == 1;
-			if (recursive) {
-				File[] files = cache.listFiles(ctx, StatusInfo.STATUS_LOCAL_CHANGE);
-				for (int i = 0; i &lt; files.length; i++) {
-					for (int r = 0; r &lt; roots.length; r++) {
-						if (GitUtils.isParentOrEqual(roots[r], files[i]))
-							if (!fileList.contains(files[i]))
-								fileList.add(files[i]);
-					}
-				}
-			} else {
-				File[] files = GitUtils.flatten(roots, StatusInfo.STATUS_LOCAL_CHANGE);
-				for (int i = 0; i &lt; files.length; i++) {
-					if (!fileList.contains(files[i]))
-						fileList.add(files[i]);
-				}
-			}
-		}
-
-		if (fileList.size() == 0)
-			return;
-
-		// show commit dialog
-		final CommitPanel panel = new CommitPanel();
-		final CommitTable data = new CommitTable(panel.filesLabel, CommitTable.COMMIT_COLUMNS, new String[]{CommitTableModel.COLUMN_NAME_PATH});
-
-		panel.setCommitTable(data);
-
-		GitFileNode[] nodes;
-		ArrayList&lt;GitFileNode&gt; nodesList = new ArrayList&lt;GitFileNode&gt;(fileList.size());
-
-		for (Iterator&lt;File&gt; it = fileList.iterator(); it.hasNext();) {
-			File file = it.next();
-			GitFileNode node = new GitFileNode(file);
-			nodesList.add(node);
-		}
-		nodes = nodesList.toArray(new GitFileNode[fileList.size()]);
-		data.setNodes(nodes);
-
-		JComponent component = data.getComponent();
-		panel.filesPanel.setLayout(new BorderLayout());
-		panel.filesPanel.add(component, BorderLayout.CENTER);
-
-		DialogDescriptor dd = new DialogDescriptor(panel, org.openide.util.NbBundle.getMessage(CommitAction.class, &quot;CTL_CommitDialog_Title&quot;, contentTitle)); // NOI18N
-		dd.setModal(true);
-		final JButton commitButton = new JButton();
-		org.openide.awt.Mnemonics.setLocalizedText(commitButton, org.openide.util.NbBundle.getMessage(CommitAction.class, &quot;CTL_Commit_Action_Commit&quot;));
-		commitButton.getAccessibleContext().setAccessibleName(org.openide.util.NbBundle.getMessage(CommitAction.class, &quot;ACSN_Commit_Action_Commit&quot;));
-		commitButton.getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getMessage(CommitAction.class, &quot;ACSD_Commit_Action_Commit&quot;));
-		final JButton cancelButton = new JButton(org.openide.util.NbBundle.getMessage(CommitAction.class, &quot;CTL_Commit_Action_Cancel&quot;)); // NOI18N
-		org.openide.awt.Mnemonics.setLocalizedText(cancelButton, org.openide.util.NbBundle.getMessage(CommitAction.class, &quot;CTL_Commit_Action_Cancel&quot;));
-		cancelButton.getAccessibleContext().setAccessibleName(org.openide.util.NbBundle.getMessage(CommitAction.class, &quot;ACSN_Commit_Action_Cancel&quot;));
-		cancelButton.getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getMessage(CommitAction.class, &quot;ACSD_Commit_Action_Cancel&quot;));
-
-		commitButton.setEnabled(false);
-		dd.setOptions(new Object[]{commitButton, cancelButton});
-		dd.setHelpCtx(new HelpCtx(CommitAction.class));
-		panel.addVersioningListener(new VersioningListener() {
-
-			public void versioningEvent(VersioningEvent event)
-			{
-				refreshCommitDialog(panel, data, commitButton);
-			}
-
-		});
-		data.getTableModel().addTableModelListener(new TableModelListener() {
-
-			public void tableChanged(TableModelEvent e)
-			{
-				refreshCommitDialog(panel, data, commitButton);
-			}
-
-		});
-		commitButton.setEnabled(containsCommitable(data));
-
-		panel.putClientProperty(&quot;contentTitle&quot;, contentTitle);  // NOI18N
-		panel.putClientProperty(&quot;DialogDescriptor&quot;, dd); // NOI18N
-		final Dialog dialog = DialogDisplayer.getDefault().createDialog(dd);
-
-		dialog.addWindowListener(new DialogBoundsPreserver(GitModuleConfig.getDefault().getPreferences(), &quot;git.commit.dialog&quot;)); // NOI18N
-		dialog.pack();
-		dialog.setVisible(true);
-
-		if (dd.getValue() == commitButton) {
-
-			final Map&lt;GitFileNode, CommitOptions&gt; commitFiles = data.getCommitFiles();
-			final String message = panel.messageTextArea.getText();
-			org.netbeans.modules.versioning.util.Utils.insert(GitModuleConfig.getDefault().getPreferences(), RECENT_COMMIT_MESSAGES, message, 20);
-			RequestProcessor rp = Git.getInstance().getRequestProcessor(repository.getAbsolutePath());
-			GitProgressSupport support = new GitProgressSupport() {
-
-				public void perform()
-				{
-					OutputLogger logger = getLogger();
-					performCommit(message, commitFiles, ctx, this, prjName, logger);
-				}
-
-			};
-			support.start(rp, repository.getAbsolutePath(), org.openide.util.NbBundle.getMessage(CommitAction.class, &quot;LBL_Commit_Progress&quot;)); // NOI18N
-		}
-	}
-
-	private static boolean containsCommitable(CommitTable data)
-	{
-		Map&lt;GitFileNode, CommitOptions&gt; map = data.getCommitFiles();
-		for (CommitOptions co : map.values()) {
-			if (co != CommitOptions.EXCLUDE)
-				return true;
-		}
-		return false;
-	}
-
-	/**
-	 * User changed a commit action.
-	 *
-	 * @param panel
-	 * @param commit
-	 */
-	private static void refreshCommitDialog(CommitPanel panel, CommitTable table, JButton commit)
-	{
-		ResourceBundle loc = NbBundle.getBundle(CommitAction.class);
-		Map&lt;GitFileNode, CommitOptions&gt; files = table.getCommitFiles();
-		Set&lt;String&gt; stickyTags = new HashSet&lt;String&gt;();
-		boolean conflicts = false;
-
-		boolean enabled = commit.isEnabled();
-
-		for (GitFileNode fileNode : files.keySet()) {
-
-			CommitOptions options = files.get(fileNode);
-			if (options == CommitOptions.EXCLUDE)
-				continue;
-			//stickyTags.add(GitUtils.getCopy(fileNode.getFile()));
-			int status = fileNode.getInformation().getStatus();
-			if ((status &amp; StatusInfo.STATUS_REMOTE_CHANGE) != 0 || status == StatusInfo.STATUS_VERSIONED_CONFLICT) {
-				enabled = false;
-				String msg = (status == StatusInfo.STATUS_VERSIONED_CONFLICT) ? loc.getString(&quot;MSG_CommitForm_ErrorConflicts&quot;) : // NOI18N
-					loc.getString(&quot;MSG_CommitForm_ErrorRemoteChanges&quot;); // NOI18N
-				panel.setErrorLabel(&quot;&lt;html&gt;&lt;font color=\&quot;#002080\&quot;&gt;&quot; + msg + &quot;&lt;/font&gt;&lt;/html&gt;&quot;);  // NOI18N
-				conflicts = true;
-			}
-		//stickyTags.add(GitUtils.getCopy(fileNode.getFile()));
-
-		}
-
-		if (stickyTags.size() &gt; 1)
-			table.setColumns(new String[]{CommitTableModel.COLUMN_NAME_NAME, CommitTableModel.COLUMN_NAME_BRANCH, CommitTableModel.COLUMN_NAME_STATUS,
-					CommitTableModel.COLUMN_NAME_ACTION, CommitTableModel.COLUMN_NAME_PATH
-				});
-		else
-			table.setColumns(new String[]{CommitTableModel.COLUMN_NAME_NAME, CommitTableModel.COLUMN_NAME_STATUS,
-					CommitTableModel.COLUMN_NAME_ACTION, CommitTableModel.COLUMN_NAME_PATH
-				});
-
-		String contentTitle = (String) panel.getClientProperty(&quot;contentTitle&quot;); // NOI18N
+    static final String RECENT_COMMIT_MESSAGES = &quot;recentCommitMessage&quot;; // NOI18N
+
+    public CommitAction(String name, VCSContext context)
+    {
+        super(name, context);
+    }
+
+    @Override
+    public boolean isEnabled()
+    {
+        StatusCache cache = Git.getInstance().getStatusCache();
+        return cache.containsFileOfStatus(context, StatusInfo.STATUS_LOCAL_CHANGE);
+    }
+
+    public void performAction(ActionEvent e)
+    {
+        final File root = GitUtils.getRootFile(context);
+        if (root == null) {
+            OutputLogger logger = OutputLogger.getLogger(Git.GIT_OUTPUT_TAB_TITLE);
+            logger.outputInRed(NbBundle.getMessage(CommitAction.class, &quot;MSG_COMMIT_TITLE&quot;)); // NOI18N
+            logger.outputInRed(NbBundle.getMessage(CommitAction.class, &quot;MSG_COMMIT_TITLE_SEP&quot;)); // NOI18N
+            logger.outputInRed(
+                NbBundle.getMessage(CommitAction.class, &quot;MSG_COMMIT_NOT_SUPPORTED_INVIEW_INFO&quot;)); // NOI18N
+            logger.output(&quot;&quot;); // NOI18N
+            logger.closeLog();
+            JOptionPane.showMessageDialog(null,
+                NbBundle.getMessage(CommitAction.class, &quot;MSG_COMMIT_NOT_SUPPORTED_INVIEW&quot;),// NOI18N
+                NbBundle.getMessage(CommitAction.class, &quot;MSG_COMMIT_NOT_SUPPORTED_INVIEW_TITLE&quot;),// NOI18N
+                JOptionPane.INFORMATION_MESSAGE);
+            return;
+        }
+        String contentTitle = Utils.getContextDisplayName(context);
+
+        commit(contentTitle, context);
+    }
+
+    public static void commit(String contentTitle, final VCSContext ctx)
+    {
+        StatusCache cache = Git.getInstance().getStatusCache();
+        File[] roots = ctx.getRootFiles().toArray(new File[ctx.getRootFiles().size()]);
+        if (roots == null || roots.length == 0)
+            return;
+
+        final File repository = GitUtils.getRootFile(ctx);
+        if (repository == null)
+            return;
+        String projName = GitProjectUtils.getProjectName(repository);
+        if (projName == null) {
+            File projFile = GitUtils.getProjectFile(ctx);
+            projName = GitProjectUtils.getProjectName(projFile);
+        }
+        final String prjName = projName;
+
+        File[][] split = Utils.splitFlatOthers(roots);
+        List&lt;File&gt; fileList = new ArrayList&lt;File&gt;();
+        for (int c = 0; c &lt; split.length; c++) {
+            roots = split[c];
+            boolean recursive = c == 1;
+            if (recursive) {
+                File[] files = cache.listFiles(ctx, StatusInfo.STATUS_LOCAL_CHANGE);
+                for (int i = 0; i &lt; files.length; i++) {
+                    for (int r = 0; r &lt; roots.length; r++) {
+                        if (GitUtils.isParentOrEqual(roots[r], files[i]))
+                            if (!fileList.contains(files[i]))
+                                fileList.add(files[i]);
+                    }
+                }
+            } else {
+                File[] files = GitUtils.flatten(roots, StatusInfo.STATUS_LOCAL_CHANGE);
+                for (int i = 0; i &lt; files.length; i++) {
+                    if (!fileList.contains(files[i]))
+                        fileList.add(files[i]);
+                }
+            }
+        }
+
+        if (fileList.size() == 0)
+            return;
+
+        // show commit dialog
+        final CommitPanel panel = new CommitPanel();
+        final CommitTable data = new CommitTable(panel.filesLabel, CommitTable.COMMIT_COLUMNS, new String[]{CommitTableModel.COLUMN_NAME_PATH});
+
+        panel.setCommitTable(data);
+
+        GitFileNode[] nodes;
+        ArrayList&lt;GitFileNode&gt; nodesList = new ArrayList&lt;GitFileNode&gt;(fileList.size());
+
+        for (Iterator&lt;File&gt; it = fileList.iterator(); it.hasNext();) {
+            File file = it.next();
+            GitFileNode node = new GitFileNode(file);
+            nodesList.add(node);
+        }
+        nodes = nodesList.toArray(new GitFileNode[fileList.size()]);
+        data.setNodes(nodes);
+
+        JComponent component = data.getComponent();
+        panel.filesPanel.setLayout(new BorderLayout());
+        panel.filesPanel.add(component, BorderLayout.CENTER);
+
+        DialogDescriptor dd = new DialogDescriptor(panel, org.openide.util.NbBundle.getMessage(CommitAction.class, &quot;CTL_CommitDialog_Title&quot;, contentTitle)); // NOI18N
+        dd.setModal(true);
+        final JButton commitButton = new JButton();
+        org.openide.awt.Mnemonics.setLocalizedText(commitButton, org.openide.util.NbBundle.getMessage(CommitAction.class, &quot;CTL_Commit_Action_Commit&quot;));
+        commitButton.getAccessibleContext().setAccessibleName(org.openide.util.NbBundle.getMessage(CommitAction.class, &quot;ACSN_Commit_Action_Commit&quot;));
+        commitButton.getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getMessage(CommitAction.class, &quot;ACSD_Commit_Action_Commit&quot;));
+        final JButton cancelButton = new JButton(org.openide.util.NbBundle.getMessage(CommitAction.class, &quot;CTL_Commit_Action_Cancel&quot;)); // NOI18N
+        org.openide.awt.Mnemonics.setLocalizedText(cancelButton, org.openide.util.NbBundle.getMessage(CommitAction.class, &quot;CTL_Commit_Action_Cancel&quot;));
+        cancelButton.getAccessibleContext().setAccessibleName(org.openide.util.NbBundle.getMessage(CommitAction.class, &quot;ACSN_Commit_Action_Cancel&quot;));
+        cancelButton.getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getMessage(CommitAction.class, &quot;ACSD_Commit_Action_Cancel&quot;));
+
+        commitButton.setEnabled(false);
+        dd.setOptions(new Object[]{commitButton, cancelButton});
+        dd.setHelpCtx(new HelpCtx(CommitAction.class));
+        panel.addVersioningListener(new VersioningListener() {
+
+            public void versioningEvent(VersioningEvent event)
+            {
+                refreshCommitDialog(panel, data, commitButton);
+            }
+
+        });
+        data.getTableModel().addTableModelListener(new TableModelListener() {
+
+            public void tableChanged(TableModelEvent e)
+            {
+                refreshCommitDialog(panel, data, commitButton);
+            }
+
+        });
+        commitButton.setEnabled(containsCommitable(data));
+
+        panel.putClientProperty(&quot;contentTitle&quot;, contentTitle);  // NOI18N
+        panel.putClientProperty(&quot;DialogDescriptor&quot;, dd); // NOI18N
+        final Dialog dialog = DialogDisplayer.getDefault().createDialog(dd);
+
+        dialog.addWindowListener(new DialogBoundsPreserver(GitModuleConfig.getDefault().getPreferences(), &quot;git.commit.dialog&quot;)); // NOI18N
+        dialog.pack();
+        dialog.setVisible(true);
+
+        if (dd.getValue() == commitButton) {
+
+            final Map&lt;GitFileNode, CommitOptions&gt; commitFiles = data.getCommitFiles();
+            final String message = panel.messageTextArea.getText();
+            org.netbeans.modules.versioning.util.Utils.insert(GitModuleConfig.getDefault().getPreferences(), RECENT_COMMIT_MESSAGES, message, 20);
+            RequestProcessor rp = Git.getInstance().getRequestProcessor(repository.getAbsolutePath());
+            GitProgressSupport support = new GitProgressSupport() {
+
+                public void perform()
+                {
+                    OutputLogger logger = getLogger();
+                    performCommit(message, commitFiles, ctx, this, prjName, logger);
+                }
+
+            };
+            support.start(rp, repository.getAbsolutePath(), org.openide.util.NbBundle.getMessage(CommitAction.class, &quot;LBL_Commit_Progress&quot;)); // NOI18N
+        }
+    }
+
+    private static boolean containsCommitable(CommitTable data)
+    {
+        Map&lt;GitFileNode, CommitOptions&gt; map = data.getCommitFiles();
+        for (CommitOptions co : map.values()) {
+            if (co != CommitOptions.EXCLUDE)
+                return true;
+        }
+        return false;
+    }
+
+    /**
+     * User changed a commit action.
+     *
+     * @param panel
+     * @param commit
+     */
+    private static void refreshCommitDialog(CommitPanel panel, CommitTable table, JButton commit)
+    {
+        ResourceBundle loc = NbBundle.getBundle(CommitAction.class);
+        Map&lt;GitFileNode, CommitOptions&gt; files = table.getCommitFiles();
+        Set&lt;String&gt; stickyTags = new HashSet&lt;String&gt;();
+        boolean conflicts = false;
+
+        boolean enabled = commit.isEnabled();
+
+        for (GitFileNode fileNode : files.keySet()) {
+
+            CommitOptions options = files.get(fileNode);
+            if (options == CommitOptions.EXCLUDE)
+                continue;
+            //stickyTags.add(GitUtils.getCopy(fileNode.getFile()));
+            int status = fileNode.getInformation().getStatus();
+            if ((status &amp; StatusInfo.STATUS_REMOTE_CHANGE) != 0 || status == StatusInfo.STATUS_VERSIONED_CONFLICT) {
+                enabled = false;
+                String msg = (status == StatusInfo.STATUS_VERSIONED_CONFLICT) ? loc.getString(&quot;MSG_CommitForm_ErrorConflicts&quot;) : // NOI18N
+                    loc.getString(&quot;MSG_CommitForm_ErrorRemoteChanges&quot;); // NOI18N
+                panel.setErrorLabel(&quot;&lt;html&gt;&lt;font color=\&quot;#002080\&quot;&gt;&quot; + msg + &quot;&lt;/font&gt;&lt;/html&gt;&quot;);  // NOI18N
+                conflicts = true;
+            }
+        //stickyTags.add(GitUtils.getCopy(fileNode.getFile()));
+
+        }
+
+        if (stickyTags.size() &gt; 1)
+            table.setColumns(new String[]{CommitTableModel.COLUMN_NAME_NAME, CommitTableModel.COLUMN_NAME_BRANCH, CommitTableModel.COLUMN_NAME_STATUS,
+                    CommitTableModel.COLUMN_NAME_ACTION, CommitTableModel.COLUMN_NAME_PATH
+                });
+        else
+            table.setColumns(new String[]{CommitTableModel.COLUMN_NAME_NAME, CommitTableModel.COLUMN_NAME_STATUS,
+                    CommitTableModel.COLUMN_NAME_ACTION, CommitTableModel.COLUMN_NAME_PATH
+                });
+
+        String contentTitle = (String) panel.getClientProperty(&quot;contentTitle&quot;); // NOI18N
 // NOI18N
-		DialogDescriptor dd = (DialogDescriptor) panel.getClientProperty(&quot;DialogDescriptor&quot;); // NOI18N
-		String errorLabel;
-		if (stickyTags.size() &lt;= 1) {
-			String stickyTag = stickyTags.size() == 0 ? null : stickyTags.iterator().next();
-			if (stickyTag == null) {
-				dd.setTitle(MessageFormat.format(loc.getString(&quot;CTL_CommitDialog_Title&quot;), new Object[]{contentTitle})); // NOI18N
-				errorLabel = &quot;&quot;; // NOI18N
-			} else {
-				dd.setTitle(MessageFormat.format(loc.getString(&quot;CTL_CommitDialog_Title_Branch&quot;), new Object[]{contentTitle, stickyTag})); // NOI18N
-				String msg = MessageFormat.format(loc.getString(&quot;MSG_CommitForm_InfoBranch&quot;), new Object[]{stickyTag}); // NOI18N
-				errorLabel = &quot;&lt;html&gt;&lt;font color=\&quot;#002080\&quot;&gt;&quot; + msg + &quot;&lt;/font&gt;&lt;/html&gt;&quot;; // NOI18N
-			}
-		} else {
-			dd.setTitle(MessageFormat.format(loc.getString(&quot;CTL_CommitDialog_Title_Branches&quot;), new Object[]{contentTitle})); // NOI18N
-			String msg = loc.getString(&quot;MSG_CommitForm_ErrorMultipleBranches&quot;); // NOI18N
-			errorLabel = &quot;&lt;html&gt;&lt;font color=\&quot;#CC0000\&quot;&gt;&quot; + msg + &quot;&lt;/font&gt;&lt;/html&gt;&quot;; // NOI18N
-		}
-		if (!conflicts) {
-			panel.setErrorLabel(errorLabel);
-			enabled = true;
-		}
-		commit.setEnabled(enabled &amp;&amp; containsCommitable(table));
-	}
-
-	private static void performCommit(String message, Map&lt;GitFileNode, CommitOptions&gt; commitFiles,
-		VCSContext ctx, GitProgressSupport support, String prjName, OutputLogger logger)
-	{
-		StatusCache cache = Git.getInstance().getStatusCache();
-		final File repository = GitUtils.getRootFile(ctx);
-		List&lt;File&gt; addCandidates = new ArrayList&lt;File&gt;();
-		List&lt;File&gt; deleteCandidates = new ArrayList&lt;File&gt;();
-		List&lt;File&gt; commitCandidates = new ArrayList&lt;File&gt;();
-		Iterator&lt;GitFileNode&gt; it = commitFiles.keySet().iterator();
-
-		List&lt;String&gt; excPaths = new ArrayList&lt;String&gt;();
-		List&lt;String&gt; incPaths = new ArrayList&lt;String&gt;();
-		while (it.hasNext()) {
-			if (support.isCanceled())
-				return;
-			GitFileNode node = it.next();
-			CommitOptions option = commitFiles.get(node);
-			if (option != CommitOptions.EXCLUDE) {
-				int status = cache.getStatus(node.getFile()).getStatus();
-				if ((status &amp; StatusInfo.STATUS_NOTVERSIONED_NEWLOCALLY) != 0)
-					addCandidates.add(node.getFile());
-				else if ((status &amp; StatusInfo.STATUS_VERSIONED_DELETEDLOCALLY) != 0)
-					deleteCandidates.add(node.getFile());
-				commitCandidates.add(node.getFile());
-				incPaths.add(node.getFile().getAbsolutePath());
-			} else
-				excPaths.add(node.getFile().getAbsolutePath());
-		}
-		if (support.isCanceled())
-			return;
-
-		if (!excPaths.isEmpty())
-			GitModuleConfig.getDefault().addExclusionPaths(excPaths);
-		if (!incPaths.isEmpty())
-			GitModuleConfig.getDefault().removeExclusionPaths(incPaths);
-
-		try {
-			logger.outputInRed(
-				NbBundle.getMessage(CommitAction.class,
-				&quot;MSG_COMMIT_TITLE&quot;)); // NOI18N
-			logger.outputInRed(
-				NbBundle.getMessage(CommitAction.class,
-				&quot;MSG_COMMIT_TITLE_SEP&quot;)); // NOI18N
-			logger.output(message); // NOI18N
-			if (addCandidates.size() &gt; 0) {
-				GitCommand.doAdd(repository, addCandidates, logger);
-				for (File f : addCandidates) {
-					logger.output(&quot;git add &quot; + f.getName()); //NOI18N
-				}
-			}
-			if (deleteCandidates.size() &gt; 0) {
-				GitCommand.doRemove(repository, deleteCandidates, logger);
-				for (File f : deleteCandidates) {
-					logger.output(&quot;git delete &quot; + f.getName()); //NOI18N
-				}
-			}
-
-			GitCommand.doCommit(repository, commitCandidates, message, logger);
-
-			if (commitCandidates.size() == 1)
-				logger.output(
-					NbBundle.getMessage(CommitAction.class,
-					&quot;MSG_COMMIT_INIT_SEP_ONE&quot;, commitCandidates.size(), prjName));
-			else
-				logger.output(
-					NbBundle.getMessage(CommitAction.class,
-					&quot;MSG_COMMIT_INIT_SEP&quot;, commitCandidates.size(), prjName));
-			for (File f : commitCandidates) {
-				logger.output(&quot;\t&quot; + f.getAbsolutePath()); // NOI18N
-			}
-		} catch (Exception ex) {
-			NotifyDescriptor.Exception e = new NotifyDescriptor.Exception(ex);
-			DialogDisplayer.getDefault().notifyLater(e);
-		} finally {
-			cache.refreshCached(ctx);
-			logger.outputInRed(NbBundle.getMessage(CommitAction.class, &quot;MSG_COMMIT_DONE&quot;)); // NOI18N
-			logger.output(&quot;&quot;); // NOI18N
-		}
-	}
+        DialogDescriptor dd = (DialogDescriptor) panel.getClientProperty(&quot;DialogDescriptor&quot;); // NOI18N
+        String errorLabel;
+        if (stickyTags.size() &lt;= 1) {
+            String stickyTag = stickyTags.size() == 0 ? null : stickyTags.iterator().next();
+            if (stickyTag == null) {
+                dd.setTitle(MessageFormat.format(loc.getString(&quot;CTL_CommitDialog_Title&quot;), new Object[]{contentTitle})); // NOI18N
+                errorLabel = &quot;&quot;; // NOI18N
+            } else {
+                dd.setTitle(MessageFormat.format(loc.getString(&quot;CTL_CommitDialog_Title_Branch&quot;), new Object[]{contentTitle, stickyTag})); // NOI18N
+                String msg = MessageFormat.format(loc.getString(&quot;MSG_CommitForm_InfoBranch&quot;), new Object[]{stickyTag}); // NOI18N
+                errorLabel = &quot;&lt;html&gt;&lt;font color=\&quot;#002080\&quot;&gt;&quot; + msg + &quot;&lt;/font&gt;&lt;/html&gt;&quot;; // NOI18N
+            }
+        } else {
+            dd.setTitle(MessageFormat.format(loc.getString(&quot;CTL_CommitDialog_Title_Branches&quot;), new Object[]{contentTitle})); // NOI18N
+            String msg = loc.getString(&quot;MSG_CommitForm_ErrorMultipleBranches&quot;); // NOI18N
+            errorLabel = &quot;&lt;html&gt;&lt;font color=\&quot;#CC0000\&quot;&gt;&quot; + msg + &quot;&lt;/font&gt;&lt;/html&gt;&quot;; // NOI18N
+        }
+        if (!conflicts) {
+            panel.setErrorLabel(errorLabel);
+            enabled = true;
+        }
+        commit.setEnabled(enabled &amp;&amp; containsCommitable(table));
+    }
+
+    private static void performCommit(String message, Map&lt;GitFileNode, CommitOptions&gt; commitFiles,
+        VCSContext ctx, GitProgressSupport support, String prjName, OutputLogger logger)
+    {
+        StatusCache cache = Git.getInstance().getStatusCache();
+        final File repository = GitUtils.getRootFile(ctx);
+        List&lt;File&gt; addCandidates = new ArrayList&lt;File&gt;();
+        List&lt;File&gt; deleteCandidates = new ArrayList&lt;File&gt;();
+        List&lt;File&gt; commitCandidates = new ArrayList&lt;File&gt;();
+        Iterator&lt;GitFileNode&gt; it = commitFiles.keySet().iterator();
+
+        List&lt;String&gt; excPaths = new ArrayList&lt;String&gt;();
+        List&lt;String&gt; incPaths = new ArrayList&lt;String&gt;();
+        while (it.hasNext()) {
+            if (support.isCanceled())
+                return;
+            GitFileNode node = it.next();
+            CommitOptions option = commitFiles.get(node);
+            if (option != CommitOptions.EXCLUDE) {
+                int status = cache.getStatus(node.getFile()).getStatus();
+                if ((status &amp; StatusInfo.STATUS_NOTVERSIONED_NEWLOCALLY) != 0)
+                    addCandidates.add(node.getFile());
+                else if ((status &amp; StatusInfo.STATUS_VERSIONED_DELETEDLOCALLY) != 0)
+                    deleteCandidates.add(node.getFile());
+                commitCandidates.add(node.getFile());
+                incPaths.add(node.getFile().getAbsolutePath());
+            } else
+                excPaths.add(node.getFile().getAbsolutePath());
+        }
+        if (support.isCanceled())
+            return;
+
+        if (!excPaths.isEmpty())
+            GitModuleConfig.getDefault().addExclusionPaths(excPaths);
+        if (!incPaths.isEmpty())
+            GitModuleConfig.getDefault().removeExclusionPaths(incPaths);
+
+        try {
+            logger.outputInRed(
+                NbBundle.getMessage(CommitAction.class,
+                &quot;MSG_COMMIT_TITLE&quot;)); // NOI18N
+            logger.outputInRed(
+                NbBundle.getMessage(CommitAction.class,
+                &quot;MSG_COMMIT_TITLE_SEP&quot;)); // NOI18N
+            logger.output(message); // NOI18N
+            if (addCandidates.size() &gt; 0) {
+                GitCommand.doAdd(repository, addCandidates, logger);
+                for (File f : addCandidates) {
+                    logger.output(&quot;git add &quot; + f.getName()); //NOI18N
+                }
+            }
+            if (deleteCandidates.size() &gt; 0) {
+                GitCommand.doRemove(repository, deleteCandidates, logger);
+                for (File f : deleteCandidates) {
+                    logger.output(&quot;git delete &quot; + f.getName()); //NOI18N
+                }
+            }
+
+            GitCommand.doCommit(repository, commitCandidates, message, logger);
+
+            if (commitCandidates.size() == 1)
+                logger.output(
+                    NbBundle.getMessage(CommitAction.class,
+                    &quot;MSG_COMMIT_INIT_SEP_ONE&quot;, commitCandidates.size(), prjName));
+            else
+                logger.output(
+                    NbBundle.getMessage(CommitAction.class,
+                    &quot;MSG_COMMIT_INIT_SEP&quot;, commitCandidates.size(), prjName));
+            for (File f : commitCandidates) {
+                logger.output(&quot;\t&quot; + f.getAbsolutePath()); // NOI18N
+            }
+        } catch (Exception ex) {
+            NotifyDescriptor.Exception e = new NotifyDescriptor.Exception(ex);
+            DialogDisplayer.getDefault().notifyLater(e);
+        } finally {
+            cache.refreshCached(ctx);
+            logger.outputInRed(NbBundle.getMessage(CommitAction.class, &quot;MSG_COMMIT_DONE&quot;)); // NOI18N
+            logger.output(&quot;&quot;); // NOI18N
+        }
+    }
 
 }</diff>
      <filename>src/org/nbgit/ui/commit/CommitAction.java</filename>
    </modified>
    <modified>
      <diff>@@ -51,7 +51,7 @@ abstract class CommitOptions {
     public static final CommitOptions COMMIT = new Commit(&quot;CTL_CommitOption_Commit&quot;); // NOI18N
     public static final CommitOptions COMMIT_REMOVE = new Commit(&quot;CTL_CommitOption_CommitRemove&quot;); // NOI18N
     public static final CommitOptions EXCLUDE = new Commit(&quot;CTL_CommitOption_Exclude&quot;); // NOI18N
-    
+
     private final String bundleKey;
 
     public CommitOptions(String bundleKey) {
@@ -62,16 +62,16 @@ abstract class CommitOptions {
     public String toString() {
         return NbBundle.getMessage(CommitOptions.class, bundleKey);
     }
-    
+
     static class Add extends CommitOptions {
-        
+
         public Add(String bundleKey) {
             super(bundleKey);
         }
     }
-    
+
     static class Commit extends CommitOptions {
-        
+
         public Commit(String bundleKey) {
             super(bundleKey);
         }</diff>
      <filename>src/org/nbgit/ui/commit/CommitOptions.java</filename>
    </modified>
    <modified>
      <diff>@@ -33,11 +33,11 @@
           &lt;Group type=&quot;102&quot; alignment=&quot;1&quot; attributes=&quot;0&quot;&gt;
               &lt;EmptySpace max=&quot;-2&quot; attributes=&quot;0&quot;/&gt;
               &lt;Group type=&quot;103&quot; groupAlignment=&quot;1&quot; attributes=&quot;0&quot;&gt;
-                  &lt;Component id=&quot;filesPanel&quot; alignment=&quot;0&quot; pref=&quot;626&quot; max=&quot;32767&quot; attributes=&quot;0&quot;/&gt;
-                  &lt;Component id=&quot;jScrollPane1&quot; alignment=&quot;0&quot; pref=&quot;626&quot; max=&quot;32767&quot; attributes=&quot;0&quot;/&gt;
+                  &lt;Component id=&quot;filesPanel&quot; alignment=&quot;0&quot; pref=&quot;610&quot; max=&quot;32767&quot; attributes=&quot;0&quot;/&gt;
+                  &lt;Component id=&quot;jScrollPane1&quot; alignment=&quot;0&quot; pref=&quot;610&quot; max=&quot;32767&quot; attributes=&quot;0&quot;/&gt;
                   &lt;Group type=&quot;102&quot; alignment=&quot;0&quot; attributes=&quot;0&quot;&gt;
                       &lt;Component id=&quot;jLabel1&quot; min=&quot;-2&quot; max=&quot;-2&quot; attributes=&quot;0&quot;/&gt;
-                      &lt;EmptySpace pref=&quot;426&quot; max=&quot;32767&quot; attributes=&quot;0&quot;/&gt;
+                      &lt;EmptySpace pref=&quot;498&quot; max=&quot;32767&quot; attributes=&quot;0&quot;/&gt;
                       &lt;Component id=&quot;recentLink&quot; min=&quot;-2&quot; max=&quot;-2&quot; attributes=&quot;0&quot;/&gt;
                   &lt;/Group&gt;
                   &lt;Component id=&quot;filesLabel&quot; alignment=&quot;0&quot; min=&quot;-2&quot; max=&quot;-2&quot; attributes=&quot;0&quot;/&gt;
@@ -60,7 +60,7 @@
               &lt;EmptySpace min=&quot;-2&quot; pref=&quot;15&quot; max=&quot;-2&quot; attributes=&quot;0&quot;/&gt;
               &lt;Component id=&quot;filesLabel&quot; min=&quot;-2&quot; max=&quot;-2&quot; attributes=&quot;0&quot;/&gt;
               &lt;EmptySpace max=&quot;-2&quot; attributes=&quot;0&quot;/&gt;
-              &lt;Component id=&quot;filesPanel&quot; pref=&quot;205&quot; max=&quot;32767&quot; attributes=&quot;0&quot;/&gt;
+              &lt;Component id=&quot;filesPanel&quot; pref=&quot;173&quot; max=&quot;32767&quot; attributes=&quot;0&quot;/&gt;
               &lt;EmptySpace max=&quot;-2&quot; attributes=&quot;0&quot;/&gt;
               &lt;Component id=&quot;jLabel2&quot; min=&quot;-2&quot; max=&quot;-2&quot; attributes=&quot;0&quot;/&gt;
               &lt;EmptySpace max=&quot;-2&quot; attributes=&quot;0&quot;/&gt;
@@ -125,12 +125,12 @@
       &lt;Layout&gt;
         &lt;DimensionLayout dim=&quot;0&quot;&gt;
           &lt;Group type=&quot;103&quot; groupAlignment=&quot;0&quot; attributes=&quot;0&quot;&gt;
-              &lt;EmptySpace min=&quot;0&quot; pref=&quot;626&quot; max=&quot;32767&quot; attributes=&quot;0&quot;/&gt;
+              &lt;EmptySpace min=&quot;0&quot; pref=&quot;610&quot; max=&quot;32767&quot; attributes=&quot;0&quot;/&gt;
           &lt;/Group&gt;
         &lt;/DimensionLayout&gt;
         &lt;DimensionLayout dim=&quot;1&quot;&gt;
           &lt;Group type=&quot;103&quot; groupAlignment=&quot;0&quot; attributes=&quot;0&quot;&gt;
-              &lt;EmptySpace min=&quot;0&quot; pref=&quot;205&quot; max=&quot;32767&quot; attributes=&quot;0&quot;/&gt;
+              &lt;EmptySpace min=&quot;0&quot; pref=&quot;173&quot; max=&quot;32767&quot; attributes=&quot;0&quot;/&gt;
           &lt;/Group&gt;
         &lt;/DimensionLayout&gt;
       &lt;/Layout&gt;</diff>
      <filename>src/org/nbgit/ui/commit/CommitPanel.form</filename>
    </modified>
    <modified>
      <diff>@@ -65,7 +65,7 @@ public class CommitPanel extends javax.swing.JPanel implements PreferenceChangeL
     static final Object EVENT_SETTINGS_CHANGED = new Object();
 
     private CommitTable commitTable;
-    
+
     /** Creates new form CommitPanel */
     public CommitPanel() {
         initComponents();
@@ -74,10 +74,10 @@ public class CommitPanel extends javax.swing.JPanel implements PreferenceChangeL
     void setCommitTable(CommitTable commitTable) {
         this.commitTable = commitTable;
     }
-    
+
     void setErrorLabel(String htmlErrorLabel) {
         jLabel2.setText(htmlErrorLabel);
-    }    
+    }
 
     @Override
     public void addNotify() {
@@ -93,7 +93,7 @@ public class CommitPanel extends javax.swing.JPanel implements PreferenceChangeL
                 onBrowseRecentMessages();
             }
         });
-        
+
         List&lt;String&gt; messages = Utils.getStringList(GitModuleConfig.getDefault().getPreferences(), CommitAction.RECENT_COMMIT_MESSAGES);
         if (messages.size() &gt; 0) {
             messageTextArea.setText(messages.get(0));
@@ -107,7 +107,7 @@ public class CommitPanel extends javax.swing.JPanel implements PreferenceChangeL
         GitModuleConfig.getDefault().getPreferences().removePreferenceChangeListener(this);
         super.removeNotify();
     }
-    
+
     private void onBrowseRecentMessages() {
         String message = StringSelector.select(NbBundle.getMessage(CommitPanel.class, &quot;CTL_CommitForm_RecentTitle&quot;),  // NOI18N
                                                NbBundle.getMessage(CommitPanel.class, &quot;CTL_CommitForm_RecentPrompt&quot;),  // NOI18N
@@ -116,7 +116,7 @@ public class CommitPanel extends javax.swing.JPanel implements PreferenceChangeL
             messageTextArea.replaceSelection(message);
         }
     }
-    
+
     public void preferenceChange(PreferenceChangeEvent evt) {
         if (evt.getKey().startsWith(GitModuleConfig.PROP_COMMIT_EXCLUSIONS)) {
             commitTable.dataChanged();
@@ -127,7 +127,7 @@ public class CommitPanel extends javax.swing.JPanel implements PreferenceChangeL
     public void tableChanged(TableModelEvent e) {
         listenerSupport.fireVersioningEvent(EVENT_SETTINGS_CHANGED);
     }
-    
+
     /** This method is called from within the constructor to
      * initialize the form.
      * WARNING: Do NOT modify this code. The content of this method is
@@ -208,7 +208,7 @@ public class CommitPanel extends javax.swing.JPanel implements PreferenceChangeL
         getAccessibleContext().setAccessibleName(org.openide.util.NbBundle.getMessage(CommitPanel.class, &quot;ACSN_CommitDialog&quot;)); // NOI18N
         getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getMessage(CommitPanel.class, &quot;ACSD_CommitDialog&quot;)); // NOI18N
     }// &lt;/editor-fold&gt;//GEN-END:initComponents
-    
+
     ListenersSupport listenerSupport = new ListenersSupport(this);
     public void addVersioningListener(VersioningListener listener) {
         listenerSupport.addListener(listener);
@@ -216,8 +216,8 @@ public class CommitPanel extends javax.swing.JPanel implements PreferenceChangeL
 
     public void removeVersioningListener(VersioningListener listener) {
         listenerSupport.removeListener(listener);
-    }    
-    
+    }
+
     // Variables declaration - do not modify//GEN-BEGIN:variables
     final javax.swing.JLabel filesLabel = new javax.swing.JLabel();
     final javax.swing.JPanel filesPanel = new javax.swing.JPanel();
@@ -227,5 +227,5 @@ public class CommitPanel extends javax.swing.JPanel implements PreferenceChangeL
     final javax.swing.JTextArea messageTextArea = new javax.swing.JTextArea();
     final javax.swing.JLabel recentLink = new javax.swing.JLabel();
     // End of variables declaration//GEN-END:variables
-    
+
 }
\ No newline at end of file</diff>
      <filename>src/org/nbgit/ui/commit/CommitPanel.java</filename>
    </modified>
    <modified>
      <diff>@@ -69,298 +69,298 @@ import org.openide.util.NbBundle;
 
 /**
  * {@link #getComponent Table} that displays nodes in the commit dialog.
- * 
+ *
  * @author Maros Sandor
  */
 public class CommitTable implements AncestorListener, TableModelListener {
 
-	public static String[] COMMIT_COLUMNS = new String[]{
-		CommitTableModel.COLUMN_NAME_NAME,
-		CommitTableModel.COLUMN_NAME_STATUS,
-		CommitTableModel.COLUMN_NAME_ACTION,
-		CommitTableModel.COLUMN_NAME_PATH
-	};
-	public static String[] IMPORT_COLUMNS = new String[]{
-		CommitTableModel.COLUMN_NAME_NAME,
-		CommitTableModel.COLUMN_NAME_ACTION,
-		CommitTableModel.COLUMN_NAME_PATH
-	};
-	private CommitTableModel tableModel;
-	private JTable table;
-	private JComponent component;
-	private TableSorter sorter;
-	private String[] columns;
-	private String[] sortByColumns;
-
-	public CommitTable(JLabel label, String[] columns, String[] sortByColumns)
-	{
-		init(label, columns, null);
-		this.sortByColumns = sortByColumns;
-		setSortingStatus();
-	}
-
-	public CommitTable(JLabel label, String[] columns, TableSorter sorter)
-	{
-		init(label, columns, sorter);
-	}
-
-	private void init(JLabel label, String[] columns, TableSorter sorter)
-	{
-		tableModel = new CommitTableModel(columns);
-		tableModel.addTableModelListener(this);
-		if (sorter == null)
-			sorter = new TableSorter(tableModel);
-		this.sorter = sorter;
-		table = new JTable(this.sorter);
-		table.getTableHeader().setReorderingAllowed(false);
-		table.setDefaultRenderer(String.class, new CommitStringsCellRenderer());
-		table.setDefaultEditor(CommitOptions.class, new CommitOptionsCellEditor());
-		table.getTableHeader().setReorderingAllowed(true);
-		this.sorter.setTableHeader(table.getTableHeader());
-		table.setRowHeight(table.getRowHeight() * 6 / 5);
-		table.addAncestorListener(this);
-		component = new JScrollPane(table, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
-		label.setLabelFor(table);
-		table.getAccessibleContext().setAccessibleDescription(NbBundle.getMessage(CommitTable.class, &quot;ACSD_CommitTable&quot;)); // NOI18N        
-		setColumns(columns);
-	}
-
-	public void ancestorAdded(AncestorEvent event)
-	{
-		setDefaultColumnSizes();
-	}
-
-	/**
-	 * Sets sizes of Commit table columns, kind of hardcoded.
-	 */
-	private void setDefaultColumnSizes()
-	{
-		int width = table.getWidth();
-		TableColumnModel columnModel = table.getColumnModel();
-		if (columns == null || columnModel == null)
-			return; // unsure when this methed will be called (component realization) 
-		if (columnModel.getColumnCount() != columns.length)
-			return;
-		if (columns.length == 3)
-			for (int i = 0; i &lt; columns.length; i++) {
-				String col = columns[i];
-				sorter.setColumnComparator(i, null);
-				if (col.equals(CommitTableModel.COLUMN_NAME_NAME)) {
-					sorter.setColumnComparator(i, new FileNameComparator());
-					columnModel.getColumn(i).setPreferredWidth(width * 30 / 100);
-				} else if (col.equals(CommitTableModel.COLUMN_NAME_ACTION))
-					columnModel.getColumn(i).setPreferredWidth(width * 15 / 100);
-				else
-					columnModel.getColumn(i).setPreferredWidth(width * 40 / 100);
-			}
-		else if (columns.length == 4)
-			for (int i = 0; i &lt; columns.length; i++) {
-				String col = columns[i];
-				sorter.setColumnComparator(i, null);
-				if (col.equals(CommitTableModel.COLUMN_NAME_NAME)) {
-					sorter.setColumnComparator(i, new FileNameComparator());
-					columnModel.getColumn(i).setPreferredWidth(width * 25 / 100);
-				} else if (col.equals(CommitTableModel.COLUMN_NAME_STATUS)) {
-					sorter.setColumnComparator(i, new StatusComparator());
-					columnModel.getColumn(i).setPreferredWidth(width * 15 / 100);
-				} else if (col.equals(CommitTableModel.COLUMN_NAME_ACTION))
-					columnModel.getColumn(i).setPreferredWidth(width * 20 / 100);
-				else
-					columnModel.getColumn(i).setPreferredWidth(width * 40 / 100);
-			}
-		else if (columns.length == 5)
-			for (int i = 0; i &lt; columns.length; i++) {
-				String col = columns[i];
-				sorter.setColumnComparator(i, null);
-				if (col.equals(CommitTableModel.COLUMN_NAME_NAME)) {
-					sorter.setColumnComparator(i, new FileNameComparator());
-					columnModel.getColumn(i).setPreferredWidth(width * 25 / 100);
-				} else if (col.equals(CommitTableModel.COLUMN_NAME_STATUS)) {
-					sorter.setColumnComparator(i, new StatusComparator());
-					sorter.setSortingStatus(i, TableSorter.ASCENDING);
-					columnModel.getColumn(i).setPreferredWidth(width * 15 / 100);
-				} else if (col.equals(CommitTableModel.COLUMN_NAME_ACTION))
-					columnModel.getColumn(i).setPreferredWidth(width * 15 / 100);
-				else
-					columnModel.getColumn(i).setPreferredWidth(width * 30 / 100);
-			}
-	}
-
-	private void setSortingStatus()
-	{
-		for (int i = 0; i &lt; sortByColumns.length; i++) {
-			String sortByColumn = sortByColumns[i];
-			for (int j = 0; j &lt; columns.length; j++) {
-				String column = columns[j];
-				if (column.equals(sortByColumn)) {
-					sorter.setSortingStatus(j, column.equals(sortByColumn) ? TableSorter.ASCENDING : TableSorter.NOT_SORTED);
-					break;
-				}
-			}
-		}
-	}
-
-	public TableSorter getSorter()
-	{
-		return sorter;
-	}
-
-	public void ancestorMoved(AncestorEvent event)
-	{
-	}
-
-	public void ancestorRemoved(AncestorEvent event)
-	{
-	}
-
-	void setColumns(String[] cols)
-	{
-		if (Arrays.equals(columns, cols))
-			return;
-		columns = cols;
-		tableModel.setColumns(cols);
-		setDefaultColumnSizes();
-	}
-
-	public void setNodes(GitFileNode[] nodes)
-	{
-		tableModel.setNodes(nodes);
-	}
-
-	/**
-	 * 
-	 * @return Map&amp;lt;GitFileNode, CommitOptions&amp;gt;
-	 */
-	public Map&lt;GitFileNode, CommitOptions&gt; getCommitFiles()
-	{
-		return tableModel.getCommitFiles();
-	}
-
-	/**
-	 * @return table in a scrollpane 
-	 */
-	public JComponent getComponent()
-	{
-		return component;
-	}
-
-	void dataChanged()
-	{
-		int idx = table.getSelectedRow();
-		tableModel.fireTableDataChanged();
-		if (idx != -1)
-			table.getSelectionModel().addSelectionInterval(idx, idx);
-	}
-
-	TableModel getTableModel()
-	{
-		return tableModel;
-	}
-
-	public void tableChanged(TableModelEvent e)
-	{
-		// change in commit options may alter name rendering (strikethrough)
-		table.repaint();
-	}
-
-	public void setRootFile(String repositoryPath, String rootLocalPath)
-	{
-		tableModel.setRootFile(repositoryPath, rootLocalPath);
-	}
-
-	private class CommitOptionsCellEditor extends DefaultCellEditor {
-
-		private final Object[] dirAddOptions = new Object[]{
-			CommitOptions.COMMIT,
-			CommitOptions.EXCLUDE
-		};
-		private final Object[] addOptions = new Object[]{
-			CommitOptions.COMMIT,
-			CommitOptions.EXCLUDE
-		};
-		private final Object[] commitOptions = new Object[]{
-			CommitOptions.COMMIT,
-			CommitOptions.EXCLUDE
-		};
-		private final Object[] removeOptions = new Object[]{
-			CommitOptions.COMMIT_REMOVE,
-			CommitOptions.EXCLUDE
-		};
-
-		public CommitOptionsCellEditor()
-		{
-			super(new JComboBox());
-		}
-
-		@Override
-		public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column)
-		{
-			StatusInfo info = tableModel.getNode(sorter.modelIndex(row)).getInformation();
-			int fileStatus = info.getStatus();
-			JComboBox combo = (JComboBox) editorComponent;
-			if (fileStatus == StatusInfo.STATUS_VERSIONED_DELETEDLOCALLY || fileStatus == StatusInfo.STATUS_VERSIONED_REMOVEDLOCALLY)
-				combo.setModel(new DefaultComboBoxModel(removeOptions));
-			else if ((fileStatus &amp; StatusInfo.STATUS_IN_REPOSITORY) == 0)
-				if (info.isDirectory())
-					combo.setModel(new DefaultComboBoxModel(dirAddOptions));
-				else
-					combo.setModel(new DefaultComboBoxModel(addOptions));
-			else
-				combo.setModel(new DefaultComboBoxModel(commitOptions));
-			return super.getTableCellEditorComponent(table, value, isSelected, row, column);
-		}
-
-	}
-
-	private class CommitStringsCellRenderer extends DefaultTableCellRenderer {
-
-		private FilePathCellRenderer pathRenderer = new FilePathCellRenderer();
-
-		@Override
-		public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)
-		{
-			int col = table.convertColumnIndexToModel(column);
-			if (columns[col] == CommitTableModel.COLUMN_NAME_NAME) {
-				TableSorter sorter = (TableSorter) table.getModel();
-				CommitTableModel model = (CommitTableModel) sorter.getTableModel();
-				GitFileNode node = model.getNode(sorter.modelIndex(row));
-				CommitOptions options = model.getOptions(sorter.modelIndex(row));
-				if (!isSelected)
-					value = &quot;&lt;html&gt;&quot; + HtmlFormatter.getInstance().annotateNameHtml( // NOI18N
-						node.getFile().getName(), node.getInformation(), null);
-				if (options == CommitOptions.EXCLUDE)
-					value = &quot;&lt;html&gt;&lt;s&gt;&quot; + value + &quot;&lt;/s&gt;&lt;/html&gt;&quot;;
-				return super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
-			} else if (columns[col] == CommitTableModel.COLUMN_NAME_PATH)
-				return pathRenderer.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
-			else
-				return super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
-		}
-
-	}
-
-	private class StatusComparator extends GitUtils.ByImportanceComparator {
-
-		public int compare(Object o1, Object o2)
-		{
-			Integer row1 = (Integer) o1;
-			Integer row2 = (Integer) o2;
-			return super.compare(tableModel.getNode(row1.intValue()).getInformation(),
-				tableModel.getNode(row2.intValue()).getInformation());
-		}
-
-	}
-
-	private class FileNameComparator implements Comparator {
-
-		public int compare(Object o1, Object o2)
-		{
-			Integer row1 = (Integer) o1;
-			Integer row2 = (Integer) o2;
-			return tableModel.getNode(row1.intValue()).getName().compareToIgnoreCase(
-				tableModel.getNode(row2.intValue()).getName());
-		}
-
-	}
+    public static String[] COMMIT_COLUMNS = new String[]{
+        CommitTableModel.COLUMN_NAME_NAME,
+        CommitTableModel.COLUMN_NAME_STATUS,
+        CommitTableModel.COLUMN_NAME_ACTION,
+        CommitTableModel.COLUMN_NAME_PATH
+    };
+    public static String[] IMPORT_COLUMNS = new String[]{
+        CommitTableModel.COLUMN_NAME_NAME,
+        CommitTableModel.COLUMN_NAME_ACTION,
+        CommitTableModel.COLUMN_NAME_PATH
+    };
+    private CommitTableModel tableModel;
+    private JTable table;
+    private JComponent component;
+    private TableSorter sorter;
+    private String[] columns;
+    private String[] sortByColumns;
+
+    public CommitTable(JLabel label, String[] columns, String[] sortByColumns)
+    {
+        init(label, columns, null);
+        this.sortByColumns = sortByColumns;
+        setSortingStatus();
+    }
+
+    public CommitTable(JLabel label, String[] columns, TableSorter sorter)
+    {
+        init(label, columns, sorter);
+    }
+
+    private void init(JLabel label, String[] columns, TableSorter sorter)
+    {
+        tableModel = new CommitTableModel(columns);
+        tableModel.addTableModelListener(this);
+        if (sorter == null)
+            sorter = new TableSorter(tableModel);
+        this.sorter = sorter;
+        table = new JTable(this.sorter);
+        table.getTableHeader().setReorderingAllowed(false);
+        table.setDefaultRenderer(String.class, new CommitStringsCellRenderer());
+        table.setDefaultEditor(CommitOptions.class, new CommitOptionsCellEditor());
+        table.getTableHeader().setReorderingAllowed(true);
+        this.sorter.setTableHeader(table.getTableHeader());
+        table.setRowHeight(table.getRowHeight() * 6 / 5);
+        table.addAncestorListener(this);
+        component = new JScrollPane(table, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
+        label.setLabelFor(table);
+        table.getAccessibleContext().setAccessibleDescription(NbBundle.getMessage(CommitTable.class, &quot;ACSD_CommitTable&quot;)); // NOI18N
+        setColumns(columns);
+    }
+
+    public void ancestorAdded(AncestorEvent event)
+    {
+        setDefaultColumnSizes();
+    }
+
+    /**
+     * Sets sizes of Commit table columns, kind of hardcoded.
+     */
+    private void setDefaultColumnSizes()
+    {
+        int width = table.getWidth();
+        TableColumnModel columnModel = table.getColumnModel();
+        if (columns == null || columnModel == null)
+            return; // unsure when this methed will be called (component realization)
+        if (columnModel.getColumnCount() != columns.length)
+            return;
+        if (columns.length == 3)
+            for (int i = 0; i &lt; columns.length; i++) {
+                String col = columns[i];
+                sorter.setColumnComparator(i, null);
+                if (col.equals(CommitTableModel.COLUMN_NAME_NAME)) {
+                    sorter.setColumnComparator(i, new FileNameComparator());
+                    columnModel.getColumn(i).setPreferredWidth(width * 30 / 100);
+                } else if (col.equals(CommitTableModel.COLUMN_NAME_ACTION))
+                    columnModel.getColumn(i).setPreferredWidth(width * 15 / 100);
+                else
+                    columnModel.getColumn(i).setPreferredWidth(width * 40 / 100);
+            }
+        else if (columns.length == 4)
+            for (int i = 0; i &lt; columns.length; i++) {
+                String col = columns[i];
+                sorter.setColumnComparator(i, null);
+                if (col.equals(CommitTableModel.COLUMN_NAME_NAME)) {
+                    sorter.setColumnComparator(i, new FileNameComparator());
+                    columnModel.getColumn(i).setPreferredWidth(width * 25 / 100);
+                } else if (col.equals(CommitTableModel.COLUMN_NAME_STATUS)) {
+                    sorter.setColumnComparator(i, new StatusComparator());
+                    columnModel.getColumn(i).setPreferredWidth(width * 15 / 100);
+                } else if (col.equals(CommitTableModel.COLUMN_NAME_ACTION))
+                    columnModel.getColumn(i).setPreferredWidth(width * 20 / 100);
+                else
+                    columnModel.getColumn(i).setPreferredWidth(width * 40 / 100);
+            }
+        else if (columns.length == 5)
+            for (int i = 0; i &lt; columns.length; i++) {
+                String col = columns[i];
+                sorter.setColumnComparator(i, null);
+                if (col.equals(CommitTableModel.COLUMN_NAME_NAME)) {
+                    sorter.setColumnComparator(i, new FileNameComparator());
+                    columnModel.getColumn(i).setPreferredWidth(width * 25 / 100);
+                } else if (col.equals(CommitTableModel.COLUMN_NAME_STATUS)) {
+                    sorter.setColumnComparator(i, new StatusComparator());
+                    sorter.setSortingStatus(i, TableSorter.ASCENDING);
+                    columnModel.getColumn(i).setPreferredWidth(width * 15 / 100);
+                } else if (col.equals(CommitTableModel.COLUMN_NAME_ACTION))
+                    columnModel.getColumn(i).setPreferredWidth(width * 15 / 100);
+                else
+                    columnModel.getColumn(i).setPreferredWidth(width * 30 / 100);
+            }
+    }
+
+    private void setSortingStatus()
+    {
+        for (int i = 0; i &lt; sortByColumns.length; i++) {
+            String sortByColumn = sortByColumns[i];
+            for (int j = 0; j &lt; columns.length; j++) {
+                String column = columns[j];
+                if (column.equals(sortByColumn)) {
+                    sorter.setSortingStatus(j, column.equals(sortByColumn) ? TableSorter.ASCENDING : TableSorter.NOT_SORTED);
+                    break;
+                }
+            }
+        }
+    }
+
+    public TableSorter getSorter()
+    {
+        return sorter;
+    }
+
+    public void ancestorMoved(AncestorEvent event)
+    {
+    }
+
+    public void ancestorRemoved(AncestorEvent event)
+    {
+    }
+
+    void setColumns(String[] cols)
+    {
+        if (Arrays.equals(columns, cols))
+            return;
+        columns = cols;
+        tableModel.setColumns(cols);
+        setDefaultColumnSizes();
+    }
+
+    public void setNodes(GitFileNode[] nodes)
+    {
+        tableModel.setNodes(nodes);
+    }
+
+    /**
+     *
+     * @return Map&amp;lt;GitFileNode, CommitOptions&amp;gt;
+     */
+    public Map&lt;GitFileNode, CommitOptions&gt; getCommitFiles()
+    {
+        return tableModel.getCommitFiles();
+    }
+
+    /**
+     * @return table in a scrollpane
+     */
+    public JComponent getComponent()
+    {
+        return component;
+    }
+
+    void dataChanged()
+    {
+        int idx = table.getSelectedRow();
+        tableModel.fireTableDataChanged();
+        if (idx != -1)
+            table.getSelectionModel().addSelectionInterval(idx, idx);
+    }
+
+    TableModel getTableModel()
+    {
+        return tableModel;
+    }
+
+    public void tableChanged(TableModelEvent e)
+    {
+        // change in commit options may alter name rendering (strikethrough)
+        table.repaint();
+    }
+
+    public void setRootFile(String repositoryPath, String rootLocalPath)
+    {
+        tableModel.setRootFile(repositoryPath, rootLocalPath);
+    }
+
+    private class CommitOptionsCellEditor extends DefaultCellEditor {
+
+        private final Object[] dirAddOptions = new Object[]{
+            CommitOptions.COMMIT,
+            CommitOptions.EXCLUDE
+        };
+        private final Object[] addOptions = new Object[]{
+            CommitOptions.COMMIT,
+            CommitOptions.EXCLUDE
+        };
+        private final Object[] commitOptions = new Object[]{
+            CommitOptions.COMMIT,
+            CommitOptions.EXCLUDE
+        };
+        private final Object[] removeOptions = new Object[]{
+            CommitOptions.COMMIT_REMOVE,
+            CommitOptions.EXCLUDE
+        };
+
+        public CommitOptionsCellEditor()
+        {
+            super(new JComboBox());
+        }
+
+        @Override
+        public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column)
+        {
+            StatusInfo info = tableModel.getNode(sorter.modelIndex(row)).getInformation();
+            int fileStatus = info.getStatus();
+            JComboBox combo = (JComboBox) editorComponent;
+            if (fileStatus == StatusInfo.STATUS_VERSIONED_DELETEDLOCALLY || fileStatus == StatusInfo.STATUS_VERSIONED_REMOVEDLOCALLY)
+                combo.setModel(new DefaultComboBoxModel(removeOptions));
+            else if ((fileStatus &amp; StatusInfo.STATUS_IN_REPOSITORY) == 0)
+                if (info.isDirectory())
+                    combo.setModel(new DefaultComboBoxModel(dirAddOptions));
+                else
+                    combo.setModel(new DefaultComboBoxModel(addOptions));
+            else
+                combo.setModel(new DefaultComboBoxModel(commitOptions));
+            return super.getTableCellEditorComponent(table, value, isSelected, row, column);
+        }
+
+    }
+
+    private class CommitStringsCellRenderer extends DefaultTableCellRenderer {
+
+        private FilePathCellRenderer pathRenderer = new FilePathCellRenderer();
+
+        @Override
+        public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)
+        {
+            int col = table.convertColumnIndexToModel(column);
+            if (columns[col] == CommitTableModel.COLUMN_NAME_NAME) {
+                TableSorter sorter = (TableSorter) table.getModel();
+                CommitTableModel model = (CommitTableModel) sorter.getTableModel();
+                GitFileNode node = model.getNode(sorter.modelIndex(row));
+                CommitOptions options = model.getOptions(sorter.modelIndex(row));
+                if (!isSelected)
+                    value = &quot;&lt;html&gt;&quot; + HtmlFormatter.getInstance().annotateNameHtml( // NOI18N
+                        node.getFile().getName(), node.getInformation(), null);
+                if (options == CommitOptions.EXCLUDE)
+                    value = &quot;&lt;html&gt;&lt;s&gt;&quot; + value + &quot;&lt;/s&gt;&lt;/html&gt;&quot;;
+                return super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
+            } else if (columns[col] == CommitTableModel.COLUMN_NAME_PATH)
+                return pathRenderer.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
+            else
+                return super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
+        }
+
+    }
+
+    private class StatusComparator extends GitUtils.ByImportanceComparator {
+
+        public int compare(Object o1, Object o2)
+        {
+            Integer row1 = (Integer) o1;
+            Integer row2 = (Integer) o2;
+            return super.compare(tableModel.getNode(row1.intValue()).getInformation(),
+                tableModel.getNode(row2.intValue()).getInformation());
+        }
+
+    }
+
+    private class FileNameComparator implements Comparator {
+
+        public int compare(Object o1, Object o2)
+        {
+            Integer row1 = (Integer) o1;
+            Integer row2 = (Integer) o2;
+            return tableModel.getNode(row1.intValue()).getName().compareToIgnoreCase(
+                tableModel.getNode(row2.intValue()).getName());
+        }
+
+    }
 
 }
\ No newline at end of file</diff>
      <filename>src/org/nbgit/ui/commit/CommitTable.java</filename>
    </modified>
    <modified>
      <diff>@@ -60,200 +60,200 @@ import org.openide.util.NbBundle;
  */
 public class CommitTableModel extends AbstractTableModel {
 
-	public static final String COLUMN_NAME_NAME = &quot;name&quot;; // NOI18N
-	public static final String COLUMN_NAME_STATUS = &quot;status&quot;; // NOI18N
-	public static final String COLUMN_NAME_ACTION = &quot;action&quot;; // NOI18N
-	public static final String COLUMN_NAME_PATH = &quot;path&quot;; // NOI18N
-	public static final String COLUMN_NAME_BRANCH = &quot;branch&quot;; // NOI18N
+    public static final String COLUMN_NAME_NAME = &quot;name&quot;; // NOI18N
+    public static final String COLUMN_NAME_STATUS = &quot;status&quot;; // NOI18N
+    public static final String COLUMN_NAME_ACTION = &quot;action&quot;; // NOI18N
+    public static final String COLUMN_NAME_PATH = &quot;path&quot;; // NOI18N
+    public static final String COLUMN_NAME_BRANCH = &quot;branch&quot;; // NOI18N
 
-	private class RootFile {
+    private class RootFile {
 
-		String repositoryPath;
-		String rootLocalPath;
-	}
-	//private Set&lt;SVNUrl&gt; repositoryRoots;
-	private RootFile rootFile;
-	/**
-	 * Defines labels for Versioning view table columns.
-	 */
-	private static final Map&lt;String, String[]&gt; columnLabels = new HashMap&lt;String, String[]&gt;(4);
-	
+        String repositoryPath;
+        String rootLocalPath;
+    }
+    //private Set&lt;SVNUrl&gt; repositoryRoots;
+    private RootFile rootFile;
+    /**
+     * Defines labels for Versioning view table columns.
+     */
+    private static final Map&lt;String, String[]&gt; columnLabels = new HashMap&lt;String, String[]&gt;(4);
 
-	{
-		ResourceBundle loc = NbBundle.getBundle(CommitTableModel.class);
-		columnLabels.put(COLUMN_NAME_NAME, new String[]{
-				loc.getString(&quot;CTL_CommitTable_Column_File&quot;), // NOI18N
-				loc.getString(&quot;CTL_CommitTable_Column_File&quot;)
-			}); // NOI18N
-		columnLabels.put(COLUMN_NAME_BRANCH, new String[]{
-				loc.getString(&quot;CTL_CommitTable_Column_Branch&quot;), // NOI18N
-				loc.getString(&quot;CTL_CommitTable_Column_Branch&quot;)
-			}); // NOI18N
-		columnLabels.put(COLUMN_NAME_STATUS, new String[]{
-				loc.getString(&quot;CTL_CommitTable_Column_Status&quot;), // NOI18N
-				loc.getString(&quot;CTL_CommitTable_Column_Status&quot;)
-			}); // NOI18N
-		columnLabels.put(COLUMN_NAME_ACTION, new String[]{
-				loc.getString(&quot;CTL_CommitTable_Column_Action&quot;), // NOI18N
-				loc.getString(&quot;CTL_CommitTable_Column_Action&quot;)
-			}); // NOI18N
-		columnLabels.put(COLUMN_NAME_PATH, new String[]{
-				loc.getString(&quot;CTL_CommitTable_Column_Folder&quot;), // NOI18N
-				loc.getString(&quot;CTL_CommitTable_Column_Folder&quot;)
-			}); // NOI18N
-	}
 
-	private CommitOptions[] commitOptions;
-	private GitFileNode[] nodes;
-	private String[] columns;
+    {
+        ResourceBundle loc = NbBundle.getBundle(CommitTableModel.class);
+        columnLabels.put(COLUMN_NAME_NAME, new String[]{
+                loc.getString(&quot;CTL_CommitTable_Column_File&quot;), // NOI18N
+                loc.getString(&quot;CTL_CommitTable_Column_File&quot;)
+            }); // NOI18N
+        columnLabels.put(COLUMN_NAME_BRANCH, new String[]{
+                loc.getString(&quot;CTL_CommitTable_Column_Branch&quot;), // NOI18N
+                loc.getString(&quot;CTL_CommitTable_Column_Branch&quot;)
+            }); // NOI18N
+        columnLabels.put(COLUMN_NAME_STATUS, new String[]{
+                loc.getString(&quot;CTL_CommitTable_Column_Status&quot;), // NOI18N
+                loc.getString(&quot;CTL_CommitTable_Column_Status&quot;)
+            }); // NOI18N
+        columnLabels.put(COLUMN_NAME_ACTION, new String[]{
+                loc.getString(&quot;CTL_CommitTable_Column_Action&quot;), // NOI18N
+                loc.getString(&quot;CTL_CommitTable_Column_Action&quot;)
+            }); // NOI18N
+        columnLabels.put(COLUMN_NAME_PATH, new String[]{
+                loc.getString(&quot;CTL_CommitTable_Column_Folder&quot;), // NOI18N
+                loc.getString(&quot;CTL_CommitTable_Column_Folder&quot;)
+            }); // NOI18N
+    }
 
-	/**
-	 * Create stable with name, status, action and path columns
-	 * and empty nodes {@link #setNodes model}.
-	 */
-	public CommitTableModel(String[] columns)
-	{
-		setColumns(columns);
-		setNodes(new GitFileNode[0]);
-	}
+    private CommitOptions[] commitOptions;
+    private GitFileNode[] nodes;
+    private String[] columns;
 
-	void setNodes(GitFileNode[] nodes)
-	{
-		this.nodes = nodes;
-		defaultCommitOptions();
-		fireTableDataChanged();
-	}
+    /**
+     * Create stable with name, status, action and path columns
+     * and empty nodes {@link #setNodes model}.
+     */
+    public CommitTableModel(String[] columns)
+    {
+        setColumns(columns);
+        setNodes(new GitFileNode[0]);
+    }
 
-	void setColumns(String[] cols)
-	{
-		if (Arrays.equals(cols, columns))
-			return;
-		columns = cols;
-		fireTableStructureChanged();
-	}
+    void setNodes(GitFileNode[] nodes)
+    {
+        this.nodes = nodes;
+        defaultCommitOptions();
+        fireTableDataChanged();
+    }
 
-	/**
-	 * @return Map&amp;lt;GitFileNode, CommitOptions&gt;
-	 */
-	public Map&lt;GitFileNode, CommitOptions&gt; getCommitFiles()
-	{
-		Map&lt;GitFileNode, CommitOptions&gt; ret = new HashMap&lt;GitFileNode, CommitOptions&gt;(nodes.length);
-		for (int i = 0; i &lt; nodes.length; i++) {
-			ret.put(nodes[i], commitOptions[i]);
-		}
-		return ret;
-	}
+    void setColumns(String[] cols)
+    {
+        if (Arrays.equals(cols, columns))
+            return;
+        columns = cols;
+        fireTableStructureChanged();
+    }
 
-	@Override
-	public String getColumnName(int column)
-	{
-		return columnLabels.get(columns[column])[0];
-	}
+    /**
+     * @return Map&amp;lt;GitFileNode, CommitOptions&gt;
+     */
+    public Map&lt;GitFileNode, CommitOptions&gt; getCommitFiles()
+    {
+        Map&lt;GitFileNode, CommitOptions&gt; ret = new HashMap&lt;GitFileNode, CommitOptions&gt;(nodes.length);
+        for (int i = 0; i &lt; nodes.length; i++) {
+            ret.put(nodes[i], commitOptions[i]);
+        }
+        return ret;
+    }
 
-	public int getColumnCount()
-	{
-		return columns.length;
-	}
+    @Override
+    public String getColumnName(int column)
+    {
+        return columnLabels.get(columns[column])[0];
+    }
 
-	public int getRowCount()
-	{
-		return nodes.length;
-	}
+    public int getColumnCount()
+    {
+        return columns.length;
+    }
 
-	@Override
-	public Class getColumnClass(int columnIndex)
-	{
-		String col = columns[columnIndex];
-		if (col.equals(COLUMN_NAME_ACTION))
-			return CommitOptions.class;
-		return String.class;
-	}
+    public int getRowCount()
+    {
+        return nodes.length;
+    }
 
-	@Override
-	public boolean isCellEditable(int rowIndex, int columnIndex)
-	{
-		String col = columns[columnIndex];
-		return col.equals(COLUMN_NAME_ACTION);
-	}
+    @Override
+    public Class getColumnClass(int columnIndex)
+    {
+        String col = columns[columnIndex];
+        if (col.equals(COLUMN_NAME_ACTION))
+            return CommitOptions.class;
+        return String.class;
+    }
 
-	public Object getValueAt(int rowIndex, int columnIndex)
-	{
-		GitFileNode node;
-		String col = columns[columnIndex];
-		if (col.equals(COLUMN_NAME_NAME))
-			return nodes[rowIndex].getName();
-		else if (col.equals(COLUMN_NAME_STATUS)) {
-			node = nodes[rowIndex];
-			StatusInfo finfo = node.getInformation();
-			//TODO what should we do with this?
-			//finfo.getEntry(node.getFile());  // HACK returned value is not interesting, point is side effect, it loads ISVNStatus structure
-			return finfo.getStatusText();
-		} else if (col.equals(COLUMN_NAME_ACTION))
-			return commitOptions[rowIndex];
-		else if (col.equals(COLUMN_NAME_PATH)) {
-			String shortPath = null;
-			// XXX this is a mess
-			if (rootFile != null) {
-				// must convert from native separators to slashes
-				String relativePath = nodes[rowIndex].getFile().getAbsolutePath().substring(rootFile.rootLocalPath.length());
-				shortPath = rootFile.repositoryPath + relativePath.replace(File.separatorChar, '/');
-			} else {
-				shortPath = GitUtils.getRelativePath(nodes[rowIndex].getFile());
-				if (shortPath == null)
-					shortPath = org.openide.util.NbBundle.getMessage(CommitTableModel.class, &quot;CTL_CommitForm_NotInRepository&quot;);
-			}
-			return shortPath;
-		}
-		throw new IllegalArgumentException(&quot;Column index out of range: &quot; + columnIndex); // NOI18N
-	}
+    @Override
+    public boolean isCellEditable(int rowIndex, int columnIndex)
+    {
+        String col = columns[columnIndex];
+        return col.equals(COLUMN_NAME_ACTION);
+    }
 
-	@Override
-	public void setValueAt(Object aValue, int rowIndex, int columnIndex)
-	{
-		String col = columns[columnIndex];
-		if (col.equals(COLUMN_NAME_ACTION)) {
-			commitOptions[rowIndex] = (CommitOptions) aValue;
-			fireTableCellUpdated(rowIndex, columnIndex);
-		} else
-			throw new IllegalArgumentException(&quot;Column index out of range: &quot; + columnIndex);
-	}
+    public Object getValueAt(int rowIndex, int columnIndex)
+    {
+        GitFileNode node;
+        String col = columns[columnIndex];
+        if (col.equals(COLUMN_NAME_NAME))
+            return nodes[rowIndex].getName();
+        else if (col.equals(COLUMN_NAME_STATUS)) {
+            node = nodes[rowIndex];
+            StatusInfo finfo = node.getInformation();
+            //TODO what should we do with this?
+            //finfo.getEntry(node.getFile());  // HACK returned value is not interesting, point is side effect, it loads ISVNStatus structure
+            return finfo.getStatusText();
+        } else if (col.equals(COLUMN_NAME_ACTION))
+            return commitOptions[rowIndex];
+        else if (col.equals(COLUMN_NAME_PATH)) {
+            String shortPath = null;
+            // XXX this is a mess
+            if (rootFile != null) {
+                // must convert from native separators to slashes
+                String relativePath = nodes[rowIndex].getFile().getAbsolutePath().substring(rootFile.rootLocalPath.length());
+                shortPath = rootFile.repositoryPath + relativePath.replace(File.separatorChar, '/');
+            } else {
+                shortPath = GitUtils.getRelativePath(nodes[rowIndex].getFile());
+                if (shortPath == null)
+                    shortPath = org.openide.util.NbBundle.getMessage(CommitTableModel.class, &quot;CTL_CommitForm_NotInRepository&quot;);
+            }
+            return shortPath;
+        }
+        throw new IllegalArgumentException(&quot;Column index out of range: &quot; + columnIndex); // NOI18N
+    }
 
-	private void defaultCommitOptions()
-	{
-		boolean excludeNew = System.getProperty(&quot;netbeans.git.excludeNewFiles&quot;) != null; // NOI18N
-		commitOptions = new CommitOptions[nodes.length];
-		for (int i = 0; i &lt; nodes.length; i++) {
-			GitFileNode node = nodes[i];
-			File file = node.getFile();
-			if (GitModuleConfig.getDefault().isExcludedFromCommit(file.getAbsolutePath()))
-				commitOptions[i] = CommitOptions.EXCLUDE;
-			else
-				switch (node.getInformation().getStatus()) {
-				case StatusInfo.STATUS_VERSIONED_DELETEDLOCALLY:
-				case StatusInfo.STATUS_VERSIONED_REMOVEDLOCALLY:
-					commitOptions[i] = CommitOptions.COMMIT_REMOVE;
-					break;
-				default:
-					commitOptions[i] = CommitOptions.COMMIT;
-				}
-		}
-	}
+    @Override
+    public void setValueAt(Object aValue, int rowIndex, int columnIndex)
+    {
+        String col = columns[columnIndex];
+        if (col.equals(COLUMN_NAME_ACTION)) {
+            commitOptions[rowIndex] = (CommitOptions) aValue;
+            fireTableCellUpdated(rowIndex, columnIndex);
+        } else
+            throw new IllegalArgumentException(&quot;Column index out of range: &quot; + columnIndex);
+    }
 
-	public GitFileNode getNode(int row)
-	{
-		return nodes[row];
-	}
+    private void defaultCommitOptions()
+    {
+        boolean excludeNew = System.getProperty(&quot;netbeans.git.excludeNewFiles&quot;) != null; // NOI18N
+        commitOptions = new CommitOptions[nodes.length];
+        for (int i = 0; i &lt; nodes.length; i++) {
+            GitFileNode node = nodes[i];
+            File file = node.getFile();
+            if (GitModuleConfig.getDefault().isExcludedFromCommit(file.getAbsolutePath()))
+                commitOptions[i] = CommitOptions.EXCLUDE;
+            else
+                switch (node.getInformation().getStatus()) {
+                case StatusInfo.STATUS_VERSIONED_DELETEDLOCALLY:
+                case StatusInfo.STATUS_VERSIONED_REMOVEDLOCALLY:
+                    commitOptions[i] = CommitOptions.COMMIT_REMOVE;
+                    break;
+                default:
+                    commitOptions[i] = CommitOptions.COMMIT;
+                }
+        }
+    }
 
-	public CommitOptions getOptions(int row)
-	{
-		return commitOptions[row];
-	}
+    public GitFileNode getNode(int row)
+    {
+        return nodes[row];
+    }
 
-	void setRootFile(String repositoryPath, String rootLocalPath)
-	{
-		rootFile = new RootFile();
-		rootFile.repositoryPath = repositoryPath;
-		rootFile.rootLocalPath = rootLocalPath;
-	}
+    public CommitOptions getOptions(int row)
+    {
+        return commitOptions[row];
+    }
+
+    void setRootFile(String repositoryPath, String rootLocalPath)
+    {
+        rootFile = new RootFile();
+        rootFile.repositoryPath = repositoryPath;
+        rootFile.rootLocalPath = rootLocalPath;
+    }
 
 }
\ No newline at end of file</diff>
      <filename>src/org/nbgit/ui/commit/CommitTableModel.java</filename>
    </modified>
    <modified>
      <diff>@@ -60,90 +60,90 @@ import org.openide.util.RequestProcessor;
  */
 public final class ExcludeFromCommitAction extends ContextAction {
 
-	public static final int UNDEFINED = -1;
-	public static final int EXCLUDING = 1;
-	public static final int INCLUDING = 2;
+    public static final int UNDEFINED = -1;
+    public static final int EXCLUDING = 1;
+    public static final int INCLUDING = 2;
 
-	public ExcludeFromCommitAction(String name, VCSContext context)
-	{
-		super(name, context);
-	}
+    public ExcludeFromCommitAction(String name, VCSContext context)
+    {
+        super(name, context);
+    }
 
-	protected boolean enable(VCSContext ctx)
-	{
-		return getActionStatus(ctx) != UNDEFINED;
-	}
+    protected boolean enable(VCSContext ctx)
+    {
+        return getActionStatus(ctx) != UNDEFINED;
+    }
 
-	protected int getFileEnabledStatus()
-	{
-		return StatusInfo.STATUS_LOCAL_CHANGE;
-	}
+    protected int getFileEnabledStatus()
+    {
+        return StatusInfo.STATUS_LOCAL_CHANGE;
+    }
 
-	protected int getDirectoryEnabledStatus()
-	{
-		return StatusInfo.STATUS_LOCAL_CHANGE;
-	}
+    protected int getDirectoryEnabledStatus()
+    {
+        return StatusInfo.STATUS_LOCAL_CHANGE;
+    }
 
-	protected String getBaseName(VCSContext ctx)
-	{
-		int actionStatus = getActionStatus(ctx);
-		switch (actionStatus) {
-		case UNDEFINED:
-		case EXCLUDING:
-			return &quot;popup_commit_exclude&quot;; // NOI18N
-		case INCLUDING:
-			return &quot;popup_commit_include&quot;; // NOI18N
-		default:
-			throw new RuntimeException(&quot;Invalid action status: &quot; + actionStatus); // NOI18N
-		}
-	}
+    protected String getBaseName(VCSContext ctx)
+    {
+        int actionStatus = getActionStatus(ctx);
+        switch (actionStatus) {
+        case UNDEFINED:
+        case EXCLUDING:
+            return &quot;popup_commit_exclude&quot;; // NOI18N
+        case INCLUDING:
+            return &quot;popup_commit_include&quot;; // NOI18N
+        default:
+            throw new RuntimeException(&quot;Invalid action status: &quot; + actionStatus); // NOI18N
+        }
+    }
 
-	public int getActionStatus(VCSContext ctx)
-	{
-		GitModuleConfig config = GitModuleConfig.getDefault();
-		int status = UNDEFINED;
-		if (ctx == null)
-			ctx = context;
-		Set&lt;File&gt; files = ctx.getRootFiles();
-		for (File file : files) {
-			if (config.isExcludedFromCommit(file.getAbsolutePath())) {
-				if (status == EXCLUDING)
-					return UNDEFINED;
-				status = INCLUDING;
-			} else {
-				if (status == INCLUDING)
-					return UNDEFINED;
-				status = EXCLUDING;
-			}
-		}
-		return status;
-	}
+    public int getActionStatus(VCSContext ctx)
+    {
+        GitModuleConfig config = GitModuleConfig.getDefault();
+        int status = UNDEFINED;
+        if (ctx == null)
+            ctx = context;
+        Set&lt;File&gt; files = ctx.getRootFiles();
+        for (File file : files) {
+            if (config.isExcludedFromCommit(file.getAbsolutePath())) {
+                if (status == EXCLUDING)
+                    return UNDEFINED;
+                status = INCLUDING;
+            } else {
+                if (status == INCLUDING)
+                    return UNDEFINED;
+                status = EXCLUDING;
+            }
+        }
+        return status;
+    }
 
-	public void performAction(ActionEvent e)
-	{
-		final VCSContext ctx = context;
-		RequestProcessor rp = Git.getInstance().getRequestProcessor();
-		GitProgressSupport support = new GitProgressSupport() {
+    public void performAction(ActionEvent e)
+    {
+        final VCSContext ctx = context;
+        RequestProcessor rp = Git.getInstance().getRequestProcessor();
+        GitProgressSupport support = new GitProgressSupport() {
 
-			public void perform()
-			{
-				GitModuleConfig config = GitModuleConfig.getDefault();
-				int status = getActionStatus(ctx);
-				Set&lt;File&gt; files = ctx.getRootFiles();
-				List&lt;String&gt; paths = new ArrayList&lt;String&gt;(files.size());
-				for (File file : files) {
-					paths.add(file.getAbsolutePath());
-				}
-				if (isCanceled())
-					return;
-				if (status == EXCLUDING)
-					config.addExclusionPaths(paths);
-				else if (status == INCLUDING)
-					config.removeExclusionPaths(paths);
-			}
+            public void perform()
+            {
+                GitModuleConfig config = GitModuleConfig.getDefault();
+                int status = getActionStatus(ctx);
+                Set&lt;File&gt; files = ctx.getRootFiles();
+                List&lt;String&gt; paths = new ArrayList&lt;String&gt;(files.size());
+                for (File file : files) {
+                    paths.add(file.getAbsolutePath());
+                }
+                if (isCanceled())
+                    return;
+                if (status == EXCLUDING)
+                    config.addExclusionPaths(paths);
+                else if (status == INCLUDING)
+                    config.removeExclusionPaths(paths);
+            }
 
-		};
-		support.start(rp, &quot;&quot;, &quot;&quot;); // NOI18N
-	}
+        };
+        support.start(rp, &quot;&quot;, &quot;&quot;); // NOI18N
+    }
 
 }
\ No newline at end of file</diff>
      <filename>src/org/nbgit/ui/commit/ExcludeFromCommitAction.java</filename>
    </modified>
    <modified>
      <diff>@@ -56,69 +56,69 @@ import org.netbeans.modules.versioning.util.Utils;
 import org.openide.util.NbBundle;
 
 /**
- * Diff action for Git: 
+ * Diff action for Git:
  * git diff - diff repository (or selected files)
- * 
+ *
  * @author alexbcoles
  * @author John Rice
  */
 public class DiffAction extends ContextAction {
 
-	public DiffAction(String name, VCSContext context)
-	{
-		super(name, context);
-	}
+    public DiffAction(String name, VCSContext context)
+    {
+        super(name, context);
+    }
 
-	public void performAction(ActionEvent e)
-	{
-		String contextName = Utils.getContextDisplayName(context);
+    public void performAction(ActionEvent e)
+    {
+        String contextName = Utils.getContextDisplayName(context);
 
-		File root = GitUtils.getRootFile(context);
-		File[] files = context.getRootFiles().toArray(new File[context.getRootFiles().size()]);
-		boolean bNotManaged = (root == null) || (files == null || files.length == 0);
+        File root = GitUtils.getRootFile(context);
+        File[] files = context.getRootFiles().toArray(new File[context.getRootFiles().size()]);
+        boolean bNotManaged = (root == null) || (files == null || files.length == 0);
 
-		if (bNotManaged) {
-			OutputLogger logger = OutputLogger.getLogger(Git.GIT_OUTPUT_TAB_TITLE);
-			logger.outputInRed(NbBundle.getMessage(DiffAction.class, &quot;MSG_DIFF_TITLE&quot;)); // NOI18N
-			logger.outputInRed(NbBundle.getMessage(DiffAction.class, &quot;MSG_DIFF_TITLE_SEP&quot;)); // NOI18N
-			logger.outputInRed(
-				NbBundle.getMessage(DiffAction.class, &quot;MSG_DIFF_NOT_SUPPORTED_INVIEW_INFO&quot;)); // NOI18N
-			logger.output(&quot;&quot;); // NOI18N
-			logger.closeLog();
-			JOptionPane.showMessageDialog(null,
-				NbBundle.getMessage(DiffAction.class, &quot;MSG_DIFF_NOT_SUPPORTED_INVIEW&quot;),// NOI18N
-				NbBundle.getMessage(DiffAction.class, &quot;MSG_DIFF_NOT_SUPPORTED_INVIEW_TITLE&quot;),// NOI18N
-				JOptionPane.INFORMATION_MESSAGE);
-			return;
-		}
+        if (bNotManaged) {
+            OutputLogger logger = OutputLogger.getLogger(Git.GIT_OUTPUT_TAB_TITLE);
+            logger.outputInRed(NbBundle.getMessage(DiffAction.class, &quot;MSG_DIFF_TITLE&quot;)); // NOI18N
+            logger.outputInRed(NbBundle.getMessage(DiffAction.class, &quot;MSG_DIFF_TITLE_SEP&quot;)); // NOI18N
+            logger.outputInRed(
+                NbBundle.getMessage(DiffAction.class, &quot;MSG_DIFF_NOT_SUPPORTED_INVIEW_INFO&quot;)); // NOI18N
+            logger.output(&quot;&quot;); // NOI18N
+            logger.closeLog();
+            JOptionPane.showMessageDialog(null,
+                NbBundle.getMessage(DiffAction.class, &quot;MSG_DIFF_NOT_SUPPORTED_INVIEW&quot;),// NOI18N
+                NbBundle.getMessage(DiffAction.class, &quot;MSG_DIFF_NOT_SUPPORTED_INVIEW_TITLE&quot;),// NOI18N
+                JOptionPane.INFORMATION_MESSAGE);
+            return;
+        }
 
-		diff(context, Setup.DIFFTYPE_LOCAL, contextName);
-	}
+        diff(context, Setup.DIFFTYPE_LOCAL, contextName);
+    }
 
-	@Override
-	public boolean isEnabled()
-	{
-		StatusCache cache = Git.getInstance().getStatusCache();
-		return cache.containsFileOfStatus(context, StatusInfo.STATUS_LOCAL_CHANGE);
-	}
+    @Override
+    public boolean isEnabled()
+    {
+        StatusCache cache = Git.getInstance().getStatusCache();
+        return cache.containsFileOfStatus(context, StatusInfo.STATUS_LOCAL_CHANGE);
+    }
 
-	public static void diff(VCSContext ctx, int type, String contextName)
-	{
+    public static void diff(VCSContext ctx, int type, String contextName)
+    {
 
-		MultiDiffPanel panel = new MultiDiffPanel(ctx, type, contextName); // spawns background DiffPrepareTask
-		DiffTopComponent tc = new DiffTopComponent(panel);
-		tc.setName(NbBundle.getMessage(DiffAction.class, &quot;CTL_DiffPanel_Title&quot;, contextName)); // NOI18N
-		tc.open();
-		tc.requestActive();
-	}
+        MultiDiffPanel panel = new MultiDiffPanel(ctx, type, contextName); // spawns background DiffPrepareTask
+        DiffTopComponent tc = new DiffTopComponent(panel);
+        tc.setName(NbBundle.getMessage(DiffAction.class, &quot;CTL_DiffPanel_Title&quot;, contextName)); // NOI18N
+        tc.open();
+        tc.requestActive();
+    }
 
-	public static void diff(File file, String rev1, String rev2)
-	{
-		MultiDiffPanel panel = new MultiDiffPanel(file, rev1, rev2); // spawns background DiffPrepareTask
-		DiffTopComponent tc = new DiffTopComponent(panel);
-		tc.setName(NbBundle.getMessage(DiffAction.class, &quot;CTL_DiffPanel_Title&quot;, file.getName())); // NOI18N
-		tc.open();
-		tc.requestActive();
-	}
+    public static void diff(File file, String rev1, String rev2)
+    {
+        MultiDiffPanel panel = new MultiDiffPanel(file, rev1, rev2); // spawns background DiffPrepareTask
+        DiffTopComponent tc = new DiffTopComponent(panel);
+        tc.setName(NbBundle.getMessage(DiffAction.class, &quot;CTL_DiffPanel_Title&quot;, file.getName())); // NOI18N
+        tc.open();
+        tc.requestActive();
+    }
 
 }</diff>
      <filename>src/org/nbgit/ui/diff/DiffAction.java</filename>
    </modified>
    <modified>
      <diff>@@ -81,42 +81,42 @@ import org.openide.util.NbBundle;
 import org.openide.windows.TopComponent;
 
 /**
- * 
+ *
  * @author Maros Sandor
  */
 class DiffFileTable implements MouseListener, ListSelectionListener, AncestorListener {
-    
+
     private NodeTableModel tableModel;
     private JTable table;
     private JScrollPane     component;
     private Node [] nodes = new Node[0];
-    
-    private String []   tableColumns; 
+
+    private String []   tableColumns;
     private TableSorter sorter;
 
     /**
      * Defines labels for Diff view table columns.
-     */ 
+     */
     private static final Map&lt;String, String[]&gt; columnLabels = new HashMap&lt;String, String[]&gt;(4);
 
     {
         ResourceBundle loc = NbBundle.getBundle(DiffFileTable.class);
         columnLabels.put(DiffNode.COLUMN_NAME_NAME, new String [] {
-                loc.getString(&quot;CTL_DiffTable_Column_Name_Title&quot;), 
+                loc.getString(&quot;CTL_DiffTable_Column_Name_Title&quot;),
                 loc.getString(&quot;CTL_DiffTable_Column_Name_Desc&quot;)});
         columnLabels.put(DiffNode.COLUMN_NAME_PROPERTY, new String [] {
-                loc.getString(&quot;CTL_DiffTable_Column_Property_Title&quot;), 
+                loc.getString(&quot;CTL_DiffTable_Column_Property_Title&quot;),
                 loc.getString(&quot;CTL_DiffTable_Column_Property_Desc&quot;)});
-        columnLabels.put(DiffNode.COLUMN_NAME_STATUS, new String [] { 
-                loc.getString(&quot;CTL_DiffTable_Column_Status_Title&quot;), 
+        columnLabels.put(DiffNode.COLUMN_NAME_STATUS, new String [] {
+                loc.getString(&quot;CTL_DiffTable_Column_Status_Title&quot;),
                 loc.getString(&quot;CTL_DiffTable_Column_Status_Desc&quot;)});
-        columnLabels.put(DiffNode.COLUMN_NAME_LOCATION, new String [] { 
-                loc.getString(&quot;CTL_DiffTable_Column_Location_Title&quot;), 
+        columnLabels.put(DiffNode.COLUMN_NAME_LOCATION, new String [] {
+                loc.getString(&quot;CTL_DiffTable_Column_Location_Title&quot;),
                 loc.getString(&quot;CTL_DiffTable_Column_Location_Desc&quot;)});
     }
 
-    
-    
+
+
     private static final Comparator NodeComparator = new Comparator() {
         public int compare(Object o1, Object o2) {
             Node.Property p1 = (Node.Property) o1;
@@ -213,12 +213,12 @@ class DiffFileTable implements MouseListener, ListSelectionListener, AncestorLis
     public JComponent getComponent() {
         return component;
     }
-    
+
     /**
      * Sets visible columns in the Versioning table.
-     * 
-     * @param columns array of column names, they must be one of SyncFileNode.COLUMN_NAME_XXXXX constants.  
-     */ 
+     *
+     * @param columns array of column names, they must be one of SyncFileNode.COLUMN_NAME_XXXXX constants.
+     */
     final void setColumns(String [] columns) {
         if (Arrays.equals(columns, tableColumns)) return;
         setModelProperties(columns);
@@ -231,15 +231,15 @@ class DiffFileTable implements MouseListener, ListSelectionListener, AncestorLis
                 break;
             }
         }
-        setDefaultColumnSizes();        
+        setDefaultColumnSizes();
     }
-        
+
     private void setModelProperties(String [] columns) {
         Node.Property [] properties = new Node.Property[columns.length];
         for (int i = 0; i &lt; columns.length; i++) {
             String column = columns[i];
             String [] labels = columnLabels.get(column);
-            properties[i] = new ColumnDescriptor(column, String.class, labels[0], labels[1]);  
+            properties[i] = new ColumnDescriptor(column, String.class, labels[0], labels[1]);
         }
         tableModel.setProperties(properties);
     }
@@ -276,7 +276,7 @@ class DiffFileTable implements MouseListener, ListSelectionListener, AncestorLis
     }
 
     private static class ColumnDescriptor extends PropertySupport.ReadOnly {
-        
+
         @SuppressWarnings(&quot;unchecked&quot;)
         public ColumnDescriptor(String name, Class type, String displayName, String shortDescription) {
             super(name, type, displayName, shortDescription);
@@ -361,11 +361,11 @@ class DiffFileTable implements MouseListener, ListSelectionListener, AncestorLis
         if (tc == null) return; // table is no longer in component hierarchy
         master.setSelectedIndex(table.getSelectedRow());
     }
-    
+
     private class DiffTableCellRenderer extends DefaultTableCellRenderer {
-        
+
         private FilePathCellRenderer pathRenderer = new FilePathCellRenderer();
-        
+
         @Override
         public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
             Component renderer;
@@ -382,8 +382,8 @@ class DiffFileTable implements MouseListener, ListSelectionListener, AncestorLis
                 renderer = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
             }
             if (renderer instanceof JComponent) {
-                File file = nodes[sorter.modelIndex(row)].getLookup().lookup(File.class); 
-                String path = file != null ? file.getAbsolutePath() : null; 
+                File file = nodes[sorter.modelIndex(row)].getLookup().lookup(File.class);
+                String path = file != null ? file.getAbsolutePath() : null;
                 ((JComponent) renderer).setToolTipText(path);
             }
             return renderer;</diff>
      <filename>src/org/nbgit/ui/diff/DiffFileTable.java</filename>
    </modified>
    <modified>
      <diff>@@ -55,157 +55,157 @@ import org.openide.util.lookup.Lookups;
 
 /**
  * Visible in the Search History Diff view.
- * 
+ *
  * @author Maros Sandor
  * @author alexbcoles
  */
 class DiffNode extends AbstractNode {
 
-	static final String COLUMN_NAME_NAME = &quot;name&quot;;
-	static final String COLUMN_NAME_PROPERTY = &quot;property&quot;;
-	static final String COLUMN_NAME_STATUS = &quot;status&quot;;
-	static final String COLUMN_NAME_LOCATION = &quot;location&quot;;
-	private final Setup setup;
-	private String htmlDisplayName;
-
-	public DiffNode(Setup setup)
-	{
-		super(Children.LEAF, Lookups.singleton(setup));
-		this.setup = setup;
-		setName(setup.getBaseFile().getName());
-		initProperties();
-		refreshHtmlDisplayName();
-	}
-
-	private void refreshHtmlDisplayName()
-	{
-		StatusInfo info = setup.getInfo();
-		int status = info.getStatus();
-		// Special treatment: Mergeable status should be annotated as Conflict in Versioning view according to UI spec
-		if (status == StatusInfo.STATUS_VERSIONED_MERGE)
-			status = StatusInfo.STATUS_VERSIONED_CONFLICT;
-		htmlDisplayName = HtmlFormatter.getInstance().annotateNameHtml(setup.getBaseFile().getName(), info, null);
-		fireDisplayNameChange(htmlDisplayName, htmlDisplayName);
-	}
-
-	@Override
-	public String getHtmlDisplayName()
-	{
-		return htmlDisplayName;
-	}
-
-	public Setup getSetup()
-	{
-		return setup;
-	}
-
-	@Override
-	public Action[] getActions(boolean context)
-	{
-		if (context)
-			return null;
-		return new Action[0];
-	}
-
-	private void initProperties()
-	{
-		Sheet sheet = Sheet.createDefault();
-		Sheet.Set ps = Sheet.createPropertiesSet();
-
-		ps.put(new NameProperty());
-		ps.put(new LocationProperty());
-		ps.put(new StatusProperty());
-		if (setup.getPropertyName() != null)
-			ps.put(new PropertyNameProperty());
-
-		sheet.put(ps);
-		setSheet(sheet);
-	}
-
-	private abstract class DiffNodeProperty extends PropertySupport.ReadOnly {
-
-		@SuppressWarnings(&quot;unchecked&quot;)
-		protected DiffNodeProperty(String name, Class type, String displayName, String shortDescription)
-		{
-			super(name, type, displayName, shortDescription);
-		}
-
-		@Override
-		public String toString()
-		{
-			try {
-				return getValue().toString();
-			} catch (Exception e) {
-				ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e);
-				return e.getLocalizedMessage();
-			}
-		}
-
-	}
-
-	private class NameProperty extends DiffNodeProperty {
-
-		public NameProperty()
-		{
-			super(COLUMN_NAME_NAME, String.class, COLUMN_NAME_NAME, COLUMN_NAME_NAME);
-		}
-
-		public Object getValue() throws IllegalAccessException, InvocationTargetException
-		{
-			return DiffNode.this.getName();
-		}
-
-	}
-
-	private class PropertyNameProperty extends DiffNodeProperty {
-
-		public PropertyNameProperty()
-		{
-			super(COLUMN_NAME_PROPERTY, String.class, COLUMN_NAME_PROPERTY, COLUMN_NAME_PROPERTY);
-		}
-
-		public Object getValue() throws IllegalAccessException, InvocationTargetException
-		{
-			return setup.getPropertyName();
-		}
-
-	}
-
-	private class LocationProperty extends DiffNodeProperty {
-
-		private String location;
-
-		public LocationProperty()
-		{
-			super(COLUMN_NAME_LOCATION, String.class, COLUMN_NAME_LOCATION, COLUMN_NAME_LOCATION);
-			location = GitUtils.getRelativePath(setup.getBaseFile());
-			setValue(&quot;sortkey&quot;, location + &quot;\t&quot; + DiffNode.this.getName()); // NOI18N
-		}
-
-		public Object getValue() throws IllegalAccessException, InvocationTargetException
-		{
-			return location;
-		}
-
-	}
-
-	private static final String[] zeros = new String[]{&quot;&quot;, &quot;00&quot;, &quot;0&quot;, &quot;&quot;}; // NOI18N
-
-	private class StatusProperty extends DiffNodeProperty {
-
-		public StatusProperty()
-		{
-			super(COLUMN_NAME_STATUS, String.class, COLUMN_NAME_STATUS, COLUMN_NAME_STATUS);
-			String shortPath = GitUtils.getRelativePath(setup.getBaseFile());
-			String sortable = Integer.toString(GitUtils.getComparableStatus(setup.getInfo().getStatus()));
-			setValue(&quot;sortkey&quot;, zeros[sortable.length()] + sortable + &quot;\t&quot; + shortPath + &quot;\t&quot; + DiffNode.this.getName().toUpperCase()); // NOI18N
-		}
-
-		public Object getValue() throws IllegalAccessException, InvocationTargetException
-		{
-			return setup.getInfo().getStatusText();
-		}
+    static final String COLUMN_NAME_NAME = &quot;name&quot;;
+    static final String COLUMN_NAME_PROPERTY = &quot;property&quot;;
+    static final String COLUMN_NAME_STATUS = &quot;status&quot;;
+    static final String COLUMN_NAME_LOCATION = &quot;location&quot;;
+    private final Setup setup;
+    private String htmlDisplayName;
+
+    public DiffNode(Setup setup)
+    {
+        super(Children.LEAF, Lookups.singleton(setup));
+        this.setup = setup;
+        setName(setup.getBaseFile().getName());
+        initProperties();
+        refreshHtmlDisplayName();
+    }
+
+    private void refreshHtmlDisplayName()
+    {
+        StatusInfo info = setup.getInfo();
+        int status = info.getStatus();
+        // Special treatment: Mergeable status should be annotated as Conflict in Versioning view according to UI spec
+        if (status == StatusInfo.STATUS_VERSIONED_MERGE)
+            status = StatusInfo.STATUS_VERSIONED_CONFLICT;
+        htmlDisplayName = HtmlFormatter.getInstance().annotateNameHtml(setup.getBaseFile().getName(), info, null);
+        fireDisplayNameChange(htmlDisplayName, htmlDisplayName);
+    }
+
+    @Override
+    public String getHtmlDisplayName()
+    {
+        return htmlDisplayName;
+    }
+
+    public Setup getSetup()
+    {
+        return setup;
+    }
+
+    @Override
+    public Action[] getActions(boolean context)
+    {
+        if (context)
+            return null;
+        return new Action[0];
+    }
+
+    private void initProperties()
+    {
+        Sheet sheet = Sheet.createDefault();
+        Sheet.Set ps = Sheet.createPropertiesSet();
+
+        ps.put(new NameProperty());
+        ps.put(new LocationProperty());
+        ps.put(new StatusProperty());
+        if (setup.getPropertyName() != null)
+            ps.put(new PropertyNameProperty());
+
+        sheet.put(ps);
+        setSheet(sheet);
+    }
+
+    private abstract class DiffNodeProperty extends PropertySupport.ReadOnly {
+
+        @SuppressWarnings(&quot;unchecked&quot;)
+        protected DiffNodeProperty(String name, Class type, String displayName, String shortDescription)
+        {
+            super(name, type, displayName, shortDescription);
+        }
+
+        @Override
+        public String toString()
+        {
+            try {
+                return getValue().toString();
+            } catch (Exception e) {
+                ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e);
+                return e.getLocalizedMessage();
+            }
+        }
+
+    }
+
+    private class NameProperty extends DiffNodeProperty {
+
+        public NameProperty()
+        {
+            super(COLUMN_NAME_NAME, String.class, COLUMN_NAME_NAME, COLUMN_NAME_NAME);
+        }
+
+        public Object getValue() throws IllegalAccessException, InvocationTargetException
+        {
+            return DiffNode.this.getName();
+        }
+
+    }
+
+    private class PropertyNameProperty extends DiffNodeProperty {
+
+        public PropertyNameProperty()
+        {
+            super(COLUMN_NAME_PROPERTY, String.class, COLUMN_NAME_PROPERTY, COLUMN_NAME_PROPERTY);
+        }
+
+        public Object getValue() throws IllegalAccessException, InvocationTargetException
+        {
+            return setup.getPropertyName();
+        }
+
+    }
+
+    private class LocationProperty extends DiffNodeProperty {
+
+        private String location;
+
+        public LocationProperty()
+        {
+            super(COLUMN_NAME_LOCATION, String.class, COLUMN_NAME_LOCATION, COLUMN_NAME_LOCATION);
+            location = GitUtils.getRelativePath(setup.getBaseFile());
+            setValue(&quot;sortkey&quot;, location + &quot;\t&quot; + DiffNode.this.getName()); // NOI18N
+        }
+
+        public Object getValue() throws IllegalAccessException, InvocationTargetException
+        {
+            return location;
+        }
+
+    }
+
+    private static final String[] zeros = new String[]{&quot;&quot;, &quot;00&quot;, &quot;0&quot;, &quot;&quot;}; // NOI18N
+
+    private class StatusProperty extends DiffNodeProperty {
+
+        public StatusProperty()
+        {
+            super(COLUMN_NAME_STATUS, String.class, COLUMN_NAME_STATUS, COLUMN_NAME_STATUS);
+            String shortPath = GitUtils.getRelativePath(setup.getBaseFile());
+            String sortable = Integer.toString(GitUtils.getComparableStatus(setup.getInfo().getStatus()));
+            setValue(&quot;sortkey&quot;, zeros[sortable.length()] + sortable + &quot;\t&quot; + shortPath + &quot;\t&quot; + DiffNode.this.getName().toUpperCase()); // NOI18N
+        }
+
+        public Object getValue() throws IllegalAccessException, InvocationTargetException
+        {
+            return setup.getInfo().getStatusText();
+        }
 
-	}
+    }
 
 }</diff>
      <filename>src/org/nbgit/ui/diff/DiffNode.java</filename>
    </modified>
    <modified>
      <diff>@@ -70,176 +70,176 @@ import org.openide.util.lookup.Lookups;
  */
 public class DiffStreamSource extends StreamSource {
 
-	private final File baseFile;
-	private final String revision;
-	private final String title;
-	private String mimeType;
-	private Boolean start;
-	/**
-	 * Null is a valid value if base file does not exist in this revision. 
-	 */
-	private File remoteFile;
-
-	/**
-	 * Creates a new StreamSource implementation for Diff engine.
-	 * 
-	 * @param baseFile
-	 * @param revision file revision, may be null if the revision does not exist (ie for new files)
-	 * @param title title to use in diff panel
-	 */
-	public DiffStreamSource(File baseFile, String revision, String title)
-	{
-		this.baseFile = baseFile;
-		this.revision = revision;
-		this.title = title;
-		this.start = true;
-	}
-
-	/** Creates DiffStreamSource for nonexiting files. */
-	public DiffStreamSource(String title)
-	{
-		this.baseFile = null;
-		this.revision = null;
-		this.title = title;
-		this.start = true;
-	}
-
-	public String getName()
-	{
-		if (baseFile != null)
-			return baseFile.getName();
-		else
-			return NbBundle.getMessage(DiffStreamSource.class, &quot;LBL_Diff_Anonymous&quot;);
-	}
-
-	public String getTitle()
-	{
-		return title;
-	}
-
-	public synchronized String getMIMEType()
-	{
-		if (baseFile.isDirectory())
-			// http://www.rfc-editor.org/rfc/rfc2425.txt
-			return &quot;content/unknown&quot;;
-
-		try {
-			init();
-		} catch (IOException e) {
-			return null; // XXX use error manager HACK null  potentionally kills DiffViewImpl, NPE while constructing EditorKit
-		}
-		return mimeType;
-	}
-
-	public synchronized Reader createReader() throws IOException
-	{
-		if (baseFile.isDirectory())
-			// XXX return directory listing?
-			// could be nice te return sorted directory content
-			// such as vim if user &quot;edits&quot; directory // NOI18N
-			return new StringReader(NbBundle.getMessage(DiffStreamSource.class, &quot;LBL_Diff_NoFolderDiff&quot;));
-		init();
-		if (revision == null || remoteFile == null)
-			return null;
-		if (!mimeType.startsWith(&quot;text/&quot;)) // NOI18N
-			return null;
-		else
-			return Utils.createReader(remoteFile);
-	}
-
-	public Writer createWriter(Difference[] conflicts) throws IOException
-	{
-		throw new IOException(&quot;Operation not supported&quot;); // NOI18N
-	}
-
-	public boolean isEditable()
-	{
-		return GitRepository.REVISION_CURRENT.equals(revision) &amp;&amp; isPrimary();
-	}
-
-	private boolean isPrimary()
-	{
-		FileObject fo = FileUtil.toFileObject(baseFile);
-		if (fo != null)
-			try {
-				DataObject dao = DataObject.find(fo);
-				return fo.equals(dao.getPrimaryFile());
-			} catch (DataObjectNotFoundException e) {
-				// no dataobject, never mind
-			}
-		return true;
-	}
-
-	@Override
-	public synchronized Lookup getLookup()
-	{
-		try {
-			init();
-		} catch (IOException e) {
-			return Lookups.fixed();
-		}
-		if (remoteFile == null || !isPrimary())
-			return Lookups.fixed();
-		FileObject remoteFo = FileUtil.toFileObject(remoteFile);
-		if (remoteFo == null)
-			return Lookups.fixed();
-
-		return Lookups.fixed(remoteFo);
-	}
-
-	/**
-	 * Loads data.
-	 */
-	synchronized void init() throws IOException
-	{
-		if (baseFile.isDirectory())
-			return;
-		if (start == false)
-			return;
-		start = false;
-		if (remoteFile != null || revision == null)
-			return;
-		mimeType = Git.getInstance().getMimeType(baseFile);
-		try {
-			if (isEditable())
-				// we cannot move editable documents because that would break Document sharing
-				remoteFile = GitUtils.getFileRevision(baseFile, revision);
-			else {
-				File tempFolder = Utils.getTempFolder();
-				// To correctly get content of the base file, we need to checkout all files that belong to the same
-				// DataObject. One example is Form files: data loader removes //GEN:BEGIN comments from the java file but ONLY
-				// if it also finds associate .form file in the same directory
-				Set&lt;File&gt; allFiles = Utils.getAllDataObjectFiles(baseFile);
-				for (File file : allFiles) {
-					boolean isBase = file.equals(baseFile);
-					try {
-						File rf = GitUtils.getFileRevision(file, revision);
-						if (rf == null) {
-							remoteFile = null;
-							return;
-						}
-						File newRemoteFile = new File(tempFolder, file.getName());
-						Utils.copyStreamsCloseAll(new FileOutputStream(newRemoteFile), new FileInputStream(rf));
-						newRemoteFile.deleteOnExit();
-						if (isBase) {
-							remoteFile = newRemoteFile;
-							Utils.associateEncoding(file, newRemoteFile);
-						}
-					} catch (Exception e) {
-						if (isBase)
-							throw e;
-					// we cannot check out peer file so the dataobject will not be constructed properly
-					}
-				}
-			}
-			if (!baseFile.exists() &amp;&amp; remoteFile != null &amp;&amp; remoteFile.exists())
-				mimeType = Git.getInstance().getMimeType(remoteFile);
-		} catch (Exception e) {
-			// TODO detect interrupted IO (exception subclass), i.e. user cancel
-			IOException failure = new IOException(&quot;Can not load remote file for &quot; + baseFile); // NOI18N
-			failure.initCause(e);
-			throw failure;
-		}
-	}
+    private final File baseFile;
+    private final String revision;
+    private final String title;
+    private String mimeType;
+    private Boolean start;
+    /**
+     * Null is a valid value if base file does not exist in this revision.
+     */
+    private File remoteFile;
+
+    /**
+     * Creates a new StreamSource implementation for Diff engine.
+     *
+     * @param baseFile
+     * @param revision file revision, may be null if the revision does not exist (ie for new files)
+     * @param title title to use in diff panel
+     */
+    public DiffStreamSource(File baseFile, String revision, String title)
+    {
+        this.baseFile = baseFile;
+        this.revision = revision;
+        this.title = title;
+        this.start = true;
+    }
+
+    /** Creates DiffStreamSource for nonexiting files. */
+    public DiffStreamSource(String title)
+    {
+        this.baseFile = null;
+        this.revision = null;
+        this.title = title;
+        this.start = true;
+    }
+
+    public String getName()
+    {
+        if (baseFile != null)
+            return baseFile.getName();
+        else
+            return NbBundle.getMessage(DiffStreamSource.class, &quot;LBL_Diff_Anonymous&quot;);
+    }
+
+    public String getTitle()
+    {
+        return title;
+    }
+
+    public synchronized String getMIMEType()
+    {
+        if (baseFile.isDirectory())
+            // http://www.rfc-editor.org/rfc/rfc2425.txt
+            return &quot;content/unknown&quot;;
+
+        try {
+            init();
+        } catch (IOException e) {
+            return null; // XXX use error manager HACK null  potentionally kills DiffViewImpl, NPE while constructing EditorKit
+        }
+        return mimeType;
+    }
+
+    public synchronized Reader createReader() throws IOException
+    {
+        if (baseFile.isDirectory())
+            // XXX return directory listing?
+            // could be nice te return sorted directory content
+            // such as vim if user &quot;edits&quot; directory // NOI18N
+            return new StringReader(NbBundle.getMessage(DiffStreamSource.class, &quot;LBL_Diff_NoFolderDiff&quot;));
+        init();
+        if (revision == null || remoteFile == null)
+            return null;
+        if (!mimeType.startsWith(&quot;text/&quot;)) // NOI18N
+            return null;
+        else
+            return Utils.createReader(remoteFile);
+    }
+
+    public Writer createWriter(Difference[] conflicts) throws IOException
+    {
+        throw new IOException(&quot;Operation not supported&quot;); // NOI18N
+    }
+
+    public boolean isEditable()
+    {
+        return GitRepository.REVISION_CURRENT.equals(revision) &amp;&amp; isPrimary();
+    }
+
+    private boolean isPrimary()
+    {
+        FileObject fo = FileUtil.toFileObject(baseFile);
+        if (fo != null)
+            try {
+                DataObject dao = DataObject.find(fo);
+                return fo.equals(dao.getPrimaryFile());
+            } catch (DataObjectNotFoundException e) {
+                // no dataobject, never mind
+            }
+        return true;
+    }
+
+    @Override
+    public synchronized Lookup getLookup()
+    {
+        try {
+            init();
+        } catch (IOException e) {
+            return Lookups.fixed();
+        }
+        if (remoteFile == null || !isPrimary())
+            return Lookups.fixed();
+        FileObject remoteFo = FileUtil.toFileObject(remoteFile);
+        if (remoteFo == null)
+            return Lookups.fixed();
+
+        return Lookups.fixed(remoteFo);
+    }
+
+    /**
+     * Loads data.
+     */
+    synchronized void init() throws IOException
+    {
+        if (baseFile.isDirectory())
+            return;
+        if (start == false)
+            return;
+        start = false;
+        if (remoteFile != null || revision == null)
+            return;
+        mimeType = Git.getInstance().getMimeType(baseFile);
+        try {
+            if (isEditable())
+                // we cannot move editable documents because that would break Document sharing
+                remoteFile = GitUtils.getFileRevision(baseFile, revision);
+            else {
+                File tempFolder = Utils.getTempFolder();
+                // To correctly get content of the base file, we need to checkout all files that belong to the same
+                // DataObject. One example is Form files: data loader removes //GEN:BEGIN comments from the java file but ONLY
+                // if it also finds associate .form file in the same directory
+                Set&lt;File&gt; allFiles = Utils.getAllDataObjectFiles(baseFile);
+                for (File file : allFiles) {
+                    boolean isBase = file.equals(baseFile);
+                    try {
+                        File rf = GitUtils.getFileRevision(file, revision);
+                        if (rf == null) {
+                            remoteFile = null;
+                            return;
+                        }
+                        File newRemoteFile = new File(tempFolder, file.getName());
+                        Utils.copyStreamsCloseAll(new FileOutputStream(newRemoteFile), new FileInputStream(rf));
+                        newRemoteFile.deleteOnExit();
+                        if (isBase) {
+                            remoteFile = newRemoteFile;
+                            Utils.associateEncoding(file, newRemoteFile);
+                        }
+                    } catch (Exception e) {
+                        if (isBase)
+                            throw e;
+                    // we cannot check out peer file so the dataobject will not be constructed properly
+                    }
+                }
+            }
+            if (!baseFile.exists() &amp;&amp; remoteFile != null &amp;&amp; remoteFile.exists())
+                mimeType = Git.getInstance().getMimeType(remoteFile);
+        } catch (Exception e) {
+            // TODO detect interrupted IO (exception subclass), i.e. user cancel
+            IOException failure = new IOException(&quot;Can not load remote file for &quot; + baseFile); // NOI18N
+            failure.initCause(e);
+            throw failure;
+        }
+    }
 
 }</diff>
      <filename>src/org/nbgit/ui/diff/DiffStreamSource.java</filename>
    </modified>
    <modified>
      <diff>@@ -71,7 +71,7 @@ public class DiffTopComponent extends TopComponent implements DiffSetupSource {
     public UndoRedo getUndoRedo() {
         return panel.getUndoRedo();
     }
-    
+
     @Override
     public int getPersistenceType(){
         return TopComponent.PERSISTENCE_NEVER;
@@ -85,7 +85,7 @@ public class DiffTopComponent extends TopComponent implements DiffSetupSource {
 
     @Override
     protected String preferredID(){
-        return &quot;PERSISTENCE_NEVER-DiffTopComponent&quot;;    // NOI18N       
+        return &quot;PERSISTENCE_NEVER-DiffTopComponent&quot;;    // NOI18N
     }
 
     @Override
@@ -108,5 +108,5 @@ public class DiffTopComponent extends TopComponent implements DiffSetupSource {
         DiffSetupSource mainPanel = ((DiffSetupSource) getComponent(0));
         return mainPanel.getSetupDisplayName();
     }
-    
+
 }</diff>
      <filename>src/org/nbgit/ui/diff/DiffTopComponent.java</filename>
    </modified>
    <modified>
      <diff>@@ -58,7 +58,7 @@
             &lt;DimensionLayout dim=&quot;1&quot;&gt;
               &lt;Group type=&quot;103&quot; groupAlignment=&quot;0&quot; attributes=&quot;0&quot;&gt;
                   &lt;Group type=&quot;102&quot; alignment=&quot;1&quot; attributes=&quot;0&quot;&gt;
-                      &lt;EmptySpace max=&quot;32767&quot; attributes=&quot;0&quot;/&gt;
+                      &lt;EmptySpace pref=&quot;20&quot; max=&quot;32767&quot; attributes=&quot;0&quot;/&gt;
                       &lt;Component id=&quot;jPanel3&quot; min=&quot;-2&quot; max=&quot;-2&quot; attributes=&quot;0&quot;/&gt;
                   &lt;/Group&gt;
               &lt;/Group&gt;</diff>
      <filename>src/org/nbgit/ui/diff/MultiDiffPanel.form</filename>
    </modified>
    <modified>
      <diff>@@ -99,14 +99,14 @@ import org.openide.windows.WindowManager;
  * @author Maros Sandor
  */
 class MultiDiffPanel extends javax.swing.JPanel implements ActionListener, DiffSetupSource, PropertyChangeListener {
-    
+
     /**
      * Array of DIFF setups that we show in the DIFF view. Contents of this array is changed if
      * the user switches DIFF types.
      */
     private Setup[] setups;
-    
-    private final DelegatingUndoRedo delegatingUndoRedo = new DelegatingUndoRedo(); 
+
+    private final DelegatingUndoRedo delegatingUndoRedo = new DelegatingUndoRedo();
 
     /**
      * Context in which to DIFF.
@@ -117,19 +117,19 @@ class MultiDiffPanel extends javax.swing.JPanel implements ActionListener, DiffS
 
     /**
      * Display name of the context of this diff.
-     */ 
+     */
     private final String contextName;
-    
+
     private int currentType;
     private int currentIndex = -1;
     private int currentModelIndex = -1;
-    
+
     private RequestProcessor.Task prepareTask;
     private DiffPrepareTask dpt;
 
     private AbstractAction nextAction;
     private AbstractAction          prevAction;
-    
+
     /**
      * null for view that are not
      */
@@ -140,7 +140,7 @@ class MultiDiffPanel extends javax.swing.JPanel implements ActionListener, DiffS
     private boolean                 dividerSet;
 
     private GitProgressSupport executeStatusSupport;
-    
+
     /**
      * Creates diff panel and immediatelly starts loading...
      */
@@ -182,7 +182,7 @@ class MultiDiffPanel extends javax.swing.JPanel implements ActionListener, DiffS
         if (fileTableSetSelectedIndexContext) return;
         setDiffIndex(viewIndex, 0);
     }
-    
+
     UndoRedo getUndoRedo() {
         return delegatingUndoRedo;
     }
@@ -201,7 +201,7 @@ class MultiDiffPanel extends javax.swing.JPanel implements ActionListener, DiffS
      */
     void componentClosed() {
         setups = null;
-        cancelBackgroundTasks(); 
+        cancelBackgroundTasks();
     }
 
     void requestActive() {
@@ -215,15 +215,15 @@ class MultiDiffPanel extends javax.swing.JPanel implements ActionListener, DiffS
         splitPane.setTopComponent(fileTable.getComponent());
         splitPane.setBottomComponent(new NoContentPanel(NbBundle.getMessage(MultiDiffPanel.class, &quot;MSG_DiffPanel_NoContent&quot;)));
         commitButton.addActionListener(this);
-        
+
         commitButton.setToolTipText(NbBundle.getMessage(MultiDiffPanel.class, &quot;MSG_CommitDiff_Tooltip&quot;, contextName));
         updateButton.setToolTipText(NbBundle.getMessage(MultiDiffPanel.class, &quot;MSG_UpdateDiff_Tooltip&quot;, contextName));
         ButtonGroup grp = new ButtonGroup();
-        
+
         nextAction = new AbstractAction(null, new javax.swing.ImageIcon(getClass().getResource(&quot;/org/nbgit/resources/icons/diff-next.png&quot;))) {  // NOI18N
             {
                 putValue(Action.SHORT_DESCRIPTION, java.util.ResourceBundle.getBundle(&quot;org/nbgit/ui/diff/Bundle&quot;).
-                                                   getString(&quot;CTL_DiffPanel_Next_Tooltip&quot;));                
+                                                   getString(&quot;CTL_DiffPanel_Next_Tooltip&quot;));
             }
             public void actionPerformed(ActionEvent e) {
                 onNextButton();
@@ -232,7 +232,7 @@ class MultiDiffPanel extends javax.swing.JPanel implements ActionListener, DiffS
         prevAction = new AbstractAction(null, new javax.swing.ImageIcon(getClass().getResource(&quot;/org/nbgit/resources/icons/diff-prev.png&quot;))) { // NOI18N
             {
                 putValue(Action.SHORT_DESCRIPTION, java.util.ResourceBundle.getBundle(&quot;org/nbgit/ui/diff/Bundle&quot;).
-                                                   getString(&quot;CTL_DiffPanel_Prev_Tooltip&quot;));                
+                                                   getString(&quot;CTL_DiffPanel_Prev_Tooltip&quot;));
             }
             public void actionPerformed(ActionEvent e) {
                 onPrevButton();
@@ -241,7 +241,7 @@ class MultiDiffPanel extends javax.swing.JPanel implements ActionListener, DiffS
         nextButton.setAction(nextAction);
         prevButton.setAction(prevAction);
     }
-    
+
     private void refreshComponents() {
         DiffController view = setups != null &amp;&amp; currentModelIndex != -1 ? setups[currentModelIndex].getView() : null;
         int currentDifferenceIndex = view != null ? view.getDifferenceIndex() : -1;
@@ -254,7 +254,7 @@ class MultiDiffPanel extends javax.swing.JPanel implements ActionListener, DiffS
         dividerSet = false;
         updateSplitLocation();
     }
-    
+
     @Override
     public void addNotify() {
         super.addNotify();
@@ -288,13 +288,13 @@ class MultiDiffPanel extends javax.swing.JPanel implements ActionListener, DiffS
         }
         splitPane.setDividerLocation(optimalLocation);
     }
-    
+
     @Override
     public void removeNotify() {
         Git.getInstance().getStatusCache().removePropertyChangeListener(this);
         super.removeNotify();
     }
-    
+
     private boolean affectsView(PropertyChangeEvent event) {
         StatusCache.ChangedEvent changedEvent = (StatusCache.ChangedEvent) event.getNewValue();
         File file = changedEvent.getFile();
@@ -307,11 +307,11 @@ class MultiDiffPanel extends javax.swing.JPanel implements ActionListener, DiffS
         }
         return context == null? false: context.contains(file);
     }
-    
+
     private void setDiffIndex(int idx, int location) {
         currentIndex = idx;
         DiffController view = null;
-        
+
         if (currentIndex != -1) {
             currentModelIndex = showingFileTable() ? fileTable.getModelIndex(currentIndex) : 0;
             view = setups[currentModelIndex].getView();
@@ -329,7 +329,7 @@ class MultiDiffPanel extends javax.swing.JPanel implements ActionListener, DiffS
                 }
                 tc.setActivatedNodes(new Node[] {node});
             }
-            
+
             diffView = null;
             boolean focus = false;
             if (view != null) {
@@ -354,7 +354,7 @@ class MultiDiffPanel extends javax.swing.JPanel implements ActionListener, DiffS
                 }
             } else {
                 diffView = new NoContentPanel(NbBundle.getMessage(MultiDiffPanel.class, &quot;MSG_DiffPanel_NoContent&quot;));
-            }            
+            }
         } else {
             currentModelIndex = -1;
             diffView = new NoContentPanel(NbBundle.getMessage(MultiDiffPanel.class, &quot;MSG_DiffPanel_NoFileSelected&quot;));
@@ -393,28 +393,28 @@ class MultiDiffPanel extends javax.swing.JPanel implements ActionListener, DiffS
             executeStatusSupport.cancel();
             executeStatusSupport = null;
         }
-        
+
         LifecycleManager.getDefault().saveAll();
         RequestProcessor rp = Git.getInstance().getRequestProcessor();
         executeStatusSupport = new GitProgressSupport() {
-            public void perform() {                                                
+            public void perform() {
                 StatusAction.executeStatus(context, this);
                 SwingUtilities.invokeLater(new Runnable() {
                     public void run() {
                         refreshSetups();
                     }
-                    
+
                 });
             }
         };
         String repository = GitUtils.getRootPath(context);
         executeStatusSupport.start(rp, repository, NbBundle.getMessage(MultiDiffPanel.class, &quot;MSG_Refresh_Progress&quot;));
-    }                    
+    }
 
     private void onUpdateButton() {
         UpdateAction.update(context);
     }
-    
+
     private void onCommitButton() {
         LifecycleManager.getDefault().saveAll();
         CommitAction.commit(contextName, context);
@@ -497,16 +497,16 @@ class MultiDiffPanel extends javax.swing.JPanel implements ActionListener, DiffS
             displayStatuses = StatusInfo.STATUS_LOCAL_CHANGE;
             break;
         case Setup.DIFFTYPE_REMOTE:
-            displayStatuses = StatusInfo.STATUS_REMOTE_CHANGE; 
+            displayStatuses = StatusInfo.STATUS_REMOTE_CHANGE;
             break;
         case Setup.DIFFTYPE_ALL:
-            displayStatuses = StatusInfo.STATUS_LOCAL_CHANGE | StatusInfo.STATUS_REMOTE_CHANGE; 
+            displayStatuses = StatusInfo.STATUS_LOCAL_CHANGE | StatusInfo.STATUS_REMOTE_CHANGE;
             break;
         default:
             throw new IllegalStateException(&quot;Unknown DIFF type:&quot; + currentType); // NOI18N
         }
         files = GitUtils.getModifiedFiles(context, displayStatuses);
-        
+
         setups = computeSetups(files);
         boolean propertyColumnVisible = false;
         for (Setup setup : setups) {
@@ -515,7 +515,7 @@ class MultiDiffPanel extends javax.swing.JPanel implements ActionListener, DiffS
                 break;
             }
         }
-        fileTable.setColumns(propertyColumnVisible ? 
+        fileTable.setColumns(propertyColumnVisible ?
                 new String[] { DiffNode.COLUMN_NAME_NAME, DiffNode.COLUMN_NAME_PROPERTY, DiffNode.COLUMN_NAME_STATUS, DiffNode.COLUMN_NAME_LOCATION } :
                 new String[] { DiffNode.COLUMN_NAME_NAME, DiffNode.COLUMN_NAME_STATUS, DiffNode.COLUMN_NAME_LOCATION }
         );
@@ -594,7 +594,7 @@ class MultiDiffPanel extends javax.swing.JPanel implements ActionListener, DiffS
     }
 
     private class DiffPrepareTask implements Runnable {
-        
+
         private final Setup[] prepareSetups;
 
         public DiffPrepareTask(Setup [] prepareSetups) {
@@ -656,7 +656,7 @@ class MultiDiffPanel extends javax.swing.JPanel implements ActionListener, DiffS
             });
         }
     }
-    
+
     /** This method is called from within the constructor to
      * initialize the form.
      * WARNING: Do NOT modify this code. The content of this method is
@@ -828,8 +828,8 @@ class MultiDiffPanel extends javax.swing.JPanel implements ActionListener, DiffS
     private void refreshButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_refreshButtonActionPerformed
         onRefreshButton();
     }//GEN-LAST:event_refreshButtonActionPerformed
-    
-    
+
+
     // Variables declaration - do not modify//GEN-BEGIN:variables
     private javax.swing.JButton commitButton;
     private javax.swing.JToolBar controlsToolBar;
@@ -844,7 +844,7 @@ class MultiDiffPanel extends javax.swing.JPanel implements ActionListener, DiffS
     private javax.swing.JSplitPane splitPane;
     private javax.swing.JButton updateButton;
     // End of variables declaration//GEN-END:variables
-    
+
     /** Interprets property blob. */
     static final class Property {
         final byte[] value;
@@ -853,7 +853,7 @@ class MultiDiffPanel extends javax.swing.JPanel implements ActionListener, DiffS
             this.value = (byte[]) value;
         }
 
-        String getMIME() {            
+        String getMIME() {
             return &quot;text/plain&quot;; // NOI18N
         }
 </diff>
      <filename>src/org/nbgit/ui/diff/MultiDiffPanel.java</filename>
    </modified>
    <modified>
      <diff>@@ -61,223 +61,223 @@ import org.openide.util.NbBundle;
  */
 public final class Setup {
 
-	/**
-	 * What was locally changed? The right pane contains local file.
-	 *
-	 * &lt;p&gt;Local addition, removal or change is displayed in
-	 * the right pane as addition, removal or change respectively
-	 * (i.e. not reversed as removal, addition or change).
-	 *
-	 * &lt;pre&gt;
-	 * diff from-BASE to-LOCAL
-	 * &lt;/pre&gt;
-	 */
-	public static final int DIFFTYPE_LOCAL = 0;
-	/**
-	 * What was remotely changed? The right pane contains remote file.
-	 *
-	 * &lt;p&gt;Remote addition, removal or change is displayed in
-	 * the right pane as addition, removal or change respectively
-	 * (i.e. not reversed as removal, addition or change).
-	 *
-	 * &lt;pre&gt;
-	 * diff from-BASE to-HEAD
-	 * &lt;/pre&gt;
-	 */
-	public static final int DIFFTYPE_REMOTE = 1;
-	/**
-	 * What was locally changed comparing to recent head?
-	 * The Right pane contains local file.
-	 *
-	 * &lt;p&gt; Local addition, removal or change is displayed in
-	 * the right pane as addition, removal or change respectively
-	 * (i.e. not reversed as removal, addition or change).
-	 *
-	 * &lt;pre&gt;
-	 * diff from-HEAD to-LOCAL
-	 * &lt;/pre&gt;
-	 */
-	public static final int DIFFTYPE_ALL = 2;
-	private final File baseFile;
-	/**
-	 * Name of the file's property if the setup represents a property diff setup, null otherwise.
-	 */
-	private final String propertyName;
-	private final String firstRevision;
-	private final String secondRevision;
-	private StatusInfo info;
-	private DiffStreamSource firstSource;
-	private DiffStreamSource secondSource;
-	private DiffController view;
-	private DiffNode node;
-	private String title;
-
-	public Setup(File baseFile, String propertyName, int type)
-	{
-		this.baseFile = baseFile;
-		this.propertyName = propertyName;
-		info = Git.getInstance().getStatusCache().getStatus(baseFile);
-		int status = info.getStatus();
-
-		ResourceBundle loc = NbBundle.getBundle(Setup.class);
-		String firstTitle;
-		String secondTitle;
-
-		// the first source
-
-		switch (type) {
-		case DIFFTYPE_LOCAL:
-
-			// from-BASE
-
-			if (match(status, StatusInfo.STATUS_NOTVERSIONED_NEWLOCALLY | StatusInfo.STATUS_VERSIONED_ADDEDLOCALLY)) {
-				firstRevision = GitRepository.REVISION_BASE;
-
-				firstTitle = loc.getString(&quot;MSG_DiffPanel_LocalNew&quot;); // NOI18N
-
-			} else if (match(status, StatusInfo.STATUS_VERSIONED_NEWINREPOSITORY)) {
-				firstRevision = null;
-				firstTitle = NbBundle.getMessage(Setup.class, &quot;LBL_Diff_NoLocalFile&quot;); // NOI18N
-
-			} else if (match(status, StatusInfo.STATUS_VERSIONED_DELETEDLOCALLY | StatusInfo.STATUS_VERSIONED_REMOVEDLOCALLY)) {
-				firstRevision = GitRepository.REVISION_BASE;
-				firstTitle = MessageFormat.format(loc.getString(&quot;MSG_DiffPanel_BaseRevision&quot;), new Object[]{firstRevision}); // NOI18N
-
-			} else {
-				firstRevision = GitRepository.REVISION_BASE;
-				firstTitle = MessageFormat.format(loc.getString(&quot;MSG_DiffPanel_BaseRevision&quot;), new Object[]{firstRevision}); // NOI18N
-
-			}
-
-			break;
-
-		default:
-			throw new IllegalArgumentException(&quot;Unknow diff type: &quot; + type); // NOI18N
-
-		}
-
-
-		// the second source
-
-		switch (type) {
-		case DIFFTYPE_LOCAL:
-
-			// to-LOCAL
-
-			if (match(status, StatusInfo.STATUS_VERSIONED_CONFLICT)) {
-				secondRevision = GitRepository.REVISION_CURRENT;
-				secondTitle = MessageFormat.format(loc.getString(&quot;MSG_DiffPanel_LocalConflict&quot;), new Object[]{secondRevision}); // NOI18N
-
-			} else if (match(status, StatusInfo.STATUS_NOTVERSIONED_NEWLOCALLY | StatusInfo.STATUS_VERSIONED_ADDEDLOCALLY)) {
-				secondRevision = GitRepository.REVISION_CURRENT;
-				secondTitle = loc.getString(&quot;MSG_DiffPanel_LocalNew&quot;); // NOI18N
-
-			} else if (match(status, StatusInfo.STATUS_VERSIONED_NEWINREPOSITORY)) {
-				secondRevision = null;
-				secondTitle = NbBundle.getMessage(Setup.class, &quot;LBL_Diff_NoLocalFile&quot;); // NOI18N
-
-			} else if (match(status, StatusInfo.STATUS_VERSIONED_DELETEDLOCALLY | StatusInfo.STATUS_VERSIONED_REMOVEDLOCALLY)) {
-				secondRevision = null;
-				secondTitle = loc.getString(&quot;MSG_DiffPanel_LocalDeleted&quot;); // NOI18N
-
-			} else {
-				secondRevision = GitRepository.REVISION_CURRENT;
-				secondTitle = MessageFormat.format(loc.getString(&quot;MSG_DiffPanel_LocalModified&quot;), new Object[]{secondRevision}); // NOI18N
-
-			}
-			break;
-
-		default:
-			throw new IllegalArgumentException(&quot;Unknow diff type: &quot; + type); // NOI18N
-
-		}
-
-		firstSource = new DiffStreamSource(baseFile, firstRevision, firstTitle);
-		secondSource = new DiffStreamSource(baseFile, secondRevision, secondTitle);
-		title = &quot;&lt;html&gt;&quot; + HtmlFormatter.getInstance().annotateNameHtml(baseFile, info); // NOI18N
-
-	}
-
-	/**
-	 * Text file setup for arbitrary revisions.
-	 * @param firstRevision first revision or &lt;code&gt;null&lt;/code&gt; for inital.
-	 * @param secondRevision second revision
-	 */
-	public Setup(File baseFile, String firstRevision, String secondRevision)
-	{
-		this.baseFile = baseFile;
-		this.propertyName = null;
-		this.firstRevision = firstRevision;
-		this.secondRevision = secondRevision;
-		firstSource = new DiffStreamSource(baseFile, firstRevision, firstRevision);
-		secondSource = new DiffStreamSource(baseFile, secondRevision, secondRevision);
-	}
-
-	public String getPropertyName()
-	{
-		return propertyName;
-	}
+    /**
+     * What was locally changed? The right pane contains local file.
+     *
+     * &lt;p&gt;Local addition, removal or change is displayed in
+     * the right pane as addition, removal or change respectively
+     * (i.e. not reversed as removal, addition or change).
+     *
+     * &lt;pre&gt;
+     * diff from-BASE to-LOCAL
+     * &lt;/pre&gt;
+     */
+    public static final int DIFFTYPE_LOCAL = 0;
+    /**
+     * What was remotely changed? The right pane contains remote file.
+     *
+     * &lt;p&gt;Remote addition, removal or change is displayed in
+     * the right pane as addition, removal or change respectively
+     * (i.e. not reversed as removal, addition or change).
+     *
+     * &lt;pre&gt;
+     * diff from-BASE to-HEAD
+     * &lt;/pre&gt;
+     */
+    public static final int DIFFTYPE_REMOTE = 1;
+    /**
+     * What was locally changed comparing to recent head?
+     * The Right pane contains local file.
+     *
+     * &lt;p&gt; Local addition, removal or change is displayed in
+     * the right pane as addition, removal or change respectively
+     * (i.e. not reversed as removal, addition or change).
+     *
+     * &lt;pre&gt;
+     * diff from-HEAD to-LOCAL
+     * &lt;/pre&gt;
+     */
+    public static final int DIFFTYPE_ALL = 2;
+    private final File baseFile;
+    /**
+     * Name of the file's property if the setup represents a property diff setup, null otherwise.
+     */
+    private final String propertyName;
+    private final String firstRevision;
+    private final String secondRevision;
+    private StatusInfo info;
+    private DiffStreamSource firstSource;
+    private DiffStreamSource secondSource;
+    private DiffController view;
+    private DiffNode node;
+    private String title;
+
+    public Setup(File baseFile, String propertyName, int type)
+    {
+        this.baseFile = baseFile;
+        this.propertyName = propertyName;
+        info = Git.getInstance().getStatusCache().getStatus(baseFile);
+        int status = info.getStatus();
+
+        ResourceBundle loc = NbBundle.getBundle(Setup.class);
+        String firstTitle;
+        String secondTitle;
+
+        // the first source
+
+        switch (type) {
+        case DIFFTYPE_LOCAL:
+
+            // from-BASE
+
+            if (match(status, StatusInfo.STATUS_NOTVERSIONED_NEWLOCALLY | StatusInfo.STATUS_VERSIONED_ADDEDLOCALLY)) {
+                firstRevision = GitRepository.REVISION_BASE;
+
+                firstTitle = loc.getString(&quot;MSG_DiffPanel_LocalNew&quot;); // NOI18N
+
+            } else if (match(status, StatusInfo.STATUS_VERSIONED_NEWINREPOSITORY)) {
+                firstRevision = null;
+                firstTitle = NbBundle.getMessage(Setup.class, &quot;LBL_Diff_NoLocalFile&quot;); // NOI18N
+
+            } else if (match(status, StatusInfo.STATUS_VERSIONED_DELETEDLOCALLY | StatusInfo.STATUS_VERSIONED_REMOVEDLOCALLY)) {
+                firstRevision = GitRepository.REVISION_BASE;
+                firstTitle = MessageFormat.format(loc.getString(&quot;MSG_DiffPanel_BaseRevision&quot;), new Object[]{firstRevision}); // NOI18N
+
+            } else {
+                firstRevision = GitRepository.REVISION_BASE;
+                firstTitle = MessageFormat.format(loc.getString(&quot;MSG_DiffPanel_BaseRevision&quot;), new Object[]{firstRevision}); // NOI18N
+
+            }
+
+            break;
+
+        default:
+            throw new IllegalArgumentException(&quot;Unknow diff type: &quot; + type); // NOI18N
+
+        }
+
+
+        // the second source
+
+        switch (type) {
+        case DIFFTYPE_LOCAL:
+
+            // to-LOCAL
+
+            if (match(status, StatusInfo.STATUS_VERSIONED_CONFLICT)) {
+                secondRevision = GitRepository.REVISION_CURRENT;
+                secondTitle = MessageFormat.format(loc.getString(&quot;MSG_DiffPanel_LocalConflict&quot;), new Object[]{secondRevision}); // NOI18N
+
+            } else if (match(status, StatusInfo.STATUS_NOTVERSIONED_NEWLOCALLY | StatusInfo.STATUS_VERSIONED_ADDEDLOCALLY)) {
+                secondRevision = GitRepository.REVISION_CURRENT;
+                secondTitle = loc.getString(&quot;MSG_DiffPanel_LocalNew&quot;); // NOI18N
+
+            } else if (match(status, StatusInfo.STATUS_VERSIONED_NEWINREPOSITORY)) {
+                secondRevision = null;
+                secondTitle = NbBundle.getMessage(Setup.class, &quot;LBL_Diff_NoLocalFile&quot;); // NOI18N
+
+            } else if (match(status, StatusInfo.STATUS_VERSIONED_DELETEDLOCALLY | StatusInfo.STATUS_VERSIONED_REMOVEDLOCALLY)) {
+                secondRevision = null;
+                secondTitle = loc.getString(&quot;MSG_DiffPanel_LocalDeleted&quot;); // NOI18N
+
+            } else {
+                secondRevision = GitRepository.REVISION_CURRENT;
+                secondTitle = MessageFormat.format(loc.getString(&quot;MSG_DiffPanel_LocalModified&quot;), new Object[]{secondRevision}); // NOI18N
+
+            }
+            break;
+
+        default:
+            throw new IllegalArgumentException(&quot;Unknow diff type: &quot; + type); // NOI18N
+
+        }
+
+        firstSource = new DiffStreamSource(baseFile, firstRevision, firstTitle);
+        secondSource = new DiffStreamSource(baseFile, secondRevision, secondTitle);
+        title = &quot;&lt;html&gt;&quot; + HtmlFormatter.getInstance().annotateNameHtml(baseFile, info); // NOI18N
+
+    }
+
+    /**
+     * Text file setup for arbitrary revisions.
+     * @param firstRevision first revision or &lt;code&gt;null&lt;/code&gt; for inital.
+     * @param secondRevision second revision
+     */
+    public Setup(File baseFile, String firstRevision, String secondRevision)
+    {
+        this.baseFile = baseFile;
+        this.propertyName = null;
+        this.firstRevision = firstRevision;
+        this.secondRevision = secondRevision;
+        firstSource = new DiffStreamSource(baseFile, firstRevision, firstRevision);
+        secondSource = new DiffStreamSource(baseFile, secondRevision, secondRevision);
+    }
+
+    public String getPropertyName()
+    {
+        return propertyName;
+    }
 
-	public File getBaseFile()
-	{
-		return baseFile;
-	}
+    public File getBaseFile()
+    {
+        return baseFile;
+    }
 
-	public StatusInfo getInfo()
-	{
-		return info;
-	}
-
-	public void setView(DiffController view)
-	{
-		this.view = view;
-	}
-
-	public DiffController getView()
-	{
-		return view;
-	}
-
-	public StreamSource getFirstSource()
-	{
-		return firstSource;
-	}
-
-	public StreamSource getSecondSource()
-	{
-		return secondSource;
-	}
-
-	public void setNode(DiffNode node)
-	{
-		this.node = node;
-	}
-
-	public DiffNode getNode()
-	{
-		return node;
-	}
-
-	public String toString()
-	{
-		return title;
-	}
-
-	/**
-	 * Loads data
-	 * @param group that carries shared state. Note that this group must not be executed later on. 
-	 */
-	void initSources() throws IOException
-	{
-		if (firstSource != null)
-			firstSource.init();
-		if (secondSource != null)
-			secondSource.init();
-	}
-
-	private static boolean match(int status, int mask)
-	{
-		return (status &amp; mask) != 0;
-	}
+    public StatusInfo getInfo()
+    {
+        return info;
+    }
+
+    public void setView(DiffController view)
+    {
+        this.view = view;
+    }
+
+    public DiffController getView()
+    {
+        return view;
+    }
+
+    public StreamSource getFirstSource()
+    {
+        return firstSource;
+    }
+
+    public StreamSource getSecondSource()
+    {
+        return secondSource;
+    }
+
+    public void setNode(DiffNode node)
+    {
+        this.node = node;
+    }
+
+    public DiffNode getNode()
+    {
+        return node;
+    }
+
+    public String toString()
+    {
+        return title;
+    }
+
+    /**
+     * Loads data
+     * @param group that carries shared state. Note that this group must not be executed later on.
+     */
+    void initSources() throws IOException
+    {
+        if (firstSource != null)
+            firstSource.init();
+        if (secondSource != null)
+            secondSource.init();
+    }
+
+    private static boolean match(int status, int mask)
+    {
+        return (status &amp; mask) != 0;
+    }
 
 }</diff>
      <filename>src/org/nbgit/ui/diff/Setup.java</filename>
    </modified>
    <modified>
      <diff>@@ -67,18 +67,18 @@ public class VerticalFlowLayout implements LayoutManager {
     public VerticalFlowLayout(Component parent) {
         this.parent = parent;
     }
-    
+
     public void addLayoutComponent(String name, Component comp) {
     }
-    
+
     public void removeLayoutComponent(Component comp) {
     }
-    
+
     public Dimension preferredLayoutSize(Container target) {
         synchronized (target.getTreeLock()) {
             Dimension dim = new Dimension(0, 0);
             int nmembers = target.getComponentCount();
-            
+
             for (int i = 0 ; i &lt; nmembers ; i++) {
                 Component m = target.getComponent(i);
                 if (m.isVisible()) {
@@ -93,12 +93,12 @@ public class VerticalFlowLayout implements LayoutManager {
             return dim;
         }
     }
-    
+
     public Dimension minimumLayoutSize(Container target) {
         synchronized (target.getTreeLock()) {
             Dimension dim = new Dimension(0, 0);
             int nmembers = target.getComponentCount();
-            
+
             for (int i = 0 ; i &lt; nmembers ; i++) {
                 Component m = target.getComponent(i);
                 if (m.isVisible()) {
@@ -113,15 +113,15 @@ public class VerticalFlowLayout implements LayoutManager {
             return dim;
         }
     }
-    
+
     public void layoutContainer(Container target) {
-        
+
         synchronized (target.getTreeLock()) {
             Insets insets = target.getInsets();
             int maxwidth = parent.getWidth() - (insets.left + insets.right);
             int nmembers = target.getComponentCount();
             int x = insets.left, y = insets.top;
-            
+
             for (int i = 0 ; i &lt; nmembers ; i++) {
                 Component m = target.getComponent(i);
                 if (m.isVisible()) {
@@ -133,5 +133,5 @@ public class VerticalFlowLayout implements LayoutManager {
             }
         }
     }
-    
+
 }
\ No newline at end of file</diff>
      <filename>src/org/nbgit/ui/diff/VerticalFlowLayout.java</filename>
    </modified>
    <modified>
      <diff>@@ -69,213 +69,213 @@ import org.spearce.jgit.treewalk.FileTreeIterator;
 import org.spearce.jgit.treewalk.TreeWalk;
 
 /**
- * Create action for Git: 
+ * Create action for Git:
  * git init - create a new repository in the given directory
- * 
+ *
  * @author John Rice
  */
 public class InitAction extends ContextAction {
 
-	public InitAction(String name, VCSContext context)
-	{
-		super(name, context);
-	}
-
-	@Override
-	public boolean isEnabled()
-	{
-		// If it is not a Git managed repository enable action
-		File root = GitUtils.getRootFile(context);
-		File[] files = context.getRootFiles().toArray(new File[context.getRootFiles().size()]);
-		if (files == null || files.length == 0) {
-			return false;
-		}
-		if (root == null) {
-			return true;
-		} else {
-			return false;
-		}
-	}
-
-	private File getCommonAncestor(File firstFile, File secondFile)
-	{
-		if (firstFile.equals(secondFile)) {
-			return firstFile;
-		}
-		File tempFirstFile = firstFile;
-		while (tempFirstFile != null) {
-			File tempSecondFile = secondFile;
-			while (tempSecondFile != null) {
-				if (tempFirstFile.equals(tempSecondFile)) {
-					return tempSecondFile;
-				}
-				tempSecondFile = tempSecondFile.getParentFile();
-			}
-			tempFirstFile = tempFirstFile.getParentFile();
-		}
-		return null;
-	}
-
-	private File getCommonAncestor(File[] files)
-	{
-		File f1 = files[0];
-
-		for (int i = 1; i &lt; files.length; i++) {
-			f1 = getCommonAncestor(f1, files[i]);
-			if (f1 == null) {
-				Git.LOG.log(Level.SEVERE, &quot;Unable to get common parent of {0} and {1} &quot;, // NOI18N
-					new Object[]{f1.getAbsolutePath(), files[i].getAbsolutePath()});
-			}
-		}
-		return f1;
-	}
-
-	public void performAction(ActionEvent e)
-	{
-		final Git git = Git.getInstance();
-
-		File[] files = context.getRootFiles().toArray(new File[context.getRootFiles().size()]);
-		if (files == null || files.length == 0) {
-			return;		// If there is a .git directory in an ancestor of any of the files in 
-		// the context we fail.
-		}
-		for (File file : files) {
-			if (!file.isDirectory()) {
-				file = file.getParentFile();
-			}
-			if (git.getTopmostManagedParent(file) != null) {
-				Git.LOG.log(Level.SEVERE, &quot;Found .git directory in ancestor of {0} &quot;, // NOI18N
-					file);
-				return;
-			}
-		}
-
-		final Project proj = GitUtils.getProject(context);
-		File projFile = GitUtils.getProjectFile(proj);
-
-		if (projFile == null) {
-			OutputLogger logger = OutputLogger.getLogger(Git.GIT_OUTPUT_TAB_TITLE);
-			logger.outputInRed(NbBundle.getMessage(InitAction.class, &quot;MSG_CREATE_TITLE&quot;)); // NOI18N
-			logger.outputInRed(NbBundle.getMessage(InitAction.class, &quot;MSG_CREATE_TITLE_SEP&quot;)); // NOI18N
-			logger.outputInRed(
-				NbBundle.getMessage(InitAction.class, &quot;MSG_CREATE_NOT_SUPPORTED_INVIEW_INFO&quot;)); // NOI18N
-			logger.output(&quot;&quot;); // NOI18N
-			JOptionPane.showMessageDialog(null,
-				NbBundle.getMessage(InitAction.class, &quot;MSG_CREATE_NOT_SUPPORTED_INVIEW&quot;),// NOI18N
-				NbBundle.getMessage(InitAction.class, &quot;MSG_CREATE_NOT_SUPPORTED_INVIEW_TITLE&quot;),// NOI18N
-				JOptionPane.INFORMATION_MESSAGE);
-			logger.closeLog();
-			return;
-		}
-		String projName = GitProjectUtils.getProjectName(projFile);
-
-		File rootDir = getCommonAncestor(files);
-		final File root = getCommonAncestor(rootDir, projFile);
-		if (root == null) {
-			return;
-		}
-		final String prjName = projName;
-		final Repository repo = git.getRepository(root);
-
-		RequestProcessor rp = git.getRequestProcessor(root.getAbsolutePath());
-
-		GitProgressSupport supportCreate = new GitProgressSupport() {
-
-			public void perform()
-			{
-				try {
-					OutputLogger logger = getLogger();
-					logger.outputInRed(
-						NbBundle.getMessage(InitAction.class,
-						&quot;MSG_CREATE_TITLE&quot;)); // NOI18N
-					logger.outputInRed(
-						NbBundle.getMessage(InitAction.class,
-						&quot;MSG_CREATE_TITLE_SEP&quot;)); // NOI18N
-					logger.output(
-						NbBundle.getMessage(InitAction.class,
-						&quot;MSG_CREATE_INIT&quot;, prjName, root)); // NOI18N
-
-					repo.create();
-					git.versionedFilesChanged();
-					git.refreshAllAnnotations();
-				} catch (IOException ex) {
-					NotifyDescriptor.Exception e = new NotifyDescriptor.Exception(ex);
-					DialogDisplayer.getDefault().notifyLater(e);
-				}
-			}
-		};
-		supportCreate.start(rp, root.getAbsolutePath(),
-			org.openide.util.NbBundle.getMessage(InitAction.class, &quot;MSG_Create_Progress&quot;)); // NOI18N
-
-		GitProgressSupport supportAdd = new GitProgressSupport() {
-
-			public void perform()
-			{
-				OutputLogger logger = getLogger();
-				try {
-					GitIndex index = repo.getIndex();
-					int newFiles = 0;
-
-					for (File file : getFileList(repo, root)) {
-						Entry entry = index.add(root, file);
-
-						entry.setAssumeValid(false);
-						newFiles++;
-
-						if (newFiles &lt; OutputLogger.MAX_LINES_TO_PRINT) {
-							logger.output(&quot;\t&quot; + file.getAbsolutePath()); // NOI18N
-						}
-					}
-
-					logger.output(
-						NbBundle.getMessage(InitAction.class,
-						&quot;MSG_CREATE_ADD&quot;, newFiles, root.getAbsolutePath())); // NOI18N
-
-					if (newFiles &gt; 0) {
-						index.write();
-					}
-					logger.output(&quot;&quot;); // NOI18N
-					logger.outputInRed(NbBundle.getMessage(InitAction.class, &quot;MSG_CREATE_DONE_WARNING&quot;)); // NOI18N
-				} catch (IOException ex) {
-					NotifyDescriptor.Exception e = new NotifyDescriptor.Exception(ex);
-					DialogDisplayer.getDefault().notifyLater(e);
-				} finally {
-					logger.outputInRed(NbBundle.getMessage(InitAction.class, &quot;MSG_CREATE_DONE&quot;)); // NOI18N
-					logger.output(&quot;&quot;); // NOI18N
-				}
-			}
-		};
-
-		supportAdd.start(rp, root.getAbsolutePath(),
-			org.openide.util.NbBundle.getMessage(InitAction.class, &quot;MSG_Create_Add_Progress&quot;)); // NOI18N
-	}
-
-	private List&lt;File&gt; getFileList(Repository repo, File rootFile) throws IOException
-	{
-		final FileTreeIterator workTree = new FileTreeIterator(rootFile);
-		final TreeWalk walk = new TreeWalk(repo);
-		final List&lt;File&gt; files = new ArrayList&lt;File&gt;();
-		int share = SharabilityQuery.getSharability(rootFile);
-
-		if (share == SharabilityQuery.NOT_SHARABLE)
-			return files;
-
-		walk.reset(); // drop the first empty tree, which we do not need here
-		walk.setRecursive(true);
-		walk.addTree(workTree);
-
-		while (walk.next()) {
-			String path = walk.getPathString();
-			File file = new File(rootFile, path);
-
-			if (share == SharabilityQuery.MIXED &amp;&amp;
-				!GitIgnore.isSharable(file))
-				continue;
-
-			files.add(file);
-		}
-
-		return files;
-	}
+    public InitAction(String name, VCSContext context)
+    {
+        super(name, context);
+    }
+
+    @Override
+    public boolean isEnabled()
+    {
+        // If it is not a Git managed repository enable action
+        File root = GitUtils.getRootFile(context);
+        File[] files = context.getRootFiles().toArray(new File[context.getRootFiles().size()]);
+        if (files == null || files.length == 0) {
+            return false;
+        }
+        if (root == null) {
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    private File getCommonAncestor(File firstFile, File secondFile)
+    {
+        if (firstFile.equals(secondFile)) {
+            return firstFile;
+        }
+        File tempFirstFile = firstFile;
+        while (tempFirstFile != null) {
+            File tempSecondFile = secondFile;
+            while (tempSecondFile != null) {
+                if (tempFirstFile.equals(tempSecondFile)) {
+                    return tempSecondFile;
+                }
+                tempSecondFile = tempSecondFile.getParentFile();
+            }
+            tempFirstFile = tempFirstFile.getParentFile();
+        }
+        return null;
+    }
+
+    private File getCommonAncestor(File[] files)
+    {
+        File f1 = files[0];
+
+        for (int i = 1; i &lt; files.length; i++) {
+            f1 = getCommonAncestor(f1, files[i]);
+            if (f1 == null) {
+                Git.LOG.log(Level.SEVERE, &quot;Unable to get common parent of {0} and {1} &quot;, // NOI18N
+                    new Object[]{f1.getAbsolutePath(), files[i].getAbsolutePath()});
+            }
+        }
+        return f1;
+    }
+
+    public void performAction(ActionEvent e)
+    {
+        final Git git = Git.getInstance();
+
+        File[] files = context.getRootFiles().toArray(new File[context.getRootFiles().size()]);
+        if (files == null || files.length == 0) {
+            return;     // If there is a .git directory in an ancestor of any of the files in
+        // the context we fail.
+        }
+        for (File file : files) {
+            if (!file.isDirectory()) {
+                file = file.getParentFile();
+            }
+            if (git.getTopmostManagedParent(file) != null) {
+                Git.LOG.log(Level.SEVERE, &quot;Found .git directory in ancestor of {0} &quot;, // NOI18N
+                    file);
+                return;
+            }
+        }
+
+        final Project proj = GitUtils.getProject(context);
+        File projFile = GitUtils.getProjectFile(proj);
+
+        if (projFile == null) {
+            OutputLogger logger = OutputLogger.getLogger(Git.GIT_OUTPUT_TAB_TITLE);
+            logger.outputInRed(NbBundle.getMessage(InitAction.class, &quot;MSG_CREATE_TITLE&quot;)); // NOI18N
+            logger.outputInRed(NbBundle.getMessage(InitAction.class, &quot;MSG_CREATE_TITLE_SEP&quot;)); // NOI18N
+            logger.outputInRed(
+                NbBundle.getMessage(InitAction.class, &quot;MSG_CREATE_NOT_SUPPORTED_INVIEW_INFO&quot;)); // NOI18N
+            logger.output(&quot;&quot;); // NOI18N
+            JOptionPane.showMessageDialog(null,
+                NbBundle.getMessage(InitAction.class, &quot;MSG_CREATE_NOT_SUPPORTED_INVIEW&quot;),// NOI18N
+                NbBundle.getMessage(InitAction.class, &quot;MSG_CREATE_NOT_SUPPORTED_INVIEW_TITLE&quot;),// NOI18N
+                JOptionPane.INFORMATION_MESSAGE);
+            logger.closeLog();
+            return;
+        }
+        String projName = GitProjectUtils.getProjectName(projFile);
+
+        File rootDir = getCommonAncestor(files);
+        final File root = getCommonAncestor(rootDir, projFile);
+        if (root == null) {
+            return;
+        }
+        final String prjName = projName;
+        final Repository repo = git.getRepository(root);
+
+        RequestProcessor rp = git.getRequestProcessor(root.getAbsolutePath());
+
+        GitProgressSupport supportCreate = new GitProgressSupport() {
+
+            public void perform()
+            {
+                try {
+                    OutputLogger logger = getLogger();
+                    logger.outputInRed(
+                        NbBundle.getMessage(InitAction.class,
+                        &quot;MSG_CREATE_TITLE&quot;)); // NOI18N
+                    logger.outputInRed(
+                        NbBundle.getMessage(InitAction.class,
+                        &quot;MSG_CREATE_TITLE_SEP&quot;)); // NOI18N
+                    logger.output(
+                        NbBundle.getMessage(InitAction.class,
+                        &quot;MSG_CREATE_INIT&quot;, prjName, root)); // NOI18N
+
+                    repo.create();
+                    git.versionedFilesChanged();
+                    git.refreshAllAnnotations();
+                } catch (IOException ex) {
+                    NotifyDescriptor.Exception e = new NotifyDescriptor.Exception(ex);
+                    DialogDisplayer.getDefault().notifyLater(e);
+                }
+            }
+        };
+        supportCreate.start(rp, root.getAbsolutePath(),
+            org.openide.util.NbBundle.getMessage(InitAction.class, &quot;MSG_Create_Progress&quot;)); // NOI18N
+
+        GitProgressSupport supportAdd = new GitProgressSupport() {
+
+            public void perform()
+            {
+                OutputLogger logger = getLogger();
+                try {
+                    GitIndex index = repo.getIndex();
+                    int newFiles = 0;
+
+                    for (File file : getFileList(repo, root)) {
+                        Entry entry = index.add(root, file);
+
+                        entry.setAssumeValid(false);
+                        newFiles++;
+
+                        if (newFiles &lt; OutputLogger.MAX_LINES_TO_PRINT) {
+                            logger.output(&quot;\t&quot; + file.getAbsolutePath()); // NOI18N
+                        }
+                    }
+
+                    logger.output(
+                        NbBundle.getMessage(InitAction.class,
+                        &quot;MSG_CREATE_ADD&quot;, newFiles, root.getAbsolutePath())); // NOI18N
+
+                    if (newFiles &gt; 0) {
+                        index.write();
+                    }
+                    logger.output(&quot;&quot;); // NOI18N
+                    logger.outputInRed(NbBundle.getMessage(InitAction.class, &quot;MSG_CREATE_DONE_WARNING&quot;)); // NOI18N
+                } catch (IOException ex) {
+                    NotifyDescriptor.Exception e = new NotifyDescriptor.Exception(ex);
+                    DialogDisplayer.getDefault().notifyLater(e);
+                } finally {
+                    logger.outputInRed(NbBundle.getMessage(InitAction.class, &quot;MSG_CREATE_DONE&quot;)); // NOI18N
+                    logger.output(&quot;&quot;); // NOI18N
+                }
+            }
+        };
+
+        supportAdd.start(rp, root.getAbsolutePath(),
+            org.openide.util.NbBundle.getMessage(InitAction.class, &quot;MSG_Create_Add_Progress&quot;)); // NOI18N
+    }
+
+    private List&lt;File&gt; getFileList(Repository repo, File rootFile) throws IOException
+    {
+        final FileTreeIterator workTree = new FileTreeIterator(rootFile);
+        final TreeWalk walk = new TreeWalk(repo);
+        final List&lt;File&gt; files = new ArrayList&lt;File&gt;();
+        int share = SharabilityQuery.getSharability(rootFile);
+
+        if (share == SharabilityQuery.NOT_SHARABLE)
+            return files;
+
+        walk.reset(); // drop the first empty tree, which we do not need here
+        walk.setRecursive(true);
+        walk.addTree(workTree);
+
+        while (walk.next()) {
+            String path = walk.getPathString();
+            File file = new File(rootFile, path);
+
+            if (share == SharabilityQuery.MIXED &amp;&amp;
+                !GitIgnore.isSharable(file))
+                continue;
+
+            files.add(file);
+        }
+
+        return files;
+    }
 
 }
\ No newline at end of file</diff>
      <filename>src/org/nbgit/ui/init/InitAction.java</filename>
    </modified>
    <modified>
      <diff>@@ -70,337 +70,337 @@ import org.openide.windows.TopComponent;
 
 /**
  * Shows Search History results in a table with Diff pane below it.
- * 
+ *
  * @author Maros Sandor
  */
 class DiffResultsView implements AncestorListener, PropertyChangeListener, DiffSetupSource {
 
-	private final SearchHistoryPanel parent;
-	private DiffTreeTable treeView;
-	private JSplitPane diffView;
-	private ShowDiffTask currentTask;
-	private RequestProcessor.Task currentShowDiffTask;
-	private DiffView currentDiff;
-	private int currentDifferenceIndex;
-	private int currentIndex;
-	private boolean dividerSet;
-	private List&lt;RepositoryRevision&gt; results;
-	private static final RequestProcessor rp = new RequestProcessor(&quot;GitDiff&quot;, 1, true);  // NOI18N
-
-	public DiffResultsView(SearchHistoryPanel parent, List&lt;RepositoryRevision&gt; results)
-	{
-		this.parent = parent;
-		this.results = results;
-		treeView = new DiffTreeTable(parent);
-		treeView.setResults(results);
-		treeView.addAncestorListener(this);
-
-		diffView = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
-		diffView.setTopComponent(treeView);
-		setBottomComponent(new NoContentPanel(NbBundle.getMessage(DiffResultsView.class, &quot;MSG_DiffPanel_NoRevisions&quot;))); // NOI18N
-	}
-
-	public void ancestorAdded(AncestorEvent event)
-	{
-		ExplorerManager em = ExplorerManager.find(treeView);
-		em.addPropertyChangeListener(this);
-		if (!dividerSet)
-			SwingUtilities.invokeLater(new Runnable() {
-
-				public void run()
-				{
-					dividerSet = true;
-					diffView.setDividerLocation(0.33);
-				}
-
-			});
-	}
-
-	public void ancestorMoved(AncestorEvent event)
-	{
-	}
-
-	public void ancestorRemoved(AncestorEvent event)
-	{
-		ExplorerManager em = ExplorerManager.find(treeView);
-		em.removePropertyChangeListener(this);
-		cancelBackgroundTasks();
-	}
-
-	public void propertyChange(PropertyChangeEvent evt)
-	{
-		if (ExplorerManager.PROP_SELECTED_NODES.equals(evt.getPropertyName())) {
-			final Node[] nodes = (Node[]) evt.getNewValue();
-			currentDifferenceIndex = 0;
-			if (nodes.length == 0) {
-				showDiffError(NbBundle.getMessage(DiffResultsView.class, &quot;MSG_DiffPanel_NoRevisions&quot;)); // NOI18N
-				parent.refreshComponents(false);
-				return;
-			} else if (nodes.length &gt; 2) {
-				showDiffError(NbBundle.getMessage(DiffResultsView.class, &quot;MSG_DiffPanel_TooManyRevisions&quot;)); // NOI18N
-				parent.refreshComponents(false);
-				return;
-			}
-
-			// invoked asynchronously becase treeView.getSelection() may not be ready yet
-			Runnable runnable = new Runnable() {
-
-				public void run()
-				{
-					RepositoryRevision container1 = nodes[0].getLookup().lookup(RepositoryRevision.class);
-					RepositoryRevision.Event r1 = nodes[0].getLookup().lookup(RepositoryRevision.Event.class);
-					try {
-						currentIndex = treeView.getSelection()[0];
-						if (nodes.length == 1) {
-							if (container1 != null)
-								showContainerDiff(container1, onSelectionshowLastDifference);
-							else if (r1 != null)
-								showRevisionDiff(r1, onSelectionshowLastDifference);
-						} else if (nodes.length == 2) {
-							RepositoryRevision.Event r2 = nodes[1].getLookup().lookup(RepositoryRevision.Event.class);
-							if (r2.getFile() == null || !r2.getFile().equals(r1.getFile()))
-								throw new Exception();
-							showDiff(r1, r1.getLogInfoHeader().getRevision(),
-								r2.getLogInfoHeader().getRevision(), false);
-						}
-					} catch (Exception e) {
-						showDiffError(NbBundle.getMessage(DiffResultsView.class, &quot;MSG_DiffPanel_IllegalSelection&quot;)); // NOI18N
-						parent.refreshComponents(false);
-						return;
-					}
-
-				}
-
-			};
-			SwingUtilities.invokeLater(runnable);
-		}
-	}
-
-	public Collection getSetups()
-	{
-		Node[] nodes = TopComponent.getRegistry().getActivatedNodes();
-		if (nodes.length == 0)
-			return parent.getSetups(results.toArray(new RepositoryRevision[results.size()]), new RepositoryRevision.Event[0]);
-
-		Set&lt;RepositoryRevision.Event&gt; events = new HashSet&lt;RepositoryRevision.Event&gt;();
-		Set&lt;RepositoryRevision&gt; revisions = new HashSet&lt;RepositoryRevision&gt;();
-		for (Node n : nodes) {
-			RevisionNode node = (RevisionNode) n;
-			if (node.getEvent() != null)
-				events.add(node.getEvent());
-			else
-				revisions.add(node.getContainer());
-		}
-		return parent.getSetups(revisions.toArray(new RepositoryRevision[revisions.size()]), events.toArray(new RepositoryRevision.Event[events.size()]));
-	}
-
-	public String getSetupDisplayName()
-	{
-		return null;
-	}
-
-	private void showDiffError(String s)
-	{
-		setBottomComponent(new NoContentPanel(s));
-	}
-
-	private void setBottomComponent(Component component)
-	{
-		int dl = diffView.getDividerLocation();
-		diffView.setBottomComponent(component);
-		diffView.setDividerLocation(dl);
-	}
-
-	private void showDiff(RepositoryRevision.Event header, String revision1, String revision2, boolean showLastDifference)
-	{
-		synchronized (this) {
-			cancelBackgroundTasks();
-			currentTask = new ShowDiffTask(header, revision1, revision2, showLastDifference);
-			currentShowDiffTask = rp.create(currentTask);
-			currentShowDiffTask.schedule(0);
-		}
-	}
-
-	private synchronized void cancelBackgroundTasks()
-	{
-		if (currentShowDiffTask != null &amp;&amp; !currentShowDiffTask.isFinished()) {
-			currentShowDiffTask.cancel();  // it almost always late it's enqueued, so:
-			currentTask.cancel();
-		}
-	}
-
-	private boolean onSelectionshowLastDifference;
-
-	private void setDiffIndex(int idx, boolean showLastDifference)
-	{
-		currentIndex = idx;
-		onSelectionshowLastDifference = showLastDifference;
-		treeView.setSelection(idx);
-	}
-
-	private void showRevisionDiff(RepositoryRevision.Event rev, boolean showLastDifference)
-	{
-		if (rev.getFile() == null)
-			return;
-		String id = rev.getLogInfoHeader().getRevision();
-
-		showDiff(rev, id + &quot;^&quot;, id, showLastDifference);
-	}
-
-	private void showContainerDiff(RepositoryRevision container, boolean showLastDifference)
-	{
-		List&lt;RepositoryRevision.Event&gt; revs = container.getEvents();
-
-		RepositoryRevision.Event newest = null;
-		//try to get the root        
-		File[] roots = parent.getRoots();
-		for (File root : roots) {
-			for (RepositoryRevision.Event evt : revs) {
-				if (root.equals(evt.getFile()))
-					newest = evt;
-			}
-		}
-		if (newest == null)
-			newest = revs.get(0);
-		if (newest.getFile() == null)
-			return;
-		String rev = newest.getLogInfoHeader().getRevision();
-		showDiff(newest, rev + &quot;^&quot;, rev, showLastDifference);
-	}
-
-	void onNextButton()
-	{
-		if (currentDiff != null)
-			if (++currentDifferenceIndex &gt;= currentDiff.getDifferenceCount()) {
-				if (++currentIndex &gt;= treeView.getRowCount())
-					currentIndex = 0;
-				setDiffIndex(currentIndex, false);
-			} else
-				currentDiff.setCurrentDifference(currentDifferenceIndex);
-		else {
-			if (++currentIndex &gt;= treeView.getRowCount())
-				currentIndex = 0;
-			setDiffIndex(currentIndex, false);
-		}
-	}
-
-	void onPrevButton()
-	{
-		if (currentDiff != null)
-			if (--currentDifferenceIndex &lt; 0) {
-				if (--currentIndex &lt; 0)
-					currentIndex = treeView.getRowCount() - 1;
-				setDiffIndex(currentIndex, true);
-			} else
-				currentDiff.setCurrentDifference(currentDifferenceIndex);
-		else {
-			if (--currentIndex &lt; 0)
-				currentIndex = treeView.getRowCount() - 1;
-			setDiffIndex(currentIndex, true);
-		}
-	}
-
-	boolean isNextEnabled()
-	{
-		if (currentDiff != null)
-			return currentIndex &lt; treeView.getRowCount() - 1 || currentDifferenceIndex &lt; currentDiff.getDifferenceCount() - 1;
-		else
-			return false;
-	}
-
-	boolean isPrevEnabled()
-	{
-		return currentIndex &gt; 0 || currentDifferenceIndex &gt; 0;
-	}
-
-	/**
-	 * Selects given revision in the view as if done by the user.
-	 *
-	 * @param revision revision to select
-	 */
-	void select(RepositoryRevision.Event revision)
-	{
-		treeView.requestFocusInWindow();
-		treeView.setSelection(revision);
-	}
-
-	void select(RepositoryRevision container)
-	{
-		treeView.requestFocusInWindow();
-		treeView.setSelection(container);
-	}
-
-	private class ShowDiffTask implements Runnable, Cancellable {
-
-		private final RepositoryRevision.Event header;
-		private final String revision1;
-		private final String revision2;
-		private boolean showLastDifference;
-		private volatile boolean cancelled;
-
-		public ShowDiffTask(RepositoryRevision.Event header, String revision1, String revision2, boolean showLastDifference)
-		{
-			this.header = header;
-			this.revision1 = revision1;
-			this.revision2 = revision2;
-			this.showLastDifference = showLastDifference;
-		}
-
-		public void run()
-		{
-			final Diff diff = Diff.getDefault();
-			final DiffStreamSource s1 = new DiffStreamSource(header.getFile(), revision1, revision1);
-			final DiffStreamSource s2 = new DiffStreamSource(header.getFile(), revision2, revision2);
-
-			// it's enqueued at ClientRuntime queue and does not return until previous request handled
-			s1.getMIMEType();  // triggers s1.init()
-			if (cancelled)
-				return;
-
-			s2.getMIMEType();  // triggers s2.init()
-			if (cancelled)
-				return;
-
-			if (currentTask != this)
-				return;
-
-			SwingUtilities.invokeLater(new Runnable() {
-
-				public void run()
-				{
-					try {
-						if (cancelled)
-							return;
-						final DiffView view = diff.createDiff(s1, s2);
-						if (currentTask == ShowDiffTask.this) {
-							currentDiff = view;
-							setBottomComponent(currentDiff.getComponent());
-							if (currentDiff.getDifferenceCount() &gt; 0) {
-								currentDifferenceIndex = showLastDifference ? currentDiff.getDifferenceCount() - 1 : 0;
-								currentDiff.setCurrentDifference(currentDifferenceIndex);
-							}
-							parent.refreshComponents(false);
-						}
-					} catch (IOException e) {
-						ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e);
-					}
-				}
-
-			});
-		}
-
-		public boolean cancel()
-		{
-			cancelled = true;
-			return true;
-		}
-
-	}
-
-	public JComponent getComponent()
-	{
-		return diffView;
-	}
+    private final SearchHistoryPanel parent;
+    private DiffTreeTable treeView;
+    private JSplitPane diffView;
+    private ShowDiffTask currentTask;
+    private RequestProcessor.Task currentShowDiffTask;
+    private DiffView currentDiff;
+    private int currentDifferenceIndex;
+    private int currentIndex;
+    private boolean dividerSet;
+    private List&lt;RepositoryRevision&gt; results;
+    private static final RequestProcessor rp = new RequestProcessor(&quot;GitDiff&quot;, 1, true);  // NOI18N
+
+    public DiffResultsView(SearchHistoryPanel parent, List&lt;RepositoryRevision&gt; results)
+    {
+        this.parent = parent;
+        this.results = results;
+        treeView = new DiffTreeTable(parent);
+        treeView.setResults(results);
+        treeView.addAncestorListener(this);
+
+        diffView = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
+        diffView.setTopComponent(treeView);
+        setBottomComponent(new NoContentPanel(NbBundle.getMessage(DiffResultsView.class, &quot;MSG_DiffPanel_NoRevisions&quot;))); // NOI18N
+    }
+
+    public void ancestorAdded(AncestorEvent event)
+    {
+        ExplorerManager em = ExplorerManager.find(treeView);
+        em.addPropertyChangeListener(this);
+        if (!dividerSet)
+            SwingUtilities.invokeLater(new Runnable() {
+
+                public void run()
+                {
+                    dividerSet = true;
+                    diffView.setDividerLocation(0.33);
+                }
+
+            });
+    }
+
+    public void ancestorMoved(AncestorEvent event)
+    {
+    }
+
+    public void ancestorRemoved(AncestorEvent event)
+    {
+        ExplorerManager em = ExplorerManager.find(treeView);
+        em.removePropertyChangeListener(this);
+        cancelBackgroundTasks();
+    }
+
+    public void propertyChange(PropertyChangeEvent evt)
+    {
+        if (ExplorerManager.PROP_SELECTED_NODES.equals(evt.getPropertyName())) {
+            final Node[] nodes = (Node[]) evt.getNewValue();
+            currentDifferenceIndex = 0;
+            if (nodes.length == 0) {
+                showDiffError(NbBundle.getMessage(DiffResultsView.class, &quot;MSG_DiffPanel_NoRevisions&quot;)); // NOI18N
+                parent.refreshComponents(false);
+                return;
+            } else if (nodes.length &gt; 2) {
+                showDiffError(NbBundle.getMessage(DiffResultsView.class, &quot;MSG_DiffPanel_TooManyRevisions&quot;)); // NOI18N
+                parent.refreshComponents(false);
+                return;
+            }
+
+            // invoked asynchronously becase treeView.getSelection() may not be ready yet
+            Runnable runnable = new Runnable() {
+
+                public void run()
+                {
+                    RepositoryRevision container1 = nodes[0].getLookup().lookup(RepositoryRevision.class);
+                    RepositoryRevision.Event r1 = nodes[0].getLookup().lookup(RepositoryRevision.Event.class);
+                    try {
+                        currentIndex = treeView.getSelection()[0];
+                        if (nodes.length == 1) {
+                            if (container1 != null)
+                                showContainerDiff(container1, onSelectionshowLastDifference);
+                            else if (r1 != null)
+                                showRevisionDiff(r1, onSelectionshowLastDifference);
+                        } else if (nodes.length == 2) {
+                            RepositoryRevision.Event r2 = nodes[1].getLookup().lookup(RepositoryRevision.Event.class);
+                            if (r2.getFile() == null || !r2.getFile().equals(r1.getFile()))
+                                throw new Exception();
+                            showDiff(r1, r1.getLogInfoHeader().getRevision(),
+                                r2.getLogInfoHeader().getRevision(), false);
+                        }
+                    } catch (Exception e) {
+                        showDiffError(NbBundle.getMessage(DiffResultsView.class, &quot;MSG_DiffPanel_IllegalSelection&quot;)); // NOI18N
+                        parent.refreshComponents(false);
+                        return;
+                    }
+
+                }
+
+            };
+            SwingUtilities.invokeLater(runnable);
+        }
+    }
+
+    public Collection getSetups()
+    {
+        Node[] nodes = TopComponent.getRegistry().getActivatedNodes();
+        if (nodes.length == 0)
+            return parent.getSetups(results.toArray(new RepositoryRevision[results.size()]), new RepositoryRevision.Event[0]);
+
+        Set&lt;RepositoryRevision.Event&gt; events = new HashSet&lt;RepositoryRevision.Event&gt;();
+        Set&lt;RepositoryRevision&gt; revisions = new HashSet&lt;RepositoryRevision&gt;();
+        for (Node n : nodes) {
+            RevisionNode node = (RevisionNode) n;
+            if (node.getEvent() != null)
+                events.add(node.getEvent());
+            else
+                revisions.add(node.getContainer());
+        }
+        return parent.getSetups(revisions.toArray(new RepositoryRevision[revisions.size()]), events.toArray(new RepositoryRevision.Event[events.size()]));
+    }
+
+    public String getSetupDisplayName()
+    {
+        return null;
+    }
+
+    private void showDiffError(String s)
+    {
+        setBottomComponent(new NoContentPanel(s));
+    }
+
+    private void setBottomComponent(Component component)
+    {
+        int dl = diffView.getDividerLocation();
+        diffView.setBottomComponent(component);
+        diffView.setDividerLocation(dl);
+    }
+
+    private void showDiff(RepositoryRevision.Event header, String revision1, String revision2, boolean showLastDifference)
+    {
+        synchronized (this) {
+            cancelBackgroundTasks();
+            currentTask = new ShowDiffTask(header, revision1, revision2, showLastDifference);
+            currentShowDiffTask = rp.create(currentTask);
+            currentShowDiffTask.schedule(0);
+        }
+    }
+
+    private synchronized void cancelBackgroundTasks()
+    {
+        if (currentShowDiffTask != null &amp;&amp; !currentShowDiffTask.isFinished()) {
+            currentShowDiffTask.cancel();  // it almost always late it's enqueued, so:
+            currentTask.cancel();
+        }
+    }
+
+    private boolean onSelectionshowLastDifference;
+
+    private void setDiffIndex(int idx, boolean showLastDifference)
+    {
+        currentIndex = idx;
+        onSelectionshowLastDifference = showLastDifference;
+        treeView.setSelection(idx);
+    }
+
+    private void showRevisionDiff(RepositoryRevision.Event rev, boolean showLastDifference)
+    {
+        if (rev.getFile() == null)
+            return;
+        String id = rev.getLogInfoHeader().getRevision();
+
+        showDiff(rev, id + &quot;^&quot;, id, showLastDifference);
+    }
+
+    private void showContainerDiff(RepositoryRevision container, boolean showLastDifference)
+    {
+        List&lt;RepositoryRevision.Event&gt; revs = container.getEvents();
+
+        RepositoryRevision.Event newest = null;
+        //try to get the root
+        File[] roots = parent.getRoots();
+        for (File root : roots) {
+            for (RepositoryRevision.Event evt : revs) {
+                if (root.equals(evt.getFile()))
+                    newest = evt;
+            }
+        }
+        if (newest == null)
+            newest = revs.get(0);
+        if (newest.getFile() == null)
+            return;
+        String rev = newest.getLogInfoHeader().getRevision();
+        showDiff(newest, rev + &quot;^&quot;, rev, showLastDifference);
+    }
+
+    void onNextButton()
+    {
+        if (currentDiff != null)
+            if (++currentDifferenceIndex &gt;= currentDiff.getDifferenceCount()) {
+                if (++currentIndex &gt;= treeView.getRowCount())
+                    currentIndex = 0;
+                setDiffIndex(currentIndex, false);
+            } else
+                currentDiff.setCurrentDifference(currentDifferenceIndex);
+        else {
+            if (++currentIndex &gt;= treeView.getRowCount())
+                currentIndex = 0;
+            setDiffIndex(currentIndex, false);
+        }
+    }
+
+    void onPrevButton()
+    {
+        if (currentDiff != null)
+            if (--currentDifferenceIndex &lt; 0) {
+                if (--currentIndex &lt; 0)
+                    currentIndex = treeView.getRowCount() - 1;
+                setDiffIndex(currentIndex, true);
+            } else
+                currentDiff.setCurrentDifference(currentDifferenceIndex);
+        else {
+            if (--currentIndex &lt; 0)
+                currentIndex = treeView.getRowCount() - 1;
+            setDiffIndex(currentIndex, true);
+        }
+    }
+
+    boolean isNextEnabled()
+    {
+        if (currentDiff != null)
+            return currentIndex &lt; treeView.getRowCount() - 1 || currentDifferenceIndex &lt; currentDiff.getDifferenceCount() - 1;
+        else
+            return false;
+    }
+
+    boolean isPrevEnabled()
+    {
+        return currentIndex &gt; 0 || currentDifferenceIndex &gt; 0;
+    }
+
+    /**
+     * Selects given revision in the view as if done by the user.
+     *
+     * @param revision revision to select
+     */
+    void select(RepositoryRevision.Event revision)
+    {
+        treeView.requestFocusInWindow();
+        treeView.setSelection(revision);
+    }
+
+    void select(RepositoryRevision container)
+    {
+        treeView.requestFocusInWindow();
+        treeView.setSelection(container);
+    }
+
+    private class ShowDiffTask implements Runnable, Cancellable {
+
+        private final RepositoryRevision.Event header;
+        private final String revision1;
+        private final String revision2;
+        private boolean showLastDifference;
+        private volatile boolean cancelled;
+
+        public ShowDiffTask(RepositoryRevision.Event header, String revision1, String revision2, boolean showLastDifference)
+        {
+            this.header = header;
+            this.revision1 = revision1;
+            this.revision2 = revision2;
+            this.showLastDifference = showLastDifference;
+        }
+
+        public void run()
+        {
+            final Diff diff = Diff.getDefault();
+            final DiffStreamSource s1 = new DiffStreamSource(header.getFile(), revision1, revision1);
+            final DiffStreamSource s2 = new DiffStreamSource(header.getFile(), revision2, revision2);
+
+            // it's enqueued at ClientRuntime queue and does not return until previous request handled
+            s1.getMIMEType();  // triggers s1.init()
+            if (cancelled)
+                return;
+
+            s2.getMIMEType();  // triggers s2.init()
+            if (cancelled)
+                return;
+
+            if (currentTask != this)
+                return;
+
+            SwingUtilities.invokeLater(new Runnable() {
+
+                public void run()
+                {
+                    try {
+                        if (cancelled)
+                            return;
+                        final DiffView view = diff.createDiff(s1, s2);
+                        if (currentTask == ShowDiffTask.this) {
+                            currentDiff = view;
+                            setBottomComponent(currentDiff.getComponent());
+                            if (currentDiff.getDifferenceCount() &gt; 0) {
+                                currentDifferenceIndex = showLastDifference ? currentDiff.getDifferenceCount() - 1 : 0;
+                                currentDiff.setCurrentDifference(currentDifferenceIndex);
+                            }
+                            parent.refreshComponents(false);
+                        }
+                    } catch (IOException e) {
+                        ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e);
+                    }
+                }
+
+            });
+        }
+
+        public boolean cancel()
+        {
+            cancelled = true;
+            return true;
+        }
+
+    }
+
+    public JComponent getComponent()
+    {
+        return diffView;
+    }
 
 }
 </diff>
      <filename>src/org/nbgit/ui/log/DiffResultsView.java</filename>
    </modified>
    <modified>
      <diff>@@ -62,208 +62,208 @@ import org.openide.util.lookup.Lookups;
 
 /**
  * Treetable to show results of Search History action.
- * 
+ *
  * @author Maros Sandor
  */
 class DiffTreeTable extends TreeTableView {
 
-	private RevisionsRootNode rootNode;
-	private List results;
-	private final SearchHistoryPanel master;
-
-	public DiffTreeTable(SearchHistoryPanel master)
-	{
-		this.master = master;
-		treeTable.setShowHorizontalLines(true);
-		treeTable.setShowVerticalLines(false);
-		setRootVisible(false);
-		setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
-		setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
-		setupColumns();
-
-		DefaultTreeCellRenderer renderer = new DefaultTreeCellRenderer();
-		renderer.setOpenIcon(null);
-		renderer.setClosedIcon(null);
-		renderer.setLeafIcon(null);
-		tree.setCellRenderer(renderer);
-	}
-
-	@SuppressWarnings(&quot;unchecked&quot;)
-	private void setupColumns()
-	{
-		Node.Property[] columns = new Node.Property[4];
-		ResourceBundle loc = NbBundle.getBundle(DiffTreeTable.class);
-		columns[0] = new ColumnDescriptor(RevisionNode.COLUMN_NAME_NAME, String.class, &quot;&quot;, &quot;&quot;);  // NOI18N
-		columns[0].setValue(&quot;TreeColumnTTV&quot;, Boolean.TRUE); // NOI18N
-		columns[1] = new ColumnDescriptor(RevisionNode.COLUMN_NAME_DATE, String.class, loc.getString(&quot;LBL_DiffTree_Column_Time&quot;), loc.getString(&quot;LBL_DiffTree_Column_Time_Desc&quot;));
-		columns[2] = new ColumnDescriptor(RevisionNode.COLUMN_NAME_USERNAME, String.class, loc.getString(&quot;LBL_DiffTree_Column_Username&quot;), loc.getString(&quot;LBL_DiffTree_Column_Username_Desc&quot;));
-		columns[3] = new ColumnDescriptor(RevisionNode.COLUMN_NAME_MESSAGE, String.class, loc.getString(&quot;LBL_DiffTree_Column_Message&quot;), loc.getString(&quot;LBL_DiffTree_Column_Message_Desc&quot;));
-		setProperties(columns);
-	}
-
-	private void setDefaultColumnSizes()
-	{
-		SwingUtilities.invokeLater(new Runnable() {
-
-			public void run()
-			{
-				int width = getWidth();
-				treeTable.getColumnModel().getColumn(0).setPreferredWidth(width * 25 / 100);
-				treeTable.getColumnModel().getColumn(1).setPreferredWidth(width * 15 / 100);
-				treeTable.getColumnModel().getColumn(2).setPreferredWidth(width * 10 / 100);
-				treeTable.getColumnModel().getColumn(3).setPreferredWidth(width * 50 / 100);
-			}
-
-		});
-	}
-
-	void setSelection(int idx)
-	{
-		treeTable.getSelectionModel().setValueIsAdjusting(false);
-		treeTable.scrollRectToVisible(treeTable.getCellRect(idx, 1, true));
-		treeTable.getSelectionModel().setSelectionInterval(idx, idx);
-	}
-
-	void setSelection(RepositoryRevision container)
-	{
-		RevisionNode node = (RevisionNode) getNode(rootNode, container);
-		if (node == null)
-			return;
-		ExplorerManager em = ExplorerManager.find(this);
-		try {
-			em.setSelectedNodes(new Node[]{node});
-		} catch (PropertyVetoException e) {
-			ErrorManager.getDefault().notify(e);
-		}
-	}
-
-	void setSelection(RepositoryRevision.Event revision)
-	{
-		RevisionNode node = (RevisionNode) getNode(rootNode, revision);
-		if (node == null)
-			return;
-		ExplorerManager em = ExplorerManager.find(this);
-		try {
-			em.setSelectedNodes(new Node[]{node});
-		} catch (PropertyVetoException e) {
-			ErrorManager.getDefault().notify(e);
-		}
-	}
-
-	private Node getNode(Node node, Object obj)
-	{
-		Object object = node.getLookup().lookup(obj.getClass());
-		if (obj.equals(object))
-			return node;
-		Enumeration children = node.getChildren().nodes();
-		while (children.hasMoreElements()) {
-			Node child = (Node) children.nextElement();
-			Node result = getNode(child, obj);
-			if (result != null)
-				return result;
-		}
-		return null;
-	}
-
-	public int[] getSelection()
-	{
-		return treeTable.getSelectedRows();
-	}
-
-	public int getRowCount()
-	{
-		return treeTable.getRowCount();
-	}
-
-	private static class ColumnDescriptor&lt;T&gt; extends PropertySupport.ReadOnly&lt;T&gt; {
-
-		public ColumnDescriptor(String name, Class&lt;T&gt; type, String displayName, String shortDescription)
-		{
-			super(name, type, displayName, shortDescription);
-		}
-
-		public T getValue() throws IllegalAccessException, InvocationTargetException
-		{
-			return null;
-		}
-
-	}
-
-	public void addNotify()
-	{
-		super.addNotify();
-		ExplorerManager em = ExplorerManager.find(this);
-		em.setRootContext(rootNode);
-		setDefaultColumnSizes();
-	}
-
-	public void setResults(List results)
-	{
-		this.results = results;
-		rootNode = new RevisionsRootNode();
-		ExplorerManager em = ExplorerManager.find(this);
-		if (em != null)
-			em.setRootContext(rootNode);
-	}
-
-	private class RevisionsRootNode extends AbstractNode {
-
-		public RevisionsRootNode()
-		{
-			super(new RevisionsRootNodeChildren(), Lookups.singleton(results));
-		}
-
-		public String getName()
-		{
-			return &quot;revision&quot;; // NOI18N
-		}
-
-		public String getDisplayName()
-		{
-			return NbBundle.getMessage(DiffTreeTable.class, &quot;LBL_DiffTree_Column_Name&quot;); // NOI18N
-		}
-
-		public String getShortDescription()
-		{
-			return NbBundle.getMessage(DiffTreeTable.class, &quot;LBL_DiffTree_Column_Name_Desc&quot;); // NOI18N
-		}
-
-	}
-
-	private class RevisionsRootNodeChildren extends Children.Keys {
-
-		public RevisionsRootNodeChildren()
-		{
-		}
-
-		protected void addNotify()
-		{
-			refreshKeys();
-		}
-
-		@SuppressWarnings(&quot;unchecked&quot;)
-		@Override
-		protected void removeNotify()
-		{
-			setKeys(Collections.EMPTY_SET);
-		}
-
-		@SuppressWarnings(&quot;unchecked&quot;)
-		private void refreshKeys()
-		{
-			setKeys(results);
-		}
-
-		protected Node[] createNodes(Object key)
-		{
-			RevisionNode node;
-			if (key instanceof RepositoryRevision)
-				node = new RevisionNode((RepositoryRevision) key, master);
-			else // key instanceof RepositoryRevision.Event
-				node = new RevisionNode(((RepositoryRevision.Event) key), master);
-			return new Node[]{node};
-		}
-
-	}
+    private RevisionsRootNode rootNode;
+    private List results;
+    private final SearchHistoryPanel master;
+
+    public DiffTreeTable(SearchHistoryPanel master)
+    {
+        this.master = master;
+        treeTable.setShowHorizontalLines(true);
+        treeTable.setShowVerticalLines(false);
+        setRootVisible(false);
+        setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
+        setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
+        setupColumns();
+
+        DefaultTreeCellRenderer renderer = new DefaultTreeCellRenderer();
+        renderer.setOpenIcon(null);
+        renderer.setClosedIcon(null);
+        renderer.setLeafIcon(null);
+        tree.setCellRenderer(renderer);
+    }
+
+    @SuppressWarnings(&quot;unchecked&quot;)
+    private void setupColumns()
+    {
+        Node.Property[] columns = new Node.Property[4];
+        ResourceBundle loc = NbBundle.getBundle(DiffTreeTable.class);
+        columns[0] = new ColumnDescriptor(RevisionNode.COLUMN_NAME_NAME, String.class, &quot;&quot;, &quot;&quot;);  // NOI18N
+        columns[0].setValue(&quot;TreeColumnTTV&quot;, Boolean.TRUE); // NOI18N
+        columns[1] = new ColumnDescriptor(RevisionNode.COLUMN_NAME_DATE, String.class, loc.getString(&quot;LBL_DiffTree_Column_Time&quot;), loc.getString(&quot;LBL_DiffTree_Column_Time_Desc&quot;));
+        columns[2] = new ColumnDescriptor(RevisionNode.COLUMN_NAME_USERNAME, String.class, loc.getString(&quot;LBL_DiffTree_Column_Username&quot;), loc.getString(&quot;LBL_DiffTree_Column_Username_Desc&quot;));
+        columns[3] = new ColumnDescriptor(RevisionNode.COLUMN_NAME_MESSAGE, String.class, loc.getString(&quot;LBL_DiffTree_Column_Message&quot;), loc.getString(&quot;LBL_DiffTree_Column_Message_Desc&quot;));
+        setProperties(columns);
+    }
+
+    private void setDefaultColumnSizes()
+    {
+        SwingUtilities.invokeLater(new Runnable() {
+
+            public void run()
+            {
+                int width = getWidth();
+                treeTable.getColumnModel().getColumn(0).setPreferredWidth(width * 25 / 100);
+                treeTable.getColumnModel().getColumn(1).setPreferredWidth(width * 15 / 100);
+                treeTable.getColumnModel().getColumn(2).setPreferredWidth(width * 10 / 100);
+                treeTable.getColumnModel().getColumn(3).setPreferredWidth(width * 50 / 100);
+            }
+
+        });
+    }
+
+    void setSelection(int idx)
+    {
+        treeTable.getSelectionModel().setValueIsAdjusting(false);
+        treeTable.scrollRectToVisible(treeTable.getCellRect(idx, 1, true));
+        treeTable.getSelectionModel().setSelectionInterval(idx, idx);
+    }
+
+    void setSelection(RepositoryRevision container)
+    {
+        RevisionNode node = (RevisionNode) getNode(rootNode, container);
+        if (node == null)
+            return;
+        ExplorerManager em = ExplorerManager.find(this);
+        try {
+            em.setSelectedNodes(new Node[]{node});
+        } catch (PropertyVetoException e) {
+            ErrorManager.getDefault().notify(e);
+        }
+    }
+
+    void setSelection(RepositoryRevision.Event revision)
+    {
+        RevisionNode node = (RevisionNode) getNode(rootNode, revision);
+        if (node == null)
+            return;
+        ExplorerManager em = ExplorerManager.find(this);
+        try {
+            em.setSelectedNodes(new Node[]{node});
+        } catch (PropertyVetoException e) {
+            ErrorManager.getDefault().notify(e);
+        }
+    }
+
+    private Node getNode(Node node, Object obj)
+    {
+        Object object = node.getLookup().lookup(obj.getClass());
+        if (obj.equals(object))
+            return node;
+        Enumeration children = node.getChildren().nodes();
+        while (children.hasMoreElements()) {
+            Node child = (Node) children.nextElement();
+            Node result = getNode(child, obj);
+            if (result != null)
+                return result;
+        }
+        return null;
+    }
+
+    public int[] getSelection()
+    {
+        return treeTable.getSelectedRows();
+    }
+
+    public int getRowCount()
+    {
+        return treeTable.getRowCount();
+    }
+
+    private static class ColumnDescriptor&lt;T&gt; extends PropertySupport.ReadOnly&lt;T&gt; {
+
+        public ColumnDescriptor(String name, Class&lt;T&gt; type, String displayName, String shortDescription)
+        {
+            super(name, type, displayName, shortDescription);
+        }
+
+        public T getValue() throws IllegalAccessException, InvocationTargetException
+        {
+            return null;
+        }
+
+    }
+
+    public void addNotify()
+    {
+        super.addNotify();
+        ExplorerManager em = ExplorerManager.find(this);
+        em.setRootContext(rootNode);
+        setDefaultColumnSizes();
+    }
+
+    public void setResults(List results)
+    {
+        this.results = results;
+        rootNode = new RevisionsRootNode();
+        ExplorerManager em = ExplorerManager.find(this);
+        if (em != null)
+            em.setRootContext(rootNode);
+    }
+
+    private class RevisionsRootNode extends AbstractNode {
+
+        public RevisionsRootNode()
+        {
+            super(new RevisionsRootNodeChildren(), Lookups.singleton(results));
+        }
+
+        public String getName()
+        {
+            return &quot;revision&quot;; // NOI18N
+        }
+
+        public String getDisplayName()
+        {
+            return NbBundle.getMessage(DiffTreeTable.class, &quot;LBL_DiffTree_Column_Name&quot;); // NOI18N
+        }
+
+        public String getShortDescription()
+        {
+            return NbBundle.getMessage(DiffTreeTable.class, &quot;LBL_DiffTree_Column_Name_Desc&quot;); // NOI18N
+        }
+
+    }
+
+    private class RevisionsRootNodeChildren extends Children.Keys {
+
+        public RevisionsRootNodeChildren()
+        {
+        }
+
+        protected void addNotify()
+        {
+            refreshKeys();
+        }
+
+        @SuppressWarnings(&quot;unchecked&quot;)
+        @Override
+        protected void removeNotify()
+        {
+            setKeys(Collections.EMPTY_SET);
+        }
+
+        @SuppressWarnings(&quot;unchecked&quot;)
+        private void refreshKeys()
+        {
+            setKeys(results);
+        }
+
+        protected Node[] createNodes(Object key)
+        {
+            RevisionNode node;
+            if (key instanceof RepositoryRevision)
+                node = new RevisionNode((RepositoryRevision) key, master);
+            else // key instanceof RepositoryRevision.Event
+                node = new RevisionNode(((RepositoryRevision.Event) key), master);
+            return new Node[]{node};
+        }
+
+    }
 
 }
\ No newline at end of file</diff>
      <filename>src/org/nbgit/ui/log/DiffTreeTable.java</filename>
    </modified>
    <modified>
      <diff>@@ -56,83 +56,83 @@ import org.openide.util.NbBundle;
  */
 class Divider extends JPanel {
 
-	public static final int DIVIDER_CLICKED = 1;
-	public static final int DOWN = 0;
-	public static final int UP = 1;
-	private Color bkg;
-	private Color sbkg;
-	private Color arrowColor;
-	private Color selectedArrowColor;
-	private ActionListener listener;
-	private int arrowDirection;
+    public static final int DIVIDER_CLICKED = 1;
+    public static final int DOWN = 0;
+    public static final int UP = 1;
+    private Color bkg;
+    private Color sbkg;
+    private Color arrowColor;
+    private Color selectedArrowColor;
+    private ActionListener listener;
+    private int arrowDirection;
 
-	public Divider(ActionListener listener)
-	{
-		this.listener = listener;
-		enableEvents(MouseEvent.MOUSE_ENTERED | MouseEvent.MOUSE_EXITED | MouseEvent.MOUSE_CLICKED);
-		bkg = getBackground();
-		sbkg = UIManager.getColor(&quot;TextField.selectionBackground&quot;); // NOI18N
-		selectedArrowColor = UIManager.getColor(&quot;TextField.selectionForeground&quot;); // NOI18N
-		arrowColor = UIManager.getColor(&quot;TextField.inactiveForeground&quot;); // NOI18N
-		getAccessibleContext().setAccessibleName(NbBundle.getMessage(Divider.class, &quot;ACSN_Divider&quot;));
-		getAccessibleContext().setAccessibleDescription(NbBundle.getMessage(Divider.class, &quot;ACSD_Divider&quot;));
-	}
+    public Divider(ActionListener listener)
+    {
+        this.listener = listener;
+        enableEvents(MouseEvent.MOUSE_ENTERED | MouseEvent.MOUSE_EXITED | MouseEvent.MOUSE_CLICKED);
+        bkg = getBackground();
+        sbkg = UIManager.getColor(&quot;TextField.selectionBackground&quot;); // NOI18N
+        selectedArrowColor = UIManager.getColor(&quot;TextField.selectionForeground&quot;); // NOI18N
+        arrowColor = UIManager.getColor(&quot;TextField.inactiveForeground&quot;); // NOI18N
+        getAccessibleContext().setAccessibleName(NbBundle.getMessage(Divider.class, &quot;ACSN_Divider&quot;));
+        getAccessibleContext().setAccessibleDescription(NbBundle.getMessage(Divider.class, &quot;ACSD_Divider&quot;));
+    }
 
-	@Override
-	public Dimension getPreferredSize()
-	{
-		return new Dimension(Integer.MAX_VALUE, 6);
-	}
+    @Override
+    public Dimension getPreferredSize()
+    {
+        return new Dimension(Integer.MAX_VALUE, 6);
+    }
 
-	@Override
-	public Dimension getMaximumSize()
-	{
-		return new Dimension(Integer.MAX_VALUE, 6);
-	}
+    @Override
+    public Dimension getMaximumSize()
+    {
+        return new Dimension(Integer.MAX_VALUE, 6);
+    }
 
-	public void setArrowDirection(int direction)
-	{
-		arrowDirection = direction;
-	}
+    public void setArrowDirection(int direction)
+    {
+        arrowDirection = direction;
+    }
 
-	@Override
-	protected void processMouseEvent(MouseEvent e)
-	{
-		super.processMouseEvent(e);
-		if (e.getID() == MouseEvent.MOUSE_ENTERED) {
-			setBackground(sbkg);
-			repaint();
-		}
-		if (e.getID() == MouseEvent.MOUSE_EXITED) {
-			setBackground(bkg);
-			repaint();
-		}
-		if (e.getID() == MouseEvent.MOUSE_CLICKED)
-			listener.actionPerformed(new ActionEvent(this, DIVIDER_CLICKED, &quot;&quot;));
-	}
+    @Override
+    protected void processMouseEvent(MouseEvent e)
+    {
+        super.processMouseEvent(e);
+        if (e.getID() == MouseEvent.MOUSE_ENTERED) {
+            setBackground(sbkg);
+            repaint();
+        }
+        if (e.getID() == MouseEvent.MOUSE_EXITED) {
+            setBackground(bkg);
+            repaint();
+        }
+        if (e.getID() == MouseEvent.MOUSE_CLICKED)
+            listener.actionPerformed(new ActionEvent(this, DIVIDER_CLICKED, &quot;&quot;));
+    }
 
-	@Override
-	protected void paintComponent(Graphics g)
-	{
-		super.paintComponent(g);
-		Dimension dim = getSize();
-		if (getBackground().equals(bkg))
-			g.setColor(arrowColor);
-		else
-			g.setColor(selectedArrowColor);
+    @Override
+    protected void paintComponent(Graphics g)
+    {
+        super.paintComponent(g);
+        Dimension dim = getSize();
+        if (getBackground().equals(bkg))
+            g.setColor(arrowColor);
+        else
+            g.setColor(selectedArrowColor);
 
-		int mid = dim.width / 2;
-		if (arrowDirection == DOWN) {
-			g.drawLine(mid - 4, 1, mid + 4, 1);
-			g.drawLine(mid - 3, 2, mid + 3, 2);
-			g.drawLine(mid - 2, 3, mid + 2, 3);
-			g.drawLine(mid - 1, 4, mid + 1, 4);
-		} else if (arrowDirection == UP) {
-			g.drawLine(mid - 4, 4, mid + 4, 4);
-			g.drawLine(mid - 3, 3, mid + 3, 3);
-			g.drawLine(mid - 2, 2, mid + 2, 2);
-			g.drawLine(mid - 1, 1, mid + 1, 1);
-		}
-	}
+        int mid = dim.width / 2;
+        if (arrowDirection == DOWN) {
+            g.drawLine(mid - 4, 1, mid + 4, 1);
+            g.drawLine(mid - 3, 2, mid + 3, 2);
+            g.drawLine(mid - 2, 3, mid + 2, 3);
+            g.drawLine(mid - 1, 4, mid + 1, 4);
+        } else if (arrowDirection == UP) {
+            g.drawLine(mid - 4, 4, mid + 4, 4);
+            g.drawLine(mid - 3, 3, mid + 3, 3);
+            g.drawLine(mid - 2, 2, mid + 2, 2);
+            g.drawLine(mid - 1, 1, mid + 1, 1);
+        }
+    }
 
 }
\ No newline at end of file</diff>
      <filename>src/org/nbgit/ui/log/Divider.java</filename>
    </modified>
    <modified>
      <diff>@@ -47,36 +47,36 @@ package org.nbgit.ui.log;
  */
 class GitLogMessageChangedPath {
 
-	private String path;
-	private String copyPath;
-	private char action;
+    private String path;
+    private String copyPath;
+    private char action;
 
-	public GitLogMessageChangedPath(String path, char action)
-	{
-		this.path = path;
-		this.action = action;
-		this.copyPath = null;
-	}
+    public GitLogMessageChangedPath(String path, char action)
+    {
+        this.path = path;
+        this.action = action;
+        this.copyPath = null;
+    }
 
-	public String getPath()
-	{
-		return path;
-	}
+    public String getPath()
+    {
+        return path;
+    }
 
-	public char getAction()
-	{
-		return action;
-	}
+    public char getAction()
+    {
+        return action;
+    }
 
-	public String getCopySrcPath()
-	{
-		return copyPath;
-	}
+    public String getCopySrcPath()
+    {
+        return copyPath;
+    }
 
-	@Override
-	public String toString()
-	{
-		return &quot;action: &quot; + this.action + &quot; path: &quot; + this.path;
-	}
+    @Override
+    public String toString()
+    {
+        return &quot;action: &quot; + this.action + &quot; path: &quot; + this.path;
+    }
 
 }
\ No newline at end of file</diff>
      <filename>src/org/nbgit/ui/log/GitLogMessageChangedPath.java</filename>
    </modified>
    <modified>
      <diff>@@ -47,22 +47,22 @@ import org.netbeans.modules.versioning.spi.VCSContext;
 import org.openide.util.NbBundle;
 
 /**
- * Log action for Git: 
+ * Log action for Git:
  * git log - show revision history of entire repository or files
- * 
+ *
  * @author John Rice
  */
 public class LogAction extends ContextAction {
 
-	public LogAction(String name, VCSContext context)
-	{
-		super(name, context);
-	}
+    public LogAction(String name, VCSContext context)
+    {
+        super(name, context);
+    }
 
-	public void performAction(ActionEvent e)
-	{
-		SearchHistoryAction.openHistory(context,
-			NbBundle.getMessage(LogAction.class, &quot;MSG_Log_TabTitle&quot;, org.netbeans.modules.versioning.util.Utils.getContextDisplayName(context)));
-	}
+    public void performAction(ActionEvent e)
+    {
+        SearchHistoryAction.openHistory(context,
+            NbBundle.getMessage(LogAction.class, &quot;MSG_Log_TabTitle&quot;, org.netbeans.modules.versioning.util.Utils.getContextDisplayName(context)));
+    }
 
 }
\ No newline at end of file</diff>
      <filename>src/org/nbgit/ui/log/LogAction.java</filename>
    </modified>
    <modified>
      <diff>@@ -66,240 +66,240 @@ import org.spearce.jgit.treewalk.TreeWalk;
  */
 public class RepositoryRevision extends RevCommit {
 
-	private final Repository repo;
-	/**
-	 * List of events associated with the revision.
-	 */
-	private final List&lt;Event&gt; events = new ArrayList&lt;Event&gt;(1);
-
-	private RepositoryRevision(AnyObjectId id, Repository repo)
-	{
-		super(id);
-		this.repo = repo;
-	}
-
-	public String getRepositoryRootUrl()
-	{
-		return repo.getDirectory().getAbsolutePath();
-	}
-
-	Iterable&lt;Event&gt; createEvents(Walk walk)
-	{
-		try {
-			initEvents(walk.getTreeWalk());
-		} catch (MissingObjectException ex) {
-			Exceptions.printStackTrace(ex);
-		} catch (IncorrectObjectTypeException ex) {
-			Exceptions.printStackTrace(ex);
-		} catch (CorruptObjectException ex) {
-			Exceptions.printStackTrace(ex);
-		} catch (IOException ex) {
-			Exceptions.printStackTrace(ex);
-		}
-
-		return events;
-	}
-
-	private ObjectId[] getTrees()
-	{
-		final ObjectId[] r = new ObjectId[getParentCount() + 1];
-		for (int i = 0; i &lt; r.length - 1; i++) {
-			r[i] = getParent(i).getTree().getId();
-		}
-		r[r.length - 1] = getTree().getId();
-		return r;
-	}
-
-	private char getStatus(TreeWalk walk, int mode0, int mode1)
-	{
-		if (mode0 == 0 &amp;&amp; mode1 != 0)
-			return 'A';
-		else if (mode0 != 0 &amp;&amp; mode1 == 0)
-			return 'D';
-		else if (!walk.idEqual(0, 1))
-			return 'M';
-		else if (mode0 != mode1)
-			return 'm';
-
-		return 0;
-	}
-
-	private void initEvents(final TreeWalk walk)
-		throws MissingObjectException, IncorrectObjectTypeException,
-		CorruptObjectException, IOException
-	{
-		ObjectId[] trees = getTrees();
-		final int revTree = trees.length - 1;
-
-		walk.reset(trees);
-
-		switch (trees.length) {
-		case 1:
-			/* Inital commit. */
-			while (walk.next()) {
-				events.add(new Event(walk.getPathString(), 'A'));
-			}
-			break;
-		case 2:
-			while (walk.next()) {
-				int mode0 = walk.getRawMode(0);
-				int mode1 = walk.getRawMode(1);
-				char status = getStatus(walk, mode0, mode1);
-				if (status == 0)
-					continue;
-
-				events.add(new Event(walk.getPathString(), status));
-			}
-			break;
-		default:
-			/* Merge. */
-			while (walk.next()) {
-				int mode0 = 0;
-				int mode1 = walk.getRawMode(revTree);
-				int i;
-
-				for (i = 0; i &lt; revTree; i++) {
-					int mode = walk.getRawMode(i);
-					if (mode == mode1 &amp;&amp; walk.idEqual(i, revTree))
-						break;
-					mode0 |= mode;
-				}
-
-				if (i != revTree)
-					continue;
-
-				char status = getStatus(walk, mode0, mode1);
-				if (status == 0)
-					continue;
-
-				events.add(new Event(walk.getPathString(), status));
-			}
-			break;
-		}
-
-	}
-
-	public List&lt;Event&gt; getEvents()
-	{
-		return events;
-	}
-
-	public String getAuthor()
-	{
-		return getAuthorIdent().getName();
-	}
-
-	String getMessage()
-	{
-		return getFullMessage();
-	}
-
-	public String getRevision()
-	{
-		return getId().toString();
-	}
-
-	public Date getDate()
-	{
-		return getCommitterIdent().getWhen();
-	}
-
-	public class Event {
-
-		/**
-		 * The file or folder that this event is about. It may be null if the File cannot be computed.
-		 */
-		private File file;
-		private GitLogMessageChangedPath changedPath;
-		private String name;
-		private String path;
-
-		private Event(GitLogMessageChangedPath changedPath)
-		{
-			this.changedPath = changedPath;
-			name = changedPath.getPath().substring(changedPath.getPath().lastIndexOf('/') + 1);
-
-			int indexPath = changedPath.getPath().lastIndexOf('/');
-			if (indexPath &gt; -1)
-				path = changedPath.getPath().substring(0, indexPath);
-			else
-				path = &quot;&quot;;
-		}
-
-		private Event(String pathString, char c)
-		{
-			this(new GitLogMessageChangedPath(pathString, c));
-		}
-
-		public RepositoryRevision getLogInfoHeader()
-		{
-			return RepositoryRevision.this;
-		}
-
-		public GitLogMessageChangedPath getChangedPath()
-		{
-			return changedPath;
-		}
-
-		/** Getter for property file.
-		 * @return Value of property file.
-		 */
-		public File getFile()
-		{
-			return file;
-		}
-
-		/** Setter for property file.
-		 * @param file New value of property file.
-		 */
-		public void setFile(File file)
-		{
-			this.file = file;
-		}
-
-		public String getName()
-		{
-			return name;
-		}
-
-		public String getPath()
-		{
-			return path;
-		}
-
-		@Override
-		public String toString()
-		{
-			StringBuffer text = new StringBuffer();
-			text.append(&quot;\t&quot;);
-			text.append(getPath());
-			return text.toString();
-		}
-
-	}
-
-	public static class Walk extends RevWalk {
-
-		private final TreeWalk walk;
-
-		public Walk(Repository repo)
-		{
-			super(repo);
-			walk = new TreeWalk(repo);
-			walk.setRecursive(true);
-		}
-
-		@Override
-		protected RevCommit createCommit(final AnyObjectId id)
-		{
-			return new RepositoryRevision(id, getRepository());
-		}
-
-		private TreeWalk getTreeWalk()
-		{
-			return walk;
-		}
-
-	}
+    private final Repository repo;
+    /**
+     * List of events associated with the revision.
+     */
+    private final List&lt;Event&gt; events = new ArrayList&lt;Event&gt;(1);
+
+    private RepositoryRevision(AnyObjectId id, Repository repo)
+    {
+        super(id);
+        this.repo = repo;
+    }
+
+    public String getRepositoryRootUrl()
+    {
+        return repo.getDirectory().getAbsolutePath();
+    }
+
+    Iterable&lt;Event&gt; createEvents(Walk walk)
+    {
+        try {
+            initEvents(walk.getTreeWalk());
+        } catch (MissingObjectException ex) {
+            Exceptions.printStackTrace(ex);
+        } catch (IncorrectObjectTypeException ex) {
+            Exceptions.printStackTrace(ex);
+        } catch (CorruptObjectException ex) {
+            Exceptions.printStackTrace(ex);
+        } catch (IOException ex) {
+            Exceptions.printStackTrace(ex);
+        }
+
+        return events;
+    }
+
+    private ObjectId[] getTrees()
+    {
+        final ObjectId[] r = new ObjectId[getParentCount() + 1];
+        for (int i = 0; i &lt; r.length - 1; i++) {
+            r[i] = getParent(i).getTree().getId();
+        }
+        r[r.length - 1] = getTree().getId();
+        return r;
+    }
+
+    private char getStatus(TreeWalk walk, int mode0, int mode1)
+    {
+        if (mode0 == 0 &amp;&amp; mode1 != 0)
+            return 'A';
+        else if (mode0 != 0 &amp;&amp; mode1 == 0)
+            return 'D';
+        else if (!walk.idEqual(0, 1))
+            return 'M';
+        else if (mode0 != mode1)
+            return 'm';
+
+        return 0;
+    }
+
+    private void initEvents(final TreeWalk walk)
+        throws MissingObjectException, IncorrectObjectTypeException,
+        CorruptObjectException, IOException
+    {
+        ObjectId[] trees = getTrees();
+        final int revTree = trees.length - 1;
+
+        walk.reset(trees);
+
+        switch (trees.length) {
+        case 1:
+            /* Inital commit. */
+            while (walk.next()) {
+                events.add(new Event(walk.getPathString(), 'A'));
+            }
+            break;
+        case 2:
+            while (walk.next()) {
+                int mode0 = walk.getRawMode(0);
+                int mode1 = walk.getRawMode(1);
+                char status = getStatus(walk, mode0, mode1);
+                if (status == 0)
+                    continue;
+
+                events.add(new Event(walk.getPathString(), status));
+            }
+            break;
+        default:
+            /* Merge. */
+            while (walk.next()) {
+                int mode0 = 0;
+                int mode1 = walk.getRawMode(revTree);
+                int i;
+
+                for (i = 0; i &lt; revTree; i++) {
+                    int mode = walk.getRawMode(i);
+                    if (mode == mode1 &amp;&amp; walk.idEqual(i, revTree))
+                        break;
+                    mode0 |= mode;
+                }
+
+                if (i != revTree)
+                    continue;
+
+                char status = getStatus(walk, mode0, mode1);
+                if (status == 0)
+                    continue;
+
+                events.add(new Event(walk.getPathString(), status));
+            }
+            break;
+        }
+
+    }
+
+    public List&lt;Event&gt; getEvents()
+    {
+        return events;
+    }
+
+    public String getAuthor()
+    {
+        return getAuthorIdent().getName();
+    }
+
+    String getMessage()
+    {
+        return getFullMessage();
+    }
+
+    public String getRevision()
+    {
+        return getId().toString();
+    }
+
+    public Date getDate()
+    {
+        return getCommitterIdent().getWhen();
+    }
+
+    public class Event {
+
+        /**
+         * The file or folder that this event is about. It may be null if the File cannot be computed.
+         */
+        private File file;
+        private GitLogMessageChangedPath changedPath;
+        private String name;
+        private String path;
+
+        private Event(GitLogMessageChangedPath changedPath)
+        {
+            this.changedPath = changedPath;
+            name = changedPath.getPath().substring(changedPath.getPath().lastIndexOf('/') + 1);
+
+            int indexPath = changedPath.getPath().lastIndexOf('/');
+            if (indexPath &gt; -1)
+                path = changedPath.getPath().substring(0, indexPath);
+            else
+                path = &quot;&quot;;
+        }
+
+        private Event(String pathString, char c)
+        {
+            this(new GitLogMessageChangedPath(pathString, c));
+        }
+
+        public RepositoryRevision getLogInfoHeader()
+        {
+            return RepositoryRevision.this;
+        }
+
+        public GitLogMessageChangedPath getChangedPath()
+        {
+            return changedPath;
+        }
+
+        /** Getter for property file.
+         * @return Value of property file.
+         */
+        public File getFile()
+        {
+            return file;
+        }
+
+        /** Setter for property file.
+         * @param file New value of property file.
+         */
+        public void setFile(File file)
+        {
+            this.file = file;
+        }
+
+        public String getName()
+        {
+            return name;
+        }
+
+        public String getPath()
+        {
+            return path;
+        }
+
+        @Override
+        public String toString()
+        {
+            StringBuffer text = new StringBuffer();
+            text.append(&quot;\t&quot;);
+            text.append(getPath());
+            return text.toString();
+        }
+
+    }
+
+    public static class Walk extends RevWalk {
+
+        private final TreeWalk walk;
+
+        public Walk(Repository repo)
+        {
+            super(repo);
+            walk = new TreeWalk(repo);
+            walk.setRecursive(true);
+        }
+
+        @Override
+        protected RevCommit createCommit(final AnyObjectId id)
+        {
+            return new RepositoryRevision(id, getRepository());
+        }
+
+        private TreeWalk getTreeWalk()
+        {
+            return walk;
+        }
+
+    }
 
 }
\ No newline at end of file</diff>
      <filename>src/org/nbgit/ui/log/RepositoryRevision.java</filename>
    </modified>
    <modified>
      <diff>@@ -68,247 +68,247 @@ import org.openide.util.lookup.Lookups;
 
 /**
  * Visible in the Search History Diff view.
- * 
+ *
  * @author Maros Sandor
  */
 class RevisionNode extends AbstractNode {
 
-	static final String COLUMN_NAME_NAME = &quot;name&quot;; // NOI18N
-	static final String COLUMN_NAME_DATE = &quot;date&quot;; // NOI18N
-	static final String COLUMN_NAME_USERNAME = &quot;username&quot;; // NOI18N
-	static final String COLUMN_NAME_MESSAGE = &quot;message&quot;; // NOI18N
-	private RepositoryRevision.Event event;
-	private RepositoryRevision container;
-	private String path;
-
-	public RevisionNode(RepositoryRevision container, SearchHistoryPanel master)
-	{
-		super(new RevisionNodeChildren(container, master), Lookups.fixed(master, container));
-		this.container = container;
-		this.event = null;
-		this.path = null;
-		setName(container.getRevision() +
-			NbBundle.getMessage(RevisionNode.class, &quot;LBL_NumberOfChangedPaths&quot;, 0/*container.getLog().getChangedPaths().length*/));
-		initProperties();
-	}
-
-	public RevisionNode(RepositoryRevision.Event revision, SearchHistoryPanel master)
-	{
-		super(Children.LEAF, Lookups.fixed(master, revision));
-		this.path = revision.getChangedPath().getPath();
-		this.event = revision;
-		setName(revision.getName());
-		initProperties();
-	}
-
-	RepositoryRevision.Event getRevision()
-	{
-		return event;
-	}
-
-	RepositoryRevision getContainer()
-	{
-		return container;
-	}
-
-	RepositoryRevision.Event getEvent()
-	{
-		return event;
-	}
-
-	public String getShortDescription()
-	{
-		return path;
-	}
-
-	public Action[] getActions(boolean context)
-	{
-		if (context)
-			return null;
-		// TODO: reuse action code from SummaryView
-		if (event == null)
-			return new Action[]{
-					SystemAction.get(RevertModificationsAction.class)
-				};
-		else
-			return new Action[]{
-					new RollbackAction(),
-					SystemAction.get(RevertModificationsAction.class)
-				};
-	}
-
-	private void initProperties()
-	{
-		Sheet sheet = Sheet.createDefault();
-		Sheet.Set ps = Sheet.createPropertiesSet();
-
-		ps.put(new DateProperty());
-		ps.put(new UsernameProperty());
-		ps.put(new MessageProperty());
-
-		sheet.put(ps);
-		setSheet(sheet);
-	}
-
-	private abstract class CommitNodeProperty&lt;T&gt; extends PropertySupport.ReadOnly&lt;T&gt; {
-
-		protected CommitNodeProperty(String name, Class&lt;T&gt; type, String displayName, String shortDescription)
-		{
-			super(name, type, displayName, shortDescription);
-		}
-
-		public String toString()
-		{
-			try {
-				return getValue().toString();
-			} catch (Exception e) {
-				ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e);
-				return e.getLocalizedMessage();
-			}
-		}
-
-		public PropertyEditor getPropertyEditor()
-		{
-			try {
-				return new RevisionPropertyEditor((String) getValue());
-			} catch (Exception e) {
-				return super.getPropertyEditor();
-			}
-		}
-
-	}
-
-	private class UsernameProperty extends CommitNodeProperty {
-
-		@SuppressWarnings(&quot;unchecked&quot;)
-		public UsernameProperty()
-		{
-			super(COLUMN_NAME_USERNAME, String.class, COLUMN_NAME_USERNAME, COLUMN_NAME_USERNAME);
-		}
-
-		public Object getValue() throws IllegalAccessException, InvocationTargetException
-		{
-			if (event == null)
-				return container.getAuthor();
-			else
-				return &quot;&quot;;
-		}
-
-	}
-
-	private class DateProperty extends CommitNodeProperty {
-
-		@SuppressWarnings(&quot;unchecked&quot;)
-		public DateProperty()
-		{
-			super(COLUMN_NAME_DATE, String.class, COLUMN_NAME_DATE, COLUMN_NAME_DATE);
-		}
-
-		public Object getValue() throws IllegalAccessException, InvocationTargetException
-		{
-			if (event == null)
-				return DateFormat.getDateTimeInstance().format(container.getDate());
-			else
-				return &quot;&quot;;
-		}
-
-	}
-
-	private class MessageProperty extends CommitNodeProperty {
-
-		@SuppressWarnings(&quot;unchecked&quot;)
-		public MessageProperty()
-		{
-			super(COLUMN_NAME_MESSAGE, String.class, COLUMN_NAME_MESSAGE, COLUMN_NAME_MESSAGE);
-		}
-
-		public Object getValue() throws IllegalAccessException, InvocationTargetException
-		{
-			if (event == null)
-				return container.getMessage();
-			else
-				return &quot;&quot;;
-		}
-
-	}
-
-	private class RollbackAction extends AbstractAction {
-
-		public RollbackAction()
-		{
-			putValue(Action.NAME, NbBundle.getMessage(RevisionNode.class, &quot;CTL_Action_RollbackTo&quot;, // NOI18N
-				event.getLogInfoHeader().getRevision()));
-		}
-
-		public void actionPerformed(ActionEvent e)
-		{
-			SummaryView.rollback(event);
-		}
-
-	}
-
-	private static class RevertModificationsAction extends NodeAction {
-
-		protected void performAction(Node[] activatedNodes)
-		{
-			Set&lt;RepositoryRevision.Event&gt; events = new HashSet&lt;RepositoryRevision.Event&gt;();
-			Set&lt;RepositoryRevision&gt; revisions = new HashSet&lt;RepositoryRevision&gt;();
-			for (Node n : activatedNodes) {
-				RevisionNode node = (RevisionNode) n;
-				if (node.event != null)
-					events.add(node.event);
-				else
-					revisions.add(node.container);
-			}
-			SearchHistoryPanel master = activatedNodes[0].getLookup().lookup(SearchHistoryPanel.class);
-			SummaryView.revert(master, revisions.toArray(new RepositoryRevision[revisions.size()]), events.toArray(new RepositoryRevision.Event[events.size()]));
-		}
-
-		protected boolean enable(Node[] activatedNodes)
-		{
-			return true;
-		}
-
-		public String getName()
-		{
-			return NbBundle.getMessage(RevisionNode.class, &quot;CTL_Action_RollbackChange&quot;); // NOI18N
-		}
-
-		public HelpCtx getHelpCtx()
-		{
-			return new HelpCtx(RevertModificationsAction.class);
-		}
-
-	}
-
-	private static class RevisionPropertyEditor extends PropertyEditorSupport {
-
-		private static final JLabel renderer = new JLabel();
-		
-
-		static {
-			renderer.setBorder(BorderFactory.createEmptyBorder(0, 2, 0, 2));
-		}
-
-		public RevisionPropertyEditor(String value)
-		{
-			setValue(value);
-		}
-
-		public void paintValue(Graphics gfx, Rectangle box)
-		{
-			renderer.setForeground(gfx.getColor());
-			renderer.setText((String) getValue());
-			renderer.setBounds(box);
-			renderer.paint(gfx);
-		}
-
-		@Override
-		public boolean isPaintable()
-		{
-			return true;
-		}
-
-	}
+    static final String COLUMN_NAME_NAME = &quot;name&quot;; // NOI18N
+    static final String COLUMN_NAME_DATE = &quot;date&quot;; // NOI18N
+    static final String COLUMN_NAME_USERNAME = &quot;username&quot;; // NOI18N
+    static final String COLUMN_NAME_MESSAGE = &quot;message&quot;; // NOI18N
+    private RepositoryRevision.Event event;
+    private RepositoryRevision container;
+    private String path;
+
+    public RevisionNode(RepositoryRevision container, SearchHistoryPanel master)
+    {
+        super(new RevisionNodeChildren(container, master), Lookups.fixed(master, container));
+        this.container = container;
+        this.event = null;
+        this.path = null;
+        setName(container.getRevision() +
+            NbBundle.getMessage(RevisionNode.class, &quot;LBL_NumberOfChangedPaths&quot;, 0/*container.getLog().getChangedPaths().length*/));
+        initProperties();
+    }
+
+    public RevisionNode(RepositoryRevision.Event revision, SearchHistoryPanel master)
+    {
+        super(Children.LEAF, Lookups.fixed(master, revision));
+        this.path = revision.getChangedPath().getPath();
+        this.event = revision;
+        setName(revision.getName());
+        initProperties();
+    }
+
+    RepositoryRevision.Event getRevision()
+    {
+        return event;
+    }
+
+    RepositoryRevision getContainer()
+    {
+        return container;
+    }
+
+    RepositoryRevision.Event getEvent()
+    {
+        return event;
+    }
+
+    public String getShortDescription()
+    {
+        return path;
+    }
+
+    public Action[] getActions(boolean context)
+    {
+        if (context)
+            return null;
+        // TODO: reuse action code from SummaryView
+        if (event == null)
+            return new Action[]{
+                    SystemAction.get(RevertModificationsAction.class)
+                };
+        else
+            return new Action[]{
+                    new RollbackAction(),
+                    SystemAction.get(RevertModificationsAction.class)
+                };
+    }
+
+    private void initProperties()
+    {
+        Sheet sheet = Sheet.createDefault();
+        Sheet.Set ps = Sheet.createPropertiesSet();
+
+        ps.put(new DateProperty());
+        ps.put(new UsernameProperty());
+        ps.put(new MessageProperty());
+
+        sheet.put(ps);
+        setSheet(sheet);
+    }
+
+    private abstract class CommitNodeProperty&lt;T&gt; extends PropertySupport.ReadOnly&lt;T&gt; {
+
+        protected CommitNodeProperty(String name, Class&lt;T&gt; type, String displayName, String shortDescription)
+        {
+            super(name, type, displayName, shortDescription);
+        }
+
+        public String toString()
+        {
+            try {
+                return getValue().toString();
+            } catch (Exception e) {
+                ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e);
+                return e.getLocalizedMessage();
+            }
+        }
+
+        public PropertyEditor getPropertyEditor()
+        {
+            try {
+                return new RevisionPropertyEditor((String) getValue());
+            } catch (Exception e) {
+                return super.getPropertyEditor();
+            }
+        }
+
+    }
+
+    private class UsernameProperty extends CommitNodeProperty {
+
+        @SuppressWarnings(&quot;unchecked&quot;)
+        public UsernameProperty()
+        {
+            super(COLUMN_NAME_USERNAME, String.class, COLUMN_NAME_USERNAME, COLUMN_NAME_USERNAME);
+        }
+
+        public Object getValue() throws IllegalAccessException, InvocationTargetException
+        {
+            if (event == null)
+                return container.getAuthor();
+            else
+                return &quot;&quot;;
+        }
+
+    }
+
+    private class DateProperty extends CommitNodeProperty {
+
+        @SuppressWarnings(&quot;unchecked&quot;)
+        public DateProperty()
+        {
+            super(COLUMN_NAME_DATE, String.class, COLUMN_NAME_DATE, COLUMN_NAME_DATE);
+        }
+
+        public Object getValue() throws IllegalAccessException, InvocationTargetException
+        {
+            if (event == null)
+                return DateFormat.getDateTimeInstance().format(container.getDate());
+            else
+                return &quot;&quot;;
+        }
+
+    }
+
+    private class MessageProperty extends CommitNodeProperty {
+
+        @SuppressWarnings(&quot;unchecked&quot;)
+        public MessageProperty()
+        {
+            super(COLUMN_NAME_MESSAGE, String.class, COLUMN_NAME_MESSAGE, COLUMN_NAME_MESSAGE);
+        }
+
+        public Object getValue() throws IllegalAccessException, InvocationTargetException
+        {
+            if (event == null)
+                return container.getMessage();
+            else
+                return &quot;&quot;;
+        }
+
+    }
+
+    private class RollbackAction extends AbstractAction {
+
+        public RollbackAction()
+        {
+            putValue(Action.NAME, NbBundle.getMessage(RevisionNode.class, &quot;CTL_Action_RollbackTo&quot;, // NOI18N
+                event.getLogInfoHeader().getRevision()));
+        }
+
+        public void actionPerformed(ActionEvent e)
+        {
+            SummaryView.rollback(event);
+        }
+
+    }
+
+    private static class RevertModificationsAction extends NodeAction {
+
+        protected void performAction(Node[] activatedNodes)
+        {
+            Set&lt;RepositoryRevision.Event&gt; events = new HashSet&lt;RepositoryRevision.Event&gt;();
+            Set&lt;RepositoryRevision&gt; revisions = new HashSet&lt;RepositoryRevision&gt;();
+            for (Node n : activatedNodes) {
+                RevisionNode node = (RevisionNode) n;
+                if (node.event != null)
+                    events.add(node.event);
+                else
+                    revisions.add(node.container);
+            }
+            SearchHistoryPanel master = activatedNodes[0].getLookup().lookup(SearchHistoryPanel.class);
+            SummaryView.revert(master, revisions.toArray(new RepositoryRevision[revisions.size()]), events.toArray(new RepositoryRevision.Event[events.size()]));
+        }
+
+        protected boolean enable(Node[] activatedNodes)
+        {
+            return true;
+        }
+
+        public String getName()
+        {
+            return NbBundle.getMessage(RevisionNode.class, &quot;CTL_Action_RollbackChange&quot;); // NOI18N
+        }
+
+        public HelpCtx getHelpCtx()
+        {
+            return new HelpCtx(RevertModificationsAction.class);
+        }
+
+    }
+
+    private static class RevisionPropertyEditor extends PropertyEditorSupport {
+
+        private static final JLabel renderer = new JLabel();
+
+
+        static {
+            renderer.setBorder(BorderFactory.createEmptyBorder(0, 2, 0, 2));
+        }
+
+        public RevisionPropertyEditor(String value)
+        {
+            setValue(value);
+        }
+
+        public void paintValue(Graphics gfx, Rectangle box)
+        {
+            renderer.setForeground(gfx.getColor());
+            renderer.setText((String) getValue());
+            renderer.setBounds(box);
+            renderer.paint(gfx);
+        }
+
+        @Override
+        public boolean isPaintable()
+        {
+            return true;
+        }
+
+    }
 
 }
\ No newline at end of file</diff>
      <filename>src/org/nbgit/ui/log/RevisionNode.java</filename>
    </modified>
    <modified>
      <diff>@@ -69,11 +69,11 @@ class RevisionNodeChildren extends Children.Keys&lt;RepositoryRevision.Event&gt; {
     protected void removeNotify() {
         setKeys (Collections.&lt;RepositoryRevision.Event&gt;emptySet());
     }
-    
+
     private void refreshKeys() {
         setKeys(container.getEvents());
     }
-    
+
     protected Node[] createNodes(RepositoryRevision.Event fn) {
         RevisionNode node = new RevisionNode(fn, master);
         return new Node[] { node };</diff>
      <filename>src/org/nbgit/ui/log/RevisionNodeChildren.java</filename>
    </modified>
    <modified>
      <diff>@@ -54,7 +54,7 @@ import org.openide.util.NbBundle;
  * @author Maros Sandor
  */
 class SearchCriteriaPanel extends javax.swing.JPanel {
-    
+
     private final File[] roots;
     private final String url;
 
@@ -70,7 +70,7 @@ class SearchCriteriaPanel extends javax.swing.JPanel {
         this.roots = null;
         initComponents();
     }
-    
+
     public String getFrom() {
         String s = tfFrom.getText().trim();
         if(s.length() == 0) {
@@ -98,7 +98,7 @@ class SearchCriteriaPanel extends javax.swing.JPanel {
         tfFrom.setEnabled(false);
         fromLabel.setEnabled(false);
     }
-    
+
     void setForOut() {
         fromInfoLabel.setText(NbBundle.getMessage(SearchCriteriaPanel.class, &quot;CTL_FromToOutOrIncomingHint&quot;));
         toInfoLabel.setText(NbBundle.getMessage(SearchCriteriaPanel.class, &quot;CTL_FromToOutOrIncomingHint&quot;));
@@ -110,7 +110,7 @@ class SearchCriteriaPanel extends javax.swing.JPanel {
         tfFrom.setEnabled(false);
         fromLabel.setEnabled(false);
     }
-    
+
     private Date parseDate(String s) {
         if (s == null) return null;
         for (int i = 0; i &lt; SearchExecutor.dateFormats.length; i++) {
@@ -123,7 +123,7 @@ class SearchCriteriaPanel extends javax.swing.JPanel {
         }
         return null;
     }
-    
+
     public String getCommitMessage() {
         String s = tfCommitMessage.getText().trim();
         return s.length() &gt; 0 ? s : null;
@@ -143,7 +143,7 @@ class SearchCriteriaPanel extends javax.swing.JPanel {
         if (to == null) to = &quot;&quot;;  // NOI18N
         tfTo.setText(to);
     }
-    
+
     public void setCommitMessage(String message) {
         if (message == null) message = &quot;&quot;; // NOI18N
         tfCommitMessage.setText(message);
@@ -153,7 +153,7 @@ class SearchCriteriaPanel extends javax.swing.JPanel {
         if (username == null) username = &quot;&quot;; // NOI18N
         tfUsername.setText(username);
     }
-    
+
     @Override
     public void addNotify() {
         super.addNotify();
@@ -278,7 +278,7 @@ class SearchCriteriaPanel extends javax.swing.JPanel {
         add(toInfoLabel, gridBagConstraints);
     }// &lt;/editor-fold&gt;//GEN-END:initComponents
 
-    
+
     // Variables declaration - do not modify//GEN-BEGIN:variables
     private javax.swing.JLabel commitMessageLabel;
     private javax.swing.JLabel fromInfoLabel;
@@ -291,5 +291,5 @@ class SearchCriteriaPanel extends javax.swing.JPanel {
     private javax.swing.JLabel toLabel;
     private javax.swing.JLabel usernameLabel;
     // End of variables declaration//GEN-END:variables
-    
+
 }
\ No newline at end of file</diff>
      <filename>src/org/nbgit/ui/log/SearchCriteriaPanel.java</filename>
    </modified>
    <modified>
      <diff>@@ -66,200 +66,200 @@ import org.spearce.jgit.revwalk.filter.RevFilter;
 
 /**
  * Executes searches in Search History panel.
- * 
+ *
  * @author Maros Sandor
  */
 class SearchExecutor implements Runnable {
 
-	public static final SimpleDateFormat simpleDateFormat = new SimpleDateFormat(&quot;yyyy-MM-dd HH:mm&quot;);  // NOI18N
-	static final SimpleDateFormat fullDateFormat = new SimpleDateFormat(&quot;yyyy-MM-dd HH:mm:ss Z&quot;);  // NOI18N
-	static final DateFormat[] dateFormats = new DateFormat[]{
-		fullDateFormat,
-		new SimpleDateFormat(&quot;yyyy-MM-dd HH:mm:ss&quot;), // NOI18N
-		simpleDateFormat,
-		new SimpleDateFormat(&quot;yyyy-MM-dd&quot;), // NOI18N
-	};
-	private final SearchHistoryPanel master;
-	private Map&lt;String, Set&lt;File&gt;&gt; workFiles;
-	private Map&lt;String, File&gt; pathToRoot;
-	private final SearchCriteriaPanel criteria;
-	private boolean filterUsername;
-	private boolean filterMessage;
-	private int completedSearches;
-	private boolean searchCanceled;
-	private List&lt;RepositoryRevision&gt; results = new ArrayList&lt;RepositoryRevision&gt;();
+    public static final SimpleDateFormat simpleDateFormat = new SimpleDateFormat(&quot;yyyy-MM-dd HH:mm&quot;);  // NOI18N
+    static final SimpleDateFormat fullDateFormat = new SimpleDateFormat(&quot;yyyy-MM-dd HH:mm:ss Z&quot;);  // NOI18N
+    static final DateFormat[] dateFormats = new DateFormat[]{
+        fullDateFormat,
+        new SimpleDateFormat(&quot;yyyy-MM-dd HH:mm:ss&quot;), // NOI18N
+        simpleDateFormat,
+        new SimpleDateFormat(&quot;yyyy-MM-dd&quot;), // NOI18N
+    };
+    private final SearchHistoryPanel master;
+    private Map&lt;String, Set&lt;File&gt;&gt; workFiles;
+    private Map&lt;String, File&gt; pathToRoot;
+    private final SearchCriteriaPanel criteria;
+    private boolean filterUsername;
+    private boolean filterMessage;
+    private int completedSearches;
+    private boolean searchCanceled;
+    private List&lt;RepositoryRevision&gt; results = new ArrayList&lt;RepositoryRevision&gt;();
 
-	public SearchExecutor(SearchHistoryPanel master)
-	{
-		this.master = master;
-		criteria = master.getCriteria();
-		filterUsername = criteria.getUsername() != null;
-		filterMessage = criteria.getCommitMessage() != null;
+    public SearchExecutor(SearchHistoryPanel master)
+    {
+        this.master = master;
+        criteria = master.getCriteria();
+        filterUsername = criteria.getUsername() != null;
+        filterMessage = criteria.getCommitMessage() != null;
 
-		pathToRoot = new HashMap&lt;String, File&gt;();
-		if (searchingUrl()) {
-			String rootPath = Git.getInstance().getTopmostManagedParent(master.getRoots()[0]).toString();
-			pathToRoot.put(rootPath, master.getRoots()[0]);
-		} else {
-			workFiles = new HashMap&lt;String, Set&lt;File&gt;&gt;();
-			for (File file : master.getRoots()) {
-				String rootPath = Git.getInstance().getTopmostManagedParent(file).toString();
+        pathToRoot = new HashMap&lt;String, File&gt;();
+        if (searchingUrl()) {
+            String rootPath = Git.getInstance().getTopmostManagedParent(master.getRoots()[0]).toString();
+            pathToRoot.put(rootPath, master.getRoots()[0]);
+        } else {
+            workFiles = new HashMap&lt;String, Set&lt;File&gt;&gt;();
+            for (File file : master.getRoots()) {
+                String rootPath = Git.getInstance().getTopmostManagedParent(file).toString();
 
-				Set&lt;File&gt; set = workFiles.get(rootPath);
-				if (set == null) {
-					set = new HashSet&lt;File&gt;(2);
-					workFiles.put(rootPath, set);
-				}
-				set.add(file);
-			}
-		}
+                Set&lt;File&gt; set = workFiles.get(rootPath);
+                if (set == null) {
+                    set = new HashSet&lt;File&gt;(2);
+                    workFiles.put(rootPath, set);
+                }
+                set.add(file);
+            }
+        }
 
-	}
+    }
 
-	public void run()
-	{
+    public void run()
+    {
 
-		final String fromRevision = criteria.getFrom();
-		final String toRevision = criteria.getTo();
+        final String fromRevision = criteria.getFrom();
+        final String toRevision = criteria.getTo();
 
-		completedSearches = 0;
-		if (searchingUrl()) {
-			RequestProcessor rp = Git.getInstance().getRequestProcessor(master.getRepositoryUrl());
-			GitProgressSupport support = new GitProgressSupport() {
+        completedSearches = 0;
+        if (searchingUrl()) {
+            RequestProcessor rp = Git.getInstance().getRequestProcessor(master.getRepositoryUrl());
+            GitProgressSupport support = new GitProgressSupport() {
 
-				public void perform()
-				{
-					OutputLogger logger = getLogger();
-					search(master.getRepositoryUrl(), null, fromRevision, toRevision, this, logger);
-				}
+                public void perform()
+                {
+                    OutputLogger logger = getLogger();
+                    search(master.getRepositoryUrl(), null, fromRevision, toRevision, this, logger);
+                }
 
-			};
-			support.start(rp, master.getRepositoryUrl(), NbBundle.getMessage(SearchExecutor.class, &quot;MSG_Search_Progress&quot;)); // NOI18N
-		} else
-			for (Iterator i = workFiles.keySet().iterator(); i.hasNext();) {
-				final String rootUrl = (String) i.next();
-				final Set&lt;File&gt; files = workFiles.get(rootUrl);
-				RequestProcessor rp = Git.getInstance().getRequestProcessor(rootUrl);
-				GitProgressSupport support = new GitProgressSupport() {
+            };
+            support.start(rp, master.getRepositoryUrl(), NbBundle.getMessage(SearchExecutor.class, &quot;MSG_Search_Progress&quot;)); // NOI18N
+        } else
+            for (Iterator i = workFiles.keySet().iterator(); i.hasNext();) {
+                final String rootUrl = (String) i.next();
+                final Set&lt;File&gt; files = workFiles.get(rootUrl);
+                RequestProcessor rp = Git.getInstance().getRequestProcessor(rootUrl);
+                GitProgressSupport support = new GitProgressSupport() {
 
-					public void perform()
-					{
-						OutputLogger logger = getLogger();
-						search(rootUrl, files, fromRevision, toRevision, this, logger);
-					}
+                    public void perform()
+                    {
+                        OutputLogger logger = getLogger();
+                        search(rootUrl, files, fromRevision, toRevision, this, logger);
+                    }
 
-				};
-				support.start(rp, rootUrl, NbBundle.getMessage(SearchExecutor.class, &quot;MSG_Search_Progress&quot;)); // NOI18N
-			}
-	}
+                };
+                support.start(rp, rootUrl, NbBundle.getMessage(SearchExecutor.class, &quot;MSG_Search_Progress&quot;)); // NOI18N
+            }
+    }
 
-	private void search(String rootUrl, Set&lt;File&gt; files, String fromRevision,
-		String toRevision, GitProgressSupport progressSupport, OutputLogger logger)
-	{
-		if (progressSupport.isCanceled()) {
-			searchCanceled = true;
-			return;
-		}
+    private void search(String rootUrl, Set&lt;File&gt; files, String fromRevision,
+        String toRevision, GitProgressSupport progressSupport, OutputLogger logger)
+    {
+        if (progressSupport.isCanceled()) {
+            searchCanceled = true;
+            return;
+        }
 
-		RepositoryRevision.Walk walk;
-		/*
-		if (master.isIncomingSearch()) {
-		messages = GitCommand.getIncomingMessages(rootUrl, toRevision, master.isShowMerges(), logger);
-		}else if (master.isOutSearch()) {
-		messages = GitCommand.getOutMessages(rootUrl, master.isShowMerges(), logger);
-		} else {
-		 */
-		walk = GitCommand.getLogMessages(rootUrl, files, fromRevision, toRevision,
-			master.isShowMerges(), logger);
-		//}
-		if (walk != null)
-			appendResults(rootUrl, walk);
-	}
+        RepositoryRevision.Walk walk;
+        /*
+        if (master.isIncomingSearch()) {
+        messages = GitCommand.getIncomingMessages(rootUrl, toRevision, master.isShowMerges(), logger);
+        }else if (master.isOutSearch()) {
+        messages = GitCommand.getOutMessages(rootUrl, master.isShowMerges(), logger);
+        } else {
+         */
+        walk = GitCommand.getLogMessages(rootUrl, files, fromRevision, toRevision,
+            master.isShowMerges(), logger);
+        //}
+        if (walk != null)
+            appendResults(rootUrl, walk);
+    }
 
-	private void setupRevFilter(RepositoryRevision.Walk walk)
-	{
-		RevFilter filter = walk.getRevFilter();
+    private void setupRevFilter(RepositoryRevision.Walk walk)
+    {
+        RevFilter filter = walk.getRevFilter();
 
-		if (filterUsername) {
-			RevFilter author = AuthorRevFilter.create(criteria.getUsername());
+        if (filterUsername) {
+            RevFilter author = AuthorRevFilter.create(criteria.getUsername());
 
-			if (filter == RevFilter.ALL)
-				filter = author;
-			else
-				filter = AndRevFilter.create(filter, author);
-		}
+            if (filter == RevFilter.ALL)
+                filter = author;
+            else
+                filter = AndRevFilter.create(filter, author);
+        }
 
-		if (filterMessage) {
-			RevFilter message = MessageRevFilter.create(criteria.getCommitMessage());
-			if (filter == RevFilter.ALL)
-				filter = message;
-			else
-				filter = AndRevFilter.create(filter, message);
-		}
+        if (filterMessage) {
+            RevFilter message = MessageRevFilter.create(criteria.getCommitMessage());
+            if (filter == RevFilter.ALL)
+                filter = message;
+            else
+                filter = AndRevFilter.create(filter, message);
+        }
 
-		walk.setRevFilter(filter);
-	}
+        walk.setRevFilter(filter);
+    }
 
-	/**
-	 * Processes search results from a single repository. 
-	 * 
-	 * @param rootUrl repository root URL
-	 * @param logMessages events in chronological order
-	 */
-	private synchronized void appendResults(String rootUrl, RepositoryRevision.Walk walk)
-	{
-		Map&lt;String, String&gt; historyPaths = new HashMap&lt;String, String&gt;();
-		RevFilter filter = walk.getRevFilter();
+    /**
+     * Processes search results from a single repository.
+     *
+     * @param rootUrl repository root URL
+     * @param logMessages events in chronological order
+     */
+    private synchronized void appendResults(String rootUrl, RepositoryRevision.Walk walk)
+    {
+        Map&lt;String, String&gt; historyPaths = new HashMap&lt;String, String&gt;();
+        RevFilter filter = walk.getRevFilter();
 
-		setupRevFilter(walk);
+        setupRevFilter(walk);
 
-		// traverse in reverse chronological order
-		for (RevCommit commit : walk) {
-			RepositoryRevision rev = (RepositoryRevision) commit;
-			for (RepositoryRevision.Event event : rev.createEvents(walk)) {
-				if (event.getChangedPath().getAction() == 'A' &amp;&amp; event.getChangedPath().getCopySrcPath() != null) {
-					// TBD: Need to handle Copy status
-					String existingMapping = historyPaths.get(event.getChangedPath().getPath());
-					if (existingMapping == null)
-						existingMapping = event.getChangedPath().getPath();
-					historyPaths.put(event.getChangedPath().getCopySrcPath(), existingMapping);
-				}
-				String originalFilePath = event.getChangedPath().getPath();
-				for (String srcPath : historyPaths.keySet()) {
-					if (originalFilePath.startsWith(srcPath) &amp;&amp;
-						(originalFilePath.length() == srcPath.length() || originalFilePath.charAt(srcPath.length()) == '/')) {
-						originalFilePath = historyPaths.get(srcPath) + originalFilePath.substring(srcPath.length());
-						break;
-					}
-				}
-				File file = new File(rootUrl + File.separator + originalFilePath);
-				event.setFile(file);
-			}
-			results.add(rev);
-		}
-		if (results.isEmpty())
-			results = null;
+        // traverse in reverse chronological order
+        for (RevCommit commit : walk) {
+            RepositoryRevision rev = (RepositoryRevision) commit;
+            for (RepositoryRevision.Event event : rev.createEvents(walk)) {
+                if (event.getChangedPath().getAction() == 'A' &amp;&amp; event.getChangedPath().getCopySrcPath() != null) {
+                    // TBD: Need to handle Copy status
+                    String existingMapping = historyPaths.get(event.getChangedPath().getPath());
+                    if (existingMapping == null)
+                        existingMapping = event.getChangedPath().getPath();
+                    historyPaths.put(event.getChangedPath().getCopySrcPath(), existingMapping);
+                }
+                String originalFilePath = event.getChangedPath().getPath();
+                for (String srcPath : historyPaths.keySet()) {
+                    if (originalFilePath.startsWith(srcPath) &amp;&amp;
+                        (originalFilePath.length() == srcPath.length() || originalFilePath.charAt(srcPath.length()) == '/')) {
+                        originalFilePath = historyPaths.get(srcPath) + originalFilePath.substring(srcPath.length());
+                        break;
+                    }
+                }
+                File file = new File(rootUrl + File.separator + originalFilePath);
+                event.setFile(file);
+            }
+            results.add(rev);
+        }
+        if (results.isEmpty())
+            results = null;
 
-		checkFinished();
-	}
+        checkFinished();
+    }
 
-	private boolean searchingUrl()
-	{
-		return master.getRepositoryUrl() != null;
-	}
+    private boolean searchingUrl()
+    {
+        return master.getRepositoryUrl() != null;
+    }
 
-	private void checkFinished()
-	{
-		completedSearches++;
-		if (searchingUrl() &amp;&amp; completedSearches &gt;= 1 || workFiles.size() == completedSearches)
-			SwingUtilities.invokeLater(new Runnable() {
+    private void checkFinished()
+    {
+        completedSearches++;
+        if (searchingUrl() &amp;&amp; completedSearches &gt;= 1 || workFiles.size() == completedSearches)
+            SwingUtilities.invokeLater(new Runnable() {
 
-				public void run()
-				{
-					master.setResults(results);
-				}
+                public void run()
+                {
+                    master.setResults(results);
+                }
 
-			});
-	}
+            });
+    }
 
 }
\ No newline at end of file</diff>
      <filename>src/org/nbgit/ui/log/SearchExecutor.java</filename>
    </modified>
    <modified>
      <diff>@@ -54,167 +54,167 @@ import org.openide.windows.TopComponent;
 
 /**
  * Opens Search History Component.
- * 
+ *
  * @author Maros Sandor
  */
 public class SearchHistoryAction extends ContextAction {
 
-	static final int DIRECTORY_ENABLED_STATUS = StatusInfo.STATUS_MANAGED &amp; ~StatusInfo.STATUS_NOTVERSIONED_EXCLUDED &amp; ~StatusInfo.STATUS_NOTVERSIONED_NEWLOCALLY;
-	static final int FILE_ENABLED_STATUS = StatusInfo.STATUS_MANAGED &amp; ~StatusInfo.STATUS_NOTVERSIONED_EXCLUDED &amp; ~StatusInfo.STATUS_NOTVERSIONED_NEWLOCALLY;
-
-	public SearchHistoryAction(String name, VCSContext context)
-	{
-		super(name, context);
-	}
-
-	protected String getBaseName(Node[] activatedNodes)
-	{
-		return &quot;CTL_MenuItem_SearchHistory&quot;; // NOI18N
-	}
-
-	protected int getFileEnabledStatus()
-	{
-		return FILE_ENABLED_STATUS;
-	}
-
-	protected int getDirectoryEnabledStatus()
-	{
-		return DIRECTORY_ENABLED_STATUS;
-	}
-
-	protected boolean asynchronous()
-	{
-		return false;
-	}
-
-	public void performAction(ActionEvent e)
-	{
-		String title = NbBundle.getMessage(SearchHistoryAction.class, &quot;CTL_SearchHistory_Title&quot;, Utils.getContextDisplayName(context)); // NOI18N
-		openHistory(context, title);
-	}
-
-	public static void openHistory(final VCSContext context, final String title)
-	{
-		SwingUtilities.invokeLater(new Runnable() {
-
-			public void run()
-			{
-				if (context == null)
-					return;
-				SearchHistoryTopComponent tc = new SearchHistoryTopComponent(context);
-				tc.setDisplayName(title);
-				tc.open();
-				tc.requestActive();
-				tc.search(true);
-			}
-
-		});
-	}
-
-	/**
-	 * Opens the Search History panel to view Git Changesets that will be sent on next Pull from remote repo
-	 * using: git incoming - to get the data
-	 * 
-	 * @param title title of the search
-	 * @param commitMessage commit message to search for
-	 * @param username user name to search for
-	 * @param date date of the change in question
-	 */
-	public static void openIncoming(final VCSContext context, final String title)
-	{
-		SwingUtilities.invokeLater(new Runnable() {
-
-			public void run()
-			{
-				if (context == null)
-					return;
-				SearchHistoryTopComponent tc = new SearchHistoryTopComponent(context);
-				tc.setDisplayName(title);
-				tc.open();
-				tc.requestActive();
-				tc.searchIncoming();
-			}
-
-		});
-	}
-
-	/**
-	 * Opens the Search History panel to view Git Out Changesets that will be sent on next Push to remote repo
-	 * using: git out - to get the data
-	 * 
-	 * @param title title of the search
-	 * @param commitMessage commit message to search for
-	 * @param username user name to search for
-	 * @param date date of the change in question
-	 */
-	public static void openOut(final VCSContext context, final String title)
-	{
-		SwingUtilities.invokeLater(new Runnable() {
-
-			public void run()
-			{
-				if (context == null)
-					return;
-				SearchHistoryTopComponent tc = new SearchHistoryTopComponent(context);
-				tc.setDisplayName(title);
-				tc.open();
-				tc.requestActive();
-				tc.searchOut();
-			}
-
-		});
-	}
-
-	/**
-	 * Opens the Search History panel with given pre-filled values. The search is executed in default context
-	 * (all open projects). 
-	 * 
-	 * @param title title of the search
-	 * @param commitMessage commit message to search for
-	 * @param username user name to search for
-	 * @param rev the revision of the change in question
-	 */
-	public static void openSearch(String title, String commitMessage, String username, String rev)
-	{
-		openSearch(getDefaultContext(), title, commitMessage, username, rev);
-	}
-
-	public static void openSearch(VCSContext context, String title, String commitMessage, String username, String from)
-	{
-		String to = from + &quot;~20&quot;;
-
-		if (commitMessage != null &amp;&amp; commitMessage.indexOf('\n') != -1)
-			commitMessage = commitMessage.substring(0, commitMessage.indexOf('\n'));
-		SearchHistoryTopComponent tc = new SearchHistoryTopComponent(context, commitMessage, username, from, to);
-		String tcTitle = NbBundle.getMessage(SearchHistoryAction.class, &quot;CTL_SearchHistory_Title&quot;, title); // NOI18N
-		tc.setDisplayName(tcTitle);
-		tc.open();
-		tc.requestActive();
-		tc.search(false);
-	}
-
-	private static VCSContext getDefaultContext()
-	{
-		Node[] nodes = TopComponent.getRegistry().getActivatedNodes();
-
-		return nodes != null ? VCSContext.forNodes(nodes) : VCSContext.EMPTY;
-	}
-
-	/**
-	 * Opens search panel in the context of the given repository URL.
-	 * 
-	 * @param repositoryUrl URL to search
-	 * @param localRoot local working copy root that corresponds to the repository URL 
-	 * @param revision revision to search for
-	 */
-	public static void openSearch(String repositoryUrl, File localRoot, String revision)
-	{
-		SearchHistoryTopComponent tc = new SearchHistoryTopComponent(repositoryUrl, localRoot, revision);
-		String tcTitle = NbBundle.getMessage(SearchHistoryAction.class, &quot;CTL_SearchHistory_Title&quot;, repositoryUrl); // NOI18N
-		tc.setDisplayName(tcTitle);
-		tc.open();
-		tc.requestActive();
-		tc.search(false);
-	}
+    static final int DIRECTORY_ENABLED_STATUS = StatusInfo.STATUS_MANAGED &amp; ~StatusInfo.STATUS_NOTVERSIONED_EXCLUDED &amp; ~StatusInfo.STATUS_NOTVERSIONED_NEWLOCALLY;
+    static final int FILE_ENABLED_STATUS = StatusInfo.STATUS_MANAGED &amp; ~StatusInfo.STATUS_NOTVERSIONED_EXCLUDED &amp; ~StatusInfo.STATUS_NOTVERSIONED_NEWLOCALLY;
+
+    public SearchHistoryAction(String name, VCSContext context)
+    {
+        super(name, context);
+    }
+
+    protected String getBaseName(Node[] activatedNodes)
+    {
+        return &quot;CTL_MenuItem_SearchHistory&quot;; // NOI18N
+    }
+
+    protected int getFileEnabledStatus()
+    {
+        return FILE_ENABLED_STATUS;
+    }
+
+    protected int getDirectoryEnabledStatus()
+    {
+        return DIRECTORY_ENABLED_STATUS;
+    }
+
+    protected boolean asynchronous()
+    {
+        return false;
+    }
+
+    public void performAction(ActionEvent e)
+    {
+        String title = NbBundle.getMessage(SearchHistoryAction.class, &quot;CTL_SearchHistory_Title&quot;, Utils.getContextDisplayName(context)); // NOI18N
+        openHistory(context, title);
+    }
+
+    public static void openHistory(final VCSContext context, final String title)
+    {
+        SwingUtilities.invokeLater(new Runnable() {
+
+            public void run()
+            {
+                if (context == null)
+                    return;
+                SearchHistoryTopComponent tc = new SearchHistoryTopComponent(context);
+                tc.setDisplayName(title);
+                tc.open();
+                tc.requestActive();
+                tc.search(true);
+            }
+
+        });
+    }
+
+    /**
+     * Opens the Search History panel to view Git Changesets that will be sent on next Pull from remote repo
+     * using: git incoming - to get the data
+     *
+     * @param title title of the search
+     * @param commitMessage commit message to search for
+     * @param username user name to search for
+     * @param date date of the change in question
+     */
+    public static void openIncoming(final VCSContext context, final String title)
+    {
+        SwingUtilities.invokeLater(new Runnable() {
+
+            public void run()
+            {
+                if (context == null)
+                    return;
+                SearchHistoryTopComponent tc = new SearchHistoryTopComponent(context);
+                tc.setDisplayName(title);
+                tc.open();
+                tc.requestActive();
+                tc.searchIncoming();
+            }
+
+        });
+    }
+
+    /**
+     * Opens the Search History panel to view Git Out Changesets that will be sent on next Push to remote repo
+     * using: git out - to get the data
+     *
+     * @param title title of the search
+     * @param commitMessage commit message to search for
+     * @param username user name to search for
+     * @param date date of the change in question
+     */
+    public static void openOut(final VCSContext context, final String title)
+    {
+        SwingUtilities.invokeLater(new Runnable() {
+
+            public void run()
+            {
+                if (context == null)
+                    return;
+                SearchHistoryTopComponent tc = new SearchHistoryTopComponent(context);
+                tc.setDisplayName(title);
+                tc.open();
+                tc.requestActive();
+                tc.searchOut();
+            }
+
+        });
+    }
+
+    /**
+     * Opens the Search History panel with given pre-filled values. The search is executed in default context
+     * (all open projects).
+     *
+     * @param title title of the search
+     * @param commitMessage commit message to search for
+     * @param username user name to search for
+     * @param rev the revision of the change in question
+     */
+    public static void openSearch(String title, String commitMessage, String username, String rev)
+    {
+        openSearch(getDefaultContext(), title, commitMessage, username, rev);
+    }
+
+    public static void openSearch(VCSContext context, String title, String commitMessage, String username, String from)
+    {
+        String to = from + &quot;~20&quot;;
+
+        if (commitMessage != null &amp;&amp; commitMessage.indexOf('\n') != -1)
+            commitMessage = commitMessage.substring(0, commitMessage.indexOf('\n'));
+        SearchHistoryTopComponent tc = new SearchHistoryTopComponent(context, commitMessage, username, from, to);
+        String tcTitle = NbBundle.getMessage(SearchHistoryAction.class, &quot;CTL_SearchHistory_Title&quot;, title); // NOI18N
+        tc.setDisplayName(tcTitle);
+        tc.open();
+        tc.requestActive();
+        tc.search(false);
+    }
+
+    private static VCSContext getDefaultContext()
+    {
+        Node[] nodes = TopComponent.getRegistry().getActivatedNodes();
+
+        return nodes != null ? VCSContext.forNodes(nodes) : VCSContext.EMPTY;
+    }
+
+    /**
+     * Opens search panel in the context of the given repository URL.
+     *
+     * @param repositoryUrl URL to search
+     * @param localRoot local working copy root that corresponds to the repository URL
+     * @param revision revision to search for
+     */
+    public static void openSearch(String repositoryUrl, File localRoot, String revision)
+    {
+        SearchHistoryTopComponent tc = new SearchHistoryTopComponent(repositoryUrl, localRoot, revision);
+        String tcTitle = NbBundle.getMessage(SearchHistoryAction.class, &quot;CTL_SearchHistory_Title&quot;, repositoryUrl); // NOI18N
+        tc.setDisplayName(tcTitle);
+        tc.open();
+        tc.requestActive();
+        tc.search(false);
+    }
 
 }
\ No newline at end of file</diff>
      <filename>src/org/nbgit/ui/log/SearchHistoryAction.java</filename>
    </modified>
    <modified>
      <diff>@@ -83,7 +83,7 @@ class SearchHistoryPanel extends javax.swing.JPanel implements ExplorerManager.P
     private final File[]                roots;
     private final String                repositoryUrl;
     private final SearchCriteriaPanel   criteria;
-    
+
     private Divider                 divider;
     private Action                  searchAction;
     private SearchExecutor          currentSearch;
@@ -92,7 +92,7 @@ class SearchHistoryPanel extends javax.swing.JPanel implements ExplorerManager.P
     private boolean                 criteriaVisible;
     private boolean                 searchInProgress;
     private List&lt;RepositoryRevision&gt; results;
-    private SummaryView             summaryView;    
+    private SummaryView             summaryView;
     private DiffResultsView         diffView;
     private boolean                 bOutSearch;
     private boolean                 bIncomingSearch;
@@ -112,7 +112,7 @@ class SearchHistoryPanel extends javax.swing.JPanel implements ExplorerManager.P
         setupComponents();
         refreshComponents(true);
     }
-    
+
     public SearchHistoryPanel(String repositoryUrl, File localRoot, SearchCriteriaPanel criteria) {
         this.bOutSearch = false;
         this.bIncomingSearch = false;
@@ -143,7 +143,7 @@ class SearchHistoryPanel extends javax.swing.JPanel implements ExplorerManager.P
         return showMergesChkBox.isSelected();
     }
 
-    
+
     void setIncomingSearch() {
         criteria.setForIncoming();
         bIncomingSearch = true;
@@ -153,7 +153,7 @@ class SearchHistoryPanel extends javax.swing.JPanel implements ExplorerManager.P
         showMergesChkBox.setToolTipText(NbBundle.getMessage(SearchHistoryPanel.class,  &quot;TT_IncomingShowMerges&quot;));
         tbSummary.setToolTipText(NbBundle.getMessage(SearchHistoryPanel.class,  &quot;TT_IncomingSummary&quot;));
     }
-    
+
     boolean isIncomingSearch() {
         return bIncomingSearch;
     }
@@ -189,13 +189,13 @@ class SearchHistoryPanel extends javax.swing.JPanel implements ExplorerManager.P
         getActionMap().put(&quot;search&quot;, searchAction); // NOI18N
         bSearch.setAction(searchAction);
         Mnemonics.setLocalizedText(bSearch, NbBundle.getMessage(SearchHistoryPanel.class,  &quot;CTL_Search&quot;)); // NOI18N
-        
+
         Dimension d1 = tbSummary.getPreferredSize();
         Dimension d2 = tbDiff.getPreferredSize();
         if (d1.width &gt; d2.width) {
             tbDiff.setPreferredSize(d1);
         }
-        
+
         nextAction = new AbstractAction(null, new javax.swing.ImageIcon(getClass().getResource(&quot;/org/nbgit/resources/icons/diff-next.png&quot;))) { // NOI18N
             {
                 putValue(Action.SHORT_DESCRIPTION, java.util.ResourceBundle.getBundle(&quot;org/nbgit/ui/diff/Bundle&quot;). // NOI18N
@@ -219,10 +219,10 @@ class SearchHistoryPanel extends javax.swing.JPanel implements ExplorerManager.P
 
         criteria.tfFrom.getDocument().addDocumentListener(this);
         criteria.tfTo.getDocument().addDocumentListener(this);
-        
+
         getActionMap().put(&quot;jumpNext&quot;, nextAction); // NOI18N
         getActionMap().put(&quot;jumpPrev&quot;, prevAction); // NOI18N
-        
+
         showMergesChkBox.setSelected(GitModuleConfig.getDefault().getShowHistoryMerges());
         showMergesChkBox.setOpaque(false);
     }
@@ -253,11 +253,11 @@ class SearchHistoryPanel extends javax.swing.JPanel implements ExplorerManager.P
         explorerManager.removePropertyChangeListener(this);
         super.removeNotify();
     }
-    
+
     public ExplorerManager getExplorerManager () {
         return explorerManager;
     }
-    
+
     final void refreshComponents(boolean refreshResults) {
         if (refreshResults) {
             resultsPanel.removeAll();
@@ -292,7 +292,7 @@ class SearchHistoryPanel extends javax.swing.JPanel implements ExplorerManager.P
         revalidate();
         repaint();
     }
-    
+
     public void setResults(List&lt;RepositoryRevision&gt; newResults) {
         setResults(newResults, false);
     }
@@ -311,7 +311,7 @@ class SearchHistoryPanel extends javax.swing.JPanel implements ExplorerManager.P
 
     public String getSearchRepositoryRootUrl() {
         if (repositoryUrl != null) return repositoryUrl;
-        
+
         File root = Git.getInstance().getTopmostManagedParent(roots[0]);
         return root.toString();
     }
@@ -333,7 +333,7 @@ class SearchHistoryPanel extends javax.swing.JPanel implements ExplorerManager.P
         currentSearchTask = RequestProcessor.getDefault().create(currentSearch);
         currentSearchTask.schedule(0);
     }
-    
+
     void executeSearch() {
         search();
     }
@@ -365,12 +365,12 @@ class SearchHistoryPanel extends javax.swing.JPanel implements ExplorerManager.P
             return summaryView.getSetups();
         }
     }
-    
+
     Collection getSetups(RepositoryRevision [] revisions, RepositoryRevision.Event [] events) {
         long fromRevision = Long.MAX_VALUE;
         long toRevision = Long.MIN_VALUE;
         Set&lt;File&gt; filesToDiff = new HashSet&lt;File&gt;();
-        
+
         for (RepositoryRevision revision : revisions) {
             long rev = 0; //Long.parseLong(revision.getLog().getRevision());
             if (rev &gt; toRevision) toRevision = rev;
@@ -400,7 +400,7 @@ class SearchHistoryPanel extends javax.swing.JPanel implements ExplorerManager.P
         }
         return setups;
     }
-    
+
     public String getSetupDisplayName() {
         return null;
     }
@@ -420,7 +420,7 @@ class SearchHistoryPanel extends javax.swing.JPanel implements ExplorerManager.P
             if (n1 != n2) return n2 - n1;
         }
     }
-    
+
     /** This method is called from within the constructor to
      * initialize the form.
      * WARNING: Do NOT modify this code. The content of this method is
@@ -557,13 +557,13 @@ private void showMergesChkBoxStateChanged(javax.swing.event.ChangeEvent evt) {//
     }
 
     public void removeUpdate(DocumentEvent e) {
-        validateUserInput();        
+        validateUserInput();
     }
 
     public void changedUpdate(DocumentEvent e) {
-        validateUserInput();        
+        validateUserInput();
     }
-    
+
     private void validateUserInput() {
         String from = criteria.getFrom();
         if(from == null &amp;&amp; criteria.tfFrom.getText().trim().length() &gt; 0) {
@@ -574,10 +574,10 @@ private void showMergesChkBoxStateChanged(javax.swing.event.ChangeEvent evt) {//
         if(to == null &amp;&amp; criteria.tfTo.getText().trim().length() &gt; 0) {
             bSearch.setEnabled(false);
             return;
-        }        
+        }
         bSearch.setEnabled(true);
-    }    
-    
+    }
+
     // Variables declaration - do not modify//GEN-BEGIN:variables
     private javax.swing.JButton bNext;
     private javax.swing.JButton bPrev;
@@ -593,5 +593,5 @@ private void showMergesChkBoxStateChanged(javax.swing.event.ChangeEvent evt) {//
     private javax.swing.JToggleButton tbDiff;
     private javax.swing.JToggleButton tbSummary;
     // End of variables declaration//GEN-END:variables
-    
+
 }
\ No newline at end of file</diff>
      <filename>src/org/nbgit/ui/log/SearchHistoryPanel.java</filename>
    </modified>
    <modified>
      <diff>@@ -56,119 +56,119 @@ import org.spearce.jgit.lib.Constants;
  */
 public class SearchHistoryTopComponent extends TopComponent implements DiffSetupSource {
 
-	private SearchHistoryPanel shp;
-	private SearchCriteriaPanel scp;
-
-	public SearchHistoryTopComponent()
-	{
-	        setIcon(org.openide.util.Utilities.loadImage(&quot;org/nbgit/resources/icons/gitvcs-icon.png&quot;));  // NOI18N
-		getAccessibleContext().setAccessibleName(NbBundle.getMessage(SearchHistoryTopComponent.class, &quot;ACSN_SearchHistoryT_Top_Component&quot;)); // NOI18N
-		getAccessibleContext().setAccessibleDescription(NbBundle.getMessage(SearchHistoryTopComponent.class, &quot;ACSD_SearchHistoryT_Top_Component&quot;)); // NOI18N
-	}
-
-	public SearchHistoryTopComponent(VCSContext context)
-	{
-		this(context, null, null, null, null);
-	}
-
-	public SearchHistoryTopComponent(VCSContext context, String commitMessage, String username, String from, String to)
-	{
-		this();
-		File[] roots = context.getRootFiles().toArray(new File[0]);
-		initComponents(roots, commitMessage, username, from, to);
-	}
-
-	public SearchHistoryTopComponent(String repositoryUrl, File localRoot, String revision)
-	{
-		this();
-		initComponents(repositoryUrl, localRoot, revision);
-	}
-
-	public void search(boolean showSearchCriteria)
-	{
-		shp.executeSearch();
-		shp.setSearchCriteria(showSearchCriteria);
-	}
-
-	public void searchOut()
-	{
-		shp.setOutSearch();
-		shp.executeSearch();
-		shp.setSearchCriteria(false);
-		scp.setFrom(&quot;&quot;);
-		scp.setTo(&quot;&quot;);
-	}
-
-	public void searchIncoming()
-	{
-		shp.setIncomingSearch();
-		scp.setFrom(&quot;&quot;);
-		scp.setTo(&quot;&quot;);
-	}
-
-	private void initComponents(String repositoryUrl, File localRoot, String revision)
-	{
-		setLayout(new BorderLayout());
-		scp = new SearchCriteriaPanel(repositoryUrl);
-		scp.setFrom(revision);
-		scp.setTo(revision);
-		shp = new SearchHistoryPanel(repositoryUrl, localRoot, scp);
-		add(shp);
-	}
-
-	private void initComponents(File[] roots, String commitMessage, String username, String from, String to)
-	{
-		setLayout(new BorderLayout());
-		scp = new SearchCriteriaPanel(roots);
-		scp.setCommitMessage(commitMessage);
-		scp.setUsername(username);
-		if (from == null)
-			from = Constants.HEAD;
-		scp.setFrom(from);
-		if (to == null)
-			to = &quot;&quot;;
-		scp.setTo(to);
-		shp = new SearchHistoryPanel(roots, scp);
-		add(shp);
-	}
-
-	@Override
-	public int getPersistenceType()
-	{
-		return TopComponent.PERSISTENCE_NEVER;
-	}
-
-	@Override
-	protected void componentClosed()
-	{
-		//((DiffMainPanel) getComponent(0)).componentClosed();
-		super.componentClosed();
-	}
-
-	@Override
-	protected String preferredID()
-	{
-		if (shp.isIncomingSearch())
-			return &quot;Git.IncomingSearchHistoryTopComponent&quot;;
-		else if (shp.isOutSearch())
-			return &quot;Git.OutSearchHistoryTopComponent&quot;;
-		return &quot;Git.SearchHistoryTopComponent&quot;;    // NOI18N
-	}
-
-	@Override
-	public HelpCtx getHelpCtx()
-	{
-		return new HelpCtx(getClass());
-	}
-
-	public Collection getSetups()
-	{
-		return shp.getSetups();
-	}
-
-	public String getSetupDisplayName()
-	{
-		return getDisplayName();
-	}
+    private SearchHistoryPanel shp;
+    private SearchCriteriaPanel scp;
+
+    public SearchHistoryTopComponent()
+    {
+            setIcon(org.openide.util.Utilities.loadImage(&quot;org/nbgit/resources/icons/gitvcs-icon.png&quot;));  // NOI18N
+        getAccessibleContext().setAccessibleName(NbBundle.getMessage(SearchHistoryTopComponent.class, &quot;ACSN_SearchHistoryT_Top_Component&quot;)); // NOI18N
+        getAccessibleContext().setAccessibleDescription(NbBundle.getMessage(SearchHistoryTopComponent.class, &quot;ACSD_SearchHistoryT_Top_Component&quot;)); // NOI18N
+    }
+
+    public SearchHistoryTopComponent(VCSContext context)
+    {
+        this(context, null, null, null, null);
+    }
+
+    public SearchHistoryTopComponent(VCSContext context, String commitMessage, String username, String from, String to)
+    {
+        this();
+        File[] roots = context.getRootFiles().toArray(new File[0]);
+        initComponents(roots, commitMessage, username, from, to);
+    }
+
+    public SearchHistoryTopComponent(String repositoryUrl, File localRoot, String revision)
+    {
+        this();
+        initComponents(repositoryUrl, localRoot, revision);
+    }
+
+    public void search(boolean showSearchCriteria)
+    {
+        shp.executeSearch();
+        shp.setSearchCriteria(showSearchCriteria);
+    }
+
+    public void searchOut()
+    {
+        shp.setOutSearch();
+        shp.executeSearch();
+        shp.setSearchCriteria(false);
+        scp.setFrom(&quot;&quot;);
+        scp.setTo(&quot;&quot;);
+    }
+
+    public void searchIncoming()
+    {
+        shp.setIncomingSearch();
+        scp.setFrom(&quot;&quot;);
+        scp.setTo(&quot;&quot;);
+    }
+
+    private void initComponents(String repositoryUrl, File localRoot, String revision)
+    {
+        setLayout(new BorderLayout());
+        scp = new SearchCriteriaPanel(repositoryUrl);
+        scp.setFrom(revision);
+        scp.setTo(revision);
+        shp = new SearchHistoryPanel(repositoryUrl, localRoot, scp);
+        add(shp);
+    }
+
+    private void initComponents(File[] roots, String commitMessage, String username, String from, String to)
+    {
+        setLayout(new BorderLayout());
+        scp = new SearchCriteriaPanel(roots);
+        scp.setCommitMessage(commitMessage);
+        scp.setUsername(username);
+        if (from == null)
+            from = Constants.HEAD;
+        scp.setFrom(from);
+        if (to == null)
+            to = &quot;&quot;;
+        scp.setTo(to);
+        shp = new SearchHistoryPanel(roots, scp);
+        add(shp);
+    }
+
+    @Override
+    public int getPersistenceType()
+    {
+        return TopComponent.PERSISTENCE_NEVER;
+    }
+
+    @Override
+    protected void componentClosed()
+    {
+        //((DiffMainPanel) getComponent(0)).componentClosed();
+        super.componentClosed();
+    }
+
+    @Override
+    protected String preferredID()
+    {
+        if (shp.isIncomingSearch())
+            return &quot;Git.IncomingSearchHistoryTopComponent&quot;;
+        else if (shp.isOutSearch())
+            return &quot;Git.OutSearchHistoryTopComponent&quot;;
+        return &quot;Git.SearchHistoryTopComponent&quot;;    // NOI18N
+    }
+
+    @Override
+    public HelpCtx getHelpCtx()
+    {
+        return new HelpCtx(getClass());
+    }
+
+    public Collection getSetups()
+    {
+        return shp.getSetups();
+    }
+
+    public String getSetupDisplayName()
+    {
+        return getDisplayName();
+    }
 
 }
\ No newline at end of file</diff>
      <filename>src/org/nbgit/ui/log/SearchHistoryTopComponent.java</filename>
    </modified>
    <modified>
      <diff>@@ -107,725 +107,725 @@ import org.openide.windows.TopComponent;
 
 /**
  * Shows Search History results in a JList.
- * 
+ *
  * @author Maros Sandor
  */
 class SummaryView implements MouseListener, ComponentListener, MouseMotionListener, DiffSetupSource {
 
-	private static final String SUMMARY_DIFF_PROPERTY = &quot;Summary-Diff-&quot;;
-	private static final String SUMMARY_REVERT_PROPERTY = &quot;Summary-Revert-&quot;;
-	private static final String SUMMARY_EXPORTDIFFS_PROPERTY = &quot;Summary-ExportDiffs-&quot;;
-	private final SearchHistoryPanel master;
-	private JList resultsList;
-	private JScrollPane scrollPane;
-	private final List dispResults;
-	private String message;
-	private AttributeSet searchHiliteAttrs;
-	private List&lt;RepositoryRevision&gt; results;
-
-	public SummaryView(SearchHistoryPanel master, List&lt;RepositoryRevision&gt; results)
-	{
-		this.master = master;
-		this.results = results;
-		this.dispResults = expandResults(results);
-		FontColorSettings fcs = MimeLookup.getLookup(MimePath.get(&quot;text/x-java&quot;)).lookup(FontColorSettings.class); // NOI18N
-		searchHiliteAttrs = fcs.getFontColors(&quot;highlight-search&quot;); // NOI18N
-		message = master.getCriteria().getCommitMessage();
-		resultsList = new JList(new SummaryListModel());
-		resultsList.setFixedCellHeight(-1);
-		resultsList.addMouseListener(this);
-		resultsList.addMouseMotionListener(this);
-		resultsList.setCellRenderer(new SummaryCellRenderer());
-		resultsList.getAccessibleContext().setAccessibleName(NbBundle.getMessage(SummaryView.class, &quot;ACSN_SummaryView_List&quot;)); // NOI18N
-		resultsList.getAccessibleContext().setAccessibleDescription(NbBundle.getMessage(SummaryView.class, &quot;ACSD_SummaryView_List&quot;)); // NOI18N
-		scrollPane = new JScrollPane(resultsList, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
-		master.addComponentListener(this);
-		resultsList.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(
-			KeyStroke.getKeyStroke(KeyEvent.VK_F10, KeyEvent.SHIFT_DOWN_MASK), &quot;org.openide.actions.PopupAction&quot;);
-		resultsList.getActionMap().put(&quot;org.openide.actions.PopupAction&quot;, new AbstractAction() {
-
-			public void actionPerformed(ActionEvent e)
-			{
-				onPopup(org.netbeans.modules.versioning.util.Utils.getPositionForPopup(resultsList));
-			}
-
-		});
-	}
-
-	public void componentResized(ComponentEvent e)
-	{
-		int[] selection = resultsList.getSelectedIndices();
-		resultsList.setModel(new SummaryListModel());
-		resultsList.setSelectedIndices(selection);
-	}
-
-	public void componentHidden(ComponentEvent e)
-	{
-		// not interested
-	}
-
-	public void componentMoved(ComponentEvent e)
-	{
-		// not interested
-	}
-
-	public void componentShown(ComponentEvent e)
-	{
-		// not interested
-	}
-
-	@SuppressWarnings(&quot;unchecked&quot;)
-	private List expandResults(List&lt;RepositoryRevision&gt; results)
-	{
-		ArrayList newResults = new ArrayList(results.size());
-		for (RepositoryRevision repositoryRevision : results) {
-			newResults.add(repositoryRevision);
-			List&lt;RepositoryRevision.Event&gt; events = repositoryRevision.getEvents();
-			for (RepositoryRevision.Event event : events) {
-				newResults.add(event);
-			}
-		}
-		return newResults;
-	}
-
-	public void mouseClicked(MouseEvent e)
-	{
-		int idx = resultsList.locationToIndex(e.getPoint());
-		if (idx == -1)
-			return;
-		Rectangle rect = resultsList.getCellBounds(idx, idx);
-		Point p = new Point(e.getX() - rect.x, e.getY() - rect.y);
-		Rectangle diffBounds = (Rectangle) resultsList.getClientProperty(SUMMARY_DIFF_PROPERTY + idx); // NOI18N
-		if (diffBounds != null &amp;&amp; diffBounds.contains(p))
-			diffPrevious(idx);
-		diffBounds = (Rectangle) resultsList.getClientProperty(SUMMARY_REVERT_PROPERTY + idx); // NOI18N
-		if (diffBounds != null &amp;&amp; diffBounds.contains(p))
-			revertModifications(new int[]{idx});
-	}
-
-	public void mouseEntered(MouseEvent e)
-	{
-		// not interested
-	}
-
-	public void mouseExited(MouseEvent e)
-	{
-		// not interested
-	}
-
-	public void mousePressed(MouseEvent e)
-	{
-		if (!master.isIncomingSearch() &amp;&amp; e.isPopupTrigger())
-			onPopup(e);
-	}
-
-	public void mouseReleased(MouseEvent e)
-	{
-		if (!master.isIncomingSearch() &amp;&amp; e.isPopupTrigger())
-			onPopup(e);
-	}
-
-	public void mouseDragged(MouseEvent e)
-	{
-	}
-
-	public void mouseMoved(MouseEvent e)
-	{
-		int idx = resultsList.locationToIndex(e.getPoint());
-		if (idx == -1)
-			return;
-		Rectangle rect = resultsList.getCellBounds(idx, idx);
-		Point p = new Point(e.getX() - rect.x, e.getY() - rect.y);
-		Rectangle diffBounds = (Rectangle) resultsList.getClientProperty(SUMMARY_DIFF_PROPERTY + idx); // NOI18N
-		if (diffBounds != null &amp;&amp; diffBounds.contains(p)) {
-			resultsList.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
-			return;
-		}
-		diffBounds = (Rectangle) resultsList.getClientProperty(SUMMARY_REVERT_PROPERTY + idx); // NOI18N
-		if (diffBounds != null &amp;&amp; diffBounds.contains(p)) {
-			resultsList.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
-			return;
-		}
-		diffBounds = (Rectangle) resultsList.getClientProperty(SUMMARY_EXPORTDIFFS_PROPERTY + idx); // NOI18N
-		if (diffBounds != null &amp;&amp; diffBounds.contains(p)) {
-			resultsList.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
-			return;
-		}
-		resultsList.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
-	}
-
-	public Collection getSetups()
-	{
-		Node[] nodes = TopComponent.getRegistry().getActivatedNodes();
-		if (nodes.length == 0)
-			return master.getSetups(results.toArray(new RepositoryRevision[results.size()]), new RepositoryRevision.Event[0]);
-
-		Set&lt;RepositoryRevision.Event&gt; events = new HashSet&lt;RepositoryRevision.Event&gt;();
-		Set&lt;RepositoryRevision&gt; revisions = new HashSet&lt;RepositoryRevision&gt;();
-
-		int[] sel = resultsList.getSelectedIndices();
-		for (int i : sel) {
-			Object revCon = dispResults.get(i);
-			if (revCon instanceof RepositoryRevision)
-				revisions.add((RepositoryRevision) revCon);
-			else
-				events.add((RepositoryRevision.Event) revCon);
-		}
-		return master.getSetups(revisions.toArray(new RepositoryRevision[revisions.size()]), events.toArray(new RepositoryRevision.Event[events.size()]));
-	}
-
-	public String getSetupDisplayName()
-	{
-		return null;
-	}
-
-	private void onPopup(MouseEvent e)
-	{
-		onPopup(e.getPoint());
-	}
-
-	private void onPopup(Point p)
-	{
-		int[] sel = resultsList.getSelectedIndices();
-		if (sel.length == 0) {
-			int idx = resultsList.locationToIndex(p);
-			if (idx == -1)
-				return;
-			resultsList.setSelectedIndex(idx);
-			sel = new int[]{idx};
-		}
-		final int[] selection = sel;
-
-		JPopupMenu menu = new JPopupMenu();
-
-		String previousRevision = null;
-		RepositoryRevision container = null;
-		final RepositoryRevision.Event[] drev;
-
-		Object revCon = dispResults.get(selection[0]);
-
-
-		boolean noExDeletedExistingFiles = true;
-		boolean revisionSelected;
-		boolean missingFile = false;
-		boolean oneRevisionMultiselected = true;
-
-		if (revCon instanceof RepositoryRevision) {
-			revisionSelected = true;
-			container = (RepositoryRevision) dispResults.get(selection[0]);
-			drev = new RepositoryRevision.Event[0];
-			oneRevisionMultiselected = true;
-			noExDeletedExistingFiles = true;
-		} else {
-			revisionSelected = false;
-			drev = new RepositoryRevision.Event[selection.length];
-
-			for (int i = 0; i &lt; selection.length; i++) {
-				drev[i] = (RepositoryRevision.Event) dispResults.get(selection[i]);
-
-				if (!missingFile &amp;&amp; drev[i].getFile() == null)
-					missingFile = true;
-				if (oneRevisionMultiselected &amp;&amp; i &gt; 0 &amp;&amp;
-					drev[0].getLogInfoHeader().getRevision().equals(drev[i].getLogInfoHeader().getRevision()))
-					oneRevisionMultiselected = false;
-				if (drev[i].getFile() != null &amp;&amp; drev[i].getFile().exists() &amp;&amp; drev[i].getChangedPath().getAction() == 'D')
-					noExDeletedExistingFiles = false;
-			}
-			container = drev[0].getLogInfoHeader();
-		}
-		long revision = 0; //Long.parseLong(container.getLog().getRevision());
-
-		final boolean rollbackToEnabled = !missingFile &amp;&amp; !revisionSelected &amp;&amp; oneRevisionMultiselected;
-		final boolean rollbackChangeEnabled = !missingFile &amp;&amp; oneRevisionMultiselected &amp;&amp; (drev.length == 0 || noExDeletedExistingFiles); // drev.length == 0 =&gt; the whole revision was selected
-		final boolean viewEnabled = selection.length == 1 &amp;&amp; !revisionSelected &amp;&amp; drev[0].getFile() != null &amp;&amp; drev[0].getFile().exists() &amp;&amp; !drev[0].getFile().isDirectory();
-		final boolean diffToPrevEnabled = selection.length == 1;
-
-		if (revision &gt; 0)
-			menu.add(new JMenuItem(new AbstractAction(NbBundle.getMessage(SummaryView.class, &quot;CTL_SummaryView_DiffToPrevious&quot;, &quot;&quot; + previousRevision)) { // NOI18N
-
-				{
-					setEnabled(diffToPrevEnabled);
-				}
-
-				public void actionPerformed(ActionEvent e)
-				{
-					diffPrevious(selection[0]);
-				}
-
-			}));
-
-		/* TBD - Support Rollback Changes:
-		 * Need to figure out how to implement SVN functionality to allow you to rollback a change
-		 * currently for svn this cmd runs: merge -R &lt;revX&gt;:&lt;revY&gt; it basically diffs the two revs
-		 * and creates a patch which is then applied ot the file in the working dir, effectively removing
-		 * the change applied between revX and revY
-		 * In hg we'd need to do a hg diff -r revX -r revY, generate a patch and then apply it to the working dir copy
-		 * /
-		menu.add(new JMenuItem(new AbstractAction(NbBundle.getMessage(SummaryView.class, &quot;CTL_SummaryView_RollbackChange&quot;)) { // NOI18N
-		{
-		setEnabled(false); // rollbackChangeEnabled); 
-		}
-		public void actionPerformed(ActionEvent e) {
-		revertModifications(selection);
-		}
-		}));
-		 */
-		if (!revisionSelected) {
-			menu.add(new JMenuItem(new AbstractAction(NbBundle.getMessage(SummaryView.class, &quot;CTL_SummaryView_RollbackTo&quot;, &quot;&quot; + revision)) { // NOI18N
-
-				{
-					setEnabled(rollbackToEnabled);
-				}
-
-				public void actionPerformed(ActionEvent e)
-				{
-					revertModifications(selection);
-				}
-
-				/*public void actionPerformed(ActionEvent e) {
-				RequestProcessor.getDefault().post(new Runnable() {
-				public void run() {                            
-				rollback(drev);
-				}
-				});
-				}*/
-			}));
-			menu.add(new JMenuItem(new AbstractAction(NbBundle.getMessage(SummaryView.class, &quot;CTL_SummaryView_View&quot;)) { // NOI18N
-
-				{
-					setEnabled(viewEnabled);
-				}
-
-				public void actionPerformed(ActionEvent e)
-				{
-					RequestProcessor.getDefault().post(new Runnable() {
-
-						public void run()
-						{
-							view(selection[0]);
-						}
-
-					});
-				}
-
-			}));
-		}
-
-		menu.show(resultsList, p.x, p.y);
-	}
-
-	/**
-	 * Overwrites local file with this revision.
-	 *
-	 * @param event
-	 */
-	static void rollback(RepositoryRevision.Event event)
-	{
-		rollback(new RepositoryRevision.Event[]{event});
-	}
-
-	/**
-	 * Overwrites local file with this revision.
-	 *
-	 * @param event
-	 */
-	static void rollback(final RepositoryRevision.Event[] events)
-	{
-		String repository = events[0].getLogInfoHeader().getRepositoryRootUrl();
-		RequestProcessor rp = Git.getInstance().getRequestProcessor(repository);
-		GitProgressSupport support = new GitProgressSupport() {
-
-			public void perform()
-			{
-				for (RepositoryRevision.Event event : events) {
-					rollback(event, this);
-				}
-			}
-
-		};
-		support.start(rp, repository, NbBundle.getMessage(SummaryView.class, &quot;MSG_Rollback_Progress&quot;)); // NOI18N
-
-	}
-
-	private static void rollback(RepositoryRevision.Event event, GitProgressSupport progress)
-	{
-		File file = event.getFile();
-		File parent = file.getParentFile();
-		parent.mkdirs();
-		try {
-			File oldFile = GitUtils.getFileRevision(event.getFile(), event.getLogInfoHeader().getRevision());
-			file.delete();
-			FileUtil.copyFile(FileUtil.toFileObject(oldFile), FileUtil.toFileObject(parent), file.getName(), &quot;&quot;);
-		} catch (IOException e) {
-			ErrorManager.getDefault().notify(e);
-		}
-	}
-
-	private void revertModifications(int[] selection)
-	{
-		Set&lt;RepositoryRevision.Event&gt; events = new HashSet&lt;RepositoryRevision.Event&gt;();
-		Set&lt;RepositoryRevision&gt; revisions = new HashSet&lt;RepositoryRevision&gt;();
-		for (int idx : selection) {
-			Object o = dispResults.get(idx);
-			if (o instanceof RepositoryRevision)
-				revisions.add((RepositoryRevision) o);
-			else
-				events.add((RepositoryRevision.Event) o);
-		}
-		revert(master, revisions.toArray(new RepositoryRevision[revisions.size()]), events.toArray(new RepositoryRevision.Event[events.size()]));
-	}
-
-	static void revert(final SearchHistoryPanel master, final RepositoryRevision[] revisions, final RepositoryRevision.Event[] events)
-	{
-		String url = master.getSearchRepositoryRootUrl();
-		RequestProcessor rp = Git.getInstance().getRequestProcessor(url);
-		GitProgressSupport support = new GitProgressSupport() {
-
-			public void perform()
-			{
-				revertImpl(master, revisions, events, this);
-			}
-
-		};
-		support.start(rp, url, NbBundle.getMessage(SummaryView.class, &quot;MSG_Revert_Progress&quot;)); // NOI18N
-	}
-
-	private static void revertImpl(SearchHistoryPanel master, RepositoryRevision[] revisions, RepositoryRevision.Event[] events, GitProgressSupport progress)
-	{
-		List&lt;File&gt; revertFiles = new ArrayList&lt;File&gt;();
-		boolean doBackup = GitModuleConfig.getDefault().getBackupOnRevertModifications();
-		for (RepositoryRevision revision : revisions) {
-			File root = new File(revision.getRepositoryRootUrl());
-			for (RepositoryRevision.Event event : revision.getEvents()) {
-				if (event.getFile() == null)
-					continue;
-				revertFiles.add(event.getFile());
-			}
-			RevertModificationsAction.performRevert(
-				root, revision.getRevision(), revertFiles, doBackup, progress.getLogger());
-
-			revertFiles.clear();
-		}
-
-		Map&lt;File, List&lt;RepositoryRevision.Event&gt;&gt; revertMap = new HashMap&lt;File, List&lt;RepositoryRevision.Event&gt;&gt;();
-		for (RepositoryRevision.Event event : events) {
-			if (event.getFile() == null)
-				continue;
-
-			File root = Git.getInstance().getTopmostManagedParent(event.getFile());
-			if (revertMap == null)
-				revertMap = new HashMap&lt;File, List&lt;RepositoryRevision.Event&gt;&gt;();
-			List&lt;RepositoryRevision.Event&gt; revEvents = revertMap.get(root);
-			if (revEvents == null) {
-				revEvents = new ArrayList&lt;RepositoryRevision.Event&gt;();
-				revertMap.put(root, revEvents);
-			}
-			revEvents.add(event);
-		}
-		if (events != null &amp;&amp; events.length &gt; 0 &amp;&amp; revertMap != null &amp;&amp; !revertMap.isEmpty()) {
-			Set&lt;File&gt; roots = revertMap.keySet();
-			for (File root : roots) {
-				List&lt;RepositoryRevision.Event&gt; revEvents = revertMap.get(root);
-				for (RepositoryRevision.Event event : revEvents) {
-					if (event.getFile() == null)
-						continue;
-					revertFiles.add(event.getFile());
-				}
-				if (revEvents != null &amp;&amp; !revEvents.isEmpty()) {
-					// Assuming all files in a given repository reverting to same revision
-			/*
-					RevertModificationsAction.performRevert(
-					root, revEvents.get(0).getLogInfoHeader().getLog().getRevision(), revertFiles, doBackup, progress.getLogger());
-					 */
-				}
-			}
-		}
-
-	}
-
-	private void view(int idx)
-	{
-		Object o = dispResults.get(idx);
-		if (o instanceof RepositoryRevision.Event)
-			try {
-				RepositoryRevision.Event drev = (RepositoryRevision.Event) o;
-				File file = GitUtils.getFileRevision(drev.getFile(), drev.getLogInfoHeader().getRevision());
-
-				FileObject fo = FileUtil.toFileObject(FileUtil.normalizeFile(file));
-				org.netbeans.modules.versioning.util.Utils.openFile(fo, drev.getLogInfoHeader().getRevision());
-			} catch (IOException ex) {
-				// Ignore if file not available in cache
-			}
-	}
-
-	private void diffPrevious(int idx)
-	{
-		Object o = dispResults.get(idx);
-		if (o instanceof RepositoryRevision.Event) {
-			RepositoryRevision.Event drev = (RepositoryRevision.Event) o;
-			master.showDiff(drev);
-		} else {
-			RepositoryRevision container = (RepositoryRevision) o;
-			master.showDiff(container);
-		}
-	}
-
-	public JComponent getComponent()
-	{
-		return scrollPane;
-	}
-
-	private class SummaryListModel extends AbstractListModel {
-
-		public int getSize()
-		{
-			return dispResults.size();
-		}
-
-		public Object getElementAt(int index)
-		{
-			return dispResults.get(index);
-		}
-
-	}
-
-	private class SummaryCellRenderer extends JPanel implements ListCellRenderer {
-
-		private static final String FIELDS_SEPARATOR = &quot;        &quot;; // NOI18N
-		private static final double DARKEN_FACTOR = 0.95;
-		private Style selectedStyle;
-		private Style normalStyle;
-		private Style filenameStyle;
-		private Style indentStyle;
-		private Style noindentStyle;
-		private Style hiliteStyle;
-		private JTextPane textPane = new JTextPane();
-		private JPanel actionsPane = new JPanel();
-		private DateFormat defaultFormat;
-		private int index;
-		private HyperlinkLabel diffLink;
-		private HyperlinkLabel revertLink;
-
-		public SummaryCellRenderer()
-		{
-			selectedStyle = textPane.addStyle(&quot;selected&quot;, null); // NOI18N
-			StyleConstants.setForeground(selectedStyle, UIManager.getColor(&quot;List.selectionForeground&quot;)); // NOI18N
-			normalStyle = textPane.addStyle(&quot;normal&quot;, null); // NOI18N
-			StyleConstants.setForeground(normalStyle, UIManager.getColor(&quot;List.foreground&quot;)); // NOI18N
-			filenameStyle = textPane.addStyle(&quot;filename&quot;, normalStyle); // NOI18N
-			StyleConstants.setBold(filenameStyle, true);
-			indentStyle = textPane.addStyle(&quot;indent&quot;, null); // NOI18N
-			StyleConstants.setLeftIndent(indentStyle, 50);
-			noindentStyle = textPane.addStyle(&quot;noindent&quot;, null); // NOI18N
-			StyleConstants.setLeftIndent(noindentStyle, 0);
-			defaultFormat = DateFormat.getDateTimeInstance();
-
-			hiliteStyle = textPane.addStyle(&quot;hilite&quot;, normalStyle); // NOI18N
-			Color c = (Color) searchHiliteAttrs.getAttribute(StyleConstants.Background);
-			if (c != null)
-				StyleConstants.setBackground(hiliteStyle, c);
-			c = (Color) searchHiliteAttrs.getAttribute(StyleConstants.Foreground);
-			if (c != null)
-				StyleConstants.setForeground(hiliteStyle, c);
-
-			setLayout(new BorderLayout());
-			add(textPane);
-			add(actionsPane, BorderLayout.PAGE_END);
-			actionsPane.setLayout(new FlowLayout(FlowLayout.TRAILING, 2, 5));
-
-			diffLink = new HyperlinkLabel();
-			diffLink.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 8));
-			actionsPane.add(diffLink);
-
-			revertLink = new HyperlinkLabel();
-			revertLink.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 8));
-			//actionsPane.add(revertLink);
-
-			textPane.setBorder(null);
-		}
-
-		public Color darker(Color c)
-		{
-			return new Color(Math.max((int) (c.getRed() * DARKEN_FACTOR), 0),
-				Math.max((int) (c.getGreen() * DARKEN_FACTOR), 0),
-				Math.max((int) (c.getBlue() * DARKEN_FACTOR), 0));
-		}
-
-		public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus)
-		{
-			if (value instanceof RepositoryRevision)
-				renderContainer(list, (RepositoryRevision) value, index, isSelected);
-			else
-				renderRevision(list, (RepositoryRevision.Event) value, index, isSelected);
-			return this;
-		}
-
-		private void renderContainer(JList list, RepositoryRevision container, int index, boolean isSelected)
-		{
-
-			StyledDocument sd = textPane.getStyledDocument();
-
-			Style style;
-			Color backgroundColor;
-			Color foregroundColor;
-
-			if (isSelected) {
-				foregroundColor = UIManager.getColor(&quot;List.selectionForeground&quot;); // NOI18N
-				backgroundColor = UIManager.getColor(&quot;List.selectionBackground&quot;); // NOI18N
-				style = selectedStyle;
-			} else {
-				foregroundColor = UIManager.getColor(&quot;List.foreground&quot;); // NOI18N
-				backgroundColor = UIManager.getColor(&quot;List.background&quot;); // NOI18N
-				backgroundColor = darker(backgroundColor);
-				style = normalStyle;
-			}
-			textPane.setBackground(backgroundColor);
-			actionsPane.setBackground(backgroundColor);
-
-			this.index = index;
-
-			try {
-				sd.remove(0, sd.getLength());
-				sd.setParagraphAttributes(0, sd.getLength(), noindentStyle, false);
-
-				sd.insertString(0, container.getRevision(), null); // NOI18N
-				sd.setCharacterAttributes(0, sd.getLength(), filenameStyle, false);
-				sd.insertString(sd.getLength(), FIELDS_SEPARATOR + container.getAuthor(), null);
-				sd.insertString(sd.getLength(), FIELDS_SEPARATOR + defaultFormat.format(container.getDate()), null);
-
-				String commitMessage = container.getMessage();
-				if (commitMessage.endsWith(&quot;\n&quot;))
-					commitMessage = commitMessage.substring(0, commitMessage.length() - 1); // NOI18N
-				sd.insertString(sd.getLength(), &quot;\n&quot;, null);
-
-				sd.insertString(sd.getLength(), commitMessage, null);
-
-				if (message != null &amp;&amp; !isSelected) {
-					int idx = commitMessage.indexOf(message);
-					if (idx != -1) {
-						int len = commitMessage.length();
-						int doclen = sd.getLength();
-						sd.setCharacterAttributes(doclen - len + idx, message.length(), hiliteStyle, false);
-					}
-				}
-
-				resizePane(commitMessage, list.getFontMetrics(list.getFont()));
-				sd.setCharacterAttributes(0, Integer.MAX_VALUE, style, false);
-			} catch (BadLocationException e) {
-				ErrorManager.getDefault().notify(e);
-			}
-
-			actionsPane.setVisible(true);
-			if (!master.isIncomingSearch()) {
-				diffLink.set(NbBundle.getMessage(SummaryView.class, &quot;CTL_Action_Diff&quot;), foregroundColor, backgroundColor);// NOI18N
-				revertLink.set(NbBundle.getMessage(SummaryView.class, &quot;CTL_Action_Revert&quot;), foregroundColor, backgroundColor); // NOI18N
-			}
-		}
-
-		private void renderRevision(JList list, RepositoryRevision.Event dispRevision, final int index, boolean isSelected)
-		{
-			Style style;
-			StyledDocument sd = textPane.getStyledDocument();
-
-			Color backgroundColor;
-			Color foregroundColor;
-
-			if (isSelected) {
-				foregroundColor = UIManager.getColor(&quot;List.selectionForeground&quot;); // NOI18N
-				backgroundColor = UIManager.getColor(&quot;List.selectionBackground&quot;); // NOI18N
-				style = selectedStyle;
-			} else {
-				foregroundColor = UIManager.getColor(&quot;List.foreground&quot;); // NOI18N
-				backgroundColor = UIManager.getColor(&quot;List.background&quot;); // NOI18N
-				style = normalStyle;
-			}
-			textPane.setBackground(backgroundColor);
-			actionsPane.setVisible(false);
-
-			this.index = -1;
-			try {
-				sd.remove(0, sd.getLength());
-				sd.setParagraphAttributes(0, sd.getLength(), indentStyle, false);
-
-				sd.insertString(sd.getLength(), String.valueOf(dispRevision.getChangedPath().getAction()), null);
-				sd.insertString(sd.getLength(), FIELDS_SEPARATOR + dispRevision.getChangedPath().getPath(), null);
-
-				sd.setCharacterAttributes(0, Integer.MAX_VALUE, style, false);
-				resizePane(sd.getText(0, sd.getLength() - 1), list.getFontMetrics(list.getFont()));
-			} catch (BadLocationException e) {
-				ErrorManager.getDefault().notify(e);
-			}
-		}
-
-		@SuppressWarnings(&quot;empty-statement&quot;)
-		private void resizePane(String text, FontMetrics fm)
-		{
-			if (text == null)
-				text = &quot;&quot;;
-			int width = master.getWidth();
-			if (width &gt; 0) {
-				Rectangle2D rect = fm.getStringBounds(text, textPane.getGraphics());
-				int nlc, i;
-				for (nlc = -1    , i = 0; i != -1; i = text.indexOf('\n', i + 1), nlc++);
-				nlc++;
-				int lines = (int) (rect.getWidth() / (width - 80) + 1);
-				int ph = fm.getHeight() * (lines + nlc) + 0;
-				textPane.setPreferredSize(new Dimension(width - 50, ph));
-			}
-		}
-
-		@Override
-		protected void paintComponent(Graphics g)
-		{
-			super.paintComponent(g);
-			if (index == -1)
-				return;
-			Rectangle apb = actionsPane.getBounds();
-
-			{
-				Rectangle bounds = diffLink.getBounds();
-				bounds.setBounds(bounds.x, bounds.y + apb.y, bounds.width, bounds.height);
-				resultsList.putClientProperty(SUMMARY_DIFF_PROPERTY + index, bounds); // NOI18N
-			}
-
-			Rectangle bounds = revertLink.getBounds();
-			bounds.setBounds(bounds.x, bounds.y + apb.y, bounds.width, bounds.height);
-			resultsList.putClientProperty(SUMMARY_REVERT_PROPERTY + index, bounds); // NOI18N
-		}
-
-	}
-
-	private static class HyperlinkLabel extends JLabel {
-
-		public HyperlinkLabel()
-		{
-			setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
-		}
-
-		public void set(String text, Color foreground, Color background)
-		{
-			StringBuilder sb = new StringBuilder(100);
-			if (foreground.equals(UIManager.getColor(&quot;List.foreground&quot;))) { // NOI18N
-				sb.append(&quot;&lt;html&gt;&lt;a href=\&quot;\&quot;&gt;&quot;); // NOI18N
-				sb.append(text);
-				sb.append(&quot;&lt;/a&gt;&quot;); // NOI18N
-			} else {
-				sb.append(&quot;&lt;html&gt;&lt;a href=\&quot;\&quot; style=\&quot;color:&quot;); // NOI18N
-				sb.append(&quot;rgb(&quot;); // NOI18N
-				sb.append(foreground.getRed());
-				sb.append(&quot;,&quot;); // NOI18N
-				sb.append(foreground.getGreen());
-				sb.append(&quot;,&quot;); // NOI18N
-				sb.append(foreground.getBlue());
-				sb.append(&quot;)&quot;); // NOI18N
-				sb.append(&quot;\&quot;&gt;&quot;); // NOI18N
-				sb.append(text);
-				sb.append(&quot;&lt;/a&gt;&quot;); // NOI18N
-			}
-			setText(sb.toString());
-			setBackground(background);
-		}
-
-	}
+    private static final String SUMMARY_DIFF_PROPERTY = &quot;Summary-Diff-&quot;;
+    private static final String SUMMARY_REVERT_PROPERTY = &quot;Summary-Revert-&quot;;
+    private static final String SUMMARY_EXPORTDIFFS_PROPERTY = &quot;Summary-ExportDiffs-&quot;;
+    private final SearchHistoryPanel master;
+    private JList resultsList;
+    private JScrollPane scrollPane;
+    private final List dispResults;
+    private String message;
+    private AttributeSet searchHiliteAttrs;
+    private List&lt;RepositoryRevision&gt; results;
+
+    public SummaryView(SearchHistoryPanel master, List&lt;RepositoryRevision&gt; results)
+    {
+        this.master = master;
+        this.results = results;
+        this.dispResults = expandResults(results);
+        FontColorSettings fcs = MimeLookup.getLookup(MimePath.get(&quot;text/x-java&quot;)).lookup(FontColorSettings.class); // NOI18N
+        searchHiliteAttrs = fcs.getFontColors(&quot;highlight-search&quot;); // NOI18N
+        message = master.getCriteria().getCommitMessage();
+        resultsList = new JList(new SummaryListModel());
+        resultsList.setFixedCellHeight(-1);
+        resultsList.addMouseListener(this);
+        resultsList.addMouseMotionListener(this);
+        resultsList.setCellRenderer(new SummaryCellRenderer());
+        resultsList.getAccessibleContext().setAccessibleName(NbBundle.getMessage(SummaryView.class, &quot;ACSN_SummaryView_List&quot;)); // NOI18N
+        resultsList.getAccessibleContext().setAccessibleDescription(NbBundle.getMessage(SummaryView.class, &quot;ACSD_SummaryView_List&quot;)); // NOI18N
+        scrollPane = new JScrollPane(resultsList, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
+        master.addComponentListener(this);
+        resultsList.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(
+            KeyStroke.getKeyStroke(KeyEvent.VK_F10, KeyEvent.SHIFT_DOWN_MASK), &quot;org.openide.actions.PopupAction&quot;);
+        resultsList.getActionMap().put(&quot;org.openide.actions.PopupAction&quot;, new AbstractAction() {
+
+            public void actionPerformed(ActionEvent e)
+            {
+                onPopup(org.netbeans.modules.versioning.util.Utils.getPositionForPopup(resultsList));
+            }
+
+        });
+    }
+
+    public void componentResized(ComponentEvent e)
+    {
+        int[] selection = resultsList.getSelectedIndices();
+        resultsList.setModel(new SummaryListModel());
+        resultsList.setSelectedIndices(selection);
+    }
+
+    public void componentHidden(ComponentEvent e)
+    {
+        // not interested
+    }
+
+    public void componentMoved(ComponentEvent e)
+    {
+        // not interested
+    }
+
+    public void componentShown(ComponentEvent e)
+    {
+        // not interested
+    }
+
+    @SuppressWarnings(&quot;unchecked&quot;)
+    private List expandResults(List&lt;RepositoryRevision&gt; results)
+    {
+        ArrayList newResults = new ArrayList(results.size());
+        for (RepositoryRevision repositoryRevision : results) {
+            newResults.add(repositoryRevision);
+            List&lt;RepositoryRevision.Event&gt; events = repositoryRevision.getEvents();
+            for (RepositoryRevision.Event event : events) {
+                newResults.add(event);
+            }
+        }
+        return newResults;
+    }
+
+    public void mouseClicked(MouseEvent e)
+    {
+        int idx = resultsList.locationToIndex(e.getPoint());
+        if (idx == -1)
+            return;
+        Rectangle rect = resultsList.getCellBounds(idx, idx);
+        Point p = new Point(e.getX() - rect.x, e.getY() - rect.y);
+        Rectangle diffBounds = (Rectangle) resultsList.getClientProperty(SUMMARY_DIFF_PROPERTY + idx); // NOI18N
+        if (diffBounds != null &amp;&amp; diffBounds.contains(p))
+            diffPrevious(idx);
+        diffBounds = (Rectangle) resultsList.getClientProperty(SUMMARY_REVERT_PROPERTY + idx); // NOI18N
+        if (diffBounds != null &amp;&amp; diffBounds.contains(p))
+            revertModifications(new int[]{idx});
+    }
+
+    public void mouseEntered(MouseEvent e)
+    {
+        // not interested
+    }
+
+    public void mouseExited(MouseEvent e)
+    {
+        // not interested
+    }
+
+    public void mousePressed(MouseEvent e)
+    {
+        if (!master.isIncomingSearch() &amp;&amp; e.isPopupTrigger())
+            onPopup(e);
+    }
+
+    public void mouseReleased(MouseEvent e)
+    {
+        if (!master.isIncomingSearch() &amp;&amp; e.isPopupTrigger())
+            onPopup(e);
+    }
+
+    public void mouseDragged(MouseEvent e)
+    {
+    }
+
+    public void mouseMoved(MouseEvent e)
+    {
+        int idx = resultsList.locationToIndex(e.getPoint());
+        if (idx == -1)
+            return;
+        Rectangle rect = resultsList.getCellBounds(idx, idx);
+        Point p = new Point(e.getX() - rect.x, e.getY() - rect.y);
+        Rectangle diffBounds = (Rectangle) resultsList.getClientProperty(SUMMARY_DIFF_PROPERTY + idx); // NOI18N
+        if (diffBounds != null &amp;&amp; diffBounds.contains(p)) {
+            resultsList.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
+            return;
+        }
+        diffBounds = (Rectangle) resultsList.getClientProperty(SUMMARY_REVERT_PROPERTY + idx); // NOI18N
+        if (diffBounds != null &amp;&amp; diffBounds.contains(p)) {
+            resultsList.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
+            return;
+        }
+        diffBounds = (Rectangle) resultsList.getClientProperty(SUMMARY_EXPORTDIFFS_PROPERTY + idx); // NOI18N
+        if (diffBounds != null &amp;&amp; diffBounds.contains(p)) {
+            resultsList.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
+            return;
+        }
+        resultsList.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
+    }
+
+    public Collection getSetups()
+    {
+        Node[] nodes = TopComponent.getRegistry().getActivatedNodes();
+        if (nodes.length == 0)
+            return master.getSetups(results.toArray(new RepositoryRevision[results.size()]), new RepositoryRevision.Event[0]);
+
+        Set&lt;RepositoryRevision.Event&gt; events = new HashSet&lt;RepositoryRevision.Event&gt;();
+        Set&lt;RepositoryRevision&gt; revisions = new HashSet&lt;RepositoryRevision&gt;();
+
+        int[] sel = resultsList.getSelectedIndices();
+        for (int i : sel) {
+            Object revCon = dispResults.get(i);
+            if (revCon instanceof RepositoryRevision)
+                revisions.add((RepositoryRevision) revCon);
+            else
+                events.add((RepositoryRevision.Event) revCon);
+        }
+        return master.getSetups(revisions.toArray(new RepositoryRevision[revisions.size()]), events.toArray(new RepositoryRevision.Event[events.size()]));
+    }
+
+    public String getSetupDisplayName()
+    {
+        return null;
+    }
+
+    private void onPopup(MouseEvent e)
+    {
+        onPopup(e.getPoint());
+    }
+
+    private void onPopup(Point p)
+    {
+        int[] sel = resultsList.getSelectedIndices();
+        if (sel.length == 0) {
+            int idx = resultsList.locationToIndex(p);
+            if (idx == -1)
+                return;
+            resultsList.setSelectedIndex(idx);
+            sel = new int[]{idx};
+        }
+        final int[] selection = sel;
+
+        JPopupMenu menu = new JPopupMenu();
+
+        String previousRevision = null;
+        RepositoryRevision container = null;
+        final RepositoryRevision.Event[] drev;
+
+        Object revCon = dispResults.get(selection[0]);
+
+
+        boolean noExDeletedExistingFiles = true;
+        boolean revisionSelected;
+        boolean missingFile = false;
+        boolean oneRevisionMultiselected = true;
+
+        if (revCon instanceof RepositoryRevision) {
+            revisionSelected = true;
+            container = (RepositoryRevision) dispResults.get(selection[0]);
+            drev = new RepositoryRevision.Event[0];
+            oneRevisionMultiselected = true;
+            noExDeletedExistingFiles = true;
+        } else {
+            revisionSelected = false;
+            drev = new RepositoryRevision.Event[selection.length];
+
+            for (int i = 0; i &lt; selection.length; i++) {
+                drev[i] = (RepositoryRevision.Event) dispResults.get(selection[i]);
+
+                if (!missingFile &amp;&amp; drev[i].getFile() == null)
+                    missingFile = true;
+                if (oneRevisionMultiselected &amp;&amp; i &gt; 0 &amp;&amp;
+                    drev[0].getLogInfoHeader().getRevision().equals(drev[i].getLogInfoHeader().getRevision()))
+                    oneRevisionMultiselected = false;
+                if (drev[i].getFile() != null &amp;&amp; drev[i].getFile().exists() &amp;&amp; drev[i].getChangedPath().getAction() == 'D')
+                    noExDeletedExistingFiles = false;
+            }
+            container = drev[0].getLogInfoHeader();
+        }
+        long revision = 0; //Long.parseLong(container.getLog().getRevision());
+
+        final boolean rollbackToEnabled = !missingFile &amp;&amp; !revisionSelected &amp;&amp; oneRevisionMultiselected;
+        final boolean rollbackChangeEnabled = !missingFile &amp;&amp; oneRevisionMultiselected &amp;&amp; (drev.length == 0 || noExDeletedExistingFiles); // drev.length == 0 =&gt; the whole revision was selected
+        final boolean viewEnabled = selection.length == 1 &amp;&amp; !revisionSelected &amp;&amp; drev[0].getFile() != null &amp;&amp; drev[0].getFile().exists() &amp;&amp; !drev[0].getFile().isDirectory();
+        final boolean diffToPrevEnabled = selection.length == 1;
+
+        if (revision &gt; 0)
+            menu.add(new JMenuItem(new AbstractAction(NbBundle.getMessage(SummaryView.class, &quot;CTL_SummaryView_DiffToPrevious&quot;, &quot;&quot; + previousRevision)) { // NOI18N
+
+                {
+                    setEnabled(diffToPrevEnabled);
+                }
+
+                public void actionPerformed(ActionEvent e)
+                {
+                    diffPrevious(selection[0]);
+                }
+
+            }));
+
+        /* TBD - Support Rollback Changes:
+         * Need to figure out how to implement SVN functionality to allow you to rollback a change
+         * currently for svn this cmd runs: merge -R &lt;revX&gt;:&lt;revY&gt; it basically diffs the two revs
+         * and creates a patch which is then applied ot the file in the working dir, effectively removing
+         * the change applied between revX and revY
+         * In hg we'd need to do a hg diff -r revX -r revY, generate a patch and then apply it to the working dir copy
+         * /
+        menu.add(new JMenuItem(new AbstractAction(NbBundle.getMessage(SummaryView.class, &quot;CTL_SummaryView_RollbackChange&quot;)) { // NOI18N
+        {
+        setEnabled(false); // rollbackChangeEnabled);
+        }
+        public void actionPerformed(ActionEvent e) {
+        revertModifications(selection);
+        }
+        }));
+         */
+        if (!revisionSelected) {
+            menu.add(new JMenuItem(new AbstractAction(NbBundle.getMessage(SummaryView.class, &quot;CTL_SummaryView_RollbackTo&quot;, &quot;&quot; + revision)) { // NOI18N
+
+                {
+                    setEnabled(rollbackToEnabled);
+                }
+
+                public void actionPerformed(ActionEvent e)
+                {
+                    revertModifications(selection);
+                }
+
+                /*public void actionPerformed(ActionEvent e) {
+                RequestProcessor.getDefault().post(new Runnable() {
+                public void run() {
+                rollback(drev);
+                }
+                });
+                }*/
+            }));
+            menu.add(new JMenuItem(new AbstractAction(NbBundle.getMessage(SummaryView.class, &quot;CTL_SummaryView_View&quot;)) { // NOI18N
+
+                {
+                    setEnabled(viewEnabled);
+                }
+
+                public void actionPerformed(ActionEvent e)
+                {
+                    RequestProcessor.getDefault().post(new Runnable() {
+
+                        public void run()
+                        {
+                            view(selection[0]);
+                        }
+
+                    });
+                }
+
+            }));
+        }
+
+        menu.show(resultsList, p.x, p.y);
+    }
+
+    /**
+     * Overwrites local file with this revision.
+     *
+     * @param event
+     */
+    static void rollback(RepositoryRevision.Event event)
+    {
+        rollback(new RepositoryRevision.Event[]{event});
+    }
+
+    /**
+     * Overwrites local file with this revision.
+     *
+     * @param event
+     */
+    static void rollback(final RepositoryRevision.Event[] events)
+    {
+        String repository = events[0].getLogInfoHeader().getRepositoryRootUrl();
+        RequestProcessor rp = Git.getInstance().getRequestProcessor(repository);
+        GitProgressSupport support = new GitProgressSupport() {
+
+            public void perform()
+            {
+                for (RepositoryRevision.Event event : events) {
+                    rollback(event, this);
+                }
+            }
+
+        };
+        support.start(rp, repository, NbBundle.getMessage(SummaryView.class, &quot;MSG_Rollback_Progress&quot;)); // NOI18N
+
+    }
+
+    private static void rollback(RepositoryRevision.Event event, GitProgressSupport progress)
+    {
+        File file = event.getFile();
+        File parent = file.getParentFile();
+        parent.mkdirs();
+        try {
+            File oldFile = GitUtils.getFileRevision(event.getFile(), event.getLogInfoHeader().getRevision());
+            file.delete();
+            FileUtil.copyFile(FileUtil.toFileObject(oldFile), FileUtil.toFileObject(parent), file.getName(), &quot;&quot;);
+        } catch (IOException e) {
+            ErrorManager.getDefault().notify(e);
+        }
+    }
+
+    private void revertModifications(int[] selection)
+    {
+        Set&lt;RepositoryRevision.Event&gt; events = new HashSet&lt;RepositoryRevision.Event&gt;();
+        Set&lt;RepositoryRevision&gt; revisions = new HashSet&lt;RepositoryRevision&gt;();
+        for (int idx : selection) {
+            Object o = dispResults.get(idx);
+            if (o instanceof RepositoryRevision)
+                revisions.add((RepositoryRevision) o);
+            else
+                events.add((RepositoryRevision.Event) o);
+        }
+        revert(master, revisions.toArray(new RepositoryRevision[revisions.size()]), events.toArray(new RepositoryRevision.Event[events.size()]));
+    }
+
+    static void revert(final SearchHistoryPanel master, final RepositoryRevision[] revisions, final RepositoryRevision.Event[] events)
+    {
+        String url = master.getSearchRepositoryRootUrl();
+        RequestProcessor rp = Git.getInstance().getRequestProcessor(url);
+        GitProgressSupport support = new GitProgressSupport() {
+
+            public void perform()
+            {
+                revertImpl(master, revisions, events, this);
+            }
+
+        };
+        support.start(rp, url, NbBundle.getMessage(SummaryView.class, &quot;MSG_Revert_Progress&quot;)); // NOI18N
+    }
+
+    private static void revertImpl(SearchHistoryPanel master, RepositoryRevision[] revisions, RepositoryRevision.Event[] events, GitProgressSupport progress)
+    {
+        List&lt;File&gt; revertFiles = new ArrayList&lt;File&gt;();
+        boolean doBackup = GitModuleConfig.getDefault().getBackupOnRevertModifications();
+        for (RepositoryRevision revision : revisions) {
+            File root = new File(revision.getRepositoryRootUrl());
+            for (RepositoryRevision.Event event : revision.getEvents()) {
+                if (event.getFile() == null)
+                    continue;
+                revertFiles.add(event.getFile());
+            }
+            RevertModificationsAction.performRevert(
+                root, revision.getRevision(), revertFiles, doBackup, progress.getLogger());
+
+            revertFiles.clear();
+        }
+
+        Map&lt;File, List&lt;RepositoryRevision.Event&gt;&gt; revertMap = new HashMap&lt;File, List&lt;RepositoryRevision.Event&gt;&gt;();
+        for (RepositoryRevision.Event event : events) {
+            if (event.getFile() == null)
+                continue;
+
+            File root = Git.getInstance().getTopmostManagedParent(event.getFile());
+            if (revertMap == null)
+                revertMap = new HashMap&lt;File, List&lt;RepositoryRevision.Event&gt;&gt;();
+            List&lt;RepositoryRevision.Event&gt; revEvents = revertMap.get(root);
+            if (revEvents == null) {
+                revEvents = new ArrayList&lt;RepositoryRevision.Event&gt;();
+                revertMap.put(root, revEvents);
+            }
+            revEvents.add(event);
+        }
+        if (events != null &amp;&amp; events.length &gt; 0 &amp;&amp; revertMap != null &amp;&amp; !revertMap.isEmpty()) {
+            Set&lt;File&gt; roots = revertMap.keySet();
+            for (File root : roots) {
+                List&lt;RepositoryRevision.Event&gt; revEvents = revertMap.get(root);
+                for (RepositoryRevision.Event event : revEvents) {
+                    if (event.getFile() == null)
+                        continue;
+                    revertFiles.add(event.getFile());
+                }
+                if (revEvents != null &amp;&amp; !revEvents.isEmpty()) {
+                    // Assuming all files in a given repository reverting to same revision
+            /*
+                    RevertModificationsAction.performRevert(
+                    root, revEvents.get(0).getLogInfoHeader().getLog().getRevision(), revertFiles, doBackup, progress.getLogger());
+                     */
+                }
+            }
+        }
+
+    }
+
+    private void view(int idx)
+    {
+        Object o = dispResults.get(idx);
+        if (o instanceof RepositoryRevision.Event)
+            try {
+                RepositoryRevision.Event drev = (RepositoryRevision.Event) o;
+                File file = GitUtils.getFileRevision(drev.getFile(), drev.getLogInfoHeader().getRevision());
+
+                FileObject fo = FileUtil.toFileObject(FileUtil.normalizeFile(file));
+                org.netbeans.modules.versioning.util.Utils.openFile(fo, drev.getLogInfoHeader().getRevision());
+            } catch (IOException ex) {
+                // Ignore if file not available in cache
+            }
+    }
+
+    private void diffPrevious(int idx)
+    {
+        Object o = dispResults.get(idx);
+        if (o instanceof RepositoryRevision.Event) {
+            RepositoryRevision.Event drev = (RepositoryRevision.Event) o;
+            master.showDiff(drev);
+        } else {
+            RepositoryRevision container = (RepositoryRevision) o;
+            master.showDiff(container);
+        }
+    }
+
+    public JComponent getComponent()
+    {
+        return scrollPane;
+    }
+
+    private class SummaryListModel extends AbstractListModel {
+
+        public int getSize()
+        {
+            return dispResults.size();
+        }
+
+        public Object getElementAt(int index)
+        {
+            return dispResults.get(index);
+        }
+
+    }
+
+    private class SummaryCellRenderer extends JPanel implements ListCellRenderer {
+
+        private static final String FIELDS_SEPARATOR = &quot;        &quot;; // NOI18N
+        private static final double DARKEN_FACTOR = 0.95;
+        private Style selectedStyle;
+        private Style normalStyle;
+        private Style filenameStyle;
+        private Style indentStyle;
+        private Style noindentStyle;
+        private Style hiliteStyle;
+        private JTextPane textPane = new JTextPane();
+        private JPanel actionsPane = new JPanel();
+        private DateFormat defaultFormat;
+        private int index;
+        private HyperlinkLabel diffLink;
+        private HyperlinkLabel revertLink;
+
+        public SummaryCellRenderer()
+        {
+            selectedStyle = textPane.addStyle(&quot;selected&quot;, null); // NOI18N
+            StyleConstants.setForeground(selectedStyle, UIManager.getColor(&quot;List.selectionForeground&quot;)); // NOI18N
+            normalStyle = textPane.addStyle(&quot;normal&quot;, null); // NOI18N
+            StyleConstants.setForeground(normalStyle, UIManager.getColor(&quot;List.foreground&quot;)); // NOI18N
+            filenameStyle = textPane.addStyle(&quot;filename&quot;, normalStyle); // NOI18N
+            StyleConstants.setBold(filenameStyle, true);
+            indentStyle = textPane.addStyle(&quot;indent&quot;, null); // NOI18N
+            StyleConstants.setLeftIndent(indentStyle, 50);
+            noindentStyle = textPane.addStyle(&quot;noindent&quot;, null); // NOI18N
+            StyleConstants.setLeftIndent(noindentStyle, 0);
+            defaultFormat = DateFormat.getDateTimeInstance();
+
+            hiliteStyle = textPane.addStyle(&quot;hilite&quot;, normalStyle); // NOI18N
+            Color c = (Color) searchHiliteAttrs.getAttribute(StyleConstants.Background);
+            if (c != null)
+                StyleConstants.setBackground(hiliteStyle, c);
+            c = (Color) searchHiliteAttrs.getAttribute(StyleConstants.Foreground);
+            if (c != null)
+                StyleConstants.setForeground(hiliteStyle, c);
+
+            setLayout(new BorderLayout());
+            add(textPane);
+            add(actionsPane, BorderLayout.PAGE_END);
+            actionsPane.setLayout(new FlowLayout(FlowLayout.TRAILING, 2, 5));
+
+            diffLink = new HyperlinkLabel();
+            diffLink.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 8));
+            actionsPane.add(diffLink);
+
+            revertLink = new HyperlinkLabel();
+            revertLink.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 8));
+            //actionsPane.add(revertLink);
+
+            textPane.setBorder(null);
+        }
+
+        public Color darker(Color c)
+        {
+            return new Color(Math.max((int) (c.getRed() * DARKEN_FACTOR), 0),
+                Math.max((int) (c.getGreen() * DARKEN_FACTOR), 0),
+                Math.max((int) (c.getBlue() * DARKEN_FACTOR), 0));
+        }
+
+        public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus)
+        {
+            if (value instanceof RepositoryRevision)
+                renderContainer(list, (RepositoryRevision) value, index, isSelected);
+            else
+                renderRevision(list, (RepositoryRevision.Event) value, index, isSelected);
+            return this;
+        }
+
+        private void renderContainer(JList list, RepositoryRevision container, int index, boolean isSelected)
+        {
+
+            StyledDocument sd = textPane.getStyledDocument();
+
+            Style style;
+            Color backgroundColor;
+            Color foregroundColor;
+
+            if (isSelected) {
+                foregroundColor = UIManager.getColor(&quot;List.selectionForeground&quot;); // NOI18N
+                backgroundColor = UIManager.getColor(&quot;List.selectionBackground&quot;); // NOI18N
+                style = selectedStyle;
+            } else {
+                foregroundColor = UIManager.getColor(&quot;List.foreground&quot;); // NOI18N
+                backgroundColor = UIManager.getColor(&quot;List.background&quot;); // NOI18N
+                backgroundColor = darker(backgroundColor);
+                style = normalStyle;
+            }
+            textPane.setBackground(backgroundColor);
+            actionsPane.setBackground(backgroundColor);
+
+            this.index = index;
+
+            try {
+                sd.remove(0, sd.getLength());
+                sd.setParagraphAttributes(0, sd.getLength(), noindentStyle, false);
+
+                sd.insertString(0, container.getRevision(), null); // NOI18N
+                sd.setCharacterAttributes(0, sd.getLength(), filenameStyle, false);
+                sd.insertString(sd.getLength(), FIELDS_SEPARATOR + container.getAuthor(), null);
+                sd.insertString(sd.getLength(), FIELDS_SEPARATOR + defaultFormat.format(container.getDate()), null);
+
+                String commitMessage = container.getMessage();
+                if (commitMessage.endsWith(&quot;\n&quot;))
+                    commitMessage = commitMessage.substring(0, commitMessage.length() - 1); // NOI18N
+                sd.insertString(sd.getLength(), &quot;\n&quot;, null);
+
+                sd.insertString(sd.getLength(), commitMessage, null);
+
+                if (message != null &amp;&amp; !isSelected) {
+                    int idx = commitMessage.indexOf(message);
+                    if (idx != -1) {
+                        int len = commitMessage.length();
+                        int doclen = sd.getLength();
+                        sd.setCharacterAttributes(doclen - len + idx, message.length(), hiliteStyle, false);
+                    }
+                }
+
+                resizePane(commitMessage, list.getFontMetrics(list.getFont()));
+                sd.setCharacterAttributes(0, Integer.MAX_VALUE, style, false);
+            } catch (BadLocationException e) {
+                ErrorManager.getDefault().notify(e);
+            }
+
+            actionsPane.setVisible(true);
+            if (!master.isIncomingSearch()) {
+                diffLink.set(NbBundle.getMessage(SummaryView.class, &quot;CTL_Action_Diff&quot;), foregroundColor, backgroundColor);// NOI18N
+                revertLink.set(NbBundle.getMessage(SummaryView.class, &quot;CTL_Action_Revert&quot;), foregroundColor, backgroundColor); // NOI18N
+            }
+        }
+
+        private void renderRevision(JList list, RepositoryRevision.Event dispRevision, final int index, boolean isSelected)
+        {
+            Style style;
+            StyledDocument sd = textPane.getStyledDocument();
+
+            Color backgroundColor;
+            Color foregroundColor;
+
+            if (isSelected) {
+                foregroundColor = UIManager.getColor(&quot;List.selectionForeground&quot;); // NOI18N
+                backgroundColor = UIManager.getColor(&quot;List.selectionBackground&quot;); // NOI18N
+                style = selectedStyle;
+            } else {
+                foregroundColor = UIManager.getColor(&quot;List.foreground&quot;); // NOI18N
+                backgroundColor = UIManager.getColor(&quot;List.background&quot;); // NOI18N
+                style = normalStyle;
+            }
+            textPane.setBackground(backgroundColor);
+            actionsPane.setVisible(false);
+
+            this.index = -1;
+            try {
+                sd.remove(0, sd.getLength());
+                sd.setParagraphAttributes(0, sd.getLength(), indentStyle, false);
+
+                sd.insertString(sd.getLength(), String.valueOf(dispRevision.getChangedPath().getAction()), null);
+                sd.insertString(sd.getLength(), FIELDS_SEPARATOR + dispRevision.getChangedPath().getPath(), null);
+
+                sd.setCharacterAttributes(0, Integer.MAX_VALUE, style, false);
+                resizePane(sd.getText(0, sd.getLength() - 1), list.getFontMetrics(list.getFont()));
+            } catch (BadLocationException e) {
+                ErrorManager.getDefault().notify(e);
+            }
+        }
+
+        @SuppressWarnings(&quot;empty-statement&quot;)
+        private void resizePane(String text, FontMetrics fm)
+        {
+            if (text == null)
+                text = &quot;&quot;;
+            int width = master.getWidth();
+            if (width &gt; 0) {
+                Rectangle2D rect = fm.getStringBounds(text, textPane.getGraphics());
+                int nlc, i;
+                for (nlc = -1    , i = 0; i != -1; i = text.indexOf('\n', i + 1), nlc++);
+                nlc++;
+                int lines = (int) (rect.getWidth() / (width - 80) + 1);
+                int ph = fm.getHeight() * (lines + nlc) + 0;
+                textPane.setPreferredSize(new Dimension(width - 50, ph));
+            }
+        }
+
+        @Override
+        protected void paintComponent(Graphics g)
+        {
+            super.paintComponent(g);
+            if (index == -1)
+                return;
+            Rectangle apb = actionsPane.getBounds();
+
+            {
+                Rectangle bounds = diffLink.getBounds();
+                bounds.setBounds(bounds.x, bounds.y + apb.y, bounds.width, bounds.height);
+                resultsList.putClientProperty(SUMMARY_DIFF_PROPERTY + index, bounds); // NOI18N
+            }
+
+            Rectangle bounds = revertLink.getBounds();
+            bounds.setBounds(bounds.x, bounds.y + apb.y, bounds.width, bounds.height);
+            resultsList.putClientProperty(SUMMARY_REVERT_PROPERTY + index, bounds); // NOI18N
+        }
+
+    }
+
+    private static class HyperlinkLabel extends JLabel {
+
+        public HyperlinkLabel()
+        {
+            setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
+        }
+
+        public void set(String text, Color foreground, Color background)
+        {
+            StringBuilder sb = new StringBuilder(100);
+            if (foreground.equals(UIManager.getColor(&quot;List.foreground&quot;))) { // NOI18N
+                sb.append(&quot;&lt;html&gt;&lt;a href=\&quot;\&quot;&gt;&quot;); // NOI18N
+                sb.append(text);
+                sb.append(&quot;&lt;/a&gt;&quot;); // NOI18N
+            } else {
+                sb.append(&quot;&lt;html&gt;&lt;a href=\&quot;\&quot; style=\&quot;color:&quot;); // NOI18N
+                sb.append(&quot;rgb(&quot;); // NOI18N
+                sb.append(foreground.getRed());
+                sb.append(&quot;,&quot;); // NOI18N
+                sb.append(foreground.getGreen());
+                sb.append(&quot;,&quot;); // NOI18N
+                sb.append(foreground.getBlue());
+                sb.append(&quot;)&quot;); // NOI18N
+                sb.append(&quot;\&quot;&gt;&quot;); // NOI18N
+                sb.append(text);
+                sb.append(&quot;&lt;/a&gt;&quot;); // NOI18N
+            }
+            setText(sb.toString());
+            setBackground(background);
+        }
+
+    }
 
 }
\ No newline at end of file</diff>
      <filename>src/org/nbgit/ui/log/SummaryView.java</filename>
    </modified>
    <modified>
      <diff>@@ -63,154 +63,154 @@ import org.spearce.jgit.lib.RepositoryConfig;
  */
 public class GitProperties implements ListSelectionListener {
 
-	public static final String GITPROPNAME_USER_EMAIL = &quot;email&quot;; // NOI18N
-	public static final String GITPROPNAME_USER_NAME = &quot;name&quot;; // NOI18N
-	public static final String GITPROPNAME_DEFAULT_PULL = &quot;default-pull&quot;; // NOI18N
-	private PropertiesPanel panel;
-	private File root;
-	private PropertiesTable propTable;
-	private GitProgressSupport support;
-	private File loadedValueFile;
-	private Font fontTextArea;
-
-	/** Creates a new instance of GitProperties */
-	public GitProperties(PropertiesPanel panel, PropertiesTable propTable, File root)
-	{
-		this.panel = panel;
-		this.propTable = propTable;
-		this.root = root;
-		propTable.getTable().getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
-		propTable.getTable().getSelectionModel().addListSelectionListener(this);
-
-		refreshProperties();
-	}
-
-	public PropertiesPanel getPropertiesPanel()
-	{
-		return panel;
-	}
-
-	public void setPropertiesPanel(PropertiesPanel panel)
-	{
-		this.panel = panel;
-	}
-
-	public File getRoot()
-	{
-		return root;
-	}
-
-	public void setRoot(File root)
-	{
-		this.root = root;
-	}
-
-	protected String getPropertyValue()
-	{
-		return panel.txtAreaValue.getText();
-	}
-
-	protected void refreshProperties()
-	{
-		RequestProcessor rp = Git.getInstance().getRequestProcessor(root.getAbsolutePath());
-		try {
-			support = new GitProgressSupport() {
-
-				protected void perform()
-				{
-					Properties props = GitModuleConfig.getDefault().getProperties(root);
-					GitPropertiesNode[] gitProps = new GitPropertiesNode[props.size()];
-					int i = 0;
-
-					for (Enumeration e = props.propertyNames(); e.hasMoreElements();) {
-						String name = (String) e.nextElement();
-						String tmp = props.getProperty(name);
-						String value = tmp != null ? tmp : &quot;&quot;; // NOI18N
-						gitProps[i] = new GitPropertiesNode(name, value);
-						i++;
-					}
-					propTable.setNodes(gitProps);
-				}
-			};
-			support.start(rp, root.getAbsolutePath(), org.openide.util.NbBundle.getMessage(GitProperties.class, &quot;LBL_Properties_Progress&quot;)); // NOI18N
-		} finally {
-			support = null;
-		}
-	}
-
-	public void setProperties()
-	{
-		RequestProcessor rp = Git.getInstance().getRequestProcessor(root.getAbsolutePath());
-		try {
-			support = new GitProgressSupport() {
-
-				protected void perform()
-				{
-					Repository repo = Git.getInstance().getRepository(root);
-					if (repo == null) {
-						return;
-					}
-					RepositoryConfig config = repo.getConfig();
-					boolean save = false;
-					/*
-					GitModuleConfig.getDefault().clearProperties(root, &quot;paths&quot;); // NOI18N
-					GitModuleConfig.getDefault().removeProperty(root, &quot;user&quot;, GITPROPNAME_USER_EMAIL); // NOI18N
-					GitModuleConfig.getDefault().removeProperty(root, &quot;user&quot;, GITPROPNAME_USER_NAME); // NOI18N
-					 */
-					GitPropertiesNode[] gitPropertiesNodes = propTable.getNodes();
-					for (int i = 0; i &lt; gitPropertiesNodes.length; i++) {
-						String name = gitPropertiesNodes[i].getName();
-						String value = gitPropertiesNodes[i].getValue().trim();
-						if (value.length() == 0) {
-							continue;
-						}
-						if (name.equals(&quot;user.name&quot;)) {
-							config.setString(&quot;user&quot;, null, &quot;name&quot;, value);
-							save = true;
-						}
-
-						if (name.equals(&quot;user.email&quot;)) {
-							config.setString(&quot;user&quot;, null, &quot;email&quot;, value);
-							save = true;
-						}
-					}
-
-					//GitRepositoryContextCache.resetPullDefault();
-					//GitRepositoryContextCache.resetPushDefault();
-					try {
-						config.save();
-					} catch (IOException ex) {
-						Exceptions.printStackTrace(ex);
-					}
-				}
-			};
-			support.start(rp, root.getAbsolutePath(), org.openide.util.NbBundle.getMessage(GitProperties.class, &quot;LBL_Properties_Progress&quot;)); // NOI18N
-		} finally {
-			support = null;
-		}
-	}
-	private int lastIndex = -1;
-
-	public void updateLastSelection()
-	{
-		GitPropertiesNode[] gitPropertiesNodes = propTable.getNodes();
-		if (lastIndex &gt;= 0) {
-			gitPropertiesNodes[lastIndex].setValue(getPropertyValue());
-		}
-	}
-
-	public void valueChanged(ListSelectionEvent e)
-	{
-		int index = propTable.getTable().getSelectedRow();
-		if (index &lt; 0) {
-			lastIndex = -1;
-			return;
-		}
-		GitPropertiesNode[] gitPropertiesNodes = propTable.getNodes();
-		if (lastIndex &gt;= 0) {
-			gitPropertiesNodes[lastIndex].setValue(getPropertyValue());
-		}
-		panel.txtAreaValue.setText(gitPropertiesNodes[index].getValue());
-		lastIndex = index;
-	}
+    public static final String GITPROPNAME_USER_EMAIL = &quot;email&quot;; // NOI18N
+    public static final String GITPROPNAME_USER_NAME = &quot;name&quot;; // NOI18N
+    public static final String GITPROPNAME_DEFAULT_PULL = &quot;default-pull&quot;; // NOI18N
+    private PropertiesPanel panel;
+    private File root;
+    private PropertiesTable propTable;
+    private GitProgressSupport support;
+    private File loadedValueFile;
+    private Font fontTextArea;
+
+    /** Creates a new instance of GitProperties */
+    public GitProperties(PropertiesPanel panel, PropertiesTable propTable, File root)
+    {
+        this.panel = panel;
+        this.propTable = propTable;
+        this.root = root;
+        propTable.getTable().getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+        propTable.getTable().getSelectionModel().addListSelectionListener(this);
+
+        refreshProperties();
+    }
+
+    public PropertiesPanel getPropertiesPanel()
+    {
+        return panel;
+    }
+
+    public void setPropertiesPanel(PropertiesPanel panel)
+    {
+        this.panel = panel;
+    }
+
+    public File getRoot()
+    {
+        return root;
+    }
+
+    public void setRoot(File root)
+    {
+        this.root = root;
+    }
+
+    protected String getPropertyValue()
+    {
+        return panel.txtAreaValue.getText();
+    }
+
+    protected void refreshProperties()
+    {
+        RequestProcessor rp = Git.getInstance().getRequestProcessor(root.getAbsolutePath());
+        try {
+            support = new GitProgressSupport() {
+
+                protected void perform()
+                {
+                    Properties props = GitModuleConfig.getDefault().getProperties(root);
+                    GitPropertiesNode[] gitProps = new GitPropertiesNode[props.size()];
+                    int i = 0;
+
+                    for (Enumeration e = props.propertyNames(); e.hasMoreElements();) {
+                        String name = (String) e.nextElement();
+                        String tmp = props.getProperty(name);
+                        String value = tmp != null ? tmp : &quot;&quot;; // NOI18N
+                        gitProps[i] = new GitPropertiesNode(name, value);
+                        i++;
+                    }
+                    propTable.setNodes(gitProps);
+                }
+            };
+            support.start(rp, root.getAbsolutePath(), org.openide.util.NbBundle.getMessage(GitProperties.class, &quot;LBL_Properties_Progress&quot;)); // NOI18N
+        } finally {
+            support = null;
+        }
+    }
+
+    public void setProperties()
+    {
+        RequestProcessor rp = Git.getInstance().getRequestProcessor(root.getAbsolutePath());
+        try {
+            support = new GitProgressSupport() {
+
+                protected void perform()
+                {
+                    Repository repo = Git.getInstance().getRepository(root);
+                    if (repo == null) {
+                        return;
+                    }
+                    RepositoryConfig config = repo.getConfig();
+                    boolean save = false;
+                    /*
+                    GitModuleConfig.getDefault().clearProperties(root, &quot;paths&quot;); // NOI18N
+                    GitModuleConfig.getDefault().removeProperty(root, &quot;user&quot;, GITPROPNAME_USER_EMAIL); // NOI18N
+                    GitModuleConfig.getDefault().removeProperty(root, &quot;user&quot;, GITPROPNAME_USER_NAME); // NOI18N
+                     */
+                    GitPropertiesNode[] gitPropertiesNodes = propTable.getNodes();
+                    for (int i = 0; i &lt; gitPropertiesNodes.length; i++) {
+                        String name = gitPropertiesNodes[i].getName();
+                        String value = gitPropertiesNodes[i].getValue().trim();
+                        if (value.length() == 0) {
+                            continue;
+                        }
+                        if (name.equals(&quot;user.name&quot;)) {
+                            config.setString(&quot;user&quot;, null, &quot;name&quot;, value);
+                            save = true;
+                        }
+
+                        if (name.equals(&quot;user.email&quot;)) {
+                            config.setString(&quot;user&quot;, null, &quot;email&quot;, value);
+                            save = true;
+                        }
+                    }
+
+                    //GitRepositoryContextCache.resetPullDefault();
+                    //GitRepositoryContextCache.resetPushDefault();
+                    try {
+                        config.save();
+                    } catch (IOException ex) {
+                        Exceptions.printStackTrace(ex);
+                    }
+                }
+            };
+            support.start(rp, root.getAbsolutePath(), org.openide.util.NbBundle.getMessage(GitProperties.class, &quot;LBL_Properties_Progress&quot;)); // NOI18N
+        } finally {
+            support = null;
+        }
+    }
+    private int lastIndex = -1;
+
+    public void updateLastSelection()
+    {
+        GitPropertiesNode[] gitPropertiesNodes = propTable.getNodes();
+        if (lastIndex &gt;= 0) {
+            gitPropertiesNodes[lastIndex].setValue(getPropertyValue());
+        }
+    }
+
+    public void valueChanged(ListSelectionEvent e)
+    {
+        int index = propTable.getTable().getSelectedRow();
+        if (index &lt; 0) {
+            lastIndex = -1;
+            return;
+        }
+        GitPropertiesNode[] gitPropertiesNodes = propTable.getNodes();
+        if (lastIndex &gt;= 0) {
+            gitPropertiesNodes[lastIndex].setValue(getPropertyValue());
+        }
+        panel.txtAreaValue.setText(gitPropertiesNodes[index].getValue());
+        lastIndex = index;
+    }
 }
\ No newline at end of file</diff>
      <filename>src/org/nbgit/ui/properties/GitProperties.java</filename>
    </modified>
    <modified>
      <diff>@@ -49,25 +49,25 @@ public class GitPropertiesNode {
 
     private String name;
     private String value;
-    
+
     /** Creates a new instance of GitPropertiesNode */
     public GitPropertiesNode(String name, String value) {
         this.name = name;
         this.value = value;
     }
-    
+
     public String getName() {
         return name;
-    }    
-    
+    }
+
     public String getValue() {
         return value;
     }
-    
+
     public void setValue(String value) {
         this.value = value;
-    }    
-    
+    }
+
     @Override
     public int hashCode() {
         return name.hashCode();</diff>
      <filename>src/org/nbgit/ui/properties/GitPropertiesNode.java</filename>
    </modified>
    <modified>
      <diff>@@ -55,60 +55,60 @@ import org.openide.DialogDisplayer;
 import org.openide.util.HelpCtx;
 
 /**
- * Properties for Git: 
+ * Properties for Git:
  * Set git repository properties
- * 
+ *
  * @author John Rice
  */
 public class PropertiesAction extends ContextAction {
 
-	public PropertiesAction(String name, VCSContext context)
-	{
-		super(name, context);
-	}
+    public PropertiesAction(String name, VCSContext context)
+    {
+        super(name, context);
+    }
 
-	public void performAction(ActionEvent e)
-	{
-		File root = GitUtils.getRootFile(context);
-		if (root == null)
-			return;
-		final PropertiesPanel panel = new PropertiesPanel();
-		final PropertiesTable propTable;
+    public void performAction(ActionEvent e)
+    {
+        File root = GitUtils.getRootFile(context);
+        if (root == null)
+            return;
+        final PropertiesPanel panel = new PropertiesPanel();
+        final PropertiesTable propTable;
 
-		propTable = new PropertiesTable(panel.labelForTable, PropertiesTable.PROPERTIES_COLUMNS);
-		panel.setPropertiesTable(propTable);
+        propTable = new PropertiesTable(panel.labelForTable, PropertiesTable.PROPERTIES_COLUMNS);
+        panel.setPropertiesTable(propTable);
 
-		JComponent component = propTable.getComponent();
+        JComponent component = propTable.getComponent();
 
-		panel.propsPanel.setLayout(new BorderLayout());
-		panel.propsPanel.add(component, BorderLayout.CENTER);
+        panel.propsPanel.setLayout(new BorderLayout());
+        panel.propsPanel.add(component, BorderLayout.CENTER);
 
-		GitProperties gitProperties = new GitProperties(panel, propTable, root);
+        GitProperties gitProperties = new GitProperties(panel, propTable, root);
 
-		DialogDescriptor dd = new DialogDescriptor(panel, org.openide.util.NbBundle.getMessage(PropertiesAction.class, &quot;CTL_PropertiesDialog_Title&quot;, null), true, null); // NOI18N
+        DialogDescriptor dd = new DialogDescriptor(panel, org.openide.util.NbBundle.getMessage(PropertiesAction.class, &quot;CTL_PropertiesDialog_Title&quot;, null), true, null); // NOI18N
 
-		JButton okButton = new JButton();
-		org.openide.awt.Mnemonics.setLocalizedText(okButton, org.openide.util.NbBundle.getMessage(PropertiesAction.class, &quot;CTL_Properties_Action_OK&quot;));
-		okButton.getAccessibleContext().setAccessibleName(org.openide.util.NbBundle.getMessage(PropertiesAction.class, &quot;ACSN_Properties_Action_OK&quot;)); // NOI18N
-		okButton.getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getMessage(PropertiesAction.class, &quot;ACSD_Properties_Action_OK&quot;));
+        JButton okButton = new JButton();
+        org.openide.awt.Mnemonics.setLocalizedText(okButton, org.openide.util.NbBundle.getMessage(PropertiesAction.class, &quot;CTL_Properties_Action_OK&quot;));
+        okButton.getAccessibleContext().setAccessibleName(org.openide.util.NbBundle.getMessage(PropertiesAction.class, &quot;ACSN_Properties_Action_OK&quot;)); // NOI18N
+        okButton.getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getMessage(PropertiesAction.class, &quot;ACSD_Properties_Action_OK&quot;));
 
-		JButton cancelButton = new JButton();
-		org.openide.awt.Mnemonics.setLocalizedText(cancelButton, org.openide.util.NbBundle.getMessage(PropertiesAction.class, &quot;CTL_Properties_Action_Cancel&quot;));
-		cancelButton.getAccessibleContext().setAccessibleName(org.openide.util.NbBundle.getMessage(PropertiesAction.class, &quot;ACSN_Properties_Action_Cancel&quot;)); // NOI18N
-		cancelButton.getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getMessage(PropertiesAction.class, &quot;ACSD_Properties_Action_Cancel&quot;));
-		dd.setOptions(new Object[]{okButton, cancelButton});
-		dd.setHelpCtx(new HelpCtx(PropertiesAction.class));
-		panel.putClientProperty(&quot;contentTitle&quot;, null);  // NOI18N
-		panel.putClientProperty(&quot;DialogDescriptor&quot;, dd); // NOI18N
+        JButton cancelButton = new JButton();
+        org.openide.awt.Mnemonics.setLocalizedText(cancelButton, org.openide.util.NbBundle.getMessage(PropertiesAction.class, &quot;CTL_Properties_Action_Cancel&quot;));
+        cancelButton.getAccessibleContext().setAccessibleName(org.openide.util.NbBundle.getMessage(PropertiesAction.class, &quot;ACSN_Properties_Action_Cancel&quot;)); // NOI18N
+        cancelButton.getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getMessage(PropertiesAction.class, &quot;ACSD_Properties_Action_Cancel&quot;));
+        dd.setOptions(new Object[]{okButton, cancelButton});
+        dd.setHelpCtx(new HelpCtx(PropertiesAction.class));
+        panel.putClientProperty(&quot;contentTitle&quot;, null);  // NOI18N
+        panel.putClientProperty(&quot;DialogDescriptor&quot;, dd); // NOI18N
 
-		Dialog dialog = DialogDisplayer.getDefault().createDialog(dd);
-		dialog.getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getMessage(PropertiesAction.class, &quot;ACSD_Properties_Dialog&quot;)); // NOI18N
-		dialog.pack();
-		dialog.setVisible(true);
-		if (dd.getValue() == okButton) {
-			gitProperties.updateLastSelection();
-			gitProperties.setProperties();
-		}
-	}
+        Dialog dialog = DialogDisplayer.getDefault().createDialog(dd);
+        dialog.getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getMessage(PropertiesAction.class, &quot;ACSD_Properties_Dialog&quot;)); // NOI18N
+        dialog.pack();
+        dialog.setVisible(true);
+        if (dd.getValue() == okButton) {
+            gitProperties.updateLastSelection();
+            gitProperties.setProperties();
+        }
+    }
 
 }
\ No newline at end of file</diff>
      <filename>src/org/nbgit/ui/properties/PropertiesAction.java</filename>
    </modified>
    <modified>
      <diff>@@ -57,12 +57,12 @@ public class PropertiesPanel extends javax.swing.JPanel implements PreferenceCha
     private static final Object EVENT_SETTINGS_CHANGED = new Object();
     private PropertiesTable propertiesTable;
     private ListenersSupport listenerSupport = new ListenersSupport(this);
-    
+
     /** Creates new form PropertiesPanel */
     public PropertiesPanel() {
         initComponents();
     }
-    
+
     public javax.swing.JTextArea getTxtAreaValue() {
         return txtAreaValue;
     }
@@ -70,11 +70,11 @@ public class PropertiesPanel extends javax.swing.JPanel implements PreferenceCha
     public void setPropertiesTable(PropertiesTable propertiesTable){
         this.propertiesTable = propertiesTable;
     }
-    
+
     @Override
     public void addNotify() {
         super.addNotify();
-        GitModuleConfig.getDefault().getPreferences().addPreferenceChangeListener(this);        
+        GitModuleConfig.getDefault().getPreferences().addPreferenceChangeListener(this);
         propertiesTable.getTableModel().addTableModelListener(this);
         listenerSupport.fireVersioningEvent(EVENT_SETTINGS_CHANGED);
         txtAreaValue.selectAll();
@@ -86,7 +86,7 @@ public class PropertiesPanel extends javax.swing.JPanel implements PreferenceCha
         GitModuleConfig.getDefault().getPreferences().removePreferenceChangeListener(this);
         super.removeNotify();
     }
-    
+
     public void preferenceChange(PreferenceChangeEvent evt) {
         if (evt.getKey().startsWith(GitModuleConfig.PROP_COMMIT_EXCLUSIONS)) {
             propertiesTable.dataChanged();
@@ -97,7 +97,7 @@ public class PropertiesPanel extends javax.swing.JPanel implements PreferenceCha
     public void tableChanged(TableModelEvent e) {
         listenerSupport.fireVersioningEvent(EVENT_SETTINGS_CHANGED);
     }
-    
+
     /** This method is called from within the constructor to
      * initialize the form.
      * WARNING: Do NOT modify this code. The content of this method is
@@ -159,8 +159,8 @@ public class PropertiesPanel extends javax.swing.JPanel implements PreferenceCha
                 .addContainerGap())
         );
     }// &lt;/editor-fold&gt;//GEN-END:initComponents
-    
-    
+
+
     // Variables declaration - do not modify//GEN-BEGIN:variables
     private javax.swing.JLabel jLabel1;
     private javax.swing.JScrollPane jScrollPane1;
@@ -168,5 +168,5 @@ public class PropertiesPanel extends javax.swing.JPanel implements PreferenceCha
     public javax.swing.JPanel propsPanel;
     final javax.swing.JTextArea txtAreaValue = new javax.swing.JTextArea();
     // End of variables declaration//GEN-END:variables
-    
+
 }
\ No newline at end of file</diff>
      <filename>src/org/nbgit/ui/properties/PropertiesPanel.java</filename>
    </modified>
    <modified>
      <diff>@@ -62,19 +62,19 @@ import org.openide.util.NbBundle;
  * @author Padraig O'Briain
  */
 public class PropertiesTable implements AncestorListener, TableModelListener {
-    
+
     public static final String[] PROPERTIES_COLUMNS = new String[]{PropertiesTableModel.COLUMN_NAME_NAME, PropertiesTableModel.COLUMN_NAME_VALUE};
-            
+
     private PropertiesTableModel tableModel;
     private JTable table;
     private JComponent component;
     private String[] columns;
-    
+
     /** Creates a new instance of PropertiesTable */
     public PropertiesTable(JLabel label, String[] columns) {
         init(label, columns);
     }
-    
+
     private void init(JLabel label, String[] columns) {
         tableModel = new PropertiesTableModel(columns);
         tableModel.addTableModelListener(this);
@@ -85,12 +85,12 @@ public class PropertiesTable implements AncestorListener, TableModelListener {
         table.addAncestorListener(this);
         component = new JScrollPane(table, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
         component.setPreferredSize(new Dimension(340, 150));
-        table.getAccessibleContext().setAccessibleDescription(NbBundle.getMessage(PropertiesTable.class, &quot;ACSD_PropertiesTable&quot;)); // NOI18N        
-        table.getAccessibleContext().setAccessibleName(NbBundle.getMessage(PropertiesTable.class, &quot;ACSN_PropertiesTable&quot;)); // NOI18N        
+        table.getAccessibleContext().setAccessibleDescription(NbBundle.getMessage(PropertiesTable.class, &quot;ACSD_PropertiesTable&quot;)); // NOI18N
+        table.getAccessibleContext().setAccessibleName(NbBundle.getMessage(PropertiesTable.class, &quot;ACSN_PropertiesTable&quot;)); // NOI18N
         label.setLabelFor(table);
         setColumns(columns);
     }
-    
+
     public void setColumns(String[] clmns) {
         if (Arrays.equals(columns, clmns))
             return;
@@ -98,11 +98,11 @@ public class PropertiesTable implements AncestorListener, TableModelListener {
         tableModel.setColumns(clmns);
         setDefaultColumnSize();
     }
-    
+
     public JTable getTable() {
         return table;
     }
-    
+
     private void setDefaultColumnSize() {
         int width = table.getWidth();
         TableColumnModel columnModel = table.getColumnModel();
@@ -111,7 +111,7 @@ public class PropertiesTable implements AncestorListener, TableModelListener {
         if (columnModel.getColumnCount() != columns.length)
             return;
         for (int i = 0; i &lt; columns.length; i++) {
-            String col = columns[i];                                
+            String col = columns[i];
             if (col.equals(PropertiesTableModel.COLUMN_NAME_NAME)) {
                 columnModel.getColumn(i).setPreferredWidth(width * 20 / 100);
             } else if (col.equals(PropertiesTableModel.COLUMN_NAME_VALUE)) {
@@ -119,35 +119,35 @@ public class PropertiesTable implements AncestorListener, TableModelListener {
             }
         }
     }
-    
+
     public TableModel getTableModel() {
         return tableModel;
     }
-    
+
     public void dataChanged() {
         int idx = table.getSelectedRow();
         tableModel.fireTableDataChanged();
         if (idx != -1) {
             table.getSelectionModel().addSelectionInterval(idx, idx);
-        }    
+        }
     }
-    
+
     public int[] getSelectedItems() {
         return table.getSelectedRows();
     }
-     
+
     public GitPropertiesNode[] getNodes() {
         return tableModel.getNodes();
     }
-    
+
     public void setNodes(GitPropertiesNode[] nodes) {
         tableModel.setNodes(nodes);
     }
-    
+
     public JComponent getComponent() {
         return component;
     }
-    
+
     public void ancestorAdded(AncestorEvent arg0) {
         setDefaultColumnSize();
     }
@@ -163,7 +163,7 @@ public class PropertiesTable implements AncestorListener, TableModelListener {
     }
 
     public class PropertiesTableCellRenderer extends DefaultTableCellRenderer {
-           
+
         @Override
         public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int rowIndex, int columnIndex) {
             Component renderer = super.getTableCellRendererComponent(table, value, hasFocus, hasFocus, rowIndex, columnIndex);
@@ -175,5 +175,5 @@ public class PropertiesTable implements AncestorListener, TableModelListener {
             return renderer;
         }
     }
-    
+
 }
\ No newline at end of file</diff>
      <filename>src/org/nbgit/ui/properties/PropertiesTable.java</filename>
    </modified>
    <modified>
      <diff>@@ -53,7 +53,7 @@ import org.openide.util.NbBundle;
  * @author Peter Pis
  */
 public class PropertiesTableModel extends AbstractTableModel {
-    
+
     public static final String COLUMN_NAME_NAME = &quot;name&quot;;   // NOI18N
     public static final String COLUMN_NAME_VALUE = &quot;value&quot;; // NOI18N
 
@@ -66,7 +66,7 @@ public class PropertiesTableModel extends AbstractTableModel {
         columnLabels.put(COLUMN_NAME_NAME, new String[]{loc.getString(&quot;CTL_PropertiesTable_Column_Name&quot;), loc.getString(&quot;CTL_PropertiesTable_Column_Name&quot;)}); // NOI18N
         columnLabels.put(COLUMN_NAME_VALUE, new String[]{loc.getString(&quot;CTL_PropertiesTable_Column_Value&quot;), loc.getString(&quot;CTL_PropertiesTable_Column_Value&quot;)}); // NOI18N
     }
-    
+
     /** Creates a new instance of PropertiesTableModel */
     public PropertiesTableModel(String[] clms) {
         if (Arrays.equals(columns, clms))
@@ -74,25 +74,25 @@ public class PropertiesTableModel extends AbstractTableModel {
         setColumns(clms);
         setNodes(new GitPropertiesNode[0]);
     }
-    
+
     public void setColumns(String[] clms) {
         this.columns = clms;
         fireTableStructureChanged();
     }
-    
+
     public void setNodes(GitPropertiesNode[] nodes) {
         this.nodes = nodes;
         fireTableDataChanged();
     }
-    
+
     public GitPropertiesNode[] getNodes() {
         return nodes;
     }
-    
+
     public GitPropertiesNode getNode(int row) {
         return nodes[row];
     }
-    
+
     public int getRowCount() {
         return nodes.length;
     }
@@ -101,7 +101,7 @@ public class PropertiesTableModel extends AbstractTableModel {
     public String getColumnName(int column) {
         return columnLabels.get(columns[column])[0];
     }
-    
+
     public int getColumnCount() {
         return columns.length;
     }
@@ -115,5 +115,5 @@ public class PropertiesTableModel extends AbstractTableModel {
         }
         throw new IllegalArgumentException(&quot;The column index is out of index: &quot; + columnIndex); // NOI18N
     }
-    
+
 }
\ No newline at end of file</diff>
      <filename>src/org/nbgit/ui/properties/PropertiesTableModel.java</filename>
    </modified>
    <modified>
      <diff>@@ -57,22 +57,22 @@ import org.openide.windows.WindowManager;
 
 /**
  * Top component of the Versioning view.
- * 
+ *
  * @author Maros Sandor
  */
 public class GitVersioningTopComponent extends TopComponent {
- 
-    private static final long serialVersionUID = 1L;    
-    
+
+    private static final long serialVersionUID = 1L;
+
     private VersioningPanel         syncPanel;
     private VCSContext              context;
     private String                  contentTitle;
     private String                  branchTitle;
     private long                    lastUpdateTimestamp;
     private static final String PREFERRED_ID = &quot;gitversioning&quot;; // NOI18N
-    
+
     private static GitVersioningTopComponent instance;
-    
+
     public GitVersioningTopComponent() {
         putClientProperty(&quot;SlidingName&quot;, NbBundle.getMessage(GitVersioningTopComponent.class, &quot;CTL_Versioning_TopComponent_Title&quot;)); //NOI18N
 
@@ -83,7 +83,7 @@ public class GitVersioningTopComponent extends TopComponent {
         syncPanel = new VersioningPanel(this);
         add(syncPanel);
     }
-    
+
     @Override
     public HelpCtx getHelpCtx() {
         return new HelpCtx(getClass());
@@ -109,15 +109,15 @@ public class GitVersioningTopComponent extends TopComponent {
     private void refreshContent() {
         if (syncPanel == null) return;  // the component is not showing =&gt; nothing to refresh
         updateTitle();
-        syncPanel.setContext(context);        
+        syncPanel.setContext(context);
     }
 
     /**
      * Sets the 'content' portion of Versioning component title.
      * Title pattern: Versioning[ - contentTitle[ - branchTitle]] (10 minutes ago)
-     * 
+     *
      * @param contentTitle a new content title, e.g. &quot;2 projects&quot; // NOI18N
-     */ 
+     */
     public void setContentTitle(String contentTitle) {
         this.contentTitle = contentTitle;
         updateTitle();
@@ -126,23 +126,23 @@ public class GitVersioningTopComponent extends TopComponent {
     /**
      * Sets the 'branch' portion of Versioning component title.
      * Title pattern: Versioning[ - contentTitle[ - branchTitle]] (10 minutes ago)
-     * 
+     *
      * @param branchTitle a new content title, e.g. &quot;release40&quot; branch // NOI18N
-     */ 
+     */
     void setBranchTitle(String branchTitle) {
         this.branchTitle = branchTitle;
         updateTitle();
     }
-    
+
     public void contentRefreshed() {
         lastUpdateTimestamp = System.currentTimeMillis();
         updateTitle();
     }
-    
+
     private void updateTitle() {
         SwingUtilities.invokeLater(new Runnable (){
             public void run() {
-                
+
                 if (contentTitle == null) {
                     setName(NbBundle.getMessage(GitVersioningTopComponent.class, &quot;CTL_Versioning_TopComponent_Title&quot;)); // NOI18N
                 } else {
@@ -151,17 +151,17 @@ public class GitVersioningTopComponent extends TopComponent {
                     if(baseFile != null){
                         name = baseFile.getName();
                     }
-                    
+
                     if (branchTitle == null) {
-                        setName(NbBundle.getMessage(GitVersioningTopComponent.class, 
-                                &quot;CTL_Versioning_TopComponent_MultiTitle&quot;, 
+                        setName(NbBundle.getMessage(GitVersioningTopComponent.class,
+                                &quot;CTL_Versioning_TopComponent_MultiTitle&quot;,
                                 contentTitle, name.equals(contentTitle)? &quot;&quot;: &quot;[&quot; + name + &quot;]&quot;));  // NOI18N
                     } else {
-                        setName(NbBundle.getMessage(GitVersioningTopComponent.class, 
-                                &quot;CTL_Versioning_TopComponent_Title_ContentBranch&quot;, 
+                        setName(NbBundle.getMessage(GitVersioningTopComponent.class,
+                                &quot;CTL_Versioning_TopComponent_Title_ContentBranch&quot;,
                                 contentTitle, name.equals(contentTitle)? &quot;&quot;: &quot;[&quot; + name + &quot;] &quot;, branchTitle)); // NOI18N
                     }
-                }                
+                }
             }
         });
     }
@@ -181,7 +181,7 @@ public class GitVersioningTopComponent extends TopComponent {
         }
         return instance;
     }
-    
+
     /**
      * Obtain the GitVersioningTopComponent  instance. Never call {@link #getDefault} directly!
      */
@@ -194,7 +194,7 @@ public class GitVersioningTopComponent extends TopComponent {
         if (win instanceof GitVersioningTopComponent) {
             return (GitVersioningTopComponent)win;
         }
-        Git.LOG.log(Level.FINE, 
+        Git.LOG.log(Level.FINE,
                 &quot;There seem to be multiple components with the '&quot; + PREFERRED_ID + // NOI18N
                 &quot;' ID. That is a potential source of errors and unexpected behavior.&quot;); // NOI18N
         return getDefault();
@@ -204,18 +204,18 @@ public class GitVersioningTopComponent extends TopComponent {
     public int getPersistenceType() {
         return TopComponent.PERSISTENCE_ALWAYS;
     }
-    
+
     /** replaces this in object stream */
     @Override
     public Object writeReplace() {
         return new ResolvableHelper();
     }
-    
+
     @Override
     protected String preferredID() {
         return PREFERRED_ID;
     }
-    
+
     final static class ResolvableHelper implements Serializable {
         private static final long serialVersionUID = 1L;
         public Object readResolve() {
@@ -225,14 +225,14 @@ public class GitVersioningTopComponent extends TopComponent {
 
     /**
      * Programmatically invokes the Refresh action.
-     */ 
+     */
     public void performRefreshAction() {
         syncPanel.performRefreshAction();
     }
 
     /**
      * Sets files/folders the user wants to synchronize. They are typically activated (selected) nodes.
-     * 
+     *
      * @param ctx new context of the Versioning view
      */
     public void setContext(VCSContext ctx) {
@@ -252,19 +252,19 @@ public class GitVersioningTopComponent extends TopComponent {
         }
         setToolTipText(getContextFilesList(ctx));
     }
-    
+
     private String getContextFilesList(VCSContext ctx) {
         if (ctx == null || ctx.getRootFiles().size() == 0)
-		return NbBundle.getMessage(GitVersioningTopComponent.class, &quot;CTL_Versioning_TopComponent_Title&quot;); // NOI18N
-	int size = ctx.getRootFiles().size();
+        return NbBundle.getMessage(GitVersioningTopComponent.class, &quot;CTL_Versioning_TopComponent_Title&quot;); // NOI18N
+    int size = ctx.getRootFiles().size();
 
-	StringBuffer sb = new StringBuffer(200);
+    StringBuffer sb = new StringBuffer(200);
         if (size &gt; 1)
-		sb.append(&quot;&lt;html&gt;&quot;); // NOI18N
+        sb.append(&quot;&lt;html&gt;&quot;); // NOI18N
         for (File file : ctx.getRootFiles()) {
             sb.append(file.getAbsolutePath());
-	    size--;
-	    if (size &gt; 0)
+        size--;
+        if (size &gt; 0)
                 sb.append(&quot;&lt;br&gt;&quot;); // NOI18N
         }
         return sb.toString();
@@ -274,5 +274,5 @@ public class GitVersioningTopComponent extends TopComponent {
     public boolean hasContext() {
         return context != null &amp;&amp; context.getRootFiles().size() &gt; 0;
     }
-    
+
 }
\ No newline at end of file</diff>
      <filename>src/org/nbgit/ui/status/GitVersioningTopComponent.java</filename>
    </modified>
    <modified>
      <diff>@@ -63,65 +63,65 @@ import org.openide.util.NbBundle;
  */
 public class OpenInEditorAction extends AbstractAction {
 
-	public OpenInEditorAction()
-	{
-		super(NbBundle.getBundle(OpenInEditorAction.class).getString(&quot;CTL_Synchronize_Popup_OpenInEditor&quot;)); // NOI18N
-		setEnabled(isActionEnabled());
-	}
+    public OpenInEditorAction()
+    {
+        super(NbBundle.getBundle(OpenInEditorAction.class).getString(&quot;CTL_Synchronize_Popup_OpenInEditor&quot;)); // NOI18N
+        setEnabled(isActionEnabled());
+    }
 
-	private boolean isActionEnabled()
-	{
-		for (File file : GitUtils.getCurrentContext(null).getRootFiles()) {
-			if (file.canRead())
-				return true;
-		}
-		return false;
-	}
+    private boolean isActionEnabled()
+    {
+        for (File file : GitUtils.getCurrentContext(null).getRootFiles()) {
+            if (file.canRead())
+                return true;
+        }
+        return false;
+    }
 
-	public void actionPerformed(ActionEvent e)
-	{
-		for (File file : GitUtils.getCurrentContext(null).getRootFiles()) {
-			FileObject fo = FileUtil.toFileObject(file);
-			if (fo != null)
-				try {
-					openDataObjectByCookie(DataObject.find(fo));
-				} catch (DataObjectNotFoundException ex) {
-					// ignore this error and try to open other files too
-				}
-		}
-	}
+    public void actionPerformed(ActionEvent e)
+    {
+        for (File file : GitUtils.getCurrentContext(null).getRootFiles()) {
+            FileObject fo = FileUtil.toFileObject(file);
+            if (fo != null)
+                try {
+                    openDataObjectByCookie(DataObject.find(fo));
+                } catch (DataObjectNotFoundException ex) {
+                    // ignore this error and try to open other files too
+                }
+        }
+    }
 
-	private final boolean openDataObjectByCookie(DataObject dataObject)
-	{
-		Node.Cookie cookie;
+    private final boolean openDataObjectByCookie(DataObject dataObject)
+    {
+        Node.Cookie cookie;
 
-		if ((cookie = dataObject.getCookie(EditorCookie.Observable.class)) != null)
-			return openByCookie(cookie, EditorCookie.Observable.class);
-		if ((cookie = dataObject.getCookie(EditorCookie.class)) != null)
-			return openByCookie(cookie, EditorCookie.class);
-		if ((cookie = dataObject.getCookie(OpenCookie.class)) != null)
-			return openByCookie(cookie, OpenCookie.class);
-		if ((cookie = dataObject.getCookie(EditCookie.class)) != null)
-			return openByCookie(cookie, EditCookie.class);
-		if ((cookie = dataObject.getCookie(ViewCookie.class)) != null)
-			return openByCookie(cookie, ViewCookie.class);
+        if ((cookie = dataObject.getCookie(EditorCookie.Observable.class)) != null)
+            return openByCookie(cookie, EditorCookie.Observable.class);
+        if ((cookie = dataObject.getCookie(EditorCookie.class)) != null)
+            return openByCookie(cookie, EditorCookie.class);
+        if ((cookie = dataObject.getCookie(OpenCookie.class)) != null)
+            return openByCookie(cookie, OpenCookie.class);
+        if ((cookie = dataObject.getCookie(EditCookie.class)) != null)
+            return openByCookie(cookie, EditCookie.class);
+        if ((cookie = dataObject.getCookie(ViewCookie.class)) != null)
+            return openByCookie(cookie, ViewCookie.class);
 
-		return false;
-	}
+        return false;
+    }
 
-	private boolean openByCookie(Node.Cookie cookie, Class cookieClass)
-	{
-		if ((cookieClass == EditorCookie.class) || (cookieClass == EditorCookie.Observable.class))
-			((EditorCookie) cookie).open();
-		else if (cookieClass == OpenCookie.class)
-			((OpenCookie) cookie).open();
-		else if (cookieClass == EditCookie.class)
-			((EditCookie) cookie).edit();
-		else if (cookieClass == ViewCookie.class)
-			((ViewCookie) cookie).view();
-		else
-			throw new IllegalArgumentException(&quot;Reopen #58766: &quot; + cookieClass);
-		return true;
-	}
+    private boolean openByCookie(Node.Cookie cookie, Class cookieClass)
+    {
+        if ((cookieClass == EditorCookie.class) || (cookieClass == EditorCookie.Observable.class))
+            ((EditorCookie) cookie).open();
+        else if (cookieClass == OpenCookie.class)
+            ((OpenCookie) cookie).open();
+        else if (cookieClass == EditCookie.class)
+            ((EditCookie) cookie).edit();
+        else if (cookieClass == ViewCookie.class)
+            ((ViewCookie) cookie).view();
+        else
+            throw new IllegalArgumentException(&quot;Reopen #58766: &quot; + cookieClass);
+        return true;
+    }
 
 }
\ No newline at end of file</diff>
      <filename>src/org/nbgit/ui/status/OpenInEditorAction.java</filename>
    </modified>
    <modified>
      <diff>@@ -49,8 +49,8 @@ import org.openide.util.NbBundle;
 import org.openide.util.Utilities;
 
 /**
- * Open the Git view. It focuses recently opened view unless it's not 
- * initialized yet. For uninitialized view it behaves like StatusProjectsAction 
+ * Open the Git view. It focuses recently opened view unless it's not
+ * initialized yet. For uninitialized view it behaves like StatusProjectsAction
  * without on-open refresh.
  *
  * @author Petr Kuzel
@@ -69,14 +69,14 @@ public class OpenVersioningAction extends ShowAllChangesAction {
 
     /**
      * Window/Versioning should be always enabled.
-     * 
+     *
      * @return true
-     */ 
+     */
     @Override
     public boolean isEnabled() {
         return true;
     }
-    
+
     @Override
     public HelpCtx getHelpCtx() {
         return new HelpCtx(OpenVersioningAction.class);
@@ -84,7 +84,7 @@ public class OpenVersioningAction extends ShowAllChangesAction {
 
     @Override
     public void actionPerformed(ActionEvent e) {
-        
+
         GitVersioningTopComponent stc = GitVersioningTopComponent.findInstance();
         if (stc.hasContext() == false) {
             super.actionPerformed(e);
@@ -98,5 +98,5 @@ public class OpenVersioningAction extends ShowAllChangesAction {
     protected boolean shouldPostRefresh() {
         return false;
     }
-    
+
 }
\ No newline at end of file</diff>
      <filename>src/org/nbgit/ui/status/OpenVersioningAction.java</filename>
    </modified>
    <modified>
      <diff>@@ -92,5 +92,5 @@ public class ShowAllChangesAction extends SystemAction {
     protected boolean shouldPostRefresh() {
         return true;
     }
-    
+
 }
\ No newline at end of file</diff>
      <filename>src/org/nbgit/ui/status/ShowAllChangesAction.java</filename>
    </modified>
    <modified>
      <diff>@@ -56,70 +56,70 @@ import org.netbeans.modules.versioning.spi.VCSContext;
 import org.netbeans.modules.versioning.util.Utils;
 
 /**
- * Status action for Git: 
+ * Status action for Git:
  * git status - show changed files in the working directory
- * 
+ *
  * @author John Rice
  */
 public class StatusAction extends ContextAction {
 
-	public StatusAction(String name, VCSContext context)
-	{
-		super(name, context);
-	}
+    public StatusAction(String name, VCSContext context)
+    {
+        super(name, context);
+    }
 
-	public void performAction(ActionEvent ev)
-	{
-		File[] files = context.getRootFiles().toArray(new File[context.getRootFiles().size()]);
-		if (files == null || files.length == 0)
-			return;
+    public void performAction(ActionEvent ev)
+    {
+        File[] files = context.getRootFiles().toArray(new File[context.getRootFiles().size()]);
+        if (files == null || files.length == 0)
+            return;
 
-		final GitVersioningTopComponent stc = GitVersioningTopComponent.findInstance();
-		stc.setContentTitle(Utils.getContextDisplayName(context));
-		stc.setContext(context);
-		stc.open();
-		stc.requestActive();
-		stc.performRefreshAction();
-	}
+        final GitVersioningTopComponent stc = GitVersioningTopComponent.findInstance();
+        stc.setContentTitle(Utils.getContextDisplayName(context));
+        stc.setContext(context);
+        stc.open();
+        stc.requestActive();
+        stc.performRefreshAction();
+    }
 
-	/**
-	 * Connects to repository and gets recent status.
-	 */
-	public static void executeStatus(final VCSContext context, GitProgressSupport support)
-	{
-		if (context == null || context.getRootFiles().size() == 0)
-			return;
-		File repository = GitUtils.getRootFile(context);
-		if (repository == null)
-			return;
+    /**
+     * Connects to repository and gets recent status.
+     */
+    public static void executeStatus(final VCSContext context, GitProgressSupport support)
+    {
+        if (context == null || context.getRootFiles().size() == 0)
+            return;
+        File repository = GitUtils.getRootFile(context);
+        if (repository == null)
+            return;
 
-		StatusCache cache = Git.getInstance().getStatusCache();
-		cache.refreshCached(context);
+        StatusCache cache = Git.getInstance().getStatusCache();
+        cache.refreshCached(context);
 
-		for (File root : context.getRootFiles()) {
-			if (support.isCanceled())
-				return;
-			if (root.isDirectory()) {
-				Map&lt;File, StatusInfo&gt; interestingFiles;
-				interestingFiles = GitCommand.getInterestingStatus(repository, root);
-				if (!interestingFiles.isEmpty()) {
-					Collection&lt;File&gt; files = interestingFiles.keySet();
+        for (File root : context.getRootFiles()) {
+            if (support.isCanceled())
+                return;
+            if (root.isDirectory()) {
+                Map&lt;File, StatusInfo&gt; interestingFiles;
+                interestingFiles = GitCommand.getInterestingStatus(repository, root);
+                if (!interestingFiles.isEmpty()) {
+                    Collection&lt;File&gt; files = interestingFiles.keySet();
 
-					Map&lt;File, Map&lt;File, StatusInfo&gt;&gt; interestingDirs =
-						GitUtils.getInterestingDirs(interestingFiles, files);
+                    Map&lt;File, Map&lt;File, StatusInfo&gt;&gt; interestingDirs =
+                        GitUtils.getInterestingDirs(interestingFiles, files);
 
-					for (File file : files) {
-						if (support.isCanceled())
-							return;
-						StatusInfo fi = interestingFiles.get(file);
+                    for (File file : files) {
+                        if (support.isCanceled())
+                            return;
+                        StatusInfo fi = interestingFiles.get(file);
 
-						cache.refreshFileStatus(file, fi,
-							interestingDirs.get(file.isDirectory() ? file : file.getParentFile()));
-					}
-				}
-			} else
-				cache.refresh(root, StatusCache.REPOSITORY_STATUS_UNKNOWN);
-		}
-	}
+                        cache.refreshFileStatus(file, fi,
+                            interestingDirs.get(file.isDirectory() ? file : file.getParentFile()));
+                    }
+                }
+            } else
+                cache.refresh(root, StatusCache.REPOSITORY_STATUS_UNKNOWN);
+        }
+    }
 
 }
\ No newline at end of file</diff>
      <filename>src/org/nbgit/ui/status/StatusAction.java</filename>
    </modified>
    <modified>
      <diff>@@ -23,219 +23,219 @@ import org.openide.util.RequestProcessor;
 import org.openide.util.lookup.Lookups;
 
 /**
- * The node that is rendered in the SyncTable view. It gets values to display 
+ * The node that is rendered in the SyncTable view. It gets values to display
  * from the GitFileNode which serves as the 'data' node for this 'visual' node.
- * 
+ *
  * @author Maros Sandor
  */
 public class SyncFileNode extends AbstractNode {
 
-	private GitFileNode node;
-	static final String COLUMN_NAME_NAME = &quot;name&quot;; // NOI18N;
-	static final String COLUMN_NAME_PATH = &quot;path&quot;; // NOI18N;
-	static final String COLUMN_NAME_STATUS = &quot;status&quot;; // NOI18N;
-	static final String COLUMN_NAME_BRANCH = &quot;branch&quot;; // NOI18N;
-	private String htmlDisplayName;
-	private RequestProcessor.Task repoload;
-	private final VersioningPanel panel;
-
-	public SyncFileNode(GitFileNode node, VersioningPanel _panel)
-	{
-		this(Children.LEAF, node, _panel);
-	}
-
-	private SyncFileNode(Children children, GitFileNode node, VersioningPanel _panel)
-	{
-		super(children, Lookups.fixed(node.getLookupObjects()));
-		this.node = node;
-		this.panel = _panel;
-		initProperties();
-		refreshHtmlDisplayName();
-	}
-
-	public File getFile()
-	{
-		return node.getFile();
-	}
-
-	public StatusInfo getFileInformation()
-	{
-		return node.getInformation();
-	}
-
-	@Override
-	public String getName()
-	{
-		return node.getName();
-	}
-
-	@Override
-	public Action getPreferredAction()
-	{
-		// TODO: getPreferedAction
-		if (node.getInformation().getStatus() == StatusInfo.STATUS_VERSIONED_CONFLICT)
-			return null;
-		return new DiffAction(null, GitUtils.getCurrentContext(null));
-	}
-
-	/**
-	 * Provide cookies to actions.
-	 * If a node represents primary file of a DataObject
-	 * it has respective DataObject cookies.
-	 */
-	@SuppressWarnings(&quot;unchecked&quot;) // Adding getCookie(Class&lt;Cookie&gt; klass) results in name clash
-	@Override
-	public Cookie getCookie(Class klass)
-	{
-		FileObject fo = FileUtil.toFileObject(getFile());
-		if (fo != null)
-			try {
-				DataObject dobj = DataObject.find(fo);
-				if (fo.equals(dobj.getPrimaryFile()))
-					return dobj.getCookie(klass);
-			} catch (DataObjectNotFoundException e) {
-				// ignore file without data objects
-			}
-		return super.getCookie(klass);
-	}
-
-	private void initProperties()
-	{
-		if (node.getFile().isDirectory())
-			setIconBaseWithExtension(&quot;org/openide/loaders/defaultFolder.gif&quot;); // NOI18N
-
-		Sheet sheet = Sheet.createDefault();
-		Sheet.Set ps = Sheet.createPropertiesSet();
-
-		ps.put(new NameProperty());
-		ps.put(new PathProperty());
-		ps.put(new StatusProperty());
-		ps.put(new BranchProperty());
-
-		sheet.put(ps);
-		setSheet(sheet);
-	}
-
-	private void refreshHtmlDisplayName()
-	{
-		StatusInfo info = node.getInformation();
-		int status = info.getStatus();
-		// Special treatment: Mergeable status should be annotated as Conflict in Versioning view according to UI spec
-		if (status == StatusInfo.STATUS_VERSIONED_MERGE)
-			status = StatusInfo.STATUS_VERSIONED_CONFLICT;
-		htmlDisplayName = HtmlFormatter.getInstance().annotateNameHtml(node.getFile().getName(), info, null);
-		fireDisplayNameChange(node.getName(), node.getName());
-	}
-
-	@Override
-	public String getHtmlDisplayName()
-	{
-		return htmlDisplayName;
-	}
-
-	public void refresh()
-	{
-		refreshHtmlDisplayName();
-	}
-
-	private abstract class SyncFileProperty extends org.openide.nodes.PropertySupport.ReadOnly {
-
-		@SuppressWarnings(&quot;unchecked&quot;)
-		protected SyncFileProperty(String name, Class type, String displayName, String shortDescription)
-		{
-			super(name, type, displayName, shortDescription);
-		}
-
-		@Override
-		public String toString()
-		{
-			try {
-				return getValue().toString();
-			} catch (Exception e) {
-				Git.LOG.log(Level.INFO, null, e);
-				return e.getLocalizedMessage();
-			}
-		}
-
-	}
-
-	private class BranchProperty extends SyncFileProperty {
-
-		public BranchProperty()
-		{
-			super(COLUMN_NAME_BRANCH, String.class, NbBundle.getMessage(SyncFileNode.class, &quot;BK2001&quot;), NbBundle.getMessage(SyncFileNode.class, &quot;BK2002&quot;)); // NOI18N
-		}
-
-		public Object getValue()
-		{
-			String branchInfo = panel.getDisplayBranchInfo();
-			return branchInfo == null ? &quot;&quot; : branchInfo; // NOI18N
-		}
-
-	}
-
-	private class PathProperty extends SyncFileProperty {
-
-		private String shortPath;
-
-		public PathProperty()
-		{
-			super(COLUMN_NAME_PATH, String.class, NbBundle.getMessage(SyncFileNode.class, &quot;BK2003&quot;), NbBundle.getMessage(SyncFileNode.class, &quot;BK2004&quot;)); // NOI18N
-			shortPath = GitUtils.getRelativePath(node.getFile());
-			setValue(&quot;sortkey&quot;, shortPath + &quot;\t&quot; + SyncFileNode.this.getName()); // NOI18N
-		}
-
-		public Object getValue() throws IllegalAccessException, InvocationTargetException
-		{
-			return shortPath;
-		}
-
-	}
-
-	// XXX it's not probably called, are there another Node lifecycle events
-	@Override
-	public void destroy() throws IOException
-	{
-		super.destroy();
-		if (repoload != null)
-			repoload.cancel();
-	}
-
-	private class NameProperty extends SyncFileProperty {
-
-		public NameProperty()
-		{
-			super(COLUMN_NAME_NAME, String.class, NbBundle.getMessage(SyncFileNode.class, &quot;BK2005&quot;), NbBundle.getMessage(SyncFileNode.class, &quot;BK2006&quot;)); // NOI18N
-			setValue(&quot;sortkey&quot;, SyncFileNode.this.getName()); // NOI18N
-		}
-
-		public Object getValue() throws IllegalAccessException, InvocationTargetException
-		{
-			return SyncFileNode.this.getDisplayName();
-		}
-
-	}
-
-	private static final String[] zeros = new String[]{&quot;&quot;, &quot;00&quot;, &quot;0&quot;, &quot;&quot;}; // NOI18N
-
-	private class StatusProperty extends SyncFileProperty {
-
-		public StatusProperty()
-		{
-			super(COLUMN_NAME_STATUS, String.class, NbBundle.getMessage(SyncFileNode.class, &quot;BK2007&quot;), NbBundle.getMessage(SyncFileNode.class, &quot;BK2008&quot;)); // NOI18N
-			String shortPath = GitUtils.getRelativePath(node.getFile()); // NOI18N
-			String sortable = Integer.toString(GitUtils.getComparableStatus(node.getInformation().getStatus()));
-			setValue(&quot;sortkey&quot;, zeros[sortable.length()] + sortable + &quot;\t&quot; + shortPath + &quot;\t&quot; + SyncFileNode.this.getName()); // NOI18N
-		}
-
-		public Object getValue() throws IllegalAccessException, InvocationTargetException
-		{
-			StatusInfo finfo = node.getInformation();
-			//TODO: finfo.getEntry(node.getFile());  // XXX not interested in return value, side effect loads ISVNStatus structure
-			int mask = panel.getDisplayStatuses();
-			return finfo.getStatusText(mask);
-		}
-
-	}
+    private GitFileNode node;
+    static final String COLUMN_NAME_NAME = &quot;name&quot;; // NOI18N;
+    static final String COLUMN_NAME_PATH = &quot;path&quot;; // NOI18N;
+    static final String COLUMN_NAME_STATUS = &quot;status&quot;; // NOI18N;
+    static final String COLUMN_NAME_BRANCH = &quot;branch&quot;; // NOI18N;
+    private String htmlDisplayName;
+    private RequestProcessor.Task repoload;
+    private final VersioningPanel panel;
+
+    public SyncFileNode(GitFileNode node, VersioningPanel _panel)
+    {
+        this(Children.LEAF, node, _panel);
+    }
+
+    private SyncFileNode(Children children, GitFileNode node, VersioningPanel _panel)
+    {
+        super(children, Lookups.fixed(node.getLookupObjects()));
+        this.node = node;
+        this.panel = _panel;
+        initProperties();
+        refreshHtmlDisplayName();
+    }
+
+    public File getFile()
+    {
+        return node.getFile();
+    }
+
+    public StatusInfo getFileInformation()
+    {
+        return node.getInformation();
+    }
+
+    @Override
+    public String getName()
+    {
+        return node.getName();
+    }
+
+    @Override
+    public Action getPreferredAction()
+    {
+        // TODO: getPreferedAction
+        if (node.getInformation().getStatus() == StatusInfo.STATUS_VERSIONED_CONFLICT)
+            return null;
+        return new DiffAction(null, GitUtils.getCurrentContext(null));
+    }
+
+    /**
+     * Provide cookies to actions.
+     * If a node represents primary file of a DataObject
+     * it has respective DataObject cookies.
+     */
+    @SuppressWarnings(&quot;unchecked&quot;) // Adding getCookie(Class&lt;Cookie&gt; klass) results in name clash
+    @Override
+    public Cookie getCookie(Class klass)
+    {
+        FileObject fo = FileUtil.toFileObject(getFile());
+        if (fo != null)
+            try {
+                DataObject dobj = DataObject.find(fo);
+                if (fo.equals(dobj.getPrimaryFile()))
+                    return dobj.getCookie(klass);
+            } catch (DataObjectNotFoundException e) {
+                // ignore file without data objects
+            }
+        return super.getCookie(klass);
+    }
+
+    private void initProperties()
+    {
+        if (node.getFile().isDirectory())
+            setIconBaseWithExtension(&quot;org/openide/loaders/defaultFolder.gif&quot;); // NOI18N
+
+        Sheet sheet = Sheet.createDefault();
+        Sheet.Set ps = Sheet.createPropertiesSet();
+
+        ps.put(new NameProperty());
+        ps.put(new PathProperty());
+        ps.put(new StatusProperty());
+        ps.put(new BranchProperty());
+
+        sheet.put(ps);
+        setSheet(sheet);
+    }
+
+    private void refreshHtmlDisplayName()
+    {
+        StatusInfo info = node.getInformation();
+        int status = info.getStatus();
+        // Special treatment: Mergeable status should be annotated as Conflict in Versioning view according to UI spec
+        if (status == StatusInfo.STATUS_VERSIONED_MERGE)
+            status = StatusInfo.STATUS_VERSIONED_CONFLICT;
+        htmlDisplayName = HtmlFormatter.getInstance().annotateNameHtml(node.getFile().getName(), info, null);
+        fireDisplayNameChange(node.getName(), node.getName());
+    }
+
+    @Override
+    public String getHtmlDisplayName()
+    {
+        return htmlDisplayName;
+    }
+
+    public void refresh()
+    {
+        refreshHtmlDisplayName();
+    }
+
+    private abstract class SyncFileProperty extends org.openide.nodes.PropertySupport.ReadOnly {
+
+        @SuppressWarnings(&quot;unchecked&quot;)
+        protected SyncFileProperty(String name, Class type, String displayName, String shortDescription)
+        {
+            super(name, type, displayName, shortDescription);
+        }
+
+        @Override
+        public String toString()
+        {
+            try {
+                return getValue().toString();
+            } catch (Exception e) {
+                Git.LOG.log(Level.INFO, null, e);
+                return e.getLocalizedMessage();
+            }
+        }
+
+    }
+
+    private class BranchProperty extends SyncFileProperty {
+
+        public BranchProperty()
+        {
+            super(COLUMN_NAME_BRANCH, String.class, NbBundle.getMessage(SyncFileNode.class, &quot;BK2001&quot;), NbBundle.getMessage(SyncFileNode.class, &quot;BK2002&quot;)); // NOI18N
+        }
+
+        public Object getValue()
+        {
+            String branchInfo = panel.getDisplayBranchInfo();
+            return branchInfo == null ? &quot;&quot; : branchInfo; // NOI18N
+        }
+
+    }
+
+    private class PathProperty extends SyncFileProperty {
+
+        private String shortPath;
+
+        public PathProperty()
+        {
+            super(COLUMN_NAME_PATH, String.class, NbBundle.getMessage(SyncFileNode.class, &quot;BK2003&quot;), NbBundle.getMessage(SyncFileNode.class, &quot;BK2004&quot;)); // NOI18N
+            shortPath = GitUtils.getRelativePath(node.getFile());
+            setValue(&quot;sortkey&quot;, shortPath + &quot;\t&quot; + SyncFileNode.this.getName()); // NOI18N
+        }
+
+        public Object getValue() throws IllegalAccessException, InvocationTargetException
+        {
+            return shortPath;
+        }
+
+    }
+
+    // XXX it's not probably called, are there another Node lifecycle events
+    @Override
+    public void destroy() throws IOException
+    {
+        super.destroy();
+        if (repoload != null)
+            repoload.cancel();
+    }
+
+    private class NameProperty extends SyncFileProperty {
+
+        public NameProperty()
+        {
+            super(COLUMN_NAME_NAME, String.class, NbBundle.getMessage(SyncFileNode.class, &quot;BK2005&quot;), NbBundle.getMessage(SyncFileNode.class, &quot;BK2006&quot;)); // NOI18N
+            setValue(&quot;sortkey&quot;, SyncFileNode.this.getName()); // NOI18N
+        }
+
+        public Object getValue() throws IllegalAccessException, InvocationTargetException
+        {
+            return SyncFileNode.this.getDisplayName();
+        }
+
+    }
+
+    private static final String[] zeros = new String[]{&quot;&quot;, &quot;00&quot;, &quot;0&quot;, &quot;&quot;}; // NOI18N
+
+    private class StatusProperty extends SyncFileProperty {
+
+        public StatusProperty()
+        {
+            super(COLUMN_NAME_STATUS, String.class, NbBundle.getMessage(SyncFileNode.class, &quot;BK2007&quot;), NbBundle.getMessage(SyncFileNode.class, &quot;BK2008&quot;)); // NOI18N
+            String shortPath = GitUtils.getRelativePath(node.getFile()); // NOI18N
+            String sortable = Integer.toString(GitUtils.getComparableStatus(node.getInformation().getStatus()));
+            setValue(&quot;sortkey&quot;, zeros[sortable.length()] + sortable + &quot;\t&quot; + shortPath + &quot;\t&quot; + SyncFileNode.this.getName()); // NOI18N
+        }
+
+        public Object getValue() throws IllegalAccessException, InvocationTargetException
+        {
+            StatusInfo finfo = node.getInformation();
+            //TODO: finfo.getEntry(node.getFile());  // XXX not interested in return value, side effect loads ISVNStatus structure
+            int mask = panel.getDisplayStatuses();
+            return finfo.getStatusText(mask);
+        }
+
+    }
 
 }
\ No newline at end of file</diff>
      <filename>src/org/nbgit/ui/status/SyncFileNode.java</filename>
    </modified>
    <modified>
      <diff>@@ -63,456 +63,456 @@ import org.openide.windows.TopComponent;
  * Controls the {@link #getComponent() table} that displays nodes
  * in the Versioning view. The table is  {@link #setTableModel populated)
  * from VersioningPanel.
- * 
+ *
  * @author Maros Sandor
  */
 class SyncTable implements MouseListener, ListSelectionListener, AncestorListener {
 
-	private NodeTableModel tableModel;
-	private JTable table;
-	private JScrollPane component;
-	private SyncFileNode[] nodes = new SyncFileNode[0];
-	private String[] tableColumns;
-	private TableSorter sorter;
-	/**
-	 * Defines labels for Versioning view table columns.
-	 */
-	private static final Map&lt;String, String[]&gt; columnLabels = new HashMap&lt;String, String[]&gt;(4);
-	
-
-	{
-		ResourceBundle loc = NbBundle.getBundle(SyncTable.class);
-		columnLabels.put(SyncFileNode.COLUMN_NAME_BRANCH, new String[]{
-				loc.getString(&quot;CTL_VersioningView_Column_Branch_Title&quot;), // NOI18N
-				loc.getString(&quot;CTL_VersioningView_Column_Branch_Desc&quot;)
-			}); // NOI18N
-		columnLabels.put(SyncFileNode.COLUMN_NAME_NAME, new String[]{
-				loc.getString(&quot;CTL_VersioningView_Column_File_Title&quot;), // NOI18N
-				loc.getString(&quot;CTL_VersioningView_Column_File_Desc&quot;)
-			}); // NOI18N
-		columnLabels.put(SyncFileNode.COLUMN_NAME_STATUS, new String[]{
-				loc.getString(&quot;CTL_VersioningView_Column_Status_Title&quot;), // NOI18N
-				loc.getString(&quot;CTL_VersioningView_Column_Status_Desc&quot;)
-			}); // NOI18N
-		columnLabels.put(SyncFileNode.COLUMN_NAME_PATH, new String[]{
-				loc.getString(&quot;CTL_VersioningView_Column_Path_Title&quot;), // NOI18N
-				loc.getString(&quot;CTL_VersioningView_Column_Path_Desc&quot;)
-			}); // NOI18N
-	}
-
-	private static final Comparator NodeComparator = new Comparator() {
-
-		public int compare(Object o1, Object o2)
-		{
-			Node.Property p1 = (Node.Property) o1;
-			Node.Property p2 = (Node.Property) o2;
-			String sk1 = (String) p1.getValue(&quot;sortkey&quot;); // NOI18N
-			if (sk1 != null) {
-				String sk2 = (String) p2.getValue(&quot;sortkey&quot;); // NOI18N
-				return sk1.compareToIgnoreCase(sk2);
-			} else
-				try {
-					String s1 = (String) p1.getValue();
-					String s2 = (String) p2.getValue();
-					return s1.compareToIgnoreCase(s2);
-				} catch (Exception e) {
-					Git.LOG.log(Level.INFO, null, e);
-					return 0;
-				}
-		}
-
-	};
-
-	public SyncTable()
-	{
-		tableModel = new NodeTableModel();
-		sorter = new TableSorter(tableModel);
-		sorter.setColumnComparator(Node.Property.class, NodeComparator);
-		table = new JTable(sorter);
-		sorter.setTableHeader(table.getTableHeader());
-		table.setRowHeight(table.getRowHeight() * 6 / 5);
-		component = new JScrollPane(table, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
-		component.getViewport().setBackground(table.getBackground());
-		Color borderColor = UIManager.getColor(&quot;scrollpane_border&quot;); // NOI18N
-		if (borderColor == null)
-			borderColor = UIManager.getColor(&quot;controlShadow&quot;); // NOI18N
-		component.setBorder(BorderFactory.createMatteBorder(1, 0, 0, 0, borderColor));
-		table.addMouseListener(this);
-		table.setDefaultRenderer(Node.Property.class, new SyncTableCellRenderer());
-		table.getSelectionModel().addListSelectionListener(this);
-		table.addAncestorListener(this);
-		table.getAccessibleContext().setAccessibleName(NbBundle.getMessage(SyncTable.class, &quot;ACSN_VersioningTable&quot;)); // NOI18N
-		table.getAccessibleContext().setAccessibleDescription(NbBundle.getMessage(SyncTable.class, &quot;ACSD_VersioningTable&quot;)); // NOI18N
-		setColumns(new String[]{
-				SyncFileNode.COLUMN_NAME_NAME,
-				SyncFileNode.COLUMN_NAME_STATUS,
-				SyncFileNode.COLUMN_NAME_PATH
-			});
-		table.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(
-			KeyStroke.getKeyStroke(KeyEvent.VK_F10, KeyEvent.SHIFT_DOWN_MASK), &quot;org.openide.actions.PopupAction&quot;); // NOI18N
-		table.getActionMap().put(&quot;org.openide.actions.PopupAction&quot;, new AbstractAction() { // NOI18N
-
-			public void actionPerformed(ActionEvent e)
-			{
-				showPopup(org.netbeans.modules.versioning.util.Utils.getPositionForPopup(table));
-			}
-
-		});
-	}
-
-	void setDefaultColumnSizes()
-	{
-		SwingUtilities.invokeLater(new Runnable() {
-
-			public void run()
-			{
-				int width = table.getWidth();
-				if (tableColumns.length == 3)
-					for (int i = 0; i &lt; tableColumns.length; i++) {
-						if (SyncFileNode.COLUMN_NAME_PATH.equals(tableColumns[i]))
-							table.getColumnModel().getColumn(i).setPreferredWidth(width * 60 / 100);
-						else
-							table.getColumnModel().getColumn(i).setPreferredWidth(width * 20 / 100);
-					}
-				else if (tableColumns.length == 4)
-					for (int i = 0; i &lt; tableColumns.length; i++) {
-						if (SyncFileNode.COLUMN_NAME_PATH.equals(tableColumns[i]))
-							table.getColumnModel().getColumn(i).setPreferredWidth(width * 55 / 100);
-						else if (SyncFileNode.COLUMN_NAME_BRANCH.equals(tableColumns[i]))
-							table.getColumnModel().getColumn(i).setPreferredWidth(width * 20 / 100);
-						else
-							table.getColumnModel().getColumn(i).setPreferredWidth(width * 15 / 100);
-					}
-			}
-
-		});
-	}
-
-	public void ancestorAdded(AncestorEvent event)
-	{
-		setDefaultColumnSizes();
-	}
-
-	public void ancestorMoved(AncestorEvent event)
-	{
-	}
-
-	public void ancestorRemoved(AncestorEvent event)
-	{
-	}
-
-	public SyncFileNode[] getDisplayedNodes()
-	{
-		int n = sorter.getRowCount();
-		SyncFileNode[] ret = new SyncFileNode[n];
-		for (int i = 0; i &lt; n; i++) {
-			ret[i] = nodes[sorter.modelIndex(i)];
-		}
-		return ret;
-	}
-
-	public JComponent getComponent()
-	{
-		return component;
-	}
-
-	/**
-	 * Sets visible columns in the Versioning table.
-	 * 
-	 * @param columns array of column names, they must be one of SyncFileNode.COLUMN_NAME_XXXXX constants.  
-	 */
-	final void setColumns(String[] columns)
-	{
-		if (Arrays.equals(columns, tableColumns))
-			return;
-		setModelProperties(columns);
-		tableColumns = columns;
-		for (int i = 0; i &lt; tableColumns.length; i++) {
-			sorter.setColumnComparator(i, null);
-			sorter.setSortingStatus(i, TableSorter.NOT_SORTED);
-			if (SyncFileNode.COLUMN_NAME_STATUS.equals(tableColumns[i])) {
-				sorter.setSortingStatus(i, TableSorter.ASCENDING);
-				break;
-			}
-		}
-		setDefaultColumnSizes();
-	}
-
-	private void setModelProperties(String[] columns)
-	{
-		Node.Property[] properties = new Node.Property[columns.length];
-		for (int i = 0; i &lt; columns.length; i++) {
-			String column = columns[i];
-			String[] labels = columnLabels.get(column);
-			properties[i] = new ColumnDescriptor(column, String.class, labels[0], labels[1]);
-		}
-		tableModel.setProperties(properties);
-	}
-
-	void setTableModel(SyncFileNode[] nodes)
-	{
-		this.nodes = nodes;
-		tableModel.setNodes(nodes);
-	}
-
-	void focus()
-	{
-		table.requestFocus();
-	}
-
-	private static class ColumnDescriptor extends ReadOnly {
-
-		@SuppressWarnings(&quot;unchecked&quot;)
-		public ColumnDescriptor(String name, Class type, String displayName, String shortDescription)
-		{
-			super(name, type, displayName, shortDescription);
-		}
-
-		public Object getValue() throws IllegalAccessException, InvocationTargetException
-		{
-			return null;
-		}
-
-	}
-
-	private void showPopup(final MouseEvent e)
-	{
-		int row = table.rowAtPoint(e.getPoint());
-		if (row != -1) {
-			boolean makeRowSelected = true;
-			int[] selectedrows = table.getSelectedRows();
-
-			for (int i = 0; i &lt; selectedrows.length; i++) {
-				if (row == selectedrows[i]) {
-					makeRowSelected = false;
-					break;
-				}
-			}
-			if (makeRowSelected)
-				table.getSelectionModel().setSelectionInterval(row, row);
-		}
-		SwingUtilities.invokeLater(new Runnable() {
-
-			public void run()
-			{
-				// invoke later so the selection on the table will be set first
-				JPopupMenu menu = getPopup();
-				menu.show(table, e.getX(), e.getY());
-			}
-
-		});
-	}
-
-	private void showPopup(Point p)
-	{
-		JPopupMenu menu = getPopup();
-		menu.show(table, p.x, p.y);
-	}
-
-	/**
-	 * Constructs contextual Menu: File Node
-	&lt;pre&gt;
-	Open
-	-------------------
-	Diff                 (default action)
-	Update
-	Commit...        
-	--------------------
-	Conflict Resolved    (on conflicting file)
-	--------------------
-	Blame
-	Show History...
-	--------------------        
-	Revert Modifications  (Revert Delete)(Delete)
-	Exclude from Commit   (Include in Commit)
-	Ignore                (Unignore)
-	&lt;/pre&gt;
-	 */
-	private JPopupMenu getPopup()
-	{
-
-		JPopupMenu menu = new JPopupMenu();
-		JMenuItem item;
-		VCSContext context = GitUtils.getCurrentContext(null);
-		ResourceBundle loc = NbBundle.getBundle(Git.class);
-
-		item = menu.add(new OpenInEditorAction());
-		Mnemonics.setLocalizedText(item, item.getText());
-		menu.add(new JSeparator());
-		item = menu.add(new DiffAction(loc.getString(&quot;CTL_PopupMenuItem_Diff&quot;), context)); // NOI18N
-		Mnemonics.setLocalizedText(item, item.getText());
-		item = menu.add(new CommitAction(loc.getString(&quot;CTL_PopupMenuItem_Commit&quot;), context)); // NOI18N
-		Mnemonics.setLocalizedText(item, item.getText());
-
-		/*
-		menu.add(new JSeparator());
-
-		item = menu.add(new ConflictResolvedAction(loc.getString(&quot;CTL_PopupMenuItem_MarkResolved&quot;), context)); // NOI18N
-		Mnemonics.setLocalizedText(item, item.getText());
-		menu.add(new JSeparator());
-		*/
-
-		/*
-		AnnotateAction tempA = new AnnotateAction(loc.getString(&quot;CTL_PopupMenuItem_ShowAnnotations&quot;), context); // NOI18N
-		if (tempA.visible(null)) {
-		tempA = new AnnotateAction(loc.getString(&quot;CTL_PopupMenuItem_HideAnnotations&quot;), context); // NOI18N
-		}
-		item = menu.add(tempA);
-		Mnemonics.setLocalizedText(item, item.getText());
-		 */
-		menu.add(new JSeparator());
-
-		boolean allLocallyDeleted = true;
-		StatusCache cache = Git.getInstance().getStatusCache();
-		Set&lt;File&gt; files = GitUtils.getCurrentContext(null).getRootFiles();
-
-		for (File file : files) {
-			StatusInfo info = cache.getStatus(file);
-			if (info.getStatus() != StatusInfo.STATUS_VERSIONED_DELETEDLOCALLY &amp;&amp; info.getStatus() != StatusInfo.STATUS_VERSIONED_REMOVEDLOCALLY)
-				allLocallyDeleted = false;
-		}
-		if (allLocallyDeleted)
-			item = menu.add(new RevertModificationsAction(loc.getString(&quot;CTL_PopupMenuItem_RevertDelete&quot;), context));
-		else
-			item = menu.add(new RevertModificationsAction(loc.getString(&quot;CTL_PopupMenuItem_GetClean&quot;), context));
-		Mnemonics.setLocalizedText(item, item.getText());
-
-		ExcludeFromCommitAction exclude = new ExcludeFromCommitAction(loc.getString(&quot;CTL_PopupMenuItem_IncludeInCommit&quot;), context); // NOI18N
-		if (exclude.getActionStatus(null) != ExcludeFromCommitAction.INCLUDING)
-			exclude = new ExcludeFromCommitAction(loc.getString(&quot;CTL_PopupMenuItem_ExcludeFromCommit&quot;), context); // NOI18N
-		item = menu.add(exclude);
-		Mnemonics.setLocalizedText(item, item.getText());
-
-		/*
-		item = menu.add(new SystemActionBridge(SystemAction.get(SearchHistoryAction.class), actionString(&quot;CTL_PopupMenuItem_SearchHistory&quot;))); // NOI18N
-		Mnemonics.setLocalizedText(item, item.getText());
-		
-		menu.add(new JSeparator());                
-		
-		//        item = menu.add(new SystemActionBridge(SystemAction.get(ResolveConflictsAction.class), actionString(&quot;CTL_PopupMenuItem_ResolveConflicts&quot;))); // NOI18N
-		//        Mnemonics.setLocalizedText(item, item.getText());
-		/*		
-		Action ignoreAction = new SystemActionBridge(SystemAction.get(IgnoreAction.class),
-		((IgnoreAction)SystemAction.get(IgnoreAction.class)).getActionStatus(files) == IgnoreAction.UNIGNORING ?
-		actionString(&quot;CTL_PopupMenuItem_Unignore&quot;) : // NOI18N
-		actionString(&quot;CTL_PopupMenuItem_Ignore&quot;)); // NOI18N
-		item = menu.add(ignoreAction);
-		Mnemonics.setLocalizedText(item, item.getText());
-		 */
-
-		return menu;
-	}
-
-	/** 
-	 * Workaround.
-	 * I18N Test Wizard searches for keys in syncview package Bundle.properties 
-	 */
-	private String actionString(String key)
-	{
-		ResourceBundle actionsLoc = NbBundle.getBundle(GitAnnotator.class);
-		return actionsLoc.getString(key);
-	}
-
-	public void mouseEntered(MouseEvent e)
-	{
-	}
-
-	public void mouseExited(MouseEvent e)
-	{
-	}
-
-	public void mousePressed(MouseEvent e)
-	{
-		if (e.isPopupTrigger())
-			showPopup(e);
-	}
-
-	public void mouseReleased(MouseEvent e)
-	{
-		if (e.isPopupTrigger())
-			showPopup(e);
-	}
-
-	public void mouseClicked(MouseEvent e)
-	{
-		if (SwingUtilities.isLeftMouseButton(e) &amp;&amp; MouseUtils.isDoubleClick(e)) {
-			int row = table.rowAtPoint(e.getPoint());
-			if (row == -1)
-				return;
-			row = sorter.modelIndex(row);
-			Action action = nodes[row].getPreferredAction();
-			if (action == null || !action.isEnabled())
-				action = new OpenInEditorAction();
-			if (action.isEnabled())
-				action.actionPerformed(new ActionEvent(this, 0, &quot;&quot;));
-		}
-	}
-
-	public void valueChanged(ListSelectionEvent e)
-	{
-		List&lt;SyncFileNode&gt; selectedNodes = new ArrayList&lt;SyncFileNode&gt;();
-		ListSelectionModel selectionModel = table.getSelectionModel();
-		final TopComponent tc = (TopComponent) SwingUtilities.getAncestorOfClass(TopComponent.class, table);
-		if (tc == null)
-			return; // table is no longer in component hierarchy
-
-		int min = selectionModel.getMinSelectionIndex();
-		if (min != -1) {
-			int max = selectionModel.getMaxSelectionIndex();
-			for (int i = min; i &lt;= max; i++) {
-				if (selectionModel.isSelectedIndex(i)) {
-					int idx = sorter.modelIndex(i);
-					selectedNodes.add(nodes[idx]);
-				}
-			}
-		}
-		// this method may be called outside of AWT if a node fires change events from some other thread, see #79174
-		final Node[] nodes = selectedNodes.toArray(new Node[selectedNodes.size()]);
-		if (SwingUtilities.isEventDispatchThread())
-			tc.setActivatedNodes(nodes);
-		else
-			SwingUtilities.invokeLater(new Runnable() {
-
-				public void run()
-				{
-					tc.setActivatedNodes(nodes);
-				}
-
-			});
-	}
-
-	private class SyncTableCellRenderer extends DefaultTableCellRenderer {
-
-		private FilePathCellRenderer pathRenderer = new FilePathCellRenderer();
-
-		@Override
-		public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)
-		{
-			Component renderer;
-			int modelColumnIndex = table.convertColumnIndexToModel(column);
-			if (modelColumnIndex == 0) {
-				SyncFileNode node = nodes[sorter.modelIndex(row)];
-				if (!isSelected)
-					value = &quot;&lt;html&gt;&quot; + node.getHtmlDisplayName();
-				if (GitModuleConfig.getDefault().isExcludedFromCommit(node.getFile().getAbsolutePath())) {
-					String nodeName = node.getDisplayName();
-					if (isSelected)
-						value = &quot;&lt;html&gt;&lt;s&gt;&quot; + nodeName + &quot;&lt;/s&gt;&lt;/html&gt;&quot;;
-					else
-						value = &quot;&lt;html&gt;&lt;s&gt;&quot; + HtmlFormatter.getInstance().annotateNameHtml(nodeName, node.getFileInformation(), null) + &quot;&lt;/s&gt;&quot;;
-				}
-			}
-			if (modelColumnIndex == 2)
-				renderer = pathRenderer.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
-			else
-				renderer = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
-			if (renderer instanceof JComponent) {
-				String path = nodes[sorter.modelIndex(row)].getFile().getAbsolutePath();
-				((JComponent) renderer).setToolTipText(path);
-			}
-			return renderer;
-		}
-
-	}
+    private NodeTableModel tableModel;
+    private JTable table;
+    private JScrollPane component;
+    private SyncFileNode[] nodes = new SyncFileNode[0];
+    private String[] tableColumns;
+    private TableSorter sorter;
+    /**
+     * Defines labels for Versioning view table columns.
+     */
+    private static final Map&lt;String, String[]&gt; columnLabels = new HashMap&lt;String, String[]&gt;(4);
+
+
+    {
+        ResourceBundle loc = NbBundle.getBundle(SyncTable.class);
+        columnLabels.put(SyncFileNode.COLUMN_NAME_BRANCH, new String[]{
+                loc.getString(&quot;CTL_VersioningView_Column_Branch_Title&quot;), // NOI18N
+                loc.getString(&quot;CTL_VersioningView_Column_Branch_Desc&quot;)
+            }); // NOI18N
+        columnLabels.put(SyncFileNode.COLUMN_NAME_NAME, new String[]{
+                loc.getString(&quot;CTL_VersioningView_Column_File_Title&quot;), // NOI18N
+                loc.getString(&quot;CTL_VersioningView_Column_File_Desc&quot;)
+            }); // NOI18N
+        columnLabels.put(SyncFileNode.COLUMN_NAME_STATUS, new String[]{
+                loc.getString(&quot;CTL_VersioningView_Column_Status_Title&quot;), // NOI18N
+                loc.getString(&quot;CTL_VersioningView_Column_Status_Desc&quot;)
+            }); // NOI18N
+        columnLabels.put(SyncFileNode.COLUMN_NAME_PATH, new String[]{
+                loc.getString(&quot;CTL_VersioningView_Column_Path_Title&quot;), // NOI18N
+                loc.getString(&quot;CTL_VersioningView_Column_Path_Desc&quot;)
+            }); // NOI18N
+    }
+
+    private static final Comparator NodeComparator = new Comparator() {
+
+        public int compare(Object o1, Object o2)
+        {
+            Node.Property p1 = (Node.Property) o1;
+            Node.Property p2 = (Node.Property) o2;
+            String sk1 = (String) p1.getValue(&quot;sortkey&quot;); // NOI18N
+            if (sk1 != null) {
+                String sk2 = (String) p2.getValue(&quot;sortkey&quot;); // NOI18N
+                return sk1.compareToIgnoreCase(sk2);
+            } else
+                try {
+                    String s1 = (String) p1.getValue();
+                    String s2 = (String) p2.getValue();
+                    return s1.compareToIgnoreCase(s2);
+                } catch (Exception e) {
+                    Git.LOG.log(Level.INFO, null, e);
+                    return 0;
+                }
+        }
+
+    };
+
+    public SyncTable()
+    {
+        tableModel = new NodeTableModel();
+        sorter = new TableSorter(tableModel);
+        sorter.setColumnComparator(Node.Property.class, NodeComparator);
+        table = new JTable(sorter);
+        sorter.setTableHeader(table.getTableHeader());
+        table.setRowHeight(table.getRowHeight() * 6 / 5);
+        component = new JScrollPane(table, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
+        component.getViewport().setBackground(table.getBackground());
+        Color borderColor = UIManager.getColor(&quot;scrollpane_border&quot;); // NOI18N
+        if (borderColor == null)
+            borderColor = UIManager.getColor(&quot;controlShadow&quot;); // NOI18N
+        component.setBorder(BorderFactory.createMatteBorder(1, 0, 0, 0, borderColor));
+        table.addMouseListener(this);
+        table.setDefaultRenderer(Node.Property.class, new SyncTableCellRenderer());
+        table.getSelectionModel().addListSelectionListener(this);
+        table.addAncestorListener(this);
+        table.getAccessibleContext().setAccessibleName(NbBundle.getMessage(SyncTable.class, &quot;ACSN_VersioningTable&quot;)); // NOI18N
+        table.getAccessibleContext().setAccessibleDescription(NbBundle.getMessage(SyncTable.class, &quot;ACSD_VersioningTable&quot;)); // NOI18N
+        setColumns(new String[]{
+                SyncFileNode.COLUMN_NAME_NAME,
+                SyncFileNode.COLUMN_NAME_STATUS,
+                SyncFileNode.COLUMN_NAME_PATH
+            });
+        table.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(
+            KeyStroke.getKeyStroke(KeyEvent.VK_F10, KeyEvent.SHIFT_DOWN_MASK), &quot;org.openide.actions.PopupAction&quot;); // NOI18N
+        table.getActionMap().put(&quot;org.openide.actions.PopupAction&quot;, new AbstractAction() { // NOI18N
+
+            public void actionPerformed(ActionEvent e)
+            {
+                showPopup(org.netbeans.modules.versioning.util.Utils.getPositionForPopup(table));
+            }
+
+        });
+    }
+
+    void setDefaultColumnSizes()
+    {
+        SwingUtilities.invokeLater(new Runnable() {
+
+            public void run()
+            {
+                int width = table.getWidth();
+                if (tableColumns.length == 3)
+                    for (int i = 0; i &lt; tableColumns.length; i++) {
+                        if (SyncFileNode.COLUMN_NAME_PATH.equals(tableColumns[i]))
+                            table.getColumnModel().getColumn(i).setPreferredWidth(width * 60 / 100);
+                        else
+                            table.getColumnModel().getColumn(i).setPreferredWidth(width * 20 / 100);
+                    }
+                else if (tableColumns.length == 4)
+                    for (int i = 0; i &lt; tableColumns.length; i++) {
+                        if (SyncFileNode.COLUMN_NAME_PATH.equals(tableColumns[i]))
+                            table.getColumnModel().getColumn(i).setPreferredWidth(width * 55 / 100);
+                        else if (SyncFileNode.COLUMN_NAME_BRANCH.equals(tableColumns[i]))
+                            table.getColumnModel().getColumn(i).setPreferredWidth(width * 20 / 100);
+                        else
+                            table.getColumnModel().getColumn(i).setPreferredWidth(width * 15 / 100);
+                    }
+            }
+
+        });
+    }
+
+    public void ancestorAdded(AncestorEvent event)
+    {
+        setDefaultColumnSizes();
+    }
+
+    public void ancestorMoved(AncestorEvent event)
+    {
+    }
+
+    public void ancestorRemoved(AncestorEvent event)
+    {
+    }
+
+    public SyncFileNode[] getDisplayedNodes()
+    {
+        int n = sorter.getRowCount();
+        SyncFileNode[] ret = new SyncFileNode[n];
+        for (int i = 0; i &lt; n; i++) {
+            ret[i] = nodes[sorter.modelIndex(i)];
+        }
+        return ret;
+    }
+
+    public JComponent getComponent()
+    {
+        return component;
+    }
+
+    /**
+     * Sets visible columns in the Versioning table.
+     *
+     * @param columns array of column names, they must be one of SyncFileNode.COLUMN_NAME_XXXXX constants.
+     */
+    final void setColumns(String[] columns)
+    {
+        if (Arrays.equals(columns, tableColumns))
+            return;
+        setModelProperties(columns);
+        tableColumns = columns;
+        for (int i = 0; i &lt; tableColumns.length; i++) {
+            sorter.setColumnComparator(i, null);
+            sorter.setSortingStatus(i, TableSorter.NOT_SORTED);
+            if (SyncFileNode.COLUMN_NAME_STATUS.equals(tableColumns[i])) {
+                sorter.setSortingStatus(i, TableSorter.ASCENDING);
+                break;
+            }
+        }
+        setDefaultColumnSizes();
+    }
+
+    private void setModelProperties(String[] columns)
+    {
+        Node.Property[] properties = new Node.Property[columns.length];
+        for (int i = 0; i &lt; columns.length; i++) {
+            String column = columns[i];
+            String[] labels = columnLabels.get(column);
+            properties[i] = new ColumnDescriptor(column, String.class, labels[0], labels[1]);
+        }
+        tableModel.setProperties(properties);
+    }
+
+    void setTableModel(SyncFileNode[] nodes)
+    {
+        this.nodes = nodes;
+        tableModel.setNodes(nodes);
+    }
+
+    void focus()
+    {
+        table.requestFocus();
+    }
+
+    private static class ColumnDescriptor extends ReadOnly {
+
+        @SuppressWarnings(&quot;unchecked&quot;)
+        public ColumnDescriptor(String name, Class type, String displayName, String shortDescription)
+        {
+            super(name, type, displayName, shortDescription);
+        }
+
+        public Object getValue() throws IllegalAccessException, InvocationTargetException
+        {
+            return null;
+        }
+
+    }
+
+    private void showPopup(final MouseEvent e)
+    {
+        int row = table.rowAtPoint(e.getPoint());
+        if (row != -1) {
+            boolean makeRowSelected = true;
+            int[] selectedrows = table.getSelectedRows();
+
+            for (int i = 0; i &lt; selectedrows.length; i++) {
+                if (row == selectedrows[i]) {
+                    makeRowSelected = false;
+                    break;
+                }
+            }
+            if (makeRowSelected)
+                table.getSelectionModel().setSelectionInterval(row, row);
+        }
+        SwingUtilities.invokeLater(new Runnable() {
+
+            public void run()
+            {
+                // invoke later so the selection on the table will be set first
+                JPopupMenu menu = getPopup();
+                menu.show(table, e.getX(), e.getY());
+            }
+
+        });
+    }
+
+    private void showPopup(Point p)
+    {
+        JPopupMenu menu = getPopup();
+        menu.show(table, p.x, p.y);
+    }
+
+    /**
+     * Constructs contextual Menu: File Node
+    &lt;pre&gt;
+    Open
+    -------------------
+    Diff                 (default action)
+    Update
+    Commit...
+    --------------------
+    Conflict Resolved    (on conflicting file)
+    --------------------
+    Blame
+    Show History...
+    --------------------
+    Revert Modifications  (Revert Delete)(Delete)
+    Exclude from Commit   (Include in Commit)
+    Ignore                (Unignore)
+    &lt;/pre&gt;
+     */
+    private JPopupMenu getPopup()
+    {
+
+        JPopupMenu menu = new JPopupMenu();
+        JMenuItem item;
+        VCSContext context = GitUtils.getCurrentContext(null);
+        ResourceBundle loc = NbBundle.getBundle(Git.class);
+
+        item = menu.add(new OpenInEditorAction());
+        Mnemonics.setLocalizedText(item, item.getText());
+        menu.add(new JSeparator());
+        item = menu.add(new DiffAction(loc.getString(&quot;CTL_PopupMenuItem_Diff&quot;), context)); // NOI18N
+        Mnemonics.setLocalizedText(item, item.getText());
+        item = menu.add(new CommitAction(loc.getString(&quot;CTL_PopupMenuItem_Commit&quot;), context)); // NOI18N
+        Mnemonics.setLocalizedText(item, item.getText());
+
+        /*
+        menu.add(new JSeparator());
+
+        item = menu.add(new ConflictResolvedAction(loc.getString(&quot;CTL_PopupMenuItem_MarkResolved&quot;), context)); // NOI18N
+        Mnemonics.setLocalizedText(item, item.getText());
+        menu.add(new JSeparator());
+        */
+
+        /*
+        AnnotateAction tempA = new AnnotateAction(loc.getString(&quot;CTL_PopupMenuItem_ShowAnnotations&quot;), context); // NOI18N
+        if (tempA.visible(null)) {
+        tempA = new AnnotateAction(loc.getString(&quot;CTL_PopupMenuItem_HideAnnotations&quot;), context); // NOI18N
+        }
+        item = menu.add(tempA);
+        Mnemonics.setLocalizedText(item, item.getText());
+         */
+        menu.add(new JSeparator());
+
+        boolean allLocallyDeleted = true;
+        StatusCache cache = Git.getInstance().getStatusCache();
+        Set&lt;File&gt; files = GitUtils.getCurrentContext(null).getRootFiles();
+
+        for (File file : files) {
+            StatusInfo info = cache.getStatus(file);
+            if (info.getStatus() != StatusInfo.STATUS_VERSIONED_DELETEDLOCALLY &amp;&amp; info.getStatus() != StatusInfo.STATUS_VERSIONED_REMOVEDLOCALLY)
+                allLocallyDeleted = false;
+        }
+        if (allLocallyDeleted)
+            item = menu.add(new RevertModificationsAction(loc.getString(&quot;CTL_PopupMenuItem_RevertDelete&quot;), context));
+        else
+            item = menu.add(new RevertModificationsAction(loc.getString(&quot;CTL_PopupMenuItem_GetClean&quot;), context));
+        Mnemonics.setLocalizedText(item, item.getText());
+
+        ExcludeFromCommitAction exclude = new ExcludeFromCommitAction(loc.getString(&quot;CTL_PopupMenuItem_IncludeInCommit&quot;), context); // NOI18N
+        if (exclude.getActionStatus(null) != ExcludeFromCommitAction.INCLUDING)
+            exclude = new ExcludeFromCommitAction(loc.getString(&quot;CTL_PopupMenuItem_ExcludeFromCommit&quot;), context); // NOI18N
+        item = menu.add(exclude);
+        Mnemonics.setLocalizedText(item, item.getText());
+
+        /*
+        item = menu.add(new SystemActionBridge(SystemAction.get(SearchHistoryAction.class), actionString(&quot;CTL_PopupMenuItem_SearchHistory&quot;))); // NOI18N
+        Mnemonics.setLocalizedText(item, item.getText());
+
+        menu.add(new JSeparator());
+
+        //        item = menu.add(new SystemActionBridge(SystemAction.get(ResolveConflictsAction.class), actionString(&quot;CTL_PopupMenuItem_ResolveConflicts&quot;))); // NOI18N
+        //        Mnemonics.setLocalizedText(item, item.getText());
+        /*
+        Action ignoreAction = new SystemActionBridge(SystemAction.get(IgnoreAction.class),
+        ((IgnoreAction)SystemAction.get(IgnoreAction.class)).getActionStatus(files) == IgnoreAction.UNIGNORING ?
+        actionString(&quot;CTL_PopupMenuItem_Unignore&quot;) : // NOI18N
+        actionString(&quot;CTL_PopupMenuItem_Ignore&quot;)); // NOI18N
+        item = menu.add(ignoreAction);
+        Mnemonics.setLocalizedText(item, item.getText());
+         */
+
+        return menu;
+    }
+
+    /**
+     * Workaround.
+     * I18N Test Wizard searches for keys in syncview package Bundle.properties
+     */
+    private String actionString(String key)
+    {
+        ResourceBundle actionsLoc = NbBundle.getBundle(GitAnnotator.class);
+        return actionsLoc.getString(key);
+    }
+
+    public void mouseEntered(MouseEvent e)
+    {
+    }
+
+    public void mouseExited(MouseEvent e)
+    {
+    }
+
+    public void mousePressed(MouseEvent e)
+    {
+        if (e.isPopupTrigger())
+            showPopup(e);
+    }
+
+    public void mouseReleased(MouseEvent e)
+    {
+        if (e.isPopupTrigger())
+            showPopup(e);
+    }
+
+    public void mouseClicked(MouseEvent e)
+    {
+        if (SwingUtilities.isLeftMouseButton(e) &amp;&amp; MouseUtils.isDoubleClick(e)) {
+            int row = table.rowAtPoint(e.getPoint());
+            if (row == -1)
+                return;
+            row = sorter.modelIndex(row);
+            Action action = nodes[row].getPreferredAction();
+            if (action == null || !action.isEnabled())
+                action = new OpenInEditorAction();
+            if (action.isEnabled())
+                action.actionPerformed(new ActionEvent(this, 0, &quot;&quot;));
+        }
+    }
+
+    public void valueChanged(ListSelectionEvent e)
+    {
+        List&lt;SyncFileNode&gt; selectedNodes = new ArrayList&lt;SyncFileNode&gt;();
+        ListSelectionModel selectionModel = table.getSelectionModel();
+        final TopComponent tc = (TopComponent) SwingUtilities.getAncestorOfClass(TopComponent.class, table);
+        if (tc == null)
+            return; // table is no longer in component hierarchy
+
+        int min = selectionModel.getMinSelectionIndex();
+        if (min != -1) {
+            int max = selectionModel.getMaxSelectionIndex();
+            for (int i = min; i &lt;= max; i++) {
+                if (selectionModel.isSelectedIndex(i)) {
+                    int idx = sorter.modelIndex(i);
+                    selectedNodes.add(nodes[idx]);
+                }
+            }
+        }
+        // this method may be called outside of AWT if a node fires change events from some other thread, see #79174
+        final Node[] nodes = selectedNodes.toArray(new Node[selectedNodes.size()]);
+        if (SwingUtilities.isEventDispatchThread())
+            tc.setActivatedNodes(nodes);
+        else
+            SwingUtilities.invokeLater(new Runnable() {
+
+                public void run()
+                {
+                    tc.setActivatedNodes(nodes);
+                }
+
+            });
+    }
+
+    private class SyncTableCellRenderer extends DefaultTableCellRenderer {
+
+        private FilePathCellRenderer pathRenderer = new FilePathCellRenderer();
+
+        @Override
+        public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)
+        {
+            Component renderer;
+            int modelColumnIndex = table.convertColumnIndexToModel(column);
+            if (modelColumnIndex == 0) {
+                SyncFileNode node = nodes[sorter.modelIndex(row)];
+                if (!isSelected)
+                    value = &quot;&lt;html&gt;&quot; + node.getHtmlDisplayName();
+                if (GitModuleConfig.getDefault().isExcludedFromCommit(node.getFile().getAbsolutePath())) {
+                    String nodeName = node.getDisplayName();
+                    if (isSelected)
+                        value = &quot;&lt;html&gt;&lt;s&gt;&quot; + nodeName + &quot;&lt;/s&gt;&lt;/html&gt;&quot;;
+                    else
+                        value = &quot;&lt;html&gt;&lt;s&gt;&quot; + HtmlFormatter.getInstance().annotateNameHtml(nodeName, node.getFileInformation(), null) + &quot;&lt;/s&gt;&quot;;
+                }
+            }
+            if (modelColumnIndex == 2)
+                renderer = pathRenderer.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
+            else
+                renderer = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
+            if (renderer instanceof JComponent) {
+                String path = nodes[sorter.modelIndex(row)].getFile().getAbsolutePath();
+                ((JComponent) renderer).setToolTipText(path);
+            }
+            return renderer;
+        }
+
+    }
 
 }</diff>
      <filename>src/org/nbgit/ui/status/SyncTable.java</filename>
    </modified>
    <modified>
      <diff>@@ -65,643 +65,643 @@ import org.spearce.jgit.lib.Repository;
  */
 class VersioningPanel extends JPanel implements ExplorerManager.Provider, PreferenceChangeListener, PropertyChangeListener, ActionListener {
 
-	private ExplorerManager explorerManager;
-	private final GitVersioningTopComponent parentTopComponent;
-	private final Git git;
-	private VCSContext context;
-	private int displayStatuses;
-	private String branchInfo;
-	private SyncTable syncTable;
-	private RequestProcessor.Task refreshViewTask;
-	private Thread refreshViewThread;
-	private GitProgressSupport gitProgressSupport;
-	private static final RequestProcessor rp = new RequestProcessor(&quot;GitView&quot;, 1, true);  // NOI18N
-	private final NoContentPanel noContentComponent = new NoContentPanel();
-
-	/**
-	 * Creates a new Synchronize Panel managed by the given versioning system.
-	 *
-	 * @param parent enclosing top component
-	 */
-	public VersioningPanel(GitVersioningTopComponent parent)
-	{
-		this.parentTopComponent = parent;
-		this.git = Git.getInstance();
-		refreshViewTask = rp.create(new RefreshViewTask());
-		explorerManager = new ExplorerManager();
-		displayStatuses = StatusInfo.STATUS_LOCAL_CHANGE;
-		noContentComponent.setLabel(NbBundle.getMessage(VersioningPanel.class, &quot;MSG_No_Changes_All&quot;)); // NOI18N
-		syncTable = new SyncTable();
-
-		initComponents();
-		setVersioningComponent(syncTable.getComponent());
-		reScheduleRefresh(0);
-
-		// XXX click it in form editor, probbaly requires  Mattisse &gt;=v2
-		jPanel2.setFloatable(false);
-		jPanel2.putClientProperty(&quot;JToolBar.isRollover&quot;, Boolean.TRUE);  // NOI18N
-		jPanel2.setLayout(new ToolbarLayout());
-	}
-
-	public void preferenceChange(PreferenceChangeEvent evt)
-	{
-		if (evt.getKey().startsWith(GitModuleConfig.PROP_COMMIT_EXCLUSIONS))
-			repaint();
-	}
-
-	public void propertyChange(PropertyChangeEvent evt)
-	{
-		if (StatusCache.PROP_FILE_STATUS_CHANGED.equals(evt.getPropertyName())) {
-			StatusCache.ChangedEvent changedEvent = (StatusCache.ChangedEvent) evt.getNewValue();
-			Git.LOG.log(Level.FINE, &quot;Status.propertyChange(): {0} file:  {1}&quot;, new Object[]{parentTopComponent.getContentTitle(), changedEvent.getFile()}); // NOI18N
-			if (affectsView(evt))
-				reScheduleRefresh(1000);
-			return;
-		}
-		if (Git.PROP_CHANGESET_CHANGED.equals(evt.getPropertyName())) {
-			Object source = evt.getOldValue();
-			File root = GitUtils.getRootFile(context);
-			Git.LOG.log(Level.FINE, &quot;Git.changesetChanged: source {0} repo {1} &quot;, new Object[]{source, root}); // NOI18N
-			if (root != null &amp;&amp; root.equals(source))
-				reScheduleRefresh(1000);
-			return;
-		}
-		if (ExplorerManager.PROP_SELECTED_NODES.equals(evt.getPropertyName())) {
-			TopComponent tc = (TopComponent) SwingUtilities.getAncestorOfClass(TopComponent.class, this);
-			if (tc != null)
-				tc.setActivatedNodes((Node[]) evt.getNewValue());
-			return;
-		}
-	}
-
-	/**
-	 * Sets roots (directories) to display in the view.
-	 *
-	 * @param ctx new context if the Versioning panel
-	 */
-	void setContext(VCSContext ctx)
-	{
-		context = ctx;
-		reScheduleRefresh(0);
-	}
-
-	public ExplorerManager getExplorerManager()
-	{
-		return explorerManager;
-	}
-
-	@Override
-	public void addNotify()
-	{
-		super.addNotify();
-		GitModuleConfig.getDefault().getPreferences().addPreferenceChangeListener(this);
-		git.getStatusCache().addPropertyChangeListener(this);
-		git.addPropertyChangeListener(this);
-		explorerManager.addPropertyChangeListener(this);
-		reScheduleRefresh(0);   // the view does not listen for changes when it is not visible
-	}
-
-	@Override
-	public void removeNotify()
-	{
-		GitModuleConfig.getDefault().getPreferences().removePreferenceChangeListener(this);
-		git.getStatusCache().removePropertyChangeListener(this);
-		git.removePropertyChangeListener(this);
-		explorerManager.removePropertyChangeListener(this);
-		super.removeNotify();
-	}
-
-	private void setVersioningComponent(JComponent component)
-	{
-		Component[] children = getComponents();
-		for (int i = 0; i &lt; children.length; i++) {
-			Component child = children[i];
-			if (child != jPanel2)
-				if (child == component)
-					return;
-				else {
-					remove(child);
-					break;
-				}
-		}
-		GridBagConstraints gbc = new GridBagConstraints();
-		gbc.gridx = 0;
-		gbc.gridy = 2;
-		gbc.gridwidth = GridBagConstraints.REMAINDER;
-		gbc.gridheight = 1;
-		gbc.anchor = GridBagConstraints.FIRST_LINE_START;
-		gbc.fill = GridBagConstraints.BOTH;
-		gbc.weightx = 1;
-		gbc.weighty = 1;
-
-		add(component, gbc);
-		revalidate();
-		repaint();
-	}
-
-	/**
-	 * Must NOT be run from AWT.
-	 */
-	private void setupModels()
-	{
-		if (context == null) {
-			SwingUtilities.invokeLater(new Runnable() {
-
-				public void run()
-				{
-					syncTable.setTableModel(new SyncFileNode[0]);
-					File root = GitUtils.getRootFile(GitUtils.getCurrentContext(null));
-				/* #126311: Optimize UI for Large repos
-				if (root != null) {
-				String[] info = getRepositoryBranchInfo(root);
-				String rev = info != null ? info[1] : null;
-				String changeset = info != null ? info[2] : null;
-				setRepositoryBranchInfo(rev, changeset);
-				}*/
-				}
-
-			});
-			return;
-		}
-		// XXX attach Cancelable hook
-		final ProgressHandle ph = ProgressHandleFactory.createHandle(NbBundle.getMessage(VersioningPanel.class, &quot;MSG_Refreshing_Versioning_View&quot;)); // NOI18N
-		try {
-			refreshViewThread = Thread.currentThread();
-			Thread.interrupted();  // clear interupted status
-			ph.start();
-			final SyncFileNode[] nodes = getNodes(context, displayStatuses);  // takes long
-
-			if (nodes == null)
-				return;
-
-			final String[] tableColumns;
-			final String branchTitle;
-			File[] files = context.getRootFiles().toArray(new File[context.getRootFiles().size()]);
-			if (files == null || files.length == 0)
-				return;
-
-			/* #126311: begin Optimize UI for Large repos */
-			File root = git.getTopmostManagedParent(files[0]);
-			String[] info = getRepositoryBranchInfo(root);
-			if (info != null)
-				branchTitle = NbBundle.getMessage(VersioningPanel.class, &quot;CTL_VersioningView_BranchTitle&quot;, info[0]);
-			else
-				branchTitle = NbBundle.getMessage(VersioningPanel.class, &quot;CTL_VersioningView_UnnamedBranchTitle&quot;);
-			/* #126311: end */
-			if (nodes.length &gt; 0) {
-				boolean stickyCommon = false;
-				for (int i = 1; i &lt; nodes.length; i++) {
-					if (Thread.interrupted())
-						// TODO set model that displays that fact to user
-						return;
-				}
-				tableColumns = new String[]{SyncFileNode.COLUMN_NAME_NAME, SyncFileNode.COLUMN_NAME_STATUS, SyncFileNode.COLUMN_NAME_PATH};
-			} else
-				tableColumns = null;
-			/* #126311: Optimize UI for Large repos */
-			setRepositoryBranchInfo(info != null ? info[1] : null);
-			/* end */
-			SwingUtilities.invokeLater(new Runnable() {
-
-				public void run()
-				{
-					/* #126311: Optimize UI for Large repos */
-					parentTopComponent.setBranchTitle(branchTitle);
-					/* end */
-					if (nodes.length &gt; 0) {
-						syncTable.setColumns(tableColumns);
-						setVersioningComponent(syncTable.getComponent());
-					} else
-						setVersioningComponent(noContentComponent);
-					syncTable.setTableModel(nodes);
-				// finally section, it's enqueued after this request
-				}
-
-			});
-		} finally {
-			SwingUtilities.invokeLater(new Runnable() {
-
-				public void run()
-				{
-					ph.finish();
-				}
-
-			});
-		}
-	}
-
-	private void setRepositoryBranchInfo(String rev)
-	{
-		String info;
-		if (rev != null)
-			info = NbBundle.getMessage(VersioningPanel.class,
-				&quot;CTL_VersioningView_BranchInfo&quot;, // NOI18N
-				rev);
-		else
-			info = NbBundle.getMessage(VersioningPanel.class,
-				&quot;CTL_VersioningView_BranchInfoNotCommitted&quot;);
-		String title = NbBundle.getMessage(VersioningPanel.class, &quot;CTL_VersioningView_StatusTitle&quot;, info); // NOI18N
-		if (!title.equals(statusLabel.getText()))
-			statusLabel.setText(title);
-	}
-
-	private String[] getRepositoryBranchInfo(File root)
-	{
-		Repository repo = git.getRepository(root);
-
-		if (repo == null)
-			return null;
-
-		try {
-			String branch = repo.getBranch();
-			String head = branch != null ? repo.getFullBranch() : Constants.HEAD;
-			ObjectId id = repo.resolve(head);
-			if (branch == null)
-				branch = Constants.HEAD;
-			return new String[]{
-					branch,
-					id != null ? id.toString() : null
-				};
-		} catch (IOException ex) {
-			Exceptions.printStackTrace(ex);
-		}
-
-		return null;
-	}
-
-	private SyncFileNode[] getNodes(VCSContext context, int status)
-	{
-		File[] files = git.getStatusCache().listFiles(context, status);
-		SyncFileNode[] nodes = new SyncFileNode[files.length];
-		int i = 0;
-
-		for (File file: files) {
-			if (Thread.interrupted())
-				return null;
-			nodes[i++] = new SyncFileNode(new GitFileNode(file), this);
-		}
-
-		return nodes;
-	}
-
-	public int getDisplayStatuses()
-	{
-		return displayStatuses;
-	}
-
-	public String getDisplayBranchInfo()
-	{
-		return branchInfo;
-	}
-
-	/**
-	 * Performs the &quot;cvs commit&quot; command on all diplayed roots plus &quot;cvs add&quot; for files that are not yet added. // NOI18N
-	 */
-	private void onCommitAction()
-	{
-		//TODO: Status Commit Action
-		LifecycleManager.getDefault().saveAll();
-		CommitAction.commit(parentTopComponent.getContentTitle(), context);
-	}
-
-	/**
-	 * Performs the &quot;cvs update&quot; command on all diplayed roots. // NOI18N
-	 */
-	private void onUpdateAction()
-	{
-		UpdateAction.update(context);
-		parentTopComponent.contentRefreshed();
-	}
-
-	/**
-	 * Refreshes statuses of all files in the view. It does
-	 * that by issuing the &quot;git status -marduiC&quot; command, updating the cache
-	 * and refreshing file nodes.
-	 */
-	private void onRefreshAction()
-	{
-		LifecycleManager.getDefault().saveAll();
-		if (context == null || context.getRootFiles().size() == 0)
-			return;
-		refreshStatuses();
-	}
-
-	/**
-	 * Programmatically invokes the Refresh action.
-	 * Connects to repository and gets recent status.
-	 */
-	void performRefreshAction()
-	{
-		refreshStatuses();
-	}
-
-	/* Async Connects to repository and gets recent status. */
-	private void refreshStatuses()
-	{
-		if (gitProgressSupport != null) {
-			gitProgressSupport.cancel();
-			gitProgressSupport = null;
-		}
-
-		final String repository = GitUtils.getRootPath(context);
-		if (repository == null)
-			return;
-
-		RequestProcessor rp = Git.getInstance().getRequestProcessor(repository);
-		gitProgressSupport = new GitProgressSupport() {
-
-			public void perform()
-			{
-				StatusAction.executeStatus(context, this);
-				setupModels();
-			}
-
-		};
-
-		parentTopComponent.contentRefreshed();
-		gitProgressSupport.start(rp, repository, org.openide.util.NbBundle.getMessage(VersioningPanel.class, &quot;LBL_Refresh_Progress&quot;)); // NOI18N
-
-	}
-
-	/**
-	 * Shows Diff panel for all files in the view. The initial type of diff depends on the sync mode: Local, Remote, All.
-	 * In Local mode, the diff shows CURRENT &lt;-&gt; BASE differences. In Remote mode, it shows BASE&lt;-&gt;HEAD differences.
-	 */
-	private void onDiffAction()
-	{
-		String title = parentTopComponent.getContentTitle();
-		if (displayStatuses == StatusInfo.STATUS_LOCAL_CHANGE) {
-			LifecycleManager.getDefault().saveAll();
-			DiffAction.diff(context, Setup.DIFFTYPE_LOCAL, title);
-		} else if (displayStatuses == StatusInfo.STATUS_REMOTE_CHANGE)
-			DiffAction.diff(context, Setup.DIFFTYPE_REMOTE, title);
-		else {
-			LifecycleManager.getDefault().saveAll();
-			DiffAction.diff(context, Setup.DIFFTYPE_ALL, title);
-		}
-	}
-
-	private void onDisplayedStatusChanged()
-	{
-		setDisplayStatuses(StatusInfo.STATUS_REMOTE_CHANGE | StatusInfo.STATUS_LOCAL_CHANGE);
-		noContentComponent.setLabel(NbBundle.getMessage(VersioningPanel.class, &quot;MSG_No_Changes_All&quot;)); // NOI18N
-	}
-
-	private void setDisplayStatuses(int displayStatuses)
-	{
-		this.displayStatuses = displayStatuses;
-		reScheduleRefresh(0);
-	}
-
-	private boolean affectsView(PropertyChangeEvent event)
-	{
-		StatusCache.ChangedEvent changedEvent = (StatusCache.ChangedEvent) event.getNewValue();
-		File file = changedEvent.getFile();
-		StatusInfo oldInfo = changedEvent.getOldInfo();
-		StatusInfo newInfo = changedEvent.getNewInfo();
-		if (oldInfo == null) {
-			if ((newInfo.getStatus() &amp; displayStatuses) == 0)
-				return false;
-		} else if ((oldInfo.getStatus() &amp; displayStatuses) + (newInfo.getStatus() &amp; displayStatuses) == 0)
-			return false;
-		return context == null ? false : context.contains(file);
-	}
-
-	/** Reloads data from cache */
-	private void reScheduleRefresh(int delayMillis)
-	{
-		refreshViewTask.schedule(delayMillis);
-	}
-	// HACK copy&amp;paste HACK, replace by save/restore of column width/position
-	void deserialize()
-	{
-		if (syncTable != null)
-			SwingUtilities.invokeLater(new Runnable() {
-
-				public void run()
-				{
-					syncTable.setDefaultColumnSizes();
-				}
-
-			});
-	}
-
-	void focus()
-	{
-		syncTable.focus();
-	}
-
-	/**
-	 * Cancels both:
-	 * &lt;ul&gt;
-	 * &lt;li&gt;cache data fetching
-	 * &lt;li&gt;background cvs -N update
-	 * &lt;/ul&gt;
-	 */
-	public void cancelRefresh()
-	{
-		refreshViewTask.cancel();
-	}
-
-	private class RefreshViewTask implements Runnable {
-
-		public void run()
-		{
-			setupModels();
-		}
-
-	}
-
-	/**
-	 * Hardcoded toolbar layout. It eliminates need
-	 * for nested panels their look is hardly maintanable
-	 * accross several look and feels
-	 * (e.g. strange layouting panel borders on GTK+).
-	 *
-	 * &lt;p&gt;It sets authoritatively component height and takes
-	 * &quot;prefered&quot; width from components itself. // NOI18N
-	 *
-	 */
-	private class ToolbarLayout implements LayoutManager {
-
-		/** Expected border height */
-		private int TOOLBAR_HEIGHT_ADJUSTMENT = 4;
-		private int TOOLBAR_SEPARATOR_MIN_WIDTH = 12;
-		/** Cached toolbar height */
-		private int toolbarHeight = -1;
-		/** Guard for above cache. */
-		private Dimension parentSize;
-		private Set&lt;JComponent&gt; adjusted = new HashSet&lt;JComponent&gt;();
-
-		public void removeLayoutComponent(Component comp)
-		{
-		}
-
-		public void layoutContainer(Container parent)
-		{
-			Dimension dim = VersioningPanel.this.getSize();
-			Dimension max = parent.getSize();
-
-			int reminder = max.width - minimumLayoutSize(parent).width;
-
-			int components = parent.getComponentCount();
-			int horizont = 0;
-			for (int i = 0; i &lt; components; i++) {
-				JComponent comp = (JComponent) parent.getComponent(i);
-				if (comp.isVisible() == false)
-					continue;
-				comp.setLocation(horizont, 0);
-				Dimension pref = comp.getPreferredSize();
-				int width = pref.width;
-				if (comp instanceof JSeparator &amp;&amp; ((dim.height - dim.width) &lt;= 0))
-					width = Math.max(width, TOOLBAR_SEPARATOR_MIN_WIDTH);
-				if (comp instanceof JProgressBar &amp;&amp; reminder &gt; 0)
-					width += reminder;
+    private ExplorerManager explorerManager;
+    private final GitVersioningTopComponent parentTopComponent;
+    private final Git git;
+    private VCSContext context;
+    private int displayStatuses;
+    private String branchInfo;
+    private SyncTable syncTable;
+    private RequestProcessor.Task refreshViewTask;
+    private Thread refreshViewThread;
+    private GitProgressSupport gitProgressSupport;
+    private static final RequestProcessor rp = new RequestProcessor(&quot;GitView&quot;, 1, true);  // NOI18N
+    private final NoContentPanel noContentComponent = new NoContentPanel();
+
+    /**
+     * Creates a new Synchronize Panel managed by the given versioning system.
+     *
+     * @param parent enclosing top component
+     */
+    public VersioningPanel(GitVersioningTopComponent parent)
+    {
+        this.parentTopComponent = parent;
+        this.git = Git.getInstance();
+        refreshViewTask = rp.create(new RefreshViewTask());
+        explorerManager = new ExplorerManager();
+        displayStatuses = StatusInfo.STATUS_LOCAL_CHANGE;
+        noContentComponent.setLabel(NbBundle.getMessage(VersioningPanel.class, &quot;MSG_No_Changes_All&quot;)); // NOI18N
+        syncTable = new SyncTable();
+
+        initComponents();
+        setVersioningComponent(syncTable.getComponent());
+        reScheduleRefresh(0);
+
+        // XXX click it in form editor, probbaly requires  Mattisse &gt;=v2
+        jPanel2.setFloatable(false);
+        jPanel2.putClientProperty(&quot;JToolBar.isRollover&quot;, Boolean.TRUE);  // NOI18N
+        jPanel2.setLayout(new ToolbarLayout());
+    }
+
+    public void preferenceChange(PreferenceChangeEvent evt)
+    {
+        if (evt.getKey().startsWith(GitModuleConfig.PROP_COMMIT_EXCLUSIONS))
+            repaint();
+    }
+
+    public void propertyChange(PropertyChangeEvent evt)
+    {
+        if (StatusCache.PROP_FILE_STATUS_CHANGED.equals(evt.getPropertyName())) {
+            StatusCache.ChangedEvent changedEvent = (StatusCache.ChangedEvent) evt.getNewValue();
+            Git.LOG.log(Level.FINE, &quot;Status.propertyChange(): {0} file:  {1}&quot;, new Object[]{parentTopComponent.getContentTitle(), changedEvent.getFile()}); // NOI18N
+            if (affectsView(evt))
+                reScheduleRefresh(1000);
+            return;
+        }
+        if (Git.PROP_CHANGESET_CHANGED.equals(evt.getPropertyName())) {
+            Object source = evt.getOldValue();
+            File root = GitUtils.getRootFile(context);
+            Git.LOG.log(Level.FINE, &quot;Git.changesetChanged: source {0} repo {1} &quot;, new Object[]{source, root}); // NOI18N
+            if (root != null &amp;&amp; root.equals(source))
+                reScheduleRefresh(1000);
+            return;
+        }
+        if (ExplorerManager.PROP_SELECTED_NODES.equals(evt.getPropertyName())) {
+            TopComponent tc = (TopComponent) SwingUtilities.getAncestorOfClass(TopComponent.class, this);
+            if (tc != null)
+                tc.setActivatedNodes((Node[]) evt.getNewValue());
+            return;
+        }
+    }
+
+    /**
+     * Sets roots (directories) to display in the view.
+     *
+     * @param ctx new context if the Versioning panel
+     */
+    void setContext(VCSContext ctx)
+    {
+        context = ctx;
+        reScheduleRefresh(0);
+    }
+
+    public ExplorerManager getExplorerManager()
+    {
+        return explorerManager;
+    }
+
+    @Override
+    public void addNotify()
+    {
+        super.addNotify();
+        GitModuleConfig.getDefault().getPreferences().addPreferenceChangeListener(this);
+        git.getStatusCache().addPropertyChangeListener(this);
+        git.addPropertyChangeListener(this);
+        explorerManager.addPropertyChangeListener(this);
+        reScheduleRefresh(0);   // the view does not listen for changes when it is not visible
+    }
+
+    @Override
+    public void removeNotify()
+    {
+        GitModuleConfig.getDefault().getPreferences().removePreferenceChangeListener(this);
+        git.getStatusCache().removePropertyChangeListener(this);
+        git.removePropertyChangeListener(this);
+        explorerManager.removePropertyChangeListener(this);
+        super.removeNotify();
+    }
+
+    private void setVersioningComponent(JComponent component)
+    {
+        Component[] children = getComponents();
+        for (int i = 0; i &lt; children.length; i++) {
+            Component child = children[i];
+            if (child != jPanel2)
+                if (child == component)
+                    return;
+                else {
+                    remove(child);
+                    break;
+                }
+        }
+        GridBagConstraints gbc = new GridBagConstraints();
+        gbc.gridx = 0;
+        gbc.gridy = 2;
+        gbc.gridwidth = GridBagConstraints.REMAINDER;
+        gbc.gridheight = 1;
+        gbc.anchor = GridBagConstraints.FIRST_LINE_START;
+        gbc.fill = GridBagConstraints.BOTH;
+        gbc.weightx = 1;
+        gbc.weighty = 1;
+
+        add(component, gbc);
+        revalidate();
+        repaint();
+    }
+
+    /**
+     * Must NOT be run from AWT.
+     */
+    private void setupModels()
+    {
+        if (context == null) {
+            SwingUtilities.invokeLater(new Runnable() {
+
+                public void run()
+                {
+                    syncTable.setTableModel(new SyncFileNode[0]);
+                    File root = GitUtils.getRootFile(GitUtils.getCurrentContext(null));
+                /* #126311: Optimize UI for Large repos
+                if (root != null) {
+                String[] info = getRepositoryBranchInfo(root);
+                String rev = info != null ? info[1] : null;
+                String changeset = info != null ? info[2] : null;
+                setRepositoryBranchInfo(rev, changeset);
+                }*/
+                }
+
+            });
+            return;
+        }
+        // XXX attach Cancelable hook
+        final ProgressHandle ph = ProgressHandleFactory.createHandle(NbBundle.getMessage(VersioningPanel.class, &quot;MSG_Refreshing_Versioning_View&quot;)); // NOI18N
+        try {
+            refreshViewThread = Thread.currentThread();
+            Thread.interrupted();  // clear interupted status
+            ph.start();
+            final SyncFileNode[] nodes = getNodes(context, displayStatuses);  // takes long
+
+            if (nodes == null)
+                return;
+
+            final String[] tableColumns;
+            final String branchTitle;
+            File[] files = context.getRootFiles().toArray(new File[context.getRootFiles().size()]);
+            if (files == null || files.length == 0)
+                return;
+
+            /* #126311: begin Optimize UI for Large repos */
+            File root = git.getTopmostManagedParent(files[0]);
+            String[] info = getRepositoryBranchInfo(root);
+            if (info != null)
+                branchTitle = NbBundle.getMessage(VersioningPanel.class, &quot;CTL_VersioningView_BranchTitle&quot;, info[0]);
+            else
+                branchTitle = NbBundle.getMessage(VersioningPanel.class, &quot;CTL_VersioningView_UnnamedBranchTitle&quot;);
+            /* #126311: end */
+            if (nodes.length &gt; 0) {
+                boolean stickyCommon = false;
+                for (int i = 1; i &lt; nodes.length; i++) {
+                    if (Thread.interrupted())
+                        // TODO set model that displays that fact to user
+                        return;
+                }
+                tableColumns = new String[]{SyncFileNode.COLUMN_NAME_NAME, SyncFileNode.COLUMN_NAME_STATUS, SyncFileNode.COLUMN_NAME_PATH};
+            } else
+                tableColumns = null;
+            /* #126311: Optimize UI for Large repos */
+            setRepositoryBranchInfo(info != null ? info[1] : null);
+            /* end */
+            SwingUtilities.invokeLater(new Runnable() {
+
+                public void run()
+                {
+                    /* #126311: Optimize UI for Large repos */
+                    parentTopComponent.setBranchTitle(branchTitle);
+                    /* end */
+                    if (nodes.length &gt; 0) {
+                        syncTable.setColumns(tableColumns);
+                        setVersioningComponent(syncTable.getComponent());
+                    } else
+                        setVersioningComponent(noContentComponent);
+                    syncTable.setTableModel(nodes);
+                // finally section, it's enqueued after this request
+                }
+
+            });
+        } finally {
+            SwingUtilities.invokeLater(new Runnable() {
+
+                public void run()
+                {
+                    ph.finish();
+                }
+
+            });
+        }
+    }
+
+    private void setRepositoryBranchInfo(String rev)
+    {
+        String info;
+        if (rev != null)
+            info = NbBundle.getMessage(VersioningPanel.class,
+                &quot;CTL_VersioningView_BranchInfo&quot;, // NOI18N
+                rev);
+        else
+            info = NbBundle.getMessage(VersioningPanel.class,
+                &quot;CTL_VersioningView_BranchInfoNotCommitted&quot;);
+        String title = NbBundle.getMessage(VersioningPanel.class, &quot;CTL_VersioningView_StatusTitle&quot;, info); // NOI18N
+        if (!title.equals(statusLabel.getText()))
+            statusLabel.setText(title);
+    }
+
+    private String[] getRepositoryBranchInfo(File root)
+    {
+        Repository repo = git.getRepository(root);
+
+        if (repo == null)
+            return null;
+
+        try {
+            String branch = repo.getBranch();
+            String head = branch != null ? repo.getFullBranch() : Constants.HEAD;
+            ObjectId id = repo.resolve(head);
+            if (branch == null)
+                branch = Constants.HEAD;
+            return new String[]{
+                    branch,
+                    id != null ? id.toString() : null
+                };
+        } catch (IOException ex) {
+            Exceptions.printStackTrace(ex);
+        }
+
+        return null;
+    }
+
+    private SyncFileNode[] getNodes(VCSContext context, int status)
+    {
+        File[] files = git.getStatusCache().listFiles(context, status);
+        SyncFileNode[] nodes = new SyncFileNode[files.length];
+        int i = 0;
+
+        for (File file: files) {
+            if (Thread.interrupted())
+                return null;
+            nodes[i++] = new SyncFileNode(new GitFileNode(file), this);
+        }
+
+        return nodes;
+    }
+
+    public int getDisplayStatuses()
+    {
+        return displayStatuses;
+    }
+
+    public String getDisplayBranchInfo()
+    {
+        return branchInfo;
+    }
+
+    /**
+     * Performs the &quot;cvs commit&quot; command on all diplayed roots plus &quot;cvs add&quot; for files that are not yet added. // NOI18N
+     */
+    private void onCommitAction()
+    {
+        //TODO: Status Commit Action
+        LifecycleManager.getDefault().saveAll();
+        CommitAction.commit(parentTopComponent.getContentTitle(), context);
+    }
+
+    /**
+     * Performs the &quot;cvs update&quot; command on all diplayed roots. // NOI18N
+     */
+    private void onUpdateAction()
+    {
+        UpdateAction.update(context);
+        parentTopComponent.contentRefreshed();
+    }
+
+    /**
+     * Refreshes statuses of all files in the view. It does
+     * that by issuing the &quot;git status -marduiC&quot; command, updating the cache
+     * and refreshing file nodes.
+     */
+    private void onRefreshAction()
+    {
+        LifecycleManager.getDefault().saveAll();
+        if (context == null || context.getRootFiles().size() == 0)
+            return;
+        refreshStatuses();
+    }
+
+    /**
+     * Programmatically invokes the Refresh action.
+     * Connects to repository and gets recent status.
+     */
+    void performRefreshAction()
+    {
+        refreshStatuses();
+    }
+
+    /* Async Connects to repository and gets recent status. */
+    private void refreshStatuses()
+    {
+        if (gitProgressSupport != null) {
+            gitProgressSupport.cancel();
+            gitProgressSupport = null;
+        }
+
+        final String repository = GitUtils.getRootPath(context);
+        if (repository == null)
+            return;
+
+        RequestProcessor rp = Git.getInstance().getRequestProcessor(repository);
+        gitProgressSupport = new GitProgressSupport() {
+
+            public void perform()
+            {
+                StatusAction.executeStatus(context, this);
+                setupModels();
+            }
+
+        };
+
+        parentTopComponent.contentRefreshed();
+        gitProgressSupport.start(rp, repository, org.openide.util.NbBundle.getMessage(VersioningPanel.class, &quot;LBL_Refresh_Progress&quot;)); // NOI18N
+
+    }
+
+    /**
+     * Shows Diff panel for all files in the view. The initial type of diff depends on the sync mode: Local, Remote, All.
+     * In Local mode, the diff shows CURRENT &lt;-&gt; BASE differences. In Remote mode, it shows BASE&lt;-&gt;HEAD differences.
+     */
+    private void onDiffAction()
+    {
+        String title = parentTopComponent.getContentTitle();
+        if (displayStatuses == StatusInfo.STATUS_LOCAL_CHANGE) {
+            LifecycleManager.getDefault().saveAll();
+            DiffAction.diff(context, Setup.DIFFTYPE_LOCAL, title);
+        } else if (displayStatuses == StatusInfo.STATUS_REMOTE_CHANGE)
+            DiffAction.diff(context, Setup.DIFFTYPE_REMOTE, title);
+        else {
+            LifecycleManager.getDefault().saveAll();
+            DiffAction.diff(context, Setup.DIFFTYPE_ALL, title);
+        }
+    }
+
+    private void onDisplayedStatusChanged()
+    {
+        setDisplayStatuses(StatusInfo.STATUS_REMOTE_CHANGE | StatusInfo.STATUS_LOCAL_CHANGE);
+        noContentComponent.setLabel(NbBundle.getMessage(VersioningPanel.class, &quot;MSG_No_Changes_All&quot;)); // NOI18N
+    }
+
+    private void setDisplayStatuses(int displayStatuses)
+    {
+        this.displayStatuses = displayStatuses;
+        reScheduleRefresh(0);
+    }
+
+    private boolean affectsView(PropertyChangeEvent event)
+    {
+        StatusCache.ChangedEvent changedEvent = (StatusCache.ChangedEvent) event.getNewValue();
+        File file = changedEvent.getFile();
+        StatusInfo oldInfo = changedEvent.getOldInfo();
+        StatusInfo newInfo = changedEvent.getNewInfo();
+        if (oldInfo == null) {
+            if ((newInfo.getStatus() &amp; displayStatuses) == 0)
+                return false;
+        } else if ((oldInfo.getStatus() &amp; displayStatuses) + (newInfo.getStatus() &amp; displayStatuses) == 0)
+            return false;
+        return context == null ? false : context.contains(file);
+    }
+
+    /** Reloads data from cache */
+    private void reScheduleRefresh(int delayMillis)
+    {
+        refreshViewTask.schedule(delayMillis);
+    }
+    // HACK copy&amp;paste HACK, replace by save/restore of column width/position
+    void deserialize()
+    {
+        if (syncTable != null)
+            SwingUtilities.invokeLater(new Runnable() {
+
+                public void run()
+                {
+                    syncTable.setDefaultColumnSizes();
+                }
+
+            });
+    }
+
+    void focus()
+    {
+        syncTable.focus();
+    }
+
+    /**
+     * Cancels both:
+     * &lt;ul&gt;
+     * &lt;li&gt;cache data fetching
+     * &lt;li&gt;background cvs -N update
+     * &lt;/ul&gt;
+     */
+    public void cancelRefresh()
+    {
+        refreshViewTask.cancel();
+    }
+
+    private class RefreshViewTask implements Runnable {
+
+        public void run()
+        {
+            setupModels();
+        }
+
+    }
+
+    /**
+     * Hardcoded toolbar layout. It eliminates need
+     * for nested panels their look is hardly maintanable
+     * accross several look and feels
+     * (e.g. strange layouting panel borders on GTK+).
+     *
+     * &lt;p&gt;It sets authoritatively component height and takes
+     * &quot;prefered&quot; width from components itself. // NOI18N
+     *
+     */
+    private class ToolbarLayout implements LayoutManager {
+
+        /** Expected border height */
+        private int TOOLBAR_HEIGHT_ADJUSTMENT = 4;
+        private int TOOLBAR_SEPARATOR_MIN_WIDTH = 12;
+        /** Cached toolbar height */
+        private int toolbarHeight = -1;
+        /** Guard for above cache. */
+        private Dimension parentSize;
+        private Set&lt;JComponent&gt; adjusted = new HashSet&lt;JComponent&gt;();
+
+        public void removeLayoutComponent(Component comp)
+        {
+        }
+
+        public void layoutContainer(Container parent)
+        {
+            Dimension dim = VersioningPanel.this.getSize();
+            Dimension max = parent.getSize();
+
+            int reminder = max.width - minimumLayoutSize(parent).width;
+
+            int components = parent.getComponentCount();
+            int horizont = 0;
+            for (int i = 0; i &lt; components; i++) {
+                JComponent comp = (JComponent) parent.getComponent(i);
+                if (comp.isVisible() == false)
+                    continue;
+                comp.setLocation(horizont, 0);
+                Dimension pref = comp.getPreferredSize();
+                int width = pref.width;
+                if (comp instanceof JSeparator &amp;&amp; ((dim.height - dim.width) &lt;= 0))
+                    width = Math.max(width, TOOLBAR_SEPARATOR_MIN_WIDTH);
+                if (comp instanceof JProgressBar &amp;&amp; reminder &gt; 0)
+                    width += reminder;
 //                if (comp == getMiniStatus()) {
 //                    width = reminder;
 //                }
 
-				// in column layout use taller toolbar
-				int height = getToolbarHeight(dim) - 1;
-				comp.setSize(width, height);  // 1 verySoftBevel compensation
-				horizont += width;
-			}
-		}
-
-		public void addLayoutComponent(String name, Component comp)
-		{
-		}
-
-		public Dimension minimumLayoutSize(Container parent)
-		{
-
-			// in column layout use taller toolbar
-			Dimension dim = VersioningPanel.this.getSize();
-			int height = getToolbarHeight(dim);
-
-			int components = parent.getComponentCount();
-			int horizont = 0;
-			for (int i = 0; i &lt; components; i++) {
-				Component comp = parent.getComponent(i);
-				if (comp.isVisible() == false)
-					continue;
-				if (comp instanceof AbstractButton)
-					adjustToobarButton((AbstractButton) comp);
-				else
-					adjustToolbarComponentSize((JComponent) comp);
-				Dimension pref = comp.getPreferredSize();
-				int width = pref.width;
-				if (comp instanceof JSeparator &amp;&amp; ((dim.height - dim.width) &lt;= 0))
-					width = Math.max(width, TOOLBAR_SEPARATOR_MIN_WIDTH);
-				horizont += width;
-			}
-
-			return new Dimension(horizont, height);
-		}
-
-		public Dimension preferredLayoutSize(Container parent)
-		{
-			// Eliminates double height toolbar problem
-			Dimension dim = VersioningPanel.this.getSize();
-			int height = getToolbarHeight(dim);
-
-			return new Dimension(Integer.MAX_VALUE, height);
-		}
-
-		/**
-		 * Computes vertical toolbar components height that can used for layout manager hinting.
-		 * @return size based on font size and expected border.
-		 */
-		private int getToolbarHeight(Dimension parent)
-		{
-
-			if (parentSize == null || (parentSize.equals(parent) == false)) {
-				parentSize = parent;
-				toolbarHeight = -1;
-			}
-
-			if (toolbarHeight == -1) {
-				BufferedImage image = new BufferedImage(1, 1, BufferedImage.TYPE_BYTE_GRAY);
-				Graphics2D g = image.createGraphics();
-				UIDefaults def = UIManager.getLookAndFeelDefaults();
-
-				int height = 0;
-				String[] fonts = {&quot;Label.font&quot;, &quot;Button.font&quot;, &quot;ToggleButton.font&quot;};      // NOI18N
-				for (int i = 0; i &lt; fonts.length; i++) {
-					Font f = def.getFont(fonts[i]);
-					FontMetrics fm = g.getFontMetrics(f);
-					height = Math.max(height, fm.getHeight());
-				}
-				toolbarHeight = height + TOOLBAR_HEIGHT_ADJUSTMENT;
-				if ((parent.height - parent.width) &gt; 0)
-					toolbarHeight += TOOLBAR_HEIGHT_ADJUSTMENT;
-			}
-
-			return toolbarHeight;
-		}
-
-		/** Toolbar controls must be smaller and should be transparent*/
-		private void adjustToobarButton(final AbstractButton button)
-		{
-
-			if (adjusted.contains(button))
-				return;
-
-			// workaround for Ocean L&amp;F clutter - toolbars use gradient.
-			// To make the gradient visible under buttons the content area must not
-			// be filled. To support rollover it must be temporarily filled
-			if (button instanceof JToggleButton == false) {
-				button.setContentAreaFilled(false);
-				button.setMargin(new Insets(0, 3, 0, 3));
-				button.setBorderPainted(false);
-				button.addMouseListener(new MouseAdapter() {
-
-					@Override
-					public void mouseEntered(MouseEvent e)
-					{
-						button.setContentAreaFilled(true);
-						button.setBorderPainted(true);
-					}
-
-					@Override
-					public void mouseExited(MouseEvent e)
-					{
-						button.setContentAreaFilled(false);
-						button.setBorderPainted(false);
-					}
-
-				});
-			}
-
-			adjustToolbarComponentSize(button);
-		}
-
-		private void adjustToolbarComponentSize(JComponent button)
-		{
-
-			if (adjusted.contains(button))
-				return;
-
-			// as we cannot get the button small enough using the margin and border...
-			if (button.getBorder() instanceof CompoundBorder) { // from BasicLookAndFeel
-				Dimension pref = button.getPreferredSize();
-
-				// XXX #41827 workaround w2k, that adds eclipsis (...) instead of actual text
-				if (&quot;Windows&quot;.equals(UIManager.getLookAndFeel().getID()))  // NOI18N
-					pref.width += 9;
-				button.setPreferredSize(pref);
-			}
-
-			adjusted.add(button);
-		}
-
-	}
-
-	/** This method is called from within the constructor to
-	 * initialize the form.
-	 * WARNING: Do NOT modify this code. The content of this method is
-	 * always regenerated by the Form Editor.
-	 */
+                // in column layout use taller toolbar
+                int height = getToolbarHeight(dim) - 1;
+                comp.setSize(width, height);  // 1 verySoftBevel compensation
+                horizont += width;
+            }
+        }
+
+        public void addLayoutComponent(String name, Component comp)
+        {
+        }
+
+        public Dimension minimumLayoutSize(Container parent)
+        {
+
+            // in column layout use taller toolbar
+            Dimension dim = VersioningPanel.this.getSize();
+            int height = getToolbarHeight(dim);
+
+            int components = parent.getComponentCount();
+            int horizont = 0;
+            for (int i = 0; i &lt; components; i++) {
+                Component comp = parent.getComponent(i);
+                if (comp.isVisible() == false)
+                    continue;
+                if (comp instanceof AbstractButton)
+                    adjustToobarButton((AbstractButton) comp);
+                else
+                    adjustToolbarComponentSize((JComponent) comp);
+                Dimension pref = comp.getPreferredSize();
+                int width = pref.width;
+                if (comp instanceof JSeparator &amp;&amp; ((dim.height - dim.width) &lt;= 0))
+                    width = Math.max(width, TOOLBAR_SEPARATOR_MIN_WIDTH);
+                horizont += width;
+            }
+
+            return new Dimension(horizont, height);
+        }
+
+        public Dimension preferredLayoutSize(Container parent)
+        {
+            // Eliminates double height toolbar problem
+            Dimension dim = VersioningPanel.this.getSize();
+            int height = getToolbarHeight(dim);
+
+            return new Dimension(Integer.MAX_VALUE, height);
+        }
+
+        /**
+         * Computes vertical toolbar components height that can used for layout manager hinting.
+         * @return size based on font size and expected border.
+         */
+        private int getToolbarHeight(Dimension parent)
+        {
+
+            if (parentSize == null || (parentSize.equals(parent) == false)) {
+                parentSize = parent;
+                toolbarHeight = -1;
+            }
+
+            if (toolbarHeight == -1) {
+                BufferedImage image = new BufferedImage(1, 1, BufferedImage.TYPE_BYTE_GRAY);
+                Graphics2D g = image.createGraphics();
+                UIDefaults def = UIManager.getLookAndFeelDefaults();
+
+                int height = 0;
+                String[] fonts = {&quot;Label.font&quot;, &quot;Button.font&quot;, &quot;ToggleButton.font&quot;};      // NOI18N
+                for (int i = 0; i &lt; fonts.length; i++) {
+                    Font f = def.getFont(fonts[i]);
+                    FontMetrics fm = g.getFontMetrics(f);
+                    height = Math.max(height, fm.getHeight());
+                }
+                toolbarHeight = height + TOOLBAR_HEIGHT_ADJUSTMENT;
+                if ((parent.height - parent.width) &gt; 0)
+                    toolbarHeight += TOOLBAR_HEIGHT_ADJUSTMENT;
+            }
+
+            return toolbarHeight;
+        }
+
+        /** Toolbar controls must be smaller and should be transparent*/
+        private void adjustToobarButton(final AbstractButton button)
+        {
+
+            if (adjusted.contains(button))
+                return;
+
+            // workaround for Ocean L&amp;F clutter - toolbars use gradient.
+            // To make the gradient visible under buttons the content area must not
+            // be filled. To support rollover it must be temporarily filled
+            if (button instanceof JToggleButton == false) {
+                button.setContentAreaFilled(false);
+                button.setMargin(new Insets(0, 3, 0, 3));
+                button.setBorderPainted(false);
+                button.addMouseListener(new MouseAdapter() {
+
+                    @Override
+                    public void mouseEntered(MouseEvent e)
+                    {
+                        button.setContentAreaFilled(true);
+                        button.setBorderPainted(true);
+                    }
+
+                    @Override
+                    public void mouseExited(MouseEvent e)
+                    {
+                        button.setContentAreaFilled(false);
+                        button.setBorderPainted(false);
+                    }
+
+                });
+            }
+
+            adjustToolbarComponentSize(button);
+        }
+
+        private void adjustToolbarComponentSize(JComponent button)
+        {
+
+            if (adjusted.contains(button))
+                return;
+
+            // as we cannot get the button small enough using the margin and border...
+            if (button.getBorder() instanceof CompoundBorder) { // from BasicLookAndFeel
+                Dimension pref = button.getPreferredSize();
+
+                // XXX #41827 workaround w2k, that adds eclipsis (...) instead of actual text
+                if (&quot;Windows&quot;.equals(UIManager.getLookAndFeel().getID()))  // NOI18N
+                    pref.width += 9;
+                button.setPreferredSize(pref);
+            }
+
+            adjusted.add(button);
+        }
+
+    }
+
+    /** This method is called from within the constructor to
+     * initialize the form.
+     * WARNING: Do NOT modify this code. The content of this method is
+     * always regenerated by the Form Editor.
+     */
     // &lt;editor-fold defaultstate=&quot;collapsed&quot; desc=&quot;Generated Code&quot;&gt;//GEN-BEGIN:initComponents
     private void initComponents() {
         java.awt.GridBagConstraints gridBagConstraints;
@@ -813,19 +813,19 @@ class VersioningPanel extends JPanel implements ExplorerManager.Provider, Prefer
     }// &lt;/editor-fold&gt;//GEN-END:initComponents
 
 private void btnRefreshActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnRefreshActionPerformed
-	onRefreshAction();
+    onRefreshAction();
 }//GEN-LAST:event_btnRefreshActionPerformed
 
     private void btnDiffActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnDiffActionPerformed
-	    onDiffAction();
+        onDiffAction();
     }//GEN-LAST:event_btnDiffActionPerformed
 
     private void btnUpdateActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnUpdateActionPerformed
-	    onUpdateAction();
+        onUpdateAction();
     }//GEN-LAST:event_btnUpdateActionPerformed
 
     private void btnCommitActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnCommitActionPerformed
-	    onCommitAction();
+        onCommitAction();
     }//GEN-LAST:event_btnCommitActionPerformed
     // Variables declaration - do not modify//GEN-BEGIN:variables
     private javax.swing.JButton btnCommit;</diff>
      <filename>src/org/nbgit/ui/status/VersioningPanel.java</filename>
    </modified>
    <modified>
      <diff>@@ -61,74 +61,74 @@ import org.openide.util.RequestProcessor;
  */
 public class ConflictResolvedAction extends ContextAction {
 
-	public ConflictResolvedAction(String name, VCSContext context)
-	{
-		super(name, context);
-	}
-
-	public void performAction(ActionEvent e)
-	{
-		resolved(context);
-	}
-
-	public static void resolved(VCSContext ctx)
-	{
-		StatusCache cache = Git.getInstance().getStatusCache();
-		File[] files = cache.listFiles(ctx, StatusInfo.STATUS_VERSIONED_CONFLICT);
-		final File root = GitUtils.getRootFile(ctx);
-		if (root == null || files == null || files.length == 0)
-			return;
-
-		conflictResolved(root, files);
-
-		return;
-	}
-
-	@Override
-	public boolean isEnabled()
-	{
-		StatusCache cache = Git.getInstance().getStatusCache();
-
-		if (cache.listFiles(context, StatusInfo.STATUS_VERSIONED_CONFLICT).length != 0)
-			return true;
-
-		return false;
-	}
-
-	public static void conflictResolved(File repository, final File[] files)
-	{
-		if (repository == null || files == null || files.length == 0)
-			return;
-		RequestProcessor rp = Git.getInstance().getRequestProcessor(repository);
-		GitProgressSupport support = new GitProgressSupport() {
-
-			public void perform()
-			{
-				for (int i = 0; i &lt; files.length; i++) {
-					if (isCanceled())
-						return;
-					File file = files[i];
-					ConflictResolvedAction.perform(file);
-				}
-			}
-
-		};
-		support.start(rp, repository.getAbsolutePath(), NbBundle.getMessage(ConflictResolvedAction.class, &quot;MSG_ConflictResolved_Progress&quot;)); // NOI18N
-	}
-
-	private static void perform(File file)
-	{
-		if (file == null)
-			return;
-		StatusCache cache = Git.getInstance().getStatusCache();
-
-		GitCommand.deleteConflictFile(file.getAbsolutePath());
-		cache.refresh(file, StatusCache.REPOSITORY_STATUS_UNKNOWN);
-	}
-
-	public static void resolved(File file)
-	{
-		perform(file);
-	}
+    public ConflictResolvedAction(String name, VCSContext context)
+    {
+        super(name, context);
+    }
+
+    public void performAction(ActionEvent e)
+    {
+        resolved(context);
+    }
+
+    public static void resolved(VCSContext ctx)
+    {
+        StatusCache cache = Git.getInstance().getStatusCache();
+        File[] files = cache.listFiles(ctx, StatusInfo.STATUS_VERSIONED_CONFLICT);
+        final File root = GitUtils.getRootFile(ctx);
+        if (root == null || files == null || files.length == 0)
+            return;
+
+        conflictResolved(root, files);
+
+        return;
+    }
+
+    @Override
+    public boolean isEnabled()
+    {
+        StatusCache cache = Git.getInstance().getStatusCache();
+
+        if (cache.listFiles(context, StatusInfo.STATUS_VERSIONED_CONFLICT).length != 0)
+            return true;
+
+        return false;
+    }
+
+    public static void conflictResolved(File repository, final File[] files)
+    {
+        if (repository == null || files == null || files.length == 0)
+            return;
+        RequestProcessor rp = Git.getInstance().getRequestProcessor(repository);
+        GitProgressSupport support = new GitProgressSupport() {
+
+            public void perform()
+            {
+                for (int i = 0; i &lt; files.length; i++) {
+                    if (isCanceled())
+                        return;
+                    File file = files[i];
+                    ConflictResolvedAction.perform(file);
+                }
+            }
+
+        };
+        support.start(rp, repository.getAbsolutePath(), NbBundle.getMessage(ConflictResolvedAction.class, &quot;MSG_ConflictResolved_Progress&quot;)); // NOI18N
+    }
+
+    private static void perform(File file)
+    {
+        if (file == null)
+            return;
+        StatusCache cache = Git.getInstance().getStatusCache();
+
+        GitCommand.deleteConflictFile(file.getAbsolutePath());
+        cache.refresh(file, StatusCache.REPOSITORY_STATUS_UNKNOWN);
+    }
+
+    public static void resolved(File file)
+    {
+        perform(file);
+    }
 
 }
\ No newline at end of file</diff>
      <filename>src/org/nbgit/ui/update/ConflictResolvedAction.java</filename>
    </modified>
    <modified>
      <diff>@@ -59,46 +59,46 @@ import org.openide.NotifyDescriptor;
  */
 public class ResolveConflictsAction extends ContextAction {
 
-	public ResolveConflictsAction(String name, VCSContext context)
-	{
-		super(name, context);
-	}
+    public ResolveConflictsAction(String name, VCSContext context)
+    {
+        super(name, context);
+    }
 
-	public void performAction(ActionEvent e)
-	{
-		resolve(context);
-	}
+    public void performAction(ActionEvent e)
+    {
+        resolve(context);
+    }
 
-	public static void resolve(VCSContext ctx)
-	{
-		StatusCache cache = Git.getInstance().getStatusCache();
-		File[] files = cache.listFiles(ctx, StatusInfo.STATUS_VERSIONED_CONFLICT);
+    public static void resolve(VCSContext ctx)
+    {
+        StatusCache cache = Git.getInstance().getStatusCache();
+        File[] files = cache.listFiles(ctx, StatusInfo.STATUS_VERSIONED_CONFLICT);
 
-		resolveConflicts(files);
+        resolveConflicts(files);
 
-		return;
-	}
+        return;
+    }
 
-	@Override
-	public boolean isEnabled()
-	{
-		StatusCache cache = Git.getInstance().getStatusCache();
-		return cache.containsFileOfStatus(context, StatusInfo.STATUS_VERSIONED_CONFLICT);
-	}
+    @Override
+    public boolean isEnabled()
+    {
+        StatusCache cache = Git.getInstance().getStatusCache();
+        return cache.containsFileOfStatus(context, StatusInfo.STATUS_VERSIONED_CONFLICT);
+    }
 
-	static void resolveConflicts(File[] files)
-	{
-		if (files.length == 0) {
-			NotifyDescriptor nd = new NotifyDescriptor.Message(
-				org.openide.util.NbBundle.getMessage(
-				ResolveConflictsAction.class, &quot;MSG_NoConflictsFound&quot;)); // NOI18N
-			DialogDisplayer.getDefault().notify(nd);
-		} else
-			for (int i = 0; i &lt; files.length; i++) {
-				File file = files[i];
-				ResolveConflictsExecutor executor = new ResolveConflictsExecutor(file);
-				executor.exec();
-			}
-	}
+    static void resolveConflicts(File[] files)
+    {
+        if (files.length == 0) {
+            NotifyDescriptor nd = new NotifyDescriptor.Message(
+                org.openide.util.NbBundle.getMessage(
+                ResolveConflictsAction.class, &quot;MSG_NoConflictsFound&quot;)); // NOI18N
+            DialogDisplayer.getDefault().notify(nd);
+        } else
+            for (int i = 0; i &lt; files.length; i++) {
+                File file = files[i];
+                ResolveConflictsExecutor executor = new ResolveConflictsExecutor(file);
+                executor.exec();
+            }
+    }
 
 }
\ No newline at end of file</diff>
      <filename>src/org/nbgit/ui/update/ResolveConflictsAction.java</filename>
    </modified>
    <modified>
      <diff>@@ -78,15 +78,15 @@ import org.openide.windows.TopComponent;
  * @author  Martin Entlicher
  */
 public class ResolveConflictsExecutor extends GitProgressSupport {
-    
+
     private static final String TMP_PREFIX = &quot;merge&quot;; // NOI18N
-    private static final String ORIG_SUFFIX = &quot;.orig.&quot;; // NOI18N  
-    
+    private static final String ORIG_SUFFIX = &quot;.orig.&quot;; // NOI18N
+
     static final String CHANGE_LEFT = &quot;&lt;&lt;&lt;&lt;&lt;&lt;&lt; &quot;; // NOI18N
     static final String CHANGE_RIGHT = &quot;&gt;&gt;&gt;&gt;&gt;&gt;&gt; &quot;; // NOI18N
     static final String CHANGE_DELIMETER = &quot;=======&quot;; // NOI18N
     static final String CHANGE_BASE_DELIMETER = &quot;|||||||&quot;; // NOI18N
-    
+
     private String leftFileRevision = null;
     private String rightFileRevision = null;
 
@@ -103,7 +103,7 @@ public class ResolveConflictsExecutor extends GitProgressSupport {
         if (merge == null) {
             throw new IllegalStateException(&quot;No Merge engine found.&quot;); // NOI18N
         }
-        
+
         try {
             FileObject fo = FileUtil.toFileObject(file);
             handleMergeFor(file, fo, fo.lock(), merge);
@@ -119,7 +119,7 @@ public class ResolveConflictsExecutor extends GitProgressSupport {
             org.openide.ErrorManager.getDefault().notify(ioex);
         }
     }
-    
+
     private void handleMergeFor(final File file, FileObject fo, FileLock lock,
                                 final MergeVisualizer merge) throws IOException {
         String mimeType = (fo == null) ? &quot;text/plain&quot; : fo.getMIMEType(); // NOI18N
@@ -130,7 +130,7 @@ public class ResolveConflictsExecutor extends GitProgressSupport {
         f1.deleteOnExit();
         f2.deleteOnExit();
         f3.deleteOnExit();
-        
+
         final Difference[] diffs = copyParts(true, file, f1, true);
         if (diffs.length == 0) {
             ConflictResolvedAction.resolved(file);  // remove conflict status
@@ -153,7 +153,7 @@ public class ResolveConflictsExecutor extends GitProgressSupport {
         } else {
             rightFileRevision = org.openide.util.NbBundle.getMessage(ResolveConflictsExecutor.class, &quot;Diff.titleRevision&quot;, rightFileRevision); // NOI18N
         }
-        
+
         final StreamSource s1;
         final StreamSource s2;
         Charset encoding = FileEncodingQuery.getEncoding(fo);
@@ -189,13 +189,13 @@ public class ResolveConflictsExecutor extends GitProgressSupport {
             String line;
             boolean isChangeLeft = false;
             boolean isChangeRight = false;
-            boolean isChangeBase = false; 
+            boolean isChangeBase = false;
             int f1l1 = 0, f1l2 = 0, f2l1 = 0, f2l2 = 0;
             StringBuffer text1 = new StringBuffer();
             StringBuffer text2 = new StringBuffer();
             int i = 1, j = 1;
             while ((line = r.readLine()) != null) {
-                // As the Graphical Merge Visualizer does not support 3 way diff, 
+                // As the Graphical Merge Visualizer does not support 3 way diff,
                 // remove the base diff itself.
                 // Only show the diffs of the two heads against the base
                 if (line.startsWith(CHANGE_BASE_DELIMETER)) {
@@ -375,10 +375,10 @@ public class ResolveConflictsExecutor extends GitProgressSupport {
     public void run() {
         throw new RuntimeException(&quot;Not implemented&quot;); // NOI18N
     }
-    
-    
+
+
     private static class MergeResultWriterInfo extends StreamSource {
-        
+
         private File tempf1, tempf2, tempf3, outputFile;
         private File fileToRepairEntriesOf;
         private String mimeType;
@@ -387,7 +387,7 @@ public class ResolveConflictsExecutor extends GitProgressSupport {
         private FileObject fo;
         private FileLock lock;
         private Charset encoding;
-        
+
         public MergeResultWriterInfo(File tempf1, File tempf2, File tempf3,
                                      File outputFile, String mimeType,
                                      String leftFileRevision, String rightFileRevision,
@@ -406,23 +406,23 @@ public class ResolveConflictsExecutor extends GitProgressSupport {
             }
             this.encoding = encoding;
         }
-        
+
         public String getName() {
             return outputFile.getName();
         }
-        
+
         public String getTitle() {
             return org.openide.util.NbBundle.getMessage(ResolveConflictsExecutor.class, &quot;Merge.titleResult&quot;); // NOI18N
         }
-        
+
         public String getMIMEType() {
             return mimeType;
         }
-        
+
         public Reader createReader() throws IOException {
             throw new IOException(&quot;No reader of merge result&quot;); // NOI18N
         }
-        
+
         /**
          * Create a writer, that writes to the source.
          * @param conflicts The list of conflicts remaining in the source.
@@ -444,7 +444,7 @@ public class ResolveConflictsExecutor extends GitProgressSupport {
                                                    leftFileRevision, rightFileRevision);
             }
         }
-        
+
         /**
          * This method is called when the visual merging process is finished.
          * All possible writting processes are finished before this method is called.
@@ -469,16 +469,16 @@ public class ResolveConflictsExecutor extends GitProgressSupport {
             ConflictResolvedAction.resolved(file);  // remove conflict status
         }
     }
-    
+
     private static class MergeConflictFileWriter extends FilterWriter {
-        
+
         private Difference[] conflicts;
         private int lineNumber;
         private int currentConflict;
         private String leftName;
         private String rightName;
         private FileObject fo;
-        
+
         public MergeConflictFileWriter(Writer delegate, FileObject fo,
                                        Difference[] conflicts, String leftName,
                                        String rightName) throws IOException {
@@ -494,7 +494,7 @@ public class ResolveConflictsExecutor extends GitProgressSupport {
             }
             this.fo = fo;
         }
-        
+
         @Override
         public void write(String str) throws IOException {
             super.write(str);
@@ -504,7 +504,7 @@ public class ResolveConflictsExecutor extends GitProgressSupport {
                 currentConflict++;
             }
         }
-        
+
         private void writeConflict(Difference conflict) throws IOException {
             super.write(CHANGE_LEFT + leftName + &quot;\n&quot;); // NOI18N
             super.write(conflict.getFirstText());
@@ -512,7 +512,7 @@ public class ResolveConflictsExecutor extends GitProgressSupport {
             super.write(conflict.getSecondText());
             super.write(CHANGE_RIGHT + rightName + &quot;\n&quot;); // NOI18N
         }
-        
+
         private static int numChars(char c, String str) {
             int n = 0;
             for (int pos = str.indexOf(c); pos &gt;= 0 &amp;&amp; pos &lt; str.length(); pos = str.indexOf(c, pos + 1)) {
@@ -520,7 +520,7 @@ public class ResolveConflictsExecutor extends GitProgressSupport {
             }
             return n;
         }
-        
+
         @Override
         public void close() throws IOException {
             super.close();</diff>
      <filename>src/org/nbgit/ui/update/ResolveConflictsExecutor.java</filename>
    </modified>
    <modified>
      <diff>@@ -59,7 +59,7 @@ public class RevertModifications implements PropertyChangeListener {
     private RevertModificationsPanel panel;
     private JButton okButton;
     private JButton cancelButton;
-    
+
     /** Creates a new instance of RevertModifications */
     public RevertModifications(File repository, File[] files) {
         this (repository, files, null);
@@ -75,23 +75,23 @@ public class RevertModifications implements PropertyChangeListener {
         org.openide.awt.Mnemonics.setLocalizedText(cancelButton, org.openide.util.NbBundle.getMessage(RevertModifications.class, &quot;CTL_RevertForm_Action_Cancel&quot;)); // NOI18N
         cancelButton.getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getMessage(RevertModifications.class, &quot;ACSD_RevertForm_Action_Cancel&quot;)); // NOI18N
         cancelButton.getAccessibleContext().setAccessibleName(org.openide.util.NbBundle.getMessage(RevertModifications.class, &quot;ACSN_RevertForm_Action_Cancel&quot;)); // NOI18N
-    } 
-    
+    }
+
     public boolean showDialog() {
         File[] revertFiles = panel.getRevertFiles();
         DialogDescriptor dialogDescriptor;
         if (revertFiles.length == 1) {
             dialogDescriptor = new DialogDescriptor(panel, org.openide.util.NbBundle.getMessage(RevertModifications.class, &quot;CTL_RevertDialog&quot;, revertFiles[0].getName())); // NOI18N
         } else {
-            dialogDescriptor = new DialogDescriptor(panel, org.openide.util.NbBundle.getMessage(RevertModifications.class, &quot;CTL_MultiRevertDialog&quot;)); // NOI18N 
+            dialogDescriptor = new DialogDescriptor(panel, org.openide.util.NbBundle.getMessage(RevertModifications.class, &quot;CTL_MultiRevertDialog&quot;)); // NOI18N
         }
         dialogDescriptor.setOptions(new Object[] {okButton, cancelButton});
-        
+
         dialogDescriptor.setModal(true);
         dialogDescriptor.setHelpCtx(new HelpCtx(this.getClass()));
         dialogDescriptor.setValid(false);
-        
-        Dialog dialog = DialogDisplayer.getDefault().createDialog(dialogDescriptor);     
+
+        Dialog dialog = DialogDisplayer.getDefault().createDialog(dialogDescriptor);
         if (revertFiles.length == 1) {
             dialog.getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getMessage(RevertModifications.class, &quot;ACSD_RevertDialog&quot;, revertFiles[0].getName())); // NOI18N
         } else {
@@ -100,21 +100,21 @@ public class RevertModifications implements PropertyChangeListener {
         dialog.setVisible(true);
         dialog.setResizable(false);
         boolean ret = dialogDescriptor.getValue() == okButton;
-        return ret;       
+        return ret;
     }
 
     public void propertyChange(PropertyChangeEvent evt) {
         if(okButton != null) {
             boolean valid = ((Boolean)evt.getNewValue()).booleanValue();
             okButton.setEnabled(valid);
-        }       
+        }
     }
 
     public String getSelectionRevision() {
         if (panel == null) return null;
         return panel.getSelectedRevision();
     }
-    
+
     public boolean isBackupRequested() {
         if (panel == null) return false;
         return panel.isBackupRequested();</diff>
      <filename>src/org/nbgit/ui/update/RevertModifications.java</filename>
    </modified>
    <modified>
      <diff>@@ -68,126 +68,126 @@ import org.openide.util.RequestProcessor;
  */
 public class RevertModificationsAction extends ContextAction {
 
-	public RevertModificationsAction(String name, VCSContext context)
-	{
-		super(name, context);
-	}
-
-	public void performAction(ActionEvent e)
-	{
-		revert(context);
-	}
-
-	public static void revert(final VCSContext ctx)
-	{
-		final File[] files = ctx.getRootFiles().toArray(new File[ctx.getRootFiles().size()]);
-		final File repository = GitUtils.getRootFile(ctx);
-		if (repository == null)
-			return;
-		String rev = null;
-
-		final RevertModifications revertModifications = new RevertModifications(repository, files);
-		if (!revertModifications.showDialog())
-			return;
-		rev = revertModifications.getSelectionRevision();
-		final String revStr = rev;
-		final boolean doBackup = revertModifications.isBackupRequested();
-
-		RequestProcessor rp = Git.getInstance().getRequestProcessor(repository);
-		GitProgressSupport support = new GitProgressSupport() {
-
-			public void perform()
-			{
-				performRevert(repository, revStr, files, doBackup, this.getLogger());
-			}
-
-		};
-		support.start(rp, repository.getAbsolutePath(), org.openide.util.NbBundle.getMessage(UpdateAction.class, &quot;MSG_Revert_Progress&quot;)); // NOI18N
-
-		return;
-	}
-
-	public static void performRevert(File repository, String revStr, File file, boolean doBackup, OutputLogger logger)
-	{
-		List&lt;File&gt; revertFiles = new ArrayList&lt;File&gt;();
-		revertFiles.add(file);
-
-		performRevert(repository, revStr, revertFiles, doBackup, logger);
-	}
-
-	public static void performRevert(File repository, String revStr, File[] files, boolean doBackup, OutputLogger logger)
-	{
-		List&lt;File&gt; revertFiles = new ArrayList&lt;File&gt;();
-		for (File file : files) {
-			revertFiles.add(file);
-		}
-		performRevert(repository, revStr, revertFiles, doBackup, logger);
-	}
-
-	public static void performRevert(File repository, String revStr, List&lt;File&gt; revertFiles, boolean doBackup, OutputLogger logger)
-	{
-		logger.outputInRed(
-			NbBundle.getMessage(RevertModificationsAction.class,
-			&quot;MSG_REVERT_TITLE&quot;)); // NOI18N
-		logger.outputInRed(
-			NbBundle.getMessage(RevertModificationsAction.class,
-			&quot;MSG_REVERT_TITLE_SEP&quot;)); // NOI18N
-
-		// revStr == null =&gt; no -r REV in git revert command
-		// No revisions to revert too
-		if (revStr != null &amp;&amp; NbBundle.getMessage(RevertModificationsAction.class,
-			&quot;MSG_Revision_Default&quot;).startsWith(revStr)) {
-			logger.output(
-				NbBundle.getMessage(RevertModificationsAction.class,
-				&quot;MSG_REVERT_NOTHING&quot;)); // NOI18N
-			logger.outputInRed(
-				NbBundle.getMessage(RevertModificationsAction.class,
-				&quot;MSG_REVERT_DONE&quot;)); // NOI18N
-			logger.outputInRed(&quot;&quot;); // NOI18N
-			return;
-		}
-
-		logger.output(
-			NbBundle.getMessage(RevertModificationsAction.class,
-			&quot;MSG_REVERT_REVISION_STR&quot;, revStr)); // NOI18N
-		for (File file : revertFiles) {
-			logger.output(file.getAbsolutePath());
-		}
-		logger.output(&quot;&quot;); // NOI18N
-
-		GitCommand.doRevert(repository, revertFiles, revStr, doBackup, logger);
-		StatusCache cache = Git.getInstance().getStatusCache();
-		File[] conflictFiles = cache.listFiles(revertFiles.toArray(new File[0]), StatusInfo.STATUS_VERSIONED_CONFLICT);
-		if (conflictFiles.length != 0)
-			ConflictResolvedAction.conflictResolved(repository, conflictFiles);
-
-		if (revStr == null)
-			for (File file : revertFiles) {
-				GitUtils.forceStatusRefresh(file);
-			}
-		else if (revertFiles.size() &gt; 0)
-			GitUtils.forceStatusRefresh(revertFiles.get(0));
-
-		// refresh filesystem to take account of changes
-		FileObject rootObj = FileUtil.toFileObject(repository);
-		try {
-			rootObj.getFileSystem().refresh(true);
-		} catch (java.lang.Exception exc) {
-		}
-		logger.outputInRed(
-			NbBundle.getMessage(RevertModificationsAction.class,
-			&quot;MSG_REVERT_DONE&quot;)); // NOI18N
-		logger.outputInRed(&quot;&quot;); // NOI18N
-
-	}
-
-	@Override
-	public boolean isEnabled()
-	{
-		Set&lt;File&gt; ctxFiles = context != null ? context.getRootFiles() : null;
-		if (GitUtils.getRootFile(context) == null || ctxFiles == null || ctxFiles.size() == 0)
-			return false;
-		return true;
-	}
+    public RevertModificationsAction(String name, VCSContext context)
+    {
+        super(name, context);
+    }
+
+    public void performAction(ActionEvent e)
+    {
+        revert(context);
+    }
+
+    public static void revert(final VCSContext ctx)
+    {
+        final File[] files = ctx.getRootFiles().toArray(new File[ctx.getRootFiles().size()]);
+        final File repository = GitUtils.getRootFile(ctx);
+        if (repository == null)
+            return;
+        String rev = null;
+
+        final RevertModifications revertModifications = new RevertModifications(repository, files);
+        if (!revertModifications.showDialog())
+            return;
+        rev = revertModifications.getSelectionRevision();
+        final String revStr = rev;
+        final boolean doBackup = revertModifications.isBackupRequested();
+
+        RequestProcessor rp = Git.getInstance().getRequestProcessor(repository);
+        GitProgressSupport support = new GitProgressSupport() {
+
+            public void perform()
+            {
+                performRevert(repository, revStr, files, doBackup, this.getLogger());
+            }
+
+        };
+        support.start(rp, repository.getAbsolutePath(), org.openide.util.NbBundle.getMessage(UpdateAction.class, &quot;MSG_Revert_Progress&quot;)); // NOI18N
+
+        return;
+    }
+
+    public static void performRevert(File repository, String revStr, File file, boolean doBackup, OutputLogger logger)
+    {
+        List&lt;File&gt; revertFiles = new ArrayList&lt;File&gt;();
+        revertFiles.add(file);
+
+        performRevert(repository, revStr, revertFiles, doBackup, logger);
+    }
+
+    public static void performRevert(File repository, String revStr, File[] files, boolean doBackup, OutputLogger logger)
+    {
+        List&lt;File&gt; revertFiles = new ArrayList&lt;File&gt;();
+        for (File file : files) {
+            revertFiles.add(file);
+        }
+        performRevert(repository, revStr, revertFiles, doBackup, logger);
+    }
+
+    public static void performRevert(File repository, String revStr, List&lt;File&gt; revertFiles, boolean doBackup, OutputLogger logger)
+    {
+        logger.outputInRed(
+            NbBundle.getMessage(RevertModificationsAction.class,
+            &quot;MSG_REVERT_TITLE&quot;)); // NOI18N
+        logger.outputInRed(
+            NbBundle.getMessage(RevertModificationsAction.class,
+            &quot;MSG_REVERT_TITLE_SEP&quot;)); // NOI18N
+
+        // revStr == null =&gt; no -r REV in git revert command
+        // No revisions to revert too
+        if (revStr != null &amp;&amp; NbBundle.getMessage(RevertModificationsAction.class,
+            &quot;MSG_Revision_Default&quot;).startsWith(revStr)) {
+            logger.output(
+                NbBundle.getMessage(RevertModificationsAction.class,
+                &quot;MSG_REVERT_NOTHING&quot;)); // NOI18N
+            logger.outputInRed(
+                NbBundle.getMessage(RevertModificationsAction.class,
+                &quot;MSG_REVERT_DONE&quot;)); // NOI18N
+            logger.outputInRed(&quot;&quot;); // NOI18N
+            return;
+        }
+
+        logger.output(
+            NbBundle.getMessage(RevertModificationsAction.class,
+            &quot;MSG_REVERT_REVISION_STR&quot;, revStr)); // NOI18N
+        for (File file : revertFiles) {
+            logger.output(file.getAbsolutePath());
+        }
+        logger.output(&quot;&quot;); // NOI18N
+
+        GitCommand.doRevert(repository, revertFiles, revStr, doBackup, logger);
+        StatusCache cache = Git.getInstance().getStatusCache();
+        File[] conflictFiles = cache.listFiles(revertFiles.toArray(new File[0]), StatusInfo.STATUS_VERSIONED_CONFLICT);
+        if (conflictFiles.length != 0)
+            ConflictResolvedAction.conflictResolved(repository, conflictFiles);
+
+        if (revStr == null)
+            for (File file : revertFiles) {
+                GitUtils.forceStatusRefresh(file);
+            }
+        else if (revertFiles.size() &gt; 0)
+            GitUtils.forceStatusRefresh(revertFiles.get(0));
+
+        // refresh filesystem to take account of changes
+        FileObject rootObj = FileUtil.toFileObject(repository);
+        try {
+            rootObj.getFileSystem().refresh(true);
+        } catch (java.lang.Exception exc) {
+        }
+        logger.outputInRed(
+            NbBundle.getMessage(RevertModificationsAction.class,
+            &quot;MSG_REVERT_DONE&quot;)); // NOI18N
+        logger.outputInRed(&quot;&quot;); // NOI18N
+
+    }
+
+    @Override
+    public boolean isEnabled()
+    {
+        Set&lt;File&gt; ctxFiles = context != null ? context.getRootFiles() : null;
+        if (GitUtils.getRootFile(context) == null || ctxFiles == null || ctxFiles.size() == 0)
+            return false;
+        return true;
+    }
 
 }
\ No newline at end of file</diff>
      <filename>src/org/nbgit/ui/update/RevertModificationsAction.java</filename>
    </modified>
    <modified>
      <diff>@@ -21,7 +21,7 @@
                       &lt;EmptySpace min=&quot;-2&quot; pref=&quot;47&quot; max=&quot;-2&quot; attributes=&quot;0&quot;/&gt;
                       &lt;Component id=&quot;revisionsLabel&quot; min=&quot;-2&quot; max=&quot;-2&quot; attributes=&quot;0&quot;/&gt;
                       &lt;EmptySpace max=&quot;-2&quot; attributes=&quot;0&quot;/&gt;
-                      &lt;Component id=&quot;revisionsComboBox&quot; pref=&quot;334&quot; max=&quot;32767&quot; attributes=&quot;0&quot;/&gt;
+                      &lt;Component id=&quot;revisionsComboBox&quot; pref=&quot;504&quot; max=&quot;32767&quot; attributes=&quot;0&quot;/&gt;
                   &lt;/Group&gt;
                   &lt;Group type=&quot;102&quot; alignment=&quot;0&quot; attributes=&quot;0&quot;&gt;
                       &lt;EmptySpace max=&quot;-2&quot; attributes=&quot;0&quot;/&gt;
@@ -112,7 +112,7 @@
               &lt;Group type=&quot;102&quot; alignment=&quot;0&quot; attributes=&quot;0&quot;&gt;
                   &lt;EmptySpace max=&quot;-2&quot; attributes=&quot;0&quot;/&gt;
                   &lt;Component id=&quot;doBackupChxBox&quot; min=&quot;-2&quot; max=&quot;-2&quot; attributes=&quot;0&quot;/&gt;
-                  &lt;EmptySpace pref=&quot;312&quot; max=&quot;32767&quot; attributes=&quot;0&quot;/&gt;
+                  &lt;EmptySpace pref=&quot;329&quot; max=&quot;32767&quot; attributes=&quot;0&quot;/&gt;
               &lt;/Group&gt;
           &lt;/Group&gt;
         &lt;/DimensionLayout&gt;</diff>
      <filename>src/org/nbgit/ui/update/RevertModificationsPanel.form</filename>
    </modified>
    <modified>
      <diff>@@ -62,56 +62,56 @@ import org.openide.util.RequestProcessor;
  */
 public class RevertModificationsPanel extends javax.swing.JPanel {
 
-	private File repository;
-	private File[] revertFiles;
-	private RequestProcessor.Task refreshViewTask;
-	private Thread refreshViewThread;
-	private static final RequestProcessor rp = new RequestProcessor(&quot;GitRevert&quot;, 1);  // NOI18N
-	private static final int GIT_REVERT_TARGET_LIMIT = 100;
-	private List&lt;String[]&gt; revisionMap;
+    private File repository;
+    private File[] revertFiles;
+    private RequestProcessor.Task refreshViewTask;
+    private Thread refreshViewThread;
+    private static final RequestProcessor rp = new RequestProcessor(&quot;GitRevert&quot;, 1);  // NOI18N
+    private static final int GIT_REVERT_TARGET_LIMIT = 100;
+    private List&lt;String[]&gt; revisionMap;
 
-	/** Creates new form ReverModificationsPanel */
-	public RevertModificationsPanel(File repo, File[] files)
-	{
-		repository = repo;
-		revertFiles = files;
-		refreshViewTask = rp.create(new RefreshViewTask());
-		initComponents();
-		refreshViewTask.schedule(0);
-	}
+    /** Creates new form ReverModificationsPanel */
+    public RevertModificationsPanel(File repo, File[] files)
+    {
+        repository = repo;
+        revertFiles = files;
+        refreshViewTask = rp.create(new RefreshViewTask());
+        initComponents();
+        refreshViewTask.schedule(0);
+    }
 
-	public File[] getRevertFiles()
-	{
-		return revertFiles;
-	}
+    public File[] getRevertFiles()
+    {
+        return revertFiles;
+    }
 
-	public boolean isBackupRequested()
-	{
-		return doBackupChxBox.isSelected();
-	}
+    public boolean isBackupRequested()
+    {
+        return doBackupChxBox.isSelected();
+    }
 
-	public String getSelectedRevision()
-	{
-		String revStr = (String) revisionsComboBox.getSelectedItem();
-		if (revStr != null)
-			if (revStr.equals(NbBundle.getMessage(RevertModificationsPanel.class, &quot;MSG_Revision_Default&quot;)) || // NOI18N
-				revStr.equals(NbBundle.getMessage(RevertModificationsPanel.class, &quot;MSG_Fetching_Revisions&quot;))) // NOI18N
-				revStr = null;
-			else if (revisionMap != null)
-				for (String[] entry : revisionMap) {
-					if (entry[0].equals(revStr)) {
-						revStr = entry[1];
-						break;
-					}
-				}
-		return revStr;
-	}
+    public String getSelectedRevision()
+    {
+        String revStr = (String) revisionsComboBox.getSelectedItem();
+        if (revStr != null)
+            if (revStr.equals(NbBundle.getMessage(RevertModificationsPanel.class, &quot;MSG_Revision_Default&quot;)) || // NOI18N
+                revStr.equals(NbBundle.getMessage(RevertModificationsPanel.class, &quot;MSG_Fetching_Revisions&quot;))) // NOI18N
+                revStr = null;
+            else if (revisionMap != null)
+                for (String[] entry : revisionMap) {
+                    if (entry[0].equals(revStr)) {
+                        revStr = entry[1];
+                        break;
+                    }
+                }
+        return revStr;
+    }
 
-	/** This method is called from within the constructor to
-	 * initialize the form.
-	 * WARNING: Do NOT modify this code. The content of this method is
-	 * always regenerated by the Form Editor.
-	 */
+    /** This method is called from within the constructor to
+     * initialize the form.
+     * WARNING: Do NOT modify this code. The content of this method is
+     * always regenerated by the Form Editor.
+     */
     // &lt;editor-fold defaultstate=&quot;collapsed&quot; desc=&quot;Generated Code&quot;&gt;//GEN-BEGIN:initComponents
     private void initComponents() {
 
@@ -190,66 +190,66 @@ public class RevertModificationsPanel extends javax.swing.JPanel {
         revisionsComboBox.getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getMessage(RevertModificationsPanel.class, &quot;ACSD_revisionsComboBox&quot;)); // NOI18N
     }// &lt;/editor-fold&gt;//GEN-END:initComponents
 
-	/**
-	 * Must NOT be run from AWT.
-	 */
-	private void setupModels()
-	{
-		// XXX attach Cancelable hook
-		final ProgressHandle ph = ProgressHandleFactory.createHandle(NbBundle.getMessage(RevertModificationsPanel.class, &quot;MSG_Refreshing_Revert_Versions&quot;)); // NOI18N
-		try {
-			boolean doBackup = GitModuleConfig.getDefault().getBackupOnRevertModifications();
-			doBackupChxBox.setSelected(doBackup);
+    /**
+     * Must NOT be run from AWT.
+     */
+    private void setupModels()
+    {
+        // XXX attach Cancelable hook
+        final ProgressHandle ph = ProgressHandleFactory.createHandle(NbBundle.getMessage(RevertModificationsPanel.class, &quot;MSG_Refreshing_Revert_Versions&quot;)); // NOI18N
+        try {
+            boolean doBackup = GitModuleConfig.getDefault().getBackupOnRevertModifications();
+            doBackupChxBox.setSelected(doBackup);
 
-			Set&lt;String&gt; initialRevsSet = new LinkedHashSet&lt;String&gt;();
-			initialRevsSet.add(NbBundle.getMessage(RevertModificationsPanel.class, &quot;MSG_Fetching_Revisions&quot;)); // NOI18N
-			ComboBoxModel targetsModel = new DefaultComboBoxModel(new Vector&lt;String&gt;(initialRevsSet));
-			revisionsComboBox.setModel(targetsModel);
-			refreshViewThread = Thread.currentThread();
-			Thread.interrupted();  // clear interupted status
-			ph.start();
+            Set&lt;String&gt; initialRevsSet = new LinkedHashSet&lt;String&gt;();
+            initialRevsSet.add(NbBundle.getMessage(RevertModificationsPanel.class, &quot;MSG_Fetching_Revisions&quot;)); // NOI18N
+            ComboBoxModel targetsModel = new DefaultComboBoxModel(new Vector&lt;String&gt;(initialRevsSet));
+            revisionsComboBox.setModel(targetsModel);
+            refreshViewThread = Thread.currentThread();
+            Thread.interrupted();  // clear interupted status
+            ph.start();
 
-			refreshRevisions();
-		} finally {
-			SwingUtilities.invokeLater(new Runnable() {
+            refreshRevisions();
+        } finally {
+            SwingUtilities.invokeLater(new Runnable() {
 
-				public void run()
-				{
-					ph.finish();
-					refreshViewThread = null;
-				}
+                public void run()
+                {
+                    ph.finish();
+                    refreshViewThread = null;
+                }
 
-			});
-		}
-	}
+            });
+        }
+    }
 
-	private void refreshRevisions()
-	{
-		revisionMap = GitCommand.getRevisionsForFile(repository, revertFiles, GIT_REVERT_TARGET_LIMIT);
+    private void refreshRevisions()
+    {
+        revisionMap = GitCommand.getRevisionsForFile(repository, revertFiles, GIT_REVERT_TARGET_LIMIT);
 
-		Set&lt;String&gt; targetRevsSet = new LinkedHashSet&lt;String&gt;();
+        Set&lt;String&gt; targetRevsSet = new LinkedHashSet&lt;String&gt;();
 
-		if (revisionMap == null)
-			targetRevsSet.add(NbBundle.getMessage(RevertModificationsPanel.class, &quot;MSG_Revision_Default&quot;));
-		else
-			for (String[] entry : revisionMap) {
-				targetRevsSet.add(entry[0]);
-			}
-		ComboBoxModel targetsModel = new DefaultComboBoxModel(new Vector&lt;String&gt;(targetRevsSet));
-		revisionsComboBox.setModel(targetsModel);
+        if (revisionMap == null)
+            targetRevsSet.add(NbBundle.getMessage(RevertModificationsPanel.class, &quot;MSG_Revision_Default&quot;));
+        else
+            for (String[] entry : revisionMap) {
+                targetRevsSet.add(entry[0]);
+            }
+        ComboBoxModel targetsModel = new DefaultComboBoxModel(new Vector&lt;String&gt;(targetRevsSet));
+        revisionsComboBox.setModel(targetsModel);
 
-		if (targetRevsSet.size() &gt; 0)
-			revisionsComboBox.setSelectedIndex(0);
-	}
+        if (targetRevsSet.size() &gt; 0)
+            revisionsComboBox.setSelectedIndex(0);
+    }
 
-	private class RefreshViewTask implements Runnable {
+    private class RefreshViewTask implements Runnable {
 
-		public void run()
-		{
-			setupModels();
-		}
+        public void run()
+        {
+            setupModels();
+        }
 
-	}
+    }
 
     // Variables declaration - do not modify//GEN-BEGIN:variables
     private javax.swing.JCheckBox doBackupChxBox;</diff>
      <filename>src/org/nbgit/ui/update/RevertModificationsPanel.java</filename>
    </modified>
    <modified>
      <diff>@@ -60,7 +60,7 @@ public class Update implements PropertyChangeListener {
     private JButton okButton;
     private JButton cancelButton;
     private File repository;
-    
+
     /** Creates a new instance of Update */
     public Update(File repository) {
         this (repository, null);
@@ -77,30 +77,30 @@ public class Update implements PropertyChangeListener {
         org.openide.awt.Mnemonics.setLocalizedText(cancelButton, org.openide.util.NbBundle.getMessage(RevertModifications.class, &quot;CTL_UpdateForm_Action_Cancel&quot;)); // NOI18N
         cancelButton.getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getMessage(RevertModifications.class, &quot;ACSD_UpdateForm_Action_Cancel&quot;)); // NOI18N
         cancelButton.getAccessibleContext().setAccessibleName(org.openide.util.NbBundle.getMessage(RevertModifications.class, &quot;ACSN_UpdateForm_Action_Cancel&quot;)); // NOI18N
-    } 
-    
+    }
+
     public boolean showDialog() {
         DialogDescriptor dialogDescriptor;
         dialogDescriptor = new DialogDescriptor(panel, org.openide.util.NbBundle.getMessage(RevertModifications.class, &quot;CTL_UpdateDialog&quot;, repository.getName())); // NOI18N
         dialogDescriptor.setOptions(new Object[] {okButton, cancelButton});
-        
+
         dialogDescriptor.setModal(true);
         dialogDescriptor.setHelpCtx(new HelpCtx(this.getClass()));
         dialogDescriptor.setValid(false);
-        
-        Dialog dialog = DialogDisplayer.getDefault().createDialog(dialogDescriptor);     
+
+        Dialog dialog = DialogDisplayer.getDefault().createDialog(dialogDescriptor);
         dialog.getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getMessage(RevertModifications.class, &quot;ACSD_UpdateDialog&quot;, repository.getName())); // NOI18N
         dialog.setVisible(true);
         dialog.setResizable(false);
         boolean ret = dialogDescriptor.getValue() == okButton;
-        return ret;       
+        return ret;
     }
 
     public void propertyChange(PropertyChangeEvent evt) {
         if(okButton != null) {
             boolean valid = ((Boolean)evt.getNewValue()).booleanValue();
             okButton.setEnabled(valid);
-        }       
+        }
     }
 
     public String getSelectionRevision() {</diff>
      <filename>src/org/nbgit/ui/update/Update.java</filename>
    </modified>
    <modified>
      <diff>@@ -57,82 +57,82 @@ import org.openide.util.NbBundle;
 import org.openide.util.RequestProcessor;
 
 /**
- * Update action for Git: 
+ * Update action for Git:
  * git update - update or merge working directory
- * 
+ *
  * @author John Rice
  */
 public class UpdateAction extends ContextAction {
 
-	public UpdateAction(String name, VCSContext context)
-	{
-		super(name, context);
-	}
+    public UpdateAction(String name, VCSContext context)
+    {
+        super(name, context);
+    }
 
-	public void performAction(ActionEvent e)
-	{
-		update(context);
-	}
+    public void performAction(ActionEvent e)
+    {
+        update(context);
+    }
 
-	public static void update(final VCSContext ctx)
-	{
-		final File root = GitUtils.getRootFile(ctx);
-		if (root == null)
-			return;
-		String repository = root.getAbsolutePath();
-		String rev = null;
+    public static void update(final VCSContext ctx)
+    {
+        final File root = GitUtils.getRootFile(ctx);
+        if (root == null)
+            return;
+        String repository = root.getAbsolutePath();
+        String rev = null;
 
-		final Update update = new Update(root);
-		if (!update.showDialog())
-			return;
-		rev = update.getSelectionRevision();
-		final boolean doForcedUpdate = update.isForcedUpdateRequested();
-		final String revStr = rev;
+        final Update update = new Update(root);
+        if (!update.showDialog())
+            return;
+        rev = update.getSelectionRevision();
+        final boolean doForcedUpdate = update.isForcedUpdateRequested();
+        final String revStr = rev;
 
-		RequestProcessor rp = Git.getInstance().getRequestProcessor(repository);
-		GitProgressSupport support = new GitProgressSupport() {
+        RequestProcessor rp = Git.getInstance().getRequestProcessor(repository);
+        GitProgressSupport support = new GitProgressSupport() {
 
-			public void perform()
-			{
-				boolean bNoUpdates = true;
-				OutputLogger logger = getLogger();
+            public void perform()
+            {
+                boolean bNoUpdates = true;
+                OutputLogger logger = getLogger();
 
-				logger.outputInRed(
-						NbBundle.getMessage(UpdateAction.class,
-						&quot;MSG_UPDATE_TITLE&quot;)); // NOI18N
-					logger.outputInRed(
-						NbBundle.getMessage(UpdateAction.class,
-						&quot;MSG_UPDATE_TITLE_SEP&quot;)); // NOI18N
-					logger.output(
-						NbBundle.getMessage(UpdateAction.class,
-						&quot;MSG_UPDATE_INFO_SEP&quot;, revStr, root.getAbsolutePath())); // NOI18N
-					List&lt;String&gt; list = GitCommand.doUpdateAll(root, doForcedUpdate, revStr);
+                logger.outputInRed(
+                        NbBundle.getMessage(UpdateAction.class,
+                        &quot;MSG_UPDATE_TITLE&quot;)); // NOI18N
+                    logger.outputInRed(
+                        NbBundle.getMessage(UpdateAction.class,
+                        &quot;MSG_UPDATE_TITLE_SEP&quot;)); // NOI18N
+                    logger.output(
+                        NbBundle.getMessage(UpdateAction.class,
+                        &quot;MSG_UPDATE_INFO_SEP&quot;, revStr, root.getAbsolutePath())); // NOI18N
+                    List&lt;String&gt; list = GitCommand.doUpdateAll(root, doForcedUpdate, revStr);
 
-					if (list != null &amp;&amp; !list.isEmpty()) {
-						bNoUpdates = GitCommand.isNoUpdates(list.get(0));
-						//logger.clearOutput();
-						logger.output(list);
-						logger.output(&quot;&quot;); // NOI18N
-					}
-					// refresh filesystem to take account of changes
-					FileObject rootObj = FileUtil.toFileObject(root);
-					try {
-						rootObj.getFileSystem().refresh(true);
-					} catch (Exception ex) {
-					}
+                    if (list != null &amp;&amp; !list.isEmpty()) {
+                        bNoUpdates = GitCommand.isNoUpdates(list.get(0));
+                        //logger.clearOutput();
+                        logger.output(list);
+                        logger.output(&quot;&quot;); // NOI18N
+                    }
+                    // refresh filesystem to take account of changes
+                    FileObject rootObj = FileUtil.toFileObject(root);
+                    try {
+                        rootObj.getFileSystem().refresh(true);
+                    } catch (Exception ex) {
+                    }
 
-				// Force Status Refresh from this dir and below
-				if (!bNoUpdates)
-					GitUtils.forceStatusRefreshProject(ctx);
+                // Force Status Refresh from this dir and below
+                if (!bNoUpdates)
+                    GitUtils.forceStatusRefreshProject(ctx);
 
-				logger.outputInRed(
-					NbBundle.getMessage(UpdateAction.class,
-					&quot;MSG_UPDATE_DONE&quot;)); // NOI18N
-				logger.output(&quot;&quot;); // NOI18N
-			}
+                logger.outputInRed(
+                    NbBundle.getMessage(UpdateAction.class,
+                    &quot;MSG_UPDATE_DONE&quot;)); // NOI18N
+                logger.output(&quot;&quot;); // NOI18N
+            }
 
-		};
-		support.start(rp, repository, org.openide.util.NbBundle.getMessage(UpdateAction.class, &quot;MSG_Update_Progress&quot;)); // NOI18N
-	}
+        };
+        support.start(rp, repository, org.openide.util.NbBundle.getMessage(UpdateAction.class, &quot;MSG_Update_Progress&quot;)); // NOI18N
+    }
 
 }
\ No newline at end of file</diff>
      <filename>src/org/nbgit/ui/update/UpdateAction.java</filename>
    </modified>
    <modified>
      <diff>@@ -20,12 +20,12 @@
               &lt;Group type=&quot;103&quot; groupAlignment=&quot;0&quot; attributes=&quot;0&quot;&gt;
                   &lt;Component id=&quot;jPanel1&quot; alignment=&quot;0&quot; max=&quot;32767&quot; attributes=&quot;1&quot;/&gt;
                   &lt;Component id=&quot;jLabel2&quot; alignment=&quot;0&quot; min=&quot;-2&quot; max=&quot;-2&quot; attributes=&quot;0&quot;/&gt;
-                  &lt;Component id=&quot;jLabel1&quot; alignment=&quot;0&quot; pref=&quot;586&quot; max=&quot;32767&quot; attributes=&quot;0&quot;/&gt;
+                  &lt;Component id=&quot;jLabel1&quot; alignment=&quot;0&quot; pref=&quot;647&quot; max=&quot;32767&quot; attributes=&quot;0&quot;/&gt;
                   &lt;Group type=&quot;102&quot; alignment=&quot;0&quot; attributes=&quot;0&quot;&gt;
                       &lt;EmptySpace min=&quot;-2&quot; pref=&quot;36&quot; max=&quot;-2&quot; attributes=&quot;0&quot;/&gt;
                       &lt;Component id=&quot;revisionsLabel&quot; min=&quot;-2&quot; max=&quot;-2&quot; attributes=&quot;0&quot;/&gt;
                       &lt;EmptySpace max=&quot;-2&quot; attributes=&quot;0&quot;/&gt;
-                      &lt;Component id=&quot;revisionsComboBox&quot; pref=&quot;311&quot; max=&quot;32767&quot; attributes=&quot;0&quot;/&gt;
+                      &lt;Component id=&quot;revisionsComboBox&quot; pref=&quot;457&quot; max=&quot;32767&quot; attributes=&quot;0&quot;/&gt;
                   &lt;/Group&gt;
               &lt;/Group&gt;
               &lt;EmptySpace max=&quot;-2&quot; attributes=&quot;0&quot;/&gt;
@@ -92,7 +92,7 @@
       &lt;Properties&gt;
         &lt;Property name=&quot;border&quot; type=&quot;javax.swing.border.Border&quot; editor=&quot;org.netbeans.modules.form.editors2.BorderEditor&quot;&gt;
           &lt;Border info=&quot;org.netbeans.modules.form.compat2.border.TitledBorderInfo&quot;&gt;
-            &lt;TitledBorder title=&quot;&amp;lt;UpdatePanel.jPanel1.border.title&amp;gt;&quot;&gt;
+            &lt;TitledBorder title=&quot;Options&quot;&gt;
               &lt;ResourceString PropertyName=&quot;titleX&quot; bundle=&quot;org/nbgit/ui/update/Bundle.properties&quot; key=&quot;UpdatePanel.jPanel1.border.title&quot; replaceFormat=&quot;org.openide.util.NbBundle.getMessage({sourceFileName}.class, &amp;quot;{key}&amp;quot;)&quot;/&gt;
             &lt;/TitledBorder&gt;
           &lt;/Border&gt;</diff>
      <filename>src/org/nbgit/ui/update/UpdatePanel.form</filename>
    </modified>
    <modified>
      <diff>@@ -61,49 +61,49 @@ import org.openide.util.RequestProcessor;
  */
 public class UpdatePanel extends javax.swing.JPanel {
 
-	private File repository;
-	private List&lt;String[]&gt; revisionMap;
-	private RequestProcessor.Task refreshViewTask;
-	private static final RequestProcessor rp = new RequestProcessor(&quot;GitUpdate&quot;, 1);  // NOI18N
-	private Thread refreshViewThread;
-	private static final int GIT_REVERT_TARGET_LIMIT = 100;
-
-	/** Creates new form ReverModificationsPanel */
-	public UpdatePanel(File repo)
-	{
-		repository = repo;
-		refreshViewTask = rp.create(new RefreshViewTask());
-		initComponents();
-		refreshViewTask.schedule(0);
-	}
-
-	public String getSelectedRevision()
-	{
-		String revStr = (String) revisionsComboBox.getSelectedItem();
-		if (revStr != null)
-			if (revStr.equals(NbBundle.getMessage(RevertModificationsPanel.class, &quot;MSG_Revision_Default&quot;)) || // NOI18N
-				revStr.equals(NbBundle.getMessage(RevertModificationsPanel.class, &quot;MSG_Fetching_Revisions&quot;))) // NOI18N
-				revStr = null;
-			else if (revisionMap != null)
-				for (String[] entry : revisionMap) {
-					if (entry[0].equals(revStr)) {
-						revStr = entry[1];
-						break;
-					}
-				}
-		return revStr;
-	}
-
-	public boolean isForcedUpdateRequested()
-	{
-		return forcedUpdateChxBox.isSelected();
-	}
-
-	/** This method is called from within the constructor to
-	 * initialize the form.
-	 * WARNING: Do NOT modify this code. The content of this method is
-	 * always regenerated by the Form Editor.
-	 */
+    private File repository;
+    private List&lt;String[]&gt; revisionMap;
+    private RequestProcessor.Task refreshViewTask;
+    private static final RequestProcessor rp = new RequestProcessor(&quot;GitUpdate&quot;, 1);  // NOI18N
+    private Thread refreshViewThread;
+    private static final int GIT_REVERT_TARGET_LIMIT = 100;
+
+    /** Creates new form ReverModificationsPanel */
+    public UpdatePanel(File repo)
+    {
+        repository = repo;
+        refreshViewTask = rp.create(new RefreshViewTask());
+        initComponents();
+        refreshViewTask.schedule(0);
+    }
+
+    public String getSelectedRevision()
+    {
+        String revStr = (String) revisionsComboBox.getSelectedItem();
+        if (revStr != null)
+            if (revStr.equals(NbBundle.getMessage(RevertModificationsPanel.class, &quot;MSG_Revision_Default&quot;)) || // NOI18N
+                revStr.equals(NbBundle.getMessage(RevertModificationsPanel.class, &quot;MSG_Fetching_Revisions&quot;))) // NOI18N
+                revStr = null;
+            else if (revisionMap != null)
+                for (String[] entry : revisionMap) {
+                    if (entry[0].equals(revStr)) {
+                        revStr = entry[1];
+                        break;
+                    }
+                }
+        return revStr;
+    }
+
+    public boolean isForcedUpdateRequested()
+    {
+        return forcedUpdateChxBox.isSelected();
+    }
+
+    /** This method is called from within the constructor to
+     * initialize the form.
+     * WARNING: Do NOT modify this code. The content of this method is
+     * always regenerated by the Form Editor.
+     */
     // &lt;editor-fold defaultstate=&quot;collapsed&quot; desc=&quot;Generated Code&quot;&gt;//GEN-BEGIN:initComponents
     private void initComponents() {
 
@@ -176,64 +176,64 @@ public class UpdatePanel extends javax.swing.JPanel {
         );
     }// &lt;/editor-fold&gt;//GEN-END:initComponents
 
-	/**
-	 * Must NOT be run from AWT.
-	 */
-	private void setupModels()
-	{
-		// XXX attach Cancelable hook
-		final ProgressHandle ph = ProgressHandleFactory.createHandle(NbBundle.getMessage(RevertModificationsPanel.class, &quot;MSG_Refreshing_Update_Versions&quot;)); // NOI18N
-		try {
-			Set&lt;String&gt; initialRevsSet = new LinkedHashSet&lt;String&gt;();
-			initialRevsSet.add(NbBundle.getMessage(RevertModificationsPanel.class, &quot;MSG_Fetching_Revisions&quot;)); // NOI18N
-			ComboBoxModel targetsModel = new DefaultComboBoxModel(new Vector&lt;String&gt;(initialRevsSet));
-			revisionsComboBox.setModel(targetsModel);
-			refreshViewThread = Thread.currentThread();
-			Thread.interrupted();  // clear interupted status
-			ph.start();
-
-			refreshRevisions();
-		} finally {
-			SwingUtilities.invokeLater(new Runnable() {
-
-				public void run()
-				{
-					ph.finish();
-					refreshViewThread = null;
-				}
-
-			});
-		}
-	}
-
-	private void refreshRevisions()
-	{
-		revisionMap = GitCommand.getRevisions(repository, GIT_REVERT_TARGET_LIMIT);
-
-		Set&lt;String&gt; targetRevsSet = new LinkedHashSet&lt;String&gt;();
-
-		if (revisionMap == null)
-			targetRevsSet.add(NbBundle.getMessage(RevertModificationsPanel.class, &quot;MSG_Revision_Default&quot;));
-		else
-			for (String[] entry : revisionMap) {
-				targetRevsSet.add(entry[0]);
-			}
-
-		ComboBoxModel targetsModel = new DefaultComboBoxModel(new Vector&lt;String&gt;(targetRevsSet));
-		revisionsComboBox.setModel(targetsModel);
-
-		if (targetRevsSet.size() &gt; 0)
-			revisionsComboBox.setSelectedIndex(0);
-	}
-
-	private class RefreshViewTask implements Runnable {
-
-		public void run()
-		{
-			setupModels();
-		}
-
-	}
+    /**
+     * Must NOT be run from AWT.
+     */
+    private void setupModels()
+    {
+        // XXX attach Cancelable hook
+        final ProgressHandle ph = ProgressHandleFactory.createHandle(NbBundle.getMessage(RevertModificationsPanel.class, &quot;MSG_Refreshing_Update_Versions&quot;)); // NOI18N
+        try {
+            Set&lt;String&gt; initialRevsSet = new LinkedHashSet&lt;String&gt;();
+            initialRevsSet.add(NbBundle.getMessage(RevertModificationsPanel.class, &quot;MSG_Fetching_Revisions&quot;)); // NOI18N
+            ComboBoxModel targetsModel = new DefaultComboBoxModel(new Vector&lt;String&gt;(initialRevsSet));
+            revisionsComboBox.setModel(targetsModel);
+            refreshViewThread = Thread.currentThread();
+            Thread.interrupted();  // clear interupted status
+            ph.start();
+
+            refreshRevisions();
+        } finally {
+            SwingUtilities.invokeLater(new Runnable() {
+
+                public void run()
+                {
+                    ph.finish();
+                    refreshViewThread = null;
+                }
+
+            });
+        }
+    }
+
+    private void refreshRevisions()
+    {
+        revisionMap = GitCommand.getRevisions(repository, GIT_REVERT_TARGET_LIMIT);
+
+        Set&lt;String&gt; targetRevsSet = new LinkedHashSet&lt;String&gt;();
+
+        if (revisionMap == null)
+            targetRevsSet.add(NbBundle.getMessage(RevertModificationsPanel.class, &quot;MSG_Revision_Default&quot;));
+        else
+            for (String[] entry : revisionMap) {
+                targetRevsSet.add(entry[0]);
+            }
+
+        ComboBoxModel targetsModel = new DefaultComboBoxModel(new Vector&lt;String&gt;(targetRevsSet));
+        revisionsComboBox.setModel(targetsModel);
+
+        if (targetRevsSet.size() &gt; 0)
+            revisionsComboBox.setSelectedIndex(0);
+    }
+
+    private class RefreshViewTask implements Runnable {
+
+        public void run()
+        {
+            setupModels();
+        }
+
+    }
 
     // Variables declaration - do not modify//GEN-BEGIN:variables
     private javax.swing.JCheckBox forcedUpdateChxBox;</diff>
      <filename>src/org/nbgit/ui/update/UpdatePanel.java</filename>
    </modified>
    <modified>
      <diff>@@ -81,570 +81,570 @@ import org.spearce.jgit.treewalk.filter.PathFilterGroup;
  */
 public class GitCommand {
 
-	public static void deleteConflictFile(String absolutePath)
-	{
-		// boolean success = (new File(path + GIT_STR_CONFLICT_EXT)).delete();
-		throw new UnsupportedOperationException(&quot;Not yet implemented&quot;);
-	}
-
-	static public void doAdd(File root, List&lt;File&gt; addCandidates, OutputLogger logger)
-	{
-		try {
-			Repository repo = Git.getInstance().getRepository(root);
-			GitIndex index = repo.getIndex();
-
-			for (File dstFile : addCandidates) {
-				Entry entry = index.add(root, dstFile);
-				entry.setAssumeValid(false);
-			}
-
-			index.write();
-
-		} catch (Exception ex) {
-			logger.output(ex.getMessage());
-		}
-	}
-
-	public static void doAdd(File root, File dstFile, OutputLogger logger)
-	{
-		try {
-			Repository repo = Git.getInstance().getRepository(root);
-			GitIndex index = repo.getIndex();
-			Entry entry = index.add(root, dstFile);
-
-			entry.setAssumeValid(false);
-			index.write();
-
-		} catch (Exception ex) {
-			logger.output(ex.getMessage());
-		}
-	}
-
-	public static void doCat(File root, File base, File tempFile, String revision)
-	{
-		OutputLogger logger = Git.getInstance().getLogger(root.getAbsolutePath());
-		try {
-			Repository repo = Git.getInstance().getRepository(root);
-			Commit commit = repo.mapCommit(revision);
-
-			if (commit == null) {
-				logger.output(&quot;Revision &quot; + revision + &quot; not found&quot;);
-				return;
-			}
-
-			String relative = toGitPath(getRelative(root, base));
-
-			ObjectId[] ids = { commit.getTree().getId() };
-			TreeWalk walk = TreeWalk.forPath(repo, relative, ids);
-
-			ObjectId blobId = walk.getObjectId(0);
-
-			ObjectLoader blob = repo.openBlob(blobId);
-			if (blob == null) {
-				logger.output(&quot;Failed to open blob &quot; + blobId);
-				return;
-			}
-
-			FileOutputStream out = new FileOutputStream(tempFile);
-			out.write(blob.getCachedBytes());
-
-			out.close();
-
-		} catch (Exception ex) {
-			// FIXME: Do unload, delete, ... here
-			logger.output(ex.getMessage());
-		}
-	}
-
-	public static void doRevert(File root, List&lt;File&gt; files, String revStr, boolean doBackup, OutputLogger logger)
-	{
-		Repository repo = Git.getInstance().getRepository(root);
-
-		try {
-			GitIndex index = new GitIndex(repo);
-			Tree tree = repo.mapTree(revStr);
-			index.readTree(tree);
-
-			for (File file : files) {
-				String path = getRelative(root, file);
-				Entry entry = index.getEntry(path);
-
-				if (entry == null)
-					continue;
-				if (doBackup)
-					file.renameTo(new File(file.getAbsolutePath() + &quot;.orig&quot;));
-				index.checkoutEntry(root, entry);
-			}
-
-		} catch (IOException ex) {
-		}
-	}
-
-	public static List&lt;String&gt; doUpdateAll(File root, boolean doForcedUpdate, String revStr)
-	{
-		throw new UnsupportedOperationException(&quot;Not yet implemented&quot;);
-	}
-
-	public static RepositoryRevision.Walk getLogMessages(String rootPath, Set&lt;File&gt; files, String fromRevision, String toRevision, boolean showMerges, OutputLogger logger)
-	{
-		File root = new File(rootPath);
-		Repository repo = Git.getInstance().getRepository(root);
-		RepositoryRevision.Walk walk = new RepositoryRevision.Walk(repo);
-
-		try {
-			if (fromRevision == null)
-				fromRevision = Constants.HEAD;
-			ObjectId from = repo.resolve(fromRevision);
-			if (from == null)
-				return null;
-			walk.markStart(walk.parseCommit(from));
-			ObjectId to = toRevision != null ? repo.resolve(toRevision) : null;
-			if (to != null)
-				walk.markUninteresting(walk.parseCommit(to));
-
-			List&lt;PathFilter&gt; paths = new ArrayList&lt;PathFilter&gt;();
-			for (File file : files) {
-				String path = getRelative(root, file);
-
-				if (!(path.length() == 0))
-					paths.add(PathFilter.create(path));
-			}
-
-			if (!paths.isEmpty())
-				walk.setTreeFilter(PathFilterGroup.create(paths));
-			if (!showMerges)
-				walk.setRevFilter(RevFilter.NO_MERGES);
-
-		} catch (IOException ioe) {
-			return null;
-		}
-
-		return walk;
-	}
-
-	public static boolean isNoUpdates(String get)
-	{
-		throw new UnsupportedOperationException(&quot;Not yet implemented&quot;);
-	}
-
-	private static String buildReflogMessage(String commitMessage)
-	{
-		String firstLine = commitMessage;
-		int newlineIndex = commitMessage.indexOf(&quot;\n&quot;);
-
-		if (newlineIndex &gt; 0)
-			firstLine = commitMessage.substring(0, newlineIndex);
-		return &quot;\tcommit: &quot; + firstLine;
-	}
-
-	private static void prepareTrees(File root, List&lt;File&gt; selectedItems,
-		HashMap&lt;Repository, Tree&gt; treeMap)
-		throws IOException, UnsupportedEncodingException
-	{
-		Repository repo = Git.getInstance().getRepository(root);
-
-		for (File file : selectedItems) {
-			Tree projTree = treeMap.get(repo);
-			if (projTree == null) {
-				projTree = repo.mapTree(&quot;HEAD&quot;);
-				if (projTree == null)
-					projTree = new Tree(repo);
-				treeMap.put(repo, projTree);
-				System.out.println(&quot;Orig tree id: &quot; + projTree.getId());
-			}
-
-			GitIndex index = repo.getIndex();
-			String repoRelativePath = getRelative(root, file);
-			String string = repoRelativePath;
-
-			TreeEntry treeMember = projTree.findBlobMember(repoRelativePath);
-			// we always want to delete it from the current tree, since if it's
-			// updated, we'll add it again
-			if (treeMember != null)
-				treeMember.delete();
-			Entry idxEntry = index.getEntry(string);
-			if (true /* if modified on disk or missing */) {
-				if (!file.isFile()) {
-					index.remove(root, file);
-					index.write();
-					System.out.println(&quot;Phantom file, so removing from index&quot;);
-					continue;
-				}
-
-				if (idxEntry.update(file))
-					index.write();
-			}
-
-			if (idxEntry != null) {
-				projTree.addFile(repoRelativePath);
-				TreeEntry newMember = projTree.findBlobMember(repoRelativePath);
-
-				newMember.setId(idxEntry.getObjectId());
-				System.out.println(&quot;New member id for &quot; + repoRelativePath + &quot;: &quot; + newMember.getId() + &quot; idx id: &quot; + idxEntry.getObjectId());
-			}
-		}
-	}
-
-	private static void writeTreeWithSubTrees(Tree tree) throws IOException
-	{
-		if (tree.getId() == null) {
-			System.out.println(&quot;writing tree for: &quot; + tree.getFullName());
-
-			for (TreeEntry entry : tree.members()) {
-				if (entry.isModified())
-					if (entry instanceof Tree)
-						writeTreeWithSubTrees((Tree) entry);
-					else
-						System.out.println(&quot;BAD JUJU: &quot; + entry.getFullName());
-			}
-			ObjectWriter writer = new ObjectWriter(tree.getRepository());
-			tree.setId(writer.writeTree(tree));
-		}
-	}
-
-	public static void doCommit(File root, List&lt;File&gt; commitCandidates, String message, OutputLogger logger) throws IOException
-	{
-		HashMap&lt;Repository, Tree&gt; treeMap = new HashMap&lt;Repository, Tree&gt;();
-
-		prepareTrees(root, commitCandidates, treeMap);
-
-		for (java.util.Map.Entry&lt;Repository, Tree&gt; entry : treeMap.entrySet()) {
-
-			Tree tree = entry.getValue();
-			Repository repo = tree.getRepository();
-			PersonIdent personIdent = new PersonIdent(repo);
-
-			writeTreeWithSubTrees(tree);
-
-			final RefUpdate ru = repo.updateRef(Constants.HEAD);
-			ObjectId[] parentIds;
-			if (ru.getOldObjectId() != null)
-				parentIds = new ObjectId[] { ru.getOldObjectId() };
-			else
-				parentIds = new ObjectId[0];
-			Commit commit = new Commit(repo, parentIds);
-			commit.setTree(tree);
-			message = message.replaceAll(&quot;\r&quot;, &quot;\n&quot;);
-
-			commit.setMessage(message);
-			commit.setAuthor(personIdent);
-			commit.setCommitter(personIdent);
-
-			ObjectWriter writer = new ObjectWriter(repo);
-			commit.setCommitId(writer.writeCommit(commit));
-
-			ru.setNewObjectId(commit.getCommitId());
-			ru.setRefLogMessage(buildReflogMessage(message), false);
-			ru.update();
-			boolean ok;
-			if (ru.getOldObjectId() != null)
-				ok = ru.getResult() == RefUpdate.Result.FAST_FORWARD;
-			else
-				ok = ru.getResult() == RefUpdate.Result.NEW;
-
-			if (!ok)
-				logger.output(&quot;Failed to update &quot; + ru.getName() + &quot; to commit &quot; + commit.getCommitId() + &quot;.&quot;);
-		}
-	}
-
-	public static void doRemove(File root, List&lt;File&gt; deleteCandidates, OutputLogger logger)
-	{
-		try {
-			Repository repo = Git.getInstance().getRepository(root);
-			GitIndex index = repo.getIndex();
-			boolean dirty = false;
-
-			for (File srcFile : deleteCandidates) {
-				if (index.remove(root, srcFile))
-					dirty = true;
-			}
-
-			if (dirty)
-				index.write();
-		} catch (Exception ex) {
-			logger.output(ex.getMessage());
-		}
-
-	}
-
-	public static void doRemove(File root, File srcFile, OutputLogger logger)
-	{
-		try {
-			Repository repo = Git.getInstance().getRepository(root);
-			GitIndex index = repo.getIndex();
-
-			if (index.remove(root, srcFile))
-				index.write();
-		} catch (Exception ex) {
-			logger.output(ex.getMessage());
-		}
-
-	}
-
-	public static void doRenameAfter(File root, File srcFile, File dstFile, OutputLogger logger)
-	{
-		throw new UnsupportedOperationException(&quot;Not yet implemented&quot;);
-	}
-
-	public static List&lt;String[]&gt; getRevisions(File root, int limit)
-	{
-		return getRevisionsForFile(root, null, limit);
-	}
-
-	public static List&lt;String[]&gt; getRevisionsForFile(File root, File[] files, int limit)
-	{
-		Repository repo = Git.getInstance().getRepository(root);
-		RevWalk walk = new RevWalk(repo);
-		List&lt;String[]&gt; revs = new ArrayList&lt;String[]&gt;();
-
-		try {
-			ObjectId from = repo.resolve(Constants.HEAD);
-			if (from == null)
-				return null;
-			walk.markStart(walk.parseCommit(from));
-
-			if (files != null) {
-				List&lt;PathFilter&gt; paths = new ArrayList&lt;PathFilter&gt;();
-				for (File file : files) {
-					String path = getRelative(root, file);
-
-					if (!(path.length() == 0))
-						paths.add(PathFilter.create(path));
-				}
-
-				if (!paths.isEmpty())
-					walk.setTreeFilter(PathFilterGroup.create(paths));
-			}
-
-			for (RevCommit rev : walk) {
-				revs.add(new String[] { rev.getShortMessage(), rev.getId().toString() });
-				if (--limit &lt;= 0)
-					break;
-			}
-
-		} catch (IOException ioe) {
-		}
-
-		return revs;
-	}
-
-	private static String getRelative(File root, File dir)
-	{
-		return getRelative(root.getAbsolutePath(), dir.getAbsolutePath());
-	}
-
-	private static String getRelative(String root, String dir)
-	{
-		if (dir.equals(root))
-			return &quot;&quot;;
-		return dir.replace(root + File.separator, &quot;&quot;);
-	}
-
-	private static String toGitPath(String path)
-	{
-		return File.separatorChar == '/'
-			? path : path.replace(File.separator, &quot;/&quot;);
-	}
-
-	private static void put(Set&lt;String&gt; set, String relPath,
-		Map&lt;File, StatusInfo&gt; files, File root, int status)
-	{
-		for (String path : set) {
-			if (relPath.length() &gt; 0 &amp;&amp; !path.startsWith(relPath))
-				continue;
-			File file = new File(root, path);
-			files.put(file, new StatusInfo(status, null, false));
-		}
-
-	}
-
-	/*
-	 * m odified
-	 * a dded
-	 * r emoved
-	 * d eleted
-	 * u nknown
-	 * C opies
-	 *
-	 * i gnored
-	 * c lean
-	 */
-	public static Map&lt;File, StatusInfo&gt; getAllStatus(File root, File dir) throws IOException
-	{
-		String relPath = getRelative(root, dir);
-		OutputLogger logger = Git.getInstance().getLogger(root.getAbsolutePath());
-
-		Repository repo = Git.getInstance().getRepository(root);
-		Map&lt;File, StatusInfo&gt; files = new HashMap&lt;File, StatusInfo&gt;();
-
-		try {
-			repo.refreshFromDisk();
-			IndexDiff index = new IndexDiff(repo);
-			index.diff();
-
-			put(index.getAdded(), relPath, files, root,
-				StatusInfo.STATUS_VERSIONED_ADDEDLOCALLY);
-			put(index.getRemoved(), relPath, files, root,
-				StatusInfo.STATUS_VERSIONED_REMOVEDLOCALLY);
-			put(index.getMissing(), relPath, files, root,
-				StatusInfo.STATUS_VERSIONED_DELETEDLOCALLY);
-			put(index.getChanged(), relPath, files, root,
-				StatusInfo.STATUS_VERSIONED_MODIFIEDLOCALLY);
-			put(index.getModified(), relPath, files, root,
-				StatusInfo.STATUS_VERSIONED_MODIFIEDLOCALLY);
-
-			final FileTreeIterator workTree = new FileTreeIterator(repo.getWorkDir());
-			final TreeWalk walk = new TreeWalk(repo);
-
-			walk.reset(); // drop the first empty tree
-			walk.setRecursive(true);
-			walk.addTree(workTree);
-
-			int share = SharabilityQuery.getSharability(dir);
-			if (share == SharabilityQuery.NOT_SHARABLE)
-				return files;
-
-			while (walk.next()) {
-				String path = walk.getPathString();
-
-				if (relPath.length() &gt; 0 &amp;&amp; !path.startsWith(relPath))
-					continue;
-				if (index.getAdded().contains(path) ||
-					index.getRemoved().contains(path) ||
-					index.getMissing().contains(path) ||
-					index.getChanged().contains(path) ||
-					index.getModified().contains(path))
-					continue;
-				Entry entry = repo.getIndex().getEntry(path);
-				File file = new File(root, path);
-
-				int status;
-				if (entry != null)
-					status = StatusInfo.STATUS_VERSIONED_UPTODATE;
-				else {
-					if (share == SharabilityQuery.MIXED &amp;&amp;
-						SharabilityQuery.getSharability(file) == SharabilityQuery.NOT_SHARABLE)
-						continue;
-
-					status = StatusInfo.STATUS_NOTVERSIONED_NEWLOCALLY;
-				}
-
-				files.put(file, new StatusInfo(status, null, false));
-			}
-
-		} catch (IOException ex) {
-			Exceptions.printStackTrace(ex);
-		}
-
-		return files;
-	}
-
-	/*
-	 * m odified
-	 * a dded
-	 * r emoved
-	 * d eleted
-	 * u nknown
-	 * C opies
-	 */
-	public static Map&lt;File, StatusInfo&gt; getInterestingStatus(File root, File dir)
-	{
-		String relPath = getRelative(root, dir);
-
-		Repository repo = Git.getInstance().getRepository(root);
-		IndexDiff index;
-
-		Map&lt;File, StatusInfo&gt; files = new HashMap&lt;File, StatusInfo&gt;();
-
-		try {
-			repo.refreshFromDisk();
-			index = new IndexDiff(repo);
-			index.diff();
-
-			put(index.getAdded(), relPath, files, root,
-				StatusInfo.STATUS_VERSIONED_ADDEDLOCALLY);
-			put(index.getRemoved(), relPath, files, root,
-				StatusInfo.STATUS_VERSIONED_REMOVEDLOCALLY);
-			put(index.getMissing(), relPath, files, root,
-				StatusInfo.STATUS_VERSIONED_DELETEDLOCALLY);
-			put(index.getChanged(), relPath, files, root,
-				StatusInfo.STATUS_VERSIONED_MODIFIEDLOCALLY);
-			put(index.getModified(), relPath, files, root,
-				StatusInfo.STATUS_VERSIONED_MODIFIEDLOCALLY);
-
-			final FileTreeIterator workTree = new FileTreeIterator(repo.getWorkDir());
-			final TreeWalk walk = new TreeWalk(repo);
-
-			walk.reset(); // drop the first empty tree
-			walk.setRecursive(true);
-			walk.addTree(workTree);
-
-			while (walk.next()) {
-				String path = walk.getPathString();
-
-				if (relPath.length() &gt; 0 &amp;&amp; !path.startsWith(relPath))
-					continue;
-				if (index.getAdded().contains(path) ||
-					index.getRemoved().contains(path) ||
-					index.getMissing().contains(path) ||
-					index.getChanged().contains(path) ||
-					index.getModified().contains(path))
-					continue;
-				Entry entry = repo.getIndex().getEntry(path);
-				if (entry != null)
-					continue;
-				int status = StatusInfo.STATUS_NOTVERSIONED_NEWLOCALLY;
-				File file = new File(root, path);
-				files.put(file, new StatusInfo(status, null, false));
-			}
-
-		} catch (IOException ex) {
-			Exceptions.printStackTrace(ex);
-		}
-
-		return files;
-	}
-
-	public static StatusInfo getSingleStatus(File root, File file)
-	{
-		OutputLogger logger = Git.getInstance().getLogger(root.getAbsolutePath());
-		Repository repo = Git.getInstance().getRepository(root);
-		IndexDiff index;
-
-		int share = SharabilityQuery.getSharability(file.getParentFile());
-		if (share == SharabilityQuery.NOT_SHARABLE ||
-			(share == SharabilityQuery.MIXED &amp;&amp;
-			SharabilityQuery.getSharability(file) == SharabilityQuery.NOT_SHARABLE))
-			return new StatusInfo(StatusInfo.STATUS_NOTVERSIONED_EXCLUDED, null, false);
-
-		int status = StatusInfo.STATUS_UNKNOWN;
-		String name = getRelative(root, file);
-
-		try {
-			repo.refreshFromDisk();
-			index = new IndexDiff(repo);
-			index.diff();
-		} catch (IOException ex) {
-			Exceptions.printStackTrace(ex);
-			return new StatusInfo(status, null, false);
-		}
-
-		if (index.getAdded().contains(name))
-			status = StatusInfo.STATUS_VERSIONED_ADDEDLOCALLY;
-		else if (index.getRemoved().contains(name))
-			status = StatusInfo.STATUS_VERSIONED_REMOVEDLOCALLY;
-		else if (index.getMissing().contains(name))
-			status = StatusInfo.STATUS_VERSIONED_DELETEDLOCALLY;
-		else if (index.getChanged().contains(name))
-			status = StatusInfo.STATUS_VERSIONED_MODIFIEDLOCALLY;
-		else if (index.getModified().contains(name))
-			status = StatusInfo.STATUS_VERSIONED_MODIFIEDLOCALLY;
-		else
-			status = StatusInfo.STATUS_VERSIONED_UPTODATE;
-		StatusInfo info = new StatusInfo(status, null, false);
-
-		return info;
-	}
+    public static void deleteConflictFile(String absolutePath)
+    {
+        // boolean success = (new File(path + GIT_STR_CONFLICT_EXT)).delete();
+        throw new UnsupportedOperationException(&quot;Not yet implemented&quot;);
+    }
+
+    static public void doAdd(File root, List&lt;File&gt; addCandidates, OutputLogger logger)
+    {
+        try {
+            Repository repo = Git.getInstance().getRepository(root);
+            GitIndex index = repo.getIndex();
+
+            for (File dstFile : addCandidates) {
+                Entry entry = index.add(root, dstFile);
+                entry.setAssumeValid(false);
+            }
+
+            index.write();
+
+        } catch (Exception ex) {
+            logger.output(ex.getMessage());
+        }
+    }
+
+    public static void doAdd(File root, File dstFile, OutputLogger logger)
+    {
+        try {
+            Repository repo = Git.getInstance().getRepository(root);
+            GitIndex index = repo.getIndex();
+            Entry entry = index.add(root, dstFile);
+
+            entry.setAssumeValid(false);
+            index.write();
+
+        } catch (Exception ex) {
+            logger.output(ex.getMessage());
+        }
+    }
+
+    public static void doCat(File root, File base, File tempFile, String revision)
+    {
+        OutputLogger logger = Git.getInstance().getLogger(root.getAbsolutePath());
+        try {
+            Repository repo = Git.getInstance().getRepository(root);
+            Commit commit = repo.mapCommit(revision);
+
+            if (commit == null) {
+                logger.output(&quot;Revision &quot; + revision + &quot; not found&quot;);
+                return;
+            }
+
+            String relative = toGitPath(getRelative(root, base));
+
+            ObjectId[] ids = { commit.getTree().getId() };
+            TreeWalk walk = TreeWalk.forPath(repo, relative, ids);
+
+            ObjectId blobId = walk.getObjectId(0);
+
+            ObjectLoader blob = repo.openBlob(blobId);
+            if (blob == null) {
+                logger.output(&quot;Failed to open blob &quot; + blobId);
+                return;
+            }
+
+            FileOutputStream out = new FileOutputStream(tempFile);
+            out.write(blob.getCachedBytes());
+
+            out.close();
+
+        } catch (Exception ex) {
+            // FIXME: Do unload, delete, ... here
+            logger.output(ex.getMessage());
+        }
+    }
+
+    public static void doRevert(File root, List&lt;File&gt; files, String revStr, boolean doBackup, OutputLogger logger)
+    {
+        Repository repo = Git.getInstance().getRepository(root);
+
+        try {
+            GitIndex index = new GitIndex(repo);
+            Tree tree = repo.mapTree(revStr);
+            index.readTree(tree);
+
+            for (File file : files) {
+                String path = getRelative(root, file);
+                Entry entry = index.getEntry(path);
+
+                if (entry == null)
+                    continue;
+                if (doBackup)
+                    file.renameTo(new File(file.getAbsolutePath() + &quot;.orig&quot;));
+                index.checkoutEntry(root, entry);
+            }
+
+        } catch (IOException ex) {
+        }
+    }
+
+    public static List&lt;String&gt; doUpdateAll(File root, boolean doForcedUpdate, String revStr)
+    {
+        throw new UnsupportedOperationException(&quot;Not yet implemented&quot;);
+    }
+
+    public static RepositoryRevision.Walk getLogMessages(String rootPath, Set&lt;File&gt; files, String fromRevision, String toRevision, boolean showMerges, OutputLogger logger)
+    {
+        File root = new File(rootPath);
+        Repository repo = Git.getInstance().getRepository(root);
+        RepositoryRevision.Walk walk = new RepositoryRevision.Walk(repo);
+
+        try {
+            if (fromRevision == null)
+                fromRevision = Constants.HEAD;
+            ObjectId from = repo.resolve(fromRevision);
+            if (from == null)
+                return null;
+            walk.markStart(walk.parseCommit(from));
+            ObjectId to = toRevision != null ? repo.resolve(toRevision) : null;
+            if (to != null)
+                walk.markUninteresting(walk.parseCommit(to));
+
+            List&lt;PathFilter&gt; paths = new ArrayList&lt;PathFilter&gt;();
+            for (File file : files) {
+                String path = getRelative(root, file);
+
+                if (!(path.length() == 0))
+                    paths.add(PathFilter.create(path));
+            }
+
+            if (!paths.isEmpty())
+                walk.setTreeFilter(PathFilterGroup.create(paths));
+            if (!showMerges)
+                walk.setRevFilter(RevFilter.NO_MERGES);
+
+        } catch (IOException ioe) {
+            return null;
+        }
+
+        return walk;
+    }
+
+    public static boolean isNoUpdates(String get)
+    {
+        throw new UnsupportedOperationException(&quot;Not yet implemented&quot;);
+    }
+
+    private static String buildReflogMessage(String commitMessage)
+    {
+        String firstLine = commitMessage;
+        int newlineIndex = commitMessage.indexOf(&quot;\n&quot;);
+
+        if (newlineIndex &gt; 0)
+            firstLine = commitMessage.substring(0, newlineIndex);
+        return &quot;\tcommit: &quot; + firstLine;
+    }
+
+    private static void prepareTrees(File root, List&lt;File&gt; selectedItems,
+        HashMap&lt;Repository, Tree&gt; treeMap)
+        throws IOException, UnsupportedEncodingException
+    {
+        Repository repo = Git.getInstance().getRepository(root);
+
+        for (File file : selectedItems) {
+            Tree projTree = treeMap.get(repo);
+            if (projTree == null) {
+                projTree = repo.mapTree(&quot;HEAD&quot;);
+                if (projTree == null)
+                    projTree = new Tree(repo);
+                treeMap.put(repo, projTree);
+                System.out.println(&quot;Orig tree id: &quot; + projTree.getId());
+            }
+
+            GitIndex index = repo.getIndex();
+            String repoRelativePath = getRelative(root, file);
+            String string = repoRelativePath;
+
+            TreeEntry treeMember = projTree.findBlobMember(repoRelativePath);
+            // we always want to delete it from the current tree, since if it's
+            // updated, we'll add it again
+            if (treeMember != null)
+                treeMember.delete();
+            Entry idxEntry = index.getEntry(string);
+            if (true /* if modified on disk or missing */) {
+                if (!file.isFile()) {
+                    index.remove(root, file);
+                    index.write();
+                    System.out.println(&quot;Phantom file, so removing from index&quot;);
+                    continue;
+                }
+
+                if (idxEntry.update(file))
+                    index.write();
+            }
+
+            if (idxEntry != null) {
+                projTree.addFile(repoRelativePath);
+                TreeEntry newMember = projTree.findBlobMember(repoRelativePath);
+
+                newMember.setId(idxEntry.getObjectId());
+                System.out.println(&quot;New member id for &quot; + repoRelativePath + &quot;: &quot; + newMember.getId() + &quot; idx id: &quot; + idxEntry.getObjectId());
+            }
+        }
+    }
+
+    private static void writeTreeWithSubTrees(Tree tree) throws IOException
+    {
+        if (tree.getId() == null) {
+            System.out.println(&quot;writing tree for: &quot; + tree.getFullName());
+
+            for (TreeEntry entry : tree.members()) {
+                if (entry.isModified())
+                    if (entry instanceof Tree)
+                        writeTreeWithSubTrees((Tree) entry);
+                    else
+                        System.out.println(&quot;BAD JUJU: &quot; + entry.getFullName());
+            }
+            ObjectWriter writer = new ObjectWriter(tree.getRepository());
+            tree.setId(writer.writeTree(tree));
+        }
+    }
+
+    public static void doCommit(File root, List&lt;File&gt; commitCandidates, String message, OutputLogger logger) throws IOException
+    {
+        HashMap&lt;Repository, Tree&gt; treeMap = new HashMap&lt;Repository, Tree&gt;();
+
+        prepareTrees(root, commitCandidates, treeMap);
+
+        for (java.util.Map.Entry&lt;Repository, Tree&gt; entry : treeMap.entrySet()) {
+
+            Tree tree = entry.getValue();
+            Repository repo = tree.getRepository();
+            PersonIdent personIdent = new PersonIdent(repo);
+
+            writeTreeWithSubTrees(tree);
+
+            final RefUpdate ru = repo.updateRef(Constants.HEAD);
+            ObjectId[] parentIds;
+            if (ru.getOldObjectId() != null)
+                parentIds = new ObjectId[] { ru.getOldObjectId() };
+            else
+                parentIds = new ObjectId[0];
+            Commit commit = new Commit(repo, parentIds);
+            commit.setTree(tree);
+            message = message.replaceAll(&quot;\r&quot;, &quot;\n&quot;);
+
+            commit.setMessage(message);
+            commit.setAuthor(personIdent);
+            commit.setCommitter(personIdent);
+
+            ObjectWriter writer = new ObjectWriter(repo);
+            commit.setCommitId(writer.writeCommit(commit));
+
+            ru.setNewObjectId(commit.getCommitId());
+            ru.setRefLogMessage(buildReflogMessage(message), false);
+            ru.update();
+            boolean ok;
+            if (ru.getOldObjectId() != null)
+                ok = ru.getResult() == RefUpdate.Result.FAST_FORWARD;
+            else
+                ok = ru.getResult() == RefUpdate.Result.NEW;
+
+            if (!ok)
+                logger.output(&quot;Failed to update &quot; + ru.getName() + &quot; to commit &quot; + commit.getCommitId() + &quot;.&quot;);
+        }
+    }
+
+    public static void doRemove(File root, List&lt;File&gt; deleteCandidates, OutputLogger logger)
+    {
+        try {
+            Repository repo = Git.getInstance().getRepository(root);
+            GitIndex index = repo.getIndex();
+            boolean dirty = false;
+
+            for (File srcFile : deleteCandidates) {
+                if (index.remove(root, srcFile))
+                    dirty = true;
+            }
+
+            if (dirty)
+                index.write();
+        } catch (Exception ex) {
+            logger.output(ex.getMessage());
+        }
+
+    }
+
+    public static void doRemove(File root, File srcFile, OutputLogger logger)
+    {
+        try {
+            Repository repo = Git.getInstance().getRepository(root);
+            GitIndex index = repo.getIndex();
+
+            if (index.remove(root, srcFile))
+                index.write();
+        } catch (Exception ex) {
+            logger.output(ex.getMessage());
+        }
+
+    }
+
+    public static void doRenameAfter(File root, File srcFile, File dstFile, OutputLogger logger)
+    {
+        throw new UnsupportedOperationException(&quot;Not yet implemented&quot;);
+    }
+
+    public static List&lt;String[]&gt; getRevisions(File root, int limit)
+    {
+        return getRevisionsForFile(root, null, limit);
+    }
+
+    public static List&lt;String[]&gt; getRevisionsForFile(File root, File[] files, int limit)
+    {
+        Repository repo = Git.getInstance().getRepository(root);
+        RevWalk walk = new RevWalk(repo);
+        List&lt;String[]&gt; revs = new ArrayList&lt;String[]&gt;();
+
+        try {
+            ObjectId from = repo.resolve(Constants.HEAD);
+            if (from == null)
+                return null;
+            walk.markStart(walk.parseCommit(from));
+
+            if (files != null) {
+                List&lt;PathFilter&gt; paths = new ArrayList&lt;PathFilter&gt;();
+                for (File file : files) {
+                    String path = getRelative(root, file);
+
+                    if (!(path.length() == 0))
+                        paths.add(PathFilter.create(path));
+                }
+
+                if (!paths.isEmpty())
+                    walk.setTreeFilter(PathFilterGroup.create(paths));
+            }
+
+            for (RevCommit rev : walk) {
+                revs.add(new String[] { rev.getShortMessage(), rev.getId().toString() });
+                if (--limit &lt;= 0)
+                    break;
+            }
+
+        } catch (IOException ioe) {
+        }
+
+        return revs;
+    }
+
+    private static String getRelative(File root, File dir)
+    {
+        return getRelative(root.getAbsolutePath(), dir.getAbsolutePath());
+    }
+
+    private static String getRelative(String root, String dir)
+    {
+        if (dir.equals(root))
+            return &quot;&quot;;
+        return dir.replace(root + File.separator, &quot;&quot;);
+    }
+
+    private static String toGitPath(String path)
+    {
+        return File.separatorChar == '/'
+            ? path : path.replace(File.separator, &quot;/&quot;);
+    }
+
+    private static void put(Set&lt;String&gt; set, String relPath,
+        Map&lt;File, StatusInfo&gt; files, File root, int status)
+    {
+        for (String path : set) {
+            if (relPath.length() &gt; 0 &amp;&amp; !path.startsWith(relPath))
+                continue;
+            File file = new File(root, path);
+            files.put(file, new StatusInfo(status, null, false));
+        }
+
+    }
+
+    /*
+     * m odified
+     * a dded
+     * r emoved
+     * d eleted
+     * u nknown
+     * C opies
+     *
+     * i gnored
+     * c lean
+     */
+    public static Map&lt;File, StatusInfo&gt; getAllStatus(File root, File dir) throws IOException
+    {
+        String relPath = getRelative(root, dir);
+        OutputLogger logger = Git.getInstance().getLogger(root.getAbsolutePath());
+
+        Repository repo = Git.getInstance().getRepository(root);
+        Map&lt;File, StatusInfo&gt; files = new HashMap&lt;File, StatusInfo&gt;();
+
+        try {
+            repo.refreshFromDisk();
+            IndexDiff index = new IndexDiff(repo);
+            index.diff();
+
+            put(index.getAdded(), relPath, files, root,
+                StatusInfo.STATUS_VERSIONED_ADDEDLOCALLY);
+            put(index.getRemoved(), relPath, files, root,
+                StatusInfo.STATUS_VERSIONED_REMOVEDLOCALLY);
+            put(index.getMissing(), relPath, files, root,
+                StatusInfo.STATUS_VERSIONED_DELETEDLOCALLY);
+            put(index.getChanged(), relPath, files, root,
+                StatusInfo.STATUS_VERSIONED_MODIFIEDLOCALLY);
+            put(index.getModified(), relPath, files, root,
+                StatusInfo.STATUS_VERSIONED_MODIFIEDLOCALLY);
+
+            final FileTreeIterator workTree = new FileTreeIterator(repo.getWorkDir());
+            final TreeWalk walk = new TreeWalk(repo);
+
+            walk.reset(); // drop the first empty tree
+            walk.setRecursive(true);
+            walk.addTree(workTree);
+
+            int share = SharabilityQuery.getSharability(dir);
+            if (share == SharabilityQuery.NOT_SHARABLE)
+                return files;
+
+            while (walk.next()) {
+                String path = walk.getPathString();
+
+                if (relPath.length() &gt; 0 &amp;&amp; !path.startsWith(relPath))
+                    continue;
+                if (index.getAdded().contains(path) ||
+                    index.getRemoved().contains(path) ||
+                    index.getMissing().contains(path) ||
+                    index.getChanged().contains(path) ||
+                    index.getModified().contains(path))
+                    continue;
+                Entry entry = repo.getIndex().getEntry(path);
+                File file = new File(root, path);
+
+                int status;
+                if (entry != null)
+                    status = StatusInfo.STATUS_VERSIONED_UPTODATE;
+                else {
+                    if (share == SharabilityQuery.MIXED &amp;&amp;
+                        SharabilityQuery.getSharability(file) == SharabilityQuery.NOT_SHARABLE)
+                        continue;
+
+                    status = StatusInfo.STATUS_NOTVERSIONED_NEWLOCALLY;
+                }
+
+                files.put(file, new StatusInfo(status, null, false));
+            }
+
+        } catch (IOException ex) {
+            Exceptions.printStackTrace(ex);
+        }
+
+        return files;
+    }
+
+    /*
+     * m odified
+     * a dded
+     * r emoved
+     * d eleted
+     * u nknown
+     * C opies
+     */
+    public static Map&lt;File, StatusInfo&gt; getInterestingStatus(File root, File dir)
+    {
+        String relPath = getRelative(root, dir);
+
+        Repository repo = Git.getInstance().getRepository(root);
+        IndexDiff index;
+
+        Map&lt;File, StatusInfo&gt; files = new HashMap&lt;File, StatusInfo&gt;();
+
+        try {
+            repo.refreshFromDisk();
+            index = new IndexDiff(repo);
+            index.diff();
+
+            put(index.getAdded(), relPath, files, root,
+                StatusInfo.STATUS_VERSIONED_ADDEDLOCALLY);
+            put(index.getRemoved(), relPath, files, root,
+                StatusInfo.STATUS_VERSIONED_REMOVEDLOCALLY);
+            put(index.getMissing(), relPath, files, root,
+                StatusInfo.STATUS_VERSIONED_DELETEDLOCALLY);
+            put(index.getChanged(), relPath, files, root,
+                StatusInfo.STATUS_VERSIONED_MODIFIEDLOCALLY);
+            put(index.getModified(), relPath, files, root,
+                StatusInfo.STATUS_VERSIONED_MODIFIEDLOCALLY);
+
+            final FileTreeIterator workTree = new FileTreeIterator(repo.getWorkDir());
+            final TreeWalk walk = new TreeWalk(repo);
+
+            walk.reset(); // drop the first empty tree
+            walk.setRecursive(true);
+            walk.addTree(workTree);
+
+            while (walk.next()) {
+                String path = walk.getPathString();
+
+                if (relPath.length() &gt; 0 &amp;&amp; !path.startsWith(relPath))
+                    continue;
+                if (index.getAdded().contains(path) ||
+                    index.getRemoved().contains(path) ||
+                    index.getMissing().contains(path) ||
+                    index.getChanged().contains(path) ||
+                    index.getModified().contains(path))
+                    continue;
+                Entry entry = repo.getIndex().getEntry(path);
+                if (entry != null)
+                    continue;
+                int status = StatusInfo.STATUS_NOTVERSIONED_NEWLOCALLY;
+                File file = new File(root, path);
+                files.put(file, new StatusInfo(status, null, false));
+            }
+
+        } catch (IOException ex) {
+            Exceptions.printStackTrace(ex);
+        }
+
+        return files;
+    }
+
+    public static StatusInfo getSingleStatus(File root, File file)
+    {
+        OutputLogger logger = Git.getInstance().getLogger(root.getAbsolutePath());
+        Repository repo = Git.getInstance().getRepository(root);
+        IndexDiff index;
+
+        int share = SharabilityQuery.getSharability(file.getParentFile());
+        if (share == SharabilityQuery.NOT_SHARABLE ||
+            (share == SharabilityQuery.MIXED &amp;&amp;
+            SharabilityQuery.getSharability(file) == SharabilityQuery.NOT_SHARABLE))
+            return new StatusInfo(StatusInfo.STATUS_NOTVERSIONED_EXCLUDED, null, false);
+
+        int status = StatusInfo.STATUS_UNKNOWN;
+        String name = getRelative(root, file);
+
+        try {
+            repo.refreshFromDisk();
+            index = new IndexDiff(repo);
+            index.diff();
+        } catch (IOException ex) {
+            Exceptions.printStackTrace(ex);
+            return new StatusInfo(status, null, false);
+        }
+
+        if (index.getAdded().contains(name))
+            status = StatusInfo.STATUS_VERSIONED_ADDEDLOCALLY;
+        else if (index.getRemoved().contains(name))
+            status = StatusInfo.STATUS_VERSIONED_REMOVEDLOCALLY;
+        else if (index.getMissing().contains(name))
+            status = StatusInfo.STATUS_VERSIONED_DELETEDLOCALLY;
+        else if (index.getChanged().contains(name))
+            status = StatusInfo.STATUS_VERSIONED_MODIFIEDLOCALLY;
+        else if (index.getModified().contains(name))
+            status = StatusInfo.STATUS_VERSIONED_MODIFIEDLOCALLY;
+        else
+            status = StatusInfo.STATUS_VERSIONED_UPTODATE;
+        StatusInfo info = new StatusInfo(status, null, false);
+
+        return info;
+    }
 
 }
 </diff>
      <filename>src/org/nbgit/util/GitCommand.java</filename>
    </modified>
    <modified>
      <diff>@@ -26,402 +26,402 @@ import org.openide.filesystems.FileUtil;
 
 public class GitIgnore {
 
-	private GitIgnore()
-	{		
-	}
-
-	// IGNORE SUPPORT GIT: following file patterns are added to {Git repos}/.gitignore and Git will ignore any files
-	// that match these patterns, reporting &quot;I&quot;status for them // NOI18N
-	//private static final String [] GIT_IGNORE_FILES = { &quot;.orig&quot;, &quot;\\.orig\\..*$&quot;, &quot;\\.chg\\..*$&quot;, &quot;.rej&quot;, &quot;\\.conflict\\~$&quot;}; // NOI18N
-	private static final String[] GIT_IGNORE_FILES = {&quot;.orig&quot;};
-	private static final String GIT_IGNORE_ORIG_FILES = &quot;\\.orig$&quot;; // NOI18N
-	private static final String GIT_IGNORE_ORIG_ANY_FILES = &quot;\\.orig\\..*$&quot;; // NOI18N
-	private static final String GIT_IGNORE_CHG_ANY_FILES = &quot;\\.chg\\..*$&quot;; // NOI18N
-	private static final String GIT_IGNORE_REJ_ANY_FILES = &quot;\\.rej$&quot;; // NOI18N
-	private static final String GIT_IGNORE_CONFLICT_ANY_FILES = &quot;\\.conflict\\~$&quot;; // NOI18N
-	private static final String FILENAME_GITIGNORE = &quot;.gitignore&quot;; // NOI18N
-	private static HashMap&lt;String, Set&lt;Pattern&gt;&gt; ignorePatterns;
-
-	private static void resetIgnorePatterns(File file)
-	{
-		if (ignorePatterns == null)
-			return;
-		String key = file.getAbsolutePath();
-		ignorePatterns.remove(key);
-	}
-
-	private static Set&lt;Pattern&gt; getIgnorePatterns(File file)
-	{
-		if (ignorePatterns == null)
-			ignorePatterns = new HashMap&lt;String, Set&lt;Pattern&gt;&gt;();
-		String key = file.getAbsolutePath();
-		Set&lt;Pattern&gt; patterns = ignorePatterns.get(key);
-		if (patterns == null) {
-			patterns = new HashSet&lt;Pattern&gt;(5);
-			addIgnorePatterns(patterns, file);
-			ignorePatterns.put(key, patterns);
-		}
-		return patterns;
-	}
-
-	public static boolean isSharable(File file)
-	{
-		return SharabilityQuery.getSharability(file) != SharabilityQuery.NOT_SHARABLE;
-	}
-
-	/**
-	 * isIgnored - checks to see if this is a file Git should ignore
-	 *
-	 * @param File file to check
-	 * @return boolean true - ignore, false - not ignored
-	 */
-	public static boolean isIgnored(File file)
-	{
-		return isIgnored(file, true);
-	}
-
-	public static boolean isIgnored(File file, boolean checkSharability)
-	{
-		// FIXME Disabled for now.
-		if (true != false)
-			return false;
-		if (file == null)
-			return false;
-		String path = file.getPath();
-		String name = file.getName();
-		File topFile = Git.getInstance().getTopmostManagedParent(file);
-
-		// We assume that the toplevel directory should not be ignored.
-		if (topFile == null || topFile.equals(file))
-			return false;
-
-		// We assume that the Project should not be ignored.
-		if (file.isDirectory()) {
-			ProjectManager projectManager = ProjectManager.getDefault();
-			if (projectManager.isProject(FileUtil.toFileObject(file)))
-				return false;
-		}
-
-		Set&lt;Pattern&gt; patterns = getIgnorePatterns(topFile);
-
-		for (Iterator i = patterns.iterator(); i.hasNext();) {
-			Pattern pattern = (Pattern) i.next();
-			if (pattern.matcher(path).find())
-				return true;
-		}
-
-		if (FILENAME_GITIGNORE.equals(name))
-			return false;
-		if (checkSharability &amp;&amp; !isSharable(file))
-			return true;
-		return false;
-	}
-
-	/**
-	 * createIgnored - creates .gitignore file in the repository in which 
-	 * the given file belongs. This .ignore file ensures Git will ignore 
-	 * the files specified in GIT_IGNORE_FILES list
-	 *
-	 * @param path to repository to place .gitignore file
-	 */
-	public static void createIgnored(File path)
-	{
-		if (path == null)
-			return;
-		BufferedWriter fileWriter = null;
-		Git git = Git.getInstance();
-		File root = git.getTopmostManagedParent(path);
-		if (root == null)
-			return;
-		File ignore = new File(root, FILENAME_GITIGNORE);
-
-		try {
-			if (!ignore.exists()) {
-				fileWriter = new BufferedWriter(
-					new OutputStreamWriter(new FileOutputStream(ignore)));
-				for (String name : GIT_IGNORE_FILES) {
-					fileWriter.write(name + &quot;\n&quot;); // NOI18N
-				}
-			} else
-				addToExistingIgnoredFile(ignore);
-		} catch (IOException ex) {
-			Git.LOG.log(Level.FINE, &quot;createIgnored(): File {0} - {1}&quot;, // NOI18N
-				new Object[]{ignore.getAbsolutePath(), ex.toString()});
-		} finally {
-			try {
-				if (fileWriter != null)
-					fileWriter.close();
-				git.getStatusCache().refresh(ignore, StatusCache.REPOSITORY_STATUS_UNKNOWN);
-			} catch (IOException ex) {
-				Git.LOG.log(Level.FINE, &quot;createIgnored(): File {0} - {1}&quot;, // NOI18N
-					new Object[]{ignore.getAbsolutePath(), ex.toString()});
-			}
-		}
-	}
-
-	private static int GIT_NUM_PATTERNS_TO_CHECK = 5;
-
-	private static void addToExistingIgnoredFile(File gitIgnoreFile)
-	{
-		if (gitIgnoreFile == null || !gitIgnoreFile.exists() || !gitIgnoreFile.canWrite())
-			return;
-		File tempFile = null;
-		BufferedReader br = null;
-		PrintWriter pw = null;
-		boolean bOrigAnyPresent = false;
-		boolean bOrigPresent = false;
-		boolean bChgAnyPresent = false;
-		boolean bRejAnyPresent = false;
-		boolean bConflictAnyPresent = false;
-
-		// If new patterns are added to GIT_IGNORE_FILES, following code needs to
-		// check for these new patterns
-		assert (GIT_IGNORE_FILES.length == GIT_NUM_PATTERNS_TO_CHECK);
-
-		try {
-			tempFile = new File(gitIgnoreFile.getAbsolutePath() + &quot;.tmp&quot;); // NOI18N
-			if (tempFile == null)
-				return;
-
-			br = new BufferedReader(new FileReader(gitIgnoreFile));
-			pw = new PrintWriter(new FileWriter(tempFile));
-
-			String line = null;
-			while ((line = br.readLine()) != null) {
-				if (!bOrigAnyPresent &amp;&amp; line.equals(GIT_IGNORE_ORIG_ANY_FILES))
-					bOrigAnyPresent = true;
-				else if (!bOrigPresent &amp;&amp; line.equals(GIT_IGNORE_ORIG_FILES))
-					bOrigPresent = true;
-				else if (!bChgAnyPresent &amp;&amp; line.equals(GIT_IGNORE_CHG_ANY_FILES))
-					bChgAnyPresent = true;
-				else if (!bRejAnyPresent &amp;&amp; line.equals(GIT_IGNORE_REJ_ANY_FILES))
-					bRejAnyPresent = true;
-				else if (!bConflictAnyPresent &amp;&amp; line.equals(GIT_IGNORE_CONFLICT_ANY_FILES))
-					bConflictAnyPresent = true;
-				pw.println(line);
-				pw.flush();
-			}
-			// If not found add as required
-			if (!bOrigAnyPresent) {
-				pw.println(GIT_IGNORE_ORIG_ANY_FILES);
-				pw.flush();
-			}
-			if (!bOrigPresent) {
-				pw.println(GIT_IGNORE_ORIG_FILES);
-				pw.flush();
-			}
-			if (!bChgAnyPresent) {
-				pw.println(GIT_IGNORE_CHG_ANY_FILES);
-				pw.flush();
-			}
-			if (!bRejAnyPresent) {
-				pw.println(GIT_IGNORE_REJ_ANY_FILES);
-				pw.flush();
-			}
-			if (!bConflictAnyPresent) {
-				pw.println(GIT_IGNORE_CONFLICT_ANY_FILES);
-				pw.flush();
-			}
-
-		} catch (IOException ex) {
-			// Ignore
-		} finally {
-			try {
-				if (pw != null)
-					pw.close();
-				if (br != null)
-					br.close();
-
-				boolean bAnyAdditions = !bOrigAnyPresent || !bOrigPresent ||
-					!bChgAnyPresent || !bRejAnyPresent || !bConflictAnyPresent;
-				if (bAnyAdditions) {
-					if (!GitUtils.confirmDialog(GitUtils.class, &quot;MSG_IGNORE_FILES_TITLE&quot;, &quot;MSG_IGNORE_FILES&quot;)) { // NOI18N 
-						tempFile.delete();
-						return;
-					}
-					if (tempFile != null &amp;&amp; tempFile.isFile() &amp;&amp; tempFile.canWrite() &amp;&amp; gitIgnoreFile != null) {
-						gitIgnoreFile.delete();
-						tempFile.renameTo(gitIgnoreFile);
-					}
-				} else
-					tempFile.delete();
-			} catch (IOException ex) {
-				// Ignore
-			}
-		}
-	}
-
-	private static void addIgnorePatterns(Set&lt;Pattern&gt; patterns, File file)
-	{
-		Set&lt;String&gt; shPatterns;
-		try {
-			shPatterns = readIgnoreEntries(file);
-		} catch (IOException e) {
-			// ignore invalid entries
-			return;
-		}
-		for (Iterator i = shPatterns.iterator(); i.hasNext();) {
-			String shPattern = (String) i.next();
-			if (&quot;!&quot;.equals(shPattern)) // NOI18N
-				patterns.clear();
-			else
-				try {
-					patterns.add(Pattern.compile(shPattern));
-				} catch (Exception e) {
-					// unsupported pattern
-				}
-		}
-	}
-
-	private static Boolean ignoreContainsSyntax(File directory) throws IOException
-	{
-		File gitIgnore = new File(directory, FILENAME_GITIGNORE);
-		Boolean val = false;
-
-		if (!gitIgnore.canRead())
-			return val;
-
-		String s;
-		BufferedReader r = null;
-		try {
-			r = new BufferedReader(new FileReader(gitIgnore));
-			while ((s = r.readLine()) != null) {
-				String line = s.trim();
-				int indexOfHash = line.indexOf(&quot;#&quot;);
-				if (indexOfHash != -1) {
-					if (indexOfHash == 0)
-						continue;
-					line = line.substring(0, indexOfHash - 1);
-				}
-				String[] array = line.split(&quot; &quot;);
-				if (array[0].equals(&quot;syntax:&quot;)) {
-					val = true;
-					break;
-				}
-			}
-		} finally {
-			if (r != null)
-				try {
-					r.close();
-				} catch (IOException e) {
-				}
-		}
-		return val;
-	}
-
-	private static Set&lt;String&gt; readIgnoreEntries(File directory) throws IOException
-	{
-		File gitIgnore = new File(directory, FILENAME_GITIGNORE);
-
-		Set&lt;String&gt; entries = new HashSet&lt;String&gt;(5);
-		if (!gitIgnore.canRead())
-			return entries;
-
-		String s;
-		BufferedReader r = null;
-		try {
-			r = new BufferedReader(new FileReader(gitIgnore));
-			while ((s = r.readLine()) != null) {
-				String line = s.trim();
-				if (line.length() == 0)
-					continue;
-				int indexOfHash = line.indexOf(&quot;#&quot;);
-				if (indexOfHash != -1) {
-					if (indexOfHash == 0)
-						continue;
-					line = line.substring(0, indexOfHash - 1);
-				}
-				String[] array = line.split(&quot; &quot;);
-				if (array[0].equals(&quot;syntax:&quot;))
-					continue;
-				entries.addAll(Arrays.asList(array));
-			}
-		} finally {
-			if (r != null)
-				try {
-					r.close();
-				} catch (IOException e) {
-				}
-		}
-		return entries;
-	}
-
-	private static String computePatternToIgnore(File directory, File file)
-	{
-		String name = file.getAbsolutePath().substring(directory.getAbsolutePath().length() + 1);
-		return name.replace(' ', '?').replace(File.separatorChar, '/');
-	}
-
-	private static void writeIgnoreEntries(File directory, Set entries) throws IOException
-	{
-		File gitIgnore = new File(directory, FILENAME_GITIGNORE);
-		FileObject fo = FileUtil.toFileObject(gitIgnore);
-
-		if (entries.size() == 0) {
-			if (fo != null)
-				fo.delete();
-			return;
-		}
-
-		if (fo == null || !fo.isValid()) {
-			fo = FileUtil.toFileObject(directory);
-			fo = fo.createData(FILENAME_GITIGNORE);
-		}
-		FileLock lock = fo.lock();
-		PrintWriter w = null;
-		try {
-			w = new PrintWriter(fo.getOutputStream(lock));
-			for (Iterator i = entries.iterator(); i.hasNext();) {
-				w.println(i.next());
-			}
-		} finally {
-			lock.releaseLock();
-			if (w != null)
-				w.close();
-			resetIgnorePatterns(directory);
-		}
-	}
-
-	/**
-	 * addIgnored - Add the specified files to the .gitignore file in the 
-	 * specified repository.
-	 *
-	 * @param directory for repository for .gitignore file
-	 * @param files an array of Files to be added
-	 */
-	public static void addIgnored(File directory, File[] files) throws IOException
-	{
-		if (ignoreContainsSyntax(directory)) {
-			GitUtils.warningDialog(GitUtils.class, &quot;MSG_UNABLE_TO_IGNORE_TITLE&quot;, &quot;MSG_UNABLE_TO_IGNORE&quot;);
-			return;
-		}
-		Set&lt;String&gt; entries = readIgnoreEntries(directory);
-		for (File file : files) {
-			String patterntoIgnore = computePatternToIgnore(directory, file);
-			entries.add(patterntoIgnore);
-		}
-		writeIgnoreEntries(directory, entries);
-	}
-
-	/**
-	 * removeIgnored - Remove the specified files from the .gitignore file in 
-	 * the specified repository.
-	 *
-	 * @param directory for repository for .gitignore file
-	 * @param files an array of Files to be removed
-	 */
-	public static void removeIgnored(File directory, File[] files) throws IOException
-	{
-		if (ignoreContainsSyntax(directory)) {
-			GitUtils.warningDialog(GitUtils.class, &quot;MSG_UNABLE_TO_UNIGNORE_TITLE&quot;, &quot;MSG_UNABLE_TO_UNIGNORE&quot;);
-			return;
-		}
-		Set entries = readIgnoreEntries(directory);
-		for (File file : files) {
-			String patterntoIgnore = computePatternToIgnore(directory, file);
-			entries.remove(patterntoIgnore);
-		}
-		writeIgnoreEntries(directory, entries);
-	}
+    private GitIgnore()
+    {
+    }
+
+    // IGNORE SUPPORT GIT: following file patterns are added to {Git repos}/.gitignore and Git will ignore any files
+    // that match these patterns, reporting &quot;I&quot;status for them // NOI18N
+    //private static final String [] GIT_IGNORE_FILES = { &quot;.orig&quot;, &quot;\\.orig\\..*$&quot;, &quot;\\.chg\\..*$&quot;, &quot;.rej&quot;, &quot;\\.conflict\\~$&quot;}; // NOI18N
+    private static final String[] GIT_IGNORE_FILES = {&quot;.orig&quot;};
+    private static final String GIT_IGNORE_ORIG_FILES = &quot;\\.orig$&quot;; // NOI18N
+    private static final String GIT_IGNORE_ORIG_ANY_FILES = &quot;\\.orig\\..*$&quot;; // NOI18N
+    private static final String GIT_IGNORE_CHG_ANY_FILES = &quot;\\.chg\\..*$&quot;; // NOI18N
+    private static final String GIT_IGNORE_REJ_ANY_FILES = &quot;\\.rej$&quot;; // NOI18N
+    private static final String GIT_IGNORE_CONFLICT_ANY_FILES = &quot;\\.conflict\\~$&quot;; // NOI18N
+    private static final String FILENAME_GITIGNORE = &quot;.gitignore&quot;; // NOI18N
+    private static HashMap&lt;String, Set&lt;Pattern&gt;&gt; ignorePatterns;
+
+    private static void resetIgnorePatterns(File file)
+    {
+        if (ignorePatterns == null)
+            return;
+        String key = file.getAbsolutePath();
+        ignorePatterns.remove(key);
+    }
+
+    private static Set&lt;Pattern&gt; getIgnorePatterns(File file)
+    {
+        if (ignorePatterns == null)
+            ignorePatterns = new HashMap&lt;String, Set&lt;Pattern&gt;&gt;();
+        String key = file.getAbsolutePath();
+        Set&lt;Pattern&gt; patterns = ignorePatterns.get(key);
+        if (patterns == null) {
+            patterns = new HashSet&lt;Pattern&gt;(5);
+            addIgnorePatterns(patterns, file);
+            ignorePatterns.put(key, patterns);
+        }
+        return patterns;
+    }
+
+    public static boolean isSharable(File file)
+    {
+        return SharabilityQuery.getSharability(file) != SharabilityQuery.NOT_SHARABLE;
+    }
+
+    /**
+     * isIgnored - checks to see if this is a file Git should ignore
+     *
+     * @param File file to check
+     * @return boolean true - ignore, false - not ignored
+     */
+    public static boolean isIgnored(File file)
+    {
+        return isIgnored(file, true);
+    }
+
+    public static boolean isIgnored(File file, boolean checkSharability)
+    {
+        // FIXME Disabled for now.
+        if (true != false)
+            return false;
+        if (file == null)
+            return false;
+        String path = file.getPath();
+        String name = file.getName();
+        File topFile = Git.getInstance().getTopmostManagedParent(file);
+
+        // We assume that the toplevel directory should not be ignored.
+        if (topFile == null || topFile.equals(file))
+            return false;
+
+        // We assume that the Project should not be ignored.
+        if (file.isDirectory()) {
+            ProjectManager projectManager = ProjectManager.getDefault();
+            if (projectManager.isProject(FileUtil.toFileObject(file)))
+                return false;
+        }
+
+        Set&lt;Pattern&gt; patterns = getIgnorePatterns(topFile);
+
+        for (Iterator i = patterns.iterator(); i.hasNext();) {
+            Pattern pattern = (Pattern) i.next();
+            if (pattern.matcher(path).find())
+                return true;
+        }
+
+        if (FILENAME_GITIGNORE.equals(name))
+            return false;
+        if (checkSharability &amp;&amp; !isSharable(file))
+            return true;
+        return false;
+    }
+
+    /**
+     * createIgnored - creates .gitignore file in the repository in which
+     * the given file belongs. This .ignore file ensures Git will ignore
+     * the files specified in GIT_IGNORE_FILES list
+     *
+     * @param path to repository to place .gitignore file
+     */
+    public static void createIgnored(File path)
+    {
+        if (path == null)
+            return;
+        BufferedWriter fileWriter = null;
+        Git git = Git.getInstance();
+        File root = git.getTopmostManagedParent(path);
+        if (root == null)
+            return;
+        File ignore = new File(root, FILENAME_GITIGNORE);
+
+        try {
+            if (!ignore.exists()) {
+                fileWriter = new BufferedWriter(
+                    new OutputStreamWriter(new FileOutputStream(ignore)));
+                for (String name : GIT_IGNORE_FILES) {
+                    fileWriter.write(name + &quot;\n&quot;); // NOI18N
+                }
+            } else
+                addToExistingIgnoredFile(ignore);
+        } catch (IOException ex) {
+            Git.LOG.log(Level.FINE, &quot;createIgnored(): File {0} - {1}&quot;, // NOI18N
+                new Object[]{ignore.getAbsolutePath(), ex.toString()});
+        } finally {
+            try {
+                if (fileWriter != null)
+                    fileWriter.close();
+                git.getStatusCache().refresh(ignore, StatusCache.REPOSITORY_STATUS_UNKNOWN);
+            } catch (IOException ex) {
+                Git.LOG.log(Level.FINE, &quot;createIgnored(): File {0} - {1}&quot;, // NOI18N
+                    new Object[]{ignore.getAbsolutePath(), ex.toString()});
+            }
+        }
+    }
+
+    private static int GIT_NUM_PATTERNS_TO_CHECK = 5;
+
+    private static void addToExistingIgnoredFile(File gitIgnoreFile)
+    {
+        if (gitIgnoreFile == null || !gitIgnoreFile.exists() || !gitIgnoreFile.canWrite())
+            return;
+        File tempFile = null;
+        BufferedReader br = null;
+        PrintWriter pw = null;
+        boolean bOrigAnyPresent = false;
+        boolean bOrigPresent = false;
+        boolean bChgAnyPresent = false;
+        boolean bRejAnyPresent = false;
+        boolean bConflictAnyPresent = false;
+
+        // If new patterns are added to GIT_IGNORE_FILES, following code needs to
+        // check for these new patterns
+        assert (GIT_IGNORE_FILES.length == GIT_NUM_PATTERNS_TO_CHECK);
+
+        try {
+            tempFile = new File(gitIgnoreFile.getAbsolutePath() + &quot;.tmp&quot;); // NOI18N
+            if (tempFile == null)
+                return;
+
+            br = new BufferedReader(new FileReader(gitIgnoreFile));
+            pw = new PrintWriter(new FileWriter(tempFile));
+
+            String line = null;
+            while ((line = br.readLine()) != null) {
+                if (!bOrigAnyPresent &amp;&amp; line.equals(GIT_IGNORE_ORIG_ANY_FILES))
+                    bOrigAnyPresent = true;
+                else if (!bOrigPresent &amp;&amp; line.equals(GIT_IGNORE_ORIG_FILES))
+                    bOrigPresent = true;
+                else if (!bChgAnyPresent &amp;&amp; line.equals(GIT_IGNORE_CHG_ANY_FILES))
+                    bChgAnyPresent = true;
+                else if (!bRejAnyPresent &amp;&amp; line.equals(GIT_IGNORE_REJ_ANY_FILES))
+                    bRejAnyPresent = true;
+                else if (!bConflictAnyPresent &amp;&amp; line.equals(GIT_IGNORE_CONFLICT_ANY_FILES))
+                    bConflictAnyPresent = true;
+                pw.println(line);
+                pw.flush();
+            }
+            // If not found add as required
+            if (!bOrigAnyPresent) {
+                pw.println(GIT_IGNORE_ORIG_ANY_FILES);
+                pw.flush();
+            }
+            if (!bOrigPresent) {
+                pw.println(GIT_IGNORE_ORIG_FILES);
+                pw.flush();
+            }
+            if (!bChgAnyPresent) {
+                pw.println(GIT_IGNORE_CHG_ANY_FILES);
+                pw.flush();
+            }
+            if (!bRejAnyPresent) {
+                pw.println(GIT_IGNORE_REJ_ANY_FILES);
+                pw.flush();
+            }
+            if (!bConflictAnyPresent) {
+                pw.println(GIT_IGNORE_CONFLICT_ANY_FILES);
+                pw.flush();
+            }
+
+        } catch (IOException ex) {
+            // Ignore
+        } finally {
+            try {
+                if (pw != null)
+                    pw.close();
+                if (br != null)
+                    br.close();
+
+                boolean bAnyAdditions = !bOrigAnyPresent || !bOrigPresent ||
+                    !bChgAnyPresent || !bRejAnyPresent || !bConflictAnyPresent;
+                if (bAnyAdditions) {
+                    if (!GitUtils.confirmDialog(GitUtils.class, &quot;MSG_IGNORE_FILES_TITLE&quot;, &quot;MSG_IGNORE_FILES&quot;)) { // NOI18N
+                        tempFile.delete();
+                        return;
+                    }
+                    if (tempFile != null &amp;&amp; tempFile.isFile() &amp;&amp; tempFile.canWrite() &amp;&amp; gitIgnoreFile != null) {
+                        gitIgnoreFile.delete();
+                        tempFile.renameTo(gitIgnoreFile);
+                    }
+                } else
+                    tempFile.delete();
+            } catch (IOException ex) {
+                // Ignore
+            }
+        }
+    }
+
+    private static void addIgnorePatterns(Set&lt;Pattern&gt; patterns, File file)
+    {
+        Set&lt;String&gt; shPatterns;
+        try {
+            shPatterns = readIgnoreEntries(file);
+        } catch (IOException e) {
+            // ignore invalid entries
+            return;
+        }
+        for (Iterator i = shPatterns.iterator(); i.hasNext();) {
+            String shPattern = (String) i.next();
+            if (&quot;!&quot;.equals(shPattern)) // NOI18N
+                patterns.clear();
+            else
+                try {
+                    patterns.add(Pattern.compile(shPattern));
+                } catch (Exception e) {
+                    // unsupported pattern
+                }
+        }
+    }
+
+    private static Boolean ignoreContainsSyntax(File directory) throws IOException
+    {
+        File gitIgnore = new File(directory, FILENAME_GITIGNORE);
+        Boolean val = false;
+
+        if (!gitIgnore.canRead())
+            return val;
+
+        String s;
+        BufferedReader r = null;
+        try {
+            r = new BufferedReader(new FileReader(gitIgnore));
+            while ((s = r.readLine()) != null) {
+                String line = s.trim();
+                int indexOfHash = line.indexOf(&quot;#&quot;);
+                if (indexOfHash != -1) {
+                    if (indexOfHash == 0)
+                        continue;
+                    line = line.substring(0, indexOfHash - 1);
+                }
+                String[] array = line.split(&quot; &quot;);
+                if (array[0].equals(&quot;syntax:&quot;)) {
+                    val = true;
+                    break;
+                }
+            }
+        } finally {
+            if (r != null)
+                try {
+                    r.close();
+                } catch (IOException e) {
+                }
+        }
+        return val;
+    }
+
+    private static Set&lt;String&gt; readIgnoreEntries(File directory) throws IOException
+    {
+        File gitIgnore = new File(directory, FILENAME_GITIGNORE);
+
+        Set&lt;String&gt; entries = new HashSet&lt;String&gt;(5);
+        if (!gitIgnore.canRead())
+            return entries;
+
+        String s;
+        BufferedReader r = null;
+        try {
+            r = new BufferedReader(new FileReader(gitIgnore));
+            while ((s = r.readLine()) != null) {
+                String line = s.trim();
+                if (line.length() == 0)
+                    continue;
+                int indexOfHash = line.indexOf(&quot;#&quot;);
+                if (indexOfHash != -1) {
+                    if (indexOfHash == 0)
+                        continue;
+                    line = line.substring(0, indexOfHash - 1);
+                }
+                String[] array = line.split(&quot; &quot;);
+                if (array[0].equals(&quot;syntax:&quot;))
+                    continue;
+                entries.addAll(Arrays.asList(array));
+            }
+        } finally {
+            if (r != null)
+                try {
+                    r.close();
+                } catch (IOException e) {
+                }
+        }
+        return entries;
+    }
+
+    private static String computePatternToIgnore(File directory, File file)
+    {
+        String name = file.getAbsolutePath().substring(directory.getAbsolutePath().length() + 1);
+        return name.replace(' ', '?').replace(File.separatorChar, '/');
+    }
+
+    private static void writeIgnoreEntries(File directory, Set entries) throws IOException
+    {
+        File gitIgnore = new File(directory, FILENAME_GITIGNORE);
+        FileObject fo = FileUtil.toFileObject(gitIgnore);
+
+        if (entries.size() == 0) {
+            if (fo != null)
+                fo.delete();
+            return;
+        }
+
+        if (fo == null || !fo.isValid()) {
+            fo = FileUtil.toFileObject(directory);
+            fo = fo.createData(FILENAME_GITIGNORE);
+        }
+        FileLock lock = fo.lock();
+        PrintWriter w = null;
+        try {
+            w = new PrintWriter(fo.getOutputStream(lock));
+            for (Iterator i = entries.iterator(); i.hasNext();) {
+                w.println(i.next());
+            }
+        } finally {
+            lock.releaseLock();
+            if (w != null)
+                w.close();
+            resetIgnorePatterns(directory);
+        }
+    }
+
+    /**
+     * addIgnored - Add the specified files to the .gitignore file in the
+     * specified repository.
+     *
+     * @param directory for repository for .gitignore file
+     * @param files an array of Files to be added
+     */
+    public static void addIgnored(File directory, File[] files) throws IOException
+    {
+        if (ignoreContainsSyntax(directory)) {
+            GitUtils.warningDialog(GitUtils.class, &quot;MSG_UNABLE_TO_IGNORE_TITLE&quot;, &quot;MSG_UNABLE_TO_IGNORE&quot;);
+            return;
+        }
+        Set&lt;String&gt; entries = readIgnoreEntries(directory);
+        for (File file : files) {
+            String patterntoIgnore = computePatternToIgnore(directory, file);
+            entries.add(patterntoIgnore);
+        }
+        writeIgnoreEntries(directory, entries);
+    }
+
+    /**
+     * removeIgnored - Remove the specified files from the .gitignore file in
+     * the specified repository.
+     *
+     * @param directory for repository for .gitignore file
+     * @param files an array of Files to be removed
+     */
+    public static void removeIgnored(File directory, File[] files) throws IOException
+    {
+        if (ignoreContainsSyntax(directory)) {
+            GitUtils.warningDialog(GitUtils.class, &quot;MSG_UNABLE_TO_UNIGNORE_TITLE&quot;, &quot;MSG_UNABLE_TO_UNIGNORE&quot;);
+            return;
+        }
+        Set entries = readIgnoreEntries(directory);
+        for (File file : files) {
+            String patterntoIgnore = computePatternToIgnore(directory, file);
+            entries.remove(patterntoIgnore);
+        }
+        writeIgnoreEntries(directory, entries);
+    }
 
 }</diff>
      <filename>src/org/nbgit/util/GitIgnore.java</filename>
    </modified>
    <modified>
      <diff>@@ -65,105 +65,105 @@ import org.openide.windows.WindowManager;
 
 /**
  * Class to handle various aspects of NetBeans Project management.
- * 
+ *
  * @author alexbcoles
  */
 public class GitProjectUtils {
 
-	private static final String ProjectTab_ID_LOGICAL = &quot;projectTabLogical_tc&quot;; // NOI18N    
-
-	public static void renameProject(Project p, Object caller)
-	{
-		if (p == null)
-			return;
-
-		ContextAwareAction action = (ContextAwareAction) CommonProjectActions.renameProjectAction();
-		Lookup ctx = Lookups.singleton(p);
-		Action ctxAction = action.createContextAwareInstance(ctx);
-		ctxAction.actionPerformed(new ActionEvent(caller, 0, &quot;&quot;)); // NOI18N
-	}
-
-	public static void openProject(Project p, Object caller, boolean setMain)
-	{
-		if (p == null)
-			return;
-		Project[] projects = new Project[]{p};
-		OpenProjects.getDefault().open(projects, false);
-		if (setMain)
-			OpenProjects.getDefault().setMainProject(p);
-
-		// set as main project and expand
-		selectAndExpandProject(p);
-	}
-
-	public static void selectAndExpandProject(final Project p)
-	{
-		if (p == null)
-			return;
-
-		// invoke later to select the being opened project if the focus is outside ProjectTab
-		SwingUtilities.invokeLater(new Runnable() {
-
-			final ExplorerManager.Provider ptLogial = findDefault(ProjectTab_ID_LOGICAL);
-
-			public void run()
-			{
-				Node root = ptLogial.getExplorerManager().getRootContext();
-				// Node projNode = root.getChildren ().findChild( p.getProjectDirectory().getName () );
-				Node projNode = root.getChildren().findChild(ProjectUtils.getInformation(p).getName());
-				if (projNode != null)
-					try {
-						ptLogial.getExplorerManager().setSelectedNodes(new Node[]{projNode});
-					} catch (Exception ignore) {
-						// may ignore it
-					}
-			}
-
-		});
-	}
-
-	public static String getProjectName(final File root)
-	{
-		if (root == null || !root.isDirectory())
-			return null;
-		final ProjectManager projectManager = ProjectManager.getDefault();
-		FileObject rootFileObj = FileUtil.toFileObject(FileUtil.normalizeFile(root));
-		// This can happen if the root is &quot;ssh://&lt;something&gt;&quot;
-		if (rootFileObj == null || projectManager == null)
-			return null;
-
-		String res = null;
-		if (projectManager.isProject(rootFileObj))
-			try {
-				Project prj = projectManager.findProject(rootFileObj);
-
-				res = getProjectName(prj);
-			} catch (Exception ex) {
-				Git.LOG.log(Level.FINE, &quot;getProjectName() file: {0} {1}&quot;, new Object[]{rootFileObj.getPath(), ex.toString()}); // NOI18N
-			} finally {
-				return res;
-			}
-		else
-			return res;
-	}
-
-	public static String getProjectName(final Project p)
-	{
-		if (p == null)
-			return null;
-
-		ProjectInformation pi = ProjectUtils.getInformation(p);
-		return pi == null ? null : pi.getDisplayName();
-	}
-
-	private static synchronized ExplorerManager.Provider findDefault(String tcID)
-	{
-		TopComponent tc = WindowManager.getDefault().findTopComponent(tcID);
-		return (ExplorerManager.Provider) tc;
-	}
-	// Should not be creating an instance of this class
-	private GitProjectUtils()
-	{
-	}
+    private static final String ProjectTab_ID_LOGICAL = &quot;projectTabLogical_tc&quot;; // NOI18N
+
+    public static void renameProject(Project p, Object caller)
+    {
+        if (p == null)
+            return;
+
+        ContextAwareAction action = (ContextAwareAction) CommonProjectActions.renameProjectAction();
+        Lookup ctx = Lookups.singleton(p);
+        Action ctxAction = action.createContextAwareInstance(ctx);
+        ctxAction.actionPerformed(new ActionEvent(caller, 0, &quot;&quot;)); // NOI18N
+    }
+
+    public static void openProject(Project p, Object caller, boolean setMain)
+    {
+        if (p == null)
+            return;
+        Project[] projects = new Project[]{p};
+        OpenProjects.getDefault().open(projects, false);
+        if (setMain)
+            OpenProjects.getDefault().setMainProject(p);
+
+        // set as main project and expand
+        selectAndExpandProject(p);
+    }
+
+    public static void selectAndExpandProject(final Project p)
+    {
+        if (p == null)
+            return;
+
+        // invoke later to select the being opened project if the focus is outside ProjectTab
+        SwingUtilities.invokeLater(new Runnable() {
+
+            final ExplorerManager.Provider ptLogial = findDefault(ProjectTab_ID_LOGICAL);
+
+            public void run()
+            {
+                Node root = ptLogial.getExplorerManager().getRootContext();
+                // Node projNode = root.getChildren ().findChild( p.getProjectDirectory().getName () );
+                Node projNode = root.getChildren().findChild(ProjectUtils.getInformation(p).getName());
+                if (projNode != null)
+                    try {
+                        ptLogial.getExplorerManager().setSelectedNodes(new Node[]{projNode});
+                    } catch (Exception ignore) {
+                        // may ignore it
+                    }
+            }
+
+        });
+    }
+
+    public static String getProjectName(final File root)
+    {
+        if (root == null || !root.isDirectory())
+            return null;
+        final ProjectManager projectManager = ProjectManager.getDefault();
+        FileObject rootFileObj = FileUtil.toFileObject(FileUtil.normalizeFile(root));
+        // This can happen if the root is &quot;ssh://&lt;something&gt;&quot;
+        if (rootFileObj == null || projectManager == null)
+            return null;
+
+        String res = null;
+        if (projectManager.isProject(rootFileObj))
+            try {
+                Project prj = projectManager.findProject(rootFileObj);
+
+                res = getProjectName(prj);
+            } catch (Exception ex) {
+                Git.LOG.log(Level.FINE, &quot;getProjectName() file: {0} {1}&quot;, new Object[]{rootFileObj.getPath(), ex.toString()}); // NOI18N
+            } finally {
+                return res;
+            }
+        else
+            return res;
+    }
+
+    public static String getProjectName(final Project p)
+    {
+        if (p == null)
+            return null;
+
+        ProjectInformation pi = ProjectUtils.getInformation(p);
+        return pi == null ? null : pi.getDisplayName();
+    }
+
+    private static synchronized ExplorerManager.Provider findDefault(String tcID)
+    {
+        TopComponent tc = WindowManager.getDefault().findTopComponent(tcID);
+        return (ExplorerManager.Provider) tc;
+    }
+    // Should not be creating an instance of this class
+    private GitProjectUtils()
+    {
+    }
 
 }
\ No newline at end of file</diff>
      <filename>src/org/nbgit/util/GitProjectUtils.java</filename>
    </modified>
    <modified>
      <diff>@@ -86,615 +86,615 @@ import org.spearce.jgit.lib.Constants;
  */
 public class GitUtils {
 
-	private static final Pattern httpPasswordPattern = Pattern.compile(&quot;(https*://)(\\w+\\b):(\\b\\S*)@&quot;); //NOI18N
-	private static final String httpPasswordReplacementStr = &quot;$1$2:\\*\\*\\*\\*@&quot;; //NOI18N
-	private static final Pattern metadataPattern = Pattern.compile(&quot;.*\\&quot; + File.separatorChar + &quot;(\\.)git(\\&quot; + File.separatorChar + &quot;.*|$)&quot;); // NOI18N
-
-	/**
-	 * replaceHttpPassword - replace any http or https passwords in the string
-	 *
-	 * @return String modified string with **** instead of passwords
-	 */
-	public static String replaceHttpPassword(String s)
-	{
-		Matcher m = httpPasswordPattern.matcher(s);
-		return m.replaceAll(httpPasswordReplacementStr);
-	}
-
-	/**
-	 * replaceHttpPassword - replace any http or https passwords in the List&lt;String&gt;
-	 *
-	 * @return List&lt;String&gt; containing modified strings with **** instead of passwords
-	 */
-	public static List&lt;String&gt; replaceHttpPassword(List&lt;String&gt; list)
-	{
-		if (list == null)
-			return null;
-
-		List&lt;String&gt; out = new ArrayList&lt;String&gt;(list.size());
-		for (String s : list) {
-			out.add(replaceHttpPassword(s));
-		}
-		return out;
-	}
-
-	/**
-	 * isInUserPath - check if passed in name is on the Users PATH environment setting
-	 *
-	 * @param name to check
-	 * @return boolean true - on PATH, false - not on PATH
-	 */
-	public static boolean isInUserPath(String name)
-	{
-		String pathEnv = System.getenv().get(&quot;PATH&quot;);// NOI18N
-		// Work around issues on Windows fetching PATH
-		if (pathEnv == null)
-			pathEnv = System.getenv().get(&quot;Path&quot;);// NOI18N
-		if (pathEnv == null)
-			pathEnv = System.getenv().get(&quot;path&quot;);// NOI18N
-		String pathSeparator = System.getProperty(&quot;path.separator&quot;);// NOI18N
-		if (pathEnv == null || pathSeparator == null)
-			return false;
-
-		String[] paths = pathEnv.split(pathSeparator);
-		for (String path : paths) {
-			File f = new File(path, name);
-			// On Windows isFile will fail on gitk.cmd use !isDirectory
-			if (f.exists() &amp;&amp; !f.isDirectory())
-				return true;
-		}
-		return false;
-	}
-
-	/**
-	 * confirmDialog - display a confirmation dialog
-	 *
-	 * @param bundleLocation location of string resources to display
-	 * @param title of dialog to display    
-	 * @param query ask user
-	 * @return boolean true - answered Yes, false - answered No
-	 */
-	public static boolean confirmDialog(Class bundleLocation, String title, String query)
-	{
-		int response = JOptionPane.showOptionDialog(null, NbBundle.getMessage(bundleLocation, query), NbBundle.getMessage(bundleLocation, title), JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null, null, null);
-
-		if (response == JOptionPane.YES_OPTION)
-			return true;
-		else
-			return false;
-	}
-
-	/**
-	 * warningDialog - display a warning dialog
-	 *
-	 * @param bundleLocation location of string resources to display
-	 * @param title of dialog to display    
-	 * @param warning to display to the user
-	 */
-	public static void warningDialog(Class bundleLocation, String title, String warning)
-	{
-		JOptionPane.showMessageDialog(null,
-			NbBundle.getMessage(bundleLocation, warning),
-			NbBundle.getMessage(bundleLocation, title),
-			JOptionPane.WARNING_MESSAGE);
-	}
-
-	/**
-	 * stripDoubleSlash - converts '\\' to '\' in path on Windows
-	 *
-	 * @param String path to convert
-	 * @return String converted path
-	 */
-	public static String stripDoubleSlash(String path)
-	{
-		if (Utilities.isWindows())
-			return path.replace(&quot;\\\\&quot;, &quot;\\&quot;);
-		return path;
-	}
-
-	/**
-	 * isLocallyAdded - checks to see if this file has been Locally Added to Git
-	 *
-	 * @param file to check
-	 * @return boolean true - ignore, false - not ignored
-	 */
-	public static boolean isLocallyAdded(File file)
-	{
-		if (file == null)
-			return false;
-		Git git = Git.getInstance();
-
-		if ((git.getStatusCache().getStatus(file).getStatus() &amp; StatusInfo.STATUS_VERSIONED_ADDEDLOCALLY) != 0)
-			return true;
-		else
-			return false;
-	}
-
-	/**
-	 * Returns a Map keyed by Directory, containing a single File/StatusInfo Map for each Directories file contents.
-	 *
-	 * @param Map of &lt;File, StatusInfo&gt; interestingFiles to be processed and divided up into Files in Directory
-	 * @param Collection of &lt;File&gt; files to be processed against the interestingFiles
-	 * @return Map of Dirs containing Map of files and status for all files in each directory
-	 */
-	public static Map&lt;File, Map&lt;File, StatusInfo&gt;&gt; getInterestingDirs(Map&lt;File, StatusInfo&gt; interestingFiles, Collection&lt;File&gt; files)
-	{
-		Map&lt;File, Map&lt;File, StatusInfo&gt;&gt; interestingDirs = new HashMap&lt;File, Map&lt;File, StatusInfo&gt;&gt;();
-
-		for (File file : files) {
-			if (file.isDirectory()) {
-				if (interestingDirs.get(file) == null)
-					interestingDirs.put(file, new HashMap&lt;File, StatusInfo&gt;());
-			} else {
-				File par = file.getParentFile();
-				if (par != null) {
-					if (interestingDirs.get(par) == null)
-						interestingDirs.put(par, new HashMap&lt;File, StatusInfo&gt;());
-					StatusInfo fi = interestingFiles.get(file);
-					interestingDirs.get(par).put(file, fi);
-				}
-			}
-		}
-
-		return interestingDirs;
-	}
-
-	/**
-	 * Semantics is similar to {@link org.openide.windows.TopComponent#getActivatedNodes()} except that this
-	 * method returns File objects instead of Nodes. Every node is examined for Files it represents. File and Folder
-	 * nodes represent their underlying files or folders. Project nodes are represented by their source groups. Other
-	 * logical nodes must provide FileObjects in their Lookup.
-	 *
-	 * @param nodes null (then taken from windowsystem, it may be wrong on editor tabs #66700).
-	 * @param includingFileStatus if any activated file does not have this CVS status, an empty array is returned
-	 * @param includingFolderStatus if any activated folder does not have this CVS status, an empty array is returned
-	 * @return File [] array of activated files, or an empty array if any of examined files/folders does not have given status
-	 */
-	public static VCSContext getCurrentContext(Node[] nodes, int includingFileStatus, int includingFolderStatus)
-	{
-		VCSContext context = getCurrentContext(nodes);
-		StatusCache cache = Git.getInstance().getStatusCache();
-		for (File file : context.getRootFiles()) {
-			StatusInfo fi = cache.getStatus(file);
-			if (file.isDirectory()) {
-				if ((fi.getStatus() &amp; includingFolderStatus) == 0)
-					return VCSContext.EMPTY;
-			} else if ((fi.getStatus() &amp; includingFileStatus) == 0)
-				return VCSContext.EMPTY;
-		}
-		return context;
-	}
-
-	/**
-	 * Semantics is similar to {@link org.openide.windows.TopComponent#getActiva
-	tedNodes()} except that this
-	 * method returns File objects instead of Nodes. Every node is examined for
-	Files it represents. File and Folder
-	 * nodes represent their underlying files or folders. Project nodes are repr
-	esented by their source groups. Other
-	 * logical nodes must provide FileObjects in their Lookup.
-	 *
-	 * @return File [] array of activated files
-	 * @param nodes or null (then taken from windowsystem, it may be wrong on ed
-	itor tabs #66700).
-	 */
-	public static VCSContext getCurrentContext(Node[] nodes)
-	{
-		if (nodes == null)
-			nodes = TopComponent.getRegistry().getActivatedNodes();
-		return VCSContext.forNodes(nodes);
-	}
-
-	/**
-	 * Returns path to repository root or null if not managed
-	 *
-	 * @param VCSContext
-	 * @return String of repository root path
-	 */
-	public static String getRootPath(VCSContext context)
-	{
-		File root = getRootFile(context);
-		return (root == null) ? null : root.getAbsolutePath();
-	}
-
-	/**
-	 * Returns path to repository root or null if not managed
-	 *
-	 * @param VCSContext
-	 * @return String of repository root path
-	 */
-	public static File getRootFile(VCSContext context)
-	{
-		if (context == null)
-			return null;
-		Git git = Git.getInstance();
-		File[] files = context.getRootFiles().toArray(new File[context.getRootFiles().size()]);
-		if (files == null || files.length == 0)
-			return null;
-
-		return git.getTopmostManagedParent(files[0]);
-	}
-
-	/**
-	 * Returns File object for Project Directory
-	 *
-	 * @param VCSContext
-	 * @return File object of Project Directory
-	 */
-	public static File getProjectFile(VCSContext context)
-	{
-		return getProjectFile(getProject(context));
-	}
-
-	public static Project getProject(VCSContext context)
-	{
-		if (context == null)
-			return null;
-		File[] files = context.getRootFiles().toArray(new File[context.getRootFiles().size()]);
-
-		for (File file : files) {
-			/* We may be committing a LocallyDeleted file */
-			if (!file.exists())
-				file = file.getParentFile();
-
-			Project p = FileOwnerQuery.getOwner(FileUtil.toFileObject(file));
-			if (p != null)
-				return p;
-			else
-				Git.LOG.log(Level.FINE, &quot;GitUtils.getProjectFile(): No project for {0}&quot;, // NOI18N
-					file);
-		}
-		return null;
-	}
-
-	public static File getProjectFile(Project project)
-	{
-		if (project == null)
-			return null;
-
-		FileObject fo = project.getProjectDirectory();
-		return FileUtil.toFile(fo);
-	}
-
-	public static File[] getProjectRootFiles(Project project)
-	{
-		if (project == null)
-			return null;
-		Set&lt;File&gt; set = new HashSet&lt;File&gt;();
-
-		Sources sources = ProjectUtils.getSources(project);
-		SourceGroup[] sourceGroups = sources.getSourceGroups(Sources.TYPE_GENERIC);
-		for (int j = 0; j &lt; sourceGroups.length; j++) {
-			SourceGroup sourceGroup = sourceGroups[j];
-			FileObject srcRootFo = sourceGroup.getRootFolder();
-			File rootFile = FileUtil.toFile(srcRootFo);
-			set.add(rootFile);
-		}
-		return set.toArray(new File[set.size()]);
-	}
-
-	/**
-	 * Checks file location to see if it is part of Git metdata
-	 *
-	 * @param file file to check
-	 * @return true if the file or folder is a part of Git metadata, false otherwise
-	 */
-	public static boolean isPartOfGitMetadata(File file)
-	{
-		return metadataPattern.matcher(file.getAbsolutePath()).matches();
-	}
-
-	/**
-	 * Forces refresh of Status for the given directory 
-	 *
-	 * @param start file or dir to begin refresh from
-	 * @return void
-	 */
-	public static void forceStatusRefresh(File file)
-	{
-		if (Git.getInstance().isAdministrative(file))
-			return;
-
-		StatusCache cache = Git.getInstance().getStatusCache();
-
-		cache.refreshCached(file);
-		File repository = Git.getInstance().getTopmostManagedParent(file);
-		if (repository == null)
-			return;
-
-		if (file.isDirectory()) {
-			Map&lt;File, StatusInfo&gt; interestingFiles;
-			interestingFiles = GitCommand.getInterestingStatus(repository, file);
-			if (!interestingFiles.isEmpty()) {
-				Collection&lt;File&gt; files = interestingFiles.keySet();
-				for (File aFile : files) {
-					StatusInfo fi = interestingFiles.get(aFile);
-					cache.refreshFileStatus(aFile, fi, null);
-				}
-			}
-		}
-	}
-
-	/**
-	 * Forces refresh of Status for the specfied context.
-	 *
-	 * @param VCSContext context to be updated.
-	 * @return void
-	 */
-	public static void forceStatusRefresh(VCSContext context)
-	{
-		for (File root : context.getRootFiles()) {
-			forceStatusRefresh(root);
-		}
-	}
-
-	/**
-	 * Forces refresh of Status for the project of the specified context
-	 *
-	 * @param VCSContext ctx whose project is be updated.
-	 * @return void
-	 */
-	public static void forceStatusRefreshProject(VCSContext context)
-	{
-		Project project = getProject(context);
-		if (project == null)
-			return;
-		File[] files = getProjectRootFiles(project);
-		for (int j = 0; j &lt; files.length; j++) {
-			forceStatusRefresh(files[j]);
-		}
-	}
-
-	/**
-	 * Tests parent/child relationship of files.
-	 *
-	 * @param parent file to be parent of the second parameter
-	 * @param file file to be a child of the first parameter
-	 * @return true if the second parameter represents the same file as the first parameter OR is its descendant (child)
-	 */
-	public static boolean isParentOrEqual(File parent, File file)
-	{
-		for (; file != null; file = file.getParentFile()) {
-			if (file.equals(parent))
-				return true;
-		}
-		return false;
-	}
-
-	/**
-	 * Returns path of file relative to root repository or a warning message
-	 * if the file is not under the repository root.
-	 *
-	 * @param File to get relative path from the repository root
-	 * @return String of relative path of the file from teh repository root
-	 */
-	public static String getRelativePath(File file)
-	{
-		if (file == null)
-			return NbBundle.getMessage(SyncFileNode.class, &quot;LBL_Location_NotInRepository&quot;);
-		String shortPath = file.getAbsolutePath();
-		if (shortPath == null)
-			return NbBundle.getMessage(SyncFileNode.class, &quot;LBL_Location_NotInRepository&quot;);
-
-		Git git = Git.getInstance();
-		File rootManagedFolder = git.getTopmostManagedParent(file);
-		if (rootManagedFolder == null)
-			return NbBundle.getMessage(SyncFileNode.class, &quot;LBL_Location_NotInRepository&quot;);
-
-		String root = rootManagedFolder.getAbsolutePath();
-		if (shortPath.startsWith(root))
-			return shortPath.substring(root.length() + 1);
-		else
-			return NbBundle.getMessage(SyncFileNode.class, &quot;LBL_Location_NotInRepository&quot;);
-	}
-
-	/**
-	 * Normalize flat files, Git treats folder as normal file
-	 * so it's necessary explicitly list direct descendants to
-	 * get classical flat behaviour.
-	 *
-	 * &lt;p&gt; E.g. revert on package node means:
-	 * &lt;ul&gt;
-	 *   &lt;li&gt;revert package folder properties AND
-	 *   &lt;li&gt;revert all modified (including deleted) files in the folder
-	 * &lt;/ul&gt;
-	 *
-	 * @return files with given status and direct descendants with given status.
-	 */
-	public static File[] flatten(File[] files, int status)
-	{
-		LinkedList&lt;File&gt; ret = new LinkedList&lt;File&gt;();
-
-		StatusCache cache = Git.getInstance().getStatusCache();
-		for (int i = 0; i &lt; files.length; i++) {
-			File dir = files[i];
-			StatusInfo info = cache.getStatus(dir);
-			if ((status &amp; info.getStatus()) != 0)
-				ret.add(dir);
-			File[] entries = cache.listFiles(dir);  // comparing to dir.listFiles() lists already deleted too
-			for (int e = 0; e &lt; entries.length; e++) {
-				File entry = entries[e];
-				info = cache.getStatus(entry);
-				if ((status &amp; info.getStatus()) != 0)
-					ret.add(entry);
-			}
-		}
-
-		return ret.toArray(new File[ret.size()]);
-	}
-
-	/**
-	 * Utility method that returns all non-excluded modified files that are
-	 * under given roots (folders) and have one of specified statuses.
-	 *
-	 * @param context context to search
-	 * @param includeStatus bit mask of file statuses to include in result
-	 * @return File [] array of Files having specified status
-	 */
-	public static File[] getModifiedFiles(VCSContext context, int includeStatus)
-	{
-		File[] all = Git.getInstance().getStatusCache().listFiles(context, includeStatus);
-		List&lt;File&gt; files = new ArrayList&lt;File&gt;();
-		for (int i = 0; i &lt; all.length; i++) {
-			File file = all[i];
-			String path = file.getAbsolutePath();
-			if (GitModuleConfig.getDefault().isExcludedFromCommit(path) == false)
-				files.add(file);
-		}
-
-		// ensure that command roots (files that were explicitly selected by user) are included in Diff
-		StatusCache cache = Git.getInstance().getStatusCache();
-		for (File file : context.getRootFiles()) {
-			if (file.isFile() &amp;&amp; (cache.getStatus(file).getStatus() &amp; includeStatus) != 0 &amp;&amp; !files.contains(file))
-				files.add(file);
-		}
-		return files.toArray(new File[files.size()]);
-	}
-
-	/**
-	 * Checks if the file is binary.
-	 *
-	 * @param file file to check
-	 * @return true if the file cannot be edited in NetBeans text editor, false otherwise
-	 */
-	public static boolean isFileContentBinary(File file)
-	{
-		FileObject fo = FileUtil.toFileObject(file);
-		if (fo == null)
-			return false;
-		try {
-			DataObject dao = DataObject.find(fo);
-			return dao.getCookie(EditorCookie.class) == null;
-		} catch (DataObjectNotFoundException e) {
-			// not found, continue
-		}
-		return false;
-	}
-
-	/**
-	 * @return true if the buffer is almost certainly binary.
-	 * Note: Non-ASCII based encoding encoded text is binary,
-	 * newlines cannot be reliably detected.
-	 */
-	public static boolean isBinary(byte[] buffer)
-	{
-		for (int i = 0; i &lt; buffer.length; i++) {
-			int ch = buffer[i];
-			if (ch &lt; 32 &amp;&amp; ch != '\t' &amp;&amp; ch != '\n' &amp;&amp; ch != '\r')
-				return true;
-		}
-		return false;
-	}
-
-	/**
-	 * Loads the file in specified revision.
-	 *
-	 * @return null if the file does not exist in given revision
-	 */
-	public static File getFileRevision(File base, String revision) throws IOException
-	{
-		if (revision.equals(&quot;-1&quot;))
-			return null;
-
-		if (GitRepository.REVISION_CURRENT.equals(revision))
-			return base;
-
-		if (GitRepository.REVISION_BASE.equals(revision))
-			revision = Constants.HEAD;
-
-		File tempFile = File.createTempFile(&quot;tmp&quot;, &quot;-&quot; + base.getName()); //NOI18N
-		File repository = Git.getInstance().getTopmostManagedParent(base);
-
-		GitCommand.doCat(repository, base, tempFile, revision);
-		if (tempFile.length() == 0)
-			return null;
-		return tempFile;
-	}
-
-	/**
-	 * Compares two {@link StatusInfo} objects by importance of statuses they represent.
-	 */
-	public static class ByImportanceComparator&lt;T&gt; implements Comparator&lt;StatusInfo&gt; {
-
-		public int compare(StatusInfo i1, StatusInfo i2)
-		{
-			return getComparableStatus(i1.getStatus()) - getComparableStatus(i2.getStatus());
-		}
-
-	}
-
-	/**
-	 * Gets integer status that can be used in comparators. The more important the status is for the user,
-	 * the lower value it has. Conflict is 0, unknown status is 100.
-	 *
-	 * @return status constant suitable for 'by importance' comparators
-	 */
-	public static int getComparableStatus(int status)
-	{
-		if (0 != (status &amp; StatusInfo.STATUS_VERSIONED_CONFLICT))
-			return 0;
-		else if (0 != (status &amp; StatusInfo.STATUS_VERSIONED_MERGE))
-			return 1;
-		else if (0 != (status &amp; StatusInfo.STATUS_VERSIONED_DELETEDLOCALLY))
-			return 10;
-		else if (0 != (status &amp; StatusInfo.STATUS_VERSIONED_REMOVEDLOCALLY))
-			return 11;
-		else if (0 != (status &amp; StatusInfo.STATUS_NOTVERSIONED_NEWLOCALLY))
-			return 12;
-		else if (0 != (status &amp; StatusInfo.STATUS_VERSIONED_COPIEDLOCALLY))
-			return 13;
-		else if (0 != (status &amp; StatusInfo.STATUS_VERSIONED_ADDEDLOCALLY))
-			return 14;
-		else if (0 != (status &amp; StatusInfo.STATUS_VERSIONED_MODIFIEDLOCALLY))
-			return 15;
-		else if (0 != (status &amp; StatusInfo.STATUS_VERSIONED_REMOVEDINREPOSITORY))
-			return 30;
-		else if (0 != (status &amp; StatusInfo.STATUS_VERSIONED_NEWINREPOSITORY))
-			return 31;
-		else if (0 != (status &amp; StatusInfo.STATUS_VERSIONED_MODIFIEDINREPOSITORY))
-			return 32;
-		else if (0 != (status &amp; StatusInfo.STATUS_VERSIONED_UPTODATE))
-			return 50;
-		else if (0 != (status &amp; StatusInfo.STATUS_NOTVERSIONED_EXCLUDED))
-			return 100;
-		else if (0 != (status &amp; StatusInfo.STATUS_NOTVERSIONED_NOTMANAGED))
-			return 101;
-		else if (status == StatusInfo.STATUS_UNKNOWN)
-			return 102;
-		else
-			throw new IllegalArgumentException(&quot;Uncomparable status: &quot; + status);
-	}
-
-	protected static int getFileEnabledStatus()
-	{
-		return ~0;
-	}
-
-	protected static int getDirectoryEnabledStatus()
-	{
-		return StatusInfo.STATUS_MANAGED &amp; ~StatusInfo.STATUS_NOTVERSIONED_EXCLUDED;
-	}
-
-	/**
-	 * Rips an eventual username off - e.g. user@svn.host.org
-	 *
-	 * @param host - hostname with a userneame
-	 * @return host - hostname without the username
-	 */
-	public static String ripUserFromHost(String host)
-	{
-		int idx = host.indexOf('@');
-		if (idx &lt; 0)
-			return host;
-		else
-			return host.substring(idx + 1);
-	}
-
-	/**
-	 * This utility class should not be instantiated anywhere.
-	 */
-	private GitUtils()
-	{
-	}
+    private static final Pattern httpPasswordPattern = Pattern.compile(&quot;(https*://)(\\w+\\b):(\\b\\S*)@&quot;); //NOI18N
+    private static final String httpPasswordReplacementStr = &quot;$1$2:\\*\\*\\*\\*@&quot;; //NOI18N
+    private static final Pattern metadataPattern = Pattern.compile(&quot;.*\\&quot; + File.separatorChar + &quot;(\\.)git(\\&quot; + File.separatorChar + &quot;.*|$)&quot;); // NOI18N
+
+    /**
+     * replaceHttpPassword - replace any http or https passwords in the string
+     *
+     * @return String modified string with **** instead of passwords
+     */
+    public static String replaceHttpPassword(String s)
+    {
+        Matcher m = httpPasswordPattern.matcher(s);
+        return m.replaceAll(httpPasswordReplacementStr);
+    }
+
+    /**
+     * replaceHttpPassword - replace any http or https passwords in the List&lt;String&gt;
+     *
+     * @return List&lt;String&gt; containing modified strings with **** instead of passwords
+     */
+    public static List&lt;String&gt; replaceHttpPassword(List&lt;String&gt; list)
+    {
+        if (list == null)
+            return null;
+
+        List&lt;String&gt; out = new ArrayList&lt;String&gt;(list.size());
+        for (String s : list) {
+            out.add(replaceHttpPassword(s));
+        }
+        return out;
+    }
+
+    /**
+     * isInUserPath - check if passed in name is on the Users PATH environment setting
+     *
+     * @param name to check
+     * @return boolean true - on PATH, false - not on PATH
+     */
+    public static boolean isInUserPath(String name)
+    {
+        String pathEnv = System.getenv().get(&quot;PATH&quot;);// NOI18N
+        // Work around issues on Windows fetching PATH
+        if (pathEnv == null)
+            pathEnv = System.getenv().get(&quot;Path&quot;);// NOI18N
+        if (pathEnv == null)
+            pathEnv = System.getenv().get(&quot;path&quot;);// NOI18N
+        String pathSeparator = System.getProperty(&quot;path.separator&quot;);// NOI18N
+        if (pathEnv == null || pathSeparator == null)
+            return false;
+
+        String[] paths = pathEnv.split(pathSeparator);
+        for (String path : paths) {
+            File f = new File(path, name);
+            // On Windows isFile will fail on gitk.cmd use !isDirectory
+            if (f.exists() &amp;&amp; !f.isDirectory())
+                return true;
+        }
+        return false;
+    }
+
+    /**
+     * confirmDialog - display a confirmation dialog
+     *
+     * @param bundleLocation location of string resources to display
+     * @param title of dialog to display
+     * @param query ask user
+     * @return boolean true - answered Yes, false - answered No
+     */
+    public static boolean confirmDialog(Class bundleLocation, String title, String query)
+    {
+        int response = JOptionPane.showOptionDialog(null, NbBundle.getMessage(bundleLocation, query), NbBundle.getMessage(bundleLocation, title), JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null, null, null);
+
+        if (response == JOptionPane.YES_OPTION)
+            return true;
+        else
+            return false;
+    }
+
+    /**
+     * warningDialog - display a warning dialog
+     *
+     * @param bundleLocation location of string resources to display
+     * @param title of dialog to display
+     * @param warning to display to the user
+     */
+    public static void warningDialog(Class bundleLocation, String title, String warning)
+    {
+        JOptionPane.showMessageDialog(null,
+            NbBundle.getMessage(bundleLocation, warning),
+            NbBundle.getMessage(bundleLocation, title),
+            JOptionPane.WARNING_MESSAGE);
+    }
+
+    /**
+     * stripDoubleSlash - converts '\\' to '\' in path on Windows
+     *
+     * @param String path to convert
+     * @return String converted path
+     */
+    public static String stripDoubleSlash(String path)
+    {
+        if (Utilities.isWindows())
+            return path.replace(&quot;\\\\&quot;, &quot;\\&quot;);
+        return path;
+    }
+
+    /**
+     * isLocallyAdded - checks to see if this file has been Locally Added to Git
+     *
+     * @param file to check
+     * @return boolean true - ignore, false - not ignored
+     */
+    public static boolean isLocallyAdded(File file)
+    {
+        if (file == null)
+            return false;
+        Git git = Git.getInstance();
+
+        if ((git.getStatusCache().getStatus(file).getStatus() &amp; StatusInfo.STATUS_VERSIONED_ADDEDLOCALLY) != 0)
+            return true;
+        else
+            return false;
+    }
+
+    /**
+     * Returns a Map keyed by Directory, containing a single File/StatusInfo Map for each Directories file contents.
+     *
+     * @param Map of &lt;File, StatusInfo&gt; interestingFiles to be processed and divided up into Files in Directory
+     * @param Collection of &lt;File&gt; files to be processed against the interestingFiles
+     * @return Map of Dirs containing Map of files and status for all files in each directory
+     */
+    public static Map&lt;File, Map&lt;File, StatusInfo&gt;&gt; getInterestingDirs(Map&lt;File, StatusInfo&gt; interestingFiles, Collection&lt;File&gt; files)
+    {
+        Map&lt;File, Map&lt;File, StatusInfo&gt;&gt; interestingDirs = new HashMap&lt;File, Map&lt;File, StatusInfo&gt;&gt;();
+
+        for (File file : files) {
+            if (file.isDirectory()) {
+                if (interestingDirs.get(file) == null)
+                    interestingDirs.put(file, new HashMap&lt;File, StatusInfo&gt;());
+            } else {
+                File par = file.getParentFile();
+                if (par != null) {
+                    if (interestingDirs.get(par) == null)
+                        interestingDirs.put(par, new HashMap&lt;File, StatusInfo&gt;());
+                    StatusInfo fi = interestingFiles.get(file);
+                    interestingDirs.get(par).put(file, fi);
+                }
+            }
+        }
+
+        return interestingDirs;
+    }
+
+    /**
+     * Semantics is similar to {@link org.openide.windows.TopComponent#getActivatedNodes()} except that this
+     * method returns File objects instead of Nodes. Every node is examined for Files it represents. File and Folder
+     * nodes represent their underlying files or folders. Project nodes are represented by their source groups. Other
+     * logical nodes must provide FileObjects in their Lookup.
+     *
+     * @param nodes null (then taken from windowsystem, it may be wrong on editor tabs #66700).
+     * @param includingFileStatus if any activated file does not have this CVS status, an empty array is returned
+     * @param includingFolderStatus if any activated folder does not have this CVS status, an empty array is returned
+     * @return File [] array of activated files, or an empty array if any of examined files/folders does not have given status
+     */
+    public static VCSContext getCurrentContext(Node[] nodes, int includingFileStatus, int includingFolderStatus)
+    {
+        VCSContext context = getCurrentContext(nodes);
+        StatusCache cache = Git.getInstance().getStatusCache();
+        for (File file : context.getRootFiles()) {
+            StatusInfo fi = cache.getStatus(file);
+            if (file.isDirectory()) {
+                if ((fi.getStatus() &amp; includingFolderStatus) == 0)
+                    return VCSContext.EMPTY;
+            } else if ((fi.getStatus() &amp; includingFileStatus) == 0)
+                return VCSContext.EMPTY;
+        }
+        return context;
+    }
+
+    /**
+     * Semantics is similar to {@link org.openide.windows.TopComponent#getActiva
+    tedNodes()} except that this
+     * method returns File objects instead of Nodes. Every node is examined for
+    Files it represents. File and Folder
+     * nodes represent their underlying files or folders. Project nodes are repr
+    esented by their source groups. Other
+     * logical nodes must provide FileObjects in their Lookup.
+     *
+     * @return File [] array of activated files
+     * @param nodes or null (then taken from windowsystem, it may be wrong on ed
+    itor tabs #66700).
+     */
+    public static VCSContext getCurrentContext(Node[] nodes)
+    {
+        if (nodes == null)
+            nodes = TopComponent.getRegistry().getActivatedNodes();
+        return VCSContext.forNodes(nodes);
+    }
+
+    /**
+     * Returns path to repository root or null if not managed
+     *
+     * @param VCSContext
+     * @return String of repository root path
+     */
+    public static String getRootPath(VCSContext context)
+    {
+        File root = getRootFile(context);
+        return (root == null) ? null : root.getAbsolutePath();
+    }
+
+    /**
+     * Returns path to repository root or null if not managed
+     *
+     * @param VCSContext
+     * @return String of repository root path
+     */
+    public static File getRootFile(VCSContext context)
+    {
+        if (context == null)
+            return null;
+        Git git = Git.getInstance();
+        File[] files = context.getRootFiles().toArray(new File[context.getRootFiles().size()]);
+        if (files == null || files.length == 0)
+            return null;
+
+        return git.getTopmostManagedParent(files[0]);
+    }
+
+    /**
+     * Returns File object for Project Directory
+     *
+     * @param VCSContext
+     * @return File object of Project Directory
+     */
+    public static File getProjectFile(VCSContext context)
+    {
+        return getProjectFile(getProject(context));
+    }
+
+    public static Project getProject(VCSContext context)
+    {
+        if (context == null)
+            return null;
+        File[] files = context.getRootFiles().toArray(new File[context.getRootFiles().size()]);
+
+        for (File file : files) {
+            /* We may be committing a LocallyDeleted file */
+            if (!file.exists())
+                file = file.getParentFile();
+
+            Project p = FileOwnerQuery.getOwner(FileUtil.toFileObject(file));
+            if (p != null)
+                return p;
+            else
+                Git.LOG.log(Level.FINE, &quot;GitUtils.getProjectFile(): No project for {0}&quot;, // NOI18N
+                    file);
+        }
+        return null;
+    }
+
+    public static File getProjectFile(Project project)
+    {
+        if (project == null)
+            return null;
+
+        FileObject fo = project.getProjectDirectory();
+        return FileUtil.toFile(fo);
+    }
+
+    public static File[] getProjectRootFiles(Project project)
+    {
+        if (project == null)
+            return null;
+        Set&lt;File&gt; set = new HashSet&lt;File&gt;();
+
+        Sources sources = ProjectUtils.getSources(project);
+        SourceGroup[] sourceGroups = sources.getSourceGroups(Sources.TYPE_GENERIC);
+        for (int j = 0; j &lt; sourceGroups.length; j++) {
+            SourceGroup sourceGroup = sourceGroups[j];
+            FileObject srcRootFo = sourceGroup.getRootFolder();
+            File rootFile = FileUtil.toFile(srcRootFo);
+            set.add(rootFile);
+        }
+        return set.toArray(new File[set.size()]);
+    }
+
+    /**
+     * Checks file location to see if it is part of Git metdata
+     *
+     * @param file file to check
+     * @return true if the file or folder is a part of Git metadata, false otherwise
+     */
+    public static boolean isPartOfGitMetadata(File file)
+    {
+        return metadataPattern.matcher(file.getAbsolutePath()).matches();
+    }
+
+    /**
+     * Forces refresh of Status for the given directory
+     *
+     * @param start file or dir to begin refresh from
+     * @return void
+     */
+    public static void forceStatusRefresh(File file)
+    {
+        if (Git.getInstance().isAdministrative(file))
+            return;
+
+        StatusCache cache = Git.getInstance().getStatusCache();
+
+        cache.refreshCached(file);
+        File repository = Git.getInstance().getTopmostManagedParent(file);
+        if (repository == null)
+            return;
+
+        if (file.isDirectory()) {
+            Map&lt;File, StatusInfo&gt; interestingFiles;
+            interestingFiles = GitCommand.getInterestingStatus(repository, file);
+            if (!interestingFiles.isEmpty()) {
+                Collection&lt;File&gt; files = interestingFiles.keySet();
+                for (File aFile : files) {
+                    StatusInfo fi = interestingFiles.get(aFile);
+                    cache.refreshFileStatus(aFile, fi, null);
+                }
+            }
+        }
+    }
+
+    /**
+     * Forces refresh of Status for the specfied context.
+     *
+     * @param VCSContext context to be updated.
+     * @return void
+     */
+    public static void forceStatusRefresh(VCSContext context)
+    {
+        for (File root : context.getRootFiles()) {
+            forceStatusRefresh(root);
+        }
+    }
+
+    /**
+     * Forces refresh of Status for the project of the specified context
+     *
+     * @param VCSContext ctx whose project is be updated.
+     * @return void
+     */
+    public static void forceStatusRefreshProject(VCSContext context)
+    {
+        Project project = getProject(context);
+        if (project == null)
+            return;
+        File[] files = getProjectRootFiles(project);
+        for (int j = 0; j &lt; files.length; j++) {
+            forceStatusRefresh(files[j]);
+        }
+    }
+
+    /**
+     * Tests parent/child relationship of files.
+     *
+     * @param parent file to be parent of the second parameter
+     * @param file file to be a child of the first parameter
+     * @return true if the second parameter represents the same file as the first parameter OR is its descendant (child)
+     */
+    public static boolean isParentOrEqual(File parent, File file)
+    {
+        for (; file != null; file = file.getParentFile()) {
+            if (file.equals(parent))
+                return true;
+        }
+        return false;
+    }
+
+    /**
+     * Returns path of file relative to root repository or a warning message
+     * if the file is not under the repository root.
+     *
+     * @param File to get relative path from the repository root
+     * @return String of relative path of the file from teh repository root
+     */
+    public static String getRelativePath(File file)
+    {
+        if (file == null)
+            return NbBundle.getMessage(SyncFileNode.class, &quot;LBL_Location_NotInRepository&quot;);
+        String shortPath = file.getAbsolutePath();
+        if (shortPath == null)
+            return NbBundle.getMessage(SyncFileNode.class, &quot;LBL_Location_NotInRepository&quot;);
+
+        Git git = Git.getInstance();
+        File rootManagedFolder = git.getTopmostManagedParent(file);
+        if (rootManagedFolder == null)
+            return NbBundle.getMessage(SyncFileNode.class, &quot;LBL_Location_NotInRepository&quot;);
+
+        String root = rootManagedFolder.getAbsolutePath();
+        if (shortPath.startsWith(root))
+            return shortPath.substring(root.length() + 1);
+        else
+            return NbBundle.getMessage(SyncFileNode.class, &quot;LBL_Location_NotInRepository&quot;);
+    }
+
+    /**
+     * Normalize flat files, Git treats folder as normal file
+     * so it's necessary explicitly list direct descendants to
+     * get classical flat behaviour.
+     *
+     * &lt;p&gt; E.g. revert on package node means:
+     * &lt;ul&gt;
+     *   &lt;li&gt;revert package folder properties AND
+     *   &lt;li&gt;revert all modified (including deleted) files in the folder
+     * &lt;/ul&gt;
+     *
+     * @return files with given status and direct descendants with given status.
+     */
+    public static File[] flatten(File[] files, int status)
+    {
+        LinkedList&lt;File&gt; ret = new LinkedList&lt;File&gt;();
+
+        StatusCache cache = Git.getInstance().getStatusCache();
+        for (int i = 0; i &lt; files.length; i++) {
+            File dir = files[i];
+            StatusInfo info = cache.getStatus(dir);
+            if ((status &amp; info.getStatus()) != 0)
+                ret.add(dir);
+            File[] entries = cache.listFiles(dir);  // comparing to dir.listFiles() lists already deleted too
+            for (int e = 0; e &lt; entries.length; e++) {
+                File entry = entries[e];
+                info = cache.getStatus(entry);
+                if ((status &amp; info.getStatus()) != 0)
+                    ret.add(entry);
+            }
+        }
+
+        return ret.toArray(new File[ret.size()]);
+    }
+
+    /**
+     * Utility method that returns all non-excluded modified files that are
+     * under given roots (folders) and have one of specified statuses.
+     *
+     * @param context context to search
+     * @param includeStatus bit mask of file statuses to include in result
+     * @return File [] array of Files having specified status
+     */
+    public static File[] getModifiedFiles(VCSContext context, int includeStatus)
+    {
+        File[] all = Git.getInstance().getStatusCache().listFiles(context, includeStatus);
+        List&lt;File&gt; files = new ArrayList&lt;File&gt;();
+        for (int i = 0; i &lt; all.length; i++) {
+            File file = all[i];
+            String path = file.getAbsolutePath();
+            if (GitModuleConfig.getDefault().isExcludedFromCommit(path) == false)
+                files.add(file);
+        }
+
+        // ensure that command roots (files that were explicitly selected by user) are included in Diff
+        StatusCache cache = Git.getInstance().getStatusCache();
+        for (File file : context.getRootFiles()) {
+            if (file.isFile() &amp;&amp; (cache.getStatus(file).getStatus() &amp; includeStatus) != 0 &amp;&amp; !files.contains(file))
+                files.add(file);
+        }
+        return files.toArray(new File[files.size()]);
+    }
+
+    /**
+     * Checks if the file is binary.
+     *
+     * @param file file to check
+     * @return true if the file cannot be edited in NetBeans text editor, false otherwise
+     */
+    public static boolean isFileContentBinary(File file)
+    {
+        FileObject fo = FileUtil.toFileObject(file);
+        if (fo == null)
+            return false;
+        try {
+            DataObject dao = DataObject.find(fo);
+            return dao.getCookie(EditorCookie.class) == null;
+        } catch (DataObjectNotFoundException e) {
+            // not found, continue
+        }
+        return false;
+    }
+
+    /**
+     * @return true if the buffer is almost certainly binary.
+     * Note: Non-ASCII based encoding encoded text is binary,
+     * newlines cannot be reliably detected.
+     */
+    public static boolean isBinary(byte[] buffer)
+    {
+        for (int i = 0; i &lt; buffer.length; i++) {
+            int ch = buffer[i];
+            if (ch &lt; 32 &amp;&amp; ch != '\t' &amp;&amp; ch != '\n' &amp;&amp; ch != '\r')
+                return true;
+        }
+        return false;
+    }
+
+    /**
+     * Loads the file in specified revision.
+     *
+     * @return null if the file does not exist in given revision
+     */
+    public static File getFileRevision(File base, String revision) throws IOException
+    {
+        if (revision.equals(&quot;-1&quot;))
+            return null;
+
+        if (GitRepository.REVISION_CURRENT.equals(revision))
+            return base;
+
+        if (GitRepository.REVISION_BASE.equals(revision))
+            revision = Constants.HEAD;
+
+        File tempFile = File.createTempFile(&quot;tmp&quot;, &quot;-&quot; + base.getName()); //NOI18N
+        File repository = Git.getInstance().getTopmostManagedParent(base);
+
+        GitCommand.doCat(repository, base, tempFile, revision);
+        if (tempFile.length() == 0)
+            return null;
+        return tempFile;
+    }
+
+    /**
+     * Compares two {@link StatusInfo} objects by importance of statuses they represent.
+     */
+    public static class ByImportanceComparator&lt;T&gt; implements Comparator&lt;StatusInfo&gt; {
+
+        public int compare(StatusInfo i1, StatusInfo i2)
+        {
+            return getComparableStatus(i1.getStatus()) - getComparableStatus(i2.getStatus());
+        }
+
+    }
+
+    /**
+     * Gets integer status that can be used in comparators. The more important the status is for the user,
+     * the lower value it has. Conflict is 0, unknown status is 100.
+     *
+     * @return status constant suitable for 'by importance' comparators
+     */
+    public static int getComparableStatus(int status)
+    {
+        if (0 != (status &amp; StatusInfo.STATUS_VERSIONED_CONFLICT))
+            return 0;
+        else if (0 != (status &amp; StatusInfo.STATUS_VERSIONED_MERGE))
+            return 1;
+        else if (0 != (status &amp; StatusInfo.STATUS_VERSIONED_DELETEDLOCALLY))
+            return 10;
+        else if (0 != (status &amp; StatusInfo.STATUS_VERSIONED_REMOVEDLOCALLY))
+            return 11;
+        else if (0 != (status &amp; StatusInfo.STATUS_NOTVERSIONED_NEWLOCALLY))
+            return 12;
+        else if (0 != (status &amp; StatusInfo.STATUS_VERSIONED_COPIEDLOCALLY))
+            return 13;
+        else if (0 != (status &amp; StatusInfo.STATUS_VERSIONED_ADDEDLOCALLY))
+            return 14;
+        else if (0 != (status &amp; StatusInfo.STATUS_VERSIONED_MODIFIEDLOCALLY))
+            return 15;
+        else if (0 != (status &amp; StatusInfo.STATUS_VERSIONED_REMOVEDINREPOSITORY))
+            return 30;
+        else if (0 != (status &amp; StatusInfo.STATUS_VERSIONED_NEWINREPOSITORY))
+            return 31;
+        else if (0 != (status &amp; StatusInfo.STATUS_VERSIONED_MODIFIEDINREPOSITORY))
+            return 32;
+        else if (0 != (status &amp; StatusInfo.STATUS_VERSIONED_UPTODATE))
+            return 50;
+        else if (0 != (status &amp; StatusInfo.STATUS_NOTVERSIONED_EXCLUDED))
+            return 100;
+        else if (0 != (status &amp; StatusInfo.STATUS_NOTVERSIONED_NOTMANAGED))
+            return 101;
+        else if (status == StatusInfo.STATUS_UNKNOWN)
+            return 102;
+        else
+            throw new IllegalArgumentException(&quot;Uncomparable status: &quot; + status);
+    }
+
+    protected static int getFileEnabledStatus()
+    {
+        return ~0;
+    }
+
+    protected static int getDirectoryEnabledStatus()
+    {
+        return StatusInfo.STATUS_MANAGED &amp; ~StatusInfo.STATUS_NOTVERSIONED_EXCLUDED;
+    }
+
+    /**
+     * Rips an eventual username off - e.g. user@svn.host.org
+     *
+     * @param host - hostname with a userneame
+     * @return host - hostname without the username
+     */
+    public static String ripUserFromHost(String host)
+    {
+        int idx = host.indexOf('@');
+        if (idx &lt; 0)
+            return host;
+        else
+            return host.substring(idx + 1);
+    }
+
+    /**
+     * This utility class should not be instantiated anywhere.
+     */
+    private GitUtils()
+    {
+    }
 
 }
\ No newline at end of file</diff>
      <filename>src/org/nbgit/util/GitUtils.java</filename>
    </modified>
    <modified>
      <diff>@@ -65,261 +65,261 @@ import org.spearce.jgit.treewalk.filter.TreeFilter;
  */
 public class HtmlFormatter {
 
-	private static MessageFormat uptodateFormat = getFormat(&quot;uptodateFormat&quot;);  // NOI18N
-	private static MessageFormat newLocallyFormat = getFormat(&quot;newLocallyFormat&quot;);  // NOI18N
-	private static MessageFormat addedLocallyFormat = getFormat(&quot;addedLocallyFormat&quot;); // NOI18N
-	private static MessageFormat modifiedLocallyFormat = getFormat(&quot;modifiedLocallyFormat&quot;); // NOI18N
-	private static MessageFormat removedLocallyFormat = getFormat(&quot;removedLocallyFormat&quot;); // NOI18N
-	private static MessageFormat deletedLocallyFormat = getFormat(&quot;deletedLocallyFormat&quot;); // NOI18N
-	private static MessageFormat excludedFormat = getFormat(&quot;excludedFormat&quot;); // NOI18N
-	private static MessageFormat conflictFormat = getFormat(&quot;conflictFormat&quot;); // NOI18N
-	private static final int STATUS_TEXT_ANNOTABLE =
-		StatusInfo.STATUS_NOTVERSIONED_EXCLUDED |
-		StatusInfo.STATUS_NOTVERSIONED_NEWLOCALLY |
-		StatusInfo.STATUS_VERSIONED_UPTODATE |
-		StatusInfo.STATUS_VERSIONED_MODIFIEDLOCALLY |
-		StatusInfo.STATUS_VERSIONED_CONFLICT |
-		StatusInfo.STATUS_VERSIONED_REMOVEDLOCALLY |
-		StatusInfo.STATUS_VERSIONED_DELETEDLOCALLY |
-		StatusInfo.STATUS_VERSIONED_ADDEDLOCALLY;
-	private static final Pattern lessThan = Pattern.compile(&quot;&lt;&quot;);  // NOI18N
-	private static HtmlFormatter instance;
-	private String emptyFormat;
-	private Boolean needRevisionForFormat;
-	private MessageFormat format;
+    private static MessageFormat uptodateFormat = getFormat(&quot;uptodateFormat&quot;);  // NOI18N
+    private static MessageFormat newLocallyFormat = getFormat(&quot;newLocallyFormat&quot;);  // NOI18N
+    private static MessageFormat addedLocallyFormat = getFormat(&quot;addedLocallyFormat&quot;); // NOI18N
+    private static MessageFormat modifiedLocallyFormat = getFormat(&quot;modifiedLocallyFormat&quot;); // NOI18N
+    private static MessageFormat removedLocallyFormat = getFormat(&quot;removedLocallyFormat&quot;); // NOI18N
+    private static MessageFormat deletedLocallyFormat = getFormat(&quot;deletedLocallyFormat&quot;); // NOI18N
+    private static MessageFormat excludedFormat = getFormat(&quot;excludedFormat&quot;); // NOI18N
+    private static MessageFormat conflictFormat = getFormat(&quot;conflictFormat&quot;); // NOI18N
+    private static final int STATUS_TEXT_ANNOTABLE =
+        StatusInfo.STATUS_NOTVERSIONED_EXCLUDED |
+        StatusInfo.STATUS_NOTVERSIONED_NEWLOCALLY |
+        StatusInfo.STATUS_VERSIONED_UPTODATE |
+        StatusInfo.STATUS_VERSIONED_MODIFIEDLOCALLY |
+        StatusInfo.STATUS_VERSIONED_CONFLICT |
+        StatusInfo.STATUS_VERSIONED_REMOVEDLOCALLY |
+        StatusInfo.STATUS_VERSIONED_DELETEDLOCALLY |
+        StatusInfo.STATUS_VERSIONED_ADDEDLOCALLY;
+    private static final Pattern lessThan = Pattern.compile(&quot;&lt;&quot;);  // NOI18N
+    private static HtmlFormatter instance;
+    private String emptyFormat;
+    private Boolean needRevisionForFormat;
+    private MessageFormat format;
 
-	public static HtmlFormatter getInstance()
-	{
-		if (instance == null)
-			instance = new HtmlFormatter();
-		return instance;
-	}
+    public static HtmlFormatter getInstance()
+    {
+        if (instance == null)
+            instance = new HtmlFormatter();
+        return instance;
+    }
 
-	private HtmlFormatter()
-	{
-		initDefaults();
-	}
+    private HtmlFormatter()
+    {
+        initDefaults();
+    }
 
-	private void initDefaults()
-	{
-		Field[] fields = HtmlFormatter.class.getDeclaredFields();
-		for (int i = 0; i &lt; fields.length; i++) {
-			String name = fields[i].getName();
-			if (name.endsWith(&quot;Format&quot;))  // NOI18N
-				initDefaultColor(name.substring(0, name.length() - 6));
-		}
-		refresh();
-	}
+    private void initDefaults()
+    {
+        Field[] fields = HtmlFormatter.class.getDeclaredFields();
+        for (int i = 0; i &lt; fields.length; i++) {
+            String name = fields[i].getName();
+            if (name.endsWith(&quot;Format&quot;))  // NOI18N
+                initDefaultColor(name.substring(0, name.length() - 6));
+        }
+        refresh();
+    }
 
-	public void refresh()
-	{
-		String string = GitModuleConfig.getDefault().getAnnotationFormat();
-		if (string != null &amp;&amp; !string.trim().equals(&quot;&quot;)) { // NOI18N
-			needRevisionForFormat = isRevisionInAnnotationFormat(string);
-			string = string.replaceAll(&quot;\\{revision\\}&quot;, &quot;\\{0\\}&quot;);           // NOI18N
-			string = string.replaceAll(&quot;\\{status\\}&quot;, &quot;\\{1\\}&quot;);           // NOI18N
-			string = string.replaceAll(&quot;\\{folder\\}&quot;, &quot;\\{2\\}&quot;);           // NOI18N
-			format = new MessageFormat(string);
-			emptyFormat = format.format(new String[]{&quot;&quot;, &quot;&quot;, &quot;&quot;}, new StringBuffer(), null).toString().trim(); // NOI18N
-		}
-	}
+    public void refresh()
+    {
+        String string = GitModuleConfig.getDefault().getAnnotationFormat();
+        if (string != null &amp;&amp; !string.trim().equals(&quot;&quot;)) { // NOI18N
+            needRevisionForFormat = isRevisionInAnnotationFormat(string);
+            string = string.replaceAll(&quot;\\{revision\\}&quot;, &quot;\\{0\\}&quot;);           // NOI18N
+            string = string.replaceAll(&quot;\\{status\\}&quot;, &quot;\\{1\\}&quot;);           // NOI18N
+            string = string.replaceAll(&quot;\\{folder\\}&quot;, &quot;\\{2\\}&quot;);           // NOI18N
+            format = new MessageFormat(string);
+            emptyFormat = format.format(new String[]{&quot;&quot;, &quot;&quot;, &quot;&quot;}, new StringBuffer(), null).toString().trim(); // NOI18N
+        }
+    }
 
-	public static boolean isRevisionInAnnotationFormat(String str)
-	{
-		if (str.indexOf(&quot;{revision}&quot;) != -1) // NOI18N
-			return true;
-		else
-			return false;
-	}
+    public static boolean isRevisionInAnnotationFormat(String str)
+    {
+        if (str.indexOf(&quot;{revision}&quot;) != -1) // NOI18N
+            return true;
+        else
+            return false;
+    }
 
-	private void initDefaultColor(String name)
-	{
-		String color = System.getProperty(&quot;git.color.&quot; + name);  // NOI18N
-		if (color == null)
-			return;
-		setAnnotationColor(name, color);
-	}
+    private void initDefaultColor(String name)
+    {
+        String color = System.getProperty(&quot;git.color.&quot; + name);  // NOI18N
+        if (color == null)
+            return;
+        setAnnotationColor(name, color);
+    }
 
-	/**
-	 * Changes annotation color of files.
-	 *
-	 * @param name name of the color to change. Can be one of:
-	 * newLocally, addedLocally, modifiedLocally, removedLocally, deletedLocally, newInRepository, modifiedInRepository,
-	 * removedInRepository, conflict, mergeable, excluded.
-	 * @param colorString new color in the format: 4455AA (RGB hexadecimal)
-	 */
-	private void setAnnotationColor(String name, String colorString)
-	{
-		try {
-			Field field = HtmlFormatter.class.getDeclaredField(name + &quot;Format&quot;);  // NOI18N
-			MessageFormat msgFormat = new MessageFormat(&quot;&lt;font color=\&quot;&quot; + colorString + &quot;\&quot;&gt;{0}&lt;/font&gt;&lt;font color=\&quot;#999999\&quot;&gt;{1}&lt;/font&gt;&quot;);  // NOI18N
-			field.set(null, msgFormat);
-		} catch (Exception e) {
-			throw new IllegalArgumentException(&quot;Invalid color name&quot;);  // NOI18N
-		}
-	}
+    /**
+     * Changes annotation color of files.
+     *
+     * @param name name of the color to change. Can be one of:
+     * newLocally, addedLocally, modifiedLocally, removedLocally, deletedLocally, newInRepository, modifiedInRepository,
+     * removedInRepository, conflict, mergeable, excluded.
+     * @param colorString new color in the format: 4455AA (RGB hexadecimal)
+     */
+    private void setAnnotationColor(String name, String colorString)
+    {
+        try {
+            Field field = HtmlFormatter.class.getDeclaredField(name + &quot;Format&quot;);  // NOI18N
+            MessageFormat msgFormat = new MessageFormat(&quot;&lt;font color=\&quot;&quot; + colorString + &quot;\&quot;&gt;{0}&lt;/font&gt;&lt;font color=\&quot;#999999\&quot;&gt;{1}&lt;/font&gt;&quot;);  // NOI18N
+            field.set(null, msgFormat);
+        } catch (Exception e) {
+            throw new IllegalArgumentException(&quot;Invalid color name&quot;);  // NOI18N
+        }
+    }
 
-	public String annotateNameHtml(File file, StatusInfo info)
-	{
-		return annotateNameHtml(file.getName(), info, file);
-	}
+    public String annotateNameHtml(File file, StatusInfo info)
+    {
+        return annotateNameHtml(file.getName(), info, file);
+    }
 
-	public String annotateNameHtml(String name, StatusInfo mostImportantInfo, File mostImportantFile)
-	{
-		// Git: The codes used to show the status of files are:
-		// M = modified
-		// A = added
-		// R = removed
-		// C = clean
-		// ! = deleted, but still tracked
-		// ? = not tracked
-		// I = ignored (not shown by default)
+    public String annotateNameHtml(String name, StatusInfo mostImportantInfo, File mostImportantFile)
+    {
+        // Git: The codes used to show the status of files are:
+        // M = modified
+        // A = added
+        // R = removed
+        // C = clean
+        // ! = deleted, but still tracked
+        // ? = not tracked
+        // I = ignored (not shown by default)
 
-		name = htmlEncode(name);
+        name = htmlEncode(name);
 
-		String textAnnotation;
-		boolean annotationsVisible = VersioningSupport.getPreferences().getBoolean(VersioningSupport.PREF_BOOLEAN_TEXT_ANNOTATIONS_VISIBLE, false);
-		int status = mostImportantInfo.getStatus();
+        String textAnnotation;
+        boolean annotationsVisible = VersioningSupport.getPreferences().getBoolean(VersioningSupport.PREF_BOOLEAN_TEXT_ANNOTATIONS_VISIBLE, false);
+        int status = mostImportantInfo.getStatus();
 
-		if (annotationsVisible &amp;&amp; mostImportantFile != null &amp;&amp; (status &amp; STATUS_TEXT_ANNOTABLE) != 0)
-			if (format != null)
-				textAnnotation = formatAnnotation(mostImportantInfo, mostImportantFile);
-			else {
-				//String sticky = SvnUtils.getCopy(mostImportantFile);
-				String sticky = null;
-				if (status == StatusInfo.STATUS_VERSIONED_UPTODATE &amp;&amp; sticky == null)
-					textAnnotation = &quot;&quot;;
-				else if (status == StatusInfo.STATUS_VERSIONED_UPTODATE)
-					textAnnotation = &quot; [&quot; + sticky + &quot;]&quot;;
-				else if (sticky == null) {
-					String statusText = mostImportantInfo.getShortStatusText();
-					if (!statusText.equals(&quot;&quot;)) // NOI18N
-						textAnnotation = &quot; [&quot; + mostImportantInfo.getShortStatusText() + &quot;]&quot;;
-					else
-						textAnnotation = &quot;&quot;;
-				} else
-					textAnnotation = &quot; [&quot; + mostImportantInfo.getShortStatusText() + &quot;; &quot; + sticky + &quot;]&quot;;
-			}
-		else
-			textAnnotation = &quot;&quot;;
+        if (annotationsVisible &amp;&amp; mostImportantFile != null &amp;&amp; (status &amp; STATUS_TEXT_ANNOTABLE) != 0)
+            if (format != null)
+                textAnnotation = formatAnnotation(mostImportantInfo, mostImportantFile);
+            else {
+                //String sticky = SvnUtils.getCopy(mostImportantFile);
+                String sticky = null;
+                if (status == StatusInfo.STATUS_VERSIONED_UPTODATE &amp;&amp; sticky == null)
+                    textAnnotation = &quot;&quot;;
+                else if (status == StatusInfo.STATUS_VERSIONED_UPTODATE)
+                    textAnnotation = &quot; [&quot; + sticky + &quot;]&quot;;
+                else if (sticky == null) {
+                    String statusText = mostImportantInfo.getShortStatusText();
+                    if (!statusText.equals(&quot;&quot;)) // NOI18N
+                        textAnnotation = &quot; [&quot; + mostImportantInfo.getShortStatusText() + &quot;]&quot;;
+                    else
+                        textAnnotation = &quot;&quot;;
+                } else
+                    textAnnotation = &quot; [&quot; + mostImportantInfo.getShortStatusText() + &quot;; &quot; + sticky + &quot;]&quot;;
+            }
+        else
+            textAnnotation = &quot;&quot;;
 
-		if (textAnnotation.length() &gt; 0)
-			textAnnotation = NbBundle.getMessage(HtmlFormatter.class, &quot;textAnnotation&quot;, textAnnotation);
+        if (textAnnotation.length() &gt; 0)
+            textAnnotation = NbBundle.getMessage(HtmlFormatter.class, &quot;textAnnotation&quot;, textAnnotation);
 
-		if (0 != (status &amp; StatusInfo.STATUS_NOTVERSIONED_EXCLUDED))
-			return excludedFormat.format(new Object[]{name, textAnnotation});
-		else if (0 != (status &amp; StatusInfo.STATUS_VERSIONED_DELETEDLOCALLY))
-			return deletedLocallyFormat.format(new Object[]{name, textAnnotation});
-		else if (0 != (status &amp; StatusInfo.STATUS_VERSIONED_REMOVEDLOCALLY))
-			return removedLocallyFormat.format(new Object[]{name, textAnnotation});
-		else if (0 != (status &amp; StatusInfo.STATUS_NOTVERSIONED_NEWLOCALLY))
-			return newLocallyFormat.format(new Object[]{name, textAnnotation});
-		else if (0 != (status &amp; StatusInfo.STATUS_VERSIONED_ADDEDLOCALLY))
-			return addedLocallyFormat.format(new Object[]{name, textAnnotation});
-		else if (0 != (status &amp; StatusInfo.STATUS_VERSIONED_MODIFIEDLOCALLY))
-			return modifiedLocallyFormat.format(new Object[]{name, textAnnotation});
-		else if (0 != (status &amp; StatusInfo.STATUS_VERSIONED_UPTODATE))
-			return uptodateFormat.format(new Object[]{name, textAnnotation});
-		else if (0 != (status &amp; StatusInfo.STATUS_VERSIONED_CONFLICT))
-			return conflictFormat.format(new Object[]{name, textAnnotation});
-		else if (0 != (status &amp; StatusInfo.STATUS_NOTVERSIONED_NOTMANAGED))
-			return name;
-		else if (status == StatusInfo.STATUS_UNKNOWN)
-			return name;
-		else
-			throw new IllegalArgumentException(&quot;Uncomparable status: &quot; + status);
-	}
+        if (0 != (status &amp; StatusInfo.STATUS_NOTVERSIONED_EXCLUDED))
+            return excludedFormat.format(new Object[]{name, textAnnotation});
+        else if (0 != (status &amp; StatusInfo.STATUS_VERSIONED_DELETEDLOCALLY))
+            return deletedLocallyFormat.format(new Object[]{name, textAnnotation});
+        else if (0 != (status &amp; StatusInfo.STATUS_VERSIONED_REMOVEDLOCALLY))
+            return removedLocallyFormat.format(new Object[]{name, textAnnotation});
+        else if (0 != (status &amp; StatusInfo.STATUS_NOTVERSIONED_NEWLOCALLY))
+            return newLocallyFormat.format(new Object[]{name, textAnnotation});
+        else if (0 != (status &amp; StatusInfo.STATUS_VERSIONED_ADDEDLOCALLY))
+            return addedLocallyFormat.format(new Object[]{name, textAnnotation});
+        else if (0 != (status &amp; StatusInfo.STATUS_VERSIONED_MODIFIEDLOCALLY))
+            return modifiedLocallyFormat.format(new Object[]{name, textAnnotation});
+        else if (0 != (status &amp; StatusInfo.STATUS_VERSIONED_UPTODATE))
+            return uptodateFormat.format(new Object[]{name, textAnnotation});
+        else if (0 != (status &amp; StatusInfo.STATUS_VERSIONED_CONFLICT))
+            return conflictFormat.format(new Object[]{name, textAnnotation});
+        else if (0 != (status &amp; StatusInfo.STATUS_NOTVERSIONED_NOTMANAGED))
+            return name;
+        else if (status == StatusInfo.STATUS_UNKNOWN)
+            return name;
+        else
+            throw new IllegalArgumentException(&quot;Uncomparable status: &quot; + status);
+    }
 
-	private static MessageFormat getFormat(String key)
-	{
-		String format = NbBundle.getMessage(HtmlFormatter.class, key);
-		return new MessageFormat(format);
-	}
+    private static MessageFormat getFormat(String key)
+    {
+        String format = NbBundle.getMessage(HtmlFormatter.class, key);
+        return new MessageFormat(format);
+    }
 
-	private String htmlEncode(String name)
-	{
-		if (name.indexOf('&lt;') == -1)
-			return name;
-		return lessThan.matcher(name).replaceAll(&quot;&amp;lt;&quot;); // NOI18N
-	}
+    private String htmlEncode(String name)
+    {
+        if (name.indexOf('&lt;') == -1)
+            return name;
+        return lessThan.matcher(name).replaceAll(&quot;&amp;lt;&quot;); // NOI18N
+    }
 
-	/**
-	 * Applies custom format.
-	 */
-	private String formatAnnotation(StatusInfo info, File file)
-	{
-		String statusString = &quot;&quot;;  // NOI18N
-		int status = info.getStatus();
-		if (status != StatusInfo.STATUS_VERSIONED_UPTODATE)
-			statusString = info.getShortStatusText();
+    /**
+     * Applies custom format.
+     */
+    private String formatAnnotation(StatusInfo info, File file)
+    {
+        String statusString = &quot;&quot;;  // NOI18N
+        int status = info.getStatus();
+        if (status != StatusInfo.STATUS_VERSIONED_UPTODATE)
+            statusString = info.getShortStatusText();
 
-		String revisionString = &quot;&quot;;     // NOI18N
-		String binaryString = &quot;&quot;;       // NOI18N
+        String revisionString = &quot;&quot;;     // NOI18N
+        String binaryString = &quot;&quot;;       // NOI18N
 
-		if (needRevisionForFormat)
-			if ((status &amp; StatusInfo.STATUS_NOTVERSIONED_EXCLUDED) == 0)
-				try {
-					File root = Git.getInstance().getTopmostManagedParent(file);
-					Repository repo = Git.getInstance().getRepository(root);
-					ObjectId branch = repo.resolve(repo.getFullBranch());
-					String absPath = file.getAbsolutePath();
-					String relPath = absPath.replace(root.getAbsolutePath(), &quot;&quot;);
-					RevWalk walk = new RevWalk(repo);
-					RevCommit start = walk.parseCommit(branch);
-					TreeFilter filter = PathFilter.create(relPath);
+        if (needRevisionForFormat)
+            if ((status &amp; StatusInfo.STATUS_NOTVERSIONED_EXCLUDED) == 0)
+                try {
+                    File root = Git.getInstance().getTopmostManagedParent(file);
+                    Repository repo = Git.getInstance().getRepository(root);
+                    ObjectId branch = repo.resolve(repo.getFullBranch());
+                    String absPath = file.getAbsolutePath();
+                    String relPath = absPath.replace(root.getAbsolutePath(), &quot;&quot;);
+                    RevWalk walk = new RevWalk(repo);
+                    RevCommit start = walk.parseCommit(branch);
+                    TreeFilter filter = PathFilter.create(relPath);
 
-					walk.setTreeFilter(filter);
-					walk.markStart(start);
+                    walk.setTreeFilter(filter);
+                    walk.markStart(start);
 
-					for (RevCommit commit : walk) {
-						revisionString = commit.getId().toString();
-						break;
-					}
-					walk.dispose();
+                    for (RevCommit commit : walk) {
+                        revisionString = commit.getId().toString();
+                        break;
+                    }
+                    walk.dispose();
 
-				} catch (IOException ex) {
-					NotifyDescriptor.Exception e = new NotifyDescriptor.Exception(ex);
-					DialogDisplayer.getDefault().notifyLater(e);
-				}
+                } catch (IOException ex) {
+                    NotifyDescriptor.Exception e = new NotifyDescriptor.Exception(ex);
+                    DialogDisplayer.getDefault().notifyLater(e);
+                }
 
-		//String stickyString = SvnUtils.getCopy(file);
-		String stickyString = null;
-		if (stickyString == null)
-			stickyString = &quot;&quot;;
+        //String stickyString = SvnUtils.getCopy(file);
+        String stickyString = null;
+        if (stickyString == null)
+            stickyString = &quot;&quot;;
 
-		Object[] arguments = new Object[]{
-			revisionString,
-			statusString,
-			stickyString,
-		};
+        Object[] arguments = new Object[]{
+            revisionString,
+            statusString,
+            stickyString,
+        };
 
-		String annotation = format.format(arguments, new StringBuffer(), null).toString().trim();
-		if (annotation.equals(emptyFormat))
-			return &quot;&quot;;
-		else
-			return &quot; &quot; + annotation;
-	}
+        String annotation = format.format(arguments, new StringBuffer(), null).toString().trim();
+        if (annotation.equals(emptyFormat))
+            return &quot;&quot;;
+        else
+            return &quot; &quot; + annotation;
+    }
 
-	public String annotateFolderNameHtml(String name, StatusInfo mostImportantInfo, File mostImportantFile)
-	{
-		String nameHtml = htmlEncode(name);
-		if (mostImportantInfo.getStatus() == StatusInfo.STATUS_NOTVERSIONED_EXCLUDED)
-			return excludedFormat.format(new Object[]{nameHtml, &quot;&quot;});
-		String fileName = mostImportantFile.getName();
-		if (fileName.equals(name))
-			return uptodateFormat.format(new Object[]{nameHtml, &quot;&quot;});
+    public String annotateFolderNameHtml(String name, StatusInfo mostImportantInfo, File mostImportantFile)
+    {
+        String nameHtml = htmlEncode(name);
+        if (mostImportantInfo.getStatus() == StatusInfo.STATUS_NOTVERSIONED_EXCLUDED)
+            return excludedFormat.format(new Object[]{nameHtml, &quot;&quot;});
+        String fileName = mostImportantFile.getName();
+        if (fileName.equals(name))
+            return uptodateFormat.format(new Object[]{nameHtml, &quot;&quot;});
 
-		// Label top level repository nodes with a repository name label when:
-		// Display Name (name) is different from its repo name (repo.getName())
-		fileName = null;
-		File repo = Git.getInstance().getTopmostManagedParent(mostImportantFile);
-		if (repo != null &amp;&amp; repo.equals(mostImportantFile))
-			if (!repo.getName().equals(name))
-				fileName = repo.getName();
-		if (fileName != null)
-			return uptodateFormat.format(new Object[]{nameHtml, &quot; [&quot; + fileName + &quot;]&quot;}); // NOI18N
-		else
-			return uptodateFormat.format(new Object[]{nameHtml, &quot;&quot;}); // NOI18N
-	}
+        // Label top level repository nodes with a repository name label when:
+        // Display Name (name) is different from its repo name (repo.getName())
+        fileName = null;
+        File repo = Git.getInstance().getTopmostManagedParent(mostImportantFile);
+        if (repo != null &amp;&amp; repo.equals(mostImportantFile))
+            if (!repo.getName().equals(name))
+                fileName = repo.getName();
+        if (fileName != null)
+            return uptodateFormat.format(new Object[]{nameHtml, &quot; [&quot; + fileName + &quot;]&quot;}); // NOI18N
+        else
+            return uptodateFormat.format(new Object[]{nameHtml, &quot;&quot;}); // NOI18N
+    }
 
 }</diff>
      <filename>src/org/nbgit/util/HtmlFormatter.java</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>24282ebfe1b8e8148890158f929d386493069964</id>
    </parent>
  </parents>
  <author>
    <name>Alex Coles</name>
    <email>alexbcoles@mac.com</email>
  </author>
  <url>http://github.com/myabc/nbgit/commit/c62bbad6ff323a1e710a69e295012701b49f3357</url>
  <id>c62bbad6ff323a1e710a69e295012701b49f3357</id>
  <committed-date>2008-09-05T11:26:42-07:00</committed-date>
  <authored-date>2008-09-05T11:26:42-07:00</authored-date>
  <message>Cleanup code whitespace

* Convert tabs to spaces.
* Strip EOL whitespace.

Signed-off-by: Alex Coles &lt;alexbcoles@mac.com&gt;</message>
  <tree>94c20949f895959e3034890058d3fc2d4228011f</tree>
  <committer>
    <name>Alex Coles</name>
    <email>alexbcoles@mac.com</email>
  </committer>
</commit>
