import { ServiceIdentifier, Either, Newable, LazyServiceIdentifier } from '@inversifyjs/common';

declare function getBindingId(): number;

type BindingScope = 'Singleton' | 'Transient' | 'Request';
declare const bindingScopeValues: {
    [TKey in BindingScope]: TKey;
};

interface AutobindOptions {
    scope: BindingScope;
}

type MetadataName = number | string | symbol;

type MetadataTag = number | string | symbol;

interface BindingConstraints {
    readonly name: MetadataName | undefined;
    readonly tags: Map<MetadataTag, unknown>;
    readonly serviceIdentifier: ServiceIdentifier;
    getAncestor(): BindingConstraints | undefined;
}

type BindingType = 'ConstantValue' | 'DynamicValue' | 'Factory' | 'Instance' | 'Provider' | 'ResolvedValue' | 'ServiceRedirection';
declare const bindingTypeValues: {
    [TKey in BindingType]: TKey;
};

interface BaseBinding<TType extends BindingType, TActivated> {
    readonly id: number;
    readonly moduleId: number | undefined;
    readonly serviceIdentifier: ServiceIdentifier<TActivated>;
    readonly type: TType;
    readonly isSatisfiedBy: (constraints: BindingConstraints) => boolean;
}

type Resolved<TActivated> = SyncResolved<TActivated> | Promise<SyncResolved<TActivated>>;
type SyncResolved<TActivated> = TActivated;

interface GetOptionsTagConstraint {
    key: MetadataTag;
    value: unknown;
}

interface GetOptions {
    autobind?: boolean;
    name?: MetadataName;
    optional?: boolean;
    tag?: GetOptionsTagConstraint;
}

interface OptionalGetOptions extends GetOptions {
    optional: true;
}

interface ResolutionContext {
    get<TActivated>(serviceIdentifier: ServiceIdentifier<TActivated>, options: OptionalGetOptions): TActivated | undefined;
    get<TActivated>(serviceIdentifier: ServiceIdentifier<TActivated>, options?: GetOptions): TActivated;
    getAll<TActivated>(serviceIdentifier: ServiceIdentifier<TActivated>, options?: GetOptions): TActivated[];
    getAllAsync<TActivated>(serviceIdentifier: ServiceIdentifier<TActivated>, options?: GetOptions): Promise<TActivated[]>;
    getAsync<TActivated>(serviceIdentifier: ServiceIdentifier<TActivated>, options: OptionalGetOptions): Promise<TActivated | undefined>;
    getAsync<TActivated>(serviceIdentifier: ServiceIdentifier<TActivated>, options?: GetOptions): Promise<TActivated>;
}

type BindingActivation<T = unknown> = (context: ResolutionContext, injectable: T) => Resolved<T>;

type BindingDeactivation<T = unknown> = (injectable: T) => void | Promise<void>;

interface ScopedBinding<TType extends BindingType, TScope extends BindingScope, TActivated> extends BaseBinding<TType, TActivated> {
    cache: Either<undefined, Resolved<TActivated>>;
    readonly onActivation: BindingActivation<TActivated> | undefined;
    readonly onDeactivation: BindingDeactivation<TActivated> | undefined;
    readonly scope: TScope;
}

interface ConstantValueBinding<TActivated> extends ScopedBinding<typeof bindingTypeValues.ConstantValue, typeof bindingScopeValues.Singleton, TActivated> {
    readonly value: Resolved<TActivated>;
}

type DynamicValueBuilder<T> = (context: ResolutionContext) => Resolved<T>;

interface DynamicValueBinding<TActivated> extends ScopedBinding<typeof bindingTypeValues.DynamicValue, BindingScope, TActivated> {
    readonly value: DynamicValueBuilder<TActivated>;
}

type Factory<TActivated, in TArgs extends unknown[] = any[]> = (...args: TArgs) => TActivated | Promise<TActivated>;

interface FactoryBinding<TActivated extends Factory<unknown>> extends ScopedBinding<typeof bindingTypeValues.Factory, typeof bindingScopeValues.Singleton, TActivated> {
    readonly factory: (context: ResolutionContext) => TActivated | Promise<TActivated>;
}

interface InstanceBinding<TActivated> extends ScopedBinding<typeof bindingTypeValues.Instance, BindingScope, TActivated> {
    readonly implementationType: Newable<TActivated>;
}

