diff --git a/CHANGES b/CHANGES
index 93ecf94c193c1ec1e8334fb09259bfe612e50491..173a41127c721d80a5c0a03f1c10f721218e3669 100644
--- a/CHANGES
+++ b/CHANGES
@@ -205,6 +205,14 @@ Queue
 --- Functionality changes from Asterisk 13.7.0 to Asterisk 13.8.0 ------------
 ------------------------------------------------------------------------------
 
+res_pjproject
+------------------
+ * This module is the successor of res_pjsip_log_forwarder.  As well as
+   handling the log forwarding (which now displays as 'pjproject:0' instead
+   of 'pjsip:0'), it also adds a 'pjproject show buildopts' command to the CLI.
+   This displays the compiled-in options of the pjproject installation
+   Asterisk is currently running against.
+
 res_pjsip
 ------------------
 
diff --git a/include/asterisk/res_pjproject.h b/include/asterisk/res_pjproject.h
new file mode 100644
index 0000000000000000000000000000000000000000..2095caed2629be26eea47828d690e6e12de82983
--- /dev/null
+++ b/include/asterisk/res_pjproject.h
@@ -0,0 +1,62 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2016, Fairview 5 Engineering, LLC
+ *
+ * George Joseph <george.joseph@fairview5.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_PJPROJECT_H
+#define _RES_PJPROJECT_H
+
+/*!
+ * \brief Retrieve a pjproject build option
+ *
+ * \param option The build option requested
+ * \param format_string A scanf-style format string to parse the option value into
+ * \param ... Pointers to variables to receive the values parsed
+ *
+ * \retval The number of values parsed
+ *
+ * \since 13.8.0
+ *
+ * \note The option requested must be from those returned by pj_dump_config()
+ * which can be displayed with the 'pjsip show buildopts' CLI command.
+ *
+ *   <b>Sample Usage:</b>
+ *   \code
+ *
+ *   int max_hostname;
+ *
+ *   ast_sip_get_pjproject_buildopt("PJ_MAX_HOSTNAME", "%d", &max_hostname);
+ *
+ *   \endcode
+ *
+ */
+int ast_pjproject_get_buildopt(char *option, char *format_string, ...) __attribute__((format(scanf, 2,3)));
+
+/*!
+ * \brief Increment the res_pjproject reference count.
+ *
+ * This ensures graceful shutdown happens in the proper order.
+ */
+void ast_pjproject_ref(void);
+
+/*!
+ * \brief Decrement the res_pjproject reference count.
+ *
+ * This ensures graceful shutdown happens in the proper order.
+ */
+void ast_pjproject_unref(void);
+
+#endif /* _RES_PJPROJECT_H */
diff --git a/res/res_pjproject.c b/res/res_pjproject.c
index c6b396afc5f013f5865b8d947cfede269889d23a..de1cecbc8e776a50c52cd808d3cee5d9a164d53b 100644
--- a/res/res_pjproject.c
+++ b/res/res_pjproject.c
@@ -18,18 +18,18 @@
 
 /*! \file
  *
- * \brief Bridge PJSIP logging to Asterisk logging.
+ * \brief Bridge PJPROJECT logging to Asterisk logging.
  * \author David M. Lee, II <dlee@digium.com>
  *
- * PJSIP logging doesn't exactly match Asterisk logging, but mapping the two is
- * not too bad. PJSIP log levels are identified by a single int. Limits are
- * not specified by PJSIP, but their implementation used 1 through 6.
+ * PJPROJECT logging doesn't exactly match Asterisk logging, but mapping the two is
+ * not too bad. PJPROJECT log levels are identified by a single int. Limits are
+ * not specified by PJPROJECT, but their implementation used 1 through 6.
  *
  * The mapping is as follows:
  *  - 0: LOG_ERROR
  *  - 1: LOG_ERROR
  *  - 2: LOG_WARNING
- *  - 3 and above: equivalent to ast_debug(level, ...) for res_pjsip.so
+ *  - 3 and above: equivalent to ast_debug(level, ...) for res_pjproject.so
  */
 
 /*** MODULEINFO
@@ -41,47 +41,31 @@
 
 ASTERISK_REGISTER_FILE()
 
+#include <stdarg.h>
+#include <pjlib.h>
 #include <pjsip.h>
 #include <pj/log.h>
 
 #include "asterisk/logger.h"
 #include "asterisk/module.h"
 #include "asterisk/cli.h"
+#include "asterisk/res_pjproject.h"
+#include "asterisk/vector.h"
 
 static pj_log_func *log_cb_orig;
 static unsigned decor_orig;
 
-/*! Protection from other CLI instances. */
-AST_MUTEX_DEFINE_STATIC(show_buildopts_lock);
+static AST_VECTOR(buildopts, char *) buildopts;
 
