apicompatanamdw/compatanalysercmd/headeranalyser/src/BBCAnalyser.cpp
changeset 0 638b9c697799
child 3 ebe3f8f03b59
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/apicompatanamdw/compatanalysercmd/headeranalyser/src/BBCAnalyser.cpp	Tue Jan 12 14:52:39 2010 +0530
@@ -0,0 +1,3164 @@
+/*
+* Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  
+*
+*/
+
+
+#include "CmdGlobals.h"
+#ifdef __WIN__
+#pragma warning(disable:4786)
+#endif
+
+#include <assert.h>
+#include <map>
+#include <list>
+#include <string>
+#include <time.h>
+#include <xercesc/dom/DOM.hpp>
+
+#include "BBCAnalyser.h"
+#include "BBCPreAnalysis.h"
+#include "Issues.h"
+#include "ReportGenerator.h"
+#include "ReportIssue.h"
+#include "XMLUtils.h"
+#include "XMLStringConst.h"
+#include "VariableNodeAnalysis.h"
+#include "EnumNodeAnalysis.h"
+#include "FunctionNodeAnalysis.h"
+#include "TypedefNodeAnalysis.h"
+#include "OperatorFunctionNodeAnalysis.h"
+#include "UnionNodeAnalysis.h"
+#include "ClassNodeAnalysis.h"
+#include "StructNodeAnalysis.h"
+#include "NodeTypeComparator.h"
+#include "Utils.h"
+
+using namespace std;
+
+XERCES_CPP_NAMESPACE_USE
+
+
+
+struct ConstructorElement
+{
+    const XMLCHAR* iEntityName;	
+    NodeAnalysis::Constructor iConstructor;
+};
+
+// Table of different node analysis constructor functions
+const ConstructorElement KConstructorTable[KEntityComparisonTableCount]=
+    {
+    {KXMLBaseString,UnderConstructionNodeAnalysis::Construct},
+    {KXMLFundamentalTypeString,UnderConstructionNodeAnalysis::Construct},
+    {KXMLTypedefString,TypedefNodeAnalysis::Construct},//
+    {KXMLNamespaceString,UnderConstructionNodeAnalysis::Construct},
+    {KXMLCvQualifiedTypeString,UnderConstructionNodeAnalysis::Construct},
+    {KXMLVariableString,VariableNodeAnalysis::Construct},//
+    {KXMLFundamentalTypeString,UnderConstructionNodeAnalysis::Construct},
+    {KXMLTypedefString,UnderConstructionNodeAnalysis::Construct},
+    {KXMLNamespaceString,UnderConstructionNodeAnalysis::Construct},
+    {KXMLFunctionString,FunctionNodeAnalysis::Construct},//
+    {KXMLEnumerationString,EnumNodeAnalysis::Construct},//
+    {KXMLFieldString,UnderConstructionNodeAnalysis::Construct},
+    {KXMLArgumentString,UnderConstructionNodeAnalysis::Construct},
+    {KXMLEllipsisString,UnderConstructionNodeAnalysis::Construct},
+    {KXMLArrayTypeString,UnderConstructionNodeAnalysis::Construct},
+    {KXMLClassString,ClassNodeAnalysis::Construct},//
+    {KXMLConstructorString,UnderConstructionNodeAnalysis::Construct},
+    {KXMLConverterString,UnderConstructionNodeAnalysis::Construct},
+    {KXMLDestructorString,UnderConstructionNodeAnalysis::Construct},
+    {KXMLEnumValueString,UnderConstructionNodeAnalysis::Construct},
+    {KXMLFileString,UnderConstructionNodeAnalysis::Construct},
+    {KXMLFunctionTypeString,UnderConstructionNodeAnalysis::Construct},
+    {KXMLMethodString,UnderConstructionNodeAnalysis::Construct},
+    {KXMLMethodTypeString,UnderConstructionNodeAnalysis::Construct},
+    {KXMLNamespaceAliasString,UnderConstructionNodeAnalysis::Construct},
+    {KXMLOffsetTypeString,UnderConstructionNodeAnalysis::Construct},
+    {KXMLOperatorFunctionString,OperatorFunctionNodeAnalysis::Construct},
+    {KXMLOperatorMethodString,UnderConstructionNodeAnalysis::Construct},
+    {KXMLPointerTypeString,UnderConstructionNodeAnalysis::Construct},
+    {KXMLReferenceTypeString,UnderConstructionNodeAnalysis::Construct},
+    {KXMLStructString,StructNodeAnalysis::Construct},
+    {KXMLUnimplementedString,UnderConstructionNodeAnalysis::Construct},
+    {KXMLUnionString,UnionNodeAnalysis::Construct}
+    };
+
+// ----------------------------------------------------------------------------
+// NodeAnalysis::FindNodeAnalysisConstructor
+// ----------------------------------------------------------------------------
+//
+NodeAnalysis::Constructor FindNodeAnalysisConstructor(const XMLCh* nodeName)
+{
+    int i = 0;
+
+    for (i = 0;i < KEntityComparisonTableCount; ++i)
+    {
+        if ( Equals(KConstructorTable[i].iEntityName,nodeName) )
+        {
+            return KConstructorTable[i].iConstructor;
+        }
+    }
+    return NULL;
+}
+
+// ----------------------------------------------------------------------------
+// BBCPreAnalysis::preAnalyseClassForVirtuality
+// 
+// Analyse for virtuality
+// ----------------------------------------------------------------------------
+//
+bool BBCPreAnalysis::preAnalyseClassForVirtuality(HANodeIterator classNode)
+{
+	bool isvirtual = false;
+	bool hasvirtualbases = false;
+
+    //Check to see if we have already inspected this class
+    if ( classNode.GetAttribute(KXMLBBCVirtualString) )
+    {
+        return classNode.CheckForBooleanAttribute(KXMLBBCVirtualString);
+    }
+
+    if ( classNode->hasChildNodes() )
+    {
+        //Check for virtual bases first as it is quicker
+        DOMNodeList * childs = classNode->getChildNodes();
+        
+        XMLSize_t childcount = childs->getLength();
+        
+        for (unsigned int i = 0; i < childcount; ++i)
+        {
+            DOMNode* child = childs->item(i);
+            
+            //Skip any other than Base node
+            if ( !Equals(child->getNodeName(),KXMLBaseString) ) 
+            {
+                continue;
+            }
+            
+            HANodeIterator childclass(classNode);
+            childclass.current = child;
+
+            if ( childclass.CheckForBooleanAttribute(KXMLVirtualString) )
+            {
+                classNode.SetAttribute(KXMLBBCVirtualInheritanceString,KXML1String);
+                hasvirtualbases = true;
+            }
+				
+            const XMLCh * classid = childclass.GetAttribute(KXMLTypeString);
+    
+            assert(classid != NULL);
+
+            bool ret = childclass.FindNodeById(classid);
+
+            assert(ret == true);
+
+            if ( preAnalyseClassForVirtuality( childclass ) )
+            {
+                //The class is virtual, mark it to the xml document and return
+                classNode.SetAttribute(KXMLBBCVirtualString, KXML1String);
+                isvirtual = true;
+            }
+            
+            if ( childclass.CheckForBooleanAttribute(KXMLBBCVirtualInheritanceString) )
+            {
+                classNode.SetAttribute(KXMLBBCVirtualInheritanceString,KXML1String);
+                hasvirtualbases = true;
+            }
+        }
+        
+    }
+
+    //We have already detected that this is virtual class
+    if ( isvirtual )
+    {
+        ClassGenerateVirtualTable(classNode);
+        return true;
+    }
+
+    //Go through the methods of the class and check them for virtuality
+    const XMLCh* attributeValue = classNode.GetAttribute(KXMLMembersString);
+    
+    if (attributeValue)
+    {
+        BaseRefVectorOf< XMLCh > * memberids_ptr = XMLString::tokenizeString(attributeValue);
+        auto_ptr<BaseRefVectorOf< XMLCh > > memberids(memberids_ptr);
+
+        for (unsigned int i = 0; i < memberids->size(); ++i)
+        {
+            const XMLCh * memberid = memberids->elementAt(i);
+            
+            HANodeIterator member(classNode);
+            bool memberfound = member.FindNodeById(memberid);
+
+            if ( memberfound )
+            {
+                if ( member.CheckForBooleanAttribute(KXMLVirtualString) ||
+                    member.CheckForBooleanAttribute(KXMLPureVirtualString))
+                {
+                    //Generate primary virtual table for the class
+                    ClassGenerateVirtualTable(classNode);
+                    //The class is virtual, mark it to the xml document and return
+                    classNode.SetAttribute(KXMLBBCVirtualString, KXML1String);
+                    return true;
+                }
+            }
+            else
+            {
+                //The tree is broken
+                assert(false);
+            }
+        }
+        //memberids->cleanup();
+        //delete memberids;
+    }
+    
+    classNode.SetAttribute(KXMLBBCVirtualString, KXML0String);
+    return false;
+}
+
+// ----------------------------------------------------------------------------
+// BBCAnalyser::preAnalyseClassForDerivability
+//
+// Check for derivability. The class is derivable iff:
+// 1. Has a public or protected explicitely declared exported constructor
+// 2. Has a public or protected inline constructor
+// In GCCXML:
+// 
+// Check methods of type "Constructor" 
+//
+// Constructor type / attribute:| artificial | explicit | inline | exported
+//--------------------------------------------------------------------------
+// implicite inline constructor |     x     |     x     |   x    |          
+// inline constructor           |           |    (x)    |   x    |          
+// exported constructor         |           |    (x)    |        |    x     
+// ----------------------------------------------------------------------------
+//
+void BBCPreAnalysis::preAnalyseClassForDerivability(HANodeIterator classNode)
+{
+    //Go through the methods of the class and check them for constructor
+    const XMLCh* attributeValue = classNode.GetAttribute(KXMLMembersString);
+
+    //Default to public desctructor as it is same as no desctructor at all
+    classNode.SetAttribute(KXMLBBCDestructorAccessString,KXMLBBCAccessPublicString);
+	
+    if (attributeValue)
+    {
+        BaseRefVectorOf< XMLCh > * memberids_ptr = XMLString::tokenizeString (attributeValue);
+        auto_ptr<BaseRefVectorOf< XMLCh > > memberids(memberids_ptr);
+
+        for (unsigned int i = 0; i < memberids->size(); ++i)
+        {
+            const XMLCh * memberid = memberids->elementAt(i);
+            
+            HANodeIterator member(classNode);
+            
+            if ( member.FindNodeById(memberid) )
+            {
+                //The member is constructor
+                if ( Equals(member->getNodeName(),KXMLConstructorString) )
+                {
+                    //Check if the constructor is protected or public
+                    const XMLCh* accessAttribute = member.GetAttribute(KXMLAccessString);
+                    
+                    if ( Equals(accessAttribute,KXMLProtectedString) || Equals(accessAttribute,KXMLPublicString) )
+                    {
+                        //If the constructor is artificial (compiler generated) we need to check for the explicit attribute 
+                        // to recognize the proper constructor and not the helper constructor generated by the compiler
+                        bool artificial = member.CheckForBooleanAttribute(KXMLArtificialString);
+                        
+                        bool explicit_val = member.CheckForBooleanAttribute(KXMLExplicitString);
+                        
+                        bool inline_val = member.CheckForBooleanAttribute(KXMLInlineString);
+                    
+                        const XMLCh* attributeAttribute = member.GetAttribute(KXMLAttributeString);                            
+                        //Check for export or inline
+                        if ( ( inline_val && explicit_val && artificial ) || //the constructor is compiler generated inline function
+                             ( inline_val && !artificial ) ||  //the constructor is explicitely declared inline function
+                             (attributeAttribute && Equals(attributeAttribute,KXMLExportedString))  //the constructor is explicitely declared exported function
+                            )
+                            {
+                                if ( Equals(accessAttribute,KXMLProtectedString) )
+                                {
+                                    //Is derivable class. Mark the node as one.
+                                    classNode.SetAttribute(KXMLBBCProtectedConstructorString,KXML1String);
+                                }
+                                
+                                if ( Equals(accessAttribute,KXMLPublicString) )
+                                {
+                                    classNode.SetAttribute(KXMLBBCPublicConstructorString,KXML1String);
+                                    //Class is instantiable,too!!!
+                                }
+                            }
+                    }
+                } else if ( Equals(member->getNodeName(),KXMLDestructorString) )
+                {
+                    //Check if the destructor is private, protected or public and accessibility
+                    // if the desctructor is not accessible it is marked as private 
+                    const XMLCh* accessAttribute = member.GetAttribute(KXMLAccessString);
+                    
+                    bool inline_val = member.CheckForBooleanAttribute(KXMLInlineString);
+                    bool virtual_val = member.CheckForBooleanAttribute(KXMLVirtualString) ||
+                                        member.CheckForBooleanAttribute(KXMLPureVirtualString);
+                    bool exported_val = false; 
+                    const XMLCh* attributeAttribute = member.GetAttribute(KXMLAttributeString);                            
+                             
+                    if (attributeAttribute && Equals(attributeAttribute,KXMLExportedString) )
+                    {
+                        exported_val = true;
+                    }
+
+                    if ( !Equals(accessAttribute,KXMLPrivateString) && (inline_val || virtual_val || exported_val) )
+                    {
+
+                        if ( Equals(accessAttribute,KXMLPublicString) )
+                        {
+                            classNode.SetAttribute(KXMLBBCDestructorAccessString,KXMLBBCAccessPublicString);
+
+                        } else if ( Equals(accessAttribute,KXMLProtectedString) )
+                        {
+                            classNode.SetAttribute(KXMLBBCDestructorAccessString,KXMLBBCAccessProtectedString);
+                        } 
+                    }
+                    else
+                    {
+                        classNode.SetAttribute(KXMLBBCDestructorAccessString,KXMLBBCAccessPrivateString);
+                    }
+                }
+
+            }
+            else
+            {
+                //The tree is broken
+                assert(false);
+            }
+        }
+        //delete memberids;
+    }
+}
+
+
+// ----------------------------------------------------------------------------
+// BBCAnalyser::preAnalyseClassForInlineFunctions
+// 
+// ----------------------------------------------------------------------------
+//
+void BBCPreAnalysis::preAnalyseClassForInlineFunctions(HANodeIterator classNode)
+{
+    //Go through the methods of the class and check them for virtuality
+    const XMLCh* attributeValue = classNode.GetAttribute(KXMLMembersString);
+
+    if (attributeValue)
+    {
+        BaseRefVectorOf< XMLCh > * memberids_ptr = XMLString::tokenizeString (attributeValue);
+        auto_ptr<BaseRefVectorOf< XMLCh > > memberids(memberids_ptr);
+        bool hasPublicInline = false;
+        bool hasProtectedInline = false;
+        
+        for (unsigned int i = 0; i < memberids->size(); ++i)
+        {
+            const XMLCh * memberid = memberids->elementAt(i);
+            
+            HANodeIterator member(classNode);
+            
+            if ( member.FindNodeById(memberid) )
+            {
+                //Check every inline function but do not take artificial (compiler generated) functions into account
+                if ( member.CheckForBooleanAttribute(KXMLInlineString) && !member.CheckForBooleanAttribute(KXMLArtificialString) )
+                {
+
+                    //Check if the constructor is protected or public
+                    const XMLCh* attributeValue = member.GetAttribute(KXMLAccessString);
+                    
+                    if ( Equals(attributeValue,KXMLProtectedString) )
+                    {
+                        //The class has protected inline function
+                        hasProtectedInline = true;
+                        classNode.SetAttribute(KXMLBBCProtectedInlineString,KXML1String);
+                    }
+                    
+                    if ( Equals(attributeValue,KXMLPublicString) )
+                    {
+                        //The class has public inline function
+                        hasPublicInline = true;
+                        classNode.SetAttribute(KXMLBBCPublicInlineString,KXML1String);
+                    }
+                    
+                    //It is enough if we have public inline, the class is fully exposed
+                    if ( hasPublicInline )
+                    {
+                        return;
+                    }
+                }
+            }
+            else
+            {
+                //The tree is broken
+                assert(false);
+            }
+        }
+        //memberids->cleanup();
+        //delete memberids;
+    }
+    
+}
+
+
+// ----------------------------------------------------------------------------
+// BBCAnalyser::preAnalyseClass
+// 
+// ----------------------------------------------------------------------------
+//
+void BBCPreAnalysis::preAnalyseClass(HANodeIterator classNode)
+{
+    preAnalyseClassForVirtuality(classNode);
+    preAnalyseClassForDerivability(classNode);
+    preAnalyseClassForInlineFunctions(classNode);
+}
+
+
+// ----------------------------------------------------------------------------
+// printNode
+// DEBUG method
+// 
+// ----------------------------------------------------------------------------
+//
+void printNode(HANodeIterator node)
+{
+    DEBUG_STUFF(const XMLCh * name = node->getNodeName();)
+    const XMLCh * value = node->getNodeValue();
+ 
+    DEBUG_PRINT_XMLCh(name)
+
+    if ( value )
+    {
+        DEBUG_PRINT(":")
+        DEBUG_PRINT_XMLCh(value)
+    }
+
+    DOMNamedNodeMap * atts = node->getAttributes();
+    if (atts)
+    {
+        DEBUG_PRINT(" attributes: ")
+        XMLSize_t size = atts->getLength();
+        for (unsigned int i = 0; i < size; ++i )
+        {
+            DOMNode * att = atts->item(i);
+            HANodeIterator cit(node);
+            cit.current = att;
+            printNode(cit);
+        }
+    }
+    DEBUG_PRINT("\n")
+}
+
+
+// ----------------------------------------------------------------------------
+// BBCAnalyser::preAnalyseGenerateMaps
+// 
+// ----------------------------------------------------------------------------
+//
+void BBCPreAnalysis::preAnalyseGenerateMaps(HANodeIterator rootnode, bool baseline)
+{
+    //First generate the file maps	
+    short nodetype = rootnode->getNodeType();
+    assert(nodetype == DOMNode::ELEMENT_NODE);
+
+#ifndef NO_DBG
+    DEBUG_PRINT("****************preAnalyse: Generating index*********************\n")
+    DEBUG_STUFF(time_t starttime = time(NULL);)
+#endif
+
+    DOMDocument * doc =  rootnode->getOwnerDocument();
+    DOMNodeIterator * domit = doc->createNodeIterator (rootnode.current,DOMNodeFilter::SHOW_ELEMENT, NULL, true);
+    DOMNode * it = NULL;
+    while ( NULL != (it = domit->nextNode()) )
+    {
+        HANodeIterator childit(rootnode);
+        childit.current = it;
+
+#ifdef _DEBUG
+        //printNode(childit);
+        // Keep commented, too much stuff to print
+#endif
+        if (DOMNode::ELEMENT_NODE == childit->getNodeType())
+        {
+            childit.IndexNode();
+        }
+    }
+#ifndef NO_DBG
+    DEBUG_PRINT("****************preAnalyse: Generating index END*********************\n")
+    DEBUG_STUFF(time_t endtime = time(NULL);)
+    DEBUG_STUFF(time_t runningtime = endtime - starttime;)
+    DEBUG_PRINT("ELAPSED TIME: ")
+    DEBUG_PRINT((long)runningtime)
+    DEBUG_PRINT("\n")
+
+    DEBUG_PRINT("****************preAnalyse: Generating name map*********************\n")
+    DEBUG_STUFF(time_t starttime2 = time(NULL);)
+#endif
+
+    doc =  rootnode->getOwnerDocument();
+    domit = doc->createNodeIterator (rootnode.current,DOMNodeFilter::SHOW_ELEMENT, NULL, true);
+    it = NULL;
+    while ( NULL != (it = domit->nextNode()) )
+    {
+        HANodeIterator childit(rootnode);
+        childit.current = it;		
+
+        // Add node to name map if following conditions are true:
+        // 1. Node is proper i.e. it is in proper context and it is not artificial (compiler generated).
+        // 2. Node is named (class, enum, function.. etc.)
+        // 3. It is declared in the analysed header OR it is not a baseline node. 
+        //    Without this rule, classes that are moved to another, not to be analysed header,
+        //    would not be properly analysed.
+        if (IsProperNode(childit) && IsNamedNode(childit) && (childit.toBeAnalysed() || !baseline))
+        {        
+            const XMLCh* nodetype = childit->getNodeName();
+            
+            if ( Equals(nodetype,KXMLEnumerationString) )
+            {
+                //Check to see if the enumeration is anonymous	
+                if ( IsAnonymous(childit) )
+                {
+                    DOMNodeList* enumchilds = childit.GetElementsByTagName(KXMLEnumValueString);
+                    XMLSize_t enumchildcount = enumchilds->getLength();
+                    unsigned int i = 0;
+                    for (i = 0; i < enumchildcount; ++i)
+                    {
+                        HANodeIterator enumchildit(childit);
+                        enumchildit.current = enumchilds->item(i);
+                        
+                        enumchildit.NameNode(!baseline);
+                        
+                    }
+
+                    continue;//Skip the enum naming 
+                }
+            }
+
+            childit.NameNode(!baseline);
+        }
+    }
+
+#ifndef NO_DBG
+    DEBUG_PRINT("****************preAnalyse: Generating name map END*********************\n")
+    DEBUG_STUFF(time_t endtime2 = time(NULL);)
+    DEBUG_STUFF(time_t runningtime2 = endtime2 - starttime2;)
+    DEBUG_PRINT("ELAPSED TIME: ")
+    DEBUG_PRINT((long)runningtime2)
+    DEBUG_PRINT("\n")
+#endif
+}
+
+
+// ----------------------------------------------------------------------------
+// BBCAnalyser::checkForEmptyFiles 
+// ----------------------------------------------------------------------------
+//
+vector<bool> BBCAnalyser::checkForEmptyFiles(HANodeIterator rootnode, const list<string>& filesToAnalyse, const list<string>& aMacroFiles)
+{
+    DOMNodeList* childs = rootnode.GetElementsByTagName(KXMLFileString);
+    XMLSize_t childcount = childs->getLength();
+
+    vector<bool> filefound(filesToAnalyse.size(),false);
+
+    for (unsigned int i = 0; i < childcount; ++i)
+    {
+        DOMNode* child = childs->item(i);
+        HANodeIterator childit(rootnode);
+        childit.current = child;        
+        const XMLCh* filename = childit.GetAttribute(KXMLNameString);
+        list<string>::const_iterator it = filesToAnalyse.begin();
+        int j = 0;
+        for (;it != filesToAnalyse.end(); ++it)
+        {
+            if ( CompareFileNames((*it),toString(filename)) )
+            {
+                filefound[j] = true;
+                break;
+            }
+            ++j;
+        }
+    }
+	
+	//validate that file is not empty
+	//in case file only contained macros
+	if(!aMacroFiles.empty())
+	{
+		list<string>::const_iterator start = filesToAnalyse.begin();
+		for(unsigned int i=0; i < filesToAnalyse.size(); i++, start++)
+		{
+			if(!filefound[i])
+			{
+				list<string>::const_iterator mFiles = aMacroFiles.begin();
+				for(;mFiles != aMacroFiles.end();mFiles++)
+					if( toLowerCaseWin(*start) == *mFiles )
+					{
+						filefound[i] = true;
+						break;
+					}
+			}
+		}
+	}
+	return filefound;
+}
+
+
+// ----------------------------------------------------------------------------
+// BBCAnalyser::preAnalyse
+// 
+// ----------------------------------------------------------------------------
+//
+void BBCPreAnalysis::preAnalyse(HANodeIterator rootnode,const list<string> & filesToAnalyse, bool baseline)
+{
+    short nodetype = rootnode->getNodeType();    
+    assert(nodetype == DOMNode::ELEMENT_NODE);
+
+    //First generate the file maps	
+#ifndef NO_DBG
+    DEBUG_PRINT("****************preAnalyse: Generating file maps*********************\n")
+    DEBUG_STUFF(time_t starttime = time(NULL);)
+#endif
+
+    DOMNodeList* childs = rootnode.GetElementsByTagName(KXMLFileString);
+    XMLSize_t childcount = childs->getLength();
+#ifndef NO_DBG
+    DEBUG_PRINT("preAnalyseGenerateMaps: Files to analyse: ")
+    DEBUG_PRINT(childcount)
+    DEBUG_PRINT("\n")
+#endif
+
+    unsigned int i = 0;
+    for (i = 0; i < childcount; ++i)
+    {
+        DOMNode* child = childs->item(i);
+        HANodeIterator childit(rootnode);
+        childit.current = child;
+        bool filetoanalyse = false;
+        const XMLCh* filename = childit.GetAttribute(KXMLNameString);
+        list<string>::const_iterator it = filesToAnalyse.begin();
+        int i = 0;
+        for (;it != filesToAnalyse.end(); ++it)
+        {
+            if ( CompareFileNames((*it),toString(filename)) )
+            {
+                filetoanalyse = true;
+                break;
+            }
+            ++i;
+        }
+        childit.IndexFileNode(filetoanalyse);
+    }
+#ifndef NO_DBG
+    DEBUG_PRINT("****************preAnalyse: Generating file maps END*********************\n")
+    DEBUG_STUFF(time_t endtime = time(NULL);)
+    DEBUG_STUFF(time_t runningtime = endtime - starttime;)
+    DEBUG_PRINT("ELAPSED TIME: ")
+    DEBUG_PRINT((long)runningtime)
+    DEBUG_PRINT("\n")
+#endif
+
+    preAnalyseGenerateMaps(rootnode,baseline);
+
+    //rootnode.iNodeIndex.DumpTables();
+
+#ifndef NO_DBG
+    DEBUG_PRINT("****************preAnalyse: Preanalysing classes*********************\n")
+    DEBUG_STUFF(time_t starttime2 = time(NULL);)
+    DEBUG_PRINT("preAnalyse: Nodes to analyse: ")
+    DEBUG_PRINT(childcount)
+    DEBUG_PRINT("\n")
+#endif
+
+    DOMDocument * doc =  rootnode->getOwnerDocument();
+    DOMNodeIterator * domit = doc->createNodeIterator (rootnode.current,DOMNodeFilter::SHOW_ELEMENT, NULL, true);
+    DOMNode * it = NULL;
+    while ( NULL != (it = domit->nextNode()) )
+    {
+        HANodeIterator childit(rootnode);
+        childit.current = it;
+#ifdef _DEBUG
+        // printNode(childit);
+        // Keep commented, too much stuff to print
+#endif      
+        const XMLCh * nodename = childit->getNodeName();
+        if ( DOMNode::ELEMENT_NODE == childit->getNodeType() && childit.toBeAnalysed() && 
+             ( Equals(nodename,KXMLClassString) || Equals(nodename,KXMLStructString)
+			 || Equals(nodename,KXMLUnionString))
+           )
+        {
+            preAnalyseClass(childit);
+        }
+    }
+    
+#ifndef NO_DBG
+    DEBUG_PRINT("****************preAnalyse: Preanalysing classes END*********************\n")
+    DEBUG_STUFF(time_t endtime2 = time(NULL);)
+    DEBUG_STUFF(time_t runningtime2 = endtime2 - starttime2;)
+    DEBUG_PRINT("ELAPSED TIME: ")
+    DEBUG_PRINT((long)runningtime2)
+    DEBUG_PRINT("\n")
+#endif
+}
+
+// ----------------------------------------------------------------------------
+// BBCAnalyser::nodeAnalyseTrees
+// ----------------------------------------------------------------------------
+//
+int BBCAnalyser::nodeAnalyseTrees(HANodeIterator baseline, HANodeIterator current,const list< pair<string,string> >& filesToAnalyse)
+{
+    //Find out the files to be processed
+    short nodetype = baseline->getNodeType();    
+    assert(nodetype == DOMNode::ELEMENT_NODE);
+    nodetype = current->getNodeType();    
+    assert(nodetype == DOMNode::ELEMENT_NODE);
+
+    int ret = 0;
+
+    DOMDocument * doc =  baseline->getOwnerDocument();
+    DOMNodeIterator * domit = doc->createNodeIterator (baseline.current,DOMNodeFilter::SHOW_ELEMENT, NULL, true);
+    DOMNode * it = NULL;
+
+    while ( NULL != (it = domit->nextNode()) )
+    {
+        HANodeIterator childit(baseline);
+        childit.current = it;
+
+         if (IsNamedNode(childit) && IsProperNode(childit) && childit.toBeAnalysed())
+        {
+            if ( !CheckAccessibility(childit) )
+            {
+                //The node is not visible, so no need to analyse
+                continue;
+            }
+            HANodeIterator currentit(current);
+			
+            const XMLCh* name = childit.GetAttribute(KXMLNameString);
+            if ( StartsWith(name,KXMLInternalNamePrefix) )
+            {
+                //Skip compiler generated pseudo elements
+                continue;
+            }
+            
+            const XMLCh* id = childit.GetAttribute(KXMLIdString);
+            DEBUG_PRINT("Analysing:")
+            if ( name )
+            {
+                DEBUG_PRINT_XMLCh(name)
+            }
+            if ( id )
+            {
+                DEBUG_PRINT(":")
+                DEBUG_PRINT_XMLCh(id)
+            }
+            DEBUG_PRINT("\n")
+
+
+            NodeAnalysis::Constructor constructorfunction = FindNodeAnalysisConstructor(childit->getNodeName());
+            NodeAnalysis * analyser = constructorfunction();
+        
+            ret += analyser->FindNodeAndAnalyse(childit,currentit);
+            delete analyser;			
+        }
+    }
+
+    return ret;
+}
+
+// ----------------------------------------------------------------------------
+// BBCAnalyser::analyseTrees
+// ----------------------------------------------------------------------------
+//
+int BBCAnalyser::analyseTrees(DOMNode* baseline, DOMNode* current,const list< pair<string,string> >& filesToAnalyse, const list<string>& aMacroFiles)
+{
+#ifndef NO_DBG
+    DEBUG_PRINT("****************Analyse: ANALYSE starts*********************\n")
+    DEBUG_STUFF(time_t starttime = time(NULL);)
+#endif
+
+    iBaselineIndex.clear();
+    iCurrentIndex.clear();
+    
+    HANodeIterator baselineit(baseline,iBaselineIndex,iReport, filesToAnalyse, true );
+    HANodeIterator currentit(current,iCurrentIndex,iReport, filesToAnalyse, false);
+    
+    list<string> basefiles, currentfiles;
+    list< pair<string,string> >::const_iterator it = filesToAnalyse.begin();
+    
+    for (; it != filesToAnalyse.end(); ++it)
+    {
+        basefiles.push_back((*it).first);
+        currentfiles.push_back((*it).second);
+    }
+
+    preAnalysis.preAnalyse(baselineit,basefiles,true);
+    preAnalysis.preAnalyse(currentit,currentfiles,false);
+
+    vector<bool> bfilefound;
+    bfilefound = checkForEmptyFiles(baselineit,basefiles,aMacroFiles);
+    
+    vector<bool> cfilefound;
+    cfilefound = checkForEmptyFiles(currentit,currentfiles,aMacroFiles);
+
+    list<pair<string,string> >::const_iterator fileit = filesToAnalyse.begin();
+    size_t i = 0;
+
+    for (i=0;i < bfilefound.size(); ++i,++fileit)
+    {
+        if ( !cfilefound[i] && !bfilefound[i] )
+        {
+            // Serious problem, the analysed file is not in the GCCXML output
+            iReport.addIssue(fileit->first,"", EIssueIdentityFile, EIssueTypeEmpty, 
+            BCseverityAccessible<EIssueIdentityFile,EIssueTypeEmpty>(true), SCseverityAccessible<EIssueIdentityFile,EIssueTypeEmpty>(true), "", 0, fileit->second, "");
+        }
+        else if ( !bfilefound[i] )
+        {
+            // Serious problem, the analysed file is not in the GCCXML output
+            iReport.addIssue(fileit->first,"", EIssueIdentityFile, EIssueTypeEmpty, 
+            BCseverityAccessible<EIssueIdentityFile,EIssueTypeEmpty>(true), SCseverityAccessible<EIssueIdentityFile,EIssueTypeEmpty>(true), "", 0, fileit->second, "");
+        }
+        else if ( !cfilefound[i])
+        {
+            // Serious problem, the analysed file is not in the GCCXML output
+            iReport.addIssue(fileit->first,"", EIssueIdentityFile, EIssueTypeEmpty, 
+				    BCseverityAccessible<EIssueIdentityFile,EIssueTypeEmpty>(true), SCseverityAccessible<EIssueIdentityFile,EIssueTypeEmpty>(true), "", 0, fileit->second, "",false);
+        }
+    }
+
+    //baselineit.iNodeIndex.DumpTables();
+    //currentit.iNodeIndex.DumpTables();
+
+#ifndef NO_DBG
+    DEBUG_PRINT("****************nodeAnalyse: Analysing*********************\n")
+    DEBUG_STUFF(time_t starttime2 = time(NULL);)
+#endif
+
+    int ret = nodeAnalyseTrees(baselineit, currentit, filesToAnalyse);
+#ifndef NO_DBG
+    DEBUG_STUFF(time_t endtime2 = time(NULL);)
+    DEBUG_STUFF(time_t runningtime2 = endtime2- starttime2;)
+    DEBUG_PRINT("****************nodeAnalyse: Analysing END*********************\n")
+    DEBUG_PRINT("ELAPSED TIME: ")
+    DEBUG_PRINT((long)runningtime2)
+    DEBUG_PRINT("\n")
+
+    DEBUG_PRINT("****************Analyse: ANALYSE END*********************\n")
+    DEBUG_STUFF(time_t endtime = time(NULL);)
+    DEBUG_STUFF(time_t runningtime = endtime - starttime;)
+    DEBUG_PRINT("ELAPSED TIME: ")
+    DEBUG_PRINT((long)runningtime)
+    DEBUG_PRINT("\n")
+#endif
+
+    return ret;
+}
+
+
+// ----------------------------------------------------------------------------
+// BBCAnalyser::BBCAnalyser
+// ----------------------------------------------------------------------------
+//
+BBCAnalyser::BBCAnalyser(ReportGenerator & report):
+iReport(report)
+{
+}
+
+
+// ----------------------------------------------------------------------------
+// NodeAnalysis::findNode
+// 
+// ----------------------------------------------------------------------------
+//
+DOMNode* NodeAnalysis::findNode(HANodeIterator nodetofind, HANodeIterator findfrom )
+{
+    DOMNode * ret = NULL;
+
+    pair<const XMLCh*,const XMLCh*> fqname = nodetofind.GetFullyQualifiedName();
+#ifndef NO_DBG
+    DEBUG_PRINT("Finding node from current three with fqname: ")
+    DEBUG_PRINT_XMLCh(fqname.first)
+    DEBUG_PRINT(" ... ")
+#endif
+
+    if ( findfrom.FindNodeByName(fqname) )
+    {
+        ret = findfrom.current;
+    }
+    return ret;
+}
+
+///////////////////////////////UnderConstructionNodeAnalysis////////////////////////////
+
+// ----------------------------------------------------------------------------
+// UnderConstructionNodeAnalysis::Construct
+// 
+// ----------------------------------------------------------------------------
+//
+NodeAnalysis* UnderConstructionNodeAnalysis::Construct()
+{
+    return new UnderConstructionNodeAnalysis();
+}
+
+
+// ----------------------------------------------------------------------------
+// UnderConstructionNodeAnalysis::Analyse
+// 
+// ----------------------------------------------------------------------------
+//
+int UnderConstructionNodeAnalysis::Analyse(HANodeIterator baseline,HANodeIterator current, bool report)
+{
+    assert(
+        Equals(baseline->getNodeName(), current->getNodeName())
+        );
+
+    if (report)
+    {
+        AddIssue<EIssueIdentityFile, EIssueTypeUnderConstruction>(&baseline, baseline,0);
+    }
+    return 1;
+}
+
+
+// ----------------------------------------------------------------------------
+// UnderConstructionNodeAnalysis::FindNodeAndAnalyse
+// 
+// ----------------------------------------------------------------------------
+//
+int UnderConstructionNodeAnalysis::FindNodeAndAnalyse(HANodeIterator baseline,HANodeIterator current)
+{
+    AddIssue<EIssueIdentityFile,EIssueTypeUnderConstruction>(&baseline,baseline,0);
+    return 1;
+}
+////////////////////////////////////////////////////////////////////////////////////////
+///////////////////////////////VariableNodeAnalysis/////////////////////////////////////
+
+
+// ----------------------------------------------------------------------------
+// VariableNodeAnalysis::Construct
+// ----------------------------------------------------------------------------
+//
+NodeAnalysis* VariableNodeAnalysis::Construct()
+{
+    return new VariableNodeAnalysis();
+}
+
+// ----------------------------------------------------------------------------
+// VariableNodeAnalysis::FindNodeAndAnalyse 
+// ----------------------------------------------------------------------------
+//
+int VariableNodeAnalysis::FindNodeAndAnalyse(HANodeIterator baseline,HANodeIterator current)
+{
+    DOMNode* node = NodeAnalysis::findNode(baseline,current);
+    if ( !node )
+    {
+        AddIssue<EIssueIdentityVariable, EIssueTypeRemoval>(&baseline, baseline,0);
+        return 1;
+    }
+    current.current = node;
+
+    return this->Analyse(baseline,current);
+}
+
+
+// ----------------------------------------------------------------------------
+// VariableNodeAnalysis::Analyse
+// ----------------------------------------------------------------------------
+//
+int VariableNodeAnalysis::Analyse(HANodeIterator baseline,HANodeIterator current, bool report)
+{
+    assert( Equals(KXMLVariableString, baseline->getNodeName()) &&
+        Equals(KXMLVariableString, current->getNodeName()) &&
+        Equals(baseline->getNodeName(), current->getNodeName())
+        );
+
+    int ret = 0;
+
+	int lineNo = 0;
+	const XMLCh* lineNumber = current.GetAttribute(KXMLLineString);
+	lineNo = atoi(toString(lineNumber).c_str());
+
+    if ( IsAnonymousType(baseline) )
+    {
+        //We need to to comparison between the baseline type and current type anonymously
+    
+        HANodeIterator baselinetypeit(baseline);
+        HANodeIterator currenttypeit(current);
+
+        const XMLCh* baselinetypeid = baseline.GetAttribute(KXMLTypeString);
+        const XMLCh* currenttypeid = current.GetAttribute(KXMLTypeString);
+
+        assert( baselinetypeid && currenttypeid);
+
+        bool ret1 = baselinetypeit.FindNodeById(baselinetypeid);
+        bool ret2 = currenttypeit.FindNodeById(currenttypeid);
+
+        assert(ret1 && ret2);
+
+        HANodeIterator baselinetypeanonit(baselinetypeit);
+        HANodeIterator currenttypeanonit(currenttypeit);
+        ret1 = FindAnonymousType(baselinetypeit,baselinetypeanonit);
+        ret2 = FindAnonymousType(currenttypeit,currenttypeanonit);
+        
+        assert(ret1);
+
+        if ( !ret2 || !baselinetypeanonit.IsSameNodeType(currenttypeanonit) )
+        {
+            if (report)
+            {
+                AddIssue<EIssueIdentityVariable, EIssueTypeChangeInType>(&baseline, current,lineNo);
+            }
+            ++ret;
+        }
+        else
+        {
+
+            NodeAnalysis::Constructor constructorfunction = FindNodeAnalysisConstructor(baselinetypeanonit->getNodeName());
+            NodeAnalysis * analyser = constructorfunction();
+            int ret = analyser->Analyse(baselinetypeanonit,currenttypeanonit,false);
+            if ( ret > 0 )
+            {
+                if (report)
+                {
+                    AddIssue<EIssueIdentityVariable, EIssueTypeChangeInType>(&baseline, current,lineNo);
+                }
+                ++ret;
+            }
+            delete analyser;
+        }
+    }
+    else
+    {
+        //{KXMLTypeString,EIdAttribute}
+        if ( !CompareAttributes(baseline,current,KXMLTypeString,ETypeAttribute) )
+        {
+            if (report)
+            {
+                AddIssue<EIssueIdentityVariable, EIssueTypeChangeInType>(&baseline, current,lineNo);
+            }
+            ++ret;
+        }
+    }
+
+    //{KXMLInitString,EOptionalSimpleAttribute}
+    if ( !CompareAttributes(baseline,current,KXMLInitString,EOptionalSimpleAttribute) )
+    {
+        if (report)
+        {
+            AddIssue<EIssueIdentityVariable, EIssueTypeChangeInInitialisation>(&baseline, current,lineNo);
+        }
+        ++ret;
+    }
+
+	if (!CheckAccessModifier(baseline,current))
+    {
+        if (report)
+        {
+            //AddIssue<iIdentity,EIssueTypeAccess>(&baseline, current);
+			AddIssue<EIssueIdentityVariable,EIssueTypeAccess>(&baseline, current,lineNo);
+        }
+        ret += 1;
+    }
+    
+    return ret;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+///////////////////////////////EnumNodeAnalysis/////////////////////////////////////////
+
+// ----------------------------------------------------------------------------
+// EnumNodeAnalysis::Construct
+// 
+// ----------------------------------------------------------------------------
+//
+NodeAnalysis* EnumNodeAnalysis::Construct()
+{
+    return new EnumNodeAnalysis;
+}
+
+// ----------------------------------------------------------------------------
+// EnumNodeAnalysis::FindNodeAndAnalyse
+// 
+// ----------------------------------------------------------------------------
+//
+int EnumNodeAnalysis::FindNodeAndAnalyse(HANodeIterator baseline,HANodeIterator current)
+{
+    int ret = 0;
+    if ( IsAnonymous(baseline) )
+    {
+        DOMNodeList* enumchilds = baseline.GetElementsByTagName(KXMLEnumValueString);
+        XMLSize_t enumchildcount = enumchilds->getLength();
+        unsigned int i = 0;
+        for (i = 0; i < enumchildcount; ++i)
+        {
+			int lineNo = 0;
+            HANodeIterator enumchildit(baseline);
+            enumchildit.current = enumchilds->item(i);
+            
+            DOMNode* node = NodeAnalysis::findNode(enumchildit,current);
+            if ( !node )
+            {
+                AddIssue<EIssueIdentityEnumerationValue,EIssueTypeRemoval>(&enumchildit, enumchildit, 0, baseline.GetAttribute(KXMLFileIdString));
+                ++ret;
+                continue;
+            }
+            current.current = node;
+			DOMNode* parentnode = node->getParentNode();
+			const XMLCh* lineNumber = GetAttribute(parentnode,KXMLLineString);
+			lineNo = atoi(toString(lineNumber).c_str());
+
+            if ( !CheckEnumValue(enumchildit,current) )
+            {
+                AddIssue<EIssueIdentityEnumerationValue,EIssueTypeChangeInInitialisation>(&enumchildit, current, lineNo, baseline.GetAttribute(KXMLFileIdString));
+                ++ret;
+            }
+			HANodeIterator currentparent(current);
+			if ( FindParentContext(current, currentparent))
+			{
+				if ( !CheckAccessModifier(baseline,currentparent) )
+				{
+					AddIssue<EIssueIdentityEnumerationValue,EIssueTypeAccess>(&enumchildit, current, lineNo, baseline.GetAttribute(KXMLFileIdString));
+					++ret;
+				}
+			}
+        }
+    }
+    else
+    {
+
+         DOMNode* node = NodeAnalysis::findNode(baseline,current);
+        if ( !node )
+        {
+            AddIssue<EIssueIdentityEnumeration,EIssueTypeRemoval>(&baseline, baseline,0);
+            return 1;
+        }
+        current.current = node;
+
+        ret += this->Analyse(baseline,current);
+    }
+    return ret;
+}
+
+
+// ----------------------------------------------------------------------------
+// EnumNodeAnalysis::CheckEnumValue
+// 
+// ----------------------------------------------------------------------------
+//
+bool EnumNodeAnalysis::CheckEnumValue(HANodeIterator baseline,HANodeIterator current)
+{
+
+    return CompareNodes(baseline,current);
+}
+
+// ----------------------------------------------------------------------------
+// EnumNodeAnalysis::Analyse
+// 
+// ----------------------------------------------------------------------------
+//
+int EnumNodeAnalysis::Analyse(HANodeIterator baseline,HANodeIterator current, bool report)
+{
+    assert( Equals(KXMLEnumerationString, baseline->getNodeName()) &&
+            Equals(KXMLEnumerationString, current->getNodeName()) &&
+            Equals(baseline->getNodeName(), current->getNodeName())
+            );
+
+
+    int ret = 0;
+	int lineNo = 0;
+	const XMLCh* lineNumber = current.GetAttribute(KXMLLineString);
+	lineNo = atoi(toString(lineNumber).c_str());
+
+    //{KXMLAlignString,ESimpleAttribute}
+    if ( !CompareAttributes(baseline,current,KXMLAlignString,ESimpleAttribute) )
+    {
+        if (report)
+        {
+            AddIssue<EIssueIdentityEnumeration,EIssueTypeAlign>(&baseline, current,lineNo);
+        }
+        ++ret;
+    }
+
+    //{KXMLSizeString,ESimpleAttribute}
+    if ( !CompareAttributes(baseline,current,KXMLSizeString,ESimpleAttribute) )
+    {
+        if (report)
+        {
+            AddIssue<EIssueIdentityEnumeration,EIssueTypeSize>(&baseline, current,lineNo);
+        }
+        ++ret;
+    }
+
+	if (!CheckAccessModifier(baseline,current))
+    {
+        if (report)
+        {
+            //AddIssue<iIdentity,EIssueTypeAccess>(&baseline, current);
+			AddIssue<EIssueIdentityEnumeration, EIssueTypeAccess>(&baseline, current,lineNo);
+        }
+        ++ret;
+    }
+
+    //Check the enum values
+    DOMNodeList* baselinechilds = baseline.GetElementsByTagName(KXMLEnumValueString);
+    DOMNodeList* currentchilds = current.GetElementsByTagName(KXMLEnumValueString);
+   
+    XMLSize_t baselinechildcount = baselinechilds->getLength();
+    XMLSize_t currentchildcount = currentchilds->getLength();
+
+    unsigned int i = 0;
+    for (i = 0; i < baselinechildcount; ++i)
+    {
+        HANodeIterator baselineit(baseline);
+        baselineit.current = baselinechilds->item(i);
+        unsigned int ii = 0;
+        for (ii = 0; ii < currentchildcount; ++ii)
+        {
+            HANodeIterator currentit(current);
+            currentit.current = currentchilds->item(ii);
+
+            if ( CompareAttributes(baselineit,currentit,KXMLNameString,ESimpleAttribute)  )
+            {
+                if ( !CompareAttributes(baselineit,currentit,KXMLInitString,ESimpleAttribute) )
+                {
+                    if (report)
+                    {
+                        AddIssue<EIssueIdentityEnumeration,EIssueTypeChange>(&baseline, current,lineNo);
+                    }
+                    ++ret;
+                    return ret;
+                }
+                break;
+            }
+
+        }
+
+        if ( currentchildcount == ii )
+        {
+
+            if (report)
+            {
+				AddIssue<EIssueIdentityEnumerationValue,EIssueTypeRemoval>(&baseline, current,lineNo);
+            }
+            ++ret;
+            return ret;
+        }
+    }
+
+    return ret;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+///////////////////////////////FunctionNodeAnalysis/////////////////////////////////////
+
+
+// ----------------------------------------------------------------------------
+// FunctionNodeAnalysis::FunctionNodeAnalysis
+// 
+// ----------------------------------------------------------------------------
+//
+FunctionNodeAnalysis::FunctionNodeAnalysis():
+iFuncType(EIssueIdentityExportedFunction)
+{
+}
+
+// ----------------------------------------------------------------------------
+// FunctionNodeAnalysis::Construct
+// 
+// ----------------------------------------------------------------------------
+//
+NodeAnalysis* FunctionNodeAnalysis::Construct()
+{
+    return new FunctionNodeAnalysis;
+}
+
+// ----------------------------------------------------------------------------
+// FunctionNodeAnalysis::FindNodeAndAnalyse
+// 
+// ----------------------------------------------------------------------------
+//
+int FunctionNodeAnalysis::FindNodeAndAnalyse(HANodeIterator baseline,HANodeIterator current)
+{
+    if ( baseline.CheckForBooleanAttribute(KXMLInlineString) )
+    {
+        iFuncType = EIssueIdentityInlineFunction;
+    }
+
+    //Check first if the function is exported
+    const XMLCh* attributeValue = baseline.GetAttribute(KXMLAttributeString);                            
+
+    if ( (iFuncType == EIssueIdentityInlineFunction) || (attributeValue && Equals(attributeValue,KXMLExportedString)) )
+    {
+        DOMNode* node = NodeAnalysis::findNode(baseline,current);
+        if ( !node )
+        {
+			//AddIssue<iFuncType,EIssueTypeRemoval>(&baseline, baseline);
+            AddIssueFunction<EIssueTypeRemoval>(&baseline,iFuncType,baseline,0);
+            return 1;
+        }
+        current.current = node;
+
+        return this->Analyse(baseline,current);
+    }
+    
+    return 0;
+}
+
+// ----------------------------------------------------------------------------
+// FunctionNodeAnalysis::Analyse
+// 
+// ----------------------------------------------------------------------------
+//
+int FunctionNodeAnalysis::Analyse(HANodeIterator baseline,HANodeIterator current, bool report)
+{
+    assert( 
+    Equals(baseline->getNodeName(), current->getNodeName())
+    );
+
+    int ret = 0;
+//<!ELEMENT FunctionType (Argument | Ellipsis)*>
+//<!ATTLIST FunctionType attributes CDATA #IMPLIED>
+//<!ATTLIST FunctionType id ID #REQUIRED>
+//<!ATTLIST FunctionType returns IDREF #REQUIRED>
+
+	int lineNo = 0;
+	const XMLCh* lineNumber = current.GetAttribute(KXMLLineString);
+	lineNo = atoi(toString(lineNumber).c_str());
+
+    const XMLCh* attributeValue = current.GetAttribute(KXMLAttributeString);                            
+    if (
+        (
+            (iFuncType == EIssueIdentityInlineFunction) && !current.CheckForBooleanAttribute(KXMLInlineString) 
+        ) ||
+        ( 
+            (iFuncType == EIssueIdentityExportedFunction) && (!attributeValue || !Equals(attributeValue,KXMLExportedString) )
+            &&
+            (!current.CheckForBooleanAttribute(KXMLVirtualString))
+        )
+       )
+    {
+        if (report)
+        {
+			AddIssueFunction<EIssueTypeRemoval>(&baseline,iFuncType,baseline,0);
+
+        }
+        ++ret;
+        return ret;
+    }
+    
+    string basefuncsig = GenerateFunctionSignature(baseline);
+    string currentfuncsig = GenerateFunctionSignature(current);
+
+    if ( basefuncsig != currentfuncsig )
+    {
+        ++ret;
+        if (report)
+        {
+			AddIssueFunction<EIssueTypeParam>(&baseline,iFuncType,current,lineNo);
+        }
+    }
+    else
+    {
+        //Check also the default parameter values
+        DOMElement * baselineelement = static_cast<DOMElement*>(baseline.current);
+        DOMNodeList* baselinechilds = baselineelement->getChildNodes();
+        DOMElement * currentelement = static_cast<DOMElement*>(current.current);
+        DOMNodeList* currentchilds = currentelement->getChildNodes();
+        
+        XMLSize_t childcount = baselinechilds->getLength();
+
+        unsigned int i = 0;
+        for (i = 0; i < childcount; ++i)
+        {
+            DOMNode* baselinechild = baselinechilds->item(i);
+            HANodeIterator baselinechildit(baseline);
+            baselinechildit.current = baselinechild;
+
+            DOMNode* currentchild = currentchilds->item(i);
+            HANodeIterator currentchildit(current);
+            currentchildit.current = currentchild;
+
+            short nodetype = baselinechildit->getNodeType();
+            if (nodetype == DOMNode::ELEMENT_NODE)
+            {
+				const XMLCh * baselinesize = FindAttributeValueForType(baselinechildit,KXMLSizeString);
+				const XMLCh * currentsize = FindAttributeValueForType(currentchildit,KXMLSizeString);
+
+				const XMLCh * baselinealign = FindAttributeValueForType(baselinechildit,KXMLAlignString);
+				const XMLCh * currentalign = FindAttributeValueForType(currentchildit,KXMLAlignString);
+
+				if ( !baselinesize )
+				{
+					baselinesize = baselinealign;
+				}
+					
+				if ( !currentsize )
+				{
+					currentsize = currentalign;
+				}
+
+				if ( !Equals(baselinesize,currentsize) || !Equals(baselinealign, currentalign) ||
+					!CompareAttributes(baselinechildit,currentchildit,KXMLDefaultString,EOptionalSimpleAttribute))
+				{
+                    ++ret;
+                    if (report)
+                    {
+                        //AddIssue<iFuncType,EIssueTypeParam>(&baseline, current);
+						AddIssueFunction<EIssueTypeParam>(&baseline,iFuncType,current,lineNo);
+                    }
+                    break;
+				}
+            }
+
+        }
+
+    }
+
+    if ( !CompareAttributes(baseline,current,KXMLReturnsString,EOptionalTypeAttribute) )
+    {
+        ++ret;
+        if (report)
+        {
+			AddIssueFunction<EIssueTypeReturn>(&baseline,iFuncType,current,lineNo);
+        }
+    }
+
+    return ret;
+}
+
+
+////////////////////////////////////////////////////////////////////////////////////////
+///////////////////////////////TypedefNodeAnalysis/////////////////////////////////////
+
+
+// ----------------------------------------------------------------------------
+// TypedefNodeAnalysis::Construct
+// ----------------------------------------------------------------------------
+//
+NodeAnalysis* TypedefNodeAnalysis::Construct()
+{
+    return new TypedefNodeAnalysis;
+}
+
+// ----------------------------------------------------------------------------
+// TypedefNodeAnalysis::FindNodeAndAnalyse
+// ----------------------------------------------------------------------------
+//
+int TypedefNodeAnalysis::FindNodeAndAnalyse(HANodeIterator baseline,HANodeIterator current)
+{
+     DOMNode* node = NodeAnalysis::findNode(baseline,current);
+    if ( !node )
+    {
+        AddIssue<EIssueIdentityTypedef,EIssueTypeRemoval>(&baseline, baseline,0);
+        return 1;
+    }
+    current.current = node;
+
+    return this->Analyse(baseline,current);
+}
+
+// ----------------------------------------------------------------------------
+// TypedefNodeAnalysis::Analyse
+// ----------------------------------------------------------------------------
+//
+int TypedefNodeAnalysis::Analyse(HANodeIterator baseline,HANodeIterator current, bool report)
+{
+    assert( Equals(KXMLTypedefString, baseline->getNodeName()) &&
+    Equals(KXMLTypedefString, current->getNodeName()) &&
+    Equals(baseline->getNodeName(), current->getNodeName())
+    );
+
+  //<Typedef id="_9" name="TOmaInt" type="_8" context="_1" location="f0:108" file="f0" line="108"/>
+
+	int lineNo = 0;
+	const XMLCh* lineNumber = current.GetAttribute(KXMLLineString);
+	lineNo = atoi(toString(lineNumber).c_str());
+
+    int ret = 0;
+
+    if ( !CompareAttributes(baseline,current,KXMLNameString,ESimpleAttribute) )
+    {
+        if (report)
+        {
+            AddIssue<EIssueIdentityTypedef,EIssueTypeChange>(&baseline, current,lineNo);
+        }
+        ++ret;
+    }
+
+    if ( !CompareAttributes(baseline,current,KXMLTypeString,ETypeAttribute) )
+    {
+        if (report)
+        {
+            AddIssue<EIssueIdentityTypedef,EIssueTypeChange>(&baseline, current,lineNo);
+        }
+        ++ret;
+    }
+
+    HANodeIterator baselinetypeit(baseline);
+    HANodeIterator currenttypeit(current);
+
+    const XMLCh* baselinetypeid = baseline.GetAttribute(KXMLTypeString);
+    const XMLCh* currenttypeid = current.GetAttribute(KXMLTypeString);
+
+    assert( baselinetypeid && currenttypeid);
+
+    bool ret1 = baselinetypeit.FindNodeById(baselinetypeid);
+    bool ret2 = currenttypeit.FindNodeById(currenttypeid);
+
+    assert(ret1 && ret2);
+
+	if ( IsFunction(baselinetypeit) )
+	{
+		if ( !CompareAttributes(baselinetypeit,currenttypeit,KXMLReturnsString,EOptionalTypeAttribute) )
+		{
+			if (report)
+			{
+				AddIssue<EIssueIdentityTypedef,EIssueTypeChange>(&baseline, current,lineNo);
+			}
+			++ret;
+		}
+	}
+
+	if (!CheckAccessModifier(baseline,current))
+    {
+        if (report)
+        {
+            //AddIssue<iIdentity,EIssueTypeAccess>(&baseline, current);
+            AddIssue<EIssueIdentityTypedef,EIssueTypeAccess>(&baseline, current,lineNo);
+        }
+        ret += 1;
+    }
+
+    return ret;
+}
+
+
+////////////////////////////////////////////////////////////////////////////////////////
+///////////////////////////////OperatorFunctionNodeAnalysis/////////////////////////////
+
+// ----------------------------------------------------------------------------
+// OperatorFunctionNodeAnalysis::Construct
+// ----------------------------------------------------------------------------
+//
+NodeAnalysis* OperatorFunctionNodeAnalysis::Construct()
+{
+    return new OperatorFunctionNodeAnalysis;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+///////////////////////////////UnionNodeAnalysis////////////////////////////////////////
+
+// ----------------------------------------------------------------------------
+// UnionNodeAnalysis::Construct
+// ----------------------------------------------------------------------------
+//
+NodeAnalysis* UnionNodeAnalysis::Construct()
+{
+    return new UnionNodeAnalysis;
+}
+
+// ----------------------------------------------------------------------------
+// UnionNodeAnalysis::UnionNodeAnalysis
+// 
+// ----------------------------------------------------------------------------
+//
+UnionNodeAnalysis::UnionNodeAnalysis()
+{
+	iIdentity = EIssueIdentityUnion;
+}
+
+// ----------------------------------------------------------------------------
+// UnionNodeAnalysis::compareBaseSizes
+// ----------------------------------------------------------------------------
+//
+int UnionNodeAnalysis::compareBaseSizes(HANodeIterator baseline, HANodeIterator current, const NodeIndex::dtable_t& bfields, const NodeIndex::dtable_t& cfields, bool report)
+{
+	//Not meaningful in union as it can not be derived
+	return 0;
+}
+
+// ----------------------------------------------------------------------------
+// UnionNodeAnalysis::FindNodeAndAnalyse
+// ----------------------------------------------------------------------------
+//
+int UnionNodeAnalysis::FindNodeAndAnalyse(HANodeIterator baseline,HANodeIterator current)
+{
+    //First check to see if this is an anonymous Union
+    const XMLCh* name = baseline.GetAttribute(KXMLNameString);
+    if ( !name )
+    {
+        //This is anonymous union and does not need to be analysed
+        return 0;
+    }
+    
+    if ( Equals(name,KXMLEmptyString) )
+    {
+        return 0;
+    }
+
+    DOMNode* node = NodeAnalysis::findNode(baseline,current);
+
+    if ( !node )
+    {
+        AddIssue<EIssueIdentityUnion,EIssueTypeRemoval>(&baseline, baseline,0);
+        return 1;
+    }
+    current.current = node;
+
+    return this->Analyse(baseline,current);
+}
+
+// ----------------------------------------------------------------------------
+// UnionNodeAnalysis::compareVirtualFunctions
+// The union can not have virtual functions
+// ----------------------------------------------------------------------------
+//
+int UnionNodeAnalysis::compareVirtualFunctions(HANodeIterator baseline,HANodeIterator current, 
+                                                  const vector<DOMNode*>& bvirtualMethods, 
+												  const vector<DOMNode*>& cvirtualMethods, 
+                                                  bool report)
+{
+	return 0;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+///////////////////////////////ClassNodeAnalysis////////////////////////////////////////
+
+// ----------------------------------------------------------------------------
+// printMember
+// Debug stuff
+// ----------------------------------------------------------------------------
+//
+void printMember(HANodeIterator member)
+{
+    DEBUG_PRINT_XMLCh(member->getNodeName());
+    DEBUG_PRINT(":");
+    const XMLCh * memname = member.GetAttribute(KXMLNameString);
+    if (memname)
+    {
+        DEBUG_PRINT_XMLCh(memname);
+    }
+}
+
+// ----------------------------------------------------------------------------
+// ClassNodeAnalysis::compareMethodsSignature
+// Compare baseline and current methods and return false if they do not match.
+// Uses additional comparator object if available.
+// ----------------------------------------------------------------------------
+//
+bool ClassNodeAnalysis::compareMethodsSignature(HANodeIterator basemethod,HANodeIterator currentmethod, const NodeTypeComparator& comparator)
+{
+    short basenodetype = basemethod->getNodeType();
+    short currnodetype = currentmethod->getNodeType();
+    assert(basenodetype == DOMNode::ELEMENT_NODE && currnodetype == DOMNode::ELEMENT_NODE);
+    assert(IsFunction(basemethod) && IsFunction(currentmethod));
+
+#ifdef _DEBUG
+    string basefuncsig = GenerateFunctionSignature(basemethod);
+    string currentfuncsig = GenerateFunctionSignature(currentmethod);
+    cout << "   basefuncsig=" << basefuncsig << endl;
+    cout << "currentfuncsig=" << currentfuncsig << endl;
+#endif
+
+    if( !Equals(basemethod->getNodeName(), currentmethod->getNodeName() ))
+    {
+        return false;
+    }
+
+    const XMLCh* basenameatt = basemethod.GetAttribute(KXMLNameString);
+    const XMLCh* currnameatt = currentmethod.GetAttribute(KXMLNameString);
+
+    if( !Equals(basenameatt, currnameatt ))
+    {
+        return false;
+    }
+
+    DOMElement * basenodeelement = static_cast<DOMElement*>(basemethod.current);
+    DOMElement * currnodeelement = static_cast<DOMElement*>(currentmethod.current);    
+    std::vector<DOMNode*> baseElementNodes;
+    std::vector<DOMNode*> currElementNodes;
+    GetElementNodes(basemethod, basenodeelement->getChildNodes(), baseElementNodes);
+    GetElementNodes(currentmethod, currnodeelement->getChildNodes(), currElementNodes);    
+
+    if( baseElementNodes.size() != currElementNodes.size() )
+    {
+        return false;
+    }
+
+    for(size_t i = 0; i < baseElementNodes.size(); ++i)
+    {
+        DOMNode* basechild = baseElementNodes[i];
+        DOMNode* currchild = currElementNodes[i];
+        HANodeIterator basechildit(basemethod);
+        HANodeIterator currchildit(currentmethod);
+        basechildit.current = basechild;
+        currchildit.current = currchild;
+        
+        short basetype = basechildit->getNodeType();
+        short currtype = currchildit->getNodeType();
+        if( !comparator.CompareParameter(basechildit, currchildit) )
+        {
+            return false;
+        }        
+    }
+    
+    if( !comparator.CompareConstness(basemethod, currentmethod) )
+    {
+        return false;
+    }
+
+    return true;
+}
+// ----------------------------------------------------------------------------
+// ClassNodeAnalysis::compareMethodsReturn
+// ----------------------------------------------------------------------------
+//
+bool ClassNodeAnalysis::compareMethodsReturn(HANodeIterator basemethod,HANodeIterator currentmethod, NodeTypeComparator& cmp) 
+{
+    return cmp.CompareReturnValue(basemethod, currentmethod);
+}
+
+// ----------------------------------------------------------------------------
+// ClassNodeAnalysis::compareField
+// ----------------------------------------------------------------------------
+//
+int ClassNodeAnalysis::compareField(HANodeIterator baseline, HANodeIterator current, const DataMember& basemember,const DataMember& currentmember, bool report)
+{
+	//<!ATTLIST Field mutable (0 | 1) "0">
+	//<!ATTLIST Field name CDATA #REQUIRED>
+	//<!ATTLIST Field offset CDATA #IMPLIED>
+	//<!ATTLIST Field type CDATA #REQUIRED>
+	int ret = 0;
+
+	HANodeIterator basefield(baseline);
+	basefield.current = basemember.iNode;
+	HANodeIterator currentfield(current);
+	currentfield.current = currentmember.iNode;
+	
+	int baseoffset = basemember.iOffset;
+    int currentoffset = currentmember.iOffset;
+
+	TIssueIdentity identity = EIssueIdentityField;
+	bool accessthroughinline = false;
+
+	if ( !CheckAccessibility(baseline,accessthroughinline,basemember.iAccess) )
+	{
+		identity = EIssueIdentityFieldInaccessible;
+	} else
+	{
+
+		if ( baseoffset != currentoffset )
+		{
+			ret++;
+			if ( report )
+			{
+				AddIssueField<EIssueTypeOffset>(&baseline,identity, currentfield,currentmember.iLineNo,NULL,basemember);
+			}
+			else
+			{
+				return ret;
+			}
+
+		}
+	}
+
+	if ( IsAnonymousType(basefield) )
+    {
+        //We need to do comparison between the baseline type and current type anonymously
+    
+        HANodeIterator baselinetypeit(basefield);
+        HANodeIterator currenttypeit(currentfield);
+
+        const XMLCh* baselinetypeid = basefield.GetAttribute(KXMLTypeString);
+        const XMLCh* currenttypeid = currentfield.GetAttribute(KXMLTypeString);
+
+        assert( baselinetypeid && currenttypeid);
+
+        bool ret1 = baselinetypeit.FindNodeById(baselinetypeid);
+        bool ret2 = currenttypeit.FindNodeById(currenttypeid);
+
+        assert(ret1 && ret2);
+
+        HANodeIterator baselinetypeanonit(baselinetypeit);
+        HANodeIterator currenttypeanonit(currenttypeit);
+        ret1 = FindAnonymousType(baselinetypeit,baselinetypeanonit);
+        ret2 = FindAnonymousType(currenttypeit,currenttypeanonit);
+        
+        assert(ret1);
+
+		if ( !ret2 || !baselinetypeanonit.IsSameNodeType(currenttypeanonit) )
+		{
+			if (report)
+			{
+				AddIssueField<EIssueTypeChangeInType>(&baseline,identity, currentfield,currentmember.iLineNo,NULL,basemember);
+			}
+			ret++;
+		}
+		else
+		{
+			bool report2 = false;
+
+            if ( Equals(KXMLUnionString, baselinetypeit->getNodeName()) && Equals(KXMLEmptyString, basefield.GetAttribute(KXMLNameString)) )
+            {
+                report2 = report;
+            }
+
+			NodeAnalysis::Constructor constructorfunction = FindNodeAnalysisConstructor(baselinetypeanonit->getNodeName());
+			NodeAnalysis * analyser = constructorfunction();
+			int retval2 = analyser->Analyse(baselinetypeanonit,currenttypeanonit,report2);
+			if ( retval2 > 0 && !report2)
+			{
+				if (report)
+				{
+					AddIssueField<EIssueTypeChangeInType>(&baseline,identity, currentfield,currentmember.iLineNo,NULL,basemember);
+				}
+				++ret;
+            }
+            delete analyser;
+        }
+    }
+    else
+    {
+        //{KXMLTypeString,EIdAttribute}
+        if ( !CompareAttributes(basefield,currentfield,KXMLTypeString,ETypeAttribute) )
+        {
+			ret++;
+			if ( report )
+			{
+				AddIssueField<EIssueTypeChangeInType>(&baseline,identity, currentfield,currentmember.iLineNo,NULL,basemember);
+			}
+			else
+			{
+				return ret;
+			}
+		}else //Check if the size has changed although the the type has remained same
+		{
+			const XMLCh* basefieldsize = GetSize(basefield);
+			const XMLCh* currentfieldsize = GetSize(currentfield);
+
+			if ( !Equals(basefieldsize,currentfieldsize) )
+			{
+				ret++;
+				if ( report )
+				{
+					AddIssueField<EIssueTypeSize>(&baseline,identity, currentfield,currentmember.iLineNo,NULL,basemember);
+				}
+				else
+				{
+					return ret;
+				}
+			}
+
+		}
+    }
+    return ret;
+}
+
+// ----------------------------------------------------------------------------
+// dumpNodeVectordumpNodeVector
+// ----------------------------------------------------------------------------
+//
+void dumpNodeVector(HANodeIterator node,const vector<DOMNode*> & nodes)
+{
+    DEBUG_PRINT("Dumping node vector:\n")
+    vector<DOMNode*>::const_iterator it = nodes.begin();
+    for (;it != nodes.end(); ++it)
+    {
+        node.current = (*it);
+
+        DEBUG_PRINT_XMLCh(node->getNodeName())
+        const XMLCh * name = node.GetAttribute(KXMLNameString);
+        if (name)
+        {
+        DEBUG_PRINT(":")
+        DEBUG_PRINT_XMLCh(name)
+        }
+        const XMLCh * id = node.GetAttribute(KXMLIdString);
+        if (id)
+        {
+        DEBUG_PRINT(" with id ")
+        DEBUG_PRINT_XMLCh(id)
+        }
+        DEBUG_PRINT("\n")
+    }
+}
+
+// ----------------------------------------------------------------------------
+// ClassNodeAnalysis::compareNonvirtualFunctions
+// ----------------------------------------------------------------------------
+//
+int ClassNodeAnalysis::compareNonvirtualFunctions( HANodeIterator baseline,
+                                                    HANodeIterator current, 
+                                                    const vector<DOMNode*>& bexportedMethods,
+                                                    const vector<DOMNode*>& cexportedMethods,
+                                                    TIssueIdentity identity,
+                                                    bool report )
+{
+    int ret = 0;
+	int parentLineNo = 0;
+
+    // Get default comparator:
+    const ComparatorVector& cmps = ComparatorFactory::Instance().GetComparators();       
+    ComparatorVector::const_iterator comparator = cmps.begin();
+	const XMLCh* parenLinenumber = current.GetAttribute( KXMLLineString);
+	parentLineNo = atoi(toString(parenLinenumber).c_str());
+
+    // Build method maps for baseline and current platform's classes:
+    MethodMatchMap baseMap;    
+    vector<DOMNode*>::const_iterator i = bexportedMethods.begin();
+    for( ; i != bexportedMethods.end(); ++i )
+    {
+        baseMap.insert( make_pair(*i, MethodMatchFlags(false, false)));
+    }
+
+    vector<DOMNode*>::const_iterator j = cexportedMethods.begin();
+    MethodMatchMap currMap;    
+    for( ; j != cexportedMethods.end(); ++j )
+    {
+        currMap.insert( make_pair(*j, MethodMatchFlags(false, false)));
+    }
+
+    if( comparator != cmps.end() )
+    {
+        int comparatorRound = 1;
+        // Call compare function and give the default comparator as a parameter
+        ret = this->compareNonvirtualFunctions(baseline, current, bexportedMethods, cexportedMethods, identity, report, comparator, baseMap, currMap, comparatorRound);        
+    }
+
+    if( report )
+    {
+        MethodMatchMap::iterator baseFunc = baseMap.begin();
+        for(; baseFunc != baseMap.end(); ++baseFunc )
+        {
+			int lineNo = 0;
+			string baseMethodName = toString(GetAttribute(baseFunc->first,KXMLNameString));
+			MethodMatchMap::iterator curFunc = currMap.begin();
+			for(; curFunc != currMap.end(); ++curFunc )
+			{
+				string curMethodName = toString(GetAttribute(curFunc->first,KXMLNameString));
+				if (baseMethodName == curMethodName)
+				{
+					const XMLCh* linenumber = GetAttribute(curFunc->first, KXMLLineString);
+					lineNo = atoi(toString(linenumber).c_str());
+					break;
+
+				}
+			}
+            if( baseFunc->second.signatureMatch == false )
+            {
+                // Function signatures do not match
+                HANodeIterator removedMethod(baseline);
+                removedMethod.current = baseFunc->first;
+                AddIssueFunction<EIssueTypeRemoval>(&removedMethod, identity, removedMethod,parentLineNo);            
+                ++ret;
+            }
+            else if( baseFunc->second.returnValueMatch == false )
+			{
+				// Function return values do not match
+				HANodeIterator removedMethod(baseline);
+				removedMethod.current = baseFunc->first;
+				AddIssueFunction<EIssueTypeReturn>(&removedMethod,identity, removedMethod,lineNo);                
+				++ret;
+			}
+        }
+    }
+    return ret;
+}
+// ----------------------------------------------------------------------------
+// ClassNodeAnalysis::compareNonvirtualFunctions
+// ----------------------------------------------------------------------------
+//
+int ClassNodeAnalysis::compareNonvirtualFunctions(
+        HANodeIterator baseline,
+        HANodeIterator current, 
+        const vector<DOMNode*>& bexportedMethods,
+        const vector<DOMNode*>& cexportedMethods,
+        TIssueIdentity identity,                                          
+        bool report,
+        ComparatorVector::const_iterator comparator,
+        MethodMatchMap& baseMap,
+        MethodMatchMap& currMap,
+		int comparatorRound)
+{
+    int ret = 0;
+
+	int lineNo1 = 0;
+	//const XMLCh* lineNumber = current.GetAttribute(KXMLLineString);
+	//lineNo = atoi(toString(lineNumber).c_str());
+
+	//Exported methods    
+	vector<DOMNode*>::const_iterator bIter = bexportedMethods.begin();        
+	for( ; bIter != bexportedMethods.end(); ++bIter )
+	{
+		MethodMatchMap::iterator baseMapIter = baseMap.find(*bIter);
+		assert(baseMapIter != baseMap.end());
+		if( baseMapIter->second.signatureMatch )
+		{
+			continue; // This method has already been found and analyzed.
+		}
+		HANodeIterator basemethod(baseline);        
+		basemethod.current = *bIter;
+
+		//Check the accessibility
+		if ( CheckAccessibility(basemethod) )
+		{            
+			vector<DOMNode*>::const_iterator cIter = cexportedMethods.begin();   
+
+			for( ; cIter != cexportedMethods.end(); ++cIter)            
+			{                
+				HANodeIterator currentmethod(current);
+				currentmethod.current = *cIter;
+				const XMLCh* lineNumber1 = GetAttribute(currentmethod.current,KXMLLineString);
+				lineNo1 = atoi(toString(lineNumber1).c_str());
+
+				MethodMatchMap::iterator currMapIter = currMap.find(*cIter);
+
+                if( currMapIter != currMap.end() && 
+                    currMapIter->second.signatureMatch == false &&
+                    compareMethodsSignature(basemethod, currentmethod, **comparator) )
+                {                    
+                    if( comparatorRound==CONSTFILTER_COMPARATOR )
+                    {                        
+                        // if one of the parameter has changed from non-const to const
+                        ret++;
+                        if(report)
+                        {
+                            //add the issue as it is a source compatibility break
+                            AddIssueFunction<EIssueTypeParamConst>(&basemethod,identity,currentmethod,lineNo1);
+                        }
+                        
+                        //make signature and return value true so that the issue is not reported again
+                        if( baseMapIter != baseMap.end() )
+                            baseMapIter->second.signatureMatch = true;
+                        currMapIter->second.signatureMatch = true;
+                        
+                        baseMapIter->second.returnValueMatch = true;
+                        currMapIter->second.returnValueMatch = true;
+                        break;
+                    }
+                    
+                    else if( comparatorRound==CONSTFILTER2_COMPARATOR )
+                    {                        
+                        // if one of the parameter has changed from const to non-const
+                        ret++;
+                        if(report)
+                        {
+                            //add the issue as it is a source compatibility break
+							AddIssueFunction<EIssueTypeParamConst2>(&basemethod,identity,currentmethod,lineNo1);
+                        }
+                        
+                        //make signature and return value true so that the issue is not reported again
+                        if( baseMapIter != baseMap.end() )
+                            baseMapIter->second.signatureMatch = true;
+                        currMapIter->second.signatureMatch = true;
+                        
+                        baseMapIter->second.returnValueMatch = true;
+                        currMapIter->second.returnValueMatch = true;
+                        break;
+                    }
+                    
+                    if( baseMapIter != baseMap.end() )
+                        baseMapIter->second.signatureMatch = true;
+                    currMapIter->second.signatureMatch = true;
+                    //Check also the default parameter values
+                    DOMElement * baselineelement = static_cast<DOMElement*>(basemethod.current);
+                    DOMNodeList* baselinechilds = baselineelement->getChildNodes();
+                    DOMElement * currentelement = static_cast<DOMElement*>(currentmethod.current);
+                    DOMNodeList* currentchilds = currentelement->getChildNodes();
+                        
+                    XMLSize_t childcount = baselinechilds->getLength();
+                    
+                    unsigned int i = 0;
+                    for (i = 0; i < childcount; ++i)
+                    {
+                        DOMNode* baselinechild = baselinechilds->item(i);
+                        HANodeIterator baselinechildit(baseline);
+                        baselinechildit.current = baselinechild;
+                         
+                        DOMNode* currentchild = currentchilds->item(i);
+                        HANodeIterator currentchildit(current);
+                        currentchildit.current = currentchild;
+                                
+                        short nodetype = baselinechildit->getNodeType();
+                        if (nodetype == DOMNode::ELEMENT_NODE)
+                        {
+                            const XMLCh * baselinesize = FindAttributeValueForType(baselinechildit,KXMLSizeString);
+                            const XMLCh * currentsize = FindAttributeValueForType(currentchildit,KXMLSizeString);
+                               
+                            const XMLCh * baselinealign = FindAttributeValueForType(baselinechildit,KXMLAlignString);
+                            const XMLCh * currentalign = FindAttributeValueForType(currentchildit,KXMLAlignString);
+                                  
+                            if ( !baselinesize )
+                            {
+                                baselinesize = baselinealign;
+                            }
+                                 
+                            if ( !currentsize )
+                            {
+                                currentsize = currentalign;
+                            }
+                                 
+                            if ( !Equals(baselinesize,currentsize) || !Equals(baselinealign, currentalign) ||
+                                 !CompareAttributes(baselinechildit,currentchildit,KXMLDefaultString,EOptionalSimpleAttribute))
+                            {
+                                 ++ret;
+                                 if (report)
+                                 {
+									AddIssueFunction<EIssueTypeParam>(&basemethod,identity,currentmethod,lineNo1);
+                                 }
+                                 break;
+                            }
+                        }
+                    }
+                    
+                    // Check function return values
+                    const ComparatorVector& cmps = ComparatorFactory::Instance().GetComparators();       
+                    ComparatorVector::const_iterator retComparator = cmps.begin();
+                    int retComparatorRound = 1;
+                    for ( ; retComparator != cmps.end(); retComparator++ )
+                    {
+                        if ( compareMethodsReturn(basemethod,currentmethod, **retComparator) )
+                        { 
+                            if( retComparatorRound==CONSTFILTER_COMPARATOR )
+                            {                       
+                                // if the return value has changed from const to non-const
+                                ret++;
+                                if(report)
+                                {
+                                    //add the issue as it is a source compatibility break
+									AddIssueFunction<EIssueTypeReturnConst>(&basemethod,identity,currentmethod,lineNo1);
+                                }
+                            }
+                            else if( retComparatorRound==CONSTFILTER2_COMPARATOR )
+                            {                       
+                                // if the return calue has changed from non-const to const
+                                ret++;
+                                if(report)
+                                {
+                                    //add the issue as it is a source compatibility break
+									AddIssueFunction<EIssueTypeReturnConst2>(&basemethod,identity,currentmethod,lineNo1);
+                                }
+                            }         
+                            
+                            baseMapIter->second.returnValueMatch = true;
+                            currMapIter->second.returnValueMatch = true;
+                            break;
+                        }
+                        retComparatorRound++;
+                    }
+                    
+                                    
+                    if ( !CheckAccessModifier(basemethod,currentmethod) )
+                    {
+                        if (report)
+                        {
+							AddIssueFunction<EIssueTypeAccess>(&basemethod,identity, currentmethod,lineNo1);
+                        }
+                        ++ret;
+                    }
+                    break;
+                }
+            }
+        }
+        else
+        {
+            // Not accessible, can be marked as matching.
+            if( baseMapIter != baseMap.end() )
+            {
+                baseMapIter->second.signatureMatch = true;
+                baseMapIter->second.returnValueMatch = true;
+            }
+        }
+    }
+        
+    // Recursive call with next comparator (if any) and updated method maps.
+    const ComparatorVector& cmps = ComparatorFactory::Instance().GetComparators();
+    if( ++comparator != cmps.end() )
+    {
+        comparatorRound++;
+        ret += ClassNodeAnalysis::compareNonvirtualFunctions(
+            baseline,
+            current, 
+            bexportedMethods,        
+            cexportedMethods,                                           
+            identity,                                          
+            report,
+            comparator,
+            baseMap,
+            currMap,
+            comparatorRound);
+    }
+    
+    return ret;
+}
+
+// ----------------------------------------------------------------------------
+// ClassNodeAnalysis::compareOthers
+// ----------------------------------------------------------------------------
+//
+int ClassNodeAnalysis::compareOthers(HANodeIterator baseline,HANodeIterator current, 
+                                     const vector<DOMNode*>& bothers, const vector<DOMNode*>& cothers, 
+                                     bool report)
+{
+	int retval = 0;
+	return retval;
+}
+
+// ----------------------------------------------------------------------------
+// printlist
+// ----------------------------------------------------------------------------
+//
+void printlist(const NodeIndex::dtable_t& lista)
+{
+	NodeIndex::dtable_t::const_iterator it = lista.begin();
+	for (; it != lista.end(); ++it)
+	{
+		cout << it->iName << " at " << it->iOffset << "with node:" << it->iNode <<  endl;
+	}
+}
+
+// ----------------------------------------------------------------------------
+// ClassNodeAnalysis::compareFields
+// ----------------------------------------------------------------------------
+//
+int ClassNodeAnalysis::compareFields(HANodeIterator baseline,HANodeIterator current,
+                                     const vector<DOMNode*>& bfields_class,
+									 const vector<DOMNode*>& cfields_class,
+                                     bool report)
+{
+	int ret = 0;
+
+	const NodeIndex::dtable_t& bfields = ClassGenerateDataMemberTable(baseline);
+	const NodeIndex::dtable_t& cfields = ClassGenerateDataMemberTable(current);
+
+	int lineNo = 0;
+	const XMLCh* lineNumber = current.GetAttribute(KXMLLineString);
+	lineNo = atoi(toString(lineNumber).c_str());
+
+	// If you don't like to see the issue about base size when the size has changed
+	// uncomment the test below
+
+	//if (!iReportAddedMembers)
+	//{
+		// Check only if size has not changed
+		ret += compareBaseSizes(baseline, current, bfields, cfields, report);
+	//}
+
+	// Fields
+    // Order and type of accessible members matters
+    //////////////////////////////////////////////////////////////
+    vector<bool> fieldFound(cfields.size(),false);
+    vector<bool> fieldRemoved(bfields.size(),false);
+    vector<bool> fieldChanged(bfields.size(),false);
+    vector<int> fieldChangedCurrent(bfields.size(),-1);
+    vector<bool> fieldAccessible(bfields.size(),false);
+
+	unsigned int i = 0;
+    for (i=0; i < bfields.size(); ++i)
+    {
+		if ( !bfields[i].iNode )
+		{
+			unsigned int ii = 0;
+			for (ii=0; ii < cfields.size(); ++ii)
+			{
+				if ( !fieldFound[ii] && (bfields[i].iName == cfields[ii].iName) )
+				{
+	                fieldFound[ii] = true;
+
+					if ( bfields[i].iOffset != cfields[ii].iOffset )
+					{
+						if (report)
+						{
+							AddIssue<EIssueIdentityVirtualTablePointer,EIssueTypeOffset>(&baseline,current,lineNo,NULL,bfields[i]);							
+						}
+						++ret;
+					}
+					break;
+				}
+			}
+
+			if ( cfields.size() == ii )
+			{
+				fieldRemoved[i] = true;
+			}
+
+			continue;
+		}
+
+        HANodeIterator basefield(baseline);
+        basefield.current = bfields[i].iNode;
+		bool dummy;
+ 		fieldAccessible[i] = CheckAccessibility(baseline, dummy, bfields[i].iAccess);
+
+        unsigned int ii = 0;
+        for (ii=0; ii < cfields.size(); ++ii)
+        {
+            HANodeIterator currentfield(current);
+            currentfield.current = cfields[ii].iNode;
+            
+            if ( !fieldFound[ii] && (bfields[i].iName == cfields[ii].iName) )//CompareNames(basefield,currentfield) )
+            {
+                fieldFound[ii] = true;
+
+                if ( fieldAccessible[i] && !CheckAccessModifier(bfields[i].iAccess,cfields[ii].iAccess) )
+                {
+                    if (report)
+                    {
+                        AddIssue<EIssueIdentityField,EIssueTypeAccess>(&baseline, currentfield,cfields[ii].iLineNo,NULL,bfields[i]);
+                    }
+                    ++ret;
+                }
+
+				if ( 0 != compareField(baseline,current,bfields[i],cfields[ii],false) )
+                {
+					fieldChanged[i] = true;
+					fieldChangedCurrent[i] = ii;
+					if (fieldAccessible[i])
+					{
+						iReportAddedMembers = true;
+					}
+                }
+                break;
+            }
+        }
+
+        if ( cfields.size() == ii )
+        {
+			fieldRemoved[i] = true;
+            if ( fieldAccessible[i] )
+            {
+				iReportAddedMembers = true;
+            }
+        }
+    }
+
+    for (i = 0; i < fieldRemoved.size(); ++i)
+    {
+        if (fieldRemoved[i])
+        {
+			if ( !bfields[i].iNode )
+			{
+				if (report)
+				{
+					AddIssue<EIssueIdentityVirtualTablePointer,EIssueTypeRemoval>(&baseline,current,lineNo,NULL,bfields[i]);							
+				}
+				continue;
+			}
+
+            HANodeIterator basefield(baseline);
+            basefield.current = bfields[i].iNode;
+
+			if (iReportAddedMembers || fieldAccessible[i])
+			{
+				if (report)
+				{
+					if (fieldAccessible[i])
+					{
+						AddIssue<EIssueIdentityField,EIssueTypeRemoval>(&baseline, basefield,lineNo,NULL,bfields[i]);
+					}
+					else
+					{
+						AddIssue<EIssueIdentityFieldInaccessible,EIssueTypeRemoval>(&baseline, basefield,lineNo,NULL,bfields[i]);
+					}
+				}
+				++ret;
+			}
+        }
+
+        if (fieldChanged[i])
+        {
+            HANodeIterator basefield(baseline);
+            HANodeIterator currentfield(current);
+            basefield.current = bfields[i].iNode;
+			int ii = fieldChangedCurrent[i];
+
+			if ( -1 == ii )
+			{
+				continue;
+			}
+
+			if (iReportAddedMembers || fieldAccessible[i])
+			{
+				if (report)
+				{
+					compareField(baseline, current, bfields[i], cfields[ii], report);
+				}
+				++ret;
+			}
+        }
+
+    }
+
+    for (i = 0; i < fieldFound.size(); ++i)
+    {
+        if (!fieldFound[i])
+        {
+ 			if ( !cfields[i].iNode )
+			{
+				if (report)
+				{
+					AddIssue<EIssueIdentityVirtualTablePointer,EIssueTypeAddition>(&baseline,current,lineNo,NULL,cfields[i]);							
+				}
+				continue;
+			}
+
+			HANodeIterator currentfield(current);
+            currentfield.current = cfields[i].iNode;
+            if (report && iReportAddedMembers)
+            {
+                AddIssue<EIssueIdentityField,EIssueTypeAddition>(&current, currentfield,cfields[i].iLineNo,NULL,cfields[i]);
+            }
+            ++ret;
+        }
+    }
+	return ret;
+}
+
+// ----------------------------------------------------------------------------
+// printlist
+// Output list members
+// 
+// ----------------------------------------------------------------------------
+//
+void printlist(const NodeIndex::vtable_t& lista)
+{
+	NodeIndex::vtable_t::const_iterator it = lista.begin();
+	for (; it != lista.end(); ++it)
+	{
+		cout << it->first << endl;
+	}
+
+}
+
+// ----------------------------------------------------------------------------
+// ClassNodeAnalysis::indexVirtualMethods
+// ----------------------------------------------------------------------------
+//
+void ClassNodeAnalysis::indexVirtualMethods(HANodeIterator node, 
+											const vector<DOMNode*>& virtualMethods, 
+											const NodeIndex::vtable_t& vtable,
+											vector<pair<DOMNode*,int> >& virtualMethodsWithIndex)
+{
+	vector<DOMNode*>::const_iterator it = virtualMethods.begin();
+
+	for (; it != virtualMethods.end(); ++it)
+	{	
+		NodeIndex::vtable_t::const_iterator vtableit = vtable.begin();
+		for (int i = 0; vtableit != vtable.end(); ++vtableit, ++i)
+		{
+			HANodeIterator funcnode(node);
+			funcnode.current = *it;
+
+			char index_str[256];
+
+			sprintf(index_str, "%d",i);
+			
+			funcnode.SetAttribute(KXMLBBCVirtualFunctionIndex, index_str );
+
+			string funcsig = GenerateFunctionSignature(funcnode);
+			if (funcsig == vtableit->first)
+			{
+				virtualMethodsWithIndex.push_back(pair<DOMNode*,int>(*it,i));
+			}
+		}
+	}
+}
+
+// ----------------------------------------------------------------------------
+// ClassNodeAnalysis::compareVirtualTables
+// ----------------------------------------------------------------------------
+//
+int ClassNodeAnalysis::compareVirtualTables(HANodeIterator baseline,HANodeIterator current,
+											const NodeIndex::vtable_t& basevtable, 
+											const NodeIndex::vtable_t& currentvtable,
+                                            bool report)
+{
+	if ( basevtable.size() != currentvtable.size() )
+	{
+		return 1;
+	}
+
+	NodeIndex::vtable_t::const_iterator baseit = basevtable.begin();
+	NodeIndex::vtable_t::const_iterator currentit = currentvtable.begin();
+
+	unsigned int i = 0;
+    for (i=0; baseit != basevtable.end(); ++baseit,++i,++currentit)
+    {
+
+        if ( baseit->first != currentit->first )
+		{
+			return 1;
+		}
+    }
+	return 0;
+}
+
+// ----------------------------------------------------------------------------
+// ClassNodeAnalysis::compareVirtualFunctions
+// ----------------------------------------------------------------------------
+//
+int ClassNodeAnalysis::compareVirtualFunctions(HANodeIterator baseline,HANodeIterator current, 
+                                                  const vector<DOMNode*>& bvirtualMethods, 
+												  const vector<DOMNode*>& cvirtualMethods, 
+                                                  bool report)
+{
+	int ret = 0;
+	//Analyse virtual methods, not a single change is tolerated
+
+    // First we build virtual tables for baseline and current classes.
+	const NodeIndex::vtable_t& basevtable = ClassGenerateVirtualTable(baseline);
+	const NodeIndex::vtable_t& currentvtable = ClassGenerateVirtualTable(current);
+
+	int parentLineNo = 0;
+	int lineNo = 0;
+	const XMLCh* parentlineNumber = current.GetAttribute(KXMLLineString);
+	parentLineNo = atoi(toString(parentlineNumber).c_str());
+
+	if ( 0 != compareVirtualTables(baseline,current,basevtable,currentvtable,report) )
+	{
+        // Virtual table has been changed.
+		AddIssue<EIssueIdentityVirtualTable,EIssueTypeChange>(&baseline, current, parentLineNo, NULL, "[Primary-vtable]");	
+	}
+
+	vector<pair<DOMNode*,int> > bvirtualMethodsWithIndex;
+	vector<pair<DOMNode*,int> > cvirtualMethodsWithIndex;
+
+    // Add virtual methods to vectors with their indexes (i.e. order inside a class).
+	indexVirtualMethods(baseline,bvirtualMethods,basevtable,bvirtualMethodsWithIndex);
+	indexVirtualMethods(current,cvirtualMethods,currentvtable,cvirtualMethodsWithIndex);
+
+    unsigned int i = 0;
+    vector<bool> virtualMethodFound(cvirtualMethodsWithIndex.size(),false);
+
+    // Use only default comparator here, since virtual functions should have strict match.
+    const ComparatorVector& cmps = ComparatorFactory::Instance().GetComparators();
+    ComparatorVector::const_iterator defaultcomparator = cmps.begin();
+    assert( defaultcomparator != cmps.end() );
+
+    for (i=0; i < bvirtualMethodsWithIndex.size(); ++i)
+    {
+        HANodeIterator basemethod(baseline);
+        basemethod.current = bvirtualMethodsWithIndex[i].first;
+
+        unsigned int ii = 0;
+        for (ii=0; ii < cvirtualMethodsWithIndex.size(); ++ii)
+        {
+            HANodeIterator currentmethod(current);
+            currentmethod.current = cvirtualMethodsWithIndex[ii].first;
+            
+			lineNo = 0;
+			const XMLCh* lineNumber = currentmethod.GetAttribute(KXMLLineString);
+			lineNo = atoi(toString(lineNumber).c_str());
+                if ( compareMethodsSignature(basemethod,currentmethod, **defaultcomparator) )
+            {
+                virtualMethodFound[ii] = true;
+                if (bvirtualMethodsWithIndex[i].second != cvirtualMethodsWithIndex[ii].second)
+                {
+                    // Here the indexes don't match --> The order of virtual methods has been
+                    // changed. This means that the layout of the virtual table has been changed
+                    // and the binary compatibility is broken.
+                    if (report)
+                    {
+						AddIssue<EIssueIdentityVirtualFunction,EIssueTypeOrderChange>(&basemethod, currentmethod,lineNo);
+					}
+                    ++ret;
+                }
+
+				//Check also the default parameter values
+				DOMElement * baselineelement = static_cast<DOMElement*>(basemethod.current);
+				DOMNodeList* baselinechilds = baselineelement->getChildNodes();
+				DOMElement * currentelement = static_cast<DOMElement*>(currentmethod.current);
+				DOMNodeList* currentchilds = currentelement->getChildNodes();
+			    
+				XMLSize_t childcount = baselinechilds->getLength();
+
+				unsigned int i = 0;
+				for (i = 0; i < childcount; ++i)
+				{
+					DOMNode* baselinechild = baselinechilds->item(i);
+					HANodeIterator baselinechildit(baseline);
+					baselinechildit.current = baselinechild;
+
+					DOMNode* currentchild = currentchilds->item(i);
+					HANodeIterator currentchildit(current);
+					currentchildit.current = currentchild;
+
+					short nodetype = baselinechildit->getNodeType();
+					if (nodetype == DOMNode::ELEMENT_NODE)
+					{
+						const XMLCh * baselinesize = FindAttributeValueForType(baselinechildit,KXMLSizeString);
+						const XMLCh * currentsize = FindAttributeValueForType(currentchildit,KXMLSizeString);
+
+						const XMLCh * baselinealign = FindAttributeValueForType(baselinechildit,KXMLAlignString);
+						const XMLCh * currentalign = FindAttributeValueForType(currentchildit,KXMLAlignString);
+
+						if ( !baselinesize )
+						{
+							baselinesize = baselinealign;
+						}
+							
+						if ( !currentsize )
+						{
+							currentsize = currentalign;
+						}
+
+						if ( !Equals(baselinesize,currentsize) || !Equals(baselinealign, currentalign) ||
+							!CompareAttributes(baselinechildit,currentchildit,KXMLDefaultString,EOptionalSimpleAttribute))
+						{
+							++ret;
+							if (report)
+							{
+								AddIssue<EIssueIdentityVirtualFunction,EIssueTypeParam>(&basemethod,currentmethod, lineNo);
+							}
+							break;
+						}
+					}
+				}					
+                // check the return types of the methods
+				if ( !compareMethodsReturn(basemethod,currentmethod,**defaultcomparator) )
+                {
+                    if (report)
+                    {
+						AddIssue<EIssueIdentityVirtualFunction,EIssueTypeReturn>(&basemethod, currentmethod,lineNo);
+                    }
+                    ++ret;
+                }
+
+                if ( !CheckAccessModifier(basemethod,currentmethod) )
+                {
+                    if (report)
+                    {
+						AddIssue<EIssueIdentityVirtualFunction,EIssueTypeAccess>(&basemethod, currentmethod,lineNo);
+                    }
+                    ++ret;
+                }
+                break;
+            }
+        }
+
+        if ( cvirtualMethodsWithIndex.size() == ii )
+        {
+            //Method not found
+
+/*
+			// This code detects if the removed virtual function was actually an removed override.
+            unsigned int baseindex = bvirtualMethodsWithIndex[i].second;
+            HANodeIterator basemethod(baseline);
+            basemethod.current = bvirtualMethodsWithIndex[i].first;
+			
+			if ( (baseindex < currentvtable.size()) && (currentvtable[baseindex].first == GenerateFunctionSignature(basemethod)) )
+			{
+				//This is a new override and we should report this if the class is derivable
+				if (ClassIsDerivable(baseline))
+				{
+					if (report)
+					{
+						AddIssue<EIssueIdentityVirtualFunction,EIssueTypeRemovedOverride>(&basemethod, basemethod);
+					}
+					++ret;
+				}
+			}
+			else*/
+			{				
+				if (report)
+				{
+					AddIssue<EIssueIdentityVirtualFunction,EIssueTypeRemoval>(&basemethod, basemethod,parentLineNo);
+				}
+				++ret;
+			}
+        }
+    }
+
+    for (i = 0; i < virtualMethodFound.size(); ++i)
+    {
+        if (!virtualMethodFound[i])
+        {
+            HANodeIterator currentmethod(current);
+            currentmethod.current = cvirtualMethodsWithIndex[i].first;
+
+			lineNo = 0;
+			const XMLCh* lineNumber = currentmethod.GetAttribute(KXMLLineString);
+			lineNo = atoi(toString(lineNumber).c_str());
+			//Check the base vtable for entry for this function
+            unsigned int baseindex = cvirtualMethodsWithIndex[i].second;
+			
+			if ( (baseindex < basevtable.size()) && (basevtable[baseindex].first == GenerateFunctionSignature(currentmethod)) )
+			{
+				//This is a new overwrite and we should report this if the class is derivable
+				if (ClassIsDerivable(baseline))
+				{
+					if (report)
+					{
+						AddIssue<EIssueIdentityVirtualFunction,EIssueTypeNewOverride>(&currentmethod, currentmethod,lineNo);
+					}
+					++ret;
+				}
+			}
+			else
+			{	
+				//This method really modifies the primary vtable
+				// If you also want to find out if this function overrides entry in vtable of non-primary base 
+				// then generate virtual table for them and search for the function signature from them
+				if (report)
+				{
+					AddIssue<EIssueIdentityVirtualFunction,EIssueTypeAddition>(&currentmethod, currentmethod,lineNo);
+				}
+				++ret;
+			}
+        }
+    }
+	return ret;
+}
+
+// ----------------------------------------------------------------------------
+// ClassNodeAnalysis::compareBaseSizes
+// ----------------------------------------------------------------------------
+//
+int ClassNodeAnalysis::compareBaseSizes(HANodeIterator baseline, HANodeIterator current, const NodeIndex::dtable_t& bfields, const NodeIndex::dtable_t& cfields, bool report)
+{
+	int ret = 0;
+
+	if ( ClassIsDerivable(baseline) )
+	{
+		int bbasesize = ClassBaseSize(baseline,bfields);
+		int cbasesize = ClassBaseSize(current,cfields);
+
+		if ( (bbasesize) != (cbasesize) )
+		{
+			int lineNo = 0;
+			const XMLCh* lineNumber = current.GetAttribute(KXMLLineString);
+			lineNo = atoi(toString(lineNumber).c_str());
+			++ret;
+			if (report)
+			{		
+				AddIssueClass<EIssueTypeBaseSize>(&baseline,iIdentity, current,lineNo);
+			}
+		}
+	}
+	return ret;
+}
+
+// ----------------------------------------------------------------------------
+// ClassNodeAnalysis::compareClassMembers
+// ----------------------------------------------------------------------------
+//
+int ClassNodeAnalysis::compareClassMembers(HANodeIterator baseline,HANodeIterator current, bool report)
+{
+	int ret = 0;
+    //Base material
+    vector<DOMNode*> bvirtualMethods;
+    vector<DOMNode*> binlineMethods;
+    vector<DOMNode*> bexportedMethods;
+    vector<DOMNode*> bexportedvirtualMethods;
+    vector<DOMNode*> bmethods;
+    vector<DOMNode*> bfields;
+    vector<DOMNode*> bothers;
+
+    //Current material
+    vector<DOMNode*> cvirtualMethods;
+    vector<DOMNode*> cinlineMethods;
+    vector<DOMNode*> cexportedMethods;
+    vector<DOMNode*> cexportedvirtualMethods;
+    vector<DOMNode*> cmethods;
+    vector<DOMNode*> cfields;
+    vector<DOMNode*> cothers;
+
+    //Reserve some space for efficiency
+    bvirtualMethods.reserve(10);
+    bexportedMethods.reserve(10);
+    bmethods.reserve(10);
+    bfields.reserve(10);
+    bothers.reserve(10);
+
+    cvirtualMethods.reserve(10);
+    cexportedMethods.reserve(10);
+    cmethods.reserve(10);
+    cfields.reserve(10);
+    cothers.reserve(10);
+
+    //Order members
+    ClassOrderMembers(baseline,bvirtualMethods,binlineMethods,bexportedMethods,bexportedvirtualMethods,bmethods,bfields,bothers);
+    ClassOrderMembers(current,cvirtualMethods,cinlineMethods,cexportedMethods,cexportedvirtualMethods,cmethods,cfields,cothers);
+
+	//Virtual functions
+	ret += compareVirtualFunctions(baseline, current, bvirtualMethods, cvirtualMethods, report);
+
+	//if ( baseline.CheckForBooleanAttribute(KXMLBBCVirtualString) )
+	//{
+		//ret += compareExportedVirtualFunctions(baseline, current, bexportedvirtualMethods, cexportedvirtualMethods, report);
+	//}else if ( current.CheckForBooleanAttribute(KXMLBBCVirtualString) )
+	//{
+		//The class has changed from non-dynamic class to dynamic class
+		//Do we need to report something?
+	//}
+    
+    //Exported methods
+	ret += compareNonvirtualFunctions(baseline,current,bexportedMethods,cexportedMethods,EIssueIdentityExportedFunction,report);
+
+    //Inlined methods
+    ret += compareNonvirtualFunctions(baseline, current, binlineMethods, cinlineMethods,EIssueIdentityInlineFunction, report);
+
+	//Fields
+	ret += compareFields(baseline,current,bfields, cfields, report);
+
+	//Others
+	ret += compareOthers(baseline, current, bothers, cothers, report);
+
+    return ret;
+}
+
+// ----------------------------------------------------------------------------
+// ClassNodeAnalysis::compareBases
+// ----------------------------------------------------------------------------
+//
+int ClassNodeAnalysis::compareBases(HANodeIterator baseline,HANodeIterator current,bool report)
+{
+    //Check base classes
+    int ret = 0;
+
+    DOMNodeList* baselinechilds = baseline.GetElementsByTagName(KXMLBaseString);
+    DOMNodeList* currentchilds = current.GetElementsByTagName(KXMLBaseString);
+   
+    XMLSize_t baselinechildcount = baselinechilds->getLength();
+    XMLSize_t currentchildcount = currentchilds->getLength();
+
+	int lineNo = 0;
+	const XMLCh* lineNumber = current.GetAttribute(KXMLLineString);
+	lineNo = atoi(toString(lineNumber).c_str());
+    if ( baselinechildcount == currentchildcount )
+    {
+		unsigned int i = 0;
+        for (i = 0; i < baselinechildcount; ++i)
+        {
+            HANodeIterator baselineit(baseline);
+            HANodeIterator currentit(current);
+            baselineit.current = baselinechilds->item(i);
+            
+            HANodeIterator basenameit(baseline);
+            basenameit.FindNodeById(baselineit.GetAttribute(KXMLTypeString));
+            string basename( GenerateFullyQualifiedName(basenameit) );
+
+			unsigned int ii = 0;
+			for (ii = 0; ii < currentchildcount; ++ii)
+			{
+				currentit.current = currentchilds->item(ii);
+
+				HANodeIterator currentnameit(current);
+				currentnameit.FindNodeById(currentit.GetAttribute(KXMLTypeString));
+				string currentname( GenerateFullyQualifiedName(currentnameit) );
+				if ( basename == currentname )
+				{
+					if ( basenameit.CheckForBooleanAttribute(KXMLBBCVirtualString) )
+					{
+					
+						const NodeIndex::vtable_t& basevtable = ClassGenerateVirtualTable(basenameit);
+						const NodeIndex::vtable_t& currentvtable = ClassGenerateVirtualTable(currentnameit);
+
+						if ( 0 != compareVirtualTables(basenameit,currentnameit,basevtable,currentvtable,report) )
+						{
+							string vtablename = "[";
+							vtablename += basename;
+							vtablename += "-vtable]";
+							AddIssue<EIssueIdentityVirtualTable,EIssueTypeChange>(&baseline, current, lineNo, NULL, vtablename);
+						}
+					
+					}
+					if ( 
+						!Equals( baselineit.GetAttribute(KXMLVirtualString), currentit.GetAttribute(KXMLVirtualString)) )
+					{
+						//Virtuality differs
+						if (report)
+						{
+							AddIssueClass<EIssueTypeInheritance>(&baseline,iIdentity, current,lineNo);
+						}
+						++ret;
+					}
+            
+					if ( !Equals( baselineit.GetAttribute(KXMLOffsetString), currentit.GetAttribute(KXMLOffsetString)) )
+					{
+						if (report)
+						{
+							string subobjectname = "[" + basename;
+							subobjectname += "]";
+							AddIssue<EIssueIdentitySubobject,EIssueTypeOffset>(&baseline,current,lineNo, NULL,subobjectname);
+						}
+						++ret;
+					}
+					break;
+				}
+			}
+			if ( currentchildcount == ii )
+			{
+				if (report)
+				{
+					//AddIssueClass<EIssueTypeInheritance>(&baseline,iIdentity, current);
+                    //base class removed from inheritance
+					string subobjectname = "[" + basename;
+					subobjectname += "]";
+					AddIssue<EIssueIdentitySubobject,EIssueTypeRemoval>(&baseline,current,lineNo, NULL,subobjectname);
+				}
+				++ret;
+			}
+        }    
+    } else
+    {
+        //Different amount of bases
+        if (report)
+        {
+			AddIssueClass<EIssueTypeInheritance>(&baseline,iIdentity, current,lineNo);
+        }
+        ++ret;
+
+        //check if a base class is removed from inheritance
+		unsigned int i = 0;
+        for (i = 0; i < baselinechildcount; ++i)
+        {
+            HANodeIterator baselineit(baseline);
+            HANodeIterator currentit(current);
+            baselineit.current = baselinechilds->item(i);
+            
+            HANodeIterator basenameit(baseline);
+            basenameit.FindNodeById(baselineit.GetAttribute(KXMLTypeString));
+            string basename( GenerateFullyQualifiedName(basenameit) );
+
+			unsigned int ii = 0;
+			for (ii = 0; ii < currentchildcount; ++ii)
+			{
+				currentit.current = currentchilds->item(ii);
+				
+				HANodeIterator currentnameit(current);
+				currentnameit.FindNodeById(currentit.GetAttribute(KXMLTypeString));
+				
+				string currentname( GenerateFullyQualifiedName(currentnameit) );
+				if ( basename == currentname )
+				{
+					break;
+				}
+			}
+			if ( currentchildcount == ii )
+			{
+				if (report)
+				{
+					string subobjectname = "[" + basename;
+					subobjectname += "]";
+					AddIssue<EIssueIdentitySubobject,EIssueTypeRemoval>(&baseline,current,lineNo, NULL,subobjectname);
+				}
+				++ret;
+			}
+        }    
+    }
+
+    return ret;
+
+}
+
+// ----------------------------------------------------------------------------
+// ClassNodeAnalysis::ClassNodeAnalysis
+// ----------------------------------------------------------------------------
+//
+ClassNodeAnalysis::ClassNodeAnalysis()
+    : iReportAddedMembers(false),
+      iIdentity(EIssueIdentityClass)
+{
+}
+
+
+// ----------------------------------------------------------------------------
+// ClassNodeAnalysis::Construct
+// ----------------------------------------------------------------------------
+//
+NodeAnalysis* ClassNodeAnalysis::Construct()
+{
+    return new ClassNodeAnalysis;
+}
+
+// ----------------------------------------------------------------------------
+// ClassNodeAnalysis::FindNodeAndAnalyse
+// ----------------------------------------------------------------------------
+//
+int ClassNodeAnalysis::FindNodeAndAnalyse(HANodeIterator baseline,HANodeIterator current)
+{
+    if ( baseline.CheckForBooleanAttribute(KXMIncompleteString) )
+    {
+        return 0;
+    }
+
+     DOMNode* node = NodeAnalysis::findNode(baseline,current);
+    if ( !node )
+    {
+        //AddIssue<>(&baseline,EIssue_class_removal);
+        AddIssue<EIssueIdentityClass,EIssueTypeRemoval>(&baseline, baseline,0);
+        return 1;
+    }
+    current.current = node;
+
+    return this->Analyse(baseline,current);
+}
+
+// ----------------------------------------------------------------------------
+// ClassNodeAnalysis::Analyse
+// ----------------------------------------------------------------------------
+//
+int ClassNodeAnalysis::Analyse(HANodeIterator baseline,HANodeIterator current, bool report)
+{
+    //ASSERTS
+    int ret=0;
+    short nodetype = baseline->getNodeType();    
+    assert(nodetype == DOMNode::ELEMENT_NODE);
+    nodetype = current->getNodeType();    
+    assert(nodetype == DOMNode::ELEMENT_NODE);
+	int lineNo = 0;
+	const XMLCh* lineNumber = current.GetAttribute(KXMLLineString);
+	lineNo = atoi(toString(lineNumber).c_str());
+
+    const XMLCh* baseanalysisstatus = baseline.GetAttribute(KXMLBBCAnalysisStatus);
+
+    if (baseanalysisstatus)
+    {
+        if ( Equals(baseanalysisstatus,KXMLBBCAnalysisStatusAnalysing) )
+        {
+            //We are analysing recursively, should not happen
+            assert(false);
+        }
+        else if ( Equals(baseanalysisstatus,KXMLBBCAnalysisStatusClean) )
+        {
+            return 0;
+        }
+
+		if (!report)
+		{
+			return 1;
+		}
+    }
+
+    
+    baseline.SetAttribute(KXMLBBCAnalysisStatus,KXMLBBCAnalysisStatusAnalysing);
+
+    bool bincomplete = baseline.CheckForBooleanAttribute(KXMIncompleteString);
+    bool cincomplete = current.CheckForBooleanAttribute(KXMIncompleteString);
+
+    // Check if either baseline or current node is of incomplete type.
+    // Type is incomplete if the type is just forward declared or the
+    // analysed header file can be compiled without resolving the details
+    // of the type. This kind of situation occurs for example when only
+    // a reference or pointer to the class is used in the analyzed header, 
+    // and the class is declared in other header file.
+    //
+    // If the type is incomplete, we cannot compare the nodes.
+    if ( bincomplete || cincomplete )
+    {
+        if ( bincomplete && cincomplete )
+        {	
+            ret = 0;
+        }
+        else if (bincomplete)
+        {
+            ret = 0;
+        }
+        else
+        {            
+			AddIssueClass<EIssueTypeNotAnalysed>(&baseline,iIdentity, baseline,0);
+            ret = 1;
+        }
+    }
+    else
+    {
+        // Check that the access level of the current node has not been changed
+        // to more restricted.
+        if (!CheckAccessModifier(baseline,current))
+        {
+            if (report)
+            {         
+				AddIssueClass<EIssueTypeAccess>(&baseline,iIdentity, current,lineNo);
+            }
+            ret += 1;
+        }
+
+
+		// Check if the class has virtual bases
+		if ( baseline.CheckForBooleanAttribute(KXMLBBCVirtualInheritanceString) )
+		{
+			AddIssueClass<EIssueTypeVirtualBases>(&baseline,iIdentity, current,lineNo);
+			++ret;
+		}
+
+		if ( current.CheckForBooleanAttribute(KXMLBBCVirtualInheritanceString) )
+		{
+			AddIssueClass<EIssueTypeVirtualBases>(&current,iIdentity, current,lineNo);
+			++ret;
+		}
+
+        // Check if the class is istantiable or derivable
+        if ( ClassIsInstantiable(baseline) || (ClassIsDerivable(baseline) && EIssueIdentityUnion != iIdentity) )
+        {
+
+            if ( !CompareAttributes(baseline,current,KXMLAlignString,ESimpleAttribute) )
+            {
+                if (report)
+                {                    
+					AddIssueClass<EIssueTypeAlign>(&baseline,iIdentity, current,lineNo);
+                    iReportAddedMembers = true;
+                }
+                ret += 1;
+            }
+
+            if ( !CompareAttributes(baseline,current,KXMLSizeString,ESimpleAttribute) )
+            {
+                if (report)
+                {                 
+					AddIssueClass<EIssueTypeSize>(&baseline,iIdentity, current,lineNo);
+                    iReportAddedMembers = true;
+                }
+                ret += 1;
+            }
+        }
+       	//ret += compareBaseSizes(baseline,current,report);
+        ret += compareClassMembers(baseline,current,report);
+        ret += compareBases(baseline,current,report);
+    }
+
+    if ( ret == 0 )
+    {
+        baseline.SetAttribute(KXMLBBCAnalysisStatus,KXMLBBCAnalysisStatusClean);
+    } else
+    {
+        baseline.SetAttribute(KXMLBBCAnalysisStatus,KXMLBBCAnalysisStatusIssues);
+    }
+
+    return ret;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+///////////////////////////////StructNodeAnalysis///////////////////////////////////////
+
+// ----------------------------------------------------------------------------
+// StructNodeAnalysis::Construct
+// ----------------------------------------------------------------------------
+//
+NodeAnalysis* StructNodeAnalysis::Construct()
+{
+    return new StructNodeAnalysis;
+}
+
+// ----------------------------------------------------------------------------
+// StructNodeAnalysis::StructNodeAnalysis
+// ----------------------------------------------------------------------------
+//
+StructNodeAnalysis::StructNodeAnalysis()
+{
+	iIdentity = EIssueIdentityStruct;
+}
+////////////////////////////////////////////////////////////////////////////////////////
+