     @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 {}')

  getActiveThemes: ->
    pack for pack in @packageManager.getActivePackages() when pack.isTheme()

  # Public: Get an array of all the loaded themes.
  getLoadedThemes: ->
    pack for pack in @packageManager.getLoadedPackages() when pack.isTheme()

  activatePackages: -> @activateThemes()

  # Get the enabled theme names from the config.
  #
  # Returns an array of theme names in the order that they should be activated.
  getEnabledThemeNames: ->

    EmitterMixin::on.apply(this, arguments)

  ###
  Section: Accessing Available Themes
  ###

  getAvailableNames: ->
    # TODO: Maybe should change to list all the available themes out there?
    @getLoadedNames()

  ###
  Section: Accessing Loaded Themes
  ###

  # Public: Get an array of all the loaded theme names.
  getLoadedNames: ->
    theme.name for theme in @getLoadedThemes()

  # Public: Get an array of all the loaded themes.
  getLoadedThemes: ->
    pack for pack in @packageManager.getLoadedPackages() when pack.isTheme()

  ###
  Section: Accessing Active Themes
  ###

  # Public: Get an array of all the active theme names.
  getActiveNames: ->
    theme.name for theme in @getActiveThemes()
