//////////////////////////////////////////////////////////////////////////////
//
//  Copyright 2025 Autodesk, Inc.  All rights reserved.
//
//  Use of this software is subject to the terms of the Autodesk license 
//  agreement provided at the time of installation or download, or which 
//  otherwise accompanies this software in either electronic or hard copy form.   
//
//////////////////////////////////////////////////////////////////////////////
#ifndef __BOMMGR_H
#define __BOMMGR_H
#include "AdAChar.h"

class AcmIterator;
class AcmDataDictionary;
class AcmCPartList;
class AcmBomReactor;

class AmiCompDefKey;
class AmiCompKey;


#pragma warning(push)
#pragma warning(disable : 4275)
///<summary>This class works much the same way that the standard manager works for standards. 
///It primarily gets the current BOM, list BOMs, and gets their names.</summary>
class ACMSYMBB_CRX_DLLSHARE AcmBOMManager : public AcRxService
{
public:
    ACRX_DECLARE_MEMBERS(AcmBOMManager);

    ///<summary>Creates a new BOM table for the specified target.</summary>
    ///<param name="aNewBomTableId">  </param>
    ///<param name="targetId">If targetId is kNull, then a Main BOM table is created.
    ///If targetId is a paper space Id, then the model space Id will be used as the target to created the BOM table</param>
    ///<param name="name">The name must be used and must not be an empty string or NULL. </param>
    ///<param name="addToBrowser">  </param>
    ///<param name="pHostDb">Indicates the database the function will operate on. Passing NULL means that the working database is used.</param>
    virtual Acad::ErrorStatus createBomTable(AcDbObjectId& aNewBomTableId,
                                             const AcDbObjectId targetId = AcDbObjectId::kNull,
                                             LPCTSTR name = NULL,
											                       bool addToBrowser = true,
                                             AcDbDatabase *pHostDb = NULL) = 0;

    ///<summary>Creates a new BOM table for the specified target.</summary>
    ///<param name="aNewBomTableId">  </param>
    ///<param name="pTargetKey"> </param>
    ///<param name="name">The name must be used and must not be an empty string or NULL.</param>
    virtual Acad::ErrorStatus createBomTable(AcDbObjectId& aNewBomTableId,
                                             const AmiCompDefKey* pTargetKey,
                                             LPCTSTR name = NULL) = 0;

    ///<summary>Creates a new BOM table for the specified borderId.</summary>
    ///<param name="borderId">If targetId is kNull, then a Main BOM table is created. </param>
    ///<param name="name">The name must be used and must not be an empty string or NULL. </param>
    ///<param name="populate"> </param>
    virtual Acad::ErrorStatus createBorderBomTable(AcDbObjectId& aNewBomTableId,
                                           const AcDbObjectId borderId,LPCTSTR name = NULL,bool populate = false) = 0;
    ///<summary>Removes the BOM table from the current drawing.</summary>
    virtual Acad::ErrorStatus removeBomTable(const AcDbObjectId& bomTableId) = 0;

    ///<summary>Returns the Id of the BOM table associated with the assembly (subassembly) present.</summary>
    ///<param name="name">The name will contain the BOM table name.</param>
    ///<param name="targetId">If targetId is kNull, then the main BOM table Id is returned.</param>
    ///<param name="pHostDb">Indicates the database the function will operate on. Passing NULL means that the working database is used.</param>
    virtual Acad::ErrorStatus getBomTable(AcDbObjectId& aBomTableId,CString& name,
                                          const AcDbObjectId& targetId,
                                          AcDbDatabase *pHostDb = NULL) const = 0;

    ///<summary>Returns the Id of the BOM table associated with the assembly (subassembly) present.</summary>
    ///<param name="name">The name will contain the BOM table name.</param>
    ///<param name="pTargetKey"> </param>
    virtual Acad::ErrorStatus getBomTable(AcDbObjectId& aBomTableId,CString& name,
                                       const AmiCompDefKey* pTargetKey) const = 0;

    ///<summary>Returns the Id of the BOM table associated with the assembly (subassembly) present.</summary>
    ///<param name="name">The name will contain the BOM table name.</param>
    ///<param name="aBomTableId"> </param>
    ///<param name="pDb">Indicates the database the function will operate on. Passing NULL means that the working database is used.</param>
    virtual Acad::ErrorStatus getBomTable(LPCTSTR name,AcDbObjectId& aBomTableId,AcDbDatabase *pDb=NULL) const = 0;

    ///<param name="pHostDb">Indicates the database the function will operate on. Passing NULL means that the working database is used.</param>
    virtual Acad::ErrorStatus getBOMIdByCompDef(const AcDbObjectId& cmpDefId, AcDbObjectId& bomId, AcDbDatabase *pHostDb = NULL) const = 0;

    ///<summary>Returns Id of the BOM Table associated with some borderId.</summary>
    ///<param name="name"> If table doesn't exist, it returns eKeyNotFound.The name will contain the BOM table name.</param>
    virtual Acad::ErrorStatus getBorderBomTable(AcDbObjectId& aBomTableId,CString& name,
                                       const AcDbObjectId& borderId) const = 0;

    ///<summary>Checks whether the BOM Table for the specified target exists.</summary>
    ///<param name="targetId">If targetId is kNull, then the main BOM table is checked.</param>
    ///<param name="pHostDb">Indicates the database the function will operate on. Passing NULL means that the working database is used.</param>
    ///<returns>If there is already a BOM Table, the eDuplicateEntry error code is returned.</returns>
    virtual Acad::ErrorStatus existBomTable(const AcDbObjectId& targetId = AcDbObjectId::kNull, AcDbDatabase *pHostDb = NULL) const = 0;

    ///<summary>Checks whether the BOM Table for the specified target exists.</summary>
    ///<returns>If there is already a BOM Table, the eDuplicateEntry error code is returned.</returns>
    virtual Acad::ErrorStatus existBomTable(const AmiCompDefKey* pTargetKey) const = 0;

    ///<summary>Checks whether the BOM Table for the specified target exists.</summary>
    ///<param name="pHostDb">Indicates the database the function will operate on. Passing NULL means that the working database is used. </param>
    ///<returns>If there is already a BOM Table, the eDuplicateEntry error code is returned.</returns>
    virtual Acad::ErrorStatus existBomTable(LPCTSTR name, AcDbDatabase *pHostDb = NULL) const = 0;

