diff --git a/app/helpers/diff_helper.rb b/app/helpers/diff_helper.rb
index 425a8ced549308b3da5116c829ba3d9ccfe102b0..e524f6da9c8c941fbdbedf1068dea4528feae715 100644
--- a/app/helpers/diff_helper.rb
+++ b/app/helpers/diff_helper.rb
@@ -39,110 +39,6 @@ module DiffHelper
     end
   end
 
-  def generate_line_code(file_path, line)
-    Gitlab::Diff::LineCode.generate(file_path, line.new_pos, line.old_pos)
-  end
-
-  def parallel_diff(diff_file, index)
-    lines = []
-    skip_next = false
-
-    diff_file.highlighted_diff_lines.each do |line|
-      full_line = line.text
-      type = line.type
-      line_code = generate_line_code(diff_file.file_path, line)
-      line_new = line.new_pos
-      line_old = line.old_pos
-
-      next_line = diff_file.next_line(line.index)
-
-      if next_line
-        next_line_code = generate_line_code(diff_file.file_path, next_line)
-        next_type = next_line.type
-        next_line = next_line.text
-      end
-
-      case type
-      when 'match', nil
-        # line in the right panel is the same as in the left one
-        lines << {
-          left: {
-            type:       type,
-            number:     line_old,
-            text:       full_line,
-            line_code:  line_code,
-          },
-          right: {
-            type:       type,
-            number:     line_new,
-            text:       full_line,
-            line_code:  line_code
-          }
-        }
-      when 'old'
-        case next_type
-        when 'new'
-          # Left side has text removed, right side has text added
-          lines << {
-            left: {
-              type:       type,
-              number:     line_old,
-              text:       full_line,
-              line_code:  line_code,
-            },
-            right: {
-              type:       next_type,
-              number:     line_new,
-              text:       next_line,
-              line_code:  next_line_code
-            }
-          }
-          skip_next = true
-        when 'old', nil
-          # Left side has text removed, right side doesn't have any change
-          # No next line code, no new line number, no new line text
-          lines << {
-            left: {
-              type:       type,
-              number:     line_old,
-              text:       full_line,
-              line_code:  line_code,
-            },
-            right: {
-              type:       next_type,
-              number:     nil,
-              text:       "",
-              line_code:  nil
-            }
-          }
-        end
-      when 'new'
-        if skip_next
-          # Change has been already included in previous line so no need to do it again
-          skip_next = false
-          next
-        else
-          # Change is only on the right side, left side has no change
-          lines << {
-            left: {
-              type:       nil,
-              number:     nil,
-              text:       "",
-              line_code:  line_code,
-            },
-            right: {
-              type:       type,
-              number:     line_new,
-              text:       full_line,
-              line_code:  line_code
-            }
-          }
-        end
-      end
-    end
-    lines
-  end
-
   def unfold_bottom_class(bottom)
     (bottom) ? 'js-unfold-bottom' : ''
   end
diff --git a/app/views/projects/diffs/_parallel_view.html.haml b/app/views/projects/diffs/_parallel_view.html.haml
index 7b9cecbc3da8ac6fad341a7c2f0fdc59f2d09e5f..986d30d36a8217301e40ea6f3c57593c99c83980 100644
--- a/app/views/projects/diffs/_parallel_view.html.haml
+++ b/app/views/projects/diffs/_parallel_view.html.haml
@@ -1,7 +1,7 @@
 / Side-by-side diff view
 %div.text-file.diff-wrap-lines.code.file-content.js-syntax-highlight
   %table
-    - parallel_diff(diff_file, index).each do |line|
+    - diff_file.parallel_diff_lines.each do |line|
       - left = line[:left]
       - right = line[:right]
       %tr.line_holder.parallel
@@ -13,7 +13,7 @@
             = link_to raw(left[:number]), "##{left[:line_code]}", id: left[:line_code]
             - if @comments_allowed && can?(current_user, :create_note, @project)
               = link_to_new_diff_note(left[:line_code], 'old')
-            %td.line_content{class: "parallel noteable_line #{left[:type]} #{left[:line_code]}", data: { "line_code" => left[:line_code] }}= diff_line_content(left[:text])
+            %td.line_content{class: "parallel noteable_line #{left[:type]} #{left[:line_code]}", data: { line_code: left[:line_code] }}= diff_line_content(left[:text])
 
           - if right[:type] == 'new'
             - new_line_class = 'new'
@@ -26,7 +26,7 @@
             = link_to raw(right[:number]), "##{new_line_code}", id: new_line_code
             - if @comments_allowed && can?(current_user, :create_note, @project)
               = link_to_new_diff_note(right[:line_code], 'new')
