     return data
 
 
-  setLineWidget: (rowNumber, username) ->
-    oldWidget    = @lineWidgets[username]
-    lineHeight   = @getEditor().renderer.lineHeight + 2
-    color        = KD.utils.getColorFromString username
-    style        = "border-bottom:2px dotted #{color};margin-top:-#{lineHeight}px;"
-    cssClass     = 'ace-line-widget'
-    manager      = @getAce().lineWidgetManager
-
-    if oldWidget
-      manager.removeLineWidget oldWidget
-
-    options      =
-      row        : rowNumber
-      rowCount   : 0
-      fixedWidth : yes
-      editor     : @getEditor()
-      html       : "<div class='#{cssClass}' style='#{style}'>#{username}</div>"
-
-    KD.utils.defer =>
-      manager.addLineWidget options
-      @lineWidgets[username] = options
-
-
-  setParticipantCursor: (row, column, username) ->
-    oldCursor = @cursors[username]
-    session   = @getEditorSession()
-    AceRange  = @getAce().Range
-    color     = KD.utils.getColorFromString username
-    cssClass  = "ace-participant-cursor ace-cursor-#{username}"
-
-    return unless AceRange
-
-    if oldCursor
-      session.removeMarker oldCursor.id
-
-    range = new AceRange row, column, row, column + 1
-    id    = session.addMarker range, cssClass, 'text'
-
-    @cursors[username] = { id, row, column }
+  # setLineWidget: (rowNumber, username) ->
+  #   oldWidget    = @lineWidgets[username]
+  #   lineHeight   = @getEditor().renderer.lineHeight + 2
+  #   color        = KD.utils.getColorFromString username
+  #   style        = "border-bottom:2px dotted #{color};margin-top:-#{lineHeight}px;"
+  #   cssClass     = 'ace-line-widget'
+  #   manager      = @getAce().lineWidgetManager
+
+  #   if oldWidget
+  #     manager.removeLineWidget oldWidget
+
+  #   options      =
+  #     row        : rowNumber
+  #     rowCount   : 0
+  #     fixedWidth : yes
+  #     editor     : @getEditor()
+  #     html       : "<div class='#{cssClass}' style='#{style}'>#{username}</div>"
+
+  #   KD.utils.defer =>
+  #     manager.addLineWidget options
+  #     @lineWidgets[username] = options
+
+
+  # setParticipantCursor: (row, column, username) ->
+  #   oldCursor = @cursors[username]
+  #   session   = @getEditorSession()
+  #   AceRange  = @getAce().Range
+  #   color     = KD.utils.getColorFromString username
+  #   cssClass  = "ace-participant-cursor ace-cursor-#{username}"
+
+  #   return unless AceRange
+
+  #   if oldCursor
+  #     session.removeMarker oldCursor.id
+
+  #   range = new AceRange row, column, row, column + 1
+  #   id    = session.addMarker range, cssClass, 'text'
+
+  #   @cursors[username] = { id, row, column }
 
 
   handleChange: (change, rtm, realTimeDoc) ->
     {context, type, origin} = change
 