    ///<summary>Returns the list of all BOM tables in the current drawing and all xrefed drawings (if xrefInc is kTrue).
    ///If there is not table at all, it just returns
    ///Note that it is critical for the caller to understand that it is up to the
    ///caller responsibility to check the returned bomId.database() for any further action expecially with the ext-objectId
    ///Never ever try to dwgout the xrefed objectId! </summary>
    ///<param name="pHostDb">Indicates the database the function will operate on. 
	  ///Passing NULL means that the current host drawing is used.</param>
    virtual Acad::ErrorStatus getAllBomTables(AcDbObjectIdArray& array,
                                              Adesk::Boolean xrefed = Adesk::kFalse,
                                              AcDbDatabase *pHostDb = NULL) const = 0;

    ///<summary>Gets the current BOM table.</summary>
	  ///<param name="pDb">Indicates the database the function will operate on. 
	  ///Passing NULL means that the current host drawing is used.</param>
    virtual Acad::ErrorStatus getCurrentBom(AcDbObjectId& bomId,
                                            AcDbDatabase *pDb = NULL) const = 0;
    ///<summary>Specifies the current BOM, to be used for editing and querying purposes.</summary>
    virtual Acad::ErrorStatus setCurrentBomTarget(const AcDbObjectId& targetId) = 0;
    ///<summary>Specifies the current BOM, to be used for editing and querying purposes.</summary>
    virtual Acad::ErrorStatus setCurrentBomTarget(const AmiCompDefKey* pTargetKey) = 0;

    ///<summary>Specifies the current BOM, to be used for editing and querying purposes.</summary>
    ///<param name="addToBrowser">Indicates if the specified bom?s name should be added to the ambrowser. 
	  ///Default is to add to the browser.Indicates if the specified bom?s name should be added to the ambrowser. 
	  ///Default is to add to the browser.</param>
    ///<param name="pHostDb">Indicates the database the function will operate on. 
	  ///Passing NULL means that the current host drawing is used.</param>
    virtual Acad::ErrorStatus setCurrentBom(const AcDbObjectId& bomId, bool addToBrowser = true, AcDbDatabase * pHostDb = NULL) = 0;
    
    ///<summary>Specifies the current BOM, to be used for editing and querying purposes.</summary>
    ///<param name="addToBrowser">Indicates if the specified bom?s name should be added to the ambrowser. 
	  ///Default is to add to the browser.Indicates if the specified bom?s name should be added to the ambrowser. </param>
    ///<param name="pHostDb">Indicates the database the function will operate on. Passing NULL means that the current host drawing is used.</param>
    virtual Acad::ErrorStatus setCurrentBom(const CString& bomName, bool addToBrowser = true, AcDbDatabase * pHostDb = NULL) = 0;
    virtual void setInputBom(const CString& bomName)=0; 
    virtual void getInputBom(CString& bomName, AcDbObjectId& inputBomId)=0; 

    ///<summary>Gets the main data that describes the BOM table, such as name, material, 
    ///vendor, and so on, along with a list of other values.</summary>
    ///<param name="name">Specifies the BOM table name.</param>
    ///<returns>The function returns all actual values together with their names.</returns>
    virtual Acad::ErrorStatus getBomData(const AcDbObjectId& bomId,CString& name,
                                         CMapStringToString& valueMap) const = 0;

    ///<summary>Sets the main data that describes the BOM table, such as name, material, vendor, 
    ///and so on, along with a list of other values.
    ///all of the previous data will be removed and new data will be inserted. If it doesn't
    ///new data are created and initialized using valueMap. Data doesn't contain item number
    ///and number if items.</summary>
    ///<param name="bomId"></param>
    ///<param name="name">Specifies the BOM table name.</param>
    ///<param name="valueMap"></param>
    virtual Acad::ErrorStatus setBomData(const AcDbObjectId& bomId, LPCTSTR name,
                                         const CMapStringToString& valueMap) const = 0;

    ///<summary>Gets the BOM properties.such as expansion type, separator, and assembly path usage,
    ///associated sheet IDs, associatd Target ID.</summary>
    virtual Acad::ErrorStatus getBomProperties(const AcDbObjectId& bomId,
                                                bool& isStructuralyExpanded, // true - structural, false - expanded
                                                bool& isUsingAssmPath,       // true - 1-2, false 2.
                                                CString& structSeparator,    // separator - default is "-"
                                                AcDbObjectIdArray& assocLayoutIds, // which layouts allows to create parts list from this BOM
                                                AcDbObjectId& targetId       // associated target
                                                ) const = 0;

    ///<summary>Sets the BOM table properties, such as expansion type, separator, and assembly path usage,
    ///associated sheet IDs, associated border ID. You cannot use this method to change associatd Target ID.
    ///use createBomTable instead.
    ///he method return eOk, if everything is Ok, otherwise error status of inherit operation (enotOpen...)
    ///If parts lists and balloons will be regenerated, regen is set ot true, otherwise it is false.</summary>
    virtual Acad::ErrorStatus setBomProperties(const AcDbObjectId& bomId,
                                                bool isStructuralyExpanded, // true - structural, false - expanded
                                                bool isUsingAssmPath,       // true - 1-2, false 2.
                                                LPCTSTR structSeparator,    // separator - default is "-"
                                                AcDbObjectIdArray assocLayoutIds, // which layouts allows to create parts list from this BOM
                                                bool& regen
                                              ) const = 0;

    ///<summary>Sorts the items in the BOM table.
    ///Use Iterator and set the sorting priority to each item
    ///you like to change the sort order. Than call this method to update aprts lists.
    ///AMBOM dialog and Parts List dialog do this automatically, so you do not need to
    ///call it, if it will be called later</summary>
    virtual Acad::ErrorStatus applySort(const AcDbObjectId& bomId) const = 0;


    ///<summary>Get all partrefs in the specific database. NULL for workingdatabase.
    ///This API return the ids of all the partrefs in the specific database,
    ///including the partrefs in MAIN , border bom, and in the xref dwg files.
    ///The method returns eOk if succeeds otherwise return error status.</summary>
    virtual Acad::ErrorStatus getPartRefs(AcDbObjectIdArray& partRefs,
                                          AcDbDatabase *pDb = NULL) const = 0;


    ///<summary>Creates a new BOM iterator.</summary>
    ///<param name="sort">Specifies whether to take the current sort state or not. 
	///If not, the items are sorted in the same order as created.</param>
    ///<param name="expanded">Specifies if it will include expanded (shaded in dialog) items as well.
	///Specifies if it will include expanded (shaded in dialog) items as well.</param>
    virtual AcmIterator* newItemIterator(const AcDbObjectId& bomId,
                                         Acm::PartListDirection sort =Acm::kTopDown,
                                         Adesk::Boolean expanded = Adesk::kFalse) const = 0;
    ///<summary>Creates a new BOM iterator.</summary>
    ///<param name="pSymb"></param>
    ///<param name="expanded">Specifies if it will include expanded (shaded in dialog) items as well.
	///Specifies if it will include expanded (shaded in dialog) items as well.</param>
    virtual AcmIterator* newItemIterator(const AcDbObjectId& bomId,
                                         const AcmCPartList* pSymb,
                                         Adesk::Boolean expanded = Adesk::kFalse) const = 0;

