diff -pruN 0.2.21-3/debian/apparmor-profile 0.2.21-5/debian/apparmor-profile
--- 0.2.21-3/debian/apparmor-profile	2014-02-24 11:01:12.000000000 +0000
+++ 0.2.21-5/debian/apparmor-profile	2014-08-18 08:11:16.000000000 +0000
@@ -10,6 +10,9 @@
   owner @{HOME}/.vidalia/ rw,
   owner @{HOME}/.vidalia/** rwmk,
 
+  /{var/,} r,
+  /{var/,}run/ r,
+  /{var/,}run/tor/ r,
   /{var/,}run/tor/control rw,
   /{var/,}run/tor/control.authcookie r,
 
diff -pruN 0.2.21-3/debian/changelog 0.2.21-5/debian/changelog
--- 0.2.21-3/debian/changelog	2014-02-24 11:01:12.000000000 +0000
+++ 0.2.21-5/debian/changelog	2014-08-18 08:11:16.000000000 +0000
@@ -1,3 +1,24 @@
+vidalia (0.2.21-5) unstable; urgency=medium
+
+  * Put under the umbrella of the Anonymity Tools Debian Maintainers team.
+  * AppArmor: allow Vidalia to browse directories up to /{var/,}run/tor,
+    that contains the control port authentication cookie by default.
+  * Adjust-filename-of-the-cookie-authentication-file-to.patch:
+    new patch that adjusts the filename of the Tor cookie authentication file
+    to match Debian's default.
+  * Update README.Debian to match default location of the Tor authentication
+    cookie.
+
+ -- intrigeri <intrigeri@debian.org>  Thu, 14 Aug 2014 11:32:11 +0200
+
+vidalia (0.2.21-4) unstable; urgency=medium
+
+  * Add Turkish translation of debconf messages (Closes: #757501).
+    Thanks to Mert Dirik <mertdirik@gmail.com> for the patch!
+  * Drop Suggests on iceweasel-torbutton, that was removed from Debian.
+
+ -- intrigeri <intrigeri@debian.org>  Thu, 14 Aug 2014 09:50:50 +0200
+
 vidalia (0.2.21-3) unstable; urgency=medium
 
   * Disable miniupnpc support: it uses a very old embedded copy of that library.
diff -pruN 0.2.21-3/debian/control 0.2.21-5/debian/control
--- 0.2.21-3/debian/control	2014-02-24 11:01:12.000000000 +0000
+++ 0.2.21-5/debian/control	2014-08-18 08:11:16.000000000 +0000
@@ -1,8 +1,8 @@
 Source: vidalia
 Section: net
 Priority: extra
-Maintainer: Ulises Vitulli <dererk@debian.org>
-Uploaders: Vern Sun <s5unty@gmail.com>, intrigeri <intrigeri@debian.org>
+Maintainer: Anonymity Tools Debian Maintainers <pkg-anonymity-tools@lists.alioth.debian.org>
+Uploaders: Vern Sun <s5unty@gmail.com>, intrigeri <intrigeri@debian.org>, Ulises Vitulli <dererk@debian.org>
 Build-Depends: debhelper (>= 6.0.7~), dh-apparmor, autotools-dev, libqt4-dev, cmake, libssl-dev, dpkg-dev (>= 1.16.1.1~)
 Standards-Version: 3.9.5
 Homepage: https://www.torproject.org/projects/vidalia
@@ -13,7 +13,7 @@ Package: vidalia
 Architecture: any
 Depends: ${shlibs:Depends}, ${misc:Depends}, debconf | debconf-2.0,
  ucf, adduser, tor
-Suggests: iceweasel-torbutton, apparmor
+Suggests: apparmor
 Description: controller GUI for Tor
  Vidalia offers a graphical user interface to start and stop Tor, view
  its status at a glance, and monitor its bandwidth usage.
diff -pruN 0.2.21-3/debian/patches/Adjust-filename-of-the-cookie-authentication-file-to.patch 0.2.21-5/debian/patches/Adjust-filename-of-the-cookie-authentication-file-to.patch
--- 0.2.21-3/debian/patches/Adjust-filename-of-the-cookie-authentication-file-to.patch	1970-01-01 00:00:00.000000000 +0000
+++ 0.2.21-5/debian/patches/Adjust-filename-of-the-cookie-authentication-file-to.patch	2014-08-18 08:11:16.000000000 +0000
@@ -0,0 +1,73 @@
+From: intrigeri <intrigeri@boum.org>
+Date: Thu, 14 Aug 2014 09:28:19 +0000
+Subject: Adjust filename of the cookie authentication file to match Debian's
+ default.
+
+Debian's system-wide Tor service sets this torrc parameter:
+CookieAuthFile /var/run/tor/control.authcookie
+---
+ src/vidalia/MainWindow.cpp | 10 +++++-----
+ src/vidalia/MainWindow.h   |  2 +-
+ 2 files changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/src/vidalia/MainWindow.cpp b/src/vidalia/MainWindow.cpp
+index fef48ec..6c66240 100644
+--- a/src/vidalia/MainWindow.cpp
++++ b/src/vidalia/MainWindow.cpp
+@@ -1500,14 +1500,14 @@ MainWindow::authenticate()
+     /* Try to load an auth cookie and send it to Tor */
+     QByteArray cookie = loadControlCookie(pi.cookieAuthFile());
+     while (cookie.isEmpty()) {
+-      /* Prompt the user to find their control_auth_cookie */
++      /* Prompt the user to find their control.authcookie */
+       int ret = VMessageBox::question(this,
+                   tr("Cookie Authentication Required"),
+                   p(tr("The Tor software requires Vidalia to send the "
+                        "contents of an authentication cookie, but Vidalia "
+                        "was unable to find one."))
+                   + p(tr("Would you like to browse for the file "
+-                         "'control_auth_cookie' yourself?")),
++                         "'control.authcookie' yourself?")),
+                 VMessageBox::Browse|VMessageBox::Default,
+                 VMessageBox::Cancel|VMessageBox::Escape);
+ 
+@@ -1516,7 +1516,7 @@ MainWindow::authenticate()
+       QString cookieDir = QFileDialog::getOpenFileName(this,
+                             tr("Data Directory"),
+                             settings.getDataDirectory(),
+-                            tr("Control Cookie (control_auth_cookie)"));
++                            tr("Control Cookie (control.authcookie)"));
+       if (cookieDir.isEmpty())
+         goto cancel;
+       cookieDir = QFileInfo(cookieDir).absolutePath();
+@@ -1680,7 +1680,7 @@ MainWindow::authenticationFailed(QString errmsg)
+ }
+ 
+ /** Searches for and attempts to load the control authentication cookie. This
+- * assumes the cookie is named 'control_auth_cookie'. If <b>cookiePath</b> is
++ * assumes the cookie is named 'control.authcookie'. If <b>cookiePath</b> is
+  * empty, this method will search some default locations depending on the
+  * current platform. <b>cookiePath</b> can point to either a cookie file or a
+  * directory containing the cookie file. */
+@@ -1709,7 +1709,7 @@ MainWindow::loadControlCookie(QString cookiePath)
+   /* Search for the cookie file */
+   foreach (QString path, pathList) {
+     QString cookieFile = QFileInfo(path).isFile() ?
+-                          path : path + "/control_auth_cookie";
++                          path : path + "/control.authcookie";
+     vDebug("Checking for authentication cookie in '%1'").arg(cookieFile);
+     if (!QFileInfo(cookieFile).exists())
+       continue;
+diff --git a/src/vidalia/MainWindow.h b/src/vidalia/MainWindow.h
+index a434e66..a2ad35a 100644
+--- a/src/vidalia/MainWindow.h
++++ b/src/vidalia/MainWindow.h
+@@ -212,7 +212,7 @@ private:
+   /** Authenticates Vidalia to Tor's control port. */
+   bool authenticate();
+   /** Searches for and attempts to load the control authentication cookie.
+-   * This assumes the cookie is named 'control_auth_cookie'. If
++   * This assumes the cookie is named 'control.authcookie'. If
+    * <b>cookiePath</b> is empty, this method will search some default locations
+    * depending on the current platform. <b>cookiePath</b> can point to either
+    * a cookie file or a directory containing the cookie file. */
diff -pruN 0.2.21-3/debian/patches/series 0.2.21-5/debian/patches/series
--- 0.2.21-3/debian/patches/series	2014-02-24 11:01:12.000000000 +0000
+++ 0.2.21-5/debian/patches/series	2014-08-18 08:11:16.000000000 +0000
@@ -1,2 +1,3 @@
 debians-tor-binary-path.patch
 use-control-socket.patch
+Adjust-filename-of-the-cookie-authentication-file-to.patch
diff -pruN 0.2.21-3/debian/po/tr.po 0.2.21-5/debian/po/tr.po
--- 0.2.21-3/debian/po/tr.po	1970-01-01 00:00:00.000000000 +0000
+++ 0.2.21-5/debian/po/tr.po	2014-08-18 08:11:16.000000000 +0000
@@ -0,0 +1,52 @@
+# Turkish translation of vidalia package
+# Copyright (C) 2014 Mert Dirik
+# This file is distributed under the same license as the vidalia package.
+# Mert Dirik <mertdirik@gmail.com>, 2014.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: vidalia\n"
+"Report-Msgid-Bugs-To: vidalia@packages.debian.org\n"
+"POT-Creation-Date: 2012-01-06 01:47-0300\n"
+"PO-Revision-Date: 2014-08-01 17:24+0200\n"
+"Last-Translator: Mert Dirik <mertdirik@gmail.com>\n"
+"Language-Team: Debian L10n Turkish <debian-l10n-turkish@lists.debian.org>\n"
+"Language: tr\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: Poedit 1.5.4\n"
+
+#. Type: multiselect
+#. Description
+#: ../templates:1001
+msgid "Users to add to the debian-tor group:"
+msgstr "debian-tor grubuna eklenilecek kullanıcılar:"
+
+#. Type: multiselect
+#. Description
+#: ../templates:1001
+msgid ""
+"Select which users from the list below should be able to control Tor daemon."
+msgstr ""
+"Tor artalan sürecini yönetmesini istediğiniz kullanıcıları aşağıdaki "
+"listeden seçin."
+
+#. Type: multiselect
+#. Description
+#: ../templates:1001
+msgid ""
+"Please restart your X sessions to apply changes before starting Vidalia."
+msgstr ""
+"Lütfen Vidalia'yı başlatmadan önce X oturumlarını yeniden başlatarak "
+"ayarların etkin hale gelmesini sağlayın."
+
+#. Type: multiselect
+#. Description
+#: ../templates:1001
+msgid ""
+"For more information, please refer to /usr/share/doc/vidalia/README.Debian."
+"gz."
+msgstr ""
+"Daha fazla bilgi için /usr/share/doc/vidalia/README.Debian.gz dosyasına "
+"bakabilirsiniz."
diff -pruN 0.2.21-3/debian/README.Debian 0.2.21-5/debian/README.Debian
--- 0.2.21-3/debian/README.Debian	2014-02-24 11:01:12.000000000 +0000
+++ 0.2.21-5/debian/README.Debian	2014-08-18 08:11:16.000000000 +0000
@@ -91,7 +91,7 @@ Vidalia for Debian
      configure Vidalia to use it.
 
   2. Enable Tor's ControlPort and enable CookieAuthentication in Tor's config,
-    then grab the cookie file from /var/lib/tor/control_auth_cookie, profit!
+    then grab the cookie file from /var/lib/tor/control.authcookie, profit!
 
   3. Enable Tor's ControlPort, get a hashed password at 'tor --hash-password',
     load back the output into the HashedControlPassword Tor's config field, 
@@ -205,7 +205,7 @@ Vidalia for Debian
      
      ------------------------------------------------------------------------
        You will have to fetch the "cookie file" from your local filesystem,
-       by default at '/var/lib/tor/control_auth_cookie'
+       by default at '/var/lib/tor/control.authcookie'
 
        DO NOT share this file with anyone, Tor's privacy depends on it!
      ------------------------------------------------------------------------
@@ -280,4 +280,4 @@ Vidalia for Debian
 
 
 
- -- Ulises Vitulli <dererk@debian.org>  Sun, 12 Jun 2012 19:21:02 -0300
+ -- intrigeri <intrigeri@debian.org>, Thu, 14 Aug 2014 11:31:41 +0200
diff -pruN 0.2.21-3/.pc/Adjust-filename-of-the-cookie-authentication-file-to.patch/src/vidalia/MainWindow.cpp 0.2.21-5/.pc/Adjust-filename-of-the-cookie-authentication-file-to.patch/src/vidalia/MainWindow.cpp
--- 0.2.21-3/.pc/Adjust-filename-of-the-cookie-authentication-file-to.patch/src/vidalia/MainWindow.cpp	1970-01-01 00:00:00.000000000 +0000
+++ 0.2.21-5/.pc/Adjust-filename-of-the-cookie-authentication-file-to.patch/src/vidalia/MainWindow.cpp	2012-11-30 20:07:59.000000000 +0000
@@ -0,0 +1,2231 @@
+/*
+**  This file is part of Vidalia, and is subject to the license terms in the
+**  LICENSE file, found in the top level directory of this distribution. If you
+**  did not receive the LICENSE file with this file, you may obtain it from the
+**  Vidalia source package distributed by the Vidalia Project at
+**  http://www.torproject.org/projects/vidalia.html. No part of Vidalia,
+**  including this file, may be copied, modified, propagated, or distributed
+**  except according to the terms described in the LICENSE file.
+*/
+
+/*
+** \file MainWindow.cpp
+** \brief Main (hidden) window. Creates tray menu and child windows
+**
+** Implements the main window. The main window is a hidden window that serves
+** as the parent of the tray icon and popup menu, as well as other application
+** dialogs.
+*/
+
+#include "MainWindow.h"
+#include "Vidalia.h"
+#include "VMessageBox.h"
+#include "ControlPasswordInputDialog.h"
+#include "TorSettings.h"
+#include "ServerSettings.h"
+#ifdef USE_AUTOUPDATE
+#include "UpdatesAvailableDialog.h"
+#endif
+
+#include "ProtocolInfo.h"
+
+#include "net.h"
+#include "file.h"
+#include "html.h"
+#include "stringutil.h"
+#include "procutil.h"
+
+#include <QMenuBar>
+#include <QTimer>
+#include <QTextStream>
+
+#ifdef Q_WS_MAC
+#include <Carbon/Carbon.h>
+#endif
+
+#define IMG_BWGRAPH        ":/images/16x16/utilities-system-monitor.png"
+#define IMG_CONTROL_PANEL  ":/images/16x16/system-run.png"
+#define IMG_MESSAGELOG     ":/images/16x16/format-justify-fill.png"
+#define IMG_CONFIG         ":/images/16x16/preferences-system.png"
+#define IMG_IDENTITY       ":/images/16x16/view-media-artist.png"
+#define IMG_HELP           ":/images/16x16/system-help.png"
+#define IMG_ABOUT          ":/images/16x16/help-about.png"
+#define IMG_EXIT           ":/images/16x16/application-exit.png"
+#define IMG_NETWORK        ":/images/16x16/applications-internet.png"
+
+#define IMG_START_TOR_16     ":/images/16x16/media-playback-start.png"
+#define IMG_STOP_TOR_16      ":/images/16x16/media-playback-stop.png"
+#define IMG_START_TOR_48     ":/images/48x48/media-playback-start.png"
+#define IMG_STOP_TOR_48      ":/images/48x48/media-playback-stop.png"
+#define IMG_TOR_STOPPED_48   ":/images/48x48/tor-off.png"
+#define IMG_TOR_RUNNING_48   ":/images/48x48/tor-on.png"
+#define IMG_TOR_STARTING_48  ":/images/48x48/tor-starting.png"
+#define IMG_TOR_STOPPING_48  ":/images/48x48/tor-stopping.png"
+
+/* Decide which of our four sets of tray icons to use. */
+#if defined(Q_WS_WIN)
+/* QSystemTrayIcon on Windows wants 16x16 .png files */
+#define IMG_TOR_STOPPED  ":/images/16x16/tor-off.png"
+#define IMG_TOR_RUNNING  ":/images/16x16/tor-on.png"
+#define IMG_TOR_STARTING ":/images/16x16/tor-starting.png"
+#define IMG_TOR_STOPPING ":/images/16x16/tor-stopping.png"
+#elif defined(Q_WS_MAC)
+/* On Mac, the dock icons look best at 128x128, otherwise they get blurry
+ * if resized from a smaller image */
+#define IMG_TOR_STOPPED    ":/images/128x128/tor-off.png"
+#define IMG_TOR_RUNNING    ":/images/128x128/tor-on.png"
+#define IMG_TOR_STARTING   ":/images/128x128/tor-starting.png"
+#define IMG_TOR_STOPPING   ":/images/128x128/tor-stopping.png"
+void qt_mac_set_dock_menu(QMenu *menu);
+#else
+/* On X11, we just use always the 22x22 .png files */
+#define IMG_TOR_STOPPED    ":/images/22x22/tor-off.png"
+#define IMG_TOR_RUNNING    ":/images/22x22/tor-on.png"
+#define IMG_TOR_STARTING   ":/images/22x22/tor-starting.png"
+#define IMG_TOR_STOPPING   ":/images/22x22/tor-stopping.png"
+#endif
+
+/** Only allow 'New Identity' to be clicked once every 10 seconds. */
+#define MIN_NEWIDENTITY_INTERVAL   (10*1000)
+
+/* Startup progress milestones */
+#define STARTUP_PROGRESS_STARTING          0
+#define STARTUP_PROGRESS_CONNECTING       10
+#define STARTUP_PROGRESS_AUTHENTICATING   20
+#define STARTUP_PROGRESS_BOOTSTRAPPING    30
+#define STARTUP_PROGRESS_CIRCUITBUILD     75
+#define STARTUP_PROGRESS_MAXIMUM          (STARTUP_PROGRESS_BOOTSTRAPPING+100)
+
+/** Default constructor. It installs an icon in the system tray area and
+ * creates the popup menu associated with that icon. */
+MainWindow::MainWindow()
+: VidaliaWindow("MainWindow")
+{
+  VidaliaSettings settings;
+
+  ui.setupUi(this);
+
+  _warnTimer = new QTimer();
+
+  /* Pressing 'Esc' or 'Ctrl+W' will close the window */
+  Vidalia::createShortcut("Ctrl+W", this, ui.btnHide, SLOT(click()));
+  Vidalia::createShortcut("Esc", this, ui.btnHide, SLOT(click()));
+
+  /* Create all the dialogs of which we only want one instance */
+  _messageLog     = new MessageLog();
+  _bandwidthGraph = new BandwidthGraph();
+  _netViewer      = new NetViewer();
+  _configDialog   = new ConfigDialog();
+  _menuBar        = 0;
+  connect(_messageLog, SIGNAL(helpRequested(QString)),
+          this, SLOT(showHelpDialog(QString)));
+  connect(_netViewer, SIGNAL(helpRequested(QString)),
+          this, SLOT(showHelpDialog(QString)));
+  connect(_configDialog, SIGNAL(helpRequested(QString)),
+          this, SLOT(showHelpDialog(QString)));
+  connect(_configDialog, SIGNAL(restartTor()),
+          this, SLOT(restart()));
+
+  /* Create the actions that will go in the tray menu */
+  createActions();
+  /* Creates a tray icon with a context menu and adds it to the system's
+   * notification area. */
+  createTrayIcon();
+  /* Start with Tor initially stopped */
+  _status = Unset;
+  _isVidaliaRunningTor = false;
+  updateTorStatus(Stopped);
+
+  /* Create a new TorControl object, used to communicate with Tor */
+  _torControl = Vidalia::torControl();
+  connect(_torControl, SIGNAL(started()), this, SLOT(started()));
+  connect(_torControl, SIGNAL(startFailed(QString)),
+          this, SLOT(startFailed(QString)));
+  connect(_torControl, SIGNAL(stopped(int, QProcess::ExitStatus)),
+          this, SLOT(stopped(int, QProcess::ExitStatus)));
+  connect(_torControl, SIGNAL(connected()), this, SLOT(connected()));
+  connect(_torControl, SIGNAL(disconnected()), this, SLOT(disconnected()));
+  connect(_torControl, SIGNAL(connectFailed(QString)),
+          this, SLOT(connectFailed(QString)));
+  connect(_torControl, SIGNAL(authenticated()), this, SLOT(authenticated()));
+  connect(_torControl, SIGNAL(authenticationFailed(QString)),
+          this, SLOT(authenticationFailed(QString)));
+
+  _torControl->setEvent(TorEvents::GeneralStatus);
+  connect(_torControl, SIGNAL(dangerousTorVersion(tc::TorVersionStatus,
+                                                  QString, QStringList)),
+          this, SLOT(dangerousTorVersion(tc::TorVersionStatus,
+                                         QString, QStringList)));
+
+  _torControl->setEvent(TorEvents::ClientStatus);
+  connect(_torControl, SIGNAL(bootstrapStatusChanged(BootstrapStatus)),
+          this, SLOT(bootstrapStatusChanged(BootstrapStatus)));
+  connect(_torControl, SIGNAL(circuitEstablished()),
+          this, SLOT(circuitEstablished()));
+  connect(_torControl, SIGNAL(dangerousPort(quint16, bool)),
+          this, SLOT(warnDangerousPort(quint16, bool)));
+  connect(_torControl, SIGNAL(logMessage(tc::Severity, QString)),
+          this, SLOT(log(tc::Severity, QString)));
+
+  /* Create a new HelperProcess object, used to start the web browser */
+  _browserProcess = new HelperProcess(this);
+  connect(_browserProcess, SIGNAL(finished(int, QProcess::ExitStatus)),
+           this, SLOT(onSubprocessFinished(int, QProcess::ExitStatus)));
+  connect(_browserProcess, SIGNAL(startFailed(QString)),
+           this, SLOT(onBrowserFailed(QString)));
+
+  /* Create a new HelperProcess object, used to start the IM client */
+  _imProcess = new HelperProcess(this);
+  connect(_imProcess, SIGNAL(finished(int, QProcess::ExitStatus)),
+           this, SLOT(onSubprocessFinished(int, QProcess::ExitStatus)));
+  connect(_imProcess, SIGNAL(startFailed(QString)),
+           this, SLOT(onIMFailed(QString)));
+
+  /* Create a new HelperProcess object, used to start the proxy server */
+  _proxyProcess = new HelperProcess(this);
+  connect(_proxyProcess, SIGNAL(startFailed(QString)),
+           this, SLOT(onProxyFailed(QString)));
+
+  /* Catch signals when the application is running or shutting down */
+  connect(vApp, SIGNAL(running()), this, SLOT(running()));
+  connect(vApp, SIGNAL(aboutToQuit()), this, SLOT(aboutToQuit()));
+
+  connect(_warnTimer, SIGNAL(timeout()), this, SLOT(warnButton()));
+
+#if defined(USE_AUTOUPDATE)
+  /* Create a timer used to remind us to check for software updates */
+  connect(&_updateTimer, SIGNAL(timeout()), this, SLOT(checkForUpdates()));
+
+  /* Also check for updates in the foreground when the user clicks the
+   * "Check Now" button in the config dialog. */
+  connect(_configDialog, SIGNAL(checkForUpdates()),
+          this, SLOT(checkForUpdatesWithUi()));
+
+  /* The rest of these slots are called as the update process executes. */
+  connect(&_updateProcess, SIGNAL(downloadProgress(QString,int,int)),
+          &_updateProgressDialog, SLOT(setDownloadProgress(QString,int,int)));
+  connect(&_updateProcess, SIGNAL(updatesAvailable(UpdateProcess::BundleInfo,PackageList)),
+          this, SLOT(updatesAvailable(UpdateProcess::BundleInfo,PackageList)));
+  connect(&_updateProcess, SIGNAL(updatesInstalled(int)),
+          this, SLOT(updatesInstalled(int)));
+  connect(&_updateProcess, SIGNAL(installUpdatesFailed(QString)),
+          this, SLOT(installUpdatesFailed(QString)));
+  connect(&_updateProgressDialog, SIGNAL(cancelUpdate()),
+          &_updateProcess, SLOT(cancel()));
+#endif
+
+#if defined(USE_MINIUPNPC)
+  /* Catch UPnP-related signals */
+  connect(UPNPControl::instance(), SIGNAL(error(UPNPControl::UPNPError)),
+         this, SLOT(upnpError(UPNPControl::UPNPError)));
+#endif
+
+  ui.chkShowOnStartup->setChecked(settings.showMainWindowAtStart());
+  if (ui.chkShowOnStartup->isChecked())
+    show();
+  /* Optimistically hope that the tray icon gets added. */
+  _trayIcon.show();
+
+#if defined(Q_WS_MAC)
+  /* Display OSX dock icon if icon preference is not set to "Tray Only" */
+  if (settings.getIconPref() != VidaliaSettings::Tray) {
+      ProcessSerialNumber psn = { 0, kCurrentProcess };
+      TransformProcessType(&psn, kProcessTransformToForegroundApplication);
+  }
+  /* Vidalia launched in background (LSUIElement=true). Bring to foreground. */
+  VidaliaWindow::setVisible(settings.showMainWindowAtStart());
+#endif
+
+  _flashToggle = false;
+}
+
+/** Destructor. */
+MainWindow::~MainWindow()
+{
+  _trayIcon.hide();
+  delete _messageLog;
+  delete _bandwidthGraph;
+  delete _netViewer;
+  delete _configDialog;
+}
+
+void
+MainWindow::setVisible(bool visible)
+{
+  if (visible) {
+    /* In Gnome, will hide buttons if Vidalia is run on startup. */
+    if (!QSystemTrayIcon::isSystemTrayAvailable()) {
+      /* Don't let people hide the main window, since that's all they have. */
+      ui.chkShowOnStartup->hide();
+      ui.btnHide->hide();
+      /* Causes window to not appear in Enlightenment. */
+      //setMinimumHeight(height()-ui.btnHide->height());
+      //setMaximumHeight(height()-ui.btnHide->height());
+    }
+  }
+  VidaliaWindow::setVisible(visible);
+}
+
+void
+MainWindow::retranslateUi()
+{
+  ui.retranslateUi(this);
+
+  updateTorStatus(_status);
+  if (_status == Stopped) {
+    _actionStartStopTor->setText(tr("Start Tor"));
+    ui.lblStartStopTor->setText(tr("Start Tor"));
+  } else if (_status == Starting) {
+    _actionStartStopTor->setText(tr("Starting Tor"));
+    ui.lblStartStopTor->setText(tr("Starting Tor"));
+  } else {
+    _actionStartStopTor->setText(tr("Stop Tor"));
+    ui.lblStartStopTor->setText(tr("Stop Tor"));
+  }
+
+  _actionShowBandwidth->setText(tr("Bandwidth Graph"));
+  _actionShowMessageLog->setText(tr("Message Log"));
+  _actionShowNetworkMap->setText(tr("Network Map"));
+  _actionShowControlPanel->setText(tr("Control Panel"));
+  _actionShowHelp->setText(tr("Help"));
+  _actionNewIdentity->setText(tr("New Identity"));
+
+#if !defined(Q_WS_MAC)
+  _actionShowAbout->setText(tr("About"));
+  _actionShowConfig->setText(tr("Settings"));
+  _actionExit->setText(tr("Exit"));
+#else
+  createMenuBar();
+#endif
+}
+
+/** Called when the application has started and the main event loop is
+ * running. */
+void
+MainWindow::running()
+{
+  VidaliaSettings settings;
+
+  if (vApp->readPasswordFromStdin()) {
+    QTextStream in(stdin);
+    in >> _controlPassword;
+    _useSavedPassword = false;
+  } else {
+    /* Initialize _useSavedPassword to true. If Tor is already running when
+     * Vidalia starts, then there is no point in generating a random password.
+     * If Tor is not already running, then this will be set according to the
+     * current configuration in the start() method.
+     */
+    _useSavedPassword = true;
+  }
+
+  if (settings.runTorAtStart()) {
+    /* If we're supposed to start Tor when Vidalia starts, then do it now */
+    start();
+  }
+
+  /* Start the proxy server, if configured */
+  if (settings.runProxyAtStart())
+    startProxy();
+
+#if defined(USE_AUTOUPDATE)
+  if (settings.isAutoUpdateEnabled()) {
+    QDateTime lastCheckedAt = settings.lastCheckedForUpdates();
+    if (UpdateProcess::shouldCheckForUpdates(lastCheckedAt)) {
+      if (settings.runTorAtStart() && ! _torControl->isCircuitEstablished()) {
+        /* We started Tor but it hasn't bootstrapped yet, so give it a bit
+         * before we decide to check for updates. If Tor manages to build a
+         * circuit before this timer times out, we will stop the timer and
+         * launch a check for updates immediately. (see circuitEstablished()).
+         */
+        _updateTimer.start(5*60*1000);
+      } else {
+        /* Initiate a background check for updates now */
+        checkForUpdates();
+      }
+    } else {
+      /* Schedule the next time to check for updates */
+      QDateTime nextCheckAt = UpdateProcess::nextCheckForUpdates(lastCheckedAt);
+      QDateTime now = QDateTime::currentDateTime().toUTC();
+
+      vInfo("Last checked for software updates at %1. Will check again at %2.")
+        .arg(lastCheckedAt.toLocalTime().toString("dd-MM-yyyy hh:mm:ss"))
+        .arg(nextCheckAt.toLocalTime().toString("dd-MM-yyyy hh:mm:ss"));
+      _updateTimer.start((nextCheckAt.toTime_t() - now.toTime_t()) * 1000);
+    }
+  }
+#endif
+}
+
+/** Terminate the Tor process if it is being run under Vidalia, disconnect all
+ * TorControl signals, and exit Vidalia. */
+void
+MainWindow::aboutToQuit()
+{
+  vNotice("Cleaning up before exiting.");
+
+  if (_torControl->isVidaliaRunningTor()) {
+    /* Kill our Tor process now */
+    _torControl->stop();
+  }
+
+  /* Disable port forwarding */
+  ServerSettings settings(_torControl);
+  settings.cleanupPortForwarding();
+
+  if (_proxyProcess->state() != QProcess::NotRunning) {
+    /* Close the proxy server (Polipo ignores the WM_CLOSE event sent by
+     * terminate() so we have to kill() it) */
+    _proxyProcess->kill();
+  }
+
+  /* Kill the browser and IM client if using the new launcher */
+  VidaliaSettings vidalia_settings;
+
+  if (! vidalia_settings.getBrowserDirectory().isEmpty()) {
+    /* Disconnect the finished signals so that we won't try to exit Vidalia again */
+    QObject::disconnect(_browserProcess, SIGNAL(finished(int, QProcess::ExitStatus)), 0, 0);
+    QObject::disconnect(_imProcess, SIGNAL(finished(int, QProcess::ExitStatus)), 0, 0);
+
+    /* Use QProcess terminate function */
+    if (_browserProcess->state() == QProcess::Running)
+      _browserProcess->terminate();
+
+#if defined(Q_OS_WIN)
+    /* Kill any processes which might have been forked off */
+    win32_end_process_by_filename(vidalia_settings.getBrowserExecutable());
+#endif
+
+    if (_imProcess->state() == QProcess::Running)
+      _imProcess->terminate();
+  }
+
+  /* Disconnect all of the TorControl object's signals */
+  QObject::disconnect(_torControl, 0, 0, 0);
+}
+
+/** Called when the application is closing, by selecting "Exit" from the tray
+ * menu. If we're running a Tor server, then ask if we want to kill Tor now,
+ * or do a delayed shutdown. */
+void
+MainWindow::close()
+{
+  if (_torControl->isVidaliaRunningTor()) {
+    /* If we're running a server currently, ask if we want to do a delayed
+     * shutdown. If we do, then close Vidalia only when Tor stops. Otherwise,
+     * kill Tor and bail now. */
+    ServerSettings settings(_torControl);
+    if (_torControl->isConnected() && settings.isServerEnabled()) {
+      connect(_torControl, SIGNAL(stopped()), vApp, SLOT(quit()));
+      if (!stop())
+        QObject::disconnect(_torControl, SIGNAL(stopped()), vApp, SLOT(quit()));
+      return;
+    }
+  }
+  vApp->quit();
+}
+
+/** Create and bind actions to events. Setup for initial
+ * tray menu configuration. */
+void
+MainWindow::createActions()
+{
+  _actionStartStopTor = new QAction(tr("Start Tor"), this);
+  connect(_actionStartStopTor, SIGNAL(triggered()), this, SLOT(start()));
+
+  _actionExit = new QAction(tr("Exit"), this);
+  connect(_actionExit, SIGNAL(triggered()), this, SLOT(close()));
+
+  _actionShowBandwidth = new QAction(tr("Bandwidth Graph"), this);
+  connect(_actionShowBandwidth, SIGNAL(triggered()),
+          _bandwidthGraph, SLOT(showWindow()));
+  connect(ui.lblBandwidthGraph, SIGNAL(clicked()),
+          _bandwidthGraph, SLOT(showWindow()));
+
+  _actionShowMessageLog = new QAction(tr("Message Log"), this);
+  connect(_actionShowMessageLog, SIGNAL(triggered()),
+          _messageLog, SLOT(showWindow()));
+  connect(ui.lblMessageLog, SIGNAL(clicked()),
+          _messageLog, SLOT(showWindow()));
+  connect(ui.lblMessageLog, SIGNAL(clicked()),
+          _warnTimer, SLOT(stop()));
+  connect(ui.lblMessageLog, SIGNAL(clicked()),
+          ui.lblMessageLog, SLOT(disableFlashing()));
+
+  _actionShowNetworkMap = new QAction(tr("Network Map"), this);
+  connect(_actionShowNetworkMap, SIGNAL(triggered()),
+          _netViewer, SLOT(showWindow()));
+  connect(ui.lblViewNetwork, SIGNAL(clicked()),
+          _netViewer, SLOT(showWindow()));
+
+  _actionShowControlPanel = new QAction(tr("Control Panel"), this);
+  connect(_actionShowControlPanel, SIGNAL(triggered()), this, SLOT(show()));
+
+  _actionShowConfig = new QAction(tr("Settings"), this);
+  connect(_actionShowConfig, SIGNAL(triggered()), this, SLOT(showConfigDialog()));
+
+  _actionShowAbout = new QAction(tr("About"), this);
+  connect(_actionShowAbout, SIGNAL(triggered()), this, SLOT(showAboutDialog()));
+
+  _actionShowHelp = new QAction(tr("Help"), this);
+  connect(_actionShowHelp, SIGNAL(triggered()), this, SLOT(showHelpDialog()));
+  connect(ui.lblHelpBrowser, SIGNAL(clicked()), this, SLOT(showHelpDialog()));
+
+  _actionNewIdentity = new QAction(tr("New Identity"), this);
+  _actionNewIdentity->setEnabled(false);
+  connect(_actionNewIdentity, SIGNAL(triggered()), this, SLOT(newIdentity()));
+
+#if !defined(Q_WS_MAC)
+  /* Don't give the menu items icons on OS X, since they end up in the
+   * application menu bar. Menu bar items on OS X typically do not have
+   * icons. */
+  _actionStartStopTor->setIcon(QIcon(IMG_START_TOR_16));
+  _actionExit->setIcon(QIcon(IMG_EXIT));
+  _actionShowBandwidth->setIcon(QIcon(IMG_BWGRAPH));
+  _actionShowMessageLog->setIcon(QIcon(IMG_MESSAGELOG));
+  _actionShowNetworkMap->setIcon(QIcon(IMG_NETWORK));
+  _actionShowControlPanel->setIcon(QIcon(IMG_CONTROL_PANEL));
+  _actionShowConfig->setIcon(QIcon(IMG_CONFIG));
+  _actionShowAbout->setIcon(QIcon(IMG_ABOUT));
+  _actionShowHelp->setIcon(QIcon(IMG_HELP));
+  _actionNewIdentity->setIcon(QIcon(IMG_IDENTITY));
+#endif
+}
+
+/** Creates a tray icon with a context menu and adds it to the system
+ * notification area. On Mac, we also set up an application menubar. */
+void
+MainWindow::createTrayIcon()
+{
+  QMenu *menu = createTrayMenu();
+
+  /* Add the menu it to the tray icon */
+  _trayIcon.setContextMenu(menu);
+
+  connect(&_trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)),
+          this, SLOT(trayIconActivated(QSystemTrayIcon::ActivationReason)));
+
+#if defined(Q_WS_MAC)
+  createMenuBar();
+  qt_mac_set_dock_menu(menu);
+#endif
+}
+
+/** Creates a QMenu object that contains QActions which compose the system
+ * tray menu. */
+QMenu*
+MainWindow::createTrayMenu()
+{
+  QMenu *menu = new QMenu(this);
+  menu->addAction(_actionStartStopTor);
+  menu->addSeparator();
+  menu->addAction(_actionShowBandwidth);
+  menu->addAction(_actionShowMessageLog);
+  menu->addAction(_actionShowNetworkMap);
+  menu->addAction(_actionNewIdentity);
+  menu->addSeparator();
+  menu->addAction(_actionShowControlPanel);
+
+#if !defined(Q_WS_MAC)
+  /* These aren't added to the dock menu on Mac, since they are in the
+   * standard Mac locations in the menu bar. */
+  menu->addAction(_actionShowConfig);
+  menu->addAction(_actionShowHelp);
+  menu->addAction(_actionShowAbout);
+  menu->addSeparator();
+  menu->addAction(_actionExit);
+#endif
+  return menu;
+}
+
+/** Creates a new menubar with no parent, so Qt will use this as the "default
+ * menubar" on Mac. This adds on to the existing actions from the createMens()
+ * method. */
+void
+MainWindow::createMenuBar()
+{
+#if defined(Q_WS_MAC)
+  /* Mac users sure like their shortcuts. Actions NOT mentioned below
+   * don't explicitly need shortcuts, since they are merged to the default
+   * menubar and get the default shortcuts anyway. */
+  _actionStartStopTor->setShortcut(tr("Ctrl+T"));
+  _actionShowBandwidth->setShortcut(tr("Ctrl+B"));
+  _actionShowMessageLog->setShortcut(tr("Ctrl+L"));
+  _actionShowNetworkMap->setShortcut(tr("Ctrl+N"));
+  _actionShowHelp->setShortcut(tr("Ctrl+?"));
+  _actionNewIdentity->setShortcut(tr("Ctrl+I"));
+  _actionShowControlPanel->setShortcut(tr("Ctrl+P"));
+
+  /* Force Qt to put merge the Exit, Configure, and About menubar options into
+   * the default menu, even if Vidalia is currently not speaking English. */
+  _actionShowConfig->setText("config");
+  _actionShowConfig->setMenuRole(QAction::PreferencesRole);
+  _actionShowAbout->setText("about");
+  _actionShowAbout->setMenuRole(QAction::AboutRole);
+  _actionExit->setText("quit");
+  _actionExit->setMenuRole(QAction::QuitRole);
+
+  /* The File, Help, and Configure menus will get merged into the application
+   * menu by Qt. */
+  if (_menuBar)
+    delete _menuBar;
+  _menuBar = new QMenuBar(0);
+  QMenu *fileMenu = _menuBar->addMenu("File");
+  fileMenu->addAction(_actionExit);
+  fileMenu->addAction(_actionShowConfig);
+
+  QMenu *torMenu = _menuBar->addMenu(tr("Tor"));
+  torMenu->addAction(_actionStartStopTor);
+  torMenu->addSeparator();
+  torMenu->addAction(_actionNewIdentity);
+
+  QMenu *viewMenu = _menuBar->addMenu(tr("View"));
+  viewMenu->addAction(_actionShowControlPanel);
+  viewMenu->addSeparator();
+  viewMenu->addAction(_actionShowBandwidth);
+  viewMenu->addAction(_actionShowMessageLog);
+  viewMenu->addAction(_actionShowNetworkMap);
+
+  QMenu *helpMenu = _menuBar->addMenu(tr("Help"));
+  _actionShowHelp->setText(tr("Vidalia Help"));
+  helpMenu->addAction(_actionShowHelp);
+  helpMenu->addAction(_actionShowAbout);
+#endif
+}
+
+/** Sets the current tray or dock icon image to <b>iconFile</b>. */
+void
+MainWindow::setTrayIcon(const QString &iconFile)
+{
+#if defined(Q_WS_MAC)
+  VidaliaSettings settings;
+  QApplication::setWindowIcon(QPixmap(iconFile));
+  /* only display tray icon if icon preference is not set to "Dock Only" */
+  if (settings.getIconPref() != VidaliaSettings::Dock)
+    _trayIcon.setIcon(QIcon(iconFile));
+#else
+  /* always display tray icon for other platforms */
+  _trayIcon.setIcon(QIcon(iconFile));
+#endif
+}
+
+/** Respond to a double-click on the tray icon by opening the Control Panel
+ * window. */
+void
+MainWindow::trayIconActivated(QSystemTrayIcon::ActivationReason reason)
+{
+  if (reason == QSystemTrayIcon::DoubleClick)
+    setVisible(true);
+}
+
+/** Start a web browser when given the directory containing the executable and profile */
+void
+MainWindow::launchBrowserFromDirectory()
+{
+  VidaliaSettings settings;
+
+  /** Directory for the browser */
+  QString browserDirectory = settings.getBrowserDirectory();
+  if(QDir(browserDirectory).isRelative())
+    browserDirectory = QDir(QDir::toNativeSeparators(QCoreApplication::applicationDirPath()
+                                                     + "/" + browserDirectory)).canonicalPath();
+
+  /** Relative path to the browser executable from the browserDirectory */
+  QString browserExecutable = QDir::toNativeSeparators(browserDirectory + "/" + settings.getBrowserExecutable());
+
+  /** Relative path to profile from the browserDirectory */
+  QString profileDirectory = QDir::toNativeSeparators(settings.getProfileDirectory());
+  /** Default profile to copy from */
+  QString defaultProfileDirectory = QDir::toNativeSeparators(settings.getDefaultProfileDirectory());
+
+  /** Relative path to the plugins directory from the browserDirectory */
+  QString pluginsDirectory = QDir::toNativeSeparators(settings.getPluginsDirectory());
+  /** Relative path to the default plugins directory from the browserDirectory */
+  QString defaultPluginsDirectory = QDir::toNativeSeparators(settings.getDefaultPluginsDirectory());
+
+  QString profileDir = QDir(browserDirectory + "/" + profileDirectory).canonicalPath();
+
+  _browserProcess->setEnvironment(updateBrowserEnv());
+
+  QDir browserDirObj = QDir(browserDirectory);
+
+  /* Copy the profile directory if it's not already there */
+  if (!browserDirObj.exists(profileDirectory)) {
+    browserDirObj.mkdir(profileDirectory);
+    copy_dir(QDir(browserDirectory + "/" + defaultProfileDirectory).canonicalPath(),
+             QDir(browserDirectory + "/" + profileDirectory).canonicalPath());
+  }
+
+  /* Copy the pluginss directory if it's not already there */
+  if (!browserDirObj.exists(pluginsDirectory)) {
+    browserDirObj.mkdir(pluginsDirectory);
+    copy_dir(QDir(browserDirectory + "/" + defaultPluginsDirectory).canonicalPath(),
+             QDir(browserDirectory + "/" + pluginsDirectory).canonicalPath());
+  }
+
+  /* Build the command line arguments */
+  QStringList commandLine;
+  // Is this better or worse than MOZ_NO_REMOTE?
+  commandLine << "-no-remote";
+  commandLine << "-profile";
+  commandLine << profileDir;
+
+  /* Launch the browser */
+  if(!_browserProcess->state() != QProcess::NotRunning)
+    _browserProcess->start(browserExecutable, commandLine);
+  _browserProcess->toForeground();
+}
+
+/** Starts the web browser and IM client, if appropriately configured */
+void
+MainWindow::startSubprocesses()
+{
+  VidaliaSettings settings;
+  QString subprocess;
+
+  /* Launch the web browser */
+  if (!(subprocess = settings.getBrowserDirectory()).isEmpty()) {
+    /* The user has set BrowserDirectory; use this */
+    launchBrowserFromDirectory();
+  } else if (!(subprocess = settings.getBrowserExecutable()).isEmpty()) {
+    /* BrowserDirectory is not set, but BrowserExecutable is; use this */
+    _browserProcess->setEnvironment(updateBrowserEnv());
+    if(!_browserProcess->state() != QProcess::NotRunning)
+      _browserProcess->start(subprocess, QStringList());
+    _browserProcess->toForeground();
+  }
+
+  /* Launch the IM client */
+  subprocess = settings.getIMExecutable();
+
+  if (!subprocess.isEmpty())
+    _imProcess->start(subprocess, QStringList());
+}
+
+/** Called when browser or IM client have exited */
+void
+MainWindow::onSubprocessFinished(int exitCode, QProcess::ExitStatus exitStatus)
+{
+  Q_UNUSED(exitCode)
+  Q_UNUSED(exitStatus)
+
+  /* Get path to browser and IM client */
+  VidaliaSettings settings;
+  QString browserExecutable = settings.getBrowserExecutable();
+  QString browserDirectory = settings.getBrowserDirectory();
+  QString imExecutable = settings.getIMExecutable();
+
+  /* A subprocess is finished if it successfully exited or was never asked to start */
+  bool browserDone = (browserExecutable.isEmpty()
+                        && browserDirectory.isEmpty())
+                        || _browserProcess->isDone();
+  bool imDone = imExecutable.isEmpty() || _imProcess->isDone();
+
+  /* Exit if both subprocesses are finished */
+  if (browserDone && imDone) {
+    if (browserDirectory.isEmpty()) {
+      /* We are using the standard launcher, exit immediately */
+      vApp->quit();
+    } else {
+      /* We are using the alternate launcher, wait until the browser has really died */
+      QTimer *browserWatcher = new QTimer(this);
+      connect(browserWatcher, SIGNAL(timeout()), this, SLOT(onCheckForBrowser()));
+      browserWatcher->start(2000);
+    }
+  }
+}
+
+/** Called periodically to check if the browser is running. If it is not,
+ * exit Vidalia cleanly */
+void
+MainWindow::onCheckForBrowser()
+{
+/* This only works on Windows for now */
+#if defined(Q_OS_WIN)
+
+  VidaliaSettings settings;
+  QString browserDirectoryFilename = settings.getBrowserExecutable();
+
+  /* Get list of running processes */
+  QHash<qint64, QString> procList = win32_process_list();
+
+  /* On old versions of Windows win32_process_list() will return
+     an empty list. In this case, just keep Vidalia open */
+  if (procList.isEmpty()) {
+    return;
+  }
+
+  /* Loop over all processes or until we find <browserDirectoryFilename> */
+  QHashIterator<qint64, QString> i(procList);
+  while (i.hasNext()) {
+    i.next();
+    if (i.value().toLower() == browserDirectoryFilename) {
+      /* The browser is still running, so Vidalia should keep running too */
+      return;
+    }
+  }
+
+  /* The browser isn't running, exit Vidalia */
+  vApp->quit();
+#endif
+}
+
+/** Called when the web browser failed to start, for example, because the path
+ * specified to the web browser executable didn't lead to an executable. */
+void
+MainWindow::onBrowserFailed(QString errmsg)
+{
+  Q_UNUSED(errmsg);
+
+  /* Display an error message and see if the user wants some help */
+  VMessageBox::warning(this, tr("Error starting web browser"),
+              tr("Vidalia was unable to start the configured web browser"),
+              VMessageBox::Ok|VMessageBox::Default|VMessageBox::Escape);
+}
+
+/** Called when the IM client failed to start, for example, because the path
+ * specified to the IM client executable didn't lead to an executable. */
+void
+MainWindow::onIMFailed(QString errmsg)
+{
+  Q_UNUSED(errmsg);
+
+  /* Display an error message and see if the user wants some help */
+  VMessageBox::warning(this, tr("Error starting IM client"),
+              tr("Vidalia was unable to start the configured IM client"),
+              VMessageBox::Ok|VMessageBox::Default|VMessageBox::Escape);
+}
+
+/** Starts the proxy server, if appropriately configured */
+void
+MainWindow::startProxy()
+{
+  VidaliaSettings settings;
+  QString executable = settings.getProxyExecutable();
+  _proxyProcess->start(executable, settings.getProxyExecutableArguments());
+}
+
+/** Called when the proxy server fails to start, for example, because
+ * the path specified didn't lead to an executable. */
+void
+MainWindow::onProxyFailed(QString errmsg)
+{
+  Q_UNUSED(errmsg);
+
+  /* Display an error message and see if the user wants some help */
+  VMessageBox::warning(this, tr("Error starting proxy server"),
+              tr("Vidalia was unable to start the configured proxy server"),
+              VMessageBox::Ok|VMessageBox::Default|VMessageBox::Escape);
+}
+
+/** Called when Tor's bootstrapping status changes. <b>bse</b> represents
+ * Tor's current estimate of its bootstrapping progress. */
+void
+MainWindow::bootstrapStatusChanged(const BootstrapStatus &bs)
+{
+  int percentComplete = STARTUP_PROGRESS_BOOTSTRAPPING + bs.percentComplete();
+  bool warn = (bs.severity() == tc::WarnSeverity &&
+               bs.recommendedAction() != BootstrapStatus::RecommendIgnore);
+
+  QString description;
+  switch (bs.status()) {
+    case BootstrapStatus::ConnectingToDirMirror:
+      description = tr("Connecting to a relay directory");
+      break;
+    case BootstrapStatus::HandshakingWithDirMirror:
+    case BootstrapStatus::CreatingOneHopCircuit:
+      description = tr("Establishing an encrypted directory connection");
+      break;
+    case BootstrapStatus::RequestingNetworkStatus:
+      description = tr("Retrieving network status");
+      break;
+    case BootstrapStatus::LoadingNetworkStatus:
+      description = tr("Loading network status");
+      break;
+    case BootstrapStatus::LoadingAuthorityCertificates:
+      description = tr("Loading authority certificates");
+      break;
+    case BootstrapStatus::RequestingDescriptors:
+      description = tr("Requesting relay information");
+      break;
+    case BootstrapStatus::LoadingDescriptors:
+      description = tr("Loading relay information");
+      break;
+    case BootstrapStatus::ConnectingToEntryGuard:
+      description = tr("Connecting to the Tor network");
+      break;
+    case BootstrapStatus::HandshakingWithEntryGuard:
+    case BootstrapStatus::EstablishingCircuit:
+      description = tr("Establishing a Tor circuit");
+      break;
+    case BootstrapStatus::BootstrappingDone:
+      description = tr("Connected to the Tor network!");
+      warn = false; /* probably false anyway */
+      break;
+    default:
+      description = bs.description();
+  }
+  if (warn) {
+    QString reason;
+    /* Is it really a good idea to translate these? */
+    switch (bs.reason()) {
+      case tc::MiscellaneousReason:
+        reason = tr("miscellaneous");
+        break;
+      case tc::IdentityMismatch:
+        reason = tr("identity mismatch");
+        break;
+      case tc::ConnectionDone:
+        reason = tr("done");
+        break;
+      case tc::ConnectionRefused:
+        reason = tr("connection refused");
+        break;
+      case tc::ConnectionTimeout:
+        reason = tr("connection timeout");
+        break;
+      case tc::ConnectionIoError:
+        reason = tr("read/write error");
+        break;
+      case tc::NoRouteToHost:
+        reason = tr("no route to host");
+        break;
+      case tc::ResourceLimitReached:
+        reason = tr("insufficient resources");
+        break;
+      default:
+        reason = tr("unknown");
+    }
+    description += tr(" failed (%1)").arg(reason);
+  }
+  setStartupProgress(percentComplete, description);
+}
+
+/** Updates the UI to reflect Tor's current <b>status</b>. Returns the
+ * previously set TorStatus value.*/
+MainWindow::TorStatus
+MainWindow::updateTorStatus(TorStatus status)
+{
+  QString statusText, actionText;
+  QString trayIconFile, statusIconFile;
+  TorStatus prevStatus = _status;
+
+  vNotice("Tor status changed from '%1' to '%2'.")
+    .arg(toString(prevStatus)).arg(toString(status));
+  _status = status;
+
+  if (status == Stopped) {
+      statusText = tr("Tor is not running");
+      actionText = tr("Start Tor");
+      trayIconFile = IMG_TOR_STOPPED;
+      statusIconFile = IMG_TOR_STOPPED_48;
+      _actionStartStopTor->setEnabled(true);
+      _actionStartStopTor->setText(actionText);
+      _actionStartStopTor->setIcon(QIcon(IMG_START_TOR_16));
+      ui.lblStartStopTor->setEnabled(true);
+      ui.lblStartStopTor->setText(actionText);
+      ui.lblStartStopTor->setPixmap(QPixmap(IMG_START_TOR_48));
+      ui.lblStartStopTor->setStatusTip(actionText);
+
+      /* XXX: This might need to be smarter if we ever start connecting other
+       * slots to these triggered() and clicked() signals. */
+      QObject::disconnect(_actionStartStopTor, SIGNAL(triggered()), this, 0);
+      QObject::disconnect(ui.lblStartStopTor, SIGNAL(clicked()), this, 0);
+      connect(_actionStartStopTor, SIGNAL(triggered()), this, SLOT(start()));
+      connect(ui.lblStartStopTor, SIGNAL(clicked()), this, SLOT(start()));
+      setStartupProgressVisible(false);
+  } else if (status == Stopping) {
+      if (_delayedShutdownStarted) {
+        statusText = tr("Your relay is shutting down.\n"
+                        "Click 'Stop' again to stop your relay now.");
+      } else {
+        statusText = tr("Tor is shutting down");
+      }
+      trayIconFile = IMG_TOR_STOPPING;
+      statusIconFile = IMG_TOR_STOPPING_48;
+
+      ui.lblStartStopTor->setStatusTip(tr("Stop Tor Now"));
+  } else if (status == Started) {
+      actionText = tr("Stop Tor");
+      _actionStartStopTor->setEnabled(true);
+      _actionStartStopTor->setText(actionText);
+      _actionStartStopTor->setIcon(QIcon(IMG_STOP_TOR_16));
+      ui.lblStartStopTor->setEnabled(true);
+      ui.lblStartStopTor->setText(actionText);
+      ui.lblStartStopTor->setPixmap(QPixmap(IMG_STOP_TOR_48));
+      ui.lblStartStopTor->setStatusTip(actionText);
+
+      /* XXX: This might need to be smarter if we ever start connecting other
+       * slots to these triggered() and clicked() signals. */
+      QObject::disconnect(_actionStartStopTor, SIGNAL(triggered()), this, 0);
+      QObject::disconnect(ui.lblStartStopTor, SIGNAL(clicked()), this, 0);
+      connect(_actionStartStopTor, SIGNAL(triggered()), this, SLOT(stop()));
+      connect(ui.lblStartStopTor, SIGNAL(clicked()), this, SLOT(stop()));
+  } else if (status == Starting)  {
+      statusText = tr("Starting the Tor software");
+      trayIconFile = IMG_TOR_STARTING;
+      statusIconFile = IMG_TOR_STARTING_48;
+      _actionStartStopTor->setEnabled(false);
+      ui.lblStartStopTor->setText(tr("Starting Tor"));
+      ui.lblStartStopTor->setEnabled(false);
+      ui.lblStartStopTor->setStatusTip(statusText);
+      setStartupProgressVisible(true);
+      setStartupProgress(STARTUP_PROGRESS_STARTING, statusText);
+  } else if (status == CircuitEstablished) {
+      statusText = tr("Connected to the Tor network!");
+      trayIconFile = IMG_TOR_RUNNING;
+      statusIconFile = IMG_TOR_RUNNING_48;
+      setStartupProgressVisible(false);
+  }
+
+  /* Update the tray icon */
+  if (!trayIconFile.isEmpty()) {
+    setTrayIcon(trayIconFile);
+  }
+  /* Update the status banner on the control panel */
+  if (!statusIconFile.isEmpty())
+    ui.lblTorStatusImg->setPixmap(QPixmap(statusIconFile));
+  if (!statusText.isEmpty()) {
+    _trayIcon.setToolTip(statusText);
+    ui.lblTorStatus->setText(statusText);
+  }
+  return prevStatus;
+}
+
+/** Called when the "show on startup" checkbox is toggled. */
+void
+MainWindow::toggleShowOnStartup(bool checked)
+{
+  VidaliaSettings settings;
+  settings.setShowMainWindowAtStart(checked);
+}
+
+/** Sets the visibility of the startup status description and progress bar to
+ * <b>visible</b>. */
+void
+MainWindow::setStartupProgressVisible(bool visible)
+{
+  /* XXX: We force a repaint() to make sure the progress bar and onion status
+   * icon don't overlap briefly. This is pretty hacktastic. */
+  if (visible) {
+    ui.lblTorStatus->setVisible(false);
+    ui.lblTorStatusImg->setVisible(false);
+    repaint(ui.grpStatus->rect());
+    ui.lblStartupProgress->setVisible(true);
+    ui.progressBar->setVisible(true);
+  } else {
+    ui.lblStartupProgress->setVisible(false);
+    ui.progressBar->setVisible(false);
+    repaint(ui.grpStatus->rect());
+    ui.lblTorStatus->setVisible(true);
+    ui.lblTorStatusImg->setVisible(true);
+  }
+}
+
+/** Sets the progress bar completion value to <b>progressValue</b> and sets
+ * the status text to <b>description</b>. */
+void
+MainWindow::setStartupProgress(int progressValue,
+                               const QString &description)
+{
+  ui.progressBar->setValue(progressValue);
+  ui.lblStartupProgress->setText(description);
+  _trayIcon.setToolTip(description);
+}
+
+/** Attempts to start Tor. If Tor fails to start, then startFailed() will be
+ * called with an error message containing the reason. */
+void
+MainWindow::start()
+{
+  TorSettings settings;
+  QStringList args;
+
+  updateTorStatus(Starting);
+
+  // Disable autoconfiguration if there are missing config data
+  if(settings.autoControlPort()) {
+    if(settings.getDataDirectory().isEmpty()) {
+      vWarn("Disabling ControlPort autoconfiguration. DataDirectory is empty!");
+      settings.setAutoControlPort(false);
+    }
+  }
+
+  /* Check if Tor is already running separately */
+  if(settings.getControlMethod() == ControlMethod::Port) {
+    if(!settings.autoControlPort() && net_test_connect(settings.getControlAddress(),
+                                                       settings.getControlPort())) {
+      started();
+      return;
+    }
+  } else {
+    if (socket_test_connect(settings.getSocketPath())) {
+      started();
+      return;
+    }
+  }
+
+  QString torrc = settings.getTorrc();
+  QFileInfo torrcInfo(torrc);
+
+  if(QDir(torrcInfo.filePath()).isRelative()) {
+    torrc = QCoreApplication::applicationDirPath() + "/" + torrc;
+
+    QFileInfo newTorrcInfo(torrc);
+    if(!newTorrcInfo.exists() and torrcInfo.exists()) {
+      torrc = QDir(QCoreApplication::applicationDirPath()).relativeFilePath(torrcInfo.absoluteFilePath());
+      vWarn("Automigrating configuration for Torrc:\nOld path: %1\nNew path: %2")
+        .arg(newTorrcInfo.filePath())
+        .arg(torrc);
+      settings.setTorrc(torrc);
+      torrc = QCoreApplication::applicationDirPath() + "/" + torrc;
+    }
+  }
+
+  if(settings.bootstrap()) {
+    QString boottorrc = settings.bootstrapFrom();
+    vNotice(tr("Bootstrapping torrc from %1 to %2")
+        .arg(boottorrc).arg(torrc));
+    if(QFileInfo(boottorrc).exists()) {
+      if(QFile::copy(boottorrc, torrc)) {
+        settings.setBootstrap(false);
+      }
+    }
+  }
+
+  /* Make sure the torrc we want to use really exists. */
+  if (!torrc.isEmpty()) {
+    if (!QFileInfo(torrc).exists())
+      touch_file(torrc, true);
+    args << "-f" << torrc;
+  }
+
+  /* Specify Tor's data directory, if different from the default */
+  QString dataDirectory = settings.getDataDirectory();
+  QFileInfo dataDirectoryInfo(dataDirectory);
+
+  if(not dataDirectory.isEmpty() and QDir(dataDirectory).isRelative()) {
+    dataDirectory = QCoreApplication::applicationDirPath() + "/" + dataDirectory;
+
+    QFileInfo newDataDirectoryInfo(dataDirectory);
+    if(!newDataDirectoryInfo.exists() and dataDirectoryInfo.exists()) {
+      dataDirectory = QDir(QCoreApplication::applicationDirPath()).relativeFilePath(dataDirectoryInfo.absoluteFilePath());
+      vWarn("Automigrating configuration for DataDirectory:\nOld path: %1\nNew path: %2")
+        .arg(newDataDirectoryInfo.absoluteFilePath())
+        .arg(dataDirectory);
+      settings.setDataDirectory(dataDirectory);
+      dataDirectory = QCoreApplication::applicationDirPath() + "/" + dataDirectory;
+    }
+  }
+
+  QString expDataDirectory = QDir(expand_filename(dataDirectory)).canonicalPath();
+  if (!dataDirectory.isEmpty())
+    args << "DataDirectory" << expDataDirectory;
+
+  if(settings.getControlMethod() == ControlMethod::Port) {
+    if(settings.autoControlPort()) {
+      QString dataDirectory = settings.getDataDirectory();
+      if(QDir(dataDirectory).isRelative())
+        dataDirectory = QCoreApplication::applicationDirPath() + "/" + dataDirectory;
+
+      QString relativePortConf = QDir(QDir::currentPath())
+        .relativeFilePath(QString("%1/port.conf").arg(dataDirectory));
+
+#if defined(Q_WS_WIN)
+      QString torPath = settings.getExecutable();
+      if(QDir(torPath).isRelative())
+        torPath = QCoreApplication::applicationDirPath() + "/" + torPath;
+      relativePortConf = QDir(torPath).relativeFilePath(QString("%1/port.conf").arg(dataDirectory));
+#endif
+      QString portconf = QString("%1/port.conf").arg(expDataDirectory);
+      if(!QFile::remove(portconf))
+        vWarn(QString("Unable to remove %1, may be it didn't existed.").arg(portconf));
+
+      args << "ControlPort" << "auto";
+      args << "SocksPort" << "auto";
+      args << "ControlPortWriteToFile" << relativePortConf;
+    } else {
+      /* Add the intended control port value */
+      quint16 controlPort = settings.getControlPort();
+      if (controlPort)
+        args << "ControlPort" << QString::number(controlPort);
+    }
+  } else {
+    QString path = settings.getSocketPath();
+    args << "ControlSocket" << path;
+  }
+
+  args << "__OwningControllerProcess" << QString::number(QCoreApplication::applicationPid());
+
+  /* Add the control port authentication arguments */
+  switch (settings.getAuthenticationMethod()) {
+    case TorSettings::PasswordAuth:
+      if (! vApp->readPasswordFromStdin()) {
+        if (settings.useRandomPassword()) {
+          _controlPassword = TorSettings::randomPassword();
+          _useSavedPassword = false;
+        } else {
+          _controlPassword = settings.getControlPassword();
+          _useSavedPassword = true;
+        }
+      }
+      args << "HashedControlPassword"
+           << TorSettings::hashPassword(_controlPassword);
+      break;
+    case TorSettings::CookieAuth:
+      args << "CookieAuthentication"  << "1";
+      break;
+    default:
+      args << "CookieAuthentication"  << "0";
+  }
+
+  /* This doesn't get set to false until Tor is actually up and running, so we
+   * don't yell at users twice if their Tor doesn't even start, due to the fact
+   * that QProcess::stopped() is emitted even if the process didn't even
+   * start. */
+  _isIntentionalExit = true;
+  /* Kick off the Tor process */
+  QString torExecutable = settings.getExecutable();
+  QFileInfo torExecutableInfo(torExecutable);
+
+  if(QDir(torExecutableInfo.filePath()).isRelative()) {
+    torExecutable = QCoreApplication::applicationDirPath() + "/" + torExecutable;
+
+    QFileInfo newTorExecutableInfo(torExecutable);
+    if(!newTorExecutableInfo.exists() and torExecutableInfo.exists()) {
+      torExecutable = QDir(QCoreApplication::applicationDirPath()).relativeFilePath(torExecutableInfo.absoluteFilePath());
+      vWarn("Automigrating configuration for TorExecutable:\nOld path: %1\nNew path: %2")
+        .arg(newTorExecutableInfo.filePath())
+        .arg(torExecutable);
+      settings.setExecutable(torExecutable);
+      torExecutable = QCoreApplication::applicationDirPath() + "/" + torExecutable;
+    }
+  }
+
+  _torControl->start(torExecutable, args);
+}
+
+/** Called when the user changes a setting that needs Tor restarting */
+void
+MainWindow::restart()
+{
+  if(_torControl->stop()) {
+    start();
+  }
+}
+
+/** Called when the Tor process fails to start, for example, because the path
+ * specified to the Tor executable didn't lead to an executable. */
+void
+MainWindow::startFailed(QString errmsg)
+{
+  /* We don't display the error message for now, because the error message
+   * that Qt gives us in this instance is almost always "Unknown Error". That
+   * will make users sad. */
+  Q_UNUSED(errmsg);
+
+  updateTorStatus(Stopped);
+
+  /* Display an error message and see if the user wants some help */
+  int response = VMessageBox::warning(this, tr("Error Starting Tor"),
+                   tr("Vidalia was unable to start Tor. Check your settings "
+                        "to ensure the correct name and location of your Tor "
+                        "executable is specified."),
+                   VMessageBox::ShowSettings|VMessageBox::Default,
+                   VMessageBox::Cancel|VMessageBox::Escape,
+                   VMessageBox::Help);
+
+  if (response == VMessageBox::ShowSettings) {
+    /* Show the settings dialog so the user can make sure they're pointing to
+     * the correct Tor. */
+     showConfigDialog();
+  } else if (response == VMessageBox::Help) {
+    /* Show troubleshooting information about starting Tor */
+    showHelpDialog("troubleshooting.start");
+  }
+}
+
+/** Slot: Called when the Tor process is started. It will connect the control
+ * socket and set the icons and tooltips accordingly. */
+void
+MainWindow::started()
+{
+  TorSettings settings;
+
+  updateTorStatus(Started);
+
+  /* Now that Tor is running, we want to know if it dies when we didn't want
+   * it to. */
+  _isIntentionalExit = false;
+  /* We haven't started a delayed shutdown yet. */
+  _delayedShutdownStarted = false;
+  /* Remember whether we started Tor or not */
+  _isVidaliaRunningTor = _torControl->isVidaliaRunningTor();
+  /* Try to connect to Tor's control port */
+  if(settings.autoControlPort()) {
+    QString dataDirectory = settings.getDataDirectory();
+    if(QDir(dataDirectory).isRelative())
+      dataDirectory = QCoreApplication::applicationDirPath() + "/" + dataDirectory;
+
+    QFile file(QString("%1/port.conf").arg(QDir(expand_filename(dataDirectory)).canonicalPath()));
+    int tries = 0, maxtries = 5;
+    while((!file.open(QIODevice::ReadOnly | QIODevice::Text)) and
+          (tries++ < maxtries)) {
+      vWarn(QString("This is try number: %1.").arg(tries));
+#if defined(Q_WS_WIN)
+      Sleep(1000);
+#else
+      sleep(1);
+#endif
+    }
+
+    if(tries >= maxtries) {
+      vWarn("Couldn't read port.conf file");
+      if(_torControl->isRunning()) {
+        connectFailed(tr("Vidalia can't find out how to talk to Tor because it can't access this file: %1\n\nHere's the last error message:\n%2")
+                      .arg(file.fileName())
+                      .arg(file.errorString()));
+      } else {
+        vWarn("Tor isn't running!");
+        connectFailed(tr("It seems Tor has stopped running since Vidalia started it.\n\nSee the Advanced Message Log for more information."));
+      }
+
+      return;
+    }
+
+    QTextStream in(&file);
+    if(!in.atEnd()) {
+      QString line = in.readLine();
+      QStringList parts = line.split("=");
+      if(parts.size() != 2) return;
+      if(parts[0].trimmed() != "PORT") return;
+
+      QStringList addrPort = parts[1].split(":");
+      if(addrPort.size() != 2) return;
+
+      QHostAddress addr(addrPort.at(0));
+      _autoControlPort = addrPort.at(1).toInt();
+      _torControl->connect(addr, _autoControlPort);
+    }
+
+    file.close();
+  } else {
+    /* Try to connect to Tor's control port */
+    if(settings.getControlMethod() == ControlMethod::Port) {
+      _torControl->connect(settings.getControlAddress(),
+                          settings.getControlPort());
+      _autoControlPort = settings.getControlPort();
+    } else
+      _torControl->connect(settings.getSocketPath());
+  }
+  setStartupProgress(STARTUP_PROGRESS_CONNECTING, tr("Connecting to Tor"));
+}
+
+/** Called when the connection to the control socket fails. The reason will be
+ * given in the errmsg parameter. */
+void
+MainWindow::connectFailed(QString errmsg)
+{
+  /* Ok, ok. It really isn't going to connect. I give up. */
+  int response = VMessageBox::warning(this,
+                   tr("Connection Error"), p(errmsg),
+                   VMessageBox::Ok|VMessageBox::Default|VMessageBox::Escape,
+                   VMessageBox::Retry, VMessageBox::Help);
+
+
+  if (response == VMessageBox::Retry) {
+    /* Let's give it another try. */
+    TorSettings settings;
+    _torControl->connect(settings.getControlAddress(),
+                         settings.getControlPort());
+  } else {
+    /* Show the help browser (if requested) */
+    if (response == VMessageBox::Help)
+      showHelpDialog("troubleshooting.connect");
+    /* Since Vidalia can't connect, we can't really do much, so stop Tor. */
+    _torControl->stop();
+  }
+}
+
+/** Disconnects the control socket and stops the Tor process. */
+bool
+MainWindow::stop()
+{
+  ServerSettings server(_torControl);
+  QString errmsg;
+  TorStatus prevStatus;
+  bool rc;
+
+  /* If we're running a server, give users the option of terminating
+   * gracefully so clients have time to find new servers. */
+  if (server.isServerEnabled() && !_delayedShutdownStarted) {
+    /* Ask the user if they want to shutdown nicely. */
+    int response = VMessageBox::question(this, tr("Relaying is Enabled"),
+                     tr("You are currently running a relay. "
+                        "Terminating your relay will interrupt any "
+                        "open connections from clients.\n\n"
+                        "Would you like to shutdown gracefully and "
+                        "give clients time to find a new relay?"),
+                        VMessageBox::Yes|VMessageBox::Default,
+                        VMessageBox::No,
+                        VMessageBox::Cancel|VMessageBox::Escape);
+    if (response == VMessageBox::Yes)
+      _delayedShutdownStarted = true;
+    else if (response == VMessageBox::Cancel)
+      return false;
+  }
+
+  prevStatus = updateTorStatus(Stopping);
+  if (_delayedShutdownStarted) {
+    /* Start a delayed shutdown */
+    rc = _torControl->signal(TorSignal::Shutdown, &errmsg);
+  } else {
+    /* We want Tor to stop now, regardless of whether we're a server. */
+    _isIntentionalExit = true;
+    rc = _torControl->stop(&errmsg);
+  }
+
+  if (!rc) {
+    /* We couldn't tell Tor to stop, for some reason. */
+    int response = VMessageBox::warning(this, tr("Error Shutting Down"),
+                     p(tr("Vidalia was unable to stop the Tor software."))
+                       + p(errmsg),
+                     VMessageBox::Ok|VMessageBox::Default|VMessageBox::Escape,
+                     VMessageBox::Help);
+
+    if (response == VMessageBox::Help) {
+      /* Show some troubleshooting help */
+      showHelpDialog("troubleshooting.stop");
+    }
+    /* Tor is still running since stopping failed */
+    _isIntentionalExit = false;
+    _delayedShutdownStarted = false;
+    updateTorStatus(prevStatus);
+  }
+  return rc;
+}
+
+/** Slot: Called when the Tor process has exited. It will adjust the tray
+ * icons and tooltips accordingly. */
+void
+MainWindow::stopped(int exitCode, QProcess::ExitStatus exitStatus)
+{
+  updateTorStatus(Stopped);
+
+  /* If we didn't intentionally close Tor, then check to see if it crashed or
+   * if it closed itself and returned an error code. */
+  if (!_isIntentionalExit) {
+    /* A quick overview of Tor's code tells me that if it catches a SIGTERM or
+     * SIGINT, Tor will exit(0). We might need to change this warning message
+     * if this turns out to not be the case. */
+    if (exitStatus == QProcess::CrashExit || exitCode != 0) {
+      int ret = VMessageBox::warning(this, tr("Unexpected Error"),
+                  tr("Vidalia detected that the Tor software exited "
+                     "unexpectedly.\n\n"
+                     "Please check the message log for recent "
+                     "warning or error messages."),
+                  VMessageBox::Ok|VMessageBox::Escape,
+                  VMessageBox::ShowLog|VMessageBox::Default,
+                  VMessageBox::Help);
+      if (ret == VMessageBox::ShowLog)
+        _messageLog->showWindow();
+      else if (ret == VMessageBox::Help)
+        showHelpDialog("troubleshooting.torexited");
+    }
+  }
+}
+
+/** Called when the control socket has successfully connected to Tor. */
+void
+MainWindow::connected()
+{
+  authenticate();
+  if(_torControl->isVidaliaRunningTor()) {
+    QString err;
+    if(!_torControl->takeOwnership(&err))
+      vWarn(err);
+  }
+}
+
+/** Called when Vidalia wants to disconnect from a Tor it did not start. */
+void
+MainWindow::disconnect()
+{
+  _torControl->disconnect();
+}
+
+/** Called when the control socket has been disconnected. */
+void
+MainWindow::disconnected()
+{
+  if (!_isVidaliaRunningTor) {
+    /* If we didn't start our own Tor process, interpret losing the control
+     * connection as "Tor is stopped". */
+    updateTorStatus(Stopped);
+  }
+
+  /*XXX We should warn here if we get disconnected when we didn't intend to */
+  _actionNewIdentity->setEnabled(false);
+  ui.lblNewIdentity->setEnabled(false);
+  _isVidaliaRunningTor = false;
+}
+
+/** Attempts to authenticate to Tor's control port, depending on the
+ * authentication method specified in TorSettings::getAuthenticationMethod().
+ */
+bool
+MainWindow::authenticate()
+{
+  TorSettings::AuthenticationMethod authMethod;
+  TorSettings settings;
+  ProtocolInfo pi;
+
+  updateTorStatus(Authenticating);
+  setStartupProgress(STARTUP_PROGRESS_AUTHENTICATING,
+                     tr("Authenticating to Tor"));
+
+  authMethod = settings.getAuthenticationMethod();
+  pi = _torControl->protocolInfo();
+  if (!pi.isEmpty()) {
+    QStringList authMethods = pi.authMethods();
+    if (authMethods.contains("COOKIE"))
+      authMethod = TorSettings::CookieAuth;
+    else if (authMethods.contains("HASHEDPASSWORD"))
+      authMethod = TorSettings::PasswordAuth;
+    else if (authMethods.contains("NULL"))
+      authMethod = TorSettings::NullAuth;
+  }
+
+  if (authMethod == TorSettings::CookieAuth) {
+    /* Try to load an auth cookie and send it to Tor */
+    QByteArray cookie = loadControlCookie(pi.cookieAuthFile());
+    while (cookie.isEmpty()) {
+      /* Prompt the user to find their control_auth_cookie */
+      int ret = VMessageBox::question(this,
+                  tr("Cookie Authentication Required"),
+                  p(tr("The Tor software requires Vidalia to send the "
+                       "contents of an authentication cookie, but Vidalia "
+                       "was unable to find one."))
+                  + p(tr("Would you like to browse for the file "
+                         "'control_auth_cookie' yourself?")),
+                VMessageBox::Browse|VMessageBox::Default,
+                VMessageBox::Cancel|VMessageBox::Escape);
+
+      if (ret == VMessageBox::Cancel)
+        goto cancel;
+      QString cookieDir = QFileDialog::getOpenFileName(this,
+                            tr("Data Directory"),
+                            settings.getDataDirectory(),
+                            tr("Control Cookie (control_auth_cookie)"));
+      if (cookieDir.isEmpty())
+        goto cancel;
+      cookieDir = QFileInfo(cookieDir).absolutePath();
+      cookie = loadControlCookie(cookieDir);
+    }
+    if(cookie.size() != 32) {
+      vWarn(QString("Cookie length has to be exactly 32 bytes long. Found %1 bytes")
+            .arg(cookie.size()));
+      goto cancel;
+    }
+    vNotice("Authenticating using 'cookie' authentication.");
+    return _torControl->authenticate(cookie);
+  } else if (authMethod == TorSettings::PasswordAuth) {
+    /* Get the control password and send it to Tor */
+    vNotice("Authenticating using 'hashed password' authentication.");
+    if (_useSavedPassword) {
+      TorSettings settings;
+      _controlPassword = settings.getControlPassword();
+    }
+    return _torControl->authenticate(_controlPassword);
+  }
+  /* No authentication. Send an empty password. */
+  vNotice("Authenticating using 'null' authentication.");
+  return _torControl->authenticate(QString(""));
+
+cancel:
+  vWarn("Cancelling control authentication attempt.");
+  if (_isVidaliaRunningTor)
+    stop();
+  else
+    disconnect();
+  return false;
+}
+
+/** Called when Vidalia has successfully authenticated to Tor. */
+void
+MainWindow::authenticated()
+{
+  ServerSettings serverSettings(_torControl);
+  QString errmsg;
+
+  updateTorStatus(Authenticated);
+
+  /* If Tor doesn't have bootstrapping events, then update the current
+   * status string and bump the progress bar along a bit. */
+  if (_torControl->getTorVersion() < 0x020101) {
+    setStartupProgress(STARTUP_PROGRESS_CIRCUITBUILD,
+                       tr("Connecting to the Tor network"));
+  }
+
+  /* Let people click on their beloved "New Identity" button */
+  _actionNewIdentity->setEnabled(true);
+  ui.lblNewIdentity->setEnabled(true);
+
+  /* Register for any pertinent asynchronous events. */
+  if (!_torControl->setEvents(&errmsg)) {
+    VMessageBox::warning(this, tr("Error Registering for Events"),
+      p(tr("Vidalia was unable to register for some events. "
+           "Many of Vidalia's features may be unavailable."))
+         + p(errmsg),
+      VMessageBox::Ok);
+  } else {
+    /* Stop reading from Tor's stdout immediately, since we successfully
+     * registered for Tor events, including any desired log events. */
+    _torControl->closeTorStdout();
+  }
+
+  /* Configure UPnP port forwarding if needed */
+  serverSettings.configurePortForwarding();
+
+  /* Check if Tor has a circuit established */
+  if (_torControl->isCircuitEstablished())
+    circuitEstablished();
+  /* Check the status of Tor's version */
+  if (_torControl->getTorVersion() >= 0x020001)
+    checkTorVersion();
+  if (_torControl->getTorVersion() >= 0x020102) {
+    BootstrapStatus status = _torControl->bootstrapStatus();
+    if (status.isValid())
+      bootstrapStatusChanged(status);
+  }
+}
+
+/** Called when Vidalia fails to authenticate to Tor. The failure reason is
+ * specified in <b>errmsg</b>. */
+void
+MainWindow::authenticationFailed(QString errmsg)
+{
+  bool retry = false;
+
+  vWarn("Authentication failed: %1").arg(errmsg);
+
+  /* Parsing log messages is evil, but we're left with little option */
+  if (errmsg.contains("Password did not match")) {
+    ControlPasswordInputDialog dlg;
+    connect(&dlg, SIGNAL(helpRequested(QString)),
+            this, SLOT(showHelpDialog(QString)));
+
+    qint64 torPid = 0;
+
+#if defined(Q_OS_WIN32)
+    QHash<qint64, QString> procs = process_list();
+    foreach (qint64 pid, procs.keys()) {
+      if (! procs.value(pid).compare("tor.exe", Qt::CaseInsensitive)) {
+        torPid = pid;
+        break;
+      }
+    }
+    dlg.setResetEnabled(torPid > 0);
+#else
+    dlg.setResetEnabled(false);
+#endif
+
+    int ret = dlg.exec();
+    if (ret == QDialogButtonBox::Ok) {
+      if (dlg.isSavePasswordChecked()) {
+        TorSettings settings;
+        settings.setAuthenticationMethod(TorSettings::PasswordAuth);
+        settings.setUseRandomPassword(false);
+        settings.setControlPassword(dlg.password());
+        _useSavedPassword = true;
+      } else {
+        _controlPassword = dlg.password();
+        _useSavedPassword = false;
+      }
+      retry = true;
+    } else if (ret == QDialogButtonBox::Reset) {
+      if (! process_kill(torPid)) {
+        VMessageBox::warning(this,
+          tr("Password Reset Failed"),
+          p(tr("Vidalia tried to reset Tor's control password, but was not "
+               "able to restart the Tor software. Please check your Task "
+               "Manager to ensure there are no other Tor processes running.")),
+               VMessageBox::Ok|VMessageBox::Default);
+      } else {
+        retry = true;
+      }
+    }
+  } else {
+    /* Something else went wrong */
+    int ret = VMessageBox::warning(this,
+                tr("Authentication Error"),
+                p(tr("Vidalia was unable to authenticate to the Tor software. "
+                     "(%1)").arg(errmsg)) +
+                p(tr("Please check your control port authentication "
+                     "settings.")),
+                VMessageBox::ShowSettings|VMessageBox::Default,
+                VMessageBox::Cancel|VMessageBox::Escape);
+
+    if (ret == VMessageBox::ShowSettings)
+      showConfigDialog(ConfigDialog::Advanced);
+  }
+
+  if (_torControl->isRunning())
+    if (_isVidaliaRunningTor)
+      stop();
+    else
+      disconnect();
+  if (retry)
+    start();
+}
+
+/** Searches for and attempts to load the control authentication cookie. This
+ * assumes the cookie is named 'control_auth_cookie'. If <b>cookiePath</b> is
+ * empty, this method will search some default locations depending on the
+ * current platform. <b>cookiePath</b> can point to either a cookie file or a
+ * directory containing the cookie file. */
+QByteArray
+MainWindow::loadControlCookie(QString cookiePath)
+{
+  QFile authCookie;
+  QStringList pathList;
+
+  if (!cookiePath.isEmpty()) {
+    pathList << cookiePath;
+  } else {
+    /* Try some default locations */
+    TorSettings settings;
+    QString dataDir = settings.getDataDirectory();
+    if (!dataDir.isEmpty())
+      pathList << dataDir;
+
+#if defined(Q_WS_WIN)
+    pathList << expand_filename("%APPDATA%\\Tor");
+#else
+    pathList << expand_filename("~/.tor");
+#endif
+  }
+
+  /* Search for the cookie file */
+  foreach (QString path, pathList) {
+    QString cookieFile = QFileInfo(path).isFile() ?
+                          path : path + "/control_auth_cookie";
+    vDebug("Checking for authentication cookie in '%1'").arg(cookieFile);
+    if (!QFileInfo(cookieFile).exists())
+      continue;
+
+    authCookie.setFileName(cookieFile);
+    if (authCookie.open(QIODevice::ReadOnly)) {
+      vInfo("Reading authentication cookie from '%1'").arg(cookieFile);
+      return authCookie.readAll();
+    } else {
+      vWarn("Couldn't open cookie file '%1': %2")
+        .arg(cookieFile).arg(authCookie.errorString());
+    }
+  }
+  vWarn("Couldn't find a readable authentication cookie.");
+  return QByteArray();
+}
+
+/** Called when Tor has successfully established a circuit. */
+void
+MainWindow::circuitEstablished()
+{
+  updateTorStatus(CircuitEstablished);
+  setStartupProgress(ui.progressBar->maximum(),
+                     tr("Connected to the Tor network!"));
+  startSubprocesses();
+
+#if defined(USE_AUTOUPDATE)
+  VidaliaSettings settings;
+  if (settings.isAutoUpdateEnabled()) {
+    QDateTime lastCheckedAt = settings.lastCheckedForUpdates();
+    if (UpdateProcess::shouldCheckForUpdates(lastCheckedAt)) {
+      /* Initiate a background check for updates now */
+      _updateTimer.stop();
+      checkForUpdates();
+    }
+  }
+#endif
+}
+
+/** Checks the status of the current version of Tor to see if it's old,
+ * unrecommended, or obsolete. */
+void
+MainWindow::checkTorVersion()
+{
+  VidaliaSettings settings;
+  if(settings.skipVersionCheck())
+    return;
+  QString status;
+  if (_torControl->getInfo("status/version/current", status)) {
+    if (!status.compare("old", Qt::CaseInsensitive)
+          || !status.compare("unrecommended", Qt::CaseInsensitive)
+          || !status.compare("obsolete", Qt::CaseInsensitive)) {
+      displayTorVersionWarning();
+    }
+  }
+}
+
+/** Called when Tor thinks its version is old or unrecommended, and displays
+ * a message notifying the user. */
+void
+MainWindow::dangerousTorVersion(tc::TorVersionStatus reason,
+                                const QString &current,
+                                const QStringList &recommended)
+{
+  Q_UNUSED(current);
+  Q_UNUSED(recommended);
+
+  if (reason == tc::ObsoleteTorVersion
+        || reason == tc::UnrecommendedTorVersion)
+    displayTorVersionWarning();
+}
+
+/** Called when Tor thinks its version is old or unrecommended, and displays a
+ * message notifying the user. */
+void
+MainWindow::displayTorVersionWarning()
+{
+  static bool alreadyWarned = false;
+
+  if (!alreadyWarned) {
+#if !defined(USE_AUTOUPDATE)
+    QString website = "https://www.torproject.org/";
+# if QT_VERSION >= 0x040200
+    website = QString("<a href=\"%1\">%1</a>").arg(website);
+# endif
+
+    VMessageBox::information(this, tr("Tor Update Available"),
+      p(tr("The currently installed version of Tor is out of date or no longer "
+           "recommended. Please visit the Tor website to download the latest "
+           "version.")) + p(tr("Tor website: %1").arg(website)),
+      VMessageBox::Ok);
+#else
+    int ret = VMessageBox::information(this,
+                tr("Tor Update Available"),
+                p(tr("The currently installed version of Tor is out of date "
+                     "or no longer recommended."))
+                  + p(tr("Would you like to check if a newer package is "
+                         "available for installation?")),
+                VMessageBox::Yes|VMessageBox::Default,
+                VMessageBox::No|VMessageBox::Escape);
+
+    if (ret == VMessageBox::Yes)
+      checkForUpdatesWithUi();
+#endif
+    alreadyWarned = true;
+  }
+}
+
+/** Called when Tor thinks the user has tried to connect to a port that
+ * typically is used for unencrypted applications. Warns the user and allows
+ * them to ignore future warnings on <b>port</b>. It is possible that Tor
+ * will produce multiple asynchronous status events warning of dangerous ports
+ * while the message box is displayed (for example, while the user is away
+ * from the keyboard), so subsequent messages will be discarded until the
+ * first message box is dismissed. */
+void
+MainWindow::warnDangerousPort(quint16 port, bool rejected)
+{
+  static QMessageBox *dlg = 0;
+
+  /* Don't display another message box until the first one is dismissed */
+  if (dlg)
+    return;
+
+  QString application;
+  switch (port) {
+    case  23:
+     application = tr("(probably Telnet)");
+     break;
+
+    case 109:
+    case 110:
+    case 143:
+      application = tr("(probably an email client)");
+      break;
+
+    default:
+      application = "";
+  }
+
+  QString text = tr("One of your applications %1 appears to be making a "
+                    "potentially unencrypted and unsafe connection to port %2.")
+                    .arg(application).arg(port);
+
+  QString extraText = p(tr("Anything sent over this connection could be "
+                           "monitored. Please check your application's "
+                           "configuration and use only encrypted protocols, "
+                           "such as SSL, if possible."));
+  if (rejected) {
+    extraText.append(p(tr("Tor has automatically closed your connection in "
+                          "order to protect your anonymity.")));
+  }
+
+  dlg = new QMessageBox(QMessageBox::Warning,
+                        tr("Potentially Unsafe Connection"), text,
+                        QMessageBox::Ok | QMessageBox::Ignore);
+  dlg->setInformativeText(extraText);
+  dlg->setDefaultButton(QMessageBox::Ok);
+  dlg->setEscapeButton(QMessageBox::Ok);
+
+  int ret = dlg->exec();
+  if (ret == QMessageBox::Ignore) {
+    TorControl *tc = Vidalia::torControl();
+    TorSettings settings;
+    QStringList portList;
+    QList<quint16> ports;
+    int idx;
+
+    ports = settings.getWarnPlaintextPorts();
+    idx   = ports.indexOf(port);
+    if (idx >= 0) {
+      ports.removeAt(idx);
+      settings.setWarnPlaintextPorts(ports);
+
+      foreach (quint16 port, ports) {
+        portList << QString::number(port);
+      }
+      tc->setConf("WarnPlaintextPorts", portList.join(","));
+      portList.clear();
+    }
+
+    ports = settings.getRejectPlaintextPorts();
+    idx   = ports.indexOf(port);
+    if (idx >= 0) {
+      ports.removeAt(idx);
+      settings.setRejectPlaintextPorts(ports);
+
+      foreach (quint16 port, ports) {
+        portList << QString::number(port);
+      }
+      tc->setConf("RejectPlaintextPorts", portList.join(","));
+    }
+  }
+  delete dlg;
+  dlg = 0;
+}
+
+/** Creates and displays Vidalia's About dialog. */
+void
+MainWindow::showAboutDialog()
+{
+  AboutDialog dlg(this);
+  dlg.exec();
+}
+
+/** Displays the help browser and displays the most recently viewed help
+ * topic. */
+void
+MainWindow::showHelpDialog()
+{
+  showHelpDialog(QString());
+}
+
+/**< Shows the help browser and displays the given help <b>topic</b>. */
+void
+MainWindow::showHelpDialog(const QString &topic)
+{
+  static HelpBrowser *helpBrowser = 0;
+  if (!helpBrowser)
+    helpBrowser = new HelpBrowser(this);
+  helpBrowser->showWindow(topic);
+}
+
+/** Creates and displays the Configuration dialog with the current page set to
+ * <b>page</b>. */
+void
+MainWindow::showConfigDialog(ConfigDialog::Page page)
+{
+  _configDialog->showWindow(page);
+}
+
+/** Displays the Configuration dialog, set to the Server page. */
+void
+MainWindow::showServerConfigDialog()
+{
+  showConfigDialog(ConfigDialog::Server);
+}
+
+/** Called when the user selects the "New Identity" action from the menu. */
+void
+MainWindow::newIdentity()
+{
+  QString errmsg;
+
+  /* Send the NEWNYM signal. If message balloons are supported and the NEWNYM
+   * is successful, we will show the result as a balloon. Otherwise, we'll
+   * just use a message box. */
+  if (_torControl->signal(TorSignal::NewNym, &errmsg)) {
+    /* NEWNYM signal was successful */
+    QString title = tr("New Identity");
+    QString message = tr("All subsequent connections will "
+                         "appear to be different than your "
+                         "old connections.");
+
+    /* Disable the New Identity button for MIN_NEWIDENTITY_INTERVAL */
+    _actionNewIdentity->setEnabled(false);
+    ui.lblNewIdentity->setEnabled(false);
+    QTimer::singleShot(MIN_NEWIDENTITY_INTERVAL,
+                       this, SLOT(enableNewIdentity()));
+
+    if (QSystemTrayIcon::supportsMessages())
+      _trayIcon.showMessage(title, message, QSystemTrayIcon::Information);
+    else
+      VMessageBox::information(this, title, message, VMessageBox::Ok);
+  } else {
+    /* NEWNYM signal failed */
+    VMessageBox::warning(this,
+      tr("Failed to Create New Identity"), errmsg, VMessageBox::Ok);
+  }
+}
+
+/** Re-enables the 'New Identity' button after a delay from the previous time
+ * 'New Identity' was used. */
+void
+MainWindow::enableNewIdentity()
+{
+  if (_torControl->isConnected()) {
+    _actionNewIdentity->setEnabled(true);
+    ui.lblNewIdentity->setEnabled(true);
+  }
+}
+
+/** Converts a TorStatus enum value to a string for debug logging purposes. */
+QString
+MainWindow::toString(TorStatus status)
+{
+  switch (status) {
+    /* These strings only appear in debug logs, so they should not be
+     * translated. */
+    case Unset:     return "Unset";
+    case Stopping:  return "Stopping";
+    case Stopped:   return "Stopped";
+    case Starting:  return "Starting";
+    case Started:   return "Started";
+    case Authenticating:  return "Authenticating";
+    case Authenticated:   return "Authenticated";
+    case CircuitEstablished: return "Circuit Established";
+    default: break;
+  }
+  return "Unknown";
+}
+
+#if defined(USE_MINIUPNPC)
+/** Called when a UPnP error occurs. */
+void
+MainWindow::upnpError(UPNPControl::UPNPError error)
+{
+  Q_UNUSED(error);
+
+#if 0
+  /* XXX: Is there a better way to do this? Currently, this could get called
+   * if there is an error when testing UPnP support, and again when attempting
+   * to reset the UPnP state when the test dialog is closed. The user would
+   * not be amused with all the warning dialogs. */
+
+  VMessageBox::warning(this,
+    tr("Port Forwarding Failed"),
+    p(tr("Vidalia was unable to configure automatic port forwarding."))
+      + p(UPNPControl::Instance()->errorString()),
+    VMessageBox::Ok);
+#endif
+}
+#endif
+
+#if defined(USE_AUTOUPDATE)
+/** Called when the user clicks the 'Check Now' button in the General
+ * settings page. */
+void
+MainWindow::checkForUpdatesWithUi()
+{
+  checkForUpdates(true);
+}
+
+/** Called when the update interval timer expires, notifying Vidalia that
+ * we should check for updates again. */
+void
+MainWindow::checkForUpdates(bool showProgress)
+{
+  VidaliaSettings settings;
+
+  if (_updateProcess.isRunning()) {
+    if (showProgress) {
+      /* A check for updates is already in progress, so just bring the update
+       * progress dialog into focus.
+       */
+      _updateProgressDialog.show();
+    }
+  } else {
+    /* If Tor is running and bootstrapped, then use Tor to check for updates */
+    if (_torControl->isRunning() && _torControl->circuitEstablished())
+      _updateProcess.setSocksPort(_torControl->getSocksPort());
+    else
+      _updateProcess.setSocksPort(0);
+
+    /* Initialize the UpdateProgressDialog and display it, if necessary. */
+    _updateProgressDialog.setStatus(UpdateProgressDialog::CheckingForUpdates);
+    if (showProgress)
+      _updateProgressDialog.show();
+
+    /* Initiate a check for available software updates. This check will
+     * be done in the background, notifying the user only if there are
+     * updates to be installed.
+     */
+    _updateProcess.checkForUpdates(UpdateProcess::TorBundleInfo);
+
+    /* Remember when we last checked for software updates */
+    settings.setLastCheckedForUpdates(QDateTime::currentDateTime().toUTC());
+
+    /* Restart the "Check for Updates" timer */
+    _updateTimer.start(UpdateProcess::checkForUpdatesInterval() * 1000);
+  }
+}
+
+/** Called when the check for software updates fails. */
+void
+MainWindow::checkForUpdatesFailed(const QString &errmsg)
+{
+  if (_updateProgressDialog.isVisible()) {
+    _updateProgressDialog.hide();
+    VMessageBox::warning(this, tr("Update Failed"), errmsg,
+                         VMessageBox::Ok);
+  }
+}
+
+/** Called when there is an update available for installation. */
+void
+MainWindow::updatesAvailable(UpdateProcess::BundleInfo bi,
+                             const PackageList &packageList)
+{
+  vInfo("%1 software update(s) available").arg(packageList.size());
+  if (packageList.size() > 0) {
+    UpdatesAvailableDialog dlg(packageList, &_updateProgressDialog);
+
+    switch (dlg.exec()) {
+      case UpdatesAvailableDialog::InstallUpdatesNow:
+        installUpdates(bi);
+        break;
+
+      default:
+        _updateProgressDialog.hide();
+        break;
+    }
+  } else {
+    if (_updateProgressDialog.isVisible()) {
+      _updateProgressDialog.hide();
+      VMessageBox::information(this, tr("Your software is up to date"),
+                               tr("There are no new Tor software packages "
+                                  "available for your computer at this time."),
+                               VMessageBox::Ok);
+    }
+  }
+}
+
+/** Stops Tor (if necessary), installs any available for <b>bi</b>, and
+ * restarts Tor (if necessary). */
+void
+MainWindow::installUpdates(UpdateProcess::BundleInfo bi)
+{
+  _updateProgressDialog.setStatus(UpdateProgressDialog::InstallingUpdates);
+  _updateProgressDialog.show();
+
+  if (_isVidaliaRunningTor) {
+    _restartTorAfterUpgrade = true;
+    _isIntentionalExit = true;
+    _torControl->stop();
+  } else {
+    _restartTorAfterUpgrade = false;
+  }
+  _updateProcess.installUpdates(bi);
+}
+
+/** Called when all <b>numUpdates</b> software updates have been installed
+ * successfully. */
+void
+MainWindow::updatesInstalled(int numUpdates)
+{
+  _updateProgressDialog.setStatus(UpdateProgressDialog::UpdatesInstalled);
+  _updateProgressDialog.show();
+
+  if (_restartTorAfterUpgrade)
+    start();
+}
+
+/** Called when an update fails to install. <b>errmsg</b> contains details
+ * about the failure. */
+void
+MainWindow::installUpdatesFailed(const QString &errmsg)
+{
+  _updateProgressDialog.hide();
+
+  VMessageBox::warning(this, tr("Installation Failed"),
+                       p(tr("Vidalia was unable to install your software updates."))
+                         + p(tr("The following error occurred:"))
+                         + p(errmsg),
+                       VMessageBox::Ok);
+
+  if (_restartTorAfterUpgrade)
+    start();
+}
+
+#endif
+
+QStringList
+MainWindow::updateBrowserEnv() {
+  TorSettings settings;
+  QStringList env = QProcess::systemEnvironment();
+  env << "TZ=UTC";
+  env << "MOZ_NO_REMOTE=1";
+
+  if(settings.autoControlPort()) {
+    QString errmsg, socks;
+    if(!(_torControl->getInfo("net/listeners/socks", socks, &errmsg))) {
+      vInfo(errmsg);
+      return env;
+    }
+
+    QStringList addrPort = socks.split(":");
+    if(addrPort.size() != 2) return env;
+
+    QHostAddress addr(addrPort.at(0));
+    quint16 port = addrPort.at(1).toInt();
+
+    env << QString("TOR_SOCKS_HOST=%1").arg(addr.toString());
+    env << QString("TOR_SOCKS_PORT=%1").arg(port);
+
+    vInfo(QString("Using automatic ControlPort and SocksPort configuration:\n"
+                  "   ControlPort=%1\n   SocksPort=%2\n   Host=%3\n   Configuration file:%4")
+          .arg(_autoControlPort)
+          .arg(port)
+          .arg(addrPort.at(0))
+          .arg(QString("%1/port.conf").arg(expand_filename(settings.getDataDirectory()))));
+  }
+
+  if(settings.getAuthenticationMethod() == TorSettings::PasswordAuth) {
+    env << QString("TOR_CONTROL_PASSWD=%1").arg(QString(_controlPassword.toAscii().toHex()));
+    env << QString("TOR_CONTROL_PORT=%1").arg(_autoControlPort);
+  }
+
+  return env;
+}
+
+void
+MainWindow::log(tc::Severity type, const QString &message)
+{
+  if(type == tc::WarnSeverity)
+    _warnTimer->start(1000);
+}
+
+void
+MainWindow::warnButton()
+{
+  if(_flashToggle) {
+    ui.lblMessageLog->enableFlashing();
+  } else {
+    ui.lblMessageLog->disableFlashing();
+  }
+
+  _flashToggle = !_flashToggle;
+}
diff -pruN 0.2.21-3/.pc/Adjust-filename-of-the-cookie-authentication-file-to.patch/src/vidalia/MainWindow.h 0.2.21-5/.pc/Adjust-filename-of-the-cookie-authentication-file-to.patch/src/vidalia/MainWindow.h
--- 0.2.21-3/.pc/Adjust-filename-of-the-cookie-authentication-file-to.patch/src/vidalia/MainWindow.h	1970-01-01 00:00:00.000000000 +0000
+++ 0.2.21-5/.pc/Adjust-filename-of-the-cookie-authentication-file-to.patch/src/vidalia/MainWindow.h	2012-11-30 20:07:59.000000000 +0000
@@ -0,0 +1,307 @@
+/*
+**  This file is part of Vidalia, and is subject to the license terms in the
+**  LICENSE file, found in the top level directory of this distribution. If you
+**  did not receive the LICENSE file with this file, you may obtain it from the
+**  Vidalia source package distributed by the Vidalia Project at
+**  http://www.torproject.org/projects/vidalia.html. No part of Vidalia,
+**  including this file, may be copied, modified, propagated, or distributed
+**  except according to the terms described in the LICENSE file.
+*/
+
+/*
+** \file MainWindow.h
+** \brief Main window. Creates tray menu and child windows
+*/
+
+#ifndef _MAINWINDOW_H
+#define _MAINWINDOW_H
+
+#include "config.h"
+#include "ui_MainWindow.h"
+
+#include "VidaliaWindow.h"
+#include "HelperProcess.h"
+#include "AboutDialog.h"
+#include "MessageLog.h"
+#include "BandwidthGraph.h"
+#include "ConfigDialog.h"
+#include "HelpBrowser.h"
+#include "NetViewer.h"
+
+#include "TorControl.h"
+
+#if defined(USE_AUTOUPDATE)
+#include "UpdateProcess.h"
+#include "UpdateProgressDialog.h"
+#endif
+#if defined(USE_MINIUPNPC)
+#include "UPNPControl.h"
+#endif
+
+#include <QMainWindow>
+#include <QTimer>
+#include <QSystemTrayIcon>
+
+class MainWindow : public VidaliaWindow
+{
+  Q_OBJECT
+
+public:
+  /** Default constructor */
+  MainWindow();
+  /** Destructor. */
+  ~MainWindow();
+
+public slots:
+  /** Shows or hides this window. **/
+  virtual void setVisible(bool visible);
+
+protected:
+  /** Called when the user changes the UI translation. */
+  virtual void retranslateUi();
+
+private slots:
+  /** Respond to a double-click on the tray icon by opening the Control Panel
+   * window. */
+  void trayIconActivated(QSystemTrayIcon::ActivationReason reason);
+  /** Displays the help browser and displays the most recently viewed help
+   * topic. */
+  void showHelpDialog();
+  /** Called when a child window requests the given help <b>topic</b>. */
+  void showHelpDialog(const QString &topic);
+  /** Called when the user selects "Start" from the menu. */
+  void start();
+  /** Called when the user changes a setting that needs Tor restarting */
+  void restart();
+  /** Called when the Tor process fails to start. */
+  void startFailed(QString errmsg);
+  /** Called when the Tor process has successfully started. */
+  void started();
+  /** Called when the user selects "Stop" form the menu. */
+  bool stop();
+  /** Called when the Tor process has exited, either expectedly or not. */
+  void stopped(int errorCode, QProcess::ExitStatus exitStatus);
+  /** Called when the control socket has connected to Tor. */
+  void connected();
+  /** Called when the control connection fails. */
+  void connectFailed(QString errmsg);
+  /** Called when Vidalia wants to disconnect from a Tor it did not start. */
+  void disconnect();
+  /** Called when the control socket has been disconnected. */
+  void disconnected();
+  /** Called when Vidalia has successfully authenticated to Tor. */
+  void authenticated();
+  /** Called when Vidalia fails to authenticate to Tor. The failure reason is
+   * specified in <b>errmsg</b>. */
+  void authenticationFailed(QString errmsg);
+  /** Re-enables the 'New Identity' button after a delay from the previous time
+   * 'New Identity' was used. */
+  void enableNewIdentity();
+  /** Called when the user selects the "New Identity" action from the menu. */
+  void newIdentity();
+  /** Called when the user exits Vidalia. */
+  void close();
+  /** Called when the application has started and the main event loop is
+   * running. */
+  void running();
+  /** Terminate the Tor process if it is being run under Vidalia, disconnect
+   * all TorControl signals, and exit Vidalia. */
+  void aboutToQuit();
+  /** Creates and displays Vidalia's About dialog. */
+  void showAboutDialog();
+  /** Creates and displays the Configuration dialog with the current page set
+   * to <b>page</b>. */
+  void showConfigDialog(ConfigDialog::Page page = ConfigDialog::General);
+  /** Displays the Configuration dialog, set to the Server page. */
+  void showServerConfigDialog();
+  /** Called when the "show on startup" checkbox is toggled. */
+  void toggleShowOnStartup(bool checked);
+  /** Called when the web browser or IM client have stopped */
+  void onSubprocessFinished(int exitCode, QProcess::ExitStatus exitStatus);
+  /** Called periodically to check if the browser is running. If it is not,
+   * exit Vidalia cleanly */
+  void onCheckForBrowser();
+  /** Called web the web browser failed to start */
+  void onBrowserFailed(QString errmsg);
+  /** Called web the IM client failed to start */
+  void onIMFailed(QString errmsg);
+  /** Called when the proxy server fails to start */
+  void onProxyFailed(QString errmsg);
+
+  /** Called when Tor has successfully established a circuit. */
+  void circuitEstablished();
+  /** Called when Tor thinks the user has tried to connect to a port that
+   * typically is used for unencrypted applications. Warns the user and allows
+   * them to ignore future warnings on <b>port</b>. */
+  void warnDangerousPort(quint16 port, bool rejected);
+  /** Called when Tor's bootstrapping status changes. <b>bse</b> represents
+   * Tor's current estimate of its bootstrapping progress. */
+  void bootstrapStatusChanged(const BootstrapStatus &bs);
+  /** Called when Tor thinks its version is old or unrecommended, and displays
+   * a message notifying the user. */
+  void dangerousTorVersion(tc::TorVersionStatus reason,
+                           const QString &version,
+                           const QStringList &recommended);
+
+  /** Called when torControl emits logMessage() */
+  void log(tc::Severity type, const QString &message);
+  /** Toggles the color for the Message Log button */
+  void warnButton();
+
+#if defined(USE_AUTOUPDATE)
+  /** Called when the user clicks the 'Check Now' button in the General
+   * settings page. */
+  void checkForUpdatesWithUi();
+  /** Called when the update interval timer expires, notifying Vidalia that
+   * we should check for updates again. */
+  void checkForUpdates(bool showProgress = false);
+  /** Called when the check for software updates fails. */
+  void checkForUpdatesFailed(const QString &errmsg);
+  /** Called when there is an update available for installation. */
+  void updatesAvailable(UpdateProcess::BundleInfo bi,
+                        const PackageList &packageList);
+  /** Stops Tor (if necessary), installs any available for <b>bi</b>, and
+   * restarts Tor (if necessary). */
+  void installUpdates(UpdateProcess::BundleInfo bi);
+  /** Called when all <b>numUpdates</b> software updates have been installed
+   * successfully. */
+  void updatesInstalled(int numUpdates);
+  /** Called when an update fails to install. <b>errmsg</b> contains details
+   * about the failure. */
+  void installUpdatesFailed(const QString &errmsg);
+#endif
+
+#if defined(USE_MINIUPNPC)
+  /** Called when a UPnP error occurs. */
+  void upnpError(UPNPControl::UPNPError error);
+#endif
+
+private:
+  enum TorStatus {
+    Unset,      /**< Tor's status has not yet been set. */
+    Stopping,   /**< Tor is in the process of shutting down. */
+    Stopped,    /**< Tor is not running. */
+    Starting,   /**< Tor is in the process of starting. */
+    Started,    /**< Tor is currently running. */
+    Authenticating, /**< Vidalia is authenticating to Tor. */
+    Authenticated,  /**< Vidalia has authenticated to Tor. */
+    CircuitEstablished /**< Tor has built a circuit. */
+  };
+  /** Create the actions on the tray menu or menubar */
+  void createActions();
+  /** Creates a tray icon with a context menu and adds it to the system
+   * notification area. On Mac, we also set up an application menubar. */
+  void createTrayIcon();
+  /** Create the tray popup menu and it's submenus */
+  QMenu* createTrayMenu();
+  /** Creates a default menubar on Mac */
+  void createMenuBar();
+  /** Sets the current tray or dock icon image to <b>iconFile</b>. */
+  void setTrayIcon(const QString &iconFile);
+  /** Updates the UI to reflect Tor's current <b>status</b>. Returns the
+   * previously set TorStatus value. */
+  TorStatus updateTorStatus(TorStatus status);
+  /** Start a web browser when given the directory containing the executable and profile */
+  void launchBrowserFromDirectory();
+  /** Starts the web browser, if appropriately configured */
+  void startSubprocesses();
+  /** Starts the proxy server, if appropriately configured */
+  void startProxy();
+  /** Converts a TorStatus enum value to a string for debug logging purposes. */
+  QString toString(TorStatus status);
+  /** Authenticates Vidalia to Tor's control port. */
+  bool authenticate();
+  /** Searches for and attempts to load the control authentication cookie.
+   * This assumes the cookie is named 'control_auth_cookie'. If
+   * <b>cookiePath</b> is empty, this method will search some default locations
+   * depending on the current platform. <b>cookiePath</b> can point to either
+   * a cookie file or a directory containing the cookie file. */
+  QByteArray loadControlCookie(QString cookiePath = QString());
+  /** Checks the status of the current version of Tor to see if it's old,
+   * unrecommended, or obsolete. */
+  void checkTorVersion();
+  /** Alerts the user that their current Tor version is either obsolete or
+   * no longer recommended. If Vidalia was built with auto-update support,
+   * they will be given the option to check for available updates. */
+  void displayTorVersionWarning();
+  /** Sets the visibility of the startup status description and progress bar
+   * to <b>visible</b>. */
+  void setStartupProgressVisible(bool visible);
+  /** Sets the progress bar completion value to <b>progressValue</b> and sets
+   * the status text to <b>description</b>. */
+  void setStartupProgress(int percentComplete, const QString &description);
+  /** Adds the needed variables to the environment that the browser will
+   * need */
+  QStringList updateBrowserEnv();
+
+  /** The current status of Tor. */
+  TorStatus _status;
+  /** Used to determine if the Tor process exiting was intentional or not */
+  bool _isIntentionalExit;
+  /** Tracks whether we started a delayed server shutdown. */
+  bool _delayedShutdownStarted;
+  /** Set to true if Vidalia started its own Tor process. */
+  bool _isVidaliaRunningTor;
+  /** A MessageLog object which handles logging Tor messages */
+  MessageLog* _messageLog;
+  /** A BandwidthGraph object which handles monitoring Tor bandwidth usage */
+  BandwidthGraph* _bandwidthGraph;
+  /** A NetViewer object which displays the Tor network graphically */
+  NetViewer* _netViewer;
+  /** A ConfigDialog object which lets the user configure Tor and Vidalia */
+  ConfigDialog* _configDialog;
+  /** A TorControl object that handles communication with Tor */
+  TorControl* _torControl;
+  /** A HelperProcess object that manages the web browser */
+  HelperProcess* _browserProcess;
+  /** A HelperProcess object that manages the IM client */
+  HelperProcess* _imProcess;
+  /** A HelperProcess object that manages the proxy server */
+  HelperProcess* _proxyProcess;
+  /** Remembers the control password between when we start Tor with a hash of
+   * the password and when we need to provide the password itself. */
+  QString _controlPassword;
+  /** Set to true if we should use the control password saved in TorSettings
+   * when authenticating to Tor. */
+  bool _useSavedPassword;
+  /** The Vidalia icon that sits in the tray. */
+  QSystemTrayIcon _trayIcon;
+
+#if defined(USE_AUTOUPDATE)
+  /** Timer used to remind us to check for software updates. */
+  QTimer _updateTimer;
+  /** The auto-update process used to check for and download updates. */
+  UpdateProcess _updateProcess;
+  /** Dialog instance that is be used to show the progress of the auto-update
+   * executable. */
+  UpdateProgressDialog _updateProgressDialog;
+  /** Set to true if Vidalia should restart Tor after a software upgrade. */
+  bool _restartTorAfterUpgrade;
+#endif
+  /** The menubar (Mac OS X only). */
+  QMenuBar *_menuBar;
+
+  /** Defines the actions for the tray menu */
+  QAction* _actionShowControlPanel;
+  QAction* _actionStartStopTor;
+  QAction* _actionShowConfig;
+  QAction* _actionShowAbout;
+  QAction* _actionExit;
+  QAction* _actionShowBandwidth;
+  QAction* _actionShowMessageLog;
+  QAction* _actionShowHelp;
+  QAction* _actionShowNetworkMap;
+  QAction* _actionNewIdentity;
+
+  quint16 _autoControlPort;
+
+  /** Timer and bool used to flash buttons with a different color */
+  QTimer *_warnTimer;
+  bool _flashToggle;
+
+  Ui::MainWindow ui; /**< Qt Designer generated object. */
+};
+
+#endif
+
+
diff -pruN 0.2.21-3/.pc/applied-patches 0.2.21-5/.pc/applied-patches
--- 0.2.21-3/.pc/applied-patches	2014-08-18 16:27:40.667707387 +0000
+++ 0.2.21-5/.pc/applied-patches	2014-08-18 16:27:41.211721869 +0000
@@ -1,2 +1,3 @@
 debians-tor-binary-path.patch
 use-control-socket.patch
