diff --git a/java/com/android/server/sip/SipService.java b/java/com/android/server/sip/SipService.java
index afa696c..5ad5d26 100644
--- a/java/com/android/server/sip/SipService.java
+++ b/java/com/android/server/sip/SipService.java
@@ -60,6 +60,7 @@
 import java.util.Timer;
 import java.util.TimerTask;
 import java.util.TreeSet;
+import java.util.concurrent.Executor;
 import javax.sip.SipException;
 
 /**
@@ -68,8 +69,7 @@
 public final class SipService extends ISipService.Stub {
     static final String TAG = "SipService";
     static final boolean DEBUGV = false;
-    private static final boolean DEBUG = false;
-    private static final boolean DEBUG_TIMER = DEBUG && false;
+    static final boolean DEBUG = false;
     private static final int EXPIRY_TIME = 3600;
     private static final int SHORT_EXPIRY_TIME = 10;
     private static final int MIN_EXPIRY_TIME = 60;
@@ -78,13 +78,13 @@
     private String mLocalIp;
     private String mNetworkType;
     private boolean mConnected;
-    private WakeupTimer mTimer;
+    private SipWakeupTimer mTimer;
     private WifiScanProcess mWifiScanProcess;
     private WifiManager.WifiLock mWifiLock;
     private boolean mWifiOnly;
     private IntervalMeasurementProcess mIntervalMeasurementProcess;
 
-    private MyExecutor mExecutor;
+    private MyExecutor mExecutor = new MyExecutor();
 
     // SipProfile URI --> group
     private Map<String, SipSessionGroupExt> mSipGroups =
@@ -118,7 +118,7 @@
         mMyWakeLock = new SipWakeLock((PowerManager)
                 context.getSystemService(Context.POWER_SERVICE));
 
-        mTimer = new WakeupTimer(context);
+        mTimer = new SipWakeupTimer(context, mExecutor);
         mWifiOnly = SipManager.isSipWifiOnly(context);
     }
 
@@ -159,12 +159,6 @@
         if (DEBUG) Log.d(TAG, " --- unregister receivers");
     }
 
-    private MyExecutor getExecutor() {
-        // create mExecutor lazily
-        if (mExecutor == null) mExecutor = new MyExecutor();
-        return mExecutor;
-    }
-
     public synchronized SipProfile[] getListOfProfiles() {
         mContext.enforceCallingOrSelfPermission(
                 android.Manifest.permission.USE_SIP, null);
@@ -716,8 +710,8 @@
         private int mMaxInterval = MAX_INTERVAL;
         private int mInterval = MAX_INTERVAL / 2;
         private int mPassCounter = 0;
-        private WakeupTimer mTimer = new WakeupTimer(mContext);
-
+        private SipWakeupTimer mTimer = new SipWakeupTimer(mContext, mExecutor);
+        // TODO: fix SipWakeupTimer so that we only use one instance of the timer
 
         public IntervalMeasurementProcess(SipSessionGroup group) {
             try {
@@ -1123,7 +1117,7 @@
         @Override
         public void onReceive(final Context context, final Intent intent) {
             // Run the handler in MyExecutor to be protected by wake lock
-            getExecutor().execute(new Runnable() {
+            mExecutor.execute(new Runnable() {
                 public void run() {
                     onReceiveInternal(context, intent);
                 }
@@ -1227,7 +1221,7 @@
             @Override
             public void run() {
                 // delegate to mExecutor
-                getExecutor().execute(new Runnable() {
+                mExecutor.execute(new Runnable() {
                     public void run() {
                         realRun();
                     }
@@ -1252,300 +1246,6 @@
         }
     }
 
-    /**
-     * Timer that can schedule events to occur even when the device is in sleep.
-     * Only used internally in this package.
-     */
-    class WakeupTimer extends BroadcastReceiver {
-        private static final String TAG = "_SIP.WkTimer_";
-        private static final String TRIGGER_TIME = "TriggerTime";
-
-        private Context mContext;
-        private AlarmManager mAlarmManager;
-
-        // runnable --> time to execute in SystemClock
-        private TreeSet<MyEvent> mEventQueue =
-                new TreeSet<MyEvent>(new MyEventComparator());
-
-        private PendingIntent mPendingIntent;
-
-        public WakeupTimer(Context context) {
-            mContext = context;
-            mAlarmManager = (AlarmManager)
-                    context.getSystemService(Context.ALARM_SERVICE);
-
-            IntentFilter filter = new IntentFilter(getAction());
-            context.registerReceiver(this, filter);
-        }
-
-        /**
-         * Stops the timer. No event can be scheduled after this method is called.
-         */
-        public synchronized void stop() {
-            mContext.unregisterReceiver(this);
-            if (mPendingIntent != null) {
-                mAlarmManager.cancel(mPendingIntent);
-                mPendingIntent = null;
-            }
-            mEventQueue.clear();
-            mEventQueue = null;
-        }
-
-        private synchronized boolean stopped() {
-            if (mEventQueue == null) {
-                Log.w(TAG, "Timer stopped");
-                return true;
-            } else {
-                return false;
-            }
-        }
-
-        private void cancelAlarm() {
-            mAlarmManager.cancel(mPendingIntent);
-            mPendingIntent = null;
-        }
-
-        private void recalculatePeriods() {
-            if (mEventQueue.isEmpty()) return;
-
-            MyEvent firstEvent = mEventQueue.first();
-            int minPeriod = firstEvent.mMaxPeriod;
-            long minTriggerTime = firstEvent.mTriggerTime;
-            for (MyEvent e : mEventQueue) {
-                e.mPeriod = e.mMaxPeriod / minPeriod * minPeriod;
-                int interval = (int) (e.mLastTriggerTime + e.mMaxPeriod
-                        - minTriggerTime);
-                interval = interval / minPeriod * minPeriod;
-                e.mTriggerTime = minTriggerTime + interval;
-            }
-            TreeSet<MyEvent> newQueue = new TreeSet<MyEvent>(
-                    mEventQueue.comparator());
-            newQueue.addAll((Collection<MyEvent>) mEventQueue);
-            mEventQueue.clear();
-            mEventQueue = newQueue;
-            if (DEBUG_TIMER) {
-                Log.d(TAG, "queue re-calculated");
-                printQueue();
-            }
-        }
-
-        // Determines the period and the trigger time of the new event and insert it
-        // to the queue.
-        private void insertEvent(MyEvent event) {
-            long now = SystemClock.elapsedRealtime();
-            if (mEventQueue.isEmpty()) {
-                event.mTriggerTime = now + event.mPeriod;
-                mEventQueue.add(event);
-                return;
-            }
-            MyEvent firstEvent = mEventQueue.first();
-            int minPeriod = firstEvent.mPeriod;
-            if (minPeriod <= event.mMaxPeriod) {
-                event.mPeriod = event.mMaxPeriod / minPeriod * minPeriod;
-                int interval = event.mMaxPeriod;
-                interval -= (int) (firstEvent.mTriggerTime - now);
-                interval = interval / minPeriod * minPeriod;
-                event.mTriggerTime = firstEvent.mTriggerTime + interval;
-                mEventQueue.add(event);
-            } else {
-                long triggerTime = now + event.mPeriod;
-                if (firstEvent.mTriggerTime < triggerTime) {
-                    event.mTriggerTime = firstEvent.mTriggerTime;
-                    event.mLastTriggerTime -= event.mPeriod;
-                } else {
-                    event.mTriggerTime = triggerTime;
-                }
-                mEventQueue.add(event);
-                recalculatePeriods();
-            }
-        }
-
-        /**
-         * Sets a periodic timer.
-         *
-         * @param period the timer period; in milli-second
-         * @param callback is called back when the timer goes off; the same callback
-         *      can be specified in multiple timer events
-         */
-        public synchronized void set(int period, Runnable callback) {
-            if (stopped()) return;
-
-            long now = SystemClock.elapsedRealtime();
-            MyEvent event = new MyEvent(period, callback, now);
-            insertEvent(event);
-
-            if (mEventQueue.first() == event) {
-                if (mEventQueue.size() > 1) cancelAlarm();
-                scheduleNext();
-            }
-
-            long triggerTime = event.mTriggerTime;
-            if (DEBUG_TIMER) {
-                Log.d(TAG, " add event " + event + " scheduled at "
-                        + showTime(triggerTime) + " at " + showTime(now)
-                        + ", #events=" + mEventQueue.size());
-                printQueue();
-            }
-        }
-
-        /**
-         * Cancels all the timer events with the specified callback.
-         *
-         * @param callback the callback
-         */
-        public synchronized void cancel(Runnable callback) {
-            if (stopped() || mEventQueue.isEmpty()) return;
-            if (DEBUG_TIMER) Log.d(TAG, "cancel:" + callback);
-
-            MyEvent firstEvent = mEventQueue.first();
-            for (Iterator<MyEvent> iter = mEventQueue.iterator();
-                    iter.hasNext();) {
-                MyEvent event = iter.next();
-                if (event.mCallback == callback) {
-                    iter.remove();
-                    if (DEBUG_TIMER) Log.d(TAG, "    cancel found:" + event);
-                }
-            }
-            if (mEventQueue.isEmpty()) {
-                cancelAlarm();
-            } else if (mEventQueue.first() != firstEvent) {
-                cancelAlarm();
-                firstEvent = mEventQueue.first();
-                firstEvent.mPeriod = firstEvent.mMaxPeriod;
-                firstEvent.mTriggerTime = firstEvent.mLastTriggerTime
-                        + firstEvent.mPeriod;
-                recalculatePeriods();
-                scheduleNext();
-            }
-            if (DEBUG_TIMER) {
-                Log.d(TAG, "after cancel:");
-                printQueue();
-            }
-        }
-
-        private void scheduleNext() {
-            if (stopped() || mEventQueue.isEmpty()) return;
-
-            if (mPendingIntent != null) {
-                throw new RuntimeException("pendingIntent is not null!");
-            }
-
-            MyEvent event = mEventQueue.first();
-            Intent intent = new Intent(getAction());
-            intent.putExtra(TRIGGER_TIME, event.mTriggerTime);
-            PendingIntent pendingIntent = mPendingIntent =
-                    PendingIntent.getBroadcast(mContext, 0, intent,
-                            PendingIntent.FLAG_UPDATE_CURRENT);
-            mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
-                    event.mTriggerTime, pendingIntent);
-        }
-
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            // This callback is already protected by AlarmManager's wake lock.
-            String action = intent.getAction();
-            if (getAction().equals(action)
-                    && intent.getExtras().containsKey(TRIGGER_TIME)) {
-                mPendingIntent = null;
-                long triggerTime = intent.getLongExtra(TRIGGER_TIME, -1L);
-                execute(triggerTime);
-            } else {
-                Log.d(TAG, "unrecognized intent: " + intent);
-            }
-        }
-
-        private void printQueue() {
-            int count = 0;
-            for (MyEvent event : mEventQueue) {
-                Log.d(TAG, "     " + event + ": scheduled at "
-                        + showTime(event.mTriggerTime) + ": last at "
-                        + showTime(event.mLastTriggerTime));
-                if (++count >= 5) break;
-            }
-            if (mEventQueue.size() > count) {
-                Log.d(TAG, "     .....");
-            } else if (count == 0) {
-                Log.d(TAG, "     <empty>");
-            }
-        }
-
-        private synchronized void execute(long triggerTime) {
-            if (DEBUG_TIMER) Log.d(TAG, "time's up, triggerTime = "
-                    + showTime(triggerTime) + ": " + mEventQueue.size());
-            if (stopped() || mEventQueue.isEmpty()) return;
-
-            for (MyEvent event : mEventQueue) {
-                if (event.mTriggerTime != triggerTime) break;
-                if (DEBUG_TIMER) Log.d(TAG, "execute " + event);
-
-                event.mLastTriggerTime = event.mTriggerTime;
-                event.mTriggerTime += event.mPeriod;
-
-                // run the callback in the handler thread to prevent deadlock
-                getExecutor().execute(event.mCallback);
-            }
-            if (DEBUG_TIMER) {
-                Log.d(TAG, "after timeout execution");
-                printQueue();
-            }
-            scheduleNext();
-        }
-
-        private String getAction() {
-            return toString();
-        }
-
-        private String showTime(long time) {
-            int ms = (int) (time % 1000);
-            int s = (int) (time / 1000);
-            int m = s / 60;
-            s %= 60;
-            return String.format("%d.%d.%d", m, s, ms);
-        }
-    }
-
-    private static class MyEvent {
-        int mPeriod;
-        int mMaxPeriod;
-        long mTriggerTime;
-        long mLastTriggerTime;
-        Runnable mCallback;
-
-        MyEvent(int period, Runnable callback, long now) {
-            mPeriod = mMaxPeriod = period;
-            mCallback = callback;
-            mLastTriggerTime = now;
-        }
-
-        @Override
-        public String toString() {
-            String s = super.toString();
-            s = s.substring(s.indexOf("@"));
-            return s + ":" + (mPeriod / 1000) + ":" + (mMaxPeriod / 1000) + ":"
-                    + toString(mCallback);
-        }
-
-        private String toString(Object o) {
-            String s = o.toString();
-            int index = s.indexOf("$");
-            if (index > 0) s = s.substring(index + 1);
-            return s;
-        }
-    }
-
-    private static class MyEventComparator implements Comparator<MyEvent> {
-        public int compare(MyEvent e1, MyEvent e2) {
-            if (e1 == e2) return 0;
-            int diff = e1.mMaxPeriod - e2.mMaxPeriod;
-            if (diff == 0) diff = -1;
-            return diff;
-        }
-
-        public boolean equals(Object that) {
-            return (this == that);
-        }
-    }
-
     private static Looper createLooper() {
         HandlerThread thread = new HandlerThread("SipService.Executor");
         thread.start();
@@ -1554,12 +1254,13 @@
 
     // Executes immediate tasks in a single thread.
     // Hold/release wake lock for running tasks
-    private class MyExecutor extends Handler {
+    private class MyExecutor extends Handler implements Executor {
         MyExecutor() {
             super(createLooper());
         }
 
-        void execute(Runnable task) {
+        @Override
+        public void execute(Runnable task) {
             mMyWakeLock.acquire(task);
             Message.obtain(this, 0/* don't care */, task).sendToTarget();
         }
diff --git a/java/com/android/server/sip/SipWakeupTimer.java b/java/com/android/server/sip/SipWakeupTimer.java
new file mode 100644
index 0000000..9cc26b0
--- /dev/null
+++ b/java/com/android/server/sip/SipWakeupTimer.java
@@ -0,0 +1,339 @@
+/*
+ * 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 com.android.server.sip;
+
+import android.app.AlarmManager;
+import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.SystemClock;
+import android.util.Log;
+
+import java.io.IOException;
+import java.net.DatagramSocket;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Timer;
+import java.util.TimerTask;
+import java.util.TreeSet;
+import java.util.concurrent.Executor;
+import javax.sip.SipException;
+
+/**
+ * Timer that can schedule events to occur even when the device is in sleep.
+ */
+class SipWakeupTimer extends BroadcastReceiver {
+    private static final String TAG = "_SIP.WkTimer_";
+    private static final String TRIGGER_TIME = "TriggerTime";
+    private static final boolean DEBUG_TIMER = SipService.DEBUG && false;
+
+    private Context mContext;
+    private AlarmManager mAlarmManager;
+
+    // runnable --> time to execute in SystemClock
+    private TreeSet<MyEvent> mEventQueue =
+            new TreeSet<MyEvent>(new MyEventComparator());
+
+    private PendingIntent mPendingIntent;
+
+    private Executor mExecutor;
+
+    public SipWakeupTimer(Context context, Executor executor) {
+        mContext = context;
+        mAlarmManager = (AlarmManager)
+                context.getSystemService(Context.ALARM_SERVICE);
+
+        IntentFilter filter = new IntentFilter(getAction());
+        context.registerReceiver(this, filter);
+        mExecutor = executor;
+    }
+
+    /**
+     * Stops the timer. No event can be scheduled after this method is called.
+     */
+    public synchronized void stop() {
+        mContext.unregisterReceiver(this);
+        if (mPendingIntent != null) {
+            mAlarmManager.cancel(mPendingIntent);
+            mPendingIntent = null;
+        }
+        mEventQueue.clear();
+        mEventQueue = null;
+    }
+
+    private synchronized boolean stopped() {
+        if (mEventQueue == null) {
+            Log.w(TAG, "Timer stopped");
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    private void cancelAlarm() {
+        mAlarmManager.cancel(mPendingIntent);
+        mPendingIntent = null;
+    }
+
+    private void recalculatePeriods() {
+        if (mEventQueue.isEmpty()) return;
+
+        MyEvent firstEvent = mEventQueue.first();
+        int minPeriod = firstEvent.mMaxPeriod;
+        long minTriggerTime = firstEvent.mTriggerTime;
+        for (MyEvent e : mEventQueue) {
+            e.mPeriod = e.mMaxPeriod / minPeriod * minPeriod;
+            int interval = (int) (e.mLastTriggerTime + e.mMaxPeriod
+                    - minTriggerTime);
+            interval = interval / minPeriod * minPeriod;
+            e.mTriggerTime = minTriggerTime + interval;
+        }
+        TreeSet<MyEvent> newQueue = new TreeSet<MyEvent>(
+                mEventQueue.comparator());
+        newQueue.addAll((Collection<MyEvent>) mEventQueue);
+        mEventQueue.clear();
+        mEventQueue = newQueue;
+        if (DEBUG_TIMER) {
+            Log.d(TAG, "queue re-calculated");
+            printQueue();
+        }
+    }
+
+    // Determines the period and the trigger time of the new event and insert it
+    // to the queue.
+    private void insertEvent(MyEvent event) {
+        long now = SystemClock.elapsedRealtime();
+        if (mEventQueue.isEmpty()) {
+            event.mTriggerTime = now + event.mPeriod;
+            mEventQueue.add(event);
+            return;
+        }
+        MyEvent firstEvent = mEventQueue.first();
+        int minPeriod = firstEvent.mPeriod;
+        if (minPeriod <= event.mMaxPeriod) {
+            event.mPeriod = event.mMaxPeriod / minPeriod * minPeriod;
+            int interval = event.mMaxPeriod;
+            interval -= (int) (firstEvent.mTriggerTime - now);
+            interval = interval / minPeriod * minPeriod;
+            event.mTriggerTime = firstEvent.mTriggerTime + interval;
+            mEventQueue.add(event);
+        } else {
+            long triggerTime = now + event.mPeriod;
+            if (firstEvent.mTriggerTime < triggerTime) {
+                event.mTriggerTime = firstEvent.mTriggerTime;
+                event.mLastTriggerTime -= event.mPeriod;
+            } else {
+                event.mTriggerTime = triggerTime;
+            }
+            mEventQueue.add(event);
+            recalculatePeriods();
+        }
+    }
+
+    /**
+     * Sets a periodic timer.
+     *
+     * @param period the timer period; in milli-second
+     * @param callback is called back when the timer goes off; the same callback
+     *      can be specified in multiple timer events
+     */
+    public synchronized void set(int period, Runnable callback) {
+        if (stopped()) return;
+
+        long now = SystemClock.elapsedRealtime();
+        MyEvent event = new MyEvent(period, callback, now);
+        insertEvent(event);
+
+        if (mEventQueue.first() == event) {
+            if (mEventQueue.size() > 1) cancelAlarm();
+            scheduleNext();
+        }
+
+        long triggerTime = event.mTriggerTime;
+        if (DEBUG_TIMER) {
+            Log.d(TAG, " add event " + event + " scheduled at "
+                    + showTime(triggerTime) + " at " + showTime(now)
+                    + ", #events=" + mEventQueue.size());
+            printQueue();
+        }
+    }
+
+    /**
+     * Cancels all the timer events with the specified callback.
+     *
+     * @param callback the callback
+     */
+    public synchronized void cancel(Runnable callback) {
+        if (stopped() || mEventQueue.isEmpty()) return;
+        if (DEBUG_TIMER) Log.d(TAG, "cancel:" + callback);
+
+        MyEvent firstEvent = mEventQueue.first();
+        for (Iterator<MyEvent> iter = mEventQueue.iterator();
+                iter.hasNext();) {
+            MyEvent event = iter.next();
+            if (event.mCallback == callback) {
+                iter.remove();
+                if (DEBUG_TIMER) Log.d(TAG, "    cancel found:" + event);
+            }
+        }
+        if (mEventQueue.isEmpty()) {
+            cancelAlarm();
+        } else if (mEventQueue.first() != firstEvent) {
+            cancelAlarm();
+            firstEvent = mEventQueue.first();
+            firstEvent.mPeriod = firstEvent.mMaxPeriod;
+            firstEvent.mTriggerTime = firstEvent.mLastTriggerTime
+                    + firstEvent.mPeriod;
+            recalculatePeriods();
+            scheduleNext();
+        }
+        if (DEBUG_TIMER) {
+            Log.d(TAG, "after cancel:");
+            printQueue();
+        }
+    }
+
+    private void scheduleNext() {
+        if (stopped() || mEventQueue.isEmpty()) return;
+
+        if (mPendingIntent != null) {
+            throw new RuntimeException("pendingIntent is not null!");
+        }
+
+        MyEvent event = mEventQueue.first();
+        Intent intent = new Intent(getAction());
+        intent.putExtra(TRIGGER_TIME, event.mTriggerTime);
+        PendingIntent pendingIntent = mPendingIntent =
+                PendingIntent.getBroadcast(mContext, 0, intent,
+                        PendingIntent.FLAG_UPDATE_CURRENT);
+        mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
+                event.mTriggerTime, pendingIntent);
+    }
+
+    @Override
+    public void onReceive(Context context, Intent intent) {
+        // This callback is already protected by AlarmManager's wake lock.
+        String action = intent.getAction();
+        if (getAction().equals(action)
+                && intent.getExtras().containsKey(TRIGGER_TIME)) {
+            mPendingIntent = null;
+            long triggerTime = intent.getLongExtra(TRIGGER_TIME, -1L);
+            execute(triggerTime);
+        } else {
+            Log.d(TAG, "unrecognized intent: " + intent);
+        }
+    }
+
+    private void printQueue() {
+        int count = 0;
+        for (MyEvent event : mEventQueue) {
+            Log.d(TAG, "     " + event + ": scheduled at "
+                    + showTime(event.mTriggerTime) + ": last at "
+                    + showTime(event.mLastTriggerTime));
+            if (++count >= 5) break;
+        }
+        if (mEventQueue.size() > count) {
+            Log.d(TAG, "     .....");
+        } else if (count == 0) {
+            Log.d(TAG, "     <empty>");
+        }
+    }
+
+    private synchronized void execute(long triggerTime) {
+        if (DEBUG_TIMER) Log.d(TAG, "time's up, triggerTime = "
+                + showTime(triggerTime) + ": " + mEventQueue.size());
+        if (stopped() || mEventQueue.isEmpty()) return;
+
+        for (MyEvent event : mEventQueue) {
+            if (event.mTriggerTime != triggerTime) break;
+            if (DEBUG_TIMER) Log.d(TAG, "execute " + event);
+
+            event.mLastTriggerTime = event.mTriggerTime;
+            event.mTriggerTime += event.mPeriod;
+
+            // run the callback in the handler thread to prevent deadlock
+            mExecutor.execute(event.mCallback);
+        }
+        if (DEBUG_TIMER) {
+            Log.d(TAG, "after timeout execution");
+            printQueue();
+        }
+        scheduleNext();
+    }
+
+    private String getAction() {
+        return toString();
+    }
+
+    private String showTime(long time) {
+        int ms = (int) (time % 1000);
+        int s = (int) (time / 1000);
+        int m = s / 60;
+        s %= 60;
+        return String.format("%d.%d.%d", m, s, ms);
+    }
+
+    private static class MyEvent {
+        int mPeriod;
+        int mMaxPeriod;
+        long mTriggerTime;
+        long mLastTriggerTime;
+        Runnable mCallback;
+
+        MyEvent(int period, Runnable callback, long now) {
+            mPeriod = mMaxPeriod = period;
+            mCallback = callback;
+            mLastTriggerTime = now;
+        }
+
+        @Override
+        public String toString() {
+            String s = super.toString();
+            s = s.substring(s.indexOf("@"));
+            return s + ":" + (mPeriod / 1000) + ":" + (mMaxPeriod / 1000) + ":"
+                    + toString(mCallback);
+        }
+
+        private String toString(Object o) {
+            String s = o.toString();
+            int index = s.indexOf("$");
+            if (index > 0) s = s.substring(index + 1);
+            return s;
+        }
+    }
+
+    private static class MyEventComparator implements Comparator<MyEvent> {
+        public int compare(MyEvent e1, MyEvent e2) {
+            if (e1 == e2) return 0;
+            int diff = e1.mMaxPeriod - e2.mMaxPeriod;
+            if (diff == 0) diff = -1;
+            return diff;
+        }
+
+        public boolean equals(Object that) {
+            return (this == that);
+        }
+    }
+}
