GitBlit integration into Gerrit as repo viewer.

GitBlit is plugged into the Gerrit Servlet Container with
integration of Gerrit authentication, authorisation and
Git repositories.

[gitweb]
        type = custom
        url = plugins/gitblit-plugin-1.0-SNAPSHOT/
        linkname = GitBlit
        project = summary/${project}
        revision = commit/${project}/${commit}
        branch = log/${project}/${branch}
        filehistory = history/${project}/${branch}/${file}

Change-Id: Ie82658bcbbf308520d48b88057212a683aca16a7
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..77b4e9c
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,7 @@
+/.classpath
+/.project
+/.settings
+/.settings/org.eclipse.jdt.core.prefs
+/.settings/org.maven.ide.eclipse.prefs
+/.idea
+/target
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..11069ed
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,201 @@
+                              Apache License
+                        Version 2.0, January 2004
+                     http://www.apache.org/licenses/
+
+TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+1. Definitions.
+
+   "License" shall mean the terms and conditions for use, reproduction,
+   and distribution as defined by Sections 1 through 9 of this document.
+
+   "Licensor" shall mean the copyright owner or entity authorized by
+   the copyright owner that is granting the License.
+
+   "Legal Entity" shall mean the union of the acting entity and all
+   other entities that control, are controlled by, or are under common
+   control with that entity. For the purposes of this definition,
+   "control" means (i) the power, direct or indirect, to cause the
+   direction or management of such entity, whether by contract or
+   otherwise, or (ii) ownership of fifty percent (50%) or more of the
+   outstanding shares, or (iii) beneficial ownership of such entity.
+
+   "You" (or "Your") shall mean an individual or Legal Entity
+   exercising permissions granted by this License.
+
+   "Source" form shall mean the preferred form for making modifications,
+   including but not limited to software source code, documentation
+   source, and configuration files.
+
+   "Object" form shall mean any form resulting from mechanical
+   transformation or translation of a Source form, including but
+   not limited to compiled object code, generated documentation,
+   and conversions to other media types.
+
+   "Work" shall mean the work of authorship, whether in Source or
+   Object form, made available under the License, as indicated by a
+   copyright notice that is included in or attached to the work
+   (an example is provided in the Appendix below).
+
+   "Derivative Works" shall mean any work, whether in Source or Object
+   form, that is based on (or derived from) the Work and for which the
+   editorial revisions, annotations, elaborations, or other modifications
+   represent, as a whole, an original work of authorship. For the purposes
+   of this License, Derivative Works shall not include works that remain
+   separable from, or merely link (or bind by name) to the interfaces of,
+   the Work and Derivative Works thereof.
+
+   "Contribution" shall mean any work of authorship, including
+   the original version of the Work and any modifications or additions
+   to that Work or Derivative Works thereof, that is intentionally
+   submitted to Licensor for inclusion in the Work by the copyright owner
+   or by an individual or Legal Entity authorized to submit on behalf of
+   the copyright owner. For the purposes of this definition, "submitted"
+   means any form of electronic, verbal, or written communication sent
+   to the Licensor or its representatives, including but not limited to
+   communication on electronic mailing lists, source code control systems,
+   and issue tracking systems that are managed by, or on behalf of, the
+   Licensor for the purpose of discussing and improving the Work, but
+   excluding communication that is conspicuously marked or otherwise
+   designated in writing by the copyright owner as "Not a Contribution."
+
+   "Contributor" shall mean Licensor and any individual or Legal Entity
+   on behalf of whom a Contribution has been received by Licensor and
+   subsequently incorporated within the Work.
+
+2. Grant of Copyright License. Subject to the terms and conditions of
+   this License, each Contributor hereby grants to You a perpetual,
+   worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+   copyright license to reproduce, prepare Derivative Works of,
+   publicly display, publicly perform, sublicense, and distribute the
+   Work and such Derivative Works in Source or Object form.
+
+3. Grant of Patent License. Subject to the terms and conditions of
+   this License, each Contributor hereby grants to You a perpetual,
+   worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+   (except as stated in this section) patent license to make, have made,
+   use, offer to sell, sell, import, and otherwise transfer the Work,
+   where such license applies only to those patent claims licensable
+   by such Contributor that are necessarily infringed by their
+   Contribution(s) alone or by combination of their Contribution(s)
+   with the Work to which such Contribution(s) was submitted. If You
+   institute patent litigation against any entity (including a
+   cross-claim or counterclaim in a lawsuit) alleging that the Work
+   or a Contribution incorporated within the Work constitutes direct
+   or contributory patent infringement, then any patent licenses
+   granted to You under this License for that Work shall terminate
+   as of the date such litigation is filed.
+
+4. Redistribution. You may reproduce and distribute copies of the
+   Work or Derivative Works thereof in any medium, with or without
+   modifications, and in Source or Object form, provided that You
+   meet the following conditions:
+
+   (a) You must give any other recipients of the Work or
+       Derivative Works a copy of this License; and
+
+   (b) You must cause any modified files to carry prominent notices
+       stating that You changed the files; and
+
+   (c) You must retain, in the Source form of any Derivative Works
+       that You distribute, all copyright, patent, trademark, and
+       attribution notices from the Source form of the Work,
+       excluding those notices that do not pertain to any part of
+       the Derivative Works; and
+
+   (d) If the Work includes a "NOTICE" text file as part of its
+       distribution, then any Derivative Works that You distribute must
+       include a readable copy of the attribution notices contained
+       within such NOTICE file, excluding those notices that do not
+       pertain to any part of the Derivative Works, in at least one
+       of the following places: within a NOTICE text file distributed
+       as part of the Derivative Works; within the Source form or
+       documentation, if provided along with the Derivative Works; or,
+       within a display generated by the Derivative Works, if and
+       wherever such third-party notices normally appear. The contents
+       of the NOTICE file are for informational purposes only and
+       do not modify the License. You may add Your own attribution
+       notices within Derivative Works that You distribute, alongside
+       or as an addendum to the NOTICE text from the Work, provided
+       that such additional attribution notices cannot be construed
+       as modifying the License.
+
+   You may add Your own copyright statement to Your modifications and
+   may provide additional or different license terms and conditions
+   for use, reproduction, or distribution of Your modifications, or
+   for any such Derivative Works as a whole, provided Your use,
+   reproduction, and distribution of the Work otherwise complies with
+   the conditions stated in this License.
+
+5. Submission of Contributions. Unless You explicitly state otherwise,
+   any Contribution intentionally submitted for inclusion in the Work
+   by You to the Licensor shall be under the terms and conditions of
+   this License, without any additional terms or conditions.
+   Notwithstanding the above, nothing herein shall supersede or modify
+   the terms of any separate license agreement you may have executed
+   with Licensor regarding such Contributions.
+
+6. Trademarks. This License does not grant permission to use the trade
+   names, trademarks, service marks, or product names of the Licensor,
+   except as required for reasonable and customary use in describing the
+   origin of the Work and reproducing the content of the NOTICE file.
+
+7. Disclaimer of Warranty. Unless required by applicable law or
+   agreed to in writing, Licensor provides the Work (and each
+   Contributor provides its Contributions) on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+   implied, including, without limitation, any warranties or conditions
+   of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+   PARTICULAR PURPOSE. You are solely responsible for determining the
+   appropriateness of using or redistributing the Work and assume any
+   risks associated with Your exercise of permissions under this License.
+
+8. Limitation of Liability. In no event and under no legal theory,
+   whether in tort (including negligence), contract, or otherwise,
+   unless required by applicable law (such as deliberate and grossly
+   negligent acts) or agreed to in writing, shall any Contributor be
+   liable to You for damages, including any direct, indirect, special,
+   incidental, or consequential damages of any character arising as a
+   result of this License or out of the use or inability to use the
+   Work (including but not limited to damages for loss of goodwill,
+   work stoppage, computer failure or malfunction, or any and all
+   other commercial damages or losses), even if such Contributor
+   has been advised of the possibility of such damages.
+
+9. Accepting Warranty or Additional Liability. While redistributing
+   the Work or Derivative Works thereof, You may choose to offer,
+   and charge a fee for, acceptance of support, warranty, indemnity,
+   or other liability obligations and/or rights consistent with this
+   License. However, in accepting such obligations, You may act only
+   on Your own behalf and on Your sole responsibility, not on behalf
+   of any other Contributor, and only if You agree to indemnify,
+   defend, and hold each Contributor harmless for any liability
+   incurred by, or claims asserted against, such Contributor by reason
+   of your accepting any such warranty or additional liability.
+
+END OF TERMS AND CONDITIONS
+
+APPENDIX: How to apply the Apache License to your work.
+
+   To apply the Apache License to your work, attach the following
+   boilerplate notice, with the fields enclosed by brackets "[]"
+   replaced with your own identifying information. (Don't include
+   the brackets!)  The text should be enclosed in the appropriate
+   comment syntax for the file format. We also recommend that a
+   file or class name and description of purpose be included on the
+   same "printed page" as the copyright notice for easier
+   identification within third-party archives.
+
+Copyright [yyyy] [name of copyright owner]
+
+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.
diff --git a/README b/README
new file mode 100644
index 0000000..70ec955
--- /dev/null
+++ b/README
@@ -0,0 +1,15 @@
+GitBlit plugin
+==============
+
+In order to use GitBlit as GitWeb replacement, please apply
+the following configuration to your Gerrit config.
+(assuming plugin was copied as gitblit.jar)
+
+[gitweb]
+        type = custom
+        url = /plugins/gitblit/
+        linkname = gitblit
+        project = summary/${project}.git
+        revision = commit/${project}.git/${commit}
+        branch = log/${project}.git/${branch}
+        filehistory = history/${project}.git/${branch}/${file}
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..c4d7714
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,191 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+<!--
+Copyright (C) 2012 The Android Open Source Project
+
+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.
+-->
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>com.googlesource.gerrit.plugins.gitblit</groupId>
+  <artifactId>gitblit-plugin</artifactId>
+  <description>GitBlit for Gerrit integrated as a plugin</description>
+  <name>Gerrit - GitBlit Plugin</name>
+  <version>1.0-SNAPSHOT</version>
+  <properties>
+    <Gerrit-ApiType>plugin</Gerrit-ApiType>
+    <Gerrit-ApiVersion>2.6-SNAPSHOT</Gerrit-ApiVersion>
+    <Gerrit-ReloadMode>reload</Gerrit-ReloadMode>
+    <Gerrit-InitStep>com.googlesource.gerrit.plugins.gitblit.GitBlitInitStep</Gerrit-InitStep>
+    <Gerrit-HttpModule>com.googlesource.gerrit.plugins.gitblit.GitBlitModule</Gerrit-HttpModule>
+  </properties>
+  <dependencies>
+    <dependency>
+      <groupId>com.google.gerrit</groupId>
+      <artifactId>gerrit-plugin-api</artifactId>
+      <version>${Gerrit-ApiVersion}</version>
+    </dependency>
+    <dependency>
+      <groupId>com.gitblit</groupId>
+      <artifactId>gitblit</artifactId>
+      <version>1.2.0-SNAPSHOT</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.wicket</groupId>
+      <artifactId>wicket-auth-roles</artifactId>
+      <version>1.4.20-selfload</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.wicket</groupId>
+      <artifactId>wicket-extensions</artifactId>
+      <version>1.4.20-selfload</version>
+    </dependency>
+    <dependency>
+      <groupId>org.wicketstuff</groupId>
+      <artifactId>googlecharts</artifactId>
+      <version>1.4.20</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.httpcomponents</groupId>
+      <artifactId>httpcore</artifactId>
+      <version>4.2.1</version>
+    </dependency>
+    <dependency>
+      <groupId>javax.mail</groupId>
+      <artifactId>mail</artifactId>
+      <version>1.4</version>
+    </dependency>
+    <dependency>
+      <groupId>commons-net</groupId>
+      <artifactId>commons-net</artifactId>
+      <scope>provided</scope>
+      <version>3.1</version>
+    </dependency>
+    <dependency>
+      <groupId>org.codehaus.groovy</groupId>
+      <artifactId>groovy-all</artifactId>
+      <version>1.8.6</version>
+    </dependency>
+    <dependency>
+      <groupId>com.beust</groupId>
+      <artifactId>jcommander</artifactId>
+      <version>1.17</version>
+    </dependency>
+    <dependency>
+      <groupId>jdom</groupId>
+      <artifactId>jdom</artifactId>
+      <version>1.0</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.lucene</groupId>
+      <artifactId>lucene-core</artifactId>
+      <version>3.6.0</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.lucene</groupId>
+      <artifactId>lucene-highlighter</artifactId>
+      <version>3.6.0</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.lucene</groupId>
+      <artifactId>lucene-memory</artifactId>
+      <version>3.6.0</version>
+    </dependency>
+    <dependency>
+      <groupId>org.tautua.markdownpapers</groupId>
+      <artifactId>markdownpapers-core</artifactId>
+      <version>1.2.7</version>
+    </dependency>
+    <dependency>
+      <groupId>rome</groupId>
+      <artifactId>rome</artifactId>
+      <version>1.0-selfload</version>
+    </dependency>
+    <dependency>
+      <groupId>com.unboundid</groupId>
+      <artifactId>unboundid-ldapsdk</artifactId>
+      <version>2.3.0</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.wicket</groupId>
+      <artifactId>wicket</artifactId>
+      <version>1.4.20-selfload</version>
+    </dependency>
+  </dependencies>
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-compiler-plugin</artifactId>
+        <version>2.5.1</version>
+        <configuration>
+          <source>1.6</source>
+          <target>1.6</target>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-jar-plugin</artifactId>
+        <version>2.4</version>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-shade-plugin</artifactId>
+        <version>1.6</version>
+        <configuration>
+          <promoteTransitiveDependencies>true</promoteTransitiveDependencies>
+          <artifactSet>
+            <excludes>
+              <exclude>com.google.gerrit:*</exclude>
+              <exclude>org.bouncycastle:*</exclude>
+              <exclude>org.slf4j:*</exclude>
+              <exclude>com.google.guava:*</exclude>
+              <exclude>org.eclipse.jgit:*</exclude>
+            </excludes>
+          </artifactSet>
+          <transformers>
+            <transformer
+              implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
+              <manifestEntries>
+                <Gerrit-HttpModule>${Gerrit-HttpModule}</Gerrit-HttpModule>
+                <Gerrit-InitStep>${Gerrit-InitStep}</Gerrit-InitStep>
+                <Implementation-Vendor>Gerrit Code Review</Implementation-Vendor>
+                <Implementation-URL>http://code.google.com/p/gerrit/</Implementation-URL>
+                <Implementation-Title>Plugin ${project.artifactId}</Implementation-Title>
+                <Implementation-Version>${project.version}</Implementation-Version>
+                <Gerrit-ApiType>${Gerrit-ApiType}</Gerrit-ApiType>
+                <Gerrit-ApiVersion>${Gerrit-ApiVersion}</Gerrit-ApiVersion>
+                <Gerrit-ReloadMode>${Gerrit-ReloadMode}</Gerrit-ReloadMode>
+              </manifestEntries>
+            </transformer>
+          </transformers>
+        </configuration>
+        <executions>
+          <execution>
+            <phase>package</phase>
+            <goals>
+              <goal>shade</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+
+  <repositories>
+    <repository>
+      <id>gerritforge-gitblit-repository</id>
+      <url>http://gerritforge.com/snapshot/</url>
+    </repository>
+  </repositories>
+
+</project>
diff --git a/src/main/java/com/googlesource/gerrit/plugins/gitblit/GerritWicketFilter.java b/src/main/java/com/googlesource/gerrit/plugins/gitblit/GerritWicketFilter.java
new file mode 100644
index 0000000..53b4b56
--- /dev/null
+++ b/src/main/java/com/googlesource/gerrit/plugins/gitblit/GerritWicketFilter.java
@@ -0,0 +1,179 @@
+// Copyright (C) 2012 The Android Open Source Project
+//
+// 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.googlesource.gerrit.plugins.gitblit;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Properties;
+import java.util.Vector;
+
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletContextEvent;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+
+import org.apache.wicket.protocol.http.WicketFilter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.gitblit.Constants;
+import com.gitblit.GitBlit;
+import com.gitblit.IStoredSettings;
+import com.google.gerrit.httpd.WebSession;
+import com.google.gerrit.server.git.LocalDiskRepositoryManager;
+import com.google.inject.Inject;
+import com.google.inject.Provider;
+import com.google.inject.Singleton;
+import com.googlesource.gerrit.plugins.gitblit.app.GerritGitBlit;
+import com.googlesource.gerrit.plugins.gitblit.app.GerritToGitBlitWebApp;
+import com.googlesource.gerrit.plugins.gitblit.app.GitBlitSettings;
+import com.googlesource.gerrit.plugins.gitblit.auth.GerritAuthFilter;
+
+@Singleton
+public class GerritWicketFilter extends WicketFilter {
+  private static final String GITBLIT_REFERENCE_PROPERTIES = "reference.properties";
+
+  private static final Logger log = LoggerFactory
+      .getLogger(GerritWicketFilter.class);
+
+  private final LocalDiskRepositoryManager repoManager;
+  private final Provider<WebSession> webSession;
+  @SuppressWarnings("unused")
+  // We need Guice to create the GerritGitBlit instance
+  private final GerritGitBlit gitBlit;
+  private final GerritAuthFilter gerritAuthFilter;
+
+  @Inject
+  public GerritWicketFilter(final LocalDiskRepositoryManager repoManager,
+      final Provider<WebSession> webSession, final GerritGitBlit gitBlit,
+      final GerritAuthFilter gerritAuthFilter) {
+
+    this.repoManager = repoManager;
+    this.webSession = webSession;
+    this.gitBlit = gitBlit;
+    this.gerritAuthFilter = gerritAuthFilter;
+  }
+
+  @Override
+  public void init(FilterConfig filterConfig) throws ServletException {
+    showGitBlitBanner();
+
+    try {
+      InputStream resin =
+          getClass().getResourceAsStream(GITBLIT_REFERENCE_PROPERTIES);
+      Properties properties = null;
+      try {
+        properties = new Properties();
+        properties.load(resin);
+        properties.put("git.repositoriesFolder", repoManager.getBasePath()
+            .toString());
+      } finally {
+        resin.close();
+      }
+      IStoredSettings settings = new GitBlitSettings(properties);
+      GitBlit.self().configureContext(settings, false);
+      GitBlit.self().contextInitialized(
+          new ServletContextEvent(filterConfig.getServletContext()),
+          getClass().getResourceAsStream(GITBLIT_REFERENCE_PROPERTIES));
+      super.init(new CustomFilterConfig(filterConfig));
+    } catch (Exception e) {
+      throw new ServletException(e);
+    }
+  }
+
+  private void showGitBlitBanner() {
+    log.info(Constants.BORDER);
+    log.info("            _____  _  _    _      _  _  _");
+    log.info("           |  __ \\(_)| |  | |    | |(_)| |");
+    log.info("           | |  \\/ _ | |_ | |__  | | _ | |_");
+    log.info("           | | __ | || __|| '_ \\ | || || __|");
+    log.info("           | |_\\ \\| || |_ | |_) || || || |_");
+    log.info("            \\____/|_| \\__||_.__/ |_||_| \\__|");
+    String submsg = Constants.getGitBlitVersion();
+    int spacing = (Constants.BORDER.length() - submsg.length()) / 2;
+    StringBuilder sb = new StringBuilder();
+    while (spacing > 0) {
+      spacing--;
+      sb.append(' ');
+    }
+    log.info(sb.toString() + submsg);
+    log.info("");
+    log.info(Constants.BORDER);
+  }
+
+  @Override
+  public void doFilter(ServletRequest request, ServletResponse response,
+      FilterChain chain) throws IOException, ServletException {
+    if (gerritAuthFilter.doFilter(webSession, request, response, chain)) {
+      super.doFilter(request, response, chain);
+    }
+  }
+
+  class CustomFilterConfig implements FilterConfig {
+    private final HashMap<String, String> gitBlitParams = getGitblitInitParams();
+    private FilterConfig parentFilterConfig;
+
+    private HashMap<String, String> getGitblitInitParams() {
+      HashMap<String, String> props = new HashMap<String, String>();
+      props.put("applicationClassName", GerritToGitBlitWebApp.class.getName());
+      props.put("filterMappingUrlPattern", "/*");
+      props.put("ignorePaths", "pages/,feed/");
+      return props;
+    }
+
+    public CustomFilterConfig(FilterConfig parent) {
+      this.parentFilterConfig = parent;
+    }
+
+    public String getFilterName() {
+      return "gerritWicketFilter";
+    }
+
+    public ServletContext getServletContext() {
+      return parentFilterConfig.getServletContext();
+    }
+
+    public String getInitParameter(String paramString) {
+      return gitBlitParams.get(paramString);
+    }
+
+    public Enumeration<String> getInitParameterNames() {
+      return new Vector<String>(gitBlitParams.keySet()).elements();
+    }
+
+    class ParamEnum implements Enumeration<String> {
+      Vector<String> items;
+      Iterator<String> iter;
+
+      public ParamEnum(Vector<String> items) {
+        this.items = items;
+        this.iter = this.items.iterator();
+      }
+
+      public boolean hasMoreElements() {
+        return iter.hasNext();
+      }
+
+      public String nextElement() {
+        return iter.next();
+      }
+    }
+  }
+}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/gitblit/GitBlitInitStep.java b/src/main/java/com/googlesource/gerrit/plugins/gitblit/GitBlitInitStep.java
new file mode 100644
index 0000000..0ab8ceb
--- /dev/null
+++ b/src/main/java/com/googlesource/gerrit/plugins/gitblit/GitBlitInitStep.java
@@ -0,0 +1,57 @@
+// Copyright (C) 2012 The Android Open Source Project
+//
+// 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.googlesource.gerrit.plugins.gitblit;
+
+import com.google.gerrit.extensions.annotations.PluginName;
+import com.google.gerrit.pgm.init.InitStep;
+import com.google.gerrit.pgm.init.Section;
+import com.google.gerrit.pgm.init.Section.Factory;
+import com.google.gerrit.pgm.util.ConsoleUI;
+import com.google.inject.Inject;
+
+public class GitBlitInitStep implements InitStep {
+  private final ConsoleUI ui;
+  private final String pluginName;
+  private final Factory sections;
+
+  @Inject
+  public GitBlitInitStep(final ConsoleUI ui, final Section.Factory sections,
+      @PluginName final String pluginName) {
+    this.ui = ui;
+    this.pluginName = pluginName;
+    this.sections = sections;
+  }
+
+  @Override
+  public void run() throws Exception {
+    ui.message("\n");
+    ui.header("GitBlit Integration");
+
+    if(ui.yesno(true, "Do you want to use GitBlit as your GitWeb viewer ?")) {
+      configureGitBlit();
+    }
+  }
+
+  private void configureGitBlit() {
+    Section gitWeb = sections.get("gitweb", null);
+    gitWeb.set("type", "custom");
+    gitWeb.set("url", "plugins/");
+    gitWeb.set("project", pluginName + "/summary/${project}");
+    gitWeb.set("revision", pluginName + "/commit/${project}/${commit}");
+    gitWeb.set("branch", pluginName + "/log/${project}/${branch}");
+    gitWeb.set("filehistory", pluginName + "/history/${project}/${branch}/${file}");
+    gitWeb.string("Link name", "linkname", "GitBlit");
+  }
+
+}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/gitblit/GitBlitModule.java b/src/main/java/com/googlesource/gerrit/plugins/gitblit/GitBlitModule.java
new file mode 100644
index 0000000..2c9ce86
--- /dev/null
+++ b/src/main/java/com/googlesource/gerrit/plugins/gitblit/GitBlitModule.java
@@ -0,0 +1,51 @@
+// Copyright (C) 2012 The Android Open Source Project
+//
+// 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.googlesource.gerrit.plugins.gitblit;
+
+import org.eclipse.jgit.lib.Config;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.gitblit.IUserService;
+import com.google.gerrit.extensions.annotations.PluginName;
+import com.google.gerrit.server.config.GerritServerConfig;
+import com.google.gerrit.server.config.SitePaths;
+import com.google.inject.Inject;
+import com.google.inject.servlet.ServletModule;
+import com.googlesource.gerrit.plugins.gitblit.app.GerritGitBlit;
+import com.googlesource.gerrit.plugins.gitblit.auth.GerritToGitBlitUserService;
+
+public class GitBlitModule extends ServletModule {
+  private static final Logger log = LoggerFactory.getLogger(GitBlitModule.class);
+
+  @Inject
+  public GitBlitModule(@PluginName final String name,
+      @GerritServerConfig final Config gerritConfig, final SitePaths sitePaths) {
+    log.info("Create GitBlitModule with name='" + name);
+  }
+
+  @Override
+  protected void configureServlets() {
+    log.info("Configuring servlet and filters");
+    bind(IUserService.class).to(GerritToGitBlitUserService.class);
+    bind(GerritGitBlit.class);
+
+    serve("/pages/*").with(WrappedPagesServlet.class);
+    serve("/feed/*").with(WrappedSyndicationServlet.class);
+
+    filter("/*").through(GerritWicketFilter.class);
+    filter("/pages/*").through(WrappedPagesFilter.class);
+    filter("/feed/*").through(WrappedSyndicationFilter.class);
+  }
+}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/gitblit/WrappedPagesFilter.java b/src/main/java/com/googlesource/gerrit/plugins/gitblit/WrappedPagesFilter.java
new file mode 100644
index 0000000..ad01de7
--- /dev/null
+++ b/src/main/java/com/googlesource/gerrit/plugins/gitblit/WrappedPagesFilter.java
@@ -0,0 +1,61 @@
+// Copyright (C) 2012 The Android Open Source Project
+//
+// 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.googlesource.gerrit.plugins.gitblit;
+
+import java.io.IOException;
+
+import javax.servlet.FilterChain;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+
+import com.gitblit.PagesFilter;
+import com.gitblit.models.UserModel;
+import com.google.gerrit.httpd.WebSession;
+import com.google.inject.Inject;
+import com.google.inject.Provider;
+import com.google.inject.Singleton;
+import com.googlesource.gerrit.plugins.gitblit.auth.GerritAuthFilter;
+
+@Singleton
+public class WrappedPagesFilter extends PagesFilter {
+  private final GerritAuthFilter gerritAuthFilter;
+  private final Provider<WebSession> webSession;
+
+  @Inject
+  public WrappedPagesFilter(final Provider<WebSession> webSession, final GerritAuthFilter gerritAuthFilter) {
+    super();
+
+    this.webSession = webSession;
+    this.gerritAuthFilter = gerritAuthFilter;
+  }
+
+  @Override
+  public void doFilter(ServletRequest request, ServletResponse response,
+      FilterChain chain) throws IOException, ServletException {
+    if (gerritAuthFilter.doFilter(webSession, request, response, chain)) {
+      super.doFilter(request, response, chain);
+    }
+  }
+
+  @Override
+  protected UserModel getUser(HttpServletRequest httpRequest) {
+    UserModel userModel = gerritAuthFilter.getUser(httpRequest);
+    if (userModel == null)
+      return super.getUser(httpRequest);
+    else
+      return userModel;
+  }
+}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/gitblit/WrappedPagesServlet.java b/src/main/java/com/googlesource/gerrit/plugins/gitblit/WrappedPagesServlet.java
new file mode 100644
index 0000000..13bfcfc
--- /dev/null
+++ b/src/main/java/com/googlesource/gerrit/plugins/gitblit/WrappedPagesServlet.java
@@ -0,0 +1,27 @@
+// Copyright (C) 2012 The Android Open Source Project
+//
+// 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.googlesource.gerrit.plugins.gitblit;
+
+import com.gitblit.PagesServlet;
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
+
+@Singleton
+@SuppressWarnings("serial")
+public class WrappedPagesServlet extends PagesServlet {
+  @Inject
+  public WrappedPagesServlet() {
+   super();
+  }
+}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/gitblit/WrappedSyndicationFilter.java b/src/main/java/com/googlesource/gerrit/plugins/gitblit/WrappedSyndicationFilter.java
new file mode 100644
index 0000000..d86a268
--- /dev/null
+++ b/src/main/java/com/googlesource/gerrit/plugins/gitblit/WrappedSyndicationFilter.java
@@ -0,0 +1,62 @@
+// Copyright (C) 2012 The Android Open Source Project
+//
+// 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.googlesource.gerrit.plugins.gitblit;
+
+import java.io.IOException;
+
+import javax.servlet.FilterChain;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+
+import com.gitblit.SyndicationFilter;
+import com.gitblit.models.UserModel;
+import com.google.gerrit.httpd.WebSession;
+import com.google.inject.Inject;
+import com.google.inject.Provider;
+import com.google.inject.Singleton;
+import com.googlesource.gerrit.plugins.gitblit.auth.GerritAuthFilter;
+
+@Singleton
+public class WrappedSyndicationFilter extends SyndicationFilter {
+  @Inject
+  private GerritAuthFilter gerritAuthFilter;
+
+  @Inject
+  private final Provider<WebSession> webSession;
+
+  @Inject
+  public WrappedSyndicationFilter(final Provider<WebSession> webSession) {
+    super();
+    this.webSession = webSession;
+  }
+
+  @Override
+  public void doFilter(ServletRequest request, ServletResponse response,
+      FilterChain chain) throws IOException, ServletException {
+    if (gerritAuthFilter.doFilter(webSession, request, response, chain)) {
+      super.doFilter(request, response, chain);
+    }
+  }
+
+  @Override
+  protected UserModel getUser(HttpServletRequest httpRequest) {
+    UserModel userModel = gerritAuthFilter.getUser(httpRequest);
+    if (userModel == null)
+      return super.getUser(httpRequest);
+    else
+      return userModel;
+  }
+}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/gitblit/WrappedSyndicationServlet.java b/src/main/java/com/googlesource/gerrit/plugins/gitblit/WrappedSyndicationServlet.java
new file mode 100644
index 0000000..8560b74
--- /dev/null
+++ b/src/main/java/com/googlesource/gerrit/plugins/gitblit/WrappedSyndicationServlet.java
@@ -0,0 +1,27 @@
+// Copyright (C) 2012 The Android Open Source Project
+//
+// 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.googlesource.gerrit.plugins.gitblit;
+
+import com.gitblit.SyndicationServlet;
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
+
+@Singleton
+@SuppressWarnings("serial")
+public class WrappedSyndicationServlet extends SyndicationServlet {
+  @Inject
+  public WrappedSyndicationServlet() {
+    super();
+  }
+}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/gitblit/app/GerritGitBlit.java b/src/main/java/com/googlesource/gerrit/plugins/gitblit/app/GerritGitBlit.java
new file mode 100644
index 0000000..6e1fe55
--- /dev/null
+++ b/src/main/java/com/googlesource/gerrit/plugins/gitblit/app/GerritGitBlit.java
@@ -0,0 +1,59 @@
+// Copyright (C) 2012 The Android Open Source Project
+//
+// 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.googlesource.gerrit.plugins.gitblit.app;
+
+import java.io.InputStream;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.wicket.util.resource.ResourceStreamNotFoundException;
+
+import com.gitblit.GitBlit;
+import com.gitblit.models.UserModel;
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
+import com.googlesource.gerrit.plugins.gitblit.auth.GerritToGitBlitUserService;
+
+@Singleton
+public class GerritGitBlit extends GitBlit {
+
+  @Inject
+  public GerritGitBlit(GerritToGitBlitUserService userService) {
+    super(userService);
+  }
+
+  public UserModel authenticate(HttpServletRequest request) {
+    String user = (String) request.getAttribute("gerrit-username");
+    String token = (String) request.getAttribute("gerrit-token");
+    if (token == null) {
+      return null;
+    }
+
+    return GitBlit.self().authenticate(user,
+        (GerritToGitBlitUserService.SESSIONAUTH + token).toCharArray());
+  }
+
+  @Override
+  public InputStream getResourceAsStream(String file)
+      throws ResourceStreamNotFoundException {
+    String resourceName = "/static/" + file;
+    InputStream is = getClass().getResourceAsStream(resourceName);
+    if (is == null) {
+      throw new ResourceStreamNotFoundException("Cannot access resource "
+          + resourceName + " using class-loader " + getClass().getClassLoader());
+    }
+
+    return is;
+  }
+}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/gitblit/app/GerritToGitBlitWebApp.java b/src/main/java/com/googlesource/gerrit/plugins/gitblit/app/GerritToGitBlitWebApp.java
new file mode 100644
index 0000000..d291279
--- /dev/null
+++ b/src/main/java/com/googlesource/gerrit/plugins/gitblit/app/GerritToGitBlitWebApp.java
@@ -0,0 +1,31 @@
+// Copyright (C) 2012 The Android Open Source Project
+//
+// 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.googlesource.gerrit.plugins.gitblit.app;
+
+import org.apache.wicket.protocol.http.WebRequestCycleProcessor;
+import org.apache.wicket.request.IRequestCodingStrategy;
+import org.apache.wicket.request.IRequestCycleProcessor;
+
+import com.gitblit.wicket.GitBlitWebApp;
+
+public class GerritToGitBlitWebApp extends GitBlitWebApp {
+    @Override
+    protected IRequestCycleProcessor newRequestCycleProcessor() {
+        return new WebRequestCycleProcessor() {
+            protected IRequestCodingStrategy newRequestCodingStrategy() {
+                return new StaticCodingStrategy();
+            }
+        };
+    }
+}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/gitblit/app/GitBlitSettings.java b/src/main/java/com/googlesource/gerrit/plugins/gitblit/app/GitBlitSettings.java
new file mode 100644
index 0000000..f11e715
--- /dev/null
+++ b/src/main/java/com/googlesource/gerrit/plugins/gitblit/app/GitBlitSettings.java
@@ -0,0 +1,39 @@
+// Copyright (C) 2012 The Android Open Source Project
+//
+// 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.googlesource.gerrit.plugins.gitblit.app;
+
+import java.util.Map;
+import java.util.Properties;
+
+import com.gitblit.IStoredSettings;
+
+public class GitBlitSettings extends IStoredSettings {
+  private Properties properties;
+
+  public GitBlitSettings(Properties properties) {
+    super(GitBlitSettings.class);
+    this.properties = properties;
+  }
+
+  @Override
+  protected Properties read() {
+    return properties;
+  }
+
+  @Override
+  public boolean saveSettings(Map<String, String> updatedSettings) {
+    properties.putAll(updatedSettings);
+    return true;
+  }
+}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/gitblit/app/StaticCodingStrategy.java b/src/main/java/com/googlesource/gerrit/plugins/gitblit/app/StaticCodingStrategy.java
new file mode 100644
index 0000000..5dd9e5f
--- /dev/null
+++ b/src/main/java/com/googlesource/gerrit/plugins/gitblit/app/StaticCodingStrategy.java
@@ -0,0 +1,65 @@
+//Copyright (C) 2012 The Android Open Source Project
+//
+//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.googlesource.gerrit.plugins.gitblit.app;
+
+import org.apache.wicket.Request;
+import org.apache.wicket.RequestCycle;
+import org.apache.wicket.protocol.http.request.WebRequestCodingStrategy;
+import org.apache.wicket.protocol.http.servlet.ServletWebRequest;
+
+public class StaticCodingStrategy extends WebRequestCodingStrategy {
+
+  @Override
+  public String rewriteStaticRelativeUrl(String url) {
+    // Avoid rewriting of non-static resources
+    String[] urlParts = url.split("/");
+    if (urlParts[urlParts.length - 1].indexOf('.') < 0) {
+      return url;
+    }
+
+    int depth =
+        ((ServletWebRequest) RequestCycle.get().getRequest())
+            .getDepthRelativeToWicketHandler();
+    return getRelativeStaticUrl(url, depth);
+  }
+
+  public static String getRelativePrefix(Request request) {
+    int depth = ((ServletWebRequest) request).getDepthRelativeToWicketHandler();
+
+    StringBuffer urlBuffer = new StringBuffer();
+    for (; depth > 0; depth--) {
+      urlBuffer.append("../");
+    }
+
+    return urlBuffer.toString();
+  }
+
+  public static String getStaticRelativePrefix(Request request) {
+    int depth = ((ServletWebRequest) request).getDepthRelativeToWicketHandler();
+    return getRelativeStaticUrl("", depth);
+  }
+
+  public static String getRelativeStaticUrl(String url, int depth) {
+    StringBuffer urlBuffer = new StringBuffer();
+    for (; depth > 0; depth--) {
+      urlBuffer.append("../");
+    }
+    urlBuffer.append("static/"); // tells to Gerrit plugin runtime to load
+                                 // static resources from gitblit plugin jar
+                                 // file
+    urlBuffer.append(url);
+
+    return urlBuffer.toString();
+  }
+}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/gitblit/auth/GerritAuthFilter.java b/src/main/java/com/googlesource/gerrit/plugins/gitblit/auth/GerritAuthFilter.java
new file mode 100644
index 0000000..81ff438
--- /dev/null
+++ b/src/main/java/com/googlesource/gerrit/plugins/gitblit/auth/GerritAuthFilter.java
@@ -0,0 +1,77 @@
+// Copyright (C) 2012 The Android Open Source Project
+//
+// 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.googlesource.gerrit.plugins.gitblit.auth;
+
+import java.io.IOException;
+import java.net.HttpURLConnection;
+
+import javax.servlet.FilterChain;
+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.GitBlit;
+import com.gitblit.models.UserModel;
+import com.google.gerrit.httpd.WebSession;
+import com.google.inject.Provider;
+
+public class GerritAuthFilter {
+
+  /**
+   * Returns the user making the request, if the user has authenticated.
+   * @param httpRequest
+   * @return user
+   */
+  public UserModel getUser(HttpServletRequest httpRequest) {
+    UserModel user = null;
+    String username = (String) httpRequest.getAttribute("gerrit-username");
+    String token = (String) httpRequest.getAttribute("gerrit-token");
+
+    if (token == null || username == null) {
+      return null;
+    }
+
+    user =
+        GitBlit.self().authenticate(username,
+            (GerritToGitBlitUserService.SESSIONAUTH + token).toCharArray());
+    if (user != null) {
+      return user;
+    }
+
+    return null;
+  }
+
+  public boolean doFilter(final Provider<WebSession> webSession,
+      ServletRequest request, ServletResponse response, FilterChain chain)
+      throws IOException, ServletException {
+    HttpServletRequest httpRequest = (HttpServletRequest) request;
+    HttpServletResponse httpResponse = (HttpServletResponse) response;
+
+    if (webSession.get().isSignedIn()
+        || httpRequest.getHeader("Authorization") != null) {
+      request.setAttribute("gerrit-username", webSession.get().getCurrentUser()
+          .getUserName());
+      request.setAttribute("gerrit-token", webSession.get().getToken());
+      return true;
+    } else {
+      httpResponse.setStatus(HttpURLConnection.HTTP_UNAUTHORIZED);
+      httpResponse.setHeader("WWW-Authenticate",
+          "Basic realm=\"Gerrit Code Review\"");
+      return false;
+    }
+  }
+
+}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/gitblit/auth/GerritToGitBlitUserModel.java b/src/main/java/com/googlesource/gerrit/plugins/gitblit/auth/GerritToGitBlitUserModel.java
new file mode 100644
index 0000000..fa5e377
--- /dev/null
+++ b/src/main/java/com/googlesource/gerrit/plugins/gitblit/auth/GerritToGitBlitUserModel.java
@@ -0,0 +1,215 @@
+// Copyright (C) 2012 The Android Open Source Project
+//
+// 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.googlesource.gerrit.plugins.gitblit.auth;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import com.gitblit.Constants.AccessPermission;
+import com.gitblit.Constants.AccessRestrictionType;
+import com.gitblit.models.RepositoryModel;
+import com.gitblit.models.TeamModel;
+import com.gitblit.models.UserModel;
+import com.gitblit.utils.StringUtils;
+import com.google.gerrit.reviewdb.client.Project.NameKey;
+import com.google.gerrit.server.project.NoSuchProjectException;
+import com.google.gerrit.server.project.ProjectControl;
+import com.google.gerrit.server.project.RefControl;
+
+public class GerritToGitBlitUserModel extends UserModel {
+
+  private static final long serialVersionUID = 1L;
+
+  // field names are reflectively mapped in EditUser page
+  public String username;
+  public String password;
+  public String cookie;
+  public String displayName;
+  public String emailAddress;
+  public boolean canAdmin;
+  public boolean excludeFromFederation;
+  public final Set<String> repositories = new HashSet<String>();
+  public final Set<TeamModel> teams = new HashSet<TeamModel>();
+
+  private transient final ProjectControl.Factory projectControlFactory;
+
+  // non-persisted fields
+  public boolean isAuthenticated;
+
+  public GerritToGitBlitUserModel(String username) {
+    this(username, null);
+  }
+
+  public GerritToGitBlitUserModel(String username,
+      final ProjectControl.Factory projectControlFactory) {
+    super(username);
+    this.username = username;
+    this.isAuthenticated = true;
+    this.projectControlFactory = projectControlFactory;
+  }
+
+  @Deprecated
+  public boolean canAccessRepository(String repositoryName) {
+    boolean result = false;
+
+    try {
+      ProjectControl control =
+          projectControlFactory.validateFor(new NameKey(repositoryName));
+      result = control != null;
+    } catch (NoSuchProjectException e) {
+      result = false;
+    }
+
+    return result;
+  }
+
+  @Override
+  protected boolean canAccess(RepositoryModel repository,
+      AccessRestrictionType ifRestriction, AccessPermission requirePermission) {
+    boolean result = false;
+
+    try {
+      ProjectControl control =
+          projectControlFactory.validateFor(new NameKey(
+              getRepositoryName(repository.name)));
+
+      if (control == null) {
+        return false;
+      }
+
+      switch (ifRestriction) {
+        case VIEW:
+          return control.isVisible();
+        case CLONE:
+          return control.canRunUploadPack();
+        case PUSH:
+          return control.canRunReceivePack();
+        default:
+          return true;
+      }
+    } catch (NoSuchProjectException e) {
+      result = false;
+    }
+
+    return result;
+  }
+
+  public String getRepositoryName(String name) {
+    if (name.endsWith(".git")) {
+      name = name.substring(0, name.length() - 4);
+    }
+    return name;
+  }
+
+  @Override
+  public boolean hasRepositoryPermission(String name) {
+    boolean result = false;
+
+    try {
+      name = getRepositoryName(name);
+      ProjectControl control =
+          projectControlFactory.validateFor(new NameKey(name));
+      result = control != null && control.isVisible();
+    } catch (NoSuchProjectException e) {
+      result = false;
+    }
+
+    return result;
+  }
+
+  @Override
+  public boolean hasBranchPermission(String repoName, String branchRef) {
+    boolean result = false;
+
+    try {
+      repoName = getRepositoryName(repoName);
+
+      ProjectControl control =
+          projectControlFactory.validateFor(new NameKey(repoName));
+      if (control != null && control.isVisible()) {
+        RefControl branchCtrl = control.controlForRef(branchRef);
+        result = branchCtrl != null && branchCtrl.isVisible();
+      }
+
+    } catch (NoSuchProjectException e) {
+      result = false;
+    }
+
+    return result;
+  }
+
+  public boolean hasTeamAccess(String repositoryName) {
+    for (TeamModel team : teams) {
+      if (team.hasRepository(repositoryName)) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  public boolean hasRepository(String name) {
+    return repositories.contains(name.toLowerCase());
+  }
+
+  public void addRepository(String name) {
+    repositories.add(name.toLowerCase());
+  }
+
+  public void removeRepository(String name) {
+    repositories.remove(name.toLowerCase());
+  }
+
+  public boolean isTeamMember(String teamname) {
+    for (TeamModel team : teams) {
+      if (team.name.equalsIgnoreCase(teamname)) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  public TeamModel getTeam(String teamname) {
+    if (teams == null) {
+      return null;
+    }
+    for (TeamModel team : teams) {
+      if (team.name.equalsIgnoreCase(teamname)) {
+        return team;
+      }
+    }
+    return null;
+  }
+
+  @Override
+  public String getName() {
+    return username;
+  }
+
+  public String getDisplayName() {
+    if (StringUtils.isEmpty(displayName)) {
+      return username;
+    }
+    return displayName;
+  }
+
+  @Override
+  public String toString() {
+    return username;
+  }
+
+  @Override
+  public int compareTo(UserModel o) {
+    return username.compareTo(o.username);
+  }
+}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/gitblit/auth/GerritToGitBlitUserService.java b/src/main/java/com/googlesource/gerrit/plugins/gitblit/auth/GerritToGitBlitUserService.java
new file mode 100644
index 0000000..2a3e774
--- /dev/null
+++ b/src/main/java/com/googlesource/gerrit/plugins/gitblit/auth/GerritToGitBlitUserService.java
@@ -0,0 +1,269 @@
+// Copyright (C) 2012 The Android Open Source Project
+//
+// 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.googlesource.gerrit.plugins.gitblit.auth;
+
+import java.util.List;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.gitblit.IStoredSettings;
+import com.gitblit.IUserService;
+import com.gitblit.models.TeamModel;
+import com.gitblit.models.UserModel;
+import com.google.common.base.Strings;
+import com.google.gerrit.httpd.WebSession;
+import com.google.gerrit.server.account.AccountException;
+import com.google.gerrit.server.account.AccountManager;
+import com.google.gerrit.server.account.AuthMethod;
+import com.google.gerrit.server.account.AuthRequest;
+import com.google.gerrit.server.account.AuthResult;
+import com.google.gerrit.server.project.ProjectControl;
+import com.google.inject.Inject;
+import com.google.inject.Provider;
+import com.google.inject.Singleton;
+
+@Singleton
+public class GerritToGitBlitUserService implements IUserService {
+  private static final Logger log = LoggerFactory
+      .getLogger(GerritToGitBlitUserService.class);
+
+  private final ProjectControl.Factory projectControl;
+  private AccountManager accountManager;
+
+  private Provider<WebSession> webSession;
+
+  public static final String SESSIONAUTH = "sessionid:";
+
+  @Inject
+  public GerritToGitBlitUserService(
+      final ProjectControl.Factory projectControl,
+      AccountManager accountManager, final Provider<WebSession> webSession) {
+    this.projectControl = projectControl;
+    this.accountManager = accountManager;
+    this.webSession = webSession;
+  }
+
+  @Override
+  public UserModel authenticate(String username, char[] password) {
+    String passwordString = new String(password);
+
+    if (passwordString.startsWith(GerritToGitBlitUserService.SESSIONAUTH)) {
+      return authenticateSSO(username,
+          passwordString.substring(GerritToGitBlitUserService.SESSIONAUTH
+              .length()));
+    } else {
+      return authenticateBasicAuth(username, passwordString);
+    }
+  }
+
+  public UserModel authenticateSSO(String username, String sessionToken) {
+    WebSession session = webSession.get();
+
+    if (session.getToken() == null || !session.getToken().equals(sessionToken)) {
+      log.warn("Invalid Gerrit session token for user '" + username + "'");
+      return null;
+    }
+
+    if (!session.isSignedIn()) {
+      log.warn("Gerrit session " + session.getToken() + " is not signed-in");
+      return null;
+    }
+
+    if (!session.getCurrentUser().getUserName().equals(username)) {
+      log.warn("Gerrit session " + session.getToken()
+          + " is not assigned to user " + username);
+      return null;
+    }
+
+    return new GerritToGitBlitUserModel(username, projectControl);
+  }
+
+  public UserModel authenticateBasicAuth(String username, String password) {
+    if (Strings.isNullOrEmpty(username) || password == null
+        || password.length() <= 0) {
+      log.warn("Authentication failed: no username or password specified");
+      return null;
+    }
+
+    AuthRequest who = AuthRequest.forUser(username);
+    who.setPassword(new String(password));
+
+    try {
+      AuthResult authResp = accountManager.authenticate(who);
+      webSession.get().login(authResp, AuthMethod.PASSWORD, false);
+    } catch (AccountException e) {
+      log.warn("Authentication failed for '" + username + "'", e);
+      return null;
+    }
+
+    return new GerritToGitBlitUserModel(username, projectControl);
+  }
+
+  @Override
+  public UserModel getUserModel(String username) {
+
+    return new GerritToGitBlitUserModel(username, projectControl);
+  }
+
+  @Override
+  public boolean supportsCookies() {
+    return false;
+  }
+
+  @Override
+  public void setup(IStoredSettings settings) {
+  }
+
+  @Override
+  public boolean supportsCredentialChanges() {
+    return false;
+  }
+
+  @Override
+  public boolean supportsDisplayNameChanges() {
+    return false;
+  }
+
+  @Override
+  public boolean supportsEmailAddressChanges() {
+    return false;
+  }
+
+  @Override
+  public boolean supportsTeamMembershipChanges() {
+    return false;
+  }
+
+  @Override
+  public String getCookie(UserModel model) {
+    return model.cookie;
+  }
+
+  @Override
+  public UserModel authenticate(char[] cookie) {
+    return null;
+  }
+
+  @Override
+  public void logout(UserModel user) {
+  }
+
+  @Override
+  public boolean updateUserModel(UserModel model) {
+    return false;
+  }
+
+  @Override
+  public boolean updateUserModel(String username, UserModel model) {
+    return false;
+  }
+
+  @Override
+  public boolean deleteUserModel(UserModel model) {
+    return false;
+  }
+
+  @Override
+  public boolean deleteUser(String username) {
+    return false;
+  }
+
+  @Override
+  public List<String> getAllUsernames() {
+    return null;
+  }
+
+  @Override
+  public List<UserModel> getAllUsers() {
+    return null;
+  }
+
+  @Override
+  public List<String> getAllTeamNames() {
+    return null;
+  }
+
+  @Override
+  public List<TeamModel> getAllTeams() {
+    return null;
+  }
+
+  @Override
+  public List<String> getTeamnamesForRepositoryRole(String role) {
+    return null;
+  }
+
+  @Override
+  public boolean setTeamnamesForRepositoryRole(String role,
+      List<String> teamnames) {
+    return false;
+  }
+
+  @Override
+  public TeamModel getTeamModel(String teamname) {
+    return null;
+  }
+
+  @Override
+  public boolean updateTeamModel(TeamModel model) {
+    return false;
+  }
+
+  @Override
+  public boolean updateTeamModel(String teamname, TeamModel model) {
+    return false;
+  }
+
+  @Override
+  public boolean deleteTeamModel(TeamModel model) {
+    return false;
+  }
+
+  @Override
+  public boolean deleteTeam(String teamname) {
+    return false;
+  }
+
+  @Override
+  public List<String> getUsernamesForRepositoryRole(String role) {
+    return null;
+  }
+
+  @Override
+  public boolean setUsernamesForRepositoryRole(String role,
+      List<String> usernames) {
+    return false;
+  }
+
+  @Override
+  public boolean renameRepositoryRole(String oldRole, String newRole) {
+    return false;
+  }
+
+  @Override
+  public boolean deleteRepositoryRole(String role) {
+    return false;
+  }
+
+  @Override
+  public boolean updateUserModels(List<UserModel> models) {
+    return false;
+  }
+
+  @Override
+  public boolean updateTeamModels(List<TeamModel> models) {
+    return false;
+  }
+}
diff --git a/src/main/resources/com/googlesource/gerrit/plugins/gitblit/reference.properties b/src/main/resources/com/googlesource/gerrit/plugins/gitblit/reference.properties
new file mode 100644
index 0000000..98b109c
--- /dev/null
+++ b/src/main/resources/com/googlesource/gerrit/plugins/gitblit/reference.properties
@@ -0,0 +1,1017 @@
+#
+# Git Servlet Settings
+#
+
+# Base folder for repositories.
+# This folder may contain bare and non-bare repositories but Gitblit will only
+# allow you to push to bare repositories.
+# Use forward slashes even on Windows!!
+# e.g. c:/gitrepos
+#
+# SINCE 0.5.0
+# RESTART REQUIRED
+#git.repositoriesFolder = /Users/simone/Documents/workspace/gerritent/test/git
+
+# Search the repositories folder subfolders for other repositories.
+# Repositories MAY NOT be nested (i.e. one repository within another)
+# but they may be grouped together in subfolders.
+# e.g. c:/gitrepos/libraries/mylibrary.git
+#      c:/gitrepos/libraries/myotherlibrary.git
+#
+# SINCE 0.5.0
+git.searchRepositoriesSubfolders = true
+
+# Maximum number of folders to recurse into when searching for repositories.
+# The default value, -1, disables depth limits.
+#
+# SINCE 1.0.1
+git.searchRecursionDepth = -1
+
+# List of regex exclusion patterns to match against folders found in
+# *git.repositoriesFolder*.
+# Use forward slashes even on Windows!!
+# e.g. test/jgit\.git
+#
+# SPACE-DELIMITED
+# CASE-SENSITIVE
+# SINCE 1.0.1
+git.searchExclusions =
+
+# List of regex url patterns for extracting a repository name when locating
+# submodules.
+#   e.g. git.submoduleUrlPatterns = .*?://github.com/(.*) will extract
+#   *gitblit/gitblit.git* from *git://github.com/gitblit/gitblit.git*
+# If no matches are found then the submodule repository name is assumed to be
+# whatever trails the last / character. (e.g. gitblit.git).
+#
+# SPACE-DELIMITED
+# CASE-SENSITIVE
+# SINCE 1.0.1
+git.submoduleUrlPatterns = .*?://github.com/(.*)
+
+# Allow push/pull over http/https with JGit servlet.
+# If you do NOT want to allow Git clients to clone/push to Gitblit set this
+# to false.  You might want to do this if you are only using ssh:// or git://.
+# If you set this false, consider changing the *web.otherUrls* setting to
+# indicate your clone/push urls.
+#
+# SINCE 0.5.0
+git.enableGitServlet = false
+
+# Only serve/display bare repositories.
+# If there are non-bare repositories in git.repositoriesFolder and this setting
+# is true, they will be excluded from the ui. 
+#
+# SINCE 0.9.0
+git.onlyAccessBareRepositories = false
+
+# The default access restriction for new repositories.
+# Valid values are NONE, PUSH, CLONE, VIEW
+#  NONE = anonymous view, clone, & push
+#  PUSH = anonymous view & clone and authenticated push
+#  CLONE = anonymous view, authenticated clone & push
+#  VIEW = authenticated view, clone, & push
+#
+# SINCE 1.0.0
+git.defaultAccessRestriction = VIEW
+
+# The default authorization control for new repositories.
+# Valid values are AUTHENTICATED and NAMED
+#  AUTHENTICATED = any authenticated user is granted restricted access
+#  NAMED = only named users/teams are granted restricted access
+#
+# SINCE 1.0.1
+git.defaultAuthorizationControl = NAMED
+
+# Number of bytes of a pack file to load into memory in a single read operation.
+# This is the "page size" of the JGit buffer cache, used for all pack access
+# operations. All disk IO occurs as single window reads. Setting this too large
+# may cause the process to load more data than is required; setting this too small
+# may increase the frequency of read() system calls.
+#
+# Default on JGit is 8 KiB on all platforms.
+#
+# Common unit suffixes of k, m, or g are supported.
+# Documentation courtesy of the Gerrit project.
+#
+# SINCE 1.0.0
+# RESTART REQUIRED
+git.packedGitWindowSize = 8k
+
+# Maximum number of bytes to load and cache in memory from pack files. If JGit
+# needs to access more than this many bytes it will unload less frequently used
+# windows to reclaim memory space within the process. As this buffer must be shared
+# with the rest of the JVM heap, it should be a fraction of the total memory available.
+#
+# The JGit team recommends setting this value larger than the size of your biggest
+# repository. This ensures you can serve most requests from memory.
+#
+# Default on JGit is 10 MiB on all platforms.
+#
+# Common unit suffixes of k, m, or g are supported.
+# Documentation courtesy of the Gerrit project.
+#
+# SINCE 1.0.0
+# RESTART REQUIRED
+git.packedGitLimit = 10m
+
+# Maximum number of bytes to reserve for caching base objects that multiple deltafied
+# objects reference. By storing the entire decompressed base object in a cache Git
+# is able to avoid unpacking and decompressing frequently used base objects multiple times.
+#
+# Default on JGit is 10 MiB on all platforms. You probably do not need to adjust
+# this value.
+#
+# Common unit suffixes of k, m, or g are supported.
+# Documentation courtesy of the Gerrit project.
+#
+# SINCE 1.0.0
+# RESTART REQUIRED
+git.deltaBaseCacheLimit = 10m
+
+# Maximum number of pack files to have open at once. A pack file must be opened
+# in order for any of its data to be available in a cached window.
+#
+# If you increase this to a larger setting you may need to also adjust the ulimit
+# on file descriptors for the host JVM, as Gitblit needs additional file descriptors
+# available for network sockets and other repository data manipulation.
+#
+# Default on JGit is 128 file descriptors on all platforms.
+# Documentation courtesy of the Gerrit project.
+#
+# SINCE 1.0.0
+# RESTART REQUIRED
+git.packedGitOpenFiles = 128
+
+# Largest object size, in bytes, that JGit will allocate as a contiguous byte
+# array. Any file revision larger than this threshold will have to be streamed,
+# typically requiring the use of temporary files under $GIT_DIR/objects to implement
+# psuedo-random access during delta decompression.
+#
+# Servers with very high traffic should set this to be larger than the size of
+# their common big files. For example a server managing the Android platform
+# typically has to deal with ~10-12 MiB XML files, so 15 m would be a reasonable
+# setting in that environment. Setting this too high may cause the JVM to run out
+# of heap space when handling very big binary files, such as device firmware or
+# CD-ROM ISO images. Make sure to adjust your JVM heap accordingly. 
+#
+# Default is 50 MiB on all platforms.
+#
+# Common unit suffixes of k, m, or g are supported.
+# Documentation courtesy of the Gerrit project.
+#
+# SINCE 1.0.0
+# RESTART REQUIRED
+git.streamFileThreshold = 50m
+
+# When true, JGit will use mmap() rather than malloc()+read() to load data from
+# pack files.  The use of mmap can be problematic on some JVMs as the garbage
+# collector must deduce that a memory mapped segment is no longer in use before
+# a call to munmap() can be made by the JVM native code.
+#
+# In server applications (such as Gitblit) that need to access many pack files,
+# setting this to true risks artificially running out of virtual address space, 
+# as the garbage collector cannot reclaim unused mapped spaces fast enough.
+#
+# Default on JGit is false. Although potentially slower, it yields much more
+# predictable behavior.
+# Documentation courtesy of the Gerrit project.
+#
+# SINCE 1.0.0
+# RESTART REQUIRED
+git.packedGitMmap = false
+
+#
+# Groovy Integration
+#
+
+# Location of Groovy scripts to use for Pre and Post receive hooks.
+# Use forward slashes even on Windows!!
+# e.g. c:/groovy
+#
+# RESTART REQUIRED
+# SINCE 0.8.0
+groovy.scriptsFolder = groovy
+
+# Specify the directory Grape uses for downloading libraries.
+# http://groovy.codehaus.org/Grape
+#
+# RESTART REQUIRED
+# SINCE 1.0.0
+groovy.grapeFolder = groovy/grape
+
+# Scripts to execute on Pre-Receive.
+#
+# These scripts execute after an incoming push has been parsed and validated
+# but BEFORE the changes are applied to the repository.  You might reject a
+# push in this script based on the repository and branch the push is attempting
+# to change.
+#
+# Script names are case-sensitive on case-sensitive file systems.  You may omit
+# the traditional ".groovy" from this list if your file extension is ".groovy" 
+#
+# NOTE:
+# These scripts are only executed when pushing to *Gitblit*, not to other Git
+# tooling you may be using.  Also note that these scripts are shared between
+# repositories. These are NOT repository-specific scripts!  Within the script
+# you may customize the control-flow for a specific repository by checking the
+# *repository* variable.
+#
+# SPACE-DELIMITED
+# CASE-SENSITIVE
+# SINCE 0.8.0
+groovy.preReceiveScripts =
+
+# Scripts to execute on Post-Receive.
+#
+# These scripts execute AFTER an incoming push has been applied to a repository.
+# You might trigger a continuous-integration build here or send a notification.
+#
+# Script names are case-sensitive on case-sensitive file systems.  You may omit
+# the traditional ".groovy" from this list if your file extension is ".groovy" 
+#
+# NOTE:
+# These scripts are only executed when pushing to *Gitblit*, not to other Git
+# tooling you may be using.  Also note that these scripts are shared between
+# repositories. These are NOT repository-specific scripts!  Within the script
+# you may customize the control-flow for a specific repository by checking the
+# *repository* variable.
+# 
+# SPACE-DELIMITED
+# CASE-SENSITIVE
+# SINCE 0.8.0
+groovy.postReceiveScripts =
+
+# Repository custom fields for Groovy Hook mechanism
+#
+# List of key=label pairs of custom fields to prompt for in the Edit Repository
+# page.  These keys are stored in the repository's git config file in the 
+# section [gitblit "customFields"].  Key names are alphanumeric only.  These
+# fields are intended to be used for the Groovy hook mechanism where a script
+# can adjust it's execution based on the custom fields stored in the repository
+# config.
+#
+# e.g. "commitMsgRegex=Commit Message Regular Expression" anotherProperty=Another
+#
+# SPACE-DELIMITED
+# SINCE 1.0.0
+groovy.customFields = 
+
+#
+# Authentication Settings
+#
+
+# Require authentication to see everything but the admin pages
+#
+# SINCE 0.5.0
+# RESTART REQUIRED
+web.authenticateViewPages = true
+
+# Require admin authentication for the admin functions and pages
+#
+# SINCE 0.5.0
+# RESTART REQUIRED
+web.authenticateAdminPages = true
+
+# Allow Gitblit to store a cookie in the user's browser for automatic
+# authentication.  The cookie is generated by the user service.
+#
+# SINCE 0.5.0
+web.allowCookieAuthentication = true
+
+# Either the full path to a user config file (users.conf)
+# OR the full path to a simple user properties file (users.properties)
+# OR a fully qualified class name that implements the IUserService interface.
+#
+# Alternative user services:
+#    com.gitblit.LdapUserService
+#
+# Any custom user service implementation must have a public default constructor.
+#
+# SINCE 0.5.0
+# RESTART REQUIRED
+realm.userService = com.gitblit.gerrit.GerritUserService
+
+# How to store passwords.
+# Valid values are plain, md5, or combined-md5.  md5 is the hash of password.
+# combined-md5 is the hash of username.toLowerCase()+password.
+# Default is md5.
+#
+# SINCE 0.5.0 
+realm.passwordStorage = md5
+
+# Minimum valid length for a plain text password.
+# Default value is 5.  Absolute minimum is 4.
+#
+# SINCE 0.5.0 
+realm.minPasswordLength = 5
+
+#
+# Gitblit Web Settings
+#
+# If blank Gitblit is displayed.
+#
+# SINCE 0.5.0
+web.siteName = GerritForge
+
+
+# If *web.authenticateAdminPages*=true, users with "admin" role can create
+# repositories, create users, and edit repository metadata.
+#
+# If *web.authenticateAdminPages*=false, any user can execute the aforementioned
+# functions. 
+#
+# SINCE 0.5.0 
+web.allowAdministration = false
+
+# Allows rpc clients to list repositories and possibly manage or administer the 
+# Gitblit server, if the authenticated account has administrator permissions.
+# See *web.enableRpcManagement* and *web.enableRpcAdministration*.
+#
+# SINCE 0.7.0 
+web.enableRpcServlet = false
+
+# Allows rpc clients to manage repositories and users of the Gitblit instance,
+# if the authenticated account has administrator permissions.
+# Requires *web.enableRpcServlet=true*.
+#
+# SINCE 0.7.0 
+web.enableRpcManagement = false
+
+# Allows rpc clients to control the server settings and monitor the health of this
+# this Gitblit instance, if the authenticated account has administrator permissions.
+# Requires *web.enableRpcServlet=true* and *web.enableRpcManagement*.
+#
+# SINCE 0.7.0 
+web.enableRpcAdministration = false
+
+# Full path to a configurable robots.txt file.  With this file you can control
+# what parts of your Gitblit server respectable robots are allowed to traverse.
+# http://googlewebmastercentral.blogspot.com/2008/06/improving-on-robots-exclusion-protocol.html
+#
+# SINCE 1.0.0
+web.robots.txt = 
+
+# If true, the web ui layout will respond and adapt to the browser's dimensions.
+# if false, the web ui will use a 940px fixed-width layout.
+# http://twitter.github.com/bootstrap/scaffolding.html#responsive
+#
+# SINCE 1.0.0
+web.useResponsiveLayout = true
+
+# Allow Gravatar images to be displayed in Gitblit pages.
+#
+# SINCE 0.8.0
+web.allowGravatar = true
+
+# Allow dynamic zip downloads.
+#
+# SINCE 0.5.0   
+web.allowZipDownloads = true
+
+# Allow optional Lucene integration. Lucene indexing is an opt-in feature.
+# A repository may specify branches to index with Lucene instead of using Git
+# commit traversal. There are scenarios where you may want to completely disable
+# Lucene indexing despite a repository specifying indexed branches.  One such
+# scenario is on a resource-constrained federated Gitblit mirror.
+#
+# SINCE 0.9.0
+web.allowLuceneIndexing = false
+
+# Use Clippy (Flash solution) to provide a copy-to-clipboard button.
+# If false, a button with a more primitive JavaScript-based prompt box will
+# offer a 3-step (click, ctrl+c, enter) copy-to-clipboard alternative.
+#
+# SINCE 0.8.0
+web.allowFlashCopyToClipboard = true
+
+# Default number of entries to include in RSS Syndication links
+#
+# SINCE 0.5.0
+web.syndicationEntries = 25
+
+# Show the size of each repository on the repositories page.
+# This requires recursive traversal of each repository folder.  This may be
+# non-performant on some operating systems and/or filesystems. 
+#
+# SINCE 0.5.2
+web.showRepositorySizes = true
+
+# List of custom regex expressions that can be displayed in the Filters menu
+# of the Repositories and Activity pages.  Keep them very simple because you
+# are likely to run into encoding issues if they are too complex.
+#
+# Use !!! to separate the filters 
+#
+# SINCE 0.8.0
+web.customFilters =
+
+# Show federation registrations (without token) and the current pull status
+# to non-administrator users. 
+#
+# SINCE 0.6.0
+web.showFederationRegistrations = false
+
+# This is the message displayed when *web.authenticateViewPages=true*.
+# This can point to a file with Markdown content.
+# Specifying "gitblit" uses the internal login message.
+#
+# SINCE 0.7.0
+web.loginMessage = gitblit
+
+# This is the message displayed above the repositories table.
+# This can point to a file with Markdown content.
+# Specifying "gitblit" uses the internal welcome message.
+#
+# SINCE 0.5.0
+web.repositoriesMessage = gitblit
+
+# Ordered list of charsets/encodings to use when trying to display a blob.
+# If empty, UTF-8 and ISO-8859-1 are used.  The server's default charset
+# is always appended to the encoding list.  If all encodings fail to cleanly
+# decode the blob content, UTF-8 will be used with the standard malformed
+# input/unmappable character replacement strings.
+# 
+# SPACE-DELIMITED
+# SINCE 1.0.0
+web.blobEncodings = UTF-8 ISO-8859-1
+
+# Manually set the default timezone to be used by Gitblit for display in the 
+# web ui.  This value is independent of the JVM timezone.  Specifying a blank
+# value will default to the JVM timezone.
+# e.g. America/New_York, US/Pacific, UTC, Europe/Berlin
+#
+# SINCE 0.9.0
+# RESTART REQUIRED
+web.timezone =
+
+# Use the client timezone when formatting dates.
+# This uses AJAX to determine the browser's timezone and may require more
+# server overhead because a Wicket session is created.  All Gitblit pages
+# attempt to be stateless, if possible.
+#
+# SINCE 0.5.0
+# RESTART REQUIRED
+web.useClientTimezone = false
+
+# Time format
+# <http://download.oracle.com/javase/6/docs/api/java/text/SimpleDateFormat.html>
+#
+# SINCE 0.8.0
+web.timeFormat = HH:mm
+
+# Short date format
+# <http://download.oracle.com/javase/6/docs/api/java/text/SimpleDateFormat.html>
+#
+# SINCE 0.5.0
+web.datestampShortFormat = yyyy-MM-dd
+
+# Long date format
+#
+# SINCE 0.8.0
+web.datestampLongFormat = EEEE, MMMM d, yyyy
+
+# Long timestamp format
+# <http://download.oracle.com/javase/6/docs/api/java/text/SimpleDateFormat.html>
+#
+# SINCE 0.5.0
+web.datetimestampLongFormat = EEEE, MMMM d, yyyy HH:mm Z
+
+# Mount URL parameters
+# This setting controls if pretty or parameter URLs are used.
+# i.e.
+# if true:
+#     http://localhost/commit/myrepo/abcdef
+# if false:
+#     http://localhost/commit/?r=myrepo&h=abcdef
+#
+# SINCE 0.5.0
+# RESTART REQUIRED
+web.mountParameters = true
+
+# Some servlet containers (e.g. Tomcat >= 6.0.10) disallow '/' (%2F) encoding
+# in URLs as a security precaution for proxies.  This setting tells Gitblit
+# to preemptively replace '/' with '*' or '!' for url string parameters.
+#
+# <https://issues.apache.org/jira/browse/WICKET-1303>
+# <http://tomcat.apache.org/security-6.html#Fixed_in_Apache_Tomcat_6.0.10>
+# Add *-Dorg.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH=true* to your
+# *CATALINA_OPTS* or to your JVM launch parameters
+#
+# SINCE 0.5.2
+web.forwardSlashCharacter = /
+
+# Show other URLs on the summary page for accessing your git repositories
+# Use spaces to separate urls. {0} is the token for the repository name.
+# e.g.
+# web.otherUrls = ssh://localhost/git/{0} git://localhost/git/{0}
+#
+# SPACE-DELIMITED
+# SINCE 0.5.0
+web.otherUrls = 
+
+# Choose how to present the repositories list.
+#   grouped = group nested/subfolder repositories together (no sorting)
+#   flat = flat list of repositories (sorting allowed)
+#
+# SINCE 0.5.0
+web.repositoryListType = grouped
+
+# If using a grouped repository list and there are repositories at the
+# root level of your repositories folder, you may specify the displayed
+# group name with this setting.  This value is only used for web presentation.
+#
+# SINCE 0.5.0
+web.repositoryRootGroupName = main
+
+# Display the repository swatch color next to the repository name link in the 
+# repositories list. 
+#
+# SINCE 0.8.0
+web.repositoryListSwatches = true
+
+# Choose the diff presentation style: gitblt, gitweb, or plain
+#
+# SINCE 0.5.0
+web.diffStyle = gitblit
+
+# Control if email addresses are shown in web ui
+#
+# SINCE 0.5.0
+web.showEmailAddresses = true
+
+# Shows a combobox in the page links header with commit, committer, and author
+# search selection.  Default search is commit.
+#
+# SINCE 0.5.0
+web.showSearchTypeSelection = false
+
+# Generates a line graph of repository activity over time on the Summary page.
+# This uses the Google Charts API.
+#
+# SINCE 0.5.0 
+web.generateActivityGraph = true
+
+# The number of days to show on the activity page.
+# Value must exceed 0 else default of 14 is used
+#
+# SINCE 0.8.0
+web.activityDuration = 14
+
+# The number of commits to display on the summary page
+# Value must exceed 0 else default of 20 is used
+#
+# SINCE 0.5.0
+web.summaryCommitCount = 16
+
+# The number of tags/branches to display on the summary page.
+# -1 = all tags/branches
+# 0 = hide tags/branches
+# N = N tags/branches
+#
+# SINCE 0.5.0
+web.summaryRefsCount = 5
+
+# The number of items to show on a page before showing the first, prev, next
+# pagination links.  A default if 50 is used for any invalid value.
+#
+# SINCE 0.5.0
+web.itemsPerPage = 50
+
+# Registered file extensions to ignore during Lucene indexing
+#
+# SPACE-DELIMITED
+# SINCE 0.9.0
+web.luceneIgnoreExtensions = 7z arc arj bin bmp dll doc docx exe gif gz jar jpg lib lzh odg odf odt pdf ppt png so swf xcf xls xlsx zip
+
+# Registered extensions for google-code-prettify
+#
+# SPACE-DELIMITED
+# SINCE 0.5.0
+web.prettyPrintExtensions = c cpp cs css htm html java js php pl prefs properties py rb sh sql xml vb
+
+# Registered extensions for markdown transformation
+#
+# SPACE-DELIMITED
+# CASE-SENSITIVE
+# SINCE 0.5.0
+web.markdownExtensions = md mkd markdown MD MKD
+
+# Image extensions
+#
+# SPACE-DELIMITED
+# SINCE 0.5.0
+web.imageExtensions = bmp jpg gif png 
+
+# Registered extensions for binary blobs
+#
+# SPACE-DELIMITED
+# SINCE 0.5.0
+web.binaryExtensions = jar pdf tar.gz zip
+
+# Aggressive heap management will run the garbage collector on every generated
+# page.  This slows down page generation a little but improves heap consumption. 
+#
+# SINCE 0.5.0
+web.aggressiveHeapManagement = false
+
+# Run the webapp in debug mode
+#
+# SINCE 0.5.0
+# RESTART REQUIRED
+web.debugMode = false
+
+# Enable/disable global regex substitutions (i.e. shared across repositories)
+#
+# SINCE 0.5.0
+regex.global = true
+
+# Example global regex substitutions
+# Use !!! to separate the search pattern and the replace pattern
+# searchpattern!!!replacepattern
+# SINCE 0.5.0
+regex.global.bug = \\b(Bug:)(\\s*[#]?|-){0,1}(\\d+)\\b!!!<a href="http://somehost/bug/$3">Bug-Id: $3</a>
+# SINCE 0.5.0
+regex.global.changeid = \\b(Change-Id:\\s*)([A-Za-z0-9]*)\\b!!!<a href="http://somehost/changeid/$2">Change-Id: $2</a>
+
+# Example per-repository regex substitutions overrides global
+# SINCE 0.5.0
+regex.myrepository.bug = \\b(Bug:)(\\s*[#]?|-){0,1}(\\d+)\\b!!!<a href="http://elsewhere/bug/$3">Bug-Id: $3</a>
+
+#
+# Mail Settings
+# SINCE 0.6.0
+#
+# Mail settings are used to notify administrators of received federation proposals
+#
+
+# ip or hostname of smtp server
+#
+# SINCE 0.6.0
+mail.server =
+
+# port to use for smtp requests
+#
+# SINCE 0.6.0
+mail.port = 25
+
+# debug the mail executor
+#
+# SINCE 0.6.0
+mail.debug = false
+
+# if your smtp server requires authentication, supply the credentials here
+#
+# SINCE 0.6.0
+mail.username =
+# SINCE 0.6.0
+mail.password =
+
+# from address for generated emails
+#
+# SINCE 0.6.0
+mail.fromAddress = 
+
+# List of email addresses for the Gitblit administrators
+#
+# SPACE-DELIMITED
+# SINCE 0.6.0
+mail.adminAddresses = 
+
+# List of email addresses for sending push email notifications.
+#
+# This key currently requires use of the sendemail.groovy hook script.
+# If you set sendemail.groovy in *groovy.postReceiveScripts* then email
+# notifications for all repositories (regardless of access restrictions!)
+# will be sent to these addresses.
+#
+# SPACE-DELIMITED
+# SINCE 0.8.0
+mail.mailingLists =
+
+#
+# Federation Settings
+# SINCE 0.6.0
+#
+# A Gitblit federation is a way to backup one Gitblit instance to another.
+#
+# *git.enableGitServlet* must be true to use this feature.
+
+# Your federation name is used for federation status acknowledgments.  If it is
+# unset, and you elect to send a status acknowledgment, your Gitblit instance
+# will be identified by its hostname, if available, else your internal ip address.
+# The source Gitblit instance will also append your external IP address to your
+# identification to differentiate multiple pulling systems behind a single proxy.
+#
+# SINCE 0.6.0
+federation.name =
+
+# Specify the passphrase of this Gitblit instance.
+#
+# An unspecified (empty) passphrase disables processing federation requests.
+#
+# This value can be anything you want: an integer, a sentence, an haiku, etc.
+# Keep the value simple, though, to avoid Java properties file encoding issues.
+#
+# Changing your passphrase will break any registrations you have established with other
+# Gitblit instances.
+#
+# CASE-SENSITIVE
+# SINCE 0.6.0
+# RESTART REQUIRED *(only to enable or disable federation)*
+federation.passphrase =
+
+# Control whether or not this Gitblit instance can receive federation proposals
+# from another Gitblit instance.  Registering a federated Gitblit is a manual
+# process.  Proposals help to simplify that process by allowing a remote Gitblit
+# instance to send your Gitblit instance the federation pull data.
+#
+# SINCE 0.6.0
+federation.allowProposals = false
+
+# The destination folder for cached federation proposals.
+# Use forward slashes even on Windows!!
+#
+# SINCE 0.6.0
+federation.proposalsFolder = proposals
+
+# The default pull frequency if frequency is unspecified on a registration
+#
+# SINCE 0.6.0
+federation.defaultFrequency = 60 mins
+
+# Federation Sets are named groups of repositories.  The Federation Sets are 
+# available for selection in the repository settings page.  You can assign a
+# repository to one or more sets and then distribute the token for the set.
+# This allows you to grant federation pull access to a subset of your available
+# repositories.  Tokens for federation sets only grant repository pull access.
+#
+# SPACE-DELIMITED
+# CASE-SENSITIVE
+# SINCE 0.6.0
+federation.sets = 
+
+# Federation pull registrations
+# Registrations are read once, at startup.
+#
+# RESTART REQUIRED
+#
+# frequency:
+#   The shortest frequency allowed is every 5 minutes
+#   Decimal frequency values are cast to integers
+#   Frequency values may be specified in mins, hours, or days
+#   Values that can not be parsed or are unspecified default to *federation.defaultFrequency*
+#
+# folder:
+#   if unspecified, the folder is *git.repositoriesFolder*
+#   if specified, the folder is relative to *git.repositoriesFolder*
+#
+# bare:
+#   if true, each repository will be created as a *bare* repository and will not
+#   have a working directory.
+#
+#   if false, each repository will be created as a normal repository suitable
+#   for local work.
+#
+# mirror:
+#   if true, each repository HEAD is reset to *origin/master* after each pull.
+#   The repository will be flagged *isFrozen* after the initial clone.
+#
+#   if false, each repository HEAD will point to the FETCH_HEAD of the initial
+#   clone from the origin until pushed to or otherwise manipulated.
+#
+# mergeAccounts:
+#   if true, remote accounts and their permissions are merged into your 
+#   users.properties file 
+#
+# notifyOnError:
+#   if true and the mail configuration is properly set, administrators will be
+#   notified by email of pull failures
+#
+# include and exclude:
+#   Space-delimited list of repositories to include or exclude from pull
+#   may be * wildcard to include or exclude all
+#   may use fuzzy match (e.g. org.eclipse.*)
+
+#
+# (Nearly) Perfect Mirror example
+#
+
+#federation.example1.url = https://go.gitblit.com
+#federation.example1.token = 6f3b8a24bf970f17289b234284c94f43eb42f0e4
+#federation.example1.frequency = 120 mins
+#federation.example1.folder =
+#federation.example1.bare = true 
+#federation.example1.mirror = true 
+#federation.example1.mergeAccounts = true
+
+#
+# Advanced Realm Settings
+#
+
+# URL of the LDAP server.
+# To use encrypted transport, use either ldaps:// URL for SSL or ldap+tls:// to
+# send StartTLS command.
+#
+# SINCE 1.0.0
+realm.ldap.server = ldap://localhost
+
+# Login username for LDAP searches.
+# If this value is unspecified, anonymous LDAP login will be used.
+# 
+# e.g. mydomain\\username
+#
+# SINCE 1.0.0
+realm.ldap.username = cn=Directory Manager
+
+# Login password for LDAP searches.
+#
+# SINCE 1.0.0
+realm.ldap.password = password
+
+# The LdapUserService must be backed by another user service for standard user
+# and team management.
+# default: users.conf
+#
+# SINCE 1.0.0
+# RESTART REQUIRED
+realm.ldap.backingUserService = users.conf
+
+# Delegate team membership control to LDAP.
+#
+# If true, team user memberships will be specified by LDAP groups.  This will
+# disable team selection in Edit User and user selection in Edit Team.
+#
+# If false, LDAP will only be used for authentication and Gitblit will maintain
+# team memberships with the *realm.ldap.backingUserService*.
+#
+# SINCE 1.0.0
+realm.ldap.maintainTeams = false
+
+# Root node for all LDAP users
+#
+# This is the root node from which subtree user searches will begin.
+# If blank, Gitblit will search ALL nodes.
+#
+# SINCE 1.0.0
+realm.ldap.accountBase = OU=Users,OU=UserControl,OU=MyOrganization,DC=MyDomain
+
+# Filter criteria for LDAP users
+#
+# Query pattern to use when searching for a user account. This may be any valid 
+# LDAP query expression, including the standard (&) and (|) operators.
+#
+# Variables may be injected via the ${variableName} syntax.
+# Recognized variables are:
+#    ${username} - The text entered as the user name
+#
+# SINCE 1.0.0
+realm.ldap.accountPattern = (&(objectClass=person)(sAMAccountName=${username}))
+
+# Root node for all LDAP groups to be used as Gitblit Teams
+#
+# This is the root node from which subtree team searches will begin.
+# If blank, Gitblit will search ALL nodes.  
+#
+# SINCE 1.0.0
+realm.ldap.groupBase = OU=Groups,OU=UserControl,OU=MyOrganization,DC=MyDomain
+
+# Filter criteria for LDAP groups
+#
+# Query pattern to use when searching for a team. This may be any valid 
+# LDAP query expression, including the standard (&) and (|) operators.
+#
+# Variables may be injected via the ${variableName} syntax.
+# Recognized variables are:
+#    ${username} - The text entered as the user name
+#    ${dn} - The Distinguished Name of the user logged in
+#
+# All attributes from the LDAP User record are available. For example, if a user
+# has an attribute "fullName" set to "John", "(fn=${fullName})" will be 
+# translated to "(fn=John)".
+#
+# SINCE 1.0.0
+realm.ldap.groupMemberPattern = (&(objectClass=group)(member=${dn}))
+
+# LDAP users or groups that should be given administrator privileges.
+#
+# Teams are specified with a leading '@' character.  Groups with spaces in the
+# name can be entered as "@team name".
+#
+# e.g. realm.ldap.admins = john @git_admins "@git admins"
+#
+# SPACE-DELIMITED
+# SINCE 1.0.0
+realm.ldap.admins = @Git_Admins
+
+# Attribute(s) on the USER record that indicate their display (or full) name.
+# Leave blank for no mapping available in LDAP.
+#
+# This may be a single attribute, or a string of multiple attributes.  Examples:
+#  displayName - Uses the attribute 'displayName' on the user record
+#  ${personalTitle}. ${givenName} ${surname} - Will concatenate the 3 
+#       attributes together, with a '.' after personalTitle
+#
+# SINCE 1.0.0
+realm.ldap.displayName = displayName
+
+# Attribute(s) on the USER record that indicate their email address.
+# Leave blank for no mapping available in LDAP.
+#
+# This may be a single attribute, or a string of multiple attributes.  Examples:
+#  email - Uses the attribute 'email' on the user record
+#  ${givenName}.${surname}@gitblit.com -Will concatenate the 2 attributes
+#       together with a '.' and '@' creating something like first.last@gitblit.com 
+#
+# SINCE 1.0.0
+realm.ldap.email = email
+
+#
+# Server Settings
+#
+
+# The temporary folder to decompress the embedded gitblit webapp. 
+#
+# SINCE 0.5.0
+# RESTART REQUIRED
+server.tempFolder = temp
+
+# Use Jetty NIO connectors.  If false, Jetty Socket connectors will be used.
+#
+# SINCE 0.5.0
+# RESTART REQUIRED
+server.useNio = true
+
+# Context path for the GO application.  You might want to change the context
+# path if running Gitblit behind a proxy layer such as mod_proxy.
+#
+# SINCE 0.7.0
+# RESTART REQUIRED
+server.contextPath = /
+
+# Standard http port to serve.  <= 0 disables this connector.
+# On Unix/Linux systems, ports < 1024 require root permissions.
+# Recommended value: 80 or 8080
+#
+# SINCE 0.5.0
+# RESTART REQUIRED
+server.httpPort = 0
+
+# Secure/SSL https port to serve. <= 0 disables this connector.
+# On Unix/Linux systems, ports < 1024 require root permissions.
+# Recommended value: 443 or 8443
+#
+# SINCE 0.5.0
+# RESTART REQUIRED
+server.httpsPort = 8443
+
+# Port for serving an Apache JServ Protocol (AJP) 1.3 connector for integrating
+# Gitblit GO into an Apache HTTP server setup.  <= 0 disables this connector.
+# Recommended value: 8009
+#
+# SINCE 0.9.0
+# RESTART REQUIRED
+server.ajpPort = 0
+
+# Specify the interface for Jetty to bind the standard connector.
+# You may specify an ip or an empty value to bind to all interfaces.
+# Specifying localhost will result in Gitblit ONLY listening to requests to
+# localhost.
+#
+# SINCE 0.5.0
+# RESTART REQUIRED
+server.httpBindInterface = localhost
+
+# Specify the interface for Jetty to bind the secure connector.
+# You may specify an ip or an empty value to bind to all interfaces.
+# Specifying localhost will result in Gitblit ONLY listening to requests to
+# localhost.
+#
+# SINCE 0.5.0
+# RESTART REQUIRED
+server.httpsBindInterface = localhost
+
+# Specify the interface for Jetty to bind the AJP connector.
+# You may specify an ip or an empty value to bind to all interfaces.
+# Specifying localhost will result in Gitblit ONLY listening to requests to
+# localhost.
+#
+# SINCE 0.9.0
+# RESTART REQUIRED
+server.ajpBindInterface = localhost
+
+# Password for SSL keystore.
+# Keystore password and certificate password must match.
+# This is provided for convenience, its probably more secure to set this value
+# using the --storePassword command line parameter.
+#
+# SINCE 0.5.0
+# RESTART REQUIRED
+server.storePassword = gitblit
+
+# Port for shutdown monitor to listen on.
+#
+# SINCE 0.5.0
+# RESTART REQUIRED
+server.shutdownPort = 8081
+