diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 8bb553b0396924d27cd165278de05a2dedf0b0d4..80353f24d57fbd67d79880ae1ad8f40563016162 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -20,6 +20,7 @@
         <activity android:name=".activity.MainActivity"
                   android:label="@string/app_name"
                   android:icon="@drawable/ic_launcher_itoopie"
+                  android.theme="@android:style/Theme.NoTitleBar"
                   android:launchMode="singleTask" >
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
@@ -30,5 +31,9 @@
                   android:label="@string/app_name"
                   android.theme="@android:style/Theme.NoTitleBar" >
         </activity>
+        <activity android:name=".activity.TextResourceActivity"
+                  android:label="@string/app_name"
+                  android.theme="@android:style/Theme.NoTitleBar" >
+        </activity>
     </application>
 </manifest> 
diff --git a/build.xml b/build.xml
index b40e02996b60e04bee39e308240a58dfd9c187c4..21d83490e21390ca3f2332d784001da27cc8f808 100644
--- a/build.xml
+++ b/build.xml
@@ -150,6 +150,16 @@
         <copy file="${i2pbase}/installer/resources/themes/console/images/i2plogo.png" todir="res/drawable/" />
         <copy file="${i2pbase}/installer/resources/blocklist.txt" tofile="res/raw/blocklist_txt" />
         <copy file="${i2pbase}/installer/resources/hosts.txt" tofile="res/raw/hosts_txt" />
+        <copy file="${i2pbase}/licenses/LICENSE-ElGamalDSA.txt" tofile="res/raw/license_elgamaldsa_txt" />
+        <copy file="${i2pbase}/licenses/LICENSE-SHA256.txt" tofile="res/raw/license_sha256_txt" />
+        <copy file="${i2pbase}/licenses/LICENSE-BSD.txt" tofile="res/raw/license_bsd_txt" />
+        <copy file="${i2pbase}/licenses/LICENSE-SNTP.txt" tofile="res/raw/license_sntp_txt" />
+        <copy file="${i2pbase}/licenses/LICENSE-LGPLv2.1.txt" tofile="res/raw/license_lgplv2_1_txt" />
+        <copy file="${i2pbase}/licenses/LICENSE-InstallCert.txt" tofile="res/raw/license_installcert_txt" />
+        <copy file="${i2pbase}/licenses/LICENSE-BlockFile.txt" tofile="res/raw/license_blockfile_txt" />
+        <copy file="${i2pbase}/licenses/LICENSE-GPLv2.txt" tofile="res/raw/license_gplv2_txt" />
+        <copy file="${i2pbase}/licenses/LICENSE-GPLv3.txt" tofile="res/raw/license_gplv3_txt" />
+        <copy file="${i2pbase}/licenses/LICENSE-LGPLv3.txt" tofile="res/raw/license_lgplv3_txt" />
     </target>
 
     <target name="hackcleanup">
@@ -182,8 +192,21 @@
         <delete file="res/drawable/i2plogo.png" verbose="${verbose}"/>
         <delete file="res/raw/blocklist_txt" verbose="${verbose}" />
         <delete file="res/raw/hosts_txt" verbose="${verbose}" />
+        <delete file="res/raw/license_elgamaldsa_txt" />
+        <delete file="res/raw/license_sha256_txt" />
+        <delete file="res/raw/license_bsd_txt" />
+        <delete file="res/raw/license_sntp_txt" />
+        <delete file="res/raw/license_lgplv2_1_txt" />
+        <delete file="res/raw/license_installcert_txt" />
+        <delete file="res/raw/license_blockfile_txt" />
+        <delete file="res/raw/license_gplv2_txt" />
+        <delete file="res/raw/license_gplv3_txt" />
+        <delete file="res/raw/license_lgplv3_txt" />
         <delete dir="jni/build/" verbose="${verbose}" />
+        <echo message="Not deleting jni/libjbigi.so" />
+<!--
         <delete file="jni/libjbigi.so" verbose="${verbose}" />
+-->
         <delete file="scripts/build.number" verbose="${verbose}" />
         <delete file="scripts/version.properties" verbose="${verbose}" />
     </target>
