 			displayResult = (highlights) =>
 				if linesToProcess?
 					for shouldProcess, row in linesToProcess
-						@highlightedWordManager.clearRows(row, row) if shouldProcess
+						@adapter.wordManager.clearRow(row) if shouldProcess
 				else
-					@highlightedWordManager.clearRows()
+					@adapter.wordManager.reset()
 				for highlight in highlights
-					@highlightedWordManager.addHighlight highlight
+					@adapter.wordManager.addHighlight highlight
 
 			if not words.length
 				displayResult highlights

define [
	"ide/editor/directives/aceEditor/spell-check/HighlightedWordManager"
	"ace/ace"
], (HighlightedWordManager) ->
	Range = ace.require("ace/range").Range

	class SpellCheckManager
		constructor: (@$scope, @editor, @element, @cache, @$http, @$q) ->
			$(document.body).append @element.find(".spell-check-menu")
			@inProgressRequest = null
			@updatedLines = []
			@highlightedWordManager = new HighlightedWordManager(@editor)

			@$scope.$watch "spellCheckLanguage", (language, oldLanguage) =>
				if language != oldLanguage and oldLanguage?
					@runFullCheck()

			onChange = (e) =>
				@runCheckOnChange(e)
				
			onScroll = () =>
				@closeContextMenu()

			@editor.on "changeSession", (e) =>
				@highlightedWordManager.reset()
				if @inProgressRequest?
					@inProgressRequest.abort()

				if @$scope.spellCheckEnabled and @$scope.spellCheckLanguage and @$scope.spellCheckLanguage != ""
					@runSpellCheckSoon(200)

				e.oldSession?.getDocument().off "change", onChange
				e.session.getDocument().on "change", onChange
				
				e.oldSession?.off "changeScrollTop", onScroll
				e.session.on "changeScrollTop", onScroll

			@$scope.spellingMenu = {left: '0px', top: '0px'}

			@editor.on "nativecontextmenu", (e) =>
				e.domEvent.stopPropagation();
				@closeContextMenu(e.domEvent)
				@openContextMenu(e.domEvent)

			$(document).on "click", (e) =>
				if e.which != 3 # Ignore if this was a right click
					@closeContextMenu(e)
				return true

			@$scope.replaceWord = (highlight, suggestion) =>
				@replaceWord(highlight, suggestion)

			@$scope.learnWord = (highlight) =>
				@learnWord(highlight)

		runFullCheck: () ->
			@highlightedWordManager.clearRows()
			if @$scope.spellCheckLanguage and @$scope.spellCheckLanguage != ""
				@runSpellCheck()

		runCheckOnChange: (e) ->
			if @$scope.spellCheckLanguage and @$scope.spellCheckLanguage != ""
				@highlightedWordManager.applyChange(e)
				@markLinesAsUpdated(e)
				@runSpellCheckSoon()

		openContextMenu: (e) ->
			position = @editor.renderer.screenToTextCoordinates(e.clientX, e.clientY)
			highlight = @highlightedWordManager.findHighlightWithinRange
				start: position
				end:   position

			@$scope.$apply () =>
				@$scope.spellingMenu.highlight = highlight

			if highlight
				e.stopPropagation()
				e.preventDefault()

				@editor.getSession().getSelection().setSelectionRange(
					new Range(
						highlight.row, highlight.column
						highlight.row, highlight.column + highlight.word.length
					)
				)

				@$scope.$apply () =>
					@$scope.spellingMenu.open = true
					@$scope.spellingMenu.left = e.clientX + 'px'
					@$scope.spellingMenu.top = e.clientY + 'px'
				return false

		closeContextMenu: (e) ->
			# this is triggered on scroll, so for performance only apply
			# setting when it changes
			if @$scope?.spellingMenu?.open != false
				@$scope.$apply () =>
					@$scope.spellingMenu.open = false

		replaceWord: (highlight, text) ->
			@editor.getSession().replace(new Range(
				highlight.row, highlight.column,
				highlight.row, highlight.column + highlight.word.length
			), text)

		learnWord: (highlight) ->
			@apiRequest "/learn", word: highlight.word
			@highlightedWordManager.removeWord highlight.word
			language = @$scope.spellCheckLanguage
			@cache?.put("#{language}:#{highlight.word}", true)

		getHighlightedWordAtCursor: () ->
			cursor = @editor.getCursorPosition()
			highlight = @highlightedWordManager.findHighlightWithinRange
				start: cursor
				end: cursor
			return highlight

		runSpellCheckSoon: (delay = 1000) ->
			run = () =>
				delete @timeoutId
				@runSpellCheck(@updatedLines)
				@updatedLines = []
			if @timeoutId?
				clearTimeout @timeoutId
			@timeoutId = setTimeout run, delay

		markLinesAsUpdated: (change) ->
			start = change.start

						positions.push row: row, column: result.index
						words.push(word)
			return words: words, positions: positions

		blacklistedCommandRegex: ///
			\\                    # initial backslash
