diff --git a/CHANGELOG b/CHANGELOG
index 235a99b43270fb8c1491c8d733e39eddceed0932..8d01bc4d890ce03cf83e7646b321cc81c5cd0e5b 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -32,6 +32,8 @@ v 7.8.0
   - Disable blacklist validation for project names
   - Allow configuring protection of the default branch upon first push (Marco Wessel)
   -
+  - Add gitlab.com importer
+  - Add an ability to login with gitlab.com
   - 
   - Add a commit calendar to the user profile (Hannes Rosenögger)  
   - 
diff --git a/Gemfile b/Gemfile
index 8eede269e2d278bd95051366dde7541eacab147d..9676d3c85d21011818632826dea5a10045ad7082 100644
--- a/Gemfile
+++ b/Gemfile
@@ -29,6 +29,7 @@ gem 'omniauth-twitter'
 gem 'omniauth-github'
 gem 'omniauth-shibboleth'
 gem 'omniauth-kerberos'
+gem 'omniauth-gitlab'
 gem 'doorkeeper', '2.1.0'
 gem "rack-oauth2", "~> 1.0.5"
 
diff --git a/Gemfile.lock b/Gemfile.lock
index 7f115d79de02729d3ec7f590cdba2dbd57e7e312..6d2d281e4768acf6079696b381ab277faaf28525 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -332,6 +332,9 @@ GEM
     omniauth-github (1.1.1)
       omniauth (~> 1.0)
       omniauth-oauth2 (~> 1.1)
+    omniauth-gitlab (1.0.0)
+      omniauth (~> 1.0)
+      omniauth-oauth2 (~> 1.0)
     omniauth-google-oauth2 (0.2.5)
       omniauth (> 1.0)
       omniauth-oauth2 (~> 1.1)
@@ -689,6 +692,7 @@ DEPENDENCIES
   octokit (= 3.7.0)
   omniauth (~> 1.1.3)
   omniauth-github
+  omniauth-gitlab
   omniauth-google-oauth2
   omniauth-kerberos
   omniauth-shibboleth
diff --git a/app/assets/images/authbuttons/gitlab_32.png b/app/assets/images/authbuttons/gitlab_32.png
new file mode 100644
index 0000000000000000000000000000000000000000..f3b78cb6efba1e8cff625fd262b36705dd707c93
Binary files /dev/null and b/app/assets/images/authbuttons/gitlab_32.png differ
diff --git a/app/assets/images/authbuttons/gitlab_64.png b/app/assets/images/authbuttons/gitlab_64.png
new file mode 100644
index 0000000000000000000000000000000000000000..ff2945fe89eddf03e2e1fc8deb39a6a7bc5bc088
Binary files /dev/null and b/app/assets/images/authbuttons/gitlab_64.png differ
diff --git a/app/assets/javascripts/importer_status.js.coffee b/app/assets/javascripts/importer_status.js.coffee
new file mode 100644
index 0000000000000000000000000000000000000000..268efd7c832555b1d27bb87d5419f092bbddaf82
--- /dev/null
+++ b/app/assets/javascripts/importer_status.js.coffee
@@ -0,0 +1,31 @@
+class @ImporterStatus
+  constructor: (@jobs_url, @import_url) ->
+    this.initStatusPage()
+    this.setAutoUpdate()
+
+  initStatusPage: ->
+    $(".btn-add-to-import").click (event) =>
+      new_namespace = null
+      tr = $(event.currentTarget).closest("tr")
+      id = tr.attr("id").replace("repo_", "")
+      if tr.find(".import-target input").length > 0
+        new_namespace = tr.find(".import-target input").prop("value")
+        tr.find(".import-target").empty().append(new_namespace + "/" + tr.find(".import-target").data("project_name"))
+      $.post @import_url, {repo_id: id, new_namespace: new_namespace}, dataType: 'script'
+  
+  setAutoUpdate: ->
+    setInterval (=>
+      $.get @jobs_url, (data) =>
+        $.each data, (i, job) =>
+          job_item = $("#project_" + job.id)
+          status_field = job_item.find(".job-status")
+          
+          if job.import_status == 'finished'
+            job_item.removeClass("active").addClass("success")
+            status_field.html('<span class="cgreen"><i class="fa fa-check"></i> done</span>')
+          else if job.import_status == 'started'
+            status_field.html("<i class='fa fa-spinner fa-spin'></i> started")
+          else
+            status_field.html(job.import_status)
+          
+    ), 4000
\ No newline at end of file
diff --git a/app/controllers/import/base_controller.rb b/app/controllers/import/base_controller.rb
new file mode 100644
index 0000000000000000000000000000000000000000..4df171dbcfea2ffaf7ab2d6ec721eb7056a58037
--- /dev/null
+++ b/app/controllers/import/base_controller.rb
@@ -0,0 +1,21 @@
+class Import::BaseController < ApplicationController
+
+  private
+
+  def get_or_create_namespace
+    existing_namespace = Namespace.find_by("path = ? OR name = ?", @target_namespace, @target_namespace)
+
+    if existing_namespace
+      if existing_namespace.owner == current_user
+        namespace = existing_namespace
+      else
+        @already_been_taken = true
+        return false
+      end
+    else
+      namespace = Group.create(name: @target_namespace, path: @target_namespace, owner: current_user)
+      namespace.add_owner(current_user)
+      namespace
+    end
+  end
+end
diff --git a/app/controllers/github_imports_controller.rb b/app/controllers/import/github_controller.rb
similarity index 57%
rename from app/controllers/github_imports_controller.rb
rename to app/controllers/import/github_controller.rb
index b73e3f7ffac44f3ad16d5a39849735fef702f209..108fc4396a6069bda1d6f6e5ff0b647200340932 100644
--- a/app/controllers/github_imports_controller.rb
+++ b/app/controllers/import/github_controller.rb
@@ -1,4 +1,4 @@
-class GithubImportsController < ApplicationController
+class Import::GithubController < Import::BaseController
   before_filter :github_auth, except: :callback
 
   rescue_from Octokit::Unauthorized, with: :github_unauthorized