-            %td.line_content.parallel{class: "noteable_line #{new_line_class} #{new_line_code}", data: { "line_code" => new_line_code }}= diff_line_content(right[:text])
+            %td.line_content.parallel{class: "noteable_line #{new_line_class} #{new_line_code}", data: { line_code: new_line_code }}= diff_line_content(right[:text])
 
       - if @reply_allowed
         - comments_left, comments_right = organize_comments(left[:type], right[:type], left[:line_code], right[:line_code])
diff --git a/app/views/projects/diffs/_text_file.html.haml b/app/views/projects/diffs/_text_file.html.haml
index 6761155dcf916f06aefe68f09e7907472aa5ed9f..310bbd4efeae5c84b7785979f50e7c02a5ed6f5f 100644
--- a/app/views/projects/diffs/_text_file.html.haml
+++ b/app/views/projects/diffs/_text_file.html.haml
@@ -22,7 +22,7 @@
             = link_to_new_diff_note(line_code)
         %td.new_line{data: {linenumber: line.new_pos}}
           = link_to raw(type == "old" ? "&nbsp;" : line.new_pos), "##{line_code}", id: line_code
-        %td.line_content{class: "noteable_line #{type} #{line_code}", data: { "line_code" => line_code }}= diff_line_content(line.text)
+        %td.line_content{class: "noteable_line #{type} #{line_code}", data: { line_code: line_code }}= diff_line_content(line.text)
 
     - if @reply_allowed
       - comments = @line_notes.select { |n| n.line_code == line_code && n.active? }.sort_by(&:created_at)
diff --git a/app/views/projects/notes/discussions/_diff.html.haml b/app/views/projects/notes/discussions/_diff.html.haml
index 97347a9f67ffc7bab9ae9aae9f69d1a3e07cb0bb..46962b184cee5331bf80c7f527ba7d565b162591 100644
--- a/app/views/projects/notes/discussions/_diff.html.haml
+++ b/app/views/projects/notes/discussions/_diff.html.haml
@@ -24,7 +24,7 @@
                 = raw(type == "new" ? "&nbsp;" : line.old_pos)
               %td.new_line
                 = raw(type == "old" ? "&nbsp;" : line.new_pos)
-              %td.line_content{class: "noteable_line #{type} #{line_code}", "line_code" => line_code}= diff_line_content(line.text)
+              %td.line_content{class: "noteable_line #{type} #{line_code}", line_code: line_code}= diff_line_content(line.text)
 
               - if line_code == note.line_code
                 = render "projects/notes/diff_notes_with_reply", notes: discussion_notes
diff --git a/lib/gitlab/diff/file.rb b/lib/gitlab/diff/file.rb
index a6a7fc8ff4c4e0212acdffe9848934810cdce049..74b1c117129339bc9bd4424c67782348cc993db3 100644
--- a/lib/gitlab/diff/file.rb
+++ b/lib/gitlab/diff/file.rb
@@ -20,6 +20,10 @@ module Gitlab
         Gitlab::Diff::Highlight.new(self).highlight
       end
 
+      def parallel_diff_lines
+        Gitlab::Diff::ParallelDiff.new(self).parallelize
+      end
+
       def mode_changed?
         !!(diff.a_mode && diff.b_mode && diff.a_mode != diff.b_mode)
       end
