Takes the defaults and current options, merges them and returns options which have
the default keys removed and full set of options as the scope.

@param array $defaults
@param array $scope the complete set of options
@return array $scope, $options
345315
protected function _options(array $defaults, array $scope) {
		$scope += $defaults;
		$options = array_diff_key($scope, $defaults);
		return [$scope, $options];
	}
463177
private function figureOutWhichIncludes(Scope $scope)
    {
        $includes = $this->getDefaultIncludes();
        foreach ($this->getAvailableIncludes() as $include) {
            if ($scope->isRequested($include)) {
                $includes[] = $include;
            }
        }

        return $includes;
    }
52196
protected function mergeDefaults(array $params, array $defaults): array
    {
        foreach ($params as $key => $value) {
            if (!\is_int($key) && null !== $value) {
                $defaults[$key] = $value;
            }
        }

        return $defaults;
    }
788250
public function withoutGlobalScopes(array $scopes = null)
    {
        if (! is_array($scopes)) {
            $scopes = array_keys($this->scopes);
        }

        foreach ($scopes as $scope) {
            $this->withoutGlobalScope($scope);
        }

        return $this;
    }
752454
protected static function mergeDefinitions(array $keys, array $customs, array $defaultValues)
    {
        $final = $defaultValues;

        foreach ($customs as $key => $custom) {

            if (!is_array($custom) || !array_key_exists('match', $custom) || !array_key_exists('set', $custom)) {
                continue;
            }
            $matches = (array) $custom['match'];
            $combined = array_intersect($keys, $matches);

            if (!empty($combined)) {
                $final = array_merge($final, (array) $custom['set']);
            }
        }

        return $final;
    }
351193
private function figureOutWhichIncludes(Scope $scope)
    {
        $includes = $this->getDefaultIncludes();

        foreach ($this->getAvailableIncludes() as $include) {
            if ($scope->isRequested($include)) {
                $includes[] = $include;
            }
        }

        foreach ($includes as $include) {
            if ($scope->isExcluded($include)) {
                $includes = array_diff($includes, [$include]);
            }
        }

        return $includes;
    }
1148051
private function mergeDefaults(&$options)
    {
        // Merging optimization for when no headers are present
        if (!isset($options['headers'])
            || !isset($this->defaults['headers'])) {
            $options = array_replace_recursive($this->defaults, $options);
            return null;
        }

        $defaults = $this->defaults;
        unset($defaults['headers']);
        $options = array_replace_recursive($defaults, $options);

        return $this->defaults['headers'];
    }
1093628
public function getScopeValue($scope, $default = null)
    {
        if (is_string($scope)) {
            $scope = $this->getScope($scope);
        }

        $cacheKey = 'scope-'.$scope->scopeName;
        return $this->getSession($cacheKey, $default);
    }
201735
protected function mergeAttributesWith( array $defaults )
	{
		// similar to array_merge except overwrite empty values
		foreach( $defaults as $key => $value ) {
			if( isset( $this->args[ $key ] ) && !empty( $this->args[ $key ] ))continue;
			$this->args[ $key ] = $value;
		}

		$attributes = $this->args['attributes'];

		// prioritize $attributes over $this->args, don't worry about duplicates
		return array_merge( $this->args, $attributes );
	}
319586
public function scope($scope)
	{
		$scope = (new Scope())->scope($scope);

		$this->scopes[] = $scope;
		return $scope;
	}
360625
protected function getAvailableOptions($scope, $searchQuery = null)
    {
        if ($scope->options) {
            return $this->getOptionsFromArray($scope, $searchQuery);
        }

        $available = [];
        $nameColumn = $this->getScopeNameFrom($scope);
        $options = $this->getOptionsFromModel($scope, $searchQuery);
        foreach ($options as $option) {
            $available[$option->getKey()] = $option->{$nameColumn};
        }

        return $available;
    }
79807
public function removeScope($scope)
    {
        $this->validateScopeValue($scope);

        $key = $this->getScopeKey($scope);
        if (false === $key) {
            return $this;
        }

        unset($this->descriptor['scopes'][$key]);
        return $this;
    }
1328135
public static function config($config = null) {
		$defaults = ['scope' => null];

		if (is_array($config)) {
			foreach ($config as $i => $item) {
				$config[$i] += $defaults;
			}
		}
		return parent::config($config);
	}
928596
public function setScopes(Mutable $scopes = null)
    {
        if ($scopes && $scopes->count()) {
            $scopes->prepend(
                new Scope('all')
            );
        }

        $this->scopes = $scopes;

        return $this;
    }
1023653
public function setScopes(array $scopes = null)
    {
        ValidationUtility::ensureNullOrArrayOfString('$scopes', $scopes);

        $this->scopes = $scopes;

        return $this;
    }
549838
public function scopes(array $scopes)
    {
        $builder = $this;

        foreach ($scopes as $scope => $parameters) {
            // If the scope key is an integer, then the scope was passed as the value and
            // the parameter list is empty, so we will format the scope name and these
            // parameters here. Then, we'll be ready to call the scope on the model.
            if (is_int($scope)) {
                [$scope, $parameters] = [$parameters, []];
            }

            // Next we'll pass the scope callback to the callScope method which will take
            // care of grouping the "wheres" properly so the logical order doesn't get
            // messed up when adding scopes. Then we'll return back out the builder.
            $builder = $builder->callScope(
                [$this->model, 'scope'.ucfirst($scope)],
                (array) $parameters
            );
        }

        return $builder;
    }
494828
public function create($options, $defaults = array())
    {
        if (is_array($options)) {
            $options += $defaults;
            $options = $this->format($options);
            $options = $this->normalize($options);

            $options = new RequestOptions($options);
        } elseif ($options instanceof RequestOptions) {
            $defaults = $this->create($defaults);
            $options->addDefaultHeaders($defaults->getHeaders());
            $options->addDefaultQueryParameters($defaults->getQueryParameters());
            $options->addDefaultBodyParameters($defaults->getBody());
        } else {
            throw new \InvalidArgumentException(
                'RequestOptions can only be created from array or from RequestOptions object'
            );
        }

        return $options->addDefaultHeaders($this->config->getDefaultHeaders());
    }