     @emit 'stylesheets-changed'
     @emitter.emit 'did-change-stylesheets'
 
+  ###
+  Section: Private
+  ###
+
+  stringToId: (string) ->
+    string.replace(/\\/g, '/')
+
+  activateThemes: ->
+    deferred = Q.defer()
+
+    # atom.config.observe runs the callback once, then on subsequent changes.
+    atom.config.observe 'core.themes', =>
+      @deactivateThemes()
+
+      @refreshLessCache() # Update cache for packages in core.themes config
+
+      promises = []
+      for themeName in @getEnabledThemeNames()
+        if @packageManager.resolvePackagePath(themeName)
+          promises.push(@packageManager.activatePackage(themeName))
+        else
+          console.warn("Failed to activate theme '#{themeName}' because it isn't installed.")
+
+      Q.all(promises).then =>
+        @addActiveThemeClasses()
+        @refreshLessCache() # Update cache again now that @getActiveThemes() is populated
+        @loadUserStylesheet()
+        @reloadBaseStylesheets()
+        @initialLoadComplete = true
+        @emit 'reloaded'
+        @emitter.emit 'did-reload-all'
+        deferred.resolve()
+
+    deferred.promise
+
+  deactivateThemes: ->
+    @removeActiveThemeClasses()
+    @unwatchUserStylesheet()
+    @packageManager.deactivatePackage(pack.name) for pack in @getActiveThemes()
+    null
+
+  isInitialLoadComplete: -> @initialLoadComplete
+
+  addActiveThemeClasses: ->
+    for pack in @getActiveThemes()
+      atom.workspaceView?[0]?.classList.add("theme-#{pack.name}")
+    return
+
+  removeActiveThemeClasses: ->
+    for pack in @getActiveThemes()
+      atom.workspaceView?[0]?.classList.remove("theme-#{pack.name}")
+    return
+
+  refreshLessCache: ->
+    @lessCache?.setImportPaths(@getImportPaths())
+
+  getImportPaths: ->
+    activeThemes = @getActiveThemes()
+    if activeThemes.length > 0
+      themePaths = (theme.getStylesheetsPath() for theme in activeThemes when theme)
+    else
+      themePaths = []
+      for themeName in @getEnabledThemeNames()
+        if themePath = @packageManager.resolvePackagePath(themeName)
+          themePaths.push(path.join(themePath, Package.stylesheetsDir))
+
+    themePaths.filter (themePath) -> fs.isDirectorySync(themePath)
+
   updateGlobalEditorStyle: (property, value) ->
     unless styleNode = @stylesheetElementForId('global-editor-styles')
       @applyStylesheet('global-editor-styles', '.editor {}')

    # the first/top theme to override later themes in the stack.
    themeNames.reverse()

  activateThemes: ->
    deferred = Q.defer()

    # atom.config.observe runs the callback once, then on subsequent changes.
    atom.config.observe 'core.themes', =>
      @deactivateThemes()

      @refreshLessCache() # Update cache for packages in core.themes config

      promises = []
      for themeName in @getEnabledThemeNames()
        if @packageManager.resolvePackagePath(themeName)
          promises.push(@packageManager.activatePackage(themeName))
        else
          console.warn("Failed to activate theme '#{themeName}' because it isn't installed.")

      Q.all(promises).then =>
        @addActiveThemeClasses()
        @refreshLessCache() # Update cache again now that @getActiveThemes() is populated
        @loadUserStylesheet()
        @reloadBaseStylesheets()
        @initialLoadComplete = true
        @emit 'reloaded'
        @emitter.emit 'did-reload-all'
        deferred.resolve()

    deferred.promise

  deactivateThemes: ->
    @removeActiveThemeClasses()
    @unwatchUserStylesheet()
    @packageManager.deactivatePackage(pack.name) for pack in @getActiveThemes()
    null

  isInitialLoadComplete: -> @initialLoadComplete

  addActiveThemeClasses: ->
    for pack in @getActiveThemes()
      atom.workspaceView?[0]?.classList.add("theme-#{pack.name}")
    return

  removeActiveThemeClasses: ->
    for pack in @getActiveThemes()
      atom.workspaceView?[0]?.classList.remove("theme-#{pack.name}")
    return

  refreshLessCache: ->
    @lessCache?.setImportPaths(@getImportPaths())

  # Public: Set the list of enabled themes.
  #
  # * `enabledThemeNames` An {Array} of {String} theme names.
  setEnabledThemes: (enabledThemeNames) ->
    atom.config.set('core.themes', enabledThemeNames)

  getImportPaths: ->
    activeThemes = @getActiveThemes()
    if activeThemes.length > 0
      themePaths = (theme.getStylesheetsPath() for theme in activeThemes when theme)
    else
      themePaths = []
      for themeName in @getEnabledThemeNames()
        if themePath = @packageManager.resolvePackagePath(themeName)
          themePaths.push(path.join(themePath, Package.stylesheetsDir))

    themePaths.filter (themePath) -> fs.isDirectorySync(themePath)

  # Public: Returns the {String} path to the user's stylesheet under ~/.atom
  getUserStylesheetPath: ->

      fs.resolveOnLoadPath(stylesheetPath)
    else
      fs.resolveOnLoadPath(stylesheetPath, ['css', 'less'])

  loadStylesheet: (stylesheetPath, importFallbackVariables) ->
    if path.extname(stylesheetPath) is '.less'