/**
 * @deprecated Use `Factory` instead. Provider will be removed in v8.
 * Providers exist for historical reasons from v5 when async dependencies weren't supported.
 * Factories are more flexible and can handle both sync and async operations.
 */
type Provider<TActivated, in TArgs extends unknown[] = any[]> = (...args: TArgs) => Promise<TActivated>;

interface ProviderBinding<TActivated extends Provider<unknown>>// eslint-disable-line @typescript-eslint/no-deprecated
 extends ScopedBinding<typeof bindingTypeValues.Provider, typeof bindingScopeValues.Singleton, TActivated> {
    readonly provider: (context: ResolutionContext) => TActivated;
}

interface BaseResolvedValueElementMetadata<TKind> {
    kind: TKind;
    name: MetadataName | undefined;
    optional: boolean;
    tags: Map<MetadataTag, unknown>;
    value: ServiceIdentifier | LazyServiceIdentifier;
}

declare enum ResolvedValueElementMetadataKind {
    multipleInjection = 0,
    singleInjection = 1
}

interface MultipleInjectionResolvedValueElementMetadata extends BaseResolvedValueElementMetadata<ResolvedValueElementMetadataKind.multipleInjection> {
    chained: boolean;
}

type SingleInjectionResolvedValueElementMetadata = BaseResolvedValueElementMetadata<ResolvedValueElementMetadataKind.singleInjection>;

type ResolvedValueElementMetadata = SingleInjectionResolvedValueElementMetadata | MultipleInjectionResolvedValueElementMetadata;

interface ResolvedValueMetadata {
    arguments: ResolvedValueElementMetadata[];
}

interface ResolvedValueBinding<TActivated> extends ScopedBinding<typeof bindingTypeValues.ResolvedValue, BindingScope, TActivated> {
    readonly factory: (...args: any[]) => TActivated | Promise<TActivated>;
    readonly metadata: ResolvedValueMetadata;
}

interface ServiceRedirectionBinding<TActivated> extends BaseBinding<typeof bindingTypeValues.ServiceRedirection, TActivated> {
    targetServiceIdentifier: ServiceIdentifier;
}

type Binding<TActivated = any> = ConstantValueBinding<TActivated> | DynamicValueBinding<TActivated> | (TActivated extends Factory<unknown> ? FactoryBinding<TActivated> : never) | InstanceBinding<TActivated> | (TActivated extends Provider<unknown> ? ProviderBinding<TActivated> : never) | ResolvedValueBinding<TActivated> | ServiceRedirectionBinding<TActivated>;

interface Cloneable<T> {
    clone(): T;
}

declare enum ActivationRelationKind {
    moduleId = "moduleId",
    serviceId = "serviceId"
}
interface BindingActivationRelation {
    [ActivationRelationKind.moduleId]?: number;
    [ActivationRelationKind.serviceId]: ServiceIdentifier;
}
declare class ActivationsService implements Cloneable<ActivationsService> {
    #private;
    private constructor();
    static build(getParent: () => ActivationsService | undefined): ActivationsService;
    add(activation: BindingActivation, relation: BindingActivationRelation): void;
    clone(): ActivationsService;
    get(serviceIdentifier: ServiceIdentifier): Iterable<BindingActivation> | undefined;
    removeAllByModuleId(moduleId: number): void;
    removeAllByServiceId(serviceId: ServiceIdentifier): void;
}

declare class BindingService implements Cloneable<BindingService> {
    #private;
    private constructor();
    static build(getParent: () => BindingService | undefined, autobindOptions?: AutobindOptions): BindingService;
    clone(): BindingService;
    get<TResolved>(serviceIdentifier: ServiceIdentifier): Iterable<Binding<TResolved>> | undefined;
    getChained<TResolved>(serviceIdentifier: ServiceIdentifier): Generator<Binding<TResolved>, void, unknown>;
    getBoundServices(): Iterable<ServiceIdentifier>;
    getById<TResolved>(id: number): Iterable<Binding<TResolved>> | undefined;
    getByModuleId<TResolved>(moduleId: number): Iterable<Binding<TResolved>> | undefined;
    getNonParentBindings<TResolved>(serviceId: ServiceIdentifier): Iterable<Binding<TResolved>> | undefined;
    getNonParentBoundServices(): Iterable<ServiceIdentifier>;
    removeById(id: number): void;
    removeAllByModuleId(moduleId: number): void;
    removeAllByServiceId(serviceId: ServiceIdentifier): void;
    set<TInstance>(binding: Binding<TInstance>): void;
}

