text: import subprocess
  import sys
  
  from paver import tasks
  #needed for paver.easy.* import
  from paver.options import Bunch
  
  def dry(message, func, *args, **kw):
      """Wraps a function that performs a destructive operation, so that
      nothing will happen when a dry run is requested.
  
      Runs func with the given arguments and keyword arguments. If this
      is a dry run, print the message rather than running the function."""
      if message is not None:
          info(message)
      if tasks.environment.dry_run:
          return
      return func(*args, **kw)
  
  def error(message, *args):
      """Displays an error message to the user."""
      tasks.environment.error(message, *args)
  
  def info(message, *args):
      """Displays a message to the user. If the quiet option is specified, the
      message will not be displayed."""
      tasks.environment.info(message, *args)
  
  def debug(message, *args):
      """Displays a message to the user, but only if the verbose flag is
      set."""
      tasks.environment.debug(message, *args)
  
  def sh(command, capture=False, ignore_error=False, cwd=None):
      """Runs an external command. If capture is True, the output of the
      command will be captured and returned as a string.  If the command 
      has a non-zero return code raise a BuildFailure. You can pass
      ignore_error=True to allow non-zero return codes to be allowed to
      pass silently, silently into the night.  If you pass cwd='some/path'
      paver will chdir to 'some/path' before exectuting the command.
      
      If the dry_run option is True, the command will not
      actually be run."""
      def runpipe():
          kwargs = { 'shell': True, 'cwd': cwd}
          if capture:
              kwargs['stderr'] = subprocess.STDOUT
              kwargs['stdout'] = subprocess.PIPE
          p = subprocess.Popen(command, **kwargs)
          p_stdout = p.communicate()[0]
          if p_stdout is not None:
              p_stdout = p_stdout.decode(sys.getdefaultencoding(), 'ignore')
          if p.returncode and not ignore_error:
              if capture and p_stdout is not None:
                  error(p_stdout)
              raise BuildFailure("Subprocess return code: %d" % p.returncode)
  
          if capture:
              return p_stdout
  
      return dry(command, runpipe)
  
  
  class _SimpleProxy(object):
      __initialized = False
      def __init__(self, rootobj, name):
          self.__rootobj = rootobj
          self.__name = name
          self.__initialized = True
      
      def __get_object(self):
          return getattr(self.__rootobj, self.__name)
          
      def __getattr__(self, attr):
          return getattr(self.__get_object(), attr)
      
      def __setattr__(self, attr, value):
          if self.__initialized:
              setattr(self.__get_object(), attr, value)
          else:
              super(_SimpleProxy, self).__setattr__(attr, value)
              
      def __call__(self, *args, **kw):
          return self.__get_object()(*args, **kw)
      
      def __str__(self):
          return str(self.__get_object())
      
      def __repr__(self):
          return repr(self.__get_object())
  
  environment = _SimpleProxy(tasks, "environment")
  options = _SimpleProxy(environment, "options")
  call_task = _SimpleProxy(environment, "call_task")
  
  call_pavement = tasks.call_pavement
  task = tasks.task
  needs = tasks.needs
  might_call = tasks.might_call
  cmdopts = tasks.cmdopts
  consume_args = tasks.consume_args
  consume_nargs = tasks.consume_nargs
  no_auto = tasks.no_auto
  no_help = tasks.no_help
  BuildFailure = tasks.BuildFailure
  PavementError = tasks.PavementError
  
  # these are down here to avoid circular dependencies. Ideally, nothing would
  # be using paver.easy other than pavements.
  from paver.path import path, pushd
  
  import paver.misctasks
  