@@ -7,7 +7,7 @@ class GithubImportsController < ApplicationController
     token = client.auth_code.get_token(params[:code]).token
     current_user.github_access_token = token
     current_user.save
-    redirect_to status_github_import_url
+    redirect_to status_import_github_url
   end
 
   def status
@@ -19,7 +19,7 @@ class GithubImportsController < ApplicationController
     @already_added_projects = current_user.created_projects.where(import_type: "github")
     already_added_projects_names = @already_added_projects.pluck(:import_source)
 
-    @repos.reject!{|repo| already_added_projects_names.include? repo.full_name}
+    @repos.reject!{ |repo| already_added_projects_names.include? repo.full_name }
   end
 
   def jobs
@@ -30,30 +30,18 @@ class GithubImportsController < ApplicationController
   def create
     @repo_id = params[:repo_id].to_i
     repo = octo_client.repo(@repo_id)
-    target_namespace = params[:new_namespace].presence || repo.owner.login
-    existing_namespace = Namespace.find_by("path = ? OR name = ?", target_namespace, target_namespace)
+    @target_namespace = params[:new_namespace].presence || repo.owner.login
+    @project_name = repo.name
+    
+    namespace = get_or_create_namespace || (render and return)
 
-    if existing_namespace
-      if existing_namespace.owner == current_user
-        namespace = existing_namespace
-      else
-        @already_been_taken = true
-        @target_namespace = target_namespace
-        @project_name = repo.name
-        render and return
-      end
-    else
-      namespace = Group.create(name: target_namespace, path: target_namespace, owner: current_user)
-      namespace.add_owner(current_user)
-    end
-
-    @project = Gitlab::Github::ProjectCreator.new(repo, namespace, current_user).execute
+    @project = Gitlab::GithubImport::ProjectCreator.new(repo, namespace, current_user).execute
   end
 
   private
 
   def client
-    @client ||= Gitlab::Github::Client.new.client
+    @client ||= Gitlab::GithubImport::Client.new.client
   end
 
   def octo_client
@@ -69,7 +57,7 @@ class GithubImportsController < ApplicationController
 
   def go_to_github_for_permissions
     redirect_to client.auth_code.authorize_url({
-      redirect_uri: callback_github_import_url,
+      redirect_uri: callback_import_github_url,
       scope: "repo, user, user:email"
     })
   end
diff --git a/app/controllers/import/gitlab_controller.rb b/app/controllers/import/gitlab_controller.rb
new file mode 100644
index 0000000000000000000000000000000000000000..a51ea36aff8dce24be9b8d72d95a4626d3b09d8d
--- /dev/null
+++ b/app/controllers/import/gitlab_controller.rb
@@ -0,0 +1,57 @@
+class Import::GitlabController < Import::BaseController
+  before_filter :gitlab_auth, except: :callback
+
+  rescue_from OAuth2::Error, with: :gitlab_unauthorized
+
+  def callback
+    token = client.get_token(params[:code], callback_import_gitlab_url)
+    current_user.gitlab_access_token = token
+    current_user.save
+    redirect_to status_import_gitlab_url
+  end
+
+  def status
+    @repos = client.projects
+    
+    @already_added_projects = current_user.created_projects.where(import_type: "gitlab")
+    already_added_projects_names = @already_added_projects.pluck(:import_source)
+
+    @repos.to_a.reject!{ |repo| already_added_projects_names.include? repo["path_with_namespace"] }
+  end
+
+  def jobs
+    jobs = current_user.created_projects.where(import_type: "gitlab").to_json(only: [:id, :import_status])
+    render json: jobs
+  end
+
+  def create
+    @repo_id = params[:repo_id].to_i
+    repo = client.project(@repo_id)
+    @target_namespace = params[:new_namespace].presence || repo["namespace"]["path"]
+    @project_name = repo["name"]
+    
+    namespace = get_or_create_namespace || (render and return)
+
+    @project = Gitlab::GitlabImport::ProjectCreator.new(repo, namespace, current_user).execute
+  end
+
+  private
+
+  def client
+    @client ||= Gitlab::GitlabImport::Client.new(current_user.gitlab_access_token)
+  end
+
+  def gitlab_auth
+    if current_user.gitlab_access_token.blank?
+      go_to_gitlab_for_permissions
+    end
+  end
+
+  def go_to_gitlab_for_permissions
+    redirect_to client.authorize_url(callback_import_gitlab_url)
+  end
+
+  def gitlab_unauthorized
+    go_to_gitlab_for_permissions
+  end
+end
diff --git a/app/helpers/oauth_helper.rb b/app/helpers/oauth_helper.rb
index df18db71c84d7c1a88f9c18a2388355c693ab5bb..c7bc9307a58c31244a0ae618914b00d58126b4c3 100644
--- a/app/helpers/oauth_helper.rb
+++ b/app/helpers/oauth_helper.rb
@@ -4,7 +4,7 @@ module OauthHelper
   end
 
   def default_providers
