@param string $name
@param array  $step
@param array  $conditions
@param array  $metDependencies
@param array  $stepArguments

@return array $providedDependencies
324811
private function runStep(
        string $name,
        array $step,
        array $conditions,
        array $metDependencies,
        array $stepArguments
    ): array {

        // If array, run commands in parallel
        if (!empty($step['steps'])) {
            $providedDependencies = [];
            foreach ($step['steps'] as $parallelName => $parallelStep) {
                Loop::delay(
                    0,
                    // Since these are run in parallel, they cannot provide dependencies for each other
                    function () use (
                        $parallelName,
                        $parallelStep,
                        $conditions,
                        $metDependencies,
                        $stepArguments,
                        &
                        $providedDependencies
                    ) {
                        $stepProvidedDependencies = $this->runStep(
                            $parallelName,
                            $parallelStep,
                            $conditions,
                            $metDependencies,
                            $stepArguments
                        );
                        $providedDependencies = array_unique(
                            array_merge($providedDependencies, $stepProvidedDependencies)
                        );
                    }
                );
            }

            Loop::run();
            return $providedDependencies;
        }

        if (!empty($step['conditions'])) {
            if (!array_intersect($conditions, $step['conditions'])) {
                $this->logger->debug(
                    sprintf(
                        'Step: %s - skipped because run %s [%s] not met.',
                        $name,
                        (1 == count($step['conditions'])) ? 'condition' : 'conditions',
                        implode(', ', $step['conditions'])
                    )
                );
                return [];
            }
        }

        if (!empty($step['depends'])) {
            $allDependenciesMet = count(array_intersect($metDependencies, $step['depends'])) == count($step['depends']);
            if (!$allDependenciesMet) {
                $this->logger->debug(
                    sprintf(
                        'Step: %s - skipped because %s [%s] not deployed.',
                        $name,
                        (1 == count($step['depends'])) ? 'dependency' : 'dependencies',
                        implode(', ', $step['depends'])
                    )
                );
                return [];
            }
        }

        $this->logger->info("Step: $name");
        if (!empty($step['comment'])) {
            $this->logger->debug($step['comment']);
        }
        # @todo Add logic that logs a notice if run_in_code_root is specified for a given step, but class is given instead of command
        $commandWorkingDirectory = !empty($step['run_in_code_root'])
            ? $stepArguments['codePath']
            : $this->planPath;

        if (!empty($step['command'])) {
            $environmentVariables = array_replace(
                getenv(),
                $stepArguments,
                $step['environment_variables'] ?? []
            );

            $stringEnvironmentVariables = [];
            foreach ($environmentVariables as $key => $value) {
                if (is_string($value)) {
                    $stringEnvironmentVariables[$key] = $value;
                }
            }

            $output = $this->shellAdapter->runShellCommand(
                $step['command'],
                $commandWorkingDirectory,
                $stringEnvironmentVariables,
                $step['run_priority'] ?? ShellAdapterInterface::PRIORITY_NORMAL,
                $step['options'] ?? null
            );

            // @todo Allow callable? Not sure where this could be more useful than creating a class that implements the
            //       correct interface and this could cause confusion
//        } elseif (!empty($step['callable'])) {
//            chdir($commandWorkingDirectory);
//            $output = call_user_func_array($step['callable'], $step['arguments'] ?? []);
        } else {
            chdir($commandWorkingDirectory);
            $stepObject = new $step['class']();
            if ($stepObject instanceof LoggerAwareInterface) {
                $stepObject->setLogger($this->logger);
            }

            if ($stepObject instanceof ApplicationConfigAwareInterface) {
                $stepObject->setApplicationConfig($this->applicationConfig);
            }

            if ($stepObject instanceof RepositoryAdapterAwareInterface) {
                $stepObject->setRepositoryAdapter($this->repositoryAdapter);
            }

            if ($stepObject instanceof ShellAdapterAwareInterface) {
                $stepObject->setShellAdapter($this->shellAdapter);
            }

            if ($stepObject instanceof MountManagerAwareInterface) {
                $stepObject->setMountManager($this->mountManager);
            }

            if ($stepObject instanceof MaintenanceStrategyAwareInterface) {
                $stepObject->setMaintenanceStrategy($this->maintenanceStrategy);
            }

            if ($stepObject instanceof DatabaseAdapterManagerAwareInterface) {
                $stepObject->setDatabaseAdapterManager($this->databaseAdapterManager);
            }

            if ($stepObject instanceof DatabaseImportExportAdapterManagerAwareInterface) {
                $stepObject->setDatabaseImportExportAdapterManager($this->databaseImportExportAdapterManager);
            }

            if ($stepObject instanceof ApplicationSkeletonDeployerAwareInterface) {
                $stepObject->setApplicationSkeletonDeployer($this->applicationSkeletonDeployer);
            }

            if ($stepObject instanceof ApplicationCodeDeployerAwareInterface) {
                $stepObject->setApplicationCodeDeployer($this->applicationCodeDeployer);
            }

            if ($stepObject instanceof ApplicationAssetDeployerAwareInterface) {
                $stepObject->setApplicationAssetDeployer($this->applicationAssetDeployer);
            }

            if ($stepObject instanceof ApplicationDatabaseDeployerAwareInterface) {
                $stepObject->setApplicationDatabaseDeployer($this->applicationDatabaseDeployer);
            }

            $output = call_user_func_array(
                [$stepObject, 'run'],
                array_merge($stepArguments, ['options' => $step['options'] ?? []])
            );
        }

        if (!empty($output)) {
            $output = trim($output);
            // If output is multi-line, start the output on a new line
            if (false !== strpos($output, "\n")) {
                $output = "\n$output";
            }
            $this->logger->debug('Step "' . $name . '" output: ' . $output);
        }

        return $step['provides'] ?? [];
    }
