diff --git a/Gemfile b/Gemfile
index c74d2f54c201f0e8439d9f30eea0b2775dcb348d..5b45b8bdcc2b5ea52c3025ab4db581451ab6ebab 100644
--- a/Gemfile
+++ b/Gemfile
@@ -8,7 +8,7 @@ def linux_only(require_as)
   RUBY_PLATFORM.include?('linux') && require_as
 end
 
-gem "rails", "~> 4.0.0"
+gem "rails", "~> 4.1.0"
 
 gem "protected_attributes"
 gem 'rails-observers'
@@ -207,7 +207,7 @@ group :development, :test do
   gem 'factory_girl_rails'
 
   # Prevent occasions where minitest is not bundled in packaged versions of ruby (see #3826)
-  gem 'minitest', '~> 4.7.0'
+  gem 'minitest', '~> 5.3.0'
 
   # Generate Fake data
   gem "ffaker"
@@ -224,7 +224,7 @@ group :development, :test do
   # PhantomJS driver for Capybara
   gem 'poltergeist', '~> 1.5.1'
 
-  gem 'jasmine', '2.0.0.rc5'
+  gem 'jasmine', '2.0.2'
 
   gem "spring", '1.1.1'
   gem "spring-commands-rspec", '1.0.1'
diff --git a/Gemfile.lock b/Gemfile.lock
index 7a72d3c3e82a952668a3c0591eec829993190874..5124863692ad7b86b58a6bcf7642f4dc931d6024 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -2,37 +2,39 @@ GEM
   remote: https://rubygems.org/
   specs:
     ace-rails-ap (2.0.1)
-    actionmailer (4.0.5)
-      actionpack (= 4.0.5)
+    actionmailer (4.1.1)
+      actionpack (= 4.1.1)
+      actionview (= 4.1.1)
       mail (~> 2.5.4)
-    actionpack (4.0.5)
-      activesupport (= 4.0.5)
-      builder (~> 3.1.0)
-      erubis (~> 2.7.0)
+    actionpack (4.1.1)
+      actionview (= 4.1.1)
+      activesupport (= 4.1.1)
       rack (~> 1.5.2)
       rack-test (~> 0.6.2)
-    activemodel (4.0.5)
-      activesupport (= 4.0.5)
-      builder (~> 3.1.0)
-    activerecord (4.0.5)
-      activemodel (= 4.0.5)
-      activerecord-deprecated_finders (~> 1.0.2)
-      activesupport (= 4.0.5)
-      arel (~> 4.0.0)
-    activerecord-deprecated_finders (1.0.3)
-    activesupport (4.0.5)
+    actionview (4.1.1)
+      activesupport (= 4.1.1)
+      builder (~> 3.1)
+      erubis (~> 2.7.0)
+    activemodel (4.1.1)
+      activesupport (= 4.1.1)
+      builder (~> 3.1)
+    activerecord (4.1.1)
+      activemodel (= 4.1.1)
+      activesupport (= 4.1.1)
+      arel (~> 5.0.0)
+    activesupport (4.1.1)
       i18n (~> 0.6, >= 0.6.9)
-      minitest (~> 4.2)
-      multi_json (~> 1.3)
+      json (~> 1.7, >= 1.7.7)
+      minitest (~> 5.1)
       thread_safe (~> 0.1)
-      tzinfo (~> 0.3.37)
+      tzinfo (~> 1.1)
     acts-as-taggable-on (2.4.1)
       rails (>= 3, < 5)
     addressable (2.3.5)
     annotate (2.6.0)
       activerecord (>= 2.3.0)
       rake (>= 0.8.7)
-    arel (4.0.2)
+    arel (5.0.1.20140414130214)
     asciidoctor (0.1.4)
     awesome_print (1.2.0)
     axiom-types (0.0.5)
@@ -46,7 +48,7 @@ GEM
       debug_inspector (>= 0.0.1)
     bootstrap-sass (3.0.3.0)
       sass (~> 3.2)
-    builder (3.1.4)
+    builder (3.2.2)
     capybara (2.2.1)
       mime-types (>= 1.16)
       nokogiri (>= 1.3.3)
