import "oaidl.idl";
import "ocidl.idl";

// Next ID 153

cpp_quote( "#define CONFIDENCE_FITS_VERY_BROAD_PATTERN 10" )
cpp_quote( "#define CONFIDENCE_FITS_BROAD_PATTERN 15" )
cpp_quote( "#define CONFIDENCE_FITS_GENERAL_PATTERN 25" )
cpp_quote( "#define CONFIDENCE_FITS_SPECIFIC_PATTERN 50" )
cpp_quote( "#define CONFIDENCE_FITS_VERY_SPECIFIC_PATTERN 100" )
cpp_quote( "#define ATTR_IMPLEMENTS L\"implements\"" )
cpp_quote( "#define ATTR_EVENT_SOURCES L\"event_sources\"" )
cpp_quote( "#define ATTR_DEFAULT_INTERFACE L\"default_interface\"" )
cpp_quote( "#define ATTR_DEFAULT_EVENT_SOURCE L\"default_event_source\"" )
cpp_quote( "#define ATTR_SUPERCLASSES L\"superclasses\"" )
cpp_quote( "#define ATTR_SUBCLASSES L\"subclasses\"" )
cpp_quote( "#define ATTR_ORDER_IN_CODE L\"orderInCode\"" )
cpp_quote( "#define ATTR_OTHER_CONTEXTS L\"otherContexts\"" )
cpp_quote( "#define ATTR_ACCESS L\"security\"" )
cpp_quote( "#define AV_PUBLIC L\"public\"" )
cpp_quote( "#define AV_PRIVATE L\"private\"" )
cpp_quote( "#define AV_PROTECTED L\"protected\"" )
cpp_quote( "#define ATTR_TYPE L\"type\"" )
cpp_quote( "#define ATTR_ARGDIR L\"argdir\"" )
cpp_quote( "#define AV_ARGDIR_BYVAL L\"input\"" )
cpp_quote( "#define AV_ARGDIR_BYREF L\"output\"" )
cpp_quote( "#define AV_ARGDIR_RETVAL L\"retval\"" )
cpp_quote( "#define AV_ARGDIR_INOUT L\"inout\"" )
cpp_quote( "#define ATTR_DEFAULT_VALUE L\"default\"" )
cpp_quote( "#define ATTR_OPTIONAL L\"optional\"" )
cpp_quote( "#define AV_DEFVAL_OPTIONAL L\"\"" )
cpp_quote( "#define ATTR_VIRTUAL L\"virtual\"" )
cpp_quote( "#define ATTR_NAMESPACE_ALIAS L\"alias_of\"" )
cpp_quote( "#define ATTR_FINAL L\"final\"" )
cpp_quote( "#define AV_TRUE L\"true\"" )
cpp_quote( "#define AV_FALSE L\"false\"" )
cpp_quote( "#define ATTR_ABSTRACT L\"abstract\"" )
cpp_quote( "#define ATTR_IMPORTS L\"imports\"" )
cpp_quote( "#define ATTR_TRANSIENT L\"transient\"" )
cpp_quote( "#define ATTR_VOLATILE L\"volatile\"" )
cpp_quote( "#define ATTR_SYNCHRONIZED L\"synchronized\"" )
cpp_quote( "#define ATTR_THROWS L\"throws\"" )
cpp_quote( "#define ATTR_STATIC L\"static\"" )
cpp_quote( "#define ATTR_VOLATILE L\"volatile\"" )
cpp_quote( "#define ATTR_EXPLICIT L\"explicit\"" )
cpp_quote( "#define ATTR_INLINE L\"inline\"" )
cpp_quote( "#define ATTR_DEFAULT_GROUP L\"defaultGroup\"" )
cpp_quote( "#define ATTR_library L\"library\"" )
cpp_quote( "#define ATTR_TARGET L\"target\"" )
cpp_quote( "#define ATTR_TARGET_OBJECT L\"target_object\"" )
cpp_quote( "#define ATTR_OVERVIEW L\"overview\"" )
cpp_quote( "#define ATTR_DECLARATION_FILE L\"declarationFile\"" )
cpp_quote( "#define ATTR_DECLARATION_LINE L\"declarationLine\"" )
cpp_quote( "#define ATTR_IMPLEMENTATION_FILE L\"implementationFile\"" )
cpp_quote( "#define ATTR_IMPLEMENTATION_LINE L\"implementationLine\"" )
cpp_quote( "#define ATTR_HELP_STRING L\"helpstring\"" )
cpp_quote( "#define ATTR_HELP_CONTEXT L\"helpcontext\"" )
cpp_quote( "#define ATTR_GROUP L\"group\"" )
cpp_quote( "#define ATTR_GROUPS L\"groups\"" )
cpp_quote( "#define ATTR_FILENAME L\"filename\"" )
cpp_quote( "#define ATTR_TITLE L\"title\"" )
cpp_quote( "#define ATTR_AUTOLINK_ALIASES L\"autolink_aliases\"" )
cpp_quote( "#define ATTR_HEAD L\"head\"" )
cpp_quote( "#define ATTR_USED_BY L\"used_by\"" )


