diff --git a/.gitignore b/.gitignore
index 94a210b94612ae613a7f677ed731da6fa847e334..24297583fd23c2f0f4eb0de598bed5517278947b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -24,3 +24,4 @@ db/data.yml
 .DS_Store
 .chef
 vendor/bundle/*
+rails_best_practices_output.html
diff --git a/.travis.yml b/.travis.yml
index 59d22f32ee32f39e39b9ab7f7dfff4a4cda976df..e8bd744267fc0c5be4e9625c97980d9e6374721d 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -8,7 +8,7 @@ branches:
   only:
     - 'master'
 rvm:
-  - 1.9.3
+  - 1.9.2
 services:
   - mysql
   - postgresql
diff --git a/Gemfile b/Gemfile
index 4defcec325fe36bb79614a54698c1ff7afdc59dd..6a2d6a8042db38358b0a7bdc11a2f93ca59a7913 100644
--- a/Gemfile
+++ b/Gemfile
@@ -123,6 +123,8 @@ group :development do
   gem 'better_errors'
   gem 'binding_of_caller'
 
+  gem 'rails_best_practices'
+
   # Docs generator
   gem "sdoc"
 end
diff --git a/Gemfile.lock b/Gemfile.lock
index 4b08c3141b44aaedb01dcd372488affb0c483636..722881e5768ee2953377a21a7655901829922660 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -132,6 +132,8 @@ GEM
     chosen-rails (0.9.8)
       railties (~> 3.0)
       thor (~> 0.14)
+    code_analyzer (0.3.1)
+      sexp_processor
     coderay (1.0.8)
     coffee-rails (3.2.2)
       coffee-script (>= 2.2.0)
@@ -302,6 +304,7 @@ GEM
     pg (0.14.1)
     polyglot (0.3.3)
     posix-spawn (0.3.6)
+    progressbar (0.12.0)
     pry (0.9.10)
       coderay (~> 1.0.5)
       method_source (~> 0.8)
@@ -335,6 +338,14 @@ GEM
     rails-dev-tweaks (0.6.1)
       actionpack (~> 3.1)
       railties (~> 3.1)
+    rails_best_practices (1.13.2)
+      activesupport
+      awesome_print
+      code_analyzer
+      colored
+      erubis
+      i18n
+      progressbar
     railties (3.2.9)
       actionpack (= 3.2.9)
       activesupport (= 3.2.9)
@@ -393,6 +404,7 @@ GEM
       multi_json (~> 1.0)
       rubyzip
     settingslogic (2.0.8)
+    sexp_processor (4.1.3)
     shoulda-matchers (1.3.0)
       activesupport (>= 3.0.0)
     simplecov (0.7.1)
@@ -512,6 +524,7 @@ DEPENDENCIES
   rack-mini-profiler
   rails (= 3.2.9)
   rails-dev-tweaks
+  rails_best_practices
   raphael-rails (= 1.5.2)
   rb-fsevent
   rb-inotify
diff --git a/app/assets/stylesheets/gitlab_bootstrap/blocks.scss b/app/assets/stylesheets/gitlab_bootstrap/blocks.scss
index f9c8b7b05ea0c54c2541aa6dc9b54b0f75c37efc..8cb1c045778ef3aa8b990c6fae0fc34fe4dbbbdd 100644
--- a/app/assets/stylesheets/gitlab_bootstrap/blocks.scss
+++ b/app/assets/stylesheets/gitlab_bootstrap/blocks.scss
@@ -1,23 +1,24 @@
 /**
  * ===================================
- * Contain 3 main UI block elements:
- *   .main_box - for show pages
- *   .ui-box   - for simple block & widgets
+ * Contain UI block elements:
+ *   .ui-box   - for any block & widgets
  * ===================================
  */
 
 /**
- *  UI box element
- *  contains top, middle, bottom blocks
+ * UI Block
  *
  */
-.main_box {
-  @extend .borders;
-  @extend .prepend-top-20;
-  @extend .append-bottom-20;
-  border-width: 1px;
+.ui-box {
+  background: #F9F9F9;
+  margin-bottom: 25px;
+  border: 1px solid #CCC;
   @include solid-shade;
 
+  &.ui-box-show {
+    margin:20px 0;
+    background: #FFF;
+  }
 
   img { max-width: 100%; }
 
@@ -27,9 +28,9 @@
     }
   }
 
-  .top_box_content,
-  .middle_box_content,
-  .bottom_box_content {
+  .ui-box-head,
+  .ui-box-body,
+  .ui-box-bottom {
     padding: 15px;
     word-wrap: break-word;
 
@@ -39,19 +40,25 @@
       border: none;
       padding: 0;
     }
+
+    .clearfix {
+      margin: 0;
+    }
   }
 