diff --git a/res/layout/main.xml b/res/layout/main.xml
index cf9ce895c3e4ad8a0784c4bc71ab086ed407e656..c942bdf9ea498e37c5723a424ff08d4ffc9c5f94 100644
--- a/res/layout/main.xml
+++ b/res/layout/main.xml
@@ -15,24 +15,48 @@
     android:layout_height="wrap_content" 
     android:src="@drawable/i2plogo"
     />
-<Button 
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="horizontal"
+    android:layout_width="fill_parent"
+    android:layout_height="wrap_content" 
+    >
+ <Button 
     android:id="@+id/news_button"
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
-    android:text="Go to news"
+    android:text="News"
+    />
+ <Button 
+    android:id="@+id/releasenotes_button"
+    android:layout_width="wrap_content" 
+    android:layout_height="wrap_content" 
+    android:text="Release Notes"
+    />
+ <Button 
+    android:id="@+id/licenses_button"
+    android:layout_width="wrap_content" 
+    android:layout_height="wrap_content" 
+    android:text="Licenses"
     />
-<Button 
+</LinearLayout>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="horizontal"
+    android:layout_width="fill_parent"
+    android:layout_height="wrap_content" 
+    >
+ <Button 
     android:id="@+id/router_start_button"
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:text="Start router"
     />
-<Button 
+ <Button 
     android:id="@+id/router_stop_button"
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:text="Stop router"
     />
+</LinearLayout>
 <TextView  
     android:id="@+id/main_status_text"
     android:layout_width="fill_parent" 
diff --git a/res/layout/text_resource.xml b/res/layout/text_resource.xml
new file mode 100644
index 0000000000000000000000000000000000000000..0d1503f3e959baa6b69d4d7c50f1ec0196213874
--- /dev/null
+++ b/res/layout/text_resource.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent"
+    >
+<TextView  
+    android:id="@+id/text_resource_text"
+    android:layout_width="fill_parent" 
+    android:layout_height="fill_parent" 
+    android:scrollbars="vertical" 
+    android:text="Release Notes"
+    />
+</LinearLayout>
+
diff --git a/res/raw/i2ptunnel_config b/res/raw/i2ptunnel_config
index 37a71106d253ef09b9c33b5bab57ff44feae1a10..55d0648a68911b006e8830f181be5c982e6c6ba0 100644
--- a/res/raw/i2ptunnel_config
+++ b/res/raw/i2ptunnel_config
@@ -15,10 +15,10 @@ tunnel.0.option.i2cp.reduceIdleTime=600000
 tunnel.0.option.i2cp.reduceOnIdle=true
 tunnel.0.option.i2cp.reduceQuantity=1
 tunnel.0.option.i2p.streaming.connectDelay=1000
-tunnel.0.option.inbound.length=2
-tunnel.0.option.inbound.lengthVariance=0
-tunnel.0.option.outbound.length=2
-tunnel.0.option.outbound.lengthVariance=0
+tunnel.0.option.inbound.length=1
+tunnel.0.option.inbound.lengthVariance=1
+tunnel.0.option.outbound.length=1
+tunnel.0.option.outbound.lengthVariance=1
 tunnel.0.startOnLoad=true
 
 # irc
@@ -38,8 +38,8 @@ tunnel.1.option.i2cp.reduceIdleTime=600000
 tunnel.1.option.i2cp.reduceOnIdle=true
 tunnel.1.option.i2cp.reduceQuantity=1
 tunnel.1.option.i2p.streaming.connectDelay=1000
-tunnel.1.option.inbound.length=2
-tunnel.1.option.inbound.lengthVariance=0
-tunnel.1.option.outbound.length=2
-tunnel.1.option.outbound.lengthVariance=0
+tunnel.1.option.inbound.length=1
+tunnel.1.option.inbound.lengthVariance=1
+tunnel.1.option.outbound.length=1
+tunnel.1.option.outbound.lengthVariance=1
 tunnel.1.startOnLoad=true
