diff --git a/channels/chan_sip.c b/channels/chan_sip.c
index 53c80e9472253210a1c92de2ab11cf16b1ee131b..f8b0470670ab85e0c056061d5ba27f4893f8079d 100644
--- a/channels/chan_sip.c
+++ b/channels/chan_sip.c
@@ -2373,9 +2373,8 @@ static enum sip_result __sip_reliable_xmit(struct sip_pvt *p, int seqno, int res
 		siptimer_a = pkt->timer_t1 * 2;
 
 	/* Schedule retransmission */
-	if (pkt->retransid > -1)
-		ast_sched_del(sched, pkt->retransid);
-	pkt->retransid = ast_sched_add_variable(sched, siptimer_a, retrans_pkt, pkt, 1);
+	pkt->retransid = ast_sched_replace_variable(pkt->retransid, sched, 
+		siptimer_a, retrans_pkt, pkt, 1);
 	if (sipdebug)
 		ast_debug(4, "*** SIP TIMER: Initalizing retransmit timer on packet: Id  #%d\n", pkt->retransid);
 	if (sipmethod == SIP_INVITE) {
@@ -3134,10 +3133,8 @@ static struct sip_peer *realtime_peer(const char *newpeername, struct sockaddr_i
 		/* Cache peer */
 		ast_copy_flags(&peer->flags[1],&global_flags[1], SIP_PAGE2_RTAUTOCLEAR|SIP_PAGE2_RTCACHEFRIENDS);
 		if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTAUTOCLEAR)) {
-			if (peer->expire > -1) {
-				ast_sched_del(sched, peer->expire);
-			}
-			peer->expire = ast_sched_add(sched, global_rtautoclear * 1000, expire_register, (void *)peer);
+			peer->expire = ast_sched_replace(peer->expire, sched, 
+				global_rtautoclear * 1000, expire_register, (void *) peer);
 		}
 		ASTOBJ_CONTAINER_LINK(&peerl,peer);
 	} else {
@@ -3563,9 +3560,8 @@ static int sip_call(struct ast_channel *ast, char *dest, int timeout)
 		p->invitestate = INV_CALLING;
 	
 		/* Initialize auto-congest time */
-		if (p->initid > -1)
-			ast_sched_del(sched, p->initid);
-		p->initid = ast_sched_add(sched, SIP_TRANS_TIMEOUT, auto_congest, dialog_ref(p));
+		p->initid = ast_sched_replace(p->initid, sched, SIP_TRANS_TIMEOUT, 
+			auto_congest, dialog_ref(p));
 	}
 
 	return res;
