diff --git a/src/comm/LinkConfiguration.cc b/src/comm/LinkConfiguration.cc
index de05037ff9aec117c1c3bd988be94c75d9071ae0..26d59990b579034ae5d8e87b2359fb3bc5580714 100644
--- a/src/comm/LinkConfiguration.cc
+++ b/src/comm/LinkConfiguration.cc
@@ -45,6 +45,7 @@ LinkConfiguration::LinkConfiguration(const QString& name)
     : _link(NULL)
     , _name(name)
     , _dynamic(false)
+    , _autoConnect(false)
 {
     _name = name;
     if (_name.isEmpty()) {
@@ -57,6 +58,7 @@ LinkConfiguration::LinkConfiguration(LinkConfiguration* copy)
     _link       = copy->link();
     _name       = copy->name();
     _dynamic    = copy->isDynamic();
+    _autoConnect= copy->isAutoConnect();
     Q_ASSERT(!_name.isEmpty());
 }
 
@@ -66,6 +68,7 @@ void LinkConfiguration::copyFrom(LinkConfiguration* source)
     _link       = source->link();
     _name       = source->name();
     _dynamic    = source->isDynamic();
+    _autoConnect= source->isAutoConnect();
 }
 
 /*!
diff --git a/src/comm/LinkConfiguration.h b/src/comm/LinkConfiguration.h
index 7812c8cdaddf9cbbd48838d8b5ec9dac538fbddd..70761ff7370ed5e27d8b55ee33af5f7472329cc0 100644
--- a/src/comm/LinkConfiguration.h
+++ b/src/comm/LinkConfiguration.h
@@ -40,9 +40,11 @@ public:
     LinkConfiguration(LinkConfiguration* copy);
     virtual ~LinkConfiguration() {}
 
-    Q_PROPERTY(QString          name        READ name           WRITE setName   NOTIFY nameChanged)
-    Q_PROPERTY(LinkInterface*   link        READ link           WRITE setLink   NOTIFY linkChanged)
+    Q_PROPERTY(QString          name        READ name           WRITE setName           NOTIFY nameChanged)
+    Q_PROPERTY(LinkInterface*   link        READ link           WRITE setLink           NOTIFY linkChanged)
     Q_PROPERTY(LinkType         linkType    READ type           CONSTANT)
+    Q_PROPERTY(bool             dynamic     READ isDynamic      WRITE setDynamic        NOTIFY dynamicChanged)
+    Q_PROPERTY(bool             autoConnect READ isAutoConnect  WRITE setAutoConnect    NOTIFY autoConnectChanged)
 
     // Property accessors
 
@@ -77,10 +79,22 @@ public:
      */
     bool isDynamic() { return _dynamic; }
 
+    /*!
+     *
+     * Is this an Auto Connect configuration?
+     * @return True if this is an Auto Connect configuration (connects automatically at boot time).
+     */
+    bool isAutoConnect() { return _autoConnect; }
+
     /*!
      * Set if this is this a dynamic configuration. (decided at runtime)
     */
-    void setDynamic(bool dynamic = true) { _dynamic = dynamic; }
+    void setDynamic(bool dynamic = true) { _dynamic = dynamic; emit dynamicChanged(); }
+
+    /*!
+     * Set if this is this an Auto Connect configuration.
+    */
+    void setAutoConnect(bool autoc = true) { _autoConnect = autoc; emit autoConnectChanged(); }
 
     /// Virtual Methods
 
@@ -152,14 +166,17 @@ public:
     static LinkConfiguration* duplicateSettings(LinkConfiguration *source);
 
 signals:
-    void nameChanged(const QString& name);
-    void linkChanged(LinkInterface* link);
+    void nameChanged        (const QString& name);
+    void linkChanged        (LinkInterface* link);
+    void dynamicChanged     ();
+    void autoConnectChanged ();
 
 protected:
     LinkInterface* _link; ///< Link currently using this configuration (if any)
 private:
     QString _name;
-    bool    _dynamic;    ///< A connection added automatically and not persistent (unless it's edited).
+    bool    _dynamic;       ///< A connection added automatically and not persistent (unless it's edited).
+    bool    _autoConnect;   ///< This connection is started automatically at boot
 };
 
 #endif // LINKCONFIGURATION_H
