/*
 * Copyright 2014 gitblit.com.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.gitblit.wicket.pages;

import java.text.DateFormat;
import java.text.MessageFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TimeZone;
import java.util.TreeSet;

import javax.servlet.http.HttpServletRequest;

import org.apache.wicket.AttributeModifier;
import org.apache.wicket.Component;
import org.apache.wicket.MarkupContainer;
import org.apache.wicket.PageParameters;
import org.apache.wicket.RestartResponseException;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.behavior.SimpleAttributeModifier;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.image.ContextImage;
import org.apache.wicket.markup.html.link.BookmarkablePageLink;
import org.apache.wicket.markup.html.link.ExternalLink;
import org.apache.wicket.markup.html.list.ListItem;
import org.apache.wicket.markup.html.list.ListView;
import org.apache.wicket.markup.html.panel.Fragment;
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.apache.wicket.model.Model;
import org.apache.wicket.protocol.http.WebRequest;
import org.eclipse.jgit.diff.DiffEntry.ChangeType;
import org.eclipse.jgit.lib.PersonIdent;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;

import com.gitblit.Constants;
import com.gitblit.Constants.AccessPermission;
import com.gitblit.Constants.AuthorizationControl;
import com.gitblit.Keys;
import com.gitblit.git.PatchsetCommand;
import com.gitblit.git.PatchsetReceivePack;
import com.gitblit.models.PathModel.PathChangeModel;
import com.gitblit.models.RegistrantAccessPermission;
import com.gitblit.models.RepositoryModel;
import com.gitblit.models.RepositoryUrl;
import com.gitblit.models.SubmoduleModel;
import com.gitblit.models.TicketModel;
import com.gitblit.models.TicketModel.Change;
import com.gitblit.models.TicketModel.CommentSource;
import com.gitblit.models.TicketModel.Field;
import com.gitblit.models.TicketModel.Patchset;
import com.gitblit.models.TicketModel.PatchsetType;
import com.gitblit.models.TicketModel.Review;
import com.gitblit.models.TicketModel.Score;
import com.gitblit.models.TicketModel.Status;
import com.gitblit.models.UserModel;
import com.gitblit.tickets.TicketIndexer.Lucene;
import com.gitblit.tickets.TicketLabel;
import com.gitblit.tickets.TicketMilestone;
import com.gitblit.tickets.TicketResponsible;
import com.gitblit.utils.ArrayUtils;
import com.gitblit.utils.JGitUtils;
import com.gitblit.utils.JGitUtils.MergeStatus;
import com.gitblit.utils.MarkdownUtils;
import com.gitblit.utils.StringUtils;
import com.gitblit.utils.TimeUtils;
import com.gitblit.wicket.GitBlitWebSession;
import com.gitblit.wicket.TicketsUI;
import com.gitblit.wicket.WicketUtils;
import com.gitblit.wicket.panels.BasePanel.JavascriptTextPrompt;
import com.gitblit.wicket.panels.CommentPanel;
import com.gitblit.wicket.panels.DiffStatPanel;
import com.gitblit.wicket.panels.GravatarImage;
import com.gitblit.wicket.panels.IconAjaxLink;
import com.gitblit.wicket.panels.LinkPanel;
import com.gitblit.wicket.panels.ShockWaveComponent;
import com.gitblit.wicket.panels.SimpleAjaxLink;

/**
 * The ticket page handles viewing and updating a ticket.
 *
 * @author James Moger
 *
 */
public class TicketPage extends RepositoryPage {

	static final String NIL = "<nil>";

	static final String ESC_NIL = StringUtils.escapeForHtml(NIL,  false);

	final int avatarWidth = 40;

	final TicketModel ticket;

