def populate_public_keys(users, public_keys_cache, remove_if_missing = false)
      missing = []
      users.reject! do |user|
        reject = false

        # Create any missing fingerprints from the public keys so that fingerprints
        # are as populated as possible
        user.public_key_fingerprints ||= user.public_keys.map { |key| fingerprint(key, user.username) }
        user.public_key_fingerprints = user.public_keys.zip(user.public_key_fingerprints).map do |(k, f)|
          f || fingerprint(k, user.username)
        end

        # Where possible use cache of old public keys to populate any missing ones
        public_keys = user.public_keys.zip(user.public_key_fingerprints).inject([]) do |keys, (k, f)|
          if f
            if k ||= public_keys_cache[f]
              keys << k
            else
              if remove_if_missing
                Log.error("Failed to obtain public key with fingerprint #{f.inspect} for user #{user.username}, " +
                          "removing it from login policy")
              else
                keys << k
              end
              missing << [user, f]
            end
          else
            Log.error("Failed to obtain public key with fingerprint #{f.inspect} for user #{user.username}, " +
                      "removing it from login policy")
          end
          keys
        end

        # Reject user if none of its public keys could be populated
        # This will not happen unless remove_if_missing is true
        if public_keys.empty?
          reject = true
        else
          user.public_keys = public_keys
        end
        reject
      end
      missing
    end
def populate_public_keys(users, public_keys_cache, remove_if_missing = false)
      missing = []
      users.reject! do |user|
        reject = false

        # Create any missing fingerprints from the public keys so that fingerprints
        # are as populated as possible
        user.public_key_fingerprints ||= user.public_keys.map { |key| fingerprint(key, user.username) }
        user.public_key_fingerprints = user.public_keys.zip(user.public_key_fingerprints).map do |(k, f)|
          f || fingerprint(k, user.username)
        end

        # Where possible use cache of old public keys to populate any missing ones
        public_keys = user.public_keys.zip(user.public_key_fingerprints).inject([]) do |keys, (k, f)|
          if f
            if k ||= public_keys_cache[f]
              keys << k
            else
              if remove_if_missing
                Log.error("Failed to obtain public key with fingerprint #{f.inspect} for user #{user.username}, " +
                          "removing it from login policy")
              else
                keys << k
              end
              missing << [user, f]
            end
          else
            Log.error("Failed to obtain public key with fingerprint #{f.inspect} for user #{user.username}, " +
                      "removing it from login policy")
          end
          keys
        end

        # Reject user if none of its public keys could be populated
        # This will not happen unless remove_if_missing is true
        if public_keys.empty?
          reject = true
        else
          user.public_keys = public_keys
        end
        reject
      end
      missing
    end
Populate missing public keys from old public keys using associated fingerprints
 Also populate any missing fingerprints where possible

 == Parameters:
 @param [Array<LoginUser>] Login users whose public keys are to be updated if nil
 @param [Hash<String, String>] Public keys with fingerprint as key and public key as value
 @param [Boolean] Whether to remove a user's public key if it cannot be obtained
           and the user itself if none of its public keys can be obtained

 == Returns:
 @return [Array<LoginUser,String] User and fingerprint for each missing public key