-  .top_box_content {
+  .ui-box-head {
     .box-title {
       color: $style_color;
       font-size: 18px;
       font-weight: normal;
       line-height: 28px;
     }
+    h3 {
+      margin: 0;
+    }
   }
 
-  .middle_box_content {
-    @include border-radius(0);
+  .ui-box-body {
     border: none;
     font-size: 12px;
     background-color: #f5f5f5;
@@ -59,24 +66,9 @@
     border-top: 1px solid #eee;
   }
 
-  .bottom_box_content {
+  .ui-box-bottom {
     border-top: 1px solid #eee;
   }
-}
-
-/**
- * Big UI Block for show page content
- *
- */
-.ui-box {
-  background: #F9F9F9;
-  margin-bottom: 25px;
-
-  border: 1px solid #eaeaea;
-  @include border-radius(4px);
-
-  border-color: #CCC;
-  @include solid-shade;
 
   &.white {
     background: #fff;
@@ -86,47 +78,47 @@
     margin: 0;
   }
 
-  h5, .title {
-    padding: 0 10px;
-    @include border-radius(4px 4px 0 0);
+  .title {
     @include bg-gray-gradient;
-    border-top: 1px solid #eaeaea;
-    border-bottom: 1px solid #bbb;
+    border-bottom: 1px solid #CCC;
+    color: #456;
+    font-size: 16px;
+    text-shadow: 0 1px 1px #fff;
+    padding: 0px 10px;
+    line-height: 36px;
+    font-size: 14px;
+    font-weight: normal;
 
     > a {
       text-shadow: 0 1px 1px #fff;
     }
 
-    &.small {
-      line-height: 28px;
-      font-size: 14px;
-      line-height: 28px;
-      text-shadow: 0 1px 1px white;
-    }
-
     form {
-      padding: 9px 0;
-      margin: 0px;
+      margin-bottom: 0;
+      margin-top: 3px;
     }
 
     .nav-pills {
-      li {
-        padding: 3px 0;
-        &.active a { background-color: $style_color; }
-        a {
-          @include border-radius(7px);
+      > li {
+        > a {
+          padding: 13px;
+          margin: 0;
+          font-size: 13px;
+        }
+        &.active {
+          > a {
+            background: #D5D5D5;
+            color: $style_color;
+            @include border-radius(0);
+            border-radius: 0;
+            border-left: 1px solid #CCC;
+            border-right: 1px solid #CCC;
+          }
         }
       }
     }
   }
 
-  .bottom {
-    @include bg-gray-gradient;
-    @include border-radius(0 0 4px 4px);
-    border-bottom: none;
-    border-top: 1px solid #bbb;
-  }
-
   &.padded {
     h5, .title {
       margin: -20px;
@@ -143,6 +135,7 @@
       color: #777;
     }
   }
+
   .row_title {
     font-weight: bold;
     color: #444;
@@ -151,8 +144,4 @@
       text-decoration: underline;
     }
   }
-
-  .ui-box-body {
-    padding: 10px;
-  }
 }
diff --git a/app/assets/stylesheets/gitlab_bootstrap/lists.scss b/app/assets/stylesheets/gitlab_bootstrap/lists.scss
index edaf3cef2cf02604bf3fc757d28f153499001bfe..0f893a553eec3642cbf3261e4a50a6a412b21832 100644
--- a/app/assets/stylesheets/gitlab_bootstrap/lists.scss
+++ b/app/assets/stylesheets/gitlab_bootstrap/lists.scss
@@ -23,14 +23,12 @@
       border-bottom: 1px solid #ADF;
     }
 
-    &:first-child {
-      @include border-radius(4px 4px 0 0);
-      border-top: none;
-    }
-
     &:last-child {
-      @include border-radius(0 0 4px 4px);
-      border: none;
+      border-bottom: none;
+
+      &.bottom {
+        background: #f5f5f5;
+      }
     }
 
     .author { color: #999; }
diff --git a/app/assets/stylesheets/gitlab_bootstrap/tables.scss b/app/assets/stylesheets/gitlab_bootstrap/tables.scss
index 5905efd3aae68a2976012a5faf29392e6bf9ecfb..7a9eac8256680301c8c1031ac3b68aa91efcdc3e 100644
--- a/app/assets/stylesheets/gitlab_bootstrap/tables.scss
+++ b/app/assets/stylesheets/gitlab_bootstrap/tables.scss
@@ -25,7 +25,7 @@ table {
   }
 
   th, td {
-    padding: 8px;
+    padding: 10px;
     line-height: 18px;
     text-align: left;
   }
diff --git a/app/assets/stylesheets/sections/commits.scss b/app/assets/stylesheets/sections/commits.scss
index 7ed53333f8cbce5cb0396250a2b3f49681a1f0c5..ebec51c971534f7a769c42d6722833f070429cb5 100644
--- a/app/assets/stylesheets/sections/commits.scss
+++ b/app/assets/stylesheets/sections/commits.scss
@@ -1,74 +1,17 @@
-.commit-box {
-  @extend .main_box;
-
-  .commit-head {
-    @extend .top_box_content;
-
-    .commit-title {
-      line-height: 26px;
-      margin: 0;
-    }
-
-    .commit-description {
-      font-size: 14px;
-      border: none;
-      background-color: white;
-      padding-top: 10px;
-    }
-
-    .browse-button {
-      @extend .btn;
-      @extend .btn-small;
-      float: right;
-    }
-  }
-
-  .commit-info {
-    @extend .middle_box_content;
-    @extend .clearfix;
-
-    .sha-block {
-      text-align: right;
-      &:first-child {
-        padding-bottom: 6px;
-      }
-
-      a {
-        border-bottom: 1px solid #aaa;
-        margin-left: 9px;
-      }
-    }
-
-    &.merge-commit .sha-block {
-      clear: right;
-    }
-
-    .committer {
-      padding-left: 32px;
-    }
-
-    .author a,
-    .committer a {
-      font-size: 14px;
-      line-height: 22px;
-      text-shadow: 0 1px 1px #fff;
-      color: #777;
-      &:hover {
-        color: #999;
-      }
-    }
-
-    .avatar {
-      margin-right: 10px;
-    }
-  }
-}
-
 /**
  *
  * COMMIT SHOw
  *
  */
+.commit-committer-link,
+.commit-author-link {
+  font-size: 13px;
+  color: #555;
+  &:hover {
+    color: #999;
+  }
+}
+
 .diff_file {
   border: 1px solid #CCC;
   margin-bottom: 1em;
@@ -255,13 +198,6 @@
     min-width: 65px;
     font-family: $monospace;
   }
-
-  .commit-author-name {
-    color: #777;
-    &:hover {
-      color: #999;
-    }
-  }
 }
 
 .diff_file_header a,
diff --git a/app/assets/stylesheets/sections/issues.scss b/app/assets/stylesheets/sections/issues.scss
index fd995728978c18237d618c4f9bf5f3ba5acdef74..79c592822ce414f9a73854f3968696e8809479c7 100644
--- a/app/assets/stylesheets/sections/issues.scss
+++ b/app/assets/stylesheets/sections/issues.scss
@@ -1,31 +1,3 @@
-.issue_form_box {
-  @extend .main_box;
-  .issue_title {
-    @extend .top_box_content;
-    .clearfix {
-      margin-bottom: 0px;
-      input {
-        @extend .span8;
-      }
-    }
-  }
-  .issue_middle_block {
-    @extend .middle_box_content;
-    height: 30px;
-    .issue_assignee {
-      @extend .span6;
-      float: left;
-    }
-    .issue_milestone {
-      @extend .span4;
-      float: left;
-    }
-  }
-  .issue_description {
-    @extend .bottom_box_content;
-  }
-}
-
 .issues_table {
   .issue {
     padding: 7px 10px;
@@ -89,31 +61,25 @@ input.check_all_issues {
 
 #issues-table-holder {
   .issues_filters {
-    form {
-      padding: 0;
-      margin: 0;
-      margin-top:7px
-    }
   }
 
   .issues_bulk_update {
     margin: 0;
     form {
-      padding: 0;
-      margin: 0;
-      margin-top:7px
+      float:left;
     }
     .update_selected_issues {
       position: relative;
-      top:-2px;
+      top:5px;
       margin-left: 4px;
       float: left;
     }
 
     .update_issues_text {
       padding: 3px;
-      line-height: 18px;
+      line-height: 28px;
       float: left;
+      color: #479;
     }
   }
 }
diff --git a/app/assets/stylesheets/sections/merge_requests.scss b/app/assets/stylesheets/sections/merge_requests.scss
index 9fb1d14967fc295e4e8542c8535a95d7ea4088ca..66ec642e057829966991a90e100cfeee35dadcdb 100644
--- a/app/assets/stylesheets/sections/merge_requests.scss
+++ b/app/assets/stylesheets/sections/merge_requests.scss
@@ -1,17 +1,3 @@
-/**
- * MR form
- *
- */
-
-.mr_branch_box {
-  @extend .ui-box;
-  margin-bottom: 20px;
-
-  .body {
-    background: #f1f1f1;
-  }
-
-}
 
 /**
  * MR -> show: Automerge widget
@@ -121,19 +107,3 @@ li.merge_request {
 .mr_direction_tip {
   margin-top:40px
 }
-
-.merge_requests_form_box {
-  @extend .main_box;
-  .merge_requests_middle_box {
-    @extend .middle_box_content;
-    height: 30px;
-    .merge_requests_assignee {
-      @extend .span6;
-      float: left;
-    }
-    .merge_requests_milestone {
-      @extend .span4;
-      float: left;
-    }
-  }
-}
diff --git a/app/assets/stylesheets/sections/projects.scss b/app/assets/stylesheets/sections/projects.scss
index 717f85024ccc3e1b49ceddba7767bab15fdcf94f..072ade80ad3130fe649e0cc466739b83d8315ab8 100644
--- a/app/assets/stylesheets/sections/projects.scss
+++ b/app/assets/stylesheets/sections/projects.scss
@@ -8,16 +8,12 @@
 
     .groups_box,
     .projects_box {
-      > h5 {
-        color: $style_color;
-        font-size: 16px;
-        text-shadow: 0 1px 1px #fff;
-        padding: 2px 10px;
-        line-height: 32px;
-        font-size: 14px;
+      > .title {
+        padding: 2px 15px;
       }
       .nav-projects-tabs li { padding: 0; }
       .well-list {
+        li { padding: 15px; }
         .arrow {
           float: right;
           padding: 10px;
@@ -109,7 +105,7 @@ ul.nav.nav-projects-tabs {
 
   li {
     a {
-      padding: 4px 20px;
+      padding: 6px 25px;
       margin-top: 2px;
       border-color: #DDD;
       background-color: #EEE;
diff --git a/app/contexts/commit_load_context.rb b/app/contexts/commit_load_context.rb
index e43e5a078055b81866aa6287957d15d8557cc239..a14291b9b0d1a94b7453e634543290dfef05ea16 100644
--- a/app/contexts/commit_load_context.rb
+++ b/app/contexts/commit_load_context.rb
@@ -9,7 +9,7 @@ class CommitLoadContext < BaseContext
       status: :ok
     }
 
-    commit = project.commit(params[:id])
+    commit = project.repository.commit(params[:id])
 
     if commit
       commit = CommitDecorator.decorate(commit)
diff --git a/app/contexts/notes/load_context.rb b/app/contexts/notes/load_context.rb
index 9f8299f52f7b900f302eae9540631468e72bf5a1..907c7c7ade286f10486e2351c4421fa62ab883b2 100644
--- a/app/contexts/notes/load_context.rb
+++ b/app/contexts/notes/load_context.rb
@@ -9,7 +9,7 @@ module Notes
 
       @notes = case target_type
                when "commit"
-                 project.commit_notes(project.commit(target_id)).fresh.limit(20)
+                 project.commit_notes(project.repository.commit(target_id)).fresh.limit(20)
                when "issue"
                  project.issues.find(target_id).notes.inc_author.fresh.limit(20)
                when "merge_request"
@@ -18,7 +18,7 @@ module Notes
                  project.snippets.find(target_id).notes.fresh
                when "wall"
                  # this is the only case, where the order is DESC
-                 project.common_notes.order("created_at DESC, id DESC").limit(50)
+                 project.notes.common.inc_author_project.order("created_at DESC, id DESC").limit(50)
                end
 
       @notes = if after_id
diff --git a/app/contexts/test_hook_context.rb b/app/contexts/test_hook_context.rb
index cba5d1f87c2afacfe7f369581ec758ae52fc2de8..d2d82a52cf5301ada55248527a6d2c11b3b3ccfb 100644
--- a/app/contexts/test_hook_context.rb
+++ b/app/contexts/test_hook_context.rb
@@ -1,7 +1,7 @@
 class TestHookContext < BaseContext
   def execute
     hook = project.hooks.find(params[:id])
-    commits = project.commits(project.default_branch, nil, 3)
+    commits = project.repository.commits(project.default_branch, nil, 3)
     data = project.post_receive_data(commits.last.id, commits.first.id, "refs/heads/#{project.default_branch}", current_user)
     hook.execute(data)
   end
diff --git a/app/controllers/admin/projects_controller.rb b/app/controllers/admin/projects_controller.rb
index e1982eee5770d93bc2b0b88336a0f49f0bf401ce..d5e6f3cdc0e8b08f86b3026b89f97538330aa011 100644
--- a/app/controllers/admin/projects_controller.rb
+++ b/app/controllers/admin/projects_controller.rb
@@ -10,6 +10,7 @@ class Admin::ProjectsController < AdminController
   end
 
   def show
+    @repository = @project.repository
     @users = User.active
     @users = @users.not_in_project(@project) if @project.users.present?
     @users = @users.all
@@ -19,7 +20,7 @@ class Admin::ProjectsController < AdminController
   end
 
   def team_update
-    @project.add_users_ids_to_team(params[:user_ids], params[:project_access])
+    @project.team.add_users_ids(params[:user_ids], params[:project_access])
 
     redirect_to [:admin, @project], notice: 'Project was successfully updated.'
   end
@@ -36,7 +37,7 @@ class Admin::ProjectsController < AdminController
 
   def destroy
     # Delete team first in order to prevent multiple gitolite calls
-    @project.truncate_team
+    @project.team.truncate
 
     @project.destroy
 
diff --git a/app/controllers/admin/users_controller.rb b/app/controllers/admin/users_controller.rb
index b255c73a21f31a8c7a6f7f0d89874bf23e5b7ab3..8669f5d1d38928dc575872512dfc19431a8da974 100644
--- a/app/controllers/admin/users_controller.rb
+++ b/app/controllers/admin/users_controller.rb
@@ -19,9 +19,9 @@ class Admin::UsersController < AdminController
   def team_update
     @admin_user = User.find(params[:id])
 
-    UsersProject.user_bulk_import(
-      @admin_user,
+    UsersProject.add_users_into_projects(
       params[:project_ids],
+      [@admin_user.id],
       params[:project_access]
     )
 
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index 75cd8f156052a64363f9cd994fa8edd6bf2d8e71..3457a1ab1b4a14dd10e6e27d07a6dea884fe4fda 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -76,6 +76,12 @@ class ApplicationController < ActionController::Base
     end
   end
 
+  def repository
+    @repository ||= project.repository
+  rescue Grit::NoSuchPathError
+    nil
+  end
+
   def add_abilities
     abilities << Ability
   end
diff --git a/app/controllers/commits_controller.rb b/app/controllers/commits_controller.rb
index 3b8ebdb5ddcf9864a0e891fdea4b99c5f238fcee..534ae1edd3136df5f81949c582d930ad617eb866 100644
--- a/app/controllers/commits_controller.rb
+++ b/app/controllers/commits_controller.rb
@@ -9,10 +9,10 @@ class CommitsController < ProjectResourceController
   before_filter :require_non_empty_project
 
   def show
-    @repo = @project.repo
+    @repo = @project.repository
     @limit, @offset = (params[:limit] || 40), (params[:offset] || 0)
 
-    @commits = @project.commits(@ref, @path, @limit, @offset)
+    @commits = @repo.commits(@ref, @path, @limit, @offset)
     @commits = CommitDecorator.decorate(@commits)
 
     respond_to do |format|
diff --git a/app/controllers/merge_requests_controller.rb b/app/controllers/merge_requests_controller.rb
index fa4eaff84698806faf5d99782984c1b26c72822e..d2d92e60585549e342ff7c4d48975683fbd1625f 100644
--- a/app/controllers/merge_requests_controller.rb
+++ b/app/controllers/merge_requests_controller.rb
@@ -83,12 +83,12 @@ class MergeRequestsController < ProjectResourceController
   end
 
   def branch_from
-    @commit = project.commit(params[:ref])
+    @commit = @repository.commit(params[:ref])
     @commit = CommitDecorator.decorate(@commit)
   end
 
   def branch_to
-    @commit = project.commit(params[:ref])
+    @commit = @repository.commit(params[:ref])
     @commit = CommitDecorator.decorate(@commit)
   end
 
diff --git a/app/controllers/project_resource_controller.rb b/app/controllers/project_resource_controller.rb
index 81bc3a91bd1ab07d1ed2c4752208745b8d83b64f..ea78b3ff7c4684720abf1c4657cb487c63cc6df2 100644
--- a/app/controllers/project_resource_controller.rb
+++ b/app/controllers/project_resource_controller.rb
@@ -1,3 +1,4 @@
 class ProjectResourceController < ApplicationController
   before_filter :project
+  before_filter :repository
 end
diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb
index 47143624ec4b9830f25494683820a9f9563cb01c..0df30220ebdcdc1eedf8f018005670de028e84cd 100644
--- a/app/controllers/projects_controller.rb
+++ b/app/controllers/projects_controller.rb
@@ -2,6 +2,7 @@ require Rails.root.join('lib', 'gitlab', 'graph', 'json_builder')
 
 class ProjectsController < ProjectResourceController
   skip_before_filter :project, only: [:new, :create]
+  skip_before_filter :repository, only: [:new, :create]
 
   # Authorize
   before_filter :authorize_read_project!, except: [:index, :new, :create]
@@ -58,7 +59,7 @@ class ProjectsController < ProjectResourceController
 
     respond_to do |format|
       format.html do
-        unless @project.empty_repo?
+        if @project.repository && !@project.repository.empty?
           @last_push = current_user.recent_push(@project.id)
           render :show
         else
diff --git a/app/controllers/refs_controller.rb b/app/controllers/refs_controller.rb
index b48d5ec702744a8ccf9fa4684b5cba5d5b359d87..e4eb2d33ea65754a14341d4e6c14ef68141bc1ff 100644
--- a/app/controllers/refs_controller.rb
+++ b/app/controllers/refs_controller.rb
@@ -31,7 +31,7 @@ class RefsController < ProjectResourceController
     contents = @tree.contents
     @logs = contents.map do |content|
       file = params[:path] ? File.join(params[:path], content.name) : content.name
-      last_commit = @project.commits(@commit.id, file, 1).last
+      last_commit = @repo.commits(@commit.id, file, 1).last
       last_commit = CommitDecorator.decorate(last_commit)
       {
         file_name: content.name,
@@ -45,10 +45,10 @@ class RefsController < ProjectResourceController
   def define_tree_vars
     params[:path] = nil if params[:path].blank?
 
-    @repo = project.repo
-    @commit = project.commit(@ref)
+    @repo = project.repository
+    @commit = @repo.commit(@ref)
     @commit = CommitDecorator.decorate(@commit)
-    @tree = Tree.new(@commit.tree, project, @ref, params[:path])
+    @tree = Tree.new(@commit.tree, @ref, params[:path])
     @tree = TreeDecorator.new(@tree)
     @hex_path = Digest::SHA1.hexdigest(params[:path] || "")
 
diff --git a/app/controllers/repositories_controller.rb b/app/controllers/repositories_controller.rb
index 7678fbff3f17a704da75e0c74338ede71b3786e7..229cb36949b82f28d484376fa3c45e9ce2fd623b 100644
--- a/app/controllers/repositories_controller.rb
+++ b/app/controllers/repositories_controller.rb
@@ -5,19 +5,19 @@ class RepositoriesController < ProjectResourceController
   before_filter :require_non_empty_project
 
   def show
-    @activities = @project.commits_with_refs(20)
+    @activities = @repository.commits_with_refs(20)
   end
 
   def branches
-    @branches = @project.branches
+    @branches = @repository.branches
   end
 
   def tags
-    @tags = @project.tags
+    @tags = @repository.tags
   end
 
   def stats
-    @stats = Gitlab::GitStats.new(@project.repo, @project.root_ref)
+    @stats = Gitlab::GitStats.new(@repository.raw, @repository.root_ref)
     @graph = @stats.graph
   end
 
@@ -27,7 +27,7 @@ class RepositoriesController < ProjectResourceController
     end
 
 
-    file_path = @project.archive_repo(params[:ref])
+    file_path = @repository.archive_repo(params[:ref])
 
     if file_path
       # Send file to user
diff --git a/app/controllers/services_controller.rb b/app/controllers/services_controller.rb
index 50f7e97af9faa8930c2b421aa4516a5f397012fc..d0df469b967b2f9a6418443521f12e1efe07dfa9 100644
--- a/app/controllers/services_controller.rb
+++ b/app/controllers/services_controller.rb
@@ -26,7 +26,7 @@ class ServicesController < ProjectResourceController
   end
 
   def test
-    commits = project.commits(project.default_branch, nil, 3)
+    commits = project.repository.commits(project.default_branch, nil, 3)
     data = project.post_receive_data(commits.last.id, commits.first.id, "refs/heads/#{project.default_branch}", current_user)
 
     @service = project.gitlab_ci_service
diff --git a/app/controllers/team_members_controller.rb b/app/controllers/team_members_controller.rb
index 311af62b8db87d22d74707bb1bbc8008243bbdd7..8378a8458ffa7193717eab782e117d36ce28ed98 100644
--- a/app/controllers/team_members_controller.rb
+++ b/app/controllers/team_members_controller.rb
@@ -16,10 +16,9 @@ class TeamMembersController < ProjectResourceController
   end
 
   def create
-    @project.add_users_ids_to_team(
-      params[:user_ids],
-      params[:project_access]
-    )
+    users = User.where(id: params[:user_ids])
+
+    @project.team << [users, params[:project_access]]
 
     if params[:redirect_to]
       redirect_to params[:redirect_to]
@@ -50,7 +49,7 @@ class TeamMembersController < ProjectResourceController
 
   def apply_import
     giver = Project.find(params[:source_project_id])
-    status = UsersProject.import_team(giver, project)
+    status = @project.team.import(giver)
     notice = status ? "Succesfully imported" : "Import failed"
 
     redirect_to project_team_members_path(project), notice: notice
diff --git a/app/controllers/tree_controller.rb b/app/controllers/tree_controller.rb
index 725f48fa014ee2d9775c0dd6603cce85bd88972e..2151bd7cbbddf9b92edde92ddc595b5ecb637a70 100644
--- a/app/controllers/tree_controller.rb
+++ b/app/controllers/tree_controller.rb
@@ -22,7 +22,7 @@ class TreeController < ProjectResourceController
   end
 
   def edit
-    @last_commit = @project.last_commit_for(@ref, @path).sha
+    @last_commit = @project.repository.last_commit_for(@ref, @path).sha
   end
 
   def update
diff --git a/app/decorators/tree_decorator.rb b/app/decorators/tree_decorator.rb
index c12227afb5d9255348ff4e718747d976d60a962e..0e760f97dee3c64afc8eb80c9167a56b2328f48a 100644
--- a/app/decorators/tree_decorator.rb
+++ b/app/decorators/tree_decorator.rb
@@ -6,16 +6,14 @@ class TreeDecorator < ApplicationDecorator
       part_path = ""
       parts = path.split("\/")
 
-      #parts = parts[0...-1] if is_blob?
-
-      yield(h.link_to("..", "#")) if parts.count > max_links
+      yield('..', nil) if parts.count > max_links
 
       parts.each do |part|
         part_path = File.join(part_path, part) unless part_path.empty?
         part_path = part if part_path.empty?
 
         next unless parts.last(2).include?(part) if parts.count > max_links
-        yield(h.link_to(h.truncate(part, length: 40), h.project_tree_path(project, h.tree_join(ref, part_path))))
+        yield(part, h.tree_join(ref, part_path))
       end
     end
   end
@@ -26,7 +24,7 @@ class TreeDecorator < ApplicationDecorator
 
   def up_dir_path
     file = File.join(path, "..")
-    h.project_tree_path(project, h.tree_join(ref, file))
+    h.tree_join(ref, file)
   end
 
   def readme
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index 2a33bae24f37b42e5099dbbef1419b6d94062042..a1eea96be43bb7804acaa30ea07be987bd0cff80 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -53,7 +53,7 @@ module ApplicationHelper
 
   def last_commit(project)
     if project.repo_exists?
-      time_ago_in_words(project.commit.committed_date) + " ago"
+      time_ago_in_words(project.repository.commit.committed_date) + " ago"
     else
       "Never"
     end
@@ -62,9 +62,11 @@ module ApplicationHelper
   end
 
   def grouped_options_refs(destination = :tree)
+    repository = @project.repository
+
     options = [
-      ["Branch", @project.branch_names ],
-      [ "Tag", @project.tag_names ]
+      ["Branch", repository.branch_names ],
+      [ "Tag", repository.tag_names ]
     ]
 
     # If reference is commit id -
@@ -100,15 +102,15 @@ module ApplicationHelper
     ]
 
     project_nav = []
-    if @project && !@project.new_record?
+    if @project && @project.repository && @project.repository.root_ref
       project_nav = [
         { label: "#{@project.name} Issues",   url: project_issues_path(@project) },
-        { label: "#{@project.name} Commits",  url: project_commits_path(@project, @ref || @project.root_ref) },
+        { label: "#{@project.name} Commits",  url: project_commits_path(@project, @ref || @project.repository.root_ref) },
         { label: "#{@project.name} Merge Requests", url: project_merge_requests_path(@project) },
         { label: "#{@project.name} Milestones", url: project_milestones_path(@project) },
         { label: "#{@project.name} Snippets", url: project_snippets_path(@project) },
         { label: "#{@project.name} Team",     url: project_team_index_path(@project) },
-        { label: "#{@project.name} Tree",     url: project_tree_path(@project, @ref || @project.root_ref) },
+        { label: "#{@project.name} Tree",     url: project_tree_path(@project, @ref || @project.repository.root_ref) },
         { label: "#{@project.name} Wall",     url: wall_project_path(@project) },
         { label: "#{@project.name} Wiki",     url: project_wikis_path(@project) },
       ]
@@ -140,6 +142,7 @@ module ApplicationHelper
       event.last_push_to_non_root? &&
       !event.rm_ref? &&
       event.project &&
+      event.project.repository &&
       event.project.merge_requests_enabled
   end
 
diff --git a/app/helpers/events_helper.rb b/app/helpers/events_helper.rb
index a2548a23e5e3b80803bf2561445cb4bab4d1cf40..2b9e7186bcde73817472ee94cbe0aa0d22b944b3 100644
--- a/app/helpers/events_helper.rb
+++ b/app/helpers/events_helper.rb
@@ -20,20 +20,6 @@ module EventsHelper
     [event.action_name, target].join(" ")
   end
 
-  def event_image event
-    event_image_path = if event.push?
-                   "event_push.png"
-                 elsif event.merged?
-                   "event_mr_merged.png"
-                 end
-
-    return nil unless event_image_path
-
-    content_tag :div, class: 'event_icon' do
-      image_tag event_image_path
-    end
-  end
-
   def event_filter_link key, tooltip
     key = key.to_s
 
diff --git a/app/helpers/merge_requests_helper.rb b/app/helpers/merge_requests_helper.rb
index f48425bd6de3dac6cf61c15224a51a90c6f5a021..ca0a89c374923ac203ba36b1709066bdd623e321 100644
--- a/app/helpers/merge_requests_helper.rb
+++ b/app/helpers/merge_requests_helper.rb
@@ -4,7 +4,7 @@ module MergeRequestsHelper
       event.project,
       merge_request: {
         source_branch: event.branch_name,
-        target_branch: event.project.root_ref,
+        target_branch: event.project.repository.root_ref,
         title: event.branch_name.titleize
       }
     )
diff --git a/app/models/ability.rb b/app/models/ability.rb
index 75a7163c219735cfde1ce83e84d811de55681c05..256af1e800b8614e10902faf0efe5efa5781c84d 100644
--- a/app/models/ability.rb
+++ b/app/models/ability.rb
@@ -15,17 +15,19 @@ class Ability
     def project_abilities(user, project)
       rules = []
 
+      team = project.team
+
       # Rules based on role in project
-      if project.master_access_for?(user)
+      if team.masters.include?(user)
         rules << project_master_rules
 
-      elsif project.dev_access_for?(user)
+      elsif team.developers.include?(user)
         rules << project_dev_rules
 
-      elsif project.report_access_for?(user)
+      elsif team.reporters.include?(user)
         rules << project_report_rules
 
-      elsif project.guest_access_for?(user)
+      elsif team.guests.include?(user)
         rules << project_guest_rules
       end
 
diff --git a/app/models/commit.rb b/app/models/commit.rb
index 07c5fbd7183b66130b89c7f4d1cbb2b70d937ab5..7e64c0f6e8268bad7960c35d7381824edb155e9b 100644
--- a/app/models/commit.rb
+++ b/app/models/commit.rb
@@ -11,7 +11,7 @@ class Commit
   attr_accessor :commit, :head, :refs
 
   delegate  :message, :authored_date, :committed_date, :parents, :sha,
-            :date, :committer, :author, :diffs, :tree, :id,
+            :date, :committer, :author, :diffs, :tree, :id, :stats,
             :to_patch, to: :commit
 
   class << self
@@ -83,8 +83,8 @@ class Commit
 
       return result unless from && to
 
-      first = project.commit(to.try(:strip))
-      last = project.commit(from.try(:strip))
+      first = project.repository.commit(to.try(:strip))
+      last = project.repository.commit(from.try(:strip))
 
       if first && last
         result[:same] = (first.id == last.id)
@@ -98,6 +98,8 @@ class Commit
   end
 
   def initialize(raw_commit, head = nil)
+    raise "Nil as raw commit passed" unless raw_commit
+
     @commit = raw_commit
     @head = head
   end
@@ -136,7 +138,11 @@ class Commit
   end
 
   def prev_commit
-    parents.try :first
+    @prev_commit ||= if parents.present?
+                       Commit.new(parents.first)
+                     else
+                       nil
+                     end
   end
 
   def prev_commit_id
diff --git a/app/models/event.rb b/app/models/event.rb
index 95075ffae71057befd99ca9ac7282ca4cccb2d08..d0ba61544d1157af3595a5e9339ae45eee0f5928 100644
--- a/app/models/event.rb
+++ b/app/models/event.rb
@@ -110,26 +110,6 @@ class Event < ActiveRecord::Base
     target_type == "MergeRequest"
   end
 
-  def new_issue?
-    target_type == "Issue" &&
-      action == Created
-  end
-
-  def new_merge_request?
-    target_type == "MergeRequest" &&
-      action == Created
-  end
-
-  def changed_merge_request?
-    target_type == "MergeRequest" &&
-      [Closed, Reopened].include?(action)
-  end
-
-  def changed_issue?
-    target_type == "Issue" &&
-      [Closed, Reopened].include?(action)
-  end
-
   def joined?
     action == Joined
   end
@@ -224,7 +204,7 @@ class Event < ActiveRecord::Base
 
   # Max 20 commits from push DESC
   def commits
-    @commits ||= data[:commits].map { |commit| project.commit(commit[:id]) }.reverse
+    @commits ||= data[:commits].map { |commit| repository.commit(commit[:id]) }.reverse
   end
 
   def commits_count
@@ -245,14 +225,18 @@ class Event < ActiveRecord::Base
     end
   end
 
+  def repository
+    project.repository
+  end
+
   def parent_commit
-    project.commit(commit_from)
+    repository.commit(commit_from)
   rescue => ex
     nil
   end
 
   def last_commit
-    project.commit(commit_to)
+    repository.commit(commit_to)
   rescue => ex
     nil
   end
diff --git a/app/models/gitlab_ci_service.rb b/app/models/gitlab_ci_service.rb
index 0b0b65e2863661e305c88d0aa1e79690e102fb8a..4eb39c7ef4d5a7aebdc43a6071d34440199a88b7 100644
--- a/app/models/gitlab_ci_service.rb
+++ b/app/models/gitlab_ci_service.rb
@@ -29,10 +29,6 @@ class GitlabCiService < Service
     hook.save
   end
 
-  def commit_badge_path sha
-    project_url + "/status?sha=#{sha}"
-  end
-
   def commit_status_path sha
     project_url + "/builds/#{sha}/status.json?token=#{token}"
   end
diff --git a/app/models/note.rb b/app/models/note.rb
index 28b3879239fa8026c78bc684d0e366c00380ba70..abd89a8a46ec1aa365c2a2afc1d91f242a3c4a9f 100644
--- a/app/models/note.rb
+++ b/app/models/note.rb
@@ -4,7 +4,6 @@
 #
 #  id            :integer          not null, primary key
 #  note          :text
-#  noteable_id   :string(255)
 #  noteable_type :string(255)
 #  author_id     :integer
 #  created_at    :datetime         not null
@@ -12,6 +11,8 @@
 #  project_id    :integer
 #  attachment    :string(255)
 #  line_code     :string(255)
+#  commit_id     :string(255)
+#  noteable_id   :integer
 #
 
 require 'carrierwave/orm/activerecord'
@@ -42,7 +43,7 @@ class Note < ActiveRecord::Base
 
   # Scopes
   scope :for_commits, ->{ where(noteable_type: "Commit") }
-  scope :common, ->{ where(noteable_id: nil, commit_id: nil) }
+  scope :common, ->{ where(noteable_type: ["", nil]) }
   scope :today, ->{ where("created_at >= :date", date: Date.today) }
   scope :last_week, ->{ where("created_at  >= :date", date: (Date.today - 7.days)) }
   scope :since, ->(day) { where("created_at  >= :date", date: (day)) }
@@ -70,7 +71,7 @@ class Note < ActiveRecord::Base
   # override to return commits, which are not active record
   def noteable
     if for_commit?
-      project.commit(commit_id)
+      project.repository.commit(commit_id)
     else
       super
     end
diff --git a/app/models/project.rb b/app/models/project.rb
index f60c24426aa16a5afdf79054981c1dbae7aac65e..2204d4a56e58092c11cef5716d6ec74e912c4e9f 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -9,7 +9,7 @@
 #  created_at             :datetime         not null
 #  updated_at             :datetime         not null
 #  private_flag           :boolean          default(TRUE), not null
-#  owner_id               :integer
+#  creator_id             :integer
 #  default_branch         :string(255)
 #  issues_enabled         :boolean          default(TRUE), not null
 #  wall_enabled           :boolean          default(TRUE), not null
@@ -75,7 +75,6 @@ class Project < ActiveRecord::Base
   validate :check_limit, :repo_name
 
   # Scopes
-  scope :public_only, where(private_flag: false)
   scope :without_user, ->(user)  { where("id NOT IN (:ids)", ids: user.authorized_projects.map(&:id) ) }
   scope :not_in_group, ->(group) { where("id NOT IN (:ids)", ids: group.project_ids ) }
   scope :in_namespace, ->(namespace) { where(namespace_id: namespace.id) }
@@ -162,6 +161,20 @@ class Project < ActiveRecord::Base
     end
   end
 
+  def team
+    @team ||= Team.new(self)
+  end
+
+  def repository
+    if path
+      @repository ||= Repository.new(path_with_namespace, default_branch)
+    else
+      nil
+    end
+  rescue Grit::NoSuchPathError
+    nil
+  end
+
   def git_error?
     error_code == :gitolite
   end
@@ -198,10 +211,6 @@ class Project < ActiveRecord::Base
     [Gitlab.config.gitlab.url, path_with_namespace].join("/")
   end
 
-  def common_notes
-    notes.where(noteable_type: ["", nil]).inc_author_project
-  end
-
   def build_commit_note(commit)
     notes.new(commit_id: commit.id, noteable_type: "Commit")
   end
@@ -214,14 +223,6 @@ class Project < ActiveRecord::Base
     notes.where(commit_id: commit.id, noteable_type: "Commit").where("line_code IS NOT NULL")
   end
 
-  def public?
-    !private_flag
-  end
-
-  def private?
-    private_flag
-  end
-
   def last_activity
     last_event
   end
@@ -284,110 +285,6 @@ class Project < ActiveRecord::Base
     users_projects.find_by_user_id(user_id)
   end
 
-  # Add user to project
-  # with passed access role
-  def add_user_to_team(user, access_role)
-    add_user_id_to_team(user.id, access_role)
-  end
-
-  # Add multiple users to project
-  # with same access role
-  def add_users_to_team(users, access_role)
-    add_users_ids_to_team(users.map(&:id), access_role)
-  end
-
-  # Add user to project
-  # with passed access role by user id
-  def add_user_id_to_team(user_id, access_role)
-    users_projects.create(
-      user_id: user_id,
-      project_access: access_role
-    )
-  end
-
-  # Add multiple users to project
-  # with same access role by user ids
-  def add_users_ids_to_team(users_ids, access_role)
-    UsersProject.bulk_import(self, users_ids, access_role)
-  end
-
-  # Update multiple project users
-  # to same access role by user ids
-  def update_users_ids_to_role(users_ids, access_role)
-    UsersProject.bulk_update(self, users_ids, access_role)
-  end
-
-  # Delete multiple users from project by user ids
-  def delete_users_ids_from_team(users_ids)
-    UsersProject.bulk_delete(self, users_ids)
-  end
-
-  # Remove all users from project team
-  def truncate_team
-    UsersProject.truncate_team(self)
-  end
-
-  # Compatible with all access rights
-  # Should be rewrited for new access rights
-  def add_access(user, *access)
-    access = if access.include?(:admin)
-               { project_access: UsersProject::MASTER }
-             elsif access.include?(:write)
-               { project_access: UsersProject::DEVELOPER }
-             else
-               { project_access: UsersProject::REPORTER }
-             end
-    opts = { user: user }
-    opts.merge!(access)
-    users_projects.create(opts)
-  end
-
-  def reset_access(user)
-    users_projects.where(project_id: self.id, user_id: user.id).destroy if self.id
-  end
-
-  def repository_readers
-    repository_members[UsersProject::REPORTER]
-  end
-
-  def repository_writers
-    repository_members[UsersProject::DEVELOPER]
-  end
-
-  def repository_masters
-    repository_members[UsersProject::MASTER]
-  end
-
-  def repository_members
-    keys = Hash.new {|h,k| h[k] = [] }
-    UsersProject.select("keys.identifier, project_access").
-        joins(user: :keys).where(project_id: id).
-        each {|row| keys[row.project_access] << [row.identifier] }
-
-    keys[UsersProject::REPORTER] += deploy_keys.pluck(:identifier)
-    keys
-  end
-
-  def allow_read_for?(user)
-    !users_projects.where(user_id: user.id).empty?
-  end
-
-  def guest_access_for?(user)
-    !users_projects.where(user_id: user.id).empty?
-  end
-
-  def report_access_for?(user)
-    !users_projects.where(user_id: user.id, project_access: [UsersProject::REPORTER, UsersProject::DEVELOPER, UsersProject::MASTER]).empty?
-  end
-
-  def dev_access_for?(user)
-    !users_projects.where(user_id: user.id, project_access: [UsersProject::DEVELOPER, UsersProject::MASTER]).empty?
-  end
-
-  def master_access_for?(user)
-    !users_projects.where(user_id: user.id, project_access: [UsersProject::MASTER]).empty?
-  end
-
   def transfer(new_namespace)
     Project.transaction do
       old_namespace = namespace
@@ -464,8 +361,8 @@ class Project < ActiveRecord::Base
 
     # Discover the default branch, but only if it hasn't already been set to
     # something else
-    if default_branch.nil?
-      update_attributes(default_branch: discover_default_branch)
+    if repository && default_branch.nil?
+      update_attributes(default_branch: self.repository.discover_default_branch)
     end
   end
 
@@ -517,7 +414,7 @@ class Project < ActiveRecord::Base
   #
   def post_receive_data(oldrev, newrev, ref, user)
 
-    push_commits = commits_between(oldrev, newrev)
+    push_commits = repository.commits_between(oldrev, newrev)
 
     # Total commits count
     push_commits_count = push_commits.size
@@ -564,7 +461,7 @@ class Project < ActiveRecord::Base
   def update_merge_requests(oldrev, newrev, ref, user)
     return true unless ref =~ /heads/
     branch_name = ref.gsub("refs/heads/", "")
-    c_ids = self.commits_between(oldrev, newrev).map(&:id)
+    c_ids = self.repository.commits_between(oldrev, newrev).map(&:id)
 
     # Update code for merge requests
     mrs = self.merge_requests.opened.find_all_by_branch(branch_name).all
@@ -586,97 +483,21 @@ class Project < ActiveRecord::Base
   end
 
   def empty_repo?
-    !repo_exists? || !has_commits?
-  end
-
-  def commit(commit_id = nil)
-    Commit.find_or_first(repo, commit_id, root_ref)
-  end
-
-  def fresh_commits(n = 10)
-    Commit.fresh_commits(repo, n)
-  end
-
-  def commits_with_refs(n = 20)
-    Commit.commits_with_refs(repo, n)
-  end
-
-  def commits_since(date)
-    Commit.commits_since(repo, date)
-  end
-
-  def commits(ref, path = nil, limit = nil, offset = nil)
-    Commit.commits(repo, ref, path, limit, offset)
-  end
-
-  def last_commit_for(ref, path = nil)
-    commits(ref, path, 1).first
-  end
-
-  def commits_between(from, to)
-    Commit.commits_between(repo, from, to)
+    !repository || repository.empty?
   end
 
   def satellite
     @satellite ||= Gitlab::Satellite::Satellite.new(self)
   end
 
-  def has_post_receive_file?
-    !!hook_file
-  end
-
-  def valid_post_receive_file?
-    valid_hook_file == hook_file
-  end
-
-  def valid_hook_file
-    @valid_hook_file ||= File.read(Rails.root.join('lib', 'hooks', 'post-receive'))
-  end
-
-  def hook_file
-    @hook_file ||= begin
-                     hook_path = File.join(path_to_repo, 'hooks', 'post-receive')
-                     File.read(hook_path) if File.exists?(hook_path)
-                   end
-  end
-
-  # Returns an Array of branch names
-  def branch_names
-    repo.branches.collect(&:name).sort
-  end
-
-  # Returns an Array of Branches
-  def branches
-    repo.branches.sort_by(&:name)
-  end
-
-  # Returns an Array of tag names
-  def tag_names
-    repo.tags.collect(&:name).sort.reverse
-  end
-
-  # Returns an Array of Tags
-  def tags
-    repo.tags.sort_by(&:name).reverse
-  end
-
-  # Returns an Array of branch and tag names
-  def ref_names
-    [branch_names + tag_names].flatten
-  end
-
   def repo
-    @repo ||= Grit::Repo.new(path_to_repo)
+    repository.raw
   end
 
   def url_to_repo
     gitolite.url_to_repo(path_with_namespace)
   end
 
-  def path_to_repo
-    File.join(Gitlab.config.gitolite.repos_path, "#{path_with_namespace}.git")
-  end
-
   def namespace_dir
     namespace.try(:path) || ''
   end
@@ -690,21 +511,11 @@ class Project < ActiveRecord::Base
   end
 
   def repo_exists?
-    @repo_exists ||= (repo && !repo.branches.empty?)
+    @repo_exists ||= (repository && repository.branches.present?)
   rescue
     @repo_exists = false
   end
 
-  def heads
-    @heads ||= repo.heads
-  end
-
-  def tree(fcommit, path = nil)
-    fcommit = commit if fcommit == :head
-    tree = fcommit.tree
-    path ? (tree / path) : tree
-  end
-
   def open_branches
     if protected_branches.empty?
       self.repo.heads
@@ -714,61 +525,8 @@ class Project < ActiveRecord::Base
     end.sort_by(&:name)
   end
 
-  # Discovers the default branch based on the repository's available branches
-  #
-  # - If no branches are present, returns nil
-  # - If one branch is present, returns its name
-  # - If two or more branches are present, returns the one that has a name
-  #   matching root_ref (default_branch or 'master' if default_branch is nil)
-  def discover_default_branch
-    if branch_names.length == 0
-      nil
-    elsif branch_names.length == 1
-      branch_names.first
-    else
-      branch_names.select { |v| v == root_ref }.first
-    end
-  end
-
-  def has_commits?
-    !!commit
-  rescue Grit::NoSuchPathError
-    false
-  end
-
-  def root_ref
-    default_branch || "master"
-  end
-
   def root_ref?(branch)
-    root_ref == branch
-  end
-
-  # Archive Project to .tar.gz
-  #
-  # Already packed repo archives stored at
-  # app_root/tmp/repositories/project_name/project_name-commit-id.tag.gz
-  #
-  def archive_repo(ref)
-    ref = ref || self.root_ref
-    commit = self.commit(ref)
-    return nil unless commit
-
-    # Build file path
-    file_name = self.path + "-" + commit.id.to_s + ".tar.gz"
-    storage_path = Rails.root.join("tmp", "repositories", self.path_with_namespace)
-    file_path = File.join(storage_path, file_name)
-
-    # Put files into a directory before archiving
-    prefix = self.path + "/"
-
-    # Create file if not exists
-    unless File.exists?(file_path)
-      FileUtils.mkdir_p storage_path
-      file = self.repo.archive_to_file(ref, prefix,  file_path)
-    end
-
-    file_path
+    repository.root_ref == branch
   end
 
   def ssh_url_to_repo
diff --git a/app/models/protected_branch.rb b/app/models/protected_branch.rb
index f405a7bf7bc089e6883c729637ebcfafd468bf9a..3308caf360a38e12cac1ab85e3bee63cdf09d40a 100644
--- a/app/models/protected_branch.rb
+++ b/app/models/protected_branch.rb
@@ -26,6 +26,6 @@ class ProtectedBranch < ActiveRecord::Base
   end
 
   def commit
-    project.commit(self.name)
+    project.repository.commit(self.name)
   end
 end
diff --git a/app/models/repository.rb b/app/models/repository.rb
new file mode 100644
index 0000000000000000000000000000000000000000..cf8ba4530a154158e470bf736a3dfee6e0ca7894
--- /dev/null
+++ b/app/models/repository.rb
@@ -0,0 +1,169 @@
+class Repository
+  # Repository directory name with namespace direcotry
+  # Examples:
+  #   gitlab/gitolite
+  #   diaspora
+  #
+  attr_accessor :path_with_namespace
+
+  # Grit repo object
+  attr_accessor :repo
+
+  # Default branch in the repository
+  attr_accessor :root_ref
+
+  def initialize(path_with_namespace, root_ref = 'master')
+    @root_ref = root_ref || "master"
+    @path_with_namespace = path_with_namespace
+
+    # Init grit repo object
+    repo
+  end
+
+  def raw
+    repo
+  end
+
+  def path_to_repo
+    @path_to_repo ||= File.join(Gitlab.config.gitolite.repos_path, "#{path_with_namespace}.git")
+  end
+
+  def repo
+    @repo ||= Grit::Repo.new(path_to_repo)
+  end
+
+  def commit(commit_id = nil)
+    Commit.find_or_first(repo, commit_id, root_ref)
+  end
+
+  def fresh_commits(n = 10)
+    Commit.fresh_commits(repo, n)
+  end
+
+  def commits_with_refs(n = 20)
+    Commit.commits_with_refs(repo, n)
+  end
+
+  def commits_since(date)
+    Commit.commits_since(repo, date)
+  end
+
+  def commits(ref, path = nil, limit = nil, offset = nil)
+    Commit.commits(repo, ref, path, limit, offset)
+  end
+
+  def last_commit_for(ref, path = nil)
+    commits(ref, path, 1).first
+  end
+
+  def commits_between(from, to)
+    Commit.commits_between(repo, from, to)
+  end
+
+  def has_post_receive_file?
+    !!hook_file
+  end
+
+  def valid_post_receive_file?
+    valid_hook_file == hook_file
+  end
+
+  def valid_hook_file
+    @valid_hook_file ||= File.read(Rails.root.join('lib', 'hooks', 'post-receive'))
+  end
+
+  def hook_file
+    @hook_file ||= begin
+                     hook_path = File.join(path_to_repo, 'hooks', 'post-receive')
+                     File.read(hook_path) if File.exists?(hook_path)
+                   end
+  end
+
+  # Returns an Array of branch names
+  def branch_names
+    repo.branches.collect(&:name).sort
+  end
+
+  # Returns an Array of Branches
+  def branches
+    repo.branches.sort_by(&:name)
+  end
+
+  # Returns an Array of tag names
+  def tag_names
+    repo.tags.collect(&:name).sort.reverse
+  end
+
+  # Returns an Array of Tags
+  def tags
+    repo.tags.sort_by(&:name).reverse
+  end
+
+  # Returns an Array of branch and tag names
+  def ref_names
+    [branch_names + tag_names].flatten
+  end
+
+  def heads
+    @heads ||= repo.heads
+  end
+
+  def tree(fcommit, path = nil)
+    fcommit = commit if fcommit == :head
+    tree = fcommit.tree
+    path ? (tree / path) : tree
+  end
+
+  def has_commits?
+    !!commit
+  rescue Grit::NoSuchPathError
+    false
+  end
+
+  def empty?
+    !has_commits?
+  end
+
+  # Discovers the default branch based on the repository's available branches
+  #
+  # - If no branches are present, returns nil
+  # - If one branch is present, returns its name
+  # - If two or more branches are present, returns the one that has a name
+  #   matching root_ref (default_branch or 'master' if default_branch is nil)
+  def discover_default_branch
+    if branch_names.length == 0
+      nil
+    elsif branch_names.length == 1
+      branch_names.first
+    else
+      branch_names.select { |v| v == root_ref }.first
+    end
+  end
+
+  # Archive Project to .tar.gz
+  #
+  # Already packed repo archives stored at
+  # app_root/tmp/repositories/project_name/project_name-commit-id.tag.gz
+  #
+  def archive_repo(ref)
+    ref = ref || self.root_ref
+    commit = self.commit(ref)
+    return nil unless commit
+
+    # Build file path
+    file_name = self.path + "-" + commit.id.to_s + ".tar.gz"
+    storage_path = Rails.root.join("tmp", "repositories", self.path_with_namespace)
+    file_path = File.join(storage_path, file_name)
+
+    # Put files into a directory before archiving
+    prefix = self.path + "/"
+
+    # Create file if not exists
+    unless File.exists?(file_path)
+      FileUtils.mkdir_p storage_path
+      file = self.repo.archive_to_file(ref, prefix,  file_path)
+    end
+
+    file_path
+  end
+end
diff --git a/app/models/team.rb b/app/models/team.rb
new file mode 100644
index 0000000000000000000000000000000000000000..f235d20ebdbfc7285bd8d98db0aebcb907b0e3d1
--- /dev/null
+++ b/app/models/team.rb
@@ -0,0 +1,118 @@
+class Team
+  attr_accessor :project
+
+  def initialize(project)
+    @project = project
+  end
+
+  # Shortcut to add users
+  #
+  # Use:
+  #   @team << [@user, :master]
+  #   @team << [@users, :master]
+  #
+  def << args
+    users = args.first
+
+    if users.respond_to?(:each)
+      add_users(users, args.second)
+    else
+      add_user(users, args.second)
+    end
+  end
+
+  def add_user(user, access)
+    add_users_ids([user.id], access)
+  end
+
+  def add_users(users, access)
+    add_users_ids(users.map(&:id), access)
+  end
+
+  def add_users_ids(user_ids, access)
+    UsersProject.add_users_into_projects(
+      [project.id],
+      user_ids,
+      access
+    )
+  end
+
+  # Remove all users from project team
+  def truncate
+    UsersProject.truncate_team(project)
+  end
+
+  def members
+    project.users_projects
+  end
+
+  def guests
+    members.guests.map(&:user)
+  end
+
+  def reporters
+    members.reporters.map(&:user)
+  end
+
+  def developers
+    members.developers.map(&:user)
+  end
+
+  def masters
+    members.masters.map(&:user)
+  end
+
+  def repository_readers
+    repository_members[UsersProject::REPORTER]
+  end
+
+  def repository_writers
+    repository_members[UsersProject::DEVELOPER]
+  end
+
+  def repository_masters
+    repository_members[UsersProject::MASTER]
+  end
+
+  def repository_members
+    keys = Hash.new {|h,k| h[k] = [] }
+    UsersProject.select("keys.identifier, project_access").
+        joins(user: :keys).where(project_id: project.id).
+        each {|row| keys[row.project_access] << [row.identifier] }
+
+    keys[UsersProject::REPORTER] += project.deploy_keys.pluck(:identifier)
+    keys
+  end
+
+  def import(source_project)
+    target_project = project
+
+    source_team = source_project.users_projects.all
+    target_team = target_project.users_projects.all
+    target_user_ids = target_team.map(&:user_id)
+
+    source_team.reject! do |tm|
+      # Skip if user already present in team
+      target_user_ids.include?(tm.user_id)
+    end
+
+    source_team.map! do |tm|
+      new_tm = tm.dup
+      new_tm.id = nil
+      new_tm.project_id = target_project.id
+      new_tm.skip_git = true
+      new_tm
+    end
+
+    UsersProject.transaction do
+      source_team.each do |tm|
+        tm.save
+      end
+      target_project.update_repository
+    end
+
+    true
+  rescue
+    false
+  end
+end
diff --git a/app/models/tree.rb b/app/models/tree.rb
index c3dfd4c718cfb246d6388b2a8d33cf4d544601fa..96395a42394a75b77d08621ac6c046ddb26d99cb 100644
--- a/app/models/tree.rb
+++ b/app/models/tree.rb
@@ -1,12 +1,13 @@
 class Tree
   include Linguist::BlobHelper
-  attr_accessor :path, :tree, :project, :ref
+
+  attr_accessor :path, :tree, :ref
 
   delegate  :contents, :basename, :name, :data, :mime_type,
             :mode, :size, :text?, :colorize, to: :tree
 
-  def initialize(raw_tree, project, ref = nil, path = nil)
-    @project, @ref, @path = project, ref, path
+  def initialize(raw_tree, ref = nil, path = nil)
+    @ref, @path = ref, path
     @tree = if path.present?
               raw_tree / path
             else
diff --git a/app/models/user.rb b/app/models/user.rb
index d166ae4dc79108744e46b93836722458e8e14a09..5e4815da865dc667469ab148d9c3a4b6e7d80d2b 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -188,7 +188,7 @@ class User < ActiveRecord::Base
 
   # Team membership in personal projects
   def tm_in_personal_projects
-    personal_projects.users_projects.where(user_id: self.id)
+    UsersProject.where(project_id:  personal_projects.map(&:id), user_id: self.id)
   end
 
   # Returns a string for use as a Gitolite user identifier
diff --git a/app/models/users_project.rb b/app/models/users_project.rb
index f8e0078400f2d20e0917caacb222d7ef5cef54bd..362b1a5d8e5aca2d6d25cb3236d687e295aef576 100644
--- a/app/models/users_project.rb
+++ b/app/models/users_project.rb
@@ -42,7 +42,34 @@ class UsersProject < ActiveRecord::Base
   scope :in_project, ->(project) { where(project_id: project.id) }
 
   class << self
-    def add_users_into_projects(project_ids, user_ids, project_access)
+
+    # Add users to project teams with passed access option
+    #
+    # access can be an integer representing a access code
+    # or symbol like :master representing role
+    #
+    # Ex.
+    #   add_users_into_projects(
+    #     project_ids,
+    #     user_ids,
+    #     UsersProject::MASTER
+    #   )
+    #
+    #   add_users_into_projects(
+    #     project_ids,
+    #     user_ids,
+    #     :master
+    #   )
+    #
+    def add_users_into_projects(project_ids, user_ids, access)
+      project_access = if roles_hash.has_key?(access)
+                         roles_hash[access]
+                       elsif roles_hash.values.include?(access.to_i)
+                         access
+                       else
+                         raise "Non valid access"
+                       end
+
       UsersProject.transaction do
         project_ids.each do |project_id|
           user_ids.each do |user_id|
@@ -79,36 +106,6 @@ class UsersProject < ActiveRecord::Base
       truncate_teams [project.id]
     end
 
-    def import_team(source_project, target_project)
-      source_team = source_project.users_projects.all
-      target_team = target_project.users_projects.all
-      target_user_ids = target_team.map(&:user_id)
-
-      source_team.reject! do |tm|
-        # Skip if user already present in team
-        target_user_ids.include?(tm.user_id)
-      end
-
-      source_team.map! do |tm|
-        new_tm = tm.dup
-        new_tm.id = nil
-        new_tm.project_id = target_project.id
-        new_tm.skip_git = true
-        new_tm
-      end
-
-      UsersProject.transaction do
-        source_team.each do |tm|
-          tm.save
-        end
-        target_project.update_repository
-      end
-
-      true
-    rescue
-      false
-    end
-
     def bulk_delete(project, user_ids)
       UsersProject.transaction do
         UsersProject.where(user_id: user_ids, project_id: project.id).each do |users_project|
@@ -131,14 +128,13 @@ class UsersProject < ActiveRecord::Base
       end
     end
 
-    # TODO: depreceate in future in favor of add_users_into_projects
-    def bulk_import(project, user_ids, project_access)
-      add_users_into_projects([project.id], user_ids, project_access)
-    end
-
-    # TODO: depreceate in future in favor of add_users_into_projects
-    def user_bulk_import(user, project_ids, project_access)
-      add_users_into_projects(project_ids, [user.id], project_access)
+    def roles_hash
+      {
+        guest: GUEST,
+        reporter: REPORTER,
+        developer: DEVELOPER,
+        master: MASTER
+      }
     end
 
     def access_roles
diff --git a/app/uploaders/attachment_uploader.rb b/app/uploaders/attachment_uploader.rb
index bb7dc0dab10162e7222b188e4f29e6f64d20ae00..391731d9470f9c41b18a2212b4e9ce81b25dd030 100644
--- a/app/uploaders/attachment_uploader.rb
+++ b/app/uploaders/attachment_uploader.rb
@@ -1,49 +1,13 @@
 # encoding: utf-8
 
 class AttachmentUploader < CarrierWave::Uploader::Base
-
-  # Include RMagick or ImageScience support:
-  # include CarrierWave::RMagick
-  # include CarrierWave::MiniMagick
-  # include CarrierWave::ImageScience
-
-  # Choose what kind of storage to use for this uploader:
   storage :file
-  # storage :fog
 
-  # Override the directory where uploaded files will be stored.
-  # This is a sensible default for uploaders that are meant to be mounted:
   def store_dir
     "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
   end
 
-  # Provide a default URL as a default if there hasn't been a file uploaded:
-  # def default_url
-  #   "/images/fallback/" + [version_name, "default.png"].compact.join('_')
-  # end
-
-  # Process files as they are uploaded:
-  # process scale: [200, 300]
-  #
-  # def scale(width, height)
-  #   # do something
-  # end
-
-  # Create different versions of your uploaded files:
-  # version :thumb do
-  #   process scale: [50, 50]
-  # end
-
-  # Add a white list of extensions which are allowed to be uploaded.
-  # For images you might use something like this:
-  # def extension_white_list
-  #   %w(jpg jpeg gif png)
-  # end
-
-  # Override the filename of the uploaded files:
-  # Avoid using model.id or version_name here, see uploader/store.rb for details.
-  # def filename
-  #   "something.jpg" if original_filename
-  # end
-
+  def image?
+    %w(png jpg jpeg).include?(file.extension)
+  end
 end
diff --git a/app/views/admin/dashboard/index.html.haml b/app/views/admin/dashboard/index.html.haml
index 4320bda49999fdf65cf2e45b997e3011716935bb..672dad4377e3fed2b5de7e2e598c911256175dca 100644
--- a/app/views/admin/dashboard/index.html.haml
+++ b/app/views/admin/dashboard/index.html.haml
@@ -1,7 +1,7 @@
 .admin_dash.row
   .span3
     .ui-box
-      %h5 Projects
+      %h5.title Projects
       .data.padded
         = link_to admin_projects_path do
           %h1= Project.count
@@ -9,7 +9,7 @@
         = link_to 'New Project', new_project_path, class: "btn small"
   .span3
     .ui-box
-      %h5 Groups
+      %h5.title Groups
       .data.padded
         = link_to admin_groups_path do
           %h1= Group.count
@@ -17,7 +17,7 @@
         = link_to 'New Group', new_admin_group_path, class: "btn small"
   .span3
     .ui-box
-      %h5 Users
+      %h5.title Users
       .data.padded
         = link_to admin_users_path do
           %h1= User.count
@@ -25,7 +25,7 @@
         = link_to 'New User', new_admin_user_path, class: "btn small"
   .span3
     .ui-box
-      %h5
+      %h5.title
         Resque Workers
       .data.padded
         - if @resque_accessible
diff --git a/app/views/admin/projects/_form.html.haml b/app/views/admin/projects/_form.html.haml
index 27c22872d501456bc4b7fd4bfd2a31c45b0a0a53..534c42223b3cb25e56677bdf9b8c25fcb7341c8d 100644
--- a/app/views/admin/projects/_form.html.haml
+++ b/app/views/admin/projects/_form.html.haml
@@ -22,7 +22,7 @@
     - if project.repo_exists?
       .clearfix
         = f.label :default_branch, "Default Branch"
-        .input= f.select(:default_branch, project.heads.map(&:name), {}, style: "width:210px;")
+        .input= f.select(:default_branch, repository.heads.map(&:name), {}, style: "width:210px;")
 
   %fieldset.adv_settings
     %legend Features:
diff --git a/app/views/admin/projects/show.html.haml b/app/views/admin/projects/show.html.haml
index ca9b9d3d4441f4a5f1793f7f3b147b2c3f014746..5a745f58fe350da17b5509f6f56f31d2537bd99b 100644
--- a/app/views/admin/projects/show.html.haml
+++ b/app/views/admin/projects/show.html.haml
@@ -4,15 +4,15 @@
     %i.icon-edit
     Edit
 
-- if @project.has_commits?
-  - if !@project.has_post_receive_file?
+- if @repository && @repository.has_commits?
+  - if !@repository.has_post_receive_file?
     %br
     .alert.alert-error
       %span
         %strong Project has commits but missing post-receive file.
         %br
         If you exported project manually - make a link of post-receive hook file from gitolite to project repository
-  - elsif !@project.valid_post_receive_file?
+  - elsif !@repository.valid_post_receive_file?
     %br
     .alert.alert-error
       %span
@@ -65,42 +65,43 @@
         Created at:
     %td
       = @project.created_at.stamp("March 1, 1999")
+    %tr
+      %td
+        %b
+          Smart HTTP:
+      %td
+        = link_to @project.http_url_to_repo
+    %tr
+      %td
+        %b
+          SSH:
+      %td
+        = link_to @project.ssh_url_to_repo
 
-%table.zebra-striped
-  %thead
+- if @repository
+  %table.zebra-striped
+    %thead
+      %tr
+        %th Repository
+        %th
     %tr
-      %th Repository
-      %th
-  %tr
-    %td
-      %b
-        FS Path:
-    %td
-      %code= @project.path_to_repo
-  %tr
-    %td
-      %b
-        Smart HTTP:
-    %td
-      = link_to @project.http_url_to_repo
-  %tr
-    %td
-      %b
-        SSH:
-    %td
-      = link_to @project.ssh_url_to_repo
-  %tr
-    %td
-      %b
-        Last commit at:
-    %td
-      = last_commit(@project)
-  %tr
-    %td
-      %b
-        Post Receive File:
-    %td
-      = check_box_tag :post_receive_file, 1, @project.has_post_receive_file?, disabled: true
+      %td
+        %b
+          FS Path:
+      %td
+        %code= @repository.path_to_repo
+    %tr
+      %td
+        %b
+          Last commit at:
+      %td
+        = last_commit(@project)
+    %tr
+      %td
+        %b
+          Post Receive File:
+      %td
+        = check_box_tag :post_receive_file, 1, @repository.has_post_receive_file?, disabled: true
 
 %br
 %h5
diff --git a/app/views/commit/show.html.haml b/app/views/commit/show.html.haml
index 432d55b19e3679a5b81df34fde5d47b9e9f0688f..0144e4754c56ed66c2ba5ede572e4eac9c5f2ba5 100644
--- a/app/views/commit/show.html.haml
+++ b/app/views/commit/show.html.haml
@@ -1,9 +1,15 @@
 = render "commits/commit_box"
+
+%p.right.cgray
+  This commit has
+  %span.cgreen #{@commit.stats.additions} additions
+  and
+  %span.cred #{@commit.stats.deletions} deletions
+
 = render "commits/diffs", diffs: @commit.diffs
 = render "notes/notes_with_form", tid: @commit.id, tt: "commit"
 = render "notes/per_line_form"
 
-
 :javascript
   $(function(){
     PerLineNotes.init();
@@ -19,7 +25,7 @@
           , h = event.currentTarget.naturalHeight;
         $('.image.diff_added .image-info', this).append(' | <b>W:</b> ' + w + 'px | <b>H:</b> ' + h + 'px');
       }, this));
-      
+
     });
-    
+
   });
diff --git a/app/views/commits/_commit_box.html.haml b/app/views/commits/_commit_box.html.haml
index 8f7826e0c8db9841abdcdab6a49a196850a4db7e..0544a1d10fee4a3f6bce9ecc37bd76b15bdca748 100644
--- a/app/views/commits/_commit_box.html.haml
+++ b/app/views/commits/_commit_box.html.haml
@@ -1,47 +1,50 @@
-.commit-box{class: @commit.parents_count > 1 ? "merge-commit" : ""}
-  .commit-head
+.ui-box.ui-box-show
+  .ui-box-head
     .right
       - if @notes_count > 0
         %span.btn.disabled.grouped
           %i.icon-comment
           = @notes_count
       .left.btn-group
-        %a.btn.small.grouped.dropdown-toggle{ data: {toggle: :dropdown} }
+        %a.btn.grouped.dropdown-toggle{ data: {toggle: :dropdown} }
           %i.icon-download-alt
           Download as
           %span.caret
         %ul.dropdown-menu
           %li= link_to "Email Patches", project_commit_path(@project, @commit, format: :patch)
           %li= link_to "Plain Diff",    project_commit_path(@project, @commit, format: :diff)
-      = link_to project_tree_path(@project, @commit), class: "browse-button primary grouped" do
-        %strong Browse Code »
+      = link_to project_tree_path(@project, @commit), class: "btn primary grouped" do
+        %span Browse Code »
     %h3.commit-title.page_title
       = gfm escape_once(@commit.title)
     - if @commit.description.present?
       %pre.commit-description
         = gfm escape_once(@commit.description)
-  .commit-info
+  .ui-box-body
     .row
       .span5
         .author
-          %strong= @commit.author_link avatar: true, size: 40
+          = @commit.author_link avatar: true, size: 32
           authored
           %time{title: @commit.authored_date.stamp("Aug 21, 2011 9:23pm")}
             #{time_ago_in_words(@commit.authored_date)} ago
         - if @commit.different_committer?
           .committer
             &rarr;
-            %strong= @commit.committer_link
+            = @commit.committer_link
             committed
             %time{title: @commit.committed_date.stamp("Aug 21, 2011 9:23pm")}
               #{time_ago_in_words(@commit.committed_date)} ago
-      .span6.right
-        .sha-block
-          %span.cgray commit
-          %code.label_commit= @commit.id
-        .sha-block
-          %span.cgray= pluralize(@commit.parents.count, "parent")
-          - @commit.parents.each do |parent|
-            = link_to parent.id[0...10], project_commit_path(@project, parent)
+      .span6.pull-right
+        .pull-right
+          .sha-block
+            %span.cgray commit
+            %span.label_commit= @commit.id
+        .clearfix
+        .pull-right
+          .sha-block
+            %span.cgray= pluralize(@commit.parents.count, "parent")
+            - @commit.parents.each do |parent|
+              = link_to parent.id[0...10], project_commit_path(@project, parent)
 
 
diff --git a/app/views/commits/_commits.html.haml b/app/views/commits/_commits.html.haml
index c9217989884ac38112a1f60ba14de2f5a3ebd331..0dc6664c1d6c078ae06db3f32c1843f2ae8836a3 100644
--- a/app/views/commits/_commits.html.haml
+++ b/app/views/commits/_commits.html.haml
@@ -1,6 +1,6 @@
 - @commits.group_by { |c| c.committed_date.to_date }.each do |day, commits|
   %div.ui-box
-    %h5.small
+    %h5.title
       %i.icon-calendar
       = day.stamp("28 Aug, 2010")
     %ul.well-list= render commits
diff --git a/app/views/commits/_head.html.haml b/app/views/commits/_head.html.haml
index 2ec1d24bbef7473cb06a71a574d81a2e4e498034..a5f3fdf5c5e47170a0040b14ff33c4773b4acf49 100644
--- a/app/views/commits/_head.html.haml
+++ b/app/views/commits/_head.html.haml
@@ -2,19 +2,19 @@
   %li= render partial: 'shared/ref_switcher', locals: {destination: 'commits'}
 
   = nav_link(controller: [:commit, :commits]) do
-    = link_to 'Commits', project_commits_path(@project, @project.root_ref)
+    = link_to 'Commits', project_commits_path(@project, @repository.root_ref)
   = nav_link(controller: :compare) do
     = link_to 'Compare', project_compare_index_path(@project)
 
   = nav_link(html_options: {class: branches_tab_class}) do
     = link_to project_repository_path(@project) do
       Branches
-      %span.badge= @project.branches.length
+      %span.badge= @repository.branches.length
 
   = nav_link(controller: :repositories, action: :tags) do
     = link_to tags_project_repository_path(@project) do
       Tags
-      %span.badge= @project.tags.length
+      %span.badge= @repository.tags.length
 
   = nav_link(controller: :repositories, action: :stats) do
     = link_to stats_project_repository_path(@project) do
diff --git a/app/views/compare/_form.html.haml b/app/views/compare/_form.html.haml
index 7e3a2a0e1f52fbb4640c34039d71a8dbb5f7451f..0915782dddc70d637ecac033a0678dc9d1523c28 100644
--- a/app/views/compare/_form.html.haml
+++ b/app/views/compare/_form.html.haml
@@ -28,7 +28,7 @@
 
 :javascript
   $(function() {
-    var availableTags = #{@project.ref_names.to_json};
+    var availableTags = #{@project.repository.ref_names.to_json};
 
     $("#from, #to").autocomplete({
       source: availableTags,
diff --git a/app/views/dashboard/_groups.html.haml b/app/views/dashboard/_groups.html.haml
index 5a95ab3fb9820f74177c1846ec1831ed023bd8ec..7f544406761afaf88de0c4a11e8aa960ad0c0764 100644
--- a/app/views/dashboard/_groups.html.haml
+++ b/app/views/dashboard/_groups.html.haml
@@ -1,5 +1,5 @@
 .groups_box
-  %h5
+  %h5.title
     Groups
     %small
       (#{groups.count})
diff --git a/app/views/dashboard/_projects.html.haml b/app/views/dashboard/_projects.html.haml
index cffafb5445c2b476018974c500f3e924dd8ee9c7..6c1304ee4a852d187a6c3b7cd4d355e6e75e5108 100644
--- a/app/views/dashboard/_projects.html.haml
+++ b/app/views/dashboard/_projects.html.haml
@@ -1,5 +1,5 @@
 .projects_box
-  %h5
+  %h5.title
     Projects
     %small
       (#{projects.total_count})
diff --git a/app/views/dashboard/issues.html.haml b/app/views/dashboard/issues.html.haml
index 52863229644b040148a625074f1039a0dd8ea1e7..68e3b3dcaf57969f93091bd6090cc0f5dbde6df6 100644
--- a/app/views/dashboard/issues.html.haml
+++ b/app/views/dashboard/issues.html.haml
@@ -13,7 +13,8 @@
       - @issues.group_by(&:project).each do |group|
         %div.ui-box
           - @project = group[0]
-          %h5= link_to_project @project
+          %h5.title
+            = link_to_project @project
           %ul.well-list.issues_table
             - group[1].each do |issue|
               = render(partial: 'issues/show', locals: {issue: issue})
diff --git a/app/views/dashboard/merge_requests.html.haml b/app/views/dashboard/merge_requests.html.haml
index ea7c8c9a3d514270a02cce99fd799e779d59d653..c5245da731a81eacc6284d89c3a6653245abc76f 100644
--- a/app/views/dashboard/merge_requests.html.haml
+++ b/app/views/dashboard/merge_requests.html.haml
@@ -12,7 +12,8 @@
       - @merge_requests.group_by(&:project).each do |group|
         .ui-box
           - @project = group[0]
-          %h5= link_to_project @project
+          %h5.title
+            = link_to_project @project
           %ul.well-list
             - group[1].each do |merge_request|
               = render(partial: 'merge_requests/merge_request', locals: {merge_request: merge_request})
diff --git a/app/views/groups/_projects.html.haml b/app/views/groups/_projects.html.haml
index 0b491879fe04f581dc6883d33cef1dddac31fce7..040d1ae94aae6a79f0da1817f4d1f9f368936873 100644
--- a/app/views/groups/_projects.html.haml
+++ b/app/views/groups/_projects.html.haml
@@ -1,5 +1,5 @@
 .projects_box
-  %h5
+  %h5.title
     Projects
     %small
       (#{projects.count})
diff --git a/app/views/groups/issues.html.haml b/app/views/groups/issues.html.haml
index 0daf4d752a8469b2f2a3304c888df9f725fbf29d..ebbe4df14fb7aea6a6fc8d78d1600d88601874ef 100644
--- a/app/views/groups/issues.html.haml
+++ b/app/views/groups/issues.html.haml
@@ -9,7 +9,8 @@
   - @issues.group_by(&:project).each do |group|
     %div.ui-box
       - @project = group[0]
-      %h5= @project.name
+      %h5.title
+        = @project.name
       %ul.well-list.issues_table
         - group[1].each do |issue|
           = render(partial: 'issues/show', locals: {issue: issue})
diff --git a/app/views/groups/merge_requests.html.haml b/app/views/groups/merge_requests.html.haml
index 72aa4ad11e109f78f48370fdbcea393cda326abd..5fac48285260e72ea15a3f03a949c1e418d783b6 100644
--- a/app/views/groups/merge_requests.html.haml
+++ b/app/views/groups/merge_requests.html.haml
@@ -8,7 +8,8 @@
   - @merge_requests.group_by(&:project).each do |group|
     %ul.well-list.ui-box
       - @project = group[0]
-      %h5= @project.name
+      %h5.title
+        = @project.name
       - group[1].each do |merge_request|
         = render(partial: 'merge_requests/merge_request', locals: {merge_request: merge_request})
   %hr
diff --git a/app/views/groups/people.html.haml b/app/views/groups/people.html.haml
index 091f68756c3b9ce831645aa961c4c0ec725be502..0bceeaa3ceba6c37a24fb6812bcbb2b972114a57 100644
--- a/app/views/groups/people.html.haml
+++ b/app/views/groups/people.html.haml
@@ -5,7 +5,7 @@
     - if can?(current_user, :manage_group, @group)
       = render (@project ? "new_member" : "new_group_member")
     .ui-box
-      %h5
+      %h5.title
         Team
         %small
           (#{@users.size})
diff --git a/app/views/issues/_form.html.haml b/app/views/issues/_form.html.haml
index 030f797c088101d01f73f054e569cd4a8c60d1d6..02b11b53a956d13013493879a9cf7fb73938f21d 100644
--- a/app/views/issues/_form.html.haml
+++ b/app/views/issues/_form.html.haml
@@ -6,26 +6,27 @@
         - @issue.errors.full_messages.each do |msg|
           %span= msg
           %br
-    .issue_form_box
-      .issue_title
+    .ui-box.ui-box-show
+      .ui-box-head
         .clearfix
           = f.label :title do
             %strong= "Subject *"
           .input
             = f.text_field :title, maxlength: 255, class: "xxlarge js-gfm-input", autofocus: true, required: true
-      .issue_middle_block
-        .issue_assignee
-          = f.label :assignee_id do
-            %i.icon-user
-            Assign to
-          .input= f.select(:assignee_id, @project.users.all.collect {|p| [ p.name, p.id ] }, { include_blank: "Select a user" }, {class: 'chosen'})
-        .issue_milestone
-          = f.label :milestone_id do
-            %i.icon-time
-            Milestone
-          .input= f.select(:milestone_id, @project.milestones.active.all.collect {|p| [ p.title, p.id ] }, { include_blank: "Select milestone" }, {class: 'chosen'})
+      .ui-box-body
+        .clearfix
+          .issue_assignee.pull-left
+            = f.label :assignee_id do
+              %i.icon-user
+              Assign to
+            .input= f.select(:assignee_id, @project.users.all.collect {|p| [ p.name, p.id ] }, { include_blank: "Select a user" }, {class: 'chosen'})
+          .issue_milestone.pull-left
+            = f.label :milestone_id do
+              %i.icon-time
+              Milestone
+            .input= f.select(:milestone_id, @project.milestones.active.all.collect {|p| [ p.title, p.id ] }, { include_blank: "Select milestone" }, {class: 'chosen'})
 
-      .issue_description
+      .ui-box-bottom
         .clearfix
           = f.label :label_list do
             %i.icon-tag
diff --git a/app/views/issues/index.html.haml b/app/views/issues/index.html.haml
index 08d4393b201001d1948cb64a52bf00fca211e23a..7971a124b809182f74a7e166e2f243828b221dae 100644
--- a/app/views/issues/index.html.haml
+++ b/app/views/issues/index.html.haml
@@ -30,7 +30,7 @@
             = select_tag('update[milestone_id]', options_from_collection_for_select(issues_active_milestones, "id", "title", params[:milestone_id]), prompt: "Milestone")
             = hidden_field_tag 'update[issues_ids]', []
             = hidden_field_tag :f, params[:f]
-          = button_tag "Save", class: "btn update_selected_issues"
+          = button_tag "Save", class: "btn update_selected_issues btn-small save-btn"
       .issues_filters
         .left
           %ul.nav.nav-pills.left
diff --git a/app/views/issues/show.html.haml b/app/views/issues/show.html.haml
index 1d4d6a13c2bb33efa7c780e02d307623e95b81e2..544817192ab06b1cfbb28d50bae49042332959bb 100644
--- a/app/views/issues/show.html.haml
+++ b/app/views/issues/show.html.haml
@@ -24,14 +24,14 @@
     &larr; To issues list
 
 
-.main_box
-  .top_box_content
+.ui-box.ui-box-show
+  .ui-box-head
     %h4.box-title
       - if @issue.closed
         .error.status_info Closed
       = gfm escape_once(@issue.title)
 
-  .middle_box_content
+  .ui-box-body
     %cite.cgray
       Created by #{link_to_member(@project, @issue.author)}
       - if @issue.assignee
@@ -44,13 +44,13 @@
 
     .right
       - @issue.labels.each do |label|
-        %span.label.label-issue
+        %span
           %i.icon-tag
           = label.name
         &nbsp;
 
   - if @issue.description.present?
-    .bottom_box_content
+    .ui-box-bottom
       = preserve do
         = markdown @issue.description
 
diff --git a/app/views/layouts/project_resource.html.haml b/app/views/layouts/project_resource.html.haml
index 709807456c8701f44c8eca009cb4b5e7b6f5a97e..e00f96a7723e1f246c19746945661fc21bc27d94 100644
--- a/app/views/layouts/project_resource.html.haml
+++ b/app/views/layouts/project_resource.html.haml
@@ -14,9 +14,9 @@
         - if @project.repo_exists?
           - if can? current_user, :download_code, @project
             = nav_link(controller: %w(tree blob blame)) do
-              = link_to 'Files', project_tree_path(@project, @ref || @project.root_ref)
+              = link_to 'Files', project_tree_path(@project, @ref || @repository.root_ref)
             = nav_link(controller: %w(commit commits compare repositories protected_branches)) do
-              = link_to "Commits", project_commits_path(@project, @ref || @project.root_ref)
+              = link_to "Commits", project_commits_path(@project, @ref || @repository.root_ref)
             = nav_link(path: 'projects#graph') do
               = link_to "Network", graph_project_path(@project)
 
diff --git a/app/views/merge_requests/_form.html.haml b/app/views/merge_requests/_form.html.haml
index 9606e2e53b3a69ef2ad884845b5bbd74667a1ea0..67444dad5de2a33e531d4aac0fbe303116ecec15 100644
--- a/app/views/merge_requests/_form.html.haml
+++ b/app/views/merge_requests/_form.html.haml
@@ -5,45 +5,47 @@
         - @merge_request.errors.full_messages.each do |msg|
           %li= msg
 
-  %h4.cdark 1. Select Branches
-  %br
+  %fieldset
+    %legend 1. Select Branches
 
-  .row
-    .span5
-      .mr_branch_box
-        %h5 From (Head Branch)
-        .body
-          .padded= f.select(:source_branch, @project.heads.map(&:name), { include_blank: "Select branch" }, {class: 'chosen span4'})
-      .mr_source_commit
+    .row
+      .span5
+        .mr_branch_box
+          %h5 From (Head Branch)
+          .body
+            .padded= f.select(:source_branch, @repository.heads.map(&:name), { include_blank: "Select branch" }, {class: 'chosen span4'})
+        .mr_source_commit
 
-    .span2
-      %center= image_tag "merge.png", class: 'mr_direction_tip'
-    .span5
-      .mr_branch_box
-        %h5 To (Base Branch)
-        .body
-          .padded= f.select(:target_branch, @project.heads.map(&:name), { include_blank: "Select branch" }, {class: 'chosen span4'})
-      .mr_target_commit
+      .span2
+        %center= image_tag "merge.png", class: 'mr_direction_tip'
+      .span5
+        .mr_branch_box
+          %h5 To (Base Branch)
+          .body
+            .padded= f.select(:target_branch, @repository.heads.map(&:name), { include_blank: "Select branch" }, {class: 'chosen span4'})
+        .mr_target_commit
 
-  %h4.cdark 2. Fill info
+  %fieldset
+    %legend 2. Fill info
 
-  .clearfix
-    .merge_requests_form_box
-      .top_box_content
-        = f.label :title do
-          %strong= "Title *"
-        .input= f.text_field :title, class: "input-xxlarge pad js-gfm-input", maxlength: 255, rows: 5, required: true
-      .merge_requests_middle_box
-        .merge_requests_assignee
-          = f.label :assignee_id do
-            %i.icon-user
-            Assign to
-          .input= f.select(:assignee_id, @project.users.all.collect {|p| [ p.name, p.id ] }, { include_blank: "Select user" }, {class: 'chosen span3'})
-        .merge_requests_milestone
-          = f.label :milestone_id do
-            %i.icon-time
-            Milestone
-          .input= f.select(:milestone_id, @project.milestones.active.all.collect {|p| [ p.title, p.id ] }, { include_blank: "Select milestone" }, {class: 'chosen'})
+    .ui-box.ui-box-show
+      .ui-box-head
+        .clearfix
+          = f.label :title do
+            %strong= "Title *"
+          .input= f.text_field :title, class: "input-xxlarge pad js-gfm-input", maxlength: 255, rows: 5, required: true
+      .ui-box-body
+        .clearfix
+          .left
+            = f.label :assignee_id do
+              %i.icon-user
+              Assign to
+            .input= f.select(:assignee_id, @project.users.all.collect {|p| [ p.name, p.id ] }, { include_blank: "Select user" }, {class: 'chosen span3'})
+          .left
+            = f.label :milestone_id do
+              %i.icon-time
+              Milestone
+            .input= f.select(:milestone_id, @project.milestones.active.all.collect {|p| [ p.title, p.id ] }, { include_blank: "Select milestone" }, {class: 'chosen'})
 
   .control-group
 
diff --git a/app/views/merge_requests/show/_commits.html.haml b/app/views/merge_requests/show/_commits.html.haml
index 796922776d9c6ff7870563d88e571bb71723135b..40d85db02628be0a0d87991ecdf4e7bb62ba0f8e 100644
--- a/app/views/merge_requests/show/_commits.html.haml
+++ b/app/views/merge_requests/show/_commits.html.haml
@@ -1,6 +1,6 @@
 - if @commits.present?
   .ui-box
-    %h5
+    %h5.title
       %i.icon-list
       Commits (#{@commits.count})
     .merge-request-commits
diff --git a/app/views/merge_requests/show/_mr_box.html.haml b/app/views/merge_requests/show/_mr_box.html.haml
index cd33732d191733208f2ff516b6496c855a9c7b6e..644d7fcc58e08667a8c33beae112445073765092 100644
--- a/app/views/merge_requests/show/_mr_box.html.haml
+++ b/app/views/merge_requests/show/_mr_box.html.haml
@@ -1,5 +1,5 @@
-.main_box
-  .top_box_content
+.ui-box.ui-box-show
+  .ui-box-head
     %h4.box-title
       - if @merge_request.merged
         .error.status_info
@@ -9,7 +9,7 @@
         .error.status_info Closed
       = gfm escape_once(@merge_request.title)
 
-  .middle_box_content
+  .ui-box-body
     %div
       %cite.cgray
         Created at #{@merge_request.created_at.stamp("Aug 21, 2011")} by #{link_to_member(@project, @merge_request.author)}
@@ -22,7 +22,7 @@
 
 
   - if @merge_request.closed
-    .bottom_box_content
+    .ui-box-bottom
       - if @merge_request.merged?
         %span
           Merged by #{link_to_member(@project, @merge_request.merge_event.author)}
diff --git a/app/views/milestones/show.html.haml b/app/views/milestones/show.html.haml
index c4975c72ef299c051570c5bab3cf6b4db7735196..6d276683fdce01905137ef4c9272479cc70f6039 100644
--- a/app/views/milestones/show.html.haml
+++ b/app/views/milestones/show.html.haml
@@ -27,8 +27,8 @@
     %span All issues for this milestone are closed. You may close milestone now.
     = link_to 'Close Milestone', project_milestone_path(@project, @milestone, milestone: {closed: true }), method: :put, class: "btn small danger"
 
-.main_box
-  .top_box_content
+.ui-box.ui-box-show
+  .ui-box-head
     %h4.box-title
       - if @milestone.closed
         .error.status_info Closed
@@ -37,7 +37,7 @@
 
       = gfm escape_once(@milestone.title)
 
-  .middle_box_content
+  .ui-box-body
     %h5
       Progress:
       %small
diff --git a/app/views/notes/_note.html.haml b/app/views/notes/_note.html.haml
index 70baa212d1002d787ab6f6e28346f86d77f3039f..8591e7bd86be27a9ba3bed3f4d44f2a8ba46e816 100644
--- a/app/views/notes/_note.html.haml
+++ b/app/views/notes/_note.html.haml
@@ -34,6 +34,8 @@
     = preserve do
       = markdown(note.note)
     - if note.attachment.url
+      - if note.attachment.image?
+        = image_tag note.attachment.url, class: 'thumbnail span4'
       .right
         %div.file
           = link_to note.attachment_identifier, note.attachment.url, target: "_blank"
diff --git a/app/views/projects/_form.html.haml b/app/views/projects/_form.html.haml
index 7044d1f20be1183c446de80268903f3018b7646e..c8eacdc2a46e6319080e2135a5183d81e4cef0f0 100644
--- a/app/views/projects/_form.html.haml
+++ b/app/views/projects/_form.html.haml
@@ -15,13 +15,13 @@
       = f.label :path do
         Repository
       .controls
-        = text_field_tag :ppath, @project.path_to_repo, class: "xxlarge", readonly: true
+        = text_field_tag :ppath, @repository.path_to_repo, class: "xxlarge", readonly: true
 
 
-    - unless @project.heads.empty?
+    - unless @repository.heads.empty?
       .clearfix
         = f.label :default_branch, "Default Branch"
-        .input= f.select(:default_branch, @project.heads.map(&:name), {}, style: "width:210px;")
+        .input= f.select(:default_branch, @repository.heads.map(&:name), {}, style: "width:210px;")
 
   %fieldset.features
     %legend Features:
diff --git a/app/views/protected_branches/index.html.haml b/app/views/protected_branches/index.html.haml
index f408fd16c2c7a57de2cbe4c325ea9cdc5674a6d6..098f8d55bb31c0eb882e6e6fdf7386935b17da2a 100644
--- a/app/views/protected_branches/index.html.haml
+++ b/app/views/protected_branches/index.html.haml
@@ -36,7 +36,7 @@
           %td
             = link_to project_commits_path(@project, branch.name) do
               %strong= branch.name
-              - if branch.name == @project.root_ref
+              - if @project.root_ref?(branch.name)
                 %span.label default
           %td
             - if branch.commit
diff --git a/app/views/repositories/_branch.html.haml b/app/views/repositories/_branch.html.haml
index 2728b100ff6e60079eb8ff2dbaafc72a6ac80bb2..74f742687b1077f8e3362b2ad64107ddecb234d6 100644
--- a/app/views/repositories/_branch.html.haml
+++ b/app/views/repositories/_branch.html.haml
@@ -8,7 +8,7 @@
       - else
         %i.icon-unlock
       %strong= truncate(branch.name, length: 60)
-      - if branch.name == @project.root_ref
+      - if branch.name == @repository.root_ref
         %span.label default
   %td
     = link_to project_commit_path(@project, commit.id), class: 'commit_short_id' do
diff --git a/app/views/repositories/_feed.html.haml b/app/views/repositories/_feed.html.haml
index 496328baca5d41f42bc60c0f1af3df3436749900..443801337181bdbd7ea08c38cdd041592c62b842 100644
--- a/app/views/repositories/_feed.html.haml
+++ b/app/views/repositories/_feed.html.haml
@@ -5,7 +5,7 @@
     = link_to project_commits_path(@project, commit.head.name) do
       %strong
         = commit.head.name
-      - if commit.head.name == @project.root_ref
+      - if @project.root_ref?(commit.head.name)
         %span.label default
 
   %td
diff --git a/app/views/repositories/stats.html.haml b/app/views/repositories/stats.html.haml
index a93814a477780b293af955dbb0f6a2c768bf116d..bdf047f1e989ee9c690b756cf5f1b45aa5fdd4ad 100644
--- a/app/views/repositories/stats.html.haml
+++ b/app/views/repositories/stats.html.haml
@@ -7,7 +7,7 @@
       %b Total commits:
       %span= @stats.commits_count
     %p
-      %b Total files in #{@project.root_ref}:
+      %b Total files in #{@repository.root_ref}:
       %span= @stats.files_count
     %p
       %b Authors:
diff --git a/app/views/repositories/tags.html.haml b/app/views/repositories/tags.html.haml
index 193cb2e30f234b08c8d491348257efe5552b1f2b..8e52ad1b47d1f0850ed8bf2b2b95bbc2a9508e3d 100644
--- a/app/views/repositories/tags.html.haml
+++ b/app/views/repositories/tags.html.haml
@@ -30,4 +30,10 @@
               Download
 
 - else
-  %h3 No tags
+  %h3.nothing_here_message
+    Repository has no tags yet.
+    %br
+    %small
+      Use git tag command to add a new one:
+      %br
+      %span.monospace git tag -a v1.4 -m 'version 1.4'
diff --git a/app/views/team_members/_team.html.haml b/app/views/team_members/_team.html.haml
index 462e75af183f93a58a2af8ded15344a7f86b95a0..365d9b65942da06a0190af04ee263543cdb3dbdb 100644
--- a/app/views/team_members/_team.html.haml
+++ b/app/views/team_members/_team.html.haml
@@ -1,6 +1,6 @@
 - grouper_project_members(@project).each do |access, members|
   .ui-box
-    %h5
+    %h5.title
       = Project.access_options.key(access).pluralize
       %small= members.size
     %ul.well-list
diff --git a/app/views/tree/_tree.html.haml b/app/views/tree/_tree.html.haml
index a632bb3b0d7bb83d02d24086e2434292e0a119af..c284295951023e892ee3e69a3db1db2da3eeee56 100644
--- a/app/views/tree/_tree.html.haml
+++ b/app/views/tree/_tree.html.haml
@@ -3,9 +3,13 @@
     %span.arrow
     = link_to project_tree_path(@project, @ref) do
       = @project.name
-  - tree.breadcrumbs(6) do |link|
+  - tree.breadcrumbs(6) do |title, path|
     \/
-    %li= link
+    %li
+      - if path
+        = link_to truncate(title, length: 40), project_tree_path(@project, path)
+      - else
+        = link_to title, '#'
 
 .clear
 %div.tree_progress
@@ -26,7 +30,7 @@
         %tr.tree-item
           %td.tree-item-file-name
             = image_tag "file_empty.png", size: '16x16'
-            = link_to "..", tree.up_dir_path
+            = link_to "..", project_tree_path(@project, tree.up_dir_path)
           %td
           %td
           %td
diff --git a/app/views/wikis/_form.html.haml b/app/views/wikis/_form.html.haml
index 83b16b138d377d833df16da754239ca089923213..9eb2a571fe5c0bef1cc77913c25c534adf3e58b9 100644
--- a/app/views/wikis/_form.html.haml
+++ b/app/views/wikis/_form.html.haml
@@ -6,12 +6,12 @@
         - @wiki.errors.full_messages.each do |msg|
           %li= msg
 
-  .main_box
-    .top_box_content
+  .ui-box.ui-box-show
+    .ui-box-head
       = f.label :title
       .input= f.text_field :title, class: 'span8'
       = f.hidden_field :slug
-    .middle_box_content
+    .ui-box-body
       .input
         %span.cgray
           Wiki content is parsed with #{link_to "GitLab Flavored Markdown", help_markdown_path, target: '_blank'}.
@@ -19,7 +19,7 @@
           %code [Link Title](page-slug)
           \.
 
-    .bottom_box_content
+    .ui-box-bottom
       = f.label :content
       .input= f.text_area :content, class: 'span8 js-gfm-input'
   .actions
diff --git a/app/workers/post_receive.rb b/app/workers/post_receive.rb
index 1414ed490c92d0a8d90317534052860a1aa80f83..9e3f32f835dc9fc9fa06b1e964644be406c36f3e 100644
--- a/app/workers/post_receive.rb
+++ b/app/workers/post_receive.rb
@@ -11,7 +11,7 @@ class PostReceive
 
     # Ignore push from non-gitlab users
     user = if identifier.eql? Gitlab.config.gitolite.admin_key
-      email = project.commit(newrev).author.email rescue nil
+      email = project.repository.commit(newrev).author.email rescue nil
       User.find_by_email(email) if email
     elsif /^[A-Z0-9._%a-z\-]+@(?:[A-Z0-9a-z\-]+\.)+[A-Za-z]{2,4}$/.match(identifier)
       User.find_by_email(identifier)
diff --git a/features/steps/admin/admin_groups.rb b/features/steps/admin/admin_groups.rb
index 4cd071657feaf3e6f8fb0e8ef2cd6a2419012c60..cbca2daa70182a9abd0204551c8d41424a8dd52e 100644
--- a/features/steps/admin/admin_groups.rb
+++ b/features/steps/admin/admin_groups.rb
@@ -16,7 +16,7 @@ class AdminGroups < Spinach::FeatureSteps
     @project = create(:project, group: @group)
     @event   = create(:closed_issue_event, project: @project)
 
-    @project.add_access current_user, :admin
+    @project.team << [current_user, :master]
   end
 
   And 'Create gitlab user "John"' do
diff --git a/features/steps/dashboard/dashboard.rb b/features/steps/dashboard/dashboard.rb
index 775a721f1a486d8f7b591459f7f9731fa3021315..73e226737499f9138e02d953abe564466bba2454 100644
--- a/features/steps/dashboard/dashboard.rb
+++ b/features/steps/dashboard/dashboard.rb
@@ -61,7 +61,7 @@ class Dashboard < Spinach::FeatureSteps
 
   And 'I own project "Shop"' do
     @project = create :project, name: 'Shop'
-    @project.add_access(@user, :admin)
+    @project.team << [@user, :master]
   end
 
   And 'I have group with projects' do
@@ -69,7 +69,7 @@ class Dashboard < Spinach::FeatureSteps
     @project = create(:project, group: @group)
     @event   = create(:closed_issue_event, project: @project)
 
-    @project.add_access current_user, :admin
+    @project.team << [current_user, :master]
   end
 
   And 'project "Shop" has push event' do
diff --git a/features/steps/dashboard/dashboard_issues.rb b/features/steps/dashboard/dashboard_issues.rb
index 5ace88023f0d3f29f995ab7b0d162814e4cfbac2..fcf4296ad11b11f6061b4653ec6e50def98400a2 100644
--- a/features/steps/dashboard/dashboard_issues.rb
+++ b/features/steps/dashboard/dashboard_issues.rb
@@ -13,7 +13,7 @@ class DashboardIssues < Spinach::FeatureSteps
 
   And 'I have assigned issues' do
     project = create :project
-    project.add_access(@user, :read, :write)
+    project.team << [@user, :master]
 
     2.times { create :issue, author: @user, assignee: @user, project: project }
   end
diff --git a/features/steps/dashboard/dashboard_merge_requests.rb b/features/steps/dashboard/dashboard_merge_requests.rb
index 485a4ccc113380192c3fd5a6850e5766a6a3e887..7cfa8a13ff8a4b39a61346a50b27ab9a1f18d307 100644
--- a/features/steps/dashboard/dashboard_merge_requests.rb
+++ b/features/steps/dashboard/dashboard_merge_requests.rb
@@ -14,8 +14,8 @@ class DashboardMergeRequests < Spinach::FeatureSteps
     project1 = create :project
     project2 = create :project
 
-    project1.add_access(@user, :read, :write)
-    project2.add_access(@user, :read, :write)
+    project1.team << [@user, :master]
+    project2.team << [@user, :master]
 
     merge_request1 = create :merge_request, author: @user, project: project1
     merge_request2 = create :merge_request, author: @user, project: project2
diff --git a/features/steps/dashboard/dashboard_search.rb b/features/steps/dashboard/dashboard_search.rb
index a34c14d0c5fb503a63763e43a37bcc4cf8c1537e..9c8c879479db48edeed25cddd4c24c59cd08545c 100644
--- a/features/steps/dashboard/dashboard_search.rb
+++ b/features/steps/dashboard/dashboard_search.rb
@@ -1,6 +1,7 @@
 class DashboardSearch < Spinach::FeatureSteps
   include SharedAuthentication
   include SharedPaths
+  include SharedProject
 
   Given 'I search for "Sho"' do
     fill_in "dashboard_search", with: "Sho"
@@ -11,11 +12,6 @@ class DashboardSearch < Spinach::FeatureSteps
     page.should have_link "Shop"
   end
 
-  And 'I own project "Shop"' do
-    @project = create(:project, :name => "Shop")
-    @project.add_access(@user, :admin)
-  end
-
   Given 'I search for "Contibuting"' do
     fill_in "dashboard_search", with: "Contibuting"
     click_button "Search"
diff --git a/features/steps/group/group.rb b/features/steps/group/group.rb
index e3364f09e3405f0e64d0a30c8a1be157a77525e2..04d8c874b3ecd59c08fd539f253fb8c75de1ca3c 100644
--- a/features/steps/group/group.rb
+++ b/features/steps/group/group.rb
@@ -13,7 +13,7 @@ class Groups < Spinach::FeatureSteps
     @project = create(:project, group: @group)
     @event   = create(:closed_issue_event, project: @project)
 
-    @project.add_access current_user, :admin
+    @project.team << [current_user, :master]
   end
 
   And 'I should see projects activity feed' do
diff --git a/features/steps/project/create_project.rb b/features/steps/project/create_project.rb
index b9b4534ed6874d91a7659fbac528fe5dff99752b..0d9727732c7cdbb10b093873568417aa9bcbc0b9 100644
--- a/features/steps/project/create_project.rb
+++ b/features/steps/project/create_project.rb
@@ -3,13 +3,13 @@ class CreateProject < Spinach::FeatureSteps
   include SharedPaths
 
   And 'fill project form with valid data' do
-    fill_in 'project_name', :with => 'NewProject'
+    fill_in 'project_name', with: 'Empty'
     click_button "Create project"
   end
 
   Then 'I should see project page' do
     current_path.should == project_path(Project.last)
-    page.should have_content "NewProject"
+    page.should have_content "Empty"
   end
 
   And 'I should see empty project instuctions' do
diff --git a/features/steps/project/project_browse_commits.rb b/features/steps/project/project_browse_commits.rb
index 2c03ce14fc199a56f8cd3cc57e9ffe174e2067e3..3433c2ba5f6b60cc9ab5061ae0a1e792f9c4b71c 100644
--- a/features/steps/project/project_browse_commits.rb
+++ b/features/steps/project/project_browse_commits.rb
@@ -4,7 +4,7 @@ class ProjectBrowseCommits < Spinach::FeatureSteps
   include SharedPaths
 
   Then 'I see project commits' do
-    commit = @project.commit
+    commit = @project.repository.commit
     page.should have_content(@project.name)
     page.should have_content(commit.message)
     page.should have_content(commit.id.to_s[0..5])
@@ -15,7 +15,7 @@ class ProjectBrowseCommits < Spinach::FeatureSteps
   end
 
   Then 'I see commits atom feed' do
-    commit = CommitDecorator.decorate(@project.commit)
+    commit = CommitDecorator.decorate(@project.repository.commit)
     page.response_headers['Content-Type'].should have_content("application/atom+xml")
     page.body.should have_selector("title", :text => "Recent commits to #{@project.name}")
     page.body.should have_selector("author email", :text => commit.author_email)
@@ -48,7 +48,7 @@ class ProjectBrowseCommits < Spinach::FeatureSteps
     page.should have_selector('ul.breadcrumb span.divider', count: 3)
     page.should have_selector('ul.breadcrumb a', count: 4)
 
-    find('ul.breadcrumb li:first a')['href'].should match(/#{@project.path}\/commits\/master\z/)
+    find('ul.breadcrumb li:first a')['href'].should match(/#{@project.path_with_namespace}\/commits\/master\z/)
     find('ul.breadcrumb li:last a')['href'].should match(%r{master/app/models/project\.rb\z})
   end
 
diff --git a/features/steps/project/project_team_management.rb b/features/steps/project/project_team_management.rb
index 6bde0b64dfa6b21bc9ea1f0cc8d61d22c017573c..91b3ffeee9a85cd3391c740a846f1169e2d36c53 100644
--- a/features/steps/project/project_team_management.rb
+++ b/features/steps/project/project_team_management.rb
@@ -84,18 +84,18 @@ class ProjectTeamManagement < Spinach::FeatureSteps
   And '"Sam" is "Shop" developer' do
     user = User.find_by_name("Sam")
     project = Project.find_by_name("Shop")
-    project.add_access(user, :write)
+    project.team << [user, :developer]
   end
 
   Given 'I own project "Website"' do
     @project = create(:project, :name => "Website")
-    @project.add_access(@user, :admin)
+    @project.team << [@user, :master]
   end
 
   And '"Mike" is "Website" reporter' do
     user = User.find_by_name("Mike")
     project = Project.find_by_name("Website")
-    project.add_access(user, :read)
+    project.team << [user, :reporter]
   end
 
   And 'I click link "Import team from another project"' do
diff --git a/features/steps/shared/paths.rb b/features/steps/shared/paths.rb
index bd43ba6b3dc21a2cc69926961719bfe853b47339..22d1f33506374836958f801e1255f1bd25252c9b 100644
--- a/features/steps/shared/paths.rb
+++ b/features/steps/shared/paths.rb
@@ -114,15 +114,15 @@ module SharedPaths
   end
 
   Given "I visit my project's files page" do
-    visit project_tree_path(@project, @project.root_ref)
+    visit project_tree_path(@project, root_ref)
   end
 
   Given "I visit my project's commits page" do
-    visit project_commits_path(@project, @project.root_ref, {limit: 5})
+    visit project_commits_path(@project, root_ref, {limit: 5})
   end
 
   Given "I visit my project's commits page for a specific path" do
-    visit project_commits_path(@project, @project.root_ref + "/app/models/project.rb", {limit: 5})
+    visit project_commits_path(@project, root_ref + "/app/models/project.rb", {limit: 5})
   end
 
   Given 'I visit my project\'s commits stats page' do
@@ -174,7 +174,7 @@ module SharedPaths
   end
 
   Given 'I visit project commits page' do
-    visit project_commits_path(@project, @project.root_ref, {limit: 5})
+    visit project_commits_path(@project, root_ref, {limit: 5})
   end
 
   Given 'I visit project commits page for stable branch' do
@@ -182,7 +182,7 @@ module SharedPaths
   end
 
   Given 'I visit project source page' do
-    visit project_tree_path(@project, @project.root_ref)
+    visit project_tree_path(@project, root_ref)
   end
 
   Given 'I visit blob file from repo' do
@@ -240,4 +240,8 @@ module SharedPaths
   Given 'I visit project wiki page' do
     visit project_wiki_path(@project, :index)
   end
+
+  def root_ref
+    @project.repository.root_ref
+  end
 end
diff --git a/features/steps/shared/project.rb b/features/steps/shared/project.rb
index dfc8ce9d99c4e84d58ce2d13d0ba9082dc58f996..12dae15edf920f1ed5ace2644c0b6ac199a4c9ec 100644
--- a/features/steps/shared/project.rb
+++ b/features/steps/shared/project.rb
@@ -4,13 +4,13 @@ module SharedProject
   # Create a project without caring about what it's called
   And "I own a project" do
     @project = create(:project)
-    @project.add_access(@user, :admin)
+    @project.team << [@user, :master]
   end
 
   # Create a specific project called "Shop"
   And 'I own project "Shop"' do
-    @project = create(:project, :name => "Shop")
-    @project.add_access(@user, :admin)
+    @project = create(:project, name: "Shop")
+    @project.team << [@user, :master]
   end
 
   def current_project
diff --git a/lib/api/notes.rb b/lib/api/notes.rb
index 4875ac4c03e7ce08088347a2cfc570dac8a5fb92..4613db54578ad8de224297566c2b27bdd099a2ec 100644
--- a/lib/api/notes.rb
+++ b/lib/api/notes.rb
@@ -13,7 +13,7 @@ module Gitlab
       # Example Request:
       #   GET /projects/:id/notes
       get ":id/notes" do
-        @notes = user_project.common_notes
+        @notes = user_project.notes.common
         present paginate(@notes), with: Entities::Note
       end
 
@@ -25,7 +25,7 @@ module Gitlab
       # Example Request:
       #   GET /projects/:id/notes/:note_id
       get ":id/notes/:note_id" do
-        @note = user_project.common_notes.find(params[:note_id])
+        @note = user_project.notes.common.find(params[:note_id])
         present @note, with: Entities::Note
       end
 
diff --git a/lib/api/projects.rb b/lib/api/projects.rb
index c71fd64838bade344d211b14743fcf981966bf5e..55c81f3158acb10e899a0ba93b19edb920d4d245 100644
--- a/lib/api/projects.rb
+++ b/lib/api/projects.rb
@@ -257,7 +257,7 @@ module Gitlab
         per_page = params[:per_page] || 20
         ref = params[:ref_name] || user_project.try(:default_branch) || 'master'
 
-        commits = user_project.commits(ref, nil, per_page, page * per_page)
+        commits = user_project.repository.commits(ref, nil, per_page, page * per_page)
         present CommitDecorator.decorate(commits), with: Entities::RepoCommit
       end
 
@@ -375,10 +375,10 @@ module Gitlab
 
         ref = params[:sha]
 
-        commit = user_project.commit ref
+        commit = user_project.repository.commit ref
         not_found! "Commit" unless commit
 
-        tree = Tree.new commit.tree, user_project, ref, params[:filepath]
+        tree = Tree.new commit.tree, ref, params[:filepath]
         not_found! "File" unless tree.try(:tree)
 
         content_type tree.mime_type
diff --git a/lib/extracts_path.rb b/lib/extracts_path.rb
index 0b7a0d47caf7b27b1f15978f5735c1c2fe807b0b..5c96eac02e7de0d3bec774b5fec337464a03e24a 100644
--- a/lib/extracts_path.rb
+++ b/lib/extracts_path.rb
@@ -68,7 +68,7 @@ module ExtractsPath
       id = input
       id += '/' unless id.ends_with?('/')
 
-      valid_refs = @project.ref_names
+      valid_refs = @project.repository.ref_names
       valid_refs.select! { |v| id.start_with?("#{v}/") }
 
       if valid_refs.length != 1
@@ -114,9 +114,9 @@ module ExtractsPath
 
     @id = File.join(@ref, @path)
 
-    @commit = CommitDecorator.decorate(@project.commit(@ref))
+    @commit = CommitDecorator.decorate(@project.repository.commit(@ref))
 
-    @tree = Tree.new(@commit.tree, @project, @ref, @path)
+    @tree = Tree.new(@commit.tree, @ref, @path)
     @tree = TreeDecorator.new(@tree)
 
     raise InvalidPathError if @tree.invalid?
diff --git a/lib/gitlab/backend/gitolite_config.rb b/lib/gitlab/backend/gitolite_config.rb
index a2bc4ca8d74f662ebf56acf87b7b1c77077c9c24..10e527eac73ebf55884b0296a365685097bb8fce 100644
--- a/lib/gitlab/backend/gitolite_config.rb
+++ b/lib/gitlab/backend/gitolite_config.rb
@@ -82,7 +82,7 @@ module Gitlab
     end
 
     def destroy_project(project)
-      FileUtils.rm_rf(project.path_to_repo)
+      FileUtils.rm_rf(project.repository.path_to_repo)
       conf.rm_repo(project.path_with_namespace)
     end
 
@@ -138,9 +138,9 @@ module Gitlab
                ::Gitolite::Config::Repo.new(repo_name)
              end
 
-      name_readers = project.repository_readers
-      name_writers = project.repository_writers
-      name_masters = project.repository_masters
+      name_readers = project.team.repository_readers
+      name_writers = project.team.repository_writers
+      name_masters = project.team.repository_masters
 
       pr_br = project.protected_branches.map(&:name).join("$ ")
 
diff --git a/lib/gitlab/markdown.rb b/lib/gitlab/markdown.rb
index 859184b6c3ad028acbbcd09629f79819807d7f25..59249a229eba5c79e5be0b6cb4be7a35c9e986cc 100644
--- a/lib/gitlab/markdown.rb
+++ b/lib/gitlab/markdown.rb
@@ -170,7 +170,7 @@ module Gitlab
     end
 
     def reference_commit(identifier)
-      if @project.valid_repo? && commit = @project.commit(identifier)
+      if @project.valid_repo? && commit = @project.repository.commit(identifier)
         link_to(identifier, project_commit_path(@project, commit), html_options.merge(title: CommitDecorator.new(commit).link_title, class: "gfm gfm-commit #{html_options[:class]}"))
       end
     end
diff --git a/lib/gitlab/satellite/merge_action.rb b/lib/gitlab/satellite/merge_action.rb
index 832db6621c4f23ff58c8df93299ec60171ca6e05..556a1e2d52fdb953295fa65dc65e6d1d97fe4547 100644
--- a/lib/gitlab/satellite/merge_action.rb
+++ b/lib/gitlab/satellite/merge_action.rb
@@ -31,7 +31,7 @@ module Gitlab
             merge_repo.git.push({raise: true, timeout: true}, :origin, merge_request.target_branch)
 
             # remove source branch
-            if merge_request.should_remove_source_branch && !project.root_ref?(merge_request.source_branch)
+            if merge_request.should_remove_source_branch && !project.repository.root_ref?(merge_request.source_branch)
               # will raise CommandFailed when push fails
               merge_repo.git.push({raise: true, timeout: true}, :origin, ":#{merge_request.source_branch}")
             end
diff --git a/lib/static_model.rb b/lib/static_model.rb
index 5b64be1f0413f53779443960615c0556250ef914..185921d8fbee0ccd070d458a11d01e7e3215d8ff 100644
--- a/lib/static_model.rb
+++ b/lib/static_model.rb
@@ -38,7 +38,7 @@ module StaticModel
   end
 
   def ==(other)
-    if other.is_a? StaticModel
+    if other.is_a? ::StaticModel
       id == other.id
     else
       super
diff --git a/spec/controllers/commit_controller_spec.rb b/spec/controllers/commit_controller_spec.rb
index 5aef4c676eeb9d3b04342f5a06507e93857efda5..7bf13822829bc4607a698c7bb6358f5fb945c705 100644
--- a/spec/controllers/commit_controller_spec.rb
+++ b/spec/controllers/commit_controller_spec.rb
@@ -3,12 +3,12 @@ require 'spec_helper'
 describe CommitController do
   let(:project) { create(:project) }
   let(:user)    { create(:user) }
-  let(:commit)  { project.last_commit_for("master") }
+  let(:commit)  { project.repository.last_commit_for("master") }
 
   before do
     sign_in(user)
 
-    project.add_access(user, :read, :admin)
+    project.team << [user, :master]
   end
 
   describe "#show" do
diff --git a/spec/controllers/commits_controller_spec.rb b/spec/controllers/commits_controller_spec.rb
index da33fd8a2b5f4fa1b588e557666260537d3930bd..1d5d99df8027eabbdab80f755b4b6c8ff94b8580 100644
--- a/spec/controllers/commits_controller_spec.rb
+++ b/spec/controllers/commits_controller_spec.rb
@@ -7,7 +7,7 @@ describe CommitsController do
   before do
     sign_in(user)
 
-    project.add_access(user, :read, :admin)
+    project.team << [user, :master]
   end
 
   describe "GET show" do
diff --git a/spec/controllers/merge_requests_controller_spec.rb b/spec/controllers/merge_requests_controller_spec.rb
index 7aebe06cf0c03f9d7cacd33f7aa63560510b33d8..8478bb3adff47a275596223027a69faa0fd1d625 100644
--- a/spec/controllers/merge_requests_controller_spec.rb
+++ b/spec/controllers/merge_requests_controller_spec.rb
@@ -7,7 +7,7 @@ describe MergeRequestsController do
 
   before do
     sign_in(user)
-    project.add_access(user, :read, :admin)
+    project.team << [user, :master]
     MergeRequestsController.any_instance.stub(validates_merge_request: true)
   end
 
diff --git a/spec/controllers/tree_controller_spec.rb b/spec/controllers/tree_controller_spec.rb
index b9295537d01f565cfb1de204cfd263a3ebc25c44..81c7656d07a2bed48821393f9df2159a5333026d 100644
--- a/spec/controllers/tree_controller_spec.rb
+++ b/spec/controllers/tree_controller_spec.rb
@@ -7,7 +7,7 @@ describe TreeController do
   before do
     sign_in(user)
 
-    project.add_access(user, :read, :admin)
+    project.team << [user, :master]
 
     project.stub(:branches).and_return(['master', 'foo/bar/baz'])
     project.stub(:tags).and_return(['v1.0.0', 'v2.0.0'])
diff --git a/spec/helpers/gitlab_markdown_helper_spec.rb b/spec/helpers/gitlab_markdown_helper_spec.rb
index b792e0c86f6480150d99c13dc3e9f74718be626b..497a5f17846c1bf19a16fbdd82f00e98ee2639d2 100644
--- a/spec/helpers/gitlab_markdown_helper_spec.rb
+++ b/spec/helpers/gitlab_markdown_helper_spec.rb
@@ -4,7 +4,7 @@ describe GitlabMarkdownHelper do
   let!(:project) { create(:project) }
 
   let(:user)          { create(:user, username: 'gfm') }
-  let(:commit)        { CommitDecorator.decorate(project.commit) }
+  let(:commit)        { CommitDecorator.decorate(project.repository.commit) }
   let(:issue)         { create(:issue, project: project) }
   let(:merge_request) { create(:merge_request, project: project) }
   let(:snippet)       { create(:snippet, project: project) }
@@ -85,7 +85,7 @@ describe GitlabMarkdownHelper do
       let(:expected) { project_team_member_path(project, member) }
 
       before do
-        project.add_access(user, :admin)
+        project.team << [user, :master]
       end
 
       it "should link using a simple name" do
@@ -314,7 +314,7 @@ describe GitlabMarkdownHelper do
     end
 
     it "should handle references in lists" do
-      project.add_access(user, :admin)
+      project.team << [user, :master]
 
       actual = "\n* dark: ##{issue.id}\n* light by @#{member.user.username}"
 
diff --git a/spec/lib/extracts_path_spec.rb b/spec/lib/extracts_path_spec.rb
index 8773d77f5a5b8d35e5ea49d6c3a17116fc61f07a..deb6499e00803707ed537f044ad2f3f9696dba07 100644
--- a/spec/lib/extracts_path_spec.rb
+++ b/spec/lib/extracts_path_spec.rb
@@ -7,7 +7,7 @@ describe ExtractsPath do
 
   before do
     @project = project
-    project.stub(:ref_names).and_return(['master', 'foo/bar/baz', 'v1.0.0', 'v2.0.0'])
+    project.stub(repository: stub(ref_names: ['master', 'foo/bar/baz', 'v1.0.0', 'v2.0.0']))
     project.stub(path_with_namespace: 'gitlab/gitlab-ci')
   end
 
diff --git a/spec/models/commit_spec.rb b/spec/models/commit_spec.rb
index e760c501bd7e9b938826f94ed53fd04cc1d4bea0..91301029e89c91b8a38b39eba3f4bb9c836bb4c9 100644
--- a/spec/models/commit_spec.rb
+++ b/spec/models/commit_spec.rb
@@ -1,7 +1,7 @@
 require 'spec_helper'
 
 describe Commit do
-  let(:commit) { create(:project).commit }
+  let(:commit) { create(:project).repository.commit }
 
   describe CommitDecorator do
     let(:decorator) { CommitDecorator.new(commit) }
diff --git a/spec/models/gitlab_ci_service_spec.rb b/spec/models/gitlab_ci_service_spec.rb
index ec43d46b347b6e8535b41a2c734be06e35761791..b86588af1ace6e3a2e94b9810d6cc4b4bc5cb5bb 100644
--- a/spec/models/gitlab_ci_service_spec.rb
+++ b/spec/models/gitlab_ci_service_spec.rb
@@ -35,10 +35,6 @@ describe GitlabCiService do
       )
     end
 
-    describe :commit_badge_path do
-      it { @service.commit_badge_path("2ab7834c").should == "http://ci.gitlab.org/projects/2/status?sha=2ab7834c"}
-    end
-
     describe :commit_status_path do
       it { @service.commit_status_path("2ab7834c").should == "http://ci.gitlab.org/projects/2/builds/2ab7834c/status.json?token=verySecret"}
     end
diff --git a/spec/models/note_spec.rb b/spec/models/note_spec.rb
index 61aaf6455ebfda8e124644a0730b4ccce9037453..8e06e6748da849856a7312567dd631ab4a0f2c43 100644
--- a/spec/models/note_spec.rb
+++ b/spec/models/note_spec.rb
@@ -4,7 +4,6 @@
 #
 #  id            :integer          not null, primary key
 #  note          :text
-#  noteable_id   :string(255)
 #  noteable_type :string(255)
 #  author_id     :integer
 #  created_at    :datetime         not null
@@ -12,6 +11,8 @@
 #  project_id    :integer
 #  attachment    :string(255)
 #  line_code     :string(255)
+#  commit_id     :string(255)
+#  noteable_id   :integer
 #
 
 require 'spec_helper'
@@ -76,7 +77,7 @@ describe Note do
   end
 
   let(:project) { create(:project) }
-  let(:commit) { project.commit }
+  let(:commit) { project.repository.commit }
 
   describe "Commit notes" do
     before do
diff --git a/spec/models/project_hooks_spec.rb b/spec/models/project_hooks_spec.rb
index 77adfe06cff1b9ab0eb1ae4761806b528ee3d2fd..60457e20c51425e8bc43d6befc5f6cfab2c8cce3 100644
--- a/spec/models/project_hooks_spec.rb
+++ b/spec/models/project_hooks_spec.rb
@@ -2,6 +2,7 @@ require 'spec_helper'
 
 describe Project, "Hooks" do
   let(:project) { create(:project) }
+
   before do
     @key = create(:key, user: project.owner)
     @user = @key.user
@@ -70,8 +71,9 @@ describe Project, "Hooks" do
 
     context "when gathering commit data" do
       before do
-        @oldrev, @newrev, @ref = project.fresh_commits(2).last.sha, project.fresh_commits(2).first.sha, 'refs/heads/master'
-        @commit = project.fresh_commits(2).first
+        @oldrev, @newrev, @ref = project.repository.fresh_commits(2).last.sha,
+          project.repository.fresh_commits(2).first.sha, 'refs/heads/master'
+        @commit = project.repository.fresh_commits(2).first
 
         # Fill nil/empty attributes
         project.description = "This is a description"
diff --git a/spec/models/project_repository_spec.rb b/spec/models/project_repository_spec.rb
deleted file mode 100644
index e1d01cbfeafe377d1887728a49fa46619d236e9f..0000000000000000000000000000000000000000
--- a/spec/models/project_repository_spec.rb
+++ /dev/null
@@ -1,159 +0,0 @@
-require 'spec_helper'
-
-describe Project, "Repository" do
-  let(:project) { create(:project) }
-
-  describe "#empty_repo?" do
-    it "should return true if the repo doesn't exist" do
-      project.stub(repo_exists?: false, has_commits?: true)
-      project.should be_empty_repo
-    end
-
-    it "should return true if the repo has commits" do
-      project.stub(repo_exists?: true, has_commits?: false)
-      project.should be_empty_repo
-    end
-
-    it "should return false if the repo exists and has commits" do
-      project.stub(repo_exists?: true, has_commits?: true)
-      project.should_not be_empty_repo
-    end
-  end
-
-  describe "#discover_default_branch" do
-    let(:master) { 'master' }
-    let(:stable) { 'stable' }
-
-    it "returns 'master' when master exists" do
-      project.should_receive(:branch_names).at_least(:once).and_return([stable, master])
-      project.discover_default_branch.should == 'master'
-    end
-
-    it "returns non-master when master exists but default branch is set to something else" do
-      project.default_branch = 'stable'
-      project.should_receive(:branch_names).at_least(:once).and_return([stable, master])
-      project.discover_default_branch.should == 'stable'
-    end
-
-    it "returns a non-master branch when only one exists" do
-      project.should_receive(:branch_names).at_least(:once).and_return([stable])
-      project.discover_default_branch.should == 'stable'
-    end
-
-    it "returns nil when no branch exists" do
-      project.should_receive(:branch_names).at_least(:once).and_return([])
-      project.discover_default_branch.should be_nil
-    end
-  end
-
-  describe "#root_ref" do
-    it "returns default_branch when set" do
-      project.default_branch = 'stable'
-      project.root_ref.should == 'stable'
-    end
-
-    it "returns 'master' when default_branch is nil" do
-      project.default_branch = nil
-      project.root_ref.should == 'master'
-    end
-  end
-
-  describe "#root_ref?" do
-    it "returns true when branch is root_ref" do
-      project.default_branch = 'stable'
-      project.root_ref?('stable').should be_true
-    end
-
-    it "returns false when branch is not root_ref" do
-      project.default_branch = nil
-      project.root_ref?('stable').should be_false
-    end
-  end
-
-  describe :repo do
-    it "should return valid repo" do
-      project.repo.should be_kind_of(Grit::Repo)
-    end
-
-    it "should return nil" do
-      lambda { Project.new(path: "invalid").repo }.should raise_error(Grit::NoSuchPathError)
-    end
-
-    it "should return nil" do
-      lambda { Project.new.repo }.should raise_error(TypeError)
-    end
-  end
-
-  describe :commit do
-    it "should return first head commit if without params" do
-      project.commit.id.should == project.repo.commits.first.id
-    end
-
-    it "should return valid commit" do
-      project.commit(ValidCommit::ID).should be_valid_commit
-    end
-
-    it "should return nil" do
-      project.commit("+123_4532530XYZ").should be_nil
-    end
-  end
-
-  describe :tree do
-    before do
-      @commit = project.commit(ValidCommit::ID)
-    end
-
-    it "should raise error w/o arguments" do
-      lambda { project.tree }.should raise_error
-    end
-
-    it "should return root tree for commit" do
-      tree = project.tree(@commit)
-      tree.contents.size.should == ValidCommit::FILES_COUNT
-      tree.contents.map(&:name).should == ValidCommit::FILES
-    end
-
-    it "should return root tree for commit with correct path" do
-      tree = project.tree(@commit, ValidCommit::C_FILE_PATH)
-      tree.contents.map(&:name).should == ValidCommit::C_FILES
-    end
-
-    it "should return root tree for commit with incorrect path" do
-      project.tree(@commit, "invalid_path").should be_nil
-    end
-  end
-
-  describe "fresh commits" do
-    let(:project) { create(:project) }
-
-    it { project.fresh_commits(3).count.should == 3 }
-    it { project.fresh_commits.first.id.should == "bcf03b5de6c33f3869ef70d68cf06e679d1d7f9a" }
-    it { project.fresh_commits.last.id.should == "f403da73f5e62794a0447aca879360494b08f678" }
-  end
-
-  describe "commits_between" do
-    let(:project) { create(:project) }
-
-    subject do
-      commits = project.commits_between("3a4b4fb4cde7809f033822a171b9feae19d41fff",
-                                        "8470d70da67355c9c009e4401746b1d5410af2e3")
-      commits.map { |c| c.id }
-    end
-
-    it { should have(3).elements }
-    it { should include("f0f14c8eaba69ebddd766498a9d0b0e79becd633") }
-    it { should_not include("bcf03b5de6c33f3869ef70d68cf06e679d1d7f9a") }
-  end
-
-  describe :valid_repo? do
-    it "should be valid repo" do
-      project = create(:project)
-      project.valid_repo?.should be_true
-    end
-
-    it "should be invalid repo" do
-      project = Project.new(name: "ok_name", path: "/INVALID_PATH/", path: "NEOK")
-      project.valid_repo?.should be_false
-    end
-  end
-end
diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb
index ea1efbbec78b432028833248560ca3a6eb679637..223b9d48c015cb42f029912a20541d4e2d15f80c 100644
--- a/spec/models/project_spec.rb
+++ b/spec/models/project_spec.rb
@@ -9,7 +9,7 @@
 #  created_at             :datetime         not null
 #  updated_at             :datetime         not null
 #  private_flag           :boolean          default(TRUE), not null
-#  owner_id               :integer
+#  creator_id             :integer
 #  default_branch         :string(255)
 #  issues_enabled         :boolean          default(TRUE), not null
 #  wall_enabled           :boolean          default(TRUE), not null
@@ -75,57 +75,16 @@ describe Project do
   end
 
   describe "Respond to" do
-    it { should respond_to(:public?) }
-    it { should respond_to(:private?) }
     it { should respond_to(:url_to_repo) }
-    it { should respond_to(:path_to_repo) }
-    it { should respond_to(:valid_repo?) }
     it { should respond_to(:repo_exists?) }
-
-    # Repository Role
-    it { should respond_to(:tree) }
-    it { should respond_to(:root_ref) }
-    it { should respond_to(:repo) }
-    it { should respond_to(:tags) }
-    it { should respond_to(:commit) }
-    it { should respond_to(:commits) }
-    it { should respond_to(:commits_between) }
-    it { should respond_to(:commits_with_refs) }
-    it { should respond_to(:commits_since) }
-    it { should respond_to(:commits_between) }
     it { should respond_to(:satellite) }
     it { should respond_to(:update_repository) }
     it { should respond_to(:destroy_repository) }
-    it { should respond_to(:archive_repo) }
-
-    # Authority Role
-    it { should respond_to(:add_access) }
-    it { should respond_to(:reset_access) }
-    it { should respond_to(:repository_writers) }
-    it { should respond_to(:repository_masters) }
-    it { should respond_to(:repository_readers) }
-    it { should respond_to(:allow_read_for?) }
-    it { should respond_to(:guest_access_for?) }
-    it { should respond_to(:report_access_for?) }
-    it { should respond_to(:dev_access_for?) }
-    it { should respond_to(:master_access_for?) }
-
-    # Team Role
-    it { should respond_to(:team_member_by_name_or_email) }
-    it { should respond_to(:team_member_by_id) }
-    it { should respond_to(:add_user_to_team) }
-    it { should respond_to(:add_users_to_team) }
-    it { should respond_to(:add_user_id_to_team) }
-    it { should respond_to(:add_users_ids_to_team) }
-
-    # Project Push Role
     it { should respond_to(:observe_push) }
     it { should respond_to(:update_merge_requests) }
     it { should respond_to(:execute_hooks) }
     it { should respond_to(:post_receive_data) }
     it { should respond_to(:trigger_post_receive) }
-
-    # Namespaced Project Role
     it { should respond_to(:transfer) }
     it { should respond_to(:name_with_namespace) }
     it { should respond_to(:namespace_owner) }
@@ -138,11 +97,6 @@ describe Project do
     project.url_to_repo.should == Gitlab.config.gitolite.ssh_path_prefix + "somewhere.git"
   end
 
-  it "should return path to repo" do
-    project = Project.new(path: "somewhere")
-    project.path_to_repo.should == Rails.root.join("tmp", "repositories", "somewhere")
-  end
-
   it "returns the full web URL for this repo" do
     project = Project.new(path: "somewhere")
     project.web_url.should == "#{Gitlab.config.gitlab.url}/somewhere"
@@ -269,4 +223,16 @@ describe Project do
       it { @project.to_param.should == "gitlab-ci" }
     end
   end
+
+  describe :repository do
+    let(:project) { create(:project) }
+
+    it "should return valid repo" do
+      project.repository.should be_kind_of(Repository)
+    end
+
+    it "should return nil" do
+      Project.new(path: "empty").repository.should be_nil
+    end
+  end
 end
diff --git a/spec/models/protected_branch_spec.rb b/spec/models/protected_branch_spec.rb
index 7340ce50cede6b7d2392a3d5bea34b40e061ccf6..0835666a101267c8a2adc28c3950d7f2f196aade 100644
--- a/spec/models/protected_branch_spec.rb
+++ b/spec/models/protected_branch_spec.rb
@@ -44,7 +44,7 @@ describe ProtectedBranch do
     let(:branch) { create(:protected_branch) }
 
     it 'commits itself to its project' do
-      branch.project.should_receive(:commit).with(branch.name)
+      branch.project.repository.should_receive(:commit).with(branch.name)
       branch.commit
     end
   end
diff --git a/spec/models/repository_spec.rb b/spec/models/repository_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..71f9b964e70a012e5af52ddae02bcfebcaf9af11
--- /dev/null
+++ b/spec/models/repository_spec.rb
@@ -0,0 +1,105 @@
+require "spec_helper"
+
+describe Repository do
+  let(:project) { create(:project) }
+  let(:repository) { project.repository }
+
+  describe "Respond to" do
+    subject { repository }
+
+    it { should respond_to(:repo) }
+    it { should respond_to(:tree) }
+    it { should respond_to(:root_ref) }
+    it { should respond_to(:tags) }
+    it { should respond_to(:commit) }
+    it { should respond_to(:commits) }
+    it { should respond_to(:commits_between) }
+    it { should respond_to(:commits_with_refs) }
+    it { should respond_to(:commits_since) }
+    it { should respond_to(:commits_between) }
+  end
+
+
+  describe "#discover_default_branch" do
+    let(:master) { 'master' }
+    let(:stable) { 'stable' }
+
+    it "returns 'master' when master exists" do
+      repository.should_receive(:branch_names).at_least(:once).and_return([stable, master])
+      repository.discover_default_branch.should == 'master'
+    end
+
+    it "returns non-master when master exists but default branch is set to something else" do
+      repository.root_ref = 'stable'
+      repository.should_receive(:branch_names).at_least(:once).and_return([stable, master])
+      repository.discover_default_branch.should == 'stable'
+    end
+
+    it "returns a non-master branch when only one exists" do
+      repository.should_receive(:branch_names).at_least(:once).and_return([stable])
+      repository.discover_default_branch.should == 'stable'
+    end
+
+    it "returns nil when no branch exists" do
+      repository.should_receive(:branch_names).at_least(:once).and_return([])
+      repository.discover_default_branch.should be_nil
+    end
+  end
+
+  describe :commit do
+    it "should return first head commit if without params" do
+      repository.commit.id.should == repository.repo.commits.first.id
+    end
+
+    it "should return valid commit" do
+      repository.commit(ValidCommit::ID).should be_valid_commit
+    end
+
+    it "should return nil" do
+      repository.commit("+123_4532530XYZ").should be_nil
+    end
+  end
+
+  describe :tree do
+    before do
+      @commit = repository.commit(ValidCommit::ID)
+    end
+
+    it "should raise error w/o arguments" do
+      lambda { repository.tree }.should raise_error
+    end
+
+    it "should return root tree for commit" do
+      tree = repository.tree(@commit)
+      tree.contents.size.should == ValidCommit::FILES_COUNT
+      tree.contents.map(&:name).should == ValidCommit::FILES
+    end
+
+    it "should return root tree for commit with correct path" do
+      tree = repository.tree(@commit, ValidCommit::C_FILE_PATH)
+      tree.contents.map(&:name).should == ValidCommit::C_FILES
+    end
+
+    it "should return root tree for commit with incorrect path" do
+      repository.tree(@commit, "invalid_path").should be_nil
+    end
+  end
+
+  describe "fresh commits" do
+    it { repository.fresh_commits(3).count.should == 3 }
+    it { repository.fresh_commits.first.id.should == "bcf03b5de6c33f3869ef70d68cf06e679d1d7f9a" }
+    it { repository.fresh_commits.last.id.should == "f403da73f5e62794a0447aca879360494b08f678" }
+  end
+
+  describe "commits_between" do
+    subject do
+      commits = repository.commits_between("3a4b4fb4cde7809f033822a171b9feae19d41fff",
+                                        "8470d70da67355c9c009e4401746b1d5410af2e3")
+      commits.map { |c| c.id }
+    end
+
+    it { should have(3).elements }
+    it { should include("f0f14c8eaba69ebddd766498a9d0b0e79becd633") }
+    it { should_not include("bcf03b5de6c33f3869ef70d68cf06e679d1d7f9a") }
+  end
+end
diff --git a/spec/models/system_hook_spec.rb b/spec/models/system_hook_spec.rb
index 7ae483a4003c6caecc5cd6420a9358041b9db6de..cc358a2ed3b84306aa394effca35dfa0037f95e1 100644
--- a/spec/models/system_hook_spec.rb
+++ b/spec/models/system_hook_spec.rb
@@ -56,7 +56,7 @@ describe SystemHook do
       user = create(:user)
       project = create(:project)
       with_resque do
-        project.add_access(user, :admin)
+        project.team << [user, :master]
       end
       WebMock.should have_requested(:post, @system_hook.url).with(body: /user_add_to_team/).once
     end
@@ -64,7 +64,7 @@ describe SystemHook do
     it "project_destroy hook" do
       user = create(:user)
       project = create(:project)
-      project.add_access(user, :admin)
+      project.team << [user, :master]
       with_resque do
         project.users_projects.clear
       end
diff --git a/spec/models/team_spec.rb b/spec/models/team_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..65ffe13b490c651f75d792e4fc483718a23afbcd
--- /dev/null
+++ b/spec/models/team_spec.rb
@@ -0,0 +1,18 @@
+require "spec_helper"
+
+describe Team do
+  let(:team) { create(:project).team }
+
+  describe "Respond to" do
+    subject { team }
+
+    it { should respond_to(:developers) }
+    it { should respond_to(:masters) }
+    it { should respond_to(:reporters) }
+    it { should respond_to(:guests) }
+    it { should respond_to(:repository_writers) }
+    it { should respond_to(:repository_masters) }
+    it { should respond_to(:repository_readers) }
+  end
+end
+
diff --git a/spec/models/users_project_spec.rb b/spec/models/users_project_spec.rb
index f85e21ff3f1392e900b736c1bcf17988ed6c4566..e8f5b647ce04dd412acda238c8a0a9e0128bb6ea 100644
--- a/spec/models/users_project_spec.rb
+++ b/spec/models/users_project_spec.rb
@@ -48,10 +48,10 @@ describe UsersProject do
       @user_1 = create :user
       @user_2 = create :user
 
-      @project_1.add_access @user_1, :write
-      @project_2.add_access @user_2, :read
+      @project_1.team << [ @user_1, :developer ]
+      @project_2.team << [ @user_2, :reporter ]
 
-      @status = UsersProject.import_team(@project_1, @project_2)
+      @status = @project_2.team.import(@project_1)
     end
 
     it { @status.should be_true }
@@ -101,8 +101,8 @@ describe UsersProject do
       @user_1 = create :user
       @user_2 = create :user
 
-      @project_1.add_access @user_1, :write
-      @project_2.add_access @user_2, :read
+      @project_1.team << [ @user_1, :developer]
+      @project_2.team << [ @user_2, :reporter]
 
       UsersProject.truncate_teams([@project_1.id, @project_2.id])
     end
diff --git a/spec/requests/api/issues_spec.rb b/spec/requests/api/issues_spec.rb
index 8f4e51f5a446fa25a691b68e7f862357d46d9915..781ebab026bcc7f9a4645673e6e7b149158fb4eb 100644
--- a/spec/requests/api/issues_spec.rb
+++ b/spec/requests/api/issues_spec.rb
@@ -6,7 +6,7 @@ describe Gitlab::API do
   let(:user) { create(:user) }
   let!(:project) { create(:project, namespace: user.namespace ) }
   let!(:issue) { create(:issue, author: user, assignee: user, project: project) }
-  before { project.add_access(user, :read) }
+  before { project.team << [user, :reporter] }
 
   describe "GET /issues" do
     context "when unauthenticated" do
diff --git a/spec/requests/api/merge_requests_spec.rb b/spec/requests/api/merge_requests_spec.rb
index f7b067070e030d16b17e5cf499ff36fc56f0d6e3..5da54154a81aab0e406c177f366e585b2a760beb 100644
--- a/spec/requests/api/merge_requests_spec.rb
+++ b/spec/requests/api/merge_requests_spec.rb
@@ -6,7 +6,7 @@ describe Gitlab::API do
   let(:user) { create(:user ) }
   let!(:project) { create(:project, namespace: user.namespace ) }
   let!(:merge_request) { create(:merge_request, author: user, assignee: user, project: project, title: "Test") }
-  before { project.add_access(user, :read) }
+  before { project.team << [user, :reporters] }
 
   describe "GET /projects/:id/merge_requests" do
     context "when unauthenticated" do
diff --git a/spec/requests/api/milestones_spec.rb b/spec/requests/api/milestones_spec.rb
index f7df90d0fdd9d221cb5f399fd5933d50519ed002..8069667146241a3b41b48401e52524024eed03d0 100644
--- a/spec/requests/api/milestones_spec.rb
+++ b/spec/requests/api/milestones_spec.rb
@@ -7,7 +7,7 @@ describe Gitlab::API do
   let!(:project) { create(:project, namespace: user.namespace ) }
   let!(:milestone) { create(:milestone, project: project) }
 
-  before { project.add_access(user, :read) }
+  before { project.team << [user, :developer] }
 
   describe "GET /projects/:id/milestones" do
     it "should return project milestones" do
diff --git a/spec/requests/api/notes_spec.rb b/spec/requests/api/notes_spec.rb
index e783ccf73a54e2264bfcceb8f08a754770098603..ae4fc111f636edea2174453b8601d43a171eb6c0 100644
--- a/spec/requests/api/notes_spec.rb
+++ b/spec/requests/api/notes_spec.rb
@@ -10,7 +10,7 @@ describe Gitlab::API do
   let!(:issue_note) { create(:note, noteable: issue, project: project, author: user) }
   let!(:snippet_note) { create(:note, noteable: snippet, project: project, author: user) }
   let!(:wall_note) { create(:note, project: project, author: user) }
-  before { project.add_access(user, :read) }
+  before { project.team << [user, :reporter] }
 
   describe "GET /projects/:id/notes" do
     context "when unauthenticated" do
diff --git a/spec/requests/api/projects_spec.rb b/spec/requests/api/projects_spec.rb
index e829c95e9675d63fe81c1ad78ba69d9806628f00..c2244210bcf29da26c977e2a06dda8b91516d989 100644
--- a/spec/requests/api/projects_spec.rb
+++ b/spec/requests/api/projects_spec.rb
@@ -11,7 +11,7 @@ describe Gitlab::API do
   let!(:snippet) { create(:snippet, author: user, project: project, title: 'example') }
   let!(:users_project) { create(:users_project, user: user, project: project, project_access: UsersProject::MASTER) }
   let!(:users_project2) { create(:users_project, user: user3, project: project, project_access: UsersProject::DEVELOPER) }
-  before { project.add_access(user, :read) }
+  before { project.team << [user, :reporter] }
 
   describe "GET /projects" do
     context "when unauthenticated" do
@@ -226,14 +226,14 @@ describe Gitlab::API do
 
   describe "GET /projects/:id/repository/commits" do
     context "authorized user" do
-      before { project.add_access(user2, :read) }
+      before { project.team << [user2, :reporter] }
 
       it "should return project commits" do
         get api("/projects/#{project.id}/repository/commits", user)
         response.status.should == 200
 
         json_response.should be_an Array
-        json_response.first['id'].should == project.commit.id
+        json_response.first['id'].should == project.repository.commit.id
       end
     end
 
diff --git a/spec/requests/atom/issues_spec.rb b/spec/requests/atom/issues_spec.rb
index eeb355377c43c3865142a8bcbf45693efe121b75..0488c1f2266da9ded1408092ea43e8fe0601901a 100644
--- a/spec/requests/atom/issues_spec.rb
+++ b/spec/requests/atom/issues_spec.rb
@@ -6,7 +6,7 @@ describe "Issues Feed" do
     let!(:project)  { create(:project, namespace: user.namespace) }
     let!(:issue)    { create(:issue, author: user, project: project) }
 
-    before { project.add_access(user, :read, :write) }
+    before { project.team << [user, :developer] }
 
     context "when authenticated" do
       it "should render atom feed" do
diff --git a/spec/requests/gitlab_flavored_markdown_spec.rb b/spec/requests/gitlab_flavored_markdown_spec.rb
index 7f61c6aaa73dd20d68b9f388bf876544bb7570a9..78b8c0c513f376f02f07bb9ce7177bc184990af5 100644
--- a/spec/requests/gitlab_flavored_markdown_spec.rb
+++ b/spec/requests/gitlab_flavored_markdown_spec.rb
@@ -6,7 +6,7 @@ describe "Gitlab Flavored Markdown" do
   let(:merge_request) { create(:merge_request, project: project) }
   let(:fred) do
       u = create(:user, name: "fred")
-      project.add_access(u, :admin)
+      project.team << [u, :master]
       u
   end
 
@@ -33,11 +33,11 @@ describe "Gitlab Flavored Markdown" do
     project.repo.gc_auto
   end
 
-  let(:commit) { project.commits(@branch_name).first }
+  let(:commit) { project.repository.commits(@branch_name).first }
 
   before do
     login_as :user
-    project.add_access(@user, :read, :write)
+    project.team << [@user, :developer]
   end
 
   describe "for commits" do
diff --git a/spec/requests/issues_spec.rb b/spec/requests/issues_spec.rb
index 0814108523ba71503728565656e7ee9ff15bb1d4..2e94ffd0020f9350e219d3cc7f225914a89d428a 100644
--- a/spec/requests/issues_spec.rb
+++ b/spec/requests/issues_spec.rb
@@ -7,8 +7,7 @@ describe "Issues" do
     login_as :user
     user2 = create(:user)
 
-    project.add_access(@user, :read, :write)
-    project.add_access(user2, :read, :write)
+    project.team << [[@user, user2], :developer]
   end
 
   describe "Edit issue" do
diff --git a/spec/requests/projects_deploy_keys_spec.rb b/spec/requests/projects_deploy_keys_spec.rb
index 35323f556f90a9876ab0d0262e2c75ceed1dfaf7..25b1da9ebd8c9fa46d26a43993d40ec5c3a00f1d 100644
--- a/spec/requests/projects_deploy_keys_spec.rb
+++ b/spec/requests/projects_deploy_keys_spec.rb
@@ -5,7 +5,7 @@ describe "Projects", "DeployKeys" do
 
   before do
     login_as :user
-    project.add_access(@user, :read, :write, :admin)
+    project.team << [@user, :master]
   end
 
   describe "GET /keys" do
diff --git a/spec/requests/projects_spec.rb b/spec/requests/projects_spec.rb
index ea87e35ed94a81b69a7bc0aae2bbf5764d3b22f6..8f613b458c04077f63edb3b98db7001cfdd260d1 100644
--- a/spec/requests/projects_spec.rb
+++ b/spec/requests/projects_spec.rb
@@ -6,7 +6,7 @@ describe "Projects" do
   describe "GET /projects/show" do
     before do
       @project = create(:project, namespace: @user.namespace)
-      @project.add_access(@user, :read)
+      @project.team << [@user, :reporter]
 
       visit project_path(@project)
     end
@@ -19,7 +19,7 @@ describe "Projects" do
   describe "GET /projects/:id/edit" do
     before do
       @project = create(:project)
-      @project.add_access(@user, :admin, :read)
+      @project.team << [@user, :master]
 
       visit edit_project_path(@project)
     end
@@ -38,7 +38,7 @@ describe "Projects" do
   describe "PUT /projects/:id" do
     before do
       @project = create(:project, namespace: @user.namespace)
-      @project.add_access(@user, :admin, :read)
+      @project.team << [@user, :master]
 
       visit edit_project_path(@project)
 
@@ -59,7 +59,7 @@ describe "Projects" do
   describe "DELETE /projects/:id" do
     before do
       @project = create(:project, namespace: @user.namespace)
-      @project.add_access(@user, :read, :admin)
+      @project.team << [@user, :master]
       visit edit_project_path(@project)
     end
 
diff --git a/spec/requests/search_spec.rb b/spec/requests/search_spec.rb
index 17cc0d39946d56652c329b97cbe71a5193530db5..e338f359f888d51b2d381e4a82e6df516b0f8885 100644
--- a/spec/requests/search_spec.rb
+++ b/spec/requests/search_spec.rb
@@ -4,7 +4,7 @@ describe "Search" do
   before do
     login_as :user
     @project = create(:project)
-    @project.add_access(@user, :read)
+    @project.team << [@user, :reporter]
     visit search_path
     fill_in "search", with: @project.name[0..3]
     click_button "Search"
diff --git a/spec/requests/security/project_access_spec.rb b/spec/requests/security/project_access_spec.rb
index 060a276b7405987f5dd9ebccc86519fefde6164a..a35175102ec49bbc9991d886cc261566845b3b2b 100644
--- a/spec/requests/security/project_access_spec.rb
+++ b/spec/requests/security/project_access_spec.rb
@@ -22,10 +22,10 @@ describe "Application access" do
 
     before do
       # full access
-      project.users_projects.create(user: master, project_access: UsersProject::MASTER)
+      project.team << [master, :master]
 
       # readonly
-      project.users_projects.create(user: reporter, project_access: UsersProject::REPORTER)
+      project.team << [reporter, :reporter]
     end
 
     describe "GET /project_code" do
@@ -40,7 +40,7 @@ describe "Application access" do
     end
 
     describe "GET /project_code/tree/master" do
-      subject { project_tree_path(project, project.root_ref) }
+      subject { project_tree_path(project, project.repository.root_ref) }
 
       it { should be_allowed_for master }
       it { should be_allowed_for reporter }
@@ -51,7 +51,7 @@ describe "Application access" do
     end
 
     describe "GET /project_code/commits/master" do
-      subject { project_commits_path(project, project.root_ref, limit: 1) }
+      subject { project_commits_path(project, project.repository.root_ref, limit: 1) }
 
       it { should be_allowed_for master }
       it { should be_allowed_for reporter }
@@ -62,7 +62,7 @@ describe "Application access" do
     end
 
     describe "GET /project_code/commit/:sha" do
-      subject { project_commit_path(project, project.commit) }
+      subject { project_commit_path(project, project.repository.commit) }
 
       it { should be_allowed_for master }
       it { should be_allowed_for reporter }
@@ -107,7 +107,7 @@ describe "Application access" do
 
     describe "GET /project_code/blob" do
       before do
-        commit = project.commit
+        commit = project.repository.commit
         path = commit.tree.contents.select { |i| i.is_a?(Grit::Blob)}.first.name
         @blob_path = project_blob_path(project, File.join(commit.id, path))
       end
diff --git a/spec/requests/snippets_spec.rb b/spec/requests/snippets_spec.rb
index b231b940a84bfd778db6512e04b382b62b308126..770e34dc07cae6ca723f6ec9b09f3e1d70a8ee73 100644
--- a/spec/requests/snippets_spec.rb
+++ b/spec/requests/snippets_spec.rb
@@ -5,7 +5,7 @@ describe "Snippets" do
 
   before do
     login_as :user
-    project.add_access(@user, :read, :write)
+    project.team << [@user, :developer]
   end
 
   describe "GET /snippets" do
@@ -26,7 +26,7 @@ describe "Snippets" do
       before do
         # admin access to remove snippet
         @user.users_projects.destroy_all
-        project.add_access(@user, :read, :write, :admin)
+        project.team << [@user, :master]
         visit edit_project_snippet_path(project, @snippet)
       end
 
diff --git a/spec/support/stubbed_repository.rb b/spec/support/stubbed_repository.rb
index ad88dd77a4f33e816892d623ceb8df6b6c449ac3..e6e194d70f556b49933093795165988f455cb962 100644
--- a/spec/support/stubbed_repository.rb
+++ b/spec/support/stubbed_repository.rb
@@ -1,15 +1,14 @@
+require "repository"
+require "project"
+
 # Stubs out all Git repository access done by models so that specs can run
 # against fake repositories without Grit complaining that they don't exist.
 class Project
-  def path_to_repo
-    if new_record? || path == 'newproject'
-      # There are a couple Project specs and features that expect the Project's
-      # path to be in the returned path, so let's patronize them.
-      Rails.root.join('tmp', 'repositories', path)
+  def repository
+    if path == "empty" || !path
+      nil
     else
-      # For everything else, just give it the path to one of our real seeded
-      # repos.
-      Rails.root.join('tmp', 'repositories', 'gitlabhq')
+      GitLabTestRepo.new(path_with_namespace)
     end
   end
 
@@ -27,3 +26,9 @@ class Project
     end
   end
 end
+
+class GitLabTestRepo < Repository
+  def repo
+    @repo ||= Grit::Repo.new(Rails.root.join('tmp', 'repositories', 'gitlabhq'))
+  end
+end