	public TicketPage(PageParameters params) {
		super(params);

		final UserModel user = GitBlitWebSession.get().getUser() == null ? UserModel.ANONYMOUS : GitBlitWebSession.get().getUser();
		final RepositoryModel repository = getRepositoryModel();
		final String id = WicketUtils.getObject(params);
		long ticketId = Long.parseLong(id);
		ticket = app().tickets().getTicket(repository, ticketId);

		if (ticket == null) {
			// ticket not found
			throw new RestartResponseException(TicketsPage.class, WicketUtils.newRepositoryParameter(repositoryName));
		}

		final List<Change> revisions = new ArrayList<Change>();
		List<Change> comments = new ArrayList<Change>();
		List<Change> statusChanges = new ArrayList<Change>();
		List<Change> discussion = new ArrayList<Change>();
		for (Change change : ticket.changes) {
			if (change.hasComment() || (change.isStatusChange() && (change.getStatus() != Status.New))) {
				discussion.add(change);
			}
			if (change.hasComment()) {
				comments.add(change);
			}
			if (change.hasPatchset()) {
				revisions.add(change);
			}
			if (change.isStatusChange() && !change.hasPatchset()) {
				statusChanges.add(change);
			}
		}

		final Change currentRevision = revisions.isEmpty() ? null : revisions.get(revisions.size() - 1);
		final Patchset currentPatchset = ticket.getCurrentPatchset();

		/*
		 * TICKET HEADER
		 */
		String href = urlFor(TicketsPage.class, params).toString();
		add(new ExternalLink("ticketNumber", href, "#" + ticket.number));
		Label headerStatus = new Label("headerStatus", ticket.status.toString());
		WicketUtils.setCssClass(headerStatus, TicketsUI.getLozengeClass(ticket.status, false));
		add(headerStatus);
		add(new Label("ticketTitle", ticket.title));
		if (currentPatchset == null) {
			add(new Label("diffstat").setVisible(false));
		} else {
			// calculate the current diffstat of the patchset
			add(new DiffStatPanel("diffstat", ticket.insertions, ticket.deletions));
		}


		/*
		 * TAB TITLES
		 */
		add(new Label("commentCount", "" + comments.size()).setVisible(!comments.isEmpty()));
		add(new Label("commitCount", "" + (currentPatchset == null ? 0 : currentPatchset.commits)).setVisible(currentPatchset != null));


		/*
		 * TICKET AUTHOR and DATE (DISCUSSION TAB)
		 */
		UserModel createdBy = app().users().getUserModel(ticket.createdBy);
		if (createdBy == null) {
			add(new Label("whoCreated", ticket.createdBy));
		} else {
			add(new LinkPanel("whoCreated", null, createdBy.getDisplayName(),
					UserPage.class, WicketUtils.newUsernameParameter(createdBy.username)));
		}

		if (ticket.isProposal()) {
			// clearly indicate this is a change ticket
			add(new Label("creationMessage", getString("gb.proposedThisChange")));
		} else {
			// standard ticket
			add(new Label("creationMessage", getString("gb.createdThisTicket")));
		}

		String dateFormat = app().settings().getString(Keys.web.datestampLongFormat, "EEEE, MMMM d, yyyy");
		String timestampFormat = app().settings().getString(Keys.web.datetimestampLongFormat, "EEEE, MMMM d, yyyy");
		final TimeZone timezone = getTimeZone();
		final DateFormat df = new SimpleDateFormat(dateFormat);
		df.setTimeZone(timezone);
		final DateFormat tsf = new SimpleDateFormat(timestampFormat);
		tsf.setTimeZone(timezone);
		final Calendar cal = Calendar.getInstance(timezone);

		String fuzzydate;
		TimeUtils tu = getTimeUtils();
		Date createdDate = ticket.created;
		if (TimeUtils.isToday(createdDate, timezone)) {
			fuzzydate = tu.today();
		} else if (TimeUtils.isYesterday(createdDate, timezone)) {
			fuzzydate = tu.yesterday();
		} else {
			// calculate a fuzzy time ago date
        	cal.setTime(createdDate);
        	cal.set(Calendar.HOUR_OF_DAY, 0);
        	cal.set(Calendar.MINUTE, 0);
        	cal.set(Calendar.SECOND, 0);
        	cal.set(Calendar.MILLISECOND, 0);
        	createdDate = cal.getTime();
			fuzzydate = getTimeUtils().timeAgo(createdDate);
		}
		Label when = new Label("whenCreated", fuzzydate + ", " + df.format(createdDate));
		WicketUtils.setHtmlTooltip(when, tsf.format(ticket.created));
		add(when);

		String exportHref = urlFor(ExportTicketPage.class, params).toString();
		add(new ExternalLink("exportJson", exportHref, "json"));


		/*
		 * RESPONSIBLE (DISCUSSION TAB)
		 */
		if (StringUtils.isEmpty(ticket.responsible)) {
			add(new Label("responsible"));
		} else {
			UserModel responsible = app().users().getUserModel(ticket.responsible);
			if (responsible == null) {
				add(new Label("responsible", ticket.responsible));
			} else {
				add(new LinkPanel("responsible", null, responsible.getDisplayName(),
						UserPage.class, WicketUtils.newUsernameParameter(responsible.username)));
			}
		}

		/*
		 * MILESTONE PROGRESS (DISCUSSION TAB)
		 */
		if (StringUtils.isEmpty(ticket.milestone)) {
			add(new Label("milestone"));
		} else {
			// link to milestone query
			TicketMilestone tm = app().tickets().getMilestone(repository, ticket.milestone);
			if (tm == null) {
				tm = new TicketMilestone(ticket.milestone);
			}
			PageParameters milestoneParameters;
			if (tm.isOpen()) {
				milestoneParameters = WicketUtils.newOpenTicketsParameter(repositoryName);
			} else {
				milestoneParameters = WicketUtils.newRepositoryParameter(repositoryName);
			}
			milestoneParameters.put(Lucene.milestone.name(), ticket.milestone);
			int progress = 0;
			int open = 0;
			int closed = 0;
			if (tm != null) {
				progress = tm.getProgress();
				open = tm.getOpenTickets();
				closed = tm.getClosedTickets();
			}

			Fragment milestoneProgress = new Fragment("milestone", "milestoneProgressFragment", this);
			milestoneProgress.add(new LinkPanel("link", null, ticket.milestone, TicketsPage.class, milestoneParameters));
			Label label = new Label("progress");
			WicketUtils.setCssStyle(label, "width:" + progress + "%;");
			milestoneProgress.add(label);
			WicketUtils.setHtmlTooltip(milestoneProgress, MessageFormat.format(getString("gb.milestoneProgress"), open, closed));
			add(milestoneProgress);
		}


		/*
		 * TICKET DESCRIPTION (DISCUSSION TAB)
		 */
		String desc;
		if (StringUtils.isEmpty(ticket.body)) {
			desc = getString("gb.noDescriptionGiven");
		} else {
			String bugtraq = bugtraqProcessor().processText(getRepository(), repositoryName, ticket.body);
			String html = MarkdownUtils.transformGFM(app().settings(), bugtraq, ticket.repository);
			String safeHtml = app().xssFilter().relaxed(html);
			desc = safeHtml;
		}
		add(new Label("ticketDescription", desc).setEscapeModelStrings(false));

		/*
		 * DEPENDENCY
		 */
		List<String> dependencies = ticket.getDependencies();
		add(new ListView<String>("dependencies", dependencies) {
			@Override
			protected void populateItem(ListItem<String> item) {
				String ticketId= item.getModelObject();
				PageParameters tp = WicketUtils.newObjectParameter(ticket.repository, ticketId);
				item.add(new LinkPanel("dependencyLink", "list subject", "#"+ticketId, TicketsPage.class, tp));
			}
		});

		/*
		 * PARTICIPANTS (DISCUSSION TAB)
		 */
		if (app().settings().getBoolean(Keys.web.allowGravatar, true)) {
			// gravatar allowed
			List<String> participants = ticket.getParticipants();
			add(new Label("participantsLabel", MessageFormat.format(getString(participants.size() > 1 ? "gb.nParticipants" : "gb.oneParticipant"),
					"<b>" + participants.size() + "</b>")).setEscapeModelStrings(false));
			ListDataProvider<String> participantsDp = new ListDataProvider<String>(participants);
			DataView<String> participantsView = new DataView<String>("participants", participantsDp) {
				private static final long serialVersionUID = 1L;

				@Override
				public void populateItem(final Item<String> item) {
					String username = item.getModelObject();
					UserModel user = app().users().getUserModel(username);
					if (user == null) {
						user = new UserModel(username);
					}
					item.add(new GravatarImage("participant", user.getDisplayName(),
							user.emailAddress, null, 25, true));
				}
			};
			add(participantsView);
		} else {
			// gravatar prohibited
			add(new Label("participantsLabel").setVisible(false));
			add(new Label("participants").setVisible(false));
		}


		/*
		 * LARGE STATUS INDICATOR WITH ICON (DISCUSSION TAB->SIDE BAR)
		 */
		Fragment ticketStatus = new Fragment("ticketStatus", "ticketStatusFragment", this);
		Label ticketIcon = TicketsUI.getStateIcon("ticketIcon", ticket);
		ticketStatus.add(ticketIcon);
		ticketStatus.add(new Label("ticketStatus", ticket.status.toString()));
		WicketUtils.setCssClass(ticketStatus, TicketsUI.getLozengeClass(ticket.status, false));
		add(ticketStatus);


		/*
		 * UPDATE FORM (DISCUSSION TAB)
		 */
		if (user.canEdit(ticket, repository) && app().tickets().isAcceptingTicketUpdates(repository)) {
			if (user.canAdmin(ticket, repository) && ticket.isOpen()) {
				/*
				 * OPEN TICKET
				 */
				Fragment controls = new Fragment("controls", "openControlsFragment", this);

				/*
				 * STATUS
				 */
				List<Status> choices = new ArrayList<Status>();
				if (ticket.isProposal()) {
					choices.addAll(Arrays.asList(TicketModel.Status.proposalWorkflow));
				} else if (ticket.isBug()) {
					choices.addAll(Arrays.asList(TicketModel.Status.bugWorkflow));
				} else {
					choices.addAll(Arrays.asList(TicketModel.Status.requestWorkflow));
				}
				choices.remove(ticket.status);

				ListDataProvider<Status> workflowDp = new ListDataProvider<Status>(choices);
				DataView<Status> statusView = new DataView<Status>("newStatus", workflowDp) {
					private static final long serialVersionUID = 1L;

					@Override
					public void populateItem(final Item<Status> item) {
						SimpleAjaxLink<Status> link = new SimpleAjaxLink<Status>("link", item.getModel()) {

							private static final long serialVersionUID = 1L;

							@Override
							public void onClick(AjaxRequestTarget target) {
								Status status = getModel().getObject();
								Change change = new Change(user.username);
								change.setField(Field.status, status);
								if (!ticket.isWatching(user.username)) {
									change.watch(user.username);
								}
								TicketModel update = app().tickets().updateTicket(repository, ticket.number, change);
								app().tickets().createNotifier().sendMailing(update);
								setResponsePage(TicketsPage.class, getPageParameters());
							}
						};
						String css = TicketsUI.getStatusClass(item.getModel().getObject());
						WicketUtils.setCssClass(link, css);
						item.add(link);
					}
				};
				controls.add(statusView);

				/*
				 * RESPONSIBLE LIST
				 */
				Set<String> userlist = new TreeSet<String>(ticket.getParticipants());
				if (UserModel.ANONYMOUS.canPush(getRepositoryModel())
						|| AuthorizationControl.AUTHENTICATED == getRepositoryModel().authorizationControl) {
					// 	authorization is ANONYMOUS or AUTHENTICATED (i.e. all users can be set responsible)
					userlist.addAll(app().users().getAllUsernames());
				} else {
					// authorization is by NAMED users (users with PUSH permission can be set responsible)
					for (RegistrantAccessPermission rp : app().repositories().getUserAccessPermissions(getRepositoryModel())) {
						if (rp.permission.atLeast(AccessPermission.PUSH)) {
							userlist.add(rp.registrant);
						}
					}
				}
				List<TicketResponsible> responsibles = new ArrayList<TicketResponsible>();
				if (!StringUtils.isEmpty(ticket.responsible)) {
					// exclude the current responsible
					userlist.remove(ticket.responsible);
				}
				for (String username : userlist) {
					UserModel u = app().users().getUserModel(username);
					if (u != null) {
						responsibles.add(new TicketResponsible(u));
					}
				}
				Collections.sort(responsibles);
				responsibles.add(new TicketResponsible(ESC_NIL, "", ""));
				ListDataProvider<TicketResponsible> responsibleDp = new ListDataProvider<TicketResponsible>(responsibles);
				DataView<TicketResponsible> responsibleView = new DataView<TicketResponsible>("newResponsible", responsibleDp) {
					private static final long serialVersionUID = 1L;

					@Override
					public void populateItem(final Item<TicketResponsible> item) {
						SimpleAjaxLink<TicketResponsible> link = new SimpleAjaxLink<TicketResponsible>("link", item.getModel()) {

							private static final long serialVersionUID = 1L;

							@Override
							public void onClick(AjaxRequestTarget target) {
								TicketResponsible responsible = getModel().getObject();
								Change change = new Change(user.username);
								change.setField(Field.responsible, responsible.username);
								if (!StringUtils.isEmpty(responsible.username)) {
									if (!ticket.isWatching(responsible.username)) {
										change.watch(responsible.username);
									}
								}
								if (!ticket.isWatching(user.username)) {
									change.watch(user.username);
								}
								TicketModel update = app().tickets().updateTicket(repository, ticket.number, change);
								app().tickets().createNotifier().sendMailing(update);
								setResponsePage(TicketsPage.class, getPageParameters());
							}
						};
						item.add(link);
					}
				};
				controls.add(responsibleView);

				/*
				 * MILESTONE LIST
				 */
				List<TicketMilestone> milestones = app().tickets().getMilestones(repository, Status.Open);
				if (!StringUtils.isEmpty(ticket.milestone)) {
					for (TicketMilestone milestone : milestones) {
						if (milestone.name.equals(ticket.milestone)) {
							milestones.remove(milestone);
							break;
						}
					}
				}
				milestones.add(new TicketMilestone(ESC_NIL));
				ListDataProvider<TicketMilestone> milestoneDp = new ListDataProvider<TicketMilestone>(milestones);
				DataView<TicketMilestone> milestoneView = new DataView<TicketMilestone>("newMilestone", milestoneDp) {
					private static final long serialVersionUID = 1L;

					@Override
					public void populateItem(final Item<TicketMilestone> item) {
						SimpleAjaxLink<TicketMilestone> link = new SimpleAjaxLink<TicketMilestone>("link", item.getModel()) {

							private static final long serialVersionUID = 1L;

							@Override
							public void onClick(AjaxRequestTarget target) {
								TicketMilestone milestone = getModel().getObject();
								Change change = new Change(user.username);
								if (NIL.equals(milestone.name) || ESC_NIL.equals(milestone.name)) {
									change.setField(Field.milestone, "");
								} else {
									change.setField(Field.milestone, milestone.name);
								}
								if (!ticket.isWatching(user.username)) {
									change.watch(user.username);
								}
								TicketModel update = app().tickets().updateTicket(repository, ticket.number, change);
								app().tickets().createNotifier().sendMailing(update);
								setResponsePage(TicketsPage.class, getPageParameters());
							}
						};
						item.add(link);
					}
				};
				controls.add(milestoneView);

				String editHref = urlFor(EditTicketPage.class, params).toString();
				controls.add(new ExternalLink("editLink", editHref, getString("gb.edit")));

				add(controls);
			} else {
				/*
				 * CLOSED TICKET
				 */
				Fragment controls = new Fragment("controls", "closedControlsFragment", this);

				String editHref = urlFor(EditTicketPage.class, params).toString();
				controls.add(new ExternalLink("editLink", editHref, getString("gb.edit")));

				add(controls);
			}
		} else {
			add(new Label("controls").setVisible(false));
		}


		/*
		 * TICKET METADATA
		 */
		add(new Label("ticketType", ticket.type.toString()));

		add(new Label("priority", ticket.priority.toString()));
		add(new Label("severity", ticket.severity.toString()));

		if (StringUtils.isEmpty(ticket.topic)) {
			add(new Label("ticketTopic").setVisible(false));
		} else {
			// process the topic using the bugtraq config to link things
			String topic = bugtraqProcessor().processText(getRepository(), repositoryName, ticket.topic);
			String safeTopic = app().xssFilter().relaxed(topic);
			add(new Label("ticketTopic", safeTopic).setEscapeModelStrings(false));
		}




		/*
		 * VOTERS
		 */
		List<String> voters = ticket.getVoters();
		Label votersCount = new Label("votes", "" + voters.size());
		if (voters.size() == 0) {
			WicketUtils.setCssClass(votersCount, "badge");
		} else {
			WicketUtils.setCssClass(votersCount, "badge badge-info");
		}
		add(votersCount);
		if (user.isAuthenticated && app().tickets().isAcceptingTicketUpdates(repository)) {
			Model<String> model;
			if (ticket.isVoter(user.username)) {
				model = Model.of(getString("gb.removeVote"));
			} else {
				model = Model.of(MessageFormat.format(getString("gb.vote"), ticket.type.toString()));
			}
			SimpleAjaxLink<String> link = new SimpleAjaxLink<String>("voteLink", model) {

				private static final long serialVersionUID = 1L;

				@Override
				public void onClick(AjaxRequestTarget target) {
					Change change = new Change(user.username);
					if (ticket.isVoter(user.username)) {
						change.unvote(user.username);
					} else {
						change.vote(user.username);
					}
					app().tickets().updateTicket(repository, ticket.number, change);
					setResponsePage(TicketsPage.class, getPageParameters());
				}
			};
			add(link);
		} else {
			add(new Label("voteLink").setVisible(false));
		}


		/*
		 * WATCHERS
		 */
		List<String> watchers = ticket.getWatchers();
		Label watchersCount = new Label("watchers", "" + watchers.size());
		if (watchers.size() == 0) {
			WicketUtils.setCssClass(watchersCount, "badge");
		} else {
			WicketUtils.setCssClass(watchersCount, "badge badge-info");
		}
		add(watchersCount);
		if (user.isAuthenticated && app().tickets().isAcceptingTicketUpdates(repository)) {
			Model<String> model;
			if (ticket.isWatching(user.username)) {
				model = Model.of(getString("gb.stopWatching"));
			} else {
				model = Model.of(MessageFormat.format(getString("gb.watch"), ticket.type.toString()));
			}
			SimpleAjaxLink<String> link = new SimpleAjaxLink<String>("watchLink", model) {

				private static final long serialVersionUID = 1L;

				@Override
				public void onClick(AjaxRequestTarget target) {
					Change change = new Change(user.username);
					if (ticket.isWatching(user.username)) {
						change.unwatch(user.username);
					} else {
						change.watch(user.username);
					}
					app().tickets().updateTicket(repository, ticket.number, change);
					setResponsePage(TicketsPage.class, getPageParameters());
				}
			};
			add(link);
		} else {
			add(new Label("watchLink").setVisible(false));
		}


		/*
		 * TOPIC & LABELS (DISCUSSION TAB->SIDE BAR)
		 */
		ListDataProvider<String> labelsDp = new ListDataProvider<String>(ticket.getLabels());
		DataView<String> labelsView = new DataView<String>("labels", labelsDp) {
			private static final long serialVersionUID = 1L;

			@Override
			public void populateItem(final Item<String> item) {
				final String value = item.getModelObject();
				Label label = new Label("label", value);
				TicketLabel tLabel = app().tickets().getLabel(repository, value);
				String background = MessageFormat.format("background-color:{0};", tLabel.color);
				label.add(new SimpleAttributeModifier("style", background));
				item.add(label);
			}
		};

		add(labelsView);


		/*
		 * COMMENTS & STATUS CHANGES (DISCUSSION TAB)
		 */
		if (comments.size() == 0) {
			add(new Label("discussion").setVisible(false));
		} else {
			Fragment discussionFragment = new Fragment("discussion", "discussionFragment", this);
			ListDataProvider<Change> discussionDp = new ListDataProvider<Change>(discussion);
			DataView<Change> discussionView = new DataView<Change>("discussion", discussionDp) {
				private static final long serialVersionUID = 1L;

				@Override
				public void populateItem(final Item<Change> item) {
					final Change entry = item.getModelObject();
					if (entry.isMerge()) {
						/*
						 * MERGE
						 */
						String resolvedBy = entry.getString(Field.mergeSha);

						// identify the merged patch, it is likely the last
						Patchset mergedPatch = null;
						for (Change c : revisions) {
							if (c.patchset.tip.equals(resolvedBy)) {
								mergedPatch = c.patchset;
								break;
							}
						}

						String commitLink;
						if (mergedPatch == null) {
							// shouldn't happen, but just-in-case
							int len = app().settings().getInteger(Keys.web.shortCommitIdLength, 6);
							commitLink = resolvedBy.substring(0, len);
						} else {
							// expected result
							commitLink = mergedPatch.toString();
						}

						Fragment mergeFragment = new Fragment("entry", "mergeFragment", this);
						mergeFragment.add(new LinkPanel("commitLink", null, commitLink,
								CommitPage.class, WicketUtils.newObjectParameter(repositoryName, resolvedBy)));
						mergeFragment.add(new Label("toBranch", MessageFormat.format(getString("gb.toBranch"),
								"<b>" + ticket.mergeTo + "</b>")).setEscapeModelStrings(false));
						addUserAttributions(mergeFragment, entry, 0);
						addDateAttributions(mergeFragment, entry);

						item.add(mergeFragment);
					} else if (entry.isStatusChange()) {
						/*
						 *  STATUS CHANGE
						 */
						Fragment frag = new Fragment("entry", "statusFragment", this);
						Label status = new Label("statusChange", entry.getStatus().toString());
						String css = TicketsUI.getLozengeClass(entry.getStatus(), false);
						WicketUtils.setCssClass(status, css);
						frag.add(status);
						addUserAttributions(frag, entry, avatarWidth);
						addDateAttributions(frag, entry);
						item.add(frag);
					} else {
						/*
						 * COMMENT
						 */
						String bugtraq = bugtraqProcessor().processText(getRepository(), repositoryName, entry.comment.text);
						String comment = MarkdownUtils.transformGFM(app().settings(), bugtraq, repositoryName);
						String safeComment = app().xssFilter().relaxed(comment);
						Fragment frag = new Fragment("entry", "commentFragment", this);
						Label commentIcon = new Label("commentIcon");
						if (entry.comment.src == CommentSource.Email) {
							WicketUtils.setCssClass(commentIcon, "iconic-mail");
						} else {
							WicketUtils.setCssClass(commentIcon, "iconic-comment-alt2-stroke");
						}
						frag.add(commentIcon);
						frag.add(new Label("comment", safeComment).setEscapeModelStrings(false));
						addUserAttributions(frag, entry, avatarWidth);
						addDateAttributions(frag, entry);
						item.add(frag);
					}
				}
			};
			discussionFragment.add(discussionView);
			add(discussionFragment);
		}

		/*
		 * ADD COMMENT PANEL
		 */
		if (UserModel.ANONYMOUS.equals(user)
				|| !repository.isBare
				|| repository.isFrozen
				|| repository.isMirror) {

			// prohibit comments for anonymous users, local working copy repos,
			// frozen repos, and mirrors
			add(new Label("newComment").setVisible(false));
		} else {
			// permit user to comment
			Fragment newComment = new Fragment("newComment", "newCommentFragment", this);
			GravatarImage img = new GravatarImage("newCommentAvatar", user.username, user.emailAddress,
					"gravatar-round", avatarWidth, true);
			newComment.add(img);
			CommentPanel commentPanel = new CommentPanel("commentPanel", user, ticket, null, TicketsPage.class);
			commentPanel.setRepository(repositoryName);
			newComment.add(commentPanel);
			add(newComment);
		}


		/*
		 *  PATCHSET TAB
		 */
		if (currentPatchset == null) {
			// no patchset available
			RepositoryUrl repoUrl = getRepositoryUrl(user, repository);
			boolean canPropose = repoUrl != null && repoUrl.permission.atLeast(AccessPermission.CLONE) && !UserModel.ANONYMOUS.equals(user);
			if (ticket.isOpen() && app().tickets().isAcceptingNewPatchsets(repository) && canPropose) {
				// ticket & repo will accept a proposal patchset
				// show the instructions for proposing a patchset
				Fragment changeIdFrag = new Fragment("patchset", "proposeFragment", this);
				changeIdFrag.add(new Label("proposeInstructions", MarkdownUtils.transformMarkdown(getString("gb.proposeInstructions"))).setEscapeModelStrings(false));
				changeIdFrag.add(new Label("ptWorkflow", MessageFormat.format(getString("gb.proposeWith"), "Barnum")));
				changeIdFrag.add(new Label("ptWorkflowSteps", getProposeWorkflow("propose_pt.md", repoUrl.url, ticket.number)).setEscapeModelStrings(false));
				changeIdFrag.add(new Label("gitWorkflow", MessageFormat.format(getString("gb.proposeWith"), "Git")));
				changeIdFrag.add(new Label("gitWorkflowSteps", getProposeWorkflow("propose_git.md", repoUrl.url, ticket.number)).setEscapeModelStrings(false));
				add(changeIdFrag);
			} else {
				// explain why you can't propose a patchset
				Fragment fragment = new Fragment("patchset", "canNotProposeFragment", this);
				String reason = "";
				if (ticket.isClosed()) {
					reason = getString("gb.ticketIsClosed");
				} else if (repository.isMirror) {
					reason = getString("gb.repositoryIsMirror");
				} else if (repository.isFrozen) {
					reason = getString("gb.repositoryIsFrozen");
				} else if (!repository.acceptNewPatchsets) {
					reason = getString("gb.repositoryDoesNotAcceptPatchsets");
				} else if (!canPropose) {
					if (UserModel.ANONYMOUS.equals(user)) {
						reason = getString("gb.anonymousCanNotPropose");
					} else {
						reason = getString("gb.youDoNotHaveClonePermission");
					}
				} else {
					reason = getString("gb.serverDoesNotAcceptPatchsets");
				}
				fragment.add(new Label("reason", reason));
				add(fragment);
			}
		} else {
			// show current patchset
			Fragment patchsetFrag = new Fragment("patchset", "patchsetFragment", this);
			patchsetFrag.add(new Label("commitsInPatchset", MessageFormat.format(getString("gb.commitsInPatchsetN"), currentPatchset.number)));

			patchsetFrag.add(createMergePanel(user, repository));

			if (ticket.isOpen()) {
				// current revision
				MarkupContainer panel = createPatchsetPanel("panel", repository, user);
				patchsetFrag.add(panel);
				addUserAttributions(patchsetFrag, currentRevision, avatarWidth);
				addUserAttributions(panel, currentRevision, 0);
				addDateAttributions(panel, currentRevision);
			} else {
				// current revision
				patchsetFrag.add(new Label("panel").setVisible(false));
			}

			// commits
			List<RevCommit> commits = JGitUtils.getRevLog(getRepository(), currentPatchset.base, currentPatchset.tip);
			ListDataProvider<RevCommit> commitsDp = new ListDataProvider<RevCommit>(commits);
			DataView<RevCommit> commitsView = new DataView<RevCommit>("commit", commitsDp) {
				private static final long serialVersionUID = 1L;

				@Override
				public void populateItem(final Item<RevCommit> item) {
					RevCommit commit = item.getModelObject();
					PersonIdent author = commit.getAuthorIdent();
					item.add(new GravatarImage("authorAvatar", author.getName(), author.getEmailAddress(), null, 16, false));
					item.add(new Label("author", commit.getAuthorIdent().getName()));
					item.add(new LinkPanel("commitId", null, getShortObjectId(commit.getName()),
							CommitPage.class, WicketUtils.newObjectParameter(repositoryName, commit.getName()), true));
					item.add(new LinkPanel("diff", "link", getString("gb.diff"), CommitDiffPage.class,
							WicketUtils.newObjectParameter(repositoryName, commit.getName()), true));
					item.add(new Label("title", StringUtils.trimString(commit.getShortMessage(), Constants.LEN_SHORTLOG_REFS)));
					item.add(WicketUtils.createDateLabel("commitDate", JGitUtils.getCommitDate(commit), GitBlitWebSession
							.get().getTimezone(), getTimeUtils(), false));
					item.add(new DiffStatPanel("commitDiffStat", 0, 0, true));
				}
			};
			patchsetFrag.add(commitsView);
			add(patchsetFrag);
		}


		/*
		 * ACTIVITY TAB
		 */
		Fragment revisionHistory = new Fragment("activity", "activityFragment", this);
		List<Change> events = new ArrayList<Change>(ticket.changes);
		Collections.sort(events);
		Collections.reverse(events);
		ListDataProvider<Change> eventsDp = new ListDataProvider<Change>(events);
		DataView<Change> eventsView = new DataView<Change>("event", eventsDp) {
			private static final long serialVersionUID = 1L;

			@Override
			public void populateItem(final Item<Change> item) {
				Change event = item.getModelObject();

				addUserAttributions(item, event, 16);

				if (event.hasPatchset()) {
					// patchset
					Patchset patchset = event.patchset;
					String what;
					if (event.isStatusChange() && (Status.New == event.getStatus())) {
						what = getString("gb.proposedThisChange");
					} else if (patchset.rev == 1) {
						what = MessageFormat.format(getString("gb.uploadedPatchsetN"), patchset.number);
					} else {
						if (patchset.added == 1) {
							what = getString("gb.addedOneCommit");
						} else {
							what = MessageFormat.format(getString("gb.addedNCommits"), patchset.added);
						}
					}
					item.add(new Label("what", what));

					LinkPanel psr = new LinkPanel("patchsetRevision", null, patchset.number + "-" + patchset.rev,
							ComparePage.class, WicketUtils.newRangeParameter(repositoryName, patchset.parent == null ? patchset.base : patchset.parent, patchset.tip), true);
					WicketUtils.setHtmlTooltip(psr, patchset.toString());
					item.add(psr);
					String typeCss = getPatchsetTypeCss(patchset.type);
					Label typeLabel = new Label("patchsetType", patchset.type.toString());
					if (typeCss == null) {
						typeLabel.setVisible(false);
					} else {
						WicketUtils.setCssClass(typeLabel, typeCss);
					}
					item.add(typeLabel);

					// show commit diffstat
					item.add(new DiffStatPanel("patchsetDiffStat", patchset.insertions, patchset.deletions, patchset.rev > 1));
				} else if (event.hasComment()) {
					// comment
					item.add(new Label("what", getString("gb.commented")));
					item.add(new Label("patchsetRevision").setVisible(false));
					item.add(new Label("patchsetType").setVisible(false));
					item.add(new Label("patchsetDiffStat").setVisible(false));
				} else if (event.hasReview()) {
					// review
					String score;
					switch (event.review.score) {
					case approved:
						score = "<span style='color:darkGreen'>" + getScoreDescription(event.review.score) + "</span>";
						break;
					case vetoed:
						score = "<span style='color:darkRed'>" + getScoreDescription(event.review.score) + "</span>";
						break;
					default:
						score = getScoreDescription(event.review.score);
					}
					item.add(new Label("what", MessageFormat.format(getString("gb.reviewedPatchsetRev"),
							event.review.patchset, event.review.rev, score))
							.setEscapeModelStrings(false));
					item.add(new Label("patchsetRevision").setVisible(false));
					item.add(new Label("patchsetType").setVisible(false));
					item.add(new Label("patchsetDiffStat").setVisible(false));
				} else {
					// field change
					item.add(new Label("patchsetRevision").setVisible(false));
					item.add(new Label("patchsetType").setVisible(false));
					item.add(new Label("patchsetDiffStat").setVisible(false));

					String what = "";
					if (event.isStatusChange()) {
					switch (event.getStatus()) {
					case New:
						if (ticket.isProposal()) {
							what = getString("gb.proposedThisChange");
						} else {
							what = getString("gb.createdThisTicket");
						}
						break;
					default:
						break;
					}
					}
					item.add(new Label("what", what).setVisible(what.length() > 0));
				}

				addDateAttributions(item, event);

				if (event.hasFieldChanges()) {
					StringBuilder sb = new StringBuilder();
					sb.append("<table class=\"summary\"><tbody>");
					for (Map.Entry<Field, String> entry : event.fields.entrySet()) {
						String value;
						switch (entry.getKey()) {
							case body:
								String body = entry.getValue();
								if (event.isStatusChange() && Status.New == event.getStatus() && StringUtils.isEmpty(body)) {
									// ignore initial empty description
									continue;
								}
								// trim body changes
								if (StringUtils.isEmpty(body)) {
									value = "<i>" + ESC_NIL + "</i>";
								} else {
									value = StringUtils.trimString(body, Constants.LEN_SHORTLOG_REFS);
								}
								break;
							case status:
								// special handling for status
								Status status = event.getStatus();
								String css = TicketsUI.getLozengeClass(status, true);
								value = String.format("<span class=\"%1$s\">%2$s</span>", css, status.toString());
								break;
							default:
								value = StringUtils.isEmpty(entry.getValue()) ? ("<i>" + ESC_NIL + "</i>") : StringUtils.escapeForHtml(entry.getValue(), false);
								break;
						}
						sb.append("<tr><th style=\"width:70px;\">");
						try {
							sb.append(getString("gb." + entry.getKey().name()));
						} catch (Exception e) {
							sb.append(entry.getKey().name());
						}
						sb.append("</th><td>");
						sb.append(value);
						sb.append("</td></tr>");
					}
					sb.append("</tbody></table>");
					String safeHtml = app().xssFilter().relaxed(sb.toString());
					item.add(new Label("fields", safeHtml).setEscapeModelStrings(false));
				} else {
					item.add(new Label("fields").setVisible(false));
				}
			}
		};
		revisionHistory.add(eventsView);
		add(revisionHistory);
	}

