From fc84260e4238fda10842c1bd3b9fb0cb74b95426 Mon Sep 17 00:00:00 2001
From: James Moger <james.moger@gitblit.com>
Date: Mon, 04 Apr 2011 16:13:11 -0400
Subject: [PATCH] Dropped log links, created new stylesheet, added activity graph.

---
 src/com/gitblit/wicket/panels/TagLinksPanel.html        |    2 
 src/com/gitblit/wicket/panels/PathLinksPanel.java       |    2 
 contrib/com/codecommit/wicket/RangeMarker.java          |   55 +
 .classpath                                              |    1 
 contrib/com/codecommit/wicket/LinearStripesFill.java    |   49 +
 contrib/com/codecommit/wicket/ISolidFill.java           |   13 
 src/com/gitblit/wicket/pages/ShortLogPage.html          |   13 
 gitblit.properties                                      |    8 
 src/com/gitblit/wicket/WicketUtils.java                 |   20 
 contrib/com/codecommit/wicket/ChartDataEncoding.java    |   82 +
 contrib/com/codecommit/wicket/IFillArea.java            |   21 
 src/com/gitblit/wicket/panels/TagLinksPanel.java        |    2 
 contrib/com/codecommit/wicket/ChartAxisType.java        |   25 
 contrib/com/codecommit/wicket/ChartAxis.java            |   79 +
 contrib/com/codecommit/wicket/IChartData.java           |   16 
 src/com/gitblit/wicket/pages/BlobPage.java              |    4 
 src/com/gitblit/wicket/models/Metric.java               |   15 
 contrib/com/codecommit/wicket/LinearGradientFill.java   |   49 +
 src/com/gitblit/wicket/pages/HeadsPage.html             |    5 
 src/com/gitblit/wicket/panels/HeadLinksPanel.html       |    2 
 src/com/gitblit/wicket/pages/CommitPage.html            |   32 
 contrib/com/codecommit/wicket/FillArea.java             |   54 +
 contrib/com/codecommit/wicket/IChartFill.java           |   10 
 contrib/com/codecommit/wicket/ILinearStripesFill.java   |   18 
 src/com/gitblit/wicket/panels/PageLinksPanel.java       |    8 
 resources/blank.png                                     |    0 
 contrib/com/codecommit/wicket/IChartGrid.java           |   18 
 resources/gitblit.css                                   |  296 ++++++
 contrib/com/codecommit/wicket/ChartType.java            |   34 
 src/com/gitblit/wicket/panels/HeadLinksPanel.java       |    2 
 src/com/gitblit/wicket/pages/TagsPage.java              |    4 
 src/com/gitblit/wicket/pages/RepositoriesPage.java      |    2 
 contrib/com/codecommit/wicket/ILinearGradientFill.java  |   18 
 src/com/gitblit/wicket/panels/PathBreadcrumbsPanel.java |   27 
 contrib/com/codecommit/wicket/IRangeMarker.java         |   20 
 src/com/gitblit/wicket/pages/TagPage.html               |   12 
 src/com/gitblit/wicket/panels/PageLinksPanel.html       |    2 
 contrib/com/codecommit/wicket/ChartGrid.java            |   51 +
 contrib/com/codecommit/wicket/AbstractChartData.java    |   46 +
 contrib/com/codecommit/wicket/LineStyle.java            |   43 
 contrib/com/codecommit/wicket/ChartProvider.java        |  176 ++++
 src/com/gitblit/wicket/pages/RepositoriesPage.html      |    7 
 src/com/gitblit/wicket/panels/TreeLinksPanel.java       |    6 
 contrib/com/codecommit/wicket/ILineStyle.java           |   16 
 contrib/com/codecommit/wicket/Range.java                |   32 
 src/com/gitblit/utils/JGitUtils.java                    |   36 
 src/com/gitblit/wicket/pages/SummaryPage.html           |  102 +-
 contrib/com/codecommit/wicket/IChartProvider.java       |   47 +
 contrib/com/codecommit/wicket/SolidFill.java            |   25 
 src/com/gitblit/wicket/pages/TreePage.java              |   12 
 src/com/gitblit/wicket/panels/PageFooter.java           |    6 
 src/com/gitblit/wicket/panels/PageHeader.html           |    3 
 contrib/com/codecommit/wicket/AxisAlignment.java        |   23 
 src/com/gitblit/wicket/pages/TreePage.html              |    9 
 contrib/com/codecommit/wicket/MarkerType.java           |   31 
 src/com/gitblit/wicket/models/PathModel.java            |   11 
 contrib/com/codecommit/wicket/RangeType.java            |   22 
 contrib/com/codecommit/wicket/IShapeMarker.java         |   22 
 contrib/com/codecommit/wicket/ShapeMarker.java          |   65 +
 /dev/null                                               |   69 -
 contrib/com/codecommit/wicket/IChartAxis.java           |   26 
 src/com/gitblit/wicket/pages/TagsPage.html              |   12 
 src/com/gitblit/wicket/panels/PageFooter.html           |    5 
 src/com/gitblit/wicket/GitBlitWebApp.java               |    2 
 contrib/com/codecommit/wicket/AreaFillType.java         |   22 
 contrib/com/codecommit/wicket/Chart.java                |  602 +++++++++++++
 src/com/gitblit/wicket/pages/SummaryPage.java           |   81 +
 67 files changed, 2,347 insertions(+), 283 deletions(-)

diff --git a/.classpath b/.classpath
index c9073ae..2fc1d0f 100644
--- a/.classpath
+++ b/.classpath
@@ -2,6 +2,7 @@
 <classpath>
 	<classpathentry kind="src" path="src"/>
 	<classpathentry kind="src" path="resources"/>
+	<classpathentry kind="src" path="contrib"/>
 	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
 	<classpathentry kind="lib" path="lib/jgit-0.11.3.jar" sourcepath="/org.eclipse.jgit"/>
 	<classpathentry kind="lib" path="lib/jgit-http-0.11.3.jar" sourcepath="/org.eclipse.jgit.http.server"/>
