Move repository ownership to the UserModel and prepare for project ownership
diff --git a/src/main/java/com/gitblit/ConfigUserService.java b/src/main/java/com/gitblit/ConfigUserService.java
index d7d6c14..f57bba2 100644
--- a/src/main/java/com/gitblit/ConfigUserService.java
+++ b/src/main/java/com/gitblit/ConfigUserService.java
@@ -27,6 +27,7 @@
 import java.util.Locale;

 import java.util.Map;

 import java.util.Set;

+import java.util.TreeSet;

 import java.util.concurrent.ConcurrentHashMap;

 

 import org.eclipse.jgit.lib.StoredConfig;

@@ -96,6 +97,8 @@
 

 	private static final String STARRED = "starred";

 

+	private static final String OWNS = "owns";

+

 	private static final String LOCALE = "locale";

 

 	private static final String EMAILONMYTICKETCHANGES = "emailMeOnMyTicketChanges";

@@ -617,6 +620,11 @@
 					AccessPermission permission = model.removeRepositoryPermission(oldRole);

 					model.setRepositoryPermission(newRole, permission);

 				}

+

+				if (model.isOwner(oldRole)) {

+					model.disown(oldRole);

+					model.own(newRole);

+				}

 			}

 

 			// identify teams which require role rename

@@ -764,6 +772,11 @@
 				config.setStringList(USER, model.username, REPOSITORY, permissions);

 			}

 

+			// project and repository ownership

+			if (model.ownedPaths != null) {

+				config.setStringList(USER, model.username, OWNS, new ArrayList<String>(model.ownedPaths));

+			}

+

 			// user preferences

 			if (model.getPreferences() != null) {

 				List<String> starred =  model.getPreferences().getStarredRepositories();

@@ -927,13 +940,19 @@
 					}

 

 					// starred repositories