-    if type is 'ContentChange'
-      oldContent = @getValue()
-      string     = rtm.getFromModel context.file.path
-      newContent = string.getText()
-      cursor     = @getCursor()
-
-      @setContent newContent, no
-
-      row = @getNewCursorPosition oldContent, newContent, cursor.row
-      col = cursor.column
-
-      KD.utils.defer =>
-        @setCursor { row, column: col }
-
-    if type is 'CursorActivity'
-      {row, column} = context.cursor
-      @setLineWidget row, origin
-      @setParticipantCursor row, column, origin
-
-
-  getNewCursorPosition: (oldContent, newContent, oldRowNumber) ->
-    return if not oldContent or not newContent
-
-    oldContentLines = oldContent.split '\n'
-    newContentLines = newContent.split '\n'
-    oldLinesAbove   = oldContentLines.slice 0, oldRowNumber
-    newLinesAbove   = newContentLines.slice 0, oldRowNumber
-    oldLinesBelow   = oldContentLines.slice oldRowNumber, oldContentLines.length
-
-    unless oldLinesAbove is newLinesAbove
-      newCursorPosition = newContentLines.length - oldLinesBelow.length
-
-    return newCursorPosition ? 0
+    # if type is 'ContentChange'
+    #   oldContent = @getValue()
+    #   string     = rtm.getFromModel context.file.path
+    #   newContent = string.getText()
+    #   cursor     = @getCursor()
+
+    #   @setContent newContent, no
+
+    #   row = @getNewCursorPosition oldContent, newContent, cursor.row
+    #   col = cursor.column
+
+    #   KD.utils.defer =>
+    #     @setCursor { row, column: col }
+
+    # if type is 'CursorActivity'
+    #   {row, column} = context.cursor
+    #   @setLineWidget row, origin
+    #   @setParticipantCursor row, column, origin
+
+
+  # getNewCursorPosition: (oldContent, newContent, oldRowNumber) ->
+  #   return if not oldContent or not newContent
+
+  #   oldContentLines = oldContent.split '\n'
+  #   newContentLines = newContent.split '\n'
+  #   oldLinesAbove   = oldContentLines.slice 0, oldRowNumber
+  #   newLinesAbove   = newContentLines.slice 0, oldRowNumber
+  #   oldLinesBelow   = oldContentLines.slice oldRowNumber, oldContentLines.length
+
+  #   unless oldLinesAbove is newLinesAbove
+  #     newCursorPosition = newContentLines.length - oldLinesBelow.length
+
+  #   return newCursorPosition ? 0
+
+
+  listenCollaborativeStringChanges: ->
+    filePath = @getFile().path
+
+    return if filePath.indexOf('localfile:/') > -1
+
+    string = @rtm.getFromModel filePath
+
+    @setContent string.getText(), no
+
+    @rtm.bindRealtimeListeners string, 'string'
+
+    @rtm.on 'TextInsertedIntoString', (changedString, change) =>
+      if changedString is string
+        return if @isChangedByMe change
+
+        @applyChange change
+
+    @rtm.on 'TextDeletedFromString', (changedString, change) =>
+      if changedString is string
+        return if @isChangedByMe change
+
+        @applyChange change
+
+
+  isChangedByMe: (change) ->
+    for collaborator in @rtm.getCollaborators() when collaborator.isMe
+      me = collaborator
+
+    return me.sessionId is change.sessionId
+
+
+  getRange: (index, length, str) ->
+    start   = index
+    end     = index + length
+    lines   = str.split "\n"
+    read    = 0
+    points  =
+      start : row: 0, column: 0
+      end   : row: 0, column: 0
+
+    for line in lines when read <= index
+      read                += line.length + 1
+      offset               = read - 1 - index
+      points.start.row    += 1
+      points.start.column  = line.length - offset  if read > index
+
+    points.end.row    = points.start.row
+    points.end.column = points.start.column + end - index
+
+    for lineIndex in [points.start.row...lines.length] when read <= end
+      line               = lines[lineIndex]
+      read              += line.length + 1
+      offset             = read - 1 - end
+      points.end.row    += 1
+      points.end.column  = line.length - offset  if read > end
+
+    points.start.row -= 1
+    points.end.row   -= 1
+
+    return points
+
+
+  applyChange: (change) ->
+    isInserted = change.type is 'text_inserted'
+    isDeleted  = change.type is 'text_deleted'
+    range      = @getRange change.index, change.text.length, @getContent()
+
+    @dontEmitChangeEvent = yes
+
+    if isInserted
+      @getEditorSession().insert range.start, change.text
+
+    else if isDeleted
+      @getEditorSession().remove range
+
+    @dontEmitChangeEvent = no


    file.once 'fs.delete.finished', =>
      KD.getSingleton('appManager').tell 'IDE', 'handleFileDeleted', file

  createEditor: ->
    {file, content} = @getOptions()

      @emit 'ChangeHappened', change

    ace.on 'FileContentChanged', =>
      return if @dontEmitChangeEvent

      change.type = 'ContentChange'
      change.context.file.content = @getContent()

