public function resolve($alias, array $args = [])
    {

        // if it is an alias we will solve the orjinal one
        if (isset($this->aliases[$alias])) {
            $alias = $this->aliases[$alias];
        }

        $singleton = $this->getBoundManager()->singleton($alias);

        // determine the alias already resolved before or not.
        if ($singleton && $this->hasResolvedBefore($alias)) {

            // we resolved that before, let's reuse it.
            return $this->getAlreadyResolved($alias);
        }

        // we realized we did not add this before
        if (false === $this->boundManager->has($alias)) {
            $this->add($alias, $alias);

            // resolve this service with given args
            return $this->resolve($alias, $args);
        }


        $definition = $this
            ->boundManager
            ->findDefinition($alias);

        // if we add new args, we'll set them into definition
        if ( ! empty($args)) {
            $this->getArgumentManager()->setClassArgs(
                $alias,
                $args
            );
        }

        // determine resolved instance is as we expected or not
        $resolved = $this->checkExpectation(
            $alias,
            $this->resolveObject($definition, $alias)
        );


        // we resolved the definition, now we will add into resolvedBond or sharedResolved
        // and we will reuse they when we want to resolve them
        $this->saveResolved($alias, $resolved);

        // we already resolve and saved it. We don't need this definition anymore.
        // so we will remove it.
        // this will save memory
        if ($singleton === true) {
            $this->removeResolvedFromBound($alias);
        }

        return $resolved;
    }