+Adjust-filename-of-the-cookie-authentication-file-to.patch
diff -pruN 0.2.21-3/src/vidalia/MainWindow.cpp 0.2.21-5/src/vidalia/MainWindow.cpp
--- 0.2.21-3/src/vidalia/MainWindow.cpp	2012-11-30 20:07:59.000000000 +0000
+++ 0.2.21-5/src/vidalia/MainWindow.cpp	2014-08-18 16:27:41.000000000 +0000
@@ -1500,14 +1500,14 @@ MainWindow::authenticate()
     /* Try to load an auth cookie and send it to Tor */
     QByteArray cookie = loadControlCookie(pi.cookieAuthFile());
     while (cookie.isEmpty()) {
-      /* Prompt the user to find their control_auth_cookie */
+      /* Prompt the user to find their control.authcookie */
       int ret = VMessageBox::question(this,
                   tr("Cookie Authentication Required"),
                   p(tr("The Tor software requires Vidalia to send the "
                        "contents of an authentication cookie, but Vidalia "
                        "was unable to find one."))
                   + p(tr("Would you like to browse for the file "
-                         "'control_auth_cookie' yourself?")),
+                         "'control.authcookie' yourself?")),
                 VMessageBox::Browse|VMessageBox::Default,
                 VMessageBox::Cancel|VMessageBox::Escape);
 