	protected void addUserAttributions(MarkupContainer container, Change entry, int avatarSize) {
		UserModel commenter = app().users().getUserModel(entry.author);
		if (commenter == null) {
			// unknown user
			container.add(new GravatarImage("changeAvatar", entry.author,
					entry.author, null, avatarSize, false).setVisible(avatarSize > 0));
			container.add(new Label("changeAuthor", entry.author.toLowerCase()));
		} else {
			// known user
			container.add(new GravatarImage("changeAvatar", commenter.getDisplayName(),
					commenter.emailAddress, avatarSize > 24 ? "gravatar-round" : null,
							avatarSize, true).setVisible(avatarSize > 0));
			container.add(new LinkPanel("changeAuthor", null, commenter.getDisplayName(),
					UserPage.class, WicketUtils.newUsernameParameter(commenter.username)));
		}
	}

	protected void addDateAttributions(MarkupContainer container, Change entry) {
		container.add(WicketUtils.createDateLabel("changeDate", entry.date, GitBlitWebSession
				.get().getTimezone(), getTimeUtils(), false));

		// set the id attribute
		if (entry.hasComment()) {
			container.setOutputMarkupId(true);
			container.add(new AttributeModifier("id", Model.of(entry.getId())));
			ExternalLink link = new ExternalLink("changeLink", "#" + entry.getId());
			container.add(link);
		} else {
			container.add(new Label("changeLink").setVisible(false));
		}
	}

