You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: apply_pot.rb
    path of file: ./repos/metasploit-framework/modules/auxiliary/analyze
    
    the code of the file until where you have to start completion: ##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##


class MetasploitModule < Msf::Auxiliary
  include Msf::Auxiliary::PasswordCracker

  def initialize
    super(
      'Name'            => 'Apply Pot File To Hashes',
      'Description'     => %Q{
          This module uses a John the Ripper or Hashcat .pot file to crack any password
        hashes in the creds database instantly.  JtR's --show functionality is used to
        help combine all the passwords into an easy to use format.
      },
      'Author'          => ['h00die'],
      'License'         => MSF_LICENSE,
      'Actions'         =>
        [
          ['john', 'Description' => 'Use John the Ripper'],
          # ['hashcat', 'Description' => 'Use Hashcat'], # removed for simplicity
        ],
      'DefaultAction' => 'john',
    )
    deregister_options('ITERATION_TIMEOUT')
    deregister_options('CUSTOM_WORDLIST')
    deregister_options('KORELOGIC')
    deregister_options('MUTATE')
    deregister_options('USE_CREDS')
    deregister_options('USE_DB_INFO')
    deregister_options('USE_DEFAULT_WORDLIST')
    deregister_options('USE_ROOT_WORDS')
    deregister_options('USE_HOSTNAMES')

  end

  # Not all hash formats include an 'id' field, which corresponds which db entry
  # an item is to its hash.  This can be problematic, especially when a username
  # is used as a salt.  Due to all the variations, we make a small HashLookup
  # class to handle all the fields for easier lookup later.
  class HashLookup
    attr_accessor :db_hash
    attr_accessor :jtr_hash
    attr_accessor :username
    attr_accessor :id

    def initialize(db_hash, jtr_hash, username, id)
      @db_hash = db_hash
      @jtr_hash = jtr_hash
      @username = username
      @id = id
    end
  end

  def show_run_command(cracker_instance)
    return unless datastore['ShowCommand']
    cmd = cracker_instance.show_command
    print_status("   Cracking Command: #{cmd.join(' ')}")
  end

  def run
    cracker = new_password_cracker(action.name)

    lookups = []

    # create one massive hash file with all the hashes
    hashlist = Rex::Quickfile.new("hashes_tmp")
    framework.db.creds(workspace: myworkspace).each do |core|
      next if core.private.type == 'Metasploit::Credential::Password'
      jtr_hash = Metasploit::Framework::PasswordCracker::JtR::Formatter.hash_to_jtr(core)
      hash
    
  def run
    cracker = new_password_cracker(action.name)

    lookups = []

    # create one massive hash file with all the hashes
    hashlist = Rex::Quickfile.new("hashes_tmp")
    framework.db.creds(workspace: myworkspace).each do |core|
      next if core.private.type == 'Metasploit::Credential::Password'
      jtr_hash = Metasploit::Framework::PasswordCracker::JtR::Formatter.hash_to_jtr(core)
      hashlist.puts jtr_hash
      lookups << HashLookup.new(core.private.data, jtr_hash, core.public, core.id)
    end
    hashlist.close
    cracker.hash_path = hashlist.path
    print_status "Hashes Written out to #{hashlist.path}"
    cleanup_files = [cracker.hash_path]

    # cycle through all hash types we dump asking jtr to show us
    # cracked passwords.  The advantage to this vs just comparing
    # john.pot to the hashes directly is we use jtr to recombine
    # lanman, and other assorted nuances
    ['bcrypt', 'bsdicrypt', 'crypt', 'descrypt', 'lm', 'nt',
     'md5crypt', 'mysql', 'mysql-sha1', 'mssql', 'mssql05', 'mssql12',
     'oracle', 'oracle11', 'oracle12c', 'dynamic_1506', #oracles
     'dynamic_1034' #postgres
      ].each do |format|

      print_status("Checking #{format} hashes against pot file")
      cracker.format = format
      show_run_command(cracker)
      cracker.each_cracked_password.each do |password_line|
        password_line.chomp!
        next if password_line.blank? || password_line.nil?
        fields = password_line.split(":")
        core_id = nil
        case format
        when 'descrypt'
          next unless fields.count >=3
          username = fields.shift
          core_id  = fields.pop
          4.times { fields.pop } # Get rid of extra :
        when 'md5crypt', 'descrypt', 'bsdicrypt', 'crypt', 'bcrypt'
          next unless fields.count >=7
          username = fields.shift
          core_id  = fields.pop
          4.times { fields.pop }
        when 'mssql', 'mssql05', 'mssql12', 'mysql', 'mysql-sha1',
             'oracle', 'dynamic_1506', 'oracle11', 'oracle12c'
          next unless fields.count >=3
          username = fields.shift
          core_id  = fields.pop
        when 'dynamic_1506' #oracle H code
          next unless fields.count >=3
          username = fields.shift
          core_id  = fields.pop
        when 'dynamic_1034' #postgres
          next unless fields.count >=2
          username = fields.shift
          password = fields.join(':')
          # unfortunately to match up all the fields we need to pull the hash
          # field as well, and it is only available in the pot file.
          pot = cracker.pot || cracker.john_pot_file

          File.open(pot, 'rb').each do |line|
            if line.start_with?('$dynamic_1034$') #postgres format
              lookups.each do |l|
                pot_hash = line.split(":")[0]
                raw_pot_hash = pot_hash.split('$')[2]
                if l.username.to_s == username &&
                     l.jtr_hash == "#{username}:$dynamic_1034$#{raw_pot_hash}" &&
                     l.db_hash  == raw_pot_hash
                   core_id = l.id
                   break
                end
              end
            end
          end
        when 'lm', 'nt'
          next unless fields.count >=7
          username = fields.shift
          core_id = fields.pop
          2.times{ fields.pop }
          # get the NT and LM hashes
          nt_hash = fields.pop
          lm_hash = fields.pop
          core_id = fields.pop
          password = fields.join(':')
          if format == 'lm'
            if password.blank?
              if nt_hash == Metasploit::Credential::NTLMHash::BLANK_NT_HASH
                password = ''
              else
                next
              end