declare enum DeactivationRelationKind {
    moduleId = "moduleId",
    serviceId = "serviceId"
}
interface BindingDeactivationRelation {
    [DeactivationRelationKind.moduleId]?: number;
    [DeactivationRelationKind.serviceId]: ServiceIdentifier;
}
declare class DeactivationsService implements Cloneable<DeactivationsService> {
    #private;
    private constructor();
    static build(getParent: () => DeactivationsService | undefined): DeactivationsService;
    add(deactivation: BindingDeactivation, relation: BindingDeactivationRelation): void;
    clone(): DeactivationsService;
    get(serviceIdentifier: ServiceIdentifier): Iterable<BindingDeactivation> | undefined;
    removeAllByModuleId(moduleId: number): void;
    removeAllByServiceId(serviceId: ServiceIdentifier): void;
}

declare function decorate(decorators: ClassDecorator | ClassDecorator[], target: Function): void;
declare function decorate(decorators: ParameterDecorator | ParameterDecorator[], target: Function, parameterIndex: number): void;
declare function decorate(decorators: ParameterDecorator | ParameterDecorator[], target: Function, methodName: string | symbol, parameterIndex: number): void;
declare function decorate(decorators: MethodDecorator | PropertyDecorator | MethodDecorator[] | PropertyDecorator[], target: Function, property: string | symbol): void;

declare enum InversifyCoreErrorKind {
    injectionDecoratorConflict = 0,
    missingInjectionDecorator = 1,
    planning = 2,
    resolution = 3,
    unknown = 4
}

declare const isAppErrorSymbol: unique symbol;
declare class InversifyCoreError extends Error {
    [isAppErrorSymbol]: true;
    kind: InversifyCoreErrorKind;
    constructor(kind: InversifyCoreErrorKind, message?: string, options?: ErrorOptions);
    static is(value: unknown): value is InversifyCoreError;
    static isErrorOfKind(value: unknown, kind: InversifyCoreErrorKind): value is InversifyCoreError;
}

interface BaseClassElementMetadata<TKind> {
    kind: TKind;
}

interface BaseManagedClassElementMetadata<TKind> extends BaseClassElementMetadata<TKind> {
    isFromTypescriptParamType?: true;
    name: MetadataName | undefined;
    optional: boolean;
    tags: Map<MetadataTag, unknown>;
    value: ServiceIdentifier | LazyServiceIdentifier;
}

declare enum ClassElementMetadataKind {
    multipleInjection = 0,
    singleInjection = 1,
    unmanaged = 2
}

interface MultipleInjectionManagedClassElementMetadata extends BaseManagedClassElementMetadata<ClassElementMetadataKind.multipleInjection> {
    chained: boolean;
}

type SingleInjectionManagedClassElementMetadata = BaseManagedClassElementMetadata<ClassElementMetadataKind.singleInjection>;

type ManagedClassElementMetadata = SingleInjectionManagedClassElementMetadata | MultipleInjectionManagedClassElementMetadata;

type UnmanagedClassElementMetadata = BaseClassElementMetadata<ClassElementMetadataKind.unmanaged>;

type ClassElementMetadata = ManagedClassElementMetadata | UnmanagedClassElementMetadata;

interface ClassMetadataLifecycle {
    postConstructMethodNames: Set<string | symbol>;
    preDestroyMethodNames: Set<string | symbol>;
}

interface ClassMetadata {
    constructorArguments: ClassElementMetadata[];
    lifecycle: ClassMetadataLifecycle;
    properties: Map<string | symbol, ClassElementMetadata>;
    scope: BindingScope | undefined;
}

declare function getClassMetadata(type: Newable): ClassMetadata;

declare function inject(serviceIdentifier: ServiceIdentifier | LazyServiceIdentifier): MethodDecorator & ParameterDecorator & PropertyDecorator;

declare function injectable(scope?: BindingScope): ClassDecorator;

interface InjectFromBaseOptionsLifecycle {
    extendPreDestroyMethods?: boolean | undefined;
    extendPostConstructMethods?: boolean | undefined;
}

interface InjectFromBaseOptions {
    extendConstructorArguments?: boolean | undefined;
    extendProperties?: boolean | undefined;
    lifecycle?: InjectFromBaseOptionsLifecycle | undefined;
}

