Return the previous service factory extended with the current service
factory.

@param callable $previous
@param callable $current
@return callable
551014
private function extended(callable $previous = null, callable $current): callable
    {
        return is_null($previous) ? $current : new Extension($current, $previous);
    }
1168302
public static function history(History $history)
    {
        return function (callable $handler) use ($history) {
            return function (
                CommandInterface $command,
                RequestInterface $request = null
            ) use ($handler, $history) {
                $ticket = $history->start($command, $request);
                return $handler($command, $request)
                    ->then(
                        function ($result) use ($history, $ticket) {
                            $history->finish($ticket, $result);
                            return $result;
                        },
                        function ($reason) use ($history, $ticket) {
                            $history->finish($ticket, $reason);
                            return Promise\rejection_for($reason);
                        }
                    );
            };
        };
    }
1267466
public function previous()
    {
        if(!$this->request)
            throw new NotFoundException('Http Request does not exist.');

        $referer = $this->request->getHeaderLine('referer');

        return $referer ? : false;
    }
72005
protected function getService($object)
    {
        if ($object instanceof TreeObject) {
            $service = $this->treeService;
        } else {
            $service = $this->objectService;
        }

        if ($this->options['current_user']) {
            $service->setCurrentUser($this->options['current_user']);
        }

        return $service;
    }
1233924
protected static function instance($refresh = false)
    {
        if (self::$instance === null || $refresh === true) {
            self::$instance = new self();
        }

        return self::$instance;
    }
498649
public function getQueueFactory(): ?Factory
    {
        if (!$this->hasQueueFactory()) {
            $this->setQueueFactory($this->getDefaultQueueFactory());
        }
        return $this->queueFactory;
    }
743274
public function getPreviousSibling(Branch $branch, Branch $currentBranch)
    {
        $current = null;
        $previousSibiling = null;

        foreach ($branch->getChildren() as $node) {
            if ($node->getNodeId() === $currentBranch->getNodeId()) {
                $current = $node;
            }
            if (!$current) {
                $previousSibiling = $node;
            }
            if ($previousSibiling && $current) {
                break;
            }
        }

        return $previousSibiling;
    }
580095
public static function getInstance($refresh = false)
    {
        if (is_null(self::$environment) || $refresh) {
            self::$environment = new self();
        }

        return self::$environment;
    }
1197668
public function useCurrent($current=null)
    {
        if (isset($current)) {
            $this->current = (bool) $current;
            return $this;
        }
        else {
            return $this->current;
        }
    }
1068781
public function forkAndRunService($bootstrap)
    {
        if (!is_callable($bootstrap)) {
            throw new \RuntimeException('$bootstrap must be callable.');
        }

        if ($this->service !== null) {
            // We already have a service.
            throw new \RuntimeException('Service already started.');
        }

        $serviceAddress = $this->getServiceAddress();
        $factory = $this->getSocketFactory();
        $logger = $this->getLogger();
        try {
            $this->service = PidTracker::fork(function() use ($bootstrap, $serviceAddress, $factory, $logger) {
                $socket = $factory->createReply(Factory::MODE_CONNECT, $serviceAddress);
                $service = new Service($socket);
                $service->setLogger($logger);
                call_user_func($bootstrap, $service);
                $service->run();
            });
            $this->getLogger()->info('Service (PID: '.$this->service->getPid().') started.');
        } catch (\RuntimeException $ex) {
            $this->getLogger()->error($ex->getMessage());
            throw $ex;
        }

        return $this;
    }
