src/main/java/js/container/Container.java
@SuppressWarnings("unchecked")
	private <T> T getInstance(ManagedClassSPI managedClass, InstanceKey instanceKey, Object... args) {
		// if(managedClass.getInstanceType().isREMOTE()) {
		// return getRemoteInstance(new URL(managedClass.getImplementationURL()), (Class<? super T>)
		// managedClass.getInterfaceClass());
		// }

		ScopeFactory scopeFactory = scopeFactories.get(managedClass.getInstanceScope());
		InstanceFactory instanceFactory = instanceFactories.get(managedClass.getInstanceType());

		if (scopeFactory == null) {
			args = argumentsProcessor.preProcessArguments(managedClass, args);
			return instanceFactory.newInstance(managedClass, args);
		}

		boolean postProcessingEnabled = false;
		Object instance = null;
		synchronized (scopeMutex) {
			instance = scopeFactory.getInstance(instanceKey);
			if (instance == null) {
				postProcessingEnabled = true;
				args = argumentsProcessor.preProcessArguments(managedClass, args);
				instance = instanceFactory.newInstance(managedClass, args);
				scopeFactory.persistInstance(instanceKey, instance);
			}
		}

		if (!postProcessingEnabled) {
			return (T) instance;
		}

		// post-processors operate on bare POJO instances but is possible for instance factory to return a Java Proxy
		// if instance is a Java Proxy that uses InstanceInvocationHandler extract wrapped POJO instance
		// if instance is a Java Proxy that does not use InstanceInvocationHandler post-processing is not performed at all
		// if instance is not a Java Proxy execute post-processing on it

		Object pojoInstance = null;
		if (instance instanceof Proxy) {
			if (Proxy.getInvocationHandler(instance) instanceof InstanceInvocationHandler) {
				InstanceInvocationHandler<T> handler = (InstanceInvocationHandler<T>) Proxy.getInvocationHandler(instance);
				pojoInstance = handler.getWrappedInstance();
			}
		} else {
			pojoInstance = instance;
		}

		if (pojoInstance != null) {
			for (InstanceProcessor instanceProcessor : instanceProcessors) {
				instanceProcessor.postProcessInstance(managedClass, pojoInstance);
			}
		}

		return (T) instance;
	}
@SuppressWarnings("unchecked")
	private <T> T getInstance(ManagedClassSPI managedClass, InstanceKey instanceKey, Object... args) {
		// if(managedClass.getInstanceType().isREMOTE()) {
		// return getRemoteInstance(new URL(managedClass.getImplementationURL()), (Class<? super T>)
		// managedClass.getInterfaceClass());
		// }

		ScopeFactory scopeFactory = scopeFactories.get(managedClass.getInstanceScope());
		InstanceFactory instanceFactory = instanceFactories.get(managedClass.getInstanceType());

		if (scopeFactory == null) {
			args = argumentsProcessor.preProcessArguments(managedClass, args);
			return instanceFactory.newInstance(managedClass, args);
		}

		boolean postProcessingEnabled = false;
		Object instance = null;
		synchronized (scopeMutex) {
			instance = scopeFactory.getInstance(instanceKey);
			if (instance == null) {
				postProcessingEnabled = true;
				args = argumentsProcessor.preProcessArguments(managedClass, args);
				instance = instanceFactory.newInstance(managedClass, args);
				scopeFactory.persistInstance(instanceKey, instance);
			}
		}

		if (!postProcessingEnabled) {
			return (T) instance;
		}

		// post-processors operate on bare POJO instances but is possible for instance factory to return a Java Proxy
		// if instance is a Java Proxy that uses InstanceInvocationHandler extract wrapped POJO instance
		// if instance is a Java Proxy that does not use InstanceInvocationHandler post-processing is not performed at all
		// if instance is not a Java Proxy execute post-processing on it

		Object pojoInstance = null;
		if (instance instanceof Proxy) {
			if (Proxy.getInvocationHandler(instance) instanceof InstanceInvocationHandler) {
				InstanceInvocationHandler<T> handler = (InstanceInvocationHandler<T>) Proxy.getInvocationHandler(instance);
				pojoInstance = handler.getWrappedInstance();
			}
		} else {
			pojoInstance = instance;
		}

		if (pojoInstance != null) {
			for (InstanceProcessor instanceProcessor : instanceProcessors) {
				instanceProcessor.postProcessInstance(managedClass, pojoInstance);
			}
		}

		return (T) instance;
	}
Utility method that implements the core of managed instances retrieval algorithm. This method gets existing managed
instance from container caches or creates a new instance. If instance is fresh created add instance services via
registered instance processors.
<p>
Here is managed instance retrieval algorithm part implemented by this method.
<ol>
<li>get scope and instance factories for managed class instance scope and type; if managed class instance scope is local
there is no scope factory,
<li>if scope factory is null execute local instance factory, that creates a new instance, and returns it; applies
arguments processing on local instance but not instance processors,
<li>if there is scope factory do next steps into synchronized block,
<li>try to retrieve instance from scope factory cache,
<li>if no cached instance pre-process arguments, create a new instance using instance factory and persist instance on
scope factory,
<li>end synchronized block,
<li>arguments pre-processing takes care to inject constructor dependencies,
<li>if new instance is created execute instance post-processors into registration order.
</ol>

@param managedClass managed class for which instance is to be retrieved,
@param instanceKey managed instance key,
@param args optional constructor arguments, used only if new local instance is created.
@param <T> managed instance type.
@return managed instance, created on the fly or reused from caches, but never null.

@throws InvocationException if instance is local and constructor fails.
@throws NoProviderException if interface is a service and no provider found on run-time.
@throws ConverterException if attempt to initialize a field with a type for which there is no converter,
@throws BugError if dependency value cannot be created or circular dependency is detected.
@throws BugError if instance configuration fails either due to bad configuration object or fail on configuration user
defined logic.
@throws BugError if instance post-construction fails due to exception of user defined logic.
@throws BugError if attempt to assign field to not POJO type.