@@ -223,13 +225,13 @@ GEM
     guard-spinach (0.0.2)
       guard (>= 1.1)
       spinach
-    haml (4.0.4)
+    haml (4.0.5)
       tilt
-    haml-rails (0.5.1)
-      actionpack (~> 4.0.0)
-      activesupport (~> 4.0.0)
+    haml-rails (0.5.3)
+      actionpack (>= 4.0.1)
+      activesupport (>= 4.0.1)
       haml (>= 3.1, < 5.0)
-      railties (~> 4.0.0)
+      railties (>= 4.0.1)
     hashie (2.0.5)
     hike (1.2.3)
     hipchat (0.14.0)
@@ -242,12 +244,12 @@ GEM
     httpauth (0.2.0)
     i18n (0.6.9)
     ice_nine (0.10.0)
-    jasmine (2.0.0.rc5)
-      jasmine-core (~> 2.0.0.rc5)
+    jasmine (2.0.2)
+      jasmine-core (~> 2.0.0)
       phantomjs
       rack (>= 1.2.1)
       rake
-    jasmine-core (2.0.0.rc5)
+    jasmine-core (2.0.0)
     jquery-atwho-rails (0.3.3)
     jquery-rails (3.1.0)
       railties (>= 3.0, < 5.0)
@@ -282,11 +284,11 @@ GEM
     method_source (0.8.2)
     mime-types (1.25.1)
     mini_portile (0.6.0)
-    minitest (4.7.5)
+    minitest (5.3.4)
     multi_json (1.10.1)
     multi_xml (0.5.5)
     multipart-post (1.2.0)
-    mysql2 (0.3.11)
+    mysql2 (0.3.16)
     net-ldap (0.3.1)
     net-scp (1.1.2)
       net-ssh (>= 2.6.5)
@@ -355,14 +357,16 @@ GEM
       rack
     rack-test (0.6.2)
       rack (>= 1.0)
-    rails (4.0.5)
-      actionmailer (= 4.0.5)
-      actionpack (= 4.0.5)
-      activerecord (= 4.0.5)
-      activesupport (= 4.0.5)
+    rails (4.1.1)
+      actionmailer (= 4.1.1)
+      actionpack (= 4.1.1)
+      actionview (= 4.1.1)
+      activemodel (= 4.1.1)
+      activerecord (= 4.1.1)
+      activesupport (= 4.1.1)
       bundler (>= 1.3.0, < 2.0)
-      railties (= 4.0.5)
-      sprockets-rails (~> 2.0.0)
+      railties (= 4.1.1)
+      sprockets-rails (~> 2.0)
     rails-observers (0.1.2)
       activemodel (~> 4.0)
     rails_best_practices (1.14.4)
@@ -374,13 +378,13 @@ GEM
       i18n
       require_all
       ruby-progressbar
-    railties (4.0.5)
-      actionpack (= 4.0.5)
-      activesupport (= 4.0.5)
+    railties (4.1.1)
+      actionpack (= 4.1.1)
+      activesupport (= 4.1.1)
       rake (>= 0.8.7)
       thor (>= 0.18.1, < 2.0)
     raindrops (0.12.0)
-    rake (10.3.1)
+    rake (10.3.2)
     raphael-rails (2.1.2)
     rb-fsevent (0.9.3)
     rb-inotify (0.9.2)
@@ -443,9 +447,9 @@ GEM
     sdoc (0.3.20)
       json (>= 1.1.3)
       rdoc (~> 3.10)
-    seed-fu (2.3.0)
-      activerecord (>= 3.1, < 4.1)
-      activesupport (>= 3.1, < 4.1)
+    seed-fu (2.3.1)
+      activerecord (>= 3.1, < 4.2)
+      activesupport (>= 3.1, < 4.2)
     select2-rails (3.5.2)
       thor (~> 0.14)
     settingslogic (2.0.9)
@@ -491,7 +495,7 @@ GEM
       multi_json (~> 1.0)
       rack (~> 1.0)
       tilt (~> 1.1, != 1.3.0)
-    sprockets-rails (2.0.1)
+    sprockets-rails (2.1.3)
       actionpack (>= 3.0)
       activesupport (>= 3.0)
       sprockets (~> 2.8)
