Merge branch 'ticket/167' into develop
diff --git a/.classpath b/.classpath
index f6e655e..53faa53 100644
--- a/.classpath
+++ b/.classpath
@@ -5,27 +5,28 @@
 	<classpathentry kind="src" path="src/test/java" output="bin/test-classes" />
 	<classpathentry kind="src" path="src/test/bugtraq" output="bin/test-classes" />
 	<classpathentry kind="src" path="src/main/resources" />
-	<classpathentry kind="lib" path="ext/dagger-1.1.0.jar" sourcepath="ext/src/dagger-1.1.0.jar" />
+	<classpathentry kind="lib" path="ext/guice-4.0-beta4.jar" sourcepath="ext/src/guice-4.0-beta4.jar" />
 	<classpathentry kind="lib" path="ext/javax.inject-1.jar" sourcepath="ext/src/javax.inject-1.jar" />
-	<classpathentry kind="lib" path="ext/dagger-compiler-1.1.0.jar" sourcepath="ext/src/dagger-compiler-1.1.0.jar" />
-	<classpathentry kind="lib" path="ext/javawriter-2.1.1.jar" sourcepath="ext/src/javawriter-2.1.1.jar" />
+	<classpathentry kind="lib" path="ext/aopalliance-1.0.jar" sourcepath="ext/src/aopalliance-1.0.jar" />
+	<classpathentry kind="lib" path="ext/guava-17.0.jar" sourcepath="ext/src/guava-17.0.jar" />
+	<classpathentry kind="lib" path="ext/guice-servlet-4.0-gb1.jar" sourcepath="ext/src/guice-servlet-4.0-gb1.jar" />
 	<classpathentry kind="lib" path="ext/annotations-12.0.jar" sourcepath="ext/src/annotations-12.0.jar" />
 	<classpathentry kind="lib" path="ext/log4j-1.2.17.jar" sourcepath="ext/src/log4j-1.2.17.jar" />
-	<classpathentry kind="lib" path="ext/slf4j-api-1.7.5.jar" sourcepath="ext/src/slf4j-api-1.7.5.jar" />
-	<classpathentry kind="lib" path="ext/slf4j-log4j12-1.7.5.jar" sourcepath="ext/src/slf4j-log4j12-1.7.5.jar" />
+	<classpathentry kind="lib" path="ext/slf4j-api-1.7.7.jar" sourcepath="ext/src/slf4j-api-1.7.7.jar" />
+	<classpathentry kind="lib" path="ext/slf4j-log4j12-1.7.7.jar" sourcepath="ext/src/slf4j-log4j12-1.7.7.jar" />
 	<classpathentry kind="lib" path="ext/javax.mail-1.5.1.jar" sourcepath="ext/src/javax.mail-1.5.1.jar" />
 	<classpathentry kind="lib" path="ext/javax.servlet-api-3.1.0.jar" sourcepath="ext/src/javax.servlet-api-3.1.0.jar" />
-	<classpathentry kind="lib" path="ext/jetty-all-9.1.4.v20140401.jar" sourcepath="ext/src/jetty-all-9.1.4.v20140401.jar" />
+	<classpathentry kind="lib" path="ext/jetty-all-9.2.2.v20140723.jar" sourcepath="ext/src/jetty-all-9.2.2.v20140723.jar" />
 	<classpathentry kind="lib" path="ext/wicket-1.4.21.jar" sourcepath="ext/src/wicket-1.4.21.jar" />
 	<classpathentry kind="lib" path="ext/wicket-auth-roles-1.4.21.jar" sourcepath="ext/src/wicket-auth-roles-1.4.21.jar" />
 	<classpathentry kind="lib" path="ext/wicket-extensions-1.4.21.jar" sourcepath="ext/src/wicket-extensions-1.4.21.jar" />
-	<classpathentry kind="lib" path="ext/lucene-core-4.6.0.jar" sourcepath="ext/src/lucene-core-4.6.0.jar" />
-	<classpathentry kind="lib" path="ext/lucene-analyzers-common-4.6.0.jar" sourcepath="ext/src/lucene-analyzers-common-4.6.0.jar" />
-	<classpathentry kind="lib" path="ext/lucene-highlighter-4.6.0.jar" sourcepath="ext/src/lucene-highlighter-4.6.0.jar" />
-	<classpathentry kind="lib" path="ext/lucene-memory-4.6.0.jar" sourcepath="ext/src/lucene-memory-4.6.0.jar" />
-	<classpathentry kind="lib" path="ext/lucene-queries-4.6.0.jar" sourcepath="ext/src/lucene-queries-4.6.0.jar" />
-	<classpathentry kind="lib" path="ext/lucene-queryparser-4.6.0.jar" sourcepath="ext/src/lucene-queryparser-4.6.0.jar" />
-	<classpathentry kind="lib" path="ext/lucene-sandbox-4.6.0.jar" sourcepath="ext/src/lucene-sandbox-4.6.0.jar" />
+	<classpathentry kind="lib" path="ext/lucene-core-4.10.0.jar" sourcepath="ext/src/lucene-core-4.10.0.jar" />
+	<classpathentry kind="lib" path="ext/lucene-analyzers-common-4.10.0.jar" sourcepath="ext/src/lucene-analyzers-common-4.10.0.jar" />
+	<classpathentry kind="lib" path="ext/lucene-highlighter-4.10.0.jar" sourcepath="ext/src/lucene-highlighter-4.10.0.jar" />
+	<classpathentry kind="lib" path="ext/lucene-memory-4.10.0.jar" sourcepath="ext/src/lucene-memory-4.10.0.jar" />
+	<classpathentry kind="lib" path="ext/lucene-queries-4.10.0.jar" sourcepath="ext/src/lucene-queries-4.10.0.jar" />
+	<classpathentry kind="lib" path="ext/lucene-queryparser-4.10.0.jar" sourcepath="ext/src/lucene-queryparser-4.10.0.jar" />
+	<classpathentry kind="lib" path="ext/lucene-sandbox-4.10.0.jar" sourcepath="ext/src/lucene-sandbox-4.10.0.jar" />
 	<classpathentry kind="lib" path="ext/jakarta-regexp-1.4.jar" />
 	<classpathentry kind="lib" path="ext/pegdown-1.4.2.jar" sourcepath="ext/src/pegdown-1.4.2.jar" />
 	<classpathentry kind="lib" path="ext/parboiled-java-1.1.6.jar" sourcepath="ext/src/parboiled-java-1.1.6.jar" />
@@ -40,23 +41,23 @@
 	<classpathentry kind="lib" path="ext/tracwiki-core-1.4.jar" sourcepath="ext/src/tracwiki-core-1.4.jar" />
 	<classpathentry kind="lib" path="ext/mediawiki-core-1.4.jar" sourcepath="ext/src/mediawiki-core-1.4.jar" />
 	<classpathentry kind="lib" path="ext/confluence-core-1.4.jar" sourcepath="ext/src/confluence-core-1.4.jar" />
-	<classpathentry kind="lib" path="ext/org.eclipse.jgit-3.3.1.201403241930-r.jar" sourcepath="ext/src/org.eclipse.jgit-3.3.1.201403241930-r.jar" />
+	<classpathentry kind="lib" path="ext/org.eclipse.jgit-3.4.1.201406201815-r.jar" sourcepath="ext/src/org.eclipse.jgit-3.4.1.201406201815-r.jar" />
 	<classpathentry kind="lib" path="ext/jsch-0.1.50.jar" sourcepath="ext/src/jsch-0.1.50.jar" />
 	<classpathentry kind="lib" path="ext/JavaEWAH-0.7.9.jar" sourcepath="ext/src/JavaEWAH-0.7.9.jar" />
 	<classpathentry kind="lib" path="ext/httpclient-4.1.3.jar" sourcepath="ext/src/httpclient-4.1.3.jar" />
 	<classpathentry kind="lib" path="ext/httpcore-4.1.4.jar" sourcepath="ext/src/httpcore-4.1.4.jar" />
 	<classpathentry kind="lib" path="ext/commons-logging-1.1.1.jar" sourcepath="ext/src/commons-logging-1.1.1.jar" />
 	<classpathentry kind="lib" path="ext/commons-codec-1.7.jar" sourcepath="ext/src/commons-codec-1.7.jar" />
-	<classpathentry kind="lib" path="ext/org.eclipse.jgit.http.server-3.3.1.201403241930-r.jar" sourcepath="ext/src/org.eclipse.jgit.http.server-3.3.1.201403241930-r.jar" />
+	<classpathentry kind="lib" path="ext/org.eclipse.jgit.http.server-3.4.1.201406201815-r.jar" sourcepath="ext/src/org.eclipse.jgit.http.server-3.4.1.201406201815-r.jar" />
 	<classpathentry kind="lib" path="ext/bcprov-jdk15on-1.49.jar" sourcepath="ext/src/bcprov-jdk15on-1.49.jar" />
 	<classpathentry kind="lib" path="ext/bcmail-jdk15on-1.49.jar" sourcepath="ext/src/bcmail-jdk15on-1.49.jar" />
 	<classpathentry kind="lib" path="ext/bcpkix-jdk15on-1.49.jar" sourcepath="ext/src/bcpkix-jdk15on-1.49.jar" />
-	<classpathentry kind="lib" path="ext/sshd-core-0.11.1-atlassian-1.jar" sourcepath="ext/src/sshd-core-0.11.1-atlassian-1.jar" />
+	<classpathentry kind="lib" path="ext/sshd-core-0.12.0.jar" sourcepath="ext/src/sshd-core-0.12.0.jar" />
 	<classpathentry kind="lib" path="ext/mina-core-2.0.7.jar" sourcepath="ext/src/mina-core-2.0.7.jar" />
 	<classpathentry kind="lib" path="ext/rome-0.9.jar" sourcepath="ext/src/rome-0.9.jar" />
 	<classpathentry kind="lib" path="ext/jdom-1.0.jar" sourcepath="ext/src/jdom-1.0.jar" />
-	<classpathentry kind="lib" path="ext/gson-1.7.2.jar" sourcepath="ext/src/gson-1.7.2.jar" />
-	<classpathentry kind="lib" path="ext/groovy-all-1.8.8.jar" sourcepath="ext/src/groovy-all-1.8.8.jar" />
+	<classpathentry kind="lib" path="ext/gson-2.2.2.jar" sourcepath="ext/src/gson-2.2.2.jar" />
+	<classpathentry kind="lib" path="ext/groovy-all-2.3.3.jar" sourcepath="ext/src/groovy-all-2.3.3.jar" />
 	<classpathentry kind="lib" path="ext/unboundid-ldapsdk-2.3.0.jar" sourcepath="ext/src/unboundid-ldapsdk-2.3.0.jar" />
 	<classpathentry kind="lib" path="ext/ivy-2.2.0.jar" sourcepath="ext/src/ivy-2.2.0.jar" />
 	<classpathentry kind="lib" path="ext/jcalendar-1.3.2.jar" />
@@ -66,16 +67,15 @@
 	<classpathentry kind="lib" path="ext/force-partner-api-24.0.0.jar" sourcepath="ext/src/force-partner-api-24.0.0.jar" />
 	<classpathentry kind="lib" path="ext/force-wsc-24.0.0.jar" sourcepath="ext/src/force-wsc-24.0.0.jar" />
 	<classpathentry kind="lib" path="ext/js-1.7R2.jar" sourcepath="ext/src/js-1.7R2.jar" />
-	<classpathentry kind="lib" path="ext/freemarker-2.3.19.jar" sourcepath="ext/src/freemarker-2.3.19.jar" />
+	<classpathentry kind="lib" path="ext/freemarker-2.3.20.jar" sourcepath="ext/src/freemarker-2.3.20.jar" />
 	<classpathentry kind="lib" path="ext/waffle-jna-1.5.jar" sourcepath="ext/src/waffle-jna-1.5.jar" />
 	<classpathentry kind="lib" path="ext/platform-3.5.0.jar" sourcepath="ext/src/platform-3.5.0.jar" />
 	<classpathentry kind="lib" path="ext/jna-3.5.0.jar" sourcepath="ext/src/jna-3.5.0.jar" />
-	<classpathentry kind="lib" path="ext/guava-13.0.1.jar" sourcepath="ext/src/guava-13.0.1.jar" />
 	<classpathentry kind="lib" path="ext/libpam4j-1.7.jar" sourcepath="ext/src/libpam4j-1.7.jar" />
 	<classpathentry kind="lib" path="ext/args4j-2.0.26.jar" sourcepath="ext/src/args4j-2.0.26.jar" />
 	<classpathentry kind="lib" path="ext/jedis-2.3.1.jar" sourcepath="ext/src/jedis-2.3.1.jar" />
 	<classpathentry kind="lib" path="ext/commons-pool2-2.0.jar" sourcepath="ext/src/commons-pool2-2.0.jar" />
-	<classpathentry kind="lib" path="ext/pf4j-0.8.0.jar" sourcepath="ext/src/pf4j-0.8.0.jar" />
+	<classpathentry kind="lib" path="ext/pf4j-0.9.0.jar" sourcepath="ext/src/pf4j-0.9.0.jar" />
 	<classpathentry kind="lib" path="ext/tika-core-1.5.jar" sourcepath="ext/src/tika-core-1.5.jar" />
 	<classpathentry kind="lib" path="ext/junit-4.11.jar" sourcepath="ext/src/junit-4.11.jar" />
 	<classpathentry kind="lib" path="ext/hamcrest-core-1.3.jar" sourcepath="ext/src/hamcrest-core-1.3.jar" />
diff --git a/NOTICE b/NOTICE
index da61b20..69d7c74 100644
--- a/NOTICE
+++ b/NOTICE
@@ -358,3 +358,12 @@
    Apache License 2.0
 
    https://github.com/decebals/pf4j
+
+---------------------------------------------------------------------------
+google-guice
+---------------------------------------------------------------------------
+   google-guice, release under the 
+   Apache License 2.0
+
+   https://code.google.com/p/google-guice
+   
\ No newline at end of file
diff --git a/build.moxie b/build.moxie
index 0801644..ea2763c 100644
--- a/build.moxie
+++ b/build.moxie
@@ -3,14 +3,14 @@
 #
 
 # Specify minimum Moxie version required to build
-requires: 0.9.3
+requires: 0.9.4
 
 # Project Metadata
 name: Gitblit
 description: pure Java Git solution
 groupId: com.gitblit
 artifactId: gitblit
-version: 1.6.1-SNAPSHOT
+version: 1.7.0-SNAPSHOT
 inceptionYear: 2011
 
 # Current stable release
@@ -58,7 +58,7 @@
 sourceDirectories:
 - compile 'src/main/java'
 - compile 'src/main/bugtraq'
-- compile 'src/main/dagger' apt
+- compile 'src/main/gen' apt
 - test 'src/test/java'
 - test 'src/test/bugtraq'
 # Moxie supports one site-scoped directory for mx:doc
@@ -95,23 +95,26 @@
 registeredRepositories:
 - { id: eclipse, url: 'http://repo.eclipse.org/content/groups/releases' }
 - { id: eclipse-snapshots, url: 'http://repo.eclipse.org/content/groups/snapshots' }
-- { id: atlassian-contrib, url: 'https://maven.atlassian.com/content/repositories/atlassian-3rdparty' }
+- { id: gitblit, url: 'http://gitblit.github.io/gitblit-maven' }
 
 # Source all dependencies from the following repositories in the specified order
-repositories: central, eclipse-snapshots, eclipse, atlassian-contrib
+repositories: central, eclipse-snapshots, eclipse, gitblit
 
 # Convenience properties for dependencies
 properties: {
-  jetty.version  : 9.1.4.v20140401
+  jetty.version  : 9.2.2.v20140723
   wicket.version : 1.4.21
-  lucene.version : 4.6.0
-  jgit.version   : 3.3.1.201403241930-r
-  groovy.version : 1.8.8
+  lucene.version : 4.10.0
+  jgit.version   : 3.4.1.201406201815-r
+  groovy.version : 2.3.3
   bouncycastle.version : 1.49
   selenium.version : 2.28.0
   wikitext.version : 1.4
-  sshd.version: 0.11.1-atlassian-1
+  sshd.version: 0.12.0
   mina.version: 2.0.7
+  guice.version : 4.0-beta4
+  # Gitblit maintains a fork of guice-servlet
+  guice-servlet.version : 4.0-gb1
   }
 
 # Dependencies
@@ -126,15 +129,14 @@
 #
 
 dependencies:
-# Dagger dependency injection library (annotation processor)
-- compile 'com.squareup.dagger:dagger:1.1.0' :war apt
-- compile 'com.squareup.dagger:dagger-compiler:1.1.0' :war optional apt
-# Standard dependencies
+- compile 'com.google.inject:guice:${guice.version}' :war :fedclient
+- compile 'com.google.inject.extensions:guice-servlet:${guice-servlet.version}' :war
+- compile 'com.google.guava:guava:17.0' :war :fedclient
 - compile 'com.intellij:annotations:12.0' :war
-- compile 'log4j:log4j:1.2.17' :war :fedclient :authority
-- compile 'org.slf4j:slf4j-api:1.7.5' :war :fedclient :authority
-- compile 'org.slf4j:slf4j-log4j12:1.7.5' :war :fedclient :authority
-- compile 'com.sun.mail:javax.mail:1.5.1' :war :authority
+- compile 'log4j:log4j:1.2.17' :war :fedclient
+- compile 'org.slf4j:slf4j-api:1.7.7' :war :fedclient
+- compile 'org.slf4j:slf4j-log4j12:1.7.7' :war :fedclient
+- compile 'com.sun.mail:javax.mail:1.5.1' :war
 - compile 'javax.servlet:javax.servlet-api:3.1.0' :fedclient
 - compile 'org.eclipse.jetty.aggregate:jetty-all:${jetty.version}' @jar
 - compile 'org.apache.wicket:wicket:${wicket.version}' :war !org.mockito
@@ -152,15 +154,15 @@
 - compile 'org.fusesource.wikitext:tracwiki-core:${wikitext.version}' :war
 - compile 'org.fusesource.wikitext:mediawiki-core:${wikitext.version}' :war
 - compile 'org.fusesource.wikitext:confluence-core:${wikitext.version}' :war
-- compile 'org.eclipse.jgit:org.eclipse.jgit:${jgit.version}' :war :fedclient :manager :authority !junit
-- compile 'org.eclipse.jgit:org.eclipse.jgit.http.server:${jgit.version}' :war :manager :authority !junit
-- compile 'org.bouncycastle:bcprov-jdk15on:${bouncycastle.version}' :war :authority
-- compile 'org.bouncycastle:bcmail-jdk15on:${bouncycastle.version}' :war :authority
-- compile 'org.bouncycastle:bcpkix-jdk15on:${bouncycastle.version}' :war :authority
+- compile 'org.eclipse.jgit:org.eclipse.jgit:${jgit.version}' :war :fedclient :manager !junit
+- compile 'org.eclipse.jgit:org.eclipse.jgit.http.server:${jgit.version}' :war :manager !junit
+- compile 'org.bouncycastle:bcprov-jdk15on:${bouncycastle.version}' :war
+- compile 'org.bouncycastle:bcmail-jdk15on:${bouncycastle.version}' :war
+- compile 'org.bouncycastle:bcpkix-jdk15on:${bouncycastle.version}' :war
 - compile 'org.apache.sshd:sshd-core:${sshd.version}' :war !org.easymock
 - compile 'org.apache.mina:mina-core:${mina.version}' :war !org.easymock
 - compile 'rome:rome:0.9' :war :manager :api
-- compile 'com.google.code.gson:gson:1.7.2' :war :fedclient :manager :api
+- compile 'com.google.code.gson:gson:2.2.2' :war :fedclient :manager :api
 - compile 'org.codehaus.groovy:groovy-all:${groovy.version}' :war
 - compile 'com.unboundid:unboundid-ldapsdk:2.3.0' :war
 - compile 'org.apache.ivy:ivy:2.2.0' :war
@@ -168,13 +170,13 @@
 - compile 'org.apache.commons:commons-compress:1.4.1' :war
 - compile 'commons-io:commons-io:2.2' :war
 - compile 'com.force.api:force-partner-api:24.0.0' :war
-- compile 'org.freemarker:freemarker:2.3.19' :war
+- compile 'org.freemarker:freemarker:2.3.20' :war
 - compile 'com.github.dblock.waffle:waffle-jna:1.5' :war
 - compile 'org.kohsuke:libpam4j:1.7' :war
-- compile 'args4j:args4j:2.0.26' :war :fedclient :authority
+- compile 'args4j:args4j:2.0.26' :war :fedclient
 - compile 'commons-codec:commons-codec:1.7' :war
 - compile 'redis.clients:jedis:2.3.1' :war
-- compile 'ro.fortsoft.pf4j:pf4j:0.8.0' :war
+- compile 'ro.fortsoft.pf4j:pf4j:0.9.0' :war
 - compile 'org.apache.tika:tika-core:1.5' :war
 - test 'junit'
 # Dependencies for Selenium web page testing
diff --git a/build.xml b/build.xml
index fa02ee3..8128f6f 100644
--- a/build.xml
+++ b/build.xml
@@ -8,7 +8,7 @@
 		documentation @ http://gitblit.github.io/moxie

 		~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

 	-->

-	<property name="moxie.version" value="0.9.3" />

+	<property name="moxie.version" value="0.9.4" />

 	<property name="moxie.url" value="http://gitblit.github.io/moxie/maven" />

 	<property name="moxie.jar" value="moxie-toolkit-${moxie.version}.jar" />

 	<property name="moxie.dir" value="${user.home}/.moxie" />

@@ -41,9 +41,10 @@
 		<mx:init verbose="no" mxroot="${moxie.dir}" />

 				

 		<!-- Set Ant project properties -->

-		<property name="distribution.zipfile" value="gitblit-${project.version}.zip" />

-		<property name="distribution.tgzfile" value="gitblit-${project.version}.tar.gz" />

-		<property name="distribution.warfile" value="gitblit-${project.version}.war" />

+		<property name="release.name" value="gitblit-${project.version}"/>

+		<property name="distribution.zipfile" value="${release.name}.zip" />

+		<property name="distribution.tgzfile" value="${release.name}.tar.gz" />

+		<property name="distribution.warfile" value="${release.name}.war" />

 		<property name="fedclient.zipfile" value="fedclient-${project.version}.zip" />

 		<property name="manager.zipfile" value="manager-${project.version}.zip" />

 		<property name="authority.zipfile" value="authority-${project.version}.zip" />

@@ -170,14 +171,17 @@
 		

 		<echo>Building Gitblit GO ${project.version}</echo>

 

-		<local name="go.dir" />

-		<property name="go.dir" value="${project.outputDirectory}/go" />	

+		<local name="go.dir"/>

+		<property name="go.dir" value="${project.outputDirectory}/go"/>

 		<delete dir="${go.dir}" />

+		

+		<local name="go.release.dir" />

+		<property name="go.release.dir" value="${go.dir}/${release.name}" />	

 

 		<local name="webinf" />

 		<property name="webinf" value="${project.compileOutputDirectory}/WEB-INF" />

 

-		<prepareDataDirectory toDir="${go.dir}/data" />

+		<prepareDataDirectory toDir="${go.release.dir}/data" />

 		

 		<!-- Copy the web.xml from the prototype web.xml -->

 		<copy todir="${webinf}" overwrite="true">

@@ -188,42 +192,43 @@
 		</copy>

 		

 		<!-- Build jar -->

-		<mx:jar destfile="${go.dir}/gitblit.jar" includeresources="true">

+		<mx:jar destfile="${go.release.dir}/gitblit.jar" includeresources="true">

 			<mainclass name="com.gitblit.GitBlitServer" />

 			<launcher paths="ext" />

 		</mx:jar>

 

 		<!-- Generate the docs for the GO build -->

-		<generateDocs toDir="${go.dir}/docs" />

-		

+		<generateDocs toDir="${go.release.dir}/docs" />

+

 		<!-- Create GO Windows Zip deployment -->

 		<mx:zip basedir="${go.dir}">

 			<!-- LICENSE and NOTICE -->

-			<fileset dir="${basedir}" >

+			<zipfileset dir="${basedir}" prefix="${release.name}">

 				<include name="LICENSE" />

 				<include name="NOTICE" />

-			</fileset>

+			</zipfileset>

 			<!-- Windows distrib files -->

-			<zipfileset dir="${project.distrib.dir}/win" />

+			<zipfileset dir="${project.distrib.dir}/win" prefix="${release.name}"/>

 			<!-- Gitblit Authority data -->

-			<zipfileset dir="${project.distrib.dir}/data/certs" prefix="data/certs" />

+			<zipfileset dir="${project.distrib.dir}/data/certs" prefix="${release.name}/data/certs" />

+

 			<!-- include all dependencies -->

-			<dependencies prefix="ext" />

+			<dependencies prefix="${release.name}/ext" />

 		</mx:zip>

 

 		<!-- Create GO Linux/OSX tar.gz deployment -->

 		<mx:tar basedir="${go.dir}" longfile="gnu" compression="gzip">

 			<!-- LICENSE and NOTICE -->

-			<fileset dir="${basedir}" >

+			<zipfileset dir="${basedir}" prefix="${release.name}">

 				<include name="LICENSE" />

 				<include name="NOTICE" />

-			</fileset>

+			</zipfileset>

 			<!-- Linux/OSX distrib files -->

-			<tarfileset dir="${project.distrib.dir}/linux" filemode="755" />

+			<tarfileset dir="${project.distrib.dir}/linux" filemode="755" prefix="${release.name}"/>

 			<!-- Gitblit Authority data -->

-			<zipfileset dir="${project.distrib.dir}/data/certs" prefix="data/certs" />

+			<zipfileset dir="${project.distrib.dir}/data/certs" prefix="${release.name}/data/certs" />

 			<!-- include all dependencies -->

-			<dependencies prefix="ext" />

+			<dependencies prefix="${release.name}/ext" />

 		</mx:tar>		

 

 	</target>

@@ -290,7 +295,7 @@
 			 classes, exclude any classes in classpath jars -->

 		<mx:genjar tag="" includeresources="false" excludeClasspathJars="true"

 			destfile="${project.targetDirectory}/fedclient.jar"

-			excludes="**/.class,**/*.java, **/Thumbs.db, **/*.mkd, com/gitblit/wicket/**">

+			excludes="**/.class, **/*.java, **/Thumbs.db, **/*.mkd, **/*.md, **/*.css, com/gitblit/wicket/**">

 			<mainclass name="com.gitblit.FederationClient" />

 			<class name="com.gitblit.Keys" />

 			<launcher paths="ext" />

@@ -330,7 +335,8 @@
 		<!-- generate jar by traversing the class hierarchy of the specified

 			 classes, exclude any classes in classpath jars -->

 		<mx:genjar tag="" includeResources="false" excludeClasspathJars="true"

-			destfile="${project.targetDirectory}/manager.jar">

+			destfile="${project.targetDirectory}/manager.jar"

+			excludes="**/.class, **/*.java, **/Thumbs.db, **/*.mkd, **/*.md, **/*.css, com/gitblit/wicket/**">

 			<resource file="${project.src.dir}/com/gitblit/client/splash.png" />

 			<resource file="${project.resources.dir}/gitblt-favicon.png" />

 			<resource file="${project.resources.dir}/gitweb-favicon.png" />

@@ -406,9 +412,10 @@
 

 		<!-- Build API Library jar -->

 		<mx:genjar tag="" includeResources="false" excludeClasspathJars="true"

-			destfile="${project.targetDirectory}/gbapi-${project.version}.jar">

+			destfile="${project.targetDirectory}/gbapi-${project.version}.jar"

+			excludes="**/.class, **/*.java, **/Thumbs.db, **/*.mkd, **/*.md, **/*.css, com/gitblit/wicket/**">

+			<mainclass name="com.gitblit.client.GitblitClient" />

 			<class name="com.gitblit.Keys" />

-			<class name="com.gitblit.client.GitblitClient" />

 			<class name="com.gitblit.models.FederationModel" />

 			<class name="com.gitblit.models.FederationProposal" />

 			<class name="com.gitblit.models.FederationSet" />			

diff --git a/gitblit.iml b/gitblit.iml
index 03e2896..4061daf 100644
--- a/gitblit.iml
+++ b/gitblit.iml
@@ -7,20 +7,20 @@
     <content url="file://$MODULE_DIR$">
       <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
       <sourceFolder url="file://$MODULE_DIR$/src/main/bugtraq" isTestSource="false" />
-      <sourceFolder url="file://$MODULE_DIR$/src/main/dagger" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/main/gen" isTestSource="false" />
       <sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
       <sourceFolder url="file://$MODULE_DIR$/src/test/bugtraq" isTestSource="true" />
       <sourceFolder url="file://$MODULE_DIR$/src/main/resources" isTestSource="false" />
     </content>
     <orderEntry type="sourceFolder" forTests="false" />
     <orderEntry type="module-library">
-      <library name="dagger-1.1.0.jar">
+      <library name="guice-4.0-beta4.jar">
         <CLASSES>
-          <root url="jar://$MODULE_DIR$/ext/dagger-1.1.0.jar!/" />
+          <root url="jar://$MODULE_DIR$/ext/guice-4.0-beta4.jar!/" />
         </CLASSES>
         <JAVADOC />
         <SOURCES>
-          <root url="jar://$MODULE_DIR$/ext/src/dagger-1.1.0.jar!/" />
+          <root url="jar://$MODULE_DIR$/ext/src/guice-4.0-beta4.jar!/" />
         </SOURCES>
       </library>
     </orderEntry>
@@ -36,24 +36,35 @@
       </library>
     </orderEntry>
     <orderEntry type="module-library">
-      <library name="dagger-compiler-1.1.0.jar">
+      <library name="aopalliance-1.0.jar">
         <CLASSES>
-          <root url="jar://$MODULE_DIR$/ext/dagger-compiler-1.1.0.jar!/" />
+          <root url="jar://$MODULE_DIR$/ext/aopalliance-1.0.jar!/" />
         </CLASSES>
         <JAVADOC />
         <SOURCES>
-          <root url="jar://$MODULE_DIR$/ext/src/dagger-compiler-1.1.0.jar!/" />
+          <root url="jar://$MODULE_DIR$/ext/src/aopalliance-1.0.jar!/" />
         </SOURCES>
       </library>
     </orderEntry>
     <orderEntry type="module-library">
