docs: def download_folder(project, destdir, folder="/", overwrite=False, chunksize=dxfile.DEFAULT_BUFFER_SIZE,
                      show_progress=False, **kwargs):
      '''
      :param project: Project ID to use as context for this download.
      :type project: string
      :param destdir: Local destination location
      :type destdir: string
      :param folder: Path to the remote folder to download
      :type folder: string
      :param overwrite: Overwrite existing files
      :type overwrite: boolean
  
      Downloads the contents of the remote *folder* of the *project* into the local directory specified by *destdir*.
  
      Example::
  
          download_folder("project-xxxx", "/home/jsmith/input", folder="/input")
  
      '''
  
      def ensure_local_dir(d):
          if not os.path.isdir(d):
              if os.path.exists(d):
                  raise DXFileError("Destination location '{}' already exists and is not a directory".format(d))
              logger.debug("Creating destination directory: '%s'", d)
              os.makedirs(d)
  
      def compose_local_dir(d, remote_folder, remote_subfolder):
          suffix = remote_subfolder[1:] if remote_folder == "/" else remote_subfolder[len(remote_folder) + 1:]
          if os.sep != '/':
              suffix = suffix.replace('/', os.sep)
          return os.path.join(d, suffix) if suffix != "" else d
  
      normalized_folder = folder.strip()
      if normalized_folder != "/" and normalized_folder.endswith("/"):
          normalized_folder = normalized_folder[:-1]
      if normalized_folder == "":
          raise DXFileError("Invalid remote folder name: '{}'".format(folder))
      normalized_dest_dir = os.path.normpath(destdir).strip()
      if normalized_dest_dir == "":
          raise DXFileError("Invalid destination directory name: '{}'".format(destdir))
      # Creating target directory tree
      remote_folders = list(list_subfolders(project, normalized_folder, recurse=True))
      if len(remote_folders) <= 0:
          raise DXFileError("Remote folder '{}' not found".format(normalized_folder))
      remote_folders.sort()
      for remote_subfolder in remote_folders:
          ensure_local_dir(compose_local_dir(normalized_dest_dir, normalized_folder, remote_subfolder))
  
      # Downloading files
      describe_input = dict(fields=dict(folder=True,
                                        name=True,
                                        id=True,
                                        parts=True,
                                        size=True,
                                        drive=True,
                                        md5=True))
  
      # A generator that returns the files one by one. We don't want to materialize it, because
      # there could be many files here.
      files_gen = dxpy.search.find_data_objects(classname='file', state='closed', project=project,
                                                folder=normalized_folder, recurse=True, describe=describe_input)
      if files_gen is None:
          # In python 3, the generator can be None, and iterating on it
          # will cause an error.
          return
  
      # Now it is safe, in both python 2 and 3, to iterate on the generator
      for remote_file in files_gen:
          local_filename = os.path.join(compose_local_dir(normalized_dest_dir,
                                                          normalized_folder,
                                                          remote_file['describe']['folder']),
                                        remote_file['describe']['name'])
          if os.path.exists(local_filename) and not overwrite:
              raise DXFileError(
                  "Destination file '{}' already exists but no overwrite option is provided".format(local_filename)
              )
          logger.debug("Downloading '%s/%s' remote file to '%s' location",
                       ("" if remote_file['describe']['folder'] == "/" else remote_file['describe']['folder']),
                       remote_file['describe']['name'],
                       local_filename)
          download_dxfile(remote_file['describe']['id'],
                          local_filename,
                          chunksize=chunksize,
                          project=project,
                          show_progress=show_progress,
                          describe_output=remote_file['describe'],
                          **kwargs)