pj_ssl_sock_start_accept2(pj_ssl_sock_t *ssock,
			  pj_pool_t *pool,
			  const pj_sockaddr_t *localaddr,
			  int addr_len,
			  const pj_ssl_sock_param *newsock_param)
{
    pj_status_t status;
#ifndef SSL_SOCK_IMP_USE_OWN_NETWORK
    pj_activesock_cb asock_cb;
    pj_activesock_cfg asock_cfg;
#endif

    PJ_ASSERT_RETURN(ssock && pool && localaddr && addr_len, PJ_EINVAL);

    /* Verify new socket parameters */
    if (newsock_param->grp_lock != ssock->param.grp_lock ||
        newsock_param->sock_af != ssock->param.sock_af ||
        newsock_param->sock_type != ssock->param.sock_type)
    {
        return PJ_EINVAL;
    }

    ssock->is_server = PJ_TRUE;

#ifdef SSL_SOCK_IMP_USE_OWN_NETWORK
    status = network_start_accept(ssock, pool, localaddr, addr_len,
    				  newsock_param);
    if (status != PJ_SUCCESS)
	goto on_error;
#else
    /* Create socket */
    status = pj_sock_socket(ssock->param.sock_af, ssock->param.sock_type, 0, 
			    &ssock->sock);
    if (status != PJ_SUCCESS)
	goto on_error;

    /* Apply SO_REUSEADDR */
    if (ssock->param.reuse_addr) {
	int enabled = 1;
	status = pj_sock_setsockopt(ssock->sock, pj_SOL_SOCKET(),
				    pj_SO_REUSEADDR(),
				    &enabled, sizeof(enabled));
	if (status != PJ_SUCCESS) {
	    PJ_PERROR(4,(ssock->pool->obj_name, status,
		         "Warning: error applying SO_REUSEADDR"));
	}
    }

    /* Apply QoS, if specified */
    status = pj_sock_apply_qos2(ssock->sock, ssock->param.qos_type,
				&ssock->param.qos_params, 2, 
				ssock->pool->obj_name, NULL);
    if (status != PJ_SUCCESS && !ssock->param.qos_ignore_error)
	goto on_error;

    /* Apply socket options, if specified */
    if (ssock->param.sockopt_params.cnt) {
	status = pj_sock_setsockopt_params(ssock->sock, 
					   &ssock->param.sockopt_params);

	if (status != PJ_SUCCESS && !ssock->param.sockopt_ignore_error)
	    goto on_error;
    }

    /* Bind socket */
    status = pj_sock_bind(ssock->sock, localaddr, addr_len);
    if (status != PJ_SUCCESS)
	goto on_error;

    /* Start listening to the address */
    status = pj_sock_listen(ssock->sock, PJ_SOMAXCONN);
    if (status != PJ_SUCCESS)
	goto on_error;

    /* Create active socket */
    pj_activesock_cfg_default(&asock_cfg);
    asock_cfg.async_cnt = ssock->param.async_cnt;
    asock_cfg.concurrency = ssock->param.concurrency;
    asock_cfg.whole_data = PJ_FALSE;
    asock_cfg.grp_lock = ssock->param.grp_lock;

    pj_bzero(&asock_cb, sizeof(asock_cb));
    //asock_cb.on_accept_complete = asock_on_accept_complete;
    asock_cb.on_accept_complete2 = asock_on_accept_complete2;

    status = pj_activesock_create(pool,
				  ssock->sock, 
				  ssock->param.sock_type,
				  &asock_cfg,
				  ssock->param.ioqueue, 
				  &asock_cb,
				  ssock,
				  &ssock->asock);

    if (status != PJ_SUCCESS)
	goto on_error;

    /* Start accepting */
    pj_ssl_sock_param_copy(pool, &ssock->newsock_param, newsock_param);
    ssock->newsock_param.grp_lock = NULL;
    status = pj_activesock_start_accept(ssock->asock, pool);
    if (status != PJ_SUCCESS)
	goto on_error;

    /* Update local address */
    ssock->addr_len = addr_len;
    status = pj_sock_getsockname(ssock->sock, &ssock->local_addr, 
				 &ssock->addr_len);
    if (status != PJ_SUCCESS)
	pj_sockaddr_cp(&ssock->local_addr, localaddr);
#endif

    return PJ_SUCCESS;

on_error:
    ssl_reset_sock_state(ssock);
    return status;
}