	protected String getProposeWorkflow(String resource, String url, long ticketId) {
		String md = readResource(resource);
		md = md.replace("${url}", url);
		md = md.replace("${repo}", StringUtils.getLastPathElement(StringUtils.stripDotGit(repositoryName)));
		md = md.replace("${ticketId}", "" + ticketId);
		md = md.replace("${patchset}", "" + 1);
		md = md.replace("${reviewBranch}", Repository.shortenRefName(PatchsetCommand.getTicketBranch(ticketId)));
		String integrationBranch = Repository.shortenRefName(getRepositoryModel().mergeTo);
		if (!StringUtils.isEmpty(ticket.mergeTo)) {
			integrationBranch = ticket.mergeTo;
		}
		md = md.replace("${integrationBranch}", integrationBranch);
		return MarkdownUtils.transformMarkdown(md);
	}

	protected Fragment createPatchsetPanel(String wicketId, RepositoryModel repository, UserModel user) {
		final Patchset currentPatchset = ticket.getCurrentPatchset();
		List<Patchset> patchsets = new ArrayList<Patchset>(ticket.getPatchsetRevisions(currentPatchset.number));
		patchsets.remove(currentPatchset);
		Collections.reverse(patchsets);

		Fragment panel = new Fragment(wicketId, "collapsiblePatchsetFragment", this);

		// patchset header
		String ps = "<b>" + currentPatchset.number + "</b>";
		if (currentPatchset.rev == 1) {
			panel.add(new Label("uploadedWhat", MessageFormat.format(getString("gb.uploadedPatchsetN"), ps)).setEscapeModelStrings(false));
		} else {
			String rev = "<b>" + currentPatchset.rev + "</b>";
			panel.add(new Label("uploadedWhat", MessageFormat.format(getString("gb.uploadedPatchsetNRevisionN"), ps, rev)).setEscapeModelStrings(false));
		}
		panel.add(new LinkPanel("patchId", null, "rev " + currentPatchset.rev,
				CommitPage.class, WicketUtils.newObjectParameter(repositoryName, currentPatchset.tip), true));

		// compare menu
		panel.add(new LinkPanel("compareMergeBase", null, getString("gb.compareToMergeBase"),
				ComparePage.class, WicketUtils.newRangeParameter(repositoryName, currentPatchset.base, currentPatchset.tip), true));

		ListDataProvider<Patchset> compareMenuDp = new ListDataProvider<Patchset>(patchsets);
		DataView<Patchset> compareMenu = new DataView<Patchset>("comparePatch", compareMenuDp) {
			private static final long serialVersionUID = 1L;
			@Override
			public void populateItem(final Item<Patchset> item) {
				Patchset patchset = item.getModelObject();
				LinkPanel link = new LinkPanel("compareLink", null,
						MessageFormat.format(getString("gb.compareToN"), patchset.number + "-" + patchset.rev),
						ComparePage.class, WicketUtils.newRangeParameter(getRepositoryModel().name,
								patchset.tip, currentPatchset.tip), true);
				item.add(link);

			}
		};
		panel.add(compareMenu);


		// reviews
		List<Change> reviews = ticket.getReviews(currentPatchset);
		ListDataProvider<Change> reviewsDp = new ListDataProvider<Change>(reviews);
		DataView<Change> reviewsView = new DataView<Change>("reviews", reviewsDp) {
			private static final long serialVersionUID = 1L;

			@Override
			public void populateItem(final Item<Change> item) {
				Change change = item.getModelObject();
				final String username = change.author;
				UserModel user = app().users().getUserModel(username);
				if (user == null) {
					item.add(new Label("reviewer", username));
				} else {
					item.add(new LinkPanel("reviewer", null, user.getDisplayName(),
							UserPage.class, WicketUtils.newUsernameParameter(username)));
				}

				// indicate review score
				Review review = change.review;
				Label scoreLabel = new Label("score");
				String scoreClass = getScoreClass(review.score);
				String tooltip = getScoreDescription(review.score);
				WicketUtils.setCssClass(scoreLabel, scoreClass);
				if (!StringUtils.isEmpty(tooltip)) {
					WicketUtils.setHtmlTooltip(scoreLabel, tooltip);
				}
				item.add(scoreLabel);
			}
		};
		panel.add(reviewsView);


		if (ticket.isOpen() && user.canReviewPatchset(repository) && app().tickets().isAcceptingTicketUpdates(repository)) {
			// can only review open tickets
			Review myReview = null;
			for (Change change : ticket.getReviews(currentPatchset)) {
				if (change.author.equals(user.username)) {
					myReview = change.review;
				}
			}

			// user can review, add review controls
			Fragment reviewControls = new Fragment("reviewControls", "reviewControlsFragment", this);

			// show "approve" button if no review OR not current score
			if (user.canApprovePatchset(repository) && (myReview == null || Score.approved != myReview.score)) {
				reviewControls.add(createReviewLink("approveLink", Score.approved));
			} else {
				reviewControls.add(new Label("approveLink").setVisible(false));
			}

			// show "looks good" button if no review OR not current score
			if (myReview == null || Score.looks_good != myReview.score) {
				reviewControls.add(createReviewLink("looksGoodLink", Score.looks_good));
			} else {
				reviewControls.add(new Label("looksGoodLink").setVisible(false));
			}

			// show "needs improvement" button if no review OR not current score
			if (myReview == null || Score.needs_improvement != myReview.score) {
				reviewControls.add(createReviewLink("needsImprovementLink", Score.needs_improvement));
			} else {
				reviewControls.add(new Label("needsImprovementLink").setVisible(false));
			}

			// show "veto" button if no review OR not current score
			if (user.canVetoPatchset(repository) && (myReview == null || Score.vetoed != myReview.score)) {
				reviewControls.add(createReviewLink("vetoLink", Score.vetoed));
			} else {
				reviewControls.add(new Label("vetoLink").setVisible(false));
			}
			panel.add(reviewControls);
		} else {
			// user can not review
			panel.add(new Label("reviewControls").setVisible(false));
		}

		String insertions = MessageFormat.format("<span style=\"color:darkGreen;font-weight:bold;\">+{0}</span>", ticket.insertions);
		String deletions = MessageFormat.format("<span style=\"color:darkRed;font-weight:bold;\">-{0}</span>", ticket.deletions);
		panel.add(new Label("patchsetStat", MessageFormat.format(StringUtils.escapeForHtml(getString("gb.diffStat"), false),
				insertions, deletions)).setEscapeModelStrings(false));

		// changed paths list
		List<PathChangeModel> paths = JGitUtils.getFilesInRange(getRepository(), currentPatchset.base, currentPatchset.tip);
		ListDataProvider<PathChangeModel> pathsDp = new ListDataProvider<PathChangeModel>(paths);
		DataView<PathChangeModel> pathsView = new DataView<PathChangeModel>("changedPath", pathsDp) {
			private static final long serialVersionUID = 1L;
			int counter;

			@Override
			public void populateItem(final Item<PathChangeModel> item) {
				final PathChangeModel entry = item.getModelObject();
				Label changeType = new Label("changeType", "");
				WicketUtils.setChangeTypeCssClass(changeType, entry.changeType);
				setChangeTypeTooltip(changeType, entry.changeType);
				item.add(changeType);

				boolean hasSubmodule = false;
				String submodulePath = null;
				if (entry.isTree()) {
					// tree
					item.add(new LinkPanel("pathName", null, entry.path, TreePage.class,
							WicketUtils
									.newPathParameter(repositoryName, currentPatchset.tip, entry.path), true));
					item.add(new Label("diffStat").setVisible(false));
				} else if (entry.isSubmodule()) {
					// submodule
					String submoduleId = entry.objectId;
					SubmoduleModel submodule = getSubmodule(entry.path);
					submodulePath = submodule.gitblitPath;
					hasSubmodule = submodule.hasSubmodule;

					item.add(new LinkPanel("pathName", "list", entry.path + " @ " +
							getShortObjectId(submoduleId), TreePage.class,
							WicketUtils.newPathParameter(submodulePath, submoduleId, ""), true).setEnabled(hasSubmodule));
					item.add(new Label("diffStat").setVisible(false));
				} else {
					// blob
					String displayPath = entry.path;
					String path = entry.path;
					if (entry.isSymlink()) {
						RevCommit commit = JGitUtils.getCommit(getRepository(), PatchsetCommand.getTicketBranch(ticket.number));
						path = JGitUtils.getStringContent(getRepository(), commit.getTree(), path);
						displayPath = entry.path + " -> " + path;
					}

					if (entry.changeType.equals(ChangeType.ADD)) {
						// add show view
						item.add(new LinkPanel("pathName", "list", displayPath, BlobPage.class,
								WicketUtils.newPathParameter(repositoryName, currentPatchset.tip, path), true));
					} else if (entry.changeType.equals(ChangeType.DELETE)) {
						// delete, show label
						item.add(new Label("pathName", displayPath));
					} else {
						// mod, show diff
						item.add(new LinkPanel("pathName", "list", displayPath, BlobDiffPage.class,
								WicketUtils.newPathParameter(repositoryName, currentPatchset.tip, path), true));
					}
					item.add(new DiffStatPanel("diffStat", entry.insertions, entry.deletions, true));
				}

				// quick links
				if (entry.isSubmodule()) {
					// submodule
					item.add(setNewTarget(new BookmarkablePageLink<Void>("diff", BlobDiffPage.class, WicketUtils
							.newPathParameter(repositoryName, entry.commitId, entry.path)))
							.setEnabled(!entry.changeType.equals(ChangeType.ADD)));
					item.add(new BookmarkablePageLink<Void>("view", CommitPage.class, WicketUtils
							.newObjectParameter(submodulePath, entry.objectId)).setEnabled(hasSubmodule));
				} else {
					// tree or blob
					item.add(setNewTarget(new BookmarkablePageLink<Void>("diff", BlobDiffPage.class, WicketUtils
							.newBlobDiffParameter(repositoryName, currentPatchset.base, currentPatchset.tip, entry.path)))
							.setEnabled(!entry.changeType.equals(ChangeType.ADD)
									&& !entry.changeType.equals(ChangeType.DELETE)));
					item.add(setNewTarget(new BookmarkablePageLink<Void>("view", BlobPage.class, WicketUtils
							.newPathParameter(repositoryName, currentPatchset.tip, entry.path)))
							.setEnabled(!entry.changeType.equals(ChangeType.DELETE)));
				}

				WicketUtils.setAlternatingBackground(item, counter);
				counter++;
			}
		};
		panel.add(pathsView);

		addPtCheckoutInstructions(user, repository, panel);
		addGitCheckoutInstructions(user, repository, panel);

		return panel;
	}