302951
public function addRelation($name) {
    if (!$this->hasValue($name)) {
      $this->relationStates[$name] = self::RELATION_STATE_UNINITIALIZED;
      $this->setValueInternal($name, null);
    }
  }
94603
protected function buildSteps($processName, $steps, $container, $stepClass)
    {
        $stepReferences = array();

        foreach ($steps as $stepName => $stepConfig) {
            $definition = new Definition($stepClass, array(
                $stepName,
                $stepConfig['label'],
                array(),
                $stepConfig['model_status'],
                $stepConfig['roles'],
                $stepConfig['on_invalid'],
            ));

            $this->addStepNextStates($definition, $stepConfig['next_states'], $processName);

            $definition->setPublic(false)
                       ->addTag(sprintf('lexik_workflow.process.%s.step', $processName), array('alias' => $stepName));

            $stepReference = sprintf('lexik_workflow.process.%s.step.%s', $processName, $stepName);
            $container->setDefinition($stepReference, $definition);

            $stepReferences[$stepName] = new Reference($stepReference);
        }

        return $stepReferences;
    }
1326717
public function add($name, $dependencyUnit, $arguments = array()) {
        if (is_object($dependencyUnit)) {
            $dependencyClass = get_class($dependencyUnit);
        } else {
            $dependencyClass = $dependencyUnit;
        }
        if (!is_array($arguments)) $arguments = array('arguments' => $arguments);

        $this->_dependencies[$name] = array_merge($arguments, array(
            'className' => $dependencyClass,
            'object'    => !empty($arguments['object']) ? $arguments['object'] : null
        ));
    }
151490
public static function get_store_instance_actions($name, array $storedetails) {
        $actions = array();
        if (has_capability('moodle/site:config', context_system::instance())) {
            $baseurl = new moodle_url('/cache/admin.php', array('store' => $name, 'sesskey' => sesskey()));
            if (empty($storedetails['default'])) {
                $actions[] = array(
                    'text' => get_string('editstore', 'cache'),
                    'url' => new moodle_url($baseurl, array('action' => 'editstore', 'plugin' => $storedetails['plugin']))
                );
                $actions[] = array(
                    'text' => get_string('deletestore', 'cache'),
                    'url' => new moodle_url($baseurl, array('action' => 'deletestore'))
                );
            }
            $actions[] = array(
                'text' => get_string('purge', 'cache'),
                'url' => new moodle_url($baseurl, array('action' => 'purgestore'))
            );
        }
        return $actions;
    }
1037415
public function callCatchAll($entity, $name, $args, &$processed) {
		#$article->authors()
		if($this->getDataMapper()->hasRelation($this->definition, $name)) {
			$processed = true;
			return $this->getDataMapper()->related($entity, $name);
		}
	}
156060
protected function create($step)
    {
        $roleService = $this->repository->getRoleService();
        $userService = $this->repository->getUserService();

        $roleName = $this->referenceResolver->resolveReference($step->dsl['name']);
        $roleCreateStruct = $roleService->newRoleCreateStruct($roleName);

        // Publish new role
        $role = $roleService->createRole($roleCreateStruct);
        if (is_callable(array($roleService, 'publishRoleDraft'))) {
            $roleService->publishRoleDraft($role);
        }

        if (isset($step->dsl['policies'])) {
            foreach ($step->dsl['policies'] as $key => $ymlPolicy) {
                $this->addPolicy($role, $roleService, $ymlPolicy);
            }
        }

        if (isset($step->dsl['assign'])) {
            $this->assignRole($role, $roleService, $userService, $step->dsl['assign']);
        }

        $this->setReferences($role, $step);

        return $role;
    }