-    [:twitter, :github, :google_oauth2, :ldap]
+    [:twitter, :github, :gitlab, :google_oauth2, :ldap]
   end
 
   def enabled_oauth_providers
@@ -13,7 +13,7 @@ module OauthHelper
 
   def enabled_social_providers
     enabled_oauth_providers.select do |name|
-      [:twitter, :github, :google_oauth2].include?(name.to_sym)
+      [:twitter, :gitlab, :github, :google_oauth2].include?(name.to_sym)
     end
   end
 
diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb
index 5cec6ae99d87d3223c4fd74de6c80b30b0d274e3..36463892ebf9f9d0fcd2558350291e9937140156 100644
--- a/app/helpers/projects_helper.rb
+++ b/app/helpers/projects_helper.rb
@@ -253,4 +253,8 @@ module ProjectsHelper
   def github_import_enabled?
     enabled_oauth_providers.include?(:github)
   end
+
+  def gitlab_import_enabled?
+    enabled_oauth_providers.include?(:gitlab)
+  end
 end
diff --git a/app/views/github_imports/status.html.haml b/app/views/github_imports/status.html.haml
deleted file mode 100644
index 52a1e16cd047543535afc6df2fba4c9da075f1b3..0000000000000000000000000000000000000000
--- a/app/views/github_imports/status.html.haml
+++ /dev/null
@@ -1,63 +0,0 @@
-%h3.page-title
-  %i.fa.fa-github
-  Import repositories from GitHub.com
-
-%p.light
-  Select projects you want to import.  
-
-%hr
-%table.table.import-jobs
-  %thead
-    %tr
-      %th From GitHub
-      %th To GitLab
-      %th Status
-  %tbody
-    - @already_added_projects.each do |project|
-      %tr{id: "project_#{project.id}", class: "#{project_status_css_class(project.import_status)}"}
-        %td= project.import_source
-        %td
-          %strong= link_to project.name_with_namespace, project
-        %td.job-status
-          - if project.import_status == 'finished'
-            %span.cgreen
-              %i.fa.fa-check
-              done
-          - else
-            = project.human_import_status_name
-
-    - @repos.each do |repo|
-      %tr{id: "repo_#{repo.id}"}
-        %td= repo.full_name
-        %td.import-target
-          = repo.full_name
-        %td.import-actions.job-status
-          = button_tag "Add", class: "btn btn-add-to-import"
-
-
-:coffeescript
-  $(".btn-add-to-import").click () ->
-    new_namespace = null
-    tr = $(this).closest("tr")
-    id = tr.attr("id").replace("repo_", "")
-    if tr.find(".import-target input").length > 0
-      new_namespace = tr.find(".import-target input").prop("value")
-      tr.find(".import-target").empty().append(new_namespace + "/" + tr.find(".import-target").data("project_name"))
-    $.post "#{github_import_url}", {repo_id: id, new_namespace: new_namespace}, dataType: 'script'
-  
-
-  setInterval (->
-    $.get "#{jobs_github_import_path}", (data)->
-      $.each data, (i, job) ->
-        job_item = $("#project_" + job.id)
-        status_field = job_item.find(".job-status")
-        
-        if job.import_status == 'finished'
-          job_item.removeClass("active").addClass("success")
-          status_field.html('<span class="cgreen"><i class="fa fa-check"></i> done</span>')
-        else if job.import_status == 'started'
-          status_field.html("<i class='fa fa-spinner fa-spin'></i> started")
-        else
-          status_field.html(job.import_status)
-        
-  ), 4000
diff --git a/app/views/github_imports/create.js.haml b/app/views/import/base/create.js.haml
similarity index 100%
rename from app/views/github_imports/create.js.haml
rename to app/views/import/base/create.js.haml
diff --git a/app/views/import/github/status.html.haml b/app/views/import/github/status.html.haml
new file mode 100644
index 0000000000000000000000000000000000000000..1676c3c26aed508c1fbcb2e82c70042ad9fd8107
--- /dev/null
+++ b/app/views/import/github/status.html.haml
@@ -0,0 +1,39 @@
+%h3.page-title
+  %i.fa.fa-github
+  Import repositories from GitHub.com
+
+%p.light
+  Select projects you want to import.  
+
+%hr
+%table.table.import-jobs
+  %thead
+    %tr
+      %th From GitHub
+      %th To GitLab
+      %th Status
+  %tbody
+    - @already_added_projects.each do |project|
+      %tr{id: "project_#{project.id}", class: "#{project_status_css_class(project.import_status)}"}
+        %td= project.import_source
+        %td
+          %strong= link_to project.path_with_namespace, project
+        %td.job-status
+          - if project.import_status == 'finished'
+            %span.cgreen
+              %i.fa.fa-check
+              done
+          - else
+            = project.human_import_status_name
+
+    - @repos.each do |repo|
+      %tr{id: "repo_#{repo.id}"}
+        %td= repo.full_name
+        %td.import-target
+          = repo.full_name
+        %td.import-actions.job-status
+          = button_tag "Add", class: "btn btn-add-to-import"
+
+:coffeescript
+  $ ->
+    new ImporterStatus("#{jobs_import_github_path}", "#{import_github_path}")
diff --git a/app/views/import/gitlab/status.html.haml b/app/views/import/gitlab/status.html.haml
new file mode 100644
index 0000000000000000000000000000000000000000..9aedacef04bc2d6bc96c2ad7f62bbe242d11a039
--- /dev/null
+++ b/app/views/import/gitlab/status.html.haml
@@ -0,0 +1,39 @@
+%h3.page-title
+  %i.fa.fa-github
+  Import repositories from GitLab.com
+
+%p.light
+  Select projects you want to import.  
+
+%hr
+%table.table.import-jobs
+  %thead
+    %tr
+      %th From GitLab.com
+      %th To GitLab private instance
+      %th Status
+  %tbody
+    - @already_added_projects.each do |project|
+      %tr{id: "project_#{project.id}", class: "#{project_status_css_class(project.import_status)}"}
+        %td= project.import_source
+        %td
+          %strong= link_to project.path_with_namespace, project
+        %td.job-status
+          - if project.import_status == 'finished'
+            %span.cgreen
+              %i.fa.fa-check
+              done
+          - else
+            = project.human_import_status_name
+
+    - @repos.each do |repo|
+      %tr{id: "repo_#{repo["id"]}"}
+        %td= repo["path_with_namespace"]
+        %td.import-target
+          = repo["path_with_namespace"]
+        %td.import-actions.job-status
+          = button_tag "Add", class: "btn btn-add-to-import"
+
+:coffeescript
+  $ -> 
+    new ImporterStatus("#{jobs_import_gitlab_path}", "#{import_gitlab_url}")
diff --git a/app/views/projects/_github_import_modal.html.haml b/app/views/projects/_github_import_modal.html.haml
index 02c9ef45f2b37625909a11b4f0469e232455ca9d..99325e66119a67a8f22a82bf230d44369d8d30fa 100644
--- a/app/views/projects/_github_import_modal.html.haml
+++ b/app/views/projects/_github_import_modal.html.haml
@@ -6,17 +6,4 @@
         %h3 GitHub OAuth import
       .modal-body
         You need to setup integration with GitHub first.