-struct pjsip_show_buildopts {
-	pthread_t thread;
-	int fd;
-};
-
-static struct pjsip_show_buildopts show_buildopts = {
-	.thread = AST_PTHREADT_NULL,
-	.fd = -1,
-};
-
-static void log_cb(int level, const char *data, int len)
+static void log_forwarder(int level, const char *data, int len)
 {
 	int ast_level;
-	/* PJSIP doesn't provide much in the way of source info */
-	const char * log_source = "pjsip";
+	/* PJPROJECT doesn't provide much in the way of source info */
+	const char * log_source = "pjproject";
 	int log_line = 0;
 	const char *log_func = "<?>";
 	int mod_level;
 
-	if (show_buildopts.fd != -1 && show_buildopts.thread == pthread_self()) {
-		/*
-		 * We are handling the CLI command dumping the
-		 * PJPROJECT compile time config option settings.
-		 */
-		ast_cli(show_buildopts.fd, "%s\n", data);
-		return;
-	}
-
 	/* Lower number indicates higher importance */
 	switch (level) {
 	case 0: /* level zero indicates fatal error, according to docs */
@@ -94,29 +78,72 @@ static void log_cb(int level, const char *data, int len)
 	default:
 		ast_level = __LOG_DEBUG;
 
-		/* For levels 3 and up, obey the debug level for res_pjsip */
+		/* For levels 3 and up, obey the debug level for res_pjproject */
 		mod_level = ast_opt_dbg_module ?
-			ast_debug_get_by_module("res_pjsip") : 0;
+			ast_debug_get_by_module("res_pjproject") : 0;
 		if (option_debug < level && mod_level < level) {
 			return;
 		}
 		break;
 	}
 
-	/* PJSIP uses indention to indicate function call depth. We'll prepend
+	/* PJPROJECT uses indention to indicate function call depth. We'll prepend
 	 * log statements with a tab so they'll have a better shot at lining
 	 * up */
 	ast_log(ast_level, log_source, log_line, log_func, "\t%s\n", data);
 }
 
