diff --git a/core/java/android/net/VpnBuilder.java b/core/java/android/net/VpnBuilder.java
deleted file mode 100644
index 4582523..0000000
--- a/core/java/android/net/VpnBuilder.java
+++ /dev/null
@@ -1,413 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net;
-
-import android.app.Activity;
-import android.app.PendingIntent;
-import android.content.Context;
-import android.content.Intent;
-import android.os.ParcelFileDescriptor;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-
-import com.android.internal.net.VpnConfig;
-
-import java.net.InetAddress;
-import java.net.Inet4Address;
-import java.net.Inet6Address;
-import java.net.DatagramSocket;
-import java.net.Socket;
-import java.util.ArrayList;
-
-/**
- * VpnBuilder is a framework which enables applications to build their
- * own VPN solutions. In general, it creates a virtual network interface,
- * configures addresses and routing rules, and returns a file descriptor
- * to the application. Each read from the descriptor retrieves an outgoing
- * packet which was routed to the interface. Each write to the descriptor
- * injects an incoming packet just like it was received from the interface.
- * The framework is running on Internet Protocol (IP), so packets are
- * always started with IP headers. The application then completes a VPN
- * connection by processing and exchanging packets with a remote server
- * over a secured tunnel.
- *
- * <p>Letting applications intercept packets raises huge security concerns.
- * Besides, a VPN application can easily break the network, and two of them
- * may conflict with each other. The framework takes several actions to
- * address these issues. Here are some key points:
- * <ul>
- *   <li>User action is required to create a VPN connection.</li>
- *   <li>There can be only one VPN connection running at the same time. The
- *       existing interface is deactivated when a new one is created.</li>
- *   <li>A system-managed notification is shown during the lifetime of a
- *       VPN connection.</li>
- *   <li>A system-managed dialog gives the information of the current VPN
- *       connection. It also provides a button to disconnect.</li>
- *   <li>The network is restored automatically when the file descriptor is
- *       closed. It also covers the cases when a VPN application is crashed
- *       or killed by the system.</li>
- * </ul>
- *
- * <p>There are two primary methods in this class: {@link #prepare} and
- * {@link #establish}. The former deals with the user action and stops
- * the existing VPN connection created by another application. The latter
- * creates a VPN interface using the parameters supplied to this builder.
- * An application must call {@link #prepare} to grant the right to create
- * an interface, and it can be revoked at any time by another application.
- * The application got revoked is notified by an {@link #ACTION_VPN_REVOKED}
- * broadcast. Here are the general steps to create a VPN connection:
- * <ol>
- *   <li>When the user press the button to connect, call {@link #prepare}
- *       and launch the intent if necessary.</li>
- *   <li>Register a receiver for {@link #ACTION_VPN_REVOKED} broadcasts.
- *   <li>Connect to the remote server and negotiate the network parameters
- *       of the VPN connection.</li>
- *   <li>Use those parameters to configure a VpnBuilder and create a VPN
- *       interface by calling {@link #establish}.</li>
- *   <li>Start processing packets between the returned file descriptor and
- *       the VPN tunnel.</li>
- *   <li>When an {@link #ACTION_VPN_REVOKED} broadcast is received, the
- *       interface is already deactivated by the framework. Close the file
- *       descriptor and shut down the VPN tunnel gracefully.
- * </ol>
- * Methods in this class can be used in activities and services. However,
- * the intent returned from {@link #prepare} must be launched from an
- * activity. The broadcast receiver can be registered at any time, but doing
- * it before calling {@link #establish} effectively avoids race conditions.
- *
- * <p class="note">Using this class requires
- * {@link android.Manifest.permission#VPN} permission.
- * @hide
- */
-public class VpnBuilder {
-
-    /**
-     * Broadcast intent action indicating that the VPN application has been
-     * revoked. This can be only received by the target application on the
-     * receiver explicitly registered using {@link Context#registerReceiver}.
-     *
-     * <p>This is a protected intent that can only be sent by the system.
-     */
-    public static final String ACTION_VPN_REVOKED = VpnConfig.ACTION_VPN_REVOKED;
-
-    /**
-     * Use IConnectivityManager instead since those methods are hidden and
-     * not available in ConnectivityManager.
-     */
-    private static IConnectivityManager getService() {
-        return IConnectivityManager.Stub.asInterface(
-                ServiceManager.getService(Context.CONNECTIVITY_SERVICE));
-    }
-
-    /**
-     * Prepare to establish a VPN connection. This method returns {@code null}
-     * if the VPN application is already prepared. Otherwise, it returns an
-     * {@link Intent} to a system activity. The application should launch the
-     * activity using {@link Activity#startActivityForResult} to get itself
-     * prepared. The activity may pop up a dialog to require user action, and
-     * the result will come back to the application through its
-     * {@link Activity#onActivityResult}. The application becomes prepared if
-     * the result is {@link Activity#RESULT_OK}, and it is granted to create a
-     * VPN interface by calling {@link #establish}.
-     *
-     * <p>Only one application can be granted at the same time. The right
-     * is revoked when another application is granted. The application
-     * losing the right will be notified by an {@link #ACTION_VPN_REVOKED}
-     * broadcast, and its VPN interface will be deactivated by the system.
-     * The application should then notify the remote server and disconnect
-     * gracefully. Unless the application becomes prepared again, subsequent
-     * calls to {@link #establish} will return {@code null}.
-     *
-     * @see #establish
-     * @see #ACTION_VPN_REVOKED
-     */
-    public static Intent prepare(Context context) {
-        try {
-            if (getService().prepareVpn(context.getPackageName(), null)) {
-                return null;
-            }
-        } catch (RemoteException e) {
-            // ignore
-        }
-        return VpnConfig.getIntentForConfirmation();
-    }
-
-    private VpnConfig mConfig = new VpnConfig();
-    private StringBuilder mAddresses = new StringBuilder();
-    private StringBuilder mRoutes = new StringBuilder();
-
-    /**
-     * Set the name of this session. It will be displayed in system-managed
-     * dialogs and notifications. This is recommended not required.
-     */
-    public VpnBuilder setSession(String session) {
-        mConfig.session = session;
-        return this;
-    }
-
-    /**
-     * Set the {@link PendingIntent} to an activity for users to configure
-     * the VPN connection. If it is not set, the button to configure will
-     * not be shown in system-managed dialogs.
-     */
-    public VpnBuilder setConfigureIntent(PendingIntent intent) {
-        mConfig.configureIntent = intent;
-        return this;
-    }
-
-    /**
-     * Set the maximum transmission unit (MTU) of the VPN interface. If it
-     * is not set, the default value in the operating system will be used.
-     *
-     * @throws IllegalArgumentException if the value is not positive.
-     */
-    public VpnBuilder setMtu(int mtu) {
-        if (mtu <= 0) {
-            throw new IllegalArgumentException("Bad mtu");
-        }
-        mConfig.mtu = mtu;
-        return this;
-    }
-
-    /**
-     * Private method to validate address and prefixLength.
-     */
-    private static void check(InetAddress address, int prefixLength) {
-        if (address.isLoopbackAddress()) {
-            throw new IllegalArgumentException("Bad address");
-        }
-        if (address instanceof Inet4Address) {
-            if (prefixLength < 0 || prefixLength > 32) {
-                throw new IllegalArgumentException("Bad prefixLength");
-            }
-        } else if (address instanceof Inet6Address) {
-            if (prefixLength < 0 || prefixLength > 128) {
-                throw new IllegalArgumentException("Bad prefixLength");
-            }
-        } else {
-            throw new IllegalArgumentException("Unsupported family");
-        }
-    }
-
-    /**
-     * Convenience method to add a network address to the VPN interface
-     * using a numeric address string. See {@link InetAddress} for the
-     * definitions of numeric address formats.
-     *
-     * @throws IllegalArgumentException if the address is invalid.
-     * @see #addAddress(InetAddress, int)
-     */
-    public VpnBuilder addAddress(String address, int prefixLength) {
-        return addAddress(InetAddress.parseNumericAddress(address), prefixLength);
-    }
-
-    /**
-     * Add a network address to the VPN interface. Both IPv4 and IPv6
-     * addresses are supported. At least one address must be set before
-     * calling {@link #establish}.
-     *
-     * @throws IllegalArgumentException if the address is invalid.
-     */
-    public VpnBuilder addAddress(InetAddress address, int prefixLength) {
-        check(address, prefixLength);
-
-        if (address.isAnyLocalAddress()) {
-            throw new IllegalArgumentException("Bad address");
-        }
-
-        mAddresses.append(String.format(" %s/%d", address.getHostAddress(), prefixLength));
-        return this;
-    }
-
-    /**
-     * Convenience method to add a network route to the VPN interface
-     * using a numeric address string. See {@link InetAddress} for the
-     * definitions of numeric address formats.
-     *
-     * @see #addRoute(InetAddress, int)
-     * @throws IllegalArgumentException if the route is invalid.
-     */
-    public VpnBuilder addRoute(String address, int prefixLength) {
-        return addRoute(InetAddress.parseNumericAddress(address), prefixLength);
-    }
-
-    /**
-     * Add a network route to the VPN interface. Both IPv4 and IPv6
-     * routes are supported.
-     *
-     * @throws IllegalArgumentException if the route is invalid.
-     */
-    public VpnBuilder addRoute(InetAddress address, int prefixLength) {
-        check(address, prefixLength);
-
-        int offset = prefixLength / 8;
-        byte[] bytes = address.getAddress();
-        if (offset < bytes.length) {
-            if ((byte)(bytes[offset] << (prefixLength % 8)) != 0) {
-                throw new IllegalArgumentException("Bad address");
-            }
-            while (++offset < bytes.length) {
-                if (bytes[offset] != 0) {
-                    throw new IllegalArgumentException("Bad address");
-                }
-            }
-        }
-
-        mRoutes.append(String.format(" %s/%d", address.getHostAddress(), prefixLength));
-        return this;
-    }
-
-    /**
-     * Convenience method to add a DNS server to the VPN connection
-     * using a numeric address string. See {@link InetAddress} for the
-     * definitions of numeric address formats.
-     *
-     * @throws IllegalArgumentException if the address is invalid.
-     * @see #addDnsServer(InetAddress)
-     */
-    public VpnBuilder addDnsServer(String address) {
-        return addDnsServer(InetAddress.parseNumericAddress(address));
-    }
-
-    /**
-     * Add a DNS server to the VPN connection. Both IPv4 and IPv6
-     * addresses are supported. If none is set, the DNS servers of
-     * the default network will be used.
-     *
-     * @throws IllegalArgumentException if the address is invalid.
-     */
-    public VpnBuilder addDnsServer(InetAddress address) {
-        if (address.isLoopbackAddress() || address.isAnyLocalAddress()) {
-            throw new IllegalArgumentException("Bad address");
-        }
-        if (mConfig.dnsServers == null) {
-            mConfig.dnsServers = new ArrayList<String>();
-        }
-        mConfig.dnsServers.add(address.getHostAddress());
-        return this;
-    }
-
-    /**
-     * Add a search domain to the DNS resolver.
-     */
-    public VpnBuilder addSearchDomain(String domain) {
-        if (mConfig.searchDomains == null) {
-            mConfig.searchDomains = new ArrayList<String>();
-        }
-        mConfig.searchDomains.add(domain);
-        return this;
-    }
-
-    /**
-     * Create a VPN interface using the parameters supplied to this builder.
-     * The interface works on IP packets, and a file descriptor is returned
-     * for the application to access them. Each read retrieves an outgoing
-     * packet which was routed to the interface. Each write injects an
-     * incoming packet just like it was received from the interface. The file
-     * descriptor is put into non-blocking mode by default to avoid blocking
-     * Java threads. To use the file descriptor completely in native space,
-     * see {@link ParcelFileDescriptor#detachFd()}. The application MUST
-     * close the file descriptor when the VPN connection is terminated. The
-     * VPN interface will be removed and the network will be restored by the
-     * framework automatically.
-     *
-     * <p>To avoid conflicts, there can be only one active VPN interface at
-     * the same time. Usually network parameters are never changed during the
-     * lifetime of a VPN connection. It is also common for an application to
-     * create a new file descriptor after closing the previous one. However,
-     * it is rare but not impossible to have two interfaces while performing a
-     * seamless handover. In this case, the old interface will be deactivated
-     * when the new one is configured successfully. Both file descriptors are
-     * valid but now outgoing packets will be routed to the new interface.
-     * Therefore, after draining the old file descriptor, the application MUST
-     * close it and start using the new file descriptor. If the new interface
-     * cannot be created, the existing interface and its file descriptor remain
-     * untouched.
-     *
-     * <p>An exception will be thrown if the interface cannot be created for
-     * any reason. However, this method returns {@code null} if the application
-     * is not prepared or is revoked by another application. This helps solve
-     * possible race conditions while handling {@link #ACTION_VPN_REVOKED}
-     * broadcasts.
-     *
-     * @return {@link ParcelFileDescriptor} of the VPN interface, or
-     *         {@code null} if the application is not prepared.
-     * @throws IllegalArgumentException if a parameter is not accepted by the
-     *         operating system.
-     * @throws IllegalStateException if a parameter cannot be applied by the
-     *         operating system.
-     * @see #prepare
-     */
-    public ParcelFileDescriptor establish() {
-        mConfig.addresses = mAddresses.toString();
-        mConfig.routes = mRoutes.toString();
-
-        try {
-            return getService().establishVpn(mConfig);
-        } catch (RemoteException e) {
-            throw new IllegalStateException(e);
-        }
-    }
-
-    /**
-     * Protect a socket from VPN connections. The socket will be bound to the
-     * current default network interface, so its traffic will not be forwarded
-     * through VPN. This method is useful if some connections need to be kept
-     * outside of VPN. For example, a VPN tunnel should protect itself if its
-     * destination is covered by VPN routes. Otherwise its outgoing packets
-     * will be sent back to the VPN interface and cause an infinite loop.
-     *
-     * <p>The socket is NOT closed by this method.
-     *
-     * @return {@code true} on success.
-     */
-    public static boolean protect(int socket) {
-        ParcelFileDescriptor dup = null;
-        try {
-            dup = ParcelFileDescriptor.fromFd(socket);
-            return getService().protectVpn(dup);
-        } catch (Exception e) {
-            return false;
-        } finally {
-            try {
-                dup.close();
-            } catch (Exception e) {
-                // ignore
-            }
-        }
-    }
-
-    /**
-     * Protect a {@link Socket} from VPN connections.
-     *
-     * @return {@code true} on success.
-     * @see #protect(int)
-     */
-    public static boolean protect(Socket socket) {
-        return protect(socket.getFileDescriptor$().getInt$());
-    }
-
-    /**
-     * Protect a {@link DatagramSocket} from VPN connections.
-     *
-     * @return {@code true} on success.
-     * @see #protect(int)
-     */
-    public static boolean protect(DatagramSocket socket) {
-        return protect(socket.getFileDescriptor$().getInt$());
-    }
-}
diff --git a/core/java/com/android/internal/net/VpnConfig.java b/core/java/com/android/internal/net/VpnConfig.java
index d36be10..d61a579 100644
--- a/core/java/com/android/internal/net/VpnConfig.java
+++ b/core/java/com/android/internal/net/VpnConfig.java
@@ -32,7 +32,7 @@
  */
 public class VpnConfig implements Parcelable {
 
-    public static final String ACTION_VPN_REVOKED = "android.net.vpn.action.REVOKED";
+    public static final String SERVICE_INTERFACE = "android.net.VpnService";
 
     public static final String LEGACY_VPN = "[Legacy VPN]";
 
@@ -52,7 +52,7 @@
                 PendingIntent.FLAG_NO_CREATE : PendingIntent.FLAG_CANCEL_CURRENT);
     }
 