@@ -1516,7 +1516,7 @@ MainWindow::authenticate()
       QString cookieDir = QFileDialog::getOpenFileName(this,
                             tr("Data Directory"),
                             settings.getDataDirectory(),
-                            tr("Control Cookie (control_auth_cookie)"));
+                            tr("Control Cookie (control.authcookie)"));
       if (cookieDir.isEmpty())
         goto cancel;
       cookieDir = QFileInfo(cookieDir).absolutePath();
@@ -1680,7 +1680,7 @@ MainWindow::authenticationFailed(QString
 }
 
 /** Searches for and attempts to load the control authentication cookie. This
- * assumes the cookie is named 'control_auth_cookie'. If <b>cookiePath</b> is
+ * assumes the cookie is named 'control.authcookie'. If <b>cookiePath</b> is
  * empty, this method will search some default locations depending on the
  * current platform. <b>cookiePath</b> can point to either a cookie file or a
  * directory containing the cookie file. */
@@ -1709,7 +1709,7 @@ MainWindow::loadControlCookie(QString co
   /* Search for the cookie file */
   foreach (QString path, pathList) {
     QString cookieFile = QFileInfo(path).isFile() ?
-                          path : path + "/control_auth_cookie";
+                          path : path + "/control.authcookie";
     vDebug("Checking for authentication cookie in '%1'").arg(cookieFile);
     if (!QFileInfo(cookieFile).exists())
       continue;
diff -pruN 0.2.21-3/src/vidalia/MainWindow.h 0.2.21-5/src/vidalia/MainWindow.h
--- 0.2.21-3/src/vidalia/MainWindow.h	2012-11-30 20:07:59.000000000 +0000
+++ 0.2.21-5/src/vidalia/MainWindow.h	2014-08-18 16:27:41.000000000 +0000
@@ -212,7 +212,7 @@ private:
   /** Authenticates Vidalia to Tor's control port. */
   bool authenticate();
   /** Searches for and attempts to load the control authentication cookie.
-   * This assumes the cookie is named 'control_auth_cookie'. If
+   * This assumes the cookie is named 'control.authcookie'. If
    * <b>cookiePath</b> is empty, this method will search some default locations
    * depending on the current platform. <b>cookiePath</b> can point to either
    * a cookie file or a directory containing the cookie file. */
