public function log($length = null, $start = null, $upcoming = false, $installed = true, $search = null, $format = '%an: %s', $count = false)
	{
		$args = array();

		// Count trumps all, just compute and return
		if ($count)
		{
			return $this->countLogs($installed, $upcoming, $search);
		}

		if ($upcoming)
		{
			$args['upcoming'] = "HEAD..{$this->upstream}";
		}
		if (isset($length))
		{
			$args['length'] = '-' . (int)$length;
		}
		if (isset($start))
		{
			$args['skip'] = '--skip=' . (int)$start;
		}
		if (isset($format))
		{
			$args['format'] = '--pretty=format:' . escapeshellarg($format);
		}
		if (isset($search))
		{
			$args['case-insensitive'] = '-i';
			$args['search'] = '--grep=' . escapeshellarg($search);
		}

		// If upcoming is set, we have to pull those commits first
		$upcomingCount = 0;
		$upcomingTotal = 0;
		if ($upcoming)
		{
			$upcomingLog = $this->call('log', $args);

			if (isset($upcomingLog))
			{
				$upcomingLogs  = explode("\n", $upcomingLog);
				$upcomingCount = count($upcomingLogs);
			}

			$upcomingTotal = $this->countLogs(false, true, $search);
		}

		if ($upcomingCount < $length)
		{
			if (isset($args['upcoming']))
			{
				unset($args['upcoming']);
			}
			$args['length'] = '-' . ($length - $upcomingCount);
			$args['skip']   = '--skip=' . ((($start - $upcomingTotal) >= 0) ? ($start - $upcomingTotal) : 0);
			$currentLog     = $this->call('log', $args);
			$currentLogs    = (!empty($currentLog)) ? explode("\n", $currentLog) : array();
		}

		$response = array();

		if ($upcomingCount > 0)
		{
			foreach ($upcomingLogs as $entry)
			{
				$response[] = '* ' . $entry;
			}
		}
		if (isset($currentLogs) && count($currentLogs) > 0 && $installed)
		{
			foreach ($currentLogs as $entry)
			{
				$response[] = $entry;
			}
		}

		return $response;
	}