-static char *handle_pjsip_show_buildopts(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
+static void capture_buildopts_cb(int level, const char *data, int len)
+{
+	if (strstr(data, "Teluu") || strstr(data, "Dumping")) {
+		return;
+	}
+
+	AST_VECTOR_ADD_SORTED(&buildopts, ast_strdup(ast_skip_blanks(data)), strcmp);
+}
+
+int ast_pjproject_get_buildopt(char *option, char *format_string, ...)
+{
+	int res = 0;
+	char *format_temp;
+	int i;
+
+	format_temp = ast_alloca(strlen(option) + strlen(" : ") + strlen(format_string) + 1);
+	sprintf(format_temp, "%s : %s", option, format_string);
+
+	for (i = 0; i < AST_VECTOR_SIZE(&buildopts); i++) {
+		va_list arg_ptr;
+		va_start(arg_ptr, format_string);
+		res = vsscanf(AST_VECTOR_GET(&buildopts, i), format_temp, arg_ptr);
+		va_end(arg_ptr);
+		if (res) {
+			break;
+		}
+	}
+
+	return res;
+}
+
+void ast_pjproject_ref(void)
 {
-	switch(cmd) {
+	ast_module_ref(ast_module_info->self);
+}
+
+void ast_pjproject_unref(void)
+{
+	ast_module_unref(ast_module_info->self);
+}
+
+static char *handle_pjproject_show_buildopts(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
+{
+	int i;
+
+	switch (cmd) {
 	case CLI_INIT:
-		e->command = "pjsip show buildopts";
+		e->command = "pjproject show buildopts";
 		e->usage =
-			"Usage: pjsip show buildopts\n"
-			"       Show the compile time config of pjproject that res_pjsip is\n"
+			"Usage: pjproject show buildopts\n"
+			"       Show the compile time config of the pjproject that Asterisk is\n"
 			"       running against.\n";
 		return NULL;
 	case CLI_GENERATE:
@@ -125,60 +152,63 @@ static char *handle_pjsip_show_buildopts(struct ast_cli_entry *e, int cmd, struc
 
 	ast_cli(a->fd, "PJPROJECT compile time config currently running against:\n");
 
-	/* Protect from other CLI instances trying to do this at the same time. */
-	ast_mutex_lock(&show_buildopts_lock);
-
-	show_buildopts.thread = pthread_self();
-	show_buildopts.fd = a->fd;
-	pj_dump_config();
-	show_buildopts.fd = -1;
-	show_buildopts.thread = AST_PTHREADT_NULL;
-
-	ast_mutex_unlock(&show_buildopts_lock);
+	for (i = 0; i < AST_VECTOR_SIZE(&buildopts); i++) {
+		ast_cli(a->fd, "%s\n", AST_VECTOR_GET(&buildopts, i));
+	}
 
 	return CLI_SUCCESS;
 }
 
-static struct ast_cli_entry pjsip_cli[] = {
-	AST_CLI_DEFINE(handle_pjsip_show_buildopts, "Show the compiled config of pjproject in use"),
+static struct ast_cli_entry pjproject_cli[] = {
+	AST_CLI_DEFINE(handle_pjproject_show_buildopts, "Show the compiled config of the pjproject in use"),
 };
 
 static int load_module(void)
 {
+	ast_debug(3, "Starting PJPROJECT logging to Asterisk logger\n");
+
 	pj_init();
 
 	decor_orig = pj_log_get_decor();
 	log_cb_orig = pj_log_get_log_func();
 
-	ast_debug(3, "Forwarding PJSIP logger to Asterisk logger\n");
-	/* SENDER prepends the source to the log message. This could be a
-	 * filename, object reference, or simply a string
-	 *
-	 * INDENT is assumed to be on by most log statements in PJSIP itself.
+	if (AST_VECTOR_INIT(&buildopts, 64)) {
+		return AST_MODULE_LOAD_DECLINE;
+	}
+
+	/*
+	 * On startup, we want to capture the dump once and store it.
 	 */
+	pj_log_set_log_func(capture_buildopts_cb);
+	pj_log_set_decor(0);
+	pj_dump_config();
 	pj_log_set_decor(PJ_LOG_HAS_SENDER | PJ_LOG_HAS_INDENT);
-	pj_log_set_log_func(log_cb);
+	pj_log_set_log_func(log_forwarder);
 
-	ast_cli_register_multiple(pjsip_cli, ARRAY_LEN(pjsip_cli));
+	ast_cli_register_multiple(pjproject_cli, ARRAY_LEN(pjproject_cli));
 
 	return AST_MODULE_LOAD_SUCCESS;
 }
 
+#define NOT_EQUALS(a, b) (a != b)
+
 static int unload_module(void)
 {
-	ast_cli_unregister_multiple(pjsip_cli, ARRAY_LEN(pjsip_cli));
-
+	ast_cli_unregister_multiple(pjproject_cli, ARRAY_LEN(pjproject_cli));
 	pj_log_set_log_func(log_cb_orig);
 	pj_log_set_decor(decor_orig);
 
+	AST_VECTOR_REMOVE_CMP_UNORDERED(&buildopts, NULL, NOT_EQUALS, ast_free);
+	AST_VECTOR_FREE(&buildopts);
+
+	ast_debug(3, "Stopped PJPROJECT logging to Asterisk logger\n");
+
 	pj_shutdown();
 
 	return 0;
 }
 
-/* While we don't really export global symbols, we want to load before other
- * modules that do */
-AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_LOAD_ORDER, "PJSIP Log Forwarder",
+AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_LOAD_ORDER, "PJPROJECT Log and Utility Support",
 	.support_level = AST_MODULE_SUPPORT_CORE,
 	.load = load_module,
 	.unload = unload_module,
diff --git a/res/res_pjproject.exports.in b/res/res_pjproject.exports.in
new file mode 100644
index 0000000000000000000000000000000000000000..f1821a6a28cdd139dfcb806c795abcf0a0ccc580
--- /dev/null
+++ b/res/res_pjproject.exports.in
@@ -0,0 +1,6 @@
+{
+	global:
+		LINKER_SYMBOL_PREFIXast_pjproject_*;
+	local:
+		*;
+};