public function login()
    {
        $cookieValue = $this->cookie->getValue();

        if (!$cookieValue) {
            return LoginResult::newNoCookieResult();
        }

        $triplet = Triplet::fromString($cookieValue);

        if (!$triplet->isValid()) {
            return LoginResult::newManipulationResult();
        }

        if ($this->cleanExpiredTokensOnLogin) {
            $this->storage->cleanExpiredTokens(time() - $this->expireTime);
        }

        $tripletLookupResult = $this->storage->findTriplet(
            $triplet->getCredential(),
            $triplet->getSaltedOneTimeToken($this->salt),
            $triplet->getSaltedPersistentToken($this->salt)
        );
        switch ($tripletLookupResult) {
            case Storage\StorageInterface::TRIPLET_FOUND:
                $expire = time() + $this->expireTime;
                $newTriplet = new Triplet($triplet->getCredential(), $this->tokenGenerator->createToken(), $triplet->getPersistentToken());
                $this->storage->replaceTriplet(
                    $newTriplet->getCredential(),
                    $newTriplet->getSaltedOneTimeToken($this->salt),
                    $newTriplet->getSaltedPersistentToken($this->salt),
                    $expire
                );
                $this->cookie->setValue((string) $newTriplet);

                return LoginResult::newSuccessResult($triplet->getCredential());

            case Storage\StorageInterface::TRIPLET_INVALID:
                $this->cookie->deleteCookie();

                if ($this->cleanStoredTokensOnInvalidResult) {
                    $this->storage->cleanAllTriplets($triplet->getCredential());
                }

                return LoginResult::newManipulationResult();
            default:
                return LoginResult::newExpiredResult();
        }
    }