'Returns a form that lets the user change password'

def change_password(self, next=DEFAULT, onvalidation=DEFAULT, onaccept=DEFAULT, log=DEFAULT):

    if (not self.is_logged_in()):
        redirect(self.settings.login_url, client_side=self.settings.client_side)
    messages = self.messages
    settings = self.settings
    utable = settings.table_user
    s = self.db((utable.id == self.user.id))
    request = current.request
    session = current.session
    if (next is DEFAULT):
        next = (self.get_vars_next() or settings.change_password_next)
    if (onvalidation is DEFAULT):
        onvalidation = settings.change_password_onvalidation
    if (onaccept is DEFAULT):
        onaccept = settings.change_password_onaccept
    if (log is DEFAULT):
        log = messages['change_password_log']
    passfield = settings.password_field
    form = SQLFORM.factory(Field('old_password', 'password', label=messages.old_password, requires=utable[passfield].requires), Field('new_password', 'password', label=messages.new_password, requires=utable[passfield].requires), Field('new_password2', 'password', label=messages.verify_password, requires=[IS_EXPR(('value==%s' % repr(request.vars.new_password)), messages.mismatched_password)]), submit_button=messages.password_change_button, hidden=dict(_next=next), formstyle=current.deployment_settings.get_ui_formstyle(), separator=settings.label_separator)
    form.add_class('auth_change_password')
    if form.accepts(request, session, formname='change_password', onvalidation=onvalidation, hideerror=settings.hideerror):
        if (not (form.vars['old_password'] == s.select(limitby=(0, 1), orderby_on_limitby=False).first()[passfield])):
            form.errors['old_password'] = messages.invalid_password
        else:
            d = {passfield: str(form.vars.new_password)}
            s.update(**d)
            session.confirmation = messages.password_changed
            self.log_event(log, self.user)
            callback(onaccept, form)
            if (not next):
                next = self.url(args=request.args)
            else:
                next = replace_id(next, form)
            redirect(next, client_side=settings.client_side)
    return form
