diff --git a/qupgrade.pro b/qupgrade.pro
new file mode 100644
index 0000000000000000000000000000000000000000..3a827c57c5e4be35899e9b247d34eaf919462baa
--- /dev/null
+++ b/qupgrade.pro
@@ -0,0 +1,253 @@
+# Video streaming application for simple UDP direct byte streaming
+
+
+QT       += svg network
+
+TEMPLATE = app
+TARGET = qupgrade
+
+BASEDIR = .
+
+LANGUAGE = C++
+
+linux-g++|linux-g++-64{
+    debug {
+        TARGETDIR = $${OUT_PWD}/debug
+        BUILDDIR = $${OUT_PWD}/build-debug
+    }
+    release {
+        TARGETDIR = $${OUT_PWD}/release
+        BUILDDIR = $${OUT_PWD}/build-release
+    }
+} else {
+    TARGETDIR = $${OUT_PWD}
+    BUILDDIR = $${OUT_PWD}/build
+}
+
+INCLUDEPATH += . \
+    src \
+    src/ui \
+    src/comm \
+    include/ui \
+    src/apps/qupgrade \
+
+# Input
+
+HEADERS += \
+    src/comm/SerialLink.h \
+    src/comm/LinkInterface.h \
+    src/comm/SerialLinkInterface.h \
+    src/comm/LinkManager.h \
+    src/QGC.h \
+    src/apps/qupgrade/QUpgradeApp.h \
+    src/apps/qupgrade/QUpgradeMainWindow.h \
+    libs/qextserialport/qextserialenumerator.h \
+    src/ui/PX4FirmwareUpgrader.h \
+    src/PX4FirmwareUpgradeWorker.h
+
+SOURCES += \
+    src/comm/SerialLink.cc \
+    src/comm/LinkManager.cc \
+    src/QGC.cc \
+    src/apps/qupgrade/main.cc \
+    src/apps/qupgrade/QUpgradeApp.cc \
+    src/apps/qupgrade/QUpgradeMainWindow.cc \
+    src/ui/PX4FirmwareUpgrader.cc \
+    src/PX4FirmwareUpgradeWorker.cc
+
+FORMS += \
+    src/apps/qupgrade/QUpgradeMainWindow.ui \
+    src/ui/PX4FirmwareUpgrader.ui
+
+RESOURCES = qgroundcontrol.qrc
+
+# Include serial library functions
+DEPENDPATH += . \
+    plugins \
+    libs/thirdParty/qserialport/include \
+    libs/thirdParty/qserialport/include/QtSerialPort \
+    libs/thirdParty/qserialport \
+    libs/qextserialport
+
+INCLUDEPATH += . \
+    libs/thirdParty/qserialport/include \
+    libs/thirdParty/qserialport/include/QtSerialPort \
+    libs/thirdParty/qserialport/src \
+    libs/qextserialport
+
+# Include serial port library (QSerial)
+include(qserialport.pri)
+
+# Serial port detection (ripped-off from qextserialport library)
+macx|macx-g++|macx-g++42::SOURCES += libs/qextserialport/qextserialenumerator_osx.cpp
+linux-g++::SOURCES += libs/qextserialport/qextserialenumerator_unix.cpp
+linux-g++-64::SOURCES += libs/qextserialport/qextserialenumerator_unix.cpp
+win32::SOURCES += libs/qextserialport/qextserialenumerator_win.cpp
+win32-msvc2008|win32-msvc2010::SOURCES += libs/qextserialport/qextserialenumerator_win.cpp
+
+# -------------------------------------------------
+# QGroundControl - Micro Air Vehicle Groundstation
+# Please see our website at <http://qgroundcontrol.org>
+# Maintainer:
+# Lorenz Meier <lm@inf.ethz.ch>
+# (c) 2009-2011 QGroundControl Developers
+# This file is part of the open groundstation project
+# QGroundControl is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+# QGroundControl is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+# You should have received a copy of the GNU General Public License
+# along with QGroundControl. If not, see <http://www.gnu.org/licenses/>.
+# -------------------------------------------------
+
+message(Qt version $$[QT_VERSION])
+message(Using Qt from $$(QTDIR))
+
+# Turn off serial port warnings
+DEFINES += _TTY_NOWARN_
+
+# MAC OS X
+macx|macx-g++42|macx-g++|macx-llvm: {
+
+        CONFIG += x86_64 cocoa phonon
+        CONFIG -= x86
+
+        QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.6
+
+        LIBS += -framework IOKit \
+                -F$$BASEDIR/libs/lib/Frameworks \
+                -framework CoreFoundation \
+                -framework ApplicationServices \
+                -lm
+
+        ICON = $$BASEDIR/files/images/icons/macx.icns
+
+        # For release builds remove support for various Qt debugging macros.
+        CONFIG(release, debug|release) {
+                DEFINES += QT_NO_DEBUG
+        }
+}
+
+# GNU/Linux
+linux-g++|linux-g++-64{
+
+        CONFIG -= console
+
+        release {
+                DEFINES += QT_NO_DEBUG
+        }
+
+        INCLUDEPATH += /usr/include \
+        /usr/local/include
+
+        # For release builds remove support for various Qt debugging macros.
+        CONFIG(release, debug|release) {
+                DEFINES += QT_NO_DEBUG
+        }
+
+        LIBS += \
+                -L/usr/lib \
+                -L/usr/local/lib64 \
+                -lm
+
+        # Validated copy commands
+        !exists($$TARGETDIR){
+                QMAKE_POST_LINK += && mkdir -p $$TARGETDIR
+        }
+        DESTDIR = $$TARGETDIR
+}
+
+linux-g++ {
+        message("Building for GNU/Linux 32bit/i386")
+}
+linux-g++-64 {
+        message("Building for GNU/Linux 64bit/x64 (g++-64)")
+        exists(/usr/local/lib64) {
+                LIBS += -L/usr/local/lib64
+        }
+}
+
+# Windows (32bit), Visual Studio
+win32-msvc2008|win32-msvc2010 {
+
+        win32-msvc2008 {
+                message(Building for Windows Visual Studio 2008 (32bit))
+        }
+        win32-msvc2010 {
+                message(Building for Windows Visual Studio 2010 (32bit))
+        }
+
+        # Specify multi-process compilation within Visual Studio.
+        # (drastically improves compilation times for multi-core computers)
+        QMAKE_CXXFLAGS_DEBUG += -MP
+        QMAKE_CXXFLAGS_RELEASE += -MP
+
+        # For release builds remove support for various Qt debugging macros.
+        CONFIG(release, debug|release) {
+                DEFINES += QT_NO_DEBUG
+        }
+
+        # For debug releases we just want the debugging console.
+        CONFIG(debug, debug|release) {
+                CONFIG += console
+        }
+
+        INCLUDEPATH += $$BASEDIR/libs/lib/msinttypes
+
+        LIBS += -lsetupapi
+
+        RC_FILE = $$BASEDIR/qgroundcontrol.rc
+
+        # Copy dependencies
+        BASEDIR_WIN = $$replace(BASEDIR,"/","\\")
+        TARGETDIR_WIN = $$replace(TARGETDIR,"/","\\")
+
+        CONFIG(debug, debug|release) {
+                # Copy application resources
+                QMAKE_POST_LINK += $$quote(xcopy /D /Y "$$BASEDIR_WIN\\files" "$$TARGETDIR_WIN\\debug\\files" /E /I $$escape_expand(\\n))
+                # Copy Qt DLLs
+                QMAKE_POST_LINK += $$quote(xcopy /D /Y "$$(QTDIR)\\plugins" "$$TARGETDIR_WIN\\debug" /E /I $$escape_expand(\\n))
+                QMAKE_POST_LINK += $$quote(xcopy /D /Y "$$(QTDIR)\\bin\\QtCored4.dll" "$$TARGETDIR_WIN\\debug"$$escape_expand(\\n))
+                QMAKE_POST_LINK += $$quote(xcopy /D /Y "$$(QTDIR)\\bin\\QtGuid4.dll" "$$TARGETDIR_WIN\\debug"$$escape_expand(\\n))
+                QMAKE_POST_LINK += $$quote(xcopy /D /Y "$$(QTDIR)\\bin\\QtMultimediad4.dll" "$$TARGETDIR_WIN\\debug"$$escape_expand(\\n))
+                QMAKE_POST_LINK += $$quote(xcopy /D /Y "$$(QTDIR)\\bin\\QtNetworkd4.dll" "$$TARGETDIR_WIN\\debug"$$escape_expand(\\n))
+                QMAKE_POST_LINK += $$quote(xcopy /D /Y "$$(QTDIR)\\bin\\QtSqld4.dll" "$$TARGETDIR_WIN\\debug"$$escape_expand(\\n))
+                QMAKE_POST_LINK += $$quote(xcopy /D /Y "$$(QTDIR)\\bin\\QtSvgd4.dll" "$$TARGETDIR_WIN\\debug"$$escape_expand(\\n))
+                QMAKE_POST_LINK += $$quote(xcopy /D /Y "$$(QTDIR)\\bin\\QtTestd4.dll" "$$TARGETDIR_WIN\\debug"$$escape_expand(\\n))
+                QMAKE_POST_LINK += $$quote(xcopy /D /Y "$$(QTDIR)\\bin\\QtWebKitd4.dll" "$$TARGETDIR_WIN\\debug"$$escape_expand(\\n))
+                QMAKE_POST_LINK += $$quote(xcopy /D /Y "$$(QTDIR)\\bin\\QtXmld4.dll" "$$TARGETDIR_WIN\\debug"$$escape_expand(\\n))
+                QMAKE_POST_LINK += $$quote(xcopy /D /Y "$$(QTDIR)\\bin\\QtXmlPatternsd4.dll" "$$TARGETDIR_WIN\\debug"$$escape_expand(\\n))
+        }
+
+        CONFIG(release, debug|release) {
+                # Copy application resources
+                QMAKE_POST_LINK += $$quote(xcopy /D /Y "$$BASEDIR_WIN\\files" "$$TARGETDIR_WIN\\release\\files" /E /I $$escape_expand(\\n))
+
+                # Copy Qt DLLs
+                QMAKE_POST_LINK += $$quote(xcopy /D /Y "$$(QTDIR)\\plugins" "$$TARGETDIR_WIN\\release" /E /I $$escape_expand(\\n))
+                QMAKE_POST_LINK += $$quote(xcopy /D /Y "$$(QTDIR)\\bin\\QtCore4.dll" "$$TARGETDIR_WIN\\release"$$escape_expand(\\n))
+                QMAKE_POST_LINK += $$quote(xcopy /D /Y "$$(QTDIR)\\bin\\QtGui4.dll" "$$TARGETDIR_WIN\\release"$$escape_expand(\\n))
+                QMAKE_POST_LINK += $$quote(xcopy /D /Y "$$(QTDIR)\\bin\\QtMultimedia4.dll" "$$TARGETDIR_WIN\\release"$$escape_expand(\\n))
+                QMAKE_POST_LINK += $$quote(xcopy /D /Y "$$(QTDIR)\\bin\\QtNetwork4.dll" "$$TARGETDIR_WIN\\release"$$escape_expand(\\n))
+                QMAKE_POST_LINK += $$quote(xcopy /D /Y "$$(QTDIR)\\bin\\QtOpenGL4.dll" "$$TARGETDIR_WIN\\release"$$escape_expand(\\n))
+                QMAKE_POST_LINK += $$quote(xcopy /D /Y "$$(QTDIR)\\bin\\QtSql4.dll" "$$TARGETDIR_WIN\\release"$$escape_expand(\\n))
+                QMAKE_POST_LINK += $$quote(xcopy /D /Y "$$(QTDIR)\\bin\\QtSvg4.dll" "$$TARGETDIR_WIN\\release"$$escape_expand(\\n))
+                QMAKE_POST_LINK += $$quote(xcopy /D /Y "$$(QTDIR)\\bin\\QtTestd4.dll" "$$TARGETDIR_WIN\\release"$$escape_expand(\\n))
+                QMAKE_POST_LINK += $$quote(xcopy /D /Y "$$(QTDIR)\\bin\\QtWebKit4.dll" "$$TARGETDIR_WIN\\release"$$escape_expand(\\n))
+                QMAKE_POST_LINK += $$quote(xcopy /D /Y "$$(QTDIR)\\bin\\QtXml4.dll" "$$TARGETDIR_WIN\\release"$$escape_expand(\\n))
+                QMAKE_POST_LINK += $$quote(xcopy /D /Y "$$(QTDIR)\\bin\\QtXmlPatterns4.dll" "$$TARGETDIR_WIN\\release"$$escape_expand(\\n))
+                QMAKE_POST_LINK += $$quote(del /F "$$TARGETDIR_WIN\\release\\qupgrade.exp"$$escape_expand(\\n))
+                QMAKE_POST_LINK += $$quote(del /F "$$TARGETDIR_WIN\\release\\qupgrade.lib"$$escape_expand(\\n))
+
+                # Copy Visual Studio DLLs
+                # Note that this is only done for release because the debugging versions of these DLLs cannot be redistributed.
+                # I'm not certain of the path for VS2008, so this only works for VS2010.
+                win32-msvc2010 {
+                        QMAKE_POST_LINK += $$quote(xcopy /D /Y "\"C:\\Program Files \(x86\)\\Microsoft Visual Studio 10.0\\VC\\redist\\x86\\Microsoft.VC100.CRT\\*.dll\""  "$$TARGETDIR_WIN\\release\\"$$escape_expand(\\n))
+                }
+        }
+}
diff --git a/src/PX4FirmwareUpgradeWorker.cc b/src/PX4FirmwareUpgradeWorker.cc
new file mode 100644
index 0000000000000000000000000000000000000000..461b82d7eff7831e5417c6292ef5ae3a016b1597
--- /dev/null
+++ b/src/PX4FirmwareUpgradeWorker.cc
@@ -0,0 +1,137 @@
+#include "PX4FirmwareUpgradeWorker.h"
+
+#include <SerialLink.h>
+#include <QGC.h>
+
+#include <QDebug>
+
+// protocol bytes
+#define INSYNC		0x12
+#define EOC		0x20
+
+// reply bytes
+#define OK		0x10
+#define FAILED		0x11
+#define INVALID		0x13	// rev3+
+
+// command bytes
+#define NOP		0x00	// guaranteed to be discarded by the bootloader
+#define GET_SYNC	0x21
+#define GET_DEVICE	0x22
+#define CHIP_ERASE	0x23
+#define CHIP_VERIFY	0x24	// rev2 only
+#define PROG_MULTI	0x27
+#define READ_MULTI	0x28	// rev2 only
+#define GET_CRC		0x29	// rev3+
+#define REBOOT		0x30
+
+#define INFO_BL_REV	1	// bootloader protocol revision
+#define BL_REV_MIN	2	// minimum supported bootloader protocol
+#define BL_REV_MAX	3	// maximum supported bootloader protocol
+#define INFO_BOARD_ID	2	// board type
+#define INFO_BOARD_REV	3	// board revision
+#define INFO_FLASH_SIZE	4	// max firmware size in bytes
+
+PX4FirmwareUpgradeWorker::PX4FirmwareUpgradeWorker(QObject *parent) :
+    QObject(parent),
+    link(NULL)
+{
+}
+
+PX4FirmwareUpgradeWorker* PX4FirmwareUpgradeWorker::putWorkerInThread(QObject *parent)
+{
+    PX4FirmwareUpgradeWorker *worker = new PX4FirmwareUpgradeWorker;
+    QThread *workerThread = new QThread(parent);
+
+    connect(workerThread, SIGNAL(started()), worker, SLOT(startContinousScan()));
+    connect(workerThread, SIGNAL(finished()), worker, SLOT(deleteLater()));
+    worker->moveToThread(workerThread);
+
+    // Starts an event loop, and emits workerThread->started()
+    workerThread->start();
+}
+
+
+bool PX4FirmwareUpgradeWorker::startContinousScan()
+{
+    while (true) {
+        if (detect()) {
+            break;
+        }
+    }
+
+    return true;
+}
+
+bool PX4FirmwareUpgradeWorker::detect()
+{
+    if (!link)
+    {
+        link = new SerialLink("", 921600);
+        connect(link, SIGNAL(bytesReceived(LinkInterface*,QByteArray)), this, SLOT(receiveBytes(LinkInterface*,QByteArray)));
+    }
+
+    // Get a list of ports
+    QVector<QString>* ports = link->getCurrentPorts();
+
+    // Scan
+    for (int i = 0; i < ports->size(); i++)
+    {
+        // Ignore known wrong link names
+
+        if (ports->at(i).contains("Bluetooth")) {
+            continue;
+        }
+
+        link->setPortName(ports->at(i));
+        // Open port and talk to it
+        link->connect();
+        char buf[2] = { GET_SYNC, EOC };
+        if (!link->isConnected()) {
+            continue;
+        }
+        // Send sync request
+        insync = false;
+        link->writeBytes(buf, 2);
+        // Wait for response
+        QGC::SLEEP::msleep(20);
+
+        if (insync)
+            emit validPortFound(ports->at(i));
+            break;
+    }
+
+    if (insync) {
+        return true;
+    } else {
+        return false;
+    }
+
+    //ui.portName->setCurrentIndex(ui.baudRate->findText(QString("%1").arg(this->link->getPortName())));
+
+    // Set port
+
+    // Load current link config
+
+}
+
+void PX4FirmwareUpgradeWorker::receiveBytes(LinkInterface* link, QByteArray b)
+{
+    for (int position = 0; position < b.size(); position++) {
+        qDebug() << "BYTES";
+        qDebug() << std::hex << (char)(b[position]);
+        if (((const char)b[position]) == INSYNC)
+        {
+            qDebug() << "SYNC";
+            insync = true;
+            emit detectionStatusChanged("Found PX4 board");
+        }
+    }
+
+    printf("\n");
+}
+
+bool PX4FirmwareUpgradeWorker::upgrade(const QString &filename)
+{
+
+}
diff --git a/src/PX4FirmwareUpgradeWorker.h b/src/PX4FirmwareUpgradeWorker.h
new file mode 100644
index 0000000000000000000000000000000000000000..88c1acda3dca866fa968af6c0f7ed11d9abff6af
--- /dev/null
+++ b/src/PX4FirmwareUpgradeWorker.h
@@ -0,0 +1,58 @@
+#ifndef PX4FIRMWAREUPGRADEWORKER_H
+#define PX4FIRMWAREUPGRADEWORKER_H
+
+#include <QObject>
+
+#include <SerialLink.h>
+
+class PX4FirmwareUpgradeWorker : public QObject
+{
+    Q_OBJECT
+public:
+    explicit PX4FirmwareUpgradeWorker(QObject *parent = 0);
+    static PX4FirmwareUpgradeWorker* putWorkerInThread(QObject *parent);
+
+signals:
+    void detectionStatusChanged(const QString& status);
+    void upgradeStatusChanged(const QString& status);
+    void upgradeProgressChanged(int percent);
+    void validPortFound(const QString& portName);
+    
+public slots:
+
+    /**
+     * @brief Continously scan for bootloaders
+     * @return
+     */
+    bool startContinousScan();
+
+    /**
+     * @brief Detect connected PX4 bootloaders
+     *
+     * If a bootloader was found, the link will be opened to this
+     * bootloader and ready for flashing when returning from the call.
+     *
+     * @return true if found on one link, false else
+     */
+    bool detect();
+
+    /**
+     * @brief Upgrade the firmware using the currently connected link
+     * @param filename file name / path of the firmware file
+     * @return true if upgrade succeeds, false else
+     */
+    bool upgrade(const QString &filename);
+
+    /**
+     * @brief Receive bytes from a link
+     * @param link
+     * @param b
+     */
+    void receiveBytes(LinkInterface* link, QByteArray b);
+
+private:
+    SerialLink *link;
+    bool insync;
+};
+
+#endif // PX4FIRMWAREUPGRADEWORKER_H
diff --git a/src/apps/qupgrade/QUpgradeApp.cc b/src/apps/qupgrade/QUpgradeApp.cc
new file mode 100644
index 0000000000000000000000000000000000000000..1ca955b3ac9c4202e8e80a2caf06f847eada1412
--- /dev/null
+++ b/src/apps/qupgrade/QUpgradeApp.cc
@@ -0,0 +1,94 @@
+/*=====================================================================
+
+ QGroundControl Open Source Ground Control Station
+
+ (c) 2009 - 2011 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
+
+ This file is part of the QGROUNDCONTROL project
+
+ QGROUNDCONTROL is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ QGROUNDCONTROL is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.
+
+ ======================================================================*/
+
+/**
+ * @file
+ *   @brief Implementation of main application class
+ *
+ *   @author Lorenz Meier <lm@inf.ethz.ch>
+ *
+ */
+
+
+#include <QFile>
+#include <QFlags>
+#include <QThread>
+#include <QSplashScreen>
+#include <QPixmap>
+#include <QDesktopWidget>
+#include <QPainter>
+#include <QStyleFactory>
+#include <QAction>
+#include <QSettings>
+#include <QFontDatabase>
+#include <QMainWindow>
+
+#include "QUpgradeApp.h"
+#include "QUpgradeMainWindow.h"
+#include "PX4FirmwareUpgradeWorker.h"
+#include "UDPLink.h"
+
+
+/**
+ * @brief Constructor for the main application.
+ *
+ * This constructor initializes and starts the whole application. It takes standard
+ * command-line parameters
+ *
+ * @param argc The number of command-line parameters
+ * @param argv The string array of parameters
+ **/
+
+QUpgradeApp::QUpgradeApp(int &argc, char* argv[]) : QApplication(argc, argv)
+{
+    this->setApplicationName("Q PX4 Firmware Upgrade");
+    this->setApplicationVersion("v. 1.0.0 (Beta)");
+    this->setOrganizationName(QLatin1String("PX4"));
+    this->setOrganizationDomain("http://pixhawk.ethz.ch/px4/");
+
+    QSettings::setDefaultFormat(QSettings::IniFormat);
+    // Exit main application when last window is closed
+    connect(this, SIGNAL(lastWindowClosed()), this, SLOT(quit()));
+
+    // Create main window
+    QUpgradeMainWindow* window = new QUpgradeMainWindow();
+
+    // Get PX4 upgrade widget and instantiate worker thread
+    PX4FirmwareUpgradeWorker* worker = PX4FirmwareUpgradeWorker::putWorkerInThread(this);
+    connect(worker, SIGNAL(detectionStatusChanged(QString)), window->firmwareUpgrader(), SLOT(setDetectionStatusText(QString)));
+    connect(worker, SIGNAL(upgradeStatusChanged(QString)), window->firmwareUpgrader(), SLOT(setFlashStatusText(QString)));
+    connect(worker, SIGNAL(upgradeProgressChanged(int)), window->firmwareUpgrader(), SLOT(setFlashProgress(int)));
+    connect(worker, SIGNAL(validPortFound(QString)), window->firmwareUpgrader(), SLOT(setPortName(QString)));
+
+    window->setWindowTitle(applicationName() + " " + applicationVersion());
+    window->show();
+}
+
+/**
+ * @brief Destructor for the groundstation. It destroys all loaded instances.
+ *
+ **/
+QUpgradeApp::~QUpgradeApp()
+{
+}
+
diff --git a/src/apps/qupgrade/QUpgradeApp.h b/src/apps/qupgrade/QUpgradeApp.h
new file mode 100644
index 0000000000000000000000000000000000000000..b4f72a9c3550ef6d4b56ff58a0981899ee6a4391
--- /dev/null
+++ b/src/apps/qupgrade/QUpgradeApp.h
@@ -0,0 +1,58 @@
+/*=====================================================================
+
+ QGroundControl Open Source Ground Control Station
+
+ (c) 2009 - 2011 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
+
+ This file is part of the QGROUNDCONTROL project
+
+ QGROUNDCONTROL is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ QGROUNDCONTROL is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.
+
+ ======================================================================*/
+
+/**
+ * @file
+ *   @brief Definition of main application class
+ *
+ *   @author Lorenz Meier <lm@inf.ethz.ch>
+ *
+ */
+
+
+#ifndef QUPGRADEAPP_H
+#define QUPGRADEAPP_H
+
+#include <QApplication>
+
+/**
+ * @brief The main application and management class.
+ *
+ * This class is started by the main method and provides
+ * the central management unit of the groundstation application.
+ *
+ **/
+class QUpgradeApp : public QApplication
+{
+    Q_OBJECT
+
+public:
+    QUpgradeApp(int &argc, char* argv[]);
+    ~QUpgradeApp();
+
+protected:
+
+private:
+};
+
+#endif /* QUPGRADEAPP_H */
diff --git a/src/apps/qupgrade/QUpgradeMainWindow.cc b/src/apps/qupgrade/QUpgradeMainWindow.cc
new file mode 100644
index 0000000000000000000000000000000000000000..ad0bb2d186b5b027672e0c715ca637b96c015ed1
--- /dev/null
+++ b/src/apps/qupgrade/QUpgradeMainWindow.cc
@@ -0,0 +1,53 @@
+/*=====================================================================
+
+ QGroundControl Open Source Ground Control Station
+
+ (c) 2009 - 2011 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
+
+ This file is part of the QGROUNDCONTROL project
+
+ QGROUNDCONTROL is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ QGROUNDCONTROL is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.
+
+ ======================================================================*/
+
+/**
+ * @file
+ *   @brief Implementation of main window
+ *
+ *   @author Lorenz Meier
+ *
+ */
+
+#include "QUpgradeMainWindow.h"
+#include "ui_QUpgradeMainWindow.h"
+
+//#include "UDPLink.h"
+#include <QDebug>
+
+QUpgradeMainWindow::QUpgradeMainWindow(QWidget *parent) :
+    QMainWindow(parent),
+    ui(new Ui::QUpgradeMainWindow)
+{
+    ui->setupUi(this);
+}
+
+PX4FirmwareUpgrader* QUpgradeMainWindow::firmwareUpgrader() {
+    return ui->centralwidget;
+}
+
+QUpgradeMainWindow::~QUpgradeMainWindow()
+{
+    delete ui;
+}
+
diff --git a/src/apps/qupgrade/QUpgradeMainWindow.h b/src/apps/qupgrade/QUpgradeMainWindow.h
new file mode 100644
index 0000000000000000000000000000000000000000..dbb523779376effbf358151189a31bfe49164e01
--- /dev/null
+++ b/src/apps/qupgrade/QUpgradeMainWindow.h
@@ -0,0 +1,61 @@
+/*=====================================================================
+
+ QGroundControl Open Source Ground Control Station
+
+ (c) 2009 - 2011 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
+
+ This file is part of the QGROUNDCONTROL project
+
+ QGROUNDCONTROL is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ QGROUNDCONTROL is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.
+
+ ======================================================================*/
+
+/**
+ * @file
+ *   @brief Definition of main window
+ *
+ *   @author Lorenz Meier
+ *
+ */
+
+#ifndef QUPGRADEMAINWINDOW_H
+#define QUPGRADEMAINWINDOW_H
+
+#include <QMainWindow>
+
+#include "PX4FirmwareUpgrader.h"
+
+namespace Ui {
+    class QUpgradeMainWindow;
+}
+
+class QUpgradeMainWindow : public QMainWindow
+{
+    Q_OBJECT
+
+public:
+    explicit QUpgradeMainWindow(QWidget *parent = 0);
+    ~QUpgradeMainWindow();
+
+    PX4FirmwareUpgrader* firmwareUpgrader();
+
+public slots:
+
+protected:
+
+private:
+    Ui::QUpgradeMainWindow *ui;
+};
+
+#endif // QUPGRADEMAINWINDOW_H
diff --git a/src/apps/qupgrade/QUpgradeMainWindow.ui b/src/apps/qupgrade/QUpgradeMainWindow.ui
new file mode 100644
index 0000000000000000000000000000000000000000..75f16d006b14cb3624646d56886aee5f9e741a00
--- /dev/null
+++ b/src/apps/qupgrade/QUpgradeMainWindow.ui
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>QUpgradeMainWindow</class>
+ <widget class="QMainWindow" name="QUpgradeMainWindow">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>800</width>
+    <height>600</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>MainWindow</string>
+  </property>
+  <widget class="PX4FirmwareUpgrader" name="centralwidget">
+   <layout class="QGridLayout" name="gridLayout" rowstretch="0"/>
+  </widget>
+  <widget class="QMenuBar" name="menubar">
+   <property name="geometry">
+    <rect>
+     <x>0</x>
+     <y>0</y>
+     <width>800</width>
+     <height>22</height>
+    </rect>
+   </property>
+  </widget>
+  <widget class="QStatusBar" name="statusbar"/>
+ </widget>
+ <customwidgets>
+  <customwidget>
+   <class>PX4FirmwareUpgrader</class>
+   <extends>QWidget</extends>
+   <header location="global">PX4FirmwareUpgrader.h</header>
+   <container>1</container>
+  </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/apps/qupgrade/main.cc b/src/apps/qupgrade/main.cc
new file mode 100644
index 0000000000000000000000000000000000000000..384013e2872cb22bb82b20b415e95fe48c1d7f4b
--- /dev/null
+++ b/src/apps/qupgrade/main.cc
@@ -0,0 +1,46 @@
+/*=====================================================================
+ 
+ QGroundControl Open Source Ground Control Station
+ 
+ (c) 2009 - 2011 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
+ 
+ This file is part of the QGROUNDCONTROL project
+ 
+ QGROUNDCONTROL is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+ 
+ QGROUNDCONTROL is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ GNU General Public License for more details.
+ 
+ You should have received a copy of the GNU General Public License
+ along with QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.
+ 
+ ======================================================================*/
+
+/**
+ * @file
+ *   @brief Main executable
+ *   @author Lorenz Meier <lm@inf.ethz.ch>
+ *
+ */
+
+#include <QtGui/QApplication>
+#include "QUpgradeApp.h"
+
+/**
+ * @brief Starts the application
+ *
+ * @param argc Number of commandline arguments
+ * @param argv Commandline arguments
+ * @return exit code, 0 for normal exit and !=0 for error cases
+ */
+int main(int argc, char *argv[])
+{
+
+    QUpgradeApp app(argc, argv);
+    return app.exec();
+}
diff --git a/src/comm/SerialLink.cc b/src/comm/SerialLink.cc
index 129fa01fa5b9d687bbb29fd58efbc543a9cc2d7f..7fec64a8304651dfb448a3cf90d1bad43a5e1fd0 100644
--- a/src/comm/SerialLink.cc
+++ b/src/comm/SerialLink.cc
@@ -563,10 +563,16 @@ bool SerialLink::disconnect()
 
         emit disconnected();
         emit connected(false);
