void findPasswordFormFields(HTMLFormElement* form, PasswordFormFields* fields)
{
    ASSERT(form);
    ASSERT(fields);

    HTMLInputElement* latestInputElement = 0;
    const Vector<FormAssociatedElement*>& formElements = form->associatedElements();
    for (size_t i = 0; i < formElements.size(); i++) {
        if (!formElements[i]->isFormControlElement())
            continue;
        HTMLFormControlElement* control = toHTMLFormControlElement(formElements[i]);
        if (control->isActivatedSubmit())
            fields->submit = control;

        if (!control->hasTagName(HTMLNames::inputTag))
            continue;

        HTMLInputElement* inputElement = toHTMLInputElement(control);
        if (inputElement->isDisabledFormControl())
            continue;

        if ((fields->passwords.size() < maxPasswords)
                && inputElement->isPasswordField()) {
            // We assume that the username is the input element before the
            // first password element.
            if (fields->passwords.isEmpty() && latestInputElement) {
                fields->userName = latestInputElement;
                // Remove the selected username from alternateUserNames.
                if (!fields->alternateUserNames.isEmpty() && !latestInputElement->value().isEmpty())
                    fields->alternateUserNames.removeLast();
            }
            fields->passwords.append(inputElement);
        }

        // Various input types such as text, url, email can be a username field.
        if (inputElement->isTextField() && !inputElement->isPasswordField()) {
            latestInputElement = inputElement;
            // We ignore elements that have no value. Unlike userName, alternateUserNames
            // is used only for autofill, not for form identification, and blank autofill
            // entries are not useful.
            if (!inputElement->value().isEmpty())
                fields->alternateUserNames.append(inputElement->value());
        }
    }
}