BOOL CInstanceTree::UpdateTargets()
{
    // only do update if something has changed in the target view
    if (!(m_pProjectManager->GetTargetTree())->m_bTargetTreeChanged)
    {
        return TRUE;
    }

    BOOL ret;
    CXMLDocument    tTargetDoc;
    TStringList listNewTargets;
    CXMLNode nodeTargetRoot;
    CXMLNode nodeInstanceRoot;

    // update lists
    TStringList listUpdateChanged;
    TStringList listUpdateNew;
    TStringList listUpdateDeleted;

    (m_pProjectManager->GetTargetTree())->m_bTargetTreeChanged = FALSE;

    // get instance tree root node
    if (!m_domDocument.GetRootNode(nodeInstanceRoot))
    {
        return FALSE;
    }

    // get root node of target view
    IUnknown*   pTmp = NULL;
    HRESULT hr = m_pProjectManager->GetTargetViewDOM(&pTmp);
    if(hr != S_OK)
    {
        return FALSE;
    }
    tTargetDoc.SetIXMLDocument(pTmp);
    pTmp->Release();
    // add target nodes as children
    if(!tTargetDoc.GetRootNode(nodeTargetRoot))
    {
        return FALSE;
    }

    // get new targets from target view
    if (!GetTargetsFromTargetTree(listNewTargets))
    {
        return FALSE;
    }

    // empty xml tree
    nodeInstanceRoot.RemoveAllChilds();

    // mark all nodes not used:
    POSITION posH = m_mapInstanceTargets.GetStartPosition();
    while(posH)
    {
        CString strId;
        TInstanceTargetInfo* pInfo;
        m_mapInstanceTargets.GetNextAssoc(posH, strId, pInfo);
        if (pInfo)
        {
            pInfo->bUsed = FALSE;
        }
    }
    


    // look at all new targets, hang targets into the tree:
    // test if target is a new target or the attributes have changed or it is the same
    // in the last two cases, take the old node and only change attributes if necessary
    POSITION posNewTargets = listNewTargets.GetHeadPosition();
    while(posNewTargets)
    {
        CXMLNode nodeTarget;
        CXMLNode nodeInstance;
        CXMLNode nodeLink;

        // attributes of the target node
        CString     strTText;                // node text
        CString     strTId;                  // node id
        CString     strTType;                // node type (KAD type)
        CString     strTAddress;             // connect info
        CString     strTUserAddress;         // user connect info
        CString     strTConsoleAddress;      // console address
        CString     strTAssignedResource;    // assigned resource
        CString     strTSource;              // source file for add on action
        
        CString     strParseSource;         // parser source help var
        CString     strParseSourceNew;      // parser source
        CString     strInstType;             // type of the instance node

        CString     strIdPathTarg;          // id path of target node in target tree
        CString     strIdPathInst;          // id path of target instance in instance tree
        CString     strTargetId;
        CString     strWaitForTarget;
        
        strIdPathTarg = listNewTargets.GetNext(posNewTargets);

        strTargetId = strIdPathTarg;
        int iFind = strTargetId.ReverseFind(CE_XML_IDPATH_SEP_CHAR);
        ASSERT(iFind>0);
        if (iFind>0)
        {
            strTargetId = strTargetId.Mid(iFind+1);
        }

        // get target node
        ret = nodeTargetRoot.GetNodeFromIdPath(strIdPathTarg, nodeTarget);
        ASSERT(ret);
        if (!ret)
        {
            continue;
        }

        // get attributes of the target node
        nodeTarget.GetAttribute(CE_XMLATTR_TEXT, strTText);
        nodeTarget.GetAttribute(CE_XMLATTR_ID, strTId);
        nodeTarget.GetAttribute(CE_XMLATTR_TYPE, strTType);
        nodeTarget.GetAttribute(CE_XMLATTR_ADDR, strTAddress);
        nodeTarget.GetAttribute(CE_XMLATTR_USERADDR, strTUserAddress);
        nodeTarget.GetAttribute(CE_XMLATTR_CONSOLE_ADDR, strTConsoleAddress);
        nodeTarget.GetAttribute(CE_XMLATTR_RESOURCE, strTAssignedResource);
        nodeTarget.GetAttribute(CE_XMLATTR_SOURCE, strTSource);
        nodeTarget.GetAttribute(CE_XMLATTR_WAIT_TARGET_CONN , strWaitForTarget);

        strInstType = strTType + CE_XML_INST_ADD;
        strParseSource = strTId + _T(".") + CE_INSTANCE_EXT;
        strParseSourceNew = CString(CE_GEN_PATH) + _T("\\") + strTId + _T("\\") + strParseSource;

        // does node already exist in instance tree:
        TInstanceTargetInfo* pInstTargetInfo = NULL;
        CString strLowerId = strTargetId;
        strLowerId.MakeLower();
        if (m_mapInstanceTargets.Lookup(strLowerId, pInstTargetInfo))
        {
            // *** existing node ***
            ASSERT(pInstTargetInfo);
            pInstTargetInfo->bUsed = TRUE;
            nodeInstance = pInstTargetInfo->xmlNode;
            ret = nodeInstanceRoot.AppendChild(nodeInstance, TRUE);
            ASSERT(ret);

            // check if attributes have changed
            // get instance node attributes
            CString strInstText;
            CString strInstId;
            //CString strInstType;
            CString strInstAddress;
            CString strInstUserAddress;
            CString strInstConsoleAddress;
            CString strInstAssignedResource;
            CString strInstSource;

            nodeInstance.GetAttribute(CE_XMLATTR_TEXT, strInstText);
            nodeInstance.GetAttribute(CE_XMLATTR_ID, strInstId);
            //nodeInstance.GetAttribute(CE_XMLATTR_TYPE, strInstType); // type can't change
            nodeInstance.GetAttribute(CE_XMLATTR_ADDR, strInstAddress);
            nodeInstance.GetAttribute(CE_XMLATTR_USERADDR, strInstUserAddress);
            nodeInstance.GetAttribute(CE_XMLATTR_CONSOLE_ADDR, strInstConsoleAddress);
            nodeInstance.GetAttribute(CE_XMLATTR_RESOURCE, strInstAssignedResource);
            nodeInstance.GetAttribute(CE_XMLATTR_SOURCE, strInstSource);
            
            if ((strInstText.CompareNoCase(strTText)!=0)
                || (strInstId.CompareNoCase(strTId)!=0)
                //|| (strInstType.CompareNoCase(strType)!=0)
                || (strInstAddress.CompareNoCase(strTAddress)!=0)
                || (strInstConsoleAddress.CompareNoCase(strTConsoleAddress)!=0)
                || (strInstAssignedResource.CompareNoCase(strTAssignedResource)!=0)
                || (strInstSource.CompareNoCase(strTSource) != 0))
            {
                // node has changed -> update nodes
                nodeInstance.SetAttribute(CE_XMLATTR_TEXT, strTText);
                nodeInstance.SetAttribute(CE_XMLATTR_ID, strTId);
                //nodeInstance.SetAttribute(CE_XMLATTR_TYPE, strType);
                nodeInstance.SetAttribute(CE_XMLATTR_ADDR, strTAddress);
                nodeInstance.SetAttribute(CE_XMLATTR_USERADDR, strTUserAddress);
                nodeInstance.SetAttribute(CE_XMLATTR_CONSOLE_ADDR, strTConsoleAddress);
                nodeInstance.SetAttribute(CE_XMLATTR_RESOURCE, strTAssignedResource);
                nodeInstance.SetAttribute(CE_XMLATTR_SOURCE, strTSource);

                listUpdateChanged.AddTail(pInstTargetInfo->strIdPath);
            }
           
        }
        else // *** new node ***
        {
            if(!m_domDocument.CreateNode(nodeInstance, CE_XMLTAG_NODE))
            {
                continue;
            }

            // set attributes of target instance node
            nodeInstance.SetAttribute(CE_XMLATTR_TEXT, strTText);
            nodeInstance.SetAttribute(CE_XMLATTR_ID, strTId);
            nodeInstance.SetAttribute(CE_XMLATTR_ADDR, strTAddress);
            nodeInstance.SetAttribute(CE_XMLATTR_USERADDR, strTUserAddress);
            nodeInstance.SetAttribute(CE_XMLATTR_CONSOLE_ADDR, strTConsoleAddress);
            nodeInstance.SetAttribute(CE_XMLATTR_RESOURCE, strTAssignedResource);
            nodeInstance.SetAttribute(CE_XMLATTR_TARGET_TYPE, strTType);
            nodeInstance.SetAttribute(CE_XMLATTR_SOURCE, strTSource);

            nodeInstance.SetAttribute(CE_XMLATTR_TYPE, strInstType);
            if (!strWaitForTarget.IsEmpty())
            {
                nodeInstance.SetAttribute(CE_XMLATTR_WAIT_TARGET_CONN, strWaitForTarget);
            }

            // create new instance info struct
            ASSERT(pInstTargetInfo==NULL);
            pInstTargetInfo = new TInstanceTargetInfo;
            ASSERT(pInstTargetInfo);
            if (!pInstTargetInfo)
            {
                continue;
            }

            ret = nodeInstanceRoot.AppendChild(nodeInstance, TRUE);
            ASSERT(ret);

            nodeInstance.GetIdPath(strIdPathInst);
            pInstTargetInfo->strIdPath = strIdPathInst;
            pInstTargetInfo->strTargetId = strTId;
            pInstTargetInfo->xmlNode = nodeInstance;
            pInstTargetInfo->bUsed = TRUE;

            strLowerId = strTId;
            strLowerId.MakeLower();

            m_mapInstanceTargets.SetAt(strLowerId, pInstTargetInfo);

            // add to update list (new node)
            listUpdateNew.AddTail(strIdPathInst);

           

            // now create target link node: the link that will be replaced by compiler outpu
            if((!m_domDocument.CreateNode(nodeLink, CE_XMLTAG_LINK))
                ||(!nodeInstance.AppendChild(nodeLink)) )
            {
                continue;
            }

            nodeLink.SetAttribute(CE_XMLATTR_PARSERSOURCE, strParseSourceNew);
            nodeLink.SetAttribute(CE_XMLATTR_ID, strTId);

            TSourceFileInfo* pFileInfo;
            pFileInfo = CreateSourceFileInfo(strParseSourceNew, nodeLink, "");
            SourceFileMap_SetAt(strParseSourceNew, pFileInfo, m_mapSourceFiles);

            AddSourceFileToReparse(strParseSourceNew);
        }
    }

   
    

    // find deleted nodes:
    posH = m_mapInstanceTargets.GetStartPosition();
    while(posH)
    {
        CString strId;
        TInstanceTargetInfo* pInfo;
        m_mapInstanceTargets.GetNextAssoc(posH, strId, pInfo);
        if (pInfo)
        {
            if (pInfo->bUsed == FALSE)
            {
                listUpdateDeleted.AddTail(pInfo->strIdPath);
                delete pInfo;
                m_mapInstanceTargets.RemoveKey(strId);
            }
        }
    }

    if (m_bInit)
    {
        return TRUE;
    }

    // send update messages
    POSITION lPos;
    lPos = listUpdateDeleted.GetHeadPosition();
    while(lPos)
    {
        CString strIdPath = listUpdateDeleted.GetNext(lPos);
        if (!strIdPath.IsEmpty())
        {
            FireUpdateTree(strIdPath, eUpdateDelete);
            CString strId = strIdPath;
            int iFind = strId.ReverseFind(CE_XML_IDPATH_SEP_CHAR);
            ASSERT(iFind>0);
            if (iFind>0)
            {
                strId = strId.Mid(iFind+1);
            }
            CComBSTR sId = strId;
            m_pProjectManager->Fire_TargetInstanceRemoved(sId);
        }
    }
    lPos = listUpdateChanged.GetHeadPosition();
    while(lPos)
    {
        CString strIdPath = listUpdateChanged.GetNext(lPos);
        if (!strIdPath.IsEmpty())
        {
            FireUpdateTree(strIdPath, eUpdateAttributes);
            CString strId = strIdPath;
            int iFind = strId.ReverseFind(CE_XML_IDPATH_SEP_CHAR);
            ASSERT(iFind>0);
            if (iFind>0)
            {
                strId = strId.Mid(iFind+1);
            }
            CComBSTR sId = strId;
            CComBSTR sIdPath = strIdPath;
            m_pProjectManager->Fire_TargetInstanceAdded(sId, sIdPath);
        }
    }
    lPos = listUpdateNew.GetHeadPosition();
    while(lPos)
    {
        CString strIdPath = listUpdateNew.GetNext(lPos);
        if (!strIdPath.IsEmpty())
        {
            FireUpdateTree(strIdPath, eUpdateInsert);
            CString strId = strIdPath;
            int iFind = strId.ReverseFind(CE_XML_IDPATH_SEP_CHAR);
            ASSERT(iFind>0);
            if (iFind>0)
            {
                strId = strId.Mid(iFind+1);
            }
            CComBSTR sId = strId;
            CComBSTR sIdPath = strIdPath;
            m_pProjectManager->Fire_TargetInstanceAdded(sId, sIdPath);
        }
    }

    Reparse(FALSE);
    
    return TRUE;
}
/**
 * InitTree
 * initialize the instance tree for the first time: get all necessary 
 * information from the kad and construct root and classes group nodes
 *
 * @return          TRUE: on success
 *                  FALSE: else
 * @exception       -
 * @see             
*/
BOOL CInstanceTree::InitTree()
{
    GetStaticInfos();

    // create project node
    CXMLNode docRoot;
    CXMLNode projectNode;

    PROJ_MAN_ASSERT(m_pProjectManager);

    CString strProjNodeId;
    strProjNodeId = m_pProjectManager->GetProjectName()+_T(".")+ID_PATH_INSTANCEVIEW;
    CString strVersion;
    strVersion.Format(_T("%i"), PRODUCT_BUILD);
    if (  (!m_domDocument.GetDocNode(docRoot))
        ||(!m_domDocument.CreateNode(projectNode, CE_XMLTAG_NODE))
        ||(!docRoot.AppendChild(projectNode))
        ||(!projectNode.SetAttribute(CE_XMLATTR_TEXT, m_pProjectManager->GetProjectName()))
        ||(!projectNode.SetAttribute(CE_XMLATTR_ID, strProjNodeId))
        ||(!projectNode.SetAttribute(CE_XMLATTR_PARSERSOURCE, m_pProjectManager->GetProjectFileName()))
        ||(!projectNode.SetAttribute(CE_XMLATTR_TYPE, m_strInstancesType))
        ||(!projectNode.SetAttribute(PRJMAN_VERSION, strVersion))    )
    {
        return FALSE;
    }

    Reparse4CPAttributes(&projectNode);

    // add project file to source file list
    TSourceFileInfo* pProjFileInfo;
    CString strProjFileName = m_pProjectManager->GetProjectFileName();
    pProjFileInfo = CreateSourceFileInfo(strProjFileName,
                                         projectNode,  _T(""));
    PROJ_MAN_ASSERT(pProjFileInfo);
    pProjFileInfo->strIdPath = CE_XML_IDPATH_SEP + strProjNodeId;
    SetSourceTime(pProjFileInfo, m_pProjectManager->GetProjectFileNameWithPath());
    SourceFileMap_SetAt(strProjFileName, pProjFileInfo, m_mapSourceFiles);

    // update targets
    UpdateTargets();

    Reparse(FALSE);

    ExpandFromViewData();

    IXMLDOMDocument *pXMLDoc;
    m_domDocument.GetIXMLDocument(&pXMLDoc);
    m_pProjectManager->Fire_InitInstanceTree((IUnknown*)pXMLDoc);
    pXMLDoc->Release();

    m_bInit = FALSE;

    POSITION pos = m_mapInstanceTargets.GetStartPosition();
    while(pos)
    {
        CString strId;
        TInstanceTargetInfo* pInfo;
        m_mapInstanceTargets.GetNextAssoc(pos, strId, pInfo);
        if (pInfo)
        {
            CComBSTR sId = pInfo->strTargetId;
            CComBSTR sIdPath = pInfo->strIdPath;
            m_pProjectManager->Fire_TargetInstanceAdded(sId, sIdPath);
        }
    }

    return TRUE;
}
// 15.12.05 SIS >>
// added parameter crstrIndex
// to save index range
bool CCeWatchElement::SaveToNode(CXMLNode& rtNode, CXMLDocument& rtDocument, const CString& crstrIndexRange)
// 15.12.05 SIS <<
{
    bool bReturn = true;
	// don't forget to increment the version string if you change anything here
	CString str;

    if(m_bInitExpanded)
    {
        rtNode.SetAttribute(CEWATCH_XMLATTR_EXPANDED, _T("1"));
    }

	CString strExpression = m_Name;
	if(!crstrIndexRange.IsEmpty())
	{
		strExpression.Format(_T("%s, %s"), m_Name, crstrIndexRange);
	}
	rtNode.SetAttribute(CEWATCH_XMLATTR_EXPRESSION, strExpression);

	if (m_Type.GetName().GetLength() > 0)
	{
		str.Format("%s;%d", m_Type.GetName(), (int)m_Type.GetVarKind());
        rtNode.SetAttribute(CEWATCH_XMLATTR_TYPE, str);
	}
    rtNode.SetAttribute(CEWATCH_XMLATTR_VALUE, m_strValue);

	if (m_strFormat.GetLength() > 0)
    {
        rtNode.SetAttribute(CEWATCH_XMLATTR_FORMAT, m_strFormat);
    }

	// #2149 10.10.06 SIS >>
	// only save visible array elements
    int iNumChildren = GetChildrenCount();
	int	iChildStart = 0;
	int iChildStop = iNumChildren-1;
	if(m_Type.IsArray())
	{
		VERIFY(ExtractArrayIndices(crstrIndexRange, iChildStart, iChildStop));
		iChildStart = max(iChildStart - m_Type.GetArrayLowerBound(), 0);
		iChildStop = min(iChildStop - m_Type.GetArrayLowerBound(), iNumChildren-1);
	}
	CCeWatchElement* pElem = NULL;
	for (int iChild = iChildStart; iChild <= iChildStop; iChild++)
	// #2149 10.10.06 SIS <<
    {
        CXMLNode    tNodeChild;
        if(rtDocument.CreateNode(tNodeChild, CEWATCH_XMLTAG_VARNODE))
        {
			pElem = GetChild(iChild);
			if(!pElem)
			{
				break;
			}
		    bReturn &= pElem->SaveToNode(tNodeChild, rtDocument, _T(""));
            if(!bReturn)
            {
                break;
            }
            rtNode.AppendChild(tNodeChild);
        }
    }

    return bReturn;
}