// TODO: Can we find a better name for this?
        public ComponentReplacementBuilder <TService> CurrentlyImplementedBy(Type implementationType)
        {
            if (implementationType == null)
            {
                throw new ArgumentNullException(nameof(implementationType));
            }
            if (!ServiceTypes.First().IsAssignableFrom(implementationType))
            {
                throw new ArgumentException(
                          $"Type '{implementationType.FullName}' is not an implementation of '{ServiceTypes.First().FullName}'",
                          nameof(implementationType));
            }

            OldImplementationType = implementationType;

            return(this);
        }
        public override IReplacement ReplacedBy(Type implementationType)
        {
            if (implementationType == null)
            {
                throw new ArgumentNullException(nameof(implementationType));
            }
            if (!ServiceTypes.First().IsAssignableFrom(implementationType))
            {
                throw new ArgumentException(
                          $"Type '{implementationType.FullName}' is not an implementation of '{ServiceTypes.First().FullName}'",
                          nameof(implementationType));
            }

            return(new UnnamedComponentReplacement <TService>
            {
                ServiceTypes = ServiceTypes,
                OldImplementationType = OldImplementationType,
                NewImplementationType = implementationType,
                IsActive = IsActive
            });
        }
        public void Apply(ICompactContainer container)
        {
            if (ImplementationType == null)
            {
                if (instance != null)
                {
                    ImplementationType = instance.GetType();
                }
                else
                {
                    if (ServiceTypes.Count() != 1)
                    {
                        throw new CompactContainerException("Cannot infer implementation type when more than one service is specified: " +
                                                            ServiceTypes.Select(t => t.Name).ToCommaSeparatedString());
                    }
                    ImplementationType = ServiceTypes.Single();
                }
            }

            if (ImplementationType.IsAbstract)
            {
                throw new CompactContainerException("Cannot register implementation type " + ImplementationType.FullName +
                                                    " because it is abstract");
            }


            // name calculation
            if (name == null)
            {
                if (ImplementationType != null)
                {
                    name = ImplementationType.FullName;
                }
                else if (instance != null)
                {
                    name = instance.GetType().FullName;
                }
                else if (ServiceTypes.Count() > 0)
                {
                    name = ServiceTypes.First().FullName;
                }
                else
                {
                    throw new CompactContainerException("Cannot infer name for component");
                }
            }

            var ci = new ComponentInfo(name, ServiceTypes, ImplementationType, lifestyle ?? container.DefaultLifestyle)
            {
                Instance = instance,
            };

            if (registrationParts != null)
            {
                foreach (var part in registrationParts)
                {
                    part.ApplyTo(ci);
                }
            }

            container.AddComponentInfo(ci);
        }