diff --git a/CHANGELOG b/CHANGELOG
index 4095ac48782f88cec1e6974b4b30ba3af7840d46..3971b924277610527b33ac6095506767b702e9d2 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -21,6 +21,7 @@ v 7.13.0 (unreleased)
   - Show a user's Two-factor Authentication status in the administration area.
   - Explicit error when commit not found in the CI
   - Improve performance for issue and merge request pages 
+  - Users with guest access level can not set assignee, labels or milestones for issue and merge request
 
 v 7.12.0 (unreleased)
   - Fix Error 500 when one user attempts to access a personal, internal snippet (Stan Hu)
diff --git a/app/assets/javascripts/dispatcher.js.coffee b/app/assets/javascripts/dispatcher.js.coffee
index 84873e389ea07c3130fec9c03ce67ec2897f8c4e..a8ec0abc2643e26e457ca3784870fda83fdafd06 100644
--- a/app/assets/javascripts/dispatcher.js.coffee
+++ b/app/assets/javascripts/dispatcher.js.coffee
@@ -31,20 +31,14 @@ class Dispatcher
       when 'projects:compare:show'
         new Diff()
       when 'projects:issues:new','projects:issues:edit'
-        GitLab.GfmAutoComplete.setup()
         shortcut_handler = new ShortcutsNavigation()
-        new ZenMode()
         new DropzoneInput($('.issue-form'))
-        if page == 'projects:issues:new'
-          new IssuableForm($('.issue-form'))
+        new IssuableForm($('.issue-form'))
       when 'projects:merge_requests:new', 'projects:merge_requests:edit'
-        GitLab.GfmAutoComplete.setup()
         new Diff()
         shortcut_handler = new ShortcutsNavigation()
-        new ZenMode()
         new DropzoneInput($('.merge-request-form'))
-        if page == 'projects:merge_requests:new'
-          new IssuableForm($('.merge-request-form'))
+        new IssuableForm($('.merge-request-form'))
       when 'projects:merge_requests:show'
         new Diff()
         shortcut_handler = new ShortcutsIssuable()
@@ -113,13 +107,6 @@ class Dispatcher
             new NamespaceSelect()
       when 'dashboard'
         shortcut_handler = new ShortcutsDashboardNavigation()
-        switch path[1]
-          when 'issues', 'merge_requests'
-            new UsersSelect()
-      when 'groups'
-        switch path[1]
-          when 'issues', 'merge_requests'
-            new UsersSelect()
       when 'profiles'
         new Profile()
       when 'projects'
@@ -135,8 +122,6 @@ class Dispatcher
             new ProjectNew()
           when 'show'
             new ProjectShow()
-          when 'issues', 'merge_requests'
-            new UsersSelect()
           when 'wikis'
             new Wikis()
             shortcut_handler = new ShortcutsNavigation()
diff --git a/app/assets/javascripts/issuable_context.js.coffee b/app/assets/javascripts/issuable_context.js.coffee
new file mode 100644
index 0000000000000000000000000000000000000000..176d9cabefa76dc1164a37ba2b9fc7c58247ef54
--- /dev/null
+++ b/app/assets/javascripts/issuable_context.js.coffee
@@ -0,0 +1,22 @@
+#= require jquery.waitforimages
+
+class @IssuableContext
+  constructor: ->
+    new UsersSelect()
+    $('select.select2').select2({width: 'resolve', dropdownAutoWidth: true})
+
+    $(".context .inline-update").on "change", "select", ->
+      $(this).submit()
+    $(".context .inline-update").on "change", ".js-assignee", ->
+      $(this).submit()
+
+    $('.issuable-details').waitForImages ->
+      $('.issuable-affix').affix offset:
+        top: ->
+          @top = ($('.issuable-affix').offset().top - 70)
+        bottom: ->
+          @bottom = $('.footer').outerHeight(true)
+      $('.issuable-affix').on 'affix.bs.affix', ->
+        $(@).width($(@).outerWidth())
+      .on 'affixed-top.bs.affix affixed-bottom.bs.affix', ->
+        $(@).width('')
diff --git a/app/assets/javascripts/issuable_form.js.coffee b/app/assets/javascripts/issuable_form.js.coffee
index abd58bcf9783bd3b801dfe5f214a4d34553a7ccc..48c249943f2d25489d5bfd916a012fa98d496bd1 100644
--- a/app/assets/javascripts/issuable_form.js.coffee
+++ b/app/assets/javascripts/issuable_form.js.coffee
@@ -1,5 +1,9 @@
 class @IssuableForm
   constructor: (@form) ->
+    GitLab.GfmAutoComplete.setup()
+    new UsersSelect()
+    new ZenMode()
+
     @titleField       = @form.find("input[name*='[title]']")
     @descriptionField = @form.find("textarea[name*='[description]']")
 
diff --git a/app/assets/javascripts/issue.js.coffee b/app/assets/javascripts/issue.js.coffee
index 74d6b80be5ea642f3f2214acb3ad665d78e4f2b8..603a16da1ce645d51f2958fa68437e91653ebb65 100644
--- a/app/assets/javascripts/issue.js.coffee
+++ b/app/assets/javascripts/issue.js.coffee
@@ -3,29 +3,12 @@
 
 class @Issue
   constructor: ->
-    $('.edit-issue.inline-update input[type="submit"]').hide()
-    $(".context .inline-update").on "change", "select", ->
-      $(this).submit()
-    $(".context .inline-update").on "change", "#issue_assignee_id", ->
-      $(this).submit()
-
     # Prevent duplicate event bindings
     @disableTaskList()
 
     if $("a.btn-close").length
       @initTaskList()
 
-    $('.issue-details').waitForImages ->
-      $('.issuable-affix').affix offset:
-        top: ->
-          @top = ($('.issuable-affix').offset().top - 70)
-        bottom: ->
-          @bottom = $('.footer').outerHeight(true)
-      $('.issuable-affix').on 'affix.bs.affix', ->
-        $(@).width($(@).outerWidth())
-      .on 'affixed-top.bs.affix affixed-bottom.bs.affix', ->
-        $(@).width('')
-
   initTaskList: ->
     $('.issue-details .js-task-list-container').taskList('enable')
     $(document).on 'tasklist:changed', '.issue-details .js-task-list-container', @updateTaskList
