             cb     : opts.cb
 
     do_account_creation_actions: (opts) =>
-        throw Error("NotImplementedError")
+        opts = defaults opts,
+            email_address : required
+            account_id    : required
+            cb            : required
+        dbg = @_dbg("do_account_creation_actions(email_address='#{opts.email_address}')")
+        @account_creation_actions
+            email_address : opts.email_address
+            cb            : (err, actions) =>
+                if err
+                    opts.cb(err); return
+                f = (action, cb) =>
+                    dbg("account_creation_actions: action = #{misc.to_json(action)}")
+                    if action.action == 'add_to_project'
+                        @add_user_to_project
+                            project_id : action.project_id
+                            account_id : opts.account_id
+                            group      : action.group
+                            cb         : (err) =>
+                                if err
+                                    dbg("Error adding user to project: #{err}")
+                                cb(err)
+                    else
+                        # TODO: need to report this some better way, maybe email?
+                        dbg("skipping unknown action -- #{action.action}")
+                        cb()
+                async.map actions, f, (err) =>
+                    if not err
+                        @account_creation_actions_success
+                            account_id : opts.account_id
+                            cb         : opts.cb
+                    else
+                        opts.cb(err)
 
     set_stripe_customer_id: (opts) =>
         throw Error("NotImplementedError")

        opts  = defaults opts,
            query     : required
            params    : []
            where     : undefined # Used for SELECT: If given, must be a map with keys clauses with $::TYPE  (not $1::TYPE!)
                                  # and values the corresponding params.  Also, WHERE must not be in the query already.
                                  # If where[cond] is undefined, then cond is completely **ignored**.
            values    : undefined # Used for INSERT: If given, then params and where must not be given.   Values is a map
                                  # {'field1::type1':value, , 'field2::type2':value2, ...} which gets converted to
                                  # ' (field1, field2, ...) VALUES ($1::type1, $2::type2, ...) '
                                  # with corresponding params set.  Undefined valued fields are ignored and types may be omited.
            conflict  : undefined # If given, then values must also be given; appends this to query:
                                  #     ON CONFLICT (name) DO UPDATE SET value=EXCLUDED.value'
            jsonb_set : undefined # Used for setting a field that contains a JSONB javascript map.
                                  # Give as input an object {key1:val1, key2:val2, ...}.
                                  # Every key has the corresponding value set, unless val is undefined/null, in which
                                  # case that key is deleted from the JSONB object.  Simple as that!  This is much, much
                                  # cleaner to use than the generated SQL.   Also, if the field itself is NULL, it gets
                                  # created automatically.
            cb     : required
        dbg = @_dbg("_query('#{opts.query}') (concurrent=#{@_concurrent_queries})")
        dbg()

        throw Error("NotImplementedError")

    create_project: (opts) =>
        opts = defaults opts,
            account_id  : required    # initial owner
            title       : undefined
            description : undefined
            cb          : required    # cb(err, project_id)
        if not @_validate_opts(opts) then return
        project_id = misc.uuid()
        now = new Date()
        @_query
            query  : "INSERT INTO projects"
            values :
                project_id  : project_id
                title       : opts.title
                description : opts.description
                created     : now
                last_edited : now
                users       : {"#{opts.account_id}":{group:'owner'}}
            cb : (err, result) =>
                opts.cb(err, if not err then project_id)

    get_project: (opts) =>
        throw Error("NotImplementedError")