348759
private function sort(array $stageSteps)
    {
        if (empty($stageSteps)) {
            return [];
        }

        $dependencyGraphBuilder = new StepDependencyGraphBuilder($stageSteps);
        return $dependencyGraphBuilder->build()->sort();
    }
687172
protected function loadCondition($name,$models){
        if(isset($this->_condition[$name]) && !empty($this->_condition[$name])){
            $data=[];
            foreach ($this->_condition[$name] as $attribute=>$v){
                if(preg_match('/{(?P<model>\w+):(?P<attribute>\w+)}/',$v,$match)){
                    if(isset($models[$match['model']])){
                        if(isset($models[$match['model']]->{$match['attribute']})){
                            $data[$attribute]=$models[$match['model']]->{$match['attribute']};
                        }
                    }
                }
            }
            if(!empty($data)){
                return $data;
            }
        }
        return false;
    }
1250811
protected function newMethodSegment($name, array $arguments = [])
    {
        return $this->repositoryProvider->createRepository($this->newMethod($name, $arguments));
    }
292628
public function findDefinition(Environment $environment, FeatureNode $feature, StepNode $step)
    {
        foreach ($this->engines as $engine) {
            $result = $engine->searchDefinition($environment, $feature, $step);

            if (null !== $result && $result->hasMatch()) {
                return $result;
            }
        }

        return new SearchResult();
    }
259813
public function relation($name, $label, $builder = null)
    {
        if (is_null($builder)) {
            $builder = $label;
            $label = '';
        }

        return $this->addRelation($name, $builder, $label);
    }
1085392
public function executeStep($stepAction, &$stepActionParams, &$options, array &$context)
    {
        return $this->getConfHelper()->executeStep($stepAction, $stepActionParams, $options, $context);
    }
126530
public function execute($name, $args = [], $trackedArgs = [])
    {
        // In pipeline mode
        if ($this->usePipeline) {
            if ($name === 'pipeline') {
                throw new RedisException('A pipeline is already in use and only one pipeline is supported.');
            }

            if ($name === 'exec') {
                if ($this->isMulti) {
                    $this->commandNames[] = [$name, $trackedArgs];
                    $this->commands .= Helpers::prepareCommand([$name]);
                }

                // Write request
                if ($this->commands) {
                    $this->writeCommand($this->commands);
                }
                $this->commands = null;

                // Read response
                $queuedResponses = $response = [];
                foreach ($this->commandNames as $command) {
                    [$n, $arguments] = $command;
                    $result = $this->readReply($n, true);
                    if ($result !== null) {
                        $result = $this->decodeReply($n, $result, $arguments);
                    } else {
                        $queuedResponses[] = $command;
                    }
                    $response[] = $result;
                }

                if ($this->isMulti) {
                    $response = \array_pop($response);

                    foreach ($queuedResponses as $key => [$n, $arguments]) {
                        $response[$key] = $this->decodeReply($n, $response[$key], $arguments);
                    }
                }
                $this->commandNames = null;
                $this->usePipeline = $this->isMulti = false;

                return $response;
            }

            if ($name === 'discard') {
                $this->commands = null;
                $this->commandNames = null;
                $this->usePipeline = $this->isMulti = false;
            } else {
                if ($name === 'multi') {
                    $this->isMulti = true;
                }
                \array_unshift($args, $name);
                $this->commandNames[] = [$name, $trackedArgs];
                $this->commands .= Helpers::prepareCommand($args);

                return $this;
            }
        }

        // Start pipeline mode
        if ($name === 'pipeline') {
            $this->usePipeline = true;
            $this->commandNames = [];
            $this->commands = '';

            return $this;
        }

        // If unwatching, allow reconnect with no error thrown
        if ($name === 'unwatch') {
            $this->isWatching = false;
        }

        // Non-pipeline mode
        \array_unshift($args, $name);
        $command = Helpers::prepareCommand($args);
        $this->writeCommand($command);
        $response = $this->readReply($name);
        $response = $this->decodeReply($name, $response, $trackedArgs);

        // Watch mode disables reconnect so error is thrown
        if ($name === 'watch') {
            $this->isWatching = true;
        } // Transaction mode
        else {
            if ($this->isMulti && ($name === 'exec' || $name === 'discard')) {
                $this->isMulti = false;
            } // Started transaction
            else {
                if ($this->isMulti || $name === 'multi') {
                    $this->isMulti = true;
                    $response = $this;
                }
            }
        }

        return $response;
    }