-        = link_to 'How to setup integration with GitHub', 'https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/integration/github.md'
-
-
-:javascript
-  $(function(){
-    var import_modal = $('#github_import_modal').modal({modal: true, show:false});
-    $('.how_to_import_link').bind("click", function(e){
-      e.preventDefault();
-      import_modal.show();
-    });
-    $('.modal-header .close').bind("click", function(){
-      import_modal.hide();
-    })
-  })
+        = link_to 'How to setup integration with GitHub', 'https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/integration/github.md'
\ No newline at end of file
diff --git a/app/views/projects/_gitlab_import_modal.html.haml b/app/views/projects/_gitlab_import_modal.html.haml
new file mode 100644
index 0000000000000000000000000000000000000000..e7503f023b13b8fd187ef3a5f63a54a9cb821f33
--- /dev/null
+++ b/app/views/projects/_gitlab_import_modal.html.haml
@@ -0,0 +1,9 @@
+%div#gitlab_import_modal.modal.hide
+  .modal-dialog
+    .modal-content
+      .modal-header
+        %a.close{href: "#", "data-dismiss" => "modal"} ×
+        %h3 GitLab OAuth import
+      .modal-body
+        You need to setup integration with GitLab first.
+        = link_to 'How to setup integration with GitLab', 'https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/integration/gitlab.md'
\ No newline at end of file
diff --git a/app/views/projects/new.html.haml b/app/views/projects/new.html.haml
index 3e0f9cbd80b1785f79212f93482c5f7f48484ab4..61f6a66c386cd07eca2690d130e528643fa8d3f5 100644
--- a/app/views/projects/new.html.haml
+++ b/app/views/projects/new.html.haml
@@ -44,7 +44,7 @@
         .col-sm-2
         .col-sm-10
           - if github_import_enabled?
-            = link_to status_github_import_path do
+            = link_to status_import_github_path do
               %i.fa.fa-github
               Import projects from GitHub
           - else
@@ -52,6 +52,19 @@
               %i.fa.fa-github
               Import projects from GitHub
             = render 'github_import_modal'
+      
+      .project-import.form-group
+        .col-sm-2
+        .col-sm-10
+          - if gitlab_import_enabled?
+            = link_to status_import_gitlab_path do
+              %i.fa.fa-heart
+              Import projects from GitLab.com
+          - else
+            = link_to '#', class: 'how_to_import_link light' do
+              %i.fa.fa-heart
+              Import projects from GitLab.com
+            = render 'gitlab_import_modal'
 
       %hr.prepend-botton-10
 
@@ -79,3 +92,11 @@
       %i.fa.fa-spinner.fa-spin
       Creating project &amp; repository.
     %p Please wait a moment, this page will automatically refresh when ready.