    ///<summary>Returns list of parts lists associated with the BOM table.</summary>
    ///<param name="partsListIdArray">Specifies the BOM table name.</param>
    virtual Acad::ErrorStatus getBomPartsLists(const AcDbObjectId& bomId,
                                              AcDbObjectIdArray& partsListIdArray) const = 0;

    ///<summary>Creates part data for the specified part.If the Part has already associated data,
    ///it returns eAlreadyInDb. The Part data will be initialized using valueMap.
    ///Part data doesn't contain item number. Number of items is initialized when the reference
    ///to the part is created.</summary>
    virtual Acad::ErrorStatus createPartData( const AcDbObjectId& partId,
                                              const CMapStringToString& valueMap) const = 0;

    ///<summary>Checks whether the part reference is one of the known types of 
    ///isKindOf(AcDbBlockReference or AcDbPartRef). Otherwise, this function returns eIllegalEntityType.
    ///If part reference has DataEntry associated, it will return
    ///all actual values together with thir names, otherwise returns eKeyNotFound.
    ///Part data doesn't contain item number. Number of items returned is associated to the part reference only.</summary>
    virtual Acad::ErrorStatus getPartData(const AcDbObjectId& referenceId,
                                          Adesk::UInt32& numOfItems,          // number of items
                                          CMapStringToString& valueMap) const = 0;

    ///<summary>Checks whether the part reference is one of the known types of 
    ///isKindOf(AcDbBlockReference or AcDbPartRef). Otherwise, this function returns eIllegalEntityType.</summary>
    virtual Acad::ErrorStatus getPartData(const AmiCompKey*  pCompKey,
                                          Adesk::UInt32& numOfItems,          // number of items
                                          CMapStringToString& valueMap) const = 0;

    ///<summary>Checks whether the part reference is one of the known types of 
    ///isKindOf(AcDbBlockReference or AcDbPartRef). Otherwise, this function returns eIllegalEntityType.</summary>
    virtual Acad::ErrorStatus getPartData(const AcDbObjectId& partId,
                                          CMapStringToString& valueMap) const = 0;

    ///<summary>Sets the BOM data for the specified reference to a part.If the part has already associated data,
    ///all of the previous data will be removed and new data will be inserted. If it doesn't
    ///have bom data associated, new data is created and initialized using valueMap.
    ///Part data doesn't contain item number. Number of items is initialozed to 1 by default and
    ///is stored on per reference basis.</summary>
    virtual Acad::ErrorStatus setPartData(const AcDbObjectId& referenceId,
                                          Adesk::UInt32 numOfItems,           // number of items
                                          const CMapStringToString& valueMap,
                                          Adesk::Boolean = Adesk::kFalse) const = 0;

    ///<summary>Sets the BOM data for the specified reference to a part.</summary>
    virtual Acad::ErrorStatus setPartData(const AmiCompKey* pCompKey,
                                          Adesk::UInt32 numOfItems,           // number of items
                                          const CMapStringToString& valueMap,
                                          Adesk::Boolean = Adesk::kFalse) const = 0;

    ///<summary>Sets the BOM data for the specified reference to a part.</summary>
    virtual Acad::ErrorStatus setPartData(const AcDbObjectId& partId,
                                          const CMapStringToString& valueMap) const = 0;

    ///<summary>Creates a new BOM iterator for the specified reference to a part.</summary>
    ///<param name="mainOnly">If mainOnly is true, then only data associated with any BOM table will be returned.</param>
    ///<param name="pHostDb">Indicates the database the function will operate on. Passing NULL means that the current host drawing is used.</param>
    virtual AcmIterator* newPartDataIterator(Adesk::Boolean mainOnly = Adesk::kFalse,
                                             Adesk::Boolean noXref = Adesk::kTrue,
                                             AcDbDatabase *pHostDb = NULL) const = 0;

    ///<summary>Checks whether reference Id has BOM data associated with it. If yes,
    ///this function creates a new item in the current BOM table and associates the reference with the row.
    ///If no, eKeyNotFound is returned.</summary>
    ///<param name="itemId"></param>
    ///<param name="bomId"></param>
    ///<param name="refIdArray"></param>
    ///<param name="itemNo">If the itemNo string is used, its value is used to initialize the item 
    ///number for the created row. If NULL or an empty value is used, the function finds the last one 
    ///and initializes the new item with last+1. If the number of items is the default, the BOM table 
    ///will try to determine the actual number of items. Otherwise it will use the specified value and 
    ///let the user determine the number of items.</param>
    virtual Acad::ErrorStatus createItem(AcDbObjectId& itemId,            // created item
                                         const AcDbObjectId& bomId,
                                         const AcDbObjectIdArray& refIdArray, // reference to a part
                                         LPCTSTR itemNo) const = 0;   // initial number of items

    ///<summary>Checks whether reference Id has BOM data associated with it. If yes, this function 
    ///creates a new item in the current BOM table and associates the reference with the row. 
    ///If no, eKeyNotFound is returned.</summary>
    ///<param name="itemId"></param>
    ///<param name="bomId"></param>
    ///<param name="pCompKey"></param>
    ///<param name="itemNo">If the itemNo string is used, its value is used to initialize the item number 
    ///for the created row. If NULL or an empty value is used, the function finds the last one and initializes
    ///the new item with last+1. If the number of items is the default, the BOM table will try to determine the 
    ///actual number of items. Otherwise it will use the specified value and let the user determine 
    ///the number of items.</param>
    virtual Acad::ErrorStatus createItem(AcDbObjectId& itemId,            // created item
                                         const AcDbObjectId& bomId,
                                         const AmiCompKey* pCompKey, // reference to a part
                                         LPCTSTR itemNo) const = 0;   // initial number of items