diff --git a/contrib/com/codecommit/wicket/AbstractChartData.java b/contrib/com/codecommit/wicket/AbstractChartData.java
new file mode 100644
index 0000000..73c0092
--- /dev/null
+++ b/contrib/com/codecommit/wicket/AbstractChartData.java
@@ -0,0 +1,46 @@
+/*
+ * Created on Dec 11, 2007
+ */
+package com.codecommit.wicket;
+
+import java.io.Serializable;
+
+/**
+ * @author Daniel Spiewak
+ */
+public abstract class AbstractChartData implements IChartData, Serializable {
+	
+	private static final long serialVersionUID = 1L;
+
+	private ChartDataEncoding encoding;
+	private double max;
+	
+	public AbstractChartData() {
+		this(62);
+	}
+	
+	public AbstractChartData(double max) {
+		this(ChartDataEncoding.SIMPLE, max);
+	}
+	
+	public AbstractChartData(ChartDataEncoding encoding, double max) {
+		this.encoding = encoding;
+		this.max = max;
+	}
+
+	public ChartDataEncoding getEncoding() {
+		return encoding;
+	}
+	
+	public double getMax() {
+		return max;
+	}
+	
+	public void setEncoding(ChartDataEncoding encoding) {
+		this.encoding = encoding;
+	}
+	
+	public void setMax(double max) {
+		this.max = max;
+	}
+}
diff --git a/contrib/com/codecommit/wicket/AreaFillType.java b/contrib/com/codecommit/wicket/AreaFillType.java
new file mode 100644
index 0000000..76ed1a1
--- /dev/null
+++ b/contrib/com/codecommit/wicket/AreaFillType.java
@@ -0,0 +1,22 @@
+/*
+ * Created on Dec 11, 2007
+ */
+package com.codecommit.wicket;
+
+/**
+ * @author Daniel Spiewak
+ */
+public enum AreaFillType {
+	BETWEEN("b"),
+	DOWN("B");
+	
+	private final String rendering;
+	
+	private AreaFillType(String rendering) {
+		this.rendering = rendering;
+	}
+	
+	public String getRendering() {
+		return rendering;
+	}
+}
diff --git a/contrib/com/codecommit/wicket/AxisAlignment.java b/contrib/com/codecommit/wicket/AxisAlignment.java
new file mode 100644
index 0000000..0f15ec0
--- /dev/null
+++ b/contrib/com/codecommit/wicket/AxisAlignment.java
@@ -0,0 +1,23 @@
+/*
+ * Created on Dec 11, 2007
+ */
+package com.codecommit.wicket;
+
+/**
+ * @author Daniel Spiewak
+ */
+public enum AxisAlignment {
+	LEFT(-1),
+	CENTER(0),
+	RIGHT(1);
+	
+	private final int rendering;
+	
+	private AxisAlignment(int rendering) {
+		this.rendering = rendering;
+	}
+	
+	public int getRendering() {
+		return rendering;
+	}
+}
diff --git a/contrib/com/codecommit/wicket/Chart.java b/contrib/com/codecommit/wicket/Chart.java
new file mode 100644
index 0000000..95461cf
--- /dev/null
+++ b/contrib/com/codecommit/wicket/Chart.java
@@ -0,0 +1,602 @@
+/*
+ * Created on Dec 11, 2007
+ */
+package com.codecommit.wicket;
+
+import java.awt.Color;
+import java.awt.Dimension;
+import java.lang.reflect.InvocationTargetException;
+import java.util.concurrent.locks.ReadWriteLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+
+import org.apache.wicket.markup.ComponentTag;
+import org.apache.wicket.markup.html.WebComponent;
+
+/**
+ * @author Daniel Spiewak
+ */
+public class Chart extends WebComponent {
+	private static final long serialVersionUID = 1L;
+
+	private IChartProvider provider;
+	
+	private StringBuilder url;
+	private final ReadWriteLock lock = new ReentrantReadWriteLock();
+	
+	public Chart(String id, IChartProvider provider) {
+		super(id);
+		
+		this.provider = provider;
+	}
+	
+	@Override
+	public boolean getStatelessHint() {
+		return false;
+	}
+	
+	public void invalidate() {
+		lock.writeLock().lock();
+		try {
+			url = null;
+		} finally {
+			lock.writeLock().unlock();
+		}
+	}
+	
+	public CharSequence constructURL() {
+		lock.writeLock().lock();
+		try {
+			if (url != null) {
+				return url;
+			}
+			
+			url = new StringBuilder("http://chart.apis.google.com/chart?");
+			
+			addParameter(url, "chs", render(provider.getSize()));
+			addParameter(url, "chd", render(provider.getData()));
+			addParameter(url, "cht", render(provider.getType()));
+			addParameter(url, "chbh", render(provider.getBarWidth(), provider.getBarGroupSpacing()));
+			addParameter(url, "chtt", render(provider.getTitle()));
+			addParameter(url, "chdl", render(provider.getLegend()));
+			addParameter(url, "chco", render(provider.getColors()));
+			
+			IChartFill bgFill = provider.getBackgroundFill();
+			IChartFill fgFill = provider.getChartFill();
+	
+			StringBuilder fillParam = new StringBuilder();
+	
+			if (bgFill != null) {
+				fillParam.append("bg,").append(render(bgFill));
+			}
+	
+			if (fgFill != null) {
+				if (fillParam.length() > 0) {
+					fillParam.append('|');
+				}
+	
+				fillParam.append("c,").append(render(fgFill));
+			}
+			
+			if (fillParam.toString().trim().equals("")) {
+				fillParam = null;
+			}
+	
+			addParameter(url, "chf", fillParam);
+	
+			IChartAxis[] axes = provider.getAxes();
+			addParameter(url, "chxt", renderTypes(axes));
+			addParameter(url, "chxl", renderLabels(axes));
+			addParameter(url, "chxp", renderPositions(axes));
+			addParameter(url, "chxr", renderRanges(axes));
+			addParameter(url, "chxs", renderStyles(axes));
+			
+			addParameter(url, "chg", render(provider.getGrid()));
+			addParameter(url, "chm", render(provider.getShapeMarkers()));
+			addParameter(url, "chm", render(provider.getRangeMarkers()));
+			addParameter(url, "chls", render(provider.getLineStyles()));
+			addParameter(url, "chm", render(provider.getFillAreas()));
+			addParameter(url, "chl", render(provider.getPieLabels()));
+	
+			return url;
+		} finally {
+			lock.writeLock().unlock();
+		}
+	}
+	
+	private void addParameter(StringBuilder url, CharSequence param, CharSequence value) {
+		if (value == null || value.length() == 0) {
+			return;
+		}
+		
+		if (url.charAt(url.length() - 1) != '?') {
+			url.append('&');
+		}
+		
+		url.append(param).append('=').append(value);
+	}
+	
+	private CharSequence render(Dimension dim) {
+		if (dim == null) {
+			return null;
+		}
+		
+		return new StringBuilder().append(dim.width).append('x').append(dim.height);
+	}
+	
+	private CharSequence render(IChartData data) {
+		if (data == null) {
+			return null;
+		}
+
+		ChartDataEncoding encoding = data.getEncoding();
+		
+		StringBuilder back = new StringBuilder();
+		back.append(render(encoding)).append(':');
+		
+		for (double[] set : data.getData()) {
+			if (set == null || set.length == 0) {
+				back.append(encoding.convert(-1, data.getMax()));
+			} else {
+				for (double value : set) {
+					back.append(encoding.convert(value, data.getMax())).append(encoding.getValueSeparator());
+				}
+				
+				if (back.substring(back.length() - encoding.getValueSeparator().length(), 
+						back.length()).equals(encoding.getValueSeparator())) {
+					back.setLength(back.length() - encoding.getValueSeparator().length());
+				}
+			}
+			
+			back.append(encoding.getSetSeparator());
+		}
+		
+		if (back.substring(back.length() - encoding.getSetSeparator().length(), 
+				back.length()).equals(encoding.getSetSeparator())) {
+			back.setLength(back.length() - encoding.getSetSeparator().length());
+		}
+		
+		return back;
+	}
+	
+	private CharSequence render(Enum<?> value) {
+		if (value == null) {
+			return null;
+		}
+		
+		try {
+			Object back = value.getClass().getMethod("getRendering").invoke(value);
+			
+			if (back != null) {
+				return back.toString();
+			}
+		} catch (IllegalArgumentException e) {
+		} catch (SecurityException e) {
+		} catch (IllegalAccessException e) {
+		} catch (InvocationTargetException e) {
+		} catch (NoSuchMethodException e) {
+		}
+		
+		return null;
+	}
+	
+	private CharSequence render(int barWidth, int groupSpacing) {
+		if (barWidth == -1) {
+			return null;
+		}
+		
+		StringBuilder back = new StringBuilder(barWidth);
+		
+		if (groupSpacing >= 0) {
+			back.append(',').append(groupSpacing);
+		}
+		
+		return back;
+	}
+	
+	private CharSequence render(String[] values) {
+		if (values == null) {
+			return null;
+		}
+		
+		StringBuilder back = new StringBuilder();
+		
+		for (String value : values) {
+			CharSequence toRender = render(value);
+			if (toRender == null) {
+				toRender = "";
+			}
+			
+			back.append(toRender).append('|');
+		}
+		
+		if (back.length() > 0) {
+			back.setLength(back.length() - 1);
+		}
+		
+		return back;
+	}
+	
+	private CharSequence render(String value) {
+		if (value == null) {
+			return value;
+		}
+		
+		StringBuilder back = new StringBuilder();
+		
+		for (char c : value.toCharArray()) {
+			if (c == ' ') {
+				back.append('+');
+			} else {
+				back.append(c);
+			}
+		}
+		
+		return back;
+	}
+	
+	private CharSequence render(Color[] values) {
+		if (values == null) {
+			return null;
+		}
+		
+		StringBuilder back = new StringBuilder();
+		
+		for (Color value : values) {
+			CharSequence toRender = render(value);
+			if (toRender == null) {
+				continue;
+			}
+			char delimiter = ',';
+			switch(provider.getType()) {
+			case PIE:
+			case PIE_3D:
+			case BAR_VERTICAL_SET:
+				delimiter = '|';
+				break;
+			}
+			back.append(toRender).append(delimiter);
+		}
+		
+		if (back.length() > 0) {
+			back.setLength(back.length() - 1);
+		}
+		
+		return back;
+	}
+	
+	private CharSequence render(Color value) {
+		if (value == null) {
+			return null;
+		}
+		
+		StringBuilder back = new StringBuilder();
+		
+		{
+			String toPad = Integer.toHexString(value.getRed());
+			
+			if (toPad.length() == 1) {
+				back.append(0);
+			}
+			back.append(toPad);
+		}
+		
+		{
+			String toPad = Integer.toHexString(value.getGreen());
+			
+			if (toPad.length() == 1) {
+				back.append(0);
+			}
+			back.append(toPad);
+		}
+		
+		{
+			String toPad = Integer.toHexString(value.getBlue());
+			
+			if (toPad.length() == 1) {
+				back.append(0);
+			}
+			back.append(toPad);
+		}
+		
+		{
+			String toPad = Integer.toHexString(value.getAlpha());
+			
+			if (toPad.length() == 1) {
+				back.append(0);
+			}
+			back.append(toPad);
+		}
+		
+		return back;
+	}
+	
+	private CharSequence render(IChartFill fill) {
+		if (fill == null) {
+			return null;
+		}
+		
+		StringBuilder back = new StringBuilder();
+		
+		if (fill instanceof ISolidFill) {
+			ISolidFill solidFill = (ISolidFill) fill;
+			
+			back.append("s,");
+			back.append(render(solidFill.getColor()));
+		} else if (fill instanceof ILinearGradientFill) {
+			ILinearGradientFill gradientFill = (ILinearGradientFill) fill;
+			
+			back.append("lg,").append(gradientFill.getAngle()).append(',');
+			
+			Color[] colors = gradientFill.getColors();
+			double[] offsets = gradientFill.getOffsets();
+			for (int i = 0; i < colors.length; i++) {
+				back.append(render(colors[i])).append(',').append(offsets[i]).append(',');
+			}
+			
+			back.setLength(back.length() - 1);
+		} else if (fill instanceof ILinearStripesFill) {
+			ILinearStripesFill stripesFill = (ILinearStripesFill) fill;
+			
+			back.append("ls,").append(stripesFill.getAngle()).append(',');
+			
+			Color[] colors = stripesFill.getColors();
+			double[] widths = stripesFill.getWidths();
+			for (int i = 0; i < colors.length; i++) {
+				back.append(render(colors[i])).append(',').append(widths[i]).append(',');
+			}
+			
+			back.setLength(back.length() - 1);
+		} else {
+			return null;
+		}
+		
+		return back;
+	}
+	
+	private CharSequence renderTypes(IChartAxis[] axes) {
+		if (axes == null) {
+			return null;
+		}
+		
+		StringBuilder back = new StringBuilder();
+		
+		for (IChartAxis axis : axes) {
+			back.append(render(axis.getType())).append(',');
+		}
+		
+		if (back.length() > 0) {
+			back.setLength(back.length() - 1);
+		}
+		
+		return back;
+	}
+	
+	private CharSequence renderLabels(IChartAxis[] axes) {
+		if (axes == null) {
+			return null;
+		}
+		
+		StringBuilder back = new StringBuilder();
+		
+		for (int i = 0; i < axes.length; i++) {
+			if (axes[i] == null || axes[i].getLabels() == null) {
+				continue;
+			}
+			
+			back.append(i).append(":|");
+			
+			for (String label : axes[i].getLabels()) {
+				if (label == null) {
+					back.append('|');
+					continue;
+				}
+				
+				back.append(render(label)).append('|');
+			}
+			
+			if (i == axes.length - 1) {
+				back.setLength(back.length() - 1);
+			}
+		}
+		
+		return back;
+	}
+	
+	private CharSequence renderPositions(IChartAxis[] axes) {
+		if (axes == null) {
+			return null;
+		}
+		
+		StringBuilder back = new StringBuilder();
+		
+		for (int i = 0; i < axes.length; i++) {
+			if (axes[i] == null || axes[i].getPositions() == null) {
+				continue;
+			}
+			
+			back.append(i).append(',');
+			
+			for (double position : axes[i].getPositions()) {
+				back.append(position).append(',');
+			}
+			
+			back.setLength(back.length() - 1);
+			
+			back.append('|');
+		}
+		
+		if (back.length() > 0) {
+			back.setLength(back.length() - 1);
+		}
+		
+		return back;
+	}
+	
+	private CharSequence renderRanges(IChartAxis[] axes) {
+		if (axes == null) {
+			return null;
+		}
+		
+		StringBuilder back = new StringBuilder();
+		
+		for (int i = 0; i < axes.length; i++) {
+			if (axes[i] == null || axes[i].getRange() == null) {
+				continue;
+			}
+			
+			back.append(i).append(',');
+			
+			Range range = axes[i].getRange();
+			back.append(range.getStart()).append(',').append(range.getEnd()).append('|');
+		}
+		
+		if (back.length() > 0) {
+			back.setLength(back.length() - 1);
+		}
+		
+		return back;
+	}
+	
+	private CharSequence renderStyles(IChartAxis[] axes) {
+		if (axes == null) {
+			return null;
+		}
+		
+		StringBuilder back = new StringBuilder();
+		
+		for (int i = 0; i < axes.length; i++) {
+			if (axes[i] == null || axes[i].getColor() == null 
+					|| axes[i].getFontSize() < 0 || axes[i].getAlignment() == null) {
+				continue;
+			}
+			
+			back.append(i).append(',');
+			back.append(render(axes[i].getColor())).append(',');
+			back.append(axes[i].getFontSize()).append(',');
+			back.append(render(axes[i].getAlignment())).append('|');
+		}
+		
+		if (back.length() > 0) {
+			back.setLength(back.length() - 1);
+		}
+		
+		return back;
+	}
+	
+	private CharSequence render(IChartGrid grid) {
+		if (grid == null) {
+			return null;
+		}
+		
+		StringBuilder back = new StringBuilder();
+		
+		back.append(grid.getXStepSize()).append(',');
+		back.append(grid.getYStepSize());
+		
+		if (grid.getSegmentLength() >= 0) {
+			back.append(',').append(grid.getSegmentLength());
+			back.append(',').append(grid.getBlankLength());
+		}
+		
+		return back;
+	}
+	
+	private CharSequence render(IShapeMarker[] markers) {
+		if (markers == null) {
+			return null;
+		}
+		
+		StringBuilder back = new StringBuilder();
+		
+		for (IShapeMarker marker : markers) {
+			back.append(render(marker.getType())).append(',');
+			back.append(render(marker.getColor())).append(',');
+			back.append(marker.getIndex()).append(',');
+			back.append(marker.getPoint()).append(',');
+			back.append(marker.getSize()).append('|');
+		}
+		
+		if (back.length() > 0) {
+			back.setLength(back.length() - 1);
+		}
+		
+		return back;
+	}
+	
+	private CharSequence render(IRangeMarker[] markers) {
+		if (markers == null) {
+			return null;
+		}
+		
+		StringBuilder back = new StringBuilder();
+		
+		for (IRangeMarker marker : markers) {
+			back.append(render(marker.getType())).append(',');
+			back.append(render(marker.getColor())).append(',');
+			back.append(0).append(',');
+			back.append(marker.getStart()).append(',');
+			back.append(marker.getEnd()).append('|');
+		}
+		
+		if (back.length() > 0) {
+			back.setLength(back.length() - 1);
+		}
+		
+		return back;
+	}
+	
+	private CharSequence render(IFillArea[] areas) {
+		if (areas == null) {
+			return null;
+		}
+		
+		StringBuilder back = new StringBuilder();
+		
+		for (IFillArea area : areas) {
+			back.append(render(area.getType())).append(',');
+			back.append(render(area.getColor())).append(',');
+			back.append(area.getStartIndex()).append(',');
+			back.append(area.getEndIndex()).append(',');
+			back.append(0).append('|');
+		}
+		
+		if (back.length() > 0) {
+			back.setLength(back.length() - 1);
+		}
+		
+		return back;
+	}
+	
+	private CharSequence render(ILineStyle[] styles) {
+		if (styles == null) {
+			return null;
+		}
+		
+		StringBuilder back = new StringBuilder();
+		
+		for (ILineStyle style : styles) {
+			if (style == null) {
+				back.append('|');
+				continue;
+			}
+			
+			back.append(style.getThickness()).append(',');
+			back.append(style.getSegmentLength()).append(',');
+			back.append(style.getBlankLength()).append('|');
+		}
+		
+		if (back.length() > 0) {
+			back.setLength(back.length() - 1);
+		}
+		
+		return back;
+	}
+	
+	@Override
+	protected void onComponentTag(ComponentTag tag) {
+		checkComponentTag(tag, "img");
+		super.onComponentTag(tag);
+		
+		tag.put("src", constructURL());
+	}
+}
\ No newline at end of file
diff --git a/contrib/com/codecommit/wicket/ChartAxis.java b/contrib/com/codecommit/wicket/ChartAxis.java
new file mode 100644
index 0000000..7042c0c
--- /dev/null
+++ b/contrib/com/codecommit/wicket/ChartAxis.java
@@ -0,0 +1,79 @@
+/*
+ * Created on Dec 11, 2007
+ */
+package com.codecommit.wicket;
+
+import java.awt.Color;
+
+/**
+ * @author Daniel Spiewak
+ */
+public class ChartAxis implements IChartAxis {
+	private AxisAlignment alignment;
+	private Color color;
+	private int fontSize = -1;
+	private String[] labels;
+	private double[] positions;
+	private Range range;
+	private ChartAxisType type;
+	
+	public ChartAxis(ChartAxisType type) {
+		this.type = type;
+	}
+
+	public AxisAlignment getAlignment() {
+		return alignment;
+	}
+
+	public Color getColor() {
+		return color;
+	}
+
+	public int getFontSize() {
+		return fontSize;
+	}
+
+	public String[] getLabels() {
+		return labels;
+	}
+
+	public double[] getPositions() {
+		return positions;
+	}
+
+	public Range getRange() {
+		return range;
+	}
+
+	public ChartAxisType getType() {
+		return type;
+	}
+
+	public void setAlignment(AxisAlignment alignment) {
+		this.alignment = alignment;
+	}
+
+	public void setColor(Color color) {
+		this.color = color;
+	}
+
+	public void setFontSize(int fontSize) {
+		this.fontSize = fontSize;
+	}
+
+	public void setLabels(String[] labels) {
+		this.labels = labels;
+	}
+
+	public void setPositions(double[] positions) {
+		this.positions = positions;
+	}
+
+	public void setRange(Range range) {
+		this.range = range;
+	}
+
+	public void setType(ChartAxisType type) {
+		this.type = type;
+	}
+}
diff --git a/contrib/com/codecommit/wicket/ChartAxisType.java b/contrib/com/codecommit/wicket/ChartAxisType.java
new file mode 100644
index 0000000..8246654
--- /dev/null
+++ b/contrib/com/codecommit/wicket/ChartAxisType.java
@@ -0,0 +1,25 @@
+/*
+ * Created on Dec 11, 2007
+ */
+package com.codecommit.wicket;
+
+/**
+ * @author Daniel Spiewak
+ */
+public enum ChartAxisType {
+	BOTTOM("x"),
+	TOP("t"),
+	
+	LEFT("y"),
+	RIGHT("r");
+	
+	private final String rendering;
+	
+	private ChartAxisType(String rendering) {
+		this.rendering = rendering;
+	}
+	
+	public String getRendering() {
+		return rendering;
+	}
+}
diff --git a/contrib/com/codecommit/wicket/ChartDataEncoding.java b/contrib/com/codecommit/wicket/ChartDataEncoding.java
new file mode 100644
index 0000000..15677f4
--- /dev/null
+++ b/contrib/com/codecommit/wicket/ChartDataEncoding.java
@@ -0,0 +1,82 @@
+/*
+ * Created on Dec 11, 2007
+ */
+package com.codecommit.wicket;
+
+
+/**
+ * @author Daniel Spiewak
+ */
+public enum ChartDataEncoding {
+	SIMPLE("s", "", ",") {
+		CharSequence convert(double value, double max) {
+			if (value < 0) {
+				return "_";
+			}
+			
+			value = Math.round((CHARS.length() - 1) * value / max);
+			
+			if (value > CHARS.length() - 1) {
+				throw new IllegalArgumentException(value + " is out of range for SIMPLE encoding");
+			}
+			
+			return Character.toString(CHARS.charAt((int) value));
+		}
+	},
+	TEXT("t", ",", "|") {
+		CharSequence convert(double value, double max) {
+			if (value < 0) {
+				value = -1;
+			}
+			
+			if (value > 100) {
+				throw new IllegalArgumentException(value + " is out of range for TEXT encoding");
+			}
+			
+			return Double.toString(value);
+		}
+	},
+	EXTENDED("e", "", ",") {
+		CharSequence convert(double value, double max) {
+			if (value < 0) {
+				return "__";
+			}
+			
+			value = Math.round(value);
+			
+			if (value > (EXT_CHARS.length() - 1) * (EXT_CHARS.length() - 1)) {
+				throw new IllegalArgumentException(value + " is out of range for EXTENDED encoding");
+			}
+			
+			int rem = (int) (value % EXT_CHARS.length());
+			int exp = (int) (value / EXT_CHARS.length());
+			
+			return new StringBuilder().append(EXT_CHARS.charAt(exp)).append(EXT_CHARS.charAt(rem));
+		}
+	};
+	
+	private static final String CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
+	private static final String EXT_CHARS = CHARS + "-_.";
+	
+	private final String rendering, valueSeparator, setSeparator;
+	
+	private ChartDataEncoding(String rendering, String valueSeparator, String setSeparator) {
+		this.rendering = rendering;
+		this.valueSeparator = valueSeparator;
+		this.setSeparator = setSeparator;
+	}
+	
+	public String getRendering() {
+		return rendering;
+	}
+	
+	public String getValueSeparator() {
+		return valueSeparator;
+	}
+	
+	public String getSetSeparator() {
+		return setSeparator;
+	}
+	
+	abstract CharSequence convert(double value, double max);
+}
diff --git a/contrib/com/codecommit/wicket/ChartGrid.java b/contrib/com/codecommit/wicket/ChartGrid.java
new file mode 100644
index 0000000..9fdee20
--- /dev/null
+++ b/contrib/com/codecommit/wicket/ChartGrid.java
@@ -0,0 +1,51 @@
+/*
+ * Created on Dec 11, 2007
+ */
+package com.codecommit.wicket;
+
+/**
+ * @author Daniel Spiewak
+ */
+public class ChartGrid implements IChartGrid {
+	private int blankLength = -1;
+	private int segmentLength = -1;
+	private int xStepSize = -1;
+	private int yStepSize = -1;
+	
+	public ChartGrid(int xStepSize, int yStepSize) {
+		this.xStepSize = xStepSize;
+		this.yStepSize = yStepSize;
+	}
+
+	public int getBlankLength() {
+		return blankLength;
+	}
+
+	public int getSegmentLength() {
+		return segmentLength;
+	}
+
+	public double getXStepSize() {
+		return xStepSize;
+	}
+
+	public double getYStepSize() {
+		return yStepSize;
+	}
+
+	public void setBlankLength(int blankLength) {
+		this.blankLength = blankLength;
+	}
+
+	public void setSegmentLength(int segmentLength) {
+		this.segmentLength = segmentLength;
+	}
+
+	public void setXStepSize(int stepSize) {
+		xStepSize = stepSize;
+	}
+
+	public void setYStepSize(int stepSize) {
+		yStepSize = stepSize;
+	}
+}
diff --git a/contrib/com/codecommit/wicket/ChartProvider.java b/contrib/com/codecommit/wicket/ChartProvider.java
new file mode 100644
index 0000000..4e69bfc
--- /dev/null
+++ b/contrib/com/codecommit/wicket/ChartProvider.java
@@ -0,0 +1,176 @@
+/*
+ * Created on Dec 11, 2007
+ */
+package com.codecommit.wicket;
+
+import java.awt.Color;
+import java.awt.Dimension;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author Daniel Spiewak
+ */
+public class ChartProvider implements IChartProvider, Serializable {
+	private static final long serialVersionUID = 1L;
+	private List<IChartAxis> axes = new ArrayList<IChartAxis>();
+	private IChartFill backgroundFill;
+	private int barGroupSpacing = -1;
+	private int barWidth = -1;
+	private IChartFill chartFill;
+	private Color[] colors;
+	private List<IFillArea> fillAreas = new ArrayList<IFillArea>();
+	private IChartGrid grid;
+	private String[] legend;
+	private ILineStyle[] lineStyles;
+	private String[] pieLabels;
+	private List<IRangeMarker> rangeMarkers = new ArrayList<IRangeMarker>();
+	private List<IShapeMarker> shapeMarkers = new ArrayList<IShapeMarker>();
+	private Dimension size;
+	private String title;
+	private ChartType type;
+	private IChartData data;
+	
+	public ChartProvider(Dimension size, ChartType type, IChartData data) {
+		this.size = size;
+		this.type = type;
+		this.data = data;
+	}
+	
+	public IChartAxis[] getAxes() {
+		return axes.toArray(new IChartAxis[axes.size()]);
+	}
+
+	public IChartFill getBackgroundFill() {
+		return backgroundFill;
+	}
+
+	public int getBarGroupSpacing() {
+		return barGroupSpacing;
+	}
+
+	public int getBarWidth() {
+		return barWidth;
+	}
+
+	public IChartFill getChartFill() {
+		return chartFill;
+	}
+
+	public Color[] getColors() {
+		return colors;
+	}
+
+	public IFillArea[] getFillAreas() {
+		return fillAreas.toArray(new IFillArea[fillAreas.size()]);
+	}
+
+	public IChartGrid getGrid() {
+		return grid;
+	}
+
+	public String[] getLegend() {
+		return legend;
+	}
+
+	public ILineStyle[] getLineStyles() {
+		return lineStyles;
+	}
+
+	public String[] getPieLabels() {
+		return pieLabels;
+	}
+
+	public IRangeMarker[] getRangeMarkers() {
+		return rangeMarkers.toArray(new IRangeMarker[rangeMarkers.size()]);
+	}
+
+	public IShapeMarker[] getShapeMarkers() {
+		return shapeMarkers.toArray(new IShapeMarker[shapeMarkers.size()]);
+	}
+
+	public Dimension getSize() {
+		return size;
+	}
+
+	public String getTitle() {
+		return title;
+	}
+
+	public ChartType getType() {
+		return type;
+	}
+	
+	public void addFillArea(IFillArea fillArea) {
+		fillAreas.add(fillArea);
+	}
+
+	public void addAxis(IChartAxis axis) {
+		axes.add(axis);
+	}
+
+	public void setBackgroundFill(IChartFill backgroundFill) {
+		this.backgroundFill = backgroundFill;
+	}
+
+	public void setBarGroupSpacing(int barGroupSpacing) {
+		this.barGroupSpacing = barGroupSpacing;
+	}
+
+	public void setBarWidth(int barWidth) {
+		this.barWidth = barWidth;
+	}
+
+	public void setChartFill(IChartFill chartFill) {
+		this.chartFill = chartFill;
+	}
+
+	public void setColors(Color[] colors) {
+		this.colors = colors;
+	}
+
+	public void setGrid(IChartGrid grid) {
+		this.grid = grid;
+	}
+
+	public void setLegend(String[] legend) {
+		this.legend = legend;
+	}
+
+	public void setLineStyles(ILineStyle[] lineStyles) {
+		this.lineStyles = lineStyles;
+	}
+
+	public void setPieLabels(String[] pieLabels) {
+		this.pieLabels = pieLabels;
+	}
+
+	public void addRangeMarker(IRangeMarker rangeMarker) {
+		rangeMarkers.add(rangeMarker);
+	}
+
+	public void addShapeMarker(IShapeMarker shapeMarker) {
+		shapeMarkers.add(shapeMarker);
+	}
+
+	public void setSize(Dimension size) {
+		this.size = size;
+	}
+
+	public void setTitle(String title) {
+		this.title = title;
+	}
+
+	public void setType(ChartType type) {
+		this.type = type;
+	}
+
+	public IChartData getData() {
+		return data;
+	}
+
+	public void setData(IChartData data) {
+		this.data = data;
+	}
+}
diff --git a/contrib/com/codecommit/wicket/ChartType.java b/contrib/com/codecommit/wicket/ChartType.java
new file mode 100644
index 0000000..3d25d42
--- /dev/null
+++ b/contrib/com/codecommit/wicket/ChartType.java
@@ -0,0 +1,34 @@
+/*
+ * Created on Dec 11, 2007
+ */
+package com.codecommit.wicket;
+
+/**
+ * @author Daniel Spiewak
+ */
+public enum ChartType {
+	LINE("lc"),
+	LINE_XY("lxy"),
+	
+	BAR_HORIZONTAL_SET("bhs"),
+	BAR_VERTICAL_SET("bvs"),
+	BAR_HORIZONTAL_GROUP("bhg"),
+	BAR_VERTICAL_GROUP("bvg"),
+	
+	PIE("p"),
+	PIE_3D("p3"),
+	
+	VENN("v"),
+	
+	SCATTER("s");
+	
+	private final String rendering;
+	
+	private ChartType(String rendering) {
+		this.rendering = rendering;
+	}
+	
+	public String getRendering() {
+		return rendering;
+	}
+}
diff --git a/contrib/com/codecommit/wicket/FillArea.java b/contrib/com/codecommit/wicket/FillArea.java
new file mode 100644
index 0000000..2ab5ef3
--- /dev/null
+++ b/contrib/com/codecommit/wicket/FillArea.java
@@ -0,0 +1,54 @@
+/*
+ * Created on Dec 11, 2007
+ */
+package com.codecommit.wicket;
+
+import java.awt.Color;
+
+/**
+ * @author Daniel Spiewak
+ */
+public class FillArea implements IFillArea {
+	private Color color;
+	private int endIndex = -1;
+	private int startIndex = -1;
+	private AreaFillType type = AreaFillType.BETWEEN;
+	
+	public FillArea(Color color, int startIndex, int endIndex) {
+		this.color = color;
+		this.startIndex = startIndex;
+		this.endIndex = endIndex;
+	}
+
+	public Color getColor() {
+		return color;
+	}
+
+	public int getEndIndex() {
+		return endIndex;
+	}
+
+	public int getStartIndex() {
+		return startIndex;
+	}
+
+	public AreaFillType getType() {
+		return type;
+	}
+
+	public void setColor(Color color) {
+		this.color = color;
+	}
+
+	public void setEndIndex(int endIndex) {
+		this.endIndex = endIndex;
+	}
+
+	public void setStartIndex(int startIndex) {
+		this.startIndex = startIndex;
+	}
+
+	public void setType(AreaFillType type) {
+		this.type = type;
+	}
+}
diff --git a/contrib/com/codecommit/wicket/IChartAxis.java b/contrib/com/codecommit/wicket/IChartAxis.java
new file mode 100644
index 0000000..c7c83dc
--- /dev/null
+++ b/contrib/com/codecommit/wicket/IChartAxis.java
@@ -0,0 +1,26 @@
+/*
+ * Created on Dec 11, 2007
+ */
+package com.codecommit.wicket;
+
+import java.awt.Color;
+
+/**
+ * @author Daniel Spiewak
+ */
+public interface IChartAxis {
+	
+	public ChartAxisType getType();
+	
+	public String[] getLabels();
+	
+	public double[] getPositions();
+	
+	public Range getRange();
+	
+	public Color getColor();
+	
+	public int getFontSize();
+	
+	public AxisAlignment getAlignment();
+}
diff --git a/contrib/com/codecommit/wicket/IChartData.java b/contrib/com/codecommit/wicket/IChartData.java
new file mode 100644
index 0000000..c4f6ec7
--- /dev/null
+++ b/contrib/com/codecommit/wicket/IChartData.java
@@ -0,0 +1,16 @@
+/*
+ * Created on Dec 11, 2007
+ */
+package com.codecommit.wicket;
+
+/**
+ * @author Daniel Spiewak
+ */
+public interface IChartData {
+	
+	public ChartDataEncoding getEncoding();
+	
+	public double[][] getData();
+	
+	public double getMax();
+}
diff --git a/contrib/com/codecommit/wicket/IChartFill.java b/contrib/com/codecommit/wicket/IChartFill.java
new file mode 100644
index 0000000..2ccb1d6
--- /dev/null
+++ b/contrib/com/codecommit/wicket/IChartFill.java
@@ -0,0 +1,10 @@
+/*
+ * Created on Dec 11, 2007
+ */
+package com.codecommit.wicket;
+
+/**
+ * @author Daniel Spiewak
+ */
+public interface IChartFill {
+}
diff --git a/contrib/com/codecommit/wicket/IChartGrid.java b/contrib/com/codecommit/wicket/IChartGrid.java
new file mode 100644
index 0000000..05f4c5f
--- /dev/null
+++ b/contrib/com/codecommit/wicket/IChartGrid.java
@@ -0,0 +1,18 @@
+/*
+ * Created on Dec 11, 2007
+ */
+package com.codecommit.wicket;
+
+/**
+ * @author Daniel Spiewak
+ */
+public interface IChartGrid {
+	
+	public double getXStepSize();
+	
+	public double getYStepSize();
+	
+	public int getSegmentLength();
+	
+	public int getBlankLength();
+}
diff --git a/contrib/com/codecommit/wicket/IChartProvider.java b/contrib/com/codecommit/wicket/IChartProvider.java
new file mode 100644
index 0000000..76e7fa6
--- /dev/null
+++ b/contrib/com/codecommit/wicket/IChartProvider.java
@@ -0,0 +1,47 @@
+/*
+ * Created on Dec 11, 2007
+ */
+package com.codecommit.wicket;
+
+import java.awt.Color;
+import java.awt.Dimension;
+
+/**
+ * @author Daniel Spiewak
+ */
+public interface IChartProvider {
+	
+	public Dimension getSize();
+	
+	public IChartData getData();
+	
+	public ChartType getType();
+	
+	public int getBarWidth();
+	
+	public int getBarGroupSpacing();
+	
+	public String getTitle();
+	
+	public String[] getLegend();
+	
+	public Color[] getColors();
+	
+	public IChartFill getChartFill();
+	
+	public IChartFill getBackgroundFill();
+	
+	public String[] getPieLabels();
+	
+	public IChartAxis[] getAxes();
+	
+	public ILineStyle[] getLineStyles();
+	
+	public IChartGrid getGrid();
+	
+	public IShapeMarker[] getShapeMarkers();
+	
+	public IRangeMarker[] getRangeMarkers();
+	
+	public IFillArea[] getFillAreas();
+}
diff --git a/contrib/com/codecommit/wicket/IFillArea.java b/contrib/com/codecommit/wicket/IFillArea.java
new file mode 100644
index 0000000..3ba7f0a
--- /dev/null
+++ b/contrib/com/codecommit/wicket/IFillArea.java
@@ -0,0 +1,21 @@
+/*
+ * Created on Dec 11, 2007
+ */
+package com.codecommit.wicket;
+
+import java.awt.Color;
+
+/**
+ * @author Daniel Spiewak
+ */
+public interface IFillArea {
+	
+	public AreaFillType getType();
+	
+	public Color getColor();
+	
+	public int getStartIndex();
+	
+	// unnecessary if BOTTOM
+	public int getEndIndex();
+}
diff --git a/contrib/com/codecommit/wicket/ILineStyle.java b/contrib/com/codecommit/wicket/ILineStyle.java
new file mode 100644
index 0000000..873debe
--- /dev/null
+++ b/contrib/com/codecommit/wicket/ILineStyle.java
@@ -0,0 +1,16 @@
+/*
+ * Created on Dec 11, 2007
+ */
+package com.codecommit.wicket;
+
+/**
+ * @author Daniel Spiewak
+ */
+public interface ILineStyle {
+	
+	public int getThickness();
+	
+	public int getSegmentLength();
+	
+	public int getBlankLength();
+}
diff --git a/contrib/com/codecommit/wicket/ILinearGradientFill.java b/contrib/com/codecommit/wicket/ILinearGradientFill.java
new file mode 100644
index 0000000..8ed51de
--- /dev/null
+++ b/contrib/com/codecommit/wicket/ILinearGradientFill.java
@@ -0,0 +1,18 @@
+/*
+ * Created on Dec 11, 2007
+ */
+package com.codecommit.wicket;
+
+import java.awt.Color;
+
+/**
+ * @author Daniel Spiewak
+ */
+public interface ILinearGradientFill extends IChartFill {
+	
+	public int getAngle();
+	
+	public Color[] getColors();
+	
+	public double[] getOffsets();
+}
diff --git a/contrib/com/codecommit/wicket/ILinearStripesFill.java b/contrib/com/codecommit/wicket/ILinearStripesFill.java
new file mode 100644
index 0000000..534896f
--- /dev/null
+++ b/contrib/com/codecommit/wicket/ILinearStripesFill.java
@@ -0,0 +1,18 @@
+/*
+ * Created on Dec 11, 2007
+ */
+package com.codecommit.wicket;
+
+import java.awt.Color;
+
+/**
+ * @author Daniel Spiewak
+ */
+public interface ILinearStripesFill extends IChartFill {
+	
+	public int getAngle();
+	
+	public Color[] getColors();
+	
+	public double[] getWidths();
+}
diff --git a/contrib/com/codecommit/wicket/IRangeMarker.java b/contrib/com/codecommit/wicket/IRangeMarker.java
new file mode 100644
index 0000000..1cc3040
--- /dev/null
+++ b/contrib/com/codecommit/wicket/IRangeMarker.java
@@ -0,0 +1,20 @@
+/*
+ * Created on Dec 11, 2007
+ */
+package com.codecommit.wicket;
+
+import java.awt.Color;
+
+/**
+ * @author Daniel Spiewak
+ */
+public interface IRangeMarker {
+
+	public RangeType getType();
+	
+	public Color getColor();
+	
+	public double getStart();
+	
+	public double getEnd();
+}
diff --git a/contrib/com/codecommit/wicket/IShapeMarker.java b/contrib/com/codecommit/wicket/IShapeMarker.java
new file mode 100644
index 0000000..626eccb
--- /dev/null
+++ b/contrib/com/codecommit/wicket/IShapeMarker.java
@@ -0,0 +1,22 @@
+/*
+ * Created on Dec 11, 2007
+ */
+package com.codecommit.wicket;
+
+import java.awt.Color;
+
+/**
+ * @author Daniel Spiewak
+ */
+public interface IShapeMarker {
+	
+	public MarkerType getType();
+	
+	public Color getColor();
+	
+	public int getIndex();
+	
+	public double getPoint();
+	
+	public int getSize();
+}
diff --git a/contrib/com/codecommit/wicket/ISolidFill.java b/contrib/com/codecommit/wicket/ISolidFill.java
new file mode 100644
index 0000000..f97b064
--- /dev/null
+++ b/contrib/com/codecommit/wicket/ISolidFill.java
@@ -0,0 +1,13 @@
+/*
+ * Created on Dec 11, 2007
+ */
+package com.codecommit.wicket;
+
+import java.awt.Color;
+
+/**
+ * @author Daniel Spiewak
+ */
+public interface ISolidFill extends IChartFill {
+	public Color getColor();
+}
diff --git a/contrib/com/codecommit/wicket/LineStyle.java b/contrib/com/codecommit/wicket/LineStyle.java
new file mode 100644
index 0000000..0b1eade
--- /dev/null
+++ b/contrib/com/codecommit/wicket/LineStyle.java
@@ -0,0 +1,43 @@
+/*
+ * Created on Dec 11, 2007
+ */
+package com.codecommit.wicket;
+
+/**
+ * @author Daniel Spiewak
+ */
+public class LineStyle implements ILineStyle {
+	private int blankLength = -1;
+	private int segmentLength = -1;
+	private int thickness = -1;
+	
+	public LineStyle(int thickness, int segmentLength, int blankLength) {
+		this.thickness = thickness;
+		this.segmentLength = segmentLength;
+		this.blankLength = blankLength;
+	}
+	
+	public int getBlankLength() {
+		return blankLength;
+	}
+
+	public int getSegmentLength() {
+		return segmentLength;
+	}
+
+	public int getThickness() {
+		return thickness;
+	}
+
+	public void setBlankLength(int blankLength) {
+		this.blankLength = blankLength;
+	}
+
+	public void setSegmentLength(int segmentLength) {
+		this.segmentLength = segmentLength;
+	}
+
+	public void setThickness(int thickness) {
+		this.thickness = thickness;
+	}
+}
diff --git a/contrib/com/codecommit/wicket/LinearGradientFill.java b/contrib/com/codecommit/wicket/LinearGradientFill.java
new file mode 100644
index 0000000..090a9a8
--- /dev/null
+++ b/contrib/com/codecommit/wicket/LinearGradientFill.java
@@ -0,0 +1,49 @@
+/*
+ * Created on Dec 11, 2007
+ */
+package com.codecommit.wicket;
+
+import java.awt.Color;
+
+/**
+ * @author Daniel Spiewak
+ */
+public class LinearGradientFill implements ILinearGradientFill {
+	private int angle = -1;
+	private Color[] colors;
+	private double[] offsets;
+	
+	public LinearGradientFill(int angle, Color[] colors, double[] offsets) {
+		if (colors.length != offsets.length) {
+			throw new IllegalArgumentException("Must be same number of colors as offsets");
+		}
+		
+		this.angle = angle;
+		this.colors = colors;
+		this.offsets = offsets;
+	}
+
+	public int getAngle() {
+		return angle;
+	}
+
+	public Color[] getColors() {
+		return colors;
+	}
+
+	public double[] getOffsets() {
+		return offsets;
+	}
+
+	public void setAngle(int angle) {
+		this.angle = angle;
+	}
+
+	public void setColors(Color[] colors) {
+		this.colors = colors;
+	}
+
+	public void setOffsets(double[] offsets) {
+		this.offsets = offsets;
+	}
+}
diff --git a/contrib/com/codecommit/wicket/LinearStripesFill.java b/contrib/com/codecommit/wicket/LinearStripesFill.java
new file mode 100644
index 0000000..52b6f1e
--- /dev/null
+++ b/contrib/com/codecommit/wicket/LinearStripesFill.java
@@ -0,0 +1,49 @@
+/*
+ * Created on Dec 11, 2007
+ */
+package com.codecommit.wicket;
+
+import java.awt.Color;
+
+/**
+ * @author Daniel Spiewak
+ */
+public class LinearStripesFill implements ILinearStripesFill {
+	private int angle = -1;
+	private Color[] colors;
+	private double[] widths;
+	
+	public LinearStripesFill(int angle, Color[] colors, double[] widths) {
+		if (colors.length != widths.length) {
+			throw new IllegalArgumentException("Must be same number of colors as widths");
+		}
+		
+		this.angle = angle;
+		this.colors = colors;
+		this.widths = widths;
+	}
+	
+	public int getAngle() {
+		return angle;
+	}
+
+	public Color[] getColors() {
+		return colors;
+	}
+
+	public double[] getWidths() {
+		return widths;
+	}
+
+	public void setAngle(int angle) {
+		this.angle = angle;
+	}
+
+	public void setColors(Color[] colors) {
+		this.colors = colors;
+	}
+
+	public void setWidths(double[] widths) {
+		this.widths = widths;
+	}
+}
diff --git a/contrib/com/codecommit/wicket/MarkerType.java b/contrib/com/codecommit/wicket/MarkerType.java
new file mode 100644
index 0000000..d14ff54
--- /dev/null
+++ b/contrib/com/codecommit/wicket/MarkerType.java
@@ -0,0 +1,31 @@
+/*
+ * Created on Dec 11, 2007
+ */
+package com.codecommit.wicket;
+
+/**
+ * @author Daniel Spiewak
+ */
+public enum MarkerType {
+	ARROW("a"),
+	CROSS("c"),
+	DIAMOND("d"),
+	CIRCLE("o"),
+	SQUARE("s"),
+	
+	VERTICAL_TO_DATA("v"),
+	VERTICAL_TO_TOP("V"),
+	HORIZONTAL_ACROSS("h"),
+	
+	X("x");
+	
+	private final String rendering;
+	
+	private MarkerType(String rendering) {
+		this.rendering = rendering;
+	}
+	
+	public String getRendering() {
+		return rendering;
+	}
+}
diff --git a/contrib/com/codecommit/wicket/Range.java b/contrib/com/codecommit/wicket/Range.java
new file mode 100644
index 0000000..d5b7eb6
--- /dev/null
+++ b/contrib/com/codecommit/wicket/Range.java
@@ -0,0 +1,32 @@
+/*
+ * Created on Dec 11, 2007
+ */
+package com.codecommit.wicket;
+
+/**
+ * @author Daniel Spiewak
+ */
+public class Range {
+	private double start, end;
+	
+	public Range(double start, double end) {
+		this.start = start;
+		this.end = end;
+	}
+
+	public double getStart() {
+		return start;
+	}
+
+	public void setStart(double start) {
+		this.start = start;
+	}
+
+	public double getEnd() {
+		return end;
+	}
+
+	public void setEnd(double end) {
+		this.end = end;
+	}
+}
diff --git a/contrib/com/codecommit/wicket/RangeMarker.java b/contrib/com/codecommit/wicket/RangeMarker.java
new file mode 100644
index 0000000..a44c95c
--- /dev/null
+++ b/contrib/com/codecommit/wicket/RangeMarker.java
@@ -0,0 +1,55 @@
+/*
+ * Created on Dec 11, 2007
+ */
+package com.codecommit.wicket;
+
+import java.awt.Color;
+
+/**
+ * @author Daniel Spiewak
+ */
+public class RangeMarker implements IRangeMarker {
+	private Color color;
+	private double end = -1;
+	private double start = -1;
+	private RangeType type;
+	
+	public RangeMarker(RangeType type, Color color, double start, double end) {
+		this.type = type;
+		this.color = color;
+		this.start = start;
+		this.end = end;
+	}
+	
+	public Color getColor() {
+		return color;
+	}
+
+	public double getEnd() {
+		return end;
+	}
+
+	public double getStart() {
+		return start;
+	}
+
+	public RangeType getType() {
+		return type;
+	}
+
+	public void setColor(Color color) {
+		this.color = color;
+	}
+
+	public void setEnd(double end) {
+		this.end = end;
+	}
+
+	public void setStart(double start) {
+		this.start = start;
+	}
+
+	public void setType(RangeType type) {
+		this.type = type;
+	}
+}
diff --git a/contrib/com/codecommit/wicket/RangeType.java b/contrib/com/codecommit/wicket/RangeType.java
new file mode 100644
index 0000000..7a86d41
--- /dev/null
+++ b/contrib/com/codecommit/wicket/RangeType.java
@@ -0,0 +1,22 @@
+/*
+ * Created on Dec 11, 2007
+ */
+package com.codecommit.wicket;
+
+/**
+ * @author Daniel Spiewak
+ */
+public enum RangeType {
+	HORIZONTAL("r"),
+	VERTICAL("R");
+	
+	private final String rendering;
+	
+	private RangeType(String rendering) {
+		this.rendering = rendering;
+	}
+	
+	public String getRendering() {
+		return rendering;
+	}
+}
diff --git a/contrib/com/codecommit/wicket/ShapeMarker.java b/contrib/com/codecommit/wicket/ShapeMarker.java
new file mode 100644
index 0000000..88d1aa1
--- /dev/null
+++ b/contrib/com/codecommit/wicket/ShapeMarker.java
@@ -0,0 +1,65 @@
+/*
+ * Created on Dec 11, 2007
+ */
+package com.codecommit.wicket;
+
+import java.awt.Color;
+
+/**
+ * @author Daniel Spiewak
+ */
+public class ShapeMarker implements IShapeMarker {
+	private Color color;
+	private int index = -1;
+	private double point = -1;
+	private int size = -1;
+	private MarkerType type;
+	
+	public ShapeMarker(MarkerType type, Color color, int index, double point, int size) {
+		this.type = type;
+		this.color = color;
+		this.index = index;
+		this.point = point;
+		this.size = size;
+	}
+	
+	public Color getColor() {
+		return color;
+	}
+
+	public int getIndex() {
+		return index;
+	}
+
+	public double getPoint() {
+		return point;
+	}
+
+	public int getSize() {
+		return size;
+	}
+
+	public MarkerType getType() {
+		return type;
+	}
+
+	public void setColor(Color color) {
+		this.color = color;
+	}
+
+	public void setIndex(int index) {
+		this.index = index;
+	}
+
+	public void setPoint(double point) {
+		this.point = point;
+	}
+
+	public void setSize(int size) {
+		this.size = size;
+	}
+
+	public void setType(MarkerType type) {
+		this.type = type;
+	}
+}
diff --git a/contrib/com/codecommit/wicket/SolidFill.java b/contrib/com/codecommit/wicket/SolidFill.java
new file mode 100644
index 0000000..dac8734
--- /dev/null
+++ b/contrib/com/codecommit/wicket/SolidFill.java
@@ -0,0 +1,25 @@
+/*
+ * Created on Dec 11, 2007
+ */
+package com.codecommit.wicket;
+
+import java.awt.Color;
+
+/**
+ * @author Daniel Spiewak
+ */
+public class SolidFill implements ISolidFill {
+	private Color color;
+	
+	public SolidFill(Color color) {
+		this.color = color;
+	}
+
+	public Color getColor() {
+		return color;
+	}
+	
+	public void setColor(Color color) {
+		this.color = color;
+	}
+}
diff --git a/gitblit.properties b/gitblit.properties
index 815c646..7982504 100644
--- a/gitblit.properties
+++ b/gitblit.properties
@@ -49,9 +49,11 @@
 #
 # Git:Blit UI Settings
 #