	protected IconAjaxLink<String> createReviewLink(String wicketId, final Score score) {
		return new IconAjaxLink<String>(wicketId, getScoreClass(score), Model.of(getScoreDescription(score))) {

			private static final long serialVersionUID = 1L;

			@Override
			public void onClick(AjaxRequestTarget target) {
				review(score);
			}
		};
	}

	protected String getScoreClass(Score score) {
		switch (score) {
		case vetoed:
			return "fa fa-exclamation-circle";
		case needs_improvement:
			return "fa fa-thumbs-o-down";
		case looks_good:
			return "fa fa-thumbs-o-up";
		case approved:
			return "fa fa-check-circle";
		case not_reviewed:
		default:
			return "fa fa-minus-circle";
		}
	}

	protected String getScoreDescription(Score score) {
		String description;
		switch (score) {
		case vetoed:
			description = getString("gb.veto");
			break;
		case needs_improvement:
			description = getString("gb.needsImprovement");
			break;
		case looks_good:
			description = getString("gb.looksGood");
			break;
		case approved:
			description = getString("gb.approve");
			break;
		case not_reviewed:
		default:
			description = getString("gb.hasNotReviewed");
		}
		return String.format("%1$s (%2$+d)", description, score.getValue());
	}

	protected void review(Score score) {
		UserModel user = GitBlitWebSession.get().getUser();
		Patchset ps = ticket.getCurrentPatchset();
		Change change = new Change(user.username);
		change.review(ps, score, !ticket.isReviewer(user.username));
		if (!ticket.isWatching(user.username)) {
			change.watch(user.username);
		}
		TicketModel updatedTicket = app().tickets().updateTicket(getRepositoryModel(), ticket.number, change);
		app().tickets().createNotifier().sendMailing(updatedTicket);
		setResponsePage(TicketsPage.class, getPageParameters());
	}