declare function injectFromBase(options?: InjectFromBaseOptions): ClassDecorator;

interface InjectFromHierarchyOptionsLifecycle {
    extendPreDestroyMethods?: boolean | undefined;
    extendPostConstructMethods?: boolean | undefined;
}

interface InjectFromHierarchyOptions {
    extendConstructorArguments?: boolean | undefined;
    extendProperties?: boolean | undefined;
    lifecycle?: InjectFromHierarchyOptionsLifecycle | undefined;
}

declare function injectFromHierarchy(options?: InjectFromHierarchyOptions): ClassDecorator;

interface MultiInjectOptions {
    chained?: boolean;
}

declare function multiInject(serviceIdentifier: ServiceIdentifier | LazyServiceIdentifier, options?: MultiInjectOptions): MethodDecorator & ParameterDecorator & PropertyDecorator;

declare function named(name: MetadataName): MethodDecorator & ParameterDecorator & PropertyDecorator;

declare function optional(): MethodDecorator & ParameterDecorator & PropertyDecorator;

declare function postConstruct(): MethodDecorator;

declare function preDestroy(): MethodDecorator;

declare function tagged(key: MetadataTag, value: unknown): MethodDecorator & ParameterDecorator & PropertyDecorator;

declare function unmanaged(): MethodDecorator & ParameterDecorator & PropertyDecorator;

interface InjectFromOptionsLifecycle {
    extendPreDestroyMethods?: boolean | undefined;
    extendPostConstructMethods?: boolean | undefined;
}

interface InjectFromOptions {
    extendConstructorArguments?: boolean | undefined;
    extendProperties?: boolean | undefined;
    lifecycle?: InjectFromOptionsLifecycle | undefined;
    type: Newable;
}

interface SingleImmutableLinkedListNode<T> {
    elem: T;
    previous: SingleImmutableLinkedListNode<T> | undefined;
}
declare class SingleImmutableLinkedList<T> implements Iterable<T> {
    readonly last: SingleImmutableLinkedListNode<T>;
    constructor(last: SingleImmutableLinkedListNode<T>);
    concat(elem: T): SingleImmutableLinkedList<T>;
    [Symbol.iterator](): Iterator<T>;
}

interface InternalBindingConstraints {
    getAncestorsCalled: boolean;
    readonly name: MetadataName | undefined;
    readonly tags: Map<MetadataTag, unknown>;
    readonly serviceIdentifier: ServiceIdentifier;
}

interface GetPlanOptionsTagConstraint {
    key: MetadataTag;
    value: unknown;
}

interface BaseGetPlanOptions {
    serviceIdentifier: ServiceIdentifier;
    name: MetadataName | undefined;
    optional: boolean;
    tag: GetPlanOptionsTagConstraint | undefined;
}

interface GetMultipleServicePlanOptions extends BaseGetPlanOptions {
    chained: boolean;
    isMultiple: true;
}

interface GetSingleServicePlanOptions extends BaseGetPlanOptions {
    isMultiple: false;
}

type GetPlanOptions = GetSingleServicePlanOptions | GetMultipleServicePlanOptions;

interface NonCachedServiceNodeContext {
    bindingConstraintsList: SingleImmutableLinkedList<InternalBindingConstraints>;
    chainedBindings: boolean;
    optionalBindings: boolean;
}

interface BaseBindingNode<TBinding extends Binding<any> = Binding<any>> {
    readonly binding: TBinding;
}

type LeafBindingNode<TActivated = any> = BaseBindingNode<ConstantValueBinding<TActivated> | DynamicValueBinding<TActivated> | (TActivated extends Factory<unknown> ? FactoryBinding<TActivated> : never) | (TActivated extends Provider<unknown> ? ProviderBinding<TActivated> : never)>;

interface InstanceBindingNode<TBinding extends InstanceBinding<any> = InstanceBinding<any>> extends BaseBindingNode<TBinding> {
    readonly classMetadata: ClassMetadata;
    readonly constructorParams: (PlanServiceNode | undefined)[];
    readonly propertyParams: Map<string | symbol, PlanServiceNode>;
}

interface ResolvedValueBindingNode<TBinding extends ResolvedValueBinding<any> = ResolvedValueBinding<any>> extends BaseBindingNode<TBinding> {
    readonly params: PlanServiceNode[];
}

type PlanServiceNodeParent<TActivated = any> = InstanceBindingNode<InstanceBinding<TActivated>> | ResolvedValueBindingNode<ResolvedValueBinding<TActivated>>;

