text: (function () {
    // for convenience
    var loginButtonsSession = Accounts._loginButtonsSession;
  
  
    //
    // populate the session so that the appropriate dialogs are
    // displayed by reading variables set by accounts-urls, which parses
    // special URLs. since accounts-ui depends on accounts-urls, we are
    // guaranteed to have these set at this point.
    //
  
    if (Accounts._resetPasswordToken) {
      loginButtonsSession.set('resetPasswordToken', Accounts._resetPasswordToken);
    }
  
    if (Accounts._enrollAccountToken) {
      loginButtonsSession.set('enrollAccountToken', Accounts._enrollAccountToken);
    }
  
    // Needs to be in Meteor.startup because of a package loading order
    // issue. We can't be sure that accounts-password is loaded earlier
    // than accounts-ui so Accounts.verifyEmail might not be defined.
    Meteor.startup(function () {
      if (Accounts._verifyEmailToken) {
        Accounts.verifyEmail(Accounts._verifyEmailToken, function(error) {
          Accounts._enableAutoLogin();
          if (!error)
            loginButtonsSession.set('justVerifiedEmail', true);
          // XXX show something if there was an error.
        });
      }
    });
  
  
    //
    // resetPasswordDialog template
    //
    Template._resetPasswordDialog.rendered = function() {
      var $modal = $(this.find('#login-buttons-reset-password-modal'));
      $modal.modal();
    }
  
    Template._resetPasswordDialog.events({
      'click #login-buttons-reset-password-button': function () {
        resetPassword();
      },
      'keypress #reset-password-new-password': function (event) {
        if (event.keyCode === 13)
          resetPassword();
      },
      'click #login-buttons-cancel-reset-password': function () {
        loginButtonsSession.set('resetPasswordToken', null);
        Accounts._enableAutoLogin();
        $('#login-buttons-reset-password-modal').modal("hide");
      }
    });
  
    var resetPassword = function () {
      loginButtonsSession.resetMessages();
      var newPassword = document.getElementById('reset-password-new-password').value;
      if (!Accounts._loginButtons.validatePassword(newPassword))
        return;
  
      Accounts.resetPassword(
        loginButtonsSession.get('resetPasswordToken'), newPassword,
        function (error) {
          if (error) {
            loginButtonsSession.errorMessage(error.reason || "Unknown error");
          } else {
            loginButtonsSession.set('resetPasswordToken', null);
            Accounts._enableAutoLogin();
            $('#login-buttons-reset-password-modal').modal("hide");
          }
        });
    };
  
    Template._resetPasswordDialog.inResetPasswordFlow = function () {
      return loginButtonsSession.get('resetPasswordToken');
    };
  
  
    //
    // enrollAccountDialog template
    //
  
    Template._enrollAccountDialog.events({
      'click #login-buttons-enroll-account-button': function () {
        enrollAccount();
      },
      'keypress #enroll-account-password': function (event) {
        if (event.keyCode === 13)
          enrollAccount();
      },
      'click #login-buttons-cancel-enroll-account-button': function () {
        loginButtonsSession.set('enrollAccountToken', null);
        Accounts._enableAutoLogin();
        $modal.modal("hide");
      }
    });
  
    Template._enrollAccountDialog.rendered = function() {
      $modal = $(this.find('#login-buttons-enroll-account-modal'));
      $modal.modal();
    };
  
    var enrollAccount = function () {
      loginButtonsSession.resetMessages();
      var password = document.getElementById('enroll-account-password').value;
      if (!Accounts._loginButtons.validatePassword(password))
        return;
  
      Accounts.resetPassword(
        loginButtonsSession.get('enrollAccountToken'), password,
        function (error) {
          if (error) {
            loginButtonsSession.errorMessage(error.reason || "Unknown error");
          } else {
            loginButtonsSession.set('enrollAccountToken', null);
            Accounts._enableAutoLogin();
            $modal.modal("hide");
          }
        });
    };
  
    Template._enrollAccountDialog.inEnrollAccountFlow = function () {
      return loginButtonsSession.get('enrollAccountToken');
    };
  
  
    //
    // justVerifiedEmailDialog template
    //
  
    Template._justVerifiedEmailDialog.events({
      'click #just-verified-dismiss-button': function () {
        loginButtonsSession.set('justVerifiedEmail', false);
      }
    });
  
    Template._justVerifiedEmailDialog.visible = function () {
      return loginButtonsSession.get('justVerifiedEmail');
    };
  
  
    //
    // loginButtonsMessagesDialog template
    //
  
    // Template._loginButtonsMessagesDialog.rendered = function() {
    //   var $modal = $(this.find('#configure-login-service-dialog-modal'));
    //   $modal.modal();
    // }
  
    Template._loginButtonsMessagesDialog.events({
      'click #messages-dialog-dismiss-button': function () {
        loginButtonsSession.resetMessages();
      }
    });
  
    Template._loginButtonsMessagesDialog.visible = function () {
      var hasMessage = loginButtonsSession.get('infoMessage') || loginButtonsSession.get('errorMessage');
      return !Accounts._loginButtons.dropdown() && hasMessage;
    };
  
  
    //
    // configureLoginServiceDialog template
    //
  
    Template._configureLoginServiceDialog.events({
      'click .configure-login-service-dismiss-button': function () {
        loginButtonsSession.set('configureLoginServiceDialogVisible', false);
      },
      'click #configure-login-service-dialog-save-configuration': function () {
        if (loginButtonsSession.get('configureLoginServiceDialogVisible') &&
            ! loginButtonsSession.get('configureLoginServiceDialogSaveDisabled')) {
          // Prepare the configuration document for this login service
          var serviceName = loginButtonsSession.get('configureLoginServiceDialogServiceName');
          var configuration = {
            service: serviceName
          };
          _.each(configurationFields(), function(field) {
            configuration[field.property] = document.getElementById(
              'configure-login-service-dialog-' + field.property).value
              .replace(/^\s*|\s*$/g, ""); // trim;
          });
  
          // Configure this login service
          Meteor.call("configureLoginService", configuration, function (error, result) {
            if (error)
              Meteor._debug("Error configuring login service " + serviceName, error);
            else
              loginButtonsSession.set('configureLoginServiceDialogVisible', false);
          });
        }
      },
      // IE8 doesn't support the 'input' event, so we'll run this on the keyup as
      // well. (Keeping the 'input' event means that this also fires when you use
      // the mouse to change the contents of the field, eg 'Cut' menu item.)
      'input, keyup input': function (event) {
        // if the event fired on one of the configuration input fields,
        // check whether we should enable the 'save configuration' button
        if (event.target.id.indexOf('configure-login-service-dialog') === 0)
          updateSaveDisabled();
      }
    });
  
    // check whether the 'save configuration' button should be enabled.
    // this is a really strange way to implement this and a Forms
    // Abstraction would make all of this reactive, and simpler.
    var updateSaveDisabled = function () {
      var anyFieldEmpty = _.any(configurationFields(), function(field) {
        return document.getElementById(
          'configure-login-service-dialog-' + field.property).value === '';
      });
  
      loginButtonsSession.set('configureLoginServiceDialogSaveDisabled', anyFieldEmpty);
    };
  
    // Returns the appropriate template for this login service.  This
    // template should be defined in the service's package
    var configureLoginServiceDialogTemplateForService = function () {
      var serviceName = loginButtonsSession.get('configureLoginServiceDialogServiceName');
      return Template['configureLoginServiceDialogFor' + capitalize(serviceName)];
    };
  
    var configurationFields = function () {
      var template = configureLoginServiceDialogTemplateForService();
      return template.fields();
    };
  
    Template._configureLoginServiceDialog.configurationFields = function () {
      return configurationFields();
    };
  
    Template._configureLoginServiceDialog.visible = function () {
      return loginButtonsSession.get('configureLoginServiceDialogVisible');
    };
  
    Template._configureLoginServiceDialog.configurationSteps = function () {
      // renders the appropriate template
      return configureLoginServiceDialogTemplateForService()();
    };
  
    Template._configureLoginServiceDialog.saveDisabled = function () {
      return loginButtonsSession.get('configureLoginServiceDialogSaveDisabled');
    };
  
  
    // XXX from http://epeli.github.com/underscore.string/lib/underscore.string.js
    var capitalize = function(str){
      str = str == null ? '' : String(str);
      return str.charAt(0).toUpperCase() + str.slice(1);
    };
  
  }) ();
  