/// <summary>
        /// Generates an observable declaration that wraps a event.
        /// </summary>
        /// <param name="eventDetails">The details of the event to wrap.</param>
        /// <param name="dataObjectName">The name of the item where the event is stored.</param>
        /// <param name="prefix">A prefix to append to the name.</param>
        /// <returns>The property declaration.</returns>
        protected static PropertyDeclarationSyntax?GenerateEventWrapperObservable(IEventSymbol eventDetails, string dataObjectName, string?prefix)
        {
            prefix ??= string.Empty;

            // Create "Observable.FromEvent" for our method.
            var(expressionBody, observableEventArgType) = GenerateFromEventExpression(eventDetails, dataObjectName);

            if (observableEventArgType == null || expressionBody == null)
            {
                return(null);
            }

            var modifiers = eventDetails.IsStatic
                ? new[] { SyntaxKind.PublicKeyword, SyntaxKind.StaticKeyword }
                : new[] { SyntaxKind.PublicKeyword };

            var attributes = RoslynHelpers.GenerateObsoleteAttributeList(eventDetails);

            // Produces for static: public static global::System.IObservable<(argType1, argType2)> EventName => (contents of expression body)
            // Produces for instance: public global::System.IObservable<(argType1, argType2)> EventName => (contents of expression body)
            return(PropertyDeclaration(observableEventArgType, prefix + eventDetails.Name, attributes, modifiers, expressionBody, 2)
                   .WithLeadingTrivia(XmlSyntaxFactory.GenerateSummarySeeAlsoComment("Gets an observable which signals when the {0} event triggers.", eventDetails.ConvertToDocument()))
                   .WithSemicolonToken(Token(SyntaxKind.SemicolonToken)));
        }