@@ -42,5 +25,5 @@ class @Issue
 
     $.ajax
       type: 'PATCH'
-      url: $('form.js-issue-update').attr('action')
+      url: $('form.js-issuable-update').attr('action')
       data: patchData
diff --git a/app/assets/javascripts/merge_request.js.coffee b/app/assets/javascripts/merge_request.js.coffee
index 5c0bc6861117a1c0535a0fc40f205509a7ce3f74..7462975bd3de8e82b769ed3c4b1f0189f3334866 100644
--- a/app/assets/javascripts/merge_request.js.coffee
+++ b/app/assets/javascripts/merge_request.js.coffee
@@ -10,7 +10,6 @@ class @MergeRequest
   #   action - String, current controller action
   #
   constructor: (@opts) ->
-    @initContextWidget()
     this.$el = $('.merge-request')
 
     this.$('.show-all-commits').on 'click', =>
@@ -26,28 +25,10 @@ class @MergeRequest
     if $("a.btn-close").length
       @initTaskList()
 
-    $('.merge-request-details').waitForImages ->
-      $('.issuable-affix').affix offset:
-        top: ->
-          @top = ($('.issuable-affix').offset().top - 70)
-        bottom: ->
-          @bottom = $('.footer').outerHeight(true)
-      $('.issuable-affix').on 'affix.bs.affix', ->
-        $(@).width($(@).outerWidth())
-      .on 'affixed-top.bs.affix affixed-bottom.bs.affix', ->
-        $(@).width('')
-
   # Local jQuery finder
   $: (selector) ->
     this.$el.find(selector)
 
-  initContextWidget: ->
-    $('.edit-merge_request.inline-update input[type="submit"]').hide()
-    $(".context .inline-update").on "change", "select", ->
-      $(this).submit()
-    $(".context .inline-update").on "change", "#merge_request_assignee_id", ->
-      $(this).submit()
-
   showAllCommits: ->
     this.$('.first-commits').remove()
     this.$('.all-commits').removeClass 'hide'
@@ -68,5 +49,5 @@ class @MergeRequest
 
     $.ajax
       type: 'PATCH'
-      url: $('form.js-merge-request-update').attr('action')
+      url: $('form.js-issuable-update').attr('action')
       data: patchData
diff --git a/app/assets/stylesheets/pages/issues.scss b/app/assets/stylesheets/pages/issues.scss
index ed938f86b3550a49d5184937fe7e3878f4f1d710..3572f33e91fff979bd34a08c25bfc48d55cea041 100644
--- a/app/assets/stylesheets/pages/issues.scss
+++ b/app/assets/stylesheets/pages/issues.scss
@@ -145,9 +145,3 @@ h2.issue-title {
 .issue-form .select2-container {
   width: 250px !important;
 }
-
-.issues-holder {
-  .issue-info {
-    margin-left: 20px;
-  }
-}
diff --git a/app/helpers/gitlab_routing_helper.rb b/app/helpers/gitlab_routing_helper.rb
index 9703c8d9e9cb6c290d290fb67716c7c8bf89eaf2..9d072f81092f9480f905131f9f05541740a81a81 100644
--- a/app/helpers/gitlab_routing_helper.rb
+++ b/app/helpers/gitlab_routing_helper.rb
@@ -52,4 +52,12 @@ module GitlabRoutingHelper
   def project_snippet_url(entity, *args)
     namespace_project_snippet_url(entity.project.namespace, entity.project, entity, *args)
   end
+
+  def toggle_subscription_path(entity, *args)
+    if entity.is_a?(Issue)
+      toggle_subscription_namespace_project_issue_path(entity.project.namespace, entity.project, entity)
+    else
+      toggle_subscription_namespace_project_merge_request_path(entity.project.namespace, entity.project, entity)
+    end
+  end
 end
diff --git a/app/models/ability.rb b/app/models/ability.rb
index a5db22040e00bd2c7acbaffe608e846e56238a82..c90c99c5b5f952d476ff2f12fd92437382af7d8f 100644
--- a/app/models/ability.rb
+++ b/app/models/ability.rb
@@ -185,7 +185,6 @@ class Ability
         :modify_issue,
         :modify_project_snippet,
         :modify_merge_request,
-        :admin_issue,
         :admin_milestone,
         :admin_project_snippet,
         :admin_project_member,
diff --git a/app/services/issuable_base_service.rb b/app/services/issuable_base_service.rb
index 1d99223cfe685d5b14fbb94620e3195b78e30582..f1ef5ca84feae3ccda8da655ca6e118fa8c6f2c8 100644
--- a/app/services/issuable_base_service.rb
+++ b/app/services/issuable_base_service.rb
@@ -26,4 +26,12 @@ class IssuableBaseService < BaseService
       issuable, issuable.project, current_user, branch_type,
       old_branch, new_branch)
   end
+
+  def filter_params
+    unless can?(current_user, :admin_issue, project)
+      params.delete(:milestone_id)
+      params.delete(:label_ids)
+      params.delete(:assignee_id)
+    end
+  end
 end
diff --git a/app/services/issues/create_service.rb b/app/services/issues/create_service.rb
index d5c17906a553f6fea262f1e83792b1dff2911dc0..1ea4b72216c6a2e9edeaa682c43b4da8b1e21686 100644
--- a/app/services/issues/create_service.rb
+++ b/app/services/issues/create_service.rb
@@ -1,6 +1,7 @@
 module Issues
   class CreateService < Issues::BaseService
     def execute
+      filter_params
       label_params = params[:label_ids]
       issue = project.issues.new(params.except(:label_ids))
       issue.author = current_user