@@ -510,7 +514,7 @@ GEM
       eventmachine (>= 1.0.0)
       rack (>= 1.0.0)
     thor (0.19.1)
-    thread_safe (0.3.3)
+    thread_safe (0.3.4)
     tilt (1.4.1)
     timers (1.1.0)
     tinder (1.9.3)
@@ -532,7 +536,8 @@ GEM
       eventmachine (>= 0.12.8)
       http_parser.rb (~> 0.5.1)
       simple_oauth (~> 0.1.4)
-    tzinfo (0.3.39)
+    tzinfo (1.2.0)
+      thread_safe (~> 0.1)
     uglifier (2.3.2)
       execjs (>= 0.3.0)
       json (>= 1.8.0)
@@ -612,7 +617,7 @@ DEPENDENCIES
   haml-rails
   hipchat (~> 0.14.0)
   httparty
-  jasmine (= 2.0.0.rc5)
+  jasmine (= 2.0.2)
   jquery-atwho-rails (~> 0.3.3)
   jquery-rails
   jquery-scrollto-rails
@@ -621,7 +626,7 @@ DEPENDENCIES
   kaminari (~> 0.15.1)
   launchy
   letter_opener
-  minitest (~> 4.7.0)
+  minitest (~> 5.3.0)
   mysql2
   nprogress-rails
   omniauth (~> 1.1.3)
@@ -637,7 +642,7 @@ DEPENDENCIES
   rack-attack
   rack-cors
   rack-mini-profiler
-  rails (~> 4.0.0)
+  rails (~> 4.1.0)
   rails-observers
   rails_best_practices
   raphael-rails (~> 2.1.2)
diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb
index b9af36a0c7eb32700144d5043c658891fb7eb48f..9e14af620481c0d91850f9abdd93029b55ccd364 100644
--- a/app/controllers/projects_controller.rb
+++ b/app/controllers/projects_controller.rb
@@ -211,6 +211,6 @@ class ProjectsController < ApplicationController
   end
 
   def sorted(users)
-    users.uniq.compact.sort_by(&:username).map { |user| { username: user.username, name: user.name } }
+    users.uniq.to_a.compact.sort_by(&:username).map { |user| { username: user.username, name: user.name } }
   end
 end
diff --git a/app/controllers/snippets_controller.rb b/app/controllers/snippets_controller.rb
index 0dd941a48e27a7e4aed1b652de4877b01163c805..4fe98f804dce60677ec0037ecb3c166f103569bf 100644
--- a/app/controllers/snippets_controller.rb
+++ b/app/controllers/snippets_controller.rb
@@ -14,7 +14,7 @@ class SnippetsController < ApplicationController
   layout 'navless'
 
   def index
-    @snippets = Snippet.public.fresh.non_expired.page(params[:page]).per(20)
+    @snippets = Snippet.are_public.fresh.non_expired.page(params[:page]).per(20)
   end
 
   def user_index
@@ -26,15 +26,15 @@ class SnippetsController < ApplicationController
 
     if @user == current_user
       @snippets = case params[:scope]
-                  when 'public' then
-                    @snippets.public
-                  when 'private' then
-                    @snippets.private
+                  when 'are_public' then
+                    @snippets.are_public
+                  when 'are_private' then
+                    @snippets.are_private
                   else
                     @snippets
                   end
     else
-      @snippets = @snippets.public
+      @snippets = @snippets.are_public
     end
 
     @snippets = @snippets.page(params[:page]).per(20)
diff --git a/app/models/snippet.rb b/app/models/snippet.rb
index 720accd73dc512ef526a5535adfc7f4a7cc452c6..9e4409daa1a9d7c5bfba4ed5dc3310bbadd480f6 100644
--- a/app/models/snippet.rb
+++ b/app/models/snippet.rb
@@ -34,8 +34,8 @@ class Snippet < ActiveRecord::Base
   validates :content, presence: true
 
   # Scopes