// It seems that if you include this IDL via an IDL 'import'
//   statement, you can't include interfaces in the library
//   definition or the IDL compiler GPF's.  However, if you
//   *don't* put the interface definitions under the library,
//   then VB can't see them.  When we run DocJet over this
//   IDL, it works out better to have the interfaces under the
//   library definition too.
//
// We get around this by putting the library definition both
//   in front and in back.  It's guarded by this #ifdef.
//
#ifdef IN_DOCJET_INCLUDE
[
    uuid(4493823F-C9E1-11d3-A956-00C0F0111CD7),
    helpfile("DocJetInterfaces.chm"),
    version(1.0),
    helpstring("DocJet Extensions Type library")
]
library DocJetInterfaceLib
{
#endif

interface IObjectCollection;
interface IObject;
interface ISourceFiles;
interface ISubtypeCollection;
interface IErrors;


// {group:Character Scanning}
// Description:  A segment of generator output
//
// Remarks:
//   This object is really a wrapper around a string.  If we used
//   BSTR's in place of these objects, you'd end up with lots and
//   lots of calls to SysAllocString, and that wouldn't be very
//   performant.
[
    object,
    uuid(866E1625-C9E1-11d3-A956-00C0F0111CD7),
    /* dual, */
    helpstring("IAltHelpInterface interface"),
    pointer_default(unique),
    helpcontext( 1014 ),
]
interface IMarkupSegment : IDispatch
{
    // Description:  Clears the markup segment
    [ id(2),
      helpstring( "Clears the markup segment object" ),
      helpcontext( 1002 ) ]
    HRESULT Reset();

    // Description:  Appends a string to the accumulated output
    //
    // Arguments:
    //   s - The string to append.
    [ id(3),
      helpstring( "Appends a string to the markup segment" ),
      helpcontext( 1003 ) ]
    HRESULT AppendString( [in] BSTR s );

    // Description:  Appends a string to the accumulated output
    //
    // Arguments:
    //   ms - The markup segment to append.
    [ id(140),
      helpstring( "Appends a markup segment to the markup segment" ),
      helpcontext( 1140 ) ]
    HRESULT AppendSegment( [in] IMarkupSegment *ms );

    // Description:  Creates a new markup segment
    //
    // Returns:
    //   A new, empty, markup segment.
    [ id(141),
      helpstring( "Creates a new markup segment to work with" ),
      helpcontext( 1141 ) ]
    HRESULT CreateNewMarkupSegment( [out,retval] IMarkupSegment **ms );

    // Description:  Appends the results of a call to the output format
    //    to the accumulated output
    //
    // Arguments:
    //   function - The name of the function in the output format to call
    //   args - An array of arguments.  The array elements can either
    //          be BSTR's or references to IMarkupSegment.
    //
    // Remarks:
    //   Again, function is the name of a procedure or output type element
    //   within the output format.  If it is a call to a procedure or
    //   non-markup function, it should be preceeded with a period.
    [ id(4),
      helpstring( "Appends the results of a call to the output format to the markup segment" ),
      helpcontext( 1004 ),
      vararg ]
    HRESULT AppendResultsOfCallToOutputFormat
        ( [in] BSTR function,
          [in,out] SAFEARRAY(VARIANT)* args );
};

// {group:Character Scanning}
//
// Description:  A markup transformation thunk
//
// Remarks:
//   This interfaces defines a "thunk" for doing markup transformations.
//   A "thunk" which is an object that represents a bit of computation.
[
    object,
    uuid(55E0E1F1-C9F8-11d3-A956-00C0F0111CD7),
    /* dual, */
    helpstring("Implemented by scanners to do markup chores"),
    pointer_default(unique),
    helpcontext( 1013 ),
]
interface IMarkupFunctionObject : IDispatch
{
    // Description:  Executes the operation
    //
    // Arguments:
    //  input - The part of the comment reported by the
    //          scanner which needs transforming.
    //  output - The storage for the results
    //  context - An arbitrary string defined by the
    //            output format giving you contextual
    //            information.  Wherever possible, you
    //            should ignore this string.  When you
    //            need it, you'll know why (because you're
    //            dorking with the output format.)
    [ id(9),
      helpstring( "Does the dirty work of dealing with text markups" ),
      helpcontext( 1009 ) ]
    HRESULT DoMarkup( [in] BSTR input,
              [in] IMarkupSegment *context,
              [in] IMarkupSegment *output );
};

// {group:Section Scanning}
//
// Description:  The interface for reporting section-level discoveries in comments.
[
    object,
    uuid(49073488-C9F9-11d3-A956-00C0F0111CD7),
    /* dual, */
    helpstring("The class for reporting section-level discoveries in comments"),
    helpcontext( 1011 ),
    pointer_default(unique)
]
interface ISectionFindings : IDispatch
{
    // Description:  The method for reporting an error in the comment
    //
    // Arguments:
    //   markupStart - The beginning of the bad markup block (not just the
    //                 start of the errant section of the block).
    //   markupEnd - The end of the bad markup block (ditto).
    //   errorMessage - The error message to be printed.
    //
    // Remarks:
    //  This method is called when your implementation of ISectionMarkupScanner
    //  finds what it believes to be a malformed markup of its type.
    //  IT COULD BE WRONG!  The "wrong" markup may actually be perfectly good
    //  markup to another scanner.  If this is the case, then the "bad" markup
    //  will be reported as part of a legal markup block by another scanner.
    //  Legal markup always supercedes error messages, so your scanner's
    //  complaint will never be aired.
    [ id(10),
      helpstring( "Report an error in the comment" ),
      helpcontext( 1010 ) ]
    HRESULT CommentError( [in]long markupStart, [in]long markupEnd,
                  [in]BSTR errorMessage );

    // Description:  Called by ISectionMarkupScanner to report a section finding.
    //
    // Arguments:
    //   bodyStart -   The start of the contents of the section
    //   bodyEnd -     The end of the contents of the section.  If equal to
    //                 bodyStart, then the section extends from bodyStart
    //                 onward to the next finding (see Body).
    //   markupStart - The start of the textual clue that indicates the section
    //                 (see Markup).
    //   markupEnd -   The end of the textual clue.
    //   confidence -  An indication of the likelihood that this markup really
    //                 is being correctly identified.
    //   logicalSection - The name of the comment section found.
    [ id(15),
      helpstring( "Report a section finding" ),
      helpcontext( 1015 )
    ]
    HRESULT AddSectionFinding( [in]long bodyStart, [in]long bodyEnd,
                   [in]long markupStart, [in]long markupEnd,
                   [in]long confidence,
                   [in]BSTR logicalSection );
};

// {group:Directive Scanning}
//
// Description:  The interface for reporting discovery-time directives in comments.
[
    object,
    uuid(93569F9E-067D-4f15-9523-FCC1E728C051),
    /* dual, */
    helpstring("The class for reporting section-level discoveries in comments"),
    helpcontext( 1145 ),
    pointer_default(unique)
]
interface IDirectiveFindings : IDispatch
{
    // Description:  Called by IDirectiveScanner to report a directive finding.
    //
    // Arguments:
    //   markupStart - The start of the textual clue that indicates the section
    //                 (see Markup).
    //   markupEnd -   The end of the textual clue.
    //   confidence -  An indication of the likelihood that this markup really
    //                 is being correctly identified.
    //   directive   - The name of the directive
    //   directiveArgs - The arguments to pass to the directive.
    [ id(146),
      helpstring( "Report a directive finding" ),
      helpcontext( 1146 )
    ]
    HRESULT AddDirectiveFinding(
                   [in]long markupStart, [in]long markupEnd,
                   [in]long confidence,
                   [in]BSTR directive,
                   [in]SAFEARRAY(BSTR) *directiveArgs );
};

// {Group:Paragraph Scanning}
//
// Description: Turns IBlock findings into output markup
[
    uuid(E1A636EF-A044-4e1a-A811-1D70197D2018),
    helpstring("MFO for combining blocks of text"),
    helpcontext( 1127 )
]
interface IBlockMarkupFunctionObject : IDispatch
{
    // Description:  Performs the markup translation for IBlock
    //
    // Arguments:
    //   subordinates - A vector of IMarkupSegments that represent the
    //                  result of parsing the members of the block.
    //   depthInfo -    Markup that will help the output format build
    //                  the markup by telling it how deeply nested within
    //                  other paragraph blocks we are.
    //   context -      Output-format specific stuff - should be passed
    //                  through to the output format intact
    //   output -       The place to put your output
    //
    // Remarks:
    //   Do not modify depthInfo, context, or any of the subordinate
    //   markup segments.
    [ id(136),
      helpstring( "Create the markup" ),
      helpcontext( 1136 ) ]
    HRESULT DoMarkup( [in] SAFEARRAY(IMarkupSegment*) *subordinates,
                      [in] IMarkupSegment *depthInfo,
                      [in] IMarkupSegment *context,
                      [in] IMarkupSegment *output );
};

// {Group:Paragraph Scanning}
//
// Description: Provides the markup function for simple elements of
//              an IBlock.
[
    uuid(920DB9BB-CDFD-4fc9-8ED8-71EAEA5ECDBC),
    helpstring("Provides GUI features for the object"),
    helpcontext( 1128 )
]
interface ITextMarkupFunctionObject : IDispatch
{
    // Description:  Performs the markup translation for simple elements
    //               of IBlocks.
    //
    // Arguments:
    //   text -         The marked up (possibly by character markups)
    //                  version of the text of the simple block.
    //   depthInfo -    Markup that will help the output format build
    //                  the markup by telling it how deeply nested within
    //                  other paragraph blocks we are.
    //   context -      Output-format specific stuff - should be passed
    //                  through to the output format intact
    //   output -       The place to put your output
    //
    // Remarks:
    //   Do not modify depthInfo, context, or any of the subordinate
    //   markup segments.
    //
    // See Also:
    //   IBlock.SimpleElement
    [ id(135),
      helpstring( "Create the markup" ),
      helpcontext( 1135 ) ]
    HRESULT DoMarkup( [in] IMarkupSegment *text,
                      [in] IMarkupSegment *depthInfo,
                      [in] IMarkupSegment *context,
                      [in] IMarkupSegment *output );
};

// {group:Paragraph Scanning}
//
// Description:  Provides a mechanism for increasing the indent depth
//               for subordinate paragraphs
[
    uuid(B78FDFEF-E470-4b87-812E-6F348D036511),
    helpstring("Provides GUI features for the object"),
    helpcontext( 1129 )
]
interface IIndentMarkupFunctionObject : IDispatch
{
    // Description:  Performs the markup translation for simple elements
    //               of IBlocks.
    //
    // Arguments:
    //   depthInfo -    The current paragraph depth.  For un-nested
    //                  paragraphs, this will be null.  Otherwise, it is
    //                  the result of previous calls to ident MFO's.
    //   context -      Output-format specific stuff - should be passed
    //                  through to the output format intact
    //   output -       The place to put your output
    //
    // Remarks:
    //   Do not modify depthInfo or context.
    //
    // See Also:
    //   IBlock.Subsection
    [ id(134),
      helpstring( "Create the markup" ),
      helpcontext( 1134 ) ]
    HRESULT DoMarkup( [in] IMarkupSegment *depthInfo,
                      [in] IMarkupSegment *context,
                      [in] IMarkupSegment *output );
};

// {group:Paragraph Scanning}
//
// Description:  Combines a number of findings about a paragraph or
//               series of paragraphs.
[
    uuid(ECCDEB81-3CA3-4071-83FB-4768D81CEC28),
    helpstring("Provides GUI features for the object"),
    helpcontext( 1130 )
]
interface IBlock : IDispatch
{
    // Description:  Creates a sub-block
    //
    // Arguments:
    //   bmfo - The markup function to use to combine the elements of the
    //          block into a single markup segment
    //
    // Returns:
    //   A new, empty, block.
    [ id(133),
      helpstring( "Report a complex block" ),
      helpcontext( 1133 ) ]
    HRESULT CreateBlock( [in]IBlockMarkupFunctionObject *bmfo,
                         [out,retval]IBlock **out );

    // Description:  Used to report a block of text within a block.
    //
    // Arguments:
    //   start - The start of the sequence
    //   end - The end of the sequence
    //   doTextMarkups - If true, character scanning (with ICharacterScanners)
    //                   is done on the block of text.
    //   mfo - The markup function for the block.  If you don't need to do
    //         anything to the block of text, you can pass 0 for this
    //         parameter.
    //
    [ id(132),
      helpstring( "Report a simple text block" ),
      helpcontext( 1132 ) ]
    HRESULT SimpleElement( [in]int start, [in]int end, [in]BOOL doTextMarkups,
                           [in]ITextMarkupFunctionObject *mfo );

    // Description: Declares the boundaries of a set of subordinate paragraphs
    //
    // Arguments:
    //  start - The start of the block
    //  end - The end of the block
    //  imfo - The markup function used for calculating the indent level
    //         of the subordinate paragraphs
    [ id(131),
      helpstring( "Report a subordinate paragraph block" ),
      helpcontext( 1131 ) ]
    HRESULT Subsection( [in]int start, [in]int end, [in]IIndentMarkupFunctionObject *imfo );
};




// {group:Paragraph Scanning}
//
// Description:  The interface for reporting paragraph-level discoveries in comments.
[
    object,
    uuid(8F36EDA8-C9FA-11d3-A956-00C0F0111CD7),
    /* dual, */
    helpstring("The class for reporting paragraph-level discoveries in comments"),
    helpcontext( 1016 ),
    pointer_default(unique)
]
interface IParagraphFindings : IDispatch
{
    // Description:  The method for reporting an error in the comment
    //
    // Arguments:
    //   markupStart - The beginning of the bad markup block (not just the
    //                 start of the errant section of the block).
    //   markupEnd - The end of the bad markup block (ditto).
    //   errormessage - The error message to be printed.
    //
    [ id(10),
      helpstring( "Report an error in the comment" ),
      helpcontext( 1010 ) ]
    HRESULT CommentError( [in]long markupStart, [in]long markupEnd,
                  [in]BSTR errormessage );

    // Description:  Starts a paragraph finding
    //
    // Arguments:
    //  bmfo - The markup function used to combine the elements of the
    //         paragraph finding
    //
    // Return Value:
    //   The new, empty, block
    //
    // Remarks:
    //   Before calling CreateBlock again, you need to call either
    //   SetBlockLimits or CancelBlock.
    [ id(137),
      helpstring( "Adds a subordinate block" ),
      helpcontext( 1137 ) ]
    HRESULT CreateBlock( [in]IBlockMarkupFunctionObject *bmfo,
                         [out,retval]IBlock **out );

    // Description:  Declares the limits of a paragraph finding
    //
    // Arguments:
    //   b - The open block.  This must match the results of the previous
    //       call to CreateBlock
    //   start - The start of the region associated with the paragraph
    //   end - The end of the region
    //   confidence - The level of assurance we should have that this is
    //                the correct way to interpret the text within the block.
    [ id(138),
      helpstring( "Finishes a subordinate block" ),
      helpcontext( 1138 ) ]
    HRESULT SetBlockLimits( [in]IBlock *b, [in]int start, [in]int end, [in]int confidence );

    // Description:  Cancels the previously started paragraph block
    //
    // Arguments:
    //   b - The open block.  This must match the results of the previous
    //       call to CreateBlock
    //
    // Remarks:
    //  Call this if your scanner thought it saw a matching piece of markup,
    //  but after further investigation, determined it had been wrong.
    [ id(139),
      helpstring( "Cancels the creation of a subordinate block" ),
      helpcontext( 1139 ) ]
    HRESULT CancelBlock( [in]IBlock *b );
};


// {group:Character Scanning}
//
// Description:  The interface for reporting character-level discoveries in comments.
[
    object,
    uuid(814B11D3-C9FB-11d3-A956-00C0F0111CD7),
    /* dual, */
    helpstring("The class for reporting character-level discoveries in comments"),
    helpcontext( 1020 ),
    pointer_default(unique)
]
interface ICharacterFindings : IDispatch
{
    // Description:  The method for reporting an error in the comment
    //
    // Arguments:
    //   markupStart - The beginning of the bad markup block (not just the
    //                 start of the errant part of the block).
    //   markupEnd - The end of the bad markup block (ditto).
    //   errormessage - The error message to be printed.
    //
    [ id(10),
      helpstring( "Report an error in the comment" ),
      helpcontext( 1010 ) ]
    HRESULT CommentError( [in]long markupStart, [in]long markupEnd,
                  [in]BSTR errormessage );

    // Description:  Called by ICharacterMarkupScanner to report a finding.
    //
    // Arguments:
    //   bodyStart -   The start of the contents of the block
    //   bodyEnd -     The end of the contents of the block.  Unlike other
    //                 types of markups, bodyEnd must be greater than bodyStart,
    //                 as open-ended character markups are not supported.
    //
    //                 Note: But in real life, it actually does work...
    //                       I just don't think it's a good idea.
    //
    //   markupStart - The start of the textual clue that indicates the block
    //                 (see Markup).
    //   markupEnd -   The end of the textual clue.
    //   confidence -  An indication of the likelihood that this markup really
    //                 is being correctly identified.
    //   o -           A markup function for translating the block.
    [ id(21),
      helpstring( "Report a character finding" ),
      helpcontext( 1021 )
    ]
    HRESULT AddCharacterFinding(
                     [in]long markupStart, [in]long markupEnd,
                     [in]long confidence,
                     [in]IMarkupFunctionObject *o );
};


// {group:Core Interfaces}
//
// Description:  An iterator for the directive set of an output format
//
// Remarks:
//   Objects that implement this are used in conjunction with
//   IOutputFormat.WithAllDirectives
[
    object,
    uuid(E73BBA19-FA6C-4832-B0D3-C01ACE631594),
    /* dual, */
    helpstring("Executed for each directive in an output format"),
    helpcontext( 1147 ),
    pointer_default(unique)
]
interface IWithDirective : IDispatch {
    // Description:  Executed for each directive defined by the output format
    //
    // Arguments:
    //  name - The name of the directive
    //  nArgs - The number of arguments that the directive is declared
    //          to take
    [id(148), helpcontext(1148),
     helpstring("Execute a function given a directive" ) ]
    HRESULT DoIt( [in]BSTR name, [in]long nArgs );
};


// {group:Core Interfaces}
//
// Description:  This interface provides calls that allow markup-generating
//               plug-ins to verify that the output format has the right
//               set of capabilities.
[
    object,
    uuid(B2373295-C9FB-11d3-A956-00C0F0111CD7),
    /* dual, */
    helpstring("Provides a mechanism for testing the capabilities of the output format"),
    helpcontext( 1023 ),
    pointer_default(unique)
]
interface IOutputFormat : IDispatch
{
    // Description:  Called to test whether the output format implements a
    //               certain function.
    //
    // Arguments:
    //  name - The name of the markup function
    //  nargs - The number of arguments that we intend to pass it
    //          if it exists.
    //
    // Returns:
    //   TRUE if the function exists and has the required number of arguments,
    //   FALSE otherwise.
    [ id(24),
      helpstring( "Test to see if a function exists" ),
      helpcontext( 1024 )
    ]
    HRESULT HasFunction( [in]BSTR name, [in]long nargs,
                 [out,retval]BOOL *gotIt );

    // Description:  Iterates through all the directives in the output format
    //
    // Arguments:
    //  iterator - The iterator for the collection.  Its /DoIt/
    //             method will be called for each directive.
    [ id(144),
      helpstring( "Gets the names of all directives" ),
      helpcontext( 1144 )
    ]
    HRESULT WithAllDirectives( [in]IWithDirective *iterator );
};

// {group:Core Interfaces}
//
// Description:  Provides access to the project configuration file
//
// Remarks:
//  This interface provides functions that allow hooks to store and
//  retrieve their project-specific settings as well as accessing the
//  list of comment sections and introducers.
[
    object,
    uuid(0C25EEBD-DD7A-11d3-A983-00D0B71B1994),
    /* dual, */
    helpstring("Allows add-ins to write to the project-configuration file"),
    helpcontext( 1038 ),
    pointer_default(unique)
]
interface IProjectConfiguration : IDispatch {
    // Description:  Retrieves a persistent setting from the project file.
    //
    // Arguments:
    //   attr - The name of the attribute to retrieve.
    //
    // Returns:
    //    The setting of the attribute in the configuration file.
    //    Null if the attribute has not been set.
    //
    // Remarks:
    //    The attribute name is unique to the requesting object.
    //    This means you do not need to worry about conflicts with
    //    other plug-ins using the same attribute name.  On the
    //    other hand, this means that two plug-ins cannot share
    //    settings information.
    [ id(39),
      helpstring( "Gets the value of an attribute" ),
      helpcontext( 1039 )
    ]
    HRESULT GetAttribute( [in]BSTR attr, [retval,out]BSTR *out );


    // Description:  Makes a persistent setting in the project file.
    //
    // Arguments:
    //   attr - The name of the attribute to set.
    //   val - The value to set it to.
    //
    // Remarks:
    //    The attribute name is unique to the requesting object.
    //    This means you do not need to worry about conflicts with
    //    other plug-ins using the same attribute name.  On the
    //    other hand, this means that two plug-ins cannot share
    //    settings information.
    [ id(40),
      helpstring( "Sets the value of an attribute" ),
      helpcontext( 1040 )
    ]
    HRESULT SetAttribute( [in]BSTR attr, [in]BSTR val );

    /*
     * Description:
     *  Gets the names of all comment sections
     *
     * Arguments:
     *  array - An array that will be filled in with the names
     *          of all the comment sections.
     *
     * Remarks:
     *  Note: These comment section names are /logical/ names, not
     *  /introducers/. "Logical Names" are used by the output format
     *  to refer to sections found in the comment in a language-
     *  independent manner.  "Introducers" are the actual text that
     *  appears in comments to signal the start of a section.
     */
    [ id(41),
      helpstring( "Gets the names of all comment sections" ),
      helpcontext( 1041 )
    ]
    HRESULT GetAllCommentSectionNames( [in,out]SAFEARRAY(BSTR) *array );

    /*
     * Description:
     *  Gets the keywords that introduce a comment section.
     *
     * Arguments:
     *  section - The logical name of the comment section.
     *  array - An array that will be filled in with the comment
     *          section's introducers.
     */
    [ id(42),
      helpstring( "Gets the keywords that introduce a comment section" ),
      helpcontext( 1042 )
    ]
    HRESULT GetCommentSectionIntroducers( [in]BSTR section, [in,out]SAFEARRAY(BSTR) *array );

};

// {group:Core Interfaces}
//
// Description:  Provides access to the project configuration file
//
// Remarks:
//  This interface provides functions that allow hooks to store and
//  retrieve their project-specific settings as well as accessing the
//  list of comment sections and introducers.
[
    object,
    uuid(B5DC411E-984E-4f37-863D-EFAC0A529937),
    /* dual, */
    helpstring("Allows add-ins an upgrade path from their equivolents in the 3.x world"),
    helpcontext( 1144 ),
    pointer_default(unique)
]
interface I3XUpgradePath : IDispatch {

    /*
     * Description:
     *   Allows hooks to get at legacy settings from the 3.x world.
     *
     * Arguments:
     *  hookData - The data from the 3.x world (which was always stored in binary format.
     *  lengthInBytes - The number of bytes of data in hookData
     *  storeSettingsIn - The project configuration from which the data came from
     *                    and to which the attributes should be put.
     */
    [ id(143),
      helpstring( "Gets the settings for the object stored in the old 3.x format" ),
      helpcontext( 1143 )
    ]
    HRESULT TranslateData( [in]IProjectConfiguration *storeSettingsIn,
                           [in]const void *hookData, [in]DWORD lengthInBytes );

    /*
     * Description:  The name of the hook in the 3.x world.
     *
     * Remarks:
     *   This is the base name of the DLL as it was in 3.x.
     */
    [ id(145),
      helpstring( "Gets the old name of the hook (as stored in the HookData section." ),
      helpcontext( 1145 ),
      propget ]
    HRESULT Name( [out,retval]BSTR *name );
};



// {group:Core Interfaces}
// Description:  Settings controls must implement this interface -
//   it supplies one method which is used to validate and store
//   input data.
[
    object,
    uuid(A93FB9C7-C9FC-11d3-A956-00C0F0111CD8),
    /* dual, */
    helpstring("Provides GUI features for the object"),
    helpcontext( 1027 ),
    pointer_default(unique)
]
interface IDocJetAdvancedSettingsControl : IDispatch
{
    // Description:  Asks the control to validate the input and
    //   store it.
    //
    // Arguments:
    //   settings - The project configuration file's interface.
    //
    // Return Value:
    //   TRUE if the input was valid, FALSE otherwise.
    [ id(28),
      helpstring( "Validate and store settings" ),
      helpcontext( 1028 )
    ]
    HRESULT KillActive( [in]IProjectConfiguration *settings, [retval,out]BOOL *ok );
};

// {group:Core Interfaces}
// Description:  The events class for settings controls.
//        Its sole function right now is to let the owner
//        of the control know that the user has dorked with
//        something inside the control so that the owner can
//        set a dirty bit.
[
    uuid(A93FB9C7-C9FC-11d3-A956-00C0F0111CD9),
    helpstring("Provides GUI features for the object"),
    helpcontext( 1027 )
]
interface IDocJetAdvancedSettingsEvents : IDispatch
{
    // Description:  Asks the control to validate the input and
    //   store it.
    //
    // Arguments:
    //   settings - The project configuration file's interface.
    //
    // Return Value:
    //   TRUE if the input was valid, FALSE otherwise.
    [ id(28)]
    HRESULT SettingChanged();
};


// {group:Core Interfaces}
// Description:  An interface to implement in plug-ins that need
//     to have persistent settings.
//
// Remarks:
//   This interface supports just one method, GetAXControl, which
//   returns a pointer to an ActiveX control that controls the
//   settings for the object.  Initialization of the persistent
//   settings is done in IDocJetAddIn::Initialize.  That method
//   is in the main interface because there are rare circumstances
//   in which a settings-free plug-in needs to access the
//   project configuration's section heading information.
[
    object,
    uuid(E7AB5F9F-CEE6-4c41-85A5-2DF3E1B8D3A9),
    /* dual, */
    helpstring("Provides GUI features for the object"),
    helpcontext( 1126 ),
    pointer_default(unique)
]
interface IDocJetAddInSettings : IDispatch
{
    // Description:  Gets the ActiveX control for the object
    //
    // Return Value:
    //   The ActiveX control for the object.  This control will be
    //   rendered in the project configuration editor
    [ id(125),
      helpstring( "Returns an ActiveX control for the object" ),
      helpcontext(1125)
    ]
    HRESULT GetAXControl( [out,retval]IDocJetAdvancedSettingsControl **p );
};






// {group:Core Interfaces}
//
//  Description:  Core methods implemented by all plug-ins
//
//  Remarks:
//    All plug-ins must implement this interface.
[
    uuid(C5B3E98D-C9FD-11d3-A956-00C0F0111CD7),
    object,
    helpstring("Provides GUI features for the object"),
    helpcontext( 1028 ),
    pointer_default(unique)
]
interface IDocJetAddIn : IDispatch
{
    // Description:  Returns the name of the object as seen in the DocJet GUI
    //
    // Return Value:  The name of the plug-in.
    [ id(29),
      helpstring( "Gets a textual description of the scanner" ),
      helpcontext( 1029 )
    ]
    HRESULT GetLongDescription( [out,retval]BSTR *out );

    // Description:  Validates that the output format implements all required function
    //
    // Arguments:
    //  o - The interface of the output format.
    //
    // Return value:
    //  TRUE if the output format implements all required functions and FALSE
    //  otherwise.
    //
    // Remarks:
    //  At present, only comment-scanning plug-ins (those that implement
    //  ICharacterMarkupScanner et. al.) need to implement this guy.
    //  Your implementation should guard against any call to
    //  IMarkupSegment.AppendResultsOfCallToOutputFormat
    //  going awry because the function you called is not there.
    [ id(43),
      helpstring( "Tells the add-in to reset for a new output format" ),
      helpcontext( 1043 )
    ]
    HRESULT TestOutputFormat( [in]IOutputFormat *o, [out,retval]BOOL *isComplete );

    // Description:  Called to initialize the plug-in's persistent settings.
    //
    // Arguments:
    //  p - The interface of the project configuration file.
    //
    // Remarks:
    //  This brings in the persistent settings from the project
    //  configuration file, with calls to IProjectConfiguration::GetAttribute.
    //  It can also be used to load information on comment sections.
    //
    //  It is that last capability that puts Initialize here instead of
    //  IDocJetAddInSettings, where it seems more appropriate.  In reality,
    //  the comment sections area of the project configuration is a sort
    //  of communal information store.
    [ id(30),
      helpstring( "Loads the persistent settings from the project configuration" ),
      helpcontext( 1030 )
    ]
    HRESULT Initialize( [in]IProjectConfiguration *p );
};


// {group:Character Scanning}
//
// Description:  Implemented by plug-ins that scan comments for
//         character-level markups.
//
// Remarks:
//   Character-level markups modulate the appearance of a string
//   of text within a paragraph.
//
// See Also:  IParagraphMarkupScanner and ISectionMarkupScanner.
[
    object,
    uuid(13084E53-C9FF-11d3-A956-00C0F0111CD7),
    /* dual, */
    helpstring("interface for character scanning comment manipulators"),
    helpcontext( 1031 ),
    pointer_default(unique)
]
interface ICharacterMarkupScanner : IDispatch {
    // Description:  Scans paragraph text for character markups
    //
    // Arguments:
    //   text - The paragraph text
    //   reportTo - An object that we will use to report any
    //              character blocks we find.
    //
    [ id(32),
      helpstring( "Scans a block of text for markups" ),
      helpcontext( 1032 )
    ]
    HRESULT Scan( [in]BSTR text, [in]ICharacterFindings *reportTo );
};

// {group:Paragraph Scanning}
//
// Description:  Implemented by plug-ins that scan comments for
//         paragraph-level markups.
//
// Remarks:
//   Paragraph-level markups identify the blocks of text that
//   form paragraphs.  This scanner can also identify blocks
//   of paragraphs, like numbered lists.
//
// See Also:  ICharacterMarkupScanner and ISectionMarkupScanner.
[
    object,
    uuid(67C1BE3D-CA00-11d3-A956-00C0F0111CD7),
    /* dual, */
    helpstring("interface for paragraph-scanning comment manipulators"),
    helpcontext( 1033 ),
    pointer_default(unique)
]
interface IParagraphMarkupScanner : IDispatch {
    // Description:  Scans section text for character markups
    //
    // Arguments:
    //   text - The text of a comment section
    //   segmentStart - The start of the part of text that we should be
    //                  looking at
    //   segmentEnd - The end of the segment
    //   firstLineOffset - The number of characters between the beginning
    //                     of the line and the first character in the segment.
    //   reportTo - An object that we will use to report any
    //              paragraphs or paragraph blocks we find.
    //   embedded - TRUE if this is a paragraph within a list or some
    //              other surrounding paragraph block
    //   sectionName - The logical section name of the block we are scanning.
    //
    [ id(34),
      helpstring( "Scans a block of text for markups" ),
      helpcontext( 1034 )
    ]
    HRESULT Scan( [in]BSTR text, [in]int firstLineOffset, [in]int segmentStart,
                  [in]int segmentEnd, [in]BOOL embedded, [in]BSTR sectionName,
                  [in]IParagraphFindings *reportTo );

    // Description:  Returns the maximum Confidence value that this plug-in will return.
    //
    // Return Value:
    //   out - The maximum Confidence value that this plug-in will return.
    [ id(142), propget,
      helpstring( "The maximum confidence of paragraphs found by this scanner" ),
      helpcontext( 1142 )
    ]
    HRESULT MaxConfidence( [out,retval]LONG *maxConfidence );
};

// {group:Section Scanning}
//
// Description:  Implemented by plug-ins that scan comments for
//         section-level markups.
//
// Remarks:
//   Section-level markups identify the blocks of text that
//   form comment sections.
//
// See Also:  ICharacterMarkupScanner and IParagraphMarkupScanner.
[
    object,
    uuid(833D79B3-CA00-11d3-A956-00C0F0111CD7),
    /* dual, */
    helpstring("interface for section-scanning comment manipulators"),
    helpcontext( 1035 ),
    pointer_default(unique)
]
interface ISectionMarkupScanner : IDispatch {
    // Description:  Scans comments for character markups
    //
    // Arguments:
    //   text - The text of the entire comment
    //   reportTo - An object that we will use to report any
    //              section markers we find.
    //
    [ id(36),
      helpstring( "Scans a block of text for section markups" ),
      helpcontext( 1036 )
    ]
    HRESULT Scan( [in]BSTR text, [in]ISectionFindings *reportTo );
};

// {group:Directive Scanning}
//
// Description:  Implemented by plug-ins that scan comments for
//         directives.
//
// See Also:  ISectionMarkupScanner, ICharacterMarkupScanner and
//            IParagraphMarkupScanner.
[
    object,
    uuid(A2A193BA-A1A7-4d70-BCC6-E0FDDAF45419),
    /* dual, */
    helpstring("interface for section-scanning comment manipulators"),
    helpcontext( 1149 ),
    pointer_default(unique)
]
interface IDirectiveScanner : IDispatch {
    // Description:  Scans comments for character markups
    //
    // Arguments:
    //   text - The text of the entire comment
    //   reportTo - An object that we will use to report any
    //              section markers we find.
    //
    [ id(150),
      helpstring( "Scans a block of text for directives" ),
      helpcontext( 1150 )
    ]
    HRESULT Scan( [in]BSTR text,
                  [in]IDirectiveFindings *reportTo );
};

// {group:Unboxing}
//
// Description:  Implemented by plug-ins that separate comment-delineators
//    from comment text.
[
    object,
    uuid(A83913C1-CA00-11d3-A956-00C0F0111CD7),
    /* dual, */
    helpstring("interface for comment-unboxing comment manipulators"),
    helpcontext( 1037 ),
    pointer_default(unique)
]
interface ICommentUnboxer : IDispatch {
    // Description:  Removes the comment delineators from a comment
    //
    // Arguments:
    //  input - The comment with comment markers included
    //  confidence - If the comment cannot be unboxed, this should be
    //               set to zero.  If it can be unboxed, then set this
    //               to a value that indicates how confident you are
    //               that this was the correct way to unbox it.
    //  out - Set this to the cleaned-up comment.
    //
    // See Also:  Confidence.
    [ id(37),
      helpstring( "Pulls boxing characters out of comments" ),
      helpcontext( 1037 )
    ]
    HRESULT Unbox( [in]BSTR input, [in,out]long *confidence, [in,out]BSTR *out );

    // Description:  Returns the maximum Confidence value that this plug-in will return.
    //
    // Return Value:
    //   out - The maximum Confidence value that this plug-in will return.
    [ id(38),
      helpstring( "Returns the maximum confidence that this object will return" ),
      helpcontext( 1038 ) ]
    HRESULT GetMaxConfidence( [out,retval]long *out );
};

// {group:Source File Scanning}
//
// Description:  A rough description of a type of object.
//
// Remarks:
//   Each sub-type (ISubtype) has a RoughType that tells any
//   other interested plug-in and the DocJet generator roughly
//   what the object is.
typedef [uuid(C41BAA81-E7B2-11d3-A997-00D0B71B1994)] enum RoughType {
    ABSTRACT_ID = 0,    // For rough-types that are
                        //   used as groups, and never have
                        //   instances.
    TYPEDEF_ID = 't',   // Objects that are simple type definitions.
                        //   If an object defines a namespace,
                        //   such as a class, should use CLASS_ID.
    FUNCTION_ID= 'f',   // Any object that manipulates, rather than *is*
                        //   data.  E.g. a method.
    VARIABLE_ID = 'v',  // Any data object
    CLASS_ID = 'c',     // Any data type that also defines a namespace.
                        //  The line is a bit fuzzy here, as structures
                        //  and enums technically define a namespace,
                        //  but still they can be thought of as typedefs.
    PAPER_ID = 'p',     // This rough type that means something
                        //  to the generator.  It indicates that the object's
                        //  comment is already in a markup language and
                        //  should not get the usual comment parsing treatment.
    ARGUMENT_ID = 'a',  // Arguments to functions, macros, templates, etc.
    GLOSSARY_TERM_ID = 'w', // Glossary words
    HYPERLINK_ID = 'h', // Hyperlinks, like papers, are treated differently
                        //  by the generator.  Here the comment is the
                        //  object being hyperlinked to.
} RoughType;

// {group:Source File Scanning}
//
// Description:  Describes a subcategory of objects
//
// Remarks:
//   All objects reported to a generator have an ISubtype associated with
//   them.  The ISubtype essentially identifies the type of object.  It is
//   mainly used by the Output Format, inasmuch as "Categories" are made
//   up of collections of sub-types.
//
//   The "sub" in subtype is really a misnomer.  Just "type" would be a
//   more accurate description of what these guys are about.  This is a
//   legacy from days of old when "Categories" were considered types.
//   "Categories" were renamed, subtypes weren't.
//
//   Subtypes can have a hierarchical relationship to one another.
//   This allows us to be able to define automatic actions for
//   "operator++" and still be able to define them for all
//   "methods" at once.
//
//   Plug-ins do not implement this interface - source file scanners will
//   be given an ISubtypeCollection that they add their subtypes to.
//   ISubtypeCollection provides a mechanism where you add a subtype
//   (by name and attributes) to the collection, the generator then
//   creates an ISubtype object and returns a pointer to it.  The scanner
//   keeps track of this pointer and gives it back to the generator
//   when reporting objects.
//
//   ISubtypes are fairly static.  Once initialized, they do not change.
//   This is obvious in that all the properties are read-only -- the
//   only real way to modify a subtype is by creating new ones (new
//   subordinate subtypes, that is).  That activity should all be
//   accomplished during initialization.
[
    object,
    uuid(9F8DF646-E96A-11d3-A999-00D0B71B1994),
    /* dual, */
    helpstring("Defines a subtype for a language scanner"),
    helpcontext(1043),
    pointer_default(unique)
]
interface ISubtype : IDispatch {
    // Description:  Returns the owning subtype
    //
    // Return Value:
    //   The sub-type that this is a specialization of.  If there is no
    //   specialization, null will be returned.
    [ propget, id(44), helpcontext(1044),
      helpstring( "A pointer to the subtype that abstracts this one" ) ]
    HRESULT Generalization( [out,retval]ISubtype **superType );

    // Description:  The name of the subtype
    //
    // Return Value:
    //   The name of the subtype.  This will be displayed in the "Automatics"
    //   page of the project configuration file and the "Categories" page of
    //   the output format editor.
    [ propget, id(45), helpcontext(1045),
      helpstring( "The name of this subtype" ) ]
    HRESULT Name( [out,retval]BSTR *name );

    // Description:  The RoughType of the object
    //
    // Return Value:
    //   A RoughType that describes in general terms what objects of this
    //   subtype are about.
    [ propget, id(46), helpcontext(1046),
      helpstring( "A rough classification for this sort of object" ) ]
    HRESULT Classification( [out,retval]RoughType *roughType );

    // Description:  Tells the generator if the comment does not need to be unboxed
    //
    // Return Value:  TRUE if the object does not need to be unboxed, FALSE if it should be.
    //
    // Remarks:
    //   Certain source file scanner types do not need to use ASCII markups to
    //   delineate the boundaries of a comment.  For instance, the glossary language
    //   we created needs no markup for comments, because the markup scheme only
    //   asks you to tag the glossary words with markup (the leading ">" character).
    //   Also, we have the example of the Output Format Source scanner (the source
    //   file scanner that reads in DOF files.)  DOF files are binary
    //   and hold their comments in a separate spot in the binary file.
    [ propget, id(47), helpcontext(1047),
      helpstring( "True if the comment for this object does not need to be unboxed" ) ]
    HRESULT AlreadyUnboxed( [out,retval]BOOL *alreadyUnboxed );

    // {group:Subordinate management}
    // Description:  Creates a new subtype.
    //
    // Arguments:
    //   name - The name (shown in the output format editor, etc.) of the object.
    //   classification - A rough description of the type.
    //   alreadyUnboxed - TRUE if objects of this type do not need to be unboxed.
    //                    (See AlreadyUnboxed).
    // 
    // Return Value:
    //  A new Subtype object.
    //
    // Remarks:
    //  This is no different than Subtypes.Add.  It's just a shorthand, really.
    [ id(111), helpcontext( 1111 ),
      helpstring( "Creates a new subtype" ) ]
    HRESULT Add( [in]BSTR name, [in]RoughType classification,
                 [in]BOOL alreadyUnboxed, [out,retval]ISubtype **out );

    // {group:Subordinate management}
    // Description:  The collection of subordinates
    //
    // Remarks:
    //  This is a container object for all subtypes that specialize this subtype.
    [ id(112), helpcontext( 1112 ), propget,
      helpstring( "Gets the collection object for the children of the subtype" ) ]
    HRESULT Subtypes( [out,retval]ISubtypeCollection **children );
};

// {group:Source File Scanning}
//
// Description:  An interface that helps translate papers (raw markup) into
//    finished DocJet output.
//
// Remarks:
//  Objects implementing this appear exclusively as arguments to
//  ICustomGenerator.Generate.  These objects are implemented by
//  the generator.
[
    object,
    uuid(9F8DF64f-E96A-11d3-A999-00D0B71B1994),
    /* dual, */
    helpstring("interface that does auto-hyperlinking for custom-generators"),
    helpcontext( 1089 ),
    pointer_default(unique)
]
interface ICustomGeneratorSubstitutor : IDispatch {
    // Description:  Takes pure text as input, scans it for the appearance of
    //               names of objects and replaces them with hyperlink markup.
    //
    // Arguments:
    //   output - Where to put the result
    //   segment - The text segment.  This should be free of any markup.
    [ id(90), helpcontext( 1090 ),
      helpstring( "The source file patterns that this scanner will read" ) ]
    HRESULT AutoHyperlink( [in]IMarkupSegment *output,
                           [in]BSTR segment );
};

// {group:Source File Scanning}
//
// Description:  Implements a paper-translation scheme
//
// Remarks:
//   Source file scanners that read markup-language source files
//   (e.g. HTML, RTF, etc.) will need to implement objects of this
//   type.  The main function here is Generate, which will take
//   in the raw markup language and contort it to fit into a
//   DocJet output set.
[
    object,
    uuid(9F8DF64d-E96A-11d3-A999-00D0B71B1994),
    /* dual, */
    helpstring("interface for source file scanners"),
    helpcontext( 1091 ),
    pointer_default(unique)
]
interface ICustomGenerator : IDispatch {
    // Description:  The name of the translation scheme
    //
    // Remarks:
    //   This is the name of the scheme as is shown in the output format
    //   editor GUI.
    [ id(118), helpcontext( 1118 ), propget,
      helpstring( "The name of the generator" ) ]
    HRESULT Name( [out,retval]BSTR *name );

    // Description:  Transforms a block of raw markup into finished markup.
    //
    // Arguments:
    //  output - Where to put the result.
    //  obj - The object on which we're operating
    //  doSubs - A mechanism to replace object names with hyperlinks to
    //           the object names in markup-free blocks of text.
    //  assignedTag - The topic tag (hyperlink target) for the whole file.
    //  title - The title of the topic (also the object name as reported
    //          by the source file scanner).
    //  body - The raw markup
    //  filename - The source file name
    //  customArg - This comes from the output format editor.
    //  reportErrorsTo - An interface where you can post complaints
    //
    [ id(92),
      helpstring( "The source file patterns that this scanner will read" ),
      helpcontext( 1092 ) ]
    HRESULT Generate( [in]IMarkupSegment *output,
                      [in]IObject *obj,
                      [in]ICustomGeneratorSubstitutor *doSubs,
                      [in]BSTR assignedTag,
                      [in]BSTR title,
                      [in]BSTR body,
                      [in]BSTR filename,
                      [in]BSTR customArg,
                      [in]IErrors *reportErrorsTo );
};

// {group:Source File Scanning}
//
// Description:  A collection of objects implementing ISubtype
//
// Remarks:
//  This should only be implemented by the generator.
//
//  Associated with each source file type there is a subtype collection.
//  The source file scanner will add root subtypes to this collection.
//  If a subtype has specializations, it will also have a collection.
[
    object,
    uuid(9BD01665-0C05-11d4-A9E6-00D0B71B1994),
    helpstring("A collection of subtypes - associated with source file scanners"),
    helpcontext( 1109 ),
    pointer_default(unique)
]
interface ISubtypeCollection : IDispatch {
    // Description:  The number of items in the collection
    [ id(106), helpcontext( 1106 ), propget,
      helpstring( "Returns the number of subtypes" ) ]
    HRESULT Count( [out,retval]long *count );

    // {secret}
    [ id(DISPID_NEWENUM), propget, restricted,
      helpstring( "Returns an IEnumUnknown" ) ]
    HRESULT _NewEnum( [out,retval]IUnknown ** NewEnum );

    // Description:  Returns an element of the collection
    //
    // Arguments:
    //   index - The index (zero-based) of the item you want.
    //
    // Return Value:
    //   The subtype object or null if the index is out of bounds.
    [ id(108), helpcontext( 1108 ), propget,
      helpstring( "Returns a particular enum item" ) ]
    HRESULT Item( [in]long index, [out,retval]ISubtype ** Item);

    // Description:  Adds a new subordinate subtype to the collection
    //
    // Arguments:
    //   name - The name (shown in the output format editor, etc.) of the object.
    //   classification - A rough description of the type.
    //   alreadyUnboxed - TRUE if objects of this type do not need to be unboxed.
    //                    (See AlreadyUnboxed).
    // 
    // Return Value:
    //  A new Subtype object.
    [ id(110), helpcontext( 1110 ),
      helpstring( "Creates a new subtype" ) ]
    HRESULT Add( [in]BSTR name, [in]RoughType classification,
                 [in]BOOL alreadyUnboxed, [out,retval]ISubtype **out );
};

// {group:Source File Scanning}
//
// Description:  A collection for all the custom markup generators
//               implemented in a source file scanner.
//
// Remarks:
//   This is implemented by the generator and passed to
//   ISourceFileScanners.InitializeCustomGenerators.
//   The source file scanner will populate the collection at
//   that time.
[
    object,
    uuid(9CFC8D31-0C9E-11d4-A9E7-00D0B71B1994),
    helpstring("A collection of custom generators - associated with source file scanners"),
    helpcontext( 1114 ),
    pointer_default(unique)
]
interface ICustomGeneratorCollection : IDispatch {
    // Description:  The number of items in the collection
    [ id(115), helpcontext( 1115 ), propget,
      helpstring( "Returns the number of subtypes" ) ]
    HRESULT Count( [out,retval]long *count );

    // {secret}
    [ id(DISPID_NEWENUM), propget, restricted,
      helpstring( "Returns an IEnumVARIANT for VB's For Each statement" ) ]
    HRESULT _NewEnum( [out,retval]IUnknown ** NewEnum );

    // Description:  Returns an element of the collection
    //
    // Arguments:
    //   index - The index (zero-based) of the item you want.
    //
    // Return Value:
    //   The generator object or null if the index is out of bounds.
    [ id(116), helpcontext( 1116 ), propget,
      helpstring( "Returns a particular generator" ) ]
    HRESULT Item( [in]BSTR index, [out,retval]ICustomGenerator ** out );

    // Description:  Adds an element to the collection
    //
    // Arguments:
    //   toAdd - The custom generator
    //
    // Remarks:
    //   ICustomGeneratorCollection is implemented by DocJet, but
    //   ICustomGenerator will be implemented by the plug-in.  This
    //   is different than what you see in ISubtypeCollection.
    [ id(117), helpcontext( 1117 ),
      helpstring( "Adds a generator to the collection" ) ]
    HRESULT Add( [in]ICustomGenerator *toAdd );
};


// {group:Source File Scanning}
//
// Description:  Parses source files and identifies the objects
//               in them.
//
// Remarks:
//   This interface abstracts most of what DocJet knows about programming
//   languages.  The business end is ScanSource, which is given a
//   source file name reports on the objects contained within.
[
    object,
    uuid(9F8DF64e-E96A-11d3-A999-00D0B71B1994),
    /* dual, */
    helpstring("interface for source file scanners"),
    helpcontext( 1091 ),
    pointer_default(unique)
]
interface ISourceFileScanner : IDispatch {
    // Description:  Called to set up the subtype collections.
    //
    // Arguments:
    //   subtypes - The collection object created by the generator for
    //              the storage of the file's subtypes.
    //
    // Remarks:
    //   Associated with each file type is a set of object types.
    //   Just as ISourceFileScanner abstracts source file types,
    //   ISubtype abstracts object types.  Implementations of this
    //   method are responsible for creating the object types that are
    //   associated with this file type.
    //
    //   This method is called after IDocJetAddIn::Initialize
    //   and before any calls to ScanSource.
    //
    //   Implementations need to store a reference to subtypes, as
    //   it can be queried with the Subtypes property.
    [ id(119), helpcontext(119),
      helpstring( "Sets up the subtypes collection" ) ]
    HRESULT InitializeSubtypes( [in]ISubtypeCollection *subtypes );

    // Description:  Called to set up the custom-generator collections.
    //
    // Arguments:
    //   customGenerators - The collection object created by
    //                      the generator to hold the custom
    //                      generators for this source file type.
    //
    // Remarks:
    //   This interface is only useful for source file types that deal
    //   with markup languages (e.g. .html and .rtf source files).
    //   Markup language processors need to be able to separate out
    //   blocks of clear text from markup code so that that text can
    //   be auto-hyperlinked.  These functions also reorganize the
    //   markup to fit within the DocJet output more neatly.
    //
    //   This function just points DocJet at the translation mechanism,
    //   which is implemented by ICustomGenerator.  Usually you will only
    //   need a single ICustomGenerator object for any given markup
    //   language.
    //
    //   Implementations need to store a reference to subtypes, as
    //   it can be queried with the CustomGenerators property.
    [ id(120), helpcontext(120),
      helpstring( "Sets up the custom generators collection" ) ]
    HRESULT InitializeCustomGenerators( [in]ICustomGeneratorCollection *customGenerators );

    // Description:  The extensions that the source file scanner can read.
    //
    // Remarks:
    //   This should give the filename pattern for the source files,
    //   e.g. "*.idl;*.odl" would be the pattern for the IDL scanner.
    [ propget, id(92),
      helpstring( "The source file patterns that this scanner will read" ),
      helpcontext( 1049 ) ]
    HRESULT FileExtension( [out,retval] BSTR *ext );

    // Description:  The name of the source file type
    //
    // Remarks:
    //   This is used in the GUI's.  Particularly, it is shown in the
    //   "Add Individual Files" File Open dialog box on the project
    //   configuration editor's "Sources" page.
    [ propget, id(50),
      helpstring( "The name of the source file type" ),
      helpcontext( 1050 ) ]
    HRESULT FileTypeName( [out,retval] BSTR *ftn );

    // Description:  Parses a source file and identifies all objects in it.
    //
    // Arguments:
    //   realSourceFile - Always is the source file name that the object
    //                    originally came from.
    //   mungedSourceFile - If the source file was transformed via a Hook
    //                      (IHook::RewriteSource), then what the source
    //                      file scanner will actually be reading is a
    //                      temporary file created by the hook.  If that
    //                      is the case, mungedSourceFile will be the
    //                      temporary file name and realSourceFile will be
    //                      the original source file.
    //
    //                      The important difference is that you want to
    //                      open and read mungedSourceFile, but always
    //                      report the objects as having been found in
    //                      realSourceFile.
    //   reportObjectsTo -  Called when we find objects.
    //   reportErrorsTo -   Called should we find an error in the source file.
    //
    // Remarks:
    //   This is where the rubber meets the road in a source file scanner.
    //   We open up mungedSourceFile here, parse the file, and, when we
    //   discover objects, we report them with
    //   IObjectCollection::AddObject.
    //
    //   In some cases, it may not be possible to report the objects as
    //   soon as they are spotted, as the full definition for the object
    //   might be spread across several files.  If that is the case,
    //   you will need to store up all the objects that you find and then
    //   report them in ScanComplete.
    [ id(51),
      helpstring( "Provides a set of SubTypes generated by this function" ),
      helpcontext( 1051 ) ]
    HRESULT ScanSource( [in]BSTR realSourceFile, [in]BSTR mungedSourceFile,
                        [in]IObjectCollection *reportObjectsTo,
                        [in]IErrors *reportErrorsTo );

    // Description:  Called to inform the interface that the last source
    //               file of this type has been scanned.
    //
    // Arguments:
    //   reportObjectsTo -  Called when we find objects.
    //   reportErrorsTo -   Called should we find an error in the source file.
    //
    // Remarks:
    //   This function is only useful if an objects definition can span more
    //   than one source file.  In that case, each possibly incomplete
    //   definition will need to be remembered during ScanSource.
    //   Here in ScanComplete, we look through all those remembered definitions,
    //   combine them, and add them to reportObjectsTo.
    [ id(82),
      helpstring( "Called when the last source file has been scanned" ),
      helpcontext( 1082 ) ]
    HRESULT ScanComplete( [in]IObjectCollection *reportObjectsTo,
                          [in]IErrors *reportErrorsTo );

    // Description:  The custom generator collection for this class
    //
    // Remarks:
    //  This should simply return a reference to the argument given to
    //  InitializeCustomGenerators.
    [ id(94), propget, helpcontext( 1094 ),
      helpstring( "Gets the collection object for custom generators" ) ]
    HRESULT CustomGenerators( [out,retval]ICustomGeneratorCollection **children );

    // Description:  The subtype collection for this class
    //
    // Remarks:
    //  This should simply return a reference to the argument given to
    //  InitializeSubtypes.
    [ id(113), helpcontext( 1113 ), propget,
      helpstring( "Gets the collection object for the children of the subtype" ) ]
    HRESULT Subtypes( [out,retval]ISubtypeCollection **children );
};


// {group:Rewriting Files and object Sets}
//
// Description:
//   Used by IObjectCollection::Foreach to iterate over the elements of an object collection
//
// Remarks:
//   The name of this class is somewhat misleading, as more things than just
//   Hooks can use it.  You will want to implement this class whenever you
//   want to iterate through all the objects in an IObjectCollection.
[
    object,
    uuid(9F8DF647-E96A-11d3-A999-00D0B71B1994),
    /* dual, */
    helpstring("Called by IObjectCollection::Foreach to iterate over the elements of an object array"),
    helpcontext( 1053 ),
    pointer_default(unique)
]
interface IHookIterator : IDispatch {
    // Description:
    //   Called for each object in an IObjectCollection via
    //   IObjectCollection::Foreach
    //
    // Arguments:
    //   obj - The object under the cursor
    //   name - The object's full name
    //   subtype - The objects type
    //   inheritor - If the object inherits documentation from another object,
    //               this is the name of that object.  If not, set it to 0
    //   sourceFileName - The source file name (original) where the object was found
    //   sourceFileLine - The line number it was found at
    //   comment - The comment found with the object
    //   declaration - The declaration of the object
    //   body - The declaration+implementation of the object
    //   attr1 - An extended attribute of the object.  Exactly which extended
    //           attribute depends on the corresponding argument in
    //           IObjectCollection::Foreach.
    //   attr2 - ditto
    //   attr3 - ditto
    //
    // Remarks:
    //   The parameters, name, subtype, and so forth, are all things you could
    //   get by querying the attributes of obj.  By going ahead and passing
    //   the arguments in, we save not only a function call, but also calls
    //   to SysAllocString and SysFreeString, which is a pretty signifigant
    //   savings.
    [ id(54), helpcontext(1054),
      helpstring( "Executed for each object in a set" ) ]
    HRESULT DoIt( [in]IObject *obj,
                  [in]BSTR name,
                  [in]ISubtype *subtype,
                  [in]BSTR inheritor,
                  [in]BSTR sourceFileName,
                  [in]ULONG sourceFileLine,
                  [in]BSTR comment,
                  [in]BSTR declaration,
                  [in]BSTR body,
                  [in]BSTR attr1,
                  [in]BSTR attr2,
                  [in]BSTR attr3 );
};

// {group:Source File Scanning}
//
// Description:  Implements a database of objects
//
// Remarks:
//   All the objects found in the source file sets eventually find a home
//   in an object collection.  In some ways, it helps to think about
//   IObjectCollection as two different things:  There's the central
//   repository IObjectCollection that stores all the objects we've got,
//   and then there are subordinate IObjectCollection's that we create
//   to deal with subsets of things.
[
    object,
    uuid(9F8DF648-E96A-11d3-A999-00D0B71B1994),
    /* dual, */
    helpstring("The complete set of objects in the source set"),
    helpcontext( 1055 ),
    pointer_default(unique)
]
interface IObjectCollection : IDispatch {
    // Description:  Fetches an object from the collection by its name
    //
    // Arguments:
    //   objName - The name of the object to fetch
    //
    // Return Value:
    //  The object associated with the full name given.
    //
    //  If an object is overloaded, this function will return the first
    //  of the overloads.  Use GetNextOverload to see the rest of the
    //  overloads
    //
    // Remarks:
    //   This uses a reasonably effecient hash mechanism to find the name.
    [ id(56), helpcontext(1056),
      helpstring( "Looks up an object by name" ) ]
    HRESULT GetObjectByName( [in]BSTR objName, [out,retval]IObject** obj );

    // Description:  Fetches the next overload of an object
    //
    // Arguments:
    //  o - An object in an overload sequence.
    //
    // Return Value:
    //  The next overload after o.
    //
    // Example:
    //  ' This loops through all overloads of C::Foo...
    //  o = collection.GetObjectByName( "C::Foo" )
    //  While o <> nil Do
    //    ...
    //    o = collection.GetNextOverload( o );
    //  End While
    [ id(151), helpcontext(1151),
      helpstring( "Gets the next overload of an object" ) ]
    HRESULT GetNextOverload( [in]IObject *o, [out,retval]IObject** out );

    // Description:  Creates a new IObjectCollection.
    //
    // Return Value:
    //  The new collection object
    //
    // Remarks:
    //   You cannot implement IObjectCollection for yourself (due to some
    //   sticky performance issues), so instead you get this method to
    //   let you create one.
    [ id(57), helpcontext(1057),
      helpstring( "Builds a new collection for you" ) ]
    HRESULT MakeNewCollection( [out,retval]IObjectCollection **newCollection );

    // Description:  Empties the collection
    [ id(58), helpcontext(1058),
      helpstring( "Empties the collection" ) ]
    HRESULT Reset();

    // Description:  Adds all the members of one collection that have a certain
    //               RoughType to the current collection.
    //
    // Arguments:
    //   otherCollection - The collection we will be looking through
    //   t - The RoughType (category) of objects we will be adding.
    //
    // Remarks:
    //   This scans through each object in otherCollection, looking for objects
    //   whose subtype sports the same RoughType as t.  Those get added to this
    //   collection.  Typically you will start with an empty collection before
    //   calling this guy, but that is not required.
    [ id(59), helpcontext(1059),
      helpstring( "Finds a set of objects matching a RoughType" ) ]
    HRESULT IncludeByRoughType( [in]IObjectCollection *otherCollection, [in]RoughType t );

    // Description:  Adds a particular object to the collection
    //
    // Arguments:
    //   o - The new object
    //
    // Remarks:
    //   Adds a particular object to the current collection.
    [ id(81), helpcontext(1081),
      helpstring("Adds a single object to the set") ]
    HRESULT IncludeObject( [in]IObject *o );

    // Description:  Creates a new object and inserts it into the collection
    //
    // Arguments:
    //   sourceFile - The source file the object was found in.  This *must*
    //                be a filename passed into ISourceFileScanner::ScanSource.
    //   commentStartLine - The line number it was found at.
    //   declStartLine - ditto
    //   objectName - The name of the object
    //   subtype - The subtype of the object.  This subtype must be a member
    //             of the ISubtypeCollection associated with the source file
    //             scanner for sourceFile.
    //   inheritsFrom - The name of an object from which documentation can be
    //                  inherited from.
    //   declaration - The declaration of the object (from the source file)
    //   comment - The comment (with comment characters included) for the object.
    //   body - The declaration + implementation for the object
    //   attributes - An array of strings that specifies additional attributes
    //                for the object.  This is contains a series of pairs of
    //                strings (e.g. String(1..2)(1..n)], where each pair is
    //                an attribute name and an attribute value.
    //
    // Return Value:
    //   A reference to the object created
    //
    // Remarks:
    //   Note:  The parameters declStartLine and commentStartLine really should
    //          be given values according to their names (that is commentStartLine
    //          should be the line on which the comment started).  I really
    //          don't know why this lives on like this, as in practice nothing
    //          uses anything but declStartLine.  The idea was to be able to
    //          point out errors in comments on the line in the comment.
    //          In real life, that just isn't done, and it's unclear that it
    //          ever will be.
    [ id(60), helpcontext(1060),
      helpstring( "Creates a new IObject and adds it to the collection" ) ]
    HRESULT AddObject(
                [in]BSTR sourceFile,
                [in]LONG commentStartLine,
                [in]LONG declStartLine,
                [in]BSTR objectName,
                [in]ISubtype *subtype,
                [in]BSTR inheritsFrom,
                [in]BSTR declaration,
                [in]BSTR comment,
                [in]BSTR body,
                [in]SAFEARRAY(BSTR) *attributes,
                [out,retval]IObject **o );

    // Description:  Removes a particular object from a collection
    //
    // Arguments:
    //  o - A reference to an object to remove from the collection
    //
    [ id(61), helpcontext(1061),
      helpstring( "Removes an object from the collection" ) ]
    HRESULT RemoveObject( [in]IObject *o );

    // Description:  Iterates over every object in the collection
    //
    // Arguments:
    //  iterator - Implements the IHookIterator::DoIt method which gets called
    //             for each object in the collection.
    //  attr1 - The name of an extended attribute to pass into DoIt.
    //  attr2 - Another extended attribute.  These guys can be NULL.
    //  attr3 - Rounds out the trio.
    // 
    // Remarks:
    //  Note:  Three attributes seems like a good number.  It was just
    //         picked out of the air.  Perhaps you'll wish we had gone
    //         for four...  Hopefully not.
    //
    //  Note:  The iteration process is safe even if you change the collection
    //         in the middle.  That is, if your implementation of IHookIterator::DoIt
    //         calls RemoveObject on an item within this collection, that won't
    //         change the execution of Foreach.  It will still iterate through
    //         the same objects either way.  (Essentially, a copy of the
    //         collection is made before DoIt is called.)
    [ id(62), helpcontext(1062),
      helpstring( "Executes IHookIterator::DoIt for every member of the collection" ) ]
    HRESULT Foreach( [in]IHookIterator *iterator,
                     [in]BSTR attr1, [in]BSTR attr2, [in]BSTR attr3 );


    // Description:  Gives the number of objects in the collection
    //
    // Return Value:  The number of objects in the collection
    [ id(102), helpcontext(1102),
      helpstring( "Gets a count of the number of objects in the collection" ) ]
    HRESULT GetCount( [out,retval]ULONG *count );

    // Description:  Adds a single object to the collection
    //
    // Arguments:
    //  o - The object to add.
    //
    // Remarks:
    //   This function is the reciprocal of RemoveObject.
    [ id(103), helpcontext(1103),
      helpstring( "Adds an object to the collection" ) ]
    HRESULT Add( [in]IObject *o );

    // {secret}
    [ id(DISPID_NEWENUM), propget, restricted,
      helpstring( "Returns an IEnumVARIANT" ) ]
    HRESULT _NewEnum( [out,retval]IUnknown ** NewEnum );
};

// {group:Source File Scanning}
//
// Description:  Provides a handle to the error reporting mechanism
//
// Remarks:
//  This gets passed to all hooks and source file scanners so that they have
//  a central place to complain about stuff.  The implementation of this
//  fellow stores up all errors found and reports them in a sorted order
//  after all execution is complete.
[
    object,
    uuid(7C2F65B1-0E5F-11d4-A9EA-00D0B71B1994),
    /* dual, */
    helpstring("Handles any errors found in the source files"),
    helpcontext( 1119 ),
    pointer_default(unique)
]
interface IErrors : IDispatch {
    // Description:  The function for reporting errors
    //
    // Arguments:
    //  sourceFile - The file containing the bogus stuff
    //  lineNo - The line number
    //  errmsg - The error message (should not include sourceFile or lineNo,
    //           the generator will take care of that for you.)
    [ id(101), helpcontext(1101),
      helpstring( "This is how the source file scanners report errors" ) ]
    HRESULT SyntaxError( [in]BSTR sourceFile, [in]LONG lineNo,
                         [in]BSTR errmsg );
};


// {group:Rewriting Files and object Sets}
//
// Description:  A performant alternative for dealing with attributes that return
//               strings.
//
// Remarks:
//   Typically, we query an attribute on an object like so:
//
//        CComBSTR b;
//        o->get_MyAttr( &b );
//
//   While this is okay, it hides a performance problem:  the implementation of
//   get_MyAttr has to call SysAllocString to pass the value back, and then
//   the caller has to free that string with SysFreeString.  In older versions
//   of COM, this was an absolute performance disaster, as SysAllocString was
//   notoriosly slow.  In newer versions, it's not so bad, but in DocJet, where
//   some projects range into the tens of millions of objects, we still get into
//   some trouble here.
//
//   The really disappointing thing about this whole operation is that we know
//   that as long as o exists, the string will too, so we really would like
//   something akin to the old C++ gimick of:
//
//            CString m_MyAttr;
//            :
//            const char *MyAttr() { return m_MyAttr; }
//
//
//   Enter IWithString.  What's typically done with it is:
//
//          class CMyAttrWithString : public IWithString {
//            public:
//              BSTR MyAttr;
//
//              STDMETHOD(DoIt)( BSTR attr ) { MyAttr = attr; return S_OK; }
//          };
//
//
//  And then we use it to get an attribute via:
//
//          CMyAttrWithString ws;
//          o->WithMyAttr( &ws );
//          :
//          
//
//  Of course this is technically rather naughty, but there are some clean ways
//  to actually use this guy.  Most of the object design is done in such a way
//  that you won't have to use this thing very much.
[
    object,
    uuid(9F8DF64a-E96A-11d3-A999-00D0B71B1994),
    /* dual, */
    helpstring("A single object in a collection"),
    helpcontext( 1065 ),
    pointer_default(unique)
]
interface IWithString : IDispatch {
    // Description:  Called in response to a 'With' attribute request
    //
    // Arguments:
    //    s - The string value fetched.
    //
    // Remarks:
    //   See IWithString for details on what this method is for.
    [id(66), helpcontext(1066),
     helpstring("Execute a function given a certain string" ) ]
    HRESULT DoIt( [in]BSTR s );
};

// {group:Rewriting Files and object Sets}
//
// Description:  Used to iterate over the whole attribute collection
//
// Remarks:
//   This is a user-implemented object used basically as a callback for
//   IObject.WithAllAttributes.
[
    object,
    uuid(C84A8447-5FFB-11d4-AA71-00D0B71B1994),
    helpstring("Executed for each attribute pair"),
    helpcontext( 1120 ),
    pointer_default(unique)
]
interface IWithAttributePair : IDispatch {
    // Description:  Called in response to IObject.WithAllAttributes
    //
    // Arguments:
    //  attr -  The attribute's name
    //  value - The value currently assigned to the attribute
    //
    // Remarks:
    //   See IObject.WithAllAttributes.
    [id(121), helpcontext(1121),
     helpstring("Execute a function given an attribute/value pair" ) ]
    HRESULT DoIt( [in]BSTR attr, [in]BSTR value );
};


// {group:Source File Scanning}
//
// Description:  Interfaces with an object found in the source file set
//
// Remarks:
//   When a source file scanner finds something in a source file to document,
//   it calls IObjectCollection.AddObject.  As a result, an "object" is created
//   in the Generator and this interface to it is returned.  This, therefor, is
//   the view you get of objects in DocJet's internal database.
//
//   The methods of this object are mainly involved with getting and setting
//   attributes of the object, which were initially set up during the call
//   to AddObject.
[
    object,
    uuid(9F8DF649-E96A-11d3-A999-00D0B71B1994),
    /* dual, */
    helpstring("A single object in a collection"),
    helpcontext( 1063 ),
    pointer_default(unique)
]
interface IObject : IDispatch {
    // Description:  The file name that the object was found in
    //
    // Remarks:
    //   This is a read-only attribute.
    //
    //   DeclLine holds the line number it was found at.
    [propget, id(64), helpcontext(1064),
     helpstring("The source file that contains the object")]
    HRESULT SourceFile( [out,retval]BSTR *sfn );
    // Description:  A high-performance mechanism for getting the name of the object
    //
    // Arguments:
    //  p - A pointer to an implementation of IWithString.  The method IWithString::DoIt
    //      of p will be called with the source file name of this object as its argument.
    //
    // Remarks:
    //  See IWithString for a discussion of the performance implications.
    [id(67), helpcontext(1067),
     helpstring("Executes IWithString::DoIt with the source file name" ) ]
    HRESULT WithSourceFile( [in]IWithString *p );

    // Description:  Gets the line within the source file that the object was found on
    //
    // Remarks:
    //   This is a read-only attribute.
    //
    //   SourceFile gives you the source file name
    [propget, id(68), helpcontext(1068),
     helpstring("Gets the line that the object was found on") ]
    HRESULT DeclLine( [out,retval]ULONG *line );

    // Description:  The name of the object
    [propget, id(69), helpcontext(1069),
     helpstring("Gets the name of the object") ]
    HRESULT Name( [out,retval]BSTR *name );
    [propput,
     helpstring("Sets the name of the object") ]
    HRESULT Name( [in]BSTR name );

    // Description:  The object that owns the current object
    //
    // Remarks:
    //  The only time when you should set the owner for an object
    //  is if the current object is a parameter of an overloaded
    //  function.
    [propget, id(1152), helpcontext(1152),
     helpstring("The object that owns this object") ]
    HRESULT Owner( [out,retval]IObject **o );
    [propputref]
    HRESULT Owner( [in]IObject *o );


    // Description:  A high-performance mec