     commandName += '.cmd' if process.platform is 'win32'
     @apmPath ?= path.resolve(__dirname, '..', 'apm', 'node_modules', 'atom-package-manager', 'bin', commandName)
 
-  # Extended: Get the paths being used to look for packages.
+  # Public: Get the paths being used to look for packages.
   #
   # Returns an {Array} of {String} directory paths.
   getPackageDirPaths: ->
     _.clone(@packageDirPaths)
 
-  getPackageState: (name) ->
-    @packageStates[name]
-
-  setPackageState: (name, state) ->
-    @packageStates[name] = state
-
-  # Extended: Enable the package with the given name.
+  ###
+  Section: General package data
+  ###
+
+  # Public: Resolve the given package name to a path on disk.
+  #
+  # * `name` - The {String} package name.
+  #
+  # Return a {String} folder path or undefined if it could not be resolved.
+  resolvePackagePath: (name) ->
+    return name if fs.isDirectorySync(name)
+
+    packagePath = fs.resolve(@packageDirPaths..., name)
+    return packagePath if fs.isDirectorySync(packagePath)
+
+    packagePath = path.join(@resourcePath, 'node_modules', name)
+    return packagePath if @hasAtomEngine(packagePath)
+
+  # Public: Is the package with the given name bundled with Atom?
+  #
+  # * `name` - The {String} package name.
+  #
+  # Returns a {Boolean}.
+  isBundledPackage: (name) ->
+    @getPackageDependencies().hasOwnProperty(name)
+
+  ###
+  Section: Enabling and disabling packages
+  ###
+
+  # Public: Enable the package with the given name.
   #
   # Returns the {Package} that was enabled or null if it isn't loaded.
   enablePackage: (name) ->

    pack?.enable()
    pack

  # Extended: Disable the package with the given name.
  #
  # Returns the {Package} that was disabled or null if it isn't loaded.
  disablePackage: (name) ->

  # Returns a {Boolean}.
  isPackageActive: (name) ->
    @getActivePackage(name)?

  ###
  Section: Accessing loaded packages
  ###

  # Public: Get an {Array} of all the loaded {Package}s
  getLoadedPackages: ->
    _.values(@loadedPackages)

  # Get packages for a certain package type
  #
  # * `types` an {Array} of {String}s like ['atom', 'textmate'].
  getLoadedPackagesForTypes: (types) ->
    pack for pack in @getLoadedPackages() when pack.getType() in types

  # Public: Get the loaded {Package} with the given name.
  #
  # * `name` - The {String} package name.
  #
  # Returns a {Package} or undefined.
  getLoadedPackage: (name) ->
    @loadedPackages[name]

  # Public: Is the package with the given name loaded?
  #
  # * `name` - The {String} package name.
  #
  # Returns a {Boolean}.
  isPackageLoaded: (name) ->
    @getLoadedPackage(name)?

  ###
  Section: Accessing available packages
  ###

  # Public: Get an {Array} of {String}s of all the available package paths.
  getAvailablePackagePaths: ->
    packagePaths = []

    for packageDirPath in @packageDirPaths
      for packagePath in fs.listSync(packageDirPath)
        packagePaths.push(packagePath) if fs.isDirectorySync(packagePath)

    packagesPath = path.join(@resourcePath, 'node_modules')
    for packageName, packageVersion of @getPackageDependencies()
      packagePath = path.join(packagesPath, packageName)
      packagePaths.push(packagePath) if fs.isDirectorySync(packagePath)

    _.uniq(packagePaths)

  # Public: Get an {Array} of {String}s of all the available package names.
  getAvailablePackageNames: ->
    _.uniq _.map @getAvailablePackagePaths(), (packagePath) -> path.basename(packagePath)

  # Public: Get an {Array} of {String}s of all the available package metadata.
  getAvailablePackageMetadata: ->
    packages = []
    for packagePath in @getAvailablePackagePaths()
      name = path.basename(packagePath)
      metadata = @getLoadedPackage(name)?.metadata ? Package.loadMetadata(packagePath, true)
      packages.push(metadata)
    packages

  ###
  Section: Private
  ###

  getPackageState: (name) ->
    @packageStates[name]

  setPackageState: (name, state) ->
    @packageStates[name] = state

  getPackageDependencies: ->
    unless @packageDependencies?
      try
        metadataPath = path.join(@resourcePath, 'package.json')
        {@packageDependencies} = JSON.parse(fs.readFileSync(metadataPath)) ? {}
      @packageDependencies ?= {}

    @packageDependencies

  hasAtomEngine: (packagePath) ->
    metadata = Package.loadMetadata(packagePath, true)
    metadata?.engines?.atom?

  unobserveDisabledPackages: ->
    @disabledPackagesSubscription?.off()