diff --git a/res/raw/licenses_txt b/res/raw/licenses_txt
new file mode 100644
index 0000000000000000000000000000000000000000..e5a679788ab45128fb653db2116f277214966d2a
--- /dev/null
+++ b/res/raw/licenses_txt
@@ -0,0 +1,121 @@
+This product includes both public domain code and licensed code as described below.
+For all code, unless otherwise stated in the appropriate license, the following applies:
+
+
+			    NO WARRANTY
+
+  BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+
+
+LICENSES
+--------
+
+Core (i2p.jar):
+Public domain except as listed below:
+
+   ElGamal and DSA code:
+   Copyright (c) 2003, TheCrypto
+   See LICENSE-ElGamalDSA.txt
+
+   SHA256 and HMAC-SHA256:
+   Copyright (c) 2000 - 2004 The Legion Of The Bouncy Castle
+   See LICENSE-SHA256.txt
+
+   AES code:
+   Under the Cryptix (MIT) license, written by the Cryptix team
+   (That's what our website says but all our AES code looks like it is public domain)
+
+   Crypto filters:
+   From the xlattice app - http://xlattice.sourceforge.net/
+   See LICENSE-BSD.txt
+
+   SNTP code:
+   Copyright (c) 2004, Adam Buckley
+   See LICENSE-SNTP.txt
+
+   PRNG:
+   Copyright (C) 2001, 2002, Free Software Foundation, Inc.
+   See LICENSE-LGPLv2.1.txt
+
+   HashCash code:
+   Copyright 2006 Gregory Rubin grrubin@gmail.com
+   See LICENSE-HashCash.txt
+
+   GettextResource from gettext v0.18:
+   Copyright (C) 2001, 2007 Free Software Foundation, Inc.
+   See LICENSE-LGPLv2.1.txt
+
+   SSLEepGet:
+   Contains some code Copyright 2006 Sun Microsystems, Inc.
+   See LICENSE-InstallCert.txt
+
+   BlockFile:
+   Copyright (c) 2006, Matthew Estes
+   See LICENSE-BlockFile.txt
+
+
+Router (router.jar):
+Public domain except as listed below:
+   UPnP.java:
+   From freenet
+   See LICENSE-GPLv2.txt
+
+   UPnP subsystem 1.7:
+   Copyright (C) 2003-2006 Satoshi Konno
+   See LICENSE-UPnP.txt
+
+Jbigi Libraries (jbigi.jar):
+   JNI code public domain.
+
+   GMP 4.3.2 / 5.0.2:
+   Copyright 1991, 1996, 1999, 2000, 2007 Free Software Foundation, Inc.
+   See LICENSE-LGPLv3.txt
+
+
+Applications:
+
+   Addressbook:
+   Copyright (c) 2004 Ragnarok
+   See LICENSE-Addressbook.txt
+
+   I2PTunnel:
+   (c) 2003 - 2004 mihi
+   GPLv2 with exception.
+   See LICENSE-I2PTunnel.txt
+   See LICENSE-GPLv2.txt
+
+   I2PTunnel SOCKS Proxy:
+   Copyright (c) 2004 by human
+   GPLv2 with exception.
+   See LICENSE-I2PTunnel.txt
+   See LICENSE-GPLv2.txt
+
+   I2PTunnel UDP and Streamr:
+   By welterde.
+   See LICENSE-GPLv2.txt
+
+   Ministreaming Lib:
+   By mihi.
+   See LICENSE-BSD.txt
+
+   Streaming Lib:
+   Public domain.
diff --git a/res/raw/releasenotes_txt b/res/raw/releasenotes_txt
new file mode 100644
index 0000000000000000000000000000000000000000..51b40ef0129d71dc0a7dc16e507ad1e4fc0e85ea
--- /dev/null
+++ b/res/raw/releasenotes_txt
@@ -0,0 +1,15 @@
+This is ALPHA SOFTWARE. It may crash your phone. Do not rely upon it for strong anonymity. Tunnels may be as short as one hop.
+
+This is only tested on the Droid. You need at least 256 MB of RAM. 512 should be much better.
+
+The app may be moved to the SD card if you have Froyo (2.2) or higher.
+
+The app will work best when you are not changing IPs. If you are moving around, changing WIFI nodes, or switching from cellular to WIFI networks, it won't work well.
+
+There is an HTTP proxy at localhost port 4444 and a transparent IRC proxy at localhost port 6668.
+
+The HTTP proxy is untested (other than with the news fetcher). It should work with Firefox 4 Mobile and the ProxyMob Firefox plugin, if you have at least 512 MB of RAM.
+
+The IRC proxy is tested with the "Android IRC Free" app.
+
+Report results and bugs on the zzz.i2p Android forum.
diff --git a/res/raw/router_config b/res/raw/router_config
index b448224c28b6e19df2b29e7959e6d9cfb7da6803..cd1015180bf389218fa1ec9f733d0050bef4c94e 100644
--- a/res/raw/router_config
+++ b/res/raw/router_config
@@ -19,12 +19,12 @@ i2cp.disableInterface=true
 ##### Tunnels
 #
 router.inboundPool.backupQuantity=0
-router.inboundPool.length=2
-router.inboundPool.lengthVariance=0
+router.inboundPool.length=1
+router.inboundPool.lengthVariance=1
 router.inboundPool.quantity=2
 router.outboundPool.backupQuantity=0
-router.outboundPool.length=2
-router.outboundPool.lengthVariance=0
+router.outboundPool.length=1
+router.outboundPool.lengthVariance=1
 router.outboundPool.quantity=2
 router.maxParticipatingTunnels=0
 router.sharePercentage=10
diff --git a/res/values/strings.xml b/res/values/strings.xml
index d1ab96508e6091b8634eb9c74ce5dc8d58ab8692..de7c12c8f0f4aae8b54da8ac7ce93ee2a5c630b2 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -1,4 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <resources>
     <string name="app_name">I2P</string>
+    <string name="welcome_new_install">Welcome to I2P! This app is ALPHA software and it does not provide strong anonymity. Please read the release notes and license information.</string>
+    <string name="welcome_new_version">New version installed. Please read the release notes. Version:</string>
 </resources>
diff --git a/src/net/i2p/android/router/activity/I2PWebViewClient.java b/src/net/i2p/android/router/activity/I2PWebViewClient.java
new file mode 100644
index 0000000000000000000000000000000000000000..a2564e482163f6e5b2dd20a5d95f6c846e46d6a6
--- /dev/null
+++ b/src/net/i2p/android/router/activity/I2PWebViewClient.java
@@ -0,0 +1,43 @@
+package net.i2p.android.router.activity;
+
+import android.webkit.WebView;
+import android.webkit.WebViewClient;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+
+class I2PWebViewClient extends WebViewClient {
+
+    // TODO add some inline style
+    private static final String HEADER = "<html><head></head><body>";
+    private static final String FOOTER = "</body></html>";
+    private static final String ERROR_EEPSITE = HEADER + "Sorry, eepsites not yet supported" + FOOTER;
+
+    @Override
+    public boolean shouldOverrideUrlLoading(WebView view, String url) {
+        System.err.println("Should override? " + url);
+        try {
+            URI uri = new URI(url);
+            String s = uri.getScheme();
+            if (s == null)
+                return false;
+            s = s.toLowerCase();
+            if (!(s.equals("http") || s.equals("https")))
+                return false;
+            String h = uri.getHost();
+            if (h == null)
+                return false;
+            h = h.toLowerCase();
+            if (h.endsWith(".i2p")) {
+                // if (s.equals("https")
+                //    return false;
+                view.loadData(ERROR_EEPSITE, "text/html", "UTF-8");
+            } else {
+                view.loadUrl(url);
+            }
+            return true;
+        } catch (URISyntaxException use) {
+            return false;
+        }
+    }
+}
diff --git a/src/net/i2p/android/router/activity/MainActivity.java b/src/net/i2p/android/router/activity/MainActivity.java
index 97abaa67af5583a02a2e482dbed2d80c85070337..305c7a3b223888f522636cccac5af2ca860a1dab 100644
--- a/src/net/i2p/android/router/activity/MainActivity.java
+++ b/src/net/i2p/android/router/activity/MainActivity.java
@@ -1,5 +1,8 @@
 package net.i2p.android.router.activity;
 
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.content.DialogInterface;
 import android.content.Intent;
 import android.os.Bundle;
 import android.os.Handler;
@@ -17,7 +20,12 @@ public class MainActivity extends I2PActivityBase {
 
     private Handler _handler;
     private Runnable _updater;
-    private int _counter;
+    private String _savedStatus;
+
+    protected static final String PROP_NEW_INSTALL = "i2p.newInstall";
+    protected static final String PROP_NEW_VERSION = "i2p.newVersion";
+    protected static final int DIALOG_NEW_INSTALL = 0;
+    protected static final int DIALOG_NEW_VERSION = 1;
 
     /** Called when the activity is first created. */
     @Override
@@ -34,6 +42,24 @@ public class MainActivity extends I2PActivityBase {
             }
         });
 
