diff --git a/tts/java/android/tts/TtsService.java b/tts/java/android/tts/TtsService.java
index 4b794db..d317181 100755
--- a/tts/java/android/tts/TtsService.java
+++ b/tts/java/android/tts/TtsService.java
@@ -45,563 +45,216 @@
  */
 public class TtsService extends Service implements OnCompletionListener {
 
-  private class SpeechItem {
-    public static final int SPEECH = 0;
-    public static final int EARCON = 1;
-    public static final int SILENCE = 2;
-    public String mText = null;
-    public ArrayList<String> mParams = null;
-    public int mType = SPEECH;
-    public long mDuration = 0;
+    private static class SpeechItem {
+        public static final int SPEECH = 0;
+        public static final int EARCON = 1;
+        public static final int SILENCE = 2;
+        public String mText = null;
+        public ArrayList<String> mParams = null;
+        public int mType = SPEECH;
+        public long mDuration = 0;
 
-    public SpeechItem(String text, ArrayList<String> params, int itemType) {
-      mText = text;
-      mParams = params;
-      mType = itemType;
-    }
-
-    public SpeechItem(long silenceTime) {
-      mDuration = silenceTime;
-    }
-  }
-
-  /**
-   * Contains the information needed to access a sound resource; the name of
-   * the package that contains the resource and the resID of the resource
-   * within that package.
-   */
-  private class SoundResource {
-    public String mSourcePackageName = null;
-    public int mResId = -1;
-    public String mFilename = null;
-
-    public SoundResource(String packageName, int id) {
-      mSourcePackageName = packageName;
-      mResId = id;
-      mFilename = null;
-    }
-
-    public SoundResource(String file) {
-      mSourcePackageName = null;
-      mResId = -1;
-      mFilename = file;
-    }
-  }
-
-  private static final String ACTION = "android.intent.action.USE_TTS";
-  private static final String CATEGORY = "android.intent.category.TTS";
-  private static final String PKGNAME = "android.tts";
-
-  final RemoteCallbackList<ITtsCallback> mCallbacks = new RemoteCallbackList<ITtsCallback>();
-
-  private Boolean isSpeaking;
-  private ArrayList<SpeechItem> speechQueue;
-  private HashMap<String, SoundResource> earcons;
-  private HashMap<String, SoundResource> utterances;
-  private MediaPlayer player;
-  private TtsService self;
-
-  private SharedPreferences prefs;
-
-  private final ReentrantLock speechQueueLock = new ReentrantLock();
-  private final ReentrantLock synthesizerLock = new ReentrantLock();
-
-  // TODO support multiple SpeechSynthesis objects
-  private SynthProxy nativeSynth;
-
-  @Override
-  public void onCreate() {
-    super.onCreate();
-    Log.i("TTS", "TTS starting");
-
-
-    // TODO: Make this work when the settings are done in the main Settings
-    // app.
-    prefs = PreferenceManager.getDefaultSharedPreferences(this);
-
-    // TODO: This should be changed to work by requesting the path
-    // from the default engine.
-    nativeSynth = new SynthProxy(prefs.getString("engine_pref", ""));
-
-
-    self = this;
-    isSpeaking = false;
-
-    earcons = new HashMap<String, SoundResource>();
-    utterances = new HashMap<String, SoundResource>();
-
-    speechQueue = new ArrayList<SpeechItem>();
-    player = null;
-
-    setLanguage(prefs.getString("lang_pref", "en-rUS"));
-    setSpeechRate(Integer.parseInt(prefs.getString("rate_pref", "140")));
-  }
-
-  @Override
-  public void onDestroy() {
-    super.onDestroy();
-    // Don't hog the media player
-    cleanUpPlayer();
-
-    nativeSynth.shutdown();
-
-    // Unregister all callbacks.
-    mCallbacks.kill();
-  }
-
-  private void setSpeechRate(int rate) {
-    if (prefs.getBoolean("override_pref", false)) {
-      // This is set to the default here so that the preview in the prefs
-      // activity will show the change without a restart, even if apps are
-      // not allowed to change the defaults.
-      rate = Integer.parseInt(prefs.getString("rate_pref", "140"));
-    }
-    nativeSynth.setSpeechRate(rate);
-  }
-
-  private void setLanguage(String lang) {
-    if (prefs.getBoolean("override_pref", false)) {
-      // This is set to the default here so that the preview in the prefs
-      // activity will show the change without a restart, even if apps are
-      // not
-      // allowed to change the defaults.
-      lang = prefs.getString("lang_pref", "en-rUS");
-    }
-    nativeSynth.setLanguage(lang);
-  }
-
-  private void setEngine(String engineName, String[] requestedLanguages,
-      int strictness) {
-    // TODO: Implement engine selection code here.
-    Intent engineIntent = new Intent(
-        "android.intent.action.START_TTS_ENGINE");
-    if (engineName != null) {
-      engineIntent.addCategory("android.intent.action.tts_engine."
-          + engineName);
-    }
-    for (int i = 0; i < requestedLanguages.length; i++) {
-      engineIntent.addCategory("android.intent.action.tts_lang."
-          + requestedLanguages[i]);
-    }
-    ResolveInfo[] enginesArray = new ResolveInfo[0];
-    PackageManager pm = getPackageManager();
-    enginesArray = pm.queryIntentActivities(engineIntent, 0).toArray(
-        enginesArray);
-  }
-
-  private void setEngine(Intent engineIntent) {
-    // TODO: Implement engine selection code here.
-  }
-
-  private int getEngineStatus() {
-    // TODO: Proposal - add a sanity check method that
-    // TTS engine plugins must implement.
-    return 0;
-  }
-
-  /**
-   * Adds a sound resource to the TTS.
-   *
-   * @param text
-   *            The text that should be associated with the sound resource
-   * @param packageName
-   *            The name of the package which has the sound resource
-   * @param resId
-   *            The resource ID of the sound within its package
-   */
-  private void addSpeech(String text, String packageName, int resId) {
-    utterances.put(text, new SoundResource(packageName, resId));
-  }
-
-  /**
-   * Adds a sound resource to the TTS.
-   *
-   * @param text
-   *            The text that should be associated with the sound resource
-   * @param filename
-   *            The filename of the sound resource. This must be a complete
-   *            path like: (/sdcard/mysounds/mysoundbite.mp3).
-   */
-  private void addSpeech(String text, String filename) {
-    utterances.put(text, new SoundResource(filename));
-  }
-
-  /**
-   * Adds a sound resource to the TTS as an earcon.
-   *
-   * @param earcon
-   *            The text that should be associated with the sound resource
-   * @param packageName
-   *            The name of the package which has the sound resource
-   * @param resId
-   *            The resource ID of the sound within its package
-   */
-  private void addEarcon(String earcon, String packageName, int resId) {
-    earcons.put(earcon, new SoundResource(packageName, resId));
-  }
-
-  /**
-   * Adds a sound resource to the TTS as an earcon.
-   *
-   * @param earcon
-   *            The text that should be associated with the sound resource
-   * @param filename
-   *            The filename of the sound resource. This must be a complete
-   *            path like: (/sdcard/mysounds/mysoundbite.mp3).
-   */
-  private void addEarcon(String earcon, String filename) {
-    earcons.put(earcon, new SoundResource(filename));
-  }
-
-  /**
-   * Speaks the given text using the specified queueing mode and parameters.
-   *
-   * @param text
-   *            The text that should be spoken
-   * @param queueMode
-   *            0 for no queue (interrupts all previous utterances), 1 for
-   *            queued
-   * @param params
-   *            An ArrayList of parameters. This is not implemented for all
-   *            engines.
-   */
-  private void speak(String text, int queueMode, ArrayList<String> params) {
-    if (queueMode == 0) {
-      stop();
-    }
-    speechQueue.add(new SpeechItem(text, params, SpeechItem.SPEECH));
-    if (!isSpeaking) {
-      processSpeechQueue();
-    }
-  }
-
-  /**
-   * Plays the earcon using the specified queueing mode and parameters.
-   *
-   * @param earcon
-   *            The earcon that should be played
-   * @param queueMode
-   *            0 for no queue (interrupts all previous utterances), 1 for
-   *            queued
-   * @param params
-   *            An ArrayList of parameters. This is not implemented for all
-   *            engines.
-   */
-  private void playEarcon(String earcon, int queueMode,
-      ArrayList<String> params) {
-    if (queueMode == 0) {
-      stop();
-    }
-    speechQueue.add(new SpeechItem(earcon, params, SpeechItem.EARCON));
-    if (!isSpeaking) {
-      processSpeechQueue();
-    }
-  }
-
-  /**
-   * Stops all speech output and removes any utterances still in the queue.
-   */
-  private void stop() {
-    Log.i("TTS", "Stopping");
-    speechQueue.clear();
-
-    nativeSynth.stop();
-    isSpeaking = false;
-    if (player != null) {
-      try {
-        player.stop();
-      } catch (IllegalStateException e) {
-        // Do nothing, the player is already stopped.
-      }
-    }
-    Log.i("TTS", "Stopped");
-  }
-
-  public void onCompletion(MediaPlayer arg0) {
-    processSpeechQueue();
-  }
-
-  private void playSilence(long duration, int queueMode,
-      ArrayList<String> params) {
-    if (queueMode == 0) {
-      stop();
-    }
-    speechQueue.add(new SpeechItem(duration));
-    if (!isSpeaking) {
-      processSpeechQueue();
-    }
-  }
-
-  private void silence(final long duration) {
-    class SilenceThread implements Runnable {
-      public void run() {
-        try {
-          Thread.sleep(duration);
-        } catch (InterruptedException e) {
-          e.printStackTrace();
-        } finally {
-          processSpeechQueue();
+        public SpeechItem(String text, ArrayList<String> params, int itemType) {
+            mText = text;
+            mParams = params;
+            mType = itemType;
         }
-      }
-    }
-    Thread slnc = (new Thread(new SilenceThread()));
-    slnc.setPriority(Thread.MIN_PRIORITY);
-    slnc.start();
-  }
 
-  private void speakInternalOnly(final String text,
-      final ArrayList<String> params) {
-    class SynthThread implements Runnable {
-      public void run() {
-        boolean synthAvailable = false;
-        try {
-          synthAvailable = synthesizerLock.tryLock();
-          if (!synthAvailable) {
-            Thread.sleep(100);
-            Thread synth = (new Thread(new SynthThread()));
-            synth.setPriority(Thread.MIN_PRIORITY);
-            synth.start();
-            return;
-          }
-          nativeSynth.speak(text);
-        } catch (InterruptedException e) {
-          e.printStackTrace();
-        } finally {
-          // This check is needed because finally will always run;
-          // even if the
-          // method returns somewhere in the try block.
-          if (synthAvailable) {
-            synthesizerLock.unlock();
-          }
+        public SpeechItem(long silenceTime) {
+            mDuration = silenceTime;
         }
-      }
     }
-    Thread synth = (new Thread(new SynthThread()));
-    synth.setPriority(Thread.MIN_PRIORITY);
-    synth.start();
-  }
 
-  private SoundResource getSoundResource(SpeechItem speechItem) {
-    SoundResource sr = null;
-    String text = speechItem.mText;
-    if (speechItem.mType == SpeechItem.SILENCE) {
-      // Do nothing if this is just silence
-    } else if (speechItem.mType == SpeechItem.EARCON) {
-      sr = earcons.get(text);
-    } else {
-      sr = utterances.get(text);
-    }
-    return sr;
-  }
+    /**
+     * Contains the information needed to access a sound resource; the name of
+     * the package that contains the resource and the resID of the resource
+     * within that package.
+     */
+    private static class SoundResource {
+        public String mSourcePackageName = null;
+        public int mResId = -1;
+        public String mFilename = null;
 
-  private void dispatchSpeechCompletedCallbacks(String mark) {
-    Log.i("TTS callback", "dispatch started");
-    // Broadcast to all clients the new value.
-    final int N = mCallbacks.beginBroadcast();
-    for (int i = 0; i < N; i++) {
-      try {
-        mCallbacks.getBroadcastItem(i).markReached(mark);
-      } catch (RemoteException e) {
-        // The RemoteCallbackList will take care of removing
-        // the dead object for us.
-      }
-    }
-    mCallbacks.finishBroadcast();
-    Log.i("TTS callback", "dispatch completed to " + N);
-  }
-
-  private void processSpeechQueue() {
-    boolean speechQueueAvailable = false;
-    try {
-      speechQueueAvailable = speechQueueLock.tryLock();
-      if (!speechQueueAvailable) {
-        return;
-      }
-      if (speechQueue.size() < 1) {
-        isSpeaking = false;
-        // Dispatch a completion here as this is the
-        // only place where speech completes normally.
-        // Nothing left to say in the queue is a special case
-        // that is always a "mark" - associated text is null.
-        dispatchSpeechCompletedCallbacks("");
-        return;
-      }
-
-      SpeechItem currentSpeechItem = speechQueue.get(0);
-      isSpeaking = true;
-      SoundResource sr = getSoundResource(currentSpeechItem);
-      // Synth speech as needed - synthesizer should call
-      // processSpeechQueue to continue running the queue
-      Log.i("TTS processing: ", currentSpeechItem.mText);
-      if (sr == null) {
-        if (currentSpeechItem.mType == SpeechItem.SPEECH) {
-          // TODO: Split text up into smaller chunks before accepting
-          // them
-          // for processing.
-          speakInternalOnly(currentSpeechItem.mText,
-              currentSpeechItem.mParams);
-        } else {
-          // This is either silence or an earcon that was missing
-          silence(currentSpeechItem.mDuration);
+        public SoundResource(String packageName, int id) {
+            mSourcePackageName = packageName;
+            mResId = id;
+            mFilename = null;
         }
-      } else {
+
+        public SoundResource(String file) {
+            mSourcePackageName = null;
+            mResId = -1;
+            mFilename = file;
+        }
+    }
+
+    private static final String ACTION = "android.intent.action.USE_TTS";
+    private static final String CATEGORY = "android.intent.category.TTS";
+    private static final String PKGNAME = "android.tts";
+
+    final RemoteCallbackList<ITtsCallback> mCallbacks = new RemoteCallbackList<ITtsCallback>();
+
+    private Boolean mIsSpeaking;
+    private ArrayList<SpeechItem> mSpeechQueue;
+    private HashMap<String, SoundResource> mEarcons;
+    private HashMap<String, SoundResource> mUtterances;
+    private MediaPlayer mPlayer;
+    private TtsService mSelf;
+
+    private SharedPreferences prefs;
+
+    private final ReentrantLock speechQueueLock = new ReentrantLock();
+    private final ReentrantLock synthesizerLock = new ReentrantLock();
+
+    // TODO support multiple SpeechSynthesis objects
+    private SynthProxy nativeSynth;
+
+    @Override
+    public void onCreate() {
+        super.onCreate();
+        Log.i("TTS", "TTS starting");
+
+
+        // TODO: Make this work when the settings are done in the main Settings
+        // app.
+        prefs = PreferenceManager.getDefaultSharedPreferences(this);
+
+        // TODO: This should be changed to work by requesting the path
+        // from the default engine.
+        nativeSynth = new SynthProxy(prefs.getString("engine_pref", ""));
+
+
+        mSelf = this;
+        mIsSpeaking = false;
+
+        mEarcons = new HashMap<String, SoundResource>();
+        mUtterances = new HashMap<String, SoundResource>();
+
+        mSpeechQueue = new ArrayList<SpeechItem>();
+        mPlayer = null;
+
+        setLanguage(prefs.getString("lang_pref", "en-rUS"));
+        setSpeechRate(Integer.parseInt(prefs.getString("rate_pref", "140")));
+    }
+
+    @Override
+    public void onDestroy() {
+        super.onDestroy();
+        // Don't hog the media player
         cleanUpPlayer();
-        if (sr.mSourcePackageName == PKGNAME) {
-          // Utterance is part of the TTS library
-          player = MediaPlayer.create(this, sr.mResId);
-        } else if (sr.mSourcePackageName != null) {
-          // Utterance is part of the app calling the library
-          Context ctx;
-          try {
-            ctx = this.createPackageContext(sr.mSourcePackageName,
-                0);
-          } catch (NameNotFoundException e) {
-            e.printStackTrace();
-            speechQueue.remove(0); // Remove it from the queue and
-            // move on
-            isSpeaking = false;
-            return;
-          }
-          player = MediaPlayer.create(ctx, sr.mResId);
-        } else {
-          // Utterance is coming from a file
-          player = MediaPlayer.create(this, Uri.parse(sr.mFilename));
+
+        nativeSynth.shutdown();
+
+        // Unregister all callbacks.
+        mCallbacks.kill();
+    }
+
+    private void setSpeechRate(int rate) {
+        if (prefs.getBoolean("override_pref", false)) {
+            // This is set to the default here so that the preview in the prefs
+            // activity will show the change without a restart, even if apps are
+            // not allowed to change the defaults.
+            rate = Integer.parseInt(prefs.getString("rate_pref", "140"));
         }
+        nativeSynth.setSpeechRate(rate);
+    }
 
-        // Check if Media Server is dead; if it is, clear the queue and
-        // give up for now - hopefully, it will recover itself.
-        if (player == null) {
-          speechQueue.clear();
-          isSpeaking = false;
-          return;
+    private void setLanguage(String lang) {
+        if (prefs.getBoolean("override_pref", false)) {
+            // This is set to the default here so that the preview in the prefs
+            // activity will show the change without a restart, even if apps are
+            // not
+            // allowed to change the defaults.
+            lang = prefs.getString("lang_pref", "en-rUS");
         }
-        player.setOnCompletionListener(this);
-        try {
-          player.start();
-        } catch (IllegalStateException e) {
-          speechQueue.clear();
-          isSpeaking = false;
-          cleanUpPlayer();
-          return;
+        nativeSynth.setLanguage(lang);
+    }
+
+    private void setEngine(String engineName, String[] requestedLanguages,
+            int strictness) {
+        // TODO: Implement engine selection code here.
+        Intent engineIntent = new Intent(
+        "android.intent.action.START_TTS_ENGINE");
+        if (engineName != null) {
+            engineIntent.addCategory("android.intent.action.tts_engine."
+                    + engineName);
         }
-      }
-      if (speechQueue.size() > 0) {
-        speechQueue.remove(0);
-      }
-    } finally {
-      // This check is needed because finally will always run; even if the
-      // method returns somewhere in the try block.
-      if (speechQueueAvailable) {
-        speechQueueLock.unlock();
-      }
-    }
-  }
-
-  private void cleanUpPlayer() {
-    if (player != null) {
-      player.release();
-      player = null;
-    }
-  }
-
-  /**
-   * Synthesizes the given text using the specified queuing mode and
-   * parameters.
-   *
-   * @param text
-   *            The String of text that should be synthesized
-   * @param params
-   *            An ArrayList of parameters. The first element of this array
-   *            controls the type of voice to use.
-   * @param filename
-   *            The string that gives the full output filename; it should be
-   *            something like "/sdcard/myappsounds/mysound.wav".
-   * @return A boolean that indicates if the synthesis succeeded
-   */
-  private boolean synthesizeToFile(String text, ArrayList<String> params,
-      String filename, boolean calledFromApi) {
-    // Only stop everything if this is a call made by an outside app trying
-    // to
-    // use the API. Do NOT stop if this is a call from within the service as
-    // clearing the speech queue here would be a mistake.
-    if (calledFromApi) {
-      stop();
-    }
-    Log.i("TTS", "Synthesizing to " + filename);
-    boolean synthAvailable = false;
-    try {
-      synthAvailable = synthesizerLock.tryLock();
-      if (!synthAvailable) {
-        return false;
-      }
-      // Don't allow a filename that is too long
-      // TODO use platform constant
-      if (filename.length() > 250) {
-        return false;
-      }
-      nativeSynth.synthesizeToFile(text, filename);
-    } finally {
-      // This check is needed because finally will always run; even if the
-      // method returns somewhere in the try block.
-      if (synthAvailable) {
-        synthesizerLock.unlock();
-      }
-    }
-    Log.i("TTS", "Completed synthesis for " + filename);
-    return true;
-  }
-
-  @Override
-  public IBinder onBind(Intent intent) {
-    if (ACTION.equals(intent.getAction())) {
-      for (String category : intent.getCategories()) {
-        if (category.equals(CATEGORY)) {
-          return mBinder;
+        for (int i = 0; i < requestedLanguages.length; i++) {
+            engineIntent.addCategory("android.intent.action.tts_lang."
+                    + requestedLanguages[i]);
         }
-      }
-    }
-    return null;
-  }
-
-  private final ITts.Stub mBinder = new Stub() {
-
-    public void registerCallback(ITtsCallback cb) {
-      if (cb != null)
-        mCallbacks.register(cb);
+        ResolveInfo[] enginesArray = new ResolveInfo[0];
+        PackageManager pm = getPackageManager();
+        enginesArray = pm.queryIntentActivities(engineIntent, 0).toArray(
+                enginesArray);
     }
 
-    public void unregisterCallback(ITtsCallback cb) {
-      if (cb != null)
-        mCallbacks.unregister(cb);
+    private void setEngine(Intent engineIntent) {
+        // TODO: Implement engine selection code here.
+    }
+
+    private int getEngineStatus() {
+        // TODO: Proposal - add a sanity check method that
+        // TTS engine plugins must implement.
+        return 0;
     }
 
     /**
-     * Gives a hint about the type of engine that is preferred.
+     * Adds a sound resource to the TTS.
      *
-     * @param selectedEngine
-     *            The TTS engine that should be used
+     * @param text
+     *            The text that should be associated with the sound resource
+     * @param packageName
+     *            The name of the package which has the sound resource
+     * @param resId
+     *            The resource ID of the sound within its package
      */
-    public void setEngine(String engineName, String[] supportedLanguages,
-        int strictness) {
-      self.setEngine(engineName, supportedLanguages, strictness);
+    private void addSpeech(String text, String packageName, int resId) {
+        mUtterances.put(text, new SoundResource(packageName, resId));
     }
 
     /**
-     * Specifies exactly what the engine has to support. Will always be
-     * considered "strict"; can be used for implementing
-     * optional/experimental features that are not supported by all engines.
+     * Adds a sound resource to the TTS.
      *
-     * @param engineIntent
-     *            An intent that specifies exactly what the engine has to
-     *            support.
+     * @param text
+     *            The text that should be associated with the sound resource
+     * @param filename
+     *            The filename of the sound resource. This must be a complete
+     *            path like: (/sdcard/mysounds/mysoundbite.mp3).
      */
-    public void setEngineWithIntent(Intent engineIntent) {
-      self.setEngine(engineIntent);
+    private void addSpeech(String text, String filename) {
+        mUtterances.put(text, new SoundResource(filename));
     }
 
     /**
-     * Speaks the given text using the specified queueing mode and
-     * parameters.
+     * Adds a sound resource to the TTS as an earcon.
+     *
+     * @param earcon
+     *            The text that should be associated with the sound resource
+     * @param packageName
+     *            The name of the package which has the sound resource
+     * @param resId
+     *            The resource ID of the sound within its package
+     */
+    private void addEarcon(String earcon, String packageName, int resId) {
+        mEarcons.put(earcon, new SoundResource(packageName, resId));
+    }
+
+    /**
+     * Adds a sound resource to the TTS as an earcon.
+     *
+     * @param earcon
+     *            The text that should be associated with the sound resource
+     * @param filename
+     *            The filename of the sound resource. This must be a complete
+     *            path like: (/sdcard/mysounds/mysoundbite.mp3).
+     */
+    private void addEarcon(String earcon, String filename) {
+        mEarcons.put(earcon, new SoundResource(filename));
+    }
+
+    /**
+     * Speaks the given text using the specified queueing mode and parameters.
      *
      * @param text
      *            The text that should be spoken
@@ -609,15 +262,17 @@
      *            0 for no queue (interrupts all previous utterances), 1 for
      *            queued
      * @param params
-     *            An ArrayList of parameters. The first element of this
-     *            array controls the type of voice to use.
+     *            An ArrayList of parameters. This is not implemented for all
+     *            engines.
      */
-    public void speak(String text, int queueMode, String[] params) {
-      ArrayList<String> speakingParams = new ArrayList<String>();
-      if (params != null) {
-        speakingParams = new ArrayList<String>(Arrays.asList(params));
-      }
-      self.speak(text, queueMode, speakingParams);
+    private void speak(String text, int queueMode, ArrayList<String> params) {
+        if (queueMode == 0) {
+            stop();
+        }
+        mSpeechQueue.add(new SpeechItem(text, params, SpeechItem.SPEECH));
+        if (!mIsSpeaking) {
+            processSpeechQueue();
+        }
     }
 
     /**
@@ -629,155 +284,500 @@
      *            0 for no queue (interrupts all previous utterances), 1 for
      *            queued
      * @param params
-     *            An ArrayList of parameters.
+     *            An ArrayList of parameters. This is not implemented for all
+     *            engines.
      */
-    public void playEarcon(String earcon, int queueMode, String[] params) {
-      ArrayList<String> speakingParams = new ArrayList<String>();
-      if (params != null) {
-        speakingParams = new ArrayList<String>(Arrays.asList(params));
-      }
-      self.playEarcon(earcon, queueMode, speakingParams);
+    private void playEarcon(String earcon, int queueMode,
+            ArrayList<String> params) {
+        if (queueMode == 0) {
+            stop();
+        }
+        mSpeechQueue.add(new SpeechItem(earcon, params, SpeechItem.EARCON));
+        if (!mIsSpeaking) {
+            processSpeechQueue();
+        }
     }
 
     /**
-     * Plays the silence using the specified queueing mode and parameters.
-     *
-     * @param duration
-     *            The duration of the silence that should be played
-     * @param queueMode
-     *            0 for no queue (interrupts all previous utterances), 1 for
-     *            queued
-     * @param params
-     *            An ArrayList of parameters.
+     * Stops all speech output and removes any utterances still in the queue.
      */
-    public void playSilence(long duration, int queueMode, String[] params) {
-      ArrayList<String> speakingParams = new ArrayList<String>();
-      if (params != null) {
-        speakingParams = new ArrayList<String>(Arrays.asList(params));
-      }
-      self.playSilence(duration, queueMode, speakingParams);
+    private void stop() {
+        Log.i("TTS", "Stopping");
+        mSpeechQueue.clear();
+
+        nativeSynth.stop();
+        mIsSpeaking = false;
+        if (mPlayer != null) {
+            try {
+                mPlayer.stop();
+            } catch (IllegalStateException e) {
+                // Do nothing, the player is already stopped.
+            }
+        }
+        Log.i("TTS", "Stopped");
     }
 
+    public void onCompletion(MediaPlayer arg0) {
+        processSpeechQueue();
+    }
 
-    /**
-     * Stops all speech output and removes any utterances still in the
-     * queue.
-     */
-    public void stop() {
-      self.stop();
+    private void playSilence(long duration, int queueMode,
+            ArrayList<String> params) {
+        if (queueMode == 0) {
+            stop();
+        }
+        mSpeechQueue.add(new SpeechItem(duration));
+        if (!mIsSpeaking) {
+            processSpeechQueue();
+        }
+    }
+
+    private void silence(final long duration) {
+        class SilenceThread implements Runnable {
+            public void run() {
+                try {
+                    Thread.sleep(duration);
+                } catch (InterruptedException e) {
+                    e.printStackTrace();
+                } finally {
+                    processSpeechQueue();
+                }
+            }
+        }
+        Thread slnc = (new Thread(new SilenceThread()));
+        slnc.setPriority(Thread.MIN_PRIORITY);
+        slnc.start();
+    }
+
+    private void speakInternalOnly(final String text,
+            final ArrayList<String> params) {
+        class SynthThread implements Runnable {
+            public void run() {
+                boolean synthAvailable = false;
+                try {
+                    synthAvailable = synthesizerLock.tryLock();
+                    if (!synthAvailable) {
+                        Thread.sleep(100);
+                        Thread synth = (new Thread(new SynthThread()));
+                        synth.setPriority(Thread.MIN_PRIORITY);
+                        synth.start();
+                        return;
+                    }
+                    nativeSynth.speak(text);
+                } catch (InterruptedException e) {
+                    e.printStackTrace();
+                } finally {
+                    // This check is needed because finally will always run;
+                    // even if the
+                    // method returns somewhere in the try block.
+                    if (synthAvailable) {
+                        synthesizerLock.unlock();
+                    }
+                }
+            }
+        }
+        Thread synth = (new Thread(new SynthThread()));
+        synth.setPriority(Thread.MIN_PRIORITY);
+        synth.start();
+    }
+
+    private SoundResource getSoundResource(SpeechItem speechItem) {
+        SoundResource sr = null;
+        String text = speechItem.mText;
+        if (speechItem.mType == SpeechItem.SILENCE) {
+            // Do nothing if this is just silence
+        } else if (speechItem.mType == SpeechItem.EARCON) {
+            sr = mEarcons.get(text);
+        } else {
+            sr = mUtterances.get(text);
+        }
+        return sr;
+    }
+
+    private void dispatchSpeechCompletedCallbacks(String mark) {
+        Log.i("TTS callback", "dispatch started");
+        // Broadcast to all clients the new value.
+        final int N = mCallbacks.beginBroadcast();
+        for (int i = 0; i < N; i++) {
+            try {
+                mCallbacks.getBroadcastItem(i).markReached(mark);
+            } catch (RemoteException e) {
+                // The RemoteCallbackList will take care of removing
+                // the dead object for us.
+            }
+        }
+        mCallbacks.finishBroadcast();
+        Log.i("TTS callback", "dispatch completed to " + N);
+    }
+
+    private void processSpeechQueue() {
+        boolean speechQueueAvailable = false;
+        try {
+            speechQueueAvailable = speechQueueLock.tryLock();
+            if (!speechQueueAvailable) {
+                return;
+            }
+            if (mSpeechQueue.size() < 1) {
+                mIsSpeaking = false;
+                // Dispatch a completion here as this is the
+                // only place where speech completes normally.
+                // Nothing left to say in the queue is a special case
+                // that is always a "mark" - associated text is null.
+                dispatchSpeechCompletedCallbacks("");
+                return;
+            }
+
+            SpeechItem currentSpeechItem = mSpeechQueue.get(0);
+            mIsSpeaking = true;
+            SoundResource sr = getSoundResource(currentSpeechItem);
+            // Synth speech as needed - synthesizer should call
+            // processSpeechQueue to continue running the queue
+            Log.i("TTS processing: ", currentSpeechItem.mText);
+            if (sr == null) {
+                if (currentSpeechItem.mType == SpeechItem.SPEECH) {
+                    // TODO: Split text up into smaller chunks before accepting
+                    // them
+                    // for processing.
+                    speakInternalOnly(currentSpeechItem.mText,
+                            currentSpeechItem.mParams);
+                } else {
+                    // This is either silence or an earcon that was missing
+                    silence(currentSpeechItem.mDuration);
+                }
+            } else {
+                cleanUpPlayer();
+                if (sr.mSourcePackageName == PKGNAME) {
+                    // Utterance is part of the TTS library
+                    mPlayer = MediaPlayer.create(this, sr.mResId);
+                } else if (sr.mSourcePackageName != null) {
+                    // Utterance is part of the app calling the library
+                    Context ctx;
+                    try {
+                        ctx = this.createPackageContext(sr.mSourcePackageName,
+                                0);
+                    } catch (NameNotFoundException e) {
+                        e.printStackTrace();
+                        mSpeechQueue.remove(0); // Remove it from the queue and
+                        // move on
+                        mIsSpeaking = false;
+                        return;
+                    }
+                    mPlayer = MediaPlayer.create(ctx, sr.mResId);
+                } else {
+                    // Utterance is coming from a file
+                    mPlayer = MediaPlayer.create(this, Uri.parse(sr.mFilename));
+                }
+
+                // Check if Media Server is dead; if it is, clear the queue and
+                // give up for now - hopefully, it will recover itself.
+                if (mPlayer == null) {
+                    mSpeechQueue.clear();
+                    mIsSpeaking = false;
+                    return;
+                }
+                mPlayer.setOnCompletionListener(this);
+                try {
+                    mPlayer.start();
+                } catch (IllegalStateException e) {
+                    mSpeechQueue.clear();
+                    mIsSpeaking = false;
+                    cleanUpPlayer();
+                    return;
+                }
+            }
+            if (mSpeechQueue.size() > 0) {
+                mSpeechQueue.remove(0);
+            }
+        } finally {
+            // This check is needed because finally will always run; even if the
+            // method returns somewhere in the try block.
+            if (speechQueueAvailable) {
+                speechQueueLock.unlock();
+            }
+        }
+    }
+
+    private void cleanUpPlayer() {
+        if (mPlayer != null) {
+            mPlayer.release();
+            mPlayer = null;
+        }
     }
 
     /**
-     * Returns whether or not the TTS is speaking.
-     *
-     * @return Boolean to indicate whether or not the TTS is speaking
-     */
-    public boolean isSpeaking() {
-      return (self.isSpeaking && (speechQueue.size() < 1));
-    }
-
-    /**
-     * Adds a sound resource to the TTS.
-     *
-     * @param text
-     *            The text that should be associated with the sound resource
-     * @param packageName
-     *            The name of the package which has the sound resource
-     * @param resId
-     *            The resource ID of the sound within its package
-     */
-    public void addSpeech(String text, String packageName, int resId) {
-      self.addSpeech(text, packageName, resId);
-    }
-
-    /**
-     * Adds a sound resource to the TTS.
-     *
-     * @param text
-     *            The text that should be associated with the sound resource
-     * @param filename
-     *            The filename of the sound resource. This must be a
-     *            complete path like: (/sdcard/mysounds/mysoundbite.mp3).
-     */
-    public void addSpeechFile(String text, String filename) {
-      self.addSpeech(text, filename);
-    }
-
-    /**
-     * Adds a sound resource to the TTS as an earcon.
-     *
-     * @param earcon
-     *            The text that should be associated with the sound resource
-     * @param packageName
-     *            The name of the package which has the sound resource
-     * @param resId
-     *            The resource ID of the sound within its package
-     */
-    public void addEarcon(String earcon, String packageName, int resId) {
-      self.addEarcon(earcon, packageName, resId);
-    }
-
-    /**
-     * Adds a sound resource to the TTS as an earcon.
-     *
-     * @param earcon
-     *            The text that should be associated with the sound resource
-     * @param filename
-     *            The filename of the sound resource. This must be a
-     *            complete path like: (/sdcard/mysounds/mysoundbite.mp3).
-     */
-    public void addEarconFile(String earcon, String filename) {
-      self.addEarcon(earcon, filename);
-    }
-
-    /**
-     * Sets the speech rate for the TTS. Note that this will only have an
-     * effect on synthesized speech; it will not affect pre-recorded speech.
-     *
-     * @param speechRate
-     *            The speech rate that should be used
-     */
-    public void setSpeechRate(int speechRate) {
-      self.setSpeechRate(speechRate);
-    }
-
-    // TODO: Fix comment about language
-    /**
-     * Sets the speech rate for the TTS. Note that this will only have an
-     * effect on synthesized speech; it will not affect pre-recorded speech.
-     *
-     * @param language
-     *            The language to be used. The languages are specified by
-     *            their IETF language tags as defined by BCP 47. This is the
-     *            same standard used for the lang attribute in HTML. See:
-     *            http://en.wikipedia.org/wiki/IETF_language_tag
-     */
-    public void setLanguage(String language) {
-      self.setLanguage(language);
-    }
-
-    /**
-     * Speaks the given text using the specified queueing mode and
+     * Synthesizes the given text using the specified queuing mode and
      * parameters.
      *
      * @param text
      *            The String of text that should be synthesized
      * @param params
-     *            An ArrayList of parameters. The first element of this
-     *            array controls the type of voice to use.
+     *            An ArrayList of parameters. The first element of this array
+     *            controls the type of voice to use.
      * @param filename
-     *            The string that gives the full output filename; it should
-     *            be something like "/sdcard/myappsounds/mysound.wav".
+     *            The string that gives the full output filename; it should be
+     *            something like "/sdcard/myappsounds/mysound.wav".
      * @return A boolean that indicates if the synthesis succeeded
      */
-    public boolean synthesizeToFile(String text, String[] params,
-        String filename) {
-      ArrayList<String> speakingParams = new ArrayList<String>();
-      if (params != null) {
-        speakingParams = new ArrayList<String>(Arrays.asList(params));
-      }
-      return self.synthesizeToFile(text, speakingParams, filename, true);
+    private boolean synthesizeToFile(String text, ArrayList<String> params,
+            String filename, boolean calledFromApi) {
+        // Only stop everything if this is a call made by an outside app trying
+        // to
+        // use the API. Do NOT stop if this is a call from within the service as
+        // clearing the speech queue here would be a mistake.
+        if (calledFromApi) {
+            stop();
+        }
+        Log.i("TTS", "Synthesizing to " + filename);
+        boolean synthAvailable = false;
+        try {
+            synthAvailable = synthesizerLock.tryLock();
+            if (!synthAvailable) {
+                return false;
+            }
+            // Don't allow a filename that is too long
+            // TODO use platform constant
+            if (filename.length() > 250) {
+                return false;
+            }
+            nativeSynth.synthesizeToFile(text, filename);
+        } finally {
+            // This check is needed because finally will always run; even if the
+            // method returns somewhere in the try block.
+            if (synthAvailable) {
+                synthesizerLock.unlock();
+            }
+        }
+        Log.i("TTS", "Completed synthesis for " + filename);
+        return true;
     }
-  };
+
+    @Override
+    public IBinder onBind(Intent intent) {
+        if (ACTION.equals(intent.getAction())) {
+            for (String category : intent.getCategories()) {
+                if (category.equals(CATEGORY)) {
+                    return mBinder;
+                }
+            }
+        }
+        return null;
+    }
+
+    private final ITts.Stub mBinder = new Stub() {
+
+        public void registerCallback(ITtsCallback cb) {
+            if (cb != null)
+                mCallbacks.register(cb);
+        }
+
+        public void unregisterCallback(ITtsCallback cb) {
+            if (cb != null)
+                mCallbacks.unregister(cb);
+        }
+
+        /**
+         * Gives a hint about the type of engine that is preferred.
+         *
+         * @param selectedEngine
+         *            The TTS engine that should be used
+         */
+        public void setEngine(String engineName, String[] supportedLanguages,
+                int strictness) {
+            mSelf.setEngine(engineName, supportedLanguages, strictness);
+        }
+
+        /**
+         * Specifies exactly what the engine has to support. Will always be
+         * considered "strict"; can be used for implementing
+         * optional/experimental features that are not supported by all engines.
+         *
+         * @param engineIntent
+         *            An intent that specifies exactly what the engine has to
+         *            support.
+         */
+        public void setEngineWithIntent(Intent engineIntent) {
+            mSelf.setEngine(engineIntent);
+        }
+
+        /**
+         * Speaks the given text using the specified queueing mode and
+         * parameters.
+         *
+         * @param text
+         *            The text that should be spoken
+         * @param queueMode
+         *            0 for no queue (interrupts all previous utterances), 1 for
+         *            queued
+         * @param params
+         *            An ArrayList of parameters. The first element of this
+         *            array controls the type of voice to use.
+         */
+        public void speak(String text, int queueMode, String[] params) {
+            ArrayList<String> speakingParams = new ArrayList<String>();
+            if (params != null) {
+                speakingParams = new ArrayList<String>(Arrays.asList(params));
+            }
+            mSelf.speak(text, queueMode, speakingParams);
+        }
+
+        /**
+         * Plays the earcon using the specified queueing mode and parameters.
+         *
+         * @param earcon
+         *            The earcon that should be played
+         * @param queueMode
+         *            0 for no queue (interrupts all previous utterances), 1 for
+         *            queued
+         * @param params
+         *            An ArrayList of parameters.
+         */
+        public void playEarcon(String earcon, int queueMode, String[] params) {
+            ArrayList<String> speakingParams = new ArrayList<String>();
+            if (params != null) {
+                speakingParams = new ArrayList<String>(Arrays.asList(params));
+            }
+            mSelf.playEarcon(earcon, queueMode, speakingParams);
+        }
+
+        /**
+         * Plays the silence using the specified queueing mode and parameters.
+         *
+         * @param duration
+         *            The duration of the silence that should be played
+         * @param queueMode
+         *            0 for no queue (interrupts all previous utterances), 1 for
+         *            queued
+         * @param params
+         *            An ArrayList of parameters.
+         */
+        public void playSilence(long duration, int queueMode, String[] params) {
+            ArrayList<String> speakingParams = new ArrayList<String>();
+            if (params != null) {
+                speakingParams = new ArrayList<String>(Arrays.asList(params));
+            }
+            mSelf.playSilence(duration, queueMode, speakingParams);
+        }
+
+
+        /**
+         * Stops all speech output and removes any utterances still in the
+         * queue.
+         */
+        public void stop() {
+            mSelf.stop();
+        }
+
+        /**
+         * Returns whether or not the TTS is speaking.
+         *
+         * @return Boolean to indicate whether or not the TTS is speaking
+         */
+        public boolean isSpeaking() {
+            return (mSelf.mIsSpeaking && (mSpeechQueue.size() < 1));
+        }
+
+        /**
+         * Adds a sound resource to the TTS.
+         *
+         * @param text
+         *            The text that should be associated with the sound resource
+         * @param packageName
+         *            The name of the package which has the sound resource
+         * @param resId
+         *            The resource ID of the sound within its package
+         */
+        public void addSpeech(String text, String packageName, int resId) {
+            mSelf.addSpeech(text, packageName, resId);
+        }
+
+        /**
+         * Adds a sound resource to the TTS.
+         *
+         * @param text
+         *            The text that should be associated with the sound resource
+         * @param filename
+         *            The filename of the sound resource. This must be a
+         *            complete path like: (/sdcard/mysounds/mysoundbite.mp3).
+         */
+        public void addSpeechFile(String text, String filename) {
+            mSelf.addSpeech(text, filename);
+        }
+
+        /**
+         * Adds a sound resource to the TTS as an earcon.
+         *
+         * @param earcon
+         *            The text that should be associated with the sound resource
+         * @param packageName
+         *            The name of the package which has the sound resource
+         * @param resId
+         *            The resource ID of the sound within its package
+         */
+        public void addEarcon(String earcon, String packageName, int resId) {
+            mSelf.addEarcon(earcon, packageName, resId);
+        }
+
+        /**
+         * Adds a sound resource to the TTS as an earcon.
+         *
+         * @param earcon
+         *            The text that should be associated with the sound resource
+         * @param filename
+         *            The filename of the sound resource. This must be a
+         *            complete path like: (/sdcard/mysounds/mysoundbite.mp3).
+         */
+        public void addEarconFile(String earcon, String filename) {
+            mSelf.addEarcon(earcon, filename);
+        }
+
+        /**
+         * Sets the speech rate for the TTS. Note that this will only have an
+         * effect on synthesized speech; it will not affect pre-recorded speech.
+         *
+         * @param speechRate
+         *            The speech rate that should be used
+         */
+        public void setSpeechRate(int speechRate) {
+            mSelf.setSpeechRate(speechRate);
+        }
+
+        // TODO: Fix comment about language
+        /**
+         * Sets the speech rate for the TTS. Note that this will only have an
+         * effect on synthesized speech; it will not affect pre-recorded speech.
+         *
+         * @param language
+         *            The language to be used. The languages are specified by
+         *            their IETF language tags as defined by BCP 47. This is the
+         *            same standard used for the lang attribute in HTML. See:
+         *            http://en.wikipedia.org/wiki/IETF_language_tag
+         */
+        public void setLanguage(String language) {
+            mSelf.setLanguage(language);
+        }
+
+        /**
+         * Speaks the given text using the specified queueing mode and
+         * parameters.
+         *
+         * @param text
+         *            The String of text that should be synthesized
+         * @param params
+         *            An ArrayList of parameters. The first element of this
+         *            array controls the type of voice to use.
+         * @param filename
+         *            The string that gives the full output filename; it should
+         *            be something like "/sdcard/myappsounds/mysound.wav".
+         * @return A boolean that indicates if the synthesis succeeded
+         */
+        public boolean synthesizeToFile(String text, String[] params,
+                String filename) {
+            ArrayList<String> speakingParams = new ArrayList<String>();
+            if (params != null) {
+                speakingParams = new ArrayList<String>(Arrays.asList(params));
+            }
+            return mSelf.synthesizeToFile(text, speakingParams, filename, true);
+        }
+    };
 
 }