+        if (port) {
+            port->close();
+        }
         return closed;
     }
     else {
-        // No port, so we're disconnected
+        // not running
+        if (port) {
+            port->close();
+        }
         return true;
     }
 
diff --git a/src/ui/PX4FirmwareUpgrader.cc b/src/ui/PX4FirmwareUpgrader.cc
new file mode 100644
index 0000000000000000000000000000000000000000..5d9fabff88dc60ec418b4263702e1b6851c43578
--- /dev/null
+++ b/src/ui/PX4FirmwareUpgrader.cc
@@ -0,0 +1,50 @@
+#include "PX4FirmwareUpgrader.h"
+#include "ui_PX4FirmwareUpgrader.h"
+
+#include <QGC.h>
+#include <QDebug>
+
+PX4FirmwareUpgrader::PX4FirmwareUpgrader(QWidget *parent) :
+    QWidget(parent),
+    ui(new Ui::PX4FirmwareUpgrader)
+{
+    ui->setupUi(this);
+
+    connect(ui->selectFileButton, SIGNAL(clicked()), this, SLOT(selectFirmwareFile()));
+    connect(ui->flashButton, SIGNAL(clicked()), this, SIGNAL(upgrade()));
+}
+
+PX4FirmwareUpgrader::~PX4FirmwareUpgrader()
+{
+    delete ui;
+}
+
+void PX4FirmwareUpgrader::selectFirmwareFile()
+{
+
+}
+
+void PX4FirmwareUpgrader::setDetectionStatusText(const QString &text)
+{
+    ui->detectionStatusLabel->setText(text);
+}
+
+void PX4FirmwareUpgrader::setFlashStatusText(const QString &text)
+{
+    ui->flashProgressLabel->setText(text);
+}
+
+void PX4FirmwareUpgrader::setFlashProgress(int percent)
+{
+    ui->flashProgressBar->setValue(percent);
+}
+
+void PX4FirmwareUpgrader::setPortName(const QString &portname)
+{
+    // Prepend newly found port to the list
+    if (ui->serialPortComboBox->findText(portname) == -1)
+    {
+        ui->serialPortComboBox->insertItem(0, portname);
+        ui->serialPortComboBox->setEditText(portname);
+    }
+}
diff --git a/src/ui/PX4FirmwareUpgrader.h b/src/ui/PX4FirmwareUpgrader.h
new file mode 100644
index 0000000000000000000000000000000000000000..94daf3763a798d65f719a33c966b87bdd5a9f4e8
--- /dev/null
+++ b/src/ui/PX4FirmwareUpgrader.h
@@ -0,0 +1,41 @@
+#ifndef PX4FIRMWAREUPGRADER_H
+#define PX4FIRMWAREUPGRADER_H
+
+#include <QWidget>
+#include <QTimer>
+
+#include <SerialLink.h>
+
+namespace Ui {
+class PX4FirmwareUpgrader;
+}
+
+class PX4FirmwareUpgrader : public QWidget
+{
+    Q_OBJECT
+    
+public:
+    PX4FirmwareUpgrader(QWidget *parent = 0);
+    ~PX4FirmwareUpgrader();
+
+public slots:
+
+    void setDetectionStatusText(const QString &text);
+
+    void setFlashStatusText(const QString &text);
+
+    void setFlashProgress(int percent);
+
+    void selectFirmwareFile();
+
+    void setPortName(const QString &portname);
+
+signals:
+    void firmwareFileNameSet(const QString &fileName);
+    void upgrade();
+
+private:
+    Ui::PX4FirmwareUpgrader *ui;
+};
+
+#endif // PX4FIRMWAREUPGRADER_H
diff --git a/src/ui/PX4FirmwareUpgrader.ui b/src/ui/PX4FirmwareUpgrader.ui
new file mode 100644
index 0000000000000000000000000000000000000000..91d2249ca4400d3472426ba2801c1e7c046d97d1
--- /dev/null
+++ b/src/ui/PX4FirmwareUpgrader.ui
@@ -0,0 +1,96 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>PX4FirmwareUpgrader</class>
+ <widget class="QWidget" name="PX4FirmwareUpgrader">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>428</width>
+    <height>331</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Form</string>
+  </property>
+  <layout class="QGridLayout" name="gridLayout">
+   <item row="3" column="0" colspan="3">
+    <widget class="QTextBrowser" name="descriptionTextBrowser"/>
+   </item>
+   <item row="4" column="0" colspan="3">
+    <widget class="QProgressBar" name="flashProgressBar">
+     <property name="value">
+      <number>24</number>
+     </property>
+    </widget>
+   </item>
+   <item row="5" column="0" colspan="2">
+    <widget class="QLabel" name="flashProgressLabel">
+     <property name="text">
+      <string>No update in progress.</string>
+     </property>
+    </widget>
+   </item>
+   <item row="2" column="0">
+    <widget class="QComboBox" name="versionComboBox"/>
+   </item>
+   <item row="2" column="2">
+    <widget class="QPushButton" name="selectFileButton">
+     <property name="text">
+      <string>Select File..</string>
+     </property>
+    </widget>
+   </item>
+   <item row="2" column="1">
+    <widget class="QPushButton" name="versionButton">
+     <property name="text">
+      <string>Check Online</string>
+     </property>
+    </widget>
+   </item>
+   <item row="1" column="2">
+    <widget class="QPushButton" name="serialPortButton">
+     <property name="enabled">
+      <bool>false</bool>
+     </property>
+     <property name="text">
+      <string>Set Serial Port</string>
+     </property>
+    </widget>
+   </item>
+   <item row="5" column="2">
+    <widget class="QPushButton" name="flashButton">
+     <property name="text">
+      <string>Flash Firmware</string>
+     </property>
+    </widget>
+   </item>
+   <item row="0" column="0" colspan="2">
+    <widget class="QLabel" name="detectionStatusLabel">
+     <property name="text">
+      <string>No PX4 board detected..</string>
+     </property>
+    </widget>
+   </item>
+   <item row="1" column="1">
+    <widget class="QCheckBox" name="detectionAutoCheckBox">
+     <property name="text">
+      <string>Auto Detect Port</string>
+     </property>
+     <property name="checked">
+      <bool>true</bool>
+     </property>
+    </widget>
+   </item>
+   <item row="1" column="0">
+    <widget class="QComboBox" name="serialPortComboBox">
+     <property name="editable">
+      <bool>true</bool>
+     </property>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>