-      <library name="javawriter-2.1.1.jar">
+      <library name="guava-17.0.jar">
         <CLASSES>
-          <root url="jar://$MODULE_DIR$/ext/javawriter-2.1.1.jar!/" />
+          <root url="jar://$MODULE_DIR$/ext/guava-17.0.jar!/" />
         </CLASSES>
         <JAVADOC />
         <SOURCES>
-          <root url="jar://$MODULE_DIR$/ext/src/javawriter-2.1.1.jar!/" />
+          <root url="jar://$MODULE_DIR$/ext/src/guava-17.0.jar!/" />
+        </SOURCES>
+      </library>
+    </orderEntry>
+    <orderEntry type="module-library">
+      <library name="guice-servlet-4.0-gb1.jar">
+        <CLASSES>
+          <root url="jar://$MODULE_DIR$/ext/guice-servlet-4.0-gb1.jar!/" />
+        </CLASSES>
+        <JAVADOC />
+        <SOURCES>
+          <root url="jar://$MODULE_DIR$/ext/src/guice-servlet-4.0-gb1.jar!/" />
         </SOURCES>
       </library>
     </orderEntry>
@@ -80,24 +91,24 @@
       </library>
     </orderEntry>
     <orderEntry type="module-library">
-      <library name="slf4j-api-1.7.5.jar">
+      <library name="slf4j-api-1.7.7.jar">
         <CLASSES>
-          <root url="jar://$MODULE_DIR$/ext/slf4j-api-1.7.5.jar!/" />
+          <root url="jar://$MODULE_DIR$/ext/slf4j-api-1.7.7.jar!/" />
         </CLASSES>
         <JAVADOC />
         <SOURCES>
-          <root url="jar://$MODULE_DIR$/ext/src/slf4j-api-1.7.5.jar!/" />
+          <root url="jar://$MODULE_DIR$/ext/src/slf4j-api-1.7.7.jar!/" />
         </SOURCES>
       </library>
     </orderEntry>
     <orderEntry type="module-library">
-      <library name="slf4j-log4j12-1.7.5.jar">
+      <library name="slf4j-log4j12-1.7.7.jar">
         <CLASSES>
-          <root url="jar://$MODULE_DIR$/ext/slf4j-log4j12-1.7.5.jar!/" />
+          <root url="jar://$MODULE_DIR$/ext/slf4j-log4j12-1.7.7.jar!/" />
         </CLASSES>
         <JAVADOC />
         <SOURCES>
-          <root url="jar://$MODULE_DIR$/ext/src/slf4j-log4j12-1.7.5.jar!/" />
+          <root url="jar://$MODULE_DIR$/ext/src/slf4j-log4j12-1.7.7.jar!/" />
         </SOURCES>
       </library>
     </orderEntry>
@@ -124,13 +135,13 @@
       </library>
     </orderEntry>
     <orderEntry type="module-library">
-      <library name="jetty-all-9.1.4.v20140401.jar">
+      <library name="jetty-all-9.2.2.v20140723.jar">
         <CLASSES>
-          <root url="jar://$MODULE_DIR$/ext/jetty-all-9.1.4.v20140401.jar!/" />
+          <root url="jar://$MODULE_DIR$/ext/jetty-all-9.2.2.v20140723.jar!/" />
         </CLASSES>
         <JAVADOC />
         <SOURCES>
-          <root url="jar://$MODULE_DIR$/ext/src/jetty-all-9.1.4.v20140401.jar!/" />
+          <root url="jar://$MODULE_DIR$/ext/src/jetty-all-9.2.2.v20140723.jar!/" />
         </SOURCES>
       </library>
     </orderEntry>
@@ -168,79 +179,79 @@
       </library>
     </orderEntry>
     <orderEntry type="module-library">
-      <library name="lucene-core-4.6.0.jar">
+      <library name="lucene-core-4.10.0.jar">
         <CLASSES>
-          <root url="jar://$MODULE_DIR$/ext/lucene-core-4.6.0.jar!/" />
+          <root url="jar://$MODULE_DIR$/ext/lucene-core-4.10.0.jar!/" />
         </CLASSES>
         <JAVADOC />
         <SOURCES>
-          <root url="jar://$MODULE_DIR$/ext/src/lucene-core-4.6.0.jar!/" />
+          <root url="jar://$MODULE_DIR$/ext/src/lucene-core-4.10.0.jar!/" />
         </SOURCES>
       </library>
     </orderEntry>
     <orderEntry type="module-library">
-      <library name="lucene-analyzers-common-4.6.0.jar">
+      <library name="lucene-analyzers-common-4.10.0.jar">
         <CLASSES>
-          <root url="jar://$MODULE_DIR$/ext/lucene-analyzers-common-4.6.0.jar!/" />
+          <root url="jar://$MODULE_DIR$/ext/lucene-analyzers-common-4.10.0.jar!/" />
         </CLASSES>
         <JAVADOC />
         <SOURCES>
-          <root url="jar://$MODULE_DIR$/ext/src/lucene-analyzers-common-4.6.0.jar!/" />
+          <root url="jar://$MODULE_DIR$/ext/src/lucene-analyzers-common-4.10.0.jar!/" />
         </SOURCES>
       </library>
     </orderEntry>
     <orderEntry type="module-library">
-      <library name="lucene-highlighter-4.6.0.jar">
+      <library name="lucene-highlighter-4.10.0.jar">
         <CLASSES>
-          <root url="jar://$MODULE_DIR$/ext/lucene-highlighter-4.6.0.jar!/" />
+          <root url="jar://$MODULE_DIR$/ext/lucene-highlighter-4.10.0.jar!/" />
         </CLASSES>
         <JAVADOC />
         <SOURCES>
-          <root url="jar://$MODULE_DIR$/ext/src/lucene-highlighter-4.6.0.jar!/" />
+          <root url="jar://$MODULE_DIR$/ext/src/lucene-highlighter-4.10.0.jar!/" />
         </SOURCES>
       </library>
     </orderEntry>
     <orderEntry type="module-library">
-      <library name="lucene-memory-4.6.0.jar">
+      <library name="lucene-memory-4.10.0.jar">
         <CLASSES>
-          <root url="jar://$MODULE_DIR$/ext/lucene-memory-4.6.0.jar!/" />
+          <root url="jar://$MODULE_DIR$/ext/lucene-memory-4.10.0.jar!/" />
         </CLASSES>
         <JAVADOC />
         <SOURCES>
-          <root url="jar://$MODULE_DIR$/ext/src/lucene-memory-4.6.0.jar!/" />
+          <root url="jar://$MODULE_DIR$/ext/src/lucene-memory-4.10.0.jar!/" />
         </SOURCES>
       </library>
     </orderEntry>
     <orderEntry type="module-library">
-      <library name="lucene-queries-4.6.0.jar">
+      <library name="lucene-queries-4.10.0.jar">
         <CLASSES>
-          <root url="jar://$MODULE_DIR$/ext/lucene-queries-4.6.0.jar!/" />
+          <root url="jar://$MODULE_DIR$/ext/lucene-queries-4.10.0.jar!/" />
         </CLASSES>
         <JAVADOC />
         <SOURCES>
-          <root url="jar://$MODULE_DIR$/ext/src/lucene-queries-4.6.0.jar!/" />
+          <root url="jar://$MODULE_DIR$/ext/src/lucene-queries-4.10.0.jar!/" />
         </SOURCES>
       </library>
     </orderEntry>
     <orderEntry type="module-library">
-      <library name="lucene-queryparser-4.6.0.jar">
+      <library name="lucene-queryparser-4.10.0.jar">
         <CLASSES>
-          <root url="jar://$MODULE_DIR$/ext/lucene-queryparser-4.6.0.jar!/" />
+          <root url="jar://$MODULE_DIR$/ext/lucene-queryparser-4.10.0.jar!/" />
         </CLASSES>
         <JAVADOC />
         <SOURCES>
-          <root url="jar://$MODULE_DIR$/ext/src/lucene-queryparser-4.6.0.jar!/" />
+          <root url="jar://$MODULE_DIR$/ext/src/lucene-queryparser-4.10.0.jar!/" />
         </SOURCES>
       </library>
     </orderEntry>
     <orderEntry type="module-library">
-      <library name="lucene-sandbox-4.6.0.jar">
+      <library name="lucene-sandbox-4.10.0.jar">
         <CLASSES>
-          <root url="jar://$MODULE_DIR$/ext/lucene-sandbox-4.6.0.jar!/" />
+          <root url="jar://$MODULE_DIR$/ext/lucene-sandbox-4.10.0.jar!/" />
         </CLASSES>
         <JAVADOC />
         <SOURCES>
-          <root url="jar://$MODULE_DIR$/ext/src/lucene-sandbox-4.6.0.jar!/" />
+          <root url="jar://$MODULE_DIR$/ext/src/lucene-sandbox-4.10.0.jar!/" />
         </SOURCES>
       </library>
     </orderEntry>
@@ -397,13 +408,13 @@
       </library>
     </orderEntry>
     <orderEntry type="module-library">
-      <library name="org.eclipse.jgit-3.3.1.201403241930-r.jar">
+      <library name="org.eclipse.jgit-3.4.1.201406201815-r.jar">
         <CLASSES>
-          <root url="jar://$MODULE_DIR$/ext/org.eclipse.jgit-3.3.1.201403241930-r.jar!/" />
+          <root url="jar://$MODULE_DIR$/ext/org.eclipse.jgit-3.4.1.201406201815-r.jar!/" />
         </CLASSES>
         <JAVADOC />
         <SOURCES>
-          <root url="jar://$MODULE_DIR$/ext/src/org.eclipse.jgit-3.3.1.201403241930-r.jar!/" />
+          <root url="jar://$MODULE_DIR$/ext/src/org.eclipse.jgit-3.4.1.201406201815-r.jar!/" />
         </SOURCES>
       </library>
     </orderEntry>
@@ -474,13 +485,13 @@
       </library>
     </orderEntry>
     <orderEntry type="module-library">
-      <library name="org.eclipse.jgit.http.server-3.3.1.201403241930-r.jar">
+      <library name="org.eclipse.jgit.http.server-3.4.1.201406201815-r.jar">
         <CLASSES>
-          <root url="jar://$MODULE_DIR$/ext/org.eclipse.jgit.http.server-3.3.1.201403241930-r.jar!/" />
+          <root url="jar://$MODULE_DIR$/ext/org.eclipse.jgit.http.server-3.4.1.201406201815-r.jar!/" />
         </CLASSES>
         <JAVADOC />
         <SOURCES>
-          <root url="jar://$MODULE_DIR$/ext/src/org.eclipse.jgit.http.server-3.3.1.201403241930-r.jar!/" />
+          <root url="jar://$MODULE_DIR$/ext/src/org.eclipse.jgit.http.server-3.4.1.201406201815-r.jar!/" />
         </SOURCES>
       </library>
     </orderEntry>
@@ -518,13 +529,13 @@
       </library>
     </orderEntry>
     <orderEntry type="module-library">
-      <library name="sshd-core-0.11.1-atlassian-1.jar">
+      <library name="sshd-core-0.12.0.jar">
         <CLASSES>
-          <root url="jar://$MODULE_DIR$/ext/sshd-core-0.11.1-atlassian-1.jar!/" />
+          <root url="jar://$MODULE_DIR$/ext/sshd-core-0.12.0.jar!/" />
         </CLASSES>
         <JAVADOC />
         <SOURCES>
-          <root url="jar://$MODULE_DIR$/ext/src/sshd-core-0.11.1-atlassian-1.jar!/" />
+          <root url="jar://$MODULE_DIR$/ext/src/sshd-core-0.12.0.jar!/" />
         </SOURCES>
       </library>
     </orderEntry>
@@ -562,24 +573,24 @@
       </library>
     </orderEntry>
     <orderEntry type="module-library">
-      <library name="gson-1.7.2.jar">
+      <library name="gson-2.2.2.jar">
         <CLASSES>
-          <root url="jar://$MODULE_DIR$/ext/gson-1.7.2.jar!/" />
+          <root url="jar://$MODULE_DIR$/ext/gson-2.2.2.jar!/" />
         </CLASSES>
         <JAVADOC />
         <SOURCES>
-          <root url="jar://$MODULE_DIR$/ext/src/gson-1.7.2.jar!/" />
+          <root url="jar://$MODULE_DIR$/ext/src/gson-2.2.2.jar!/" />
         </SOURCES>
       </library>
     </orderEntry>
     <orderEntry type="module-library">
-      <library name="groovy-all-1.8.8.jar">
+      <library name="groovy-all-2.3.3.jar">
         <CLASSES>
-          <root url="jar://$MODULE_DIR$/ext/groovy-all-1.8.8.jar!/" />
+          <root url="jar://$MODULE_DIR$/ext/groovy-all-2.3.3.jar!/" />
         </CLASSES>
         <JAVADOC />
         <SOURCES>
-          <root url="jar://$MODULE_DIR$/ext/src/groovy-all-1.8.8.jar!/" />
+          <root url="jar://$MODULE_DIR$/ext/src/groovy-all-2.3.3.jar!/" />
         </SOURCES>
       </library>
     </orderEntry>
@@ -681,13 +692,13 @@
       </library>
     </orderEntry>
     <orderEntry type="module-library">
-      <library name="freemarker-2.3.19.jar">
+      <library name="freemarker-2.3.20.jar">
         <CLASSES>
-          <root url="jar://$MODULE_DIR$/ext/freemarker-2.3.19.jar!/" />
+          <root url="jar://$MODULE_DIR$/ext/freemarker-2.3.20.jar!/" />
         </CLASSES>
         <JAVADOC />
         <SOURCES>
-          <root url="jar://$MODULE_DIR$/ext/src/freemarker-2.3.19.jar!/" />
+          <root url="jar://$MODULE_DIR$/ext/src/freemarker-2.3.20.jar!/" />
         </SOURCES>
       </library>
     </orderEntry>
@@ -725,17 +736,6 @@
       </library>
     </orderEntry>
     <orderEntry type="module-library">
-      <library name="guava-13.0.1.jar">
-        <CLASSES>
-          <root url="jar://$MODULE_DIR$/ext/guava-13.0.1.jar!/" />
-        </CLASSES>
-        <JAVADOC />
-        <SOURCES>
-          <root url="jar://$MODULE_DIR$/ext/src/guava-13.0.1.jar!/" />
-        </SOURCES>
-      </library>
-    </orderEntry>
-    <orderEntry type="module-library">
       <library name="libpam4j-1.7.jar">
         <CLASSES>
           <root url="jar://$MODULE_DIR$/ext/libpam4j-1.7.jar!/" />
@@ -780,13 +780,13 @@
       </library>
     </orderEntry>
     <orderEntry type="module-library">
-      <library name="pf4j-0.8.0.jar">
+      <library name="pf4j-0.9.0.jar">
         <CLASSES>
-          <root url="jar://$MODULE_DIR$/ext/pf4j-0.8.0.jar!/" />
+          <root url="jar://$MODULE_DIR$/ext/pf4j-0.9.0.jar!/" />
         </CLASSES>
         <JAVADOC />
         <SOURCES>
-          <root url="jar://$MODULE_DIR$/ext/src/pf4j-0.8.0.jar!/" />
+          <root url="jar://$MODULE_DIR$/ext/src/pf4j-0.9.0.jar!/" />
         </SOURCES>
       </library>
     </orderEntry>
diff --git a/releases.moxie b/releases.moxie
index 2a301ba..e99cbd5 100644
--- a/releases.moxie
+++ b/releases.moxie
@@ -9,11 +9,32 @@
     html: ~
     text: ~
     security: ~
-    fixes: ~
-    changes: ~
+    fixes:
+    - Fixed NPE when there are two repositories which only differ in case (pr-204, ticket-108)
+    - Fixed api/manager download links in documentation (issue-449, ticket-111)
+    - Fixed stackoverflow on (de)serialization of the history page (ticket-114)
+    - Fixed queries for milestones with hyphentated names (ticket-115)
+    - Fixed duplicate repositories on the dashboard (issue-454, ticket-117)
+    - Fixed lower-case project selection (ticket-118)
+    changes:
+    - Update Korean translation (pr-206, ticket-120)
+    - Improve web.canonicalUrl documentation (pr-205, ticket-121, issue-453)
     additions: ~
-    dependencyChanges: ~
-    contributors: ~
+    dependencyChanges:
+    - Jetty 9.2.1 (pr-202)
+    - Lucene 4.8.1 (pr-201)
+    - JGit 3.4.0 (pr-200)
+    - Guice 4.0-beta4 (ticket-80)
+    - SLF4j 1.7.7 (ticket-122)
+    - gson 2.2.2 (ticket-123)
+    - Freemarker 2.3.20 (ticket-124)
+    contributors:
+    - James Moger
+    - David Ostrovsky
+    - Kyle Gottfried
+    - Yena Hong
+    - Eric Fairon
+    - Gareth Collins
 }
 
 #
@@ -1432,6 +1453,6 @@
 	- James Moger
 }
 
-snapshot: &r25
+snapshot: ~
 release: &r24
 releases: &r[1..24]
diff --git a/src/main/.gitignore b/src/main/.gitignore
index 01c48ab..0d04688 100644
--- a/src/main/.gitignore
+++ b/src/main/.gitignore
@@ -1 +1,2 @@
 /dagger
+/gen
diff --git a/src/main/java/WEB-INF/web.xml b/src/main/java/WEB-INF/web.xml
index 13f612e..8842224 100644
--- a/src/main/java/WEB-INF/web.xml
+++ b/src/main/java/WEB-INF/web.xml
@@ -1,361 +1,49 @@
-<?xml version="1.0" encoding="UTF-8"?>

-<web-app version="2.4"

-	xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

-	xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

-

-	<!-- The base folder is used to specify the root location of your Gitblit data.

-	

-			${baseFolder}/gitblit.properties

-			${baseFolder}/users.conf

-			${baseFolder}/projects.conf

-			${baseFolder}/robots.txt

-			${baseFolder}/git

-			${baseFolder}/groovy

-			${baseFolder}/groovy/grape

-			${baseFolder}/proposals

-

-		By default, this location is WEB-INF/data.  It is recommended to set this

-		path to a location outside your webapps folder that is writable by your

-		servlet container.  Gitblit will copy the WEB-INF/data files to that

-		location for you when it restarts.  This approach makes upgrading simpler.

-		All you have to do is set this parameter for the new release and then

-		review the defaults for any new settings.  Settings are always versioned

-		with a SINCE x.y.z attribute and also noted in the release changelog.

-		-->

-	<env-entry>

-		<description>The base folder is used to specify the root location of your Gitblit data.</description>

-		<env-entry-name>baseFolder</env-entry-name>

-		<env-entry-type>java.lang.String</env-entry-type>

-		<env-entry-value>${contextFolder}/WEB-INF/data</env-entry-value>

-	</env-entry>

-	

-	<!-- Gitblit Displayname -->

-	<display-name>Gitblit - @gb.version@</display-name>

-

-	 

-<!-- Gitblit Context Listener --><!-- STRIP	 

-	<listener>

- 		<listener-class>com.gitblit.servlet.GitblitContext</listener-class>

- 	</listener>STRIP --> 	

-	

-	

-	<!-- Git Servlet

-		 <url-pattern> MUST match: 

-			* GitFilter

-			* com.gitblit.Constants.GIT_PATH

-			* Wicket Filter ignorePaths parameter -->

-	<servlet>

-		<servlet-name>GitServlet</servlet-name>

-		<servlet-class>com.gitblit.servlet.GitServlet</servlet-class>

-	</servlet>

-	<servlet-mapping>

-		<servlet-name>GitServlet</servlet-name>		

