docs: def _check_resolution_needed(path, project, folderpath, entity_name, expected_classes=None, describe=True,
                               enclose_in_list=False):
      """
      :param path: Path to the object that required resolution; propagated from
                   command-line
      :type path: string
      :param project: The potential project the entity belongs to
      :type project: string
      :param folderpath: Path to the entity
      :type folderpath: string
      :param entity_name: The name of the entity
      :type entity_name: string
      :param expected_classes: A list of expected classes the entity is allowed
                               to belong to if it is an ID (e.g. "record",
                               "file", "job"); if None, then entity_name may be
                               any data object class
      :type expected_classes: list or None
      :param describe: Dictionary of inputs to the describe API call; if
                       no describe input is provided (default value True), then
                       an empty mapping is passed to the describe API method
      :type describe: dict or True
      :param enclose_in_list: Whether the describe output is to be in the form
                              of a list (if False, the last return value is a
                              dictionary; if True, the last return value is a
                              list of one dictionary); it will only have an
                              effect if entity_name is a DX ID and is described
      :type enclose_in_list: boolean
      :returns: Whether or not the entity needs to be resolved with a more
                general resolution method, the project, the folderpath, and the
                entity name
      :rtype: tuple of 4 elements
      :raises: ResolutionError if the entity fails to be described
  
      Attempts to resolve the entity to a folder or an object, and describes
      the entity iff it is a DX ID of an expected class in the list
      expected_classes.
      Otherwise, determines whether or not more general resolution may be able
      to resolve the entity.
  
      If a more general resolution method is needed, then the return values will
      look like:
      (True, <project>, <folderpath>, <entity_name>)
  
      If the entity is a DX ID, but is not one of the supplied expected
      classes, then the return values will look like:
      (False, None, None, None)
  
      If the entity can be successfully described, then the return values will
      look like:
      <desc_output> ::= {"id": entity_name, "describe": {...}}
      <desc_or_desc_list> ::= <desc_output> || [<desc_output>]
      (False, <project>, <folderpath>, <desc_or_desc_list>)
  
      If the entity may be a folder, then the return values will look like:
      (False, <project>, <folderpath>, None)
  
      TODO: Allow arbitrary flags for the describe mapping.
      """
      if entity_name is None:
          # Definitely a folder (or project)
          # TODO: find a good way to check if folder exists and expected=folder
          return False, project, folderpath, None
      elif is_hashid(entity_name):
  
          found_valid_class = True
          if expected_classes is not None:
              found_valid_class = False
              for klass in expected_classes:
                  if entity_name.startswith(klass):
                      found_valid_class = True
          if not found_valid_class:
              return False, None, None, None
  
          if describe is True:
              describe = {}
  
          # entity is an ID of a valid class, try to describe it
          if 'project' not in describe:
              if project != dxpy.WORKSPACE_ID:
                  describe['project'] = project
              elif dxpy.WORKSPACE_ID is not None:
                  describe['project'] = dxpy.WORKSPACE_ID
          try:
              desc = dxpy.DXHTTPRequest('/' + entity_name + '/describe', describe)
              desc = dxpy.append_underlying_workflow_describe(desc)
          except Exception as details:
              if 'project' in describe:
                  # Now try it without the hint
                  del describe['project']
                  try:
                      desc = dxpy.DXHTTPRequest('/' + entity_name + '/describe', describe)
                  except Exception as details2:
                      raise ResolutionError(str(details2))
              else:
                  raise ResolutionError(str(details))
          result = {"id": entity_name, "describe": desc}
          if enclose_in_list:
              return False, project, folderpath, [result]
          else:
              return False, project, folderpath, result
  
      else:
          # Need to resolve later
          return True, project, folderpath, entity_name