848574
protected function generateRelationOptionsArray($name, Annotation $annotation, EntityDefinition &$entityMetadata)
    {
        $options = [];

        // belongsTo relation
        if ($annotation->type == 'belongsTo') {
            $options['relatedForeignKey'] = $annotation->relatedForeignKey ?: $this->generateKey($annotation->relatedEntity);
            $options['localKey'] = $annotation->localKey ?: 'id';
            $options['relation'] = $annotation->relation;
        }

        // belongsToMany relation
        if ($annotation->type == 'belongsToMany') {
            $options['pivotTable'] = $annotation->pivotTable ?: $this->generatePivotTablename($entityMetadata['class'], $annotation->relatedEntity, $annotation->inverse);
            $options['localPivotKey'] = $annotation->localPivotKey ?: $this->generateKey($entityMetadata['class']);
            $options['relatedPivotKey'] = $annotation->relatedPivotKey ?: $this->generateKey($annotation->relatedEntity);
            $options['relation'] = $annotation->relation;
        }

        // hasMany relation
        if ($annotation->type == 'hasMany') {
            $options['localForeignKey'] = $annotation->localForeignKey ?: $this->generateKey($entityMetadata['class']);
            $options['localKey'] = $annotation->localKey ?: 'id';
        }

        // hasManyThrough relation
        if ($annotation->type == 'hasManyThrough') {
            $options['throughEntity'] = $annotation->throughEntity;
            $options['localForeignKey'] = $annotation->localForeignKey ?: $this->generateKey($entityMetadata['class']);
            $options['throughForeignKey'] = $annotation->throughForeignKey ?: $this->generateKey($annotation->throughEntity);
        }

        // hasOne relation
        if ($annotation->type == 'hasOne') {
            $options['localForeignKey'] = $annotation->localForeignKey ?: $this->generateKey($entityMetadata['class']);
            $options['localKey'] = $annotation->localKey ?: 'id';
        }

        // morphMany relation
        if ($annotation->type == 'morphMany') {
            $options['morphName'] = $annotation->morphName ?: $name;
            $options['morphType'] = $annotation->morphType;
            $options['morphId'] = $annotation->morphId;
            $options['localKey'] = $annotation->localKey ?: 'id';
        }

        // morphOne relation
        if ($annotation->type == 'morphOne') {
            $options['morphName'] = $annotation->morphName ?: $name;
            $options['morphType'] = $annotation->morphType;
            $options['morphId'] = $annotation->morphId;
            $options['localKey'] = $annotation->localKey ?: 'id';
        }

        // morphTo relation
        if ($annotation->type == 'morphTo') {
            $options['morphName'] = $annotation->morphName ?: $name;
            $options['morphType'] = $annotation->morphType;
            $options['morphId'] = $annotation->morphId;
        }

        // morphToMany relation
        if ($annotation->type == 'morphToMany') {
            $options['morphName'] = $annotation->morphName ?: $name;
            $options['pivotTable'] = $annotation->pivotTable ?: $this->generatePivotTablename($entityMetadata['class'], $annotation->relatedEntity, $annotation->inverse, $annotation->morphName);
            if ($annotation->inverse) {
                $options['localPivotKey'] = $annotation->localPivotKey ?: $this->generateKey($entityMetadata['class']);
                $options['relatedPivotKey'] = $annotation->morphName.'_id';
            } else {
                $options['localPivotKey'] = $annotation->morphName.'_id';
                $options['relatedPivotKey'] = $annotation->relatedPivotKey ?: $this->generateKey($annotation->relatedEntity);
            }
            $options['inverse'] = $annotation->inverse;
        }

        return $options;
    }
536031
private function pushPipelineStep($name, $stepConfig) {
		$lastStep = $this->Steps()->sort("Order DESC")->first();
		$order = $lastStep ? $lastStep->Order + 1 : 1;
		return $this->generateStep($name, $stepConfig, $order);
	}
514192
public function inc(string $name, int $step = 1)
    {
        $this->writeTimes++;

        $key = $this->getCacheKey($name);

        if ($this->handler->get($key)) {
            return $this->handler->increment($key, $step);
        }

        return $this->handler->set($key, $step);
    }