-		<url-pattern>/git/*</url-pattern>

-	</servlet-mapping>

-	<servlet-mapping>

-		<servlet-name>GitServlet</servlet-name>		

-		<url-pattern>/r/*</url-pattern>

-	</servlet-mapping>

-

-	

-	<!-- SparkleShare Invite Servlet

-		 <url-pattern> MUST match: 

-			* com.gitblit.Constants.SPARKLESHARE_INVITE_PATH

-			* Wicket Filter ignorePaths parameter -->

-	<servlet>

-		<servlet-name>SparkleShareInviteServlet</servlet-name>

-		<servlet-class>com.gitblit.servlet.SparkleShareInviteServlet</servlet-class>

-	</servlet>

-	<servlet-mapping>

-		<servlet-name>SparkleShareInviteServlet</servlet-name>		

-		<url-pattern>/sparkleshare/*</url-pattern>

-	</servlet-mapping>

-

-	

-	<!-- Syndication Servlet

-		 <url-pattern> MUST match: 

-			* SyndicationFilter

-			* com.gitblit.Constants.SYNDICATION_PATH

-			* Wicket Filter ignorePaths parameter -->

-	<servlet>

-		<servlet-name>SyndicationServlet</servlet-name>

-		<servlet-class>com.gitblit.servlet.SyndicationServlet</servlet-class>		

-	</servlet>

-	<servlet-mapping>

-		<servlet-name>SyndicationServlet</servlet-name>

-		<url-pattern>/feed/*</url-pattern>

-	</servlet-mapping>

-	

-	

-	<!-- Zip Servlet

-		 <url-pattern> MUST match: 

-			* ZipServlet

-			* com.gitblit.Constants.ZIP_PATH

-			* Wicket Filter ignorePaths parameter -->

-	<servlet>

-		<servlet-name>ZipServlet</servlet-name>

-		<servlet-class>com.gitblit.servlet.DownloadZipServlet</servlet-class>		

-	</servlet>

-	<servlet-mapping>

-		<servlet-name>ZipServlet</servlet-name>

-		<url-pattern>/zip/*</url-pattern>

-	</servlet-mapping>

-	

-	

-	<!-- Federation Servlet

-		 <url-pattern> MUST match: 

-		 	* com.gitblit.Constants.FEDERATION_PATH		 

-			* Wicket Filter ignorePaths parameter -->

-	<servlet>

-		<servlet-name>FederationServlet</servlet-name>

-		<servlet-class>com.gitblit.servlet.FederationServlet</servlet-class>		

-	</servlet>

-	<servlet-mapping>

-		<servlet-name>FederationServlet</servlet-name>

-		<url-pattern>/federation/*</url-pattern>

-	</servlet-mapping>	

-	

-	

-	<!-- Rpc Servlet

-		 <url-pattern> MUST match: 

-		 	* com.gitblit.Constants.RPC_PATH		 

-			* Wicket Filter ignorePaths parameter -->

-	<servlet>

-		<servlet-name>RpcServlet</servlet-name>

-		<servlet-class>com.gitblit.servlet.RpcServlet</servlet-class>		

-	</servlet>

-	<servlet-mapping>

-		<servlet-name>RpcServlet</servlet-name>

-		<url-pattern>/rpc/*</url-pattern>

-	</servlet-mapping>	

-

-

-	<!-- Raw Servlet

-		 <url-pattern> MUST match: 

-			* RawFilter

-			* com.gitblit.Constants.RAW_PATH

-			* Wicket Filter ignorePaths parameter -->

-	<servlet>

-		<servlet-name>RawServlet</servlet-name>

-		<servlet-class>com.gitblit.servlet.RawServlet</servlet-class>

-	</servlet>

-	<servlet-mapping>

-		<servlet-name>RawServlet</servlet-name>		

-		<url-pattern>/raw/*</url-pattern>

-	</servlet-mapping>	

-

-

-	<!-- Pages Servlet

-		 <url-pattern> MUST match: 

-			* PagesFilter

-			* com.gitblit.Constants.PAGES_PATH

-			* Wicket Filter ignorePaths parameter -->

-	<servlet>

-		<servlet-name>PagesServlet</servlet-name>

-		<servlet-class>com.gitblit.servlet.PagesServlet</servlet-class>

-	</servlet>

-	<servlet-mapping>

-		<servlet-name>PagesServlet</servlet-name>		

-		<url-pattern>/pages/*</url-pattern>

-	</servlet-mapping>	

-

-	

-	<!-- Logo Servlet

-		 <url-pattern> MUST match: 

-			* Wicket Filter ignorePaths parameter -->

-	<servlet>

-		<servlet-name>LogoServlet</servlet-name>

-		<servlet-class>com.gitblit.servlet.LogoServlet</servlet-class>

-	</servlet>

-	<servlet-mapping>

-		<servlet-name>LogoServlet</servlet-name>		

-		<url-pattern>/logo.png</url-pattern>

-	</servlet-mapping>

-

-

-	<!-- PT Servlet

-		 <url-pattern> MUST match: 

-			* Wicket Filter ignorePaths parameter -->

-	<servlet>

-		<servlet-name>PtServlet</servlet-name>

-		<servlet-class>com.gitblit.servlet.PtServlet</servlet-class>

-	</servlet>

-	<servlet-mapping>

-		<servlet-name>PtServlet</servlet-name>		

-		<url-pattern>/pt</url-pattern>

-	</servlet-mapping>

-

-

-	<!-- Branch Graph Servlet

-		 <url-pattern> MUST match: 

-			* Wicket Filter ignorePaths parameter -->

-	<servlet>

-		<servlet-name>BranchGraphServlet</servlet-name>

-		<servlet-class>com.gitblit.servlet.BranchGraphServlet</servlet-class>

-	</servlet>

-	<servlet-mapping>

-		<servlet-name>BranchGraphServlet</servlet-name>		

-		<url-pattern>/graph/*</url-pattern>

-	</servlet-mapping>

-

-	<!-- Robots.txt Servlet

-		 <url-pattern> MUST match: 

-			* Wicket Filter ignorePaths parameter -->

-	<servlet>

-		<servlet-name>RobotsTxtServlet</servlet-name>

-		<servlet-class>com.gitblit.servlet.RobotsTxtServlet</servlet-class>

-	</servlet>

-	<servlet-mapping>

-		<servlet-name>RobotsTxtServlet</servlet-name>		

-		<url-pattern>/robots.txt</url-pattern>

-	</servlet-mapping>

-

-    <filter>

-		<filter-name>ProxyFilter</filter-name>

-		<filter-class>com.gitblit.servlet.ProxyFilter</filter-class>

-	</filter>

-	<filter-mapping>

-		<filter-name>ProxyFilter</filter-name>

-		<url-pattern>/*</url-pattern>

-	</filter-mapping>

-	

-	<!-- Git Access Restriction Filter

-		 <url-pattern> MUST match: 

-			* GitServlet

-			* com.gitblit.Constants.GIT_PATH

-			* Wicket Filter ignorePaths parameter -->

-	<filter>

-		<filter-name>GitFilter</filter-name>

-		<filter-class>com.gitblit.servlet.GitFilter</filter-class>

-	</filter>

-	<filter-mapping>

-		<filter-name>GitFilter</filter-name>

-		<url-pattern>/git/*</url-pattern>

-	</filter-mapping>

-	<filter-mapping>

-		<filter-name>GitFilter</filter-name>

-		<url-pattern>/r/*</url-pattern>

-	</filter-mapping>

-	

-	

-	<!-- Syndication Restriction Filter

-		 <url-pattern> MUST match: 

-			* SyndicationServlet

-			* com.gitblit.Constants.SYNDICATION_PATH

-			* Wicket Filter ignorePaths parameter -->

-	<filter>

-		<filter-name>SyndicationFilter</filter-name>

-		<filter-class>com.gitblit.servlet.SyndicationFilter</filter-class>

-	</filter>

-	<filter-mapping>

-		<filter-name>SyndicationFilter</filter-name>

-		<url-pattern>/feed/*</url-pattern>

-	</filter-mapping>

-	

-	

-	<!-- Download Zip Restriction Filter

-		 <url-pattern> MUST match: 

-			* DownloadZipServlet

-			* com.gitblit.Constants.ZIP_PATH

-			* Wicket Filter ignorePaths parameter -->

-	<filter>

-		<filter-name>ZipFilter</filter-name>

-		<filter-class>com.gitblit.servlet.DownloadZipFilter</filter-class>

-	</filter>

-	<filter-mapping>

-		<filter-name>ZipFilter</filter-name>

-		<url-pattern>/zip/*</url-pattern>

-	</filter-mapping>

-

-		

-	<!-- Rpc Restriction Filter

-		 <url-pattern> MUST match: 

-			* RpcServlet

-			* com.gitblit.Constants.RPC_PATH

-			* Wicket Filter ignorePaths parameter -->

-	<filter>

-		<filter-name>RpcFilter</filter-name>

-		<filter-class>com.gitblit.servlet.RpcFilter</filter-class>

-	</filter>

-	<filter-mapping>

-		<filter-name>RpcFilter</filter-name>

-		<url-pattern>/rpc/*</url-pattern>

-	</filter-mapping>

-

-

-	<!-- Branch Restriction Filter

-		 <url-pattern> MUST match: 

-			* RawServlet

-			* com.gitblit.Constants.BRANCH_PATH

-			* Wicket Filter ignorePaths parameter -->

-	<filter>

-		<filter-name>RawFilter</filter-name>

-		<filter-class>com.gitblit.servlet.RawFilter</filter-class>

-	</filter>

-	<filter-mapping>

-		<filter-name>RawFilter</filter-name>

-		<url-pattern>/raw/*</url-pattern>

-	</filter-mapping>

-	

-

-	<!-- Pages Restriction Filter

-		 <url-pattern> MUST match: 

-			* PagesServlet

-			* com.gitblit.Constants.PAGES_PATH

-			* Wicket Filter ignorePaths parameter -->

-	<filter>

-		<filter-name>PagesFilter</filter-name>

-		<filter-class>com.gitblit.servlet.PagesFilter</filter-class>

-	</filter>

-	<filter-mapping>

-		<filter-name>PagesFilter</filter-name>

-		<url-pattern>/pages/*</url-pattern>

-	</filter-mapping>

-	

-	<filter>

-		<filter-name>EnforceAuthenticationFilter</filter-name>

-		<filter-class>com.gitblit.servlet.EnforceAuthenticationFilter</filter-class>

-	</filter>

-	<filter-mapping>

-        <filter-name>EnforceAuthenticationFilter</filter-name>

-        <url-pattern>/*</url-pattern>

-    </filter-mapping>

-

-

-	<!-- Wicket Filter -->

-    <filter>

-        <filter-name>wicketFilter</filter-name>

-        <filter-class>

-            com.gitblit.wicket.GitblitWicketFilter

-        </filter-class>        

-        <init-param>

-            <param-name>ignorePaths</param-name>

-            <!-- Paths should match 

-             	* SyndicationFilter <url-pattern>

-             	* SyndicationServlet <url-pattern>

-             	* com.gitblit.Constants.SYNDICATION_PATH

-             	* GitFilter <url-pattern>

-             	* GitServlet <url-pattern>

-             	* com.gitblit.Constants.GIT_PATH

-             	* SparkleshareInviteServlet <url-pattern>

-             	* com.gitblit.Constants.SPARKLESHARE_INVITE_PATH

-             	* Zipfilter <url-pattern>

-             	* ZipServlet <url-pattern>

-             	* com.gitblit.Constants.ZIP_PATH

-             	* FederationServlet <url-pattern>

-             	* RpcFilter <url-pattern>

-             	* RpcServlet <url-pattern>

-             	* RawFilter <url-pattern>

-             	* RawServlet <url-pattern>

-             	* PagesFilter <url-pattern>

-             	* PagesServlet <url-pattern>

-             	* com.gitblit.Constants.PAGES_PATH -->

-            <param-value>r/,git/,pt,feed/,zip/,federation/,rpc/,raw/,pages/,robots.txt,logo.png,graph/,sparkleshare/</param-value>

-        </init-param>

-    </filter>

-    <filter-mapping>

-        <filter-name>wicketFilter</filter-name>

-        <url-pattern>/*</url-pattern>

-    </filter-mapping>

-    

+<?xml version="1.0" encoding="UTF-8"?>
+<web-app version="2.4"
+	xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
+
+	<!-- The base folder is used to specify the root location of your Gitblit data.
+	
+			${baseFolder}/gitblit.properties
+			${baseFolder}/users.conf
+			${baseFolder}/projects.conf
+			${baseFolder}/robots.txt
+			${baseFolder}/git
+			${baseFolder}/groovy
+			${baseFolder}/groovy/grape
+			${baseFolder}/proposals
+
+		By default, this location is WEB-INF/data.  It is recommended to set this
+		path to a location outside your webapps folder that is writable by your
+		servlet container.  Gitblit will copy the WEB-INF/data files to that
+		location for you when it restarts.  This approach makes upgrading simpler.
+		All you have to do is set this parameter for the new release and then
+		review the defaults for any new settings.  Settings are always versioned
+		with a SINCE x.y.z attribute and also noted in the release changelog.
+		-->
+	<env-entry>
+		<description>The base folder is used to specify the root location of your Gitblit data.</description>
+		<env-entry-name>baseFolder</env-entry-name>
+		<env-entry-type>java.lang.String</env-entry-type>
+		<env-entry-value>${contextFolder}/WEB-INF/data</env-entry-value>
+	</env-entry>
+	
+	<!-- Gitblit Displayname -->
+	<display-name>Gitblit - @gb.version@</display-name>
+
+	<listener>
+  		<listener-class>com.gitblit.servlet.GitblitContext</listener-class>
+	</listener>
+	
+	<filter>
+    	<filter-name>guiceFilter</filter-name>
+		<filter-class>com.google.inject.servlet.GuiceFilter</filter-class>
+	</filter>
+
+	<filter-mapping>
+		<filter-name>guiceFilter</filter-name>
+		<url-pattern>/*</url-pattern>
+	</filter-mapping>
+  
 </web-app>
\ No newline at end of file
diff --git a/src/main/java/com/gitblit/Constants.java b/src/main/java/com/gitblit/Constants.java
index 3e30753..279d3c9 100644
--- a/src/main/java/com/gitblit/Constants.java
+++ b/src/main/java/com/gitblit/Constants.java
@@ -70,6 +70,8 @@
 

 	public static final String RAW_PATH = "/raw/";

 

+	public static final String PT_PATH = "/pt";

+

 	public static final String BRANCH_GRAPH_PATH = "/graph/";

 

 	public static final String BORDER = "*****************************************************************";

@@ -146,6 +148,17 @@
 		return getManifestValue("build-date", "PENDING");

 	}

 

+	public static String getASCIIArt() {

+		StringBuilder sb = new StringBuilder();

+		sb.append("  _____  _  _    _      _  _  _").append('\n');

+		sb.append(" |  __ \\(_)| |  | |    | |(_)| |").append('\n');

+		sb.append(" | |  \\/ _ | |_ | |__  | | _ | |_").append('\n');

+		sb.append(" | | __ | || __|| '_ \\ | || || __|").append("  ").append("http://gitblit.com").append('\n');

+		sb.append(" | |_\\ \\| || |_ | |_) || || || |_").append("   ").append("@gitblit").append('\n');

+		sb.append("  \\____/|_| \\__||_.__/ |_||_| \\__|").append("  ").append(Constants.getVersion()).append('\n');

+		return sb.toString();

+	}

+

 	private static String getManifestValue(String attrib, String defaultValue) {

 		Class<?> clazz = Constants.class;

 		String className = clazz.getSimpleName() + ".class";

diff --git a/src/main/java/com/gitblit/DaggerModule.java b/src/main/java/com/gitblit/DaggerModule.java
deleted file mode 100644
index 6ad3fe6..0000000
--- a/src/main/java/com/gitblit/DaggerModule.java
+++ /dev/null
@@ -1,215 +0,0 @@
-/*
- * Copyright 2013 gitblit.com.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.gitblit;
-
-import javax.inject.Singleton;
-
-import com.gitblit.manager.AuthenticationManager;
-import com.gitblit.manager.FederationManager;
-import com.gitblit.manager.IAuthenticationManager;
-import com.gitblit.manager.IFederationManager;
-import com.gitblit.manager.IGitblit;
-import com.gitblit.manager.INotificationManager;
-import com.gitblit.manager.IPluginManager;
-import com.gitblit.manager.IProjectManager;
-import com.gitblit.manager.IRepositoryManager;
-import com.gitblit.manager.IRuntimeManager;
-import com.gitblit.manager.IUserManager;
-import com.gitblit.manager.NotificationManager;
-import com.gitblit.manager.PluginManager;
-import com.gitblit.manager.ProjectManager;
-import com.gitblit.manager.RepositoryManager;
-import com.gitblit.manager.RuntimeManager;
-import com.gitblit.manager.UserManager;
-import com.gitblit.transport.ssh.FileKeyManager;
-import com.gitblit.transport.ssh.IPublicKeyManager;
-import com.gitblit.transport.ssh.MemoryKeyManager;
-import com.gitblit.transport.ssh.NullKeyManager;
-import com.gitblit.utils.StringUtils;
-import com.gitblit.wicket.GitBlitWebApp;
-
-import dagger.Module;
-import dagger.Provides;
-
-/**
- * DaggerModule references all injectable objects.
- *
- * @author James Moger
- *
- */
-@Module(
-	library = true,
-	injects = {
-			IStoredSettings.class,
-
-			// core managers
-			IRuntimeManager.class,
-			IPluginManager.class,
-			INotificationManager.class,
-			IUserManager.class,
-			IAuthenticationManager.class,
-			IPublicKeyManager.class,
-			IRepositoryManager.class,
-			IProjectManager.class,
-			IFederationManager.class,
-
-			// the monolithic manager
-			IGitblit.class,
-
-			// the Gitblit Wicket app
-			GitBlitWebApp.class
-		}
-)
-public class DaggerModule {
-
-	@Provides @Singleton IStoredSettings provideSettings() {
-		return new FileSettings();
-	}
-
-	@Provides @Singleton IRuntimeManager provideRuntimeManager(IStoredSettings settings) {
-		return new RuntimeManager(settings);
-	}
-
-	@Provides @Singleton IPluginManager providePluginManager(IRuntimeManager runtimeManager) {
-		return new PluginManager(runtimeManager);
-	}
-
-	@Provides @Singleton INotificationManager provideNotificationManager(IStoredSettings settings) {
-		return new NotificationManager(settings);
-	}
-
-	@Provides @Singleton IUserManager provideUserManager(
-			IRuntimeManager runtimeManager,
-			IPluginManager pluginManager) {
-
-		return new UserManager(runtimeManager, pluginManager);
-	}
-
-	@Provides @Singleton IAuthenticationManager provideAuthenticationManager(
-			IRuntimeManager runtimeManager,
-			IUserManager userManager) {
-
-		return new AuthenticationManager(
-				runtimeManager,
-				userManager);
-	}
-
-	@Provides @Singleton IPublicKeyManager providePublicKeyManager(
-			IStoredSettings settings,
-			IRuntimeManager runtimeManager) {
-
-		String clazz = settings.getString(Keys.git.sshKeysManager, FileKeyManager.class.getName());
-		if (StringUtils.isEmpty(clazz)) {
-			clazz = FileKeyManager.class.getName();
-		}
-		if (FileKeyManager.class.getName().equals(clazz)) {
-			return new FileKeyManager(runtimeManager);
-		} else if (NullKeyManager.class.getName().equals(clazz)) {
-			return new NullKeyManager();
-		} else if (MemoryKeyManager.class.getName().equals(clazz)) {
-			return new MemoryKeyManager();
-		} else {
-			try {
-				Class<?> mgrClass = Class.forName(clazz);
-				return (IPublicKeyManager) mgrClass.newInstance();
-			} catch (Exception e) {
-
-			}
-			return null;
-		}
-	}
-
-	@Provides @Singleton IRepositoryManager provideRepositoryManager(
-			IRuntimeManager runtimeManager,
-			IPluginManager pluginManager,
-			IUserManager userManager) {
-
-		return new RepositoryManager(
-				runtimeManager,
-				pluginManager,
-				userManager);
-	}
-
-	@Provides @Singleton IProjectManager provideProjectManager(
-			IRuntimeManager runtimeManager,
-			IUserManager userManager,
-			IRepositoryManager repositoryManager) {
-
-		return new ProjectManager(
-				runtimeManager,
-				userManager,
-				repositoryManager);
-	}
-
-	@Provides @Singleton IFederationManager provideFederationManager(
-			IRuntimeManager runtimeManager,
-			INotificationManager notificationManager,
-			IRepositoryManager repositoryManager) {
-
-		return new FederationManager(
-				runtimeManager,
-				notificationManager,
-				repositoryManager);
-	}
-
-	@Provides @Singleton IGitblit provideGitblit(
-			IRuntimeManager runtimeManager,
-			IPluginManager pluginManager,
-			INotificationManager notificationManager,
-			IUserManager userManager,
-			IAuthenticationManager authenticationManager,
-			IPublicKeyManager publicKeyManager,
-			IRepositoryManager repositoryManager,
-			IProjectManager projectManager,
-			IFederationManager federationManager) {
-
-		return new GitBlit(
-				runtimeManager,
-				pluginManager,
-				notificationManager,
-				userManager,
-				authenticationManager,
-				publicKeyManager,
-				repositoryManager,
-				projectManager,
-				federationManager);
-	}
-
-	@Provides @Singleton GitBlitWebApp provideWebApplication(
-			IRuntimeManager runtimeManager,
-			IPluginManager pluginManager,
-			INotificationManager notificationManager,
-			IUserManager userManager,
-			IAuthenticationManager authenticationManager,
-			IPublicKeyManager publicKeyManager,
-			IRepositoryManager repositoryManager,
-			IProjectManager projectManager,
-			IFederationManager federationManager,
-			IGitblit gitblit) {
-
-		return new GitBlitWebApp(
-				runtimeManager,
-				pluginManager,
-				notificationManager,
-				userManager,
-				authenticationManager,
-				publicKeyManager,
-				repositoryManager,
-				projectManager,
-				federationManager,
-				gitblit);
-	}
-}
\ No newline at end of file
diff --git a/src/main/java/com/gitblit/FederationClient.java b/src/main/java/com/gitblit/FederationClient.java
index 29cdefe..822e8a7 100644
--- a/src/main/java/com/gitblit/FederationClient.java
+++ b/src/main/java/com/gitblit/FederationClient.java
@@ -1,189 +1,189 @@
-/*

- * Copyright 2011 gitblit.com.

- *

- * Licensed under the Apache License, Version 2.0 (the "License");

- * you may not use this file except in compliance with the License.

- * You may obtain a copy of the License at

- *

- *     http://www.apache.org/licenses/LICENSE-2.0

- *

- * Unless required by applicable law or agreed to in writing, software

- * distributed under the License is distributed on an "AS IS" BASIS,

- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

- * See the License for the specific language governing permissions and

- * limitations under the License.

- */

-package com.gitblit;

-

-import java.io.File;

-import java.util.ArrayList;

-import java.util.Collection;

-import java.util.List;

-

-import org.kohsuke.args4j.CmdLineException;

-import org.kohsuke.args4j.CmdLineParser;

-import org.kohsuke.args4j.Option;

-

-import com.gitblit.manager.FederationManager;

-import com.gitblit.manager.GitblitManager;

-import com.gitblit.manager.IGitblit;

-import com.gitblit.manager.INotificationManager;

-import com.gitblit.manager.RepositoryManager;

-import com.gitblit.manager.RuntimeManager;

-import com.gitblit.manager.UserManager;

-import com.gitblit.models.FederationModel;

-import com.gitblit.models.Mailing;

-import com.gitblit.service.FederationPullService;

-import com.gitblit.utils.FederationUtils;

-import com.gitblit.utils.StringUtils;

-

-/**

- * Command-line client to pull federated Gitblit repositories.

- *

- * @author James Moger

- *

- */

-public class FederationClient {

-

-	public static void main(String[] args) {

-		Params params = new Params();

-		CmdLineParser parser = new CmdLineParser(params);

-		try {

-			parser.parseArgument(args);

-		} catch (CmdLineException t) {

-			usage(parser, t);

-		}

-

-		System.out.println("Gitblit Federation Client v" + Constants.getVersion() + " (" + Constants.getBuildDate() + ")");

-

-		// command-line specified base folder

-		File baseFolder = new File(System.getProperty("user.dir"));

-		if (!StringUtils.isEmpty(params.baseFolder)) {

-			baseFolder = new File(params.baseFolder);

-		}

-

-		File regFile = com.gitblit.utils.FileUtils.resolveParameter(Constants.baseFolder$, baseFolder, params.registrationsFile);

-		FileSettings settings = new FileSettings(regFile.getAbsolutePath());

-		List<FederationModel> registrations = new ArrayList<FederationModel>();

-		if (StringUtils.isEmpty(params.url)) {

-			registrations.addAll(FederationUtils.getFederationRegistrations(settings));

-		} else {

-			if (StringUtils.isEmpty(params.token)) {

-				System.out.println("Must specify --token parameter!");

-				System.exit(0);

-			}

-			FederationModel model = new FederationModel("Gitblit");

-			model.url = params.url;

-			model.token = params.token;

-			model.mirror = params.mirror;

-			model.bare = params.bare;

-			model.folder = "";

-			registrations.add(model);

-		}

-		if (registrations.size() == 0) {

-			System.out.println("No Federation Registrations!  Nothing to do.");

-			System.exit(0);

-		}

-

-		// command-line specified repositories folder

-		if (!StringUtils.isEmpty(params.repositoriesFolder)) {

-			settings.overrideSetting(Keys.git.repositoriesFolder, new File(

-					params.repositoriesFolder).getAbsolutePath());

-		}

-

-		// configure the Gitblit singleton for minimal, non-server operation

-		RuntimeManager runtime = new RuntimeManager(settings, baseFolder).start();

-		NoopNotificationManager notifications = new NoopNotificationManager().start();

-		UserManager users = new UserManager(runtime, null).start();

-		RepositoryManager repositories = new RepositoryManager(runtime, null, users).start();

-		FederationManager federation = new FederationManager(runtime, notifications, repositories).start();

-		IGitblit gitblit = new GitblitManager(runtime, null, notifications, users, null, null, repositories, null, federation);

-

-		FederationPullService puller = new FederationPullService(gitblit, federation.getFederationRegistrations()) {

-			@Override

-			public void reschedule(FederationModel registration) {

-				// NOOP

-			}

-		};

-		puller.run();

-

-		System.out.println("Finished.");

-		System.exit(0);

-	}

-

-	private static void usage(CmdLineParser parser, CmdLineException t) {

-		System.out.println(Constants.getGitBlitVersion());

-		System.out.println();

-		if (t != null) {

-			System.out.println(t.getMessage());

-			System.out.println();

-		}

-

-		if (parser != null) {

-			parser.printUsage(System.out);

-		}

-		System.exit(0);

-	}

-

-	/**

-	 * Parameters class for FederationClient.

-	 */

-	private static class Params {

-

-		@Option(name = "--registrations", usage = "Gitblit Federation Registrations File", metaVar = "FILE")

-		public String registrationsFile = "${baseFolder}/federation.properties";

-

-		@Option(name = "--url", usage = "URL of Gitblit instance to mirror from", metaVar = "URL")

-		public String url;

-

-		@Option(name = "--mirror", usage = "Mirror repositories")

-		public boolean mirror;

-

-		@Option(name = "--bare", usage = "Create bare repositories")

-		public boolean bare;

-

-		@Option(name = "--token", usage = "Federation Token", metaVar = "TOKEN")

-		public String token;

-

-		@Option(name = "--baseFolder", usage = "Base folder for received data", metaVar = "PATH")

-		public String baseFolder;

-

-		@Option(name = "--repositoriesFolder", usage = "Destination folder for cloned repositories", metaVar = "PATH")

-		public String repositoriesFolder;

-

-	}

-

-	private static class NoopNotificationManager implements INotificationManager {

-

-		@Override

-		public NoopNotificationManager start() {

-			return this;

-		}

-

-		@Override

-		public NoopNotificationManager stop() {

-			return this;

-		}

-

-		@Override

-		public boolean isSendingMail() {

-			return false;

-		}

-

-		@Override

-		public void sendMailToAdministrators(String subject, String message) {

-		}

-

-		@Override

-		public void sendMail(String subject, String message, Collection<String> toAddresses) {

-		}

-

-		@Override

-		public void sendHtmlMail(String subject, String message, Collection<String> toAddresses) {

-		}

-

-		@Override

-		public void send(Mailing mailing) {

-		}

-	}

-}

+/*
+ * Copyright 2011 gitblit.com.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.gitblit;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import org.kohsuke.args4j.CmdLineException;
+import org.kohsuke.args4j.CmdLineParser;
+import org.kohsuke.args4j.Option;
+
+import com.gitblit.manager.FederationManager;
+import com.gitblit.manager.GitblitManager;
+import com.gitblit.manager.IGitblit;
+import com.gitblit.manager.INotificationManager;
+import com.gitblit.manager.RepositoryManager;
+import com.gitblit.manager.RuntimeManager;
+import com.gitblit.manager.UserManager;
+import com.gitblit.models.FederationModel;
+import com.gitblit.models.Mailing;
+import com.gitblit.service.FederationPullService;
+import com.gitblit.utils.FederationUtils;
+import com.gitblit.utils.StringUtils;
+
+/**
+ * Command-line client to pull federated Gitblit repositories.
+ *
+ * @author James Moger
+ *
+ */
+public class FederationClient {
+
+	public static void main(String[] args) {
+		Params params = new Params();
+		CmdLineParser parser = new CmdLineParser(params);
+		try {
+			parser.parseArgument(args);
+		} catch (CmdLineException t) {
+			usage(parser, t);
+		}
+
+		System.out.println("Gitblit Federation Client v" + Constants.getVersion() + " (" + Constants.getBuildDate() + ")");
+
+		// command-line specified base folder
+		File baseFolder = new File(System.getProperty("user.dir"));
+		if (!StringUtils.isEmpty(params.baseFolder)) {
+			baseFolder = new File(params.baseFolder);
+		}
+
+		File regFile = com.gitblit.utils.FileUtils.resolveParameter(Constants.baseFolder$, baseFolder, params.registrationsFile);
+		FileSettings settings = new FileSettings(regFile.getAbsolutePath());
+		List<FederationModel> registrations = new ArrayList<FederationModel>();
+		if (StringUtils.isEmpty(params.url)) {
+			registrations.addAll(FederationUtils.getFederationRegistrations(settings));
+		} else {
+			if (StringUtils.isEmpty(params.token)) {
+				System.out.println("Must specify --token parameter!");
+				System.exit(0);
+			}
+			FederationModel model = new FederationModel("Gitblit");
+			model.url = params.url;
+			model.token = params.token;
+			model.mirror = params.mirror;
+			model.bare = params.bare;
+			model.folder = "";
+			registrations.add(model);
+		}
+		if (registrations.size() == 0) {
+			System.out.println("No Federation Registrations!  Nothing to do.");
+			System.exit(0);
+		}
+
+		// command-line specified repositories folder
+		if (!StringUtils.isEmpty(params.repositoriesFolder)) {
+			settings.overrideSetting(Keys.git.repositoriesFolder, new File(
+					params.repositoriesFolder).getAbsolutePath());
+		}
+
+		// configure the Gitblit singleton for minimal, non-server operation
+		RuntimeManager runtime = new RuntimeManager(settings, baseFolder).start();
+		NoopNotificationManager notifications = new NoopNotificationManager().start();
+		UserManager users = new UserManager(runtime, null).start();
+		RepositoryManager repositories = new RepositoryManager(runtime, null, users).start();
+		FederationManager federation = new FederationManager(runtime, notifications, repositories).start();
+		IGitblit gitblit = new GitblitManager(null, null, runtime, null, notifications, users, null, repositories, null, federation);
+
+		FederationPullService puller = new FederationPullService(gitblit, federation.getFederationRegistrations()) {
+			@Override
+			public void reschedule(FederationModel registration) {
+				// NOOP
+			}
+		};
+		puller.run();
+
+		System.out.println("Finished.");
+		System.exit(0);
+	}
+
+	private static void usage(CmdLineParser parser, CmdLineException t) {
+		System.out.println(Constants.getGitBlitVersion());
+		System.out.println();
+		if (t != null) {
+			System.out.println(t.getMessage());
+			System.out.println();
+		}
+
+		if (parser != null) {
+			parser.printUsage(System.out);
+		}
+		System.exit(0);
+	}
+
+	/**
+	 * Parameters class for FederationClient.
+	 */
+	private static class Params {
+
+		@Option(name = "--registrations", usage = "Gitblit Federation Registrations File", metaVar = "FILE")
+		public String registrationsFile = "${baseFolder}/federation.properties";
+
+		@Option(name = "--url", usage = "URL of Gitblit instance to mirror from", metaVar = "URL")
+		public String url;
+
+		@Option(name = "--mirror", usage = "Mirror repositories")
+		public boolean mirror;
+
+		@Option(name = "--bare", usage = "Create bare repositories")
+		public boolean bare;
+
+		@Option(name = "--token", usage = "Federation Token", metaVar = "TOKEN")
+		public String token;
+
+		@Option(name = "--baseFolder", usage = "Base folder for received data", metaVar = "PATH")
+		public String baseFolder;
+
+		@Option(name = "--repositoriesFolder", usage = "Destination folder for cloned repositories", metaVar = "PATH")
+		public String repositoriesFolder;
+
+	}
+
+	private static class NoopNotificationManager implements INotificationManager {
+
+		@Override
+		public NoopNotificationManager start() {
+			return this;
+		}
+
+		@Override
+		public NoopNotificationManager stop() {
+			return this;
+		}
+
+		@Override
+		public boolean isSendingMail() {
+			return false;
+		}
+
+		@Override
+		public void sendMailToAdministrators(String subject, String message) {
+		}
+
+		@Override
+		public void sendMail(String subject, String message, Collection<String> toAddresses) {
+		}
+
+		@Override
+		public void sendHtmlMail(String subject, String message, Collection<String> toAddresses) {
+		}
+
+		@Override
+		public void send(Mailing mailing) {
+		}
+	}
+}
diff --git a/src/main/java/com/gitblit/GitBlit.java b/src/main/java/com/gitblit/GitBlit.java
index f9d9be9..68a91bb 100644
--- a/src/main/java/com/gitblit/GitBlit.java
+++ b/src/main/java/com/gitblit/GitBlit.java
@@ -15,471 +15,55 @@
  */
 package com.gitblit;
 
-import java.text.MessageFormat;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Set;
-
-import javax.inject.Singleton;
-import javax.servlet.http.HttpServletRequest;
-
-import com.gitblit.Constants.AccessPermission;
-import com.gitblit.Constants.Transport;
 import com.gitblit.manager.GitblitManager;
 import com.gitblit.manager.IAuthenticationManager;
 import com.gitblit.manager.IFederationManager;
-import com.gitblit.manager.IGitblit;
 import com.gitblit.manager.INotificationManager;
 import com.gitblit.manager.IPluginManager;
 import com.gitblit.manager.IProjectManager;
 import com.gitblit.manager.IRepositoryManager;
 import com.gitblit.manager.IRuntimeManager;
 import com.gitblit.manager.IUserManager;
-import com.gitblit.manager.ServicesManager;
-import com.gitblit.models.RepositoryModel;
-import com.gitblit.models.RepositoryUrl;
-import com.gitblit.models.UserModel;
-import com.gitblit.tickets.BranchTicketService;
-import com.gitblit.tickets.FileTicketService;
 import com.gitblit.tickets.ITicketService;
-import com.gitblit.tickets.NullTicketService;
-import com.gitblit.tickets.RedisTicketService;
 import com.gitblit.transport.ssh.IPublicKeyManager;
-import com.gitblit.utils.StringUtils;
-
-import dagger.Module;
-import dagger.ObjectGraph;
-import dagger.Provides;
+import com.google.inject.Inject;
+import com.google.inject.Provider;
+import com.google.inject.Singleton;
 
 /**
- * GitBlit is the aggregate manager for the Gitblit webapp.  It provides all
- * management functions and also manages some long-running services.
+ * GitBlit is the aggregate manager for the Gitblit webapp.  The parent class provides all
+ * functionality.  This class exists to not break existing Groovy push hooks.
  *
  * @author James Moger
  *
  */