    ///<summary>Checks whether reference Id has BOM data associated with it. If yes, this function creates a 
    ///new item in the current BOM table and associates the reference with the row.
    ///If no, eKeyNotFound is returned.</summary>
    ///<param name="itemId"></param>
    ///<param name="bomId"></param>
    ///<param name="numOfItems"></param>
    ///<param name="itemNo">If the itemNo string is used, its value is used to initialize the item number for
    ///the created row. If NULL or an empty value is used, the function finds the last one and initializes the
    ///new item with last+1. If the number of items is the default, the BOM table will try to determine the actual 
    ///number of items. Otherwise it will use the specified value and let the user determine the number of items.</param>
    ///<param name="valueMap">It can contain any amount of data, similar to setBomPartData.</param>
    virtual Acad::ErrorStatus createItem(AcDbObjectId& itemId,            // created item
                                         const AcDbObjectId& bomId,
                                         LPCTSTR itemNo,                  // item number
                                         Adesk::UInt32 numOfItems,        // number of items
                                         const CMapStringToString& valueMap) const = 0;   // other values to initialize bom data

    ///<summary>Sets Item values - item number and num of items are specific to this item, other data (valueMap) are shared
    /// used to create bom table. If the map contains unknown entries, (doesn't match to any column defined in bom standard),
    /// it is stripped from the map.
    /// If user try to call setItemData on expanded item, it returs eInvalidContext.
    /// If user try to set the number of items (other than -1), which is calculated automatically,
    /// it returns eInvalidData</summary>
    ///<param name="valueMap">It contains the column name of the pair and is checked against the current BOM standard.</param>
    virtual Acad::ErrorStatus setItemData(const AcDbObjectId& itemId,
                                          LPCTSTR itemNo,                  // item number
                                          Adesk::UInt32 numOfItems,        // number of items
                                          const CMapStringToString& valueMap) const = 0;

    ///<summary>Gets Item values - item number and quantity are specific to this item, other data (valueMap) 
    ///are shared with other BOM tables as well.</summary>
    ///<param name="itemId"></param>
    ///<param name="itemNo"></param>
    ///<param name="numOfItems"></param>
    ///<param name="valueMap">It contains pairs of column's name and value. It is created using the current
    ///BOM standard, so it contains only those values that match the BOM table's column definitions.</param>
    ///<param name="bomStdId">The standard Id is necessary to get correct default formulas, which are stored 
    ///in the BOM standard. These are then evaluated and the result is returned in valueMap.</param>
    virtual Acad::ErrorStatus getItemData(const AcDbObjectId& itemId,
                                          CString& itemNo,
                                          Adesk::UInt32& numOfItems,
                                          CMapStringToString& valueMap,
                                          const AcDbObjectId& bomStdId=AcDbObjectId::kNull)const = 0;

    ///<param name="itemId">It is identical to getItemData.</param>
    ///<param name="itemNo">It is identical to getItemData.</param>
    ///<param name="numOfItems">It is identical to getItemData.</param>
    ///<param name="valueMap">It is identical to getItemData.</param>
    ///<param name="bomStdId">The standard Id is necessary to get correct default formulas, which are stored in 
    ///the BOM standard. These are then evaluated and the result is returned in valueMap.</param>
    virtual Acad::ErrorStatus getItemRawData(const AcDbObjectId& itemId,
                                             CString& itemNo,
                                             Adesk::UInt32& numOfItems,
                                             CMapStringToString& valueMap,
                                             const AcDbObjectId& bomStdId=AcDbObjectId::kNull)const = 0;

    ///<summary>Gets Item values - item number and quantity are specific to this item, other data (valueMap) are
    ///shared with other BOM tables as well.</summary>
    ///<param name="refId"></param>
    ///<param name="bomId"></param>
    ///<param name="itemId">It is identical to getItemData.</param>
    ///<param name="itemNo">It is identical to getItemData.</param>
    ///<param name="numOfItems">It is identical to getItemData.</param>
    ///<param name="valueMap">It is identical to getItemData.</param>
    ///<param name="bomStdId">The standard Id is necessary to get correct default formulas, which are stored in 
    ///the BOM standard. These are then evaluated and the result is returned in valueMap.</param>
    virtual Acad::ErrorStatus getItemData(const AcDbObjectId& refId,
                                          const AcDbObjectId& bomId,
                                          AcDbObjectId& itemId,
                                          CString& itemNo,
                                          Adesk::UInt32& numOfItems,
                                          CMapStringToString& valueMap,
                                          const AcDbObjectId& bomStdId=AcDbObjectId::kNull)const = 0;

    ///<summary>Gets Item values - item number and quantity are specific to this item, other data (valueMap) are
    ///shared with other BOM tables as well.</summary>
    ///<param name="pCompKey"></param>
    ///<param name="bomId"></param>
    ///<param name="itemId">It is identical to getItemData.</param>
    ///<param name="itemNo">It is identical to getItemData.</param>
    ///<param name="numOfItems">It is identical to getItemData.</param>
    ///<param name="valueMap">It is identical to getItemData.</param>
    ///<param name="bomStdId">The standard Id is necessary to get correct default formulas, which are stored in
    ///the BOM standard. These are then evaluated and the result is returned in valueMap.</param>
    virtual Acad::ErrorStatus getItemData(const AmiCompKey* pCompKey,
                                          const AcDbObjectId& bomId,
                                          AcDbObjectId& itemId,
                                          CString& itemNo,
                                          Adesk::UInt32& numOfItems,
                                          CMapStringToString& valueMap,
                                          const AcDbObjectId& bomStdId=AcDbObjectId::kNull)const = 0;
    virtual Acad::ErrorStatus getBlockData(const AcDbObjectId& blockId,          
                                           AcDbObjectId& bomRowId,               
                                           AcDbObjectId& dataEntryId) const = 0; 
    virtual Acad::ErrorStatus getBlockData(const AcDbObjectId& blockId,             
                                           CString& itemNo,                         
                                           Adesk::UInt32& numOfItems,               
                                           CMapStringToString& valueMap) const = 0; 

    ///<summary>Returns the status of the item.</summary>
    ///<param name="isAutoCalcEnabled">Specifies whether to calculate the quantity for the specified item.</param>
    ///<param name="isExpanded">Specifies the information about the current expansion status of the item.</param>
    ///<param name="isExpandable">Specifies whether it is possible to expand the item.</param>
    virtual Acad::ErrorStatus getItemStatus(const AcDbObjectId& itemId,
                                            Adesk::Boolean& isAutoCalcEnabled,
                                            Adesk::Boolean& isExpanded,             // true only if isExpandable is true
                                            Adesk::Boolean& isExpandable) const =0; // true if bom table for part exists

    ///<summary>Sets the autoCalc status for item.</summary>
    ///<param name="isAutoCalcEnabled">Specifies whether to calculate the quantity for the specified item.</param>
    virtual Acad::ErrorStatus setAutoCalc(const AcDbObjectId& rowId,
                                          Adesk::Boolean isAutoCalcEnabled) const =0;

