/// <summary>
        ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to
        ///     the same compatibility standards as public APIs. It may be changed or removed without notice in
        ///     any release. You should only use it directly in your code with extreme caution and knowing that
        ///     doing so can result in application failures when updating to a new Entity Framework Core release.
        /// </summary>
        public virtual InternalSkipNavigationBuilder Attach(
            [CanBeNull] InternalEntityTypeBuilder entityTypeBuilder = null,
            [CanBeNull] EntityType targetEntityType = null,
            [CanBeNull] InternalSkipNavigationBuilder inverseBuilder = null)
        {
            entityTypeBuilder ??= Metadata.DeclaringEntityType.Builder;
            if (entityTypeBuilder == null)
            {
                entityTypeBuilder = Metadata.DeclaringEntityType.Model.FindEntityType(Metadata.DeclaringEntityType.Name)?.Builder;
                if (entityTypeBuilder == null)
                {
                    return(null);
                }
            }

            targetEntityType ??= Metadata.TargetEntityType;
            if (targetEntityType.Builder == null)
            {
                targetEntityType = Metadata.DeclaringEntityType.Model.FindEntityType(targetEntityType.Name);
                if (targetEntityType == null)
                {
                    return(null);
                }
            }

            var newSkipNavigationBuilder = entityTypeBuilder.HasSkipNavigation(
                Metadata.CreateMemberIdentity(),
                targetEntityType,
                Metadata.GetConfigurationSource(),
                Metadata.IsCollection,
                Metadata.IsOnDependent);

            if (newSkipNavigationBuilder == null)
            {
                return(null);
            }

            newSkipNavigationBuilder.MergeAnnotationsFrom(Metadata);

            var foreignKeyConfigurationSource = Metadata.GetForeignKeyConfigurationSource();

            if (foreignKeyConfigurationSource.HasValue)
            {
                var foreignKey = Metadata.ForeignKey;
                if (foreignKey.Builder == null)
                {
                    foreignKey = InternalRelationshipBuilder.FindCurrentRelationshipBuilder(
                        foreignKey.PrincipalEntityType,
                        foreignKey.DeclaringEntityType,
                        foreignKey.DependentToPrincipal?.CreateMemberIdentity(),
                        foreignKey.PrincipalToDependent?.CreateMemberIdentity(),
                        dependentProperties: foreignKey.Properties,
                        principalProperties: foreignKey.PrincipalKey.Properties)?.Metadata;
                }

                if (foreignKey != null)
                {
                    newSkipNavigationBuilder.HasForeignKey(foreignKey, foreignKeyConfigurationSource.Value);
                }
            }

            var inverseConfigurationSource = Metadata.GetInverseConfigurationSource();

            if (inverseConfigurationSource.HasValue)
            {
                var inverse = Metadata.Inverse;
                if (inverse.Builder == null)
                {
                    inverse = inverse.DeclaringEntityType.FindSkipNavigation(inverse.Name);
                }

                if (inverseBuilder != null)
                {
                    inverse = inverseBuilder.Attach(targetEntityType.Builder, entityTypeBuilder.Metadata)?.Metadata
                              ?? inverse;
                }

                if (inverse != null)
                {
                    newSkipNavigationBuilder.HasInverse(inverse, inverseConfigurationSource.Value);
                }
            }

            var propertyAccessModeConfigurationSource = Metadata.GetPropertyAccessModeConfigurationSource();

            if (propertyAccessModeConfigurationSource.HasValue)
            {
                newSkipNavigationBuilder.UsePropertyAccessMode(
                    ((ISkipNavigation)Metadata).GetPropertyAccessMode(), propertyAccessModeConfigurationSource.Value);
            }

            var oldFieldInfoConfigurationSource = Metadata.GetFieldInfoConfigurationSource();

            if (oldFieldInfoConfigurationSource.HasValue &&
                newSkipNavigationBuilder.CanSetField(Metadata.FieldInfo, oldFieldInfoConfigurationSource))
            {
                newSkipNavigationBuilder.HasField(Metadata.FieldInfo, oldFieldInfoConfigurationSource.Value);
            }

            return(newSkipNavigationBuilder);
        }