diff --git a/app/services/issues/update_service.rb b/app/services/issues/update_service.rb
index 6af942a5ca436fb8efaaec579b52ba3dab17d9ac..3220facaf7c2f76d308a2513f1d20e1c8d5ed690 100644
--- a/app/services/issues/update_service.rb
+++ b/app/services/issues/update_service.rb
@@ -17,6 +17,7 @@ module Issues
       params[:assignee_id]  = "" if params[:assignee_id] == IssuableFinder::NONE
       params[:milestone_id] = "" if params[:milestone_id] == IssuableFinder::NONE
 
+      filter_params
       old_labels = issue.labels.to_a
 
       if params.present? && issue.update_attributes(params.except(:state_event,
diff --git a/app/services/merge_requests/create_service.rb b/app/services/merge_requests/create_service.rb
index ca8d80f6c0c128a3049f451f4a83399c7f8e4351..f431c5d55343eee2d6931f77ed75bf2ed6262de3 100644
--- a/app/services/merge_requests/create_service.rb
+++ b/app/services/merge_requests/create_service.rb
@@ -1,6 +1,7 @@
 module MergeRequests
   class CreateService < MergeRequests::BaseService
     def execute
+      filter_params
       label_params = params[:label_ids]
       merge_request = MergeRequest.new(params.except(:label_ids))
       merge_request.source_project = project
diff --git a/app/services/merge_requests/update_service.rb b/app/services/merge_requests/update_service.rb
index 4f6c6cba9a90dde625cd992a9bad89f169765f4e..f6570f52241e728e72453bf661d34edd81945b09 100644
--- a/app/services/merge_requests/update_service.rb
+++ b/app/services/merge_requests/update_service.rb
@@ -27,6 +27,7 @@ module MergeRequests
       params[:assignee_id]  = "" if params[:assignee_id] == IssuableFinder::NONE
       params[:milestone_id] = "" if params[:milestone_id] == IssuableFinder::NONE
 
+      filter_params
       old_labels = merge_request.labels.to_a
 
       if params.present? && merge_request.update_attributes(
diff --git a/app/views/dashboard/issues.html.haml b/app/views/dashboard/issues.html.haml
index 0dd2edbb1bcb63f27374319615d306432dba4a63..94318d1bcf5517e6f14c478321cbc1137e59bbd5 100644
--- a/app/views/dashboard/issues.html.haml
+++ b/app/views/dashboard/issues.html.haml
@@ -17,5 +17,5 @@
         = link_to issues_dashboard_url(format: :atom, private_token: current_user.private_token), class: 'btn' do
           %i.fa.fa-rss
 
-  = render 'shared/issuable_filter', type: :issues
+  = render 'shared/issuable/filter', type: :issues
 = render 'shared/issues'
diff --git a/app/views/dashboard/merge_requests.html.haml b/app/views/dashboard/merge_requests.html.haml
index 61d2fbe538cb3de33363c14e48bdaaefe74c9b83..90611d562b05342bc6faa901b7a1fdb9c4b8b962 100644
--- a/app/views/dashboard/merge_requests.html.haml
+++ b/app/views/dashboard/merge_requests.html.haml
@@ -7,5 +7,5 @@
   List all merge requests from all projects you have access to.
 %hr
 .append-bottom-20
-  = render 'shared/issuable_filter', type: :merge_requests
+  = render 'shared/issuable/filter', type: :merge_requests
 = render 'shared/merge_requests'
diff --git a/app/views/groups/issues.html.haml b/app/views/groups/issues.html.haml
index e0756e909be14d682104b8e4c0c5ad689c8a4654..f0d90782556f3b64e2ea389185e961442f5de8b9 100644
--- a/app/views/groups/issues.html.haml
+++ b/app/views/groups/issues.html.haml
@@ -21,5 +21,5 @@
         = link_to issues_group_url(@group, format: :atom, private_token: current_user.private_token), class: 'btn' do
           %i.fa.fa-rss
 
-  = render 'shared/issuable_filter', type: :issues
+  = render 'shared/issuable/filter', type: :issues
 = render 'shared/issues'
diff --git a/app/views/groups/merge_requests.html.haml b/app/views/groups/merge_requests.html.haml
index 3d9e857cc5274a68e21d9dadf0b995d98493a50a..ca85a158707bec4b66b3879fb66a057735b1607c 100644
--- a/app/views/groups/merge_requests.html.haml
+++ b/app/views/groups/merge_requests.html.haml
@@ -10,5 +10,5 @@
     To see all merge requests you should visit #{link_to 'dashboard', merge_requests_dashboard_path} page.
 %hr
 .append-bottom-20
-  = render 'shared/issuable_filter', type: :merge_requests
+  = render 'shared/issuable/filter', type: :merge_requests
 = render 'shared/merge_requests'
diff --git a/app/views/projects/issues/_discussion.html.haml b/app/views/projects/issues/_discussion.html.haml
index 656e06ca105c699629899661f54b0e3da73b657e..a099e5972945a0556515481e4d4f8ad398d5cc3d 100644
--- a/app/views/projects/issues/_discussion.html.haml
+++ b/app/views/projects/issues/_discussion.html.haml
@@ -23,7 +23,7 @@
           = cross_project_reference(@project, @issue)
       %hr
       .context
-        = render partial: 'issue_context', locals: { issue: @issue }
+        = render 'shared/issuable/context', issuable: @issue
 
       - if @issue.labels.any?
         .issuable-context-title
diff --git a/app/views/projects/issues/_form.html.haml b/app/views/projects/issues/_form.html.haml
index 8d2564be55e9054bb2c7732a329ae016f0ac6cc3..f39bb7d2574a5aebc3f527e7d48ac1e2bb18e388 100644
--- a/app/views/projects/issues/_form.html.haml
+++ b/app/views/projects/issues/_form.html.haml
@@ -3,7 +3,7 @@
   %hr
 
   = form_for [@project.namespace.becomes(Namespace), @project, @issue], html: { class: 'form-horizontal issue-form gfm-form' } do |f|
-    = render 'projects/issuable_form', f: f, issuable: @issue
+    = render 'shared/issuable/form', f: f, issuable: @issue
 
 :javascript
   $('.assign-to-me-link').on('click', function(e){
diff --git a/app/views/projects/issues/_issue.html.haml b/app/views/projects/issues/_issue.html.haml
index 2c296cab9771b715e037ac04c6d21e7fc1abbd40..cdb3839d13b9295bb94b74e57dcfba3607c8c057 100644
--- a/app/views/projects/issues/_issue.html.haml
+++ b/app/views/projects/issues/_issue.html.haml
@@ -1,7 +1,7 @@
 %li{ id: dom_id(issue), class: issue_css_classes(issue), url: issue_path(issue) }
-  - if controller.controller_name == 'issues'
+  - if controller.controller_name == 'issues' && can?(current_user, :admin_issue, @project)
     .issue-check
-      = check_box_tag dom_id(issue,"selected"), nil, false, 'data-id' => issue.id, class: "selected_issue", disabled: !can?(current_user, :modify_issue, issue)
+      = check_box_tag dom_id(issue,"selected"), nil, false, 'data-id' => issue.id, class: "selected_issue"
 
   .issue-title
     %span.issue-title-text
diff --git a/app/views/projects/issues/_issue_context.html.haml b/app/views/projects/issues/_issue_context.html.haml
deleted file mode 100644
index 88b63946905915af45f35cc2703f9ebe7fee0a0a..0000000000000000000000000000000000000000
--- a/app/views/projects/issues/_issue_context.html.haml
+++ /dev/null
@@ -1,47 +0,0 @@
-= form_for [@project.namespace.becomes(Namespace), @project, @issue], remote: true, html: {class: 'edit-issue inline-update js-issue-update'} do |f|
-  %div.prepend-top-20
-    .issuable-context-title
-      %label
-        Assignee:
-      - if issue.assignee
-        %strong= link_to_member(@project, @issue.assignee, size: 24)
-      - else
-        none
-    - if can?(current_user, :modify_issue, @issue)
-      = users_select_tag('issue[assignee_id]', placeholder: 'Select assignee', class: 'custom-form-control js-select2 js-assignee', selected: @issue.assignee_id, null_user: true, first_user: true)
-
-  %div.prepend-top-20.clearfix
-    .issuable-context-title
-      %label
-        Milestone:
-      - if issue.milestone
-        %span.back-to-milestone
-          = link_to namespace_project_milestone_path(@project.namespace, @project, @issue.milestone) do
-            %strong
-              %i.fa.fa-clock-o
-              = @issue.milestone.title
-      - else
-        none
-    - if can?(current_user, :modify_issue, @issue)
-      = f.select(:milestone_id, milestone_options(@issue), { include_blank: "Select milestone" }, {class: 'select2 select2-compact js-select2 js-milestone'})
-      = hidden_field_tag :issue_context
-      = f.submit class: 'btn'
-
-  - if current_user
-    - subscribed = @issue.subscribed?(current_user)
-    %div.prepend-top-20.clearfix
-      .issuable-context-title
-        %label
-          Subscription:
-      %button.btn.btn-block.subscribe-button{:type => 'button'}
-        %i.fa.fa-eye
-        %span= subscribed ? "Unsubscribe" : "Subscribe"
-      - subscribtion_status = subscribed ? "subscribed" : "unsubscribed"
-      .subscription-status{"data-status" => subscribtion_status}
-        .description-block.unsubscribed{class: ( "hidden" if subscribed )}
-          You're not receiving notifications from this thread.
-        .description-block.subscribed{class: ( "hidden" unless subscribed )}
-          You're receiving notifications because you're subscribed to this thread.
-
-:coffeescript
-  new Subscription("#{toggle_subscription_namespace_project_issue_path(@issue.project.namespace, @project, @issue)}")
diff --git a/app/views/projects/issues/index.html.haml b/app/views/projects/issues/index.html.haml
index 1d5597602d1908835b7a43643149add635502d67..2785ff25e69db688af556b22fe92dcf7d53084bd 100644
--- a/app/views/projects/issues/index.html.haml
+++ b/app/views/projects/issues/index.html.haml
@@ -11,14 +11,14 @@
           = link_to namespace_project_issues_path(@project.namespace, @project, :atom, { private_token: current_user.private_token }), class: 'btn append-right-10' do
             %i.fa.fa-rss
 
-      = render 'shared/issuable_search_form', path: namespace_project_issues_path(@project.namespace, @project)
+      = render 'shared/issuable/search_form', path: namespace_project_issues_path(@project.namespace, @project)
 
     - if can? current_user, :write_issue, @project
       = link_to new_namespace_project_issue_path(@project.namespace, @project, issue: { assignee_id: @issuable_finder.assignee.try(:id), milestone_id: @issuable_finder.milestones.try(:first).try(:id) }), class: "btn btn-new pull-left", title: "New Issue", id: "new_issue_link" do
         %i.fa.fa-plus
         New Issue
 
-  = render 'shared/issuable_filter', type: :issues
+  = render 'shared/issuable/filter', type: :issues
 
 .issues-holder
   = render "issues"
diff --git a/app/views/projects/issues/show.html.haml b/app/views/projects/issues/show.html.haml
index ee1b2a08bc4a90e1de9c75a9cc2ebe1aede6216a..5bbb1fd4e92623a1ca93d2a2ae5b337f41090c30 100644
--- a/app/views/projects/issues/show.html.haml
+++ b/app/views/projects/issues/show.html.haml
@@ -1,6 +1,6 @@
 - page_title "#{@issue.title} (##{@issue.iid})", "Issues"
 .issue
-  .issue-details
+  .issue-details.issuable-details
     %h4.page-title
       .issue-box{ class: issue_box_class(@issue) }
         - if @issue.closed?
diff --git a/app/views/projects/issues/update.js.haml b/app/views/projects/issues/update.js.haml
index 1d38662bff8f18237bdbab4f5d1d76e635849852..b7735aaf3c1b8dfc636552bac06102d09a4bf97d 100644
--- a/app/views/projects/issues/update.js.haml
+++ b/app/views/projects/issues/update.js.haml
@@ -1,17 +1,3 @@
-- if params[:status_only]
-  - if @issue.valid?
-    :plain
-      $("##{dom_id(@issue)}").fadeOut();
-- elsif params[:issue_context]
-  $('.context').html("#{escape_javascript(render partial: 'issue_context', locals: { issue: @issue })}");
-  $('.context').effect('highlight');
-  - if @issue.milestone
-    $('.milestone-nav-link').replaceWith("<span class='milestone-nav-link'>| <span class='light'>Milestone</span> #{escape_javascript(link_to @issue.milestone.title, namespace_project_milestone_path(@issue.project.namespace, @issue.project, @issue.milestone))}</span>")
-  - else
-    $('.milestone-nav-link').html('')
-
-
-$('select.select2').select2({width: 'resolve', dropdownAutoWidth: true})
-$('.edit-issue.inline-update input[type="submit"]').hide();
-new UsersSelect()
+$('.context').html("#{escape_javascript(render 'shared/issuable/context', issuable: @issue)}");
+$('.context').effect('highlight')
 new Issue();
diff --git a/app/views/projects/merge_requests/_discussion.html.haml b/app/views/projects/merge_requests/_discussion.html.haml
index eb3dba6858d1a28be1603fc4f2431c65457cd3ef..76088b9c862c51b8e3ec98054af5c78db9055af9 100644
--- a/app/views/projects/merge_requests/_discussion.html.haml
+++ b/app/views/projects/merge_requests/_discussion.html.haml
@@ -20,7 +20,7 @@
           = cross_project_reference(@project, @merge_request)
       %hr
       .context
-        = render partial: 'projects/merge_requests/show/context', locals: { merge_request: @merge_request }
+        = render 'shared/issuable/context', issuable: @merge_request
 
       - if @merge_request.labels.any?
         .issuable-context-title
diff --git a/app/views/projects/merge_requests/_form.html.haml b/app/views/projects/merge_requests/_form.html.haml
index be73f08744927689466460c71f415e838e20d4ff..8f225a432e4e576d22718ecde7920e1631d1f58c 100644
--- a/app/views/projects/merge_requests/_form.html.haml
+++ b/app/views/projects/merge_requests/_form.html.haml
@@ -1,6 +1,6 @@
 = form_for [@project.namespace.becomes(Namespace), @project, @merge_request], html: { class: 'merge-request-form form-horizontal gfm-form' } do |f|
   .merge-request-form-info
-    = render 'projects/issuable_form', f: f, issuable: @merge_request
+    = render 'shared/issuable/form', f: f, issuable: @merge_request
 
 :javascript
   disableButtonIfEmptyField("#merge_request_title", ".btn-save");
diff --git a/app/views/projects/merge_requests/_new_submit.html.haml b/app/views/projects/merge_requests/_new_submit.html.haml
index 6792104569be59a8e1a804beacb907589a45dfd5..2f147f9095dbdd639a9c3f54da743c2073798d05 100644
--- a/app/views/projects/merge_requests/_new_submit.html.haml
+++ b/app/views/projects/merge_requests/_new_submit.html.haml
@@ -11,7 +11,7 @@
 %hr
 = form_for [@project.namespace.becomes(Namespace), @project, @merge_request], html: { class: 'merge-request-form form-horizontal gfm-form' } do |f|
   .merge-request-form-info
-    = render 'projects/issuable_form', f: f, issuable: @merge_request
+    = render 'shared/issuable/form', f: f, issuable: @merge_request
     = f.hidden_field :source_project_id
     = f.hidden_field :source_branch
     = f.hidden_field :target_project_id
diff --git a/app/views/projects/merge_requests/_show.html.haml b/app/views/projects/merge_requests/_show.html.haml
index 9dc4a47258e0f564f1c3d7da9b8bcee4816b590b..b6d9b135c70c6ab2c0c341a96b4164329f551f93 100644
--- a/app/views/projects/merge_requests/_show.html.haml
+++ b/app/views/projects/merge_requests/_show.html.haml
@@ -1,6 +1,6 @@
 - page_title "#{@merge_request.title} (##{@merge_request.iid})", "Merge Requests"
 .merge-request{'data-url' => merge_request_path(@merge_request)}
-  .merge-request-details
+  .merge-request-details.issuable-details
     = render "projects/merge_requests/show/mr_title"
     %hr
     = render "projects/merge_requests/show/mr_box"
diff --git a/app/views/projects/merge_requests/index.html.haml b/app/views/projects/merge_requests/index.html.haml
index fa591b0537e5ea5ae99ee653e2d4a1a4bede1b36..750cc3e6eea4e8cfdcdf16a1a94692c40357f092 100644
--- a/app/views/projects/merge_requests/index.html.haml
+++ b/app/views/projects/merge_requests/index.html.haml
@@ -1,13 +1,13 @@
 - page_title "Merge Requests"
 .append-bottom-10
   .pull-right
-    = render 'shared/issuable_search_form', path: namespace_project_merge_requests_path(@project.namespace, @project)
+    = render 'shared/issuable/search_form', path: namespace_project_merge_requests_path(@project.namespace, @project)
 
     - if can? current_user, :write_merge_request, @project
       .pull-left.hidden-xs
         = link_to new_namespace_project_merge_request_path(@project.namespace, @project), class: "btn btn-new", title: "New Merge Request" do
           %i.fa.fa-plus
           New Merge Request
-  = render 'shared/issuable_filter', type: :merge_requests
+  = render 'shared/issuable/filter', type: :merge_requests
 .merge-requests-holder
   = render 'merge_requests'
diff --git a/app/views/projects/merge_requests/show/_context.html.haml b/app/views/projects/merge_requests/show/_context.html.haml
deleted file mode 100644
index 5f2f65e0087d3b6d0c2a4d60fe3ece368ea2348b..0000000000000000000000000000000000000000
--- a/app/views/projects/merge_requests/show/_context.html.haml
+++ /dev/null
@@ -1,49 +0,0 @@
-= form_for [@project.namespace.becomes(Namespace), @project, @merge_request], remote: true, html: {class: 'edit-merge_request inline-update js-merge-request-update'} do |f|
-  %div.prepend-top-20
-    .issuable-context-title
-      %label
-        Assignee:
-      - if @merge_request.assignee
-        %strong= link_to_member(@project, @merge_request.assignee, size: 24)
-      - else
-        none
-    .issuable-context-selectbox
-      - if can?(current_user, :modify_merge_request, @merge_request)
-        = users_select_tag('merge_request[assignee_id]', placeholder: 'Select assignee', class: 'custom-form-control js-select2 js-assignee', selected: @merge_request.assignee_id, project: @target_project, null_user: true)
-
-  %div.prepend-top-20.clearfix
-    .issuable-context-title
-      %label
-        Milestone:
-      - if @merge_request.milestone
-        %span.back-to-milestone
-          = link_to namespace_project_milestone_path(@project.namespace, @project, @merge_request.milestone) do
-            %strong
-              = icon('clock-o')
-              = @merge_request.milestone.title
-      - else
-        none
-    .issuable-context-selectbox
-      - if can?(current_user, :modify_merge_request, @merge_request)
-        = f.select(:milestone_id, milestone_options(@merge_request), { include_blank: 'Select milestone' }, {class: 'select2 select2-compact js-select2 js-milestone'})
-        = hidden_field_tag :merge_request_context
-        = f.submit class: 'btn'
-
-  - if current_user
-    - subscribed = @merge_request.subscribed?(current_user)
-    %div.prepend-top-20.clearfix
-      .issuable-context-title
-        %label
-          Subscription:
-      %button.btn.btn-block.subscribe-button{:type => 'button'}
-        = icon('eye')
-        %span= subscribed ? 'Unsubscribe' : 'Subscribe'
-      - subscribtion_status = subscribed ? 'subscribed' : 'unsubscribed'
-      .subscription-status{data: {status: subscribtion_status}}
-        .description-block.unsubscribed{class: ( 'hidden' if subscribed )}
-          You're not receiving notifications from this thread.
-        .description-block.subscribed{class: ( 'hidden' unless subscribed )}
-          You're receiving notifications because you're subscribed to this thread.
-
-:coffeescript
-  new Subscription("#{toggle_subscription_namespace_project_merge_request_path(@merge_request.project.namespace, @project, @merge_request)}")
diff --git a/app/views/projects/merge_requests/update.js.haml b/app/views/projects/merge_requests/update.js.haml
index b4df1d20737468718827d968170df1696c4bb043..25583b2cc6f0aba1e175868501ea88a11e8a8d13 100644
--- a/app/views/projects/merge_requests/update.js.haml
+++ b/app/views/projects/merge_requests/update.js.haml
@@ -1,8 +1,3 @@
-- if params[:merge_request_context]
-  $('.context').html("#{escape_javascript(render partial: 'projects/merge_requests/show/context', locals: { issue: @issue })}");
-  $('.context').effect('highlight');
-
-  new UsersSelect()
-
-  $('select.select2').select2({width: 'resolve', dropdownAutoWidth: true});
-  merge_request = new MergeRequest();
+$('.context').html("#{escape_javascript(render 'shared/issuable/context', issuable: @merge_request)}");
+$('.context').effect('highlight')
+merge_request = new MergeRequest();
diff --git a/app/views/shared/issuable/_context.html.haml b/app/views/shared/issuable/_context.html.haml
new file mode 100644
index 0000000000000000000000000000000000000000..46990895d33e0e6a905506b28bf28fc64ea78c79
--- /dev/null
+++ b/app/views/shared/issuable/_context.html.haml
@@ -0,0 +1,50 @@
+= form_for [@project.namespace.becomes(Namespace), @project, issuable], remote: true, html: {class: 'issuable-context-form inline-update js-issuable-update'} do |f|
+  %div.prepend-top-20
+    .issuable-context-title
+      %label
+        Assignee:
+      - if issuable.assignee
+        %strong= link_to_member(@project, issuable.assignee, size: 24)
+      - else
+        none
+    .issuable-context-selectbox
+      - if can?(current_user, :admin_issue, @project)
+        = users_select_tag("#{issuable.class.table_name.singularize}[assignee_id]", placeholder: 'Select assignee', class: 'custom-form-control js-select2 js-assignee', selected: issuable.assignee_id, project: @target_project, null_user: true)
+
+  %div.prepend-top-20.clearfix
+    .issuable-context-title
+      %label
+        Milestone:
+      - if issuable.milestone
+        %span.back-to-milestone
+          = link_to namespace_project_milestone_path(@project.namespace, @project, issuable.milestone) do
+            %strong
+              = icon('clock-o')
+              = issuable.milestone.title
+      - else
+        none
+    .issuable-context-selectbox
+      - if can?(current_user, :admin_issue, @project)
+        = f.select(:milestone_id, milestone_options(issuable), { include_blank: 'Select milestone' }, {class: 'select2 select2-compact js-select2 js-milestone'})
+        = hidden_field_tag :issuable_context
+        = f.submit class: 'btn hide'
+
+  - if current_user
+    - subscribed = issuable.subscribed?(current_user)
+    %div.prepend-top-20.clearfix
+      .issuable-context-title
+        %label
+          Subscription:
+      %button.btn.btn-block.subscribe-button{:type => 'button'}
+        = icon('eye')
+        %span= subscribed ? 'Unsubscribe' : 'Subscribe'
+      - subscribtion_status = subscribed ? 'subscribed' : 'unsubscribed'
+      .subscription-status{data: {status: subscribtion_status}}
+        .description-block.unsubscribed{class: ( 'hidden' if subscribed )}
+          You're not receiving notifications from this thread.
+        .description-block.subscribed{class: ( 'hidden' unless subscribed )}
+          You're receiving notifications because you're subscribed to this thread.
+
+:coffeescript
+  new Subscription("#{toggle_subscription_path(issuable)}")
+  new IssuableContext()
diff --git a/app/views/shared/_issuable_filter.html.haml b/app/views/shared/issuable/_filter.html.haml
similarity index 95%
rename from app/views/shared/_issuable_filter.html.haml
rename to app/views/shared/issuable/_filter.html.haml
index a355eb62813b90d333f7a6962583195dcf3d169f..a829782fc4f2af615c5d6909b4a4dee69e9b6e26 100644
--- a/app/views/shared/_issuable_filter.html.haml
+++ b/app/views/shared/issuable/_filter.html.haml
@@ -29,11 +29,10 @@
 
   .issues-details-filters
     = form_tag page_filter_path(without: [:assignee_id, :author_id, :milestone_title, :label_name]), method: :get, class: 'filter-form' do
-      - if controller.controller_name == 'issues'
+      - if controller.controller_name == 'issues' && can?(current_user, :admin_issue, @project)
         .check-all-holder
           = check_box_tag "check_all_issues", nil, false,
-            class: "check_all_issues left",
-            disabled: !can?(current_user, :modify_issue, @project)
+            class: "check_all_issues left"
       .issues-other-filters
         .filter-item.inline
           = users_select_tag(:assignee_id, selected: params[:assignee_id],
@@ -64,6 +63,8 @@
           = button_tag "Update issues", class: "btn update_selected_issues btn-save"
 
 :coffeescript
+  new UsersSelect()
+
   $('form.filter-form').on 'submit', (event) ->
     event.preventDefault()
     Turbolinks.visit @.action + '&' + $(@).serialize()
diff --git a/app/views/projects/_issuable_form.html.haml b/app/views/shared/issuable/_form.html.haml
similarity index 64%
rename from app/views/projects/_issuable_form.html.haml
rename to app/views/shared/issuable/_form.html.haml
index 496fad34dc223efedbe9df36738e6da3cca04439..e434e1b6b9873d2502ca977e078ced7ec3e49b37 100644
--- a/app/views/projects/_issuable_form.html.haml
+++ b/app/views/shared/issuable/_form.html.haml
@@ -37,47 +37,48 @@
 
       .clearfix
       .error-alert
-%hr
-.form-group
-  .issue-assignee
-    = f.label :assignee_id, class: 'control-label' do
-      %i.fa.fa-user
-      Assign to
-    .col-sm-10
-      = users_select_tag("#{issuable.class.model_name.param_key}[assignee_id]",
-          placeholder: 'Select a user', class: 'custom-form-control', null_user: true,
-          selected: issuable.assignee_id, project: @target_project || @project)
-      &nbsp;
-      = link_to 'Assign to me', '#', class: 'btn assign-to-me-link'
-.form-group
-  .issue-milestone
-    = f.label :milestone_id, class: 'control-label' do
-      %i.fa.fa-clock-o
-      Milestone
+  %hr
+- if can?(current_user, :admin_issue, @project)
+  .form-group
+    .issue-assignee
+      = f.label :assignee_id, class: 'control-label' do
+        %i.fa.fa-user
+        Assign to
+      .col-sm-10
+        = users_select_tag("#{issuable.class.model_name.param_key}[assignee_id]",
+            placeholder: 'Select a user', class: 'custom-form-control', null_user: true,
+            selected: issuable.assignee_id, project: @target_project || @project)
+        &nbsp;
+        = link_to 'Assign to me', '#', class: 'btn assign-to-me-link'
+  .form-group
+    .issue-milestone
+      = f.label :milestone_id, class: 'control-label' do
+        %i.fa.fa-clock-o
+        Milestone
+      .col-sm-10
+        - if milestone_options(issuable).present?
+          = f.select(:milestone_id, milestone_options(issuable),
+            { include_blank: 'Select milestone' }, { class: 'select2' })
+        - else
+          .prepend-top-10
+          %span.light No open milestones available.
+        &nbsp;
+        - if can? current_user, :admin_milestone, issuable.project
+          = link_to 'Create new milestone', new_namespace_project_milestone_path(issuable.project.namespace, issuable.project), target: :blank
+  .form-group
+    = f.label :label_ids, class: 'control-label' do
+      %i.fa.fa-tag
+      Labels
     .col-sm-10
-      - if milestone_options(issuable).present?
-        = f.select(:milestone_id, milestone_options(issuable),
-          { include_blank: 'Select milestone' }, { class: 'select2' })
+      - if issuable.project.labels.any?
+        = f.collection_select :label_ids, issuable.project.labels.all, :id, :name,
+          { selected: issuable.label_ids }, multiple: true, class: 'select2'
       - else
         .prepend-top-10
-        %span.light No open milestones available.
+        %span.light No labels yet.
       &nbsp;
-      - if can? current_user, :admin_milestone, issuable.project
-        = link_to 'Create new milestone', new_namespace_project_milestone_path(issuable.project.namespace, issuable.project), target: :blank
-.form-group
-  = f.label :label_ids, class: 'control-label' do
-    %i.fa.fa-tag
-    Labels
-  .col-sm-10
-    - if issuable.project.labels.any?
-      = f.collection_select :label_ids, issuable.project.labels.all, :id, :name,
-        { selected: issuable.label_ids }, multiple: true, class: 'select2'
-    - else
-      .prepend-top-10
-      %span.light No labels yet.
-    &nbsp;
-    - if can? current_user, :admin_label, issuable.project
-      = link_to 'Create new label', new_namespace_project_label_path(issuable.project.namespace, issuable.project), target: :blank
+      - if can? current_user, :admin_label, issuable.project
+        = link_to 'Create new label', new_namespace_project_label_path(issuable.project.namespace, issuable.project), target: :blank
 
 - if issuable.is_a?(MergeRequest)
   %hr
diff --git a/app/views/shared/_issuable_search_form.html.haml b/app/views/shared/issuable/_search_form.html.haml
similarity index 100%
rename from app/views/shared/_issuable_search_form.html.haml
rename to app/views/shared/issuable/_search_form.html.haml
diff --git a/features/project/issues/issues.feature b/features/project/issues/issues.feature
index bf84e2f8e87fbd208209392296ae1307f58c2055..a15298fc452d57423fa22ec02d0decfb8a10e460 100644
--- a/features/project/issues/issues.feature
+++ b/features/project/issues/issues.feature
@@ -184,3 +184,15 @@ Feature: Project Issues
     Then I should see that I am subscribed
     When I click button "Unsubscribe"
     Then I should see that I am unsubscribed
+
+  Scenario: I submit new unassigned issue as guest
+    Given I logout
+    Given public project "Community"
+    When I visit project "Community" page
+    And I click link "New Issue"
+    And I should not see assignee field
+    And I should not see milestone field
+    And I should not see labels field
+    And I submit new issue "500 error on profile"
+    Then I should see issue "500 error on profile"
+
diff --git a/features/steps/project/issues/issues.rb b/features/steps/project/issues/issues.rb
index 6873c043e190345e8fe679dc488f7533b3ee7bb8..91d5c3688e21c3075ea739a1584282ac5f2124f7 100644
--- a/features/steps/project/issues/issues.rb
+++ b/features/steps/project/issues/issues.rb
@@ -262,6 +262,24 @@ class Spinach::Features::ProjectIssues < Spinach::FeatureSteps
     end
   end
 
+  step 'I should not see labels field' do
+    page.within '.issue-form' do
+      expect(page).not_to have_content("Labels")
+    end
+  end
+
+  step 'I should not see milestone field' do
+    page.within '.issue-form' do
+      expect(page).not_to have_content("Milestone")
+    end
+  end
+
+  step 'I should not see assignee field' do
+    page.within '.issue-form' do
+      expect(page).not_to have_content("Assign to")
+    end
+  end
+
   def filter_issue(text)
     fill_in 'issue_search', with: text
   end
diff --git a/lib/api/issues.rb b/lib/api/issues.rb
index c8db93eb77866730d6fb7c806df2831d66168a12..4d632ce77c10b60ec4bedaa0f4b52069824f8a9d 100644
--- a/lib/api/issues.rb
+++ b/lib/api/issues.rb
@@ -157,7 +157,7 @@ module API
         if issue.valid?
           # Find or create labels and attach to issue. Labels are valid because
           # we already checked its name, so there can't be an error here
-          unless params[:labels].nil?
+          if params[:labels] && can?(current_user, :admin_issue, user_project)
             issue.remove_labels
             # Create and add labels to the new created issue
             issue.add_labels_by_names(params[:labels].split(','))
diff --git a/spec/features/issues_spec.rb b/spec/features/issues_spec.rb
index 158a5c0c29c239b1f1b4dd4f19d56fb626dbb211..808a6eeb958a0f47376ad2e9d6a5c300542f391d 100644
--- a/spec/features/issues_spec.rb
+++ b/spec/features/issues_spec.rb
@@ -218,7 +218,7 @@ describe 'Issues', feature: true do
       it 'with dropdown menu' do
         visit namespace_project_issue_path(project.namespace, project, issue)
 
-        find('.edit-issue.inline-update #issue_assignee_id').
+        find('.context #issue_assignee_id').
           set project.team.members.first.id
         click_button 'Update Issue'
 
@@ -257,7 +257,7 @@ describe 'Issues', feature: true do
       it 'with dropdown menu' do
         visit namespace_project_issue_path(project.namespace, project, issue)
 
-        find('.edit-issue.inline-update').
+        find('.context').
           select(milestone.title, from: 'issue_milestone_id')
         click_button 'Update Issue'
 
diff --git a/spec/features/task_lists_spec.rb b/spec/features/task_lists_spec.rb
index 2099fc40ccabce2207a4f56ca902189ced976d97..fca3c77fc64464e9e8a1fda7d31c237b7c699902 100644
--- a/spec/features/task_lists_spec.rb
+++ b/spec/features/task_lists_spec.rb
@@ -1,6 +1,6 @@
 require 'spec_helper'
 
-feature 'Task Lists' do
+feature 'Task Lists', feature: true do
   include Warden::Test::Helpers
 
   let(:project) { create(:project) }
@@ -52,7 +52,7 @@ feature 'Task Lists' do
       expect(page).to have_selector(container)
       expect(page).to have_selector("#{container} .wiki .task-list .task-list-item .task-list-item-checkbox")
       expect(page).to have_selector("#{container} .js-task-list-field")
-      expect(page).to have_selector('form.js-issue-update')
+      expect(page).to have_selector('form.js-issuable-update')
       expect(page).to have_selector('a.btn-close')
     end
 
@@ -128,7 +128,7 @@ feature 'Task Lists' do
       expect(page).to have_selector(container)
       expect(page).to have_selector("#{container} .wiki .task-list .task-list-item .task-list-item-checkbox")
       expect(page).to have_selector("#{container} .js-task-list-field")
-      expect(page).to have_selector('form.js-merge-request-update')
+      expect(page).to have_selector('form.js-issuable-update')
       expect(page).to have_selector('a.btn-close')
     end
 
diff --git a/spec/javascripts/fixtures/issues_show.html.haml b/spec/javascripts/fixtures/issues_show.html.haml
index db5abe0cae3f82d6bd318ebbd240cae3ba5a8399..7e8b2a64351f176907213128c04d0f4af597ae0c 100644
--- a/spec/javascripts/fixtures/issues_show.html.haml
+++ b/spec/javascripts/fixtures/issues_show.html.haml
@@ -10,4 +10,4 @@
       %textarea.js-task-list-field
         \- [ ] Task List Item
 
-%form.js-issue-update{action: '/foo'}
+%form.js-issuable-update{action: '/foo'}
diff --git a/spec/javascripts/fixtures/merge_requests_show.html.haml b/spec/javascripts/fixtures/merge_requests_show.html.haml
index c4329b8f94a343c57e271979bf1826b1e88140e8..f0c622935f849cc2680fa27b3534ec035b05c76b 100644
--- a/spec/javascripts/fixtures/merge_requests_show.html.haml
+++ b/spec/javascripts/fixtures/merge_requests_show.html.haml
@@ -10,4 +10,4 @@
       %textarea.js-task-list-field
         \- [ ] Task List Item
 
-%form.js-merge-request-update{action: '/foo'}
+%form.js-issuable-update{action: '/foo'}