public static string ToDebugString(
            [NotNull] this IReadOnlyProperty property,
            MetadataDebugStringOptions options,
            int indent = 0)
        {
            var builder      = new StringBuilder();
            var indentString = new string(' ', indent);

            builder.Append(indentString);

            var singleLine = (options & MetadataDebugStringOptions.SingleLine) != 0;

            if (singleLine)
            {
                builder.Append($"Property: {property.DeclaringEntityType.DisplayName()}.");
            }

            builder.Append(property.Name).Append(" (");

            var field = property.GetFieldName();

            if (field == null)
            {
                builder.Append("no field, ");
            }
            else if (!field.EndsWith(">k__BackingField", StringComparison.Ordinal))
            {
                builder.Append(field).Append(", ");
            }

            builder.Append(property.ClrType.ShortDisplayName()).Append(")");

            if (property.IsShadowProperty())
            {
                builder.Append(" Shadow");
            }

            if (property.IsIndexerProperty())
            {
                builder.Append(" Indexer");
            }

            if (!property.IsNullable)
            {
                builder.Append(" Required");
            }

            if (property.IsPrimaryKey())
            {
                builder.Append(" PK");
            }

            if (property.IsForeignKey())
            {
                builder.Append(" FK");
            }

            if (property.IsKey() &&
                !property.IsPrimaryKey())
            {
                builder.Append(" AlternateKey");
            }

            if (property.IsIndex())
            {
                builder.Append(" Index");
            }

            if (property.IsConcurrencyToken)
            {
                builder.Append(" Concurrency");
            }

            if (property.GetBeforeSaveBehavior() != PropertySaveBehavior.Save)
            {
                builder.Append(" BeforeSave:").Append(property.GetBeforeSaveBehavior());
            }

            if (property.GetAfterSaveBehavior() != PropertySaveBehavior.Save)
            {
                builder.Append(" AfterSave:").Append(property.GetAfterSaveBehavior());
            }

            if (property.ValueGenerated != ValueGenerated.Never)
            {
                builder.Append(" ValueGenerated.").Append(property.ValueGenerated);
            }

            if (property.GetMaxLength() != null)
            {
                builder.Append(" MaxLength(").Append(property.GetMaxLength()).Append(")");
            }

            if (property.IsUnicode() == false)
            {
                builder.Append(" Ansi");
            }

            if (property.GetPropertyAccessMode() != PropertyAccessMode.PreferField)
            {
                builder.Append(" PropertyAccessMode.").Append(property.GetPropertyAccessMode());
            }

            if ((options & MetadataDebugStringOptions.IncludePropertyIndexes) != 0 &&
                ((Annotatable)property).IsReadOnly)
            {
                var indexes = ((IProperty)property).GetPropertyIndexes();
                builder.Append(" ").Append(indexes.Index);
                builder.Append(" ").Append(indexes.OriginalValueIndex);
                builder.Append(" ").Append(indexes.RelationshipIndex);
                builder.Append(" ").Append(indexes.ShadowIndex);
                builder.Append(" ").Append(indexes.StoreGenerationIndex);
            }

            if (!singleLine && (options & MetadataDebugStringOptions.IncludeAnnotations) != 0)
            {
                builder.Append(property.AnnotationsToDebugString(indent + 2));
            }

            return(builder.ToString());
        }