-siteName = Git:Blit
+siteName = Repositories
 allowAdministration = true
 indexMessage = Welcome to Git:Blit!<br>A quick and easy way to host your own GIT repositories.<br>Built with <a href="http://eclipse.org/jgit">JGit</a>, <a href="http://wicket.apache.org">Wicket</a>, <a href="http://code.google.com/p/google-code-prettify/">google-code-prettify</a>, <a href="http://eclipse.org/jetty">Jetty</a>, <a href="http://www.slf4j.org">SLF4J</a>, <a href="http://logging.apache.org/log4j">Log4j</a>, and <a href="http://jcommander.org">JCommander</a>.
+
+# Date and Time formats
 timestampFormat = h:mm a
 
 datestampShortFormat = yyyy-MM-dd
@@ -60,6 +62,10 @@
 datetimestampShortFormat = yyyy-MM-dd h:mm a
 datetimestampLongFormat = EEEE, MMMM d, yyyy h:mm a
 
+# Generates a line graph of repository activity over time on the Summary page.
+# This is a real-time graph so generation may be expensive. 
+generateActivityGraph = true
+
 # Registered extensions for google-code-prettify
 prettyPrintExtensions = c cpp cs css htm html java js php pl prefs properties py rb sh sql xml vb
 
diff --git a/resources/blank.png b/resources/blank.png
new file mode 100644
index 0000000..109296b
--- /dev/null
+++ b/resources/blank.png
Binary files differ
diff --git a/resources/gitblit.css b/resources/gitblit.css
index d81c063..eebfdab 100644
--- a/resources/gitblit.css
+++ b/resources/gitblit.css
@@ -1,16 +1,74 @@
 /*
- JGitWeb css.
+ Git:Blit css.
 */
