void CalDavClient::reportRequestFinished()
{
    Report *request = qobject_cast<Report*>(sender());
    if (!request) {
        syncFinished(Buteo::SyncResults::INTERNAL_ERROR, QStringLiteral("Invalid request object"));
        return;
    }

    if (request->errorCode() != Buteo::SyncResults::NO_ERROR) {
        qWarning() << "REPORT request failed!" << request->errorString();
    }
    syncFinished(request->errorCode(), request->errorString());
}
void NotebookSyncAgent::processETags()
{

    NOTEBOOK_FUNCTION_CALL_TRACE;

    Report *report = qobject_cast<Report*>(sender());
    mRequests.remove(report);
    report->deleteLater();

    if (report->errorCode() == Buteo::SyncResults::NO_ERROR) {
        LOG_DEBUG("Process tags for server path" << mServerPath);
        QHash<QString, Reader::CalendarResource> map = report->receivedCalendarResources();

        // Incidences must be loaded with ExtendedStorage::allIncidences() rather than
        // ExtendedCalendar::incidences(), because the latter will load incidences from all
        // notebooks, rather than just the one for this report.
        // Note that storage incidence references cannot be used with ExtendedCalendar::deleteEvent()
        // etc. Those methods only work for references created by ExtendedCalendar.
        KCalCore::Incidence::List storageIncidenceList;
        if (!mStorage->allIncidences(&storageIncidenceList, mNotebook->uid())) {
            emitFinished(Buteo::SyncResults::DATABASE_FAILURE, QString("Unable to load storage incidences for notebook: %1").arg(mNotebook->uid()));
            return;
        }

        KCalCore::Incidence::List deletions;
        if (!mStorage->deletedIncidences(&deletions, KDateTime(mChangesSinceDate), mNotebook->uid())) {
            LOG_CRITICAL("mKCal::ExtendedStorage::deletedIncidences() failed");
        }

        QStringList eventIdList;

        Q_FOREACH (KCalCore::Incidence::Ptr incidence, storageIncidenceList) {
            QString uri = incidence->customProperty("buteo", "uri");
            if (uri.isEmpty()) {
                //Newly added to Local DB -- Skip this incidence
                continue;
            }
            if (!map.contains(uri)) {
                // we have an incidence that's not on the remote server, so delete it
                switch (incidence->type()) {
                case KCalCore::IncidenceBase::TypeEvent:
                case KCalCore::IncidenceBase::TypeTodo:
                case KCalCore::IncidenceBase::TypeJournal:
                    mIncidenceUidsToDelete.append(incidence->uid());
                    break;
                case KCalCore::IncidenceBase::TypeFreeBusy:
                case KCalCore::IncidenceBase::TypeUnknown:
                    break;
                }
                continue;
            } else {
                Reader::CalendarResource resource = map.take(uri);
                if (mLocalETags.value(incidence->uid()) != resource.etag) {
                    LOG_DEBUG("Will fetch update for" << resource.href
                              << "tag changed from" << mLocalETags.value(incidence->uid())
                              << "to" << resource.etag);
                    eventIdList.append(resource.href);
                }
            }
        }