diff --git a/src/main/java/com/gitblit/LuceneExecutor.java b/src/main/java/com/gitblit/LuceneExecutor.java
index 0e4baae..3446289 100644
--- a/src/main/java/com/gitblit/LuceneExecutor.java
+++ b/src/main/java/com/gitblit/LuceneExecutor.java
@@ -56,7 +56,6 @@
 import org.apache.lucene.search.IndexSearcher;
 import org.apache.lucene.search.Query;
 import org.apache.lucene.search.ScoreDoc;
-import org.apache.lucene.search.TermQuery;
 import org.apache.lucene.search.TopScoreDocCollector;
 import org.apache.lucene.search.highlight.Fragmenter;
 import org.apache.lucene.search.highlight.Highlighter;
@@ -86,14 +85,11 @@
 import org.slf4j.LoggerFactory;
 
 import com.gitblit.Constants.SearchObjectType;
-import com.gitblit.models.IssueModel;
-import com.gitblit.models.IssueModel.Attachment;
 import com.gitblit.models.PathModel.PathChangeModel;
 import com.gitblit.models.RefModel;
 import com.gitblit.models.RepositoryModel;
 import com.gitblit.models.SearchResult;
 import com.gitblit.utils.ArrayUtils;
-import com.gitblit.utils.IssueUtils;
 import com.gitblit.utils.JGitUtils;
 import com.gitblit.utils.StringUtils;
 
@@ -109,7 +105,6 @@
 	private static final int INDEX_VERSION = 5;
 
 	private static final String FIELD_OBJECT_TYPE = "type";
-	private static final String FIELD_ISSUE = "issue";
 	private static final String FIELD_PATH = "path";
 	private static final String FIELD_COMMIT = "commit";
 	private static final String FIELD_BRANCH = "branch";
@@ -120,7 +115,6 @@
 	private static final String FIELD_DATE = "date";
 	private static final String FIELD_TAG = "tag";
 	private static final String FIELD_LABEL = "label";
-	private static final String FIELD_ATTACHMENT = "attachment";
 
 	private static final String CONF_FILE = "lucene.conf";
 	private static final String LUCENE_DIR = "lucene";