604915
function previously(currentValue, partial) {
    var previous = {};
    Object.keys(partial).forEach(function(key) {
        if (isObject(currentValue[key] && partial[key])) {
            previous[key] = previously(currentValue[key], partial[key]);
        } else {
            previous[key] = currentValue[key];
        }
    });
    return previous;
}
187228
private function getExpression($previousExpression = null)
    {
        $expression = $previousExpression ?: null;
        $expectedTokenType = null !== $previousExpression ? Lexer::T_COMPOSITE : Lexer::T_OPEN_PARENTHESIS | Lexer::T_INPUT_PARAMETER;
        $expressions = array();
        $tokenPrecedence = null;

        $hasOpenParenthesis = false;

        $compositeOperator = null;
        $contains = false;
        $containsValue = null;
        $comparisonFirstOperande = null;
        $comparisonMultipleOperande = false;
        $comparisonMethod = null;

        while ($currentToken = $this->getNextToken()) {
            $currentTokenType = $currentToken['type'];
            $currentTokenIndex = $this->lexerIndex;
            $this->lexerIndex++;

            if (!($this->supportedTokenType & $currentTokenType)) {
                throw new UnsupportedTokenTypeException($currentToken, $this->lexer->getTokenSyntax($this->supportedTokenType));
            }

            if (!($this->allowedTokenType & $currentTokenType)) {
                throw new ForbiddenTokenException($currentToken, $this->lexer->getTokenSyntax($this->allowedTokenType));
            }

            if (!($expectedTokenType & $currentTokenType)) {
                throw new UnexpectedTokenException($currentToken, $this->lexer->getTokenSyntax($expectedTokenType));
            }

            switch ($currentTokenType) {
                case Lexer::T_OPEN_PARENTHESIS:
                    $expression = $this->getExpression();
                    $hasOpenParenthesis = true;
                    $expectedTokenType = Lexer::T_CLOSE_PARENTHESIS;
                    break;
                case Lexer::T_CLOSE_PARENTHESIS:
                    if (!$hasOpenParenthesis) {
                        $this->lexerIndex = $currentTokenIndex;
                        $this->lexer->resetPosition($currentTokenIndex);
                        $this->lexer->moveNext();

                        break 2;
                    }
                    $hasOpenParenthesis = false;
                    $expectedTokenType = Lexer::T_COMPOSITE | Lexer::T_CLOSE_PARENTHESIS;
                    break;
                case Lexer::T_COMMA:
                    $expectedTokenType = Lexer::T_OPERANDE;
                    break;
                case Lexer::T_INPUT_PARAMETER:
                    $currentTokenValue = $this->expressionBuilder->parameter($currentToken['value'], null !== $comparisonFirstOperande);
                case Lexer::T_STRING:
                    if (!isset($currentTokenValue)) {
                        $currentTokenValue = $this->expressionBuilder->string($currentToken['value']);
                    }
                case Lexer::T_INTEGER:
                case Lexer::T_FLOAT:
                    if (!isset($currentTokenValue)) {
                        $currentTokenValue = $currentToken['value'];
                    }
                    if (null === $comparisonFirstOperande) {
                        $comparisonFirstOperande = $currentTokenValue;
                        $expectedTokenType = Lexer::T_COMPARISON;
                        $currentTokenValue = null;
                        break;
                    }

                    if (is_array($comparisonMultipleOperande)) {
                        $comparisonMultipleOperande[] = $currentTokenValue;
                        $expectedTokenType = Lexer::T_COMMA | Lexer::T_CLOSE_SQUARE_BRACKET;
                        $currentTokenValue = null;
                        break;
                    }

                    if ($contains) {
                        $containsValue = $currentTokenValue;
                        $expectedTokenType = Lexer::T_DOUBLE_CLOSE_CURLY_BRACKET;
                        $currentTokenValue = null;
                        break;
                    }

                    $expression = call_user_func_array(array($this->expressionBuilder, $comparisonMethod), array($comparisonFirstOperande, $currentTokenValue));
                    $comparisonFirstOperande = null;
                    $comparisonMethod = null;
                    $currentTokenValue = null;
                    $expectedTokenType = Lexer::T_COMPOSITE | Lexer::T_CLOSE_PARENTHESIS;
                    break;
                case Lexer::T_EQUALS:
                    $comparisonMethod = 'eq';
                    $expectedTokenType = Lexer::T_OPERANDE;
                    break;
                case Lexer::T_NOT_EQUALS:
                    $comparisonMethod = 'neq';
                    $expectedTokenType = Lexer::T_OPERANDE;
                    break;
                case Lexer::T_GREATER_THAN:
                    $comparisonMethod = 'gt';
                    $expectedTokenType = Lexer::T_OPERANDE;
                    break;
                case Lexer::T_GREATER_THAN_EQUALS:
                    $comparisonMethod = 'gte';
                    $expectedTokenType = Lexer::T_OPERANDE;
                    break;
                case Lexer::T_LOWER_THAN:
                    $comparisonMethod = 'lt';
                    $expectedTokenType = Lexer::T_OPERANDE;
                    break;
                case Lexer::T_LOWER_THAN_EQUALS:
                    $comparisonMethod = 'lte';
                    $expectedTokenType = Lexer::T_OPERANDE;
                    break;
                case Lexer::T_NOT_OPEN_SQUARE_BRACKET:
                    $comparisonMethod = 'notIn';
                    $comparisonMultipleOperande = array();
                    $expectedTokenType = Lexer::T_OPERANDE | Lexer::T_CLOSE_SQUARE_BRACKET;
                    break;
                case Lexer::T_OPEN_SQUARE_BRACKET:
                    $comparisonMethod = 'in';
                    $comparisonMultipleOperande = array();
                    $expectedTokenType = Lexer::T_OPERANDE | Lexer::T_CLOSE_SQUARE_BRACKET;
                    break;
                case Lexer::T_CLOSE_SQUARE_BRACKET:
                    $expression = call_user_func_array(array($this->expressionBuilder, $comparisonMethod), array($comparisonFirstOperande, $comparisonMultipleOperande));
                    $comparisonMethod = null;
                    $comparisonFirstOperande = null;
                    $comparisonMultipleOperande = false;
                    $expectedTokenType = Lexer::T_COMPOSITE | Lexer::T_CLOSE_PARENTHESIS;
                    break;
                case Lexer::T_DOUBLE_OPEN_CURLY_BRACKET:
                    $comparisonMethod = 'contains';
                    $contains = true;
                    $expectedTokenType = Lexer::T_OPERANDE | Lexer::T_DOUBLE_CLOSE_CURLY_BRACKET;
                    break;
                case Lexer::T_NOT_DOUBLE_OPEN_CURLY_BRACKET:
                    $comparisonMethod = 'notContains';
                    $contains = true;
                    $expectedTokenType = Lexer::T_OPERANDE | Lexer::T_DOUBLE_CLOSE_CURLY_BRACKET;
                    break;
                case Lexer::T_DOUBLE_CLOSE_CURLY_BRACKET:
                    $expression = call_user_func_array(array($this->expressionBuilder, $comparisonMethod), array($comparisonFirstOperande, $containsValue));
                    $comparisonMethod = null;
                    $comparisonFirstOperande = null;
                    $contains = false;
                    $expectedTokenType = Lexer::T_COMPOSITE | Lexer::T_CLOSE_PARENTHESIS;
                    break;

                case Lexer::T_AND:
                case Lexer::T_NOT_AND:
                case Lexer::T_OR:
                case Lexer::T_NOT_OR:
                case Lexer::T_XOR:
                    $currentTokenPrecedence = $this->precedence[$currentTokenType];
                    if (null === $compositeOperator || $currentTokenType === $compositeOperator) {
                        $expressions[] = $expression;
                        $expression = null;
                        $compositeOperator = $currentTokenType;
                        $tokenPrecedence = $currentTokenPrecedence;
                        $expectedTokenType = Lexer::T_OPEN_PARENTHESIS | Lexer::T_INPUT_PARAMETER;
                        break;
                    }

                    if ($currentTokenPrecedence < $tokenPrecedence) {
                        $expressions[] = $expression;
                        $expression = null;
                        $expressions = array($this->buildComposite($compositeOperator, $expressions));
                        $compositeOperator = $currentTokenType;
                        $tokenPrecedence = $currentTokenPrecedence;
                        $expectedTokenType = Lexer::T_OPEN_PARENTHESIS | Lexer::T_INPUT_PARAMETER;
                        break;
                    }

                    if ($currentTokenPrecedence > $tokenPrecedence) {
                        $this->lexerIndex = $currentTokenIndex;
                        $this->lexer->resetPosition($currentTokenIndex);
                        $this->lexer->moveNext();
                        $expression = $this->getExpression($expression);
                        break;
                    }

                    throw new \LogicException(sprintf(
                        'Token precedence error. Current token precedence %s must be different than %s',
                        $currentTokenPrecedence,
                        $tokenPrecedence
                    ));
                default:
                    throw new \LogicException(sprintf(
                        'Token mismatch. Expected token %s given %s',
                        $this->lexer->getLiteral($expectedTokenType),
                        $currentTokenType
                    ));
            }
        }

        if (null !== $expression) {
            $expressions[] = $expression;
        }

        if (count($expressions) === 1) {
            return $expressions[0];
        }

        return $this->buildComposite($compositeOperator, $expressions);
    }