+
+:coffeescript
+  $ ->
+    $('.how_to_import_link').bind 'click', (e) ->
+      e.preventDefault()
+      import_modal = $(this).parent().find(".modal").show()
+    $('.modal-header .close').bind 'click', ->
+      $(".modal").hide()
\ No newline at end of file
diff --git a/app/workers/repository_import_worker.rb b/app/workers/repository_import_worker.rb
index 0bcc42bc62c8d9781556814b503841552eab4950..5f9970d3795a4fe2eba22bb8a73547035976c545 100644
--- a/app/workers/repository_import_worker.rb
+++ b/app/workers/repository_import_worker.rb
@@ -10,11 +10,13 @@ class RepositoryImportWorker
                                project.path_with_namespace,
                                project.import_url)
 
-    if project.import_type == 'github'
-      result_of_data_import = Gitlab::Github::Importer.new(project).execute
-    else
-      result_of_data_import = true
-    end
+    result_of_data_import = if project.import_type == 'github'
+                              Gitlab::GithubImport::Importer.new(project).execute
+                            elsif project.import_type == 'gitlab'
+                              Gitlab::GitlabImport::Importer.new(project).execute
+                            else
+                              true
+                            end
 
     if result && result_of_data_import
       project.import_finish
diff --git a/config/initializers/doorkeeper.rb b/config/initializers/doorkeeper.rb
index e9b843e29b4b2e44544a3012b3efa497c2f204f2..9da7ebf4290df3f7a04f44c96480018332ba536c 100644
--- a/config/initializers/doorkeeper.rb
+++ b/config/initializers/doorkeeper.rb
@@ -27,7 +27,7 @@ Doorkeeper.configure do
 
   # Access token expiration time (default 2 hours).
   # If you want to disable expiration, set this to nil.
-  # access_token_expires_in 2.hours
+  access_token_expires_in nil
 
   # Reuse access token for the same resource owner within an application (disabled by default)
   # Rationale: https://github.com/doorkeeper-gem/doorkeeper/issues/383
diff --git a/config/routes.rb b/config/routes.rb
index f0abd876ecda998d3d8b0efff67eb2a860a129f8..3aadb732e6d0a6cf98c634e707d485d4081275f9 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -51,14 +51,25 @@ Gitlab::Application.routes.draw do
   end
   get '/s/:username' => 'snippets#user_index', as: :user_snippets, constraints: { username: /.*/ }
 
+  
   #
-  # Github importer area
+  # Import
   #
-  resource :github_import, only: [:create, :new] do
-    get :status
-    get :callback
-    get :jobs
+  namespace :import do
+    resource :github, only: [:create, :new], controller: :github do
+      get :status
+      get :callback
+      get :jobs
+    end
+
+    resource :gitlab, only: [:create, :new], controller: :gitlab do
+      get :status
+      get :callback
+      get :jobs
+    end
   end
+  
+  
 
   #
   # Explore area
