diff --git a/channels/chan_misdn.c b/channels/chan_misdn.c
index 35ac69d06607f9853ffe3f5976193a9d61483d23..a47d1aa7d001e19f0a229e78eb31e47ea35d7940 100644
--- a/channels/chan_misdn.c
+++ b/channels/chan_misdn.c
@@ -338,6 +338,9 @@ struct hold_info {
 	int channel;
 };
 
+#define chan_list_ref(obj, debug) (ao2_t_ref((obj), +1, (debug)), (obj))
+#define chan_list_unref(obj, debug) (ao2_t_ref((obj), -1, (debug)), NULL)
+
 /*!
  * \brief Channel call record structure
  */
@@ -542,19 +545,6 @@ struct chan_list {
 	 */
 	int nttimeout;
 
-	/*!
-	 * \brief Other channel call record PID
-	 * \note Value imported from Asterisk environment variable MISDN_PID
-	 */
-	int other_pid;
-
-	/*!
-	 * \brief Bridged other channel call record
-	 * \note Pointer set when other_pid imported from Asterisk environment
-	 * variable MISDN_PID by either side.
-	 */
-	struct chan_list *other_ch;
-
 	/*!
 	 * \brief Tone zone sound used for dialtone generation.
 	 * \note Used as a boolean.  Non-NULL to prod generation if enabled.
@@ -744,6 +734,7 @@ static int misdn_chan_is_valid(struct chan_list *ch)
 	return 0;
 }
 
+/*! Returns a reference to the found chan_list. */
 static struct chan_list *get_chan_by_ast(struct ast_channel *ast)
 {
 	struct chan_list *tmp;
@@ -751,6 +742,7 @@ static struct chan_list *get_chan_by_ast(struct ast_channel *ast)
 	ast_mutex_lock(&cl_te_lock);
 	for (tmp = cl_te; tmp; tmp = tmp->next) {
 		if (tmp->ast == ast) {
+			chan_list_ref(tmp, "Found chan_list by ast");
 			ast_mutex_unlock(&cl_te_lock);
 			return tmp;
 		}
@@ -760,6 +752,7 @@ static struct chan_list *get_chan_by_ast(struct ast_channel *ast)
 	return NULL;
 }
 
+/*! Returns a reference to the found chan_list. */
 static struct chan_list *get_chan_by_ast_name(const char *name)
 {
 	struct chan_list *tmp;
@@ -767,6 +760,7 @@ static struct chan_list *get_chan_by_ast_name(const char *name)
 	ast_mutex_lock(&cl_te_lock);
 	for (tmp = cl_te; tmp; tmp = tmp->next) {
 		if (tmp->ast && strcmp(tmp->ast->name, name) == 0) {
+			chan_list_ref(tmp, "Found chan_list by ast name");
 			ast_mutex_unlock(&cl_te_lock);
 			return tmp;
 		}
@@ -5199,12 +5193,15 @@ static char *handle_cli_misdn_send_facility(struct ast_cli_entry *e, int cmd, st
 			ast_verbose("Sending CD with nr %s to %s failed: Channel does not exist.\n", nr, channame);
 			return 0;
 		}
+		ao2_lock(tmp);
 
 #if defined(AST_MISDN_ENHANCEMENTS)
 		max_len = sizeof(tmp->bc->fac_out.u.CallDeflection.Component.Invoke.Deflection.Party.Number) - 1;
 		if (max_len < strlen(nr)) {
 			ast_verbose("Sending CD with nr %s to %s failed: Number too long (up to %u digits are allowed).\n",
 				nr, channame, max_len);
+			ao2_unlock(tmp);
+			chan_list_unref(tmp, "Number too long");
 			return 0;
 		}
 		tmp->bc->fac_out.Function = Fac_CallDeflection;
@@ -5223,6 +5220,8 @@ static char *handle_cli_misdn_send_facility(struct ast_cli_entry *e, int cmd, st
 		if (max_len < strlen(nr)) {
 			ast_verbose("Sending CD with nr %s to %s failed: Number too long (up to %u digits are allowed).\n",
 				nr, channame, max_len);
+			ao2_unlock(tmp);
+			chan_list_unref(tmp, "Number too long");
 			return 0;
 		}
 		tmp->bc->fac_out.Function = Fac_CD;
@@ -5233,7 +5232,9 @@ static char *handle_cli_misdn_send_facility(struct ast_cli_entry *e, int cmd, st
 
 		/* Send message */
 		print_facility(&tmp->bc->fac_out, tmp->bc);
+		ao2_unlock(tmp);
 		misdn_lib_send_event(tmp->bc, EVENT_FACILITY);
+		chan_list_unref(tmp, "Send facility complete");
 #if defined(AST_MISDN_ENHANCEMENTS)
 	} else if (strstr(a->argv[3], "callrerouteing") || strstr(a->argv[3], "callrerouting")) {
 		if (a->argc < 6) {
@@ -5249,11 +5250,14 @@ static char *handle_cli_misdn_send_facility(struct ast_cli_entry *e, int cmd, st
 			ast_verbose("Sending Call Rerouting with nr %s to %s failed: Channel does not exist.\n", nr, channame);
 			return 0;
 		}
+		ao2_lock(tmp);
 
 		max_len = sizeof(tmp->bc->fac_out.u.CallRerouteing.Component.Invoke.CalledAddress.Party.Number) - 1;
 		if (max_len < strlen(nr)) {
 			ast_verbose("Sending Call Rerouting with nr %s to %s failed: Number too long (up to %u digits are allowed).\n",
 				nr, channame, max_len);
+			ao2_unlock(tmp);
+			chan_list_unref(tmp, "Number too long");
 			return 0;
 		}
 		tmp->bc->fac_out.Function = Fac_CallRerouteing;
@@ -5284,11 +5288,13 @@ static char *handle_cli_misdn_send_facility(struct ast_cli_entry *e, int cmd, st
 
 		/* Send message */
 		print_facility(&tmp->bc->fac_out, tmp->bc);
+		ao2_unlock(tmp);
 		misdn_lib_send_event(tmp->bc, EVENT_FACILITY);
+		chan_list_unref(tmp, "Send facility complete");
 #endif	/* defined(AST_MISDN_ENHANCEMENTS) */
-		} else if (strstr(a->argv[3], "CFActivate")) {
-			if (a->argc < 7) {
-				ast_verbose("CFActivate requires 2 args: 1.FromNumber, 2.ToNumber\n\n");
+	} else if (strstr(a->argv[3], "CFActivate")) {
+		if (a->argc < 7) {
+			ast_verbose("CFActivate requires 2 args: 1.FromNumber, 2.ToNumber\n\n");
 			return 0;
 		}
 		port = atoi(a->argv[4]);
@@ -5373,20 +5379,23 @@ static char *handle_cli_misdn_send_facility(struct ast_cli_entry *e, int cmd, st
 		}
 		port = atoi(a->argv[4]);
 
-		channame = argv[4];
+		channame = a->argv[4];
 		tmp = get_chan_by_ast_name(channame);
 		if (tmp) {
 			/* We are going to send this FACILITY message out on an existing connection */
-			msg_number = atoi(argv[5]);
+			msg_number = atoi(a->argv[5]);
 			if (msg_number < ARRAY_LEN(Fac_Msgs)) {
+				ao2_lock(tmp);
 				tmp->bc->fac_out = Fac_Msgs[msg_number];
 
 				/* Send message */
 				print_facility(&tmp->bc->fac_out, tmp->bc);
+				ao2_unlock(tmp);
 				misdn_lib_send_event(tmp->bc, EVENT_FACILITY);
 			} else {
 				ast_verbose("test <channel-name> <msg#>\n\n");
 			}
+			chan_list_unref(tmp, "Facility test done");
 		} else if (a->argc < 6) {
 			for (msg_number = 0; msg_number < ARRAY_LEN(Fac_Msgs); ++msg_number) {
 				misdn_make_dummy(bc, port, 0, misdn_lib_port_is_nt(port), 0);
@@ -5410,16 +5419,16 @@ static char *handle_cli_misdn_send_facility(struct ast_cli_entry *e, int cmd, st
 				ast_verbose("test <port> [<msg#>]\n\n");
 			}
 		}
-	} else if (strstr(argv[3], "register")) {
-		if (argc < 5) {
-			ast_cli(fd, "register <port>\n\n");
+	} else if (strstr(a->argv[3], "register")) {
+		if (a->argc < 5) {
+			ast_verbose("register <port>\n\n");
 			return 0;
 		}
-		port = atoi(argv[4]);
+		port = atoi(a->argv[4]);
 
 		bc = misdn_lib_get_register_bc(port);
 		if (!bc) {
-			ast_cli(fd, "Could not allocate REGISTER bc struct\n\n");
+			ast_verbose("Could not allocate REGISTER bc struct\n\n");
 			return 0;
 		}
 		bc->fac_out = Fac_Msgs[45];
@@ -5501,6 +5510,9 @@ static char *handle_cli_misdn_send_digit(struct ast_cli_entry *e, int cmd, struc
 	}
 #if 1
 	for (i = 0; i < msglen; i++) {
+		if (!tmp->ast) {
+			break;
+		}
 		ast_cli(a->fd, "Sending: %c\n", msg[i]);
 		send_digit_to_chan(tmp, msg[i]);
 		/* res = ast_safe_sleep(tmp->ast, 250); */
@@ -5508,8 +5520,11 @@ static char *handle_cli_misdn_send_digit(struct ast_cli_entry *e, int cmd, struc
 		/* res = ast_waitfor(tmp->ast,100); */
 	}
 #else
-	ast_dtmf_stream(tmp->ast, NULL, msg, 250);
+	if (tmp->ast) {
+		ast_dtmf_stream(tmp->ast, NULL, msg, 250);
+	}
 #endif
+	chan_list_unref(tmp, "Digit(s) sent");
 
 	return CLI_SUCCESS;
 }
@@ -5556,6 +5571,7 @@ static char *handle_cli_misdn_toggle_echocancel(struct ast_cli_entry *e, int cmd
 	} else {
 		manager_ec_disable(tmp->bc);
 	}
+	chan_list_unref(tmp, "Done toggling echo cancel");
 
 	return CLI_SUCCESS;
 }
@@ -5586,12 +5602,16 @@ static char *handle_cli_misdn_send_display(struct ast_cli_entry *e, int cmd, str
 	msg = a->argv[4];
 
 	ast_cli(a->fd, "Sending %s to %s\n", msg, channame);
-	tmp = get_chan_by_ast_name(channame);
 
+	tmp = get_chan_by_ast_name(channame);
 	if (tmp && tmp->bc) {
 		ast_copy_string(tmp->bc->display, msg, sizeof(tmp->bc->display));
 		misdn_lib_send_event(tmp->bc, EVENT_INFORMATION);
+		chan_list_unref(tmp, "Done sending display");
 	} else {
+		if (tmp) {
+			chan_list_unref(tmp, "Display failed");
+		}
 		ast_cli(a->fd, "No such channel %s\n", channame);
 		return CLI_SUCCESS;
 	}
@@ -6457,7 +6477,6 @@ static int misdn_call(struct ast_channel *ast, char *dest, int timeout)
 	int port = 0;
 	int r;
 	int exceed;
-	int bridging;
 	int number_type;
 	struct chan_list *ch;
 	struct misdn_bchannel *newbc;
@@ -6675,20 +6694,6 @@ static int misdn_call(struct ast_channel *ast, char *dest, int timeout)
 			newbc->div_leg_3_rx_wanted = 1;
 		}
 #endif	/* defined(AST_MISDN_ENHANCEMENTS) */
-
-		/*check for bridging*/
-		misdn_cfg_get(0, MISDN_GEN_BRIDGING, &bridging, sizeof(bridging));
-		if (bridging && ch->other_ch) {
-#ifdef MISDN_1_2
-			chan_misdn_log(1, port, "Disabling EC (aka Pipeline) on both Sides\n");
-			*ch->bc->pipeline = 0;
-			*ch->other_ch->bc->pipeline = 0;
-#else
-			chan_misdn_log(1, port, "Disabling EC on both Sides\n");
-			ch->bc->ec_enable = 0;
-			ch->other_ch->bc->ec_enable = 0;
-#endif
-		}
 	}
 
 	exceed = add_out_calls(port);
@@ -6937,18 +6942,6 @@ static int misdn_indication(struct ast_channel *ast, int cond, const void *data,
 			chan_misdn_log(2, p->bc->port, " --> * IND :\tringing pid:%d\n", p->bc->pid);
 			misdn_lib_send_event(p->bc, EVENT_ALERTING);
 
-			if (p->other_ch && p->other_ch->bc) {
-				if (misdn_inband_avail(p->other_ch->bc)) {
-					chan_misdn_log(2, p->bc->port, " --> other End is mISDN and has inband info available\n");
-					break;
-				}
-
-				if (!p->other_ch->bc->nt) {
-					chan_misdn_log(2, p->bc->port, " --> other End is mISDN TE so it has inband info for sure (?)\n");
-					break;
-				}
-			}
-
 			chan_misdn_log(3, p->bc->port, " --> * SEND: State Ring pid:%d\n", p->bc->pid);
 			ast_setstate(ast, AST_STATE_RING);
 
@@ -7034,15 +7027,22 @@ static int misdn_hangup(struct ast_channel *ast)
 		return -1;
 	}
 
+	ast_debug(1, "misdn_hangup(%s)\n", ast->name);
+
+	/* Take the ast_channel's tech_pvt reference. */
 	ast_mutex_lock(&release_lock);
 	p = MISDN_ASTERISK_TECH_PVT(ast);
-	if (!p || !misdn_chan_is_valid(p)) {
+	if (!p) {
 		ast_mutex_unlock(&release_lock);
 		return -1;
 	}
 	MISDN_ASTERISK_TECH_PVT(ast) = NULL;
 
-	ast_debug(1, "misdn_hangup(%s)\n", ast->name);
+	if (!misdn_chan_is_valid(p)) {
+		ast_mutex_unlock(&release_lock);
+		chan_list_unref(p, "Release ast_channel reference.  Was not active?");
+		return 0;
+	}
 
 	if (p->hold.state == MISDN_HOLD_IDLE) {
 		bc = p->bc;
@@ -7054,6 +7054,7 @@ static int misdn_hangup(struct ast_channel *ast)
 				"misdn_hangup: Could not find held bc for (%s)\n", ast->name);
 			release_chan_early(p);
 			ast_mutex_unlock(&release_lock);
+			chan_list_unref(p, "Release ast_channel reference");
 			return 0;
 		}
 	}
@@ -7066,6 +7067,7 @@ static int misdn_hangup(struct ast_channel *ast)
 			misdn_lib_release(bc);
 		}
 		ast_mutex_unlock(&release_lock);
+		chan_list_unref(p, "Release ast_channel reference");
 		return 0;
 	}
 	if (!bc) {
@@ -7073,6 +7075,7 @@ static int misdn_hangup(struct ast_channel *ast)
 			misdn_get_ch_state(p), p->l3id);
 		release_chan_early(p);
 		ast_mutex_unlock(&release_lock);
+		chan_list_unref(p, "Release ast_channel reference");
 		return 0;
 	}
 
@@ -7132,6 +7135,7 @@ static int misdn_hangup(struct ast_channel *ast)
 		release_chan(p, bc);
 		misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE);
 		ast_mutex_unlock(&release_lock);
+		chan_list_unref(p, "Release ast_channel reference");
 		return 0;
 	case MISDN_DIALING:
 		if (p->hold.state == MISDN_HOLD_IDLE) {
@@ -7185,6 +7189,7 @@ static int misdn_hangup(struct ast_channel *ast)
 
 	case MISDN_CLEANING:
 		ast_mutex_unlock(&release_lock);
+		chan_list_unref(p, "Release ast_channel reference");
 		return 0;
 
 	case MISDN_BUSY:
@@ -7208,6 +7213,7 @@ static int misdn_hangup(struct ast_channel *ast)
 		misdn_get_ch_state(p));
 
 	ast_mutex_unlock(&release_lock);
+	chan_list_unref(p, "Release ast_channel reference");
 	return 0;
 }
 
@@ -7494,20 +7500,25 @@ static enum ast_bridge_result misdn_bridge(struct ast_channel *c0,
 	int bridging;
 
 	ch1 = get_chan_by_ast(c0);
+	if (!ch1) {
+		return -1;
+	}
 	ch2 = get_chan_by_ast(c1);
+	if (!ch2) {
+		chan_list_unref(ch1, "Failed to find ch2");
+		return -1;
+	}
 
 	carr[0] = c0;
 	carr[1] = c1;
 
-	if (!(ch1 && ch2)) {
-		return -1;
-	}
-
 	misdn_cfg_get(ch1->bc->port, MISDN_CFG_BRIDGING, &p1_b, sizeof(p1_b));
 	misdn_cfg_get(ch2->bc->port, MISDN_CFG_BRIDGING, &p2_b, sizeof(p2_b));
 
 	if (! p1_b || ! p2_b) {
 		ast_log(LOG_NOTICE, "Falling back to Asterisk bridging\n");
+		chan_list_unref(ch1, "Bridge fallback ch1");
+		chan_list_unref(ch2, "Bridge fallback ch2");
 		return AST_BRIDGE_FAILED;
 	}
 
@@ -7581,6 +7592,8 @@ static enum ast_bridge_result misdn_bridge(struct ast_channel *c0,
 
 	misdn_lib_split_bridge(ch1->bc, ch2->bc);
 
+	chan_list_unref(ch1, "Bridge complete ch1");
+	chan_list_unref(ch2, "Bridge complete ch2");
 	return AST_BRIDGE_COMPLETE;
 }
 
@@ -7663,12 +7676,58 @@ static int stop_bc_tones(struct chan_list *cl)
 	return 0;
 }
 
+/*!
+ * \internal
+ * \brief Destroy the chan_list object.
+ *
+ * \param obj chan_list object to destroy.
+ *
+ * \return Nothing
+ */
+static void chan_list_destructor(void *obj)
+{
+	struct chan_list *ch = obj;
+
+#if defined(AST_MISDN_ENHANCEMENTS)
+	if (ch->peer) {
+		ao2_ref(ch->peer, -1);
+		ch->peer = NULL;
+	}
+#endif /* AST_MISDN_ENHANCEMENTS */
+
+	if (ch->dsp) {
+		ast_dsp_free(ch->dsp);
+		ch->dsp = NULL;
+	}
+
+	/* releasing jitterbuffer */
+	if (ch->jb) {
+		misdn_jb_destroy(ch->jb);
+		ch->jb = NULL;
+	}
+
+	if (ch->overlap_dial) {
+		if (ch->overlap_dial_task != -1) {
+			misdn_tasks_remove(ch->overlap_dial_task);
+			ch->overlap_dial_task = -1;
+		}
+		ast_mutex_destroy(&ch->overlap_tv_lock);
+	}
 
-static struct chan_list *init_chan_list(int orig)
+	if (-1 < ch->pipe[0]) {
+		close(ch->pipe[0]);
+	}
+	if (-1 < ch->pipe[1]) {
+		close(ch->pipe[1]);
+	}
+}
+
+/*! Returns a reference to the new chan_list. */
+static struct chan_list *chan_list_init(int orig)
 {
 	struct chan_list *cl;
 
-	cl = ast_calloc(1, sizeof(*cl));
+	cl = ao2_alloc(sizeof(*cl), chan_list_destructor);
 	if (!cl) {
 		chan_misdn_log(-1, 0, "misdn_request: malloc failed!");
 		return NULL;
@@ -7682,6 +7741,8 @@ static struct chan_list *init_chan_list(int orig)
 #if defined(AST_MISDN_ENHANCEMENTS)
 	cl->record_id = -1;
 #endif	/* defined(AST_MISDN_ENHANCEMENTS) */
+	cl->pipe[0] = -1;
+	cl->pipe[1] = -1;
 
 	return cl;
 }
@@ -7905,7 +7966,7 @@ static struct ast_channel *misdn_request(const char *type, format_t format, cons
 	}
 
 	/* create ast_channel and link all the objects together */
-	cl = init_chan_list(ORG_AST);
+	cl = chan_list_init(ORG_AST);
 	if (!cl) {
 		ast_log(LOG_ERROR, "Could not create call record for Dial(%s)\n", dial_str);
 		return NULL;
@@ -7914,11 +7975,10 @@ static struct ast_channel *misdn_request(const char *type, format_t format, cons
 
 	ast = misdn_new(cl, AST_STATE_RESERVED, args.ext, NULL, format, requestor ? requestor->linkedid : NULL, port, channel);
 	if (!ast) {
-		ast_free(cl);
+		chan_list_unref(cl, "Failed to create a new channel");
 		ast_log(LOG_ERROR, "Could not create Asterisk channel for Dial(%s)\n", dial_str);
 		return NULL;
 	}
-	cl->ast = ast;
 
 #if defined(AST_MISDN_ENHANCEMENTS)
 	cl->record_id = record_id;
@@ -7933,13 +7993,14 @@ static struct ast_channel *misdn_request(const char *type, format_t format, cons
 	/* important */
 	cl->need_hangup = 0;
 
+	chan_list_unref(cl, "Successful misdn_request()");
 	return ast;
 }
 
 
 static int misdn_send_text(struct ast_channel *chan, const char *text)
 {
-	struct chan_list *tmp = chan->tech_pvt;
+	struct chan_list *tmp = MISDN_ASTERISK_TECH_PVT(chan);
 
 	if (tmp && tmp->bc) {
 		ast_copy_string(tmp->bc->display, text, sizeof(tmp->bc->display));
@@ -8050,7 +8111,10 @@ static struct ast_channel *misdn_new(struct chan_list *chlist, int state,  char
 		tmp->writeformat = format;
 		tmp->rawwriteformat = format;
 
-		tmp->tech_pvt = chlist;
+		/* Link the channel and private together */
+		chan_list_ref(chlist, "Give a reference to ast_channel");
+		MISDN_ASTERISK_TECH_PVT(tmp) = chlist;
+		chlist->ast = tmp;
 
 		misdn_cfg_get(0, MISDN_GEN_BRIDGING, &bridging, sizeof(bridging));
 		tmp->tech = bridging ? &misdn_tech : &misdn_tech_wo_bridge;
@@ -8087,6 +8151,7 @@ static struct ast_channel *misdn_new(struct chan_list *chlist, int state,  char
 	return tmp;
 }
 
+/*! Returns a reference to the found chan_list. */
 static struct chan_list *find_chan_by_bc(struct misdn_bchannel *bc)
 {
 	struct chan_list *help;
@@ -8094,6 +8159,7 @@ static struct chan_list *find_chan_by_bc(struct misdn_bchannel *bc)
 	ast_mutex_lock(&cl_te_lock);
 	for (help = cl_te; help; help = help->next) {
 		if (help->bc == bc) {
+			chan_list_ref(help, "Found chan_list by bc");
 			ast_mutex_unlock(&cl_te_lock);
 			return help;
 		}
@@ -8109,24 +8175,7 @@ static struct chan_list *find_chan_by_bc(struct misdn_bchannel *bc)
 	return NULL;
 }
 
-static struct chan_list *find_chan_by_pid(int pid)
-{
-	struct chan_list *help;
-
-	ast_mutex_lock(&cl_te_lock);
-	for (help = cl_te; help; help = help->next) {
-		if (help->bc && (help->bc->pid == pid)) {
-			ast_mutex_unlock(&cl_te_lock);
-			return help;
-		}
-	}
-	ast_mutex_unlock(&cl_te_lock);
-
-	chan_misdn_log(6, 0, "$$$ find_chan_by_pid: No channel found for pid:%d\n", pid);
-
-	return NULL;
-}
-
+/*! Returns a reference to the found chan_list. */
 static struct chan_list *find_hold_call(struct misdn_bchannel *bc)
 {
 	struct chan_list *help;
@@ -8144,6 +8193,7 @@ static struct chan_list *find_hold_call(struct misdn_bchannel *bc)
 	for (help = cl_te; help; help = help->next) {
 		chan_misdn_log(4, bc->port, "$$$ find_hold_call: --> hold:%d channel:%d\n", help->hold.state, help->hold.channel);
 		if (help->hold.state == MISDN_HOLD_ACTIVE && help->hold.port == bc->port) {
+			chan_list_ref(help, "Found chan_list hold call");
 			ast_mutex_unlock(&cl_te_lock);
 			return help;
 		}
@@ -8159,6 +8209,7 @@ static struct chan_list *find_hold_call(struct misdn_bchannel *bc)
 }
 
 
+/*! Returns a reference to the found chan_list. */
 static struct chan_list *find_hold_call_l3(unsigned long l3_id)
 {
 	struct chan_list *help;
@@ -8166,6 +8217,7 @@ static struct chan_list *find_hold_call_l3(unsigned long l3_id)
 	ast_mutex_lock(&cl_te_lock);
 	for (help = cl_te; help; help = help->next) {
 		if (help->hold.state != MISDN_HOLD_IDLE && help->l3id == l3_id) {
+			chan_list_ref(help, "Found chan_list hold call l3");
 			ast_mutex_unlock(&cl_te_lock);
 			return help;
 		}
@@ -8185,6 +8237,8 @@ static struct chan_list *find_hold_call_l3(unsigned long l3_id)
  *
  * \return Found call record or NULL.
  *
+ * \note Returns a reference to the found chan_list.
+ *
  * \note There could be a possibility where we find the wrong active call to transfer.
  * This concern is mitigated by the fact that there could be at most one other call
  * on a PTMP BRI link to another device.  Maybe the l3_id could help in locating an
@@ -8203,6 +8257,7 @@ static struct chan_list *find_hold_active_call(struct misdn_bchannel *bc)
 			case MISDN_PROGRESS:
 			case MISDN_ALERTING:
 			case MISDN_CONNECTED:
+				chan_list_ref(list, "Found chan_list hold active call");
 				ast_mutex_unlock(&cl_te_lock);
 				return list;
 			default:
@@ -8219,6 +8274,7 @@ static void cl_queue_chan(struct chan_list *chan)
 {
 	chan_misdn_log(4, chan->bc ? chan->bc->port : 0, "* Queuing chan %p\n", chan);
 
+	chan_list_ref(chan, "Adding chan_list to list");
 	ast_mutex_lock(&cl_te_lock);
 	chan->next = NULL;
 	if (!cl_te) {
@@ -8251,6 +8307,7 @@ static int cl_dequeue_chan(struct chan_list *chan)
 		/* What we want is the head of the list. */
 		cl_te = cl_te->next;
 		ast_mutex_unlock(&cl_te_lock);
+		chan_list_unref(chan, "Removed chan_list from list head");
 		return 1;
 	}
 
@@ -8265,6 +8322,9 @@ static int cl_dequeue_chan(struct chan_list *chan)
 	}
 
 	ast_mutex_unlock(&cl_te_lock);
+	if (found_it) {
+		chan_list_unref(chan, "Removed chan_list from list");
+	}
 	return found_it;
 }
 
@@ -8326,7 +8386,7 @@ static void hangup_chan(struct chan_list *ch, struct misdn_bchannel *bc)
  *
  * \return Nothing
  *
- * \note ch must not be referenced after calling.
+ * \note The only valid thing to do with ch after calling is to chan_list_unref(ch, "").
  */
 static void release_chan(struct chan_list *ch, struct misdn_bchannel *bc)
 {
@@ -8353,6 +8413,9 @@ static void release_chan(struct chan_list *ch, struct misdn_bchannel *bc)
 	ch->state = MISDN_CLEANING;
 	ch->ast = NULL;
 	if (ast) {
+		struct chan_list *ast_ch;
+
+		ast_ch = MISDN_ASTERISK_TECH_PVT(ast);
 		MISDN_ASTERISK_TECH_PVT(ast) = NULL;
 		chan_misdn_log(1, bc->port,
 			"* RELEASING CHANNEL pid:%d context:%s dialed:%s caller:\"%s\" <%s>\n",
@@ -8367,49 +8430,17 @@ static void release_chan(struct chan_list *ch, struct misdn_bchannel *bc)
 			ast_setstate(ast, AST_STATE_DOWN);
 		}
 		ast_channel_unlock(ast);
-	}
-
-#if defined(AST_MISDN_ENHANCEMENTS)
-	if (ch->peer) {
-		ao2_ref(ch->peer, -1);
-		ch->peer = NULL;
-	}
-#endif /* AST_MISDN_ENHANCEMENTS */
-
-	if (ch->dsp) {
-		ast_dsp_free(ch->dsp);
-		ch->dsp = NULL;
-	}
-
-	/* releasing jitterbuffer */
-	if (ch->jb) {
-		misdn_jb_destroy(ch->jb);
-		ch->jb = NULL;
-	} else {
-		if (!bc->nojitter) {
-			chan_misdn_log(5, bc->port, "Jitterbuffer already destroyed.\n");
+		if (ast_ch) {
+			chan_list_unref(ast_ch, "Release ast_channel reference.");
 		}
 	}
 
-	if (ch->overlap_dial) {
-		if (ch->overlap_dial_task != -1) {
-			misdn_tasks_remove(ch->overlap_dial_task);
-			ch->overlap_dial_task = -1;
-		}
-		ast_mutex_destroy(&ch->overlap_tv_lock);
-	}
-
 	if (ch->originator == ORG_AST) {
 		--misdn_out_calls[bc->port];
 	} else {
 		--misdn_in_calls[bc->port];
 	}
 
-	close(ch->pipe[0]);
-	close(ch->pipe[1]);
-
-	ast_free(ch);
-
 	ast_mutex_unlock(&release_lock);
 }
 
@@ -8421,7 +8452,7 @@ static void release_chan(struct chan_list *ch, struct misdn_bchannel *bc)
  *
  * \return Nothing
  *
- * \note ch must not be referenced after calling.
+ * \note The only valid thing to do with ch after calling is to chan_list_unref(ch, "").
  */
 static void release_chan_early(struct chan_list *ch)
 {
@@ -8446,37 +8477,18 @@ static void release_chan_early(struct chan_list *ch)
 	ch->state = MISDN_CLEANING;
 	ch->ast = NULL;
 	if (ast) {
+		struct chan_list *ast_ch;
+
+		ast_ch = MISDN_ASTERISK_TECH_PVT(ast);
 		MISDN_ASTERISK_TECH_PVT(ast) = NULL;
+
 		if (ast->_state != AST_STATE_RESERVED) {
 			ast_setstate(ast, AST_STATE_DOWN);
 		}
 		ast_channel_unlock(ast);
-	}
-
-#if defined(AST_MISDN_ENHANCEMENTS)
-	if (ch->peer) {
-		ao2_ref(ch->peer, -1);
-		ch->peer = NULL;
-	}
-#endif /* AST_MISDN_ENHANCEMENTS */
-
-	if (ch->dsp) {
-		ast_dsp_free(ch->dsp);
-		ch->dsp = NULL;
-	}
-
-	/* releasing jitterbuffer */
-	if (ch->jb) {
-		misdn_jb_destroy(ch->jb);
-		ch->jb = NULL;
-	}
-
-	if (ch->overlap_dial) {
-		if (ch->overlap_dial_task != -1) {
-			misdn_tasks_remove(ch->overlap_dial_task);
-			ch->overlap_dial_task = -1;
+		if (ast_ch) {
+			chan_list_unref(ast_ch, "Release ast_channel reference.");
 		}
-		ast_mutex_destroy(&ch->overlap_tv_lock);
 	}
 
 	if (ch->hold.state != MISDN_HOLD_IDLE) {
@@ -8487,11 +8499,6 @@ static void release_chan_early(struct chan_list *ch)
 		}
 	}
 
-	close(ch->pipe[0]);
-	close(ch->pipe[1]);
-
-	ast_free(ch);
-
 	ast_mutex_unlock(&release_lock);
 }
 
@@ -8796,18 +8803,6 @@ void import_ch(struct ast_channel *chan, struct misdn_bchannel *bc, struct chan_
 	const char *tmp;
 
 	ast_channel_lock(chan);
-	tmp = pbx_builtin_getvar_helper(chan, "MISDN_PID");
-	if (tmp) {
-		ch->other_pid = atoi(tmp);
-		chan_misdn_log(3, bc->port, " --> IMPORT_PID: importing pid:%s\n", tmp);
-		if (ch->other_pid > 0) {
-			ch->other_ch = find_chan_by_pid(ch->other_pid);
-			if (ch->other_ch) {
-				ch->other_ch->other_ch = ch;
-			}
-		}
-	}
-
 	tmp = pbx_builtin_getvar_helper(chan, "MISDN_ADDRESS_COMPLETE");
 	if (tmp && (atoi(tmp) == 1)) {
 		bc->sending_complete = 1;
@@ -8832,6 +8827,12 @@ void export_ch(struct ast_channel *chan, struct misdn_bchannel *bc, struct chan_
 {
 	char tmp[32];
 
+	/*
+	 * The only use for MISDN_PID is if there is a problem and you
+	 * have to use the "misdn restart pid" CLI command.  Otherwise,
+	 * the pid is not used by anyone.  The internal use of MISDN_PID
+	 * has been deleted.
+	 */
 	chan_misdn_log(3, bc->port, " --> EXPORT_PID: pid:%d\n", bc->pid);
 	snprintf(tmp, sizeof(tmp), "%d", bc->pid);
 	pbx_builtin_setvar_helper(chan, "_MISDN_PID", tmp);
@@ -9962,9 +9963,7 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
 			chan_misdn_log(1, bc->port, "Chan not existing at the moment bc->l3id:%x bc:%p event:%s port:%d channel:%d\n", bc->l3_id, bc, manager_isdn_get_info(event), bc->port, bc->channel);
 			return -1;
 		}
-	}
-
-	if (ch) {
+	} else {
 		switch (event) {
 		case EVENT_TONE_GENERATE:
 			break;
@@ -9982,6 +9981,7 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
 				if (event != EVENT_BCHAN_DATA) {
 					ast_log(LOG_NOTICE, "No Ast or No private Pointer in Event (%d:%s)\n", event, manager_isdn_get_info(event));
 				}
+				chan_list_unref(ch, "No Ast or Ast private pointer");
 				return -1;
 			}
 			break;
@@ -10157,7 +10157,6 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
 		break;
 	case EVENT_SETUP:
 	{
-		struct chan_list *ch = find_chan_by_bc(bc);
 		struct ast_channel *chan;
 		int exceed;
 		int ai;
@@ -10167,9 +10166,11 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
 		if (ch) {
 			switch (ch->state) {
 			case MISDN_NOTHING:
+				chan_list_unref(ch, "Ignore found ch.  Is it for an outgoing call?");
 				ch = NULL;
 				break;
 			default:
+				chan_list_unref(ch, "Already have a call.");
 				chan_misdn_log(1, bc->port, " --> Ignoring Call we have already one\n");
 				return RESPONSE_IGNORE_SETUP_WITHOUT_CLOSE; /*  Ignore MSNs which are not in our List */
 			}
@@ -10190,7 +10191,7 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
 
 		print_bearer(bc);
 
-		ch = init_chan_list(ORG_MISDN);
+		ch = chan_list_init(ORG_MISDN);
 		if (!ch) {
 			chan_misdn_log(-1, bc->port, "cb_events: malloc for chan_list failed!\n");
 			return 0;
@@ -10202,14 +10203,12 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
 
 		chan = misdn_new(ch, AST_STATE_RESERVED, bc->dialed.number, bc->caller.number, AST_FORMAT_ALAW, NULL, bc->port, bc->channel);
 		if (!chan) {
-			ast_free(ch);
+			chan_list_unref(ch, "Failed to create a new channel");
 			misdn_lib_send_event(bc,EVENT_RELEASE_COMPLETE);
 			ast_log(LOG_ERROR, "cb_events: misdn_new failed !\n");
 			return 0;
 		}
 
-		ch->ast = chan;
-
 		if ((exceed = add_in_calls(bc->port))) {
 			char tmp[16];
 			snprintf(tmp, sizeof(tmp), "%d", exceed);
@@ -10292,6 +10291,7 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
 
 				ch->state = MISDN_EXTCANTMATCH;
 				misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE);
+				chan_list_unref(ch, "BC not allowed, releasing call");
 				return RESPONSE_OK;
 			}
 		}
@@ -10679,6 +10679,9 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
 				}
 			}
 		}
+		if (held_ch) {
+			chan_list_unref(held_ch, "Done with held call");
+		}
 		bc->out_cause = -1;
 		if (bc->need_release) {
 			misdn_lib_send_event(bc, EVENT_RELEASE);
@@ -11045,6 +11048,9 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
 		break;
 	}
 
+	if (ch) {
+		chan_list_unref(ch, "cb_event complete OK");
+	}
 	return RESPONSE_OK;
 }
 
@@ -12483,13 +12489,22 @@ static int misdn_set_opt_exec(struct ast_channel *chan, const char *data)
 
 int chan_misdn_jb_empty(struct misdn_bchannel *bc, char *buf, int len)
 {
-	struct chan_list *ch = find_chan_by_bc(bc);
+	struct chan_list *ch;
+	int res;
 
-	if (ch && ch->jb) {
-		return misdn_jb_empty(ch->jb, buf, len);
+	ch = find_chan_by_bc(bc);
+	if (!ch) {
+		return 0;
 	}
 
-	return -1;
+	if (ch->jb) {
+		res = misdn_jb_empty(ch->jb, buf, len);
+	} else {
+		res = 0;
+	}
+	chan_list_unref(ch, "Done emptying jb");
+
+	return res;
 }