diff --git a/src/comm/LinkManager.cc b/src/comm/LinkManager.cc
index f8d4771c2db354d85ee2b776204e55e8db824559..574be911902e115ed87568e973780a7343e75a20 100644
--- a/src/comm/LinkManager.cc
+++ b/src/comm/LinkManager.cc
@@ -286,17 +286,17 @@ void LinkManager::saveLinkConfigurationList()
 {
     QSettings settings;
     settings.remove(LinkConfiguration::settingsRoot());
-
-    for (int i=0; i<_linkConfigurations.count(); i++) {
+    int trueCount = 0;
+    for (int i = 0; i < _linkConfigurations.count(); i++) {
         LinkConfiguration* linkConfig = _linkConfigurations.value<LinkConfiguration*>(i);
-
         if (linkConfig) {
             if(!linkConfig->isDynamic())
             {
                 QString root = LinkConfiguration::settingsRoot();
-                root += QString("/Link%1").arg(i);
+                root += QString("/Link%1").arg(trueCount++);
                 settings.setValue(root + "/name", linkConfig->name());
                 settings.setValue(root + "/type", linkConfig->type());
+                settings.setValue(root + "/auto", linkConfig->isAutoConnect());
                 // Have the instance save its own values
                 linkConfig->saveSettings(settings, root);
             }
@@ -304,17 +304,16 @@ void LinkManager::saveLinkConfigurationList()
             qWarning() << "Internal error";
         }
     }
-
     QString root(LinkConfiguration::settingsRoot());
-    settings.setValue(root + "/count", _linkConfigurations.count());
-    emit linkConfigurationChanged();
+    settings.setValue(root + "/count", trueCount);
+    emit linkConfigurationsChanged();
 }
 
 void LinkManager::loadLinkConfigurationList()
 {
     bool linksChanged = false;
+    bool mockPresent  = false;
     QSettings settings;
-
     // Is the group even there?
     if(settings.contains(LinkConfiguration::settingsRoot() + "/count")) {
         // Find out how many configurations we have
@@ -324,12 +323,13 @@ void LinkManager::loadLinkConfigurationList()
             root += QString("/Link%1").arg(i);
             if(settings.contains(root + "/type")) {
                 int type = settings.value(root + "/type").toInt();
-                if(type < LinkConfiguration::TypeLast) {
+                if((LinkConfiguration::LinkType)type < LinkConfiguration::TypeLast) {
                     if(settings.contains(root + "/name")) {
                         QString name = settings.value(root + "/name").toString();
                         if(!name.isEmpty()) {
                             LinkConfiguration* pLink = NULL;
-                            switch(type) {
+                            bool autoConnect = settings.value(root + "/auto").toBool();
+                            switch((LinkConfiguration::LinkType)type) {
 #ifndef __ios__
                                 case LinkConfiguration::TypeSerial:
                                     pLink = (LinkConfiguration*)new SerialConfiguration(name);
@@ -347,42 +347,48 @@ void LinkManager::loadLinkConfigurationList()
 #ifdef QT_DEBUG
                                 case LinkConfiguration::TypeMock:
                                     pLink = (LinkConfiguration*)new MockConfiguration(name);
+                                    mockPresent = true;
                                     break;
 #endif
+                                default:
+                                case LinkConfiguration::TypeLast:
+                                    break;
                             }
                             if(pLink) {
-                                // Have the instance load its own values
+                                //-- Have the instance load its own values
+                                pLink->setAutoConnect(autoConnect);
                                 pLink->loadSettings(settings, root);
                                 _linkConfigurations.append(pLink);
                                 linksChanged = true;
                             }
                         } else {
-                            qWarning() << "Link Configuration " << root << " has an empty name." ;
+                            qWarning() << "Link Configuration" << root << "has an empty name." ;
                         }
                     } else {
-                        qWarning() << "Link Configuration " << root << " has no name." ;
+                        qWarning() << "Link Configuration" << root << "has no name." ;
                     }
                 } else {
-                    qWarning() << "Link Configuration " << root << " an invalid type: " << type;
+                    qWarning() << "Link Configuration" << root << "an invalid type: " << type;
                 }
             } else {
-                qWarning() << "Link Configuration " << root << " has no type." ;
+                qWarning() << "Link Configuration" << root << "has no type." ;
             }
         }
     }
-
-    // Debug buids always add MockLink automatically
+    // Debug buids always add MockLink automatically (if one is not already there)
 #ifdef QT_DEBUG
-    MockConfiguration* pMock = new MockConfiguration("Mock Link PX4");
-    pMock->setDynamic(true);
-    _linkConfigurations.append(pMock);
-    linksChanged = true;
+    if(!mockPresent)
+    {
+        MockConfiguration* pMock = new MockConfiguration("Mock Link PX4");
+        pMock->setDynamic(true);
+        _linkConfigurations.append(pMock);
+        linksChanged = true;
+    }
 #endif
 
     if(linksChanged) {
-        emit linkConfigurationChanged();
+        emit linkConfigurationsChanged();
     }
-
     // Enable automatic Serial PX4/3DR Radio hunting
     _configurationsLoaded = true;
 }
@@ -417,7 +423,6 @@ void LinkManager::_updateAutoConnectLinks(void)
     bool foundUDP = false;
     for (int i=0; i<_links.count(); i++) {
         LinkConfiguration* linkConfig = _links.value<LinkInterface*>(i)->getLinkConfiguration();
-
         if (linkConfig->type() == LinkConfiguration::TypeUdp && linkConfig->name() == _defaultUPDLinkName) {
             foundUDP = true;
             break;
@@ -428,7 +433,9 @@ void LinkManager::_updateAutoConnectLinks(void)
         UDPConfiguration* udpConfig = new UDPConfiguration(_defaultUPDLinkName);
         udpConfig->setLocalPort(QGC_UDP_LOCAL_PORT);
         udpConfig->setDynamic(true);
+        _linkConfigurations.append(udpConfig);
         createConnectedLink(udpConfig);
+        emit linkConfigurationsChanged();
     }
 
 #ifndef __ios__
@@ -503,9 +510,7 @@ void LinkManager::_updateAutoConnectLinks(void)
                     pSerialConfig->setBaud(boardType == QGCSerialPortInfo::BoardType3drRadio ? 57600 : 115200);
                     pSerialConfig->setDynamic(true);
                     pSerialConfig->setPortName(portInfo.systemLocation());
-
                     _autoconnectConfigurations.append(pSerialConfig);
-
                     createConnectedLink(pSerialConfig);
                 }
             }
@@ -516,7 +521,6 @@ void LinkManager::_updateAutoConnectLinks(void)
     QList<LinkConfiguration*>  _confToDelete;
     for (int i=0; i<_autoconnectConfigurations.count(); i++) {
         SerialConfiguration* linkConfig = _autoconnectConfigurations.value<SerialConfiguration*>(i);
-
         if (linkConfig) {
             if (!currentPorts.contains(linkConfig->portName())) {
                 // We don't remove links which are still connected even though at this point the cable may
@@ -682,19 +686,36 @@ QStringList LinkManager::linkTypeStrings(void) const
     return list;
 }
 
-QStringList LinkManager::serialPortStrings(void)
+void LinkManager::_updateSerialPorts()
 {
+    _commPortList.clear();
+    _commPortDisplayList.clear();
 #ifndef __ios__
-    if(!_commPortList.size())
+    QList<QSerialPortInfo> portList = QSerialPortInfo::availablePorts();
+    foreach (const QSerialPortInfo &info, portList)
     {
-        QList<QSerialPortInfo> portList = QSerialPortInfo::availablePorts();
-        foreach (const QSerialPortInfo &info, portList)
-        {
-            QString name = info.portName();
-            _commPortList += name;
-        }
+        QString port = info.systemLocation().trimmed();
+        _commPortList += port;
+        _commPortDisplayList += SerialConfiguration::cleanPortDisplayname(port);
     }
 #endif
+}
+
+QStringList LinkManager::serialPortStrings(void)
+{
+    if(!_commPortDisplayList.size())
+    {
+        _updateSerialPorts();
+    }
+    return _commPortDisplayList;
+}
+
+QStringList LinkManager::serialPorts(void)
+{
+    if(!_commPortList.size())
+    {
+        _updateSerialPorts();
+    }
     return _commPortList;
 }
 
@@ -707,3 +728,107 @@ QStringList LinkManager::serialBaudRates(void)
     return SerialConfiguration::supportedBaudRates();
 #endif
 }
+
+bool LinkManager::endConfigurationEditing(LinkConfiguration* config, LinkConfiguration* editedConfig)
+{
+    Q_ASSERT(config != NULL);
+    Q_ASSERT(editedConfig != NULL);
+    _fixUnnamed(editedConfig);
+    config->copyFrom(editedConfig);
+    saveLinkConfigurationList();
+    // Tell link about changes (if any)
+    config->updateSettings();
+    // Discard temporary duplicate
+    delete editedConfig;
+    return true;
+}
+
+bool LinkManager::endCreateConfiguration(LinkConfiguration* config)
+{
+    Q_ASSERT(config != NULL);
+    _fixUnnamed(config);
+    _linkConfigurations.append(config);
+    saveLinkConfigurationList();
+    return true;
+}
+
+LinkConfiguration* LinkManager::createConfiguration(int type, const QString& name)
+{
+    if((LinkConfiguration::LinkType)type == LinkConfiguration::TypeSerial)
+        _updateSerialPorts();
+    return LinkConfiguration::createSettings(type, name);
+}
+
+LinkConfiguration* LinkManager::startConfigurationEditing(LinkConfiguration* config)
+{
+    Q_ASSERT(config != NULL);
+    if(config->type() == LinkConfiguration::TypeSerial)
+        _updateSerialPorts();
+    return LinkConfiguration::duplicateSettings(config);
+}
+
+
+void LinkManager::_fixUnnamed(LinkConfiguration* config)
+{
+    Q_ASSERT(config != NULL);
+    //-- Check for "Unnamed"
+    if (config->name() == "Unnamed") {
+        switch(config->type()) {
+#ifndef __ios__
+            case LinkConfiguration::TypeSerial: {
+                QString tname = dynamic_cast<SerialConfiguration*>(config)->portName();
+#ifdef Q_OS_WIN32
+                tname.replace("\\\\.\\", "");
+#else
+                tname.replace("/dev/cu.", "");
+                tname.replace("/dev/", "");
+#endif
+                config->setName(QString("Serial Device on %1").arg(tname));
+                break;
+                }
+#endif
+            case LinkConfiguration::TypeUdp:
+                config->setName(
+                    QString("UDP Link on Port %1").arg(dynamic_cast<UDPConfiguration*>(config)->localPort()));
+                break;
+            case LinkConfiguration::TypeTcp: {
+                    TCPConfiguration* tconfig = dynamic_cast<TCPConfiguration*>(config);
+                    if(tconfig) {
+                        config->setName(
+                            QString("TCP Link %1:%2").arg(tconfig->address().toString()).arg((int)tconfig->port()));
+                    }
+                }
+                break;
+            case LinkConfiguration::TypeLogReplay: {
+                LogReplayLinkConfiguration* tconfig = dynamic_cast<LogReplayLinkConfiguration*>(config);
+                if(tconfig) {
+                    config->setName(QString("Log Replay %1").arg(tconfig->logFilenameShort()));
+                }
+            }
+                break;
+#ifdef QT_DEBUG
+            case LinkConfiguration::TypeMock:
+                config->setName(
+                    QString("Mock Link"));
+                break;
+#endif
+            case LinkConfiguration::TypeLast:
+            default:
+                break;
+        }
+    }
+}
+
+void LinkManager::removeConfiguration(LinkConfiguration* config)
+{
+    Q_ASSERT(config != NULL);
+    LinkInterface* iface = config->link();
+    if(iface) {
+        disconnectLink(iface);
+    }
+    // Remove configuration
+    _linkConfigurations.removeOne(config);
+    delete config;
+    // Save list
+    saveLinkConfigurationList();
+}
diff --git a/src/comm/LinkManager.h b/src/comm/LinkManager.h
index a93fa19880aca396cd9233cf8d1a3cb4736570cf..9558d937d65bfa6360b8248daa4f5c468931c32d 100644
--- a/src/comm/LinkManager.h
+++ b/src/comm/LinkManager.h
@@ -80,15 +80,25 @@ public:
     Q_PROPERTY(bool autoconnectPX4Flow                  READ autoconnectPX4Flow                 WRITE setAutoconnectPX4Flow     NOTIFY autoconnectPX4FlowChanged)
 
     /// LinkInterface Accessor
-    Q_PROPERTY(QmlObjectListModel* links                READ links                              CONSTANT)
+    Q_PROPERTY(QmlObjectListModel*  links               READ links                              CONSTANT)
     /// LinkConfiguration Accessor
-    Q_PROPERTY(QmlObjectListModel* linkConfigurations   READ linkConfigurations                 CONSTANT)
+    Q_PROPERTY(QmlObjectListModel*  linkConfigurations  READ linkConfigurations                                                 NOTIFY linkConfigurationsChanged)
     /// List of comm type strings
-    Q_PROPERTY(QStringList         linkTypeStrings      READ linkTypeStrings                    CONSTANT)
+    Q_PROPERTY(QStringList          linkTypeStrings     READ linkTypeStrings                    CONSTANT)
     /// List of supported baud rates for serial links
-    Q_PROPERTY(QStringList         serialBaudRates      READ serialBaudRates                    CONSTANT)
+    Q_PROPERTY(QStringList          serialBaudRates     READ serialBaudRates                    CONSTANT)
+    /// List of comm ports display names
+    Q_PROPERTY(QStringList          serialPortStrings   READ serialPortStrings                                                  NOTIFY commPortStringsChanged)
     /// List of comm ports
-    Q_PROPERTY(QStringList         serialPortStrings    READ serialPortStrings                                                    NOTIFY commPortStringsChanged)
+    Q_PROPERTY(QStringList          serialPorts         READ serialPorts                                                        NOTIFY commPortsChanged)
+
+    // Create/Edit Link Configuration
+    Q_INVOKABLE LinkConfiguration*  createConfiguration         (int type, const QString& name);
+    Q_INVOKABLE LinkConfiguration*  startConfigurationEditing   (LinkConfiguration* config);
+    Q_INVOKABLE void                cancelConfigurationEditing  (LinkConfiguration* config) { delete config; }
+    Q_INVOKABLE bool                endConfigurationEditing     (LinkConfiguration* config, LinkConfiguration* editedConfig);
+    Q_INVOKABLE bool                endCreateConfiguration      (LinkConfiguration* config);
+    Q_INVOKABLE void                removeConfiguration         (LinkConfiguration* config);
 
     // Property accessors
 
@@ -104,6 +114,7 @@ public:
     QStringList         linkTypeStrings     (void) const;
     QStringList         serialBaudRates     (void);
     QStringList         serialPortStrings   (void);
+    QStringList         serialPorts         (void);
 
     void setAutoconnectUDP      (bool autoconnect);
     void setAutoconnectPixhawk  (bool autoconnect);
@@ -186,8 +197,9 @@ signals:
     // No longer hearing from any vehicles on this link.
     void linkInactive(LinkInterface* link);
 
-    void linkConfigurationChanged();
     void commPortStringsChanged();
+    void commPortsChanged();
+    void linkConfigurationsChanged();
 
 private slots:
     void _linkConnected(void);
@@ -197,6 +209,8 @@ private slots:
 private:
     bool _connectionsSuspendedMsg(void);
     void _updateAutoConnectLinks(void);
+    void _updateSerialPorts();
+    void _fixUnnamed(LinkConfiguration* config);
 
 #ifndef __ios__
     SerialConfiguration* _autoconnectConfigurationsContainsPort(const QString& portName);
@@ -218,6 +232,7 @@ private:
 
     QStringList _autoconnectWaitList;
     QStringList _commPortList;
+    QStringList _commPortDisplayList;
 
     bool _autoconnectUDP;
     bool _autoconnectPixhawk;
diff --git a/src/comm/SerialLink.cc b/src/comm/SerialLink.cc
index 0e27ae7d1a1adea7eceb2da35674344f769b426f..4ea97260f4f7c35b3f27c22ca38a7bf62dc6c335 100644
--- a/src/comm/SerialLink.cc
+++ b/src/comm/SerialLink.cc
@@ -395,12 +395,13 @@ SerialConfiguration::SerialConfiguration(const QString& name) : LinkConfiguratio
 
 SerialConfiguration::SerialConfiguration(SerialConfiguration* copy) : LinkConfiguration(copy)
 {
-    _baud       = copy->baud();
-    _flowControl= copy->flowControl();
-    _parity     = copy->parity();
-    _dataBits   = copy->dataBits();
-    _stopBits   = copy->stopBits();
-    _portName   = copy->portName();
+    _baud               = copy->baud();
+    _flowControl        = copy->flowControl();
+    _parity             = copy->parity();
+    _dataBits           = copy->dataBits();
+    _stopBits           = copy->stopBits();
+    _portName           = copy->portName();
+    _portDisplayName    = copy->portDisplayName();
 }
 
 void SerialConfiguration::copyFrom(LinkConfiguration *source)
@@ -408,12 +409,13 @@ void SerialConfiguration::copyFrom(LinkConfiguration *source)
     LinkConfiguration::copyFrom(source);
     SerialConfiguration* ssource = dynamic_cast<SerialConfiguration*>(source);
     Q_ASSERT(ssource != NULL);
-    _baud       = ssource->baud();
-    _flowControl= ssource->flowControl();
-    _parity     = ssource->parity();
-    _dataBits   = ssource->dataBits();
-    _stopBits   = ssource->stopBits();
-    _portName   = ssource->portName();
+    _baud               = ssource->baud();
+    _flowControl        = ssource->flowControl();
+    _parity             = ssource->parity();
+    _dataBits           = ssource->dataBits();
+    _stopBits           = ssource->stopBits();
+    _portName           = ssource->portName();
+    _portDisplayName    = ssource->portDisplayName();
 }
 
 void SerialConfiguration::updateSettings()
@@ -457,30 +459,45 @@ void SerialConfiguration::setPortName(const QString& portName)
     QString pname = portName.trimmed();
     if (!pname.isEmpty() && pname != _portName) {
         _portName = pname;
+        _portDisplayName = cleanPortDisplayname(pname);
     }
 }
 