-  scope :public,  -> { where(private: false) }
-  scope :private, -> { where(private: true) }
+  scope :are_public,  -> { where(private: false) }
+  scope :are_private, -> { where(private: true) }
   scope :fresh,   -> { order("created_at DESC") }
   scope :expired, -> { where(["expires_at IS NOT NULL AND expires_at < ?", Time.current]) }
   scope :non_expired, -> { where(["expires_at IS NULL OR expires_at > ?", Time.current]) }
diff --git a/app/views/snippets/current_user_index.html.haml b/app/views/snippets/current_user_index.html.haml
index 90ddc7198f6dfe3d38c79babb2eb29ea003ce4c4..e3edd85698374357d17e3b04afcc449cf904e528 100644
--- a/app/views/snippets/current_user_index.html.haml
+++ b/app/views/snippets/current_user_index.html.haml
@@ -18,16 +18,16 @@
           All
           %span.pull-right
             = @user.snippets.count
-      = nav_tab :scope, 'private' do
-        = link_to user_snippets_path(@user, scope: 'private') do
+      = nav_tab :scope, 'are_private' do
+        = link_to user_snippets_path(@user, scope: 'are_private') do
           Private
           %span.pull-right
-            = @user.snippets.private.count
-      = nav_tab :scope, 'public' do
-        = link_to user_snippets_path(@user, scope: 'public') do
+            = @user.snippets.are_private.count
+      = nav_tab :scope, 'are_public' do
+        = link_to user_snippets_path(@user, scope: 'are_public') do
           Public
           %span.pull-right
-            = @user.snippets.public.count
+            = @user.snippets.are_public.count
 
   .col-md-9.my-snippets
     = render 'snippets'
diff --git a/config/environments/production.rb b/config/environments/production.rb
index 47f7e17aeb6e73800bdda9abd6ee75a359c6f60d..2450d5719eb2d221d5db1cc614317fa9050bd2ee 100644
--- a/config/environments/production.rb
+++ b/config/environments/production.rb
@@ -74,10 +74,6 @@ Gitlab::Application.configure do
   # Send deprecation notices to registered listeners
   config.active_support.deprecation = :notify
 
-  # Log the query plan for queries taking more than this (works
-  # with SQLite, MySQL, and PostgreSQL)
-  # config.active_record.auto_explain_threshold_in_seconds = 0.5
-
   config.action_mailer.delivery_method = :sendmail
   # Defaults to:
   # # config.action_mailer.sendmail_settings = {