+        Button notes = (Button) findViewById(R.id.releasenotes_button);
+        notes.setOnClickListener(new View.OnClickListener() {
+            public void onClick(View view) {
+                Intent intent = new Intent(view.getContext(), TextResourceActivity.class);
+                intent.putExtra(TextResourceActivity.TEXT_RESOURCE_ID, R.raw.releasenotes_txt);
+                startActivityForResult(intent, 0);
+            }
+        });
+
+        Button licenses = (Button) findViewById(R.id.licenses_button);
+        licenses.setOnClickListener(new View.OnClickListener() {
+            public void onClick(View view) {
+                Intent intent = new Intent(view.getContext(), TextResourceActivity.class);
+                intent.putExtra(TextResourceActivity.TEXT_RESOURCE_ID, R.raw.licenses_txt);
+                startActivityForResult(intent, 0);
+            }
+        });
+
         Button start = (Button) findViewById(R.id.router_start_button);
         start.setOnClickListener(new View.OnClickListener() {
             public void onClick(View view) {
@@ -54,6 +80,13 @@ public class MainActivity extends I2PActivityBase {
             }
         });
 
+        if (savedInstanceState != null) {
+            String saved = savedInstanceState.getString("status");
+            if (saved != null) {
+                _savedStatus = saved;
+            }
+        }
+
         _handler = new Handler();
         _updater = new Updater();
     }