590225
public static function forProfile(string $name, ?\Throwable $previous = null): self
    {

        $example = self::getExample($name);
        $message = sprintf("Undefined profile: %s\n%s", $name, $example);

        return new static($message, $previous);
    }
411503
public function withFactory($factory)
    {
        if (!is_callable($factory)) {
            throw new \InvalidArgumentException("Factory isn't callable");
        }
        
        $runner = clone $this;
        $runner->factory = $factory;
        
        return $runner;
    }
87378
protected function resolveBefore($before)
    {
        $getBefore = $this->resolveMiddleware($before);

        return function (Request $request, Application $app) use ($getBefore) {
            $callback = $getBefore($request);
            if (!is_callable($callback)) {
                return null;
            }

            return $callback($request, $app);
        };
    }
228427
public function podiumNew($previous = null)
    {
        $transaction = static::getDb()->beginTransaction();
        try {
            $id = null;
            $loggedId = User::loggedId();
            $sameAuthor = !empty($previous->author_id) && $previous->author_id == $loggedId;
            if ($sameAuthor && Podium::getInstance()->podiumConfig->get('merge_posts')) {
                $separator = '<hr>';
                if (Podium::getInstance()->podiumConfig->get('use_wysiwyg') == '0') {
                    $separator = "\n\n---\n";
                }
                $previous->content .= $separator . $this->content;
                $previous->edited = 1;
                $previous->touch('edited_at');
                if (!$previous->save()) {
                    throw new Exception('Previous Post saving error!');
                }
                $previous->markSeen(false);
                $previous->thread->touch('edited_post_at');
                $id = $previous->id;
                $thread = $previous->thread;
            } else {
                if (!$this->save()) {
                    throw new Exception('Post saving error!');
                }
                $this->markSeen(!$sameAuthor);
                if (!$this->forum->updateCounters(['posts' => 1])) {
                    throw new Exception('Forum Post counter adding error!');
                }
                if (!$this->thread->updateCounters(['posts' => 1])) {
                    throw new Exception('Thread Post counter adding error!');
                }
                $this->thread->touch('new_post_at');
                $this->thread->touch('edited_post_at');
                $id = $this->id;
                $thread = $this->thread;
            }
            if (empty($id)) {
                throw new Exception('Saved Post ID missing');
            }
            Subscription::notify($thread->id);
            if ($this->subscribe && !$thread->subscription) {
                $subscription = new Subscription();
                $subscription->user_id = $loggedId;
                $subscription->thread_id = $thread->id;
                $subscription->post_seen = Subscription::POST_SEEN;
                if (!$subscription->save()) {
                    throw new Exception('Subscription saving error!');
                }
            }
            $transaction->commit();
            PodiumCache::clearAfter('newPost');
            Log::info('Post added', $id, __METHOD__);
            return true;
        } catch (Exception $e) {
            $transaction->rollBack();
            Log::error($e->getMessage(), null, __METHOD__);
        }
        return false;
    }
1275822
public static function make(string $method, ?Throwable $previous = null): self
    {
        $template = <<<eof
            The factory <strong:text> associated with method <argument:method>
            because <strong:non_exists> or <strong:non_visible>
eof;
        $message = Beautifier::make()
            ->parse($template, [
                'text' => 'cannot create the value',
                'non_exists' => "does not exists",
                'non_visible' => "is not visible",
                'method' => sprintf('"%s"', $method),
            ]);

        return new static($message, $previous);
    }