diff --git a/MiniZincIDE/MiniZincIDE.pro b/MiniZincIDE/MiniZincIDE.pro
index 3099045..26fa6e7 100644
--- a/MiniZincIDE/MiniZincIDE.pro
+++ b/MiniZincIDE/MiniZincIDE.pro
@@ -4,14 +4,22 @@
 #
 #-------------------------------------------------
 
-QT       += core gui webkitwidgets
+QT       += core gui widgets
 
-greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
+greaterThan(QT_MAJOR_VERSION, 4): {
+  greaterThan(QT_MINOR_VERSION, 5): {
+    QT += webenginewidgets
+    DEFINES += MINIZINC_IDE_HAVE_WEBENGINE
+  }
+  !greaterThan(QT_MINOR_VERSION, 5): {
+    QT += webkitwidgets
+  }
+}
 
 TARGET = MiniZincIDE
 TEMPLATE = app
 
-VERSION = 2.0.13
+VERSION = 2.0.14
 DEFINES += MINIZINC_IDE_VERSION=\\\"$$VERSION\\\"
 
 bundled {
@@ -86,3 +94,6 @@ FORMS    += \
 
 RESOURCES += \
     minizincide.qrc
+
+target.path = /bin
+INSTALLS += target
diff --git a/MiniZincIDE/aboutdialog.ui b/MiniZincIDE/aboutdialog.ui
index 31d51c6..7e34d52 100644
--- a/MiniZincIDE/aboutdialog.ui
+++ b/MiniZincIDE/aboutdialog.ui
@@ -51,8 +51,8 @@
     <string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
 &lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
 p, li { white-space: pre-wrap; }
-&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'.Helvetica Neue DeskInterface'; font-size:13pt; font-weight:400; font-style:normal;&quot;&gt;
-&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:30px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;a href=&quot;http://www.minizinc.org&quot;&gt;&lt;img src=&quot;:/images/mznlogo.png&quot; width=&quot;128&quot; height=&quot;108&quot; /&gt;&lt;/a&gt;&lt;span style=&quot; font-family:'.Lucida Grande UI';&quot;&gt; &lt;/span&gt;&lt;/p&gt;
+&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'.SF NS Text'; font-size:13pt; font-weight:400; font-style:normal;&quot;&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:30px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;a href=&quot;http://www.minizinc.org&quot;&gt;&lt;img src=&quot;:/images/mznicon.png&quot; width=&quot;108&quot; height=&quot;108&quot; /&gt;&lt;/a&gt;&lt;span style=&quot; font-family:'.Lucida Grande UI';&quot;&gt; &lt;/span&gt;&lt;/p&gt;
 &lt;p style=&quot; margin-top:14px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'.Lucida Grande UI'; font-size:large; font-weight:600;&quot;&gt;The MiniZinc IDE&lt;/span&gt;&lt;/p&gt;
 &lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'.Lucida Grande UI';&quot;&gt;Version $VERSION&lt;/span&gt;&lt;/p&gt;
 &lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'.Lucida Grande UI';&quot;&gt;&lt;br /&gt;&lt;/p&gt;
diff --git a/MiniZincIDE/codeeditor.cpp b/MiniZincIDE/codeeditor.cpp
index f83794c..78258a4 100755
--- a/MiniZincIDE/codeeditor.cpp
+++ b/MiniZincIDE/codeeditor.cpp
@@ -129,6 +129,15 @@ void CodeEditor::keyPressEvent(QKeyEvent *e)
         e->accept();
         QTextCursor cursor(textCursor());
         cursor.insertText("  ");
+    } else if (e->key() == Qt::Key_Return) {
+        e->accept();
+        QTextCursor cursor(textCursor());
+        QString curLine = cursor.block().text();
+        QRegExp leadingWhitespace("^(\\s*)");
+        cursor.insertText("\n");
+        if (leadingWhitespace.indexIn(curLine) != -1) {
+            cursor.insertText(leadingWhitespace.cap(1));
+        }
     } else {
         QPlainTextEdit::keyPressEvent(e);
     }
diff --git a/MiniZincIDE/courserasubmission.cpp b/MiniZincIDE/courserasubmission.cpp
index 6e83b65..50b3432 100644
--- a/MiniZincIDE/courserasubmission.cpp
+++ b/MiniZincIDE/courserasubmission.cpp
@@ -11,6 +11,7 @@
 #include <QNetworkReply>
 #include <QUrlQuery>
 #include <QCryptographicHash>
+#include <QJsonDocument>
 
 CourseraSubmission::CourseraSubmission(MainWindow* mw0, CourseraProject& cp) :
     QDialog(NULL), _cur_phase(S_NONE), project(cp), mw(mw0),
@@ -28,7 +29,7 @@ CourseraSubmission::CourseraSubmission(MainWindow* mw0, CourseraProject& cp) :
     for (int i=0; i<project.models.size(); i++) {
         const CourseraItem& item = project.models.at(i);
         QCheckBox* cb = new QCheckBox(item.name);
-        cb->setChecked(false);
+        cb->setChecked(true);
         modelLayout->addWidget(cb);
     }
     for (int i=0; i<project.problems.size(); i++) {
@@ -41,14 +42,17 @@ CourseraSubmission::CourseraSubmission(MainWindow* mw0, CourseraProject& cp) :
         modelLayout->addWidget(new QLabel("none"));
     if (project.problems.empty())
         problemLayout->addWidget(new QLabel("none"));
-    _output_stream.setString(&_submission);
+    _output_stream.setString(&_output_string);
 
     QSettings settings;
     settings.beginGroup("coursera");
     ui->storePassword->setChecked(settings.value("storeLogin",false).toBool());
-    ui->login->setText(settings.value("login").toString());
-    ui->password->setText(settings.value("password").toString());
+    ui->login->setText(settings.value("courseraEmail").toString());
+    settings.beginGroup(project.assignmentKey);
+    ui->password->setText(settings.value("token").toString());
+    settings.endGroup();
     settings.endGroup();
+
 }
 
 CourseraSubmission::~CourseraSubmission()
