public function generateOccurrences(Array $events, \DateTime $fromDate, \DateTime $toDate, $limit = null)
	{
		$return = array();
		$object = $this;

		$monthlyEvents = array_filter($events, function ($event) use ($object) {
			return $event->getRecurrenceType() === $object->getLabel();
		});

		foreach ($monthlyEvents as $monthlyEvent) {
			$monthlyEventTime = $monthlyEvent->getStartDate()->format('H:i:s');

			$monthlyDate = $monthlyEvent->getStartDate()->format('d');

			$start = $fromDate > $monthlyEvent->getStartDate()
				? clone($fromDate)
				: clone($monthlyEvent->getStartDate());

			$startMarker = clone($start);
			$startMarker->setDate($start->format('Y'), $start->format('m'), 1);

			$maxEndMarker = clone($startMarker);
			$maxEndMarker->modify($this->limit);

			$endMarker = $monthlyEvent->getRecurrenceUntil()
				? min($monthlyEvent->getRecurrenceUntil(), clone($toDate), $maxEndMarker)
				: min(clone($toDate), $maxEndMarker);

			$actualEndMarker = clone($endMarker);

			// The DatePeriod class does not actually include the end date so you have to increment it first
			$endMarker->modify('+1 day');

			$dateInterval = new \DateInterval('P1M');
			$datePeriod = new \DatePeriod($startMarker, $dateInterval, $endMarker);

			$limitMarker = 0;

			foreach ($datePeriod as $date) {
				if (($limit and ($limit === $limitMarker)) or ($date > $actualEndMarker)) {
					break;
				}

				if ($monthlyDate > $date->format('t')) {
					continue;
				}

				$date->setDate($date->format('Y'), $date->format('m'), sprintf('%2d', $monthlyDate));

				$newMonthlyEvent = clone($monthlyEvent);
				$newStartDate = new \DateTime($date->format('Y-m-d').' '.$monthlyEventTime);

				if ($newStartDate < $startMarker) {
					continue;
				}

				$duration = $newMonthlyEvent->getDuration();

				$newMonthlyEvent->setStartDate($newStartDate);

				$newEndDate = clone($newStartDate);
				$newEndDate->add($duration);
				
				$newMonthlyEvent->setEndDate($newEndDate);
				$newMonthlyEvent->setRecurrenceType();

				$return[] = $newMonthlyEvent;

				$limit and $limitMarker++;
			}
		}

		return $return;
	}