proxy_C_OpenSession (CK_X_FUNCTION_LIST *self,
                     CK_SLOT_ID id,
                     CK_FLAGS flags,
                     CK_VOID_PTR user_data,
                     CK_NOTIFY callback,
                     CK_SESSION_HANDLE_PTR handle)
{
	State *state = (State *)self;
	Session *sess;
	Mapping map;
	CK_RV rv;

	return_val_if_fail (handle != NULL, CKR_ARGUMENTS_BAD);

	rv = map_slot_to_real (state->px, &id, &map);
	if (rv != CKR_OK)
		return rv;

	rv = (map.funcs->C_OpenSession) (id, flags, user_data, callback, handle);

	if (rv == CKR_OK) {
		p11_lock ();

			if (!PROXY_VALID (state->px)) {
				/*
				 * The underlying module should have returned an error, so this
				 * code should never be reached with properly behaving modules.
				 * That's why we don't cleanup and close the newly opened session here
				 * or anything like that.
				 */
				rv = CKR_CRYPTOKI_NOT_INITIALIZED;

			} else {
				sess = calloc (1, sizeof (Session));
				return_val_if_fail (sess != NULL, CKR_HOST_MEMORY);
				sess->wrap_slot = map.wrap_slot;
				sess->real_session = *handle;
				sess->wrap_session = ++state->last_handle; /* TODO: Handle wrapping, and then collisions */
				if (!p11_dict_set (state->px->sessions, &sess->wrap_session, sess))
					warn_if_reached ();
				*handle = sess->wrap_session;
			}

		p11_unlock ();
	}

	return rv;
}
proxy_C_OpenSession (CK_X_FUNCTION_LIST *self,
                     CK_SLOT_ID id,
                     CK_FLAGS flags,
                     CK_VOID_PTR user_data,
                     CK_NOTIFY callback,
                     CK_SESSION_HANDLE_PTR handle)
{
	State *state = (State *)self;
	Session *sess;
	Mapping map;
	CK_RV rv;

	return_val_if_fail (handle != NULL, CKR_ARGUMENTS_BAD);

	rv = map_slot_to_real (state->px, &id, &map);
	if (rv != CKR_OK)
		return rv;

	rv = (map.funcs->C_OpenSession) (id, flags, user_data, callback, handle);

	if (rv == CKR_OK) {
		p11_lock ();

			if (!PROXY_VALID (state->px)) {
				 
				rv = CKR_CRYPTOKI_NOT_INITIALIZED;

			} else {
				sess = calloc (1, sizeof (Session));
				return_val_if_fail (sess != NULL, CKR_HOST_MEMORY);
				sess->wrap_slot = map.wrap_slot;
				sess->real_session = *handle;
				sess->wrap_session = ++state->last_handle;  
				if (!p11_dict_set (state->px->sessions, &sess->wrap_session, sess))
					warn_if_reached ();
				*handle = sess->wrap_session;
			}

		p11_unlock ();
	}

	return rv;
}