@@ -58,22 +62,15 @@ CourseraSubmission::~CourseraSubmission()
     bool storeLogin = ui->storePassword->isChecked();
     settings.setValue("storeLogin", storeLogin);
     if (storeLogin) {
-        settings.setValue("login",ui->login->text());
-        settings.setValue("password",ui->password->text());
-    } else {
-        settings.setValue("login","");
-        settings.setValue("password","");
+        settings.setValue("courseraEmail",ui->login->text());
+        settings.beginGroup(project.assignmentKey);
+        settings.setValue("token",ui->password->text());
+        settings.endGroup();
     }
     settings.endGroup();
     delete ui;
 }
 
-QByteArray CourseraSubmission::challenge_response(QString passwd, QString challenge)
-{
-    QByteArray hash = QCryptographicHash::hash(QString(challenge+passwd).toLocal8Bit(), QCryptographicHash::Sha1);
-    return hash.toHex();
-}
-
 void CourseraSubmission::disableUI()
 {
     ui->loginGroup->setEnabled(false);
@@ -95,15 +92,15 @@ void CourseraSubmission::cancelOperation()
     switch (_cur_phase) {
     case S_NONE:
         return;
-    case S_WAIT_CHALLENGE:
-        disconnect(reply, SIGNAL(finished()), this, SLOT(rcv_challenge()));
+    case S_WAIT_PWD:
+        disconnect(mw, SIGNAL(finished()), this, SLOT(rcvLoginCheckResponse()));
         break;
     case S_WAIT_SOLVE:
-        disconnect(mw, SIGNAL(finished()), this, SLOT(solver_finished()));
+        disconnect(mw, SIGNAL(finished()), this, SLOT(solverFinished()));
         mw->on_actionStop_triggered();
         break;
     case S_WAIT_SUBMIT:
-        disconnect(reply, SIGNAL(finished()), this, SLOT(rcv_solution_reply()));
+        disconnect(reply, SIGNAL(finished()), this, SLOT(rcvSubmissionResponse()));
         break;
     }
     ui->textBrowser->insertPlainText("Aborted.\n");
@@ -124,226 +121,202 @@ void CourseraSubmission::reject()
     QDialog::reject();
 }
 