@@ -64,7 +97,11 @@ public class MainActivity extends I2PActivityBase {
     {
         super.onStart();
         _handler.removeCallbacks(_updater);
-        _handler.postDelayed(_updater, 50);
+        if (_savedStatus != null) {
+            TextView tv = (TextView) findViewById(R.id.main_status_text);
+            tv.setText(_savedStatus);
+        }
+        _handler.postDelayed(_updater, 100);
     }
 
     @Override
@@ -78,14 +115,30 @@ public class MainActivity extends I2PActivityBase {
     public void onResume()
     {
         super.onResume();
+        checkDialog();
         updateVisibility();
         updateStatus();
     }
 
+    @Override
+    public void onSaveInstanceState(Bundle outState)
+    {
+        if (_savedStatus != null)
+            outState.putString("status", _savedStatus);
+        super.onSaveInstanceState(outState);
+    }
+
     private class Updater implements Runnable {
+        private boolean needsCheck = true;
+        private int counter;
+
         public void run() {
+            if (getRouterContext() != null && needsCheck) {
+                checkDialog();
+                needsCheck = false;
+            }
             updateVisibility();
-            if (++_counter % 3 == 0)
+            if (counter++ % 3 == 0)
                 updateStatus();
             _handler.postDelayed(this, 2500);
         }
@@ -129,22 +182,99 @@ public class MainActivity extends I2PActivityBase {
                 fmt = new DecimalFormat("#0.00");
 
             String status =
-                   "Router status: " +
-                   " Peers " + active + '/' + known +
-                   "; Expl. Tunnels " + inEx + '/' + outEx +
-                   "; Client Tunnels " + inCl + '/' + outCl;
+                   "ROUTER STATUS" +
+                   "\nPeers active/known: " + active + " / " + known +
+                   "\nExploratory Tunnels in/out: " + inEx + " / " + outEx +
+                   "\nClient Tunnels in/out: " + inCl + " / " + outCl;
                    //" Pt " + part +
 
             String details =
-                   "; Bandwidth " + fmt.format(inBW) + '/' + fmt.format(outBW) + " KBps" +
-                   "; Job Lag " + jobLag +
-                   "; Msg Delay " + msgDelay +
-                   "; Up " + uptime;
+                   "\nBandwidth in/out: " + fmt.format(inBW) + " / " + fmt.format(outBW) + " KBps" +
+                   "\nJob Lag: " + jobLag +
+                   "\nMsg Delay: " + msgDelay +
+                   "\nUptime: " + uptime;
 
-            tv.setText(status + details);
+            _savedStatus = status + details;
+            tv.setText(_savedStatus);
             tv.setVisibility(View.VISIBLE);
         } else {
             tv.setVisibility(View.INVISIBLE);
         }
     }
+
+    private void checkDialog() {
+        if (Boolean.valueOf(System.getProperty(PROP_NEW_INSTALL)).booleanValue()) {
+            showDialog(DIALOG_NEW_INSTALL);
+        } else if (Boolean.valueOf(System.getProperty(PROP_NEW_VERSION)).booleanValue()) {
+            showDialog(DIALOG_NEW_VERSION);
+        }
+    }
+
+    protected Dialog onCreateDialog(int id) {
+        Dialog rv = null;
+        AlertDialog.Builder b = new AlertDialog.Builder(this);
+        switch (id) {
+          case DIALOG_NEW_INSTALL:
+            b.setMessage(getResources().getText(R.string.welcome_new_install))
+              .setCancelable(false)
+              .setPositiveButton("OK", new DialogInterface.OnClickListener() {
+                       public void onClick(DialogInterface dialog, int id) {
+                           System.setProperty(PROP_NEW_INSTALL, "false");
+                           System.setProperty(PROP_NEW_VERSION, "false");
+                           dialog.cancel();
+                           MainActivity.this.removeDialog(id);
+                       }
+               })
+              .setNeutralButton("Release Notes", new DialogInterface.OnClickListener() {
+                       public void onClick(DialogInterface dialog, int id) {
+                           System.setProperty(PROP_NEW_INSTALL, "false");
+                           System.setProperty(PROP_NEW_VERSION, "false");
+                           dialog.cancel();
+                           MainActivity.this.removeDialog(id);
+                           Intent intent = new Intent(MainActivity.this, TextResourceActivity.class);
+                           intent.putExtra(TextResourceActivity.TEXT_RESOURCE_ID, R.raw.releasenotes_txt);
+                           startActivityForResult(intent, 0);
+                       }
+               })
+              .setNegativeButton("Licenses", new DialogInterface.OnClickListener() {
+                       public void onClick(DialogInterface dialog, int id) {
+                           System.setProperty(PROP_NEW_INSTALL, "false");
+                           System.setProperty(PROP_NEW_VERSION, "false");
+                           dialog.cancel();
+                           MainActivity.this.removeDialog(id);
+                           Intent intent = new Intent(MainActivity.this, TextResourceActivity.class);
+                           intent.putExtra(TextResourceActivity.TEXT_RESOURCE_ID, R.raw.licenses_txt);
+                           startActivityForResult(intent, 0);
+                       }
+               });
+            rv = b.create();
+            break;
+
+          case DIALOG_NEW_VERSION:
+            b.setMessage(getResources().getText(R.string.welcome_new_version) + " " + System.getProperty("i2p.version"))
+              .setCancelable(true)
+              .setPositiveButton("OK", new DialogInterface.OnClickListener() {
+                       public void onClick(DialogInterface dialog, int id) {
+                           System.setProperty(PROP_NEW_VERSION, "false");
+                           dialog.cancel();
+                           MainActivity.this.removeDialog(id);
+                       }
+               })
+              .setNegativeButton("Release Notes", new DialogInterface.OnClickListener() {
+                       public void onClick(DialogInterface dialog, int id) {
+                           System.setProperty(PROP_NEW_VERSION, "false");
+                           dialog.cancel();
+                           MainActivity.this.removeDialog(id);
+                           Intent intent = new Intent(MainActivity.this, TextResourceActivity.class);
+                           intent.putExtra(TextResourceActivity.TEXT_RESOURCE_ID, R.raw.releasenotes_txt);
+                           startActivityForResult(intent, 0);
+                       }
+               });
+
+
+            rv = b.create();
+            break;
+        }
+        return rv;
+    }
 }
diff --git a/src/net/i2p/android/router/activity/NewsActivity.java b/src/net/i2p/android/router/activity/NewsActivity.java
index bfee330c8414c9d5d177fbe4acace4e7f74b78ac..906ab83098473830e9010521e3d4b691e09e14b6 100644
--- a/src/net/i2p/android/router/activity/NewsActivity.java
+++ b/src/net/i2p/android/router/activity/NewsActivity.java
@@ -26,7 +26,6 @@ public class NewsActivity extends I2PActivityBase {
     // TODO add some inline style
     private static final String HEADER = "<html><head></head><body>";
     private static final String FOOTER = "</body></html>";
-    private static final String ERROR_EEPSITE = HEADER + "Sorry, eepsites not yet supported" + FOOTER;
 
     @Override
     public void onCreate(Bundle savedInstanceState)
@@ -34,7 +33,7 @@ public class NewsActivity extends I2PActivityBase {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.news);
         WebView wv = (WebView) findViewById(R.id.news_webview);
-        wv.setWebViewClient(new NewsWebViewClient());
+        wv.setWebViewClient(new I2PWebViewClient());
     }
 
     @Override
@@ -97,34 +96,4 @@ public class NewsActivity extends I2PActivityBase {
         }
         return super.onKeyDown(keyCode, event);
     }
