Iterate through given file list and extract all files matching the file
  format list from each RAR file. After sucessful extraction move RAR files to
  archive directory.

  Parameters
  ----------
    fileList : list
      List of files to attempt to extract.

    fileFormatList : list
      List of file formats to extract from each RAR archive.

    archiveDir : string
      Directory to move RAR files once extract is complete.

    skipUserInput : boolean
      Set to skip any potential user input (if a single option is available
      it will be selected otherwise the user input will default to take no action).

def Extract(fileList, fileFormatList, archiveDir, skipUserInput):
  """
  Iterate through given file list and extract all files matching the file
  format list from each RAR file. After sucessful extraction move RAR files to
  archive directory.

  Parameters
  ----------
    fileList : list
      List of files to attempt to extract.

    fileFormatList : list
      List of file formats to extract from each RAR archive.

    archiveDir : string
      Directory to move RAR files once extract is complete.

    skipUserInput : boolean
      Set to skip any potential user input (if a single option is available
      it will be selected otherwise the user input will default to take no action).
  """
  goodlogging.Log.Info("EXTRACT", "Extracting files from compressed archives")
  goodlogging.Log.IncreaseIndent()
  if len(fileList) == 0:
    goodlogging.Log.Info("EXTRACT", "No files to extract")
    goodlogging.Log.DecreaseIndent()
    return None

  firstPartExtractList = []
  otherPartSkippedList = []

  lastPassword = False
  reuseLastPassword = 0
  for filePath in fileList:
    goodlogging.Log.Info("EXTRACT", "{0}".format(filePath))
    goodlogging.Log.IncreaseIndent()
    try:
      rarArchive = rarfile.RarFile(filePath)
    except ImportError:
      goodlogging.Log.Info("EXTRACT", "Unable to extract - Python needs the rarfile package to be installed (see README for more details)")
    except rarfile.NeedFirstVolume:
      goodlogging.Log.Info("EXTRACT", "File skipped - this is not the first part of the RAR archive")
      MultipartArchiving(firstPartExtractList, otherPartSkippedList, archiveDir, filePath)
    except BaseException as ex:
      goodlogging.Log.Info("EXTRACT", "Unable to extract - Exception: {0}".format(ex))
    else:
      dirPath = os.path.dirname(filePath)
      fileExtracted = False
      rarAuthentication = True

      if rarArchive.needs_password():
        if lastPassword and reuseLastPassword in (0, 1):
          reuseLastPassword = CheckPasswordReuse(skipUserInput)

        if lastPassword and reuseLastPassword in (1, 2):
          rarArchive.setpassword(lastPassword)
        else:
          rarPassword = GetRarPassword(skipUserInput)

          if rarPassword:
            rarArchive.setpassword(rarPassword)
            lastPassword = rarPassword
          else:
            rarAuthentication = False

      if rarAuthentication:
        for f in rarArchive.infolist():
          if util.FileExtensionMatch(f.filename, fileFormatList):
            goodlogging.Log.Info("EXTRACT", "Extracting file: {0}".format(f.filename))

            extractPath = os.path.join(dirPath, f.filename)
            targetPath = os.path.join(dirPath, os.path.basename(f.filename))

            if os.path.isfile(targetPath):
              goodlogging.Log.Info("EXTRACT", "Extraction skipped - file already exists at target: {0}".format(targetPath))
              fileExtracted = True
            elif os.path.isfile(extractPath):
              goodlogging.Log.Info("EXTRACT", "Extraction skipped - file already exists at extract directory: {0}".format(extractPath))
              fileExtracted = True
            else:
              fileExtracted = DoRarExtraction(rarArchive, f, dirPath)

            if os.path.isfile(extractPath) and not os.path.isfile(targetPath):
              os.rename(extractPath, targetPath)
              util.RemoveEmptyDirectoryTree(os.path.dirname(extractPath))

      if fileExtracted is True:
        util.ArchiveProcessedFile(filePath, archiveDir)

        try:
          firstPartFileName = re.findall('(.+?)[.]part1[.]rar', filePath)[0]
        except IndexError:
          pass
        else:
          firstPartExtractList.append(firstPartFileName)
          MultipartArchiving(firstPartExtractList, otherPartSkippedList, archiveDir)

    finally:
      goodlogging.Log.DecreaseIndent()
  goodlogging.Log.DecreaseIndent()