static QCFType<CFPropertyListRef> macValue(const QVariant &value)
{
    CFPropertyListRef result = 0;

    switch (value.type()) {
    case QVariant::ByteArray:
        {
            QByteArray ba = value.toByteArray();
            result = CFDataCreate(kCFAllocatorDefault, reinterpret_cast<const UInt8 *>(ba.data()),
                                  CFIndex(ba.size()));
        }
        break;
    // should be same as below (look for LIST)
    case QVariant::List:
    case QVariant::StringList:
    case QVariant::Polygon:
        result = macList(value.toList());
        break;
    case QVariant::Map:
        {
            /*
                QMap<QString, QVariant> is potentially a multimap,
                whereas CFDictionary is a single-valued map. To allow
                for multiple values with the same key, we store
                multiple values in a CFArray. To avoid ambiguities,
                we also wrap lists in a CFArray singleton.
            */
            QMap<QString, QVariant> map = value.toMap();
            QMap<QString, QVariant>::const_iterator i = map.constBegin();

            int maxUniqueKeys = map.size();
            int numUniqueKeys = 0;
            QVarLengthArray<QCFType<CFPropertyListRef> > cfkeys(maxUniqueKeys);
            QVarLengthArray<QCFType<CFPropertyListRef> > cfvalues(maxUniqueKeys);

            while (i != map.constEnd()) {
                const QString &key = i.key();
                QList<QVariant> values;

                do {
                    values << i.value();
                    ++i;
                } while (i != map.constEnd() && i.key() == key);

                bool singleton = (values.count() == 1);
                if (singleton) {
                    switch (values.constFirst().type()) {
                    // should be same as above (look for LIST)
                    case QVariant::List:
                    case QVariant::StringList:
                    case QVariant::Polygon:
                        singleton = false;
                    default:
                        ;
                    }
                }

                cfkeys[numUniqueKeys] = QCFString::toCFStringRef(key);
                cfvalues[numUniqueKeys] = singleton ? macValue(values.constFirst()) : macList(values);
                ++numUniqueKeys;
            }

            result = CFDictionaryCreate(kCFAllocatorDefault,
                                        reinterpret_cast<const void **>(cfkeys.data()),
                                        reinterpret_cast<const void **>(cfvalues.data()),
                                        CFIndex(numUniqueKeys),
                                        &kCFTypeDictionaryKeyCallBacks,
                                        &kCFTypeDictionaryValueCallBacks);
        }
        break;
    case QVariant::DateTime:
        {
            /*
                CFDate, unlike QDateTime, doesn't store timezone information.
            */
            QDateTime dt = value.toDateTime();
            if (dt.timeSpec() == Qt::LocalTime) {
                QDateTime reference;
                reference.setTime_t((uint)kCFAbsoluteTimeIntervalSince1970);
                result = CFDateCreate(kCFAllocatorDefault, CFAbsoluteTime(reference.secsTo(dt)));
            } else {
                goto string_case;
            }
        }
        break;
    case QVariant::Bool:
        result = value.toBool() ? kCFBooleanTrue : kCFBooleanFalse;
        break;
    case QVariant::Int:
    case QVariant::UInt:
        {
            int n = value.toInt();
            result = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &n);
        }
        break;
    case QVariant::Double:
        {
            double n = value.toDouble();
            result = CFNumberCreate(kCFAllocatorDefault, kCFNumberDoubleType, &n);
        }
        break;
    case QVariant::LongLong:
    case QVariant::ULongLong:
        {
            qint64 n = value.toLongLong();
            result = CFNumberCreate(0, kCFNumberLongLongType, &n);
        }
        break;
    case QVariant::String:
    string_case:
    default:
        result = QCFString::toCFStringRef(QSettingsPrivate::variantToString(value));
    }
    return result;
}