docs: function (options) {
    // Unknown keys allowed, because a onCreateUserHook can take arbitrary
    // options.
    check(options, Match.ObjectIncluding({
      username: Match.Optional(String),
      email: Match.Optional(String),
      password: Match.Optional(String),
      srp: Match.Optional(SRP.matchVerifier)
    }));
  
    var username = options.username;
    var email = options.email;
    if (!username && !email)
      throw new Meteor.Error(400, "Need to set a username or email");
  
    // Raw password. The meteor client doesn't send this, but a DDP
    // client that didn't implement SRP could send this. This should
    // only be done over SSL.
    if (options.password) {
      if (options.srp)
        throw new Meteor.Error(400, "Don't pass both password and srp in options");
      options.srp = SRP.generateVerifier(options.password);
    }
  
    var user = {services: {}};
    if (options.srp)
      user.services.password = {srp: options.srp}; // XXX validate verifier
    if (username)
      user.username = username;
    if (email)
      user.emails = [{address: email, verified: false}];
  
    return Accounts.insertUserDoc(options, user);
  }