void QDeclarativeBluetoothDiscoveryModel::serviceDiscovered(const QBluetoothServiceInfo &service)
{
    QDeclarativeBluetoothService *bs = new QDeclarativeBluetoothService(service, this);

    for(int i = 0; i < d->m_services.count(); i++) {
        if(bs->deviceAddress() == d->m_services.at(i)->deviceAddress()){
            delete bs;
            return;
        }
    }

    beginResetModel(); // beginInsertRows(...) doesn't work for full discovery...
    d->m_services.append(bs);
    endResetModel();
    emit newServiceDiscovered(bs);
}
QVariant QDeclarativeBluetoothDiscoveryModel::data(const QModelIndex &index, int role) const
{
    QDeclarativeBluetoothService *service = d->m_services.value(index.row());
    QBluetoothServiceInfo *info = service->serviceInfo();

    switch(role) {
        case Qt::DisplayRole:
        {
            QString label = info->device().name();
            if(label.isEmpty())
                label += info->device().address().toString();
            label += " " + info->serviceName();
            return label;
        }
        case Qt::DecorationRole:
            return QLatin1String("image://bluetoothicons/default");
        case ServiceRole:
        {
            return QVariant::fromValue(service);
        }
    }
    return QVariant();
}
QVariant QDeclarativeBluetoothDiscoveryModel::data(const QModelIndex &index, int role) const
{
    if (!index.isValid() || index.row() < 0)
        return QVariant();

    if (discoveryMode() != DeviceDiscovery) {
        if (index.row() >= d->m_services.count()){
            qCWarning(QT_BT_QML) << "index out of bounds";
            return QVariant();
        }

        QDeclarativeBluetoothService *service = d->m_services.value(index.row());

        switch (role) {
            case Name: {
                QString label = service->deviceName();
                if (label.isEmpty())
                    label += service->deviceAddress();
                else
                    label+= QStringLiteral(":");
                label += QStringLiteral(" ") + service->serviceName();
                return label;
            }
            case ServiceRole:
                return QVariant::fromValue(service);
            case DeviceName:
                return service->deviceName();
            case RemoteAddress:
                return service->deviceAddress();
        }
    } else {
        if (index.row() >= d->m_devices.count()) {
            qCWarning(QT_BT_QML) << "index out of bounds";
            return QVariant();
        }

        QBluetoothDeviceInfo device = d->m_devices.value(index.row());
        switch (role) {
            case Name:
            return (device.name() + QStringLiteral(" (") + device.address().toString() + QStringLiteral(")"));
            case ServiceRole:
                break;
            case DeviceName:
                return device.name();
            case RemoteAddress:
                return device.address().toString();
        }
    }

    return QVariant();
}
void QDeclarativeBluetoothDiscoveryModel::serviceDiscovered(const QBluetoothServiceInfo &service)
{
    //qDebug() << "service discovered";

    QDeclarativeBluetoothService *bs = new QDeclarativeBluetoothService(service, this);
    QDeclarativeBluetoothService *current = 0;
    for (int i = 0; i < d->m_services.count(); i++) {
        current = d->m_services.at(i);
        if (bs->deviceAddress() == current->deviceAddress()
                && bs->serviceName() == current->serviceName()
                && bs->serviceUuid() == current->serviceUuid()) {
            delete bs;
            return;
        }
    }

    beginInsertRows(QModelIndex(),d->m_services.count(), d->m_services.count());
    d->m_services.append(bs);
    endInsertRows();
    emit serviceDiscovered(bs);
}