    ///<summary>Expands or collapses the item to include or exclude inherited items from the subassembly.
    ///If the item cannot be expanded,it returns eNotApplicable. If the operation couldn't be finished succesfully, no item
    ///is added. After this operation,the isExpanded status will change for current Item.</summary>
    ///<param name="expand">Specifies whether to calculate the quantity for the specified item.</param>
    virtual Acad::ErrorStatus expandItem(const AcDbObjectId& itemId,
                                         Adesk::Boolean expand = Adesk::kTrue) const = 0;

    ///<param name="">Adds a graphical definition to represent the same part. Both definitions will
    ///use the same data, for example front view and bottom view of the same part.</param>
    virtual Acad::ErrorStatus addPartGrfDef(const AcDbObjectId& referenceId,
                                            const AcDbObjectId& newGrfDefId) const = 0;

    ///<summary>Removes the graphical definition of the part. This graphical definition will no longer 
    ///represent the part.It will find which Bom data is associated it and
    /// than removes its definition. If the definition is referenced, references will be removed
    /// as well.</summary>
    virtual Acad::ErrorStatus removePartGrfDef(const AcDbObjectId& referenceId) const = 0;

    ///<summary>Returns a list of all references to the same part, together with the number of items. 
    ///As the input parameter, you can use any of the part references.</summary>
    virtual Acad::ErrorStatus getPartGrfDefs(const AcDbObjectId& referenceId,
                                             AcDbObjectIdArray& refIdArray,
                                             AcDbIntArray& numOfItAr) const = 0;

    ///<summary>Adds a reference to the item. The reference is validated before it is appended. 
    ///If the reference is BlockReference, then its BlockTableRecord has to be associated with the BOM data.</summary>
    virtual Acad::ErrorStatus addItemReference(const AcDbObjectId& itemId,
                                               const AcDbObjectIdArray& refIdArray) const = 0;
    ///<summary>Adds a reference to the item. The reference is validated before it is appended. 
    ///If the reference is BlockReference, then its BlockTableRecord has to be associated with the BOM data.</summary>
    virtual Acad::ErrorStatus addItemReference(const AcDbObjectId& itemId,
                                               const AmiCompKey* pCompKey) const = 0;
    ///<summary>Checks to determine whether the specified item reference exists.</summary>
    virtual Adesk::Boolean existItemReference(const AcDbObjectId& itemId,
                                              const AcDbObjectIdArray& refIdArray) const = 0;
    ///<summary>Checks to determine whether the specified item reference exists.</summary>
    virtual Adesk::Boolean existItemReference(const AcDbObjectId& itemId,
                                              const AmiCompKey* pCompKey) const = 0;
    ///<summary>Removes the reference to this item. If the reference has any balloons associated with it, 
    ///they will be erased as well.</summary>
    virtual Acad::ErrorStatus removeItemReference(const AcDbObjectId& itemId,
                                                  const AcDbObjectIdArray& refIdArray) const = 0;
    ///<summary>Removes the reference to this item. If the reference has any balloons associated with it,
    ///they will be erased as well.</summary>
    virtual Acad::ErrorStatus removeItemReference(const AcDbObjectId& itemId,
                                                  const AmiCompKey* pCompKey) const = 0;
    ///<summary>Returns a list of reference to the item, together with the number of items in the list.</summary>
    virtual Acad::ErrorStatus getItemReferences(const AcDbObjectId& itemId,
                                                AcmCObjArray<AcDbObjectIdArray>& referenceArray,
                                                AcDbIntArray& numItemArray) const = 0;

    ///<summary>Returns a list of reference to the item, together with the number of items in the list.</summary>
    virtual Acad::ErrorStatus getItemReferences(const AcDbObjectId& itemId,
                                                AcmCObjPtrArray<AmiCompKey>& referenceArray,
                                                AcDbIntArray& numItemArray) const = 0;

    ///<summary>Returns a list of balloons associated with the item (and references).</summary>
    ///<param name="itemId">Input only. Specifies the BOM row item.</param>
    ///<param name="ballIdArray">Output only. Returns an array of object ids representing the balloons.</param>
    ///<param name="refIds">Input only. Specifies an array of part reference object ids.</param>
    virtual Acad::ErrorStatus getItemBalloons(const AcDbObjectId& itemId,
                                              AcDbObjectIdArray& ballIdArray,
                                              const AcDbObjectId& refId) const = 0;

    ///<summary>Returns a list of balloons associated with the item (and references).</summary>
    ///<param name="itemId">Input only. Specifies the BOM row item.</param>
    ///<param name="ballIdArray">Output only. Returns an array of object ids representing the balloons.</param>
    ///<param name="refIds">Input only. Specifies an array of part reference object ids.</param>
    virtual Acad::ErrorStatus getItemBalloons(const AcDbObjectId& itemId,
                                              AcDbObjectIdArray& ballIdArray,
                                              const AcDbObjectIdArray& refIds) const = 0;

	///<summary>Returns the id of the BOM table associated with given paper sheet Id.</summary>
    virtual AcDbObjectId sheetBomTable(const AcDbObjectId& sheetId) const = 0;

    ///<summary>Sets the sheet Id to be associated with the given BOM table.</summary>
    virtual bool setSheetBomTable(const AcDbObjectId& sheetId,const AcDbObjectId& bomId) const = 0;

	  /// reactor methods
    ///<summary>Attaches the BOM reactor. This reactor is then used to monitor changes being made to BOM data,
    ///items, part lists, and balloons.</summary>
    virtual void attachBomReactor(AcmBomReactor* pReactor) = 0;
    ///<summary>Detaches the BOM reactor.</summary>
    virtual void removeBomReactor(AcmBomReactor* pReactor) = 0;