@@ -8182,8 +8178,8 @@ static int transmit_register(struct sip_registry *r, int sipmethod, const char *
 			 * probably DNS.  We need to reschedule a registration try */
 			sip_destroy(p);
 			if (r->timeout > -1) {
-				ast_sched_del(sched, r->timeout);
-				r->timeout = ast_sched_add(sched, global_reg_timeout*1000, sip_reg_timeout, r);
+				r->timeout = ast_sched_replace(r->timeout, sched, 
+					global_reg_timeout * 1000, sip_reg_timeout, r);
 				ast_log(LOG_WARNING, "Still have a registration timeout for %s@%s (create_addr() error), %d\n", r->username, r->hostname, r->timeout);
 			} else {
 				r->timeout = ast_sched_add(sched, global_reg_timeout*1000, sip_reg_timeout, r);
@@ -8232,11 +8228,9 @@ static int transmit_register(struct sip_registry *r, int sipmethod, const char *
 
 	/* set up a timeout */
 	if (auth == NULL)  {
-		if (r->timeout > -1) {
+		if (r->timeout > -1)
 			ast_log(LOG_WARNING, "Still have a registration timeout, #%d - deleting it\n", r->timeout);
-			ast_sched_del(sched, r->timeout);
-		}
-		r->timeout = ast_sched_add(sched, global_reg_timeout * 1000, sip_reg_timeout, r);
+		r->timeout = ast_sched_replace(r->timeout, sched, global_reg_timeout * 1000, sip_reg_timeout, r);
 		ast_debug(1, "Scheduled a registration timeout for %s id  #%d \n", r->hostname, r->timeout);
 	}
 
@@ -8613,14 +8607,12 @@ static void reg_source_db(struct sip_peer *peer)
 	peer->addr.sin_port = htons(port);
 	if (sipsock < 0) {
 		/* SIP isn't up yet, so schedule a poke only, pretty soon */
-		if (peer->pokeexpire > -1)
-			ast_sched_del(sched, peer->pokeexpire);
-		peer->pokeexpire = ast_sched_add(sched, ast_random() % 5000 + 1, sip_poke_peer_s, peer);
+		peer->pokeexpire = ast_sched_replace(peer->pokeexpire, sched, 
+			ast_random() % 5000 + 1, sip_poke_peer_s, peer);
 	} else
 		sip_poke_peer(peer);
-	if (peer->expire > -1)
-		ast_sched_del(sched, peer->expire);
-	peer->expire = ast_sched_add(sched, (expiry + 10) * 1000, expire_register, peer);
+	peer->expire = ast_sched_replace(peer->expire, sched, 
+		(expiry + 10) * 1000, expire_register, peer);
 	register_peer_exten(peer, TRUE);
 }
 
@@ -13443,9 +13435,7 @@ static int handle_response_register(struct sip_pvt *p, int resp, char *rest, str
 		r->refresh= (int) expires_ms / 1000;
 
 		/* Schedule re-registration before we expire */
-		if (r->expire > -1)
-			ast_sched_del(sched, r->expire);
-		r->expire = ast_sched_add(sched, expires_ms, sip_reregister, r); 
+		r->expire = ast_sched_replace(r->expire, sched, expires_ms, sip_reregister, r); 
 		registry_unref(r);
 	}
 	return 1;
@@ -13490,12 +13480,10 @@ static void handle_response_peerpoke(struct sip_pvt *p, int resp, struct sip_req
 			register_peer_exten(peer, TRUE);
 	}
 
-	if (peer->pokeexpire > -1)
-		ast_sched_del(sched, peer->pokeexpire);
 	p->needdestroy = 1;
 
 	/* Try again eventually */
-	peer->pokeexpire = ast_sched_add(sched,
+	peer->pokeexpire = ast_sched_replace(peer->pokeexpire, sched,
 		is_reachable ? DEFAULT_FREQ_OK : DEFAULT_FREQ_NOTOK,
 		sip_poke_peer_s, peer);
 }
@@ -16570,9 +16558,8 @@ static int sip_poke_noanswer(void *data)
 	peer->lastms = -1;
 	ast_device_state_changed("SIP/%s", peer->name);
 	/* Try again quickly */
-	if (peer->pokeexpire > -1)
-		ast_sched_del(sched, peer->pokeexpire);
-	peer->pokeexpire = ast_sched_add(sched, DEFAULT_FREQ_NOTOK, sip_poke_peer_s, peer);
+	peer->pokeexpire = ast_sched_replace(peer->pokeexpire, sched, 
+		DEFAULT_FREQ_NOTOK, sip_poke_peer_s, peer);
 	return 0;
 }
 
@@ -16635,9 +16622,8 @@ static int sip_poke_peer(struct sip_peer *peer)
 	if (xmitres == XMIT_ERROR)
 		sip_poke_noanswer(peer);	/* Immediately unreachable, network problems */
 	else {
-		if (peer->pokeexpire > -1)
-			ast_sched_del(sched, peer->pokeexpire);
-		peer->pokeexpire = ast_sched_add(sched, DEFAULT_MAXMS * 2, sip_poke_noanswer, peer);
+		peer->pokeexpire = ast_sched_replace(peer->pokeexpire, sched, 
+			DEFAULT_MAXMS * 2, sip_poke_noanswer, peer);
 	}
 
 	return 0;
@@ -18672,10 +18658,9 @@ static void sip_poke_all_peers(void)
 
 	ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do {
 		ASTOBJ_WRLOCK(iterator);
-		if (iterator->pokeexpire > -1)
-			ast_sched_del(sched, iterator->pokeexpire);
 		ms += 100;
-		iterator->pokeexpire = ast_sched_add(sched, ms, sip_poke_peer_s, iterator);
+		iterator->pokeexpire = ast_sched_replace(iterator->pokeexpire, 
+			sched, ms, sip_poke_peer_s, iterator);
 		ASTOBJ_UNLOCK(iterator);
 	} while (0)
 	);