	protected <X extends MarkupContainer> X setNewTarget(X x) {
		x.add(new SimpleAttributeModifier("target", "_blank"));
		return x;
	}

	protected void addGitCheckoutInstructions(UserModel user, RepositoryModel repository, MarkupContainer panel) {
		panel.add(new Label("gitStep1", MessageFormat.format(getString("gb.stepN"), 1)));
		panel.add(new Label("gitStep2", MessageFormat.format(getString("gb.stepN"), 2)));

		String ticketBranch  = Repository.shortenRefName(PatchsetCommand.getTicketBranch(ticket.number));

		String step1 = "git fetch origin";
		String step2 = MessageFormat.format("git checkout {0} && git pull --ff-only\nOR\ngit checkout {0} && git reset --hard origin/{0}", ticketBranch);

		panel.add(new Label("gitPreStep1", step1));
		panel.add(new Label("gitPreStep2", step2));

		panel.add(createCopyFragment("gitCopyStep1", step1.replace("\n", " && ")));
		panel.add(createCopyFragment("gitCopyStep2", step2.replace("\n", " && ")));
	}

	protected void addPtCheckoutInstructions(UserModel user, RepositoryModel repository, MarkupContainer panel) {
		String step1 = MessageFormat.format("pt checkout {0,number,0}", ticket.number);
		panel.add(new Label("ptPreStep", step1));
		panel.add(createCopyFragment("ptCopyStep", step1));
	}