diff --git a/config/initializers/acts_as_taggable_on_patch.rb b/config/initializers/acts_as_taggable_on_patch.rb
new file mode 100644
index 0000000000000000000000000000000000000000..baa77fde392b45754d5d94bf17079d63124125ba
--- /dev/null
+++ b/config/initializers/acts_as_taggable_on_patch.rb
@@ -0,0 +1,130 @@
+# This is a patch to address the issue in https://github.com/mbleigh/acts-as-taggable-on/issues/427 caused by
+# https://github.com/rails/rails/commit/31a43ebc107fbd50e7e62567e5208a05909ec76c
+# gem 'acts-as-taggable-on' has the fix included https://github.com/mbleigh/acts-as-taggable-on/commit/89bbed3864a9252276fb8dd7d535fce280454b90
+# but not in the currently used version of gem ('2.4.1')
+# With replacement of 'acts-as-taggable-on' gem this file will become obsolete
+
+module ActsAsTaggableOn::Taggable
+  module Core
+    module ClassMethods
+      def tagged_with(tags, options = {})
+        tag_list = ActsAsTaggableOn::TagList.from(tags)
+        empty_result = where("1 = 0")
+
+        return empty_result if tag_list.empty?
+
+        joins = []
+        conditions = []
+        having = []
+        select_clause = []
+
+        context = options.delete(:on)
+        owned_by = options.delete(:owned_by)
+        alias_base_name = undecorated_table_name.gsub('.','_')
+        quote = ActsAsTaggableOn::Tag.using_postgresql? ? '"' : ''
+
+        if options.delete(:exclude)
+          if options.delete(:wild)
+            tags_conditions = tag_list.map { |t| sanitize_sql(["#{ActsAsTaggableOn::Tag.table_name}.name #{like_operator} ? ESCAPE '!'", "%#{escape_like(t)}%"]) }.join(" OR ")
+          else
+            tags_conditions = tag_list.map { |t| sanitize_sql(["#{ActsAsTaggableOn::Tag.table_name}.name #{like_operator} ?", t]) }.join(" OR ")
+          end
+
+          conditions << "#{table_name}.#{primary_key} NOT IN (SELECT #{ActsAsTaggableOn::Tagging.table_name}.taggable_id FROM #{ActsAsTaggableOn::Tagging.table_name} JOIN #{ActsAsTaggableOn::Tag.table_name} ON #{ActsAsTaggableOn::Tagging.table_name}.tag_id = #{ActsAsTaggableOn::Tag.table_name}.#{ActsAsTaggableOn::Tag.primary_key} AND (#{tags_conditions}) WHERE #{ActsAsTaggableOn::Tagging.table_name}.taggable_type = #{quote_value(base_class.name, nil)})"
+
+          if owned_by
+            joins <<  "JOIN #{ActsAsTaggableOn::Tagging.table_name}" +
+                      "  ON #{ActsAsTaggableOn::Tagging.table_name}.taggable_id = #{quote}#{table_name}#{quote}.#{primary_key}" +
+                      " AND #{ActsAsTaggableOn::Tagging.table_name}.taggable_type = #{quote_value(base_class.name, nil)}" +
+                      " AND #{ActsAsTaggableOn::Tagging.table_name}.tagger_id = #{owned_by.id}" +
+                      " AND #{ActsAsTaggableOn::Tagging.table_name}.tagger_type = #{quote_value(owned_by.class.base_class.to_s, nil)}"
+          end
+
+        elsif options.delete(:any)
+          # get tags, drop out if nothing returned (we need at least one)
+          tags = if options.delete(:wild)
+            ActsAsTaggableOn::Tag.named_like_any(tag_list)
+          else
+            ActsAsTaggableOn::Tag.named_any(tag_list)
+          end
+
+          return empty_result unless tags.length > 0
+
+          # setup taggings alias so we can chain, ex: items_locations_taggings_awesome_cool_123
+          # avoid ambiguous column name
+          taggings_context = context ? "_#{context}" : ''
+
+          taggings_alias   = adjust_taggings_alias(
+            "#{alias_base_name[0..4]}#{taggings_context[0..6]}_taggings_#{sha_prefix(tags.map(&:name).join('_'))}"
+          )
+
+          tagging_join  = "JOIN #{ActsAsTaggableOn::Tagging.table_name} #{taggings_alias}" +
+                          "  ON #{taggings_alias}.taggable_id = #{quote}#{table_name}#{quote}.#{primary_key}" +
+                          " AND #{taggings_alias}.taggable_type = #{quote_value(base_class.name, nil)}"
+          tagging_join << " AND " + sanitize_sql(["#{taggings_alias}.context = ?", context.to_s]) if context
+
+          # don't need to sanitize sql, map all ids and join with OR logic
+          conditions << tags.map { |t| "#{taggings_alias}.tag_id = #{t.id}" }.join(" OR ")
+          select_clause = "DISTINCT #{table_name}.*" unless context and tag_types.one?
+
+          if owned_by
+              tagging_join << " AND " +
+                  sanitize_sql([
+                      "#{taggings_alias}.tagger_id = ? AND #{taggings_alias}.tagger_type = ?",
+                      owned_by.id,
+                      owned_by.class.base_class.to_s
+                  ])
+          end
+
+          joins << tagging_join
+        else
+          tags = ActsAsTaggableOn::Tag.named_any(tag_list)
+
+          return empty_result unless tags.length == tag_list.length
+
+          tags.each do |tag|
+            taggings_alias = adjust_taggings_alias("#{alias_base_name[0..11]}_taggings_#{sha_prefix(tag.name)}")
+            tagging_join  = "JOIN #{ActsAsTaggableOn::Tagging.table_name} #{taggings_alias}" +
+                            "  ON #{taggings_alias}.taggable_id = #{quote}#{table_name}#{quote}.#{primary_key}" +
+                            " AND #{taggings_alias}.taggable_type = #{quote_value(base_class.name, nil)}" +
+                            " AND #{taggings_alias}.tag_id = #{tag.id}"
+
+            tagging_join << " AND " + sanitize_sql(["#{taggings_alias}.context = ?", context.to_s]) if context
+
+            if owned_by
+                tagging_join << " AND " +
+                  sanitize_sql([
+                    "#{taggings_alias}.tagger_id = ? AND #{taggings_alias}.tagger_type = ?",
+                    owned_by.id,
+                    owned_by.class.base_class.to_s
+                  ])
+            end
+
+            joins << tagging_join
+          end
+        end
+
+        taggings_alias, tags_alias = adjust_taggings_alias("#{alias_base_name}_taggings_group"), "#{alias_base_name}_tags_group"
+
+        if options.delete(:match_all)
+          joins << "LEFT OUTER JOIN #{ActsAsTaggableOn::Tagging.table_name} #{taggings_alias}" +
+                   "  ON #{taggings_alias}.taggable_id = #{quote}#{table_name}#{quote}.#{primary_key}" +
+                   " AND #{taggings_alias}.taggable_type = #{quote_value(base_class.name, nil)}"
+
+
+          group_columns = ActsAsTaggableOn::Tag.using_postgresql? ? grouped_column_names_for(self) : "#{table_name}.#{primary_key}"
+          group = group_columns
+          having = "COUNT(#{taggings_alias}.taggable_id) = #{tags.size}"
+        end
+
+        select(select_clause) \
+          .joins(joins.join(" ")) \
+          .where(conditions.join(" AND ")) \
+          .group(group) \
+          .having(having) \
+          .order(options[:order]) \
+          .readonly(false)
+      end
+    end
+  end
+end
diff --git a/config/initializers/state_machine_patch.rb b/config/initializers/state_machine_patch.rb
new file mode 100644
index 0000000000000000000000000000000000000000..72d010fa5deab3f48285ad4ab07f1793f6d9c3a2
--- /dev/null
+++ b/config/initializers/state_machine_patch.rb
@@ -0,0 +1,9 @@
+# This is a patch to address the issue in https://github.com/pluginaweek/state_machine/issues/251
+# where gem 'state_machine' was not working for Rails 4.1
+module StateMachine
+  module Integrations
+    module ActiveModel
+      public :around_validation
+    end
+  end
+end
diff --git a/spec/helpers/submodule_helper_spec.rb b/spec/helpers/submodule_helper_spec.rb
index 20378b1b17dbd947f52b140371ab757b078ff209..41c9f038c266a5adeefa55cbdb75f77a675593a3 100644
--- a/spec/helpers/submodule_helper_spec.rb
+++ b/spec/helpers/submodule_helper_spec.rb
@@ -16,7 +16,8 @@ describe SubmoduleHelper do
       end
 
       it 'should detect ssh on standard port' do
-        Gitlab.config.gitlab.stub(ssh_port: 22) # set this just to be sure
+        Gitlab.config.gitlab_shell.stub(ssh_port: 22) # set this just to be sure
+        Gitlab.config.gitlab_shell.stub(ssh_path_prefix: Settings.send(:build_gitlab_shell_ssh_path_prefix))
         stub_url([ config.user, '@', config.host, ':gitlab-org/gitlab-ce.git' ].join(''))
         submodule_links(submodule_item).should == [ project_path('gitlab-org/gitlab-ce'), project_tree_path('gitlab-org/gitlab-ce', 'hash') ]
       end
diff --git a/spec/models/system_hook_spec.rb b/spec/models/system_hook_spec.rb
index 73144397301be83865ca3e3f07cca8ef7f18215e..47d6d861d70ed862218f25199d0fadf0e19a7977 100644
--- a/spec/models/system_hook_spec.rb
+++ b/spec/models/system_hook_spec.rb
@@ -59,7 +59,7 @@ describe SystemHook do
       user = create(:user)
       project = create(:project)
       project.team << [user, :master]
-      project.users_projects.clear
+      project.users_projects.destroy_all
       WebMock.should have_requested(:post, @system_hook.url).with(body: /user_remove_from_team/).once
     end
   end