diff --git a/coreapi/help/java/org/linphone/core/tutorials/TutorialRegistration.java b/coreapi/help/java/org/linphone/core/tutorials/TutorialRegistration.java
index 08e3c4ea334a883b42a079de41943bc434908870..7ca24bbf02a1a8b8d67e7fbd5252b3177be36cfa 100644
--- a/coreapi/help/java/org/linphone/core/tutorials/TutorialRegistration.java
+++ b/coreapi/help/java/org/linphone/core/tutorials/TutorialRegistration.java
@@ -65,9 +65,6 @@ public class TutorialRegistration implements LinphoneCoreListener {
 	 */
 	public void registrationState(LinphoneCore lc, LinphoneProxyConfig cfg,RegistrationState cstate, String smessage) {
 		write(cfg.getIdentity() + " : "+smessage+"\n");
-
-		if (RegistrationState.RegistrationOk.equals(cstate))
-			running = false;
 	}
 
 	public void show(LinphoneCore lc) {}
@@ -127,36 +124,57 @@ public class TutorialRegistration implements LinphoneCoreListener {
 
 			// create proxy config
 			LinphoneProxyConfig proxyCfg = lcFactory.createProxyConfig(sipAddress, domain, null, true);
+			proxyCfg.setExpires(2000);
 			lc.addProxyConfig(proxyCfg); // add it to linphone
 			lc.setDefaultProxyConfig(proxyCfg);
 
-			
-			
+
 			
 			// main loop for receiving notifications and doing background linphonecore work
 			running = true;
 			while (running) {
 				lc.iterate(); // first iterate initiates registration 
-				try{
-					Thread.sleep(50);
-				} catch(InterruptedException ie) {
-					write("Interrupted!\nAborting");
-					return;
-				}
+				sleep(50);
+			}
+
+
+			// Unregister
+			lc.getDefaultProxyConfig().edit();
+			lc.getDefaultProxyConfig().enableRegister(false);
+			lc.getDefaultProxyConfig().done();
+			while(lc.getDefaultProxyConfig().getState() != RegistrationState.RegistrationCleared) {
+				lc.iterate();
+				sleep(50);
+			}
+
+			// Then register again
+			lc.getDefaultProxyConfig().edit();
+			lc.getDefaultProxyConfig().enableRegister(true);
+			lc.getDefaultProxyConfig().done();
+
+			while(lc.getDefaultProxyConfig().getState() != RegistrationState.RegistrationOk
+					&& lc.getDefaultProxyConfig().getState() != RegistrationState.RegistrationFailed) {
+				lc.iterate();
+				sleep(50);
 			}
 
 
 			// Automatic unregistration on exit
-			
-			
 		} finally {
-			write("Shutting down...");
+			write("Shutting down linphone...");
 			// You need to destroy the LinphoneCore object when no longer used
 			lc.destroy();
-			write("Exited");
 		}
 	}
 
+	private void sleep(int ms) {
+		try {
+			Thread.sleep(ms);
+		} catch(InterruptedException ie) {
+			write("Interrupted!\nAborting");
+			return;
+		}
+	}
 
 	public void stopMainLoop() {
 		running=false;
diff --git a/coreapi/linphonecore_jni.cc b/coreapi/linphonecore_jni.cc
index d22edef6175c68904a5a122473dbb578a65b4e45..3a9346999fa5e514d422323e111936e8ef4f6c62 100644
--- a/coreapi/linphonecore_jni.cc
+++ b/coreapi/linphonecore_jni.cc
@@ -924,3 +924,10 @@ extern "C" void Java_org_linphone_core_LinphoneChatRoomImpl_sendMessage(JNIEnv*
 
 }
 
+extern "C" int Java_org_linphone_core_LinphoneProxyConfigImpl_getState(JNIEnv*  env,jobject thiz,jlong ptr) {
+	return (int) linphone_proxy_config_get_state((const LinphoneProxyConfig *) ptr);
+}
+extern "C" void Java_org_linphone_core_LinphoneProxyConfigImpl_setExpires(JNIEnv*  env,jobject thiz,jlong ptr,jint delay) {
+	linphone_proxy_config_expires((LinphoneProxyConfig *) ptr, (int) delay);
+}
+
diff --git a/java/common/org/linphone/core/LinphoneProxyConfig.java b/java/common/org/linphone/core/LinphoneProxyConfig.java
index 729fd249d5c389c2740ddc9d0738c8d80b4918c8..31444827582781d3fbfe296e36596cbad683b3e5 100644
--- a/java/common/org/linphone/core/LinphoneProxyConfig.java
+++ b/java/common/org/linphone/core/LinphoneProxyConfig.java
@@ -113,4 +113,11 @@ public interface LinphoneProxyConfig {
 	 */
 	public String getRoute();
 	
+	LinphoneCore.RegistrationState getState();
+	
+	/**
+	 * Sets the registration expiration time.
+	 * @param delay expiration time in seconds
+	 */
+	void setExpires(int delay);
 }