diff --git a/apps/app_dial.c b/apps/app_dial.c
index fa4ee7a4b787012540894c490403e39eed187a51..831a708e5597ad18bc465f38708fc5728f339c10 100644
--- a/apps/app_dial.c
+++ b/apps/app_dial.c
@@ -2215,14 +2215,9 @@ static int dial_exec_full(struct ast_channel *chan, void *data, struct ast_flags
 			res = ast_bridge_call(chan, peer, &config);
 		}
 
-		if (res != AST_PBX_NO_HANGUP_PEER_PARKED && ast_test_flag64(&opts, OPT_PEER_H)) {
-			ast_log(LOG_NOTICE, "PEER context: %s; PEER exten: %s;  PEER priority: %d\n",
-				peer->context, peer->exten, peer->priority);
-		}
-		if (res != AST_PBX_NO_HANGUP_PEER_PARKED)
-			strcpy(peer->context, chan->context);
+		strcpy(peer->context, chan->context);
 
-		if (res != AST_PBX_NO_HANGUP_PEER_PARKED && ast_test_flag64(&opts, OPT_PEER_H) && ast_exists_extension(peer, peer->context, "h", 1, peer->cid.cid_num)) {
+		if (ast_test_flag64(&opts, OPT_PEER_H) && ast_exists_extension(peer, peer->context, "h", 1, peer->cid.cid_num)) {
 			int autoloopflag;
 			int found;
 			int res9;
@@ -2242,41 +2237,34 @@ static int dial_exec_full(struct ast_channel *chan, void *data, struct ast_flags
 			}
 			ast_set2_flag(peer, autoloopflag, AST_FLAG_IN_AUTOLOOP);  /* set it back the way it was */
 		}
-		if (res != AST_PBX_NO_HANGUP_PEER && res != AST_PBX_NO_HANGUP_PEER_PARKED) {
-			if (!ast_check_hangup(peer) && ast_test_flag64(&opts, OPT_CALLEE_GO_ON) && !ast_strlen_zero(opt_args[OPT_ARG_CALLEE_GO_ON])) {		
-				replace_macro_delimiter(opt_args[OPT_ARG_CALLEE_GO_ON]);
-				ast_parseable_goto(peer, opt_args[OPT_ARG_CALLEE_GO_ON]);
-				ast_pbx_start(peer);
-			} else {
-				if (!ast_check_hangup(chan))
-					chan->hangupcause = peer->hangupcause;
-				ast_hangup(peer);
-			}
+		if (!ast_check_hangup(peer) && ast_test_flag64(&opts, OPT_CALLEE_GO_ON) && !ast_strlen_zero(opt_args[OPT_ARG_CALLEE_GO_ON])) {		
+			replace_macro_delimiter(opt_args[OPT_ARG_CALLEE_GO_ON]);
+			ast_parseable_goto(peer, opt_args[OPT_ARG_CALLEE_GO_ON]);
+			ast_pbx_start(peer);
+		} else {
+			if (!ast_check_hangup(chan))
+				chan->hangupcause = peer->hangupcause;
+			ast_hangup(peer);
 		}
 	}
 out:
-	/* cleaning up chan is not a good idea here if AST_PBX_KEEPALIVE
-	   is returned; chan will get the love it needs from another
-	   thread */
-	if (res != AST_PBX_KEEPALIVE) {
-		if (moh) {
-			moh = 0;
-			ast_moh_stop(chan);
-		} else if (sentringing) {
-			sentringing = 0;
-			ast_indicate(chan, -1);
-		}
-		ast_channel_early_bridge(chan, NULL);
-		hanguptree(outgoing, NULL, 0); /* In this case, there's no answer anywhere */
-		pbx_builtin_setvar_helper(chan, "DIALSTATUS", pa.status);
-		senddialendevent(chan, pa.status);
-		ast_debug(1, "Exiting with DIALSTATUS=%s.\n", pa.status);
-
-		if ((ast_test_flag64(peerflags, OPT_GO_ON)) && !ast_check_hangup(chan) && (res != AST_PBX_KEEPALIVE) && (res != AST_PBX_INCOMPLETE)) {
-			if (!ast_tvzero(calldurationlimit))
-				memset(&chan->whentohangup, 0, sizeof(chan->whentohangup));
-			res = 0;
-		}
+	if (moh) {
+		moh = 0;
+		ast_moh_stop(chan);
+	} else if (sentringing) {
+		sentringing = 0;
+		ast_indicate(chan, -1);
+	}
+	ast_channel_early_bridge(chan, NULL);
+	hanguptree(outgoing, NULL, 0); /* In this case, there's no answer anywhere */
+	pbx_builtin_setvar_helper(chan, "DIALSTATUS", pa.status);
+	senddialendevent(chan, pa.status);
+	ast_debug(1, "Exiting with DIALSTATUS=%s.\n", pa.status);
+	
+	if ((ast_test_flag64(peerflags, OPT_GO_ON)) && !ast_check_hangup(chan) && (res != AST_PBX_INCOMPLETE)) {
+		if (!ast_tvzero(calldurationlimit))
+			memset(&chan->whentohangup, 0, sizeof(chan->whentohangup));
+		res = 0;
 	}
 
 done:
diff --git a/apps/app_macro.c b/apps/app_macro.c
index c90432a62192ada4626653c045c790a78c7de7c3..9d659996330d354b70ace63fda69ac90dcec6f26 100644
--- a/apps/app_macro.c
+++ b/apps/app_macro.c
@@ -406,10 +406,6 @@ static int _macro_exec(struct ast_channel *chan, void *data, int exclusive)
 			case MACRO_EXIT_RESULT:
 				res = 0;
 				goto out;
-			case AST_PBX_KEEPALIVE:
-				ast_debug(2, "Spawn extension (%s,%s,%d) exited KEEPALIVE in macro %s on '%s'\n", chan->context, chan->exten, chan->priority, macro, chan->name);
-				ast_verb(2, "Spawn extension (%s, %s, %d) exited KEEPALIVE in macro '%s' on '%s'\n", chan->context, chan->exten, chan->priority, macro, chan->name);
-				goto out;
 			default:
 				ast_debug(2, "Spawn extension (%s,%s,%d) exited non-zero on '%s' in macro '%s'\n", chan->context, chan->exten, chan->priority, chan->name, macro);
 				ast_verb(2, "Spawn extension (%s, %s, %d) exited non-zero on '%s' in macro '%s'\n", chan->context, chan->exten, chan->priority, chan->name, macro);
diff --git a/apps/app_queue.c b/apps/app_queue.c
index 5b6c4393283fc2fbefb2286c399b72d3ba3f38e8..1d86d3df683c36bc3158490d32560d9e78846c56 100644
--- a/apps/app_queue.c
+++ b/apps/app_queue.c
@@ -4069,24 +4069,21 @@ static int try_calling(struct queue_ent *qe, const char *options, char *announce
 		/* If the queue member did an attended transfer, then the TRANSFER already was logged in the queue_log
 		 * when the masquerade occurred. These other "ending" queue_log messages are unnecessary
 		 */
-		if (bridge != AST_PBX_KEEPALIVE && !attended_transfer_occurred(qe->chan)) {
+		if (!attended_transfer_occurred(qe->chan)) {
 			struct ast_datastore *tds;
 			if (strcasecmp(oldcontext, qe->chan->context) || strcasecmp(oldexten, qe->chan->exten)) {
 				ast_queue_log(queuename, qe->chan->uniqueid, member->membername, "TRANSFER", "%s|%s|%ld|%ld|%d",
 					qe->chan->exten, qe->chan->context, (long) (callstart - qe->start),
 					(long) (time(NULL) - callstart), qe->opos);
-				if (bridge != AST_PBX_NO_HANGUP_PEER && bridge != AST_PBX_NO_HANGUP_PEER_PARKED)
-					send_agent_complete(qe, queuename, peer, member, callstart, vars, sizeof(vars), TRANSFER);
+				send_agent_complete(qe, queuename, peer, member, callstart, vars, sizeof(vars), TRANSFER);
 			} else if (ast_check_hangup(qe->chan)) {
 				ast_queue_log(queuename, qe->chan->uniqueid, member->membername, "COMPLETECALLER", "%ld|%ld|%d",
 					(long) (callstart - qe->start), (long) (time(NULL) - callstart), qe->opos);
-				if (bridge != AST_PBX_NO_HANGUP_PEER && bridge != AST_PBX_NO_HANGUP_PEER_PARKED)
-					send_agent_complete(qe, queuename, peer, member, callstart, vars, sizeof(vars), CALLER);
+				send_agent_complete(qe, queuename, peer, member, callstart, vars, sizeof(vars), CALLER);
 			} else {
 				ast_queue_log(queuename, qe->chan->uniqueid, member->membername, "COMPLETEAGENT", "%ld|%ld|%d",
 					(long) (callstart - qe->start), (long) (time(NULL) - callstart), qe->opos);
-				if (bridge != AST_PBX_NO_HANGUP_PEER && bridge != AST_PBX_NO_HANGUP_PEER_PARKED)
-					send_agent_complete(qe, queuename, peer, member, callstart, vars, sizeof(vars), AGENT);
+				send_agent_complete(qe, queuename, peer, member, callstart, vars, sizeof(vars), AGENT);
 			}
 			ast_channel_lock(qe->chan);
 			if ((tds = ast_channel_datastore_find(qe->chan, &queue_transfer_info, NULL))) {
@@ -4099,8 +4096,7 @@ static int try_calling(struct queue_ent *qe, const char *options, char *announce
 		if (transfer_ds) {
 			ast_datastore_free(transfer_ds);
 		}
-		if (bridge != AST_PBX_NO_HANGUP_PEER && bridge != AST_PBX_NO_HANGUP_PEER_PARKED)
-			ast_hangup(peer);
+		ast_hangup(peer);
 		res = bridge ? bridge : 1;
 		ao2_ref(member, -1);
 	}
@@ -5065,7 +5061,7 @@ stop:
 	}
 
 	/* Don't allow return code > 0 */
-	if (res >= 0 && res != AST_PBX_KEEPALIVE) {
+	if (res >= 0) {
 		res = 0;	
 		if (ringing) {
 			ast_indicate(chan, -1);
diff --git a/include/asterisk/features.h b/include/asterisk/features.h
index a3716cb92635f28f95fe6749fb96061b71daab40..4d581885dc998634c796c6c66b314a28a366182d 100644
--- a/include/asterisk/features.h
+++ b/include/asterisk/features.h
@@ -61,18 +61,13 @@ struct ast_call_feature {
 	AST_LIST_ENTRY(ast_call_feature) feature_entry;
 };
 
-
 #define AST_FEATURE_RETURN_HANGUP                   -1
 #define AST_FEATURE_RETURN_SUCCESSBREAK             0
-#define AST_FEATURE_RETURN_PBX_KEEPALIVE            AST_PBX_KEEPALIVE
-#define AST_FEATURE_RETURN_NO_HANGUP_PEER           AST_PBX_NO_HANGUP_PEER
-#define AST_FEATURE_RETURN_NO_HANGUP_PEER_PARKED    AST_PBX_NO_HANGUP_PEER_PARKED
 #define AST_FEATURE_RETURN_PASSDIGITS               21
 #define AST_FEATURE_RETURN_STOREDIGITS              22
 #define AST_FEATURE_RETURN_SUCCESS                  23
 #define AST_FEATURE_RETURN_KEEPTRYING               24
 
-
 /*!
  * \brief Park a call and read back parked location 
  * \param chan the channel to actually be parked
diff --git a/include/asterisk/pbx.h b/include/asterisk/pbx.h
index 22144538abb5e2ff77007e2c0832f2c3d59c6874..161277efe5c871b9e5c9c279dabc818aee1d6404 100644
--- a/include/asterisk/pbx.h
+++ b/include/asterisk/pbx.h
@@ -41,10 +41,7 @@ extern "C" {
 #define AST_PBX_HANGUP                -1    /*!< Jump to the 'h' exten */
 #define AST_PBX_OK                     0    /*!< No errors */
 #define AST_PBX_ERROR                  1    /*!< Jump to the 'e' exten */
-#define AST_PBX_KEEPALIVE              10   /*!< Destroy the thread, but don't hang up the channel */
-#define AST_PBX_NO_HANGUP_PEER         11   /*!< The peer has been involved in a transfer */
 #define AST_PBX_INCOMPLETE             12   /*!< Return to PBX matching, allowing more digits for the extension */
-#define AST_PBX_NO_HANGUP_PEER_PARKED  13   /*!< Don't touch the peer channel - it was sent to the parking lot and might be gone by now */
 /*! } */
 
 #define PRIORITY_HINT	-1	/*!< Special Priority for a hint */
diff --git a/main/features.c b/main/features.c
index 184196b8f85536ff6e1b1b328ef0ee695e33997d..e243e2c55dcc3394c17d1ce969e87abe00d405ac 100644
--- a/main/features.c
+++ b/main/features.c
@@ -832,29 +832,22 @@ static int builtin_parkcall(struct ast_channel *chan, struct ast_channel *peer,
 	int res = 0;
 
 	set_peers(&parker, &parkee, peer, chan, sense);
-	/* Setup the exten/priority to be s/1 since we don't know
-	   where this call should return */
-	strcpy(chan->exten, "s");
-	chan->priority = 1;
+	/* we used to set chan's exten and priority to "s" and 1
+	   here, but this generates (in some cases) an invalid
+	   extension, and if "s" exists, could errantly
+	   cause execution of extensions you don't expect. It
+	   makes more sense to let nature take its course
+	   when chan finishes, and let the pbx do its thing
+	   and hang up when the park is over.
+	*/
 	if (chan->_state != AST_STATE_UP)
 		res = ast_answer(chan);
 	if (!res)
 		res = ast_safe_sleep(chan, 1000);
 
-	if (!res) {
-		if (sense == FEATURE_SENSE_CHAN) {
-			res = ast_park_call(parkee, parker, 0, NULL);
-			if (!res) {
-				if (sense == FEATURE_SENSE_CHAN) {
-					res = AST_PBX_NO_HANGUP_PEER_PARKED;
-				} else {
-					res = AST_PBX_KEEPALIVE;
-				}
-			}
-		} else if (sense == FEATURE_SENSE_PEER) {
-			masq_park_call_announce(parkee, parker, 0, NULL);
-			res = 0; /* PBX should hangup zombie channel */
-		}
+	if (!res) { /* one direction used to call park_call.... */
+		masq_park_call_announce(parkee, parker, 0, NULL);
+		res = 0; /* PBX should hangup zombie channel */
 	}
 
 	return res;
@@ -1191,12 +1184,12 @@ static int builtin_blindtransfer(struct ast_channel *chan, struct ast_channel *p
 		res = finishup(transferee);
 		if (res)
 			res = -1;
-		else if (!ast_park_call(transferee, transferer, 0, NULL)) {	/* success */
+		else if (!masq_park_call_announce(transferee, transferer, 0, NULL)) {	/* success */
 			/* We return non-zero, but tell the PBX not to hang the channel when
 			   the thread dies -- We have to be careful now though.  We are responsible for 
 			   hanging up the channel, else it will never be hung up! */
 
-			return (transferer == peer) ? AST_PBX_KEEPALIVE : AST_PBX_NO_HANGUP_PEER_PARKED;
+			return 0;
 		} else {
 			ast_log(LOG_WARNING, "Unable to park call %s\n", transferee->name);
 		}
@@ -1747,7 +1740,7 @@ struct ast_call_feature *ast_find_call_feature(const char *name)
  * \param chan,peer,config,code,sense,data
  *
  * Find a feature, determine which channel activated
- * \retval AST_FEATURE_RETURN_PBX_KEEPALIVE,AST_FEATURE_RETURN_NO_HANGUP_PEER
+ * \retval AST_FEATURE_RETURN_NO_HANGUP_PEER
  * \retval -1 error.
  * \retval -2 when an application cannot be found.
 */
@@ -1802,20 +1795,9 @@ static int feature_exec_app(struct ast_channel *chan, struct ast_channel *peer,
 
 	ast_autoservice_stop(idle);
 
-	if (res == AST_PBX_KEEPALIVE) {
-		/* do not hangup peer if feature is to be activated on it */
-		if ((ast_test_flag(feature, AST_FEATURE_FLAG_ONPEER) && sense == FEATURE_SENSE_CHAN) || (ast_test_flag(feature, AST_FEATURE_FLAG_ONSELF) && sense == FEATURE_SENSE_PEER))
-			return AST_FEATURE_RETURN_NO_HANGUP_PEER;
-		else
-			return AST_FEATURE_RETURN_PBX_KEEPALIVE;
-	}
-	else if (res == AST_PBX_NO_HANGUP_PEER)
-		return AST_FEATURE_RETURN_NO_HANGUP_PEER;
-	else if (res == AST_PBX_NO_HANGUP_PEER_PARKED)
-		return AST_FEATURE_RETURN_NO_HANGUP_PEER_PARKED;
-	else if (res)
+	if (res) {
 		return AST_FEATURE_RETURN_SUCCESSBREAK;
-	
+	}
 	return AST_FEATURE_RETURN_SUCCESS;	/*! \todo XXX should probably return res */
 }
 
@@ -2472,7 +2454,7 @@ int ast_bridge_call(struct ast_channel *chan,struct ast_channel *peer,struct ast
 
 	}
    before_you_go:
-	if (res != AST_PBX_KEEPALIVE && config->end_bridge_callback) {
+	if (config->end_bridge_callback) {
 		config->end_bridge_callback(config->end_bridge_callback_data);
 	}
 
@@ -2482,7 +2464,7 @@ int ast_bridge_call(struct ast_channel *chan,struct ast_channel *peer,struct ast
 	 */
 	autoloopflag = ast_test_flag(chan, AST_FLAG_IN_AUTOLOOP);
 	ast_set_flag(chan, AST_FLAG_IN_AUTOLOOP);
-	if (res != AST_PBX_KEEPALIVE && !ast_test_flag(&(config->features_caller),AST_FEATURE_NO_H_EXTEN) && ast_exists_extension(chan, chan->context, "h", 1, chan->cid.cid_num)) {
+	if (!ast_test_flag(&(config->features_caller),AST_FEATURE_NO_H_EXTEN) && ast_exists_extension(chan, chan->context, "h", 1, chan->cid.cid_num)) {
 		struct ast_cdr *swapper = NULL;
 		char savelastapp[AST_MAX_EXTENSION];
 		char savelastdata[AST_MAX_EXTENSION];
@@ -2533,11 +2515,9 @@ int ast_bridge_call(struct ast_channel *chan,struct ast_channel *peer,struct ast
 	ast_set2_flag(chan, autoloopflag, AST_FLAG_IN_AUTOLOOP);
 
 	/* obey the NoCDR() wishes. -- move the DISABLED flag to the bridge CDR if it was set on the channel during the bridge... */
-	if (res != AST_PBX_KEEPALIVE) {
-		new_chan_cdr = pick_unlocked_cdr(chan->cdr); /* the proper chan cdr, if there are forked cdrs */
-		if (bridge_cdr && new_chan_cdr && ast_test_flag(new_chan_cdr, AST_CDR_FLAG_POST_DISABLED))
-			ast_set_flag(bridge_cdr, AST_CDR_FLAG_POST_DISABLED);
-	}
+	new_chan_cdr = pick_unlocked_cdr(chan->cdr); /* the proper chan cdr, if there are forked cdrs */
+	if (bridge_cdr && new_chan_cdr && ast_test_flag(new_chan_cdr, AST_CDR_FLAG_POST_DISABLED))
+		ast_set_flag(bridge_cdr, AST_CDR_FLAG_POST_DISABLED);
 
 	/* we can post the bridge CDR at this point */
 	if (bridge_cdr) {
@@ -2567,23 +2547,9 @@ int ast_bridge_call(struct ast_channel *chan,struct ast_channel *peer,struct ast
 	   5. After a bridge occurs, we have 2 or 3 channels' CDRs
 	      to attend to; if the chan or peer changed names,
 	      we have the before and after attached CDR's.
-	   6. Parking has to be accounted for in the code:
-	      a. Parking will cause ast_bridge_call to return
-	         either AST_PBX_NO_HANGUP_PEER or AST_PBX_NO_HANGUP_PEER_PARKED;
-			 in the latter case, peer is (most likely) a bad
-			 pointer, you can no longer deref it. If it does still
-			 exist, it is under another's thread control, and
-			 could be destroyed at any time.
-          b. The same applies to AST_PBX_KEEPALIVE, in which
-		     case, the chan ptr cannot be used, as another thread
-			 owns it and may have destroyed the channel.
-	      c. In the former case, you need to check peer to see if it 
-	         still exists before you deref it, and obtain a lock.
-	      d. In neither case should you do an ast_hangup(peer).
-		  e. Do not overwrite the result code from ast_bridge_call.
 	*/
 	
-	if (res != AST_PBX_KEEPALIVE && new_chan_cdr) {
+	if (new_chan_cdr) {
 		struct ast_channel *chan_ptr = NULL;
  
  		if (strcasecmp(orig_channame, chan->name) != 0) { 
@@ -2609,7 +2575,7 @@ int ast_bridge_call(struct ast_channel *chan,struct ast_channel *peer,struct ast
  		}
 	}
 	
-	if (res != AST_PBX_NO_HANGUP_PEER_PARKED) { /* if the peer was involved in a park, don't even touch it; it's probably gone */
+	{
 		struct ast_channel *chan_ptr = NULL;
 		new_peer_cdr = pick_unlocked_cdr(peer->cdr); /* the proper chan cdr, if there are forked cdrs */
 		if (new_chan_cdr && ast_test_flag(new_chan_cdr, AST_CDR_FLAG_POST_DISABLED) && new_peer_cdr && !ast_test_flag(new_peer_cdr, AST_CDR_FLAG_POST_DISABLED))
@@ -2956,14 +2922,19 @@ static int park_call_exec(struct ast_channel *chan, void *data)
 		ast_app_parse_options(park_call_options, &flags, NULL, app_args.options);
 		args.flags = flags.flags;
 
-		res = ast_park_call_full(chan, chan, &args);
+		res = ast_park_call_full(chan, chan, &args); /* In experiments, using the masq_park_call
+													   func here yielded no difference with 
+													   current implementation. I saw no advantage
+													   in calling it instead.
+													 */
 		/* Continue on in the dialplan */
 		if (res == 1) {
 			ast_copy_string(chan->exten, orig_exten, sizeof(chan->exten));
 			chan->priority = orig_priority;
 			res = 0;
-		} else if (!res)
-			res = AST_PBX_KEEPALIVE;
+		} else if (!res) {
+			res = 1;
+		}
 	}
 
 	return res;
@@ -3088,8 +3059,7 @@ static int park_exec_full(struct ast_channel *chan, void *data, struct ast_parki
 		ast_cdr_setdestchan(chan->cdr, peer->name);
 
 		/* Simulate the PBX hanging up */
-		if (res != AST_PBX_NO_HANGUP_PEER && res != AST_PBX_NO_HANGUP_PEER_PARKED)
-			ast_hangup(peer);
+		ast_hangup(peer);
 		return res;
 	} else {
 		/*! \todo XXX Play a message XXX */
diff --git a/main/pbx.c b/main/pbx.c
index 45c87faedef6434afb1c67b60934f8ba85860479..5c1755329c91f849376eb4866111962c3f5e6b10 100644
--- a/main/pbx.c
+++ b/main/pbx.c
@@ -4202,10 +4202,6 @@ static enum ast_pbx_result __ast_pbx_run(struct ast_channel *c,
 				pos = 0;
 				dst_exten[pos++] = digit = res;
 				dst_exten[pos] = '\0';
-			} else if (res == AST_PBX_KEEPALIVE) {
-				ast_debug(1, "Spawn extension (%s,%s,%d) exited KEEPALIVE on '%s'\n", c->context, c->exten, c->priority, c->name);
-				ast_verb(2, "Spawn extension (%s, %s, %d) exited KEEPALIVE on '%s'\n", c->context, c->exten, c->priority, c->name);
-				error = 1;
 			} else if (res == AST_PBX_INCOMPLETE) {
 				ast_debug(1, "Spawn extension (%s,%s,%d) exited INCOMPLETE on '%s'\n", c->context, c->exten, c->priority, c->name);
 				ast_verb(2, "Spawn extension (%s, %s, %d) exited INCOMPLETE on '%s'\n", c->context, c->exten, c->priority, c->name);