public function parseEvent($calendar = null, $userHref, $oldCalendar = null)
    {
        if ($oldCalendar) {
            if (is_string($oldCalendar)) {
                $oldCalendar = Reader::read($oldCalendar);
            }
            if (!isset($oldCalendar->VEVENT)) {
                // We only support events at the moment
                return [];
            }

            $oldEventInfo = $this->parseEventInfo($oldCalendar);
        } else {
            $oldEventInfo = [
                'organizer' => null,
                'significantChangeHash' => '',
                'attendees' => [],
            ];
        }

        $userHref = (array) $userHref;

        if (!is_null($calendar)) {
            if (is_string($calendar)) {
                $calendar = Reader::read($calendar);
            }
            if (!isset($calendar->VEVENT)) {
                // We only support events at the moment
                return [];
            }
            $eventInfo = $this->parseEventInfo($calendar);
            if (!$eventInfo['attendees'] && !$oldEventInfo['attendees']) {
                // If there were no attendees on either side of the equation,
                // we don't need to do anything.
                return [];
            }
            if (!$eventInfo['organizer'] && !$oldEventInfo['organizer']) {
                // There was no organizer before or after the change.
                return [];
            }

            $baseCalendar = $calendar;

            // If the new object didn't have an organizer, the organizer
            // changed the object from a scheduling object to a non-scheduling
            // object. We just copy the info from the old object.
            if (!$eventInfo['organizer'] && $oldEventInfo['organizer']) {
                $eventInfo['organizer'] = $oldEventInfo['organizer'];
                $eventInfo['organizerName'] = $oldEventInfo['organizerName'];
            }
        } else {
            // The calendar object got deleted, we need to process this as a
            // cancellation / decline.
            if (!$oldCalendar) {
                // No old and no new calendar, there's no thing to do.
                return [];
            }

            $eventInfo = $oldEventInfo;

            if (in_array($eventInfo['organizer'], $userHref)) {
                // This is an organizer deleting the event.
                $eventInfo['attendees'] = [];
                // Increasing the sequence, but only if the organizer deleted
                // the event.
                ++$eventInfo['sequence'];
            } else {
                // This is an attendee deleting the event.
                foreach ($eventInfo['attendees'] as $key => $attendee) {
                    if (in_array($attendee['href'], $userHref)) {
                        $eventInfo['attendees'][$key]['instances'] = ['master' => ['id' => 'master', 'partstat' => 'DECLINED'],
                        ];
                    }
                }
            }
            $baseCalendar = $oldCalendar;
        }

        if (in_array($eventInfo['organizer'], $userHref)) {
            return $this->parseEventForOrganizer($baseCalendar, $eventInfo, $oldEventInfo);
        } elseif ($oldCalendar) {
            // We need to figure out if the user is an attendee, but we're only
            // doing so if there's an oldCalendar, because we only want to
            // process updates, not creation of new events.
            foreach ($eventInfo['attendees'] as $attendee) {
                if (in_array($attendee['href'], $userHref)) {
                    return $this->parseEventForAttendee($baseCalendar, $eventInfo, $oldEventInfo, $attendee['href']);
                }
            }
        }

        return [];
    }