interface PlanServiceRedirectionBindingNode<TBinding extends ServiceRedirectionBinding<any> = ServiceRedirectionBinding<any>> extends BaseBindingNode<TBinding> {
    redirections: PlanBindingNode[];
}

type PlanBindingNode = PlanServiceNodeParent | PlanServiceRedirectionBindingNode | LeafBindingNode;

interface PlanServiceNode {
    bindings: PlanBindingNode | PlanBindingNode[] | undefined;
    isContextFree: boolean;
    readonly serviceIdentifier: ServiceIdentifier;
}

interface PlanTree {
    readonly root: PlanServiceNode;
}

interface PlanResult {
    readonly tree: PlanTree;
}

interface PlanParamsOperations {
    getBindings: <TInstance>(serviceIdentifier: ServiceIdentifier<TInstance>) => Iterable<Binding<TInstance>> | undefined;
    getBindingsChained: <TInstance>(serviceIdentifier: ServiceIdentifier<TInstance>) => Generator<Binding<TInstance>, void, unknown>;
    readonly getClassMetadata: (type: Newable) => ClassMetadata;
    readonly getPlan: (options: GetPlanOptions) => PlanResult | undefined;
    setBinding: <TInstance>(binding: Binding<TInstance>) => void;
    readonly setNonCachedServiceNode: (node: PlanServiceNode, context: NonCachedServiceNodeContext) => void;
    readonly setPlan: (options: GetPlanOptions, planResult: PlanResult) => void;
}

interface BasePlanParams {
    autobindOptions: AutobindOptions | undefined;
    operations: PlanParamsOperations;
    servicesBranch: ServiceIdentifier[];
}

interface PlanParamsTagConstraint {
    key: MetadataTag;
    value: unknown;
}

interface MultipleBindingPlanParamsConstraint {
    chained: boolean;
    name?: MetadataName;
    isMultiple: true;
    isOptional?: true;
    serviceIdentifier: ServiceIdentifier;
    tag?: PlanParamsTagConstraint;
}

interface SingleBindingPlanParamsConstraint {
    name?: MetadataName;
    isMultiple: false;
    isOptional?: true;
    serviceIdentifier: ServiceIdentifier;
    tag?: PlanParamsTagConstraint;
}

type PlanParamsConstraint = SingleBindingPlanParamsConstraint | MultipleBindingPlanParamsConstraint;

interface PlanParams extends BasePlanParams {
    rootConstraints: PlanParamsConstraint;
}

declare function plan(params: PlanParams): PlanResult;

declare enum CacheBindingInvalidationKind {
    bindingAdded = "bindingAdded",
    bindingRemoved = "bindingRemoved"
}

interface CacheBindingInvalidation {
    binding: Binding<unknown>;
    kind: CacheBindingInvalidationKind;
    operations: PlanParamsOperations;
}

declare const isLazyPlanServiceNodeSymbol: symbol;
declare abstract class LazyPlanServiceNode implements PlanServiceNode {
    [isLazyPlanServiceNodeSymbol]: true;
    protected readonly _serviceIdentifier: ServiceIdentifier;
    protected _serviceNode: PlanServiceNode | undefined;
    constructor(serviceNode: PlanServiceNode | undefined, serviceIdentifier: ServiceIdentifier);
    get bindings(): PlanBindingNode | PlanBindingNode[] | undefined;
    get isContextFree(): boolean;
    get serviceIdentifier(): ServiceIdentifier;
    set bindings(bindings: PlanBindingNode | PlanBindingNode[] | undefined);
    set isContextFree(isContextFree: boolean);
    static is(value: unknown): value is LazyPlanServiceNode;
    invalidate(): void;
    isExpanded(): boolean;
    protected _getNode(): PlanServiceNode;
    protected abstract _buildPlanServiceNode(): PlanServiceNode;
}

/**
 * Service to cache plans.
 *
 * This class is used to cache plans and to notify PlanService subscribers when the cache is cleared.
 * The cache should be cleared when a new binding is registered or when a binding is unregistered.
 *
 * Subscribers are supposed to be plan services from child containers.
 *
 * Ancestor binding constraints are the reason to avoid reusing plans from plan children nodes.
 */
