From 87cc1ed60735a419a3ea23f20614fc0a3f9bab60 Mon Sep 17 00:00:00 2001
From: James Moger <james.moger@gitblit.com>
Date: Fri, 15 Apr 2011 17:18:51 -0400
Subject: [PATCH] Settings overhaul. Fixes to authentication.  Bind interface feature.

---
 src/com/gitblit/utils/HtmlDiffFormatter.java       |    2 
 src/com/gitblit/utils/StringUtils.java             |  110 +++++++
 src/com/gitblit/Build.java                         |   71 +++--
 src/com/gitblit/utils/TimeUtils.java               |   49 ---
 src/com/gitblit/wicket/pages/RepositoriesPage.java |   15 
 src/com/gitblit/utils/PatchFormatter.java          |    2 
 src/com/gitblit/IStoredSettings.java               |   23 +
 src/com/gitblit/wicket/LogoutPage.java             |   12 
 src/com/gitblit/wicket/panels/TagsPanel.java       |    3 
 gitblit.properties                                 |   47 ++-
 src/com/gitblit/GitBlit.java                       |   63 +++-
 src/com/gitblit/wicket/GitBlitWebApp.properties    |    6 
 src/com/gitblit/wicket/WicketUtils.java            |   38 --
 src/com/gitblit/GitBlitServer.java                 |   50 ++-
 src/com/gitblit/wicket/pages/RawPage.java          |    5 
 src/com/gitblit/wicket/LinkPanel.java              |    4 
 src/com/gitblit/wicket/pages/BlobPage.java         |    8 
 src/com/gitblit/wicket/LoginPage.html              |   12 
 src/com/gitblit/FileSettings.java                  |   41 +-
 src/com/gitblit/wicket/AuthorizationStrategy.java  |   23 -
 src/com/gitblit/wicket/RepositoryPage.java         |   23 +
 src/com/gitblit/utils/ByteFormat.java              |    5 
 src/com/gitblit/wicket/pages/TicGitPage.java       |    5 
 src/com/gitblit/wicket/LoginPage.java              |   35 +-
 src/com/gitblit/WebXmlSettings.java                |   65 ++++
 src/com/gitblit/wicket/BasePage.java               |   18 
 src/com/gitblit/wicket/BasePage.html               |    2 
 src/com/gitblit/wicket/panels/BasePanel.java       |    4 
 src/com/gitblit/wicket/pages/TicGitTicketPage.java |    8 
 src/com/gitblit/wicket/panels/PageLinksPanel.java  |    7 
 src/com/gitblit/wicket/panels/BranchesPanel.java   |    3 
 src/com/gitblit/wicket/pages/TicGitTicketPage.html |    5 
 build.xml                                          |    1 
 src/com/gitblit/wicket/panels/LogPanel.java        |    7 
 src/com/gitblit/wicket/User.java                   |   10 
 src/com/gitblit/wicket/GitBlitWebApp.java          |   17 
 src/com/gitblit/wicket/pages/SummaryPage.java      |   11 
 37 files changed, 526 insertions(+), 284 deletions(-)

diff --git a/build.xml b/build.xml
index 34c1957..524a178 100644
--- a/build.xml
+++ b/build.xml
@@ -17,6 +17,7 @@
 		<javac srcdir="${basedir}/src" destdir="${project.build.dir}">
 			<include name="com/gitblit/Build.java" />
 			<include name="com/gitblit/Constants.java" />
+			<include name="com/gitblit/utils/StringUtils.java" />
 		</javac>
 		<java classpath="${project.build.dir}" classname="com.gitblit.Build" />
 
diff --git a/gitblit.properties b/gitblit.properties
index 7708a9b..1adadc8 100644
--- a/gitblit.properties
+++ b/gitblit.properties
@@ -33,25 +33,14 @@
 server.realmFile = users.properties
 
 #
-# Server Settings
-#
-server.debugMode = true
-server.tempFolder = temp
-server.log4jPattern = %-5p %d{MM-dd HH:mm:ss.SSS}  %-20.20c{1}  %m%n
-
-# Aggressive heap management will run the garbage collector on every generated
-# page.  This slows down page generation but improves heap consumption. 
-server.aggressiveHeapManagement = true
-
-#
-# Git:Blit UI Settings
+# Git:Blit Web Settings
 #
 web.siteName =
 
-# If authenticateWebUI=true, users with "admin" role can create repositories,
+# If web.authenticate=true, users with "admin" role can create repositories,
 # create users, and edit repository metadata (owner, description, etc)
 #
-# If authenticateWebUI=false, any user can execute the aforementioned functions.  
+# If web.authenticate=false, any user can execute the aforementioned functions.  
 web.allowAdministration = true
 
 # This is the message display above the repositories table.
@@ -92,18 +81,36 @@
 # Registered extensions for binary blobs
 web.binaryExtensions = jar pdf tar.gz zip
 
+# Aggressive heap management will run the garbage collector on every generated
+# page.  This slows down page generation but improves heap consumption. 
+web.aggressiveHeapManagement = true
+
+# Run the webapp in debug mode
+web.debugMode = true
+
+# Enable/disable global regex substitutions (i.e. shared across repositories)
+regex.global = true
+
 # Example global regex substitutions