diff --git a/doc/integration/gitlab.md b/doc/integration/gitlab.md
new file mode 100644
index 0000000000000000000000000000000000000000..b3b1d897225c20137f9bb46208cd2eadfab06736
--- /dev/null
+++ b/doc/integration/gitlab.md
@@ -0,0 +1,54 @@
+# GitLab OAuth2 OmniAuth Provider
+
+To enable the GitLab OmniAuth provider you must register your application with GitLab. GitLab will generate a client ID and secret key for you to use.
+
+1.  Sign in to GitLab.
+
+1.  Navigate to your settings.
+
+1.  Select "Applications" in the left menu.
+
+1.  Select "New application".
+
+1.  Provide the required details.
+    - Name: This can be anything. Consider something like "\<Organization\>'s GitLab" or "\<Your Name\>'s GitLab" or something else descriptive.
+    - Redirect URI: 
+    
+    ```
+    http://gitlab.example.com/import/gitlab/callback
+    http://gitlab.example.com/users/auth/gitlab/callback
+    ```
+
+    The first link is required for the importer and second for the authorization. 
+
+1.  Select "Submit".
+
+1.  You should now see a Application ID and Secret. Keep this page open as you continue configuration.
+
+1.  On your GitLab server, open the configuration file.
+
+    ```sh
+    cd /home/git/gitlab
+
+    sudo -u git -H editor config/gitlab.yml
+    ```
+
+1.  Find the section dealing with OmniAuth. See [Initial OmniAuth Configuration](README.md#initial-omniauth-configuration) for more details.
+
+1.  Under `providers:` uncomment (or add) lines that look like the following:
+
+    ```
+        - { name: 'gitlab', app_id: 'YOUR APP ID',
+          app_secret: 'YOUR APP SECRET',
+          args: { scope: 'api' } }
+    ```
+
+1.  Change 'YOUR APP ID' to the Application ID from the GitLab application page.
+
+1.  Change 'YOUR APP SECRET' to the secret from the GitLab application page.
+
+1.  Save the configuration file.
+
+1.  Restart GitLab for the changes to take effect.
+
+On the sign in page there should now be a GitLab icon below the regular sign in form. Click the icon to begin the authentication process. GitLab will ask the user to sign in and authorize the GitLab application. If everything goes well the user will be returned to your GitLab instance and will be signed in.
diff --git a/lib/gitlab/github/client.rb b/lib/gitlab/github_import/client.rb
similarity index 82%
rename from lib/gitlab/github/client.rb
rename to lib/gitlab/github_import/client.rb
index d6b936c649c74ca33e4ed2edc0926fe4835e6944..cf43d36c6c383fdb3e2f1ccea21ef3a3672ad614 100644
--- a/lib/gitlab/github/client.rb
+++ b/lib/gitlab/github_import/client.rb
@@ -1,5 +1,5 @@
 module Gitlab
-  module Github
+  module GithubImport
     class Client
       attr_reader :client
 
@@ -14,7 +14,7 @@ module Gitlab
       private
 
       def config
-        Gitlab.config.omniauth.providers.select{|provider| provider.name == "github"}.first
+        Gitlab.config.omniauth.providers.find{|provider| provider.name == "github"}
       end
 
       def github_options
diff --git a/lib/gitlab/github/importer.rb b/lib/gitlab/github_import/importer.rb
similarity index 71%
rename from lib/gitlab/github/importer.rb
rename to lib/gitlab/github_import/importer.rb
index 9f0fc6c4471d4474b5f0ef82a371c017d0a4f153..1f02ee49b6a359a08c0ceebe230271b96050950c 100644
--- a/lib/gitlab/github/importer.rb
+++ b/lib/gitlab/github_import/importer.rb
@@ -1,10 +1,11 @@
 module Gitlab
-  module Github
+  module GithubImport
     class Importer
       attr_reader :project
 
       def initialize(project)
         @project = project
+        @formatter = Gitlab::ImportFormatter.new
       end
 
       def execute
@@ -13,12 +14,14 @@ module Gitlab
         #Issues && Comments
         client.list_issues(project.import_source, state: :all).each do |issue|
           if issue.pull_request.nil?
-            body = "*Created by: #{issue.user.login}*\n\n#{issue.body}"
+
+            body = @formatter.author_line(issue.user.login, issue.body)
 
             if issue.comments > 0
-              body += "\n\n\n**Imported comments:**\n"
+              body += @formatter.comments_header
+
               client.issue_comments(project.import_source, issue.number).each do |c|
-                body += "\n\n*By #{c.user.login} on #{c.created_at}*\n\n#{c.body}"
+                body += @formatter.comment_to_md(c.user.login, c.created_at, c.body)
               end
             end
 
@@ -40,7 +43,8 @@ module Gitlab
       end
 
       def gl_user_id(project, github_id)
-        user = User.joins(:identities).find_by("identities.extern_uid = ?", github_id.to_s)
+        user = User.joins(:identities).
+          find_by("identities.extern_uid = ? AND identities.provider = 'github'", github_id.to_s)
         (user && user.id) || project.creator_id
       end
     end
diff --git a/lib/gitlab/github/project_creator.rb b/lib/gitlab/github_import/project_creator.rb
similarity index 97%
rename from lib/gitlab/github/project_creator.rb
rename to lib/gitlab/github_import/project_creator.rb
index 7b04926071f6180d67233f23e8463dd5c7b1e263..9439ca6cbf4803f12a50dcf416f519b32026a37d 100644
--- a/lib/gitlab/github/project_creator.rb
+++ b/lib/gitlab/github_import/project_creator.rb
@@ -1,5 +1,5 @@
 module Gitlab
-  module Github
+  module GithubImport
     class ProjectCreator
       attr_reader :repo, :namespace, :current_user
 
diff --git a/lib/gitlab/gitlab_import/client.rb b/lib/gitlab/gitlab_import/client.rb
new file mode 100644
index 0000000000000000000000000000000000000000..2206b68da99200147b5e22e643525c7b0fa14b4b
--- /dev/null
+++ b/lib/gitlab/gitlab_import/client.rb
@@ -0,0 +1,82 @@
+module Gitlab
+  module GitlabImport
+    class Client
+      attr_reader :client, :api
+
+      PER_PAGE = 100
+
+      def initialize(access_token)
+        @client = ::OAuth2::Client.new(
+          config.app_id,
+          config.app_secret,
+          github_options
+        )
+
+        if access_token
+          @api = OAuth2::AccessToken.from_hash(@client, access_token: access_token)
+        end
+      end
+
+      def authorize_url(redirect_uri)
+        client.auth_code.authorize_url({
+          redirect_uri: redirect_uri,
+          scope: "api"
+        })
+      end
+
+      def get_token(code, redirect_uri)
+        client.auth_code.get_token(code, redirect_uri: redirect_uri).token
+      end
+
+      def issues(project_identifier)
+        lazy_page_iterator(PER_PAGE) do |page|
+          api.get("/api/v3/projects/#{project_identifier}/issues?per_page=#{PER_PAGE}&page=#{page}").parsed
+        end
+      end
+
+      def issue_comments(project_identifier, issue_id)
+        lazy_page_iterator(PER_PAGE) do |page|
+          api.get("/api/v3/projects/#{project_identifier}/issues/#{issue_id}/notes?per_page=#{PER_PAGE}&page=#{page}").parsed
+        end
+      end
+
+      def project(id)
+        api.get("/api/v3/projects/#{id}").parsed
+      end
+
+      def projects
+        lazy_page_iterator(PER_PAGE) do |page|
+          api.get("/api/v3/projects?per_page=#{PER_PAGE}&page=#{page}").parsed
+        end
+      end
+
+      private
+
+      def lazy_page_iterator(per_page)
+        Enumerator.new do |y|
+          page = 1
+          loop do
+            items = yield(page)
+            items.each do |item|
+              y << item
+            end
+            break if items.empty? || items.size < per_page
+            page += 1
+          end
+        end
+      end
+
+      def config
+        Gitlab.config.omniauth.providers.find{|provider| provider.name == "gitlab"}
+      end
+
+      def github_options
+        {
+          site: 'https://gitlab.com/',
+          authorize_url: 'oauth/authorize',
+          token_url: 'oauth/token'
+        }
+      end
+    end
+  end
+end
diff --git a/lib/gitlab/gitlab_import/importer.rb b/lib/gitlab/gitlab_import/importer.rb
new file mode 100644
index 0000000000000000000000000000000000000000..5f9b14399a450136ea7849f32f49eb5f4f2e8b8e
--- /dev/null
+++ b/lib/gitlab/gitlab_import/importer.rb
@@ -0,0 +1,50 @@
+module Gitlab
+  module GitlabImport
+    class Importer
+      attr_reader :project, :client
+
+      def initialize(project)
+        @project = project
+        @client = Client.new(project.creator.gitlab_access_token)
+        @formatter = Gitlab::ImportFormatter.new
+      end
+
+      def execute
+        project_identifier = URI.encode(project.import_source, '/')
+
+        #Issues && Comments
+        issues = client.issues(project_identifier)
+        
+        issues.each do |issue|
+          body = @formatter.author_line(issue["author"]["name"], issue["description"])
+          
+          comments = client.issue_comments(project_identifier, issue["id"])
+          
+          if comments.any?
+            body += @formatter.comments_header
+          end
+
+          comments.each do |comment|
+            body += @formatter.comment_to_md(comment["author"]["name"], comment["created_at"], comment["body"])
+          end
+
+          project.issues.create!(
+            description: body, 
+            title: issue["title"],
+            state: issue["state"],
+            author_id: gl_user_id(project, issue["author"]["id"])
+          )
+        end
+        
+        true
+      end
+
+      private
+
+      def gl_user_id(project, gitlab_id)
+        user = User.joins(:identities).find_by("identities.extern_uid = ? AND identities.provider = 'gitlab'", gitlab_id.to_s)
+        (user && user.id) || project.creator_id
+      end
+    end
+  end
+end
diff --git a/lib/gitlab/gitlab_import/project_creator.rb b/lib/gitlab/gitlab_import/project_creator.rb
new file mode 100644
index 0000000000000000000000000000000000000000..6424d56f8f1b41ab5f0c88bf0e3ffbc8afb049c2
--- /dev/null
+++ b/lib/gitlab/gitlab_import/project_creator.rb
@@ -0,0 +1,39 @@
+module Gitlab
+  module GitlabImport
+    class ProjectCreator
+      attr_reader :repo, :namespace, :current_user
+
+      def initialize(repo, namespace, current_user)
+        @repo = repo
+        @namespace = namespace
+        @current_user = current_user
+      end
+
+      def execute
+        @project = Project.new(
+          name: repo["name"],
+          path: repo["path"],
+          description: repo["description"],
+          namespace: namespace,
+          creator: current_user,
+          visibility_level: repo["visibility_level"],
+          import_type: "gitlab",
+          import_source: repo["path_with_namespace"],
+          import_url: repo["http_url_to_repo"].sub("://", "://oauth2:#{current_user.gitlab_access_token}@")
+        )
+
+        if @project.save!
+          @project.reload
+
+          if @project.import_failed?
+            @project.import_retry
+          else
+            @project.import_start
+          end
+        end
+
+        @project
+      end
+    end
+  end
+end
diff --git a/lib/gitlab/import_formatter.rb b/lib/gitlab/import_formatter.rb
new file mode 100644
index 0000000000000000000000000000000000000000..ebb4b87f7e33a5d907af5c23d40a4754a3c4bdc1
--- /dev/null
+++ b/lib/gitlab/import_formatter.rb
@@ -0,0 +1,15 @@
+module Gitlab
+  class ImportFormatter
+    def comment_to_md(author, date, body)
+      "\n\n*By #{author} on #{date}*\n\n#{body}"
+    end
+
+    def comments_header
+      "\n\n\n**Imported comments:**\n"
+    end
+
+    def author_line(author, body)
+      "*Created by: #{author}*\n\n#{body}"
+    end
+  end
+end
diff --git a/spec/controllers/github_imports_controller_spec.rb b/spec/controllers/import/github_controller_spec.rb
similarity index 85%
rename from spec/controllers/github_imports_controller_spec.rb
rename to spec/controllers/import/github_controller_spec.rb
index 26e7854fea3a9fc5fc5ad0f95d75f44ff94987a9..010635677333549e185db3bd9ca908ca39bce465 100644
--- a/spec/controllers/github_imports_controller_spec.rb
+++ b/spec/controllers/import/github_controller_spec.rb
@@ -1,6 +1,6 @@
 require 'spec_helper'
 
-describe GithubImportsController do
+describe Import::GithubController do
   let(:user) { create(:user, github_access_token: 'asd123') }
 
   before do
@@ -10,13 +10,13 @@ describe GithubImportsController do
   describe "GET callback" do
     it "updates access token" do
       token = "asdasd12345"
-      Gitlab::Github::Client.any_instance.stub_chain(:client, :auth_code, :get_token, :token).and_return(token)
+      Gitlab::GithubImport::Client.any_instance.stub_chain(:client, :auth_code, :get_token, :token).and_return(token)
       Gitlab.config.omniauth.providers << OpenStruct.new(app_id: "asd123", app_secret: "asd123", name: "github")
 
       get :callback
       
       user.reload.github_access_token.should == token
-      controller.should redirect_to(status_github_import_url)
+      controller.should redirect_to(status_import_github_url)
     end
   end
 
@@ -55,7 +55,7 @@ describe GithubImportsController do
 
     it "takes already existing namespace" do
       namespace = create(:namespace, name: "john", owner: user)
-      Gitlab::Github::ProjectCreator.should_receive(:new).with(@repo, namespace, user).
+      Gitlab::GithubImport::ProjectCreator.should_receive(:new).with(@repo, namespace, user).
         and_return(double(execute: true))
       controller.stub_chain(:octo_client, :repo).and_return(@repo)
 
diff --git a/spec/controllers/import/gitlab_controller_spec.rb b/spec/controllers/import/gitlab_controller_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..36995091c690211d4163b9349a119df0d6077ebf
--- /dev/null
+++ b/spec/controllers/import/gitlab_controller_spec.rb
@@ -0,0 +1,68 @@
+require 'spec_helper'
+
+describe Import::GitlabController do
+  let(:user) { create(:user, gitlab_access_token: 'asd123') }
+
+  before do
+    sign_in(user)
+  end
+
+  describe "GET callback" do
+    it "updates access token" do
+      token = "asdasd12345"
+      Gitlab::GitlabImport::Client.any_instance.stub_chain(:client, :auth_code, :get_token, :token).and_return(token)
+      Gitlab.config.omniauth.providers << OpenStruct.new(app_id: "asd123", app_secret: "asd123", name: "gitlab")
+
+      get :callback
+      
+      user.reload.gitlab_access_token.should == token
+      controller.should redirect_to(status_import_gitlab_url)
+    end
+  end
+
+  describe "GET status" do
+    before do
+      @repo = OpenStruct.new(path: 'vim', path_with_namespace: 'asd/vim')
+    end
+
+    it "assigns variables" do
+      @project = create(:project, import_type: 'gitlab', creator_id: user.id)
+      controller.stub_chain(:client, :projects).and_return([@repo])
+      
+      get :status
+
+      expect(assigns(:already_added_projects)).to eq([@project])
+      expect(assigns(:repos)).to eq([@repo])
+    end
+
+    it "does not show already added project" do
+      @project = create(:project, import_type: 'gitlab', creator_id: user.id, import_source: 'asd/vim')
+      controller.stub_chain(:client, :projects).and_return([@repo])
+      
+      get :status
+
+      expect(assigns(:already_added_projects)).to eq([@project])
+      expect(assigns(:repos)).to eq([])
+    end
+  end
+
+  describe "POST create" do
+    before do
+      @repo = {
+        path: 'vim',
+        path_with_namespace: 'asd/vim',
+        owner: {name: "john"},
+        namespace: {path: "john"}
+      }.with_indifferent_access
+    end
+
+    it "takes already existing namespace" do
+      namespace = create(:namespace, name: "john", owner: user)
+      Gitlab::GitlabImport::ProjectCreator.should_receive(:new).with(@repo, namespace, user).
+        and_return(double(execute: true))
+      controller.stub_chain(:client, :project).and_return(@repo)
+
+      post :create, format: :js
+    end
+  end
+end
diff --git a/spec/lib/gitlab/gitlab_import/project_creator.rb b/spec/lib/gitlab/gitlab_import/project_creator.rb
new file mode 100644
index 0000000000000000000000000000000000000000..51f3534ed600fa56afbbe3b81f8349d85eadce97
--- /dev/null
+++ b/spec/lib/gitlab/gitlab_import/project_creator.rb
@@ -0,0 +1,25 @@
+require 'spec_helper'
+
+describe Gitlab::GitlabImport::ProjectCreator do
+  let(:user) { create(:user, gitlab_access_token: "asdffg") }
+  let(:repo) {{
+    name: 'vim',
+    path: 'vim',
+    visibility_level: Gitlab::VisibilityLevel::PRIVATE,
+    path_with_namespace: 'asd/vim',
+    http_url_to_repo: "https://gitlab.com/asd/vim.git",
+    owner: {name: "john"}}.with_indifferent_access
+  }
+  let(:namespace){ create(:namespace) }
+
+  it 'creates project' do
+    Project.any_instance.stub(:add_import_job)
+    
+    project_creator = Gitlab::GitlabImport::ProjectCreator.new(repo, namespace, user)
+    project_creator.execute
+    project = Project.last
+    
+    project.import_url.should ==  "https://oauth2:asdffg@gitlab.com/asd/vim.git"
+    project.visibility_level.should == Gitlab::VisibilityLevel::PRIVATE
+  end
+end