+@Singleton
+@Deprecated
 public class GitBlit extends GitblitManager {
 
-	private final ObjectGraph injector;
-
-	private final ServicesManager servicesManager;
-
-	private ITicketService ticketService;
-
+	@Inject
 	public GitBlit(
+			Provider<IPublicKeyManager> publicKeyManagerProvider,
+			Provider<ITicketService> ticketServiceProvider,
 			IRuntimeManager runtimeManager,
 			IPluginManager pluginManager,
 			INotificationManager notificationManager,
 			IUserManager userManager,
 			IAuthenticationManager authenticationManager,
-			IPublicKeyManager publicKeyManager,
 			IRepositoryManager repositoryManager,
 			IProjectManager projectManager,
 			IFederationManager federationManager) {
 
-		super(runtimeManager,
+		super(
+				publicKeyManagerProvider,
+				ticketServiceProvider,
+				runtimeManager,
 				pluginManager,
 				notificationManager,
 				userManager,
 				authenticationManager,
-				publicKeyManager,
 				repositoryManager,
 				projectManager,
 				federationManager);
-
-		this.injector = ObjectGraph.create(getModules());
-
-		this.servicesManager = new ServicesManager(this);
-	}
-
-	@Override
-	public GitBlit start() {
-		super.start();
-		logger.info("Starting services manager...");
-		servicesManager.start();
-		configureTicketService();
-		return this;
-	}
-
-	@Override
-	public GitBlit stop() {
-		super.stop();
-		servicesManager.stop();
-		ticketService.stop();
-		return this;
-	}
-
-	@Override
-	public boolean isServingRepositories() {
-		return servicesManager.isServingRepositories();
-	}
-
-	@Override
-	public boolean isServingHTTP() {
-		return servicesManager.isServingHTTP();
-	}
-
-	@Override
-	public boolean isServingGIT() {
-		return servicesManager.isServingGIT();
-	}
-
-	@Override
-	public boolean isServingSSH() {
-		return servicesManager.isServingSSH();
-	}
-
-	protected Object [] getModules() {
-		return new Object [] { new GitBlitModule()};
-	}
-
-	protected boolean acceptPush(Transport byTransport) {
-		if (byTransport == null) {
-			logger.info("Unknown transport, push rejected!");
-			return false;
-		}
-
-		Set<Transport> transports = new HashSet<Transport>();
-		for (String value : getSettings().getStrings(Keys.git.acceptedPushTransports)) {
-			Transport transport = Transport.fromString(value);
-			if (transport == null) {
-				logger.info(String.format("Ignoring unknown registered transport %s", value));
-				continue;
-			}
-
-			transports.add(transport);
-		}
-
-		if (transports.isEmpty()) {
-			// no transports are explicitly specified, all are acceptable
-			return true;
-		}
-
-		// verify that the transport is permitted
-		return transports.contains(byTransport);
-	}
-
-	/**
-	 * Returns a list of repository URLs and the user access permission.
-	 *
-	 * @param request
-	 * @param user
-	 * @param repository
-	 * @return a list of repository urls
-	 */
-	@Override
-	public List<RepositoryUrl> getRepositoryUrls(HttpServletRequest request, UserModel user, RepositoryModel repository) {
-		if (user == null) {
-			user = UserModel.ANONYMOUS;
-		}
-		String username = StringUtils.encodeUsername(UserModel.ANONYMOUS.equals(user) ? "" : user.username);
-
-		List<RepositoryUrl> list = new ArrayList<RepositoryUrl>();
-
-		// http/https url
-		if (settings.getBoolean(Keys.git.enableGitServlet, true)) {
-			AccessPermission permission = user.getRepositoryPermission(repository).permission;
-			if (permission.exceeds(AccessPermission.NONE)) {
-				Transport transport = Transport.fromString(request.getScheme());
-				if (permission.atLeast(AccessPermission.PUSH) && !acceptPush(transport)) {
-					// downgrade the repo permission for this transport
-					// because it is not an acceptable PUSH transport
-					permission = AccessPermission.CLONE;
-				}
-				list.add(new RepositoryUrl(getRepositoryUrl(request, username, repository), permission));
-			}
-		}
-
-		// ssh daemon url
-		String sshDaemonUrl = servicesManager.getSshDaemonUrl(request, user, repository);
-		if (!StringUtils.isEmpty(sshDaemonUrl)) {
-			AccessPermission permission = user.getRepositoryPermission(repository).permission;
-			if (permission.exceeds(AccessPermission.NONE)) {
-				if (permission.atLeast(AccessPermission.PUSH) && !acceptPush(Transport.SSH)) {
-					// downgrade the repo permission for this transport
-					// because it is not an acceptable PUSH transport
-					permission = AccessPermission.CLONE;
-				}
-
-				list.add(new RepositoryUrl(sshDaemonUrl, permission));
-			}
-		}
-
-		// git daemon url
-		String gitDaemonUrl = servicesManager.getGitDaemonUrl(request, user, repository);
-		if (!StringUtils.isEmpty(gitDaemonUrl)) {
-			AccessPermission permission = servicesManager.getGitDaemonAccessPermission(user, repository);
-			if (permission.exceeds(AccessPermission.NONE)) {
-				if (permission.atLeast(AccessPermission.PUSH) && !acceptPush(Transport.GIT)) {
-					// downgrade the repo permission for this transport
-					// because it is not an acceptable PUSH transport
-					permission = AccessPermission.CLONE;
-				}
-				list.add(new RepositoryUrl(gitDaemonUrl, permission));
-			}
-		}
-
-		// add all other urls
-		// {0} = repository
-		// {1} = username
-		for (String url : settings.getStrings(Keys.web.otherUrls)) {
-			if (url.contains("{1}")) {
-				// external url requires username, only add url IF we have one
-				if (!StringUtils.isEmpty(username)) {
-					list.add(new RepositoryUrl(MessageFormat.format(url, repository.name, username), null));
-				}
-			} else {
-				// external url does not require username
-				list.add(new RepositoryUrl(MessageFormat.format(url, repository.name), null));
-			}
-		}
-
-		// sort transports by highest permission and then by transport security
-		Collections.sort(list, new Comparator<RepositoryUrl>() {
-
-			@Override
-			public int compare(RepositoryUrl o1, RepositoryUrl o2) {
-				if (!o1.isExternal() && o2.isExternal()) {
-					// prefer Gitblit over external
-					return -1;
-				} else if (o1.isExternal() && !o2.isExternal()) {
-					// prefer Gitblit over external
-					return 1;
-				} else if (o1.isExternal() && o2.isExternal()) {
-					// sort by Transport ordinal
-					return o1.transport.compareTo(o2.transport);
-				} else if (o1.permission.exceeds(o2.permission)) {
-					// prefer highest permission
-					return -1;
-				} else if (o2.permission.exceeds(o1.permission)) {
-					// prefer highest permission
-					return 1;
-				}
-
-				// prefer more secure transports
-				return o1.transport.compareTo(o2.transport);
-			}
-		});
-
-		// consider the user's transport preference
-		RepositoryUrl preferredUrl = null;
-		Transport preferredTransport = user.getPreferences().getTransport();
-		if (preferredTransport != null) {
-			Iterator<RepositoryUrl> itr = list.iterator();
-			while (itr.hasNext()) {
-				RepositoryUrl url = itr.next();
-				if (url.transport.equals(preferredTransport)) {
-					itr.remove();
-					preferredUrl = url;
-					break;
-				}
-			}
-		}
-		if (preferredUrl != null) {
-			list.add(0, preferredUrl);
-		}
-
-		return list;
-	}
-
-	/**
-	 * Detect renames and reindex as appropriate.
-	 */
-	@Override
-	public void updateRepositoryModel(String repositoryName, RepositoryModel repository,
-			boolean isCreate) throws GitBlitException {
-		RepositoryModel oldModel = null;
-		boolean isRename = !isCreate && !repositoryName.equalsIgnoreCase(repository.name);
-		if (isRename) {
-			oldModel = repositoryManager.getRepositoryModel(repositoryName);
-		}
-
-		super.updateRepositoryModel(repositoryName, repository, isCreate);
-
-		if (isRename && ticketService != null) {
-			ticketService.rename(oldModel, repository);
-		}
-	}
-
-	/**
-	 * Delete the user and all associated public ssh keys.
-	 */
-	@Override
-	public boolean deleteUser(String username) {
-		UserModel user = userManager.getUserModel(username);
-		return deleteUserModel(user);
-	}
-
-	@Override
-	public boolean deleteUserModel(UserModel model) {
-		boolean success = userManager.deleteUserModel(model);
-		if (success) {
-			getPublicKeyManager().removeAllKeys(model.username);
-		}
-		return success;
-	}
-
-	/**
-	 * Delete the repository and all associated tickets.
-	 */
-	@Override
-	public boolean deleteRepository(String repositoryName) {
-		RepositoryModel repository = repositoryManager.getRepositoryModel(repositoryName);
-		return deleteRepositoryModel(repository);
-	}
-
-	@Override
-	public boolean deleteRepositoryModel(RepositoryModel model) {
-		boolean success = repositoryManager.deleteRepositoryModel(model);
-		if (success && ticketService != null) {
-			ticketService.deleteAll(model);
-		}
-		return success;
-	}
-
-	/**
-	 * Returns the configured ticket service.
-	 *
-	 * @return a ticket service
-	 */
-	@Override
-	public ITicketService getTicketService() {
-		return ticketService;
-	}
-
-	protected void configureTicketService() {
-		String clazz = settings.getString(Keys.tickets.service, NullTicketService.class.getName());
-		if (StringUtils.isEmpty(clazz)) {
-			clazz = NullTicketService.class.getName();
-		}
-		try {
-			Class<? extends ITicketService> serviceClass = (Class<? extends ITicketService>) Class.forName(clazz);
-			ticketService = injector.get(serviceClass).start();
-			if (ticketService instanceof NullTicketService) {
-				logger.warn("No ticket service configured.");
-			} else if (ticketService.isReady()) {
-				logger.info("{} is ready.", ticketService);
-			} else {
-				logger.warn("{} is disabled.", ticketService);
-			}
-		} catch (Exception e) {
-			logger.error("failed to create ticket service " + clazz, e);
-			ticketService = injector.get(NullTicketService.class).start();
-		}
-	}
-
-	/**
-	 * A nested Dagger graph is used for constructor dependency injection of
-	 * complex classes.
-	 *
-	 * @author James Moger
-	 *
-	 */
-	@Module(
-			library = true,
-			injects = {
-					IStoredSettings.class,
-
-					// core managers
-					IRuntimeManager.class,
-					IPluginManager.class,
-					INotificationManager.class,
-					IUserManager.class,
-					IAuthenticationManager.class,
-					IRepositoryManager.class,
-					IProjectManager.class,
-					IFederationManager.class,
-
-					// the monolithic manager
-					IGitblit.class,
-
-					// ticket services
-					NullTicketService.class,
-					FileTicketService.class,
-					BranchTicketService.class,
-					RedisTicketService.class
-				}
-			)
-	class GitBlitModule {
-
-		@Provides @Singleton IStoredSettings provideSettings() {
-			return settings;
-		}
-
-		@Provides @Singleton IRuntimeManager provideRuntimeManager() {
-			return runtimeManager;
-		}
-
-		@Provides @Singleton IPluginManager providePluginManager() {
-			return pluginManager;
-		}
-
-		@Provides @Singleton INotificationManager provideNotificationManager() {
-			return notificationManager;
-		}
-
-		@Provides @Singleton IUserManager provideUserManager() {
-			return userManager;
-		}
-
-		@Provides @Singleton IAuthenticationManager provideAuthenticationManager() {
-			return authenticationManager;
-		}
-
-		@Provides @Singleton IRepositoryManager provideRepositoryManager() {
-			return repositoryManager;
-		}
-
-		@Provides @Singleton IProjectManager provideProjectManager() {
-			return projectManager;
-		}
-
-		@Provides @Singleton IFederationManager provideFederationManager() {
-			return federationManager;
-		}
-
-		@Provides @Singleton IGitblit provideGitblit() {
-			return GitBlit.this;
-		}
-
-		@Provides @Singleton NullTicketService provideNullTicketService() {
-			return new NullTicketService(
-					runtimeManager,
-					pluginManager,
-					notificationManager,
-					userManager,
-					repositoryManager);
-		}
-
-		@Provides @Singleton FileTicketService provideFileTicketService() {
-			return new FileTicketService(
-					runtimeManager,
-					pluginManager,
-					notificationManager,
-					userManager,
-					repositoryManager);
-		}
-
-		@Provides @Singleton BranchTicketService provideBranchTicketService() {
-			return new BranchTicketService(
-					runtimeManager,
-					pluginManager,
-					notificationManager,
-					userManager,
-					repositoryManager);
-		}
-
-		@Provides @Singleton RedisTicketService provideRedisTicketService() {
-			return new RedisTicketService(
-					runtimeManager,
-					pluginManager,
-					notificationManager,
-					userManager,
-					repositoryManager);
-		}
 	}
 }
diff --git a/src/main/java/com/gitblit/GitBlitServer.java b/src/main/java/com/gitblit/GitBlitServer.java
index b40e21f..cd26980 100644
--- a/src/main/java/com/gitblit/GitBlitServer.java
+++ b/src/main/java/com/gitblit/GitBlitServer.java
@@ -208,22 +208,7 @@
 		}
 
 		logger = LoggerFactory.getLogger(GitBlitServer.class);
-		logger.info(Constants.BORDER);
-		logger.info("            _____  _  _    _      _  _  _");
-		logger.info("           |  __ \\(_)| |  | |    | |(_)| |");
-		logger.info("           | |  \\/ _ | |_ | |__  | | _ | |_");
-		logger.info("           | | __ | || __|| '_ \\ | || || __|");
-		logger.info("           | |_\\ \\| || |_ | |_) || || || |_");
-		logger.info("            \\____/|_| \\__||_.__/ |_||_| \\__|");
-		int spacing = (Constants.BORDER.length() - Constants.getGitBlitVersion().length()) / 2;
-		StringBuilder sb = new StringBuilder();
-		while (spacing > 0) {
-			spacing--;
-			sb.append(' ');
-		}
-		logger.info(sb.toString() + Constants.getGitBlitVersion());
-		logger.info("");
-		logger.info(Constants.BORDER);
+		logger.info("\n" + Constants.getASCIIArt());
 
 		System.setProperty("java.awt.headless", "true");
 
diff --git a/src/main/java/com/gitblit/dagger/DaggerContext.java b/src/main/java/com/gitblit/dagger/DaggerContext.java
deleted file mode 100644
index 0e6a3fc..0000000
--- a/src/main/java/com/gitblit/dagger/DaggerContext.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright 2013 gitblit.com.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.gitblit.dagger;
-
-import javax.servlet.ServletContext;
-import javax.servlet.ServletContextEvent;
-import javax.servlet.ServletContextListener;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import dagger.ObjectGraph;
-
-/**
- * Dagger servlet context listener is a context listener that uses Dagger to
- * instantiate and inject servlets, filters, and anything else you might want.
- *
- * @author James Moger
- *
- */
-public abstract class DaggerContext implements ServletContextListener {
-
-	public static final String INJECTOR_NAME = ObjectGraph.class.getName();
-
-	protected final Logger logger = LoggerFactory.getLogger(getClass());
-
-	protected abstract Object [] getModules();
-
-	protected abstract void destroyContext(ServletContext context);
-
-	protected ObjectGraph getInjector(ServletContext context) {
-		Object o = context.getAttribute(INJECTOR_NAME);
-		if (o == null) {
-			logger.debug("instantiating Dagger modules");
-			Object [] modules = getModules();
-			logger.debug("getting Dagger injector");
-			try {
-				o = ObjectGraph.create(modules);
-				logger.debug("setting Dagger injector into {} attribute", INJECTOR_NAME);
-				context.setAttribute(INJECTOR_NAME, o);
-			} catch (Throwable t) {
-				logger.error("an error occurred creating the Dagger injector", t);
-			}
-		}
-		return (ObjectGraph) o;
-	}
-
-	@Override
-	public final void contextDestroyed(ServletContextEvent contextEvent) {
-		ServletContext context = contextEvent.getServletContext();
-		context.removeAttribute(INJECTOR_NAME);
-		destroyContext(context);
-	}
-}
diff --git a/src/main/java/com/gitblit/dagger/DaggerFilter.java b/src/main/java/com/gitblit/dagger/DaggerFilter.java
deleted file mode 100644
index 01c07a4..0000000
--- a/src/main/java/com/gitblit/dagger/DaggerFilter.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*

- * Copyright 2013 gitblit.com.

- *

- * Licensed under the Apache License, Version 2.0 (the "License");

- * you may not use this file except in compliance with the License.

- * You may obtain a copy of the License at

- *

- *     http://www.apache.org/licenses/LICENSE-2.0

- *

- * Unless required by applicable law or agreed to in writing, software

- * distributed under the License is distributed on an "AS IS" BASIS,

- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

- * See the License for the specific language governing permissions and

- * limitations under the License.

- */

-package com.gitblit.dagger;

-

-import javax.servlet.Filter;

-import javax.servlet.FilterConfig;

-import javax.servlet.ServletContext;

-import javax.servlet.ServletException;

-

-import dagger.ObjectGraph;

-

-/**

- * Uses Dagger to manually inject dependencies into a servlet filter.

- * This class is useful for servlet containers that offer CDI and are

- * confused by Dagger.

- *

- * @author James Moger

- *

- */

-public abstract class DaggerFilter implements Filter {

-

-	@Override

-	public final void init(FilterConfig filterConfig) throws ServletException {

-		ServletContext context = filterConfig.getServletContext();

-		ObjectGraph objectGraph = (ObjectGraph) context.getAttribute(DaggerContext.INJECTOR_NAME);

-		inject(objectGraph, filterConfig);

-	}

-

-	protected abstract void inject(ObjectGraph dagger, FilterConfig filterConfig) throws ServletException;

-

-	@Override

-	public void destroy() {

-	}

-}

diff --git a/src/main/java/com/gitblit/dagger/DaggerServlet.java b/src/main/java/com/gitblit/dagger/DaggerServlet.java
deleted file mode 100644
index 88331a4..0000000
--- a/src/main/java/com/gitblit/dagger/DaggerServlet.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*

- * Copyright 2013 gitblit.com.

- *

- * Licensed under the Apache License, Version 2.0 (the "License");

- * you may not use this file except in compliance with the License.

- * You may obtain a copy of the License at

- *

- *     http://www.apache.org/licenses/LICENSE-2.0

- *

- * Unless required by applicable law or agreed to in writing, software

- * distributed under the License is distributed on an "AS IS" BASIS,

- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

- * See the License for the specific language governing permissions and

- * limitations under the License.

- */

-package com.gitblit.dagger;

-

-import javax.servlet.ServletContext;

-import javax.servlet.ServletException;

-import javax.servlet.http.HttpServlet;

-

-import dagger.ObjectGraph;

-

-/**

- * Uses Dagger to manually inject dependencies into a servlet.

- * This class is useful for servlet containers that offer CDI and are

- * confused by Dagger.

- *

- * @author James Moger

- *

- */

-public abstract class DaggerServlet extends HttpServlet {

-

-	private static final long serialVersionUID = 1L;

-

-	@Override

-	public final void init() throws ServletException {

-		ServletContext context = getServletContext();

-		ObjectGraph objectGraph = (ObjectGraph) context.getAttribute(DaggerContext.INJECTOR_NAME);

-		inject(objectGraph);

-	}

-

-	protected abstract void inject(ObjectGraph dagger);

-}

diff --git a/src/main/java/com/gitblit/dagger/DaggerWicketFilter.java b/src/main/java/com/gitblit/dagger/DaggerWicketFilter.java
deleted file mode 100644
index c2fd4d6..0000000
--- a/src/main/java/com/gitblit/dagger/DaggerWicketFilter.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*

- * Copyright 2013 gitblit.com.

- *

- * Licensed under the Apache License, Version 2.0 (the "License");

- * you may not use this file except in compliance with the License.

- * You may obtain a copy of the License at

- *

- *     http://www.apache.org/licenses/LICENSE-2.0

- *

- * Unless required by applicable law or agreed to in writing, software

- * distributed under the License is distributed on an "AS IS" BASIS,

- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

- * See the License for the specific language governing permissions and

- * limitations under the License.

- */

-package com.gitblit.dagger;

-

-import javax.servlet.FilterConfig;

-import javax.servlet.ServletContext;

-import javax.servlet.ServletException;

-

-import org.apache.wicket.protocol.http.WicketFilter;

-

-import dagger.ObjectGraph;

-

-/**

- * Uses Dagger to manually inject dependencies into a Wicket filter.

- * This class is useful for servlet containers that offer CDI and are

- * confused by Dagger.

- *

- * @author James Moger

- *

- */

-public abstract class DaggerWicketFilter extends WicketFilter {

-

-	@Override

-	public final void init(FilterConfig filterConfig) throws ServletException {

-		ServletContext context = filterConfig.getServletContext();

-		ObjectGraph objectGraph = (ObjectGraph) context.getAttribute(DaggerContext.INJECTOR_NAME);

-		inject(objectGraph);

-		super.init(filterConfig);

-	}

-

-	protected abstract void inject(ObjectGraph dagger);

-}

diff --git a/src/main/java/com/gitblit/guice/CoreModule.java b/src/main/java/com/gitblit/guice/CoreModule.java
new file mode 100644
index 0000000..c0d39e9
--- /dev/null
+++ b/src/main/java/com/gitblit/guice/CoreModule.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2014 gitblit.com.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.gitblit.guice;
+
+import com.gitblit.FileSettings;
+import com.gitblit.GitBlit;
+import com.gitblit.IStoredSettings;
+import com.gitblit.manager.AuthenticationManager;
+import com.gitblit.manager.FederationManager;
+import com.gitblit.manager.IAuthenticationManager;
+import com.gitblit.manager.IFederationManager;
+import com.gitblit.manager.IGitblit;
+import com.gitblit.manager.INotificationManager;
+import com.gitblit.manager.IPluginManager;
+import com.gitblit.manager.IProjectManager;
+import com.gitblit.manager.IRepositoryManager;
+import com.gitblit.manager.IRuntimeManager;
+import com.gitblit.manager.IServicesManager;
+import com.gitblit.manager.IUserManager;
+import com.gitblit.manager.NotificationManager;
+import com.gitblit.manager.PluginManager;
+import com.gitblit.manager.ProjectManager;
+import com.gitblit.manager.RepositoryManager;
+import com.gitblit.manager.RuntimeManager;
+import com.gitblit.manager.ServicesManager;
+import com.gitblit.manager.UserManager;
+import com.gitblit.tickets.ITicketService;
+import com.gitblit.transport.ssh.IPublicKeyManager;
+import com.gitblit.utils.WorkQueue;
+import com.google.inject.AbstractModule;
+
+/**
+ * CoreModule references all the core business objects.
+ *
+ * @author James Moger
+ *
+ */
+public class CoreModule extends AbstractModule {
+
+	@Override
+	protected void configure() {
+
+		bind(IStoredSettings.class).toInstance(new FileSettings());
+
+		// bind complex providers
+		bind(IPublicKeyManager.class).toProvider(IPublicKeyManagerProvider.class);
+		bind(ITicketService.class).toProvider(ITicketServiceProvider.class);
+		bind(WorkQueue.class).toProvider(WorkQueueProvider.class);
+
+		// core managers
+		bind(IRuntimeManager.class).to(RuntimeManager.class);
+		bind(IPluginManager.class).to(PluginManager.class);
+		bind(INotificationManager.class).to(NotificationManager.class);
+		bind(IUserManager.class).to(UserManager.class);
+		bind(IAuthenticationManager.class).to(AuthenticationManager.class);
+		bind(IRepositoryManager.class).to(RepositoryManager.class);
+		bind(IProjectManager.class).to(ProjectManager.class);
+		bind(IFederationManager.class).to(FederationManager.class);
+
+		// the monolithic manager
+		bind(IGitblit.class).to(GitBlit.class);
+
+		// manager for long-running daemons and services
+		bind(IServicesManager.class).to(ServicesManager.class);
+	}
+}
\ No newline at end of file
diff --git a/src/main/java/com/gitblit/guice/IPublicKeyManagerProvider.java b/src/main/java/com/gitblit/guice/IPublicKeyManagerProvider.java
new file mode 100644
index 0000000..8075aa9
--- /dev/null
+++ b/src/main/java/com/gitblit/guice/IPublicKeyManagerProvider.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2014 gitblit.com.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.gitblit.guice;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.gitblit.IStoredSettings;
+import com.gitblit.Keys;
+import com.gitblit.manager.IRuntimeManager;
+import com.gitblit.transport.ssh.FileKeyManager;
+import com.gitblit.transport.ssh.IPublicKeyManager;
+import com.gitblit.transport.ssh.NullKeyManager;
+import com.gitblit.utils.StringUtils;
+import com.google.inject.Inject;
+import com.google.inject.Provider;
+import com.google.inject.Singleton;
+
+/**
+ * Provides a lazily-instantiated IPublicKeyManager configured from IStoredSettings.
+ *
+ * @author James Moger
+ *
+ */
+@Singleton
+public class IPublicKeyManagerProvider implements Provider<IPublicKeyManager> {
+
+	private final Logger logger = LoggerFactory.getLogger(getClass());
+
+	private final IRuntimeManager runtimeManager;
+
+	private volatile IPublicKeyManager manager;
+
+	@Inject
+	public IPublicKeyManagerProvider(IRuntimeManager runtimeManager) {
+		this.runtimeManager = runtimeManager;
+	}
+
+	@Override
+	public synchronized IPublicKeyManager get() {
+		if (manager != null) {
+			return manager;
+		}
+
+		IStoredSettings settings = runtimeManager.getSettings();
+		String clazz = settings.getString(Keys.git.sshKeysManager, FileKeyManager.class.getName());
+		if (StringUtils.isEmpty(clazz)) {
+			clazz = FileKeyManager.class.getName();
+		}
+		try {
+			Class<? extends IPublicKeyManager> mgrClass = (Class<? extends IPublicKeyManager>) Class.forName(clazz);
+			manager = runtimeManager.getInjector().getInstance(mgrClass);
+		} catch (Exception e) {
+			logger.error("failed to create public key manager", e);
+			manager = new NullKeyManager();
+		}
+		return manager;
+	}
+}
\ No newline at end of file
diff --git a/src/main/java/com/gitblit/guice/ITicketServiceProvider.java b/src/main/java/com/gitblit/guice/ITicketServiceProvider.java
new file mode 100644
index 0000000..fd39955
--- /dev/null
+++ b/src/main/java/com/gitblit/guice/ITicketServiceProvider.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2014 gitblit.com.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.gitblit.guice;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.gitblit.IStoredSettings;
+import com.gitblit.Keys;
+import com.gitblit.manager.IRuntimeManager;
+import com.gitblit.tickets.ITicketService;
+import com.gitblit.tickets.NullTicketService;
+import com.gitblit.utils.StringUtils;
+import com.google.inject.Inject;
+import com.google.inject.Provider;
+import com.google.inject.Singleton;
+
+/**
+ * Provides a lazily-instantiated ITicketService configured from IStoredSettings.
+ *
+ * @author James Moger
+ *
+ */
+@Singleton
+public class ITicketServiceProvider implements Provider<ITicketService> {
+
+	private final Logger logger = LoggerFactory.getLogger(getClass());
+
+	private final IRuntimeManager runtimeManager;
+
+	private volatile ITicketService service;
+
+	@Inject
+	public ITicketServiceProvider(IRuntimeManager runtimeManager) {
+		this.runtimeManager = runtimeManager;
+	}
+
+	@Override
+	public synchronized ITicketService get() {
+		if (service != null) {
+			return service;
+		}
+
+		IStoredSettings settings = runtimeManager.getSettings();
+		String clazz = settings.getString(Keys.tickets.service, NullTicketService.class.getName());
+		if (StringUtils.isEmpty(clazz)) {
+			clazz = NullTicketService.class.getName();
+		}
+
+		try {
+			Class<? extends ITicketService> serviceClass = (Class<? extends ITicketService>) Class.forName(clazz);
+			service = runtimeManager.getInjector().getInstance(serviceClass);
+		} catch (Exception e) {
+			logger.error("failed to create ticket service", e);
+			service = runtimeManager.getInjector().getInstance(NullTicketService.class);
+		}
+
+		return service;
+	}
+}
\ No newline at end of file
diff --git a/src/main/java/com/gitblit/guice/WebModule.java b/src/main/java/com/gitblit/guice/WebModule.java
new file mode 100644
index 0000000..5b56918
--- /dev/null
+++ b/src/main/java/com/gitblit/guice/WebModule.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright 2014 gitblit.com.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.gitblit.guice;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import com.gitblit.Constants;
+import com.gitblit.servlet.BranchGraphServlet;
+import com.gitblit.servlet.DownloadZipFilter;
+import com.gitblit.servlet.DownloadZipServlet;
+import com.gitblit.servlet.EnforceAuthenticationFilter;
+import com.gitblit.servlet.FederationServlet;
+import com.gitblit.servlet.GitFilter;
+import com.gitblit.servlet.GitServlet;
+import com.gitblit.servlet.LogoServlet;
+import com.gitblit.servlet.PagesFilter;
+import com.gitblit.servlet.PagesServlet;
+import com.gitblit.servlet.ProxyFilter;
+import com.gitblit.servlet.PtServlet;
+import com.gitblit.servlet.RawFilter;
+import com.gitblit.servlet.RawServlet;
+import com.gitblit.servlet.RobotsTxtServlet;
+import com.gitblit.servlet.RpcFilter;
+import com.gitblit.servlet.RpcServlet;
+import com.gitblit.servlet.SparkleShareInviteServlet;
+import com.gitblit.servlet.SyndicationFilter;
+import com.gitblit.servlet.SyndicationServlet;
+import com.gitblit.wicket.GitblitWicketFilter;
+import com.google.common.base.Joiner;
+import com.google.inject.servlet.ServletModule;
+
+/**
+ * Defines all the web servlets & filters.
+ *
+ * @author James Moger
+ *
+ */
+public class WebModule extends ServletModule {
+
+	final static String ALL = "/*";
+
+	@Override
+	protected void configureServlets() {
+		// servlets
+		serve(fuzzy(Constants.R_PATH), fuzzy(Constants.GIT_PATH)).with(GitServlet.class);
+		serve(fuzzy(Constants.RAW_PATH)).with(RawServlet.class);
+		serve(fuzzy(Constants.PAGES)).with(PagesServlet.class);
+		serve(fuzzy(Constants.RPC_PATH)).with(RpcServlet.class);
+		serve(fuzzy(Constants.ZIP_PATH)).with(DownloadZipServlet.class);
+		serve(fuzzy(Constants.SYNDICATION_PATH)).with(SyndicationServlet.class);
+
+		serve(fuzzy(Constants.FEDERATION_PATH)).with(FederationServlet.class);
+		serve(fuzzy(Constants.SPARKLESHARE_INVITE_PATH)).with(SparkleShareInviteServlet.class);
+		serve(fuzzy(Constants.BRANCH_GRAPH_PATH)).with(BranchGraphServlet.class);
+		serve(Constants.PT_PATH).with(PtServlet.class);
+		serve("/robots.txt").with(RobotsTxtServlet.class);
+		serve("/logo.png").with(LogoServlet.class);
+
+		// global filters
+		filter(ALL).through(ProxyFilter.class);
+		filter(ALL).through(EnforceAuthenticationFilter.class);
+
+		// security filters
+		filter(fuzzy(Constants.R_PATH), fuzzy(Constants.GIT_PATH)).through(GitFilter.class);
+		filter(fuzzy(Constants.RAW_PATH)).through(RawFilter.class);
+		filter(fuzzy(Constants.PAGES)).through(PagesFilter.class);
+		filter(fuzzy(Constants.RPC_PATH)).through(RpcFilter.class);
+		filter(fuzzy(Constants.ZIP_PATH)).through(DownloadZipFilter.class);
+		filter(fuzzy(Constants.SYNDICATION_PATH)).through(SyndicationFilter.class);
+
+		// Wicket
+		String toIgnore = Joiner.on(",").join(Constants.R_PATH, Constants.GIT_PATH, Constants.RAW_PATH,
+				Constants.PAGES, Constants.RPC_PATH, Constants.ZIP_PATH, Constants.SYNDICATION_PATH,
+				Constants.FEDERATION_PATH, Constants.SPARKLESHARE_INVITE_PATH, Constants.BRANCH_GRAPH_PATH,
+				Constants.PT_PATH, "/robots.txt", "/logo.png");
+
+		Map<String, String> params = new HashMap<String, String>();
+		params.put(GitblitWicketFilter.FILTER_MAPPING_PARAM, ALL);
+		params.put(GitblitWicketFilter.IGNORE_PATHS_PARAM, toIgnore);
+		filter(ALL).through(GitblitWicketFilter.class, params);
+	}
+
+	private String fuzzy(String path) {
+		if (path.endsWith(ALL)) {
+			return path;
+		} else if (path.endsWith("/")) {
+			return path + "*";
+		}
+		return path + ALL;
+	}
+}
diff --git a/src/main/java/com/gitblit/guice/WorkQueueProvider.java b/src/main/java/com/gitblit/guice/WorkQueueProvider.java
new file mode 100644
index 0000000..cde27ea
--- /dev/null
+++ b/src/main/java/com/gitblit/guice/WorkQueueProvider.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2014 gitblit.com.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.gitblit.guice;
+
+import com.gitblit.IStoredSettings;
+import com.gitblit.Keys;
+import com.gitblit.manager.IRuntimeManager;
+import com.gitblit.utils.IdGenerator;
+import com.gitblit.utils.WorkQueue;
+import com.google.inject.Inject;
+import com.google.inject.Provider;
+import com.google.inject.Singleton;
+
+/**
+ * Provides a lazily-instantiated WorkQueue configured from IStoredSettings.
+ *
+ * @author James Moger
+ *
+ */
+@Singleton
+public class WorkQueueProvider implements Provider<WorkQueue> {
+
+	private final IRuntimeManager runtimeManager;
+
+	private volatile WorkQueue workQueue;
+
+	@Inject
+	public WorkQueueProvider(IRuntimeManager runtimeManager) {
+		this.runtimeManager = runtimeManager;
+	}
+
+	@Override
+	public synchronized WorkQueue get() {
+		if (workQueue != null) {
+			return workQueue;
+		}
+
+		IStoredSettings settings = runtimeManager.getSettings();
+		int defaultThreadPoolSize = settings.getInteger(Keys.execution.defaultThreadPoolSize, 1);
+		IdGenerator idGenerator = new IdGenerator();
+		workQueue = new WorkQueue(idGenerator, defaultThreadPoolSize);
+		return workQueue;
+	}
+}
\ No newline at end of file
diff --git a/src/main/java/com/gitblit/manager/AuthenticationManager.java b/src/main/java/com/gitblit/manager/AuthenticationManager.java
index d1b1af0..ccf03c0 100644
--- a/src/main/java/com/gitblit/manager/AuthenticationManager.java
+++ b/src/main/java/com/gitblit/manager/AuthenticationManager.java
@@ -53,6 +53,8 @@
 import com.gitblit.utils.StringUtils;
 import com.gitblit.utils.X509Utils.X509Metadata;
 import com.gitblit.wicket.GitBlitWebSession;
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
 
 /**
  * The authentication manager handles user login & logout.
@@ -60,6 +62,7 @@
  * @author James Moger
  *
  */