-body, table, tr, th, td { font-size: 13px; }
-
-table.object_header td, div.page_body, table.diff_tree td {
+html, body, table, dl, dt, dd, ol, ul, li, form, a, span, tr, th, td, div, em {
+	font-family: verdana, sans-serif;
 	font-size: 12px;
+	line-height: 15px;
 }
 
-table.diff_tree td div.link {
-	padding: 2px 5px;
-	font-family: sans-serif;
-	font-size: 9px;
+body {
+	margin: 5px;
+	background-color: #ffffff;
+	color: #000000;
+}
+
+pre.prettyprint, pre.plainprint {
+	color: black;
+	font-size:12px;
+	border:0px;
+}
+
+/* age0: age < 60*60*2 */
+.age0 {
+	color: #009900;
+	font-style: italic;
+	font-weight: bold;
+}
+
+/* age1: 60*60*2 <= age < 60*60*24*2 */
+.age1 {
+	color: #009900;
+	font-style: italic;
+}
+
+/* age2: 60*60*24*2 <= age */
+.age2 {
+	font-style: italic;
+}
+
+
+a {
+	color: #0000cc;
+}
+
+a:hover, a:visited, a:active {
+	color: #880000;
+}
+
+img.logo {
+	float: right;
+	border-width: 0px;
+}
+
+div.header {
+	background-color: #D2C3AF;
+	padding: 3px;
+	border: 1px solid #808080;
+}
+
+div.header a {
+	color: black;
+	text-decoration: none;
+	font-weight: bold;
+}
+
+div.header a:hover {
+	text-decoration: underline;
+}
+
+div.pager {
+	padding: 0px 0px 15px 5px;
 }
 
 div.link {
@@ -19,38 +77,222 @@
 	font-size: 9px;
 }
 
-pre.prettyprint, pre.plainprint {
-	font-size:12px;
-	border:0px;
+div.link a {
+	font-size: 9px;
+}
+
+div.page_header {
+	height: 25px;
+	padding: 5px;
+	font-family: sans-serif;
+	font-weight: bold;
+	font-size: 150%;
+	color: #ccc;
+	background-color: #ffffff;
+}
+
+div.page_header span {	
+	font-family: inherit;
+	font-size: inherit;	
+}
+
+div.page_header a  {
+	font-size: inherit;	
+	font-family: inherit;
+	text-decoration: none;
+}
+
+div.page_header a:visited {
+	color: #000000;
+}
+
+div.page_header a:hover {
+	color: E66C2C;
+	text-decoration: underline;
+}
+
+div.page_footer {
+	color: black;
+	background-color: #ffffff;
+	padding: 5px;
+	border-top: 1px solid #bbb;
+	font-style: italic;
+}
+
+div.page_nav {
+	color: #ccc;
+	background-color: #000070;
+	padding: 5px;
+}
+
+div.page_nav a {
+	color: yellow;
+	text-decoration: none;
+}
+
+div.page_nav a:hover {	
+	text-decoration: underline;
 }
 
 div.page_nav2 {
-	padding: 0px 8px 8px 8px;	
+	padding: 2px 5px 7px 5px;	
 }
 
-table.project_list tr th a { padding-right: 15px; background-position: right; background-repeat:no-repeat; }
-table.project_list tr th.wicket_orderDown a {font-weight: bold; background-image: url(arrow_down.png); }
-table.project_list tr th.wicket_orderUp a { font-weight: bold; background-image: url(arrow_up.png); }
-table.project_list tr th.wicket_orderNone a { font-weight: normal; background-image: url(arrow_off.png); }
+.repositories_message {
+	border: solid #bbb;
+	border-width: 0px 0px 1px;
+	padding: 8px;
+}
 
-/* age0: age < 60*60*2 */
-table.project_list .age0 {
-	color: #009900;
-	font-style: italic;
+div.page_path {
+	padding: 8px;
 	font-weight: bold;
+	border: solid #bbb;
+	border-width: 0px 0px 1px;
 }
 
-/* age1: 60*60*2 <= age < 60*60*24*2 */
-table.project_list .age1 {
-	color: #009900;
+div.commit_message {
+	padding: 8px;
+	border: solid #bbb;
+	border-width: 1px 0px 1px;
+}
+
+a.list {
+	text-decoration: none;
+	color: #000000;
+}
+
+a.list:hover {
+	text-decoration: underline;
+	color: #880000;
+}
+
+table {
+	border-spacing: 0px;
+}
+
+th {
+	padding: 2px 5px;
+	font-size: 100%;
+	text-align: left;
+}
+
+table.plain {
+	padding: 8px;
+}
+
+table.pretty, table.repositories {
+	margin-top:5px;
+	margin-bottom:5px;
+	border-spacing: 0px;
+	border-top: 1px solid #bbb;
+	border-left: 1px solid #bbb;
+	border-right: 1px solid #bbb;	
+}
+
+table.repositories {
+	width:100%;	
+}
+
+table.repositories th {
+	background-color:#D3BDA1;
+	padding: 5px;
+	border-bottom: 1px solid #bbb;
+}
+
+tr th a { padding-right: 15px; background-position: right; background-repeat:no-repeat; }
+tr th.wicket_orderDown a {font-weight: bold; background-image: url(arrow_down.png); }
+tr th.wicket_orderUp a { font-weight: bold; background-image: url(arrow_up.png); }
+tr th.wicket_orderNone a { font-weight: normal; background-image: url(arrow_off.png); }
+
+tr.light {
+	background-color: #ffffff;
+}
+
+tr.light td {
+	border-bottom: 1px solid #bbb;	
+}
+
+tr.dark {
+	background-color: #faf8dc;
+	border-bottom: 1px solid #bbb;	
+}
+
+tr.dark td {
+	border-bottom: 1px solid #bbb;	
+}
+
+/* currently both use the same, but it can change */
+tr.light:hover,
+tr.dark:hover {
+	background-color: #f6a234;
+}
+
+td {
+	padding-left: 7px;
+	padding-right: 7px;
+}
+
+td.author {
 	font-style: italic;
 }
 
-/* age2: 60*60*24*2 <= age */
-table.project_list .age2 {
+td.date {
+	font-style: italic;
+	width:90px;
+}
+
+td.sha1, td.sha1 span {
+	font-family: monospace;
+	font-size: 13px;
+}
+
+td.mode {
+	font-family: monospace;
+	width:90px;
+	padding-right:15px;
+}
+
+td.size {
+	text-align: right;
+	width:100px;	
+	padding-right:15px;
+}
+
+span.refs span {
+	padding: 0px 4px;
+	font-family: sans-serif;
+	font-size: 70%;
+	font-weight: normal;
+	border: 1px solid;
+	background-color: #ffaaff;
+	border-color: #ffccff #ff00ee #ff00ee #ffccff;
+}
+
+span.refs span a {
+	text-decoration: none;
+	color: inherit;
+}
+
+span.refs span a:hover {
+	text-decoration: underline;
+}
+
+span.refs span.indirect {
 	font-style: italic;
 }
 
-table.diff_tree td.size {
-	width:80px;
+span.refs span.ref {
+	background-color: #aaaaff;
+	border-color: #ccccff #0033cc #0033cc #ccccff;
+}
+
+span.refs span.tag {
+	background-color: #ffffaa;
+	border-color: #ffffcc #ffee00 #ffee00 #ffffcc;
+}
+
+span.refs span.head {
+	background-color: #aaffaa;
+	border-color: #ccffcc #00cc33 #00cc33 #ccffcc;
 }
\ No newline at end of file
diff --git a/src/com/gitblit/utils/JGitUtils.java b/src/com/gitblit/utils/JGitUtils.java
index 673c987..31b5677 100644
--- a/src/com/gitblit/utils/JGitUtils.java
+++ b/src/com/gitblit/utils/JGitUtils.java
@@ -5,6 +5,8 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.RandomAccessFile;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Date;
@@ -35,9 +37,9 @@
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.gitblit.wicket.models.Metric;
 import com.gitblit.wicket.models.PathModel;
 import com.gitblit.wicket.models.RefModel;
-
 
 public class JGitUtils {
 
@@ -204,7 +206,7 @@
 
 	public static List<PathModel> getFilesInPath(Repository r, String basePath, RevCommit commit) {
 		List<PathModel> list = new ArrayList<PathModel>();
-		final TreeWalk walk = new TreeWalk(r);		
+		final TreeWalk walk = new TreeWalk(r);
 		try {
 			walk.addTree(commit.getTree());
 			if (basePath != null && basePath.length() > 0) {
@@ -214,7 +216,7 @@
 				boolean foundFolder = false;
 				while (walk.next()) {
 					if (!foundFolder && walk.isSubtree()) {
-						walk.enterSubtree();						
+						walk.enterSubtree();
 					}
 					if (walk.getPathString().equals(basePath)) {
 						foundFolder = true;
@@ -264,7 +266,7 @@
 		return list;
 	}
 
-	private static PathModel getPathModel(TreeWalk walk, String basePath, RevCommit commit) {		
+	private static PathModel getPathModel(TreeWalk walk, String basePath, RevCommit commit) {
 		String name;
 		long size = 0;
 		if (basePath == null) {
@@ -310,7 +312,6 @@
 		return FileMode.TREE.equals(mode);
 	}
 
-	
 	public static List<RevCommit> getRevLog(Repository r, int maxCount) {
 		List<RevCommit> list = new ArrayList<RevCommit>();
 		try {
@@ -427,4 +428,29 @@
 		}
 		return null;
 	}
+
+	public static List<Metric> getDateMetrics(Repository r) {
+		final Map<String, Metric> map = new HashMap<String, Metric>();
+		try {
+			DateFormat df = new SimpleDateFormat("yyyy-MM");
+			Git git = new Git(r);
+			Iterable<RevCommit> revlog = git.log().call();
+			for (RevCommit rev : revlog) {
+				Date d = getCommitDate(rev);
+				String p = df.format(d);
+				if (!map.containsKey(p))
+					map.put(p, new Metric(p));
+				map.get(p).count++;
+			}
+		} catch (Throwable t) {
+			LOGGER.error("Failed to mine log history for metrics", t);
+		}
+		List<String> keys = new ArrayList<String>(map.keySet());
+		Collections.sort(keys);
+		List<Metric> metrics = new ArrayList<Metric>();
+		for (String key:keys) {
+			metrics.add(map.get(key));
+		}		
+		return metrics;
+	}
 }
diff --git a/src/com/gitblit/wicket/GitBlitWebApp.java b/src/com/gitblit/wicket/GitBlitWebApp.java
index d971cb7..86b6ba6 100644
--- a/src/com/gitblit/wicket/GitBlitWebApp.java
+++ b/src/com/gitblit/wicket/GitBlitWebApp.java
@@ -32,7 +32,6 @@
 import com.gitblit.wicket.pages.BlobPage;
 import com.gitblit.wicket.pages.CommitPage;
 import com.gitblit.wicket.pages.HeadsPage;
-import com.gitblit.wicket.pages.LogPage;
 import com.gitblit.wicket.pages.RepositoriesPage;
 import com.gitblit.wicket.pages.ShortLogPage;
 import com.gitblit.wicket.pages.SummaryPage;
@@ -64,7 +63,6 @@
 		mount(new MixedParamUrlCodingStrategy("/about", AboutPage.class, new String[] { }));
 		mount(new MixedParamUrlCodingStrategy("/summary", SummaryPage.class, new String[] { "p" }));
 		mount(new MixedParamUrlCodingStrategy("/shortlog", ShortLogPage.class, new String[] { "p", "h" }));
-		mount(new MixedParamUrlCodingStrategy("/log", LogPage.class, new String[] { "p", "h" }));
 		mount(new MixedParamUrlCodingStrategy("/tags", TagsPage.class, new String[] { "p" }));
 		mount(new MixedParamUrlCodingStrategy("/heads", HeadsPage.class, new String[] { "p" }));
 		mount(new MixedParamUrlCodingStrategy("/commit", CommitPage.class, new String[] { "p", "h" }));
diff --git a/src/com/gitblit/wicket/WicketUtils.java b/src/com/gitblit/wicket/WicketUtils.java
index 1d85a80..e46a473 100644
--- a/src/com/gitblit/wicket/WicketUtils.java
+++ b/src/com/gitblit/wicket/WicketUtils.java
@@ -1,32 +1,20 @@
 package com.gitblit.wicket;
 
-import org.apache.wicket.AttributeModifier;
 import org.apache.wicket.Component;
-import org.apache.wicket.model.AbstractReadOnlyModel;
+import org.apache.wicket.behavior.SimpleAttributeModifier;
 
 public class WicketUtils {
 
 	public static void setCssClass(Component container, String value) {
-		container.add(newAttributeModifier("class", value));
+		container.add(new SimpleAttributeModifier("class", value));
 	}
 
 	public static void setCssStyle(Component container, String value) {
-		container.add(newAttributeModifier("style", value));
+		container.add(new SimpleAttributeModifier("style", value));
 	}
 
 	public static void setHtmlTitle(Component container, String value) {
-		container.add(newAttributeModifier("title", value));
-	}
-
-	private static AttributeModifier newAttributeModifier(String attrib, final String value) {
-		return new AttributeModifier(attrib, true, new AbstractReadOnlyModel<String>() {
-			private static final long serialVersionUID = 1L;
-
-			@Override
-			public String getObject() {
-				return value;
-			}
-		});
+		container.add(new SimpleAttributeModifier("title", value));
 	}
 
 	public static String breakLines(String string) {
diff --git a/src/com/gitblit/wicket/models/Metric.java b/src/com/gitblit/wicket/models/Metric.java
new file mode 100644
index 0000000..a5efb13
--- /dev/null
+++ b/src/com/gitblit/wicket/models/Metric.java
@@ -0,0 +1,15 @@
+package com.gitblit.wicket.models;
+
+import java.io.Serializable;
+
+public class Metric implements Serializable {
+
+	private static final long serialVersionUID = 1L;
+
+	public String name;
+	public double count;
+
+	public Metric(String name) {
+		this.name = name;
+	}
+}
\ No newline at end of file
diff --git a/src/com/gitblit/wicket/models/PathModel.java b/src/com/gitblit/wicket/models/PathModel.java
index 3fa0f63..cd44730 100644
--- a/src/com/gitblit/wicket/models/PathModel.java
+++ b/src/com/gitblit/wicket/models/PathModel.java
@@ -40,6 +40,15 @@
 
 	@Override
 	public int compareTo(PathModel o) {
-		return path.compareTo(o.path);
+		boolean isTree = isTree();
+		boolean otherTree = o.isTree();
+		if (isTree && otherTree) {
+			return path.compareTo(o.path);
+		} else if (!isTree && !otherTree) {
+			return path.compareTo(o.path);
+		} else if (isTree && !otherTree) {
+			return -1;
+		}
+		return 1;
 	}
 }
diff --git a/src/com/gitblit/wicket/pages/BlobPage.java b/src/com/gitblit/wicket/pages/BlobPage.java
index 979bb26..cfbfaa4 100644
--- a/src/com/gitblit/wicket/pages/BlobPage.java
+++ b/src/com/gitblit/wicket/pages/BlobPage.java
@@ -20,7 +20,7 @@
 public class BlobPage extends RepositoryPage {
 
 	public BlobPage(PageParameters params) {
-		super(params, "blob");
+		super(params, "view");
 
 		final String blobPath = params.getString("f", null);
 
@@ -29,7 +29,7 @@
 
 		// blob page links
 		add(new Label("historyLink", "history"));
-		add(new Label("rawLink", "raw"));
+		add(new Label("rawLink", "download"));
 		add(new Label("headLink", "HEAD"));
 
 		add(new LinkPanel("shortlog", "title", commit.getShortMessage(), CommitPage.class, newCommitParameter()));
diff --git a/src/com/gitblit/wicket/pages/CommitPage.html b/src/com/gitblit/wicket/pages/CommitPage.html
index a493e04..c2edbea 100644
--- a/src/com/gitblit/wicket/pages/CommitPage.html
+++ b/src/com/gitblit/wicket/pages/CommitPage.html
@@ -9,38 +9,32 @@
 	
 	<!-- commit nav links -->	
 	<div class="page_nav2">
-		(parent: <span wicket:id="parentLink"></span>) | <span wicket:id="patchLink"></span>
+		parent: <span wicket:id="parentLink"></span> | <span wicket:id="patchLink"></span>
 	</div>	
 	
 	<!-- shortlog header -->
 	<div class="header" wicket:id="shortlog"></div>
 	
-	<!-- Refs -->
-	<div wicket:id="refsPanel"></div>
-	
 	<!-- commit info -->
-	<div class="title_text">
-	<table class="object_header">
-		<tr><td>author</td><td><span wicket:id="commitAuthor">Message goes here</span></td></tr>
-		<tr><td></td><td><span wicket:id="commitAuthorDate">Message goes here</span></td></tr>
-		<tr><td>committer</td><td><span wicket:id="commitCommitter">Message goes here</span></td></tr>
-		<tr><td></td><td><span wicket:id="commitCommitterDate">Message goes here</span></td></tr>
-		<tr><td>commit</td><td class="sha1"><span wicket:id="commitId">Message goes here</span></td></tr>
-		<tr><td>tree</td><td class="sha1"><span wicket:id="commitTree">Message goes here</span></td></tr>
-		<tr><td>parent</td><td class="sha1"><span wicket:id="commitParents">
+	<table class="plain">
+		<tr><th>refs</th><td><div wicket:id="refsPanel"></div></td></tr>
+		<tr><th>author</th><td><span wicket:id="commitAuthor">Message goes here</span></td></tr>
+		<tr><th></th><td><span wicket:id="commitAuthorDate">Message goes here</span></td></tr>
+		<tr><th>committer</th><td><span wicket:id="commitCommitter">Message goes here</span></td></tr>
+		<tr><th></th><td><span wicket:id="commitCommitterDate">Message goes here</span></td></tr>
+		<tr><th>commit</th><td class="sha1"><span wicket:id="commitId">Message goes here</span></td></tr>
+		<tr><th>tree</th><td class="sha1"><span wicket:id="commitTree">Message goes here</span></td></tr>
+		<tr><th>parent</th><td class="sha1"><span wicket:id="commitParents">
 			<div wicket:id="commitParent">Message goes here</div></span></td></tr>
 	</table>
-	</div>
 	
 	<!-- full message -->
-	<div class="page_body" wicket:id="fullMessage"></div>
+	<div class="commit_message" wicket:id="fullMessage"></div>
 	
 	<!-- changed paths -->
-	<div class="list_head"></div>
-	<table class="diff_tree">
+	<table class="pretty">
 		<tr wicket:id="changedPath">
-			<td class="path"><span wicket:id="pathName"></span></td>
-			<td></td>
+			<td class="path"><span wicket:id="pathName"></span></td>			
 			<td><span wicket:id="pathLinks"></span></td>
 		</tr>
 	</table>
diff --git a/src/com/gitblit/wicket/pages/HeadsPage.html b/src/com/gitblit/wicket/pages/HeadsPage.html
index cd91436..ed99c89 100644
--- a/src/com/gitblit/wicket/pages/HeadsPage.html
+++ b/src/com/gitblit/wicket/pages/HeadsPage.html
@@ -8,9 +8,8 @@
 	<div wicket:id="pageLinks"></div>
 	
 	<!-- shortlog -->	
-	<div class="header" wicket:id="summary"></div>
-	
-	<table class="heads">
+	<div class="header" wicket:id="summary"></div>	
+	<table>
 		<tbody>
        		<tr wicket:id="head">
          		<td><i><span wicket:id="headDate"></span></i></td>
diff --git a/src/com/gitblit/wicket/pages/LogPage.html b/src/com/gitblit/wicket/pages/LogPage.html
deleted file mode 100644
index 3c1b54b..0000000
--- a/src/com/gitblit/wicket/pages/LogPage.html
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<html xmlns="http://www.w3.org/1999/xhtml" >
-<body>
-	<!-- page header -->
-	<div wicket:id="pageHeader"></div>
-
-	<!-- page nav links -->	
-	<div wicket:id="pageLinks"></div>
-
-	<!-- summary header -->
-	<div class="header" wicket:id="summary"></div>
-	
-	<!-- log -->		
-	<div wicket:id="commit">
-		<div class="header">
-			<b><span class="age" wicket:id="timeAgo"></span></b>
-			<span wicket:id="link"></span>
-		</div>
-		<div wicket:id="commitRefs"></div>
-		<div class="title_text">
-			<div class="log_link">commit | commitdiff | tree</div>
-			<span wicket:id="commitAuthor"></span>
-			<span wicket:id="commitDate"></span>
-		</div>
-		<div class="log_body" wicket:id="fullMessage"></div>		
-	</div>
-		
-	<div wicket:id="navigator"></div>	
-
-	<!-- footer -->
-	<div wicket:id="pageFooter"></div>
-</body>
-</html>
\ No newline at end of file
diff --git a/src/com/gitblit/wicket/pages/LogPage.java b/src/com/gitblit/wicket/pages/LogPage.java
deleted file mode 100644
index 325596a..0000000
--- a/src/com/gitblit/wicket/pages/LogPage.java
+++ /dev/null
@@ -1,69 +0,0 @@
-package com.gitblit.wicket.pages;
-
-import java.util.Date;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.wicket.PageParameters;
-import org.apache.wicket.markup.html.basic.Label;
-import org.apache.wicket.markup.html.navigation.paging.PagingNavigator;
-import org.apache.wicket.markup.repeater.Item;
-import org.apache.wicket.markup.repeater.data.DataView;
-import org.apache.wicket.markup.repeater.data.ListDataProvider;
-import org.eclipse.jgit.lib.ObjectId;
-import org.eclipse.jgit.lib.Repository;
-import org.eclipse.jgit.revwalk.RevCommit;
-
-import com.gitblit.utils.JGitUtils;
-import com.gitblit.utils.Utils;
-import com.gitblit.wicket.GitBlitWebApp;
-import com.gitblit.wicket.GitBlitWebSession;
-import com.gitblit.wicket.LinkPanel;
-import com.gitblit.wicket.RepositoryPage;
-import com.gitblit.wicket.WicketUtils;
-import com.gitblit.wicket.panels.RefsPanel;
-
-
-public class LogPage extends RepositoryPage {
-
-	public LogPage(PageParameters params) {
-		super(params, "log");
-
-		Repository r = getRepository();
-		final Map<ObjectId, List<String>> allRefs = JGitUtils.getAllRefs(r);
-		List<RevCommit> commits = JGitUtils.getRevLog(r, 100);
-		r.close();
-
-		add(new LinkPanel("summary", "title", repositoryName, SummaryPage.class, newRepositoryParameter()));
-
-		// log
-		ListDataProvider<RevCommit> dp = new ListDataProvider<RevCommit>(commits);
-		DataView<RevCommit> logView = new DataView<RevCommit>("commit", dp) {
-			private static final long serialVersionUID = 1L;
-
-			public void populateItem(final Item<RevCommit> item) {
-				final RevCommit entry = item.getModelObject();
-				final Date date = JGitUtils.getCommitDate(entry);
-
-				item.add(new Label("timeAgo", Utils.timeAgo(date)));
-
-				item.add(new LinkPanel("link", "title", entry.getShortMessage(), CommitPage.class, newCommitParameter(entry.getName())));
-
-				item.add(new RefsPanel("commitRefs", entry, allRefs));
-
-				String author = entry.getAuthorIdent().getName();
-				item.add(createAuthorLabel("commitAuthor", author));
-
-				item.add(new Label("commitDate", GitBlitWebSession.get().formatDateTimeLong(date)));
-
-				item.add(new Label("fullMessage", WicketUtils.breakLines(entry.getFullMessage())).setEscapeModelStrings(false));
-			}
-		};
-		logView.setItemsPerPage(GitBlitWebApp.PAGING_ITEM_COUNT);
-		add(logView);
-		add(new PagingNavigator("navigator", logView));
-
-		// footer
-		addFooter();
-	}
-}
diff --git a/src/com/gitblit/wicket/pages/RepositoriesPage.html b/src/com/gitblit/wicket/pages/RepositoriesPage.html
index 6a3054f..0a7b270 100644
--- a/src/com/gitblit/wicket/pages/RepositoriesPage.html
+++ b/src/com/gitblit/wicket/pages/RepositoriesPage.html
@@ -2,15 +2,13 @@
 <html xmlns="http://www.w3.org/1999/xhtml" >
 <body>
 	<div wicket:id="pageHeader"></div>
-	<div class="index_include" wicket:id="indexInclude"></div>
-	
-	<table class="project_list">
+	<div class="repositories_message" wicket:id="indexInclude"></div>	
+	<table class="repositories">
 		<tr>
 			<th wicket:id="orderByRepository">Repository</th>
 			<th wicket:id="orderByDescription">Description</th>
 			<th wicket:id="orderByOwner">Owner</th>
 			<th wicket:id="orderByDate">Last Change</th>
-			<th></th>
 		</tr>
 		<tbody>
        		<tr wicket:id="repository">
@@ -18,7 +16,6 @@
          		<td><div class="list" wicket:id="repositoryDescription"></div></td>
          		<td><i><span wicket:id="repositoryOwner"></span></i></td>
          		<td><span wicket:id="repositoryLastChange"></span></td>
-         		<td></td>
        		</tr>
     	</tbody>
 	</table>
diff --git a/src/com/gitblit/wicket/pages/RepositoriesPage.java b/src/com/gitblit/wicket/pages/RepositoriesPage.java
index 1c880d9..50bcba2 100644
--- a/src/com/gitblit/wicket/pages/RepositoriesPage.java
+++ b/src/com/gitblit/wicket/pages/RepositoriesPage.java
@@ -63,7 +63,7 @@
 		add(newSort("orderByOwner", SortBy.owner, dp, dataView));
 		add(newSort("orderByDate", SortBy.date, dp, dataView));
 
-		add(new PageFooter("pageFooter"));
+		add(new PageFooter("pageFooter", ""));
 	}
 
 	protected enum SortBy {
diff --git a/src/com/gitblit/wicket/pages/ShortLogPage.html b/src/com/gitblit/wicket/pages/ShortLogPage.html
index b10e90d..5afc6cd 100644
--- a/src/com/gitblit/wicket/pages/ShortLogPage.html
+++ b/src/com/gitblit/wicket/pages/ShortLogPage.html
@@ -8,22 +8,19 @@
 	<div wicket:id="pageLinks"></div>
 	
 	<!-- shortlog -->	
-	<div class="header" wicket:id="summary"></div>
-	
-	<table class="project_list">
+	<div style="margin-top:5px;" class="header" wicket:id="summary"></div>	
+	<table class="pretty">
 		<tbody>
        		<tr wicket:id="commit">
-         		<td><span wicket:id="commitDate"></span></td>
-         		<td><i><span wicket:id="commitAuthor"></span></i></td>
+         		<td class="date"><span wicket:id="commitDate"></span></td>
+         		<td class="author"><span wicket:id="commitAuthor"></span></td>
          		<td><div wicket:id="commitShortMessage"></div></td>
          		<td><div wicket:id="commitRefs"></div></td>         		
          		<td><span wicket:id="commitLinks"></span></td>
        		</tr>
-       		<tr>   	
-				<td colspan="4"><div wicket:id="navigator"></div></td>	
-       		</tr>   		    	
     	</tbody>
 	</table>	
+	<div class="pager" wicket:id="navigator"></div>
 	
 	<!-- footer -->
 	<div wicket:id="pageFooter"></div>
diff --git a/src/com/gitblit/wicket/pages/SummaryPage.html b/src/com/gitblit/wicket/pages/SummaryPage.html
index 3eab0a1..be00143 100644
--- a/src/com/gitblit/wicket/pages/SummaryPage.html
+++ b/src/com/gitblit/wicket/pages/SummaryPage.html
@@ -7,70 +7,76 @@
 	<!-- page nav links -->	
 	<div wicket:id="pageLinks"></div>
 	
-	<!-- repository info -->
-    <div class="title">&nbsp;</div>
-	<table class="projects_list">
-		<tr id="metadata_desc"><td>description</td><td><span wicket:id="repositoryDescription">Message goes here</span></td></tr>
-		<tr id="metadata_owner"><td>owner</td><td><span wicket:id="repositoryOwner">Message goes here</span></td></tr>
-		<tr id="metadata_lchange"><td>last change</td><td><span wicket:id="repositoryLastChange">Message goes here</span></td></tr>
-		<tr class="metadata_url"><td>URL</td><td><span wicket:id="repositoryCloneUrl">Message goes here</span></td></tr>
-	</table>
-
-
-	<!-- shortlog -->	
-	<div class="header" wicket:id="shortlog"></div>
+	<div>
+		<!-- Repository Activity Chart -->	
+		<div style="width:50%;float:right;">
+			<img style="padding-top:8px;" wicket:id="commitsChart" />
+		</div>	
 	
-	<table class="project_list">
+		<!-- Repository info -->
+		<div style="width:50%;"> 
+			<table class="plain">
+				<tr><th>description</th><td><span wicket:id="repositoryDescription">Message goes here</span></td></tr>
+				<tr><th>owner</th><td><span wicket:id="repositoryOwner">Message goes here</span></td></tr>
+				<tr><th>last change</th><td><span wicket:id="repositoryLastChange">Message goes here</span></td></tr>
+				<tr><th>URL</th><td><span wicket:id="repositoryCloneUrl">Message goes here</span></td></tr>
+			</table>
+		</div>
+	</div>
+
+	<!-- shortlog -->
+	<div class="header" wicket:id="shortlog"></div>	
+	<table style="width:100%" class="pretty">
 		<tbody>
        		<tr wicket:id="commit">
-         		<td><span wicket:id="commitDate"></span></td>
-         		<td><i><span wicket:id="commitAuthor"></span></i></td>
+         		<td class="date"><span wicket:id="commitDate"></span></td>
+         		<td class="author"><span wicket:id="commitAuthor"></span></td>
          		<td><div wicket:id="commitShortMessage"></div></td>
          		<td><div wicket:id="commitRefs"></div></td>
          		<td><span wicket:id="commitLinks"></span></td>
        		</tr>
-       		
-       		<tr>
-				<td colspan="4"><div wicket:id="shortlogMore"></div></td>
-			</tr>       		
     	</tbody>
 	</table>	
+	<div class="pager" wicket:id="shortlogMore"></div>
 
-
-	<!-- tags -->
-	<div class="header" wicket:id="tags"></div>
+	<!-- Open additional graphs body -->
+	<div style="width:25%;float:right;">
+	</div>
 	
-	<table class="project_list">
-		<tbody>
-       		<tr wicket:id="tag">
-         		<td><i><span wicket:id="tagDate"></span></i></td>
-         		<td><div wicket:id="tagName"></div></td>
-         		<td><div wicket:id="tagDescription"></div></td>
-         		<td><span wicket:id="tagLinks"></span></td>
-       		</tr>
-       		
-			<tr>
-				<td colspan="4"><div wicket:id="tagsMore"></div></td>
-			</tr>
-    	</tbody>
-	</table>
+	<!-- Open Tags and Heads body -->
+	<div style="width:65%">
+	
+	<!-- tags -->
+	<div class="header" wicket:id="tags"></div>	
+		<table style="width:100%" class="pretty">
+			<tbody>
+       			<tr wicket:id="tag">
+         			<td class="date"><span wicket:id="tagDate"></span></td>
+         			<td><b><div wicket:id="tagName"></div></b></td>
+         			<td><div wicket:id="tagDescription"></div></td>
+         			<td><span wicket:id="tagLinks"></span></td>
+       			</tr>
+    		</tbody>
+		</table>
+	<div class="pager" wicket:id="tagsMore"></div>
 
 
 	<!-- heads -->
-	<div class="header" wicket:id="heads"></div>
-	
-	<table class="heads">
+	<div class="header" wicket:id="heads"></div>	
+	<table style="width:100%" class="pretty">
 		<tbody>
-       		<tr wicket:id="head">
-         		<td><i><span wicket:id="headDate"></span></i></td>
-         		<td><div wicket:id="headName"></div></td>
-         		<td><span wicket:id="headLinks"></span></td>
-       		</tr>
-    	</tbody>
+   			<tr wicket:id="head">
+       			<td class="date"><span wicket:id="headDate"></span></td>
+       			<td><div wicket:id="headName"></div></td>
+       			<td><span wicket:id="headLinks"></span></td>
+   			</tr>
+   		</tbody>
 	</table>
-
-
+	
+	<!-- Close Tags and Heads Body -->
+	</div>
+	
 	<!-- footer -->
-	<div wicket:id="pageFooter"></div>
+	<div style="clear:both;" wicket:id="pageFooter"></div>
 </body>
 </html>
\ No newline at end of file
diff --git a/src/com/gitblit/wicket/pages/SummaryPage.java b/src/com/gitblit/wicket/pages/SummaryPage.java
index 84e78b4..318e3c9 100644
--- a/src/com/gitblit/wicket/pages/SummaryPage.java
+++ b/src/com/gitblit/wicket/pages/SummaryPage.java
@@ -1,11 +1,13 @@
 package com.gitblit.wicket.pages;
 
+import java.awt.Dimension;
 import java.util.Date;
 import java.util.List;
 import java.util.Map;
 
 import org.apache.wicket.PageParameters;
 import org.apache.wicket.markup.html.basic.Label;
+import org.apache.wicket.markup.html.image.ContextImage;
 import org.apache.wicket.markup.repeater.Item;
 import org.apache.wicket.markup.repeater.data.DataView;
 import org.apache.wicket.markup.repeater.data.ListDataProvider;
@@ -13,18 +15,26 @@
 import org.eclipse.jgit.lib.Repository;
 import org.eclipse.jgit.revwalk.RevCommit;
 
+import com.codecommit.wicket.AbstractChartData;
+import com.codecommit.wicket.Chart;
+import com.codecommit.wicket.ChartAxis;
+import com.codecommit.wicket.ChartAxisType;
+import com.codecommit.wicket.ChartProvider;
+import com.codecommit.wicket.ChartType;
+import com.codecommit.wicket.IChartData;
+import com.gitblit.StoredSettings;
 import com.gitblit.utils.JGitUtils;
 import com.gitblit.wicket.GitBlitWebApp;
 import com.gitblit.wicket.GitBlitWebSession;
 import com.gitblit.wicket.LinkPanel;
 import com.gitblit.wicket.RepositoryPage;
 import com.gitblit.wicket.WicketUtils;
+import com.gitblit.wicket.models.Metric;
 import com.gitblit.wicket.models.RefModel;
 import com.gitblit.wicket.panels.HeadLinksPanel;
 import com.gitblit.wicket.panels.RefsPanel;
 import com.gitblit.wicket.panels.ShortLogLinksPanel;
 import com.gitblit.wicket.panels.TagLinksPanel;
-
 
 public class SummaryPage extends RepositoryPage {
 
@@ -82,7 +92,7 @@
 			}
 		};
 		add(shortlogView);
-		add(new LinkPanel("shortlogMore", "link", "...", ShortLogPage.class, newRepositoryParameter()));
+		add(new LinkPanel("shortlogMore", "link", "more...", ShortLogPage.class, newRepositoryParameter()));
 
 		// tags
 		List<RefModel> tags = JGitUtils.getTags(r, summaryCount);
@@ -115,7 +125,8 @@
 			}
 		};
 		add(tagView);
-		add(new LinkPanel("tagsMore", "link", "...", TagsPage.class, newRepositoryParameter()));
+		add(new LinkPanel("tagsMore", "link", "more...", TagsPage.class, newRepositoryParameter()));
+
 		// heads
 		List<RefModel> heads = JGitUtils.getHeads(r, summaryCount);
 		add(new LinkPanel("heads", "title", "heads", HeadsPage.class, newRepositoryParameter()));
@@ -140,10 +151,74 @@
 		};
 		add(headsView);
 
+		// Display an activity line graph
+		insertActivityGraph(r);
+
 		// close the repository
 		r.close();
 
 		// footer
 		addFooter();
 	}
+
+	private void insertActivityGraph(Repository r) {
+		if (StoredSettings.getBoolean("generateActivityGraph", true)) {
+			List<Metric> dates = JGitUtils.getDateMetrics(r);
+			IChartData data = getChartData(dates);
+
+			ChartProvider provider = new ChartProvider(new Dimension(400, 80), ChartType.LINE, data);
+			ChartAxis dateAxis = new ChartAxis(ChartAxisType.BOTTOM);
+			dateAxis.setLabels(new String[] { dates.get(0).name, dates.get(dates.size() / 2).name, dates.get(dates.size() - 1).name });
+			provider.addAxis(dateAxis);
+
+			ChartAxis commitAxis = new ChartAxis(ChartAxisType.LEFT);
+			commitAxis.setLabels(new String[] { "", String.valueOf((int) maxValue(dates)) });
+			provider.addAxis(commitAxis);
+
+			add(new Chart("commitsChart", provider));
+		} else {
+			add(new ContextImage("commitsChart", "blank.png"));			
+		}
+	}
+
+	protected IChartData getChartData(List<Metric> results) {
+		final double[] counts = new double[results.size()];
+		int i = 0;
+		double max = 0;
+		for (Metric m : results) {
+			counts[i++] = m.count;
+			max = Math.max(max, m.count);
+		}
+		final double dmax = max;
+		IChartData data = new AbstractChartData() {
+			private static final long serialVersionUID = 1L;
+
+			public double[][] getData() {
+				return new double[][] { counts };
+			}
+
+			public double getMax() {
+				return dmax;
+			}
+		};
+		return data;
+	}
+
+	protected String[] getNames(List<Metric> results) {
+		String[] names = new String[results.size()];
+		for (int i = 0; i < results.size(); i++) {
+			names[i] = results.get(i).name;
+		}
+		return names;
+	}
+
+	protected double maxValue(List<Metric> metrics) {
+		double max = Double.MIN_VALUE;
+		for (Metric m : metrics) {
+			if (m.count > max) {
+				max = m.count;
+			}
+		}
+		return max;
+	}
 }
diff --git a/src/com/gitblit/wicket/pages/TagPage.html b/src/com/gitblit/wicket/pages/TagPage.html
index ae2c99c..6041185 100644
--- a/src/com/gitblit/wicket/pages/TagPage.html
+++ b/src/com/gitblit/wicket/pages/TagPage.html
@@ -11,16 +11,14 @@
 	<div class="header" wicket:id="commit"></div>
 	
 	<!-- commit info -->
-	<div class="title_text">
-	<table class="object_header">
-		<tr><td>object</td><td><span wicket:id="tagId">Message goes here</span></td></tr>
-		<tr><td>author</td><td><span wicket:id="tagAuthor">Message goes here</span></td></tr>
-		<tr><td></td><td><span wicket:id="tagDate">Message goes here</span></td></tr>
+	<table>
+		<tr><th>object</th><td><span wicket:id="tagId">Message goes here</span></td></tr>
+		<tr><th>author</th><td><span wicket:id="tagAuthor">Message goes here</span></td></tr>
+		<tr><th></th><td><span wicket:id="tagDate">Message goes here</span></td></tr>
 	</table>
-	</div>
 	
 	<!--  full message -->
-	<div class="page_body" wicket:id="fullMessage"></div>
+	<div class="commit_message" wicket:id="fullMessage"></div>
 	
 	<!-- footer -->
 	<div wicket:id="pageFooter"></div>
diff --git a/src/com/gitblit/wicket/pages/TagsPage.html b/src/com/gitblit/wicket/pages/TagsPage.html
index 314eec7..a3f7d39 100644
--- a/src/com/gitblit/wicket/pages/TagsPage.html
+++ b/src/com/gitblit/wicket/pages/TagsPage.html
@@ -8,19 +8,15 @@
 	<div wicket:id="pageLinks"></div>
 
 	<!-- shortlog -->	
-	<div class="header" wicket:id="summary"></div>
-	
-	<table class="tags">
+	<div class="header" wicket:id="summary"></div>	
+	<table>
 		<tbody>
        		<tr wicket:id="tag">
-         		<td><i><span wicket:id="tagDate"></span></i></td>
-         		<td><div wicket:id="tagName"></div></td>
+         		<td class="date"><span wicket:id="tagDate"></span></td>
+         		<td><b><div wicket:id="tagName"></div></b></td>
          		<td><div wicket:id="tagDescription"></div></td>
          		<td><span wicket:id="tagLinks"></span></td>
        		</tr>
-       		<tr>   	
-				<td colspan="4"><div wicket:id="navigator"></div></td>	
-       		</tr>   		    	
     	</tbody>
 	</table>	
 	
diff --git a/src/com/gitblit/wicket/pages/TagsPage.java b/src/com/gitblit/wicket/pages/TagsPage.java
index 85c0455..012d712 100644
--- a/src/com/gitblit/wicket/pages/TagsPage.java
+++ b/src/com/gitblit/wicket/pages/TagsPage.java
@@ -4,14 +4,12 @@
 
 import org.apache.wicket.PageParameters;
 import org.apache.wicket.markup.html.basic.Label;
-import org.apache.wicket.markup.html.navigation.paging.PagingNavigator;
 import org.apache.wicket.markup.repeater.Item;
 import org.apache.wicket.markup.repeater.data.DataView;
 import org.apache.wicket.markup.repeater.data.ListDataProvider;
 import org.eclipse.jgit.lib.Repository;
 
 import com.gitblit.utils.JGitUtils;
-import com.gitblit.wicket.GitBlitWebApp;
 import com.gitblit.wicket.LinkPanel;
 import com.gitblit.wicket.RepositoryPage;
 import com.gitblit.wicket.models.RefModel;
@@ -54,9 +52,7 @@
 				counter++;
 			}
 		};
-		tagView.setItemsPerPage(GitBlitWebApp.PAGING_ITEM_COUNT);
 		add(tagView);
-		add(new PagingNavigator("navigator", tagView));
 
 		// footer
 		addFooter();
diff --git a/src/com/gitblit/wicket/pages/TreePage.html b/src/com/gitblit/wicket/pages/TreePage.html
index e01049c..197ac94 100644
--- a/src/com/gitblit/wicket/pages/TreePage.html
+++ b/src/com/gitblit/wicket/pages/TreePage.html
@@ -18,13 +18,12 @@
 	<!-- breadcrumbs -->
 	<div wicket:id="breadcrumbs"></div>
 		
-	<!-- changed paths -->
-	<div class="list_head"></div>
-	<table class="diff_tree">
+	<!-- changed paths -->	
+	<table class="pretty">
 		<tr wicket:id="changedPath">
-			<td class="mode"><span wicket:id="pathPermissions"></span></td>
-			<td class="size"><span wicket:id="pathSize"></span></td>
 			<td><span wicket:id="pathName"></span></td>			
+			<td class="size"><span wicket:id="pathSize"></span></td>
+			<td class="mode"><span wicket:id="pathPermissions"></span></td>
 			<td><span wicket:id="treeLinks"></span></td>
 		</tr>
 	</table>
diff --git a/src/com/gitblit/wicket/pages/TreePage.java b/src/com/gitblit/wicket/pages/TreePage.java
index a608bdd..cce18be 100644
--- a/src/com/gitblit/wicket/pages/TreePage.java
+++ b/src/com/gitblit/wicket/pages/TreePage.java
@@ -38,10 +38,8 @@
 		add(new LinkPanel("shortlog", "title", commit.getShortMessage(), CommitPage.class, newCommitParameter()));
 
 		// breadcrumbs
-		if (basePath == null || basePath.trim().length() == 0) {
-			add(new Label("breadcrumbs", "").setVisible(false));
-		} else {
-			add(new PathBreadcrumbsPanel("breadcrumbs", repositoryName, basePath, commitId));
+		add(new PathBreadcrumbsPanel("breadcrumbs", repositoryName, basePath, commitId));			
+		if (basePath != null && basePath.trim().length() > 0) {
 			paths.add(0, PathModel.getParentPath(basePath, commitId));
 		}
 
@@ -58,13 +56,13 @@
 				item.add(new Label("pathPermissions", JGitUtils.getPermissionsFromMode(entry.mode)));
 				if (entry.isParentPath) {
 					// parent .. path
-					item.add(new Label("pathSize", "").setVisible(false));
+					item.add(new Label("pathSize", ""));
 					item.add(new LinkPanel("pathName", null, entry.name, TreePage.class, newPathParameter(entry.path)));
-					item.add(new Label("treeLinks", "").setVisible(false));
+					item.add(new Label("treeLinks", ""));
 				} else {
 					if (entry.isTree()) {
 						// folder/tree link
-						item.add(new Label("pathSize", "-"));
+						item.add(new Label("pathSize", ""));
 						item.add(new LinkPanel("pathName", null, entry.name, TreePage.class, newPathParameter(entry.path)));
 					} else {
 						// blob link
diff --git a/src/com/gitblit/wicket/panels/HeadLinksPanel.html b/src/com/gitblit/wicket/panels/HeadLinksPanel.html
index 4849e8e..04c6659 100644
--- a/src/com/gitblit/wicket/panels/HeadLinksPanel.html
+++ b/src/com/gitblit/wicket/panels/HeadLinksPanel.html
@@ -2,7 +2,7 @@
 <html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd">
 <wicket:panel>
 	<div class="link">
-		<span wicket:id="shortlog"></span> | <span wicket:id="log"></span>  | <span wicket:id="tree"></span>
+		<span wicket:id="shortlog"></span> | <span wicket:id="tree"></span>
 	</div>	
 </wicket:panel>
 </html>
\ No newline at end of file
diff --git a/src/com/gitblit/wicket/panels/HeadLinksPanel.java b/src/com/gitblit/wicket/panels/HeadLinksPanel.java
index 4f4c9d7..eeb2ae4 100644
--- a/src/com/gitblit/wicket/panels/HeadLinksPanel.java
+++ b/src/com/gitblit/wicket/panels/HeadLinksPanel.java
@@ -6,7 +6,6 @@
 
 import com.gitblit.wicket.LinkPanel;
 import com.gitblit.wicket.models.RefModel;
-import com.gitblit.wicket.pages.LogPage;
 import com.gitblit.wicket.pages.ShortLogPage;
 
 
@@ -17,7 +16,6 @@
 	public HeadLinksPanel(String id, String repositoryName, RefModel tag) {
 		super(id);
 		add(new LinkPanel("shortlog", null, "shortlog", ShortLogPage.class, new PageParameters("p=" + repositoryName + ",h=" + tag.getName())));
-		add(new LinkPanel("log", null, "log", LogPage.class, new PageParameters("p=" + repositoryName + ",h=" + tag.getName())));
 		add(new Label("tree", "tree"));
 	}
 }
\ No newline at end of file
diff --git a/src/com/gitblit/wicket/panels/PageFooter.html b/src/com/gitblit/wicket/panels/PageFooter.html
index e2e708d..305b6bc 100644
--- a/src/com/gitblit/wicket/panels/PageFooter.html
+++ b/src/com/gitblit/wicket/panels/PageFooter.html
@@ -2,11 +2,10 @@
 <html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd">
 <wicket:panel>
 	<div class="page_footer">
-		<div class="cachetime"><span wicket:id="cacheTime"></span></div>
-		<div class="page_footer_text"><span wicket:id="footerText"></span></div>
-		<div class="page_footer_text" style="text-align:right">
+		<div style="float:right">
 			<a title="about git:blit" href="about">About Git:Blit</a>
 		</div>
+		<div wicket:id="footerText"></div>
 	</div>	
 </wicket:panel>
 </html>
\ No newline at end of file
diff --git a/src/com/gitblit/wicket/panels/PageFooter.java b/src/com/gitblit/wicket/panels/PageFooter.java
index 91a1f57..b727408 100644
--- a/src/com/gitblit/wicket/panels/PageFooter.java
+++ b/src/com/gitblit/wicket/panels/PageFooter.java
@@ -1,12 +1,9 @@
 package com.gitblit.wicket.panels;
 
-import java.util.Date;
-
 import org.apache.wicket.markup.html.basic.Label;
 import org.apache.wicket.markup.html.panel.Panel;
 
 import com.gitblit.StoredSettings;
-import com.gitblit.wicket.GitBlitWebSession;
 
 
 public class PageFooter extends Panel {
@@ -18,8 +15,7 @@
 	}
 
 	public PageFooter(String id, String description) {
-		super(id);
-		add(new Label("cacheTime", "Page Last Updated: " + GitBlitWebSession.get().formatDateTimeLong(new Date())));
+		super(id);		
 		add(new Label("footerText", description));
 		if (StoredSettings.getBoolean("aggressiveGC", false)) {
 			System.gc();
diff --git a/src/com/gitblit/wicket/panels/PageHeader.html b/src/com/gitblit/wicket/panels/PageHeader.html
index 83edb99..982a897 100644
--- a/src/com/gitblit/wicket/panels/PageHeader.html
+++ b/src/com/gitblit/wicket/panels/PageHeader.html
@@ -4,12 +4,11 @@
 	<head>
     	<title wicket:id="title">Message goes here</title>
     	<link rel="stylesheet" type="text/css" href="gitblit.css"/>
-    	<link rel="stylesheet" type="text/css" href="gitweb.css"/>
     	<link rel="shortcut icon" href="git-favicon.png" type="image/png" />
 	</head>
 	
 	<div class="page_header">
-		<a title="gitblit homepage" href="http://gitblit.com/"><img src="gitblt-logo.png" width="91" height="31" alt="gitblit" class="logo"/></a><a href="/"><span wicket:id="siteName">name</span></a> / <span wicket:id="repositoryName">name</span> <span wicket:id="pageName">name</span> 
+		<a title="gitblit homepage" href="http://gitblit.com/"><img src="gitblt_25.png" width="79" height="25" alt="gitblit" class="logo"/></a><a href="/"><span wicket:id="siteName">name</span></a> / <span wicket:id="repositoryName">name</span> <span wicket:id="pageName">name</span> 
 	</div>
 </wicket:panel>
 </html>
\ No newline at end of file
diff --git a/src/com/gitblit/wicket/panels/PageLinksPanel.html b/src/com/gitblit/wicket/panels/PageLinksPanel.html
index 66c3ce7..18e271e 100644
--- a/src/com/gitblit/wicket/panels/PageLinksPanel.html
+++ b/src/com/gitblit/wicket/panels/PageLinksPanel.html
@@ -3,7 +3,7 @@
 <wicket:panel>
 	<!-- page nav links -->	
 	<div class="page_nav">
-		<span wicket:id="summary"></span> | <span wicket:id="shortlog"></span> | <span wicket:id="log"></span> | <span wicket:id="commit"></span> | <span wicket:id="commitdiff"></span> | <span wicket:id="tree"></span>
+		<span wicket:id="summary"></span> | <span wicket:id="shortlog"></span> | <span wicket:id="commit"></span> | <span wicket:id="commitdiff"></span> | <span wicket:id="tree"></span>
 	</div>	
 </wicket:panel>
 </html>
\ No newline at end of file
diff --git a/src/com/gitblit/wicket/panels/PageLinksPanel.java b/src/com/gitblit/wicket/panels/PageLinksPanel.java
index f72b880..7447e76 100644
--- a/src/com/gitblit/wicket/panels/PageLinksPanel.java
+++ b/src/com/gitblit/wicket/panels/PageLinksPanel.java
@@ -6,7 +6,6 @@
 
 import com.gitblit.wicket.LinkPanel;
 import com.gitblit.wicket.pages.CommitPage;
-import com.gitblit.wicket.pages.LogPage;
 import com.gitblit.wicket.pages.ShortLogPage;
 import com.gitblit.wicket.pages.SummaryPage;
 import com.gitblit.wicket.pages.TreePage;
@@ -30,13 +29,6 @@
 			add(new Label("shortlog", pageName));
 		} else {
 			add(new LinkPanel("shortlog", null, "shortlog", ShortLogPage.class, new PageParameters("p=" + repositoryName)));
-		}
-
-		// log
-		if (pageName.equals("log")) {
-			add(new Label("log", pageName));
-		} else {
-			add(new LinkPanel("log", null, "log", LogPage.class, new PageParameters("p=" + repositoryName)));
 		}
 
 		// commit
diff --git a/src/com/gitblit/wicket/panels/PathBreadcrumbsPanel.java b/src/com/gitblit/wicket/panels/PathBreadcrumbsPanel.java
index 5ce356a..a8a5c28 100644
--- a/src/com/gitblit/wicket/panels/PathBreadcrumbsPanel.java
+++ b/src/com/gitblit/wicket/panels/PathBreadcrumbsPanel.java
@@ -14,7 +14,6 @@
 import com.gitblit.wicket.LinkPanel;
 import com.gitblit.wicket.pages.TreePage;
 
-
 public class PathBreadcrumbsPanel extends Panel {
 
 	private static final long serialVersionUID = 1L;
@@ -26,14 +25,16 @@
 		List<BreadCrumb> crumbs = new ArrayList<BreadCrumb>();
 		crumbs.add(new BreadCrumb("[" + repositoryName + "]", ROOT, false));
 
-		String[] paths = pathName.split("/");
-		StringBuilder sb = new StringBuilder();
-		
-		for (int i = 0; i < paths.length; i++) {
-			String path = paths[i];
-			sb.append(path);
-			crumbs.add(new BreadCrumb(path, sb.toString(), (i == (paths.length - 1))));
-			sb.append("/");
+		if (pathName != null && pathName.length() > 0) {
+			String[] paths = pathName.split("/");
+			StringBuilder sb = new StringBuilder();
+
+			for (int i = 0; i < paths.length; i++) {
+				String path = paths[i];
+				sb.append(path);
+				crumbs.add(new BreadCrumb(path, sb.toString(), (i == (paths.length - 1))));
+				sb.append("/");
+			}
 		}
 
 		ListDataProvider<BreadCrumb> crumbsDp = new ListDataProvider<BreadCrumb>(crumbs);
@@ -49,20 +50,20 @@
 				}
 
 				item.add(new LinkPanel("pathLink", null, entry.name, TreePage.class, new PageParameters(parameters)));
-				item.add(new Label("pathSeparator", entry.isLeaf ? "":"/"));
+				item.add(new Label("pathSeparator", entry.isLeaf ? "" : "/"));
 			}
 		};
 		add(pathsView);
 	}
 
 	private class BreadCrumb implements Serializable {
-		
+
 		private static final long serialVersionUID = 1L;
-		
+
 		final String name;
 		final String path;
 		final boolean isLeaf;
-		
+
 		BreadCrumb(String name, String path, boolean isLeaf) {
 			this.name = name;
 			this.path = path;
diff --git a/src/com/gitblit/wicket/panels/PathLinksPanel.java b/src/com/gitblit/wicket/panels/PathLinksPanel.java
index fa8bdca..c29124b 100644
--- a/src/com/gitblit/wicket/panels/PathLinksPanel.java
+++ b/src/com/gitblit/wicket/panels/PathLinksPanel.java
@@ -16,7 +16,7 @@
 	public PathLinksPanel(String id, String repositoryName, PathModel path) {
 		super(id);
 		add(new Label("diff", "diff"));
-		add(new LinkPanel("blob", null, "blob", BlobPage.class, new PageParameters("p=" + repositoryName + ",h=" + path.commitId + ",f=" + path.path)));
+		add(new LinkPanel("blob", null, "view", BlobPage.class, new PageParameters("p=" + repositoryName + ",h=" + path.commitId + ",f=" + path.path)));
 		add(new Label("history", "history"));
 	}
 }
\ No newline at end of file
diff --git a/src/com/gitblit/wicket/panels/TagLinksPanel.html b/src/com/gitblit/wicket/panels/TagLinksPanel.html
index 3093408..98191a3 100644
--- a/src/com/gitblit/wicket/panels/TagLinksPanel.html
+++ b/src/com/gitblit/wicket/panels/TagLinksPanel.html
@@ -2,7 +2,7 @@
 <html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd">
 <wicket:panel>
 	<div class="link">
-		<span wicket:id="commit"></span> | <span wicket:id="shortlog"></span> | <span wicket:id="log"></span>
+		<span wicket:id="commit"></span> | <span wicket:id="shortlog"></span>
 	</div>	
 </wicket:panel>
 </html>
\ No newline at end of file
diff --git a/src/com/gitblit/wicket/panels/TagLinksPanel.java b/src/com/gitblit/wicket/panels/TagLinksPanel.java
index 73a9c3a..8011716 100644
--- a/src/com/gitblit/wicket/panels/TagLinksPanel.java
+++ b/src/com/gitblit/wicket/panels/TagLinksPanel.java
@@ -6,7 +6,6 @@
 import com.gitblit.wicket.LinkPanel;
 import com.gitblit.wicket.models.RefModel;
 import com.gitblit.wicket.pages.CommitPage;
-import com.gitblit.wicket.pages.LogPage;
 import com.gitblit.wicket.pages.ShortLogPage;
 
 
@@ -18,6 +17,5 @@
 		super(id);
 		add(new LinkPanel("commit", null, "commit", CommitPage.class, new PageParameters("p=" + repositoryName + ",h=" + tag.getCommitId().getName())));
 		add(new LinkPanel("shortlog", null, "shortlog", ShortLogPage.class, new PageParameters("p=" + repositoryName + ",h=" + tag.getName())));
-		add(new LinkPanel("log", null, "log", LogPage.class, new PageParameters("p=" + repositoryName + ",h=" + tag.getName())));
 	}
 }
\ No newline at end of file
diff --git a/src/com/gitblit/wicket/panels/TreeLinksPanel.java b/src/com/gitblit/wicket/panels/TreeLinksPanel.java
index 21da66c..ce918b9 100644
--- a/src/com/gitblit/wicket/panels/TreeLinksPanel.java
+++ b/src/com/gitblit/wicket/panels/TreeLinksPanel.java
@@ -19,11 +19,11 @@
 		if (path.isTree()) {
 			add(new LinkPanel("link", null, "tree", TreePage.class, new PageParameters("p=" + repositoryName + ",h=" + path.commitId + ",f=" + path.path)));
 			add(new Label("history", "history"));
-			add(new Label("raw", "").setVisible(false));
+			add(new Label("raw", ""));
 		} else {
-			add(new LinkPanel("link", null, "blob", BlobPage.class, new PageParameters("p=" + repositoryName + ",h=" + path.commitId + ",f=" + path.path)));
+			add(new LinkPanel("link", null, "view", BlobPage.class, new PageParameters("p=" + repositoryName + ",h=" + path.commitId + ",f=" + path.path)));
 			add(new Label("history", "history"));
-			add(new Label("raw", "raw"));
+			add(new Label("raw", "download"));
 		}
 	}
 }
\ No newline at end of file

--
Gitblit v1.9.1