+QString SerialConfiguration::cleanPortDisplayname(const QString name)
+{
+    QString pname = name.trimmed();
+#ifdef Q_OS_WIN32
+    pname.replace("\\\\.\\", "");
+#else
+    pname.replace("/dev/cu.", "");
+    pname.replace("/dev/", "");
+#endif
+    return pname;
+}
+
 void SerialConfiguration::saveSettings(QSettings& settings, const QString& root)
 {
     settings.beginGroup(root);
-    settings.setValue("baud",        _baud);
-    settings.setValue("dataBits",    _dataBits);
-    settings.setValue("flowControl", _flowControl);
-    settings.setValue("stopBits",    _stopBits);
-    settings.setValue("parity",      _parity);
-    settings.setValue("portName",    _portName);
+    settings.setValue("baud",           _baud);
+    settings.setValue("dataBits",       _dataBits);
+    settings.setValue("flowControl",    _flowControl);
+    settings.setValue("stopBits",       _stopBits);
+    settings.setValue("parity",         _parity);
+    settings.setValue("portName",       _portName);
+    settings.setValue("portDisplayName",_portDisplayName);
     settings.endGroup();
 }
 
 void SerialConfiguration::loadSettings(QSettings& settings, const QString& root)
 {
     settings.beginGroup(root);
-    if(settings.contains("baud"))        _baud         = settings.value("baud").toInt();
-    if(settings.contains("dataBits"))    _dataBits     = settings.value("dataBits").toInt();
-    if(settings.contains("flowControl")) _flowControl  = settings.value("flowControl").toInt();
-    if(settings.contains("stopBits"))    _stopBits     = settings.value("stopBits").toInt();
-    if(settings.contains("parity"))      _parity       = settings.value("parity").toInt();
-    if(settings.contains("portName"))    _portName     = settings.value("portName").toString();
+    if(settings.contains("baud"))           _baud           = settings.value("baud").toInt();
+    if(settings.contains("dataBits"))       _dataBits       = settings.value("dataBits").toInt();
+    if(settings.contains("flowControl"))    _flowControl    = settings.value("flowControl").toInt();
+    if(settings.contains("stopBits"))       _stopBits       = settings.value("stopBits").toInt();
+    if(settings.contains("parity"))         _parity         = settings.value("parity").toInt();
+    if(settings.contains("portName"))       _portName       = settings.value("portName").toString();
+    if(settings.contains("portDisplayName"))_portDisplayName= settings.value("portDisplayName").toString();
     settings.endGroup();
 }
 
