old_contents: # vim: tabstop=4 shiftwidth=4 softtabstop=4
  
  #
  #    Licensed under the Apache License, Version 2.0 (the "License"); you may
  #    not use this file except in compliance with the License. You may obtain
  #    a copy of the License at
  #
  #         http://www.apache.org/licenses/LICENSE-2.0
  #
  #    Unless required by applicable law or agreed to in writing, software
  #    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  #    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  #    License for the specific language governing permissions and limitations
  #    under the License.
  
  import pkgutil
  import sys
  import types
  
  from heat.openstack.common import log as logging
  
  logger = logging.getLogger(__name__)
  
  
  def _module_name(*components):
      return '.'.join(components)
  
  
  def create_subpackage(path, parent_package_name, subpackage_name="plugins"):
      package_name = _module_name(parent_package_name, subpackage_name)
  
      package = types.ModuleType(package_name)
      package.__path__ = [path] if isinstance(path, basestring) else list(path)
      sys.modules[package_name] = package
  
      return package
  
  
  def _import_module(importer, module_name, package):
      fullname = _module_name(package.__name__, module_name)
      if fullname in sys.modules:
          return sys.modules[fullname]
  
      loader = importer.find_module(fullname)
      if loader is None:
          return None
  
      module = loader.load_module(fullname)
      setattr(package, module_name, module)
      return module
  
  
  def load_modules(package, ignore_error=False):
      path = package.__path__
      for importer, module_name, is_package in pkgutil.walk_packages(path):
          try:
              module = _import_module(importer, module_name, package)
          except ImportError as ex:
              logger.error(_('Failed to import module %s') % module_name)
              if not ignore_error:
                  raise
          else:
              if module is not None:
                  yield module
  
new_contents: # vim: tabstop=4 shiftwidth=4 softtabstop=4
  
  #
  #    Licensed under the Apache License, Version 2.0 (the "License"); you may
  #    not use this file except in compliance with the License. You may obtain
  #    a copy of the License at
  #
  #         http://www.apache.org/licenses/LICENSE-2.0
  #
  #    Unless required by applicable law or agreed to in writing, software
  #    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  #    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  #    License for the specific language governing permissions and limitations
  #    under the License.
  
  '''
  Utilities to dynamically load plugin modules.
  
  Modules imported this way remain accessible to static imports, regardless of
  the order in which they are imported. For modules that are not part of an
  existing package tree, use create_subpackage() to dynamically create a package
  for them before loading them.
  '''
  
  import pkgutil
  import sys
  import types
  
  from heat.openstack.common import log as logging
  
  logger = logging.getLogger(__name__)
  
  
  def _module_name(*components):
      '''Assemble a fully-qualified module name from its components'''
      return '.'.join(components)
  
  
  def create_subpackage(path, parent_package_name, subpackage_name="plugins"):
      '''
      Dynamically create a package into which to load plugins.
  
      This allows us to not include an __init__.py in the plugins directory. We
      must still create a package for plugins to go in, otherwise we get warning
      messages during import. This also provides a convenient place to store the
      path(s) to the plugins directory.
      '''
      package_name = _module_name(parent_package_name, subpackage_name)
  
      package = types.ModuleType(package_name)
      package.__path__ = [path] if isinstance(path, basestring) else list(path)
      sys.modules[package_name] = package
  
      return package
  
  
  def _import_module(importer, module_name, package):
      '''
      Import a module dynamically into the specified package, given its name and
      PEP302 Importer object (which knows the path to look in).
      '''
      fullname = _module_name(package.__name__, module_name)
  
      # Duplicate copies of modules are bad, so check if this has already been
      # imported statically
      if fullname in sys.modules:
          return sys.modules[fullname]
  
      loader = importer.find_module(fullname)
      if loader is None:
          return None
  
      module = loader.load_module(fullname)
      # Make this accessible through the parent package for static imports
      setattr(package, module_name, module)
      return module
  
  
  def load_modules(package, ignore_error=False):
      '''Dynamically load all modules from a given package.'''
      path = package.__path__
      for importer, module_name, is_package in pkgutil.walk_packages(path):
          try:
              module = _import_module(importer, module_name, package)
          except ImportError as ex:
              logger.error(_('Failed to import module %s') % module_name)
              if not ignore_error:
                  raise
          else:
              if module is not None:
                  yield module
  
subject: Add documentation on plugin_loader module