-
-    private static class NewsWebViewClient extends WebViewClient {
-        @Override
-        public boolean shouldOverrideUrlLoading(WebView view, String url) {
-            System.err.println("Should override? " + url);
-            try {
-                URI uri = new URI(url);
-                String s = uri.getScheme();
-                if (s == null)
-                    return false;
-                s = s.toLowerCase();
-                if (!(s.equals("http") || s.equals("https")))
-                    return false;
-                String h = uri.getHost();
-                if (h == null)
-                    return false;
-                h = h.toLowerCase();
-                if (h.endsWith(".i2p")) {
-                    // if (s.equals("https")
-                    //    return false;
-                    view.loadData(ERROR_EEPSITE, "text/html", "UTF-8");
-                } else {
-                    view.loadUrl(url);
-                }
-                return true;
-            } catch (URISyntaxException use) {
-                return false;
-            }
-        }
-    }
 }
diff --git a/src/net/i2p/android/router/activity/TextResourceActivity.java b/src/net/i2p/android/router/activity/TextResourceActivity.java
new file mode 100644
index 0000000000000000000000000000000000000000..a343d2703e3f19a7e19090a1df9d6fc5c40a9c9c
--- /dev/null
+++ b/src/net/i2p/android/router/activity/TextResourceActivity.java
@@ -0,0 +1,64 @@
+package net.i2p.android.router.activity;
+
+import android.content.res.Resources;
+import android.content.Intent;
+import android.os.Bundle;
+import android.text.method.ScrollingMovementMethod;
+import android.widget.TextView;
+
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+
+import net.i2p.android.router.R;
+
+/**
+ *  Display a raw text resource.
+ *  The resource ID must be passed as an extra in the intent.
+ */
+public class TextResourceActivity extends I2PActivityBase {
+
+    final static String TEXT_RESOURCE_ID = "text_resource_id";
+
+    @Override
+    public void onCreate(Bundle savedInstanceState)
+    {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.text_resource);
+        TextView tv = (TextView) findViewById(R.id.text_resource_text);
+        tv.setMovementMethod(ScrollingMovementMethod.getInstance());
+        Intent intent = getIntent();
+        int id = intent.getIntExtra(TEXT_RESOURCE_ID, R.raw.releasenotes_txt);
+        if (id == R.raw.releasenotes_txt)
+            tv.setText("Release Notes for Release " + System.getProperty("i2p.version") + "\n\n" +
+                       getResourceAsString(id));
+        else
+            tv.setText(getResourceAsString(id));
+    }
+
+    private String getResourceAsString(int id) {
+        InputStream in = null;
+        ByteArrayOutputStream out = new ByteArrayOutputStream(2048);
+        byte buf[] = new byte[1024];
+        try {
+            in = getResources().openRawResource(id);
+            
+            int read = 0;
+            while ( (read = in.read(buf)) != -1)
+                out.write(buf, 0, read);
+            
+        } catch (IOException ioe) {
+            System.err.println("resource error " + ioe);
+        } catch (Resources.NotFoundException nfe) {
+            System.err.println("resource error " + nfe);
+        } finally {
+            if (in != null) try { in.close(); } catch (IOException ioe) {}
+        }
+        try {
+            return out.toString("UTF-8");
+        } catch (UnsupportedEncodingException uee) {
+        }
+        return "";
+    }
+}
diff --git a/src/net/i2p/android/router/service/Init.java b/src/net/i2p/android/router/service/Init.java
index 4c95a49527bb54db454fe1c08efe4a0a1319b4f3..c99341add470c4db7e20d426c50e5ace1962c8f2 100644
--- a/src/net/i2p/android/router/service/Init.java
+++ b/src/net/i2p/android/router/service/Init.java
@@ -26,11 +26,19 @@ class Init {
 
     private final Context ctx;
     private final String myDir;
+    private final String _ourVersion;
     private String _apkPath;
 
+    private static final String CONFIG_FILE = "android.config";
+    private static final String PROP_NEW_INSTALL = "i2p.newInstall";
+    private static final String PROP_NEW_VERSION = "i2p.newVersion";
+    private static final String PROP_INSTALLED_VERSION = "i2p.version";
+
     public Init(Context c) {
         ctx = c;
         myDir = c.getFilesDir().getAbsolutePath();
+        _ourVersion = getOurVersion();
+        System.setProperty(PROP_INSTALLED_VERSION, _ourVersion);
     }
 
     void debugStuff() {
@@ -46,7 +54,7 @@ class Init {
         System.err.println("getFilesDir()" + ": " + myDir);
         System.err.println("max mem" + ": " + DataHelper.formatSize(Runtime.getRuntime().maxMemory()));
         System.err.println("Package" + ": " + ctx.getPackageName());
-        System.err.println("Version" + ": " + getOurVersion());
+        System.err.println("Version" + ": " + _ourVersion);
         System.err.println("MODEL" + ": " + Build.MODEL);
         System.err.println("DISPLAY" + ": " + Build.DISPLAY);
         System.err.println("VERSION" + ": " + Build.VERSION.RELEASE);
@@ -73,15 +81,17 @@ class Init {
     }
 
     void initialize() {
-        Properties props = new Properties();
-        props.setProperty("i2p.dir.temp", myDir + "/tmp");
-        props.setProperty("i2p.dir.pid", myDir + "/tmp");
-        mergeResourceToFile(R.raw.router_config, "router.config", props);
-        mergeResourceToFile(R.raw.logger_config, "logger.config", null);
-        mergeResourceToFile(R.raw.i2ptunnel_config, "i2ptunnel.config", null);
-        // FIXME this is a memory hog to merge this way
-        mergeResourceToFile(R.raw.hosts_txt, "hosts.txt", null);
-        copyResourceToFile(R.raw.blocklist_txt, "blocklist.txt");
+        if (checkNewVersion()) {
+            Properties props = new Properties();
+            props.setProperty("i2p.dir.temp", myDir + "/tmp");
+            props.setProperty("i2p.dir.pid", myDir + "/tmp");
+            mergeResourceToFile(R.raw.router_config, "router.config", props);
+            mergeResourceToFile(R.raw.logger_config, "logger.config", null);
+            mergeResourceToFile(R.raw.i2ptunnel_config, "i2ptunnel.config", null);
+            // FIXME this is a memory hog to merge this way
+            mergeResourceToFile(R.raw.hosts_txt, "hosts.txt", null);
+            copyResourceToFile(R.raw.blocklist_txt, "blocklist.txt");
+        }
 
         (new File(myDir, "wrapper.log")).delete();
 
@@ -155,4 +165,39 @@ class Init {
         }
     }
     
+    /**
+     *  Check for new version.
+     *  Sets system properties i2p.newVersion and i2p.newInstall
+     *  @return true if new version
+     */
+    private boolean checkNewVersion() {
+        Properties props = new Properties();
+        
+        InputStream fin = null;
+        try {
+            fin = ctx.openFileInput(CONFIG_FILE);
+            DataHelper.loadProps(props,  fin);
+        } catch (IOException ioe) {
+            System.err.println("Looks like a new install");
+        } finally {
+            if (fin != null) try { fin.close(); } catch (IOException ioe) {}
+        }
+
+        String oldVersion = props.getProperty(PROP_INSTALLED_VERSION);
+        boolean newInstall = oldVersion == null;
+        boolean newVersion = !_ourVersion.equals(oldVersion);
+        System.setProperty(PROP_NEW_INSTALL, Boolean.toString(newInstall));
+        System.setProperty(PROP_NEW_VERSION, Boolean.toString(newVersion));
+
+        if (newVersion) {
+            System.err.println("New version " + _ourVersion);
+            props.setProperty(PROP_INSTALLED_VERSION, _ourVersion);
+            try {
+                DataHelper.storeProps(props, ctx.getFileStreamPath(CONFIG_FILE));
+            } catch (IOException ioe) {
+                System.err.println("Failed to write " + CONFIG_FILE);
+            }
+        }
+        return newVersion;
+    }
 }