diff --git a/src/comm/SerialLink.h b/src/comm/SerialLink.h
index 12d02b0dcc8975e07b1fe1dbbada535314a14175..d44b6ebfaee7cdff47951fd5b125ca0c0b028e23 100644
--- a/src/comm/SerialLink.h
+++ b/src/comm/SerialLink.h
@@ -66,22 +66,32 @@ public:
     SerialConfiguration(const QString& name);
     SerialConfiguration(SerialConfiguration* copy);
 
+    Q_PROPERTY(int      baud            READ baud               WRITE setBaud               NOTIFY baudChanged)
+    Q_PROPERTY(int      dataBits        READ dataBits           WRITE setDataBits           NOTIFY dataBitsChanged)
+    Q_PROPERTY(int      flowControl     READ flowControl        WRITE setFlowControl        NOTIFY flowControlChanged)
+    Q_PROPERTY(int      stopBits        READ stopBits           WRITE setStopBits           NOTIFY stopBitsChanged)
+    Q_PROPERTY(int      parity          READ parity             WRITE setParity             NOTIFY parityChanged)
+    Q_PROPERTY(QString  portName        READ portName           WRITE setPortName           NOTIFY portNameChanged)
+    Q_PROPERTY(QString  portDisplayName READ portDisplayName                                NOTIFY portDisplayNameChanged)
+
     int  baud()         { return _baud; }
     int  dataBits()     { return _dataBits; }
     int  flowControl()  { return _flowControl; }    ///< QSerialPort Enums
     int  stopBits()     { return _stopBits; }
     int  parity()       { return _parity; }         ///< QSerialPort Enums
 
