void am_cache_env_populate(request_rec *r, am_cache_entry_t *t)
{
    am_dir_cfg_rec *d;
    int i;
    apr_hash_t *counters;
    am_envattr_conf_t *env_varname_conf;
    const char *varname;
    const char *varname_prefix;
    const char *value;
    const char *prefixed_varname;
    int *count;
    int status;

    d = am_get_dir_cfg(r);

    /* Check if the user attribute has been set, and set it if it
     * hasn't been set. */
    if (am_cache_entry_slot_is_empty(&t->user)) {
        for(i = 0; i < t->size; ++i) {
            varname = am_cache_entry_get_string(t, &t->env[i].varname);
            if (strcmp(varname, d->userattr) == 0) {
                value = am_cache_entry_get_string(t, &t->env[i].value);
                status = am_cache_entry_store_string(t, &t->user, value);
                if (status != 0) {
                    ap_log_rerror(APLOG_MARK, APLOG_NOTICE, 0, r,
                                  "Unable to store the user name because there"
                                  " is no more space in the session. "
                                  "Username = \"%s\".", value);
                }
            }
        }
    }

    /* Allocate a set of counters for duplicate variables in the list. */
    counters = apr_hash_make(r->pool);

    /* Populate the subprocess environment with the attributes we
     * received from the IdP.
     */
    for(i = 0; i < t->size; ++i) {
        varname = am_cache_entry_get_string(t, &t->env[i].varname);
        varname_prefix = "MELLON_";

        /* Check if we should map this name into another name. */
        env_varname_conf = (am_envattr_conf_t *)apr_hash_get(
            d->envattr, varname, APR_HASH_KEY_STRING);

        if(env_varname_conf != NULL) {
            varname = env_varname_conf->name;
            if (!env_varname_conf->prefixed) {
              varname_prefix = "";
            }
        }

        value = am_cache_entry_get_string(t, &t->env[i].value);

        /*  
         * If we find a variable remapping to MellonUser, use it.
         */
        if (am_cache_entry_slot_is_empty(&t->user) &&
            (strcmp(varname, d->userattr) == 0)) {
            status = am_cache_entry_store_string(t, &t->user, value);
            if (status != 0) {
                ap_log_rerror(APLOG_MARK, APLOG_NOTICE, 0, r,
                              "Unable to store the user name because there"
                              " is no more space in the session. "
                              "Username = \"%s\".", value);
            }
        }

        prefixed_varname = apr_pstrcat(r->pool, varname_prefix, varname, NULL);

        /* Find the number of times this variable has been set. */
        count = apr_hash_get(counters, varname, APR_HASH_KEY_STRING);
        if(count == NULL) {

            /* This is the first time. Create a counter for this variable. */
            count = apr_palloc(r->pool, sizeof(int));
            *count = 0;
            apr_hash_set(counters, varname, APR_HASH_KEY_STRING, count);

            /* Add the variable without a suffix. */
            apr_table_set(r->subprocess_env,prefixed_varname,value);
        }

        /* Check if merging of environment variables is disabled.
         * This is either if it is NULL (default value if not configured
         * by user) or an empty string (if specifically disabled by the user).
         */
        if (d->merge_env_vars == NULL || *d->merge_env_vars == '\0') {
         
            /* Add the variable with a suffix indicating how many times it has
             * been added before.
             */
            apr_table_set(r->subprocess_env,
                          apr_psprintf(r->pool, "%s_%d", prefixed_varname,
                              (d->env_vars_index_start > -1
                                  ? *count + d->env_vars_index_start
                                  : *count)),
                          value);

        } else if (*count > 0) {

            /*
             * Merge multiple values, separating by default with ";"
             * this makes auth_mellon work same way mod_shib is:
             * https://wiki.shibboleth.net/confluence/display/SHIB2/NativeSPAttributeAccess
             */
             apr_table_set(r->subprocess_env,
                           prefixed_varname,
                           apr_pstrcat(r->pool, 
                                       apr_table_get(r->subprocess_env,prefixed_varname),
                                       d->merge_env_vars, value, NULL));
        }
          
        /* Increase the count. */
        ++(*count);

        if (d->env_vars_count_in_n > 0) {
             apr_table_set(r->subprocess_env,
                           apr_pstrcat(r->pool, prefixed_varname, "_N", NULL),
                           apr_itoa(r->pool, *count));
        }
    }

    if (!am_cache_entry_slot_is_empty(&t->user)) {
        /* We have a user-"name". Set r->user and r->ap_auth_type. */
        r->user = apr_pstrdup(r->pool, am_cache_entry_get_string(t, &t->user));
        r->ap_auth_type = apr_pstrdup(r->pool, "Mellon");
    } else {
        /* We don't have a user-"name". Log error. */
        ap_log_rerror(APLOG_MARK, APLOG_NOTICE, 0, r,
                      "Didn't find the attribute \"%s\" in the attributes"
                      " which were received from the IdP. Cannot set a user"
                      " for this request without a valid user attribute.",
                      d->userattr);
    }


    /* Populate with the session? */
    if (d->dump_session) {
        char *session;
        const char *srcstr;
        int srclen, dstlen;

        srcstr = am_cache_entry_get_string(t, &t->lasso_session);
        srclen = strlen(srcstr);
        dstlen = apr_base64_encode_len(srclen);

        session = apr_palloc(r->pool, dstlen);
        (void)apr_base64_encode(session, srcstr, srclen);
        apr_table_set(r->subprocess_env, "MELLON_SESSION", session);
    }

    if (d->dump_saml_response) {
        const char *sr = am_cache_entry_get_string(t, &t->lasso_saml_response);
        if (sr) {
            apr_table_set(r->subprocess_env, "MELLON_SAML_RESPONSE", sr);
        }
    }
}