diff --git a/src/plugins/qnx/blackberrydebugtokenpinsdialog.cpp b/src/plugins/qnx/blackberrydebugtokenpinsdialog.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..07c1616a90ee8cc73ec476dcf5e9af0194cbfcab
--- /dev/null
+++ b/src/plugins/qnx/blackberrydebugtokenpinsdialog.cpp
@@ -0,0 +1,173 @@
+/**************************************************************************
+**
+** Copyright (C) 2014 BlackBerry Limited. All rights reserved.
+**
+** Contact: BlackBerry (qt@blackberry.com)
+** Contact: KDAB (info@kdab.com)
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.  For licensing terms and
+** conditions see http://qt.digia.com/licensing.  For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights.  These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#include "blackberrydebugtokenpinsdialog.h"
+#include "ui_blackberrydebugtokenpinsdialog.h"
+#include "blackberrydebugtokenreader.h"
+#include "blackberryconfigurationmanager.h"
+#include "blackberrysigningutils.h"
+
+#include <QStandardItemModel>
+#include <QMessageBox>
+#include <QLineEdit>
+
+namespace Qnx {
+namespace Internal {
+
+BlackBerryDebugTokenPinsDialog::BlackBerryDebugTokenPinsDialog(const QString &debugToken, QWidget *parent) :
+    QDialog(parent),
+    ui(new Ui_BlackBerryDebugTokenPinsDialog),
+    m_model(new QStandardItemModel(this)),
+    m_debugTokenPath(debugToken),
+    m_updated(false)
+{
+    ui->setupUi(this);
+    setWindowTitle(tr("Debug Token PINs"));
+    ui->pins->setModel(m_model);
+    ui->pathLabel->setText(debugToken);
+    BlackBerryDebugTokenReader reader(debugToken);
+    if (reader.isValid()) {
+        QStringList pins = reader.pins().split(QLatin1Char(','));
+        foreach (const QString &pin, pins)
+            m_model->appendRow(new QStandardItem(pin));
+    }
+
+    m_okButton = ui->buttonBox->button(QDialogButtonBox::Ok);
+
+    ui->editButton->setEnabled(false);
+    ui->removeButton->setEnabled(false);
+
+    connect(ui->addButton, SIGNAL(clicked()), this, SLOT(addPin()));
+    connect(ui->editButton, SIGNAL(clicked()), this, SLOT(editPin()));
+    connect(ui->removeButton, SIGNAL(clicked()), this, SLOT(removePin()));
+    connect(m_okButton, SIGNAL(clicked()), this, SLOT(emitUpdatedPins()));
+    connect(ui->pins, SIGNAL(pressed(QModelIndex)), this, SLOT(updateUi(QModelIndex)));
+}
+
+BlackBerryDebugTokenPinsDialog::~BlackBerryDebugTokenPinsDialog()
+{
+    delete ui;
+}
+
+void BlackBerryDebugTokenPinsDialog::addPin()
+{
+    bool ok;
+    const QString pin = promptPIN(QString(), &ok);
+    if (ok && !pin.isEmpty()) {
+        m_model->appendRow(new QStandardItem(pin));
+        m_updated = true;
+    }
+}
+
+void BlackBerryDebugTokenPinsDialog::editPin()
+{
+    const QModelIndex index = ui->pins->currentIndex();
+    if (!index.isValid())
+        return;
+
+    bool ok;
+    QString pin = m_model->item(index.row(), 0)->text();
+    QString newPin = promptPIN(pin, &ok);
+    if (ok && newPin != pin) {
+        m_model->item(index.row(), 0)->setText(newPin);
+        m_updated = true;
+    }
+}
+
+void BlackBerryDebugTokenPinsDialog::removePin()
+{
+    const QModelIndex index = ui->pins->currentIndex();
+    if (!index.isValid())
+        return;
+
+    const QString pin = m_model->item(index.row(), 0)->text();
+    const int result = QMessageBox::question(this, tr("Confirmation"),
+            tr("Are you sure you want to remove PIN: %1")
+            .arg(pin), QMessageBox::Yes | QMessageBox::No);
+
+    if (result == QMessageBox::Yes) {
+        m_model->removeRow(index.row());
+        m_updated = true;
+    }
+}
+
+void BlackBerryDebugTokenPinsDialog::updateUi(const QModelIndex& index)
+{
+    ui->editButton->setEnabled(index.isValid());
+    ui->removeButton->setEnabled(index.isValid());
+}
+
+void BlackBerryDebugTokenPinsDialog::emitUpdatedPins()
+{
+    if (!m_updated)
+        return;
+
+    QStringList pins;
+    for (int i = 0; i < m_model->rowCount(); i++)
+        pins << m_model->item(i)->text();
+
+    emit pinsUpdated(pins);
+}
+
+QString BlackBerryDebugTokenPinsDialog::promptPIN(const QString &value, bool *ok)
+{
+    QDialog dialog(this);
+    QVBoxLayout *layout = new QVBoxLayout;
+    QLineEdit *lineEdit = new QLineEdit;
+    QDialogButtonBox *buttonBox = new QDialogButtonBox;
+
+    lineEdit->setMaxLength(8);
+    lineEdit->setText(value);
+
+    buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Ok);
+    buttonBox->button(QDialogButtonBox::Ok)->setDefault(true);
+
+    connect(buttonBox, SIGNAL(accepted()), &dialog, SLOT(accept()));
+    connect(buttonBox, SIGNAL(rejected()), &dialog, SLOT(reject()));
+
+    layout->addWidget(lineEdit);
+    layout->addWidget(buttonBox);
+
+    dialog.setWindowTitle(tr("Debug Token PIN"));
+    dialog.setLayout(layout);
+
+    const bool rejected = dialog.exec() == QDialog::Rejected;
+     if (ok)
+         *ok = !rejected;
+
+     if (rejected)
+         return QString();
+
+     return lineEdit->text();
+}
+
+} // Internal
+} // Qnx
diff --git a/src/plugins/qnx/blackberrydebugtokenpinsdialog.h b/src/plugins/qnx/blackberrydebugtokenpinsdialog.h
new file mode 100644
index 0000000000000000000000000000000000000000..d36c65a7f6c46e91d324b066cef10b0e33c9b0c4
--- /dev/null
+++ b/src/plugins/qnx/blackberrydebugtokenpinsdialog.h
@@ -0,0 +1,78 @@
+/**************************************************************************
+**
+** Copyright (C) 2014 BlackBerry Limited. All rights reserved.
+**
+** Contact: BlackBerry (qt@blackberry.com)
+** Contact: KDAB (info@kdab.com)
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.  For licensing terms and
+** conditions see http://qt.digia.com/licensing.  For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights.  These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#ifndef BLACKBERRYDEBUGTOKENSDIALOG_H
+#define BLACKBERRYDEBUGTOKENSDIALOG_H
+
+#include <QDialog>
+
+QT_BEGIN_NAMESPACE
+class QStandardItemModel;
+QT_END_NAMESPACE
+
+namespace Qnx {
+namespace Internal {
+
+class Ui_BlackBerryDebugTokenPinsDialog;
+
+class BlackBerryDebugTokenPinsDialog : public QDialog
+{
+    Q_OBJECT
+
+public:
+    explicit BlackBerryDebugTokenPinsDialog(const QString &debugToken, QWidget *parent = 0);
+    ~BlackBerryDebugTokenPinsDialog();
+
+private slots:
+    void addPin();
+    void editPin();
+    void removePin();
+    void updateUi(const QModelIndex& index);
+
+    void emitUpdatedPins();
+    QString promptPIN(const QString& defaultValue, bool *ok = 0);
+
+signals:
+    void pinsUpdated(const QStringList &pins);
+
+private:
+    Ui_BlackBerryDebugTokenPinsDialog *ui;
+    QStandardItemModel *m_model;
+
+    QPushButton *m_okButton;
+
+    QString m_debugTokenPath;
+    bool m_updated;
+};
+
+} // Internal
+} // Qnx
+#endif // BLACKBERRYDEBUGTOKENSDIALOG_H
diff --git a/src/plugins/qnx/blackberrydebugtokenpinsdialog.ui b/src/plugins/qnx/blackberrydebugtokenpinsdialog.ui
new file mode 100644
index 0000000000000000000000000000000000000000..c9ef448a63b26bcb0c94d23e8d2e8ff22ec9e56a
--- /dev/null
+++ b/src/plugins/qnx/blackberrydebugtokenpinsdialog.ui
@@ -0,0 +1,144 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>Qnx::Internal::BlackBerryDebugTokenPinsDialog</class>
+ <widget class="QDialog" name="Qnx::Internal::BlackBerryDebugTokenPinsDialog">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>432</width>
+    <height>300</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Dialog</string>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout_2">
+   <item>
+    <layout class="QHBoxLayout" name="horizontalLayout_2">
+     <item>
+      <widget class="QLabel" name="label">
+       <property name="text">
+        <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Debug Token: &lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QLabel" name="pathLabel">
+       <property name="text">
+        <string/>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <spacer name="horizontalSpacer">
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>40</width>
+         <height>20</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <layout class="QHBoxLayout" name="horizontalLayout">
+     <item>
+      <widget class="QListView" name="pins">
+       <property name="editTriggers">
+        <set>QAbstractItemView::NoEditTriggers</set>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <layout class="QVBoxLayout" name="verticalLayout">
+       <item>
+        <widget class="QPushButton" name="addButton">
+         <property name="text">
+          <string>Add</string>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <widget class="QPushButton" name="editButton">
+         <property name="text">
+          <string>Edit</string>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <widget class="QPushButton" name="removeButton">
+         <property name="text">
+          <string>Remove</string>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <spacer name="verticalSpacer">
+         <property name="orientation">
+          <enum>Qt::Vertical</enum>
+         </property>
+         <property name="sizeHint" stdset="0">
+          <size>
+           <width>20</width>
+           <height>40</height>
+          </size>
+         </property>
+        </spacer>
+       </item>
+      </layout>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <widget class="QDialogButtonBox" name="buttonBox">
+     <property name="orientation">
+      <enum>Qt::Horizontal</enum>
+     </property>
+     <property name="standardButtons">
+      <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+     </property>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>accepted()</signal>
+   <receiver>Qnx::Internal::BlackBerryDebugTokenPinsDialog</receiver>
+   <slot>accept()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>248</x>
+     <y>254</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>157</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>rejected()</signal>
+   <receiver>Qnx::Internal::BlackBerryDebugTokenPinsDialog</receiver>
+   <slot>reject()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>316</x>
+     <y>260</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>286</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>
diff --git a/src/plugins/qnx/blackberrydebugtokenreader.cpp b/src/plugins/qnx/blackberrydebugtokenreader.cpp
index 57ef69a8f53928886afc6d6b8fff5190f9171f59..3dfb45686dffa0b5d59ecc5bdbe5d6a0aec3037a 100644
--- a/src/plugins/qnx/blackberrydebugtokenreader.cpp
+++ b/src/plugins/qnx/blackberrydebugtokenreader.cpp
@@ -31,6 +31,8 @@
 
 #include "blackberrydebugtokenreader.h"
 
+#include <QStringList>
+
 #ifdef QNX_ZIP_FILE_SUPPORT
 #include <private/qzipreader_p.h>
 #endif
@@ -43,6 +45,8 @@ const char MANIFEST_FILENAME[] = "META-INF/MANIFEST.MF";
 
 const char MANIFEST_AUTHOR_KEY[]    = "Package-Author: ";
 const char MANIFEST_AUTHOR_ID_KEY[] = "Package-Author-Id: ";
+const char MANIFEST_EXPIRY[]        = "Debug-Token-Expiry-Date: ";
+const char MANIFEST_PINS[]          = "Debug-Token-Device-Id: ";
 }
 
 BlackBerryDebugTokenReader::BlackBerryDebugTokenReader(const QString &filePath)
@@ -83,6 +87,24 @@ QString BlackBerryDebugTokenReader::authorId() const
     return manifestValue(MANIFEST_AUTHOR_ID_KEY);
 }
 
+QString BlackBerryDebugTokenReader::expiry() const
+{
+    return manifestValue(MANIFEST_EXPIRY);
+}
+
+QString BlackBerryDebugTokenReader::pins() const
+{
+    const QString value = manifestValue(MANIFEST_PINS);
+    QStringList pins = value.split(QLatin1Char(','));
+    QStringList pinsHexa;
+    foreach (const QString &pin, pins) {
+        QString hexa;
+        pinsHexa << hexa.setNum(pin.toUInt(), 16);
+    }
+
+    return pinsHexa.join(QLatin1Char(','));
+}
+
 bool BlackBerryDebugTokenReader::isSupported()
 {
 #ifdef QNX_ZIP_FILE_SUPPORT
diff --git a/src/plugins/qnx/blackberrydebugtokenreader.h b/src/plugins/qnx/blackberrydebugtokenreader.h
index a8c7e69fd888843ecff853a8644893d411b0dae3..cae41e771ba9eb9f79d4ef097c50bb7780df3afb 100644
--- a/src/plugins/qnx/blackberrydebugtokenreader.h
+++ b/src/plugins/qnx/blackberrydebugtokenreader.h
@@ -51,6 +51,8 @@ public:
 
     QString author() const;
     QString authorId() const;
+    QString expiry() const;
+    QString pins() const;
 
     static bool isSupported();
 
diff --git a/src/plugins/qnx/blackberrydebugtokenrequester.cpp b/src/plugins/qnx/blackberrydebugtokenrequester.cpp
index bb0ad8f07ae431e78c58fcb0c0da82aea8befbd9..1e693f6266f20eeafda72d4ca0429a4040140b55 100644
--- a/src/plugins/qnx/blackberrydebugtokenrequester.cpp
+++ b/src/plugins/qnx/blackberrydebugtokenrequester.cpp
@@ -56,8 +56,8 @@ BlackBerryDebugTokenRequester::BlackBerryDebugTokenRequester(QObject *parent) :
 }
 
 void BlackBerryDebugTokenRequester::requestDebugToken(const QString &path,
-        const QString &cskPassword, const QString &keyStore,
-        const QString &keyStorePassword, const QString &devicePin)
+                                                      const QString &cskPassword, const QString &keyStore,
+                                                      const QString &keyStorePassword, const QString &devicePin)
 {
     QStringList arguments;
 
@@ -66,10 +66,14 @@ void BlackBerryDebugTokenRequester::requestDebugToken(const QString &path,
               << QLatin1String("-storepass")
               << keyStorePassword
               << QLatin1String("-cskpass")
-              << cskPassword
-              << QLatin1String("-devicepin")
-              << devicePin
-              << path;
+              << cskPassword;
+
+    // devicePin may contain multiple pins
+    QStringList pins = devicePin.split(QLatin1Char(','));
+    foreach (const QString &pin, pins)
+        arguments << QLatin1String("-devicepin") << pin;
+
+    arguments << path;
 
     start(arguments);
 
diff --git a/src/plugins/qnx/blackberrydeviceconfigurationwidget.cpp b/src/plugins/qnx/blackberrydeviceconfigurationwidget.cpp
index 645b7ab82aa017393a470fc037648264e8d819b6..4aa2d4fe105cb04db525446016d7b6325ffaaaa8 100644
--- a/src/plugins/qnx/blackberrydeviceconfigurationwidget.cpp
+++ b/src/plugins/qnx/blackberrydeviceconfigurationwidget.cpp
@@ -35,6 +35,7 @@
 #include "ui_blackberrydeviceconfigurationwidget.h"
 #include "blackberryconfiguration.h"
 #include "blackberrydeviceconnectionmanager.h"
+#include "blackberrysigningutils.h"
 #include "qnxconstants.h"
 #include "qnxutils.h"
 
@@ -57,20 +58,22 @@ BlackBerryDeviceConfigurationWidget::BlackBerryDeviceConfigurationWidget(const I
     IDeviceWidget(device, parent),
     ui(new Ui::BlackBerryDeviceConfigurationWidget),
     progressDialog(new QProgressDialog(this)),
-    uploader(new BlackBerryDebugTokenUploader(this))
+    uploader(new BlackBerryDebugTokenUploader(this)),
+    m_utils(BlackBerrySigningUtils::instance())
 {
     ui->setupUi(this);
 
     ui->connectionLog->setFont(TextEditor::TextEditorSettings::fontSettings().font());
 
+    populateDebugTokenCombo(deviceConfiguration()->debugToken());
+
     connect(ui->hostLineEdit, SIGNAL(editingFinished()), this, SLOT(hostNameEditingFinished()));
     connect(ui->pwdLineEdit, SIGNAL(editingFinished()), this, SLOT(passwordEditingFinished()));
     connect(ui->keyFileLineEdit, SIGNAL(editingFinished()), this, SLOT(keyFileEditingFinished()));
     connect(ui->keyFileLineEdit, SIGNAL(browsingFinished()), this, SLOT(keyFileEditingFinished()));
     connect(ui->showPasswordCheckBox, SIGNAL(toggled(bool)), this, SLOT(showPassword(bool)));
-    connect(ui->debugToken, SIGNAL(changed(QString)), this, SLOT(updateUploadButton()));
-    connect(ui->debugToken, SIGNAL(editingFinished()), this, SLOT(debugTokenEditingFinished()));
-    connect(ui->debugToken, SIGNAL(browsingFinished()), this, SLOT(debugTokenEditingFinished()));
+    connect(ui->debugToken, SIGNAL(currentTextChanged(QString)), this, SLOT(updateUploadButton()));
+    connect(ui->debugToken, SIGNAL(currentTextChanged(QString)), this, SLOT(debugTokenEditingFinished()));
     connect(uploader, SIGNAL(finished(int)), this, SLOT(uploadFinished(int)));
 
     connect(BlackBerryDeviceConnectionManager::instance(), SIGNAL(connectionOutput(Core::Id,QString)),
@@ -81,16 +84,14 @@ BlackBerryDeviceConfigurationWidget::BlackBerryDeviceConfigurationWidget(const I
     connect(ui->requestButton, SIGNAL(clicked()), this, SLOT(requestDebugToken()));
     connect(ui->uploadButton, SIGNAL(clicked()), this, SLOT(uploadDebugToken()));
 
-    QString debugTokenBrowsePath = QnxUtils::dataDirPath();
-    if (!QFileInfo(debugTokenBrowsePath).exists())
-        debugTokenBrowsePath = QDir::homePath();
-    ui->debugToken->setInitialBrowsePathBackup(debugTokenBrowsePath);
+    connect(&m_utils, SIGNAL(debugTokenListChanged()), this, SLOT(updateDebugTokenCombo()));
 
     initGui();
 }
 
 BlackBerryDeviceConfigurationWidget::~BlackBerryDeviceConfigurationWidget()
 {
+    m_utils.saveDebugTokens();
     delete ui;
 }
 
@@ -123,7 +124,7 @@ void BlackBerryDeviceConfigurationWidget::showPassword(bool showClearText)
 
 void BlackBerryDeviceConfigurationWidget::debugTokenEditingFinished()
 {
-    deviceConfiguration()->setDebugToken(ui->debugToken->path());
+    deviceConfiguration()->setDebugToken(ui->debugToken->currentText());
 }
 
 void BlackBerryDeviceConfigurationWidget::requestDebugToken()
@@ -138,27 +139,29 @@ void BlackBerryDeviceConfigurationWidget::requestDebugToken()
     if (result != QDialog::Accepted)
         return;
 
-    ui->debugToken->setPath(dialog.debugToken());
+    m_utils.addDebugToken(dialog.debugToken());
+    populateDebugTokenCombo(dialog.debugToken());
     debugTokenEditingFinished();
 }
 
 void BlackBerryDeviceConfigurationWidget::uploadDebugToken()
 {
     // check the debug token path before even laucnhing the uploader process
-    if (!QFileInfo(ui->debugToken->fileName().toString()).exists()) {
+    if (!QFileInfo(ui->debugToken->currentText()).exists()) {
         QMessageBox::critical(this, tr("Error"), tr("Invalid debug token path."));
         return;
     }
 
     progressDialog->show();
 
-    uploader->uploadDebugToken(ui->debugToken->path(),
+    uploader->uploadDebugToken(ui->debugToken->currentText(),
             ui->hostLineEdit->text(), ui->pwdLineEdit->text());
 }
 
 void BlackBerryDeviceConfigurationWidget::updateUploadButton()
 {
-    ui->uploadButton->setEnabled(!ui->debugToken->path().isEmpty());
+    const QString path = ui->debugToken->currentText();
+    ui->uploadButton->setEnabled(QFileInfo(path).exists());
 }
 
 void BlackBerryDeviceConfigurationWidget::uploadFinished(int status)
@@ -213,6 +216,20 @@ void BlackBerryDeviceConfigurationWidget::clearConnectionLog(Core::Id deviceId)
         ui->connectionLog->clear();
 }
 
+void BlackBerryDeviceConfigurationWidget::populateDebugTokenCombo(const QString& current)
+{
+    ui->debugToken->clear();
+    ui->debugToken->addItems(m_utils.debugTokens());
+    const int index = ui->debugToken->findText(current);
+    if (index != -1)
+        ui->debugToken->setCurrentIndex(index);
+}
+
+void BlackBerryDeviceConfigurationWidget::updateDebugTokenCombo()
+{
+    populateDebugTokenCombo(ui->debugToken->currentText());
+}
+
 void BlackBerryDeviceConfigurationWidget::updateDeviceFromUi()
 {
     hostNameEditingFinished();
@@ -223,9 +240,6 @@ void BlackBerryDeviceConfigurationWidget::updateDeviceFromUi()
 
 void BlackBerryDeviceConfigurationWidget::initGui()
 {
-    ui->debugToken->setExpectedKind(Utils::PathChooser::File);
-    ui->debugToken->setPromptDialogFilter(QLatin1String("*.bar"));
-
     ui->keyFileLineEdit->setExpectedKind(Utils::PathChooser::File);
     ui->keyFileLineEdit->lineEdit()->setMinimumWidth(0);
 
@@ -237,8 +251,6 @@ void BlackBerryDeviceConfigurationWidget::initGui()
     ui->pwdLineEdit->setText(sshParams.password);
     ui->keyFileLineEdit->setPath(sshParams.privateKeyFile);
     ui->showPasswordCheckBox->setChecked(false);
-    ui->debugToken->setPath(deviceConfiguration()->debugToken());
-
     if (deviceConfiguration()->machineType() == IDevice::Emulator) {
         ui->debugToken->setEnabled(false);
         ui->requestButton->setEnabled(false);
diff --git a/src/plugins/qnx/blackberrydeviceconfigurationwidget.h b/src/plugins/qnx/blackberrydeviceconfigurationwidget.h
index cef355f260623e6b64967016d503bee7d425f61d..e0950b6ac3b9943158800e47d02b77970d31176f 100644
--- a/src/plugins/qnx/blackberrydeviceconfigurationwidget.h
+++ b/src/plugins/qnx/blackberrydeviceconfigurationwidget.h
@@ -45,6 +45,7 @@ namespace Qnx {
 namespace Internal {
 
 class BlackBerryDebugTokenUploader;
+class BlackBerrySigningUtils;
 
 namespace Ui {
 class BlackBerryDeviceConfigurationWidget;
@@ -71,6 +72,8 @@ private slots:
     void uploadFinished(int status);
     void appendConnectionLog(Core::Id deviceId, const QString &line);
     void clearConnectionLog(Core::Id deviceId);
+    void populateDebugTokenCombo(const QString &current);
+    void updateDebugTokenCombo();
 
 private:
     void updateDeviceFromUi();
@@ -84,6 +87,7 @@ private:
     QProgressDialog *progressDialog;
 
     BlackBerryDebugTokenUploader *uploader;
+    BlackBerrySigningUtils &m_utils;
 };
 
 
diff --git a/src/plugins/qnx/blackberrydeviceconfigurationwidget.ui b/src/plugins/qnx/blackberrydeviceconfigurationwidget.ui
index b2c905f322a64158a048097b3288202655ec4fb6..46ea60a3f7e9cf40bd917a76f15acc07e638d99b 100644
--- a/src/plugins/qnx/blackberrydeviceconfigurationwidget.ui
+++ b/src/plugins/qnx/blackberrydeviceconfigurationwidget.ui
@@ -14,16 +14,7 @@
    <property name="fieldGrowthPolicy">
     <enum>QFormLayout::AllNonFixedFieldsGrow</enum>
    </property>
-   <property name="leftMargin">
-    <number>0</number>
-   </property>
-   <property name="topMargin">
-    <number>0</number>
-   </property>
-   <property name="rightMargin">
-    <number>0</number>
-   </property>
-   <property name="bottomMargin">
+   <property name="margin">
     <number>0</number>
    </property>
    <item row="0" column="0">
@@ -76,14 +67,8 @@
      <property name="text">
       <string>Debug token:</string>
      </property>
-     <property name="buddy">
-      <cstring>debugToken</cstring>
-     </property>
     </widget>
    </item>
-   <item row="2" column="1">
-    <widget class="Utils::PathChooser" name="debugToken" native="true"/>
-   </item>
    <item row="5" column="0">
     <widget class="QLabel" name="keyLabel">
      <property name="text">
@@ -145,8 +130,14 @@
      </item>
     </layout>
    </item>
+   <item row="2" column="1">
+    <widget class="QComboBox" name="debugToken">
+     <property name="editable">
+      <bool>true</bool>
+     </property>
+    </widget>
+   </item>
   </layout>
-  <zorder>debugToken</zorder>
   <zorder>keyFileLineEdit</zorder>
   <zorder>hostNameLabel</zorder>
   <zorder>hostLineEdit</zorder>
@@ -155,6 +146,7 @@
   <zorder>debugTokenLabel</zorder>
   <zorder>label</zorder>
   <zorder>connectionLog</zorder>
+  <zorder>debugToken</zorder>
  </widget>
  <customwidgets>
   <customwidget>
diff --git a/src/plugins/qnx/blackberrydeviceconfigurationwizardconfigpage.ui b/src/plugins/qnx/blackberrydeviceconfigurationwizardconfigpage.ui
index 386882cbc3c0845fddcb1f646bd131e1557e622a..74afa809d3817d9b57d35049ba88ea84746f586f 100644
--- a/src/plugins/qnx/blackberrydeviceconfigurationwizardconfigpage.ui
+++ b/src/plugins/qnx/blackberrydeviceconfigurationwizardconfigpage.ui
@@ -35,13 +35,16 @@
        </widget>
       </item>
       <item row="2" column="1">
-       <widget class="Utils::PathChooser" name="debugTokenField" native="true">
+       <widget class="QComboBox" name="debugTokenCombo">
         <property name="sizePolicy">
          <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
           <horstretch>0</horstretch>
           <verstretch>0</verstretch>
          </sizepolicy>
         </property>
+        <property name="editable">
+         <bool>true</bool>
+        </property>
        </widget>
       </item>
       <item row="4" column="0" colspan="3">
@@ -139,18 +142,6 @@
    </item>
   </layout>
  </widget>
- <customwidgets>
-  <customwidget>
-   <class>Utils::PathChooser</class>
-   <extends>QWidget</extends>
-   <header location="global">utils/pathchooser.h</header>
-   <container>1</container>
-   <slots>
-    <signal>editingFinished()</signal>
-    <signal>browsingFinished()</signal>
-   </slots>
-  </customwidget>
- </customwidgets>
  <tabstops>
   <tabstop>generateButton</tabstop>
  </tabstops>
diff --git a/src/plugins/qnx/blackberrydeviceconfigurationwizardpages.cpp b/src/plugins/qnx/blackberrydeviceconfigurationwizardpages.cpp
index d338747a539889e640d7b14512e89dc5c55a1ea7..62b70f1c2a5587568004a977d1ccf3b842ed1d82 100644
--- a/src/plugins/qnx/blackberrydeviceconfigurationwizardpages.cpp
+++ b/src/plugins/qnx/blackberrydeviceconfigurationwizardpages.cpp
@@ -39,6 +39,7 @@
 #include "ui_blackberrydeviceconfigurationwizardconfigpage.h"
 #include "blackberryconfiguration.h"
 #include "blackberrydeviceconnectionmanager.h"
+#include "blackberrysigningutils.h"
 #include "qnxutils.h"
 
 #include <coreplugin/icore.h>
@@ -353,24 +354,19 @@ BlackBerryDeviceConfigurationWizardConfigPage::BlackBerryDeviceConfigurationWiza
     : QWizardPage(parent)
     , m_ui(new Ui::BlackBerryDeviceConfigurationWizardConfigPage)
     , m_holder(holder)
+    , m_utils(BlackBerrySigningUtils::instance())
 {
     m_ui->setupUi(this);
     setTitle(tr("Configuration"));
 
-    m_ui->debugTokenField->setExpectedKind(Utils::PathChooser::File);
-    m_ui->debugTokenField->setPromptDialogFilter(QLatin1String("*.bar"));
-
-    QString debugTokenBrowsePath = QnxUtils::dataDirPath();
-    if (!QFileInfo(debugTokenBrowsePath).exists())
-        debugTokenBrowsePath = QDir::homePath();
-    m_ui->debugTokenField->setInitialBrowsePathBackup(debugTokenBrowsePath);
+    m_ui->debugTokenCombo->addItems(m_utils.debugTokens());
 
     connect(m_ui->configurationNameField, SIGNAL(textChanged(QString)), this, SIGNAL(completeChanged()));
-    connect(m_ui->debugTokenField, SIGNAL(changed(QString)), this, SIGNAL(completeChanged()));
+    connect(m_ui->debugTokenCombo, SIGNAL(currentTextChanged(QString)), this, SIGNAL(completeChanged()));
     connect(m_ui->generateButton, SIGNAL(clicked()), this, SLOT(generateDebugToken()));
 
     registerField(QLatin1String(CONFIGURATIONNAME_FIELD_ID), m_ui->configurationNameField);
-    registerField(QLatin1String(DEBUGTOKENPATH_FIELD_ID), m_ui->debugTokenField);
+    registerField(QLatin1String(DEBUGTOKENPATH_FIELD_ID), m_ui->debugTokenCombo);
 }
 
 BlackBerryDeviceConfigurationWizardConfigPage::~BlackBerryDeviceConfigurationWizardConfigPage()
@@ -385,16 +381,16 @@ void BlackBerryDeviceConfigurationWizardConfigPage::initializePage()
     m_ui->configurationNameField->setText(m_holder.deviceName);
     m_ui->deviceHostNameField->setText(deviceHostName);
     m_ui->deviceTypeField->setText(QLatin1String (m_holder.isSimulator ? "Simulator" : "Device"));
-    m_ui->debugTokenField->setEnabled(!m_holder.isSimulator);
+    m_ui->debugTokenCombo->setEnabled(!m_holder.isSimulator);
     m_ui->generateButton->setEnabled(!m_holder.isSimulator);
 }
 
 bool BlackBerryDeviceConfigurationWizardConfigPage::isComplete() const
 {
     bool configurationNameComplete = !m_ui->configurationNameField->text().isEmpty();
-    Utils::FileName fileName = m_ui->debugTokenField->fileName();
+    Utils::FileName fileName = Utils::FileName::fromString(m_ui->debugTokenCombo->currentText());
     bool debugTokenComplete = m_holder.isSimulator || !m_holder.isProductionDevice
-            || (!fileName.isEmpty() && QFileInfo(fileName.toString()).exists());
+            || (!fileName.isEmpty() && fileName.toFileInfo().exists());
 
     return configurationNameComplete  &&  debugTokenComplete;
 }
@@ -409,7 +405,8 @@ void BlackBerryDeviceConfigurationWizardConfigPage::generateDebugToken()
     if (result != QDialog::Accepted)
         return;
 
-    m_ui->debugTokenField->setPath(dialog.debugToken());
+    m_utils.addDebugToken(dialog.debugToken());
+    m_ui->debugTokenCombo->addItem(dialog.debugToken());
 }
 
 QString BlackBerryDeviceConfigurationWizardConfigPage::configurationName() const
@@ -419,7 +416,7 @@ QString BlackBerryDeviceConfigurationWizardConfigPage::configurationName() const
 
 QString BlackBerryDeviceConfigurationWizardConfigPage::debugToken() const
 {
-    return m_ui->debugTokenField->fileName().toString();
+    return m_ui->debugTokenCombo->currentText();
 }
 
 // ----------------------------------------------------------------------------
diff --git a/src/plugins/qnx/blackberrydeviceconfigurationwizardpages.h b/src/plugins/qnx/blackberrydeviceconfigurationwizardpages.h
index e40853d219e9dde51b9df23c0606a832a0cc4011..c736374479937516c5dae33f9b2e2f72eedbbe34 100644
--- a/src/plugins/qnx/blackberrydeviceconfigurationwizardpages.h
+++ b/src/plugins/qnx/blackberrydeviceconfigurationwizardpages.h
@@ -52,6 +52,7 @@ class BlackBerryDeviceConfigurationWizardConfigPage;
 }
 class BlackBerrySshKeysGenerator;
 class BlackBerryDeviceInformation;
+class BlackBerrySigningUtils;
 
 struct BlackBerryDeviceConfigurationWizardHolder {
     QString devicePin;
@@ -149,6 +150,7 @@ private slots:
 private:
     Ui::BlackBerryDeviceConfigurationWizardConfigPage *m_ui;
     BlackBerryDeviceConfigurationWizardHolder &m_holder;
+    BlackBerrySigningUtils &m_utils;
 };
 
 class BlackBerryDeviceConfigurationWizardFinalPage : public QWizardPage
diff --git a/src/plugins/qnx/blackberrykeyspage.cpp b/src/plugins/qnx/blackberrykeyspage.cpp
index f0435a8ffb5d44391c8fcec09d1a3fe80c958de1..97a0cf3ea7aa81684201428fc08b5d9a5b76bfe6 100644
--- a/src/plugins/qnx/blackberrykeyspage.cpp
+++ b/src/plugins/qnx/blackberrykeyspage.cpp
@@ -60,6 +60,7 @@ QWidget *BlackBerryKeysPage::widget()
 
 void BlackBerryKeysPage::apply()
 {
+    m_widget->saveSettings();
 }
 
 void BlackBerryKeysPage::finish()
diff --git a/src/plugins/qnx/blackberrykeyswidget.cpp b/src/plugins/qnx/blackberrykeyswidget.cpp
index 8c5f6d22e291ad495ddce0aef133f5b65cf3faa1..3455454c90981dd8c84a426272e7cc0d03b4ee3c 100644
--- a/src/plugins/qnx/blackberrykeyswidget.cpp
+++ b/src/plugins/qnx/blackberrykeyswidget.cpp
@@ -34,24 +34,39 @@
 #include "blackberrycertificate.h"
 #include "blackberrysigningutils.h"
 #include "blackberrycreatecertificatedialog.h"
+#include "blackberrydebugtokenreader.h"
+#include "blackberrydebugtokenpinsdialog.h"
+#include "blackberrydebugtokenrequester.h"
+#include "blackberrydebugtokenrequestdialog.h"
 #include "ui_blackberrykeyswidget.h"
 
 #include <QInputDialog>
+#include <QFileDialog>
 #include <QMessageBox>
 
+#include <QStandardItemModel>
+#include <QTreeWidgetItem>
+
 namespace Qnx {
 namespace Internal {
 
 BlackBerryKeysWidget::BlackBerryKeysWidget(QWidget *parent) :
     QWidget(parent),
     m_utils(BlackBerrySigningUtils::instance()),
-    m_ui(new Ui_BlackBerryKeysWidget)
+    m_ui(new Ui_BlackBerryKeysWidget),
+    m_dtModel(new QStandardItemModel(this)),
+    m_requester(new BlackBerryDebugTokenRequester(this))
 {
     m_ui->setupUi(this);
     m_ui->keyStatus->setTextFormat(Qt::RichText);
     m_ui->keyStatus->setTextInteractionFlags(Qt::TextBrowserInteraction);
     m_ui->keyStatus->setOpenExternalLinks(true);
     m_ui->openCertificateButton->setVisible(false);
+    m_ui->editDbTkButton->setEnabled(false);
+    m_ui->removeDbTkButton->setEnabled(false);
+    m_ui->debugTokens->setModel(m_dtModel);
+
+    updateDebugTokenList();
 
     connect(m_ui->createCertificateButton, SIGNAL(clicked()),
             this, SLOT(createCertificate()));
@@ -59,6 +74,33 @@ BlackBerryKeysWidget::BlackBerryKeysWidget(QWidget *parent) :
             this, SLOT(clearCertificate()));
     connect(m_ui->openCertificateButton, SIGNAL(clicked()),
             this, SLOT(loadDefaultCertificate()));
+    connect(m_ui->requestDbTkButton, SIGNAL(clicked()),
+            this, SLOT(requestDebugToken()));
+    connect(m_ui->importDbTkButton, SIGNAL(clicked()),
+            this, SLOT(importDebugToken()));
+    connect(m_ui->editDbTkButton, SIGNAL(clicked()),
+            this, SLOT(editDebugToken()));
+    connect(m_ui->removeDbTkButton, SIGNAL(clicked()),
+            this, SLOT(removeDebugToken()));
+    connect(m_requester, SIGNAL(finished(int)),
+            this, SLOT(requestFinished(int)));
+    connect(m_ui->debugTokens, SIGNAL(pressed(QModelIndex)),
+            this, SLOT(updateUi(QModelIndex)));
+    connect(&m_utils, SIGNAL(debugTokenListChanged()),
+            this, SLOT(updateDebugTokenList()));
+}
+
+void BlackBerryKeysWidget::saveSettings()
+{
+    m_utils.saveDebugTokens();
+}
+
+void BlackBerryKeysWidget::initModel()
+{
+    m_dtModel->clear();
+    QStringList headers;
+    headers << tr("Path") << tr("Author") << tr("PINs") << tr("Expiry");
+    m_dtModel->setHorizontalHeaderLabels(headers);
 }
 
 void BlackBerryKeysWidget::certificateLoaded(int status)
@@ -93,7 +135,7 @@ void BlackBerryKeysWidget::certificateLoaded(int status)
 
 void BlackBerryKeysWidget::createCertificate()
 {
-    BlackBerryCreateCertificateDialog dialog;
+    BlackBerryCreateCertificateDialog dialog(this);
 
     const int result = dialog.exec();
 
@@ -172,6 +214,153 @@ void BlackBerryKeysWidget::loadDefaultCertificate()
     m_utils.openDefaultCertificate(this);
 }
 
+void BlackBerryKeysWidget::updateDebugTokenList()
+{
+    initModel();
+    foreach (const QString &dt, m_utils.debugTokens()) {
+        QList<QStandardItem*> row;
+        BlackBerryDebugTokenReader debugTokenReader(dt);
+        if (!debugTokenReader.isValid())
+            continue;
+
+        row << new QStandardItem(dt);
+        row << new QStandardItem(debugTokenReader.author());
+        row << new QStandardItem(debugTokenReader.pins());
+        row << new QStandardItem(debugTokenReader.expiry());
+        m_dtModel->appendRow(row);
+    }
+
+    m_ui->debugTokens->header()->resizeSections(QHeaderView::ResizeToContents);
+}
+
+void BlackBerryKeysWidget::requestDebugToken()
+{
+    BlackBerryDebugTokenRequestDialog dialog(this);
+    if (dialog.exec() != QDialog::Accepted)
+        return;
+
+    m_utils.addDebugToken(dialog.debugToken());
+}
+
+void BlackBerryKeysWidget::importDebugToken()
+{
+    const QString debugToken = QFileDialog::getOpenFileName(this, tr("Select Debug Token"),
+                                                            QString(), tr("Bar file (*.bar)"));
+    if (debugToken.isEmpty())
+        return;
+
+    BlackBerryDebugTokenReader debugTokenReader(debugToken);
+    if (!debugTokenReader.isValid()) {
+        QMessageBox::warning(this, tr("Invalid Debug Token"),
+                             tr("Debug token file %1 cannot be read.").arg(debugToken));
+        return;
+    }
+
+    m_utils.addDebugToken(debugToken);
+}
+
+void BlackBerryKeysWidget::editDebugToken()
+{
+    const QModelIndex index = m_ui->debugTokens->currentIndex();
+    if (!index.isValid())
+        return;
+
+    QString pins = m_dtModel->item(index.row(), 0)->text();
+
+    BlackBerryDebugTokenPinsDialog dialog(pins, this);
+    connect(&dialog, SIGNAL(pinsUpdated(QStringList)), this, SLOT(updateDebugToken(QStringList)));
+    dialog.exec();
+}
+
+void BlackBerryKeysWidget::removeDebugToken()
+{
+    const QModelIndex index = m_ui->debugTokens->currentIndex();
+    if (!index.isValid())
+        return;
+
+    const QString dt = m_dtModel->item(index.row(), 0)->text();
+    const int result = QMessageBox::question(this, tr("Confirmation"),
+            tr("Are you sure you want to remove %1?")
+            .arg(dt), QMessageBox::Yes | QMessageBox::No);
+
+    if (result == QMessageBox::Yes)
+        m_utils.removeDebugToken(dt);
+}
+
+void BlackBerryKeysWidget::updateDebugToken(const QStringList &pins)
+{
+    BlackBerryConfigurationManager &configuration = BlackBerryConfigurationManager::instance();
+
+    bool ok;
+    const QString cskPassword = m_utils.cskPassword(this, &ok);
+    if (!ok)
+        return;
+
+    const QString certificatePassword = m_utils.certificatePassword(this, &ok);
+    if (!ok)
+        return;
+
+    const QString debugTokenPath = m_dtModel->item(m_ui->debugTokens->currentIndex().row(), 0)->text();
+    m_requester->requestDebugToken(debugTokenPath,
+                                   cskPassword, configuration.defaultKeystorePath(),
+                                   certificatePassword, pins.join(QLatin1Char(',')));
+}
+
+void BlackBerryKeysWidget::requestFinished(int status)
+{
+    QString errorString = tr("Failed to request debug token:") + QLatin1Char(' ');
+
+    switch (status) {
+    case BlackBerryDebugTokenRequester::Success:
+        updateDebugTokenList();
+        return;
+    case BlackBerryDebugTokenRequester::WrongCskPassword:
+        m_utils.clearCskPassword();
+        errorString += tr("Wrong CSK password.");
+        break;
+    case BlackBerryDebugTokenRequester::WrongKeystorePassword:
+        m_utils.clearCertificatePassword();
+        errorString += tr("Wrong keystore password.");
+        break;
+    case BlackBerryDebugTokenRequester::NetworkUnreachable:
+        errorString += tr("Network unreachable.");
+        break;
+    case BlackBerryDebugTokenRequester::IllegalPin:
+        errorString += tr("Illegal device PIN.");
+        break;
+    case BlackBerryDebugTokenRequester::FailedToStartInferiorProcess:
+        errorString += tr("Failed to start inferior process.");
+        break;
+    case BlackBerryDebugTokenRequester::InferiorProcessTimedOut:
+        errorString += tr("Inferior processes timed out.");
+        break;
+    case BlackBerryDebugTokenRequester::InferiorProcessCrashed:
+        errorString += tr("Inferior process has crashed.");
+        break;
+    case BlackBerryDebugTokenRequester::InferiorProcessReadError:
+    case BlackBerryDebugTokenRequester::InferiorProcessWriteError:
+        errorString += tr("Failed to communicate with the inferior process.");
+        break;
+    case BlackBerryDebugTokenRequester::NotYetRegistered:
+        errorString += tr("Not yet registered to request debug tokens.");
+        break;
+    case BlackBerryDebugTokenRequester::UnknownError:
+    default:
+        m_utils.clearCertificatePassword();
+        m_utils.clearCskPassword();
+        errorString += tr("An unknwon error has occurred.");
+        break;
+    }
+
+    QMessageBox::critical(this, tr("Error"), errorString);
+}
+
+void BlackBerryKeysWidget::updateUi(const QModelIndex &index)
+{
+    m_ui->editDbTkButton->setEnabled(index.isValid());
+    m_ui->removeDbTkButton->setEnabled(index.isValid());
+}
+
 void BlackBerryKeysWidget::setCertificateError(const QString &error)
 {
     m_ui->certificateAuthor->clear();
diff --git a/src/plugins/qnx/blackberrykeyswidget.h b/src/plugins/qnx/blackberrykeyswidget.h
index a61b267c21f65b02dbe0acb531a7f1c634c25dc2..2900e5f506914786710f85b0e302dcc008b67939 100644
--- a/src/plugins/qnx/blackberrykeyswidget.h
+++ b/src/plugins/qnx/blackberrykeyswidget.h
@@ -37,11 +37,16 @@
 #include <QWidget>
 #include <QString>
 
+QT_BEGIN_NAMESPACE
+class QStandardItemModel;
+QT_END_NAMESPACE
+
 namespace Qnx {
 namespace Internal {
 
 class BlackBerryCertificate;
 class BlackBerrySigningUtils;
+class BlackBerryDebugTokenRequester;
 class Ui_BlackBerryKeysWidget;
 
 class BlackBerryKeysWidget : public QWidget
@@ -49,12 +54,22 @@ class BlackBerryKeysWidget : public QWidget
     Q_OBJECT
 public:
     explicit BlackBerryKeysWidget(QWidget *parent = 0);
+    void saveSettings();
 
 private slots:
     void certificateLoaded(int status);
     void createCertificate();
     void clearCertificate();
     void loadDefaultCertificate();
+    void updateDebugTokenList();
+
+    void requestDebugToken();
+    void importDebugToken();
+    void editDebugToken();
+    void removeDebugToken();
+    void updateDebugToken(const QStringList &pins);
+    void requestFinished(int status);
+    void updateUi(const QModelIndex &index);
 
 protected:
     void showEvent(QShowEvent *event);
@@ -64,10 +79,13 @@ private:
     void updateCertificateSection();
     void setCertificateError(const QString &error);
     void setCreateCertificateVisible(bool show);
+    void initModel();
 
     BlackBerrySigningUtils &m_utils;
 
     Ui_BlackBerryKeysWidget *m_ui;
+    QStandardItemModel *m_dtModel;
+    BlackBerryDebugTokenRequester *m_requester;
 };
 
 } // namespace Internal
diff --git a/src/plugins/qnx/blackberrykeyswidget.ui b/src/plugins/qnx/blackberrykeyswidget.ui
index 7d1db06b974155a0c4048c6bce15863399c5d74c..e26614626e8f4e676724fc94917b32ef3ab24156 100644
--- a/src/plugins/qnx/blackberrykeyswidget.ui
+++ b/src/plugins/qnx/blackberrykeyswidget.ui
@@ -7,7 +7,7 @@
     <x>0</x>
     <y>0</y>
     <width>959</width>
-    <height>390</height>
+    <height>703</height>
    </rect>
   </property>
   <property name="windowTitle">
@@ -180,17 +180,72 @@
     </widget>
    </item>
    <item>
-    <spacer name="verticalSpacer">
-     <property name="orientation">
-      <enum>Qt::Vertical</enum>
-     </property>
-     <property name="sizeHint" stdset="0">
-      <size>
-       <width>20</width>
-       <height>207</height>
-      </size>
+    <widget class="QGroupBox" name="groupBox_3">
+     <property name="title">
+      <string>Debug Tokens</string>
      </property>
-    </spacer>
+     <layout class="QHBoxLayout" name="horizontalLayout_4">
+      <item>
+       <layout class="QHBoxLayout" name="horizontalLayout_3">
+        <item>
+         <widget class="QTreeView" name="debugTokens">
+          <property name="editTriggers">
+           <set>QAbstractItemView::NoEditTriggers</set>
+          </property>
+          <property name="selectionMode">
+           <enum>QAbstractItemView::ExtendedSelection</enum>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <layout class="QVBoxLayout" name="verticalLayout_3">
+          <item>
+           <widget class="QPushButton" name="requestDbTkButton">
+            <property name="text">
+             <string>Request</string>
+            </property>
+           </widget>
+          </item>
+          <item>
+           <widget class="QPushButton" name="importDbTkButton">
+            <property name="text">
+             <string>Import</string>
+            </property>
+           </widget>
+          </item>
+          <item>
+           <widget class="QPushButton" name="editDbTkButton">
+            <property name="text">
+             <string>Edit</string>
+            </property>
+           </widget>
+          </item>
+          <item>
+           <widget class="QPushButton" name="removeDbTkButton">
+            <property name="text">
+             <string>Remove</string>
+            </property>
+           </widget>
+          </item>
+          <item>
+           <spacer name="verticalSpacer">
+            <property name="orientation">
+             <enum>Qt::Vertical</enum>
+            </property>
+            <property name="sizeHint" stdset="0">
+             <size>
+              <width>20</width>
+              <height>40</height>
+             </size>
+            </property>
+           </spacer>
+          </item>
+         </layout>
+        </item>
+       </layout>
+      </item>
+     </layout>
+    </widget>
    </item>
   </layout>
  </widget>
diff --git a/src/plugins/qnx/blackberrysigningutils.cpp b/src/plugins/qnx/blackberrysigningutils.cpp
index c642e67763fbedd4ca5c7928914b806059e0d40f..f230c86b8afecc12b4b1e3080157424da5040c2d 100644
--- a/src/plugins/qnx/blackberrysigningutils.cpp
+++ b/src/plugins/qnx/blackberrysigningutils.cpp
@@ -33,6 +33,9 @@
 #include "blackberrycertificate.h"
 #include "blackberryconfiguration.h"
 #include "blackberryconfigurationmanager.h"
+#include "blackberrydebugtokenreader.h"
+
+#include <coreplugin/icore.h>
 
 #include <QFileInfo>
 #include <QString>
@@ -42,6 +45,11 @@
 
 using namespace Qnx::Internal;
 
+namespace {
+const QLatin1String DebugTokensGroup("DebugTokens");
+const QLatin1String DebugTokensPath("DebugTokenPath");
+}
+
 BlackBerrySigningUtils & BlackBerrySigningUtils::instance()
 {
     static BlackBerrySigningUtils utils;
@@ -53,6 +61,7 @@ BlackBerrySigningUtils::BlackBerrySigningUtils(QObject *parent) :
     QObject(parent),
     m_defaultCertificate(0)
 {
+    loadDebugTokens();
 }
 
 bool BlackBerrySigningUtils::hasRegisteredKeys()
@@ -163,6 +172,26 @@ void BlackBerrySigningUtils::deleteDefaultCertificate()
     QFile::remove(configuration.defaultKeystorePath());
 }
 
+QStringList BlackBerrySigningUtils::debugTokens() const
+{
+    return m_debugTokens;
+}
+
+void BlackBerrySigningUtils::addDebugToken(const QString &dt)
+{
+    if (m_debugTokens.contains(dt) || !QFileInfo(dt).exists())
+        return;
+
+    m_debugTokens << dt;
+    emit debugTokenListChanged();
+}
+
+void BlackBerrySigningUtils::removeDebugToken(const QString &dt)
+{
+    m_debugTokens.removeOne(dt);
+    emit debugTokenListChanged();
+}
+
 void BlackBerrySigningUtils::certificateLoaded(int status)
 {
     if (status != BlackBerryCertificate::Success) {
@@ -176,6 +205,38 @@ void BlackBerrySigningUtils::certificateLoaded(int status)
     emit defaultCertificateLoaded(status);
 }
 
+void BlackBerrySigningUtils::saveDebugTokens()
+{
+    if (m_debugTokens.isEmpty())
+        return;
+
+    QSettings *settings = Core::ICore::settings();
+    settings->beginGroup(DebugTokensGroup);
+
+    int count = 0;
+    foreach (QString dt, m_debugTokens) {
+        settings->beginGroup(QString::fromLatin1("debugToken_%1").arg(++count));
+        settings->setValue(DebugTokensPath, dt);
+        settings->endGroup();
+    }
+
+    settings->endGroup();
+}
+
+void BlackBerrySigningUtils::loadDebugTokens()
+{
+    QSettings *settings = Core::ICore::settings();
+    settings->beginGroup(DebugTokensGroup);
+
+    foreach (const QString &dt, settings->childGroups()) {
+        settings->beginGroup(dt);
+        m_debugTokens << settings->value(DebugTokensPath).toString();
+        settings->endGroup();
+    }
+
+    settings->endGroup();
+}
+
 QString BlackBerrySigningUtils::promptPassword(const QString &message,
                                                QWidget *dialogParent, bool *ok) const
 {
diff --git a/src/plugins/qnx/blackberrysigningutils.h b/src/plugins/qnx/blackberrysigningutils.h
index 388604b4fc1e561d25f51c4ce28ab6c6b35172cf..dad994c097ec7241c0b01c8a81274a8cbd2e6058 100644
--- a/src/plugins/qnx/blackberrysigningutils.h
+++ b/src/plugins/qnx/blackberrysigningutils.h
@@ -34,6 +34,7 @@
 
 #include <QtGlobal>
 #include <QObject>
+#include <QStringList>
 
 QT_BEGIN_NAMESPACE
 class QString;
@@ -65,12 +66,21 @@ public:
     void clearCskPassword();
     void clearCertificatePassword();
     void deleteDefaultCertificate();
+    void addDebugToken(const QString &dt);
+    void removeDebugToken(const QString &dt);
+
+    QStringList debugTokens() const;
 
 signals:
     void defaultCertificateLoaded(int status);
+    void debugTokenListChanged();
+
+public slots:
+    void saveDebugTokens();
 
 private slots:
     void certificateLoaded(int status);
+    void loadDebugTokens();
 
 private:
     Q_DISABLE_COPY(BlackBerrySigningUtils)
@@ -83,6 +93,8 @@ private:
 
     QString m_cskPassword;
     QString m_certificatePassword;
+
+    QStringList m_debugTokens;
 };
 
 } // namespace Internal
diff --git a/src/plugins/qnx/qnx.pro b/src/plugins/qnx/qnx.pro
index 2d8d14afc95cf86952880300cd7749fdc467d7c0..fc2607ba4c75de777fa29d9b208f8d7ba8f2ffd6 100644
--- a/src/plugins/qnx/qnx.pro
+++ b/src/plugins/qnx/qnx.pro
@@ -98,7 +98,8 @@ SOURCES += qnxplugin.cpp \
     qnxdeviceprocesslist.cpp \
     qnxtoolchain.cpp \
     slog2inforunner.cpp \
-    blackberryversionnumber.cpp
+    blackberryversionnumber.cpp \
+    blackberrydebugtokenpinsdialog.cpp
 
 HEADERS += qnxplugin.h\
     qnxconstants.h \
@@ -196,7 +197,8 @@ HEADERS += qnxplugin.h\
     qnxdeviceprocesslist.h \
     qnxtoolchain.h \
     slog2inforunner.h \
-    blackberryversionnumber.h
+    blackberryversionnumber.h \
+    blackberrydebugtokenpinsdialog.h
 
 
 FORMS += \
@@ -228,7 +230,8 @@ FORMS += \
     blackberryinstallwizardtargetpage.ui \
     blackberryinstallwizardndkpage.ui \
     blackberryinstallwizardprocesspage.ui \
-    blackberryinstallwizardoptionpage.ui
+    blackberryinstallwizardoptionpage.ui \
+    blackberrydebugtokenpinsdialog.ui
 
 include(../../private_headers.pri)
 include(./cascadesimport/cascadesimport.pri)
diff --git a/src/plugins/qnx/qnx.qbs b/src/plugins/qnx/qnx.qbs
index 8ee5a8414c34eef12bf8c2986012d57dbce398f4..6ee90f4777b51daa0ce5f78975f50983131a7848 100644
--- a/src/plugins/qnx/qnx.qbs
+++ b/src/plugins/qnx/qnx.qbs
@@ -163,6 +163,9 @@ QtcPlugin {
         "blackberrycreatecertificatedialog.cpp",
         "blackberrycreatecertificatedialog.h",
         "blackberrycreatecertificatedialog.ui",
+        "blackberrydebugtokenpinsdialog.cpp",
+        "blackberrydebugtokenpinsdialog.h",
+        "blackberrydebugtokenpinsdialog.ui",
         "blackberrydebugtokenrequester.cpp",
         "blackberrydebugtokenrequester.h",
         "blackberrydebugtokenrequestdialog.cpp",