diff --git a/lib/gitlab/diff/parallel_diff.rb b/lib/gitlab/diff/parallel_diff.rb
new file mode 100644
index 0000000000000000000000000000000000000000..a0dc3da875dd0f1fc47e6f139ca4e638b1a07fbe
--- /dev/null
+++ b/lib/gitlab/diff/parallel_diff.rb
@@ -0,0 +1,117 @@
+module Gitlab
+  module Diff
+    class ParallelDiff
+      attr_accessor :diff_file
+
+      def initialize(diff_file)
+        @diff_file = diff_file
+      end
+
+      def parallelize
+        lines = []
+        skip_next = false
+
+        diff_file.highlighted_diff_lines.each do |line|
+          full_line = line.text
+          type = line.type
+          line_code = generate_line_code(diff_file.file_path, line)
+          line_new = line.new_pos
+          line_old = line.old_pos
+
+          next_line = diff_file.next_line(line.index)
+
+          if next_line
+            next_line_code = generate_line_code(diff_file.file_path, next_line)
+            next_type = next_line.type
+            next_line = next_line.text
+          end
+
+          case type
+          when 'match', nil
+            # line in the right panel is the same as in the left one
+            lines << {
+              left: {
+                type:       type,
+                number:     line_old,
+                text:       full_line,
+                line_code:  line_code,
+              },
+              right: {
+                type:       type,
+                number:     line_new,
+                text:       full_line,
+                line_code:  line_code
+              }
+            }
+          when 'old'
+            case next_type
+            when 'new'
+              # Left side has text removed, right side has text added
+              lines << {
+                left: {
+                  type:       type,
+                  number:     line_old,
+                  text:       full_line,
+                  line_code:  line_code,
+                },
+                right: {
+                  type:       next_type,
+                  number:     line_new,
+                  text:       next_line,
+                  line_code:  next_line_code
+                }
+              }
+              skip_next = true
+            when 'old', nil
+              # Left side has text removed, right side doesn't have any change
+              # No next line code, no new line number, no new line text
+              lines << {
+                left: {
+                  type:       type,
+                  number:     line_old,
+                  text:       full_line,
+                  line_code:  line_code,
+                },
+                right: {
+                  type:       next_type,
+                  number:     nil,
+                  text:       "",
+                  line_code:  nil
+                }
+              }
+            end
+          when 'new'
+            if skip_next
+              # Change has been already included in previous line so no need to do it again
+              skip_next = false
+              next
+            else
+              # Change is only on the right side, left side has no change
+              lines << {
+                left: {
+                  type:       nil,
+                  number:     nil,
+                  text:       "",
+                  line_code:  line_code,
+                },
+                right: {
+                  type:       type,
+                  number:     line_new,
+                  text:       full_line,
+                  line_code:  line_code
+                }
+              }
+            end
+          end
+        end
+        lines
+      end
+
+      private
+
+      def generate_line_code(file_path, line)
+        Gitlab::Diff::LineCode.generate(file_path, line.new_pos, line.old_pos)
+      end
+    end
+  end
+end
diff --git a/spec/helpers/diff_helper_spec.rb b/spec/helpers/diff_helper_spec.rb
index 435ecd04fbe36c9d1f8e07944805b3e26f4c4423..955d2852cfddfa9f34195e4badf5fa86580aefa7 100644
--- a/spec/helpers/diff_helper_spec.rb
+++ b/spec/helpers/diff_helper_spec.rb
@@ -84,20 +84,6 @@ describe DiffHelper do
     end
   end
 
-  describe 'parallel_diff' do
-    it 'should return an array of arrays containing the parsed diff' do
-      expect(parallel_diff(diff_file, 0)).
-        to match_array(parallel_diff_result_array)
-    end
-  end
-
-  describe 'generate_line_code' do
-    it 'should generate correct line code' do
-      expect(generate_line_code(diff_file.file_path, diff_file.diff_lines.first)).
-        to eq('2f6fcd96b88b36ce98c38da085c795a27d92a3dd_6_6')
-    end
-  end
-
   describe 'unfold_bottom_class' do
     it 'should return empty string when bottom line shouldnt be unfolded' do
       expect(unfold_bottom_class(false)).to eq('')
@@ -135,8 +121,4 @@ describe DiffHelper do
       expect(diff_line_content(diff_file.diff_lines.first.text)).to be_html_safe
     end
   end
-
-  def parallel_diff_result_array
-    YAML.load_file("#{Rails.root}/spec/fixtures/parallel_diff_result.yml")
-  end
 end
diff --git a/spec/lib/gitlab/diff/parallel_diff_spec.rb b/spec/lib/gitlab/diff/parallel_diff_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..852218b4e62ce240844d6c66d7520254c375f18d
--- /dev/null
+++ b/spec/lib/gitlab/diff/parallel_diff_spec.rb
@@ -0,0 +1,22 @@
+require 'spec_helper'
+
+describe Gitlab::Diff::ParallelDiff, lib: true do
+  include RepoHelpers
+  
+  let(:project) { create(:project) }
+  let(:repository) { project.repository }
+  let(:commit) { project.commit(sample_commit.id) }
+  let(:diffs) { commit.diffs }
+  let(:diff) { diffs.first }
+  let(:diff_refs) { [commit.parent, commit] }
+  let(:diff_file) { Gitlab::Diff::File.new(diff, diff_refs) }
+  subject { described_class.new(diff_file) }
+
+  let(:parallel_diff_result_array) { YAML.load_file("#{Rails.root}/spec/fixtures/parallel_diff_result.yml") }
+
+  describe '#parallelize' do
+    it 'should return an array of arrays containing the parsed diff' do
+      expect(subject.parallelize).to match_array(parallel_diff_result_array)
+    end
+  end
+end