/// <summary>
        /// Visit the specified <paramref name="container"/> using the specified <paramref name="visitor"/>.
        /// </summary>
        /// <param name="visitor">The visitor.</param>
        /// <param name="container">The container to visit.</param>
        /// <param name="parameters">The visit parameters to use.</param>
        /// <typeparam name="TContainer">The declared container type.</typeparam>
        /// <exception cref="ArgumentNullException">The container is null.</exception>
        /// <exception cref="InvalidContainerTypeException">The container is null.</exception>
        /// <exception cref="MissingPropertyBagException">No property bag was found for the given container.</exception>
        public static void Accept <TContainer>(IPropertyBagVisitor visitor, ref TContainer container, VisitParameters parameters = default)
        {
            var errorCode = VisitErrorCode.Ok;

            try
            {
                if (TryAccept(visitor, ref container, out errorCode))
                {
                    return;
                }
            }
            catch (Exception)
            {
                if ((parameters.IgnoreExceptions & VisitExceptionType.Visitor) == 0)
                {
                    throw;
                }
            }

            if ((parameters.IgnoreExceptions & VisitExceptionType.Internal) != 0)
            {
                return;
            }

            switch (errorCode)
            {
            case VisitErrorCode.Ok:
            case VisitErrorCode.InvalidContainerType:
                break;

            case VisitErrorCode.NullContainer:
                throw new ArgumentException("The given container was null. Visitation only works for valid non-null containers.");

            case VisitErrorCode.MissingPropertyBag:
                throw new MissingPropertyBagException(container.GetType());

            default:
                throw new Exception($"Unexpected VisitErrorCode=[{errorCode}]");
            }
        }
        /// <summary>
        /// Visit the specified <paramref name="container"/> using the specified <paramref name="visitor"/> at the given <see cref="PropertyPath"/>.
        /// </summary>
        /// <param name="visitor">The visitor.</param>
        /// <param name="container">The container to visit.</param>
        /// <param name="path">The property path to visit.</param>
        /// <param name="parameters">The visit parameters to use.</param>
        /// <typeparam name="TContainer">The container type.</typeparam>
        /// <exception cref="ArgumentNullException">The container is null.</exception>
        /// <exception cref="InvalidContainerTypeException">The given container type is not valid for visitation.</exception>
        /// <exception cref="MissingPropertyBagException">No property bag was found for the given container.</exception>
        public static void Accept <TContainer>(IPropertyVisitor visitor, ref TContainer container, PropertyPath path, VisitParameters parameters = default)
        {
            var visitAtPath = ValueAtPathVisitor.Pool.Get();

            try
            {
                visitAtPath.Path    = path;
                visitAtPath.Visitor = visitor;

                Accept(visitAtPath, ref container, parameters);

                if ((parameters.IgnoreExceptions & VisitExceptionType.Internal) == 0)
                {
                    switch (visitAtPath.ErrorCode)
                    {
                    case VisitErrorCode.Ok:
                        break;

                    case VisitErrorCode.InvalidPath:
                        throw new InvalidPathException($"Failed to Visit at Path=[{path}]");

                    default:
                        throw new Exception($"Unexpected {nameof(VisitErrorCode)}=[{visitAtPath.ErrorCode}]");
                    }
                }
            }
            finally
            {
                ValueAtPathVisitor.Pool.Release(visitAtPath);
            }
        }
 /// <summary>
 /// Visit the specified <paramref name="container"/> using the specified <paramref name="visitor"/>.
 /// </summary>
 /// <param name="visitor">The visitor.</param>
 /// <param name="container">The container to visit.</param>
 /// <param name="parameters">The visit parameters to use.</param>
 /// <exception cref="ArgumentNullException">The container is null.</exception>
 /// <exception cref="InvalidContainerTypeException">The given container type is not valid for visitation.</exception>
 /// <exception cref="MissingPropertyBagException">No property bag was found for the given container.</exception>
 public static void Accept <TContainer>(IPropertyBagVisitor visitor, TContainer container, VisitParameters parameters = default)
 {
     Accept(visitor, ref container, parameters);
 }
 /// <summary>
 /// Visit the specified <paramref name="container"/> using the specified <paramref name="visitor"/>.
 /// </summary>
 /// <param name="container">The container to visit.</param>
 /// <param name="visitor">The visitor.</param>
 /// <param name="parameters">The visit parameters to use.</param>
 /// <typeparam name="TContainer">The declared container type.</typeparam>
 /// <exception cref="ArgumentNullException">The container is null.</exception>
 /// <exception cref="InvalidContainerTypeException">The given container type is not valid for visitation.</exception>
 /// <exception cref="MissingPropertyBagException">No property bag was found for the given container.</exception>
 public static void Visit <TContainer>(ref TContainer container, PropertyVisitor visitor, VisitParameters parameters = default)
 {
     Visit(ref container, (IVisitor)visitor, parameters);
 }