diff --git a/channels/Makefile b/channels/Makefile
index ae5a0645a30294a057809964598a8749d29169f0..10d487cfbc455eac834cdae771096dc3bea6a4b1 100644
--- a/channels/Makefile
+++ b/channels/Makefile
@@ -113,3 +113,4 @@ h323/Makefile.ast:
 
 h323/libchanh323.a: h323/Makefile.ast
 	$(CMD_PREFIX) $(MAKE) -C h323 libchanh323.a
+
diff --git a/channels/chan_gulp.c b/channels/chan_gulp.c
new file mode 100644
index 0000000000000000000000000000000000000000..39a69e8861bf9040bd0184a4cc379ebaba3343e7
--- /dev/null
+++ b/channels/chan_gulp.c
@@ -0,0 +1,1445 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2013, Digium, Inc.
+ *
+ * Joshua Colp <jcolp@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*! \file
+ *
+ * \author Joshua Colp <jcolp@digium.com>
+ *
+ * \brief Gulp SIP Channel Driver
+ *
+ * \ingroup channel_drivers
+ */
+
+/*** MODULEINFO
+	<depend>pjproject</depend>
+	<depend>res_sip</depend>
+	<depend>res_sip_session</depend>
+	<support_level>core</support_level>
+ ***/
+
+#include "asterisk.h"
+
+#include <pjsip.h>
+#include <pjsip_ua.h>
+#include <pjlib.h>
+
+ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
+
+#include "asterisk/lock.h"
+#include "asterisk/channel.h"
+#include "asterisk/module.h"
+#include "asterisk/pbx.h"
+#include "asterisk/rtp_engine.h"
+#include "asterisk/acl.h"
+#include "asterisk/callerid.h"
+#include "asterisk/file.h"
+#include "asterisk/cli.h"
+#include "asterisk/app.h"
+#include "asterisk/musiconhold.h"
+#include "asterisk/causes.h"
+#include "asterisk/taskprocessor.h"
+
+#include "asterisk/res_sip.h"
+#include "asterisk/res_sip_session.h"
+
+/*** DOCUMENTATION
+	<function name="GULP_DIAL_CONTACTS" language="en_US">
+		<synopsis>
+			Return a dial string for dialing all contacts on an AOR.
+		</synopsis>
+		<syntax>
+			<parameter name="endpoint" required="true">
+				<para>Name of the endpoint</para>
+			</parameter>
+			<parameter name="aor" required="false">
+				<para>Name of an AOR to use, if not specified the configured AORs on the endpoint are used</para>
+			</parameter>
+			<parameter name="request_user" required="false">
+				<para>Optional request user to use in the request URI</para>
+			</parameter>
+		</syntax>
+		<description>
+			<para>Returns a properly formatted dial string for dialing all contacts on an AOR.</para>
+		</description>
+	</function>
+ ***/
+
+static const char desc[] = "Gulp SIP Channel";
+static const char channel_type[] = "Gulp";
+
+/*!
+ * \brief Positions of various media
+ */
+enum sip_session_media_position {
+	/*! \brief First is audio */
+	SIP_MEDIA_AUDIO = 0,
+	/*! \brief Second is video */
+	SIP_MEDIA_VIDEO,
+	/*! \brief Last is the size for media details */
+	SIP_MEDIA_SIZE,
+};
+
+struct gulp_pvt {
+	struct ast_sip_session *session;
+	struct ast_sip_session_media *media[SIP_MEDIA_SIZE];
+};
+
+static void gulp_pvt_dtor(void *obj)
+{
+	struct gulp_pvt *pvt = obj;
+	int i;
+	ao2_cleanup(pvt->session);
+	pvt->session = NULL;
+	for (i = 0; i < SIP_MEDIA_SIZE; ++i) {
+		ao2_cleanup(pvt->media[i]);
+		pvt->media[i] = NULL;
+	}
+}
+
+/* \brief Asterisk core interaction functions */
+static struct ast_channel *gulp_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, const char *data, int *cause);
+static int gulp_sendtext(struct ast_channel *ast, const char *text);
+static int gulp_digit_begin(struct ast_channel *ast, char digit);
+static int gulp_digit_end(struct ast_channel *ast, char digit, unsigned int duration);
+static int gulp_call(struct ast_channel *ast, const char *dest, int timeout);
+static int gulp_hangup(struct ast_channel *ast);
+static int gulp_answer(struct ast_channel *ast);
+static struct ast_frame *gulp_read(struct ast_channel *ast);
+static int gulp_write(struct ast_channel *ast, struct ast_frame *f);
+static int gulp_indicate(struct ast_channel *ast, int condition, const void *data, size_t datalen);
+static int gulp_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
+
+/*! \brief PBX interface structure for channel registration */
+static struct ast_channel_tech gulp_tech = {
+	.type = channel_type,
+	.description = "Gulp SIP Channel Driver",
+	.requester = gulp_request,
+	.send_text = gulp_sendtext,
+	.send_digit_begin = gulp_digit_begin,
+	.send_digit_end = gulp_digit_end,
+	.bridge = ast_rtp_instance_bridge,
+	.call = gulp_call,
+	.hangup = gulp_hangup,
+	.answer = gulp_answer,
+	.read = gulp_read,
+	.write = gulp_write,
+	.write_video = gulp_write,
+	.exception = gulp_read,
+	.indicate = gulp_indicate,
+	.fixup = gulp_fixup,
+	.properties = AST_CHAN_TP_WANTSJITTER | AST_CHAN_TP_CREATESJITTER
+};
+
+/*! \brief SIP session interaction functions */
+static void gulp_session_begin(struct ast_sip_session *session);
+static void gulp_session_end(struct ast_sip_session *session);
+static int gulp_incoming_request(struct ast_sip_session *session, struct pjsip_rx_data *rdata);
+static void gulp_incoming_response(struct ast_sip_session *session, struct pjsip_rx_data *rdata);
+
+/*! \brief SIP session supplement structure */
+static struct ast_sip_session_supplement gulp_supplement = {
+	.method = "INVITE",
+	.priority = AST_SIP_SESSION_SUPPLEMENT_PRIORITY_CHANNEL,
+	.session_begin = gulp_session_begin,
+	.session_end = gulp_session_end,
+	.incoming_request = gulp_incoming_request,
+	.incoming_response = gulp_incoming_response,
+};
+
+static int gulp_incoming_ack(struct ast_sip_session *session, struct pjsip_rx_data *rdata);
+
+static struct ast_sip_session_supplement gulp_ack_supplement = {
+	.method = "ACK",
+	.priority = AST_SIP_SESSION_SUPPLEMENT_PRIORITY_CHANNEL,
+	.incoming_request = gulp_incoming_ack,
+};
+
+/*! \brief Dialplan function for constructing a dial string for calling all contacts */
+static int gulp_dial_contacts(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
+{
+	AST_DECLARE_APP_ARGS(args,
+		AST_APP_ARG(endpoint_name);
+		AST_APP_ARG(aor_name);
+		AST_APP_ARG(request_user);
+	);
+	RAII_VAR(struct ast_sip_endpoint *, endpoint, NULL, ao2_cleanup);
+	const char *aor_name;
+	char *rest;
+	RAII_VAR(struct ast_str *, dial, NULL, ast_free_ptr);
+
+	AST_STANDARD_APP_ARGS(args, data);
+
+	if (ast_strlen_zero(args.endpoint_name)) {
+		ast_log(LOG_WARNING, "An endpoint name must be specified when using the '%s' dialplan function\n", cmd);
+		return -1;
+	} else if (!(endpoint = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "endpoint", args.endpoint_name))) {
+		ast_log(LOG_WARNING, "Specified endpoint '%s' was not found\n", args.endpoint_name);
+		return -1;
+	}
+
+	aor_name = S_OR(args.aor_name, endpoint->aors);
+
+	if (ast_strlen_zero(aor_name)) {
+		ast_log(LOG_WARNING, "No AOR has been provided and no AORs are configured on endpoint '%s'\n", args.endpoint_name);
+		return -1;
+	} else if (!(dial = ast_str_create(len))) {
+		ast_log(LOG_WARNING, "Could not get enough buffer space for dialing contacts\n");
+		return -1;
+	} else if (!(rest = ast_strdupa(aor_name))) {
+		ast_log(LOG_WARNING, "Could not duplicate provided AORs\n");
+		return -1;
+	}
+
+	while ((aor_name = strsep(&rest, ","))) {
+		RAII_VAR(struct ast_sip_aor *, aor, ast_sip_location_retrieve_aor(aor_name), ao2_cleanup);
+		RAII_VAR(struct ao2_container *, contacts, NULL, ao2_cleanup);
+		struct ao2_iterator it_contacts;
+		struct ast_sip_contact *contact;
+
+		if (!aor) {
+			/* If the AOR provided is not found skip it, there may be more */
+			continue;
+		} else if (!(contacts = ast_sip_location_retrieve_aor_contacts(aor))) {
+			/* No contacts are available, skip it as well */
+			continue;
+		} else if (!ao2_container_count(contacts)) {
+			/* We were given a container but no contacts are in it... */
+			continue;
+		}
+
+		it_contacts = ao2_iterator_init(contacts, 0);
+		for (; (contact = ao2_iterator_next(&it_contacts)); ao2_ref(contact, -1)) {
+			ast_str_append(&dial, -1, "Gulp/");
+
+			if (!ast_strlen_zero(args.request_user)) {
+				ast_str_append(&dial, -1, "%s@", args.request_user);
+			}
+			ast_str_append(&dial, -1, "%s/%s&", args.endpoint_name, contact->uri);
+		}
+		ao2_iterator_destroy(&it_contacts);
+	}
+
+	/* Trim the '&' at the end off */
+	ast_str_truncate(dial, ast_str_strlen(dial) - 1);
+
+	ast_copy_string(buf, ast_str_buffer(dial), len);
+
+	return 0;
+}
+
+static struct ast_custom_function gulp_dial_contacts_function = {
+	.name = "GULP_DIAL_CONTACTS",
+	.read = gulp_dial_contacts,
+};
+
+/*! \brief Function called by RTP engine to get local audio RTP peer */
+static enum ast_rtp_glue_result gulp_get_rtp_peer(struct ast_channel *chan, struct ast_rtp_instance **instance)
+{
+	struct gulp_pvt *pvt = ast_channel_tech_pvt(chan);
+	struct ast_sip_endpoint *endpoint;
+
+	if (!pvt || !pvt->session || !pvt->media[SIP_MEDIA_AUDIO]->rtp) {
+		return AST_RTP_GLUE_RESULT_FORBID;
+	}
+
+	endpoint = pvt->session->endpoint;
+
+	*instance = pvt->media[SIP_MEDIA_AUDIO]->rtp;
+	ao2_ref(*instance, +1);
+
+	ast_assert(endpoint != NULL);
+	if (endpoint->direct_media) {
+		return AST_RTP_GLUE_RESULT_REMOTE;
+	}
+
+	return AST_RTP_GLUE_RESULT_LOCAL;
+}
+
+/*! \brief Function called by RTP engine to get local video RTP peer */
+static enum ast_rtp_glue_result gulp_get_vrtp_peer(struct ast_channel *chan, struct ast_rtp_instance **instance)
+{
+	struct gulp_pvt *pvt = ast_channel_tech_pvt(chan);
+
+	if (!pvt || !pvt->session || !pvt->media[SIP_MEDIA_VIDEO]->rtp) {
+		return AST_RTP_GLUE_RESULT_FORBID;
+	}
+
+	*instance = pvt->media[SIP_MEDIA_VIDEO]->rtp;
+	ao2_ref(*instance, +1);
+
+	return AST_RTP_GLUE_RESULT_LOCAL;
+}
+
+/*! \brief Function called by RTP engine to get peer capabilities */
+static void gulp_get_codec(struct ast_channel *chan, struct ast_format_cap *result)
+{
+	struct gulp_pvt *pvt = ast_channel_tech_pvt(chan);
+	ast_format_cap_copy(result, pvt->session->endpoint->codecs);
+}
+
+static int send_direct_media_request(void *data)
+{
+	RAII_VAR(struct ast_sip_session *, session, data, ao2_cleanup);
+	return ast_sip_session_refresh(session, NULL, NULL, session->endpoint->direct_media_method, 1);
+}
+
+static struct ast_datastore_info direct_media_mitigation_info = { };
+
+static int direct_media_mitigate_glare(struct ast_sip_session *session)
+{
+	RAII_VAR(struct ast_datastore *, datastore, NULL, ao2_cleanup);
+
+	if (session->endpoint->direct_media_glare_mitigation == 
+			AST_SIP_DIRECT_MEDIA_GLARE_MITIGATION_NONE) {
+		return 0;
+	}
+
+	datastore = ast_sip_session_get_datastore(session, "direct_media_glare_mitigation");
+	if (!datastore) {
+		return 0;
+	}
+
+	/* Removing the datastore ensures we won't try to mitigate glare on subsequent reinvites */
+	ast_sip_session_remove_datastore(session, "direct_media_glare_mitigation");
+
+	if ((session->endpoint->direct_media_glare_mitigation ==
+			AST_SIP_DIRECT_MEDIA_GLARE_MITIGATION_OUTGOING &&
+			session->inv_session->role == PJSIP_ROLE_UAC) ||
+			(session->endpoint->direct_media_glare_mitigation ==
+			AST_SIP_DIRECT_MEDIA_GLARE_MITIGATION_INCOMING &&
+			session->inv_session->role == PJSIP_ROLE_UAS)) {
+		return 1;
+	}
+
+	return 0;
+}
+
+static int check_for_rtp_changes(struct ast_channel *chan, struct ast_rtp_instance *rtp,
+		struct ast_sip_session_media *media, int rtcp_fd)
+{
+	int changed = 0;
+
+	if (rtp) {
+		changed = ast_rtp_instance_get_and_cmp_remote_address(rtp, &media->direct_media_addr);
+		if (media->rtp) {
+			ast_channel_set_fd(chan, rtcp_fd, -1);
+			ast_rtp_instance_set_prop(media->rtp, AST_RTP_PROPERTY_RTCP, 0);
+		}
+	} else if (!ast_sockaddr_isnull(&media->direct_media_addr)){
+		ast_sockaddr_setnull(&media->direct_media_addr);
+		changed = 1;
+		if (media->rtp) {
+			ast_rtp_instance_set_prop(media->rtp, AST_RTP_PROPERTY_RTCP, 1);
+			ast_channel_set_fd(chan, rtcp_fd, ast_rtp_instance_fd(media->rtp, 1));
+		}
+	}
+
+	return changed;
+}
+
+/*! \brief Function called by RTP engine to change where the remote party should send media */
+static int gulp_set_rtp_peer(struct ast_channel *chan,
+		struct ast_rtp_instance *rtp,
+		struct ast_rtp_instance *vrtp,
+		struct ast_rtp_instance *tpeer,
+		const struct ast_format_cap *cap,
+		int nat_active)
+{
+	struct gulp_pvt *pvt = ast_channel_tech_pvt(chan);
+	struct ast_sip_session *session = pvt->session;
+	int changed = 0;
+
+	/* Don't try to do any direct media shenanigans on early bridges */
+	if ((rtp || vrtp || tpeer) && !ast_bridged_channel(chan)) {
+		return 0;
+	}
+
+	if (nat_active && session->endpoint->disable_direct_media_on_nat) {
+		return 0;
+	}
+
+	if (pvt->media[SIP_MEDIA_AUDIO]) {
+		changed |= check_for_rtp_changes(chan, rtp, pvt->media[SIP_MEDIA_AUDIO], 1);
+	}
+	if (pvt->media[SIP_MEDIA_VIDEO]) {
+		changed |= check_for_rtp_changes(chan, vrtp, pvt->media[SIP_MEDIA_VIDEO], 3);
+	}
+
+	if (direct_media_mitigate_glare(session)) {
+		return 0;
+	}
+
+	if (cap && !ast_format_cap_is_empty(cap) && !ast_format_cap_identical(session->direct_media_cap, cap)) {
+		ast_format_cap_copy(session->direct_media_cap, cap);
+		changed = 1;
+	}
+
+	if (changed) {
+		ao2_ref(session, +1);
+		ast_sip_push_task(session->serializer, send_direct_media_request, session);
+	}
+
+	return 0;
+}
+
+/*! \brief Local glue for interacting with the RTP engine core */
+static struct ast_rtp_glue gulp_rtp_glue = {
+	.type = "Gulp",
+	.get_rtp_info = gulp_get_rtp_peer,
+	.get_vrtp_info = gulp_get_vrtp_peer,
+	.get_codec = gulp_get_codec,
+	.update_peer = gulp_set_rtp_peer,
+};
+
+/*! \brief Function called to create a new Gulp Asterisk channel */
+static struct ast_channel *gulp_new(struct ast_sip_session *session, int state, const char *exten, const char *title, const char *linkedid, const char *cid_name)
+{
+	struct ast_channel *chan;
+	struct ast_format fmt;
+	struct gulp_pvt *pvt;
+
+	if (!(pvt = ao2_alloc(sizeof(*pvt), gulp_pvt_dtor))) {
+		return NULL;
+	}
+
+	if (!(chan = ast_channel_alloc(1, state, S_OR(session->id.number.str, ""), S_OR(session->id.name.str, ""), "", "", "", linkedid, 0, "Gulp/%s-%.*s", ast_sorcery_object_get_id(session->endpoint),
+		(int)session->inv_session->dlg->call_id->id.slen, session->inv_session->dlg->call_id->id.ptr))) {
+		ao2_cleanup(pvt);
+		return NULL;
+	}
+
+	ast_channel_tech_set(chan, &gulp_tech);
+
+	ao2_ref(session, +1);
+	pvt->session = session;
+	/* If res_sip_session is ever updated to create/destroy ast_sip_session_media
+	 * during a call such as if multiple same-type stream support is introduced,
+	 * these will need to be recaptured as well */
+	pvt->media[SIP_MEDIA_AUDIO] = ao2_find(session->media, "audio", OBJ_KEY);
+	pvt->media[SIP_MEDIA_VIDEO] = ao2_find(session->media, "video", OBJ_KEY);
+	ast_channel_tech_pvt_set(chan, pvt);
+
+	if (ast_format_cap_is_empty(session->req_caps)) {
+		ast_format_cap_copy(ast_channel_nativeformats(chan), session->endpoint->codecs);
+	} else {
+		ast_format_cap_copy(ast_channel_nativeformats(chan), session->req_caps);
+	}
+
+	ast_codec_choose(&session->endpoint->prefs, ast_channel_nativeformats(chan), 1, &fmt);
+	ast_format_copy(ast_channel_writeformat(chan), &fmt);
+	ast_format_copy(ast_channel_rawwriteformat(chan), &fmt);
+	ast_format_copy(ast_channel_readformat(chan), &fmt);
+	ast_format_copy(ast_channel_rawreadformat(chan), &fmt);
+
+	if (state == AST_STATE_RING) {
+		ast_channel_rings_set(chan, 1);
+	}
+
+	ast_channel_adsicpe_set(chan, AST_ADSI_UNAVAILABLE);
+
+	ast_channel_context_set(chan, session->endpoint->context);
+	ast_channel_exten_set(chan, S_OR(exten, "s"));
+	ast_channel_priority_set(chan, 1);
+
+	return chan;
+}
+
+static int answer(void *data)
+{
+	pj_status_t status;
+	pjsip_tx_data *packet;
+	struct ast_sip_session *session = data;
+
+	if ((status = pjsip_inv_answer(session->inv_session, 200, NULL, NULL, &packet)) == PJ_SUCCESS) {
+		ast_sip_session_send_response(session, packet);
+	}
+
+	ao2_ref(session, -1);
+	return (status == PJ_SUCCESS) ? 0 : -1;
+}
+
+/*! \brief Function called by core when we should answer a Gulp session */
+static int gulp_answer(struct ast_channel *ast)
+{
+	struct gulp_pvt *pvt = ast_channel_tech_pvt(ast);
+	struct ast_sip_session *session = pvt->session;
+
+	if (ast_channel_state(ast) == AST_STATE_UP) {
+		return 0;
+	}
+
+	ast_setstate(ast, AST_STATE_UP);
+
+	ao2_ref(session, +1);
+	if (ast_sip_push_task(session->serializer, answer, session)) {
+		ast_log(LOG_WARNING, "Unable to push answer task to the threadpool. Cannot answer call\n");
+		ao2_cleanup(session);
+		return -1;
+	}
+	return 0;
+}
+
+/*! \brief Function called by core to read any waiting frames */
+static struct ast_frame *gulp_read(struct ast_channel *ast)
+{
+	struct gulp_pvt *pvt = ast_channel_tech_pvt(ast);
+	struct ast_frame *f;
+	struct ast_sip_session_media *media = NULL;
+	int rtcp = 0;
+	int fdno = ast_channel_fdno(ast);
+
+	switch (fdno) {
+	case 0:
+		media = pvt->media[SIP_MEDIA_AUDIO];
+		break;
+	case 1:
+		media = pvt->media[SIP_MEDIA_AUDIO];
+		rtcp = 1;
+		break;
+	case 2:
+		media = pvt->media[SIP_MEDIA_VIDEO];
+		break;
+	case 3:
+		media = pvt->media[SIP_MEDIA_VIDEO];
+		rtcp = 1;
+		break;
+	}
+
+	if (!media || !media->rtp) {
+		return &ast_null_frame;
+	}
+
+	f = ast_rtp_instance_read(media->rtp, rtcp);
+
+	if (f && f->frametype == AST_FRAME_VOICE) {
+		if (!(ast_format_cap_iscompatible(ast_channel_nativeformats(ast), &f->subclass.format))) {
+			ast_debug(1, "Oooh, format changed to %s\n", ast_getformatname(&f->subclass.format));
+			ast_format_cap_set(ast_channel_nativeformats(ast), &f->subclass.format);
+			ast_set_read_format(ast, ast_channel_readformat(ast));
+			ast_set_write_format(ast, ast_channel_writeformat(ast));
+		}
+	}
+
+	return f;
+}
+
+/*! \brief Function called by core to write frames */
+static int gulp_write(struct ast_channel *ast, struct ast_frame *frame)
+{
+	struct gulp_pvt *pvt = ast_channel_tech_pvt(ast);
+	int res = 0;
+	struct ast_sip_session_media *media;
+
+	switch (frame->frametype) {
+	case AST_FRAME_VOICE:
+		media = pvt->media[SIP_MEDIA_AUDIO];
+
+		if (!media) {
+			return 0;
+		}
+		if (!(ast_format_cap_iscompatible(ast_channel_nativeformats(ast), &frame->subclass.format))) {
+			char buf[256];
+
+			ast_log(LOG_WARNING,
+				"Asked to transmit frame type %s, while native formats is %s (read/write = %s/%s)\n",
+				ast_getformatname(&frame->subclass.format),
+				ast_getformatname_multiple(buf, sizeof(buf), ast_channel_nativeformats(ast)),
+				ast_getformatname(ast_channel_readformat(ast)),
+				ast_getformatname(ast_channel_writeformat(ast)));
+			return 0;
+		}
+		if (media->rtp) {
+			res = ast_rtp_instance_write(media->rtp, frame);
+		}
+		break;
+	case AST_FRAME_VIDEO:
+		if ((media = pvt->media[SIP_MEDIA_VIDEO]) && media->rtp) {
+			res = ast_rtp_instance_write(media->rtp, frame);
+		}
+		break;
+	default:
+		ast_log(LOG_WARNING, "Can't send %d type frames with Gulp\n", frame->frametype);
+		break;
+	}
+
+	return res;
+}
+
+struct fixup_data {
+	struct ast_sip_session *session;
+	struct ast_channel *chan;
+};
+
+static int fixup(void *data)
+{
+	struct fixup_data *fix_data = data;
+	fix_data->session->channel = fix_data->chan;
+	return 0;
+}
+
+/*! \brief Function called by core to change the underlying owner channel */
+static int gulp_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
+{
+	struct gulp_pvt *pvt = ast_channel_tech_pvt(newchan);
+	struct ast_sip_session *session = pvt->session;
+	struct fixup_data fix_data;
+	fix_data.session = session;
+	fix_data.chan = newchan;
+
+	if (session->channel != oldchan) {
+		return -1;
+	}
+
+	if (ast_sip_push_task_synchronous(session->serializer, fixup, &fix_data)) {
+		ast_log(LOG_WARNING, "Unable to perform channel fixup\n");
+		return -1;
+	}
+
+	return 0;
+}
+
+struct indicate_data {
+	struct ast_sip_session *session;
+	int condition;
+	int response_code;
+	void *frame_data;
+	size_t datalen;
+};
+
+static void indicate_data_destroy(void *obj)
+{
+	struct indicate_data *ind_data = obj;
+	ast_free(ind_data->frame_data);
+	ao2_ref(ind_data->session, -1);
+}
+
+static struct indicate_data *indicate_data_alloc(struct ast_sip_session *session,
+		int condition, int response_code, const void *frame_data, size_t datalen)
+{
+	struct indicate_data *ind_data = ao2_alloc(sizeof(*ind_data), indicate_data_destroy);
+	if (!ind_data) {
+		return NULL;
+	}
+	ind_data->frame_data = ast_malloc(datalen);
+	if (!ind_data->frame_data) {
+		ao2_ref(ind_data, -1);
+		return NULL;
+	}
+	memcpy(ind_data->frame_data, frame_data, datalen);
+	ind_data->datalen = datalen;
+	ind_data->condition = condition;
+	ind_data->response_code = response_code;
+	ao2_ref(session, +1);
+	ind_data->session = session;
+	return ind_data;
+}
+
+static int indicate(void *data)
+{
+	struct indicate_data *ind_data = data;
+	struct ast_sip_session *session = ind_data->session;
+	int response_code = ind_data->response_code;
+	pjsip_tx_data *packet = NULL;
+
+	if (pjsip_inv_answer(session->inv_session, response_code, NULL, NULL, &packet) == PJ_SUCCESS) {
+		ast_sip_session_send_response(session, packet);
+	}
+
+	ao2_ref(ind_data, -1);
+	return 0;
+}
+
+/*! \brief Send SIP INFO with video update request */
+static int transmit_info_with_vidupdate(void *data)
+{
+	const char * xml =
+		"<?xml version=\"1.0\" encoding=\"utf-8\" ?>\r\n"
+		" <media_control>\r\n"
+		"  <vc_primitive>\r\n"
+		"   <to_encoder>\r\n"
+		"    <picture_fast_update/>\r\n"
+		"   </to_encoder>\r\n"
+		"  </vc_primitive>\r\n"
+		" </media_control>\r\n";
+
+	const struct ast_sip_body body = {
+		.type = "application",
+		.subtype = "media_control+xml",
+		.body_text = xml
+	};
+
+	struct ast_sip_session *session = data;
+	struct pjsip_tx_data *tdata;
+
+	if (ast_sip_create_request("INFO", session->inv_session->dlg, session->endpoint, NULL, &tdata)) {
+		ast_log(LOG_ERROR, "Could not create text video update INFO request\n");
+		return -1;
+	}
+	if (ast_sip_add_body(tdata, &body)) {
+		ast_log(LOG_ERROR, "Could not add body to text video update INFO request\n");
+		return -1;
+	}
+	ast_sip_session_send_request(session, tdata);
+
+	return 0;
+}
+
+/*! \brief Function called by core to ask the channel to indicate some sort of condition */
+static int gulp_indicate(struct ast_channel *ast, int condition, const void *data, size_t datalen)
+{
+	int res = 0;
+	struct gulp_pvt *pvt = ast_channel_tech_pvt(ast);
+	struct ast_sip_session *session = pvt->session;
+	struct ast_sip_session_media *media;
+	int response_code = 0;
+
+	switch (condition) {
+	case AST_CONTROL_RINGING:
+		if (ast_channel_state(ast) == AST_STATE_RING) {
+			response_code = 180;
+		} else {
+			res = -1;
+		}
+		break;
+	case AST_CONTROL_BUSY:
+		if (ast_channel_state(ast) != AST_STATE_UP) {
+			response_code = 486;
+		} else {
+			res = -1;
+		}
+		break;
+	case AST_CONTROL_CONGESTION:
+		if (ast_channel_state(ast) != AST_STATE_UP) {
+			response_code = 503;
+		} else {
+			res = -1;
+		}
+		break;
+	case AST_CONTROL_INCOMPLETE:
+		if (ast_channel_state(ast) != AST_STATE_UP) {
+			response_code = 484;
+		} else {
+			res = -1;
+		}
+		break;
+	case AST_CONTROL_PROCEEDING:
+		if (ast_channel_state(ast) != AST_STATE_UP) {
+			response_code = 100;
+		} else {
+			res = -1;
+		}
+		break;
+	case AST_CONTROL_PROGRESS:
+		if (ast_channel_state(ast) != AST_STATE_UP) {
+			response_code = 183;
+		} else {
+			res = -1;
+		}
+		break;
+	case AST_CONTROL_VIDUPDATE:
+		media = pvt->media[SIP_MEDIA_VIDEO];
+		if (media && media->rtp) {
+			ast_sip_push_task(session->serializer, transmit_info_with_vidupdate, session);
+		} else
+			res = -1;
+		break;
+	case AST_CONTROL_UPDATE_RTP_PEER:
+	case AST_CONTROL_PVT_CAUSE_CODE:
+		break;
+	case AST_CONTROL_HOLD:
+		ast_moh_start(ast, data, NULL);
+		break;
+	case AST_CONTROL_UNHOLD:
+		ast_moh_stop(ast);
+		break;
+	case AST_CONTROL_SRCUPDATE:
+		break;
+	case AST_CONTROL_SRCCHANGE:
+		break;
+	case -1:
+		res = -1;
+		break;
+	default:
+		ast_log(LOG_WARNING, "Don't know how to indicate condition %d\n", condition);
+		res = -1;
+		break;
+	}
+
+	if (!res && response_code) {
+		struct indicate_data *ind_data = indicate_data_alloc(session, condition, response_code, data, datalen);
+		if (ind_data) {
+			res = ast_sip_push_task(session->serializer, indicate, ind_data);
+			if (res) {
+				ast_log(LOG_NOTICE, "Cannot send response code %d to endpoint %s. Could queue task properly\n",
+						response_code, ast_sorcery_object_get_id(session->endpoint));
+				ao2_cleanup(ind_data);
+			}
+		} else {
+			res = -1;
+		}
+	}
+
+	return res;
+}
+
+/*! \brief Function called by core to start a DTMF digit */
+static int gulp_digit_begin(struct ast_channel *chan, char digit)
+{
+	struct gulp_pvt *pvt = ast_channel_tech_pvt(chan);
+	struct ast_sip_session *session = pvt->session;
+	int res = 0;
+	struct ast_sip_session_media *media = pvt->media[SIP_MEDIA_AUDIO];
+
+	switch (session->endpoint->dtmf) {
+	case AST_SIP_DTMF_RFC_4733:
+		if (!media || !media->rtp) {
+			return -1;
+		}
+
+		ast_rtp_instance_dtmf_begin(media->rtp, digit);
+	case AST_SIP_DTMF_NONE:
+		break;
+	case AST_SIP_DTMF_INBAND:
+		res = -1;
+		break;
+	default:
+		break;
+	}
+
+	return res;
+}
+
+struct info_dtmf_data {
+	struct ast_sip_session *session;
+	char digit;
+	unsigned int duration;
+};
+
+static void info_dtmf_data_destroy(void *obj)
+{
+	struct info_dtmf_data *dtmf_data = obj;
+	ao2_ref(dtmf_data->session, -1);
+}
+
+static struct info_dtmf_data *info_dtmf_data_alloc(struct ast_sip_session *session, char digit, unsigned int duration)
+{
+	struct info_dtmf_data *dtmf_data = ao2_alloc(sizeof(*dtmf_data), info_dtmf_data_destroy);
+	if (!dtmf_data) {
+		return NULL;
+	}
+	ao2_ref(session, +1);
+	dtmf_data->session = session;
+	dtmf_data->digit = digit;
+	dtmf_data->duration = duration;
+	return dtmf_data;
+}
+
+static int transmit_info_dtmf(void *data)
+{
+	RAII_VAR(struct info_dtmf_data *, dtmf_data, data, ao2_cleanup);
+
+	struct ast_sip_session *session = dtmf_data->session;
+	struct pjsip_tx_data *tdata;
+
+	RAII_VAR(struct ast_str *, body_text, NULL, ast_free_ptr);
+
+	struct ast_sip_body body = {
+		.type = "application",
+		.subtype = "dtmf-relay",
+	};
+
+	if (!(body_text = ast_str_create(32))) {
+		ast_log(LOG_ERROR, "Could not allocate buffer for INFO DTMF.\n");
+		return -1;
+	}
+	ast_str_set(&body_text, 0, "Signal=%c\r\nDuration=%u\r\n", dtmf_data->digit, dtmf_data->duration);
+
+	body.body_text = ast_str_buffer(body_text);
+
+	if (ast_sip_create_request("INFO", session->inv_session->dlg, session->endpoint, NULL, &tdata)) {
+		ast_log(LOG_ERROR, "Could not create DTMF INFO request\n");
+		return -1;
+	}
+	if (ast_sip_add_body(tdata, &body)) {
+		ast_log(LOG_ERROR, "Could not add body to DTMF INFO request\n");
+		pjsip_tx_data_dec_ref(tdata);
+		return -1;
+	}
+	ast_sip_session_send_request(session, tdata);
+
+	return 0;
+}
+
+/*! \brief Function called by core to stop a DTMF digit */
+static int gulp_digit_end(struct ast_channel *ast, char digit, unsigned int duration)
+{
+	struct gulp_pvt *pvt = ast_channel_tech_pvt(ast);
+	struct ast_sip_session *session = pvt->session;
+	int res = 0;
+	struct ast_sip_session_media *media = pvt->media[SIP_MEDIA_AUDIO];
+
+	switch (session->endpoint->dtmf) {
+	case AST_SIP_DTMF_INFO:
+	{
+		struct info_dtmf_data *dtmf_data = info_dtmf_data_alloc(session, digit, duration);
+
+		if (!dtmf_data) {
+			return -1;
+		}
+
+		if (ast_sip_push_task(session->serializer, transmit_info_dtmf, dtmf_data)) {
+			ast_log(LOG_WARNING, "Error sending DTMF via INFO.\n");
+			ao2_cleanup(dtmf_data);
+			return -1;
+		}
+		break;
+	}
+	case AST_SIP_DTMF_RFC_4733:
+		if (!media || !media->rtp) {
+			return -1;
+		}
+
+		ast_rtp_instance_dtmf_end_with_duration(media->rtp, digit, duration);
+	case AST_SIP_DTMF_NONE:
+		break;
+	case AST_SIP_DTMF_INBAND:
+		res = -1;
+		break;
+	}
+
+	return res;
+}
+
+static int call(void *data)
+{
+	struct ast_sip_session *session = data;
+	pjsip_tx_data *packet;
+
+	if (pjsip_inv_invite(session->inv_session, &packet) != PJ_SUCCESS) {
+		ast_queue_hangup(session->channel);
+	} else {
+		ast_sip_session_send_request(session, packet);
+	}
+
+	ao2_ref(session, -1);
+	return 0;
+}
+
+/*! \brief Function called by core to actually start calling a remote party */
+static int gulp_call(struct ast_channel *ast, const char *dest, int timeout)
+{
+	struct gulp_pvt *pvt = ast_channel_tech_pvt(ast);
+	struct ast_sip_session *session = pvt->session;
+
+	ao2_ref(session, +1);
+	if (ast_sip_push_task(session->serializer, call, session)) {
+		ast_log(LOG_WARNING, "Error attempting to place outbound call to call '%s'\n", dest);
+		ao2_cleanup(session);
+		return -1;
+	}
+	return 0;
+}
+
+/*! \brief Internal function which translates from Asterisk cause codes to SIP response codes */
+static int hangup_cause2sip(int cause)
+{
+	switch (cause) {
+	case AST_CAUSE_UNALLOCATED:             /* 1 */
+	case AST_CAUSE_NO_ROUTE_DESTINATION:    /* 3 IAX2: Can't find extension in context */
+	case AST_CAUSE_NO_ROUTE_TRANSIT_NET:    /* 2 */
+		return 404;
+	case AST_CAUSE_CONGESTION:              /* 34 */
+	case AST_CAUSE_SWITCH_CONGESTION:       /* 42 */
+		return 503;
+	case AST_CAUSE_NO_USER_RESPONSE:        /* 18 */
+		return 408;
+	case AST_CAUSE_NO_ANSWER:               /* 19 */
+	case AST_CAUSE_UNREGISTERED:        /* 20 */
+		return 480;
+	case AST_CAUSE_CALL_REJECTED:           /* 21 */
+		return 403;
+	case AST_CAUSE_NUMBER_CHANGED:          /* 22 */
+		return 410;
+	case AST_CAUSE_NORMAL_UNSPECIFIED:      /* 31 */
+		return 480;
+	case AST_CAUSE_INVALID_NUMBER_FORMAT:
+		return 484;
+	case AST_CAUSE_USER_BUSY:
+		return 486;
+	case AST_CAUSE_FAILURE:
+		return 500;
+	case AST_CAUSE_FACILITY_REJECTED:       /* 29 */
+		return 501;
+	case AST_CAUSE_CHAN_NOT_IMPLEMENTED:
+		return 503;
+	case AST_CAUSE_DESTINATION_OUT_OF_ORDER:
+		return 502;
+	case AST_CAUSE_BEARERCAPABILITY_NOTAVAIL:       /* Can't find codec to connect to host */
+		return 488;
+	case AST_CAUSE_INTERWORKING:    /* Unspecified Interworking issues */
+		return 500;
+	case AST_CAUSE_NOTDEFINED:
+	default:
+		ast_debug(1, "AST hangup cause %d (no match found in PJSIP)\n", cause);
+		return 0;
+	}
+
+	/* Never reached */
+	return 0;
+}
+
+struct hangup_data {
+	int cause;
+	struct ast_channel *chan;
+};
+
+static void hangup_data_destroy(void *obj)
+{
+	struct hangup_data *h_data = obj;
+	h_data->chan = ast_channel_unref(h_data->chan);
+}
+
+static struct hangup_data *hangup_data_alloc(int cause, struct ast_channel *chan)
+{
+	struct hangup_data *h_data = ao2_alloc(sizeof(*h_data), hangup_data_destroy);
+	if (!h_data) {
+		return NULL;
+	}
+	h_data->cause = cause;
+	h_data->chan = ast_channel_ref(chan);
+	return h_data;
+}
+
+static int hangup(void *data)
+{
+	pj_status_t status;
+	pjsip_tx_data *packet = NULL;
+	struct hangup_data *h_data = data;
+	struct ast_channel *ast = h_data->chan;
+	struct gulp_pvt *pvt = ast_channel_tech_pvt(ast);
+	struct ast_sip_session *session = pvt->session;
+	int cause = h_data->cause;
+
+	if (((status = pjsip_inv_end_session(session->inv_session, cause ? cause : 603, NULL, &packet)) == PJ_SUCCESS) && packet) {
+		if (packet->msg->type == PJSIP_RESPONSE_MSG) {
+			ast_sip_session_send_response(session, packet);
+		} else {
+			ast_sip_session_send_request(session, packet);
+		}
+	}
+
+	session->channel = NULL;
+	ast_channel_tech_pvt_set(ast, NULL);
+
+	ao2_cleanup(pvt);
+	ao2_cleanup(h_data);
+	return 0;
+}
+
+/*! \brief Function called by core to hang up a Gulp session */
+static int gulp_hangup(struct ast_channel *ast)
+{
+	struct gulp_pvt *pvt = ast_channel_tech_pvt(ast);
+	struct ast_sip_session *session = pvt->session;
+	int cause = hangup_cause2sip(ast_channel_hangupcause(session->channel));
+	struct hangup_data *h_data = hangup_data_alloc(cause, ast);
+	if (!h_data) {
+		goto failure;
+	}
+
+	if (ast_sip_push_task(session->serializer, hangup, h_data)) {
+		ast_log(LOG_WARNING, "Unable to push hangup task to the threadpool. Expect bad things\n");
+		goto failure;
+	}
+	return 0;
+
+failure:
+	/* Go ahead and do our cleanup of the session and channel even if we're not going
+	 * to be able to send our SIP request/response
+	 */
+	ao2_cleanup(h_data);
+	session->channel = NULL;
+	ast_channel_tech_pvt_set(ast, NULL);
+
+	ao2_cleanup(pvt);
+	return -1;
+}
+
+struct request_data {
+	struct ast_sip_session *session;
+	struct ast_format_cap *caps;
+	const char *dest;
+	int cause;
+};
+
+static int request(void *obj)
+{
+	struct request_data *req_data = obj;
+	char *tmp = ast_strdupa(req_data->dest), *endpoint_name = NULL, *request_user = NULL;
+	RAII_VAR(struct ast_sip_endpoint *, endpoint, NULL, ao2_cleanup);
+	struct ast_sip_session *session = NULL;
+	AST_DECLARE_APP_ARGS(args,
+		AST_APP_ARG(endpoint);
+		AST_APP_ARG(aor);
+	);
+
+	if (ast_strlen_zero(tmp)) {
+		ast_log(LOG_ERROR, "Unable to create Gulp channel with empty destination\n");
+		req_data->cause = AST_CAUSE_CHANNEL_UNACCEPTABLE;
+		return -1;
+	}
+
+	AST_NONSTANDARD_APP_ARGS(args, tmp, '/');
+
+	/* If a request user has been specified extract it from the endpoint name portion */
+	if ((endpoint_name = strchr(args.endpoint, '@'))) {
+		request_user = args.endpoint;
+		*endpoint_name++ = '\0';
+	} else {
+		endpoint_name = args.endpoint;
+	}
+
+	if (ast_strlen_zero(endpoint_name)) {
+		ast_log(LOG_ERROR, "Unable to create Gulp channel with empty endpoint name\n");
+		req_data->cause = AST_CAUSE_CHANNEL_UNACCEPTABLE;
+	} else if (!(endpoint = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "endpoint", endpoint_name))) {
+		ast_log(LOG_ERROR, "Unable to create Gulp channel - endpoint '%s' was not found\n", endpoint_name);
+		req_data->cause = AST_CAUSE_NO_ROUTE_DESTINATION;
+		return -1;
+	}
+
+	if (!(session = ast_sip_session_create_outgoing(endpoint, args.aor, request_user, req_data->caps))) {
+		req_data->cause = AST_CAUSE_NO_ROUTE_DESTINATION;
+		return -1;
+	}
+
+	req_data->session = session;
+
+	return 0;
+}
+
+/*! \brief Function called by core to create a new outgoing Gulp session */
+static struct ast_channel *gulp_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, const char *data, int *cause)
+{
+	struct request_data req_data;
+	struct ast_sip_session *session;
+
+	req_data.caps = cap;
+	req_data.dest = data;
+
+	if (ast_sip_push_task_synchronous(NULL, request, &req_data)) {
+		*cause = req_data.cause;
+		return NULL;
+	}
+
+	session = req_data.session;
+
+	if (!(session->channel = gulp_new(session, AST_STATE_DOWN, NULL, NULL, requestor ? ast_channel_linkedid(requestor) : NULL, NULL))) {
+		/* Session needs to be terminated prematurely */
+		return NULL;
+	}
+
+	return session->channel;
+}
+
+/*! \brief Function called by core to send text on Gulp session */
+static int gulp_sendtext(struct ast_channel *ast, const char *text)
+{
+	return 0;
+}
+
+/*! \brief Convert SIP hangup causes to Asterisk hangup causes */
+static int hangup_sip2cause(int cause)
+{
+	/* Possible values taken from causes.h */
+
+	switch(cause) {
+	case 401:       /* Unauthorized */
+		return AST_CAUSE_CALL_REJECTED;
+	case 403:       /* Not found */
+		return AST_CAUSE_CALL_REJECTED;
+	case 404:       /* Not found */
+		return AST_CAUSE_UNALLOCATED;
+	case 405:       /* Method not allowed */
+		return AST_CAUSE_INTERWORKING;
+	case 407:       /* Proxy authentication required */
+		return AST_CAUSE_CALL_REJECTED;
+	case 408:       /* No reaction */
+		return AST_CAUSE_NO_USER_RESPONSE;
+	case 409:       /* Conflict */
+		return AST_CAUSE_NORMAL_TEMPORARY_FAILURE;
+	case 410:       /* Gone */
+		return AST_CAUSE_NUMBER_CHANGED;
+	case 411:       /* Length required */
+		return AST_CAUSE_INTERWORKING;
+	case 413:       /* Request entity too large */
+		return AST_CAUSE_INTERWORKING;
+	case 414:       /* Request URI too large */
+		return AST_CAUSE_INTERWORKING;
+	case 415:       /* Unsupported media type */
+		return AST_CAUSE_INTERWORKING;
+	case 420:       /* Bad extension */
+		return AST_CAUSE_NO_ROUTE_DESTINATION;
+	case 480:       /* No answer */
+		return AST_CAUSE_NO_ANSWER;
+	case 481:       /* No answer */
+		return AST_CAUSE_INTERWORKING;
+	case 482:       /* Loop detected */
+		return AST_CAUSE_INTERWORKING;
+	case 483:       /* Too many hops */
+		return AST_CAUSE_NO_ANSWER;
+	case 484:       /* Address incomplete */
+		return AST_CAUSE_INVALID_NUMBER_FORMAT;
+	case 485:       /* Ambiguous */
+		return AST_CAUSE_UNALLOCATED;
+	case 486:       /* Busy everywhere */
+		return AST_CAUSE_BUSY;
+	case 487:       /* Request terminated */
+		return AST_CAUSE_INTERWORKING;
+	case 488:       /* No codecs approved */
+		return AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;
+	case 491:       /* Request pending */
+		return AST_CAUSE_INTERWORKING;
+	case 493:       /* Undecipherable */
+		return AST_CAUSE_INTERWORKING;
+	case 500:       /* Server internal failure */
+		return AST_CAUSE_FAILURE;
+	case 501:       /* Call rejected */
+		return AST_CAUSE_FACILITY_REJECTED;
+	case 502:
+		return AST_CAUSE_DESTINATION_OUT_OF_ORDER;
+	case 503:       /* Service unavailable */
+		return AST_CAUSE_CONGESTION;
+	case 504:       /* Gateway timeout */
+		return AST_CAUSE_RECOVERY_ON_TIMER_EXPIRE;
+	case 505:       /* SIP version not supported */
+		return AST_CAUSE_INTERWORKING;
+	case 600:       /* Busy everywhere */
+		return AST_CAUSE_USER_BUSY;
+	case 603:       /* Decline */
+		return AST_CAUSE_CALL_REJECTED;
+	case 604:       /* Does not exist anywhere */
+		return AST_CAUSE_UNALLOCATED;
+	case 606:       /* Not acceptable */
+		return AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;
+	default:
+		if (cause < 500 && cause >= 400) {
+			/* 4xx class error that is unknown - someting wrong with our request */
+			return AST_CAUSE_INTERWORKING;
+		} else if (cause < 600 && cause >= 500) {
+			/* 5xx class error - problem in the remote end */
+			return AST_CAUSE_CONGESTION;
+		} else if (cause < 700 && cause >= 600) {
+			/* 6xx - global errors in the 4xx class */
+			return AST_CAUSE_INTERWORKING;
+		}
+		return AST_CAUSE_NORMAL;
+	}
+	/* Never reached */
+	return 0;
+}
+
+static void gulp_session_begin(struct ast_sip_session *session)
+{
+	RAII_VAR(struct ast_datastore *, datastore, NULL, ao2_cleanup);
+
+	if (session->endpoint->direct_media_glare_mitigation ==
+			AST_SIP_DIRECT_MEDIA_GLARE_MITIGATION_NONE) {
+		return;
+	}
+
+	datastore = ast_sip_session_alloc_datastore(&direct_media_mitigation_info,
+			"direct_media_glare_mitigation");
+
+	if (!datastore) {
+		return;
+	}
+
+	ast_sip_session_add_datastore(session, datastore);
+}
+
+/*! \brief Function called when the session ends */
+static void gulp_session_end(struct ast_sip_session *session)
+{
+	if (!session->channel) {
+		return;
+	}
+
+	if (!ast_channel_hangupcause(session->channel) && session->inv_session) {
+		int cause = hangup_sip2cause(session->inv_session->cause);
+
+		ast_queue_hangup_with_cause(session->channel, cause);
+	} else {
+		ast_queue_hangup(session->channel);
+	}
+}
+
+/*! \brief Function called when a request is received on the session */
+static int gulp_incoming_request(struct ast_sip_session *session, struct pjsip_rx_data *rdata)
+{
+	pjsip_tx_data *packet = NULL;
+	int res = AST_PBX_FAILED;
+
+	if (session->channel) {
+		return 0;
+	}
+
+	if (!(session->channel = gulp_new(session, AST_STATE_DOWN, session->exten, NULL, NULL, NULL))) {
+		if (pjsip_inv_end_session(session->inv_session, 503, NULL, &packet) == PJ_SUCCESS) {
+			ast_sip_session_send_response(session, packet);
+		}
+
+		ast_log(LOG_ERROR, "Failed to allocate new GULP channel on incoming SIP INVITE\n");
+		return -1;
+	}
+
+	ast_setstate(session->channel, AST_STATE_RING);
+	res = ast_pbx_start(session->channel);
+
+	switch (res) {
+	case AST_PBX_FAILED:
+		ast_log(LOG_WARNING, "Failed to start PBX ;(\n");
+		ast_channel_hangupcause_set(session->channel, AST_CAUSE_SWITCH_CONGESTION);
+		ast_hangup(session->channel);
+		break;
+	case AST_PBX_CALL_LIMIT:
+		ast_log(LOG_WARNING, "Failed to start PBX (call limit reached) \n");
+		ast_channel_hangupcause_set(session->channel, AST_CAUSE_SWITCH_CONGESTION);
+		ast_hangup(session->channel);
+		break;
+	case AST_PBX_SUCCESS:
+	default:
+		break;
+	}
+
+	ast_debug(3, "Started PBX on new GULP channel %s\n", ast_channel_name(session->channel));
+
+	return (res == AST_PBX_SUCCESS) ? 0 : -1;
+}
+
+/*! \brief Function called when a response is received on the session */
+static void gulp_incoming_response(struct ast_sip_session *session, struct pjsip_rx_data *rdata)
+{
+	struct pjsip_status_line status = rdata->msg_info.msg->line.status;
+
+	if (!session->channel) {
+		return;
+	}
+
+	switch (status.code) {
+	case 180:
+		ast_queue_control(session->channel, AST_CONTROL_RINGING);
+		if (ast_channel_state(session->channel) != AST_STATE_UP) {
+			ast_setstate(session->channel, AST_STATE_RINGING);
+		}
+		break;
+	case 183:
+		ast_queue_control(session->channel, AST_CONTROL_PROGRESS);
+		break;
+	case 200:
+		ast_queue_control(session->channel, AST_CONTROL_ANSWER);
+		break;
+	default:
+		break;
+	}
+}
+
+static int gulp_incoming_ack(struct ast_sip_session *session, struct pjsip_rx_data *rdata)
+{
+	if (rdata->msg_info.msg->line.req.method.id == PJSIP_ACK_METHOD) {
+		if (session->endpoint->direct_media) {
+			ast_queue_control(session->channel, AST_CONTROL_SRCCHANGE);
+		}
+	}
+	return 0;
+}
+
+/*!
+ * \brief Load the module
+ *
+ * Module loading including tests for configuration or dependencies.
+ * This function can return AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_DECLINE,
+ * or AST_MODULE_LOAD_SUCCESS. If a dependency or environment variable fails
+ * tests return AST_MODULE_LOAD_FAILURE. If the module can not load the 
+ * configuration file or other non-critical problem return 
+ * AST_MODULE_LOAD_DECLINE. On success return AST_MODULE_LOAD_SUCCESS.
+ */
+static int load_module(void)
+{
+	if (!(gulp_tech.capabilities = ast_format_cap_alloc())) {
+		return AST_MODULE_LOAD_DECLINE;
+	}
+
+	ast_format_cap_add_all_by_type(gulp_tech.capabilities, AST_FORMAT_TYPE_AUDIO);
+
+	ast_rtp_glue_register(&gulp_rtp_glue);
+
+	if (ast_channel_register(&gulp_tech)) {
+		ast_log(LOG_ERROR, "Unable to register channel class %s\n", channel_type);
+		goto end;
+	}
+
+	if (ast_custom_function_register(&gulp_dial_contacts_function)) {
+		ast_log(LOG_ERROR, "Unable to register GULP_DIAL_CONTACTS dialplan function\n");
+		goto end;
+	}
+
+	if (ast_sip_session_register_supplement(&gulp_supplement)) {
+		ast_log(LOG_ERROR, "Unable to register Gulp supplement\n");
+		goto end;
+	}
+
+	if (ast_sip_session_register_supplement(&gulp_ack_supplement)) {
+		ast_log(LOG_ERROR, "Unable to register Gulp ACK supplement\n");
+		ast_sip_session_unregister_supplement(&gulp_supplement);
+		goto end;
+	}
+
+	return 0;
+
+end:
+	ast_custom_function_unregister(&gulp_dial_contacts_function);
+	ast_channel_unregister(&gulp_tech);
+	ast_rtp_glue_unregister(&gulp_rtp_glue);
+
+	return AST_MODULE_LOAD_FAILURE;
+}
+
+/*! \brief Reload module */
+static int reload(void)
+{
+	return -1;
+}
+
+/*! \brief Unload the Gulp channel from Asterisk */
+static int unload_module(void)
+{
+	ast_sip_session_unregister_supplement(&gulp_supplement);
+	ast_custom_function_unregister(&gulp_dial_contacts_function);
+	ast_channel_unregister(&gulp_tech);
+	ast_rtp_glue_unregister(&gulp_rtp_glue);
+
+	return 0;
+}
+
+AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "Gulp SIP Channel Driver",
+		.load = load_module,
+		.unload = unload_module,
+		.reload = reload,
+		.load_pri = AST_MODPRI_CHANNEL_DRIVER,
+	       );
diff --git a/configs/res_sip.conf.sample b/configs/res_sip.conf.sample
new file mode 100644
index 0000000000000000000000000000000000000000..7fd93a72c15f5a403ed15ba63b032807acf95fef
--- /dev/null
+++ b/configs/res_sip.conf.sample
@@ -0,0 +1,24 @@
+; This is an in-flux configuration file for the res_sip module, it will change as things progress
+
+;;; Transports
+[local]
+type=transport
+protocol=udp ; Supported protocols are udp, tcp, and tls
+bind=0.0.0.0 ; This supports both IPv4 and IPv6, port is optional
+
+;;; Endpoints
+[endpoint]
+type=endpoint
+context=default
+disallow=all
+allow=ulaw
+dtmfmode=rfc4733          ; Supported DTMF modes are rfc4733, inband, info, and none
+;transport=local          ; Name of a specific transport to use when placing calls
+;100rel=yes               ; Enable or disable 100rel support - valid options are: yes, no, required
+;timers=yes               ; Enable or disable session timers support - valid options are: yes, no, required, always
+;timers_min_se=90         ; Minimum session timers expiration period, in seconds
+;timers_sess_expires=1800 ; Session timers expiration period, in seconds
+;mohsuggest=example	      ; What musiconhold class to suggest that the peer channel use when this endpoint places them on hold
+;rtp_ipv6=yes             ; Force IPv6 for RTP transport
+;rtp_symmetric=yes        ; Enable symmetric RTP support
+;use_ptime=yes            ; Whether to use the ptime value received from the endpoint or not
diff --git a/configure b/configure
index c4dd40936f9b217c3ce25e2963966457ba4898e4..a7d0ad33757ebaa149aa77a49fe1199d8621d600 100755
--- a/configure
+++ b/configure
@@ -1,12 +1,14 @@
 #! /bin/sh
-# From configure.ac Revision: 382812 .
+# From configure.ac Revision: 383581 .
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for asterisk trunk.
+# Generated by GNU Autoconf 2.65 for asterisk trunk.
 #
 # Report bugs to <https://issues.asterisk.org>.
 #
 #
-# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
+# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
+# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
+# Inc.
 #
 #
 # This configure script is free software; the Free Software Foundation
@@ -92,7 +94,6 @@ fi
 IFS=" ""	$as_nl"
 
 # Find who we are.  Look in the path if we contain no directory separator.
-as_myself=
 case $0 in #((
   *[\\/]* ) as_myself=$0 ;;
   *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
@@ -137,31 +138,6 @@ export LANGUAGE
 # CDPATH.
 (unset CDPATH) >/dev/null 2>&1 && unset CDPATH
 
-# Use a proper internal environment variable to ensure we don't fall
-  # into an infinite loop, continuously re-executing ourselves.
-  if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then
-    _as_can_reexec=no; export _as_can_reexec;
-    # We cannot yet assume a decent shell, so we have to provide a
-# neutralization value for shells without unset; and this also
-# works around shells that cannot unset nonexistent variables.
-# Preserve -v and -x to the replacement shell.
-BASH_ENV=/dev/null
-ENV=/dev/null
-(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
-case $- in # ((((
-  *v*x* | *x*v* ) as_opts=-vx ;;
-  *v* ) as_opts=-v ;;
-  *x* ) as_opts=-x ;;
-  * ) as_opts= ;;
-esac
-exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
-# Admittedly, this is quite paranoid, since all the known shells bail
-# out after a failed `exec'.
-$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
-as_fn_exit 255
-  fi
-  # We don't want this to propagate to other subprocesses.
-          { _as_can_reexec=; unset _as_can_reexec;}
 if test "x$CONFIG_SHELL" = x; then
   as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then :
   emulate sh
@@ -195,8 +171,7 @@ if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then :
 else
   exitcode=1; echo positional parameters were not saved.
 fi
-test x\$exitcode = x0 || exit 1
-test -x / || exit 1"
+test x\$exitcode = x0 || exit 1"
   as_suggested="  as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO
   as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO
   eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" &&
@@ -241,25 +216,14 @@ IFS=$as_save_IFS
 
 
       if test "x$CONFIG_SHELL" != x; then :
-  export CONFIG_SHELL
-             # We cannot yet assume a decent shell, so we have to provide a
-# neutralization value for shells without unset; and this also
-# works around shells that cannot unset nonexistent variables.
-# Preserve -v and -x to the replacement shell.
-BASH_ENV=/dev/null
-ENV=/dev/null
-(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
-case $- in # ((((
-  *v*x* | *x*v* ) as_opts=-vx ;;
-  *v* ) as_opts=-v ;;
-  *x* ) as_opts=-x ;;
-  * ) as_opts= ;;
-esac
-exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
-# Admittedly, this is quite paranoid, since all the known shells bail
-# out after a failed `exec'.
-$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
-exit 255
+  # We cannot yet assume a decent shell, so we have to provide a
+	# neutralization value for shells without unset; and this also
+	# works around shells that cannot unset nonexistent variables.
+	BASH_ENV=/dev/null
+	ENV=/dev/null
+	(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+	export CONFIG_SHELL
+	exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"}
 fi
 
     if test x$as_have_required = xno; then :
@@ -358,18 +322,10 @@ $as_echo X"$as_dir" |
       test -d "$as_dir" && break
     done
     test -z "$as_dirs" || eval "mkdir $as_dirs"
-  } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
+  } || test -d "$as_dir" || as_fn_error "cannot create directory $as_dir"
 
 
 } # as_fn_mkdir_p
-
-# as_fn_executable_p FILE
-# -----------------------
-# Test if FILE is an executable regular file.
-as_fn_executable_p ()
-{
-  test -f "$1" && test -x "$1"
-} # as_fn_executable_p
 # as_fn_append VAR VALUE
 # ----------------------
 # Append the text in VALUE to the end of the definition contained in VAR. Take
@@ -406,19 +362,19 @@ else
 fi # as_fn_arith
 
 
-# as_fn_error STATUS ERROR [LINENO LOG_FD]
-# ----------------------------------------
+# as_fn_error ERROR [LINENO LOG_FD]
+# ---------------------------------
 # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
 # provided, also output the error to LOG_FD, referencing LINENO. Then exit the
-# script with STATUS, using 1 if that was 0.
+# script with status $?, using 1 if that was 0.
 as_fn_error ()
 {
-  as_status=$1; test $as_status -eq 0 && as_status=1
-  if test "$4"; then
-    as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-    $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+  as_status=$?; test $as_status -eq 0 && as_status=1
+  if test "$3"; then
+    as_lineno=${as_lineno-"$2"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+    $as_echo "$as_me:${as_lineno-$LINENO}: error: $1" >&$3
   fi
-  $as_echo "$as_me: error: $2" >&2
+  $as_echo "$as_me: error: $1" >&2
   as_fn_exit $as_status
 } # as_fn_error
 
@@ -491,10 +447,6 @@ as_cr_alnum=$as_cr_Letters$as_cr_digits
   chmod +x "$as_me.lineno" ||
     { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
 
-  # If we had to re-execute with $CONFIG_SHELL, we're ensured to have
-  # already done that, so ensure we don't try to do so again and fall
-  # in an infinite loop.  This has already happened in practice.
-  _as_can_reexec=no; export _as_can_reexec
   # Don't try to exec as it changes $[0], causing all sort of problems
   # (the dirname of $[0] is not the place where we might find the
   # original and so on.  Autoconf is especially sensitive to this).
@@ -529,16 +481,16 @@ if (echo >conf$$.file) 2>/dev/null; then
     # ... but there are two gotchas:
     # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
     # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
-    # In both cases, we have to default to `cp -pR'.
+    # In both cases, we have to default to `cp -p'.
     ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
-      as_ln_s='cp -pR'
+      as_ln_s='cp -p'
   elif ln conf$$.file conf$$ 2>/dev/null; then
     as_ln_s=ln
   else
-    as_ln_s='cp -pR'
+    as_ln_s='cp -p'
   fi
 else
-  as_ln_s='cp -pR'
+  as_ln_s='cp -p'
 fi
 rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
 rmdir conf$$.dir 2>/dev/null
@@ -550,8 +502,28 @@ else
   as_mkdir_p=false
 fi
 
-as_test_x='test -x'
-as_executable_p=as_fn_executable_p
+if test -x / >/dev/null 2>&1; then
+  as_test_x='test -x'
+else
+  if ls -dL / >/dev/null 2>&1; then
+    as_ls_L_option=L
+  else
+    as_ls_L_option=
+  fi
+  as_test_x='
+    eval sh -c '\''
+      if test -d "$1"; then
+	test -d "$1/.";
+      else
+	case $1 in #(
+	-*)set "./$1";;
+	esac;
+	case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #((
+	???[sx]*):;;*)false;;esac;fi
+    '\'' sh
+  '
+fi
+as_executable_p=$as_test_x
 
 # Sed expression to map a string onto a valid CPP name.
 as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
@@ -564,7 +536,7 @@ test -n "$DJDIR" || exec 7<&0 </dev/null
 exec 6>&1
 
 # Name of the host.
-# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status,
+# hostname on some systems (SVR3.2, Linux) returns a bogus exit status,
 # so uname gets run too.
 ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
 
@@ -679,8 +651,6 @@ ILBC_CFLAGS
 ILBC_INTERNAL
 GSM_INTERNAL
 PBX_DAHDI_HALF_FULL
-PKG_CONFIG_LIBDIR
-PKG_CONFIG_PATH
 PKG_CONFIG
 PBX_DLADDR
 PBX_IP_MTU_DISCOVER
@@ -1326,8 +1296,6 @@ CXXFLAGS
 CCC
 CXXCPP
 PKG_CONFIG
-PKG_CONFIG_PATH
-PKG_CONFIG_LIBDIR
 ILBC_CFLAGS
 ILBC_LIBS
 LIBEDIT_CFLAGS
@@ -1400,9 +1368,8 @@ do
   fi
 
   case $ac_option in
-  *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
-  *=)   ac_optarg= ;;
-  *)    ac_optarg=yes ;;
+  *=*)	ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
+  *)	ac_optarg=yes ;;
   esac
 
   # Accept the important Cygnus configure options, so we can diagnose typos.
@@ -1447,7 +1414,7 @@ do
     ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
     # Reject names that are not valid shell variable names.
     expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
-      as_fn_error $? "invalid feature name: $ac_useropt"
+      as_fn_error "invalid feature name: $ac_useropt"
     ac_useropt_orig=$ac_useropt
     ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
     case $ac_user_opts in
@@ -1473,7 +1440,7 @@ do
     ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
     # Reject names that are not valid shell variable names.
     expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
-      as_fn_error $? "invalid feature name: $ac_useropt"
+      as_fn_error "invalid feature name: $ac_useropt"
     ac_useropt_orig=$ac_useropt
     ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
     case $ac_user_opts in
@@ -1677,7 +1644,7 @@ do
     ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
     # Reject names that are not valid shell variable names.
     expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
-      as_fn_error $? "invalid package name: $ac_useropt"
+      as_fn_error "invalid package name: $ac_useropt"
     ac_useropt_orig=$ac_useropt
     ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
     case $ac_user_opts in
@@ -1693,7 +1660,7 @@ do
     ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'`
     # Reject names that are not valid shell variable names.
     expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
-      as_fn_error $? "invalid package name: $ac_useropt"
+      as_fn_error "invalid package name: $ac_useropt"
     ac_useropt_orig=$ac_useropt
     ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
     case $ac_user_opts in
@@ -1723,8 +1690,8 @@ do
   | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
     x_libraries=$ac_optarg ;;
 
-  -*) as_fn_error $? "unrecognized option: \`$ac_option'
-Try \`$0 --help' for more information"
+  -*) as_fn_error "unrecognized option: \`$ac_option'
+Try \`$0 --help' for more information."
     ;;
 
   *=*)
@@ -1732,7 +1699,7 @@ Try \`$0 --help' for more information"
     # Reject names that are not valid shell variable names.
     case $ac_envvar in #(
       '' | [0-9]* | *[!_$as_cr_alnum]* )
-      as_fn_error $? "invalid variable name: \`$ac_envvar'" ;;
+      as_fn_error "invalid variable name: \`$ac_envvar'" ;;
     esac
     eval $ac_envvar=\$ac_optarg
     export $ac_envvar ;;
@@ -1742,7 +1709,7 @@ Try \`$0 --help' for more information"
     $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2
     expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
       $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2
-    : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}"
+    : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}
     ;;
 
   esac
@@ -1750,13 +1717,13 @@ done
 
 if test -n "$ac_prev"; then
   ac_option=--`echo $ac_prev | sed 's/_/-/g'`
-  as_fn_error $? "missing argument to $ac_option"
+  as_fn_error "missing argument to $ac_option"
 fi
 
 if test -n "$ac_unrecognized_opts"; then
   case $enable_option_checking in
     no) ;;
-    fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;;
+    fatal) as_fn_error "unrecognized options: $ac_unrecognized_opts" ;;
     *)     $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;;
   esac
 fi
@@ -1779,7 +1746,7 @@ do
     [\\/$]* | ?:[\\/]* )  continue;;
     NONE | '' ) case $ac_var in *prefix ) continue;; esac;;
   esac
-  as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val"
+  as_fn_error "expected an absolute directory name for --$ac_var: $ac_val"
 done
 
 # There might be people who depend on the old broken behavior: `$host'
@@ -1793,6 +1760,8 @@ target=$target_alias
 if test "x$host_alias" != x; then
   if test "x$build_alias" = x; then
     cross_compiling=maybe
+    $as_echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host.
+    If a cross compiler is detected then cross compile mode will be used." >&2
   elif test "x$build_alias" != "x$host_alias"; then
     cross_compiling=yes
   fi
@@ -1807,9 +1776,9 @@ test "$silent" = yes && exec 6>/dev/null
 ac_pwd=`pwd` && test -n "$ac_pwd" &&
 ac_ls_di=`ls -di .` &&
 ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` ||
-  as_fn_error $? "working directory cannot be determined"
+  as_fn_error "working directory cannot be determined"
 test "X$ac_ls_di" = "X$ac_pwd_ls_di" ||
-  as_fn_error $? "pwd does not report name of working directory"
+  as_fn_error "pwd does not report name of working directory"
 
 
 # Find the source files, if location was not specified.
@@ -1848,11 +1817,11 @@ else
 fi
 if test ! -r "$srcdir/$ac_unique_file"; then
   test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."
-  as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir"
+  as_fn_error "cannot find sources ($ac_unique_file) in $srcdir"
 fi
 ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work"
 ac_abs_confdir=`(
-	cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg"
+	cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error "$ac_msg"
 	pwd)`
 # When building in place, set srcdir=.
 if test "$ac_abs_confdir" = "$ac_pwd"; then
@@ -1892,7 +1861,7 @@ Configuration:
       --help=short        display options specific to this package
       --help=recursive    display the short help of all the included packages
   -V, --version           display version information and exit
-  -q, --quiet, --silent   do not print \`checking ...' messages
+  -q, --quiet, --silent   do not print \`checking...' messages
       --cache-file=FILE   cache test results in FILE [disabled]
   -C, --config-cache      alias for \`--cache-file=config.cache'
   -n, --no-create         do not create output files
@@ -2056,10 +2025,6 @@ Some influential environment variables:
   CXXFLAGS    C++ compiler flags
   CXXCPP      C++ preprocessor
   PKG_CONFIG  path to pkg-config utility
-  PKG_CONFIG_PATH
-              directories to add to pkg-config's search path
-  PKG_CONFIG_LIBDIR
-              path overriding pkg-config's built-in search path
   ILBC_CFLAGS C compiler flags for ILBC, overriding pkg-config
   ILBC_LIBS   linker flags for ILBC, overriding pkg-config
   LIBEDIT_CFLAGS
@@ -2143,9 +2108,9 @@ test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
 asterisk configure trunk
-generated by GNU Autoconf 2.69
+generated by GNU Autoconf 2.65
 
-Copyright (C) 2012 Free Software Foundation, Inc.
+Copyright (C) 2009 Free Software Foundation, Inc.
 This configure script is free software; the Free Software Foundation
 gives unlimited permission to copy, distribute and modify it.
 
@@ -2191,7 +2156,7 @@ sed 's/^/| /' conftest.$ac_ext >&5
 
 	ac_retval=1
 fi
-  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
   as_fn_set_status $ac_retval
 
 } # ac_fn_c_try_compile
@@ -2217,7 +2182,7 @@ $as_echo "$ac_try_echo"; } >&5
     mv -f conftest.er1 conftest.err
   fi
   $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; } > conftest.i && {
+  test $ac_status = 0; } >/dev/null && {
 	 test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
 	 test ! -s conftest.err
        }; then :
@@ -2228,7 +2193,7 @@ sed 's/^/| /' conftest.$ac_ext >&5
 
     ac_retval=1
 fi
-  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
   as_fn_set_status $ac_retval
 
 } # ac_fn_c_try_cpp
@@ -2241,10 +2206,10 @@ fi
 ac_fn_c_check_header_mongrel ()
 {
   as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-  if eval \${$3+:} false; then :
+  if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
 $as_echo_n "checking for $2... " >&6; }
-if eval \${$3+:} false; then :
+if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
   $as_echo_n "(cached) " >&6
 fi
 eval ac_res=\$$3
@@ -2280,7 +2245,7 @@ if ac_fn_c_try_cpp "$LINENO"; then :
 else
   ac_header_preproc=no
 fi
-rm -f conftest.err conftest.i conftest.$ac_ext
+rm -f conftest.err conftest.$ac_ext
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5
 $as_echo "$ac_header_preproc" >&6; }
 
@@ -2303,15 +2268,17 @@ $as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;}
 $as_echo "$as_me: WARNING: $2:     section \"Present But Cannot Be Compiled\"" >&2;}
     { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
-( $as_echo "## ------------------------------------------ ##
+( cat <<\_ASBOX
+## ------------------------------------------ ##
 ## Report this to https://issues.asterisk.org ##
-## ------------------------------------------ ##"
+## ------------------------------------------ ##
+_ASBOX
      ) | sed "s/^/$as_me: WARNING:     /" >&2
     ;;
 esac
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
 $as_echo_n "checking for $2... " >&6; }
-if eval \${$3+:} false; then :
+if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
   $as_echo_n "(cached) " >&6
 else
   eval "$3=\$ac_header_compiler"
@@ -2320,7 +2287,7 @@ eval ac_res=\$$3
 	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
 $as_echo "$ac_res" >&6; }
 fi
-  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
 
 } # ac_fn_c_check_header_mongrel
 
@@ -2361,7 +2328,7 @@ sed 's/^/| /' conftest.$ac_ext >&5
        ac_retval=$ac_status
 fi
   rm -rf conftest.dSYM conftest_ipa8_conftest.oo
-  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
   as_fn_set_status $ac_retval
 
 } # ac_fn_c_try_run
@@ -2375,7 +2342,7 @@ ac_fn_c_check_header_compile ()
   as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
 $as_echo_n "checking for $2... " >&6; }
-if eval \${$3+:} false; then :
+if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
   $as_echo_n "(cached) " >&6
 else
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -2393,7 +2360,7 @@ fi
 eval ac_res=\$$3
 	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
 $as_echo "$ac_res" >&6; }
-  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
 
 } # ac_fn_c_check_header_compile
 
@@ -2430,7 +2397,7 @@ sed 's/^/| /' conftest.$ac_ext >&5
 
 	ac_retval=1
 fi
-  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
   as_fn_set_status $ac_retval
 
 } # ac_fn_cxx_try_compile
@@ -2456,7 +2423,7 @@ $as_echo "$ac_try_echo"; } >&5
     mv -f conftest.er1 conftest.err
   fi
   $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; } > conftest.i && {
+  test $ac_status = 0; } >/dev/null && {
 	 test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" ||
 	 test ! -s conftest.err
        }; then :
@@ -2467,7 +2434,7 @@ sed 's/^/| /' conftest.$ac_ext >&5
 
     ac_retval=1
 fi
-  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
   as_fn_set_status $ac_retval
 
 } # ac_fn_cxx_try_cpp
@@ -2499,7 +2466,7 @@ $as_echo "$ac_try_echo"; } >&5
 	 test ! -s conftest.err
        } && test -s conftest$ac_exeext && {
 	 test "$cross_compiling" = yes ||
-	 test -x conftest$ac_exeext
+	 $as_test_x conftest$ac_exeext
        }; then :
   ac_retval=0
 else
@@ -2513,7 +2480,7 @@ fi
   # interfere with the next link command; also delete a directory that is
   # left behind by Apple's compiler.  We do this before executing the actions.
   rm -rf conftest.dSYM conftest_ipa8_conftest.oo
-  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
   as_fn_set_status $ac_retval
 
 } # ac_fn_c_try_link
@@ -2526,7 +2493,7 @@ ac_fn_c_check_func ()
   as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
 $as_echo_n "checking for $2... " >&6; }
-if eval \${$3+:} false; then :
+if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
   $as_echo_n "(cached) " >&6
 else
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -2581,7 +2548,7 @@ fi
 eval ac_res=\$$3
 	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
 $as_echo "$ac_res" >&6; }
-  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
 
 } # ac_fn_c_check_func
 
@@ -2594,7 +2561,7 @@ ac_fn_c_check_type ()
   as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
 $as_echo_n "checking for $2... " >&6; }
-if eval \${$3+:} false; then :
+if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
   $as_echo_n "(cached) " >&6
 else
   eval "$3=no"
@@ -2635,7 +2602,7 @@ fi
 eval ac_res=\$$3
 	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
 $as_echo "$ac_res" >&6; }
-  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
 
 } # ac_fn_c_check_type
 
@@ -2648,7 +2615,7 @@ ac_fn_c_check_member ()
   as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2.$3" >&5
 $as_echo_n "checking for $2.$3... " >&6; }
-if eval \${$4+:} false; then :
+if { as_var=$4; eval "test \"\${$as_var+set}\" = set"; }; then :
   $as_echo_n "(cached) " >&6
 else
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -2692,7 +2659,7 @@ fi
 eval ac_res=\$$4
 	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
 $as_echo "$ac_res" >&6; }
-  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
 
 } # ac_fn_c_check_member
 
@@ -2713,8 +2680,7 @@ int
 main ()
 {
 static int test_array [1 - 2 * !(($2) >= 0)];
-test_array [0] = 0;
-return test_array [0];
+test_array [0] = 0
 
   ;
   return 0;
@@ -2730,8 +2696,7 @@ int
 main ()
 {
 static int test_array [1 - 2 * !(($2) <= $ac_mid)];
-test_array [0] = 0;
-return test_array [0];
+test_array [0] = 0
 
   ;
   return 0;
@@ -2757,8 +2722,7 @@ int
 main ()
 {
 static int test_array [1 - 2 * !(($2) < 0)];
-test_array [0] = 0;
-return test_array [0];
+test_array [0] = 0
 
   ;
   return 0;
@@ -2774,8 +2738,7 @@ int
 main ()
 {
 static int test_array [1 - 2 * !(($2) >= $ac_mid)];
-test_array [0] = 0;
-return test_array [0];
+test_array [0] = 0
 
   ;
   return 0;
@@ -2809,8 +2772,7 @@ int
 main ()
 {
 static int test_array [1 - 2 * !(($2) <= $ac_mid)];
-test_array [0] = 0;
-return test_array [0];
+test_array [0] = 0
 
   ;
   return 0;
@@ -2874,7 +2836,7 @@ rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
 rm -f conftest.val
 
   fi
-  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
   as_fn_set_status $ac_retval
 
 } # ac_fn_c_compute_int
@@ -2887,10 +2849,10 @@ rm -f conftest.val
 ac_fn_cxx_check_header_mongrel ()
 {
   as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-  if eval \${$3+:} false; then :
+  if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
 $as_echo_n "checking for $2... " >&6; }
-if eval \${$3+:} false; then :
+if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
   $as_echo_n "(cached) " >&6
 fi
 eval ac_res=\$$3
@@ -2926,7 +2888,7 @@ if ac_fn_cxx_try_cpp "$LINENO"; then :
 else
   ac_header_preproc=no
 fi
-rm -f conftest.err conftest.i conftest.$ac_ext
+rm -f conftest.err conftest.$ac_ext
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5
 $as_echo "$ac_header_preproc" >&6; }
 
@@ -2949,15 +2911,17 @@ $as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;}
 $as_echo "$as_me: WARNING: $2:     section \"Present But Cannot Be Compiled\"" >&2;}
     { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
-( $as_echo "## ------------------------------------------ ##
+( cat <<\_ASBOX
+## ------------------------------------------ ##
 ## Report this to https://issues.asterisk.org ##
-## ------------------------------------------ ##"
+## ------------------------------------------ ##
+_ASBOX
      ) | sed "s/^/$as_me: WARNING:     /" >&2
     ;;
 esac
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
 $as_echo_n "checking for $2... " >&6; }
-if eval \${$3+:} false; then :
+if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
   $as_echo_n "(cached) " >&6
 else
   eval "$3=\$ac_header_compiler"
@@ -2966,7 +2930,7 @@ eval ac_res=\$$3
 	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
 $as_echo "$ac_res" >&6; }
 fi
-  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
 
 } # ac_fn_cxx_check_header_mongrel
 
@@ -2997,7 +2961,7 @@ $as_echo "$ac_try_echo"; } >&5
 	 test ! -s conftest.err
        } && test -s conftest$ac_exeext && {
 	 test "$cross_compiling" = yes ||
-	 test -x conftest$ac_exeext
+	 $as_test_x conftest$ac_exeext
        }; then :
   ac_retval=0
 else
@@ -3011,7 +2975,7 @@ fi
   # interfere with the next link command; also delete a directory that is
   # left behind by Apple's compiler.  We do this before executing the actions.
   rm -rf conftest.dSYM conftest_ipa8_conftest.oo
-  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
   as_fn_set_status $ac_retval
 
 } # ac_fn_cxx_try_link
@@ -3025,7 +2989,7 @@ ac_fn_cxx_check_header_compile ()
   as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
 $as_echo_n "checking for $2... " >&6; }
-if eval \${$3+:} false; then :
+if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
   $as_echo_n "(cached) " >&6
 else
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -3043,7 +3007,7 @@ fi
 eval ac_res=\$$3
 	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
 $as_echo "$ac_res" >&6; }
-  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
 
 } # ac_fn_cxx_check_header_compile
 cat >config.log <<_ACEOF
@@ -3051,7 +3015,7 @@ This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
 It was created by asterisk $as_me trunk, which was
-generated by GNU Autoconf 2.69.  Invocation command line was
+generated by GNU Autoconf 2.65.  Invocation command line was
 
   $ $0 $@
 
@@ -3161,9 +3125,11 @@ trap 'exit_status=$?
   {
     echo
 
-    $as_echo "## ---------------- ##
+    cat <<\_ASBOX
+## ---------------- ##
 ## Cache variables. ##
-## ---------------- ##"
+## ---------------- ##
+_ASBOX
     echo
     # The following way of writing the cache mishandles newlines in values,
 (
@@ -3197,9 +3163,11 @@ $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
 )
     echo
 
-    $as_echo "## ----------------- ##
+    cat <<\_ASBOX
+## ----------------- ##
 ## Output variables. ##
-## ----------------- ##"
+## ----------------- ##
+_ASBOX
     echo
     for ac_var in $ac_subst_vars
     do
@@ -3212,9 +3180,11 @@ $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
     echo
 
     if test -n "$ac_subst_files"; then
-      $as_echo "## ------------------- ##
+      cat <<\_ASBOX
+## ------------------- ##
 ## File substitutions. ##
-## ------------------- ##"
+## ------------------- ##
+_ASBOX
       echo
       for ac_var in $ac_subst_files
       do
@@ -3228,9 +3198,11 @@ $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
     fi
 
     if test -s confdefs.h; then
-      $as_echo "## ----------- ##
+      cat <<\_ASBOX
+## ----------- ##
 ## confdefs.h. ##
-## ----------- ##"
+## ----------- ##
+_ASBOX
       echo
       cat confdefs.h
       echo
@@ -3285,12 +3257,7 @@ _ACEOF
 ac_site_file1=NONE
 ac_site_file2=NONE
 if test -n "$CONFIG_SITE"; then
-  # We do not want a PATH search for config.site.
-  case $CONFIG_SITE in #((
-    -*)  ac_site_file1=./$CONFIG_SITE;;
-    */*) ac_site_file1=$CONFIG_SITE;;
-    *)   ac_site_file1=./$CONFIG_SITE;;
-  esac
+  ac_site_file1=$CONFIG_SITE
 elif test "x$prefix" != xNONE; then
   ac_site_file1=$prefix/share/config.site
   ac_site_file2=$prefix/etc/config.site
@@ -3305,11 +3272,7 @@ do
     { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5
 $as_echo "$as_me: loading site script $ac_site_file" >&6;}
     sed 's/^/| /' "$ac_site_file" >&5
-    . "$ac_site_file" \
-      || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error $? "failed to load site script $ac_site_file
-See \`config.log' for more details" "$LINENO" 5; }
+    . "$ac_site_file"
   fi
 done
 
@@ -3389,7 +3352,7 @@ if $ac_cache_corrupted; then
 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
   { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5
 $as_echo "$as_me: error: changes in the environment can compromise the build" >&2;}
-  as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5
+  as_fn_error "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5
 fi
 ## -------------------- ##
 ## Main body of script. ##
@@ -3406,22 +3369,16 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
 # cross-compile macros
 ac_aux_dir=
 for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do
-  if test -f "$ac_dir/install-sh"; then
-    ac_aux_dir=$ac_dir
-    ac_install_sh="$ac_aux_dir/install-sh -c"
-    break
-  elif test -f "$ac_dir/install.sh"; then
-    ac_aux_dir=$ac_dir
-    ac_install_sh="$ac_aux_dir/install.sh -c"
-    break
-  elif test -f "$ac_dir/shtool"; then
-    ac_aux_dir=$ac_dir
-    ac_install_sh="$ac_aux_dir/shtool install -c"
-    break
-  fi
+  for ac_t in install-sh install.sh shtool; do
+    if test -f "$ac_dir/$ac_t"; then
+      ac_aux_dir=$ac_dir
+      ac_install_sh="$ac_aux_dir/$ac_t -c"
+      break 2
+    fi
+  done
 done
 if test -z "$ac_aux_dir"; then
-  as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5
+  as_fn_error "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5
 fi
 
 # These three variables are undocumented and unsupported,
@@ -3435,27 +3392,27 @@ ac_configure="$SHELL $ac_aux_dir/configure"  # Please don't use this var.
 
 # Make sure we can run config.sub.
 $SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 ||
-  as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5
+  as_fn_error "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5
 $as_echo_n "checking build system type... " >&6; }
-if ${ac_cv_build+:} false; then :
+if test "${ac_cv_build+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   ac_build_alias=$build_alias
 test "x$ac_build_alias" = x &&
   ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"`
 test "x$ac_build_alias" = x &&
-  as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5
+  as_fn_error "cannot guess build type; you must specify one" "$LINENO" 5
 ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` ||
-  as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5
+  as_fn_error "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5
 
 fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5
 $as_echo "$ac_cv_build" >&6; }
 case $ac_cv_build in
 *-*-*) ;;
-*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;;
+*) as_fn_error "invalid value of canonical build" "$LINENO" 5;;
 esac
 build=$ac_cv_build
 ac_save_IFS=$IFS; IFS='-'
@@ -3473,14 +3430,14 @@ case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5
 $as_echo_n "checking host system type... " >&6; }
-if ${ac_cv_host+:} false; then :
+if test "${ac_cv_host+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   if test "x$host_alias" = x; then
   ac_cv_host=$ac_cv_build
 else
   ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` ||
-    as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5
+    as_fn_error "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5
 fi
 
 fi
@@ -3488,7 +3445,7 @@ fi
 $as_echo "$ac_cv_host" >&6; }
 case $ac_cv_host in
 *-*-*) ;;
-*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;;
+*) as_fn_error "invalid value of canonical host" "$LINENO" 5;;
 esac
 host=$ac_cv_host
 ac_save_IFS=$IFS; IFS='-'
@@ -3510,22 +3467,16 @@ case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac
 
 ac_aux_dir=
 for ac_dir in `pwd` "$srcdir"/`pwd`; do
-  if test -f "$ac_dir/install-sh"; then
-    ac_aux_dir=$ac_dir
-    ac_install_sh="$ac_aux_dir/install-sh -c"
-    break
-  elif test -f "$ac_dir/install.sh"; then
-    ac_aux_dir=$ac_dir
-    ac_install_sh="$ac_aux_dir/install.sh -c"
-    break
-  elif test -f "$ac_dir/shtool"; then
-    ac_aux_dir=$ac_dir
-    ac_install_sh="$ac_aux_dir/shtool install -c"
-    break
-  fi
+  for ac_t in install-sh install.sh shtool; do
+    if test -f "$ac_dir/$ac_t"; then
+      ac_aux_dir=$ac_dir
+      ac_install_sh="$ac_aux_dir/$ac_t -c"
+      break 2
+    fi
+  done
 done
 if test -z "$ac_aux_dir"; then
-  as_fn_error $? "cannot find install-sh, install.sh, or shtool in \`pwd\` \"$srcdir\"/\`pwd\`" "$LINENO" 5
+  as_fn_error "cannot find install-sh, install.sh, or shtool in \`pwd\` \"$srcdir\"/\`pwd\`" "$LINENO" 5
 fi
 
 # These three variables are undocumented and unsupported,
@@ -3571,7 +3522,7 @@ if test -n "$ac_tool_prefix"; then
 set dummy $ac_tool_prefix$ac_prog; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_CC+:} false; then :
+if test "${ac_cv_prog_CC+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   if test -n "$CC"; then
@@ -3583,7 +3534,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
     ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -3615,7 +3566,7 @@ do
 set dummy $ac_prog; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_ac_ct_CC+:} false; then :
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   if test -n "$ac_ct_CC"; then
@@ -3627,7 +3578,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
     ac_cv_prog_ac_ct_CC="$ac_prog"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -3667,8 +3618,8 @@ fi
 
 test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error $? "no acceptable C compiler found in \$PATH
-See \`config.log' for more details" "$LINENO" 5; }
+as_fn_error "no acceptable C compiler found in \$PATH
+See \`config.log' for more details." "$LINENO" 5; }
 
 # Provide some information about the compiler.
 $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
@@ -3782,8 +3733,9 @@ sed 's/^/| /' conftest.$ac_ext >&5
 
 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error 77 "C compiler cannot create executables
-See \`config.log' for more details" "$LINENO" 5; }
+{ as_fn_set_status 77
+as_fn_error "C compiler cannot create executables
+See \`config.log' for more details." "$LINENO" 5; }; }
 else
   { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
 $as_echo "yes" >&6; }
@@ -3825,8 +3777,8 @@ done
 else
   { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error $? "cannot compute suffix of executables: cannot compile and link
-See \`config.log' for more details" "$LINENO" 5; }
+as_fn_error "cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." "$LINENO" 5; }
 fi
 rm -f conftest conftest$ac_cv_exeext
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5
@@ -3883,9 +3835,9 @@ $as_echo "$ac_try_echo"; } >&5
     else
 	{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error $? "cannot run C compiled programs.
+as_fn_error "cannot run C compiled programs.
 If you meant to cross compile, use \`--host'.
-See \`config.log' for more details" "$LINENO" 5; }
+See \`config.log' for more details." "$LINENO" 5; }
     fi
   fi
 fi
@@ -3896,7 +3848,7 @@ rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out
 ac_clean_files=$ac_clean_files_save
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5
 $as_echo_n "checking for suffix of object files... " >&6; }
-if ${ac_cv_objext+:} false; then :
+if test "${ac_cv_objext+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -3936,8 +3888,8 @@ sed 's/^/| /' conftest.$ac_ext >&5
 
 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error $? "cannot compute suffix of object files: cannot compile
-See \`config.log' for more details" "$LINENO" 5; }
+as_fn_error "cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." "$LINENO" 5; }
 fi
 rm -f conftest.$ac_cv_objext conftest.$ac_ext
 fi
@@ -3947,7 +3899,7 @@ OBJEXT=$ac_cv_objext
 ac_objext=$OBJEXT
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5
 $as_echo_n "checking whether we are using the GNU C compiler... " >&6; }
-if ${ac_cv_c_compiler_gnu+:} false; then :
+if test "${ac_cv_c_compiler_gnu+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -3984,7 +3936,7 @@ ac_test_CFLAGS=${CFLAGS+set}
 ac_save_CFLAGS=$CFLAGS
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
 $as_echo_n "checking whether $CC accepts -g... " >&6; }
-if ${ac_cv_prog_cc_g+:} false; then :
+if test "${ac_cv_prog_cc_g+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   ac_save_c_werror_flag=$ac_c_werror_flag
@@ -4062,7 +4014,7 @@ else
 fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5
 $as_echo_n "checking for $CC option to accept ISO C89... " >&6; }
-if ${ac_cv_prog_cc_c89+:} false; then :
+if test "${ac_cv_prog_cc_c89+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   ac_cv_prog_cc_c89=no
@@ -4071,7 +4023,8 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 #include <stdarg.h>
 #include <stdio.h>
-struct stat;
+#include <sys/types.h>
+#include <sys/stat.h>
 /* Most of the following tests are stolen from RCS 5.7's src/conf.sh.  */
 struct buf { int x; };
 FILE * (*rcsopen) (struct buf *, struct stat *, int);
@@ -4170,7 +4123,7 @@ if test -n "$CPP" && test -d "$CPP"; then
   CPP=
 fi
 if test -z "$CPP"; then
-  if ${ac_cv_prog_CPP+:} false; then :
+  if test "${ac_cv_prog_CPP+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
       # Double quotes because CPP needs to be expanded
@@ -4200,7 +4153,7 @@ else
   # Broken: fails on valid input.
 continue
 fi
-rm -f conftest.err conftest.i conftest.$ac_ext
+rm -f conftest.err conftest.$ac_ext
 
   # OK, works on sane cases.  Now check whether nonexistent headers
   # can be detected and how.
@@ -4216,11 +4169,11 @@ else
 ac_preproc_ok=:
 break
 fi
-rm -f conftest.err conftest.i conftest.$ac_ext
+rm -f conftest.err conftest.$ac_ext
 
 done
 # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
-rm -f conftest.i conftest.err conftest.$ac_ext
+rm -f conftest.err conftest.$ac_ext
 if $ac_preproc_ok; then :
   break
 fi
@@ -4259,7 +4212,7 @@ else
   # Broken: fails on valid input.
 continue
 fi
-rm -f conftest.err conftest.i conftest.$ac_ext
+rm -f conftest.err conftest.$ac_ext
 
   # OK, works on sane cases.  Now check whether nonexistent headers
   # can be detected and how.
@@ -4275,18 +4228,18 @@ else
 ac_preproc_ok=:
 break
 fi
-rm -f conftest.err conftest.i conftest.$ac_ext
+rm -f conftest.err conftest.$ac_ext
 
 done
 # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
-rm -f conftest.i conftest.err conftest.$ac_ext
+rm -f conftest.err conftest.$ac_ext
 if $ac_preproc_ok; then :
 
 else
   { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error $? "C preprocessor \"$CPP\" fails sanity check
-See \`config.log' for more details" "$LINENO" 5; }
+as_fn_error "C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." "$LINENO" 5; }
 fi
 
 ac_ext=c
@@ -4298,7 +4251,7 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5
 $as_echo_n "checking for grep that handles long lines and -e... " >&6; }
-if ${ac_cv_path_GREP+:} false; then :
+if test "${ac_cv_path_GREP+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   if test -z "$GREP"; then
@@ -4312,7 +4265,7 @@ do
     for ac_prog in grep ggrep; do
     for ac_exec_ext in '' $ac_executable_extensions; do
       ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
-      as_fn_executable_p "$ac_path_GREP" || continue
+      { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue
 # Check for GNU ac_path_GREP and select it if it is found.
   # Check for GNU $ac_path_GREP
 case `"$ac_path_GREP" --version 2>&1` in
@@ -4347,7 +4300,7 @@ esac
   done
 IFS=$as_save_IFS
   if test -z "$ac_cv_path_GREP"; then
-    as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+    as_fn_error "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
   fi
 else
   ac_cv_path_GREP=$GREP
@@ -4361,7 +4314,7 @@ $as_echo "$ac_cv_path_GREP" >&6; }
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5
 $as_echo_n "checking for egrep... " >&6; }
-if ${ac_cv_path_EGREP+:} false; then :
+if test "${ac_cv_path_EGREP+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
@@ -4378,7 +4331,7 @@ do
     for ac_prog in egrep; do
     for ac_exec_ext in '' $ac_executable_extensions; do
       ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
-      as_fn_executable_p "$ac_path_EGREP" || continue
+      { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue
 # Check for GNU ac_path_EGREP and select it if it is found.
   # Check for GNU $ac_path_EGREP
 case `"$ac_path_EGREP" --version 2>&1` in
@@ -4413,7 +4366,7 @@ esac
   done
 IFS=$as_save_IFS
   if test -z "$ac_cv_path_EGREP"; then
-    as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+    as_fn_error "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
   fi
 else
   ac_cv_path_EGREP=$EGREP
@@ -4428,7 +4381,7 @@ $as_echo "$ac_cv_path_EGREP" >&6; }
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
 $as_echo_n "checking for ANSI C header files... " >&6; }
-if ${ac_cv_header_stdc+:} false; then :
+if test "${ac_cv_header_stdc+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -4545,7 +4498,8 @@ do :
   as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
 ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
 "
-if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+eval as_val=\$$as_ac_Header
+   if test "x$as_val" = x""yes; then :
   cat >>confdefs.h <<_ACEOF
 #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
 _ACEOF
@@ -4557,7 +4511,7 @@ done
 
 
   ac_fn_c_check_header_mongrel "$LINENO" "minix/config.h" "ac_cv_header_minix_config_h" "$ac_includes_default"
-if test "x$ac_cv_header_minix_config_h" = xyes; then :
+if test "x$ac_cv_header_minix_config_h" = x""yes; then :
   MINIX=yes
 else
   MINIX=
@@ -4579,14 +4533,14 @@ $as_echo "#define _MINIX 1" >>confdefs.h
 
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether it is safe to define __EXTENSIONS__" >&5
 $as_echo_n "checking whether it is safe to define __EXTENSIONS__... " >&6; }
-if ${ac_cv_safe_to_define___extensions__+:} false; then :
+if test "${ac_cv_safe_to_define___extensions__+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
-#         define __EXTENSIONS__ 1
-          $ac_includes_default
+#	  define __EXTENSIONS__ 1
+	  $ac_includes_default
 int
 main ()
 {
@@ -4775,7 +4729,7 @@ if test -n "$ac_tool_prefix"; then
 set dummy ${ac_tool_prefix}uname; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_path_UNAME+:} false; then :
+if test "${ac_cv_path_UNAME+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   case $UNAME in
@@ -4789,7 +4743,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
     ac_cv_path_UNAME="$as_dir/$ac_word$ac_exec_ext"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -4818,7 +4772,7 @@ if test -z "$ac_cv_path_UNAME"; then
 set dummy uname; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_path_ac_pt_UNAME+:} false; then :
+if test "${ac_cv_path_ac_pt_UNAME+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   case $ac_pt_UNAME in
@@ -4832,7 +4786,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
     ac_cv_path_ac_pt_UNAME="$as_dir/$ac_word$ac_exec_ext"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -4885,7 +4839,7 @@ then
 set dummy ${ac_tool_prefix}gcc; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_CC+:} false; then :
+if test "${ac_cv_prog_CC+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   if test -n "$CC"; then
@@ -4897,7 +4851,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
     ac_cv_prog_CC="${ac_tool_prefix}gcc"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -4925,7 +4879,7 @@ if test -z "$ac_cv_prog_CC"; then
 set dummy gcc; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_ac_ct_CC+:} false; then :
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   if test -n "$ac_ct_CC"; then
@@ -4937,7 +4891,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
     ac_cv_prog_ac_ct_CC="gcc"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -4977,7 +4931,7 @@ fi
 set dummy ${ac_tool_prefix}g++; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_CXX+:} false; then :
+if test "${ac_cv_prog_CXX+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   if test -n "$CXX"; then
@@ -4989,7 +4943,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
     ac_cv_prog_CXX="${ac_tool_prefix}g++"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -5017,7 +4971,7 @@ if test -z "$ac_cv_prog_CXX"; then
 set dummy g++; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_ac_ct_CXX+:} false; then :
+if test "${ac_cv_prog_ac_ct_CXX+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   if test -n "$ac_ct_CXX"; then
@@ -5029,7 +4983,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
     ac_cv_prog_ac_ct_CXX="g++"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -5069,7 +5023,7 @@ fi
 set dummy ${ac_tool_prefix}ld; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_LD+:} false; then :
+if test "${ac_cv_prog_LD+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   if test -n "$LD"; then
@@ -5081,7 +5035,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
     ac_cv_prog_LD="${ac_tool_prefix}ld"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -5109,7 +5063,7 @@ if test -z "$ac_cv_prog_LD"; then
 set dummy ld; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_ac_ct_LD+:} false; then :
+if test "${ac_cv_prog_ac_ct_LD+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   if test -n "$ac_ct_LD"; then
@@ -5121,7 +5075,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
     ac_cv_prog_ac_ct_LD="ld"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -5161,7 +5115,7 @@ fi
 set dummy ${ac_tool_prefix}ranlib; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_RANLIB+:} false; then :
+if test "${ac_cv_prog_RANLIB+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   if test -n "$RANLIB"; then
@@ -5173,7 +5127,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
     ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -5201,7 +5155,7 @@ if test -z "$ac_cv_prog_RANLIB"; then
 set dummy ranlib; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_ac_ct_RANLIB+:} false; then :
+if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   if test -n "$ac_ct_RANLIB"; then
@@ -5213,7 +5167,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
     ac_cv_prog_ac_ct_RANLIB="ranlib"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -5267,7 +5221,7 @@ if test -z "$CXX"; then
 set dummy $ac_tool_prefix$ac_prog; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_CXX+:} false; then :
+if test "${ac_cv_prog_CXX+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   if test -n "$CXX"; then
@@ -5279,7 +5233,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
     ac_cv_prog_CXX="$ac_tool_prefix$ac_prog"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -5311,7 +5265,7 @@ do
 set dummy $ac_prog; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_ac_ct_CXX+:} false; then :
+if test "${ac_cv_prog_ac_ct_CXX+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   if test -n "$ac_ct_CXX"; then
@@ -5323,7 +5277,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
     ac_cv_prog_ac_ct_CXX="$ac_prog"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -5389,7 +5343,7 @@ done
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5
 $as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; }
-if ${ac_cv_cxx_compiler_gnu+:} false; then :
+if test "${ac_cv_cxx_compiler_gnu+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -5426,7 +5380,7 @@ ac_test_CXXFLAGS=${CXXFLAGS+set}
 ac_save_CXXFLAGS=$CXXFLAGS
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5
 $as_echo_n "checking whether $CXX accepts -g... " >&6; }
-if ${ac_cv_prog_cxx_g+:} false; then :
+if test "${ac_cv_prog_cxx_g+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   ac_save_cxx_werror_flag=$ac_cxx_werror_flag
@@ -5520,7 +5474,7 @@ if test -n "$CPP" && test -d "$CPP"; then
   CPP=
 fi
 if test -z "$CPP"; then
-  if ${ac_cv_prog_CPP+:} false; then :
+  if test "${ac_cv_prog_CPP+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
       # Double quotes because CPP needs to be expanded
@@ -5550,7 +5504,7 @@ else
   # Broken: fails on valid input.
 continue
 fi
-rm -f conftest.err conftest.i conftest.$ac_ext
+rm -f conftest.err conftest.$ac_ext
 
   # OK, works on sane cases.  Now check whether nonexistent headers
   # can be detected and how.
@@ -5566,11 +5520,11 @@ else
 ac_preproc_ok=:
 break
 fi
-rm -f conftest.err conftest.i conftest.$ac_ext
+rm -f conftest.err conftest.$ac_ext
 
 done
 # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
-rm -f conftest.i conftest.err conftest.$ac_ext
+rm -f conftest.err conftest.$ac_ext
 if $ac_preproc_ok; then :
   break
 fi
@@ -5609,7 +5563,7 @@ else
   # Broken: fails on valid input.
 continue
 fi
-rm -f conftest.err conftest.i conftest.$ac_ext
+rm -f conftest.err conftest.$ac_ext
 
   # OK, works on sane cases.  Now check whether nonexistent headers
   # can be detected and how.
@@ -5625,18 +5579,18 @@ else
 ac_preproc_ok=:
 break
 fi
-rm -f conftest.err conftest.i conftest.$ac_ext
+rm -f conftest.err conftest.$ac_ext
 
 done
 # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
-rm -f conftest.i conftest.err conftest.$ac_ext
+rm -f conftest.err conftest.$ac_ext
 if $ac_preproc_ok; then :
 
 else
   { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error $? "C preprocessor \"$CPP\" fails sanity check
-See \`config.log' for more details" "$LINENO" 5; }
+as_fn_error "C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." "$LINENO" 5; }
 fi
 
 ac_ext=c
@@ -5653,7 +5607,7 @@ ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C++ preprocessor" >&5
 $as_echo_n "checking how to run the C++ preprocessor... " >&6; }
 if test -z "$CXXCPP"; then
-  if ${ac_cv_prog_CXXCPP+:} false; then :
+  if test "${ac_cv_prog_CXXCPP+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
       # Double quotes because CXXCPP needs to be expanded
@@ -5683,7 +5637,7 @@ else
   # Broken: fails on valid input.
 continue
 fi
-rm -f conftest.err conftest.i conftest.$ac_ext
+rm -f conftest.err conftest.$ac_ext
 
   # OK, works on sane cases.  Now check whether nonexistent headers
   # can be detected and how.
@@ -5699,11 +5653,11 @@ else
 ac_preproc_ok=:
 break
 fi
-rm -f conftest.err conftest.i conftest.$ac_ext
+rm -f conftest.err conftest.$ac_ext
 
 done
 # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
-rm -f conftest.i conftest.err conftest.$ac_ext
+rm -f conftest.err conftest.$ac_ext
 if $ac_preproc_ok; then :
   break
 fi
@@ -5742,7 +5696,7 @@ else
   # Broken: fails on valid input.
 continue
 fi
-rm -f conftest.err conftest.i conftest.$ac_ext
+rm -f conftest.err conftest.$ac_ext
 
   # OK, works on sane cases.  Now check whether nonexistent headers
   # can be detected and how.
@@ -5758,18 +5712,18 @@ else
 ac_preproc_ok=:
 break
 fi
-rm -f conftest.err conftest.i conftest.$ac_ext
+rm -f conftest.err conftest.$ac_ext
 
 done
 # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
-rm -f conftest.i conftest.err conftest.$ac_ext
+rm -f conftest.err conftest.$ac_ext
 if $ac_preproc_ok; then :
 
 else
   { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error $? "C++ preprocessor \"$CXXCPP\" fails sanity check
-See \`config.log' for more details" "$LINENO" 5; }
+as_fn_error "C++ preprocessor \"$CXXCPP\" fails sanity check
+See \`config.log' for more details." "$LINENO" 5; }
 fi
 
 ac_ext=c
@@ -5782,7 +5736,7 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
 # the developers regenerating the configure script don't have to install libtool.
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5
 $as_echo_n "checking for a sed that does not truncate output... " >&6; }
-if ${ac_cv_path_SED+:} false; then :
+if test "${ac_cv_path_SED+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
             ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/
@@ -5802,7 +5756,7 @@ do
     for ac_prog in sed gsed; do
     for ac_exec_ext in '' $ac_executable_extensions; do
       ac_path_SED="$as_dir/$ac_prog$ac_exec_ext"
-      as_fn_executable_p "$ac_path_SED" || continue
+      { test -f "$ac_path_SED" && $as_test_x "$ac_path_SED"; } || continue
 # Check for GNU ac_path_SED and select it if it is found.
   # Check for GNU $ac_path_SED
 case `"$ac_path_SED" --version 2>&1` in
@@ -5837,7 +5791,7 @@ esac
   done
 IFS=$as_save_IFS
   if test -z "$ac_cv_path_SED"; then
-    as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5
+    as_fn_error "no acceptable sed could be found in \$PATH" "$LINENO" 5
   fi
 else
   ac_cv_path_SED=$SED
@@ -5851,7 +5805,7 @@ $as_echo "$ac_cv_path_SED" >&6; }
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5
 $as_echo_n "checking for egrep... " >&6; }
-if ${ac_cv_prog_egrep+:} false; then :
+if test "${ac_cv_prog_egrep+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   if echo a | (grep -E '(a|b)') >/dev/null 2>&1
@@ -5911,7 +5865,7 @@ else
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5
 $as_echo_n "checking for non-GNU ld... " >&6; }
 fi
-if ${lt_cv_path_LD+:} false; then :
+if test "${lt_cv_path_LD+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   if test -z "$LD"; then
@@ -5948,10 +5902,10 @@ else
   { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
 $as_echo "no" >&6; }
 fi
-test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5
+test -z "$LD" && as_fn_error "no acceptable ld found in \$PATH" "$LINENO" 5
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5
 $as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; }
-if ${lt_cv_prog_gnu_ld+:} false; then :
+if test "${lt_cv_prog_gnu_ld+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   # I'd rather use --version here, but apparently some GNU lds only accept -v.
@@ -5975,7 +5929,7 @@ do
 set dummy $ac_prog; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_AWK+:} false; then :
+if test "${ac_cv_prog_AWK+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   if test -n "$AWK"; then
@@ -5987,7 +5941,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
     ac_cv_prog_AWK="$ac_prog"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -6028,7 +5982,7 @@ done
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5
 $as_echo_n "checking for a BSD-compatible install... " >&6; }
 if test -z "$INSTALL"; then
-if ${ac_cv_path_install+:} false; then :
+if test "${ac_cv_path_install+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
@@ -6048,7 +6002,7 @@ case $as_dir/ in #((
     # by default.
     for ac_prog in ginstall scoinst install; do
       for ac_exec_ext in '' $ac_executable_extensions; do
-	if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then
+	if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then
 	  if test $ac_prog = install &&
 	    grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
 	    # AIX install.  It has an incompatible calling convention.
@@ -6120,7 +6074,7 @@ if test -n "$ac_tool_prefix"; then
 set dummy ${ac_tool_prefix}ranlib; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_RANLIB+:} false; then :
+if test "${ac_cv_prog_RANLIB+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   if test -n "$RANLIB"; then
@@ -6132,7 +6086,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
     ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -6160,7 +6114,7 @@ if test -z "$ac_cv_prog_RANLIB"; then
 set dummy ranlib; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_ac_ct_RANLIB+:} false; then :
+if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   if test -n "$ac_ct_RANLIB"; then
@@ -6172,7 +6126,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
     ac_cv_prog_ac_ct_RANLIB="ranlib"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -6209,7 +6163,7 @@ fi
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU make" >&5
 $as_echo_n "checking for GNU make... " >&6; }
-if ${ac_cv_GNU_MAKE+:} false; then :
+if test "${ac_cv_GNU_MAKE+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   ac_cv_GNU_MAKE='Not Found' ;
@@ -6229,7 +6183,7 @@ fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_GNU_MAKE" >&5
 $as_echo "$ac_cv_GNU_MAKE" >&6; } ;
 if test  "x$ac_cv_GNU_MAKE" = "xNot Found"  ; then
-   as_fn_error $? "*** Please install GNU make.  It is required to build Asterisk!" "$LINENO" 5
+   as_fn_error "*** Please install GNU make.  It is required to build Asterisk!" "$LINENO" 5
    exit 1
 fi
 GNU_MAKE=$ac_cv_GNU_MAKE
@@ -6237,7 +6191,7 @@ GNU_MAKE=$ac_cv_GNU_MAKE
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5
 $as_echo_n "checking for egrep... " >&6; }
-if ${ac_cv_path_EGREP+:} false; then :
+if test "${ac_cv_path_EGREP+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
@@ -6254,7 +6208,7 @@ do
     for ac_prog in egrep; do
     for ac_exec_ext in '' $ac_executable_extensions; do
       ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
-      as_fn_executable_p "$ac_path_EGREP" || continue
+      { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue
 # Check for GNU ac_path_EGREP and select it if it is found.
   # Check for GNU $ac_path_EGREP
 case `"$ac_path_EGREP" --version 2>&1` in
@@ -6289,7 +6243,7 @@ esac
   done
 IFS=$as_save_IFS
   if test -z "$ac_cv_path_EGREP"; then
-    as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+    as_fn_error "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
   fi
 else
   ac_cv_path_EGREP=$EGREP
@@ -6310,7 +6264,7 @@ if test -n "$ac_tool_prefix"; then
 set dummy $ac_tool_prefix$ac_prog; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_STRIP+:} false; then :
+if test "${ac_cv_prog_STRIP+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   if test -n "$STRIP"; then
@@ -6322,7 +6276,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
     ac_cv_prog_STRIP="$ac_tool_prefix$ac_prog"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -6354,7 +6308,7 @@ do
 set dummy $ac_prog; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_ac_ct_STRIP+:} false; then :
+if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   if test -n "$ac_ct_STRIP"; then
@@ -6366,7 +6320,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
     ac_cv_prog_ac_ct_STRIP="$ac_prog"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -6410,7 +6364,7 @@ if test -n "$ac_tool_prefix"; then
 set dummy $ac_tool_prefix$ac_prog; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_AR+:} false; then :
+if test "${ac_cv_prog_AR+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   if test -n "$AR"; then
@@ -6422,7 +6376,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
     ac_cv_prog_AR="$ac_tool_prefix$ac_prog"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -6454,7 +6408,7 @@ do
 set dummy $ac_prog; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_ac_ct_AR+:} false; then :
+if test "${ac_cv_prog_ac_ct_AR+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   if test -n "$ac_ct_AR"; then
@@ -6466,7 +6420,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
     ac_cv_prog_ac_ct_AR="$ac_prog"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -6514,7 +6468,7 @@ fi
 set dummy bison; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_path_BISON+:} false; then :
+if test "${ac_cv_path_BISON+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   case $BISON in
@@ -6528,7 +6482,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
     ac_cv_path_BISON="$as_dir/$ac_word$ac_exec_ext"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -6555,7 +6509,7 @@ fi
 set dummy cmp; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_path_CMP+:} false; then :
+if test "${ac_cv_path_CMP+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   case $CMP in
@@ -6569,7 +6523,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
     ac_cv_path_CMP="$as_dir/$ac_word$ac_exec_ext"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -6596,7 +6550,7 @@ fi
 set dummy flex; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_path_FLEX+:} false; then :
+if test "${ac_cv_path_FLEX+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   case $FLEX in
@@ -6610,7 +6564,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
     ac_cv_path_FLEX="$as_dir/$ac_word$ac_exec_ext"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -6637,7 +6591,7 @@ fi
 set dummy grep; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_path_GREP+:} false; then :
+if test "${ac_cv_path_GREP+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   case $GREP in
@@ -6651,7 +6605,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
     ac_cv_path_GREP="$as_dir/$ac_word$ac_exec_ext"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -6678,7 +6632,7 @@ fi
 set dummy python; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_path_PYTHON+:} false; then :
+if test "${ac_cv_path_PYTHON+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   case $PYTHON in
@@ -6692,7 +6646,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
     ac_cv_path_PYTHON="$as_dir/$ac_word$ac_exec_ext"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -6719,7 +6673,7 @@ fi
 set dummy find; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_path_FIND+:} false; then :
+if test "${ac_cv_path_FIND+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   case $FIND in
@@ -6733,7 +6687,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
     ac_cv_path_FIND="$as_dir/$ac_word$ac_exec_ext"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -6760,7 +6714,7 @@ fi
 set dummy compress; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_path_COMPRESS+:} false; then :
+if test "${ac_cv_path_COMPRESS+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   case $COMPRESS in
@@ -6774,7 +6728,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
     ac_cv_path_COMPRESS="$as_dir/$ac_word$ac_exec_ext"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -6801,7 +6755,7 @@ fi
 set dummy basename; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_path_BASENAME+:} false; then :
+if test "${ac_cv_path_BASENAME+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   case $BASENAME in
@@ -6815,7 +6769,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
     ac_cv_path_BASENAME="$as_dir/$ac_word$ac_exec_ext"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -6842,7 +6796,7 @@ fi
 set dummy dirname; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_path_DIRNAME+:} false; then :
+if test "${ac_cv_path_DIRNAME+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   case $DIRNAME in
@@ -6856,7 +6810,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
     ac_cv_path_DIRNAME="$as_dir/$ac_word$ac_exec_ext"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -6883,7 +6837,7 @@ fi
 set dummy sh; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_path_SHELL+:} false; then :
+if test "${ac_cv_path_SHELL+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   case $SHELL in
@@ -6897,7 +6851,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
     ac_cv_path_SHELL="$as_dir/$ac_word$ac_exec_ext"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -6924,7 +6878,7 @@ fi
 set dummy ln; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_path_LN+:} false; then :
+if test "${ac_cv_path_LN+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   case $LN in
@@ -6938,7 +6892,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
     ac_cv_path_LN="$as_dir/$ac_word$ac_exec_ext"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -6965,7 +6919,7 @@ fi
 set dummy doxygen; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_path_DOXYGEN+:} false; then :
+if test "${ac_cv_path_DOXYGEN+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   case $DOXYGEN in
@@ -6979,7 +6933,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
     ac_cv_path_DOXYGEN="$as_dir/$ac_word$ac_exec_ext"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -7006,7 +6960,7 @@ fi
 set dummy dot; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_path_DOT+:} false; then :
+if test "${ac_cv_path_DOT+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   case $DOT in
@@ -7020,7 +6974,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
     ac_cv_path_DOT="$as_dir/$ac_word$ac_exec_ext"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -7047,7 +7001,7 @@ fi
 set dummy wget; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_path_WGET+:} false; then :
+if test "${ac_cv_path_WGET+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   case $WGET in
@@ -7061,7 +7015,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
     ac_cv_path_WGET="$as_dir/$ac_word$ac_exec_ext"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -7088,7 +7042,7 @@ fi
 set dummy curl; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_path_CURL+:} false; then :
+if test "${ac_cv_path_CURL+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   case $CURL in
@@ -7102,7 +7056,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
     ac_cv_path_CURL="$as_dir/$ac_word$ac_exec_ext"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -7129,7 +7083,7 @@ fi
 set dummy rubber; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_path_RUBBER+:} false; then :
+if test "${ac_cv_path_RUBBER+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   case $RUBBER in
@@ -7143,7 +7097,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
     ac_cv_path_RUBBER="$as_dir/$ac_word$ac_exec_ext"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -7170,7 +7124,7 @@ fi
 set dummy catdvi; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_path_CATDVI+:} false; then :
+if test "${ac_cv_path_CATDVI+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   case $CATDVI in
@@ -7184,7 +7138,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
     ac_cv_path_CATDVI="$as_dir/$ac_word$ac_exec_ext"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -7211,7 +7165,7 @@ fi
 set dummy kpsewhich; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_path_KPATHSEA+:} false; then :
+if test "${ac_cv_path_KPATHSEA+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   case $KPATHSEA in
@@ -7225,7 +7179,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
     ac_cv_path_KPATHSEA="$as_dir/$ac_word$ac_exec_ext"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -7252,7 +7206,7 @@ fi
 set dummy xmllint; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_path_XMLLINT+:} false; then :
+if test "${ac_cv_path_XMLLINT+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   case $XMLLINT in
@@ -7266,7 +7220,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
     ac_cv_path_XMLLINT="$as_dir/$ac_word$ac_exec_ext"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -7293,7 +7247,7 @@ fi
 set dummy xmlstarlet; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_path_XMLSTARLET+:} false; then :
+if test "${ac_cv_path_XMLSTARLET+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   case $XMLSTARLET in
@@ -7307,7 +7261,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
     ac_cv_path_XMLSTARLET="$as_dir/$ac_word$ac_exec_ext"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -7334,7 +7288,7 @@ fi
 set dummy git; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_path_GIT+:} false; then :
+if test "${ac_cv_path_GIT+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   case $GIT in
@@ -7348,7 +7302,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
     ac_cv_path_GIT="$as_dir/$ac_word$ac_exec_ext"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -7380,7 +7334,7 @@ else
 set dummy fetch; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_path_FETCH+:} false; then :
+if test "${ac_cv_path_FETCH+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   case $FETCH in
@@ -7394,7 +7348,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
     ac_cv_path_FETCH="$as_dir/$ac_word$ac_exec_ext"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -7425,7 +7379,7 @@ fi
 set dummy ldconfig; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_path_LDCONFIG+:} false; then :
+if test "${ac_cv_path_LDCONFIG+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   case $LDCONFIG in
@@ -7439,7 +7393,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
     ac_cv_path_LDCONFIG="$as_dir/$ac_word$ac_exec_ext"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -7466,7 +7420,7 @@ fi
 set dummy sha1sum; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_path_SHA1SUM+:} false; then :
+if test "${ac_cv_path_SHA1SUM+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   case $SHA1SUM in
@@ -7480,7 +7434,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
     ac_cv_path_SHA1SUM="$as_dir/$ac_word$ac_exec_ext"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -7507,7 +7461,7 @@ fi
 set dummy openssl; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_path_OPENSSL+:} false; then :
+if test "${ac_cv_path_OPENSSL+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   case $OPENSSL in
@@ -7521,7 +7475,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
     ac_cv_path_OPENSSL="$as_dir/$ac_word$ac_exec_ext"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -7547,7 +7501,7 @@ fi
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for bison that supports parse-param" >&5
 $as_echo_n "checking for bison that supports parse-param... " >&6; }
-if ${ac_cv_path_BISON2+:} false; then :
+if test "${ac_cv_path_BISON2+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
 
@@ -7601,7 +7555,7 @@ if test -n "$ac_tool_prefix"; then
 set dummy ${ac_tool_prefix}soxmix; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_SOXMIX+:} false; then :
+if test "${ac_cv_prog_SOXMIX+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   if test -n "$SOXMIX"; then
@@ -7613,7 +7567,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
     ac_cv_prog_SOXMIX="${ac_tool_prefix}soxmix"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -7641,7 +7595,7 @@ if test -z "$ac_cv_prog_SOXMIX"; then
 set dummy soxmix; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_ac_ct_SOXMIX+:} false; then :
+if test "${ac_cv_prog_ac_ct_SOXMIX+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   if test -n "$ac_ct_SOXMIX"; then
@@ -7653,7 +7607,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
     ac_cv_prog_ac_ct_SOXMIX="soxmix"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -7700,7 +7654,7 @@ do
 set dummy $ac_prog; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_MD5+:} false; then :
+if test "${ac_cv_prog_MD5+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   if test -n "$MD5"; then
@@ -7712,7 +7666,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
     ac_cv_prog_MD5="$ac_prog"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -7866,7 +7820,7 @@ $as_echo_n "checking whether pthreads work with $flag... " >&6; }
 set dummy pthread-config; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_acx_pthread_config+:} false; then :
+if test "${ac_cv_prog_acx_pthread_config+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   if test -n "$acx_pthread_config"; then
@@ -7878,7 +7832,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
     ac_cv_prog_acx_pthread_config="yes"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -8022,7 +7976,7 @@ do
 set dummy $ac_prog; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_PTHREAD_CC+:} false; then :
+if test "${ac_cv_prog_PTHREAD_CC+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   if test -n "$PTHREAD_CC"; then
@@ -8034,7 +7988,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
     ac_cv_prog_PTHREAD_CC="$ac_prog"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -8108,7 +8062,7 @@ if test "${enable_dev_mode+set}" = set; then :
 	      AST_DEVMODE=yes
 	      AST_DEVMODE_STRICT=yes
 	      ;;
-	      *) as_fn_error $? "bad value ${enableval} for --enable-dev-mode" "$LINENO" 5  ;;
+	      *) as_fn_error "bad value ${enableval} for --enable-dev-mode" "$LINENO" 5  ;;
 	esac
 fi
 
@@ -8122,7 +8076,7 @@ if test "${enable_coverage+set}" = set; then :
   enableval=$enable_coverage; case "${enableval}" in
 	      y|ye|yes) AST_CODE_COVERAGE=yes ;;
 	      n|no) AST_CODE_COVERAGE=no ;;
-	      *) as_fn_error $? "bad value ${enableval} for --enable-coverage" "$LINENO" 5  ;;
+	      *) as_fn_error "bad value ${enableval} for --enable-coverage" "$LINENO" 5  ;;
 	esac
 fi
 
@@ -9067,7 +9021,7 @@ do
 set dummy $ac_prog; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_AWK+:} false; then :
+if test "${ac_cv_prog_AWK+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   if test -n "$AWK"; then
@@ -9079,7 +9033,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
     ac_cv_prog_AWK="$ac_prog"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -9115,7 +9069,7 @@ done
 set dummy curl-config; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_path__libcurl_config+:} false; then :
+if test "${ac_cv_path__libcurl_config+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   case $_libcurl_config in
@@ -9129,7 +9083,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
     ac_cv_path__libcurl_config="$as_dir/$ac_word$ac_exec_ext"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -9157,7 +9111,7 @@ fi
 set dummy curl-config; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_path__libcurl_config+:} false; then :
+if test "${ac_cv_path__libcurl_config+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   case $_libcurl_config in
@@ -9171,7 +9125,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
     ac_cv_path__libcurl_config="$as_dir/$ac_word$ac_exec_ext"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -9198,7 +9152,7 @@ fi
      if test x$_libcurl_config != "x" ; then
         { $as_echo "$as_me:${as_lineno-$LINENO}: checking for the version of libcurl" >&5
 $as_echo_n "checking for the version of libcurl... " >&6; }
-if ${libcurl_cv_lib_curl_version+:} false; then :
+if test "${libcurl_cv_lib_curl_version+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   libcurl_cv_lib_curl_version=`$_libcurl_config --version | $AWK '{print $2}'`
@@ -9212,7 +9166,7 @@ $as_echo "$libcurl_cv_lib_curl_version" >&6; }
         if test $_libcurl_wanted -gt 0 ; then
            { $as_echo "$as_me:${as_lineno-$LINENO}: checking for libcurl >= version 7.10.1" >&5
 $as_echo_n "checking for libcurl >= version 7.10.1... " >&6; }
-if ${libcurl_cv_lib_version_ok+:} false; then :
+if test "${libcurl_cv_lib_version_ok+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
 
@@ -9266,7 +9220,7 @@ $as_echo "$libcurl_cv_lib_version_ok" >&6; }
 
         { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether libcurl is usable" >&5
 $as_echo_n "checking whether libcurl is usable... " >&6; }
-if ${libcurl_cv_lib_curl_usable+:} false; then :
+if test "${libcurl_cv_lib_curl_usable+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
 
@@ -9325,7 +9279,7 @@ $as_echo "$libcurl_cv_lib_curl_usable" >&6; }
            LIBS="$LIBS $CURL_LIB"
 
            ac_fn_c_check_func "$LINENO" "curl_free" "ac_cv_func_curl_free"
-if test "x$ac_cv_func_curl_free" = xyes; then :
+if test "x$ac_cv_func_curl_free" = x""yes; then :
 
 else
 
@@ -11149,22 +11103,11 @@ fi
 # check for basic system features and functionality before
 # checking for package libraries
 
-ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default"
-if test "x$ac_cv_type_size_t" = xyes; then :
-
-else
-
-cat >>confdefs.h <<_ACEOF
-#define size_t unsigned int
-_ACEOF
-
-fi
-
 # The Ultrix 4.2 mips builtin alloca declared by alloca.h only works
 # for constant arguments.  Useless!
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working alloca.h" >&5
 $as_echo_n "checking for working alloca.h... " >&6; }
-if ${ac_cv_working_alloca_h+:} false; then :
+if test "${ac_cv_working_alloca_h+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -11197,7 +11140,7 @@ fi
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for alloca" >&5
 $as_echo_n "checking for alloca... " >&6; }
-if ${ac_cv_func_alloca_works+:} false; then :
+if test "${ac_cv_func_alloca_works+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -11216,7 +11159,7 @@ else
  #pragma alloca
 #   else
 #    ifndef alloca /* predefined by HP cc +Olibcalls */
-void *alloca (size_t);
+char *alloca ();
 #    endif
 #   endif
 #  endif
@@ -11260,7 +11203,7 @@ $as_echo "#define C_ALLOCA 1" >>confdefs.h
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether \`alloca.c' needs Cray hooks" >&5
 $as_echo_n "checking whether \`alloca.c' needs Cray hooks... " >&6; }
-if ${ac_cv_os_cray+:} false; then :
+if test "${ac_cv_os_cray+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -11287,7 +11230,8 @@ if test $ac_cv_os_cray = yes; then
   for ac_func in _getb67 GETB67 getb67; do
     as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
 ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
-if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+eval as_val=\$$as_ac_var
+   if test "x$as_val" = x""yes; then :
 
 cat >>confdefs.h <<_ACEOF
 #define CRAY_STACKSEG_END $ac_func
@@ -11301,7 +11245,7 @@ fi
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking stack direction for C alloca" >&5
 $as_echo_n "checking stack direction for C alloca... " >&6; }
-if ${ac_cv_c_stack_direction+:} false; then :
+if test "${ac_cv_c_stack_direction+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   if test "$cross_compiling" = yes; then :
@@ -11311,20 +11255,23 @@ else
 /* end confdefs.h.  */
 $ac_includes_default
 int
-find_stack_direction (int *addr, int depth)
+find_stack_direction ()
 {
-  int dir, dummy = 0;
-  if (! addr)
-    addr = &dummy;
-  *addr = addr < &dummy ? 1 : addr == &dummy ? 0 : -1;
-  dir = depth ? find_stack_direction (addr, depth - 1) : 0;
-  return dir + dummy;
+  static char *addr = 0;
+  auto char dummy;
+  if (addr == 0)
+    {
+      addr = &dummy;
+      return find_stack_direction ();
+    }
+  else
+    return (&dummy > addr) ? 1 : -1;
 }
 
 int
-main (int argc, char **argv)
+main ()
 {
-  return find_stack_direction (0, argc + !argv + 20) < 0;
+  return find_stack_direction () < 0;
 }
 _ACEOF
 if ac_fn_c_try_run "$LINENO"; then :
@@ -11351,7 +11298,7 @@ for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h; do
   as_ac_Header=`$as_echo "ac_cv_header_dirent_$ac_hdr" | $as_tr_sh`
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_hdr that defines DIR" >&5
 $as_echo_n "checking for $ac_hdr that defines DIR... " >&6; }
-if eval \${$as_ac_Header+:} false; then :
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then :
   $as_echo_n "(cached) " >&6
 else
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -11378,7 +11325,8 @@ fi
 eval ac_res=\$$as_ac_Header
 	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
 $as_echo "$ac_res" >&6; }
-if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+eval as_val=\$$as_ac_Header
+   if test "x$as_val" = x""yes; then :
   cat >>confdefs.h <<_ACEOF
 #define `$as_echo "HAVE_$ac_hdr" | $as_tr_cpp` 1
 _ACEOF
@@ -11391,7 +11339,7 @@ done
 if test $ac_header_dirent = dirent.h; then
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing opendir" >&5
 $as_echo_n "checking for library containing opendir... " >&6; }
-if ${ac_cv_search_opendir+:} false; then :
+if test "${ac_cv_search_opendir+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   ac_func_search_save_LIBS=$LIBS
@@ -11425,11 +11373,11 @@ for ac_lib in '' dir; do
 fi
 rm -f core conftest.err conftest.$ac_objext \
     conftest$ac_exeext
-  if ${ac_cv_search_opendir+:} false; then :
+  if test "${ac_cv_search_opendir+set}" = set; then :
   break
 fi
 done
-if ${ac_cv_search_opendir+:} false; then :
+if test "${ac_cv_search_opendir+set}" = set; then :
 
 else
   ac_cv_search_opendir=no
@@ -11448,7 +11396,7 @@ fi
 else
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing opendir" >&5
 $as_echo_n "checking for library containing opendir... " >&6; }
-if ${ac_cv_search_opendir+:} false; then :
+if test "${ac_cv_search_opendir+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   ac_func_search_save_LIBS=$LIBS
@@ -11482,11 +11430,11 @@ for ac_lib in '' x; do
 fi
 rm -f core conftest.err conftest.$ac_objext \
     conftest$ac_exeext
-  if ${ac_cv_search_opendir+:} false; then :
+  if test "${ac_cv_search_opendir+set}" = set; then :
   break
 fi
 done
-if ${ac_cv_search_opendir+:} false; then :
+if test "${ac_cv_search_opendir+set}" = set; then :
 
 else
   ac_cv_search_opendir=no
@@ -11506,7 +11454,7 @@ fi
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
 $as_echo_n "checking for ANSI C header files... " >&6; }
-if ${ac_cv_header_stdc+:} false; then :
+if test "${ac_cv_header_stdc+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -11618,7 +11566,7 @@ fi
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sys/wait.h that is POSIX.1 compatible" >&5
 $as_echo_n "checking for sys/wait.h that is POSIX.1 compatible... " >&6; }
-if ${ac_cv_header_sys_wait_h+:} false; then :
+if test "${ac_cv_header_sys_wait_h+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -11661,7 +11609,8 @@ for ac_header in arpa/inet.h fcntl.h inttypes.h libintl.h limits.h locale.h mall
 do :
   as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
 ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
-if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+eval as_val=\$$as_ac_Header
+   if test "x$as_val" = x""yes; then :
   cat >>confdefs.h <<_ACEOF
 #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
 _ACEOF
@@ -11692,7 +11641,7 @@ if test "x${PBX_TERMCAP}" != "x1" -a "${USE_TERMCAP}" != "no"; then
       as_ac_Lib=`$as_echo "ac_cv_lib_termcap_${pbxfuncname}" | $as_tr_sh`
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${pbxfuncname} in -ltermcap" >&5
 $as_echo_n "checking for ${pbxfuncname} in -ltermcap... " >&6; }
-if eval \${$as_ac_Lib+:} false; then :
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -11727,7 +11676,8 @@ fi
 eval ac_res=\$$as_ac_Lib
 	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
 $as_echo "$ac_res" >&6; }
-if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
   AST_TERMCAP_FOUND=yes
 else
   AST_TERMCAP_FOUND=no
@@ -11750,7 +11700,7 @@ fi
          ast_ext_lib_check_saved_CPPFLAGS="${CPPFLAGS}"
          CPPFLAGS="${CPPFLAGS} ${TERMCAP_INCLUDE}"
          ac_fn_c_check_header_mongrel "$LINENO" "" "ac_cv_header_" "$ac_includes_default"
-if test "x$ac_cv_header_" = xyes; then :
+if test "x$ac_cv_header_" = x""yes; then :
   TERMCAP_HEADER_FOUND=1
 else
   TERMCAP_HEADER_FOUND=0
@@ -11796,7 +11746,7 @@ if test "x${PBX_TINFO}" != "x1" -a "${USE_TINFO}" != "no"; then
       as_ac_Lib=`$as_echo "ac_cv_lib_tinfo_${pbxfuncname}" | $as_tr_sh`
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${pbxfuncname} in -ltinfo" >&5
 $as_echo_n "checking for ${pbxfuncname} in -ltinfo... " >&6; }
-if eval \${$as_ac_Lib+:} false; then :
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -11831,7 +11781,8 @@ fi
 eval ac_res=\$$as_ac_Lib
 	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
 $as_echo "$ac_res" >&6; }
-if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
   AST_TINFO_FOUND=yes
 else
   AST_TINFO_FOUND=no
@@ -11854,7 +11805,7 @@ fi
          ast_ext_lib_check_saved_CPPFLAGS="${CPPFLAGS}"
          CPPFLAGS="${CPPFLAGS} ${TINFO_INCLUDE}"
          ac_fn_c_check_header_mongrel "$LINENO" "" "ac_cv_header_" "$ac_includes_default"
-if test "x$ac_cv_header_" = xyes; then :
+if test "x$ac_cv_header_" = x""yes; then :
   TINFO_HEADER_FOUND=1
 else
   TINFO_HEADER_FOUND=0
@@ -11900,7 +11851,7 @@ if test "x${PBX_CURSES}" != "x1" -a "${USE_CURSES}" != "no"; then
       as_ac_Lib=`$as_echo "ac_cv_lib_curses_${pbxfuncname}" | $as_tr_sh`
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${pbxfuncname} in -lcurses" >&5
 $as_echo_n "checking for ${pbxfuncname} in -lcurses... " >&6; }
-if eval \${$as_ac_Lib+:} false; then :
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -11935,7 +11886,8 @@ fi
 eval ac_res=\$$as_ac_Lib
 	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
 $as_echo "$ac_res" >&6; }
-if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
   AST_CURSES_FOUND=yes
 else
   AST_CURSES_FOUND=no
@@ -11958,7 +11910,7 @@ fi
          ast_ext_lib_check_saved_CPPFLAGS="${CPPFLAGS}"
          CPPFLAGS="${CPPFLAGS} ${CURSES_INCLUDE}"
          ac_fn_c_check_header_mongrel "$LINENO" "curses.h" "ac_cv_header_curses_h" "$ac_includes_default"
-if test "x$ac_cv_header_curses_h" = xyes; then :
+if test "x$ac_cv_header_curses_h" = x""yes; then :
   CURSES_HEADER_FOUND=1
 else
   CURSES_HEADER_FOUND=0
@@ -12004,7 +11956,7 @@ if test "x${PBX_NCURSES}" != "x1" -a "${USE_NCURSES}" != "no"; then
       as_ac_Lib=`$as_echo "ac_cv_lib_ncurses_${pbxfuncname}" | $as_tr_sh`
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${pbxfuncname} in -lncurses" >&5
 $as_echo_n "checking for ${pbxfuncname} in -lncurses... " >&6; }
-if eval \${$as_ac_Lib+:} false; then :
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -12039,7 +11991,8 @@ fi
 eval ac_res=\$$as_ac_Lib
 	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
 $as_echo "$ac_res" >&6; }
-if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
   AST_NCURSES_FOUND=yes
 else
   AST_NCURSES_FOUND=no
@@ -12062,7 +12015,7 @@ fi
          ast_ext_lib_check_saved_CPPFLAGS="${CPPFLAGS}"
          CPPFLAGS="${CPPFLAGS} ${NCURSES_INCLUDE}"
          ac_fn_c_check_header_mongrel "$LINENO" "curses.h" "ac_cv_header_curses_h" "$ac_includes_default"
-if test "x$ac_cv_header_curses_h" = xyes; then :
+if test "x$ac_cv_header_curses_h" = x""yes; then :
   NCURSES_HEADER_FOUND=1
 else
   NCURSES_HEADER_FOUND=0
@@ -12108,7 +12061,7 @@ if test "x${PBX_UUID}" != "x1" -a "${USE_UUID}" != "no"; then
       as_ac_Lib=`$as_echo "ac_cv_lib_uuid_${pbxfuncname}" | $as_tr_sh`
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${pbxfuncname} in -luuid" >&5
 $as_echo_n "checking for ${pbxfuncname} in -luuid... " >&6; }
-if eval \${$as_ac_Lib+:} false; then :
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -12143,7 +12096,8 @@ fi
 eval ac_res=\$$as_ac_Lib
 	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
 $as_echo "$ac_res" >&6; }
-if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
   AST_UUID_FOUND=yes
 else
   AST_UUID_FOUND=no
@@ -12166,7 +12120,7 @@ fi
          ast_ext_lib_check_saved_CPPFLAGS="${CPPFLAGS}"
          CPPFLAGS="${CPPFLAGS} ${UUID_INCLUDE}"
          ac_fn_c_check_header_mongrel "$LINENO" "uuid/uuid.h" "ac_cv_header_uuid_uuid_h" "$ac_includes_default"
-if test "x$ac_cv_header_uuid_uuid_h" = xyes; then :
+if test "x$ac_cv_header_uuid_uuid_h" = x""yes; then :
   UUID_HEADER_FOUND=1
 else
   UUID_HEADER_FOUND=0
@@ -12212,7 +12166,7 @@ if test "x${PBX_JANSSON}" != "x1" -a "${USE_JANSSON}" != "no"; then
       as_ac_Lib=`$as_echo "ac_cv_lib_jansson_${pbxfuncname}" | $as_tr_sh`
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${pbxfuncname} in -ljansson" >&5
 $as_echo_n "checking for ${pbxfuncname} in -ljansson... " >&6; }
-if eval \${$as_ac_Lib+:} false; then :
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -12247,7 +12201,8 @@ fi
 eval ac_res=\$$as_ac_Lib
 	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
 $as_echo "$ac_res" >&6; }
-if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
   AST_JANSSON_FOUND=yes
 else
   AST_JANSSON_FOUND=no
@@ -12270,7 +12225,7 @@ fi
          ast_ext_lib_check_saved_CPPFLAGS="${CPPFLAGS}"
          CPPFLAGS="${CPPFLAGS} ${JANSSON_INCLUDE}"
          ac_fn_c_check_header_mongrel "$LINENO" "jansson.h" "ac_cv_header_jansson_h" "$ac_includes_default"
-if test "x$ac_cv_header_jansson_h" = xyes; then :
+if test "x$ac_cv_header_jansson_h" = x""yes; then :
   JANSSON_HEADER_FOUND=1
 else
   JANSSON_HEADER_FOUND=0
@@ -12307,16 +12262,16 @@ elif test "x$CURSES_LIB" != "x" ; then
 elif test "x$NCURSES_LIB" != "x" ; then
   EDITLINE_LIB="$NCURSES_LIB"
 else
-  as_fn_error $? "*** termcap support not found (on modern systems, this typically means the ncurses development package is missing)" "$LINENO" 5
+  as_fn_error "*** termcap support not found (on modern systems, this typically means the ncurses development package is missing)" "$LINENO" 5
 fi
 
 
 if test "x$UUID_LIB" == "x"; then
-  as_fn_error $? "*** uuid support not found (this typically means the uuid development package is missing)" "$LINENO" 5
+  as_fn_error "*** uuid support not found (this typically means the uuid development package is missing)" "$LINENO" 5
 fi
 
 if test "x$JANSSON_LIB" == "x"; then
-  as_fn_error $? "*** JSON support not found (this typically means the libjansson development package is missing)" "$LINENO" 5
+  as_fn_error "*** JSON support not found (this typically means the libjansson development package is missing)" "$LINENO" 5
 fi
 
 # Another mandatory item (unless it's explicitly disabled)
@@ -12325,7 +12280,7 @@ if test "${enable_xmldoc+set}" = set; then :
   enableval=$enable_xmldoc; case "${enableval}" in
 		y|ye|yes) disable_xmldoc=no ;;
 		n|no)  disable_xmldoc=yes ;;
-		*) as_fn_error $? "bad value ${enableval} for --disable-xmldoc" "$LINENO" 5  ;;
+		*) as_fn_error "bad value ${enableval} for --disable-xmldoc" "$LINENO" 5  ;;
 	esac
 else
   disable_xmldoc=no
@@ -12341,7 +12296,7 @@ if test "${disable_xmldoc}" != "yes"; then
 set dummy ${ac_tool_prefix}xml2-config; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_path_CONFIG_LIBXML2+:} false; then :
+if test "${ac_cv_path_CONFIG_LIBXML2+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   case $CONFIG_LIBXML2 in
@@ -12356,7 +12311,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
     ac_cv_path_CONFIG_LIBXML2="$as_dir/$ac_word$ac_exec_ext"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -12385,7 +12340,7 @@ if test -z "$ac_cv_path_CONFIG_LIBXML2"; then
 set dummy xml2-config; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_path_ac_pt_CONFIG_LIBXML2+:} false; then :
+if test "${ac_cv_path_ac_pt_CONFIG_LIBXML2+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   case $ac_pt_CONFIG_LIBXML2 in
@@ -12400,7 +12355,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
     ac_cv_path_ac_pt_CONFIG_LIBXML2="$as_dir/$ac_word$ac_exec_ext"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -12500,7 +12455,7 @@ fi
 for ac_header in xlocale.h
 do :
   ac_fn_c_check_header_mongrel "$LINENO" "xlocale.h" "ac_cv_header_xlocale_h" "$ac_includes_default"
-if test "x$ac_cv_header_xlocale_h" = xyes; then :
+if test "x$ac_cv_header_xlocale_h" = x""yes; then :
   cat >>confdefs.h <<_ACEOF
 #define HAVE_XLOCALE_H 1
 _ACEOF
@@ -12514,7 +12469,8 @@ for ac_header in winsock.h winsock2.h
 do :
   as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
 ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
-if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+eval as_val=\$$as_ac_Header
+   if test "x$as_val" = x""yes; then :
   cat >>confdefs.h <<_ACEOF
 #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
 _ACEOF
@@ -12525,7 +12481,7 @@ done
 
 
 ac_fn_c_check_header_mongrel "$LINENO" "sys/poll.h" "ac_cv_header_sys_poll_h" "$ac_includes_default"
-if test "x$ac_cv_header_sys_poll_h" = xyes; then :
+if test "x$ac_cv_header_sys_poll_h" = x""yes; then :
 
 else
 
@@ -12544,7 +12500,7 @@ if test "$enable_largefile" != no; then
 
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for special C compiler options needed for large files" >&5
 $as_echo_n "checking for special C compiler options needed for large files... " >&6; }
-if ${ac_cv_sys_largefile_CC+:} false; then :
+if test "${ac_cv_sys_largefile_CC+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   ac_cv_sys_largefile_CC=no
@@ -12595,7 +12551,7 @@ $as_echo "$ac_cv_sys_largefile_CC" >&6; }
 
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _FILE_OFFSET_BITS value needed for large files" >&5
 $as_echo_n "checking for _FILE_OFFSET_BITS value needed for large files... " >&6; }
-if ${ac_cv_sys_file_offset_bits+:} false; then :
+if test "${ac_cv_sys_file_offset_bits+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   while :; do
@@ -12664,7 +12620,7 @@ rm -rf conftest*
   if test $ac_cv_sys_file_offset_bits = unknown; then
     { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _LARGE_FILES value needed for large files" >&5
 $as_echo_n "checking for _LARGE_FILES value needed for large files... " >&6; }
-if ${ac_cv_sys_large_files+:} false; then :
+if test "${ac_cv_sys_large_files+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   while :; do
@@ -12731,74 +12687,90 @@ _ACEOF
 esac
 rm -rf conftest*
   fi
-
-
 fi
 
 
 # Checks for typedefs, structures, and compiler characteristics.
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdbool.h that conforms to C99" >&5
 $as_echo_n "checking for stdbool.h that conforms to C99... " >&6; }
-if ${ac_cv_header_stdbool_h+:} false; then :
+if test "${ac_cv_header_stdbool_h+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
-             #include <stdbool.h>
-             #ifndef bool
-              "error: bool is not defined"
-             #endif
-             #ifndef false
-              "error: false is not defined"
-             #endif
-             #if false
-              "error: false is not 0"
-             #endif
-             #ifndef true
-              "error: true is not defined"
-             #endif
-             #if true != 1
-              "error: true is not 1"
-             #endif
-             #ifndef __bool_true_false_are_defined
-              "error: __bool_true_false_are_defined is not defined"
-             #endif
-
-             struct s { _Bool s: 1; _Bool t; } s;
-
-             char a[true == 1 ? 1 : -1];
-             char b[false == 0 ? 1 : -1];
-             char c[__bool_true_false_are_defined == 1 ? 1 : -1];
-             char d[(bool) 0.5 == true ? 1 : -1];
-             /* See body of main program for 'e'.  */
-             char f[(_Bool) 0.0 == false ? 1 : -1];
-             char g[true];
-             char h[sizeof (_Bool)];
-             char i[sizeof s.t];
-             enum { j = false, k = true, l = false * true, m = true * 256 };
-             /* The following fails for
-                HP aC++/ANSI C B3910B A.05.55 [Dec 04 2003]. */
-             _Bool n[m];
-             char o[sizeof n == m * sizeof n[0] ? 1 : -1];
-             char p[-1 - (_Bool) 0 < 0 && -1 - (bool) 0 < 0 ? 1 : -1];
-             /* Catch a bug in an HP-UX C compiler.  See
-                http://gcc.gnu.org/ml/gcc-patches/2003-12/msg02303.html
-                http://lists.gnu.org/archive/html/bug-coreutils/2005-11/msg00161.html
-              */
-             _Bool q = true;
-             _Bool *pq = &q;
-
-int
-main ()
-{
-
-             bool e = &s;
-             *pq |= q;
-             *pq |= ! q;
-             /* Refer to every declared value, to avoid compiler optimizations.  */
-             return (!a + !b + !c + !d + !e + !f + !g + !h + !i + !!j + !k + !!l
-                     + !m + !n + !o + !p + !q + !pq);
+#include <stdbool.h>
+#ifndef bool
+ "error: bool is not defined"
+#endif
+#ifndef false
+ "error: false is not defined"
+#endif
+#if false
+ "error: false is not 0"
+#endif
+#ifndef true
+ "error: true is not defined"
+#endif
+#if true != 1
+ "error: true is not 1"
+#endif
+#ifndef __bool_true_false_are_defined
+ "error: __bool_true_false_are_defined is not defined"
+#endif
+
+	struct s { _Bool s: 1; _Bool t; } s;
+
+	char a[true == 1 ? 1 : -1];
+	char b[false == 0 ? 1 : -1];
+	char c[__bool_true_false_are_defined == 1 ? 1 : -1];
+	char d[(bool) 0.5 == true ? 1 : -1];
+	bool e = &s;
+	char f[(_Bool) 0.0 == false ? 1 : -1];
+	char g[true];
+	char h[sizeof (_Bool)];
+	char i[sizeof s.t];
+	enum { j = false, k = true, l = false * true, m = true * 256 };
+	/* The following fails for
+	   HP aC++/ANSI C B3910B A.05.55 [Dec 04 2003]. */
+	_Bool n[m];
+	char o[sizeof n == m * sizeof n[0] ? 1 : -1];
+	char p[-1 - (_Bool) 0 < 0 && -1 - (bool) 0 < 0 ? 1 : -1];
+#	if defined __xlc__ || defined __GNUC__
+	 /* Catch a bug in IBM AIX xlc compiler version 6.0.0.0
+	    reported by James Lemley on 2005-10-05; see
+	    http://lists.gnu.org/archive/html/bug-coreutils/2005-10/msg00086.html
+	    This test is not quite right, since xlc is allowed to
+	    reject this program, as the initializer for xlcbug is
+	    not one of the forms that C requires support for.
+	    However, doing the test right would require a runtime
+	    test, and that would make cross-compilation harder.
+	    Let us hope that IBM fixes the xlc bug, and also adds
+	    support for this kind of constant expression.  In the
+	    meantime, this test will reject xlc, which is OK, since
+	    our stdbool.h substitute should suffice.  We also test
+	    this with GCC, where it should work, to detect more
+	    quickly whether someone messes up the test in the
+	    future.  */
+	 char digs[] = "0123456789";
+	 int xlcbug = 1 / (&(digs + 5)[-2 + (bool) 1] == &digs[4] ? 1 : -1);
+#	endif
+	/* Catch a bug in an HP-UX C compiler.  See
+	   http://gcc.gnu.org/ml/gcc-patches/2003-12/msg02303.html
+	   http://lists.gnu.org/archive/html/bug-coreutils/2005-11/msg00161.html
+	 */
+	_Bool q = true;
+	_Bool *pq = &q;
+
+int
+main ()
+{
+
+	*pq |= q;
+	*pq |= ! q;
+	/* Refer to every declared value, to avoid compiler optimizations.  */
+	return (!a + !b + !c + !d + !e + !f + !g + !h + !i + !!j + !k + !!l
+		+ !m + !n + !o + !p + !q + !pq);
 
   ;
   return 0;
@@ -12813,8 +12785,8 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
 fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdbool_h" >&5
 $as_echo "$ac_cv_header_stdbool_h" >&6; }
-   ac_fn_c_check_type "$LINENO" "_Bool" "ac_cv_type__Bool" "$ac_includes_default"
-if test "x$ac_cv_type__Bool" = xyes; then :
+ac_fn_c_check_type "$LINENO" "_Bool" "ac_cv_type__Bool" "$ac_includes_default"
+if test "x$ac_cv_type__Bool" = x""yes; then :
 
 cat >>confdefs.h <<_ACEOF
 #define HAVE__BOOL 1
@@ -12823,7 +12795,6 @@ _ACEOF
 
 fi
 
-
 if test $ac_cv_header_stdbool_h = yes; then
 
 $as_echo "#define HAVE_STDBOOL_H 1" >>confdefs.h
@@ -12832,7 +12803,7 @@ fi
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5
 $as_echo_n "checking for an ANSI C-conforming const... " >&6; }
-if ${ac_cv_c_const+:} false; then :
+if test "${ac_cv_c_const+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -12841,11 +12812,11 @@ else
 int
 main ()
 {
-
+/* FIXME: Include the comments suggested by Paul. */
 #ifndef __cplusplus
-  /* Ultrix mips cc rejects this sort of thing.  */
+  /* Ultrix mips cc rejects this.  */
   typedef int charset[2];
-  const charset cs = { 0, 0 };
+  const charset cs;
   /* SunOS 4.1.1 cc rejects this.  */
   char const *const *pcpcc;
   char **ppc;
@@ -12862,9 +12833,8 @@ main ()
   ++pcpcc;
   ppc = (char**) pcpcc;
   pcpcc = (char const *const *) ppc;
-  { /* SCO 3.2v4 cc rejects this sort of thing.  */
-    char tx;
-    char *t = &tx;
+  { /* SCO 3.2v4 cc rejects this.  */
+    char *t;
     char const *s = 0 ? (char *) 0 : (char const *) 0;
 
     *t++ = 0;
@@ -12880,10 +12850,10 @@ main ()
     iptr p = 0;
     ++p;
   }
-  { /* AIX XL C 1.02.0.0 rejects this sort of thing, saying
+  { /* AIX XL C 1.02.0.0 rejects this saying
        "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */
-    struct s { int j; const int *ap[3]; } bx;
-    struct s *b = &bx; b->j = 5;
+    struct s { int j; const int *ap[3]; };
+    struct s *b; b->j = 5;
   }
   { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */
     const int foo = 10;
@@ -12913,7 +12883,7 @@ fi
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for uid_t in sys/types.h" >&5
 $as_echo_n "checking for uid_t in sys/types.h... " >&6; }
-if ${ac_cv_type_uid_t+:} false; then :
+if test "${ac_cv_type_uid_t+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -12943,7 +12913,7 @@ fi
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for inline" >&5
 $as_echo_n "checking for inline... " >&6; }
-if ${ac_cv_c_inline+:} false; then :
+if test "${ac_cv_c_inline+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   ac_cv_c_inline=no
@@ -12986,7 +12956,7 @@ esac
 
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for long double with more range or precision than double" >&5
 $as_echo_n "checking for long double with more range or precision than double... " >&6; }
-if ${ac_cv_type_long_double_wider+:} false; then :
+if test "${ac_cv_type_long_double_wider+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -13013,8 +12983,7 @@ static int test_array [1 - 2 * !((0 < ((DBL_MAX_EXP < LDBL_MAX_EXP)
 		   - (LDBL_MANT_DIG < DBL_MANT_DIG)))
 	    && (int) LDBL_EPSILON == 0
 	  )];
-test_array [0] = 0;
-return test_array [0];
+test_array [0] = 0
 
   ;
   return 0;
@@ -13036,7 +13005,7 @@ $as_echo "#define HAVE_LONG_DOUBLE_WIDER 1" >>confdefs.h
   fi
 
 ac_fn_c_check_type "$LINENO" "mode_t" "ac_cv_type_mode_t" "$ac_includes_default"
-if test "x$ac_cv_type_mode_t" = xyes; then :
+if test "x$ac_cv_type_mode_t" = x""yes; then :
 
 else
 
@@ -13047,7 +13016,7 @@ _ACEOF
 fi
 
 ac_fn_c_check_type "$LINENO" "off_t" "ac_cv_type_off_t" "$ac_includes_default"
-if test "x$ac_cv_type_off_t" = xyes; then :
+if test "x$ac_cv_type_off_t" = x""yes; then :
 
 else
 
@@ -13058,7 +13027,7 @@ _ACEOF
 fi
 
 ac_fn_c_check_type "$LINENO" "pid_t" "ac_cv_type_pid_t" "$ac_includes_default"
-if test "x$ac_cv_type_pid_t" = xyes; then :
+if test "x$ac_cv_type_pid_t" = x""yes; then :
 
 else
 
@@ -13069,7 +13038,7 @@ _ACEOF
 fi
 
 ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default"
-if test "x$ac_cv_type_size_t" = xyes; then :
+if test "x$ac_cv_type_size_t" = x""yes; then :
 
 else
 
@@ -13080,7 +13049,7 @@ _ACEOF
 fi
 
 ac_fn_c_check_member "$LINENO" "struct stat" "st_blksize" "ac_cv_member_struct_stat_st_blksize" "$ac_includes_default"
-if test "x$ac_cv_member_struct_stat_st_blksize" = xyes; then :
+if test "x$ac_cv_member_struct_stat_st_blksize" = x""yes; then :
 
 cat >>confdefs.h <<_ACEOF
 #define HAVE_STRUCT_STAT_ST_BLKSIZE 1
@@ -13092,7 +13061,7 @@ fi
 ac_fn_c_check_member "$LINENO" "struct ucred" "uid" "ac_cv_member_struct_ucred_uid" "#include <sys/types.h>
 #include <sys/socket.h>
 "
-if test "x$ac_cv_member_struct_ucred_uid" = xyes; then :
+if test "x$ac_cv_member_struct_ucred_uid" = x""yes; then :
 
 cat >>confdefs.h <<_ACEOF
 #define HAVE_STRUCT_UCRED_UID 1
@@ -13103,7 +13072,7 @@ fi
 ac_fn_c_check_member "$LINENO" "struct ucred" "cr_uid" "ac_cv_member_struct_ucred_cr_uid" "#include <sys/types.h>
 #include <sys/socket.h>
 "
-if test "x$ac_cv_member_struct_ucred_cr_uid" = xyes; then :
+if test "x$ac_cv_member_struct_ucred_cr_uid" = x""yes; then :
 
 cat >>confdefs.h <<_ACEOF
 #define HAVE_STRUCT_UCRED_CR_UID 1
@@ -13114,7 +13083,7 @@ fi
 ac_fn_c_check_member "$LINENO" "struct sockpeercred" "uid" "ac_cv_member_struct_sockpeercred_uid" "#include <sys/types.h>
 #include <sys/socket.h>
 "
-if test "x$ac_cv_member_struct_sockpeercred_uid" = xyes; then :
+if test "x$ac_cv_member_struct_sockpeercred_uid" = x""yes; then :
 
 cat >>confdefs.h <<_ACEOF
 #define HAVE_STRUCT_SOCKPEERCRED_UID 1
@@ -13125,7 +13094,7 @@ fi
 
 ac_fn_c_check_member "$LINENO" "struct ifreq" "ifr_ifru.ifru_hwaddr" "ac_cv_member_struct_ifreq_ifr_ifru_ifru_hwaddr" "#include <net/if.h>
 "
-if test "x$ac_cv_member_struct_ifreq_ifr_ifru_ifru_hwaddr" = xyes; then :
+if test "x$ac_cv_member_struct_ifreq_ifr_ifru_ifru_hwaddr" = x""yes; then :
 
 cat >>confdefs.h <<_ACEOF
 #define HAVE_STRUCT_IFREQ_IFR_IFRU_IFRU_HWADDR 1
@@ -13136,7 +13105,7 @@ fi
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether time.h and sys/time.h may both be included" >&5
 $as_echo_n "checking whether time.h and sys/time.h may both be included... " >&6; }
-if ${ac_cv_header_time+:} false; then :
+if test "${ac_cv_header_time+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -13171,7 +13140,7 @@ fi
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether struct tm is in sys/time.h or time.h" >&5
 $as_echo_n "checking whether struct tm is in sys/time.h or time.h... " >&6; }
-if ${ac_cv_struct_tm+:} false; then :
+if test "${ac_cv_struct_tm+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -13206,7 +13175,7 @@ fi
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working volatile" >&5
 $as_echo_n "checking for working volatile... " >&6; }
-if ${ac_cv_c_volatile+:} false; then :
+if test "${ac_cv_c_volatile+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -13239,7 +13208,7 @@ $as_echo "#define volatile /**/" >>confdefs.h
 fi
 
 ac_fn_c_check_type "$LINENO" "ptrdiff_t" "ac_cv_type_ptrdiff_t" "$ac_includes_default"
-if test "x$ac_cv_type_ptrdiff_t" = xyes; then :
+if test "x$ac_cv_type_ptrdiff_t" = x""yes; then :
 
 cat >>confdefs.h <<_ACEOF
 #define HAVE_PTRDIFF_T 1
@@ -13253,7 +13222,7 @@ fi
 for ac_header in unistd.h
 do :
   ac_fn_c_check_header_mongrel "$LINENO" "unistd.h" "ac_cv_header_unistd_h" "$ac_includes_default"
-if test "x$ac_cv_header_unistd_h" = xyes; then :
+if test "x$ac_cv_header_unistd_h" = x""yes; then :
   cat >>confdefs.h <<_ACEOF
 #define HAVE_UNISTD_H 1
 _ACEOF
@@ -13264,7 +13233,7 @@ done
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working chown" >&5
 $as_echo_n "checking for working chown... " >&6; }
-if ${ac_cv_func_chown_works+:} false; then :
+if test "${ac_cv_func_chown_works+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   if test "$cross_compiling" = yes; then :
@@ -13317,7 +13286,7 @@ fi
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether closedir returns void" >&5
 $as_echo_n "checking whether closedir returns void... " >&6; }
-if ${ac_cv_func_closedir_void+:} false; then :
+if test "${ac_cv_func_closedir_void+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   if test "$cross_compiling" = yes; then :
@@ -13359,7 +13328,7 @@ fi
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for error_at_line" >&5
 $as_echo_n "checking for error_at_line... " >&6; }
-if ${ac_cv_lib_error_at_line+:} false; then :
+if test "${ac_cv_lib_error_at_line+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -13395,7 +13364,7 @@ fi
 for ac_header in vfork.h
 do :
   ac_fn_c_check_header_mongrel "$LINENO" "vfork.h" "ac_cv_header_vfork_h" "$ac_includes_default"
-if test "x$ac_cv_header_vfork_h" = xyes; then :
+if test "x$ac_cv_header_vfork_h" = x""yes; then :
   cat >>confdefs.h <<_ACEOF
 #define HAVE_VFORK_H 1
 _ACEOF
@@ -13408,7 +13377,8 @@ for ac_func in fork vfork
 do :
   as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
 ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
-if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+eval as_val=\$$as_ac_var
+   if test "x$as_val" = x""yes; then :
   cat >>confdefs.h <<_ACEOF
 #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
 _ACEOF
@@ -13419,7 +13389,7 @@ done
 if test "x$ac_cv_func_fork" = xyes; then
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working fork" >&5
 $as_echo_n "checking for working fork... " >&6; }
-if ${ac_cv_func_fork_works+:} false; then :
+if test "${ac_cv_func_fork_works+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   if test "$cross_compiling" = yes; then :
@@ -13472,7 +13442,7 @@ ac_cv_func_vfork_works=$ac_cv_func_vfork
 if test "x$ac_cv_func_vfork" = xyes; then
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working vfork" >&5
 $as_echo_n "checking for working vfork... " >&6; }
-if ${ac_cv_func_vfork_works+:} false; then :
+if test "${ac_cv_func_vfork_works+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   if test "$cross_compiling" = yes; then :
@@ -13609,7 +13579,7 @@ fi
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _LARGEFILE_SOURCE value needed for large files" >&5
 $as_echo_n "checking for _LARGEFILE_SOURCE value needed for large files... " >&6; }
-if ${ac_cv_sys_largefile_source+:} false; then :
+if test "${ac_cv_sys_largefile_source+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   while :; do
@@ -13678,7 +13648,7 @@ fi
 if test $ac_cv_c_compiler_gnu = yes; then
     { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC needs -traditional" >&5
 $as_echo_n "checking whether $CC needs -traditional... " >&6; }
-if ${ac_cv_prog_gcc_traditional+:} false; then :
+if test "${ac_cv_prog_gcc_traditional+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
     ac_pattern="Autoconf.*'x'"
@@ -13723,7 +13693,7 @@ fi
 # AC_FUNC_REALLOC
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working memcmp" >&5
 $as_echo_n "checking for working memcmp... " >&6; }
-if ${ac_cv_func_memcmp_working+:} false; then :
+if test "${ac_cv_func_memcmp_working+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   if test "$cross_compiling" = yes; then :
@@ -13791,7 +13761,8 @@ do :
   as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
 ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
 "
-if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+eval as_val=\$$as_ac_Header
+   if test "x$as_val" = x""yes; then :
   cat >>confdefs.h <<_ACEOF
 #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
 _ACEOF
@@ -13810,7 +13781,7 @@ done
 for ac_func in getpagesize
 do :
   ac_fn_c_check_func "$LINENO" "getpagesize" "ac_cv_func_getpagesize"
-if test "x$ac_cv_func_getpagesize" = xyes; then :
+if test "x$ac_cv_func_getpagesize" = x""yes; then :
   cat >>confdefs.h <<_ACEOF
 #define HAVE_GETPAGESIZE 1
 _ACEOF
@@ -13820,7 +13791,7 @@ done
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working mmap" >&5
 $as_echo_n "checking for working mmap... " >&6; }
-if ${ac_cv_func_mmap_fixed_mapped+:} false; then :
+if test "${ac_cv_func_mmap_fixed_mapped+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   if test "$cross_compiling" = yes; then :
@@ -13988,7 +13959,8 @@ for ac_header in sys/select.h sys/socket.h
 do :
   as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
 ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
-if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+eval as_val=\$$as_ac_Header
+   if test "x$as_val" = x""yes; then :
   cat >>confdefs.h <<_ACEOF
 #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
 _ACEOF
@@ -13999,7 +13971,7 @@ done
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking types of arguments for select" >&5
 $as_echo_n "checking types of arguments for select... " >&6; }
-if ${ac_cv_func_select_args+:} false; then :
+if test "${ac_cv_func_select_args+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   for ac_arg234 in 'fd_set *' 'int *' 'void *'; do
@@ -14033,7 +14005,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
  done
 done
 # Provide a safe default value.
-: "${ac_cv_func_select_args=int,int *,struct timeval *}"
+: ${ac_cv_func_select_args='int,int *,struct timeval *'}
 
 fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_select_args" >&5
@@ -14059,7 +14031,7 @@ _ACEOF
 
 rm -f conftest*
 
-if ${ac_cv_func_setvbuf_reversed+:} false; then :
+if test "${ac_cv_func_setvbuf_reversed+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   ac_cv_func_setvbuf_reversed=no
@@ -14068,7 +14040,7 @@ fi
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking return type of signal handlers" >&5
 $as_echo_n "checking return type of signal handlers... " >&6; }
-if ${ac_cv_type_signal+:} false; then :
+if test "${ac_cv_type_signal+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -14101,7 +14073,7 @@ _ACEOF
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether lstat correctly handles trailing slash" >&5
 $as_echo_n "checking whether lstat correctly handles trailing slash... " >&6; }
-if ${ac_cv_func_lstat_dereferences_slashed_symlink+:} false; then :
+if test "${ac_cv_func_lstat_dereferences_slashed_symlink+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   rm -f conftest.sym conftest.file
@@ -14163,7 +14135,7 @@ fi
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stat accepts an empty string" >&5
 $as_echo_n "checking whether stat accepts an empty string... " >&6; }
-if ${ac_cv_func_stat_empty_string_bug+:} false; then :
+if test "${ac_cv_func_stat_empty_string_bug+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   if test "$cross_compiling" = yes; then :
@@ -14209,7 +14181,7 @@ fi
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working strcoll" >&5
 $as_echo_n "checking for working strcoll... " >&6; }
-if ${ac_cv_func_strcoll_works+:} false; then :
+if test "${ac_cv_func_strcoll_works+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   if test "$cross_compiling" = yes; then :
@@ -14249,7 +14221,7 @@ fi
 for ac_func in strftime
 do :
   ac_fn_c_check_func "$LINENO" "strftime" "ac_cv_func_strftime"
-if test "x$ac_cv_func_strftime" = xyes; then :
+if test "x$ac_cv_func_strftime" = x""yes; then :
   cat >>confdefs.h <<_ACEOF
 #define HAVE_STRFTIME 1
 _ACEOF
@@ -14258,7 +14230,7 @@ else
   # strftime is in -lintl on SCO UNIX.
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for strftime in -lintl" >&5
 $as_echo_n "checking for strftime in -lintl... " >&6; }
-if ${ac_cv_lib_intl_strftime+:} false; then :
+if test "${ac_cv_lib_intl_strftime+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -14292,7 +14264,7 @@ LIBS=$ac_check_lib_save_LIBS
 fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_intl_strftime" >&5
 $as_echo "$ac_cv_lib_intl_strftime" >&6; }
-if test "x$ac_cv_lib_intl_strftime" = xyes; then :
+if test "x$ac_cv_lib_intl_strftime" = x""yes; then :
   $as_echo "#define HAVE_STRFTIME 1" >>confdefs.h
 
 LIBS="-lintl $LIBS"
@@ -14301,17 +14273,13 @@ fi
 fi
 done
 
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working strnlen" >&5
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for working strnlen" >&5
 $as_echo_n "checking for working strnlen... " >&6; }
-if ${ac_cv_func_strnlen_working+:} false; then :
+if test "${ac_cv_func_strnlen_working+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   if test "$cross_compiling" = yes; then :
-  # Guess no on AIX systems, yes otherwise.
-		case "$host_os" in
-		  aix*) ac_cv_func_strnlen_working=no;;
-		  *)    ac_cv_func_strnlen_working=yes;;
-		esac
+  ac_cv_func_strnlen_working=no
 else
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
@@ -14360,7 +14328,7 @@ esac
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working strtod" >&5
 $as_echo_n "checking for working strtod... " >&6; }
-if ${ac_cv_func_strtod+:} false; then :
+if test "${ac_cv_func_strtod+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   if test "$cross_compiling" = yes; then :
@@ -14419,14 +14387,14 @@ if test $ac_cv_func_strtod = no; then
 esac
 
 ac_fn_c_check_func "$LINENO" "pow" "ac_cv_func_pow"
-if test "x$ac_cv_func_pow" = xyes; then :
+if test "x$ac_cv_func_pow" = x""yes; then :
 
 fi
 
 if test $ac_cv_func_pow = no; then
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pow in -lm" >&5
 $as_echo_n "checking for pow in -lm... " >&6; }
-if ${ac_cv_lib_m_pow+:} false; then :
+if test "${ac_cv_lib_m_pow+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -14460,7 +14428,7 @@ LIBS=$ac_check_lib_save_LIBS
 fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_pow" >&5
 $as_echo "$ac_cv_lib_m_pow" >&6; }
-if test "x$ac_cv_lib_m_pow" = xyes; then :
+if test "x$ac_cv_lib_m_pow" = x""yes; then :
   POW_LIB=-lm
 else
   { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cannot find library containing definition of pow" >&5
@@ -14476,7 +14444,7 @@ fi
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether utime accepts a null argument" >&5
 $as_echo_n "checking whether utime accepts a null argument... " >&6; }
-if ${ac_cv_func_utime_null+:} false; then :
+if test "${ac_cv_func_utime_null+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   rm -f conftest.data; >conftest.data
@@ -14526,13 +14494,13 @@ rm -f conftest.data
 for ac_func in vprintf
 do :
   ac_fn_c_check_func "$LINENO" "vprintf" "ac_cv_func_vprintf"
-if test "x$ac_cv_func_vprintf" = xyes; then :
+if test "x$ac_cv_func_vprintf" = x""yes; then :
   cat >>confdefs.h <<_ACEOF
 #define HAVE_VPRINTF 1
 _ACEOF
 
 ac_fn_c_check_func "$LINENO" "_doprnt" "ac_cv_func__doprnt"
-if test "x$ac_cv_func__doprnt" = xyes; then :
+if test "x$ac_cv_func__doprnt" = x""yes; then :
 
 $as_echo "#define HAVE_DOPRNT 1" >>confdefs.h
 
@@ -14546,7 +14514,8 @@ for ac_func in asprintf atexit closefrom dup2 eaccess endpwent euidaccess ffsll
 do :
   as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
 ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
-if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+eval as_val=\$$as_ac_var
+   if test "x$as_val" = x""yes; then :
   cat >>confdefs.h <<_ACEOF
 #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
 _ACEOF
@@ -14559,7 +14528,7 @@ done
 # so that AC_CHECK_FUNCS can detect functions in that library.
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sqrt in -lm" >&5
 $as_echo_n "checking for sqrt in -lm... " >&6; }
-if ${ac_cv_lib_m_sqrt+:} false; then :
+if test "${ac_cv_lib_m_sqrt+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -14593,7 +14562,7 @@ LIBS=$ac_check_lib_save_LIBS
 fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_sqrt" >&5
 $as_echo "$ac_cv_lib_m_sqrt" >&6; }
-if test "x$ac_cv_lib_m_sqrt" = xyes; then :
+if test "x$ac_cv_lib_m_sqrt" = x""yes; then :
   cat >>confdefs.h <<_ACEOF
 #define HAVE_LIBM 1
 _ACEOF
@@ -14607,7 +14576,8 @@ for ac_func in exp2 log2 exp10 log10 sin cos tan asin acos atan atan2 pow rint e
 do :
   as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
 ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
-if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+eval as_val=\$$as_ac_var
+   if test "x$as_val" = x""yes; then :
   cat >>confdefs.h <<_ACEOF
 #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
 _ACEOF
@@ -14623,7 +14593,8 @@ if test "x${ac_cv_type_long_double_wider}" = "xyes" ; then
 do :
   as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
 ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
-if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+eval as_val=\$$as_ac_var
+   if test "x$as_val" = x""yes; then :
   cat >>confdefs.h <<_ACEOF
 #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
 _ACEOF
@@ -14724,7 +14695,7 @@ LDFLAGS=${old_LDFLAGS}
 rm -f conftest.dynamics
 
 ac_fn_c_check_header_mongrel "$LINENO" "sys/poll.h" "ac_cv_header_sys_poll_h" "$ac_includes_default"
-if test "x$ac_cv_header_sys_poll_h" = xyes; then :
+if test "x$ac_cv_header_sys_poll_h" = x""yes; then :
   HAS_POLL=1
 
 $as_echo "#define HAVE_SYS_POLL_H 1" >>confdefs.h
@@ -14738,7 +14709,7 @@ if test "${enable_internal_poll+set}" = set; then :
   enableval=$enable_internal_poll; case "${enableval}" in
 		y|ye|yes) HAS_POLL="";;
 		n|no) HAS_POLL="${HAS_POLL}" ;;
-		*) as_fn_error $? "bad value ${enableval} for --enable-internal-poll" "$LINENO" 5 ;;
+		*) as_fn_error "bad value ${enableval} for --enable-internal-poll" "$LINENO" 5 ;;
 	esac
 fi
 
@@ -14749,7 +14720,7 @@ if test "${enable_asteriskssl+set}" = set; then :
   enableval=$enable_asteriskssl; case "${enableval}" in
 		y|ye|yes) AST_ASTERISKSSL=yes ;;
 		n|no)  AST_ASTERISKSSL=no ;;
-		*) as_fn_error $? "bad value ${enableval} for --disable-asteriskssl" "$LINENO" 5  ;;
+		*) as_fn_error "bad value ${enableval} for --disable-asteriskssl" "$LINENO" 5  ;;
 	esac
 else
   AST_ASTERISKSSL=yes
@@ -14763,7 +14734,8 @@ for ac_func in funopen fopencookie
 do :
   as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
 ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
-if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+eval as_val=\$$as_ac_var
+   if test "x$as_val" = x""yes; then :
   cat >>confdefs.h <<_ACEOF
 #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
 _ACEOF
@@ -14775,7 +14747,7 @@ done
 for ac_func in inet_aton
 do :
   ac_fn_c_check_func "$LINENO" "inet_aton" "ac_cv_func_inet_aton"
-if test "x$ac_cv_func_inet_aton" = xyes; then :
+if test "x$ac_cv_func_inet_aton" = x""yes; then :
   cat >>confdefs.h <<_ACEOF
 #define HAVE_INET_ATON 1
 _ACEOF
@@ -14815,7 +14787,7 @@ rm -f core conftest.err conftest.$ac_objext \
 # some systems already have gethostbyname_r so we don't need to build ours in main/utils.c
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing gethostbyname_r" >&5
 $as_echo_n "checking for library containing gethostbyname_r... " >&6; }
-if ${ac_cv_search_gethostbyname_r+:} false; then :
+if test "${ac_cv_search_gethostbyname_r+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   ac_func_search_save_LIBS=$LIBS
@@ -14849,11 +14821,11 @@ for ac_lib in '' socket nsl; do
 fi
 rm -f core conftest.err conftest.$ac_objext \
     conftest$ac_exeext
-  if ${ac_cv_search_gethostbyname_r+:} false; then :
+  if test "${ac_cv_search_gethostbyname_r+set}" = set; then :
   break
 fi
 done
-if ${ac_cv_search_gethostbyname_r+:} false; then :
+if test "${ac_cv_search_gethostbyname_r+set}" = set; then :
 
 else
   ac_cv_search_gethostbyname_r=no
@@ -14927,7 +14899,7 @@ rm -f core conftest.err conftest.$ac_objext \
     conftest$ac_exeext conftest.$ac_ext
 
 ac_fn_c_check_header_mongrel "$LINENO" "byteswap.h" "ac_cv_header_byteswap_h" "$ac_includes_default"
-if test "x$ac_cv_header_byteswap_h" = xyes; then :
+if test "x$ac_cv_header_byteswap_h" = x""yes; then :
 
 cat >>confdefs.h <<_ACEOF
 #define HAVE_BYTESWAP_H 1
@@ -15380,7 +15352,7 @@ rm -f core conftest.err conftest.$ac_objext \
 for ac_header in sys/thr.h
 do :
   ac_fn_c_check_header_mongrel "$LINENO" "sys/thr.h" "ac_cv_header_sys_thr_h" "$ac_includes_default"
-if test "x$ac_cv_header_sys_thr_h" = xyes; then :
+if test "x$ac_cv_header_sys_thr_h" = x""yes; then :
   cat >>confdefs.h <<_ACEOF
 #define HAVE_SYS_THR_H 1
 _ACEOF
@@ -15512,8 +15484,8 @@ if test "${ac_cv_have_variable_fdset}x" = "0x"; then
 	if test "$cross_compiling" = yes; then :
   { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error $? "cannot run test program while cross compiling
-See \`config.log' for more details" "$LINENO" 5; }
+as_fn_error "cannot run test program while cross compiling
+See \`config.log' for more details." "$LINENO" 5; }
 else
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
@@ -16556,7 +16528,7 @@ if test "${enable_rpath+set}" = set; then :
   enableval=$enable_rpath; case "${enableval}" in
 		y|ye|yes) check_rpath=yes ;;
 		n|no) check_rpath=no ;;
-                *) as_fn_error $? "bad value ${enableval} for --disable-rpath" "$LINENO" 5 ;;
+                *) as_fn_error "bad value ${enableval} for --disable-rpath" "$LINENO" 5 ;;
 	esac
 else
   check_rpath=yes
@@ -16606,7 +16578,7 @@ rm -f core conftest.err conftest.$ac_objext \
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing res_9_ninit" >&5
 $as_echo_n "checking for library containing res_9_ninit... " >&6; }
-if ${ac_cv_search_res_9_ninit+:} false; then :
+if test "${ac_cv_search_res_9_ninit+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   ac_func_search_save_LIBS=$LIBS
@@ -16640,11 +16612,11 @@ for ac_lib in '' resolv; do
 fi
 rm -f core conftest.err conftest.$ac_objext \
     conftest$ac_exeext
-  if ${ac_cv_search_res_9_ninit+:} false; then :
+  if test "${ac_cv_search_res_9_ninit+set}" = set; then :
   break
 fi
 done
-if ${ac_cv_search_res_9_ninit+:} false; then :
+if test "${ac_cv_search_res_9_ninit+set}" = set; then :
 
 else
   ac_cv_search_res_9_ninit=no
@@ -16691,7 +16663,7 @@ $as_echo "#define HAVE_RES_NINIT 1" >>confdefs.h
 
 	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing res_9_ndestroy" >&5
 $as_echo_n "checking for library containing res_9_ndestroy... " >&6; }
-if ${ac_cv_search_res_9_ndestroy+:} false; then :
+if test "${ac_cv_search_res_9_ndestroy+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   ac_func_search_save_LIBS=$LIBS
@@ -16725,11 +16697,11 @@ for ac_lib in '' resolv; do
 fi
 rm -f core conftest.err conftest.$ac_objext \
     conftest$ac_exeext
-  if ${ac_cv_search_res_9_ndestroy+:} false; then :
+  if test "${ac_cv_search_res_9_ndestroy+set}" = set; then :
   break
 fi
 done
-if ${ac_cv_search_res_9_ndestroy+:} false; then :
+if test "${ac_cv_search_res_9_ndestroy+set}" = set; then :
 
 else
   ac_cv_search_res_9_ndestroy=no
@@ -16783,7 +16755,7 @@ rm -f core conftest.err conftest.$ac_objext \
     conftest$ac_exeext conftest.$ac_ext
 	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing res_9_close" >&5
 $as_echo_n "checking for library containing res_9_close... " >&6; }
-if ${ac_cv_search_res_9_close+:} false; then :
+if test "${ac_cv_search_res_9_close+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   ac_func_search_save_LIBS=$LIBS
@@ -16817,11 +16789,11 @@ for ac_lib in '' resolv; do
 fi
 rm -f core conftest.err conftest.$ac_objext \
     conftest$ac_exeext
-  if ${ac_cv_search_res_9_close+:} false; then :
+  if test "${ac_cv_search_res_9_close+set}" = set; then :
   break
 fi
 done
-if ${ac_cv_search_res_9_close+:} false; then :
+if test "${ac_cv_search_res_9_close+set}" = set; then :
 
 else
   ac_cv_search_res_9_close=no
@@ -17023,7 +16995,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
 
 
 ac_fn_c_check_header_mongrel "$LINENO" "libkern/OSAtomic.h" "ac_cv_header_libkern_OSAtomic_h" "$ac_includes_default"
-if test "x$ac_cv_header_libkern_OSAtomic_h" = xyes; then :
+if test "x$ac_cv_header_libkern_OSAtomic_h" = x""yes; then :
 
 cat >>confdefs.h <<_ACEOF
 #define HAVE_OSX_ATOMICS 1
@@ -17039,7 +17011,7 @@ fi
 # This bug is HP SR number 8606223364.
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking size of int" >&5
 $as_echo_n "checking size of int... " >&6; }
-if ${ac_cv_sizeof_int+:} false; then :
+if test "${ac_cv_sizeof_int+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (int))" "ac_cv_sizeof_int"        "$ac_includes_default"; then :
@@ -17048,8 +17020,9 @@ else
   if test "$ac_cv_type_int" = yes; then
      { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error 77 "cannot compute sizeof (int)
-See \`config.log' for more details" "$LINENO" 5; }
+{ as_fn_set_status 77
+as_fn_error "cannot compute sizeof (int)
+See \`config.log' for more details." "$LINENO" 5; }; }
    else
      ac_cv_sizeof_int=0
    fi
@@ -17072,7 +17045,7 @@ _ACEOF
 # This bug is HP SR number 8606223364.
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long" >&5
 $as_echo_n "checking size of long... " >&6; }
-if ${ac_cv_sizeof_long+:} false; then :
+if test "${ac_cv_sizeof_long+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long))" "ac_cv_sizeof_long"        "$ac_includes_default"; then :
@@ -17081,8 +17054,9 @@ else
   if test "$ac_cv_type_long" = yes; then
      { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error 77 "cannot compute sizeof (long)
-See \`config.log' for more details" "$LINENO" 5; }
+{ as_fn_set_status 77
+as_fn_error "cannot compute sizeof (long)
+See \`config.log' for more details." "$LINENO" 5; }; }
    else
      ac_cv_sizeof_long=0
    fi
@@ -17105,7 +17079,7 @@ _ACEOF
 # This bug is HP SR number 8606223364.
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long long" >&5
 $as_echo_n "checking size of long long... " >&6; }
-if ${ac_cv_sizeof_long_long+:} false; then :
+if test "${ac_cv_sizeof_long_long+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long long))" "ac_cv_sizeof_long_long"        "$ac_includes_default"; then :
@@ -17114,8 +17088,9 @@ else
   if test "$ac_cv_type_long_long" = yes; then
      { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error 77 "cannot compute sizeof (long long)
-See \`config.log' for more details" "$LINENO" 5; }
+{ as_fn_set_status 77
+as_fn_error "cannot compute sizeof (long long)
+See \`config.log' for more details." "$LINENO" 5; }; }
    else
      ac_cv_sizeof_long_long=0
    fi
@@ -17138,7 +17113,7 @@ _ACEOF
 # This bug is HP SR number 8606223364.
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking size of char *" >&5
 $as_echo_n "checking size of char *... " >&6; }
-if ${ac_cv_sizeof_char_p+:} false; then :
+if test "${ac_cv_sizeof_char_p+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (char *))" "ac_cv_sizeof_char_p"        "$ac_includes_default"; then :
@@ -17147,8 +17122,9 @@ else
   if test "$ac_cv_type_char_p" = yes; then
      { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error 77 "cannot compute sizeof (char *)
-See \`config.log' for more details" "$LINENO" 5; }
+{ as_fn_set_status 77
+as_fn_error "cannot compute sizeof (char *)
+See \`config.log' for more details." "$LINENO" 5; }; }
    else
      ac_cv_sizeof_char_p=0
    fi
@@ -17171,7 +17147,7 @@ _ACEOF
 # This bug is HP SR number 8606223364.
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long" >&5
 $as_echo_n "checking size of long... " >&6; }
-if ${ac_cv_sizeof_long+:} false; then :
+if test "${ac_cv_sizeof_long+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long))" "ac_cv_sizeof_long"        "$ac_includes_default"; then :
@@ -17180,8 +17156,9 @@ else
   if test "$ac_cv_type_long" = yes; then
      { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error 77 "cannot compute sizeof (long)
-See \`config.log' for more details" "$LINENO" 5; }
+{ as_fn_set_status 77
+as_fn_error "cannot compute sizeof (long)
+See \`config.log' for more details." "$LINENO" 5; }; }
    else
      ac_cv_sizeof_long=0
    fi
@@ -17204,7 +17181,7 @@ _ACEOF
 # This bug is HP SR number 8606223364.
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long long" >&5
 $as_echo_n "checking size of long long... " >&6; }
-if ${ac_cv_sizeof_long_long+:} false; then :
+if test "${ac_cv_sizeof_long_long+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long long))" "ac_cv_sizeof_long_long"        "$ac_includes_default"; then :
@@ -17213,8 +17190,9 @@ else
   if test "$ac_cv_type_long_long" = yes; then
      { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error 77 "cannot compute sizeof (long long)
-See \`config.log' for more details" "$LINENO" 5; }
+{ as_fn_set_status 77
+as_fn_error "cannot compute sizeof (long long)
+See \`config.log' for more details." "$LINENO" 5; }; }
    else
      ac_cv_sizeof_long_long=0
    fi
@@ -17244,7 +17222,7 @@ fi
 # This bug is HP SR number 8606223364.
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking size of fd_set.fds_bits" >&5
 $as_echo_n "checking size of fd_set.fds_bits... " >&6; }
-if ${ac_cv_sizeof_fd_set_fds_bits+:} false; then :
+if test "${ac_cv_sizeof_fd_set_fds_bits+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (fd_set.fds_bits))" "ac_cv_sizeof_fd_set_fds_bits"        "$ac_includes_default"; then :
@@ -17253,8 +17231,9 @@ else
   if test "$ac_cv_type_fd_set_fds_bits" = yes; then
      { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error 77 "cannot compute sizeof (fd_set.fds_bits)
-See \`config.log' for more details" "$LINENO" 5; }
+{ as_fn_set_status 77
+as_fn_error "cannot compute sizeof (fd_set.fds_bits)
+See \`config.log' for more details." "$LINENO" 5; }; }
    else
      ac_cv_sizeof_fd_set_fds_bits=0
    fi
@@ -17327,18 +17306,13 @@ LIBS=${old_LIBS}
 # PKGCONFIG is used in later tests
 
 
-
-
-
-
-
 if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then
 	if test -n "$ac_tool_prefix"; then
   # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args.
 set dummy ${ac_tool_prefix}pkg-config; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_path_PKG_CONFIG+:} false; then :
+if test "${ac_cv_path_PKG_CONFIG+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   case $PKG_CONFIG in
@@ -17352,7 +17326,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
     ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -17381,7 +17355,7 @@ if test -z "$ac_cv_path_PKG_CONFIG"; then
 set dummy pkg-config; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_path_ac_pt_PKG_CONFIG+:} false; then :
+if test "${ac_cv_path_ac_pt_PKG_CONFIG+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   case $ac_pt_PKG_CONFIG in
@@ -17395,7 +17369,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
     ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -17444,6 +17418,7 @@ $as_echo "yes" >&6; }
 $as_echo "no" >&6; }
 		PKG_CONFIG=""
 	fi
+
 fi
 
 
@@ -17469,7 +17444,7 @@ if test "x${PBX_ALSA}" != "x1" -a "${USE_ALSA}" != "no"; then
       as_ac_Lib=`$as_echo "ac_cv_lib_asound_${pbxfuncname}" | $as_tr_sh`
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${pbxfuncname} in -lasound" >&5
 $as_echo_n "checking for ${pbxfuncname} in -lasound... " >&6; }
-if eval \${$as_ac_Lib+:} false; then :
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -17504,7 +17479,8 @@ fi
 eval ac_res=\$$as_ac_Lib
 	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
 $as_echo "$ac_res" >&6; }
-if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
   AST_ALSA_FOUND=yes
 else
   AST_ALSA_FOUND=no
@@ -17527,7 +17503,7 @@ fi
          ast_ext_lib_check_saved_CPPFLAGS="${CPPFLAGS}"
          CPPFLAGS="${CPPFLAGS} ${ALSA_INCLUDE}"
          ac_fn_c_check_header_mongrel "$LINENO" "alsa/asoundlib.h" "ac_cv_header_alsa_asoundlib_h" "$ac_includes_default"
-if test "x$ac_cv_header_alsa_asoundlib_h" = xyes; then :
+if test "x$ac_cv_header_alsa_asoundlib_h" = x""yes; then :
   ALSA_HEADER_FOUND=1
 else
   ALSA_HEADER_FOUND=0
@@ -17574,7 +17550,7 @@ if test "x${PBX_BFD}" != "x1" -a "${USE_BFD}" != "no"; then
       as_ac_Lib=`$as_echo "ac_cv_lib_bfd_${pbxfuncname}" | $as_tr_sh`
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${pbxfuncname} in -lbfd" >&5
 $as_echo_n "checking for ${pbxfuncname} in -lbfd... " >&6; }
-if eval \${$as_ac_Lib+:} false; then :
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -17609,7 +17585,8 @@ fi
 eval ac_res=\$$as_ac_Lib
 	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
 $as_echo "$ac_res" >&6; }
-if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
   AST_BFD_FOUND=yes
 else
   AST_BFD_FOUND=no
@@ -17632,7 +17609,7 @@ fi
          ast_ext_lib_check_saved_CPPFLAGS="${CPPFLAGS}"
          CPPFLAGS="${CPPFLAGS} ${BFD_INCLUDE}"
          ac_fn_c_check_header_mongrel "$LINENO" "bfd.h" "ac_cv_header_bfd_h" "$ac_includes_default"
-if test "x$ac_cv_header_bfd_h" = xyes; then :
+if test "x$ac_cv_header_bfd_h" = x""yes; then :
   BFD_HEADER_FOUND=1
 else
   BFD_HEADER_FOUND=0
@@ -17681,7 +17658,7 @@ if test "x${PBX_BFD}" != "x1" -a "${USE_BFD}" != "no"; then
       as_ac_Lib=`$as_echo "ac_cv_lib_bfd_${pbxfuncname}" | $as_tr_sh`
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${pbxfuncname} in -lbfd" >&5
 $as_echo_n "checking for ${pbxfuncname} in -lbfd... " >&6; }
-if eval \${$as_ac_Lib+:} false; then :
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -17716,7 +17693,8 @@ fi
 eval ac_res=\$$as_ac_Lib
 	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
 $as_echo "$ac_res" >&6; }
-if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
   AST_BFD_FOUND=yes
 else
   AST_BFD_FOUND=no
@@ -17739,7 +17717,7 @@ fi
          ast_ext_lib_check_saved_CPPFLAGS="${CPPFLAGS}"
          CPPFLAGS="${CPPFLAGS} ${BFD_INCLUDE}"
          ac_fn_c_check_header_mongrel "$LINENO" "bfd.h" "ac_cv_header_bfd_h" "$ac_includes_default"
-if test "x$ac_cv_header_bfd_h" = xyes; then :
+if test "x$ac_cv_header_bfd_h" = x""yes; then :
   BFD_HEADER_FOUND=1
 else
   BFD_HEADER_FOUND=0
@@ -17788,7 +17766,7 @@ if test "x${PBX_CAP}" != "x1" -a "${USE_CAP}" != "no"; then
       as_ac_Lib=`$as_echo "ac_cv_lib_cap_${pbxfuncname}" | $as_tr_sh`
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${pbxfuncname} in -lcap" >&5
 $as_echo_n "checking for ${pbxfuncname} in -lcap... " >&6; }
-if eval \${$as_ac_Lib+:} false; then :
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -17823,7 +17801,8 @@ fi
 eval ac_res=\$$as_ac_Lib
 	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
 $as_echo "$ac_res" >&6; }
-if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
   AST_CAP_FOUND=yes
 else
   AST_CAP_FOUND=no
@@ -17846,7 +17825,7 @@ fi
          ast_ext_lib_check_saved_CPPFLAGS="${CPPFLAGS}"
          CPPFLAGS="${CPPFLAGS} ${CAP_INCLUDE}"
          ac_fn_c_check_header_mongrel "$LINENO" "sys/capability.h" "ac_cv_header_sys_capability_h" "$ac_includes_default"
-if test "x$ac_cv_header_sys_capability_h" = xyes; then :
+if test "x$ac_cv_header_sys_capability_h" = x""yes; then :
   CAP_HEADER_FOUND=1
 else
   CAP_HEADER_FOUND=0
@@ -18269,7 +18248,7 @@ if test "${USE_GSM}" != "no"; then
       fi
       { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gsm_create in -lgsm" >&5
 $as_echo_n "checking for gsm_create in -lgsm... " >&6; }
-if ${ac_cv_lib_gsm_gsm_create+:} false; then :
+if test "${ac_cv_lib_gsm_gsm_create+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -18303,7 +18282,7 @@ LIBS=$ac_check_lib_save_LIBS
 fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_gsm_gsm_create" >&5
 $as_echo "$ac_cv_lib_gsm_gsm_create" >&6; }
-if test "x$ac_cv_lib_gsm_gsm_create" = xyes; then :
+if test "x$ac_cv_lib_gsm_gsm_create" = x""yes; then :
 
 cat >>confdefs.h <<_ACEOF
 #define HAVE_GSM 1
@@ -18315,7 +18294,8 @@ fi
          if test "x${GSM_DIR}" != "x" ; then
             as_ac_Header=`$as_echo "ac_cv_header_${GSM_DIR}/include/gsm.h" | $as_tr_sh`
 ac_fn_c_check_header_mongrel "$LINENO" "${GSM_DIR}/include/gsm.h" "$as_ac_Header" "$ac_includes_default"
-if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+eval as_val=\$$as_ac_Header
+   if test "x$as_val" = x""yes; then :
   GSM_HEADER_FOUND=1
 else
   GSM_HEADER_FOUND=0
@@ -18324,7 +18304,8 @@ fi
 
             as_ac_Header=`$as_echo "ac_cv_header_${GSM_DIR}/include/gsm/gsm.h" | $as_tr_sh`
 ac_fn_c_check_header_mongrel "$LINENO" "${GSM_DIR}/include/gsm/gsm.h" "$as_ac_Header" "$ac_includes_default"
-if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+eval as_val=\$$as_ac_Header
+   if test "x$as_val" = x""yes; then :
   GSM_GSM_HEADER_FOUND=1
 else
   GSM_GSM_HEADER_FOUND=0
@@ -18333,7 +18314,7 @@ fi
 
          else
             ac_fn_c_check_header_mongrel "$LINENO" "gsm.h" "ac_cv_header_gsm_h" "$ac_includes_default"
-if test "x$ac_cv_header_gsm_h" = xyes; then :
+if test "x$ac_cv_header_gsm_h" = x""yes; then :
   GSM_HEADER_FOUND=1
 else
   GSM_HEADER_FOUND=0
@@ -18341,7 +18322,7 @@ fi
 
 
             ac_fn_c_check_header_mongrel "$LINENO" "gsm/gsm.h" "ac_cv_header_gsm_gsm_h" "$ac_includes_default"
-if test "x$ac_cv_header_gsm_gsm_h" = xyes; then :
+if test "x$ac_cv_header_gsm_gsm_h" = x""yes; then :
   GSM_GSM_HEADER_FOUND=1
 else
   GSM_GSM_HEADER_FOUND=0
@@ -18420,46 +18401,46 @@ pkg_failed=no
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ILBC" >&5
 $as_echo_n "checking for ILBC... " >&6; }
 
-if test -n "$ILBC_CFLAGS"; then
-    pkg_cv_ILBC_CFLAGS="$ILBC_CFLAGS"
- elif test -n "$PKG_CONFIG"; then
-    if test -n "$PKG_CONFIG" && \
+if test -n "$PKG_CONFIG"; then
+    if test -n "$ILBC_CFLAGS"; then
+        pkg_cv_ILBC_CFLAGS="$ILBC_CFLAGS"
+    else
+        if test -n "$PKG_CONFIG" && \
     { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libilbc\""; } >&5
   ($PKG_CONFIG --exists --print-errors "libilbc") 2>&5
   ac_status=$?
   $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }; then
   pkg_cv_ILBC_CFLAGS=`$PKG_CONFIG --cflags "libilbc" 2>/dev/null`
-		      test "x$?" != "x0" && pkg_failed=yes
 else
   pkg_failed=yes
 fi
- else
-    pkg_failed=untried
+    fi
+else
+	pkg_failed=untried
 fi
-if test -n "$ILBC_LIBS"; then
-    pkg_cv_ILBC_LIBS="$ILBC_LIBS"
- elif test -n "$PKG_CONFIG"; then
-    if test -n "$PKG_CONFIG" && \
+if test -n "$PKG_CONFIG"; then
+    if test -n "$ILBC_LIBS"; then
+        pkg_cv_ILBC_LIBS="$ILBC_LIBS"
+    else
+        if test -n "$PKG_CONFIG" && \
     { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libilbc\""; } >&5
   ($PKG_CONFIG --exists --print-errors "libilbc") 2>&5
   ac_status=$?
   $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }; then
   pkg_cv_ILBC_LIBS=`$PKG_CONFIG --libs "libilbc" 2>/dev/null`
-		      test "x$?" != "x0" && pkg_failed=yes
 else
   pkg_failed=yes
 fi
- else
-    pkg_failed=untried
+    fi
+else
+	pkg_failed=untried
 fi
 
 
 
 if test $pkg_failed = yes; then
-   	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
 
 if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
         _pkg_short_errors_supported=yes
@@ -18467,20 +18448,20 @@ else
         _pkg_short_errors_supported=no
 fi
         if test $_pkg_short_errors_supported = yes; then
-	        ILBC_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libilbc" 2>&1`
+	        ILBC_PKG_ERRORS=`$PKG_CONFIG --short-errors --errors-to-stdout --print-errors "libilbc"`
         else
-	        ILBC_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libilbc" 2>&1`
+	        ILBC_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "libilbc"`
         fi
 	# Put the nasty error message in config.log where it belongs
 	echo "$ILBC_PKG_ERRORS" >&5
 
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
 
             PBX_ILBC=0
 
 
 elif test $pkg_failed = untried; then
-     	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
 
             PBX_ILBC=0
 
@@ -18527,46 +18508,46 @@ pkg_failed=no
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for LIBEDIT" >&5
 $as_echo_n "checking for LIBEDIT... " >&6; }
 
-if test -n "$LIBEDIT_CFLAGS"; then
-    pkg_cv_LIBEDIT_CFLAGS="$LIBEDIT_CFLAGS"
- elif test -n "$PKG_CONFIG"; then
-    if test -n "$PKG_CONFIG" && \
+if test -n "$PKG_CONFIG"; then
+    if test -n "$LIBEDIT_CFLAGS"; then
+        pkg_cv_LIBEDIT_CFLAGS="$LIBEDIT_CFLAGS"
+    else
+        if test -n "$PKG_CONFIG" && \
     { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libedit\""; } >&5
   ($PKG_CONFIG --exists --print-errors "libedit") 2>&5
   ac_status=$?
   $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }; then
   pkg_cv_LIBEDIT_CFLAGS=`$PKG_CONFIG --cflags "libedit" 2>/dev/null`
-		      test "x$?" != "x0" && pkg_failed=yes
 else
   pkg_failed=yes
 fi
- else
-    pkg_failed=untried
+    fi
+else
+	pkg_failed=untried
 fi
-if test -n "$LIBEDIT_LIBS"; then
-    pkg_cv_LIBEDIT_LIBS="$LIBEDIT_LIBS"
- elif test -n "$PKG_CONFIG"; then
-    if test -n "$PKG_CONFIG" && \
+if test -n "$PKG_CONFIG"; then
+    if test -n "$LIBEDIT_LIBS"; then
+        pkg_cv_LIBEDIT_LIBS="$LIBEDIT_LIBS"
+    else
+        if test -n "$PKG_CONFIG" && \
     { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libedit\""; } >&5
   ($PKG_CONFIG --exists --print-errors "libedit") 2>&5
   ac_status=$?
   $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }; then
   pkg_cv_LIBEDIT_LIBS=`$PKG_CONFIG --libs "libedit" 2>/dev/null`
-		      test "x$?" != "x0" && pkg_failed=yes
 else
   pkg_failed=yes
 fi
- else
-    pkg_failed=untried
+    fi
+else
+	pkg_failed=untried
 fi
 
 
 
 if test $pkg_failed = yes; then
-   	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
 
 if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
         _pkg_short_errors_supported=yes
@@ -18574,20 +18555,20 @@ else
         _pkg_short_errors_supported=no
 fi
         if test $_pkg_short_errors_supported = yes; then
-	        LIBEDIT_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libedit" 2>&1`
+	        LIBEDIT_PKG_ERRORS=`$PKG_CONFIG --short-errors --errors-to-stdout --print-errors "libedit"`
         else
-	        LIBEDIT_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libedit" 2>&1`
+	        LIBEDIT_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "libedit"`
         fi
 	# Put the nasty error message in config.log where it belongs
 	echo "$LIBEDIT_PKG_ERRORS" >&5
 
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
 
             PBX_LIBEDIT=0
 
 
 elif test $pkg_failed = untried; then
-     	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
 
             PBX_LIBEDIT=0
 
@@ -18637,7 +18618,7 @@ if test "x${PBX_ICONV}" != "x1" -a "${USE_ICONV}" != "no"; then
       as_ac_Lib=`$as_echo "ac_cv_lib_iconv_${pbxfuncname}" | $as_tr_sh`
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${pbxfuncname} in -liconv" >&5
 $as_echo_n "checking for ${pbxfuncname} in -liconv... " >&6; }
-if eval \${$as_ac_Lib+:} false; then :
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -18672,7 +18653,8 @@ fi
 eval ac_res=\$$as_ac_Lib
 	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
 $as_echo "$ac_res" >&6; }
-if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
   AST_ICONV_FOUND=yes
 else
   AST_ICONV_FOUND=no
@@ -18695,7 +18677,7 @@ fi
          ast_ext_lib_check_saved_CPPFLAGS="${CPPFLAGS}"
          CPPFLAGS="${CPPFLAGS} ${ICONV_INCLUDE}"
          ac_fn_c_check_header_mongrel "$LINENO" "iconv.h" "ac_cv_header_iconv_h" "$ac_includes_default"
-if test "x$ac_cv_header_iconv_h" = xyes; then :
+if test "x$ac_cv_header_iconv_h" = x""yes; then :
   ICONV_HEADER_FOUND=1
 else
   ICONV_HEADER_FOUND=0
@@ -18742,7 +18724,7 @@ if test "x${PBX_ICONV}" != "x1" -a "${USE_ICONV}" != "no"; then
       as_ac_Lib=`$as_echo "ac_cv_lib_iconv_${pbxfuncname}" | $as_tr_sh`
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${pbxfuncname} in -liconv" >&5
 $as_echo_n "checking for ${pbxfuncname} in -liconv... " >&6; }
-if eval \${$as_ac_Lib+:} false; then :
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -18777,7 +18759,8 @@ fi
 eval ac_res=\$$as_ac_Lib
 	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
 $as_echo "$ac_res" >&6; }
-if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
   AST_ICONV_FOUND=yes
 else
   AST_ICONV_FOUND=no
@@ -18800,7 +18783,7 @@ fi
          ast_ext_lib_check_saved_CPPFLAGS="${CPPFLAGS}"
          CPPFLAGS="${CPPFLAGS} ${ICONV_INCLUDE}"
          ac_fn_c_check_header_mongrel "$LINENO" "iconv.h" "ac_cv_header_iconv_h" "$ac_includes_default"
-if test "x$ac_cv_header_iconv_h" = xyes; then :
+if test "x$ac_cv_header_iconv_h" = x""yes; then :
   ICONV_HEADER_FOUND=1
 else
   ICONV_HEADER_FOUND=0
@@ -18847,7 +18830,7 @@ if test "x${PBX_ICONV}" != "x1" -a "${USE_ICONV}" != "no"; then
       as_ac_Lib=`$as_echo "ac_cv_lib_c_${pbxfuncname}" | $as_tr_sh`
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${pbxfuncname} in -lc" >&5
 $as_echo_n "checking for ${pbxfuncname} in -lc... " >&6; }
-if eval \${$as_ac_Lib+:} false; then :
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -18882,7 +18865,8 @@ fi
 eval ac_res=\$$as_ac_Lib
 	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
 $as_echo "$ac_res" >&6; }
-if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
   AST_ICONV_FOUND=yes
 else
   AST_ICONV_FOUND=no
@@ -18905,7 +18889,7 @@ fi
          ast_ext_lib_check_saved_CPPFLAGS="${CPPFLAGS}"
          CPPFLAGS="${CPPFLAGS} ${ICONV_INCLUDE}"
          ac_fn_c_check_header_mongrel "$LINENO" "iconv.h" "ac_cv_header_iconv_h" "$ac_includes_default"
-if test "x$ac_cv_header_iconv_h" = xyes; then :
+if test "x$ac_cv_header_iconv_h" = x""yes; then :
   ICONV_HEADER_FOUND=1
 else
   ICONV_HEADER_FOUND=0
@@ -18953,7 +18937,7 @@ if test "x${PBX_ICAL}" != "x1" -a "${USE_ICAL}" != "no"; then
       as_ac_Lib=`$as_echo "ac_cv_lib_ical_${pbxfuncname}" | $as_tr_sh`
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${pbxfuncname} in -lical" >&5
 $as_echo_n "checking for ${pbxfuncname} in -lical... " >&6; }
-if eval \${$as_ac_Lib+:} false; then :
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -18988,7 +18972,8 @@ fi
 eval ac_res=\$$as_ac_Lib
 	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
 $as_echo "$ac_res" >&6; }
-if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
   AST_ICAL_FOUND=yes
 else
   AST_ICAL_FOUND=no
@@ -19011,7 +18996,7 @@ fi
          ast_ext_lib_check_saved_CPPFLAGS="${CPPFLAGS}"
          CPPFLAGS="${CPPFLAGS} ${ICAL_INCLUDE}"
          ac_fn_c_check_header_mongrel "$LINENO" "libical/ical.h" "ac_cv_header_libical_ical_h" "$ac_includes_default"
-if test "x$ac_cv_header_libical_ical_h" = xyes; then :
+if test "x$ac_cv_header_libical_ical_h" = x""yes; then :
   ICAL_HEADER_FOUND=1
 else
   ICAL_HEADER_FOUND=0
@@ -19058,7 +19043,7 @@ if test "x${PBX_IKSEMEL}" != "x1" -a "${USE_IKSEMEL}" != "no"; then
       as_ac_Lib=`$as_echo "ac_cv_lib_iksemel_${pbxfuncname}" | $as_tr_sh`
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${pbxfuncname} in -liksemel" >&5
 $as_echo_n "checking for ${pbxfuncname} in -liksemel... " >&6; }
-if eval \${$as_ac_Lib+:} false; then :
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -19093,7 +19078,8 @@ fi
 eval ac_res=\$$as_ac_Lib
 	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
 $as_echo "$ac_res" >&6; }
-if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
   AST_IKSEMEL_FOUND=yes
 else
   AST_IKSEMEL_FOUND=no
@@ -19116,7 +19102,7 @@ fi
          ast_ext_lib_check_saved_CPPFLAGS="${CPPFLAGS}"
          CPPFLAGS="${CPPFLAGS} ${IKSEMEL_INCLUDE}"
          ac_fn_c_check_header_mongrel "$LINENO" "iksemel.h" "ac_cv_header_iksemel_h" "$ac_includes_default"
-if test "x$ac_cv_header_iksemel_h" = xyes; then :
+if test "x$ac_cv_header_iksemel_h" = x""yes; then :
   IKSEMEL_HEADER_FOUND=1
 else
   IKSEMEL_HEADER_FOUND=0
@@ -19791,7 +19777,7 @@ if test "x${PBX_IODBC}" != "x1" -a "${USE_IODBC}" != "no"; then
       as_ac_Lib=`$as_echo "ac_cv_lib_iodbc_${pbxfuncname}" | $as_tr_sh`
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${pbxfuncname} in -liodbc" >&5
 $as_echo_n "checking for ${pbxfuncname} in -liodbc... " >&6; }
-if eval \${$as_ac_Lib+:} false; then :
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -19826,7 +19812,8 @@ fi
 eval ac_res=\$$as_ac_Lib
 	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
 $as_echo "$ac_res" >&6; }
-if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
   AST_IODBC_FOUND=yes
 else
   AST_IODBC_FOUND=no
@@ -19849,7 +19836,7 @@ fi
          ast_ext_lib_check_saved_CPPFLAGS="${CPPFLAGS}"
          CPPFLAGS="${CPPFLAGS} ${IODBC_INCLUDE}"
          ac_fn_c_check_header_mongrel "$LINENO" "sql.h" "ac_cv_header_sql_h" "$ac_includes_default"
-if test "x$ac_cv_header_sql_h" = xyes; then :
+if test "x$ac_cv_header_sql_h" = x""yes; then :
   IODBC_HEADER_FOUND=1
 else
   IODBC_HEADER_FOUND=0
@@ -19896,7 +19883,7 @@ if test "x${PBX_INOTIFY}" != "x1" -a "${USE_INOTIFY}" != "no"; then
       as_ac_Lib=`$as_echo "ac_cv_lib_c_${pbxfuncname}" | $as_tr_sh`
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${pbxfuncname} in -lc" >&5
 $as_echo_n "checking for ${pbxfuncname} in -lc... " >&6; }
-if eval \${$as_ac_Lib+:} false; then :
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -19931,7 +19918,8 @@ fi
 eval ac_res=\$$as_ac_Lib
 	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
 $as_echo "$ac_res" >&6; }
-if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
   AST_INOTIFY_FOUND=yes
 else
   AST_INOTIFY_FOUND=no
@@ -19954,7 +19942,7 @@ fi
          ast_ext_lib_check_saved_CPPFLAGS="${CPPFLAGS}"
          CPPFLAGS="${CPPFLAGS} ${INOTIFY_INCLUDE}"
          ac_fn_c_check_header_mongrel "$LINENO" "sys/inotify.h" "ac_cv_header_sys_inotify_h" "$ac_includes_default"
-if test "x$ac_cv_header_sys_inotify_h" = xyes; then :
+if test "x$ac_cv_header_sys_inotify_h" = x""yes; then :
   INOTIFY_HEADER_FOUND=1
 else
   INOTIFY_HEADER_FOUND=0
@@ -20001,7 +19989,7 @@ if test "x${PBX_JACK}" != "x1" -a "${USE_JACK}" != "no"; then
       as_ac_Lib=`$as_echo "ac_cv_lib_jack_${pbxfuncname}" | $as_tr_sh`
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${pbxfuncname} in -ljack" >&5
 $as_echo_n "checking for ${pbxfuncname} in -ljack... " >&6; }
-if eval \${$as_ac_Lib+:} false; then :
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -20036,7 +20024,8 @@ fi
 eval ac_res=\$$as_ac_Lib
 	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
 $as_echo "$ac_res" >&6; }
-if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
   AST_JACK_FOUND=yes
 else
   AST_JACK_FOUND=no
@@ -20059,7 +20048,7 @@ fi
          ast_ext_lib_check_saved_CPPFLAGS="${CPPFLAGS}"
          CPPFLAGS="${CPPFLAGS} ${JACK_INCLUDE}"
          ac_fn_c_check_header_mongrel "$LINENO" "jack/jack.h" "ac_cv_header_jack_jack_h" "$ac_includes_default"
-if test "x$ac_cv_header_jack_jack_h" = xyes; then :
+if test "x$ac_cv_header_jack_jack_h" = x""yes; then :
   JACK_HEADER_FOUND=1
 else
   JACK_HEADER_FOUND=0
@@ -20107,7 +20096,7 @@ if test "x${PBX_KQUEUE}" != "x1" -a "${USE_KQUEUE}" != "no"; then
       as_ac_Lib=`$as_echo "ac_cv_lib_c_${pbxfuncname}" | $as_tr_sh`
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${pbxfuncname} in -lc" >&5
 $as_echo_n "checking for ${pbxfuncname} in -lc... " >&6; }
-if eval \${$as_ac_Lib+:} false; then :
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -20142,7 +20131,8 @@ fi
 eval ac_res=\$$as_ac_Lib
 	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
 $as_echo "$ac_res" >&6; }
-if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
   AST_KQUEUE_FOUND=yes
 else
   AST_KQUEUE_FOUND=no
@@ -20165,7 +20155,7 @@ fi
          ast_ext_lib_check_saved_CPPFLAGS="${CPPFLAGS}"
          CPPFLAGS="${CPPFLAGS} ${KQUEUE_INCLUDE}"
          ac_fn_c_check_header_mongrel "$LINENO" "sys/event.h" "ac_cv_header_sys_event_h" "$ac_includes_default"
-if test "x$ac_cv_header_sys_event_h" = xyes; then :
+if test "x$ac_cv_header_sys_event_h" = x""yes; then :
   KQUEUE_HEADER_FOUND=1
 else
   KQUEUE_HEADER_FOUND=0
@@ -20196,7 +20186,7 @@ fi
 for ac_func in kevent64
 do :
   ac_fn_c_check_func "$LINENO" "kevent64" "ac_cv_func_kevent64"
-if test "x$ac_cv_func_kevent64" = xyes; then :
+if test "x$ac_cv_func_kevent64" = x""yes; then :
   cat >>confdefs.h <<_ACEOF
 #define HAVE_KEVENT64 1
 _ACEOF
@@ -20226,7 +20216,7 @@ if test "x${PBX_LTDL}" != "x1" -a "${USE_LTDL}" != "no"; then
       as_ac_Lib=`$as_echo "ac_cv_lib_ltdl_${pbxfuncname}" | $as_tr_sh`
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${pbxfuncname} in -lltdl" >&5
 $as_echo_n "checking for ${pbxfuncname} in -lltdl... " >&6; }
-if eval \${$as_ac_Lib+:} false; then :
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -20261,7 +20251,8 @@ fi
 eval ac_res=\$$as_ac_Lib
 	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
 $as_echo "$ac_res" >&6; }
-if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
   AST_LTDL_FOUND=yes
 else
   AST_LTDL_FOUND=no
@@ -20284,7 +20275,7 @@ fi
          ast_ext_lib_check_saved_CPPFLAGS="${CPPFLAGS}"
          CPPFLAGS="${CPPFLAGS} ${LTDL_INCLUDE}"
          ac_fn_c_check_header_mongrel "$LINENO" "ltdl.h" "ac_cv_header_ltdl_h" "$ac_includes_default"
-if test "x$ac_cv_header_ltdl_h" = xyes; then :
+if test "x$ac_cv_header_ltdl_h" = x""yes; then :
   LTDL_HEADER_FOUND=1
 else
   LTDL_HEADER_FOUND=0
@@ -20331,7 +20322,7 @@ if test "x${PBX_LDAP}" != "x1" -a "${USE_LDAP}" != "no"; then
       as_ac_Lib=`$as_echo "ac_cv_lib_ldap_${pbxfuncname}" | $as_tr_sh`
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${pbxfuncname} in -lldap" >&5
 $as_echo_n "checking for ${pbxfuncname} in -lldap... " >&6; }
-if eval \${$as_ac_Lib+:} false; then :
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -20366,7 +20357,8 @@ fi
 eval ac_res=\$$as_ac_Lib
 	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
 $as_echo "$ac_res" >&6; }
-if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
   AST_LDAP_FOUND=yes
 else
   AST_LDAP_FOUND=no
@@ -20389,7 +20381,7 @@ fi
          ast_ext_lib_check_saved_CPPFLAGS="${CPPFLAGS}"
          CPPFLAGS="${CPPFLAGS} ${LDAP_INCLUDE}"
          ac_fn_c_check_header_mongrel "$LINENO" "ldap.h" "ac_cv_header_ldap_h" "$ac_includes_default"
-if test "x$ac_cv_header_ldap_h" = xyes; then :
+if test "x$ac_cv_header_ldap_h" = x""yes; then :
   LDAP_HEADER_FOUND=1
 else
   LDAP_HEADER_FOUND=0
@@ -20436,7 +20428,7 @@ if test "x${PBX_MISDN}" != "x1" -a "${USE_MISDN}" != "no"; then
       as_ac_Lib=`$as_echo "ac_cv_lib_mISDN_${pbxfuncname}" | $as_tr_sh`
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${pbxfuncname} in -lmISDN" >&5
 $as_echo_n "checking for ${pbxfuncname} in -lmISDN... " >&6; }
-if eval \${$as_ac_Lib+:} false; then :
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -20471,7 +20463,8 @@ fi
 eval ac_res=\$$as_ac_Lib
 	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
 $as_echo "$ac_res" >&6; }
-if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
   AST_MISDN_FOUND=yes
 else
   AST_MISDN_FOUND=no
@@ -20494,7 +20487,7 @@ fi
          ast_ext_lib_check_saved_CPPFLAGS="${CPPFLAGS}"
          CPPFLAGS="${CPPFLAGS} ${MISDN_INCLUDE}"
          ac_fn_c_check_header_mongrel "$LINENO" "mISDNuser/mISDNlib.h" "ac_cv_header_mISDNuser_mISDNlib_h" "$ac_includes_default"
-if test "x$ac_cv_header_mISDNuser_mISDNlib_h" = xyes; then :
+if test "x$ac_cv_header_mISDNuser_mISDNlib_h" = x""yes; then :
   MISDN_HEADER_FOUND=1
 else
   MISDN_HEADER_FOUND=0
@@ -20542,7 +20535,7 @@ if test "x${PBX_ISDNNET}" != "x1" -a "${USE_ISDNNET}" != "no"; then
       as_ac_Lib=`$as_echo "ac_cv_lib_isdnnet_${pbxfuncname}" | $as_tr_sh`
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${pbxfuncname} in -lisdnnet" >&5
 $as_echo_n "checking for ${pbxfuncname} in -lisdnnet... " >&6; }
-if eval \${$as_ac_Lib+:} false; then :
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -20577,7 +20570,8 @@ fi
 eval ac_res=\$$as_ac_Lib
 	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
 $as_echo "$ac_res" >&6; }
-if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
   AST_ISDNNET_FOUND=yes
 else
   AST_ISDNNET_FOUND=no
@@ -20600,7 +20594,7 @@ fi
          ast_ext_lib_check_saved_CPPFLAGS="${CPPFLAGS}"
          CPPFLAGS="${CPPFLAGS} ${ISDNNET_INCLUDE}"
          ac_fn_c_check_header_mongrel "$LINENO" "mISDNuser/isdn_net.h" "ac_cv_header_mISDNuser_isdn_net_h" "$ac_includes_default"
-if test "x$ac_cv_header_mISDNuser_isdn_net_h" = xyes; then :
+if test "x$ac_cv_header_mISDNuser_isdn_net_h" = x""yes; then :
   ISDNNET_HEADER_FOUND=1
 else
   ISDNNET_HEADER_FOUND=0
@@ -20646,7 +20640,7 @@ if test "x${PBX_SUPPSERV}" != "x1" -a "${USE_SUPPSERV}" != "no"; then
       as_ac_Lib=`$as_echo "ac_cv_lib_suppserv_${pbxfuncname}" | $as_tr_sh`
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${pbxfuncname} in -lsuppserv" >&5
 $as_echo_n "checking for ${pbxfuncname} in -lsuppserv... " >&6; }
-if eval \${$as_ac_Lib+:} false; then :
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -20681,7 +20675,8 @@ fi
 eval ac_res=\$$as_ac_Lib
 	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
 $as_echo "$ac_res" >&6; }
-if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
   AST_SUPPSERV_FOUND=yes
 else
   AST_SUPPSERV_FOUND=no
@@ -20704,7 +20699,7 @@ fi
          ast_ext_lib_check_saved_CPPFLAGS="${CPPFLAGS}"
          CPPFLAGS="${CPPFLAGS} ${SUPPSERV_INCLUDE}"
          ac_fn_c_check_header_mongrel "$LINENO" "mISDNuser/suppserv.h" "ac_cv_header_mISDNuser_suppserv_h" "$ac_includes_default"
-if test "x$ac_cv_header_mISDNuser_suppserv_h" = xyes; then :
+if test "x$ac_cv_header_mISDNuser_suppserv_h" = x""yes; then :
   SUPPSERV_HEADER_FOUND=1
 else
   SUPPSERV_HEADER_FOUND=0
@@ -20823,7 +20818,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
 
 
    ac_fn_c_check_header_mongrel "$LINENO" "linux/mISDNdsp.h" "ac_cv_header_linux_mISDNdsp_h" "$ac_includes_default"
-if test "x$ac_cv_header_linux_mISDNdsp_h" = xyes; then :
+if test "x$ac_cv_header_linux_mISDNdsp_h" = x""yes; then :
 
 cat >>confdefs.h <<_ACEOF
 #define MISDN_1_2 1
@@ -20834,7 +20829,7 @@ fi
 
    ac_fn_c_check_member "$LINENO" "Q931_info_t" "redirect_dn" "ac_cv_member_Q931_info_t_redirect_dn" "#include <mISDNuser/mISDNlib.h>
 "
-if test "x$ac_cv_member_Q931_info_t_redirect_dn" = xyes; then :
+if test "x$ac_cv_member_Q931_info_t_redirect_dn" = x""yes; then :
 
 else
   PBX_MISDN=0
@@ -20850,7 +20845,7 @@ fi
 set dummy ${ac_tool_prefix}mysql_config; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_path_CONFIG_MYSQLCLIENT+:} false; then :
+if test "${ac_cv_path_CONFIG_MYSQLCLIENT+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   case $CONFIG_MYSQLCLIENT in
@@ -20865,7 +20860,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
     ac_cv_path_CONFIG_MYSQLCLIENT="$as_dir/$ac_word$ac_exec_ext"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -20894,7 +20889,7 @@ if test -z "$ac_cv_path_CONFIG_MYSQLCLIENT"; then
 set dummy mysql_config; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_path_ac_pt_CONFIG_MYSQLCLIENT+:} false; then :
+if test "${ac_cv_path_ac_pt_CONFIG_MYSQLCLIENT+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   case $ac_pt_CONFIG_MYSQLCLIENT in
@@ -20909,7 +20904,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
     ac_cv_path_ac_pt_CONFIG_MYSQLCLIENT="$as_dir/$ac_word$ac_exec_ext"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -21013,7 +21008,7 @@ if test "x${PBX_NBS}" != "x1" -a "${USE_NBS}" != "no"; then
       as_ac_Lib=`$as_echo "ac_cv_lib_nbs_${pbxfuncname}" | $as_tr_sh`
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${pbxfuncname} in -lnbs" >&5
 $as_echo_n "checking for ${pbxfuncname} in -lnbs... " >&6; }
-if eval \${$as_ac_Lib+:} false; then :
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -21048,7 +21043,8 @@ fi
 eval ac_res=\$$as_ac_Lib
 	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
 $as_echo "$ac_res" >&6; }
-if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
   AST_NBS_FOUND=yes
 else
   AST_NBS_FOUND=no
@@ -21071,7 +21067,7 @@ fi
          ast_ext_lib_check_saved_CPPFLAGS="${CPPFLAGS}"
          CPPFLAGS="${CPPFLAGS} ${NBS_INCLUDE}"
          ac_fn_c_check_header_mongrel "$LINENO" "nbs.h" "ac_cv_header_nbs_h" "$ac_includes_default"
-if test "x$ac_cv_header_nbs_h" = xyes; then :
+if test "x$ac_cv_header_nbs_h" = x""yes; then :
   NBS_HEADER_FOUND=1
 else
   NBS_HEADER_FOUND=0
@@ -21106,7 +21102,7 @@ fi
 set dummy ${ac_tool_prefix}neon-config; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_path_CONFIG_NEON+:} false; then :
+if test "${ac_cv_path_CONFIG_NEON+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   case $CONFIG_NEON in
@@ -21121,7 +21117,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
     ac_cv_path_CONFIG_NEON="$as_dir/$ac_word$ac_exec_ext"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -21150,7 +21146,7 @@ if test -z "$ac_cv_path_CONFIG_NEON"; then
 set dummy neon-config; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_path_ac_pt_CONFIG_NEON+:} false; then :
+if test "${ac_cv_path_ac_pt_CONFIG_NEON+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   case $ac_pt_CONFIG_NEON in
@@ -21165,7 +21161,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
     ac_cv_path_ac_pt_CONFIG_NEON="$as_dir/$ac_word$ac_exec_ext"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -21257,7 +21253,7 @@ $as_echo "#define HAVE_NEON 1" >>confdefs.h
 set dummy ${ac_tool_prefix}neon-config; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_path_CONFIG_NEON29+:} false; then :
+if test "${ac_cv_path_CONFIG_NEON29+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   case $CONFIG_NEON29 in
@@ -21272,7 +21268,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
     ac_cv_path_CONFIG_NEON29="$as_dir/$ac_word$ac_exec_ext"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -21301,7 +21297,7 @@ if test -z "$ac_cv_path_CONFIG_NEON29"; then
 set dummy neon-config; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_path_ac_pt_CONFIG_NEON29+:} false; then :
+if test "${ac_cv_path_ac_pt_CONFIG_NEON29+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   case $ac_pt_CONFIG_NEON29 in
@@ -21316,7 +21312,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
     ac_cv_path_ac_pt_CONFIG_NEON29="$as_dir/$ac_word$ac_exec_ext"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -21410,7 +21406,7 @@ $as_echo "#define HAVE_NEON29 1" >>confdefs.h
 set dummy ${ac_tool_prefix}net-snmp-config; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_path_CONFIG_NETSNMP+:} false; then :
+if test "${ac_cv_path_CONFIG_NETSNMP+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   case $CONFIG_NETSNMP in
@@ -21425,7 +21421,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
     ac_cv_path_CONFIG_NETSNMP="$as_dir/$ac_word$ac_exec_ext"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -21454,7 +21450,7 @@ if test -z "$ac_cv_path_CONFIG_NETSNMP"; then
 set dummy net-snmp-config; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_path_ac_pt_CONFIG_NETSNMP+:} false; then :
+if test "${ac_cv_path_ac_pt_CONFIG_NETSNMP+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   case $ac_pt_CONFIG_NETSNMP in
@@ -21469,7 +21465,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
     ac_cv_path_ac_pt_CONFIG_NETSNMP="$as_dir/$ac_word$ac_exec_ext"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -21577,7 +21573,7 @@ if test "x${PBX_NEWT}" != "x1" -a "${USE_NEWT}" != "no"; then
       as_ac_Lib=`$as_echo "ac_cv_lib_newt_${pbxfuncname}" | $as_tr_sh`
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${pbxfuncname} in -lnewt" >&5
 $as_echo_n "checking for ${pbxfuncname} in -lnewt... " >&6; }
-if eval \${$as_ac_Lib+:} false; then :
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -21612,7 +21608,8 @@ fi
 eval ac_res=\$$as_ac_Lib
 	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
 $as_echo "$ac_res" >&6; }
-if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
   AST_NEWT_FOUND=yes
 else
   AST_NEWT_FOUND=no
@@ -21635,7 +21632,7 @@ fi
          ast_ext_lib_check_saved_CPPFLAGS="${CPPFLAGS}"
          CPPFLAGS="${CPPFLAGS} ${NEWT_INCLUDE}"
          ac_fn_c_check_header_mongrel "$LINENO" "newt.h" "ac_cv_header_newt_h" "$ac_includes_default"
-if test "x$ac_cv_header_newt_h" = xyes; then :
+if test "x$ac_cv_header_newt_h" = x""yes; then :
   NEWT_HEADER_FOUND=1
 else
   NEWT_HEADER_FOUND=0
@@ -21682,7 +21679,7 @@ if test "x${PBX_UNIXODBC}" != "x1" -a "${USE_UNIXODBC}" != "no"; then
       as_ac_Lib=`$as_echo "ac_cv_lib_odbc_${pbxfuncname}" | $as_tr_sh`
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${pbxfuncname} in -lodbc" >&5
 $as_echo_n "checking for ${pbxfuncname} in -lodbc... " >&6; }
-if eval \${$as_ac_Lib+:} false; then :
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -21717,7 +21714,8 @@ fi
 eval ac_res=\$$as_ac_Lib
 	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
 $as_echo "$ac_res" >&6; }
-if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
   AST_UNIXODBC_FOUND=yes
 else
   AST_UNIXODBC_FOUND=no
@@ -21740,7 +21738,7 @@ fi
          ast_ext_lib_check_saved_CPPFLAGS="${CPPFLAGS}"
          CPPFLAGS="${CPPFLAGS} ${UNIXODBC_INCLUDE}"
          ac_fn_c_check_header_mongrel "$LINENO" "sql.h" "ac_cv_header_sql_h" "$ac_includes_default"
-if test "x$ac_cv_header_sql_h" = xyes; then :
+if test "x$ac_cv_header_sql_h" = x""yes; then :
   UNIXODBC_HEADER_FOUND=1
 else
   UNIXODBC_HEADER_FOUND=0
@@ -21787,7 +21785,7 @@ if test "x${PBX_OGG}" != "x1" -a "${USE_OGG}" != "no"; then
       as_ac_Lib=`$as_echo "ac_cv_lib_ogg_${pbxfuncname}" | $as_tr_sh`
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${pbxfuncname} in -logg" >&5
 $as_echo_n "checking for ${pbxfuncname} in -logg... " >&6; }
-if eval \${$as_ac_Lib+:} false; then :
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -21822,7 +21820,8 @@ fi
 eval ac_res=\$$as_ac_Lib
 	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
 $as_echo "$ac_res" >&6; }
-if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
   AST_OGG_FOUND=yes
 else
   AST_OGG_FOUND=no
@@ -21845,7 +21844,7 @@ fi
          ast_ext_lib_check_saved_CPPFLAGS="${CPPFLAGS}"
          CPPFLAGS="${CPPFLAGS} ${OGG_INCLUDE}"
          ac_fn_c_check_header_mongrel "$LINENO" "" "ac_cv_header_" "$ac_includes_default"
-if test "x$ac_cv_header_" = xyes; then :
+if test "x$ac_cv_header_" = x""yes; then :
   OGG_HEADER_FOUND=1
 else
   OGG_HEADER_FOUND=0
@@ -21893,7 +21892,7 @@ if test "x${PBX_BKTR}" != "x1" -a "${USE_BKTR}" != "no"; then
       as_ac_Lib=`$as_echo "ac_cv_lib_execinfo_${pbxfuncname}" | $as_tr_sh`
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${pbxfuncname} in -lexecinfo" >&5
 $as_echo_n "checking for ${pbxfuncname} in -lexecinfo... " >&6; }
-if eval \${$as_ac_Lib+:} false; then :
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -21928,7 +21927,8 @@ fi
 eval ac_res=\$$as_ac_Lib
 	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
 $as_echo "$ac_res" >&6; }
-if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
   AST_BKTR_FOUND=yes
 else
   AST_BKTR_FOUND=no
@@ -21951,7 +21951,7 @@ fi
          ast_ext_lib_check_saved_CPPFLAGS="${CPPFLAGS}"
          CPPFLAGS="${CPPFLAGS} ${BKTR_INCLUDE}"
          ac_fn_c_check_header_mongrel "$LINENO" "execinfo.h" "ac_cv_header_execinfo_h" "$ac_includes_default"
-if test "x$ac_cv_header_execinfo_h" = xyes; then :
+if test "x$ac_cv_header_execinfo_h" = x""yes; then :
   BKTR_HEADER_FOUND=1
 else
   BKTR_HEADER_FOUND=0
@@ -21998,7 +21998,7 @@ if test "x${PBX_BKTR}" != "x1" -a "${USE_BKTR}" != "no"; then
       as_ac_Lib=`$as_echo "ac_cv_lib_c_${pbxfuncname}" | $as_tr_sh`
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${pbxfuncname} in -lc" >&5
 $as_echo_n "checking for ${pbxfuncname} in -lc... " >&6; }
-if eval \${$as_ac_Lib+:} false; then :
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -22033,7 +22033,8 @@ fi
 eval ac_res=\$$as_ac_Lib
 	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
 $as_echo "$ac_res" >&6; }
-if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
   AST_BKTR_FOUND=yes
 else
   AST_BKTR_FOUND=no
@@ -22056,7 +22057,7 @@ fi
          ast_ext_lib_check_saved_CPPFLAGS="${CPPFLAGS}"
          CPPFLAGS="${CPPFLAGS} ${BKTR_INCLUDE}"
          ac_fn_c_check_header_mongrel "$LINENO" "execinfo.h" "ac_cv_header_execinfo_h" "$ac_includes_default"
-if test "x$ac_cv_header_execinfo_h" = xyes; then :
+if test "x$ac_cv_header_execinfo_h" = x""yes; then :
   BKTR_HEADER_FOUND=1
 else
   BKTR_HEADER_FOUND=0
@@ -22103,7 +22104,7 @@ if test "x${PBX_BLUETOOTH}" != "x1" -a "${USE_BLUETOOTH}" != "no"; then
       as_ac_Lib=`$as_echo "ac_cv_lib_bluetooth_${pbxfuncname}" | $as_tr_sh`
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${pbxfuncname} in -lbluetooth" >&5
 $as_echo_n "checking for ${pbxfuncname} in -lbluetooth... " >&6; }
-if eval \${$as_ac_Lib+:} false; then :
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -22138,7 +22139,8 @@ fi
 eval ac_res=\$$as_ac_Lib
 	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
 $as_echo "$ac_res" >&6; }
-if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
   AST_BLUETOOTH_FOUND=yes
 else
   AST_BLUETOOTH_FOUND=no
@@ -22161,7 +22163,7 @@ fi
          ast_ext_lib_check_saved_CPPFLAGS="${CPPFLAGS}"
          CPPFLAGS="${CPPFLAGS} ${BLUETOOTH_INCLUDE}"
          ac_fn_c_check_header_mongrel "$LINENO" "bluetooth/bluetooth.h" "ac_cv_header_bluetooth_bluetooth_h" "$ac_includes_default"
-if test "x$ac_cv_header_bluetooth_bluetooth_h" = xyes; then :
+if test "x$ac_cv_header_bluetooth_bluetooth_h" = x""yes; then :
   BLUETOOTH_HEADER_FOUND=1
 else
   BLUETOOTH_HEADER_FOUND=0
@@ -22209,7 +22211,7 @@ if test "x${PBX_OSS}" != "x1" -a "${USE_OSS}" != "no"; then
       as_ac_Lib=`$as_echo "ac_cv_lib_ossaudio_${pbxfuncname}" | $as_tr_sh`
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${pbxfuncname} in -lossaudio" >&5
 $as_echo_n "checking for ${pbxfuncname} in -lossaudio... " >&6; }
-if eval \${$as_ac_Lib+:} false; then :
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -22244,7 +22246,8 @@ fi
 eval ac_res=\$$as_ac_Lib
 	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
 $as_echo "$ac_res" >&6; }
-if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
   AST_OSS_FOUND=yes
 else
   AST_OSS_FOUND=no
@@ -22267,7 +22270,7 @@ fi
          ast_ext_lib_check_saved_CPPFLAGS="${CPPFLAGS}"
          CPPFLAGS="${CPPFLAGS} ${OSS_INCLUDE}"
          ac_fn_c_check_header_mongrel "$LINENO" "linux/soundcard.h" "ac_cv_header_linux_soundcard_h" "$ac_includes_default"
-if test "x$ac_cv_header_linux_soundcard_h" = xyes; then :
+if test "x$ac_cv_header_linux_soundcard_h" = x""yes; then :
   OSS_HEADER_FOUND=1
 else
   OSS_HEADER_FOUND=0
@@ -22313,7 +22316,7 @@ if test "x${PBX_OSS}" != "x1" -a "${USE_OSS}" != "no"; then
       as_ac_Lib=`$as_echo "ac_cv_lib_ossaudio_${pbxfuncname}" | $as_tr_sh`
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${pbxfuncname} in -lossaudio" >&5
 $as_echo_n "checking for ${pbxfuncname} in -lossaudio... " >&6; }
-if eval \${$as_ac_Lib+:} false; then :
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -22348,7 +22351,8 @@ fi
 eval ac_res=\$$as_ac_Lib
 	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
 $as_echo "$ac_res" >&6; }
-if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
   AST_OSS_FOUND=yes
 else
   AST_OSS_FOUND=no
@@ -22371,7 +22375,7 @@ fi
          ast_ext_lib_check_saved_CPPFLAGS="${CPPFLAGS}"
          CPPFLAGS="${CPPFLAGS} ${OSS_INCLUDE}"
          ac_fn_c_check_header_mongrel "$LINENO" "sys/soundcard.h" "ac_cv_header_sys_soundcard_h" "$ac_includes_default"
-if test "x$ac_cv_header_sys_soundcard_h" = xyes; then :
+if test "x$ac_cv_header_sys_soundcard_h" = x""yes; then :
   OSS_HEADER_FOUND=1
 else
   OSS_HEADER_FOUND=0
@@ -22417,7 +22421,7 @@ if test "x${PBX_OSS}" != "x1" -a "${USE_OSS}" != "no"; then
       as_ac_Lib=`$as_echo "ac_cv_lib_ossaudio_${pbxfuncname}" | $as_tr_sh`
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${pbxfuncname} in -lossaudio" >&5
 $as_echo_n "checking for ${pbxfuncname} in -lossaudio... " >&6; }
-if eval \${$as_ac_Lib+:} false; then :
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -22452,7 +22456,8 @@ fi
 eval ac_res=\$$as_ac_Lib
 	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
 $as_echo "$ac_res" >&6; }
-if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
   AST_OSS_FOUND=yes
 else
   AST_OSS_FOUND=no
@@ -22475,7 +22480,7 @@ fi
          ast_ext_lib_check_saved_CPPFLAGS="${CPPFLAGS}"
          CPPFLAGS="${CPPFLAGS} ${OSS_INCLUDE}"
          ac_fn_c_check_header_mongrel "$LINENO" "soundcard.h" "ac_cv_header_soundcard_h" "$ac_includes_default"
-if test "x$ac_cv_header_soundcard_h" = xyes; then :
+if test "x$ac_cv_header_soundcard_h" = x""yes; then :
   OSS_HEADER_FOUND=1
 else
   OSS_HEADER_FOUND=0
@@ -22510,7 +22515,7 @@ if test "${USE_PGSQL}" != "no"; then
 set dummy ${ac_tool_prefix}pg_config; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_path_PG_CONFIG+:} false; then :
+if test "${ac_cv_path_PG_CONFIG+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   case $PG_CONFIG in
@@ -22524,7 +22529,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
     ac_cv_path_PG_CONFIG="$as_dir/$ac_word$ac_exec_ext"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -22553,7 +22558,7 @@ if test -z "$ac_cv_path_PG_CONFIG"; then
 set dummy pg_config; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_path_ac_pt_PG_CONFIG+:} false; then :
+if test "${ac_cv_path_ac_pt_PG_CONFIG+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   case $ac_pt_PG_CONFIG in
@@ -22567,7 +22572,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
     ac_cv_path_ac_pt_PG_CONFIG="$as_dir/$ac_word$ac_exec_ext"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -22622,7 +22627,7 @@ $as_echo "$as_me: *** including --without-postgres" >&6;}
 set dummy ${ac_tool_prefix}pg_config; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_path_PG_CONFIG+:} false; then :
+if test "${ac_cv_path_PG_CONFIG+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   case $PG_CONFIG in
@@ -22636,7 +22641,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
     ac_cv_path_PG_CONFIG="$as_dir/$ac_word$ac_exec_ext"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -22665,7 +22670,7 @@ if test -z "$ac_cv_path_PG_CONFIG"; then
 set dummy pg_config; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_path_ac_pt_PG_CONFIG+:} false; then :
+if test "${ac_cv_path_ac_pt_PG_CONFIG+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   case $ac_pt_PG_CONFIG in
@@ -22679,7 +22684,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
     ac_cv_path_ac_pt_PG_CONFIG="$as_dir/$ac_word$ac_exec_ext"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -22735,7 +22740,7 @@ $as_echo "$as_me: *** including --without-postgres" >&6;}
    else
       { $as_echo "$as_me:${as_lineno-$LINENO}: checking for PQescapeStringConn in -lpq" >&5
 $as_echo_n "checking for PQescapeStringConn in -lpq... " >&6; }
-if ${ac_cv_lib_pq_PQescapeStringConn+:} false; then :
+if test "${ac_cv_lib_pq_PQescapeStringConn+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -22769,7 +22774,7 @@ LIBS=$ac_check_lib_save_LIBS
 fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pq_PQescapeStringConn" >&5
 $as_echo "$ac_cv_lib_pq_PQescapeStringConn" >&6; }
-if test "x$ac_cv_lib_pq_PQescapeStringConn" = xyes; then :
+if test "x$ac_cv_lib_pq_PQescapeStringConn" = x""yes; then :
 
 cat >>confdefs.h <<_ACEOF
 #define HAVE_PGSQL 1
@@ -22838,46 +22843,46 @@ pkg_failed=no
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for PJPROJECT" >&5
 $as_echo_n "checking for PJPROJECT... " >&6; }
 
-if test -n "$PJPROJECT_CFLAGS"; then
-    pkg_cv_PJPROJECT_CFLAGS="$PJPROJECT_CFLAGS"
- elif test -n "$PKG_CONFIG"; then
-    if test -n "$PKG_CONFIG" && \
+if test -n "$PKG_CONFIG"; then
+    if test -n "$PJPROJECT_CFLAGS"; then
+        pkg_cv_PJPROJECT_CFLAGS="$PJPROJECT_CFLAGS"
+    else
+        if test -n "$PKG_CONFIG" && \
     { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libpjproject\""; } >&5
   ($PKG_CONFIG --exists --print-errors "libpjproject") 2>&5
   ac_status=$?
   $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }; then
   pkg_cv_PJPROJECT_CFLAGS=`$PKG_CONFIG --cflags "libpjproject" 2>/dev/null`
-		      test "x$?" != "x0" && pkg_failed=yes
 else
   pkg_failed=yes
 fi
- else
-    pkg_failed=untried
+    fi
+else
+	pkg_failed=untried
 fi
-if test -n "$PJPROJECT_LIBS"; then
-    pkg_cv_PJPROJECT_LIBS="$PJPROJECT_LIBS"
- elif test -n "$PKG_CONFIG"; then
-    if test -n "$PKG_CONFIG" && \
+if test -n "$PKG_CONFIG"; then
+    if test -n "$PJPROJECT_LIBS"; then
+        pkg_cv_PJPROJECT_LIBS="$PJPROJECT_LIBS"
+    else
+        if test -n "$PKG_CONFIG" && \
     { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libpjproject\""; } >&5
   ($PKG_CONFIG --exists --print-errors "libpjproject") 2>&5
   ac_status=$?
   $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }; then
   pkg_cv_PJPROJECT_LIBS=`$PKG_CONFIG --libs "libpjproject" 2>/dev/null`
-		      test "x$?" != "x0" && pkg_failed=yes
 else
   pkg_failed=yes
 fi
- else
-    pkg_failed=untried
+    fi
+else
+	pkg_failed=untried
 fi
 
 
 
 if test $pkg_failed = yes; then
-   	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
 
 if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
         _pkg_short_errors_supported=yes
@@ -22885,20 +22890,20 @@ else
         _pkg_short_errors_supported=no
 fi
         if test $_pkg_short_errors_supported = yes; then
-	        PJPROJECT_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libpjproject" 2>&1`
+	        PJPROJECT_PKG_ERRORS=`$PKG_CONFIG --short-errors --errors-to-stdout --print-errors "libpjproject"`
         else
-	        PJPROJECT_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libpjproject" 2>&1`
+	        PJPROJECT_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "libpjproject"`
         fi
 	# Put the nasty error message in config.log where it belongs
 	echo "$PJPROJECT_PKG_ERRORS" >&5
 
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
 
             PBX_PJPROJECT=0
 
 
 elif test $pkg_failed = untried; then
-     	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
 
             PBX_PJPROJECT=0
 
@@ -22940,7 +22945,7 @@ if test "x${PBX_POPT}" != "x1" -a "${USE_POPT}" != "no"; then
       as_ac_Lib=`$as_echo "ac_cv_lib_popt_${pbxfuncname}" | $as_tr_sh`
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${pbxfuncname} in -lpopt" >&5
 $as_echo_n "checking for ${pbxfuncname} in -lpopt... " >&6; }
-if eval \${$as_ac_Lib+:} false; then :
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -22975,7 +22980,8 @@ fi
 eval ac_res=\$$as_ac_Lib
 	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
 $as_echo "$ac_res" >&6; }
-if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
   AST_POPT_FOUND=yes
 else
   AST_POPT_FOUND=no
@@ -22998,7 +23004,7 @@ fi
          ast_ext_lib_check_saved_CPPFLAGS="${CPPFLAGS}"
          CPPFLAGS="${CPPFLAGS} ${POPT_INCLUDE}"
          ac_fn_c_check_header_mongrel "$LINENO" "popt.h" "ac_cv_header_popt_h" "$ac_includes_default"
-if test "x$ac_cv_header_popt_h" = xyes; then :
+if test "x$ac_cv_header_popt_h" = x""yes; then :
   POPT_HEADER_FOUND=1
 else
   POPT_HEADER_FOUND=0
@@ -23045,7 +23051,7 @@ if test "x${PBX_PORTAUDIO}" != "x1" -a "${USE_PORTAUDIO}" != "no"; then
       as_ac_Lib=`$as_echo "ac_cv_lib_portaudio_${pbxfuncname}" | $as_tr_sh`
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${pbxfuncname} in -lportaudio" >&5
 $as_echo_n "checking for ${pbxfuncname} in -lportaudio... " >&6; }
-if eval \${$as_ac_Lib+:} false; then :
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -23080,7 +23086,8 @@ fi
 eval ac_res=\$$as_ac_Lib
 	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
 $as_echo "$ac_res" >&6; }
-if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
   AST_PORTAUDIO_FOUND=yes
 else
   AST_PORTAUDIO_FOUND=no
@@ -23103,7 +23110,7 @@ fi
          ast_ext_lib_check_saved_CPPFLAGS="${CPPFLAGS}"
          CPPFLAGS="${CPPFLAGS} ${PORTAUDIO_INCLUDE}"
          ac_fn_c_check_header_mongrel "$LINENO" "portaudio.h" "ac_cv_header_portaudio_h" "$ac_includes_default"
-if test "x$ac_cv_header_portaudio_h" = xyes; then :
+if test "x$ac_cv_header_portaudio_h" = x""yes; then :
   PORTAUDIO_HEADER_FOUND=1
 else
   PORTAUDIO_HEADER_FOUND=0
@@ -23150,7 +23157,7 @@ if test "x${PBX_PRI}" != "x1" -a "${USE_PRI}" != "no"; then
       as_ac_Lib=`$as_echo "ac_cv_lib_pri_${pbxfuncname}" | $as_tr_sh`
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${pbxfuncname} in -lpri" >&5
 $as_echo_n "checking for ${pbxfuncname} in -lpri... " >&6; }
-if eval \${$as_ac_Lib+:} false; then :
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -23185,7 +23192,8 @@ fi
 eval ac_res=\$$as_ac_Lib
 	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
 $as_echo "$ac_res" >&6; }
-if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
   AST_PRI_FOUND=yes
 else
   AST_PRI_FOUND=no
@@ -23208,7 +23216,7 @@ fi
          ast_ext_lib_check_saved_CPPFLAGS="${CPPFLAGS}"
          CPPFLAGS="${CPPFLAGS} ${PRI_INCLUDE}"
          ac_fn_c_check_header_mongrel "$LINENO" "libpri.h" "ac_cv_header_libpri_h" "$ac_includes_default"
-if test "x$ac_cv_header_libpri_h" = xyes; then :
+if test "x$ac_cv_header_libpri_h" = x""yes; then :
   PRI_HEADER_FOUND=1
 else
   PRI_HEADER_FOUND=0
@@ -23254,7 +23262,7 @@ if test "x${PBX_PRI_L2_PERSISTENCE}" != "x1" -a "${USE_PRI_L2_PERSISTENCE}" != "
       as_ac_Lib=`$as_echo "ac_cv_lib_pri_${pbxfuncname}" | $as_tr_sh`
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${pbxfuncname} in -lpri" >&5
 $as_echo_n "checking for ${pbxfuncname} in -lpri... " >&6; }
-if eval \${$as_ac_Lib+:} false; then :
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -23289,7 +23297,8 @@ fi
 eval ac_res=\$$as_ac_Lib
 	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
 $as_echo "$ac_res" >&6; }
-if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
   AST_PRI_L2_PERSISTENCE_FOUND=yes
 else
   AST_PRI_L2_PERSISTENCE_FOUND=no
@@ -23312,7 +23321,7 @@ fi
          ast_ext_lib_check_saved_CPPFLAGS="${CPPFLAGS}"
          CPPFLAGS="${CPPFLAGS} ${PRI_L2_PERSISTENCE_INCLUDE}"
          ac_fn_c_check_header_mongrel "$LINENO" "libpri.h" "ac_cv_header_libpri_h" "$ac_includes_default"
-if test "x$ac_cv_header_libpri_h" = xyes; then :
+if test "x$ac_cv_header_libpri_h" = x""yes; then :
   PRI_L2_PERSISTENCE_HEADER_FOUND=1
 else
   PRI_L2_PERSISTENCE_HEADER_FOUND=0
@@ -23358,7 +23367,7 @@ if test "x${PBX_PRI_DATETIME_SEND}" != "x1" -a "${USE_PRI_DATETIME_SEND}" != "no
       as_ac_Lib=`$as_echo "ac_cv_lib_pri_${pbxfuncname}" | $as_tr_sh`
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${pbxfuncname} in -lpri" >&5
 $as_echo_n "checking for ${pbxfuncname} in -lpri... " >&6; }
-if eval \${$as_ac_Lib+:} false; then :
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -23393,7 +23402,8 @@ fi
 eval ac_res=\$$as_ac_Lib
 	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
 $as_echo "$ac_res" >&6; }
-if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
   AST_PRI_DATETIME_SEND_FOUND=yes
 else
   AST_PRI_DATETIME_SEND_FOUND=no
@@ -23416,7 +23426,7 @@ fi
          ast_ext_lib_check_saved_CPPFLAGS="${CPPFLAGS}"
          CPPFLAGS="${CPPFLAGS} ${PRI_DATETIME_SEND_INCLUDE}"
          ac_fn_c_check_header_mongrel "$LINENO" "libpri.h" "ac_cv_header_libpri_h" "$ac_includes_default"
-if test "x$ac_cv_header_libpri_h" = xyes; then :
+if test "x$ac_cv_header_libpri_h" = x""yes; then :
   PRI_DATETIME_SEND_HEADER_FOUND=1
 else
   PRI_DATETIME_SEND_HEADER_FOUND=0
@@ -23462,7 +23472,7 @@ if test "x${PBX_PRI_MWI_V2}" != "x1" -a "${USE_PRI_MWI_V2}" != "no"; then
       as_ac_Lib=`$as_echo "ac_cv_lib_pri_${pbxfuncname}" | $as_tr_sh`
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${pbxfuncname} in -lpri" >&5
 $as_echo_n "checking for ${pbxfuncname} in -lpri... " >&6; }
-if eval \${$as_ac_Lib+:} false; then :
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -23497,7 +23507,8 @@ fi
 eval ac_res=\$$as_ac_Lib
 	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
 $as_echo "$ac_res" >&6; }
-if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
   AST_PRI_MWI_V2_FOUND=yes
 else
   AST_PRI_MWI_V2_FOUND=no
@@ -23520,7 +23531,7 @@ fi
          ast_ext_lib_check_saved_CPPFLAGS="${CPPFLAGS}"
          CPPFLAGS="${CPPFLAGS} ${PRI_MWI_V2_INCLUDE}"
          ac_fn_c_check_header_mongrel "$LINENO" "libpri.h" "ac_cv_header_libpri_h" "$ac_includes_default"
-if test "x$ac_cv_header_libpri_h" = xyes; then :
+if test "x$ac_cv_header_libpri_h" = x""yes; then :
   PRI_MWI_V2_HEADER_FOUND=1
 else
   PRI_MWI_V2_HEADER_FOUND=0
@@ -23566,7 +23577,7 @@ if test "x${PBX_PRI_DISPLAY_TEXT}" != "x1" -a "${USE_PRI_DISPLAY_TEXT}" != "no";
       as_ac_Lib=`$as_echo "ac_cv_lib_pri_${pbxfuncname}" | $as_tr_sh`
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${pbxfuncname} in -lpri" >&5
 $as_echo_n "checking for ${pbxfuncname} in -lpri... " >&6; }
-if eval \${$as_ac_Lib+:} false; then :
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -23601,7 +23612,8 @@ fi
 eval ac_res=\$$as_ac_Lib
 	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
 $as_echo "$ac_res" >&6; }
-if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
   AST_PRI_DISPLAY_TEXT_FOUND=yes
 else
   AST_PRI_DISPLAY_TEXT_FOUND=no
@@ -23624,7 +23636,7 @@ fi
          ast_ext_lib_check_saved_CPPFLAGS="${CPPFLAGS}"
          CPPFLAGS="${CPPFLAGS} ${PRI_DISPLAY_TEXT_INCLUDE}"
          ac_fn_c_check_header_mongrel "$LINENO" "libpri.h" "ac_cv_header_libpri_h" "$ac_includes_default"
-if test "x$ac_cv_header_libpri_h" = xyes; then :
+if test "x$ac_cv_header_libpri_h" = x""yes; then :
   PRI_DISPLAY_TEXT_HEADER_FOUND=1
 else
   PRI_DISPLAY_TEXT_HEADER_FOUND=0
@@ -23670,7 +23682,7 @@ if test "x${PBX_PRI_MWI}" != "x1" -a "${USE_PRI_MWI}" != "no"; then
       as_ac_Lib=`$as_echo "ac_cv_lib_pri_${pbxfuncname}" | $as_tr_sh`
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${pbxfuncname} in -lpri" >&5
 $as_echo_n "checking for ${pbxfuncname} in -lpri... " >&6; }
-if eval \${$as_ac_Lib+:} false; then :
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -23705,7 +23717,8 @@ fi
 eval ac_res=\$$as_ac_Lib
 	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
 $as_echo "$ac_res" >&6; }
-if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
   AST_PRI_MWI_FOUND=yes
 else
   AST_PRI_MWI_FOUND=no
@@ -23728,7 +23741,7 @@ fi
          ast_ext_lib_check_saved_CPPFLAGS="${CPPFLAGS}"
          CPPFLAGS="${CPPFLAGS} ${PRI_MWI_INCLUDE}"
          ac_fn_c_check_header_mongrel "$LINENO" "libpri.h" "ac_cv_header_libpri_h" "$ac_includes_default"
-if test "x$ac_cv_header_libpri_h" = xyes; then :
+if test "x$ac_cv_header_libpri_h" = x""yes; then :
   PRI_MWI_HEADER_FOUND=1
 else
   PRI_MWI_HEADER_FOUND=0
@@ -23774,7 +23787,7 @@ if test "x${PBX_PRI_MCID}" != "x1" -a "${USE_PRI_MCID}" != "no"; then
       as_ac_Lib=`$as_echo "ac_cv_lib_pri_${pbxfuncname}" | $as_tr_sh`
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${pbxfuncname} in -lpri" >&5
 $as_echo_n "checking for ${pbxfuncname} in -lpri... " >&6; }
-if eval \${$as_ac_Lib+:} false; then :
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -23809,7 +23822,8 @@ fi
 eval ac_res=\$$as_ac_Lib
 	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
 $as_echo "$ac_res" >&6; }
-if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
   AST_PRI_MCID_FOUND=yes
 else
   AST_PRI_MCID_FOUND=no
@@ -23832,7 +23846,7 @@ fi
          ast_ext_lib_check_saved_CPPFLAGS="${CPPFLAGS}"
          CPPFLAGS="${CPPFLAGS} ${PRI_MCID_INCLUDE}"
          ac_fn_c_check_header_mongrel "$LINENO" "libpri.h" "ac_cv_header_libpri_h" "$ac_includes_default"
-if test "x$ac_cv_header_libpri_h" = xyes; then :
+if test "x$ac_cv_header_libpri_h" = x""yes; then :
   PRI_MCID_HEADER_FOUND=1
 else
   PRI_MCID_HEADER_FOUND=0
@@ -23878,7 +23892,7 @@ if test "x${PBX_PRI_CALL_WAITING}" != "x1" -a "${USE_PRI_CALL_WAITING}" != "no";
       as_ac_Lib=`$as_echo "ac_cv_lib_pri_${pbxfuncname}" | $as_tr_sh`
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${pbxfuncname} in -lpri" >&5
 $as_echo_n "checking for ${pbxfuncname} in -lpri... " >&6; }
-if eval \${$as_ac_Lib+:} false; then :
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -23913,7 +23927,8 @@ fi
 eval ac_res=\$$as_ac_Lib
 	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
 $as_echo "$ac_res" >&6; }
-if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
   AST_PRI_CALL_WAITING_FOUND=yes
 else
   AST_PRI_CALL_WAITING_FOUND=no
@@ -23936,7 +23951,7 @@ fi
          ast_ext_lib_check_saved_CPPFLAGS="${CPPFLAGS}"
          CPPFLAGS="${CPPFLAGS} ${PRI_CALL_WAITING_INCLUDE}"
          ac_fn_c_check_header_mongrel "$LINENO" "libpri.h" "ac_cv_header_libpri_h" "$ac_includes_default"
-if test "x$ac_cv_header_libpri_h" = xyes; then :
+if test "x$ac_cv_header_libpri_h" = x""yes; then :
   PRI_CALL_WAITING_HEADER_FOUND=1
 else
   PRI_CALL_WAITING_HEADER_FOUND=0
@@ -23982,7 +23997,7 @@ if test "x${PBX_PRI_AOC_EVENTS}" != "x1" -a "${USE_PRI_AOC_EVENTS}" != "no"; the
       as_ac_Lib=`$as_echo "ac_cv_lib_pri_${pbxfuncname}" | $as_tr_sh`
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${pbxfuncname} in -lpri" >&5
 $as_echo_n "checking for ${pbxfuncname} in -lpri... " >&6; }
-if eval \${$as_ac_Lib+:} false; then :
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -24017,7 +24032,8 @@ fi
 eval ac_res=\$$as_ac_Lib
 	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
 $as_echo "$ac_res" >&6; }
-if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
   AST_PRI_AOC_EVENTS_FOUND=yes
 else
   AST_PRI_AOC_EVENTS_FOUND=no
@@ -24040,7 +24056,7 @@ fi
          ast_ext_lib_check_saved_CPPFLAGS="${CPPFLAGS}"
          CPPFLAGS="${CPPFLAGS} ${PRI_AOC_EVENTS_INCLUDE}"
          ac_fn_c_check_header_mongrel "$LINENO" "libpri.h" "ac_cv_header_libpri_h" "$ac_includes_default"
-if test "x$ac_cv_header_libpri_h" = xyes; then :
+if test "x$ac_cv_header_libpri_h" = x""yes; then :
   PRI_AOC_EVENTS_HEADER_FOUND=1
 else
   PRI_AOC_EVENTS_HEADER_FOUND=0
@@ -24086,7 +24102,7 @@ if test "x${PBX_PRI_TRANSFER}" != "x1" -a "${USE_PRI_TRANSFER}" != "no"; then
       as_ac_Lib=`$as_echo "ac_cv_lib_pri_${pbxfuncname}" | $as_tr_sh`
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${pbxfuncname} in -lpri" >&5
 $as_echo_n "checking for ${pbxfuncname} in -lpri... " >&6; }
-if eval \${$as_ac_Lib+:} false; then :
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -24121,7 +24137,8 @@ fi
 eval ac_res=\$$as_ac_Lib
 	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
 $as_echo "$ac_res" >&6; }
-if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
   AST_PRI_TRANSFER_FOUND=yes
 else
   AST_PRI_TRANSFER_FOUND=no
@@ -24144,7 +24161,7 @@ fi
          ast_ext_lib_check_saved_CPPFLAGS="${CPPFLAGS}"
          CPPFLAGS="${CPPFLAGS} ${PRI_TRANSFER_INCLUDE}"
          ac_fn_c_check_header_mongrel "$LINENO" "libpri.h" "ac_cv_header_libpri_h" "$ac_includes_default"
-if test "x$ac_cv_header_libpri_h" = xyes; then :
+if test "x$ac_cv_header_libpri_h" = x""yes; then :
   PRI_TRANSFER_HEADER_FOUND=1
 else
   PRI_TRANSFER_HEADER_FOUND=0
@@ -24190,7 +24207,7 @@ if test "x${PBX_PRI_CCSS}" != "x1" -a "${USE_PRI_CCSS}" != "no"; then
       as_ac_Lib=`$as_echo "ac_cv_lib_pri_${pbxfuncname}" | $as_tr_sh`
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${pbxfuncname} in -lpri" >&5
 $as_echo_n "checking for ${pbxfuncname} in -lpri... " >&6; }
-if eval \${$as_ac_Lib+:} false; then :
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -24225,7 +24242,8 @@ fi
 eval ac_res=\$$as_ac_Lib
 	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
 $as_echo "$ac_res" >&6; }
-if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
   AST_PRI_CCSS_FOUND=yes
 else
   AST_PRI_CCSS_FOUND=no
@@ -24248,7 +24266,7 @@ fi
          ast_ext_lib_check_saved_CPPFLAGS="${CPPFLAGS}"
          CPPFLAGS="${CPPFLAGS} ${PRI_CCSS_INCLUDE}"
          ac_fn_c_check_header_mongrel "$LINENO" "libpri.h" "ac_cv_header_libpri_h" "$ac_includes_default"
-if test "x$ac_cv_header_libpri_h" = xyes; then :
+if test "x$ac_cv_header_libpri_h" = x""yes; then :
   PRI_CCSS_HEADER_FOUND=1
 else
   PRI_CCSS_HEADER_FOUND=0
@@ -24294,7 +24312,7 @@ if test "x${PBX_PRI_HANGUP_FIX}" != "x1" -a "${USE_PRI_HANGUP_FIX}" != "no"; the
       as_ac_Lib=`$as_echo "ac_cv_lib_pri_${pbxfuncname}" | $as_tr_sh`
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${pbxfuncname} in -lpri" >&5
 $as_echo_n "checking for ${pbxfuncname} in -lpri... " >&6; }
-if eval \${$as_ac_Lib+:} false; then :
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -24329,7 +24347,8 @@ fi
 eval ac_res=\$$as_ac_Lib
 	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
 $as_echo "$ac_res" >&6; }
-if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
   AST_PRI_HANGUP_FIX_FOUND=yes
 else
   AST_PRI_HANGUP_FIX_FOUND=no
@@ -24352,7 +24371,7 @@ fi
          ast_ext_lib_check_saved_CPPFLAGS="${CPPFLAGS}"
          CPPFLAGS="${CPPFLAGS} ${PRI_HANGUP_FIX_INCLUDE}"
          ac_fn_c_check_header_mongrel "$LINENO" "libpri.h" "ac_cv_header_libpri_h" "$ac_includes_default"
-if test "x$ac_cv_header_libpri_h" = xyes; then :
+if test "x$ac_cv_header_libpri_h" = x""yes; then :
   PRI_HANGUP_FIX_HEADER_FOUND=1
 else
   PRI_HANGUP_FIX_HEADER_FOUND=0
@@ -24398,7 +24417,7 @@ if test "x${PBX_PRI_SUBADDR}" != "x1" -a "${USE_PRI_SUBADDR}" != "no"; then
       as_ac_Lib=`$as_echo "ac_cv_lib_pri_${pbxfuncname}" | $as_tr_sh`
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${pbxfuncname} in -lpri" >&5
 $as_echo_n "checking for ${pbxfuncname} in -lpri... " >&6; }
-if eval \${$as_ac_Lib+:} false; then :
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -24433,7 +24452,8 @@ fi
 eval ac_res=\$$as_ac_Lib
 	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
 $as_echo "$ac_res" >&6; }
-if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
   AST_PRI_SUBADDR_FOUND=yes
 else
   AST_PRI_SUBADDR_FOUND=no
@@ -24456,7 +24476,7 @@ fi
          ast_ext_lib_check_saved_CPPFLAGS="${CPPFLAGS}"
          CPPFLAGS="${CPPFLAGS} ${PRI_SUBADDR_INCLUDE}"
          ac_fn_c_check_header_mongrel "$LINENO" "libpri.h" "ac_cv_header_libpri_h" "$ac_includes_default"
-if test "x$ac_cv_header_libpri_h" = xyes; then :
+if test "x$ac_cv_header_libpri_h" = x""yes; then :
   PRI_SUBADDR_HEADER_FOUND=1
 else
   PRI_SUBADDR_HEADER_FOUND=0
@@ -24502,7 +24522,7 @@ if test "x${PBX_PRI_CALL_HOLD}" != "x1" -a "${USE_PRI_CALL_HOLD}" != "no"; then
       as_ac_Lib=`$as_echo "ac_cv_lib_pri_${pbxfuncname}" | $as_tr_sh`
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${pbxfuncname} in -lpri" >&5
 $as_echo_n "checking for ${pbxfuncname} in -lpri... " >&6; }
-if eval \${$as_ac_Lib+:} false; then :
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -24537,7 +24557,8 @@ fi
 eval ac_res=\$$as_ac_Lib
 	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
 $as_echo "$ac_res" >&6; }
-if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
   AST_PRI_CALL_HOLD_FOUND=yes
 else
   AST_PRI_CALL_HOLD_FOUND=no
@@ -24560,7 +24581,7 @@ fi
          ast_ext_lib_check_saved_CPPFLAGS="${CPPFLAGS}"
          CPPFLAGS="${CPPFLAGS} ${PRI_CALL_HOLD_INCLUDE}"
          ac_fn_c_check_header_mongrel "$LINENO" "libpri.h" "ac_cv_header_libpri_h" "$ac_includes_default"
-if test "x$ac_cv_header_libpri_h" = xyes; then :
+if test "x$ac_cv_header_libpri_h" = x""yes; then :
   PRI_CALL_HOLD_HEADER_FOUND=1
 else
   PRI_CALL_HOLD_HEADER_FOUND=0
@@ -24606,7 +24627,7 @@ if test "x${PBX_PRI_CALL_REROUTING}" != "x1" -a "${USE_PRI_CALL_REROUTING}" != "
       as_ac_Lib=`$as_echo "ac_cv_lib_pri_${pbxfuncname}" | $as_tr_sh`
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${pbxfuncname} in -lpri" >&5
 $as_echo_n "checking for ${pbxfuncname} in -lpri... " >&6; }
-if eval \${$as_ac_Lib+:} false; then :
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -24641,7 +24662,8 @@ fi
 eval ac_res=\$$as_ac_Lib
 	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
 $as_echo "$ac_res" >&6; }
-if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
   AST_PRI_CALL_REROUTING_FOUND=yes
 else
   AST_PRI_CALL_REROUTING_FOUND=no
@@ -24664,7 +24686,7 @@ fi
          ast_ext_lib_check_saved_CPPFLAGS="${CPPFLAGS}"
          CPPFLAGS="${CPPFLAGS} ${PRI_CALL_REROUTING_INCLUDE}"
          ac_fn_c_check_header_mongrel "$LINENO" "libpri.h" "ac_cv_header_libpri_h" "$ac_includes_default"
-if test "x$ac_cv_header_libpri_h" = xyes; then :
+if test "x$ac_cv_header_libpri_h" = x""yes; then :
   PRI_CALL_REROUTING_HEADER_FOUND=1
 else
   PRI_CALL_REROUTING_HEADER_FOUND=0
@@ -24710,7 +24732,7 @@ if test "x${PBX_PRI_SETUP_KEYPAD}" != "x1" -a "${USE_PRI_SETUP_KEYPAD}" != "no";
       as_ac_Lib=`$as_echo "ac_cv_lib_pri_${pbxfuncname}" | $as_tr_sh`
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${pbxfuncname} in -lpri" >&5
 $as_echo_n "checking for ${pbxfuncname} in -lpri... " >&6; }
-if eval \${$as_ac_Lib+:} false; then :
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -24745,7 +24767,8 @@ fi
 eval ac_res=\$$as_ac_Lib
 	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
 $as_echo "$ac_res" >&6; }
-if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
   AST_PRI_SETUP_KEYPAD_FOUND=yes
 else
   AST_PRI_SETUP_KEYPAD_FOUND=no
@@ -24768,7 +24791,7 @@ fi
          ast_ext_lib_check_saved_CPPFLAGS="${CPPFLAGS}"
          CPPFLAGS="${CPPFLAGS} ${PRI_SETUP_KEYPAD_INCLUDE}"
          ac_fn_c_check_header_mongrel "$LINENO" "libpri.h" "ac_cv_header_libpri_h" "$ac_includes_default"
-if test "x$ac_cv_header_libpri_h" = xyes; then :
+if test "x$ac_cv_header_libpri_h" = x""yes; then :
   PRI_SETUP_KEYPAD_HEADER_FOUND=1
 else
   PRI_SETUP_KEYPAD_HEADER_FOUND=0
@@ -24818,7 +24841,7 @@ if test "x${PBX_PRI_PROG_W_CAUSE}" != "x1" -a "${USE_PRI_PROG_W_CAUSE}" != "no";
       as_ac_Lib=`$as_echo "ac_cv_lib_pri_${pbxfuncname}" | $as_tr_sh`
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${pbxfuncname} in -lpri" >&5
 $as_echo_n "checking for ${pbxfuncname} in -lpri... " >&6; }
-if eval \${$as_ac_Lib+:} false; then :
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -24853,7 +24876,8 @@ fi
 eval ac_res=\$$as_ac_Lib
 	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
 $as_echo "$ac_res" >&6; }
-if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
   AST_PRI_PROG_W_CAUSE_FOUND=yes
 else
   AST_PRI_PROG_W_CAUSE_FOUND=no
@@ -24876,7 +24900,7 @@ fi
          ast_ext_lib_check_saved_CPPFLAGS="${CPPFLAGS}"
          CPPFLAGS="${CPPFLAGS} ${PRI_PROG_W_CAUSE_INCLUDE}"
          ac_fn_c_check_header_mongrel "$LINENO" "libpri.h" "ac_cv_header_libpri_h" "$ac_includes_default"
-if test "x$ac_cv_header_libpri_h" = xyes; then :
+if test "x$ac_cv_header_libpri_h" = x""yes; then :
   PRI_PROG_W_CAUSE_HEADER_FOUND=1
 else
   PRI_PROG_W_CAUSE_HEADER_FOUND=0
@@ -24922,7 +24946,7 @@ if test "x${PBX_PRI_INBANDDISCONNECT}" != "x1" -a "${USE_PRI_INBANDDISCONNECT}"
       as_ac_Lib=`$as_echo "ac_cv_lib_pri_${pbxfuncname}" | $as_tr_sh`
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${pbxfuncname} in -lpri" >&5
 $as_echo_n "checking for ${pbxfuncname} in -lpri... " >&6; }
-if eval \${$as_ac_Lib+:} false; then :
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -24957,7 +24981,8 @@ fi
 eval ac_res=\$$as_ac_Lib
 	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
 $as_echo "$ac_res" >&6; }
-if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
   AST_PRI_INBANDDISCONNECT_FOUND=yes
 else
   AST_PRI_INBANDDISCONNECT_FOUND=no
@@ -24980,7 +25005,7 @@ fi
          ast_ext_lib_check_saved_CPPFLAGS="${CPPFLAGS}"
          CPPFLAGS="${CPPFLAGS} ${PRI_INBANDDISCONNECT_INCLUDE}"
          ac_fn_c_check_header_mongrel "$LINENO" "libpri.h" "ac_cv_header_libpri_h" "$ac_includes_default"
-if test "x$ac_cv_header_libpri_h" = xyes; then :
+if test "x$ac_cv_header_libpri_h" = x""yes; then :
   PRI_INBANDDISCONNECT_HEADER_FOUND=1
 else
   PRI_INBANDDISCONNECT_HEADER_FOUND=0
@@ -25026,7 +25051,7 @@ if test "x${PBX_PRI_SERVICE_MESSAGES}" != "x1" -a "${USE_PRI_SERVICE_MESSAGES}"
       as_ac_Lib=`$as_echo "ac_cv_lib_pri_${pbxfuncname}" | $as_tr_sh`
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${pbxfuncname} in -lpri" >&5
 $as_echo_n "checking for ${pbxfuncname} in -lpri... " >&6; }
-if eval \${$as_ac_Lib+:} false; then :
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -25061,7 +25086,8 @@ fi
 eval ac_res=\$$as_ac_Lib
 	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
 $as_echo "$ac_res" >&6; }
-if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
   AST_PRI_SERVICE_MESSAGES_FOUND=yes
 else
   AST_PRI_SERVICE_MESSAGES_FOUND=no
@@ -25084,7 +25110,7 @@ fi
          ast_ext_lib_check_saved_CPPFLAGS="${CPPFLAGS}"
          CPPFLAGS="${CPPFLAGS} ${PRI_SERVICE_MESSAGES_INCLUDE}"
          ac_fn_c_check_header_mongrel "$LINENO" "libpri.h" "ac_cv_header_libpri_h" "$ac_includes_default"
-if test "x$ac_cv_header_libpri_h" = xyes; then :
+if test "x$ac_cv_header_libpri_h" = x""yes; then :
   PRI_SERVICE_MESSAGES_HEADER_FOUND=1
 else
   PRI_SERVICE_MESSAGES_HEADER_FOUND=0
@@ -25130,7 +25156,7 @@ if test "x${PBX_PRI_REVERSE_CHARGE}" != "x1" -a "${USE_PRI_REVERSE_CHARGE}" != "
       as_ac_Lib=`$as_echo "ac_cv_lib_pri_${pbxfuncname}" | $as_tr_sh`
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${pbxfuncname} in -lpri" >&5
 $as_echo_n "checking for ${pbxfuncname} in -lpri... " >&6; }
-if eval \${$as_ac_Lib+:} false; then :
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -25165,7 +25191,8 @@ fi
 eval ac_res=\$$as_ac_Lib
 	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
 $as_echo "$ac_res" >&6; }
-if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
   AST_PRI_REVERSE_CHARGE_FOUND=yes
 else
   AST_PRI_REVERSE_CHARGE_FOUND=no
@@ -25188,7 +25215,7 @@ fi
          ast_ext_lib_check_saved_CPPFLAGS="${CPPFLAGS}"
          CPPFLAGS="${CPPFLAGS} ${PRI_REVERSE_CHARGE_INCLUDE}"
          ac_fn_c_check_header_mongrel "$LINENO" "libpri.h" "ac_cv_header_libpri_h" "$ac_includes_default"
-if test "x$ac_cv_header_libpri_h" = xyes; then :
+if test "x$ac_cv_header_libpri_h" = x""yes; then :
   PRI_REVERSE_CHARGE_HEADER_FOUND=1
 else
   PRI_REVERSE_CHARGE_HEADER_FOUND=0
@@ -25236,7 +25263,7 @@ if test "x${PBX_RESAMPLE}" != "x1" -a "${USE_RESAMPLE}" != "no"; then
       as_ac_Lib=`$as_echo "ac_cv_lib_resample_${pbxfuncname}" | $as_tr_sh`
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${pbxfuncname} in -lresample" >&5
 $as_echo_n "checking for ${pbxfuncname} in -lresample... " >&6; }
-if eval \${$as_ac_Lib+:} false; then :
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -25271,7 +25298,8 @@ fi
 eval ac_res=\$$as_ac_Lib
 	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
 $as_echo "$ac_res" >&6; }
-if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
   AST_RESAMPLE_FOUND=yes
 else
   AST_RESAMPLE_FOUND=no
@@ -25294,7 +25322,7 @@ fi
          ast_ext_lib_check_saved_CPPFLAGS="${CPPFLAGS}"
          CPPFLAGS="${CPPFLAGS} ${RESAMPLE_INCLUDE}"
          ac_fn_c_check_header_mongrel "$LINENO" "libresample.h" "ac_cv_header_libresample_h" "$ac_includes_default"
-if test "x$ac_cv_header_libresample_h" = xyes; then :
+if test "x$ac_cv_header_libresample_h" = x""yes; then :
   RESAMPLE_HEADER_FOUND=1
 else
   RESAMPLE_HEADER_FOUND=0
@@ -25403,7 +25431,7 @@ if test "x${PBX_SPANDSP}" != "x1" -a "${USE_SPANDSP}" != "no"; then
       as_ac_Lib=`$as_echo "ac_cv_lib_spandsp_${pbxfuncname}" | $as_tr_sh`
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${pbxfuncname} in -lspandsp" >&5
 $as_echo_n "checking for ${pbxfuncname} in -lspandsp... " >&6; }
-if eval \${$as_ac_Lib+:} false; then :
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -25438,7 +25466,8 @@ fi
 eval ac_res=\$$as_ac_Lib
 	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
 $as_echo "$ac_res" >&6; }
-if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
   AST_SPANDSP_FOUND=yes
 else
   AST_SPANDSP_FOUND=no
@@ -25461,7 +25490,7 @@ fi
          ast_ext_lib_check_saved_CPPFLAGS="${CPPFLAGS}"
          CPPFLAGS="${CPPFLAGS} ${SPANDSP_INCLUDE}"
          ac_fn_c_check_header_mongrel "$LINENO" "spandsp.h" "ac_cv_header_spandsp_h" "$ac_includes_default"
-if test "x$ac_cv_header_spandsp_h" = xyes; then :
+if test "x$ac_cv_header_spandsp_h" = x""yes; then :
   SPANDSP_HEADER_FOUND=1
 else
   SPANDSP_HEADER_FOUND=0
@@ -25512,7 +25541,7 @@ if test "x${PBX_SPANDSP}" != "x1" -a "${USE_SPANDSP}" != "no"; then
       as_ac_Lib=`$as_echo "ac_cv_lib_spandsp_${pbxfuncname}" | $as_tr_sh`
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${pbxfuncname} in -lspandsp" >&5
 $as_echo_n "checking for ${pbxfuncname} in -lspandsp... " >&6; }
-if eval \${$as_ac_Lib+:} false; then :
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -25547,7 +25576,8 @@ fi
 eval ac_res=\$$as_ac_Lib
 	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
 $as_echo "$ac_res" >&6; }
-if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
   AST_SPANDSP_FOUND=yes
 else
   AST_SPANDSP_FOUND=no
@@ -25570,7 +25600,7 @@ fi
          ast_ext_lib_check_saved_CPPFLAGS="${CPPFLAGS}"
          CPPFLAGS="${CPPFLAGS} ${SPANDSP_INCLUDE}"
          ac_fn_c_check_header_mongrel "$LINENO" "spandsp.h" "ac_cv_header_spandsp_h" "$ac_includes_default"
-if test "x$ac_cv_header_spandsp_h" = xyes; then :
+if test "x$ac_cv_header_spandsp_h" = x""yes; then :
   SPANDSP_HEADER_FOUND=1
 else
   SPANDSP_HEADER_FOUND=0
@@ -25619,7 +25649,7 @@ if test "x${PBX_SS7}" != "x1" -a "${USE_SS7}" != "no"; then
       as_ac_Lib=`$as_echo "ac_cv_lib_ss7_${pbxfuncname}" | $as_tr_sh`
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${pbxfuncname} in -lss7" >&5
 $as_echo_n "checking for ${pbxfuncname} in -lss7... " >&6; }
-if eval \${$as_ac_Lib+:} false; then :
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -25654,7 +25684,8 @@ fi
 eval ac_res=\$$as_ac_Lib
 	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
 $as_echo "$ac_res" >&6; }
-if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
   AST_SS7_FOUND=yes
 else
   AST_SS7_FOUND=no
@@ -25677,7 +25708,7 @@ fi
          ast_ext_lib_check_saved_CPPFLAGS="${CPPFLAGS}"
          CPPFLAGS="${CPPFLAGS} ${SS7_INCLUDE}"
          ac_fn_c_check_header_mongrel "$LINENO" "libss7.h" "ac_cv_header_libss7_h" "$ac_includes_default"
-if test "x$ac_cv_header_libss7_h" = xyes; then :
+if test "x$ac_cv_header_libss7_h" = x""yes; then :
   SS7_HEADER_FOUND=1
 else
   SS7_HEADER_FOUND=0
@@ -25724,7 +25755,7 @@ if test "x${PBX_OPENR2}" != "x1" -a "${USE_OPENR2}" != "no"; then
       as_ac_Lib=`$as_echo "ac_cv_lib_openr2_${pbxfuncname}" | $as_tr_sh`
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${pbxfuncname} in -lopenr2" >&5
 $as_echo_n "checking for ${pbxfuncname} in -lopenr2... " >&6; }
-if eval \${$as_ac_Lib+:} false; then :
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -25759,7 +25790,8 @@ fi
 eval ac_res=\$$as_ac_Lib
 	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
 $as_echo "$ac_res" >&6; }
-if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
   AST_OPENR2_FOUND=yes
 else
   AST_OPENR2_FOUND=no
@@ -25782,7 +25814,7 @@ fi
          ast_ext_lib_check_saved_CPPFLAGS="${CPPFLAGS}"
          CPPFLAGS="${CPPFLAGS} ${OPENR2_INCLUDE}"
          ac_fn_c_check_header_mongrel "$LINENO" "openr2.h" "ac_cv_header_openr2_h" "$ac_includes_default"
-if test "x$ac_cv_header_openr2_h" = xyes; then :
+if test "x$ac_cv_header_openr2_h" = x""yes; then :
   OPENR2_HEADER_FOUND=1
 else
   OPENR2_HEADER_FOUND=0
@@ -25827,7 +25859,8 @@ ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
 if test "${PWLIBDIR:-unset}" != "unset" ; then
   as_ac_Header=`$as_echo "ac_cv_header_${PWLIBDIR}/version.h" | $as_tr_sh`
 ac_fn_cxx_check_header_mongrel "$LINENO" "${PWLIBDIR}/version.h" "$as_ac_Header" "$ac_includes_default"
-if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+eval as_val=\$$as_ac_Header
+   if test "x$as_val" = x""yes; then :
   HAS_PWLIB=1
 fi
 
@@ -25837,7 +25870,8 @@ if test "${HAS_PWLIB:-unset}" = "unset" ; then
   if test "${OPENH323DIR:-unset}" != "unset"; then
     as_ac_Header=`$as_echo "ac_cv_header_${OPENH323DIR}/../pwlib/version.h" | $as_tr_sh`
 ac_fn_cxx_check_header_mongrel "$LINENO" "${OPENH323DIR}/../pwlib/version.h" "$as_ac_Header" "$ac_includes_default"
-if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+eval as_val=\$$as_ac_Header
+   if test "x$as_val" = x""yes; then :
   HAS_PWLIB=1
 fi
 
@@ -25848,7 +25882,8 @@ fi
   else
     as_ac_Header=`$as_echo "ac_cv_header_${HOME}/pwlib/include/ptlib.h" | $as_tr_sh`
 ac_fn_cxx_check_header_mongrel "$LINENO" "${HOME}/pwlib/include/ptlib.h" "$as_ac_Header" "$ac_includes_default"
-if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+eval as_val=\$$as_ac_Header
+   if test "x$as_val" = x""yes; then :
   HAS_PWLIB=1
 fi
 
@@ -25857,7 +25892,7 @@ fi
       PWLIBDIR="${HOME}/pwlib"
     else
       ac_fn_cxx_check_header_mongrel "$LINENO" "/usr/local/include/ptlib.h" "ac_cv_header__usr_local_include_ptlib_h" "$ac_includes_default"
-if test "x$ac_cv_header__usr_local_include_ptlib_h" = xyes; then :
+if test "x$ac_cv_header__usr_local_include_ptlib_h" = x""yes; then :
   HAS_PWLIB=1
 fi
 
@@ -25867,7 +25902,7 @@ fi
 set dummy ptlib-config; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_path_PTLIB_CONFIG+:} false; then :
+if test "${ac_cv_path_PTLIB_CONFIG+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   case $PTLIB_CONFIG in
@@ -25881,7 +25916,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
     ac_cv_path_PTLIB_CONFIG="$as_dir/$ac_word$ac_exec_ext"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -25919,7 +25954,7 @@ fi
         PWLIB_LIB="-L${PWLIB_LIBDIR} `echo ${PWLIB_LIB}`"
       else
         ac_fn_cxx_check_header_mongrel "$LINENO" "/usr/include/ptlib.h" "ac_cv_header__usr_include_ptlib_h" "$ac_includes_default"
-if test "x$ac_cv_header__usr_include_ptlib_h" = xyes; then :
+if test "x$ac_cv_header__usr_include_ptlib_h" = x""yes; then :
   HAS_PWLIB=1
 fi
 
@@ -25929,7 +25964,7 @@ fi
 set dummy ptlib-config; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_path_PTLIB_CONFIG+:} false; then :
+if test "${ac_cv_path_PTLIB_CONFIG+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   case $PTLIB_CONFIG in
@@ -25943,7 +25978,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
     ac_cv_path_PTLIB_CONFIG="$as_dir/$ac_word$ac_exec_ext"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -26260,7 +26295,8 @@ ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
 if test "${OPENH323DIR:-unset}" != "unset" ; then
   as_ac_Header=`$as_echo "ac_cv_header_${OPENH323DIR}/version.h" | $as_tr_sh`
 ac_fn_cxx_check_header_mongrel "$LINENO" "${OPENH323DIR}/version.h" "$as_ac_Header" "$ac_includes_default"
-if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+eval as_val=\$$as_ac_Header
+   if test "x$as_val" = x""yes; then :
   HAS_OPENH323=1
 fi
 
@@ -26269,7 +26305,8 @@ fi
 if test "${HAS_OPENH323:-unset}" = "unset" ; then
   as_ac_Header=`$as_echo "ac_cv_header_${PWLIBDIR}/../openh323/version.h" | $as_tr_sh`
 ac_fn_cxx_check_header_mongrel "$LINENO" "${PWLIBDIR}/../openh323/version.h" "$as_ac_Header" "$ac_includes_default"
-if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+eval as_val=\$$as_ac_Header
+   if test "x$as_val" = x""yes; then :
   OPENH323DIR="${PWLIBDIR}/../openh323"; HAS_OPENH323=1
 fi
 
@@ -26281,7 +26318,8 @@ fi
     as_ac_Header=`$as_echo "ac_cv_header_${OPENH323DIR}/include/h323.h" | $as_tr_sh`
 ac_fn_cxx_check_header_compile "$LINENO" "${OPENH323DIR}/include/h323.h" "$as_ac_Header" "#include <ptlib.h>
 "
-if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+eval as_val=\$$as_ac_Header
+   if test "x$as_val" = x""yes; then :
 
 else
   OPENH323_INCDIR="${PWLIB_INCDIR}/openh323"; OPENH323_LIBDIR="${PWLIB_LIBDIR}"
@@ -26295,7 +26333,8 @@ fi
     as_ac_Header=`$as_echo "ac_cv_header_${HOME}/openh323/include/h323.h" | $as_tr_sh`
 ac_fn_cxx_check_header_compile "$LINENO" "${HOME}/openh323/include/h323.h" "$as_ac_Header" "#include <ptlib.h>
 "
-if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+eval as_val=\$$as_ac_Header
+   if test "x$as_val" = x""yes; then :
   HAS_OPENH323=1
 fi
 
@@ -26308,7 +26347,7 @@ fi
       CPPFLAGS="${CPPFLAGS} -I/usr/local/include/openh323 -I${PWLIB_INCDIR}"
       ac_fn_cxx_check_header_compile "$LINENO" "/usr/local/include/openh323/h323.h" "ac_cv_header__usr_local_include_openh323_h323_h" "#include <ptlib.h>
 "
-if test "x$ac_cv_header__usr_local_include_openh323_h323_h" = xyes; then :
+if test "x$ac_cv_header__usr_local_include_openh323_h323_h" = x""yes; then :
   HAS_OPENH323=1
 fi
 
@@ -26327,7 +26366,7 @@ fi
         CPPFLAGS="${CPPFLAGS} -I/usr/include/openh323 -I${PWLIB_INCDIR}"
         ac_fn_cxx_check_header_compile "$LINENO" "/usr/include/openh323/h323.h" "ac_cv_header__usr_include_openh323_h323_h" "#include <ptlib.h>
 "
-if test "x$ac_cv_header__usr_include_openh323_h323_h" = xyes; then :
+if test "x$ac_cv_header__usr_include_openh323_h323_h" = x""yes; then :
   HAS_OPENH323=1
 fi
 
@@ -26569,7 +26608,7 @@ if test "x${PBX_LUA}" != "x1" -a "${USE_LUA}" != "no"; then
       as_ac_Lib=`$as_echo "ac_cv_lib_lua5.1_${pbxfuncname}" | $as_tr_sh`
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${pbxfuncname} in -llua5.1" >&5
 $as_echo_n "checking for ${pbxfuncname} in -llua5.1... " >&6; }
-if eval \${$as_ac_Lib+:} false; then :
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -26604,7 +26643,8 @@ fi
 eval ac_res=\$$as_ac_Lib
 	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
 $as_echo "$ac_res" >&6; }
-if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
   AST_LUA_FOUND=yes
 else
   AST_LUA_FOUND=no
@@ -26627,7 +26667,7 @@ fi
          ast_ext_lib_check_saved_CPPFLAGS="${CPPFLAGS}"
          CPPFLAGS="${CPPFLAGS} ${LUA_INCLUDE}"
          ac_fn_c_check_header_mongrel "$LINENO" "lua5.1/lua.h" "ac_cv_header_lua5_1_lua_h" "$ac_includes_default"
-if test "x$ac_cv_header_lua5_1_lua_h" = xyes; then :
+if test "x$ac_cv_header_lua5_1_lua_h" = x""yes; then :
   LUA_HEADER_FOUND=1
 else
   LUA_HEADER_FOUND=0
@@ -26682,7 +26722,7 @@ if test "x${PBX_LUA}" != "x1" -a "${USE_LUA}" != "no"; then
       as_ac_Lib=`$as_echo "ac_cv_lib_lua_${pbxfuncname}" | $as_tr_sh`
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${pbxfuncname} in -llua" >&5
 $as_echo_n "checking for ${pbxfuncname} in -llua... " >&6; }
-if eval \${$as_ac_Lib+:} false; then :
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -26717,7 +26757,8 @@ fi
 eval ac_res=\$$as_ac_Lib
 	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
 $as_echo "$ac_res" >&6; }
-if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
   AST_LUA_FOUND=yes
 else
   AST_LUA_FOUND=no
@@ -26740,7 +26781,7 @@ fi
          ast_ext_lib_check_saved_CPPFLAGS="${CPPFLAGS}"
          CPPFLAGS="${CPPFLAGS} ${LUA_INCLUDE}"
          ac_fn_c_check_header_mongrel "$LINENO" "lua.h" "ac_cv_header_lua_h" "$ac_includes_default"
-if test "x$ac_cv_header_lua_h" = xyes; then :
+if test "x$ac_cv_header_lua_h" = x""yes; then :
   LUA_HEADER_FOUND=1
 else
   LUA_HEADER_FOUND=0
@@ -26787,7 +26828,7 @@ if test "x${PBX_RADIUS}" != "x1" -a "${USE_RADIUS}" != "no"; then
       as_ac_Lib=`$as_echo "ac_cv_lib_radiusclient-ng_${pbxfuncname}" | $as_tr_sh`
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${pbxfuncname} in -lradiusclient-ng" >&5
 $as_echo_n "checking for ${pbxfuncname} in -lradiusclient-ng... " >&6; }
-if eval \${$as_ac_Lib+:} false; then :
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -26822,7 +26863,8 @@ fi
 eval ac_res=\$$as_ac_Lib
 	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
 $as_echo "$ac_res" >&6; }
-if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
   AST_RADIUS_FOUND=yes
 else
   AST_RADIUS_FOUND=no
@@ -26845,7 +26887,7 @@ fi
          ast_ext_lib_check_saved_CPPFLAGS="${CPPFLAGS}"
          CPPFLAGS="${CPPFLAGS} ${RADIUS_INCLUDE}"
          ac_fn_c_check_header_mongrel "$LINENO" "radiusclient-ng.h" "ac_cv_header_radiusclient_ng_h" "$ac_includes_default"
-if test "x$ac_cv_header_radiusclient_ng_h" = xyes; then :
+if test "x$ac_cv_header_radiusclient_ng_h" = x""yes; then :
   RADIUS_HEADER_FOUND=1
 else
   RADIUS_HEADER_FOUND=0
@@ -26892,7 +26934,7 @@ if test "x${PBX_COROSYNC}" != "x1" -a "${USE_COROSYNC}" != "no"; then
       as_ac_Lib=`$as_echo "ac_cv_lib_cpg_${pbxfuncname}" | $as_tr_sh`
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${pbxfuncname} in -lcpg" >&5
 $as_echo_n "checking for ${pbxfuncname} in -lcpg... " >&6; }
-if eval \${$as_ac_Lib+:} false; then :
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -26927,7 +26969,8 @@ fi
 eval ac_res=\$$as_ac_Lib
 	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
 $as_echo "$ac_res" >&6; }
-if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
   AST_COROSYNC_FOUND=yes
 else
   AST_COROSYNC_FOUND=no
@@ -26950,7 +26993,7 @@ fi
          ast_ext_lib_check_saved_CPPFLAGS="${CPPFLAGS}"
          CPPFLAGS="${CPPFLAGS} ${COROSYNC_INCLUDE}"
          ac_fn_c_check_header_mongrel "$LINENO" "corosync/cpg.h" "ac_cv_header_corosync_cpg_h" "$ac_includes_default"
-if test "x$ac_cv_header_corosync_cpg_h" = xyes; then :
+if test "x$ac_cv_header_corosync_cpg_h" = x""yes; then :
   COROSYNC_HEADER_FOUND=1
 else
   COROSYNC_HEADER_FOUND=0
@@ -26996,7 +27039,7 @@ if test "x${PBX_COROSYNC_CFG_STATE_TRACK}" != "x1" -a "${USE_COROSYNC_CFG_STATE_
       as_ac_Lib=`$as_echo "ac_cv_lib_cfg_${pbxfuncname}" | $as_tr_sh`
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${pbxfuncname} in -lcfg" >&5
 $as_echo_n "checking for ${pbxfuncname} in -lcfg... " >&6; }
-if eval \${$as_ac_Lib+:} false; then :
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -27031,7 +27074,8 @@ fi
 eval ac_res=\$$as_ac_Lib
 	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
 $as_echo "$ac_res" >&6; }
-if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
   AST_COROSYNC_CFG_STATE_TRACK_FOUND=yes
 else
   AST_COROSYNC_CFG_STATE_TRACK_FOUND=no
@@ -27054,7 +27098,7 @@ fi
          ast_ext_lib_check_saved_CPPFLAGS="${CPPFLAGS}"
          CPPFLAGS="${CPPFLAGS} ${COROSYNC_CFG_STATE_TRACK_INCLUDE}"
          ac_fn_c_check_header_mongrel "$LINENO" "corosync/cfg.h" "ac_cv_header_corosync_cfg_h" "$ac_includes_default"
-if test "x$ac_cv_header_corosync_cfg_h" = xyes; then :
+if test "x$ac_cv_header_corosync_cfg_h" = x""yes; then :
   COROSYNC_CFG_STATE_TRACK_HEADER_FOUND=1
 else
   COROSYNC_CFG_STATE_TRACK_HEADER_FOUND=0
@@ -27101,7 +27145,7 @@ if test "x${PBX_SPEEX}" != "x1" -a "${USE_SPEEX}" != "no"; then
       as_ac_Lib=`$as_echo "ac_cv_lib_speex_${pbxfuncname}" | $as_tr_sh`
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${pbxfuncname} in -lspeex" >&5
 $as_echo_n "checking for ${pbxfuncname} in -lspeex... " >&6; }
-if eval \${$as_ac_Lib+:} false; then :
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -27136,7 +27180,8 @@ fi
 eval ac_res=\$$as_ac_Lib
 	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
 $as_echo "$ac_res" >&6; }
-if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
   AST_SPEEX_FOUND=yes
 else
   AST_SPEEX_FOUND=no
@@ -27159,7 +27204,7 @@ fi
          ast_ext_lib_check_saved_CPPFLAGS="${CPPFLAGS}"
          CPPFLAGS="${CPPFLAGS} ${SPEEX_INCLUDE}"
          ac_fn_c_check_header_mongrel "$LINENO" "speex/speex.h" "ac_cv_header_speex_speex_h" "$ac_includes_default"
-if test "x$ac_cv_header_speex_speex_h" = xyes; then :
+if test "x$ac_cv_header_speex_speex_h" = x""yes; then :
   SPEEX_HEADER_FOUND=1
 else
   SPEEX_HEADER_FOUND=0
@@ -27207,7 +27252,7 @@ if test "x${PBX_SPEEX_PREPROCESS}" != "x1" -a "${USE_SPEEX_PREPROCESS}" != "no";
       as_ac_Lib=`$as_echo "ac_cv_lib_speex_${pbxfuncname}" | $as_tr_sh`
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${pbxfuncname} in -lspeex" >&5
 $as_echo_n "checking for ${pbxfuncname} in -lspeex... " >&6; }
-if eval \${$as_ac_Lib+:} false; then :
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -27242,7 +27287,8 @@ fi
 eval ac_res=\$$as_ac_Lib
 	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
 $as_echo "$ac_res" >&6; }
-if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
   AST_SPEEX_PREPROCESS_FOUND=yes
 else
   AST_SPEEX_PREPROCESS_FOUND=no
@@ -27265,7 +27311,7 @@ fi
          ast_ext_lib_check_saved_CPPFLAGS="${CPPFLAGS}"
          CPPFLAGS="${CPPFLAGS} ${SPEEX_PREPROCESS_INCLUDE}"
          ac_fn_c_check_header_mongrel "$LINENO" "speex/speex.h" "ac_cv_header_speex_speex_h" "$ac_includes_default"
-if test "x$ac_cv_header_speex_speex_h" = xyes; then :
+if test "x$ac_cv_header_speex_speex_h" = x""yes; then :
   SPEEX_PREPROCESS_HEADER_FOUND=1
 else
   SPEEX_PREPROCESS_HEADER_FOUND=0
@@ -27315,7 +27361,7 @@ if test "x${PBX_SPEEXDSP}" != "x1" -a "${USE_SPEEXDSP}" != "no"; then
       as_ac_Lib=`$as_echo "ac_cv_lib_speexdsp_${pbxfuncname}" | $as_tr_sh`
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${pbxfuncname} in -lspeexdsp" >&5
 $as_echo_n "checking for ${pbxfuncname} in -lspeexdsp... " >&6; }
-if eval \${$as_ac_Lib+:} false; then :
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -27350,7 +27396,8 @@ fi
 eval ac_res=\$$as_ac_Lib
 	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
 $as_echo "$ac_res" >&6; }
-if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
   AST_SPEEXDSP_FOUND=yes
 else
   AST_SPEEXDSP_FOUND=no
@@ -27373,7 +27420,7 @@ fi
          ast_ext_lib_check_saved_CPPFLAGS="${CPPFLAGS}"
          CPPFLAGS="${CPPFLAGS} ${SPEEXDSP_INCLUDE}"
          ac_fn_c_check_header_mongrel "$LINENO" "speex/speex.h" "ac_cv_header_speex_speex_h" "$ac_includes_default"
-if test "x$ac_cv_header_speex_speex_h" = xyes; then :
+if test "x$ac_cv_header_speex_speex_h" = x""yes; then :
   SPEEXDSP_HEADER_FOUND=1
 else
   SPEEXDSP_HEADER_FOUND=0
@@ -27425,7 +27472,7 @@ if test "x${PBX_SQLITE}" != "x1" -a "${USE_SQLITE}" != "no"; then
       as_ac_Lib=`$as_echo "ac_cv_lib_sqlite_${pbxfuncname}" | $as_tr_sh`
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${pbxfuncname} in -lsqlite" >&5
 $as_echo_n "checking for ${pbxfuncname} in -lsqlite... " >&6; }
-if eval \${$as_ac_Lib+:} false; then :
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -27460,7 +27507,8 @@ fi
 eval ac_res=\$$as_ac_Lib
 	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
 $as_echo "$ac_res" >&6; }
-if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
   AST_SQLITE_FOUND=yes
 else
   AST_SQLITE_FOUND=no
@@ -27483,7 +27531,7 @@ fi
          ast_ext_lib_check_saved_CPPFLAGS="${CPPFLAGS}"
          CPPFLAGS="${CPPFLAGS} ${SQLITE_INCLUDE}"
          ac_fn_c_check_header_mongrel "$LINENO" "sqlite.h" "ac_cv_header_sqlite_h" "$ac_includes_default"
-if test "x$ac_cv_header_sqlite_h" = xyes; then :
+if test "x$ac_cv_header_sqlite_h" = x""yes; then :
   SQLITE_HEADER_FOUND=1
 else
   SQLITE_HEADER_FOUND=0
@@ -27530,7 +27578,7 @@ if test "x${PBX_SQLITE3}" != "x1" -a "${USE_SQLITE3}" != "no"; then
       as_ac_Lib=`$as_echo "ac_cv_lib_sqlite3_${pbxfuncname}" | $as_tr_sh`
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${pbxfuncname} in -lsqlite3" >&5
 $as_echo_n "checking for ${pbxfuncname} in -lsqlite3... " >&6; }
-if eval \${$as_ac_Lib+:} false; then :
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -27565,7 +27613,8 @@ fi
 eval ac_res=\$$as_ac_Lib
 	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
 $as_echo "$ac_res" >&6; }
-if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
   AST_SQLITE3_FOUND=yes
 else
   AST_SQLITE3_FOUND=no
@@ -27588,7 +27637,7 @@ fi
          ast_ext_lib_check_saved_CPPFLAGS="${CPPFLAGS}"
          CPPFLAGS="${CPPFLAGS} ${SQLITE3_INCLUDE}"
          ac_fn_c_check_header_mongrel "$LINENO" "sqlite3.h" "ac_cv_header_sqlite3_h" "$ac_includes_default"
-if test "x$ac_cv_header_sqlite3_h" = xyes; then :
+if test "x$ac_cv_header_sqlite3_h" = x""yes; then :
   SQLITE3_HEADER_FOUND=1
 else
   SQLITE3_HEADER_FOUND=0
@@ -27643,7 +27692,7 @@ if test "x${PBX_CRYPTO}" != "x1" -a "${USE_CRYPTO}" != "no"; then
       as_ac_Lib=`$as_echo "ac_cv_lib_crypto_${pbxfuncname}" | $as_tr_sh`
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${pbxfuncname} in -lcrypto" >&5
 $as_echo_n "checking for ${pbxfuncname} in -lcrypto... " >&6; }
-if eval \${$as_ac_Lib+:} false; then :
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -27678,7 +27727,8 @@ fi
 eval ac_res=\$$as_ac_Lib
 	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
 $as_echo "$ac_res" >&6; }
-if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
   AST_CRYPTO_FOUND=yes
 else
   AST_CRYPTO_FOUND=no
@@ -27701,7 +27751,7 @@ fi
          ast_ext_lib_check_saved_CPPFLAGS="${CPPFLAGS}"
          CPPFLAGS="${CPPFLAGS} ${CRYPTO_INCLUDE}"
          ac_fn_c_check_header_mongrel "$LINENO" "openssl/aes.h" "ac_cv_header_openssl_aes_h" "$ac_includes_default"
-if test "x$ac_cv_header_openssl_aes_h" = xyes; then :
+if test "x$ac_cv_header_openssl_aes_h" = x""yes; then :
   CRYPTO_HEADER_FOUND=1
 else
   CRYPTO_HEADER_FOUND=0
@@ -27750,7 +27800,7 @@ if test "x${PBX_OPENSSL}" != "x1" -a "${USE_OPENSSL}" != "no"; then
       as_ac_Lib=`$as_echo "ac_cv_lib_ssl_${pbxfuncname}" | $as_tr_sh`
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${pbxfuncname} in -lssl" >&5
 $as_echo_n "checking for ${pbxfuncname} in -lssl... " >&6; }
-if eval \${$as_ac_Lib+:} false; then :
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -27785,7 +27835,8 @@ fi
 eval ac_res=\$$as_ac_Lib
 	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
 $as_echo "$ac_res" >&6; }
-if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
   AST_OPENSSL_FOUND=yes
 else
   AST_OPENSSL_FOUND=no
@@ -27808,7 +27859,7 @@ fi
          ast_ext_lib_check_saved_CPPFLAGS="${CPPFLAGS}"
          CPPFLAGS="${CPPFLAGS} ${OPENSSL_INCLUDE}"
          ac_fn_c_check_header_mongrel "$LINENO" "openssl/ssl.h" "ac_cv_header_openssl_ssl_h" "$ac_includes_default"
-if test "x$ac_cv_header_openssl_ssl_h" = xyes; then :
+if test "x$ac_cv_header_openssl_ssl_h" = x""yes; then :
   OPENSSL_HEADER_FOUND=1
 else
   OPENSSL_HEADER_FOUND=0
@@ -27854,7 +27905,7 @@ then
 		osptk_saved_cppflags="${CPPFLAGS}"
 		CPPFLAGS="${CPPFLAGS} ${osptk_cflags}"
 		ac_fn_c_check_header_mongrel "$LINENO" "osp/osp.h" "ac_cv_header_osp_osp_h" "$ac_includes_default"
-if test "x$ac_cv_header_osp_osp_h" = xyes; then :
+if test "x$ac_cv_header_osp_osp_h" = x""yes; then :
   osptk_header_found=yes
 else
   osptk_header_found=no
@@ -27869,7 +27920,7 @@ fi
 
 			{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for OSPPInit in -losptk" >&5
 $as_echo_n "checking for OSPPInit in -losptk... " >&6; }
-if ${ac_cv_lib_osptk_OSPPInit+:} false; then :
+if test "${ac_cv_lib_osptk_OSPPInit+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -27903,7 +27954,7 @@ LIBS=$ac_check_lib_save_LIBS
 fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_osptk_OSPPInit" >&5
 $as_echo "$ac_cv_lib_osptk_OSPPInit" >&6; }
-if test "x$ac_cv_lib_osptk_OSPPInit" = xyes; then :
+if test "x$ac_cv_lib_osptk_OSPPInit" = x""yes; then :
   osptk_library_found=yes
 else
   osptk_library_found=no
@@ -27920,8 +27971,8 @@ $as_echo_n "checking if OSP Toolkit version is compatible with app_osplookup...
 				if test "$cross_compiling" = yes; then :
   { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error $? "cannot run test program while cross compiling
-See \`config.log' for more details" "$LINENO" 5; }
+as_fn_error "cannot run test program while cross compiling
+See \`config.log' for more details." "$LINENO" 5; }
 else
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
@@ -27985,7 +28036,7 @@ if test "x${PBX_OPENSSL_SRTP}" != "x1" -a "${USE_OPENSSL_SRTP}" != "no"; then
       as_ac_Lib=`$as_echo "ac_cv_lib_ssl_${pbxfuncname}" | $as_tr_sh`
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${pbxfuncname} in -lssl" >&5
 $as_echo_n "checking for ${pbxfuncname} in -lssl... " >&6; }
-if eval \${$as_ac_Lib+:} false; then :
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -28020,7 +28071,8 @@ fi
 eval ac_res=\$$as_ac_Lib
 	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
 $as_echo "$ac_res" >&6; }
-if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
   AST_OPENSSL_SRTP_FOUND=yes
 else
   AST_OPENSSL_SRTP_FOUND=no
@@ -28043,7 +28095,7 @@ fi
          ast_ext_lib_check_saved_CPPFLAGS="${CPPFLAGS}"
          CPPFLAGS="${CPPFLAGS} ${OPENSSL_SRTP_INCLUDE}"
          ac_fn_c_check_header_mongrel "$LINENO" "openssl/ssl.h" "ac_cv_header_openssl_ssl_h" "$ac_includes_default"
-if test "x$ac_cv_header_openssl_ssl_h" = xyes; then :
+if test "x$ac_cv_header_openssl_ssl_h" = x""yes; then :
   OPENSSL_SRTP_HEADER_FOUND=1
 else
   OPENSSL_SRTP_HEADER_FOUND=0
@@ -28091,7 +28143,7 @@ if test "x${PBX_SRTP}" != "x1" -a "${USE_SRTP}" != "no"; then
       as_ac_Lib=`$as_echo "ac_cv_lib_srtp_${pbxfuncname}" | $as_tr_sh`
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${pbxfuncname} in -lsrtp" >&5
 $as_echo_n "checking for ${pbxfuncname} in -lsrtp... " >&6; }
-if eval \${$as_ac_Lib+:} false; then :
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -28126,7 +28178,8 @@ fi
 eval ac_res=\$$as_ac_Lib
 	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
 $as_echo "$ac_res" >&6; }
-if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
   AST_SRTP_FOUND=yes
 else
   AST_SRTP_FOUND=no
@@ -28149,7 +28202,7 @@ fi
          ast_ext_lib_check_saved_CPPFLAGS="${CPPFLAGS}"
          CPPFLAGS="${CPPFLAGS} ${SRTP_INCLUDE}"
          ac_fn_c_check_header_mongrel "$LINENO" "srtp/srtp.h" "ac_cv_header_srtp_srtp_h" "$ac_includes_default"
-if test "x$ac_cv_header_srtp_srtp_h" = xyes; then :
+if test "x$ac_cv_header_srtp_srtp_h" = x""yes; then :
   SRTP_HEADER_FOUND=1
 else
   SRTP_HEADER_FOUND=0
@@ -28247,46 +28300,46 @@ pkg_failed=no
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GMIME" >&5
 $as_echo_n "checking for GMIME... " >&6; }
 
-if test -n "$GMIME_CFLAGS"; then
-    pkg_cv_GMIME_CFLAGS="$GMIME_CFLAGS"
- elif test -n "$PKG_CONFIG"; then
-    if test -n "$PKG_CONFIG" && \
+if test -n "$PKG_CONFIG"; then
+    if test -n "$GMIME_CFLAGS"; then
+        pkg_cv_GMIME_CFLAGS="$GMIME_CFLAGS"
+    else
+        if test -n "$PKG_CONFIG" && \
     { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gmime-\$ver\""; } >&5
   ($PKG_CONFIG --exists --print-errors "gmime-$ver") 2>&5
   ac_status=$?
   $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }; then
   pkg_cv_GMIME_CFLAGS=`$PKG_CONFIG --cflags "gmime-$ver" 2>/dev/null`
-		      test "x$?" != "x0" && pkg_failed=yes
 else
   pkg_failed=yes
 fi
- else
-    pkg_failed=untried
+    fi
+else
+	pkg_failed=untried
 fi
-if test -n "$GMIME_LIBS"; then
-    pkg_cv_GMIME_LIBS="$GMIME_LIBS"
- elif test -n "$PKG_CONFIG"; then
-    if test -n "$PKG_CONFIG" && \
+if test -n "$PKG_CONFIG"; then
+    if test -n "$GMIME_LIBS"; then
+        pkg_cv_GMIME_LIBS="$GMIME_LIBS"
+    else
+        if test -n "$PKG_CONFIG" && \
     { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gmime-\$ver\""; } >&5
   ($PKG_CONFIG --exists --print-errors "gmime-$ver") 2>&5
   ac_status=$?
   $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }; then
   pkg_cv_GMIME_LIBS=`$PKG_CONFIG --libs "gmime-$ver" 2>/dev/null`
-		      test "x$?" != "x0" && pkg_failed=yes
 else
   pkg_failed=yes
 fi
- else
-    pkg_failed=untried
+    fi
+else
+	pkg_failed=untried
 fi
 
 
 
 if test $pkg_failed = yes; then
-   	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
 
 if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
         _pkg_short_errors_supported=yes
@@ -28294,20 +28347,20 @@ else
         _pkg_short_errors_supported=no
 fi
         if test $_pkg_short_errors_supported = yes; then
-	        GMIME_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "gmime-$ver" 2>&1`
+	        GMIME_PKG_ERRORS=`$PKG_CONFIG --short-errors --errors-to-stdout --print-errors "gmime-$ver"`
         else
-	        GMIME_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "gmime-$ver" 2>&1`
+	        GMIME_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "gmime-$ver"`
         fi
 	# Put the nasty error message in config.log where it belongs
 	echo "$GMIME_PKG_ERRORS" >&5
 
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
 
             PBX_GMIME=0
 
 
 elif test $pkg_failed = untried; then
-     	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
 
             PBX_GMIME=0
 
@@ -28353,7 +28406,7 @@ if test "x${PBX_HOARD}" != "x1" -a "${USE_HOARD}" != "no"; then
       as_ac_Lib=`$as_echo "ac_cv_lib_hoard_${pbxfuncname}" | $as_tr_sh`
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${pbxfuncname} in -lhoard" >&5
 $as_echo_n "checking for ${pbxfuncname} in -lhoard... " >&6; }
-if eval \${$as_ac_Lib+:} false; then :
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -28388,7 +28441,8 @@ fi
 eval ac_res=\$$as_ac_Lib
 	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
 $as_echo "$ac_res" >&6; }
-if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
   AST_HOARD_FOUND=yes
 else
   AST_HOARD_FOUND=no
@@ -28411,7 +28465,7 @@ fi
          ast_ext_lib_check_saved_CPPFLAGS="${CPPFLAGS}"
          CPPFLAGS="${CPPFLAGS} ${HOARD_INCLUDE}"
          ac_fn_c_check_header_mongrel "$LINENO" "" "ac_cv_header_" "$ac_includes_default"
-if test "x$ac_cv_header_" = xyes; then :
+if test "x$ac_cv_header_" = x""yes; then :
   HOARD_HEADER_FOUND=1
 else
   HOARD_HEADER_FOUND=0
@@ -28458,7 +28512,7 @@ if test "x${PBX_FREETDS}" != "x1" -a "${USE_FREETDS}" != "no"; then
       as_ac_Lib=`$as_echo "ac_cv_lib_sybdb_${pbxfuncname}" | $as_tr_sh`
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${pbxfuncname} in -lsybdb" >&5
 $as_echo_n "checking for ${pbxfuncname} in -lsybdb... " >&6; }
-if eval \${$as_ac_Lib+:} false; then :
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -28493,7 +28547,8 @@ fi
 eval ac_res=\$$as_ac_Lib
 	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
 $as_echo "$ac_res" >&6; }
-if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
   AST_FREETDS_FOUND=yes
 else
   AST_FREETDS_FOUND=no
@@ -28516,7 +28571,7 @@ fi
          ast_ext_lib_check_saved_CPPFLAGS="${CPPFLAGS}"
          CPPFLAGS="${CPPFLAGS} ${FREETDS_INCLUDE}"
          ac_fn_c_check_header_mongrel "$LINENO" "sybdb.h" "ac_cv_header_sybdb_h" "$ac_includes_default"
-if test "x$ac_cv_header_sybdb_h" = xyes; then :
+if test "x$ac_cv_header_sybdb_h" = x""yes; then :
   FREETDS_HEADER_FOUND=1
 else
   FREETDS_HEADER_FOUND=0
@@ -28545,7 +28600,7 @@ fi
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for tone_zone_find_by_num in -ltonezone" >&5
 $as_echo_n "checking for tone_zone_find_by_num in -ltonezone... " >&6; }
-if ${ac_cv_lib_tonezone_tone_zone_find_by_num+:} false; then :
+if test "${ac_cv_lib_tonezone_tone_zone_find_by_num+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -28579,7 +28634,7 @@ LIBS=$ac_check_lib_save_LIBS
 fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_tonezone_tone_zone_find_by_num" >&5
 $as_echo "$ac_cv_lib_tonezone_tone_zone_find_by_num" >&6; }
-if test "x$ac_cv_lib_tonezone_tone_zone_find_by_num" = xyes; then :
+if test "x$ac_cv_lib_tonezone_tone_zone_find_by_num" = x""yes; then :
   tonezone_does_not_need_lm=yes
 else
   tonezone_does_not_need_lm=no
@@ -28610,7 +28665,7 @@ if test "x${PBX_TONEZONE}" != "x1" -a "${USE_TONEZONE}" != "no"; then
       as_ac_Lib=`$as_echo "ac_cv_lib_tonezone_${pbxfuncname}" | $as_tr_sh`
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${pbxfuncname} in -ltonezone" >&5
 $as_echo_n "checking for ${pbxfuncname} in -ltonezone... " >&6; }
-if eval \${$as_ac_Lib+:} false; then :
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -28645,7 +28700,8 @@ fi
 eval ac_res=\$$as_ac_Lib
 	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
 $as_echo "$ac_res" >&6; }
-if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
   AST_TONEZONE_FOUND=yes
 else
   AST_TONEZONE_FOUND=no
@@ -28668,7 +28724,7 @@ fi
          ast_ext_lib_check_saved_CPPFLAGS="${CPPFLAGS}"
          CPPFLAGS="${CPPFLAGS} ${TONEZONE_INCLUDE}"
          ac_fn_c_check_header_mongrel "$LINENO" "dahdi/tonezone.h" "ac_cv_header_dahdi_tonezone_h" "$ac_includes_default"
-if test "x$ac_cv_header_dahdi_tonezone_h" = xyes; then :
+if test "x$ac_cv_header_dahdi_tonezone_h" = x""yes; then :
   TONEZONE_HEADER_FOUND=1
 else
   TONEZONE_HEADER_FOUND=0
@@ -28717,7 +28773,7 @@ if test "x${PBX_VORBIS}" != "x1" -a "${USE_VORBIS}" != "no"; then
       as_ac_Lib=`$as_echo "ac_cv_lib_vorbis_${pbxfuncname}" | $as_tr_sh`
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${pbxfuncname} in -lvorbis" >&5
 $as_echo_n "checking for ${pbxfuncname} in -lvorbis... " >&6; }
-if eval \${$as_ac_Lib+:} false; then :
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -28752,7 +28808,8 @@ fi
 eval ac_res=\$$as_ac_Lib
 	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
 $as_echo "$ac_res" >&6; }
-if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
   AST_VORBIS_FOUND=yes
 else
   AST_VORBIS_FOUND=no
@@ -28775,7 +28832,7 @@ fi
          ast_ext_lib_check_saved_CPPFLAGS="${CPPFLAGS}"
          CPPFLAGS="${CPPFLAGS} ${VORBIS_INCLUDE}"
          ac_fn_c_check_header_mongrel "$LINENO" "vorbis/codec.h" "ac_cv_header_vorbis_codec_h" "$ac_includes_default"
-if test "x$ac_cv_header_vorbis_codec_h" = xyes; then :
+if test "x$ac_cv_header_vorbis_codec_h" = x""yes; then :
   VORBIS_HEADER_FOUND=1
 else
   VORBIS_HEADER_FOUND=0
@@ -28822,7 +28879,7 @@ if test "x${PBX_VORBIS}" != "x1" -a "${USE_VORBIS}" != "no"; then
       as_ac_Lib=`$as_echo "ac_cv_lib_vorbis_${pbxfuncname}" | $as_tr_sh`
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${pbxfuncname} in -lvorbis" >&5
 $as_echo_n "checking for ${pbxfuncname} in -lvorbis... " >&6; }
-if eval \${$as_ac_Lib+:} false; then :
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -28857,7 +28914,8 @@ fi
 eval ac_res=\$$as_ac_Lib
 	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
 $as_echo "$ac_res" >&6; }
-if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
   AST_VORBIS_FOUND=yes
 else
   AST_VORBIS_FOUND=no
@@ -28880,7 +28938,7 @@ fi
          ast_ext_lib_check_saved_CPPFLAGS="${CPPFLAGS}"
          CPPFLAGS="${CPPFLAGS} ${VORBIS_INCLUDE}"
          ac_fn_c_check_header_mongrel "$LINENO" "vorbis/codec.h" "ac_cv_header_vorbis_codec_h" "$ac_includes_default"
-if test "x$ac_cv_header_vorbis_codec_h" = xyes; then :
+if test "x$ac_cv_header_vorbis_codec_h" = x""yes; then :
   VORBIS_HEADER_FOUND=1
 else
   VORBIS_HEADER_FOUND=0
@@ -29043,7 +29101,7 @@ if test "x${PBX_ZLIB}" != "x1" -a "${USE_ZLIB}" != "no"; then
       as_ac_Lib=`$as_echo "ac_cv_lib_z_${pbxfuncname}" | $as_tr_sh`
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${pbxfuncname} in -lz" >&5
 $as_echo_n "checking for ${pbxfuncname} in -lz... " >&6; }
-if eval \${$as_ac_Lib+:} false; then :
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -29078,7 +29136,8 @@ fi
 eval ac_res=\$$as_ac_Lib
 	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
 $as_echo "$ac_res" >&6; }
-if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
   AST_ZLIB_FOUND=yes
 else
   AST_ZLIB_FOUND=no
@@ -29101,7 +29160,7 @@ fi
          ast_ext_lib_check_saved_CPPFLAGS="${CPPFLAGS}"
          CPPFLAGS="${CPPFLAGS} ${ZLIB_INCLUDE}"
          ac_fn_c_check_header_mongrel "$LINENO" "zlib.h" "ac_cv_header_zlib_h" "$ac_includes_default"
-if test "x$ac_cv_header_zlib_h" = xyes; then :
+if test "x$ac_cv_header_zlib_h" = x""yes; then :
   ZLIB_HEADER_FOUND=1
 else
   ZLIB_HEADER_FOUND=0
@@ -29160,7 +29219,7 @@ rm -f core conftest.err conftest.$ac_objext \
 fi
 
 ac_fn_c_check_header_mongrel "$LINENO" "h323.h" "ac_cv_header_h323_h" "$ac_includes_default"
-if test "x$ac_cv_header_h323_h" = xyes; then :
+if test "x$ac_cv_header_h323_h" = x""yes; then :
   PBX_H323=1
 else
   PBX_H323=0
@@ -29170,7 +29229,7 @@ fi
 
 
 ac_fn_c_check_header_mongrel "$LINENO" "linux/compiler.h" "ac_cv_header_linux_compiler_h" "$ac_includes_default"
-if test "x$ac_cv_header_linux_compiler_h" = xyes; then :
+if test "x$ac_cv_header_linux_compiler_h" = x""yes; then :
 
 cat >>confdefs.h <<_ACEOF
 #define HAVE_LINUX_COMPILER_H 1
@@ -29187,7 +29246,7 @@ ac_fn_c_check_header_compile "$LINENO" "linux/ixjuser.h" "ac_cv_header_linux_ixj
 				   #endif
 
 "
-if test "x$ac_cv_header_linux_ixjuser_h" = xyes; then :
+if test "x$ac_cv_header_linux_ixjuser_h" = x""yes; then :
   PBX_IXJUSER=1
 else
   PBX_IXJUSER=0
@@ -29298,7 +29357,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
 set dummy ${ac_tool_prefix}sdl-config; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_path_CONFIG_SDL+:} false; then :
+if test "${ac_cv_path_CONFIG_SDL+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   case $CONFIG_SDL in
@@ -29313,7 +29372,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
     ac_cv_path_CONFIG_SDL="$as_dir/$ac_word$ac_exec_ext"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -29342,7 +29401,7 @@ if test -z "$ac_cv_path_CONFIG_SDL"; then
 set dummy sdl-config; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_path_ac_pt_CONFIG_SDL+:} false; then :
+if test "${ac_cv_path_ac_pt_CONFIG_SDL+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   case $ac_pt_CONFIG_SDL in
@@ -29357,7 +29416,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
     ac_cv_path_ac_pt_CONFIG_SDL="$as_dir/$ac_word$ac_exec_ext"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -29460,7 +29519,7 @@ if test "x${PBX_SDL_IMAGE}" != "x1" -a "${USE_SDL_IMAGE}" != "no"; then
       as_ac_Lib=`$as_echo "ac_cv_lib_SDL_image_${pbxfuncname}" | $as_tr_sh`
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${pbxfuncname} in -lSDL_image" >&5
 $as_echo_n "checking for ${pbxfuncname} in -lSDL_image... " >&6; }
-if eval \${$as_ac_Lib+:} false; then :
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -29495,7 +29554,8 @@ fi
 eval ac_res=\$$as_ac_Lib
 	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
 $as_echo "$ac_res" >&6; }
-if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
   AST_SDL_IMAGE_FOUND=yes
 else
   AST_SDL_IMAGE_FOUND=no
@@ -29518,7 +29578,7 @@ fi
          ast_ext_lib_check_saved_CPPFLAGS="${CPPFLAGS}"
          CPPFLAGS="${CPPFLAGS} ${SDL_IMAGE_INCLUDE}"
          ac_fn_c_check_header_mongrel "$LINENO" "SDL_image.h" "ac_cv_header_SDL_image_h" "$ac_includes_default"
-if test "x$ac_cv_header_SDL_image_h" = xyes; then :
+if test "x$ac_cv_header_SDL_image_h" = x""yes; then :
   SDL_IMAGE_HEADER_FOUND=1
 else
   SDL_IMAGE_HEADER_FOUND=0
@@ -29564,7 +29624,7 @@ if test "x${PBX_FFMPEG}" != "x1" -a "${USE_FFMPEG}" != "no"; then
       as_ac_Lib=`$as_echo "ac_cv_lib_avcodec_${pbxfuncname}" | $as_tr_sh`
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${pbxfuncname} in -lavcodec" >&5
 $as_echo_n "checking for ${pbxfuncname} in -lavcodec... " >&6; }
-if eval \${$as_ac_Lib+:} false; then :
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -29599,7 +29659,8 @@ fi
 eval ac_res=\$$as_ac_Lib
 	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
 $as_echo "$ac_res" >&6; }
-if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
   AST_FFMPEG_FOUND=yes
 else
   AST_FFMPEG_FOUND=no
@@ -29622,7 +29683,7 @@ fi
          ast_ext_lib_check_saved_CPPFLAGS="${CPPFLAGS}"
          CPPFLAGS="${CPPFLAGS} ${FFMPEG_INCLUDE}"
          ac_fn_c_check_header_mongrel "$LINENO" "ffmpeg/avcodec.h" "ac_cv_header_ffmpeg_avcodec_h" "$ac_includes_default"
-if test "x$ac_cv_header_ffmpeg_avcodec_h" = xyes; then :
+if test "x$ac_cv_header_ffmpeg_avcodec_h" = x""yes; then :
   FFMPEG_HEADER_FOUND=1
 else
   FFMPEG_HEADER_FOUND=0
@@ -29651,7 +29712,7 @@ fi
 
 # possible places for video4linux version 1
 ac_fn_c_check_header_mongrel "$LINENO" "linux/videodev.h" "ac_cv_header_linux_videodev_h" "$ac_includes_default"
-if test "x$ac_cv_header_linux_videodev_h" = xyes; then :
+if test "x$ac_cv_header_linux_videodev_h" = x""yes; then :
 
 cat >>confdefs.h <<_ACEOF
 #define HAVE_VIDEODEV_H 1
@@ -29682,7 +29743,7 @@ if test "x${PBX_X11}" != "x1" -a "${USE_X11}" != "no"; then
       as_ac_Lib=`$as_echo "ac_cv_lib_X11_${pbxfuncname}" | $as_tr_sh`
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${pbxfuncname} in -lX11" >&5
 $as_echo_n "checking for ${pbxfuncname} in -lX11... " >&6; }
-if eval \${$as_ac_Lib+:} false; then :
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -29717,7 +29778,8 @@ fi
 eval ac_res=\$$as_ac_Lib
 	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
 $as_echo "$ac_res" >&6; }
-if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
   AST_X11_FOUND=yes
 else
   AST_X11_FOUND=no
@@ -29740,7 +29802,7 @@ fi
          ast_ext_lib_check_saved_CPPFLAGS="${CPPFLAGS}"
          CPPFLAGS="${CPPFLAGS} ${X11_INCLUDE}"
          ac_fn_c_check_header_mongrel "$LINENO" "X11/Xlib.h" "ac_cv_header_X11_Xlib_h" "$ac_includes_default"
-if test "x$ac_cv_header_X11_Xlib_h" = xyes; then :
+if test "x$ac_cv_header_X11_Xlib_h" = x""yes; then :
   X11_HEADER_FOUND=1
 else
   X11_HEADER_FOUND=0
@@ -29790,7 +29852,7 @@ if test "x${PBX_X11}" != "x1" -a "${USE_X11}" != "no"; then
       as_ac_Lib=`$as_echo "ac_cv_lib_X11_${pbxfuncname}" | $as_tr_sh`
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${pbxfuncname} in -lX11" >&5
 $as_echo_n "checking for ${pbxfuncname} in -lX11... " >&6; }
-if eval \${$as_ac_Lib+:} false; then :
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -29825,7 +29887,8 @@ fi
 eval ac_res=\$$as_ac_Lib
 	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
 $as_echo "$ac_res" >&6; }
-if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
   AST_X11_FOUND=yes
 else
   AST_X11_FOUND=no
@@ -29848,7 +29911,7 @@ fi
          ast_ext_lib_check_saved_CPPFLAGS="${CPPFLAGS}"
          CPPFLAGS="${CPPFLAGS} ${X11_INCLUDE}"
          ac_fn_c_check_header_mongrel "$LINENO" "X11/Xlib.h" "ac_cv_header_X11_Xlib_h" "$ac_includes_default"
-if test "x$ac_cv_header_X11_Xlib_h" = xyes; then :
+if test "x$ac_cv_header_X11_Xlib_h" = x""yes; then :
   X11_HEADER_FOUND=1
 else
   X11_HEADER_FOUND=0
@@ -29884,11 +29947,11 @@ if test "${cross_compiling}" = "no";
 then
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for /sbin/launchd" >&5
 $as_echo_n "checking for /sbin/launchd... " >&6; }
-if ${ac_cv_file__sbin_launchd+:} false; then :
+if test "${ac_cv_file__sbin_launchd+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   test "$cross_compiling" = yes &&
-  as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5
+  as_fn_error "cannot check for file existence when cross compiling" "$LINENO" 5
 if test -r "/sbin/launchd"; then
   ac_cv_file__sbin_launchd=yes
 else
@@ -29897,7 +29960,7 @@ fi
 fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_file__sbin_launchd" >&5
 $as_echo "$ac_cv_file__sbin_launchd" >&6; }
-if test "x$ac_cv_file__sbin_launchd" = xyes; then :
+if test "x$ac_cv_file__sbin_launchd" = x""yes; then :
 
 $as_echo "#define HAVE_SBIN_LAUNCHD 1" >>confdefs.h
 
@@ -29916,46 +29979,46 @@ pkg_failed=no
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GTK2" >&5
 $as_echo_n "checking for GTK2... " >&6; }
 
-if test -n "$GTK2_CFLAGS"; then
-    pkg_cv_GTK2_CFLAGS="$GTK2_CFLAGS"
- elif test -n "$PKG_CONFIG"; then
-    if test -n "$PKG_CONFIG" && \
+if test -n "$PKG_CONFIG"; then
+    if test -n "$GTK2_CFLAGS"; then
+        pkg_cv_GTK2_CFLAGS="$GTK2_CFLAGS"
+    else
+        if test -n "$PKG_CONFIG" && \
     { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gtk+-2.0\""; } >&5
   ($PKG_CONFIG --exists --print-errors "gtk+-2.0") 2>&5
   ac_status=$?
   $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }; then
   pkg_cv_GTK2_CFLAGS=`$PKG_CONFIG --cflags "gtk+-2.0" 2>/dev/null`
-		      test "x$?" != "x0" && pkg_failed=yes
 else
   pkg_failed=yes
 fi
- else
-    pkg_failed=untried
+    fi
+else
+	pkg_failed=untried
 fi
-if test -n "$GTK2_LIBS"; then
-    pkg_cv_GTK2_LIBS="$GTK2_LIBS"
- elif test -n "$PKG_CONFIG"; then
-    if test -n "$PKG_CONFIG" && \
+if test -n "$PKG_CONFIG"; then
+    if test -n "$GTK2_LIBS"; then
+        pkg_cv_GTK2_LIBS="$GTK2_LIBS"
+    else
+        if test -n "$PKG_CONFIG" && \
     { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gtk+-2.0\""; } >&5
   ($PKG_CONFIG --exists --print-errors "gtk+-2.0") 2>&5
   ac_status=$?
   $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }; then
   pkg_cv_GTK2_LIBS=`$PKG_CONFIG --libs "gtk+-2.0" 2>/dev/null`
-		      test "x$?" != "x0" && pkg_failed=yes
 else
   pkg_failed=yes
 fi
- else
-    pkg_failed=untried
+    fi
+else
+	pkg_failed=untried
 fi
 
 
 
 if test $pkg_failed = yes; then
-   	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
 
 if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
         _pkg_short_errors_supported=yes
@@ -29963,20 +30026,20 @@ else
         _pkg_short_errors_supported=no
 fi
         if test $_pkg_short_errors_supported = yes; then
-	        GTK2_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "gtk+-2.0" 2>&1`
+	        GTK2_PKG_ERRORS=`$PKG_CONFIG --short-errors --errors-to-stdout --print-errors "gtk+-2.0"`
         else
-	        GTK2_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "gtk+-2.0" 2>&1`
+	        GTK2_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "gtk+-2.0"`
         fi
 	# Put the nasty error message in config.log where it belongs
 	echo "$GTK2_PKG_ERRORS" >&5
 
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
 
             PBX_GTK2=0
 
 
 elif test $pkg_failed = untried; then
-     	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
 
             PBX_GTK2=0
 
@@ -30641,21 +30704,10 @@ $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
      :end' >>confcache
 if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
   if test -w "$cache_file"; then
-    if test "x$cache_file" != "x/dev/null"; then
+    test "x$cache_file" != "x/dev/null" &&
       { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5
 $as_echo "$as_me: updating cache $cache_file" >&6;}
-      if test ! -f "$cache_file" || test -h "$cache_file"; then
-	cat confcache >"$cache_file"
-      else
-        case $cache_file in #(
-        */* | ?:*)
-	  mv -f confcache "$cache_file"$$ &&
-	  mv -f "$cache_file"$$ "$cache_file" ;; #(
-        *)
-	  mv -f confcache "$cache_file" ;;
-	esac
-      fi
-    fi
+    cat confcache >$cache_file
   else
     { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5
 $as_echo "$as_me: not updating unwritable cache $cache_file" >&6;}
@@ -30671,7 +30723,6 @@ DEFS=-DHAVE_CONFIG_H
 
 ac_libobjs=
 ac_ltlibobjs=
-U=
 for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
   # 1. Remove the extension, and $U if already installed.
   ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
@@ -30687,7 +30738,7 @@ LTLIBOBJS=$ac_ltlibobjs
 
 
 
-: "${CONFIG_STATUS=./config.status}"
+: ${CONFIG_STATUS=./config.status}
 ac_write_fail=0
 ac_clean_files_save=$ac_clean_files
 ac_clean_files="$ac_clean_files $CONFIG_STATUS"
@@ -30788,7 +30839,6 @@ fi
 IFS=" ""	$as_nl"
 
 # Find who we are.  Look in the path if we contain no directory separator.
-as_myself=
 case $0 in #((
   *[\\/]* ) as_myself=$0 ;;
   *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
@@ -30834,19 +30884,19 @@ export LANGUAGE
 (unset CDPATH) >/dev/null 2>&1 && unset CDPATH
 
 
-# as_fn_error STATUS ERROR [LINENO LOG_FD]
-# ----------------------------------------
+# as_fn_error ERROR [LINENO LOG_FD]
+# ---------------------------------
 # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
 # provided, also output the error to LOG_FD, referencing LINENO. Then exit the
-# script with STATUS, using 1 if that was 0.
+# script with status $?, using 1 if that was 0.
 as_fn_error ()
 {
-  as_status=$1; test $as_status -eq 0 && as_status=1
-  if test "$4"; then
-    as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-    $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+  as_status=$?; test $as_status -eq 0 && as_status=1
+  if test "$3"; then
+    as_lineno=${as_lineno-"$2"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+    $as_echo "$as_me:${as_lineno-$LINENO}: error: $1" >&$3
   fi
-  $as_echo "$as_me: error: $2" >&2
+  $as_echo "$as_me: error: $1" >&2
   as_fn_exit $as_status
 } # as_fn_error
 
@@ -30984,16 +31034,16 @@ if (echo >conf$$.file) 2>/dev/null; then
     # ... but there are two gotchas:
     # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
     # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
-    # In both cases, we have to default to `cp -pR'.
+    # In both cases, we have to default to `cp -p'.
     ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
-      as_ln_s='cp -pR'
+      as_ln_s='cp -p'
   elif ln conf$$.file conf$$ 2>/dev/null; then
     as_ln_s=ln
   else
-    as_ln_s='cp -pR'
+    as_ln_s='cp -p'
   fi
 else
-  as_ln_s='cp -pR'
+  as_ln_s='cp -p'
 fi
 rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
 rmdir conf$$.dir 2>/dev/null
@@ -31042,7 +31092,7 @@ $as_echo X"$as_dir" |
       test -d "$as_dir" && break
     done
     test -z "$as_dirs" || eval "mkdir $as_dirs"
-  } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
+  } || test -d "$as_dir" || as_fn_error "cannot create directory $as_dir"
 
 
 } # as_fn_mkdir_p
@@ -31053,16 +31103,28 @@ else
   as_mkdir_p=false
 fi
 
-
-# as_fn_executable_p FILE
-# -----------------------
-# Test if FILE is an executable regular file.
-as_fn_executable_p ()
-{
-  test -f "$1" && test -x "$1"
-} # as_fn_executable_p
-as_test_x='test -x'
-as_executable_p=as_fn_executable_p
+if test -x / >/dev/null 2>&1; then
+  as_test_x='test -x'
+else
+  if ls -dL / >/dev/null 2>&1; then
+    as_ls_L_option=L
+  else
+    as_ls_L_option=
+  fi
+  as_test_x='
+    eval sh -c '\''
+      if test -d "$1"; then
+	test -d "$1/.";
+      else
+	case $1 in #(
+	-*)set "./$1";;
+	esac;
+	case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #((
+	???[sx]*):;;*)false;;esac;fi
+    '\'' sh
+  '
+fi
+as_executable_p=$as_test_x
 
 # Sed expression to map a string onto a valid CPP name.
 as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
@@ -31084,7 +31146,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
 # values after options handling.
 ac_log="
 This file was extended by asterisk $as_me trunk, which was
-generated by GNU Autoconf 2.69.  Invocation command line was
+generated by GNU Autoconf 2.65.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
   CONFIG_HEADERS  = $CONFIG_HEADERS
@@ -31146,10 +31208,10 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
 asterisk config.status trunk
-configured by $0, generated by GNU Autoconf 2.69,
+configured by $0, generated by GNU Autoconf 2.65,
   with options \\"\$ac_cs_config\\"
 
-Copyright (C) 2012 Free Software Foundation, Inc.
+Copyright (C) 2009 Free Software Foundation, Inc.
 This config.status script is free software; the Free Software Foundation
 gives unlimited permission to copy, distribute and modify it."
 
@@ -31166,16 +31228,11 @@ ac_need_defaults=:
 while test $# != 0
 do
   case $1 in
-  --*=?*)
+  --*=*)
     ac_option=`expr "X$1" : 'X\([^=]*\)='`
     ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'`
     ac_shift=:
     ;;
-  --*=)
-    ac_option=`expr "X$1" : 'X\([^=]*\)='`
-    ac_optarg=
-    ac_shift=:
-    ;;
   *)
     ac_option=$1
     ac_optarg=$2
@@ -31197,7 +31254,6 @@ do
     $ac_shift
     case $ac_optarg in
     *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
-    '') as_fn_error $? "missing file argument" ;;
     esac
     as_fn_append CONFIG_FILES " '$ac_optarg'"
     ac_need_defaults=false;;
@@ -31210,7 +31266,7 @@ do
     ac_need_defaults=false;;
   --he | --h)
     # Conflict between --help and --header
-    as_fn_error $? "ambiguous option: \`$1'
+    as_fn_error "ambiguous option: \`$1'
 Try \`$0 --help' for more information.";;
   --help | --hel | -h )
     $as_echo "$ac_cs_usage"; exit ;;
@@ -31219,7 +31275,7 @@ Try \`$0 --help' for more information.";;
     ac_cs_silent=: ;;
 
   # This is an error.
-  -*) as_fn_error $? "unrecognized option: \`$1'
+  -*) as_fn_error "unrecognized option: \`$1'
 Try \`$0 --help' for more information." ;;
 
   *) as_fn_append ac_config_targets " $1"
@@ -31239,7 +31295,7 @@ fi
 _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 if \$ac_cs_recheck; then
-  set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+  set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
   shift
   \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6
   CONFIG_SHELL='$SHELL'
@@ -31273,7 +31329,7 @@ do
     "makeopts") CONFIG_FILES="$CONFIG_FILES makeopts" ;;
     "channels/h323/Makefile") CONFIG_FILES="$CONFIG_FILES channels/h323/Makefile" ;;
 
-  *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
+  *) as_fn_error "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
   esac
 done
 
@@ -31295,10 +31351,9 @@ fi
 # after its creation but before its name has been assigned to `$tmp'.
 $debug ||
 {
-  tmp= ac_tmp=
+  tmp=
   trap 'exit_status=$?
-  : "${ac_tmp:=$tmp}"
-  { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status
+  { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status
 ' 0
   trap 'as_fn_exit 1' 1 2 13 15
 }
@@ -31306,13 +31361,12 @@ $debug ||
 
 {
   tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
-  test -d "$tmp"
+  test -n "$tmp" && test -d "$tmp"
 }  ||
 {
   tmp=./conf$$-$RANDOM
   (umask 077 && mkdir "$tmp")
-} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5
-ac_tmp=$tmp
+} || as_fn_error "cannot create a temporary directory in ." "$LINENO" 5
 
 # Set up the scripts for CONFIG_FILES section.
 # No need to generate them if there are no CONFIG_FILES.
@@ -31329,12 +31383,12 @@ if test "x$ac_cr" = x; then
 fi
 ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null`
 if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then
-  ac_cs_awk_cr='\\r'
+  ac_cs_awk_cr='\r'
 else
   ac_cs_awk_cr=$ac_cr
 fi
 
-echo 'BEGIN {' >"$ac_tmp/subs1.awk" &&
+echo 'BEGIN {' >"$tmp/subs1.awk" &&
 _ACEOF
 
 
@@ -31343,18 +31397,18 @@ _ACEOF
   echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' &&
   echo "_ACEOF"
 } >conf$$subs.sh ||
-  as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
-ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'`
+  as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5
+ac_delim_num=`echo "$ac_subst_vars" | grep -c '$'`
 ac_delim='%!_!# '
 for ac_last_try in false false false false false :; do
   . ./conf$$subs.sh ||
-    as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+    as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5
 
   ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X`
   if test $ac_delim_n = $ac_delim_num; then
     break
   elif $ac_last_try; then
-    as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+    as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5
   else
     ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
   fi
@@ -31362,7 +31416,7 @@ done
 rm -f conf$$subs.sh
 
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
-cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK &&
+cat >>"\$tmp/subs1.awk" <<\\_ACAWK &&
 _ACEOF
 sed -n '
 h
@@ -31410,7 +31464,7 @@ t delim
 rm -f conf$$subs.awk
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 _ACAWK
-cat >>"\$ac_tmp/subs1.awk" <<_ACAWK &&
+cat >>"\$tmp/subs1.awk" <<_ACAWK &&
   for (key in S) S_is_set[key] = 1
   FS = ""
 
@@ -31442,29 +31496,21 @@ if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then
   sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g"
 else
   cat
-fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \
-  || as_fn_error $? "could not setup config files machinery" "$LINENO" 5
+fi < "$tmp/subs1.awk" > "$tmp/subs.awk" \
+  || as_fn_error "could not setup config files machinery" "$LINENO" 5
 _ACEOF
 
-# VPATH may cause trouble with some makes, so we remove sole $(srcdir),
-# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and
+# VPATH may cause trouble with some makes, so we remove $(srcdir),
+# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and
 # trailing colons and then remove the whole line if VPATH becomes empty
 # (actually we leave an empty line to preserve line numbers).
 if test "x$srcdir" = x.; then
-  ac_vpsub='/^[	 ]*VPATH[	 ]*=[	 ]*/{
-h
-s///
-s/^/:/
-s/[	 ]*$/:/
-s/:\$(srcdir):/:/g
-s/:\${srcdir}:/:/g
-s/:@srcdir@:/:/g
-s/^:*//
+  ac_vpsub='/^[	 ]*VPATH[	 ]*=/{
+s/:*\$(srcdir):*/:/
+s/:*\${srcdir}:*/:/
+s/:*@srcdir@:*/:/
+s/^\([^=]*=[	 ]*\):*/\1/
 s/:*$//
-x
-s/\(=[	 ]*\).*/\1/
-G
-s/\n//
 s/^[^=]*=[	 ]*$//
 }'
 fi
@@ -31476,7 +31522,7 @@ fi # test -n "$CONFIG_FILES"
 # No need to generate them if there are no CONFIG_HEADERS.
 # This happens for instance with `./config.status Makefile'.
 if test -n "$CONFIG_HEADERS"; then
-cat >"$ac_tmp/defines.awk" <<\_ACAWK ||
+cat >"$tmp/defines.awk" <<\_ACAWK ||
 BEGIN {
 _ACEOF
 
@@ -31488,11 +31534,11 @@ _ACEOF
 # handling of long lines.
 ac_delim='%!_!# '
 for ac_last_try in false false :; do
-  ac_tt=`sed -n "/$ac_delim/p" confdefs.h`
-  if test -z "$ac_tt"; then
+  ac_t=`sed -n "/$ac_delim/p" confdefs.h`
+  if test -z "$ac_t"; then
     break
   elif $ac_last_try; then
-    as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5
+    as_fn_error "could not make $CONFIG_HEADERS" "$LINENO" 5
   else
     ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
   fi
@@ -31577,7 +31623,7 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 _ACAWK
 _ACEOF
 cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
-  as_fn_error $? "could not setup config headers machinery" "$LINENO" 5
+  as_fn_error "could not setup config headers machinery" "$LINENO" 5
 fi # test -n "$CONFIG_HEADERS"
 
 
@@ -31590,7 +31636,7 @@ do
   esac
   case $ac_mode$ac_tag in
   :[FHL]*:*);;
-  :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;;
+  :L* | :C*:*) as_fn_error "invalid tag \`$ac_tag'" "$LINENO" 5;;
   :[FH]-) ac_tag=-:-;;
   :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
   esac
@@ -31609,7 +31655,7 @@ do
     for ac_f
     do
       case $ac_f in
-      -) ac_f="$ac_tmp/stdin";;
+      -) ac_f="$tmp/stdin";;
       *) # Look for the file first in the build tree, then in the source tree
 	 # (if the path is not absolute).  The absolute path cannot be DOS-style,
 	 # because $ac_f cannot contain `:'.
@@ -31618,7 +31664,7 @@ do
 	   [\\/$]*) false;;
 	   *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
 	   esac ||
-	   as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;;
+	   as_fn_error "cannot find input file: \`$ac_f'" "$LINENO" 5;;
       esac
       case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
       as_fn_append ac_file_inputs " '$ac_f'"
@@ -31644,8 +31690,8 @@ $as_echo "$as_me: creating $ac_file" >&6;}
     esac
 
     case $ac_tag in
-    *:-:* | *:-) cat >"$ac_tmp/stdin" \
-      || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;;
+    *:-:* | *:-) cat >"$tmp/stdin" \
+      || as_fn_error "could not create $ac_file" "$LINENO" 5 ;;
     esac
     ;;
   esac
@@ -31775,24 +31821,23 @@ s&@abs_top_builddir@&$ac_abs_top_builddir&;t t
 s&@INSTALL@&$ac_INSTALL&;t t
 $ac_datarootdir_hack
 "
-eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \
-  >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$tmp/subs.awk" >$tmp/out \
+  || as_fn_error "could not create $ac_file" "$LINENO" 5
 
 test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
-  { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } &&
-  { ac_out=`sed -n '/^[	 ]*datarootdir[	 ]*:*=/p' \
-      "$ac_tmp/out"`; test -z "$ac_out"; } &&
+  { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } &&
+  { ac_out=`sed -n '/^[	 ]*datarootdir[	 ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } &&
   { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir'
-which seems to be undefined.  Please make sure it is defined" >&5
+which seems to be undefined.  Please make sure it is defined." >&5
 $as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
-which seems to be undefined.  Please make sure it is defined" >&2;}
+which seems to be undefined.  Please make sure it is defined." >&2;}
 
-  rm -f "$ac_tmp/stdin"
+  rm -f "$tmp/stdin"
   case $ac_file in
-  -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";;
-  *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";;
+  -) cat "$tmp/out" && rm -f "$tmp/out";;
+  *) rm -f "$ac_file" && mv "$tmp/out" "$ac_file";;
   esac \
-  || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+  || as_fn_error "could not create $ac_file" "$LINENO" 5
  ;;
   :H)
   #
@@ -31801,21 +31846,21 @@ which seems to be undefined.  Please make sure it is defined" >&2;}
   if test x"$ac_file" != x-; then
     {
       $as_echo "/* $configure_input  */" \
-      && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs"
-    } >"$ac_tmp/config.h" \
-      || as_fn_error $? "could not create $ac_file" "$LINENO" 5
-    if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then
+      && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs"
+    } >"$tmp/config.h" \
+      || as_fn_error "could not create $ac_file" "$LINENO" 5
+    if diff "$ac_file" "$tmp/config.h" >/dev/null 2>&1; then
       { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5
 $as_echo "$as_me: $ac_file is unchanged" >&6;}
     else
       rm -f "$ac_file"
-      mv "$ac_tmp/config.h" "$ac_file" \
-	|| as_fn_error $? "could not create $ac_file" "$LINENO" 5
+      mv "$tmp/config.h" "$ac_file" \
+	|| as_fn_error "could not create $ac_file" "$LINENO" 5
     fi
   else
     $as_echo "/* $configure_input  */" \
-      && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \
-      || as_fn_error $? "could not create -" "$LINENO" 5
+      && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" \
+      || as_fn_error "could not create -" "$LINENO" 5
   fi
  ;;
 
@@ -31830,7 +31875,7 @@ _ACEOF
 ac_clean_files=$ac_clean_files_save
 
 test $ac_write_fail = 0 ||
-  as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5
+  as_fn_error "write failure creating $CONFIG_STATUS" "$LINENO" 5
 
 
 # configure is writing to config.log, and then calls config.status.
@@ -31851,7 +31896,7 @@ if test "$no_create" != yes; then
   exec 5>>config.log
   # Use ||, not &&, to avoid exiting from the if with $? = 1, which
   # would make configure fail if this is the last instruction.
-  $ac_cs_success || as_fn_exit 1
+  $ac_cs_success || as_fn_exit $?
 fi
 if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then
   { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
diff --git a/include/asterisk/autoconfig.h.in b/include/asterisk/autoconfig.h.in
index f7294b36e648bb05de272e0569068517fb08c424..60f2068e50a390eb896941e9e83853d3a8786d61 100644
--- a/include/asterisk/autoconfig.h.in
+++ b/include/asterisk/autoconfig.h.in
@@ -294,7 +294,7 @@
 /* Define if your system has the GLOB_NOMAGIC headers. */
 #undef HAVE_GLOB_NOMAGIC
 
-/* Define if your system has the GMIME libraries. */
+/* Define to 1 if you have the GMime library. */
 #undef HAVE_GMIME
 
 /* Define to indicate the GSM library */
@@ -306,7 +306,7 @@
 /* Define to indicate that gsm.h has no prefix for its location */
 #undef HAVE_GSM_HEADER
 
-/* Define if your system has the GTK2 libraries. */
+/* Define to 1 if you have the gtk2 library. */
 #undef HAVE_GTK2
 
 /* Define to 1 if you have the Hoard Memory Allocator library. */
@@ -324,7 +324,7 @@
 /* Define to 1 if you have the Iksemel Jabber library. */
 #undef HAVE_IKSEMEL
 
-/* Define if your system has the ILBC libraries. */
+/* Define to 1 if you have the System iLBC library. */
 #undef HAVE_ILBC
 
 /* Define if your system has the UW IMAP Toolkit c-client library. */
@@ -376,7 +376,7 @@
 /* Define to 1 if you have the OpenLDAP library. */
 #undef HAVE_LDAP
 
-/* Define if your system has the LIBEDIT libraries. */
+/* Define to 1 if you have the NetBSD Editline library library. */
 #undef HAVE_LIBEDIT
 
 /* Define to 1 if you have the <libintl.h> header file. */
@@ -551,7 +551,7 @@
 /* Define to indicate presence of the pg_encoding_to_char API. */
 #undef HAVE_PGSQL_pg_encoding_to_char
 
-/* Define if your system has the PJPROJECT libraries. */
+/* Define to 1 if you have the PJPROJECT library. */
 #undef HAVE_PJPROJECT
 
 /* Define to 1 if your system defines IP_PKTINFO. */
@@ -854,19 +854,19 @@
 /* Define to 1 if you have the `strtoq' function. */
 #undef HAVE_STRTOQ
 
-/* Define to 1 if `ifr_ifru.ifru_hwaddr' is a member of `struct ifreq'. */
+/* Define to 1 if `ifr_ifru.ifru_hwaddr' is member of `struct ifreq'. */
 #undef HAVE_STRUCT_IFREQ_IFR_IFRU_IFRU_HWADDR
 
-/* Define to 1 if `uid' is a member of `struct sockpeercred'. */
+/* Define to 1 if `uid' is member of `struct sockpeercred'. */
 #undef HAVE_STRUCT_SOCKPEERCRED_UID
 
-/* Define to 1 if `st_blksize' is a member of `struct stat'. */
+/* Define to 1 if `st_blksize' is member of `struct stat'. */
 #undef HAVE_STRUCT_STAT_ST_BLKSIZE
 
-/* Define to 1 if `cr_uid' is a member of `struct ucred'. */
+/* Define to 1 if `cr_uid' is member of `struct ucred'. */
 #undef HAVE_STRUCT_UCRED_CR_UID
 
-/* Define to 1 if `uid' is a member of `struct ucred'. */
+/* Define to 1 if `uid' is member of `struct ucred'. */
 #undef HAVE_STRUCT_UCRED_UID
 
 /* Define to 1 if you have the mISDN Supplemental Services library. */
@@ -1144,12 +1144,12 @@
 /* Define to the one symbol short name of this package. */
 #undef PACKAGE_TARNAME
 
-/* Define to the home page for this package. */
-#undef PACKAGE_URL
-
 /* Define to the version of this package. */
 #undef PACKAGE_VERSION
 
+/* Define to 1 if the C compiler supports function prototypes. */
+#undef PROTOTYPES
+
 /* Define to necessary symbol if this constant uses a non-standard name on
    your system. */
 #undef PTHREAD_CREATE_JOINABLE
@@ -1169,6 +1169,11 @@
 /* Define to the type of arg 5 for `select'. */
 #undef SELECT_TYPE_ARG5
 
+/* Define to 1 if the `setvbuf' function takes the buffering type as its
+   second argument and the buffer pointer as the third, as on System V before
+   release 3. */
+#undef SETVBUF_REVERSED
+
 /* The size of `char *', as computed by sizeof. */
 #undef SIZEOF_CHAR_P
 
@@ -1204,39 +1209,24 @@
 /* Define to a type of the same size as fd_set.fds_bits[[0]] */
 #undef TYPEOF_FD_SET_FDS_BITS
 
-/* Enable extensions on AIX 3, Interix.  */
+/* Define to 1 if on AIX 3.
+   System headers sometimes define this.
+   We just want to avoid a redefinition error message.  */
 #ifndef _ALL_SOURCE
 # undef _ALL_SOURCE
 #endif
-/* Enable GNU extensions on systems that have them.  */
-#ifndef _GNU_SOURCE
-# undef _GNU_SOURCE
-#endif
-/* Enable threading extensions on Solaris.  */
-#ifndef _POSIX_PTHREAD_SEMANTICS
-# undef _POSIX_PTHREAD_SEMANTICS
-#endif
-/* Enable extensions on HP NonStop.  */
-#ifndef _TANDEM_SOURCE
-# undef _TANDEM_SOURCE
-#endif
-/* Enable general extensions on Solaris.  */
-#ifndef __EXTENSIONS__
-# undef __EXTENSIONS__
-#endif
-
 
 /* Define to 1 if running on Darwin. */
 #undef _DARWIN_UNLIMITED_SELECT
 
-/* Enable large inode numbers on Mac OS X 10.5.  */
-#ifndef _DARWIN_USE_64_BIT_INODE
-# define _DARWIN_USE_64_BIT_INODE 1
-#endif
-
 /* Number of bits in a file offset, on hosts where this is settable. */
 #undef _FILE_OFFSET_BITS
 
+/* Enable GNU extensions on systems that have them.  */
+#ifndef _GNU_SOURCE
+# undef _GNU_SOURCE
+#endif
+
 /* Define to 1 to make fseeko visible on some hosts (e.g. glibc 2.2). */
 #undef _LARGEFILE_SOURCE
 
@@ -1253,6 +1243,20 @@
 /* Define to 1 if you need to in order for `stat' and other things to work. */
 #undef _POSIX_SOURCE
 
+/* Enable extensions on Solaris.  */
+#ifndef __EXTENSIONS__
+# undef __EXTENSIONS__
+#endif
+#ifndef _POSIX_PTHREAD_SEMANTICS
+# undef _POSIX_PTHREAD_SEMANTICS
+#endif
+#ifndef _TANDEM_SOURCE
+# undef _TANDEM_SOURCE
+#endif
+
+/* Define like PROTOTYPES; this can be used by system headers. */
+#undef __PROTOTYPES
+
 /* Define to empty if `const' does not conform to ANSI C. */
 #undef const
 
diff --git a/include/asterisk/res_sip.h b/include/asterisk/res_sip.h
new file mode 100644
index 0000000000000000000000000000000000000000..7cfc382601796d5c35dfca4b2723ff770da0a422
--- /dev/null
+++ b/include/asterisk/res_sip.h
@@ -0,0 +1,1092 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2013, Digium, Inc.
+ *
+ * Mark Michelson <mmichelson@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+#ifndef _RES_SIP_H
+#define _RES_SIP_H
+
+#include "asterisk/stringfields.h"
+/* Needed for struct ast_sockaddr */
+#include "asterisk/netsock2.h"
+/* Needed for linked list macros */
+#include "asterisk/linkedlists.h"
+/* Needed for ast_party_id */
+#include "asterisk/channel.h"
+/* Needed for ast_sorcery */
+#include "asterisk/sorcery.h"
+/* Needed for ast_dnsmgr */
+#include "asterisk/dnsmgr.h"
+/* Needed for pj_sockaddr */
+#include <pjlib.h>
+
+/* Forward declarations of PJSIP stuff */
+struct pjsip_rx_data;
+struct pjsip_module;
+struct pjsip_tx_data;
+struct pjsip_dialog;
+struct pjsip_transport;
+struct pjsip_tpfactory;
+struct pjsip_tls_setting;
+struct pjsip_tpselector;
+
+/*!
+ * \brief Structure for SIP transport information
+ */
+struct ast_sip_transport_state {
+	/*! \brief Transport itself */
+	struct pjsip_transport *transport;
+
+	/*! \brief Transport factory */
+	struct pjsip_tpfactory *factory;
+};
+
+#define SIP_SORCERY_DOMAIN_ALIAS_TYPE "domain_alias"
+
+/*!
+ * Details about a SIP domain alias
+ */
+struct ast_sip_domain_alias {
+	/*! Sorcery object details */
+	SORCERY_OBJECT(details);
+	AST_DECLARE_STRING_FIELDS(
+		/*! Domain to be aliased to */
+		AST_STRING_FIELD(domain);
+	);
+};
+
+/*!
+ * \brief Types of supported transports
+ */
+enum ast_sip_transport_type {
+	AST_SIP_TRANSPORT_UDP,
+	AST_SIP_TRANSPORT_TCP,
+	AST_SIP_TRANSPORT_TLS,
+	/* XXX Websocket ? */
+};
+
+/*! \brief Maximum number of ciphers supported for a TLS transport */
+#define SIP_TLS_MAX_CIPHERS 64
+
+/*
+ * \brief Transport to bind to
+ */
+struct ast_sip_transport {
+	/*! Sorcery object details */
+	SORCERY_OBJECT(details);
+	AST_DECLARE_STRING_FIELDS(
+		/*! Certificate of authority list file */
+		AST_STRING_FIELD(ca_list_file);
+		/*! Public certificate file */
+		AST_STRING_FIELD(cert_file);
+		/*! Optional private key of the certificate file */
+		AST_STRING_FIELD(privkey_file);
+		/*! Password to open the private key */
+		AST_STRING_FIELD(password);
+		/*! External signaling address */
+		AST_STRING_FIELD(external_signaling_address);
+		/*! External media address */
+		AST_STRING_FIELD(external_media_address);
+		/*! Optional domain to use for messages if provided could not be found */
+		AST_STRING_FIELD(domain);
+		);
+	/*! Type of transport */
+	enum ast_sip_transport_type type;
+	/*! Address and port to bind to */
+	pj_sockaddr host;
+	/*! Number of simultaneous asynchronous operations */
+	unsigned int async_operations;
+	/*! Optional external port for signaling */
+	unsigned int external_signaling_port;
+	/*! TLS settings */
+	pjsip_tls_setting tls;
+	/*! Configured TLS ciphers */
+	pj_ssl_cipher ciphers[SIP_TLS_MAX_CIPHERS];
+	/*! Optional local network information, used for NAT purposes */
+	struct ast_ha *localnet;
+	/*! DNS manager for refreshing the external address */
+	struct ast_dnsmgr_entry *external_address_refresher;
+	/*! Optional external address information */
+	struct ast_sockaddr external_address;
+	/*! Transport state information */
+	struct ast_sip_transport_state *state;
+};
+
+/*!
+ * \brief Structure for SIP nat hook information
+ */
+struct ast_sip_nat_hook {
+	/*! Sorcery object details */
+	SORCERY_OBJECT(details);
+	/*! Callback for when a message is going outside of our local network */
+	void (*outgoing_external_message)(struct pjsip_tx_data *tdata, struct ast_sip_transport *transport);
+};
+
+/*!
+ * \brief Contact associated with an address of record
+ */
+struct ast_sip_contact {
+	/*! Sorcery object details, the id is the aor name plus a random string */
+	SORCERY_OBJECT(details);
+	AST_DECLARE_STRING_FIELDS(
+		/*! Full URI of the contact */
+		AST_STRING_FIELD(uri);
+	);
+	/*! Absolute time that this contact is no longer valid after */
+	struct timeval expiration_time;
+};
+
+/*!
+ * \brief A SIP address of record
+ */
+struct ast_sip_aor {
+	/*! Sorcery object details, the id is the AOR name */
+	SORCERY_OBJECT(details);
+	AST_DECLARE_STRING_FIELDS(
+		/*! Voicemail boxes for this AOR */
+		AST_STRING_FIELD(mailboxes);
+	);
+	/*! Minimum expiration time */
+	unsigned int minimum_expiration;
+	/*! Maximum expiration time */
+	unsigned int maximum_expiration;
+	/*! Default contact expiration if one is not provided in the contact */
+	unsigned int default_expiration;
+	/*! Maximum number of external contacts, 0 to disable */
+	unsigned int max_contacts;
+	/*! Whether to remove any existing contacts not related to an incoming REGISTER when it comes in */
+	unsigned int remove_existing;
+	/*! Any permanent configured contacts */
+	struct ao2_container *permanent_contacts;
+};
+
+/*!
+ * \brief DTMF modes for SIP endpoints
+ */
+enum ast_sip_dtmf_mode {
+	/*! No DTMF to be used */
+	AST_SIP_DTMF_NONE,
+	/* XXX Should this be 2833 instead? */
+	/*! Use RFC 4733 events for DTMF */
+	AST_SIP_DTMF_RFC_4733,
+	/*! Use DTMF in the audio stream */
+	AST_SIP_DTMF_INBAND,
+	/*! Use SIP INFO DTMF (blech) */
+	AST_SIP_DTMF_INFO,
+};
+
+/*!
+ * \brief Methods of storing SIP digest authentication credentials.
+ *
+ * Note that both methods result in MD5 digest authentication being
+ * used. The two methods simply alter how Asterisk determines the
+ * credentials for a SIP authentication
+ */
+enum ast_sip_auth_type {
+	/*! Credentials stored as a username and password combination */
+	AST_SIP_AUTH_TYPE_USER_PASS,
+	/*! Credentials stored as an MD5 sum */
+	AST_SIP_AUTH_TYPE_MD5,
+};
+
+#define SIP_SORCERY_AUTH_TYPE "auth"
+
+struct ast_sip_auth {
+	/* Sorcery ID of the auth is its name */
+	SORCERY_OBJECT(details);
+	AST_DECLARE_STRING_FIELDS(
+		/* Identification for these credentials */
+		AST_STRING_FIELD(realm);
+		/* Authentication username */
+		AST_STRING_FIELD(auth_user);
+		/* Authentication password */
+		AST_STRING_FIELD(auth_pass);
+		/* Authentication credentials in MD5 format (hash of user:realm:pass) */
+		AST_STRING_FIELD(md5_creds);
+	);
+	/* The time period (in seconds) that a nonce may be reused */
+	unsigned int nonce_lifetime;
+	/* Used to determine what to use when authenticating */
+	enum ast_sip_auth_type type;
+};
+
+/*!
+ * \brief Different methods by which incoming requests can be matched to endpoints
+ */
+enum ast_sip_endpoint_identifier_type {
+	/*! Identify based on user name in From header */
+	AST_SIP_ENDPOINT_IDENTIFY_BY_USERNAME = (1 << 0),
+	/*! Identify based on source location of the SIP message */
+	AST_SIP_ENDPOINT_IDENTIFY_BY_LOCATION = (1 << 1),
+};
+
+enum ast_sip_session_refresh_method {
+	/*! Use reinvite to negotiate direct media */
+	AST_SIP_SESSION_REFRESH_METHOD_INVITE,
+	/*! Use UPDATE to negotiate direct media */
+	AST_SIP_SESSION_REFRESH_METHOD_UPDATE,
+};
+
+enum ast_sip_direct_media_glare_mitigation {
+	/*! Take no special action to mitigate reinvite glare */
+	AST_SIP_DIRECT_MEDIA_GLARE_MITIGATION_NONE,
+	/*! Do not send an initial direct media session refresh on outgoing call legs
+	 * Subsequent session refreshes will be sent no matter the session direction
+	 */
+	AST_SIP_DIRECT_MEDIA_GLARE_MITIGATION_OUTGOING,
+	/*! Do not send an initial direct media session refresh on incoming call legs
+	 * Subsequent session refreshes will be sent no matter the session direction
+	 */
+	AST_SIP_DIRECT_MEDIA_GLARE_MITIGATION_INCOMING,
+};
+
+/*!
+ * \brief An entity with which Asterisk communicates
+ */
+struct ast_sip_endpoint {
+	SORCERY_OBJECT(details);
+	AST_DECLARE_STRING_FIELDS(
+		/*! Context to send incoming calls to */
+		AST_STRING_FIELD(context);
+		/*! Name of an explicit transport to use */
+		AST_STRING_FIELD(transport);
+		/*! Outbound proxy to use */
+		AST_STRING_FIELD(outbound_proxy);
+		/*! Explicit AORs to dial if none are specified */
+		AST_STRING_FIELD(aors);
+                /*! Musiconhold class to suggest that the other side use when placing on hold */
+                AST_STRING_FIELD(mohsuggest);
+		/*! Optional external media address to use in SDP */
+		AST_STRING_FIELD(external_media_address);
+		/*! Configured voicemail boxes for this endpoint. Used for MWI */
+		AST_STRING_FIELD(mailboxes);
+	);
+	/*! Identification information for this endpoint */
+	struct ast_party_id id;
+	/*! Domain to which this endpoint belongs */
+	struct ast_sip_domain *domain;
+	/*! Address of record for incoming registrations */
+	struct ast_sip_aor *aor;
+	/*! Codec preferences */
+	struct ast_codec_pref prefs;
+	/*! Configured codecs */
+	struct ast_format_cap *codecs;
+	/*! Names of inbound authentication credentials */
+	const char **sip_inbound_auths;
+	/*! Number of configured auths */
+	size_t num_inbound_auths;
+	/*! Names of outbound authentication credentials */
+	const char **sip_outbound_auths;
+	/*! Number of configured outbound auths */
+	size_t num_outbound_auths;
+	/*! DTMF mode to use with this endpoint */
+	enum ast_sip_dtmf_mode dtmf;
+	/*! Whether IPv6 RTP is enabled or not */
+	unsigned int rtp_ipv6;
+	/*! Whether symmetric RTP is enabled or not */
+	unsigned int rtp_symmetric;
+	/*! Whether ICE support is enabled or not */
+	unsigned int ice_support;
+	/*! Whether to use the "ptime" attribute received from the endpoint or not */
+	unsigned int use_ptime;
+	/*! Whether to force using the source IP address/port for sending responses */
+	unsigned int force_rport;
+	/*! Whether to rewrite the Contact header with the source IP address/port or not */
+	unsigned int rewrite_contact;
+	/*! Enabled SIP extensions */
+	unsigned int extensions;
+	/*! Minimum session expiration period, in seconds */
+	unsigned int min_se;
+	/*! Session expiration period, in seconds */
+	unsigned int sess_expires;
+	/*! List of outbound registrations */
+	AST_LIST_HEAD_NOLOCK(, ast_sip_registration) registrations;
+	/*! Frequency to send OPTIONS requests to endpoint. 0 is disabled. */
+	unsigned int qualify_frequency;
+	/*! Method(s) by which the endpoint should be identified. */
+	enum ast_sip_endpoint_identifier_type ident_method;
+	/*! Boolean indicating if direct_media is permissible */
+	unsigned int direct_media;
+	/*! When using direct media, which method should be used */
+	enum ast_sip_session_refresh_method direct_media_method;
+	/*! Take steps to mitigate glare for direct media */
+	enum ast_sip_direct_media_glare_mitigation direct_media_glare_mitigation;
+	/*! Do not attempt direct media session refreshes if a media NAT is detected */
+	unsigned int disable_direct_media_on_nat;
+	/*! Do we trust the endpoint with our outbound identity? */
+	unsigned int trust_id_outbound;
+	/*! Do we trust identity information that originates externally (e.g. P-Asserted-Identity header)? */
+	unsigned int trust_id_inbound;
+	/*! Do we send P-Asserted-Identity headers to this endpoint? */
+	unsigned int send_pai;
+	/*! Do we send Remote-Party-ID headers to this endpoint? */
+	unsigned int send_rpid;
+	/*! Should unsolicited MWI be aggregated into a single NOTIFY? */
+	unsigned int aggregate_mwi;
+};
+
+/*!
+ * \brief Possible returns from ast_sip_check_authentication
+ */
+enum ast_sip_check_auth_result {
+    /*! Authentication needs to be challenged */
+    AST_SIP_AUTHENTICATION_CHALLENGE,
+    /*! Authentication succeeded */
+    AST_SIP_AUTHENTICATION_SUCCESS,
+    /*! Authentication failed */
+    AST_SIP_AUTHENTICATION_FAILED,
+    /*! Authentication encountered some internal error */
+    AST_SIP_AUTHENTICATION_ERROR,
+};
+
+/*!
+ * \brief An interchangeable way of handling digest authentication for SIP.
+ *
+ * An authenticator is responsible for filling in the callbacks provided below. Each is called from a publicly available
+ * function in res_sip. The authenticator can use configuration or other local policy to determine whether authentication
+ * should take place and what credentials should be used when challenging and authenticating a request.
+ */
+struct ast_sip_authenticator {
+    /*!
+     * \brief Check if a request requires authentication
+     * See ast_sip_requires_authentication for more details
+     */
+    int (*requires_authentication)(struct ast_sip_endpoint *endpoint, pjsip_rx_data *rdata);
+	/*!
+	 * \brief Check that an incoming request passes authentication.
+	 *
+	 * The tdata parameter is useful for adding information such as digest challenges.
+	 *
+	 * \param endpoint The endpoint sending the incoming request
+	 * \param rdata The incoming request
+	 * \param tdata Tentative outgoing request.
+	 */
+	enum ast_sip_check_auth_result (*check_authentication)(struct ast_sip_endpoint *endpoint,
+			pjsip_rx_data *rdata, pjsip_tx_data *tdata);
+};
+
+/*!
+ * \brief an interchangeable way of responding to authentication challenges
+ *
+ * An outbound authenticator takes incoming challenges and formulates a new SIP request with
+ * credentials.
+ */
+struct ast_sip_outbound_authenticator {
+	/*!
+	 * \brief Create a new request with authentication credentials
+	 *
+	 * \param auths An array of IDs of auth sorcery objects
+	 * \param num_auths The number of IDs in the array
+	 * \param challenge The SIP response with authentication challenge(s)
+	 * \param tsx The transaction in which the challenge was received
+	 * \param new_request The new SIP request with challenge response(s)
+	 * \retval 0 Successfully created new request
+	 * \retval -1 Failed to create a new request
+	 */
+	int (*create_request_with_auth)(const char **auths, size_t num_auths, struct pjsip_rx_data *challenge,
+			struct pjsip_transaction *tsx, struct pjsip_tx_data **new_request);
+};
+
+/*!
+ * \brief An entity responsible for identifying the source of a SIP message
+ */
+struct ast_sip_endpoint_identifier {
+    /*!
+     * \brief Callback used to identify the source of a message.
+     * See ast_sip_identify_endpoint for more details
+     */
+    struct ast_sip_endpoint *(*identify_endpoint)(pjsip_rx_data *rdata);
+};
+
+/*!
+ * \brief Register a SIP service in Asterisk.
+ *
+ * This is more-or-less a wrapper around pjsip_endpt_register_module().
+ * Registering a service makes it so that PJSIP will call into the
+ * service at appropriate times. For more information about PJSIP module
+ * callbacks, see the PJSIP documentation. Asterisk modules that call
+ * this function will likely do so at module load time.
+ *
+ * \param module The module that is to be registered with PJSIP
+ * \retval 0 Success
+ * \retval -1 Failure
+ */
+int ast_sip_register_service(pjsip_module *module);
+
+/*!
+ * This is the opposite of ast_sip_register_service().  Unregistering a
+ * service means that PJSIP will no longer call into the module any more.
+ * This will likely occur when an Asterisk module is unloaded.
+ *
+ * \param module The PJSIP module to unregister
+ */
+void ast_sip_unregister_service(pjsip_module *module);
+
+/*!
+ * \brief Register a SIP authenticator
+ *
+ * An authenticator has three main purposes:
+ * 1) Determining if authentication should be performed on an incoming request
+ * 2) Gathering credentials necessary for issuing an authentication challenge
+ * 3) Authenticating a request that has credentials
+ *
+ * Asterisk provides a default authenticator, but it may be replaced by a
+ * custom one if desired.
+ *
+ * \param auth The authenticator to register
+ * \retval 0 Success
+ * \retval -1 Failure
+ */
+int ast_sip_register_authenticator(struct ast_sip_authenticator *auth);
+
+/*!
+ * \brief Unregister a SIP authenticator
+ *
+ * When there is no authenticator registered, requests cannot be challenged
+ * or authenticated.
+ *
+ * \param auth The authenticator to unregister
+ */
+void ast_sip_unregister_authenticator(struct ast_sip_authenticator *auth);
+
+ /*!
+ * \brief Register an outbound SIP authenticator
+ *
+ * An outbound authenticator is responsible for creating responses to
+ * authentication challenges by remote endpoints.
+ *
+ * \param auth The authenticator to register
+ * \retval 0 Success
+ * \retval -1 Failure
+ */
+int ast_sip_register_outbound_authenticator(struct ast_sip_outbound_authenticator *outbound_auth);
+
+/*!
+ * \brief Unregister an outbound SIP authenticator
+ *
+ * When there is no outbound authenticator registered, authentication challenges
+ * will be handled as any other final response would be.
+ *
+ * \param auth The authenticator to unregister
+ */
+void ast_sip_unregister_outbound_authenticator(struct ast_sip_outbound_authenticator *auth);
+
+/*!
+ * \brief Register a SIP endpoint identifier
+ *
+ * An endpoint identifier's purpose is to determine which endpoint a given SIP
+ * message has come from.
+ *
+ * Multiple endpoint identifiers may be registered so that if an endpoint
+ * cannot be identified by one identifier, it may be identified by another.
+ *
+ * Asterisk provides two endpoint identifiers. One identifies endpoints based
+ * on the user part of the From header URI. The other identifies endpoints based
+ * on the source IP address.
+ *
+ * If the order in which endpoint identifiers is run is important to you, then
+ * be sure to load individual endpoint identifier modules in the order you wish
+ * for them to be run in modules.conf
+ *
+ * \param identifier The SIP endpoint identifier to register
+ * \retval 0 Success
+ * \retval -1 Failure
+ */
+int ast_sip_register_endpoint_identifier(struct ast_sip_endpoint_identifier *identifier);
+
+/*!
+ * \brief Unregister a SIP endpoint identifier
+ *
+ * This stops an endpoint identifier from being used.
+ *
+ * \param identifier The SIP endoint identifier to unregister
+ */
+void ast_sip_unregister_endpoint_identifier(struct ast_sip_endpoint_identifier *identifier);
+
+/*!
+ * \brief Allocate a new SIP endpoint
+ *
+ * This will return an endpoint with its refcount increased by one. This reference
+ * can be released using ao2_ref().
+ *
+ * \param name The name of the endpoint.
+ * \retval NULL Endpoint allocation failed
+ * \retval non-NULL The newly allocated endpoint
+ */
+void *ast_sip_endpoint_alloc(const char *name);
+
+/*!
+ * \brief Get a pointer to the PJSIP endpoint.
+ *
+ * This is useful when modules have specific information they need
+ * to register with the PJSIP core.
+ * \retval NULL endpoint has not been created yet.
+ * \retval non-NULL PJSIP endpoint.
+ */
+pjsip_endpoint *ast_sip_get_pjsip_endpoint(void);
+
+/*!
+ * \brief Get a pointer to the SIP sorcery structure.
+ *
+ * \retval NULL sorcery has not been initialized
+ * \retval non-NULL sorcery structure
+ */
+struct ast_sorcery *ast_sip_get_sorcery(void);
+
+/*!
+ * \brief Initialize transport support on a sorcery instance
+ *
+ * \param sorcery The sorcery instance
+ *
+ * \retval -1 failure
+ * \retval 0 success
+ */
+int ast_sip_initialize_sorcery_transport(struct ast_sorcery *sorcery);
+
+/*!
+ * \brief Initialize location support on a sorcery instance
+ *
+ * \param sorcery The sorcery instance
+ *
+ * \retval -1 failure
+ * \retval 0 success
+ */
+int ast_sip_initialize_sorcery_location(struct ast_sorcery *sorcery);
+
+/*!
+ * \brief Retrieve a named AOR
+ *
+ * \param aor_name Name of the AOR
+ *
+ * \retval NULL if not found
+ * \retval non-NULL if found
+ */
+struct ast_sip_aor *ast_sip_location_retrieve_aor(const char *aor_name);
+
+/*!
+ * \brief Retrieve the first bound contact for an AOR
+ *
+ * \param aor Pointer to the AOR
+ * \retval NULL if no contacts available
+ * \retval non-NULL if contacts available
+ */
+struct ast_sip_contact *ast_sip_location_retrieve_first_aor_contact(const struct ast_sip_aor *aor);
+
+/*!
+ * \brief Retrieve all contacts currently available for an AOR
+ *
+ * \param aor Pointer to the AOR
+ *
+ * \retval NULL if no contacts available
+ * \retval non-NULL if contacts available
+ */
+struct ao2_container *ast_sip_location_retrieve_aor_contacts(const struct ast_sip_aor *aor);
+
+/*!
+ * \brief Retrieve the first bound contact from a list of AORs
+ *
+ * \param aor_list A comma-separated list of AOR names
+ * \retval NULL if no contacts available
+ * \retval non-NULL if contacts available
+ */
+struct ast_sip_contact *ast_sip_location_retrieve_contact_from_aor_list(const char *aor_list);
+
+/*!
+ * \brief Retrieve a named contact
+ *
+ * \param contact_name Name of the contact
+ *
+ * \retval NULL if not found
+ * \retval non-NULL if found
+ */
+struct ast_sip_contact *ast_sip_location_retrieve_contact(const char *contact_name);
+
+/*!
+ * \brief Add a new contact to an AOR
+ *
+ * \param aor Pointer to the AOR
+ * \param uri Full contact URI
+ * \param expiration_time Optional expiration time of the contact
+ *
+ * \retval -1 failure
+ * \retval 0 success
+ */
+int ast_sip_location_add_contact(struct ast_sip_aor *aor, const char *uri, struct timeval expiration_time);
+
+/*!
+ * \brief Update a contact
+ *
+ * \param contact New contact object with details
+ *
+ * \retval -1 failure
+ * \retval 0 success
+ */
+int ast_sip_location_update_contact(struct ast_sip_contact *contact);
+
+/*!
+* \brief Delete a contact
+*
+* \param contact Contact object to delete
+*
+* \retval -1 failure
+* \retval 0 success
+*/
+int ast_sip_location_delete_contact(struct ast_sip_contact *contact);
+
+/*!
+ * \brief Initialize domain aliases support on a sorcery instance
+ *
+ * \param sorcery The sorcery instance
+ *
+ * \retval -1 failure
+ * \retval 0 success
+ */
+int ast_sip_initialize_sorcery_domain_alias(struct ast_sorcery *sorcery);
+
+/*!
+ * \brief Initialize authentication support on a sorcery instance
+ *
+ * \param sorcery The sorcery instance
+ *
+ * \retval -1 failure
+ * \retval 0 success
+ */
+int ast_sip_initialize_sorcery_auth(struct ast_sorcery *sorcery);
+
+/*!
+ * \brief Callback called when an outbound request with authentication credentials is to be sent in dialog
+ *
+ * This callback will have the created request on it. The callback's purpose is to do any extra
+ * housekeeping that needs to be done as well as to send the request out.
+ *
+ * This callback is only necessary if working with a PJSIP API that sits between the application
+ * and the dialog layer.
+ *
+ * \param dlg The dialog to which the request belongs
+ * \param tdata The created request to be sent out
+ * \param user_data Data supplied with the callback
+ *
+ * \retval 0 Success
+ * \retval -1 Failure
+ */
+typedef int (*ast_sip_dialog_outbound_auth_cb)(pjsip_dialog *dlg, pjsip_tx_data *tdata, void *user_data);
+
+/*!
+ * \brief Set up outbound authentication on a SIP dialog
+ *
+ * This sets up the infrastructure so that all requests associated with a created dialog
+ * can be re-sent with authentication credentials if the original request is challenged.
+ *
+ * \param dlg The dialog on which requests will be authenticated
+ * \param endpoint The endpoint whom this dialog pertains to
+ * \param cb Callback to call to send requests with authentication
+ * \param user_data Data to be provided to the callback when it is called
+ *
+ * \retval 0 Success
+ * \retval -1 Failure
+ */
+int ast_sip_dialog_setup_outbound_authentication(pjsip_dialog *dlg, const struct ast_sip_endpoint *endpoint,
+		ast_sip_dialog_outbound_auth_cb cb, void *user_data);
+
+/*!
+ * \brief Initialize the distributor module
+ *
+ * The distributor module is responsible for taking an incoming
+ * SIP message and placing it into the threadpool. Once in the threadpool,
+ * the distributor will perform endpoint lookups and authentication, and
+ * then distribute the message up the stack to any further modules.
+ *
+ * \retval -1 Failure
+ * \retval 0 Success
+ */
+int ast_sip_initialize_distributor(void);
+
+/*!
+ * \page Threading model for SIP
+ *
+ * There are three major types of threads that SIP will have to deal with:
+ * \li Asterisk threads
+ * \li PJSIP threads
+ * \li SIP threadpool threads (a.k.a. "servants")
+ *
+ * \par Asterisk Threads
+ *
+ * Asterisk threads are those that originate from outside of SIP but within
+ * Asterisk. The most common of these threads are PBX (channel) threads and
+ * the autoservice thread. Most interaction with these threads will be through
+ * channel technology callbacks. Within these threads, it is fine to handle
+ * Asterisk data from outside of SIP, but any handling of SIP data should be
+ * left to servants, \b especially if you wish to call into PJSIP for anything.
+ * Asterisk threads are not registered with PJLIB, so attempting to call into
+ * PJSIP will cause an assertion to be triggered, thus causing the program to
+ * crash.
+ *
+ * \par PJSIP Threads
+ *
+ * PJSIP threads are those that originate from handling of PJSIP events, such
+ * as an incoming SIP request or response, or a transaction timeout. The role
+ * of these threads is to process information as quickly as possible so that
+ * the next item on the SIP socket(s) can be serviced. On incoming messages,
+ * Asterisk automatically will push the request to a servant thread. When your
+ * module callback is called, processing will already be in a servant. However,
+ * for other PSJIP events, such as transaction state changes due to timer
+ * expirations, your module will be called into from a PJSIP thread. If you
+ * are called into from a PJSIP thread, then you should push whatever processing
+ * is needed to a servant as soon as possible. You can discern if you are currently
+ * in a SIP servant thread using the \ref ast_sip_thread_is_servant function.
+ *
+ * \par Servants
+ *
+ * Servants are where the bulk of SIP work should be performed. These threads
+ * exist in order to do the work that Asterisk threads and PJSIP threads hand
+ * off to them. Servant threads register themselves with PJLIB, meaning that
+ * they are capable of calling PJSIP and PJLIB functions if they wish.
+ *
+ * \par Serializer
+ *
+ * Tasks are handed off to servant threads using the API call \ref ast_sip_push_task.
+ * The first parameter of this call is a serializer. If this pointer
+ * is NULL, then the work will be handed off to whatever servant can currently handle
+ * the task. If this pointer is non-NULL, then the task will not be executed until
+ * previous tasks pushed with the same serializer have completed. For more information
+ * on serializers and the benefits they provide, see \ref ast_threadpool_serializer
+ *
+ * \note
+ *
+ * Do not make assumptions about individual threads based on a corresponding serializer.
+ * In other words, just because several tasks use the same serializer when being pushed
+ * to servants, it does not mean that the same thread is necessarily going to execute those
+ * tasks, even though they are all guaranteed to be executed in sequence.
+ */
+
+/*!
+ * \brief Create a new serializer for SIP tasks
+ *
+ * See \ref ast_threadpool_serializer for more information on serializers.
+ * SIP creates serializers so that tasks operating on similar data will run
+ * in sequence.
+ *
+ * \retval NULL Failure
+ * \retval non-NULL Newly-created serializer
+ */
+struct ast_taskprocessor *ast_sip_create_serializer(void);
+
+/*!
+ * \brief Set a serializer on a SIP dialog so requests and responses are automatically serialized
+ *
+ * Passing a NULL serializer is a way to remove a serializer from a dialog.
+ *
+ * \param dlg The SIP dialog itself
+ * \param serializer The serializer to use
+ */
+void ast_sip_dialog_set_serializer(pjsip_dialog *dlg, struct ast_taskprocessor *serializer);
+
+/*!
+ * \brief Set an endpoint on a SIP dialog so in-dialog requests do not undergo endpoint lookup.
+ *
+ * \param dlg The SIP dialog itself
+ * \param endpoint The endpoint that this dialog is communicating with
+ */
+void ast_sip_dialog_set_endpoint(pjsip_dialog *dlg, struct ast_sip_endpoint *endpoint);
+
+/*!
+ * \brief Get the endpoint associated with this dialog
+ *
+ * This function increases the refcount of the endpoint by one. Release
+ * the reference once you are finished with the endpoint.
+ *
+ * \param dlg The SIP dialog from which to retrieve the endpoint
+ * \retval NULL No endpoint associated with this dialog
+ * \retval non-NULL The endpoint.
+ */
+struct ast_sip_endpoint *ast_sip_dialog_get_endpoint(pjsip_dialog *dlg);
+
+/*!
+ * \brief Pushes a task to SIP servants
+ *
+ * This uses the serializer provided to determine how to push the task.
+ * If the serializer is NULL, then the task will be pushed to the
+ * servants directly. If the serializer is non-NULL, then the task will be
+ * queued behind other tasks associated with the same serializer.
+ *
+ * \param serializer The serializer to which the task belongs. Can be NULL
+ * \param sip_task The task to execute
+ * \param task_data The parameter to pass to the task when it executes
+ * \retval 0 Success
+ * \retval -1 Failure
+ */
+int ast_sip_push_task(struct ast_taskprocessor *serializer, int (*sip_task)(void *), void *task_data);
+
+/*!
+ * \brief Push a task to SIP servants and wait for it to complete
+ *
+ * Like \ref ast_sip_push_task except that it blocks until the task completes.
+ *
+ * \warning \b Never use this function in a SIP servant thread. This can potentially
+ * cause a deadlock. If you are in a SIP servant thread, just call your function
+ * in-line.
+ *
+ * \param serializer The SIP serializer to which the task belongs. May be NULL.
+ * \param sip_task The task to execute
+ * \param task_data The parameter to pass to the task when it executes
+ * \retval 0 Success
+ * \retval -1 Failure
+ */
+int ast_sip_push_task_synchronous(struct ast_taskprocessor *serializer, int (*sip_task)(void *), void *task_data);
+
+/*!
+ * \brief Determine if the current thread is a SIP servant thread
+ *
+ * \retval 0 This is not a SIP servant thread
+ * \retval 1 This is a SIP servant thread
+ */
+int ast_sip_thread_is_servant(void);
+
+/*!
+ * \brief SIP body description
+ *
+ * This contains a type and subtype that will be added as
+ * the "Content-Type" for the message as well as the body
+ * text.
+ */
+struct ast_sip_body {
+	/*! Type of the body, such as "application" */
+	const char *type;
+	/*! Subtype of the body, such as "sdp" */
+	const char *subtype;
+	/*! The text to go in the body */
+	const char *body_text;
+};
+
+/*!
+ * \brief General purpose method for creating a dialog with an endpoint
+ *
+ * \param endpoint A pointer to the endpoint
+ * \param aor_name Optional name of the AOR to target, may even be an explicit SIP URI
+ * \param request_user Optional user to place into the target URI
+ *
+ * \retval non-NULL success
+ * \retval NULL failure
+ */
+ pjsip_dialog *ast_sip_create_dialog(const struct ast_sip_endpoint *endpoint, const char *aor_name, const char *request_user);
+
+/*!
+ * \brief General purpose method for creating a SIP request
+ *
+ * Its typical use would be to create one-off requests such as an out of dialog
+ * SIP MESSAGE.
+ *
+ * The request can either be in- or out-of-dialog. If in-dialog, the
+ * dlg parameter MUST be present. If out-of-dialog the endpoint parameter
+ * MUST be present. If both are present, then we will assume that the message
+ * is to be sent in-dialog.
+ *
+ * The uri parameter can be specified if the request should be sent to an explicit
+ * URI rather than one configured on the endpoint.
+ *
+ * \param method The method of the SIP request to send
+ * \param dlg Optional. If specified, the dialog on which to request the message.
+ * \param endpoint Optional. If specified, the request will be created out-of-dialog
+ * to the endpoint.
+ * \param uri Optional. If specified, the request will be sent to this URI rather
+ * than one configured for the endpoint.
+ * \param[out] tdata The newly-created request
+ * \retval 0 Success
+ * \retval -1 Failure
+ */
+int ast_sip_create_request(const char *method, struct pjsip_dialog *dlg,
+		struct ast_sip_endpoint *endpoint, const char *uri, pjsip_tx_data **tdata);
+
+/*!
+ * \brief General purpose method for sending a SIP request
+ *
+ * This is a companion function for \ref ast_sip_create_request. The request
+ * created there can be passed to this function, though any request may be
+ * passed in.
+ *
+ * This will automatically set up handling outbound authentication challenges if
+ * they arrive.
+ *
+ * \param tdata The request to send
+ * \param dlg Optional. If specified, the dialog on which the request should be sent
+ * \param endpoint Optional. If specified, the request is sent out-of-dialog to the endpoint.
+ * \retval 0 Success
+ * \retval -1 Failure
+ */
+int ast_sip_send_request(pjsip_tx_data *tdata, struct pjsip_dialog *dlg, struct ast_sip_endpoint *endpoint);
+
+/*!
+ * \brief Determine if an incoming request requires authentication
+ *
+ * This calls into the registered authenticator's requires_authentication callback
+ * in order to determine if the request requires authentication.
+ *
+ * If there is no registered authenticator, then authentication will be assumed
+ * not to be required.
+ *
+ * \param endpoint The endpoint from which the request originates
+ * \param rdata The incoming SIP request
+ * \retval non-zero The request requires authentication
+ * \retval 0 The request does not require authentication
+ */
+int ast_sip_requires_authentication(struct ast_sip_endpoint *endpoint, pjsip_rx_data *rdata);
+
+/*!
+ * \brief Method to determine authentication status of an incoming request
+ *
+ * This will call into a registered authenticator. The registered authenticator will
+ * do what is necessary to determine whether the incoming request passes authentication.
+ * A tentative response is passed into this function so that if, say, a digest authentication
+ * challenge should be sent in the ensuing response, it can be added to the response.
+ *
+ * \param endpoint The endpoint from the request was sent
+ * \param rdata The request to potentially authenticate
+ * \param tdata Tentative response to the request
+ * \return The result of checking authentication.
+ */
+enum ast_sip_check_auth_result ast_sip_check_authentication(struct ast_sip_endpoint *endpoint,
+		pjsip_rx_data *rdata, pjsip_tx_data *tdata);
+
+/*!
+ * \brief Create a response to an authentication challenge
+ *
+ * This will call into an outbound authenticator's create_request_with_auth callback
+ * to create a new request with authentication credentials. See the create_request_with_auth
+ * callback in the \ref ast_sip_outbound_authenticator structure for details about
+ * the parameters and return values.
+ */
+int ast_sip_create_request_with_auth(const char **auths, size_t num_auths, pjsip_rx_data *challenge,
+		pjsip_transaction *tsx, pjsip_tx_data **new_request);
+
+/*!
+ * \brief Determine the endpoint that has sent a SIP message
+ *
+ * This will call into each of the registered endpoint identifiers'
+ * identify_endpoint() callbacks until one returns a non-NULL endpoint.
+ * This will return an ao2 object. Its reference count will need to be
+ * decremented when completed using the endpoint.
+ *
+ * \param rdata The inbound SIP message to use when identifying the endpoint.
+ * \retval NULL No matching endpoint
+ * \retval non-NULL The matching endpoint
+ */
+struct ast_sip_endpoint *ast_sip_identify_endpoint(pjsip_rx_data *rdata);
+
+/*!
+ * \brief Add a header to an outbound SIP message
+ *
+ * \param tdata The message to add the header to
+ * \param name The header name
+ * \param value The header value
+ * \retval 0 Success
+ * \retval -1 Failure
+ */
+int ast_sip_add_header(pjsip_tx_data *tdata, const char *name, const char *value);
+
+/*!
+ * \brief Add a body to an outbound SIP message
+ *
+ * If this is called multiple times, the latest body will replace the current
+ * body.
+ *
+ * \param tdata The message to add the body to
+ * \param body The message body to add
+ * \retval 0 Success
+ * \retval -1 Failure
+ */
+int ast_sip_add_body(pjsip_tx_data *tdata, const struct ast_sip_body *body);
+
+/*!
+ * \brief Add a multipart body to an outbound SIP message
+ *
+ * This will treat each part of the input array as part of a multipart body and
+ * add each part to the SIP message.
+ *
+ * \param tdata The message to add the body to
+ * \param bodies The parts of the body to add
+ * \retval 0 Success
+ * \retval -1 Failure
+ */
+int ast_sip_add_body_multipart(pjsip_tx_data *tdata, const struct ast_sip_body *bodies[], int num_bodies);
+
+/*!
+ * \brief Append body data to a SIP message
+ *
+ * This acts mostly the same as ast_sip_add_body, except that rather than replacing
+ * a body if it currently exists, it appends data to an existing body.
+ *
+ * \param tdata The message to append the body to
+ * \param body The string to append to the end of the current body
+ * \retval 0 Success
+ * \retval -1 Failure
+ */
+int ast_sip_append_body(pjsip_tx_data *tdata, const char *body_text);
+
+/*!
+ * \brief Copy a pj_str_t into a standard character buffer.
+ *
+ * pj_str_t is not NULL-terminated. Any place that expects a NULL-
+ * terminated string needs to have the pj_str_t copied into a separate
+ * buffer.
+ *
+ * This method copies the pj_str_t contents into the destination buffer
+ * and NULL-terminates the buffer.
+ *
+ * \param dest The destination buffer
+ * \param src The pj_str_t to copy
+ * \param size The size of the destination buffer.
+ */
+void ast_copy_pj_str(char *dest, pj_str_t *src, size_t size);
+
+/*!
+ * \brief Get the looked-up endpoint on an out-of dialog request or response
+ *
+ * The function may ONLY be called on out-of-dialog requests or responses. For
+ * in-dialog requests and responses, it is required that the user of the dialog
+ * has the looked-up endpoint stored locally.
+ *
+ * This function should never return NULL if the message is out-of-dialog. It will
+ * always return NULL if the message is in-dialog.
+ *
+ * This function will increase the reference count of the returned endpoint by one.
+ * Release your reference using the ao2_ref function when finished.
+ *
+ * \param rdata Out-of-dialog request or response
+ * \return The looked up endpoint
+ */
+struct ast_sip_endpoint *ast_pjsip_rdata_get_endpoint(pjsip_rx_data *rdata);
+
+/*!
+ * \brief Retrieve relevant SIP auth structures from sorcery
+ *
+ * \param auth_names The sorcery IDs of auths to retrieve
+ * \param num_auths The number of auths to retrieve
+ * \param[out] out The retrieved auths are stored here
+ */
+int ast_sip_retrieve_auths(const char *auth_names[], size_t num_auths, struct ast_sip_auth **out);
+
+/*!
+ * \brief Clean up retrieved auth structures from memory
+ *
+ * Call this function once you have completed operating on auths
+ * retrieved from \ref ast_sip_retrieve_auths
+ *
+ * \param auths An array of auth structures to clean up
+ * \param num_auths The number of auths in the array
+ */
+void ast_sip_cleanup_auths(struct ast_sip_auth *auths[], size_t num_auths);
+
+#endif /* _RES_SIP_H */
diff --git a/include/asterisk/res_sip_pubsub.h b/include/asterisk/res_sip_pubsub.h
new file mode 100644
index 0000000000000000000000000000000000000000..33614b2853c1aa054da3a56d60de47fd600661c4
--- /dev/null
+++ b/include/asterisk/res_sip_pubsub.h
@@ -0,0 +1,346 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2013, Digium, Inc.
+ *
+ * Mark Michelson <mmichelson@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+#ifndef _RES_SIP_PUBSUB_H
+#define _RES_SIP_PUBSUB_H
+
+#include "asterisk/linkedlists.h"
+
+/* Forward declarations */
+struct pjsip_rx_data;
+struct pjsip_tx_data;
+struct pjsip_evsub;
+struct ast_sip_endpoint;
+struct ast_datastore;
+struct ast_datastore_info;
+
+/*!
+ * \brief Opaque structure representing an RFC 3265 SIP subscription
+ */
+struct ast_sip_subscription;
+ 
+/*!
+ * \brief Role for the subscription that is being created
+ */
+enum ast_sip_subscription_role {
+    /* Sending SUBSCRIBEs, receiving NOTIFYs */
+    AST_SIP_SUBSCRIBER,
+    /* Sending NOTIFYs, receiving SUBSCRIBEs */
+    AST_SIP_NOTIFIER,
+};
+
+/*!
+ * \brief Data for responses to SUBSCRIBEs and NOTIFIEs
+ *
+ * Some of PJSIP's evsub callbacks expect us to provide them
+ * with data so that they can craft a response rather than have
+ * us create our own response.
+ *
+ * Filling in the structure is optional, since the framework
+ * will automatically respond with a 200 OK response if we do
+ * not provide it with any additional data.
+ */
+struct ast_sip_subscription_response_data {
+    /*! Status code of the response */
+    int status_code;
+    /*! Optional status text */
+    const char *status_text;
+    /*! Optional additional headers to add to the response */
+    struct ast_variable *headers;
+    /*! Optional body to add to the response */
+    struct ast_sip_body *body;
+};
+
+#define AST_SIP_MAX_ACCEPT 32
+
+struct ast_sip_subscription_handler {
+    /*! The name of the event this handler deals with */
+    const char *event_name;
+    /*! The types of body this handler accepts */
+    const char *accept[AST_SIP_MAX_ACCEPT];
+ 
+    /*!
+     * \brief Called when a subscription is to be destroyed
+     *
+     * This is a subscriber and notifier callback.
+     *
+     * The handler is not expected to send any sort of requests or responses
+     * during this callback. The handler MUST, however, begin the destruction
+	 * process for the subscription during this callback.
+     */
+   void (*subscription_shutdown)(struct ast_sip_subscription *subscription);
+ 
+    /*!
+     * \brief Called when a SUBSCRIBE arrives in order to create a new subscription
+     *
+     * This is a notifier callback.
+     *
+     * If the notifier wishes to accept the subscription, then it can create
+     * a new ast_sip_subscription to do so. 
+     *
+     * If the notifier chooses to create a new subscription, then it must accept
+     * the incoming subscription using pjsip_evsub_accept() and it must also
+     * send an initial NOTIFY with the current subscription state.
+     *
+     * \param endpoint The endpoint from which we received the SUBSCRIBE
+     * \param rdata The SUBSCRIBE request
+     * \retval NULL The SUBSCRIBE has not been accepted
+     * \retval non-NULL The newly-created subscription
+     */
+    struct ast_sip_subscription *(*new_subscribe)(struct ast_sip_endpoint *endpoint,
+            pjsip_rx_data *rdata);
+ 
+    /*!
+     * \brief Called when an endpoint renews a subscription.
+     *
+     * This is a notifier callback.
+     *
+     * Because of the way that the PJSIP evsub framework works, it will automatically
+     * send a response to the SUBSCRIBE. However, the subscription handler must send
+	 * a NOTIFY with the current subscription state when this callback is called.
+	 *
+	 * The response_data that is passed into this callback is used to craft what should
+	 * be in the response to the incoming SUBSCRIBE. It is initialized with a 200 status
+	 * code and all other parameters are empty.
+     *
+     * \param sub The subscription that is being renewed
+     * \param rdata The SUBSCRIBE request in question
+	 * \param[out] response_data Data pertaining to the SIP response that should be
+	 * sent to the SUBSCRIBE
+     */
+    void (*resubscribe)(struct ast_sip_subscription *sub,
+            pjsip_rx_data *rdata, struct ast_sip_subscription_response_data *response_data);
+ 
+    /*!
+     * \brief Called when a subscription times out.
+     *
+     * This is a notifier callback
+     *
+     * This indicates that the subscription has timed out. The subscription handler is
+     * expected to send a NOTIFY that terminates the subscription.
+     *
+     * \param sub The subscription that has timed out
+     */
+    void (*subscription_timeout)(struct ast_sip_subscription *sub);
+ 
+    /*!
+     * \brief Called when a subscription is terminated via a SUBSCRIBE or NOTIFY request
+     *
+     * This is a notifier and subscriber callback.
+     *
+     * The PJSIP subscription framework will automatically send the response to the
+     * request. If a notifier receives this callback, then the subscription handler
+	 * is expected to send a final NOTIFY to terminate the subscription.
+     *
+     * \param sub The subscription being terminated
+     * \param rdata The request that terminated the subscription
+     */
+    void (*subscription_terminated)(struct ast_sip_subscription *sub, pjsip_rx_data *rdata);
+ 
+    /*!
+     * \brief Called when a subscription handler's outbound NOTIFY receives a response
+     *
+     * This is a notifier callback.
+     *
+     * \param sub The subscription
+     * \param rdata The NOTIFY response
+     */
+    void (*notify_response)(struct ast_sip_subscription *sub, pjsip_rx_data *rdata);
+ 
+    /*!
+     * \brief Called when a subscription handler receives an inbound NOTIFY
+     *
+     * This is a subscriber callback.
+     *
+     * Because of the way that the PJSIP evsub framework works, it will automatically
+     * send a response to the NOTIFY. By default this will be a 200 OK response, but
+     * this callback can change details of the response by returning response data
+     * to use.
+	 *
+	 * The response_data that is passed into this callback is used to craft what should
+	 * be in the response to the incoming SUBSCRIBE. It is initialized with a 200 status
+	 * code and all other parameters are empty.
+     *
+     * \param sub The subscription
+     * \param rdata The NOTIFY request
+	 * \param[out] response_data Data pertaining to the SIP response that should be
+	 * sent to the SUBSCRIBE
+     */
+    void (*notify_request)(struct ast_sip_subscription *sub,
+            pjsip_rx_data *rdata, struct ast_sip_subscription_response_data *response_data);
+ 
+    /*!
+     * \brief Called when it is time for a subscriber to resubscribe
+     *
+     * This is a subscriber callback.
+     *
+     * The subscriber can reresh the subscription using the pjsip_evsub_initiate()
+     * function.
+     *
+     * \param sub The subscription to refresh
+     * \retval 0 Success
+     * \retval non-zero Failure
+     */
+    int (*refresh_subscription)(struct ast_sip_subscription *sub);
+	AST_LIST_ENTRY(ast_sip_subscription_handler) next;
+};
+
+/*!
+ * \brief Create a new ast_sip_subscription structure
+ *
+ * In most cases the pubsub core will create a general purpose subscription
+ * within PJSIP. However, PJSIP provides enhanced support for the following
+ * event packages:
+ *
+ * presence
+ * message-summary
+ *
+ * If either of these events are handled by the subscription handler, then
+ * the special-purpose event subscriptions will be created within PJSIP,
+ * and it will be expected that your subscription handler make use of the
+ * special PJSIP APIs.
+ *
+ * \param handler The subsription handler for this subscription
+ * \param role Whether we are acting as subscriber or notifier for this subscription
+ * \param endpoint The endpoint involved in this subscription
+ * \param rdata If acting as a notifier, the SUBSCRIBE request that triggered subscription creation
+ */
+struct ast_sip_subscription *ast_sip_create_subscription(const struct ast_sip_subscription_handler *handler,
+        enum ast_sip_subscription_role role, struct ast_sip_endpoint *endpoint, pjsip_rx_data *rdata);
+ 
+ 
+/*!
+ * \brief Get the endpoint that is associated with this subscription
+ *
+ * This function will increase the reference count of the endpoint. Be sure to
+ * release the reference to it when you are finished with the endpoint.
+ *
+ * \retval NULL Could not get endpoint
+ * \retval non-NULL The endpoint
+ */
+struct ast_sip_endpoint *ast_sip_subscription_get_endpoint(struct ast_sip_subscription *sub);
+ 
+/*!
+ * \brief Get the serializer for the subscription
+ *
+ * Tasks that originate outside of a SIP servant thread should get the serializer
+ * and push the task to the serializer.
+ *
+ * \param sub The subscription
+ * \retval NULL Failure
+ * \retval non-NULL The subscription's serializer
+ */
+struct ast_taskprocessor *ast_sip_subscription_get_serializer(struct ast_sip_subscription *sub);
+ 
+/*!
+ * \brief Get the underlying PJSIP evsub structure
+ *
+ * This is useful when wishing to call PJSIP's API calls in order to
+ * create SUBSCRIBEs, NOTIFIES, etc. as well as get subscription state
+ *
+ * This function, as well as all methods called on the pjsip_evsub should
+ * be done in a SIP servant thread.
+ *
+ * \param sub The subscription
+ * \retval NULL Failure
+ * \retval non-NULL The underlying pjsip_evsub
+ */
+pjsip_evsub *ast_sip_subscription_get_evsub(struct ast_sip_subscription *sub);
+ 
+/*!
+ * \brief Send a request created via a PJSIP evsub method
+ *
+ * Callers of this function should take care to do so within a SIP servant
+ * thread.
+ *
+ * \param sub The subscription on which to send the request
+ * \param tdata The request to send
+ * \retval 0 Success
+ * \retval non-zero Failure
+ */
+int ast_sip_subscription_send_request(struct ast_sip_subscription *sub, pjsip_tx_data *tdata);
+ 
+/*!
+ * \brief Alternative for ast_datastore_alloc()
+ *
+ * There are two major differences between this and ast_datastore_alloc()
+ * 1) This allocates a refcounted object
+ * 2) This will fill in a uid if one is not provided
+ *
+ * DO NOT call ast_datastore_free() on a datastore allocated in this
+ * way since that function will attempt to free the datastore rather
+ * than play nicely with its refcount.
+ *
+ * \param info Callbacks for datastore
+ * \param uid Identifier for datastore
+ * \retval NULL Failed to allocate datastore
+ * \retval non-NULL Newly allocated datastore
+ */
+struct ast_datastore *ast_sip_subscription_alloc_datastore(const struct ast_datastore_info *info, const char *uid);
+ 
+/*!
+ * \brief Add a datastore to a SIP subscription
+ *
+ * Note that SIP uses reference counted datastores. The datastore passed into this function
+ * must have been allocated using ao2_alloc() or there will be serious problems.
+ *
+ * \param subscription The ssubscription to add the datastore to
+ * \param datastore The datastore to be added to the subscription
+ * \retval 0 Success
+ * \retval -1 Failure
+ */
+int ast_sip_subscription_add_datastore(struct ast_sip_subscription *subscription, struct ast_datastore *datastore);
+ 
+/*!
+ * \brief Retrieve a subscription datastore
+ *
+ * The datastore retrieved will have its reference count incremented. When the caller is done
+ * with the datastore, the reference counted needs to be decremented using ao2_ref().
+ *
+ * \param subscription The subscription from which to retrieve the datastore
+ * \param name The name of the datastore to retrieve
+ * \retval NULL Failed to find the specified datastore
+ * \retval non-NULL The specified datastore
+ */
+struct ast_datastore *ast_sip_subscription_get_datastore(struct ast_sip_subscription *subscription, const char *name);
+ 
+/*!
+ * \brief Remove a subscription datastore from the subscription
+ *
+ * This operation may cause the datastore's free() callback to be called if the reference
+ * count reaches zero.
+ *
+ * \param subscription The subscription to remove the datastore from
+ * \param name The name of the datastore to remove
+ */
+void ast_sip_subscription_remove_datastore(struct ast_sip_subscription *subscription, const char *name);
+ 
+/*!
+ * \brief Register a subscription handler
+ *
+ * \retval 0 Handler was registered successfully
+ * \retval non-zero Handler was not registered successfully
+ */
+int ast_sip_register_subscription_handler(struct ast_sip_subscription_handler *handler);
+ 
+/*!
+ * \brief Unregister a subscription handler
+ */
+void ast_sip_unregister_subscription_handler(struct ast_sip_subscription_handler *handler);
+
+#endif /* RES_SIP_PUBSUB_H */
diff --git a/include/asterisk/res_sip_session.h b/include/asterisk/res_sip_session.h
new file mode 100644
index 0000000000000000000000000000000000000000..cbed5262108fe9fb95af67a26e2b2d0b16e4d40c
--- /dev/null
+++ b/include/asterisk/res_sip_session.h
@@ -0,0 +1,468 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2013, Digium, Inc.
+ *
+ * Mark Michelson <mmichelson@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+#ifndef _RES_SIP_SESSION_H
+#define _RES_SIP_SESSION_H
+
+/* Needed for pj_timer_entry definition */
+#include "pjlib.h"
+#include "asterisk/linkedlists.h"
+/* Needed for AST_MAX_EXTENSION constant */
+#include "asterisk/channel.h"
+/* Needed for ast_sockaddr struct */
+#include "asterisk/netsock.h"
+
+/* Forward declarations */
+struct ast_sip_endpoint;
+struct ast_sip_transport;
+struct pjsip_inv_session;
+struct ast_channel;
+struct ast_datastore;
+struct ast_datastore_info;
+struct ao2_container;
+struct pjsip_tx_data;
+struct pjsip_rx_data;
+struct ast_party_id;
+struct pjmedia_sdp_media;
+struct pjmedia_sdp_session;
+struct ast_rtp_instance;
+
+struct ast_sip_session_sdp_handler;
+
+/*!
+ * \brief A structure containing SIP session media information
+ */
+struct ast_sip_session_media {
+	/*! \brief RTP instance itself */
+	struct ast_rtp_instance *rtp;
+	/*! \brief Direct media address */
+	struct ast_sockaddr direct_media_addr;
+	/*! \brief SDP handler that setup the RTP */
+	struct ast_sip_session_sdp_handler *handler;
+	/*! \brief Stream is on hold */
+	unsigned int held:1;
+	/*! \brief Stream type this session media handles */
+	char stream_type[1];
+};
+
+/*!
+ * \brief Opaque structure representing a request that could not be sent
+ * due to an outstanding INVITE transaction
+ */
+struct ast_sip_session_delayed_request;
+
+/*!
+ * \brief A structure describing a SIP session
+ *
+ * For the sake of brevity, a "SIP session" in Asterisk is referring to
+ * a dialog initiated by an INVITE. While "session" is typically interpreted
+ * to refer to the negotiated media within a SIP dialog, we have opted
+ * to use the term "SIP session" to refer to the INVITE dialog itself.
+ */
+struct ast_sip_session {
+	/* Dialplan extension where incoming call is destined */
+	char exten[AST_MAX_EXTENSION];
+	/* The endpoint with which Asterisk is communicating */
+	struct ast_sip_endpoint *endpoint;
+	/* The PJSIP details of the session, which includes the dialog */
+	struct pjsip_inv_session *inv_session;
+	/* The Asterisk channel associated with the session */
+	struct ast_channel *channel;
+	/* Registered session supplements */
+	AST_LIST_HEAD(, ast_sip_session_supplement) supplements;
+	/* Datastores added to the session by supplements to the session */
+	struct ao2_container *datastores;
+	/* Media streams */
+	struct ao2_container *media;
+	/* Serializer for tasks relating to this SIP session */
+	struct ast_taskprocessor *serializer;
+	/* Requests that could not be sent due to current inv_session state */
+	AST_LIST_HEAD_NOLOCK(, ast_sip_session_delayed_request) delayed_requests;
+	/* When we need to reschedule a reinvite, we use this structure to do it */
+	pj_timer_entry rescheduled_reinvite;
+	/* Format capabilities pertaining to direct media */
+	struct ast_format_cap *direct_media_cap;
+	/* Identity of endpoint this session deals with */
+	struct ast_party_id id;
+	/* Requested capabilities */
+	struct ast_format_cap *req_caps;
+};
+
+typedef int (*ast_sip_session_request_creation_cb)(struct ast_sip_session *session, pjsip_tx_data *tdata);
+typedef int (*ast_sip_session_response_cb)(struct ast_sip_session *session, pjsip_rx_data *rdata);
+
+enum ast_sip_session_supplement_priority {
+	/*! Top priority. Supplements with this priority are those that need to run before any others */
+	AST_SIP_SESSION_SUPPLEMENT_PRIORITY_FIRST = 0,
+	/*! Channel creation priority.
+	 * chan_gulp creates a channel at this priority. If your supplement depends on being run before
+	 * or after channel creation, then set your priority to be lower or higher than this value.
+	 */
+	AST_SIP_SESSION_SUPPLEMENT_PRIORITY_CHANNEL = 1000000,
+	/*! Lowest priority. Supplements with this priority should be run after all other supplements */
+	AST_SIP_SESSION_SUPPLEMENT_PRIORITY_LAST = INT_MAX,
+};
+
+/*!
+ * \brief A supplement to SIP message processing
+ *
+ * These can be registered by any module in order to add
+ * processing to incoming and outgoing SIP requests and responses
+ */
+struct ast_sip_session_supplement {
+    /*! Method on which to call the callbacks. If NULL, call on all methods */
+    const char *method;
+	/*! Priority for this supplement. Lower numbers are visited before higher numbers */
+	enum ast_sip_session_supplement_priority priority;
+    /*!
+	 * \brief Notification that the session has begun
+	 * This method will always be called from a SIP servant thread.
+	 */
+    void (*session_begin)(struct ast_sip_session *session);
+    /*! 
+	 * \brief Notification that the session has ended
+	 *
+	 * This method may or may not be called from a SIP servant thread. Do
+	 * not make assumptions about being able to call PJSIP methods from within
+	 * this method.
+	 */
+    void (*session_end)(struct ast_sip_session *session);
+	/*!
+	 * \brief Notification that the session is being destroyed
+	 */
+	void (*session_destroy)(struct ast_sip_session *session);
+    /*!
+     * \brief Called on incoming SIP request
+     * This method can indicate a failure in processing in its return. If there
+     * is a failure, it is required that this method sends a response to the request.
+	 * This method is always called from a SIP servant thread.
+	 *
+	 * \note
+	 * The following PJSIP methods will not work properly:
+	 * pjsip_rdata_get_dlg()
+	 * pjsip_rdata_get_tsx()
+	 * The reason is that the rdata passed into this function is a cloned rdata structure,
+	 * and its module data is not copied during the cloning operation.
+	 * If you need to get the dialog, you can get it via session->inv_session->dlg.
+     */
+    int (*incoming_request)(struct ast_sip_session *session, struct pjsip_rx_data *rdata);
+    /*! 
+	 * \brief Called on an incoming SIP response
+	 * This method is always called from a SIP servant thread.
+	 *
+	 * \note
+	 * The following PJSIP methods will not work properly:
+	 * pjsip_rdata_get_dlg()
+	 * pjsip_rdata_get_tsx()
+	 * The reason is that the rdata passed into this function is a cloned rdata structure,
+	 * and its module data is not copied during the cloning operation.
+	 * If you need to get the dialog, you can get it via session->inv_session->dlg.
+	 */
+    void (*incoming_response)(struct ast_sip_session *session, struct pjsip_rx_data *rdata);
+    /*!
+	 * \brief Called on an outgoing SIP request
+	 * This method is always called from a SIP servant thread.
+	 */
+    void (*outgoing_request)(struct ast_sip_session *session, struct pjsip_tx_data *tdata);
+    /*! 
+	 * \brief Called on an outgoing SIP response
+	 * This method is always called from a SIP servant thread.
+	 */
+    void (*outgoing_response)(struct ast_sip_session *session, struct pjsip_tx_data *tdata);
+	/*! Next item in the list */
+	AST_LIST_ENTRY(ast_sip_session_supplement) next;
+};
+
+/*!
+ * \brief A handler for SDPs in SIP sessions
+ *
+ * An SDP handler is registered by a module that is interested in being the
+ * responsible party for specific types of SDP streams.
+ */
+struct ast_sip_session_sdp_handler {
+	/*! An identifier for this handler */
+	const char *id;
+	/*!
+	 * \brief Set session details based on a stream in an incoming SDP offer or answer
+	 * \param session The session for which the media is being negotiated
+	 * \param session_media The media to be setup for this session
+	 * \param sdp The entire SDP. Useful for getting "global" information, such as connections or attributes
+	 * \param stream The stream on which to operate
+	 * \retval 0 The stream was not handled by this handler. If there are other registered handlers for this stream type, they will be called.
+	 * \retval <0 There was an error encountered. No further operation will take place and the current negotiation will be abandoned.
+	 * \retval >0 The stream was handled by this handler. No further handler of this stream type will be called.
+	 */
+	int (*negotiate_incoming_sdp_stream)(struct ast_sip_session *session, struct ast_sip_session_media *session_media, const struct pjmedia_sdp_session *sdp, const struct pjmedia_sdp_media *stream);
+	/*!
+	 * \brief Create an SDP media stream and add it to the outgoing SDP offer or answer
+	 * \param session The session for which media is being added
+	 * \param session_media The media to be setup for this session
+	 * \param stream The stream on which to operate
+	 * \retval 0 The stream was not handled by this handler. If there are other registered handlers for this stream type, they will be called.
+	 * \retval <0 There was an error encountered. No further operation will take place and the current negotiation will be abandoned.
+	 * \retval >0 The stream was handled by this handler. No further handler of this stream type will be called.
+	 */
+	int (*handle_incoming_sdp_stream)(struct ast_sip_session *session, struct ast_sip_session_media *session_media, const struct pjmedia_sdp_session *sdp, struct pjmedia_sdp_media *stream);
+	/*!
+	 * \brief Create an SDP media stream and add it to the outgoing SDP offer or answer
+	 * \param session The session for which media is being added
+	 * \param session_media The media to be setup for this session
+	 * \param sdp The entire SDP as currently built
+	 * \retval 0 This handler has no stream to add. If there are other registered handlers for this stream type, they will be called.
+	 * \retval <0 There was an error encountered. No further operation will take place and the current SDP negotiation will be abandoned.
+	 * \retval >0 The handler has a stream to be added to the SDP. No further handler of this stream type will be called.
+	 */
+	int (*create_outgoing_sdp_stream)(struct ast_sip_session *session, struct ast_sip_session_media *session_media, struct pjmedia_sdp_session *sdp);
+	/*!
+	 * \brief Update media stream with external address if applicable
+	 * \param tdata The outgoing message itself
+	 * \param stream The stream on which to operate
+	 * \param transport The transport the SDP is going out on
+	 */
+	void (*change_outgoing_sdp_stream_media_address)(struct pjsip_tx_data *tdata, struct pjmedia_sdp_media *stream, struct ast_sip_transport *transport);
+	/*!
+	 * \brief Apply a negotiated SDP media stream
+	 * \param session The session for which media is being applied
+	 * \param session_media The media to be setup for this session
+	 * \param local The entire local negotiated SDP
+	 * \param local_stream The local stream which to apply
+	 * \param remote The entire remote negotiated SDP
+	 * \param remote_stream The remote stream which to apply
+	 * \retval 0 The stream was not applied by this handler. If there are other registered handlers for this stream type, they will be called.
+	 * \retval <0 There was an error encountered. No further operation will take place and the current application will be abandoned.
+	 * \retval >0 The stream was handled by this handler. No further handler of this stream type will be called.
+	 */
+	int (*apply_negotiated_sdp_stream)(struct ast_sip_session *session, struct ast_sip_session_media *session_media, const struct pjmedia_sdp_session *local, const struct pjmedia_sdp_media *local_stream,
+		const struct pjmedia_sdp_session *remote, const struct pjmedia_sdp_media *remote_stream);
+	/*!
+	 * \brief Destroy a session_media created by this handler
+	 * \param session The session for which media is being destroyed
+	 * \param session_media The media to destroy
+	 */
+	void (*stream_destroy)(struct ast_sip_session_media *session_media);
+	/*! Next item in the list. */
+	AST_LIST_ENTRY(ast_sip_session_sdp_handler) next;
+};
+
+/*!
+ * \brief Allocate a new SIP session
+ *
+ * This will take care of allocating the datastores container on the session as well
+ * as placing all registered supplements onto the session.
+ *
+ * The endpoint that is passed in will have its reference count increased by one since
+ * the session will be keeping a reference to the endpoint. The session will relinquish
+ * this reference when the session is destroyed.
+ *
+ * \param endpoint The endpoint that this session communicates with
+ * \param inv_session The PJSIP INVITE session data
+ */
+struct ast_sip_session *ast_sip_session_alloc(struct ast_sip_endpoint *endpoint, pjsip_inv_session *inv);
+
+/*!
+ * \brief Create a new outgoing SIP session
+ *
+ * The endpoint that is passed in will have its reference count increased by one since
+ * the session will be keeping a reference to the endpoint. The session will relinquish
+ * this reference when the session is destroyed.
+ *
+ * \param endpoint The endpoint that this session uses for settings
+ * \param location Optional name of the location to call, be it named location or explicit URI
+ * \param request_user Optional request user to place in the request URI if permitted
+ * \param req_caps The requested capabilities
+ */
+struct ast_sip_session *ast_sip_session_create_outgoing(struct ast_sip_endpoint *endpoint, const char *location, const char *request_user, struct ast_format_cap *req_caps);
+
+/*!
+ * \brief Register an SDP handler
+ *
+ * An SDP handler is responsible for parsing incoming SDP streams and ensuring that
+ * Asterisk can cope with the contents. Similarly, the SDP handler will be
+ * responsible for constructing outgoing SDP streams.
+ *
+ * Multiple handlers for the same stream type may be registered. They will be
+ * visited in the order they were registered. Handlers will be visited for each
+ * stream type until one claims to have handled the stream.
+ *
+ * \param handler The SDP handler to register
+ * \param stream_type The type of media stream for which to call the handler
+ * \retval 0 Success
+ * \retval -1 Failure
+ */
+int ast_sip_session_register_sdp_handler(struct ast_sip_session_sdp_handler *handler, const char *stream_type);
+
+/*!
+ * \brief Unregister an SDP handler
+ *
+ * \param handler The SDP handler to unregister
+ * \param stream_type Stream type for which the SDP handler was registered
+ */
+void ast_sip_session_unregister_sdp_handler(struct ast_sip_session_sdp_handler *handler, const char *stream_type);
+
+/*!
+ * \brief Register a supplement to SIP session processing
+ *
+ * This allows for someone to insert themselves in the processing of SIP
+ * requests and responses. This, for example could allow for a module to
+ * set channel data based on headers in an incoming message. Similarly,
+ * a module could reject an incoming request if desired.
+ *
+ * \param supplement The supplement to register
+ * \retval 0 Success
+ * \retval -1 Failure
+ */
+int ast_sip_session_register_supplement(struct ast_sip_session_supplement *supplement);
+
+/*!
+ * \brief Unregister a an supplement to SIP session processing
+ *
+ * \param supplement The supplement to unregister
+ */
+void ast_sip_session_unregister_supplement(struct ast_sip_session_supplement *supplement);
+
+/*!
+ * \brief Alternative for ast_datastore_alloc()
+ *
+ * There are two major differences between this and ast_datastore_alloc()
+ * 1) This allocates a refcounted object
+ * 2) This will fill in a uid if one is not provided
+ *
+ * DO NOT call ast_datastore_free() on a datastore allocated in this
+ * way since that function will attempt to free the datastore rather
+ * than play nicely with its refcount.
+ *
+ * \param info Callbacks for datastore
+ * \param uid Identifier for datastore
+ * \retval NULL Failed to allocate datastore
+ * \retval non-NULL Newly allocated datastore
+ */
+struct ast_datastore *ast_sip_session_alloc_datastore(const struct ast_datastore_info *info, const char *uid);
+
+/*!
+ * \brief Add a datastore to a SIP session
+ *
+ * Note that SIP uses reference counted datastores. The datastore passed into this function
+ * must have been allocated using ao2_alloc() or there will be serious problems.
+ *
+ * \param session The session to add the datastore to
+ * \param datastore The datastore to be added to the session
+ * \retval 0 Success
+ * \retval -1 Failure
+ */
+int ast_sip_session_add_datastore(struct ast_sip_session *session, struct ast_datastore *datastore);
+
+/*!
+ * \brief Retrieve a session datastore
+ *
+ * The datastore retrieved will have its reference count incremented. When the caller is done
+ * with the datastore, the reference counted needs to be decremented using ao2_ref().
+ *
+ * \param session The session from which to retrieve the datastore
+ * \param name The name of the datastore to retrieve
+ * \retval NULL Failed to find the specified datastore
+ * \retval non-NULL The specified datastore
+ */
+struct ast_datastore *ast_sip_session_get_datastore(struct ast_sip_session *session, const char *name);
+
+/*!
+ * \brief Remove a session datastore from the session
+ *
+ * This operation may cause the datastore's free() callback to be called if the reference
+ * count reaches zero.
+ *
+ * \param session The session to remove the datastore from
+ * \param name The name of the datastore to remove
+ */
+void ast_sip_session_remove_datastore(struct ast_sip_session *session, const char *name);
+
+/*!
+ * \brief Retrieve identifying information from an incoming request
+ *
+ * This will retrieve identifying information and place it in the
+ * id parameter. The caller of the function can then apply this to
+ * caller ID, connected line, or whatever else may be proper.
+ *
+ * \param rdata The incoming request or response
+ * \param[out] id The collected identity information
+ * \retval 0 Successfully found identifying information
+ * \retval -1 Identifying information could not be found
+ */
+int ast_sip_session_get_identity(struct pjsip_rx_data *rdata, struct ast_party_id *id);
+
+/*!
+ * \brief Send a reinvite or UPDATE on a session
+ *
+ * This method will inspect the session in order to construct an appropriate
+ * session refresh request. As with any outgoing request in res_sip_session,
+ * this will call into registered supplements in case they wish to add anything.
+ *
+ * Note: The on_request_creation callback may or may not be called in the same
+ * thread where this function is called. Request creation may need to be delayed
+ * due to the current INVITE transaction state.
+ * 
+ * \param session The session on which the reinvite will be sent
+ * \param on_request_creation Callback called when request is created
+ * \param on_response Callback called when response for request is received
+ * \param method The method that should be used when constructing the session refresh
+ * \param generate_new_sdp Boolean to indicate if a new SDP should be created
+ * \retval 0 Successfully sent refresh
+ * \retval -1 Failure to send refresh
+ */
+int ast_sip_session_refresh(struct ast_sip_session *session,
+		ast_sip_session_request_creation_cb on_request_creation,
+		ast_sip_session_response_cb on_response,
+		enum ast_sip_session_refresh_method method,
+		int generate_new_sdp);
+
+/*!
+ * \brief Send a SIP response
+ *
+ * This will send the SIP response specified in tdata and
+ * call into any registered supplements' outgoing_response callback.
+ *
+ * \param session The session on which to send the response.
+ * \param tdata The response to send
+ */
+void ast_sip_session_send_response(struct ast_sip_session *session, pjsip_tx_data *tdata);
+
+/*!
+ * \brief Send a SIP request
+ *
+ * This will send the SIP request specified in tdata and
+ * call into any registered supplements' outgoing_request callback.
+ *
+ * \param session The session to which to send the request
+ * \param tdata The request to send
+ */
+void ast_sip_session_send_request(struct ast_sip_session *session, pjsip_tx_data *tdata);
+
+/*!
+ * \brief Send a SIP request and get called back when a response is received
+ *
+ * This will send the request out exactly the same as ast_sip_send_request() does.
+ * The difference is that when a response arrives, the specified callback will be
+ * called into
+ *
+ * \param session The session on which to send the request
+ * \param tdata The request to send
+ * \param on_response Callback to be called when a response is received
+ */
+void ast_sip_session_send_request_with_cb(struct ast_sip_session *session, pjsip_tx_data *tdata,
+		ast_sip_session_response_cb on_response);
+
+#endif /* _RES_SIP_SESSION_H */
diff --git a/include/asterisk/sorcery.h b/include/asterisk/sorcery.h
index e390b43cf2b6ed13ffe4f7c671b54e2a8e83a425..434f5595a35f44426789230231a3d42c173e67ad 100644
--- a/include/asterisk/sorcery.h
+++ b/include/asterisk/sorcery.h
@@ -157,10 +157,15 @@ typedef struct ast_variable *(*sorcery_transform_handler)(struct ast_variable *s
 /*!
  * \brief A callback function for when an object set is successfully applied to an object
  *
+ * \note On a failure return, the state of the object is left undefined. It is a bad
+ * idea to try to use this object.
+ *
  * \param sorcery Sorcery structure in use
  * \param obj The object itself
+ * \retval 0 Success
+ * \retval non-zero Failure
  */
-typedef void (*sorcery_apply_handler)(const struct ast_sorcery *sorcery, void *obj);
+typedef int (*sorcery_apply_handler)(const struct ast_sorcery *sorcery, void *obj);
 
 /*!
  * \brief A callback function for copying the contents of one object to another
diff --git a/include/asterisk/threadpool.h b/include/asterisk/threadpool.h
index 89076265e1d5be02766600601e689b12d613dfc0..e1e7727f5f86bc7649a16df4a760f8d1b41d2935 100644
--- a/include/asterisk/threadpool.h
+++ b/include/asterisk/threadpool.h
@@ -108,6 +108,20 @@ struct ast_threadpool_options {
 	 * maximum size.
 	 */
 	int max_size;
+	/*!
+	 * \brief Function to call when a thread starts
+	 *
+	 * This is useful if there is something common that all threads
+	 * in a threadpool need to do when they start.
+	 */
+	void (*thread_start)(void);
+	/*!
+	 * \brief Function to call when a thread ends
+	 *
+	 * This is useful if there is common cleanup to execute when
+	 * a thread completes
+	 */
+	void (*thread_end)(void);
 };
 
 /*!
diff --git a/main/astobj2.c b/main/astobj2.c
index 72a171de9a5299316412a8bb1df33f4952789b93..a980ec3792c49c29dae45c123b4944ea3d133b0a 100644
--- a/main/astobj2.c
+++ b/main/astobj2.c
@@ -525,6 +525,7 @@ int __ao2_ref_debug(void *user_data, int delta, const char *tag, const char *fil
 	struct astobj2 *obj = INTERNAL_OBJ(user_data);
 
 	if (obj == NULL) {
+		ast_backtrace();
 		ast_assert(0);
 		return -1;
 	}
diff --git a/main/loader.c b/main/loader.c
index 5befafb5574bc1873be95223cc40b386a72d14c4..10d5485da867d8118aeda915f93a29a3222d2501 100644
--- a/main/loader.c
+++ b/main/loader.c
@@ -842,6 +842,7 @@ static enum ast_module_load_result start_resource(struct ast_module *mod)
 		return AST_MODULE_LOAD_FAILURE;
 	}
 
+	printf ("!!! Going to load %s\n", mod->resource);
 	res = mod->info->load();
 
 	switch (res) {
diff --git a/main/sorcery.c b/main/sorcery.c
index 8b555222db50c0943204f5b2a6e91093a383aa0c..44e247a3898c3852094c019213ab3b3467be1eb6 100644
--- a/main/sorcery.c
+++ b/main/sorcery.c
@@ -740,7 +740,7 @@ int ast_sorcery_objectset_apply(const struct ast_sorcery *sorcery, void *object,
 	}
 
 	if (!res && object_type->apply) {
-		object_type->apply(sorcery, object);
+		res = object_type->apply(sorcery, object);
 	}
 
 	return res;
@@ -940,6 +940,7 @@ void *ast_sorcery_retrieve_by_fields(const struct ast_sorcery *sorcery, const ch
 	unsigned int cached = 0;
 
 	if (!object_type) {
+		ast_log(LOG_NOTICE, "Can't find object type '%s'\n", type);
 		return NULL;
 	}
 
diff --git a/main/taskprocessor.c b/main/taskprocessor.c
index 35076b06e10990f35e4887ca25a7efe08d86a61f..a8d1c80f97cd0aacb0feaca913fe2b9e515172ea 100644
--- a/main/taskprocessor.c
+++ b/main/taskprocessor.c
@@ -602,7 +602,6 @@ struct ast_taskprocessor *ast_taskprocessor_get(const char *name, enum ast_tps_o
 	/* Unref listener here since the taskprocessor has gained a reference to the listener */
 	ao2_ref(listener, -1);
 	return p;
-
 }
 
 struct ast_taskprocessor *ast_taskprocessor_create_with_listener(const char *name, struct ast_taskprocessor_listener *listener)
diff --git a/main/threadpool.c b/main/threadpool.c
index e2fdecc5783dd24c46f61cd5e45208a64b2da4a9..1ff76014afb96de83e51c25835ef24f0b1b7ec09 100644
--- a/main/threadpool.c
+++ b/main/threadpool.c
@@ -983,7 +983,13 @@ static void *worker_start(void *arg)
 {
 	struct worker_thread *worker = arg;
 
+	if (worker->options.thread_start) {
+		worker->options.thread_start();
+	}
 	worker_active(worker);
+	if (worker->options.thread_end) {
+		worker->options.thread_end();
+	}
 	return NULL;
 }
 
diff --git a/res/Makefile b/res/Makefile
index fec20a2e02976ae81c2af04ed0f48fb439e4b6c3..35d09275cc8423c0cce9866fff07b2fced9e783d 100644
--- a/res/Makefile
+++ b/res/Makefile
@@ -43,6 +43,9 @@ snmp/agent.o: _ASTCFLAGS+=$(call MOD_ASTCFLAGS,res_snmp)
 $(if $(filter res_ael_share,$(EMBEDDED_MODS)),modules.link,res_ael_share.so): ael/ael_lex.o ael/ael.tab.o ael/pval.o
 ael/ael_lex.o ael/ael.tab.o ael/pval.o: _ASTCFLAGS+=$(call MOD_ASTCFLAGS,res_ael_share)
 
+$(if $(filter res_sip,$(EMBEDDED_MODS)),modules.link,res_sip.so): $(subst .c,.o,$(wildcard res_sip/*.c))
+$(subst .c,.o,$(wildcard res_sip/*.c)): _ASTCFLAGS+=$(call MOD_ASTCFLAGS,res_sip)
+
 ifneq ($(findstring REBUILD_PARSERS,$(MENUSELECT_CFLAGS)),)
 ael/ael_lex.c: ael/ael.flex
 else
@@ -67,7 +70,7 @@ endif
 ael/pval.o: ael/pval.c
 
 clean::
-	rm -f snmp/*.[oi] ael/*.[oi] ais/*.[oi] stasis_http/*.[oi]
+	rm -f snmp/*.[oi] ael/*.[oi] ais/*.[oi] stasis_http/*.[oi] res_sip/*.[oi]
 
 # Dependencies for res_stasis_http_*.so are generated, so they're in this file
 include stasis_http.make
diff --git a/res/res_sip.c b/res/res_sip.c
new file mode 100644
index 0000000000000000000000000000000000000000..18eead992cf723af2a7cae16f159616a61740f93
--- /dev/null
+++ b/res/res_sip.c
@@ -0,0 +1,906 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2013, Digium, Inc.
+ *
+ * Mark Michelson <mmichelson@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+#include "asterisk.h"
+
+#include <pjsip.h>
+/* Needed for SUBSCRIBE, NOTIFY, and PUBLISH method definitions */
+#include <pjsip_simple.h>
+#include <pjlib.h>
+
+#include "asterisk/res_sip.h"
+#include "res_sip/include/res_sip_private.h"
+#include "asterisk/linkedlists.h"
+#include "asterisk/logger.h"
+#include "asterisk/lock.h"
+#include "asterisk/utils.h"
+#include "asterisk/astobj2.h"
+#include "asterisk/module.h"
+#include "asterisk/threadpool.h"
+#include "asterisk/taskprocessor.h"
+#include "asterisk/uuid.h"
+#include "asterisk/sorcery.h"
+
+/*** MODULEINFO
+	<depend>pjproject</depend>
+	<depend>res_sorcery_config</depend>
+	<support_level>core</support_level>
+ ***/
+
+static pjsip_endpoint *ast_pjsip_endpoint;
+
+static struct ast_threadpool *sip_threadpool;
+
+static int register_service(void *data)
+{
+	pjsip_module **module = data;
+	if (!ast_pjsip_endpoint) {
+		ast_log(LOG_ERROR, "There is no PJSIP endpoint. Unable to register services\n");
+		return -1;
+	}
+	if (pjsip_endpt_register_module(ast_pjsip_endpoint, *module) != PJ_SUCCESS) {
+		ast_log(LOG_ERROR, "Unable to register module %.*s\n", (int) pj_strlen(&(*module)->name), pj_strbuf(&(*module)->name));
+		return -1;
+	}
+	ast_debug(1, "Registered SIP service %.*s (%p)\n", (int) pj_strlen(&(*module)->name), pj_strbuf(&(*module)->name), *module);
+	ast_module_ref(ast_module_info->self);
+	return 0;
+}
+
+int ast_sip_register_service(pjsip_module *module)
+{
+	return ast_sip_push_task_synchronous(NULL, register_service, &module);
+}
+
+static int unregister_service(void *data)
+{
+	pjsip_module **module = data;
+	ast_module_unref(ast_module_info->self);
+	if (!ast_pjsip_endpoint) {
+		return -1;
+	}
+	pjsip_endpt_unregister_module(ast_pjsip_endpoint, *module);
+	ast_debug(1, "Unregistered SIP service %.*s\n", (int) pj_strlen(&(*module)->name), pj_strbuf(&(*module)->name));
+	return 0;
+}
+
+void ast_sip_unregister_service(pjsip_module *module)
+{
+	ast_sip_push_task_synchronous(NULL, unregister_service, &module);
+}
+
+static struct ast_sip_authenticator *registered_authenticator;
+
+int ast_sip_register_authenticator(struct ast_sip_authenticator *auth)
+{
+	if (registered_authenticator) {
+		ast_log(LOG_WARNING, "Authenticator %p is already registered. Cannot register a new one\n", registered_authenticator);
+		return -1;
+	}
+	registered_authenticator = auth;
+	ast_debug(1, "Registered SIP authenticator module %p\n", auth);
+	ast_module_ref(ast_module_info->self);
+	return 0;
+}
+
+void ast_sip_unregister_authenticator(struct ast_sip_authenticator *auth)
+{
+	if (registered_authenticator != auth) {
+		ast_log(LOG_WARNING, "Trying to unregister authenticator %p but authenticator %p registered\n",
+				auth, registered_authenticator);
+		return;
+	}
+	registered_authenticator = NULL;
+	ast_debug(1, "Unregistered SIP authenticator %p\n", auth);
+	ast_module_unref(ast_module_info->self);
+}
+
+int ast_sip_requires_authentication(struct ast_sip_endpoint *endpoint, pjsip_rx_data *rdata)
+{
+	if (!registered_authenticator) {
+		ast_log(LOG_WARNING, "No SIP authenticator registered. Assuming authentication is not required\n");
+		return 0;
+	}
+
+	return registered_authenticator->requires_authentication(endpoint, rdata);
+}
+
+enum ast_sip_check_auth_result ast_sip_check_authentication(struct ast_sip_endpoint *endpoint,
+		pjsip_rx_data *rdata, pjsip_tx_data *tdata)
+{
+	if (!registered_authenticator) {
+		ast_log(LOG_WARNING, "No SIP authenticator registered. Assuming authentication is successful\n");
+		return 0;
+	}
+	return registered_authenticator->check_authentication(endpoint, rdata, tdata);
+}
+
+static struct ast_sip_outbound_authenticator *registered_outbound_authenticator;
+
+int ast_sip_register_outbound_authenticator(struct ast_sip_outbound_authenticator *auth)
+{
+	if (registered_outbound_authenticator) {
+		ast_log(LOG_WARNING, "Outbound authenticator %p is already registered. Cannot register a new one\n", registered_outbound_authenticator);
+		return -1;
+	}
+	registered_outbound_authenticator = auth;
+	ast_debug(1, "Registered SIP outbound authenticator module %p\n", auth);
+	ast_module_ref(ast_module_info->self);
+	return 0;
+}
+
+void ast_sip_unregister_outbound_authenticator(struct ast_sip_outbound_authenticator *auth)
+{
+	if (registered_outbound_authenticator != auth) {
+		ast_log(LOG_WARNING, "Trying to unregister outbound authenticator %p but outbound authenticator %p registered\n",
+				auth, registered_outbound_authenticator);
+		return;
+	}
+	registered_outbound_authenticator = NULL;
+	ast_debug(1, "Unregistered SIP outbound authenticator %p\n", auth);
+	ast_module_unref(ast_module_info->self);
+}
+
+int ast_sip_create_request_with_auth(const char **auths, size_t num_auths, pjsip_rx_data *challenge,
+		pjsip_transaction *tsx, pjsip_tx_data **new_request)
+{
+	if (!registered_outbound_authenticator) {
+		ast_log(LOG_WARNING, "No SIP outbound authenticator registered. Cannot respond to authentication challenge\n");
+		return -1;
+	}
+	return registered_outbound_authenticator->create_request_with_auth(auths, num_auths, challenge, tsx, new_request);
+}
+
+struct endpoint_identifier_list {
+	struct ast_sip_endpoint_identifier *identifier;
+	AST_RWLIST_ENTRY(endpoint_identifier_list) list;
+};
+
+static AST_RWLIST_HEAD_STATIC(endpoint_identifiers, endpoint_identifier_list);
+
+int ast_sip_register_endpoint_identifier(struct ast_sip_endpoint_identifier *identifier)
+{
+	struct endpoint_identifier_list *id_list_item;
+	SCOPED_LOCK(lock, &endpoint_identifiers, AST_RWLIST_WRLOCK, AST_RWLIST_UNLOCK);
+
+	id_list_item = ast_calloc(1, sizeof(*id_list_item));
+	if (!id_list_item) {
+		ast_log(LOG_ERROR, "Unabled to add endpoint identifier. Out of memory.\n");
+		return -1;
+	}
+	id_list_item->identifier = identifier;
+
+	AST_RWLIST_INSERT_TAIL(&endpoint_identifiers, id_list_item, list);
+	ast_debug(1, "Registered endpoint identifier %p\n", identifier);
+
+	ast_module_ref(ast_module_info->self);
+	return 0;
+}
+
+void ast_sip_unregister_endpoint_identifier(struct ast_sip_endpoint_identifier *identifier)
+{
+	struct endpoint_identifier_list *iter;
+	SCOPED_LOCK(lock, &endpoint_identifiers, AST_RWLIST_WRLOCK, AST_RWLIST_UNLOCK);
+	AST_RWLIST_TRAVERSE_SAFE_BEGIN(&endpoint_identifiers, iter, list) {
+		if (iter->identifier == identifier) {
+			AST_RWLIST_REMOVE_CURRENT(list);
+			ast_free(iter);
+			ast_debug(1, "Unregistered endpoint identifier %p\n", identifier);
+			ast_module_unref(ast_module_info->self);
+			break;
+		}
+	}
+	AST_RWLIST_TRAVERSE_SAFE_END;
+}
+
+struct ast_sip_endpoint *ast_sip_identify_endpoint(pjsip_rx_data *rdata)
+{
+	struct endpoint_identifier_list *iter;
+	struct ast_sip_endpoint *endpoint = NULL;
+	SCOPED_LOCK(lock, &endpoint_identifiers, AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK);
+	AST_RWLIST_TRAVERSE(&endpoint_identifiers, iter, list) {
+		ast_assert(iter->identifier->identify_endpoint != NULL);
+		endpoint = iter->identifier->identify_endpoint(rdata);
+		if (endpoint) {
+			break;
+		}
+	}
+	return endpoint;
+}
+
+pjsip_endpoint *ast_sip_get_pjsip_endpoint(void)
+{
+	return ast_pjsip_endpoint;
+}
+
+static int sip_dialog_create_from(pj_pool_t *pool, pj_str_t *from, const char *user, const pj_str_t *target, pjsip_tpselector *selector)
+{
+	pj_str_t tmp, local_addr;
+	pjsip_uri *uri;
+	pjsip_sip_uri *sip_uri;
+	pjsip_transport_type_e type = PJSIP_TRANSPORT_UNSPECIFIED;
+	int local_port;
+	char uuid_str[AST_UUID_STR_LEN];
+
+	if (!user) {
+		RAII_VAR(struct ast_uuid *, uuid, ast_uuid_generate(), ast_free_ptr);
+		if (!uuid) {
+			return -1;
+		}
+		user = ast_uuid_to_str(uuid, uuid_str, sizeof(uuid_str));
+	}
+
+	/* Parse the provided target URI so we can determine what transport it will end up using */
+	pj_strdup_with_null(pool, &tmp, target);
+
+	if (!(uri = pjsip_parse_uri(pool, tmp.ptr, tmp.slen, 0)) ||
+	    (!PJSIP_URI_SCHEME_IS_SIP(uri) && !PJSIP_URI_SCHEME_IS_SIPS(uri))) {
+		return -1;
+	}
+
+	sip_uri = pjsip_uri_get_uri(uri);
+
+	/* Determine the transport type to use */
+	if (PJSIP_URI_SCHEME_IS_SIPS(sip_uri)) {
+		type = PJSIP_TRANSPORT_TLS;
+	} else if (!sip_uri->transport_param.slen) {
+		type = PJSIP_TRANSPORT_UDP;
+	} else {
+		type = pjsip_transport_get_type_from_name(&sip_uri->transport_param);
+	}
+
+	if (type == PJSIP_TRANSPORT_UNSPECIFIED) {
+		return -1;
+	}
+
+	/* If the host is IPv6 turn the transport into an IPv6 version */
+	if (pj_strchr(&sip_uri->host, ':')) {
+		type = (pjsip_transport_type_e)(((int)type) + PJSIP_TRANSPORT_IPV6);
+	}
+
+	/* Get the local bound address for the transport that will be used when communicating with the provided URI */
+	if (pjsip_tpmgr_find_local_addr(pjsip_endpt_get_tpmgr(ast_sip_get_pjsip_endpoint()), pool, type, selector,
+							      &local_addr, &local_port) != PJ_SUCCESS) {
+		return -1;
+	}
+
+	/* If IPv6 was not specified in the host but is in the transport, set the proper type */
+	if (!pj_strchr(&sip_uri->host, ':') && pj_strchr(&local_addr, ':')) {
+		type = (pjsip_transport_type_e)(((int)type) + PJSIP_TRANSPORT_IPV6);
+	}
+
+	from->ptr = pj_pool_alloc(pool, PJSIP_MAX_URL_SIZE);
+	from->slen = pj_ansi_snprintf(from->ptr, PJSIP_MAX_URL_SIZE,
+				      "<%s:%s@%s%.*s%s:%d%s%s>",
+				      (pjsip_transport_get_flag_from_type(type) & PJSIP_TRANSPORT_SECURE) ? "sips" : "sip",
+				      user,
+				      (type & PJSIP_TRANSPORT_IPV6) ? "[" : "",
+				      (int)local_addr.slen,
+				      local_addr.ptr,
+				      (type & PJSIP_TRANSPORT_IPV6) ? "]" : "",
+				      local_port,
+				      (type != PJSIP_TRANSPORT_UDP && type != PJSIP_TRANSPORT_UDP6) ? ";transport=" : "",
+				      (type != PJSIP_TRANSPORT_UDP && type != PJSIP_TRANSPORT_UDP6) ? pjsip_transport_get_type_name(type) : "");
+
+	return 0;
+}
+
+static int sip_get_tpselector_from_endpoint(const struct ast_sip_endpoint *endpoint, pjsip_tpselector *selector)
+{
+	RAII_VAR(struct ast_sip_transport *, transport, NULL, ao2_cleanup);
+	const char *transport_name = endpoint->transport;
+
+	if (ast_strlen_zero(transport_name)) {
+		return 0;
+	}
+
+	transport = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "transport", transport_name);
+
+	if (!transport || !transport->state) {
+		return -1;
+	}
+
+	if (transport->type == AST_SIP_TRANSPORT_UDP) {
+		selector->type = PJSIP_TPSELECTOR_TRANSPORT;
+		selector->u.transport = transport->state->transport;
+	} else if (transport->type == AST_SIP_TRANSPORT_TCP || transport->type == AST_SIP_TRANSPORT_TLS) {
+		selector->type = PJSIP_TPSELECTOR_LISTENER;
+		selector->u.listener = transport->state->factory;
+	} else {
+		return -1;
+	}
+
+	return 0;
+}
+
+pjsip_dialog *ast_sip_create_dialog(const struct ast_sip_endpoint *endpoint, const char *uri, const char *request_user)
+{
+	pj_str_t local_uri = { "sip:temp@temp", 13 }, remote_uri;
+	pjsip_dialog *dlg = NULL;
+	const char *outbound_proxy = endpoint->outbound_proxy;
+	pjsip_tpselector selector = { .type = PJSIP_TPSELECTOR_NONE, };
+	static const pj_str_t HCONTACT = { "Contact", 7 };
+
+	pj_cstr(&remote_uri, uri);
+
+	if (pjsip_dlg_create_uac(pjsip_ua_instance(), &local_uri, NULL, &remote_uri, NULL, &dlg) != PJ_SUCCESS) {
+		return NULL;
+	}
+
+	if (sip_get_tpselector_from_endpoint(endpoint, &selector)) {
+		pjsip_dlg_terminate(dlg);
+		return NULL;
+	}
+
+	if (sip_dialog_create_from(dlg->pool, &local_uri, NULL, &remote_uri, &selector)) {
+		pjsip_dlg_terminate(dlg);
+		return NULL;
+	}
+
+	/* Update the dialog with the new local URI, we do it afterwards so we can use the dialog pool for construction */
+	pj_strdup_with_null(dlg->pool, &dlg->local.info_str, &local_uri);
+	dlg->local.info->uri = pjsip_parse_uri(dlg->pool, dlg->local.info_str.ptr, dlg->local.info_str.slen, 0);
+	dlg->local.contact = pjsip_parse_hdr(dlg->pool, &HCONTACT, local_uri.ptr, local_uri.slen, NULL);
+
+	/* If a request user has been specified and we are permitted to change it, do so */
+	if (!ast_strlen_zero(request_user) && (PJSIP_URI_SCHEME_IS_SIP(dlg->target) || PJSIP_URI_SCHEME_IS_SIPS(dlg->target))) {
+		pjsip_sip_uri *target = pjsip_uri_get_uri(dlg->target);
+		pj_strdup2(dlg->pool, &target->user, request_user);
+	}
+
+	/* We have to temporarily bump up the sess_count here so the dialog is not prematurely destroyed */
+	dlg->sess_count++;
+
+	pjsip_dlg_set_transport(dlg, &selector);
+
+	if (!ast_strlen_zero(outbound_proxy)) {
+		pjsip_route_hdr route_set, *route;
+		static const pj_str_t ROUTE_HNAME = { "Route", 5 };
+		pj_str_t tmp;
+
+		pj_list_init(&route_set);
+
+		pj_strdup2_with_null(dlg->pool, &tmp, outbound_proxy);
+		if (!(route = pjsip_parse_hdr(dlg->pool, &ROUTE_HNAME, tmp.ptr, tmp.slen, NULL))) {
+			pjsip_dlg_terminate(dlg);
+			return NULL;
+		}
+		pj_list_push_back(&route_set, route);
+
+		pjsip_dlg_set_route_set(dlg, &route_set);
+	}
+
+	dlg->sess_count--;
+
+	return dlg;
+}
+
+/* PJSIP doesn't know about the INFO method, so we have to define it ourselves */
+const pjsip_method pjsip_info_method = {PJSIP_OTHER_METHOD, {"INFO", 4} };
+
+static struct {
+	const char *method;
+	const pjsip_method *pmethod;
+} methods [] = {
+	{ "INVITE", &pjsip_invite_method },
+	{ "CANCEL", &pjsip_cancel_method },
+	{ "ACK", &pjsip_ack_method },
+	{ "BYE", &pjsip_bye_method },
+	{ "REGISTER", &pjsip_register_method },
+	{ "OPTIONS", &pjsip_options_method },
+	{ "SUBSCRIBE", &pjsip_subscribe_method },
+	{ "NOTIFY", &pjsip_notify_method },
+	{ "PUBLISH", &pjsip_publish_method },
+	{ "INFO", &pjsip_info_method },
+};
+
+static const pjsip_method *get_pjsip_method(const char *method)
+{
+	int i;
+	for (i = 0; i < ARRAY_LEN(methods); ++i) {
+		if (!strcmp(method, methods[i].method)) {
+			return methods[i].pmethod;
+		}
+	}
+	return NULL;
+}
+
+static int create_in_dialog_request(const pjsip_method *method, struct pjsip_dialog *dlg, pjsip_tx_data **tdata)
+{
+	if (pjsip_dlg_create_request(dlg, method, -1, tdata) != PJ_SUCCESS) {
+		ast_log(LOG_WARNING, "Unable to create in-dialog request.\n");
+		return -1;
+	}
+
+	return 0;
+}
+
+static int create_out_of_dialog_request(const pjsip_method *method, struct ast_sip_endpoint *endpoint,
+		const char *uri, pjsip_tx_data **tdata)
+{
+	RAII_VAR(struct ast_sip_contact *, contact, NULL, ao2_cleanup);
+	pj_str_t remote_uri;
+	pj_str_t from;
+	pj_pool_t *pool;
+	pjsip_tpselector selector = { .type = PJSIP_TPSELECTOR_NONE, };
+
+	if (ast_strlen_zero(uri)) {
+		contact = ast_sip_location_retrieve_contact_from_aor_list(endpoint->aors);
+		if (!contact || ast_strlen_zero(contact->uri)) {
+			ast_log(LOG_ERROR, "Unable to retrieve contact for endpoint %s\n",
+					ast_sorcery_object_get_id(endpoint));
+			return -1;
+		}
+
+		pj_cstr(&remote_uri, contact->uri);
+	} else {
+		pj_cstr(&remote_uri, uri);
+	}
+
+	if (sip_get_tpselector_from_endpoint(endpoint, &selector)) {
+		ast_log(LOG_ERROR, "Unable to retrieve PJSIP transport selector for endpoint %s\n",
+				ast_sorcery_object_get_id(endpoint));
+		return -1;
+	}
+
+	pool = pjsip_endpt_create_pool(ast_sip_get_pjsip_endpoint(), "Outbound request", 256, 256);
+
+	if (!pool) {
+		ast_log(LOG_ERROR, "Unable to create PJLIB memory pool\n");
+		return -1;
+	}
+
+	if (sip_dialog_create_from(pool, &from, NULL, &remote_uri, &selector)) {
+		ast_log(LOG_ERROR, "Unable to create From header for %.*s request to endpoint %s\n",
+				(int) pj_strlen(&method->name), pj_strbuf(&method->name), ast_sorcery_object_get_id(endpoint));
+		pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), pool);
+		return -1;
+	}
+
+	if (pjsip_endpt_create_request(ast_sip_get_pjsip_endpoint(), method, &remote_uri,
+			&from, &remote_uri, &from, NULL, -1, NULL, tdata) != PJ_SUCCESS) {
+		ast_log(LOG_ERROR, "Unable to create outbound %.*s request to endpoint %s\n",
+				(int) pj_strlen(&method->name), pj_strbuf(&method->name), ast_sorcery_object_get_id(endpoint));
+		pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), pool);
+		return -1;
+	}
+
+	/* We can release this pool since request creation copied all the necessary
+	 * data into the outbound request's pool
+	 */
+	pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), pool);
+	return 0;
+}
+
+int ast_sip_create_request(const char *method, struct pjsip_dialog *dlg,
+		struct ast_sip_endpoint *endpoint, const char *uri, pjsip_tx_data **tdata)
+{
+	const pjsip_method *pmethod = get_pjsip_method(method);
+
+	if (!pmethod) {
+		ast_log(LOG_WARNING, "Unknown method '%s'. Cannot send request\n", method);
+		return -1;
+	}
+
+	if (dlg) {
+		return create_in_dialog_request(pmethod, dlg, tdata);
+	} else {
+		return create_out_of_dialog_request(pmethod, endpoint, uri, tdata);
+	}
+}
+
+static int send_in_dialog_request(pjsip_tx_data *tdata, struct pjsip_dialog *dlg)
+{
+	if (pjsip_dlg_send_request(dlg, tdata, -1, NULL) != PJ_SUCCESS) {
+		ast_log(LOG_WARNING, "Unable to send in-dialog request.\n");
+		return -1;
+	}
+	return 0;
+}
+
+static void send_request_cb(void *token, pjsip_event *e)
+{
+	RAII_VAR(struct ast_sip_endpoint *, endpoint, token, ao2_cleanup);
+	pjsip_transaction *tsx = e->body.tsx_state.tsx;
+	pjsip_rx_data *challenge = e->body.tsx_state.src.rdata;
+	pjsip_tx_data *tdata;
+
+	if (tsx->status_code != 401 && tsx->status_code != 407) {
+		return;
+	}
+
+	if (!ast_sip_create_request_with_auth(endpoint->sip_outbound_auths, endpoint->num_outbound_auths, challenge, tsx, &tdata)) {
+		pjsip_endpt_send_request(ast_sip_get_pjsip_endpoint(), tdata, -1, NULL, NULL);
+	}
+}
+
+static int send_out_of_dialog_request(pjsip_tx_data *tdata, struct ast_sip_endpoint *endpoint)
+{
+	ao2_ref(endpoint, +1);
+	if (pjsip_endpt_send_request(ast_sip_get_pjsip_endpoint(), tdata, -1, endpoint, send_request_cb) != PJ_SUCCESS) {
+		ast_log(LOG_ERROR, "Error attempting to send outbound %.*s request to endpoint %s\n",
+				(int) pj_strlen(&tdata->msg->line.req.method.name),
+				pj_strbuf(&tdata->msg->line.req.method.name),
+				ast_sorcery_object_get_id(endpoint));
+		ao2_ref(endpoint, -1);
+		return -1;
+	}
+
+	return 0;
+}
+
+int ast_sip_send_request(pjsip_tx_data *tdata, struct pjsip_dialog *dlg, struct ast_sip_endpoint *endpoint)
+{
+	ast_assert(tdata->msg->type == PJSIP_REQUEST_MSG);
+
+	if (dlg) {
+		return send_in_dialog_request(tdata, dlg);
+	} else {
+		return send_out_of_dialog_request(tdata, endpoint);
+	}
+}
+
+int ast_sip_add_header(pjsip_tx_data *tdata, const char *name, const char *value)
+{
+	pj_str_t hdr_name;
+	pj_str_t hdr_value;
+	pjsip_generic_string_hdr *hdr;
+	
+	pj_cstr(&hdr_name, name);
+	pj_cstr(&hdr_value, value);
+
+	hdr = pjsip_generic_string_hdr_create(tdata->pool, &hdr_name, &hdr_value);
+
+	pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr *) hdr);
+	return 0;
+}
+
+static pjsip_msg_body *ast_body_to_pjsip_body(pj_pool_t *pool, const struct ast_sip_body *body)
+{
+	pj_str_t type;
+	pj_str_t subtype;
+	pj_str_t body_text;
+
+	pj_cstr(&type, body->type);
+	pj_cstr(&subtype, body->subtype);
+	pj_cstr(&body_text, body->body_text);
+	
+	return pjsip_msg_body_create(pool, &type, &subtype, &body_text);
+}
+
+int ast_sip_add_body(pjsip_tx_data *tdata, const struct ast_sip_body *body)
+{
+	pjsip_msg_body *pjsip_body = ast_body_to_pjsip_body(tdata->pool, body);
+	tdata->msg->body = pjsip_body;
+	return 0;
+}
+
+int ast_sip_add_body_multipart(pjsip_tx_data *tdata, const struct ast_sip_body *bodies[], int num_bodies)
+{
+	int i;
+	/* NULL for type and subtype automatically creates "multipart/mixed" */
+	pjsip_msg_body *body = pjsip_multipart_create(tdata->pool, NULL, NULL);
+
+	for (i = 0; i < num_bodies; ++i) {
+		pjsip_multipart_part *part = pjsip_multipart_create_part(tdata->pool);
+		part->body = ast_body_to_pjsip_body(tdata->pool, bodies[i]);
+		pjsip_multipart_add_part(tdata->pool, body, part);
+	}
+
+	tdata->msg->body = body;
+	return 0;
+}
+
+int ast_sip_append_body(pjsip_tx_data *tdata, const char *body_text)
+{
+	size_t combined_size = strlen(body_text) + tdata->msg->body->len;
+	struct ast_str *body_buffer = ast_str_alloca(combined_size);
+
+	ast_str_set(&body_buffer, 0, "%.*s%s", (int) tdata->msg->body->len, (char *) tdata->msg->body->data, body_text);
+
+	tdata->msg->body->data = pj_pool_alloc(tdata->pool, combined_size);
+	pj_memcpy(tdata->msg->body->data, ast_str_buffer(body_buffer), combined_size);
+	tdata->msg->body->len = combined_size;
+
+	return 0;
+}
+
+struct ast_taskprocessor *ast_sip_create_serializer(void)
+{
+	struct ast_taskprocessor *serializer;
+	RAII_VAR(struct ast_uuid *, uuid, ast_uuid_generate(), ast_free_ptr);
+	char name[AST_UUID_STR_LEN];
+
+	if (!uuid) {
+		return NULL;
+	}
+
+	ast_uuid_to_str(uuid, name, sizeof(name));
+
+	serializer = ast_threadpool_serializer(name, sip_threadpool);
+	if (!serializer) {
+		return NULL;
+	}
+	return serializer;
+}
+
+int ast_sip_push_task(struct ast_taskprocessor *serializer, int (*sip_task)(void *), void *task_data)
+{
+	if (serializer) {
+		return ast_taskprocessor_push(serializer, sip_task, task_data);
+	} else {
+		return ast_threadpool_push(sip_threadpool, sip_task, task_data);
+	}
+}
+
+struct sync_task_data {
+	ast_mutex_t lock;
+	ast_cond_t cond;
+	int complete;
+	int fail;
+	int (*task)(void *);
+	void *task_data;
+};
+
+static int sync_task(void *data)
+{
+	struct sync_task_data *std = data;
+	std->fail = std->task(std->task_data);
+
+	ast_mutex_lock(&std->lock);
+	std->complete = 1;
+	ast_cond_signal(&std->cond);
+	ast_mutex_unlock(&std->lock);
+	return std->fail;
+}
+
+int ast_sip_push_task_synchronous(struct ast_taskprocessor *serializer, int (*sip_task)(void *), void *task_data)
+{
+	/* This method is an onion */
+	struct sync_task_data std;
+	ast_mutex_init(&std.lock);
+	ast_cond_init(&std.cond, NULL);
+	std.fail = std.complete = 0;
+	std.task = sip_task;
+	std.task_data = task_data;
+
+	if (serializer) {
+		if (ast_taskprocessor_push(serializer, sync_task, &std)) {
+			return -1;
+		}
+	} else {
+		if (ast_threadpool_push(sip_threadpool, sync_task, &std)) {
+			return -1;
+		}
+	}
+
+	ast_mutex_lock(&std.lock);
+	while (!std.complete) {
+		ast_cond_wait(&std.cond, &std.lock);
+	}
+	ast_mutex_unlock(&std.lock);
+
+	ast_mutex_destroy(&std.lock);
+	ast_cond_destroy(&std.cond);
+	return std.fail;
+}
+
+void ast_copy_pj_str(char *dest, pj_str_t *src, size_t size)
+{
+	size_t chars_to_copy = MIN(size - 1, pj_strlen(src));
+	memcpy(dest, pj_strbuf(src), chars_to_copy);
+	dest[chars_to_copy] = '\0';
+}
+
+pj_caching_pool caching_pool;
+pj_pool_t *memory_pool;
+pj_thread_t *monitor_thread;
+static int monitor_continue;
+
+static void *monitor_thread_exec(void *endpt)
+{
+	while (monitor_continue) {
+		const pj_time_val delay = {0, 10};
+		pjsip_endpt_handle_events(ast_pjsip_endpoint, &delay);
+	}
+	return NULL;
+}
+
+static void stop_monitor_thread(void)
+{
+	monitor_continue = 0;
+	pj_thread_join(monitor_thread);
+}
+
+AST_THREADSTORAGE(pj_thread_storage);
+AST_THREADSTORAGE(servant_id_storage);
+#define SIP_SERVANT_ID 0xDEFECA7E
+
+static void sip_thread_start(void)
+{
+	pj_thread_desc *desc;
+	pj_thread_t *thread;
+	uint32_t *servant_id;
+
+	servant_id = ast_threadstorage_get(&servant_id_storage, sizeof(*servant_id));
+	if (!servant_id) {
+		ast_log(LOG_ERROR, "Could not set SIP servant ID in thread-local storage.\n");
+		return;
+	}
+	*servant_id = SIP_SERVANT_ID;
+
+	desc = ast_threadstorage_get(&pj_thread_storage, sizeof(pj_thread_desc));
+	if (!desc) {
+		ast_log(LOG_ERROR, "Could not get thread desc from thread-local storage. Expect awful things to occur\n");
+		return;
+	}
+	pj_bzero(*desc, sizeof(*desc));
+
+	if (pj_thread_register("Asterisk Thread", *desc, &thread) != PJ_SUCCESS) {
+		ast_log(LOG_ERROR, "Couldn't register thread with PJLIB.\n");
+	}
+}
+
+int ast_sip_thread_is_servant(void)
+{
+	uint32_t *servant_id;
+
+	servant_id = ast_threadstorage_get(&servant_id_storage, sizeof(*servant_id));
+	if (!servant_id) {
+		return 0;
+	}
+
+	return *servant_id == SIP_SERVANT_ID;
+}
+
+static int load_module(void)
+{
+    /* The third parameter is just copied from
+     * example code from PJLIB. This can be adjusted
+     * if necessary.
+	 */
+	pj_status_t status;
+
+	/* XXX For the time being, create hard-coded threadpool
+	 * options. Just bump up by five threads every time we
+	 * don't have any available threads. Idle threads time
+	 * out after a minute. No maximum size
+	 */
+	struct ast_threadpool_options options = {
+		.version = AST_THREADPOOL_OPTIONS_VERSION,
+		.auto_increment = 5,
+		.max_size = 0,
+		.idle_timeout = 60,
+		.initial_size = 0,
+		.thread_start = sip_thread_start,
+	};
+	sip_threadpool = ast_threadpool_create("SIP", NULL, &options);
+
+	if (pj_init() != PJ_SUCCESS) {
+		return AST_MODULE_LOAD_DECLINE;
+	}
+
+	if (pjlib_util_init() != PJ_SUCCESS) {
+		pj_shutdown();
+		return AST_MODULE_LOAD_DECLINE;
+	}
+
+	pj_caching_pool_init(&caching_pool, NULL, 1024 * 1024);
+	if (pjsip_endpt_create(&caching_pool.factory, "SIP", &ast_pjsip_endpoint) != PJ_SUCCESS) {
+		ast_log(LOG_ERROR, "Failed to create PJSIP endpoint structure. Aborting load\n");
+		goto error;
+	}
+	memory_pool = pj_pool_create(&caching_pool.factory, "SIP", 1024, 1024, NULL);
+	if (!memory_pool) {
+		ast_log(LOG_ERROR, "Failed to create memory pool for SIP. Aborting load\n");
+		goto error;
+	}
+
+	pjsip_tsx_layer_init_module(ast_pjsip_endpoint);
+	pjsip_ua_init_module(ast_pjsip_endpoint, NULL);
+
+	monitor_continue = 1;
+	status = pj_thread_create(memory_pool, "SIP", (pj_thread_proc *) &monitor_thread_exec,
+			NULL, PJ_THREAD_DEFAULT_STACK_SIZE * 2, 0, &monitor_thread);
+	if (status != PJ_SUCCESS) {
+		ast_log(LOG_ERROR, "Failed to start SIP monitor thread. Aborting load\n");
+		goto error;
+	}
+
+	if (ast_res_sip_initialize_configuration()) {
+		ast_log(LOG_ERROR, "Failed to initialize SIP configuration. Aborting load\n");
+		goto error;
+	}
+
+	if (ast_sip_initialize_distributor()) {
+		ast_log(LOG_ERROR, "Failed to register distributor module. Aborting load\n");
+		goto error;
+	}
+
+	if (ast_sip_initialize_outbound_authentication()) {
+		ast_log(LOG_ERROR, "Failed to initialize outbound authentication. Aborting load\n");
+		goto error;
+	}
+
+	ast_res_sip_init_options_handling(0);
+
+return AST_MODULE_LOAD_SUCCESS;
+
+error:
+	ast_res_sip_destroy_configuration();
+	if (monitor_thread) {
+		stop_monitor_thread();
+	}
+	if (memory_pool) {
+		pj_pool_release(memory_pool);
+		memory_pool = NULL;
+	}
+	if (ast_pjsip_endpoint) {
+		pjsip_endpt_destroy(ast_pjsip_endpoint);
+		ast_pjsip_endpoint = NULL;
+	}
+	pj_caching_pool_destroy(&caching_pool);
+	/* XXX Should have a way of stopping monitor thread */
+	return AST_MODULE_LOAD_DECLINE;
+}
+
+static int reload_module(void)
+{
+	if (ast_res_sip_reload_configuration()) {
+		return AST_MODULE_LOAD_DECLINE;
+	}
+	ast_res_sip_init_options_handling(1);
+	return 0;
+}
+
+static int unload_pjsip(void *data)
+{
+	if (memory_pool) {
+		pj_pool_release(memory_pool);
+		memory_pool = NULL;
+	}
+	if (ast_pjsip_endpoint) {
+		pjsip_endpt_destroy(ast_pjsip_endpoint);
+		ast_pjsip_endpoint = NULL;
+	}
+	pj_caching_pool_destroy(&caching_pool);
+	return 0;
+}
+
+static int unload_module(void)
+{
+	ast_res_sip_destroy_configuration();
+	if (monitor_thread) {
+		stop_monitor_thread();
+	}
+	/* The thread this is called from cannot call PJSIP/PJLIB functions,
+	 * so we have to push the work to the threadpool to handle
+	 */
+	ast_sip_push_task_synchronous(NULL, unload_pjsip, NULL);
+
+	ast_threadpool_shutdown(sip_threadpool);
+
+	return 0;
+}
+
+AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_LOAD_ORDER, "Basic SIP resource",
+		.load = load_module,
+		.unload = unload_module,
+		.reload = reload_module,
+		.load_pri = AST_MODPRI_CHANNEL_DEPEND,
+);
diff --git a/res/res_sip.exports.in b/res/res_sip.exports.in
new file mode 100644
index 0000000000000000000000000000000000000000..010f90cb1db9b80f227e1dcb106670b0cfca4f84
--- /dev/null
+++ b/res/res_sip.exports.in
@@ -0,0 +1,52 @@
+{
+	global:
+		LINKER_SYMBOL_PREFIXast_sip_register_service;
+		LINKER_SYMBOL_PREFIXast_sip_unregister_service;
+		LINKER_SYMBOL_PREFIXast_sip_register_authenticator;
+		LINKER_SYMBOL_PREFIXast_sip_unregister_authenticator;
+		LINKER_SYMBOL_PREFIXast_sip_register_outbound_authenticator;
+		LINKER_SYMBOL_PREFIXast_sip_unregister_outbound_authenticator;
+		LINKER_SYMBOL_PREFIXast_sip_register_endpoint_identifier;
+		LINKER_SYMBOL_PREFIXast_sip_unregister_endpoint_identifier;
+		LINKER_SYMBOL_PREFIXast_sip_create_serializer;
+		LINKER_SYMBOL_PREFIXast_sip_push_task;
+		LINKER_SYMBOL_PREFIXast_sip_push_task_synchronous;
+		LINKER_SYMBOL_PREFIXast_sip_create_request;
+		LINKER_SYMBOL_PREFIXast_sip_create_request_with_auth;
+		LINKER_SYMBOL_PREFIXast_sip_send_request;
+		LINKER_SYMBOL_PREFIXast_sip_requires_authentication;
+		LINKER_SYMBOL_PREFIXast_sip_authenticate_request;
+		LINKER_SYMBOL_PREFIXast_sip_get_authentication_credentials;
+		LINKER_SYMBOL_PREFIXast_sip_check_authentication;
+		LINKER_SYMBOL_PREFIXast_sip_create_auth_challenge_response;
+		LINKER_SYMBOL_PREFIXast_sip_set_outbound_authentication_credentials;
+		LINKER_SYMBOL_PREFIXast_sip_dialog_setup_outbound_authentication;
+		LINKER_SYMBOL_PREFIXast_sip_add_digest_to_challenge;
+		LINKER_SYMBOL_PREFIXast_sip_identify_endpoint;
+		LINKER_SYMBOL_PREFIXast_sip_add_header;
+		LINKER_SYMBOL_PREFIXast_sip_add_body;
+		LINKER_SYMBOL_PREFIXast_sip_add_body_multipart;
+		LINKER_SYMBOL_PREFIXast_sip_append_body;
+		LINKER_SYMBOL_PREFIXast_sip_get_pjsip_endpoint;
+		LINKER_SYMBOL_PREFIXast_sip_endpoint_alloc;
+		LINKER_SYMBOL_PREFIXast_copy_pj_str;
+		LINKER_SYMBOL_PREFIXast_sip_get_sorcery;
+		LINKER_SYMBOL_PREFIXast_sip_create_dialog;
+		LINKER_SYMBOL_PREFIXast_sip_location_retrieve_aor;
+		LINKER_SYMBOL_PREFIXast_sip_location_retrieve_first_aor_contact;
+		LINKER_SYMBOL_PREFIXast_sip_location_retrieve_contact_from_aor_list;
+		LINKER_SYMBOL_PREFIXast_sip_location_retrieve_aor_contacts;
+		LINKER_SYMBOL_PREFIXast_sip_location_retrieve_contact;
+		LINKER_SYMBOL_PREFIXast_sip_location_add_contact;
+		LINKER_SYMBOL_PREFIXast_sip_location_update_contact;
+		LINKER_SYMBOL_PREFIXast_sip_location_delete_contact;
+		LINKER_SYMBOL_PREFIXast_pjsip_rdata_get_endpoint;
+		LINKER_SYMBOL_PREFIXast_sip_thread_is_servant;
+		LINKER_SYMBOL_PREFIXast_sip_dialog_set_serializer;
+		LINKER_SYMBOL_PREFIXast_sip_dialog_set_endpoint;
+		LINKER_SYMBOL_PREFIXast_sip_dialog_get_endpoint;
+		LINKER_SYMBOL_PREFIXast_sip_retrieve_auths;
+		LINKER_SYMBOL_PREFIXast_sip_cleanup_auths;
+	local:
+		*;
+};
diff --git a/res/res_sip/config_auth.c b/res/res_sip/config_auth.c
new file mode 100644
index 0000000000000000000000000000000000000000..9881dd8c6435a28d02db0fd1216611dda02ad004
--- /dev/null
+++ b/res/res_sip/config_auth.c
@@ -0,0 +1,120 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2013, Digium, Inc.
+ *
+ * Mark Michelson <mmichelson@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+#include "asterisk.h"
+
+#include <pjsip.h>
+#include <pjlib.h>
+#include "asterisk/res_sip.h"
+#include "asterisk/logger.h"
+#include "asterisk/sorcery.h"
+
+static void auth_destroy(void *obj)
+{
+	struct ast_sip_auth *auth = obj;
+	ast_string_field_free_memory(auth);
+}
+
+static void *auth_alloc(const char *name)
+{
+	struct ast_sip_auth *auth = ao2_alloc(sizeof(*auth), auth_destroy);
+
+	if (!auth) {
+		return NULL;
+	}
+
+	if (ast_string_field_init(auth, 64)) {
+		ao2_cleanup(auth);
+		return NULL;
+	}
+
+	return auth;
+}
+
+static int auth_type_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
+{
+	struct ast_sip_auth *auth = obj;
+	if (!strcasecmp(var->value, "userpass")) {
+		auth->type = AST_SIP_AUTH_TYPE_USER_PASS;
+	} else if (!strcasecmp(var->value, "md5")) {
+		auth->type = AST_SIP_AUTH_TYPE_MD5;
+	} else {
+		ast_log(LOG_WARNING, "Unknown authentication storage type '%s' specified for %s\n",
+				var->value, var->name);
+		return -1;
+	}
+	return 0;
+}
+
+static int auth_apply(const struct ast_sorcery *sorcery, void *obj)
+{
+	struct ast_sip_auth *auth = obj;
+	int res = 0;
+
+	if (ast_strlen_zero(auth->auth_user)) {
+		ast_log(LOG_ERROR, "No authentication username for auth '%s'\n",
+				ast_sorcery_object_get_id(auth));
+		return -1;
+	}
+
+	switch (auth->type) {
+	case AST_SIP_AUTH_TYPE_USER_PASS:
+		if (ast_strlen_zero(auth->auth_pass)) {
+			ast_log(LOG_ERROR, "'userpass' authentication specified but no"
+					"password specified for auth '%s'\n", ast_sorcery_object_get_id(auth));
+			res = -1;
+		}
+		break;
+	case AST_SIP_AUTH_TYPE_MD5:
+		if (ast_strlen_zero(auth->md5_creds)) {
+			ast_log(LOG_ERROR, "'md5' authentication specified but no md5_cred"
+					"specified for auth '%s'\n", ast_sorcery_object_get_id(auth));
+			res = -1;
+		}
+		break;
+	}
+
+	return res;
+}
+
+/*! \brief Initialize sorcery with auth support */
+int ast_sip_initialize_sorcery_auth(struct ast_sorcery *sorcery)
+{
+	ast_sorcery_apply_default(sorcery, SIP_SORCERY_AUTH_TYPE, "config", "res_sip.conf,criteria=type=auth");
+
+	if (ast_sorcery_object_register(sorcery, SIP_SORCERY_AUTH_TYPE, auth_alloc, NULL, auth_apply)) {
+		return -1;
+	}
+
+	ast_sorcery_object_field_register(sorcery, SIP_SORCERY_AUTH_TYPE, "type", "",
+			OPT_NOOP_T, 0, 0);
+	ast_sorcery_object_field_register(sorcery, SIP_SORCERY_AUTH_TYPE, "username",
+			"", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_auth, auth_user));
+	ast_sorcery_object_field_register(sorcery, SIP_SORCERY_AUTH_TYPE, "password",
+			"", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_auth, auth_pass));
+	ast_sorcery_object_field_register(sorcery, SIP_SORCERY_AUTH_TYPE, "md5_cred",
+			"", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_auth, md5_creds));
+	ast_sorcery_object_field_register(sorcery, SIP_SORCERY_AUTH_TYPE, "realm",
+			"asterisk", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_auth, realm));
+	ast_sorcery_object_field_register(sorcery, SIP_SORCERY_AUTH_TYPE, "nonce_lifetime",
+			"32", OPT_UINT_T, 0, FLDSET(struct ast_sip_auth, nonce_lifetime));
+	ast_sorcery_object_field_register_custom(sorcery, SIP_SORCERY_AUTH_TYPE, "auth_type",
+			"userpass", auth_type_handler, NULL, 0, 0);
+
+	return 0;
+}
diff --git a/res/res_sip/config_domain_aliases.c b/res/res_sip/config_domain_aliases.c
new file mode 100644
index 0000000000000000000000000000000000000000..86b4636ea7b607bede808658feb693caf630dc6a
--- /dev/null
+++ b/res/res_sip/config_domain_aliases.c
@@ -0,0 +1,65 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2013, Digium, Inc.
+ *
+ * Joshua Colp <jcolp@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+#include "asterisk.h"
+
+#include "pjsip.h"
+#include "pjlib.h"
+#include "asterisk/res_sip.h"
+#include "asterisk/logger.h"
+#include "asterisk/sorcery.h"
+
+static void domain_alias_destroy(void *obj)
+{
+	struct ast_sip_domain_alias *alias = obj;
+
+	ast_string_field_free_memory(alias);
+}
+
+static void *domain_alias_alloc(const char *name)
+{
+	struct ast_sip_domain_alias *alias = ao2_alloc(sizeof(*alias), domain_alias_destroy);
+
+	if (!alias) {
+		return NULL;
+	}
+
+	if (ast_string_field_init(alias, 256)) {
+		ao2_cleanup(alias);
+		return NULL;
+	}
+
+	return alias;
+}
+
+/*! \brief Initialize sorcery with domain alias support */
+int ast_sip_initialize_sorcery_domain_alias(struct ast_sorcery *sorcery)
+{
+	ast_sorcery_apply_default(sorcery, SIP_SORCERY_DOMAIN_ALIAS_TYPE, "config", "res_sip.conf,criteria=type=domain_alias");
+
+	if (ast_sorcery_object_register(sorcery, SIP_SORCERY_DOMAIN_ALIAS_TYPE, domain_alias_alloc, NULL, NULL)) {
+		return -1;
+	}
+
+	ast_sorcery_object_field_register(sorcery, SIP_SORCERY_DOMAIN_ALIAS_TYPE, "type", "",
+			OPT_NOOP_T, 0, 0);
+	ast_sorcery_object_field_register(sorcery, SIP_SORCERY_DOMAIN_ALIAS_TYPE, "domain",
+			"", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_domain_alias, domain));
+
+	return 0;
+}
diff --git a/res/res_sip/config_transport.c b/res/res_sip/config_transport.c
new file mode 100644
index 0000000000000000000000000000000000000000..eb89ee44ee314943f85cc2d338d9ce2faee647f8
--- /dev/null
+++ b/res/res_sip/config_transport.c
@@ -0,0 +1,299 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2013, Digium, Inc.
+ *
+ * Joshua Colp <jcolp@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+#include "asterisk.h"
+
+#include <pjsip.h>
+#include <pjlib.h>
+
+#include "asterisk/res_sip.h"
+#include "asterisk/logger.h"
+#include "asterisk/astobj2.h"
+#include "asterisk/sorcery.h"
+#include "asterisk/acl.h"
+
+static int destroy_transport_state(void *data)
+{
+	pjsip_transport *transport = data;
+	pjsip_transport_shutdown(transport);
+	return 0;
+}
+
+/*! \brief Destructor for transport state information */
+static void transport_state_destroy(void *obj)
+{
+	struct ast_sip_transport_state *state = obj;
+
+	if (state->transport) {
+		ast_sip_push_task_synchronous(NULL, destroy_transport_state, state->transport);
+	}
+}
+
+/*! \brief Destructor for transport */
+static void transport_destroy(void *obj)
+{
+	struct ast_sip_transport *transport = obj;
+
+	ast_string_field_free_memory(transport);
+	ast_free_ha(transport->localnet);
+
+	if (transport->external_address_refresher) {
+		ast_dnsmgr_release(transport->external_address_refresher);
+	}
+
+	ao2_cleanup(transport->state);
+}
+
+/*! \brief Allocator for transport */
+static void *transport_alloc(const char *name)
+{
+	struct ast_sip_transport *transport = ao2_alloc(sizeof(*transport), transport_destroy);
+
+	if (!transport) {
+		return NULL;
+	}
+
+	if (ast_string_field_init(transport, 256)) {
+		ao2_cleanup(transport);
+		return NULL;
+	}
+
+	pjsip_tls_setting_default(&transport->tls);
+	transport->tls.ciphers = transport->ciphers;
+
+	return transport;
+}
+
+/*! \brief Apply handler for transports */
+static int transport_apply(const struct ast_sorcery *sorcery, void *obj)
+{
+	struct ast_sip_transport *transport = obj;
+	RAII_VAR(struct ast_sip_transport *, existing, ast_sorcery_retrieve_by_id(sorcery, "transport", ast_sorcery_object_get_id(obj)), ao2_cleanup);
+	pj_status_t res = -1;
+
+	if (!existing || !existing->state) {
+		if (!(transport->state = ao2_alloc(sizeof(*transport->state), transport_state_destroy))) {
+			ast_log(LOG_ERROR, "Transport state for '%s' could not be allocated\n", ast_sorcery_object_get_id(obj));
+			return -1;
+		}
+	} else {
+		transport->state = existing->state;
+		ao2_ref(transport->state, +1);
+	}
+
+	/* Once active a transport can not be reconfigured */
+	if (transport->state->transport || transport->state->factory) {
+		return -1;
+	}
+
+	/* Set default port if not present */
+	if (!pj_sockaddr_get_port(&transport->host)) {
+		pj_sockaddr_set_port(&transport->host, (transport->type == AST_SIP_TRANSPORT_TLS) ? 5061 : 5060);
+	}
+
+	/* Now that we know what address family we can set up a dnsmgr refresh for the external media address if present */
+	if (!ast_strlen_zero(transport->external_signaling_address)) {
+		if (transport->host.addr.sa_family == pj_AF_INET()) {
+			transport->external_address.ss.ss_family = AF_INET;
+		} else if (transport->host.addr.sa_family == pj_AF_INET6()) {
+			transport->external_address.ss.ss_family = AF_INET6;
+		} else {
+			ast_log(LOG_ERROR, "Unknown address family for transport '%s', could not get external signaling address\n",
+					ast_sorcery_object_get_id(obj));
+			return -1;
+		}
+
+		if (ast_dnsmgr_lookup(transport->external_signaling_address, &transport->external_address, &transport->external_address_refresher, NULL) < 0) {
+			ast_log(LOG_ERROR, "Could not create dnsmgr for external signaling address on '%s'\n", ast_sorcery_object_get_id(obj));
+			return -1;
+		}
+	}
+
+	if (transport->type == AST_SIP_TRANSPORT_UDP) {
+		if (transport->host.addr.sa_family == pj_AF_INET()) {
+			res = pjsip_udp_transport_start(ast_sip_get_pjsip_endpoint(), &transport->host.ipv4, NULL, transport->async_operations, &transport->state->transport);
+		} else if (transport->host.addr.sa_family == pj_AF_INET6()) {
+			res = pjsip_udp_transport_start6(ast_sip_get_pjsip_endpoint(), &transport->host.ipv6, NULL, transport->async_operations, &transport->state->transport);
+		}
+	} else if (transport->type == AST_SIP_TRANSPORT_TCP) {
+		pjsip_tcp_transport_cfg cfg;
+
+		pjsip_tcp_transport_cfg_default(&cfg, transport->host.addr.sa_family);
+		cfg.bind_addr = transport->host;
+		cfg.async_cnt = transport->async_operations;
+
+		res = pjsip_tcp_transport_start3(ast_sip_get_pjsip_endpoint(), &cfg, &transport->state->factory);
+	} else if (transport->type == AST_SIP_TRANSPORT_TLS) {
+		transport->tls.ca_list_file = pj_str((char*)transport->ca_list_file);
+		transport->tls.cert_file = pj_str((char*)transport->cert_file);
+		transport->tls.privkey_file = pj_str((char*)transport->privkey_file);
+		transport->tls.password = pj_str((char*)transport->password);
+
+		res = pjsip_tls_transport_start2(ast_sip_get_pjsip_endpoint(), &transport->tls, &transport->host, NULL, transport->async_operations, &transport->state->factory);
+	}
+
+	if (res != PJ_SUCCESS) {
+		char msg[PJ_ERR_MSG_SIZE];
+
+		pjsip_strerror(res, msg, sizeof(msg));
+		ast_log(LOG_ERROR, "Transport '%s' could not be started: %s\n", ast_sorcery_object_get_id(obj), msg);
+		return -1;
+	}
+	return 0;
+}
+
+/*! \brief Custom handler for turning a string protocol into an enum */
+static int transport_protocol_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
+{
+	struct ast_sip_transport *transport = obj;
+
+	if (!strcasecmp(var->value, "udp")) {
+		transport->type = AST_SIP_TRANSPORT_UDP;
+	} else if (!strcasecmp(var->value, "tcp")) {
+		transport->type = AST_SIP_TRANSPORT_TCP;
+	} else if (!strcasecmp(var->value, "tls")) {
+		transport->type = AST_SIP_TRANSPORT_TLS;
+	} else {
+		/* TODO: Implement websockets */
+		return -1;
+	}
+
+	return 0;
+}
+
+/*! \brief Custom handler for turning a string bind into a pj_sockaddr */
+static int transport_bind_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
+{
+	struct ast_sip_transport *transport = obj;
+	pj_str_t buf;
+
+	return (pj_sockaddr_parse(pj_AF_UNSPEC(), 0, pj_cstr(&buf, var->value), &transport->host) != PJ_SUCCESS) ? -1 : 0;
+}
+
+/*! \brief Custom handler for TLS boolean settings */
+static int transport_tls_bool_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
+{
+	struct ast_sip_transport *transport = obj;
+
+	if (!strcasecmp(var->name, "verify_server")) {
+		transport->tls.verify_server = ast_true(var->value) ? PJ_TRUE : PJ_FALSE;
+	} else if (!strcasecmp(var->name, "verify_client")) {
+		transport->tls.verify_client = ast_true(var->value) ? PJ_TRUE : PJ_FALSE;
+	} else if (!strcasecmp(var->name, "require_client_cert")) {
+		transport->tls.require_client_cert = ast_true(var->value) ? PJ_TRUE : PJ_FALSE;
+	} else {
+		return -1;
+	}
+
+	return 0;
+}
+
+/*! \brief Custom handler for TLS method setting */
+static int transport_tls_method_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
+{
+	struct ast_sip_transport *transport = obj;
+
+	if (!strcasecmp(var->value, "default")) {
+		transport->tls.method = PJSIP_SSL_DEFAULT_METHOD;
+	} else if (!strcasecmp(var->value, "unspecified")) {
+		transport->tls.method = PJSIP_SSL_UNSPECIFIED_METHOD;
+	} else if (!strcasecmp(var->value, "tlsv1")) {
+		transport->tls.method = PJSIP_TLSV1_METHOD;
+	} else if (!strcasecmp(var->value, "sslv2")) {
+		transport->tls.method = PJSIP_SSLV2_METHOD;
+	} else if (!strcasecmp(var->value, "sslv3")) {
+		transport->tls.method = PJSIP_SSLV3_METHOD;
+	} else if (!strcasecmp(var->value, "sslv23")) {
+		transport->tls.method = PJSIP_SSLV23_METHOD;
+	} else {
+		return -1;
+	}
+
+	return 0;
+}
+
+/*! \brief Custom handler for TLS cipher setting */
+static int transport_tls_cipher_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
+{
+	struct ast_sip_transport *transport = obj;
+	pj_ssl_cipher cipher;
+
+	if (transport->tls.ciphers_num == (SIP_TLS_MAX_CIPHERS - 1)) {
+		return -1;
+	}
+
+	/* TODO: Check this over/tweak - it's taken from pjsua for now */
+	if (!strnicmp(var->value, "0x", 2)) {
+		pj_str_t cipher_st = pj_str((char*)var->value + 2);
+		cipher = pj_strtoul2(&cipher_st, NULL, 16);
+	} else {
+		cipher = atoi(var->value);
+	}
+
+	if (pj_ssl_cipher_is_supported(cipher)) {
+		transport->ciphers[transport->tls.ciphers_num++] = cipher;
+		return 0;
+	} else {
+		ast_log(LOG_ERROR, "Cipher '%s' is unsupported\n", var->value);
+		return -1;
+	}
+}
+
+/*! \brief Custom handler for localnet setting */
+static int transport_localnet_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
+{
+	struct ast_sip_transport *transport = obj;
+	int error = 0;
+
+	if (!(transport->localnet = ast_append_ha("d", var->value, transport->localnet, &error))) {
+		return -1;
+	}
+
+	return error;
+}
+
+/*! \brief Initialize sorcery with transport support */
+int ast_sip_initialize_sorcery_transport(struct ast_sorcery *sorcery)
+{
+	ast_sorcery_apply_default(sorcery, "transport", "config", "res_sip.conf,criteria=type=transport");
+
+	if (ast_sorcery_object_register(sorcery, "transport", transport_alloc, NULL, transport_apply)) {
+		return -1;
+	}
+
+	ast_sorcery_object_field_register(sorcery, "transport", "type", "", OPT_NOOP_T, 0, 0);
+	ast_sorcery_object_field_register_custom(sorcery, "transport", "protocol", "udp", transport_protocol_handler, NULL, 0, 0);
+	ast_sorcery_object_field_register_custom(sorcery, "transport", "bind", "", transport_bind_handler, NULL, 0, 0);
+	ast_sorcery_object_field_register(sorcery, "transport", "async_operations", "1", OPT_UINT_T, 0, FLDSET(struct ast_sip_transport, async_operations));
+	ast_sorcery_object_field_register(sorcery, "transport", "ca_list_file", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_transport, ca_list_file));
+	ast_sorcery_object_field_register(sorcery, "transport", "cert_file", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_transport, cert_file));
+	ast_sorcery_object_field_register(sorcery, "transport", "privkey_file", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_transport, privkey_file));
+	ast_sorcery_object_field_register(sorcery, "transport", "password", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_transport, password));
+	ast_sorcery_object_field_register(sorcery, "transport", "external_signaling_address", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_transport, external_signaling_address));
+	ast_sorcery_object_field_register(sorcery, "transport", "external_signaling_port", "0", OPT_UINT_T, PARSE_IN_RANGE, FLDSET(struct ast_sip_transport, external_signaling_port), 0, 65535);
+	ast_sorcery_object_field_register(sorcery, "transport", "external_media_address", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_transport, external_media_address));
+	ast_sorcery_object_field_register(sorcery, "transport", "domain", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_transport, domain));
+	ast_sorcery_object_field_register_custom(sorcery, "transport", "verify_server", "", transport_tls_bool_handler, NULL, 0, 0);
+	ast_sorcery_object_field_register_custom(sorcery, "transport", "verify_client", "", transport_tls_bool_handler, NULL, 0, 0);
+	ast_sorcery_object_field_register_custom(sorcery, "transport", "require_client_cert", "", transport_tls_bool_handler, NULL, 0, 0);
+	ast_sorcery_object_field_register_custom(sorcery, "transport", "method", "", transport_tls_method_handler, NULL, 0, 0);
+	ast_sorcery_object_field_register_custom(sorcery, "transport", "cipher", "", transport_tls_cipher_handler, NULL, 0, 0);
+	ast_sorcery_object_field_register_custom(sorcery, "transport", "localnet", "", transport_localnet_handler, NULL, 0, 0);
+
+	return 0;
+}
diff --git a/res/res_sip/include/res_sip_private.h b/res/res_sip/include/res_sip_private.h
new file mode 100644
index 0000000000000000000000000000000000000000..318510aae0254d3c2fd89dc14c2d1ab4e57fe45d
--- /dev/null
+++ b/res/res_sip/include/res_sip_private.h
@@ -0,0 +1,57 @@
+/*
+ * res_sip.h
+ *
+ *  Created on: Jan 25, 2013
+ *      Author: mjordan
+ */
+
+#ifndef RES_SIP_PRIVATE_H_
+#define RES_SIP_PRIVATE_H_
+
+struct ao2_container;
+
+/*!
+ * \brief Initialize the configuration for res_sip
+ */
+int ast_res_sip_initialize_configuration(void);
+
+/*!
+ * \brief Annihilate the configuration objects
+ */
+void ast_res_sip_destroy_configuration(void);
+
+/*!
+ * \brief Reload the configuration
+ */
+int ast_res_sip_reload_configuration(void);
+
+/*!
+ * \brief Initialize OPTIONS request handling.
+ *
+ * XXX This currently includes qualifying peers. It shouldn't.
+ * That should go into a registrar. When that occurs, we won't
+ * need the reload stuff.
+ *
+ * \param reload Reload options handling
+ *
+ * \retval 0 on success
+ * \retval other on failure
+ */
+int ast_res_sip_init_options_handling(int reload);
+
+/*!
+ * \brief Initialize outbound authentication support
+ *
+ * \retval 0 Success
+ * \retval non-zero Failure
+ */
+int ast_sip_initialize_outbound_authentication(void);
+
+/*!
+ * \brief Get the current defined endpoints
+ *
+ * \retval The current endpoints loaded by res_sip
+ */
+struct ao2_container *ast_res_sip_get_endpoints(void);
+
+#endif /* RES_SIP_PRIVATE_H_ */
diff --git a/res/res_sip/location.c b/res/res_sip/location.c
new file mode 100644
index 0000000000000000000000000000000000000000..91521c813575ce87fd1cd218a23c4500d49a8544
--- /dev/null
+++ b/res/res_sip/location.c
@@ -0,0 +1,262 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2013, Digium, Inc.
+ *
+ * Joshua Colp <jcolp@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+#include "asterisk.h"
+#include "pjsip.h"
+#include "pjlib.h"
+
+#include "asterisk/res_sip.h"
+#include "asterisk/logger.h"
+#include "asterisk/astobj2.h"
+#include "asterisk/sorcery.h"
+
+/*! \brief Destructor for AOR */
+static void aor_destroy(void *obj)
+{
+	struct ast_sip_aor *aor = obj;
+
+	ao2_cleanup(aor->permanent_contacts);
+	ast_string_field_free_memory(aor);
+}
+
+/*! \brief Allocator for AOR */
+static void *aor_alloc(const char *name)
+{
+	struct ast_sip_aor *aor = ao2_alloc_options(sizeof(struct ast_sip_aor), aor_destroy, AO2_ALLOC_OPT_LOCK_NOLOCK);
+	if (!aor) {
+		return NULL;
+	}
+	ast_string_field_init(aor, 128);
+	return aor;
+}
+
+/*! \brief Destructor for contact */
+static void contact_destroy(void *obj)
+{
+	struct ast_sip_contact *contact = obj;
+
+	ast_string_field_free_memory(contact);
+}
+
+/*! \brief Allocator for contact */
+static void *contact_alloc(const char *name)
+{
+	struct ast_sip_contact *contact = ao2_alloc_options(sizeof(*contact), contact_destroy, AO2_ALLOC_OPT_LOCK_NOLOCK);
+
+	if (!contact) {
+		return NULL;
+	}
+
+	if (ast_string_field_init(contact, 256)) {
+		ao2_cleanup(contact);
+		return NULL;
+	}
+
+	return contact;
+}
+
+struct ast_sip_aor *ast_sip_location_retrieve_aor(const char *aor_name)
+{
+	return ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "aor", aor_name);
+}
+
+/*! \brief Internal callback function which deletes and unlinks any expired contacts */
+static int contact_expire(void *obj, void *arg, int flags)
+{
+	struct ast_sip_contact *contact = obj;
+
+	/* If the contact has not yet expired it is valid */
+	if (ast_tvdiff_ms(contact->expiration_time, ast_tvnow()) > 0) {
+		return 0;
+	}
+
+	ast_sip_location_delete_contact(contact);
+
+	return CMP_MATCH;
+}
+
+/*! \brief Internal callback function which links static contacts into another container */
+static int contact_link_static(void *obj, void *arg, int flags)
+{
+	struct ao2_container *dest = arg;
+
+	ao2_link_flags(dest, obj, OBJ_NOLOCK);
+	return 0;
+}
+
+/*! \brief Simple callback function which returns immediately, used to grab the first contact of an AOR */
+static int contact_find_first(void *obj, void *arg, int flags)
+{
+	return CMP_MATCH | CMP_STOP;
+}
+
+struct ast_sip_contact *ast_sip_location_retrieve_first_aor_contact(const struct ast_sip_aor *aor)
+{
+	RAII_VAR(struct ao2_container *, contacts, NULL, ao2_cleanup);
+	struct ast_sip_contact *contact;
+
+	contacts = ast_sip_location_retrieve_aor_contacts(aor);
+	if (!contacts || (ao2_container_count(contacts) == 0)) {
+		return NULL;
+	}
+
+	contact = ao2_callback(contacts, OBJ_NOLOCK, contact_find_first, NULL);
+	return contact;
+}
+
+struct ao2_container *ast_sip_location_retrieve_aor_contacts(const struct ast_sip_aor *aor)
+{
+	/* Give enough space for ^ at the beginning and ;@ at the end, since that is our object naming scheme */
+	char regex[strlen(ast_sorcery_object_get_id(aor)) + 4];
+	struct ao2_container *contacts;
+
+	snprintf(regex, sizeof(regex), "^%s;@", ast_sorcery_object_get_id(aor));
+
+	if (!(contacts = ast_sorcery_retrieve_by_regex(ast_sip_get_sorcery(), "contact", regex))) {
+		return NULL;
+	}
+
+	/* Prune any expired contacts and delete them, we do this first because static contacts can never expire */
+	ao2_callback(contacts, OBJ_NOLOCK | OBJ_NODATA | OBJ_MULTIPLE | OBJ_UNLINK, contact_expire, NULL);
+
+	/* Add any permanent contacts from the AOR */
+	if (aor->permanent_contacts) {
+		ao2_callback(aor->permanent_contacts, OBJ_NOLOCK | OBJ_NODATA, contact_link_static, contacts);
+	}
+
+	return contacts;
+}
+
+struct ast_sip_contact *ast_sip_location_retrieve_contact_from_aor_list(const char *aor_list)
+{
+	char *aor_name;
+	char *rest;
+	struct ast_sip_contact *contact = NULL;
+
+	/* If the location is still empty we have nowhere to go */
+	if (ast_strlen_zero(aor_list) || !(rest = ast_strdupa(aor_list))) {
+		ast_log(LOG_WARNING, "Unable to determine contacts from empty aor list\n");
+		return NULL;
+	}
+
+	while ((aor_name = strsep(&rest, ","))) {
+		RAII_VAR(struct ast_sip_aor *, aor, ast_sip_location_retrieve_aor(aor_name), ao2_cleanup);
+		RAII_VAR(struct ao2_container *, contacts, NULL, ao2_cleanup);
+
+		if (!aor) {
+			continue;
+		}
+		contact = ast_sip_location_retrieve_first_aor_contact(aor);
+		/* If a valid contact is available use its URI for dialing */
+		if (contact) {
+			break;
+		}
+	}
+
+	return contact;
+}
+
+struct ast_sip_contact *ast_sip_location_retrieve_contact(const char *contact_name)
+{
+	return ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "contact", contact_name);
+}
+
+int ast_sip_location_add_contact(struct ast_sip_aor *aor, const char *uri, struct timeval expiration_time)
+{
+	char name[AST_UUID_STR_LEN];
+	RAII_VAR(struct ast_sip_contact *, contact, NULL, ao2_cleanup);
+
+	snprintf(name, sizeof(name), "%s;@%s", ast_sorcery_object_get_id(aor), uri);
+
+	if (!(contact = ast_sorcery_alloc(ast_sip_get_sorcery(), "contact", name))) {
+		return -1;
+	}
+
+	ast_string_field_set(contact, uri, uri);
+	contact->expiration_time = expiration_time;
+
+	return ast_sorcery_create(ast_sip_get_sorcery(), contact);
+}
+
+int ast_sip_location_update_contact(struct ast_sip_contact *contact)
+{
+	return ast_sorcery_update(ast_sip_get_sorcery(), contact);
+}
+
+int ast_sip_location_delete_contact(struct ast_sip_contact *contact)
+{
+	return ast_sorcery_delete(ast_sip_get_sorcery(), contact);
+}
+
+/*! \brief Custom handler for translating from a string timeval to actual structure */
+static int expiration_str2struct(const struct aco_option *opt, struct ast_variable *var, void *obj)
+{
+	struct ast_sip_contact *contact = obj;
+	return ast_get_timeval(var->value, &contact->expiration_time, ast_tv(0, 0), NULL);
+}
+
+/*! \brief Custom handler for translating from an actual structure timeval to string */
+static int expiration_struct2str(const void *obj, const intptr_t *args, char **buf)
+{
+	const struct ast_sip_contact *contact = obj;
+	return (ast_asprintf(buf, "%lu", contact->expiration_time.tv_sec) < 0) ? -1 : 0;
+}
+
+/*! \brief Custom handler for permanent URIs */
+static int permanent_uri_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
+{
+	struct ast_sip_aor *aor = obj;
+	RAII_VAR(struct ast_sip_contact *, contact, NULL, ao2_cleanup);
+
+	if ((!aor->permanent_contacts && !(aor->permanent_contacts = ao2_container_alloc_options(AO2_ALLOC_OPT_LOCK_NOLOCK, 1, NULL, NULL))) ||
+		!(contact = ast_sorcery_alloc(ast_sip_get_sorcery(), "contact", NULL))) {
+		return -1;
+	}
+
+	ast_string_field_set(contact, uri, var->value);
+	ao2_link_flags(aor->permanent_contacts, contact, OBJ_NOLOCK);
+
+	return 0;
+}
+
+/*! \brief Initialize sorcery with location support */
+int ast_sip_initialize_sorcery_location(struct ast_sorcery *sorcery)
+{
+	ast_sorcery_apply_default(sorcery, "contact", "astdb", "registrar");
+	ast_sorcery_apply_default(sorcery, "aor", "config", "res_sip.conf,criteria=type=aor");
+
+	if (ast_sorcery_object_register(sorcery, "contact", contact_alloc, NULL, NULL) ||
+		ast_sorcery_object_register(sorcery, "aor", aor_alloc, NULL, NULL)) {
+		return -1;
+	}
+
+	ast_sorcery_object_field_register(sorcery, "contact", "type", "", OPT_NOOP_T, 0, 0);
+	ast_sorcery_object_field_register(sorcery, "contact", "uri", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_contact, uri));
+	ast_sorcery_object_field_register_custom(sorcery, "contact", "expiration_time", "", expiration_str2struct, expiration_struct2str, 0, 0);
+
+	ast_sorcery_object_field_register(sorcery, "aor", "type", "", OPT_NOOP_T, 0, 0);
+	ast_sorcery_object_field_register(sorcery, "aor", "minimum_expiration", "60", OPT_UINT_T, 0, FLDSET(struct ast_sip_aor, minimum_expiration));
+	ast_sorcery_object_field_register(sorcery, "aor", "maximum_expiration", "7200", OPT_UINT_T, 0, FLDSET(struct ast_sip_aor, maximum_expiration));
+	ast_sorcery_object_field_register(sorcery, "aor", "default_expiration", "3600", OPT_UINT_T, 0, FLDSET(struct ast_sip_aor, default_expiration));
+	ast_sorcery_object_field_register(sorcery, "aor", "max_contacts", "0", OPT_UINT_T, 0, FLDSET(struct ast_sip_aor, max_contacts));
+	ast_sorcery_object_field_register(sorcery, "aor", "remove_existing", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_aor, remove_existing));
+	ast_sorcery_object_field_register_custom(sorcery, "aor", "contact", "", permanent_uri_handler, NULL, 0, 0);
+	ast_sorcery_object_field_register(sorcery, "aor", "mailboxes", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_aor, mailboxes));
+
+	return 0;
+}
diff --git a/res/res_sip/sip_configuration.c b/res/res_sip/sip_configuration.c
new file mode 100644
index 0000000000000000000000000000000000000000..489ba6aec70333f88c5f7542136d72260953201e
--- /dev/null
+++ b/res/res_sip/sip_configuration.c
@@ -0,0 +1,463 @@
+/*
+ * sip_cli_commands.c
+ *
+ *  Created on: Jan 25, 2013
+ *      Author: mjordan
+ */
+
+#include "asterisk.h"
+
+#include <pjsip.h>
+#include <pjsip_ua.h>
+
+#include "asterisk/res_sip.h"
+#include "include/res_sip_private.h"
+#include "asterisk/cli.h"
+#include "asterisk/astobj2.h"
+#include "asterisk/utils.h"
+#include "asterisk/sorcery.h"
+#include "asterisk/callerid.h"
+
+static struct ast_sorcery *sip_sorcery;
+
+static char *handle_cli_show_endpoints(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
+{
+	RAII_VAR(struct ao2_container *, endpoints, NULL, ao2_cleanup);
+	struct ao2_iterator it_endpoints;
+	struct ast_sip_endpoint *endpoint;
+
+	switch (cmd) {
+	case CLI_INIT:
+		e->command = "sip show endpoints";
+		e->usage =
+			"Usage: sip show endpoints\n"
+			"       Show the registered SIP endpoints\n";
+		return NULL;
+	case CLI_GENERATE:
+		return NULL;
+	}
+
+	endpoints = ast_res_sip_get_endpoints();
+	if (!endpoints) {
+		return CLI_FAILURE;
+	}
+
+	if (!ao2_container_count(endpoints)) {
+		ast_cli(a->fd, "No endpoints found\n");
+		return CLI_SUCCESS;
+	}
+
+	ast_cli(a->fd, "Endpoints:\n");
+	it_endpoints = ao2_iterator_init(endpoints, 0);
+	while ((endpoint = ao2_iterator_next(&it_endpoints))) {
+		ast_cli(a->fd, "%s\n", ast_sorcery_object_get_id(endpoint));
+		ao2_ref(endpoint, -1);
+	}
+	ao2_iterator_destroy(&it_endpoints);
+	return CLI_SUCCESS;
+}
+
+static struct ast_cli_entry cli_commands[] = {
+	AST_CLI_DEFINE(handle_cli_show_endpoints, "Show SIP Endpoints"),
+};
+
+static int dtmf_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
+{
+	struct ast_sip_endpoint *endpoint = obj;
+
+	if (!strcasecmp(var->value, "rfc4733")) {
+		endpoint->dtmf = AST_SIP_DTMF_RFC_4733;
+	} else if (!strcasecmp(var->value, "inband")) {
+		endpoint->dtmf = AST_SIP_DTMF_INBAND;
+	} else if (!strcasecmp(var->value, "info")) {
+		endpoint->dtmf = AST_SIP_DTMF_INFO;
+	} else if (!strcasecmp(var->value, "none")) {
+		endpoint->dtmf = AST_SIP_DTMF_NONE;
+	} else {
+		return -1;
+	}
+
+	return 0;
+}
+
+static int prack_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
+{
+	struct ast_sip_endpoint *endpoint = obj;
+
+	if (ast_true(var->value)) {
+		endpoint->extensions |= PJSIP_INV_SUPPORT_100REL;
+	} else if (ast_false(var->value)) {
+		endpoint->extensions &= PJSIP_INV_SUPPORT_100REL;
+	} else if (!strcasecmp(var->value, "required")) {
+		endpoint->extensions |= PJSIP_INV_REQUIRE_100REL;
+	} else {
+		return -1;
+	}
+
+	return 0;
+}
+
+static int timers_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
+{
+	struct ast_sip_endpoint *endpoint = obj;
+
+	if (ast_true(var->value)) {
+		endpoint->extensions |= PJSIP_INV_SUPPORT_TIMER;
+	} else if (ast_false(var->value)) {
+		endpoint->extensions &= PJSIP_INV_SUPPORT_TIMER;
+	} else if (!strcasecmp(var->value, "required")) {
+		endpoint->extensions |= PJSIP_INV_REQUIRE_TIMER;
+	} else if (!strcasecmp(var->value, "always")) {
+		endpoint->extensions |= PJSIP_INV_ALWAYS_USE_TIMER;
+	} else {
+		return -1;
+	}
+
+	return 0;
+}
+
+static void destroy_auths(const char **auths, size_t num_auths)
+{
+	int i;
+	for (i = 0; i < num_auths; ++i) {
+		ast_free((char *) auths[i]);
+	}
+	ast_free(auths);
+}
+
+#define AUTH_INCREMENT 4
+
+static const char **auth_alloc(const char *value, size_t *num_auths)
+{
+	char *auths = ast_strdupa(value);
+	char *val;
+	int num_alloced = 0;
+	const char **alloced_auths = NULL;
+
+	while ((val = strsep(&auths, ","))) {
+		if (*num_auths >= num_alloced) {
+			size_t size;
+			num_alloced += AUTH_INCREMENT;
+			size = num_alloced * sizeof(char *);
+			alloced_auths = ast_realloc(alloced_auths, size);
+			if (!alloced_auths) {
+				goto failure;
+			}
+		}
+		alloced_auths[*num_auths] = ast_strdup(val);
+		if (!alloced_auths[*num_auths]) {
+			goto failure;
+		}
+		++(*num_auths);
+	}
+	return alloced_auths;
+
+failure:
+	destroy_auths(alloced_auths, *num_auths);
+	return NULL;
+}
+
+static int inbound_auth_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
+{
+	struct ast_sip_endpoint *endpoint = obj;
+
+	endpoint->sip_inbound_auths = auth_alloc(var->value, &endpoint->num_inbound_auths);
+	if (!endpoint->sip_inbound_auths) {
+		return -1;
+	}
+	return 0;
+}
+static int outbound_auth_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
+{
+	struct ast_sip_endpoint *endpoint = obj;
+
+	endpoint->sip_outbound_auths = auth_alloc(var->value, &endpoint->num_outbound_auths);
+	if (!endpoint->sip_outbound_auths) {
+		return -1;
+	}
+	return 0;
+}
+
+static int ident_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
+{
+	struct ast_sip_endpoint *endpoint = obj;
+	char *idents = ast_strdupa(var->value);
+	char *val;
+
+	while ((val = strsep(&idents, ","))) {
+		if (!strcasecmp(val, "username")) {
+			endpoint->ident_method |= AST_SIP_ENDPOINT_IDENTIFY_BY_USERNAME;
+		} else if (!strcasecmp(val, "location")) {
+			endpoint->ident_method |= AST_SIP_ENDPOINT_IDENTIFY_BY_LOCATION;
+		} else {
+			ast_log(LOG_ERROR, "Unrecognized identification method %s specified for endpoint %s\n",
+					val, ast_sorcery_object_get_id(endpoint));
+			return -1;
+		}
+	}
+	return 0;
+}
+
+static int direct_media_method_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
+{
+	struct ast_sip_endpoint *endpoint = obj;
+
+	if (!strcasecmp(var->value, "invite") || !strcasecmp(var->value, "reinvite")) {
+		endpoint->direct_media_method = AST_SIP_SESSION_REFRESH_METHOD_INVITE;
+	} else if (!strcasecmp(var->value, "update")) {
+		endpoint->direct_media_method = AST_SIP_SESSION_REFRESH_METHOD_UPDATE;
+	} else {
+		ast_log(LOG_NOTICE, "Unrecognized option value %s for %s on endpoint %s\n",
+				var->value, var->name, ast_sorcery_object_get_id(endpoint));
+		return -1;
+	}
+	return 0;
+}
+
+static int direct_media_glare_mitigation_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
+{
+	struct ast_sip_endpoint *endpoint = obj;
+
+	if (!strcasecmp(var->value, "none")) {
+		endpoint->direct_media_glare_mitigation = AST_SIP_DIRECT_MEDIA_GLARE_MITIGATION_NONE;
+	} else if (!strcasecmp(var->value, "outgoing")) {
+		endpoint->direct_media_glare_mitigation = AST_SIP_DIRECT_MEDIA_GLARE_MITIGATION_OUTGOING;
+	} else if (!strcasecmp(var->value, "incoming")) {
+		endpoint->direct_media_glare_mitigation = AST_SIP_DIRECT_MEDIA_GLARE_MITIGATION_INCOMING;
+	} else {
+		ast_log(LOG_NOTICE, "Unrecognized option value %s for %s on endpoint %s\n",
+				var->value, var->name, ast_sorcery_object_get_id(endpoint));
+		return -1;
+	}
+
+	return 0;
+}
+
+static int caller_id_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
+{
+	struct ast_sip_endpoint *endpoint = obj;
+	char cid_name[80] = { '\0' };
+	char cid_num[80] = { '\0' };
+
+	ast_callerid_split(var->value, cid_name, sizeof(cid_name), cid_num, sizeof(cid_num));
+	if (!ast_strlen_zero(cid_name)) {
+		endpoint->id.name.str = ast_strdup(cid_name);
+		if (!endpoint->id.name.str) {
+			return -1;
+		}
+		endpoint->id.name.valid = 1;
+	}
+	if (!ast_strlen_zero(cid_num)) {
+		endpoint->id.number.str = ast_strdup(cid_num);
+		if (!endpoint->id.number.str) {
+			return -1;
+		}
+		endpoint->id.number.valid = 1;
+	}
+	return 0;
+}
+
+static int caller_id_privacy_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
+{
+	struct ast_sip_endpoint *endpoint = obj;
+	int callingpres = ast_parse_caller_presentation(var->value);
+	if (callingpres == -1 && sscanf(var->value, "%d", &callingpres) != 1) {
+		return -1;
+	}
+	endpoint->id.number.presentation = callingpres;
+	endpoint->id.name.presentation = callingpres;
+	return 0;
+}
+
+static int caller_id_tag_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
+{
+	struct ast_sip_endpoint *endpoint = obj;
+	endpoint->id.tag = ast_strdup(var->value);
+	return endpoint->id.tag ? 0 : -1;
+}
+
+static void *sip_nat_hook_alloc(const char *name)
+{
+	return ao2_alloc(sizeof(struct ast_sip_nat_hook), NULL);
+}
+
+int ast_res_sip_initialize_configuration(void)
+{
+	if (ast_cli_register_multiple(cli_commands, ARRAY_LEN(cli_commands))) {
+		return -1;
+	}
+
+	if (!(sip_sorcery = ast_sorcery_open())) {
+		ast_log(LOG_ERROR, "Failed to open SIP sorcery failed to open\n");
+		return -1;
+	}
+
+	ast_sorcery_apply_config(sip_sorcery, "res_sip");
+
+	if (ast_sip_initialize_sorcery_auth(sip_sorcery)) {
+		ast_log(LOG_ERROR, "Failed to register SIP authentication support\n");
+		ast_sorcery_unref(sip_sorcery);
+		sip_sorcery = NULL;
+		return -1;
+	}
+
+	ast_sorcery_apply_default(sip_sorcery, "endpoint", "config", "res_sip.conf,criteria=type=endpoint");
+
+	ast_sorcery_apply_default(sip_sorcery, "nat_hook", "memory", NULL);
+
+	if (ast_sorcery_object_register(sip_sorcery, "endpoint", ast_sip_endpoint_alloc, NULL, NULL)) {
+		ast_log(LOG_ERROR, "Failed to register SIP endpoint object with sorcery\n");
+		ast_sorcery_unref(sip_sorcery);
+		sip_sorcery = NULL;
+		return -1;
+	}
+
+	ast_sorcery_object_register(sip_sorcery, "nat_hook", sip_nat_hook_alloc, NULL, NULL);
+
+	ast_sorcery_object_field_register(sip_sorcery, "endpoint", "type", "", OPT_NOOP_T, 0, 0);
+	ast_sorcery_object_field_register(sip_sorcery, "endpoint", "context", "default", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_endpoint, context));
+	ast_sorcery_object_field_register(sip_sorcery, "endpoint", "disallow", "", OPT_CODEC_T, 0, FLDSET(struct ast_sip_endpoint, prefs, codecs));
+	ast_sorcery_object_field_register(sip_sorcery, "endpoint", "allow", "", OPT_CODEC_T, 1, FLDSET(struct ast_sip_endpoint, prefs, codecs));
+	ast_sorcery_object_field_register(sip_sorcery, "endpoint", "qualify_frequency", 0, OPT_UINT_T, PARSE_IN_RANGE, FLDSET(struct ast_sip_endpoint, qualify_frequency), 0, 86400);
+	ast_sorcery_object_field_register_custom(sip_sorcery, "endpoint", "dtmfmode", "rfc4733", dtmf_handler, NULL, 0, 0);
+	ast_sorcery_object_field_register(sip_sorcery, "endpoint", "rtp_ipv6", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, rtp_ipv6));
+	ast_sorcery_object_field_register(sip_sorcery, "endpoint", "rtp_symmetric", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, rtp_symmetric));
+	ast_sorcery_object_field_register(sip_sorcery, "endpoint", "ice_support", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, ice_support));
+	ast_sorcery_object_field_register(sip_sorcery, "endpoint", "use_ptime", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, use_ptime));
+	ast_sorcery_object_field_register(sip_sorcery, "endpoint", "force_rport", "yes", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, force_rport));
+	ast_sorcery_object_field_register(sip_sorcery, "endpoint", "rewrite_contact", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, rewrite_contact));
+	ast_sorcery_object_field_register(sip_sorcery, "endpoint", "transport", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_endpoint, transport));
+	ast_sorcery_object_field_register(sip_sorcery, "endpoint", "outbound_proxy", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_endpoint, outbound_proxy));
+	ast_sorcery_object_field_register(sip_sorcery, "endpoint", "mohsuggest", "default", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_endpoint, mohsuggest));
+	ast_sorcery_object_field_register_custom(sip_sorcery, "endpoint", "100rel", "yes", prack_handler, NULL, 0, 0);
+	ast_sorcery_object_field_register_custom(sip_sorcery, "endpoint", "timers", "yes", timers_handler, NULL, 0, 0);
+	ast_sorcery_object_field_register(sip_sorcery, "endpoint", "timers_min_se", "90", OPT_UINT_T, 0, FLDSET(struct ast_sip_endpoint, min_se));
+	ast_sorcery_object_field_register(sip_sorcery, "endpoint", "timers_sess_expires", "1800", OPT_UINT_T, 0, FLDSET(struct ast_sip_endpoint, sess_expires));
+	ast_sorcery_object_field_register_custom(sip_sorcery, "endpoint", "auth", "", inbound_auth_handler, NULL, 0, 0);
+	ast_sorcery_object_field_register_custom(sip_sorcery, "endpoint", "outbound_auth", "", outbound_auth_handler, NULL, 0, 0);
+	ast_sorcery_object_field_register(sip_sorcery, "endpoint", "aors", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_endpoint, aors));
+	ast_sorcery_object_field_register(sip_sorcery, "endpoint", "external_media_address", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_endpoint, external_media_address));
+	ast_sorcery_object_field_register_custom(sip_sorcery, "endpoint", "identify_by", "username,location", ident_handler, NULL, 0, 0);
+	ast_sorcery_object_field_register(sip_sorcery, "endpoint", "direct_media", "yes", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, direct_media));
+	ast_sorcery_object_field_register_custom(sip_sorcery, "endpoint", "direct_media_method", "invite", direct_media_method_handler, NULL, 0, 0);
+	ast_sorcery_object_field_register_custom(sip_sorcery, "endpoint", "direct_media_glare_mitigation", "none", direct_media_glare_mitigation_handler, NULL, 0, 0);
+	ast_sorcery_object_field_register(sip_sorcery, "endpoint", "disable_direct_media_on_nat", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, disable_direct_media_on_nat));
+	ast_sorcery_object_field_register_custom(sip_sorcery, "endpoint", "callerid", "", caller_id_handler, NULL, 0, 0);
+	ast_sorcery_object_field_register_custom(sip_sorcery, "endpoint", "callerid_privacy", "", caller_id_privacy_handler, NULL, 0, 0);
+	ast_sorcery_object_field_register_custom(sip_sorcery, "endpoint", "callerid_tag", "", caller_id_tag_handler, NULL, 0, 0);
+	ast_sorcery_object_field_register(sip_sorcery, "endpoint", "trust_id_inbound", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, trust_id_inbound));
+	ast_sorcery_object_field_register(sip_sorcery, "endpoint", "trust_id_outbound", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, trust_id_outbound));
+	ast_sorcery_object_field_register(sip_sorcery, "endpoint", "send_pai", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, send_pai));
+	ast_sorcery_object_field_register(sip_sorcery, "endpoint", "send_rpid", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, send_rpid));
+	ast_sorcery_object_field_register(sip_sorcery, "endpoint", "mailboxes", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_endpoint, mailboxes));
+	ast_sorcery_object_field_register(sip_sorcery, "endpoint", "aggregate_mwi", "yes", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, aggregate_mwi));
+
+	if (ast_sip_initialize_sorcery_transport(sip_sorcery)) {
+		ast_log(LOG_ERROR, "Failed to register SIP transport support with sorcery\n");
+		ast_sorcery_unref(sip_sorcery);
+		sip_sorcery = NULL;
+		return -1;
+	}
+
+	if (ast_sip_initialize_sorcery_location(sip_sorcery)) {
+		ast_log(LOG_ERROR, "Failed to register SIP location support with sorcery\n");
+		ast_sorcery_unref(sip_sorcery);
+		sip_sorcery = NULL;
+		return -1;
+	}
+
+	if (ast_sip_initialize_sorcery_domain_alias(sip_sorcery)) {
+		ast_log(LOG_ERROR, "Failed to register SIP domain aliases support with sorcery\n");
+		ast_sorcery_unref(sip_sorcery);
+		sip_sorcery = NULL;
+		return -1;
+	}
+
+	ast_sorcery_load(sip_sorcery);
+
+	return 0;
+}
+
+void ast_res_sip_destroy_configuration(void)
+{
+	ast_cli_unregister_multiple(cli_commands, ARRAY_LEN(cli_commands));
+	ast_sorcery_unref(sip_sorcery);
+}
+
+int ast_res_sip_reload_configuration(void)
+{
+	if (sip_sorcery) {
+		ast_sorcery_reload(sip_sorcery);
+	}
+	return 0;
+}
+
+static void endpoint_destructor(void* obj)
+{
+	struct ast_sip_endpoint *endpoint = obj;
+
+	ast_string_field_free_memory(endpoint);
+
+	if (endpoint->codecs) {
+		ast_format_cap_destroy(endpoint->codecs);
+	}
+	destroy_auths(endpoint->sip_inbound_auths, endpoint->num_inbound_auths);
+	destroy_auths(endpoint->sip_outbound_auths, endpoint->num_outbound_auths);
+	ast_party_id_free(&endpoint->id);
+}
+
+void *ast_sip_endpoint_alloc(const char *name)
+{
+	struct ast_sip_endpoint *endpoint = ao2_alloc(sizeof(*endpoint), endpoint_destructor);
+	if (!endpoint) {
+		return NULL;
+	}
+	if (ast_string_field_init(endpoint, 64)) {
+		ao2_cleanup(endpoint);
+		return NULL;
+	}
+	if (!(endpoint->codecs = ast_format_cap_alloc_nolock())) {
+		ao2_cleanup(endpoint);
+		return NULL;
+	}
+	ast_party_id_init(&endpoint->id);
+	return endpoint;
+}
+
+struct ao2_container *ast_res_sip_get_endpoints(void)
+{
+	struct ao2_container *endpoints;
+
+	endpoints = ast_sorcery_retrieve_by_fields(sip_sorcery, "endpoint", AST_RETRIEVE_FLAG_MULTIPLE | AST_RETRIEVE_FLAG_ALL, NULL);
+
+	return endpoints;
+}
+
+int ast_sip_retrieve_auths(const char *auth_names[], size_t num_auths, struct ast_sip_auth **out)
+{
+	int i;
+
+	for (i = 0; i < num_auths; ++i) {
+		out[i] = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), SIP_SORCERY_AUTH_TYPE, auth_names[i]);
+		if (!out[i]) {
+			ast_log(LOG_NOTICE, "Couldn't find auth '%s'. Cannot authenticate\n", auth_names[i]);
+			return -1;
+		}
+	}
+
+	return 0;
+}
+
+void ast_sip_cleanup_auths(struct ast_sip_auth *auths[], size_t num_auths)
+{
+	int i;
+	for (i = 0; i < num_auths; ++i) {
+		ao2_cleanup(auths[i]);
+	}
+}
+
+struct ast_sorcery *ast_sip_get_sorcery(void)
+{
+	return sip_sorcery;
+}
+
diff --git a/res/res_sip/sip_distributor.c b/res/res_sip/sip_distributor.c
new file mode 100644
index 0000000000000000000000000000000000000000..7662610897755217f83f0b34681558ea44481e2a
--- /dev/null
+++ b/res/res_sip/sip_distributor.c
@@ -0,0 +1,239 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2013, Digium, Inc.
+ *
+ * Mark Michelson <mmichelson@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+#include "asterisk.h"
+
+#include <pjsip.h>
+
+#include "asterisk/res_sip.h"
+
+static int distribute(void *data);
+static pj_bool_t distributor(pjsip_rx_data *rdata);
+
+static pjsip_module distributor_mod = {
+	.name = {"Request Distributor", 19},
+	.priority = PJSIP_MOD_PRIORITY_TSX_LAYER - 6,
+	.on_rx_request = distributor,
+	.on_rx_response = distributor,
+};
+
+/*! Dialog-specific information the distributor uses */
+struct distributor_dialog_data {
+	/* Serializer to distribute tasks to for this dialog */
+	struct ast_taskprocessor *serializer;
+	/* Endpoint associated with this dialog */
+	struct ast_sip_endpoint *endpoint;
+};
+
+/*!
+ * \internal
+ *
+ * \note Call this with the dialog locked
+ */
+static struct distributor_dialog_data *distributor_dialog_data_alloc(pjsip_dialog *dlg)
+{
+	struct distributor_dialog_data *dist;
+
+	dist = PJ_POOL_ZALLOC_T(dlg->pool, struct distributor_dialog_data);
+	pjsip_dlg_set_mod_data(dlg, distributor_mod.id, dist);
+
+	return dist;
+}
+
+void ast_sip_dialog_set_serializer(pjsip_dialog *dlg, struct ast_taskprocessor *serializer)
+{
+	struct distributor_dialog_data *dist;
+	SCOPED_LOCK(lock, dlg, pjsip_dlg_inc_lock, pjsip_dlg_dec_lock);
+	
+	dist = pjsip_dlg_get_mod_data(dlg, distributor_mod.id);
+	if (!dist) {
+		dist = distributor_dialog_data_alloc(dlg);
+	}
+	dist->serializer = serializer;
+}
+
+void ast_sip_dialog_set_endpoint(pjsip_dialog *dlg, struct ast_sip_endpoint *endpoint)
+{
+	struct distributor_dialog_data *dist;
+	SCOPED_LOCK(lock, dlg, pjsip_dlg_inc_lock, pjsip_dlg_dec_lock);
+	
+	dist = pjsip_dlg_get_mod_data(dlg, distributor_mod.id);
+	if (!dist) {
+		dist = distributor_dialog_data_alloc(dlg);
+	}
+	dist->endpoint = endpoint;
+}
+
+struct ast_sip_endpoint *ast_sip_dialog_get_endpoint(pjsip_dialog *dlg)
+{
+	struct distributor_dialog_data *dist;
+	SCOPED_LOCK(lock, dlg, pjsip_dlg_inc_lock, pjsip_dlg_dec_lock);
+
+	dist = pjsip_dlg_get_mod_data(dlg, distributor_mod.id);
+	if (!dist || !dist->endpoint) {
+		return NULL;
+	}
+	ao2_ref(dist->endpoint, +1);
+	return dist->endpoint;
+}
+
+static pj_bool_t distributor(pjsip_rx_data *rdata)
+{
+	pjsip_dialog *dlg = pjsip_ua_find_dialog(&rdata->msg_info.cid->id, &rdata->msg_info.to->tag, &rdata->msg_info.from->tag, PJ_TRUE);
+	struct distributor_dialog_data *dist = NULL;
+	struct ast_taskprocessor *serializer = NULL;
+	pjsip_rx_data *clone;
+
+	pjsip_rx_data_clone(rdata, 0, &clone);
+	if (dlg) {
+		dist = pjsip_dlg_get_mod_data(dlg, distributor_mod.id);
+		if (dist) {
+			serializer = dist->serializer;
+			clone->endpt_info.mod_data[distributor_mod.id] = dist->endpoint;
+		}
+	}
+
+	ast_sip_push_task(serializer, distribute, clone);
+
+	if (dlg) {
+		pjsip_dlg_dec_lock(dlg);
+	}
+
+	return PJ_TRUE;
+}
+
+static pj_bool_t endpoint_lookup(pjsip_rx_data *rdata);
+
+static pjsip_module endpoint_mod = {
+	.name = {"Endpoint Identifier", 19},
+	.priority = PJSIP_MOD_PRIORITY_TSX_LAYER - 3,
+	.on_rx_request = endpoint_lookup,
+};
+
+static pj_bool_t endpoint_lookup(pjsip_rx_data *rdata)
+{
+	struct ast_sip_endpoint *endpoint;
+	int is_ack = rdata->msg_info.msg->line.req.method.id == PJSIP_ACK_METHOD;
+
+	endpoint = rdata->endpt_info.mod_data[distributor_mod.id];
+	if (endpoint) {
+		/* Bumping the refcount makes refcounting consistent whether an endpoint
+		 * is looked up or not */
+		ao2_ref(endpoint, +1);
+	} else {
+		endpoint = ast_sip_identify_endpoint(rdata);
+	}
+
+	if (!endpoint && !is_ack) {
+		/* XXX When we do an alwaysauthreject-like option, we'll need to take that into account
+		 * for this response. Either that, or have a pseudo-endpoint to pass along so that authentication
+		 * will fail
+		 */
+		pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 403, NULL, NULL, NULL);
+		return PJ_TRUE;
+	}
+	rdata->endpt_info.mod_data[endpoint_mod.id] = endpoint;
+	return PJ_FALSE;
+}
+
+static pj_bool_t authenticate(pjsip_rx_data *rdata)
+{
+	RAII_VAR(struct ast_sip_endpoint *, endpoint, ast_pjsip_rdata_get_endpoint(rdata), ao2_cleanup);
+	int is_ack = rdata->msg_info.msg->line.req.method.id == PJSIP_ACK_METHOD;
+
+	ast_assert(endpoint != NULL);
+
+	if (!is_ack && ast_sip_requires_authentication(endpoint, rdata)) {
+		pjsip_tx_data *tdata;
+		pjsip_endpt_create_response(ast_sip_get_pjsip_endpoint(), rdata, 401, NULL, &tdata);
+		switch (ast_sip_check_authentication(endpoint, rdata, tdata)) {
+		case AST_SIP_AUTHENTICATION_CHALLENGE:
+			/* Send the 401 we created for them */
+			pjsip_endpt_send_response2(ast_sip_get_pjsip_endpoint(), rdata, tdata, NULL, NULL);
+			return PJ_TRUE;
+		case AST_SIP_AUTHENTICATION_SUCCESS:
+			pjsip_tx_data_dec_ref(tdata);
+			return PJ_FALSE;
+		case AST_SIP_AUTHENTICATION_FAILED:
+			pjsip_tx_data_dec_ref(tdata);
+			pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 403, NULL, NULL, NULL);
+			return PJ_TRUE;
+		case AST_SIP_AUTHENTICATION_ERROR:
+			pjsip_tx_data_dec_ref(tdata);
+			pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 500, NULL, NULL, NULL);
+			return PJ_TRUE;
+		}
+	}
+
+	return PJ_FALSE;
+}
+
+static pjsip_module auth_mod = {
+	.name = {"Request Authenticator", 21},
+	.priority = PJSIP_MOD_PRIORITY_APPLICATION - 1,
+	.on_rx_request = authenticate,
+};
+
+static int distribute(void *data)
+{
+	static pjsip_process_rdata_param param = {
+		.start_mod = &distributor_mod,
+		.idx_after_start = 1,
+	};
+	pj_bool_t handled;
+	pjsip_rx_data *rdata = data;
+	int is_request = rdata->msg_info.msg->type == PJSIP_REQUEST_MSG;
+	int is_ack = is_request ? rdata->msg_info.msg->line.req.method.id == PJSIP_ACK_METHOD : 0;
+	struct ast_sip_endpoint *endpoint;
+
+	pjsip_endpt_process_rx_data(ast_sip_get_pjsip_endpoint(), rdata, &param, &handled);
+	if (!handled && is_request && !is_ack) {
+		pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 501, NULL, NULL, NULL);
+	}
+
+	/* The endpoint_mod stores an endpoint reference in the mod_data of rdata. This
+	 * is the only appropriate spot to actually decrement the reference.
+	 */
+	endpoint = rdata->endpt_info.mod_data[endpoint_mod.id];
+	ao2_cleanup(endpoint);
+	pjsip_rx_data_free_cloned(rdata);
+	return 0;
+}
+
+struct ast_sip_endpoint *ast_pjsip_rdata_get_endpoint(pjsip_rx_data *rdata)
+{
+	struct ast_sip_endpoint *endpoint = rdata->endpt_info.mod_data[endpoint_mod.id];
+	if (endpoint) {
+		ao2_ref(endpoint, +1);
+	}
+	return endpoint;
+}
+
+int ast_sip_initialize_distributor(void)
+{
+	if (ast_sip_register_service(&distributor_mod)) {
+		return -1;
+	}
+	if (ast_sip_register_service(&endpoint_mod)) {
+		return -1;
+	}
+	if (ast_sip_register_service(&auth_mod)) {
+		return -1;
+	}
+	return 0;
+}
diff --git a/res/res_sip/sip_options.c b/res/res_sip/sip_options.c
new file mode 100644
index 0000000000000000000000000000000000000000..5e3f8edcacf584e69b42ec476fa0dda21c52bedb
--- /dev/null
+++ b/res/res_sip/sip_options.c
@@ -0,0 +1,378 @@
+/*
+ * sip_options.c
+ *
+ *  Created on: Jan 25, 2013
+ *      Author: mjordan
+ */
+
+#include "asterisk.h"
+
+#include <pjsip.h>
+#include <pjsip_ua.h>
+#include <pjlib.h>
+
+#include "asterisk/res_sip.h"
+#include "asterisk/channel.h"
+#include "asterisk/pbx.h"
+#include "asterisk/astobj2.h"
+#include "asterisk/cli.h"
+#include "include/res_sip_private.h"
+
+#define DEFAULT_LANGUAGE "en"
+#define DEFAULT_ENCODING "text/plain"
+#define QUALIFIED_BUCKETS 211
+
+/*! \brief Scheduling context for qualifies */
+static struct ast_sched_context *sched; /* XXX move this to registrar */
+
+struct ao2_container *scheduled_qualifies;
+
+struct qualify_info {
+	AST_DECLARE_STRING_FIELDS(
+		AST_STRING_FIELD(endpoint_id);
+	);
+	char *scheduler_data;
+	int scheduler_id;
+};
+
+static pj_bool_t options_module_start(void);
+static pj_bool_t options_module_stop(void);
+static pj_bool_t options_module_on_rx_request(pjsip_rx_data *rdata);
+static pj_bool_t options_module_on_rx_response(pjsip_rx_data *rdata);
+
+static pjsip_module options_module = {
+	.name = {"Options Module", 14},
+	.id = -1,
+	.priority = PJSIP_MOD_PRIORITY_APPLICATION,
+	.start = options_module_start,
+	.stop = options_module_stop,
+	.on_rx_request = options_module_on_rx_request,
+	.on_rx_response = options_module_on_rx_response,
+};
+
+static pj_bool_t options_module_start(void)
+{
+	if (!(sched = ast_sched_context_create()) ||
+	    ast_sched_start_thread(sched)) {
+		return -1;
+	}
+
+	return PJ_SUCCESS;
+}
+
+static pj_bool_t options_module_stop(void)
+{
+	ao2_t_ref(scheduled_qualifies, -1, "Remove scheduled qualifies on module stop");
+
+	if (sched) {
+		ast_sched_context_destroy(sched);
+	}
+
+	return PJ_SUCCESS;
+}
+
+static pj_status_t send_options_response(pjsip_rx_data *rdata, pjsip_dialog *pj_dlg, int code)
+{
+	pjsip_endpoint *endpt = ast_sip_get_pjsip_endpoint();
+	pjsip_transaction *pj_trans = pjsip_rdata_get_tsx(rdata);
+	pjsip_tx_data *tdata;
+	const pjsip_hdr *hdr;
+	pjsip_response_addr res_addr;
+	pj_status_t status;
+
+	/* Make the response object */
+	status = pjsip_endpt_create_response(endpt, rdata, code, NULL, &tdata);
+	if (status != PJ_SUCCESS) {
+		return status;
+	}
+
+	/* Add appropriate headers */
+	if ((hdr = pjsip_endpt_get_capability(endpt, PJSIP_H_ACCEPT, NULL))) {
+		pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)pjsip_hdr_clone(tdata->pool, hdr));
+	}
+	if ((hdr = pjsip_endpt_get_capability(endpt, PJSIP_H_ALLOW, NULL))) {
+		pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)pjsip_hdr_clone(tdata->pool, hdr));
+	}
+	if ((hdr = pjsip_endpt_get_capability(endpt, PJSIP_H_SUPPORTED, NULL))) {
+		pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)pjsip_hdr_clone(tdata->pool, hdr));
+	}
+
+	/*
+	 * XXX TODO: pjsip doesn't care a lot about either of these headers -
+	 * while it provides specific methods to create them, they are defined
+	 * to be the standard string header creation. We never did add them
+	 * in chan_sip, although RFC 3261 says they SHOULD. Hard coded here.
+	 */
+	ast_sip_add_header(tdata, "Accept-Encoding", DEFAULT_ENCODING);
+	ast_sip_add_header(tdata, "Accept-Language", DEFAULT_LANGUAGE);
+
+	if (pj_dlg && pj_trans) {
+		status = pjsip_dlg_send_response(pj_dlg, pj_trans, tdata);
+	} else {
+		/* Get where to send request. */
+		status = pjsip_get_response_addr(tdata->pool, rdata, &res_addr);
+		if (status != PJ_SUCCESS) {
+			pjsip_tx_data_dec_ref(tdata);
+			return status;
+		}
+		status = pjsip_endpt_send_response(endpt, &res_addr, tdata, NULL, NULL);
+	}
+
+	return status;
+}
+
+static pj_bool_t options_module_on_rx_request(pjsip_rx_data *rdata)
+{
+	RAII_VAR(struct ast_sip_endpoint *, endpoint, NULL, ao2_cleanup);
+	pjsip_dialog *dlg = pjsip_rdata_get_dlg(rdata);
+	pjsip_uri *ruri;
+	pjsip_sip_uri *sip_ruri;
+	char exten[AST_MAX_EXTENSION];
+
+	if (pjsip_method_cmp(&rdata->msg_info.msg->line.req.method, &pjsip_options_method)) {
+		return PJ_FALSE;
+	}
+	endpoint = ast_pjsip_rdata_get_endpoint(rdata);
+	ast_assert(endpoint != NULL);
+
+	ruri = rdata->msg_info.msg->line.req.uri;
+	if (!PJSIP_URI_SCHEME_IS_SIP(ruri) && !PJSIP_URI_SCHEME_IS_SIPS(ruri)) {
+		send_options_response(rdata, dlg, 416);
+		return -1;
+	}
+	
+	sip_ruri = pjsip_uri_get_uri(ruri);
+	ast_copy_pj_str(exten, &sip_ruri->user, sizeof(exten));
+
+	if (ast_shutting_down()) {
+		send_options_response(rdata, dlg, 503);
+	} else if (!ast_exists_extension(NULL, endpoint->context, exten, 1, NULL)) {
+		send_options_response(rdata, dlg, 404);
+	} else {
+		send_options_response(rdata, dlg, 200);
+	}
+	return PJ_TRUE;
+}
+
+static pj_bool_t options_module_on_rx_response(pjsip_rx_data *rdata)
+{
+
+	return PJ_SUCCESS;
+}
+
+static int qualify_info_hash_fn(const void *obj, int flags)
+{
+	const struct qualify_info *info = obj;
+	const char *endpoint_id = flags & OBJ_KEY ? obj : info->endpoint_id;
+
+	return ast_str_hash(endpoint_id);
+}
+
+static int qualify_info_cmp_fn(void *obj, void *arg, int flags)
+{
+	struct qualify_info *left = obj;
+	struct qualify_info *right = arg;
+	const char *right_endpoint_id = flags & OBJ_KEY ? arg : right->endpoint_id;
+
+	return strcmp(left->endpoint_id, right_endpoint_id) ? 0 : CMP_MATCH | CMP_STOP;
+}
+
+
+static void qualify_info_destructor(void *obj)
+{
+	struct qualify_info *info = obj;
+	if (!info) {
+		return;
+	}
+	ast_string_field_free_memory(info);
+	/* Cancel the qualify */
+	if (!AST_SCHED_DEL(sched, info->scheduler_id)) {
+		/* If we successfully deleted the qualify, we got it before it
+		 * fired. We can safely delete the data that was passed to it.
+		 * Otherwise, we're getting deleted while this is firing - don't
+		 * touch that memory!
+		 */
+		ast_free(info->scheduler_data);
+	}
+}
+
+static struct qualify_info *create_qualify_info(struct ast_sip_endpoint *endpoint)
+{
+	struct qualify_info *info;
+
+	info = ao2_alloc(sizeof(*info), qualify_info_destructor);
+	if (!info) {
+		return NULL;
+	}
+
+	if (ast_string_field_init(info, 64)) {
+		ao2_ref(info, -1);
+		return NULL;
+	}
+	ast_string_field_set(info, endpoint_id, ast_sorcery_object_get_id(endpoint));
+
+	return info;
+}
+
+static int send_qualify_request(void *data)
+{
+	struct ast_sip_endpoint *endpoint = data;
+	pjsip_tx_data *tdata;
+	/* YAY! Send an OPTIONS request. */
+
+	ast_sip_create_request("OPTIONS", NULL, endpoint, NULL, &tdata);
+	ast_sip_send_request(tdata, NULL, endpoint);
+
+	ao2_cleanup(endpoint);
+	return 0;
+}
+
+static int qualify_endpoint_scheduler_cb(const void *data)
+{
+	RAII_VAR(struct ast_sip_endpoint *, endpoint, NULL, ao2_cleanup);
+	struct ast_sorcery *sorcery;
+	char *endpoint_id = (char *)data;
+
+	sorcery = ast_sip_get_sorcery();
+	if (!sorcery) {
+		ast_free(endpoint_id);
+		return 0;
+	}
+
+	endpoint = ast_sorcery_retrieve_by_id(sorcery, "endpoint", endpoint_id);
+	if (!endpoint) {
+		/* Whoops, endpoint went away */
+		ast_free(endpoint_id);
+		return 0;
+	}
+
+	ast_sip_push_task(NULL, send_qualify_request, endpoint);
+
+	return 1;
+}
+
+static void schedule_qualifies(void)
+{
+	RAII_VAR(struct ao2_container *, endpoints, NULL, ao2_cleanup);
+	struct ao2_iterator it_endpoints;
+	struct ast_sip_endpoint *endpoint;
+	struct qualify_info *info;
+	char *endpoint_id;
+
+	endpoints = ast_res_sip_get_endpoints();
+	if (!endpoints) {
+		return;
+	}
+
+	it_endpoints = ao2_iterator_init(endpoints, 0);
+	while ((endpoint = ao2_iterator_next(&it_endpoints))) {
+		if (endpoint->qualify_frequency) {
+			/* XXX TODO: This really should only qualify registered peers,
+			 * which means we need a registrar. We should check the
+			 * registrar to see if this endpoint has registered and, if
+			 * not, pass on it.
+			 *
+			 * Actually, all of this should just get moved into the registrar.
+			 * Otherwise, the registar will have to kick this off when a
+			 * new endpoint registers, so it just makes sense to have it
+			 * all live there.
+			 */
+			info = create_qualify_info(endpoint);
+			if (!info) {
+				ao2_ref(endpoint, -1);
+				break;
+			}
+			endpoint_id = ast_strdup(info->endpoint_id);
+			if (!endpoint_id) {
+				ao2_t_ref(info, -1, "Dispose of info on off nominal");
+				ao2_ref(endpoint, -1);
+				break;
+			}
+			info->scheduler_data = endpoint_id;
+			info->scheduler_id = ast_sched_add_variable(sched, endpoint->qualify_frequency * 1000, qualify_endpoint_scheduler_cb, endpoint_id, 1);
+			ao2_t_link(scheduled_qualifies, info, "Link scheduled qualify information into container");
+			ao2_t_ref(info, -1, "Dispose of creation ref");
+		}
+		ao2_t_ref(endpoint, -1, "Dispose of iterator ref");
+	}
+	ao2_iterator_destroy(&it_endpoints);
+}
+
+static char *send_options(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
+{
+	RAII_VAR(struct ast_sip_endpoint *, endpoint, NULL, ao2_cleanup);
+	const char *endpoint_name;
+	pjsip_tx_data *tdata;
+
+	switch (cmd) {
+	case CLI_INIT:
+		e->command = "sip send options";
+		e->usage =
+			"Usage: sip send options <endpoint>\n"
+			"       Send a SIP OPTIONS request to the specified endpoint.\n";
+		return NULL;
+	case CLI_GENERATE:
+		return NULL;
+	}
+
+	if (a->argc != 4) {
+		return CLI_SHOWUSAGE;
+	}
+
+	endpoint_name = a->argv[3];
+
+	endpoint = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "endpoint", endpoint_name);
+	if (!endpoint) {
+		ast_log(LOG_ERROR, "Unable to retrieve endpoint %s\n", endpoint_name);
+		return CLI_FAILURE;
+	}
+
+	if (ast_sip_create_request("OPTIONS", NULL, endpoint, NULL, &tdata)) {
+		ast_log(LOG_ERROR, "Unable to create OPTIONS request to endpoint %s\n", endpoint_name);
+		return CLI_FAILURE;
+	}
+
+	if (ast_sip_send_request(tdata, NULL, endpoint)) {
+		ast_log(LOG_ERROR, "Unable to send OPTIONS request to endpoint %s\n", endpoint_name);
+		return CLI_FAILURE;
+	}
+
+	return CLI_SUCCESS;
+}
+
+static struct ast_cli_entry cli_options[] = {
+	AST_CLI_DEFINE(send_options, "Send an OPTIONS requst to an arbitrary SIP URI"),
+};
+
+int ast_res_sip_init_options_handling(int reload)
+{
+	const pj_str_t STR_OPTIONS = { "OPTIONS", 7 };
+
+	if (scheduled_qualifies) {
+		ao2_t_ref(scheduled_qualifies, -1, "Remove old scheduled qualifies");
+	}
+	scheduled_qualifies = ao2_t_container_alloc(QUALIFIED_BUCKETS, qualify_info_hash_fn, qualify_info_cmp_fn, "Create container for scheduled qualifies");
+	if (!scheduled_qualifies) {
+		return -1;
+	}
+
+	if (reload) {
+		return 0;
+	}
+
+	if (pjsip_endpt_register_module(ast_sip_get_pjsip_endpoint(), &options_module) != PJ_SUCCESS) {
+		options_module_stop();
+		return -1;
+	}
+
+	if (pjsip_endpt_add_capability(ast_sip_get_pjsip_endpoint(), NULL, PJSIP_H_ALLOW, NULL, 1, &STR_OPTIONS) != PJ_SUCCESS) {
+		pjsip_endpt_unregister_module(ast_sip_get_pjsip_endpoint(), &options_module);
+		return -1;
+	}
+
+	ast_cli_register_multiple(cli_options, ARRAY_LEN(cli_options));
+
+	schedule_qualifies();
+
+	return 0;
+}
diff --git a/res/res_sip/sip_outbound_auth.c b/res/res_sip/sip_outbound_auth.c
new file mode 100644
index 0000000000000000000000000000000000000000..94352a52144914ad5ad65fdf61cbb777713059df
--- /dev/null
+++ b/res/res_sip/sip_outbound_auth.c
@@ -0,0 +1,94 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2013, Digium, Inc.
+ *
+ * Mark Michelson <mmichelson@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+#include "asterisk.h"
+#undef bzero
+#define bzero bzero
+#include "pjsip.h"
+
+#include "asterisk/res_sip.h"
+#include "asterisk/module.h"
+#include "include/res_sip_private.h"
+
+static pj_bool_t outbound_auth(pjsip_rx_data *rdata);
+
+static pjsip_module outbound_auth_mod = {
+	.name = {"Outbound Authentication", 19},
+	.priority = PJSIP_MOD_PRIORITY_DIALOG_USAGE,
+	.on_rx_response = outbound_auth,
+};
+
+struct outbound_auth_cb_data {
+	ast_sip_dialog_outbound_auth_cb cb;
+	void *user_data;
+};
+
+static pj_bool_t outbound_auth(pjsip_rx_data *rdata)
+{
+	RAII_VAR(struct ast_sip_endpoint *, endpoint, NULL, ao2_cleanup);
+	pjsip_transaction *tsx;
+	pjsip_dialog *dlg;
+	struct outbound_auth_cb_data *cb_data;
+	pjsip_tx_data *tdata;
+
+	if (rdata->msg_info.msg->line.status.code != 401 &&
+			rdata->msg_info.msg->line.status.code != 407) {
+		/* Doesn't pertain to us. Move on */
+		return PJ_FALSE;
+	}
+
+	tsx = pjsip_rdata_get_tsx(rdata);
+	dlg = pjsip_rdata_get_dlg(rdata);
+	ast_assert(dlg != NULL && tsx != NULL);
+	endpoint = ast_sip_dialog_get_endpoint(dlg);
+
+	if (!endpoint) {
+		return PJ_FALSE;
+	}
+
+	if (ast_sip_create_request_with_auth(endpoint->sip_outbound_auths, endpoint->num_outbound_auths, rdata, tsx, &tdata)) {
+		return PJ_FALSE;
+	}
+
+	cb_data = dlg->mod_data[outbound_auth_mod.id];
+	if (cb_data) {
+		cb_data->cb(dlg, tdata, cb_data->user_data);
+		return PJ_TRUE;
+	}
+
+	pjsip_dlg_send_request(dlg, tdata, -1, NULL);
+	return PJ_TRUE;
+}
+
+int ast_sip_dialog_setup_outbound_authentication(pjsip_dialog *dlg, const struct ast_sip_endpoint *endpoint,
+		ast_sip_dialog_outbound_auth_cb cb, void *user_data)
+{
+	struct outbound_auth_cb_data *cb_data = PJ_POOL_ZALLOC_T(dlg->pool, struct outbound_auth_cb_data);
+	cb_data->cb = cb;
+	cb_data->user_data = user_data;
+
+	dlg->sess_count++;
+	pjsip_dlg_add_usage(dlg, &outbound_auth_mod, cb_data);
+	dlg->sess_count--;
+
+	return 0;
+}
+
+int ast_sip_initialize_outbound_authentication(void) {
+	return ast_sip_register_service(&outbound_auth_mod);
+}
diff --git a/res/res_sip_acl.c b/res/res_sip_acl.c
new file mode 100644
index 0000000000000000000000000000000000000000..405c3c1bc021beb41dc191ad1ed81cd132256c73
--- /dev/null
+++ b/res/res_sip_acl.c
@@ -0,0 +1,222 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2013, Digium, Inc.
+ *
+ * Mark Michelson <mmichelson@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*** MODULEINFO
+	<depend>pjproject</depend>
+	<support_level>core</support_level>
+ ***/
+
+#include "asterisk.h"
+
+#include <pjsip.h>
+
+#include "asterisk/res_sip.h"
+#include "asterisk/module.h"
+#include "asterisk/logger.h"
+#include "asterisk/sorcery.h"
+#include "asterisk/acl.h"
+
+struct sip_acl {
+	SORCERY_OBJECT(details);
+	struct ast_acl_list *acl;
+	struct ast_acl_list *contact_acl;
+};
+
+static int apply_acl(pjsip_rx_data *rdata, struct ast_acl_list *acl)
+{
+	struct ast_sockaddr addr;
+
+	if (ast_acl_list_is_empty(acl)) {
+		return 0;
+	}
+
+	memset(&addr, 0, sizeof(addr));
+	ast_sockaddr_parse(&addr, rdata->pkt_info.src_name, PARSE_PORT_FORBID);
+	ast_sockaddr_set_port(&addr, rdata->pkt_info.src_port);
+
+	if (ast_apply_acl(acl, &addr, "SIP ACL: ") != AST_SENSE_ALLOW) {
+		ast_log(LOG_WARNING, "Incoming SIP message from %s did not pass ACL test\n", ast_sockaddr_stringify(&addr));
+		return 1;
+	}
+	return 0;
+}
+
+static int extract_contact_addr(pjsip_contact_hdr *contact, struct ast_sockaddr **addrs)
+{
+	pjsip_sip_uri *sip_uri;
+	char host[256];
+
+	if (!contact) {
+		return 0;
+	}
+	if (!PJSIP_URI_SCHEME_IS_SIP(contact->uri) && !PJSIP_URI_SCHEME_IS_SIPS(contact->uri)) {
+		return 0;
+	}
+	sip_uri = pjsip_uri_get_uri(contact->uri);
+	ast_copy_pj_str(host, &sip_uri->host, sizeof(host));
+	return ast_sockaddr_resolve(addrs, host, PARSE_PORT_FORBID, AST_AF_UNSPEC);
+}
+
+static int apply_contact_acl(pjsip_rx_data *rdata, struct ast_acl_list *contact_acl)
+{
+	int num_contact_addrs;
+	int forbidden = 0;
+	struct ast_sockaddr *contact_addrs;
+	int i;
+	pjsip_contact_hdr *contact = (pjsip_contact_hdr *)&rdata->msg_info.msg->hdr;
+
+	if (ast_acl_list_is_empty(contact_acl)) {
+		return 0;
+	}
+
+	while ((contact = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_CONTACT, contact->next))) {
+		num_contact_addrs = extract_contact_addr(contact, &contact_addrs);
+		if (num_contact_addrs <= 0) {
+			continue;
+		}
+		for (i = 0; i < num_contact_addrs; ++i) {
+			if (ast_apply_acl(contact_acl, &contact_addrs[i], "SIP Contact ACL: ") != AST_SENSE_ALLOW) {
+				ast_log(LOG_WARNING, "Incoming SIP message from %s did not pass ACL test\n", ast_sockaddr_stringify(&contact_addrs[i]));
+				forbidden = 1;
+				break;
+			}
+		}
+		ast_free(contact_addrs);
+		if (forbidden) {
+			/* No use checking other contacts if we already have failed ACL check */
+			break;
+		}
+	}
+
+	return forbidden;
+}
+
+static int check_acls(void *obj, void *arg, int flags)
+{
+	struct sip_acl *acl = obj;
+	pjsip_rx_data *rdata = arg;
+
+	if (apply_acl(rdata, acl->acl) || apply_contact_acl(rdata, acl->contact_acl)) {
+		return CMP_MATCH | CMP_STOP;
+	}
+	return 0;
+}
+
+static pj_bool_t acl_on_rx_msg(pjsip_rx_data *rdata)
+{
+	int forbidden = 0;
+	struct ao2_container *acls = ast_sorcery_retrieve_by_fields(ast_sip_get_sorcery(), "acl", AST_RETRIEVE_FLAG_MULTIPLE | AST_RETRIEVE_FLAG_ALL, NULL);
+	struct sip_acl *matched_acl;
+	if (!acls) {
+		ast_log(LOG_ERROR, "Unable to retrieve ACL sorcery data\n");
+		return PJ_FALSE;
+	}
+
+	matched_acl = ao2_callback(acls, 0, check_acls, rdata);
+	if (matched_acl) {
+		forbidden = 1;
+		ao2_ref(matched_acl, -1);
+	}
+	ao2_ref(acls, -1);
+
+	if (forbidden) {
+		if (rdata->msg_info.msg->line.req.method.id != PJSIP_ACK_METHOD) {
+			pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 403, NULL, NULL, NULL);
+		}
+		return PJ_TRUE;
+	}
+
+	return PJ_FALSE;
+}
+
+static pjsip_module acl_module = {
+	.name = { "ACL Module", 14 },
+	/* This should run after a logger but before anything else */
+	.priority = 1,
+	.on_rx_request = acl_on_rx_msg,
+};
+
+static int acl_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
+{
+	struct sip_acl *acl = obj;
+	int error;
+	int ignore;
+	if (!strncmp(var->name, "contact", 7)) {
+		ast_append_acl(var->name + 7, var->value, &acl->contact_acl, &error, &ignore);
+	} else {
+		ast_append_acl(var->name, var->value, &acl->acl, &error, &ignore);
+	}
+	return error;
+}
+
+static void sip_acl_destructor(void *obj)
+{
+	struct sip_acl *acl = obj;
+	acl->acl = ast_free_acl_list(acl->acl);
+	acl->contact_acl = ast_free_acl_list(acl->contact_acl);
+}
+
+static void *sip_acl_alloc(const char *name)
+{
+	struct sip_acl *acl = ao2_alloc(sizeof(*acl), sip_acl_destructor);
+	if (!acl) {
+		return NULL;
+	}
+	return acl;
+}
+
+static int load_acls(void)
+{
+	ast_sorcery_apply_default(ast_sip_get_sorcery(), "acl", "config", "res_sip.conf,criteria=type=acl");
+	if (ast_sorcery_object_register(ast_sip_get_sorcery(), "acl", sip_acl_alloc, NULL, NULL)) {
+		ast_log(LOG_ERROR, "Failed to register SIP ACL object with sorcery\n");
+		return -1;
+	}
+	ast_sorcery_object_field_register(ast_sip_get_sorcery(), "acl", "type", "", OPT_NOOP_T, 0, 0);
+	ast_sorcery_object_field_register_custom(ast_sip_get_sorcery(), "acl", "permit", "", acl_handler, NULL, 0, 0);
+	ast_sorcery_object_field_register_custom(ast_sip_get_sorcery(), "acl", "deny", "", acl_handler, NULL, 0, 0);
+	ast_sorcery_object_field_register_custom(ast_sip_get_sorcery(), "acl", "acl", "", acl_handler, NULL, 0, 0);
+	ast_sorcery_object_field_register_custom(ast_sip_get_sorcery(), "acl", "contactpermit", "", acl_handler, NULL, 0, 0);
+	ast_sorcery_object_field_register_custom(ast_sip_get_sorcery(), "acl", "contactdeny", "", acl_handler, NULL, 0, 0);
+	ast_sorcery_object_field_register_custom(ast_sip_get_sorcery(), "acl", "contactacl", "", acl_handler, NULL, 0, 0);
+
+	/* XXX Is there a more selective way to do this? (i.e. Just reload a specific object type?) */
+	ast_sorcery_reload(ast_sip_get_sorcery());
+	return 0;
+}
+
+static int load_module(void)
+{
+	if (load_acls()) {
+		return AST_MODULE_LOAD_DECLINE;
+	}
+	ast_sip_register_service(&acl_module);
+	return AST_MODULE_LOAD_SUCCESS;
+}
+
+static int unload_module(void)
+{
+	ast_sip_unregister_service(&acl_module);
+	return 0;
+}
+
+AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "SIP ACL Resource",
+		.load = load_module,
+		.unload = unload_module,
+		.load_pri = AST_MODPRI_APP_DEPEND,
+	       );
diff --git a/res/res_sip_authenticator_digest.c b/res/res_sip_authenticator_digest.c
new file mode 100644
index 0000000000000000000000000000000000000000..499342309f288c049d6dfaea50ae9289e6dd4dd1
--- /dev/null
+++ b/res/res_sip_authenticator_digest.c
@@ -0,0 +1,455 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2013, Digium, Inc.
+ *
+ * Mark Michelson <mmichelson@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+#include "asterisk.h"
+
+#include <pjsip.h>
+
+#include "asterisk/res_sip.h"
+#include "asterisk/logger.h"
+#include "asterisk/module.h"
+#include "asterisk/strings.h"
+
+/*** MODULEINFO
+	<depend>pjproject</depend>
+	<depend>res_sip</depend>
+	<support_level>core</support_level>
+ ***/
+
+AO2_GLOBAL_OBJ_STATIC(entity_id);
+
+/*!
+ * \brief Determine if authentication is required
+ *
+ * Authentication is required if the endpoint has at least one auth
+ * section specified
+ */
+static int digest_requires_authentication(struct ast_sip_endpoint *endpoint, pjsip_rx_data *rdata)
+{
+	return endpoint->num_inbound_auths > 0;
+}
+
+static void auth_store_cleanup(void *data)
+{
+	struct ast_sip_auth **auth = data;
+
+	ao2_cleanup(*auth);
+	ast_free(data);
+}
+
+/*!
+ * \brief Thread-local storage for \ref ast_sip_auth
+ *
+ * The PJSIP authentication API is a bit annoying. When you set
+ * up an authentication server, you specify a lookup callback to
+ * call into when verifying incoming credentials. The problem
+ * with this callback is that it only gives you the realm and
+ * authentication username. In 2.0.5, there is a new version of
+ * the callback you can use that gives the pjsip_rx_data in
+ * addition.
+ *
+ * Unfortunately, the data we actually \b need is the
+ * \ref ast_sip_auth we are currently observing. So we have two
+ * choices:
+ * 1) Use the current PJSIP API and use thread-local storage
+ * to temporarily store our SIP authentication information. Then
+ * in the callback, we can retrieve the authentication info and
+ * use as needed. Given our threading model, this is safe.
+ * 2) Use the 2.0.5 API and temporarily store the authentication
+ * information in the rdata's endpoint_info. Then in the callback,
+ * we can retrieve the authentication info from the rdata.
+ *
+ * I've chosen option 1 since it does not require backporting
+ * any APIs from future versions of PJSIP, plus I feel the
+ * thread-local option is a bit cleaner.
+ */
+AST_THREADSTORAGE_CUSTOM(auth_store, NULL, auth_store_cleanup);
+
+/*!
+ * \brief Store authentication information in thread-local storage
+ */
+static int store_auth(struct ast_sip_auth *auth)
+{
+	struct ast_sip_auth **pointing;
+	pointing = ast_threadstorage_get(&auth_store, sizeof(pointing));
+	if (!pointing || *pointing) {
+		return -1;
+	}
+
+	ao2_ref(auth, +1);
+	*pointing = auth;
+	return 0;
+}
+
+/*!
+ * \brief Remove authentication information from thread-local storage
+ */
+static int remove_auth(void)
+{
+	struct ast_sip_auth **pointing;
+	pointing = ast_threadstorage_get(&auth_store, sizeof(pointing));
+	if (!pointing) {
+		return -1;
+	}
+
+	ao2_cleanup(*pointing);
+	*pointing = NULL;
+	return 0;
+}
+
+/*!
+ * \brief Retrieve authentication information from thread-local storage
+ */
+static struct ast_sip_auth *get_auth(void)
+{
+	struct ast_sip_auth **auth;
+	auth = ast_threadstorage_get(&auth_store, sizeof(auth));
+	if (auth && *auth) {
+		ao2_ref(*auth, +1);
+		return *auth;
+	}
+	return NULL;
+}
+
+/*!
+ * \brief Lookup callback for authentication verification
+ *
+ * This function is called when we call pjsip_auth_srv_verify(). It
+ * expects us to verify that the realm and account name from the
+ * Authorization header is correct. We are then supposed to supply
+ * a password or MD5 sum of credentials.
+ *
+ * \param pool A memory pool we can use for allocations
+ * \param realm The realm from the Authorization header
+ * \param acc_name the user from the Authorization header
+ * \param[out] info The credentials we need to fill in
+ * \retval PJ_SUCCESS Successful authentication
+ * \retval other Unsuccessful
+ */
+static pj_status_t digest_lookup(pj_pool_t *pool, const pj_str_t *realm,
+		const pj_str_t *acc_name, pjsip_cred_info *info)
+{
+	RAII_VAR(struct ast_sip_auth *, auth, get_auth(), ao2_cleanup);
+	if (!auth) {
+		return PJSIP_SC_FORBIDDEN;
+	}
+
+	if (pj_strcmp2(realm, auth->realm)) {
+		return PJSIP_SC_FORBIDDEN;
+	}
+	if (pj_strcmp2(acc_name, auth->auth_user)) {
+		return PJSIP_SC_FORBIDDEN;
+	}
+
+	pj_strdup2(pool, &info->realm, auth->realm);
+	pj_strdup2(pool, &info->username, auth->auth_user);
+
+	switch (auth->type) {
+	case AST_SIP_AUTH_TYPE_USER_PASS:
+		pj_strdup2(pool, &info->data, auth->auth_pass);
+		info->data_type = PJSIP_CRED_DATA_PLAIN_PASSWD;
+		break;
+	case AST_SIP_AUTH_TYPE_MD5:
+		pj_strdup2(pool, &info->data, auth->md5_creds);
+		info->data_type = PJSIP_CRED_DATA_DIGEST;
+		break;
+	default:
+		return PJSIP_SC_FORBIDDEN;
+	}
+	return PJ_SUCCESS;
+}
+
+/*!
+ * \brief Calculate a nonce
+ *
+ * We use this in order to create authentication challenges. We also use this in order
+ * to verify that an incoming request with credentials could be in response to one
+ * of our challenges.
+ *
+ * The nonce is calculated from a timestamp, the source IP address, the source port, a
+ * unique ID for us, and the realm. This helps to ensure that the incoming request
+ * is from the same source that the nonce was calculated for. Including the realm
+ * ensures that multiple challenges to the same request have different nonces.
+ *
+ * \param A UNIX timestamp expressed as a string
+ * \param rdata The incoming request
+ * \param realm The realm for which authentication should occur
+ */
+static int build_nonce(struct ast_str **nonce, const char *timestamp, const pjsip_rx_data *rdata, const char *realm)
+{
+	struct ast_str *str = ast_str_alloca(256);
+	RAII_VAR(char *, eid, ao2_global_obj_ref(entity_id), ao2_cleanup);
+	char hash[32];
+
+	ast_str_append(&str, 0, "%s", timestamp);
+	ast_str_append(&str, 0, ":%s", rdata->pkt_info.src_name);
+	ast_str_append(&str, 0, ":%d", rdata->pkt_info.src_port);
+	ast_str_append(&str, 0, ":%s", eid);
+	ast_str_append(&str, 0, ":%s", realm);
+	ast_md5_hash(hash, ast_str_buffer(str));
+
+	ast_str_append(nonce, 0, "%s/%s", timestamp, hash);
+	return 0;
+}
+
+/*!
+ * \brief Ensure that a nonce on an incoming request is sane.
+ *
+ * The nonce in an incoming Authorization header needs to pass some scrutiny in order
+ * for us to consider accepting it. What we do is re-build a nonce based on request
+ * data and a realm and see if it matches the nonce they sent us.
+ * \param candidate The nonce on an incoming request
+ * \param rdata The incoming request
+ * \param auth The auth credentials we are trying to match against.
+ * \retval 0 Nonce does not pass validity checks
+ * \retval 1 Nonce passes validity check
+ */
+static int check_nonce(const char *candidate, const pjsip_rx_data *rdata, const struct ast_sip_auth *auth)
+{
+	char *copy = ast_strdupa(candidate);
+	char *timestamp = strsep(&copy, "/");
+	int timestamp_int;
+	time_t now = time(NULL);
+	struct ast_str *calculated = ast_str_alloca(64);
+
+	if (!copy) {
+		/* Clearly a bad nonce! */
+		return 0;
+	}
+
+	if (sscanf(timestamp, "%30d", &timestamp_int) != 1) {
+		return 0;
+	}
+
+	if ((int) now - timestamp_int > auth->nonce_lifetime) {
+		return 0;
+	}
+
+	build_nonce(&calculated, timestamp, rdata, auth->realm);
+	ast_debug(3, "Calculated nonce %s. Actual nonce is %s\n", ast_str_buffer(calculated), candidate);
+	if (strcmp(ast_str_buffer(calculated), candidate)) {
+		return 0;
+	}
+	return 1;
+}
+
+static int find_challenge(const pjsip_rx_data *rdata, const struct ast_sip_auth *auth)
+{
+	struct pjsip_authorization_hdr *auth_hdr = (pjsip_authorization_hdr *) &rdata->msg_info.msg->hdr;
+	int challenge_found = 0;
+	char nonce[64];
+
+	while ((auth_hdr = (pjsip_authorization_hdr *) pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_AUTHORIZATION, auth_hdr->next))) {
+		ast_copy_pj_str(nonce, &auth_hdr->credential.digest.nonce, sizeof(nonce));
+		if (check_nonce(nonce, rdata, auth) && !pj_strcmp2(&auth_hdr->credential.digest.realm, auth->realm)) {
+			challenge_found = 1;
+			break;
+		}
+	}
+
+	return challenge_found;
+}
+
+/*!
+ * \brief Common code for initializing a pjsip_auth_srv
+ */
+static void setup_auth_srv(pj_pool_t *pool, pjsip_auth_srv *auth_server, const struct ast_sip_auth *auth)
+{
+	pj_str_t realm;
+	pj_cstr(&realm, auth->realm);
+
+	pjsip_auth_srv_init(pool, auth_server, &realm, digest_lookup, 0);
+}
+
+/*!
+ * \brief Result of digest verification
+ */
+enum digest_verify_result {
+	/*! Authentication credentials incorrect */
+	AUTH_FAIL,
+	/*! Authentication credentials correct */
+	AUTH_SUCCESS,
+	/*! Authentication credentials correct but nonce mismatch */
+	AUTH_STALE,
+};
+
+/*!
+ * \brief astobj2 callback for verifying incoming credentials
+ *
+ * \param auth The ast_sip_auth to check against
+ * \param rdata The incoming request
+ * \param pool A pool to use for the auth server
+ * \return CMP_MATCH on successful authentication
+ * \return 0 on failed authentication
+ */
+static int verify(struct ast_sip_auth *auth, pjsip_rx_data *rdata, pj_pool_t *pool)
+{
+	pj_status_t authed;
+	int response_code;
+	pjsip_auth_srv auth_server;
+	int stale = 0;
+
+	if (!find_challenge(rdata, auth)) {
+		/* Couldn't find a challenge with a sane nonce.
+		 * Nonce mismatch may just be due to staleness.
+		 */
+		stale = 1;
+	}
+
+	setup_auth_srv(pool, &auth_server, auth);
+
+	store_auth(auth);
+
+	authed = pjsip_auth_srv_verify(&auth_server, rdata, &response_code);
+
+	remove_auth();
+
+	if (authed == PJ_SUCCESS) {
+		if (stale) {
+			return AUTH_STALE;
+		} else {
+			return AUTH_SUCCESS;
+		}
+	}
+	return AUTH_FAIL;
+}
+
+/*!
+ * \brief astobj2 callback for adding digest challenges to responses
+ *
+ * \param auth The ast_aip_auth to build a challenge from
+ * \param tdata The response to add the challenge to
+ * \param rdata The request the challenge is in response to
+ * \param is_stale Indicates whether nonce on incoming request was stale
+ */
+static void challenge(const struct ast_sip_auth *auth, pjsip_tx_data *tdata, const pjsip_rx_data *rdata, int is_stale)
+{
+	pj_str_t qop;
+	pj_str_t pj_nonce;
+	pjsip_auth_srv auth_server;
+	struct ast_str *nonce = ast_str_alloca(256);
+	char time_buf[32];
+	time_t timestamp = time(NULL);
+	snprintf(time_buf, sizeof(time_buf), "%d", (int) timestamp);
+
+	build_nonce(&nonce, time_buf, rdata, auth->realm);
+
+	setup_auth_srv(tdata->pool, &auth_server, auth);
+
+	pj_cstr(&pj_nonce, ast_str_buffer(nonce));
+	pj_cstr(&qop, "auth");
+	pjsip_auth_srv_challenge(&auth_server, &qop, &pj_nonce, NULL, is_stale ? PJ_TRUE : PJ_FALSE, tdata);
+}
+
+/*!
+ * \brief Check authentication using Digest scheme
+ *
+ * This function will check an incoming message against configured authentication
+ * options. If \b any of the incoming Authorization headers result in successful
+ * authentication, then authentication is considered successful.
+ * 
+ * \see ast_sip_check_authentication
+ */
+static enum ast_sip_check_auth_result digest_check_auth(struct ast_sip_endpoint *endpoint,
+		pjsip_rx_data *rdata, pjsip_tx_data *tdata)
+{
+	struct ast_sip_auth **auths = ast_alloca(endpoint->num_inbound_auths * sizeof(*auths));
+	enum digest_verify_result *verify_res = ast_alloca(endpoint->num_inbound_auths * sizeof(*verify_res));
+	enum ast_sip_check_auth_result res;
+	int i;
+
+	if (!auths) {
+		return AST_SIP_AUTHENTICATION_ERROR;
+	}
+
+	if (ast_sip_retrieve_auths(endpoint->sip_inbound_auths, endpoint->num_inbound_auths, auths)) {
+		res = AST_SIP_AUTHENTICATION_ERROR;
+		goto cleanup;
+	}
+
+	for (i = 0; i < endpoint->num_inbound_auths; ++i) {
+		verify_res[i] = verify(auths[i], rdata, tdata->pool);
+		if (verify_res[i] == AUTH_SUCCESS) {
+			res = AST_SIP_AUTHENTICATION_SUCCESS;
+			goto cleanup;
+		}
+	}
+
+	for (i = 0; i < endpoint->num_inbound_auths; ++i) {
+		challenge(auths[i], tdata, rdata, verify_res[i] == AUTH_STALE);
+	}
+	
+	res = AST_SIP_AUTHENTICATION_CHALLENGE;
+
+cleanup:
+	ast_sip_cleanup_auths(auths, endpoint->num_inbound_auths);
+	return res;
+}
+
+static struct ast_sip_authenticator digest_authenticator = {
+	.requires_authentication = digest_requires_authentication,
+	.check_authentication = digest_check_auth,
+};
+
+static int build_entity_id(void)
+{
+	RAII_VAR(struct ast_uuid *, uu, ast_uuid_generate(), ast_free_ptr);
+	RAII_VAR(char *, eid, ao2_alloc(AST_UUID_STR_LEN, NULL), ao2_cleanup);
+
+	if (!uu || !eid) {
+		return -1;
+	}
+
+	ast_uuid_to_str(uu, eid, AST_UUID_STR_LEN);
+	ao2_global_obj_replace_unref(entity_id, eid);
+	return 0;
+}
+
+static int reload_module(void)
+{
+	if (build_entity_id()) {
+		return -1;
+	}
+	return 0;
+}
+
+static int load_module(void)
+{
+	if (build_entity_id()) {
+		return AST_MODULE_LOAD_DECLINE;
+	}
+	if (ast_sip_register_authenticator(&digest_authenticator)) {
+		ao2_global_obj_release(entity_id);
+		return AST_MODULE_LOAD_DECLINE;
+	}
+	return AST_MODULE_LOAD_SUCCESS;
+}
+
+static int unload_module(void)
+{
+	ast_sip_unregister_authenticator(&digest_authenticator);
+	ao2_global_obj_release(entity_id);
+	return 0;
+}
+
+AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "SIP authentication resource",
+		.load = load_module,
+		.unload = unload_module,
+		.reload = reload_module,
+		.load_pri = AST_MODPRI_CHANNEL_DEPEND,
+);
diff --git a/res/res_sip_caller_id.c b/res/res_sip_caller_id.c
new file mode 100644
index 0000000000000000000000000000000000000000..22ece0436e46d390703552c2c75d7f61f1f04329
--- /dev/null
+++ b/res/res_sip_caller_id.c
@@ -0,0 +1,715 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2013, Digium, Inc.
+ *
+ * Mark Michelson <mmichelson@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*** MODULEINFO
+	<depend>pjproject</depend>
+	<depend>res_sip</depend>
+	<depend>res_sip_session</depend>
+	<support_level>core</support_level>
+ ***/
+
+#include "asterisk.h"
+
+#include <pjsip.h>
+#include <pjsip_ua.h>
+
+#include "asterisk/res_sip.h"
+#include "asterisk/res_sip_session.h"
+#include "asterisk/channel.h"
+#include "asterisk/module.h"
+#include "asterisk/callerid.h"
+
+/*!
+ * \internal
+ * \brief Set an ast_party_id name and number based on an identity header.
+ * \param hdr From, P-Asserted-Identity, or Remote-Party-ID header on incoming message
+ * \param[out] id The ID to set data on
+ */
+static void set_id_from_hdr(pjsip_fromto_hdr *hdr, struct ast_party_id *id)
+{
+	char cid_name[AST_CHANNEL_NAME];
+	char cid_num[AST_CHANNEL_NAME];
+	pjsip_sip_uri *uri;
+	pjsip_name_addr *id_name_addr = (pjsip_name_addr *) hdr->uri;
+
+	uri = pjsip_uri_get_uri(id_name_addr);
+	ast_copy_pj_str(cid_name, &id_name_addr->display, sizeof(cid_name));
+	ast_copy_pj_str(cid_num, &uri->user, sizeof(cid_num));
+
+	ast_free(id->name.str);
+	id->name.str = ast_strdup(cid_name);
+	if (!ast_strlen_zero(cid_name)) {
+		id->name.valid = 1;
+	}
+	ast_free(id->number.str);
+	id->number.str = ast_strdup(cid_num);
+	if (!ast_strlen_zero(cid_num)) {
+		id->number.valid = 1;
+	}
+}
+
+/*!
+ * \internal
+ * \brief Get a P-Asserted-Identity or Remote-Party-ID header from an incoming message
+ *
+ * This function will parse the header as if it were a From header. This allows for us
+ * to easily manipulate the URI, as well as add, modify, or remove parameters from the
+ * header
+ *
+ * \param rdata The incoming message
+ * \param header_name The name of the ID header to find
+ * \retval NULL No ID header present or unable to parse ID header
+ * \retval non-NULL The parsed ID header
+ */
+static pjsip_fromto_hdr *get_id_header(pjsip_rx_data *rdata, const pj_str_t *header_name)
+{
+	static const pj_str_t from = { "From", 4 };
+	pj_str_t header_content;
+	pjsip_fromto_hdr *parsed_hdr;
+	pjsip_generic_string_hdr *ident = pjsip_msg_find_hdr_by_name(rdata->msg_info.msg,
+			header_name, NULL);
+	int parsed_len;
+
+	if (!ident) {
+		return NULL;
+	}
+
+	pj_strdup_with_null(rdata->tp_info.pool, &header_content, &ident->hvalue);
+
+	parsed_hdr = pjsip_parse_hdr(rdata->tp_info.pool, &from, header_content.ptr,
+			pj_strlen(&header_content), &parsed_len);
+
+	if (!parsed_hdr) {
+		return NULL;
+	}
+
+	return parsed_hdr;
+}
+
+/*!
+ * \internal
+ * \brief Set an ast_party_id structure based on data in a P-Asserted-Identity header
+ *
+ * This makes use of \ref set_id_from_hdr for setting name and number. It uses
+ * the contents of a Privacy header in order to set presentation information.
+ *
+ * \param rdata The incoming message
+ * \param[out] id The ID to set
+ * \retval 0 Successfully set the party ID
+ * \retval non-zero Could not set the party ID
+ */
+static int set_id_from_pai(pjsip_rx_data *rdata, struct ast_party_id *id)
+{
+	static const pj_str_t pai_str = { "P-Asserted-Identity", 19 };
+	static const pj_str_t privacy_str = { "Privacy", 7 };
+	pjsip_fromto_hdr *pai_hdr = get_id_header(rdata, &pai_str);
+	pjsip_generic_string_hdr *privacy;
+
+	if (!pai_hdr) {
+		return -1;
+	}
+
+	set_id_from_hdr(pai_hdr, id);
+
+	if (!id->number.valid) {
+		return -1;
+	}
+
+	privacy = pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, &privacy_str, NULL);
+	if (!privacy) {
+		return 0;
+	}
+	if (!pj_stricmp2(&privacy->hvalue, "id")) {
+		id->number.presentation = AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED;
+		id->name.presentation = AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED;
+	}
+
+	return 0;
+}
+
+/*!
+ * \internal
+ * \brief Set an ast_party_id structure based on data in a Remote-Party-ID header
+ *
+ * This makes use of \ref set_id_from_hdr for setting name and number. It uses
+ * the privacy and screen parameters in order to set presentation information.
+ *
+ * \param rdata The incoming message
+ * \param[out] id The ID to set
+ * \retval 0 Succesfully set the party ID
+ * \retval non-zero Could not set the party ID
+ */
+static int set_id_from_rpid(pjsip_rx_data *rdata, struct ast_party_id *id)
+{
+	static const pj_str_t rpid_str = { "Remote-Party-ID", 15 };
+	static const pj_str_t privacy_str = { "privacy", 7 };
+	static const pj_str_t screen_str = { "screen", 6 };
+	pjsip_fromto_hdr *rpid_hdr = get_id_header(rdata, &rpid_str);
+	pjsip_param *screen;
+	pjsip_param *privacy;
+
+	if (!rpid_hdr) {
+		return -1;
+	}
+
+	set_id_from_hdr(rpid_hdr, id);
+
+	if (!id->number.valid) {
+		return -1;
+	}
+
+	privacy = pjsip_param_find(&rpid_hdr->other_param, &privacy_str);
+	screen = pjsip_param_find(&rpid_hdr->other_param, &screen_str);
+	if (privacy && !pj_stricmp2(&privacy->value, "full")) {
+		id->number.presentation |= AST_PRES_RESTRICTED;
+		id->name.presentation |= AST_PRES_RESTRICTED;
+	}
+	if (screen && !pj_stricmp2(&screen->value, "yes")) {
+		id->number.presentation |= AST_PRES_USER_NUMBER_PASSED_SCREEN;
+		id->name.presentation |= AST_PRES_USER_NUMBER_PASSED_SCREEN;
+	}
+
+	return 0;
+}
+
+/*!
+ * \internal
+ * \brief Set an ast_party_id structure based on data in a From
+ *
+ * This makes use of \ref set_id_from_hdr for setting name and number. It uses
+ * no information from the message in order to set privacy. It relies on endpoint
+ * configuration for privacy information.
+ *
+ * \param rdata The incoming message
+ * \param[out] id The ID to set
+ * \retval 0 Succesfully set the party ID
+ * \retval non-zero Could not set the party ID
+ */
+static int set_id_from_from(struct pjsip_rx_data *rdata, struct ast_party_id *id)
+{
+	pjsip_fromto_hdr *from = pjsip_msg_find_hdr(rdata->msg_info.msg,
+			PJSIP_H_FROM, rdata->msg_info.msg->hdr.next);
+
+	if (!from) {
+		/* This had better not happen */
+		return -1;
+	}
+
+	set_id_from_hdr(from, id);
+
+	if (!id->number.valid) {
+		return -1;
+	}
+
+	return 0;
+}
+
+/*!
+ * \internal
+ * \brief Determine if a connected line update should be queued
+ *
+ * This uses information about the session and the ID that would be queued
+ * in the connected line update in order to determine if we should queue
+ * a connected line update.
+ *
+ * \param session The session whose channel we wish to queue the connected line update on
+ * \param id The identification information that would be queued on the connected line update
+ * \retval 0 We should not queue a connected line update
+ * \retval non-zero We should queue a connected line update
+ */
+static int should_queue_connected_line_update(const struct ast_sip_session *session, const struct ast_party_id *id)
+{
+	/* Invalid number means no update */
+	if (!id->number.valid) {
+		return 0;
+	}
+
+	/* If the session has never communicated an update or if the
+	 * new ID has a different number than the session, then we
+	 * should queue an update
+	 */
+	if (ast_strlen_zero(session->id.number.str) ||
+			strcmp(session->id.number.str, id->number.str)) {
+		return 1;
+	}
+
+	/* By making it to this point, it means the number is not enough
+	 * to determine if an update should be sent. Now we look at
+	 * the name
+	 */
+
+	/* If the number couldn't warrant an update and the name is
+	 * invalid, then no update
+	 */
+	if (!id->name.valid) {
+		return 0;
+	}
+
+	/* If the name has changed or we don't have a name set for the
+	 * session, then we should send an update
+	 */
+	if (ast_strlen_zero(session->id.name.str) ||
+			strcmp(session->id.name.str, id->name.str)) {
+		return 1;
+	}
+
+	/* Neither the name nor the number have changed. No update */
+	return 0;
+}
+
+/*!
+ * \internal
+ * \brief Queue a connected line update on a session's channel.
+ * \param session The session whose channel should have the connected line update queued upon.
+ * \param id The identification information to place in the connected line update
+ */
+static void queue_connected_line_update(struct ast_sip_session *session, const struct ast_party_id *id)
+{
+	struct ast_party_connected_line connected;
+	struct ast_set_party_connected_line update_connected;
+
+	ast_party_connected_line_init(&connected);
+	ast_party_id_copy(&connected.id, id);
+
+	memset(&update_connected, 0, sizeof(update_connected));
+	update_connected.id.number = 1;
+	update_connected.id.name = 1;
+
+	ast_set_party_id_all(&update_connected.priv);
+	connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
+	ast_party_id_copy(&session->id, &connected.id);
+	ast_channel_queue_connected_line_update(session->channel, &connected, &update_connected);
+
+	ast_party_connected_line_free(&connected);
+}
+
+/*!
+ * \internal
+ * \brief Make updates to connected line information based on an incoming request.
+ *
+ * This will get identity information from an incoming request. Once the identification is
+ * retrieved, we will check if the new information warrants a connected line update and queue
+ * a connected line update if so.
+ *
+ * \param session The session on which we received an incoming request
+ * \param rdata The incoming request
+ */
+static void update_incoming_connected_line(struct ast_sip_session *session, pjsip_rx_data *rdata)
+{
+	struct ast_party_id id;
+
+	if (!session->endpoint->trust_id_inbound) {
+		return;
+	}
+
+	ast_party_id_init(&id);
+	if (set_id_from_pai(rdata, &id) && set_id_from_rpid(rdata, &id)) {
+		return;
+	}
+	if (should_queue_connected_line_update(session, &id)) {
+		queue_connected_line_update(session, &id);
+	}
+
+	ast_party_id_free(&id);
+}
+
+/*!
+ * \internal
+ * \brief Session supplement callback on an incoming INVITE request
+ *
+ * If we are receiving an initial INVITE, then we will set the session's identity
+ * based on the INVITE or configured endpoint values. If we are receiving a reinvite,
+ * then we will potentially queue a connected line update via the \ref update_incoming_connected_line
+ * function
+ *
+ * \param session The session that has received an INVITE
+ * \param rdata The incoming INVITE
+ */
+static int caller_id_incoming_request(struct ast_sip_session *session, pjsip_rx_data *rdata)
+{
+	if (session->inv_session->state < PJSIP_INV_STATE_CONFIRMED) {
+		/* Initial inbound INVITE. Set the session ID directly */
+		if (session->endpoint->trust_id_inbound &&
+				(!set_id_from_pai(rdata, &session->id) || !set_id_from_rpid(rdata, &session->id))) {
+			return 0;
+		}
+		ast_party_id_copy(&session->id, &session->endpoint->id);
+		if (!session->endpoint->id.number.valid) {
+			set_id_from_from(rdata, &session->id);
+		}
+	} else {
+		/* Reinvite. Check for changes to the ID and queue a connected line
+		 * update if necessary
+		 */
+		update_incoming_connected_line(session, rdata);
+	}
+	return 0;
+}
+
+/*!
+ * \internal
+ * \brief Session supplement callback on INVITE response
+ *
+ * INVITE responses could result in queuing connected line updates.
+ *
+ * \param session The session on which communication is happening
+ * \param rdata The incoming INVITE response
+ */
+static void caller_id_incoming_response(struct ast_sip_session *session, pjsip_rx_data *rdata)
+{
+	if (!session->channel) {
+		return;
+	}
+
+	update_incoming_connected_line(session, rdata);
+}
+
+/*!
+ * \internal
+ * \brief Set name and number information on an identity header.
+ * \param pool Memory pool to use for string duplication
+ * \param id_hdr A From, P-Asserted-Identity, or Remote-Party-ID header to modify
+ * \param id The identity information to apply to the header
+ */
+static void modify_id_header(pj_pool_t *pool, pjsip_fromto_hdr *id_hdr, const struct ast_party_id *id)
+{
+	pjsip_name_addr *id_name_addr;
+	pjsip_sip_uri *id_uri;
+
+	id_name_addr = (pjsip_name_addr *) id_hdr->uri;
+	id_uri = pjsip_uri_get_uri(id_name_addr->uri);
+
+	if (id->name.valid) {
+		pj_strdup2(pool, &id_name_addr->display, id->name.str);
+	}
+
+	pj_strdup2(pool, &id_uri->user, id->number.str);
+}
+
+/*!
+ * \internal
+ * \brief Create an identity header for an outgoing message
+ * \param hdr_name The name of the header to create
+ * \param tdata The message to place the header on
+ * \param id The identification information for the new header
+ * \return newly-created header
+ */
+static pjsip_fromto_hdr *create_new_id_hdr(const pj_str_t *hdr_name, pjsip_tx_data *tdata, const struct ast_party_id *id)
+{
+	pjsip_fromto_hdr *id_hdr;
+	pjsip_fromto_hdr *base;
+	pjsip_name_addr *id_name_addr;
+	pjsip_sip_uri *id_uri;
+
+	base = tdata->msg->type == PJSIP_REQUEST_MSG ? PJSIP_MSG_FROM_HDR(tdata->msg) :
+		PJSIP_MSG_TO_HDR(tdata->msg);
+	id_hdr = pjsip_from_hdr_create(tdata->pool);
+	id_hdr->type = PJSIP_H_OTHER;
+	pj_strdup(tdata->pool, &id_hdr->name, hdr_name);
+	id_hdr->sname.slen = 0;
+
+	id_name_addr = pjsip_uri_clone(tdata->pool, base->uri);
+	id_uri = pjsip_uri_get_uri(id_name_addr->uri);
+
+	if (id->name.valid) {
+		pj_strdup2(tdata->pool, &id_name_addr->display, id->name.str);
+	}
+
+	pj_strdup2(tdata->pool, &id_uri->user, id->number.str);
+
+	id_hdr->uri = (pjsip_uri *) id_name_addr;
+	return id_hdr;
+}
+
+/*!
+ * \internal
+ * \brief Add a Privacy header to an outbound message
+ *
+ * When sending a P-Asserted-Identity header, if privacy is requested, then we
+ * will need to indicate such by adding a Privacy header. Similarly, if no
+ * privacy is requested, and a Privacy header already exists on the message,
+ * then the old Privacy header should be removed.
+ *
+ * \param tdata The outbound message to add the Privacy header to
+ * \param id The id information used to determine privacy
+ */
+static void add_privacy_header(pjsip_tx_data *tdata, const struct ast_party_id *id)
+{
+	static const pj_str_t pj_privacy_name = { "Privacy", 7 };
+	static const pj_str_t pj_privacy_value = { "id", 2 };
+	pjsip_hdr *old_privacy;
+
+	old_privacy = pjsip_msg_find_hdr_by_name(tdata->msg, &pj_privacy_name, NULL);
+
+	if ((id->name.presentation & AST_PRES_RESTRICTION) == AST_PRES_RESTRICTED ||
+			(id->name.presentation & AST_PRES_RESTRICTION) == AST_PRES_RESTRICTED) {
+		if (!old_privacy) {
+			pjsip_generic_string_hdr *privacy_hdr = pjsip_generic_string_hdr_create(
+					tdata->pool, &pj_privacy_name, &pj_privacy_value);
+			pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr *)privacy_hdr);
+		}
+	} else {
+		if (old_privacy) {
+			pj_list_erase(old_privacy);
+		}
+	}
+}
+
+/*!
+ * \internal
+ * \brief Add a P-Asserted-Identity header to an outbound message
+ * \param tdata The message to add the header to
+ * \param id The identification information used to populate the header
+ */
+static void add_pai_header(pjsip_tx_data *tdata, const struct ast_party_id *id)
+{
+	static const pj_str_t pj_pai_name = { "P-Asserted-Identity", 19 };
+	pjsip_fromto_hdr *pai_hdr;
+	pjsip_fromto_hdr *old_pai;
+
+	if (!id->number.valid) {
+		return;
+	}
+
+	/* Since inv_session reuses responses, we have to make sure there's not already
+	 * a P-Asserted-Identity present. If there is, we just modify the old one.
+	 */
+	old_pai = pjsip_msg_find_hdr_by_name(tdata->msg, &pj_pai_name, NULL);
+	if (old_pai) {
+		modify_id_header(tdata->pool, old_pai, id);
+		add_privacy_header(tdata, id);
+		return;
+	}
+
+	pai_hdr = create_new_id_hdr(&pj_pai_name, tdata, id);
+	if (!pai_hdr) {
+		return;
+	}
+	add_privacy_header(tdata, id);
+
+	pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr *)pai_hdr);
+}
+
+/*!
+ * \internal
+ * \brief Add privacy and screen parameters to a Remote-Party-ID header.
+ *
+ * If privacy is requested, then the privacy and screen parameters need to
+ * reflect this. Similarly, if no privacy or screening is to be communicated,
+ * we need to make sure that any previously set values are updated.
+ *
+ * \param tdata The message where the Remote-Party-ID header is
+ * \param hdr The header on which the parameters are being added
+ * \param id The identification information used to determine privacy
+ */
+static void add_privacy_params(pjsip_tx_data *tdata, pjsip_fromto_hdr *hdr, const struct ast_party_id *id)
+{
+	static const pj_str_t privacy_str = { "privacy", 7 };
+	static const pj_str_t screen_str = { "screen", 6 };
+	static const pj_str_t privacy_full_str = { "full", 4 };
+	static const pj_str_t privacy_off_str = { "off", 3 };
+	static const pj_str_t screen_yes_str = { "yes", 3 };
+	static const pj_str_t screen_no_str = { "no", 2 };
+	pjsip_param *old_privacy;
+	pjsip_param *old_screen;
+	pjsip_param *privacy;
+	pjsip_param *screen;
+
+	old_privacy = pjsip_param_find(&hdr->other_param, &privacy_str);
+	old_screen = pjsip_param_find(&hdr->other_param, &screen_str);
+
+	if (!old_privacy) {
+		privacy = PJ_POOL_ALLOC_T(tdata->pool, pjsip_param);
+		privacy->name = privacy_str;
+		pj_list_insert_before(&hdr->other_param, privacy);
+	} else {
+		privacy = old_privacy;
+	}
+
+	if (!old_screen) {
+		screen = PJ_POOL_ALLOC_T(tdata->pool, pjsip_param);
+		screen->name = screen_str;
+		pj_list_insert_before(&hdr->other_param, screen);
+	} else {
+		screen = old_screen;
+	}
+
+	if ((id->name.presentation & AST_PRES_RESTRICTION) == AST_PRES_ALLOWED &&
+			(id->name.presentation & AST_PRES_RESTRICTION) == AST_PRES_ALLOWED) {
+		privacy->value = privacy_off_str;
+	} else {
+		privacy->value = privacy_full_str;
+	}
+
+	if ((id->name.presentation & AST_PRES_NUMBER_TYPE) == AST_PRES_USER_NUMBER_PASSED_SCREEN &&
+			(id->number.presentation & AST_PRES_NUMBER_TYPE) == AST_PRES_USER_NUMBER_PASSED_SCREEN) {
+		screen->value = screen_yes_str;
+	} else {
+		screen->value = screen_no_str;
+	}
+}
+
+/*!
+ * \internal
+ * \brief Add a Remote-Party-ID header to an outbound message
+ * \param tdata The message to add the header to
+ * \param id The identification information used to populate the header
+ */
+static void add_rpid_header(pjsip_tx_data *tdata, const struct ast_party_id *id)
+{
+	static const pj_str_t pj_rpid_name = { "Remote-Party-ID", 15 };
+	pjsip_fromto_hdr *rpid_hdr;
+	pjsip_fromto_hdr *old_rpid;
+
+	if (!id->number.valid) {
+		return;
+	}
+
+	/* Since inv_session reuses responses, we have to make sure there's not already
+	 * a P-Asserted-Identity present. If there is, we just modify the old one.
+	 */
+	old_rpid = pjsip_msg_find_hdr_by_name(tdata->msg, &pj_rpid_name, NULL);
+	if (old_rpid) {
+		modify_id_header(tdata->pool, old_rpid, id);
+		add_privacy_params(tdata, old_rpid, id);
+		return;
+	}
+
+	rpid_hdr = create_new_id_hdr(&pj_rpid_name, tdata, id);
+	if (!rpid_hdr) {
+		return;
+	}
+	add_privacy_params(tdata, rpid_hdr, id);
+	pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr *)rpid_hdr);
+}
+
+/*!
+ * \internal
+ * \brief Add any appropriate identification headers to an outbound SIP message
+ *
+ * This will determine if an outbound message should have identification headers and
+ * will add the appropriately configured headers
+ *
+ * \param session The session on which we will be sending the message
+ * \param tdata The outbound message
+ * \param The identity information to place on the message
+ */
+static void add_id_headers(const struct ast_sip_session *session, pjsip_tx_data *tdata, const struct ast_party_id *id)
+{
+	if (((id->name.presentation & AST_PRES_RESTRICTION) == AST_PRES_RESTRICTED ||
+			(id->number.presentation & AST_PRES_RESTRICTION) == AST_PRES_RESTRICTED) &&
+			!session->endpoint->trust_id_outbound) {
+		return;
+	}
+	if (session->endpoint->send_pai) {
+		add_pai_header(tdata, id);
+	}
+	if (session->endpoint->send_rpid) {
+		add_rpid_header(tdata, id);
+	}
+}
+
+/*!
+ * \internal
+ * \brief Session supplement callback for outgoing INVITE requests
+ *
+ * For an initial INVITE request, we may change the From header to appropriately
+ * reflect the identity information. On all INVITEs (initial and reinvite) we may
+ * add other identity headers such as P-Asserted-Identity and Remote-Party-ID based
+ * on configuration and privacy settings
+ *
+ * \param session The session on which the INVITE will be sent
+ * \param tdata The outbound INVITE request
+ */
+static void caller_id_outgoing_request(struct ast_sip_session *session, pjsip_tx_data *tdata)
+{
+	struct ast_party_id connected_id;
+
+	if (!session->channel) {
+		return;
+	}
+
+	connected_id = ast_channel_connected_effective_id(session->channel);
+	if (session->inv_session->state < PJSIP_INV_STATE_CONFIRMED &&
+			session->endpoint->trust_id_outbound &&
+			(connected_id.name.presentation & AST_PRES_RESTRICTION) == AST_PRES_ALLOWED &&
+			(connected_id.name.presentation & AST_PRES_RESTRICTION) == AST_PRES_ALLOWED) {
+		/* Only change the From header on the initial outbound INVITE. Switching it
+		 * mid-call might confuse some UAs.
+		 */
+		pjsip_fromto_hdr *from;
+		pjsip_dialog *dlg;
+
+		from = pjsip_msg_find_hdr(tdata->msg, PJSIP_H_FROM, tdata->msg->hdr.next);
+		dlg = session->inv_session->dlg;
+
+		modify_id_header(tdata->pool, from, &connected_id);
+		modify_id_header(dlg->pool, dlg->local.info, &connected_id);
+		if (should_queue_connected_line_update(session, &session->endpoint->id)) {
+			queue_connected_line_update(session, &session->endpoint->id);
+		}
+	}
+	add_id_headers(session, tdata, &connected_id);
+}
+
+/*!
+ * \internal
+ * \brief Session supplement for outgoing INVITE response
+ *
+ * This will add P-Asserted-Identity and Remote-Party-ID headers if necessary
+ * 
+ * \param session The session on which the INVITE response is to be sent
+ * \param tdata The outbound INVITE response
+ */
+static void caller_id_outgoing_response(struct ast_sip_session *session, pjsip_tx_data *tdata)
+{
+	struct ast_party_id connected_id;
+
+	if (!session->channel) {
+		return;
+	}
+	connected_id = ast_channel_connected_effective_id(session->channel);
+	add_id_headers(session, tdata, &connected_id);
+}
+
+static struct ast_sip_session_supplement caller_id_supplement = {
+	.method = "INVITE",
+	.priority = AST_SIP_SESSION_SUPPLEMENT_PRIORITY_CHANNEL - 1000,
+	.incoming_request = caller_id_incoming_request,
+	.incoming_response = caller_id_incoming_response,
+	.outgoing_request = caller_id_outgoing_request,
+	.outgoing_response = caller_id_outgoing_response,
+};
+
+static int load_module(void)
+{
+	ast_sip_session_register_supplement(&caller_id_supplement);
+	return AST_MODULE_LOAD_SUCCESS;
+}
+
+static int unload_module(void)
+{
+	ast_sip_session_unregister_supplement(&caller_id_supplement);
+	return 0;
+}
+
+AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "SIP Caller ID Support",
+		.load = load_module,
+		.unload = unload_module,
+		.load_pri = AST_MODPRI_APP_DEPEND,
+	       );
diff --git a/res/res_sip_dtmf_info.c b/res/res_sip_dtmf_info.c
new file mode 100644
index 0000000000000000000000000000000000000000..453e57d06163f7ea22e2de8bc7e12d4c16ba8e37
--- /dev/null
+++ b/res/res_sip_dtmf_info.c
@@ -0,0 +1,128 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2013, Digium, Inc.
+ *
+ * Jason Parker <jparker@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*** MODULEINFO
+	<depend>pjproject</depend>
+	<support_level>core</support_level>
+ ***/
+
+#include "asterisk.h"
+
+#include <pjsip.h>
+#include <pjsip_ua.h>
+
+#include "asterisk/res_sip.h"
+#include "asterisk/res_sip_session.h"
+#include "asterisk/module.h"
+
+static int dtmf_info_incoming_request(struct ast_sip_session *session, struct pjsip_rx_data *rdata)
+{
+	int res = 0;
+	pjsip_msg_body *body = rdata->msg_info.msg->body;
+
+	pjsip_tx_data *tdata;
+
+	char buf[body->len];
+	char *cur = buf;
+	char *line;
+
+	char event = '\0';
+	unsigned int duration = 0;
+
+	if (pj_strcmp2(&body->content_type.type, "application") ||
+	    pj_strcmp2(&body->content_type.subtype, "dtmf-relay")) {
+		return 0;
+	}
+
+	body->print_body(body, buf, body->len);
+
+	while ((line = strsep(&cur, "\r\n"))) {
+		char *c;
+
+		if (!(c = strchr(line, '='))) {
+			continue;
+		}
+		*c++ = '\0';
+
+		c = ast_skip_blanks(c);
+
+		if (!strcasecmp(line, "signal")) {
+			if (c[0] == '!' || c[0] == '*' || c[0] == '#' ||
+			    ('0' <= c[0] && c[0] <= '9') ||
+			    ('A' <= c[0] && c[0] <= 'D') ||
+			    ('a' <= c[0] && c[0] <= 'd')) {
+				event = c[0];
+			} else {
+				ast_log(LOG_ERROR, "Invalid DTMF event signal in INFO message.\n");
+				res = -1;
+				break;
+			}
+		} else if (!strcasecmp(line, "duration")) {
+			sscanf(c, "%30u", &duration);
+		}
+	}
+
+	if (!duration) {
+		duration = 100;
+	}
+
+	if (event == '!') {
+		struct ast_frame f = { AST_FRAME_CONTROL, { AST_CONTROL_FLASH, } };
+
+		ast_queue_frame(session->channel, &f);
+	} else if (event != '\0') {
+		struct ast_frame f = { AST_FRAME_DTMF, };
+		f.len = duration;
+		f.subclass.integer = event;
+
+		ast_queue_frame(session->channel, &f);
+	} else {
+		res = -1;
+	}
+
+	if (pjsip_dlg_create_response(session->inv_session->dlg, rdata, !res ? 200 : 500, NULL, &tdata) == PJ_SUCCESS) {
+		struct pjsip_transaction *tsx = pjsip_rdata_get_tsx(rdata);
+
+		pjsip_dlg_send_response(session->inv_session->dlg, tsx, tdata);
+	}
+
+	return res;
+}
+
+static struct ast_sip_session_supplement dtmf_info_supplement = {
+	.method = "INFO",
+	.incoming_request = dtmf_info_incoming_request,
+};
+
+static int load_module(void)
+{
+	ast_sip_session_register_supplement(&dtmf_info_supplement);
+	return AST_MODULE_LOAD_SUCCESS;
+}
+
+static int unload_module(void)
+{
+	ast_sip_session_unregister_supplement(&dtmf_info_supplement);
+	return 0;
+}
+
+AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "SIP DTMF INFO Support",
+		.load = load_module,
+		.unload = unload_module,
+		.load_pri = AST_MODPRI_APP_DEPEND,
+	       );
diff --git a/res/res_sip_endpoint_identifier_constant.c b/res/res_sip_endpoint_identifier_constant.c
new file mode 100644
index 0000000000000000000000000000000000000000..e519a9ee8eec691f59474f19a0294330bcea8567
--- /dev/null
+++ b/res/res_sip_endpoint_identifier_constant.c
@@ -0,0 +1,67 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2013, Digium, Inc.
+ *
+ * Mark Michelson <mmichelson@digium.com>
+ *
+ * Includes code and algorithms from the Zapata library.
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*** MODULEINFO
+	<depend>pjproject</depend>
+	<defaultenabled>no</defaultenabled>
+	<support_level>core</support_level>
+ ***/
+
+#include "asterisk.h"
+
+#include <pjsip.h>
+
+#include "asterisk/res_sip.h"
+#include "asterisk/module.h"
+
+static struct ast_sip_endpoint *constant_identify(pjsip_rx_data *rdata)
+{
+	/* This endpoint identifier always returns the same endpoint. It's used
+	 * simply for testing. It allocates an endpoint from sorcery so default values
+	 * do get applied.
+	 */
+	struct ast_sip_endpoint *endpoint = ast_sorcery_alloc(ast_sip_get_sorcery(), "endpoint", NULL);
+	if (!endpoint) {
+		return NULL;
+	}
+	ast_parse_allow_disallow(&endpoint->prefs, endpoint->codecs, "ulaw", 1);
+	return endpoint;
+}
+
+static struct ast_sip_endpoint_identifier constant_identifier = {
+	.identify_endpoint = constant_identify,
+};
+
+static int load_module(void)
+{
+	ast_sip_register_endpoint_identifier(&constant_identifier);
+	return AST_MODULE_LOAD_SUCCESS;
+}
+
+static int unload_module(void)
+{
+	return 0;
+}
+
+AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "SIP Constant Endpoint Identifier",
+		.load = load_module,
+		.unload = unload_module,
+		.load_pri = AST_MODPRI_APP_DEPEND,
+	       );
diff --git a/res/res_sip_endpoint_identifier_ip.c b/res/res_sip_endpoint_identifier_ip.c
new file mode 100644
index 0000000000000000000000000000000000000000..49c70b59de91dfb92e58b1918fc5ea4bc088d08d
--- /dev/null
+++ b/res/res_sip_endpoint_identifier_ip.c
@@ -0,0 +1,151 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2013, Digium, Inc.
+ *
+ * Mark Michelson <mmichelson@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*** MODULEINFO
+	<depend>pjproject</depend>
+	<support_level>core</support_level>
+ ***/
+
+#include "asterisk.h"
+
+#include <pjsip.h>
+
+#include "asterisk/res_sip.h"
+#include "asterisk/module.h"
+#include "asterisk/acl.h"
+
+/*! \brief Structure for an IP identification matching object */
+struct ip_identify_match {
+	/*! \brief Sorcery object details */
+	SORCERY_OBJECT(details);
+	/*! \brief Stringfields */
+	AST_DECLARE_STRING_FIELDS(
+		/*! The name of the endpoint */
+		AST_STRING_FIELD(endpoint_name);
+	);
+	/*! \brief Networks or addresses that should match this */
+	struct ast_ha *matches;
+};
+
+/*! \brief Destructor function for a matching object */
+static void ip_identify_destroy(void *obj)
+{
+	struct ip_identify_match *identify = obj;
+
+	ast_string_field_free_memory(identify);
+	ast_free_ha(identify->matches);
+}
+
+/*! \brief Allocator function for a matching object */
+static void *ip_identify_alloc(const char *name)
+{
+	struct ip_identify_match *identify = ao2_alloc(sizeof(*identify), ip_identify_destroy);
+
+	if (!identify || ast_string_field_init(identify, 256)) {
+		ao2_cleanup(identify);
+		return NULL;
+	}
+
+	return identify;
+}
+
+/*! \brief Comparator function for a matching object */
+static int ip_identify_match_check(void *obj, void *arg, int flags)
+{
+	struct ip_identify_match *identify = obj;
+	struct ast_sockaddr *addr = arg;
+
+	return (ast_apply_ha(identify->matches, addr) != AST_SENSE_ALLOW) ? CMP_MATCH | CMP_STOP : 0;
+}
+
+static struct ast_sip_endpoint *ip_identify(pjsip_rx_data *rdata)
+{
+	struct ast_sockaddr addr = { { 0, } };
+	RAII_VAR(struct ao2_container *, candidates, NULL, ao2_cleanup);
+	RAII_VAR(struct ip_identify_match *, match, NULL, ao2_cleanup);
+
+	/* If no possibilities exist return early to save some time */
+	if (!(candidates = ast_sorcery_retrieve_by_fields(ast_sip_get_sorcery(), "identify", AST_RETRIEVE_FLAG_MULTIPLE | AST_RETRIEVE_FLAG_ALL, NULL)) ||
+		!ao2_container_count(candidates)) {
+		return NULL;
+	}
+
+	ast_sockaddr_parse(&addr, rdata->pkt_info.src_name, PARSE_PORT_FORBID);
+	ast_sockaddr_set_port(&addr, rdata->pkt_info.src_port);
+
+	if (!(match = ao2_callback(candidates, 0, ip_identify_match_check, &addr))) {
+		return NULL;
+	}
+
+	return ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "endpoint", match->endpoint_name);
+}
+
+static struct ast_sip_endpoint_identifier ip_identifier = {
+	.identify_endpoint = ip_identify,
+};
+
+/*! \brief Custom handler for match field */
+static int ip_identify_match_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
+{
+	struct ip_identify_match *identify = obj;
+	int error = 0;
+
+	/* We deny what we actually want to match because there is an implicit permit all rule for ACLs */
+	if (!(identify->matches = ast_append_ha("d", var->value, identify->matches, &error))) {
+		return -1;
+	}
+
+	return error;
+}
+
+static int load_module(void)
+{
+	ast_sorcery_apply_default(ast_sip_get_sorcery(), "identify", "config", "res_sip.conf,criteria=type=identify");
+
+	if (ast_sorcery_object_register(ast_sip_get_sorcery(), "identify", ip_identify_alloc, NULL, NULL)) {
+		return AST_MODULE_LOAD_DECLINE;
+	}
+
+	ast_sorcery_object_field_register(ast_sip_get_sorcery(), "identify", "type", "", OPT_NOOP_T, 0, 0);
+	ast_sorcery_object_field_register(ast_sip_get_sorcery(), "identify", "endpoint", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ip_identify_match, endpoint_name));
+	ast_sorcery_object_field_register_custom(ast_sip_get_sorcery(), "identify", "match", "", ip_identify_match_handler, NULL, 0, 0);
+	ast_sorcery_reload_object(ast_sip_get_sorcery(), "identify");
+
+	ast_sip_register_endpoint_identifier(&ip_identifier);
+
+	return AST_MODULE_LOAD_SUCCESS;
+}
+
+static int reload_module(void)
+{
+	ast_sorcery_reload_object(ast_sip_get_sorcery(), "identify");
+	return 0;
+}
+
+static int unload_module(void)
+{
+	ast_sip_unregister_endpoint_identifier(&ip_identifier);
+	return 0;
+}
+
+AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "SIP IP endpoint identifier",
+		.load = load_module,
+		.reload = reload_module,
+		.unload = unload_module,
+		.load_pri = AST_MODPRI_APP_DEPEND,
+	       );
diff --git a/res/res_sip_endpoint_identifier_user.c b/res/res_sip_endpoint_identifier_user.c
new file mode 100644
index 0000000000000000000000000000000000000000..cd1f76bb1ef0a71e2e58a7ffba597cba298954bc
--- /dev/null
+++ b/res/res_sip_endpoint_identifier_user.c
@@ -0,0 +1,128 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2013, Digium, Inc.
+ *
+ * Mark Michelson <mmichelson@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*** MODULEINFO
+	<depend>pjproject</depend>
+	<support_level>core</support_level>
+ ***/
+
+#include "asterisk.h"
+
+#include <pjsip.h>
+
+#include "asterisk/res_sip.h"
+#include "asterisk/module.h"
+
+static int get_endpoint_details(pjsip_rx_data *rdata, char *endpoint, size_t endpoint_size, char *domain, size_t domain_size)
+{
+	pjsip_uri *from = rdata->msg_info.from->uri;
+	pjsip_sip_uri *sip_from;
+	if (!PJSIP_URI_SCHEME_IS_SIP(from) && !PJSIP_URI_SCHEME_IS_SIPS(from)) {
+		return -1;
+	}
+	sip_from = (pjsip_sip_uri *) pjsip_uri_get_uri(from);
+	ast_copy_pj_str(endpoint, &sip_from->user, endpoint_size);
+	ast_copy_pj_str(domain, &sip_from->host, domain_size);
+	return 0;
+}
+
+static int find_transport_in_use(void *obj, void *arg, int flags)
+{
+	struct ast_sip_transport *transport = obj;
+	pjsip_rx_data *rdata = arg;
+
+	if ((transport->state->transport == rdata->tp_info.transport) ||
+		(transport->state->factory && !pj_strcmp(&transport->state->factory->addr_name.host, &rdata->tp_info.transport->local_name.host) &&
+			transport->state->factory->addr_name.port == rdata->tp_info.transport->local_name.port)) {
+		return CMP_MATCH | CMP_STOP;
+	}
+
+	return 0;
+}
+
+static struct ast_sip_endpoint *username_identify(pjsip_rx_data *rdata)
+{
+	char endpoint_name[64], domain_name[64], id[AST_UUID_STR_LEN];
+	struct ast_sip_endpoint *endpoint;
+	RAII_VAR(struct ast_sip_domain_alias *, alias, NULL, ao2_cleanup);
+	RAII_VAR(struct ao2_container *, transports, NULL, ao2_cleanup);
+	RAII_VAR(struct ast_sip_transport *, transport, NULL, ao2_cleanup);
+
+	if (get_endpoint_details(rdata, endpoint_name, sizeof(endpoint_name), domain_name, sizeof(domain_name))) {
+		return NULL;
+	}
+
+	/* Attempt to find the endpoint given the name and domain provided */
+	snprintf(id, sizeof(id), "%s@%s", endpoint_name, domain_name);
+	if ((endpoint = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "endpoint", id))) {
+		goto done;
+	}
+
+	/* See if an alias exists for the domain provided */
+	if ((alias = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "domain_alias", domain_name))) {
+		snprintf(id, sizeof(id), "%s@%s", endpoint_name, alias->domain);
+		if ((endpoint = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "endpoint", id))) {
+			goto done;
+		}
+	}
+
+	/* See if the transport this came in on has a provided domain */
+	if ((transports = ast_sorcery_retrieve_by_fields(ast_sip_get_sorcery(), "transport", AST_RETRIEVE_FLAG_MULTIPLE | AST_RETRIEVE_FLAG_ALL, NULL)) &&
+		(transport = ao2_callback(transports, 0, find_transport_in_use, rdata)) &&
+		!ast_strlen_zero(transport->domain)) {
+		snprintf(id, sizeof(id), "%s@%s", endpoint_name, transport->domain);
+		if ((endpoint = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "endpoint", id))) {
+			goto done;
+		}
+	}
+
+	/* Fall back to no domain */
+	endpoint = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "endpoint", endpoint_name);
+
+done:
+	if (endpoint) {
+		if (!(endpoint->ident_method & AST_SIP_ENDPOINT_IDENTIFY_BY_USERNAME)) {
+			ao2_ref(endpoint, -1);
+			return NULL;
+		}
+		ast_debug(3, "Retrieved endpoint %s\n", ast_sorcery_object_get_id(endpoint));
+	}
+	return endpoint;
+}
+
+static struct ast_sip_endpoint_identifier username_identifier = {
+	.identify_endpoint = username_identify,
+};
+
+static int load_module(void)
+{
+	ast_sip_register_endpoint_identifier(&username_identifier);
+	return AST_MODULE_LOAD_SUCCESS;
+}
+
+static int unload_module(void)
+{
+	ast_sip_unregister_endpoint_identifier(&username_identifier);
+	return 0;
+}
+
+AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "SIP username endpoint identifier",
+		.load = load_module,
+		.unload = unload_module,
+		.load_pri = AST_MODPRI_APP_DEPEND,
+	       );
diff --git a/res/res_sip_logger.c b/res/res_sip_logger.c
new file mode 100644
index 0000000000000000000000000000000000000000..da17198100ad0f46a4c4ef841fab9a8314255f15
--- /dev/null
+++ b/res/res_sip_logger.c
@@ -0,0 +1,81 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2013, Digium, Inc.
+ *
+ * Mark Michelson <mmichelson@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*** MODULEINFO
+	<depend>pjproject</depend>
+	<support_level>core</support_level>
+ ***/
+
+#include "asterisk.h"
+
+#include <pjsip.h>
+
+#include "asterisk/res_sip.h"
+#include "asterisk/module.h"
+#include "asterisk/logger.h"
+
+static pj_status_t logging_on_tx_msg(pjsip_tx_data *tdata)
+{
+	ast_verbose("<--- Transmitting SIP %s (%d bytes) to %s:%s:%d --->\n%.*s\n",
+		    tdata->msg->type == PJSIP_REQUEST_MSG ? "request" : "response",
+		    (int) (tdata->buf.cur - tdata->buf.start),
+		    tdata->tp_info.transport->type_name,
+		    tdata->tp_info.dst_name,
+		    tdata->tp_info.dst_port,
+		    (int) (tdata->buf.end - tdata->buf.start), tdata->buf.start);
+	return PJ_SUCCESS;
+}
+
+static pj_bool_t logging_on_rx_msg(pjsip_rx_data *rdata)
+{
+	ast_verbose("<--- Received SIP %s (%d bytes) from %s:%s:%d --->\n%s\n",
+		    rdata->msg_info.msg->type == PJSIP_REQUEST_MSG ? "request" : "response",
+		    rdata->msg_info.len,
+		    rdata->tp_info.transport->type_name,
+		    rdata->pkt_info.src_name,
+		    rdata->pkt_info.src_port,
+		    rdata->pkt_info.packet);
+	return PJ_FALSE;
+}
+
+static pjsip_module logging_module = {
+	.name = { "Logging Module", 14 },
+	.priority = 0,
+	.on_rx_request = logging_on_rx_msg,
+	.on_rx_response = logging_on_rx_msg,
+	.on_tx_request = logging_on_tx_msg,
+	.on_tx_response = logging_on_tx_msg,
+};
+
+static int load_module(void)
+{
+	ast_sip_register_service(&logging_module);
+	return AST_MODULE_LOAD_SUCCESS;
+}
+
+static int unload_module(void)
+{
+	ast_sip_unregister_service(&logging_module);
+	return 0;
+}
+
+AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "SIP Packet Logger",
+		.load = load_module,
+		.unload = unload_module,
+		.load_pri = AST_MODPRI_APP_DEPEND,
+	       );
diff --git a/res/res_sip_mwi.c b/res/res_sip_mwi.c
new file mode 100644
index 0000000000000000000000000000000000000000..7d62816d079ff6225dd96ea6e6c58827a3d88d42
--- /dev/null
+++ b/res/res_sip_mwi.c
@@ -0,0 +1,709 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2013, Digium, Inc.
+ *
+ * Mark Michelson <mmichelson@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+#include "asterisk.h"
+
+#include <pjsip.h>
+#include <pjsip_simple.h>
+#include <pjlib.h>
+
+#include "asterisk/res_sip.h"
+#include "asterisk/res_sip_pubsub.h"
+#include "asterisk/module.h"
+#include "asterisk/logger.h"
+#include "asterisk/astobj2.h"
+#include "asterisk/sorcery.h"
+#include "asterisk/stasis.h"
+#include "asterisk/app.h"
+
+/*** MODULEINFO
+	<depend>pjproject</depend>
+	<depend>res_sip</depend>
+	<depend>res_sip_pubsub</depend>
+	<support_level>core</support_level>
+ ***/
+
+struct mwi_subscription;
+AO2_GLOBAL_OBJ_STATIC(unsolicited_mwi);
+
+#define STASIS_BUCKETS 13
+#define MWI_BUCKETS 53
+static void mwi_subscription_shutdown(struct ast_sip_subscription *sub);
+static struct ast_sip_subscription *mwi_new_subscribe(struct ast_sip_endpoint *endpoint,
+		pjsip_rx_data *rdata);
+static void mwi_resubscribe(struct ast_sip_subscription *sub, pjsip_rx_data *rdata,
+		struct ast_sip_subscription_response_data *response_data);
+static void mwi_subscription_timeout(struct ast_sip_subscription *sub);
+static void mwi_subscription_terminated(struct ast_sip_subscription *sub, pjsip_rx_data *rdata);
+static void mwi_notify_response(struct ast_sip_subscription *sub, pjsip_rx_data *rdata);
+static void mwi_notify_request(struct ast_sip_subscription *sub, pjsip_rx_data *rdata,
+		struct ast_sip_subscription_response_data *response_data);
+static int mwi_refresh_subscription(struct ast_sip_subscription *sub);
+
+static struct ast_sip_subscription_handler mwi_handler = {
+	.event_name = "message-summary",
+	.accept = { "application/simple-message-summary", },
+	.subscription_shutdown = mwi_subscription_shutdown,
+	.new_subscribe = mwi_new_subscribe,
+	.resubscribe = mwi_resubscribe,
+	.subscription_timeout = mwi_subscription_timeout,
+	.subscription_terminated = mwi_subscription_terminated,
+	.notify_response = mwi_notify_response,
+	.notify_request = mwi_notify_request,
+	.refresh_subscription = mwi_refresh_subscription,
+};
+
+/*!
+ * \brief Wrapper for stasis subscription
+ *
+ * An MWI subscription has a container of these. This
+ * represents a stasis subscription for MWI state.
+ */
+struct mwi_stasis_subscription {
+	/*! The MWI stasis subscription */
+	struct stasis_subscription *stasis_sub;
+	/*! The mailbox corresponding with the MWI subscription. Used as a hash key */
+	char mailbox[1];
+};
+
+/*!
+ * \brief A subscription for MWI
+ *
+ * This subscription is the basis for MWI for an endpoint. Each
+ * endpoint that uses MWI will have a corresponding mwi_subscription.
+ *
+ * This structure acts as the owner for the underlying SIP subscription.
+ * When the mwi_subscription is destroyed, the SIP subscription dies, too.
+ * The mwi_subscription's lifetime is governed by its underlying stasis
+ * subscriptions. When all stasis subscriptions are destroyed, the
+ * mwi_subscription is destroyed as well.
+ */
+struct mwi_subscription {
+	/*! Container of \ref mwi_stasis_subscription structures.
+	 * A single MWI subscription may be fore multiple mailboxes, thus
+	 * requiring multiple stasis subscriptions
+	 */
+	struct ao2_container *stasis_subs;
+	/*! The SIP subscription. Unsolicited MWI does not use this */
+	struct ast_sip_subscription *sip_sub;
+	/*! Is the MWI solicited (i.e. Initiated with an external SUBSCRIBE) ? */
+	unsigned int is_solicited;
+	/*! Identifier for the subscription.
+	 * The identifier is the same as the corresponding endpoint's stasis ID.
+	 * Used as a hash key
+	 */
+	char id[1];
+};
+
+static void mwi_stasis_cb(void *userdata, struct stasis_subscription *sub,
+		struct stasis_topic *topic, struct stasis_message *msg);
+
+static struct mwi_stasis_subscription *mwi_stasis_subscription_alloc(const char *mailbox, struct mwi_subscription *mwi_sub)
+{
+	struct mwi_stasis_subscription *mwi_stasis_sub;
+	struct stasis_topic *topic;
+	
+	if (!mwi_sub) {
+		return NULL;
+	}
+	
+	mwi_stasis_sub = ao2_alloc(sizeof(*mwi_stasis_sub) + strlen(mailbox), NULL);
+	if (!mwi_stasis_sub) {
+		return NULL;
+	}
+
+	topic = stasis_mwi_topic(mailbox);
+
+	/* Safe strcpy */
+	strcpy(mwi_stasis_sub->mailbox, mailbox);
+	ao2_ref(mwi_sub, +1);
+	ast_debug(3, "Creating stasis MWI subscription to mailbox %s for endpoint %s\n", mailbox, mwi_sub->id);
+	mwi_stasis_sub->stasis_sub = stasis_subscribe(topic, mwi_stasis_cb, mwi_sub);
+	return mwi_stasis_sub;
+}
+
+static int stasis_sub_hash(const void *obj, int flags)
+{
+	const struct mwi_stasis_subscription *mwi_stasis = obj;
+
+	return ast_str_hash(mwi_stasis->mailbox);
+}
+
+static int stasis_sub_cmp(void *obj, void *arg, int flags)
+{
+	struct mwi_stasis_subscription *mwi_stasis1 = obj;
+	struct mwi_stasis_subscription *mwi_stasis2 = arg;
+
+	return strcmp(mwi_stasis1->mailbox, mwi_stasis2->mailbox) ? 0 : CMP_MATCH;
+}
+
+static void mwi_subscription_destructor(void *obj)
+{
+	struct mwi_subscription *sub = obj;
+
+	ast_debug(3, "Destroying MWI subscription for endpoint %s\n", sub->id);
+	ao2_cleanup(sub->sip_sub);
+	ao2_cleanup(sub->stasis_subs);
+}
+
+static struct mwi_subscription *mwi_subscription_alloc(struct ast_sip_endpoint *endpoint,
+		enum ast_sip_subscription_role role, unsigned int is_solicited, pjsip_rx_data *rdata)
+{
+	struct mwi_subscription *sub;
+	const char *endpoint_id = ast_sorcery_object_get_id(endpoint);
+
+	sub = ao2_alloc(sizeof(*sub) + strlen(endpoint_id),
+			mwi_subscription_destructor);
+
+	if (!sub) {
+		return NULL;
+	}
+
+	/* Safe strcpy */
+	strcpy(sub->id, endpoint_id);
+	/* Unsolicited MWI doesn't actually result in a SIP subscription being
+	 * created. This is because a SIP subscription associates with a dialog.
+	 * Most devices expect unsolicited MWI NOTIFYs to appear out of dialog. If
+	 * they receive an in-dialog MWI NOTIFY (i.e. with a to-tag), then they
+	 * will reject the NOTIFY with a 481, thus resulting in message-waiting
+	 * state not being updated on the device
+	 */
+	if (is_solicited) {
+		sub->sip_sub = ast_sip_create_subscription(&mwi_handler,
+				role, endpoint, rdata);
+		if (!sub->sip_sub) {
+			ast_log(LOG_WARNING, "Unable to create MWI SIP subscription for endpoint %s\n", sub->id);
+			ao2_cleanup(sub);
+			return NULL;
+		}
+	}
+
+	sub->stasis_subs = ao2_container_alloc(STASIS_BUCKETS, stasis_sub_hash, stasis_sub_cmp);
+	if (!sub->stasis_subs) {
+		ao2_cleanup(sub);
+		return NULL;
+	}
+	sub->is_solicited = is_solicited;
+
+	ast_debug(3, "Created %s MWI subscription for endpoint %s\n", is_solicited ? "solicited" : "unsolicited", sub->id);
+
+	return sub;
+}
+
+static int mwi_sub_hash(const void *obj, int flags)
+{
+	const struct mwi_subscription *mwi_sub = obj;
+	
+	return ast_str_hash(mwi_sub->id);
+}
+
+static int mwi_sub_cmp(void *obj, void *arg, int flags)
+{
+	struct mwi_subscription *mwi_sub1 = obj;
+	struct mwi_subscription *mwi_sub2 = arg;
+
+	return strcmp(mwi_sub1->id, mwi_sub2->id) ? 0 : CMP_MATCH;
+}
+
+struct message_accumulator {
+	int old_msgs;
+	int new_msgs;
+	const char *reason;
+};
+
+static int get_message_count(void *obj, void *arg, int flags)
+{
+	RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
+	struct mwi_stasis_subscription *mwi_stasis = obj;
+	struct message_accumulator *counter = arg;
+	struct stasis_mwi_state *mwi_state;
+
+	msg = stasis_cache_get(stasis_mwi_topic_cached(), stasis_mwi_state_type(), mwi_stasis->mailbox);
+	if (!msg) {
+		return 0;
+	}
+
+	mwi_state = stasis_message_data(msg);
+	counter->old_msgs += mwi_state->old_msgs;
+	counter->new_msgs += mwi_state->new_msgs;
+	return 0;
+}
+
+struct unsolicited_mwi_data {
+	struct mwi_subscription *sub;
+	struct ast_sip_endpoint *endpoint;
+	pjsip_evsub_state state;
+	const char *reason;
+	const pjsip_media_type *mwi_type;
+	const pj_str_t *body_text;
+};
+
+static int send_unsolicited_mwi_notify_to_contact(void *obj, void *arg, int flags)
+{
+	struct unsolicited_mwi_data *mwi_data = arg;
+	struct mwi_subscription *sub = mwi_data->sub;
+	struct ast_sip_endpoint *endpoint = mwi_data->endpoint;
+	pjsip_evsub_state state = mwi_data->state;
+	const char *reason = mwi_data->reason;
+	const pjsip_media_type *mwi_type = mwi_data->mwi_type;
+	const pj_str_t *body_text = mwi_data->body_text;
+	struct ast_sip_contact *contact = obj;
+	const char *state_name;
+	pjsip_tx_data *tdata;
+	pjsip_msg_body *msg_body;
+	pjsip_sub_state_hdr *sub_state;
+	pjsip_event_hdr *event;
+	const pjsip_hdr *allow_events = pjsip_evsub_get_allow_events_hdr(NULL);
+
+	if (ast_sip_create_request("NOTIFY", NULL, endpoint, contact->uri, &tdata)) {
+		ast_log(LOG_WARNING, "Unable to create unsolicited NOTIFY request to endpoint %s URI %s\n", sub->id, contact->uri);
+		return 0;
+	}
+
+	switch (state) {
+	case PJSIP_EVSUB_STATE_ACTIVE:
+		state_name = "active";
+		break;
+	case PJSIP_EVSUB_STATE_TERMINATED:
+	default:
+		state_name = "terminated";
+		break;
+	}
+
+	sub_state = pjsip_sub_state_hdr_create(tdata->pool);
+	pj_cstr(&sub_state->sub_state, state_name);
+	if (reason) {
+		pj_cstr(&sub_state->reason_param, reason);
+	}
+	pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr *) sub_state);
+
+	event = pjsip_event_hdr_create(tdata->pool);
+	pj_cstr(&event->event_type, "message-summary");
+	pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr *) event);
+
+	pjsip_msg_add_hdr(tdata->msg, pjsip_hdr_shallow_clone(tdata->pool, allow_events));
+	msg_body = pjsip_msg_body_create(tdata->pool, &mwi_type->type, &mwi_type->subtype, body_text);
+	tdata->msg->body = msg_body;
+	ast_sip_send_request(tdata, NULL, endpoint);
+
+	return 0;
+}
+
+static void send_unsolicited_mwi_notify(struct mwi_subscription *sub, pjsip_evsub_state state, const char *reason,
+		const pjsip_media_type *mwi_type, const pj_str_t *body_text)
+{
+	RAII_VAR(struct ast_sip_endpoint *, endpoint, ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(),
+				"endpoint", sub->id), ao2_cleanup);
+	char *endpoint_aors;
+	char *aor_name;
+
+	if (!endpoint) {
+		ast_log(LOG_WARNING, "Unable to send unsolicited MWI to %s because endpoint does not exist\n",
+				sub->id);
+		return;
+	}
+	if (ast_strlen_zero(endpoint->aors)) {
+		ast_log(LOG_WARNING, "Unable to send unsolicited MWI to %s because the endpoint has no"
+				" configured AORs\n", sub->id);
+		return;
+	}
+
+	endpoint_aors = ast_strdupa(endpoint->aors);
+
+	while ((aor_name = strsep(&endpoint_aors, ","))) {
+		RAII_VAR(struct ast_sip_aor *, aor, ast_sip_location_retrieve_aor(aor_name), ao2_cleanup);
+		RAII_VAR(struct ao2_container *, contacts, NULL, ao2_cleanup);
+		struct unsolicited_mwi_data mwi_data = {
+			.sub = sub,
+			.endpoint = endpoint,
+			.state = state,
+			.reason = reason,
+			.mwi_type = mwi_type,
+			.body_text = body_text,
+		};
+
+		if (!aor) {
+			ast_log(LOG_WARNING, "Unable to locate AOR %s for unsolicited MWI\n", aor_name);
+			continue;
+		}
+
+		contacts = ast_sip_location_retrieve_aor_contacts(aor);
+		if (!contacts || (ao2_container_count(contacts) == 0)) {
+			ast_log(LOG_WARNING, "No contacts bound to AOR %s. Cannot send unsolicited MWI.\n", aor_name);
+			continue;
+		}
+
+		ao2_callback(contacts, OBJ_NODATA, send_unsolicited_mwi_notify_to_contact, &mwi_data);
+	}
+}
+
+static void send_mwi_notify(struct mwi_subscription *sub, pjsip_evsub_state state, const char *reason)
+{
+	const pj_str_t *reason_str_ptr = NULL;
+	static pjsip_media_type mwi_type = {
+		.type = { "application", 11 },
+		.subtype = { "simple-message-summary", 22 },
+	};
+	struct message_accumulator counter = {
+		.old_msgs = 0,
+		.new_msgs = 0,
+	};
+	RAII_VAR(struct ast_str *, body, ast_str_create(64), ast_free_ptr);
+	pjsip_tx_data *tdata;
+	pj_str_t reason_str;
+	pj_str_t pj_body;
+
+	ao2_callback(sub->stasis_subs, OBJ_NODATA, get_message_count, &counter);
+
+	if (reason) {
+		pj_cstr(&reason_str, reason);
+		reason_str_ptr = &reason_str;
+	}
+	ast_str_append(&body, 0, "Messages-Waiting: %s\r\n", counter.new_msgs ? "yes" : "no");
+	ast_str_append(&body, 0, "Voice-Message: %d/%d (0/0)\r\n", counter.new_msgs, counter.old_msgs);
+	pj_cstr(&pj_body, ast_str_buffer(body));
+
+	ast_debug(5, "Sending  %s MWI NOTIFY to endpoint %s, new messages: %d, old messages: %d\n",
+			sub->is_solicited ? "solicited" : "unsolicited", sub->id, counter.new_msgs,
+			counter.old_msgs);
+
+	if (sub->is_solicited) {
+		if (pjsip_mwi_notify(ast_sip_subscription_get_evsub(sub->sip_sub),
+				state,
+				NULL,
+				reason_str_ptr,
+				&mwi_type,
+				&pj_body,
+				&tdata) != PJ_SUCCESS) {
+			ast_log(LOG_WARNING, "Unable to create MWI NOTIFY request to %s.\n", sub->id);
+			return;
+		}
+		if (ast_sip_subscription_send_request(sub->sip_sub, tdata) != PJ_SUCCESS) {
+			ast_log(LOG_WARNING, "Unable to send MWI NOTIFY request to %s\n", sub->id);
+			return;
+		}
+	} else {
+		send_unsolicited_mwi_notify(sub, state, reason, &mwi_type, &pj_body);
+	}
+}
+
+static int unsubscribe_stasis(void *obj, void *arg, int flags)
+{
+	struct mwi_stasis_subscription *mwi_stasis = obj;
+	if (mwi_stasis->stasis_sub) {
+		ast_debug(3, "Removing stasis subscription to mailbox %s\n", mwi_stasis->mailbox);
+		mwi_stasis->stasis_sub = stasis_unsubscribe(mwi_stasis->stasis_sub);
+	}
+	return CMP_MATCH;
+}
+
+static void mwi_subscription_shutdown(struct ast_sip_subscription *sub)
+{
+	struct mwi_subscription *mwi_sub;
+	RAII_VAR(struct ast_datastore *, mwi_datastore,
+			ast_sip_subscription_get_datastore(sub, "MWI datastore"), ao2_cleanup);
+
+	if (!mwi_datastore) {
+		return;
+	}
+
+	mwi_sub = mwi_datastore->data;
+	ao2_callback(mwi_sub->stasis_subs, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, unsubscribe_stasis, NULL);
+}
+
+static struct ast_datastore_info mwi_ds_info = { };
+
+static int add_mwi_datastore(struct mwi_subscription *sub)
+{
+	RAII_VAR(struct ast_datastore *, mwi_datastore, NULL, ao2_cleanup);
+
+	mwi_datastore = ast_sip_subscription_alloc_datastore(&mwi_ds_info, "MWI datastore");
+	if (!mwi_datastore) {
+		return -1;
+	}
+	mwi_datastore->data = sub;
+
+	ast_sip_subscription_add_datastore(sub->sip_sub, mwi_datastore);
+	return 0;
+}
+
+static struct ast_sip_subscription *mwi_new_subscribe(struct ast_sip_endpoint *endpoint,
+		pjsip_rx_data *rdata)
+{
+	RAII_VAR(struct ast_sip_aor *, aor, NULL, ao2_cleanup);
+	/* It's not obvious here, but the reference(s) to this subscription,
+	 * once this function exits, is held by the stasis subscription(s)
+	 * created in mwi_stasis_subscription_alloc()
+	 */
+	RAII_VAR(struct mwi_subscription *, sub, NULL, ao2_cleanup);
+	pjsip_uri *ruri = rdata->msg_info.msg->line.req.uri;
+	pjsip_sip_uri *sip_ruri;
+	pjsip_evsub *evsub;
+	char aor_name[80];
+	char *mailboxes;
+	char *mailbox;
+
+	if (!PJSIP_URI_SCHEME_IS_SIP(ruri) && !PJSIP_URI_SCHEME_IS_SIPS(ruri)) {
+		ast_log(LOG_WARNING, "Attempt to SUBSCRIBE to a non-SIP URI\n");
+		return NULL;
+	}
+	sip_ruri = pjsip_uri_get_uri(ruri);
+	ast_copy_pj_str(aor_name, &sip_ruri->user, sizeof(aor_name));
+
+	aor = ast_sip_location_retrieve_aor(aor_name);
+	if (!aor) {
+		ast_log(LOG_WARNING, "Unable to locate aor %s. MWI subscription failed.\n", aor_name);
+		return NULL;
+	}
+
+	if (ast_strlen_zero(aor->mailboxes)) {
+		ast_log(LOG_WARNING, "AOR %s has no configured mailboxes. MWI subscription failed\n", aor_name);
+		return NULL;
+	}
+
+	sub = mwi_subscription_alloc(endpoint, AST_SIP_NOTIFIER, 1, rdata);
+	if (!sub) {
+		return NULL;
+	}
+
+	if (add_mwi_datastore(sub)) {
+		ast_log(LOG_WARNING, "Unable to allocate datastore on MWI subscription from %s\n", sub->id);
+		return NULL;
+	}
+
+	mailboxes = ast_strdupa(aor->mailboxes);
+	while ((mailbox = strsep(&mailboxes, ","))) {
+		RAII_VAR(struct mwi_stasis_subscription *, mwi_stasis_sub,
+				mwi_stasis_subscription_alloc(mailbox, sub), ao2_cleanup);
+		if (mwi_stasis_sub) {
+			ao2_link(sub->stasis_subs, mwi_stasis_sub);
+		}
+	}
+
+	evsub = ast_sip_subscription_get_evsub(sub->sip_sub);
+	pjsip_evsub_accept(evsub, rdata, 200, NULL);
+	send_mwi_notify(sub, PJSIP_EVSUB_STATE_ACTIVE, NULL);
+
+	return sub->sip_sub;
+}
+
+static void mwi_resubscribe(struct ast_sip_subscription *sub,
+		pjsip_rx_data *rdata, struct ast_sip_subscription_response_data *response_data)
+{
+	pjsip_tx_data *tdata;
+
+	pjsip_mwi_current_notify(ast_sip_subscription_get_evsub(sub), &tdata);
+	ast_sip_subscription_send_request(sub, tdata);
+}
+
+static void mwi_subscription_timeout(struct ast_sip_subscription *sub)
+{
+	struct mwi_subscription *mwi_sub;
+	RAII_VAR(struct ast_datastore *, mwi_datastore,
+			ast_sip_subscription_get_datastore(sub, "MWI datastore"), ao2_cleanup);
+
+	if (!mwi_datastore) {
+		return;
+	}
+
+
+	mwi_sub = mwi_datastore->data;
+
+	ast_log(LOG_NOTICE, "MWI subscription for %s has timed out.\n", mwi_sub->id);
+
+	send_mwi_notify(mwi_sub, PJSIP_EVSUB_STATE_TERMINATED, "timeout");
+}
+
+static void mwi_subscription_terminated(struct ast_sip_subscription *sub, pjsip_rx_data *rdata)
+{
+	struct mwi_subscription *mwi_sub;
+	RAII_VAR(struct ast_datastore *, mwi_datastore,
+			ast_sip_subscription_get_datastore(sub, "MWI datastore"), ao2_cleanup);
+
+	if (!mwi_datastore) {
+		return;
+	}
+
+	mwi_sub = mwi_datastore->data;
+
+	ast_log(LOG_NOTICE, "MWI subscription for %s has been terminated\n", mwi_sub->id);
+
+	send_mwi_notify(mwi_sub, PJSIP_EVSUB_STATE_TERMINATED, NULL);
+}
+
+static void mwi_notify_response(struct ast_sip_subscription *sub, pjsip_rx_data *rdata)
+{
+	/* We don't really care about NOTIFY responses for the moment */
+}
+
+static void mwi_notify_request(struct ast_sip_subscription *sub, pjsip_rx_data *rdata,
+		struct ast_sip_subscription_response_data *response_data)
+{
+	ast_log(LOG_WARNING, "Received an MWI NOTIFY request? This should not happen\n");
+}
+
+static int mwi_refresh_subscription(struct ast_sip_subscription *sub)
+{
+	ast_log(LOG_WARNING, "Being told to refresh an MWI subscription? This should not happen\n");
+	return 0;
+}
+
+static int serialized_notify(void *userdata)
+{
+	struct mwi_subscription *mwi_sub = userdata;
+
+	send_mwi_notify(mwi_sub, PJSIP_EVSUB_STATE_ACTIVE, NULL);
+	ao2_ref(mwi_sub, -1);
+	return 0;
+}
+
+static int serialized_cleanup(void *userdata)
+{
+	struct mwi_subscription *mwi_sub = userdata;
+
+	/* This is getting rid of the reference that was added
+	 * just before this serialized task was pushed.
+	 */
+	ao2_cleanup(mwi_sub);
+	/* This is getting rid of the reference held by the
+	 * stasis subscription
+	 */
+	ao2_cleanup(mwi_sub);
+	return 0;
+}
+
+static void mwi_stasis_cb(void *userdata, struct stasis_subscription *sub,
+		struct stasis_topic *topic, struct stasis_message *msg)
+{
+	struct mwi_subscription *mwi_sub = userdata;
+
+	if (stasis_subscription_final_message(sub, msg)) {
+		ao2_ref(mwi_sub, +1);
+		ast_sip_push_task(NULL, serialized_cleanup, mwi_sub);
+		return;
+	}
+
+	if (stasis_mwi_state_type() == stasis_message_type(msg)) {
+		struct ast_taskprocessor *serializer = mwi_sub->is_solicited ? ast_sip_subscription_get_serializer(mwi_sub->sip_sub) : NULL;
+		ao2_ref(mwi_sub, +1);
+		ast_sip_push_task(serializer, serialized_notify, mwi_sub);
+	}
+}
+
+static int create_mwi_subscriptions_for_endpoint(void *obj, void *arg, int flags)
+{
+	RAII_VAR(struct mwi_subscription *, aggregate_sub, NULL, ao2_cleanup);
+	struct ast_sip_endpoint *endpoint = obj;
+	struct ao2_container *mwi_subscriptions = arg;
+	char *mailboxes;
+	char *mailbox;
+
+	if (ast_strlen_zero(endpoint->mailboxes)) {
+		return 0;
+	}
+
+	if (endpoint->aggregate_mwi) {
+		aggregate_sub = mwi_subscription_alloc(endpoint, AST_SIP_NOTIFIER, 0, NULL);
+		if (!aggregate_sub) {
+			return 0;
+		}
+	}
+
+	mailboxes = ast_strdupa(endpoint->mailboxes);
+	while ((mailbox = strsep(&mailboxes, ","))) {
+		struct mwi_subscription *sub = aggregate_sub ?:
+			mwi_subscription_alloc(endpoint, AST_SIP_SUBSCRIBER, 0, NULL);
+		RAII_VAR(struct mwi_stasis_subscription *, mwi_stasis_sub,
+				mwi_stasis_subscription_alloc(mailbox, sub), ao2_cleanup);
+		if (mwi_stasis_sub) {
+			ao2_link(sub->stasis_subs, mwi_stasis_sub);
+		}
+		if (!aggregate_sub) {
+			ao2_link(mwi_subscriptions, sub);
+			ao2_cleanup(sub);
+		}
+	}
+	ao2_link(mwi_subscriptions, aggregate_sub);
+	return 0;
+}
+
+static int unsubscribe(void *obj, void *arg, int flags)
+{
+	struct mwi_subscription *mwi_sub = obj;
+
+	ao2_callback(mwi_sub->stasis_subs, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, unsubscribe_stasis, NULL);
+	return CMP_MATCH;
+}
+
+static void create_mwi_subscriptions(void)
+{
+	struct ao2_container *mwi_subscriptions = ao2_container_alloc(MWI_BUCKETS, mwi_sub_hash, mwi_sub_cmp);
+	RAII_VAR(struct ao2_container *, old_mwi_subscriptions, ao2_global_obj_ref(unsolicited_mwi), ao2_cleanup);
+	RAII_VAR(struct ao2_container *, endpoints, ast_sorcery_retrieve_by_fields(
+				ast_sip_get_sorcery(), "endpoint", AST_RETRIEVE_FLAG_MULTIPLE | AST_RETRIEVE_FLAG_ALL, NULL),
+			ao2_cleanup);
+
+	if (!mwi_subscriptions) {
+		return;
+	}
+
+	/* We remove all the old stasis subscriptions first before applying the new configuration. This
+	 * prevents a situation where there might be multiple overlapping stasis subscriptions for an
+	 * endpoint for mailboxes. Though there may be mailbox changes during the gap between unsubscribing
+	 * and resubscribing, up-to-date mailbox state will be sent out to the endpoint when the
+	 * new stasis subscription is established
+	 */
+	if (old_mwi_subscriptions) {
+		ao2_callback(old_mwi_subscriptions, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, unsubscribe, NULL);
+	}
+	ao2_callback(endpoints, OBJ_NODATA, create_mwi_subscriptions_for_endpoint, mwi_subscriptions);
+	ao2_global_obj_replace_unref(unsolicited_mwi, mwi_subscriptions);
+}
+
+static int reload(void)
+{
+	create_mwi_subscriptions();
+	return 0;
+}
+
+static int load_module(void)
+{
+	if (ast_sip_register_subscription_handler(&mwi_handler)) {
+		return AST_MODULE_LOAD_DECLINE;
+	}
+	create_mwi_subscriptions();
+	return AST_MODULE_LOAD_SUCCESS;
+}
+
+static int unload_module(void)
+{
+	RAII_VAR(struct ao2_container *, mwi_subscriptions, ao2_global_obj_ref(unsolicited_mwi), ao2_cleanup);
+	if (mwi_subscriptions) {
+		ao2_callback(mwi_subscriptions, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, unsubscribe, NULL);
+		ao2_global_obj_release(unsolicited_mwi);
+	}
+	ast_sip_unregister_subscription_handler(&mwi_handler);
+	return 0;
+}
+
+AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "SIP MWI resource",
+		.load = load_module,
+		.unload = unload_module,
+		.reload = reload,
+		.load_pri = AST_MODPRI_CHANNEL_DEPEND,
+);
diff --git a/res/res_sip_nat.c b/res/res_sip_nat.c
new file mode 100644
index 0000000000000000000000000000000000000000..6c924af68e62170c39878370cc07d6a09087a650
--- /dev/null
+++ b/res/res_sip_nat.c
@@ -0,0 +1,235 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2013, Digium, Inc.
+ *
+ * Joshua Colp <jcolp@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*** MODULEINFO
+	<support_level>core</support_level>
+ ***/
+
+#include "asterisk.h"
+
+#include <pjsip.h>
+#include <pjsip_ua.h>
+
+#include "asterisk/res_sip.h"
+#include "asterisk/module.h"
+#include "asterisk/acl.h"
+
+static pj_bool_t nat_on_rx_request(pjsip_rx_data *rdata)
+{
+	RAII_VAR(struct ast_sip_endpoint *, endpoint, ast_pjsip_rdata_get_endpoint(rdata), ao2_cleanup);
+	pjsip_contact_hdr *contact;
+
+	if (!endpoint) {
+		return PJ_FALSE;
+	}
+
+	if (endpoint->rewrite_contact && (contact = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_CONTACT, NULL)) &&
+		(PJSIP_URI_SCHEME_IS_SIP(contact->uri) || PJSIP_URI_SCHEME_IS_SIPS(contact->uri))) {
+		pjsip_sip_uri *uri = pjsip_uri_get_uri(contact->uri);
+
+		pj_cstr(&uri->host, rdata->pkt_info.src_name);
+		uri->port = rdata->pkt_info.src_port;
+	}
+
+	if (endpoint->force_rport) {
+		rdata->msg_info.via->rport_param = 0;
+	}
+
+	return PJ_FALSE;
+}
+
+/*! \brief Structure which contains information about a transport */
+struct request_transport_details {
+	/*! \brief Type of transport */
+	enum ast_sip_transport_type type;
+	/*! \brief Potential pointer to the transport itself, if UDP */
+	pjsip_transport *transport;
+	/*! \brief Potential pointer to the transport factory itself, if TCP/TLS */
+	pjsip_tpfactory *factory;
+	/*! \brief Local address for transport */
+	pj_str_t local_address;
+	/*! \brief Local port for transport */
+	int local_port;
+};
+
+/*! \brief Callback function for finding the transport the request is going out on */
+static int find_transport_in_use(void *obj, void *arg, int flags)
+{
+	struct ast_sip_transport *transport = obj;
+	struct request_transport_details *details = arg;
+
+	/* If an explicit transport or factory matches then this is what is in use, if we are unavailable
+	 * to compare based on that we make sure that the type is the same and the source IP address/port are the same
+	 */
+	if ((details->transport && details->transport == transport->state->transport) ||
+		(details->factory && details->factory == transport->state->factory) ||
+		((details->type == transport->type) && (transport->state->factory) &&
+			!pj_strcmp(&transport->state->factory->addr_name.host, &details->local_address) &&
+			transport->state->factory->addr_name.port == details->local_port)) {
+		return CMP_MATCH | CMP_STOP;
+	}
+
+	return 0;
+}
+
+/*! \brief Helper function which returns the SIP URI of a Contact header */
+static pjsip_sip_uri *nat_get_contact_sip_uri(pjsip_tx_data *tdata)
+{
+	pjsip_contact_hdr *contact = pjsip_msg_find_hdr(tdata->msg, PJSIP_H_CONTACT, NULL);
+
+	if (!contact || (!PJSIP_URI_SCHEME_IS_SIP(contact->uri) && !PJSIP_URI_SCHEME_IS_SIPS(contact->uri))) {
+		return NULL;
+	}
+
+	return pjsip_uri_get_uri(contact->uri);
+}
+
+/*! \brief Structure which contains hook details */
+struct nat_hook_details {
+	/*! \brief Outgoing message itself */
+	pjsip_tx_data *tdata;
+	/*! \brief Chosen transport */
+	struct ast_sip_transport *transport;
+};
+
+/*! \brief Callback function for invoking hooks */
+static int nat_invoke_hook(void *obj, void *arg, int flags)
+{
+	struct ast_sip_nat_hook *hook = obj;
+	struct nat_hook_details *details = arg;
+
+	if (hook->outgoing_external_message) {
+		hook->outgoing_external_message(details->tdata, details->transport);
+	}
+
+	return 0;
+}
+
+static pj_status_t nat_on_tx_message(pjsip_tx_data *tdata)
+{
+	RAII_VAR(struct ao2_container *, transports, NULL, ao2_cleanup);
+	RAII_VAR(struct ast_sip_transport *, transport, NULL, ao2_cleanup);
+	struct request_transport_details details = { 0, };
+	pjsip_via_hdr *via = NULL;
+	struct ast_sockaddr addr = { { 0, } };
+	pjsip_sip_uri *uri = NULL;
+	RAII_VAR(struct ao2_container *, hooks, NULL, ao2_cleanup);
+
+	/* If a transport selector is in use we know the transport or factory, so explicitly find it */
+	if (tdata->tp_sel.type == PJSIP_TPSELECTOR_TRANSPORT) {
+		details.transport = tdata->tp_sel.u.transport;
+	} else if (tdata->tp_sel.type == PJSIP_TPSELECTOR_LISTENER) {
+		details.factory = tdata->tp_sel.u.listener;
+	} else if (tdata->tp_info.transport->key.type == PJSIP_TRANSPORT_UDP || tdata->tp_info.transport->key.type == PJSIP_TRANSPORT_UDP6) {
+		/* Connectionless uses the same transport for all requests */
+		details.type = AST_SIP_TRANSPORT_UDP;
+		details.transport = tdata->tp_info.transport;
+	} else {
+		if (tdata->tp_info.transport->key.type == PJSIP_TRANSPORT_TCP) {
+			details.type = AST_SIP_TRANSPORT_TCP;
+		} else if (tdata->tp_info.transport->key.type == PJSIP_TRANSPORT_TLS) {
+			details.type = AST_SIP_TRANSPORT_TLS;
+		} else {
+			/* Unknown transport type, we can't map and thus can't apply NAT changes */
+			return PJ_SUCCESS;
+		}
+
+		if ((uri = nat_get_contact_sip_uri(tdata))) {
+			details.local_address = uri->host;
+			details.local_port = uri->port;
+		} else if ((tdata->msg->type == PJSIP_REQUEST_MSG) &&
+			(via = pjsip_msg_find_hdr(tdata->msg, PJSIP_H_VIA, NULL))) {
+			details.local_address = via->sent_by.host;
+			details.local_port = via->sent_by.port;
+		} else {
+			return PJ_SUCCESS;
+		}
+
+		if (!details.local_port) {
+			details.local_port = (details.type == AST_SIP_TRANSPORT_TLS) ? 5061 : 5060;
+		}
+	}
+
+	if (!(transports = ast_sorcery_retrieve_by_fields(ast_sip_get_sorcery(), "transport", AST_RETRIEVE_FLAG_MULTIPLE | AST_RETRIEVE_FLAG_ALL, NULL)) ||
+		!(transport = ao2_callback(transports, 0, find_transport_in_use, &details)) || !transport->localnet ||
+		ast_sockaddr_isnull(&transport->external_address)) {
+		return PJ_SUCCESS;
+	}
+
+	ast_sockaddr_parse(&addr, tdata->tp_info.dst_name, PARSE_PORT_FORBID);
+	ast_sockaddr_set_port(&addr, tdata->tp_info.dst_port);
+
+	/* See if where we are sending this request is local or not, and if not that we can get a Contact URI to modify */
+	if (ast_apply_ha(transport->localnet, &addr) != AST_SENSE_ALLOW) {
+		return PJ_SUCCESS;
+	}
+
+	/* Update the contact header with the external address */
+	if (uri || (uri = nat_get_contact_sip_uri(tdata))) {
+		pj_strdup2(tdata->pool, &uri->host, ast_sockaddr_stringify_host(&transport->external_address));
+		if (transport->external_signaling_port) {
+			uri->port = transport->external_signaling_port;
+		}
+	}
+
+	/* Update the via header if relevant */
+	if ((tdata->msg->type == PJSIP_REQUEST_MSG) && (via || (via = pjsip_msg_find_hdr(tdata->msg, PJSIP_H_VIA, NULL)))) {
+		pj_strdup2(tdata->pool, &via->sent_by.host, ast_sockaddr_stringify_host(&transport->external_address));
+		if (transport->external_signaling_port) {
+			via->sent_by.port = transport->external_signaling_port;
+		}
+	}
+
+	/* Invoke any additional hooks that may be registered */
+	if ((hooks = ast_sorcery_retrieve_by_fields(ast_sip_get_sorcery(), "nat_hook", AST_RETRIEVE_FLAG_MULTIPLE | AST_RETRIEVE_FLAG_ALL, NULL))) {
+		struct nat_hook_details hook_details = {
+			.tdata = tdata,
+			.transport = transport,
+		};
+		ao2_callback(hooks, 0, nat_invoke_hook, &hook_details);
+	}
+
+	return PJ_SUCCESS;
+}
+
+static pjsip_module nat_module = {
+	.name = { "NAT", 3 },
+	.id = -1,
+	.priority = PJSIP_MOD_PRIORITY_TSX_LAYER - 2,
+	.on_rx_request = nat_on_rx_request,
+	.on_tx_request = nat_on_tx_message,
+	.on_tx_response = nat_on_tx_message,
+};
+
+static int load_module(void)
+{
+	ast_sip_register_service(&nat_module);
+	return AST_MODULE_LOAD_SUCCESS;
+}
+
+static int unload_module(void)
+{
+	ast_sip_unregister_service(&nat_module);
+	return 0;
+}
+
+AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "SIP NAT Support",
+		.load = load_module,
+		.unload = unload_module,
+		.load_pri = AST_MODPRI_APP_DEPEND,
+	       );
diff --git a/res/res_sip_outbound_authenticator_digest.c b/res/res_sip_outbound_authenticator_digest.c
new file mode 100644
index 0000000000000000000000000000000000000000..180c05e277a1542c1e42923eaf8355aff0b1f700
--- /dev/null
+++ b/res/res_sip_outbound_authenticator_digest.c
@@ -0,0 +1,110 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2013, Digium, Inc.
+ *
+ * Mark Michelson <mmichelson@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+#include "asterisk.h"
+
+#include <pjsip.h>
+
+#include "asterisk/res_sip.h"
+#include "asterisk/logger.h"
+#include "asterisk/module.h"
+#include "asterisk/strings.h"
+
+static int set_outbound_authentication_credentials(pjsip_auth_clt_sess *auth_sess, const char **auth_strs, size_t num_auths)
+{
+	struct ast_sip_auth **auths = ast_alloca(num_auths * sizeof(*auths));
+	pjsip_cred_info *auth_creds = ast_alloca(num_auths * sizeof(*auth_creds));
+	int res = 0;
+	int i;
+
+	if (ast_sip_retrieve_auths(auth_strs, num_auths, auths)) {
+		res = -1;
+		goto cleanup;
+	}
+
+	for (i = 0; i < num_auths; ++i) {
+		pj_cstr(&auth_creds[i].realm, auths[i]->realm);
+		pj_cstr(&auth_creds[i].username, auths[i]->auth_user);
+		pj_cstr(&auth_creds[i].scheme, "digest");
+		switch (auths[i]->type) {
+		case AST_SIP_AUTH_TYPE_USER_PASS:
+			pj_cstr(&auth_creds[i].data, auths[i]->auth_pass);
+			auth_creds[i].data_type = PJSIP_CRED_DATA_PLAIN_PASSWD;
+			break;
+		case AST_SIP_AUTH_TYPE_MD5:
+			pj_cstr(&auth_creds[i].data, auths[i]->md5_creds);
+			auth_creds[i].data_type = PJSIP_CRED_DATA_DIGEST;
+			break;
+		}
+	}
+
+	pjsip_auth_clt_set_credentials(auth_sess, num_auths, auth_creds);
+
+cleanup:
+	ast_sip_cleanup_auths(auths, num_auths);
+	return res;
+}
+
+static int digest_create_request_with_auth(const char **auths, size_t num_auths, pjsip_rx_data *challenge,
+		pjsip_transaction *tsx, pjsip_tx_data **new_request)
+{
+	pjsip_auth_clt_sess auth_sess;
+
+	if (pjsip_auth_clt_init(&auth_sess, ast_sip_get_pjsip_endpoint(),
+				tsx->pool, 0) != PJ_SUCCESS) {
+		ast_log(LOG_WARNING, "Failed to initialize client authentication session\n");
+		return -1;
+	}
+
+	if (set_outbound_authentication_credentials(&auth_sess, auths, num_auths)) {
+		ast_log(LOG_WARNING, "Failed to set authentication credentials\n");
+		return -1;
+	}
+
+	if (pjsip_auth_clt_reinit_req(&auth_sess, challenge,
+				tsx->last_tx, new_request) != PJ_SUCCESS) {
+		ast_log(LOG_WARNING, "Failed to create new request with authentication credentials\n");
+		return -1;
+	}
+
+	return 0;
+}
+
+static struct ast_sip_outbound_authenticator digest_authenticator = {
+	.create_request_with_auth = digest_create_request_with_auth,
+};
+
+static int load_module(void)
+{
+	if (ast_sip_register_outbound_authenticator(&digest_authenticator)) {
+		return AST_MODULE_LOAD_DECLINE;
+	}
+	return AST_MODULE_LOAD_SUCCESS;
+}
+
+static int unload_module(void)
+{
+	ast_sip_unregister_outbound_authenticator(&digest_authenticator);
+	return 0;
+}
+
+AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "SIP authentication resource",
+		.load = load_module,
+		.unload = unload_module,
+		.load_pri = AST_MODPRI_CHANNEL_DEPEND,
+);
diff --git a/res/res_sip_outbound_registration.c b/res/res_sip_outbound_registration.c
new file mode 100644
index 0000000000000000000000000000000000000000..8f1108df55debd70e48ea43d5ecb6f4b39268a79
--- /dev/null
+++ b/res/res_sip_outbound_registration.c
@@ -0,0 +1,708 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2013, Digium, Inc.
+ *
+ * Joshua Colp <jcolp@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*** MODULEINFO
+	<support_level>core</support_level>
+ ***/
+
+#include "asterisk.h"
+
+#include <pjsip.h>
+#include <pjsip_ua.h>
+
+#include "asterisk/res_sip.h"
+#include "asterisk/module.h"
+#include "asterisk/taskprocessor.h"
+
+/*! \brief Amount of buffer time (in seconds) before expiration that we re-register at */
+#define REREGISTER_BUFFER_TIME 10
+
+/*! \brief Various states that an outbound registration may be in */
+enum sip_outbound_registration_status {
+	/*! \brief Currently unregistered */
+	SIP_REGISTRATION_UNREGISTERED = 0,
+	/*! \brief Registered, yay! */
+	SIP_REGISTRATION_REGISTERED,
+	/*! \brief Registration was rejected, but response was temporal */
+	SIP_REGISTRATION_REJECTED_TEMPORARY,
+	/*! \brief Registration was rejected, permanently */
+	SIP_REGISTRATION_REJECTED_PERMANENT,
+	/*! \brief Registration has been stopped */
+	SIP_REGISTRATION_STOPPED,
+};
+
+/*! \brief Outbound registration client state information (persists for lifetime of regc) */
+struct sip_outbound_registration_client_state {
+	/*! \brief Current status of this registration */
+	enum sip_outbound_registration_status status;
+	/*! \brief Outbound registration client */
+	pjsip_regc *client;
+	/*! \brief Timer entry for retrying on temporal responses */
+	pj_timer_entry timer;
+	/*! \brief Current number of retries */
+	unsigned int retries;
+	/*! \brief Maximum number of retries permitted */
+	unsigned int max_retries;
+	/*! \brief Interval at which retries should occur for temporal responses */
+	unsigned int retry_interval;
+	/*! \brief Treat authentication challenges that we cannot handle as permanent failures */
+	unsigned int auth_rejection_permanent;
+	/*! \brief Serializer for stuff and things */
+	struct ast_taskprocessor *serializer;
+	/*! \brief Configured authentication credentials */
+	const char **sip_outbound_auths;
+	/*! \brief Number of configured auths */
+	size_t num_outbound_auths;
+	/*! \brief Registration should be destroyed after completion of transaction */
+	unsigned int destroy:1;
+};
+
+/*! \brief Outbound registration state information (persists for lifetime that registration should exist) */
+struct sip_outbound_registration_state {
+	/*! \brief Client state information */
+	struct sip_outbound_registration_client_state *client_state;
+};
+
+/*! \brief Outbound registration information */
+struct sip_outbound_registration {
+	/*! \brief Sorcery object details */
+	SORCERY_OBJECT(details);
+	/*! \brief Stringfields */
+	AST_DECLARE_STRING_FIELDS(
+		/*! \brief URI for the registrar */
+		AST_STRING_FIELD(server_uri);
+		/*! \brief URI for the AOR */
+		AST_STRING_FIELD(client_uri);
+		/*! \brief Optional user for contact header */
+		AST_STRING_FIELD(contact_user);
+		/*! \brief Explicit transport to use for registration */
+		AST_STRING_FIELD(transport);
+		/*! \brief Outbound proxy to use */
+		AST_STRING_FIELD(outbound_proxy);
+	);
+	/*! \brief Requested expiration time */
+	unsigned int expiration;
+	/*! \brief Interval at which retries should occur for temporal responses */
+	unsigned int retry_interval;
+	/*! \brief Treat authentication challenges that we cannot handle as permanent failures */
+	unsigned int auth_rejection_permanent;
+	/*! \brief Maximum number of retries permitted */
+	unsigned int max_retries;
+	/*! \brief Outbound registration state */
+	struct sip_outbound_registration_state *state;
+	/*! \brief Configured authentication credentials */
+	const char **sip_outbound_auths;
+	/*! \brief Number of configured auths */
+	size_t num_outbound_auths;
+};
+
+static void destroy_auths(const char **auths, size_t num_auths)
+{
+	int i;
+	for (i = 0; i < num_auths; ++i) {
+		ast_free((char *) auths[i]);
+	}
+	ast_free(auths);
+}
+
+/*! \brief Helper function which cancels the timer on a client */
+static void cancel_registration(struct sip_outbound_registration_client_state *client_state)
+{
+	if (pj_timer_heap_cancel(pjsip_endpt_get_timer_heap(ast_sip_get_pjsip_endpoint()), &client_state->timer)) {
+		/* The timer was successfully cancelled, drop the refcount of client_state */
+		ao2_ref(client_state, -1);
+	}
+}
+
+/*! \brief Callback function for registering */
+static int handle_client_registration(void *data)
+{
+	RAII_VAR(struct sip_outbound_registration_client_state *, client_state, data, ao2_cleanup);
+	pjsip_tx_data *tdata;
+
+	cancel_registration(client_state);
+
+	if ((client_state->status == SIP_REGISTRATION_STOPPED) ||
+		(pjsip_regc_register(client_state->client, PJ_FALSE, &tdata) != PJ_SUCCESS)) {
+		return 0;
+	}
+
+	/* Due to the registration the callback may now get called, so bump the ref count */
+	ao2_ref(client_state, +1);
+	if (pjsip_regc_send(client_state->client, tdata) != PJ_SUCCESS) {
+		ao2_ref(client_state, -1);
+		pjsip_tx_data_dec_ref(tdata);
+	}
+
+	return 0;
+}
+
+/*! \brief Timer callback function, used just for registrations */
+static void sip_outbound_registration_timer_cb(pj_timer_heap_t *timer_heap, struct pj_timer_entry *entry)
+{
+	RAII_VAR(struct sip_outbound_registration_client_state *, client_state, entry->user_data, ao2_cleanup);
+
+	ao2_ref(client_state, +1);
+	if (ast_sip_push_task(client_state->serializer, handle_client_registration, client_state)) {
+		ast_log(LOG_WARNING, "Failed to pass outbound registration to threadpool\n");
+		ao2_ref(client_state, -1);
+	}
+
+	entry->id = 0;
+}
+
+/*! \brief Helper function which sets up the timer to re-register in a specific amount of time */
+static void schedule_registration(struct sip_outbound_registration_client_state *client_state, unsigned int seconds)
+{
+	pj_time_val delay = { .sec = seconds, };
+
+	cancel_registration(client_state);
+
+	ao2_ref(client_state, +1);
+	if (pjsip_endpt_schedule_timer(ast_sip_get_pjsip_endpoint(), &client_state->timer, &delay) != PJ_SUCCESS) {
+		ast_log(LOG_WARNING, "Failed to pass timed registration to scheduler\n");
+		ao2_ref(client_state, -1);
+	}
+}
+
+/*! \brief Callback function for unregistering (potentially) and destroying state */
+static int handle_client_state_destruction(void *data)
+{
+	RAII_VAR(struct sip_outbound_registration_client_state *, client_state, data, ao2_cleanup);
+	pjsip_regc_info info;
+
+	cancel_registration(client_state);
+
+	pjsip_regc_get_info(client_state->client, &info);
+
+	if (info.is_busy == PJ_TRUE) {
+		/* If a client transaction is in progress we defer until it is complete */
+		client_state->destroy = 1;
+		return 0;
+	}
+
+	if (client_state->status != SIP_REGISTRATION_UNREGISTERED && client_state->status != SIP_REGISTRATION_REJECTED_PERMANENT) {
+		pjsip_tx_data *tdata;
+
+		if (pjsip_regc_unregister(client_state->client, &tdata) == PJ_SUCCESS) {
+			pjsip_regc_send(client_state->client, tdata);
+		}
+	}
+
+	pjsip_regc_destroy(client_state->client);
+
+	client_state->status = SIP_REGISTRATION_STOPPED;
+	destroy_auths(client_state->sip_outbound_auths, client_state->num_outbound_auths);
+
+	return 0;
+}
+
+/*! \brief Structure for registration response */
+struct registration_response {
+	/*! \brief Response code for the registration attempt */
+	int code;
+	/*! \brief Expiration time for registration */
+	int expiration;
+	/*! \brief Retry-After value */
+	int retry_after;
+	/*! \brief Outbound registration client state */
+	struct sip_outbound_registration_client_state *client_state;
+	/*! \brief The response message */
+	pjsip_rx_data *rdata;
+	/*! \brief The response transaction */
+	pjsip_transaction *tsx;
+};
+
+/*! \brief Registration response structure destructor */
+static void registration_response_destroy(void *obj)
+{
+	struct registration_response *response = obj;
+
+	pjsip_rx_data_free_cloned(response->rdata);
+	ao2_cleanup(response->client_state);
+}
+
+/* \brief Helper funtion which determines if a response code is temporal or not */
+static int sip_outbound_registration_is_temporal(unsigned int code,
+		struct sip_outbound_registration_client_state *client_state)
+{
+	/* Shamelessly taken from pjsua */
+	if (code == PJSIP_SC_REQUEST_TIMEOUT ||
+		code == PJSIP_SC_INTERNAL_SERVER_ERROR ||
+		code == PJSIP_SC_BAD_GATEWAY ||
+		code == PJSIP_SC_SERVICE_UNAVAILABLE ||
+		code == PJSIP_SC_SERVER_TIMEOUT ||
+		((code == PJSIP_SC_UNAUTHORIZED ||
+		  code == PJSIP_SC_PROXY_AUTHENTICATION_REQUIRED) &&
+		 !client_state->auth_rejection_permanent) ||
+		PJSIP_IS_STATUS_IN_CLASS(code, 600)) {
+		return 1;
+	} else {
+		return 0;
+	}
+}
+
+/*! \brief Callback function for handling a response to a registration attempt */
+static int handle_registration_response(void *data)
+{
+	RAII_VAR(struct registration_response *, response, data, ao2_cleanup);
+	pjsip_regc_info info;
+	char server_uri[PJSIP_MAX_URL_SIZE], client_uri[PJSIP_MAX_URL_SIZE];
+
+	if (response->client_state->status == SIP_REGISTRATION_STOPPED) {
+		return 0;
+	}
+
+	pjsip_regc_get_info(response->client_state->client, &info);
+	ast_copy_pj_str(server_uri, &info.server_uri, sizeof(server_uri));
+	ast_copy_pj_str(client_uri, &info.client_uri, sizeof(client_uri));
+
+	if (response->code == 401 || response->code == 407) {
+		pjsip_tx_data *tdata;
+		if (!ast_sip_create_request_with_auth(response->client_state->sip_outbound_auths, response->client_state->num_outbound_auths,
+				response->rdata, response->tsx, &tdata)) {
+			pjsip_regc_send(response->client_state->client, tdata);
+			return 0;
+		}
+		/* Otherwise, fall through so the failure is processed appropriately */
+	}
+
+	if (PJSIP_IS_STATUS_IN_CLASS(response->code, 200)) {
+		/* If the registration went fine simply reschedule registration for the future */
+		response->client_state->status = SIP_REGISTRATION_REGISTERED;
+		response->client_state->retries = 0;
+		schedule_registration(response->client_state, response->expiration - REREGISTER_BUFFER_TIME);
+	} else if (response->retry_after) {
+		/* If we have been instructed to retry after a period of time, schedule it as such */
+		response->client_state->status = SIP_REGISTRATION_REJECTED_TEMPORARY;
+		schedule_registration(response->client_state, response->retry_after);
+		ast_log(LOG_WARNING, "Temporal response '%d' received from '%s' on registration attempt to '%s', instructed to retry in '%d'\n",
+			response->code, server_uri, client_uri, response->retry_after);
+	} else if (response->client_state->retry_interval && sip_outbound_registration_is_temporal(response->code, response->client_state)) {
+		if (response->client_state->retries == response->client_state->max_retries) {
+			/* If we received enough temporal responses to exceed our maximum give up permanently */
+			response->client_state->status = SIP_REGISTRATION_REJECTED_PERMANENT;
+			ast_log(LOG_WARNING, "Maximum retries reached when attempting outbound registration to '%s' with client '%s', stopping registration attempt\n",
+				server_uri, client_uri);
+		} else {
+			/* On the other hand if we can still try some more do so */
+			response->client_state->status = SIP_REGISTRATION_REJECTED_TEMPORARY;
+			response->client_state->retries++;
+			schedule_registration(response->client_state, response->client_state->retry_interval);
+			ast_log(LOG_WARNING, "Temporal response '%d' received from '%s' on registration attempt to '%s', retrying in '%d' seconds\n",
+				response->code, server_uri, client_uri, response->client_state->retry_interval);
+		}
+	} else {
+		/* Finally if there's no hope of registering give up */
+		response->client_state->status = SIP_REGISTRATION_REJECTED_PERMANENT;
+		ast_log(LOG_WARNING, "Fatal response '%d' received from '%s' on registration attempt to '%s', stopping outbound registration\n",
+			response->code, server_uri, client_uri);
+	}
+
+	/* If deferred destruction is in use see if we need to destroy now */
+	if (response->client_state->destroy) {
+		handle_client_state_destruction(response->client_state);
+	}
+
+	return 0;
+}
+
+/*! \brief Callback function for outbound registration client */
+static void sip_outbound_registration_response_cb(struct pjsip_regc_cbparam *param)
+{
+	RAII_VAR(struct sip_outbound_registration_client_state *, client_state, param->token, ao2_cleanup);
+	struct registration_response *response = ao2_alloc(sizeof(*response), registration_response_destroy);
+	struct pjsip_retry_after_hdr *retry_after = pjsip_msg_find_hdr(param->rdata->msg_info.msg, PJSIP_H_RETRY_AFTER, NULL);
+
+	response->code = param->code;
+	response->expiration = param->expiration;
+	response->retry_after = retry_after ? retry_after->ivalue : 0;
+	response->client_state = client_state;
+	response->tsx = pjsip_rdata_get_tsx(param->rdata);
+	pjsip_rx_data_clone(param->rdata, 0, &response->rdata);
+	ao2_ref(response->client_state, +1);
+
+	if (ast_sip_push_task(client_state->serializer, handle_registration_response, response)) {
+		ast_log(LOG_WARNING, "Failed to pass incoming registration response to threadpool\n");
+		ao2_cleanup(response);
+	}
+}
+
+/*! \brief Destructor function for registration state */
+static void sip_outbound_registration_state_destroy(void *obj)
+{
+	struct sip_outbound_registration_state *state = obj;
+
+	if (!state->client_state) {
+		return;
+	}
+
+	if (state->client_state->serializer && ast_sip_push_task(state->client_state->serializer, handle_client_state_destruction, state->client_state)) {
+		ast_log(LOG_WARNING, "Failed to pass outbound registration client destruction to threadpool\n");
+		ao2_ref(state->client_state, -1);
+	}
+}
+
+/*! \brief Destructor function for client registration state */
+static void sip_outbound_registration_client_state_destroy(void *obj)
+{
+	struct sip_outbound_registration_client_state *client_state = obj;
+
+	ast_taskprocessor_unreference(client_state->serializer);
+}
+
+/*! \brief Allocator function for registration state */
+static struct sip_outbound_registration_state *sip_outbound_registration_state_alloc(void)
+{
+	struct sip_outbound_registration_state *state = ao2_alloc(sizeof(*state), sip_outbound_registration_state_destroy);
+
+	if (!state || !(state->client_state = ao2_alloc(sizeof(*state->client_state), sip_outbound_registration_client_state_destroy))) {
+		ao2_cleanup(state);
+		return NULL;
+	}
+
+	if ((pjsip_regc_create(ast_sip_get_pjsip_endpoint(), state->client_state, sip_outbound_registration_response_cb, &state->client_state->client) != PJ_SUCCESS) ||
+		!(state->client_state->serializer = ast_sip_create_serializer())) {
+		/* This is on purpose, normal operation will have it be deallocated within the serializer */
+		pjsip_regc_destroy(state->client_state->client);
+		ao2_cleanup(state->client_state);
+		ao2_cleanup(state);
+		return NULL;
+	}
+
+	state->client_state->status = SIP_REGISTRATION_UNREGISTERED;
+	state->client_state->timer.user_data = state->client_state;
+	state->client_state->timer.cb = sip_outbound_registration_timer_cb;
+
+	return state;
+}
+
+/*! \brief Destructor function for registration information */
+static void sip_outbound_registration_destroy(void *obj)
+{
+	struct sip_outbound_registration *registration = obj;
+
+	ao2_cleanup(registration->state);
+	destroy_auths(registration->sip_outbound_auths, registration->num_outbound_auths);
+
+	ast_string_field_free_memory(registration);
+}
+
+/*! \brief Allocator function for registration information */
+static void *sip_outbound_registration_alloc(const char *name)
+{
+	struct sip_outbound_registration *registration = ao2_alloc(sizeof(*registration), sip_outbound_registration_destroy);
+
+	if (!registration || ast_string_field_init(registration, 256)) {
+		ao2_cleanup(registration);
+		return NULL;
+	}
+
+	return registration;
+}
+
+/*! \brief Helper function which populates a pj_str_t with a contact header */
+static int sip_dialog_create_contact(pj_pool_t *pool, pj_str_t *contact, const char *user, const pj_str_t *target, pjsip_tpselector *selector)
+{
+	pj_str_t tmp, local_addr;
+	pjsip_uri *uri;
+	pjsip_sip_uri *sip_uri;
+	pjsip_transport_type_e type = PJSIP_TRANSPORT_UNSPECIFIED;
+	int local_port;
+
+	pj_strdup_with_null(pool, &tmp, target);
+
+	if (!(uri = pjsip_parse_uri(pool, tmp.ptr, tmp.slen, 0)) ||
+	    (!PJSIP_URI_SCHEME_IS_SIP(uri) && !PJSIP_URI_SCHEME_IS_SIPS(uri))) {
+		return -1;
+	}
+
+	sip_uri = pjsip_uri_get_uri(uri);
+
+	if (PJSIP_URI_SCHEME_IS_SIPS(sip_uri)) {
+		type = PJSIP_TRANSPORT_TLS;
+	} else if (!sip_uri->transport_param.slen) {
+		type = PJSIP_TRANSPORT_UDP;
+	} else {
+		type = pjsip_transport_get_type_from_name(&sip_uri->transport_param);
+	}
+
+	if (type == PJSIP_TRANSPORT_UNSPECIFIED) {
+		return -1;
+	}
+
+	if (pj_strchr(&sip_uri->host, ':')) {
+		type = (pjsip_transport_type_e)(((int)type) + PJSIP_TRANSPORT_IPV6);
+	}
+
+	if (pjsip_tpmgr_find_local_addr(pjsip_endpt_get_tpmgr(ast_sip_get_pjsip_endpoint()), pool, type, selector,
+							      &local_addr, &local_port) != PJ_SUCCESS) {
+		return -1;
+	}
+
+	if (!pj_strchr(&sip_uri->host, ':') && pj_strchr(&local_addr, ':')) {
+		type = (pjsip_transport_type_e)(((int)type) + PJSIP_TRANSPORT_IPV6);
+	}
+
+	contact->ptr = pj_pool_alloc(pool, PJSIP_MAX_URL_SIZE);
+	contact->slen = pj_ansi_snprintf(contact->ptr, PJSIP_MAX_URL_SIZE,
+				      "<%s:%s@%s%.*s%s:%d%s%s>",
+				      (pjsip_transport_get_flag_from_type(type) & PJSIP_TRANSPORT_SECURE) ? "sips" : "sip",
+				      user,
+				      (type & PJSIP_TRANSPORT_IPV6) ? "[" : "",
+				      (int)local_addr.slen,
+				      local_addr.ptr,
+				      (type & PJSIP_TRANSPORT_IPV6) ? "]" : "",
+				      local_port,
+				      (type != PJSIP_TRANSPORT_UDP && type != PJSIP_TRANSPORT_UDP6) ? ";transport=" : "",
+				      (type != PJSIP_TRANSPORT_UDP && type != PJSIP_TRANSPORT_UDP6) ? pjsip_transport_get_type_name(type) : "");
+
+	return 0;
+}
+
+/*!
+ * \internal
+ * \brief Check if a registration can be reused
+ *
+ * This checks if the existing outbound registration's configuration differs from a newly-applied
+ * outbound registration to see if the applied one.
+ *
+ * \param existing The pre-existing outbound registration
+ * \param applied The newly-created registration
+ */
+static int can_reuse_registration(struct sip_outbound_registration *existing, struct sip_outbound_registration *applied)
+{
+	int i;
+
+	if (strcmp(existing->server_uri, applied->server_uri) || strcmp(existing->client_uri, applied->client_uri) ||
+		strcmp(existing->transport, applied->transport) || strcmp(existing->contact_user, applied->contact_user) ||
+		strcmp(existing->outbound_proxy, applied->outbound_proxy) || existing->num_outbound_auths != applied->num_outbound_auths ||
+		existing->auth_rejection_permanent != applied->auth_rejection_permanent) {
+		return 0;
+	}
+
+	for (i = 0; i < existing->num_outbound_auths; ++i) {
+		if (strcmp(existing->sip_outbound_auths[i], applied->sip_outbound_auths[i])) {
+			return 0;
+		}
+	}
+
+	return 1;
+}
+
+/*! \brief Apply function which finds or allocates a state structure */
+static int sip_outbound_registration_apply(const struct ast_sorcery *sorcery, void *obj)
+{
+	RAII_VAR(struct sip_outbound_registration *, existing, ast_sorcery_retrieve_by_id(sorcery, "registration", ast_sorcery_object_get_id(obj)), ao2_cleanup);
+	struct sip_outbound_registration *applied = obj;
+	pj_str_t server_uri, client_uri, contact_uri;
+	pjsip_tpselector selector = { .type = PJSIP_TPSELECTOR_NONE, };
+
+	if (!existing) {
+		/* If no existing registration exists we can just start fresh easily */
+		applied->state = sip_outbound_registration_state_alloc();
+	} else {
+		/* If there is an existing registration things are more complicated, we can immediately reuse this state if most stuff remains unchanged */
+		if (can_reuse_registration(existing, applied)) {
+			applied->state = existing->state;
+			ao2_ref(applied->state, +1);
+			return 0;
+		}
+		applied->state = sip_outbound_registration_state_alloc();
+	}
+
+	if (!applied->state) {
+		return -1;
+	}
+
+	if (!ast_strlen_zero(applied->transport)) {
+		RAII_VAR(struct ast_sip_transport *, transport, ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "transport", applied->transport), ao2_cleanup);
+
+		if (!transport || !transport->state) {
+			return -1;
+		}
+
+		if (transport->type == AST_SIP_TRANSPORT_UDP) {
+			selector.type = PJSIP_TPSELECTOR_TRANSPORT;
+			selector.u.transport = transport->state->transport;
+		} else if (transport->type == AST_SIP_TRANSPORT_TCP || transport->type == AST_SIP_TRANSPORT_TLS) {
+			selector.type = PJSIP_TPSELECTOR_LISTENER;
+			selector.u.listener = transport->state->factory;
+		} else {
+			return -1;
+		}
+	}
+
+	pjsip_regc_set_transport(applied->state->client_state->client, &selector);
+
+	if (!ast_strlen_zero(applied->outbound_proxy)) {
+		pjsip_route_hdr route_set, *route;
+		static const pj_str_t ROUTE_HNAME = { "Route", 5 };
+		pj_str_t tmp;
+
+		pj_list_init(&route_set);
+
+		pj_strdup2_with_null(pjsip_regc_get_pool(applied->state->client_state->client), &tmp, applied->outbound_proxy);
+		if (!(route = pjsip_parse_hdr(pjsip_regc_get_pool(applied->state->client_state->client), &ROUTE_HNAME, tmp.ptr, tmp.slen, NULL))) {
+			return -1;
+		}
+		pj_list_push_back(&route_set, route);
+
+		pjsip_regc_set_route_set(applied->state->client_state->client, &route_set);
+	}
+
+	pj_cstr(&server_uri, applied->server_uri);
+
+	if (sip_dialog_create_contact(pjsip_regc_get_pool(applied->state->client_state->client), &contact_uri, S_OR(applied->contact_user, "s"), &server_uri, &selector)) {
+		return -1;
+	}
+
+	pj_cstr(&client_uri, applied->client_uri);
+
+	if (pjsip_regc_init(applied->state->client_state->client, &server_uri, &client_uri, &client_uri, 1, &contact_uri, applied->expiration) != PJ_SUCCESS) {
+		return -1;
+	}
+
+	return 0;
+}
+
+/*! \brief Helper function which performs a single registration */
+static int sip_outbound_registration_perform(void *obj, void *arg, int flags)
+{
+	struct sip_outbound_registration *registration = obj;
+	size_t i;
+
+	/* Just in case the client state is being reused for this registration, free the auth information */
+	destroy_auths(registration->state->client_state->sip_outbound_auths,
+			registration->state->client_state->num_outbound_auths);
+	registration->state->client_state->num_outbound_auths = 0;
+
+	registration->state->client_state->sip_outbound_auths = ast_calloc(registration->num_outbound_auths, sizeof(char *));
+	for (i = 0; i < registration->num_outbound_auths; ++i) {
+		registration->state->client_state->sip_outbound_auths[i] = ast_strdup(registration->sip_outbound_auths[i]);
+	}
+	registration->state->client_state->num_outbound_auths = registration->num_outbound_auths;
+	registration->state->client_state->retry_interval = registration->retry_interval;
+	registration->state->client_state->max_retries = registration->max_retries;
+	registration->state->client_state->retries = 0;
+
+	pjsip_regc_update_expires(registration->state->client_state->client, registration->expiration);
+
+	schedule_registration(registration->state->client_state, (ast_random() % 10) + 1);
+
+	return 0;
+}
+
+/*! \brief Helper function which performs all registrations */
+static void sip_outbound_registration_perform_all(void)
+{
+	RAII_VAR(struct ao2_container *, registrations, ast_sorcery_retrieve_by_fields(ast_sip_get_sorcery(), "registration", AST_RETRIEVE_FLAG_MULTIPLE | AST_RETRIEVE_FLAG_ALL, NULL), ao2_cleanup);
+
+	if (!registrations) {
+		return;
+	}
+
+	ao2_callback(registrations, OBJ_NODATA, sip_outbound_registration_perform, NULL);
+}
+
+#define AUTH_INCREMENT 4
+
+static const char **auth_alloc(const char *value, size_t *num_auths)
+{
+	char *auths = ast_strdupa(value);
+	char *val;
+	int num_alloced = 0;
+	const char **alloced_auths = NULL;
+
+	while ((val = strsep(&auths, ","))) {
+		if (*num_auths >= num_alloced) {
+			size_t size;
+			num_alloced += AUTH_INCREMENT;
+			size = num_alloced * sizeof(char *);
+			alloced_auths = ast_realloc(alloced_auths, size);
+			if (!alloced_auths) {
+				goto failure;
+			}
+		}
+		alloced_auths[*num_auths] = ast_strdup(val);
+		if (!alloced_auths[*num_auths]) {
+			goto failure;
+		}
+		++(*num_auths);
+	}
+	return alloced_auths;
+
+failure:
+	destroy_auths(alloced_auths, *num_auths);
+	return NULL;
+}
+
+static int outbound_auth_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
+{
+	struct sip_outbound_registration *registration = obj;
+
+	registration->sip_outbound_auths = auth_alloc(var->value, &registration->num_outbound_auths);
+	if (!registration->sip_outbound_auths) {
+		return -1;
+	}
+	return 0;
+}
+
+static int load_module(void)
+{
+	ast_sorcery_apply_default(ast_sip_get_sorcery(), "registration", "config", "res_sip.conf,criteria=type=registration");
+
+	if (ast_sorcery_object_register(ast_sip_get_sorcery(), "registration", sip_outbound_registration_alloc, NULL, sip_outbound_registration_apply)) {
+		return AST_MODULE_LOAD_DECLINE;
+	}
+
+	ast_sorcery_object_field_register(ast_sip_get_sorcery(), "registration", "type", "", OPT_NOOP_T, 0, 0);
+	ast_sorcery_object_field_register(ast_sip_get_sorcery(), "registration", "server_uri", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct sip_outbound_registration, server_uri));
+	ast_sorcery_object_field_register(ast_sip_get_sorcery(), "registration", "client_uri", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct sip_outbound_registration, client_uri));
+	ast_sorcery_object_field_register(ast_sip_get_sorcery(), "registration", "contact_user", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct sip_outbound_registration, contact_user));
+	ast_sorcery_object_field_register(ast_sip_get_sorcery(), "registration", "transport", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct sip_outbound_registration, transport));
+	ast_sorcery_object_field_register(ast_sip_get_sorcery(), "registration", "outbound_proxy", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct sip_outbound_registration, outbound_proxy));
+	ast_sorcery_object_field_register(ast_sip_get_sorcery(), "registration", "expiration", "3600", OPT_UINT_T, 0, FLDSET(struct sip_outbound_registration, expiration));
+	ast_sorcery_object_field_register(ast_sip_get_sorcery(), "registration", "retry_interval", "60", OPT_UINT_T, 0, FLDSET(struct sip_outbound_registration, retry_interval));
+	ast_sorcery_object_field_register(ast_sip_get_sorcery(), "registration", "max_retries", "10", OPT_UINT_T, 0, FLDSET(struct sip_outbound_registration, max_retries));
+	ast_sorcery_object_field_register(ast_sip_get_sorcery(), "registration", "auth_rejection_permanent", "yes", OPT_BOOL_T, 1, FLDSET(struct sip_outbound_registration, auth_rejection_permanent));
+	ast_sorcery_object_field_register_custom(ast_sip_get_sorcery(), "registration", "outbound_auth", "", outbound_auth_handler, NULL, 0, 0);
+	ast_sorcery_reload_object(ast_sip_get_sorcery(), "registration");
+	sip_outbound_registration_perform_all();
+
+	return AST_MODULE_LOAD_SUCCESS;
+}
+
+static int reload_module(void)
+{
+	ast_sorcery_reload_object(ast_sip_get_sorcery(), "registration");
+	sip_outbound_registration_perform_all();
+	return 0;
+}
+
+static int unload_module(void)
+{
+	return 0;
+}
+
+AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "SIP Outbound Registration Support",
+		.load = load_module,
+		.reload = reload_module,
+		.unload = unload_module,
+		.load_pri = AST_MODPRI_APP_DEPEND,
+	       );
diff --git a/res/res_sip_pubsub.c b/res/res_sip_pubsub.c
new file mode 100644
index 0000000000000000000000000000000000000000..2983d563e539aee7ad63183fae6b6d41775ea000
--- /dev/null
+++ b/res/res_sip_pubsub.c
@@ -0,0 +1,662 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2013, Digium, Inc.
+ *
+ * Mark Michelson <mmichelson@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+/*!
+ * \brief Opaque structure representing an RFC 3265 SIP subscription
+ */
+
+#include "asterisk.h"
+
+#include <pjsip.h>
+#include <pjsip_simple.h>
+#include <pjlib.h>
+
+#include "asterisk/res_sip_pubsub.h"
+#include "asterisk/module.h"
+#include "asterisk/linkedlists.h"
+#include "asterisk/astobj2.h"
+#include "asterisk/datastore.h"
+#include "asterisk/uuid.h"
+#include "asterisk/taskprocessor.h"
+#include "asterisk/res_sip.h"
+
+static pj_bool_t sub_on_rx_request(pjsip_rx_data *rdata);
+
+static struct pjsip_module sub_module = {
+	.name = { "PubSub Module", 13 },
+	.priority = PJSIP_MOD_PRIORITY_APPLICATION,
+	.on_rx_request = sub_on_rx_request,
+};
+
+/*!
+ * \brief Structure representing a SIP subscription
+ */
+struct ast_sip_subscription {
+	/*! Subscription datastores set up by handlers */
+	struct ao2_container *datastores;
+	/*! The endpoint with which the subscription is communicating */
+	struct ast_sip_endpoint *endpoint;
+	/*! Serializer on which to place operations for this subscription */
+	struct ast_taskprocessor *serializer;
+	/*! The handler for this subscription */
+	const struct ast_sip_subscription_handler *handler;
+	/*! The role for this subscription */
+	enum ast_sip_subscription_role role;
+	/*! The underlying PJSIP event subscription structure */
+	pjsip_evsub *evsub;
+	/*! The underlying PJSIP dialog */
+	pjsip_dialog *dlg;
+};
+
+#define DATASTORE_BUCKETS 53
+
+#define DEFAULT_EXPIRES 3600
+
+static int datastore_hash(const void *obj, int flags)
+{
+	const struct ast_datastore *datastore = obj;
+	const char *uid = flags & OBJ_KEY ? obj : datastore->uid;
+
+	ast_assert(uid != NULL);
+
+	return ast_str_hash(uid);
+}
+
+static int datastore_cmp(void *obj, void *arg, int flags)
+{
+	const struct ast_datastore *datastore1 = obj;
+	const struct ast_datastore *datastore2 = arg;
+	const char *uid2 = flags & OBJ_KEY ? arg : datastore2->uid;
+
+	ast_assert(datastore1->uid != NULL);
+	ast_assert(uid2 != NULL);
+
+	return strcmp(datastore1->uid, uid2) ? 0 : CMP_MATCH | CMP_STOP;
+}
+
+static void subscription_destructor(void *obj)
+{
+	struct ast_sip_subscription *sub = obj;
+
+	ast_debug(3, "Destroying SIP subscription\n");
+
+	ao2_cleanup(sub->datastores);
+	ao2_cleanup(sub->endpoint);
+
+	if (sub->dlg) {
+		/* This is why we keep the dialog on the subscription. When the subscription
+		 * is destroyed, there is no guarantee that the underlying dialog is ready
+		 * to be destroyed. Furthermore, there's no guarantee in the opposite direction
+		 * either. The dialog could be destroyed before our subscription is. We fix
+		 * this problem by keeping a reference to the dialog until it is time to
+		 * destroy the subscription. We need to have the dialog available when the
+		 * subscription is destroyed so that we can guarantee that our attempt to
+		 * remove the serializer will be successful.
+		 */
+		ast_sip_dialog_set_serializer(sub->dlg, NULL);
+		pjsip_dlg_dec_session(sub->dlg, &sub_module);
+	}
+	ast_taskprocessor_unreference(sub->serializer);
+}
+
+static void pubsub_on_evsub_state(pjsip_evsub *sub, pjsip_event *event);
+static void pubsub_on_tsx_state(pjsip_evsub *sub, pjsip_transaction *tsx, pjsip_event *event);
+static void pubsub_on_rx_refresh(pjsip_evsub *sub, pjsip_rx_data *rdata,
+		int *p_st_code, pj_str_t **p_st_text, pjsip_hdr *res_hdr, pjsip_msg_body **p_body);
+static void pubsub_on_rx_notify(pjsip_evsub *sub, pjsip_rx_data *rdata, int *p_st_code,
+		pj_str_t **p_st_text, pjsip_hdr *res_hdr, pjsip_msg_body **p_body);
+static void pubsub_on_client_refresh(pjsip_evsub *sub);
+static void pubsub_on_server_timeout(pjsip_evsub *sub);
+
+
+static pjsip_evsub_user pubsub_cb = {
+	.on_evsub_state = pubsub_on_evsub_state,
+	.on_tsx_state = pubsub_on_tsx_state,
+	.on_rx_refresh = pubsub_on_rx_refresh,
+	.on_rx_notify = pubsub_on_rx_notify,
+	.on_client_refresh = pubsub_on_client_refresh,
+	.on_server_timeout = pubsub_on_server_timeout,
+};
+
+static pjsip_evsub *allocate_evsub(const char *event, enum ast_sip_subscription_role role,
+		struct ast_sip_endpoint *endpoint, pjsip_rx_data *rdata, pjsip_dialog *dlg)
+{
+	pjsip_evsub *evsub;
+	/* PJSIP is kind enough to have some built-in support for certain
+	 * events. We need to use the correct initialization function for the
+	 * built-in events
+	 */
+	if (role == AST_SIP_NOTIFIER) {
+		if (!strcmp(event, "message-summary")) {
+			pjsip_mwi_create_uas(dlg, &pubsub_cb, rdata, &evsub);
+		} else if (!strcmp(event, "presence")) {
+			pjsip_pres_create_uas(dlg, &pubsub_cb, rdata, &evsub);
+		} else {
+			pjsip_evsub_create_uas(dlg, &pubsub_cb, rdata, 0, &evsub);
+		}
+	} else {
+		if (!strcmp(event, "message-summary")) {
+			pjsip_mwi_create_uac(dlg, &pubsub_cb, 0, &evsub);
+		} else if (!strcmp(event, "presence")) {
+			pjsip_pres_create_uac(dlg, &pubsub_cb, 0, &evsub);
+		} else {
+			pj_str_t pj_event;
+			pj_cstr(&pj_event, event);
+			pjsip_evsub_create_uac(dlg, &pubsub_cb, &pj_event, 0, &evsub);
+		}
+	}
+	return evsub;
+}
+
+struct ast_sip_subscription *ast_sip_create_subscription(const struct ast_sip_subscription_handler *handler,
+        enum ast_sip_subscription_role role, struct ast_sip_endpoint *endpoint, pjsip_rx_data *rdata)
+{
+	struct ast_sip_subscription *sub = ao2_alloc(sizeof(*sub), subscription_destructor);
+	pjsip_dialog *dlg;
+
+	if (!sub) {
+		return NULL;
+	}
+	sub->datastores = ao2_container_alloc(DATASTORE_BUCKETS, datastore_hash, datastore_cmp);
+	if (!sub->datastores) {
+		ao2_ref(sub, -1);
+		return NULL;
+	}
+	sub->serializer = ast_sip_create_serializer();
+	if (!sub->serializer) {
+		ao2_ref(sub, -1);
+		return NULL;
+	}
+	sub->role = role;
+	if (role == AST_SIP_NOTIFIER) {
+		pjsip_dlg_create_uas(pjsip_ua_instance(), rdata, NULL, &dlg);
+	} else {
+		RAII_VAR(struct ast_sip_contact *, contact, NULL, ao2_cleanup);
+
+		contact = ast_sip_location_retrieve_contact_from_aor_list(endpoint->aors);
+		if (!contact || ast_strlen_zero(contact->uri)) {
+			ast_log(LOG_WARNING, "No contacts configured for endpoint %s. Unable to create SIP subsription\n",
+					ast_sorcery_object_get_id(endpoint));
+			ao2_ref(sub, -1);
+			return NULL;
+		}
+		dlg = ast_sip_create_dialog(endpoint, contact->uri, NULL);
+	}
+	if (!dlg) {
+		ast_log(LOG_WARNING, "Unable to create dialog for SIP subscription\n");
+		ao2_ref(sub, -1);
+		return NULL;
+	}
+	sub->evsub = allocate_evsub(handler->event_name, role, endpoint, rdata, dlg);
+	/* We keep a reference to the dialog until our subscription is destroyed. See
+	 * the subscription_destructor for more details
+	 */
+	pjsip_dlg_inc_session(dlg, &sub_module);
+	sub->dlg = dlg;
+	ast_sip_dialog_set_serializer(dlg, sub->serializer);
+	pjsip_evsub_set_mod_data(sub->evsub, sub_module.id, sub);
+	ao2_ref(endpoint, +1);
+	sub->endpoint = endpoint;
+	sub->handler = handler;
+	return sub;
+}
+ 
+struct ast_sip_endpoint *ast_sip_subscription_get_endpoint(struct ast_sip_subscription *sub)
+{
+	ast_assert(sub->endpoint != NULL);
+	ao2_ref(sub->endpoint, +1);
+	return sub->endpoint;
+}
+ 
+struct ast_taskprocessor *ast_sip_subscription_get_serializer(struct ast_sip_subscription *sub)
+{
+	ast_assert(sub->serializer != NULL);
+	return sub->serializer;
+}
+
+pjsip_evsub *ast_sip_subscription_get_evsub(struct ast_sip_subscription *sub)
+{
+	return sub->evsub;
+}
+
+int ast_sip_subscription_send_request(struct ast_sip_subscription *sub, pjsip_tx_data *tdata)
+{
+	return pjsip_evsub_send_request(ast_sip_subscription_get_evsub(sub),
+			tdata) == PJ_SUCCESS ? 0 : -1;
+}
+
+static void subscription_datastore_destroy(void *obj)
+{
+	struct ast_datastore *datastore = obj;
+
+	/* Using the destroy function (if present) destroy the data */
+	if (datastore->info->destroy != NULL && datastore->data != NULL) {
+		datastore->info->destroy(datastore->data);
+		datastore->data = NULL;
+	}
+
+	ast_free((void *) datastore->uid);
+	datastore->uid = NULL;
+}
+
+struct ast_datastore *ast_sip_subscription_alloc_datastore(const struct ast_datastore_info *info, const char *uid)
+{
+	RAII_VAR(struct ast_datastore *, datastore, NULL, ao2_cleanup);
+	const char *uid_ptr = uid;
+
+	if (!info) {
+		return NULL;
+	}
+
+	datastore = ao2_alloc(sizeof(*datastore), subscription_datastore_destroy);
+	if (!datastore) {
+		return NULL;
+	}
+
+	datastore->info = info;
+	if (ast_strlen_zero(uid)) {
+		/* They didn't provide an ID so we'll provide one ourself */
+		struct ast_uuid *uuid = ast_uuid_generate();
+		char uuid_buf[AST_UUID_STR_LEN];
+		if (!uuid) {
+			return NULL;
+		}
+		uid_ptr = ast_uuid_to_str(uuid, uuid_buf, sizeof(uuid_buf));
+		ast_free(uuid);
+	}
+
+	datastore->uid = ast_strdup(uid_ptr);
+	if (!datastore->uid) {
+		return NULL;
+	}
+
+	ao2_ref(datastore, +1);
+	return datastore;
+}
+ 
+int ast_sip_subscription_add_datastore(struct ast_sip_subscription *subscription, struct ast_datastore *datastore)
+{
+	ast_assert(datastore != NULL);
+	ast_assert(datastore->info != NULL);
+	ast_assert(ast_strlen_zero(datastore->uid) == 0);
+
+	if (!ao2_link(subscription->datastores, datastore)) {
+		return -1;
+	}
+	return 0;
+}
+
+struct ast_datastore *ast_sip_subscription_get_datastore(struct ast_sip_subscription *subscription, const char *name)
+{
+	return ao2_find(subscription->datastores, name, OBJ_KEY);
+}
+
+void ast_sip_subscription_remove_datastore(struct ast_sip_subscription *subscription, const char *name)
+{
+	ao2_callback(subscription->datastores, OBJ_KEY | OBJ_UNLINK | OBJ_NODATA, NULL, (void *) name);
+}
+
+AST_RWLIST_HEAD_STATIC(subscription_handlers, ast_sip_subscription_handler);
+
+static void add_handler(struct ast_sip_subscription_handler *handler)
+{
+	SCOPED_LOCK(lock, &subscription_handlers, AST_RWLIST_WRLOCK, AST_RWLIST_UNLOCK);
+	AST_RWLIST_INSERT_TAIL(&subscription_handlers, handler, next);
+	ast_module_ref(ast_module_info->self);
+}
+
+static int handler_exists_for_event_name(const char *event_name)
+{
+	struct ast_sip_subscription_handler *iter;
+	SCOPED_LOCK(lock, &subscription_handlers, AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK);
+
+	AST_RWLIST_TRAVERSE(&subscription_handlers, iter, next) {
+		if (!strcmp(iter->event_name, event_name)) {
+			return 1;
+		}
+	}
+	return 0;
+}
+
+int ast_sip_register_subscription_handler(struct ast_sip_subscription_handler *handler)
+{
+	pj_str_t event;
+	pj_str_t accept[AST_SIP_MAX_ACCEPT];
+	int i;
+
+	if (ast_strlen_zero(handler->event_name)) {
+		ast_log(LOG_ERROR, "No event package specifief for subscription handler. Cannot register\n");
+		return -1;
+	}
+
+	if (ast_strlen_zero(handler->accept[0])) {
+		ast_log(LOG_ERROR, "Subscription handler must supply at least one 'Accept' format\n");
+		return -1;
+	}
+
+	if (handler_exists_for_event_name(handler->event_name)) {
+		ast_log(LOG_ERROR, "A subscription handler for event %s already exists. Not registering "
+				"new subscription handler\n", handler->event_name);
+		return -1;
+	}
+
+	pj_cstr(&event, handler->event_name);
+	for (i = 0; i < AST_SIP_MAX_ACCEPT && !ast_strlen_zero(handler->accept[i]); ++i) {
+		pj_cstr(&accept[i], handler->accept[i]);
+	}
+
+	if (!strcmp(handler->event_name, "message-summary")) {
+		pjsip_mwi_init_module(ast_sip_get_pjsip_endpoint(), pjsip_evsub_instance());
+	} else if (!strcmp(handler->event_name, "presence")) {
+		pjsip_pres_init_module(ast_sip_get_pjsip_endpoint(), pjsip_evsub_instance());
+	} else {
+		pjsip_evsub_register_pkg(&sub_module, &event, DEFAULT_EXPIRES, i, accept);
+	}
+
+	add_handler(handler);
+	return 0;
+}
+ 
+void ast_sip_unregister_subscription_handler(struct ast_sip_subscription_handler *handler)
+{
+	struct ast_sip_subscription_handler *iter;
+	SCOPED_LOCK(lock, &subscription_handlers, AST_RWLIST_WRLOCK, AST_RWLIST_UNLOCK);
+	AST_RWLIST_TRAVERSE_SAFE_BEGIN(&subscription_handlers, iter, next) {
+		if (handler == iter) {
+			AST_RWLIST_REMOVE_CURRENT(next);
+			ast_module_unref(ast_module_info->self);
+			break;
+		}
+	}
+	AST_RWLIST_TRAVERSE_SAFE_END;
+}
+
+static struct ast_sip_subscription_handler *find_handler(const char *event, char accept[AST_SIP_MAX_ACCEPT][64], size_t num_accept)
+{
+	struct ast_sip_subscription_handler *iter;
+	int match = 0;
+	SCOPED_LOCK(lock, &subscription_handlers, AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK);
+	AST_RWLIST_TRAVERSE(&subscription_handlers, iter, next) {
+		int i;
+		int j;
+		if (strcmp(event, iter->event_name)) {
+			ast_debug(3, "Event %s does not match %s\n", event, iter->event_name);
+			continue;
+		}
+		ast_debug(3, "Event name match: %s = %s\n", event, iter->event_name);
+		for (i = 0; i < num_accept; ++i) {
+			for (j = 0; j < num_accept; ++j) {
+				if (ast_strlen_zero(iter->accept[i])) {
+					ast_debug(3, "Breaking because subscription handler has run out of 'accept' types\n");
+					break;
+				}
+				if (!strcmp(accept[j], iter->accept[i])) {
+					ast_debug(3, "Accept headers match: %s = %s\n", accept[j], iter->accept[i]);
+					match = 1;
+					break;
+				}
+				ast_debug(3, "Accept %s does not match %s\n", accept[j], iter->accept[i]);
+			}
+			if (match) {
+				break;
+			}
+		}
+		if (match) {
+			break;
+		}
+	}
+
+	return iter;
+}
+
+static pj_bool_t sub_on_rx_request(pjsip_rx_data *rdata)
+{
+	static const pj_str_t event_name = { "Event", 5 };
+	char event[32];
+	char accept[AST_SIP_MAX_ACCEPT][64];
+	pjsip_accept_hdr *accept_header;
+	pjsip_event_hdr *event_header;
+	struct ast_sip_subscription_handler *handler;
+	RAII_VAR(struct ast_sip_endpoint *, endpoint, NULL, ao2_cleanup);
+	struct ast_sip_subscription *sub;
+	int i;
+
+	if (pjsip_method_cmp(&rdata->msg_info.msg->line.req.method, pjsip_get_subscribe_method())) {
+		return PJ_FALSE;
+	}
+
+	endpoint = ast_pjsip_rdata_get_endpoint(rdata);
+	ast_assert(endpoint != NULL);
+
+	event_header = pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, &event_name, rdata->msg_info.msg->hdr.next);
+	if (!event_header) {
+		ast_log(LOG_WARNING, "Incoming SUBSCRIBE request with no Event header\n");
+		pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 489, NULL, NULL, NULL);
+		return PJ_TRUE;
+	}
+
+	accept_header = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_ACCEPT, rdata->msg_info.msg->hdr.next);
+	if (!accept_header) {
+		ast_log(LOG_WARNING, "Incoming SUBSCRIBE request with no Accept header\n");
+		pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 400, NULL, NULL, NULL);
+		return PJ_TRUE;
+	}
+
+	ast_copy_pj_str(event, &event_header->event_type, sizeof(event));
+	for (i = 0; i < accept_header->count; ++i) {
+		ast_copy_pj_str(accept[i], &accept_header->values[i], sizeof(accept[i]));
+	}
+
+	handler = find_handler(event, accept, accept_header->count);
+	if (!handler) {
+		ast_log(LOG_WARNING, "No registered handler for event %s\n", event);
+		pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 489, NULL, NULL, NULL);
+		return PJ_TRUE;
+	}
+	sub = handler->new_subscribe(endpoint, rdata);
+	if (!sub) {
+		pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 500, NULL, NULL, NULL);
+	}
+	return PJ_TRUE;
+}
+
+static void pubsub_on_evsub_state(pjsip_evsub *evsub, pjsip_event *event)
+{
+	struct ast_sip_subscription *sub;
+	if (pjsip_evsub_get_state(evsub) != PJSIP_EVSUB_STATE_TERMINATED) {
+		return;
+	}
+
+	sub = pjsip_evsub_get_mod_data(evsub, sub_module.id);
+	if (!sub) {
+		return;
+	}
+
+	if (event->type == PJSIP_EVENT_RX_MSG) {
+		sub->handler->subscription_terminated(sub, event->body.rx_msg.rdata);
+	}
+
+	if (event->type == PJSIP_EVENT_TSX_STATE &&
+			event->body.tsx_state.type == PJSIP_EVENT_RX_MSG) {
+		sub->handler->subscription_terminated(sub, event->body.tsx_state.src.rdata);
+	}
+
+	if (sub->handler->subscription_shutdown) {
+		sub->handler->subscription_shutdown(sub);
+	}
+	pjsip_evsub_set_mod_data(evsub, sub_module.id, NULL);
+}
+
+static void pubsub_on_tsx_state(pjsip_evsub *evsub, pjsip_transaction *tsx, pjsip_event *event)
+{
+	struct ast_sip_subscription *sub = pjsip_evsub_get_mod_data(evsub, sub_module.id);
+
+	if (!sub) {
+		return;
+	}
+
+	if (tsx->role == PJSIP_ROLE_UAC && event->body.tsx_state.type == PJSIP_EVENT_RX_MSG) {
+		sub->handler->notify_response(sub, event->body.tsx_state.src.rdata);
+	}
+}
+
+static void set_parameters_from_response_data(pj_pool_t *pool, int *p_st_code,
+		pj_str_t **p_st_text, pjsip_hdr *res_hdr, pjsip_msg_body **p_body,
+		struct ast_sip_subscription_response_data *response_data)
+{
+	ast_assert(response_data->status_code >= 200 && response_data->status_code <= 699);
+	*p_st_code = response_data->status_code;
+
+	if (!ast_strlen_zero(response_data->status_text)) {
+		pj_strdup2(pool, *p_st_text, response_data->status_text);
+	}
+
+	if (response_data->headers) {
+		struct ast_variable *iter;
+		for (iter = response_data->headers; iter; iter = iter->next) {
+			pj_str_t header_name;
+			pj_str_t header_value;	
+			pjsip_generic_string_hdr *hdr;
+
+			pj_cstr(&header_name, iter->name);
+			pj_cstr(&header_value, iter->value);
+			hdr = pjsip_generic_string_hdr_create(pool, &header_name, &header_value);
+			pj_list_insert_before(res_hdr, hdr);
+		}
+	}
+
+	if (response_data->body) {
+		pj_str_t type;
+		pj_str_t subtype;
+		pj_str_t body_text;
+
+		pj_cstr(&type, response_data->body->type);
+		pj_cstr(&subtype, response_data->body->subtype);
+		pj_cstr(&body_text, response_data->body->body_text);
+
+		*p_body = pjsip_msg_body_create(pool, &type, &subtype, &body_text);
+	}
+}
+
+static int response_data_changed(struct ast_sip_subscription_response_data *response_data)
+{
+	if (response_data->status_code != 200 ||
+			!ast_strlen_zero(response_data->status_text) ||
+			response_data->headers ||
+			response_data->body) {
+		return 1;
+	}
+	return 0;
+}
+
+static void pubsub_on_rx_refresh(pjsip_evsub *evsub, pjsip_rx_data *rdata,
+		int *p_st_code, pj_str_t **p_st_text, pjsip_hdr *res_hdr, pjsip_msg_body **p_body)
+{
+	struct ast_sip_subscription *sub = pjsip_evsub_get_mod_data(evsub, sub_module.id);
+	struct ast_sip_subscription_response_data response_data = {
+		.status_code = 200,
+	};
+
+	if (!sub) {
+		return;
+	}
+
+	sub->handler->resubscribe(sub, rdata, &response_data);
+
+	if (!response_data_changed(&response_data)) {
+		return;
+	}
+
+	set_parameters_from_response_data(rdata->tp_info.pool, p_st_code, p_st_text,
+			res_hdr, p_body, &response_data);
+}
+
+static void pubsub_on_rx_notify(pjsip_evsub *evsub, pjsip_rx_data *rdata, int *p_st_code,
+		pj_str_t **p_st_text, pjsip_hdr *res_hdr, pjsip_msg_body **p_body)
+{
+	struct ast_sip_subscription *sub = pjsip_evsub_get_mod_data(evsub, sub_module.id);
+	struct ast_sip_subscription_response_data response_data = {
+		.status_code = 200,
+	};
+
+	if (!sub|| !sub->handler->notify_request) {
+		return;
+	}
+
+	sub->handler->notify_request(sub, rdata, &response_data);
+
+	if (!response_data_changed(&response_data)) {
+		return;
+	}
+
+	set_parameters_from_response_data(rdata->tp_info.pool, p_st_code, p_st_text,
+			res_hdr, p_body, &response_data);
+}
+
+static int serialized_pubsub_on_client_refresh(void *userdata)
+{
+	struct ast_sip_subscription *sub = userdata;
+
+	sub->handler->refresh_subscription(sub);
+	ao2_cleanup(sub);
+	return 0;
+}
+
+static void pubsub_on_client_refresh(pjsip_evsub *evsub)
+{
+	struct ast_sip_subscription *sub = pjsip_evsub_get_mod_data(evsub, sub_module.id);
+
+	ao2_ref(sub, +1);
+	ast_sip_push_task(sub->serializer, serialized_pubsub_on_client_refresh, sub);
+}
+
+static int serialized_pubsub_on_server_timeout(void *userdata)
+{
+	struct ast_sip_subscription *sub = userdata;
+
+	sub->handler->subscription_timeout(sub);
+	ao2_cleanup(sub);
+	return 0;
+}
+
+static void pubsub_on_server_timeout(pjsip_evsub *evsub)
+{
+	struct ast_sip_subscription *sub = pjsip_evsub_get_mod_data(evsub, sub_module.id);
+
+	ao2_ref(sub, +1);
+	ast_sip_push_task(sub->serializer, serialized_pubsub_on_server_timeout, sub);
+}
+
+static int load_module(void)
+{
+	pjsip_evsub_init_module(ast_sip_get_pjsip_endpoint());
+	if (ast_sip_register_service(&sub_module)) {
+		return AST_MODULE_LOAD_DECLINE;
+	}
+	return AST_MODULE_LOAD_SUCCESS;
+}
+
+static int unload_module(void)
+{
+	return 0;
+}
+
+AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_LOAD_ORDER, "SIP event resource",
+		.load = load_module,
+		.unload = unload_module,
+		.load_pri = AST_MODPRI_CHANNEL_DEPEND,
+);
diff --git a/res/res_sip_pubsub.exports.in b/res/res_sip_pubsub.exports.in
new file mode 100644
index 0000000000000000000000000000000000000000..55308746a817bafaa5841ce3c9698e2a9fb51e1a
--- /dev/null
+++ b/res/res_sip_pubsub.exports.in
@@ -0,0 +1,16 @@
+{
+	global:
+		LINKER_SYMBOL_PREFIXast_sip_create_subscription;
+		LINKER_SYMBOL_PREFIXast_sip_subsription_get_endpoint;
+		LINKER_SYMBOL_PREFIXast_sip_subscription_get_serializer;
+		LINKER_SYMBOL_PREFIXast_sip_subscription_get_evsub;
+		LINKER_SYMBOL_PREFIXast_sip_subscription_send_request;
+		LINKER_SYMBOL_PREFIXast_sip_subscription_alloc_datastore;
+		LINKER_SYMBOL_PREFIXast_sip_subscription_add_datastore;
+		LINKER_SYMBOL_PREFIXast_sip_subscription_get_datastore;
+		LINKER_SYMBOL_PREFIXast_sip_subscription_remove_datastore;
+		LINKER_SYMBOL_PREFIXast_sip_register_subscription_handler;
+		LINKER_SYMBOL_PREFIXast_sip_unregister_subscription_handler;
+	local:
+		*;
+};
diff --git a/res/res_sip_registrar.c b/res/res_sip_registrar.c
new file mode 100644
index 0000000000000000000000000000000000000000..e5a2e888bef0323814b1bf8939a6a1829e41ec75
--- /dev/null
+++ b/res/res_sip_registrar.c
@@ -0,0 +1,382 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2013, Digium, Inc.
+ *
+ * Joshua Colp <jcolp@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*** MODULEINFO
+	<support_level>core</support_level>
+ ***/
+
+#include "asterisk.h"
+
+#include <pjsip.h>
+#include <pjsip_ua.h>
+
+#include "asterisk/res_sip.h"
+#include "asterisk/module.h"
+
+/*! \brief Internal function which returns the expiration time for a contact */
+static int registrar_get_expiration(const struct ast_sip_aor *aor, const pjsip_contact_hdr *contact, const pjsip_rx_data *rdata)
+{
+	pjsip_expires_hdr *expires;
+	int expiration = aor->default_expiration;
+
+	if (contact->expires != -1) {
+		/* Expiration was provided with the contact itself */
+		expiration = contact->expires;
+	} else if ((expires = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_EXPIRES, NULL))) {
+		/* Expiration was provided using the Expires header */
+		expiration = expires->ivalue;
+	}
+
+	/* If the value has explicitly been set to 0, do not enforce */
+	if (!expiration) {
+		return expiration;
+	}
+
+	/* Enforce the range that we will allow for expiration */
+	if (expiration < aor->minimum_expiration) {
+		expiration = aor->minimum_expiration;
+	} else if (expiration > aor->maximum_expiration) {
+		expiration = aor->maximum_expiration;
+	}
+
+	return expiration;
+}
+
+/*! \brief Structure used for finding contact */
+struct registrar_contact_details {
+	/*! \brief Pool used for parsing URI */
+	pj_pool_t *pool;
+	/*! \brief URI being looked for */
+	pjsip_uri *uri;
+};
+
+/*! \brief Callback function for finding a contact */
+static int registrar_find_contact(void *obj, void *arg, int flags)
+{
+	struct ast_sip_contact *contact = obj;
+	const struct registrar_contact_details *details = arg;
+	pjsip_uri *contact_uri = pjsip_parse_uri(details->pool, (char*)contact->uri, strlen(contact->uri), 0);
+
+	return (pjsip_uri_cmp(PJSIP_URI_IN_CONTACT_HDR, details->uri, contact_uri) == PJ_SUCCESS) ? CMP_MATCH | CMP_STOP : 0;
+}
+
+/*! \brief Internal function which validates provided Contact headers to confirm that they are acceptable, and returns number of contacts */
+static int registrar_validate_contacts(const pjsip_rx_data *rdata, struct ao2_container *contacts, struct ast_sip_aor *aor, int *added, int *updated, int *deleted)
+{
+	pjsip_contact_hdr *previous = NULL, *contact = (pjsip_contact_hdr *)&rdata->msg_info.msg->hdr;
+	struct registrar_contact_details details = {
+		.pool = pjsip_endpt_create_pool(ast_sip_get_pjsip_endpoint(), "Contact Comparison", 256, 256),
+	};
+
+	if (!details.pool) {
+		return -1;
+	}
+
+	while ((contact = (pjsip_contact_hdr *) pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_CONTACT, contact->next))) {
+		int expiration;
+		RAII_VAR(struct ast_sip_contact *, existing, NULL, ao2_cleanup);
+
+		if (contact->star) {
+			/* The expiration MUST be 0 when a '*' contact is used and there must be no other contact */
+			if ((contact->expires != 0) || previous) {
+				pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), details.pool);
+				return -1;
+			}
+		} else if (previous && previous->star) {
+			/* If there is a previous contact and it is a '*' this is a deal breaker */
+			pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), details.pool);
+			return -1;
+		}
+		previous = contact;
+
+		if (!PJSIP_URI_SCHEME_IS_SIP(contact->uri) && !PJSIP_URI_SCHEME_IS_SIPS(contact->uri)) {
+			continue;
+		}
+
+		details.uri = pjsip_uri_get_uri(contact->uri);
+		expiration = registrar_get_expiration(aor, contact, rdata);
+
+		/* Determine if this is an add, update, or delete for policy enforcement purposes */
+		if (!(existing = ao2_callback(contacts, 0, registrar_find_contact, &details))) {
+			if (expiration) {
+				(*added)++;
+			}
+		} else if (expiration) {
+			(*updated)++;
+		} else {
+			(*deleted)++;
+		}
+	}
+
+	/* The provided contacts are acceptable, huzzah! */
+	pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), details.pool);
+	return 0;
+}
+
+/*! \brief Callback function which prunes static contacts */
+static int registrar_prune_static(void *obj, void *arg, int flags)
+{
+	struct ast_sip_contact *contact = obj;
+
+	return ast_tvzero(contact->expiration_time) ? CMP_MATCH : 0;
+}
+
+/*! \brief Internal function used to delete all contacts from an AOR */
+static int registrar_delete_contact(void *obj, void *arg, int flags)
+{
+	struct ast_sip_contact *contact = obj;
+
+	ast_sip_location_delete_contact(contact);
+
+	return 0;
+}
+
+/*! \brief Internal function which adds a contact to a response */
+static int registrar_add_contact(void *obj, void *arg, int flags)
+{
+	struct ast_sip_contact *contact = obj;
+	pjsip_tx_data *tdata = arg;
+	pjsip_contact_hdr *hdr = pjsip_contact_hdr_create(tdata->pool);
+	pj_str_t uri;
+
+	pj_strdup2_with_null(tdata->pool, &uri, contact->uri);
+	hdr->uri = pjsip_parse_uri(tdata->pool, uri.ptr, uri.slen, PJSIP_PARSE_URI_AS_NAMEADDR);
+	hdr->expires = ast_tvdiff_ms(contact->expiration_time, ast_tvnow()) / 1000;
+
+	pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)hdr);
+
+	return 0;
+}
+
+/*! \brief Helper function which adds a Date header to a response */
+static void registrar_add_date_header(pjsip_tx_data *tdata)
+{
+	char date[256];
+	struct tm tm;
+	time_t t = time(NULL);
+
+	gmtime_r(&t, &tm);
+	strftime(date, sizeof(date), "%a, %d %b %Y %T GMT", &tm);
+
+	ast_sip_add_header(tdata, "Date", date);
+}
+
+static pj_bool_t registrar_on_rx_request(struct pjsip_rx_data *rdata)
+{
+	struct ast_sip_endpoint *endpoint = ast_pjsip_rdata_get_endpoint(rdata);
+	pjsip_sip_uri *uri;
+	char user_name[64], domain_name[64];
+	char *configured_aors, *aor_name;
+	RAII_VAR(struct ast_sip_aor *, aor, NULL, ao2_cleanup);
+	RAII_VAR(struct ao2_container *, contacts, NULL, ao2_cleanup);
+	int added = 0, updated = 0, deleted = 0;
+	pjsip_contact_hdr *contact_hdr = NULL;
+	struct registrar_contact_details details = { 0, };
+	pjsip_tx_data *tdata;
+	pjsip_response_addr addr;
+
+	if (pjsip_method_cmp(&rdata->msg_info.msg->line.req.method, &pjsip_register_method) || !endpoint) {
+		return PJ_FALSE;
+	}
+
+	if (ast_strlen_zero(endpoint->aors)) {
+		/* Short circuit early if the endpoint has no AORs configured on it, which means no registration possible */
+		pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 403, NULL, NULL, NULL);
+		return PJ_TRUE;
+	}
+
+	if (!PJSIP_URI_SCHEME_IS_SIP(rdata->msg_info.to->uri) && !PJSIP_URI_SCHEME_IS_SIPS(rdata->msg_info.to->uri)) {
+		pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 416, NULL, NULL, NULL);
+		return PJ_TRUE;
+	}
+
+	uri = pjsip_uri_get_uri(rdata->msg_info.to->uri);
+	ast_copy_pj_str(user_name, &uri->user, sizeof(user_name));
+	ast_copy_pj_str(domain_name, &uri->host, sizeof(domain_name));
+
+	configured_aors = ast_strdupa(endpoint->aors);
+
+	/* Iterate the configured AORs to see if the user or the user+domain match */
+	while ((aor_name = strsep(&configured_aors, ","))) {
+		char id[AST_UUID_STR_LEN];
+		RAII_VAR(struct ast_sip_domain_alias *, alias, NULL, ao2_cleanup);
+
+		snprintf(id, sizeof(id), "%s@%s", user_name, domain_name);
+		if (!strcmp(aor_name, id)) {
+			break;
+		}
+
+		if ((alias = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "domain_alias", domain_name))) {
+			snprintf(id, sizeof(id), "%s@%s", user_name, alias->domain);
+			if (!strcmp(aor_name, id)) {
+				break;
+			}
+		}
+
+		if (!strcmp(aor_name, user_name)) {
+			break;
+		}
+	}
+
+	if (ast_strlen_zero(aor_name) || !(aor = ast_sip_location_retrieve_aor(aor_name))) {
+		/* The provided AOR name was not found (be it within the configuration or sorcery itself) */
+		pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 404, NULL, NULL, NULL);
+		return PJ_TRUE;
+	}
+
+	if (!aor->max_contacts) {
+		/* Registration is not permitted for this AOR */
+		pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 403, NULL, NULL, NULL);
+		return PJ_TRUE;
+	}
+
+	/* Retrieve the current contacts, we'll need to know whether to update or not */
+	contacts = ast_sip_location_retrieve_aor_contacts(aor);
+
+	/* So we don't count static contacts against max_contacts we prune them out from the container */
+	ao2_callback(contacts, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, registrar_prune_static, NULL);
+
+	if (registrar_validate_contacts(rdata, contacts, aor, &added, &updated, &deleted)) {
+		/* The provided Contact headers do not conform to the specification */
+		pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 400, NULL, NULL, NULL);
+		return PJ_TRUE;
+	}
+
+	if (((added - deleted) + (!aor->remove_existing ? ao2_container_count(contacts) : 0)) > aor->max_contacts) {
+		/* Enforce the maximum number of contacts */
+		pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 403, NULL, NULL, NULL);
+		return PJ_TRUE;
+	}
+
+	if (!(details.pool = pjsip_endpt_create_pool(ast_sip_get_pjsip_endpoint(), "Contact Comparison", 256, 256))) {
+		pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 500, NULL, NULL, NULL);
+		return PJ_TRUE;
+	}
+
+	/* Iterate each provided Contact header and add, update, or delete */
+	while ((contact_hdr = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_CONTACT, contact_hdr ? contact_hdr->next : NULL))) {
+		int expiration;
+		char contact_uri[PJSIP_MAX_URL_SIZE];
+		RAII_VAR(struct ast_sip_contact *, contact, NULL, ao2_cleanup);
+
+		if (contact_hdr->star) {
+			/* A star means to unregister everything, so do so for the possible contacts */
+			ao2_callback(contacts, OBJ_NODATA | OBJ_MULTIPLE, registrar_delete_contact, NULL);
+			break;
+		}
+
+		if (!PJSIP_URI_SCHEME_IS_SIP(contact_hdr->uri) && !PJSIP_URI_SCHEME_IS_SIPS(contact_hdr->uri)) {
+			/* This registrar only currently supports sip: and sips: URI schemes */
+			continue;
+		}
+
+		expiration = registrar_get_expiration(aor, contact_hdr, rdata);
+		details.uri = pjsip_uri_get_uri(contact_hdr->uri);
+		pjsip_uri_print(PJSIP_URI_IN_CONTACT_HDR, details.uri, contact_uri, sizeof(contact_uri));
+
+		if (!(contact = ao2_callback(contacts, OBJ_UNLINK, registrar_find_contact, &details))) {
+			/* If they are actually trying to delete a contact that does not exist... be forgiving */
+			if (!expiration) {
+				ast_verb(3, "Attempted to remove non-existent contact '%s' from AOR '%s' by request\n",
+					contact_uri, aor_name);
+				continue;
+			}
+
+			ast_sip_location_add_contact(aor, contact_uri, ast_tvadd(ast_tvnow(), ast_samp2tv(expiration, 1)));
+			ast_verb(3, "Added contact '%s' to AOR '%s' with expiration of %d seconds\n",
+				contact_uri, aor_name, expiration);
+		} else if (expiration) {
+			RAII_VAR(struct ast_sip_contact *, updated, ast_sorcery_copy(ast_sip_get_sorcery(), contact), ao2_cleanup);
+
+			updated->expiration_time = ast_tvadd(ast_tvnow(), ast_samp2tv(expiration, 1));
+
+			ast_sip_location_update_contact(updated);
+			ast_debug(3, "Refreshed contact '%s' on AOR '%s' with new expiration of %d seconds\n",
+				contact_uri, aor_name, expiration);
+		} else {
+			ast_sip_location_delete_contact(contact);
+			ast_verb(3, "Removed contact '%s' from AOR '%s' due to request\n", contact_uri, aor_name);
+		}
+	}
+
+	pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), details.pool);
+
+	/* If the AOR is configured to remove any existing contacts that have not been updated/added as a result of this REGISTER
+	 * do so
+	 */
+	if (aor->remove_existing) {
+		ao2_callback(contacts, OBJ_NODATA | OBJ_MULTIPLE, registrar_delete_contact, NULL);
+	}
+
+	/* Update the contacts as things will probably have changed */
+	ao2_cleanup(contacts);
+	contacts = ast_sip_location_retrieve_aor_contacts(aor);
+
+	/* Send a response containing all of the contacts (including static) that are present on this AOR */
+	if (pjsip_endpt_create_response(ast_sip_get_pjsip_endpoint(), rdata, 200, NULL, &tdata) != PJ_SUCCESS) {
+		return PJ_TRUE;
+	}
+
+	/* Add the date header to the response, some UAs use this to set their date and time */
+	registrar_add_date_header(tdata);
+
+	ao2_callback(contacts, 0, registrar_add_contact, tdata);
+
+	if (pjsip_get_response_addr(tdata->pool, rdata, &addr) == PJ_SUCCESS) {
+		pjsip_endpt_send_response(ast_sip_get_pjsip_endpoint(), &addr, tdata, NULL, NULL);
+	} else {
+		pjsip_tx_data_dec_ref(tdata);
+	}
+
+	return PJ_TRUE;
+}
+
+static pjsip_module registrar_module = {
+	.name = { "Registrar", 9 },
+	.id = -1,
+	.priority = PJSIP_MOD_PRIORITY_APPLICATION,
+	.on_rx_request = registrar_on_rx_request,
+};
+
+static int load_module(void)
+{
+	const pj_str_t STR_REGISTER = { "REGISTER", 8 };
+
+	if (ast_sip_register_service(&registrar_module)) {
+		return AST_MODULE_LOAD_DECLINE;
+	}
+
+	if (pjsip_endpt_add_capability(ast_sip_get_pjsip_endpoint(), NULL, PJSIP_H_ALLOW, NULL, 1, &STR_REGISTER) != PJ_SUCCESS) {
+		ast_sip_unregister_service(&registrar_module);
+		return AST_MODULE_LOAD_DECLINE;
+	}
+
+	return AST_MODULE_LOAD_SUCCESS;
+}
+
+static int unload_module(void)
+{
+	ast_sip_unregister_service(&registrar_module);
+	return 0;
+}
+
+AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "SIP Registrar Support",
+		.load = load_module,
+		.unload = unload_module,
+		.load_pri = AST_MODPRI_APP_DEPEND,
+	       );
diff --git a/res/res_sip_rfc3326.c b/res/res_sip_rfc3326.c
new file mode 100644
index 0000000000000000000000000000000000000000..1c9ec6154eb1f5208651f1077113322b80660ae1
--- /dev/null
+++ b/res/res_sip_rfc3326.c
@@ -0,0 +1,145 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2013, Digium, Inc.
+ *
+ * Joshua Colp <jcolp@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*** MODULEINFO
+	<depend>pjproject</depend>
+	<support_level>core</support_level>
+ ***/
+
+#include "asterisk.h"
+
+#include <pjsip.h>
+#include <pjsip_ua.h>
+
+#include "asterisk/res_sip.h"
+#include "asterisk/res_sip_session.h"
+#include "asterisk/module.h"
+#include "asterisk/causes.h"
+
+static void rfc3326_use_reason_header(struct ast_sip_session *session, struct pjsip_rx_data *rdata)
+{
+	const pj_str_t str_reason = { "Reason", 6 };
+	pjsip_generic_string_hdr *header = pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, &str_reason, NULL);
+	char buf[20], *cause, *text;
+	int code;
+
+	if (!header) {
+		return;
+	}
+
+	ast_copy_pj_str(buf, &header->hvalue, sizeof(buf));
+	cause = ast_skip_blanks(buf);
+
+	if (strncasecmp(cause, "Q.850", 5) || !(cause = strstr(cause, "cause="))) {
+		return;
+	}
+
+	/* If text is present get rid of it */
+	if ((text = strstr(cause, ";"))) {
+		*text = '\0';
+	}
+
+	if (sscanf(cause, "cause=%30d", &code) != 1) {
+		return;
+	}
+
+	ast_channel_hangupcause_set(session->channel, code & 0x7f);
+}
+
+static int rfc3326_incoming_request(struct ast_sip_session *session, struct pjsip_rx_data *rdata)
+{
+	if ((pjsip_method_cmp(&rdata->msg_info.msg->line.req.method, &pjsip_bye_method) &&
+	     pjsip_method_cmp(&rdata->msg_info.msg->line.req.method, &pjsip_cancel_method)) ||
+	    !session->channel) {
+		return 0;
+	}
+
+	rfc3326_use_reason_header(session, rdata);
+
+	return 0;
+}
+
+static void rfc3326_incoming_response(struct ast_sip_session *session, struct pjsip_rx_data *rdata)
+{
+	struct pjsip_status_line status = rdata->msg_info.msg->line.status;
+
+	if ((status.code < 300) || !session->channel) {
+		return;
+	}
+
+	rfc3326_use_reason_header(session, rdata);
+}
+
+static void rfc3326_add_reason_header(struct ast_sip_session *session, struct pjsip_tx_data *tdata)
+{
+	char buf[20];
+
+	snprintf(buf, sizeof(buf), "Q.850;cause=%i", ast_channel_hangupcause(session->channel) & 0x7f);
+	ast_sip_add_header(tdata, "Reason", buf);
+
+	if (ast_channel_hangupcause(session->channel) == AST_CAUSE_ANSWERED_ELSEWHERE) {
+		ast_sip_add_header(tdata, "Reason", "SIP;cause=200;text=\"Call completed elsewhere\"");
+	}
+}
+
+static void rfc3326_outgoing_request(struct ast_sip_session *session, struct pjsip_tx_data *tdata)
+{
+	if ((pjsip_method_cmp(&tdata->msg->line.req.method, &pjsip_bye_method) &&
+	     pjsip_method_cmp(&tdata->msg->line.req.method, &pjsip_cancel_method)) ||
+	    !session->channel) {
+		return;
+	}
+
+	rfc3326_add_reason_header(session, tdata);
+}
+
+static void rfc3326_outgoing_response(struct ast_sip_session *session, struct pjsip_tx_data *tdata)
+{
+	struct pjsip_status_line status = tdata->msg->line.status;
+
+	if ((status.code < 300) || !session->channel) {
+		return;
+	}
+
+	rfc3326_add_reason_header(session, tdata);
+}
+
+static struct ast_sip_session_supplement rfc3326_supplement = {
+	.incoming_request = rfc3326_incoming_request,
+	.incoming_response = rfc3326_incoming_response,
+	.outgoing_request = rfc3326_outgoing_request,
+	.outgoing_response = rfc3326_outgoing_response,
+};
+
+static int load_module(void)
+{
+	ast_sip_session_register_supplement(&rfc3326_supplement);
+	return AST_MODULE_LOAD_SUCCESS;
+}
+
+static int unload_module(void)
+{
+	ast_sip_session_unregister_supplement(&rfc3326_supplement);
+	return 0;
+}
+
+AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "SIP RFC3326 Support",
+		.load = load_module,
+		.unload = unload_module,
+		.load_pri = AST_MODPRI_APP_DEPEND,
+	       );
diff --git a/res/res_sip_sdp_rtp.c b/res/res_sip_sdp_rtp.c
new file mode 100644
index 0000000000000000000000000000000000000000..13e6aa1aa5fbfe7338f3245900d537b1c913614c
--- /dev/null
+++ b/res/res_sip_sdp_rtp.c
@@ -0,0 +1,848 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2013, Digium, Inc.
+ *
+ * Joshua Colp <jcolp@digium.com>
+ * Kevin Harwell <kharwell@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*! \file
+ *
+ * \author Joshua Colp <jcolp@digium.com>
+ *
+ * \brief SIP SDP media stream handling
+ */
+
+/*** MODULEINFO
+	<depend>pjproject</depend>
+	<depend>res_sip</depend>
+	<depend>res_sip_session</depend>
+	<support_level>core</support_level>
+ ***/
+
+#include "asterisk.h"
+
+#include <pjsip.h>
+#include <pjsip_ua.h>
+#include <pjmedia.h>
+#include <pjlib.h>
+
+ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
+
+#include "asterisk/module.h"
+#include "asterisk/rtp_engine.h"
+#include "asterisk/netsock2.h"
+#include "asterisk/channel.h"
+#include "asterisk/causes.h"
+#include "asterisk/sched.h"
+#include "asterisk/acl.h"
+
+#include "asterisk/res_sip.h"
+#include "asterisk/res_sip_session.h"
+
+/*! \brief Scheduler for RTCP purposes */
+static struct ast_sched_context *sched;
+
+/*! \brief Address for IPv4 RTP */
+static struct ast_sockaddr address_ipv4;
+
+/*! \brief Address for IPv6 RTP */
+static struct ast_sockaddr address_ipv6;
+
+static const char STR_AUDIO[] = "audio";
+static const int FD_AUDIO = 0;
+
+static const char STR_VIDEO[] = "video";
+static const int FD_VIDEO = 2;
+
+/*! \brief Retrieves an ast_format_type based on the given stream_type */
+static enum ast_format_type stream_to_media_type(const char *stream_type)
+{
+	if (!strcasecmp(stream_type, STR_AUDIO)) {
+		return AST_FORMAT_TYPE_AUDIO;
+	} else if (!strcasecmp(stream_type, STR_VIDEO)) {
+		return AST_FORMAT_TYPE_VIDEO;
+	}
+
+	return 0;
+}
+
+/*! \brief Get the starting descriptor for a media type */
+static int media_type_to_fdno(enum ast_format_type media_type)
+{
+	switch (media_type) {
+	case AST_FORMAT_TYPE_AUDIO: return FD_AUDIO;
+	case AST_FORMAT_TYPE_VIDEO: return FD_VIDEO;
+	case AST_FORMAT_TYPE_TEXT:
+	case AST_FORMAT_TYPE_IMAGE: break;
+	}
+	return -1;
+}
+
+/*! \brief Remove all other cap types but the one given */
+static void format_cap_only_type(struct ast_format_cap *caps, enum ast_format_type media_type)
+{
+	int i = AST_FORMAT_INC;
+	while (i <= AST_FORMAT_TYPE_TEXT) {
+		if (i != media_type) {
+			ast_format_cap_remove_bytype(caps, i);
+		}
+		i += AST_FORMAT_INC;
+	}
+}
+
+/*! \brief Internal function which creates an RTP instance */
+static int create_rtp(struct ast_sip_session *session, struct ast_sip_session_media *session_media, unsigned int ipv6)
+{
+	struct ast_rtp_engine_ice *ice;
+
+	if (!(session_media->rtp = ast_rtp_instance_new("asterisk", sched, ipv6 ? &address_ipv6 : &address_ipv4, NULL))) {
+		return -1;
+	}
+
+	ast_rtp_instance_set_prop(session_media->rtp, AST_RTP_PROPERTY_RTCP, 1);
+	ast_rtp_instance_set_prop(session_media->rtp, AST_RTP_PROPERTY_NAT, session->endpoint->rtp_symmetric);
+
+	ast_rtp_codecs_packetization_set(ast_rtp_instance_get_codecs(session_media->rtp),
+					 session_media->rtp, &session->endpoint->prefs);
+
+	if (!session->endpoint->ice_support && (ice = ast_rtp_instance_get_ice(session_media->rtp))) {
+		ice->stop(session_media->rtp);
+	}
+
+	return 0;
+}
+
+static void get_codecs(struct ast_sip_session *session, const struct pjmedia_sdp_media *stream, struct ast_rtp_codecs *codecs)
+{
+	pjmedia_sdp_attr *attr;
+	pjmedia_sdp_rtpmap *rtpmap;
+	pjmedia_sdp_fmtp fmtp;
+	struct ast_format *format;
+	int i, num = 0;
+	char name[256];
+	char media[20];
+	char fmt_param[256];
+
+	ast_rtp_codecs_payloads_initialize(codecs);
+
+	/* Iterate through provided formats */
+	for (i = 0; i < stream->desc.fmt_count; ++i) {
+		/* The payload is kept as a string for things like t38 but for video it is always numerical */
+		ast_rtp_codecs_payloads_set_m_type(codecs, NULL, pj_strtoul(&stream->desc.fmt[i]));
+		/* Look for the optional rtpmap attribute */
+		if (!(attr = pjmedia_sdp_media_find_attr2(stream, "rtpmap", &stream->desc.fmt[i]))) {
+			continue;
+		}
+
+		/* Interpret the attribute as an rtpmap */
+		if ((pjmedia_sdp_attr_to_rtpmap(session->inv_session->pool_prov, attr, &rtpmap)) != PJ_SUCCESS) {
+			continue;
+		}
+
+		ast_copy_pj_str(name, &rtpmap->enc_name, sizeof(name));
+		ast_copy_pj_str(media, (pj_str_t*)&stream->desc.media, sizeof(media));
+		ast_rtp_codecs_payloads_set_rtpmap_type_rate(codecs, NULL, pj_strtoul(&stream->desc.fmt[i]),
+							     media, name, 0, rtpmap->clock_rate);
+		/* Look for an optional associated fmtp attribute */
+		if (!(attr = pjmedia_sdp_media_find_attr2(stream, "fmtp", &rtpmap->pt))) {
+			continue;
+		}
+
+		if ((pjmedia_sdp_attr_get_fmtp(attr, &fmtp)) == PJ_SUCCESS) {
+			sscanf(pj_strbuf(&fmtp.fmt), "%d", &num);
+			if ((format = ast_rtp_codecs_get_payload_format(codecs, num))) {
+				ast_copy_pj_str(fmt_param, &fmtp.fmt_param, sizeof(fmt_param));
+				ast_format_sdp_parse(format, fmt_param);
+			}
+		}
+	}
+}
+
+static int set_caps(struct ast_sip_session *session, struct ast_sip_session_media *session_media,
+		    const struct pjmedia_sdp_media *stream)
+{
+	RAII_VAR(struct ast_format_cap *, caps, NULL, ast_format_cap_destroy);
+	RAII_VAR(struct ast_format_cap *, peer, NULL, ast_format_cap_destroy);
+	RAII_VAR(struct ast_format_cap *, joint, NULL, ast_format_cap_destroy);
+	enum ast_format_type media_type = stream_to_media_type(session_media->stream_type);
+	struct ast_rtp_codecs codecs;
+	struct ast_format fmt;
+	int fmts = 0;
+	int direct_media_enabled = !ast_sockaddr_isnull(&session_media->direct_media_addr) &&
+		!ast_format_cap_is_empty(session->direct_media_cap);
+
+	if (!(caps = ast_format_cap_alloc_nolock()) ||
+	    !(peer = ast_format_cap_alloc_nolock())) {
+		ast_log(LOG_ERROR, "Failed to allocate %s capabilities\n", session_media->stream_type);
+		return -1;
+	}
+
+	/* get the endpoint capabilities */
+	if (direct_media_enabled) {
+		ast_format_cap_joint_copy(session->endpoint->codecs, session->direct_media_cap, caps);
+	} else {
+		ast_format_cap_copy(caps, session->endpoint->codecs);
+	}
+	format_cap_only_type(caps, media_type);
+
+	/* get the capabilities on the peer */
+	get_codecs(session, stream, &codecs);
+	ast_rtp_codecs_payload_formats(&codecs, peer, &fmts);
+
+	/* get the joint capabilities between peer and endpoint */
+	if (!(joint = ast_format_cap_joint(caps, peer))) {
+		char usbuf[64], thembuf[64];
+
+		ast_rtp_codecs_payloads_destroy(&codecs);
+
+		ast_getformatname_multiple(usbuf, sizeof(usbuf), caps);
+		ast_getformatname_multiple(thembuf, sizeof(thembuf), peer);
+		ast_log(LOG_WARNING, "No joint capabilities between our configuration(%s) and incoming SDP(%s)\n", usbuf, thembuf);
+		return -1;
+	}
+
+	ast_rtp_codecs_payloads_copy(&codecs, ast_rtp_instance_get_codecs(session_media->rtp),
+				     session_media->rtp);
+
+	ast_format_cap_copy(caps, session->req_caps);
+	ast_format_cap_remove_bytype(caps, media_type);
+	ast_format_cap_append(caps, joint);
+	ast_format_cap_append(session->req_caps, caps);
+
+	if (session->channel) {
+		ast_format_cap_copy(caps, ast_channel_nativeformats(session->channel));
+		ast_format_cap_remove_bytype(caps, media_type);
+		ast_format_cap_append(caps, joint);
+
+		/* Apply the new formats to the channel, potentially changing read/write formats while doing so */
+		ast_format_cap_append(ast_channel_nativeformats(session->channel), caps);
+		ast_codec_choose(&session->endpoint->prefs, caps, 0, &fmt);
+		ast_format_copy(ast_channel_rawwriteformat(session->channel), &fmt);
+		ast_format_copy(ast_channel_rawreadformat(session->channel), &fmt);
+		ast_set_read_format(session->channel, ast_channel_readformat(session->channel));
+		ast_set_write_format(session->channel, ast_channel_writeformat(session->channel));
+	}
+
+	ast_rtp_codecs_payloads_destroy(&codecs);
+	return 1;
+}
+
+static pjmedia_sdp_attr* generate_rtpmap_attr(pjmedia_sdp_media *media, pj_pool_t *pool, int rtp_code,
+					      int asterisk_format, struct ast_format *format, int code)
+{
+	pjmedia_sdp_rtpmap rtpmap;
+	pjmedia_sdp_attr *attr = NULL;
+	char tmp[64];
+
+	snprintf(tmp, sizeof(tmp), "%d", rtp_code);
+	pj_strdup2(pool, &media->desc.fmt[media->desc.fmt_count++], tmp);
+	rtpmap.pt = media->desc.fmt[media->desc.fmt_count - 1];
+	rtpmap.clock_rate = ast_rtp_lookup_sample_rate2(asterisk_format, format, code);
+	pj_strdup2(pool, &rtpmap.enc_name, ast_rtp_lookup_mime_subtype2(asterisk_format, format, code, 0));
+	rtpmap.param.slen = 0;
+
+	pjmedia_sdp_rtpmap_to_attr(pool, &rtpmap, &attr);
+
+	return attr;
+}
+
+static pjmedia_sdp_attr* generate_fmtp_attr(pj_pool_t *pool, struct ast_format *format, int rtp_code)
+{
+	struct ast_str *fmtp0 = ast_str_alloca(256);
+	pj_str_t fmtp1;
+	pjmedia_sdp_attr *attr = NULL;
+	char *tmp;
+
+	ast_format_sdp_generate(format, rtp_code, &fmtp0);
+	if (ast_str_strlen(fmtp0)) {
+		tmp = ast_str_buffer(fmtp0) + ast_str_strlen(fmtp0) - 1;
+		/* remove any carriage return line feeds */
+		while (*tmp == '\r' || *tmp == '\n') --tmp;
+		*++tmp = '\0';
+		/* ast...generate gives us everything, just need value */
+		tmp = strchr(ast_str_buffer(fmtp0), ':');
+		if (tmp && tmp + 1) {
+			fmtp1 = pj_str(tmp + 1);
+		} else {
+			fmtp1 = pj_str(ast_str_buffer(fmtp0));
+		}
+		attr = pjmedia_sdp_attr_create(pool, "fmtp", &fmtp1);
+	}
+	return attr;
+}
+
+/*! \brief Function which adds ICE attributes to a media stream */
+static void add_ice_to_stream(struct ast_sip_session *session, struct ast_sip_session_media *session_media, pj_pool_t *pool, pjmedia_sdp_media *media)
+{
+	struct ast_rtp_engine_ice *ice;
+	struct ao2_container *candidates;
+	const char *username, *password;
+	pj_str_t stmp;
+	pjmedia_sdp_attr *attr;
+	struct ao2_iterator it_candidates;
+	struct ast_rtp_engine_ice_candidate *candidate;
+
+	if (!session->endpoint->ice_support || !(ice = ast_rtp_instance_get_ice(session_media->rtp)) ||
+		!(candidates = ice->get_local_candidates(session_media->rtp))) {
+		return;
+	}
+
+	if ((username = ice->get_ufrag(session_media->rtp))) {
+		attr = pjmedia_sdp_attr_create(pool, "ice-ufrag", pj_cstr(&stmp, username));
+		media->attr[media->attr_count++] = attr;
+	}
+
+	if ((password = ice->get_password(session_media->rtp))) {
+		attr = pjmedia_sdp_attr_create(pool, "ice-pwd", pj_cstr(&stmp, password));
+		media->attr[media->attr_count++] = attr;
+	}
+
+	it_candidates = ao2_iterator_init(candidates, 0);
+	for (; (candidate = ao2_iterator_next(&it_candidates)); ao2_ref(candidate, -1)) {
+		struct ast_str *attr_candidate = ast_str_create(128);
+
+		ast_str_set(&attr_candidate, -1, "%s %d %s %d %s ", candidate->foundation, candidate->id, candidate->transport,
+					candidate->priority, ast_sockaddr_stringify_host(&candidate->address));
+		ast_str_append(&attr_candidate, -1, "%s typ ", ast_sockaddr_stringify_port(&candidate->address));
+
+		switch (candidate->type) {
+			case AST_RTP_ICE_CANDIDATE_TYPE_HOST:
+				ast_str_append(&attr_candidate, -1, "host");
+				break;
+			case AST_RTP_ICE_CANDIDATE_TYPE_SRFLX:
+				ast_str_append(&attr_candidate, -1, "srflx");
+				break;
+			case AST_RTP_ICE_CANDIDATE_TYPE_RELAYED:
+				ast_str_append(&attr_candidate, -1, "relay");
+				break;
+		}
+
+		if (!ast_sockaddr_isnull(&candidate->relay_address)) {
+			ast_str_append(&attr_candidate, -1, " raddr %s rport ", ast_sockaddr_stringify_host(&candidate->relay_address));
+			ast_str_append(&attr_candidate, -1, " %s", ast_sockaddr_stringify_port(&candidate->relay_address));
+		}
+
+		attr = pjmedia_sdp_attr_create(pool, "candidate", pj_cstr(&stmp, ast_str_buffer(attr_candidate)));
+		media->attr[media->attr_count++] = attr;
+
+		ast_free(attr_candidate);
+	}
+
+	ao2_iterator_destroy(&it_candidates);
+}
+
+/*! \brief Function which processes ICE attributes in an audio stream */
+static void process_ice_attributes(struct ast_sip_session *session, struct ast_sip_session_media *session_media,
+				   const struct pjmedia_sdp_session *remote, const struct pjmedia_sdp_media *remote_stream)
+{
+	struct ast_rtp_engine_ice *ice;
+	const pjmedia_sdp_attr *attr;
+	char attr_value[256];
+	unsigned int attr_i;
+
+	/* If ICE support is not enabled or available exit early */
+	if (!session->endpoint->ice_support || !(ice = ast_rtp_instance_get_ice(session_media->rtp))) {
+		return;
+	}
+
+	if ((attr = pjmedia_sdp_media_find_attr2(remote_stream, "ice-ufrag", NULL))) {
+		ast_copy_pj_str(attr_value, (pj_str_t*)&attr->value, sizeof(attr_value));
+		ice->set_authentication(session_media->rtp, attr_value, NULL);
+	}
+
+	if ((attr = pjmedia_sdp_media_find_attr2(remote_stream, "ice-pwd", NULL))) {
+		ast_copy_pj_str(attr_value, (pj_str_t*)&attr->value, sizeof(attr_value));
+		ice->set_authentication(session_media->rtp, NULL, attr_value);
+	}
+
+	if (pjmedia_sdp_media_find_attr2(remote_stream, "ice-lite", NULL)) {
+		ice->ice_lite(session_media->rtp);
+	}
+
+	/* Find all of the candidates */
+	for (attr_i = 0; attr_i < remote_stream->attr_count; ++attr_i) {
+		char foundation[32], transport[32], address[PJ_INET6_ADDRSTRLEN + 1], cand_type[6], relay_address[PJ_INET6_ADDRSTRLEN + 1] = "";
+		int port, relay_port = 0;
+		struct ast_rtp_engine_ice_candidate candidate = { 0, };
+
+		attr = remote_stream->attr[attr_i];
+
+		/* If this is not a candidate line skip it */
+		if (pj_strcmp2(&attr->name, "candidate")) {
+			continue;
+		}
+
+		ast_copy_pj_str(attr_value, (pj_str_t*)&attr->value, sizeof(attr_value));
+
+		if (sscanf(attr_value, "%31s %30u %31s %30u %46s %30u typ %5s %*s %23s %*s %30u", foundation, &candidate.id, transport,
+			&candidate.priority, address, &port, cand_type, relay_address, &relay_port) < 7) {
+			/* Candidate did not parse properly */
+			continue;
+		}
+
+		candidate.foundation = foundation;
+		candidate.transport = transport;
+
+		ast_sockaddr_parse(&candidate.address, address, PARSE_PORT_FORBID);
+		ast_sockaddr_set_port(&candidate.address, port);
+
+		if (!strcasecmp(cand_type, "host")) {
+			candidate.type = AST_RTP_ICE_CANDIDATE_TYPE_HOST;
+		} else if (!strcasecmp(cand_type, "srflx")) {
+			candidate.type = AST_RTP_ICE_CANDIDATE_TYPE_SRFLX;
+		} else if (!strcasecmp(cand_type, "relay")) {
+			candidate.type = AST_RTP_ICE_CANDIDATE_TYPE_RELAYED;
+		} else {
+			continue;
+		}
+
+		if (!ast_strlen_zero(relay_address)) {
+			ast_sockaddr_parse(&candidate.relay_address, relay_address, PARSE_PORT_FORBID);
+		}
+
+		if (relay_port) {
+			ast_sockaddr_set_port(&candidate.relay_address, relay_port);
+		}
+
+		ice->add_remote_candidate(session_media->rtp, &candidate);
+	}
+
+	ice->start(session_media->rtp);
+}
+
+static void apply_packetization(struct ast_sip_session *session, struct ast_sip_session_media *session_media,
+			 const struct pjmedia_sdp_media *remote_stream)
+{
+	pjmedia_sdp_attr *attr;
+	pj_str_t value;
+	unsigned long framing;
+	int codec;
+	struct ast_codec_pref *pref = &ast_rtp_instance_get_codecs(session_media->rtp)->pref;
+
+	/* Apply packetization if available and configured to do so */
+	if (!session->endpoint->use_ptime || !(attr = pjmedia_sdp_media_find_attr2(remote_stream, "ptime", NULL))) {
+		return;
+	}
+
+	value = attr->value;
+	framing = pj_strtoul(pj_strltrim(&value));
+
+	for (codec = 0; codec < AST_RTP_MAX_PT; codec++) {
+		struct ast_rtp_payload_type format = ast_rtp_codecs_payload_lookup(ast_rtp_instance_get_codecs(
+											   session_media->rtp), codec);
+
+		if (!format.asterisk_format) {
+			continue;
+		}
+
+		ast_codec_pref_setsize(pref, &format.format, framing);
+	}
+
+	ast_rtp_codecs_packetization_set(ast_rtp_instance_get_codecs(session_media->rtp),
+					 session_media->rtp, pref);
+}
+
+/*! \brief Function which negotiates an incoming media stream */
+static int negotiate_incoming_sdp_stream(struct ast_sip_session *session, struct ast_sip_session_media *session_media,
+					 const struct pjmedia_sdp_session *sdp, const struct pjmedia_sdp_media *stream)
+{
+	char host[NI_MAXHOST];
+	RAII_VAR(struct ast_sockaddr *, addrs, NULL, ast_free_ptr);
+	enum ast_format_type media_type = stream_to_media_type(session_media->stream_type);
+
+	/* If no type formats have been configured reject this stream */
+	if (!ast_format_cap_has_type(session->endpoint->codecs, media_type)) {
+		return 0;
+	}
+
+	ast_copy_pj_str(host, stream->conn ? &stream->conn->addr : &sdp->conn->addr, sizeof(host));
+
+	/* Ensure that the address provided is valid */
+	if (ast_sockaddr_resolve(&addrs, host, PARSE_PORT_FORBID, AST_AF_UNSPEC) <= 0) {
+		/* The provided host was actually invalid so we error out this negotiation */
+		return -1;
+	}
+
+	/* Using the connection information create an appropriate RTP instance */
+	if (!session_media->rtp && create_rtp(session, session_media, ast_sockaddr_is_ipv6(addrs))) {
+		return -1;
+	}
+
+	return set_caps(session, session_media, stream);
+}
+
+/*! \brief Function which creates an outgoing stream */
+static int create_outgoing_sdp_stream(struct ast_sip_session *session, struct ast_sip_session_media *session_media,
+				      struct pjmedia_sdp_session *sdp)
+{
+	pj_pool_t *pool = session->inv_session->pool_prov;
+	static const pj_str_t STR_IN = { "IN", 2 };
+	static const pj_str_t STR_IP4 = { "IP4", 3};
+	static const pj_str_t STR_IP6 = { "IP6", 3};
+	static const pj_str_t STR_RTP_AVP = { "RTP/AVP", 7 };
+	static const pj_str_t STR_SENDRECV = { "sendrecv", 8 };
+	pjmedia_sdp_media *media;
+	char hostip[PJ_INET6_ADDRSTRLEN+2];
+	struct ast_sockaddr addr;
+	char tmp[512];
+	pj_str_t stmp;
+	pjmedia_sdp_attr *attr;
+	int index = 0, min_packet_size = 0, noncodec = (session->endpoint->dtmf == AST_SIP_DTMF_RFC_4733) ? AST_RTP_DTMF : 0;
+	int rtp_code;
+	struct ast_format format;
+	struct ast_format compat_format;
+	RAII_VAR(struct ast_format_cap *, caps, NULL, ast_format_cap_destroy);
+	enum ast_format_type media_type = stream_to_media_type(session_media->stream_type);
+
+	int direct_media_enabled = !ast_sockaddr_isnull(&session_media->direct_media_addr) &&
+		!ast_format_cap_is_empty(session->direct_media_cap);
+
+	if (!ast_format_cap_has_type(session->endpoint->codecs, media_type)) {
+		/* If no type formats are configured don't add a stream */
+		return 0;
+	} else if (!session_media->rtp && create_rtp(session, session_media, session->endpoint->rtp_ipv6)) {
+		return -1;
+	}
+
+	if (!(media = pj_pool_zalloc(pool, sizeof(struct pjmedia_sdp_media))) ||
+		!(media->conn = pj_pool_zalloc(pool, sizeof(struct pjmedia_sdp_conn)))) {
+		return -1;
+	}
+
+	/* TODO: This should eventually support SRTP */
+	media->desc.media = pj_str(session_media->stream_type);
+	media->desc.transport = STR_RTP_AVP;
+
+	/* Add connection level details */
+	if (direct_media_enabled) {
+		ast_copy_string(hostip, ast_sockaddr_stringify_fmt(&session_media->direct_media_addr, AST_SOCKADDR_STR_ADDR), sizeof(hostip));
+	} else if (ast_strlen_zero(session->endpoint->external_media_address)) {
+		pj_sockaddr localaddr;
+
+		if (pj_gethostip(session->endpoint->rtp_ipv6 ? pj_AF_INET6() : pj_AF_INET(), &localaddr)) {
+			return -1;
+		}
+		pj_sockaddr_print(&localaddr, hostip, sizeof(hostip), 2);
+	} else {
+		ast_copy_string(hostip, session->endpoint->external_media_address, sizeof(hostip));
+	}
+
+	media->conn->net_type = STR_IN;
+	media->conn->addr_type = session->endpoint->rtp_ipv6 ? STR_IP6 : STR_IP4;
+	pj_strdup2(pool, &media->conn->addr, hostip);
+	ast_rtp_instance_get_local_address(session_media->rtp, &addr);
+	media->desc.port = direct_media_enabled ? ast_sockaddr_port(&session_media->direct_media_addr) : (pj_uint16_t) ast_sockaddr_port(&addr);
+	media->desc.port_count = 1;
+
+	/* Add ICE attributes and candidates */
+	add_ice_to_stream(session, session_media, pool, media);
+
+	if (!(caps = ast_format_cap_alloc_nolock())) {
+		ast_log(LOG_ERROR, "Failed to allocate %s capabilities\n", session_media->stream_type);
+		return -1;
+	}
+
+	if (direct_media_enabled) {
+		ast_format_cap_joint_copy(session->endpoint->codecs, session->direct_media_cap, caps);
+	} else if (ast_format_cap_is_empty(session->req_caps)) {
+		ast_format_cap_copy(caps, session->endpoint->codecs);
+	} else {
+		ast_format_cap_joint_copy(session->endpoint->codecs, session->req_caps, caps);
+	}
+
+	for (index = 0; ast_codec_pref_index(&session->endpoint->prefs, index, &format); ++index) {
+		struct ast_codec_pref *pref = &ast_rtp_instance_get_codecs(session_media->rtp)->pref;
+
+		if (AST_FORMAT_GET_TYPE(format.id) != media_type) {
+			continue;
+		}
+
+		if (!ast_format_cap_get_compatible_format(caps, &format, &compat_format)) {
+			continue;
+		}
+
+		if ((rtp_code = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(session_media->rtp), 1, &compat_format, 0)) == -1) {
+			return -1;
+		}
+
+		if (!(attr = generate_rtpmap_attr(media, pool, rtp_code, 1, &compat_format, 0))) {
+			continue;
+		}
+
+		media->attr[media->attr_count++] = attr;
+
+		if ((attr = generate_fmtp_attr(pool, &compat_format, rtp_code))) {
+			media->attr[media->attr_count++] = attr;
+		}
+
+		if (pref && media_type != AST_FORMAT_TYPE_VIDEO) {
+			struct ast_format_list fmt = ast_codec_pref_getsize(pref, &compat_format);
+			if (fmt.cur_ms && ((fmt.cur_ms < min_packet_size) || !min_packet_size)) {
+				min_packet_size = fmt.cur_ms;
+			}
+		}
+	}
+
+	/* Add non-codec formats */
+	if (media_type != AST_FORMAT_TYPE_VIDEO) {
+		for (index = 1LL; index <= AST_RTP_MAX; index <<= 1) {
+			if (!(noncodec & index) || (rtp_code = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(session_media->rtp),
+											   0, NULL, index)) == -1) {
+				continue;
+			}
+
+			if (!(attr = generate_rtpmap_attr(media, pool, rtp_code, 0, NULL, index))) {
+				continue;
+			}
+
+			media->attr[media->attr_count++] = attr;
+
+			if (index == AST_RTP_DTMF) {
+				snprintf(tmp, sizeof(tmp), "%d 0-16", rtp_code);
+				attr = pjmedia_sdp_attr_create(pool, "fmtp", pj_cstr(&stmp, tmp));
+				media->attr[media->attr_count++] = attr;
+			}
+		}
+	}
+
+	/* If ptime is set add it as an attribute */
+	if (min_packet_size) {
+		snprintf(tmp, sizeof(tmp), "%d", min_packet_size);
+		attr = pjmedia_sdp_attr_create(pool, "ptime", pj_cstr(&stmp, tmp));
+		media->attr[media->attr_count++] = attr;
+	}
+
+	/* Add the sendrecv attribute - we purposely don't keep track because pjmedia-sdp will automatically change our offer for us */
+	attr = PJ_POOL_ZALLOC_T(pool, pjmedia_sdp_attr);
+	attr->name = STR_SENDRECV;
+	media->attr[media->attr_count++] = attr;
+
+	/* Add the media stream to the SDP */
+	sdp->media[sdp->media_count++] = media;
+
+	return 1;
+}
+
+static int apply_negotiated_sdp_stream(struct ast_sip_session *session, struct ast_sip_session_media *session_media,
+				       const struct pjmedia_sdp_session *local, const struct pjmedia_sdp_media *local_stream,
+				       const struct pjmedia_sdp_session *remote, const struct pjmedia_sdp_media *remote_stream)
+{
+	RAII_VAR(struct ast_sockaddr *, addrs, NULL, ast_free_ptr);
+	enum ast_format_type media_type = stream_to_media_type(session_media->stream_type);
+	char host[NI_MAXHOST];
+	int fdno;
+
+	if (!session->channel) {
+		return 1;
+	}
+
+	/* Create an RTP instance if need be */
+	if (!session_media->rtp && create_rtp(session, session_media, session->endpoint->rtp_ipv6)) {
+		return -1;
+	}
+
+	ast_copy_pj_str(host, remote_stream->conn ? &remote_stream->conn->addr : &remote->conn->addr, sizeof(host));
+
+	/* Ensure that the address provided is valid */
+	if (ast_sockaddr_resolve(&addrs, host, PARSE_PORT_FORBID, AST_AF_UNSPEC) <= 0) {
+		/* The provided host was actually invalid so we error out this negotiation */
+		return -1;
+	}
+
+	/* Apply connection information to the RTP instance */
+	ast_sockaddr_set_port(addrs, remote_stream->desc.port);
+	ast_rtp_instance_set_remote_address(session_media->rtp, addrs);
+
+	if (set_caps(session, session_media, local_stream) < 1) {
+		return -1;
+	}
+
+	if (media_type == AST_FORMAT_TYPE_AUDIO) {
+		apply_packetization(session, session_media, remote_stream);
+	}
+
+	if ((fdno = media_type_to_fdno(media_type)) < 0) {
+		return -1;
+	}
+	ast_channel_set_fd(session->channel, fdno, ast_rtp_instance_fd(session_media->rtp, 0));
+	ast_channel_set_fd(session->channel, fdno + 1, ast_rtp_instance_fd(session_media->rtp, 1));
+
+	/* If ICE support is enabled find all the needed attributes */
+	process_ice_attributes(session, session_media, remote, remote_stream);
+
+	/* audio stream handles music on hold */
+	if (media_type != AST_FORMAT_TYPE_AUDIO) {
+		return 1;
+	}
+
+	/* Music on hold for audio streams only */
+	if (session_media->held &&
+	    (!ast_sockaddr_isnull(addrs) ||
+	     !pjmedia_sdp_media_find_attr2(remote_stream, "sendonly", NULL))) {
+		/* The remote side has taken us off hold */
+		ast_queue_control(session->channel, AST_CONTROL_UNHOLD);
+		ast_queue_frame(session->channel, &ast_null_frame);
+		session_media->held = 0;
+	} else if (ast_sockaddr_isnull(addrs) ||
+		   ast_sockaddr_is_any(addrs) ||
+		   pjmedia_sdp_media_find_attr2(remote_stream, "sendonly", NULL)) {
+		/* The remote side has put us on hold */
+		ast_queue_control_data(session->channel, AST_CONTROL_HOLD, S_OR(session->endpoint->mohsuggest, NULL),
+				       !ast_strlen_zero(session->endpoint->mohsuggest) ? strlen(session->endpoint->mohsuggest) + 1 : 0);
+		ast_rtp_instance_stop(session_media->rtp);
+		ast_queue_frame(session->channel, &ast_null_frame);
+		session_media->held = 1;
+	} else {
+		/* The remote side has not changed state, but make sure the instance is active */
+		ast_rtp_instance_activate(session_media->rtp);
+	}
+
+	return 1;
+}
+
+/*! \brief Function which updates the media stream with external media address, if applicable */
+static void change_outgoing_sdp_stream_media_address(pjsip_tx_data *tdata, struct pjmedia_sdp_media *stream, struct ast_sip_transport *transport)
+{
+	char host[NI_MAXHOST];
+	struct ast_sockaddr addr = { { 0, } };
+
+	ast_copy_pj_str(host, &stream->conn->addr, sizeof(host));
+	ast_sockaddr_parse(&addr, host, PARSE_PORT_FORBID);
+
+	/* Is the address within the SDP inside the same network? */
+	if (ast_apply_ha(transport->localnet, &addr) == AST_SENSE_ALLOW) {
+		return;
+	}
+
+	pj_strdup2(tdata->pool, &stream->conn->addr, transport->external_media_address);
+}
+
+/*! \brief Function which destroys the RTP instance when session ends */
+static void stream_destroy(struct ast_sip_session_media *session_media)
+{
+	if (session_media->rtp) {
+		ast_rtp_instance_stop(session_media->rtp);
+		ast_rtp_instance_destroy(session_media->rtp);
+	}
+}
+
+/*! \brief SDP handler for 'audio' media stream */
+static struct ast_sip_session_sdp_handler audio_sdp_handler = {
+	.id = STR_AUDIO,
+	.negotiate_incoming_sdp_stream = negotiate_incoming_sdp_stream,
+	.create_outgoing_sdp_stream = create_outgoing_sdp_stream,
+	.apply_negotiated_sdp_stream = apply_negotiated_sdp_stream,
+	.change_outgoing_sdp_stream_media_address = change_outgoing_sdp_stream_media_address,
+	.stream_destroy = stream_destroy,
+};
+
+/*! \brief SDP handler for 'video' media stream */
+static struct ast_sip_session_sdp_handler video_sdp_handler = {
+	.id = STR_VIDEO,
+	.negotiate_incoming_sdp_stream = negotiate_incoming_sdp_stream,
+	.create_outgoing_sdp_stream = create_outgoing_sdp_stream,
+	.apply_negotiated_sdp_stream = apply_negotiated_sdp_stream,
+	.change_outgoing_sdp_stream_media_address = change_outgoing_sdp_stream_media_address,
+	.stream_destroy = stream_destroy,
+};
+
+static int video_info_incoming_request(struct ast_sip_session *session, struct pjsip_rx_data *rdata)
+{
+	struct pjsip_transaction *tsx = pjsip_rdata_get_tsx(rdata);
+	pjsip_tx_data *tdata;
+
+	if (pj_strcmp2(&rdata->msg_info.msg->body->content_type.type, "application") ||
+	    pj_strcmp2(&rdata->msg_info.msg->body->content_type.subtype, "media_control+xml")) {
+
+		return 0;
+	}
+
+	ast_queue_control(session->channel, AST_CONTROL_VIDUPDATE);
+
+	if (pjsip_dlg_create_response(session->inv_session->dlg, rdata, 200, NULL, &tdata) == PJ_SUCCESS) {
+		pjsip_dlg_send_response(session->inv_session->dlg, tsx, tdata);
+	}
+
+	return 0;
+}
+
+static struct ast_sip_session_supplement video_info_supplement = {
+	.method = "INFO",
+	.incoming_request = video_info_incoming_request,
+};
+
+/*! \brief Unloads the sdp RTP/AVP module from Asterisk */
+static int unload_module(void)
+{
+	ast_sip_session_unregister_supplement(&video_info_supplement);
+	ast_sip_session_unregister_sdp_handler(&video_sdp_handler, STR_VIDEO);
+	ast_sip_session_unregister_sdp_handler(&audio_sdp_handler, STR_AUDIO);
+
+	if (sched) {
+		ast_sched_context_destroy(sched);
+	}
+
+	return 0;
+}
+
+/*!
+ * \brief Load the module
+ *
+ * Module loading including tests for configuration or dependencies.
+ * This function can return AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_DECLINE,
+ * or AST_MODULE_LOAD_SUCCESS. If a dependency or environment variable fails
+ * tests return AST_MODULE_LOAD_FAILURE. If the module can not load the
+ * configuration file or other non-critical problem return
+ * AST_MODULE_LOAD_DECLINE. On success return AST_MODULE_LOAD_SUCCESS.
+ */
+static int load_module(void)
+{
+	ast_sockaddr_parse(&address_ipv4, "0.0.0.0", 0);
+	ast_sockaddr_parse(&address_ipv6, "::", 0);
+
+	if (!(sched = ast_sched_context_create())) {
+		ast_log(LOG_ERROR, "Unable to create scheduler context.\n");
+		goto end;
+	}
+
+	if (ast_sched_start_thread(sched)) {
+		ast_log(LOG_ERROR, "Unable to create scheduler context thread.\n");
+		goto end;
+	}
+
+	if (ast_sip_session_register_sdp_handler(&audio_sdp_handler, STR_AUDIO)) {
+		ast_log(LOG_ERROR, "Unable to register SDP handler for %s stream type\n", STR_AUDIO);
+		goto end;
+	}
+
+	if (ast_sip_session_register_sdp_handler(&video_sdp_handler, STR_VIDEO)) {
+		ast_log(LOG_ERROR, "Unable to register SDP handler for %s stream type\n", STR_VIDEO);
+		goto end;
+	}
+
+	ast_sip_session_register_supplement(&video_info_supplement);
+
+	return AST_MODULE_LOAD_SUCCESS;
+end:
+	unload_module();
+
+	return AST_MODULE_LOAD_FAILURE;
+}
+
+AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "SIP SDP RTP/AVP stream handler",
+		.load = load_module,
+		.unload = unload_module,
+		.load_pri = AST_MODPRI_CHANNEL_DRIVER,
+	);
diff --git a/res/res_sip_session.c b/res/res_sip_session.c
new file mode 100644
index 0000000000000000000000000000000000000000..6a31d9448147295076488434522f3afc95f35873
--- /dev/null
+++ b/res/res_sip_session.c
@@ -0,0 +1,1799 @@
+/*
+* Asterisk -- An open source telephony toolkit.
+*
+* Copyright (C) 2013, Digium, Inc.
+*
+* Mark Michelson <mmichelson@digium.com>
+*
+* See http://www.asterisk.org for more information about
+* the Asterisk project. Please do not directly contact
+* any of the maintainers of this project for assistance;
+* the project provides a web site, mailing lists and IRC
+* channels for your use.
+*
+* This program is free software, distributed under the terms of
+* the GNU General Public License Version 2. See the LICENSE file
+* at the top of the source tree.
+*/
+
+/*** MODULEINFO
+	<depend>pjproject</depend>
+	<depend>res_sip</depend>
+	<support_level>core</support_level>
+ ***/
+
+#include "asterisk.h"
+
+#include <pjsip.h>
+#include <pjsip_ua.h>
+#include <pjlib.h>
+
+#include "asterisk/res_sip.h"
+#include "asterisk/res_sip_session.h"
+#include "asterisk/datastore.h"
+#include "asterisk/module.h"
+#include "asterisk/logger.h"
+#include "asterisk/res_sip.h"
+#include "asterisk/astobj2.h"
+#include "asterisk/lock.h"
+#include "asterisk/uuid.h"
+#include "asterisk/pbx.h"
+#include "asterisk/taskprocessor.h"
+#include "asterisk/causes.h"
+
+#define SDP_HANDLER_BUCKETS 11
+
+/* Some forward declarations */
+static void handle_incoming_request(struct ast_sip_session *session, pjsip_rx_data *rdata);
+static void handle_incoming_response(struct ast_sip_session *session, pjsip_rx_data *rdata);
+static int handle_incoming(struct ast_sip_session *session, pjsip_rx_data *rdata);
+static void handle_outgoing_request(struct ast_sip_session *session, pjsip_tx_data *tdata);
+static void handle_outgoing_response(struct ast_sip_session *session, pjsip_tx_data *tdata);
+static void handle_outgoing(struct ast_sip_session *session, pjsip_tx_data *tdata);
+
+/*! \brief NAT hook for modifying outgoing messages with SDP */
+static struct ast_sip_nat_hook *nat_hook;
+
+/*!
+ * \brief Registered SDP stream handlers
+ *
+ * This container is keyed on stream types. Each
+ * object in the container is a linked list of
+ * handlers for the stream type.
+ */
+static struct ao2_container *sdp_handlers;
+
+/*!
+ * These are the objects in the sdp_handlers container
+ */
+struct sdp_handler_list {
+	/* The list of handlers to visit */
+	AST_LIST_HEAD_NOLOCK(, ast_sip_session_sdp_handler) list;
+	/* The handlers in this list handle streams of this type */
+	char stream_type[1];
+};
+
+static struct pjmedia_sdp_session *create_local_sdp(pjsip_inv_session *inv, struct ast_sip_session *session, const pjmedia_sdp_session *offer);
+
+static int sdp_handler_list_hash(const void *obj, int flags)
+{
+	const struct sdp_handler_list *handler_list = obj;
+	const char *stream_type = flags & OBJ_KEY ? obj : handler_list->stream_type;
+
+	return ast_str_hash(stream_type);
+}
+
+static int sdp_handler_list_cmp(void *obj, void *arg, int flags)
+{
+	struct sdp_handler_list *handler_list1 = obj;
+	struct sdp_handler_list *handler_list2 = arg;
+	const char *stream_type2 = flags & OBJ_KEY ? arg : handler_list2->stream_type;
+
+	return strcmp(handler_list1->stream_type, stream_type2) ? 0 : CMP_MATCH | CMP_STOP;
+}
+
+static int session_media_hash(const void *obj, int flags)
+{
+	const struct ast_sip_session_media *session_media = obj;
+	const char *stream_type = flags & OBJ_KEY ? obj : session_media->stream_type;
+
+	return ast_str_hash(stream_type);
+}
+
+static int session_media_cmp(void *obj, void *arg, int flags)
+{
+	struct ast_sip_session_media *session_media1 = obj;
+	struct ast_sip_session_media *session_media2 = arg;
+	const char *stream_type2 = flags & OBJ_KEY ? arg : session_media2->stream_type;
+
+	return strcmp(session_media1->stream_type, stream_type2) ? 0 : CMP_MATCH | CMP_STOP;
+}
+
+int ast_sip_session_register_sdp_handler(struct ast_sip_session_sdp_handler *handler, const char *stream_type)
+{
+	RAII_VAR(struct sdp_handler_list *, handler_list,
+			ao2_find(sdp_handlers, stream_type, OBJ_KEY), ao2_cleanup);
+	SCOPED_AO2LOCK(lock, sdp_handlers);
+
+	if (handler_list) {
+		struct ast_sip_session_sdp_handler *iter;
+		/* Check if this handler is already registered for this stream type */
+		AST_LIST_TRAVERSE(&handler_list->list, iter, next) {
+			if (!strcmp(iter->id, handler->id)) {
+				ast_log(LOG_WARNING, "Handler '%s' already registered for stream type '%s'.\n", handler->id, stream_type);
+				return -1;
+			}
+		}
+		AST_LIST_INSERT_TAIL(&handler_list->list, handler, next);
+		ast_debug(1, "Registered SDP stream handler '%s' for stream type '%s'\n", handler->id, stream_type); 
+		ast_module_ref(ast_module_info->self);
+		return 0;
+	}
+
+	/* No stream of this type has been registered yet, so we need to create a new list */
+	handler_list = ao2_alloc(sizeof(*handler_list) + strlen(stream_type), NULL);
+	if (!handler_list) {
+		return -1;
+	}
+	/* Safe use of strcpy */
+	strcpy(handler_list->stream_type, stream_type);
+	AST_LIST_HEAD_INIT_NOLOCK(&handler_list->list);
+	AST_LIST_INSERT_TAIL(&handler_list->list, handler, next);
+	if (!ao2_link(sdp_handlers, handler_list)) {
+		return -1;
+	}
+	ast_debug(1, "Registered SDP stream handler '%s' for stream type '%s'\n", handler->id, stream_type); 
+	ast_module_ref(ast_module_info->self);
+	return 0;
+}
+
+static int remove_handler(void *obj, void *arg, void *data, int flags)
+{
+	struct sdp_handler_list *handler_list = obj;
+	struct ast_sip_session_sdp_handler *handler = data;
+	struct ast_sip_session_sdp_handler *iter;
+	const char *stream_type = arg;
+
+	AST_LIST_TRAVERSE_SAFE_BEGIN(&handler_list->list, iter, next) {
+		if (!strcmp(iter->id, handler->id)) {
+			AST_LIST_REMOVE_CURRENT(next);
+			ast_debug(1, "Unregistered SDP stream handler '%s' for stream type '%s'\n", handler->id, stream_type);
+			ast_module_unref(ast_module_info->self);
+		}
+	}
+	AST_LIST_TRAVERSE_SAFE_END;
+
+	if (AST_LIST_EMPTY(&handler_list->list)) {
+		ast_debug(3, "No more handlers exist for stream type '%s'\n", stream_type);
+		return CMP_MATCH;
+	} else {
+		return CMP_STOP;
+	}
+}
+
+void ast_sip_session_unregister_sdp_handler(struct ast_sip_session_sdp_handler *handler, const char *stream_type)
+{
+	ao2_callback_data(sdp_handlers, OBJ_KEY | OBJ_UNLINK | OBJ_NODATA, remove_handler, (void *)stream_type, handler);
+}
+
+static int validate_port_hash(const void *obj, int flags)
+{
+	const int *port = obj;
+	return *port;
+}
+
+static int validate_port_cmp(void *obj, void *arg, int flags)
+{
+	int *port1 = obj;
+	int *port2 = arg;
+
+	return *port1 == *port2 ? CMP_MATCH | CMP_STOP : 0;
+}
+
+struct bundle_assoc {
+	int port;
+	char tag[1];
+};
+
+static int bundle_assoc_hash(const void *obj, int flags)
+{
+	const struct bundle_assoc *assoc = obj;
+	const char *tag = flags & OBJ_KEY ? obj : assoc->tag;
+
+	return ast_str_hash(tag);
+}
+
+static int bundle_assoc_cmp(void *obj, void *arg, int flags)
+{
+	struct bundle_assoc *assoc1 = obj;
+	struct bundle_assoc *assoc2 = arg;
+	const char *tag2 = flags & OBJ_KEY ? arg : assoc2->tag;
+
+	return strcmp(assoc1->tag, tag2) ? 0 : CMP_MATCH | CMP_STOP;
+}
+
+/* return must be ast_freed */
+static pjmedia_sdp_attr *media_get_mid(pjmedia_sdp_media *media)
+{
+	pjmedia_sdp_attr *attr = pjmedia_sdp_media_find_attr2(media, "mid", NULL);
+	if (!attr) {
+		return NULL;
+	}
+
+	return attr;
+}
+
+static int get_bundle_port(const pjmedia_sdp_session *sdp, const char *mid)
+{
+	int i;
+	for (i = 0; i < sdp->media_count; ++i) {
+		pjmedia_sdp_attr *mid_attr = media_get_mid(sdp->media[i]);
+		if (mid_attr && !pj_strcmp2(&mid_attr->value, mid)) {
+			return sdp->media[i]->desc.port;
+		}
+	}
+
+	return -1;
+}
+
+static int validate_incoming_sdp(const pjmedia_sdp_session *sdp)
+{
+	int i;
+	RAII_VAR(struct ao2_container *, portlist, ao2_container_alloc(5, validate_port_hash, validate_port_cmp), ao2_cleanup);
+	RAII_VAR(struct ao2_container *, bundle_assoc_list, ao2_container_alloc(5, bundle_assoc_hash, bundle_assoc_cmp), ao2_cleanup);
+
+	/* check for bundles (for websocket RTP multiplexing, there can be more than one) */
+	for (i = 0; i < sdp->attr_count; ++i) {
+		char *bundle_list;
+		int bundle_port = 0;
+		if (pj_stricmp2(&sdp->attr[i]->name, "group")) {
+			continue;
+		}
+
+		/* check to see if this group is a bundle */
+		if (7 >= sdp->attr[i]->value.slen || pj_strnicmp2(&sdp->attr[i]->value, "bundle ", 7)) {
+			continue;
+		}
+
+		bundle_list = ast_alloca(sdp->attr[i]->value.slen - 6);
+		strncpy(bundle_list, sdp->attr[i]->value.ptr + 7, sdp->attr[i]->value.slen - 7);
+		bundle_list[sdp->attr[i]->value.slen - 7] = '\0';
+		while (bundle_list) {
+			char *item;
+			RAII_VAR(struct bundle_assoc *, assoc, NULL, ao2_cleanup);
+			item = strsep(&bundle_list, " ,");
+			if (!bundle_port) {
+				RAII_VAR(int *, port, ao2_alloc(sizeof(int), NULL), ao2_cleanup);
+				RAII_VAR(int *, port_match, NULL, ao2_cleanup);
+				bundle_port = get_bundle_port(sdp, item);
+				if (bundle_port < 0) {
+					return -1;
+				}
+				port_match = ao2_find(portlist, &bundle_port, OBJ_KEY);
+				if (port_match) {
+					/* bundle port aready consumed by a different bundle */
+					return -1;
+				}
+				*port = bundle_port;
+				ao2_link(portlist, port);
+			}
+			assoc = ao2_alloc(sizeof(*assoc) + strlen(item), NULL);
+			if (!assoc) {
+				return -1;
+			}
+
+			/* safe use of strcpy */
+			strcpy(assoc->tag, item);
+			assoc->port = bundle_port;
+			ao2_link(bundle_assoc_list, assoc);
+		}
+	}
+
+	/* validate all streams */
+	for (i = 0; i < sdp->media_count; ++i) {
+		RAII_VAR(int *, port, ao2_alloc(sizeof(int), NULL), ao2_cleanup);
+		RAII_VAR(int *, port_match, NULL, ao2_cleanup);
+		RAII_VAR(int *, bundle_match, NULL, ao2_cleanup);
+		*port = sdp->media[i]->desc.port;
+		port_match = ao2_find(portlist, port, OBJ_KEY);
+		if (port_match) {
+			RAII_VAR(struct bundle_assoc *, assoc, NULL, ao2_cleanup);
+			pjmedia_sdp_attr *mid = media_get_mid(sdp->media[i]);
+			char *mid_val;
+
+			if (!mid) {
+				/* not part of a bundle */
+				return -1;
+			}
+
+			mid_val = ast_alloca(mid->value.slen + 1);
+			strncpy(mid_val, mid->value.ptr, mid->value.slen);
+			mid_val[mid->value.slen] = '\0';
+
+			assoc = ao2_find(bundle_assoc_list, mid_val, OBJ_KEY);
+			if (!assoc || assoc->port != *port) {
+				/* This port already exists elsewhere in the SDP
+				 * and is not an appropriate bundle port, fail
+				 * catastrophically */
+				return -1;
+			}
+		}
+		ao2_link(portlist, port);
+	}
+	return 0;
+}
+
+static int handle_incoming_sdp(struct ast_sip_session *session, const pjmedia_sdp_session *sdp)
+{
+	int i;
+	if (validate_incoming_sdp(sdp)) {
+		return -1;
+	}
+
+	for (i = 0; i < sdp->media_count; ++i) {
+		/* See if there are registered handlers for this media stream type */
+		char media[20];
+		struct ast_sip_session_sdp_handler *handler;
+		RAII_VAR(struct sdp_handler_list *, handler_list, NULL, ao2_cleanup);
+
+		/* We need a null-terminated version of the media string */
+		ast_copy_pj_str(media, &sdp->media[i]->desc.media, sizeof(media));
+
+		handler_list = ao2_find(sdp_handlers, media, OBJ_KEY);
+		if (!handler_list) {
+			ast_debug(1, "No registered SDP handlers for media type '%s'\n", media);
+			continue;
+		}
+		AST_LIST_TRAVERSE(&handler_list->list, handler, next) {
+			int res;
+			RAII_VAR(struct ast_sip_session_media *, session_media, NULL, ao2_cleanup);
+			session_media = ao2_find(session->media, handler_list->stream_type, OBJ_KEY);
+			if (!session_media || session_media->handler) {
+				/* There is only one slot for this stream type and it has already been claimed
+				 * so it will go unhandled */
+				break;
+			}
+			res = handler->negotiate_incoming_sdp_stream(session, session_media, sdp, sdp->media[i]);
+			if (res < 0) {
+				/* Catastrophic failure. Abort! */
+				return -1;
+			}
+			if (res > 0) {
+				/* Handled by this handler. Move to the next stream */
+				session_media->handler = handler;
+				break;
+			}
+		}
+	}
+	return 0;
+}
+
+struct handle_negotiated_sdp_cb {
+	struct ast_sip_session *session;
+	const pjmedia_sdp_session *local;
+	const pjmedia_sdp_session *remote;
+};
+
+static int handle_negotiated_sdp_session_media(void *obj, void *arg, int flags)
+{
+	struct ast_sip_session_media *session_media = obj;
+	struct handle_negotiated_sdp_cb *callback_data = arg;
+	struct ast_sip_session *session = callback_data->session;
+	const pjmedia_sdp_session *local = callback_data->local;
+	const pjmedia_sdp_session *remote = callback_data->remote;
+	int i;
+
+	for (i = 0; i < local->media_count; ++i) {
+		/* See if there are registered handlers for this media stream type */
+		char media[20];
+		struct ast_sip_session_sdp_handler *handler;
+		RAII_VAR(struct sdp_handler_list *, handler_list, NULL, ao2_cleanup);
+
+		/* We need a null-terminated version of the media string */
+		ast_copy_pj_str(media, &local->media[i]->desc.media, sizeof(media));
+
+		/* stream type doesn't match the one we're looking to fill */
+		if (strcasecmp(session_media->stream_type, media)) {
+			continue;
+		}
+
+		handler = session_media->handler;
+		if (handler) {
+			int res = handler->apply_negotiated_sdp_stream(session, session_media, local, local->media[i], remote, remote->media[i]);
+			if (res >= 0) {
+				return CMP_MATCH;
+			}
+			return 0;
+		}
+
+		handler_list = ao2_find(sdp_handlers, media, OBJ_KEY);
+		if (!handler_list) {
+			ast_debug(1, "No registered SDP handlers for media type '%s'\n", media);
+			continue;
+		}
+		AST_LIST_TRAVERSE(&handler_list->list, handler, next) {
+			int res = handler->apply_negotiated_sdp_stream(session, session_media, local, local->media[i], remote, remote->media[i]);
+			if (res < 0) {
+				/* Catastrophic failure. Abort! */
+				return 0;
+			}
+			if (res > 0) {
+				/* Handled by this handler. Move to the next stream */
+				session_media->handler = handler;
+				return CMP_MATCH;
+			}
+		}
+	}
+	return CMP_MATCH;
+}
+
+static int handle_negotiated_sdp(struct ast_sip_session *session, const pjmedia_sdp_session *local, const pjmedia_sdp_session *remote)
+{
+	RAII_VAR(struct ao2_iterator *, successful, NULL, ao2_iterator_cleanup);
+	struct handle_negotiated_sdp_cb callback_data = {
+		.session = session,
+		.local = local,
+		.remote = remote,
+	};
+
+	successful = ao2_callback(session->media, OBJ_MULTIPLE, handle_negotiated_sdp_session_media, &callback_data);
+	if (successful && ao2_container_count(successful->c) == ao2_container_count(session->media)) {
+		/* Nothing experienced a catastrophic failure */
+		return 0;
+	}
+	return -1;
+}
+
+AST_RWLIST_HEAD_STATIC(session_supplements, ast_sip_session_supplement);
+
+int ast_sip_session_register_supplement(struct ast_sip_session_supplement *supplement)
+{
+	struct ast_sip_session_supplement *iter;
+	int inserted = 0;
+	SCOPED_LOCK(lock, &session_supplements, AST_RWLIST_WRLOCK, AST_RWLIST_UNLOCK);
+
+	AST_RWLIST_TRAVERSE_SAFE_BEGIN(&session_supplements, iter, next) {
+		if (iter->priority > supplement->priority) {
+			AST_RWLIST_INSERT_BEFORE_CURRENT(supplement, next);
+			inserted = 1;
+			break;
+		}
+	}
+	AST_RWLIST_TRAVERSE_SAFE_END;
+
+	if (!inserted) {
+		AST_RWLIST_INSERT_TAIL(&session_supplements, supplement, next);
+	}
+	ast_module_ref(ast_module_info->self);
+	return 0;
+}
+
+void ast_sip_session_unregister_supplement(struct ast_sip_session_supplement *supplement)
+{
+	struct ast_sip_session_supplement *iter;
+	SCOPED_LOCK(lock, &session_supplements, AST_RWLIST_WRLOCK, AST_RWLIST_UNLOCK);
+	AST_RWLIST_TRAVERSE_SAFE_BEGIN(&session_supplements, iter, next) {
+		if (supplement == iter) {
+			AST_RWLIST_REMOVE_CURRENT(next);
+			ast_module_unref(ast_module_info->self);
+			break;
+		}
+	}
+	AST_RWLIST_TRAVERSE_SAFE_END;
+}
+
+static struct ast_sip_session_supplement *supplement_dup(const struct ast_sip_session_supplement *src)
+{
+	struct ast_sip_session_supplement *dst = ast_calloc(1, sizeof(*dst));
+	if (!dst) {
+		return NULL;
+	}
+	/* Will need to revisit if shallow copy becomes an issue */
+	*dst = *src;
+	return dst;
+}
+
+#define DATASTORE_BUCKETS 53
+#define MEDIA_BUCKETS 7
+
+static void session_datastore_destroy(void *obj)
+{
+	struct ast_datastore *datastore = obj;
+
+	/* Using the destroy function (if present) destroy the data */
+	if (datastore->info->destroy != NULL && datastore->data != NULL) {
+		datastore->info->destroy(datastore->data);
+		datastore->data = NULL;
+	}
+
+	ast_free((void *) datastore->uid);
+	datastore->uid = NULL;
+}
+
+struct ast_datastore *ast_sip_session_alloc_datastore(const struct ast_datastore_info *info, const char *uid)
+{
+	RAII_VAR(struct ast_datastore *, datastore, NULL, ao2_cleanup);
+	const char *uid_ptr = uid;
+
+	if (!info) {
+		return NULL;
+	}
+
+	datastore = ao2_alloc(sizeof(*datastore), session_datastore_destroy);
+	if (!datastore) {
+		return NULL;
+	}
+
+	datastore->info = info;
+	if (ast_strlen_zero(uid)) {
+		/* They didn't provide an ID so we'll provide one ourself */
+		struct ast_uuid *uuid = ast_uuid_generate();
+		char uuid_buf[AST_UUID_STR_LEN];
+		if (!uuid) {
+			return NULL;
+		}
+		uid_ptr = ast_uuid_to_str(uuid, uuid_buf, sizeof(uuid_buf));
+		ast_free(uuid);
+	}
+
+	datastore->uid = ast_strdup(uid_ptr);
+	if (!datastore->uid) {
+		return NULL;
+	}
+
+	ao2_ref(datastore, +1);
+	return datastore;
+}
+
+int ast_sip_session_add_datastore(struct ast_sip_session *session, struct ast_datastore *datastore)
+{
+	ast_assert(datastore != NULL);
+	ast_assert(datastore->info != NULL);
+	ast_assert(ast_strlen_zero(datastore->uid) == 0);
+
+	if (!ao2_link(session->datastores, datastore)) {
+		return -1;
+	}
+	return 0;
+}
+
+struct ast_datastore *ast_sip_session_get_datastore(struct ast_sip_session *session, const char *name)
+{
+	return ao2_find(session->datastores, name, OBJ_KEY);
+}
+
+void ast_sip_session_remove_datastore(struct ast_sip_session *session, const char *name)
+{
+	ao2_callback(session->datastores, OBJ_KEY | OBJ_UNLINK | OBJ_NODATA, NULL, (void *) name);
+}
+
+int ast_sip_session_get_identity(struct pjsip_rx_data *rdata, struct ast_party_id *id)
+{
+	/* XXX STUB
+	 * This is low-priority as far as getting SIP working is concerned, so this
+	 * will be addressed later.
+	 *
+	 * The idea here will be that the rdata will be examined for headers such as
+	 * P-Asserted-Identity, Remote-Party-ID, and From in order to determine Identity
+	 * information.
+	 *
+	 * For reference, Asterisk SCF code does something very similar to this, except in
+	 * C++ and using its version of the ast_party_id struct, so using it as a basis
+	 * would be a smart idea here.
+	 */
+	return 0;
+}
+
+/*!
+ * \brief Structure used for sending delayed requests
+ *
+ * Requests are typically delayed because the current transaction
+ * state of an INVITE. Once the pending INVITE transaction terminates,
+ * the delayed request will be sent
+ */
+struct ast_sip_session_delayed_request {
+	/*! Method of the request */
+	char method[15];
+	/*! Callback to call when the delayed request is created. */
+	ast_sip_session_request_creation_cb on_request_creation;
+	/*! Callback to call when the delayed request receives a response */
+	ast_sip_session_response_cb on_response;
+	/*! Request to send */
+	pjsip_tx_data *tdata;
+	AST_LIST_ENTRY(ast_sip_session_delayed_request) next;
+};
+
+static struct ast_sip_session_delayed_request *delayed_request_alloc(const char *method,
+		ast_sip_session_request_creation_cb on_request_creation,
+		ast_sip_session_response_cb on_response,
+		pjsip_tx_data *tdata)
+{
+	struct ast_sip_session_delayed_request *delay = ast_calloc(1, sizeof(*delay));
+	if (!delay) {
+		return NULL;
+	}
+	ast_copy_string(delay->method, method, sizeof(delay->method));
+	delay->on_request_creation = on_request_creation;
+	delay->on_response = on_response;
+	delay->tdata = tdata;
+	return delay;
+}
+
+static int send_delayed_request(struct ast_sip_session *session, struct ast_sip_session_delayed_request *delay)
+{
+	ast_debug(3, "Sending delayed %s request to %s\n", delay->method, ast_sorcery_object_get_id(session->endpoint));
+
+	if (delay->tdata) {
+		ast_sip_session_send_request_with_cb(session, delay->tdata, delay->on_response);
+		return 0;
+	}
+
+	if (!strcmp(delay->method, "INVITE")) {
+		ast_sip_session_refresh(session, delay->on_request_creation,
+				delay->on_response, AST_SIP_SESSION_REFRESH_METHOD_INVITE, 1);
+	} else if (!strcmp(delay->method, "UPDATE")) {
+		ast_sip_session_refresh(session, delay->on_request_creation,
+				delay->on_response, AST_SIP_SESSION_REFRESH_METHOD_UPDATE, 1);
+	} else {
+		ast_log(LOG_WARNING, "Unexpected delayed %s request with no existing request structure\n", delay->method);
+		return -1;
+	}
+	return 0;
+}
+
+static int queued_delayed_request_send(void *data)
+{
+	RAII_VAR(struct ast_sip_session *, session, data, ao2_cleanup);
+	RAII_VAR(struct ast_sip_session_delayed_request *, delay, NULL, ast_free_ptr);
+
+	delay = AST_LIST_REMOVE_HEAD(&session->delayed_requests, next);
+	if (!delay) {
+		return 0;
+	}
+
+	return send_delayed_request(session, delay);
+}
+
+static void queue_delayed_request(struct ast_sip_session *session)
+{
+	if (AST_LIST_EMPTY(&session->delayed_requests)) {
+		/* No delayed request to send, so just return */
+		return;
+	}
+
+	ast_debug(3, "Queuing delayed request to run for %s\n",
+			ast_sorcery_object_get_id(session->endpoint));
+
+	ao2_ref(session, +1);
+	ast_sip_push_task(session->serializer, queued_delayed_request_send, session);
+}
+
+static int delay_request(struct ast_sip_session *session, ast_sip_session_request_creation_cb on_request,
+		ast_sip_session_response_cb on_response, const char *method, pjsip_tx_data *tdata)
+{
+	struct ast_sip_session_delayed_request *delay = delayed_request_alloc(method,
+			on_request, on_response, tdata);
+
+	if (!delay) {
+		return -1;
+	}
+
+	AST_LIST_INSERT_TAIL(&session->delayed_requests, delay, next);
+	return 0;
+}
+
+static pjmedia_sdp_session *generate_session_refresh_sdp(struct ast_sip_session *session)
+{
+	pjsip_inv_session *inv_session = session->inv_session;
+	const pjmedia_sdp_session *previous_sdp;
+
+	if (pjmedia_sdp_neg_was_answer_remote(inv_session->neg)) {
+		pjmedia_sdp_neg_get_active_remote(inv_session->neg, &previous_sdp);
+	} else {
+		pjmedia_sdp_neg_get_active_local(inv_session->neg, &previous_sdp);
+	}
+	return create_local_sdp(inv_session, session, previous_sdp);
+}
+
+int ast_sip_session_refresh(struct ast_sip_session *session,
+		ast_sip_session_request_creation_cb on_request_creation, ast_sip_session_response_cb on_response,
+		enum ast_sip_session_refresh_method method, int generate_new_sdp)
+{
+	pjsip_inv_session *inv_session = session->inv_session;
+	pjmedia_sdp_session *new_sdp = NULL;
+	pjsip_tx_data *tdata;
+
+	if (inv_session->state == PJSIP_INV_STATE_DISCONNECTED) {
+		/* Don't try to do anything with a hung-up call */
+		ast_debug(3, "Not sending reinvite to %s because of disconnected state...\n",
+				ast_sorcery_object_get_id(session->endpoint));
+		return 0;
+	}
+
+	if (inv_session->invite_tsx) {
+		/* We can't send a reinvite yet, so delay it */
+		ast_debug(3, "Delaying sending reinvite to %s because of outstanding transaction...\n",
+				ast_sorcery_object_get_id(session->endpoint));
+		return delay_request(session, on_request_creation, on_response, "INVITE", NULL);
+	}
+
+	if (generate_new_sdp) {
+		new_sdp = generate_session_refresh_sdp(session);
+		if (!new_sdp) {
+			ast_log(LOG_ERROR, "Failed to generate session refresh SDP. Not sending session refresh\n");
+			return -1;
+		}
+	}
+
+	if (method == AST_SIP_SESSION_REFRESH_METHOD_INVITE) {
+		if (pjsip_inv_reinvite(inv_session, NULL, new_sdp, &tdata)) {
+			ast_log(LOG_WARNING, "Failed to create reinvite properly.\n");
+			return -1;
+		}
+	} else if (pjsip_inv_update(inv_session, NULL, new_sdp, &tdata)) {
+		ast_log(LOG_WARNING, "Failed to create UPDATE properly.\n");
+		return -1;
+	}
+	if (on_request_creation) {
+		if (on_request_creation(session, tdata)) {
+			return -1;
+		}
+	}
+	ast_sip_session_send_request_with_cb(session, tdata, on_response);
+	return 0;
+}
+
+void ast_sip_session_send_response(struct ast_sip_session *session, pjsip_tx_data *tdata)
+{
+	handle_outgoing_response(session, tdata);
+	pjsip_inv_send_msg(session->inv_session, tdata);
+	return;
+}
+
+static pj_status_t session_load(pjsip_endpoint *endpt);
+static pj_status_t session_start(void);
+static pj_status_t session_stop(void);
+static pj_status_t session_unload(void);
+static pj_bool_t session_on_rx_request(pjsip_rx_data *rdata);
+
+static pjsip_module session_module = {
+	.name = {"Session Module", 14},
+	.priority = PJSIP_MOD_PRIORITY_APPLICATION,
+	.load = session_load,
+	.unload = session_unload,
+	.start = session_start,
+	.stop = session_stop,
+	.on_rx_request = session_on_rx_request,
+};
+
+void ast_sip_session_send_request_with_cb(struct ast_sip_session *session, pjsip_tx_data *tdata,
+		ast_sip_session_response_cb on_response)
+{
+	pjsip_inv_session *inv_session = session->inv_session;
+
+	if (inv_session->state == PJSIP_INV_STATE_DISCONNECTED) {
+		/* Don't try to do anything with a hung-up call */
+		return;
+	}
+
+	tdata->mod_data[session_module.id] = on_response;
+	handle_outgoing_request(session, tdata);
+	pjsip_inv_send_msg(session->inv_session, tdata);
+	return;
+}
+
+void ast_sip_session_send_request(struct ast_sip_session *session, pjsip_tx_data *tdata)
+{
+	ast_sip_session_send_request_with_cb(session, tdata, NULL);
+}
+
+/*!
+ * \brief Called when the PJSIP core loads us
+ *
+ * Since we already have Asterisk's fine module load/unload framework
+ * in use, we don't need to do anything special here.
+ */
+static pj_status_t session_load(pjsip_endpoint *endpt)
+{
+	return PJ_SUCCESS;
+}
+
+/*!
+ * \brief Called when the PJSIP core starts us
+ *
+ * Since we already have Asterisk's fine module load/unload framework
+ * in use, we don't need to do anything special here.
+ */
+static pj_status_t session_start(void)
+{
+	return PJ_SUCCESS;
+}
+
+/*!
+ * \brief Called when the PJSIP core stops us
+ *
+ * Since we already have Asterisk's fine module load/unload framework
+ * in use, we don't need to do anything special here.
+ */
+static pj_status_t session_stop(void)
+{
+	return PJ_SUCCESS;
+}
+
+/*!
+ * \brief Called when the PJSIP core unloads us
+ *
+ * Since we already have Asterisk's fine module load/unload framework
+ * in use, we don't need to do anything special here.
+ */
+static pj_status_t session_unload(void)
+{
+	return PJ_SUCCESS;
+}
+
+static int datastore_hash(const void *obj, int flags)
+{
+	const struct ast_datastore *datastore = obj;
+	const char *uid = flags & OBJ_KEY ? obj : datastore->uid;
+
+	ast_assert(uid != NULL);
+
+	return ast_str_hash(uid);
+}
+
+static int datastore_cmp(void *obj, void *arg, int flags)
+{
+	const struct ast_datastore *datastore1 = obj;
+	const struct ast_datastore *datastore2 = arg;
+	const char *uid2 = flags & OBJ_KEY ? arg : datastore2->uid;
+
+	ast_assert(datastore1->uid != NULL);
+	ast_assert(uid2 != NULL);
+
+	return strcmp(datastore1->uid, uid2) ? 0 : CMP_MATCH | CMP_STOP;
+}
+
+static void session_media_dtor(void *obj)
+{
+	struct ast_sip_session_media *session_media = obj;
+	if (session_media->handler) {
+		session_media->handler->stream_destroy(session_media);
+	}
+}
+
+static void session_destructor(void *obj)
+{
+	struct ast_sip_session *session = obj;
+	struct ast_sip_session_supplement *supplement;
+	struct ast_sip_session_delayed_request *delay;
+
+	ast_debug(3, "Destroying SIP session with endpoint %s\n",
+			ast_sorcery_object_get_id(session->endpoint));
+
+	while ((supplement = AST_LIST_REMOVE_HEAD(&session->supplements, next))) {
+		if (supplement->session_destroy) {
+			supplement->session_destroy(session);
+		}
+		ast_free(supplement);
+	}
+
+	ast_taskprocessor_unreference(session->serializer);
+	ao2_cleanup(session->datastores);
+	ao2_cleanup(session->media);
+	AST_LIST_HEAD_DESTROY(&session->supplements);
+	while ((delay = AST_LIST_REMOVE_HEAD(&session->delayed_requests, next))) {
+		ast_free(delay);
+	}
+	ast_party_id_free(&session->id);
+	ao2_cleanup(session->endpoint);
+	ast_format_cap_destroy(session->req_caps);
+}
+
+static int add_supplements(struct ast_sip_session *session)
+{
+	struct ast_sip_session_supplement *iter;
+	SCOPED_LOCK(lock, &session_supplements, AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK);
+
+	AST_RWLIST_TRAVERSE(&session_supplements, iter, next) {
+		struct ast_sip_session_supplement *copy = supplement_dup(iter);
+		if (!copy) {
+			return -1;
+		}
+		AST_LIST_INSERT_TAIL(&session->supplements, copy, next);
+	}
+	return 0;
+}
+
+static int add_session_media(void *obj, void *arg, int flags)
+{
+	struct sdp_handler_list *handler_list = obj;
+	struct ast_sip_session * session = arg;
+	RAII_VAR(struct ast_sip_session_media *, session_media, NULL, ao2_cleanup);
+	session_media = ao2_alloc(sizeof(*session_media) + strlen(handler_list->stream_type), session_media_dtor);
+	if (!session_media) {
+		return CMP_STOP;
+	}
+	/* Safe use of strcpy */
+	strcpy(session_media->stream_type, handler_list->stream_type);
+	ao2_link(session->media, session_media);
+	return 0;
+}
+
+struct ast_sip_session *ast_sip_session_alloc(struct ast_sip_endpoint *endpoint, pjsip_inv_session *inv_session)
+{
+	RAII_VAR(struct ast_sip_session *, session, ao2_alloc(sizeof(*session), session_destructor), ao2_cleanup);
+	struct ast_sip_session_supplement *iter;
+	if (!session) {
+		return NULL;
+	}
+	AST_LIST_HEAD_INIT(&session->supplements);
+	session->datastores = ao2_container_alloc(DATASTORE_BUCKETS, datastore_hash, datastore_cmp);
+	if (!session->datastores) {
+		return NULL;
+	}
+
+	session->media = ao2_container_alloc(MEDIA_BUCKETS, session_media_hash, session_media_cmp);
+	if (!session->media) {
+		return NULL;
+	}
+	/* fill session->media with available types */
+	ao2_callback(sdp_handlers, OBJ_NODATA, add_session_media, session);
+
+	session->serializer = ast_sip_create_serializer();
+	if (!session->serializer) {
+		return NULL;
+	}
+	ast_sip_dialog_set_serializer(inv_session->dlg, session->serializer);
+	ast_sip_dialog_set_endpoint(inv_session->dlg, endpoint);
+	ao2_ref(endpoint, +1);
+	inv_session->mod_data[session_module.id] = session;
+	session->endpoint = endpoint;
+	session->inv_session = inv_session;
+	session->req_caps = ast_format_cap_alloc_nolock();
+
+	if (add_supplements(session)) {
+		return NULL;
+	}
+	AST_LIST_TRAVERSE(&session->supplements, iter, next) {
+		if (iter->session_begin) {
+			iter->session_begin(session);
+		}
+	}
+	session->direct_media_cap = ast_format_cap_alloc_nolock();
+	AST_LIST_HEAD_INIT_NOLOCK(&session->delayed_requests);
+	ast_party_id_init(&session->id);
+	ao2_ref(session, +1);
+	return session;
+}
+
+static int session_outbound_auth(pjsip_dialog *dlg, pjsip_tx_data *tdata, void *user_data)
+{
+	pjsip_inv_session *inv = pjsip_dlg_get_inv_session(dlg);
+	struct ast_sip_session *session = inv->mod_data[session_module.id];
+
+	if (inv->state < PJSIP_INV_STATE_CONFIRMED && tdata->msg->line.req.method.id == PJSIP_INVITE_METHOD) {
+		pjsip_inv_uac_restart(inv, PJ_TRUE);
+	}
+	ast_sip_session_send_request(session, tdata);
+	return 0;
+}
+
+struct ast_sip_session *ast_sip_session_create_outgoing(struct ast_sip_endpoint *endpoint, const char *location, const char *request_user, struct ast_format_cap *req_caps)
+{
+	const char *uri = NULL;
+	RAII_VAR(struct ast_sip_contact *, contact, NULL, ao2_cleanup);
+	pjsip_timer_setting timer;
+	pjsip_dialog *dlg;
+	struct pjsip_inv_session *inv_session;
+	RAII_VAR(struct ast_sip_session *, session, NULL, ao2_cleanup);
+	pjmedia_sdp_session *offer;
+
+	/* If no location has been provided use the AOR list from the endpoint itself */
+	location = S_OR(location, endpoint->aors);
+
+	contact = ast_sip_location_retrieve_contact_from_aor_list(location);
+	if (!contact || ast_strlen_zero(contact->uri)) {
+		uri = location;
+	} else {
+		uri = contact->uri;
+	}
+
+	/* If we still have no URI to dial fail to create the session */
+	if (ast_strlen_zero(uri)) {
+		return NULL;
+	}
+
+	if (!(dlg = ast_sip_create_dialog(endpoint, uri, request_user))) {
+		return NULL;
+	}
+
+	if (ast_sip_dialog_setup_outbound_authentication(dlg, endpoint, session_outbound_auth, NULL)) {
+		pjsip_dlg_terminate(dlg);
+		return NULL;
+	}
+
+	if (pjsip_inv_create_uac(dlg, NULL, endpoint->extensions, &inv_session) != PJ_SUCCESS) {
+		pjsip_dlg_terminate(dlg);
+		return NULL;
+	}
+
+	pjsip_timer_setting_default(&timer);
+	timer.min_se = endpoint->min_se;
+	timer.sess_expires = endpoint->sess_expires;
+	pjsip_timer_init_session(inv_session, &timer);
+
+	if (!(session = ast_sip_session_alloc(endpoint, inv_session))) {
+		pjsip_inv_terminate(inv_session, 500, PJ_FALSE);
+		return NULL;
+	}
+
+	ast_format_cap_copy(session->req_caps, req_caps);
+	if ((pjsip_dlg_add_usage(dlg, &session_module, NULL) != PJ_SUCCESS) ||
+	    !(offer = create_local_sdp(inv_session, session, NULL))) {
+		pjsip_inv_terminate(inv_session, 500, PJ_FALSE);
+		return NULL;
+	}
+
+	pjsip_inv_set_local_sdp(inv_session, offer);
+
+	ao2_ref(session, +1);
+	return session;
+}
+
+enum sip_get_destination_result {
+	/*! The extension was successfully found */
+	SIP_GET_DEST_EXTEN_FOUND,
+	/*! The extension specified in the RURI was not found */
+	SIP_GET_DEST_EXTEN_NOT_FOUND,
+	/*! The extension specified in the RURI was a partial match */
+	SIP_GET_DEST_EXTEN_PARTIAL,
+	/*! The RURI is of an unsupported scheme */
+	SIP_GET_DEST_UNSUPPORTED_URI,
+};
+
+/*!
+ * \brief Determine where in the dialplan a call should go
+ *
+ * This uses the username in the request URI to try to match
+ * an extension in the endpoint's configured context in order
+ * to route the call.
+ *
+ * \param session The inbound SIP session
+ * \param rdata The SIP INVITE
+ */
+static enum sip_get_destination_result get_destination(struct ast_sip_session *session, pjsip_rx_data *rdata)
+{
+	pjsip_uri *ruri = rdata->msg_info.msg->line.req.uri;
+	pjsip_sip_uri *sip_ruri;
+	if (!PJSIP_URI_SCHEME_IS_SIP(ruri) && !PJSIP_URI_SCHEME_IS_SIPS(ruri)) {
+		return SIP_GET_DEST_UNSUPPORTED_URI;
+	}
+	sip_ruri = pjsip_uri_get_uri(ruri);
+	ast_copy_pj_str(session->exten, &sip_ruri->user, sizeof(session->exten));
+	if (ast_exists_extension(NULL, session->endpoint->context, session->exten, 1, NULL)) {
+		return SIP_GET_DEST_EXTEN_FOUND;
+	}
+	/* XXX In reality, we'll likely have further options so that partial matches
+	 * can be indicated here, but for getting something up and running, we're going
+	 * to return a "not exists" error here.
+	 */
+	return SIP_GET_DEST_EXTEN_NOT_FOUND;
+}
+
+static pjsip_inv_session *pre_session_setup(pjsip_rx_data *rdata, const struct ast_sip_endpoint *endpoint)
+{
+	pjsip_tx_data *tdata;
+	pjsip_dialog *dlg;
+	pjsip_inv_session *inv_session;
+	unsigned int options = endpoint->extensions;
+
+	if (pjsip_inv_verify_request(rdata, &options, NULL, NULL, ast_sip_get_pjsip_endpoint(), &tdata) != PJ_SUCCESS) {
+		if (tdata) {
+			pjsip_endpt_send_response2(ast_sip_get_pjsip_endpoint(), rdata, tdata, NULL, NULL);
+		} else {
+			pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 500, NULL, NULL, NULL);
+		}
+		return NULL;
+	}
+	if (pjsip_dlg_create_uas(pjsip_ua_instance(), rdata, NULL, &dlg) != PJ_SUCCESS) {
+		pjsip_endpt_send_response2(ast_sip_get_pjsip_endpoint(), rdata, tdata, NULL, NULL);
+        return NULL;
+	}
+	if (pjsip_inv_create_uas(dlg, rdata, NULL, 0, &inv_session) != PJ_SUCCESS) {
+		pjsip_endpt_send_response2(ast_sip_get_pjsip_endpoint(), rdata, tdata, NULL, NULL);
+		pjsip_dlg_terminate(dlg);
+		return NULL;
+	}
+	if (pjsip_dlg_add_usage(dlg, &session_module, NULL) != PJ_SUCCESS) {
+		if (pjsip_inv_initial_answer(inv_session, rdata, 500, NULL, NULL, &tdata) != PJ_SUCCESS) {
+			pjsip_inv_terminate(inv_session, 500, PJ_FALSE);
+		}
+		pjsip_inv_send_msg(inv_session, tdata);
+		return NULL;
+	}
+	return inv_session;
+}
+
+static void handle_new_invite_request(pjsip_rx_data *rdata)
+{
+	RAII_VAR(struct ast_sip_endpoint *, endpoint,
+			ast_pjsip_rdata_get_endpoint(rdata), ao2_cleanup);
+	pjsip_tx_data *tdata = NULL;
+	pjsip_inv_session *inv_session = NULL;
+	struct ast_sip_session *session = NULL;
+	pjsip_timer_setting timer;
+	pjsip_rdata_sdp_info *sdp_info;
+	pjmedia_sdp_session *local = NULL;
+
+	ast_assert(endpoint != NULL);
+
+	inv_session = pre_session_setup(rdata, endpoint);
+	if (!inv_session) {
+		/* pre_session_setup() returns a response on failure */
+		return;
+	}
+
+	session = ast_sip_session_alloc(endpoint, inv_session);
+	if (!session) {
+		if (pjsip_inv_initial_answer(inv_session, rdata, 500, NULL, NULL, &tdata) == PJ_SUCCESS) {
+			pjsip_inv_terminate(inv_session, 500, PJ_FALSE);
+		} else {
+			pjsip_inv_send_msg(inv_session, tdata);
+		}
+		return;
+	}
+
+	/* From this point on, any calls to pjsip_inv_terminate have the last argument as PJ_TRUE
+	 * so that we will be notified so we can destroy the session properly
+	 */
+
+	switch (get_destination(session, rdata)) {
+	case SIP_GET_DEST_EXTEN_FOUND:
+		/* Things worked. Keep going */
+		break;
+	case SIP_GET_DEST_UNSUPPORTED_URI:
+		if (pjsip_inv_initial_answer(inv_session, rdata, 416, NULL, NULL, &tdata) == PJ_SUCCESS) {
+			ast_sip_session_send_response(session, tdata);
+		} else  {
+			pjsip_inv_terminate(inv_session, 416, PJ_TRUE);
+		}
+		return;
+	case SIP_GET_DEST_EXTEN_NOT_FOUND:
+	case SIP_GET_DEST_EXTEN_PARTIAL:
+	default:
+		if (pjsip_inv_initial_answer(inv_session, rdata, 404, NULL, NULL, &tdata) == PJ_SUCCESS) {
+			ast_sip_session_send_response(session, tdata);
+		} else  {
+			pjsip_inv_terminate(inv_session, 404, PJ_TRUE);
+		}
+		return;
+	};
+
+	if ((sdp_info = pjsip_rdata_get_sdp_info(rdata)) && (sdp_info->sdp_err == PJ_SUCCESS) && sdp_info->sdp) {
+		if (handle_incoming_sdp(session, sdp_info->sdp)) {
+			if (pjsip_inv_initial_answer(inv_session, rdata, 488, NULL, NULL, &tdata) == PJ_SUCCESS) {
+				ast_sip_session_send_response(session, tdata);
+			} else  {
+				pjsip_inv_terminate(inv_session, 488, PJ_TRUE);
+			}
+			return;
+		}
+		/* We are creating a local SDP which is an answer to their offer */
+		local = create_local_sdp(inv_session, session, sdp_info->sdp);
+	} else {
+		/* We are creating a local SDP which is an offer */
+		local = create_local_sdp(inv_session, session, NULL);
+	}
+
+	/* If we were unable to create a local SDP terminate the session early, it won't go anywhere */
+	if (!local) {
+		if (pjsip_inv_initial_answer(inv_session, rdata, 500, NULL, NULL, &tdata) == PJ_SUCCESS) {
+			ast_sip_session_send_response(session, tdata);
+		} else  {
+			pjsip_inv_terminate(inv_session, 500, PJ_TRUE);
+		}
+		return;
+	} else {
+		pjsip_inv_set_local_sdp(inv_session, local);
+	}
+
+	pjsip_timer_setting_default(&timer);
+	timer.min_se = endpoint->min_se;
+	timer.sess_expires = endpoint->sess_expires;
+	pjsip_timer_init_session(inv_session, &timer);
+
+	/* At this point, we've verified what we can, so let's go ahead and send a 100 Trying out */
+	if (pjsip_inv_initial_answer(inv_session, rdata, 100, NULL, NULL, &tdata) != PJ_SUCCESS) {
+		pjsip_inv_terminate(inv_session, 500, PJ_TRUE);
+		return;
+	}
+	ast_sip_session_send_response(session, tdata);
+
+	handle_incoming_request(session, rdata);
+}
+
+static int has_supplement(struct ast_sip_session *session, pjsip_rx_data *rdata)
+{
+	struct ast_sip_session_supplement *supplement;
+	struct pjsip_method *method = &rdata->msg_info.msg->line.req.method;
+
+	if (!session) {
+		return PJ_FALSE;
+	}
+
+	AST_LIST_TRAVERSE(&session->supplements, supplement, next) {
+		if (!supplement->method || !pj_strcmp2(&method->name, supplement->method)) {
+			return PJ_TRUE;
+		}
+	}
+	return PJ_FALSE;
+}
+/*!
+ * \brief Called when a new SIP request comes into PJSIP
+ *
+ * This function is called under two circumstances
+ * 1) An out-of-dialog request is received by PJSIP
+ * 2) An in-dialog request that the inv_session layer does not
+ *    handle is received (such as an in-dialog INFO)
+ *
+ * In all cases, there is very little we actually do in this function
+ * 1) For requests we don't handle, we return PJ_FALSE
+ * 2) For new INVITEs, throw the work into the SIP threadpool to be done
+ *    there to free up the thread(s) handling incoming requests
+ * 3) For in-dialog requests we handle, we defer handling them until the
+ *    on_inv_state_change() callback instead (where we will end up putting
+ *    them into the threadpool).
+ */
+static pj_bool_t session_on_rx_request(pjsip_rx_data *rdata)
+{
+	pj_status_t handled = PJ_FALSE;
+	pjsip_dialog *dlg = pjsip_rdata_get_dlg(rdata);
+	pjsip_inv_session *inv_session;
+
+	switch (rdata->msg_info.msg->line.req.method.id) {
+	case PJSIP_INVITE_METHOD:
+		if (dlg) {
+			ast_log(LOG_WARNING, "on_rx_request called for INVITE in mid-dialog?\n");
+			break;
+		}
+		handled = PJ_TRUE;
+		handle_new_invite_request(rdata);
+		break;
+	default:
+		/* Handle other in-dialog methods if their supplements have been registered */
+		handled = dlg && (inv_session = pjsip_dlg_get_inv_session(dlg)) &&
+			has_supplement(inv_session->mod_data[session_module.id], rdata);
+		break;
+	}
+
+	return handled;
+}
+
+struct reschedule_reinvite_data {
+	struct ast_sip_session *session;
+	struct ast_sip_session_delayed_request *delay;
+};
+
+static struct reschedule_reinvite_data *reschedule_reinvite_data_alloc(
+		struct ast_sip_session *session, struct ast_sip_session_delayed_request *delay)
+{
+	struct reschedule_reinvite_data *rrd = ast_malloc(sizeof(*rrd));
+	if (!rrd) {
+		return NULL;
+	}
+	ao2_ref(session, +1);
+	rrd->session = session;
+	rrd->delay = delay;
+	return rrd;
+}
+
+static void reschedule_reinvite_data_destroy(struct reschedule_reinvite_data *rrd)
+{
+	ao2_cleanup(rrd->session);
+	ast_free(rrd->delay);
+	ast_free(rrd);
+}
+
+static int really_resend_reinvite(void *data)
+{
+	RAII_VAR(struct reschedule_reinvite_data *, rrd, data, reschedule_reinvite_data_destroy);
+
+	return send_delayed_request(rrd->session, rrd->delay);
+}
+
+static void resend_reinvite(pj_timer_heap_t *timer, pj_timer_entry *entry)
+{
+	struct reschedule_reinvite_data *rrd = entry->user_data;
+
+	ast_sip_push_task(rrd->session->serializer, really_resend_reinvite, entry->user_data);
+}
+
+static void reschedule_reinvite(struct ast_sip_session *session, ast_sip_session_response_cb on_response, pjsip_tx_data *tdata)
+{
+	struct ast_sip_session_delayed_request *delay = delayed_request_alloc("INVITE",
+			NULL, on_response, tdata);
+	pjsip_inv_session *inv = session->inv_session;
+	struct reschedule_reinvite_data *rrd = reschedule_reinvite_data_alloc(session, delay);
+	pj_time_val tv;
+	
+	if (!rrd || !delay) {
+		return;
+	}
+
+	tv.sec = 0;
+	if (inv->role == PJSIP_ROLE_UAC) {
+		tv.msec = 2100 + ast_random() % 2000;
+	} else {
+		tv.msec = ast_random() % 2000;
+	}
+
+	pj_timer_entry_init(&session->rescheduled_reinvite, 0, rrd, resend_reinvite);
+
+	pjsip_endpt_schedule_timer(ast_sip_get_pjsip_endpoint(), &session->rescheduled_reinvite, &tv);
+}
+
+static void __print_debug_details(const char *function, pjsip_inv_session *inv, pjsip_transaction *tsx, pjsip_event *e)
+{
+	struct ast_sip_session *session;
+	ast_debug(5, "Function %s called on event %s\n", function, pjsip_event_str(e->type));
+	if (!inv) {
+		ast_debug(5, "Transaction %p does not belong to an inv_session?\n", tsx);
+		ast_debug(5, "The transaction state is %s\n", pjsip_tsx_state_str(tsx->state));
+		return;
+	}
+	session = inv->mod_data[session_module.id];
+	if (!session) {
+		ast_debug(5, "inv_session %p has no ast session\n", inv);
+	} else {
+		ast_debug(5, "The state change pertains to the session with %s\n",
+				ast_sorcery_object_get_id(session->endpoint));
+	}
+	if (inv->invite_tsx) {
+		ast_debug(5, "The inv session still has an invite_tsx (%p)\n", inv->invite_tsx);
+	} else {
+		ast_debug(5, "The inv session does NOT have an invite_tsx\n");
+	}
+	if (tsx) {
+		ast_debug(5, "The transaction involved in this state change is %p\n", tsx);
+		ast_debug(5, "The current transaction state is %s\n", pjsip_tsx_state_str(tsx->state));
+		ast_debug(5, "The transaction state change event is %s\n", pjsip_event_str(e->body.tsx_state.type));
+	} else {
+		ast_debug(5, "There is no transaction involved in this state change\n");
+	}
+	ast_debug(5, "The current inv state is %s\n", pjsip_inv_state_name(inv->state));
+}
+
+#define print_debug_details(inv, tsx, e) __print_debug_details(__PRETTY_FUNCTION__, (inv), (tsx), (e))
+
+static void handle_incoming_request(struct ast_sip_session *session, pjsip_rx_data *rdata)
+{
+	struct ast_sip_session_supplement *supplement;
+	struct pjsip_request_line req = rdata->msg_info.msg->line.req;
+
+	ast_debug(3, "Method is %.*s\n", (int) pj_strlen(&req.method.name), pj_strbuf(&req.method.name));
+	AST_LIST_TRAVERSE(&session->supplements, supplement, next) {
+		if (supplement->incoming_request && (
+				!supplement->method || !pj_strcmp2(&req.method.name, supplement->method))) {
+			supplement->incoming_request(session, rdata);
+		}
+	}
+}
+
+static void handle_incoming_response(struct ast_sip_session *session, pjsip_rx_data *rdata)
+{
+	struct ast_sip_session_supplement *supplement;
+	struct pjsip_status_line status = rdata->msg_info.msg->line.status;
+
+	ast_debug(3, "Response is %d %.*s\n", status.code, (int) pj_strlen(&status.reason),
+			pj_strbuf(&status.reason));
+
+	AST_LIST_TRAVERSE(&session->supplements, supplement, next) {
+		if (supplement->incoming_response && (
+				!supplement->method || !pj_strcmp2(&rdata->msg_info.cseq->method.name, supplement->method))) {
+			supplement->incoming_response(session, rdata);
+		}
+	}
+}
+
+static int handle_incoming(struct ast_sip_session *session, pjsip_rx_data *rdata)
+{
+	ast_debug(3, "Received %s\n", rdata->msg_info.msg->type == PJSIP_REQUEST_MSG ?
+			"request" : "response");
+
+	if (rdata->msg_info.msg->type == PJSIP_REQUEST_MSG) {
+		handle_incoming_request(session, rdata);
+	} else {
+		handle_incoming_response(session, rdata);
+	}
+
+	return 0;
+}
+
+static void handle_outgoing_request(struct ast_sip_session *session, pjsip_tx_data *tdata)
+{
+	struct ast_sip_session_supplement *supplement;
+	struct pjsip_request_line req = tdata->msg->line.req;
+
+	ast_debug(3, "Method is %.*s\n", (int) pj_strlen(&req.method.name), pj_strbuf(&req.method.name));
+	AST_LIST_TRAVERSE(&session->supplements, supplement, next) {
+		if (supplement->outgoing_request &&
+				(!supplement->method || !pj_strcmp2(&req.method.name, supplement->method))) {
+			supplement->outgoing_request(session, tdata);
+		}
+	}
+}
+
+static void handle_outgoing_response(struct ast_sip_session *session, pjsip_tx_data *tdata)
+{
+	struct ast_sip_session_supplement *supplement;
+	struct pjsip_status_line status = tdata->msg->line.status;
+	ast_debug(3, "Response is %d %.*s\n", status.code, (int) pj_strlen(&status.reason),
+			pj_strbuf(&status.reason));
+
+	AST_LIST_TRAVERSE(&session->supplements, supplement, next) {
+		/* XXX Not sure how to get the method from a response.
+		 * For now, just call supplements on all responses, no
+		 * matter the method. This is less than ideal
+		 */
+		if (supplement->outgoing_response) {
+			supplement->outgoing_response(session, tdata);
+		}
+	}
+}
+
+static void handle_outgoing(struct ast_sip_session *session, pjsip_tx_data *tdata)
+{
+	ast_debug(3, "Sending %s\n", tdata->msg->type == PJSIP_REQUEST_MSG ?
+			"request" : "response");
+	if (tdata->msg->type == PJSIP_REQUEST_MSG) {
+		handle_outgoing_request(session, tdata);
+	} else {
+		handle_outgoing_response(session, tdata);
+	}
+}
+
+static int session_end(struct ast_sip_session *session)
+{
+	struct ast_sip_session_supplement *iter;
+
+	/* Session is dead. Let's get rid of the reference to the session */
+	AST_LIST_TRAVERSE(&session->supplements, iter, next) {
+		if (iter->session_end) {
+			iter->session_end(session);
+		}
+	}
+
+	session->inv_session->mod_data[session_module.id] = NULL;
+	ast_sip_dialog_set_serializer(session->inv_session->dlg, NULL);
+	ast_sip_dialog_set_endpoint(session->inv_session->dlg, NULL);
+	ao2_cleanup(session);
+	return 0;
+}
+
+static void session_inv_on_state_changed(pjsip_inv_session *inv, pjsip_event *e)
+{
+	struct ast_sip_session *session = inv->mod_data[session_module.id];
+
+	print_debug_details(inv, NULL, e);
+
+	switch(e->type) {
+	case PJSIP_EVENT_TX_MSG:
+		handle_outgoing(session, e->body.tx_msg.tdata);
+		break;
+	case PJSIP_EVENT_RX_MSG:
+		handle_incoming(session, e->body.rx_msg.rdata);
+		break;
+	case PJSIP_EVENT_TSX_STATE:
+		ast_debug(3, "Source of transaction state change is %s\n", pjsip_event_str(e->body.tsx_state.type));
+		/* Transaction state changes are prompted by some other underlying event. */
+		switch(e->body.tsx_state.type) {
+		case PJSIP_EVENT_TX_MSG:
+			handle_outgoing(session, e->body.tsx_state.src.tdata);
+			break;
+		case PJSIP_EVENT_RX_MSG:
+			handle_incoming(session, e->body.tsx_state.src.rdata);
+			break;
+		case PJSIP_EVENT_TRANSPORT_ERROR:
+		case PJSIP_EVENT_TIMER:
+		case PJSIP_EVENT_USER:
+		case PJSIP_EVENT_UNKNOWN:
+		case PJSIP_EVENT_TSX_STATE:
+			/* Inception? */
+			break;
+		}
+		break;
+	case PJSIP_EVENT_TRANSPORT_ERROR:
+	case PJSIP_EVENT_TIMER:
+	case PJSIP_EVENT_UNKNOWN:
+	case PJSIP_EVENT_USER:
+	default:
+		break;
+	}
+
+	if (inv->state == PJSIP_INV_STATE_DISCONNECTED) {
+		session_end(session);
+	}
+}
+
+static void session_inv_on_new_session(pjsip_inv_session *inv, pjsip_event *e)
+{
+	/* XXX STUB */
+}
+
+static void session_inv_on_tsx_state_changed(pjsip_inv_session *inv, pjsip_transaction *tsx, pjsip_event *e)
+{
+	struct ast_sip_session *session = inv->mod_data[session_module.id];
+	print_debug_details(inv, tsx, e);
+	if (!session) {
+		/* Transaction likely timed out after the call was hung up. Just
+		 * ignore such transaction changes
+		 */
+		return;
+	}
+	switch (e->body.tsx_state.type) {
+	case PJSIP_EVENT_TX_MSG:
+		/* When we create an outgoing request, we do not have access to the transaction that
+		 * is created. Instead, We have to place transaction-specific data in the tdata. Here,
+		 * we transfer the data into the transaction. This way, when we receive a response, we
+		 * can dig this data out again
+		 */
+		tsx->mod_data[session_module.id] = e->body.tsx_state.src.tdata->mod_data[session_module.id];
+		break;
+	case PJSIP_EVENT_RX_MSG:
+		if (tsx->method.id == PJSIP_INVITE_METHOD) {
+			if (tsx->role == PJSIP_ROLE_UAC && tsx->state == PJSIP_TSX_STATE_COMPLETED) {
+				/* This means we got a non 2XX final response to our outgoing INVITE */
+				if (tsx->status_code == PJSIP_SC_REQUEST_PENDING) {
+					reschedule_reinvite(session, tsx->mod_data[session_module.id], tsx->last_tx);
+					return;
+				} else {
+					/* Other failures result in destroying the session. */
+					pjsip_tx_data *tdata;
+					pjsip_inv_end_session(inv, 500, NULL, &tdata);
+					ast_sip_session_send_request(session, tdata);
+				}
+			}
+		} else {
+			if (tsx->role == PJSIP_ROLE_UAS && tsx->state == PJSIP_TSX_STATE_TRYING) {
+				handle_incoming_request(session, e->body.tsx_state.src.rdata);
+			}
+		}
+		if (tsx->mod_data[session_module.id]) {
+			ast_sip_session_response_cb cb = tsx->mod_data[session_module.id];
+			cb(session, e->body.tsx_state.src.rdata);
+		}
+	case PJSIP_EVENT_TRANSPORT_ERROR:
+	case PJSIP_EVENT_TIMER:
+	case PJSIP_EVENT_USER:
+	case PJSIP_EVENT_UNKNOWN:
+	case PJSIP_EVENT_TSX_STATE:
+		/* Inception? */
+		break;
+	}
+
+	/* Terminated INVITE transactions always should result in queuing delayed requests,
+	 * no matter what event caused the transaction to terminate
+	 */
+	if (tsx->method.id == PJSIP_INVITE_METHOD && tsx->state == PJSIP_TSX_STATE_TERMINATED) {
+		queue_delayed_request(session);
+	}
+}
+
+static int add_sdp_streams(void *obj, void *arg, void *data, int flags)
+{
+	struct ast_sip_session_media *session_media = obj;
+	pjmedia_sdp_session *answer = arg;
+	struct ast_sip_session *session = data;
+	struct ast_sip_session_sdp_handler *handler = session_media->handler;
+	RAII_VAR(struct sdp_handler_list *, handler_list, NULL, ao2_cleanup);
+
+	if (handler) {
+		/* if an already assigned handler does not handle the session_media or reports a catastrophic error, fail */
+		if (handler->create_outgoing_sdp_stream(session, session_media, answer) <= 0) {
+			return 0;
+		}
+		return CMP_MATCH;
+	}
+
+	handler_list = ao2_find(sdp_handlers, session_media->stream_type, OBJ_KEY);
+	if (!handler_list) {
+		return CMP_MATCH;
+	}
+
+	/* no handler for this stream type and we have a list to search */
+	AST_LIST_TRAVERSE(&handler_list->list, handler, next) {
+		int res = handler->create_outgoing_sdp_stream(session, session_media, answer);
+		if (res < 0) {
+			/* catastrophic error */
+			return 0;
+		}
+		if (res > 0) {
+			/* handled */
+			return CMP_MATCH;
+		}
+	}
+
+	/* streams that weren't handled won't be included in generated outbound SDP */
+	return CMP_MATCH;
+}
+
+static struct pjmedia_sdp_session *create_local_sdp(pjsip_inv_session *inv, struct ast_sip_session *session, const pjmedia_sdp_session *offer)
+{
+	RAII_VAR(struct ao2_iterator *, successful, NULL, ao2_iterator_cleanup);
+	static const pj_str_t STR_ASTERISK = { "Asterisk", 8 };
+	static const pj_str_t STR_IN = { "IN", 2 };
+	static const pj_str_t STR_IP4 = { "IP4", 3 };
+	static const pj_str_t STR_IP6 = { "IP6", 3 };
+	pjmedia_sdp_session *local;
+
+	if (!(local = PJ_POOL_ZALLOC_T(inv->pool_prov, pjmedia_sdp_session))) {
+		return NULL;
+	}
+
+	if (!offer) {
+		local->origin.version = local->origin.id = (pj_uint32_t)(ast_random());
+	} else {
+		local->origin.version = offer->origin.version + 1;
+		local->origin.id = offer->origin.id;
+	}
+
+	local->origin.user = STR_ASTERISK;
+	local->origin.net_type = STR_IN;
+	local->origin.addr_type = session->endpoint->rtp_ipv6 ? STR_IP6 : STR_IP4;
+	local->origin.addr = *pj_gethostname();
+	local->name = local->origin.user;
+
+	/* Now let the handlers add streams of various types, pjmedia will automatically reorder the media streams for us */
+	successful = ao2_callback_data(session->media, OBJ_MULTIPLE, add_sdp_streams, local, session);
+	if (!successful || ao2_container_count(successful->c) != ao2_container_count(session->media)) {
+		/* Something experienced a catastrophic failure */
+		return NULL;
+	}
+
+	/* Use the connection details of the first media stream if possible for SDP level */
+	if (local->media_count) {
+		local->conn = local->media[0]->conn;
+	}
+
+	return local;
+}
+
+static void session_inv_on_rx_offer(pjsip_inv_session *inv, const pjmedia_sdp_session *offer)
+{
+	struct ast_sip_session *session = inv->mod_data[session_module.id];
+	pjmedia_sdp_session *answer;
+
+	if (handle_incoming_sdp(session, offer)) {
+		return;
+	}
+
+	if ((answer = create_local_sdp(inv, session, offer))) {
+		pjsip_inv_set_sdp_answer(inv, answer);
+	}
+}
+
+#if 0
+static void session_inv_on_create_offer(pjsip_inv_session *inv, pjmedia_sdp_session **p_offer)
+{
+	/* XXX STUB */
+}
+#endif
+
+static void session_inv_on_media_update(pjsip_inv_session *inv, pj_status_t status)
+{
+	struct ast_sip_session *session = inv->mod_data[session_module.id];
+	const pjmedia_sdp_session *local, *remote;
+
+	if (!session->channel) {
+		/* If we don't have a channel. We really don't care about media updates.
+		 * Just ignore
+		 */
+		return;
+	}
+
+	if ((status != PJ_SUCCESS) || (pjmedia_sdp_neg_get_active_local(inv->neg, &local) != PJ_SUCCESS) ||
+		(pjmedia_sdp_neg_get_active_remote(inv->neg, &remote) != PJ_SUCCESS)) {
+		ast_channel_hangupcause_set(session->channel, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
+		ast_queue_hangup(session->channel);
+		return;
+	}
+
+	handle_negotiated_sdp(session, local, remote);
+}
+
+static pjsip_redirect_op session_inv_on_redirected(pjsip_inv_session *inv, const pjsip_uri *target, const pjsip_event *e)
+{
+	/* XXX STUB */
+	return PJSIP_REDIRECT_REJECT;
+}
+
+static pjsip_inv_callback inv_callback = {
+	.on_state_changed = session_inv_on_state_changed,
+	.on_new_session = session_inv_on_new_session,
+	.on_tsx_state_changed = session_inv_on_tsx_state_changed,
+	.on_rx_offer = session_inv_on_rx_offer,
+	.on_media_update = session_inv_on_media_update,
+	.on_redirected = session_inv_on_redirected,
+};
+
+/*! \brief Hook for modifying outgoing messages with SDP to contain the proper address information */
+static void session_outgoing_nat_hook(pjsip_tx_data *tdata, struct ast_sip_transport *transport)
+{
+	struct ast_sip_nat_hook *hook = tdata->mod_data[session_module.id];
+	struct pjmedia_sdp_session *sdp;
+	int stream;
+
+	/* SDP produced by us directly will never be multipart */
+	if (hook || !tdata->msg->body || pj_stricmp2(&tdata->msg->body->content_type.type, "application") ||
+		pj_stricmp2(&tdata->msg->body->content_type.subtype, "sdp") || ast_strlen_zero(transport->external_media_address)) {
+		return;
+	}
+
+	sdp = tdata->msg->body->data;
+
+	for (stream = 0; stream < sdp->media_count; ++stream) {
+		/* See if there are registered handlers for this media stream type */
+		char media[20];
+		struct ast_sip_session_sdp_handler *handler;
+		RAII_VAR(struct sdp_handler_list *, handler_list, NULL, ao2_cleanup);
+
+		/* We need a null-terminated version of the media string */
+		ast_copy_pj_str(media, &sdp->media[stream]->desc.media, sizeof(media));
+
+		handler_list = ao2_find(sdp_handlers, media, OBJ_KEY);
+		if (!handler_list) {
+			ast_debug(1, "No registered SDP handlers for media type '%s'\n", media);
+			continue;
+		}
+		AST_LIST_TRAVERSE(&handler_list->list, handler, next) {
+			if (handler->change_outgoing_sdp_stream_media_address) {
+				handler->change_outgoing_sdp_stream_media_address(tdata, sdp->media[stream], transport);
+			}
+		}
+	}
+
+	/* We purposely do this so that the hook will not be invoked multiple times, ie: if a retransmit occurs */
+	tdata->mod_data[session_module.id] = nat_hook;
+}
+
+static int load_module(void)
+{
+	pjsip_endpoint *endpt;
+	if (!ast_sip_get_sorcery() || !ast_sip_get_pjsip_endpoint()) {
+		return AST_MODULE_LOAD_DECLINE;
+	}
+	if (!(nat_hook = ast_sorcery_alloc(ast_sip_get_sorcery(), "nat_hook", NULL))) {
+		return AST_MODULE_LOAD_DECLINE;
+	}
+	nat_hook->outgoing_external_message = session_outgoing_nat_hook;
+	ast_sorcery_create(ast_sip_get_sorcery(), nat_hook);
+	sdp_handlers = ao2_container_alloc(SDP_HANDLER_BUCKETS,
+			sdp_handler_list_hash, sdp_handler_list_cmp);
+	if (!sdp_handlers) {
+		return AST_MODULE_LOAD_DECLINE;
+	}
+	endpt = ast_sip_get_pjsip_endpoint();
+	pjsip_inv_usage_init(endpt, &inv_callback);
+	pjsip_100rel_init_module(endpt);
+	pjsip_timer_init_module(endpt);
+	if (ast_sip_register_service(&session_module)) {
+		return AST_MODULE_LOAD_DECLINE;
+	}
+	return AST_MODULE_LOAD_SUCCESS;
+}
+
+static int unload_module(void)
+{
+	ast_sip_unregister_service(&session_module);
+	if (nat_hook) {
+		ast_sorcery_delete(ast_sip_get_sorcery(), nat_hook);
+		nat_hook = NULL;
+	}
+	return 0;
+}
+
+AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_LOAD_ORDER, "SIP Session resource",
+		.load = load_module,
+		.unload = unload_module,
+		.load_pri = AST_MODPRI_APP_DEPEND,
+	       );
diff --git a/res/res_sip_session.exports.in b/res/res_sip_session.exports.in
new file mode 100644
index 0000000000000000000000000000000000000000..08c6f3937933b5f8195f4b1574b2b1ec971e1e79
--- /dev/null
+++ b/res/res_sip_session.exports.in
@@ -0,0 +1,18 @@
+{
+	global:
+		LINKER_SYMBOL_PREFIXast_sip_session_register_sdp_handler;
+		LINKER_SYMBOL_PREFIXast_sip_session_unregister_sdp_handler;
+		LINKER_SYMBOL_PREFIXast_sip_session_register_supplement;
+		LINKER_SYMBOL_PREFIXast_sip_session_unregister_supplement;
+		LINKER_SYMBOL_PREFIXast_sip_session_alloc_datastore;
+		LINKER_SYMBOL_PREFIXast_sip_session_add_datastore;
+		LINKER_SYMBOL_PREFIXast_sip_session_get_datastore;
+		LINKER_SYMBOL_PREFIXast_sip_session_remove_datastore;
+		LINKER_SYMBOL_PREFIXast_sip_session_get_identity;
+		LINKER_SYMBOL_PREFIXast_sip_session_refresh;
+		LINKER_SYMBOL_PREFIXast_sip_session_send_response;
+		LINKER_SYMBOL_PREFIXast_sip_session_send_request;
+		LINKER_SYMBOL_PREFIXast_sip_session_create_outgoing;
+	local:
+		*;
+};
diff --git a/res/res_sorcery_config.c b/res/res_sorcery_config.c
index 509538f5aa9da700035c1900499112ec1a998f5a..c6ec62ed62fcf4d43b4cc62461ff7f5721019965 100644
--- a/res/res_sorcery_config.c
+++ b/res/res_sorcery_config.c
@@ -199,7 +199,6 @@ static void sorcery_config_retrieve_multiple(const struct ast_sorcery *sorcery,
 	if (!config_objects) {
 		return;
 	}
-
 	ao2_callback(config_objects, 0, sorcery_config_fields_cmp, &params);
 }
 
diff --git a/tests/test_sorcery.c b/tests/test_sorcery.c
index 3877edc62b25ffd512b3d3d0f7fefd58315563ea..6cfd2de4f8e337e07ce7e672c4878c3220fee300 100644
--- a/tests/test_sorcery.c
+++ b/tests/test_sorcery.c
@@ -130,9 +130,10 @@ struct sorcery_test_caching {
 static int apply_handler_called;
 
 /*! \brief Simple apply handler which sets global scope integer to 1 if called */
-static void test_apply_handler(const struct ast_sorcery *sorcery, void *obj)
+static int test_apply_handler(const struct ast_sorcery *sorcery, void *obj)
 {
 	apply_handler_called = 1;
+	return 0;
 }
 
 /*! \brief Global scope caching structure for testing */