-    const QString portName() { return _portName; }
+    const QString portName          () { return _portName; }
+    const QString portDisplayName   () { return _portDisplayName; }
 
-    void setBaud        (int baud);
-    void setDataBits    (int databits);
-    void setFlowControl (int flowControl);          ///< QSerialPort Enums
-    void setStopBits    (int stopBits);
-    void setParity      (int parity);               ///< QSerialPort Enums
-    void setPortName    (const QString& portName);
+    void setBaud            (int baud);
+    void setDataBits        (int databits);
+    void setFlowControl     (int flowControl);          ///< QSerialPort Enums
+    void setStopBits        (int stopBits);
+    void setParity          (int parity);               ///< QSerialPort Enums
+    void setPortName        (const QString& portName);
 
     static QStringList supportedBaudRates();
+    static QString cleanPortDisplayname(const QString name);
 
     /// From LinkConfiguration
     LinkType type() { return LinkConfiguration::TypeSerial; }
@@ -90,6 +100,15 @@ public:
     void saveSettings(QSettings& settings, const QString& root);
     void updateSettings();
 
+signals:
+    void baudChanged            ();
+    void dataBitsChanged        ();
+    void flowControlChanged     ();
+    void stopBitsChanged        ();
+    void parityChanged          ();
+    void portNameChanged        ();
+    void portDisplayNameChanged ();
+
 private:
     static void _initBaudRates();
 