    ///<summary>Highlights parts and their pick objects the same way as in the running product.</summary>
    virtual bool selectBomEntity(AcDbObjectIdArray& subentPath,const bool intoNested=false) = 0;
	  ///<param name="pHostDb">Indicates the database the function will operate on. Passing NULL means that the current 
    ///host drawing is used.</param>
    virtual void activateMainCache(AcDbDatabase *pHostDb = NULL) = 0;
	  ///<param name="pHostDb">Indicates the database the function will operate on. Passing NULL means that the current 
    ///host drawing is used.</param>
    virtual void deactivateMainCache(AcDbDatabase *pHostDb = NULL) = 0;

  
   enum ExportBOMType{ 
       ///<summary>Current Microsoft Access.</summary>
       eEXPORT_MDB = 1, 
	     ///<summary>Microsoft Access 97</summary>
       eEXPORT_MDB97, 
	     ///<summary>Microsoft Excel 97</summary>
       eEXPORT_EXCEL97, 
	     ///<summary>Microsoft Excel 95</summary>
       eEXPORT_EXCEL95, 
	     ///<summary>dBase 5</summary>
       eEXPORT_DB5,
	     ///<summary>dBase IV</summary>     
       eEXPORT_DBIV, 
	     ///<summary>dBase III</summary>
       eEXPORT_DBIII,
	     ///<summary>Microsoft Visual Foxpro 3.0</summary>
       eEXPORT_FOXVIS,
	     ///<summary>Microsoft Foxpro 2.6</summary>
       eEXPORT_FOX26,
	     ///<summary>Microsoft Foxpro 2.5</summary>
       eEXPORT_FOX25, 
       ///<summary>Format text separated with tabulator</summary>             
       eEXPORT_TXT, 
	     ///<summary>Format text separated with semicolon</summary>
       eEXPORT_CSV, 
	     ///<summary>HTML export</summary>
       eEXPORT_HTML,
	     ///<summary>The all-inclusive file filter "*.*"</summary>
       eEXPORT_ALLFILE };

    ///<summary>Exports BOM table to a specific format.</summary>
    ///<param name="format">Input only. Specifies one of the enumerated export formats defined.</param>
    ///<param name="bomId">Input only. Specifies the bom table to export.</param>
    ///<param name="path">Input only. Specifies the full path of the exported file.</param>
    ///<param name="tableName">Input only. Specifies the table name in the database of the exported file 
    ///(applicable only to Microsoft Access and Excel formats).</param>
    ///<param name="overwrite">Input only. Specifies whether to overwrite table of the same tableName if 
    ///already exists.</param>
    virtual Acad::ErrorStatus exportBOM(ExportBOMType format,
                                        const AcDbObjectId& bomId,                                     
                                        LPCTSTR path,                                  
                                        LPCTSTR tableName,
                                        bool overwrite) const = 0;

    ///<summary>Exports Part List to a specific format.</summary>
    ///<param name="format">Input only. Specifies one of the enumerated export formats defined.</param>
    ///<param name="partlistId">Input only. Specifies the part list to export.</param>
    ///<param name="path">Input only. Specifies the full path of the exported file.</param>
    ///<param name="tableName">Input only. Specifies the table name in the database of the exported file
	  ///(applicable only to Microsoft Access and Excel formats).</param>
    ///<param name="overwrite">Input only. Specifies whether to overwrite table of the same tableName if 
    ///already exists.</param>
    virtual Acad::ErrorStatus exportPartlist(ExportBOMType format,
                                             const AcDbObjectId& partlistId,
                                             LPCTSTR path,                                  
                                             LPCTSTR tableName,
                                             bool overwrite) const = 0;
	  ///<summary>Expresses the formats that are used to import BOM table and Part List.</summary>
    enum ImportBOMType{
        ///<summary>Current Microsoft Access</summary>
        eIMPORT_MDB = 1, 
        ///<summary>Microsoft Excel 97</summary>
        eIMPORT_EXCEL97, 
        ///<summary>Microsoft Excel 95</summary>
        eIMPORT_EXCEL95,
        ///<summary>dBase 5</summary>
        eIMPORT_DB5, 
        ///<summary>dBase IV </summary>
        eIMPORT_DBIV,
        ///<summary>dBase III</summary>    
        eIMPORT_DBIII, 
        ///<summary>Microsoft Visual Foxpro 3.0</summary>
        eIMPORT_FOXVIS, 
        ///<summary>Microsoft Foxpro 2.6</summary>
        eIMPORT_FOX26, 
        ///<summary>Microsoft Foxpro 2.5</summary>
        eIMPORT_FOX25, 
        ///<summary>Format text separated with tabulator</summary>
        eIMPORT_TXT,
        ///<summary>Format text separated with semicolon</summary>               
        eIMPORT_CSV };

        ///<summary>Imports a file of a specific format into a BOM table.</summary>
        ///<param name="format">Input only. Specifies one of the enumerated export formats defined.</param>
        ///<param name="bomId">Input only. Specifies the bom table to store the imported data.</param>
        ///<param name="path">Input only. Specifies the full path of the imported file.</param>
        ///<param name="tableName">Input only. Specifies the table name in the database of the imported file
        ///(applicable only to Microsoft Access and Excel formats).</param>
        ///<param name="overwrite">Input only. Specifies whether to overwrite the existing BOM items.</param>
    virtual Acad::ErrorStatus importBOM(ImportBOMType format,
                                        const AcDbObjectId& bomId,                                      
                                        LPCTSTR path,                                  
                                        LPCTSTR tableName,
                                        bool overwrite) = 0;

    ///<summary>Imports a file of a specific format into a Part List.</summary>
    ///<param name="format">Input only. Specifies one of the enumerated export formats defined.</param>
    ///<param name="partlistId">Input only. Specifies the Part List to store the imported data.</param>
    ///<param name="path">Input only. Specifies the full path of the imported file.</param>
    ///<param name="tableName">Input only. Specifies the table name in the database of the imported file 
    ///(applicable only to Microsoft Access and Excel formats).</param>
    ///<param name="overwrite">Input only. Specifies whether to overwrite the existing BOM items.</param>
    virtual Acad::ErrorStatus importPartlist(ImportBOMType format,                                     
                                             const AcDbObjectId& partlistId,
                                             LPCTSTR path,                                  
                                             LPCTSTR tableName,
                                             bool overwrite) = 0;

    ///<summary>Gets the child BOM items of a specific BOM item.</summary>
    ///<param name="itemId">Input only. Specifies the BOM row parent item.</param>
    ///<param name="childItemIds">Output only. Returns the children items of parent item.</param>
    virtual Acad::ErrorStatus getStructuredChildItems(const AcDbObjectId& itemId,
                                                      AcDbObjectIdArray& childItemIds,
                                                      bool skipPhantom = true) const = 0;

    ///<summary>Gets the parent BOM items of a specific BOM item.</summary>
    ///<param name="itemId">Input only. Specifies the BOM row parent item.</param>
    ///<param name="parentItemId">Output only. Returns the parent item.</param>
    virtual Acad::ErrorStatus getStructuredParentItem(const AcDbObjectId& itemId,
                                                      AcDbObjectId& parentItemId,
                                                      bool skipPhantom = true) const = 0;