@@ -475,9 +469,8 @@
 						&& branch.equals(defaultBranch)) {
 					// indexing "default" branch
 					indexBranch = true;
-				} else if (IssueUtils.GB_ISSUES.equals(branch)) {
-					// skip the GB_ISSUES branch because it is indexed later
-					// note: this is different than updateIndex
+				} else if (branch.getName().startsWith(com.gitblit.Constants.R_GITBLIT)) {
+					// skip Gitblit internal branches
 					indexBranch = false;
 				} else {
 					// normal explicit branch check
@@ -617,19 +610,6 @@
 			// finished
 			reader.release();
 			
-			// this repository has a gb-issues branch, index all issues
-			if (IssueUtils.getIssuesBranch(repository) != null) {
-				List<IssueModel> issues = IssueUtils.getIssues(repository, null);
-				if (issues.size() > 0) {
-					result.branchCount += 1;
-				}
-				for (IssueModel issue : issues) {
-					result.issueCount++;
-					Document doc = createDocument(issue);
-					writer.addDocument(doc);
-				}
-			}
-
 			// commit all changes and reset the searcher
 			config.setInt(CONF_INDEX, null, CONF_VERSION, INDEX_VERSION);
 			config.save();
@@ -723,55 +703,6 @@
 	}
 
 	/**
-	 * Incrementally update the index with the specified issue for the
-	 * repository.
-	 * 
-	 * @param repositoryName
-	 * @param issue
-	 * @return true, if successful
-	 */
-	public boolean index(String repositoryName, IssueModel issue) {
-		try {
-			// delete the old issue from the index, if exists
-			deleteIssue(repositoryName, issue.id);
-			Document doc = createDocument(issue);
-			return index(repositoryName, doc);
-		} catch (Exception e) {
-			logger.error(MessageFormat.format("Error while indexing issue {0} in {1}", issue.id, repositoryName), e);
-		}
-		return false;
-	}
-	
-	/**
-	 * Delete an issue from the repository index.
-	 * 
-	 * @param repositoryName
-	 * @param issueId
-	 * @throws Exception
-	 * @return true, if deleted, false if no record was deleted
-	 */
-	private boolean deleteIssue(String repositoryName, String issueId) throws Exception {
-		BooleanQuery query = new BooleanQuery();
-		Term objectTerm = new Term(FIELD_OBJECT_TYPE, SearchObjectType.issue.name());
-		query.add(new TermQuery(objectTerm), Occur.MUST);
-		Term issueidTerm = new Term(FIELD_ISSUE, issueId);
-		query.add(new TermQuery(issueidTerm), Occur.MUST);
-		
-		IndexWriter writer = getIndexWriter(repositoryName);
-		int numDocsBefore = writer.numDocs();
-		writer.deleteDocuments(query);
-		writer.commit();
-		int numDocsAfter = writer.numDocs();
-		if (numDocsBefore == numDocsAfter) {
-			logger.debug(MessageFormat.format("no records found to delete {0}", query.toString()));
-			return false;
-		} else {
-			logger.debug(MessageFormat.format("deleted {0} records with {1}", numDocsBefore - numDocsAfter, query.toString()));
-			return true;
-		}
-	}
-	
-	/**
 	 * Delete a blob from the specified branch of the repository index.
 	 * 
 	 * @param repositoryName
@@ -870,10 +801,9 @@
 						&& branch.equals(defaultBranch)) {
 					// indexing "default" branch
 					indexBranch = true;
-				} else if (IssueUtils.GB_ISSUES.equals(branch)) {
-					// update issues modified on the GB_ISSUES branch
-					// note: this is different than reindex
-					indexBranch = true;
+				} else if (branch.getName().startsWith(com.gitblit.Constants.R_GITBLIT)) {
+					// ignore internal Gitblit branches
+					indexBranch = false;
 				} else {
 					// normal explicit branch check
 					indexBranch = model.indexedBranches.contains(branch.getName());
@@ -904,35 +834,11 @@
 					result.branchCount += 1;
 				}
 				
-				// track the issue ids that we have already indexed
-				Set<String> indexedIssues = new TreeSet<String>();
-				
 				// reverse the list of commits so we start with the first commit				
 				Collections.reverse(revs);
 				for (RevCommit commit : revs) {					
-					if (IssueUtils.GB_ISSUES.equals(branch)) {
-						// only index an issue once during updateIndex
-						String issueId = commit.getShortMessage().substring(2).trim();
-						if (indexedIssues.contains(issueId)) {
-							continue;
-						}
-						indexedIssues.add(issueId);
-						
-						IssueModel issue = IssueUtils.getIssue(repository, issueId);
-						if (issue == null) {
-							// issue was deleted, remove from index
-							if (!deleteIssue(model.name, issueId)) {
-								logger.error(MessageFormat.format("Failed to delete issue {0} from Lucene index!", issueId));
-							}
-						} else {
-							// issue was updated
-							index(model.name, issue);
-							result.issueCount++;
-						}
-					} else {
-						// index a commit
-						result.add(index(model.name, repository, branchName, commit));
-					}
+					// index a commit
+					result.add(index(model.name, repository, branchName, commit));
 				}
 
 				// update the config
@@ -959,34 +865,6 @@
 	}
 	
 	/**
-	 * Creates a Lucene document from an issue.
-	 * 
-	 * @param issue
-	 * @return a Lucene document
-	 */
-	private Document createDocument(IssueModel issue) {
-		Document doc = new Document();
-		doc.add(new Field(FIELD_OBJECT_TYPE, SearchObjectType.issue.name(), Store.YES,
-				Field.Index.NOT_ANALYZED));
-		doc.add(new Field(FIELD_ISSUE, issue.id, Store.YES, Index.ANALYZED));
-		doc.add(new Field(FIELD_BRANCH, IssueUtils.GB_ISSUES, Store.YES, Index.ANALYZED));
-		doc.add(new Field(FIELD_DATE, DateTools.dateToString(issue.created, Resolution.MINUTE),
-				Store.YES, Field.Index.NO));
-		doc.add(new Field(FIELD_AUTHOR, issue.reporter, Store.YES, Index.ANALYZED));
-		List<String> attachments = new ArrayList<String>();
-		for (Attachment attachment : issue.getAttachments()) {
-			attachments.add(attachment.name.toLowerCase());
-		}
-		doc.add(new Field(FIELD_ATTACHMENT, StringUtils.flattenStrings(attachments), Store.YES,
-				Index.ANALYZED));
-		doc.add(new Field(FIELD_SUMMARY, issue.summary, Store.YES, Index.ANALYZED));
-		doc.add(new Field(FIELD_CONTENT, issue.toString(), Store.YES, Index.ANALYZED));
-		doc.add(new Field(FIELD_LABEL, StringUtils.flattenStrings(issue.getLabels()), Store.YES,
-				Index.ANALYZED));
-		return doc;
-	}
-
-	/**
 	 * Creates a Lucene document for a commit
 	 * 
 	 * @param commit
@@ -1042,7 +920,6 @@
 		result.type = SearchObjectType.fromName(doc.get(FIELD_OBJECT_TYPE));
 		result.branch = doc.get(FIELD_BRANCH);
 		result.commitId = doc.get(FIELD_COMMIT);
-		result.issueId = doc.get(FIELD_ISSUE);
 		result.path = doc.get(FIELD_PATH);
 		if (doc.get(FIELD_TAG) != null) {
 			result.tags = StringUtils.getStringsFromValue(doc.get(FIELD_TAG));
diff --git a/src/main/java/com/gitblit/models/IssueModel.java b/src/main/java/com/gitblit/models/IssueModel.java
deleted file mode 100644
index c903891..0000000
--- a/src/main/java/com/gitblit/models/IssueModel.java
+++ /dev/null
@@ -1,532 +0,0 @@
-/*
- * Copyright 2012 gitblit.com.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.gitblit.models;
-
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.Set;
-
-import com.gitblit.utils.ArrayUtils;
-import com.gitblit.utils.StringUtils;
-import com.gitblit.utils.TimeUtils;
-
-/**
- * The Gitblit Issue model, its component classes, and enums.
- * 
- * @author James Moger
- * 
- */
-public class IssueModel implements Serializable, Comparable<IssueModel> {
-
-	private static final long serialVersionUID = 1L;
-
-	public String id;
-
-	public Type type;
-
-	public Status status;
-
-	public Priority priority;
-
-	public Date created;
-
-	public String summary;
-
-	public String description;
-
-	public String reporter;
-
-	public String owner;
-
-	public String milestone;
-
-	public List<Change> changes;
-
-	public IssueModel() {
-		// the first applied change set the date appropriately
-		created = new Date(0);
-
-		type = Type.Defect;
-		status = Status.New;
-		priority = Priority.Medium;
-
-		changes = new ArrayList<Change>();
-	}
-
-	public String getStatus() {
-		String s = status.toString();
-		if (!StringUtils.isEmpty(owner))
-			s += " (" + owner + ")";
-		return s;
-	}
-
-	public boolean hasLabel(String label) {
-		return getLabels().contains(label);
-	}
-
-	public List<String> getLabels() {
-		List<String> list = new ArrayList<String>();
-		String labels = null;
-		for (Change change : changes) {
-			if (change.hasField(Field.Labels)) {
-				labels = change.getString(Field.Labels);
-			}
-		}
-		if (!StringUtils.isEmpty(labels)) {
-			list.addAll(StringUtils.getStringsFromValue(labels, " "));
-		}
-		return list;
-	}
-
-	public Attachment getAttachment(String name) {
-		Attachment attachment = null;
-		for (Change change : changes) {
-			if (change.hasAttachments()) {
-				Attachment a = change.getAttachment(name);
-				if (a != null) {
-					attachment = a;
-				}
-			}
-		}
-		return attachment;
-	}
-
-	public List<Attachment> getAttachments() {
-		List<Attachment> list = new ArrayList<Attachment>();
-		for (Change change : changes) {
-			if (change.hasAttachments()) {
-				list.addAll(change.attachments);
-			}
-		}
-		return list;
-	}
-
-	public void applyChange(Change change) {
-		if (changes.size() == 0) {
-			// first change created the issue
-			created = change.created;
-		}
-		changes.add(change);
-
-		if (change.hasFieldChanges()) {
-			for (FieldChange fieldChange : change.fieldChanges) {
-				switch (fieldChange.field) {
-				case Id:
-					id = fieldChange.value.toString();
-					break;
-				case Type:
-					type = IssueModel.Type.fromObject(fieldChange.value);
-					break;
-				case Status:
-					status = IssueModel.Status.fromObject(fieldChange.value);
-					break;
-				case Priority:
-					priority = IssueModel.Priority.fromObject(fieldChange.value);
-					break;
-				case Summary:
-					summary = fieldChange.value.toString();
-					break;
-				case Description:
-					description = fieldChange.value.toString();
-					break;
-				case Reporter:
-					reporter = fieldChange.value.toString();
-					break;
-				case Owner:
-					owner = fieldChange.value.toString();
-					break;
-				case Milestone:
-					milestone = fieldChange.value.toString();
-					break;
-				}
-			}
-		}
-	}
-
-	@Override
-	public String toString() {
-		StringBuilder sb = new StringBuilder();
-		sb.append("issue ");
-		sb.append(id.substring(0, 8));
-		sb.append(" (" + summary + ")\n");
-		for (Change change : changes) {
-			sb.append(change);
-			sb.append('\n');
-		}
-		return sb.toString();
-	}
-
-	@Override
-	public int compareTo(IssueModel o) {
-		return o.created.compareTo(created);
-	}
-
-	@Override
-	public boolean equals(Object o) {
-		if (o instanceof IssueModel)
-			return id.equals(((IssueModel) o).id);
-		return super.equals(o);
-	}
-
-	@Override
-	public int hashCode() {
-		return id.hashCode();
-	}
-
-	public static class Change implements Serializable, Comparable<Change> {
-
-		private static final long serialVersionUID = 1L;
-
-		public final Date created;
-
-		public final String author;
-
-		public String id;
-
-		public char code;
-
-		public Comment comment;
-
-		public Set<FieldChange> fieldChanges;
-
-		public Set<Attachment> attachments;
-
-		public Change(String author) {
-			this.created = new Date((System.currentTimeMillis() / 1000) * 1000);
-			this.author = author;
-			this.id = StringUtils.getSHA1(created.toString() + author);
-		}
-
-		public boolean hasComment() {
-			return comment != null && !comment.deleted;
-		}
-
-		public void comment(String text) {
-			comment = new Comment(text);
-			comment.id = StringUtils.getSHA1(created.toString() + author + text);
-		}
-
-		public boolean hasAttachments() {
-			return !ArrayUtils.isEmpty(attachments);
-		}
-
-		public void addAttachment(Attachment attachment) {
-			if (attachments == null) {
-				attachments = new LinkedHashSet<Attachment>();
-			}
-			attachments.add(attachment);
-		}
-
-		public Attachment getAttachment(String name) {
-			for (Attachment attachment : attachments) {
-				if (attachment.name.equalsIgnoreCase(name)) {
-					return attachment;
-				}
-			}
-			return null;
-		}
-
-		public boolean hasField(Field field) {
-			return !StringUtils.isEmpty(getString(field));
-		}
-
-		public boolean hasFieldChanges() {
-			return !ArrayUtils.isEmpty(fieldChanges);
-		}
-
-		public Object getField(Field field) {
-			if (fieldChanges != null) {
-				for (FieldChange fieldChange : fieldChanges) {
-					if (fieldChange.field == field) {
-						return fieldChange.value;
-					}
-				}
-			}
-			return null;
-		}
-
-		public void setField(Field field, Object value) {
-			FieldChange fieldChange = new FieldChange(field, value);
-			if (fieldChanges == null) {
-				fieldChanges = new LinkedHashSet<FieldChange>();
-			}
-			fieldChanges.add(fieldChange);
-		}
-
-		public String getString(Field field) {
-			Object value = getField(field);
-			if (value == null) {
-				return null;
-			}
-			return value.toString();
-		}
-
-		@Override
-		public int compareTo(Change c) {
-			return created.compareTo(c.created);
-		}
-
-		@Override
-		public int hashCode() {
-			return id.hashCode();
-		}
-
-		@Override
-		public boolean equals(Object o) {
-			if (o instanceof Change) {
-				return id.equals(((Change) o).id);
-			}
-			return false;
-		}
-
-		@Override
-		public String toString() {
-			StringBuilder sb = new StringBuilder();			
-			sb.append(new TimeUtils().timeAgo(created));
-			switch (code) {
-			case '+':
-				sb.append(" created by ");
-				break;
-			default:
-				if (hasComment()) {
-					sb.append(" commented on by ");
-				} else {
-					sb.append(" changed by ");
-				}
-			}
-			sb.append(author).append(" - ");
-			if (hasComment()) {
-				if (comment.deleted) {
-					sb.append("(deleted) ");
-				}
-				sb.append(comment.text).append(" ");
-			}
-			if (hasFieldChanges()) {
-				switch (code) {
-				case '+':
-					break;
-				default:
-					for (FieldChange fieldChange : fieldChanges) {
-						sb.append("\n  ");
-						sb.append(fieldChange);
-					}
-					break;
-				}
-			}
-			return sb.toString();
-		}
-	}
-
-	public static class Comment implements Serializable {
-
-		private static final long serialVersionUID = 1L;
-
-		public String text;
-
-		public String id;
-
-		public boolean deleted;
-
-		Comment(String text) {
-			this.text = text;
-		}
-
-		@Override
-		public String toString() {
-			return text;
-		}
-	}
-
-	public static class FieldChange implements Serializable {
-
-		private static final long serialVersionUID = 1L;
-
-		public final Field field;
-
-		public final Object value;
-
-		FieldChange(Field field, Object value) {
-			this.field = field;
-			this.value = value;
-		}
-
-		@Override
-		public int hashCode() {
-			return field.hashCode();
-		}
-
-		@Override
-		public boolean equals(Object o) {
-			if (o instanceof FieldChange) {
-				return field.equals(((FieldChange) o).field);
-			}
-			return false;
-		}
-
-		@Override
-		public String toString() {
-			return field + ": " + value;
-		}
-	}
-
-	public static class Attachment implements Serializable {
-
-		private static final long serialVersionUID = 1L;
-
-		public final String name;
-		public String id;
-		public long size;
-		public byte[] content;
-		public boolean deleted;
-
-		public Attachment(String name) {
-			this.name = name;
-		}
-
-		@Override
-		public int hashCode() {
-			return name.hashCode();
-		}
-
-		@Override
-		public boolean equals(Object o) {
-			if (o instanceof Attachment) {
-				return name.equalsIgnoreCase(((Attachment) o).name);
-			}
-			return false;
-		}
-
-		@Override
-		public String toString() {
-			return name;
-		}
-	}
-
-	public static enum Field {
-		Id, Summary, Description, Reporter, Owner, Type, Status, Priority, Milestone, Component, Labels;
-	}
-
-	public static enum Type {
-		Defect, Enhancement, Task, Review, Other;
-
-		public static Type fromObject(Object o) {
-			if (o instanceof Type) {
-				// cast and return
-				return (Type) o;
-			} else if (o instanceof String) {
-				// find by name
-				for (Type type : values()) {
-					String str = o.toString();
-					if (type.toString().equalsIgnoreCase(str)) {
-						return type;
-					}
-				}
-			} else if (o instanceof Number) {
-				// by ordinal
-				int id = ((Number) o).intValue();
-				if (id >= 0 && id < values().length) {
-					return values()[id];
-				}
-			}
-			return null;
-		}
-	}
-
-	public static enum Priority {
-		Low, Medium, High, Critical;
-
-		public static Priority fromObject(Object o) {
-			if (o instanceof Priority) {
-				// cast and return
-				return (Priority) o;
-			} else if (o instanceof String) {
-				// find by name
-				for (Priority priority : values()) {
-					String str = o.toString();
-					if (priority.toString().equalsIgnoreCase(str)) {
-						return priority;
-					}
-				}
-			} else if (o instanceof Number) {
-				// by ordinal
-				int id = ((Number) o).intValue();
-				if (id >= 0 && id < values().length) {
-					return values()[id];
-				}
-			}
-			return null;
-		}
-	}
-
-	public static enum Status {
-		New, Accepted, Started, Review, Queued, Testing, Done, Fixed, WontFix, Duplicate, Invalid;
-
-		public static Status fromObject(Object o) {
-			if (o instanceof Status) {
-				// cast and return
-				return (Status) o;
-			} else if (o instanceof String) {
-				// find by name
-				for (Status status : values()) {
-					String str = o.toString();
-					if (status.toString().equalsIgnoreCase(str)) {
-						return status;
-					}
-				}
-			} else if (o instanceof Number) {
-				// by ordinal
-				int id = ((Number) o).intValue();
-				if (id >= 0 && id < values().length) {
-					return values()[id];
-				}
-			}
-			return null;
-		}
-
-		public boolean atLeast(Status status) {
-			return ordinal() >= status.ordinal();
-		}
-
-		public boolean exceeds(Status status) {
-			return ordinal() > status.ordinal();
-		}
-
-		public boolean isClosed() {
-			return ordinal() >= Done.ordinal();
-		}
-
-		public Status next() {
-			switch (this) {
-			case New:
-				return Started;
-			case Accepted:
-				return Started;
-			case Started:
-				return Testing;
-			case Review:
-				return Testing;
-			case Queued:
-				return Testing;
-			case Testing:
-				return Done;
-			}
-			return Accepted;
-		}
-	}
-}
diff --git a/src/main/java/com/gitblit/utils/IssueUtils.java b/src/main/java/com/gitblit/utils/IssueUtils.java
deleted file mode 100644
index dd09235..0000000
--- a/src/main/java/com/gitblit/utils/IssueUtils.java
+++ /dev/null
@@ -1,829 +0,0 @@
-/*
- * Copyright 2012 gitblit.com.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.gitblit.utils;
-
-import java.io.IOException;
-import java.text.MessageFormat;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeSet;
-
-import org.eclipse.jgit.api.errors.ConcurrentRefUpdateException;
-import org.eclipse.jgit.api.errors.JGitInternalException;
-import org.eclipse.jgit.dircache.DirCache;
-import org.eclipse.jgit.dircache.DirCacheBuilder;
-import org.eclipse.jgit.dircache.DirCacheEntry;
-import org.eclipse.jgit.internal.JGitText;
-import org.eclipse.jgit.lib.CommitBuilder;
-import org.eclipse.jgit.lib.Constants;
-import org.eclipse.jgit.lib.FileMode;
-import org.eclipse.jgit.lib.ObjectId;
-import org.eclipse.jgit.lib.ObjectInserter;
-import org.eclipse.jgit.lib.PersonIdent;
-import org.eclipse.jgit.lib.RefUpdate;
-import org.eclipse.jgit.lib.RefUpdate.Result;
-import org.eclipse.jgit.lib.Repository;
-import org.eclipse.jgit.revwalk.RevCommit;
-import org.eclipse.jgit.revwalk.RevTree;
-import org.eclipse.jgit.revwalk.RevWalk;
-import org.eclipse.jgit.treewalk.CanonicalTreeParser;
-import org.eclipse.jgit.treewalk.TreeWalk;
-import org.eclipse.jgit.treewalk.filter.AndTreeFilter;
-import org.eclipse.jgit.treewalk.filter.PathFilterGroup;
-import org.eclipse.jgit.treewalk.filter.TreeFilter;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.gitblit.models.IssueModel;
-import com.gitblit.models.IssueModel.Attachment;
-import com.gitblit.models.IssueModel.Change;
-import com.gitblit.models.IssueModel.Field;
-import com.gitblit.models.IssueModel.Status;
-import com.gitblit.models.RefModel;
-import com.gitblit.utils.JsonUtils.ExcludeField;
-import com.google.gson.Gson;
-import com.google.gson.reflect.TypeToken;
-
-/**
- * Utility class for reading Gitblit issues.
- * 
- * @author James Moger
- * 
- */
-public class IssueUtils {
-
-	public static interface IssueFilter {
-		public abstract boolean accept(IssueModel issue);
-	}
-
-	public static final String GB_ISSUES = "refs/gitblit/issues";
-
-	static final Logger LOGGER = LoggerFactory.getLogger(IssueUtils.class);
-
-	/**
-	 * Log an error message and exception.
-	 * 
-	 * @param t
-	 * @param repository
-	 *            if repository is not null it MUST be the {0} parameter in the
-	 *            pattern.
-	 * @param pattern
-	 * @param objects
-	 */
-	private static void error(Throwable t, Repository repository, String pattern, Object... objects) {
-		List<Object> parameters = new ArrayList<Object>();
-		if (objects != null && objects.length > 0) {
-			for (Object o : objects) {
-				parameters.add(o);
-			}
-		}
-		if (repository != null) {
-			parameters.add(0, repository.getDirectory().getAbsolutePath());
-		}
-		LOGGER.error(MessageFormat.format(pattern, parameters.toArray()), t);
-	}
-
-	/**
-	 * Returns a RefModel for the gb-issues branch in the repository. If the
-	 * branch can not be found, null is returned.
-	 * 
-	 * @param repository
-	 * @return a refmodel for the gb-issues branch or null
-	 */
-	public static RefModel getIssuesBranch(Repository repository) {
-		List<RefModel> refs = JGitUtils.getRefs(repository, com.gitblit.Constants.R_GITBLIT);
-		for (RefModel ref : refs) {
-			if (ref.reference.getName().equals(GB_ISSUES)) {
-				return ref;
-			}
-		}
-		return null;
-	}
-
-	/**
-	 * Returns all the issues in the repository. Querying issues from the
-	 * repository requires deserializing all changes for all issues. This is an
-	 * expensive process and not recommended. Issues should be indexed by Lucene
-	 * and queries should be executed against that index.
-	 * 
-	 * @param repository
-	 * @param filter
-	 *            optional issue filter to only return matching results
-	 * @return a list of issues
-	 */
-	public static List<IssueModel> getIssues(Repository repository, IssueFilter filter) {
-		List<IssueModel> list = new ArrayList<IssueModel>();
-		RefModel issuesBranch = getIssuesBranch(repository);
-		if (issuesBranch == null) {
-			return list;
-		}
-
-		// Collect the set of all issue paths
-		Set<String> issuePaths = new HashSet<String>();
-		final TreeWalk tw = new TreeWalk(repository);
-		try {
-			RevCommit head = JGitUtils.getCommit(repository, GB_ISSUES);
-			tw.addTree(head.getTree());
-			tw.setRecursive(false);
-			while (tw.next()) {
-				if (tw.getDepth() < 2 && tw.isSubtree()) {
-					tw.enterSubtree();
-					if (tw.getDepth() == 2) {
-						issuePaths.add(tw.getPathString());
-					}
-				}
-			}
-		} catch (IOException e) {
-			error(e, repository, "{0} failed to query issues");
-		} finally {
-			tw.release();
-		}
-
-		// Build each issue and optionally filter out unwanted issues
-
-		for (String issuePath : issuePaths) {
-			RevWalk rw = new RevWalk(repository);
-			try {
-				RevCommit start = rw.parseCommit(repository.resolve(GB_ISSUES));
-				rw.markStart(start);
-			} catch (Exception e) {
-				error(e, repository, "Failed to find {1} in {0}", GB_ISSUES);
-			}
-			TreeFilter treeFilter = AndTreeFilter.create(
-					PathFilterGroup.createFromStrings(issuePath), TreeFilter.ANY_DIFF);
-			rw.setTreeFilter(treeFilter);
-			Iterator<RevCommit> revlog = rw.iterator();
-
-			List<RevCommit> commits = new ArrayList<RevCommit>();
-			while (revlog.hasNext()) {
-				commits.add(revlog.next());
-			}
-
-			// release the revwalk
-			rw.release();
-
-			if (commits.size() == 0) {
-				LOGGER.warn("Failed to find changes for issue " + issuePath);
-				continue;
-			}
-
-			// sort by commit order, first commit first
-			Collections.reverse(commits);
-
-			StringBuilder sb = new StringBuilder("[");
-			boolean first = true;
-			for (RevCommit commit : commits) {
-				if (!first) {
-					sb.append(',');
-				}
-				String message = commit.getFullMessage();
-				// commit message is formatted: C ISSUEID\n\nJSON
-				// C is an single char commit code
-				// ISSUEID is an SHA-1 hash
-				String json = message.substring(43);
-				sb.append(json);
-				first = false;
-			}
-			sb.append(']');
-
-			// Deserialize the JSON array as a Collection<Change>, this seems
-			// slightly faster than deserializing each change by itself.
-			Collection<Change> changes = JsonUtils.fromJsonString(sb.toString(),
-					new TypeToken<Collection<Change>>() {
-					}.getType());
-
-			// create an issue object form the changes
-			IssueModel issue = buildIssue(changes, true);
-
-			// add the issue, conditionally, to the list
-			if (filter == null) {
-				list.add(issue);
-			} else {
-				if (filter.accept(issue)) {
-					list.add(issue);
-				}
-			}
-		}
-
-		// sort the issues by creation
-		Collections.sort(list);
-		return list;
-	}
-
-	/**
-	 * Retrieves the specified issue from the repository with all changes
-	 * applied to build the effective issue.
-	 * 
-	 * @param repository
-	 * @param issueId
-	 * @return an issue, if it exists, otherwise null
-	 */
-	public static IssueModel getIssue(Repository repository, String issueId) {
-		return getIssue(repository, issueId, true);
-	}
-
-	/**
-	 * Retrieves the specified issue from the repository.
-	 * 
-	 * @param repository
-	 * @param issueId
-	 * @param effective
-	 *            if true, the effective issue is built by processing comment
-	 *            changes, deletions, etc. if false, the raw issue is built
-	 *            without consideration for comment changes, deletions, etc.
-	 * @return an issue, if it exists, otherwise null
-	 */
-	public static IssueModel getIssue(Repository repository, String issueId, boolean effective) {
-		RefModel issuesBranch = getIssuesBranch(repository);
-		if (issuesBranch == null) {
-			return null;
-		}
-
-		if (StringUtils.isEmpty(issueId)) {
-			return null;
-		}
-
-		String issuePath = getIssuePath(issueId);
-
-		// Collect all changes as JSON array from commit messages
-		List<RevCommit> commits = JGitUtils.getRevLog(repository, GB_ISSUES, issuePath, 0, -1);
-
-		// sort by commit order, first commit first
-		Collections.reverse(commits);
-
-		StringBuilder sb = new StringBuilder("[");
-		boolean first = true;
-		for (RevCommit commit : commits) {
-			if (!first) {
-				sb.append(',');
-			}
-			String message = commit.getFullMessage();
-			// commit message is formatted: C ISSUEID\n\nJSON
-			// C is an single char commit code
-			// ISSUEID is an SHA-1 hash
-			String json = message.substring(43);
-			sb.append(json);
-			first = false;
-		}
-		sb.append(']');
-
-		// Deserialize the JSON array as a Collection<Change>, this seems
-		// slightly faster than deserializing each change by itself.
-		Collection<Change> changes = JsonUtils.fromJsonString(sb.toString(),
-				new TypeToken<Collection<Change>>() {
-				}.getType());
-
-		// create an issue object and apply the changes to it
-		IssueModel issue = buildIssue(changes, effective);
-		return issue;
-	}
-
-	/**
-	 * Builds an issue from a set of changes.
-	 * 
-	 * @param changes
-	 * @param effective
-	 *            if true, the effective issue is built which accounts for
-	 *            comment changes, comment deletions, etc. if false, the raw
-	 *            issue is built.
-	 * @return an issue
-	 */
-	private static IssueModel buildIssue(Collection<Change> changes, boolean effective) {
-		IssueModel issue;
-		if (effective) {
-			List<Change> effectiveChanges = new ArrayList<Change>();
-			Map<String, Change> comments = new HashMap<String, Change>();
-			for (Change change : changes) {
-				if (change.comment != null) {
-					if (comments.containsKey(change.comment.id)) {
-						Change original = comments.get(change.comment.id);
-						Change clone = DeepCopier.copy(original);
-						clone.comment.text = change.comment.text;
-						clone.comment.deleted = change.comment.deleted;
-						int idx = effectiveChanges.indexOf(original);
-						effectiveChanges.remove(original);
-						effectiveChanges.add(idx, clone);
-						comments.put(clone.comment.id, clone);
-					} else {
-						effectiveChanges.add(change);
-						comments.put(change.comment.id, change);
-					}
-				} else {
-					effectiveChanges.add(change);
-				}
-			}
-
-			// effective issue
-			issue = new IssueModel();
-			for (Change change : effectiveChanges) {
-				issue.applyChange(change);
-			}
-		} else {
-			// raw issue
-			issue = new IssueModel();
-			for (Change change : changes) {
-				issue.applyChange(change);
-			}
-		}
-		return issue;
-	}
-
-	/**
-	 * Retrieves the specified attachment from an issue.
-	 * 
-	 * @param repository
-	 * @param issueId
-	 * @param filename
-	 * @return an attachment, if found, null otherwise
-	 */
-	public static Attachment getIssueAttachment(Repository repository, String issueId,
-			String filename) {
-		RefModel issuesBranch = getIssuesBranch(repository);
-		if (issuesBranch == null) {
-			return null;
-		}
-
-		if (StringUtils.isEmpty(issueId)) {
-			return null;
-		}
-
-		// deserialize the issue model so that we have the attachment metadata
-		IssueModel issue = getIssue(repository, issueId, true);
-		Attachment attachment = issue.getAttachment(filename);
-
-		// attachment not found
-		if (attachment == null) {
-			return null;
-		}
-
-		// retrieve the attachment content
-		String issuePath = getIssuePath(issueId);
-		RevTree tree = JGitUtils.getCommit(repository, GB_ISSUES).getTree();
-		byte[] content = JGitUtils
-				.getByteContent(repository, tree, issuePath + "/" + attachment.id, false);
-		attachment.content = content;
-		attachment.size = content.length;
-		return attachment;
-	}
-
-	/**
-	 * Creates an issue in the gb-issues branch of the repository. The branch is
-	 * automatically created if it does not already exist. Your change must
-	 * include an author, summary, and description, at a minimum. If your change
-	 * does not have those minimum requirements a RuntimeException will be
-	 * thrown.
-	 * 
-	 * @param repository
-	 * @param change
-	 * @return true if successful
-	 */
-	public static IssueModel createIssue(Repository repository, Change change) {
-		RefModel issuesBranch = getIssuesBranch(repository);
-		if (issuesBranch == null) {
-			JGitUtils.createOrphanBranch(repository, GB_ISSUES, null);
-		}
-
-		if (StringUtils.isEmpty(change.author)) {
-			throw new RuntimeException("Must specify a change author!");
-		}
-		if (!change.hasField(Field.Summary)) {
-			throw new RuntimeException("Must specify a summary!");
-		}
-		if (!change.hasField(Field.Description)) {
-			throw new RuntimeException("Must specify a description!");
-		}
-
-		change.setField(Field.Reporter, change.author);
-
-		String issueId = StringUtils.getSHA1(change.created.toString() + change.author
-				+ change.getString(Field.Summary) + change.getField(Field.Description));
-		change.setField(Field.Id, issueId);
-		change.code = '+';
-
-		boolean success = commit(repository, issueId, change);
-		if (success) {
-			return getIssue(repository, issueId, false);
-		}
-		return null;
-	}
-
-	/**
-	 * Updates an issue in the gb-issues branch of the repository.
-	 * 
-	 * @param repository
-	 * @param issueId
-	 * @param change
-	 * @return true if successful
-	 */
-	public static boolean updateIssue(Repository repository, String issueId, Change change) {
-		boolean success = false;
-		RefModel issuesBranch = getIssuesBranch(repository);
-
-		if (issuesBranch == null) {
-			throw new RuntimeException("gb-issues branch does not exist!");
-		}
-
-		if (change == null) {
-			throw new RuntimeException("change can not be null!");
-		}
-
-		if (StringUtils.isEmpty(change.author)) {
-			throw new RuntimeException("must specify a change author!");
-		}
-
-		// determine update code
-		// default update code is '=' for a general change
-		change.code = '=';
-		if (change.hasField(Field.Status)) {
-			Status status = Status.fromObject(change.getField(Field.Status));
-			if (status.isClosed()) {
-				// someone closed the issue
-				change.code = 'x';
-			}
-		}
-		success = commit(repository, issueId, change);
-		return success;
-	}
-
-	/**
-	 * Deletes an issue from the repository.
-	 * 
-	 * @param repository
-	 * @param issueId
-	 * @return true if successful
-	 */
-	public static boolean deleteIssue(Repository repository, String issueId, String author) {
-		boolean success = false;
-		RefModel issuesBranch = getIssuesBranch(repository);
-
-		if (issuesBranch == null) {
-			throw new RuntimeException(GB_ISSUES + " does not exist!");
-		}
-
-		if (StringUtils.isEmpty(issueId)) {
-			throw new RuntimeException("must specify an issue id!");
-		}
-
-		String issuePath = getIssuePath(issueId);
-
-		String message = "- " + issueId;
-		try {
-			ObjectId headId = repository.resolve(GB_ISSUES + "^{commit}");
-			ObjectInserter odi = repository.newObjectInserter();
-			try {
-				// Create the in-memory index of the new/updated issue
-				DirCache index = DirCache.newInCore();
-				DirCacheBuilder dcBuilder = index.builder();
-				// Traverse HEAD to add all other paths
-				TreeWalk treeWalk = new TreeWalk(repository);
-				int hIdx = -1;
-				if (headId != null)
-					hIdx = treeWalk.addTree(new RevWalk(repository).parseTree(headId));
-				treeWalk.setRecursive(true);
-				while (treeWalk.next()) {
-					String path = treeWalk.getPathString();
-					CanonicalTreeParser hTree = null;
-					if (hIdx != -1)
-						hTree = treeWalk.getTree(hIdx, CanonicalTreeParser.class);
-					if (!path.startsWith(issuePath)) {
-						// add entries from HEAD for all other paths
-						if (hTree != null) {
-							// create a new DirCacheEntry with data retrieved
-							// from HEAD
-							final DirCacheEntry dcEntry = new DirCacheEntry(path);
-							dcEntry.setObjectId(hTree.getEntryObjectId());
-							dcEntry.setFileMode(hTree.getEntryFileMode());
-
-							// add to temporary in-core index
-							dcBuilder.add(dcEntry);
-						}
-					}
-				}
-
-				// release the treewalk
-				treeWalk.release();
-
-				// finish temporary in-core index used for this commit
-				dcBuilder.finish();
-
-				ObjectId indexTreeId = index.writeTree(odi);
-
-				// Create a commit object
-				PersonIdent ident = new PersonIdent(author, "gitblit@localhost");
-				CommitBuilder commit = new CommitBuilder();
-				commit.setAuthor(ident);
-				commit.setCommitter(ident);
-				commit.setEncoding(Constants.CHARACTER_ENCODING);
-				commit.setMessage(message);
-				commit.setParentId(headId);
-				commit.setTreeId(indexTreeId);
-
-				// Insert the commit into the repository
-				ObjectId commitId = odi.insert(commit);
-				odi.flush();
-
-				RevWalk revWalk = new RevWalk(repository);
-				try {
-					RevCommit revCommit = revWalk.parseCommit(commitId);
-					RefUpdate ru = repository.updateRef(GB_ISSUES);
-					ru.setNewObjectId(commitId);
-					ru.setExpectedOldObjectId(headId);
-					ru.setRefLogMessage("commit: " + revCommit.getShortMessage(), false);
-					Result rc = ru.forceUpdate();
-					switch (rc) {
-					case NEW:
-					case FORCED:
-					case FAST_FORWARD:
-						success = true;
-						break;
-					case REJECTED:
-					case LOCK_FAILURE:
-						throw new ConcurrentRefUpdateException(JGitText.get().couldNotLockHEAD,
-								ru.getRef(), rc);
-					default:
-						throw new JGitInternalException(MessageFormat.format(
-								JGitText.get().updatingRefFailed, GB_ISSUES, commitId.toString(),
-								rc));
-					}
-				} finally {
-					revWalk.release();
-				}
-			} finally {
-				odi.release();
-			}
-		} catch (Throwable t) {
-			error(t, repository, "Failed to delete issue {1} to {0}", issueId);
-		}
-		return success;
-	}
-
-	/**
-	 * Changes the text of an issue comment.
-	 * 
-	 * @param repository
-	 * @param issue
-	 * @param change
-	 *            the change with the comment to change
-	 * @param author
-	 *            the author of the revision
-	 * @param comment
-	 *            the revised comment
-	 * @return true, if the change was successful
-	 */
-	public static boolean changeComment(Repository repository, IssueModel issue, Change change,
-			String author, String comment) {
-		Change revision = new Change(author);
-		revision.comment(comment);
-		revision.comment.id = change.comment.id;
-		return updateIssue(repository, issue.id, revision);
-	}
-
-	/**
-	 * Deletes a comment from an issue.
-	 * 
-	 * @param repository
-	 * @param issue
-	 * @param change
-	 *            the change with the comment to delete
-	 * @param author
-	 * @return true, if the deletion was successful
-	 */
-	public static boolean deleteComment(Repository repository, IssueModel issue, Change change,
-			String author) {
-		Change deletion = new Change(author);
-		deletion.comment(change.comment.text);
-		deletion.comment.id = change.comment.id;
-		deletion.comment.deleted = true;
-		return updateIssue(repository, issue.id, deletion);
-	}
-
-	/**
-	 * Commit a change to the repository. Each issue is composed on changes.
-	 * Issues are built from applying the changes in the order they were
-	 * committed to the repository. The changes are actually specified in the
-	 * commit messages and not in the RevTrees which allows for clean,
-	 * distributed merging.
-	 * 
-	 * @param repository
-	 * @param issueId
-	 * @param change
-	 * @return true, if the change was committed
-	 */
-	private static boolean commit(Repository repository, String issueId, Change change) {
-		boolean success = false;
-
-		try {
-			// assign ids to new attachments
-			// attachments are stored by an SHA1 id
-			if (change.hasAttachments()) {
-				for (Attachment attachment : change.attachments) {
-					if (!ArrayUtils.isEmpty(attachment.content)) {
-						byte[] prefix = (change.created.toString() + change.author).getBytes();
-						byte[] bytes = new byte[prefix.length + attachment.content.length];
-						System.arraycopy(prefix, 0, bytes, 0, prefix.length);
-						System.arraycopy(attachment.content, 0, bytes, prefix.length,
-								attachment.content.length);
-						attachment.id = "attachment-" + StringUtils.getSHA1(bytes);
-					}
-				}
-			}
-
-			// serialize the change as json
-			// exclude any attachment from json serialization
-			Gson gson = JsonUtils.gson(new ExcludeField(
-					"com.gitblit.models.IssueModel$Attachment.content"));
-			String json = gson.toJson(change);
-
-			// include the json change in the commit message
-			String issuePath = getIssuePath(issueId);
-			String message = change.code + " " + issueId + "\n\n" + json;
-
-			// Create a commit file. This is required for a proper commit and
-			// ensures we can retrieve the commit log of the issue path.
-			//
-			// This file is NOT serialized as part of the Change object.
-			switch (change.code) {
-			case '+': {
-				// New Issue.
-				Attachment placeholder = new Attachment("issue");
-				placeholder.id = placeholder.name;
-				placeholder.content = "DO NOT REMOVE".getBytes(Constants.CHARACTER_ENCODING);
-				change.addAttachment(placeholder);
-				break;
-			}
-			default: {
-				// Update Issue.
-				String changeId = StringUtils.getSHA1(json);
-				Attachment placeholder = new Attachment("change-" + changeId);
-				placeholder.id = placeholder.name;
-				placeholder.content = "REMOVABLE".getBytes(Constants.CHARACTER_ENCODING);
-				change.addAttachment(placeholder);
-				break;
-			}
-			}
-
-			ObjectId headId = repository.resolve(GB_ISSUES + "^{commit}");
-			ObjectInserter odi = repository.newObjectInserter();
-			try {
-				// Create the in-memory index of the new/updated issue
-				DirCache index = createIndex(repository, headId, issuePath, change);
-				ObjectId indexTreeId = index.writeTree(odi);
-
-				// Create a commit object
-				PersonIdent ident = new PersonIdent(change.author, "gitblit@localhost");
-				CommitBuilder commit = new CommitBuilder();
-				commit.setAuthor(ident);
-				commit.setCommitter(ident);
-				commit.setEncoding(Constants.CHARACTER_ENCODING);
-				commit.setMessage(message);
-				commit.setParentId(headId);
-				commit.setTreeId(indexTreeId);
-
-				// Insert the commit into the repository
-				ObjectId commitId = odi.insert(commit);
-				odi.flush();
-
-				RevWalk revWalk = new RevWalk(repository);
-				try {
-					RevCommit revCommit = revWalk.parseCommit(commitId);
-					RefUpdate ru = repository.updateRef(GB_ISSUES);
-					ru.setNewObjectId(commitId);
-					ru.setExpectedOldObjectId(headId);
-					ru.setRefLogMessage("commit: " + revCommit.getShortMessage(), false);
-					Result rc = ru.forceUpdate();
-					switch (rc) {
-					case NEW:
-					case FORCED:
-					case FAST_FORWARD:
-						success = true;
-						break;
-					case REJECTED:
-					case LOCK_FAILURE:
-						throw new ConcurrentRefUpdateException(JGitText.get().couldNotLockHEAD,
-								ru.getRef(), rc);
-					default:
-						throw new JGitInternalException(MessageFormat.format(
-								JGitText.get().updatingRefFailed, GB_ISSUES, commitId.toString(),
-								rc));
-					}
-				} finally {
-					revWalk.release();
-				}
-			} finally {
-				odi.release();
-			}
-		} catch (Throwable t) {
-			error(t, repository, "Failed to commit issue {1} to {0}", issueId);
-		}
-		return success;
-	}
-
-	/**
-	 * Returns the issue path. This follows the same scheme as Git's object
-	 * store path where the first two characters of the hash id are the root
-	 * folder with the remaining characters as a subfolder within that folder.
-	 * 
-	 * @param issueId
-	 * @return the root path of the issue content on the gb-issues branch
-	 */
-	static String getIssuePath(String issueId) {
-		return issueId.substring(0, 2) + "/" + issueId.substring(2);
-	}
-
-	/**
-	 * Creates an in-memory index of the issue change.
-	 * 
-	 * @param repo
-	 * @param headId
-	 * @param change
-	 * @return an in-memory index
-	 * @throws IOException
-	 */
-	private static DirCache createIndex(Repository repo, ObjectId headId, String issuePath,
-			Change change) throws IOException {
-
-		DirCache inCoreIndex = DirCache.newInCore();
-		DirCacheBuilder dcBuilder = inCoreIndex.builder();
-		ObjectInserter inserter = repo.newObjectInserter();
-
-		Set<String> ignorePaths = new TreeSet<String>();
-		try {
-			// Add any attachments to the temporary index
-			if (change.hasAttachments()) {
-				for (Attachment attachment : change.attachments) {
-					// build a path name for the attachment and mark as ignored
-					String path = issuePath + "/" + attachment.id;
-					ignorePaths.add(path);
-
-					// create an index entry for this attachment
-					final DirCacheEntry dcEntry = new DirCacheEntry(path);
-					dcEntry.setLength(attachment.content.length);
-					dcEntry.setLastModified(change.created.getTime());
-					dcEntry.setFileMode(FileMode.REGULAR_FILE);
-
-					// insert object
-					dcEntry.setObjectId(inserter.insert(Constants.OBJ_BLOB, attachment.content));
-
-					// add to temporary in-core index
-					dcBuilder.add(dcEntry);
-				}
-			}
-
-			// Traverse HEAD to add all other paths
-			TreeWalk treeWalk = new TreeWalk(repo);
-			int hIdx = -1;
-			if (headId != null)
-				hIdx = treeWalk.addTree(new RevWalk(repo).parseTree(headId));
-			treeWalk.setRecursive(true);
-
-			while (treeWalk.next()) {
-				String path = treeWalk.getPathString();
-				CanonicalTreeParser hTree = null;
-				if (hIdx != -1)
-					hTree = treeWalk.getTree(hIdx, CanonicalTreeParser.class);
-				if (!ignorePaths.contains(path)) {
-					// add entries from HEAD for all other paths
-					if (hTree != null) {
-						// create a new DirCacheEntry with data retrieved from
-						// HEAD
-						final DirCacheEntry dcEntry = new DirCacheEntry(path);
-						dcEntry.setObjectId(hTree.getEntryObjectId());
-						dcEntry.setFileMode(hTree.getEntryFileMode());
-
-						// add to temporary in-core index
-						dcBuilder.add(dcEntry);
-					}
-				}
-			}
-
-			// release the treewalk
-			treeWalk.release();
-
-			// finish temporary in-core index used for this commit
-			dcBuilder.finish();
-		} finally {
-			inserter.release();
-		}
-		return inCoreIndex;
-	}
-}
\ No newline at end of file
diff --git a/src/test/java/com/gitblit/tests/GitBlitSuite.java b/src/test/java/com/gitblit/tests/GitBlitSuite.java
index 51f05a9..2d653af 100644
--- a/src/test/java/com/gitblit/tests/GitBlitSuite.java
+++ b/src/test/java/com/gitblit/tests/GitBlitSuite.java
@@ -59,7 +59,7 @@
 		MarkdownUtilsTest.class, JGitUtilsTest.class, SyndicationUtilsTest.class,
 		DiffUtilsTest.class, MetricUtilsTest.class, X509UtilsTest.class,
 		GitBlitTest.class, FederationTests.class, RpcTests.class, GitServletTest.class, GitDaemonTest.class,
