/// <summary>
        /// Generates a fully qualified URL to the specified attachment. If the attachment is an image, the URL points to a resized version.
        /// </summary>
        /// <param name="instance">The object that provides methods to build URLs to Kentico content.</param>
        /// <param name="attachment">The attachment.</param>
        /// <param name="constraint">The size constraint that is enforced on image when resizing.</param>
        /// <param name="options">Options that affect the attachment URL.</param>
        /// <returns>The fully qualified URL to the attachment.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="instance"/> or <paramref name="attachment"/> is null.</exception>
        public static string Attachment(this ExtensionPoint<UrlHelper> instance, Attachment attachment, SizeConstraint constraint, AttachmentUrlOptions options = null)
        {
            if (instance == null)
            {
                throw new ArgumentNullException("instance");
            }
            if (attachment == null)
            {
                throw new ArgumentNullException("attachment");
            }

            return GenerateAttachmentUrl(instance, attachment, constraint, options);
        }
        private static string GenerateAttachmentUrl(ExtensionPoint<UrlHelper> instance, Attachment attachment, SizeConstraint constraint, AttachmentUrlOptions options)
        {
            var fileName = GetFileName(attachment);
            var builder = new StringBuilder().AppendFormat("~/getattachment/{0:D}/{1}", attachment.GUID, GetFileNameForUrl(fileName));
            var referenceLength = builder.Length;
            Action<string, object> append = (name, value) =>
            {
                builder.Append(builder.Length == referenceLength ? '?' : '&').Append(name).Append('=').Append(value);
            };

            if (constraint.WidthComponent > 0)
            {
                append("width", constraint.WidthComponent);
            }

            if (constraint.HeightComponent > 0)
            {
                append("height", constraint.HeightComponent);
            }

            if (constraint.MaxWidthOrHeightComponent > 0)
            {
                append("maxsidesize", constraint.MaxWidthOrHeightComponent);
            }

            // Prevent Kentico from using site settings
            if (!constraint.IsEmpty)
            {
                append("resizemode", "force");
            }

            if ((options != null) && options.AttachmentContentDisposition)
            {
                append("disposition", "attachment");
            }

            var url = builder.ToString();

            if (attachment.VersionID > 0)
            {
                url = GetAttachmentPreviewUrl(url);
            }

            return instance.Target.Content(url);
        }