    ///<summary>Describes the functionality of this enumerated type.</summary>
    enum ItemType{ 
        ///<summary>Unknown definition.</summary>
        eUnknown, 
        ///<summary>User-defined BOM item.</summary>
        eNonModal, 
        ///<summary>Part's definition is ACM Part Reference.</summary>
        ePartRef, 
        ///<summary>Part's definition is Block Definition.</summary>
        eBlockDef, 
        ///<summary>Part's definition is ACM/MDT Component Definition.</summary>
        eCompDef };
	///<summary> getItemPartDefinition </summary>
    ///<param name="itemId">Input only. Specifies the bom row item.</param>
    ///<param name="defIds">Output only. Array of object id representing the definition.</param>
    ///<param name="itemType">Output only. The type of the definition.</param>
    virtual Acad::ErrorStatus getItemPartDefinition(const AcDbObjectId& itemId, 
      AcDbObjectIdArray& defIds, 
      ItemType& itemType) const = 0;

    ///<summary>This is an enhanced version of the current getPartData(partId, valueMap) API which returns the
    ///valueMap with evaluated data and also return an extra parameter for the no. of items. Evaluation of the 
    ///data is based on the bomStdId passed in. If the partId is a data entry id, numOfItems is not applicable.</summary>
    ///<param name="partId">Input only. Specifies the part id or data entry id.</param>
    ///<param name="numOfItems">Output only. Specifies quantity of of this part.</param>
    ///<param name="valueMap">Output only. Returns the map of keys and property attributes of this part.</param>
    ///<param name="bomStdId">Input only. Specifies the BOM standard id.</param>
    virtual Acad::ErrorStatus getEvaluatedPartData(const AcDbObjectId& partId,
                                                   Adesk::UInt32& numOfItems,
                                                   CMapStringToString& valueMap,
                                                   const AcDbObjectId& bomStdId=AcDbObjectId::kNull) const = 0;

    ///<summary>This is an equivalence of the current getPartData(partId, valueMap) API which returns the attribute 
    ///of a given key.</summary>
    ///<param name="partId">Input only. Specifies the part id or data entry id.</param>
    ///<param name="key">Input only. Specifies the attribute key.</param>
    ///<param name="attrib">Output only. Returns the attribute.</param>
    virtual Acad::ErrorStatus getPartAttribute(const AcDbObjectId& partId,
                                               const CString& key,
                                               CString& attrib,
                                               bool evaluate = true,
                                               const AcDbObjectId& bomStdId=AcDbObjectId::kNull) const = 0;

    ///<summary>This is an equivalence of the current setPartData(partId, valueMap) API which sets the attribute 
    ///of a given key.</summary>
    ///<param name="partId">Input only. Specifies the part id or data entry id.</param>
    ///<param name="key">Input only. Specifies the attribute key.</param>
    ///<param name="attrib">Input only. Specifies the attribute value.</param>
    virtual Acad::ErrorStatus setPartAttribute(const AcDbObjectId& partId,
                                               LPCTSTR key,
                                               LPCTSTR attrib) = 0;

    ///<summary>This is an equivalence of the current getItemData(itemId,itemNo,numOfItems,valueMap) API 
    ///which returns the attribute of a given key.</summary>
    ///<param name="itemId">Input only. Specifies the part id or data entry id.</param>
    ///<param name="key">Input only. Specifies the attribute key.</param>
    ///<param name="attrib">Output only. Returns the attribute.</param>
    virtual Acad::ErrorStatus getItemAttribute(const AcDbObjectId& itemId,
                                               const CString& key,
                                               CString& attrib,
                                               bool evaluate = true,
                                               const AcDbObjectId& bomStdId=AcDbObjectId::kNull) const = 0;

    ///<summary>This is an equivalence of the current getItemData(itemId,itemNo,numOfItems,valueMap) API 
    ///which sets the attribute value for a given key.</summary>
    ///<param name="itemId">Input only. Specifies the BOM row item.</param>
    ///<param name="key">Input only. Specifies the attribute key.</param>
    ///<param name="attrib">Input only. Specifies the attribute value.</param>
    virtual Acad::ErrorStatus setItemAttribute(const AcDbObjectId& itemId,
                                               LPCTSTR key,
                                               LPCTSTR attrib) = 0;

    ///<summary>This sets the predefined list value for the bom item with the specified attribute key.</summary>
    ///<param name="itemId">Specifies the bom row item.</param>
    ///<param name="key">Specifies the attribute key. This column must be associated with a predefined list.</param>
    ///<param name="preDefListValue">The specific value within the predefined list to set to. This value must be a
    ///valid key in the predefined list.</param>
    virtual Acm::ErrorStatus setItemPreDefinedListValue(const AcDbObjectId& itemId,
                                                        const ACHAR* key,
                                                        const ACHAR* preDefListValue) = 0;

    ///<summary>This sets the predefined list value for the part with the specified attribute key.</summary>
    ///<param name="partId">Specifies the bom row item.</param>
    ///<param name="key">Specifies the attribute key. This column must be associated with a predefined list.</param>
    ///<param name="preDefListValue">The specific value within the predefined list to set to. This value must be a 
    ///valid key in the predefined list.</param>
    virtual Acm::ErrorStatus setPartPreDefinedListValue(const AcDbObjectId& partId,
                                                        const ACHAR* key,
                                                        const ACHAR* preDefListValue) = 0;

    ///<summary>Gets the calculated quantity associated with a BOM row item irregardless of the AutoCalc flag.</summary>
    ///<param name="itemId">Specifies the bom row item.</param>
    ///<param name="numOfItems">Output only. Returns the number of items accounting for reference quantity as seen
    ///from BOM dialog box.</param>
    ///<param name="numOfItemsIgnoreRefQty">Output only. Returns the number of items not accounting for reference
    ///quantity, that is, instance reference quantity not included.</param>
    virtual Acad::ErrorStatus getCalculatedItemCount(const AcDbObjectId& itemId,
                                                     Adesk::UInt32& numOfItems,
                                                     Adesk::UInt32& numOfItemsIgnoreRefQty) const = 0;
	///<summary>Expresses the BOM row item extended data type.</summary>
    enum ItemDataType{ 
        ///<summary>BOM row item phantom states</summary>
        ePhantomState,
        ///<summary>BOM row item exclude-from-partlist states</summary>
        eExcludeFromPartlistState };