declare class PlanResultCacheService {
    #private;
    constructor();
    clearCache(): void;
    get(options: GetPlanOptions): PlanResult | undefined;
    invalidateServiceBinding(invalidation: CacheBindingInvalidation): void;
    set(options: GetPlanOptions, planResult: PlanResult): void;
    setNonCachedServiceNode(node: PlanServiceNode, context: NonCachedServiceNodeContext): void;
    subscribe(subscriber: PlanResultCacheService): void;
}

interface ResolutionParams {
    context: ResolutionContext;
    getActivations: <TActivated>(serviceIdentifier: ServiceIdentifier<TActivated>) => Iterable<BindingActivation<TActivated>> | undefined;
    planResult: PlanResult;
    requestScopeCache: Map<number, unknown>;
}

declare function resolve(params: ResolutionParams): unknown;

interface DeactivationParams {
    getBindings: <TInstance>(serviceIdentifier: ServiceIdentifier<TInstance>) => Iterable<Binding<TInstance>> | undefined;
    getBindingsFromModule: <TInstance>(moduleId: number) => Iterable<Binding<TInstance>> | undefined;
    getClassMetadata: (type: Newable) => ClassMetadata;
    getDeactivations: <TActivated>(serviceIdentifier: ServiceIdentifier<TActivated>) => Iterable<BindingDeactivation<TActivated>> | undefined;
}

declare function resolveBindingsDeactivations(params: DeactivationParams, bindings: Iterable<Binding> | undefined): void | Promise<void>;

declare function resolveModuleDeactivations(params: DeactivationParams, moduleId: number): void | Promise<void>;

declare function resolveServiceDeactivations(params: DeactivationParams, serviceIdentifier: ServiceIdentifier): void | Promise<void>;

interface GetAllOptions extends GetOptions {
    chained?: boolean;
}

interface OptionalGetAllOptions extends GetAllOptions {
    optional: true;
}

export { ActivationsService, BindingService, CacheBindingInvalidationKind, ClassElementMetadataKind, DeactivationsService, InversifyCoreError, InversifyCoreErrorKind, LazyPlanServiceNode, PlanResultCacheService, ResolvedValueElementMetadataKind, bindingScopeValues, bindingTypeValues, decorate, getBindingId, getClassMetadata, inject, injectFromBase, injectFromHierarchy, injectable, multiInject, named, optional, plan, postConstruct, preDestroy, resolve, resolveBindingsDeactivations, resolveModuleDeactivations, resolveServiceDeactivations, tagged, unmanaged };
export type { AutobindOptions, BaseBinding, BaseBindingNode, BaseGetPlanOptions, BaseManagedClassElementMetadata, BasePlanParams, Binding, BindingActivation, BindingActivationRelation, BindingConstraints, BindingDeactivation, BindingDeactivationRelation, BindingScope, BindingType, CacheBindingInvalidation, ClassElementMetadata, ClassMetadata, ClassMetadataLifecycle, ConstantValueBinding, DeactivationParams, DynamicValueBinding, DynamicValueBuilder, Factory, FactoryBinding, GetAllOptions, GetMultipleServicePlanOptions, GetOptions, GetOptionsTagConstraint, GetPlanOptions, GetPlanOptionsTagConstraint, GetSingleServicePlanOptions, InjectFromBaseOptions, InjectFromBaseOptionsLifecycle, InjectFromHierarchyOptions, InjectFromHierarchyOptionsLifecycle, InjectFromOptions, InstanceBinding, InstanceBindingNode, LeafBindingNode, ManagedClassElementMetadata, MetadataName, MetadataTag, MultiInjectOptions, MultipleBindingPlanParamsConstraint, MultipleInjectionManagedClassElementMetadata, MultipleInjectionResolvedValueElementMetadata, NonCachedServiceNodeContext, OptionalGetAllOptions, OptionalGetOptions, PlanBindingNode, PlanParams, PlanParamsConstraint, PlanParamsOperations, PlanParamsTagConstraint, PlanResult, PlanServiceNode, PlanServiceNodeParent, PlanServiceRedirectionBindingNode, PlanTree, Provider, ProviderBinding, ResolutionContext, ResolutionParams, Resolved, ResolvedValueBinding, ResolvedValueBindingNode, ResolvedValueElementMetadata, ResolvedValueMetadata, ScopedBinding, ServiceRedirectionBinding, SingleBindingPlanParamsConstraint, SingleInjectionManagedClassElementMetadata, SingleInjectionResolvedValueElementMetadata, UnmanagedClassElementMetadata };