@@ -18694,10 +18679,9 @@ static void sip_send_all_registers(void)
 	ms = regspacing;
 	ASTOBJ_CONTAINER_TRAVERSE(&regl, 1, do {
 		ASTOBJ_WRLOCK(iterator);
-		if (iterator->expire > -1)
-			ast_sched_del(sched, iterator->expire);
 		ms += regspacing;
-		iterator->expire = ast_sched_add(sched, ms, sip_reregister, iterator);
+		iterator->expire = ast_sched_replace(iterator->expire, 
+			sched, ms, sip_reregister, iterator);
 		ASTOBJ_UNLOCK(iterator);
 	} while (0)
 	);
diff --git a/include/asterisk/sched.h b/include/asterisk/sched.h
index 00dc7a0a200a3b3906b1806a342085ef9e42d606..5238ecab5785ef23650c6d265e7688623b64fe22 100644
--- a/include/asterisk/sched.h
+++ b/include/asterisk/sched.h
@@ -71,6 +71,18 @@ typedef int (*ast_sched_cb)(void *data);
  */
 int ast_sched_add(struct sched_context *con, int when, ast_sched_cb callback, void *data);
 
+/*!
+ * \brief replace a scheduler entry
+ *
+ * This deletes the scheduler entry for old_id if it exists, and then
+ * calls ast_sched_add to create a new entry.  A negative old_id will
+ * be ignored.
+ *
+ * \retval -1 failure
+ * \retval otherwise, returns scheduled item ID
+ */
+int ast_sched_replace(int old_id, struct sched_context *con, int when, ast_sched_cb callback, void *data);
+
 /*!Adds a scheduled event with rescheduling support
  * \param con Scheduler context to add
  * \param when how many milliseconds to wait for event to occur
@@ -86,6 +98,18 @@ int ast_sched_add(struct sched_context *con, int when, ast_sched_cb callback, vo
  */
 int ast_sched_add_variable(struct sched_context *con, int when, ast_sched_cb callback, void *data, int variable);
 
+/*!
+ * \brief replace a scheduler entry
+ *
+ * This deletes the scheduler entry for old_id if it exists, and then
+ * calls ast_sched_add to create a new entry.  A negative old_id will
+ * be ignored.
+ *
+ * \retval -1 failure
+ * \retval otherwise, returns scheduled item ID
+ */
+int ast_sched_replace_variable(int old_id, struct sched_context *con, int when, ast_sched_cb callback, void *data, int variable);
+
 /*! \brief Deletes a scheduled event
  * Remove this event from being run.  A procedure should not remove its
  * own event, but return 0 instead.
diff --git a/main/sched.c b/main/sched.c
index 1a07ab65912838b92395bcf8f65227d20bad4671..602c8516e5b1218700ad287777fc19bc382ac807 100644
--- a/main/sched.c
+++ b/main/sched.c
@@ -207,6 +207,12 @@ static int sched_settime(struct timeval *tv, int when)
 	return 0;
 }
 
+int ast_sched_replace_variable(int old_id, struct sched_context *con, int when, ast_sched_cb callback, void *data, int variable)
+{
+	if (old_id > -1)
+		ast_sched_del(con, old_id);
+	return ast_sched_add_variable(con, when, callback, data, variable);
+}
 
 /*! \brief
  * Schedule callback(data) to happen when ms into the future
@@ -244,6 +250,13 @@ int ast_sched_add_variable(struct sched_context *con, int when, ast_sched_cb cal
 	return res;
 }
 
+int ast_sched_replace(int old_id, struct sched_context *con, int when, ast_sched_cb callback, void *data)
+{
+	if (old_id > -1)
+		ast_sched_del(con, old_id);
+	return ast_sched_add(con, when, callback, data);
+}
+
 int ast_sched_add(struct sched_context *con, int when, ast_sched_cb callback, void *data)
 {
 	return ast_sched_add_variable(con, when, callback, data, 0);