	/**
	 * Adds a merge panel for the patchset to the markup container.  The panel
	 * may just a message if the patchset can not be merged.
	 *
	 * @param c
	 * @param user
	 * @param repository
	 */
	protected Component createMergePanel(UserModel user, RepositoryModel repository) {
		Patchset patchset = ticket.getCurrentPatchset();
		if (patchset == null) {
			// no patchset to merge
			return new Label("mergePanel");
		}

		boolean allowMerge;
		if (repository.requireApproval) {
			// rpeository requires approval
			allowMerge = ticket.isOpen() && ticket.isApproved(patchset);
		} else {
			// vetos are binding
			allowMerge = ticket.isOpen() && !ticket.isVetoed(patchset);
		}

		MergeStatus mergeStatus = JGitUtils.canMerge(getRepository(), patchset.tip, ticket.mergeTo);
		if (allowMerge) {
			if (MergeStatus.MERGEABLE == mergeStatus) {
				// patchset can be cleanly merged to integration branch OR has already been merged
				Fragment mergePanel = new Fragment("mergePanel", "mergeableFragment", this);
				mergePanel.add(new Label("mergeTitle", MessageFormat.format(getString("gb.patchsetMergeable"), ticket.mergeTo)));
				if (user.canPush(repository)) {
					// user can merge locally
					SimpleAjaxLink<String> mergeButton = new SimpleAjaxLink<String>("mergeButton", Model.of(getString("gb.merge"))) {

						private static final long serialVersionUID = 1L;

						@Override
						public void onClick(AjaxRequestTarget target) {

							// ensure the patchset is still current AND not vetoed
							Patchset patchset = ticket.getCurrentPatchset();
							final TicketModel refreshedTicket = app().tickets().getTicket(getRepositoryModel(), ticket.number);
							if (patchset.equals(refreshedTicket.getCurrentPatchset())) {
								// patchset is current, check for recent veto
								if (!refreshedTicket.isVetoed(patchset)) {
									// patchset is not vetoed

									// execute the merge using the ticket service
									app().tickets().exec(new Runnable() {
										@Override
										public void run() {
											PatchsetReceivePack rp = new PatchsetReceivePack(
													app().gitblit(),
													getRepository(),
													getRepositoryModel(),
													GitBlitWebSession.get().getUser());
											MergeStatus result = rp.merge(refreshedTicket);
											if (MergeStatus.MERGED == result) {
												// notify participants and watchers
												rp.sendAll();
											} else {
												// merge failure
												String msg = MessageFormat.format("Failed to merge ticket {0,number,0}: {1}", ticket.number, result.name());
												logger.error(msg);
												GitBlitWebSession.get().cacheErrorMessage(msg);
											}
										}
									});
								} else {
									// vetoed patchset
									String msg = MessageFormat.format("Can not merge ticket {0,number,0}, patchset {1,number,0} has been vetoed!",
											ticket.number, patchset.number);
									GitBlitWebSession.get().cacheErrorMessage(msg);
									logger.error(msg);
								}
							} else {
								// not current patchset
								String msg = MessageFormat.format("Can not merge ticket {0,number,0}, the patchset has been updated!", ticket.number);
								GitBlitWebSession.get().cacheErrorMessage(msg);
								logger.error(msg);
							}

							setResponsePage(TicketsPage.class, getPageParameters());
						}
					};
					mergePanel.add(mergeButton);
					Component instructions = getMergeInstructions(user, repository, "mergeMore", "gb.patchsetMergeableMore");
					mergePanel.add(instructions);
				} else {
					mergePanel.add(new Label("mergeButton").setVisible(false));
					mergePanel.add(new Label("mergeMore").setVisible(false));
				}
				return mergePanel;
			} else if (MergeStatus.ALREADY_MERGED == mergeStatus) {
				// patchset already merged
				Fragment mergePanel = new Fragment("mergePanel", "alreadyMergedFragment", this);
				mergePanel.add(new Label("mergeTitle", MessageFormat.format(getString("gb.patchsetAlreadyMerged"), ticket.mergeTo)));
				return mergePanel;
			} else if (MergeStatus.MISSING_INTEGRATION_BRANCH == mergeStatus) {
				// target/integration branch is missing
				Fragment mergePanel = new Fragment("mergePanel", "notMergeableFragment", this);
				mergePanel.add(new Label("mergeTitle", MessageFormat.format(getString("gb.patchsetNotMergeable"), ticket.mergeTo)));
				mergePanel.add(new Label("mergeMore", MessageFormat.format(getString("gb.missingIntegrationBranchMore"), ticket.mergeTo)));
				return mergePanel;
			} else {
				// patchset can not be cleanly merged
				Fragment mergePanel = new Fragment("mergePanel", "notMergeableFragment", this);
				mergePanel.add(new Label("mergeTitle", MessageFormat.format(getString("gb.patchsetNotMergeable"), ticket.mergeTo)));
				if (user.canPush(repository)) {
					// user can merge locally
					Component instructions = getMergeInstructions(user, repository, "mergeMore", "gb.patchsetNotMergeableMore");
					mergePanel.add(instructions);
				} else {
					mergePanel.add(new Label("mergeMore").setVisible(false));
				}
				return mergePanel;
			}
		} else {
			// merge not allowed
			if (MergeStatus.ALREADY_MERGED == mergeStatus) {
				// patchset already merged
				Fragment mergePanel = new Fragment("mergePanel", "alreadyMergedFragment", this);
				mergePanel.add(new Label("mergeTitle", MessageFormat.format(getString("gb.patchsetAlreadyMerged"), ticket.mergeTo)));
				return mergePanel;
			} else if (ticket.isVetoed(patchset)) {
				// patchset has been vetoed
				Fragment mergePanel =  new Fragment("mergePanel", "vetoedFragment", this);
				mergePanel.add(new Label("mergeTitle", MessageFormat.format(getString("gb.patchsetNotMergeable"), ticket.mergeTo)));
				return mergePanel;
			} else if (repository.requireApproval) {
				// patchset has been not been approved for merge
				Fragment mergePanel = new Fragment("mergePanel", "notApprovedFragment", this);
				mergePanel.add(new Label("mergeTitle", MessageFormat.format(getString("gb.patchsetNotApproved"), ticket.mergeTo)));
				mergePanel.add(new Label("mergeMore", MessageFormat.format(getString("gb.patchsetNotApprovedMore"), ticket.mergeTo)));
				return mergePanel;
			} else {
				// other case
				return new Label("mergePanel");
			}
		}
	}

