public function next($base = null)
    {
        //  Ensure that $base is a Version. Parse it if we must, use ourself if
        //  it is empty.
        if (empty($base)) {
            $base = $this;
        }
        else {
            if (is_string($base)) {
                $base = Parser::parse($base);
            }
            elseif (! $base instanceof Version) {
                throw new InvalidArgumentException("\$base must be of type Version");
            }
        }

        // If the base is ahead of this Version then the next version will be
        // the base.
        if (Compare::greaterThan($base, $this)) {
            return $base->cleanCopy();
        }

        $next = new Version;

        $next->setMajor($this->getMajor());
        $next->setMinor($this->getMinor());
        $next->setPatch($this->getPatch());

        if ($base->hasPreRelease()) {
            if ($this->hasPreRelease()) {
                // We already know that $base is less than or equal to $this
                // and we won't be jumping to the next greek value. So it is
                // safe use $this prerelease and just increment the release
                // number.
                $pre = new PreRelease;
                $pre->setGreek($this->getPreRelease()->getGreek());
                $pre->setReleaseNumber($this->getPreRelease()->getReleaseNumber() + 1);

                $next->setPreRelease($pre);
            }
            else {
                throw new InvalidArgumentException("This version has left prerelease without updating the base. Base should not be prerelease.");
            }
        }
        elseif ( ! $this->hasPreRelease()) {
            $next->setPatch($this->getPatch() + 1);
        }
        // The case of $this having a pre-release when $base does not means
        // that we are essentially just leaving pre-release. Nothing needs to
        // be done.

        return $next;
    }