+@Singleton
 public class AuthenticationManager implements IAuthenticationManager {
 
 	private final Logger logger = LoggerFactory.getLogger(getClass());
@@ -76,6 +79,7 @@
 
 	private final Map<String, String> legacyRedirects;
 
+	@Inject
 	public AuthenticationManager(
 			IRuntimeManager runtimeManager,
 			IUserManager userManager) {
diff --git a/src/main/java/com/gitblit/manager/FederationManager.java b/src/main/java/com/gitblit/manager/FederationManager.java
index 95d38af..f009c1c 100644
--- a/src/main/java/com/gitblit/manager/FederationManager.java
+++ b/src/main/java/com/gitblit/manager/FederationManager.java
@@ -45,6 +45,8 @@
 import com.gitblit.utils.FederationUtils;
 import com.gitblit.utils.JsonUtils;
 import com.gitblit.utils.StringUtils;
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
 
 /**
  * Federation manager controls all aspects of handling federation sets, tokens,
@@ -53,6 +55,7 @@
  * @author James Moger
  *
  */
+@Singleton
 public class FederationManager implements IFederationManager {
 
 	private final Logger logger = LoggerFactory.getLogger(getClass());
@@ -70,6 +73,7 @@
 
 	private final IRepositoryManager repositoryManager;
 
+	@Inject
 	public FederationManager(
 			IRuntimeManager runtimeManager,
 			INotificationManager notificationManager,
diff --git a/src/main/java/com/gitblit/manager/GitblitManager.java b/src/main/java/com/gitblit/manager/GitblitManager.java
index b9ae122..da08127 100644
--- a/src/main/java/com/gitblit/manager/GitblitManager.java
+++ b/src/main/java/com/gitblit/manager/GitblitManager.java
@@ -49,12 +49,10 @@
 
 import com.gitblit.Constants;
 import com.gitblit.Constants.AccessPermission;
-import com.gitblit.Constants.AccessRestrictionType;
 import com.gitblit.Constants.FederationRequest;
 import com.gitblit.Constants.FederationToken;
 import com.gitblit.GitBlitException;
 import com.gitblit.IStoredSettings;
-import com.gitblit.Keys;
 import com.gitblit.models.FederationModel;
 import com.gitblit.models.FederationProposal;
 import com.gitblit.models.FederationSet;
@@ -68,7 +66,6 @@
 import com.gitblit.models.ProjectModel;
 import com.gitblit.models.RegistrantAccessPermission;
 import com.gitblit.models.RepositoryModel;
-import com.gitblit.models.RepositoryUrl;
 import com.gitblit.models.SearchResult;
 import com.gitblit.models.ServerSettings;
 import com.gitblit.models.ServerStatus;
@@ -79,7 +76,6 @@
 import com.gitblit.transport.ssh.IPublicKeyManager;
 import com.gitblit.transport.ssh.SshKey;
 import com.gitblit.utils.ArrayUtils;
-import com.gitblit.utils.HttpUtils;
 import com.gitblit.utils.JsonUtils;
 import com.gitblit.utils.ObjectCache;
 import com.gitblit.utils.StringUtils;
@@ -87,6 +83,10 @@
 import com.google.gson.JsonIOException;
 import com.google.gson.JsonSyntaxException;
 import com.google.gson.reflect.TypeToken;
+import com.google.inject.Inject;
+import com.google.inject.Injector;
+import com.google.inject.Singleton;
+import com.google.inject.Provider;
 
 /**
  * GitblitManager is an aggregate interface delegate.  It implements all the manager
@@ -100,12 +100,17 @@
  * @author James Moger
  *
  */
+@Singleton
 public class GitblitManager implements IGitblit {
 
 	protected final Logger logger = LoggerFactory.getLogger(getClass());
 
 	protected final ObjectCache<Collection<GitClientApplication>> clientApplications = new ObjectCache<Collection<GitClientApplication>>();
 
+	protected final Provider<IPublicKeyManager> publicKeyManagerProvider;
+
+	protected final Provider<ITicketService> ticketServiceProvider;
+
 	protected final IStoredSettings settings;
 
 	protected final IRuntimeManager runtimeManager;
@@ -118,32 +123,34 @@
 
 	protected final IAuthenticationManager authenticationManager;
 
-	protected final IPublicKeyManager publicKeyManager;
-
 	protected final IRepositoryManager repositoryManager;
 
 	protected final IProjectManager projectManager;
 
 	protected final IFederationManager federationManager;
 
+	@Inject
 	public GitblitManager(
+			Provider<IPublicKeyManager> publicKeyManagerProvider,
+			Provider<ITicketService> ticketServiceProvider,
 			IRuntimeManager runtimeManager,
 			IPluginManager pluginManager,
 			INotificationManager notificationManager,
 			IUserManager userManager,
 			IAuthenticationManager authenticationManager,
-			IPublicKeyManager publicKeyManager,
 			IRepositoryManager repositoryManager,
 			IProjectManager projectManager,
 			IFederationManager federationManager) {
 
+		this.publicKeyManagerProvider = publicKeyManagerProvider;
+		this.ticketServiceProvider = ticketServiceProvider;
+
 		this.settings = runtimeManager.getSettings();
 		this.runtimeManager = runtimeManager;
 		this.pluginManager = pluginManager;
 		this.notificationManager = notificationManager;
 		this.userManager = userManager;
 		this.authenticationManager = authenticationManager;
-		this.publicKeyManager = publicKeyManager;
 		this.repositoryManager = repositoryManager;
 		this.projectManager = projectManager;
 		this.federationManager = federationManager;
@@ -357,66 +364,6 @@
 	}
 
 	/**
-	 * Returns a list of repository URLs and the user access permission.
-	 *
-	 * @param request
-	 * @param user
-	 * @param repository
-	 * @return a list of repository urls
-	 */
-	@Override
-	public List<RepositoryUrl> getRepositoryUrls(HttpServletRequest request, UserModel user, RepositoryModel repository) {
-		if (user == null) {
-			user = UserModel.ANONYMOUS;
-		}
-		String username = StringUtils.encodeUsername(UserModel.ANONYMOUS.equals(user) ? "" : user.username);
-
-		List<RepositoryUrl> list = new ArrayList<RepositoryUrl>();
-		// http/https url
-		if (settings.getBoolean(Keys.git.enableGitServlet, true)) {
-			AccessPermission permission = user.getRepositoryPermission(repository).permission;
-			if (permission.exceeds(AccessPermission.NONE)) {
-				list.add(new RepositoryUrl(getRepositoryUrl(request, username, repository), permission));
-			}
-		}
-
-		// add all other urls
-		// {0} = repository
-		// {1} = username
-		for (String url : settings.getStrings(Keys.web.otherUrls)) {
-			if (url.contains("{1}")) {
-				// external url requires username, only add url IF we have one
-				if (!StringUtils.isEmpty(username)) {
-					list.add(new RepositoryUrl(MessageFormat.format(url, repository.name, username), null));
-				}
-			} else {
-				// external url does not require username
-				list.add(new RepositoryUrl(MessageFormat.format(url, repository.name), null));
-			}
-		}
-		return list;
-	}
-
-	protected String getRepositoryUrl(HttpServletRequest request, String username, RepositoryModel repository) {
-		String gitblitUrl = settings.getString(Keys.web.canonicalUrl, null);
-		if (StringUtils.isEmpty(gitblitUrl)) {
-			gitblitUrl = HttpUtils.getGitblitURL(request);
-		}
-		StringBuilder sb = new StringBuilder();
-		sb.append(gitblitUrl);
-		sb.append(Constants.R_PATH);
-		sb.append(repository.name);
-
-		// inject username into repository url if authentication is required
-		if (repository.accessRestriction.exceeds(AccessRestrictionType.NONE)
-				&& !StringUtils.isEmpty(username)) {
-			sb.insert(sb.indexOf("://") + 3, username + "@");
-		}
-		return sb.toString();
-	}
-
-
-	/**
 	 * Returns the list of custom client applications to be used for the
 	 * repository url panel;
 	 *
@@ -542,18 +489,14 @@
 		}
 	}
 
-	/**
-	 * Throws an exception if trying to get a ticket service.
-	 *
-	 */
 	@Override
 	public ITicketService getTicketService() {
-		throw new RuntimeException("This class does not have a ticket service!");
+		return ticketServiceProvider.get();
 	}
 
 	@Override
 	public IPublicKeyManager getPublicKeyManager() {
-		return publicKeyManager;
+		return publicKeyManagerProvider.get();
 	}
 
 	/*
@@ -604,26 +547,6 @@
 	}
 
 	@Override
-	public boolean isServingRepositories() {
-		return runtimeManager.isServingRepositories();
-	}
-
-	@Override
-	public boolean isServingHTTP() {
-		return runtimeManager.isServingHTTP();
-	}
-
-	@Override
-	public boolean isServingGIT() {
-		return runtimeManager.isServingGIT();
-	}
-
-	@Override
-	public boolean isServingSSH() {
-		return runtimeManager.isServingSSH();
-	}
-
-	@Override
 	public TimeZone getTimezone() {
 		return runtimeManager.getTimezone();
 	}
@@ -663,6 +586,11 @@
 		return runtimeManager.getStatus();
 	}
 
+	@Override
+	public Injector getInjector() {
+		return runtimeManager.getInjector();
+	}
+
 	/*
 	 * NOTIFICATION MANAGER
 	 */
@@ -788,11 +716,6 @@
 	}
 
 	@Override
-	public boolean deleteUser(String username) {
-		return userManager.deleteUser(username);
-	}
-
-	@Override
 	public UserModel getUserModel(String username) {
 		return userManager.getUserModel(username);
 	}
@@ -833,8 +756,22 @@
 	}
 
 	@Override
+	public boolean deleteUser(String username) {
+		// delegate to deleteUserModel() to delete public ssh keys
+		UserModel user = userManager.getUserModel(username);
+		return deleteUserModel(user);
+	}
+
+	/**
+	 * Delete the user and all associated public ssh keys.
+	 */
+	@Override
 	public boolean deleteUserModel(UserModel model) {
-		return userManager.deleteUserModel(model);
+		boolean success = userManager.deleteUserModel(model);
+		if (success) {
+			getPublicKeyManager().removeAllKeys(model.username);
+		}
+		return success;
 	}
 
 	@Override
@@ -1030,10 +967,23 @@
 		return repositoryManager.getRepositoryDefaultMetrics(model, repository);
 	}
 
+	/**
+	 * Detect renames and reindex as appropriate.
+	 */
 	@Override
 	public void updateRepositoryModel(String repositoryName, RepositoryModel repository,
 			boolean isCreate) throws GitBlitException {
+		RepositoryModel oldModel = null;
+		boolean isRename = !isCreate && !repositoryName.equalsIgnoreCase(repository.name);
+		if (isRename) {
+			oldModel = repositoryManager.getRepositoryModel(repositoryName);
+		}
+
 		repositoryManager.updateRepositoryModel(repositoryName, repository, isCreate);
+
+		if (isRename && ticketServiceProvider.get() != null) {
+			ticketServiceProvider.get().rename(oldModel, repository);
+		}
 	}
 
 	@Override
@@ -1046,14 +996,23 @@
 		return repositoryManager.canDelete(model);
 	}
 
+	/**
+	 * Delete the repository and all associated tickets.
+	 */
 	@Override
 	public boolean deleteRepositoryModel(RepositoryModel model) {
-		return repositoryManager.deleteRepositoryModel(model);
+		boolean success = repositoryManager.deleteRepositoryModel(model);
+		if (success && ticketServiceProvider.get() != null) {
+			ticketServiceProvider.get().deleteAll(model);
+		}
+		return success;
 	}
 
 	@Override
 	public boolean deleteRepository(String repositoryName) {
-		return repositoryManager.deleteRepository(repositoryName);
+		// delegate to deleteRepositoryModel() to destroy indexed tickets
+		RepositoryModel repository = repositoryManager.getRepositoryModel(repositoryName);
+		return deleteRepositoryModel(repository);
 	}
 
 	@Override
diff --git a/src/main/java/com/gitblit/manager/IGitblit.java b/src/main/java/com/gitblit/manager/IGitblit.java
index 50ec8b1..6c5b374 100644
--- a/src/main/java/com/gitblit/manager/IGitblit.java
+++ b/src/main/java/com/gitblit/manager/IGitblit.java
@@ -16,14 +16,10 @@
 package com.gitblit.manager;
 
 import java.util.Collection;
-import java.util.List;
-
-import javax.servlet.http.HttpServletRequest;
 
 import com.gitblit.GitBlitException;
 import com.gitblit.models.GitClientApplication;
 import com.gitblit.models.RepositoryModel;
-import com.gitblit.models.RepositoryUrl;
 import com.gitblit.models.TeamModel;
 import com.gitblit.models.UserModel;
 import com.gitblit.tickets.ITicketService;
@@ -40,17 +36,6 @@
 									IFederationManager {
 
 	/**
-	 * Returns a list of repository URLs and the user access permission.
-	 *
-	 * @param request
-	 * @param user
-	 * @param repository
-	 * @return a list of repository urls
-	 * @since 1.4.0
-	 */
-	List<RepositoryUrl> getRepositoryUrls(HttpServletRequest request, UserModel user, RepositoryModel repository);
-
-	/**
 	 * Creates a complete user object.
 	 *
 	 * @param user
diff --git a/src/main/java/com/gitblit/manager/IRuntimeManager.java b/src/main/java/com/gitblit/manager/IRuntimeManager.java
index b2d7a2b..8322d34 100644
--- a/src/main/java/com/gitblit/manager/IRuntimeManager.java
+++ b/src/main/java/com/gitblit/manager/IRuntimeManager.java
@@ -24,9 +24,12 @@
 import com.gitblit.IStoredSettings;
 import com.gitblit.models.ServerSettings;
 import com.gitblit.models.ServerStatus;
+import com.google.inject.Injector;
 
 public interface IRuntimeManager extends IManager {
 
+	Injector getInjector();
+
 	void setBaseFolder(File folder);
 
 	File getBaseFolder();
@@ -48,42 +51,6 @@
 	Locale getLocale();
 
 	/**
-	 * Determine if this Gitblit instance is actively serving git repositories
-	 * or if it is merely a repository viewer.
-	 *
-	 * @return true if Gitblit is serving repositories
- 	 * @since 1.4.0
-	 */
-	boolean isServingRepositories();
-
-	/**
-	 * Determine if this Gitblit instance is actively serving git repositories
-	 * over HTTP.
-	 *
-	 * @return true if Gitblit is serving repositories over HTTP
- 	 * @since 1.6.0
-	 */
-	boolean isServingHTTP();
-
-	/**
-	 * Determine if this Gitblit instance is actively serving git repositories
-	 * over the GIT Daemon protocol.
-	 *
-	 * @return true if Gitblit is serving repositories over the GIT Daemon protocol
- 	 * @since 1.6.0
-	 */
-	boolean isServingGIT();
-
-	/**
-	 * Determine if this Gitblit instance is actively serving git repositories
-	 * over the SSH protocol.
-	 *
-	 * @return true if Gitblit is serving repositories over the SSH protocol
- 	 * @since 1.6.0
-	 */
-	boolean isServingSSH();
-
-	/**
 	 * Determine if this Gitblit instance is running in debug mode
 	 *
 	 * @return true if Gitblit is running in debug mode
diff --git a/src/main/java/com/gitblit/manager/IServicesManager.java b/src/main/java/com/gitblit/manager/IServicesManager.java
new file mode 100644
index 0000000..5bb135d
--- /dev/null
+++ b/src/main/java/com/gitblit/manager/IServicesManager.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2014 gitblit.com.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.gitblit.manager;
+
+import java.util.List;
+
+import javax.servlet.http.HttpServletRequest;
+
+import com.gitblit.models.RepositoryModel;
+import com.gitblit.models.RepositoryUrl;
+import com.gitblit.models.UserModel;
+
+public interface IServicesManager extends IManager {
+
+	/**
+	 * Determine if this Gitblit instance is actively serving git repositories
+	 * or if it is merely a repository viewer.
+	 *
+	 * @return true if Gitblit is serving repositories
+ 	 * @since 1.7.0
+	 */
+	boolean isServingRepositories();
+
+	/**
+	 * Determine if this Gitblit instance is actively serving git repositories
+	 * over HTTP.
+	 *
+	 * @return true if Gitblit is serving repositories over HTTP
+ 	 * @since 1.7.0
+	 */
+	boolean isServingHTTP();
+
+	/**
+	 * Determine if this Gitblit instance is actively serving git repositories
+	 * over the GIT Daemon protocol.
+	 *
+	 * @return true if Gitblit is serving repositories over the GIT Daemon protocol
+ 	 * @since 1.7.0
+	 */
+	boolean isServingGIT();
+
+	/**
+	 * Determine if this Gitblit instance is actively serving git repositories
+	 * over the SSH protocol.
+	 *
+	 * @return true if Gitblit is serving repositories over the SSH protocol
+ 	 * @since 1.7.0
+	 */
+	boolean isServingSSH();
+
+	/**
+	 * Returns a list of repository URLs and the user access permission.
+	 *
+	 * @param request
+	 * @param user
+	 * @param repository
+	 * @return a list of repository urls
+	 * @since 1.7.0
+	 */
+	List<RepositoryUrl> getRepositoryUrls(HttpServletRequest request, UserModel user, RepositoryModel repository);
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/gitblit/manager/NotificationManager.java b/src/main/java/com/gitblit/manager/NotificationManager.java
index 69a611b..4bbc2ab 100644
--- a/src/main/java/com/gitblit/manager/NotificationManager.java
+++ b/src/main/java/com/gitblit/manager/NotificationManager.java
@@ -29,6 +29,8 @@
 import com.gitblit.Keys;
 import com.gitblit.models.Mailing;
 import com.gitblit.service.MailService;
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
 
 /**
  * The notification manager dispatches notifications.  Currently, email is the
@@ -38,6 +40,7 @@
  * @author James Moger
  *
  */
+@Singleton
 public class NotificationManager implements INotificationManager {
 
 	private final Logger logger = LoggerFactory.getLogger(getClass());
@@ -48,6 +51,7 @@
 
 	private final MailService mailService;
 
+	@Inject
 	public NotificationManager(IStoredSettings settings) {
 		this.settings = settings;
 		this.mailService = new MailService(settings);
diff --git a/src/main/java/com/gitblit/manager/PluginManager.java b/src/main/java/com/gitblit/manager/PluginManager.java
index 2ee4855..5830375 100644
--- a/src/main/java/com/gitblit/manager/PluginManager.java
+++ b/src/main/java/com/gitblit/manager/PluginManager.java
@@ -37,8 +37,12 @@
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import ro.fortsoft.pf4j.DefaultPluginFactory;
 import ro.fortsoft.pf4j.DefaultPluginManager;
+import ro.fortsoft.pf4j.ExtensionFactory;
+import ro.fortsoft.pf4j.Plugin;
 import ro.fortsoft.pf4j.PluginClassLoader;
+import ro.fortsoft.pf4j.PluginFactory;
 import ro.fortsoft.pf4j.PluginState;
 import ro.fortsoft.pf4j.PluginStateEvent;
 import ro.fortsoft.pf4j.PluginStateListener;
@@ -58,6 +62,8 @@
 import com.gitblit.utils.StringUtils;
 import com.google.common.io.Files;
 import com.google.common.io.InputSupplier;
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
 
 /**
  * The plugin manager maintains the lifecycle of plugins. It is exposed as
@@ -68,32 +74,23 @@
  * @author James Moger
  *
  */
+@Singleton
 public class PluginManager implements IPluginManager, PluginStateListener {
 
 	private final Logger logger = LoggerFactory.getLogger(getClass());
 
-	private final DefaultPluginManager pf4j;
-
 	private final IRuntimeManager runtimeManager;
 
+	private DefaultPluginManager pf4j;
+
 	// timeout defaults of Maven 3.0.4 in seconds
 	private int connectTimeout = 20;
 
 	private int readTimeout = 12800;
 
+	@Inject
 	public PluginManager(IRuntimeManager runtimeManager) {
-		File dir = runtimeManager.getFileOrFolder(Keys.plugins.folder, "${baseFolder}/plugins");
-		dir.mkdirs();
 		this.runtimeManager = runtimeManager;
-
-		this.pf4j = new DefaultPluginManager(dir);
-
-		try {
-			Version systemVersion = Version.createVersion(Constants.getVersion());
-			pf4j.setSystemVersion(systemVersion);
-		} catch (Exception e) {
-			logger.error(null, e);
-		}
 	}
 
 	@Override
@@ -108,6 +105,28 @@
 
 	@Override
 	public PluginManager start() {
+		File dir = runtimeManager.getFileOrFolder(Keys.plugins.folder, "${baseFolder}/plugins");
+		dir.mkdirs();
+
+		pf4j = new DefaultPluginManager(dir) {
+
+			@Override
+			protected PluginFactory createPluginFactory() {
+				return new GuicePluginFactory();
+			}
+
+			@Override
+			protected ExtensionFactory createExtensionFactory() {
+				return new GuiceExtensionFactory();
+			}
+		};
+
+		try {
+			Version systemVersion = Version.createVersion(Constants.getVersion());
+			pf4j.setSystemVersion(systemVersion);
+		} catch (Exception e) {
+			logger.error(null, e);
+		}
 		pf4j.loadPlugins();
 		logger.debug("Starting plugins");
 		pf4j.startPlugins();
@@ -569,4 +588,41 @@
 	protected String getProxyAuthorization(URL url) {
 		return "";
 	}
+
+	/**
+	 * Instantiates a plugin using pf4j but injects member fields
+	 * with Guice.
+	 */
+	private class GuicePluginFactory extends DefaultPluginFactory {
+
+		@Override
+		public Plugin create(PluginWrapper pluginWrapper) {
+			// use pf4j to create the plugin
+			Plugin plugin = super.create(pluginWrapper);
+
+			if (plugin != null) {
+				// allow Guice to inject member fields
+				runtimeManager.getInjector().injectMembers(plugin);
+			}
+
+			return plugin;
+		}
+	}
+
+	/**
+	 * Instantiates an extension using Guice.
+	 */
+	private class GuiceExtensionFactory implements ExtensionFactory {
+		@Override
+		public Object create(Class<?> extensionClass) {
+			// instantiate && inject the extension
+			logger.debug("Create instance for extension '{}'", extensionClass.getName());
+			try {
+				return runtimeManager.getInjector().getInstance(extensionClass);
+			} catch (Exception e) {
+				logger.error(e.getMessage(), e);
+			}
+			return null;
+		}
+	}
 }
diff --git a/src/main/java/com/gitblit/manager/ProjectManager.java b/src/main/java/com/gitblit/manager/ProjectManager.java
index 666f521..ae46bdf 100644
--- a/src/main/java/com/gitblit/manager/ProjectManager.java
+++ b/src/main/java/com/gitblit/manager/ProjectManager.java
@@ -41,6 +41,8 @@
 import com.gitblit.utils.ModelUtils;
 import com.gitblit.utils.ObjectCache;
 import com.gitblit.utils.StringUtils;
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
 
 /**
  * Project manager handles project-related functions.
@@ -48,6 +50,7 @@
  * @author James Moger
  *
  */
+@Singleton
 public class ProjectManager implements IProjectManager {
 
 	private final Logger logger = LoggerFactory.getLogger(getClass());
@@ -68,6 +71,7 @@
 
 	private FileBasedConfig projectConfigs;
 
+	@Inject
 	public ProjectManager(
 			IRuntimeManager runtimeManager,
 			IUserManager userManager,
diff --git a/src/main/java/com/gitblit/manager/RepositoryManager.java b/src/main/java/com/gitblit/manager/RepositoryManager.java
index a8b2323..6a22db5 100644
--- a/src/main/java/com/gitblit/manager/RepositoryManager.java
+++ b/src/main/java/com/gitblit/manager/RepositoryManager.java
@@ -91,6 +91,8 @@
 import com.gitblit.utils.ObjectCache;
 import com.gitblit.utils.StringUtils;
 import com.gitblit.utils.TimeUtils;
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
 
 /**
  * Repository manager creates, updates, deletes and caches git repositories.  It
@@ -99,6 +101,7 @@
  * @author James Moger
  *
  */
+@Singleton
 public class RepositoryManager implements IRepositoryManager {
 
 	private final Logger logger = LoggerFactory.getLogger(getClass());
@@ -121,7 +124,7 @@
 
 	private final IUserManager userManager;
 
-	private final File repositoriesFolder;
+	private File repositoriesFolder;
 
 	private LuceneService luceneExecutor;
 
@@ -129,6 +132,7 @@
 
 	private MirrorService mirrorExecutor;
 
+	@Inject
 	public RepositoryManager(
 			IRuntimeManager runtimeManager,
 			IPluginManager pluginManager,
@@ -138,11 +142,11 @@
 		this.runtimeManager = runtimeManager;
 		this.pluginManager = pluginManager;
 		this.userManager = userManager;
-		this.repositoriesFolder = runtimeManager.getFileOrFolder(Keys.git.repositoriesFolder, "${baseFolder}/git");
 	}
 
 	@Override
 	public RepositoryManager start() {
+		repositoriesFolder = runtimeManager.getFileOrFolder(Keys.git.repositoriesFolder, "${baseFolder}/git");
 		logger.info("Repositories folder : {}", repositoriesFolder.getAbsolutePath());
 
 		// initialize utilities
@@ -1948,21 +1952,19 @@
 	}
 
 	protected void confirmWriteAccess() {
-		if (runtimeManager.isServingRepositories()) {
-			try {
-				if (!getRepositoriesFolder().exists()) {
-					getRepositoriesFolder().mkdirs();
-				}
-				File file = File.createTempFile(".test-", ".txt", getRepositoriesFolder());
-				file.delete();
-			} catch (Exception e) {
-				logger.error("");
-				logger.error(Constants.BORDER2);
-				logger.error("Please check filesystem permissions!");
-				logger.error("FAILED TO WRITE TO REPOSITORIES FOLDER!!", e);
-				logger.error(Constants.BORDER2);
-				logger.error("");
+		try {
+			if (!getRepositoriesFolder().exists()) {
+				getRepositoriesFolder().mkdirs();
 			}
+			File file = File.createTempFile(".test-", ".txt", getRepositoriesFolder());
+			file.delete();
+		} catch (Exception e) {
+			logger.error("");
+			logger.error(Constants.BORDER2);
+			logger.error("Please check filesystem permissions!");
+			logger.error("FAILED TO WRITE TO REPOSITORIES FOLDER!!", e);
+			logger.error(Constants.BORDER2);
+			logger.error("");
 		}
 	}
 }
diff --git a/src/main/java/com/gitblit/manager/RuntimeManager.java b/src/main/java/com/gitblit/manager/RuntimeManager.java
index 9cdc64e..95a363f 100644
--- a/src/main/java/com/gitblit/manager/RuntimeManager.java
+++ b/src/main/java/com/gitblit/manager/RuntimeManager.java
@@ -32,7 +32,11 @@
 import com.gitblit.models.ServerStatus;
 import com.gitblit.models.SettingModel;
 import com.gitblit.utils.StringUtils;
+import com.google.inject.Inject;
+import com.google.inject.Injector;
+import com.google.inject.Singleton;
 
+@Singleton
 public class RuntimeManager implements IRuntimeManager {
 
 	private final Logger logger = LoggerFactory.getLogger(getClass());
@@ -47,6 +51,10 @@
 
 	private TimeZone timezone;
 
+	@Inject
+	private Injector injector;
+
+	@Inject
 	public RuntimeManager(IStoredSettings settings) {
 		this(settings, null);
 	}
@@ -75,6 +83,11 @@
 	}
 
 	@Override
+	public Injector getInjector() {
+		return injector;
+	}
+
+	@Override
 	public File getBaseFolder() {
 		return baseFolder;
 	}
@@ -112,52 +125,6 @@
 	}
 
 	/**
-	 * Determine if this Gitblit instance is actively serving git repositories
-	 * or if it is merely a repository viewer.
-	 *
-	 * @return true if Gitblit is serving repositories
-	 */
-	@Override
-	public boolean isServingRepositories() {
-		return isServingHTTP()
-				|| isServingGIT()
-				|| isServingSSH();
-	}
-
-	/**
-	 * Determine if this Gitblit instance is actively serving git repositories
-	 * over the HTTP protocol.
-	 *
-	 * @return true if Gitblit is serving repositories over the HTTP protocol
-	 */
-	@Override
-	public boolean isServingHTTP() {
-		return settings.getBoolean(Keys.git.enableGitServlet, true);
-	}
-
-	/**
-	 * Determine if this Gitblit instance is actively serving git repositories
-	 * over the Git Daemon protocol.
-	 *
-	 * @return true if Gitblit is serving repositories over the Git Daemon protocol
-	 */
-	@Override
-	public boolean isServingGIT() {
-		return settings.getInteger(Keys.git.daemonPort, 0) > 0;
-	}
-
-	/**
-	 * Determine if this Gitblit instance is actively serving git repositories
-	 * over the SSH protocol.
-	 *
-	 * @return true if Gitblit is serving repositories over the SSH protocol
-	 */
-	@Override
-	public boolean isServingSSH() {
-		return settings.getInteger(Keys.git.sshPort, 0) > 0;
-	}
-
-	/**
 	 * Returns the preferred timezone for the Gitblit instance.
 	 *
 	 * @return a timezone
diff --git a/src/main/java/com/gitblit/manager/ServicesManager.java b/src/main/java/com/gitblit/manager/ServicesManager.java
index 3721578..2550f66 100644
--- a/src/main/java/com/gitblit/manager/ServicesManager.java
+++ b/src/main/java/com/gitblit/manager/ServicesManager.java
@@ -18,9 +18,15 @@
 import java.io.IOException;
 import java.net.URI;
 import java.text.MessageFormat;
+import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
 import java.util.Date;
+import java.util.HashSet;
+import java.util.Iterator;
 import java.util.List;
+import java.util.Set;
 import java.util.concurrent.Executors;
 import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.TimeUnit;
@@ -30,9 +36,11 @@
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.gitblit.Constants;
 import com.gitblit.Constants.AccessPermission;
 import com.gitblit.Constants.AccessRestrictionType;
 import com.gitblit.Constants.FederationToken;
+import com.gitblit.Constants.Transport;
 import com.gitblit.IStoredSettings;
 import com.gitblit.Keys;
 import com.gitblit.fanout.FanoutNioService;
@@ -40,14 +48,18 @@
 import com.gitblit.fanout.FanoutSocketService;
 import com.gitblit.models.FederationModel;
 import com.gitblit.models.RepositoryModel;
+import com.gitblit.models.RepositoryUrl;
 import com.gitblit.models.UserModel;
 import com.gitblit.service.FederationPullService;
 import com.gitblit.transport.git.GitDaemon;
 import com.gitblit.transport.ssh.SshDaemon;
-import com.gitblit.utils.IdGenerator;
+import com.gitblit.utils.HttpUtils;
 import com.gitblit.utils.StringUtils;
 import com.gitblit.utils.TimeUtils;
 import com.gitblit.utils.WorkQueue;
+import com.google.inject.Inject;
+import com.google.inject.Provider;
+import com.google.inject.Singleton;
 
 /**
  * Services manager manages long-running services/processes that either have no
@@ -57,32 +69,35 @@
  * @author James Moger
  *
  */
-public class ServicesManager implements IManager {
+@Singleton
+public class ServicesManager implements IServicesManager {
 
 	private final Logger logger = LoggerFactory.getLogger(getClass());
 
 	private final ScheduledExecutorService scheduledExecutor = Executors.newScheduledThreadPool(5);
 
+	private final Provider<WorkQueue> workQueueProvider;
+
 	private final IStoredSettings settings;
 
 	private final IGitblit gitblit;
 
-	private final IdGenerator idGenerator;
-
-	private final WorkQueue workQueue;
-
 	private FanoutService fanoutService;
 
 	private GitDaemon gitDaemon;
 
 	private SshDaemon sshDaemon;
 
-	public ServicesManager(IGitblit gitblit) {
-		this.settings = gitblit.getSettings();
+	@Inject
+	public ServicesManager(
+			Provider<WorkQueue> workQueueProvider,
+			IStoredSettings settings,
+			IGitblit gitblit) {
+
+		this.workQueueProvider = workQueueProvider;
+
+		this.settings = settings;
 		this.gitblit = gitblit;
-		int defaultThreadPoolSize = settings.getInteger(Keys.execution.defaultThreadPoolSize, 1);
-		this.idGenerator = new IdGenerator();
-		this.workQueue = new WorkQueue(idGenerator, defaultThreadPoolSize);
 	}
 
 	@Override
@@ -107,24 +122,181 @@
 		if (sshDaemon != null) {
 			sshDaemon.stop();
 		}
-		workQueue.stop();
+		workQueueProvider.get().stop();
 		return this;
 	}
 
+	protected String getRepositoryUrl(HttpServletRequest request, String username, RepositoryModel repository) {
+		String gitblitUrl = settings.getString(Keys.web.canonicalUrl, null);
+		if (StringUtils.isEmpty(gitblitUrl)) {
+			gitblitUrl = HttpUtils.getGitblitURL(request);
+		}
+		StringBuilder sb = new StringBuilder();
+		sb.append(gitblitUrl);
+		sb.append(Constants.R_PATH);
+		sb.append(repository.name);
+
+		// inject username into repository url if authentication is required
+		if (repository.accessRestriction.exceeds(AccessRestrictionType.NONE)
+				&& !StringUtils.isEmpty(username)) {
+			sb.insert(sb.indexOf("://") + 3, username + "@");
+		}
+		return sb.toString();
+	}
+
+	/**
+	 * Returns a list of repository URLs and the user access permission.
+	 *
+	 * @param request
+	 * @param user
+	 * @param repository
+	 * @return a list of repository urls
+	 */
+	@Override
+	public List<RepositoryUrl> getRepositoryUrls(HttpServletRequest request, UserModel user, RepositoryModel repository) {
+		if (user == null) {
+			user = UserModel.ANONYMOUS;
+		}
+		String username = StringUtils.encodeUsername(UserModel.ANONYMOUS.equals(user) ? "" : user.username);
+
+		List<RepositoryUrl> list = new ArrayList<RepositoryUrl>();
+
+		// http/https url
+		if (settings.getBoolean(Keys.git.enableGitServlet, true)) {
+			AccessPermission permission = user.getRepositoryPermission(repository).permission;
+			if (permission.exceeds(AccessPermission.NONE)) {
+				Transport transport = Transport.fromString(request.getScheme());
+				if (permission.atLeast(AccessPermission.PUSH) && !acceptPush(transport)) {
+					// downgrade the repo permission for this transport
+					// because it is not an acceptable PUSH transport
+					permission = AccessPermission.CLONE;
+				}
+				list.add(new RepositoryUrl(getRepositoryUrl(request, username, repository), permission));
+			}
+		}
+
+		// ssh daemon url
+		String sshDaemonUrl = getSshDaemonUrl(request, user, repository);
+		if (!StringUtils.isEmpty(sshDaemonUrl)) {
+			AccessPermission permission = user.getRepositoryPermission(repository).permission;
+			if (permission.exceeds(AccessPermission.NONE)) {
+				if (permission.atLeast(AccessPermission.PUSH) && !acceptPush(Transport.SSH)) {
+					// downgrade the repo permission for this transport
+					// because it is not an acceptable PUSH transport
+					permission = AccessPermission.CLONE;
+				}
+
+				list.add(new RepositoryUrl(sshDaemonUrl, permission));
+			}
+		}
+
+		// git daemon url
+		String gitDaemonUrl = getGitDaemonUrl(request, user, repository);
+		if (!StringUtils.isEmpty(gitDaemonUrl)) {
+			AccessPermission permission = getGitDaemonAccessPermission(user, repository);
+			if (permission.exceeds(AccessPermission.NONE)) {
+				if (permission.atLeast(AccessPermission.PUSH) && !acceptPush(Transport.GIT)) {
+					// downgrade the repo permission for this transport
+					// because it is not an acceptable PUSH transport
+					permission = AccessPermission.CLONE;
+				}
+				list.add(new RepositoryUrl(gitDaemonUrl, permission));
+			}
+		}
+
+		// add all other urls
+		// {0} = repository
+		// {1} = username
+		for (String url : settings.getStrings(Keys.web.otherUrls)) {
+			if (url.contains("{1}")) {
+				// external url requires username, only add url IF we have one
+				if (!StringUtils.isEmpty(username)) {
+					list.add(new RepositoryUrl(MessageFormat.format(url, repository.name, username), null));
+				}
+			} else {
+				// external url does not require username
+				list.add(new RepositoryUrl(MessageFormat.format(url, repository.name), null));
+			}
+		}
+
+		// sort transports by highest permission and then by transport security
+		Collections.sort(list, new Comparator<RepositoryUrl>() {
+
+			@Override
+			public int compare(RepositoryUrl o1, RepositoryUrl o2) {
+				if (!o1.isExternal() && o2.isExternal()) {
+					// prefer Gitblit over external
+					return -1;
+				} else if (o1.isExternal() && !o2.isExternal()) {
+					// prefer Gitblit over external
+					return 1;
+				} else if (o1.isExternal() && o2.isExternal()) {
+					// sort by Transport ordinal
+					return o1.transport.compareTo(o2.transport);
+				} else if (o1.permission.exceeds(o2.permission)) {
+					// prefer highest permission
+					return -1;
+				} else if (o2.permission.exceeds(o1.permission)) {
+					// prefer highest permission
+					return 1;
+				}
+
+				// prefer more secure transports
+				return o1.transport.compareTo(o2.transport);
+			}
+		});
+
+		// consider the user's transport preference
+		RepositoryUrl preferredUrl = null;
+		Transport preferredTransport = user.getPreferences().getTransport();
+		if (preferredTransport != null) {
+			Iterator<RepositoryUrl> itr = list.iterator();
+			while (itr.hasNext()) {
+				RepositoryUrl url = itr.next();
+				if (url.transport.equals(preferredTransport)) {
+					itr.remove();
+					preferredUrl = url;
+					break;
+				}
+			}
+		}
+		if (preferredUrl != null) {
+			list.add(0, preferredUrl);
+		}
+
+		return list;
+	}
+
+	/* (non-Javadoc)
+	 * @see com.gitblit.manager.IServicesManager#isServingRepositories()
+	 */
+	@Override
 	public boolean isServingRepositories() {
 		return isServingHTTP()
 				|| isServingGIT()
 				|| isServingSSH();
 	}
 
+	/* (non-Javadoc)
+	 * @see com.gitblit.manager.IServicesManager#isServingHTTP()
+	 */
+	@Override
 	public boolean isServingHTTP() {
 		return settings.getBoolean(Keys.git.enableGitServlet, true);
 	}
 
+	/* (non-Javadoc)
+	 * @see com.gitblit.manager.IServicesManager#isServingGIT()
+	 */
+	@Override
 	public boolean isServingGIT() {
 		return gitDaemon != null && gitDaemon.isRunning();
 	}
 
+	/* (non-Javadoc)
+	 * @see com.gitblit.manager.IServicesManager#isServingSSH()
+	 */
+	@Override
 	public boolean isServingSSH() {
 		return sshDaemon != null && sshDaemon.isRunning();
 	}
@@ -158,6 +330,32 @@
 		}
 	}
 
+	protected boolean acceptPush(Transport byTransport) {
+		if (byTransport == null) {
+			logger.info("Unknown transport, push rejected!");
+			return false;
+		}
+
+		Set<Transport> transports = new HashSet<Transport>();
+		for (String value : settings.getStrings(Keys.git.acceptedPushTransports)) {
+			Transport transport = Transport.fromString(value);
+			if (transport == null) {
+				logger.info(String.format("Ignoring unknown registered transport %s", value));
+				continue;
+			}
+
+			transports.add(transport);
+		}
+
+		if (transports.isEmpty()) {
+			// no transports are explicitly specified, all are acceptable
+			return true;
+		}
+
+		// verify that the transport is permitted
+		return transports.contains(byTransport);
+	}
+
 	protected void configureGitDaemon() {
 		int port = settings.getInteger(Keys.git.daemonPort, 0);
 		String bindInterface = settings.getString(Keys.git.daemonBindInterface, "localhost");
@@ -179,7 +377,7 @@
 		String bindInterface = settings.getString(Keys.git.sshBindInterface, "localhost");
 		if (port > 0) {
 			try {
-				sshDaemon = new SshDaemon(gitblit, workQueue);
+				sshDaemon = new SshDaemon(gitblit, workQueueProvider.get());
 				sshDaemon.start();
 			} catch (IOException e) {
 				sshDaemon = null;
@@ -285,7 +483,7 @@
 	 */
 	protected String getHostname(HttpServletRequest request) {
 		String hostname = request.getServerName();
-		String canonicalUrl = gitblit.getSettings().getString(Keys.web.canonicalUrl, null);
+		String canonicalUrl = settings.getString(Keys.web.canonicalUrl, null);
 		if (!StringUtils.isEmpty(canonicalUrl)) {
 			try {
 				URI uri = new URI(canonicalUrl);
diff --git a/src/main/java/com/gitblit/manager/UserManager.java b/src/main/java/com/gitblit/manager/UserManager.java
index 2b82ffb..86be8bc 100644
--- a/src/main/java/com/gitblit/manager/UserManager.java
+++ b/src/main/java/com/gitblit/manager/UserManager.java
@@ -36,6 +36,8 @@
 import com.gitblit.models.TeamModel;
 import com.gitblit.models.UserModel;
 import com.gitblit.utils.StringUtils;
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
 
 /**
  * The user manager manages persistence and retrieval of users and teams.
@@ -43,6 +45,7 @@
  * @author James Moger
  *
  */
+@Singleton
 public class UserManager implements IUserManager {
 
 	private final Logger logger = LoggerFactory.getLogger(getClass());
@@ -57,6 +60,7 @@
 
 	private IUserService userService;
 
+	@Inject
 	public UserManager(IRuntimeManager runtimeManager, IPluginManager pluginManager) {
 		this.settings = runtimeManager.getSettings();
 		this.runtimeManager = runtimeManager;
diff --git a/src/main/java/com/gitblit/service/LuceneService.java b/src/main/java/com/gitblit/service/LuceneService.java
index 482be5c..3f7635f 100644
--- a/src/main/java/com/gitblit/service/LuceneService.java
+++ b/src/main/java/com/gitblit/service/LuceneService.java
@@ -105,7 +105,7 @@
 public class LuceneService implements Runnable {

 

 

-	private static final int INDEX_VERSION = 5;

+	private static final int INDEX_VERSION = 6;

 

 	private static final String FIELD_OBJECT_TYPE = "type";

 	private static final String FIELD_PATH = "path";

@@ -125,7 +125,7 @@
 	private static final String CONF_ALIAS = "aliases";

 	private static final String CONF_BRANCH = "branches";

 

-	private static final Version LUCENE_VERSION = Version.LUCENE_46;

+	private static final Version LUCENE_VERSION = Version.LUCENE_4_10_0;

 

 	private final Logger logger = LoggerFactory.getLogger(LuceneService.class);

 

diff --git a/src/main/java/com/gitblit/servlet/AccessRestrictionFilter.java b/src/main/java/com/gitblit/servlet/AccessRestrictionFilter.java
index 0e6d323..6d2efa4 100644
--- a/src/main/java/com/gitblit/servlet/AccessRestrictionFilter.java
+++ b/src/main/java/com/gitblit/servlet/AccessRestrictionFilter.java
@@ -19,21 +19,19 @@
 import java.text.MessageFormat;

 

 import javax.servlet.FilterChain;

-import javax.servlet.FilterConfig;

 import javax.servlet.ServletException;

 import javax.servlet.ServletRequest;

 import javax.servlet.ServletResponse;

 import javax.servlet.http.HttpServletRequest;

 import javax.servlet.http.HttpServletResponse;

 

+import com.gitblit.manager.IAuthenticationManager;

 import com.gitblit.manager.IRepositoryManager;

 import com.gitblit.manager.IRuntimeManager;

 import com.gitblit.models.RepositoryModel;

 import com.gitblit.models.UserModel;

 import com.gitblit.utils.StringUtils;

 

-import dagger.ObjectGraph;

-

 /**

  * The AccessRestrictionFilter is an AuthenticationFilter that confirms that the

  * requested repository can be accessed by the anonymous or named user.

@@ -54,11 +52,15 @@
 

 	protected IRepositoryManager repositoryManager;

 

-	@Override

-	protected void inject(ObjectGraph dagger, FilterConfig filterConfig) {

-		super.inject(dagger, filterConfig);

-		this.runtimeManager = dagger.get(IRuntimeManager.class);

-		this.repositoryManager = dagger.get(IRepositoryManager.class);

+	protected AccessRestrictionFilter(

+			IRuntimeManager runtimeManager,

+			IAuthenticationManager authenticationManager,

+			IRepositoryManager repositoryManager) {

+

+		super(authenticationManager);

+

+		this.runtimeManager = runtimeManager;

+		this.repositoryManager = repositoryManager;

 	}

 

 	/**

diff --git a/src/main/java/com/gitblit/servlet/AuthenticationFilter.java b/src/main/java/com/gitblit/servlet/AuthenticationFilter.java
index c21f869..6f13252 100644
--- a/src/main/java/com/gitblit/servlet/AuthenticationFilter.java
+++ b/src/main/java/com/gitblit/servlet/AuthenticationFilter.java
@@ -21,6 +21,7 @@
 import java.util.HashMap;

 import java.util.Map;

 

+import javax.servlet.Filter;

 import javax.servlet.FilterChain;

 import javax.servlet.FilterConfig;

 import javax.servlet.ServletException;

@@ -35,14 +36,11 @@
 import org.slf4j.LoggerFactory;

 

 import com.gitblit.Constants;

-import com.gitblit.dagger.DaggerFilter;

 import com.gitblit.manager.IAuthenticationManager;

 import com.gitblit.models.UserModel;

 import com.gitblit.utils.DeepCopier;

 import com.gitblit.utils.StringUtils;

 

-import dagger.ObjectGraph;

-

 /**

  * The AuthenticationFilter is a servlet filter that preprocesses requests that

  * match its url pattern definition in the web.xml file.

@@ -52,7 +50,7 @@
  * @author James Moger

  *

  */

-public abstract class AuthenticationFilter extends DaggerFilter {

+public abstract class AuthenticationFilter implements Filter {

 

 	protected static final String CHALLENGE = "Basic realm=\"" + Constants.NAME + "\"";

 

@@ -62,9 +60,16 @@
 

 	protected IAuthenticationManager authenticationManager;

 

+	protected AuthenticationFilter(IAuthenticationManager authenticationManager) {

+		this.authenticationManager = authenticationManager;

+	}

+

 	@Override

-	protected void inject(ObjectGraph dagger, FilterConfig filterConfig) {

-		this.authenticationManager = dagger.get(IAuthenticationManager.class);

+	public void init(FilterConfig filterConfig) throws ServletException {

+	}

+

+	@Override

+	public void destroy() {

 	}

 

 	/**

diff --git a/src/main/java/com/gitblit/servlet/BranchGraphServlet.java b/src/main/java/com/gitblit/servlet/BranchGraphServlet.java
index 0abe347..2c77553 100644
--- a/src/main/java/com/gitblit/servlet/BranchGraphServlet.java
+++ b/src/main/java/com/gitblit/servlet/BranchGraphServlet.java
@@ -36,7 +36,10 @@
 import java.util.TreeSet;

 

 import javax.imageio.ImageIO;

+import com.google.inject.Inject;

+import com.google.inject.Singleton;

 import javax.servlet.ServletException;

+import javax.servlet.http.HttpServlet;

 import javax.servlet.http.HttpServletRequest;

 import javax.servlet.http.HttpServletResponse;

 

@@ -52,20 +55,18 @@
 import com.gitblit.Constants;

 import com.gitblit.IStoredSettings;

 import com.gitblit.Keys;

-import com.gitblit.dagger.DaggerServlet;

 import com.gitblit.manager.IRepositoryManager;

 import com.gitblit.utils.JGitUtils;

 import com.gitblit.utils.StringUtils;

 

-import dagger.ObjectGraph;

-

 /**

  * Handles requests for branch graphs

  *

  * @author James Moger

  *

  */

-public class BranchGraphServlet extends DaggerServlet {

+@Singleton

+public class BranchGraphServlet extends HttpServlet {

 

 	private static final long serialVersionUID = 1L;

 

@@ -82,20 +83,20 @@
 

 	private IRepositoryManager repositoryManager;

 

-	public BranchGraphServlet() {

-		super();

+	@Inject

+	public BranchGraphServlet(

+			IStoredSettings settings,

+			IRepositoryManager repositoryManager) {

+

+		this.settings = settings;

+		this.repositoryManager = repositoryManager;

+

 		strokeCache = new Stroke[4];

 		for (int i = 1; i < strokeCache.length; i++) {

 			strokeCache[i] = new BasicStroke(i);

 		}

 	}

 

-	@Override

-	protected void inject(ObjectGraph dagger) {

-		this.settings = dagger.get(IStoredSettings.class);

-		this.repositoryManager = dagger.get(IRepositoryManager.class);

-	}

-

 	/**

 	 * Returns an url to this servlet for the specified parameters.

 	 *

diff --git a/src/main/java/com/gitblit/servlet/DownloadZipFilter.java b/src/main/java/com/gitblit/servlet/DownloadZipFilter.java
index 0c7b3e5..13703a8 100644
--- a/src/main/java/com/gitblit/servlet/DownloadZipFilter.java
+++ b/src/main/java/com/gitblit/servlet/DownloadZipFilter.java
@@ -15,7 +15,13 @@
  */

 package com.gitblit.servlet;

 

+import com.google.inject.Inject;

+import com.google.inject.Singleton;

+

 import com.gitblit.Constants.AccessRestrictionType;

+import com.gitblit.manager.IAuthenticationManager;

+import com.gitblit.manager.IRepositoryManager;

+import com.gitblit.manager.IRuntimeManager;

 import com.gitblit.models.RepositoryModel;

 import com.gitblit.models.UserModel;

 

@@ -27,8 +33,18 @@
  * @author James Moger

  *

  */

+@Singleton

 public class DownloadZipFilter extends AccessRestrictionFilter {

 

+	@Inject

+	public DownloadZipFilter(

+			IRuntimeManager runtimeManager,

+			IAuthenticationManager authenticationManager,

+			IRepositoryManager repositoryManager) {

+

+		super(runtimeManager, authenticationManager, repositoryManager);

+	}

+

 	/**

 	 * Extract the repository name from the url.

 	 *

diff --git a/src/main/java/com/gitblit/servlet/DownloadZipServlet.java b/src/main/java/com/gitblit/servlet/DownloadZipServlet.java
index 6a64778..0756256 100644
--- a/src/main/java/com/gitblit/servlet/DownloadZipServlet.java
+++ b/src/main/java/com/gitblit/servlet/DownloadZipServlet.java
@@ -20,7 +20,10 @@
 import java.text.ParseException;

 import java.util.Date;

 

+import com.google.inject.Inject;

+import com.google.inject.Singleton;

 import javax.servlet.ServletException;

+import javax.servlet.http.HttpServlet;

 import javax.servlet.http.HttpServletResponse;

 

 import org.eclipse.jgit.lib.Repository;

@@ -31,15 +34,12 @@
 import com.gitblit.Constants;

 import com.gitblit.IStoredSettings;

 import com.gitblit.Keys;

-import com.gitblit.dagger.DaggerServlet;

 import com.gitblit.manager.IRepositoryManager;

 import com.gitblit.utils.CompressionUtils;

 import com.gitblit.utils.JGitUtils;

 import com.gitblit.utils.MarkdownUtils;

 import com.gitblit.utils.StringUtils;

 

-import dagger.ObjectGraph;

-

 /**

  * Streams out a zip file from the specified repository for any tree path at any

  * revision.

@@ -47,7 +47,8 @@
  * @author James Moger

  *

  */

-public class DownloadZipServlet extends DaggerServlet {

+@Singleton

+public class DownloadZipServlet extends HttpServlet {

 

 	private static final long serialVersionUID = 1L;

 

@@ -76,10 +77,10 @@
 		}

 	}

 

-	@Override

-	protected void inject(ObjectGraph dagger) {

-		this.settings = dagger.get(IStoredSettings.class);

-		this.repositoryManager = dagger.get(IRepositoryManager.class);

+	@Inject

+	public DownloadZipServlet(IStoredSettings settings, IRepositoryManager repositoryManager) {

+		this.settings = settings;

+		this.repositoryManager = repositoryManager;

 	}

 

 	/**

diff --git a/src/main/java/com/gitblit/servlet/EnforceAuthenticationFilter.java b/src/main/java/com/gitblit/servlet/EnforceAuthenticationFilter.java
index c015021..8a3f782 100644
--- a/src/main/java/com/gitblit/servlet/EnforceAuthenticationFilter.java
+++ b/src/main/java/com/gitblit/servlet/EnforceAuthenticationFilter.java
@@ -18,6 +18,9 @@
 import java.io.IOException;
 import java.text.MessageFormat;
 
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
+import javax.servlet.Filter;
 import javax.servlet.FilterChain;
 import javax.servlet.FilterConfig;
 import javax.servlet.ServletException;
@@ -31,12 +34,9 @@
 
 import com.gitblit.IStoredSettings;
 import com.gitblit.Keys;
-import com.gitblit.dagger.DaggerFilter;
 import com.gitblit.manager.IAuthenticationManager;
 import com.gitblit.models.UserModel;
 
-import dagger.ObjectGraph;
-
 /**
  * This filter enforces authentication via HTTP Basic Authentication, if the settings indicate so.
  * It looks at the settings "web.authenticateViewPages" and "web.enforceHttpBasicAuthentication"; if
@@ -45,7 +45,8 @@
  * @author Laurens Vrijnsen
  *
  */
-public class EnforceAuthenticationFilter extends DaggerFilter {
+@Singleton
+public class EnforceAuthenticationFilter implements Filter {
 
 	protected transient Logger logger = LoggerFactory.getLogger(getClass());
 
@@ -53,10 +54,21 @@
 
 	private IAuthenticationManager authenticationManager;
 
+	@Inject
+	public EnforceAuthenticationFilter(
+			IStoredSettings settings,
+			IAuthenticationManager authenticationManager) {
+
+		this.settings = settings;
+		this.authenticationManager = authenticationManager;
+	}
+
 	@Override
-	protected void inject(ObjectGraph dagger, FilterConfig filterConfig) {
-		this.settings = dagger.get(IStoredSettings.class);
-		this.authenticationManager = dagger.get(IAuthenticationManager.class);
+	public void init(FilterConfig config) {
+	}
+
+	@Override
+	public void destroy() {
 	}
 
 	/*
@@ -87,12 +99,4 @@
 			chain.doFilter(request, response);
 		}
 	}
-
-
-	/*
-	 * @see javax.servlet.Filter#destroy()
-	 */
-	@Override
-	public void destroy() {
-	}
 }
diff --git a/src/main/java/com/gitblit/servlet/FederationServlet.java b/src/main/java/com/gitblit/servlet/FederationServlet.java
index 8dbf0e1..89ff231 100644
--- a/src/main/java/com/gitblit/servlet/FederationServlet.java
+++ b/src/main/java/com/gitblit/servlet/FederationServlet.java
@@ -25,6 +25,8 @@
 import java.util.Map;

 import java.util.Set;

 

+import com.google.inject.Inject;

+import com.google.inject.Singleton;

 import javax.servlet.http.HttpServletResponse;

 

 import com.gitblit.Constants.FederationRequest;

@@ -43,14 +45,13 @@
 import com.gitblit.utils.StringUtils;

 import com.gitblit.utils.TimeUtils;

 

-import dagger.ObjectGraph;

-

 /**

  * Handles federation requests.

  *

  * @author James Moger

  *

  */

+@Singleton

 public class FederationServlet extends JsonServlet {

 

 	private static final long serialVersionUID = 1L;

@@ -63,12 +64,17 @@
 

 	private IFederationManager federationManager;

 

-	@Override

-	protected void inject(ObjectGraph dagger) {

-		this.settings = dagger.get(IStoredSettings.class);

-		this.userManager = dagger.get(IUserManager.class);

-		this.repositoryManager = dagger.get(IRepositoryManager.class);

-		this.federationManager = dagger.get(IFederationManager.class);

+	@Inject

+	public FederationServlet(

+			IStoredSettings settings,

+			IUserManager userManager,

+			IRepositoryManager repositoryManager,

+			IFederationManager federationManager) {

+

+		this.settings = settings;

+		this.userManager = userManager;

+		this.repositoryManager = repositoryManager;

+		this.federationManager = federationManager;

 	}

 

 	/**

diff --git a/src/main/java/com/gitblit/servlet/GitFilter.java b/src/main/java/com/gitblit/servlet/GitFilter.java
index bb3d321..b29fdb6 100644
--- a/src/main/java/com/gitblit/servlet/GitFilter.java
+++ b/src/main/java/com/gitblit/servlet/GitFilter.java
@@ -17,7 +17,8 @@
 

 import java.text.MessageFormat;

 

-import javax.servlet.FilterConfig;

+import com.google.inject.Inject;

+import com.google.inject.Singleton;

 import javax.servlet.http.HttpServletRequest;

 

 import com.gitblit.Constants.AccessRestrictionType;

@@ -25,13 +26,14 @@
 import com.gitblit.GitBlitException;

 import com.gitblit.IStoredSettings;

 import com.gitblit.Keys;

+import com.gitblit.manager.IAuthenticationManager;

 import com.gitblit.manager.IFederationManager;

+import com.gitblit.manager.IRepositoryManager;

+import com.gitblit.manager.IRuntimeManager;

 import com.gitblit.models.RepositoryModel;

 import com.gitblit.models.UserModel;

 import com.gitblit.utils.StringUtils;

 

-import dagger.ObjectGraph;

-

 /**

  * The GitFilter is an AccessRestrictionFilter which ensures that Git client

  * requests for push, clone, or view restricted repositories are authenticated

@@ -40,6 +42,7 @@
  * @author James Moger

  *

  */

+@Singleton

 public class GitFilter extends AccessRestrictionFilter {

 

 	protected static final String gitReceivePack = "/git-receive-pack";

@@ -53,11 +56,18 @@
 

 	private IFederationManager federationManager;

 

-	@Override

-	protected void inject(ObjectGraph dagger, FilterConfig filterConfig) {

-		super.inject(dagger, filterConfig);

-		this.settings = dagger.get(IStoredSettings.class);

-		this.federationManager = dagger.get(IFederationManager.class);

+	@Inject

+	public GitFilter(

+			IStoredSettings settings,

+			IRuntimeManager runtimeManager,

+			IAuthenticationManager authenticationManager,

+			IRepositoryManager repositoryManager,

+			IFederationManager federationManager) {

+

+		super(runtimeManager, authenticationManager, repositoryManager);

+

+		this.settings = settings;

+		this.federationManager = federationManager;

 	}

 

 	/**

diff --git a/src/main/java/com/gitblit/servlet/GitServlet.java b/src/main/java/com/gitblit/servlet/GitServlet.java
index 93fe31d..941b4c5 100644
--- a/src/main/java/com/gitblit/servlet/GitServlet.java
+++ b/src/main/java/com/gitblit/servlet/GitServlet.java
@@ -20,6 +20,8 @@
 import java.io.IOException;

 import java.util.Enumeration;

 

+import com.google.inject.Inject;

+import com.google.inject.Singleton;

 import javax.servlet.FilterChain;

 import javax.servlet.FilterConfig;

 import javax.servlet.ServletConfig;

@@ -33,14 +35,11 @@
 

 import org.eclipse.jgit.http.server.GitFilter;

 

-import com.gitblit.dagger.DaggerContext;

 import com.gitblit.git.GitblitReceivePackFactory;

 import com.gitblit.git.GitblitUploadPackFactory;

 import com.gitblit.git.RepositoryResolver;

 import com.gitblit.manager.IGitblit;

 

-import dagger.ObjectGraph;

-

 /**

  * The GitServlet provides http/https access to Git repositories.

  * Access to this servlet is protected by the GitFilter.

@@ -48,24 +47,23 @@
  * @author James Moger

  *

  */

+@Singleton

 public class GitServlet extends HttpServlet {

 

 	private static final long serialVersionUID = 1L;

 

 	private final GitFilter gitFilter;

 

-	public GitServlet() {

+	@Inject

+	public GitServlet(IGitblit gitblit) {

 		gitFilter = new GitFilter();

+		gitFilter.setRepositoryResolver(new RepositoryResolver<HttpServletRequest>(gitblit));

+		gitFilter.setUploadPackFactory(new GitblitUploadPackFactory<HttpServletRequest>(gitblit));

+		gitFilter.setReceivePackFactory(new GitblitReceivePackFactory<HttpServletRequest>(gitblit));

 	}

 

 	@Override

 	public void init(final ServletConfig config) throws ServletException {

-		ServletContext context = config.getServletContext();

-		ObjectGraph dagger = (ObjectGraph) context.getAttribute(DaggerContext.INJECTOR_NAME);

-		IGitblit gitblit = dagger.get(IGitblit.class);

-		gitFilter.setRepositoryResolver(new RepositoryResolver<HttpServletRequest>(gitblit));

-		gitFilter.setUploadPackFactory(new GitblitUploadPackFactory<HttpServletRequest>(gitblit));

-		gitFilter.setReceivePackFactory(new GitblitReceivePackFactory<HttpServletRequest>(gitblit));

 

 		gitFilter.init(new FilterConfig() {

 			@Override

diff --git a/src/main/java/com/gitblit/servlet/GitblitContext.java b/src/main/java/com/gitblit/servlet/GitblitContext.java
index fcc702b..d8ccac3 100644
--- a/src/main/java/com/gitblit/servlet/GitblitContext.java
+++ b/src/main/java/com/gitblit/servlet/GitblitContext.java
@@ -31,14 +31,17 @@
 import javax.servlet.ServletContext;
 import javax.servlet.ServletContextEvent;
 
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
 import com.gitblit.Constants;
-import com.gitblit.DaggerModule;
 import com.gitblit.FileSettings;
 import com.gitblit.IStoredSettings;
 import com.gitblit.Keys;
 import com.gitblit.WebXmlSettings;
-import com.gitblit.dagger.DaggerContext;
 import com.gitblit.extensions.LifeCycleListener;
+import com.gitblit.guice.CoreModule;
+import com.gitblit.guice.WebModule;
 import com.gitblit.manager.IAuthenticationManager;
 import com.gitblit.manager.IFederationManager;
 import com.gitblit.manager.IGitblit;
@@ -48,28 +51,34 @@
 import com.gitblit.manager.IProjectManager;
 import com.gitblit.manager.IRepositoryManager;
 import com.gitblit.manager.IRuntimeManager;
+import com.gitblit.manager.IServicesManager;
 import com.gitblit.manager.IUserManager;
+import com.gitblit.tickets.ITicketService;
 import com.gitblit.transport.ssh.IPublicKeyManager;
 import com.gitblit.utils.ContainerUtils;
 import com.gitblit.utils.StringUtils;
-
-import dagger.ObjectGraph;
+import com.google.inject.AbstractModule;
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+import com.google.inject.servlet.GuiceServletContextListener;
 
 /**
  * This class is the main entry point for the entire webapp.  It is a singleton
  * created manually by Gitblit GO or dynamically by the WAR/Express servlet
- * container.  This class instantiates and starts all managers.  Servlets and
- * filters are instantiated defined in web.xml and instantiated by the servlet
- * container, but those servlets and filters use Dagger to manually inject their
- * dependencies.
+ * container.  This class instantiates and starts all managers.
+ *
+ * Servlets and filters are injected which allows Gitblit to be completely
+ * code-driven.
  *
  * @author James Moger
  *
  */
-public class GitblitContext extends DaggerContext {
+public class GitblitContext extends GuiceServletContextListener {
 
 	private static GitblitContext gitblit;
 
+	protected final Logger logger = LoggerFactory.getLogger(getClass());
+
 	private final List<IManager> managers = new ArrayList<IManager>();
 
 	private final IStoredSettings goSettings;
@@ -111,12 +120,16 @@
 		return null;
 	}
 
-	/**
-	 * Returns Gitblit's Dagger injection modules.
-	 */
 	@Override
-	protected Object [] getModules() {
-		return new Object [] { new DaggerModule() };
+	protected Injector getInjector() {
+		return Guice.createInjector(getModules());
+	}
+
+	/**
+	 * Returns Gitblit's Guice injection modules.
+	 */
+	protected AbstractModule [] getModules() {
+		return new AbstractModule [] { new CoreModule(), new WebModule() };
 	}
 
 	/**
@@ -127,18 +140,20 @@
 	 */
 	@Override
 	public final void contextInitialized(ServletContextEvent contextEvent) {
+		super.contextInitialized(contextEvent);
+
 		ServletContext context = contextEvent.getServletContext();
-		configureContext(context);
+		startCore(context);
 	}
 
 	/**
 	 * Prepare runtime settings and start all manager instances.
 	 */
-	protected void configureContext(ServletContext context) {
-		ObjectGraph injector = getInjector(context);
+	protected void startCore(ServletContext context) {
+		Injector injector = (Injector) context.getAttribute(Injector.class.getName());
 
 		// create the runtime settings object
-		IStoredSettings runtimeSettings = injector.get(IStoredSettings.class);
+		IStoredSettings runtimeSettings = injector.getInstance(IStoredSettings.class);
 		final File baseFolder;
 
 		if (goSettings != null) {
@@ -168,7 +183,7 @@
 
 		// Manually configure IRuntimeManager
 		logManager(IRuntimeManager.class);
-		IRuntimeManager runtime = injector.get(IRuntimeManager.class);
+		IRuntimeManager runtime = injector.getInstance(IRuntimeManager.class);
 		runtime.setBaseFolder(baseFolder);
 		runtime.getStatus().isGO = goSettings != null;
 		runtime.getStatus().servletContainer = context.getServerInfo();
@@ -186,7 +201,9 @@
 		startManager(injector, IRepositoryManager.class);
 		startManager(injector, IProjectManager.class);
 		startManager(injector, IFederationManager.class);
+		startManager(injector, ITicketService.class);
 		startManager(injector, IGitblit.class);
+		startManager(injector, IServicesManager.class);
 
 		// start the plugin manager last so that plugins can depend on
 		// deterministic access to all other managers in their start() methods
@@ -196,7 +213,7 @@
 		logger.info("All managers started.");
 		logger.info("");
 
-		IPluginManager pluginManager = injector.get(IPluginManager.class);
+		IPluginManager pluginManager = injector.getInstance(IPluginManager.class);
 		for (LifeCycleListener listener : pluginManager.getExtensions(LifeCycleListener.class)) {
 			try {
 				listener.onStartup();
@@ -218,12 +235,12 @@
 		return null;
 	}
 
-	protected <X extends IManager> X loadManager(ObjectGraph injector, Class<X> clazz) {
-		X x = injector.get(clazz);
+	protected <X extends IManager> X loadManager(Injector injector, Class<X> clazz) {
+		X x = injector.getInstance(clazz);
 		return x;
 	}
 
-	protected <X extends IManager> X startManager(ObjectGraph injector, Class<X> clazz) {
+	protected <X extends IManager> X startManager(Injector injector, Class<X> clazz) {
 		X x = loadManager(injector, clazz);
 		logManager(clazz);
 		x.start();
@@ -236,11 +253,17 @@
 		logger.info("----[{}]----", clazz.getName());
 	}
 
+	@Override
+	public final void contextDestroyed(ServletContextEvent contextEvent) {
+		super.contextDestroyed(contextEvent);
+		ServletContext context = contextEvent.getServletContext();
+		destroyContext(context);
+	}
+
 	/**
 	 * Gitblit is being shutdown either because the servlet container is
 	 * shutting down or because the servlet container is re-deploying Gitblit.
 	 */
-	@Override
 	protected void destroyContext(ServletContext context) {
 		logger.info("Gitblit context destroyed by servlet container.");
 
diff --git a/src/main/java/com/gitblit/servlet/JsonServlet.java b/src/main/java/com/gitblit/servlet/JsonServlet.java
index 4378c8a..abc0f29 100644
--- a/src/main/java/com/gitblit/servlet/JsonServlet.java
+++ b/src/main/java/com/gitblit/servlet/JsonServlet.java
@@ -21,6 +21,7 @@
 import java.text.MessageFormat;

 

 import javax.servlet.ServletException;

+import javax.servlet.http.HttpServlet;

 import javax.servlet.http.HttpServletRequest;

 import javax.servlet.http.HttpServletResponse;

 

@@ -28,7 +29,6 @@
 import org.slf4j.LoggerFactory;

 

 import com.gitblit.Constants;

-import com.gitblit.dagger.DaggerServlet;

 import com.gitblit.utils.JsonUtils;

 import com.gitblit.utils.StringUtils;

 

@@ -38,7 +38,7 @@
  * @author James Moger

  *

  */

-public abstract class JsonServlet extends DaggerServlet {

+public abstract class JsonServlet extends HttpServlet {

 

 	private static final long serialVersionUID = 1L;

 

diff --git a/src/main/java/com/gitblit/servlet/LogoServlet.java b/src/main/java/com/gitblit/servlet/LogoServlet.java
index 96f34af..d5d298b 100644
--- a/src/main/java/com/gitblit/servlet/LogoServlet.java
+++ b/src/main/java/com/gitblit/servlet/LogoServlet.java
@@ -21,24 +21,25 @@
 import java.io.InputStream;

 import java.io.OutputStream;

 

+import com.google.inject.Inject;

+import com.google.inject.Singleton;

 import javax.servlet.ServletContext;

 import javax.servlet.ServletException;

+import javax.servlet.http.HttpServlet;

 import javax.servlet.http.HttpServletRequest;

 import javax.servlet.http.HttpServletResponse;

 

 import com.gitblit.Keys;

-import com.gitblit.dagger.DaggerServlet;

 import com.gitblit.manager.IRuntimeManager;

 

-import dagger.ObjectGraph;

-

 /**

  * Handles requests for logo.png

  *

  * @author James Moger

  *

  */

-public class LogoServlet extends DaggerServlet {

+@Singleton

+public class LogoServlet extends HttpServlet {

 

 	private static final long serialVersionUID = 1L;

 

@@ -46,9 +47,9 @@
 

 	private IRuntimeManager runtimeManager;

 

-	@Override

-	protected void inject(ObjectGraph dagger) {

-		this.runtimeManager = dagger.get(IRuntimeManager.class);

+	@Inject

+	public LogoServlet(IRuntimeManager runtimeManager) {

+		this.runtimeManager = runtimeManager;

 	}

 

 	@Override

diff --git a/src/main/java/com/gitblit/servlet/PagesFilter.java b/src/main/java/com/gitblit/servlet/PagesFilter.java
index e07d9b3..1d6c3db 100644
--- a/src/main/java/com/gitblit/servlet/PagesFilter.java
+++ b/src/main/java/com/gitblit/servlet/PagesFilter.java
@@ -15,6 +15,13 @@
  */

 package com.gitblit.servlet;

 

+import com.google.inject.Inject;

+import com.google.inject.Singleton;

+

+import com.gitblit.manager.IAuthenticationManager;

+import com.gitblit.manager.IRepositoryManager;

+import com.gitblit.manager.IRuntimeManager;

+

 

 /**

  * The PagesFilter is an AccessRestrictionFilter which ensures the gh-pages

@@ -23,7 +30,17 @@
  * @author James Moger

  *

  */

+

+@Singleton

 public class PagesFilter extends RawFilter {

 

+	@Inject

+	public PagesFilter(

+			IRuntimeManager runtimeManager,

+			IAuthenticationManager authenticationManager,

+			IRepositoryManager repositoryManager) {

+

+		super(runtimeManager, authenticationManager, repositoryManager);

+	}

 

 }

diff --git a/src/main/java/com/gitblit/servlet/PagesServlet.java b/src/main/java/com/gitblit/servlet/PagesServlet.java
index defd9e6..1473e96 100644
--- a/src/main/java/com/gitblit/servlet/PagesServlet.java
+++ b/src/main/java/com/gitblit/servlet/PagesServlet.java
@@ -1,103 +1,116 @@
-/*

- * Copyright 2012 gitblit.com.

- *

- * Licensed under the Apache License, Version 2.0 (the "License");

- * you may not use this file except in compliance with the License.

- * You may obtain a copy of the License at

- *

- *     http://www.apache.org/licenses/LICENSE-2.0

- *

- * Unless required by applicable law or agreed to in writing, software

- * distributed under the License is distributed on an "AS IS" BASIS,

- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

- * See the License for the specific language governing permissions and

- * limitations under the License.

- */

-package com.gitblit.servlet;

-

-import java.io.IOException;

-import java.io.InputStream;

-import java.util.Date;

-

-import javax.servlet.ServletException;

-import javax.servlet.http.HttpServletRequest;

-import javax.servlet.http.HttpServletResponse;

-

-import org.eclipse.jgit.lib.Repository;

-import org.eclipse.jgit.revwalk.RevCommit;

-

-import com.gitblit.Constants;

-import com.gitblit.utils.JGitUtils;

-

-/**

- * Serves the content of a gh-pages branch.

- *

- * @author James Moger

- *

- */

-public class PagesServlet extends RawServlet {

-

-	private static final long serialVersionUID = 1L;

-

-

-	/**

-	 * Returns an url to this servlet for the specified parameters.

-	 *

-	 * @param baseURL

-	 * @param repository

-	 * @param path

-	 * @return an url

-	 */

-	public static String asLink(String baseURL, String repository, String path) {

-		if (baseURL.length() > 0 && baseURL.charAt(baseURL.length() - 1) == '/') {

-			baseURL = baseURL.substring(0, baseURL.length() - 1);

-		}

-		return baseURL + Constants.PAGES + repository + "/" + (path == null ? "" : ("/" + path));

-	}

-

-	@Override

-	protected String getBranch(String repository, HttpServletRequest request) {

-		return "gh-pages";

-	}

-

-	@Override

-	protected String getPath(String repository, String branch, HttpServletRequest request) {

-		String pi = request.getPathInfo().substring(1);

-		if (pi.equals(repository)) {

-			return "";

-		}

-		String path = pi.substring(pi.indexOf(repository) + repository.length() + 1);

-		if (path.endsWith("/")) {

-			path = path.substring(0, path.length() - 1);

-		}

-		return path;

-	}

-

-	@Override

-	protected boolean renderIndex() {

-		return true;

-	}

-

-	@Override

-	protected void setContentType(HttpServletResponse response, String contentType) {

-		response.setContentType(contentType);;

-	}

-

-	@Override

-	protected boolean streamFromRepo(HttpServletRequest request, HttpServletResponse response, Repository repository,

-			RevCommit commit, String requestedPath) throws IOException {

-

-		response.setDateHeader("Last-Modified", JGitUtils.getCommitDate(commit).getTime());

-		response.setHeader("Cache-Control", "public, max-age=3600, must-revalidate");

-

-		return super.streamFromRepo(request, response, repository, commit, requestedPath);

-	}

-

-	@Override

-	protected void sendContent(HttpServletResponse response, Date date, InputStream is) throws ServletException, IOException {

-		response.setDateHeader("Last-Modified", date.getTime());

-		response.setHeader("Cache-Control", "public, max-age=3600, must-revalidate");

-

-		super.sendContent(response, date, is);

-	}

-}

+/*
+ * Copyright 2012 gitblit.com.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.gitblit.servlet;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Date;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.revwalk.RevCommit;
+
+import com.gitblit.Constants;
+import com.gitblit.manager.IRepositoryManager;
+import com.gitblit.manager.IRuntimeManager;
+import com.gitblit.utils.JGitUtils;
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
+
+/**
+ * Serves the content of a gh-pages branch.
+ *
+ * @author James Moger
+ *
+ */
+@Singleton
+public class PagesServlet extends RawServlet {
+
+	private static final long serialVersionUID = 1L;
+
+
+	/**
+	 * Returns an url to this servlet for the specified parameters.
+	 *
+	 * @param baseURL
+	 * @param repository
+	 * @param path
+	 * @return an url
+	 */
+	public static String asLink(String baseURL, String repository, String path) {
+		if (baseURL.length() > 0 && baseURL.charAt(baseURL.length() - 1) == '/') {
+			baseURL = baseURL.substring(0, baseURL.length() - 1);
+		}
+		return baseURL + Constants.PAGES + repository + "/" + (path == null ? "" : ("/" + path));
+	}
+
+	@Inject
+	public PagesServlet(
+			IRuntimeManager runtimeManager,
+			IRepositoryManager repositoryManager) {
+
+		super(runtimeManager, repositoryManager);
+	}
+
+	@Override
+	protected String getBranch(String repository, HttpServletRequest request) {
+		return "gh-pages";
+	}
+
+	@Override
+	protected String getPath(String repository, String branch, HttpServletRequest request) {
+		String pi = request.getPathInfo().substring(1);
+		if (pi.equals(repository)) {
+			return "";
+		}
+		String path = pi.substring(pi.indexOf(repository) + repository.length() + 1);
+		if (path.endsWith("/")) {
+			path = path.substring(0, path.length() - 1);
+		}
+		return path;
+	}
+
+	@Override
+	protected boolean renderIndex() {
+		return true;
+	}
+
+	@Override
+	protected void setContentType(HttpServletResponse response, String contentType) {
+		response.setContentType(contentType);;
+	}
+
+	@Override
+	protected boolean streamFromRepo(HttpServletRequest request, HttpServletResponse response, Repository repository,
+			RevCommit commit, String requestedPath) throws IOException {
+
+		response.setDateHeader("Last-Modified", JGitUtils.getCommitDate(commit).getTime());
+		response.setHeader("Cache-Control", "public, max-age=3600, must-revalidate");
+
+		return super.streamFromRepo(request, response, repository, commit, requestedPath);
+	}
+
+	@Override
+	protected void sendContent(HttpServletResponse response, Date date, InputStream is) throws ServletException, IOException {
+		response.setDateHeader("Last-Modified", date.getTime());
+		response.setHeader("Cache-Control", "public, max-age=3600, must-revalidate");
+
+		super.sendContent(response, date, is);
+	}
+}
diff --git a/src/main/java/com/gitblit/servlet/ProxyFilter.java b/src/main/java/com/gitblit/servlet/ProxyFilter.java
index 46f59de..d7f096a 100644
--- a/src/main/java/com/gitblit/servlet/ProxyFilter.java
+++ b/src/main/java/com/gitblit/servlet/ProxyFilter.java
@@ -16,9 +16,13 @@
 package com.gitblit.servlet;
 
 import java.io.IOException;
+import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
 
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
+import javax.servlet.Filter;
 import javax.servlet.FilterChain;
 import javax.servlet.FilterConfig;
 import javax.servlet.ServletException;
@@ -27,13 +31,10 @@
 
 import ro.fortsoft.pf4j.PluginWrapper;
 
-import com.gitblit.dagger.DaggerFilter;
 import com.gitblit.extensions.HttpRequestFilter;
 import com.gitblit.manager.IPluginManager;
 import com.gitblit.manager.IRuntimeManager;
 
-import dagger.ObjectGraph;
-
 /**
  * A request filter than allows registered extension request filters to access
  * request data.  The intended purpose is for server monitoring plugins.
@@ -41,15 +42,29 @@
  * @author David Ostrovsky
  * @since 1.6.0
  */
-public class ProxyFilter extends DaggerFilter {
-	private List<HttpRequestFilter> filters;
+@Singleton
+public class ProxyFilter implements Filter {
+	private final IRuntimeManager runtimeManager;
+
+	private final IPluginManager pluginManager;
+
+	private final List<HttpRequestFilter> filters;
+
+	@Inject
+	public ProxyFilter(
+			IRuntimeManager runtimeManager,
+			IPluginManager pluginManager) {
+
+		this.runtimeManager = runtimeManager;
+		this.pluginManager = pluginManager;
+		this.filters = new ArrayList<>();
+
+	}
 
 	@Override
-	protected void inject(ObjectGraph dagger, FilterConfig filterConfig) throws ServletException {
-		IRuntimeManager runtimeManager = dagger.get(IRuntimeManager.class);
-		IPluginManager pluginManager = dagger.get(IPluginManager.class);
+	public void init(FilterConfig filterConfig) throws ServletException {
 
-		filters = pluginManager.getExtensions(HttpRequestFilter.class);
+		filters.addAll(pluginManager.getExtensions(HttpRequestFilter.class));
 		for (HttpRequestFilter f : filters) {
 			// wrap the filter config for Gitblit settings retrieval
 			PluginWrapper pluginWrapper = pluginManager.whichPlugin(f.getClass());
diff --git a/src/main/java/com/gitblit/servlet/PtServlet.java b/src/main/java/com/gitblit/servlet/PtServlet.java
index e9cbaa5..313b284 100644
--- a/src/main/java/com/gitblit/servlet/PtServlet.java
+++ b/src/main/java/com/gitblit/servlet/PtServlet.java
@@ -21,7 +21,10 @@
 import java.io.InputStream;

 import java.io.OutputStream;

 

+import com.google.inject.Inject;

+import com.google.inject.Singleton;

 import javax.servlet.ServletException;

+import javax.servlet.http.HttpServlet;

 import javax.servlet.http.HttpServletRequest;

 import javax.servlet.http.HttpServletResponse;

 

@@ -34,11 +37,8 @@
 import org.apache.wicket.util.io.ByteArrayOutputStream;

 import org.eclipse.jgit.lib.FileMode;

 

-import com.gitblit.dagger.DaggerServlet;

 import com.gitblit.manager.IRuntimeManager;

 

-import dagger.ObjectGraph;

-

 /**

  * Handles requests for the Barnum pt (patchset tool).

  *

@@ -47,7 +47,8 @@
  * @author James Moger

  *

  */

-public class PtServlet extends DaggerServlet {

+@Singleton

+public class PtServlet extends HttpServlet {

 

 	private static final long serialVersionUID = 1L;

 

@@ -55,9 +56,9 @@
 

 	private IRuntimeManager runtimeManager;

 

-	@Override

-	protected void inject(ObjectGraph dagger) {

-		this.runtimeManager = dagger.get(IRuntimeManager.class);

+	@Inject

+	public PtServlet(IRuntimeManager runtimeManager) {

+		this.runtimeManager = runtimeManager;

 	}

 

 	@Override

diff --git a/src/main/java/com/gitblit/servlet/RawFilter.java b/src/main/java/com/gitblit/servlet/RawFilter.java
index 34989c9..fe4af04 100644
--- a/src/main/java/com/gitblit/servlet/RawFilter.java
+++ b/src/main/java/com/gitblit/servlet/RawFilter.java
@@ -15,9 +15,15 @@
  */

 package com.gitblit.servlet;

 

+import com.google.inject.Inject;

+import com.google.inject.Singleton;

+

 import org.eclipse.jgit.lib.Repository;

 

 import com.gitblit.Constants.AccessRestrictionType;

+import com.gitblit.manager.IAuthenticationManager;

+import com.gitblit.manager.IRepositoryManager;

+import com.gitblit.manager.IRuntimeManager;

 import com.gitblit.models.RepositoryModel;

 import com.gitblit.models.UserModel;

 

@@ -28,8 +34,18 @@
  * @author James Moger

  *

  */

+@Singleton

 public class RawFilter extends AccessRestrictionFilter {

 

+	@Inject

+	public RawFilter(

+			IRuntimeManager runtimeManager,

+			IAuthenticationManager authenticationManager,

+			IRepositoryManager repositoryManager) {

+

+		super(runtimeManager, authenticationManager, repositoryManager);

+	}

+

 	/**

 	 * Extract the repository name from the url.

 	 *

diff --git a/src/main/java/com/gitblit/servlet/RawServlet.java b/src/main/java/com/gitblit/servlet/RawServlet.java
index 9fb96a5..b11bed9 100644
--- a/src/main/java/com/gitblit/servlet/RawServlet.java
+++ b/src/main/java/com/gitblit/servlet/RawServlet.java
@@ -28,8 +28,11 @@
 import java.util.Map;
 import java.util.TreeMap;
 
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
 import javax.servlet.ServletContext;
 import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
@@ -48,7 +51,6 @@
 
 import com.gitblit.Constants;
 import com.gitblit.Keys;
-import com.gitblit.dagger.DaggerServlet;
 import com.gitblit.manager.IRepositoryManager;
 import com.gitblit.manager.IRuntimeManager;
 import com.gitblit.models.PathModel;
@@ -57,28 +59,30 @@
 import com.gitblit.utils.MarkdownUtils;
 import com.gitblit.utils.StringUtils;
 
-import dagger.ObjectGraph;
-
 /**
  * Serves the content of a branch.
  *
  * @author James Moger
  *
  */
-public class RawServlet extends DaggerServlet {
+@Singleton
+public class RawServlet extends HttpServlet {
 
 	private static final long serialVersionUID = 1L;
 
 	private transient Logger logger = LoggerFactory.getLogger(RawServlet.class);
 
-	private IRuntimeManager runtimeManager;
+	private final IRuntimeManager runtimeManager;
 
-	private IRepositoryManager repositoryManager;
+	private final IRepositoryManager repositoryManager;
 
-	@Override
-	protected void inject(ObjectGraph dagger) {
-		this.runtimeManager = dagger.get(IRuntimeManager.class);
-		this.repositoryManager = dagger.get(IRepositoryManager.class);
+	@Inject
+	public RawServlet(
+			IRuntimeManager runtimeManager,
+			IRepositoryManager repositoryManager) {
+
+		this.runtimeManager = runtimeManager;
+		this.repositoryManager = repositoryManager;
 	}
 
 	/**
diff --git a/src/main/java/com/gitblit/servlet/RobotsTxtServlet.java b/src/main/java/com/gitblit/servlet/RobotsTxtServlet.java
index 9bd3b3c..4e58d4d 100644
--- a/src/main/java/com/gitblit/servlet/RobotsTxtServlet.java
+++ b/src/main/java/com/gitblit/servlet/RobotsTxtServlet.java
@@ -18,32 +18,33 @@
 import java.io.File;

 import java.io.IOException;

 

+import com.google.inject.Inject;

+import com.google.inject.Singleton;

 import javax.servlet.ServletException;

+import javax.servlet.http.HttpServlet;

 import javax.servlet.http.HttpServletRequest;

 import javax.servlet.http.HttpServletResponse;

 

 import com.gitblit.Keys;

-import com.gitblit.dagger.DaggerServlet;

 import com.gitblit.manager.IRuntimeManager;

 import com.gitblit.utils.FileUtils;

 

-import dagger.ObjectGraph;

-

 /**

  * Handles requests for robots.txt

  *

  * @author James Moger

  *

  */

-public class RobotsTxtServlet extends DaggerServlet {

+@Singleton

+public class RobotsTxtServlet extends HttpServlet {

 

 	private static final long serialVersionUID = 1L;

 

 	private IRuntimeManager runtimeManager;

 

-	@Override

-	protected void inject(ObjectGraph dagger) {

-		this.runtimeManager = dagger.get(IRuntimeManager.class);

+	@Inject

+	public RobotsTxtServlet(IRuntimeManager runtimeManager) {

+		this.runtimeManager = runtimeManager;

 	}

 

 	@Override

diff --git a/src/main/java/com/gitblit/servlet/RpcFilter.java b/src/main/java/com/gitblit/servlet/RpcFilter.java
index 23bf956..34474d5 100644
--- a/src/main/java/com/gitblit/servlet/RpcFilter.java
+++ b/src/main/java/com/gitblit/servlet/RpcFilter.java
@@ -18,8 +18,9 @@
 import java.io.IOException;

 import java.text.MessageFormat;

 

+import com.google.inject.Inject;

+import com.google.inject.Singleton;

 import javax.servlet.FilterChain;

-import javax.servlet.FilterConfig;

 import javax.servlet.ServletException;

 import javax.servlet.ServletRequest;

 import javax.servlet.ServletResponse;

@@ -29,11 +30,10 @@
 import com.gitblit.Constants.RpcRequest;

 import com.gitblit.IStoredSettings;

 import com.gitblit.Keys;

+import com.gitblit.manager.IAuthenticationManager;

 import com.gitblit.manager.IRuntimeManager;

 import com.gitblit.models.UserModel;

 

-import dagger.ObjectGraph;

-

 /**

  * The RpcFilter is a servlet filter that secures the RpcServlet.

  *

@@ -47,17 +47,23 @@
  * @author James Moger

  *

  */

+@Singleton

 public class RpcFilter extends AuthenticationFilter {

 

 	private IStoredSettings settings;

 

 	private IRuntimeManager runtimeManager;

 

-	@Override

-	protected void inject(ObjectGraph dagger, FilterConfig filterConfig) {

-		super.inject(dagger, filterConfig);

-		this.settings = dagger.get(IStoredSettings.class);

-		this.runtimeManager = dagger.get(IRuntimeManager.class);

+	@Inject

+	public RpcFilter(

+			IStoredSettings settings,

+			IRuntimeManager runtimeManager,

+			IAuthenticationManager authenticationManager) {

+

+		super(authenticationManager);

+

+		this.settings = settings;

+		this.runtimeManager = runtimeManager;

 	}

 

 	/**

diff --git a/src/main/java/com/gitblit/servlet/RpcServlet.java b/src/main/java/com/gitblit/servlet/RpcServlet.java
index b8cdfb0..9809a25 100644
--- a/src/main/java/com/gitblit/servlet/RpcServlet.java
+++ b/src/main/java/com/gitblit/servlet/RpcServlet.java
@@ -23,6 +23,8 @@
 import java.util.List;

 import java.util.Map;

 

+import com.google.inject.Inject;

+import com.google.inject.Singleton;

 import javax.servlet.ServletException;

 import javax.servlet.http.HttpServletRequest;

 import javax.servlet.http.HttpServletResponse;

@@ -47,13 +49,12 @@
 import com.gitblit.utils.RpcUtils;

 import com.gitblit.utils.StringUtils;

 

-import dagger.ObjectGraph;

-

 /**

  * Handles remote procedure calls.

  *

  * @author James Moger

  */

+@Singleton

 public class RpcServlet extends JsonServlet {

 

 	private static final long serialVersionUID = 1L;

@@ -64,10 +65,10 @@
 

 	private IGitblit gitblit;

 

-	@Override

-	protected void inject(ObjectGraph dagger) {

-		this.settings = dagger.get(IStoredSettings.class);

-		this.gitblit = dagger.get(IGitblit.class);

+	@Inject

+	public RpcServlet(IStoredSettings settings, IGitblit gitblit) {

+		this.settings = settings;

+		this.gitblit = gitblit;

 	}

 

 	/**

diff --git a/src/main/java/com/gitblit/servlet/SparkleShareInviteServlet.java b/src/main/java/com/gitblit/servlet/SparkleShareInviteServlet.java
index 150dd68..69c254c 100644
--- a/src/main/java/com/gitblit/servlet/SparkleShareInviteServlet.java
+++ b/src/main/java/com/gitblit/servlet/SparkleShareInviteServlet.java
@@ -19,13 +19,15 @@
 import java.net.URL;

 import java.text.MessageFormat;

 

+import com.google.inject.Inject;

+import com.google.inject.Singleton;

 import javax.servlet.ServletException;

+import javax.servlet.http.HttpServlet;

 import javax.servlet.http.HttpServletRequest;

 import javax.servlet.http.HttpServletResponse;

 

 import com.gitblit.IStoredSettings;

 import com.gitblit.Keys;

-import com.gitblit.dagger.DaggerServlet;

 import com.gitblit.manager.IAuthenticationManager;

 import com.gitblit.manager.IRepositoryManager;

 import com.gitblit.manager.IUserManager;

@@ -33,15 +35,14 @@
 import com.gitblit.models.UserModel;

 import com.gitblit.utils.StringUtils;

 

-import dagger.ObjectGraph;

-

 /**

  * Handles requests for Sparkleshare Invites

  *

  * @author James Moger

  *

  */

-public class SparkleShareInviteServlet extends DaggerServlet {

+@Singleton

+public class SparkleShareInviteServlet extends HttpServlet {

 

 	private static final long serialVersionUID = 1L;

 

@@ -53,12 +54,17 @@
 

 	private IRepositoryManager repositoryManager;

 

-	@Override

-	protected void inject(ObjectGraph dagger) {

-		this.settings = dagger.get(IStoredSettings.class);

-		this.userManager = dagger.get(IUserManager.class);

-		this.authenticationManager = dagger.get(IAuthenticationManager.class);

-		this.repositoryManager = dagger.get(IRepositoryManager.class);

+	@Inject

+	public SparkleShareInviteServlet(

+			IStoredSettings settings,

+			IUserManager userManager,

+			IAuthenticationManager authenticationManager,

+			IRepositoryManager repositoryManager) {

+

+		this.settings = settings;

+		this.userManager = userManager;

+		this.authenticationManager = authenticationManager;

+		this.repositoryManager = repositoryManager;

 	}

 

 	@Override

diff --git a/src/main/java/com/gitblit/servlet/SyndicationFilter.java b/src/main/java/com/gitblit/servlet/SyndicationFilter.java
index 78da47e..49348d0 100644
--- a/src/main/java/com/gitblit/servlet/SyndicationFilter.java
+++ b/src/main/java/com/gitblit/servlet/SyndicationFilter.java
@@ -18,8 +18,9 @@
 import java.io.IOException;

 import java.text.MessageFormat;

 

+import com.google.inject.Inject;

+import com.google.inject.Singleton;

 import javax.servlet.FilterChain;

-import javax.servlet.FilterConfig;

 import javax.servlet.ServletException;

 import javax.servlet.ServletRequest;

 import javax.servlet.ServletResponse;

@@ -27,6 +28,7 @@
 import javax.servlet.http.HttpServletResponse;

 

 import com.gitblit.Constants.AccessRestrictionType;

+import com.gitblit.manager.IAuthenticationManager;

 import com.gitblit.manager.IProjectManager;

 import com.gitblit.manager.IRepositoryManager;

 import com.gitblit.manager.IRuntimeManager;

@@ -34,8 +36,6 @@
 import com.gitblit.models.RepositoryModel;

 import com.gitblit.models.UserModel;

 

-import dagger.ObjectGraph;

-

 /**

  * The SyndicationFilter is an AuthenticationFilter which ensures that feed

  * requests for projects or view-restricted repositories have proper authentication

@@ -44,18 +44,24 @@
  * @author James Moger

  *

  */

+@Singleton

 public class SyndicationFilter extends AuthenticationFilter {

 

 	private IRuntimeManager runtimeManager;

 	private IRepositoryManager repositoryManager;

 	private IProjectManager projectManager;

 

-	@Override

-	protected void inject(ObjectGraph dagger, FilterConfig filterConfig) {

-		super.inject(dagger, filterConfig);

-		this.runtimeManager = dagger.get(IRuntimeManager.class);

-		this.repositoryManager = dagger.get(IRepositoryManager.class);

-		this.projectManager = dagger.get(IProjectManager.class);

+	@Inject

+	public SyndicationFilter(

+			IRuntimeManager runtimeManager,

+			IAuthenticationManager authenticationManager,

+			IRepositoryManager repositoryManager,

+			IProjectManager projectManager) {

+		super(authenticationManager);

+

+		this.runtimeManager = runtimeManager;

+		this.repositoryManager = repositoryManager;

+		this.projectManager = projectManager;

 	}

 

 	/**

diff --git a/src/main/java/com/gitblit/servlet/SyndicationServlet.java b/src/main/java/com/gitblit/servlet/SyndicationServlet.java
index 631df78..29db54d 100644
--- a/src/main/java/com/gitblit/servlet/SyndicationServlet.java
+++ b/src/main/java/com/gitblit/servlet/SyndicationServlet.java
@@ -22,6 +22,10 @@
 import java.util.List;

 import java.util.Map;

 

+import com.google.inject.Inject;

+import com.google.inject.Singleton;

+import javax.servlet.http.HttpServlet;

+

 import org.eclipse.jgit.lib.ObjectId;

 import org.eclipse.jgit.lib.Repository;

 import org.eclipse.jgit.revwalk.RevCommit;

@@ -31,7 +35,6 @@
 import com.gitblit.Constants;

 import com.gitblit.IStoredSettings;

 import com.gitblit.Keys;

-import com.gitblit.dagger.DaggerServlet;

 import com.gitblit.manager.IProjectManager;

 import com.gitblit.manager.IRepositoryManager;

 import com.gitblit.models.FeedEntryModel;

@@ -46,8 +49,6 @@
 import com.gitblit.utils.StringUtils;

 import com.gitblit.utils.SyndicationUtils;

 

-import dagger.ObjectGraph;

-

 /**

  * SyndicationServlet generates RSS 2.0 feeds and feed links.

  *

@@ -56,7 +57,8 @@
  * @author James Moger

  *

  */

-public class SyndicationServlet extends DaggerServlet {

+@Singleton

+public class SyndicationServlet extends HttpServlet {

 

 	private static final long serialVersionUID = 1L;

 

@@ -68,11 +70,15 @@
 

 	private IProjectManager projectManager;

 

-	@Override

-	protected void inject(ObjectGraph dagger) {

-		this.settings = dagger.get(IStoredSettings.class);

-		this.repositoryManager = dagger.get(IRepositoryManager.class);

-		this.projectManager = dagger.get(IProjectManager.class);

+	@Inject

+	public SyndicationServlet(

+			IStoredSettings settings,

+			IRepositoryManager repositoryManager,

+			IProjectManager projectManager) {

+

+		this.settings = settings;

+		this.repositoryManager = repositoryManager;

+		this.projectManager = projectManager;

 	}

 

 	/**

diff --git a/src/main/java/com/gitblit/tickets/BranchTicketService.java b/src/main/java/com/gitblit/tickets/BranchTicketService.java
index 8c00055..8a2bc95 100644
--- a/src/main/java/com/gitblit/tickets/BranchTicketService.java
+++ b/src/main/java/com/gitblit/tickets/BranchTicketService.java
@@ -72,6 +72,8 @@
 import com.gitblit.utils.ArrayUtils;
 import com.gitblit.utils.JGitUtils;
 import com.gitblit.utils.StringUtils;
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
 
 /**
  * Implementation of a ticket service based on an orphan branch.  All tickets
@@ -81,6 +83,7 @@
  * @author James Moger
  *
  */
+@Singleton
 public class BranchTicketService extends ITicketService implements RefsChangedListener {
 
 	public static final String BRANCH = "refs/meta/gitblit/tickets";
@@ -91,6 +94,7 @@
 
 	private final Map<String, AtomicLong> lastAssignedId;
 
+	@Inject
 	public BranchTicketService(
 			IRuntimeManager runtimeManager,
 			IPluginManager pluginManager,
@@ -112,6 +116,7 @@
 
 	@Override
 	public BranchTicketService start() {
+		log.info("{} started", getClass().getSimpleName());
 		return this;
 	}
 
diff --git a/src/main/java/com/gitblit/tickets/FileTicketService.java b/src/main/java/com/gitblit/tickets/FileTicketService.java
index b3d8838..c8346d1 100644
--- a/src/main/java/com/gitblit/tickets/FileTicketService.java
+++ b/src/main/java/com/gitblit/tickets/FileTicketService.java
@@ -42,6 +42,8 @@
 import com.gitblit.utils.ArrayUtils;
 import com.gitblit.utils.FileUtils;
 import com.gitblit.utils.StringUtils;
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
 
 /**
  * Implementation of a ticket service based on a directory within the repository.
@@ -51,6 +53,7 @@
  * @author James Moger
  *
  */
+@Singleton
 public class FileTicketService extends ITicketService {
 
 	private static final String JOURNAL = "journal.json";
@@ -59,6 +62,7 @@
 
 	private final Map<String, AtomicLong> lastAssignedId;
 
+	@Inject
 	public FileTicketService(
 			IRuntimeManager runtimeManager,
 			IPluginManager pluginManager,
@@ -77,6 +81,7 @@
 
 	@Override
 	public FileTicketService start() {
+		log.info("{} started", getClass().getSimpleName());
 		return this;
 	}
 
diff --git a/src/main/java/com/gitblit/tickets/ITicketService.java b/src/main/java/com/gitblit/tickets/ITicketService.java
index 4cf099f..5e3e372 100644
--- a/src/main/java/com/gitblit/tickets/ITicketService.java
+++ b/src/main/java/com/gitblit/tickets/ITicketService.java
@@ -36,6 +36,7 @@
 import com.gitblit.IStoredSettings;
 import com.gitblit.Keys;
 import com.gitblit.extensions.TicketHook;
+import com.gitblit.manager.IManager;
 import com.gitblit.manager.INotificationManager;
 import com.gitblit.manager.IPluginManager;
 import com.gitblit.manager.IRepositoryManager;
@@ -63,7 +64,7 @@
  * @author James Moger
  *
  */
-public abstract class ITicketService {
+public abstract class ITicketService implements IManager {
 
 	public static final String SETTING_UPDATE_DIFFSTATS = "migration.updateDiffstats";
 
@@ -176,12 +177,14 @@
 	 * Start the service.
 	 * @since 1.4.0
 	 */
+	@Override
 	public abstract ITicketService start();
 
 	/**
 	 * Stop the service.
 	 * @since 1.4.0
 	 */
+	@Override
 	public final ITicketService stop() {
 		indexer.close();
 		ticketsCache.invalidateAll();
diff --git a/src/main/java/com/gitblit/tickets/NullTicketService.java b/src/main/java/com/gitblit/tickets/NullTicketService.java
index d410cdd..3947b94 100644
--- a/src/main/java/com/gitblit/tickets/NullTicketService.java
+++ b/src/main/java/com/gitblit/tickets/NullTicketService.java
@@ -28,6 +28,8 @@
 import com.gitblit.models.TicketModel;
 import com.gitblit.models.TicketModel.Attachment;
 import com.gitblit.models.TicketModel.Change;
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
 
 /**
  * Implementation of a ticket service that rejects everything.
@@ -35,8 +37,10 @@
  * @author James Moger
  *
  */
+@Singleton
 public class NullTicketService extends ITicketService {
 
+	@Inject
 	public NullTicketService(
 			IRuntimeManager runtimeManager,
 			IPluginManager pluginManager,
@@ -58,6 +62,7 @@
 
 	@Override
 	public NullTicketService start() {
+		log.info("{} started", getClass().getSimpleName());
 		return this;
 	}
 
diff --git a/src/main/java/com/gitblit/tickets/RedisTicketService.java b/src/main/java/com/gitblit/tickets/RedisTicketService.java
index d773b0b..0f9ad17 100644
--- a/src/main/java/com/gitblit/tickets/RedisTicketService.java
+++ b/src/main/java/com/gitblit/tickets/RedisTicketService.java
@@ -43,6 +43,8 @@
 import com.gitblit.models.TicketModel.Change;
 import com.gitblit.utils.ArrayUtils;
 import com.gitblit.utils.StringUtils;
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
 
 /**
  * Implementation of a ticket service based on a Redis key-value store.  All
@@ -53,6 +55,7 @@
  * @author James Moger
  *
  */
+@Singleton
 public class RedisTicketService extends ITicketService {
 
 	private final JedisPool pool;
@@ -61,6 +64,7 @@
 		journal, ticket, counter
 	}
 
+	@Inject
 	public RedisTicketService(
 			IRuntimeManager runtimeManager,
 			IPluginManager pluginManager,
@@ -80,6 +84,10 @@
 
 	@Override
 	public RedisTicketService start() {
+		log.info("{} started", getClass().getSimpleName());
+		if (!isReady()) {
+			log.warn("{} is not ready!", getClass().getSimpleName());
+		}
 		return this;
 	}
 
diff --git a/src/main/java/com/gitblit/transport/ssh/FileKeyManager.java b/src/main/java/com/gitblit/transport/ssh/FileKeyManager.java
index a063dc7..1a2cd68 100644
--- a/src/main/java/com/gitblit/transport/ssh/FileKeyManager.java
+++ b/src/main/java/com/gitblit/transport/ssh/FileKeyManager.java
@@ -29,6 +29,7 @@
 import com.google.common.base.Charsets;
 import com.google.common.base.Joiner;
 import com.google.common.io.Files;
+import com.google.inject.Inject;
 
 /**
  * Manages public keys on the filesystem.
@@ -42,6 +43,7 @@
 
 	protected final Map<File, Long> lastModifieds;
 
+	@Inject
 	public FileKeyManager(IRuntimeManager runtimeManager) {
 		this.runtimeManager = runtimeManager;
 		this.lastModifieds = new ConcurrentHashMap<File, Long>();
diff --git a/src/main/java/com/gitblit/transport/ssh/MemoryKeyManager.java b/src/main/java/com/gitblit/transport/ssh/MemoryKeyManager.java
index 357b34a..bf78378 100644
--- a/src/main/java/com/gitblit/transport/ssh/MemoryKeyManager.java
+++ b/src/main/java/com/gitblit/transport/ssh/MemoryKeyManager.java
@@ -20,6 +20,8 @@
 import java.util.List;
 import java.util.Map;
 
+import com.google.inject.Inject;
+
 /**
  * Memory public key manager.
  *
@@ -30,6 +32,7 @@
 
 	final Map<String, List<SshKey>> keys;
 
+	@Inject
 	public MemoryKeyManager() {
 		keys = new HashMap<String, List<SshKey>>();
 	}
diff --git a/src/main/java/com/gitblit/transport/ssh/NullKeyManager.java b/src/main/java/com/gitblit/transport/ssh/NullKeyManager.java
index 0761d84..fcd3e19 100644
--- a/src/main/java/com/gitblit/transport/ssh/NullKeyManager.java
+++ b/src/main/java/com/gitblit/transport/ssh/NullKeyManager.java
@@ -17,6 +17,8 @@
 
 import java.util.List;
 
+import com.google.inject.Inject;
+
 /**
  * Rejects all public key management requests.
  *
@@ -25,6 +27,7 @@
  */
 public class NullKeyManager extends IPublicKeyManager {
 
+	@Inject
 	public NullKeyManager() {
 	}
 
diff --git a/src/main/java/com/gitblit/wicket/GitBlitWebApp.java b/src/main/java/com/gitblit/wicket/GitBlitWebApp.java
index f63ff3d..036a05a 100644
--- a/src/main/java/com/gitblit/wicket/GitBlitWebApp.java
+++ b/src/main/java/com/gitblit/wicket/GitBlitWebApp.java
@@ -43,6 +43,7 @@
 import com.gitblit.manager.IProjectManager;
 import com.gitblit.manager.IRepositoryManager;
 import com.gitblit.manager.IRuntimeManager;
+import com.gitblit.manager.IServicesManager;
 import com.gitblit.manager.IUserManager;
 import com.gitblit.tickets.ITicketService;
 import com.gitblit.transport.ssh.IPublicKeyManager;
@@ -89,7 +90,11 @@
 import com.gitblit.wicket.pages.TreePage;
 import com.gitblit.wicket.pages.UserPage;
 import com.gitblit.wicket.pages.UsersPage;
+import com.google.inject.Inject;
+import com.google.inject.Provider;
+import com.google.inject.Singleton;
 
+@Singleton
 public class GitBlitWebApp extends WebApplication implements GitblitWicketApp {
 
 	private final Class<? extends WebPage> homePageClass = MyDashboardPage.class;
@@ -98,6 +103,10 @@
 
 	private final Map<String, CacheControl> cacheablePages = new HashMap<String, CacheControl>();
 
+	private final Provider<IPublicKeyManager> publicKeyManagerProvider;
+
+	private final Provider<ITicketService> ticketServiceProvider;
+
 	private final IStoredSettings settings;
 
 	private final IRuntimeManager runtimeManager;
@@ -110,8 +119,6 @@
 
 	private final IAuthenticationManager authenticationManager;
 
-	private final IPublicKeyManager publicKeyManager;
-
 	private final IRepositoryManager repositoryManager;
 
 	private final IProjectManager projectManager;
@@ -120,30 +127,37 @@
 
 	private final IGitblit gitblit;
 
+	private final IServicesManager services;
+
+	@Inject
 	public GitBlitWebApp(
+			Provider<IPublicKeyManager> publicKeyManagerProvider,
+			Provider<ITicketService> ticketServiceProvider,
 			IRuntimeManager runtimeManager,
 			IPluginManager pluginManager,
 			INotificationManager notificationManager,
 			IUserManager userManager,
 			IAuthenticationManager authenticationManager,
-			IPublicKeyManager publicKeyManager,
 			IRepositoryManager repositoryManager,
 			IProjectManager projectManager,
 			IFederationManager federationManager,
-			IGitblit gitblit) {
+			IGitblit gitblit,
+			IServicesManager services) {
 
 		super();
+		this.publicKeyManagerProvider = publicKeyManagerProvider;
+		this.ticketServiceProvider = ticketServiceProvider;
 		this.settings = runtimeManager.getSettings();
 		this.runtimeManager = runtimeManager;
 		this.pluginManager = pluginManager;
 		this.notificationManager = notificationManager;
 		this.userManager = userManager;
 		this.authenticationManager = authenticationManager;
-		this.publicKeyManager = publicKeyManager;
 		this.repositoryManager = repositoryManager;
 		this.projectManager = projectManager;
 		this.federationManager = federationManager;
 		this.gitblit = gitblit;
+		this.services = services;
 	}
 
 	@Override
@@ -380,7 +394,7 @@
 	 */
 	@Override
 	public IPublicKeyManager keys() {
-		return publicKeyManager;
+		return publicKeyManagerProvider.get();
 	}
 
 	/* (non-Javadoc)
@@ -416,11 +430,19 @@
 	}
 
 	/* (non-Javadoc)
+	 * @see com.gitblit.wicket.Webapp#services()
+	 */
+	@Override
+	public IServicesManager services() {
+		return services;
+	}
+
+	/* (non-Javadoc)
 	 * @see com.gitblit.wicket.Webapp#tickets()
 	 */
 	@Override
 	public ITicketService tickets() {
-		return gitblit.getTicketService();
+		return ticketServiceProvider.get();
 	}
 
 	/* (non-Javadoc)
diff --git a/src/main/java/com/gitblit/wicket/GitblitWicketApp.java b/src/main/java/com/gitblit/wicket/GitblitWicketApp.java
index a56e699..7013097 100644
--- a/src/main/java/com/gitblit/wicket/GitblitWicketApp.java
+++ b/src/main/java/com/gitblit/wicket/GitblitWicketApp.java
@@ -14,6 +14,7 @@
 import com.gitblit.manager.IProjectManager;
 import com.gitblit.manager.IRepositoryManager;
 import com.gitblit.manager.IRuntimeManager;
+import com.gitblit.manager.IServicesManager;
 import com.gitblit.manager.IUserManager;
 import com.gitblit.tickets.ITicketService;
 import com.gitblit.transport.ssh.IPublicKeyManager;
@@ -65,6 +66,8 @@
 
 	public abstract IGitblit gitblit();
 
+	public abstract IServicesManager services();
+
 	public abstract ITicketService tickets();
 
 	public abstract TimeZone getTimezone();
diff --git a/src/main/java/com/gitblit/wicket/GitblitWicketFilter.java b/src/main/java/com/gitblit/wicket/GitblitWicketFilter.java
index 7865fb3..68ad84a 100644
--- a/src/main/java/com/gitblit/wicket/GitblitWicketFilter.java
+++ b/src/main/java/com/gitblit/wicket/GitblitWicketFilter.java
@@ -17,6 +17,8 @@
 

 import java.util.Date;

 

+import com.google.inject.Inject;

+import com.google.inject.Singleton;

 import javax.servlet.http.HttpServletRequest;

 

 import org.apache.wicket.protocol.http.IWebApplicationFactory;

@@ -28,7 +30,6 @@
 

 import com.gitblit.IStoredSettings;

 import com.gitblit.Keys;

-import com.gitblit.dagger.DaggerWicketFilter;

 import com.gitblit.manager.IProjectManager;

 import com.gitblit.manager.IRepositoryManager;

 import com.gitblit.manager.IRuntimeManager;

@@ -37,8 +38,6 @@
 import com.gitblit.utils.JGitUtils;

 import com.gitblit.utils.StringUtils;

 

-import dagger.ObjectGraph;

-

 /**

  *

  * Customization of the WicketFilter to allow smart browser-side caching of

@@ -47,7 +46,8 @@
  * @author James Moger

  *

  */

-public class GitblitWicketFilter extends DaggerWicketFilter {

+@Singleton

+public class GitblitWicketFilter extends WicketFilter {

 

 	private IStoredSettings settings;

 

@@ -59,13 +59,19 @@
 

 	private GitBlitWebApp webapp;

 

-	@Override

-	protected void inject(ObjectGraph dagger) {

-		this.settings = dagger.get(IStoredSettings.class);

-		this.runtimeManager = dagger.get(IRuntimeManager.class);

-		this.repositoryManager = dagger.get(IRepositoryManager.class);

-		this.projectManager = dagger.get(IProjectManager.class);

-		this.webapp = dagger.get(GitBlitWebApp.class);

+	@Inject

+	public GitblitWicketFilter(

+			IStoredSettings settings,

+			IRuntimeManager runtimeManager,

+			IRepositoryManager repositoryManager,

+			IProjectManager projectManager,

+			GitBlitWebApp webapp) {

+

+		this.settings = settings;

+		this.runtimeManager = runtimeManager;

+		this.repositoryManager = repositoryManager;

+		this.projectManager = projectManager;

+		this.webapp = webapp;

 	}

 

 	@Override

diff --git a/src/main/java/com/gitblit/wicket/pages/EmptyRepositoryPage.java b/src/main/java/com/gitblit/wicket/pages/EmptyRepositoryPage.java
index b3c5243..72d1e1a 100644
--- a/src/main/java/com/gitblit/wicket/pages/EmptyRepositoryPage.java
+++ b/src/main/java/com/gitblit/wicket/pages/EmptyRepositoryPage.java
@@ -55,7 +55,7 @@
 		}

 

 		HttpServletRequest req = ((WebRequest) getRequest()).getHttpServletRequest();

-		List<RepositoryUrl> repositoryUrls = app().gitblit().getRepositoryUrls(req, user, repository);

+		List<RepositoryUrl> repositoryUrls = app().services().getRepositoryUrls(req, user, repository);

 		RepositoryUrl primaryUrl = repositoryUrls.size() == 0 ? null : repositoryUrls.get(0);

 		String url = primaryUrl != null ? primaryUrl.url : "";

 

diff --git a/src/main/java/com/gitblit/wicket/pages/TicketPage.java b/src/main/java/com/gitblit/wicket/pages/TicketPage.java
index b1f94a5..ca1bf31 100644
--- a/src/main/java/com/gitblit/wicket/pages/TicketPage.java
+++ b/src/main/java/com/gitblit/wicket/pages/TicketPage.java
@@ -1508,7 +1508,7 @@
 	 */

 	protected RepositoryUrl getRepositoryUrl(UserModel user, RepositoryModel repository) {

 		HttpServletRequest req = ((WebRequest) getRequest()).getHttpServletRequest();

-		List<RepositoryUrl> urls = app().gitblit().getRepositoryUrls(req, user, repository);

+		List<RepositoryUrl> urls = app().services().getRepositoryUrls(req, user, repository);

 		if (ArrayUtils.isEmpty(urls)) {

 			return null;

 		}

diff --git a/src/main/java/com/gitblit/wicket/pages/UserPage.java b/src/main/java/com/gitblit/wicket/pages/UserPage.java
index 8931d5e..e21431d 100644
--- a/src/main/java/com/gitblit/wicket/pages/UserPage.java
+++ b/src/main/java/com/gitblit/wicket/pages/UserPage.java
@@ -104,7 +104,7 @@
 		if (isMyProfile) {

 			addPreferences(user);

 

-			if (app().gitblit().isServingSSH()) {

+			if (app().services().isServingSSH()) {

 				// show the SSH key management tab

 				addSshKeys(user);

 			} else {

@@ -248,14 +248,14 @@
 				emailMeOnMyTicketChanges).setVisible(app().notifier().isSendingMail()));

 

 		List<Transport> availableTransports = new ArrayList<>();

-		if (app().gitblit().isServingSSH()) {

+		if (app().services().isServingSSH()) {

 			availableTransports.add(Transport.SSH);

 		}

-		if (app().gitblit().isServingHTTP()) {

+		if (app().services().isServingHTTP()) {

 			availableTransports.add(Transport.HTTPS);

 			availableTransports.add(Transport.HTTP);

 		}

-		if (app().gitblit().isServingGIT()) {

+		if (app().services().isServingGIT()) {

 			availableTransports.add(Transport.GIT);

 		}

 

diff --git a/src/main/java/com/gitblit/wicket/panels/RepositoryUrlPanel.java b/src/main/java/com/gitblit/wicket/panels/RepositoryUrlPanel.java
index 938226a..0666fcd 100644
--- a/src/main/java/com/gitblit/wicket/panels/RepositoryUrlPanel.java
+++ b/src/main/java/com/gitblit/wicket/panels/RepositoryUrlPanel.java
@@ -80,7 +80,7 @@
 

 		HttpServletRequest req = ((WebRequest) getRequest()).getHttpServletRequest();

 

-		List<RepositoryUrl> repositoryUrls = app().gitblit().getRepositoryUrls(req, user, repository);

+		List<RepositoryUrl> repositoryUrls = app().services().getRepositoryUrls(req, user, repository);

 		// grab primary url from the top of the list

 		primaryUrl = repositoryUrls.size() == 0 ? null : repositoryUrls.get(0);

 

@@ -165,7 +165,7 @@
 		if (repository.isMirror) {

 			urlPanel.add(WicketUtils.newImage("accessRestrictionIcon", "mirror_16x16.png",

 					getString("gb.isMirror")));

-		} else if (app().gitblit().isServingRepositories()) {

+		} else if (app().services().isServingRepositories()) {

 			switch (repository.accessRestriction) {

 			case NONE:

 				urlPanel.add(WicketUtils.newClearPixel("accessRestrictionIcon").setVisible(false));

diff --git a/src/site/design.mkd b/src/site/design.mkd
index cd4b1b7..9ef302c 100644
--- a/src/site/design.mkd
+++ b/src/site/design.mkd
@@ -57,6 +57,7 @@
 - [jedis](https://github.com/xetorthio/jedis) (MIT)

 - [Mina SSHD](https://mina.apache.org) (Apache 2.0)

 - [pf4j](https://github.com/decebals/pf4j) (Apache 2.0)

+- [google-guice](https://code.google.com/p/google-guice) (Apache 2.0)

 

 ### Other Build Dependencies

 - [Fancybox image viewer](http://fancybox.net) (MIT and GPL dual-licensed)

diff --git a/src/test/java/com/gitblit/tests/mock/MockRuntimeManager.java b/src/test/java/com/gitblit/tests/mock/MockRuntimeManager.java
index 54be539..9a71c88 100644
--- a/src/test/java/com/gitblit/tests/mock/MockRuntimeManager.java
+++ b/src/test/java/com/gitblit/tests/mock/MockRuntimeManager.java
@@ -28,6 +28,7 @@
 import com.gitblit.models.ServerSettings;
 import com.gitblit.models.ServerStatus;
 import com.gitblit.models.SettingModel;
+import com.google.inject.Injector;
 
 public class MockRuntimeManager implements IRuntimeManager {
 
@@ -57,6 +58,11 @@
 	}
 
 	@Override
+	public Injector getInjector() {
+		return null;
+	}
+
+	@Override
 	public void setBaseFolder(File folder) {
 		this.baseFolder = folder;
 	}
@@ -77,26 +83,6 @@
 	}
 
 	@Override
-	public boolean isServingRepositories() {
-		return true;
-	}
-
-	@Override
-	public boolean isServingHTTP() {
-		return true;
-	}
-
-	@Override
-	public boolean isServingGIT() {
-		return true;
-	}
-
-	@Override
-	public boolean isServingSSH() {
-		return true;
-	}
-
-	@Override
 	public boolean isDebugMode() {
 		return true;
 	}