+# Use !!! to separate the search pattern and the replace pattern
+# searchpattern!!!replacepattern
 regex.global.bug = \\b(Bug:)(\\s*[#]?|-){0,1}(\\d+)\\b!!!<a href="http://somehost/bug/$3">Bug-Id: $3</a>
 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
 #regex.myrepository.bug = \\b(Bug:)(\\s*[#]?|-){0,1}(\\d+)\\b!!!<a href="http://elsewhere/bug/$3">Bug-Id: $3</a>
 
-# Enable ticgit viewer for all repositories (checks for ticgit branch)
+# Enable ticgit pages for all repositories (if ticgit branch is present)
 ticgit.global = false
 
-# Enable ticgit viewer for specified repository (checks for ticgit branch)
+# Enable ticgit pages for specified repository (if ticgit branch is present)
 #ticgit.myrepository = true
+
+#
+# Server Settings
+#
+server.tempFolder = temp
+server.log4jPattern = %-5p %d{MM-dd HH:mm:ss.SSS}  %-20.20c{1}  %m%n
 
 #
 # Jetty Settings
@@ -118,6 +125,14 @@
 # Secure/SSL https port to serve. <= 0 disables this connector.
 server.httpsPort = 443
 
+# Specify the interface for Jetty to bind the standard connector.
+# You may specify an ip or an empty value to bind to all interfaces. 
+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.
+server.httpsBindInterface = localhost
+
 # Password for SSL keystore (keystore password and certificate password must match)
 server.storePassword = dosomegit
 
diff --git a/src/com/gitblit/Build.java b/src/com/gitblit/Build.java
index ec392e1..b12d44e 100644
--- a/src/com/gitblit/Build.java
+++ b/src/com/gitblit/Build.java
@@ -8,13 +8,15 @@
 import java.io.InputStream;
 import java.io.RandomAccessFile;
 import java.net.URL;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
 import java.text.MessageFormat;
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 import java.util.Properties;
+
+import com.gitblit.utils.StringUtils;
 
 public class Build {
 
@@ -41,6 +43,7 @@
 	}
 
 	public static void buildSettingKeys() {
+		// Load all keys
 		Properties properties = new Properties();
 		try {
 			properties.load(new FileInputStream(Constants.PROPERTIES_FILE));
@@ -50,6 +53,23 @@
 		List<String> keys = new ArrayList<String>(properties.stringPropertyNames());
 		Collections.sort(keys);
 
+		// Determine static key group classes
+		Map<String, List<String>> staticClasses = new HashMap<String, List<String>>();
+		staticClasses.put("", new ArrayList<String>());
+		for (String key : keys) {
+			String clazz = "";
+			String field = key;
+			if (key.indexOf('.') > -1) {
+				clazz = key.substring(0, key.indexOf('.'));
+				field = key.substring(key.indexOf('.') + 1);
+			}
+			if (!staticClasses.containsKey(clazz)) {
+				staticClasses.put(clazz, new ArrayList<String>());
+			}
+			staticClasses.get(clazz).add(field);
+		}
+
+		// Assemble Keys source file
 		StringBuilder sb = new StringBuilder();
 		sb.append("package com.gitblit;\n");
 		sb.append("\n");
@@ -59,10 +79,28 @@
 		sb.append(" */\n");
 		sb.append("public final class Keys {\n");
 		sb.append("\n");
-		for (String key : keys) {
-			sb.append(MessageFormat.format("\tpublic static final String {0} = \"{1}\";\n\n", key.replace('.', '_'), key));
+		List<String> classSet = new ArrayList<String>(staticClasses.keySet());
+		Collections.sort(classSet);
+		for (String clazz : classSet) {
+			List<String> keySet = staticClasses.get(clazz);
+			if (clazz.equals("")) {
+				// root keys
+				for (String key : keySet) {
+					sb.append(MessageFormat.format("\tpublic static final String {0} = \"{1}\";\n\n", key.replace('.', '_'), key));
+				}
+			} else {
+				// class keys
+				sb.append(MessageFormat.format("\tpublic static final class {0} '{'\n\n", clazz));
+				sb.append(MessageFormat.format("\t\tpublic static final String _ROOT = \"{0}\";\n\n", clazz));
+				for (String key : keySet) {
+					sb.append(MessageFormat.format("\t\tpublic static final String {0} = \"{1}\";\n\n", key.replace('.', '_'), clazz + "." + key));
+				}
+				sb.append("\t}\n\n");
+			}
 		}
 		sb.append("}");
+
+		// Save Keys class definition
 		try {
 			File file = new File("src/com/gitblit/Keys.java");
 			file.delete();
@@ -119,7 +157,7 @@
 			throw new RuntimeException("Error downloading " + mavenURL + " to " + targetFile, e);
 		}
 		byte[] data = buff.toByteArray();
-		String got = getSHA1(data);
+		String got = StringUtils.getSHA1(data);
 		if (mo.sha1 != null && !got.equals(mo.sha1)) {
 			throw new RuntimeException("SHA1 checksum mismatch; got: " + got);
 		}
@@ -132,29 +170,6 @@
 			throw new RuntimeException("Error writing to file " + targetFile, e);
 		}
 		return targetFile;
-	}
-
-	/**
-	 * Generate the SHA1 checksum of a byte array.
-	 * 
-	 * @param data
-	 *            the byte array
-	 * @return the SHA1 checksum
-	 */
-	public static String getSHA1(byte[] data) {
-		MessageDigest md;
-		try {
-			md = MessageDigest.getInstance("SHA-1");
-			byte[] value = md.digest(data);
-			StringBuilder buff = new StringBuilder(value.length * 2);
-			for (byte c : value) {
-				int x = c & 0xff;
-				buff.append(Integer.toString(x >> 4, 16)).append(Integer.toString(x & 0xf, 16));
-			}
-			return buff.toString();
-		} catch (NoSuchAlgorithmException e) {
-			throw new RuntimeException(e);
-		}
 	}
 
 	private static class MavenObject {
diff --git a/src/com/gitblit/StoredSettings.java b/src/com/gitblit/FileSettings.java
similarity index 72%
rename from src/com/gitblit/StoredSettings.java
rename to src/com/gitblit/FileSettings.java
index 1db87c0..371b734 100644
--- a/src/com/gitblit/StoredSettings.java
+++ b/src/com/gitblit/FileSettings.java
@@ -11,18 +11,19 @@
 import org.slf4j.LoggerFactory;
 
 /**
- * Reads settings file.
+ * Reads GitBlit settings file.
  * 
  */
-public class StoredSettings {
+public class FileSettings implements IStoredSettings {
 
-	private static Properties properties = new Properties();
+	private Properties properties = new Properties();
 
-	private static long lastread = 0;
+	private long lastread = 0;
 
-	private static final Logger logger = LoggerFactory.getLogger(StoredSettings.class);
+	private final Logger logger = LoggerFactory.getLogger(FileSettings.class);
 
-	public static List<String> getAllKeys(String startingWith) {
+	@Override
+	public List<String> getAllKeys(String startingWith) {
 		startingWith = startingWith.toLowerCase();
 		List<String> keys = new ArrayList<String>();
 		Properties props = read();
@@ -35,7 +36,8 @@
 		return keys;
 	}
 
-	public static boolean getBoolean(String name, boolean defaultValue) {
+	@Override
+	public boolean getBoolean(String name, boolean defaultValue) {
 		Properties props = read();
 		if (props.containsKey(name)) {
 			try {
@@ -50,7 +52,8 @@
 		return defaultValue;
 	}
 
-	public static int getInteger(String name, int defaultValue) {
+	@Override
+	public int getInteger(String name, int defaultValue) {
 		Properties props = read();
 		if (props.containsKey(name)) {
 			try {
@@ -65,7 +68,8 @@
 		return defaultValue;
 	}
 
-	public static String getString(String name, String defaultValue) {
+	@Override
+	public String getString(String name, String defaultValue) {
 		Properties props = read();
 		if (props.containsKey(name)) {
 			try {
@@ -80,15 +84,18 @@
 		return defaultValue;
 	}
 
-	public static List<String> getStrings(String name) {
+	@Override
+	public List<String> getStrings(String name) {
 		return getStrings(name, " ");
 	}
 
-	public static List<String> getStringsFromValue(String value) {
+	@Override
+	public List<String> getStringsFromValue(String value) {
 		return getStringsFromValue(value, " ");
 	}
 
-	public static List<String> getStrings(String name, String separator) {
+	@Override
+	public List<String> getStrings(String name, String separator) {
 		List<String> strings = new ArrayList<String>();
 		Properties props = read();
 		if (props.containsKey(name)) {
@@ -98,7 +105,8 @@
 		return strings;
 	}
 
-	public static List<String> getStringsFromValue(String value, String separator) {
+	@Override
+	public List<String> getStringsFromValue(String value, String separator) {
 		List<String> strings = new ArrayList<String>();
 		try {
 			String[] chunks = value.split(separator);
@@ -113,7 +121,7 @@
 		return strings;
 	}
 
-	private static synchronized Properties read() {
+	private synchronized Properties read() {
 		File file = new File(Constants.PROPERTIES_FILE);
 		if (file.exists() && (file.lastModified() > lastread)) {
 			try {
@@ -127,4 +135,9 @@
 		}
 		return properties;
 	}
+	
+	@Override
+	public String toString() {
+		return getClass().getSimpleName() + ": " + new File(Constants.PROPERTIES_FILE).getAbsolutePath();
+	}
 }
diff --git a/src/com/gitblit/GitBlit.java b/src/com/gitblit/GitBlit.java
index f437e5f..f285daf 100644
--- a/src/com/gitblit/GitBlit.java
+++ b/src/com/gitblit/GitBlit.java
@@ -5,6 +5,8 @@
 import java.util.Date;
 import java.util.List;
 
+import javax.servlet.ServletContextEvent;
+import javax.servlet.ServletContextListener;
 import javax.servlet.http.Cookie;
 import javax.servlet.http.HttpServletRequest;
 
@@ -22,38 +24,43 @@
 import com.gitblit.wicket.User;
 import com.gitblit.wicket.models.RepositoryModel;
 
-public class GitBlit {
+public class GitBlit implements ServletContextListener {
 
-	private static GitBlit gitblit;
+	private final static GitBlit gitblit;
 
 	private final Logger logger = LoggerFactory.getLogger(GitBlit.class);
 
-	private final boolean debugMode;
+	private FileResolver repositoryResolver;
 
-	private final FileResolver repositoryResolver;
+	private File repositories;
 
-	private final File repositories;
-
-	private final boolean exportAll;
+	private boolean exportAll;
 
 	private ILoginService loginService;
 
+	private IStoredSettings storedSettings;
+
+	static {
+		gitblit = new GitBlit();
+	}
+
 	public static GitBlit self() {
-		if (gitblit == null) {
-			gitblit = new GitBlit();
-		}
 		return gitblit;
 	}
 
 	private GitBlit() {
-		repositories = new File(StoredSettings.getString(Keys.git_repositoriesFolder, "repos"));
-		exportAll = StoredSettings.getBoolean(Keys.git_exportAll, true);
-		repositoryResolver = new FileResolver(repositories, exportAll);
-		debugMode = StoredSettings.getBoolean(Keys.server_debugMode, false);
+	}
+
+	public IStoredSettings settings() {
+		return storedSettings;
 	}
 
 	public boolean isDebugMode() {
-		return debugMode;
+		return storedSettings.getBoolean(Keys.web.debugMode, false);
+	}
+
+	public String getCloneUrl(String repositoryName) {
+		return storedSettings.getString(Keys.git.cloneUrl, "https://localhost/git/") + repositoryName;
 	}
 
 	public void setLoginService(ILoginService loginService) {
@@ -90,7 +97,7 @@
 	}
 
 	public List<String> getRepositoryList() {
-		return JGitUtils.getRepositoryList(repositories, exportAll, StoredSettings.getBoolean(Keys.git_nestedRepositories, true));
+		return JGitUtils.getRepositoryList(repositories, exportAll, storedSettings.getBoolean(Keys.git.nestedRepositories, true));
 	}
 
 	public List<RepositoryModel> getRepositories(Request request) {
@@ -124,4 +131,28 @@
 		}
 		return r;
 	}
+
+	public void setupContext(IStoredSettings settings) {
+		logger.info("Setting up GitBlit context from " + settings.toString());
+		this.storedSettings = settings;
+		repositories = new File(settings.getString(Keys.git.repositoriesFolder, "repos"));
+		exportAll = settings.getBoolean(Keys.git.exportAll, true);
+		repositoryResolver = new FileResolver(repositories, exportAll);
+	}
+
+	@Override
+	public void contextInitialized(ServletContextEvent contextEvent) {
+		logger.info("GitBlit context initialization by servlet container...");
+		if (storedSettings == null) {
+			WebXmlSettings webxmlSettings = new WebXmlSettings(contextEvent.getServletContext());
+			setupContext(webxmlSettings);
+		} else {
+			logger.info("GitBlit context already setup by " + storedSettings.toString());	
+		}
+	}
+
+	@Override
+	public void contextDestroyed(ServletContextEvent contextEvent) {
+		logger.info("GitBlit context destroyed by servlet container.");
+	}
 }
diff --git a/src/com/gitblit/GitBlitServer.java b/src/com/gitblit/GitBlitServer.java
index b167e6c..a82b595 100644
--- a/src/com/gitblit/GitBlitServer.java
+++ b/src/com/gitblit/GitBlitServer.java
@@ -11,6 +11,7 @@
 import java.net.URL;
 import java.net.UnknownHostException;
 import java.security.ProtectionDomain;
+import java.text.MessageFormat;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -44,12 +45,15 @@
 import com.beust.jcommander.Parameter;
 import com.beust.jcommander.ParameterException;
 import com.beust.jcommander.Parameters;
+import com.gitblit.utils.StringUtils;
 import com.gitblit.wicket.GitBlitWebApp;
 
 public class GitBlitServer {
 
 	private final static Logger logger = Log.getLogger(GitBlitServer.class.getSimpleName());
 	private final static String border_star = "***********************************************************";
+
+	private final static FileSettings fileSettings = new FileSettings();
 
 	public static void main(String[] args) {
 		Params params = new Params();
@@ -106,10 +110,7 @@
 	 * Start Server.
 	 */
 	private static void start(Params params) {
-		// instantiate GitBlit
-		GitBlit.self();
-
-		PatternLayout layout = new PatternLayout(StoredSettings.getString(Keys.server_log4jPattern, "%-5p %d{MM-dd HH:mm:ss.SSS}  %-20.20c{1}  %m%n"));
+		PatternLayout layout = new PatternLayout(fileSettings.getString(Keys.server.log4jPattern, "%-5p %d{MM-dd HH:mm:ss.SSS}  %-20.20c{1}  %m%n"));
 		org.apache.log4j.Logger rootLogger = org.apache.log4j.Logger.getRootLogger();
 		rootLogger.addAppender(new ConsoleAppender(layout));
 
@@ -121,20 +122,26 @@
 		String osversion = System.getProperty("os.version");
 		logger.info("Running on " + osname + " (" + osversion + ")");
 
-		if (StoredSettings.getBoolean(Keys.server_debugMode, false)) {
-			logger.warn("DEBUG Mode");
-		}
-
 		// Determine port connectors
 		List<Connector> connectors = new ArrayList<Connector>();
 		if (params.port > 0) {
 			Connector httpConnector = createConnector(params.useNIO, params.port);
+			String bindInterface = fileSettings.getString(Keys.server.httpBindInterface, null);
+			if (!StringUtils.isEmpty(bindInterface)) {
+				logger.warn(MessageFormat.format("Binding port {0} to {1}", params.port, bindInterface));
+				httpConnector.setHost(bindInterface);
+			}
 			connectors.add(httpConnector);
 		}
 
 		if (params.securePort > 0) {
 			if (new File("keystore").exists()) {
 				Connector secureConnector = createSSLConnector(params.useNIO, params.securePort, params.storePassword);
+				String bindInterface = fileSettings.getString(Keys.server.httpsBindInterface, null);
+				if (!StringUtils.isEmpty(bindInterface)) {
+					logger.warn(MessageFormat.format("Binding port {0} to {1}", params.port, bindInterface));
+					secureConnector.setHost(bindInterface);
+				}
 				connectors.add(secureConnector);
 			} else {
 				logger.warn("Failed to find Keystore?  Did you run \"makekeystore\"?");
@@ -177,7 +184,7 @@
 		// Git Servlet
 		ServletHolder gitServlet = null;
 		String gitServletPathSpec = "/git/*";
-		if (StoredSettings.getBoolean(Keys.git_allowPushPull, true)) {
+		if (fileSettings.getBoolean(Keys.git.allowPushPull, true)) {
 			gitServlet = rootContext.addServlet(GitServlet.class, gitServletPathSpec);
 			gitServlet.setInitParameter("base-path", params.repositoriesFolder);
 			gitServlet.setInitParameter("export-all", params.exportAll ? "1" : "0");
@@ -234,6 +241,11 @@
 
 		// Set the server's contexts
 		server.setHandler(handler);
+
+		// Setup the GitBlit context
+		GitBlit gitblit = GitBlit.self();
+		gitblit.setupContext(fileSettings);
+		rootContext.addEventListener(gitblit);
 
 		// Start the Server
 		try {
@@ -356,43 +368,43 @@
 		public Boolean stop = false;
 
 		@Parameter(names = { "--temp" }, description = "Server temp folder")
-		public String temp = StoredSettings.getString(Keys.server_tempFolder, "temp");
+		public String temp = fileSettings.getString(Keys.server.tempFolder, "temp");
 
 		/*
 		 * GIT Servlet Parameters
 		 */
 		@Parameter(names = { "--repos" }, description = "Git Repositories Folder")
-		public String repositoriesFolder = StoredSettings.getString(Keys.git_repositoriesFolder, "repos");
+		public String repositoriesFolder = fileSettings.getString(Keys.git.repositoriesFolder, "repos");
 
 		@Parameter(names = { "--exportAll" }, description = "Export All Found Repositories")
-		public Boolean exportAll = StoredSettings.getBoolean(Keys.git_exportAll, true);
+		public Boolean exportAll = fileSettings.getBoolean(Keys.git.exportAll, true);
 
 		/*
 		 * Authentication Parameters
 		 */
 		@Parameter(names = { "--authenticatePushPull" }, description = "Authenticate Git Push/Pull access")
-		public Boolean authenticatePushPull = StoredSettings.getBoolean(Keys.git_authenticate, true);
+		public Boolean authenticatePushPull = fileSettings.getBoolean(Keys.git.authenticate, true);
 
 		@Parameter(names = { "--realm" }, description = "Users Realm Hash File")
-		public String realmFile = StoredSettings.getString(Keys.server_realmFile, "users.properties");
+		public String realmFile = fileSettings.getString(Keys.server.realmFile, "users.properties");
 
 		/*
 		 * JETTY Parameters
 		 */
 		@Parameter(names = { "--nio" }, description = "Use NIO Connector else use Socket Connector.")
-		public Boolean useNIO = StoredSettings.getBoolean(Keys.server_useNio, true);
+		public Boolean useNIO = fileSettings.getBoolean(Keys.server.useNio, true);
 
 		@Parameter(names = "--port", description = "HTTP port for to serve. (port <= 0 will disable this connector)")
-		public Integer port = StoredSettings.getInteger(Keys.server_httpPort, 80);
+		public Integer port = fileSettings.getInteger(Keys.server.httpPort, 80);
 
 		@Parameter(names = "--securePort", description = "HTTPS port to serve.  (port <= 0 will disable this connector)")
-		public Integer securePort = StoredSettings.getInteger(Keys.server_httpsPort, 443);
+		public Integer securePort = fileSettings.getInteger(Keys.server.httpsPort, 443);
 
 		@Parameter(names = "--storePassword", description = "Password for SSL (https) keystore.")
-		public String storePassword = StoredSettings.getString(Keys.server_storePassword, "");
+		public String storePassword = fileSettings.getString(Keys.server.storePassword, "");
 
 		@Parameter(names = "--shutdownPort", description = "Port for Shutdown Monitor to listen on. (port <= 0 will disable this monitor)")
-		public Integer shutdownPort = StoredSettings.getInteger(Keys.server_shutdownPort, 8081);
+		public Integer shutdownPort = fileSettings.getInteger(Keys.server.shutdownPort, 8081);
 
 	}
 }
\ No newline at end of file
diff --git a/src/com/gitblit/IStoredSettings.java b/src/com/gitblit/IStoredSettings.java
new file mode 100644
index 0000000..d5b74aa
--- /dev/null
+++ b/src/com/gitblit/IStoredSettings.java
@@ -0,0 +1,23 @@
+package com.gitblit;
+
+import java.util.List;
+
+public interface IStoredSettings {
+
+	public abstract List<String> getAllKeys(String startingWith);
+
+	public abstract boolean getBoolean(String name, boolean defaultValue);
+
+	public abstract int getInteger(String name, int defaultValue);
+
+	public abstract String getString(String name, String defaultValue);
+
+	public abstract List<String> getStrings(String name);
+
+	public abstract List<String> getStringsFromValue(String value);
+
+	public abstract List<String> getStrings(String name, String separator);
+
+	public abstract List<String> getStringsFromValue(String value, String separator);
+
+}
\ No newline at end of file
diff --git a/src/com/gitblit/WebXmlSettings.java b/src/com/gitblit/WebXmlSettings.java
new file mode 100644
index 0000000..00084bf
--- /dev/null
+++ b/src/com/gitblit/WebXmlSettings.java
@@ -0,0 +1,65 @@
+package com.gitblit;
+
+import java.util.List;
+
+import javax.servlet.ServletContext;
+
+public class WebXmlSettings implements IStoredSettings {
+
+	public WebXmlSettings(ServletContext context) {
+		
+	}
+	
+	@Override
+	public List<String> getAllKeys(String startingWith) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public boolean getBoolean(String name, boolean defaultValue) {
+		// TODO Auto-generated method stub
+		return false;
+	}
+
+	@Override
+	public int getInteger(String name, int defaultValue) {
+		// TODO Auto-generated method stub
+		return 0;
+	}
+
+	@Override
+	public String getString(String name, String defaultValue) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public List<String> getStrings(String name) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public List<String> getStringsFromValue(String value) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public List<String> getStrings(String name, String separator) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public List<String> getStringsFromValue(String value, String separator) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+	
+	@Override
+	public String toString() {
+		return getClass().getSimpleName() + ": web.xml";
+	}
+}
diff --git a/src/com/gitblit/utils/ByteFormat.java b/src/com/gitblit/utils/ByteFormat.java
index a726368..8634f29 100644
--- a/src/com/gitblit/utils/ByteFormat.java
+++ b/src/com/gitblit/utils/ByteFormat.java
@@ -1,8 +1,3 @@
-/*
- * Copyright 2011 Squeal Group.  Licensed under the Eclipse Public License, 
- * Version 1.0 (http://www.eclipse.org/legal/epl-v10.html).
- * Initial Developer: Squeal Group
- */
 package com.gitblit.utils;
 
 import java.text.DecimalFormat;
diff --git a/src/com/gitblit/utils/HtmlDiffFormatter.java b/src/com/gitblit/utils/HtmlDiffFormatter.java
index a3e58c3..24cdd8a 100644
--- a/src/com/gitblit/utils/HtmlDiffFormatter.java
+++ b/src/com/gitblit/utils/HtmlDiffFormatter.java
@@ -91,7 +91,7 @@
 		ByteArrayOutputStream bos = new ByteArrayOutputStream();
 		text.writeLine(bos, cur);
 		String line = bos.toString();
-		line = Utils.escapeForHtml(line, false);
+		line = StringUtils.escapeForHtml(line, false);
 		os.write(line.getBytes());
 		switch (prefix) {
 		case '+':
diff --git a/src/com/gitblit/utils/PatchFormatter.java b/src/com/gitblit/utils/PatchFormatter.java
index f019ce4..15c1f94 100644
--- a/src/com/gitblit/utils/PatchFormatter.java
+++ b/src/com/gitblit/utils/PatchFormatter.java
@@ -78,7 +78,7 @@
 		}
 		for (String path : changes.keySet()) {
 			PatchTouple touple = changes.get(path);
-			patch.append("\n " + Utils.rightPad(path, maxPathLen, ' ') + " | " + Utils.leftPad("" + touple.total(), 4, ' ') + " " + touple.relativeScale(unit));
+			patch.append("\n " + StringUtils.rightPad(path, maxPathLen, ' ') + " | " + StringUtils.leftPad("" + touple.total(), 4, ' ') + " " + touple.relativeScale(unit));
 		}
 		patch.append(MessageFormat.format("\n {0} files changed, {1} insertions(+), {2} deletions(-)\n\n", files, insertions, deletions));
 		patch.append(os.toString());
diff --git a/src/com/gitblit/utils/StringUtils.java b/src/com/gitblit/utils/StringUtils.java
new file mode 100644
index 0000000..6d646df
--- /dev/null
+++ b/src/com/gitblit/utils/StringUtils.java
@@ -0,0 +1,110 @@
+package com.gitblit.utils;
+
+import java.io.UnsupportedEncodingException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.List;
+
+public class StringUtils {
+	
+	public static boolean isEmpty(String value) {
+		return value == null || value.trim().length() == 0;
+	}
+
+	public static String breakLinesForHtml(String string) {
+		return string.replace("\r\n", "<br/>").replace("\r", "<br/>").replace("\n", "<br/>");
+	}
+
+	public static String escapeForHtml(String inStr, boolean changeSpace) {
+		StringBuffer retStr = new StringBuffer();
+		int i = 0;
+		while (i < inStr.length()) {
+			if (inStr.charAt(i) == '&') {
+				retStr.append("&amp;");
+			} else if (inStr.charAt(i) == '<') {
+				retStr.append("&lt;");
+			} else if (inStr.charAt(i) == '>') {
+				retStr.append("&gt;");
+			} else if (inStr.charAt(i) == '\"') {
+				retStr.append("&quot;");
+			} else if (changeSpace && inStr.charAt(i) == ' ') {
+				retStr.append("&nbsp;");
+			} else if (changeSpace && inStr.charAt(i) == '\t') {
+				retStr.append(" &nbsp; &nbsp;");
+			} else
+				retStr.append(inStr.charAt(i));
+			i++;
+		}
+		return retStr.toString();
+	}
+
+	public static String flattenStrings(List<String> values) {
+		StringBuilder sb = new StringBuilder();
+		for (String value : values) {
+			sb.append(value).append(" ");
+		}
+		return sb.toString().trim();
+	}
+
+	public static String trimString(String value, int max) {
+		if (value.length() <= max) {
+			return value;
+		}
+		return value.substring(0, max - 3) + "...";
+	}
+
+	public static String trimShortLog(String string) {
+		return trimString(string, 60);
+	}
+
+	public static String leftPad(String input, int length, char pad) {
+		if (input.length() < length) {
+			StringBuilder sb = new StringBuilder();
+			for (int i = 0, len = length - input.length(); i < len; i++) {
+				sb.append(pad);
+			}
+			sb.append(input);
+			return sb.toString();
+		}
+		return input;
+	}
+
+	public static String rightPad(String input, int length, char pad) {
+		if (input.length() < length) {
+			StringBuilder sb = new StringBuilder();
+			sb.append(input);
+			for (int i = 0, len = length - input.length(); i < len; i++) {
+				sb.append(pad);
+			}
+			return sb.toString();
+		}
+		return input;
+	}
+
+	public static String getSHA1(String text) {
+		try {
+			byte[] bytes = text.getBytes("iso-8859-1");
+			return getSHA1(bytes);
+		} catch (UnsupportedEncodingException u) {
+			throw new RuntimeException(u);
+		}
+	}
+
+	public static String getSHA1(byte[] bytes) {
+		try {
+			MessageDigest md = MessageDigest.getInstance("SHA-1");
+			md.update(bytes, 0, bytes.length);
+			byte[] sha1hash = md.digest();
+			StringBuilder sb = new StringBuilder(sha1hash.length * 2);
+			for (int i = 0; i < sha1hash.length; i++) {
+				if (((int) sha1hash[i] & 0xff) < 0x10)
+					sb.append("0");
+				sb.append(Long.toString((int) sha1hash[i] & 0xff, 16));
+			}
+			return sb.toString();
+		} catch (NoSuchAlgorithmException t) {
+			throw new RuntimeException(t);
+		}
+	}
+
+}
diff --git a/src/com/gitblit/utils/Utils.java b/src/com/gitblit/utils/TimeUtils.java
similarity index 69%
rename from src/com/gitblit/utils/Utils.java
rename to src/com/gitblit/utils/TimeUtils.java
index 6d0c6b3..60b525b 100644
--- a/src/com/gitblit/utils/Utils.java
+++ b/src/com/gitblit/utils/TimeUtils.java
@@ -2,7 +2,7 @@
 
 import java.util.Date;
 
-public class Utils {
+public class TimeUtils {
 	private final static long min = 1000 * 60l;
 
 	private final static long halfhour = min * 30l;
@@ -115,52 +115,5 @@
 			}
 		}
 		return ago;
-	}
-
-	public static String leftPad(String input, int length, char pad) {
-		if (input.length() < length) {
-			StringBuilder sb = new StringBuilder();
-			for (int i = 0, len = length - input.length(); i < len; i++) {
-				sb.append(pad);
-			}
-			sb.append(input);
-			return sb.toString();
-		}
-		return input;
-	}
-
-	public static String rightPad(String input, int length, char pad) {
-		if (input.length() < length) {
-			StringBuilder sb = new StringBuilder();
-			sb.append(input);
-			for (int i = 0, len = length - input.length(); i < len; i++) {
-				sb.append(pad);
-			}
-			return sb.toString();
-		}
-		return input;
-	}
-
-	public static String escapeForHtml(String inStr, boolean changeSpace) {
-		StringBuffer retStr = new StringBuffer();
-		int i = 0;
-		while (i < inStr.length()) {
-			if (inStr.charAt(i) == '&') {
-				retStr.append("&amp;");
-			} else if (inStr.charAt(i) == '<') {
-				retStr.append("&lt;");
-			} else if (inStr.charAt(i) == '>') {
-				retStr.append("&gt;");
-			} else if (inStr.charAt(i) == '\"') {
-				retStr.append("&quot;");
-			} else if (changeSpace && inStr.charAt(i) == ' ') {
-				retStr.append("&nbsp;");
-			} else if (changeSpace && inStr.charAt(i) == '\t') {
-				retStr.append(" &nbsp; &nbsp;");
-			} else
-				retStr.append(inStr.charAt(i));
-			i++;
-		}
-		return retStr.toString();
 	}
 }
diff --git a/src/com/gitblit/wicket/AuthorizationStrategy.java b/src/com/gitblit/wicket/AuthorizationStrategy.java
index b73e849..0a9d652 100644
--- a/src/com/gitblit/wicket/AuthorizationStrategy.java
+++ b/src/com/gitblit/wicket/AuthorizationStrategy.java
@@ -15,9 +15,15 @@
 	@SuppressWarnings({ "unchecked", "rawtypes" })
 	@Override
 	protected boolean isPageAuthorized(Class pageClass) {
-		if (BasePage.class.isAssignableFrom(pageClass))
-			return isAuthorized(pageClass);
-		// Return contruction by default
+		if (BasePage.class.isAssignableFrom(pageClass)) {
+			GitBlitWebSession session = GitBlitWebSession.get();
+			if (!session.isLoggedIn())
+				return false;
+			User user = session.getUser();
+			if (pageClass.isAnnotationPresent(AdminPage.class)) {
+				return user.canAdmin();
+			}
+		}
 		return true;
 	}
 
@@ -30,16 +36,5 @@
 			else
 				throw new RestartResponseAtInterceptPageException(RepositoriesPage.class);
 		}
-	}
-
-	protected boolean isAuthorized(Class<? extends BasePage> pageClass) {
-		GitBlitWebSession session = GitBlitWebSession.get();
-		if (!session.isLoggedIn())
-			return false;
-		User user = session.getUser();
-		if (pageClass.isAnnotationPresent(AdminPage.class)) {
-
-		}
-		return true;
 	}
 }
diff --git a/src/com/gitblit/wicket/BasePage.html b/src/com/gitblit/wicket/BasePage.html
index 9ca9f13..c3c56ef 100644
--- a/src/com/gitblit/wicket/BasePage.html
+++ b/src/com/gitblit/wicket/BasePage.html
@@ -32,7 +32,7 @@
 			<div style="float:right">
 				<a href="http://gitblit.com"><span wicket:id="gbVersion"></span></a> 
 			</div>
-			<div wicket:id="userText">[user text]</div>
+			<div wicket:id="userPanel">[user panel]</div>
 		</div>
 	</body>
 </html>
\ No newline at end of file
diff --git a/src/com/gitblit/wicket/BasePage.java b/src/com/gitblit/wicket/BasePage.java
index 9aa7baa..2540ce1 100644
--- a/src/com/gitblit/wicket/BasePage.java
+++ b/src/com/gitblit/wicket/BasePage.java
@@ -12,20 +12,22 @@
 import org.slf4j.LoggerFactory;
 
 import com.gitblit.Constants;
+import com.gitblit.GitBlit;
 import com.gitblit.Keys;
-import com.gitblit.StoredSettings;
 import com.gitblit.wicket.pages.SummaryPage;
 
 public abstract class BasePage extends WebPage {
 
-	Logger logger = LoggerFactory.getLogger(BasePage.class);
+	private final Logger logger;
 
 	public BasePage() {
 		super();
+		logger = LoggerFactory.getLogger(getClass());
 	}
 
 	public BasePage(PageParameters params) {
 		super(params);
+		logger = LoggerFactory.getLogger(getClass());
 	}
 
 	protected void setupPage(String repositoryName, String pageName) {
@@ -35,7 +37,7 @@
 			add(new Label("title", getServerName()));
 		}
 		// header
-		String siteName = StoredSettings.getString(Keys.web_siteName, Constants.NAME);
+		String siteName = GitBlit.self().settings().getString(Keys.web.siteName, Constants.NAME);
 		if (siteName == null || siteName.trim().length() == 0) {
 			siteName = Constants.NAME;
 		}
@@ -45,20 +47,20 @@
 
 		// footer
 		User user = null;
-		if (StoredSettings.getBoolean(Keys.web_authenticate, true)) {
+		if (GitBlit.self().settings().getBoolean(Keys.web.authenticate, true)) {
 			user = GitBlitWebSession.get().getUser();
-			add(new Label("userText", "Logout " + user.toString()));
+			add(new LinkPanel("userPanel", null, getString("gb.logout") + " " + user.toString(), LogoutPage.class));
 		} else {
-			add(new Label("userText", ""));
+			add(new Label("userPanel", ""));
 		}
 		add(new Label("gbVersion", "v" + Constants.VERSION));
-		if (StoredSettings.getBoolean(Keys.server_aggressiveHeapManagement, false)) {
+		if (GitBlit.self().settings().getBoolean(Keys.web.aggressiveHeapManagement, false)) {
 			System.gc();
 		}
 	}
 
 	protected TimeZone getTimeZone() {
-		return StoredSettings.getBoolean(Keys.web_useClientTimezone, false) ? GitBlitWebSession.get().getTimezone() : TimeZone.getDefault();
+		return GitBlit.self().settings().getBoolean(Keys.web.useClientTimezone, false) ? GitBlitWebSession.get().getTimezone() : TimeZone.getDefault();
 	}
 
 	protected String getServerName() {
diff --git a/src/com/gitblit/wicket/GitBlitWebApp.java b/src/com/gitblit/wicket/GitBlitWebApp.java
index 8589b75..b70c95f 100644
--- a/src/com/gitblit/wicket/GitBlitWebApp.java
+++ b/src/com/gitblit/wicket/GitBlitWebApp.java
@@ -12,7 +12,6 @@
 
 import com.gitblit.GitBlit;
 import com.gitblit.Keys;
-import com.gitblit.StoredSettings;
 import com.gitblit.wicket.pages.BlobDiffPage;
 import com.gitblit.wicket.pages.BlobPage;
 import com.gitblit.wicket.pages.BranchesPage;
@@ -36,14 +35,14 @@
 		super.init();
 
 		// Setup page authorization mechanism
-		if (StoredSettings.getBoolean(Keys.web_authenticate, false)) {
+		if (GitBlit.self().settings().getBoolean(Keys.web.authenticate, false)) {
 			AuthorizationStrategy authStrategy = new AuthorizationStrategy();
 			getSecuritySettings().setAuthorizationStrategy(authStrategy);
 			getSecuritySettings().setUnauthorizedComponentInstantiationListener(authStrategy);
 		}
 
 		// Grab Browser info (like timezone, etc)
-		if (StoredSettings.getBoolean(Keys.web_useClientTimezone, false)) {
+		if (GitBlit.self().settings().getBoolean(Keys.web.useClientTimezone, false)) {
 			getRequestCycleSettings().setGatherExtendedBrowserInfo(true);
 		}
 
@@ -61,11 +60,15 @@
 		mount(new MixedParamUrlCodingStrategy("/commitdiff", CommitDiffPage.class, new String[] { "r", "h" }));
 		mount(new MixedParamUrlCodingStrategy("/patch", PatchPage.class, new String[] { "r", "h", "f" }));
 
-		// setup extended urls
+		// setup ticgit urls
 		mount(new MixedParamUrlCodingStrategy("/ticgit", TicGitPage.class, new String[] { "r" }));
 		mount(new MixedParamUrlCodingStrategy("/ticgittkt", TicGitTicketPage.class, new String[] { "r", "h", "f" }));
 
-		mount(new MixedParamUrlCodingStrategy("/login", LoginPage.class, new String[] {}));
+		// setup login/logout urls, if we are using authentication
+		if (GitBlit.self().settings().getBoolean(Keys.web.authenticate, true)) {
+			mount(new MixedParamUrlCodingStrategy("/login", LoginPage.class, new String[] {}));
+			mount(new MixedParamUrlCodingStrategy("/logout", LogoutPage.class, new String[] {}));
+		}
 	}
 
 	@Override
@@ -88,10 +91,6 @@
 		if (GitBlit.self().isDebugMode())
 			return Application.DEVELOPMENT;
 		return Application.DEPLOYMENT;
-	}
-
-	public String getCloneUrl(String repositoryName) {
-		return StoredSettings.getString(Keys.git_cloneUrl, "https://localhost/git/") + repositoryName;
 	}
 
 	public static GitBlitWebApp get() {
diff --git a/src/com/gitblit/wicket/GitBlitWebApp.properties b/src/com/gitblit/wicket/GitBlitWebApp.properties
index 273ff5a..1088891 100644
--- a/src/com/gitblit/wicket/GitBlitWebApp.properties
+++ b/src/com/gitblit/wicket/GitBlitWebApp.properties
@@ -40,4 +40,8 @@
 gb.pageNext = next
 gb.parent = parent
 gb.head = HEAD
-gb.blame = blame
\ No newline at end of file
+gb.blame = blame
+gb.login = Login
+gb.logout = Logout
+gb.username = Username
+gb.password = Password
\ No newline at end of file
diff --git a/src/com/gitblit/wicket/LinkPanel.java b/src/com/gitblit/wicket/LinkPanel.java
index ab55cfd..91f24fa 100644
--- a/src/com/gitblit/wicket/LinkPanel.java
+++ b/src/com/gitblit/wicket/LinkPanel.java
@@ -16,6 +16,10 @@
 
 	private final IModel<String> labelModel;
 
+	public LinkPanel(String wicketId, String linkCssClass, String label, Class<? extends WebPage> clazz) {
+		this(wicketId, linkCssClass, new Model<String>(label), clazz, null);
+	}
+	
 	public LinkPanel(String wicketId, String linkCssClass, String label, Class<? extends WebPage> clazz, PageParameters parameters) {
 		this(wicketId, linkCssClass, new Model<String>(label), clazz, parameters);
 	}
diff --git a/src/com/gitblit/wicket/LoginPage.html b/src/com/gitblit/wicket/LoginPage.html
index adbe64f..7108edb 100644
--- a/src/com/gitblit/wicket/LoginPage.html
+++ b/src/com/gitblit/wicket/LoginPage.html
@@ -17,17 +17,21 @@
 	<body onload="document.getElementById('username').focus();">
 	<div>
 		<center>
-			<img wicket:id="logo" /><br/>
+			<wicket:link>
+				<img src="resources/gitblt2.png" alt="Git:Blit"/><br/>
+			</wicket:link>
 			<span style="font-weight:bold;" wicket:id="name">[name]</span><br/>
 
 			<div>
 				<form style="text-align:center;" wicket:id="loginForm">
 					<p/>
-					Username <input type="text" id="username" wicket:id="username" value=""/>
+					<wicket:message key="gb.username"></wicket:message>
+					<input type="text" id="username" wicket:id="username" value=""/>
 					<p/>
-					Password <input type="password"  wicket:id="password" value=""/>
+					<wicket:message key="gb.password"></wicket:message>
+					<input type="password"  wicket:id="password" value=""/>
 					<p/>
-					<input type="submit" value="Login" />
+					<input type="submit" value="Login" wicket:message="value:gb.login" />
 					<div style="background-color:#c7c7c7" wicket:id="feedback"></div>
 				</form>
 			</div>
diff --git a/src/com/gitblit/wicket/LoginPage.java b/src/com/gitblit/wicket/LoginPage.java
index e3a345c..3f8206e 100644
--- a/src/com/gitblit/wicket/LoginPage.java
+++ b/src/com/gitblit/wicket/LoginPage.java
@@ -1,24 +1,23 @@
 package com.gitblit.wicket;
 
 import javax.servlet.http.Cookie;
-import javax.servlet.http.HttpServletRequest;
 
 import org.apache.wicket.PageParameters;
 import org.apache.wicket.markup.html.WebPage;
 import org.apache.wicket.markup.html.basic.Label;
 import org.apache.wicket.markup.html.form.Form;
 import org.apache.wicket.markup.html.form.PasswordTextField;
+import org.apache.wicket.markup.html.form.StatelessForm;
 import org.apache.wicket.markup.html.form.TextField;
-import org.apache.wicket.markup.html.image.ContextImage;
 import org.apache.wicket.markup.html.panel.FeedbackPanel;
 import org.apache.wicket.model.IModel;
 import org.apache.wicket.model.Model;
 import org.apache.wicket.protocol.http.WebRequest;
 import org.apache.wicket.protocol.http.WebResponse;
-import org.apache.wicket.protocol.http.servlet.ServletWebRequest;
 
 import com.gitblit.Constants;
 import com.gitblit.GitBlit;
+import com.gitblit.Keys;
 
 public class LoginPage extends WebPage {
 
@@ -30,8 +29,7 @@
 
 		tryAutomaticLogin();
 
-		add(new Label("title", getServerName()));
-		add(new ContextImage("logo", "gitblt2.png"));
+		add(new Label("title", GitBlit.self().settings().getString(Keys.web.siteName, Constants.NAME)));
 		add(new Label("name", Constants.NAME));
 
 		Form<Void> loginForm = new LoginForm("loginForm");
@@ -41,17 +39,20 @@
 		add(loginForm);
 	}
 
-	protected String getServerName() {
-		ServletWebRequest servletWebRequest = (ServletWebRequest) getRequest();
-		HttpServletRequest req = servletWebRequest.getHttpServletRequest();
-		return req.getServerName();
-	}
-
-	class LoginForm extends Form<Void> {
+	class LoginForm extends StatelessForm<Void> {
 		private static final long serialVersionUID = 1L;
 
 		public LoginForm(String id) {
 			super(id);
+
+			// If we are already logged in because user directly accessed
+			// the login url, redirect to the home page
+			if (GitBlitWebSession.get().isLoggedIn()) {
+				setRedirect(true);
+				setResponsePage(getApplication().getHomePage());
+			}
+			
+			tryAutomaticLogin();
 		}
 
 		@Override
@@ -82,20 +83,16 @@
 
 	private void loginUser(User user) {
 		if (user != null) {
-			GitBlitWebSession session = GitBlitWebSession.get();
+			// Set the user into the session
+			GitBlitWebSession.get().setUser(user);
 
 			// Set Cookie
 			WebResponse response = (WebResponse) getRequestCycle().getResponse();
 			GitBlit.self().setCookie(response, user);
 
-			// track user object so that we do not have to continue
-			// re-authenticating on each request.
-			session.setUser(user);
-
-			// Redirect to original page OR to first available tab
 			if (!continueToOriginalDestination()) {
 				// Redirect to home page
-				setResponsePage(session.getApplication().getHomePage());
+				setResponsePage(getApplication().getHomePage());
 			}
 		}
 	}
diff --git a/src/com/gitblit/wicket/LogoutPage.java b/src/com/gitblit/wicket/LogoutPage.java
new file mode 100644
index 0000000..278fbec
--- /dev/null
+++ b/src/com/gitblit/wicket/LogoutPage.java
@@ -0,0 +1,12 @@
+package com.gitblit.wicket;
+
+import org.apache.wicket.markup.html.WebPage;
+
+public class LogoutPage extends WebPage {
+
+	public LogoutPage() {
+		getSession().invalidate();
+		setRedirect(true);
+		setResponsePage(getApplication().getHomePage());
+	}
+}
\ No newline at end of file
diff --git a/src/com/gitblit/wicket/RepositoryPage.java b/src/com/gitblit/wicket/RepositoryPage.java
index e719669..7378543 100644
--- a/src/com/gitblit/wicket/RepositoryPage.java
+++ b/src/com/gitblit/wicket/RepositoryPage.java
@@ -11,10 +11,13 @@
 import org.apache.wicket.protocol.http.servlet.ServletWebRequest;
 import org.eclipse.jgit.lib.Repository;
 import org.eclipse.jgit.revwalk.RevCommit;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import com.gitblit.GitBlit;
-import com.gitblit.StoredSettings;
+import com.gitblit.Keys;
 import com.gitblit.utils.JGitUtils;
+import com.gitblit.utils.StringUtils;
 import com.gitblit.wicket.pages.RepositoriesPage;
 import com.gitblit.wicket.panels.PageLinksPanel;
 import com.gitblit.wicket.panels.RefsPanel;
@@ -27,6 +30,8 @@
 
 	private transient Repository r = null;
 
+	private final Logger logger = LoggerFactory.getLogger(RepositoryPage.class);
+	
 	public RepositoryPage(PageParameters params) {
 		super(params);
 		if (!params.containsKey("r")) {
@@ -69,20 +74,24 @@
 	}
 
 	protected void addFullText(String wicketId, String text, boolean substituteRegex) {
-		String html = WicketUtils.breakLines(text);
+		String html = StringUtils.breakLinesForHtml(text);
 		if (substituteRegex) {
 			Map<String, String> map = new HashMap<String, String>();
 			// global regex keys
-			for (String key : StoredSettings.getAllKeys("regex.global")) {
-				String subKey = key.substring(key.lastIndexOf('.') + 1);
-				map.put(subKey, StoredSettings.getString(key, ""));
+			if (GitBlit.self().settings().getBoolean(Keys.regex.global, false)) {
+				for (String key : GitBlit.self().settings().getAllKeys(Keys.regex.global)) {
+					if (!key.equals(Keys.regex.global)) {
+						String subKey = key.substring(key.lastIndexOf('.') + 1);
+						map.put(subKey, GitBlit.self().settings().getString(key, ""));
+					}
+				}
 			}
 
 			// repository-specific regex keys
-			List<String> keys = StoredSettings.getAllKeys("regex." + repositoryName.toLowerCase());
+			List<String> keys = GitBlit.self().settings().getAllKeys(Keys.regex._ROOT + "." + repositoryName.toLowerCase());
 			for (String key : keys) {
 				String subKey = key.substring(key.lastIndexOf('.') + 1);
-				map.put(subKey, StoredSettings.getString(key, ""));
+				map.put(subKey, GitBlit.self().settings().getString(key, ""));
 			}
 
 			for (String key : map.keySet()) {
diff --git a/src/com/gitblit/wicket/User.java b/src/com/gitblit/wicket/User.java
index e506c8c..bd5e8c9 100644
--- a/src/com/gitblit/wicket/User.java
+++ b/src/com/gitblit/wicket/User.java
@@ -1,10 +1,14 @@
 package com.gitblit.wicket;
 
-import com.gitblit.Build;
+import java.io.Serializable;
+
 import com.gitblit.Constants;
+import com.gitblit.utils.StringUtils;
 
-public class User {
+public class User implements Serializable {
 
+	private static final long serialVersionUID = 1L;
+	
 	private String username;
 	private String cookie;
 	private boolean canAdmin = false;
@@ -13,7 +17,7 @@
 
 	public User(String username, char[] password) {
 		this.username = username;
-		this.cookie = Build.getSHA1((Constants.NAME + username + new String(password)).getBytes());
+		this.cookie = StringUtils.getSHA1((Constants.NAME + username + new String(password)));
 	}
 
 	public void canAdmin(boolean value) {
diff --git a/src/com/gitblit/wicket/WicketUtils.java b/src/com/gitblit/wicket/WicketUtils.java
index 27992f1..3288498 100644
--- a/src/com/gitblit/wicket/WicketUtils.java
+++ b/src/com/gitblit/wicket/WicketUtils.java
@@ -3,7 +3,6 @@
 import java.text.DateFormat;
 import java.text.SimpleDateFormat;
 import java.util.Date;
-import java.util.List;
 import java.util.TimeZone;
 
 import org.apache.wicket.Component;
@@ -12,9 +11,9 @@
 import org.apache.wicket.markup.html.basic.Label;
 import org.eclipse.jgit.lib.Constants;
 
+import com.gitblit.GitBlit;
 import com.gitblit.Keys;
-import com.gitblit.StoredSettings;
-import com.gitblit.utils.Utils;
+import com.gitblit.utils.TimeUtils;
 
 public class WicketUtils {
 
@@ -28,10 +27,6 @@
 
 	public static void setHtmlTitle(Component container, String value) {
 		container.add(new SimpleAttributeModifier("title", value));
-	}
-
-	public static String breakLines(String string) {
-		return string.replace("\r", "<br/>").replace("\n", "<br/>");
 	}
 
 	public static void setTicketCssClass(Component container, String state) {
@@ -50,14 +45,6 @@
 		}
 	}
 
-	public static String flattenStrings(List<String> values) {
-		StringBuilder sb = new StringBuilder();
-		for (String value : values) {
-			sb.append(value).append(" ");
-		}
-		return sb.toString().trim();
-	}
-
 	public static void setAlternatingBackground(Component c, int i) {
 		String clazz = i % 2 == 0 ? "dark" : "light";
 		setCssClass(c, clazz);
@@ -67,17 +54,6 @@
 		Label label = new Label(wicketId, author);
 		WicketUtils.setHtmlTitle(label, author);
 		return label;
-	}
-
-	public static String trimShortLog(String string) {
-		return trimString(string, 60);
-	}
-
-	public static String trimString(String value, int max) {
-		if (value.length() <= max) {
-			return value;
-		}
-		return value.substring(0, max - 3) + "...";
 	}
 
 	public static PageParameters newRepositoryParameter(String repositoryName) {
@@ -122,30 +98,30 @@
 	}
 
 	public static Label createDateLabel(String wicketId, Date date, TimeZone timeZone) {
-		DateFormat df = new SimpleDateFormat(StoredSettings.getString(Keys.web_datestampShortFormat, "MM/dd/yy"));
+		DateFormat df = new SimpleDateFormat(GitBlit.self().settings().getString(Keys.web.datestampShortFormat, "MM/dd/yy"));
 		if (timeZone != null) {
 			df.setTimeZone(timeZone);
 		}
 		String dateString = df.format(date);
-		String title = Utils.timeAgo(date);
+		String title = TimeUtils.timeAgo(date);
 		if ((System.currentTimeMillis() - date.getTime()) < 10 * 24 * 60 * 60 * 1000l) {
 			String tmp = dateString;
 			dateString = title;
 			title = tmp;
 		}
 		Label label = new Label(wicketId, dateString);
-		WicketUtils.setCssClass(label, Utils.timeAgoCss(date));
+		WicketUtils.setCssClass(label, TimeUtils.timeAgoCss(date));
 		WicketUtils.setHtmlTitle(label, title);
 		return label;
 	}
 
 	public static Label createTimestampLabel(String wicketId, Date date, TimeZone timeZone) {
-		DateFormat df = new SimpleDateFormat(StoredSettings.getString(Keys.web_datetimestampLongFormat, "EEEE, MMMM d, yyyy h:mm a z"));
+		DateFormat df = new SimpleDateFormat(GitBlit.self().settings().getString(Keys.web.datetimestampLongFormat, "EEEE, MMMM d, yyyy h:mm a z"));
 		if (timeZone != null) {
 			df.setTimeZone(timeZone);
 		}
 		String dateString = df.format(date);
-		String title = Utils.timeAgo(date);
+		String title = TimeUtils.timeAgo(date);
 		Label label = new Label(wicketId, dateString);
 		WicketUtils.setHtmlTitle(label, title);
 		return label;
diff --git a/src/com/gitblit/wicket/pages/BlobPage.java b/src/com/gitblit/wicket/pages/BlobPage.java
index 51749a3..51eadf3 100644
--- a/src/com/gitblit/wicket/pages/BlobPage.java
+++ b/src/com/gitblit/wicket/pages/BlobPage.java
@@ -11,8 +11,8 @@
 import org.eclipse.jgit.lib.Repository;
 import org.eclipse.jgit.revwalk.RevCommit;
 
+import com.gitblit.GitBlit;
 import com.gitblit.Keys;
-import com.gitblit.StoredSettings;
 import com.gitblit.utils.JGitUtils;
 import com.gitblit.wicket.LinkPanel;
 import com.gitblit.wicket.RepositoryPage;
@@ -45,13 +45,13 @@
 
 		// Map the extensions to types
 		Map<String, Integer> map = new HashMap<String, Integer>();
-		for (String ext : StoredSettings.getStrings(Keys.web_prettyPrintExtensions)) {
+		for (String ext : GitBlit.self().settings().getStrings(Keys.web.prettyPrintExtensions)) {
 			map.put(ext.toLowerCase(), 1);
 		}
-		for (String ext : StoredSettings.getStrings(Keys.web_imageExtensions)) {
+		for (String ext : GitBlit.self().settings().getStrings(Keys.web.imageExtensions)) {
 			map.put(ext.toLowerCase(), 2);
 		}
-		for (String ext : StoredSettings.getStrings(Keys.web_binaryExtensions)) {
+		for (String ext : GitBlit.self().settings().getStrings(Keys.web.binaryExtensions)) {
 			map.put(ext.toLowerCase(), 3);
 		}
 
diff --git a/src/com/gitblit/wicket/pages/RawPage.java b/src/com/gitblit/wicket/pages/RawPage.java
index 961e4c9..4cbf96c 100644
--- a/src/com/gitblit/wicket/pages/RawPage.java
+++ b/src/com/gitblit/wicket/pages/RawPage.java
@@ -15,7 +15,6 @@
 
 import com.gitblit.GitBlit;
 import com.gitblit.Keys;
-import com.gitblit.StoredSettings;
 import com.gitblit.utils.JGitUtils;
 import com.gitblit.wicket.WicketUtils;
 
@@ -52,10 +51,10 @@
 
 		// Map the extensions to types
 		Map<String, Integer> map = new HashMap<String, Integer>();
-		for (String ext : StoredSettings.getStrings(Keys.web_imageExtensions)) {
+		for (String ext : GitBlit.self().settings().getStrings(Keys.web.imageExtensions)) {
 			map.put(ext.toLowerCase(), 2);
 		}
-		for (String ext : StoredSettings.getStrings(Keys.web_binaryExtensions)) {
+		for (String ext : GitBlit.self().settings().getStrings(Keys.web.binaryExtensions)) {
 			map.put(ext.toLowerCase(), 3);
 		}
 
diff --git a/src/com/gitblit/wicket/pages/RepositoriesPage.java b/src/com/gitblit/wicket/pages/RepositoriesPage.java
index eca216c..fd7ab52 100644
--- a/src/com/gitblit/wicket/pages/RepositoriesPage.java
+++ b/src/com/gitblit/wicket/pages/RepositoriesPage.java
@@ -19,8 +19,7 @@
 
 import com.gitblit.GitBlit;
 import com.gitblit.Keys;
-import com.gitblit.StoredSettings;
-import com.gitblit.utils.Utils;
+import com.gitblit.utils.TimeUtils;
 import com.gitblit.wicket.BasePage;
 import com.gitblit.wicket.GitBlitWebSession;
 import com.gitblit.wicket.LinkPanel;
@@ -34,11 +33,11 @@
 		setupPage("", "");
 
 		boolean showAdmin = false;
-		if (StoredSettings.getBoolean(Keys.web_authenticate, true)) {
-			boolean allowAdmin = StoredSettings.getBoolean(Keys.web_allowAdministration, false);
+		if (GitBlit.self().settings().getBoolean(Keys.web.authenticate, true)) {
+			boolean allowAdmin = GitBlit.self().settings().getBoolean(Keys.web.allowAdministration, false);
 			showAdmin = allowAdmin && GitBlitWebSession.get().canAdmin();
 		} else {
-			showAdmin = StoredSettings.getBoolean(Keys.web_allowAdministration, false);
+			showAdmin = GitBlit.self().settings().getBoolean(Keys.web.allowAdministration, false);
 		}
 
 		Fragment adminLinks = new Fragment("adminPanel", "adminLinks", this);
@@ -46,7 +45,7 @@
 		adminLinks.add(new BookmarkablePageLink<Void>("newUser", RepositoriesPage.class));
 		add(adminLinks.setVisible(showAdmin));
 
-		add(new Label("repositoriesMessage", StoredSettings.getString(Keys.web_repositoriesMessage, "")).setEscapeModelStrings(false));
+		add(new Label("repositoriesMessage", GitBlit.self().settings().getString(Keys.web.repositoriesMessage, "")).setEscapeModelStrings(false));
 
 		List<RepositoryModel> rows = GitBlit.self().getRepositories(getRequest());
 		DataProvider dp = new DataProvider(rows);
@@ -61,10 +60,10 @@
 				item.add(new LinkPanel("repositoryDescription", "list", entry.description, SummaryPage.class, pp));
 				item.add(new Label("repositoryOwner", entry.owner));
 
-				String lastChange = Utils.timeAgo(entry.lastChange);
+				String lastChange = TimeUtils.timeAgo(entry.lastChange);
 				Label lastChangeLabel = new Label("repositoryLastChange", lastChange);
 				item.add(lastChangeLabel);
-				WicketUtils.setCssClass(lastChangeLabel, Utils.timeAgoCss(entry.lastChange));
+				WicketUtils.setCssClass(lastChangeLabel, TimeUtils.timeAgoCss(entry.lastChange));
 
 				WicketUtils.setAlternatingBackground(item, counter);
 				counter++;
diff --git a/src/com/gitblit/wicket/pages/SummaryPage.java b/src/com/gitblit/wicket/pages/SummaryPage.java
index 50de96e..6d28df6 100644
--- a/src/com/gitblit/wicket/pages/SummaryPage.java
+++ b/src/com/gitblit/wicket/pages/SummaryPage.java
@@ -15,10 +15,9 @@
 import com.codecommit.wicket.ChartProvider;
 import com.codecommit.wicket.ChartType;
 import com.codecommit.wicket.IChartData;
+import com.gitblit.GitBlit;
 import com.gitblit.Keys;
-import com.gitblit.StoredSettings;
 import com.gitblit.utils.JGitUtils;
-import com.gitblit.wicket.GitBlitWebApp;
 import com.gitblit.wicket.RepositoryPage;
 import com.gitblit.wicket.WicketUtils;
 import com.gitblit.wicket.models.Metric;
@@ -34,12 +33,12 @@
 		int numCommitsDef = 20;
 		int numRefsDef = 5;
 
-		int numberCommits = StoredSettings.getInteger(Keys.web_summaryCommitCount, numCommitsDef);
+		int numberCommits = GitBlit.self().settings().getInteger(Keys.web.summaryCommitCount, numCommitsDef);
 		if (numberCommits <= 0) {
 			numberCommits = numCommitsDef;
 		}
 
-		int numberRefs = StoredSettings.getInteger(Keys.web_summaryRefsCount, numRefsDef);
+		int numberRefs = GitBlit.self().settings().getInteger(Keys.web.summaryRefsCount, numRefsDef);
 		if (numberRefs <= 0) {
 			numberRefs = numRefsDef;
 		}
@@ -57,7 +56,7 @@
 		add(new Label("repositoryOwner", JGitUtils.getRepositoryOwner(r)));
 
 		add(WicketUtils.createTimestampLabel("repositoryLastChange", JGitUtils.getLastChange(r), getTimeZone()));
-		add(new Label("repositoryCloneUrl", GitBlitWebApp.get().getCloneUrl(repositoryName)));
+		add(new Label("repositoryCloneUrl", GitBlit.self().getCloneUrl(repositoryName)));
 
 		add(new LogPanel("commitsPanel", repositoryName, null, r, numberCommits, 0));
 		add(new TagsPanel("tagsPanel", repositoryName, r, numberRefs));
@@ -73,7 +72,7 @@
 	}
 
 	private void insertActivityGraph(List<Metric> metrics) {
-		if (StoredSettings.getBoolean(Keys.web_generateActivityGraph, true)) {
+		if (GitBlit.self().settings().getBoolean(Keys.web.generateActivityGraph, true)) {
 			IChartData data = getChartData(metrics);
 
 			ChartProvider provider = new ChartProvider(new Dimension(400, 80), ChartType.LINE, data);
diff --git a/src/com/gitblit/wicket/pages/TicGitPage.java b/src/com/gitblit/wicket/pages/TicGitPage.java
index 204565c..a03ee60 100644
--- a/src/com/gitblit/wicket/pages/TicGitPage.java
+++ b/src/com/gitblit/wicket/pages/TicGitPage.java
@@ -9,6 +9,7 @@
 import org.apache.wicket.markup.repeater.data.ListDataProvider;
 
 import com.gitblit.utils.JGitUtils;
+import com.gitblit.utils.StringUtils;
 import com.gitblit.wicket.GitBlitWebSession;
 import com.gitblit.wicket.LinkPanel;
 import com.gitblit.wicket.RepositoryPage;
@@ -36,8 +37,8 @@
 				WicketUtils.setTicketCssClass(stateLabel, entry.state);
 				item.add(stateLabel);
 				item.add(WicketUtils.createDateLabel("ticketDate", entry.date, GitBlitWebSession.get().getTimezone()));
-				item.add(new Label("ticketHandler", WicketUtils.trimString(entry.handler.toLowerCase(), 30)));
-				item.add(new LinkPanel("ticketTitle", "list subject", WicketUtils.trimString(entry.title, 80), TicGitTicketPage.class, newPathParameter(entry.name)));
+				item.add(new Label("ticketHandler", StringUtils.trimString(entry.handler.toLowerCase(), 30)));
+				item.add(new LinkPanel("ticketTitle", "list subject", StringUtils.trimString(entry.title, 80), TicGitTicketPage.class, newPathParameter(entry.name)));
 
 				WicketUtils.setAlternatingBackground(item, counter);
 				counter++;
diff --git a/src/com/gitblit/wicket/pages/TicGitTicketPage.html b/src/com/gitblit/wicket/pages/TicGitTicketPage.html
index aafbf8c..56e2980 100644
--- a/src/com/gitblit/wicket/pages/TicGitTicketPage.html
+++ b/src/com/gitblit/wicket/pages/TicGitTicketPage.html
@@ -29,8 +29,9 @@
 	<table style="width:100%;" class="comments">
 		<tbody>
 			<tr valign="top" wicket:id="comment">
-         		<td><span class="date" wicket:id="commentDate">[comment date]</span><br/>
-         		<span class="author" wicket:id="commentAuthor">[comment author]</span></td>
+         		<td><span class="author" wicket:id="commentAuthor">[comment author]</span><br/>
+         			<span class="date" wicket:id="commentDate">[comment date]</span>
+         		</td>
          		<td><span wicket:id="commentText">[comment text]</span></td>
        		</tr>
        	</tbody>
diff --git a/src/com/gitblit/wicket/pages/TicGitTicketPage.java b/src/com/gitblit/wicket/pages/TicGitTicketPage.java
index 30bd6cc..b4c9cf5 100644
--- a/src/com/gitblit/wicket/pages/TicGitTicketPage.java
+++ b/src/com/gitblit/wicket/pages/TicGitTicketPage.java
@@ -8,7 +8,7 @@
 import org.eclipse.jgit.lib.Repository;
 
 import com.gitblit.utils.JGitUtils;
-import com.gitblit.utils.Utils;
+import com.gitblit.utils.StringUtils;
 import com.gitblit.wicket.GitBlitWebSession;
 import com.gitblit.wicket.RepositoryPage;
 import com.gitblit.wicket.WicketUtils;
@@ -32,7 +32,7 @@
 		Label stateLabel = new Label("ticketState", t.state);
 		WicketUtils.setTicketCssClass(stateLabel, t.state);
 		add(stateLabel);
-		add(new Label("ticketTags", WicketUtils.flattenStrings(t.tags)));
+		add(new Label("ticketTags", StringUtils.flattenStrings(t.tags)));
 
 		ListDataProvider<Comment> commentsDp = new ListDataProvider<Comment>(t.comments);
 		DataView<Comment> commentsView = new DataView<Comment>("comment", commentsDp) {
@@ -57,8 +57,8 @@
 	}
 
 	private String prepareComment(String comment) {
-		String html = Utils.escapeForHtml(comment, false);
-		html = WicketUtils.breakLines(comment).trim();
+		String html = StringUtils.escapeForHtml(comment, false);
+		html = StringUtils.breakLinesForHtml(comment).trim();
 		return html.replaceAll("\\bcommit\\s*([A-Za-z0-9]*)\\b", "<a href=\"/commit/" + repositoryName + "/$1\">commit $1</a>");
 	}
 }
diff --git a/src/com/gitblit/wicket/panels/BasePanel.java b/src/com/gitblit/wicket/panels/BasePanel.java
index cdfc050..6ddc0a0 100644
--- a/src/com/gitblit/wicket/panels/BasePanel.java
+++ b/src/com/gitblit/wicket/panels/BasePanel.java
@@ -4,8 +4,8 @@
 
 import org.apache.wicket.markup.html.panel.Panel;
 
+import com.gitblit.GitBlit;
 import com.gitblit.Keys;
-import com.gitblit.StoredSettings;
 import com.gitblit.wicket.GitBlitWebSession;
 
 public abstract class BasePanel extends Panel {
@@ -17,6 +17,6 @@
 	}
 
 	protected TimeZone getTimeZone() {
-		return StoredSettings.getBoolean(Keys.web_useClientTimezone, false) ? GitBlitWebSession.get().getTimezone() : TimeZone.getDefault();
+		return GitBlit.self().settings().getBoolean(Keys.web.useClientTimezone, false) ? GitBlitWebSession.get().getTimezone() : TimeZone.getDefault();
 	}
 }
diff --git a/src/com/gitblit/wicket/panels/BranchesPanel.java b/src/com/gitblit/wicket/panels/BranchesPanel.java
index 8ac78e4..ff4679f 100644
--- a/src/com/gitblit/wicket/panels/BranchesPanel.java
+++ b/src/com/gitblit/wicket/panels/BranchesPanel.java
@@ -14,6 +14,7 @@
 import org.eclipse.jgit.lib.Repository;
 
 import com.gitblit.utils.JGitUtils;
+import com.gitblit.utils.StringUtils;
 import com.gitblit.wicket.LinkPanel;
 import com.gitblit.wicket.WicketUtils;
 import com.gitblit.wicket.models.RefModel;
@@ -59,7 +60,7 @@
 
 				item.add(WicketUtils.createDateLabel("branchDate", entry.getDate(), getTimeZone()));
 
-				item.add(new LinkPanel("branchName", "list name", WicketUtils.trimString(entry.getDisplayName(), 28), LogPage.class, WicketUtils.newObjectParameter(repositoryName, entry.getName())));
+				item.add(new LinkPanel("branchName", "list name", StringUtils.trimString(entry.getDisplayName(), 28), LogPage.class, WicketUtils.newObjectParameter(repositoryName, entry.getName())));
 
 				// only show branch type on the branches page
 				boolean remote = entry.getName().startsWith(Constants.R_REMOTES);
diff --git a/src/com/gitblit/wicket/panels/LogPanel.java b/src/com/gitblit/wicket/panels/LogPanel.java
index 504bdd3..2075410 100644
--- a/src/com/gitblit/wicket/panels/LogPanel.java
+++ b/src/com/gitblit/wicket/panels/LogPanel.java
@@ -14,9 +14,10 @@
 import org.eclipse.jgit.lib.Repository;
 import org.eclipse.jgit.revwalk.RevCommit;
 
+import com.gitblit.GitBlit;
 import com.gitblit.Keys;
-import com.gitblit.StoredSettings;
 import com.gitblit.utils.JGitUtils;
+import com.gitblit.utils.StringUtils;
 import com.gitblit.wicket.LinkPanel;
 import com.gitblit.wicket.WicketUtils;
 import com.gitblit.wicket.pages.CommitDiffPage;
@@ -32,7 +33,7 @@
 	public LogPanel(String wicketId, final String repositoryName, String objectId, Repository r, int limit, int pageOffset) {
 		super(wicketId);
 		boolean pageResults = limit <= 0;
-		int itemsPerPage = StoredSettings.getInteger(Keys.web_logPageCommitCount, 50);
+		int itemsPerPage = GitBlit.self().settings().getInteger(Keys.web.logPageCommitCount, 50);
 		if (itemsPerPage <= 1) {
 			itemsPerPage = 50;
 		}
@@ -73,7 +74,7 @@
 				item.add(WicketUtils.createAuthorLabel("commitAuthor", author));
 
 				String shortMessage = entry.getShortMessage();
-				String trimmedMessage = WicketUtils.trimShortLog(shortMessage);
+				String trimmedMessage = StringUtils.trimShortLog(shortMessage);
 				LinkPanel shortlog = new LinkPanel("commitShortMessage", "list subject", trimmedMessage, CommitPage.class, WicketUtils.newObjectParameter(repositoryName, entry.getName()));
 				if (!shortMessage.equals(trimmedMessage)) {
 					WicketUtils.setHtmlTitle(shortlog, shortMessage);
diff --git a/src/com/gitblit/wicket/panels/PageLinksPanel.java b/src/com/gitblit/wicket/panels/PageLinksPanel.java
index 252b49a..18cfad6 100644
--- a/src/com/gitblit/wicket/panels/PageLinksPanel.java
+++ b/src/com/gitblit/wicket/panels/PageLinksPanel.java
@@ -15,7 +15,8 @@
 import org.apache.wicket.markup.repeater.data.ListDataProvider;
 import org.eclipse.jgit.lib.Repository;
 
-import com.gitblit.StoredSettings;
+import com.gitblit.GitBlit;
+import com.gitblit.Keys;
 import com.gitblit.utils.JGitUtils;
 import com.gitblit.wicket.LinkPanel;
 import com.gitblit.wicket.WicketUtils;
@@ -55,8 +56,8 @@
 		add(new BookmarkablePageLink<Void>("tree", TreePage.class, WicketUtils.newRepositoryParameter(repositoryName)));
 
 		// Get the repository ticgit setting
-		boolean checkTicgit = StoredSettings.getBoolean("ticgit.global", false);
-		checkTicgit |= StoredSettings.getBoolean(MessageFormat.format("ticgit.{0}", repositoryName), false);
+		boolean checkTicgit = GitBlit.self().settings().getBoolean(Keys.ticgit.global, false);
+		checkTicgit |= GitBlit.self().settings().getBoolean(MessageFormat.format(Keys.ticgit._ROOT + ".{0}", repositoryName), false);
 
 		// Add dynamic repository extras
 		List<String> extras = new ArrayList<String>();
diff --git a/src/com/gitblit/wicket/panels/TagsPanel.java b/src/com/gitblit/wicket/panels/TagsPanel.java
index 3d8364c..979a275 100644
--- a/src/com/gitblit/wicket/panels/TagsPanel.java
+++ b/src/com/gitblit/wicket/panels/TagsPanel.java
@@ -11,6 +11,7 @@
 import org.eclipse.jgit.lib.Repository;
 
 import com.gitblit.utils.JGitUtils;
+import com.gitblit.utils.StringUtils;
 import com.gitblit.wicket.LinkPanel;
 import com.gitblit.wicket.WicketUtils;
 import com.gitblit.wicket.models.RefModel;
@@ -52,7 +53,7 @@
 				item.add(new LinkPanel("tagName", "list name", entry.getDisplayName(), CommitPage.class, WicketUtils.newObjectParameter(repositoryName, entry.getCommitId().getName())));
 				String message;
 				if (maxCount > 0) {
-					message = WicketUtils.trimString(entry.getShortLog(), 40);
+					message = StringUtils.trimString(entry.getShortLog(), 40);
 				} else {
 					message = entry.getShortLog();
 				}

--
Gitblit v1.9.1