-					Set<String> starred = new HashSet<String>(Arrays.asList(config

+					Set<String> starred = new TreeSet<String>(Arrays.asList(config

 							.getStringList(USER, username, STARRED)));

 					for (String repository : starred) {

 						UserRepositoryPreferences prefs = user.getPreferences().getRepositoryPreferences(repository);

 						prefs.starred = true;

 					}

 

+					// repository ownership

+					Set<String> ownerOf = new TreeSet<String>(Arrays.asList(config.getStringList(USER, username, OWNS)));

+					for (String path : ownerOf) {

+						user.own(path);

+					}

+

 					// update cache

 					users.put(user.username, user);

 					if (!StringUtils.isEmpty(user.cookie)) {

diff --git a/src/main/java/com/gitblit/Constants.java b/src/main/java/com/gitblit/Constants.java
index 3e30753..97d4c60 100644
--- a/src/main/java/com/gitblit/Constants.java
+++ b/src/main/java/com/gitblit/Constants.java
@@ -365,6 +365,7 @@
 		CREATE_REPOSITORY, EDIT_REPOSITORY, DELETE_REPOSITORY,

 		LIST_USERS, CREATE_USER, EDIT_USER, DELETE_USER,

 		LIST_TEAMS, CREATE_TEAM, EDIT_TEAM, DELETE_TEAM,

+		LIST_REPOSITORY_OWNERS, SET_REPOSITORY_OWNERS,

 		LIST_REPOSITORY_MEMBERS, SET_REPOSITORY_MEMBERS, LIST_REPOSITORY_TEAMS, SET_REPOSITORY_TEAMS,

 		LIST_REPOSITORY_MEMBER_PERMISSIONS, SET_REPOSITORY_MEMBER_PERMISSIONS, LIST_REPOSITORY_TEAM_PERMISSIONS, SET_REPOSITORY_TEAM_PERMISSIONS,

 		LIST_FEDERATION_REGISTRATIONS, LIST_FEDERATION_RESULTS, LIST_FEDERATION_PROPOSALS, LIST_FEDERATION_SETS,

diff --git a/src/main/java/com/gitblit/client/EditRepositoryDialog.java b/src/main/java/com/gitblit/client/EditRepositoryDialog.java
index ef665d1..a7cf451 100644
--- a/src/main/java/com/gitblit/client/EditRepositoryDialog.java
+++ b/src/main/java/com/gitblit/client/EditRepositoryDialog.java
@@ -579,8 +579,6 @@
 

 		repository.name = rname;

 		repository.description = descriptionField.getText();

-		repository.owners.clear();

-		repository.owners.addAll(ownersPalette.getSelections());

 		repository.HEAD = headRefField.getSelectedItem() == null ? null

 				: headRefField.getSelectedItem().toString();

 		repository.gcPeriod = (Integer) gcPeriod.getSelectedItem();

@@ -722,6 +720,10 @@
 		return teamsPalette.getPermissions();

 	}

 

+	public List<String> getOwners() {

+		return ownersPalette.getSelections();

+	}

+

 	public void setCustomFields(RepositoryModel repository, Map<String, String> customFields) {

 		customFieldsPanel.removeAll();

 		customTextfields = new ArrayList<JTextField>();

diff --git a/src/main/java/com/gitblit/client/EditUserDialog.java b/src/main/java/com/gitblit/client/EditUserDialog.java
index 676916b..4d0c1c8 100644
--- a/src/main/java/com/gitblit/client/EditUserDialog.java
+++ b/src/main/java/com/gitblit/client/EditUserDialog.java
@@ -393,7 +393,7 @@
 		List<String> restricted = new ArrayList<String>();

 		for (RepositoryModel repo : repositories) {

 			// exclude Owner or personal repositories

-			if (!repo.isOwner(username) && !repo.isUsersPersonalRepository(username)) {

+			if (!user.isOwner(repo)) {

 				if (repo.accessRestriction.exceeds(AccessRestrictionType.NONE)

 						&& repo.authorizationControl.equals(AuthorizationControl.NAMED)) {

 					restricted.add(repo.name);

@@ -456,7 +456,7 @@
 					permission.mutable = false;

 					continue;

 				}

-				boolean isOwner = rm.isOwner(username);

+				boolean isOwner = user.isOwner(rm);

 				if (isOwner) {

 					permission.permissionType = PermissionType.OWNER;

 					permission.mutable = false;

diff --git a/src/main/java/com/gitblit/client/GitblitClient.java b/src/main/java/com/gitblit/client/GitblitClient.java
index 66625a8..1477dac 100644
--- a/src/main/java/com/gitblit/client/GitblitClient.java
+++ b/src/main/java/com/gitblit/client/GitblitClient.java
@@ -162,7 +162,17 @@
 	}

 

 	public boolean isOwner(RepositoryModel model) {

-		return model.isOwner(account);

+		return getUser(account).isOwner(model);

+	}

+

+	public List<String> getOwners(RepositoryModel model) {

+		List<String> list = new ArrayList<String>();

+		for (UserModel user : allUsers) {

+			if (user.isOwner(model)) {

+				list.add(user.username);

+			}

+		}

+		return list;

 	}

 

 	public String getURL(String action, String repository, String objectId) {

@@ -529,10 +539,9 @@
 			}

 		}

 

-		// TODO reconsider ownership as a user property

 		// manually specify personal repository ownerships

 		for (RepositoryModel rm : allRepositories) {

-			if (rm.isUsersPersonalRepository(user.username) || rm.isOwner(user.username)) {

+			if (user.isOwner(rm)) {

 				RegistrantAccessPermission rp = new RegistrantAccessPermission(rm.name, AccessPermission.REWIND,

 						PermissionType.OWNER, RegistrantType.REPOSITORY, null, false);

 				// user may be owner of a repository to which they've inherited

@@ -660,13 +669,18 @@
 

 	public boolean updateRepository(String name, RepositoryModel repository,

 			List<RegistrantAccessPermission> userPermissions) throws IOException {

-		return updateRepository(name, repository, userPermissions, null);

+		return updateRepository(name, repository, null, userPermissions, null);

 	}

 

-	public boolean updateRepository(String name, RepositoryModel repository,

+	public boolean updateRepository(String name, RepositoryModel repository, List<String> owners,

 			List<RegistrantAccessPermission> userPermissions,	List<RegistrantAccessPermission> teamPermissions) throws IOException {

 		boolean success = true;

 		success &= RpcUtils.updateRepository(name, repository, url, account, password);

+		// set the repository owners

+		if (owners != null) {

+			success &= RpcUtils.setRepositoryOwners(repository, owners, url, account, password);

+		}

+

 		// set the repository members

 		if (userPermissions != null) {

 			success &= RpcUtils.setRepositoryMemberPermissions(repository, userPermissions, url, account,

diff --git a/src/main/java/com/gitblit/client/RepositoriesPanel.java b/src/main/java/com/gitblit/client/RepositoriesPanel.java
index 0fab934..7e3d96a 100644
--- a/src/main/java/com/gitblit/client/RepositoriesPanel.java
+++ b/src/main/java/com/gitblit/client/RepositoriesPanel.java
@@ -194,7 +194,6 @@
 

 		setRepositoryRenderer(RepositoriesTableModel.Columns.Name, nameRenderer, -1);

 		setRepositoryRenderer(RepositoriesTableModel.Columns.Indicators, typeRenderer, 100);

-		setRepositoryRenderer(RepositoriesTableModel.Columns.Owner, ownerRenderer, -1);

 		setRepositoryRenderer(RepositoriesTableModel.Columns.Size, sizeRenderer, 60);

 

 		table.getSelectionModel().addListSelectionListener(new ListSelectionListener() {

@@ -466,7 +465,8 @@
 		dialog.setLocationRelativeTo(RepositoriesPanel.this);

 		List<String> usernames = gitblit.getUsernames();

 		List<RegistrantAccessPermission> members = gitblit.getUserAccessPermissions(repository);

-		dialog.setUsers(new ArrayList<String>(repository.owners), usernames, members);

+		List<String> owners = gitblit.getOwners(repository);

+		dialog.setUsers(owners, usernames, members);

 		dialog.setTeams(gitblit.getTeamnames(), gitblit.getTeamAccessPermissions(repository));

 		dialog.setRepositories(gitblit.getRepositories());

 		dialog.setFederationSets(gitblit.getFederationSets(), repository.federationSets);

@@ -486,6 +486,7 @@
 		final RepositoryModel revisedRepository = dialog.getRepository();

 		final List<RegistrantAccessPermission> permittedUsers = dialog.getUserAccessPermissions();

 		final List<RegistrantAccessPermission> permittedTeams = dialog.getTeamAccessPermissions();

+		final List<String> newOwners = dialog.getOwners();

 		if (revisedRepository == null) {

 			return;

 		}

@@ -494,7 +495,7 @@
 

 			@Override

 			protected Boolean doRequest() throws IOException {

-				boolean success = gitblit.updateRepository(repository.name, revisedRepository,

+				boolean success = gitblit.updateRepository(repository.name, revisedRepository, newOwners,

 						permittedUsers, permittedTeams);

 				if (success) {

 					gitblit.refreshRepositories();

diff --git a/src/main/java/com/gitblit/client/RepositoriesTableModel.java b/src/main/java/com/gitblit/client/RepositoriesTableModel.java
index 0d26e42..f93f004 100644
--- a/src/main/java/com/gitblit/client/RepositoriesTableModel.java
+++ b/src/main/java/com/gitblit/client/RepositoriesTableModel.java
@@ -23,7 +23,6 @@
 import javax.swing.table.AbstractTableModel;

 

 import com.gitblit.models.RepositoryModel;

-import com.gitblit.utils.ArrayUtils;

 

 /**

  * Table model of a list of repositories.

@@ -38,7 +37,7 @@
 	List<RepositoryModel> list;

 

 	enum Columns {

-		Name, Description, Owner, Indicators, Last_Change, Size;

+		Name, Description, Indicators, Last_Change, Size;

 

 		@Override

 		public String toString() {

@@ -73,8 +72,6 @@
 			return Translation.get("gb.name");

 		case Description:

 			return Translation.get("gb.description");

-		case Owner:

-			return Translation.get("gb.owner");

 		case Last_Change:

 			return Translation.get("gb.lastChange");

 		case Size:

@@ -112,8 +109,6 @@
 			return model;

 		case Description:

 			return model.description;

-		case Owner:

-			return ArrayUtils.toString(model.owners);

 		case Indicators:

 			return model;

 		case Last_Change:

diff --git a/src/main/java/com/gitblit/git/GitblitReceivePack.java b/src/main/java/com/gitblit/git/GitblitReceivePack.java
index 34bbea2..0090930 100644
--- a/src/main/java/com/gitblit/git/GitblitReceivePack.java
+++ b/src/main/java/com/gitblit/git/GitblitReceivePack.java
@@ -286,7 +286,7 @@
 			} else if (ref.equals(BranchTicketService.BRANCH)) {

 				// ensure pushing user is an administrator OR an owner

 				// i.e. prevent ticket tampering

-				boolean permitted = user.canAdmin() || repository.isOwner(user.username);

+				boolean permitted = user.canAdmin() || user.isOwner(repository);

 				if (!permitted) {

 					sendRejection(cmd, "{0} is not permitted to push to {1}", user.username, ref);

 				}

diff --git a/src/main/java/com/gitblit/manager/GitblitManager.java b/src/main/java/com/gitblit/manager/GitblitManager.java
index 98ad33e..54ed0ed 100644
--- a/src/main/java/com/gitblit/manager/GitblitManager.java
+++ b/src/main/java/com/gitblit/manager/GitblitManager.java
@@ -62,6 +62,7 @@
 import com.gitblit.models.GitClientApplication;
 import com.gitblit.models.Mailing;
 import com.gitblit.models.Metric;
+import com.gitblit.models.Owner;
 import com.gitblit.models.PluginRegistry.InstallState;
 import com.gitblit.models.PluginRegistry.PluginRegistration;
 import com.gitblit.models.PluginRegistry.PluginRelease;
@@ -78,7 +79,6 @@
 import com.gitblit.tickets.ITicketService;
 import com.gitblit.transport.ssh.IPublicKeyManager;
 import com.gitblit.transport.ssh.SshKey;
-import com.gitblit.utils.ArrayUtils;
 import com.gitblit.utils.HttpUtils;
 import com.gitblit.utils.JsonUtils;
 import com.gitblit.utils.ObjectCache;
@@ -176,7 +176,7 @@
 	 */
 	@Override
 	public RepositoryModel fork(RepositoryModel repository, UserModel user) throws GitBlitException {
-		String cloneName = MessageFormat.format("{0}/{1}.git", user.getPersonalPath(), StringUtils.stripDotGit(StringUtils.getLastPathElement(repository.name)));
+		String cloneName = MessageFormat.format("{0}{1}.git", user.getPersonalPath(), StringUtils.stripDotGit(StringUtils.getLastPathElement(repository.name)));
 		String fromUrl = MessageFormat.format("file://{0}/{1}", repositoryManager.getRepositoriesFolder().getAbsolutePath(), repository.name);
 
 		// clone the repository
@@ -214,18 +214,20 @@
 
 		// create a Gitblit repository model for the clone
 		RepositoryModel cloneModel = repository.cloneAs(cloneName);
-		// owner has REWIND/RW+ permissions
-		cloneModel.addOwner(user.username);
 		repositoryManager.updateRepositoryModel(cloneName, cloneModel, false);
 
-		// add the owner of the source repository to the clone's access list
-		if (!ArrayUtils.isEmpty(repository.owners)) {
-			for (String owner : repository.owners) {
-				UserModel originOwner = userManager.getUserModel(owner);
-				if (originOwner != null && !originOwner.canClone(cloneModel)) {
+		// owner has REWIND/RW+ permissions
+		user.own(cloneModel);
+		reviseUser(user.username, user);
+
+		// add the owners of the source repository to the clone's access list
+		for (Owner owner : getOwners(repository)) {
+			if (owner instanceof UserModel) {
+				UserModel userOwner = (UserModel) owner;
+				if (!userOwner.canClone(cloneModel)) {
 					// origin owner can't yet clone fork, grant explicit clone access
-					originOwner.setRepositoryPermission(cloneName, AccessPermission.CLONE);
-					reviseUser(originOwner.username, originOwner);
+					userOwner.setRepositoryPermission(cloneName, AccessPermission.CLONE);
+					reviseUser(userOwner.username, userOwner);
 				}
 			}
 		}
@@ -325,22 +327,6 @@
 						user.username));
 			}
 
-			// rename repositories and owner fields for all repositories
-			for (RepositoryModel model : repositoryManager.getRepositoryModels(user)) {
-				if (model.isUsersPersonalRepository(username)) {
-					// personal repository
-					model.addOwner(user.username);
-					String oldRepositoryName = model.name;
-					model.name = user.getPersonalPath() + model.name.substring(model.projectPath.length());
-					model.projectPath = user.getPersonalPath();
-					repositoryManager.updateRepositoryModel(oldRepositoryName, model, false);
-				} else if (model.isOwner(username)) {
-					// common/shared repo
-					model.addOwner(user.username);
-					repositoryManager.updateRepositoryModel(model.name, model, false);
-				}
-			}
-
 			// rename the user's ssh public keystore
 			getPublicKeyManager().renameUser(username, user.username);
 		}
@@ -880,6 +866,16 @@
 		return userManager.deleteTeam(teamname);
 	}
 
+	@Override
+	public List<Owner> getOwners(RepositoryModel repository) {
+		return userManager.getOwners(repository);
+	}
+
+	@Override
+	public boolean setOwners(RepositoryModel repository, List<Owner> owners) {
+		return userManager.setOwners(repository, owners);
+	}
+
 	/*
 	 * REPOSITORY MANAGER
 	 */
diff --git a/src/main/java/com/gitblit/manager/IUserManager.java b/src/main/java/com/gitblit/manager/IUserManager.java
index b7ea9c4..8f96900 100644
--- a/src/main/java/com/gitblit/manager/IUserManager.java
+++ b/src/main/java/com/gitblit/manager/IUserManager.java
@@ -15,7 +15,11 @@
  */
 package com.gitblit.manager;
 
+import java.util.List;
+
 import com.gitblit.IUserService;
+import com.gitblit.models.Owner;
+import com.gitblit.models.RepositoryModel;
 
 public interface IUserManager extends IManager, IUserService {
 
@@ -28,4 +32,32 @@
 	 */
 	boolean isInternalAccount(String username);
 
+	/**
+	 * Returns the list of repository owners.
+	 *
+	 * @param repository
+	 * @return a list of owners
+	 * @since 1.6.0
+	 */
+	List<Owner> getOwners(RepositoryModel repository);
+
+	/**
+	 * Sets the repository owners.
+	 *
+	 * @param repository
+	 * @param a list of owners
+	 * @return true if successful
+	 * @since 1.6.0
+	 */
+	boolean setOwners(RepositoryModel repository, List<Owner> owners);
+
+//	/**
+//	 * Returns the list of project owners.
+//	 *
+//	 * @param project
+//	 * @return a list of owners
+//	 * @since 1.6.0
+//	 */
+//	List<RepositoryOwner> getOwners(ProjectModel project);
+//
 }
\ No newline at end of file
diff --git a/src/main/java/com/gitblit/manager/ProjectManager.java b/src/main/java/com/gitblit/manager/ProjectManager.java
index b30f4f1..0eb0b11 100644
--- a/src/main/java/com/gitblit/manager/ProjectManager.java
+++ b/src/main/java/com/gitblit/manager/ProjectManager.java
@@ -298,14 +298,14 @@
 				// exclude personal repositories
 				continue;
 			}
-			if (!projects.containsKey(repository.projectPath)) {
-				ProjectModel project = getProjectModel(repository.projectPath);
+			if (!projects.containsKey(repository.getProject())) {
+				ProjectModel project = getProjectModel(repository.getProject());
 				if (project == null) {
 					logger.warn(MessageFormat.format("excluding project \"{0}\" from project list because it is empty!",
-							repository.projectPath));
+							repository.getProject()));
 					continue;
 				}
-				projects.put(repository.projectPath, project);
+				projects.put(repository.getProject(), project);
 				// clear the repo list in the project because that is the system
 				// list, not the user-accessible list and start building the
 				// user-accessible list
@@ -315,7 +315,7 @@
 			} else {
 				// update the user-accessible list
 				// this is used for repository count
-				ProjectModel project = projects.get(repository.projectPath);
+				ProjectModel project = projects.get(repository.getProject());
 				project.repositories.add(repository.name);
 				if (project.lastChange.before(repository.lastChange)) {
 					project.lastChange = repository.lastChange;
diff --git a/src/main/java/com/gitblit/manager/RepositoryManager.java b/src/main/java/com/gitblit/manager/RepositoryManager.java
index e0721c7..29a63ea 100644
--- a/src/main/java/com/gitblit/manager/RepositoryManager.java
+++ b/src/main/java/com/gitblit/manager/RepositoryManager.java
@@ -277,10 +277,9 @@
 			}
 		}
 
-		// TODO reconsider ownership as a user property
 		// manually specify personal repository ownerships
 		for (RepositoryModel rm : repositoryListCache.values()) {
-			if (rm.isUsersPersonalRepository(user.username) || rm.isOwner(user.username)) {
+			if (user.isOwner(rm)) {
 				RegistrantAccessPermission rp = new RegistrantAccessPermission(rm.name, AccessPermission.REWIND,
 						PermissionType.OWNER, RegistrantType.REPOSITORY, null, false);
 				// user may be owner of a repository to which they've inherited
@@ -791,20 +790,23 @@
 		if (r == null) {
 			return null;
 		}
-		RepositoryModel model = new RepositoryModel();
-		model.isBare = r.isBare();
+
+		String name;
 		File basePath = getRepositoriesFolder();
-		if (model.isBare) {
-			model.name = com.gitblit.utils.FileUtils.getRelativePath(basePath, r.getDirectory());
+		if (r.isBare()) {
+			name = com.gitblit.utils.FileUtils.getRelativePath(basePath, r.getDirectory());
 		} else {
-			model.name = com.gitblit.utils.FileUtils.getRelativePath(basePath, r.getDirectory().getParentFile());
+			name = com.gitblit.utils.FileUtils.getRelativePath(basePath, r.getDirectory().getParentFile());
 		}
-		if (StringUtils.isEmpty(model.name)) {
+
+		if (StringUtils.isEmpty(name)) {
 			// Repository is NOT located relative to the base folder because it
 			// is symlinked.  Use the provided repository name.
-			model.name = repositoryName;
+			name = repositoryName;
 		}
-		model.projectPath = StringUtils.getFirstPathElement(repositoryName);
+
+		RepositoryModel model = new RepositoryModel(name);
+		model.isBare = r.isBare();
 
 		StoredConfig config = r.getConfig();
 		boolean hasOrigin = false;
@@ -823,7 +825,7 @@
 			}
 			model.description = getConfig(config, "description", "");
 			model.originRepository = getConfig(config, "originRepository", null);
-			model.addOwners(ArrayUtils.fromString(getConfig(config, "owner", "")));
+//			model.addOwners(ArrayUtils.fromString(getConfig(config, "owner", "")));
 			model.acceptNewPatchsets = getConfig(config, "acceptNewPatchsets", true);
 			model.acceptNewTickets = getConfig(config, "acceptNewTickets", true);
 			model.requireApproval = getConfig(config, "requireApproval", settings.getBoolean(Keys.tickets.requireApproval, false));
@@ -968,10 +970,9 @@
 		if (StringUtils.isEmpty(origin)) {
 			return null;
 		}
-		String userProject = ModelUtils.getPersonalPath(username);
+		String userPath = ModelUtils.getPersonalPath(username);
 		if (settings.getBoolean(Keys.git.cacheRepositoryList, true)) {
 			String originKey = origin.toLowerCase();
-			String userPath = userProject + "/";
 
 			// collect all origin nodes in fork network
 			Set<String> roots = new HashSet<String>();
@@ -1009,6 +1010,7 @@
 			}
 		} else {
 			// not caching
+			String userProject = ModelUtils.getPersonalProject(username);
 			File subfolder = new File(getRepositoriesFolder(), userProject);
 			List<String> repositories = JGitUtils.getRepositoryList(subfolder,
 					settings.getBoolean(Keys.git.onlyAccessBareRepositories, false),
@@ -1016,7 +1018,7 @@
 					settings.getInteger(Keys.git.searchRecursionDepth, -1),
 					settings.getStrings(Keys.git.searchExclusions));
 			for (String repository : repositories) {
-				RepositoryModel model = getRepositoryModel(userProject + "/" + repository);
+				RepositoryModel model = getRepositoryModel(userPath + repository);
 				if (model.originRepository != null && model.originRepository.equalsIgnoreCase(origin)) {
 					// user has a fork
 					return model.name;
@@ -1450,7 +1452,7 @@
 		StoredConfig config = r.getConfig();
 		config.setString(Constants.CONFIG_GITBLIT, null, "description", repository.description);
 		config.setString(Constants.CONFIG_GITBLIT, null, "originRepository", repository.originRepository);
-		config.setString(Constants.CONFIG_GITBLIT, null, "owner", ArrayUtils.toString(repository.owners));
+//		config.setString(Constants.CONFIG_GITBLIT, null, "owner", ArrayUtils.toString(repository.owners));
 		config.setBoolean(Constants.CONFIG_GITBLIT, null, "acceptNewPatchsets", repository.acceptNewPatchsets);
 		config.setBoolean(Constants.CONFIG_GITBLIT, null, "acceptNewTickets", repository.acceptNewTickets);
 		if (settings.getBoolean(Keys.tickets.requireApproval, false) == repository.requireApproval) {
diff --git a/src/main/java/com/gitblit/manager/UserManager.java b/src/main/java/com/gitblit/manager/UserManager.java
index 2b82ffb..617c81b 100644
--- a/src/main/java/com/gitblit/manager/UserManager.java
+++ b/src/main/java/com/gitblit/manager/UserManager.java
@@ -33,6 +33,8 @@
 import com.gitblit.IUserService;
 import com.gitblit.Keys;
 import com.gitblit.extensions.UserTeamLifeCycleListener;
+import com.gitblit.models.Owner;
+import com.gitblit.models.RepositoryModel;
 import com.gitblit.models.TeamModel;
 import com.gitblit.models.UserModel;
 import com.gitblit.utils.StringUtils;
@@ -491,6 +493,60 @@
 		return userService.deleteRepositoryRole(role);
 	}
 
+	/**
+	 * Returns the list of owners for the repository.
+	 *
+	 * @param repository
+	 * @return a list of owners
+	 */
+	@Override
+	public List<Owner> getOwners(RepositoryModel repository) {
+		List<Owner> list = new ArrayList<>();
+		for (UserModel user : getAllUsers()) {
+			if (user.isOwner(repository)) {
+				list.add(user);
+			}
+		}
+		return list;
+	}
+
+	/**
+	 * Set the repository owners.
+	 *
+	 * @param repository
+	 * @param a list of owners
+	 * @return true if successful
+	 */
+	@Override
+	public boolean setOwners(RepositoryModel repository, List<Owner> owners) {
+		List<Owner> oldOwners = getOwners(repository);
+		List<UserModel> users = new ArrayList<>();
+
+		// identify new owners and filter-out continued owners
+		for (Owner owner : owners) {
+			if (!oldOwners.remove(owner)) {
+				// new owner
+				owner.own(repository);
+				if (owner instanceof UserModel) {
+					users.add((UserModel) owner);
+				}
+			}
+		}
+
+		// the remaining oldOwners are now former owners
+		for (Owner formerOwner : oldOwners) {
+			formerOwner.disown(repository);
+
+			if (formerOwner instanceof UserModel) {
+				users.add((UserModel) formerOwner);
+			}
+		}
+
+		updateUserModels(users);
+
+		return true;
+	}
+
 	protected void callCreateUserListeners(UserModel user) {
 		if (pluginManager == null || user == null) {
 			return;
diff --git a/src/main/java/com/gitblit/models/Owner.java b/src/main/java/com/gitblit/models/Owner.java
new file mode 100644
index 0000000..c05a596
--- /dev/null
+++ b/src/main/java/com/gitblit/models/Owner.java
@@ -0,0 +1,90 @@
+/*
+ * 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.models;
+
+import java.io.Serializable;
+import java.util.Set;
+import java.util.TreeSet;
+
+import com.gitblit.utils.StringUtils;
+
+/**
+ * The owner class defines the ownership method contract for an object.
+ *
+ * @author James Moger
+ *
+ */
+public abstract class Owner implements Serializable {
+
+	private static final long serialVersionUID = 1L;
+
+	public final Set<String> ownedPaths = new TreeSet<String>();
+
+	public abstract String getId();
+
+	public abstract String getDisplayName();
+
+	public abstract String getPersonalPath();
+
+	public boolean isOwner(String path) {
+		if (StringUtils.isEmpty(path)) {
+			return false;
+		}
+
+		String personalPath = getPersonalPath();
+		if (personalPath != null && path.startsWith(personalPath)) {
+			return true;
+		}
+
+		if (ownedPaths == null) {
+			return false;
+		}
+
+		if (ownedPaths.contains(path.toLowerCase())) {
+			// exact path match
+			return true;
+		}
+
+		for (String ownedPath : ownedPaths) {
+			if (StringUtils.matchesIgnoreCase(path, ownedPath)) {
+				// regex match
+				return true;
+			}
+		}
+
+		return false;
+	}
+
+	public void own(String path) {
+		ownedPaths.add(path.toLowerCase());
+	}
+
+	public void disown(String path) {
+		ownedPaths.remove(path.toLowerCase());
+	}
+
+	public boolean isOwner(RepositoryModel repository) {
+		return isOwner(repository.name);
+	}
+
+	public void own(RepositoryModel repository) {
+		own(repository.name);
+	}
+
+	public void disown(RepositoryModel repository) {
+		disown(repository.name);
+	}
+}
diff --git a/src/main/java/com/gitblit/models/RepositoryModel.java b/src/main/java/com/gitblit/models/RepositoryModel.java
index a81c622..78e9728 100644
--- a/src/main/java/com/gitblit/models/RepositoryModel.java
+++ b/src/main/java/com/gitblit/models/RepositoryModel.java
@@ -17,7 +17,6 @@
 

 import java.io.Serializable;

 import java.util.ArrayList;

-import java.util.Collection;

 import java.util.Date;

 import java.util.List;

 import java.util.Map;

@@ -46,7 +45,6 @@
 	// field names are reflectively mapped in EditRepository page

 	public String name;

 	public String description;

-	public List<String> owners;

 	public Date lastChange;

 	public String lastChangeAuthor;

 	public boolean hasCommits;

@@ -74,7 +72,7 @@
 	public List<String> postReceiveScripts;

 	public List<String> mailingLists;

 	public Map<String, String> customFields;

-	public String projectPath;

+	private String projectPath;

 	private String displayName;

 	public boolean allowForks;

 	public Set<String> forks;

@@ -95,11 +93,17 @@
 	public String sparkleshareId;

 

 	public RepositoryModel() {

-		this("", "", "", new Date(0));

+		this("", "", new Date(0));

 	}

 

-	public RepositoryModel(String name, String description, String owner, Date lastchange) {

+	public RepositoryModel(String name ) {

 		this.name = name;

+		this.projectPath = StringUtils.getFirstPathElement(name);

+	}

+

+	public RepositoryModel(String name, String description, Date lastchange) {

+		this.name = name;

+		this.projectPath = StringUtils.getFirstPathElement(name);

 		this.description = description;

 		this.lastChange = lastchange;

 		this.accessRestriction = AccessRestrictionType.NONE;

@@ -107,12 +111,9 @@
 		this.federationSets = new ArrayList<String>();

 		this.federationStrategy = FederationStrategy.FEDERATE_THIS;

 		this.projectPath = StringUtils.getFirstPathElement(name);

-		this.owners = new ArrayList<String>();

 		this.isBare = true;

 		this.acceptNewTickets = true;

 		this.acceptNewPatchsets = true;

-

-		addOwner(owner);

 	}

 

 	public List<String> getLocalBranches() {

@@ -180,19 +181,31 @@
 		return !StringUtils.isEmpty(originRepository);

 	}

 

-	public boolean isOwner(String username) {

-		if (StringUtils.isEmpty(username) || ArrayUtils.isEmpty(owners)) {

-			return isUsersPersonalRepository(username);

-		}

-		return owners.contains(username.toLowerCase()) || isUsersPersonalRepository(username);

-	}

-

 	public boolean isPersonalRepository() {

 		return !StringUtils.isEmpty(projectPath) && ModelUtils.isPersonalRepository(projectPath);

 	}

 

-	public boolean isUsersPersonalRepository(String username) {

-		return !StringUtils.isEmpty(projectPath) && ModelUtils.isUsersPersonalRepository(username, projectPath);

+	public String getPersonalRepositoryOwner() {

+		return ModelUtils.getUserNameFromRepoPath(projectPath);

+	}

+

+	/**

+	 * Returns the project name.

+	 *

+	 * @return project name

+	 */

+	public String getProject() {

+		return projectPath;

+	}

+

+	/**

+	 * Returns the first path element of the full repository path.  This path will always end with

+	 * a trailing '/'.

+	 *

+	 * @return the project path of the repository

+	 */

+	public String getProjectPath() {

+		return StringUtils.isEmpty(projectPath) ? "/" : (projectPath + "/");

 	}

 

 	public boolean allowAnonymousView() {

@@ -226,37 +239,4 @@
 		clone.sparkleshareId = sparkleshareId;

 		return clone;

 	}

-

-	public void addOwner(String username) {

-		if (!StringUtils.isEmpty(username)) {

-			String name = username.toLowerCase();

-			// a set would be more efficient, but this complicates JSON

-			// deserialization so we enforce uniqueness with an arraylist

-			if (!owners.contains(name)) {

-				owners.add(name);

-			}

-		}

-	}

-

-	public void removeOwner(String username) {

-		if (!StringUtils.isEmpty(username)) {

-			owners.remove(username.toLowerCase());

-		}

-	}

-

-	public void addOwners(Collection<String> usernames) {

-		if (!ArrayUtils.isEmpty(usernames)) {

-			for (String username : usernames) {

-				addOwner(username);

-			}

-		}

-	}

-

-	public void removeOwners(Collection<String> usernames) {

-		if (!ArrayUtils.isEmpty(owners)) {

-			for (String username : usernames) {

-				removeOwner(username);

-			}

-		}

-	}

 }
diff --git a/src/main/java/com/gitblit/models/UserModel.java b/src/main/java/com/gitblit/models/UserModel.java
index e152274..a70f852 100644
--- a/src/main/java/com/gitblit/models/UserModel.java
+++ b/src/main/java/com/gitblit/models/UserModel.java
@@ -46,7 +46,7 @@
  * @author James Moger

  *

  */

-public class UserModel implements Principal, Serializable, Comparable<UserModel> {

+public class UserModel extends Owner implements Principal, Serializable, Comparable<UserModel> {

 

 	private static final long serialVersionUID = 1L;

 

@@ -94,6 +94,11 @@
 		this.userPreferences = new UserPreferences(this.username);

 	}

 

+	@Override

+	public String getId() {

+		return username;

+	}

+

 	public boolean isLocalAccount() {

 		return !Constants.EXTERNAL_ACCOUNT.equals(password)

 				|| accountType == null

@@ -279,7 +284,7 @@
 		}

 

 		// repository owner - either specified owner or personal repository

-		if (repository.isOwner(username) || repository.isUsersPersonalRepository(username)) {

+		if (isOwner(repository)) {

 			ap.permissionType = PermissionType.OWNER;

 			if (AccessPermission.REWIND.atMost(maxPermission)) {

 				ap.permission = AccessPermission.REWIND;

@@ -423,11 +428,11 @@
 	}

 

 	public boolean canFork(RepositoryModel repository) {

-		if (repository.isUsersPersonalRepository(username)) {

+		if (isMyPersonalRepository(repository.name)) {

 			// can not fork your own repository

 			return false;

 		}

-		if (canAdmin() || repository.isOwner(username)) {

+		if (canAdmin() || isOwner(repository)) {

 			return true;

 		}

 		if (!repository.allowForks) {

@@ -440,11 +445,13 @@
 	}

 

 	public boolean canDelete(RepositoryModel model) {

-		return canAdmin() || model.isUsersPersonalRepository(username);

+		return canAdmin()

+				|| isMyPersonalRepository(model.name)

+				|| (!model.isPersonalRepository() && isOwner(model));

 	}

 

 	public boolean canEdit(RepositoryModel model) {

-		return canAdmin() || model.isUsersPersonalRepository(username) || model.isOwner(username);

+		return canAdmin() || isOwner(model);

 	}

 

 	public boolean canEdit(TicketModel ticket, RepositoryModel repository) {

@@ -544,15 +551,22 @@
 			return true;

 		}

 		if (canCreate()) {

-			String projectPath = StringUtils.getFirstPathElement(repository);

-			if (!StringUtils.isEmpty(projectPath) && projectPath.equalsIgnoreCase(getPersonalPath())) {

-				// personal repository

-				return true;

-			}

+			String projectPath = StringUtils.getFirstPathElement(repository) + "/";

+			return isOwner(projectPath);

 		}

 		return false;

 	}

 

+//	/**

+//	 * Returns true if the user is allowed to administer the specified project

+//	 *

+//	 * @param project

+//	 * @return true if the user can administer the project

+//	 */

+//	public boolean canAdmin(ProjectModel project) {

+//		return canAdmin() || isOwner(project);

+//	}

+//

 	/**

 	 * Returns true if the user is allowed to administer the specified repository

 	 *

@@ -560,7 +574,7 @@
 	 * @return true if the user can administer the repository

 	 */

 	public boolean canAdmin(RepositoryModel repo) {

-		return canAdmin() || repo.isOwner(username) || isMyPersonalRepository(repo.name);

+		return canAdmin() || isOwner(repo);

 	}

 

 	public boolean isAuthenticated() {

@@ -593,6 +607,7 @@
 		return username;

 	}

 

+	@Override

 	public String getDisplayName() {

 		if (StringUtils.isEmpty(displayName)) {

 			return username;

@@ -600,6 +615,7 @@
 		return displayName;

 	}

 

+	@Override

 	public String getPersonalPath() {

 		return ModelUtils.getPersonalPath(username);

 	}

@@ -657,7 +673,31 @@
 	}

 

 	public boolean isMyPersonalRepository(String repository) {

-		String projectPath = StringUtils.getFirstPathElement(repository);

-		return !StringUtils.isEmpty(projectPath) && projectPath.equalsIgnoreCase(getPersonalPath());

+		return repository.startsWith(getPersonalPath());

 	}

+

+	@Override

+	public boolean isOwner(RepositoryModel repository) {

+		return isMyPersonalRepository(repository.name)

+				|| isOwner(repository.name);

+	}

+//	public boolean isOwner(ProjectModel project) {

+//	return isOwner(project.name + "/");

+//}

+//

+//	public void own(ProjectModel project) {

+//		if (StringUtils.isEmpty(project.name)) {

+//			own("/");

+//		} else {

+//			own(project.name.toLowerCase() + "/");

+//		}

+//	}

+//

+//	public void disown(ProjectModel project) {

+//		if (StringUtils.isEmpty(project.name)) {

+//			disown("/");

+//		} else {

+//			disown(project.name.toLowerCase() + "/");

+//		}

+//	}

 }

diff --git a/src/main/java/com/gitblit/servlet/GitFilter.java b/src/main/java/com/gitblit/servlet/GitFilter.java
index bb3d321..d9c1c08 100644
--- a/src/main/java/com/gitblit/servlet/GitFilter.java
+++ b/src/main/java/com/gitblit/servlet/GitFilter.java
@@ -26,6 +26,7 @@
 import com.gitblit.IStoredSettings;

 import com.gitblit.Keys;

 import com.gitblit.manager.IFederationManager;

+import com.gitblit.manager.IUserManager;

 import com.gitblit.models.RepositoryModel;

 import com.gitblit.models.UserModel;

 import com.gitblit.utils.StringUtils;

@@ -51,12 +52,15 @@
 

 	private IStoredSettings settings;

 

+	private IUserManager userManager;

+

 	private IFederationManager federationManager;

 

 	@Override

 	protected void inject(ObjectGraph dagger, FilterConfig filterConfig) {

 		super.inject(dagger, filterConfig);

 		this.settings = dagger.get(IStoredSettings.class);

+		this.userManager = dagger.get(IUserManager.class);

 		this.federationManager = dagger.get(IFederationManager.class);

 	}

 

@@ -241,11 +245,8 @@
 				}

 

 				// create repository

-				RepositoryModel model = new RepositoryModel();

-				model.name = repository;

-				model.addOwner(user.username);

-				model.projectPath = StringUtils.getFirstPathElement(repository);

-				if (model.isUsersPersonalRepository(user.username)) {

+				RepositoryModel model = new RepositoryModel(repository);

+				if (user.isMyPersonalRepository(model.name)) {

 					// personal repository, default to private for user

 					model.authorizationControl = AuthorizationControl.NAMED;

 					model.accessRestriction = AccessRestrictionType.VIEW;

@@ -258,6 +259,8 @@
 				// create the repository

 				try {

 					repositoryManager.updateRepositoryModel(model.name, model, true);

+					user.own(model);

+					userManager.updateUserModel(user.username, user);

 					logger.info(MessageFormat.format("{0} created {1} ON-PUSH", user.username, model.name));

 					return repositoryManager.getRepositoryModel(model.name);

 				} catch (GitBlitException e) {

diff --git a/src/main/java/com/gitblit/servlet/RpcServlet.java b/src/main/java/com/gitblit/servlet/RpcServlet.java
index b8cdfb0..e09e921 100644
--- a/src/main/java/com/gitblit/servlet/RpcServlet.java
+++ b/src/main/java/com/gitblit/servlet/RpcServlet.java
@@ -38,6 +38,7 @@
 import com.gitblit.models.RefModel;

 import com.gitblit.models.RegistrantAccessPermission;

 import com.gitblit.models.RepositoryModel;

+import com.gitblit.models.Owner;

 import com.gitblit.models.ServerSettings;

 import com.gitblit.models.TeamModel;

 import com.gitblit.models.UserModel;

@@ -300,6 +301,29 @@
 		} else if (RpcRequest.SET_REPOSITORY_MEMBERS.equals(reqType)) {

 			// rejected since 1.2.0

 			response.setStatus(failureCode);

+		} else if (RpcRequest.LIST_REPOSITORY_OWNERS.equals(reqType)) {

+			// get repository owners

+			RepositoryModel model = gitblit.getRepositoryModel(objectName);

+			List<Owner> owners = gitblit.getOwners(model);

+			List<String> names = new ArrayList<>();

+			for (Owner owner : owners) {

+				if (owner instanceof UserModel) {

+					names.add(((UserModel) owner).username);

+				}

+			}

+			result = names;

+		} else if (RpcRequest.SET_REPOSITORY_OWNERS.equals(reqType)) {

+			// set the owners for the specified repository

+			RepositoryModel model = gitblit.getRepositoryModel(objectName);

+			Collection<String> names = deserialize(request, response, RpcUtils.NAMES_TYPE);

+			List<Owner> owners = new ArrayList<>();

+			for (String name : names) {

+				UserModel owner = gitblit.getUserModel(name);

+				if (owner != null) {

+					owners.add(owner);

+				}

+			}

+			result = gitblit.setOwners(model, owners);

 		} else if (RpcRequest.LIST_REPOSITORY_MEMBER_PERMISSIONS.equals(reqType)) {

 			// get repository member permissions

 			RepositoryModel model = gitblit.getRepositoryModel(objectName);

diff --git a/src/main/java/com/gitblit/tickets/BranchTicketService.java b/src/main/java/com/gitblit/tickets/BranchTicketService.java
index 8c00055..448014f 100644
--- a/src/main/java/com/gitblit/tickets/BranchTicketService.java
+++ b/src/main/java/com/gitblit/tickets/BranchTicketService.java
@@ -494,7 +494,7 @@
 						continue;
 					}
 					TicketModel ticket = TicketModel.buildTicket(changes);
-					ticket.project = repository.projectPath;
+					ticket.project = repository.getProject();
 					ticket.repository = repository.name;
 					ticket.number = ticketId;
 
@@ -540,7 +540,7 @@
 			}
 			TicketModel ticket = TicketModel.buildTicket(changes);
 			if (ticket != null) {
-				ticket.project = repository.projectPath;
+				ticket.project = repository.getProject();
 				ticket.repository = repository.name;
 				ticket.number = ticketId;
 			}
diff --git a/src/main/java/com/gitblit/tickets/FileTicketService.java b/src/main/java/com/gitblit/tickets/FileTicketService.java
index b3d8838..33b5307 100644
--- a/src/main/java/com/gitblit/tickets/FileTicketService.java
+++ b/src/main/java/com/gitblit/tickets/FileTicketService.java
@@ -257,7 +257,7 @@
 						continue;
 					}
 					TicketModel ticket = TicketModel.buildTicket(changes);
-					ticket.project = repository.projectPath;
+					ticket.project = repository.getProject();
 					ticket.repository = repository.name;
 					ticket.number = ticketId;
 
@@ -320,7 +320,7 @@
 			}
 			TicketModel ticket = TicketModel.buildTicket(changes);
 			if (ticket != null) {
-				ticket.project = repository.projectPath;
+				ticket.project = repository.getProject();
 				ticket.repository = repository.name;
 				ticket.number = ticketId;
 			}
diff --git a/src/main/java/com/gitblit/tickets/RedisTicketService.java b/src/main/java/com/gitblit/tickets/RedisTicketService.java
index d773b0b..465bda3 100644
--- a/src/main/java/com/gitblit/tickets/RedisTicketService.java
+++ b/src/main/java/com/gitblit/tickets/RedisTicketService.java
@@ -276,7 +276,7 @@
 					continue;
 				}
 				TicketModel ticket = TicketModel.buildTicket(changes);
-				ticket.project = repository.projectPath;
+				ticket.project = repository.getProject();
 				ticket.repository = repository.name;
 				ticket.number = ticketId;
 
@@ -325,7 +325,7 @@
 				return null;
 			}
 			TicketModel ticket = TicketModel.buildTicket(changes);
-			ticket.project = repository.projectPath;
+			ticket.project = repository.getProject();
 			ticket.repository = repository.name;
 			ticket.number = ticketId;
 			log.debug("rebuilt ticket {} from Redis @ {}", ticketId, getUrl());
diff --git a/src/main/java/com/gitblit/tickets/TicketNotifier.java b/src/main/java/com/gitblit/tickets/TicketNotifier.java
index 07371b1..d430710 100644
--- a/src/main/java/com/gitblit/tickets/TicketNotifier.java
+++ b/src/main/java/com/gitblit/tickets/TicketNotifier.java
@@ -49,6 +49,7 @@
 import com.gitblit.manager.IRuntimeManager;
 import com.gitblit.manager.IUserManager;
 import com.gitblit.models.Mailing;
+import com.gitblit.models.Owner;
 import com.gitblit.models.PathModel.PathChangeModel;
 import com.gitblit.models.RepositoryModel;
 import com.gitblit.models.TicketModel;
@@ -551,11 +552,6 @@
 		//
 		Set<String> ccs = new TreeSet<String>();
 
-		// repository owners
-		if (!ArrayUtils.isEmpty(repository.owners)) {
-			ccs.addAll(repository.owners);
-		}
-
 		// cc users mentioned in last comment
 		Change lastChange = ticket.changes.get(ticket.changes.size() - 1);
 		if (lastChange.hasComment()) {
@@ -573,6 +569,7 @@
 		// TODO cc users who are watching the repository
 
 		Set<String> ccAddresses = new TreeSet<String>();
+
 		for (String name : ccs) {
 			UserModel user = userManager.getUserModel(name);
 			if (user != null && !user.disabled) {
@@ -588,6 +585,16 @@
 			}
 		}
 
+		// repository owners
+		for (Owner owner : userManager.getOwners(repository)) {
+			if (owner instanceof UserModel) {
+				UserModel user = (UserModel) owner;
+				if (!StringUtils.isEmpty(user.emailAddress)) {
+					ccAddresses.add(user.emailAddress);
+				}
+			}
+		}
+
 		// cc repository mailing list addresses
 		if (!ArrayUtils.isEmpty(repository.mailingLists)) {
 			ccAddresses.addAll(repository.mailingLists);
diff --git a/src/main/java/com/gitblit/utils/ModelUtils.java b/src/main/java/com/gitblit/utils/ModelUtils.java
index 6fb4c0a..74e97ab 100644
--- a/src/main/java/com/gitblit/utils/ModelUtils.java
+++ b/src/main/java/com/gitblit/utils/ModelUtils.java
@@ -56,6 +56,16 @@
 		return userRepoPrefix;
 	}
 
+	/**
+	 * Get the user project name for a user.
+	 *
+	 * @param username name of user
+	 * @return the active user repository project prefix concatenated with the user name
+	 */
+	public static String getPersonalProject(String username)
+	{
+		return userRepoPrefix + username.toLowerCase();
+	}
 
 	/**
 	 * Get the user project name for a user.
@@ -65,7 +75,7 @@
 	 */
 	public static String getPersonalPath(String username)
 	{
-		return userRepoPrefix + username.toLowerCase();
+		return userRepoPrefix + username.toLowerCase() + "/";
 	}
 
 
diff --git a/src/main/java/com/gitblit/utils/RpcUtils.java b/src/main/java/com/gitblit/utils/RpcUtils.java
index 8220215..21841ac 100644
--- a/src/main/java/com/gitblit/utils/RpcUtils.java
+++ b/src/main/java/com/gitblit/utils/RpcUtils.java
@@ -461,6 +461,41 @@
 	}

 

 	/**

+	 * Retrieves the list of owners for the specified repository.

+	 *

+	 * @param repository

+	 * @param serverUrl

+	 * @param account

+	 * @param password

+	 * @return list of owners

+	 * @throws IOException

+	 */

+	public static List<String> getRepositoryOwners(RepositoryModel repository,

+			String serverUrl, String account, char [] password) throws IOException {

+		String url = asLink(serverUrl, RpcRequest.LIST_REPOSITORY_OWNERS, repository.name);

+		Collection<String> list = JsonUtils.retrieveJson(url, NAMES_TYPE, account, password);

+		return new ArrayList<String>(list);

+	}

+

+	/**

+	 * Sets the repository owners

+	 *

+	 * @param repository

+	 * @param owners

+	 * @param serverUrl

+	 * @param account

+	 * @param password

+	 * @return true if the action succeeded

+	 * @throws IOException

+	 */

+	public static boolean setRepositoryOwners(RepositoryModel repository,

+			List<String> owners, String serverUrl, String account, char[] password)

+			throws IOException {

+		return doAction(RpcRequest.SET_REPOSITORY_OWNERS, repository.name, owners, serverUrl,

+				account, password);

+	}

+

+	/**

 	 * Retrieves the list of teams that can access the specified repository.

 	 *

 	 * @param repository

diff --git a/src/main/java/com/gitblit/wicket/pages/EditRepositoryPage.java b/src/main/java/com/gitblit/wicket/pages/EditRepositoryPage.java
index a1c3738..85ee55f 100644
--- a/src/main/java/com/gitblit/wicket/pages/EditRepositoryPage.java
+++ b/src/main/java/com/gitblit/wicket/pages/EditRepositoryPage.java
@@ -59,6 +59,7 @@
 import com.gitblit.Constants.RegistrantType;

 import com.gitblit.GitBlitException;

 import com.gitblit.Keys;

+import com.gitblit.models.Owner;

 import com.gitblit.models.RegistrantAccessPermission;

 import com.gitblit.models.RepositoryModel;

 import com.gitblit.models.UserChoice;

@@ -107,9 +108,8 @@
 		UserModel user = session.getUser();

 		if (user != null && user.canCreate() && !user.canAdmin()) {

 			// personal create permissions, inject personal repository path

-			model.name = user.getPersonalPath() + "/";

-			model.projectPath = user.getPersonalPath();

-			model.addOwner(user.username);

+			model.name = user.getPersonalPath();

+

 			// personal repositories are private by default

 			model.accessRestriction = AccessRestrictionType.VIEW;

 			model.authorizationControl = AuthorizationControl.NAMED;

@@ -156,7 +156,6 @@
 

 		GitBlitWebSession session = GitBlitWebSession.get();

 		final UserModel user = session.getUser() == null ? UserModel.ANONYMOUS : session.getUser();

-		final boolean allowEditName = isCreate || isAdmin || repositoryModel.isUsersPersonalRepository(user.username);

 

 		if (isCreate) {

 			if (user.canAdmin()) {

@@ -186,12 +185,10 @@
 

 		// owners palette

 		List<UserChoice> owners = new ArrayList<UserChoice>();

-		for (String owner : repositoryModel.owners) {

-			UserModel o = app().users().getUserModel(owner);

-			if (o != null) {

-				owners.add(new UserChoice(o.getDisplayName(), o.username, o.emailAddress));

-			} else {

-				owners.add(new UserChoice(owner));

+		for (Owner owner : app().users().getOwners(repositoryModel)) {

+			if (owner instanceof UserModel) {

+				UserModel userOwner = (UserModel) owner;

+				owners.add(new UserChoice(userOwner.getDisplayName(), userOwner.username, userOwner.emailAddress));

 			}

 		}

 		List<UserChoice> persons = new ArrayList<UserChoice>();

@@ -338,13 +335,6 @@
 					}

 					repositoryModel.indexedBranches = indexedBranches;

 

-					// owners

-					repositoryModel.owners.clear();

-					Iterator<UserChoice> owners = ownersPalette.getSelectedChoices();

-					while (owners.hasNext()) {

-						repositoryModel.addOwner(owners.next().getUserId());

-					}

-

 					// pre-receive scripts

 					List<String> preReceiveScripts = new ArrayList<String>();

 					Iterator<String> pres = preReceivePalette.getSelectedChoices();

@@ -381,6 +371,21 @@
 						app().gitblit().setUserAccessPermissions(repositoryModel, repositoryUsers);

 						app().gitblit().setTeamAccessPermissions(repositoryModel, repositoryTeams);

 					}

+

+					//

+					// handle ownership changes

+					//

+

+					List<Owner> newOwners = new ArrayList<>();

+					Iterator<UserChoice> owners = ownersPalette.getSelectedChoices();

+					while (owners.hasNext()) {

+						String username = owners.next().getUserId();

+						UserModel owner = app().users().getUserModel(username);

+						newOwners.add(owner);

+					}

+

+					app().users().setOwners(repositoryModel, newOwners);

+

 				} catch (GitBlitException e) {

 					error(e.getMessage());

 					return;

@@ -413,7 +418,6 @@
 		// GENERAL

 		//

 		namePanel = new RepositoryNamePanel("namePanel", repositoryModel);

-		namePanel.setEditable(allowEditName);

 		form.add(namePanel);

 

 		// XXX AccessPolicyPanel is defined later.

@@ -667,7 +671,7 @@
 		// the user can delete if deletions are allowed AND the user is an admin or the personal owner

 		// assigned ownership is not sufficient to allow deletion

 		boolean canDelete = !isCreate && app().repositories().canDelete(repositoryModel)

-				&& (user.canAdmin() || user.isMyPersonalRepository(repositoryModel.name));

+				&& user.canDelete(repositoryModel);

 

 		Link<Void> delete = new Link<Void>("delete") {

 

@@ -682,8 +686,7 @@
 						info(MessageFormat.format(getString("gb.repositoryDeleted"), latestModel));

 						if (latestModel.isPersonalRepository()) {

 							// redirect to user's profile page

-							String prefix = app().settings().getString(Keys.git.userRepositoryPrefix, "~");

-							String username = latestModel.projectPath.substring(prefix.length());

+							String username = latestModel.getPersonalRepositoryOwner();

 							setResponsePage(UserPage.class, WicketUtils.newUsernameParameter(username));

 						} else {

 							// redirect to server repositories page

@@ -740,7 +743,7 @@
 						isAdmin = true;

 						return;

 					} else {

-						if (!model.isOwner(user.username)) {

+						if (!user.isOwner(model)) {

 							// User is not an Admin nor Owner

 							error(getString("gb.errorOnlyAdminOrOwnerMayEditRepository"), true);

 						}

diff --git a/src/main/java/com/gitblit/wicket/pages/ForksPage.java b/src/main/java/com/gitblit/wicket/pages/ForksPage.java
index 9fd7f4d..1c113c3 100644
--- a/src/main/java/com/gitblit/wicket/pages/ForksPage.java
+++ b/src/main/java/com/gitblit/wicket/pages/ForksPage.java
@@ -31,6 +31,7 @@
 import com.gitblit.models.ForkModel;

 import com.gitblit.models.RepositoryModel;

 import com.gitblit.models.UserModel;

+import com.gitblit.utils.ModelUtils;

 import com.gitblit.utils.StringUtils;

 import com.gitblit.wicket.GitBlitWebSession;

 import com.gitblit.wicket.WicketUtils;

@@ -57,10 +58,11 @@
 				RepositoryModel repository = fork.repository;

 

 				if (repository.isPersonalRepository()) {

-					UserModel user = app().users().getUserModel(repository.projectPath.substring(1));

+					String name = ModelUtils.getUserNameFromRepoPath(repository.name);

+					UserModel user = app().users().getUserModel(name);

 					if (user == null) {

 						// user account no longer exists

-						user = new UserModel(repository.projectPath.substring(1));

+						user = new UserModel(name);

 					}

 					PersonIdent ident = new PersonIdent(user.getDisplayName(), user.emailAddress == null ? user.getDisplayName() : user.emailAddress);

 					item.add(new GravatarImage("anAvatar", ident, 20));

@@ -81,7 +83,7 @@
 					WicketUtils.setCssClass(swatch,  "repositorySwatch");

 					WicketUtils.setCssBackground(swatch, repository.toString());

 					item.add(swatch);

-					String projectName = repository.projectPath;

+					String projectName = repository.getProject();

 					if (StringUtils.isEmpty(projectName)) {

 						projectName = app().settings().getString(Keys.web.repositoryRootGroupName, "main");

 					}

diff --git a/src/main/java/com/gitblit/wicket/pages/MyDashboardPage.java b/src/main/java/com/gitblit/wicket/pages/MyDashboardPage.java
index 0f7d602..d7d522c 100644
--- a/src/main/java/com/gitblit/wicket/pages/MyDashboardPage.java
+++ b/src/main/java/com/gitblit/wicket/pages/MyDashboardPage.java
@@ -112,7 +112,7 @@
 		List<RepositoryModel> active = new ArrayList<RepositoryModel>();

 

 		for (RepositoryModel model : getRepositoryModels()) {

-			if (model.isUsersPersonalRepository(user.username) || model.isOwner(user.username)) {

+			if (user.isOwner(model)) {

 				owned.add(model);

 			}

 

diff --git a/src/main/java/com/gitblit/wicket/pages/NewRepositoryPage.java b/src/main/java/com/gitblit/wicket/pages/NewRepositoryPage.java
index 4687716..b4c2f66 100644
--- a/src/main/java/com/gitblit/wicket/pages/NewRepositoryPage.java
+++ b/src/main/java/com/gitblit/wicket/pages/NewRepositoryPage.java
@@ -19,6 +19,7 @@
 import java.io.IOException;

 import java.io.UnsupportedEncodingException;

 import java.util.ArrayList;

+import java.util.Arrays;

 import java.util.Collections;

 import java.util.List;

 

@@ -48,6 +49,7 @@
 import com.gitblit.Constants.AuthorizationControl;

 import com.gitblit.GitBlitException;

 import com.gitblit.Keys;

+import com.gitblit.models.Owner;

 import com.gitblit.models.RepositoryModel;

 import com.gitblit.models.UserModel;

 import com.gitblit.utils.ArrayUtils;

@@ -108,9 +110,6 @@
 					}

 					accessPolicyPanel.updateModel(repositoryModel);

 

-					repositoryModel.owners = new ArrayList<String>();

-					repositoryModel.owners.add(GitBlitWebSession.get().getUsername());

-

 					// setup branch defaults

 					boolean useGitFlow = addGitflowModel.getObject();

 

@@ -137,6 +136,10 @@
 					// init the repository

 					app().gitblit().updateRepositoryModel(repositoryModel.name, repositoryModel, true);

 

+					// save the owner change

+					List<Owner> owners = Arrays.asList((Owner) GitBlitWebSession.get().getUser());

+					app().gitblit().setOwners(repositoryModel, owners);

+

 					// optionally create an initial commit

 					initialCommit(repositoryModel, addReadme, gitignore, useGitFlow);

 

diff --git a/src/main/java/com/gitblit/wicket/pages/OverviewPage.java b/src/main/java/com/gitblit/wicket/pages/OverviewPage.java
index 1979f97..e70d3b1 100644
--- a/src/main/java/com/gitblit/wicket/pages/OverviewPage.java
+++ b/src/main/java/com/gitblit/wicket/pages/OverviewPage.java
@@ -16,7 +16,6 @@
 package com.gitblit.wicket.pages;

 

 import java.text.MessageFormat;

-import java.util.ArrayList;

 import java.util.List;

 

 import org.apache.wicket.PageParameters;

@@ -30,6 +29,7 @@
 

 import com.gitblit.Keys;

 import com.gitblit.models.Metric;

+import com.gitblit.models.Owner;

 import com.gitblit.models.RepositoryModel;

 import com.gitblit.models.UserModel;

 import com.gitblit.utils.JGitUtils;

@@ -74,23 +74,18 @@
 		add(new Label("repositoryDescription", getRepositoryModel().description));

 

 		// owner links

-		final List<String> owners = new ArrayList<String>(getRepositoryModel().owners);

-		ListDataProvider<String> ownersDp = new ListDataProvider<String>(owners);

-		DataView<String> ownersView = new DataView<String>("repositoryOwners", ownersDp) {

+		final List<Owner> owners = app().users().getOwners(getRepositoryModel());

+		ListDataProvider<Owner> ownersDp = new ListDataProvider<Owner>(owners);

+		DataView<Owner> ownersView = new DataView<Owner>("repositoryOwners", ownersDp) {

 			private static final long serialVersionUID = 1L;

 			int counter = 0;

 			@Override

-			public void populateItem(final Item<String> item) {

-				String ownername = item.getModelObject();

-				UserModel ownerModel = app().users().getUserModel(ownername);

-				if (ownerModel != null) {

-					item.add(new LinkPanel("owner", null, ownerModel.getDisplayName(), UserPage.class,

-							WicketUtils.newUsernameParameter(ownerModel.username)).setRenderBodyOnly(true));

-				} else {

-					Label owner = new Label("owner", ownername);

-					WicketUtils.setCssStyle(owner, "text-decoration: line-through;");

-					WicketUtils.setHtmlTooltip(owner,  MessageFormat.format(getString("gb.failedToFindAccount"), ownername));

-					item.add(owner);

+			public void populateItem(final Item<Owner> item) {

+				Owner owner = item.getModelObject();

+				if (owner instanceof UserModel) {

+					UserModel user = (UserModel) owner;

+					item.add(new LinkPanel("owner", null, user.getDisplayName(), UserPage.class,

+						WicketUtils.newUsernameParameter(user.username)).setRenderBodyOnly(true));

 				}

 				counter++;

 				item.add(new Label("comma", ",").setVisible(counter < owners.size()));

@@ -136,7 +131,7 @@
 				&& app().settings().getBoolean(Keys.web.generateActivityGraph, true)) {

 

 			Charts charts = new Flotr2Charts();

-			

+

 			// daily line chart

 			Chart chart = charts.createLineChart("chartDaily", "", "unit",

 					getString("gb.commits"));

diff --git a/src/main/java/com/gitblit/wicket/pages/RepositoryPage.java b/src/main/java/com/gitblit/wicket/pages/RepositoryPage.java
index fcf659a..71eb859 100644
--- a/src/main/java/com/gitblit/wicket/pages/RepositoryPage.java
+++ b/src/main/java/com/gitblit/wicket/pages/RepositoryPage.java
@@ -156,7 +156,7 @@
 			showAdmin = app().settings().getBoolean(Keys.web.allowAdministration, false);

 		}

 		isOwner = GitBlitWebSession.get().isLoggedIn()

-				&& (getRepositoryModel().isOwner(GitBlitWebSession.get().getUsername()));

+				&& (GitBlitWebSession.get().getUser().isOwner(getRepositoryModel()));

 

 		// register the available navigation links for this page and user

 		List<NavLink> navLinks = registerNavLinks();

diff --git a/src/main/java/com/gitblit/wicket/pages/RootPage.java b/src/main/java/com/gitblit/wicket/pages/RootPage.java
index b1c3639..98a8df8 100644
--- a/src/main/java/com/gitblit/wicket/pages/RootPage.java
+++ b/src/main/java/com/gitblit/wicket/pages/RootPage.java
@@ -412,7 +412,7 @@
 		String userName = WicketUtils.getUsername(params);
 		if (StringUtils.isEmpty(projectName)) {
 			if (!StringUtils.isEmpty(userName)) {
-				projectName = ModelUtils.getPersonalPath(userName);
+				projectName = ModelUtils.getPersonalProject(userName);
 			}
 		}
 		String repositoryName = WicketUtils.getRepositoryName(params);
diff --git a/src/main/java/com/gitblit/wicket/pages/RootSubPage.java b/src/main/java/com/gitblit/wicket/pages/RootSubPage.java
index 62d07a7..53ed198 100644
--- a/src/main/java/com/gitblit/wicket/pages/RootSubPage.java
+++ b/src/main/java/com/gitblit/wicket/pages/RootSubPage.java
@@ -89,17 +89,16 @@
 			RepositoryModel repositoryModel = app().repositories().getRepositoryModel(repo);

 			if (repositoryModel.accessRestriction.exceeds(AccessRestrictionType.NONE)

 					&& repositoryModel.authorizationControl.equals(AuthorizationControl.NAMED)) {

-				if (user != null &&

-						(repositoryModel.isOwner(user.username) || repositoryModel.isUsersPersonalRepository(user.username))) {

+				if (user != null && user.isOwner(repositoryModel)) {

 					// exclude Owner or personal repositories

 					continue;

 				}

 				if (includeWildcards) {

-					if (lastProject == null || !lastProject.equalsIgnoreCase(repositoryModel.projectPath)) {

-						lastProject = repositoryModel.projectPath.toLowerCase();

-						if (!StringUtils.isEmpty(repositoryModel.projectPath)) {

+					if (lastProject == null || !lastProject.equalsIgnoreCase(repositoryModel.getProject())) {

+						lastProject = repositoryModel.getProject().toLowerCase();

+						if (!StringUtils.isEmpty(repositoryModel.getProject())) {

 							// regex for all repositories within a project

-							repos.add(repositoryModel.projectPath + "/.*");

+							repos.add(repositoryModel.getProjectPath() + "/.*");

 						}

 					}

 				}

diff --git a/src/main/java/com/gitblit/wicket/pages/SummaryPage.java b/src/main/java/com/gitblit/wicket/pages/SummaryPage.java
index 090c095..a3544c7 100644
--- a/src/main/java/com/gitblit/wicket/pages/SummaryPage.java
+++ b/src/main/java/com/gitblit/wicket/pages/SummaryPage.java
@@ -18,7 +18,6 @@
 import java.text.MessageFormat;

 import java.text.ParseException;

 import java.text.SimpleDateFormat;

-import java.util.ArrayList;

 import java.util.Date;

 import java.util.List;

 

@@ -36,6 +35,7 @@
 

 import com.gitblit.Keys;

 import com.gitblit.models.Metric;

+import com.gitblit.models.Owner;

 import com.gitblit.models.RepositoryModel;

 import com.gitblit.models.UserModel;

 import com.gitblit.utils.JGitUtils;

@@ -88,23 +88,18 @@
 		add(new Label("repositoryDescription", getRepositoryModel().description));

 

 		// owner links

-		final List<String> owners = new ArrayList<String>(getRepositoryModel().owners);

-		ListDataProvider<String> ownersDp = new ListDataProvider<String>(owners);

-		DataView<String> ownersView = new DataView<String>("repositoryOwners", ownersDp) {

+		final List<Owner> owners = app().users().getOwners(getRepositoryModel());

+		ListDataProvider<Owner> ownersDp = new ListDataProvider<>(owners);

+		DataView<Owner> ownersView = new DataView<Owner>("repositoryOwners", ownersDp) {

 			private static final long serialVersionUID = 1L;

 			int counter = 0;

 			@Override

-			public void populateItem(final Item<String> item) {

-				String ownername = item.getModelObject();

-				UserModel ownerModel = app().users().getUserModel(ownername);

-				if (ownerModel != null) {

+			public void populateItem(final Item<Owner> item) {

+				Owner owner = item.getModelObject();

+				if (owner instanceof UserModel) {

+					UserModel ownerModel = (UserModel) owner;

 					item.add(new LinkPanel("owner", null, ownerModel.getDisplayName(), UserPage.class,

 							WicketUtils.newUsernameParameter(ownerModel.username)).setRenderBodyOnly(true));

-				} else {

-					Label owner = new Label("owner", ownername);

-					WicketUtils.setCssStyle(owner, "text-decoration: line-through;");

-					WicketUtils.setHtmlTooltip(owner,  MessageFormat.format(getString("gb.failedToFindAccount"), ownername));

-					item.add(owner);

 				}

 				counter++;

 				item.add(new Label("comma", ",").setVisible(counter < owners.size()));

diff --git a/src/main/java/com/gitblit/wicket/panels/ProjectRepositoryPanel.java b/src/main/java/com/gitblit/wicket/panels/ProjectRepositoryPanel.java
index 8630d20..a30faff 100644
--- a/src/main/java/com/gitblit/wicket/panels/ProjectRepositoryPanel.java
+++ b/src/main/java/com/gitblit/wicket/panels/ProjectRepositoryPanel.java
@@ -15,6 +15,7 @@
  */

 package com.gitblit.wicket.panels;

 

+import java.util.List;

 import java.util.Map;

 

 import org.apache.wicket.Component;

@@ -27,6 +28,7 @@
 

 import com.gitblit.Constants.AccessRestrictionType;

 import com.gitblit.Keys;

+import com.gitblit.models.Owner;

 import com.gitblit.models.RepositoryModel;

 import com.gitblit.models.UserModel;

 import com.gitblit.servlet.SyndicationServlet;

@@ -64,7 +66,7 @@
 		swatch.setVisible(showSwatch);

 

 		PageParameters pp = WicketUtils.newRepositoryParameter(entry.name);

-		add(new LinkPanel("repositoryName", "list", StringUtils.getRelativePath(entry.projectPath,

+		add(new LinkPanel("repositoryName", "list", StringUtils.getRelativePath(entry.getProject(),

 				StringUtils.stripDotGit(entry.name)), SummaryPage.class, pp));

 		add(new Label("repositoryDescription", entry.description).setVisible(!StringUtils

 				.isEmpty(entry.description)));

@@ -102,23 +104,17 @@
 			add(WicketUtils.newClearPixel("federatedIcon").setVisible(false));

 		}

 

-		if (ArrayUtils.isEmpty(entry.owners)) {

+		List<Owner> owners = app().users().getOwners(entry);

+		if (ArrayUtils.isEmpty(owners)) {

 			add(new Label("repositoryOwner").setVisible(false));

 		} else {

-			String owner = "";

-			for (String username : entry.owners) {

-				UserModel ownerModel = app().users().getUserModel(username);

-

-				if (ownerModel != null) {

-					owner = ownerModel.getDisplayName();

-				}

-			}

-			if (entry.owners.size() > 1) {

+			String owner = owners.get(0).getDisplayName();

+			if (owners.size() > 1) {

 				owner += ", ...";

 			}

 			Label ownerLabel = (new Label("repositoryOwner", owner + " (" +

 					localizer.getString("gb.owner", parent) + ")"));

-			WicketUtils.setHtmlTooltip(ownerLabel, ArrayUtils.toString(entry.owners));

+			WicketUtils.setHtmlTooltip(ownerLabel, ArrayUtils.toString(owners));

 			add(ownerLabel);

 		}

 

diff --git a/src/main/java/com/gitblit/wicket/panels/RepositoriesPanel.java b/src/main/java/com/gitblit/wicket/panels/RepositoriesPanel.java
index 8573e1a..49ec048 100644
--- a/src/main/java/com/gitblit/wicket/panels/RepositoriesPanel.java
+++ b/src/main/java/com/gitblit/wicket/panels/RepositoriesPanel.java
@@ -42,6 +42,7 @@
 

 import com.gitblit.Constants.AccessRestrictionType;

 import com.gitblit.Keys;

+import com.gitblit.models.Owner;

 import com.gitblit.models.ProjectModel;

 import com.gitblit.models.RepositoryModel;

 import com.gitblit.models.UserModel;

@@ -275,22 +276,17 @@
 					row.add(WicketUtils.newBlankImage("accessRestrictionIcon"));

 				}

 

+				List<Owner> owners = app().users().getOwners(entry);

+				// display first owner

 				String owner = "";

-				if (!ArrayUtils.isEmpty(entry.owners)) {

-					// display first owner

-					for (String username : entry.owners) {

-						UserModel ownerModel = app().users().getUserModel(username);

-						if (ownerModel != null) {

-							owner = ownerModel.getDisplayName();

-							break;

-						}

-					}

-					if (entry.owners.size() > 1) {

+				if (!owners.isEmpty()) {

+					owner = owners.get(0).getDisplayName();

+					if (owners.size() > 1) {

 						owner += ", ...";

 					}

 				}

 				Label ownerLabel = new Label("repositoryOwner", owner);

-				WicketUtils.setHtmlTooltip(ownerLabel, ArrayUtils.toString(entry.owners));

+				WicketUtils.setHtmlTooltip(ownerLabel, ArrayUtils.toString(owners));

 				row.add(ownerLabel);

 

 				String lastChange;

@@ -336,7 +332,7 @@
 		String title;

 

 		GroupRepositoryModel(String name, int count) {

-			super(name, "", "", new Date(0));

+			super(name, "", new Date(0));

 			this.count = count;

 		}

 

@@ -412,18 +408,6 @@
 						return o2.name.compareTo(o1.name);

 					}

 				});

-			} else if (prop.equals(SortBy.owner.name())) {

-				Collections.sort(list, new Comparator<RepositoryModel>() {

-					@Override

-					public int compare(RepositoryModel o1, RepositoryModel o2) {

-						String own1 = ArrayUtils.toString(o1.owners);

-						String own2 = ArrayUtils.toString(o2.owners);

-						if (asc) {

-							return own1.compareTo(own2);

-						}

-						return own2.compareTo(own1);

-					}

-				});

 			} else if (prop.equals(SortBy.description.name())) {

 				Collections.sort(list, new Comparator<RepositoryModel>() {

 					@Override

diff --git a/src/main/java/com/gitblit/wicket/panels/RepositoryNamePanel.java b/src/main/java/com/gitblit/wicket/panels/RepositoryNamePanel.java
index f381a45..2b2a3ad 100644
--- a/src/main/java/com/gitblit/wicket/panels/RepositoryNamePanel.java
+++ b/src/main/java/com/gitblit/wicket/panels/RepositoryNamePanel.java
@@ -1,172 +1,176 @@
-/*

- * 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.panels;

-

-import java.text.MessageFormat;

-import java.util.ArrayList;

-import java.util.Set;

-import java.util.TreeSet;

-

-import org.apache.wicket.markup.html.form.DropDownChoice;

-import org.apache.wicket.markup.html.form.TextField;

-import org.apache.wicket.model.IModel;

-import org.apache.wicket.model.Model;

-

-import com.gitblit.models.ProjectModel;

-import com.gitblit.models.RepositoryModel;

-import com.gitblit.models.UserModel;

-import com.gitblit.utils.StringUtils;

-import com.gitblit.wicket.GitBlitWebSession;

-

-/**

- * A panel for naming a repository, specifying it's project, and entering a description.

- *

- * @author James Moger

- *

- */

-public class RepositoryNamePanel extends BasePanel {

-

-	private static final long serialVersionUID = 1L;

-

-	private String fullName;

-

-	private final IModel<String> projectPath;

-

-	private DropDownChoice<String> pathChoice;

-

-	private final IModel<String> repoName;

-

-	private TextField<String> nameField;

-

-	public RepositoryNamePanel(String wicketId, RepositoryModel repository) {

-		super(wicketId);

-

-		GitBlitWebSession session = GitBlitWebSession.get();

-		UserModel user = session.getUser();

-

-		// build project set for repository destination

-		String defaultPath = null;

-		String defaultName = null;

-		Set<String> pathNames = new TreeSet<String>();

-

-		// add the registered/known projects

-		for (ProjectModel project : app().projects().getProjectModels(user, false)) {

-			// TODO issue-351: user.canAdmin(project)

-			if (user.canAdmin()) {

-				if (project.isRoot) {

-					pathNames.add("/");

-				} else {

-					pathNames.add(project.name + "/");

-				}

-			}

-		}

-

-		// add the user's personal project namespace

-		if (user.canAdmin() || user.canCreate()) {

-			pathNames.add(user.getPersonalPath() + "/");

-		}

-

-		if (!StringUtils.isEmpty(repository.name)) {

-			// editing a repository name

-			// set the defaultProject to the current repository project

-			if (StringUtils.isEmpty(repository.projectPath)) {

-				defaultPath = "/";

-				defaultName = repository.name;

-			} else {

-				defaultPath = repository.projectPath + "/";

-				defaultName = repository.name.substring(defaultPath.length());

-			}

-			pathNames.add(defaultPath);

-		}

-

-		// if default project is not already set, set preference based on the user permissions

-		if (defaultPath == null) {

-			if (user.canAdmin()) {

-				defaultPath = "/";

-			} else if (user.canCreate()) {

-				defaultPath = user.getPersonalPath() + "/";

-			}

-		}

-

-		projectPath = Model.of(defaultPath);

-		pathChoice = new DropDownChoice<String>("projectPath", projectPath, new ArrayList<String>(pathNames));

-		repoName = Model.of(defaultName);

-		nameField = new TextField<String>("name", repoName);

-

-		// only enable project selection if we actually have multiple choices

-		add(pathChoice.setEnabled(pathNames.size() > 1));

-		add(nameField);

-		add(new TextField<String>("description"));

-	}

-

-	public void setEditable(boolean editable) {

-		// only enable project selection if we actually have multiple choices

-		pathChoice.setEnabled(pathChoice.getChoices().size() > 1 && editable);

-		nameField.setEnabled(editable);

-	}

-

-	public boolean updateModel(RepositoryModel repositoryModel) {

-		// confirm a project path was selected

-		if (StringUtils.isEmpty(projectPath.getObject())) {

-			error(getString("gb.pleaseSelectProject"));

-			return false;

-		}

-

-		// confirm a repository name was entered

-		if (StringUtils.isEmpty(repoName.getObject())) {

-			error(getString("gb.pleaseSetRepositoryName"));

-			return false;

-		}

-

-		String project = projectPath.getObject();

-		String name = repoName.getObject();

-

-		fullName = (project + name).trim();

-		fullName = fullName.replace('\\', '/');

-		fullName = fullName.replace("//", "/");

-		if (fullName.charAt(0) == '/') {

-			fullName = fullName.substring(1);

-		}

-		if (fullName.endsWith("/")) {

-			fullName = fullName.substring(0, fullName.length() - 1);

-		}

-

-		if (fullName.contains("../")) {

-			error(getString("gb.illegalRelativeSlash"));

-			return false;

-		}

-		if (fullName.contains("/../")) {

-			error(getString("gb.illegalRelativeSlash"));

-			return false;

-		}

-

-		// confirm valid characters in repository name

-		Character c = StringUtils.findInvalidCharacter(fullName);

-		if (c != null) {

-			error(MessageFormat.format(getString("gb.illegalCharacterRepositoryName"), c));

-			return false;

-		}

-

-		repositoryModel.name = fullName;

-

-		return true;

-	}

-

-	@Override

-	protected boolean getStatelessHint() {

-		return false;

-	}

+/*
+ * 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.panels;
+
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.Set;
+import java.util.TreeSet;
+
+import org.apache.wicket.markup.html.form.DropDownChoice;
+import org.apache.wicket.markup.html.form.TextField;
+import org.apache.wicket.model.IModel;
+import org.apache.wicket.model.Model;
+
+import com.gitblit.models.ProjectModel;
+import com.gitblit.models.RepositoryModel;
+import com.gitblit.models.UserModel;
+import com.gitblit.utils.StringUtils;
+import com.gitblit.wicket.GitBlitWebSession;
+
+/**
+ * A panel for naming a repository, specifying it's project, and entering a description.
+ *
+ * @author James Moger
+ *
+ */
+public class RepositoryNamePanel extends BasePanel {
+
+	private static final long serialVersionUID = 1L;
+
+	private String fullName;
+
+	private final IModel<String> projectPath;
+
+	private DropDownChoice<String> pathChoice;
+
+	private final IModel<String> repoName;
+
+	private TextField<String> nameField;
+
+	public RepositoryNamePanel(String wicketId, RepositoryModel repository) {
+		super(wicketId);
+
+		GitBlitWebSession session = GitBlitWebSession.get();
+		UserModel user = session.getUser();
+
+		// build project set for repository destination
+		String defaultPath = null;
+		String defaultName = null;
+		Set<String> pathNames = new TreeSet<String>();
+
+//		// add all specified project paths
+//		if (user.ownerOf != null) {
+//			for (String path : user.ownerOf) {
+//				if (path.charAt(path.length() - 1) == '/') {
+//					projectNames.add(path);
+//				}
+//			}
+//		}
+//
+		// add the registered/known projects
+		for (ProjectModel project : app().projects().getProjectModels(user, false)) {
+			// TODO issue-351: user.canAdmin(project)
+			if (user.canAdmin()) {
+				if (project.isRoot) {
+					pathNames.add("/");
+				} else {
+					pathNames.add(project.name + "/");
+				}
+			}
+		}
+
+		// add the user's personal project namespace
+		if (user.canAdmin() || user.canCreate()) {
+			pathNames.add(user.getPersonalPath());
+		}
+
+		if (!StringUtils.isEmpty(repository.name)) {
+			// editing a repository name
+			// set the defaultProject to the current repository project
+			defaultPath = repository.getProjectPath();
+			defaultName = repository.name.substring(defaultPath.length());
+			pathNames.add(defaultPath);
+		}
+
+		// if default project is not already set, set preference based on the user permissions
+		if (defaultPath == null) {
+			if (user.canAdmin()) {
+				defaultPath = "/";
+			} else if (user.canCreate()) {
+				defaultPath = user.getPersonalPath();
+			}
+		}
+
+		projectPath = Model.of(defaultPath);
+		pathChoice = new DropDownChoice<String>("projectPath", projectPath, new ArrayList<String>(pathNames));
+		repoName = Model.of(defaultName);
+		nameField = new TextField<String>("name", repoName);
+
+		// only enable project selection if we actually have multiple choices
+		add(pathChoice.setEnabled(pathNames.size() > 1));
+		add(nameField);
+		add(new TextField<String>("description"));
+	}
+
+	public void setEditable(boolean editable) {
+		// only enable project selection if we actually have multiple choices
+		pathChoice.setEnabled(pathChoice.getChoices().size() > 1 && editable);
+		nameField.setEnabled(editable);
+	}
+
+	public boolean updateModel(RepositoryModel repositoryModel) {
+		// confirm a project path was selected
+		if (StringUtils.isEmpty(projectPath.getObject())) {
+			error(getString("gb.pleaseSelectProject"));
+			return false;
+		}
+
+		// confirm a repository name was entered
+		if (StringUtils.isEmpty(repoName.getObject())) {
+			error(getString("gb.pleaseSetRepositoryName"));
+			return false;
+		}
+
+		String project = projectPath.getObject();
+		String name = repoName.getObject();
+
+		fullName = (project + name).trim();
+		fullName = fullName.replace('\\', '/');
+		fullName = fullName.replace("//", "/");
+		if (fullName.charAt(0) == '/') {
+			fullName = fullName.substring(1);
+		}
+		if (fullName.endsWith("/")) {
+			fullName = fullName.substring(0, fullName.length() - 1);
+		}
+
+		if (fullName.contains("../")) {
+			error(getString("gb.illegalRelativeSlash"));
+			return false;
+		}
+		if (fullName.contains("/../")) {
+			error(getString("gb.illegalRelativeSlash"));
+			return false;
+		}
+
+		// confirm valid characters in repository name
+		Character c = StringUtils.findInvalidCharacter(fullName);
+		if (c != null) {
+			error(MessageFormat.format(getString("gb.illegalCharacterRepositoryName"), c));
+			return false;
+		}
+
+		repositoryModel.name = fullName;
+
+		return true;
+	}
+
+	@Override
+	protected boolean getStatelessHint() {
+		return false;
+	}
 }
\ No newline at end of file
diff --git a/src/test/config/test-users.conf b/src/test/config/test-users.conf
index 4361410..49fa863 100644
--- a/src/test/config/test-users.conf
+++ b/src/test/config/test-users.conf
@@ -5,6 +5,7 @@
 	emailMeOnMyTicketChanges = true
 	role = "#admin"
 	role = "#notfederated"
+	owns = ~admin/helloworld.git
 [team "admins"]
 	role = "#none"
 	accountType = LOCAL
diff --git a/src/test/java/com/gitblit/tests/BranchTicketServiceTest.java b/src/test/java/com/gitblit/tests/BranchTicketServiceTest.java
index cc404ab..42dd8a8 100644
--- a/src/test/java/com/gitblit/tests/BranchTicketServiceTest.java
+++ b/src/test/java/com/gitblit/tests/BranchTicketServiceTest.java
@@ -38,7 +38,7 @@
  */
 public class BranchTicketServiceTest extends TicketServiceTest {
 
-	final RepositoryModel repo = new RepositoryModel("tickets/branch.git", null, null, null);
+	final RepositoryModel repo = new RepositoryModel("tickets/branch.git", null, null);
 
 	@Override
 	protected RepositoryModel getRepository() {
diff --git a/src/test/java/com/gitblit/tests/FederationTests.java b/src/test/java/com/gitblit/tests/FederationTests.java
index 144fe3d..abf24f2 100644
--- a/src/test/java/com/gitblit/tests/FederationTests.java
+++ b/src/test/java/com/gitblit/tests/FederationTests.java
@@ -68,7 +68,6 @@
 			model.accessRestriction = AccessRestrictionType.VIEW;

 			model.description = "cloneable repository " + i;

 			model.lastChange = new Date();

-			model.addOwner("adminuser");

 			model.name = "repo" + i + ".git";

 			model.size = "5 MB";

 			model.hasCommits = true;

diff --git a/src/test/java/com/gitblit/tests/FileTicketServiceTest.java b/src/test/java/com/gitblit/tests/FileTicketServiceTest.java
index 6ede042..126b9c7 100644
--- a/src/test/java/com/gitblit/tests/FileTicketServiceTest.java
+++ b/src/test/java/com/gitblit/tests/FileTicketServiceTest.java
@@ -38,7 +38,7 @@
  */
 public class FileTicketServiceTest extends TicketServiceTest {
 
-	final RepositoryModel repo = new RepositoryModel("tickets/file.git", null, null, null);
+	final RepositoryModel repo = new RepositoryModel("tickets/file.git", null, null);
 
 	@Override
 	protected RepositoryModel getRepository() {
diff --git a/src/test/java/com/gitblit/tests/GitServletTest.java b/src/test/java/com/gitblit/tests/GitServletTest.java
index 705684a..4ec8422 100644
--- a/src/test/java/com/gitblit/tests/GitServletTest.java
+++ b/src/test/java/com/gitblit/tests/GitServletTest.java
@@ -53,7 +53,6 @@
 import com.gitblit.models.RefLogEntry;

 import com.gitblit.models.RepositoryModel;

 import com.gitblit.models.UserModel;

-import com.gitblit.utils.ArrayUtils;

 import com.gitblit.utils.JGitUtils;

 import com.gitblit.utils.RefLogUtils;

 

@@ -879,7 +878,8 @@
 

 			// confirm default personal repository permissions

 			RepositoryModel model = repositories().getRepositoryModel(MessageFormat.format("~{0}/ticgit.git", user.username));

-			assertEquals("Unexpected owner", user.username, ArrayUtils.toString(model.owners));

+			user = gitblit().getUserModel(user.username);

+			assertTrue("Unexpected owner", user.isOwner(model));

 			assertEquals("Unexpected authorization control", AuthorizationControl.NAMED, model.authorizationControl);

 			assertEquals("Unexpected access restriction", AccessRestrictionType.VIEW, model.accessRestriction);

 

@@ -903,7 +903,8 @@
 

 			// confirm default project repository permissions

 			RepositoryModel model = repositories().getRepositoryModel("project/ticgit.git");

-			assertEquals("Unexpected owner", user.username, ArrayUtils.toString(model.owners));

+			user = gitblit().getUserModel(user.username);

+			assertTrue("Unexpected owner", user.isOwner(model));

 			assertEquals("Unexpected authorization control", AuthorizationControl.fromName(settings().getString(Keys.git.defaultAuthorizationControl, "NAMED")), model.authorizationControl);

 			assertEquals("Unexpected access restriction", AccessRestrictionType.fromName(settings().getString(Keys.git.defaultAccessRestriction, "NONE")), model.accessRestriction);

 

diff --git a/src/test/java/com/gitblit/tests/GroovyScriptTest.java b/src/test/java/com/gitblit/tests/GroovyScriptTest.java
index ff40972..c73498e 100644
--- a/src/test/java/com/gitblit/tests/GroovyScriptTest.java
+++ b/src/test/java/com/gitblit/tests/GroovyScriptTest.java
@@ -147,7 +147,7 @@
 		commands.add(new ReceiveCommand(ObjectId.zeroId(), ObjectId

 				.fromString("3fa7c46d11b11d61f1cbadc6888be5d0eae21969"), "refs/heads/master"));

 

-		RepositoryModel repository = new RepositoryModel("ex@mple.git", "", "admin", new Date());

+		RepositoryModel repository = new RepositoryModel("ex@mple.git", "", new Date());

 

 		test("protect-refs.groovy", gitblit, logger, clientLogger, commands, repository);

 	}

@@ -161,7 +161,7 @@
 		commands.add(new ReceiveCommand(ObjectId.zeroId(), ObjectId

 				.fromString("3fa7c46d11b11d61f1cbadc6888be5d0eae21969"), "refs/tags/v1.0"));

 

-		RepositoryModel repository = new RepositoryModel("ex@mple.git", "", "admin", new Date());

+		RepositoryModel repository = new RepositoryModel("ex@mple.git", "", new Date());

 

 		test("protect-refs.groovy", gitblit, logger, clientLogger, commands, repository);

 		assertEquals(0, logger.messages.size());

@@ -177,7 +177,7 @@
 				.fromString("c18877690322dfc6ae3e37bb7f7085a24e94e887"), ObjectId

 				.fromString("3fa7c46d11b11d61f1cbadc6888be5d0eae21969"), "refs/heads/master"));

 

-		RepositoryModel repository = new RepositoryModel("ex@mple.git", "", "admin", new Date());

+		RepositoryModel repository = new RepositoryModel("ex@mple.git", "", new Date());

 

 		test("protect-refs.groovy", gitblit, logger, clientLogger, commands, repository);

 		assertEquals(0, logger.messages.size());

@@ -194,7 +194,7 @@
 				"refs/heads/master");

 		commands.add(command);

 

-		RepositoryModel repository = new RepositoryModel("ex@mple.git", "", "admin", new Date());

+		RepositoryModel repository = new RepositoryModel("ex@mple.git", "", new Date());

 

 		test("protect-refs.groovy", gitblit, logger, clientLogger, commands, repository);

 		assertEquals(ReceiveCommand.Result.REJECTED_NODELETE, command.getResult());

@@ -211,7 +211,7 @@
 				.fromString("3fa7c46d11b11d61f1cbadc6888be5d0eae21969"), ObjectId.zeroId(),

 				"refs/heads/other"));

 

-		RepositoryModel repository = new RepositoryModel("ex@mple.git", "", "admin", new Date());

+		RepositoryModel repository = new RepositoryModel("ex@mple.git", "", new Date());

 

 		test("protect-refs.groovy", gitblit, logger, clientLogger, commands, repository);

 		assertEquals(0, logger.messages.size());

@@ -228,7 +228,7 @@
 				"refs/tags/v1.0");

 		commands.add(command);

 

-		RepositoryModel repository = new RepositoryModel("ex@mple.git", "", "admin", new Date());

+		RepositoryModel repository = new RepositoryModel("ex@mple.git", "", new Date());

 

 		test("protect-refs.groovy", gitblit, logger, clientLogger, commands, repository);

 		assertEquals(ReceiveCommand.Result.REJECTED_NODELETE, command.getResult());

@@ -245,7 +245,7 @@
 				.fromString("c18877690322dfc6ae3e37bb7f7085a24e94e887"), ObjectId

 				.fromString("3fa7c46d11b11d61f1cbadc6888be5d0eae21969"), "refs/heads/master"));

 

-		RepositoryModel repository = new RepositoryModel("ex@mple.git", "", "admin", new Date());

+		RepositoryModel repository = new RepositoryModel("ex@mple.git", "", new Date());

 

 		try {

 			test("blockpush.groovy", gitblit, logger, clientLogger, commands, repository);

@@ -265,7 +265,7 @@
 				.fromString("c18877690322dfc6ae3e37bb7f7085a24e94e887"), ObjectId

 				.fromString("3fa7c46d11b11d61f1cbadc6888be5d0eae21969"), "refs/heads/master"));

 

-		RepositoryModel repository = new RepositoryModel("ex@mple.git", "", "admin", new Date());

+		RepositoryModel repository = new RepositoryModel("ex@mple.git", "", new Date());

 

 		File groovyDir = repositories().getHooksFolder();

 		File tempScript = File.createTempFile("testClientLogging", "groovy", groovyDir);

diff --git a/src/test/java/com/gitblit/tests/ModelUtilsTest.java b/src/test/java/com/gitblit/tests/ModelUtilsTest.java
index e34e0aa..dfccc14 100644
--- a/src/test/java/com/gitblit/tests/ModelUtilsTest.java
+++ b/src/test/java/com/gitblit/tests/ModelUtilsTest.java
@@ -4,6 +4,7 @@
 import org.junit.Test;
 
 import com.gitblit.Constants;
+import com.gitblit.models.UserModel;
 import com.gitblit.utils.ModelUtils;
 
 public class ModelUtilsTest extends GitblitUnitTest {
@@ -49,17 +50,32 @@
 
 
 	@Test
-	public void testGetPersonalPath()
+	public void testGetPersonalProject()
 	{
 		String username = "rob";
-		assertEquals(Constants.DEFAULT_USER_REPOSITORY_PREFIX+username.toLowerCase(), ModelUtils.getPersonalPath(username));
+		assertEquals(Constants.DEFAULT_USER_REPOSITORY_PREFIX+username.toLowerCase(), ModelUtils.getPersonalProject(username));
 
 		username = "James";
-		assertEquals(Constants.DEFAULT_USER_REPOSITORY_PREFIX+username.toLowerCase(), ModelUtils.getPersonalPath(username));
+		assertEquals(Constants.DEFAULT_USER_REPOSITORY_PREFIX+username.toLowerCase(), ModelUtils.getPersonalProject(username));
 
 		ModelUtils.setUserRepoPrefix("usr/");
 		username = "noMan";
-		assertEquals("usr/"+username.toLowerCase(), ModelUtils.getPersonalPath(username));
+		assertEquals("usr/"+username.toLowerCase(), ModelUtils.getPersonalProject(username));
+	}
+
+
+	@Test
+	public void testGetPersonalPath()
+	{
+		String username = "rob";
+		assertEquals(Constants.DEFAULT_USER_REPOSITORY_PREFIX+username.toLowerCase() + "/", ModelUtils.getPersonalPath(username));
+
+		username = "James";
+		assertEquals(Constants.DEFAULT_USER_REPOSITORY_PREFIX+username.toLowerCase() + "/", ModelUtils.getPersonalPath(username));
+
+		ModelUtils.setUserRepoPrefix("usr/");
+		username = "noMan";
+		assertEquals("usr/"+username.toLowerCase() + "/", ModelUtils.getPersonalPath(username));
 	}
 
 
@@ -124,4 +140,19 @@
 		assertEquals("fee", ModelUtils.getUserNameFromRepoPath(reponame));
 	}
 
+	@Test
+	public void testUserOwnership() {
+		ModelUtils.setUserRepoPrefix(Constants.DEFAULT_USER_REPOSITORY_PREFIX);
+		UserModel user = new UserModel("james");
+		user.own("test.git");
+		user.own("newyork/.*");
+
+		assertFalse(user.isOwner("test"));
+		assertTrue(user.isOwner("test.git"));
+		assertFalse(user.isOwner("newyork"));
+		assertTrue(user.isOwner("newyork/"));
+		assertTrue(user.isOwner("newyork/abc"));
+		assertTrue(user.isOwner("~james/"));
+		assertTrue(user.isOwner("~james/abc/123"));
+	}
 }
diff --git a/src/test/java/com/gitblit/tests/PermissionsTest.java b/src/test/java/com/gitblit/tests/PermissionsTest.java
index 46695e9..9e04c0b 100644
--- a/src/test/java/com/gitblit/tests/PermissionsTest.java
+++ b/src/test/java/com/gitblit/tests/PermissionsTest.java
@@ -43,7 +43,7 @@
 		user.canAdmin = true;
 
 		for (AccessRestrictionType ar : AccessRestrictionType.values()) {
-			RepositoryModel repository = new RepositoryModel("myrepo.git", null, null, new Date());
+			RepositoryModel repository = new RepositoryModel("myrepo.git", null, new Date());
 			repository.authorizationControl = AuthorizationControl.NAMED;
 			repository.accessRestriction = ar;
 
@@ -69,7 +69,7 @@
 	 */
 	@Test
 	public void testAnonymous_NONE() throws Exception {
-		RepositoryModel repository = new RepositoryModel("myrepo.git", null, null, new Date());
+		RepositoryModel repository = new RepositoryModel("myrepo.git", null, new Date());
 		repository.authorizationControl = AuthorizationControl.NAMED;
 		repository.accessRestriction = AccessRestrictionType.NONE;
 
@@ -97,7 +97,7 @@
 
 	@Test
 	public void testAnonymous_PUSH() throws Exception {
-		RepositoryModel repository = new RepositoryModel("myrepo.git", null, null, new Date());
+		RepositoryModel repository = new RepositoryModel("myrepo.git", null, new Date());
 		repository.authorizationControl = AuthorizationControl.NAMED;
 		repository.accessRestriction = AccessRestrictionType.PUSH;
 
@@ -121,7 +121,7 @@
 
 	@Test
 	public void testAnonymous_CLONE() throws Exception {
-		RepositoryModel repository = new RepositoryModel("myrepo.git", null, null, new Date());
+		RepositoryModel repository = new RepositoryModel("myrepo.git", null, new Date());
 		repository.authorizationControl = AuthorizationControl.NAMED;
 		repository.accessRestriction = AccessRestrictionType.CLONE;
 
@@ -145,7 +145,7 @@
 
 	@Test
 	public void testAnonymous_VIEW() throws Exception {
-		RepositoryModel repository = new RepositoryModel("myrepo.git", null, null, new Date());
+		RepositoryModel repository = new RepositoryModel("myrepo.git", null, new Date());
 		repository.authorizationControl = AuthorizationControl.NAMED;
 		repository.accessRestriction = AccessRestrictionType.VIEW;
 
@@ -172,7 +172,7 @@
 	 */
 	@Test
 	public void testAuthenticated_NONE() throws Exception {
-		RepositoryModel repository = new RepositoryModel("myrepo.git", null, null, new Date());
+		RepositoryModel repository = new RepositoryModel("myrepo.git", null, new Date());
 		repository.authorizationControl = AuthorizationControl.AUTHENTICATED;
 		repository.accessRestriction = AccessRestrictionType.NONE;
 
@@ -203,7 +203,7 @@
 
 	@Test
 	public void testAuthenticated_PUSH() throws Exception {
-		RepositoryModel repository = new RepositoryModel("myrepo.git", null, null, new Date());
+		RepositoryModel repository = new RepositoryModel("myrepo.git", null, new Date());
 		repository.authorizationControl = AuthorizationControl.AUTHENTICATED;
 		repository.accessRestriction = AccessRestrictionType.PUSH;
 
@@ -230,7 +230,7 @@
 
 	@Test
 	public void testAuthenticated_CLONE() throws Exception {
-		RepositoryModel repository = new RepositoryModel("myrepo.git", null, null, new Date());
+		RepositoryModel repository = new RepositoryModel("myrepo.git", null, new Date());
 		repository.authorizationControl = AuthorizationControl.AUTHENTICATED;
 		repository.accessRestriction = AccessRestrictionType.CLONE;
 
@@ -257,7 +257,7 @@
 
 	@Test
 	public void testAuthenticated_VIEW() throws Exception {
-		RepositoryModel repository = new RepositoryModel("myrepo.git", null, null, new Date());
+		RepositoryModel repository = new RepositoryModel("myrepo.git", null, new Date());
 		repository.authorizationControl = AuthorizationControl.AUTHENTICATED;
 		repository.accessRestriction = AccessRestrictionType.VIEW;
 
@@ -287,7 +287,7 @@
 	 */
 	@Test
 	public void testNamed_NONE_NONE() throws Exception {
-		RepositoryModel repository = new RepositoryModel("myrepo.git", null, null, new Date());
+		RepositoryModel repository = new RepositoryModel("myrepo.git", null, new Date());
 		repository.authorizationControl = AuthorizationControl.NAMED;
 		repository.accessRestriction = AccessRestrictionType.NONE;
 
@@ -320,7 +320,7 @@
 	 */
 	@Test
 	public void testNamed_PUSH_NONE() throws Exception {
-		RepositoryModel repository = new RepositoryModel("myrepo.git", null, null, new Date());
+		RepositoryModel repository = new RepositoryModel("myrepo.git", null, new Date());
 		repository.authorizationControl = AuthorizationControl.NAMED;
 		repository.accessRestriction = AccessRestrictionType.PUSH;
 
@@ -350,7 +350,7 @@
 	 */
 	@Test
 	public void testNamed_CLONE_NONE() throws Exception {
-		RepositoryModel repository = new RepositoryModel("myrepo.git", null, null, new Date());
+		RepositoryModel repository = new RepositoryModel("myrepo.git", null, new Date());
 		repository.authorizationControl = AuthorizationControl.NAMED;
 		repository.accessRestriction = AccessRestrictionType.CLONE;
 
@@ -380,7 +380,7 @@
 	 */
 	@Test
 	public void testNamed_VIEW_NONE() throws Exception {
-		RepositoryModel repository = new RepositoryModel("myrepo.git", null, null, new Date());
+		RepositoryModel repository = new RepositoryModel("myrepo.git", null, new Date());
 		repository.authorizationControl = AuthorizationControl.NAMED;
 		repository.accessRestriction = AccessRestrictionType.VIEW;
 
@@ -412,7 +412,7 @@
 	 */
 	@Test
 	public void testNamed_NONE_VIEW() throws Exception {
-		RepositoryModel repository = new RepositoryModel("myrepo.git", null, null, new Date());
+		RepositoryModel repository = new RepositoryModel("myrepo.git", null, new Date());
 		repository.authorizationControl = AuthorizationControl.NAMED;
 		repository.accessRestriction = AccessRestrictionType.NONE;
 
@@ -443,7 +443,7 @@
 	 */
 	@Test
 	public void testNamed_PUSH_VIEW() throws Exception {
-		RepositoryModel repository = new RepositoryModel("myrepo.git", null, null, new Date());
+		RepositoryModel repository = new RepositoryModel("myrepo.git", null, new Date());
 		repository.authorizationControl = AuthorizationControl.NAMED;
 		repository.accessRestriction = AccessRestrictionType.PUSH;
 
@@ -474,7 +474,7 @@
 	 */
 	@Test
 	public void testNamed_CLONE_VIEW() throws Exception {
-		RepositoryModel repository = new RepositoryModel("myrepo.git", null, null, new Date());
+		RepositoryModel repository = new RepositoryModel("myrepo.git", null, new Date());
 		repository.authorizationControl = AuthorizationControl.NAMED;
 		repository.accessRestriction = AccessRestrictionType.CLONE;
 
@@ -505,7 +505,7 @@
 	 */
 	@Test
 	public void testNamed_VIEW_VIEW() throws Exception {
-		RepositoryModel repository = new RepositoryModel("myrepo.git", null, null, new Date());
+		RepositoryModel repository = new RepositoryModel("myrepo.git", null, new Date());
 		repository.authorizationControl = AuthorizationControl.NAMED;
 		repository.accessRestriction = AccessRestrictionType.VIEW;
 
@@ -537,7 +537,7 @@
 	 */
 	@Test
 	public void testNamed_NONE_CLONE() throws Exception {
-		RepositoryModel repository = new RepositoryModel("myrepo.git", null, null, new Date());
+		RepositoryModel repository = new RepositoryModel("myrepo.git", null, new Date());
 		repository.authorizationControl = AuthorizationControl.NAMED;
 		repository.accessRestriction = AccessRestrictionType.NONE;
 
@@ -568,7 +568,7 @@
 	 */
 	@Test
 	public void testNamed_PUSH_CLONE() throws Exception {
-		RepositoryModel repository = new RepositoryModel("myrepo.git", null, null, new Date());
+		RepositoryModel repository = new RepositoryModel("myrepo.git", null, new Date());
 		repository.authorizationControl = AuthorizationControl.NAMED;
 		repository.accessRestriction = AccessRestrictionType.PUSH;
 
@@ -599,7 +599,7 @@
 	 */
 	@Test
 	public void testNamed_CLONE_CLONE() throws Exception {
-		RepositoryModel repository = new RepositoryModel("myrepo.git", null, null, new Date());
+		RepositoryModel repository = new RepositoryModel("myrepo.git", null, new Date());
 		repository.authorizationControl = AuthorizationControl.NAMED;
 		repository.accessRestriction = AccessRestrictionType.CLONE;
 
@@ -630,7 +630,7 @@
 	 */
 	@Test
 	public void testNamed_VIEW_CLONE() throws Exception {
-		RepositoryModel repository = new RepositoryModel("myrepo.git", null, null, new Date());
+		RepositoryModel repository = new RepositoryModel("myrepo.git", null, new Date());
 		repository.authorizationControl = AuthorizationControl.NAMED;
 		repository.accessRestriction = AccessRestrictionType.VIEW;
 
@@ -662,7 +662,7 @@
 	 */
 	@Test
 	public void testNamed_NONE_PUSH() throws Exception {
-		RepositoryModel repository = new RepositoryModel("myrepo.git", null, null, new Date());
+		RepositoryModel repository = new RepositoryModel("myrepo.git", null, new Date());
 		repository.authorizationControl = AuthorizationControl.NAMED;
 		repository.accessRestriction = AccessRestrictionType.NONE;
 
@@ -693,7 +693,7 @@
 	 */
 	@Test
 	public void testNamed_PUSH_PUSH() throws Exception {
-		RepositoryModel repository = new RepositoryModel("myrepo.git", null, null, new Date());
+		RepositoryModel repository = new RepositoryModel("myrepo.git", null, new Date());
 		repository.authorizationControl = AuthorizationControl.NAMED;
 		repository.accessRestriction = AccessRestrictionType.PUSH;
 
@@ -724,7 +724,7 @@
 	 */
 	@Test
 	public void testNamed_CLONE_PUSH() throws Exception {
-		RepositoryModel repository = new RepositoryModel("myrepo.git", null, null, new Date());
+		RepositoryModel repository = new RepositoryModel("myrepo.git", null, new Date());
 		repository.authorizationControl = AuthorizationControl.NAMED;
 		repository.accessRestriction = AccessRestrictionType.CLONE;
 
@@ -755,7 +755,7 @@
 	 */
 	@Test
 	public void testNamed_VIEW_PUSH() throws Exception {
-		RepositoryModel repository = new RepositoryModel("myrepo.git", null, null, new Date());
+		RepositoryModel repository = new RepositoryModel("myrepo.git", null, new Date());
 		repository.authorizationControl = AuthorizationControl.NAMED;
 		repository.accessRestriction = AccessRestrictionType.VIEW;
 
@@ -787,7 +787,7 @@
 	 */
 	@Test
 	public void testNamed_NONE_CREATE() throws Exception {
-		RepositoryModel repository = new RepositoryModel("myrepo.git", null, null, new Date());
+		RepositoryModel repository = new RepositoryModel("myrepo.git", null, new Date());
 		repository.authorizationControl = AuthorizationControl.NAMED;
 		repository.accessRestriction = AccessRestrictionType.NONE;
 
@@ -818,7 +818,7 @@
 	 */
 	@Test
 	public void testNamed_PUSH_CREATE() throws Exception {
-		RepositoryModel repository = new RepositoryModel("myrepo.git", null, null, new Date());
+		RepositoryModel repository = new RepositoryModel("myrepo.git", null, new Date());
 		repository.authorizationControl = AuthorizationControl.NAMED;
 		repository.accessRestriction = AccessRestrictionType.PUSH;
 
@@ -849,7 +849,7 @@
 	 */
 	@Test
 	public void testNamed_CLONE_CREATE() throws Exception {
-		RepositoryModel repository = new RepositoryModel("myrepo.git", null, null, new Date());
+		RepositoryModel repository = new RepositoryModel("myrepo.git", null, new Date());
 		repository.authorizationControl = AuthorizationControl.NAMED;
 		repository.accessRestriction = AccessRestrictionType.CLONE;
 
@@ -880,7 +880,7 @@
 	 */
 	@Test
 	public void testNamed_VIEW_CREATE() throws Exception {
-		RepositoryModel repository = new RepositoryModel("myrepo.git", null, null, new Date());
+		RepositoryModel repository = new RepositoryModel("myrepo.git", null, new Date());
 		repository.authorizationControl = AuthorizationControl.NAMED;
 		repository.accessRestriction = AccessRestrictionType.VIEW;
 
@@ -912,7 +912,7 @@
 	 */
 	@Test
 	public void testNamed_NONE_DELETE() throws Exception {
-		RepositoryModel repository = new RepositoryModel("myrepo.git", null, null, new Date());
+		RepositoryModel repository = new RepositoryModel("myrepo.git", null, new Date());
 		repository.authorizationControl = AuthorizationControl.NAMED;
 		repository.accessRestriction = AccessRestrictionType.NONE;
 
@@ -943,7 +943,7 @@
 	 */
 	@Test
 	public void testNamed_PUSH_DELETE() throws Exception {
-		RepositoryModel repository = new RepositoryModel("myrepo.git", null, null, new Date());
+		RepositoryModel repository = new RepositoryModel("myrepo.git", null, new Date());
 		repository.authorizationControl = AuthorizationControl.NAMED;
 		repository.accessRestriction = AccessRestrictionType.PUSH;
 
@@ -974,7 +974,7 @@
 	 */
 	@Test
 	public void testNamed_CLONE_DELETE() throws Exception {
-		RepositoryModel repository = new RepositoryModel("myrepo.git", null, null, new Date());
+		RepositoryModel repository = new RepositoryModel("myrepo.git", null, new Date());
 		repository.authorizationControl = AuthorizationControl.NAMED;
 		repository.accessRestriction = AccessRestrictionType.CLONE;
 
@@ -1005,7 +1005,7 @@
 	 */
 	@Test
 	public void testNamed_VIEW_DELETE() throws Exception {
-		RepositoryModel repository = new RepositoryModel("myrepo.git", null, null, new Date());
+		RepositoryModel repository = new RepositoryModel("myrepo.git", null, new Date());
 		repository.authorizationControl = AuthorizationControl.NAMED;
 		repository.accessRestriction = AccessRestrictionType.VIEW;
 
@@ -1037,7 +1037,7 @@
 	 */
 	@Test
 	public void testNamed_NONE_REWIND() throws Exception {
-		RepositoryModel repository = new RepositoryModel("myrepo.git", null, null, new Date());
+		RepositoryModel repository = new RepositoryModel("myrepo.git", null, new Date());
 		repository.authorizationControl = AuthorizationControl.NAMED;
 		repository.accessRestriction = AccessRestrictionType.NONE;
 
@@ -1068,7 +1068,7 @@
 	 */
 	@Test
 	public void testNamed_PUSH_REWIND() throws Exception {
-		RepositoryModel repository = new RepositoryModel("myrepo.git", null, null, new Date());
+		RepositoryModel repository = new RepositoryModel("myrepo.git", null, new Date());
 		repository.authorizationControl = AuthorizationControl.NAMED;
 		repository.accessRestriction = AccessRestrictionType.PUSH;
 
@@ -1099,7 +1099,7 @@
 	 */
 	@Test
 	public void testNamed_CLONE_REWIND() throws Exception {
-		RepositoryModel repository = new RepositoryModel("myrepo.git", null, null, new Date());
+		RepositoryModel repository = new RepositoryModel("myrepo.git", null, new Date());
 		repository.authorizationControl = AuthorizationControl.NAMED;
 		repository.accessRestriction = AccessRestrictionType.CLONE;
 
@@ -1130,7 +1130,7 @@
 	 */
 	@Test
 	public void testNamed_VIEW_REWIND() throws Exception {
-		RepositoryModel repository = new RepositoryModel("myrepo.git", null, null, new Date());
+		RepositoryModel repository = new RepositoryModel("myrepo.git", null, new Date());
 		repository.authorizationControl = AuthorizationControl.NAMED;
 		repository.accessRestriction = AccessRestrictionType.VIEW;
 
@@ -1161,7 +1161,7 @@
 	 */
 	@Test
 	public void testTeam_NONE_NONE() throws Exception {
-		RepositoryModel repository = new RepositoryModel("myrepo.git", null, null, new Date());
+		RepositoryModel repository = new RepositoryModel("myrepo.git", null, new Date());
 		repository.authorizationControl = AuthorizationControl.NAMED;
 		repository.accessRestriction = AccessRestrictionType.NONE;
 
@@ -1184,7 +1184,7 @@
 	 */
 	@Test
 	public void testTeam_PUSH_NONE() throws Exception {
-		RepositoryModel repository = new RepositoryModel("myrepo.git", null, null, new Date());
+		RepositoryModel repository = new RepositoryModel("myrepo.git", null, new Date());
 		repository.authorizationControl = AuthorizationControl.NAMED;
 		repository.accessRestriction = AccessRestrictionType.PUSH;
 
@@ -1207,7 +1207,7 @@
 	 */
 	@Test
 	public void testTeam_CLONE_NONE() throws Exception {
-		RepositoryModel repository = new RepositoryModel("myrepo.git", null, null, new Date());
+		RepositoryModel repository = new RepositoryModel("myrepo.git", null, new Date());
 		repository.authorizationControl = AuthorizationControl.NAMED;
 		repository.accessRestriction = AccessRestrictionType.CLONE;
 
@@ -1229,7 +1229,7 @@
 	 */
 	@Test
 	public void testTeam_VIEW_NONE() throws Exception {
-		RepositoryModel repository = new RepositoryModel("myrepo.git", null, null, new Date());
+		RepositoryModel repository = new RepositoryModel("myrepo.git", null, new Date());
 		repository.authorizationControl = AuthorizationControl.NAMED;
 		repository.accessRestriction = AccessRestrictionType.VIEW;
 
@@ -1252,7 +1252,7 @@
 	 */
 	@Test
 	public void testTeam_NONE_PUSH() throws Exception {
-		RepositoryModel repository = new RepositoryModel("myrepo.git", null, null, new Date());
+		RepositoryModel repository = new RepositoryModel("myrepo.git", null, new Date());
 		repository.authorizationControl = AuthorizationControl.NAMED;
 		repository.accessRestriction = AccessRestrictionType.NONE;
 
@@ -1275,7 +1275,7 @@
 	 */
 	@Test
 	public void testTeam_PUSH_PUSH() throws Exception {
-		RepositoryModel repository = new RepositoryModel("myrepo.git", null, null, new Date());
+		RepositoryModel repository = new RepositoryModel("myrepo.git", null, new Date());
 		repository.authorizationControl = AuthorizationControl.NAMED;
 		repository.accessRestriction = AccessRestrictionType.PUSH;
 
@@ -1298,7 +1298,7 @@
 	 */
 	@Test
 	public void testTeam_CLONE_PUSH() throws Exception {
-		RepositoryModel repository = new RepositoryModel("myrepo.git", null, null, new Date());
+		RepositoryModel repository = new RepositoryModel("myrepo.git", null, new Date());
 		repository.authorizationControl = AuthorizationControl.NAMED;
 		repository.accessRestriction = AccessRestrictionType.CLONE;
 
@@ -1321,7 +1321,7 @@
 	 */
 	@Test
 	public void testTeam_VIEW_PUSH() throws Exception {
-		RepositoryModel repository = new RepositoryModel("myrepo.git", null, null, new Date());
+		RepositoryModel repository = new RepositoryModel("myrepo.git", null, new Date());
 		repository.authorizationControl = AuthorizationControl.NAMED;
 		repository.accessRestriction = AccessRestrictionType.VIEW;
 
@@ -1345,7 +1345,7 @@
 	 */
 	@Test
 	public void testTeam_NONE_CREATE() throws Exception {
-		RepositoryModel repository = new RepositoryModel("myrepo.git", null, null, new Date());
+		RepositoryModel repository = new RepositoryModel("myrepo.git", null, new Date());
 		repository.authorizationControl = AuthorizationControl.NAMED;
 		repository.accessRestriction = AccessRestrictionType.NONE;
 
@@ -1368,7 +1368,7 @@
 	 */
 	@Test
 	public void testTeam_PUSH_CREATE() throws Exception {
-		RepositoryModel repository = new RepositoryModel("myrepo.git", null, null, new Date());
+		RepositoryModel repository = new RepositoryModel("myrepo.git", null, new Date());
 		repository.authorizationControl = AuthorizationControl.NAMED;
 		repository.accessRestriction = AccessRestrictionType.PUSH;
 
@@ -1391,7 +1391,7 @@
 	 */
 	@Test
 	public void testTeam_CLONE_CREATE() throws Exception {
-		RepositoryModel repository = new RepositoryModel("myrepo.git", null, null, new Date());
+		RepositoryModel repository = new RepositoryModel("myrepo.git", null, new Date());
 		repository.authorizationControl = AuthorizationControl.NAMED;
 		repository.accessRestriction = AccessRestrictionType.CLONE;
 
@@ -1414,7 +1414,7 @@
 	 */
 	@Test
 	public void testTeam_VIEW_CREATE() throws Exception {
-		RepositoryModel repository = new RepositoryModel("myrepo.git", null, null, new Date());
+		RepositoryModel repository = new RepositoryModel("myrepo.git", null, new Date());
 		repository.authorizationControl = AuthorizationControl.NAMED;
 		repository.accessRestriction = AccessRestrictionType.VIEW;
 
@@ -1438,7 +1438,7 @@
 	 */
 	@Test
 	public void testTeam_NONE_DELETE() throws Exception {
-		RepositoryModel repository = new RepositoryModel("myrepo.git", null, null, new Date());
+		RepositoryModel repository = new RepositoryModel("myrepo.git", null, new Date());
 		repository.authorizationControl = AuthorizationControl.NAMED;
 		repository.accessRestriction = AccessRestrictionType.NONE;
 
@@ -1461,7 +1461,7 @@
 	 */
 	@Test
 	public void testTeam_PUSH_DELETE() throws Exception {
-		RepositoryModel repository = new RepositoryModel("myrepo.git", null, null, new Date());
+		RepositoryModel repository = new RepositoryModel("myrepo.git", null, new Date());
 		repository.authorizationControl = AuthorizationControl.NAMED;
 		repository.accessRestriction = AccessRestrictionType.PUSH;
 
@@ -1484,7 +1484,7 @@
 	 */
 	@Test
 	public void testTeam_CLONE_DELETE() throws Exception {
-		RepositoryModel repository = new RepositoryModel("myrepo.git", null, null, new Date());
+		RepositoryModel repository = new RepositoryModel("myrepo.git", null, new Date());
 		repository.authorizationControl = AuthorizationControl.NAMED;
 		repository.accessRestriction = AccessRestrictionType.CLONE;
 
@@ -1507,7 +1507,7 @@
 	 */
 	@Test
 	public void testTeam_VIEW_DELETE() throws Exception {
-		RepositoryModel repository = new RepositoryModel("myrepo.git", null, null, new Date());
+		RepositoryModel repository = new RepositoryModel("myrepo.git", null, new Date());
 		repository.authorizationControl = AuthorizationControl.NAMED;
 		repository.accessRestriction = AccessRestrictionType.VIEW;
 
@@ -1531,7 +1531,7 @@
 	 */
 	@Test
 	public void testTeam_NONE_REWIND() throws Exception {
-		RepositoryModel repository = new RepositoryModel("myrepo.git", null, null, new Date());
+		RepositoryModel repository = new RepositoryModel("myrepo.git", null, new Date());
 		repository.authorizationControl = AuthorizationControl.NAMED;
 		repository.accessRestriction = AccessRestrictionType.NONE;
 
@@ -1554,7 +1554,7 @@
 	 */
 	@Test
 	public void testTeam_PUSH_REWIND() throws Exception {
-		RepositoryModel repository = new RepositoryModel("myrepo.git", null, null, new Date());
+		RepositoryModel repository = new RepositoryModel("myrepo.git", null, new Date());
 		repository.authorizationControl = AuthorizationControl.NAMED;
 		repository.accessRestriction = AccessRestrictionType.PUSH;
 
@@ -1577,7 +1577,7 @@
 	 */
 	@Test
 	public void testTeam_CLONE_REWIND() throws Exception {
-		RepositoryModel repository = new RepositoryModel("myrepo.git", null, null, new Date());
+		RepositoryModel repository = new RepositoryModel("myrepo.git", null, new Date());
 		repository.authorizationControl = AuthorizationControl.NAMED;
 		repository.accessRestriction = AccessRestrictionType.CLONE;
 
@@ -1600,7 +1600,7 @@
 	 */
 	@Test
 	public void testTeam_VIEW_REWIND() throws Exception {
-		RepositoryModel repository = new RepositoryModel("myrepo.git", null, null, new Date());
+		RepositoryModel repository = new RepositoryModel("myrepo.git", null, new Date());
 		repository.authorizationControl = AuthorizationControl.NAMED;
 		repository.accessRestriction = AccessRestrictionType.VIEW;
 
@@ -1624,7 +1624,7 @@
 	 */
 	@Test
 	public void testTeam_NONE_CLONE() throws Exception {
-		RepositoryModel repository = new RepositoryModel("myrepo.git", null, null, new Date());
+		RepositoryModel repository = new RepositoryModel("myrepo.git", null, new Date());
 		repository.authorizationControl = AuthorizationControl.NAMED;
 		repository.accessRestriction = AccessRestrictionType.NONE;
 
@@ -1647,7 +1647,7 @@
 	 */
 	@Test
 	public void testTeam_PUSH_CLONE() throws Exception {
-		RepositoryModel repository = new RepositoryModel("myrepo.git", null, null, new Date());
+		RepositoryModel repository = new RepositoryModel("myrepo.git", null, new Date());
 		repository.authorizationControl = AuthorizationControl.NAMED;
 		repository.accessRestriction = AccessRestrictionType.PUSH;
 
@@ -1670,7 +1670,7 @@
 	 */
 	@Test
 	public void testTeam_CLONE_CLONE() throws Exception {
-		RepositoryModel repository = new RepositoryModel("myrepo.git", null, null, new Date());
+		RepositoryModel repository = new RepositoryModel("myrepo.git", null, new Date());
 		repository.authorizationControl = AuthorizationControl.NAMED;
 		repository.accessRestriction = AccessRestrictionType.CLONE;
 
@@ -1693,7 +1693,7 @@
 	 */
 	@Test
 	public void testTeam_VIEW_CLONE() throws Exception {
-		RepositoryModel repository = new RepositoryModel("myrepo.git", null, null, new Date());
+		RepositoryModel repository = new RepositoryModel("myrepo.git", null, new Date());
 		repository.authorizationControl = AuthorizationControl.NAMED;
 		repository.accessRestriction = AccessRestrictionType.VIEW;
 
@@ -1717,7 +1717,7 @@
 	 */
 	@Test
 	public void testTeam_NONE_VIEW() throws Exception {
-		RepositoryModel repository = new RepositoryModel("myrepo.git", null, null, new Date());
+		RepositoryModel repository = new RepositoryModel("myrepo.git", null, new Date());
 		repository.authorizationControl = AuthorizationControl.NAMED;
 		repository.accessRestriction = AccessRestrictionType.NONE;
 
@@ -1740,7 +1740,7 @@
 	 */
 	@Test
 	public void testTeam_PUSH_VIEW() throws Exception {
-		RepositoryModel repository = new RepositoryModel("myrepo.git", null, null, new Date());
+		RepositoryModel repository = new RepositoryModel("myrepo.git", null, new Date());
 		repository.authorizationControl = AuthorizationControl.NAMED;
 		repository.accessRestriction = AccessRestrictionType.PUSH;
 
@@ -1763,7 +1763,7 @@
 	 */
 	@Test
 	public void testTeam_CLONE_VIEW() throws Exception {
-		RepositoryModel repository = new RepositoryModel("myrepo.git", null, null, new Date());
+		RepositoryModel repository = new RepositoryModel("myrepo.git", null, new Date());
 		repository.authorizationControl = AuthorizationControl.NAMED;
 		repository.accessRestriction = AccessRestrictionType.CLONE;
 
@@ -1786,7 +1786,7 @@
 	 */
 	@Test
 	public void testTeam_VIEW_VIEW() throws Exception {
-		RepositoryModel repository = new RepositoryModel("myrepo.git", null, null, new Date());
+		RepositoryModel repository = new RepositoryModel("myrepo.git", null, new Date());
 		repository.authorizationControl = AuthorizationControl.NAMED;
 		repository.accessRestriction = AccessRestrictionType.VIEW;
 
@@ -1809,7 +1809,7 @@
 	 */
 	@Test
 	public void testTeamMember_NONE_NONE() throws Exception {
-		RepositoryModel repository = new RepositoryModel("myrepo.git", null, null, new Date());
+		RepositoryModel repository = new RepositoryModel("myrepo.git", null, new Date());
 		repository.authorizationControl = AuthorizationControl.NAMED;
 		repository.accessRestriction = AccessRestrictionType.NONE;
 
@@ -1833,7 +1833,7 @@
 	 */
 	@Test
 	public void testTeamMember_PUSH_NONE() throws Exception {
-		RepositoryModel repository = new RepositoryModel("myrepo.git", null, null, new Date());
+		RepositoryModel repository = new RepositoryModel("myrepo.git", null, new Date());
 		repository.authorizationControl = AuthorizationControl.NAMED;
 		repository.accessRestriction = AccessRestrictionType.PUSH;
 
@@ -1857,7 +1857,7 @@
 	 */
 	@Test
 	public void testTeamMember_CLONE_NONE() throws Exception {
-		RepositoryModel repository = new RepositoryModel("myrepo.git", null, null, new Date());
+		RepositoryModel repository = new RepositoryModel("myrepo.git", null, new Date());
 		repository.authorizationControl = AuthorizationControl.NAMED;
 		repository.accessRestriction = AccessRestrictionType.CLONE;
 
@@ -1881,7 +1881,7 @@
 	 */
 	@Test
 	public void testTeamMember_VIEW_NONE() throws Exception {
-		RepositoryModel repository = new RepositoryModel("myrepo.git", null, null, new Date());
+		RepositoryModel repository = new RepositoryModel("myrepo.git", null, new Date());
 		repository.authorizationControl = AuthorizationControl.NAMED;
 		repository.accessRestriction = AccessRestrictionType.VIEW;
 
@@ -1906,7 +1906,7 @@
 	 */
 	@Test
 	public void testTeamMember_NONE_PUSH() throws Exception {
-		RepositoryModel repository = new RepositoryModel("myrepo.git", null, null, new Date());
+		RepositoryModel repository = new RepositoryModel("myrepo.git", null, new Date());
 		repository.authorizationControl = AuthorizationControl.NAMED;
 		repository.accessRestriction = AccessRestrictionType.NONE;
 
@@ -1931,7 +1931,7 @@
 	 */
 	@Test
 	public void testTeamMember_PUSH_PUSH() throws Exception {
-		RepositoryModel repository = new RepositoryModel("myrepo.git", null, null, new Date());
+		RepositoryModel repository = new RepositoryModel("myrepo.git", null, new Date());
 		repository.authorizationControl = AuthorizationControl.NAMED;
 		repository.accessRestriction = AccessRestrictionType.PUSH;
 
@@ -1956,7 +1956,7 @@
 	 */
 	@Test
 	public void testTeamMember_CLONE_PUSH() throws Exception {
-		RepositoryModel repository = new RepositoryModel("myrepo.git", null, null, new Date());
+		RepositoryModel repository = new RepositoryModel("myrepo.git", null, new Date());
 		repository.authorizationControl = AuthorizationControl.NAMED;
 		repository.accessRestriction = AccessRestrictionType.CLONE;
 
@@ -1981,7 +1981,7 @@
 	 */
 	@Test
 	public void testTeamMember_VIEW_PUSH() throws Exception {
-		RepositoryModel repository = new RepositoryModel("myrepo.git", null, null, new Date());
+		RepositoryModel repository = new RepositoryModel("myrepo.git", null, new Date());
 		repository.authorizationControl = AuthorizationControl.NAMED;
 		repository.accessRestriction = AccessRestrictionType.VIEW;
 
@@ -2007,7 +2007,7 @@
 	 */
 	@Test
 	public void testTeamMember_NONE_CREATE() throws Exception {
-		RepositoryModel repository = new RepositoryModel("myrepo.git", null, null, new Date());
+		RepositoryModel repository = new RepositoryModel("myrepo.git", null, new Date());
 		repository.authorizationControl = AuthorizationControl.NAMED;
 		repository.accessRestriction = AccessRestrictionType.NONE;
 
@@ -2032,7 +2032,7 @@
 	 */
 	@Test
 	public void testTeamMember_PUSH_CREATE() throws Exception {
-		RepositoryModel repository = new RepositoryModel("myrepo.git", null, null, new Date());
+		RepositoryModel repository = new RepositoryModel("myrepo.git", null, new Date());
 		repository.authorizationControl = AuthorizationControl.NAMED;
 		repository.accessRestriction = AccessRestrictionType.PUSH;
 
@@ -2057,7 +2057,7 @@
 	 */
 	@Test
 	public void testTeamMember_CLONE_CREATE() throws Exception {
-		RepositoryModel repository = new RepositoryModel("myrepo.git", null, null, new Date());
+		RepositoryModel repository = new RepositoryModel("myrepo.git", null, new Date());
 		repository.authorizationControl = AuthorizationControl.NAMED;
 		repository.accessRestriction = AccessRestrictionType.CLONE;
 
@@ -2082,7 +2082,7 @@
 	 */
 	@Test
 	public void testTeamMember_VIEW_CREATE() throws Exception {
-		RepositoryModel repository = new RepositoryModel("myrepo.git", null, null, new Date());
+		RepositoryModel repository = new RepositoryModel("myrepo.git", null, new Date());
 		repository.authorizationControl = AuthorizationControl.NAMED;
 		repository.accessRestriction = AccessRestrictionType.VIEW;
 
@@ -2108,7 +2108,7 @@
 	 */
 	@Test
 	public void testTeamMember_NONE_DELETE() throws Exception {
-		RepositoryModel repository = new RepositoryModel("myrepo.git", null, null, new Date());
+		RepositoryModel repository = new RepositoryModel("myrepo.git", null, new Date());
 		repository.authorizationControl = AuthorizationControl.NAMED;
 		repository.accessRestriction = AccessRestrictionType.NONE;
 
@@ -2133,7 +2133,7 @@
 	 */
 	@Test
 	public void testTeamMember_PUSH_DELETE() throws Exception {
-		RepositoryModel repository = new RepositoryModel("myrepo.git", null, null, new Date());
+		RepositoryModel repository = new RepositoryModel("myrepo.git", null, new Date());
 		repository.authorizationControl = AuthorizationControl.NAMED;
 		repository.accessRestriction = AccessRestrictionType.PUSH;
 
@@ -2158,7 +2158,7 @@
 	 */
 	@Test
 	public void testTeamMember_CLONE_DELETE() throws Exception {
-		RepositoryModel repository = new RepositoryModel("myrepo.git", null, null, new Date());
+		RepositoryModel repository = new RepositoryModel("myrepo.git", null, new Date());
 		repository.authorizationControl = AuthorizationControl.NAMED;
 		repository.accessRestriction = AccessRestrictionType.CLONE;
 
@@ -2183,7 +2183,7 @@
 	 */
 	@Test
 	public void testTeamMember_VIEW_DELETE() throws Exception {
-		RepositoryModel repository = new RepositoryModel("myrepo.git", null, null, new Date());
+		RepositoryModel repository = new RepositoryModel("myrepo.git", null, new Date());
 		repository.authorizationControl = AuthorizationControl.NAMED;
 		repository.accessRestriction = AccessRestrictionType.VIEW;
 
@@ -2209,7 +2209,7 @@
 	 */
 	@Test
 	public void testTeamMember_NONE_REWIND() throws Exception {
-		RepositoryModel repository = new RepositoryModel("myrepo.git", null, null, new Date());
+		RepositoryModel repository = new RepositoryModel("myrepo.git", null, new Date());
 		repository.authorizationControl = AuthorizationControl.NAMED;
 		repository.accessRestriction = AccessRestrictionType.NONE;
 
@@ -2234,7 +2234,7 @@
 	 */
 	@Test
 	public void testTeamMember_PUSH_REWIND() throws Exception {
-		RepositoryModel repository = new RepositoryModel("myrepo.git", null, null, new Date());
+		RepositoryModel repository = new RepositoryModel("myrepo.git", null, new Date());
 		repository.authorizationControl = AuthorizationControl.NAMED;
 		repository.accessRestriction = AccessRestrictionType.PUSH;
 
@@ -2259,7 +2259,7 @@
 	 */
 	@Test
 	public void testTeamMember_CLONE_REWIND() throws Exception {
-		RepositoryModel repository = new RepositoryModel("myrepo.git", null, null, new Date());
+		RepositoryModel repository = new RepositoryModel("myrepo.git", null, new Date());
 		repository.authorizationControl = AuthorizationControl.NAMED;
 		repository.accessRestriction = AccessRestrictionType.CLONE;
 
@@ -2284,7 +2284,7 @@
 	 */
 	@Test
 	public void testTeamMember_VIEW_REWIND() throws Exception {
-		RepositoryModel repository = new RepositoryModel("myrepo.git", null, null, new Date());
+		RepositoryModel repository = new RepositoryModel("myrepo.git", null, new Date());
 		repository.authorizationControl = AuthorizationControl.NAMED;
 		repository.accessRestriction = AccessRestrictionType.VIEW;
 
@@ -2310,7 +2310,7 @@
 	 */
 	@Test
 	public void testTeamMember_NONE_CLONE() throws Exception {
-		RepositoryModel repository = new RepositoryModel("myrepo.git", null, null, new Date());
+		RepositoryModel repository = new RepositoryModel("myrepo.git", null, new Date());
 		repository.authorizationControl = AuthorizationControl.NAMED;
 		repository.accessRestriction = AccessRestrictionType.NONE;
 
@@ -2335,7 +2335,7 @@
 	 */
 	@Test
 	public void testTeamMember_PUSH_CLONE() throws Exception {
-		RepositoryModel repository = new RepositoryModel("myrepo.git", null, null, new Date());
+		RepositoryModel repository = new RepositoryModel("myrepo.git", null, new Date());
 		repository.authorizationControl = AuthorizationControl.NAMED;
 		repository.accessRestriction = AccessRestrictionType.PUSH;
 
@@ -2360,7 +2360,7 @@
 	 */
 	@Test
 	public void testTeamMember_CLONE_CLONE() throws Exception {
-		RepositoryModel repository = new RepositoryModel("myrepo.git", null, null, new Date());
+		RepositoryModel repository = new RepositoryModel("myrepo.git", null, new Date());
 		repository.authorizationControl = AuthorizationControl.NAMED;
 		repository.accessRestriction = AccessRestrictionType.CLONE;
 
@@ -2385,7 +2385,7 @@
 	 */
 	@Test
 	public void testTeamMember_VIEW_CLONE() throws Exception {
-		RepositoryModel repository = new RepositoryModel("myrepo.git", null, null, new Date());
+		RepositoryModel repository = new RepositoryModel("myrepo.git", null, new Date());
 		repository.authorizationControl = AuthorizationControl.NAMED;
 		repository.accessRestriction = AccessRestrictionType.VIEW;
 
@@ -2411,7 +2411,7 @@
 	 */
 	@Test
 	public void testTeamMember_NONE_VIEW() throws Exception {
-		RepositoryModel repository = new RepositoryModel("myrepo.git", null, null, new Date());
+		RepositoryModel repository = new RepositoryModel("myrepo.git", null, new Date());
 		repository.authorizationControl = AuthorizationControl.NAMED;
 		repository.accessRestriction = AccessRestrictionType.NONE;
 
@@ -2436,7 +2436,7 @@
 	 */
 	@Test
 	public void testTeamMember_PUSH_VIEW() throws Exception {
-		RepositoryModel repository = new RepositoryModel("myrepo.git", null, null, new Date());
+		RepositoryModel repository = new RepositoryModel("myrepo.git", null, new Date());
 		repository.authorizationControl = AuthorizationControl.NAMED;
 		repository.accessRestriction = AccessRestrictionType.PUSH;
 
@@ -2461,7 +2461,7 @@
 	 */
 	@Test
 	public void testTeamMember_CLONE_VIEW() throws Exception {
-		RepositoryModel repository = new RepositoryModel("myrepo.git", null, null, new Date());
+		RepositoryModel repository = new RepositoryModel("myrepo.git", null, new Date());
 		repository.authorizationControl = AuthorizationControl.NAMED;
 		repository.accessRestriction = AccessRestrictionType.CLONE;
 
@@ -2486,7 +2486,7 @@
 	 */
 	@Test
 	public void testTeamMember_VIEW_VIEW() throws Exception {
-		RepositoryModel repository = new RepositoryModel("myrepo.git", null, null, new Date());
+		RepositoryModel repository = new RepositoryModel("myrepo.git", null, new Date());
 		repository.authorizationControl = AuthorizationControl.NAMED;
 		repository.accessRestriction = AccessRestrictionType.VIEW;
 
@@ -2508,12 +2508,12 @@
 
 	@Test
 	public void testOwner() throws Exception {
-		RepositoryModel repository = new RepositoryModel("~jj/myrepo.git", null, null, new Date());
+		RepositoryModel repository = new RepositoryModel("~jj/myrepo.git", null, new Date());
 		repository.authorizationControl = AuthorizationControl.NAMED;
 		repository.accessRestriction = AccessRestrictionType.VIEW;
 
 		UserModel user = new UserModel("test");
-		repository.addOwner(user.username);
+		user.own(repository);
 
 		assertFalse("user SHOULD NOT HAVE a repository permission!", user.hasRepositoryPermission(repository.name));
 		assertTrue("owner CAN NOT view!", user.canView(repository));
@@ -2528,7 +2528,7 @@
 
 		assertTrue("owner CAN NOT fork!", user.canFork(repository));
 
-		assertFalse("owner CAN NOT delete!", user.canDelete(repository));
+		assertFalse("owner CAN delete someone elses personal repo!", user.canDelete(repository));
 		assertTrue("owner CAN NOT edit!", user.canEdit(repository));
 
 		// test personal repo owner
@@ -2548,19 +2548,19 @@
 
 		assertTrue("jj CAN NOT delete!", jj.canDelete(repository));
 		assertTrue("jj CAN NOT edit!", jj.canEdit(repository));
-		assertTrue(repository.isOwner(jj.username));
+		assertTrue(jj.isOwner(repository));
 	}
 
 	@Test
 	public void testMultipleOwners() throws Exception {
-		RepositoryModel repository = new RepositoryModel("~jj/myrepo.git", null, null, new Date());
+		RepositoryModel repository = new RepositoryModel("~jj/myrepo.git", null, new Date());
 		repository.authorizationControl = AuthorizationControl.NAMED;
 		repository.accessRestriction = AccessRestrictionType.VIEW;
 
 		UserModel user = new UserModel("test");
-		repository.addOwner(user.username);
+		user.own(repository);
 		UserModel user2 = new UserModel("test2");
-		repository.addOwner(user2.username);
+		user2.own(repository);
 
 		// first owner
 		assertFalse("user SHOULD NOT HAVE a repository permission!", user.hasRepositoryPermission(repository.name));
@@ -2596,8 +2596,8 @@
 		assertFalse("owner CAN NOT delete!", user2.canDelete(repository));
 		assertTrue("owner CAN NOT edit!", user2.canEdit(repository));
 
-		assertTrue(repository.isOwner(user.username));
-		assertTrue(repository.isOwner(user2.username));
+		assertTrue(user.isOwner(repository));
+		assertTrue(user2.isOwner(repository));
 
 		// test personal repo owner
 		UserModel jj = new UserModel("jj");
@@ -2616,17 +2616,17 @@
 
 		assertTrue("jj CAN NOT delete!", jj.canDelete(repository));
 		assertTrue("jj CAN NOT edit!", jj.canEdit(repository));
-		assertTrue(repository.isOwner(jj.username));
+		assertTrue(jj.isOwner(repository));
 	}
 
 	@Test
 	public void testOwnerPersonalRepository() throws Exception {
-		RepositoryModel repository = new RepositoryModel("~test/myrepo.git", null, null, new Date());
+		RepositoryModel repository = new RepositoryModel("~test/myrepo.git", null, new Date());
 		repository.authorizationControl = AuthorizationControl.NAMED;
 		repository.accessRestriction = AccessRestrictionType.VIEW;
 
 		UserModel user = new UserModel("test");
-		repository.addOwner(user.username);
+		user.own(repository);
 
 		assertFalse("user SHOULD NOT HAVE a repository permission!", user.hasRepositoryPermission(repository.name));
 		assertTrue("user CAN NOT view!", user.canView(repository));
@@ -2647,12 +2647,11 @@
 
 	@Test
 	public void testVisitorPersonalRepository() throws Exception {
-		RepositoryModel repository = new RepositoryModel("~test/myrepo.git", null, null, new Date());
+		RepositoryModel repository = new RepositoryModel("~test/myrepo.git", null, new Date());
 		repository.authorizationControl = AuthorizationControl.NAMED;
 		repository.accessRestriction = AccessRestrictionType.VIEW;
 
 		UserModel user = new UserModel("visitor");
-		repository.addOwner("test");
 
 		assertFalse("user HAS a repository permission!", user.hasRepositoryPermission(repository.name));
 		assertFalse("user CAN view!", user.canView(repository));
@@ -2673,7 +2672,7 @@
 
 	@Test
 	public void testRegexMatching() throws Exception {
-		RepositoryModel repository = new RepositoryModel("ubercool/_my-r/e~po.git", null, null, new Date());
+		RepositoryModel repository = new RepositoryModel("ubercool/_my-r/e~po.git", null, new Date());
 		repository.authorizationControl = AuthorizationControl.NAMED;
 		repository.accessRestriction = AccessRestrictionType.VIEW;
 
@@ -2704,7 +2703,7 @@
 		user.setRepositoryPermission("[^~].*", AccessPermission.CLONE);
 
 		// common
-		RepositoryModel common = new RepositoryModel("ubercool/_my-r/e~po.git", null, null, new Date());
+		RepositoryModel common = new RepositoryModel("ubercool/_my-r/e~po.git", null, new Date());
 		common.authorizationControl = AuthorizationControl.NAMED;
 		common.accessRestriction = AccessRestrictionType.VIEW;
 
@@ -2725,7 +2724,7 @@
 		assertFalse("user CAN edit!", user.canEdit(common));
 
 		// personal
-		RepositoryModel personal = new RepositoryModel("~ubercool/_my-r/e~po.git", null, null, new Date());
+		RepositoryModel personal = new RepositoryModel("~ubercool/_my-r/e~po.git", null, new Date());
 		personal.authorizationControl = AuthorizationControl.NAMED;
 		personal.accessRestriction = AccessRestrictionType.VIEW;
 
@@ -2748,7 +2747,7 @@
 
 	@Test
 	public void testRegexMatching2() throws Exception {
-		RepositoryModel personal = new RepositoryModel("~ubercool/_my-r/e~po.git", null, null, new Date());
+		RepositoryModel personal = new RepositoryModel("~ubercool/_my-r/e~po.git", null, new Date());
 		personal.authorizationControl = AuthorizationControl.NAMED;
 		personal.accessRestriction = AccessRestrictionType.VIEW;
 
@@ -2778,7 +2777,7 @@
 
 	@Test
 	public void testRegexOrder() throws Exception {
-		RepositoryModel personal = new RepositoryModel("~ubercool/_my-r/e~po.git", null, null, new Date());
+		RepositoryModel personal = new RepositoryModel("~ubercool/_my-r/e~po.git", null, new Date());
 		personal.authorizationControl = AuthorizationControl.NAMED;
 		personal.accessRestriction = AccessRestrictionType.VIEW;
 
@@ -2827,7 +2826,7 @@
 
 	@Test
 	public void testExclusion() throws Exception {
-		RepositoryModel personal = new RepositoryModel("~ubercool/_my-r/e~po.git", null, null, new Date());
+		RepositoryModel personal = new RepositoryModel("~ubercool/_my-r/e~po.git", null, new Date());
 		personal.authorizationControl = AuthorizationControl.NAMED;
 		personal.accessRestriction = AccessRestrictionType.VIEW;
 
@@ -2882,7 +2881,7 @@
 
 	@Test
 	public void testIsFrozen() throws Exception {
-		RepositoryModel repo = new RepositoryModel("somerepo.git", null, null, new Date());
+		RepositoryModel repo = new RepositoryModel("somerepo.git", null, new Date());
 		repo.authorizationControl = AuthorizationControl.NAMED;
 		repo.accessRestriction = AccessRestrictionType.NONE;
 
@@ -2900,7 +2899,7 @@
 
 	@Test
 	public void testIsBare() throws Exception {
-		RepositoryModel repo = new RepositoryModel("somerepo.git", null, null, new Date());
+		RepositoryModel repo = new RepositoryModel("somerepo.git", null, new Date());
 		repo.authorizationControl = AuthorizationControl.NAMED;
 		repo.accessRestriction = AccessRestrictionType.NONE;
 
@@ -2918,7 +2917,7 @@
 
 	@Test
 	public void testIsMirror() throws Exception {
-		RepositoryModel repo = new RepositoryModel("somerepo.git", null, null, new Date());
+		RepositoryModel repo = new RepositoryModel("somerepo.git", null, new Date());
 		repo.authorizationControl = AuthorizationControl.NAMED;
 		repo.accessRestriction = AccessRestrictionType.NONE;
 
diff --git a/src/test/java/com/gitblit/tests/RedisTicketServiceTest.java b/src/test/java/com/gitblit/tests/RedisTicketServiceTest.java
index b782b44..97717d8 100644
--- a/src/test/java/com/gitblit/tests/RedisTicketServiceTest.java
+++ b/src/test/java/com/gitblit/tests/RedisTicketServiceTest.java
@@ -39,7 +39,7 @@
  */
 public class RedisTicketServiceTest extends TicketServiceTest {
 
-	final RepositoryModel repo = new RepositoryModel("tickets/redis.git", null, null, null);
+	final RepositoryModel repo = new RepositoryModel("tickets/redis.git", null, null);
 
 	@Override
 	protected RepositoryModel getRepository() {
diff --git a/src/test/java/com/gitblit/tests/RpcTests.java b/src/test/java/com/gitblit/tests/RpcTests.java
index 51b4671..2a48a8b 100644
--- a/src/test/java/com/gitblit/tests/RpcTests.java
+++ b/src/test/java/com/gitblit/tests/RpcTests.java
@@ -177,7 +177,6 @@
 		RepositoryModel model = new RepositoryModel();

 		model.name = "garbagerepo.git";

 		model.description = "created by RpcUtils";

-		model.addOwner("garbage");

 		model.accessRestriction = AccessRestrictionType.VIEW;

 		model.authorizationControl = AuthorizationControl.AUTHENTICATED;

 

diff --git a/src/test/java/com/gitblit/tests/UserServiceTest.java b/src/test/java/com/gitblit/tests/UserServiceTest.java
index cdb0a33..d3a96c8 100644
--- a/src/test/java/com/gitblit/tests/UserServiceTest.java
+++ b/src/test/java/com/gitblit/tests/UserServiceTest.java
@@ -106,9 +106,9 @@
 		assertEquals(1, service.getAllTeamNames().size());

 		assertEquals("admins", service.getAllTeamNames().get(0));

 

-		RepositoryModel newrepo1 = new RepositoryModel("newrepo1", null, null, null);

+		RepositoryModel newrepo1 = new RepositoryModel("newrepo1", null, null);

 		newrepo1.accessRestriction = AccessRestrictionType.VIEW;

-		RepositoryModel NEWREPO1 = new RepositoryModel("NEWREPO1", null, null, null);

+		RepositoryModel NEWREPO1 = new RepositoryModel("NEWREPO1", null, null);

 		NEWREPO1.accessRestriction = AccessRestrictionType.VIEW;

 

 		// remove newrepo1 from test user

@@ -144,9 +144,9 @@
 		assertTrue(user.canView(NEWREPO1));

 

 		// rename the team and add new repository

-		RepositoryModel newrepo2 = new RepositoryModel("newrepo2", null, null, null);

+		RepositoryModel newrepo2 = new RepositoryModel("newrepo2", null, null);

 		newrepo2.accessRestriction = AccessRestrictionType.VIEW;

-		RepositoryModel NEWREPO2 = new RepositoryModel("NEWREPO2", null, null, null);

+		RepositoryModel NEWREPO2 = new RepositoryModel("NEWREPO2", null, null);

 		NEWREPO2.accessRestriction = AccessRestrictionType.VIEW;

 

 		team.addRepositoryPermission(newrepo2.name);