@@ -100,9 +119,9 @@ private:
     int _stopBits;
     int _parity;
     QString _portName;
+    QString _portDisplayName;
 };
 
-
 /**
  * @brief The SerialLink class provides cross-platform access to serial links.
  * It takes care of the link management and provides a common API to higher
diff --git a/src/ui/preferences/LinkSettings.qml b/src/ui/preferences/LinkSettings.qml
index b54499c86e788f0daed5b9d284049dd673be58ac..ada39d3a253750ce8089959c9657ca50131ff92d 100644
--- a/src/ui/preferences/LinkSettings.qml
+++ b/src/ui/preferences/LinkSettings.qml
@@ -23,6 +23,7 @@
 
 import QtQuick          2.5
 import QtQuick.Controls 1.4
+import QtQuick.Dialogs  1.1
 
 import QGroundControl                       1.0
 import QGroundControl.Controls              1.0
@@ -92,7 +93,7 @@ Rectangle {
                     text:   object.name
                     width:  _linkRoot.width * 0.5
                     exclusiveGroup: linkGroup
-                    anchors.horizontalCenter: parent.horizontalCenter
+                    anchors.horizontalCenter: settingsColumn.horizontalCenter
                     onClicked: {
                         checked = true
                         _currentSelection = object
@@ -111,8 +112,26 @@ Rectangle {
         QGCButton {
             width:      ScreenTools.defaultFontPixelWidth * 10
             text:       "Delete"
-            enabled:    _currentSelection && !_currentSelection.link
+            enabled:    _currentSelection && !_currentSelection.dynamic
             onClicked: {
+                if(_currentSelection)
+                    deleteDialog.visible = true
+            }
+            MessageDialog {
+                id:         deleteDialog
+                visible:    false
+                icon:       StandardIcon.Warning
+                standardButtons: StandardButton.Yes | StandardButton.No
+                title:      "Remove Link Configuration"
+                text:       _currentSelection ? "Remove " + _currentSelection.name + ". Is this really what you want?" : ""
+                onYes: {
+                    if(_currentSelection)
+                        QGroundControl.linkManager.removeConfiguration(_currentSelection)
+                    deleteDialog.visible = false
+                }
+                onNo: {
+                    deleteDialog.visible = false
+                }
             }
         }
         QGCButton {
@@ -154,6 +173,7 @@ Rectangle {
         anchors.fill:   parent
         visible:        false
         property var linkConfig: null
+        property var editConfig: null
     }
 
     //---------------------------------------------
@@ -163,6 +183,24 @@ Rectangle {
         Rectangle {
             color:          __qgcPal.window
             anchors.fill:   parent
+            Component.onCompleted: {
+                // If editing, create copy for editing
+                if(linkConfig) {
+                    editConfig = QGroundControl.linkManager.startConfigurationEditing(linkConfig)
+                } else {
+                    // Create new link configuration
+                    if(ScreenTools.isiOS)
+                        editConfig = QGroundControl.linkManager.createConfiguration(LinkConfiguration.TypeUdp, "Unnamed")
+                    else
+                        editConfig = QGroundControl.linkManager.createConfiguration(LinkConfiguration.TypeSerial, "Unnamed")
+                }
+            }
+            Component.onDestruction: {
+                if(editConfig) {
+                    QGroundControl.linkManager.cancelConfigurationEditing(editConfig)
+                    editConfig = null
+                }
+            }
             Flickable {
                 clip:               true
                 anchors.top:        parent.top
@@ -199,7 +237,8 @@ Rectangle {
                             anchors.verticalCenter: parent.verticalCenter
                         }
                         QGCTextField {
-                            text:   linkConfig ? linkConfig.name : "Untitled"
+                            id:     nameField
+                            text:   editConfig ? editConfig.name : ""
                             width:  _secondColumn
                             anchors.verticalCenter: parent.verticalCenter
                         }
@@ -220,8 +259,17 @@ Rectangle {
                             anchors.verticalCenter: parent.verticalCenter
                             Component.onCompleted: {
                                 if(linkConfig != null) {
-                                    if(linkConfig.linkType === LinkConfiguration.TypeSerial)
+                                    var index = linkConfig.linkType
+                                    if(index === LinkConfiguration.TypeSerial)
                                         linkSettingLoader.sourceComponent = serialLinkSettings
+                                    if(index === LinkConfiguration.TypeUdp)
+                                        linkSettingLoader.sourceComponent = udpLinkSettings
+                                    if(index === LinkConfiguration.TypeTcp)
+                                        linkSettingLoader.sourceComponent = tcpLinkSettings
+                                    if(index === LinkConfiguration.TypeMock)
+                                        linkSettingLoader.sourceComponent = mockLinkSettings
+                                    if(index === LinkConfiguration.TypeLogReplay)
+                                        linkSettingLoader.sourceComponent = logLinkSettings
                                     linkSettingLoader.visible = true
                                 }
                             }
@@ -235,7 +283,14 @@ Rectangle {
                             model:          QGroundControl.linkManager.linkTypeStrings
                             anchors.verticalCenter: parent.verticalCenter
                             onActivated: {
-                                if (index != -1) {
+                                if (index != -1 && index !== editConfig.linkType) {
+                                    // Save current name
+                                    var name = editConfig.name
+                                    // Discard link configuration (old type)
+                                    QGroundControl.linkManager.cancelConfigurationEditing(editConfig)
+                                    // Create new link configuration
+                                    editConfig = QGroundControl.linkManager.createConfiguration(index, name)
+                                    // Load appropriate configuration panel
                                     linkSettingLoader.sourceComponent = null
                                     if(index === LinkConfiguration.TypeSerial)
                                         linkSettingLoader.sourceComponent = serialLinkSettings
@@ -252,12 +307,40 @@ Rectangle {
                             Component.onCompleted: {
                                 if(linkConfig == null) {
                                     linkTypeCombo.currentIndex = 0
-                                    linkSettingLoader.sourceComponent = serialLinkSettings
+                                    var index = editConfig.linkType
+                                    if(index === LinkConfiguration.TypeSerial)
+                                        linkSettingLoader.sourceComponent = serialLinkSettings
+                                    if(index === LinkConfiguration.TypeUdp)
+                                        linkSettingLoader.sourceComponent = udpLinkSettings
+                                    if(index === LinkConfiguration.TypeTcp)
+                                        linkSettingLoader.sourceComponent = tcpLinkSettings
+                                    if(index === LinkConfiguration.TypeMock)
+                                        linkSettingLoader.sourceComponent = mockLinkSettings
+                                    if(index === LinkConfiguration.TypeLogReplay)
+                                        linkSettingLoader.sourceComponent = logLinkSettings
                                     linkSettingLoader.visible = true
                                 }
                             }
                         }
                     }
+                    Item {
+                        height: ScreenTools.defaultFontPixelHeight * 0.5
+                        width:  parent.width
+                    }
+                    //-- Auto Connect
+                    QGCCheckBox {
+                        text:       "Automatically Connect on Start"
+                        checked:    false
+                        onCheckedChanged: {
+                            if(editConfig) {
+                                editConfig.autoConnect = checked
+                            }
+                        }
+                        Component.onCompleted: {
+                            if(editConfig)
+                                checked = editConfig.autoConnect
+                        }
+                    }
                     Item {
                         height: ScreenTools.defaultFontPixelHeight
                         width:  parent.width
@@ -266,7 +349,7 @@ Rectangle {
                         id:             linkSettingLoader
                         width:          parent.width
                         visible:        false
-                        property var config: linkConfig
+                        property var subEditConfig: editConfig
                     }
                 }
             }
@@ -280,6 +363,16 @@ Rectangle {
                     width:      ScreenTools.defaultFontPixelWidth * 10
                     text:       "OK"
                     onClicked: {
+                        // Save editting
+                        editConfig.name = nameField.text
+                        if(linkConfig) {
+                            QGroundControl.linkManager.endConfigurationEditing(linkConfig, editConfig)
+                        } else {
+                            // If it was edited, it's no longer "dynamic"
+                            editConfig.dynamic = false
+                            QGroundControl.linkManager.endCreateConfiguration(editConfig)
+                        }
+                        editConfig = null
                         _linkRoot.closeCommSettings()
                     }
                 }
@@ -287,6 +380,8 @@ Rectangle {
                     width:      ScreenTools.defaultFontPixelWidth * 10
                     text:       "Cancel"
                     onClicked: {
+                        QGroundControl.linkManager.cancelConfigurationEditing(editConfig)
+                        editConfig = null
                         _linkRoot.closeCommSettings()
                     }
                 }
@@ -327,10 +422,21 @@ Rectangle {
                     anchors.verticalCenter: parent.verticalCenter
                     onActivated: {
                         if (index != -1) {
+                            subEditConfig.portName = QGroundControl.linkManager.serialPorts[index]
                         }
                     }
                     Component.onCompleted: {
-                        if(config != null) {
+                        if(subEditConfig != null) {
+                            if(subEditConfig.portDisplayName === "")
+                                subEditConfig.portName = QGroundControl.linkManager.serialPorts[0]
+                            var index = commPortCombo.find(subEditConfig.portDisplayName)
+                            if (index === -1) {
+                                console.warn("Serial Port not present", subEditConfig.portName)
+                            } else {
+                                commPortCombo.currentIndex = index
+                            }
+                        } else {
+                            commPortCombo.currentIndex = 0
                         }
                     }
                 }
@@ -349,15 +455,16 @@ Rectangle {
                     anchors.verticalCenter: parent.verticalCenter
                     onActivated: {
                         if (index != -1) {
+                            subEditConfig.baud = parseInt(QGroundControl.linkManager.serialBaudRates[index])
                         }
                     }
                     Component.onCompleted: {
                         var baud = "57600"
-                        if(config != null) {
-                            // Get baud from config
+                        if(subEditConfig != null) {
+                            baud = subEditConfig.baud.toString()
                         }
                         var index = baudCombo.find(baud)
-                        if (index == -1) {
+                        if (index === -1) {
                             console.warn("Baud rate name not in combo box", baud)
                         } else {
                             baudCombo.currentIndex = index
@@ -365,6 +472,128 @@ Rectangle {
                     }
                 }
             }
+            Item {
+                height: ScreenTools.defaultFontPixelHeight / 2
+                width:  parent.width
+            }
+            //-----------------------------------------------------------------
+            //-- Advanced Serial Settings
+            QGCCheckBox {
+                id:     showAdvanced
+                text:   "Show Advanced Serial Settings"
+            }
+            Item {
+                height: ScreenTools.defaultFontPixelHeight / 2
+                width:  parent.width
+            }
+            //-- Flow Control
+            QGCCheckBox {
+                text:       "Enable Flow Control"
+                checked:    subEditConfig ? subEditConfig.flowControl !== 0 : false
+                visible:    showAdvanced.checked
+                onCheckedChanged: {
+                    if(subEditConfig) {
+                        subEditConfig.flowControl = checked ? 1 : 0
+                    }
+                }
+            }
+            //-- Parity
+            Row {
+                spacing:    ScreenTools.defaultFontPixelWidth
+                visible:    showAdvanced.checked
+                QGCLabel {
+                    text:   "Parity:"
+                    width:  _firstColumn
+                    anchors.verticalCenter: parent.verticalCenter
+                }
+                QGCComboBox {
+                    id:             parityCombo
+                    width:          _firstColumn
+                    model:          ["None", "Even", "Odd"]
+                    anchors.verticalCenter: parent.verticalCenter
+                    onActivated: {
+                        if (index != -1) {
+                            // Hard coded values from qserialport.h
+                            if(index == 0)
+                                subEditConfig.parity = 0
+                            else if(index == 1)
+                                subEditConfig.parity = 2
+                            else
+                                subEditConfig.parity = 3
+                        }
+                    }
+                    Component.onCompleted: {
+                        var index = 0
+                        if(subEditConfig != null) {
+                            index = subEditConfig.parity
+                        }
+                        if(index > 1) {
+                            index = index - 2
+                        }
+                        parityCombo.currentIndex = index
+                    }
+                }
+            }
+            //-- Data Bits
+            Row {
+                spacing:    ScreenTools.defaultFontPixelWidth
+                visible:    showAdvanced.checked
+                QGCLabel {
+                    text:   "Data Bits:"
+                    width:  _firstColumn
+                    anchors.verticalCenter: parent.verticalCenter
+                }
+                QGCComboBox {
+                    id:             dataCombo
+                    width:          _firstColumn
+                    model:          ["5", "6", "7", "8"]
+                    anchors.verticalCenter: parent.verticalCenter
+                    onActivated: {
+                        if (index != -1) {
+                            subEditConfig.dataBits = index + 5
+                        }
+                    }
+                    Component.onCompleted: {
+                        var index = 3
+                        if(subEditConfig != null) {
+                            index = subEditConfig.parity - 5
+                            if(index < 0)
+                                index = 3
+                        }
+                        dataCombo.currentIndex = index
+                    }
+                }
+            }
+            //-- Stop Bits
+            Row {
+                spacing:    ScreenTools.defaultFontPixelWidth
+                visible:    showAdvanced.checked
+                QGCLabel {
+                    text:   "Stop Bits:"
+                    width:  _firstColumn
+                    anchors.verticalCenter: parent.verticalCenter
+                }
+                QGCComboBox {
+                    id:             stopCombo
+                    width:          _firstColumn
+                    model:          ["1", "2"]
+                    anchors.verticalCenter: parent.verticalCenter
+                    onActivated: {
+                        if (index != -1) {
+                            subEditConfig.stopBits = index + 1
+                        }
+                    }
+                    Component.onCompleted: {
+                        var index = 0
+                        if(subEditConfig != null) {
+                            index = subEditConfig.stopBits - 1
+                            if(index < 0)
+                                index = 0
+                        }
+                        stopCombo.currentIndex = index
+                    }
+                }
+            }
         }
     }
     //---------------------------------------------