-void CourseraSubmission::on_checkLoginButton_clicked()
-{
-    _current_model = -2;
-    get_challenge();
-}
+void CourseraSubmission::solveNext() {
+    int n_problems = project.problems.size();
 
-void CourseraSubmission::get_challenge()
-{
-    QString email = ui->login->text();
-    if (email.isEmpty()) {
-        QMessageBox::warning(this, "MiniZinc IDE",
-                             "Enter an email address for Coursera login!");
-        _current_model = -2;
-        return;
-    }
-    if (ui->password->text().isEmpty()) {
-        QMessageBox::warning(this, "MiniZinc IDE",
-                             "Enter a password for Coursera login!");
-        _current_model = -2;
+    bool done = false;
+    do {
+        _current_model++;
+        if (_current_model < n_problems) {
+            QCheckBox* cb = qobject_cast<QCheckBox*>(ui->problemBox->layout()->itemAt(_current_model)->widget());
+            done = cb->isChecked();
+        } else {
+            done = true;
+        }
+    } while (!done);
+    if (_current_model < n_problems) {
+
+        CourseraItem& item = project.problems[_current_model];
+        connect(mw, SIGNAL(finished()), this, SLOT(solverFinished()));
+        ui->textBrowser->insertPlainText("Running "+item.name+"\n");
+        _cur_phase = S_WAIT_SOLVE;
+        _output_string = "";
+        mw->addOutput("<div style='color:orange;'>Running Coursera submission "+item.name+"</div><br>\n");
+        if (!mw->runWithOutput(item.model, item.data, item.timeout, _output_stream)) {
+            ui->textBrowser->insertPlainText("Error: could not run "+item.name+"\n");
+            ui->textBrowser->insertPlainText("Skipping.\n");
+            solveNext();
+        }
         return;
+    } else {
+        submitToCoursera();
     }
-    QUrl url("https://class.coursera.org/" + project.course + "/assignment/challenge");
-    QUrlQuery q;
-    q.addQueryItem("email_address", email);
-    q.addQueryItem("assignment_part_sid", "6vp6Er9J-dev");
-    q.addQueryItem("response_encoding","delim");
-    url.setQuery(q);
-
-    QNetworkRequest request;
-    request.setUrl(url);
-    request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
-
-    _cur_phase = S_WAIT_CHALLENGE;
-    reply = IDE::instance()->networkManager->get(request);
-    connect(reply, SIGNAL(finished()), this, SLOT(rcv_challenge()));
-
 }
 
-void CourseraSubmission::rcv_challenge()
+void CourseraSubmission::submitToCoursera()
 {
-    disconnect(reply, SIGNAL(finished()), this, SLOT(rcv_challenge()));
-
-    reply->deleteLater();
-    QString challenge = reply->readAll();
-    QStringList fields = challenge.split("|");
-
-    if (fields.size() < 7) {
-        QMessageBox::warning(this, "MiniZinc IDE",
-                             "Error: cannot connect to Coursera.\n"+challenge);
-        _cur_phase = S_NONE;
-        enableUI();
-        return;
-    }
-
-    _login = fields[2];
-    QString ch = fields[4];
-    _state = fields[6];
-
-    _ch_resp = challenge_response(ui->password->text(),ch);
+    QUrl url("https://www.coursera.org/api/onDemandProgrammingScriptSubmissions.v1");
+    QNetworkRequest request;
+    request.setUrl(url);
+    request.setRawHeader(QByteArray("Cache-Control"),QByteArray("no-cache"));
+    request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
 
-    if (_current_model < 0) {
-        // Check login information
-        _submission = "0";
-        _source = "";
-        _sid = project.checkpwdSid;
-        if (_current_model == -1)
-            ui->textBrowser->insertPlainText("Checking login\n");
-        submit_solution();
-    } else {
-        int n_problems = project.problems.size();
-
-        CourseraItem& item =
-                _current_model < n_problems ?
-                    project.problems[_current_model]
-                  : project.models[_current_model-n_problems];
-        QStringList allfiles = mw->getProject().files();
-
-        bool foundFile = false;
-        for (int i=0; i<allfiles.size(); i++) {
-            QFileInfo fi(allfiles[i]);
-            if (fi.fileName()==item.model) {
-                foundFile = true;
-                QFile file(fi.absoluteFilePath());
-                if (file.open(QFile::ReadOnly | QFile::Text)) {
-                    _source = file.readAll();
-                } else {
-                    ui->textBrowser->insertPlainText("Error: could not open "+item.name+"\n");
-                    ui->textBrowser->insertPlainText("Skipping.\n");
-                    goto_next();
-                    return;
+    // add models
+    QStringList allfiles = mw->getProject().files();
+    for (int i=0; i<project.models.size(); i++) {
+        const CourseraItem& item = project.models.at(i);
+        QCheckBox* cb = qobject_cast<QCheckBox*>(ui->modelBox->layout()->itemAt(i)->widget());
+        if (cb->isChecked()) {
+            bool foundFile = false;
+            for (int i=0; i<allfiles.size(); i++) {
+                QFileInfo fi(allfiles[i]);
+                if (fi.fileName()==item.model) {
+                    foundFile = true;
+                    QFile file(fi.absoluteFilePath());
+                    if (file.open(QFile::ReadOnly | QFile::Text)) {
+                        QJsonObject output;
+                        QTextStream ts(&file);
+                        output["output"] = ts.readAll();
+                        _parts[item.id] = output;
+                    } else {
+                        ui->textBrowser->insertPlainText("Error: could not open "+item.name+"\n");
+                        ui->textBrowser->insertPlainText("Skipping.\n");
+                        solveNext();
+                        return;
+                    }
+                    break;
                 }
-                break;
             }
-        }
-        if (!foundFile) {
-            ui->textBrowser->insertPlainText("Error: could not find "+item.name+"\n");
-            ui->textBrowser->insertPlainText("Skipping.\n");
-            goto_next();
-            return;
-        }
-        _sid = item.id;
-
-        if (_current_model < n_problems) {
-            _submission.clear();
-            connect(mw, SIGNAL(finished()), this, SLOT(solver_finished()));
-            ui->textBrowser->insertPlainText("Running "+item.name+"\n");
-            _cur_phase = S_WAIT_SOLVE;
-            mw->addOutput("<div style='color:orange;'>Running Coursera submission "+item.name+"</div><br>\n");
-            if (!mw->runWithOutput(item.model, item.data, item.timeout, _output_stream)) {
-                ui->textBrowser->insertPlainText("Error: could not run "+item.name+"\n");
+            if (!foundFile) {
+                ui->textBrowser->insertPlainText("Error: could not find "+item.name+"\n");
                 ui->textBrowser->insertPlainText("Skipping.\n");
-                goto_next();
             }
-            return;
-        } else {
-            // Submit model source code
-            _submission = _source;
-            _source = "";
-            ui->textBrowser->insertPlainText("Submitting model "+item.name+"\n");
-            submit_solution();
         }
-
     }
-}
 
-void CourseraSubmission::submit_solution()
-{
-    QUrl url("https://class.coursera.org/" + project.course + "/assignment/submit");
-    QUrlQuery q;
-    q.addQueryItem("email_address", QUrl::toPercentEncoding(_login));
-    q.addQueryItem("assignment_part_sid", QUrl::toPercentEncoding(_sid));
-    q.addQueryItem("submission", QUrl::toPercentEncoding(_submission.toUtf8().toBase64()));
-    q.addQueryItem("submission_aux",QUrl::toPercentEncoding(_source.toUtf8().toBase64()));
-    q.addQueryItem("challenge_response", QUrl::toPercentEncoding(_ch_resp));
-    q.addQueryItem("state",QUrl::toPercentEncoding(_state));
+    _submission["assignmentKey"] = project.assignmentKey;
+    _submission["secret"] = ui->password->text();
+    _submission["submitterEmail"] = ui->login->text();
+    _submission["parts"] = _parts;
+
+    QJsonDocument doc(_submission);
 
-    QNetworkRequest request;
-    request.setUrl(url);
-    request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
     _cur_phase = S_WAIT_SUBMIT;
-    reply = IDE::instance()->networkManager->post(request,q.toString().toLocal8Bit());
-    connect(reply, SIGNAL(finished()), this, SLOT(rcv_solution_reply()));
+    reply = IDE::instance()->networkManager->post(request,doc.toJson());
+    connect(reply, SIGNAL(finished()), this, SLOT(rcvSubmissionResponse()));
+    ui->textBrowser->insertPlainText("Submitting to Coursera for grading...\n");
 }
 
-void CourseraSubmission::rcv_solution_reply()
+void CourseraSubmission::rcvSubmissionResponse()
 {
-    disconnect(reply, SIGNAL(finished()), this, SLOT(rcv_solution_reply()));
+    disconnect(reply, SIGNAL(finished()), this, SLOT(rcvSubmissionResponse()));
     reply->deleteLater();
 
-    QString message = reply->readAll();
-
-    if (_current_model < 0) {
-        if (message != "password verified") {
-            QMessageBox::warning(this, "MiniZinc IDE",
-                                 "Login failed! Message: "+message);
-            _current_model = -2;
-            _cur_phase = S_NONE;
-            return;
-        }
-        if (_current_model == -2) {
-            QMessageBox::information(this, "MiniZinc IDE", "Login successful!");
-            _cur_phase = S_NONE;
-            return;
+    QJsonDocument doc = QJsonDocument::fromJson(reply->readAll());
+    if (doc.object().contains("message")) {
+        ui->textBrowser->insertPlainText("== "+doc.object()["message"].toString()+"\n");
+    }
+    if (doc.object().contains("details")) {
+        QJsonObject details = doc.object()["details"].toObject();
+        if (details.contains("learnerMessage")) {
+            ui->textBrowser->insertPlainText("== "+details["learnerMessage"].toString()+"\n");
         }
     }
-    ui->textBrowser->insertPlainText("== "+message+"\n");
-    goto_next();
+
+    ui->textBrowser->insertPlainText("Done.\n");
+    _cur_phase = S_NONE;
+    ui->runButton->setText("Done.");
+    ui->runButton->setEnabled(false);
+    ui->buttonBox->button(QDialogButtonBox::Close)->setDefault(true);
 }
 
-void CourseraSubmission::solver_finished()
+void CourseraSubmission::solverFinished()
 {
-    disconnect(mw, SIGNAL(finished()), this, SLOT(solver_finished()));
+    disconnect(mw, SIGNAL(finished()), this, SLOT(solverFinished()));
 
-    QStringList solutions = _submission.split("----------");
+    QStringList solutions = _output_string.split("----------");
     if (solutions.size() >= 2) {
-        _submission = solutions[solutions.size()-2]+"----------"+solutions[solutions.size()-1];
+        _output_string = solutions[solutions.size()-2]+"----------"+solutions[solutions.size()-1];
     }
-    if (_submission.size()==0 || _submission[_submission.size()-1] != '\n')
-        _submission += "\n";
-    _submission += "unknown time\nMiniZinc IDE submission";
-    ui->textBrowser->insertPlainText("Submitting solution\n");
-    submit_solution();
+    if (_output_string.size()==0 || _output_string[_output_string.size()-1] != '\n')
+        _output_string += "\n";
+
+    QJsonObject output;
+    output["output"] = _output_string;
+    _parts[project.problems[_current_model].id] = output;
+    ui->textBrowser->insertPlainText("Finished\n");
+    solveNext();
 }
 
-void CourseraSubmission::goto_next()
+void CourseraSubmission::on_runButton_clicked()
 {
-    int n_models = project.models.size();
-    int n_problems = project.problems.size();
-
-    bool done = false;
-    do {
-        _current_model++;
-        if (_current_model < n_problems) {
-            QCheckBox* cb = qobject_cast<QCheckBox*>(ui->problemBox->layout()->itemAt(_current_model)->widget());
-            done = cb->isChecked();
-        } else if (_current_model < n_models+n_problems) {
-            int idx = _current_model - n_problems;
-            QCheckBox* cb = qobject_cast<QCheckBox*>(ui->modelBox->layout()->itemAt(idx)->widget());
-            done = cb->isChecked();
+    if (_cur_phase==S_NONE) {
+        ui->textBrowser->clear();
+        QString email = ui->login->text();
+        if (email.isEmpty()) {
+            QMessageBox::warning(this, "MiniZinc IDE",
+                                 "Enter an email address for Coursera login!");
+            return;
         }
-        if (_current_model >= n_models+n_problems) {
-            ui->textBrowser->insertPlainText("Done.\n");
-            _cur_phase = S_NONE;
-            ui->runButton->setText("Done.");
-            ui->runButton->setEnabled(false);
-            ui->buttonBox->button(QDialogButtonBox::Close)->setDefault(true);
+        if (ui->password->text().isEmpty()) {
+            QMessageBox::warning(this, "MiniZinc IDE",
+                                 "Enter an assignment key!");
             return;
         }
-    } while (!done);
-    get_challenge();
+
+        // Send empty request to check password
+        QUrl url("https://www.coursera.org/api/onDemandProgrammingScriptSubmissions.v1");
+        QNetworkRequest request;
+        request.setUrl(url);
+        request.setRawHeader(QByteArray("Cache-Control"),QByteArray("no-cache"));
+        request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
+        QJsonObject checkPwdSubmission;
+        checkPwdSubmission["assignmentKey"] = project.assignmentKey;
+        checkPwdSubmission["secret"] = ui->password->text();
+        checkPwdSubmission["submitterEmail"] = ui->login->text();
+        QJsonObject emptyParts;
+        checkPwdSubmission["parts"] = emptyParts;
+
+        QJsonDocument doc(checkPwdSubmission);
+
+        _cur_phase = S_WAIT_PWD;
+        disableUI();
+        reply = IDE::instance()->networkManager->post(request,doc.toJson());
+        connect(reply, SIGNAL(finished()), this, SLOT(rcvLoginCheckResponse()));
+        ui->textBrowser->insertPlainText("Checking login and assignment token...\n");
+    } else {
+        cancelOperation();
+    }
 }
 
-void CourseraSubmission::on_runButton_clicked()
+void CourseraSubmission::rcvLoginCheckResponse()
 {
-    if (_cur_phase==S_NONE) {
+    disconnect(reply, SIGNAL(finished()), this, SLOT(rcvLoginCheckResponse()));
+    reply->deleteLater();
+
+    QJsonDocument doc = QJsonDocument::fromJson(reply->readAll());
+    if (doc.object().contains("message") && doc.object()["message"].toString().endsWith("but found: Set()")) {
+        ui->textBrowser->insertPlainText("Done.\n");
         _current_model = -1;
-        disableUI();
-        goto_next();
+        for (int i=0; i<project.problems.size(); i++) {
+            _parts[project.problems[i].id] = QJsonObject();
+        }
+        for (int i=0; i<project.models.size(); i++) {
+            _parts[project.models[i].id] = QJsonObject();
+        }
+        solveNext();
     } else {
-        cancelOperation();
+        if (doc.object().contains("message")) {
+            ui->textBrowser->insertPlainText("== "+doc.object()["message"].toString()+"\n");
+        }
+        if (doc.object().contains("details")) {
+            QJsonObject details = doc.object()["details"].toObject();
+            if (details.contains("learnerMessage")) {
+                ui->textBrowser->insertPlainText(">> "+details["learnerMessage"].toString()+"\n");
+            }
+        }
+        _cur_phase = S_NONE;
+        enableUI();
     }
 }
 
@@ -352,9 +325,8 @@ void CourseraSubmission::on_storePassword_toggled(bool checked)
     if (!checked) {
         QSettings settings;
         settings.beginGroup("coursera");
+        settings.remove("");
         settings.setValue("storeLogin", false);
-        settings.setValue("login","");
-        settings.setValue("password","");
         settings.endGroup();
     }
 }
diff --git a/MiniZincIDE/courserasubmission.h b/MiniZincIDE/courserasubmission.h
index 50ea12a..2e007f7 100644
--- a/MiniZincIDE/courserasubmission.h
+++ b/MiniZincIDE/courserasubmission.h
@@ -3,6 +3,7 @@
 
 #include <QDialog>
 #include <QTextStream>
+#include <QJsonObject>
 #include "project.h"
 
 class QNetworkReply;
@@ -21,45 +22,37 @@ class CourseraSubmission : public QDialog
     ~CourseraSubmission();
 
 protected:
-    enum State { S_NONE, S_WAIT_CHALLENGE, S_WAIT_SUBMIT, S_WAIT_SOLVE } _cur_phase;
+    enum State { S_NONE, S_WAIT_PWD, S_WAIT_SUBMIT, S_WAIT_SOLVE } _cur_phase;
     int _current_model;
-    QString _submission;
-    QString _source;
 
     QTextStream _output_stream;
+    QString _output_string;
 
-    QString _login;
-    QString _sid;
-    QString _ch_resp;
-    QString _state;
+    QJsonObject _submission;
+    QJsonObject _parts;
 
     CourseraProject& project;
     MainWindow* mw;
     QNetworkReply* reply;
 
-    QByteArray challenge_response(QString passwd, QString challenge);
-
     void disableUI(void);
     void enableUI(void);
     void cancelOperation(void);
+    void solveNext(void);
 
 public slots:
     void reject();
 
 private slots:
-    void on_checkLoginButton_clicked();
 
-    void get_challenge();
-    void rcv_challenge();
-    void submit_solution();
-    void rcv_solution_reply();
-    void solver_finished();
-    void goto_next();
+    void submitToCoursera();
+    void rcvSubmissionResponse();
+    void solverFinished();
 
     void on_runButton_clicked();
+    void rcvLoginCheckResponse();
 
     void on_storePassword_toggled(bool checked);
-
 private:
     Ui::CourseraSubmission *ui;
 };
diff --git a/MiniZincIDE/courserasubmission.ui b/MiniZincIDE/courserasubmission.ui
index 01c6290..a99df29 100644
--- a/MiniZincIDE/courserasubmission.ui
+++ b/MiniZincIDE/courserasubmission.ui
@@ -7,7 +7,7 @@
     <x>0</x>
     <y>0</y>
     <width>521</width>
-    <height>585</height>
+    <height>652</height>
    </rect>
   </property>
   <property name="sizePolicy">
@@ -48,7 +48,7 @@
         <item>
          <widget class="QLabel" name="label_3">
           <property name="text">
-           <string>Submission login:</string>
+           <string>Coursera login email:</string>
           </property>
          </widget>
         </item>
@@ -65,7 +65,7 @@
         <item>
          <widget class="QLabel" name="label_4">
           <property name="text">
-           <string>Submission password:</string>
+           <string>Assignment token:</string>
           </property>
          </widget>
         </item>
@@ -87,7 +87,7 @@
          </sizepolicy>
         </property>
         <property name="text">
-         <string>Note that this is your assignment submission password, not your Coursera login and password.</string>
+         <string>Note that this is your assignment submission token, not your Coursera password.</string>
         </property>
         <property name="textFormat">
          <enum>Qt::RichText</enum>
@@ -105,7 +105,7 @@
         <item>
          <widget class="QCheckBox" name="storePassword">
           <property name="text">
-           <string>Remember password</string>
+           <string>Remember login details</string>
           </property>
          </widget>
         </item>
@@ -122,13 +122,6 @@
           </property>
          </spacer>
         </item>
-        <item>
-         <widget class="QPushButton" name="checkLoginButton">
-          <property name="text">
-           <string>Check login</string>
-          </property>
-         </widget>
-        </item>
        </layout>
       </item>
      </layout>
diff --git a/MiniZincIDE/htmlpage.cpp b/MiniZincIDE/htmlpage.cpp
index c77d019..5ae26ef 100755
--- a/MiniZincIDE/htmlpage.cpp
+++ b/MiniZincIDE/htmlpage.cpp
@@ -1,6 +1,42 @@
 #include "htmlpage.h"
 #include "mainwindow.h"
 #include "QDebug"
+
+#ifdef MINIZINC_IDE_HAVE_WEBENGINE
+
+HTMLPage::HTMLPage(MainWindow* mw, QWidget *parent) :
+    QWebEnginePage(parent), _mw(mw), _webChannel(new QWebChannel(this)), _mznide(new MiniZincIDEJS(this)),
+    loadFinished(false)
+{
+    connect(this, SIGNAL(loadFinished(bool)), this, SLOT(pageLoadFinished(bool)));
+    setWebChannel(_webChannel);
+    _webChannel->registerObject("mznide", _mznide);
+}
+
+void
+HTMLPage::javaScriptConsoleMessage(JavaScriptConsoleMessageLevel, const QString &message, int lineNumber, const QString &sourceID)
+{
+    _mw->addOutput("<div style='color:red;'>JavaScript message: source " +sourceID + ", line no. " + QString().number(lineNumber) + ": " + message + "</div><br>\n");
+}
+
+void HTMLPage::runJs(QString js)
+{
+    runJavaScript(js);
+}
+
+MiniZincIDEJS::MiniZincIDEJS(HTMLPage *p)
+    : QObject(p), _htmlPage(p)
+{
+
+}
+
+void MiniZincIDEJS::selectSolution(int n)
+{
+    _htmlPage->selectSolution(n);
+}
+
+#else
+
 #include <QWebFrame>
 
 HTMLPage::HTMLPage(MainWindow* mw, QWidget *parent) :
@@ -23,9 +59,17 @@ HTMLPage::jsCleared()
     mainFrame()->addToJavaScriptWindowObject("mznide", this);
 }
 
+void HTMLPage::runJs(QString js)
+{
+    mainFrame()->evaluateJavaScript(js);
+}
+
+#endif
+
 void
 HTMLPage::selectSolution(int n)
 {
+    qDebug() << "select " << n;
     _mw->selectJSONSolution(this,n);
 }
 
@@ -34,8 +78,26 @@ HTMLPage::pageLoadFinished(bool ok)
 {
     if (ok) {
         loadFinished = true;
+
+#ifdef MINIZINC_IDE_HAVE_WEBENGINE
+        // Load qwebchannel javascript
+        QFile qwebchanneljs(":/qtwebchannel/qwebchannel.js");
+        if (!qwebchanneljs.open(QIODevice::ReadOnly | QIODevice::Text)) {
+            qDebug() << "can't open qrc:///qtwebchannel/qwebchannel.js";
+            return;
+        }
+        QTextStream qwebchanneljs_in(&qwebchanneljs);
+        QString qwebchanneljs_text = qwebchanneljs_in.readAll();
+        runJs(qwebchanneljs_text);
+
+        QString setup_object("new QWebChannel(qt.webChannelTransport, function (channel) {"
+                             "window.mznide = channel.objects.mznide;"
+                             "});"
+                             );
+        runJs(setup_object);
+#endif
         for (int i=0; i<json.size(); i++) {
-            mainFrame()->evaluateJavaScript(json[i]);
+            runJs(json[i]);
         }
         json.clear();
     }
@@ -49,7 +111,7 @@ HTMLPage::addSolution(const QString &json0)
     j.replace("\"","\\\"");
     j.replace("\n"," ");
     if (loadFinished) {
-        mainFrame()->evaluateJavaScript("addSolution('"+j+"')");
+        runJs("addSolution('"+j+"')");
     } else {
         json.push_back("addSolution('"+j+"')");
     }
@@ -60,7 +122,7 @@ HTMLPage::finish(qint64 runtime)
 {
     QString jscall = "if (typeof finish == 'function') { finish("+QString().number(runtime)+"); }";
     if (loadFinished) {
-        mainFrame()->evaluateJavaScript(jscall);
+        runJs(jscall);
     } else {
         json.push_back(jscall);
     }
@@ -70,6 +132,6 @@ void
 HTMLPage::showSolution(int n)
 {
     if (loadFinished) {
-        mainFrame()->evaluateJavaScript("gotoSolution('"+QString().number(n)+"')");
+        runJs("gotoSolution('"+QString().number(n)+"')");
     }
 }
diff --git a/MiniZincIDE/htmlpage.h b/MiniZincIDE/htmlpage.h
index d09e398..cedeaf0 100644
--- a/MiniZincIDE/htmlpage.h
+++ b/MiniZincIDE/htmlpage.h
@@ -1,10 +1,52 @@
 #ifndef HTMLPAGE_H
 #define HTMLPAGE_H
 
-#include <QWebPage>
-
 class MainWindow;
 
+#ifdef MINIZINC_IDE_HAVE_WEBENGINE
+
+#include <QWebEnginePage>
+#include <QWebChannel>
+
+class HTMLPage;
+
+class MiniZincIDEJS : public QObject {
+    Q_OBJECT
+protected:
+    HTMLPage* _htmlPage;
+public:
+    MiniZincIDEJS(HTMLPage* p);
+public slots:
+    void selectSolution(int n);
+};
+
+class HTMLPage : public QWebEnginePage
+{
+    Q_OBJECT
+protected:
+    MainWindow* _mw;
+    QWebChannel* _webChannel;
+    MiniZincIDEJS* _mznide;
+    QStringList json;
+    bool loadFinished;
+    void runJs(QString js);
+public:
+    explicit HTMLPage(MainWindow* mw, QWidget *parent = 0);
+    virtual void javaScriptConsoleMessage(JavaScriptConsoleMessageLevel level, const QString &message, int lineNumber, const QString &sourceID);
+    void addSolution(const QString& json);
+    void showSolution(int n);
+    void finish(qint64 runtime);
+public slots:
+    void selectSolution(int n);
+
+private slots:
+    void pageLoadFinished(bool ok);
+};
+
+#else
+
+#include <QWebPage>
+
 class HTMLPage : public QWebPage
 {
     Q_OBJECT
@@ -12,6 +54,7 @@ class HTMLPage : public QWebPage
     MainWindow* _mw;
     QStringList json;
     bool loadFinished;
+    void runJs(QString js);
 public:
     explicit HTMLPage(MainWindow* mw, QWidget *parent = 0);
     virtual void javaScriptConsoleMessage(const QString &message, int lineNumber, const QString &sourceID);
@@ -26,4 +69,6 @@ private slots:
     void jsCleared(void);
 };
 
+#endif
+
 #endif // HTMLPAGE_H
diff --git a/MiniZincIDE/htmlwindow.cpp b/MiniZincIDE/htmlwindow.cpp
index 9bfb021..9cd4a74 100755
--- a/MiniZincIDE/htmlwindow.cpp
+++ b/MiniZincIDE/htmlwindow.cpp
@@ -2,7 +2,6 @@
 #include "ui_htmlwindow.h"
 #include "htmlpage.h"
 
-#include <QWebView>
 #include <QMdiSubWindow>
 #include <QDebug>
 #include <QDockWidget>
@@ -15,11 +14,11 @@ HTMLWindow::HTMLWindow(const QVector<VisWindowSpec>& specs, MainWindow* mw, QWid
     ui->setupUi(this);
 
     for (int i=0; i<specs.size(); i++) {
-        QWebView* wv = new QWebView;
+        MznIdeWebView* wv = new MznIdeWebView;
         HTMLPage* p = new HTMLPage(mw,wv);
         pages.append(p);
         wv->setPage(p);
-        loadQueue.append(QPair<QWebView*,QString>(wv,specs[i].url));
+        loadQueue.append(QPair<MznIdeWebView*,QString>(wv,specs[i].url));
         QDockWidget* dw = new QDockWidget(this);
         dw->setFeatures(QDockWidget::DockWidgetMovable);
         dw->setWidget(wv);
@@ -28,7 +27,7 @@ HTMLWindow::HTMLWindow(const QVector<VisWindowSpec>& specs, MainWindow* mw, QWid
 
     if (specs.size() > 0) {
         connect(loadQueue[0].first, SIGNAL(loadFinished(bool)), this, SLOT(loadFinished(bool)));
-        QWebView* wv0 = loadQueue[0].first;
+        MznIdeWebView* wv0 = loadQueue[0].first;
         QString url0 = loadQueue[0].second;
         wv0->load(QUrl::fromUserInput(url0));
     }
@@ -65,7 +64,7 @@ void HTMLWindow::loadFinished(bool)
     loadQueue.pop_front();
     if (loadQueue.size() > 0) {
         connect(loadQueue[0].first, SIGNAL(loadFinished(bool)), this, SLOT(loadFinished(bool)));
-        QWebView* wv0 = loadQueue[0].first;
+        MznIdeWebView* wv0 = loadQueue[0].first;
         QString url0 = loadQueue[0].second;
         wv0->load(QUrl::fromUserInput(url0));
     }
diff --git a/MiniZincIDE/htmlwindow.h b/MiniZincIDE/htmlwindow.h
index f12141a..3ce5e8e 100644
--- a/MiniZincIDE/htmlwindow.h
+++ b/MiniZincIDE/htmlwindow.h
@@ -2,7 +2,12 @@
 #define HTMLWINDOW_H
 
 #include <QMainWindow>
+
+#ifdef MINIZINC_IDE_HAVE_WEBENGINE
+#include <QWebEngineView>
+#else
 #include <QWebView>
+#endif
 #include "htmlpage.h"
 
 namespace Ui {
@@ -34,7 +39,12 @@ class HTMLWindow : public QMainWindow
 private:
     Ui::HTMLWindow *ui;
     QVector<HTMLPage*> pages;
-    QVector<QPair<QWebView*,QString> > loadQueue;
+#ifdef MINIZINC_IDE_HAVE_WEBENGINE
+    typedef QWebEngineView MznIdeWebView;
+#else
+    typedef QWebView MznIdeWebView;
+#endif
+    QVector<QPair<MznIdeWebView*,QString> > loadQueue;
 protected:
     void closeEvent(QCloseEvent *);
 private slots:
diff --git a/MiniZincIDE/images/mznicon.png b/MiniZincIDE/images/mznicon.png
index db8d871..024f853 100644
Binary files a/MiniZincIDE/images/mznicon.png and b/MiniZincIDE/images/mznicon.png differ
diff --git a/MiniZincIDE/images/mznlogo.png b/MiniZincIDE/images/mznlogo.png
deleted file mode 100644
index f73bc62..0000000
Binary files a/MiniZincIDE/images/mznlogo.png and /dev/null differ
diff --git a/MiniZincIDE/mainwindow.cpp b/MiniZincIDE/mainwindow.cpp
index e2164e6..1da147c 100755
--- a/MiniZincIDE/mainwindow.cpp
+++ b/MiniZincIDE/mainwindow.cpp
@@ -837,6 +837,7 @@ void MainWindow::init(const QString& projectFile)
     projectSort->setSortRole(Qt::UserRole);
     ui->projectView->setModel(projectSort);
     ui->projectView->sortByColumn(0, Qt::AscendingOrder);
+    ui->projectView->setEditTriggers(QAbstractItemView::EditKeyPressed);
     ui->projectExplorerDockWidget->hide();
     connect(ui->projectView, SIGNAL(activated(QModelIndex)),
             this, SLOT(activateFileInProject(QModelIndex)));
@@ -914,7 +915,8 @@ void MainWindow::addFileToProject(bool dznOnly)
     QStringList fileNames;
     if (dznOnly) {
         QString fileName = QFileDialog::getOpenFileName(this, tr("Select a data file to open"), getLastPath(), "MiniZinc data files (*.dzn)");
-        fileNames.append(fileName);
+        if (!fileName.isNull())
+            fileNames.append(fileName);
     } else {
         fileNames = QFileDialog::getOpenFileNames(this, tr("Select one or more files to open"), getLastPath(), "MiniZinc Files (*.mzn *.dzn)");
     }
@@ -978,12 +980,12 @@ void MainWindow::onActionProjectRemove_triggered()
         }
     }
     project.removeFile(projectSelectedFile);
+    setupDznMenu();
 }
 
 void MainWindow::onActionProjectRename_triggered()
 {
-    project.setEditable(projectSelectedIndex);
-    ui->projectView->edit(projectSelectedIndex);
+    ui->projectView->edit(ui->projectView->currentIndex());
 }
 
 void MainWindow::onActionProjectRunWith_triggered()
@@ -1442,7 +1444,10 @@ void MainWindow::setupDznMenu()
         ui->conf_data_file->addItem(dataFiles[i]);
     }
     ui->conf_data_file->addItem("Add data file to project...");
-    ui->conf_data_file->setCurrentText(curText);
+    if (curText != "Add data file to project...")
+        ui->conf_data_file->setCurrentText(curText);
+    else
+        ui->conf_data_file->setCurrentIndex(0);
 }
 
 void MainWindow::addOutput(const QString& s, bool html)
@@ -1865,7 +1870,7 @@ void MainWindow::pipeOutput()
 }
 
 void MainWindow::procFinished(int, bool showTime) {
-    if (outputProcess)
+    if (process && outputProcess)
         pipeOutput();
     readOutput();
     updateUiProcessRunning(false);
@@ -1896,7 +1901,7 @@ void MainWindow::procError(QProcess::ProcessError e) {
     if (e==QProcess::FailedToStart) {
         QMessageBox::critical(this, "MiniZinc IDE", "Failed to start '"+processName+"'. Check your path settings.");
     } else {
-        QMessageBox::critical(this, "MiniZinc IDE", "Unknown error while executing the MiniZinc interpreter.");
+        QMessageBox::critical(this, "MiniZinc IDE", "Unknown error while executing the MiniZinc interpreter `"+processName+"': error code "+QString().number(e));
     }
     procFinished(0);
 }
@@ -1905,7 +1910,7 @@ void MainWindow::outputProcError(QProcess::ProcessError e) {
     if (e==QProcess::FailedToStart) {
         QMessageBox::critical(this, "MiniZinc IDE", "Failed to start 'solns2out'. Check your path settings.");
     } else {
-        QMessageBox::critical(this, "MiniZinc IDE", "Unknown error while executing the MiniZinc interpreter.");
+        QMessageBox::critical(this, "MiniZinc IDE", "Unknown error while executing the MiniZinc solution processor.");
     }
     procFinished(0);
 }
@@ -2009,8 +2014,10 @@ void MainWindow::on_actionStop_triggered()
 {
     ui->actionStop->setEnabled(false);
     if (process) {
+        pipeOutput();
         disconnect(process, SIGNAL(error(QProcess::ProcessError)),
                    this, SLOT(procError(QProcess::ProcessError)));
+        disconnect(process, SIGNAL(finished(int)), this, SLOT(procFinished(int)));
         processWasStopped = true;
 
 #ifdef Q_OS_WIN
diff --git a/MiniZincIDE/mainwindow.h b/MiniZincIDE/mainwindow.h
index 24eb0b0..9e106ea 100644
--- a/MiniZincIDE/mainwindow.h
+++ b/MiniZincIDE/mainwindow.h
@@ -18,7 +18,11 @@
 #include <QProcess>
 #include <QTimer>
 #include <QLabel>
+#ifdef MINIZINC_IDE_HAVE_WEBENGINE
+#include <QWebEngineView>
+#else
 #include <QWebView>
+#endif
 #include <QSet>
 #include <QTemporaryDir>
 #include <QElapsedTimer>
diff --git a/MiniZincIDE/minizincide.qrc b/MiniZincIDE/minizincide.qrc
index 4066b09..027dda0 100644
--- a/MiniZincIDE/minizincide.qrc
+++ b/MiniZincIDE/minizincide.qrc
@@ -1,6 +1,5 @@
 <RCC>
     <qresource prefix="/">
-        <file>images/mznlogo.png</file>
         <file>images/about.html</file>
         <file>images/mznicon.png</file>
         <file>cheat_sheet.mzn</file>
diff --git a/MiniZincIDE/mznide.icns b/MiniZincIDE/mznide.icns
index eaeb628..5011b1a 100644
Binary files a/MiniZincIDE/mznide.icns and b/MiniZincIDE/mznide.icns differ
diff --git a/MiniZincIDE/mznide.ico b/MiniZincIDE/mznide.ico
old mode 100755
new mode 100644
index 4bd2c25..319924c
Binary files a/MiniZincIDE/mznide.ico and b/MiniZincIDE/mznide.ico differ
diff --git a/MiniZincIDE/project.cpp b/MiniZincIDE/project.cpp
index cab301a..3cd45a5 100644
--- a/MiniZincIDE/project.cpp
+++ b/MiniZincIDE/project.cpp
@@ -140,12 +140,7 @@ void Project::addFile(QTreeView* treeView, QSortFilterProxyModel* sort, const QS
             delete cp;
             goto coursera_done;
         }
-        cp->course = in.readLine();
-        if (in.status() != QTextStream::Ok) {
-            delete cp;
-            goto coursera_done;
-        }
-        cp->checkpwdSid= in.readLine();
+        cp->assignmentKey = in.readLine();
         if (in.status() != QTextStream::Ok) {
             delete cp;
             goto coursera_done;
@@ -253,20 +248,16 @@ QString Project::fileAtIndex(const QModelIndex &index)
 
 Qt::ItemFlags Project::flags(const QModelIndex& index) const
 {
-    if (index==editable) {
-        return Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable;
-    } else {
-        QStandardItem* item = itemFromIndex(index);
-        if (!item->hasChildren() && (item==mzn || item==dzn || item==other) )
-            return Qt::ItemIsSelectable;
-        return Qt::ItemIsSelectable | Qt::ItemIsEnabled;
-    }
+    QStandardItem* item = itemFromIndex(index);
+    if (!item->hasChildren() && (item==mzn || item==dzn || item==other) )
+        return Qt::ItemIsSelectable;
+    return Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable;
 }
 
 QStringList Project::dataFiles(void) const
 {
     QStringList ret;
-    for (QMap<QString,QModelIndex>::const_iterator it = _files.begin(); it != _files.end(); ++it) {
+    for (QMap<QString,QPersistentModelIndex>::const_iterator it = _files.begin(); it != _files.end(); ++it) {
         if (it.key().endsWith(".dzn"))
             ret << it.key();
     }
@@ -298,11 +289,6 @@ void Project::removeFile(const QString &fileName)
     }
 }
 
-void Project::setEditable(const QModelIndex &index)
-{
-    editable = index;
-}
-
 void Project::setModified(bool flag, bool files)
 {
     if (!projectRoot.isEmpty()) {
@@ -337,7 +323,6 @@ void Project::setModified(bool flag, bool files)
 
 bool Project::setData(const QModelIndex& index, const QVariant& value, int role)
 {
-    editable = QModelIndex();
     QString oldName = itemFromIndex(index)->text();
     if (oldName==value.toString())
         return false;
@@ -442,7 +427,8 @@ void Project::currentDataFileIndex(int i, bool init)
         _currentDatafileIndex = i;
         ui->conf_data_file->setCurrentIndex(i);
     } else {
-        checkModified();
+        if (i < ui->conf_data_file->count()-1)
+            checkModified();
     }
 }
 
diff --git a/MiniZincIDE/project.h b/MiniZincIDE/project.h
index c11da46..12b5af7 100644
--- a/MiniZincIDE/project.h
+++ b/MiniZincIDE/project.h
@@ -39,8 +39,7 @@ class CourseraItem {
 class CourseraProject {
 public:
     QString name;
-    QString checkpwdSid;
-    QString course;
+    QString assignmentKey;
     QList<CourseraItem> problems;
     QList<CourseraItem> models;
 };
@@ -59,7 +58,6 @@ class Project : public QStandardItemModel
     QString fileAtIndex(const QModelIndex& index);
     virtual Qt::ItemFlags flags(const QModelIndex& index) const;
     QStringList dataFiles(void) const;
-    void setEditable(const QModelIndex& index);
     virtual bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole );
     bool isProjectFile(const QModelIndex& index) { return projectFile->index()==index; }
     bool isModified() const { return _isModified; }
@@ -117,12 +115,11 @@ public slots:
     bool _isModified;
     bool _filesModified;
     QString projectRoot;
-    QMap<QString, QModelIndex> _files;
+    QMap<QString, QPersistentModelIndex> _files;
     QStandardItem* projectFile;
     QStandardItem* mzn;
     QStandardItem* dzn;
     QStandardItem* other;
-    QModelIndex editable;
 
     int _currentDatafileIndex;
     bool _haveExtraArgs;