	///<summary>Gets whether a specific data is associated with a specific BOM item.</summary>
    ///<param name="itemId">Input only. Specifies the BOM row item.</param>
    ///<param name="dataType">Input only. Specifies one of the item data type defined.</param>
    ///<param name="data">Output only. Returns TRUE if item is in phantom state or excluded from the parts list. 
    ///Otherwise, FALSE.</param>
    virtual Acad::ErrorStatus getItemExtendedData(const AcDbObjectId& itemId, 
                                                  const ItemDataType& dataType,
                                                  bool& data) const = 0;

    virtual Acad::ErrorStatus setItemExtendedData(const AcDbObjectId& itemId, 
                                                  const ItemDataType& dataType,
                                                  bool data) = 0;

    ///<summary>Merges the given BOM row items.</summary>
    ///<param name="itemIds">Input only. Specifies an array of BOM item ids to merge.</param>
    virtual Acad::ErrorStatus mergeItems(const AcDbObjectIdArray& itemIds) = 0;

    ///<summary>Gets the extended BOM properties of a BOM table. It checks whether a specific BOM table is a border
    ///BOM and if the BOM is visible.</summary>
    ///<param name="bomId">Input only. Specifies the BOM table id.</param>
    ///<param name="isBorderBom">Output only. Returns TRUE if it is a border BOM table.</param>
    ///<param name="isVisible">Output only. Returns TRUE if the BOM table is visible. For border bom, this parameter
    ///will be TRUE, although it will not be listed in the browser. Bom table not listed in the BOM edit dialog box
    ///will have this parameter set to FALSE.</param>
    virtual Acad::ErrorStatus getExtendedBomProperties(const AcDbObjectId& bomId, 
                                                       bool& isBorderBom, 
                                                       bool& isVisible) const = 0;

    ///<summary>This sets the priority of the bom item for the purpose of sorting (applySort).</summary>
    ///<param name="itemId">Input only. Specifies the BOM row item.</param>
    ///<param name="priority">Input only. Specifies the priority. Typically >= 1.</param>
    virtual Acad::ErrorStatus setItemSortPriority(const AcDbObjectId& itemId,
                                                 int priority) = 0 ;
    ///<summary>This retrieves the priority of the bom item for the purpose of sorting (applySort).</summary>
    ///<param name="itemId">Input only. Specifies the BOM row item.</param>
    ///<param name="priority">Input only. Specifies the priority. Typically >= 1.</param>
    virtual Acad::ErrorStatus getItemSortPriority(const AcDbObjectId& itemId,
                                                 int &priority) const = 0;

    ///<summary>This checks if there is a bom override for the specified attribute/column of the specified item and 
	///if so, returns the override properties.</summary>
    ///<param name="itemId">Input Only. Id of the bom item/partref/data entry.</param>
    ///<param name="attribute">Input Only. Name of attribute/column to check.</param>
    ///<param name="originalValue">The original evaluated value (what would be there if there is no override). 
	  ///Would be empty if there is no bom override</param>
    ///<param name="originalData">The original unevaluated data (what would be there if there is no override).
	  ///Would be empty if there is no bom override.</param>
    ///<param name="currentValue">The current evaluated value.</param>
    ///<param name="currentData">The current unevaluated data.</param>
    ///<param name="overrideType">The type of bom override if any. Would be set to sbNoOverride if there is no bom override.</param>
    ///<param name="editable">Indicates if the attribute can be edited.</param>
    virtual Acad::ErrorStatus getBomOverride(
      const AcDbObjectId& itemId, // id of bom item/partref/data entry
      const ACHAR *attribute,
      ACHAR *& originalValue,
      ACHAR *& originalData,
      ACHAR *& currentValue,
      ACHAR *& currentData,
      Acm::BomOverrideType &overrideType,
      bool &editable
    ) const = 0;

    ///<summary>This removes the specified local attribute if any from this item.</summary>
    ///<param name="itemId">Input Only. Id of the bom item/partref/data entry.</param>
    ///<param name="attribute">Input Only. Name of attribute/column to remove.</param>
    virtual Acad::ErrorStatus removeAttribute(
      const AcDbObjectId& itemId,  // id of bom item/partref/data entry
      const ACHAR *attribute) = 0;
    

    virtual Acad::ErrorStatus splitItem(const AcDbObjectId& itemId, const AcDbObjectIdArray& PartrefIds) = 0;
};
#pragma warning(pop)
///<summary>This class allows you to sequentially retrieve the objects in the BOM dictionary, and keeps track of what the last object retrieved was.</summary>
class AcmIterator
{
public:
    virtual ~AcmIterator();
    ///<summary>This function is similar to the AcDbIterator and dictionary iterator.</summary>
    virtual AcDbObjectId  objectId() const = 0;
    ///<summary>Gets the value map data for the current item. The map is based on the current BOM standard.</summary>
    virtual Acad::ErrorStatus getData(CMapStringToString& valueMap) const = 0;
    ///<summary>Sets the value map data for the current item. The map is checked against the current BOM table. 
	  ///Value, whose name is not found in the current BOM column list, is stripped from the map.</summary>
    virtual Acad::ErrorStatus setData(const CMapStringToString& valueMap) = 0;
    ///<summary>Returns the quantity of the current item.</summary>
    virtual int numEntries() const = 0;
    virtual Acad::ErrorStatus getSortPriority(int& priority) const = 0;
    virtual Acad::ErrorStatus setSortPriority(int priority) = 0;
    ///<summary>This function is similar to the AcDbIterator and dictionary iterator.</summary>
    virtual Adesk::Boolean done() = 0;
    ///<summary>This function is similar to the AcDbIterator and dictionary iterator.</summary>
    virtual Adesk::Boolean next() = 0;
    ///<summary>This function is similar to the AcDbIterator and dictionary iterator.</summary>
    virtual Adesk::Boolean setPosition(int idx) = 0;
    ///<summary>This function is similar to the AcDbIterator and dictionary iterator.</summary>
    virtual Adesk::Boolean setPosition(const AcDbObjectId& id) = 0;
};

inline AcmIterator::~AcmIterator()
{
}



ACMSYMBB_CRX_DLLSHARE AcmBOMManager* getAcmBomMgr();

#define BOMMGR_SERVICE_NAME  ACRX_T(/*MSG0*/"AcmBomManagerService")
#define acmBomMgr            getAcmBomMgr()
#define isBomMgrReady()      acrxServiceIsRegistered(BOMMGR_SERVICE_NAME)
#define LockBomMgr()         (isBomMgrReady() ? acmBomMgr->addDependency(), TRUE : FALSE )
#define UnlockBomMgr()       (isBomMgrReady() ? acmBomMgr->removeDependency(), TRUE : FALSE )

Acm::ErrorStatus registerBomMgr();
Acm::ErrorStatus unloadBomMgr();

#endif