-    public String packagz;
+    public String user;
     public String interfaze;
     public String session;
     public int mtu = -1;
@@ -70,7 +70,7 @@
 
     @Override
     public void writeToParcel(Parcel out, int flags) {
-        out.writeString(packagz);
+        out.writeString(user);
         out.writeString(interfaze);
         out.writeString(session);
         out.writeInt(mtu);
@@ -87,7 +87,7 @@
         @Override
         public VpnConfig createFromParcel(Parcel in) {
             VpnConfig config = new VpnConfig();
-            config.packagz = in.readString();
+            config.user = in.readString();
             config.interfaze = in.readString();
             config.session = in.readString();
             config.mtu = in.readInt();
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index f99a94c..19a25cc 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -393,14 +393,6 @@
         android:description="@string/permdesc_nfc"
         android:label="@string/permlab_nfc" />
 
-    <!-- Allows applications to provide VPN functionality.
-         @hide Pending API council approval -->
-    <permission android:name="android.permission.VPN"
-        android:permissionGroup="android.permission-group.NETWORK"
-        android:protectionLevel="dangerous"
-        android:description="@string/permdesc_vpn"
-        android:label="@string/permlab_vpn" />
-
     <!-- Allows an application to use SIP service -->
     <permission android:name="android.permission.USE_SIP"
         android:permissionGroup="android.permission-group.NETWORK"
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index c5aa4b2..ae14dc8 100755
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -1358,14 +1358,6 @@
       with Near Field Communication (NFC) tags, cards, and readers.</string>
 
     <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
-    <string name="permlab_vpn">intercept and modify all network traffic</string>
-    <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
-    <string name="permdesc_vpn">Allows an application to intercept and
-      inspect all network traffic to establish a VPN connection.
-      Malicious applications may monitor, redirect, or modify network packets
-      without your knowledge.</string>
-
-    <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permlab_disableKeyguard">disable keylock</string>
     <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permdesc_disableKeyguard">Allows an application to disable
diff --git a/packages/VpnDialogs/AndroidManifest.xml b/packages/VpnDialogs/AndroidManifest.xml
index bd5f739..8e062b7 100644
--- a/packages/VpnDialogs/AndroidManifest.xml
+++ b/packages/VpnDialogs/AndroidManifest.xml
@@ -5,7 +5,6 @@
     <application android:label="VpnDialogs"
             android:allowBackup="false" >
         <activity android:name=".ConfirmDialog"
-                android:permission="android.permission.VPN"
                 android:theme="@style/transparent">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN"/>
diff --git a/packages/VpnDialogs/src/com/android/vpndialogs/ManageDialog.java b/packages/VpnDialogs/src/com/android/vpndialogs/ManageDialog.java
index 40c0a02..d668e98 100644
--- a/packages/VpnDialogs/src/com/android/vpndialogs/ManageDialog.java
+++ b/packages/VpnDialogs/src/com/android/vpndialogs/ManageDialog.java
@@ -79,7 +79,7 @@
             mDataTransmitted = (TextView) view.findViewById(R.id.data_transmitted);
             mDataReceived = (TextView) view.findViewById(R.id.data_received);
 
-            if (mConfig.packagz.equals(VpnConfig.LEGACY_VPN)) {
+            if (mConfig.user.equals(VpnConfig.LEGACY_VPN)) {
                 mDialog = new AlertDialog.Builder(this)
                         .setIcon(android.R.drawable.ic_dialog_info)
                         .setTitle(R.string.legacy_title)
@@ -89,7 +89,7 @@
                         .create();
             } else {
                 PackageManager pm = getPackageManager();
-                ApplicationInfo app = pm.getApplicationInfo(mConfig.packagz, 0);
+                ApplicationInfo app = pm.getApplicationInfo(mConfig.user, 0);
                 mDialog = new AlertDialog.Builder(this)
                         .setIcon(app.loadIcon(pm))
                         .setTitle(app.loadLabel(pm))
@@ -131,7 +131,7 @@
             if (which == AlertDialog.BUTTON_POSITIVE) {
                 mConfig.configureIntent.send();
             } else if (which == AlertDialog.BUTTON_NEUTRAL) {
-                mService.prepareVpn(mConfig.packagz, VpnConfig.LEGACY_VPN);
+                mService.prepareVpn(mConfig.user, VpnConfig.LEGACY_VPN);
             }
         } catch (Exception e) {
             Log.e(TAG, "onClick", e);
diff --git a/services/java/com/android/server/connectivity/Vpn.java b/services/java/com/android/server/connectivity/Vpn.java
index ecbad09..b69cc31 100644
--- a/services/java/com/android/server/connectivity/Vpn.java
+++ b/services/java/com/android/server/connectivity/Vpn.java
@@ -54,7 +54,6 @@
 public class Vpn extends INetworkManagementEventObserver.Stub {
 
     private final static String TAG = "Vpn";
-    private final static String VPN = android.Manifest.permission.VPN;
 
     private final Context mContext;
     private final VpnCallback mCallback;
@@ -69,18 +68,6 @@
     }
 
     /**
-     * Protect a socket from routing changes by binding it to the given
-     * interface. The socket is NOT closed by this method.
-     *
-     * @param socket The socket to be bound.
-     * @param name The name of the interface.
-     */
-    public void protect(ParcelFileDescriptor socket, String interfaze) {
-        mContext.enforceCallingPermission(VPN, "protect");
-        jniProtect(socket.getFd(), interfaze);
-    }
-
-    /**
      * Prepare for a VPN application. This method is designed to solve
      * race conditions. It first compares the current prepared package
      * with {@code oldPackage}. If they are the same, the prepared
@@ -115,13 +102,6 @@
             throw new SecurityException("Unauthorized Caller");
         }
 
-        // Check the permission of the given package.
-        PackageManager pm = mContext.getPackageManager();
-        if (!newPackage.equals(VpnConfig.LEGACY_VPN) &&
-                pm.checkPermission(VPN, newPackage) != PackageManager.PERMISSION_GRANTED) {
-            throw new SecurityException(newPackage + " does not have " + VPN);
-        }
-
         // Reset the interface and hide the notification.
         if (mInterface != null) {
             jniReset(mInterface);
@@ -130,12 +110,9 @@
             mInterface = null;
         }
 
-        // Send out the broadcast or stop LegacyVpnRunner.
+        // Revoke the connection or stop LegacyVpnRunner.
         if (!mPackage.equals(VpnConfig.LEGACY_VPN)) {
-            Intent intent = new Intent(VpnConfig.ACTION_VPN_REVOKED);
-            intent.setPackage(mPackage);
-            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
-            mContext.sendBroadcast(intent);
+            // TODO
         } else if (mLegacyVpnRunner != null) {
             mLegacyVpnRunner.exit();
             mLegacyVpnRunner = null;
@@ -147,6 +124,22 @@
     }
 
     /**
+     * Protect a socket from routing changes by binding it to the given
+     * interface. The socket is NOT closed by this method.
+     *
+     * @param socket The socket to be bound.
+     * @param name The name of the interface.
+     */
+    public void protect(ParcelFileDescriptor socket, String interfaze) throws Exception {
+        PackageManager pm = mContext.getPackageManager();
+        ApplicationInfo app = pm.getApplicationInfo(mPackage, 0);
+        if (Binder.getCallingUid() != app.uid) {
+            throw new SecurityException("Unauthorized Caller");
+        }
+        jniProtect(socket.getFd(), interfaze);
+    }
+
+    /**
      * Establish a VPN network and return the file descriptor of the VPN
      * interface. This methods returns {@code null} if the application is
      * revoked or not prepared.
@@ -155,9 +148,6 @@
      * @return The file descriptor of the VPN interface.
      */
     public synchronized ParcelFileDescriptor establish(VpnConfig config) {
-        // Check the permission of the caller.
-        mContext.enforceCallingPermission(VPN, "establish");
-
         // Check if the caller is already prepared.
         PackageManager pm = mContext.getPackageManager();
         ApplicationInfo app = null;
@@ -170,6 +160,9 @@
             return null;
         }
 
+        // Check if the service is properly declared.
+        // TODO
+
         // Load the label.
         String label = app.loadLabel(pm).toString();
 
@@ -198,6 +191,7 @@
             if (config.routes != null) {
                 jniSetRoutes(interfaze, config.routes);
             }
+            // TODO: bind the service
             if (mInterface != null && !mInterface.equals(interfaze)) {
                 jniReset(mInterface);
             }
@@ -211,23 +205,25 @@
             throw e;
         }
 
-        // Override DNS servers and search domains.
-        mCallback.override(config.dnsServers, config.searchDomains);
-
         // Fill more values.
-        config.packagz = mPackage;
+        config.user = mPackage;
         config.interfaze = mInterface;
 
-        // Show the notification!
+        // Override DNS servers and show the notification.
+        long identity = Binder.clearCallingIdentity();
+        mCallback.override(config.dnsServers, config.searchDomains);
         showNotification(config, label, bitmap);
+        Binder.restoreCallingIdentity(identity);
         return tun;
     }
 
     // INetworkManagementEventObserver.Stub
+    @Override
     public void interfaceAdded(String interfaze) {
     }
 
     // INetworkManagementEventObserver.Stub
+    @Override
     public synchronized void interfaceStatusChanged(String interfaze, boolean up) {
         if (!up && mLegacyVpnRunner != null) {
             mLegacyVpnRunner.check(interfaze);
@@ -235,23 +231,29 @@
     }
 
     // INetworkManagementEventObserver.Stub
-    public synchronized void interfaceLinkStateChanged(String interfaze, boolean up) {
-        if (!up && mLegacyVpnRunner != null) {
-            mLegacyVpnRunner.check(interfaze);
+    @Override
+    public void interfaceLinkStateChanged(String interfaze, boolean up) {
+        interfaceStatusChanged(interfaze, up);
+    }
+
+    // INetworkManagementEventObserver.Stub
+    @Override
+    public synchronized void interfaceRemoved(String interfaze) {
+        if (interfaze.equals(mInterface) && jniCheck(interfaze) == 0) {
+            long identity = Binder.clearCallingIdentity();
+            mCallback.restore();
+            hideNotification();
+            Binder.restoreCallingIdentity(identity);
+            mInterface = null;
+            // TODO: unbind the service
         }
     }
 
     // INetworkManagementEventObserver.Stub
-    public synchronized void interfaceRemoved(String interfaze) {
-        if (interfaze.equals(mInterface) && jniCheck(interfaze) == 0) {
-            mCallback.restore();
-            hideNotification();
-            mInterface = null;
-        }
+    @Override
+    public void limitReached(String limit, String interfaze) {
     }
 
-    public void limitReached(String limitName, String iface) {}
-
     private void showNotification(VpnConfig config, String label, Bitmap icon) {
         NotificationManager nm = (NotificationManager)
                 mContext.getSystemService(Context.NOTIFICATION_SERVICE);
@@ -263,7 +265,6 @@
                     mContext.getString(R.string.vpn_text_long, config.session);
             config.startTime = SystemClock.elapsedRealtime();
 
-            long identity = Binder.clearCallingIdentity();
             Notification notification = new Notification.Builder(mContext)
                     .setSmallIcon(R.drawable.vpn_connected)
                     .setLargeIcon(icon)
@@ -274,7 +275,6 @@
                     .setOngoing(true)
                     .getNotification();
             nm.notify(R.drawable.vpn_connected, notification);
-            Binder.restoreCallingIdentity(identity);
         }
     }
 
@@ -283,9 +283,7 @@
                 mContext.getSystemService(Context.NOTIFICATION_SERVICE);
 
         if (nm != null) {
-            long identity = Binder.clearCallingIdentity();
             nm.cancel(R.drawable.vpn_connected);
-            Binder.restoreCallingIdentity(identity);
         }
     }
 
@@ -355,8 +353,8 @@
             mOuterInterface = mConfig.interfaze;
 
             // Legacy VPN is not a real package, so we use it to carry the key.
-            mInfo.key = mConfig.packagz;
-            mConfig.packagz = VpnConfig.LEGACY_VPN;
+            mInfo.key = mConfig.user;
+            mConfig.user = VpnConfig.LEGACY_VPN;
         }
 
         public void check(String interfaze) {