-		GroovyScriptTest.class, LuceneExecutorTest.class, IssuesTest.class, RepositoryModelTest.class,
+		GroovyScriptTest.class, LuceneExecutorTest.class, RepositoryModelTest.class,
 		FanoutServiceTest.class, Issue0259Test.class, Issue0271Test.class, HtpasswdUserServiceTest.class,
 		ModelUtilsTest.class, JnaUtilsTest.class })
 public class GitBlitSuite {
diff --git a/src/test/java/com/gitblit/tests/IssuesTest.java b/src/test/java/com/gitblit/tests/IssuesTest.java
deleted file mode 100644
index 54cac33..0000000
--- a/src/test/java/com/gitblit/tests/IssuesTest.java
+++ /dev/null
@@ -1,231 +0,0 @@
-/*
- * Copyright 2012 gitblit.com.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.gitblit.tests;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
-import java.util.List;
-
-import org.bouncycastle.util.Arrays;
-import org.eclipse.jgit.lib.Repository;
-import org.junit.Test;
-
-import com.gitblit.LuceneExecutor;
-import com.gitblit.models.IssueModel;
-import com.gitblit.models.IssueModel.Attachment;
-import com.gitblit.models.IssueModel.Change;
-import com.gitblit.models.IssueModel.Field;
-import com.gitblit.models.IssueModel.Priority;
-import com.gitblit.models.IssueModel.Status;
-import com.gitblit.models.SearchResult;
-import com.gitblit.utils.FileUtils;
-import com.gitblit.utils.IssueUtils;
-import com.gitblit.utils.IssueUtils.IssueFilter;
-
-/**
- * Tests the mechanics of distributed issue management on the gb-issues branch.
- * 
- * @author James Moger
- * 
- */
-public class IssuesTest {
-
-	@Test
-	public void testLifecycle() throws Exception {
-		Repository repository = GitBlitSuite.getIssuesTestRepository();
-		String name = FileUtils.getRelativePath(GitBlitSuite.REPOSITORIES, repository.getDirectory());
-		
-		// create and insert an issue
-		Change c1 = newChange("testCreation() " + Long.toHexString(System.currentTimeMillis()));
-		IssueModel issue = IssueUtils.createIssue(repository, c1);
-		assertNotNull(issue.id);
-
-		// retrieve issue and compare
-		IssueModel constructed = IssueUtils.getIssue(repository, issue.id);
-		compare(issue, constructed);
-
-		assertEquals(1, constructed.changes.size());
-		
-		// C1: create the issue
-		c1 = newChange("testUpdates() " + Long.toHexString(System.currentTimeMillis()));
-		issue = IssueUtils.createIssue(repository, c1);
-		assertNotNull(issue.id);
-
-		constructed = IssueUtils.getIssue(repository, issue.id);
-		compare(issue, constructed);
-		assertEquals(1, constructed.changes.size());
-
-		// C2: set owner
-		Change c2 = new Change("C2");
-		c2.comment("I'll fix this");
-		c2.setField(Field.Owner, c2.author);
-		assertTrue(IssueUtils.updateIssue(repository, issue.id, c2));
-		constructed = IssueUtils.getIssue(repository, issue.id);
-		assertEquals(2, constructed.changes.size());
-		assertEquals(c2.author, constructed.owner);
-
-		// C3: add a note
-		Change c3 = new Change("C3");
-		c3.comment("yeah, this is working");
-		assertTrue(IssueUtils.updateIssue(repository, issue.id, c3));
-		constructed = IssueUtils.getIssue(repository, issue.id);
-		assertEquals(3, constructed.changes.size());
-
-		// C4: add attachment
-		Change c4 = new Change("C4");
-		Attachment a = newAttachment();
-		c4.addAttachment(a);
-		assertTrue(IssueUtils.updateIssue(repository, issue.id, c4));
-
-		Attachment a1 = IssueUtils.getIssueAttachment(repository, issue.id, a.name);
-		assertEquals(a.content.length, a1.content.length);
-		assertTrue(Arrays.areEqual(a.content, a1.content));
-
-		// C5: close the issue
-		Change c5 = new Change("C5");
-		c5.comment("closing issue");
-		c5.setField(Field.Status, Status.Fixed);
-		assertTrue(IssueUtils.updateIssue(repository, issue.id, c5));
-
-		// retrieve issue again
-		constructed = IssueUtils.getIssue(repository, issue.id);
-
-		assertEquals(5, constructed.changes.size());
-		assertTrue(constructed.status.isClosed());
-
-		List<IssueModel> allIssues = IssueUtils.getIssues(repository, null);
-		List<IssueModel> openIssues = IssueUtils.getIssues(repository, new IssueFilter() {
-			@Override
-			public boolean accept(IssueModel issue) {
-				return !issue.status.isClosed();
-			}
-		});
-		List<IssueModel> closedIssues = IssueUtils.getIssues(repository, new IssueFilter() {
-			@Override
-			public boolean accept(IssueModel issue) {
-				return issue.status.isClosed();
-			}
-		});
-		
-		assertTrue(allIssues.size() > 0);
-		assertEquals(1, openIssues.size());
-		assertEquals(1, closedIssues.size());
-		
-		// build a new Lucene index
-		LuceneExecutor lucene = new LuceneExecutor(null, GitBlitSuite.REPOSITORIES);
-		lucene.deleteIndex(name);
-		for (IssueModel anIssue : allIssues) {
-			lucene.index(name, anIssue);
-		}
-		List<SearchResult> hits = lucene.search("working", 1, 10, name);
-		assertTrue(hits.size() == 1);
-		
-		// reindex an issue
-		issue = allIssues.get(0);
-		Change change = new Change("reindex");
-		change.comment("this is a test of reindexing an issue");
-		IssueUtils.updateIssue(repository, issue.id, change);
-		issue = IssueUtils.getIssue(repository, issue.id);
-		lucene.index(name, issue);
-
-		hits = lucene.search("working", 1, 10, name);
-		assertTrue(hits.size() == 1);
-
-		
-		// delete all issues
-		for (IssueModel anIssue : allIssues) {
-			assertTrue(IssueUtils.deleteIssue(repository, anIssue.id, "D"));
-		}
-				
-		lucene.close();
-		repository.close();
-	}
-	
-	@Test
-	public void testChangeComment() throws Exception {
-		Repository repository = GitBlitSuite.getIssuesTestRepository();
-		// C1: create the issue
-		Change c1 = newChange("testChangeComment() " + Long.toHexString(System.currentTimeMillis()));
-		IssueModel issue = IssueUtils.createIssue(repository, c1);
-		assertNotNull(issue.id);
-		assertTrue(issue.changes.get(0).hasComment());
-
-		assertTrue(IssueUtils.changeComment(repository, issue, c1, "E1", "I changed the comment"));
-		issue = IssueUtils.getIssue(repository, issue.id);
-		assertTrue(issue.changes.get(0).hasComment());
-		assertEquals("I changed the comment", issue.changes.get(0).comment.text);
-
-		assertTrue(IssueUtils.deleteIssue(repository, issue.id, "D"));
-
-		repository.close();
-	}
-
-	@Test
-	public void testDeleteComment() throws Exception {
-		Repository repository = GitBlitSuite.getIssuesTestRepository();
-		// C1: create the issue
-		Change c1 = newChange("testDeleteComment() " + Long.toHexString(System.currentTimeMillis()));
-		IssueModel issue = IssueUtils.createIssue(repository, c1);
-		assertNotNull(issue.id);
-		assertTrue(issue.changes.get(0).hasComment());
-
-		assertTrue(IssueUtils.deleteComment(repository, issue, c1, "D1"));
-		issue = IssueUtils.getIssue(repository, issue.id);
-		assertEquals(1, issue.changes.size());
-		assertFalse(issue.changes.get(0).hasComment());
-
-		issue = IssueUtils.getIssue(repository, issue.id, false);
-		assertEquals(2, issue.changes.size());
-		assertTrue(issue.changes.get(0).hasComment());
-		assertFalse(issue.changes.get(1).hasComment());
-
-		assertTrue(IssueUtils.deleteIssue(repository, issue.id, "D"));
-
-		repository.close();
-	}
-
-	private Change newChange(String summary) {
-		Change change = new Change("C1");
-		change.setField(Field.Summary, summary);
-		change.setField(Field.Description, "this is my description");
-		change.setField(Field.Priority, Priority.High);
-		change.setField(Field.Labels, "helpdesk");
-		change.comment("my comment");
-		return change;
-	}
-
-	private Attachment newAttachment() {
-		Attachment attachment = new Attachment(Long.toHexString(System.currentTimeMillis())
-				+ ".txt");
-		attachment.content = new byte[] { 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
-				0x4a };
-		return attachment;
-	}
-
-	private void compare(IssueModel issue, IssueModel constructed) {
-		assertEquals(issue.id, constructed.id);
-		assertEquals(issue.reporter, constructed.reporter);
-		assertEquals(issue.owner, constructed.owner);
-		assertEquals(issue.summary, constructed.summary);
-		assertEquals(issue.description, constructed.description);
-		assertEquals(issue.created, constructed.created);
-
-		assertTrue(issue.hasLabel("helpdesk"));
-	}
-}
\ No newline at end of file