	protected Component getMergeInstructions(UserModel user, RepositoryModel repository, String markupId, String infoKey) {
		Fragment cmd = new Fragment(markupId, "commandlineMergeFragment", this);
		cmd.add(new Label("instructions", MessageFormat.format(getString(infoKey), ticket.mergeTo)));

		// git instructions
		cmd.add(new Label("mergeStep1", MessageFormat.format(getString("gb.stepN"), 1)));
		cmd.add(new Label("mergeStep2", MessageFormat.format(getString("gb.stepN"), 2)));
		cmd.add(new Label("mergeStep3", MessageFormat.format(getString("gb.stepN"), 3)));

		String ticketBranch = Repository.shortenRefName(PatchsetCommand.getTicketBranch(ticket.number));
		String reviewBranch = PatchsetCommand.getReviewBranch(ticket.number);

		String step1 = MessageFormat.format("git checkout -b {0} {1}", reviewBranch, ticket.mergeTo);
		String step2 = MessageFormat.format("git pull origin {0}", ticketBranch);
		String step3 = MessageFormat.format("git checkout {0}\ngit merge {1}\ngit push origin {0}\ngit branch -d {1}", ticket.mergeTo, reviewBranch);

		cmd.add(new Label("mergePreStep1", step1));
		cmd.add(new Label("mergePreStep2", step2));
		cmd.add(new Label("mergePreStep3", step3));

		cmd.add(createCopyFragment("mergeCopyStep1", step1.replace("\n", " && ")));
		cmd.add(createCopyFragment("mergeCopyStep2", step2.replace("\n", " && ")));
		cmd.add(createCopyFragment("mergeCopyStep3", step3.replace("\n", " && ")));

		// pt instructions
		String ptStep = MessageFormat.format("pt pull {0,number,0}", ticket.number);
		cmd.add(new Label("ptMergeStep", ptStep));
		cmd.add(createCopyFragment("ptMergeCopyStep", step1.replace("\n", " && ")));
		return cmd;
	}

	/**
	 * Returns the primary repository url
	 *
	 * @param user
	 * @param repository
	 * @return the primary repository url
	 */
	protected RepositoryUrl getRepositoryUrl(UserModel user, RepositoryModel repository) {
		HttpServletRequest req = ((WebRequest) getRequest()).getHttpServletRequest();
		List<RepositoryUrl> urls = app().services().getRepositoryUrls(req, user, repository);
		if (ArrayUtils.isEmpty(urls)) {
			return null;
		}
		RepositoryUrl primary = urls.get(0);
		return primary;
	}

	/**
	 * Returns the ticket (if any) that this commit references.
	 *
	 * @param commit
	 * @return null or a ticket
	 */
	protected TicketModel getTicket(RevCommit commit) {
		try {
			Map<String, Ref> refs = getRepository().getRefDatabase().getRefs(Constants.R_TICKETS_PATCHSETS);
			for (Map.Entry<String, Ref> entry : refs.entrySet()) {
				if (entry.getValue().getObjectId().equals(commit.getId())) {
					long id = PatchsetCommand.getTicketNumber(entry.getKey());
					TicketModel ticket = app().tickets().getTicket(getRepositoryModel(), id);
					return ticket;
				}
			}
		} catch (Exception e) {
			logger().error("failed to determine ticket from ref", e);
		}
		return null;
	}

	protected String getPatchsetTypeCss(PatchsetType type) {
		String typeCss;
		switch (type) {
			case Rebase:
			case Rebase_Squash:
				typeCss = TicketsUI.getLozengeClass(Status.Declined, false);
				break;
			case Squash:
			case Amend:
				typeCss = TicketsUI.getLozengeClass(Status.On_Hold, false);
				break;
			case Proposal:
				typeCss = TicketsUI.getLozengeClass(Status.New, false);
				break;
			case FastForward:
			default:
				typeCss = null;
			break;
		}
		return typeCss;
	}

	@Override
	protected String getPageName() {
		return getString("gb.ticket");
	}

	@Override
	protected Class<? extends BasePage> getRepoNavPageClass() {
		return TicketsPage.class;
	}

	@Override
	protected String getPageTitle(String repositoryName) {
		return "#" + ticket.number + " - " + ticket.title;
	}

	protected Fragment createCopyFragment(String wicketId, String text) {
		if (app().settings().getBoolean(Keys.web.allowFlashCopyToClipboard, true)) {
			// clippy: flash-based copy & paste
			Fragment copyFragment = new Fragment(wicketId, "clippyPanel", this);
			String baseUrl = WicketUtils.getGitblitURL(getRequest());
			ShockWaveComponent clippy = new ShockWaveComponent("clippy", baseUrl + "/clippy.swf");
			clippy.setValue("flashVars", "text=" + StringUtils.encodeURL(text));
			copyFragment.add(clippy);
			return copyFragment;
		} else {
			// javascript: manual copy & paste with modal browser prompt dialog
			Fragment copyFragment = new Fragment(wicketId, "jsPanel", this);
			ContextImage img = WicketUtils.newImage("copyIcon", "clippy.png");
			img.add(new JavascriptTextPrompt("onclick", "Copy to Clipboard (Ctrl+C, Enter)", text));
			copyFragment.add(img);
			return copyFragment;
		}
	}
}
