uint NotificationsEngine::Notify(const QString &app_name, uint replaces_id,
                                 const QString &app_icon, const QString &summary, const QString &body,
                                 const QStringList &actions, const QVariantMap &hints, int timeout)
{
    uint partOf = 0;

    if (m_activeNotifications.values().contains(app_name + summary)) {
        // cut off the "notification " from the source name
        partOf = m_activeNotifications.key(app_name + summary).mid(13).toUInt();

    }

    qDebug() << "Currrent active notifications:" << m_activeNotifications;
    qDebug() << "Guessing partOf as:" << partOf;
    qDebug() << " New Notification: " << summary << body << timeout << "& Part of:" << partOf;
    QString _body;

    if (partOf > 0) {
        const QString source = QString("notification %1").arg(partOf);
        Plasma::DataContainer *container = containerForSource(source);
        if (container) {
            // append the body text
            _body = container->data()["body"].toString();
            if (_body != body) {
                _body.append("\n").append(body);
            } else {
                _body = body;
            }

            // remove the old notification and replace it with the new one
            // TODO: maybe just update the current notification?
            CloseNotification(partOf);
        }
    }

    uint id = 0;
    id = replaces_id ? replaces_id : m_nextId++;

    QString appname_str = app_name;
    if (appname_str.isEmpty()) {
        appname_str = i18n("Unknown Application");
    }

    bool isPersistent = timeout == 0;

    const int AVERAGE_WORD_LENGTH = 6;
    const int WORD_PER_MINUTE = 250;
    int count = summary.length() + body.length();
    timeout = 60000 * count / AVERAGE_WORD_LENGTH / WORD_PER_MINUTE;

    // Add two seconds for the user to notice the notification, and ensure
    // it last at least five seconds, otherwise all the user see is a
    // flash
    timeout = 2000 + qMax(timeout, 3000);

    const QString source = QString("notification %1").arg(id);

    Plasma::DataEngine::Data notificationData;
    notificationData.insert("id", QString::number(id));
    notificationData.insert("appName", appname_str);
    notificationData.insert("appIcon", app_icon);
    notificationData.insert("summary", summary);
    notificationData.insert("body", partOf == 0 ? body : _body);
    notificationData.insert("actions", actions);
    notificationData.insert("isPersistent", isPersistent);
    notificationData.insert("expireTimeout", timeout);

    QString appRealName;
    bool configurable = false;
    if (hints.contains("x-kde-appname")) {
        appRealName = hints["x-kde-appname"].toString();
        configurable = true;
    }
    notificationData.insert("appRealName", appRealName);
    notificationData.insert("configurable", configurable);

    QImage image;
    if (hints.contains("image_data")) {
        QDBusArgument arg = hints["image_data"].value<QDBusArgument>();
        image = decodeNotificationSpecImageHint(arg);
    } else if (hints.contains("image_path")) {
        QString path = findImageForSpecImagePath(hints["image_path"].toString());
        if (!path.isEmpty()) {
            image.load(path);
        }
    } else if (hints.contains("icon_data")) {
        // This hint was in use in version 1.0 of the spec but has been
        // replaced by "image_data" in version 1.1. We need to support it for
        // users of the 1.0 version of the spec.
        QDBusArgument arg = hints["icon_data"].value<QDBusArgument>();
        image = decodeNotificationSpecImageHint(arg);
    }
    notificationData.insert("image", image);

    if (hints.contains("urgency")) {
        notificationData.insert("urgency", hints["urgency"].toInt());
    }

    setData(source, notificationData);

    m_activeNotifications.insert(source, app_name + summary);

    return id;
}
uint NotificationsEngine::Notify(const QString &app_name, uint replaces_id,
                                 const QString &app_icon, const QString &summary, const QString &body,
                                 const QStringList &actions, const QVariantMap &hints, int timeout)
{
    uint id = 0;
    id = replaces_id ? replaces_id : m_nextId++;

    QString appname_str = app_name;
    if (appname_str.isEmpty()) {
        appname_str = i18n("Unknown Application");
    }

    if (timeout == -1) {
        const int AVERAGE_WORD_LENGTH = 6;
        const int WORD_PER_MINUTE = 250;
        int count = summary.length() + body.length();
        timeout = 60000 * count / AVERAGE_WORD_LENGTH / WORD_PER_MINUTE;

        // Add two seconds for the user to notice the notification, and ensure
        // it last at least five seconds, otherwise all the user see is a
        // flash
        timeout = 2000 + qMax(timeout, 3000);
    }

    const QString source = QString("notification %1").arg(id);
    if (replaces_id) {
        Plasma::DataContainer *container = containerForSource(source);
        if (container && container->data()["expireTimeout"].toInt() != timeout) {
            int timerId = m_sourceTimers.value(source);
            killTimer(timerId);
            m_sourceTimers.remove(source);
            m_timeouts.remove(timerId);
        }
    }

    Plasma::DataEngine::Data notificationData;
    notificationData.insert("id", QString::number(id));
    notificationData.insert("appName", appname_str);
    notificationData.insert("appIcon", app_icon);
    notificationData.insert("summary", summary);
    notificationData.insert("body", body);
    notificationData.insert("actions", actions);
    notificationData.insert("expireTimeout", timeout);

    QImage image;
    if (hints.contains("image_data")) {
        QDBusArgument arg = hints["image_data"].value<QDBusArgument>();
        image = decodeNotificationSpecImageHint(arg);
    } else if (hints.contains("image_path")) {
        QString path = findImageForSpecImagePath(hints["image_path"].toString());
        if (!path.isEmpty()) {
            image.load(path);
        }
    } else if (hints.contains("icon_data")) {
        // This hint was in use in version 1.0 of the spec but has been
        // replaced by "image_data" in version 1.1. We need to support it for
        // users of the 1.0 version of the spec.
        QDBusArgument arg = hints["icon_data"].value<QDBusArgument>();
        image = decodeNotificationSpecImageHint(arg);
    }
    notificationData.insert("image", image);

    if (hints.contains("urgency")) {
        notificationData.insert("urgency", hints["urgency"].toInt());
    }

    setData(source, notificationData );

    if (timeout) {
        int timerId = startTimer(timeout);
        m_sourceTimers.insert(source, timerId);
        m_timeouts.insert(timerId, source);
    }

    return id;
}