/// <summary>
    /// Shares the instance with another client and returns a token that can be disposed of later to make an accompanying call
    /// to <see cref="IShareable.Unshare"/>.
    /// </summary>
    /// <param name="shareable">The shareable resource.</param>
    /// <returns>An <see cref="IDisposable"/> that will call <see cref="IShareable.Unshare"/> when disposed.</returns>
    /// <remarks>
    /// If sharing in a Using block, use <see cref="ShareInUsingBlock"/> for less object creation and garbage collection.
    /// </remarks>
    public static IDisposable ShareAsDisposable(this IShareable shareable)
    {
        Contracts.Requires.That(shareable != null);

        shareable.Share();
        return(new DisposableShare(shareable));
    }
    /// <summary>
    /// Share this instance with another client in the context of a Using block, guaranteeing that
    /// an accompanying call to <see cref="IShareable.Unshare"/> is made upon exiting the Using block.
    /// </summary>
    /// <param name="shareable">The shareable resource.</param>
    /// <returns>
    /// A <see cref="ShareStruct"/> that will manage calling <see cref="IShareable.Unshare"/>.
    /// </returns>
    /// <remarks>
    /// <para>
    /// This should be used within a Using block and you should not call <see cref="IShareable.Share"/> or
    /// <see cref="IShareable.Unshare"/> on the shareable resource, nor should you manually call
    /// <see cref="IDisposable.Dispose"/> on the <see cref="ShareStruct"/> returned.
    /// </para><para>
    /// Declare the disposable resource in the Using block as <c>var</c> or <c>ShareStruct</c> and not as <c>IDisposable</c>
    /// or else boxing will occur.
    /// </para>
    /// </remarks>
    public static ShareStruct ShareInUsingBlock(this IShareable shareable)
    {
        Contracts.Requires.That(shareable != null);

        shareable.Share();
        return(new ShareStruct(shareable));
    }